def flag_inverted_atoms_in_mcs(): """ Flag all atoms in the MCS where the chirality is inverted between moli and molj with CHI_TETRAHEDRAL_CW) """ # Generate atommappings as they are useful below map_mcs_mol() # moli chiral atoms rmoli = reorder_mol_to_mcs(self.moli) chiral_at_moli = [ seq[0] for seq in Chem.FindMolChiralCenters(rmoli) ] # molj chiral atoms rmolj = reorder_mol_to_mcs(self.molj) chiral_at_molj = [ seq[0] for seq in Chem.FindMolChiralCenters(rmolj) ] invertedatoms = [] for i in chiral_at_moli: # Is atom i in the MCS? ai = rmoli.GetAtomWithIdx(i) if (ai.HasProp('to_mcs')): #print("Checking mol i chiral atom",i,ai.GetProp('to_mcs')) for j in chiral_at_molj: # Is atom j in the MCS? aj = rmolj.GetAtomWithIdx(j) if (aj.HasProp('to_mcs')): #print("Matching mol j chiral atom",j,aj.GetProp('to_mcs')) # Are they the same atom? if (ai.GetProp('to_mcs') == aj.GetProp( 'to_mcs')): #print("Matched mcs atom ",aj.GetProp('to_mcs'),"inverted?",ai.GetChiralTag()!=aj.GetChiralTag()) # OK, atoms are both chiral, and match the same MCS atom # Check if the parities are the same. If not, flag with the # CHI_TETRAHEDRAL_CW property if (ai.GetChiralTag() != aj.GetChiralTag()): invertedatoms.append( int(aj.GetProp('to_mcs'))) for i in invertedatoms: mcsat = self.mcs_mol.GetAtomWithIdx(i) mcsat.SetChiralTag( Chem.rdchem.ChiralType.CHI_TETRAHEDRAL_CW) if options.verbose == 'pedantic': logging.info('Chiral atom detected: %d' % (i))
def getMolSvg(self): self.drawer = rdMolDraw2D.MolDraw2DSVG(300, 300) #TODO, what if self._drawmol doesn't exist? if self._drawmol != None: #Chiral tags on R/S chiraltags = Chem.FindMolChiralCenters(self._drawmol) opts = self.drawer.drawOptions() for tag in chiraltags: idx = tag[0] opts.atomLabels[idx] = self._drawmol.GetAtomWithIdx( idx).GetSymbol() + ':' + tag[1] if len(self._selectedAtoms) > 0: colors = { self._selectedAtoms[-1]: (1, 0.2, 0.2) } #Color lastly selected a different color self.drawer.DrawMolecule( self._drawmol, highlightAtoms=self._selectedAtoms, highlightAtomColors=colors, ) else: self.drawer.DrawMolecule(self._drawmol) self.drawer.FinishDrawing() self.finishedDrawing.emit() #Signal that drawer has finished svg = self.drawer.GetDrawingText().replace('svg:', '') return svg
def stereochemistry_wrapper(*args, **kwargs): data = [] for original_mol in original_func(*args, **kwargs): mol = original_mol.mol filter_func = lambda x: x[ 1] == '?' # rdkit marks unassigned stereocenters as '?' stereocenters = list( filter(filter_func, Chem.FindMolChiralCenters(mol, includeUnassigned=True))) atom_idx_stereo_pairs = [ product([atom_idx], stereochem_types) for atom_idx, _ in stereocenters ] for stereo_assignments in product(*atom_idx_stereo_pairs): new_rdkit_mol = original_mol.mol for atom_idx, stereo in stereo_assignments: new_rdkit_mol.GetAtomWithIdx(atom_idx).SetChiralTag(stereo) # format data new_model_mol = deepcopy(original_mol) new_model_mol.binary = new_rdkit_mol.ToBinary() Chem.Kekulize(new_rdkit_mol) new_model_mol.kekule = Chem.MolToSmiles(new_rdkit_mol, kekuleSmiles=True) data.append(new_model_mol) return data
def GetStereoIsomers(mol): from rdkit import Chem from copy import copy out = [] chiralCentres = Chem.FindMolChiralCenters(mol, includeUnassigned=True) #return the molecule object when no chiral centres where identified if chiralCentres == []: return [mol] #All bit permutations with number of bits equals number of chiralCentres elements = spam(len(chiralCentres)) for isoId, element in enumerate(elements): for centreId, i in enumerate(element): atomId = chiralCentres[centreId][0] if i == 0: mol.GetAtomWithIdx(atomId).SetChiralTag( Chem.rdchem.ChiralType.CHI_TETRAHEDRAL_CW) elif i == 1: mol.GetAtomWithIdx(atomId).SetChiralTag( Chem.rdchem.ChiralType.CHI_TETRAHEDRAL_CCW) outmol = copy(mol) out.append(outmol) print Chem.MolToSmiles(mol, isomericSmiles=True) return out
def enumerateStereoChem(compoundID, sampleDir, db, xtal): # first need to recreate the original CIF file with phenix.elbow because we cannot be sure # which program was used to create the initial restrains # this is because funny things happen to aromatic rings in case the file was made with GRADE os.chdir(os.path.join(sampleDir, 'compound')) sql = "select CompoundSMILESproduct from mainTable where CrystalName = '%s'" % xtal query = db.execute_statement(sql) originalSMILES = query[0][0] cmd = 'phenix.elbow --smiles="%s" --id=LIG --output=tmp' % (originalSMILES) os.system(cmd) stereosmiles = None if os.path.isfile(os.path.join(sampleDir, 'compound', 'tmp.pdb')): pdb = os.path.join(sampleDir, 'compound', 'tmp.pdb') else: print 'cannot find tmp.pdb' pass mol = Chem.MolFromPDBFile(pdb) Chem.AssignStereochemistry(mol, cleanIt=True, force=True, flagPossibleStereoCenters=True) if Chem.FindMolChiralCenters(mol, includeUnassigned=True) == []: print 'no chiral centres found' db_dict = {} db_dict['CompoundStereo'] = 'FALSE' updateDB(db, db_dict, xtal) else: stereosmiles = Chem.MolToSmiles(mol, isomericSmiles=True) generateRestraints(compoundID, sampleDir, db, stereosmiles, xtal)
def cahn_ingold_prelog(self): """ The Cahn Ingold Prelog chirality indicator. """ try: return self.props['_CIPCode'] except KeyError: if self.owner is not None: Chem.FindMolChiralCenters(self.owner) return self.props.get('_CIPCode', None)
def _is_achiral_by_symmetry(INCHI): mol = Chem.MolFromInchi(INCHI) if not mol: mol = Chem.MolFromInchi(f'InChI=1/{INCHI}') try: # is there any real chiral centre? return len(Chem.FindMolChiralCenters(mol, True, True)) == 0 except Exception: return False
def check_chiral(m, ion_smiles): chiral_atoms_mol = Chem.FindMolChiralCenters(m) number_of_chiral_atoms_mol = len(chiral_atoms_mol) if number_of_chiral_atoms_mol == 0: return ion_smiles ion = Chem.MolFromSmiles(ion_smiles) chiral_atoms_ion = Chem.FindMolChiralCenters(ion) for chiral_atom_mol, chiral_atom_ion in zip(chiral_atoms_mol, chiral_atoms_ion): if chiral_atom_mol != chiral_atom_ion: ion.GetAtomWithIdx(chiral_atom_mol[0]).InvertChirality() ion_smiles = Chem.MolToSmiles(ion, isomericSmiles=True) # print Chem.FindMolChiralCenters(ion) return ion_smiles
def set_chirality(product, reactant): """ Written by Mads Koerstz Produce all combinations of isomers (R/S and cis/trans). But force product atoms with unchanged neighbors to the same label chirality as the reactant """ # TODO move these somewhere it makes more sense. product = reassign_atom_idx(product) reactant = reassign_atom_idx(reactant) Chem.SanitizeMol(product) Chem.SanitizeMol(reactant) # Find chiral atoms - including label chirality chiral_atoms_product = Chem.FindMolChiralCenters(product, includeUnassigned=True) unchanged_atoms = [] for atom, chiral_tag in chiral_atoms_product: product_neighbors = [ a.GetIdx() for a in product.GetAtomWithIdx(atom).GetNeighbors() ] reactant_neighbors = [ a.GetIdx() for a in reactant.GetAtomWithIdx(atom).GetNeighbors() ] if sorted(product_neighbors) == sorted(reactant_neighbors): unchanged_atoms.append(atom) # make combinations of isomers. opts = StereoEnumerationOptions(onlyUnassigned=False, unique=False) rdmolops.AssignStereochemistry(product, cleanIt=True, flagPossibleStereoCenters=True, force=True) product_isomers = [] product_isomers_mols = [] for product_isomer in EnumerateStereoisomers(product, options=opts): rdmolops.AssignStereochemistry(product_isomer, force=True) for atom in unchanged_atoms: reactant_global_tag = reactant.GetAtomWithIdx(atom).GetProp( '_CIPCode') # TODO make sure that the _CIPRank is the same for atom in reactant and product. product_isomer_global_tag = product_isomer.GetAtomWithIdx( atom).GetProp('_CIPCode') if reactant_global_tag != product_isomer_global_tag: product_isomer.GetAtomWithIdx(atom).InvertChirality() if Chem.MolToSmiles(product_isomer) not in product_isomers: product_isomers.append(Chem.MolToSmiles(product_isomer)) product_isomers_mols.append(product_isomer) return product_isomers_mols