示例#1
0
    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
示例#2
0
 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
示例#3
0
 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
示例#5
0
    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)
示例#7
0
    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
示例#8
0
    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
示例#9
0
    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
示例#10
0
    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)