Пример #1
0
 def set_aromaticity_mdl(self):
     """
     Sets the aromaticity flags in this molecule to use the MDL model
     """
     oechem.OEClearAromaticFlags(self.mol)
     oechem.OEAssignAromaticFlags(self.mol, oechem.OEAroModel_MDL)
     oechem.OEAssignHybridization(self.mol)
Пример #2
0
def createOEMolFromSDF(sdf_filename, index=0):
    """
    Load an SDF file into an OEMol. Since SDF files can contain multiple molecules, an index can be provided as well.

    Parameters
    ----------
    sdf_filename : str
        The name of the SDF file
    index : int, default 0
        The index of the molecule in the SDF file

    Returns
    -------
    mol : openeye.oechem.OEMol object
        The loaded oemol object
    """
    #TODO this needs a test
    ifs = oechem.oemolistream()
    ifs.open(sdf_filename)
    # get the list of molecules
    mol_list = [oechem.OEMol(mol) for mol in ifs.GetOEMols()]
    # we'll always take the first for now

    # Assign aromaticity and hydrogens.
    for molecule in mol_list:
        oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)
        oechem.OEAssignHybridization(molecule)
        oechem.OEAddExplicitHydrogens(molecule)

    mol_to_return = mol_list[index]
    return mol_to_return
Пример #3
0
def smiles_to_oemol(smiles, title='MOL', max_confs=1):
    """
    Generate an oemol from a SMILES string

    Parameters
    ----------
    smiles : str
        SMILES string of molecule
    title : str, default 'MOL'
        title of OEMol molecule
    max_confs : int, default 1
        maximum number of conformers to generate
    Returns
    -------
    molecule : openeye.oechem.OEMol
        OEMol object of the molecule
    """
    from openeye import oeomega

    # Create molecule
    molecule = oechem.OEMol()
    oechem.OESmilesToMol(molecule, smiles)

    # create unique atom names
    if len([atom.GetName() for atom in molecule.GetAtoms()]) > len(
            set([atom.GetName() for atom in molecule.GetAtoms()])):
        # the atom names are not unique
        molecule = generate_unique_atom_names(molecule)
    else:
        pass

    # Set title.
    molecule.SetTitle(title)

    # Assign aromaticity and hydrogens.
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)
    oechem.OEAssignHybridization(molecule)
    oechem.OEAddExplicitHydrogens(molecule)
    oechem.OEPerceiveChiral(molecule)

    # Create atom names.
    oechem.OETriposAtomNames(molecule)
    oechem.OETriposBondTypeNames(molecule)

    # perceive chirality before attempting omega geometry proposal
    assert oechem.OEPerceiveChiral(molecule), f"chirality perception failed"

    # Assign geometry
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(max_confs)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(True)

    omega(molecule)
    return molecule
Пример #4
0
def createOEMolFromSDF(sdf_filename,
                       index=0,
                       add_hydrogens=True,
                       allow_undefined_stereo=False):
    """
    # TODO change this to return a list of all the mols if required
    Load an SDF file into an OEMol. Since SDF files can contain multiple
    molecules, an index can be provided as well.

    Parameters
    ----------
    sdf_filename : str
        The name of the SDF file
    index : int, default 0
        The index of the molecule in the SDF file
    allow_undefined_stereo : bool, default=False
        wether to skip stereo perception

    Returns
    -------
    mol : openeye.oechem.OEMol object
        The loaded oemol object
    """
    # TODO this needs a test
    ifs = oechem.oemolistream()
    ifs.open(sdf_filename)
    # get the list of molecules
    mol_list = [oechem.OEMol(mol) for mol in ifs.GetOEMols()]
    # we'll always take the first for now

    # pick out molecule of interest
    molecule = mol_list[index]

    # Generate unique atom names
    if len([atom.GetName() for atom in molecule.GetAtoms()]) > len(
            set([atom.GetName() for atom in molecule.GetAtoms()])):
        molecule = generate_unique_atom_names(molecule)

    # Assign aromaticity and hydrogens.
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)
    oechem.OEAssignHybridization(molecule)
    if add_hydrogens:
        oechem.OEAddExplicitHydrogens(molecule)
    oechem.OEPerceiveChiral(molecule)

    # perceive chirality
    if not allow_undefined_stereo:
        assert oechem.OE3DToInternalStereo(
            molecule
        ), f"the stereochemistry perception from 3D coordinates failed"
        assert not has_undefined_stereocenters(
            molecule), f"there is an atom with an undefined stereochemistry"

    return molecule
Пример #5
0
 def _process_mol(mol: oechem.OEMol, explicit_H: Optional[str] = None):
     if explicit_H == 'all':
         oechem.OEAddExplicitHydrogens(mol)
     elif explicit_H == 'polar':
         oechem.OESuppressHydrogens(mol, explicit_H)
     elif explicit_H is None:
         oechem.OESuppressHydrogens(mol)
     else:
         raise ValueError
     oechem.OEAssignAromaticFlags(mol)
     oechem.OEAssignHybridization(mol)
     oechem.OEAssignFormalCharges(mol)
     mol.Sweep()
def get_sf_elements(mol):
    sfObj = SymmetryFunction()
    oechem.OEAssignFormalCharges(mol)
    oechem.OEAssignHybridization(mol)
    rsf, asf = sfObj.CalculateSymmetryFunction(mol)
    tsf1 = sfObj.CalculateTorsionSymmetryFunction(mol, 1)
    tsf2 = sfObj.CalculateTorsionSymmetryFunction(mol, 2)
    tsf = []
    for elem1, elem2 in zip(tsf1, tsf2):
        tsf.append(elem1 + elem2)

    sf_elements = rsf
    sf_elements.extend(asf)
    sf_elements.extend(tsf)

    return sf_elements
Пример #7
0
def generate_initial_molecule(mol_smiles):
    """
    Generate an oemol with a geometry
    """
    import openeye.oechem as oechem
    import openeye.oeomega as oeomega
    mol = oechem.OEMol()
    oechem.OESmilesToMol(mol, mol_smiles)
    mol.SetTitle("MOL")
    # Assign aromaticity and hydrogens and hybridization.
    oechem.OEAddExplicitHydrogens(mol)
    oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye)
    oechem.OEAssignHybridization(mol)
    oechem.OETriposAtomNames(mol)
    oechem.OETriposBondTypeNames(mol)
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(1)
    omega(mol)
    return mol
Пример #8
0
def iupac_to_oemol(iupac, title='MOL', max_confs=1):
    """
    Generate an oemol from an IUPAC name
    Parameters
    ----------
    iupac : str
        iupac name of molecule
    title : str, default 'MOL'
        title of OEMol molecule
    max_confs : int, default 1
        maximum number of conformers to generate
    Returns
    -------
    molecule : openeye.oechem.OEMol
        OEMol object of the molecule
    """
    from openeye import oeiupac, oeomega

    # Create molecule
    molecule = oechem.OEMol()
    oeiupac.OEParseIUPACName(molecule, iupac)

    # Set title.
    molecule.SetTitle(title)

    # Assign aromaticity and hydrogens.
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)
    oechem.OEAssignHybridization(molecule)
    oechem.OEAddExplicitHydrogens(molecule)
    oechem.OEPerceiveChiral(molecule)

    # Create atom names.
    oechem.OETriposAtomNames(molecule)
    oechem.OETriposBondTypeNames(molecule)

    # Assign geometry
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(max_confs)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(True)
    omega(molecule)
    return molecule
Пример #9
0
def smiles_to_oemol(smiles, title='MOL',max_confs=1):
    """
    Generate an oemol from a SMILES string
    Parameters
    ----------
    smiles : str
        SMILES string of molecule
    title : str, default 'MOL'
        title of OEMol molecule
    max_confs : int, default 1
        maximum number of conformers to generate
    Returns
    -------
    molecule : openeye.oechem.OEMol
        OEMol object of the molecule
    """
    from openeye import oeiupac, oeomega

    # Create molecule
    molecule = oechem.OEMol()
    oechem.OESmilesToMol(molecule, smiles)

    # Set title.
    molecule.SetTitle(title)

    # Assign aromaticity and hydrogens.
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)
    oechem.OEAssignHybridization(molecule)
    oechem.OEAddExplicitHydrogens(molecule)

    # Create atom names.
    oechem.OETriposAtomNames(molecule)

    # Assign geometry
    omega = oeomega.OEOmega()
    omega.SetMaxConfs(max_confs)
    omega.SetIncludeInput(False)
    omega.SetStrictStereo(True)
    omega(molecule)

    return molecule
Пример #10
0
    def addCoordFiles(self, *coordFiles):
        # print(f'\n\033[1m Read Coordinate files... \033[0m')
        if len(coordFiles) == 0:
            print(
                'Skip this molecule? Empty molecule object will be created since no conformers is provided.'
            )
            self.mols.append(oechem.OEMol())
            self.atomids.append([])
            self.elems.append([])
            self.resnames.append([])
            self.atomnames.append([])
            self.resnumbers.append([])
            self.listofpolars.append([])
            self.listofburieds.append([])
            xyzs = []
            self.nmols.append(len(xyzs))
            indices = []
            charge = 0
            number = len(self.elems)
            resname = 'mol%d' % (number)
            chargeinfo = [[indices, resname, charge]]
            self.listofchargeinfo.append(chargeinfo)
        else:
            xyzs = []
            listofoemol = []
            firstconf = True
            for coordFile in coordFiles:
                fbmol = Molecule(coordFile)
                xyz = fbmol.xyzs[0]
                xyz = np.array(xyz) / bohr2Ang
                xyzs.append(xyz)
                # Making oemol using openeye toolkit : for atomID(?), equivGroup and listofpolar
                ifs = oechem.oemolistream(coordFile)
                oemol = oechem.OEGraphMol()
                oechem.OEReadMolecule(ifs, oemol)
                listofoemol.append(oemol)
                oechem.OEPerceiveSymmetry(oemol)

                if firstconf == True:
                    firstconf = False
                    atomicNum = []
                    elem = fbmol.elem
                    if 'resid' not in list(fbmol.Data.keys()):
                        print(
                            ' - Are you using xyz file? Default resid, resname, atomname will be assigned.'
                        )
                        resnumber = [1 for i in elem]
                        resname = list('MOL' for i in elem)
                        atomname = [
                            '%s%d' % (i, idx + 1) for idx, i in enumerate(elem)
                        ]
                    else:
                        resnumber = fbmol.resid
                        resname = fbmol.resname
                        atomname = fbmol.atomname
                    for elm in elem:
                        atomicNum.append(
                            list(PeriodicTable.keys()).index(elm) + 1)
                    atomid = []
                    if len(self.atomidinfo) == 0:
                        atmid = 1
                    else:
                        atmid = max(list(self.atomidinfo.keys())) + 1
                    # if resname is 'MOL', assign resname to be moli
                    if resname == list('MOL' for i in elem):
                        fnm = Path(coordFile).stem
                        newresname = fnm.split('_')[0]
                        print(
                            ' - Is this file generated from esp_generator? The residue name is MOL, which is a default residue name for small organic molecule.'
                        )
                        print(
                            '   It reassigns the residue name to %s not to confuse with other molecules while forcing symmetry.'
                            % newresname)
                        resname = list(newresname for i in elem)
                        num = 1
                        for res, atom in zip(resname, elem):
                            val = {
                                'resname': res,
                                'atomname': '%s%d' % (atom, num)
                            }
                            atomid.append(atmid)
                            self.atomidinfo[atmid] = [val]
                            atmid += 1
                            num += 1
                    else:
                        for res, atom in zip(resname, atomname):
                            val = {'resname': res, 'atomname': atom}
                            if len(self.atomidinfo) == 0:
                                atomid.append(atmid)
                                self.atomidinfo[atmid] = [val]
                                atmid += 1
                            elif any(val in v
                                     for v in list(self.atomidinfo.values())):
                                for k, v in self.atomidinfo.items():
                                    if val in v:
                                        atomid.append(int(k))
                            else:
                                atomid.append(atmid)
                                self.atomidinfo[atmid] = [val]
                                atmid += 1
                    # Using openeye tool, make listofpolar,
                    symmetryClass = []
                    listofpolar = []
                    listofburied = []
                    oechem.OEAssignHybridization(oemol)
                    for atom in oemol.GetAtoms():
                        symmetryClass.append(atom.GetSymmetryClass())
                        if atom.IsCarbon() and int(atom.GetHyb()) != 3:

                            listofpolar.append(atom.GetIdx())
                        if len([bond for bond in atom.GetBonds()]) > 3:
                            listofburied.append(atom.GetIdx())
                            # ispolar = False
                            # for bond in atom.GetBonds():
                            #     atom2 = bond.GetNbr(atom)
                            #     if bond.GetOrder() == 1 and ispolar == False:
                            #         continue
                            #     else:
                            #         ispolar = True
                            #         break
                            # if ispolar == True:
                            # listofpolar.append(atom.GetIdx())
                    for atom in oemol.GetAtoms():
                        if atom.IsHydrogen():
                            for bond in atom.GetBonds():
                                atom2 = bond.GetNbr(atom)
                                if atom2.IsPolar():
                                    listofpolar.append(atom.GetIdx())
                                elif atom2.IsCarbon() and atom2.GetIdx(
                                ) in listofpolar:
                                    listofpolar.append(atom.GetIdx())
                                if atom2.GetIdx() in listofburied:
                                    listofburied.append(
                                        atom.GetIdx()
                                    )  # store hydrogens bonded to buried atoms
                        if atom.IsPolar():
                            listofpolar.append(atom.GetIdx())

                    listofpolar = sorted(set(listofpolar))
                    listofburied = sorted(set(listofburied))
                    idxof1statm, resnameof1statm = self.getidxof1statm(
                        resnumber, resname)
                    unique_resid = set(resnameof1statm)
                    sameresid = [[
                        i for i, v in enumerate(resnameof1statm) if v == value
                    ] for value in unique_resid]
                    sameresid.sort()
                    #sameresid = self.removeSingleElemList(sameresid)
                    idxof1statm.append(len(resnumber))
                    equiv_ids = []
                    #print('symmetryClass', symmetryClass)
                    #print('sameresid', sameresid)
                    for equivresidgroup in sameresid:
                        resnum = equivresidgroup[0]
                        listofsym = symmetryClass[
                            idxof1statm[resnum]:idxof1statm[resnum + 1]]
                        #print(listofsym)
                        unique_sym = set(listofsym)
                        equiv_sym = [[
                            i + idxof1statm[resnum]
                            for i, v in enumerate(listofsym) if v == value
                        ] for value in unique_sym]
                        equiv_sym = self.removeSingleElemList(equiv_sym)
                        #print('equiv_sym', equiv_sym)
                        # change index to ID
                        equiv_ID = []
                        for lst in equiv_sym:
                            newlist = []
                            for item in lst:
                                newlist.append(atomid[item])
                            equiv_ID.append(newlist)
                        for i in equiv_ID:
                            i.sort()
                            equiv_ids.append(i)  # weird:\
                    needtoremove = []
                    for idx, equiv_id in enumerate(equiv_ids):
                        if len(set(equiv_id)) == 1:
                            needtoremove.append(idx)
                    needtoremove.sort(reverse=True)
                    for i in needtoremove:
                        del equiv_ids[i]
                    if self.inp is not None:
                        list_of_new_equiv_atoms = self.convert_equiv_atoms(
                            self.inp.equiv_atoms, self.atomidinfo)
                    else:
                        list_of_new_equiv_atoms = []
                    equiv_ids_comb = []
                    for i in equiv_ids:
                        equiv_ids_comb.append(i)
                    for i in list_of_new_equiv_atoms:
                        equiv_ids_comb.append(i)
                    for i in equiv_ids_comb:
                        i.sort()
                    equiv_ids_comb.sort()

                    newatomid = atomid.copy()
                    newatomidinfo = copy.deepcopy(self.atomidinfo)
                    for equiv_id in equiv_ids_comb:
                        newid = equiv_id[0]
                        for i in equiv_id[1:]:
                            newatomid = [
                                newid if x == i else x for x in newatomid
                            ]
                            for j in self.atomidinfo[i]:
                                newatomidinfo[newid].append(j)
                            del newatomidinfo[i]
                    # print('newatomidinfo', newatomidinfo)
                    # print('oldatomidinfo', self.atomidinfo)
                    # print('newatomid', newatomid)
                    # print('oldatomid', atomid)
                    if self.inp is not None:
                        # print( f' * symmetry: {self.inp.symmetry}')
                        if self.inp.symmetry == False:
                            self.atomids.append(atomid)
                            self.atomidinfo = self.atomidinfo
                        else:
                            self.atomids.append(newatomid)
                            self.atomidinfo = newatomidinfo
                    else:
                        self.atomids.append(newatomid)
                        self.atomidinfo = newatomidinfo
                    self.elems.append(atomicNum)
                    self.resnames.append(resname)
                    self.atomnames.append(atomname)
                    self.resnumbers.append(resnumber)
                    self.listofpolars.append(listofpolar)
                    self.listofburieds.append(listofburied)

                    if self.inp is not None:
                        chargeinfo = self.gen_chargeinfo(
                            self.inp.resChargeDict, newatomid, self.atomidinfo,
                            resnumber)
                    else:
                        indices = list(range(len(elem)))
                        charge = None
                        number = len(self.elems) + 1
                        resname = 'mol%d' % (number)
                        chargeinfo = [[indices, resname, charge]]
                    self.listofchargeinfo.append(chargeinfo)
            self.nmols.append(len(xyzs))
            for xyz in xyzs:
                self.xyzs.append(xyz)
            for oemol in listofoemol:
                self.mols.append(oemol)
Пример #11
0
 def set_aromaticity_mdl(self):
     oechem.OEClearAromaticFlags(self.mol)
     oechem.OEAssignAromaticFlags(self.mol, oechem.OEAroModel_MDL)
     oechem.OEAssignHybridization(self.mol)
# current license or subscription to the applicable OpenEye offering.
# THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED.  OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT
# NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be
# liable for any damages or liability in connection with the Sample Code
# or its use.

from openeye import oechem
from openeye import oedepict
from openeye import oegrapheme

# @ <SNIPPET-ANNOTATE-ATOM-PROPERTY>
mol = oechem.OEGraphMol()
oechem.OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1")
oechem.OEAssignHybridization(mol)
oedepict.OEPrepareDepiction(mol)

opts = oedepict.OE2DMolDisplayOptions(350, 250, oedepict.OEScale_AutoScale)
opts.SetTitleLocation(oedepict.OETitleLocation_Hidden)
disp = oedepict.OE2DMolDisplay(mol, opts)

sp2pen = oedepict.OEPen(oechem.OEWhite, oechem.OEBlueTint, oedepict.OEFill_Off,
                        1.5)
glyphSP2 = oegrapheme.OEAtomGlyphCircle(sp2pen, oegrapheme.OECircleStyle_Sun,
                                        1.2)
oegrapheme.OEAddGlyph(disp, glyphSP2,
                      oechem.OEIsAtomHybridization(oechem.OEHybridization_sp2))

sp3pen = oedepict.OEPen(oechem.OEWhite, oechem.OEPinkTint, oedepict.OEFill_Off,
                        1.5)
Пример #13
0
    def GetTorsions(mol):
        '''
        Goes through each rotatable bond in the molecule
        and extracts torsion atoms (a-b-c-d)
        Core torsion atoms are extended by one bond
        If core or extended atoms are part of a ring,
        then entire ring is kept
        Keep ortho substitution
        Keep functional groups that have at least one atom overlap
        with the core/extended torsion atoms
        Functional group inclusion criteria:
        - <= 5 heavy atoms
        - must contain at least one hetero atom
        - non-ring
        Add methyl cap if bond involving hetero atom is broken
        @param mol: OEGraphMol
        @type mol: OEGraphMol
        @return: list[OEGraphMol]
        '''
        # mol = OEGraphMol(input_mol)

        oechem.OEAssignHybridization(mol)
        funcGrps = TorsionGenerator.GetFuncGroups(mol)
        includedTorsions = oechem.OEAtomBondSet()
        torsionMols = []
        for atom in mol.GetAtoms():
            atom.SetData("idx", atom.GetIdx() + 1)

        torsions = get_canonical_torsions(mol)
        if torsions is None:
            torsions = oechem.OEGetTorsions(mol, oechem.OEIsRotor())

        for torsion in torsions:
            if torsion.a.IsHydrogen() or torsion.b.IsHydrogen() or \
                torsion.c.IsHydrogen() or torsion.d.IsHydrogen():
                continue

            torsion_bond = mol.GetBond(torsion.b, torsion.c)
            if includedTorsions.HasBond(torsion_bond):
                continue
            # if includedTorsions.HasAtom(torsion.b) and \
            #     includedTorsions.HasAtom(torsion.c):
            #     continue

            # revert map idx to zero in original mol
            for atom in mol.GetAtoms():
                atom.SetMapIdx(0)

            # includedTorsions.AddAtom(torsion.b)
            # includedTorsions.AddAtom(torsion.c)
            includedTorsions.AddBond(torsion_bond)

            torsionSet = oechem.OEAtomBondSet(mol.GetBonds())
            torsionSet.AddAtoms([torsion.a, torsion.b, torsion.c, torsion.d])
            for atom in torsionSet.GetAtoms():
                atom.SetMapIdx(1)

            # extend core torsion atoms by one bond
            nbrs = TorsionGenerator.GetNbrs(torsionSet)
            torsionSet.AddAtoms(nbrs)

            # include ring atoms
            ringAtoms = TorsionGenerator.GetSameRingAtoms(mol, torsionSet)
            torsionSet.AddAtoms(ringAtoms)

            for atom in torsionSet.GetAtoms():
                if not atom.GetMapIdx() == 1:
                    atom.SetMapIdx(2)

            # add functional groups that overlap with torsion set
            TorsionGenerator.AddFuncGroupAtoms(funcGrps, torsionSet)

            # add relevant ring atoms (ortho substituents and ring H)
            TorsionGenerator.AddRelevantRingAtoms(mol, torsion, torsionSet)

            # special treatment for C=O
            for atom in torsionSet.GetAtoms(
                    oechem.OEAndAtom(
                        oechem.OEIsOxygen(),
                        oechem.OEIsAtomHybridization(
                            oechem.OEHybridization_sp2))):
                for nbr in atom.GetAtoms():
                    if torsionSet.HasAtom(nbr):
                        for nbr2 in nbr.GetAtoms(oechem.OEIsHeavy()):
                            if not torsionSet.HasAtom(nbr2):
                                nbr2.SetMapIdx(2)
                                torsionSet.AddAtom(nbr2)

            # mark bridging atom and cap if needed
            BRIDGE_ATOM_IDX = 4
            TorsionGenerator.MarkBridgingAtoms(BRIDGE_ATOM_IDX, mol,
                                               torsionSet)

            A_IDX = 11
            B_IDX = 12
            C_IDX = 13
            D_IDX = 14
            torsion.a.SetMapIdx(A_IDX)
            torsion.b.SetMapIdx(B_IDX)
            torsion.c.SetMapIdx(C_IDX)
            torsion.d.SetMapIdx(D_IDX)

            torsionMol = oechem.OEGraphMol()
            oechem.OESubsetMol(torsionMol, mol, torsionSet, True)
            torsionMol.Sweep()
            torsionMols.append(torsionMol)

            # change bridge atom to Carbon
            for atom in torsionMol.GetAtoms(
                    oechem.OEHasMapIdx(BRIDGE_ATOM_IDX)):
                atom.SetAtomicNum(oechem.OEElemNo_C)
                explicit_valence = atom.GetExplicitValence()
                if explicit_valence < 4:
                    atom.SetImplicitHCount(4 - explicit_valence)

            TorsionGenerator.SetSDData(A_IDX, B_IDX, C_IDX, D_IDX, torsion,
                                       torsionMol)

            # set map idx to zero in torsion mol
            for atom in torsionMol.GetAtoms():
                atom.SetMapIdx(0)

        # revert map idx to zero in original mol
        for atom in mol.GetAtoms():
            atom.SetMapIdx(0)

        return torsionMols