Source code for qsarkit.representation.descriptors._rdkit_descriptors
"""The full catalogue of RDKit 2-D/topological descriptors."""
from __future__ import annotations
from typing import TYPE_CHECKING, Callable, List, Optional, Sequence, Tuple
from qsarkit.representation.descriptors._base import BaseDescriptorTransformer
if TYPE_CHECKING: # pragma: no cover
from rdkit.Chem import Mol
__all__ = ["RDKitDescriptors"]
[docs]
class RDKitDescriptors(BaseDescriptorTransformer):
"""Every descriptor registered in ``rdkit.Chem.Descriptors._descList``.
RDKit registers on the order of 200 2-D/topological/electronic
descriptors -- molecular weight and LogP, TPSA, connectivity and shape
indices (Chi, Kappa), BCUT eigenvalues, VSA bins (PEOE_VSA, SMR_VSA,
SlogP_VSA), fragment counts, ring/heteroatom counts, and more -- in a
single lookup table, ``Descriptors._descList``. This transformer
exposes that entire catalogue, or a user-selected subset of it, as one
dense, named feature block. A handful of these descriptors (notably
``Ipc`` on large fused-ring systems) can raise or overflow to
``inf``/``nan`` on some molecules; both cases are substituted with
``missing_value``.
Parameters
----------
descriptor_names : sequence of str, optional
Names of the descriptors to compute (must be keys of
``rdkit.Chem.Descriptors._descList``). ``None`` (default) computes
every registered descriptor, in the order RDKit registers them.
missing_value : float, default nan
Value substituted when a descriptor raises or returns a
non-finite value for a given molecule.
Examples
--------
>>> from rdkit import Chem
>>> from qsarkit.representation.descriptors import RDKitDescriptors
>>> rd = RDKitDescriptors(descriptor_names=["MolWt", "TPSA"])
>>> rd.fit_transform([Chem.MolFromSmiles("CCO")]).shape
(1, 2)
>>> list(rd.get_feature_names_out())
['MolWt', 'TPSA']
References
----------
- Landrum, G. RDKit: Open-source cheminformatics. https://www.rdkit.org
- RDKit documentation, "List of Available Descriptors":
https://www.rdkit.org/docs/GettingStartedInPython.html#list-of-available-descriptors
- Todeschini, R. & Consonni, V. (2009). "Molecular Descriptors for
Chemoinformatics." Wiley-VCH. https://doi.org/10.1002/9783527628766
"""
def __init__(
self,
descriptor_names: Optional[Sequence[str]] = None,
missing_value: float = float("nan"),
) -> None:
self.descriptor_names = descriptor_names
self.missing_value = missing_value
def _descriptor_functions(self) -> List[Tuple[str, Callable[["Mol"], float]]]:
from rdkit.Chem import Descriptors
catalogue = dict(Descriptors._descList)
if self.descriptor_names is None:
return list(catalogue.items())
missing = [n for n in self.descriptor_names if n not in catalogue]
if missing:
raise ValueError(
f"Unknown RDKit descriptor name(s): {missing!r}. See "
"rdkit.Chem.Descriptors._descList for valid names."
)
return [(name, catalogue[name]) for name in self.descriptor_names]