diff --git a/wwpdb/utils/nmr/pk/BasePKParserListener.py b/wwpdb/utils/nmr/pk/BasePKParserListener.py index fa949a9b..6b176a7e 100644 --- a/wwpdb/utils/nmr/pk/BasePKParserListener.py +++ b/wwpdb/utils/nmr/pk/BasePKParserListener.py @@ -38,7 +38,8 @@ MAX_PREF_LABEL_SCHEME_COUNT, MAX_ALLOWED_EXT_SEQ, UNREAL_AUTH_SEQ_NUM, - HEME_LIKE_RES_NAMES) + HEME_LIKE_RES_NAMES, + SPECTRAL_DIM_TEMPLATE) from wwpdb.utils.nmr.ChemCompUtil import ChemCompUtil from wwpdb.utils.nmr.BMRBChemShiftStat import BMRBChemShiftStat from wwpdb.utils.nmr.NEFTranslator.NEFTranslator import NEFTranslator @@ -95,7 +96,8 @@ MAX_PREF_LABEL_SCHEME_COUNT, MAX_ALLOWED_EXT_SEQ, UNREAL_AUTH_SEQ_NUM, - HEME_LIKE_RES_NAMES) + HEME_LIKE_RES_NAMES, + SPECTRAL_DIM_TEMPLATE) from nmr.ChemCompUtil import ChemCompUtil from nmr.BMRBChemShiftStat import BMRBChemShiftStat from nmr.NEFTranslator.NEFTranslator import NEFTranslator @@ -711,6 +713,30 @@ def exit(self): finally: self.warningMessage = sorted(list(set(self.f)), key=self.f.index) + def fillCurrentSpectralDim(self): + self.cur_subtype = f'peak{self.num_of_dim}d' + if self.num_of_dim not in self.listIdInternal: + self.listIdInternal[self.num_of_dim] = 0 + self.listIdInternal[self.num_of_dim] += 1 + self.cur_list_id = self.listIdInternal[self.num_of_dim] + if self.num_of_dim not in self.spectral_dim: + self.spectral_dim[self.num_of_dim] = {} + if self.cur_list_id not in self.spectral_dim[self.num_of_dim]: + self.spectral_dim[self.num_of_dim][self.cur_list_id] = {} + for _dim_id in range(1, self.num_of_dim + 1): + self.spectral_dim[self.num_of_dim][self.cur_list_id][_dim_id] =\ + copy.copy(SPECTRAL_DIM_TEMPLATE + if len(self.cur_spectral_dim) == 0 + or _dim_id not in self.cur_spectral_dim + else self.cur_spectral_dim[_dim_id]) + self.spectral_dim[self.num_of_dim][self.cur_list_id][_dim_id]['freq_hint'] = [] + if self.num_of_dim == 2: + self.peaks2D = 0 + if self.num_of_dim == 3: + self.peaks3D = 0 + if self.num_of_dim == 4: + self.peaks4D = 0 + def validatePeak2D(self, index: int, pos_1: float, pos_2: float, pos_unc_1: Optional[float], pos_unc_2: Optional[float], lw_1: Optional[float], lw_2: Optional[float], diff --git a/wwpdb/utils/nmr/pk/SparkyPKParserListener.py b/wwpdb/utils/nmr/pk/SparkyPKParserListener.py index c76cf305..2dd56226 100644 --- a/wwpdb/utils/nmr/pk/SparkyPKParserListener.py +++ b/wwpdb/utils/nmr/pk/SparkyPKParserListener.py @@ -7,7 +7,6 @@ @author: Masashi Yokochi """ import sys -import copy import numpy as np from antlr4 import ParseTreeListener @@ -17,7 +16,6 @@ from wwpdb.utils.nmr.pk.BasePKParserListener import BasePKParserListener from wwpdb.utils.nmr.mr.ParserListenerUtil import (REPRESENTATIVE_MODEL_ID, REPRESENTATIVE_ALT_ID, - SPECTRAL_DIM_TEMPLATE, getPkRow) except ImportError: @@ -25,7 +23,6 @@ from nmr.pk.BasePKParserListener import BasePKParserListener from nmr.mr.ParserListenerUtil import (REPRESENTATIVE_MODEL_ID, REPRESENTATIVE_ALT_ID, - SPECTRAL_DIM_TEMPLATE, getPkRow) @@ -798,29 +795,5 @@ def enterNumber(self, ctx: SparkyPKParser.NumberContext): def exitNumber(self, ctx: SparkyPKParser.NumberContext): # pylint: disable=unused-argument pass - def fillCurrentSpectralDim(self): - self.cur_subtype = f'peak{self.num_of_dim}d' - if self.num_of_dim not in self.listIdInternal: - self.listIdInternal[self.num_of_dim] = 0 - self.listIdInternal[self.num_of_dim] += 1 - self.cur_list_id = self.listIdInternal[self.num_of_dim] - if self.num_of_dim not in self.spectral_dim: - self.spectral_dim[self.num_of_dim] = {} - if self.cur_list_id not in self.spectral_dim[self.num_of_dim]: - self.spectral_dim[self.num_of_dim][self.cur_list_id] = {} - for _dim_id in range(1, self.num_of_dim + 1): - self.spectral_dim[self.num_of_dim][self.cur_list_id][_dim_id] =\ - copy.copy(SPECTRAL_DIM_TEMPLATE - if len(self.cur_spectral_dim) == 0 - or _dim_id not in self.cur_spectral_dim - else self.cur_spectral_dim[_dim_id]) - self.spectral_dim[self.num_of_dim][self.cur_list_id][_dim_id]['freq_hint'] = [] - if self.num_of_dim == 2: - self.peaks2D = 0 - if self.num_of_dim == 3: - self.peaks3D = 0 - if self.num_of_dim == 4: - self.peaks4D = 0 - # del SparkyPKParser diff --git a/wwpdb/utils/nmr/pk/XwinNmrPKLexer.py b/wwpdb/utils/nmr/pk/XwinNmrPKLexer.py new file mode 100644 index 00000000..dc5c6747 --- /dev/null +++ b/wwpdb/utils/nmr/pk/XwinNmrPKLexer.py @@ -0,0 +1,175 @@ +# Generated from XwinNmrPKLexer.g4 by ANTLR 4.13.0 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + + +def serializedATN(): + return [ + 4,0,15,280,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7, + 4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2, + 12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7, + 18,2,19,7,19,2,20,7,20,2,21,7,21,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, + 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1, + 3,1,72,8,1,1,1,1,1,1,2,3,2,77,8,2,1,2,1,2,3,2,81,8,2,1,3,1,3,1,3, + 1,3,1,3,1,3,3,3,89,8,3,1,4,1,4,1,5,4,5,94,8,5,11,5,12,5,95,1,6,4, + 6,99,8,6,11,6,12,6,100,1,6,1,6,1,7,1,7,1,8,1,8,3,8,109,8,8,1,9,1, + 9,3,9,113,8,9,1,10,1,10,3,10,117,8,10,1,11,4,11,120,8,11,11,11,12, + 11,121,1,11,1,11,1,12,4,12,127,8,12,11,12,12,12,128,1,13,1,13,1, + 13,4,13,134,8,13,11,13,12,13,135,1,13,1,13,4,13,140,8,13,11,13,12, + 13,141,1,13,1,13,4,13,146,8,13,11,13,12,13,147,1,13,1,13,4,13,152, + 8,13,11,13,12,13,153,1,13,1,13,4,13,158,8,13,11,13,12,13,159,1,13, + 1,13,4,13,164,8,13,11,13,12,13,165,1,13,1,13,1,13,1,13,1,13,1,13, + 3,13,174,8,13,1,13,5,13,177,8,13,10,13,12,13,180,9,13,1,13,1,13, + 1,13,1,13,1,14,1,14,1,14,4,14,189,8,14,11,14,12,14,190,1,14,1,14, + 4,14,195,8,14,11,14,12,14,196,1,14,1,14,4,14,201,8,14,11,14,12,14, + 202,1,14,1,14,4,14,207,8,14,11,14,12,14,208,1,14,1,14,4,14,213,8, + 14,11,14,12,14,214,1,14,1,14,4,14,219,8,14,11,14,12,14,220,1,14, + 1,14,1,14,1,14,1,14,1,14,3,14,229,8,14,1,14,5,14,232,8,14,10,14, + 12,14,235,9,14,1,14,1,14,1,14,1,14,1,15,4,15,242,8,15,11,15,12,15, + 243,1,16,1,16,1,17,4,17,249,8,17,11,17,12,17,250,1,17,1,17,1,18, + 4,18,256,8,18,11,18,12,18,257,1,18,1,18,1,19,4,19,263,8,19,11,19, + 12,19,264,1,20,4,20,268,8,20,11,20,12,20,269,1,20,1,20,1,21,4,21, + 275,8,21,11,21,12,21,276,1,21,1,21,0,0,22,3,1,5,2,7,3,9,0,11,0,13, + 0,15,4,17,0,19,0,21,0,23,0,25,5,27,6,29,7,31,8,33,9,35,10,37,11, + 39,12,41,13,43,14,45,15,3,0,1,2,10,2,0,43,43,45,45,1,0,48,57,3,0, + 33,33,35,35,42,42,2,0,65,90,97,122,5,0,35,35,42,43,45,46,63,63,95, + 95,2,0,34,34,39,39,2,0,9,9,32,32,2,0,10,10,13,13,2,0,59,59,92,92, + 3,0,9,10,13,13,32,32,315,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,15, + 1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33, + 1,0,0,0,1,35,1,0,0,0,1,37,1,0,0,0,1,39,1,0,0,0,2,41,1,0,0,0,2,43, + 1,0,0,0,2,45,1,0,0,0,3,47,1,0,0,0,5,71,1,0,0,0,7,76,1,0,0,0,9,88, + 1,0,0,0,11,90,1,0,0,0,13,93,1,0,0,0,15,98,1,0,0,0,17,104,1,0,0,0, + 19,108,1,0,0,0,21,112,1,0,0,0,23,116,1,0,0,0,25,119,1,0,0,0,27,126, + 1,0,0,0,29,173,1,0,0,0,31,228,1,0,0,0,33,241,1,0,0,0,35,245,1,0, + 0,0,37,248,1,0,0,0,39,255,1,0,0,0,41,262,1,0,0,0,43,267,1,0,0,0, + 45,274,1,0,0,0,47,48,5,35,0,0,48,49,5,32,0,0,49,50,5,80,0,0,50,51, + 5,69,0,0,51,52,5,65,0,0,52,53,5,75,0,0,53,54,5,76,0,0,54,55,5,73, + 0,0,55,56,5,83,0,0,56,57,5,84,0,0,57,58,5,95,0,0,58,59,5,68,0,0, + 59,60,5,73,0,0,60,61,5,77,0,0,61,62,5,69,0,0,62,63,5,78,0,0,63,64, + 5,83,0,0,64,65,5,73,0,0,65,66,5,79,0,0,66,67,5,78,0,0,67,68,1,0, + 0,0,68,69,6,0,0,0,69,4,1,0,0,0,70,72,7,0,0,0,71,70,1,0,0,0,71,72, + 1,0,0,0,72,73,1,0,0,0,73,74,3,13,5,0,74,6,1,0,0,0,75,77,7,0,0,0, + 76,75,1,0,0,0,76,77,1,0,0,0,77,80,1,0,0,0,78,81,3,13,5,0,79,81,3, + 9,3,0,80,78,1,0,0,0,80,79,1,0,0,0,81,8,1,0,0,0,82,83,3,13,5,0,83, + 84,5,46,0,0,84,85,3,13,5,0,85,89,1,0,0,0,86,87,5,46,0,0,87,89,3, + 13,5,0,88,82,1,0,0,0,88,86,1,0,0,0,89,10,1,0,0,0,90,91,7,1,0,0,91, + 12,1,0,0,0,92,94,3,11,4,0,93,92,1,0,0,0,94,95,1,0,0,0,95,93,1,0, + 0,0,95,96,1,0,0,0,96,14,1,0,0,0,97,99,7,2,0,0,98,97,1,0,0,0,99,100, + 1,0,0,0,100,98,1,0,0,0,100,101,1,0,0,0,101,102,1,0,0,0,102,103,6, + 6,1,0,103,16,1,0,0,0,104,105,7,3,0,0,105,18,1,0,0,0,106,109,3,17, + 7,0,107,109,3,11,4,0,108,106,1,0,0,0,108,107,1,0,0,0,109,20,1,0, + 0,0,110,113,3,19,8,0,111,113,7,4,0,0,112,110,1,0,0,0,112,111,1,0, + 0,0,113,22,1,0,0,0,114,117,3,21,9,0,115,117,7,5,0,0,116,114,1,0, + 0,0,116,115,1,0,0,0,117,24,1,0,0,0,118,120,7,6,0,0,119,118,1,0,0, + 0,120,121,1,0,0,0,121,119,1,0,0,0,121,122,1,0,0,0,122,123,1,0,0, + 0,123,124,6,11,2,0,124,26,1,0,0,0,125,127,7,7,0,0,126,125,1,0,0, + 0,127,128,1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,28,1,0,0,0, + 130,174,7,8,0,0,131,133,5,47,0,0,132,134,5,47,0,0,133,132,1,0,0, + 0,134,135,1,0,0,0,135,133,1,0,0,0,135,136,1,0,0,0,136,174,1,0,0, + 0,137,139,5,42,0,0,138,140,5,42,0,0,139,138,1,0,0,0,140,141,1,0, + 0,0,141,139,1,0,0,0,141,142,1,0,0,0,142,174,1,0,0,0,143,145,5,45, + 0,0,144,146,5,45,0,0,145,144,1,0,0,0,146,147,1,0,0,0,147,145,1,0, + 0,0,147,148,1,0,0,0,148,174,1,0,0,0,149,151,5,43,0,0,150,152,5,43, + 0,0,151,150,1,0,0,0,152,153,1,0,0,0,153,151,1,0,0,0,153,154,1,0, + 0,0,154,174,1,0,0,0,155,157,5,61,0,0,156,158,5,61,0,0,157,156,1, + 0,0,0,158,159,1,0,0,0,159,157,1,0,0,0,159,160,1,0,0,0,160,174,1, + 0,0,0,161,163,5,62,0,0,162,164,5,62,0,0,163,162,1,0,0,0,164,165, + 1,0,0,0,165,163,1,0,0,0,165,166,1,0,0,0,166,174,1,0,0,0,167,168, + 5,82,0,0,168,169,5,69,0,0,169,170,5,77,0,0,170,171,5,65,0,0,171, + 172,5,82,0,0,172,174,5,75,0,0,173,130,1,0,0,0,173,131,1,0,0,0,173, + 137,1,0,0,0,173,143,1,0,0,0,173,149,1,0,0,0,173,155,1,0,0,0,173, + 161,1,0,0,0,173,167,1,0,0,0,174,178,1,0,0,0,175,177,5,32,0,0,176, + 175,1,0,0,0,177,180,1,0,0,0,178,176,1,0,0,0,178,179,1,0,0,0,179, + 181,1,0,0,0,180,178,1,0,0,0,181,182,3,27,12,0,182,183,1,0,0,0,183, + 184,6,13,3,0,184,30,1,0,0,0,185,229,7,8,0,0,186,188,5,47,0,0,187, + 189,5,47,0,0,188,187,1,0,0,0,189,190,1,0,0,0,190,188,1,0,0,0,190, + 191,1,0,0,0,191,229,1,0,0,0,192,194,5,42,0,0,193,195,5,42,0,0,194, + 193,1,0,0,0,195,196,1,0,0,0,196,194,1,0,0,0,196,197,1,0,0,0,197, + 229,1,0,0,0,198,200,5,45,0,0,199,201,5,45,0,0,200,199,1,0,0,0,201, + 202,1,0,0,0,202,200,1,0,0,0,202,203,1,0,0,0,203,229,1,0,0,0,204, + 206,5,43,0,0,205,207,5,43,0,0,206,205,1,0,0,0,207,208,1,0,0,0,208, + 206,1,0,0,0,208,209,1,0,0,0,209,229,1,0,0,0,210,212,5,61,0,0,211, + 213,5,61,0,0,212,211,1,0,0,0,213,214,1,0,0,0,214,212,1,0,0,0,214, + 215,1,0,0,0,215,229,1,0,0,0,216,218,5,62,0,0,217,219,5,62,0,0,218, + 217,1,0,0,0,219,220,1,0,0,0,220,218,1,0,0,0,220,221,1,0,0,0,221, + 229,1,0,0,0,222,223,5,82,0,0,223,224,5,69,0,0,224,225,5,77,0,0,225, + 226,5,65,0,0,226,227,5,82,0,0,227,229,5,75,0,0,228,185,1,0,0,0,228, + 186,1,0,0,0,228,192,1,0,0,0,228,198,1,0,0,0,228,204,1,0,0,0,228, + 210,1,0,0,0,228,216,1,0,0,0,228,222,1,0,0,0,229,233,1,0,0,0,230, + 232,8,7,0,0,231,230,1,0,0,0,232,235,1,0,0,0,233,231,1,0,0,0,233, + 234,1,0,0,0,234,236,1,0,0,0,235,233,1,0,0,0,236,237,3,27,12,0,237, + 238,1,0,0,0,238,239,6,14,3,0,239,32,1,0,0,0,240,242,8,9,0,0,241, + 240,1,0,0,0,242,243,1,0,0,0,243,241,1,0,0,0,243,244,1,0,0,0,244, + 34,1,0,0,0,245,246,3,5,1,0,246,36,1,0,0,0,247,249,7,6,0,0,248,247, + 1,0,0,0,249,250,1,0,0,0,250,248,1,0,0,0,250,251,1,0,0,0,251,252, + 1,0,0,0,252,253,6,17,2,0,253,38,1,0,0,0,254,256,7,7,0,0,255,254, + 1,0,0,0,256,257,1,0,0,0,257,255,1,0,0,0,257,258,1,0,0,0,258,259, + 1,0,0,0,259,260,6,18,4,0,260,40,1,0,0,0,261,263,8,9,0,0,262,261, + 1,0,0,0,263,264,1,0,0,0,264,262,1,0,0,0,264,265,1,0,0,0,265,42,1, + 0,0,0,266,268,7,6,0,0,267,266,1,0,0,0,268,269,1,0,0,0,269,267,1, + 0,0,0,269,270,1,0,0,0,270,271,1,0,0,0,271,272,6,20,2,0,272,44,1, + 0,0,0,273,275,7,7,0,0,274,273,1,0,0,0,275,276,1,0,0,0,276,274,1, + 0,0,0,276,277,1,0,0,0,277,278,1,0,0,0,278,279,6,21,4,0,279,46,1, + 0,0,0,36,0,1,2,71,76,80,88,95,100,108,112,116,121,128,135,141,147, + 153,159,165,173,178,190,196,202,208,214,220,228,233,243,250,257, + 264,269,276,5,5,1,0,2,2,0,6,0,0,0,1,0,2,0,0 + ] + +class XwinNmrPKLexer(Lexer): + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + NUM_OF_DIM_MODE = 1 + COMMENT_MODE = 2 + + Num_of_dim = 1 + Integer = 2 + Float = 3 + COMMENT = 4 + SPACE = 5 + RETURN = 6 + SECTION_COMMENT = 7 + LINE_COMMENT = 8 + Annotation = 9 + Integer_ND = 10 + SPACE_ND = 11 + RETURN_ND = 12 + Any_name = 13 + SPACE_CM = 14 + RETURN_CM = 15 + + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + + modeNames = [ "DEFAULT_MODE", "NUM_OF_DIM_MODE", "COMMENT_MODE" ] + + literalNames = [ "", + "'# PEAKLIST_DIMENSION'" ] + + symbolicNames = [ "", + "Num_of_dim", "Integer", "Float", "COMMENT", "SPACE", "RETURN", + "SECTION_COMMENT", "LINE_COMMENT", "Annotation", "Integer_ND", + "SPACE_ND", "RETURN_ND", "Any_name", "SPACE_CM", "RETURN_CM" ] + + ruleNames = [ "Num_of_dim", "Integer", "Float", "DEC_DOT_DEC", "DEC_DIGIT", + "DECIMAL", "COMMENT", "ALPHA", "ALPHA_NUM", "START_CHAR", + "NAME_CHAR", "SPACE", "RETURN", "SECTION_COMMENT", "LINE_COMMENT", + "Annotation", "Integer_ND", "SPACE_ND", "RETURN_ND", "Any_name", + "SPACE_CM", "RETURN_CM" ] + + grammarFileName = "XwinNmrPKLexer.g4" + + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.13.0") + self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) + self._actions = None + self._predicates = None + + diff --git a/wwpdb/utils/nmr/pk/XwinNmrPKParser.py b/wwpdb/utils/nmr/pk/XwinNmrPKParser.py new file mode 100644 index 00000000..251f5013 --- /dev/null +++ b/wwpdb/utils/nmr/pk/XwinNmrPKParser.py @@ -0,0 +1,650 @@ +# Generated from XwinNmrPKParser.g4 by ANTLR 4.13.0 +# encoding: utf-8 +from antlr4 import * +from io import StringIO +import sys +if sys.version_info[1] > 5: + from typing import TextIO +else: + from typing.io import TextIO + +def serializedATN(): + return [ + 4,1,15,107,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,1,0,1, + 0,1,0,4,0,16,8,0,11,0,12,0,17,1,0,4,0,21,8,0,11,0,12,0,22,1,0,4, + 0,26,8,0,11,0,12,0,27,5,0,30,8,0,10,0,12,0,33,9,0,1,0,1,0,1,1,1, + 1,5,1,39,8,1,10,1,12,1,42,9,1,1,1,1,1,1,2,1,2,1,2,1,2,1,3,1,3,1, + 3,1,3,1,3,1,3,1,3,3,3,57,8,3,1,3,5,3,60,8,3,10,3,12,3,63,9,3,1,3, + 1,3,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,3,4,76,8,4,1,4,5,4,79,8, + 4,10,4,12,4,82,9,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,5,1,5,1,5,1,5,1, + 5,1,5,3,5,97,8,5,1,5,5,5,100,8,5,10,5,12,5,103,9,5,1,5,1,5,1,5,0, + 0,6,0,2,4,6,8,10,0,1,1,1,15,15,115,0,31,1,0,0,0,2,36,1,0,0,0,4,45, + 1,0,0,0,6,49,1,0,0,0,8,66,1,0,0,0,10,85,1,0,0,0,12,30,3,2,1,0,13, + 30,3,4,2,0,14,16,3,6,3,0,15,14,1,0,0,0,16,17,1,0,0,0,17,15,1,0,0, + 0,17,18,1,0,0,0,18,30,1,0,0,0,19,21,3,8,4,0,20,19,1,0,0,0,21,22, + 1,0,0,0,22,20,1,0,0,0,22,23,1,0,0,0,23,30,1,0,0,0,24,26,3,10,5,0, + 25,24,1,0,0,0,26,27,1,0,0,0,27,25,1,0,0,0,27,28,1,0,0,0,28,30,1, + 0,0,0,29,12,1,0,0,0,29,13,1,0,0,0,29,15,1,0,0,0,29,20,1,0,0,0,29, + 25,1,0,0,0,30,33,1,0,0,0,31,29,1,0,0,0,31,32,1,0,0,0,32,34,1,0,0, + 0,33,31,1,0,0,0,34,35,5,0,0,1,35,1,1,0,0,0,36,40,5,4,0,0,37,39,5, + 13,0,0,38,37,1,0,0,0,39,42,1,0,0,0,40,38,1,0,0,0,40,41,1,0,0,0,41, + 43,1,0,0,0,42,40,1,0,0,0,43,44,7,0,0,0,44,3,1,0,0,0,45,46,5,1,0, + 0,46,47,5,10,0,0,47,48,5,12,0,0,48,5,1,0,0,0,49,50,5,2,0,0,50,51, + 5,3,0,0,51,52,5,3,0,0,52,53,5,3,0,0,53,54,5,3,0,0,54,56,5,3,0,0, + 55,57,5,3,0,0,56,55,1,0,0,0,56,57,1,0,0,0,57,61,1,0,0,0,58,60,5, + 9,0,0,59,58,1,0,0,0,60,63,1,0,0,0,61,59,1,0,0,0,61,62,1,0,0,0,62, + 64,1,0,0,0,63,61,1,0,0,0,64,65,5,6,0,0,65,7,1,0,0,0,66,67,5,2,0, + 0,67,68,5,3,0,0,68,69,5,3,0,0,69,70,5,3,0,0,70,71,5,3,0,0,71,72, + 5,3,0,0,72,73,5,3,0,0,73,75,5,3,0,0,74,76,5,3,0,0,75,74,1,0,0,0, + 75,76,1,0,0,0,76,80,1,0,0,0,77,79,5,9,0,0,78,77,1,0,0,0,79,82,1, + 0,0,0,80,78,1,0,0,0,80,81,1,0,0,0,81,83,1,0,0,0,82,80,1,0,0,0,83, + 84,5,6,0,0,84,9,1,0,0,0,85,86,5,2,0,0,86,87,5,3,0,0,87,88,5,3,0, + 0,88,89,5,3,0,0,89,90,5,3,0,0,90,91,5,3,0,0,91,92,5,3,0,0,92,93, + 5,3,0,0,93,94,5,3,0,0,94,96,5,3,0,0,95,97,5,3,0,0,96,95,1,0,0,0, + 96,97,1,0,0,0,97,101,1,0,0,0,98,100,5,9,0,0,99,98,1,0,0,0,100,103, + 1,0,0,0,101,99,1,0,0,0,101,102,1,0,0,0,102,104,1,0,0,0,103,101,1, + 0,0,0,104,105,5,6,0,0,105,11,1,0,0,0,12,17,22,27,29,31,40,56,61, + 75,80,96,101 + ] + +class XwinNmrPKParser ( Parser ): + + grammarFileName = "XwinNmrPKParser.g4" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + + sharedContextCache = PredictionContextCache() + + literalNames = [ "", "'# PEAKLIST_DIMENSION'" ] + + symbolicNames = [ "", "Num_of_dim", "Integer", "Float", "COMMENT", + "SPACE", "RETURN", "SECTION_COMMENT", "LINE_COMMENT", + "Annotation", "Integer_ND", "SPACE_ND", "RETURN_ND", + "Any_name", "SPACE_CM", "RETURN_CM" ] + + RULE_xwinnmr_pk = 0 + RULE_comment = 1 + RULE_dimension = 2 + RULE_peak_2d = 3 + RULE_peak_3d = 4 + RULE_peak_4d = 5 + + ruleNames = [ "xwinnmr_pk", "comment", "dimension", "peak_2d", "peak_3d", + "peak_4d" ] + + EOF = Token.EOF + Num_of_dim=1 + Integer=2 + Float=3 + COMMENT=4 + SPACE=5 + RETURN=6 + SECTION_COMMENT=7 + LINE_COMMENT=8 + Annotation=9 + Integer_ND=10 + SPACE_ND=11 + RETURN_ND=12 + Any_name=13 + SPACE_CM=14 + RETURN_CM=15 + + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.13.0") + self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) + self._predicates = None + + + + + class Xwinnmr_pkContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def EOF(self): + return self.getToken(XwinNmrPKParser.EOF, 0) + + def comment(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(XwinNmrPKParser.CommentContext) + else: + return self.getTypedRuleContext(XwinNmrPKParser.CommentContext,i) + + + def dimension(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(XwinNmrPKParser.DimensionContext) + else: + return self.getTypedRuleContext(XwinNmrPKParser.DimensionContext,i) + + + def peak_2d(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(XwinNmrPKParser.Peak_2dContext) + else: + return self.getTypedRuleContext(XwinNmrPKParser.Peak_2dContext,i) + + + def peak_3d(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(XwinNmrPKParser.Peak_3dContext) + else: + return self.getTypedRuleContext(XwinNmrPKParser.Peak_3dContext,i) + + + def peak_4d(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(XwinNmrPKParser.Peak_4dContext) + else: + return self.getTypedRuleContext(XwinNmrPKParser.Peak_4dContext,i) + + + def getRuleIndex(self): + return XwinNmrPKParser.RULE_xwinnmr_pk + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterXwinnmr_pk" ): + listener.enterXwinnmr_pk(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitXwinnmr_pk" ): + listener.exitXwinnmr_pk(self) + + + + + def xwinnmr_pk(self): + + localctx = XwinNmrPKParser.Xwinnmr_pkContext(self, self._ctx, self.state) + self.enterRule(localctx, 0, self.RULE_xwinnmr_pk) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 31 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 22) != 0): + self.state = 29 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,3,self._ctx) + if la_ == 1: + self.state = 12 + self.comment() + pass + + elif la_ == 2: + self.state = 13 + self.dimension() + pass + + elif la_ == 3: + self.state = 15 + self._errHandler.sync(self) + _alt = 1 + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt == 1: + self.state = 14 + self.peak_2d() + + else: + raise NoViableAltException(self) + self.state = 17 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,0,self._ctx) + + pass + + elif la_ == 4: + self.state = 20 + self._errHandler.sync(self) + _alt = 1 + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt == 1: + self.state = 19 + self.peak_3d() + + else: + raise NoViableAltException(self) + self.state = 22 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,1,self._ctx) + + pass + + elif la_ == 5: + self.state = 25 + self._errHandler.sync(self) + _alt = 1 + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt == 1: + self.state = 24 + self.peak_4d() + + else: + raise NoViableAltException(self) + self.state = 27 + self._errHandler.sync(self) + _alt = self._interp.adaptivePredict(self._input,2,self._ctx) + + pass + + + self.state = 33 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 34 + self.match(XwinNmrPKParser.EOF) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class CommentContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def COMMENT(self): + return self.getToken(XwinNmrPKParser.COMMENT, 0) + + def RETURN_CM(self): + return self.getToken(XwinNmrPKParser.RETURN_CM, 0) + + def EOF(self): + return self.getToken(XwinNmrPKParser.EOF, 0) + + def Any_name(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Any_name) + else: + return self.getToken(XwinNmrPKParser.Any_name, i) + + def getRuleIndex(self): + return XwinNmrPKParser.RULE_comment + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterComment" ): + listener.enterComment(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitComment" ): + listener.exitComment(self) + + + + + def comment(self): + + localctx = XwinNmrPKParser.CommentContext(self, self._ctx, self.state) + self.enterRule(localctx, 2, self.RULE_comment) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 36 + self.match(XwinNmrPKParser.COMMENT) + self.state = 40 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==13: + self.state = 37 + self.match(XwinNmrPKParser.Any_name) + self.state = 42 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 43 + _la = self._input.LA(1) + if not(_la==-1 or _la==15): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class DimensionContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def Num_of_dim(self): + return self.getToken(XwinNmrPKParser.Num_of_dim, 0) + + def Integer_ND(self): + return self.getToken(XwinNmrPKParser.Integer_ND, 0) + + def RETURN_ND(self): + return self.getToken(XwinNmrPKParser.RETURN_ND, 0) + + def getRuleIndex(self): + return XwinNmrPKParser.RULE_dimension + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterDimension" ): + listener.enterDimension(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitDimension" ): + listener.exitDimension(self) + + + + + def dimension(self): + + localctx = XwinNmrPKParser.DimensionContext(self, self._ctx, self.state) + self.enterRule(localctx, 4, self.RULE_dimension) + try: + self.enterOuterAlt(localctx, 1) + self.state = 45 + self.match(XwinNmrPKParser.Num_of_dim) + self.state = 46 + self.match(XwinNmrPKParser.Integer_ND) + self.state = 47 + self.match(XwinNmrPKParser.RETURN_ND) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class Peak_2dContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def Integer(self): + return self.getToken(XwinNmrPKParser.Integer, 0) + + def Float(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Float) + else: + return self.getToken(XwinNmrPKParser.Float, i) + + def RETURN(self): + return self.getToken(XwinNmrPKParser.RETURN, 0) + + def Annotation(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Annotation) + else: + return self.getToken(XwinNmrPKParser.Annotation, i) + + def getRuleIndex(self): + return XwinNmrPKParser.RULE_peak_2d + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterPeak_2d" ): + listener.enterPeak_2d(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitPeak_2d" ): + listener.exitPeak_2d(self) + + + + + def peak_2d(self): + + localctx = XwinNmrPKParser.Peak_2dContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_peak_2d) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 49 + self.match(XwinNmrPKParser.Integer) + self.state = 50 + self.match(XwinNmrPKParser.Float) + self.state = 51 + self.match(XwinNmrPKParser.Float) + self.state = 52 + self.match(XwinNmrPKParser.Float) + self.state = 53 + self.match(XwinNmrPKParser.Float) + self.state = 54 + self.match(XwinNmrPKParser.Float) + self.state = 56 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==3: + self.state = 55 + self.match(XwinNmrPKParser.Float) + + + self.state = 61 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==9: + self.state = 58 + self.match(XwinNmrPKParser.Annotation) + self.state = 63 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 64 + self.match(XwinNmrPKParser.RETURN) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class Peak_3dContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def Integer(self): + return self.getToken(XwinNmrPKParser.Integer, 0) + + def Float(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Float) + else: + return self.getToken(XwinNmrPKParser.Float, i) + + def RETURN(self): + return self.getToken(XwinNmrPKParser.RETURN, 0) + + def Annotation(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Annotation) + else: + return self.getToken(XwinNmrPKParser.Annotation, i) + + def getRuleIndex(self): + return XwinNmrPKParser.RULE_peak_3d + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterPeak_3d" ): + listener.enterPeak_3d(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitPeak_3d" ): + listener.exitPeak_3d(self) + + + + + def peak_3d(self): + + localctx = XwinNmrPKParser.Peak_3dContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_peak_3d) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 66 + self.match(XwinNmrPKParser.Integer) + self.state = 67 + self.match(XwinNmrPKParser.Float) + self.state = 68 + self.match(XwinNmrPKParser.Float) + self.state = 69 + self.match(XwinNmrPKParser.Float) + self.state = 70 + self.match(XwinNmrPKParser.Float) + self.state = 71 + self.match(XwinNmrPKParser.Float) + self.state = 72 + self.match(XwinNmrPKParser.Float) + self.state = 73 + self.match(XwinNmrPKParser.Float) + self.state = 75 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==3: + self.state = 74 + self.match(XwinNmrPKParser.Float) + + + self.state = 80 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==9: + self.state = 77 + self.match(XwinNmrPKParser.Annotation) + self.state = 82 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 83 + self.match(XwinNmrPKParser.RETURN) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class Peak_4dContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def Integer(self): + return self.getToken(XwinNmrPKParser.Integer, 0) + + def Float(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Float) + else: + return self.getToken(XwinNmrPKParser.Float, i) + + def RETURN(self): + return self.getToken(XwinNmrPKParser.RETURN, 0) + + def Annotation(self, i:int=None): + if i is None: + return self.getTokens(XwinNmrPKParser.Annotation) + else: + return self.getToken(XwinNmrPKParser.Annotation, i) + + def getRuleIndex(self): + return XwinNmrPKParser.RULE_peak_4d + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterPeak_4d" ): + listener.enterPeak_4d(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitPeak_4d" ): + listener.exitPeak_4d(self) + + + + + def peak_4d(self): + + localctx = XwinNmrPKParser.Peak_4dContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_peak_4d) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 85 + self.match(XwinNmrPKParser.Integer) + self.state = 86 + self.match(XwinNmrPKParser.Float) + self.state = 87 + self.match(XwinNmrPKParser.Float) + self.state = 88 + self.match(XwinNmrPKParser.Float) + self.state = 89 + self.match(XwinNmrPKParser.Float) + self.state = 90 + self.match(XwinNmrPKParser.Float) + self.state = 91 + self.match(XwinNmrPKParser.Float) + self.state = 92 + self.match(XwinNmrPKParser.Float) + self.state = 93 + self.match(XwinNmrPKParser.Float) + self.state = 94 + self.match(XwinNmrPKParser.Float) + self.state = 96 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==3: + self.state = 95 + self.match(XwinNmrPKParser.Float) + + + self.state = 101 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==9: + self.state = 98 + self.match(XwinNmrPKParser.Annotation) + self.state = 103 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 104 + self.match(XwinNmrPKParser.RETURN) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + + + diff --git a/wwpdb/utils/nmr/pk/XwinNmrPKParserListener.py b/wwpdb/utils/nmr/pk/XwinNmrPKParserListener.py new file mode 100644 index 00000000..9cd1df08 --- /dev/null +++ b/wwpdb/utils/nmr/pk/XwinNmrPKParserListener.py @@ -0,0 +1,426 @@ +## +# File: XwinNmrPKParserListener.py +# Date: 05-Dec-2024 +# +# Updates: +""" ParserLister class for XWINNMR PK files. + @author: Masashi Yokochi +""" +import sys +import numpy as np + +from antlr4 import ParseTreeListener + +try: + from wwpdb.utils.nmr.pk.XwinNmrPKParser import XwinNmrPKParser + from wwpdb.utils.nmr.pk.BasePKParserListener import BasePKParserListener + from wwpdb.utils.nmr.mr.ParserListenerUtil import (REPRESENTATIVE_MODEL_ID, + REPRESENTATIVE_ALT_ID, + getPkRow) + +except ImportError: + from nmr.pk.XwinNmrPKParser import XwinNmrPKParser + from nmr.pk.BasePKParserListener import BasePKParserListener + from nmr.mr.ParserListenerUtil import (REPRESENTATIVE_MODEL_ID, + REPRESENTATIVE_ALT_ID, + getPkRow) + + +# This class defines a complete listener for a parse tree produced by XwinNmrPKParser. +class XwinNmrPKParserListener(ParseTreeListener, BasePKParserListener): + + __f1_ppm_col = -1 + __f2_ppm_col = -1 + __f3_ppm_col = -1 + __f4_ppm_col = -1 + __intensity_col = -1 + __volume_col = -1 + + def __init__(self, verbose=True, log=sys.stdout, + representativeModelId=REPRESENTATIVE_MODEL_ID, + representativeAltId=REPRESENTATIVE_ALT_ID, + mrAtomNameMapping=None, + cR=None, caC=None, ccU=None, csStat=None, nefT=None, + reasons=None): + super().__init__(verbose, log, representativeModelId, representativeAltId, + mrAtomNameMapping, cR, caC, ccU, csStat, nefT, reasons) + + self.file_type = 'nm-pea-xwi' + self.software_name = 'XWINNMR' + + # Enter a parse tree produced by XwinNmrPKParser#xwinnmr_pk. + def enterXwinnmr_pk(self, ctx: XwinNmrPKParser.Xwinnmr_pkContext): # pylint: disable=unused-argument + self.enter() + + # Exit a parse tree produced by XwinNmrPKParser#xwinnmr_pk. + def exitXwinnmr_pk(self, ctx: XwinNmrPKParser.Xwinnmr_pkContext): # pylint: disable=unused-argument + + if len(self.spectral_dim) > 0: + for d, v in self.spectral_dim.items(): + for _id, _v in v.items(): + self.acq_dim_id = 1 + for __d, __v in _v.items(): + if 'freq_hint' in __v: + if len(__v['freq_hint']) > 0: + center = np.mean(np.array(__v['freq_hint'])) + + if __v['atom_isotope_number'] is None: + if 125 < center < 130: + __v['atom_type'] = 'C' + __v['atom_isotope_number'] = 13 + __v['axis_code'] = 'C_aro' + elif 115 < center < 125: + __v['atom_type'] = 'N' + __v['atom_isotope_number'] = 15 + __v['axis_code'] = 'N_ami' + elif 170 < center < 180: + __v['atom_type'] = 'C' + __v['atom_isotope_number'] = 13 + __v['axis_code'] = 'CO' + elif 6 < center < 9: + __v['atom_type'] = 'H' + __v['atom_isotope_number'] = 1 + __v['axis_code'] = 'H_ami_or_aro' + elif 4 < center < 6: + __v['atom_type'] = 'H' + __v['atom_isotope_number'] = 1 + __v['axis_code'] = 'H' + elif 60 < center < 90: + __v['atom_type'] = 'C' + __v['atom_isotope_number'] = 13 + __v['axis_code'] = 'C' + elif 30 < center < 50: + __v['atom_type'] = 'C' + __v['atom_isotope_number'] = 13 + __v['axis_code'] = 'C_ali' + + isotope_number = __v['atom_isotope_number'] + + if isotope_number is not None: + __v['acquisition'] = 'yes' if __d == self.acq_dim_id\ + and (isotope_number == 1 or (isotope_number == 13 and self.exptlMethod == 'SOLID-STATE NMR')) else 'no' + + if __d == 1 and __v['acquisition'] == 'no': + self.acq_dim_id = self.num_of_dim + + __v['under_sampling_type'] = 'not observed' if __v['acquisition'] == 'yes' else 'aliased' + + if __v['spectral_region'] is None and len(__v['freq_hint']) > 0: + atom_type = __v['atom_type'] + if 125 < center < 130 and atom_type == 'C': + __v['spectral_region'] = 'C_aro' + elif 115 < center < 125 and atom_type == 'N': + __v['spectral_region'] = 'N_ami' + elif 170 < center < 180 and atom_type == 'C': + __v['spectral_region'] = 'CO' + elif 6 < center < 9 and atom_type == 'H': + __v['spectral_region'] = 'H_ami_or_aro' + elif 4 < center < 6 and atom_type == 'H': + __v['spectral_region'] = 'H_all' + elif 60 < center < 90 and atom_type == 'C': + __v['spectral_region'] = 'C_all' + elif 30 < center < 50 and atom_type == 'C': + __v['spectral_region'] = 'C_ali' + + if len(__v['freq_hint']) > 0 and d > 2 and __d >= 2\ + and self.exptlMethod != 'SOLID-STATE NMR' and __v['atom_isotope_number'] == 13: + max_ppm = max(__v['freq_hint']) + min_ppm = min(__v['freq_hint']) + width = max_ppm - min_ppm + if center < 100.0 and width < 50.0: + __v['under_sampling_type'] = 'fold' + + del __v['freq_hint'] + + for __v in _v.values(): + if __v['axis_code'] == 'H_ami_or_aro': + has_a = any(___v['spectral_region'] == 'C_aro' for ___v in _v.values()) + __v['axis_code'] = 'H_aro' if has_a else 'H_ami' + if __v['spectral_region'] == 'H_ami_or_aro': + has_a = any(___v['spectral_region'] == 'C_aro' for ___v in _v.values()) + __v['spectral_region'] = 'H_aro' if has_a else 'H_ami' + + if self.debug: + print(f'num_of_dim: {d}, list_id: {_id}') + for __d, __v in _v.items(): + print(f'{__d} {__v}') + + self.exit() + + # Enter a parse tree produced by XwinNmrPKParser#comment. + def enterComment(self, ctx: XwinNmrPKParser.CommentContext): # pylint: disable=unused-argument + pass + + # Exit a parse tree produced by XwinNmrPKParser#comment. + def exitComment(self, ctx: XwinNmrPKParser.CommentContext): + comment = [] + for col in range(20): + if ctx.Any_name(col): + text = str(ctx.Any_name(col)) + comment.append(text) + else: + break + + self.__f1_ppm_col = -1 + self.__f2_ppm_col = -1 + self.__f3_ppm_col = -1 + self.__f4_ppm_col = -1 + self.__intensity_col = -1 + self.__volume_col = -1 + + if 'F1[ppm]' in comment: + self.__f1_ppm_col = comment.index('F1[ppm]') + if 'F2[ppm]' in comment: + self.__f2_ppm_col = comment.index('F2[ppm]') + if 'F3[ppm]' in comment and self.num_of_dim >= 3: + self.__f3_ppm_col = comment.index('F3[ppm]') + if 'F4[ppm]' in comment and self.num_of_dim >= 4: + self.__f4_ppm_col = comment.index('F4[ppm]') + if 'Intensity' in comment: + self.__intensity_col = comment.index('Intensity') + if 'Volume' in comment: + self.__volume_col = comment.index('Volume') + + # Enter a parse tree produced by XwinNmrPKParser#dimension. + def enterDimension(self, ctx: XwinNmrPKParser.DimensionContext): + if ctx.Integer_ND(): + self.num_of_dim = int(str(ctx.Integer_ND())) + self.fillCurrentSpectralDim() + + # Exit a parse tree produced by XwinNmrPKParser#dimension. + def exitDimension(self, ctx: XwinNmrPKParser.DimensionContext): # pylint: disable=unused-argument + pass + + # Enter a parse tree produced by XwinNmrPKParser#peak_2d. + def enterPeak_2d(self, ctx: XwinNmrPKParser.Peak_2dContext): # pylint: disable=unused-argument + self.peaks2D += 1 + + # Exit a parse tree produced by XwinNmrPKParser#peak_2d. + def exitPeak_2d(self, ctx: XwinNmrPKParser.Peak_2dContext): + + if -1 in (self.__f1_ppm_col, self.__f2_ppm_col)\ + or (self.__intensity_col == -1 and self.__volume_col == -1): + self.peaks2D -= 1 + return + + index = int(str(ctx.Integer())) + + if ctx.Float(self.__f1_ppm_col): + f1_ppm = float(str(ctx.Float(self.__f1_ppm_col))) + else: + self.peaks2D -= 1 + return + + if ctx.Float(self.__f2_ppm_col): + f2_ppm = float(str(ctx.Float(self.__f2_ppm_col))) + else: + self.peaks2D -= 1 + return + + intensity = None + if self.__intensity_col != -1 and ctx.Float(self.__intensity_col): + intensity = float(str(ctx.Float(self.__intensity_col))) + + volume = None + if self.__volume_col != -1 and ctx.Float(self.__volume_col): + volume = float(str(ctx.Float(self.__volume_col))) + + annotation = None + if ctx.Annotation(0): + annotation = [] + i = 0 + while ctx.Annotation(i): + annotation.append(str(ctx.Annotation(i))) + i += 1 + annotation = ' '.join(annotation) + + dstFunc = self.validatePeak2D(index, f1_ppm, f2_ppm, None, None, None, None, + None, None, None, None, intensity, None, volume, None) + + if dstFunc is None: + self.peaks2D -= 1 + return + + cur_spectral_dim = self.spectral_dim[self.num_of_dim][self.cur_list_id] + + cur_spectral_dim[1]['freq_hint'].append(f1_ppm) + cur_spectral_dim[2]['freq_hint'].append(f2_ppm) + + if self.createSfDict__: + sf = self.getSf() + + if self.debug: + print(f"subtype={self.cur_subtype} id={self.peaks2D} (index={index}) {dstFunc}") + + if self.createSfDict__ and sf is not None: + sf['index_id'] += 1 + + row = getPkRow(self.cur_subtype, sf['id'], sf['index_id'], + sf['list_id'], self.entryId, dstFunc, + self.authToStarSeq, self.authToOrigSeq, self.offsetHolder, + details=annotation) + sf['loop'].add_data(row) + + # Enter a parse tree produced by XwinNmrPKParser#peak_3d. + def enterPeak_3d(self, ctx: XwinNmrPKParser.Peak_3dContext): # pylint: disable=unused-argument + self.peaks3D += 1 + + # Exit a parse tree produced by XwinNmrPKParser#peak_3d. + def exitPeak_3d(self, ctx: XwinNmrPKParser.Peak_3dContext): + + if -1 in (self.__f1_ppm_col, self.__f2_ppm_col, self.__f3_ppm_col)\ + or (self.__intensity_col == -1 and self.__volume_col == -1): + self.peaks3D -= 1 + return + + index = int(str(ctx.Integer())) + + if ctx.Float(self.__f1_ppm_col): + f1_ppm = float(str(ctx.Float(self.__f1_ppm_col))) + else: + self.peaks3D -= 1 + return + + if ctx.Float(self.__f2_ppm_col): + f2_ppm = float(str(ctx.Float(self.__f2_ppm_col))) + else: + self.peaks3D -= 1 + return + + if ctx.Float(self.__f3_ppm_col): + f3_ppm = float(str(ctx.Float(self.__f3_ppm_col))) + else: + self.peaks3D -= 1 + return + + intensity = None + if self.__intensity_col != -1 and ctx.Float(self.__intensity_col): + intensity = float(str(ctx.Float(self.__intensity_col))) + + volume = None + if self.__volume_col != -1 and ctx.Float(self.__volume_col): + volume = float(str(ctx.Float(self.__volume_col))) + + annotation = None + if ctx.Annotation(0): + annotation = [] + i = 0 + while ctx.Annotation(i): + annotation.append(str(ctx.Annotation(i))) + i += 1 + annotation = ' '.join(annotation) + + dstFunc = self.validatePeak3D(index, f1_ppm, f2_ppm, f3_ppm, None, None, None, None, None, None, + None, None, None, None, None, None, intensity, None, volume, None) + + if dstFunc is None: + self.peaks3D -= 1 + return + + cur_spectral_dim = self.spectral_dim[self.num_of_dim][self.cur_list_id] + + cur_spectral_dim[1]['freq_hint'].append(f1_ppm) + cur_spectral_dim[2]['freq_hint'].append(f2_ppm) + cur_spectral_dim[3]['freq_hint'].append(f3_ppm) + + if self.createSfDict__: + sf = self.getSf() + + if self.debug: + print(f"subtype={self.cur_subtype} id={self.peaks3D} (index={index}) {dstFunc}") + + if self.createSfDict__ and sf is not None: + sf['index_id'] += 1 + + row = getPkRow(self.cur_subtype, sf['id'], sf['index_id'], + sf['list_id'], self.entryId, dstFunc, + self.authToStarSeq, self.authToOrigSeq, self.offsetHolder, + details=annotation) + sf['loop'].add_data(row) + + # Enter a parse tree produced by XwinNmrPKParser#peak_4d. + def enterPeak_4d(self, ctx: XwinNmrPKParser.Peak_4dContext): # pylint: disable=unused-argument + self.peaks4D += 1 + + # Exit a parse tree produced by XwinNmrPKParser#peak_4d. + def exitPeak_4d(self, ctx: XwinNmrPKParser.Peak_4dContext): + + if -1 in (self.__f1_ppm_col, self.__f2_ppm_col, self.__f3_ppm_col, self.__f4_ppm_col)\ + or (self.__intensity_col == -1 and self.__volume_col == -1): + self.peaks4D -= 1 + return + + index = int(str(ctx.Integer())) + + if ctx.Float(self.__f1_ppm_col): + f1_ppm = float(str(ctx.Float(self.__f1_ppm_col))) + else: + self.peaks4D -= 1 + return + + if ctx.Float(self.__f2_ppm_col): + f2_ppm = float(str(ctx.Float(self.__f2_ppm_col))) + else: + self.peaks4D -= 1 + return + + if ctx.Float(self.__f3_ppm_col): + f3_ppm = float(str(ctx.Float(self.__f3_ppm_col))) + else: + self.peaks4D -= 1 + return + + if ctx.Float(self.__f4_ppm_col): + f4_ppm = float(str(ctx.Float(self.__f4_ppm_col))) + else: + self.peaks4D -= 1 + return + + intensity = None + if self.__intensity_col != -1 and ctx.Float(self.__intensity_col): + intensity = float(str(ctx.Float(self.__intensity_col))) + + volume = None + if self.__volume_col != -1 and ctx.Float(self.__volume_col): + volume = float(str(ctx.Float(self.__volume_col))) + + annotation = None + if ctx.Annotation(0): + annotation = [] + i = 0 + while ctx.Annotation(i): + annotation.append(str(ctx.Annotation(i))) + i += 1 + annotation = ' '.join(annotation) + + dstFunc = self.validatePeak4D(index, f1_ppm, f2_ppm, f3_ppm, f4_ppm, None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, intensity, None, volume, None) + + if dstFunc is None: + self.peaks4D -= 1 + return + + cur_spectral_dim = self.spectral_dim[self.num_of_dim][self.cur_list_id] + + cur_spectral_dim[1]['freq_hint'].append(f1_ppm) + cur_spectral_dim[2]['freq_hint'].append(f2_ppm) + cur_spectral_dim[3]['freq_hint'].append(f3_ppm) + cur_spectral_dim[4]['freq_hint'].append(f4_ppm) + + if self.createSfDict__: + sf = self.getSf() + + if self.debug: + print(f"subtype={self.cur_subtype} id={self.peaks4D} (index={index}) {dstFunc}") + + if self.createSfDict__ and sf is not None: + sf['index_id'] += 1 + + row = getPkRow(self.cur_subtype, sf['id'], sf['index_id'], + sf['list_id'], self.entryId, dstFunc, + self.authToStarSeq, self.authToOrigSeq, self.offsetHolder, + details=annotation) + sf['loop'].add_data(row) + + +# del XwinNmrPKParser diff --git a/wwpdb/utils/nmr/pk/XwinNmrPKReader.py b/wwpdb/utils/nmr/pk/XwinNmrPKReader.py new file mode 100644 index 00000000..535c99be --- /dev/null +++ b/wwpdb/utils/nmr/pk/XwinNmrPKReader.py @@ -0,0 +1,216 @@ +## +# XwinNmrPKReader.py +# +# Update: +## +""" A collection of classes for parsing XWINNMR PK files. +""" +import sys +import os + +from antlr4 import InputStream, CommonTokenStream, ParseTreeWalker + +try: + from wwpdb.utils.nmr.mr.LexerErrorListener import LexerErrorListener + from wwpdb.utils.nmr.mr.ParserErrorListener import ParserErrorListener + from wwpdb.utils.nmr.pk.XwinNmrPKLexer import XwinNmrPKLexer + from wwpdb.utils.nmr.pk.XwinNmrPKParser import XwinNmrPKParser + from wwpdb.utils.nmr.pk.XwinNmrPKParserListener import XwinNmrPKParserListener + from wwpdb.utils.nmr.mr.ParserListenerUtil import (coordAssemblyChecker, + MAX_ERROR_REPORT, + REPRESENTATIVE_MODEL_ID, + REPRESENTATIVE_ALT_ID) + from wwpdb.utils.nmr.io.CifReader import CifReader + from wwpdb.utils.nmr.ChemCompUtil import ChemCompUtil + from wwpdb.utils.nmr.BMRBChemShiftStat import BMRBChemShiftStat + from wwpdb.utils.nmr.NEFTranslator.NEFTranslator import NEFTranslator +except ImportError: + from nmr.mr.LexerErrorListener import LexerErrorListener + from nmr.mr.ParserErrorListener import ParserErrorListener + from nmr.pk.XwinNmrPKLexer import XwinNmrPKLexer + from nmr.pk.XwinNmrPKParser import XwinNmrPKParser + from nmr.pk.XwinNmrPKParserListener import XwinNmrPKParserListener + from nmr.mr.ParserListenerUtil import (coordAssemblyChecker, + MAX_ERROR_REPORT, + REPRESENTATIVE_MODEL_ID, + REPRESENTATIVE_ALT_ID) + from nmr.io.CifReader import CifReader + from nmr.ChemCompUtil import ChemCompUtil + from nmr.BMRBChemShiftStat import BMRBChemShiftStat + from nmr.NEFTranslator.NEFTranslator import NEFTranslator + + +class XwinNmrPKReader: + """ Accessor methods for parsing XWINNMR PK files. + """ + + def __init__(self, verbose=True, log=sys.stdout, + representativeModelId=REPRESENTATIVE_MODEL_ID, + representativeAltId=REPRESENTATIVE_ALT_ID, + mrAtomNameMapping=None, + cR=None, caC=None, ccU=None, csStat=None, nefT=None, + reasons=None): + self.__verbose = verbose + self.__lfh = log + self.__debug = False + + self.__maxLexerErrorReport = MAX_ERROR_REPORT + self.__maxParserErrorReport = MAX_ERROR_REPORT + + self.__representativeModelId = representativeModelId + self.__representativeAltId = representativeAltId + self.__mrAtomNameMapping = mrAtomNameMapping + + # CCD accessing utility + self.__ccU = ChemCompUtil(verbose, log) if ccU is None else ccU + + if cR is not None and caC is None: + caC = coordAssemblyChecker(verbose, log, representativeModelId, representativeAltId, + cR, self.__ccU, None, None, fullCheck=False) + + self.__cR = cR + self.__caC = caC + + # BMRB chemical shift statistics + self.__csStat = BMRBChemShiftStat(verbose, log, self.__ccU) if csStat is None else csStat + + # NEFTranslator + self.__nefT = NEFTranslator(verbose, log, self.__ccU, self.__csStat) if nefT is None else nefT + if nefT is None: + self.__nefT.set_remediation_mode(True) + + # reasons for re-parsing request from the previous trial + self.__reasons = reasons + + def setDebugMode(self, debug): + self.__debug = debug + + def setLexerMaxErrorReport(self, maxErrReport): + self.__maxLexerErrorReport = maxErrReport + + def setParserMaxErrorReport(self, maxErrReport): + self.__maxParserErrorReport = maxErrReport + + def parse(self, pkFilePath, cifFilePath=None, isFilePath=True, + createSfDict=False, originalFileName=None, listIdCounter=None, entryId=None): + """ Parse XWINNMR PK file. + @return: XwinNmrPKParserListener for success or None otherwise, ParserErrorListener, LexerErrorListener. + """ + + ifh = None + + try: + + if isFilePath: + pkString = None + + if not os.access(pkFilePath, os.R_OK): + if self.__verbose: + self.__lfh.write(f"XwinNmrPKReader.parse() {pkFilePath} is not accessible.\n") + return None, None, None + + ifh = open(pkFilePath, 'r') # pylint: disable=consider-using-with + input = InputStream(ifh.read()) + + else: + pkFilePath, pkString = None, pkFilePath + + if pkString is None or len(pkString) == 0: + if self.__verbose: + self.__lfh.write("XwinNmrPKReader.parse() Empty string.\n") + return None, None, None + + input = InputStream(pkString) + + if cifFilePath is not None: + if not os.access(cifFilePath, os.R_OK): + if self.__verbose: + self.__lfh.write(f"XwinNmrPKReader.parse() {cifFilePath} is not accessible.\n") + return None, None, None + + if self.__cR is None: + self.__cR = CifReader(self.__verbose, self.__lfh) + if not self.__cR.parse(cifFilePath): + return None, None, None + + lexer = XwinNmrPKLexer(input) + lexer.removeErrorListeners() + + lexer_error_listener = LexerErrorListener(pkFilePath, maxErrorReport=self.__maxLexerErrorReport) + lexer.addErrorListener(lexer_error_listener) + + messageList = lexer_error_listener.getMessageList() + + if messageList is not None and self.__verbose: + for description in messageList: + self.__lfh.write(f"[Syntax error] line {description['line_number']}:{description['column_position']} {description['message']}\n") + if 'input' in description: + self.__lfh.write(f"{description['input']}\n") + self.__lfh.write(f"{description['marker']}\n") + + stream = CommonTokenStream(lexer) + parser = XwinNmrPKParser(stream) + # try with simpler/faster SLL prediction mode + # parser._interp.predictionMode = PredictionMode.SLL # pylint: disable=protected-access + parser.removeErrorListeners() + parser_error_listener = ParserErrorListener(pkFilePath, maxErrorReport=self.__maxParserErrorReport) + parser.addErrorListener(parser_error_listener) + tree = parser.xwinnmr_pk() + + walker = ParseTreeWalker() + listener = XwinNmrPKParserListener(self.__verbose, self.__lfh, + self.__representativeModelId, + self.__representativeAltId, + self.__mrAtomNameMapping, + self.__cR, self.__caC, + self.__ccU, self.__csStat, self.__nefT, + self.__reasons) + listener.setDebugMode(self.__debug) + listener.createSfDict(createSfDict) + if createSfDict: + if originalFileName is not None: + listener.setOriginaFileName(originalFileName) + if listIdCounter is not None: + listener.setListIdCounter(listIdCounter) + if entryId is not None: + listener.setEntryId(entryId) + walker.walk(listener, tree) + + messageList = parser_error_listener.getMessageList() + + if messageList is not None and self.__verbose: + for description in messageList: + self.__lfh.write(f"[Syntax error] line {description['line_number']}:{description['column_position']} {description['message']}\n") + if 'input' in description: + self.__lfh.write(f"{description['input']}\n") + self.__lfh.write(f"{description['marker']}\n") + + if self.__verbose: + if listener.warningMessage is not None and len(listener.warningMessage) > 0: + print('\n'.join(listener.warningMessage)) + if isFilePath: + print(listener.getContentSubtype()) + + return listener, parser_error_listener, lexer_error_listener + + except IOError as e: + if self.__verbose: + self.__lfh.write(f"+XwinNmrPKReader.parse() ++ Error - {str(e)}\n") + return None, None, None + # pylint: disable=unreachable + """ debug code + except Exception as e: + if self.__verbose and isFilePath: + self.__lfh.write(f"+XwinNmrPKReader.parse() ++ Error - {pkFilePath!r} - {str(e)}\n") + return None, None, None + """ + finally: + if isFilePath and ifh is not None: + ifh.close() + + +if __name__ == "__main__": + reader = XwinNmrPKReader(True) + reader.setDebugMode(True) + reader.parse('../../tests-nmr/mock-data-bruker-peak-list/tspp-xwin.txt', + '../../tests-nmr/mock-data-remediation/2js7/2js7.cif') diff --git a/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/CharmmCRDLexer.g4 b/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/CharmmCRDLexer.g4 index 5ca6a0cc..25af6de1 100644 --- a/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/CharmmCRDLexer.g4 +++ b/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/CharmmCRDLexer.g4 @@ -40,7 +40,7 @@ fragment SIMPLE_NAME: START_CHAR NAME_CHAR*; SPACE: [ \t\r\n]+ -> skip; CONTINUE: '-'+ SPACE -> skip; ENCLOSE_COMMENT: '{' (ENCLOSE_COMMENT | .)*? '}' -> channel(HIDDEN); -SECTION_COMMENT: ('#' | '!' | ';' | '\\' | '/' '/'+ | '*' '*'+ | '-' '-'+ | '+' '+'+ | '=' '='+ | '>' '>'+ | 'REMARK') ' '* [\r\n]+ -> channel(HIDDEN); +SECTION_COMMENT: (';' | '\\' | '/' '/'+ | '*' '*'+ | '-' '-'+ | '+' '+'+ | '=' '='+ | '>' '>'+ | 'REMARK') ' '* [\r\n]+ -> channel(HIDDEN); LINE_COMMENT: (';' | '\\' | '/' '/'+ | '*' '*'+ | '-' '-'+ | '+' '+'+ | '=' '='+ | '>' '>'+ | 'REMARK') ~[\r\n]* -> channel(HIDDEN); mode COMMENT_MODE; diff --git a/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/XwinNmrPKLexer.g4 b/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/XwinNmrPKLexer.g4 new file mode 100644 index 00000000..5da86edc --- /dev/null +++ b/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/XwinNmrPKLexer.g4 @@ -0,0 +1,63 @@ +/* + XwinNmr PK (Spectral peak list) lexer grammar for ANTLR v4. + Copyright 2024 Masashi Yokochi + +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +lexer grammar XwinNmrPKLexer; + +Num_of_dim: '# PEAKLIST_DIMENSION' -> pushMode(NUM_OF_DIM_MODE); + +Integer: ('+' | '-')? DECIMAL; +Float: ('+' | '-')? (DECIMAL | DEC_DOT_DEC); +//Real: ('+' | '-')? (DECIMAL | DEC_DOT_DEC) ([Ee] ('+' | '-')? DECIMAL)?; +fragment DEC_DOT_DEC: (DECIMAL '.' DECIMAL) | ('.' DECIMAL); +fragment DEC_DIGIT: [0-9]; +fragment DECIMAL: DEC_DIGIT+; + +COMMENT: ('*' | '#' | '!')+ -> mode(COMMENT_MODE); + +//Simple_name: SIMPLE_NAME; +//Residue_number: Integer; +//Residue_name: SIMPLE_NAME; +//Atom_name: ALPHA_NUM ATM_NAME_CHAR*; + +fragment ALPHA: [A-Za-z]; +fragment ALPHA_NUM: ALPHA | DEC_DIGIT; +fragment START_CHAR: ALPHA_NUM | '_' | '-' | '+' | '.' | '*' | '#' | '?'; +fragment NAME_CHAR: START_CHAR | '\'' | '"'; +//fragment ATM_NAME_CHAR: ALPHA_NUM | '\''; +//fragment SIMPLE_NAME: START_CHAR NAME_CHAR*; + +SPACE: [ \t]+ -> skip; +RETURN: [\r\n]+; + +SECTION_COMMENT: (';' | '\\' | '/' '/'+ | '*' '*'+ | '-' '-'+ | '+' '+'+ | '=' '='+ | '>' '>'+ | 'REMARK') ' '* RETURN -> channel(HIDDEN); +LINE_COMMENT: (';' | '\\' | '/' '/'+ | '*' '*'+ | '-' '-'+ | '+' '+'+ | '=' '='+ | '>' '>'+ | 'REMARK') ~[\r\n]* RETURN -> channel(HIDDEN); + +Annotation: ~[ \t\r\n]+; + +mode NUM_OF_DIM_MODE; + +Integer_ND: Integer; + +SPACE_ND: [ \t]+ -> skip; +RETURN_ND: [\r\n]+ -> mode(DEFAULT_MODE); + +mode COMMENT_MODE; + +Any_name: ~[ \t\r\n]+; + +SPACE_CM: [ \t]+ -> skip; +RETURN_CM: [\r\n]+ -> mode(DEFAULT_MODE); + diff --git a/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/XwinNmrPKParser.g4 b/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/XwinNmrPKParser.g4 new file mode 100644 index 00000000..987696d7 --- /dev/null +++ b/wwpdb/utils/tests-nmr/antlr-grammars-v4.10/XwinNmrPKParser.g4 @@ -0,0 +1,54 @@ +/* + XwinNmr PK (Spectral peak list) parser grammar for ANTLR v4. + Copyright 2024 Masashi Yokochi + +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +parser grammar XwinNmrPKParser; + +options { tokenVocab=XwinNmrPKLexer; } + +xwinnmr_pk: + ( + comment | + dimension | + peak_2d+ | + peak_3d+ | + peak_4d+ + )* + EOF; + +comment: + COMMENT Any_name* (RETURN_CM | EOF); + +dimension: + Num_of_dim Integer_ND RETURN_ND; + +peak_2d: + Integer + Float Float + Float Float + Float Float? Annotation* RETURN; + +peak_3d: + Integer + Float Float Float + Float Float Float + Float Float? Annotation* RETURN; + +peak_4d: + Integer + Float Float Float Float + Float Float Float Float + Float Float? Annotation* RETURN; +