Skip to content

Cheminformatics

Sul edited this page May 10, 2024 · 4 revisions

Validating SMILES

To perform validation of the SMILES, we'll be passing it through a series of software to determine what fails and what doesn't.

The full performance of the GlobalChem against these different lists can be found below:

Software SMILES Passed
RDKit 100%
SELFIES 100%
PySMILES 99.8%
Partial SMILES 85.7%
DeepSMILES 99.25%
MolVS 98.50%

Users can also validate their own SMILES across different software:

from global_chem import GlobalChem
from global_chem_extensions import GlobalChemExtensions

gc = GlobalChem()
cheminformatics = GlobalChemExtensions().cheminformatics()

gc.build_global_chem_network()
smiles_list = list(gc.get_node_smiles('emerging_perfluoroalkyls').values())

sucesses, failures = cheminformatics.verify_smiles(
    smiles_list,
    rdkit=True, 
    partial_smiles=True,
    return_failures=True,
    pysmiles=True,
    molvs=True
)

total = len(sucesses) + len(failures)
print ("Percentage of Accepted SMILES: %s" % ((len(sucesses) / total) * 100))

Decoding Fingeringprints and SMILES to IUPAC

Decoding your fingerprints to your SMILES and to an IUPAC name takes a good annotated dictionary of bit vectors that can accurately guess the chemical space that exists within your molecule.

To accomplish this, GlobalChem has a 1 to 1 mapping of bit vectors produced on a 512 scale with a morgan radius of 2 to capture the chemical environment. So this is where you can play with the parameters to decode your fragmented SMILES or your long SMILES or individual bit vector fragments.

Load the Decoder Engine:

decoder_engine = cheminformatics.get_decoder_engine()

Generate a Morgan Fingerprint:

For ease of use we are sticking to hyperparameters as defined in GlobalChem with radius of 2 and 512 bit length with benzene.

Code:

morgan_fingerprint = decoder_engine.generate_morgan_fingerprint('C1=CC=CC=C1')

Output:

00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Classify Fingerprints

You can classify fingerprints based on the node key that you pass in or all or them. Depends on how accurate or which chemical space you would like to explore.

Code:

print(decoder_engine.classify_fingerprint(
    morgan_fingerprint,
    node='organic_and_inorganic_bronsted_acids'
))

Output:

['benzene']

Classify Bigger SMILES

If you would like to classify a bigger SMILES then GlobalChem will use the BRICS module to fragment the molecule into easier bitvector fragments and do comparisons using tanimoto similarity to achieve a viable functional group space. It follows the same concept of passing in a node to determine the bit vector chemical space to explore.

Code:

print(decoder_engine.classify_smiles_using_bits(
    'CCC(=O)N(C1CCN(CC1)CCC2=CC=CC=C2)C3=CC=CC=C3',
     node='organic_and_inorganic_bronsted_acids'
))

Output:

['benzene', 'ammonia']

SMILES to PDF And Back

PDF Parsing is going to be handling by a separate package called MolPDF. It has pretty much a fixed template and is used for handling data distribution quickly so we can get a general feel of a molecule list.

The philosophy is very simple. We don't really need a template but a simple PDF document to transfer data quickly especially in the case of a supplementary information. We use the meta data stored in the PDF to store the SMILES in accordance with the images. That way it makes it easier to mine the data quickly into a python object.

SMILES to PDF

Code:

from global_chem import GlobalChem
from global_chem_extensions import GlobalChemExtensions

gc = GlobalChem()
cheminformatics = GlobalChemExtensions().cheminformatics()
smiles_list = list(gc.get_node_smiles('pihkal').values())

cheminformatics.smiles_to_pdf(
    smiles=smiles_list,
    labels = [],
    file_name = 'molecules.pdf',
    include_failed_smiles = True,
    title = 'MY MOLECULES',
)

Output:

Method: 'generate' Time: 4.98 seconds

PDF to SMILES

Code:

molecules = cheminformatics.pdf_to_smiles(
    'molecules.pdf',
)

print (len(molecules))

Drug Design Filters

Most common are drug filters in reducing a dataset of large SMILES down. These filters can be cumbersome to find, compare, and code. So we extended GlobalChemExtensions to cover that. We use RDKit to fetch the parameters of each molecule.

from global_chem_extensions import GlobalChemExtensions
cheminformatics = GlobalChemExtensions().cheminformatics()

Filter a Drug by one of the Filters

Code:

gc.build_global_chem_network()
smiles_list = list(gc.get_node_smiles('emerging_perfluoroalkyls').values())

filtered_smiles = cheminformatics.filter_smiles_by_criteria(
    smiles_list,
    lipinski_rule_of_5=True,
    ghose=False,
    veber=False,
    rule_of_3=False,
    reos=False,
    drug_like=False,
    pass_all_filters=False
)

print (filtered_smiles)

Output:

[
   'O=C(O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F', 
   'O=C(O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F',
   'O=S(=O)(O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F',
   'O=S(=O)(O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F',
   'FC(F)(F)C1(F)OC1(F)F', 
   'O=C(O)C(F)(F)C(F)(F)C(F)(F)F',
   'O=C(O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F', 
   'O=S(=O)(O)C(F)(F)C(F)(F)C(F)(F)C(F)(F)C(F)(F)F'
]

Lipinski Rules

Moleculer Weight <= 500
LogP <= 5
H-Bond Donor Count <= 5
H-Bond Acceptor Count <= 10

Ghose Rules

Molecular weight between 160 and 480
LogP between -0.4 and +5.6
Atom count between 20 and 70
Molar refractivity between 40 and 130

Veber Rules

Rotatable bonds <= 10
Topological polar surface area <= 140

Rule of 3

Molecular weight <= 300
LogP <= 3
H-bond donor <= 3
H-bond acceptor count <= 3
Rotatable bond count <= 3

Drug-Like (QED)

mass < 400
ring count > 0
rotatable bond count < 5
h-bond donor count <= 5
h-bond acceptor count <= 10
logP < 5