Commit 921f06dc authored by alat-rights's avatar alat-rights
Browse files

First commit: new unit tests, modified one_hot_featurizer to handle arbitrary strings

Unit tests currently failing.
parent 252090d4
Loading
Loading
Loading
Loading
+41 −25
Original line number Diff line number Diff line
@@ -42,57 +42,73 @@ class OneHotFeaturizer(MolecularFeaturizer):
    self.charset = charset
    self.max_length = max_length

  def _featurize(self, mol: RDKitMol) -> np.ndarray:
    """Compute one-hot featurization of this molecule.
  def _featurize(self, string: str) -> np.ndarray:
    """Compute one-hot featurization of string.

    Parameters
    ----------
    mol: rdkit.Chem.rdchem.Mol
      RDKit Mol object
    str: An arbitrary string to be featurized.

    Returns
    -------
    np.ndarray
      An one hot vector encoded from SMILES.
      An one hot vector encoded from arbitrary input string.
      The shape is `(max_length, len(charset) + 1)`.
      The index of unknown character is `len(charset)`.
    """
    try:
      from rdkit import Chem
    except ModuleNotFoundError:
      raise ImportError("This class requires RDKit to be installed.")

    smiles = Chem.MolToSmiles(mol)
    # validation
    if len(smiles) > self.max_length:
    if len(string) > self.max_length:
      logger.info(
          "The length of {} is longer than `max_length`. So we return an empty array."
      )
      return np.array([])

    smiles = self.pad_smile(smiles)
    string = self.pad_string(string)
    return np.array([
        one_hot_encode(val, self.charset, include_unknown_set=True)
        for val in smiles
        for val in string 
    ])

  def pad_smile(self, smiles: str) -> str:
  def _featurizeMol(self, mol: RDKitMol) -> np.ndarray:
    """Compute one-hot featurization of this molecule.

    Parameters
    ----------
    mol: rdKit.Chem.rdchem.Mol
      RDKit Mol object
    
    Returns
    -------
    np.ndarray
      An one hot vector encoded from SMILES.
      The shape is '(max_length, len(charset) + 1)'
      The index of unknown character is 'len(charset)'.
    """
    try:
      from rdkit import Chem
    except ModuleNotFoundError:
      raise ImportError("This class requires RDKit to be installed.")

    smiles = Chem.MolToSmiles(mol)
    return _featurize(smiles)

  def pad_string(self, string: str) -> str:
    """Pad SMILES string to `self.pad_length`

    Parameters
    ----------
    smiles: str
      The smiles string to be padded.
    string: str
      The string to be padded.

    Returns
    -------
    str
      SMILES string space padded to self.pad_length
      String space padded to self.pad_length
    """
    return smiles.ljust(self.max_length)
    return string.ljust(self.max_length)

  def untransform(self, one_hot_vectors: np.ndarray) -> str:
    """Convert from one hot representation back to SMILES
    """Convert from one hot representation back to original string

    Parameters
    ----------
@@ -102,13 +118,13 @@ class OneHotFeaturizer(MolecularFeaturizer):
    Returns
    -------
    str
      SMILES string for an one hot encoded array.
      Original string for an one hot encoded array.
    """
    smiles = ""
    string = ""
    for one_hot in one_hot_vectors:
      try:
        idx = np.argmax(one_hot)
        smiles += self.charset[idx]
        string += self.charset[idx]
      except IndexError:
        smiles += ""
    return smiles
        string += ""
    return string
+39 −5
Original line number Diff line number Diff line
@@ -11,23 +11,51 @@ class TestOneHotFeaturizert(unittest.TestCase):
  Test OneHotFeaturizer.
  """

  def test_onehot_featurizer(self):
  def test_onehot_featurizer_arbitrary(self):
    """
    Test simple one hot encoding.
    Test simple one hot encoding for arbitrary string.
    """
    string = "abcdefghijklmnopqrstuvwxyz"
    length = len(string) + 1
    featurizer = OneHotFeaturizer()
    feature = featurizer(string) # Implicit call to _featurize()
    assert feature.shape == (1, 100, length)

    # untransform
    undo_string = featurizer.untransform(feature[0])
    assert string == undo_string

  def test_onehot_featurizer_SMILES(self):
    """
    Test simple one hot encoding for SMILES strings.
    """
    from rdkit import Chem
    length = len(ZINC_CHARSET) + 1
    smiles = 'CC(=O)Oc1ccccc1C(=O)O'
    mol = Chem.MolFromSmiles(smiles)
    featurizer = OneHotFeaturizer()
    feature = featurizer([mol])
    feature = featurizer([mol]) # Implicit call to _featurizeMol()--why []?
    assert feature.shape == (1, 100, length)

    # untranform
    undo_smiles = featurizer.untransform(feature[0])
    assert smiles == undo_smiles

  def test_onehot_featurizer_with_max_length(self):
  def test_onehot_featurizer_arbitrary_with_max_length(self):
    """
    Test one hot encoding with max_length.
    """
    string = "abcdefghijklmnopqrstuvwxyz"
    length = len(string) + 1
    featurizer = OneHotFeaturizer(max_length=120)
    feature = featurizer(string)
    assert feature.shape == (1, 120, length)

    # untranform
    undo_string = featurizer.untransform(feature[0])
    assert string == undo_string

  def test_onehot_featurizer_SMIELS_with_max_length(self):
    """
    Test one hot encoding with max_length.
    """
@@ -43,7 +71,7 @@ class TestOneHotFeaturizert(unittest.TestCase):
    undo_smiles = featurizer.untransform(feature[0])
    assert smiles == undo_smiles

  def test_correct_transformation(self):
  def test_correct_transformation_SMILES(self):
    """
    Test correct one hot encoding.
    """
@@ -62,3 +90,9 @@ class TestOneHotFeaturizert(unittest.TestCase):
    # untranform
    undo_smiles = featurizer.untransform(feature[0])
    assert smiles == undo_smiles

  def test_correct_transformation_arbitrary(self):
    """
    Test correct one hot encoding.
    """
    assert "This test case has not yet been written."