Example #1
0
def assign_canonical_am1bcc_charges(molecule):
    """
    Assign canonical AM1-BCC charges to molecule.

    From canonical AM1-BCC recipe:
    http://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        Molecule is modified in place.

    Raises
    ------
    An Exception is raised if no charges were set due to a failure.

    """

    # Create temporary copy of molecule to parameterize.
    expanded_molecule = oechem.OEMol(molecule)

    # Initialize Omega.
    omega = oeomega.OEOmega()
    omega.SetIncludeInput(True)
    omega.SetCanonOrder(False)
    omega.SetSampleHydrogens(True)
    eWindow = 15.0
    omega.SetEnergyWindow(eWindow)
    omega.SetMaxConfs(800)
    omega.SetRMSThreshold(1.0)
    if not omega(expanded_molecule):
        raise ValueError("Cannot expand molecule with Omega Toolkit!")

    oequacpac.OEAssignPartialCharges(expanded_molecule, oequacpac.OECharges_AM1BCCSym)

    # Check whether charges were set.
    total_charge = 0.0
    nonzero_charges_detected = False
    for (src_atom, dest_atom) in zip(expanded_molecule.GetAtoms(), molecule.GetAtoms()):
        if src_atom.GetPartialCharge() != dest_atom.GetPartialCharge():
            nonzero_charges_detected = True
        total_charge += src_atom.GetPartialCharge()
    if not nonzero_charges_detected:
        raise ValueError("Charge assignment failure.")

    print " Total charge: %12.8f" % total_charge

    # Copy charges back to original molecule.
    for (src_atom, dest_atom) in zip(expanded_molecule.GetAtoms(), molecule.GetAtoms()):
        dest_atom.SetFormalCharge(src_atom.GetFormalCharge())
        dest_atom.SetPartialCharge(src_atom.GetPartialCharge())

    return
Example #2
0
def assign_charges(molecule):
    """
    Assign AM1-BCC charges using recommended scheme from Christopher Bayly.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
       The molecule to be assigned conformations (will be modified).

    """
    oequacpac.OEAssignPartialCharges(
        molecule, oequacpac.OECharges_AM1BCCSym
    )  # AM1BCCSym recommended by Chris Bayly to KAB+JDC, Oct. 20 2014.
    return
Example #3
0
def compute_wbos(map_to_parent):
    oemol = cmiles.utils.load_molecule(map_to_parent)
    try:
        charged = fragmenter.chemi.get_charges(oemol,
                                               keep_confs=-1,
                                               strict_types=False)
    except:
        print('Cannot charge {}'.format(oechem.OEMolToSmiles(oemol)))
        return False
    # Collect all wbos
    elf_wbo_estimate = collect_wbos(charged)
    if not elf_wbo_estimate:
        warnings.warn('{} was not charged'.format(
            oechem.OEMolToSmiles(charged)))
        return False
    wbos = {
        key: {
            'elf_estimate': elf_wbo_estimate[key],
            'individual_confs': []
        }
        for key in elf_wbo_estimate
    }
    # Compute WBO for each conformer
    for i, conf in enumerate(charged.GetConfs()):
        mol_copy = oechem.OEMol(conf)
        # Get WBO
        if oequacpac.OEAssignPartialCharges(mol_copy,
                                            oequacpac.OECharges_AM1BCCSym):
            ind_wbos = collect_wbos(molecule=mol_copy)
            for b in ind_wbos:
                if b not in wbos and 0 in b:
                    wbos[b] = {'individual_confs': [ind_wbos[b]]}
                elif b not in wbos:
                    reverse = tuple(reversed(b))
                    wbos[reverse]['individual_confs'].append(ind_wbos[b])

                wbos[b]['individual_confs'].append(ind_wbos[b])
        else:
            print('AM1BCC charging failed for {}, {}'.format(str(i), i))
    return charged, wbos
def main(argv=[__name__]):

    itf = oechem.OEInterface(InterfaceData)

    if oechem.OECheckHelp(itf, argv):
        return 0

    if not oechem.OEParseCommandLine(itf, argv):
        return 1

    ifs = oechem.oemolistream()
    if not ifs.open(itf.GetString("-i")):
        oechem.OEThrow.Fatal("Unable to open %s for reading" %
                             itf.GetString("-i"))

    ofs = oechem.oemolostream()
    if not ofs.open(itf.GetString("-o")):
        oechem.OEThrow.Fatal("Unable to open %s for writing" %
                             itf.GetString("-o"))

    omega = oeomega.OEOmega()
    maxConfs = 0
    omega.SetMaxConfs(maxConfs)
    omega.SetStrictStereo(False)
    omega.SetSampleHydrogens(True)
    omega.SetEnumNitrogen(oeomega.OENitrogenEnumeration_All)
    mol = oechem.OEMol()
    for mol in ifs.GetOEMols():
        #print( mol.GetTitle() )
        if not omega(mol):
            print("omega failed on %s" % mol.GetTitle())
        title = mol.GetTitle()
        oechem.OETriposAtomNames(mol)
        oequacpac.OEAssignPartialCharges(mol, oequacpac.OECharges_AM1BCCSym)
        oechem.OEWriteConstMolecule(ofs, mol)

    ofs.close()
    return 0
Example #5
0
def assign_simple_am1bcc_charges(molecule, verbose=True):
    """
    Assign AM1-BCC charges to molecule using a single conformer, rather than the canonical scheme.

    Parameters
    ----------
    molecule : openeye.oechem.OEMol
        Molecule is modified in place.

    Raises
    ------
    An Exception is raised if no charges were set due to a failure.

    """

    # Create temporary copy of molecule to parameterize.
    expanded_molecule = oechem.OEMol(molecule)

    oequacpac.OEAssignPartialCharges(expanded_molecule, oequacpac.OECharges_AM1BCC)

    # Check whether charges were set.
    nonzero_charges_detected = False
    total_charge = 0.0
    for (src_atom, dest_atom) in zip(expanded_molecule.GetAtoms(), molecule.GetAtoms()):
        if src_atom.GetPartialCharge() != dest_atom.GetPartialCharge():
            nonzero_charges_detected = True
        total_charge += src_atom.GetPartialCharge()
    if not nonzero_charges_detected:
        raise Exception("Charge assignment failure.")
    if verbose: print " Total charge: %12.8f" % total_charge

    # Copy charges back to original molecule.
    for (src_atom, dest_atom) in zip(expanded_molecule.GetAtoms(), molecule.GetAtoms()):
        dest_atom.SetPartialCharge(src_atom.GetPartialCharge())
        dest_atom.SetFormalCharge(src_atom.GetFormalCharge())

    return
Example #6
0
    oechem.OESmilesToMol(mol, optimal_mapped_smiles[i])
    dih = fragmenter.torsions.find_torsion_around_bond(mol, bond)
    torsion_scans[ser_bond]['optimal'] = {
        'wbos': [],
        'elf10_wbo':
        omega_results[ser_bond][optimal_smiles[i]]['elf_estimate'],
        'frag': optimal_mapped_smiles[i]
    }
    conformers = fragmenter.chemi.generate_grid_conformers(mol,
                                                           dihedrals=[dih],
                                                           intervals=[15],
                                                           strict_types=False)
    for conf in conformers.GetConfs():
        mol_copy = oechem.OEMol(conf)
        oechem.OEAddExplicitHydrogens(mol_copy)
        if oequacpac.OEAssignPartialCharges(mol_copy,
                                            oequacpac.OECharges_AM1BCCNoSym):
            bo = get_bond(mol=mol_copy, bond_tuple=bond)
            wbo = bo.GetData('WibergBondOrder')
            torsion_scans[ser_bond]['optimal']['wbos'].append(wbo)

    plt.figure()
    sbn.kdeplot(omega_benchmark_results[ser_bond]['parent']['wbo_dist'],
                shade=True,
                color=sbn.color_palette('colorblind')[0],
                label='parent molecule')
    sbn.distplot(omega_benchmark_results[ser_bond]['parent']['wbo_dist'],
                 rug=True,
                 hist=False,
                 color=sbn.color_palette('colorblind')[0])
    # sbn.distplot(results['parent']['wbo_dist'], hist=False, color=sbn.color_palette()[0])
Example #7
0
    oeiupac.OEParseIUPACName(molecule, name)
    molecule.SetTitle(name)

    # Normalize molecule.
    oechem.OEAddExplicitHydrogens(molecule)
    oechem.OETriposAtomNames(molecule)
    oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye)

    # Create configuration.
    omega = oeomega.OEOmega()
    omega.SetStrictStereo(True)
    omega.SetIncludeInput(False)
    omega(molecule)

    # Create charges.
    oequacpac.OEAssignPartialCharges(molecule, oequacpac.OECharges_AM1BCCSym)

    # Write molecule.
    filename = '%s.tripos.mol2' % name
    print filename
    ofs = oechem.oemolostream()
    ofs.open(filename)
    oechem.OEWriteMolecule(ofs, molecule)
    ofs.close()

    # Replace <0> with resname.
    infile = open(filename, 'r')
    lines = infile.readlines()
    infile.close()
    newlines = [line.replace('<0>', resname) for line in lines]
    outfile = open(filename, 'w')
Example #8
0
File: am1wib.py Project: vtlim/misc
def am1wib(insdf, outdat, plotout=None):
    """
    Parameters
    ----------
    insdf: string, name of SDF file

    """
    outf = open(outdat, 'w')
    ### Read in .sdf file and distinguish each molecule's conformers
    ifs = oechem.oemolistream()
    ifs.SetConfTest(oechem.OEAbsoluteConfTest())
    if not ifs.open(insdf):
        oechem.OEThrow.Warning("Unable to open %s for reading" % insdf)
        return

    angList = []  # for plotting
    labelList = []  # for plotting
    for mol in ifs.GetOEMols():
        molName = mol.GetTitle()
        outf.write('\n\n>>> Molecule: %s\tNumConfs: %d' %
                   (molName, mol.NumConfs()))
        for i, conf in enumerate(mol.GetConfs()):

            ### AM1-BCC charge calculation
            charged_copy = oechem.OEMol(mol)
            status = oequacpac.OEAssignPartialCharges(
                charged_copy, oequacpac.OECharges_AM1BCCSym, False, False)
            if not status:
                raise (RuntimeError(
                    "OEAssignPartialCharges returned error code %s" % status))

            ### Our copy has the charges we want but not the right conformation.
            ### Copy charges over. Also copy over Wiberg bond orders.
            partial_charges = []
            partial_bondorders = []
            for atom in charged_copy.GetAtoms():
                partial_charges.append(atom.GetPartialCharge())
            for (idx, atom) in enumerate(mol.GetAtoms()):
                atom.SetPartialCharge(partial_charges[idx])
            for bond in charged_copy.GetBonds():
                partial_bondorders.append(bond.GetData("WibergBondOrder"))
            for (idx, bond) in enumerate(mol.GetBonds()):
                bond.SetData("WibergBondOrder", partial_bondorders[idx])

            ### Sum angles around each invertible N, and get Wiberg bond order.
            for atom in conf.GetAtoms(oechem.OEIsInvertibleNitrogen()):
                aidx = atom.GetIdx()
                nbors = list(atom.GetAtoms())
                ang1 = math.degrees(
                    oechem.OEGetAngle(conf, nbors[0], atom, nbors[1]))
                ang2 = math.degrees(
                    oechem.OEGetAngle(conf, nbors[1], atom, nbors[2]))
                ang3 = math.degrees(
                    oechem.OEGetAngle(conf, nbors[2], atom, nbors[0]))
                ang_sum = math.fsum([ang1, ang2, ang3])
                outf.write("\n\n%s: sum of angles for N, index %d: %f" %
                           (molName, aidx, ang_sum))
                angList.append(ang_sum)
                labelList.append("{}_{}_{}".format(molName, i, aidx))

                for bond in atom.GetBonds():
                    nbor = bond.GetNbr(atom)
                    nidx = nbor.GetIdx()
                    nbor_wib = bond.GetData('WibergBondOrder')
                    outf.write(
                        "\n{}: wiberg bond order for indices {} {}: {}".format(
                            molName, aidx, nidx, nbor_wib))

    if plotout is not None:
        with open(plotout, 'w') as f:
            lis = [list(range(len(angList))), angList, labelList]
            for x in zip(*lis):
                f.write("{0}\t{1}\t{2}\n".format(*x))

    ifs.close()
Example #9
0
def get_charges(molecule,
                max_confs=800,
                strict_stereo=True,
                normalize=True,
                keep_confs=None,
                legacy=True):
    """Generate charges for an OpenEye OEMol molecule.
    Parameters
    ----------
    molecule : OEMol
        Molecule for which to generate conformers.
        Omega will be used to generate max_confs conformations.
    max_confs : int, optional, default=800
        Max number of conformers to generate
    strictStereo : bool, optional, default=True
        If False, permits smiles strings with unspecified stereochemistry.
        See https://docs.eyesopen.com/omega/usage.html
    normalize : bool, optional, default=True
        If True, normalize the molecule by checking aromaticity, adding
        explicit hydrogens, and renaming by IUPAC name.
    keep_confs : int, optional, default=None
        If None, apply the charges to the provided conformation and return
        this conformation, unless no conformation is present.
        Otherwise, return some or all of the generated
        conformations. If -1, all generated conformations are returned.
        Otherwise, keep_confs = N will return an OEMol with up to N
        generated conformations.  Multiple conformations are still used to
        *determine* the charges.
    legacy : bool, default=True
        If False, uses the new OpenEye charging engine.
        See https://docs.eyesopen.com/toolkits/python/quacpactk/OEProtonFunctions/OEAssignCharges.html#
    Returns
    -------
    charged_copy : OEMol
        A molecule with OpenEye's recommended AM1BCC charge selection scheme.
    Notes
    -----
    Roughly follows
    http://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html
    """

    # If there is no geometry, return at least one conformation.
    if molecule.GetConfs() == 0:
        keep_confs = 1

    if not oechem.OEChemIsLicensed():
        raise (ImportError("Need License for OEChem!"))
    if not oequacpac.OEQuacPacIsLicensed():
        raise (ImportError("Need License for oequacpac!"))

    if normalize:
        molecule = normalize_molecule(molecule)
    else:
        molecule = oechem.OEMol(molecule)

    charged_copy = generate_conformers(
        molecule, max_confs=max_confs,
        strict_stereo=strict_stereo)  # Generate up to max_confs conformers

    if not legacy:
        # 2017.2.1 OEToolkits new charging function
        status = oequacpac.OEAssignCharges(charged_copy,
                                           oequacpac.OEAM1BCCCharges())
        if not status: raise (RuntimeError("OEAssignCharges failed."))
    else:
        # AM1BCCSym recommended by Chris Bayly to KAB+JDC, Oct. 20 2014.
        status = oequacpac.OEAssignPartialCharges(
            charged_copy, oequacpac.OECharges_AM1BCCSym)
        if not status:
            raise (RuntimeError(
                "OEAssignPartialCharges returned error code %d" % status))

    #Determine conformations to return
    if keep_confs == None:
        #If returning original conformation
        original = molecule.GetCoords()
        #Delete conformers over 1
        for k, conf in enumerate(charged_copy.GetConfs()):
            if k > 0:
                charged_copy.DeleteConf(conf)
        #Copy coordinates to single conformer
        charged_copy.SetCoords(original)
    elif keep_confs > 0:
        logger().debug(
            "keep_confs was set to %s. Molecule positions will be reset." %
            keep_confs)

        #Otherwise if a number is provided, return this many confs if available
        for k, conf in enumerate(charged_copy.GetConfs()):
            if k > keep_confs - 1:
                charged_copy.DeleteConf(conf)
    elif keep_confs == -1:
        #If we want all conformations, continue
        pass
    else:
        #Not a valid option to keep_confs
        raise (ValueError('Not a valid option to keep_confs in get_charges.'))

    return charged_copy