def parseRightTerminal(self, peeledStr): # parse the right terminal try: res, start, end = BigSmilesPattern._closer.scanString( peeledStr).__next__() except: errorMsg( self.rawStr, len(self.rawStr) - 1, 'Error', 'unrecognized element encountered during parsing the right bonding descriptor' ) raise BigSMILES_StoObjError if 'BigSMILES_Bondtype' not in res.keys(): self.rightEnd = None else: try: self.rightEnd = BigSMILES_Bond(res, S_bond='u', Bond_Dict=self.Bond_Dict, item=None) except: self.tmpHolder = len(res.rawStr) raise BigSMILES_BondInconsistencyError if len(res.rawStr) > 0: peeledStr = peeledStr[:-len(res.rawStr)] else: peeledStr = peeledStr[:] return peeledStr
def parseError(self,tmpStr,base_pos,pos): if tmpStr[0] == '(': #raise Exception(errorMsg(self.rawStr,base_pos+pos,'unbalanced parenthesis')) print(errorMsg(self.rawStr,base_pos+pos,'Error','in parsing branch, unbalanced parenthesis or illegal expression within branch')) raise SmilesError elif tmpStr[0] == ')': print(errorMsg(self.rawStr,base_pos+pos,'Error','unbalanced parenthesis')) raise SmilesError else: #raise Exception(errorMsg(self.rawStr,base_pos+pos,'cannot recognize element')) print(errorMsg(self.rawStr,base_pos+pos,'Error','cannot recognize element')) raise SmilesError
def parseRightTerminal(self, peeledStr): # parse the right terminal try: res, start, end = BigSmilesPattern._closer.scanString( peeledStr).__next__() except: print( errorMsg( self.rawStr, len(self.rawStr) - 1, 'Error', 'unrecognized element encountered during parsing the right bonding descriptor' )) raise BigSMILES_StoObjError if res.rawStr == '': self.rightEnd = None else: # the right end bond is perceived as if it is directly attached to the next segment # ...[$/1]}ABC... ==> ...;/ABC} try: self.rightEnd = BigSMILES_Bond(res, isFirst=False, Bond_Dict=self.Bond_Dict, item=None) except: #print(errorMsg(inStr,openerLen+1+start,'Error','Inconsistency in the right-end bonding descriptor')) self.tmpHolder = len(res.rawStr) raise BigSMILES_BondInconsistencyError # TODO!!! correct error handling if len(res.rawStr) > 0: peeledStr = peeledStr[:-len(res.rawStr)] else: peeledStr = peeledStr[:] return peeledStr
def addBigSmilesBondAtom(self,res,prevAtom,pos,prevBond): if 'BigSMILES_Bond' in res.keys(): _type = 'BigSMILES_Bond' # else: # _type = 'BigSMILES_ladderBond' # add the BigSMILES bonding descriptor as if it is an atom self.atomCount = self.atomCount + 1 nodeId = self.atomCount self.G.add_node(nodeId) self.G.nodes[nodeId]['rawStr'] = res.rawStr self.G.nodes[nodeId]['_type'] = _type self.G.nodes[nodeId]['neighList'] = list() self.G.nodes[nodeId]['pos'] = pos self.G.nodes[nodeId]['atom'] = _type self.G.nodes[nodeId]['chiral'] = '' isFirst = False if prevAtom == None: isFirst = True try: self.G.nodes[nodeId]['BigSMILES_Bond'] = BigSMILES_Bond(res,isFirst=isFirst,Bond_Dict=self.Bond_Dict,item=nodeId) except: print(errorMsg(self.rawStr,pos,'Error','Inconsistency between bonding descriptor')) raise BigSMILES_BondInconsistencyError if prevBond != None: if prevBond != self.G.nodes[nodeId]['BigSMILES_Bond'].getS_bond(isFirst=False): if self.G.nodes[prevAtom]['_type'] == 'BigSMILES_StoObj': print(errorMsg(self.rawStr,pos,'Error','Inconsistent bond trailing a stochastic object')) else: print(errorMsg(self.rawStr,pos,'Error','A BigSMILES bonding descriptor should not be trailing a SMILES bond')) raise BigSMILES_BondInconsistencyError currentAtom = nodeId if isFirst: prevBond = self.G.nodes[nodeId]['BigSMILES_Bond'].getS_bond(isFirst=True) return currentAtom,prevBond else: prevBond = self.G.nodes[nodeId]['BigSMILES_Bond'].getS_bond(isFirst=False) self.createEdge(prevAtom,currentAtom,prevBond) prevBond = None return currentAtom,prevBond
def addBigSmilesBondAtom(self, res, prevAtom, pos, prevBond): if 'BigSMILES_Bond' in res.keys(): _type = 'BigSMILES_Bond' # else: # _type = 'BigSMILES_ladderBond' # add the BigSMILES bonding descriptor as if it is an atom self.atomCount = self.atomCount + 1 nodeId = self.atomCount self.G.add_node(nodeId) self.G.nodes[nodeId]['rawStr'] = res.rawStr self.G.nodes[nodeId]['_type'] = _type self.G.nodes[nodeId]['neighList'] = list() self.G.nodes[nodeId]['pos'] = pos self.G.nodes[nodeId]['atom'] = _type self.G.nodes[nodeId]['chiral'] = '' isFirst = False if prevAtom == None: isFirst = True if isFirst: S_bond = 'u' else: if prevBond == None: prevBond = '-' S_bond = prevBond try: self.G.nodes[nodeId]['BigSMILES_Bond'] = BigSMILES_Bond( res, S_bond, Bond_Dict=self.Bond_Dict, item=nodeId) except: errorMsg(self.rawStr, pos, 'Error', 'Inconsistency between bonding descriptor') raise BigSMILES_BondInconsistencyError currentAtom = nodeId if prevAtom != None: self.createEdge(prevAtom, currentAtom, prevBond) prevBond = None return currentAtom, prevBond
def parseOne(self,res,level,base_pos,pos,prevBond,prevAtom): # if 'BigSMILES_ladderBond' in res.keys() or 'BigSMILES_Bond' in res.keys(): if 'BigSMILES_Bond' in res.keys(): # if prevBond != None: # print(errorMsg(self.rawStr,base_pos+pos,'Error','A BigSMILES bond should not be trailing a SMILES bond.')) # raise BigSMILESError try: prevAtom,prevBond = self.addBigSmilesBondAtom(res,prevAtom,base_pos+pos,prevBond) except BigSMILES_BondInconsistencyError: raise BigSMILESError # prevBond = None return prevBond,prevAtom elif 'BigSMILES_StoObj' in res.keys(): # if prevBond != None and self.G.nodes[prevAtom]['_type'] != 'BigSMILES_StoObj': # print(errorMsg(self.rawStr,base_pos+pos,'Error','A BigSMILES stochastic object should not be trailing a SMILES bond.')) # raise BigSMILESError # else: try: prevAtom,prevBond = self.addBigSmilesStoObjAtom(res,prevAtom,base_pos+pos,prevBond) except BigSMILES_BondInconsistencyError: print(errorMsg(self.rawStr,base_pos+pos,'Error','Inconsistent bond leading to stochastic object.')) raise BigSMILESError except BigSMILES_StoObjMissingTerminalError: print(errorMsg(self.rawStr,base_pos+pos,'Error','Missing left terminal bonding descriptor for BigSMILES stochastic object connected to other atoms.')) raise BigSMILESError except BigSMILES_StoObjError: print(errorMsg(self.rawStr,base_pos+pos,'Error','In parsing BigSMILES stochastic object ['+str(len(self.StoObj_List)+1)+']')) raise BigSMILESError #prevBond = None return prevBond,prevAtom else: if prevAtom != None and (not 'dot' in res.keys()): # there should be no SMILES bond leading up to the BigSMILES bond # if self.G.nodes[prevAtom]['_type']=='BigSMILES_Bond' and prevBond != None: # print(errorMsg(self.rawStr,base_pos+pos,'Error','A BigSMILES bond should not have trailing SMILES bond.')) # raise BigSMILESError # each BigSMILES Bond ATOM should connect to at most one atom if self.G.nodes[prevAtom]['_type']=='BigSMILES_Bond' and (not not self.G.nodes[prevAtom]['neighList']): print(errorMsg(self.rawStr,base_pos+pos,'Error','A BigSMILES bond should not connect to more than one atom.')) raise BigSMILESError elif self.G.nodes[prevAtom]['_type']=='BigSMILES_StoObj' and 'bond' in res.keys() and prevBond != res.bond: print(errorMsg(self.rawStr,base_pos+pos,'Error','A BigSMILES stochastic object should not have trailing SMILES bond.')) raise BigSMILESError # Parsing a BigSMILES stochastic object will result in an atom and a trailing bond. elif self.G.nodes[prevAtom]['_type']=='BigSMILES_StoObj' and prevBond == None: print(errorMsg(self.rawStr,base_pos+pos-1,'Error','Missing right terminal bonding descriptor for BigSMILES stochastic object connected to other atoms.')) raise BigSMILESError else: return SMILES.parseOne(self,res,level,base_pos,pos,prevBond,prevAtom) else: return SMILES.parseOne(self,res,level,base_pos,pos,prevBond,prevAtom)
def __init__(self, inStr, pos=0, index=list()): # get unique id associated with the object self._uid = BigSMILES_StoObj._count self.index = index self.tmpHolder = 0 self.pos = pos BigSMILES_StoObj._count = BigSMILES_StoObj._count + 1 # Save the string to raw string self.rawStr = inStr # the repUnit and endGrp are containers for the repeating units and end groups in the stochastic object # they are lists of BigSMILESChain self.repUnit = [] self.endGrp = [] # leftEnd and rightEnd are BigSMILESBond objects that holds the bonding descriptor object # of the two ends of the stochastic object (the [$1] or [<=1] descriptors seen in bigsmiles strings) self.leftEnd = None self.rightEnd = None # the Bond_Dict dictionary holds the BigSMILES bonds that had already appeared. # each key correspond to the [$<>][id] key # each value is a list with exactly one element, which is a copy of the first BigSMILES_Bond object that was declared # this dictionary needs to be updated after every repeat unit or end group is parsed self.Bond_Dict = dict() #print(inStr) # parse the two terminal bonding descriptors peeledStr = self.rawStr[1:-1] try: peeledStr, openerLen = self.parseLeftTerminal(peeledStr) except: print( errorMsg( self.rawStr, 1, 'Error', 'unrecognized element encountered during parsing the left bonding descriptor' )) raise BigSMILES_StoObjError try: peeledStr = self.parseRightTerminal(peeledStr) except BigSMILES_BondInconsistencyError: print( errorMsg(self.rawStr, len(self.rawStr) - self.tmpHolder, 'Error', 'Inconsistency in the right-end bonding descriptor')) raise BigSMILES_StoObjError except: print( errorMsg( self.rawStr, len(self.rawStr) - 1, 'Error', 'unrecognized element encountered during parsing the right bonding descriptor' )) raise BigSMILES_StoObjError # Parse the peeledStr to get the two lists try: res = BigSmilesPattern._StoObjLists.parseString(peeledStr) except: print( errorMsg( inStr, openerLen + 1, 'Error', 'unrecognized element encountered during parsing of Stochastic Object' )) raise BigSMILES_StoObjError from BigSMILES_BigSmilesObj import BigSMILES localpos = openerLen + 1 for i in range(len(res.repUnit)): #print(repUnit) repUnit = res.repUnit[i] try: self.repUnit.append( BigSMILES(inStr=repUnit, pos=localpos + pos, UpperBond_Dict=self.Bond_Dict, index=self.index + [i + 1])) except: print( errorMsg( inStr, localpos, 'Error', 'error in parsing repeat unit [' + str(len(self.repUnit) + 1) + ']')) raise BigSMILES_StoObjError else: # update Bond_Dict for key in self.repUnit[-1].Bond_Dict.keys(): if key in self.Bond_Dict: pass else: self.Bond_Dict[key] = list( self.repUnit[-1].Bond_Dict[key][0:1]) localpos += len(self.repUnit[-1].rawStr) + 1 #print(self.repUnit) #print(repUnit) #print('here2') #print(res.endGrp) for i in range(len(res.endGrp)): endGrp = res.endGrp[i] try: self.endGrp.append( BigSMILES(inStr=endGrp, pos=localpos + pos, UpperBond_Dict=self.Bond_Dict, index=self.index + [len(res.repUnit) + i + 1])) except: print( errorMsg( inStr, localpos, 'Error', 'error in parsing end group [' + str(len(self.endGrp) + 1) + ']')) raise BigSMILES_StoObjError else: # update Bond_Dict for key in self.repUnit[-1].Bond_Dict.keys(): if key in self.Bond_Dict: pass else: self.Bond_Dict[key] = list( self.repUnit[-1].Bond_Dict[key][0:1]) localpos += len(self.endGrp[-1].rawStr) + 1 #print('here3') if len(res.rawStr) < len(peeledStr): print( errorMsg( inStr, openerLen + 1 + len(res.rawStr), 'Error', 'unrecognized element encountered during parsing of Stochastic Object' )) raise BigSMILES_StoObjError #print('here4') return None
def parseOne(self, res, level, base_pos, pos, prevBond, prevAtom): # the case next element is a dot if 'dot' in res.keys(): if prevBond != None: # the chain ends with an open trailing bond, append explicit hydrogen to that tmpHAtom = self.createNode('[H]', 'bracket_atom', 'H', pos) self.createEdge(prevAtom, tmpHAtom, prevBond) # check if dot is within branches # support this unstandard notation #if level > 0: # errorMsg(self.rawStr,base_pos+pos,'dot can only be on base level and cannot appear within parenthesizes') # raise SmilesError # clear prevAtom prevAtom = None # the case next element is a branch elif 'branch' in res.keys(): if len(res.rawStr) == 2: errorMsg(self.rawStr, base_pos + pos, 'Warning', 'missing expressions within parenthesizes') #raise Warning if prevAtom == None: errorMsg( self.rawStr, base_pos + pos, 'Error', 'expected ATOM or BOND but got BRANCH, a branch should always follow an atom' ) raise SmilesError if pos == 0: #if level == 0: # errorMsg(self.rawStr,base_pos+pos,'Error','expected ATOM or BOND but got BRANCH, a branch should always follow an atom') # raise SmilesError #else: errorMsg( self.rawStr, base_pos + pos, 'Warning', 'ignoring extra parentheses, expected ATOM or BOND but got BRANCH, a branch should always follow an atom' ) #raise Warning if prevBond != None: errorMsg( self.rawStr, base_pos + pos, 'Warning', 'potentially misleading expression, a branch should follow immediately an ATOM and the BOND on the main chain should come directly before the corresponding ATOM.' ) #expected ATOM but got BRANCH, a branch should always follow an atom')) #raise SmilesError self.parseBranch(res, prevAtom, level, base_pos + pos) # next element is a bond elif 'bond' in res.keys(): if prevAtom == None: errorMsg( self.rawStr, base_pos + pos, 'Error', 'expected ATOM but got BOND, a BOND should always follow an ATOM' ) raise SmilesError #raise Exception(errorMsg(self.rawStr,base_pos+pos,'expected ATOM but got BOND, a bond should always follow an atom')) if prevBond != None: if prevBond == self.addBond(res, prevAtom): #errorMsg(self.rawStr,base_pos+pos,'Warning','ignoring repeated BOND symbol') # raise Warning pass else: errorMsg( self.rawStr, base_pos + pos, 'Error', 'expected ATOM but got BOND, a BOND should always be followed by an ATOM' ) raise SmilesError prevBond = self.addBond(res, prevAtom) # next element is a ring-bond elif 'ringbond' in res.keys(): if prevAtom == None: errorMsg( self.rawStr, base_pos + pos, 'Error', 'expected ATOM but got RING-BOND, a RING-BOND should always follow an ATOM' ) raise SmilesError #raise Exception(errorMsg(self.rawStr,base_pos+pos,'expected ATOM but got RINGBOND, a ring-bond should always follow an atom')) if pos == 0: errorMsg( self.rawStr, base_pos + pos, 'Warning', 'potentially ambiguous expression, a RING-BOND should directly follow an ATOM' ) #raise SmilesError #raise Exception(errorMsg(self.rawStr,base_pos+pos,'expected ATOM or BOND but got RINGBOND, a ring-bond should always follow an atom')) if prevBond != None: errorMsg( self.rawStr, base_pos + pos, 'Warning', 'potentially misleading expression, a RING-BOND should follow immediately an ATOM and the BOND on the main chain should come directly before the corresponding ATOM.' ) #expected ATOM but got RINGBOND, a ring-bond should always follow an atom')) #raise SmilesError try: self.addRingBond(res, prevAtom) except NonmatchingSymbolError: errorMsg( self.rawStr, base_pos + pos, 'Error', 'bond symbol does not match for RING-BONDS with the same ID' ) raise SmilesError #raise Exception(errorMsg(self.rawStr,base_pos+pos,'bond symbol does not match for ring bonds with the same ID')) except NonmatchingTransCisError: errorMsg(self.rawStr, base_pos + pos, 'Error', 'cis-trans in RING-BOND is not consistent') raise SmilesError except SelfLoopError: errorMsg(self.rawStr, base_pos + pos, 'Error', 'self-loops on a single ATOM is not allowed') raise SmilesError except MultiBondError: errorMsg( self.rawStr, base_pos + pos, 'Error', 'more than one BOND between a pair of atoms is found') raise SmilesError # otherwise, the next element is an atom else: try: prevAtom = self.addAtom(res, prevAtom, prevBond, base_pos + pos) except HcountChiralError: errorMsg( self.rawStr, base_pos + pos, 'Error', 'the ATOM cannot be chiral with chirality ' + res.chiral + 'with more than one Hydrogen attached') raise SmilesError except AtomicWeightError: errorMsg(self.rawStr, base_pos + pos, 'Error', 'erroneous isotope specified.') raise SmilesError prevBond = None return prevBond, prevAtom
def finalCheck(self, level, base_pos, pos, prevBond, prevAtom): # entire chain/branch parsed, doing final checks and additional treatment if prevBond != None: # the chain ends with an open trailing bond, append explicit hydrogen to that tmpHAtom = self.createNode('[H]', 'bracket_atom', 'H', pos) self.createEdge(prevAtom, tmpHAtom, prevBond) # deprecated, not considered as error #errorMsg(self.rawStr,base_pos+pos,'Error','missing ATOM, expected ATOM trailing a bond') #raise SmilesError # final check after the main chain is completely parsed if level == 0: # check for any open ring if not not self.ringDict: for i in self.ringDict.keys(): errorMsg( self.rawStr, base_pos + pos, 'Error', 'missing ring-bond, ring ID = ' + str(i) + ' not closed') raise SmilesError # check if app / \ bonds are adjacent to double bonds # for edge in self.G.edges(): # if self.G.edges[edge]['type'] != '\\' and self.G.edges[edge]['type'] != '/': # continue # else: # doubleBond = False # for node1 in edge: # neighbors = self.G.nodes[node1]['neighList'] # for node2 in neighbors: # if node2 in edge: # continue # else: # if self.G.edges[node1,node2]['type'] == '=': # doubleBond = True # break # if doubleBond: # break # if not doubleBond: # errorMsg(self.rawStr,self.G.nodes[node1]['pos'],'Error',r'\ or / should always be adjacent to double bonds.') # raise SmilesError # fill inferrable trans-cis bonds and check consistency for edge in self.G.edges(): if self.G.edges[edge]['type'] != '=': continue else: for node1 in edge: u = 0 d = 0 neighbors = self.G.nodes[node1]['neighList'] unspecified = list() skipflag = False for node2 in neighbors: if node2 in edge: continue else: if self.G.edges[node1, node2]['type'] == '=': skipflag = True break elif self.G.edges[node1, node2]['type'] == '\\': if self.G.edges[node1, node2]['direction'] == ( node1, node2): d += 1 else: u += 1 elif self.G.edges[node1, node2]['type'] == '/': if self.G.edges[node1, node2]['direction'] == ( node1, node2): u += 1 else: d += 1 else: pass if self.G.edges[node1, node2][ 'type'] != '\\' and self.G.edges[ node1, node2]['type'] != '/': unspecified.append(node2) # skip to next node if both connection of the atom are double bonds if skipflag: continue # otherwise check consistency if u > 1 or d > 1: errorMsg( self.rawStr, self.G.nodes[node1]['pos'], 'Error', 'errorneous isomeric specification; cannot have two bonds on an allenal carbon pointing in the same relative "up" or "down" direction.' ) raise SmilesError # complete inferrable up/down specification # case 1: up and down completely agnostic if u + d == 0: continue # case 2: up and down fully specified elif u + d == 2: continue # case 3: only one of the two bonds are specified else: if len(unspecified) > 1: errorMsg( self.rawStr, self.G.nodes[node1]['pos'], 'Error', 'errorneous isomeric specification; an allenal carbon with valency larger than 4 is found.' ) raise SmilesError elif len(unspecified) < 1: pass else: node2 = unspecified[0] if u == 0: self.G.edges[node1, node2]['type'] = '/' else: self.G.edges[node1, node2]['type'] = '\\' self.G.edges[node1, node2]['direction'] = (node1, node2) # check if all chiral centers have 4 bonds flag = False for node in self.G.nodes(): if self.G.nodes[node]['_type'] == 'organic' or self.G.nodes[ node]['_type'] == 'bracket_atom': if self.G.nodes[node]['chiral'] != '': # TODO: allene chiral centers if len(self.G.nodes[node]['neighList']) != 4: errorMsg( self.rawStr, self.G.nodes[node]['pos'], 'Error', 'errorneous chiral center specification, chiral centers should always have 4 distinct neighbors' ) flag = True else: numH = [0, 0, 0] for atom in self.G.nodes[node]['neighList']: if self.G.nodes[atom]['atom'] == 'H': if self.G.nodes[atom][ 'isotope'] == '' or self.G.nodes[ atom]['isotope'] == '1': numH[0] += 1 elif self.G.nodes[atom]['isotope'] == '2': numH[1] += 1 elif self.G.nodes[atom]['isotope'] == '3': numH[2] += 1 if numH[0] > 1 or numH[1] > 1 or numH[2] > 1: errorMsg( self.rawStr, self.G.nodes[node]['pos'], 'Error', 'the ATOM cannot be chiral with chirality ' + self.G.nodes[atom]['chiral'] + 'with more than one H/D/T attached') flag = True else: continue if flag: raise SmilesError
def parseOne(self, res, level, base_pos, pos, prevBond, prevAtom): if prevAtom != None: # each BigSMILES Bond ATOM should connect to at most one atom if self.G.nodes[prevAtom]['_type'] == 'BigSMILES_Bond': if not not self.G.nodes[prevAtom]['neighList']: if 'dot' in res.keys(): pass else: errorMsg( self.rawStr, base_pos + pos, 'Error', 'A BigSMILES bond should not connect to more than one atom.' ) raise BigSMILESError # check if next bond is consistent with the right terminal if 'branch' in res.keys(): errorMsg( self.rawStr, base_pos + pos, 'Error', 'The bonding descriptor must not be followed by a branch.' ) raise BigSMILESError elif 'dot' in res.keys(): pass else: if 'bond' not in res.keys(): trailing_bond = '' if 'ringbond' in res.keys(): trailing_bond = res.ringbondtype else: if prevBond == None: trailing_bond = '-' prevBond = trailing_bond else: trailing_bond = prevBond #print(prevBond) #print(self.G.nodes[prevAtom]['BigSMILES_Bond'].getS_bond()) # if self.G.nodes[prevAtom]['BigSMILES_Bond'].getS_bond( ) == 'u': self.G.nodes[prevAtom]['BigSMILES_Bond'].setS_bond( trailing_bond) if self.G.nodes[prevAtom][ 'BigSMILES_Bond'].checkConsistency( self.Bond_Dict, prevAtom) == -1: errorMsg( self.rawStr, base_pos + pos, 'Error', 'Inconsistent bond trailing the bonding descriptor.' ) raise BigSMILESError if self.G.nodes[prevAtom][ 'BigSMILES_Bond'].getBondOrder( ) != self.G.nodes[prevAtom][ 'BigSMILES_Bond'].getBondOrder( trailing_bond): errorMsg( self.rawStr, base_pos + pos, 'Error', 'Inconsistent bond trailing the bonding descriptor.' ) raise BigSMILESError else: pass if self.G.nodes[prevAtom]['_type'] == 'BigSMILES_StoObj': # Parsing a BigSMILES stochastic object will result in an atom and a prevBond=None. if self.G.nodes[prevAtom]['BigSMILES_StoObj'].rightEnd == None: errorMsg( self.rawStr, base_pos + pos - 1, 'Error', 'Missing right terminal bonding descriptor for BigSMILES stochastic object connected to other atoms.' ) raise BigSMILESError # Parsing a BigSMILES stochastic object will result in an atom and a trailing bond. if self.G.nodes[prevAtom][ 'BigSMILES_StoObj'].rightEnd.S_bond == 'u': errorMsg( self.rawStr, base_pos + pos - 1, 'Error', 'Undefined right terminal bonding descriptor for BigSMILES stochastic object.' ) raise BigSMILESError # check if next bond is consistent with the right terminal if 'branch' in res.keys(): errorMsg( self.rawStr, base_pos + pos, 'Error', 'The stochastic object must not be followed by a branch.' ) raise BigSMILESError elif 'dot' in res.keys(): pass else: if 'bond' not in res.keys(): trailing_bond = '' if 'ringbond' in res.keys(): trailing_bond = res.ringbondtype else: #print(prevBond) if prevBond == None: trailing_bond = '-' prevBond = trailing_bond else: trailing_bond = prevBond #print(prevBond) #print(self.G.nodes[prevAtom]['BigSMILES_Bond'].getS_bond()) # if self.G.nodes[prevAtom][ 'BigSMILES_StoObj'].rightEnd.getBondOrder( ) != self.G.nodes[prevAtom][ 'BigSMILES_StoObj'].rightEnd.getBondOrder( trailing_bond): errorMsg( self.rawStr, base_pos + pos, 'Error', 'Inconsistent bond trailing the stochastic object.' ) raise BigSMILESError else: pass # if 'BigSMILES_ladderBond' in res.keys() or 'BigSMILES_Bond' in res.keys(): if 'BigSMILES_Bond' in res.keys(): try: prevAtom, prevBond = self.addBigSmilesBondAtom( res, prevAtom, base_pos + pos, prevBond) except BigSMILES_BondInconsistencyError: raise BigSMILESError # prevBond = None return prevBond, prevAtom elif 'BigSMILES_StoObj' in res.keys(): try: prevAtom, prevBond = self.addBigSmilesStoObjAtom( res, prevAtom, base_pos + pos, prevBond) except BigSMILES_BondInconsistencyError: errorMsg(self.rawStr, base_pos + pos, 'Error', 'Inconsistent bond leading to stochastic object.') raise BigSMILESError except BigSMILES_StoObjMissingTerminalError: errorMsg( self.rawStr, base_pos + pos, 'Error', 'Missing left terminal bonding descriptor for BigSMILES stochastic object connected to other atoms.' ) raise BigSMILESError except BigSMILES_StoObjError: errorMsg( self.rawStr, base_pos + pos, 'Error', 'In parsing BigSMILES stochastic object [' + str(len(self.StoObj_List) + 1) + ']') raise BigSMILESError #prevBond = None return prevBond, prevAtom else: return SMILES.parseOne(self, res, level, base_pos, pos, prevBond, prevAtom)