class_docstr: Generate molecule conformers.
  
  Notes
  -----
  Procedure
  1. Generate a pool of conformers.
  2. Minimize conformers.
  3. Prune conformers using an RMSD threshold.
  
  Note that pruning is done _after_ minimization, which differs from the
  protocol described in the references [1]_ [2]_.
  
  References
  ----------
  .. [1] http://rdkit.org/docs/GettingStartedInPython.html#working-with-3d-molecules
  .. [2] http://pubs.acs.org/doi/full/10.1021/ci2004658
  
  Notes
  -----
  This class requires RDKit to be installed.
docstr: Prune conformers from a molecule using an RMSD threshold, starting
  with the lowest energy conformer.
  
  Parameters
  ----------
  mol: rdkit.Chem.rdchem.Mol
      RDKit Mol object
  
  Returns
  -------
  new_mol: rdkit.Chem.rdchem.Mol
      A new rdkit.Chem.rdchem.Mol containing the chosen conformers, sorted by
      increasing energy.
docstr_tok: ["Prune","conformers","from","a","molecule","using","an","RMSD","threshold",",","starting","with","the","lowest","energy","conformer",".","Parameters","--","--","--","--","--","mol",":","rdkit.Chem.rdchem.Mol","RDKit","Mol","object","Returns","--","--","--","-","new_mol",":","rdkit.Chem.rdchem.Mol","A","new","rdkit.Chem.rdchem.Mol","containing","the","chosen","conformers",",","sorted","by","increasing","energy","."]
code: def prune_conformers(self, mol: RDKitMol) -> RDKitMol:
      """
      Prune conformers from a molecule using an RMSD threshold, starting
      with the lowest energy conformer.
  
      Parameters
      ----------
      mol: rdkit.Chem.rdchem.Mol
          RDKit Mol object
  
      Returns
      -------
      new_mol: rdkit.Chem.rdchem.Mol
          A new rdkit.Chem.rdchem.Mol containing the chosen conformers, sorted by
          increasing energy.
      """
      try:
          from rdkit import Chem
      except ModuleNotFoundError:
          raise ImportError(
              "This function requires RDKit to be installed."
          )
  
      if self.rmsd_threshold < 0 or mol.GetNumConformers() <= 1:
          return mol
      energies = self.get_conformer_energies(mol)
      rmsd = self.get_conformer_rmsd(mol)
  
      sort = np.argsort(energies)  # sort by increasing energy
      keep: List[float] = []  # always keep lowest-energy conformer
      discard = []
      for i in sort:
          # always keep lowest-energy conformer
          if len(keep) == 0:
              keep.append(i)
              continue
  
          # discard conformers after max_conformers is reached
          if len(keep) >= self.max_conformers:
              discard.append(i)
              continue
  
          # get RMSD to selected conformers
          this_rmsd = rmsd[i][np.asarray(keep, dtype=int)]
  
          # discard conformers within the RMSD threshold
          if np.all(this_rmsd >= self.rmsd_threshold):
              keep.append(i)
          else:
              discard.append(i)
  
      # create a new molecule to hold the chosen conformers
      # this ensures proper conformer IDs and energy-based ordering
      new_mol = Chem.Mol(mol)
      new_mol.RemoveAllConformers()
      conf_ids = [conf.GetId() for conf in mol.GetConformers()]
      for i in keep:
          conf = mol.GetConformer(conf_ids[i])
          new_mol.AddConformer(conf, assignId=True)
      return new_mol
  
file_path: deepchem/deepchem/utils/conformers.py
imports: import numpy
  from typing import Any, List, Optional
  from deepchem.utils.typing import RDKitMol
label_desc: Use image node_id 8 for calling the ConformerGenerator obj's underlying member method code with example usage: obj.prune_conformers(mol) and returns: new_mol, mol