class_docstr: Abstract class for calculating a set of features for a
  molecule.
  
      The defining feature of a `MolecularFeaturizer` is that it
      uses SMILES strings and RDKit molecule objects to represent
      small molecules. All other featurizers which are subclasses of
      this class should plan to process input which comes as smiles
      strings or RDKit molecules.
  
      Child classes need to implement the _featurize method for
      calculating features for a single molecule.
  
      Note
      ----
      The subclasses of this class require RDKit to be installed.
      
class_docstr_tok: ["Abstract","class","for","calculating","a","set","of","features","for","a","molecule",".","The","defining","feature","of","a","`","MolecularFeaturizer","`","is","that","it","uses","SMILES","strings","and","RDKit","molecule","objects","to","represent","small","molecules",".","All","other","featurizers","which","are","subclasses","of","this","class","should","plan","to","process","input","which","comes","as","smiles","strings","or","RDKit","molecules",".","Child","classes","need","to","implement","the","_featurize","method","for","calculating","features","for","a","single","molecule",".","Note","--","--","The","subclasses","of","this","class","require","RDKit","to","be","installed","."]
docstr: Calculate features for molecules.
  
  Parameters
  ----------
  datapoints: rdkit.Chem.rdchem.Mol / SMILES string / iterable
      RDKit Mol, or SMILES string or iterable sequence of RDKit mols/SMILES
      strings.
  log_every_n: int, default 1000
      Logging messages reported every `log_every_n` samples.
  
  Returns
  -------
  features: np.ndarray
      A numpy array containing a featurized representation of `datapoints`.
docstr_tok: ["Calculate","features","for","molecules",".","Parameters","--","--","--","--","--","datapoints",":","rdkit.Chem.rdchem.Mol","\/","SMILES","string","\/","iterable","RDKit","Mol",",","or","SMILES","string","or","iterable","sequence","of","RDKit","mols\/SMILES","strings",".","log_every_n",":","int",",","default","1000","Logging","messages","reported","every","`","log_every_n","`","samples",".","Returns","--","--","--","-","features",":","np.ndarray","A","numpy","array","containing","a","featurized","representation","of","`","datapoints","`","."]
code: def featurize(
      self, datapoints, log_every_n=1000, **kwargs
  ) -> np.ndarray:
      """Calculate features for molecules.
  
      Parameters
      ----------
      datapoints: rdkit.Chem.rdchem.Mol / SMILES string / iterable
          RDKit Mol, or SMILES string or iterable sequence of RDKit mols/SMILES
          strings.
      log_every_n: int, default 1000
          Logging messages reported every `log_every_n` samples.
  
      Returns
      -------
      features: np.ndarray
          A numpy array containing a featurized representation of `datapoints`.
      """
      try:
          from rdkit import Chem
          from rdkit.Chem import rdmolfiles
          from rdkit.Chem import rdmolops
          from rdkit.Chem.rdchem import Mol
      except ModuleNotFoundError:
          raise ImportError(
              "This class requires RDKit to be installed."
          )
  
      if "molecules" in kwargs:
          datapoints = kwargs.get("molecules")
          raise DeprecationWarning(
              'Molecules is being phased out as a parameter, please pass "datapoints" instead.'
          )
  
      # Special case handling of single molecule
      if isinstance(datapoints, str) or isinstance(datapoints, Mol):
          datapoints = [datapoints]
      else:
          # Convert iterables to list
          datapoints = list(datapoints)
  
      features: list = []
      for i, mol in enumerate(datapoints):
          if i % log_every_n == 0:
              logger.info("Featurizing datapoint %i" % i)
  
          try:
              if isinstance(mol, str):
                  # condition if the original atom order is required
                  if (
                      hasattr(self, "use_original_atoms_order")
                      and self.use_original_atoms_order
                  ):
                      # mol must be a RDKit Mol object, so parse a SMILES
                      mol = Chem.MolFromSmiles(mol)
                  else:
                      # mol must be a RDKit Mol object, so parse a SMILES
                      mol = Chem.MolFromSmiles(mol)
                      # SMILES is unique, so set a canonical order of atoms
                      new_order = rdmolfiles.CanonicalRankAtoms(mol)
                      mol = rdmolops.RenumberAtoms(mol, new_order)
              kwargs_per_datapoint = {}
              for key in kwargs.keys():
                  kwargs_per_datapoint[key] = kwargs[key][i]
              features.append(
                  self._featurize(mol, **kwargs_per_datapoint)
              )
          except Exception as e:
              if isinstance(mol, Chem.rdchem.Mol):
                  mol = Chem.MolToSmiles(mol)
              logger.warning(
                  "Failed to featurize datapoint %d, %s. Appending empty array",
                  i,
                  mol,
              )
              logger.warning("Exception message: {}".format(e))
              features.append(np.array([]))
      try:
          return np.asarray(features)
      except ValueError as e:
          logger.warning("Exception message: {}".format(e))
          return np.asarray(features, dtype=object)
  
imports: import inspect
  import logging
  import numpy
  from typing import Any, Dict, Iterable, Optional, Tuple, Union, cast
  from deepchem.utils import get_print_threshold
  from deepchem.utils.typing import PymatgenStructure
label_desc: Use image node_id 2 for calling the MolecularFeaturizer obj's underlying member method code with example usage: obj.featurize(datapoints, log_every_n) and returns: np, np