class_docstr: This class implements the featurization to implement Weave convolutions.
  
  Weave convolutions were introduced in [1]_. Unlike Duvenaud graph
  convolutions, weave convolutions require a quadratic matrix of interaction
  descriptors for each pair of atoms. These extra descriptors may provide for
  additional descriptive power but at the cost of a larger featurized dataset.
  
  
  Examples
  --------
  >>> import deepchem as dc
  >>> mols = ["CCC"]
  >>> featurizer = dc.feat.WeaveFeaturizer()
  >>> features = featurizer.featurize(mols)
  >>> type(features[0])
  <class 'deepchem.feat.mol_graphs.WeaveMol'>
  >>> features[0].get_num_atoms() # 3 atoms in compound
  3
  >>> features[0].get_num_features() # feature size
  75
  >>> type(features[0].get_atom_features())
  <class 'numpy.ndarray'>
  >>> features[0].get_atom_features().shape
  (3, 75)
  >>> type(features[0].get_pair_features())
  <class 'numpy.ndarray'>
  >>> features[0].get_pair_features().shape
  (9, 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: Encodes mol as a WeaveMol object.
docstr_tok: ["Encodes","mol","as","a","WeaveMol","object","."]
code: def _featurize(self, mol):
      """Encodes mol as a WeaveMol object."""
      # Atom features
      idx_nodes = [
          (
              a.GetIdx(),
              atom_features(
                  a,
                  explicit_H=self.explicit_H,
                  use_chirality=self.use_chirality,
              ),
          )
          for a in mol.GetAtoms()
      ]
      idx_nodes.sort()  # Sort by ind to ensure same order as rd_kit
      idx, nodes = list(zip(*idx_nodes))
  
      # Stack nodes into an array
      nodes = np.vstack(nodes)
  
      # Get bond lists
      bond_features_map = {}
      for b in mol.GetBonds():
          bond_features_map[
              tuple(sorted([b.GetBeginAtomIdx(), b.GetEndAtomIdx()]))
          ] = bond_features(b, use_chirality=self.use_chirality)
  
      # Get canonical adjacency list
      bond_adj_list = [[] for mol_id in range(len(nodes))]
      for bond in bond_features_map.keys():
          bond_adj_list[bond[0]].append(bond[1])
          bond_adj_list[bond[1]].append(bond[0])
  
      # Calculate pair features
      pairs, pair_edges = pair_features(
          mol,
          bond_features_map,
          bond_adj_list,
          bt_len=self.bt_len,
          graph_distance=self.graph_distance,
          max_pair_distance=self.max_pair_distance,
      )
  
      return WeaveMol(nodes, pairs, pair_edges)
  
imports: import numpy
  import deepchem
  from deepchem.feat.base_classes import MolecularFeaturizer
  from deepchem.feat.mol_graphs import ConvMol, WeaveMol
  from deepchem.data import DiskDataset
  import logging
  from typing import Optional, List, Tuple, Union, Iterable
  from deepchem.utils.typing import RDKitMol, RDKitAtom
  from deepchem.utils.molecule_feature_utils import one_hot_encode
label_desc: Use image node_id 2 for calling the WeaveFeaturizer obj's underlying member method code with example usage: obj._featurize(mol) and returns: WeaveMol