class PbamAutoParser: """ELEC pbam-auto specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/pbam-auto.html keyword = CLiteral("pbam-auto") | CLiteral("pbam") # .setParseAction(GenericToken.check_depricated) grammar = (keyword & ZeroOrMore(ElecToken.name) & ZeroOrMore(PbToken.thr3dmap) & ZeroOrMore(PbToken.diff) & ZeroOrMore(PbToken.dx) & ZeroOrMore(PbToken.grid2d) & ZeroOrMore(PbToken.gridpts) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(PbToken.ntraj) & ZeroOrMore(PbToken.pbc) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(PbToken.randorient) & ZeroOrMore(PbToken.runname) & ZeroOrMore(PbToken.runtype) & ZeroOrMore(PbToken.salt) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(PbToken.term) & ZeroOrMore(PbToken.termcombine) & ZeroOrMore(PbToken.units) & ZeroOrMore(PbToken.xyz))
class MgManualParser: """ELEC mg-manual specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/mg-manual.html integer_val = ApbsLegacyInput.get_integer_grammar() nlev = Group(CLiteral("nlev") - integer_val) grammar = (CLiteral("mg-manual") & ZeroOrMore(ElecToken.name) & ZeroOrMore(ElecToken.bcfl) & ZeroOrMore(GenericToken.calcenergy) & ZeroOrMore(GenericToken.calcforce) & ZeroOrMore(ElecToken.chgm) & ZeroOrMore(ElecToken.dime) & ZeroOrMore(ElecToken.etol) & ZeroOrMore(ElecToken.gcent) & ZeroOrMore(ElecToken.glen) & ZeroOrMore(GenericToken.grid) & ZeroOrMore(ElecToken.ion) & ZeroOrMore(ElecToken.pbe) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(nlev) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(ElecToken.srfm) & ZeroOrMore(GenericToken.swin) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(ElecToken.usemap) & ZeroOrMore(ElecToken.write) & ZeroOrMore(ElecToken.writemat))
def apolar_parser(self): """Setup the tokens and grammar for the APOLAR section. :return: a dictionary containing the APOLAR section of the input file :rtype: dict """ grammar = (ZeroOrMore(ElecToken.name) & ZeroOrMore(GenericToken.bconc) & ZeroOrMore(GenericToken.calcenergy) & ZeroOrMore(GenericToken.calcforce) & ZeroOrMore(ApolarToken.dpos) & ZeroOrMore(GenericToken.gamma) & ZeroOrMore(GenericToken.grid) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(ApolarToken.press) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(ApolarToken.srfm) & ZeroOrMore(GenericToken.swin) & ZeroOrMore(GenericToken.temp)) def format_apolar(results: ParseResults): return self.format_section(results, "APOLAR") return Group( Suppress(CLiteral("APOLAR")) - grammar - Suppress(CLiteral("END"))).setParseAction(format_apolar)
class GeoflowAutoParser: """ELEC geoflow-auto specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/geoflow-auto.html number_val = ApbsLegacyInput.get_number_grammar() press = Group(CLiteral("press") - number_val) vdwdisp = Group(CLiteral("vdwdisp") - oneOf("0 1")) keyword = CLiteral("geoflow-auto") | CLiteral("geoflow") # .setParseAction(GenericToken.check_depricated) grammar = ( keyword & ZeroOrMore(ElecToken.name) & ZeroOrMore(ElecToken.bcfl) & ZeroOrMore(GenericToken.bconc) & ZeroOrMore(ElecToken.etol) & ZeroOrMore(GenericToken.gamma) & ZeroOrMore(GenericToken.grid ) # . setParseAction(GenericToken.check_depricated) & ZeroOrMore(ElecToken.pbe) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(press) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(vdwdisp))
def elec_parser(self): """Setup the tokens and grammar for the ELEC section. :return: a dictionary containing the APOLAR section of the input file :rtype: dict """ grammar = ( TabiParser.grammar | FeManualParser.grammar | GeoflowAutoParser.grammar | MgAutoParser.grammar | MgManualParser.grammar | MgParaParser.grammar | MgDummyParser.grammar | PbamAutoParser.grammar | PbsamAutoParser.grammar | PygbeParser.grammar ) def format_elec(results: ParseResults): return self.format_section(results, "ELEC") return Group( Suppress(CLiteral("ELEC")) - grammar - Suppress(CLiteral("END")) ).setParseAction(format_elec)
def print_parser(self): """Setup the tokens and grammar for the PRINT section.""" identifier = ApbsLegacyInput.get_identifier_grammar() # tokens/grammars: choices = oneOf("elecEnergy elecForce apolEnergy apolForce", caseless=True) expr = identifier + Optional( OneOrMore(oneOf("+ -") + identifier) + ZeroOrMore(oneOf("+ -") + identifier)) grammar = Group(choices - expr) def format_print(results: ParseResults): """Format the PRINT section of the APBS input file. :param results ParseResults: pyparsing results of matching grammar :return: a dictionary of the PRINT section of the input file :rtype: dict Example: Convert the following: print elecEnergy complex - mol2 - mol1 end To: 'PRINT': {0: { 'elecenergy': ['complex', '-', 'mol2', '-', 'mol1'] } } """ section = "PRINT" if section not in self.final_output: self.final_output[section] = {} idx = len(self.final_output[section]) self.final_output[section][idx] = {} for row in results[0]: LOGGER.debug("TYPE: %s", type(row)) for item in row: LOGGER.debug("type item: %s, item: %s", type(item), item) if isinstance(item, str): key = item.lower() LOGGER.debug("key: %s", key) if key not in self.final_output[section][idx].keys(): self.final_output[section][idx][key] = row[1:] break else: # NOTE: UGLY but this is how to break out of the inner and # outer loop as documented at: # https://note.nkmk.me/en/python-break-nested-loops break break return self.final_output value = Group( Suppress(CLiteral("PRINT")) - grammar - Suppress(CLiteral("END"))).setParseAction(format_print) return value
class ApolarToken: """APOLAR specific tokens/grammars that can be used by other classes.""" # https://apbs.readthedocs.io/en/latest/using/input/apolar/index.html number_val = ApbsLegacyInput.get_number_grammar() dpos = Group(CLiteral("dpos") - number_val) press = Group(CLiteral("press") - number_val) srfm = Group(CLiteral("srfm") - oneOf("sacc", caseless=True))
class FeManualParser: """ELEC fe-manual specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/fe-manual.html identifier = ApbsLegacyInput.get_identifier_grammar() integer_val = ApbsLegacyInput.get_integer_grammar() number_val = ApbsLegacyInput.get_number_grammar() akeyPRE_options = oneOf("unif geom", caseless=True) akeyPRE = Group(CLiteral("akeyPRE") - akeyPRE_options) akeySOLVE_options = oneOf("resi", caseless=True) akeySOLVE = Group(CLiteral("akeySOLVE") - akeySOLVE_options) domainLength = Group(CLiteral("domainLength") - ElecToken.grid_floats) ekey_options = oneOf("simp glob global frac", caseless=True) ekey = Group(CLiteral("ekey") - ekey_options).setParseAction( GenericToken.check_depricated ) maxsolve = Group(CLiteral("maxsolve") - number_val) maxvert = Group(CLiteral("maxvert") - number_val) targetNum = Group(CLiteral("targetNum") - integer_val) targetRes = Group(CLiteral("targetRes") - number_val) usemesh = Group(CLiteral("usemesh") - identifier) grammar = ( CLiteral("fe-manual") & ZeroOrMore(ElecToken.name) & ZeroOrMore(akeyPRE) & ZeroOrMore(akeySOLVE) & ZeroOrMore(ElecToken.async_value) & ZeroOrMore(ElecToken.bcfl) & ZeroOrMore(GenericToken.calcenergy) & ZeroOrMore(GenericToken.calcforce) & ZeroOrMore(ElecToken.chgm) & ZeroOrMore(domainLength) & ZeroOrMore(ekey) & ZeroOrMore(ElecToken.etol) & ZeroOrMore(ElecToken.ion) & ZeroOrMore(ElecToken.pbe) & ZeroOrMore(maxsolve) & ZeroOrMore(maxvert) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(ElecToken.srfm) & ZeroOrMore(GenericToken.swin) & ZeroOrMore(targetNum) & ZeroOrMore(targetRes) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(ElecToken.usemap) & ZeroOrMore(usemesh) & ZeroOrMore(ElecToken.write) )
def __init__(self): """Setup parsing tokens and grammar for the APBS input file format.""" # The FINAL_OUTPUT is a dictionary produced after parsing a file # using the grammar and processing rules. self.final_output = {} # The highest level grammar to parse the READ, ELEC, APOLAR, and # PRINT sections until the QUIT keyword is found. self.grammar = OneOrMore(self.read_parser()) + OneOrMore( self.apolar_parser() | self.elec_parser() ) + ZeroOrMore(self.print_parser()) + Suppress(CLiteral("QUIT")) | ( # The following is one way to "narrow down" errors in an input # file. It was adopted from: # https://web.archive.org/web/20160821175151/http://pyparsing.wikispaces.com/share/view/30875955 # The idea is that the parsers above will succeed or the # following will succeed and set the ParseSyntaxException # stating that the token in the file is "unknown" and will # show the line and column where the parser stopped. It does # not always point out subtle errors like when a key is used # in a section that does not support it. For example, using # a keyword from pbam-auto in an ELEC section that specifies # using tabi-auto type. empty - ~Word(printables).setName("<unknown>") )
class MgAutoParser: """ELEC mg-auto specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/mg-auto.html grammar = (CLiteral("mg-auto") & ZeroOrMore(ElecToken.name) & ZeroOrMore(ElecToken.bcfl) & ZeroOrMore(GenericToken.calcenergy) & ZeroOrMore(GenericToken.calcforce) & ZeroOrMore(ElecToken.cgcent) & ZeroOrMore(ElecToken.cglen) & ZeroOrMore(ElecToken.chgm) & ZeroOrMore(ElecToken.dime) & ZeroOrMore(ElecToken.etol) & ZeroOrMore(ElecToken.fgcent) & ZeroOrMore(ElecToken.fglen) & ZeroOrMore(ElecToken.ion) & ZeroOrMore(ElecToken.pbe) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(ElecToken.srfm) & ZeroOrMore(GenericToken.swin) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(ElecToken.usemap) & ZeroOrMore(ElecToken.write) & ZeroOrMore(ElecToken.writemat))
class MgDummyParser: """ELEC mg-dummy specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/mg-dummy.html grammar = ( CLiteral("mg-dummy") & ZeroOrMore(ElecToken.name) & ZeroOrMore(ElecToken.bcfl) & ZeroOrMore(GenericToken.calcenergy ) # .setParseAction(GenericToken.check_depricated) & ZeroOrMore(GenericToken.calcforce ) # .setParseAction(GenericToken.check_depricated) & ZeroOrMore(ElecToken.chgm) & ZeroOrMore(ElecToken.dime) & ZeroOrMore(ElecToken.gcent) & ZeroOrMore(ElecToken.glen) & ZeroOrMore(GenericToken.grid) & ZeroOrMore(ElecToken.ion) & ZeroOrMore( ElecToken.nlev) # .setParseAction(GenericToken.check_depricated) & ZeroOrMore(ElecToken.pbe) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(ElecToken.srfm) & ZeroOrMore(GenericToken.swin) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(ElecToken.write))
def read_parser(self): """Setup the tokens and grammar for the READ section.""" # https://apbs.readthedocs.io/en/latest/using/input/read.html path_val = ApbsLegacyInput.get_path_grammar() # tokens/grammars: file_fmt = oneOf("dx gz", caseless=True) charge = Group(CLiteral("charge") - file_fmt - path_val) diel = Group( CLiteral("diel") - file_fmt - path_val - path_val - path_val ) kappa = Group(CLiteral("kappa") - file_fmt - path_val) mesh = Group(CLiteral("mesh") - CLiteral("mcsf") - path_val) mol_format = oneOf("pqr pdb", caseless=True) mol = Group(CLiteral("mol") - mol_format - path_val) parm_format = oneOf("flat xml", caseless=True) parm = Group(CLiteral("parm") - parm_format - path_val) pot = Group(CLiteral("pot") - file_fmt - path_val) groups = ["charge", "diel", "kappa", "mol", "parm", "pot"] grammar = Group( OneOrMore(mol) & ZeroOrMore( mesh ) # .setParseAction(GenericToken.check_depricated) & ZeroOrMore(charge) & ZeroOrMore(diel) & ZeroOrMore(kappa) & ZeroOrMore(parm) & ZeroOrMore(pot) ) def format_read(results: ParseResults): return self.format_read_section(results, groups) return Group( Suppress(CLiteral("READ")) - grammar - Suppress(CLiteral("END")) ).setParseAction(format_read)
class MgParaParser: """ELEC mg-para specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/mg-para.html number_val = ApbsLegacyInput.get_number_grammar() pdime = Group(CLiteral("pdime") - ElecToken.grid_floats) ofrac = Group(CLiteral("ofrac") - number_val) grammar = ( CLiteral("mg-para") & ZeroOrMore(ElecToken.name) & ZeroOrMore(ElecToken.async_value) & ZeroOrMore(ElecToken.bcfl) & ZeroOrMore(GenericToken.calcenergy) & ZeroOrMore(GenericToken.calcforce) & ZeroOrMore(ElecToken.cgcent) & ZeroOrMore(ElecToken.cglen) & ZeroOrMore(ElecToken.chgm) & ZeroOrMore(ElecToken.dime) & ZeroOrMore(ElecToken.etol) & ZeroOrMore(ElecToken.fgcent) & ZeroOrMore(ElecToken.fglen) & ZeroOrMore(ElecToken.ion) & ZeroOrMore(ElecToken.pbe) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(ofrac) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(pdime) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(ElecToken.srfm) & ZeroOrMore(GenericToken.swin) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(ElecToken.usemap) & ZeroOrMore(ElecToken.write) & ZeroOrMore(ElecToken.writemat) )
class TabiParser: """ELEC tabi specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/tabi.html integer_val = ApbsLegacyInput.get_integer_grammar() number_val = ApbsLegacyInput.get_number_grammar() # TODO: Should this be replaced which a check to make # sure that "number_val is between 0.0 and 1.0" mac = Group(CLiteral("mac") - number_val) mesh = Group(CLiteral("mesh") - oneOf("0 1 2 ses skin")) outdata = Group(CLiteral("outdata") - oneOf("0 1")) tree_n0 = Group(CLiteral("tree_n0") - integer_val) tree_order = Group(CLiteral("tree_order") - integer_val) grammar = (CLiteral("tabi") & ZeroOrMore(ElecToken.name) & ZeroOrMore(ElecToken.ion) & ZeroOrMore(mac) & ZeroOrMore(mesh) & ZeroOrMore(GenericToken.mol) & ZeroOrMore(outdata) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(GenericToken.sdens) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(GenericToken.srad) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(tree_n0) & ZeroOrMore(tree_order))
class PbsamAutoParser: """ELEC pbsam-auto specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/pbsam-auto.html number_val = ApbsLegacyInput.get_number_grammar() path_val = ApbsLegacyInput.get_path_grammar() # pbsam-auto specific Keywords exp = Group(CLiteral("exp") - path_val) imat = Group(CLiteral("imat") - path_val) surf = Group(CLiteral("surf") - path_val) tolsp = Group(CLiteral("tolsp") - number_val) keyword = CLiteral("pbsam-auto") | CLiteral("pbsam") # .setParseAction(GenericToken.check_depricated) grammar = ( keyword & ZeroOrMore(ElecToken.name) & ZeroOrMore(PbToken.thr3dmap) & ZeroOrMore(PbToken.diff) & ZeroOrMore(PbToken.dx) & ZeroOrMore(exp) & ZeroOrMore(PbToken.grid2d) & ZeroOrMore(imat) & ZeroOrMore(PbToken.ntraj) & ZeroOrMore(PbToken.pbc) & ZeroOrMore(ElecToken.pdie) & ZeroOrMore(PbToken.randorient) & ZeroOrMore(PbToken.runname) & ZeroOrMore(PbToken.runtype) & ZeroOrMore(PbToken.salt) & ZeroOrMore(ElecToken.sdie) & ZeroOrMore(surf) & ZeroOrMore(GenericToken.temp) & ZeroOrMore(PbToken.term) & ZeroOrMore(PbToken.termcombine) & ZeroOrMore(tolsp) & ZeroOrMore(PbToken.units) & ZeroOrMore(PbToken.xyz) )
class PbToken: """ELEC pbam-auto and pbsam-auto specific tokens/grammars.""" identifier = ApbsLegacyInput.get_identifier_grammar() integer_val = ApbsLegacyInput.get_integer_grammar() number_val = ApbsLegacyInput.get_number_grammar() path_val = ApbsLegacyInput.get_path_grammar() thr3dmap = Group(CLiteral("3dmap") - path_val) diff = Group( CLiteral("diff") - (CLiteral("stat") | Group(CLiteral("move") - number_val - number_val) | CLiteral("rot") - number_val)) dx = Group(CLiteral("dx") - path_val) grid2d = Group( CLiteral("grid2d") - Group(path_val - oneOf("x y z", caseless=True) - number_val)) # .setDebug() gridpts = Group(CLiteral("gridpts") - integer_val) ntraj = Group(CLiteral("ntraj") - integer_val) pbc = Group(CLiteral("pbc") - number_val) randorient = CLiteral("randorient") runname = Group(CLiteral("runname") - Word(alphanums + "_")) runtype_options = oneOf("energyforce electrostatics dynamics", caseless=True) runtype = Group(CLiteral("runtype") - runtype_options) # TODO: value of number_val should be 0.00 to 0.15? salt = Group(CLiteral("salt") - number_val) term_pos_options = oneOf("x<= x>= y<= y>= z<= z>= r<= r>=", caseless=True) term_contact = Group(CLiteral("contact") - path_val) term_pos = Group(term_pos_options - number_val - identifier) term_time = Group(CLiteral("time") - number_val) term = Group(CLiteral("term") + (term_contact | term_pos | term_time)) # .setDebug() termcombine = Group( CLiteral("termcombine") - oneOf("and or", caseless=True)) units = Group(CLiteral("units") - oneOf("kcalmol jmol kT", caseless=True)) xyz = Group(CLiteral("xyz") - Group(identifier - path_val))
class PygbeParser: """ELEC pygbe specific tokens/grammars.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/pygbe.html grammar = CLiteral("pygbe") & ZeroOrMore(ElecToken.name)
class ElecToken: """ELEC specific tokens/grammars that can be used by other classes.""" # https://apbs.readthedocs.io/en/latest/using/input/elec/index.html # The following tokens are used by at least 2 of the parser types with # the same format and rules identifier = ApbsLegacyInput.get_identifier_grammar() integer_val = ApbsLegacyInput.get_integer_grammar() number_val = ApbsLegacyInput.get_number_grammar() path_val = ApbsLegacyInput.get_path_grammar() name = Group(CLiteral("name") - identifier) grid_floats = Group(number_val * 3) grid_ints = Group(integer_val * 3) mol_id = Group(CLiteral("mol") - integer_val) async_value = Group(CLiteral("async") - integer_val) bcfl_options = oneOf("focus map mdh mem sdh zero", caseless=True) bcfl = Group(CLiteral("bcfl") - bcfl_options) cgcent = Group(CLiteral("cgcent") - (mol_id | grid_floats)) cglen = Group(CLiteral("cglen") - grid_floats) chgm_options = oneOf("spl0 spl2", caseless=True) chgm = Group(CLiteral("chgm") - chgm_options) dime = Group(CLiteral("dime") - grid_ints) etol = Group(CLiteral("etol") - number_val) fgcent = Group(CLiteral("fgcent") - (mol_id | grid_floats)) fglen = Group(CLiteral("fglen") - grid_floats) gcent = Group(CLiteral("gcent") - (mol_id | grid_floats)) glen = Group(CLiteral("glen") - grid_floats) # Are charge, conc, and radius ALL required? ion_charge = Group(CLiteral("charge") - number_val) ion_conc = Group(CLiteral("conc") - number_val) ion_radius = Group(CLiteral("radius") - number_val) ion = Group(CLiteral("ion") - ion_charge & ion_conc & ion_radius) nlev = Group(CLiteral("nlev") - number_val) # TODO: I think only 1 of these are allowed (not ZeroOrMore) pbe = Group(oneOf("lpbe lrpbe npbe nrpbe", caseless=True)) # TODO: Number must be >= 1 pdie = Group(CLiteral("pdie") - number_val).setParseAction( check_range(1.0)) # NOTE: Should be a value between 78-80? sdie = Group(CLiteral("sdie") - number_val) srfm_options = oneOf("mol smol spl2", caseless=True) srfm = Group(CLiteral("srfm") - srfm_options) usemap_options = oneOf("diel kappa charge", caseless=True) usemap = Group(CLiteral("usemap") - Group(usemap_options - integer_val)) write_type_options = oneOf( "charge " "pot " "smol " "sspl " "vdw " "ivdw " "lap " "edens " "ndens " "qdens " "dielx " "diely " "dielz " "kappa", caseless=True, ) write_format_options = oneOf("avs dx flat gz uhbd", caseless=True) write = Group( CLiteral("write") - Group(write_type_options - write_format_options - path_val)) writemat = Group( CLiteral("writemat") - oneOf("poisson", caseless=True) - path_val)
class GenericToken: """Generic tokens/grammars that can be used by other classes.""" @staticmethod def check_depricated(instring: str, loc: int, tokenlist: ParseResults) -> ParseResults: """Possibly using a depricated keyword or value. Try to be produce a helpful error messsage. :param instring str: the string that may be using a depricated value :param loc int: the character offset into string :return: the original or updated ParseResults :rtype: ParseResults """ depricated_values = {"ekey": "glob", "bcfl": "mem"} substitute_values = {"glob": "global", "mem": "mdh"} if isinstance(tokenlist, ParseResults): if (isinstance(tokenlist[0], ParseResults) and len(tokenlist[0]) == 2): # We have a key and value key = tokenlist[0][0] value = tokenlist[0][1] if key in depricated_values: LOGGER.warning( "WARNING: Depricated value (%s) for key " "(%s) at offset (%s)", value, key, loc, ) if value in substitute_values: new_value = substitute_values[value] # NOTE: Unfortunatly, the location is the # offset from the begining of instring # so we don't have a line count. # Find the line number, column, and # offending line with this hack :-( count = 0 idx = 1 lineno = 0 column = 0 line = "" for data in instring.splitlines(): if count > loc: break if key in data and value in data: line = data lineno = idx column = data.find(value) + 1 count += len(data) + 1 idx += 1 LOGGER.warning( ApbsLegacyInput.banner_message( lineno, column, line, f"WARNING: Substituting new value, {new_value}" f", for {value}", )) # Substitute the depricated value with correct value tokenlist[0][1] = new_value return tokenlist number_val = ApbsLegacyInput.get_number_grammar() bconc = Group(CLiteral("bconc") - number_val) calc_options = oneOf("no total comps", caseless=True) calcenergy = Group(CLiteral("calcenergy") - calc_options) calcforce = Group(CLiteral("calcforce") - calc_options) gamma = Group(CLiteral("gamma") - number_val) grid_coord = Group(number_val * 3) grid = Group(CLiteral("grid") - grid_coord) mol = Group(CLiteral("mol") - number_val) sdens = Group(CLiteral("sdens") - number_val) srad = Group(CLiteral("srad") - number_val) swin = Group(CLiteral("swin") - number_val) temp = Group(CLiteral("temp") - number_val)