def ReadAtomSuffix(self, tree, atom):
     constraint = None
     #'+','-','.',':','+.','-.','*'
     if tree[0] == '+.':
         constraint = AtomRadical(False, ConstraintNumber('=1'))
         atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(1))
     elif tree[0] == '-.':
         constraint = AtomRadical(False, ConstraintNumber('=1'))
         atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(-1))
     elif tree[0] == '+':
         atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(1))
     elif tree[0] == '-':
         atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(-1))
     elif tree[0] == '.':
         constraint = AtomRadical(False, ConstraintNumber('=1'))
     elif tree[0] == ':':
         constraint = AtomRadical(False, ConstraintNumber('=2'))
     elif tree[0] == ':.':
         constraint = AtomRadical(False, ConstraintNumber('=3'))
     elif tree[0] == '*':
         from rdkit.Chem import GetPeriodicTable
         #if type(atom).__name__ == 'QueryAtom':
         #    raise NotImplementedError('Onium $,&,X atoms not supported yet')
         atomicnum = atom.GetAtomicNum()
         atom = rdqueries.AtomNumEqualsQueryAtom(atomicnum)
         valence = GetPeriodicTable().GetDefaultValence(atomicnum)
         atom.ExpandQuery(rdqueries.TotalValenceEqualsQueryAtom(valence +
                                                                1))
         atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(1))
     elif tree[0] == '?':
         pass
     else:
         s = "Unsupported atom suffic: '" + tree[0] + "'"
         raise NotImplementedError(s)
     return constraint
 def __call__(self,comb_mol,mapped_index):
     atom = comb_mol.GetAtomWithIdx(mapped_index[self.idx])
     if self.valence != 0:
         from rdkit.Chem import GetPeriodicTable
         atomicnum = atom.GetAtomicNum()
         atom = rdqueries.AtomNumEqualsQueryAtom(atomicnum)
         valence = GetPeriodicTable().GetDefaultValence(atomicnum)
         atom.ExpandQuery(rdqueries.TotalValenceEqualsQueryAtom(valence+self.valence))
         atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(self.charge))
         comb_mol.ReplaceAtom(self.idx,atom)
     
     atom.SetNumRadicalElectrons(self.radical)
     atom.SetFormalCharge(self.charge)
    def ReadAtomType(self, tree):
        i = 0
        constraints = list()
        if tree[i][0] == 'AtomPrefix':
            constraints.append(self.ReadAtomPrefix(tree[i][1:]))
            i += 1

        assert tree[i][0] == 'Symbols'
        atom = self.ReadSymbols(tree[i][1:])
        i += 1

        if len(tree) > i:
            constraint = self.ReadAtomSuffix(tree[i][1:], atom)
            if constraint:
                constraints.append(constraint)
        else:
            # no suffix means it's neutral. RDkit atom with 0 formal charge and
            # radical electron finds all variables of formal charge and radical
            # electrons, so they need to be treated.
            atom.ExpandQuery(rdqueries.FormalChargeEqualsQueryAtom(0))
            constraints.append(AtomRadical(False, ConstraintNumber('=0')))
        # return atom
        return atom, constraints