Skip to content

Commit

Permalink
Add XEASY PROT file lexer, parser, parserlistener, and reader
Browse files Browse the repository at this point in the history
  • Loading branch information
yokochi47 committed Dec 5, 2024
1 parent 8e4d8f6 commit 598240a
Show file tree
Hide file tree
Showing 23 changed files with 2,232 additions and 467 deletions.
3 changes: 2 additions & 1 deletion wwpdb/utils/nmr/NmrDpReport.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
# 14-Nov-2024 M. Yokochi - add 'nm-aux-cha' file type for CHARMM extended CRD (CARD) file acting as CHARMM topology definition
# 19-Nov-2024 M. Yokochi - add support for pH titration data (NMR restraint remediation)
# 22-Nov-2024 M. Yokochi - add 'nm-res-noa' file type for CYANA NOA (NOE Assignment) file
# 05-Dec-2024 M. Yokochi - add 'nm-aux-xea' file type for XEASY PROT (Assignment) file (NMR restraint remediation)
##
""" Wrapper class for NMR data processing report.
@author: Masashi Yokochi
Expand Down Expand Up @@ -1752,7 +1753,7 @@ def __init__(self, verbose=True, log=sys.stdout):
'stats_of_exptl_data')
self.file_types = ('pdbx',
'nef', 'nmr-star',
'nm-aux-amb', 'nm-aux-cha', 'nm-aux-gro',
'nm-aux-amb', 'nm-aux-cha', 'nm-aux-gro', 'nm-aux-xea',
'nm-res-amb', 'nm-res-ari', 'nm-res-bio', 'nm-res-cha', 'nm-res-cns',
'nm-res-cya', 'nm-res-dyn', 'nm-res-gro', 'nm-res-isd', 'nm-res-mr',
'nm-res-noa', 'nm-res-oth', 'nm-res-ros', 'nm-res-sax', 'nm-res-syb',
Expand Down
8 changes: 8 additions & 0 deletions wwpdb/utils/nmr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,12 @@ nm-res-xpl|nm-res-xpl|nmr-restraints/xplor-nih|Restraint file in XPLOR-NIH forma
nm-res-oth|nm-res-oth|nmr-restraints/any|Restraint file in other format
nm-res-mr|**not applicable**|nmr-restraints/pdb-mr|Restraint file in PDB-MR format
nm-res-sax|**not applicable**|nmr-restraints/any|SAX CSV file
nm-pea-ari|**not applicable**|nmr-peaks/any|Spectral peak list file in ARIA format
nm-pea-pip|**not applicable**|nmr-peaks/any|Spectral peak list file in NMRPIPE format
nm-pea-spa|**not applicable**|nmr-peaks/any|Spectral peak list file in SPARKY format
nm-pea-top|**not applicable**|nmr-peaks/any|Spectral peak list file in TOPSPIN format
nm-pea-vie|**not applicable**|nmr-peaks/any|Spectral peak list file in NMRVIEW format
nm-aux-xea|**not applicable**|nmr-peaks/any|Assignment file in XEASY format
nm-pea-xea|**not applicable**|nmr-peaks/any|Spectral peak list file in XEASY format
nm-pea-xwi|**not applicable**|nmr-peaks/any|Spectral peak list file in XWINNMR format
nm-pea-any|nm-pea-any|nmr-peaks/any|Any spectral peak list file
5 changes: 4 additions & 1 deletion wwpdb/utils/nmr/mr/AmberPTParserListener.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def is_metal_elem(prev_atom_name, prev_seq_id, seq_id):
atomName = _atomName
retrievedAtomNumList.append(atomNum)

if (terminus[atomNum - 1] and ancAtomName.endswith('T'))\
if (0 < atomNum < len(terminus) + 1 and terminus[atomNum - 1] and ancAtomName.endswith('T'))\
or is_segment(prevCompId, prevAtomName, compId, atomName)\
or is_ligand(prevCompId, compId)\
or is_metal_ion(compId, atomName)\
Expand Down Expand Up @@ -1753,7 +1753,9 @@ def exitTree_chain_classification_statement(self, ctx: AmberPTParser.Tree_chain_

# Enter a parse tree produced by AmberPTParser#format_function.
def enterFormat_function(self, ctx: AmberPTParser.Format_functionContext):

try:

if ctx.Fortran_format_A():
g = self.__a_format_pat.search(str(ctx.Fortran_format_A())).groups()
# self.__cur_column_len = int(g[0])
Expand All @@ -1766,6 +1768,7 @@ def enterFormat_function(self, ctx: AmberPTParser.Format_functionContext):
g = self.__e_format_pat.search(str(ctx.Fortran_format_E())).groups()
# self.__cur_column_len = int(g[0])
self.__cur_word_len = int(g[1])

except AttributeError:
# self.__cur_column_len = None
self.__cur_word_len = None
Expand Down
1 change: 1 addition & 0 deletions wwpdb/utils/nmr/mr/AriaMRParserListener.py
Original file line number Diff line number Diff line change
Expand Up @@ -2933,6 +2933,7 @@ def exitAtom_pair(self, ctx: AriaMRParser.Atom_pairContext): # pylint: disable=

# Enter a parse tree produced by AriaMRParser#atom_selection.
def enterAtom_selection(self, ctx: AriaMRParser.Atom_selectionContext):

try:

atom_sel = {'atom_id': str(ctx.Simple_name(1)).upper()}
Expand Down
3 changes: 2 additions & 1 deletion wwpdb/utils/nmr/mr/CharmmCRDParserListener.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def is_metal_elem(prev_atom_name, prev_seq_id, seq_id):
atomName = _atomName
retrievedAtomNumList.append(atomNum)

if (terminus[atomNum - 1] and ancAtomName.endswith('T'))\
if (0 < atomNum < len(terminus) + 1 and terminus[atomNum - 1] and ancAtomName.endswith('T'))\
or is_segment(prevAsymId, prevCompId, prevAtomName, asymId, compId, atomName)\
or is_ligand(prevCompId, compId)\
or is_metal_ion(compId, atomName)\
Expand Down Expand Up @@ -956,6 +956,7 @@ def enterAtom_coordinate(self, ctx: CharmmCRDParser.Atom_coordinateContext): #
def exitAtom_coordinate(self, ctx: CharmmCRDParser.Atom_coordinateContext):

try:

nr = int(str(ctx.Integer(0)))
seqId = int(str(ctx.Integer(1)))

Expand Down
24 changes: 12 additions & 12 deletions wwpdb/utils/nmr/mr/CharmmCRDReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def setLexerMaxErrorReport(self, maxErrReport):
def setParserMaxErrorReport(self, maxErrReport):
self.__maxParserErrorReport = maxErrReport

def parse(self, ptFilePath, cifFilePath=None, isFilePath=True):
def parse(self, crdFilePath, cifFilePath=None, isFilePath=True):
""" Parse CHARMM CRD file.
@return: CharmmCRDParserListener for success or None otherwise, ParserErrorListener, LexerErrorListener.
"""
Expand All @@ -86,25 +86,25 @@ def parse(self, ptFilePath, cifFilePath=None, isFilePath=True):
try:

if isFilePath:
ptString = None
crdString = None

if not os.access(ptFilePath, os.R_OK):
if not os.access(crdFilePath, os.R_OK):
if self.__verbose:
self.__lfh.write(f"CharmmCRDReader.parse() {ptFilePath} is not accessible.\n")
self.__lfh.write(f"CharmmCRDReader.parse() {crdFilePath} is not accessible.\n")
return None, None, None

ifh = open(ptFilePath, 'r') # pylint: disable=consider-using-with
ifh = open(crdFilePath, 'r') # pylint: disable=consider-using-with
input = InputStream(ifh.read())

else:
ptFilePath, ptString = None, ptFilePath
crdFilePath, crdString = None, crdFilePath

if ptString is None or len(ptString) == 0:
if crdString is None or len(crdString) == 0:
if self.__verbose:
self.__lfh.write("CharmmCRDReader.parse() Empty string.\n")
return None, None, None

input = InputStream(ptString)
input = InputStream(crdString)

if cifFilePath is not None:
if not os.access(cifFilePath, os.R_OK):
Expand All @@ -120,7 +120,7 @@ def parse(self, ptFilePath, cifFilePath=None, isFilePath=True):
lexer = CharmmCRDLexer(input)
lexer.removeErrorListeners()

lexer_error_listener = LexerErrorListener(ptFilePath, maxErrorReport=self.__maxLexerErrorReport)
lexer_error_listener = LexerErrorListener(crdFilePath, maxErrorReport=self.__maxLexerErrorReport)
lexer.addErrorListener(lexer_error_listener)

messageList = lexer_error_listener.getMessageList()
Expand All @@ -137,7 +137,7 @@ def parse(self, ptFilePath, cifFilePath=None, isFilePath=True):
# try with simpler/faster SLL prediction mode
parser._interp.predictionMode = PredictionMode.SLL # pylint: disable=protected-access
parser.removeErrorListeners()
parser_error_listener = ParserErrorListener(ptFilePath, maxErrorReport=self.__maxParserErrorReport)
parser_error_listener = ParserErrorListener(crdFilePath, maxErrorReport=self.__maxParserErrorReport)
parser.addErrorListener(parser_error_listener)
tree = parser.charmm_crd()

Expand All @@ -159,7 +159,7 @@ def parse(self, ptFilePath, cifFilePath=None, isFilePath=True):
self.__lfh.write(f"{description['input']}\n")
self.__lfh.write(f"{description['marker']}\n")
elif messageList is None and cifFilePath is None:
parser_error_listener = ParserErrorListener(ptFilePath, maxErrorReport=self.__maxParserErrorReport)
parser_error_listener = ParserErrorListener(crdFilePath, maxErrorReport=self.__maxParserErrorReport)

if self.__verbose:
if listener.warningMessage is not None and len(listener.warningMessage) > 0:
Expand All @@ -177,7 +177,7 @@ def parse(self, ptFilePath, cifFilePath=None, isFilePath=True):
""" debug code
except Exception as e:
if self.__verbose and isFilePath:
self.__lfh.write(f"+CharmmCRDReader.parse() ++ Error - {ptFilePath!r} - {str(e)}\n")
self.__lfh.write(f"+CharmmCRDReader.parse() ++ Error - {crdFilePath!r} - {str(e)}\n")
return None, None, None
"""
finally:
Expand Down
2 changes: 1 addition & 1 deletion wwpdb/utils/nmr/mr/GromacsPTParserListener.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def is_metal_elem(prev_atom_name, prev_seq_id, seq_id):
atomName = _atomName
retrievedAtomNumList.append(atomNum)

if (terminus[atomNum - 1] and ancAtomName.endswith('T'))\
if (0 < atomNum < len(terminus) + 1 and terminus[atomNum - 1] and ancAtomName.endswith('T'))\
or is_segment(prevCompId, prevAtomName, compId, atomName)\
or is_ligand(prevCompId, compId)\
or is_metal_ion(compId, atomName)\
Expand Down
Loading

0 comments on commit 598240a

Please sign in to comment.