Repository: deepchem/deepchem
Issue: use_chirality in WeaveFeaturizer

System:

- DeepChem Version: 2.3.0 (built from source with GPU support)
- Platform: Linux Fedora 30 

WeaveFeaturizer does not seem to work when setting ```use_chirality=True```:

```
...
~/anaconda3/envs/deepchem_gpu/lib/python3.5/site-packages/deepchem/feat/graph_features.py in _featurize(self, mol)
    436         canon_adj_list,
    437         bt_len=6,
--> 438         graph_distance=self.graph_distance)
    439 
    440     return WeaveMol(nodes, pairs)

~/anaconda3/envs/deepchem_gpu/lib/python3.5/site-packages/deepchem/feat/graph_features.py in pair_features(mol, edge_list, canon_adj_list, bt_len, graph_distance)
    230       # first `bt_len` features are bond features(if applicable)
    231       features[a1, a2, :bt_len] = np.asarray(
--> 232           edge_list[tuple(sorted((a1, a2)))], dtype=float)
    233     for ring in rings:
    234       if a1 in ring:

ValueError: could not broadcast input array from shape (10) into shape (6)
```

The ```bt_len``` variable in line 437 in graph_features.py appears to be hard-coded as 6. A small work-around that worked for me was adding the following code to ```def _featurize(self, mol)``` of the ```WeaveFeaturizer``` class in graph_features.py:
```
    if self.use_chirality:
        bt_len_var = 10
    else:
        bt_len_var = 6
```
line 437: ``` bt_len=bt_len_var```

Best regards,
J.

Changed files:
deepchem/feat/graph_features.py, deepchem/data/data_loader.py

diff --git a/deepchem/data/data_loader.py b/deepchem/data/data_loader.py
index 8afd8176d..373666efb 100644
--- a/deepchem/data/data_loader.py
+++ b/deepchem/data/data_loader.py
@@ -128,7 +128,8 @@ def get_user_specified_features(df, featurizer, verbose=True):
   time1 = time.time()
   df[featurizer.feature_fields] = df[featurizer.feature_fields].apply(
       pd.to_numeric)
-  X_shard = df.as_matrix(columns=featurizer.feature_fields)
+  df_fields = df[featurizer.feature_fields]
+  X_shard = df_fields.values
   time2 = time.time()
   log("TIMING: user specified processing took %0.3f s" % (time2 - time1),
       verbose)
diff --git a/deepchem/feat/graph_features.py b/deepchem/feat/graph_features.py
index daca74b14..89d9ba91b 100644
--- a/deepchem/feat/graph_features.py
+++ b/deepchem/feat/graph_features.py
@@ -73,6 +73,8 @@ reference_lists = [
 ]
 
 intervals = get_intervals(reference_lists)
+possible_bond_stereo = ["STEREONONE", "STEREOANY", "STEREOZ", "STEREOE"]
+bond_fdim_base = 6
 
 
 def get_feature_list(atom):
@@ -210,8 +212,7 @@ def bond_features(bond, use_chirality=False):
   ]
   if use_chirality:
     bond_feats = bond_feats + one_of_k_encoding_unk(
-        str(bond.GetStereo()),
-        ["STEREONONE", "STEREOANY", "STEREOZ", "STEREOE"])
+        str(bond.GetStereo()), possible_bond_stereo)
   return np.array(bond_feats)
 
 
@@ -287,19 +288,19 @@ class ConvMolFeaturizer(Featurizer):
       Neural Message Passing for Quantum Chemistry
       https://arxiv.org/pdf/1704.01212.pdf
     use_chirality: Boolean
-      if true then make the resulting atom features aware of the 
+      if true then make the resulting atom features aware of the
       chirality of the molecules in question
     atom_properties: list of string or None
       properties in the RDKit Mol object to use as additional
       atom-level features in the larger molecular feature.  If None,
-      then no atom-level properties are used.  Properties should be in the 
-      RDKit mol object should be in the form 
+      then no atom-level properties are used.  Properties should be in the
+      RDKit mol object should be in the form
       atom XXXXXXXX NAME
       where XXXXXXXX is a zero-padded 8 digit number coresponding to the
       zero-indexed atom index of each atom and NAME is the name of the property
       provided in atom_properties.  So "atom 00000000 sasa" would be the
-      name of the molecule level property in mol where the solvent 
-      accessible surface area of atom 0 would be stored. 
+      name of the molecule level property in mol where the solvent
+      accessible surface area of atom 0 would be stored.
 
     Since ConvMol is an object and not a numpy array, need to set dtype to
     object.
@@ -314,7 +315,7 @@ class ConvMolFeaturizer(Featurizer):
     For a given input RDKit atom return the values of the properties
     requested when initializing the featurize.  See the __init__ of the
     class for a full description of the names of the properties
-    
+
     Parameters
     ----------
     atom: RDKit.rdchem.Atom
@@ -396,6 +397,10 @@ class WeaveFeaturizer(Featurizer):
     self.explicit_H = explicit_H
     # If uses use_chirality
     self.use_chirality = use_chirality
+    if self.use_chirality:
+      self.bt_len = bond_fdim_base + len(possible_bond_stereo)
+    else:
+      self.bt_len = bond_fdim_base
 
   def _featurize(self, mol):
     """Encodes mol as a WeaveMol object."""
@@ -430,7 +435,7 @@ class WeaveFeaturizer(Featurizer):
         mol,
         edge_list,
         canon_adj_list,
-        bt_len=6,
+        bt_len=self.bt_len,
         graph_distance=self.graph_distance)
 
     return WeaveMol(nodes, pairs)