Chemistry¶
Chemical graph manipulation performed before modelling: standardization,
glycan handling, protecting-group removal, core extraction and graph
conversion. Every component accepts Iterable[rdkit.Chem.Mol] and
follows the scikit-learn transformer protocol.
Standardization¶
The first step of any QSAR workflow. Two records of the same compound that differ only in salt form, protonation or tautomer are the same compound, and a model that sees them as different is learning the registration system rather than the chemistry.
>>> from rdkit import Chem
>>> from qsarkit.chemistry import MolecularStandardizer
>>> standardizer = MolecularStandardizer()
>>> mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)[O-].[Na+]")
>>> Chem.MolToSmiles(standardizer.transform([mol])[0])
'CC(=O)Oc1ccccc1C(=O)O'
Failures keep their position, so a parallel array of activities stays aligned:
>>> [m is None for m in standardizer.transform([mol, None])]
[False, True]
Glycans¶
Natural-product datasets are full of glycosides. The sugar usually carries no activity of its own but dominates the fingerprint, so two glycosides of unrelated aglycones score as more similar to each other than either does to its own aglycone.
>>> from qsarkit.chemistry import GlycanDetector, GlycanRemover
>>> q3g = named_mols["quercetin_3_glucoside"]
>>> GlycanDetector().detect(q3g)["num_sugar_residues"]
1
>>> Chem.MolToSmiles(GlycanRemover().remove(q3g)["aglycone"])
'O=c1cc(-c2ccc(O)c(O)c2)oc2cc(O)cc(O)c12'
Detection is not just “a ring with an oxygen in it” — the exocyclic hydroxylation pattern is what separates a real sugar from a look-alike:
>>> detector = GlycanDetector()
>>> detector.detect(Chem.MolFromSmiles("C1CCOCC1"))["num_sugar_residues"]
0
GlycanDescriptors turns that into features. It returns a
DataFrame rather than an array, because one column is a string:
>>> from qsarkit.chemistry import GlycanDescriptors
>>> frame = GlycanDescriptors().transform([q3g, named_mols["aspirin"]])
>>> frame["sugar_count"].tolist()
[1, 0]
Protecting groups and cores¶
>>> from qsarkit.chemistry import CoreExtractor, FragmentRemover
>>> boc = Chem.MolFromSmiles("CC(C)(C)OC(=O)NCc1ccccc1")
>>> Chem.MolToSmiles(FragmentRemover().transform([boc])[0])
'NCc1ccccc1'
A protecting group is a synthesis artefact, not a pharmacophore. Leaving it on makes every intermediate look like a distinct chemotype and lets a model key on the tag.
>>> extractor = CoreExtractor()
>>> Chem.MolToSmiles(extractor.bemis_murcko(demo_mols[8]))
'c1ccccc1'
>>> pair = [demo_mols[8], demo_mols[9]]
>>> Chem.MolToSmarts(extractor.mcs(pair))
'[#6]-[#6](=[#8])-[#7]-[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1'
Graphs¶
>>> from qsarkit.chemistry import MolecularGraph
>>> graph = MolecularGraph()
>>> G = graph.to_networkx(Chem.MolFromSmiles("CCO"))
>>> G.number_of_nodes(), G.number_of_edges()
(3, 2)
>>> d = graph.descriptors(Chem.MolFromSmiles("c1ccccc1"))
>>> d["num_rings"], d["diameter"], round(d["wiener_index"], 1)
(1, 3, 27.0)
API¶
Chemical structure curation performed before modeling.
Standardization is the step that makes a QSAR dataset comparable at all: without it the same compound appears as several distinct structures and duplicate detection, splitting and modeling all quietly go wrong. The remaining components support that work – glycan handling for natural-product datasets, protecting-group removal, scaffold extraction and graph descriptors.
All components accept Iterable[rdkit.Chem.Mol].
Examples
>>> from rdkit import Chem
>>> from qsarkit.chemistry import MolecularStandardizer
>>> mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)[O-].[Na+]")
>>> Chem.MolToSmiles(MolecularStandardizer().transform([mol])[0])
'CC(=O)Oc1ccccc1C(=O)O'
References
Fourches, D., Muratov, E. & Tropsha, A. (2010). “Trust, But Verify: On the Importance of Chemical Structure Curation in Cheminformatics and QSAR Modeling Research.” J. Chem. Inf. Model., 50(7), 1189-1204. https://doi.org/10.1021/ci100176x
Bemis, G. W. & Murcko, M. A. (1996). “The Properties of Known Drugs. 1. Molecular Frameworks.” J. Med. Chem., 39(15), 2887-2893. https://doi.org/10.1021/jm9602928
RDKit: Open-source cheminformatics. https://www.rdkit.org
- class qsarkit.chemistry.MolecularStandardizer(remove_salts=True, neutralize=True, normalize_tautomers=True, handle_stereochemistry='retain', normalize_hydrogens=True, on_error='none')[source]¶
Bases:
MoleculeToMoleculeTransformerStandardize a batch of molecules into a canonical, model-ready form.
Applies, in order: sanitization, salt/solvent removal (keep the largest organic fragment), charge neutralization, tautomer normalization, stereochemistry handling, and explicit-hydrogen normalization. This mirrors the “structure normalization” stage expected before any downstream QSAR/curation step (OECD QSAR guidance recommends normalized, unambiguous structures prior to model building).
- Parameters:
remove_salts (
bool) – Keep only the largest organic fragment (strips counter-ions, solvates, hydrates).neutralize (
bool) – Neutralize charges where a neutral tautomer/protomer exists (e.g. carboxylates, ammoniums), leaving permanent charges (e.g. quaternary ammonium) untouched.normalize_tautomers (
bool) – Canonicalize to the RDKit-preferred tautomer using the Sybyl/MolVS-derived tautomer scoring rules.handle_stereochemistry (
str) – One of"retain"(keep stereo as parsed, but reassign stereocenters from the 2D/3D structure), or"remove"(strip all stereochemistry, useful when comparing 2D scaffolds).normalize_hydrogens (
bool) – Strip explicit hydrogens except where required for correct valence/stereo perception (RDKit’s implicit-H convention).on_error (
str) –"none"-> failed molecules becomeNonein the output list (positional alignment preserved);"raise"-> raiseInvalidMoleculeErroron the first failure.
Examples
Sodium acetylsalicylate loses its counter-ion and its charge:
>>> from rdkit import Chem >>> from qsarkit.chemistry import MolecularStandardizer >>> standardizer = MolecularStandardizer() >>> mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)[O-].[Na+]") >>> Chem.MolToSmiles(standardizer.transform([mol])[0]) 'CC(=O)Oc1ccccc1C(=O)O'
Failures do not shift the batch. An unparseable record becomes
Nonein place, so a parallel array of activities stays aligned:>>> out = standardizer.transform([mol, None]) >>> [m is None for m in out] [False, True]
handle_stereochemistry="remove"strips stereocentres, which is what you want when comparing 2D scaffolds rather than modelling enantiomer-specific activity:>>> flat = MolecularStandardizer(handle_stereochemistry="remove") >>> Chem.MolToSmiles(flat.transform([Chem.MolFromSmiles("C[C@H](N)C(=O)O")])[0]) 'CC(N)C(=O)O'
References
Sitzmann et al. (2010). “Tautomerism in Large Databases.” J. Comput. Aided Mol. Des., 24, 521-551. https://doi.org/10.1007/s10822-010-9346-4
RDKit MolStandardize documentation: https://www.rdkit.org/docs/source/rdkit.Chem.MolStandardize.html
OECD (2007). “Guidance Document on the Validation of (Quantitative) Structure-Activity Relationship [(Q)SAR] Models,” ENV/JM/MONO(2007)2. https://doi.org/10.1787/9789264085442-en
- set_fit_request(*, mols='$UNCHANGED$')¶
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- set_transform_request(*, mols='$UNCHANGED$')¶
Configure whether metadata should be requested to be passed to the
transformmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed totransformif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it totransform.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- class qsarkit.chemistry.GlycanDetector(min_exocyclic_oxygens=2)[source]¶
Bases:
objectDetect carbohydrate (sugar) ring systems in a molecule.
Uses the circular-sugar detection strategy of the Sugar Removal Utility (SRU): a candidate ring is a 5- or 6-membered ring with exactly one ring oxygen and only sp3 carbons otherwise, and is accepted as a sugar only if it is decorated with enough exocyclic oxygens (hydroxyls / glycosidic ethers / an exocyclic CH2OH) to match the hydroxylation pattern of a real aldose/ketose ring - which excludes plain carbocycles (cyclohexane) and simple ethers (tetrahydropyran, tetrahydrofuran).
- Parameters:
min_exocyclic_oxygens (
int) – Exocyclic oxygens a candidate ring must carry to be called a sugar. Lowering it admits deoxy sugars along with false positives; raising it rejects rhamnose and other deoxy sugars.
Examples
Quercetin 3-O-glucoside carries one pyranose ring, contributing 39% of the molecular weight:
>>> from rdkit import Chem >>> from qsarkit.chemistry import GlycanDetector >>> q3g = Chem.MolFromSmiles( ... "OC[C@H]1O[C@@H](Oc2c(-c3ccc(O)c(O)c3)oc3cc(O)cc(O)c3c2=O)" ... "[C@H](O)[C@@H](O)[C@@H]1O") >>> result = GlycanDetector().detect(q3g) >>> result["num_sugar_residues"] 1 >>> round(result["glycan_mw_fraction"], 3) 0.386
The exocyclic-oxygen requirement is what separates a sugar from a look-alike ring. Tetrahydropyran has the right ring but no hydroxylation, and is correctly rejected:
>>> GlycanDetector().detect(Chem.MolFromSmiles("C1CCOCC1"))["num_sugar_residues"] 0 >>> GlycanDetector().detect(Chem.MolFromSmiles("CCO"))["num_sugar_residues"] 0
References
Fischer et al. (2020). “The Sugar Removal Utility (SRU): An Open-Source Peptide- and Sugar-Stripping Tool for Chemical Structure Databases.” Molecules, 25(8), 1988. https://doi.org/10.3390/molecules25081988
RDKit ring perception documentation: https://www.rdkit.org/docs/RDKit_Book.html#ring-perception
- find_glycans(mol)[source]¶
Return one
GlycanMatchper detected sugar ring.- Return type:
List[GlycanMatch]
- detect(mol)[source]¶
Summarize glycan content of a molecule.
- Returns:
num_sugar_residues: number of detected sugar rings.glycan_atoms: sorted list of atom indices belonging to glycan rings/substituents.glycan_mw_fraction: fraction of the molecule’s molecular weight contributed by glycan atoms (including attached H’s).- Return type:
- class qsarkit.chemistry.GlycanRemover(detector=None)[source]¶
Bases:
objectRemove carbohydrate (sugar) moieties, keeping the aglycone core.
Detects sugar rings with
GlycanDetector, cleaves the glycosidic (single) bonds linking sugar atoms to the rest of the molecule, and returns the largest non-sugar fragment as the “aglycone” - e.g. quercetin-3-glucoside -> quercetin.- Parameters:
detector (
Optional[GlycanDetector]) – Detector used to locate sugar rings. A default instance is created if not supplied.
Examples
>>> from rdkit import Chem >>> from qsarkit.chemistry import GlycanRemover >>> q3g = Chem.MolFromSmiles( ... "OC[C@H]1O[C@@H](Oc2c(-c3ccc(O)c(O)c3)oc3cc(O)cc(O)c3c2=O)" ... "[C@H](O)[C@@H](O)[C@@H]1O") >>> result = GlycanRemover().remove(q3g) >>> Chem.MolToSmiles(result["aglycone"]) 'O=c1cc(-c2ccc(O)c(O)c2)oc2cc(O)cc(O)c12'
The result keeps the input alongside what was cut away, so a curation step can record why a structure changed:
>>> sorted(result) ['aglycone', 'original', 'removed_fragments']
Deglycosylation matters for QSAR because the sugar usually carries no activity of its own but dominates the fingerprint, so two glycosides of unrelated aglycones look more similar to each other than either does to its own aglycone. A molecule with no sugar passes through unchanged:
>>> aspirin = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)O") >>> Chem.MolToSmiles(GlycanRemover().remove(aspirin)["aglycone"]) 'CC(=O)Oc1ccccc1C(=O)O'
References
Fischer et al. (2020). “The Sugar Removal Utility (SRU).” Molecules, 25(8), 1988. https://doi.org/10.3390/molecules25081988
RDKit fragmentation documentation (
Chem.GetMolFrags,Chem.RWMol): https://www.rdkit.org/docs/GettingStartedInPython.html
- remove(mol)[source]¶
Remove glycan moieties from a single molecule.
- Returns:
original: the input Mol.aglycone: the largest non-sugar fragment, orNoneif the whole molecule was consumed by sugar rings.removed_fragments: list of removed sugar (and any other minor) fragments as Mol objects.- Return type:
- class qsarkit.chemistry.GlycanDescriptors(detector=None)[source]¶
Bases:
MoleculeTransformerCompute glycan-content descriptors for a batch of molecules.
The three columns produced are:
sugar_countNumber of detected sugar rings (see
GlycanDetector).glycan_fractionFraction of molecular weight contributed by glycan atoms.
glycosylation_patternComma-separated summary such as
"6-ring:O-glycoside x2"describing ring size and linkage type of each detected sugar.
- Parameters:
detector (
Optional[GlycanDetector])
Notes
Unlike the transformers in
qsarkit.representation, this one returns apandas.DataFramerather than a NumPy array, becauseglycosylation_patternis a string. Forcing it into an array would give the whole blockobjectdtype and lose the numeric columns’ types.Examples
>>> from rdkit import Chem >>> from qsarkit.chemistry import GlycanDescriptors >>> q3g = Chem.MolFromSmiles( ... "OC[C@H]1O[C@@H](Oc2c(-c3ccc(O)c(O)c3)oc3cc(O)cc(O)c3c2=O)" ... "[C@H](O)[C@@H](O)[C@@H]1O") >>> df = GlycanDescriptors().transform([q3g, Chem.MolFromSmiles("CCO")]) >>> list(df.columns) ['sugar_count', 'glycan_fraction', 'glycosylation_pattern'] >>> df["sugar_count"].tolist() [1, 0] >>> df["glycosylation_pattern"][0] '6-ring:terminal'
References
Fischer et al. (2020). “The Sugar Removal Utility (SRU).” Molecules, 25(8), 1988. https://doi.org/10.3390/molecules25081988
- set_fit_request(*, mols='$UNCHANGED$')¶
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- set_transform_request(*, mols='$UNCHANGED$')¶
Configure whether metadata should be requested to be passed to the
transformmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed totransformif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it totransform.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- class qsarkit.chemistry.FragmentRemover(groups=None, max_iterations=5)[source]¶
Bases:
MoleculeToMoleculeTransformerStrip protecting groups, synthesis linkers, tags and click-handles.
Matches each pattern in
groupsas a substituent attached to the core structure via a single bond, deletes the matched atoms, and caps the resulting open valence with an implicit hydrogen - conceptually the reverse of a protection reaction.- Parameters:
groups (
Optional[Dict[str,str]]) – Mapping of group name -> SMARTS pattern. Defaults toDEFAULT_GROUPS(Boc, Cbz, Fmoc, acetyl, TBS, trityl, benzyl ether, PEG linkers, biotin tag, azide/alkyne click handles).max_iterations (
int) – Repeat removal up to this many times per molecule, since removing one group can expose another (e.g. a doubly-Boc-protected amine).
Examples
Boc-protected benzylamine loses its carbamate:
>>> from rdkit import Chem >>> from qsarkit.chemistry import FragmentRemover >>> boc = Chem.MolFromSmiles("CC(C)(C)OC(=O)NCc1ccccc1") >>> Chem.MolToSmiles(FragmentRemover().transform([boc])[0]) 'NCc1ccccc1'
This belongs in curation because a protecting group is a synthesis artefact, not a pharmacophore: leaving it on makes every intermediate in a series look like a distinct chemotype and lets a model key on the tag instead of the chemistry.
Restricting
groupsnarrows what is stripped – here Boc is not in the set, so the molecule is returned unchanged:>>> only_acetyl = FragmentRemover(groups={"acetyl": "[CX3](=O)[CH3]"}) >>> Chem.MolToSmiles(only_acetyl.transform([boc])[0]) 'CC(C)(C)OC(=O)NCc1ccccc1'
References
Wuts, P. G. M. & Greene, T. W. (2014). “Greene’s Protective Groups in Organic Synthesis,” 5th ed. Wiley. https://doi.org/10.1002/9781118978075
RDKit reaction/substructure editing documentation: https://www.rdkit.org/docs/GettingStartedInPython.html#chemical-reactions
- set_fit_request(*, mols='$UNCHANGED$')¶
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- set_transform_request(*, mols='$UNCHANGED$')¶
Configure whether metadata should be requested to be passed to the
transformmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed totransformif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it totransform.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- class qsarkit.chemistry.CoreExtractor[source]¶
Bases:
objectExtract a representative structural core from one or more molecules.
Three definitions of “core”, answering different questions:
bemis_murcko()gives ring systems plus linkers (the classic scaffold definition), or the fully generic skeleton with element and bond-order information stripped.mcs()gives the maximum common substructure across a set of molecules, which is the right notion for a congeneric series.medchem_core()gives a medicinal-chemistry-oriented core: the Bemis-Murcko scaffold with terminal exocyclic double bonds trimmed back to rings, which tends to match how chemists describe a series’ “core” more closely than the strict Murcko definition.
Examples
>>> from rdkit import Chem >>> from qsarkit.chemistry import CoreExtractor >>> extractor = CoreExtractor() >>> paracetamol_like = Chem.MolFromSmiles("CC(=O)Nc1ccc(Cl)cc1") >>> Chem.MolToSmiles(extractor.bemis_murcko(paracetamol_like)) 'c1ccccc1'
generic=Truediscards element identity and bond order, so pyridine and benzene analogues collapse onto one skeleton – the right granularity for asking “how many ring systems are in this library”, the wrong one for asking “which chemotype is this”:>>> Chem.MolToSmiles(extractor.bemis_murcko(paracetamol_like, generic=True)) 'C1CCCCC1'
mcs()works across a series rather than on one molecule, and returns the shared substructure as a query mol:>>> pair = [Chem.MolFromSmiles(s) for s in ... ("CC(=O)Nc1ccc(Cl)cc1", "CC(=O)Nc1ccc(Br)cc1")] >>> Chem.MolToSmarts(extractor.mcs(pair)) '[#6]-[#6](=[#8])-[#7]-[#6]1:[#6]:[#6]:[#6]:[#6]:[#6]:1'
References
Bemis, G. W. & Murcko, M. A. (1996). “The Properties of Known Drugs. 1. Molecular Frameworks.” J. Med. Chem., 39(15), 2887-2893. https://doi.org/10.1021/jm9602928
Rogers, D. & Hahn, M. (2010) discuss MCS-based series analysis; canonical algorithm: Cao, Y. et al. (2008). “A Maximum Common Substructure-Based Algorithm for Searching and Predicting Drug-like Compounds.” Bioinformatics, 24(13), i366-i374. https://doi.org/10.1093/bioinformatics/btn186
RDKit
rdFMCSandChem.Scaffolds.MurckoScaffolddocumentation: https://www.rdkit.org/docs/source/rdkit.Chem.Scaffolds.MurckoScaffold.html https://www.rdkit.org/docs/source/rdkit.Chem.rdFMCS.html
- class qsarkit.chemistry.MolecularGraph[source]¶
Bases:
objectConvert RDKit molecules to NetworkX graphs and compute graph descriptors.
Atoms become nodes carrying
symbol,atomic_num,formal_charge,is_aromatic,in_ring,degreeandhybridization; bonds become edges carryingbond_type,is_aromatic,in_ringandorder. This is the substrate for the topological indices below, and for any analysis that is easier to express with NetworkX than with RDKit’s own graph API.Examples
>>> from rdkit import Chem >>> from qsarkit.chemistry import MolecularGraph >>> graph = MolecularGraph() >>> G = graph.to_networkx(Chem.MolFromSmiles("CCO")) >>> G.number_of_nodes(), G.number_of_edges() (3, 2) >>> G.nodes[2]["symbol"], G.nodes[2]["hybridization"] ('O', 'SP3')
Hydrogens are implicit, so a node’s heavy-atom
degreeand itsnum_hsare reported separately:>>> G.nodes[0]["degree"], G.nodes[0]["num_hs"] (1, 3)
descriptors()returns the classic topological indices for a single molecule:>>> d = graph.descriptors(Chem.MolFromSmiles("c1ccccc1")) >>> d["num_rings"], d["cyclomatic_number"], d["diameter"] (1, 1, 3) >>> round(d["wiener_index"], 1) 27.0
References
Hagberg, A., Schult, D. & Swart, P. (2008). “Exploring Network Structure, Dynamics, and Function using NetworkX.” Proc. SciPy 2008. https://www.osti.gov/biblio/960616
Wiener, H. (1947). “Structural Determination of Paraffin Boiling Points.” J. Am. Chem. Soc., 69(1), 17-20. https://doi.org/10.1021/ja01193a005
Balaban, A. T. (1982). “Highly Discriminating Distance-Based Topological Index.” Chem. Phys. Lett., 89(5), 399-404. https://doi.org/10.1016/0009-2614(82)80009-2
RDKit graph descriptors documentation: https://www.rdkit.org/docs/source/rdkit.Chem.GraphDescriptors.html
References¶
Fourches, D., Muratov, E. & Tropsha, A. (2010). “Trust, But Verify.” J. Chem. Inf. Model., 50(7), 1189-1204. doi:10.1021/ci100176x
Fischer, J. et al. (2020). “The Sugar Removal Utility.” Molecules, 25(8), 1988. doi:10.3390/molecules25081988
Bemis, G. W. & Murcko, M. A. (1996). “The Properties of Known Drugs. 1. Molecular Frameworks.” J. Med. Chem., 39(15), 2887-2893. doi:10.1021/jm9602928