class_docstr: This class is a featurizer for Directed Message Passing Neural Network (D-MPNN) implementation
  
  The default node(atom) and edge(bond) representations are based on
  `Analyzing Learned Molecular Representations for Property Prediction paper <https://arxiv.org/pdf/1904.01561.pdf>`_.
  
  The default node representation are constructed by concatenating the following values,
  and the feature length is 133.
  
  - Atomic num: A one-hot vector of this atom, in a range of first 100 atoms.
  - Degree: A one-hot vector of the degree (0-5) of this atom.
  - Formal charge: Integer electronic charge, -1, -2, 1, 2, 0.
  - Chirality: A one-hot vector of the chirality tag (0-3) of this atom.
  - Number of Hydrogens: A one-hot vector of the number of hydrogens (0-4) that this atom connected.
  - Hybridization: A one-hot vector of "SP", "SP2", "SP3", "SP3D", "SP3D2".
  - Aromatic: A one-hot vector of whether the atom belongs to an aromatic ring.
  - Mass: Atomic mass * 0.01
  
  The default edge representation are constructed by concatenating the following values,
  and the feature length is 14.
  
  - Bond type: A one-hot vector of the bond type, "single", "double", "triple", or "aromatic".
  - Same ring: A one-hot vector of whether the atoms in the pair are in the same ring.
  - Conjugated: A one-hot vector of whether this bond is conjugated or not.
  - Stereo: A one-hot vector of the stereo configuration (0-5) of a bond.
  
  If you want to know more details about features, please check the paper [1]_ and
  utilities in deepchem.utils.molecule_feature_utils.py.
  
  Examples
  --------
  >>> smiles = ["C1=CC=CN=C1", "C1CCC1"]
  >>> featurizer = DMPNNFeaturizer()
  >>> out = featurizer.featurize(smiles)
  >>> type(out[0])
  <class 'deepchem.feat.graph_data.GraphData'>
  >>> out[0].num_nodes
  6
  >>> out[0].num_node_features
  133
  >>> out[0].node_features.shape
  (6, 133)
  >>> out[0].num_edge_features
  14
  >>> out[0].num_edges
  12
  >>> out[0].edge_features.shape
  (12, 14)
  
  References
  ----------
  .. [1] Kearnes, Steven, et al. "Molecular graph convolutions: moving beyond fingerprints."
      Journal of computer-aided molecular design 30.8 (2016):595-608.
  
  Note
  ----
  This class requires RDKit to be installed.
class_docstr_tok: ["This","class","is","a","featurizer","for","Directed","Message","Passing","Neural","Network","(","D-MPNN",")","implementation","The","default","node","(","atom",")","and","edge","(","bond",")","representations","are","based","on","`","Analyzing","Learned","Molecular","Representations","for","Property","Prediction","paper","<","https",":","\/\/arxiv.org\/pdf\/1904.01561.pdf",">","`","_",".","The","default","node","representation","are","constructed","by","concatenating","the","following","values",",","and","the","feature","length","is","133",".","-","Atomic","num",":","A","one-hot","vector","of","this","atom",",","in","a","range","of","first","100","atoms",".","-","Degree",":","A","one-hot","vector","of","the","degree","(","0-5",")","of","this","atom",".","-","Formal","charge",":","Integer","electronic","charge",",","-1",",","-2",",","1",",","2",",","0",".","-","Chirality",":","A","one-hot","vector","of","the","chirality","tag","(","0-3",")","of","this","atom",".","-","Number","of","Hydrogens",":","A","one-hot","vector","of","the","number","of","hydrogens","(","0-4",")","that","this","atom","connected",".","-","Hybridization",":","A","one-hot","vector","of","``","SP","''",",","``","SP2","''",",","``","SP3","''",",","``","SP3D","''",",","``","SP3D2","''",".","-","Aromatic",":","A","one-hot","vector","of","whether","the","atom","belongs","to","an","aromatic","ring",".","-","Mass",":","Atomic","mass","*","0.01","The","default","edge","representation","are","constructed","by","concatenating","the","following","values",",","and","the","feature","length","is","14",".","-","Bond","type",":","A","one-hot","vector","of","the","bond","type",",","``","single","''",",","``","double","''",",","``","triple","''",",","or","``","aromatic","''",".","-","Same","ring",":","A","one-hot","vector","of","whether","the","atoms","in","the","pair","are","in","the","same","ring",".","-","Conjugated",":","A","one-hot","vector","of","whether","this","bond","is","conjugated","or","not",".","-","Stereo",":","A","one-hot","vector","of","the","stereo","configuration","(","0-5",")","of","a","bond",".","If","you","want","to","know","more","details","about","features",",","please","check","the","paper","[","1","]","_","and","utilities","in","deepchem.utils.molecule_feature_utils.py",".","Examples","--","--","--","--",">",">",">","smiles","=","[","``","C1=CC=CN=C1","''",",","``","C1CCC1","''","]",">",">",">","featurizer","=","DMPNNFeaturizer","(",")",">",">",">","out","=","featurizer.featurize","(","smiles",")",">",">",">","type","(","out","[","0","]",")","<","class","'deepchem.feat.graph_data.GraphData","'",">",">",">",">","out","[","0","]",".num_nodes","6",">",">",">","out","[","0","]",".num_node_features","133",">",">",">","out","[","0","]",".node_features.shape","(","6",",","133",")",">",">",">","out","[","0","]",".num_edge_features","14",">",">",">","out","[","0","]",".num_edges","12",">",">",">","out","[","0","]",".edge_features.shape","(","12",",","14",")","References","--","--","--","--","--","..","[","1","]","Kearnes",",","Steven",",","et","al",".","``","Molecular","graph","convolutions",":","moving","beyond","fingerprints",".","''","Journal","of","computer-aided","molecular","design","30.8","(","2016",")",":595-608",".","Note","--","--","This","class","requires","RDKit","to","be","installed","."]
docstr: Construct bond(edge) features for the given datapoint
  
  For each bond index, 2 bond feature arrays are added to the main features array,
  for the current bond and its reverse bond respectively.
  
  Note: This method of generating bond features ensures that the shape of the bond features array
      is always equal to (number of bonds, number of bond features), even if the number of bonds
      is equal to 0.
  
  Parameters
  ----------
  datapoint: RDKitMol
      RDKit mol object.
  
  Returns
  -------
  f_bonds: np.ndarray
      Bond features array
docstr_tok: ["Construct","bond","(","edge",")","features","for","the","given","datapoint","For","each","bond","index",",","2","bond","feature","arrays","are","added","to","the","main","features","array",",","for","the","current","bond","and","its","reverse","bond","respectively",".","Note",":","This","method","of","generating","bond","features","ensures","that","the","shape","of","the","bond","features","array","is","always","equal","to","(","number","of","bonds",",","number","of","bond","features",")",",","even","if","the","number","of","bonds","is","equal","to","0",".","Parameters","--","--","--","--","--","datapoint",":","RDKitMol","RDKit","mol","object",".","Returns","--","--","--","-","f_bonds",":","np.ndarray","Bond","features","array"]
code: def _get_bond_features(self, datapoint: RDKitMol) -> np.ndarray:
      """
      Construct bond(edge) features for the given datapoint
  
      For each bond index, 2 bond feature arrays are added to the main features array,
      for the current bond and its reverse bond respectively.
  
      Note: This method of generating bond features ensures that the shape of the bond features array
          is always equal to (number of bonds, number of bond features), even if the number of bonds
          is equal to 0.
  
      Parameters
      ----------
      datapoint: RDKitMol
          RDKit mol object.
  
      Returns
      -------
      f_bonds: np.ndarray
          Bond features array
  
      """
      bonds: Chem.rdchem._ROBondSeq = datapoint.GetBonds()
  
      bond_fdim: int = GraphConvConstants.BOND_FDIM
      number_of_bonds: int = (
          len(bonds) * 2
      )  # Note the value is doubled to account for reverse bonds
      f_bonds: np.ndarray = np.empty((number_of_bonds, bond_fdim))
  
      for index in range(0, number_of_bonds, 2):
          bond_id: int = index // 2
          bond_feature: np.ndarray = np.asarray(
              bond_features(bonds[bond_id]), dtype=float
          )
          f_bonds[index] = bond_feature  # bond
          f_bonds[index + 1] = bond_feature  # reverse bond
      return f_bonds
  
imports: from rdkit import Chem
  import numpy
  import logging
  from typing import List, Tuple, Union, Dict, Set, Sequence, Optional
  from deepchem.utils.typing import RDKitAtom, RDKitMol, RDKitBond
  from deepchem.feat.base_classes import MolecularFeaturizer
  from deepchem.feat.graph_data import GraphData
  from deepchem.feat.molecule_featurizers.circular_fingerprint import CircularFingerprint
  from deepchem.feat.molecule_featurizers.rdkit_descriptors import RDKitDescriptors
  from deepchem.utils.molecule_feature_utils import one_hot_encode
  from deepchem.utils.molecule_feature_utils import get_atom_total_degree_one_hot
  from deepchem.utils.molecule_feature_utils import get_atom_formal_charge_one_hot
  from deepchem.utils.molecule_feature_utils import get_atom_total_num_Hs_one_hot
  from deepchem.utils.molecule_feature_utils import get_atom_hybridization_one_hot
  from deepchem.utils.molecule_feature_utils import get_atom_is_in_aromatic_one_hot
  from deepchem.feat.graph_features import bond_features
label_desc: Use image node_id 3 for calling the DMPNNFeaturizer obj's underlying member method code with example usage: obj._get_bond_features(datapoint) and returns: f_bonds