Esempio n. 1
0
 def test_identifier_getters(self):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(type='NAME', value='water')
     self.assertEqual(message_helpers.get_compound_name(compound), 'water')
     self.assertIsNone(message_helpers.get_compound_smiles(compound))
     compound.identifiers.add(type='SMILES', value='O')
     self.assertEqual(message_helpers.get_compound_smiles(compound), 'O')
     self.assertEqual(message_helpers.smiles_from_compound(compound), 'O')
     compound = reaction_pb2.Compound()
     compound.identifiers.add(type='MOLBLOCK', value=_BENZENE_MOLBLOCK)
     self.assertEqual(message_helpers.get_compound_molblock(compound),
                      _BENZENE_MOLBLOCK)
     self.assertEqual(message_helpers.molblock_from_compound(compound),
                      _BENZENE_MOLBLOCK)
Esempio n. 2
0
def test_render_compound(client):
    compound = reaction_pb2.Compound()
    compound.identifiers.add(value="c1ccccc1", type="SMILES")
    response = client.post("/render/reaction",
                           data=compound.SerializeToString(),
                           follow_redirects=True)
    assert response.status_code == 200
Esempio n. 3
0
 def test_get_molfile_no_structure(self):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value='benzene', type='NAME')
     response = self.client.post('/ketcher/molfile',
                                 data=compound.SerializeToString(),
                                 follow_redirects=True)
     self.assertEqual(response.status_code, 204)
Esempio n. 4
0
def test_get_molfile_no_structure(client):
    compound = reaction_pb2.Compound()
    compound.identifiers.add(value="benzene", type="NAME")
    response = client.post("/ketcher/molfile",
                           data=compound.SerializeToString(),
                           follow_redirects=True)
    assert response.status_code == 204
Esempio n. 5
0
 def test_render_compound(self):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value='c1ccccc1', type='SMILES')
     response = self.client.post('/render/reaction',
                                 data=compound.SerializeToString(),
                                 follow_redirects=True)
     self.assertEqual(response.status_code, 200)
Esempio n. 6
0
 def test_smiles_and_name(self):
     compound = message_helpers.build_compound(smiles='c1ccccc1',
                                               name='benzene')
     expected = reaction_pb2.Compound(identifiers=[
         reaction_pb2.CompoundIdentifier(value='c1ccccc1', type='SMILES'),
         reaction_pb2.CompoundIdentifier(value='benzene', type='NAME')
     ])
     self.assertEqual(compound, expected)
Esempio n. 7
0
def get_molfile():
    """Retrieves a POSTed Compound message string and returns a MolFile."""
    compound = reaction_pb2.Compound()
    compound.ParseFromString(flask.request.get_data())
    try:
        molblock = message_helpers.molblock_from_compound(compound)
        return flask.jsonify(molblock)
    except ValueError:
        return 'no existing structural identifier', 204
Esempio n. 8
0
def render_compound():
    """Returns an HTML-tagged SVG for the given Compound."""
    compound = reaction_pb2.Compound()
    compound.ParseFromString(flask.request.get_data())
    try:
        mol = message_helpers.mol_from_compound(compound)
        return flask.jsonify(drawing.mol_to_svg(mol))
    except ValueError:
        return ''
Esempio n. 9
0
 def test_mol_from_compound(self, value, identifier_type, expected):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value=value, type=identifier_type)
     mol = message_helpers.mol_from_compound(compound)
     self.assertEqual(Chem.MolToSmiles(mol), expected)
     mol, identifier = message_helpers.mol_from_compound(
         compound, return_identifier=True)
     self.assertEqual(Chem.MolToSmiles(mol), expected)
     self.assertEqual(identifier, compound.identifiers[0])
Esempio n. 10
0
 def test_get_molfile(self):
     smiles = 'c1ccccc1'
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value=smiles, type='SMILES')
     response = self.client.post('/ketcher/molfile',
                                 data=compound.SerializeToString(),
                                 follow_redirects=True)
     self.assertEqual(response.status_code, 200)
     self.assertEqual(json.loads(response.data),
                      Chem.MolToMolBlock(Chem.MolFromSmiles(smiles)))
Esempio n. 11
0
 def test_check_compound_identifiers(self):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value='c1ccccc1', type='SMILES')
     message_helpers.check_compound_identifiers(compound)
     compound.identifiers.add(value='InChI=1S/C6H6/c1-2-4-6-5-3-1/h1-6H',
                              type='INCHI')
     message_helpers.check_compound_identifiers(compound)
     compound.identifiers.add(value='c1ccc(O)cc1', type='SMILES')
     with self.assertRaisesRegex(ValueError, 'inconsistent'):
         message_helpers.check_compound_identifiers(compound)
Esempio n. 12
0
def test_get_molfile(client):
    smiles = "c1ccccc1"
    compound = reaction_pb2.Compound()
    compound.identifiers.add(value=smiles, type="SMILES")
    response = client.post("/ketcher/molfile",
                           data=compound.SerializeToString(),
                           follow_redirects=True)
    assert response.status_code == 200
    assert json.loads(response.data) == Chem.MolToMolBlock(
        Chem.MolFromSmiles(smiles))
Esempio n. 13
0
 def test_compound_rdkit_binary(self):
     mol = Chem.MolFromSmiles('CC(=O)OC1=CC=CC=C1C(=O)O')
     message = reaction_pb2.Compound()
     identifier = message.identifiers.add()
     identifier.type = identifier.SMILES
     identifier.value = Chem.MolToSmiles(mol)
     validations.validate_message(message)  # Message is modified in place.
     self.assertEqual(
         message.identifiers[1],
         reaction_pb2.CompoundIdentifier(type='RDKIT_BINARY',
                                         bytes_value=mol.ToBinary()))
Esempio n. 14
0
 def test_compound_name_resolver(self):
     message = reaction_pb2.Compound()
     identifier = message.identifiers.add()
     identifier.type = identifier.NAME
     identifier.value = 'aspirin'
     validations.validate_message(message)  # Message is modified in place.
     self.assertEqual(
         message.identifiers[1],
         reaction_pb2.CompoundIdentifier(
             type='SMILES',
             value='CC(=O)OC1=CC=CC=C1C(=O)O',
             details='NAME resolved by PubChem'))
Esempio n. 15
0
 def test_identifier_setters(self):
     compound = reaction_pb2.Compound()
     identifier = message_helpers.set_compound_name(compound, 'water')
     self.assertEqual(
         identifier,
         reaction_pb2.CompoundIdentifier(type='NAME', value='water'))
     self.assertEqual(
         compound.identifiers[0],
         reaction_pb2.CompoundIdentifier(type='NAME', value='water'))
     message_helpers.set_compound_smiles(compound, 'O')
     self.assertEqual(
         compound.identifiers[1],
         reaction_pb2.CompoundIdentifier(type='SMILES', value='O'))
     identifier = message_helpers.set_compound_name(compound, 'ice')
     self.assertEqual(
         identifier, reaction_pb2.CompoundIdentifier(type='NAME',
                                                     value='ice'))
     self.assertEqual(
         compound.identifiers[0],
         reaction_pb2.CompoundIdentifier(type='NAME', value='ice'))
     compound = reaction_pb2.Compound()
     identifier = message_helpers.set_compound_molblock(
         compound, _BENZENE_MOLBLOCK)
     self.assertEqual(_BENZENE_MOLBLOCK, compound.identifiers[0].value)
Esempio n. 16
0
 def test_mol_from_compound_failures(self, value, identifier_type):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value=value, type=identifier_type)
     with self.assertRaisesRegex(ValueError,
                                 'invalid structural identifier'):
         message_helpers.mol_from_compound(compound)
Esempio n. 17
0
 def test_smiles_from_compound(self, value, identifier_type, expected):
     compound = reaction_pb2.Compound()
     compound.identifiers.add(value=value, type=identifier_type)
     self.assertEqual(message_helpers.smiles_from_compound(compound),
                      expected)
Esempio n. 18
0
def build_compound(smiles=None,
                   name=None,
                   amount=None,
                   role=None,
                   is_limiting=None,
                   prep=None,
                   prep_details=None,
                   vendor=None):
    """Builds a Compound message with the most common fields.

    Args:
        smiles: Text compound SMILES.
        name: Text compound name.
        amount: Text amount string, e.g. '1.25 g'.
        role: Text reaction role. Must match a value in ReactionRoleType.
        is_limiting: Boolean whether this compound is limiting for the reaction.
        prep: Text compound preparation type. Must match a value in
            PreparationType.
        prep_details: Text compound preparation details. If provided, `prep` is
            required.
        vendor: Text compound vendor/supplier.

    Returns:
        Compound message.

    Raises:
        KeyError: if `role` or `prep` does not match a supported enum value.
        TypeError: if `amount` units are not supported.
        ValueError: if `prep_details` is provided and `prep` is None.
    """
    compound = reaction_pb2.Compound()
    if smiles:
        compound.identifiers.add(value=smiles, type='SMILES')
    if name:
        compound.identifiers.add(value=name, type='NAME')
    if amount:
        resolver = units.UnitResolver()
        amount_pb = resolver.resolve(amount)
        if isinstance(amount_pb, reaction_pb2.Mass):
            compound.amount.mass.CopyFrom(amount_pb)
        elif isinstance(amount_pb, reaction_pb2.Moles):
            compound.amount.moles.CopyFrom(amount_pb)
        elif isinstance(amount_pb, reaction_pb2.Volume):
            compound.amount.volume.CopyFrom(amount_pb)
        else:
            raise TypeError(f'unsupported units for amount: {amount_pb}')
    if role:
        field = reaction_pb2.Compound.DESCRIPTOR.fields_by_name[
            'reaction_role']
        values_dict = field.enum_type.values_by_name
        try:
            compound.reaction_role = values_dict[role.upper()].number
        except KeyError as error:
            raise KeyError(
                f'{role} is not a supported type: {values_dict.keys()}'
            ) from error
    if is_limiting is not None:
        if not (is_limiting is True or is_limiting is False):
            raise TypeError(
                f'is_limiting must be a boolean value: {is_limiting}')
        compound.is_limiting = is_limiting
    if prep:
        field = reaction_pb2.CompoundPreparation.DESCRIPTOR.fields_by_name[
            'type']
        values_dict = field.enum_type.values_by_name
        try:
            compound.preparations.add().type = values_dict[prep.upper()].number
        except KeyError as error:
            raise KeyError(
                f'{prep} is not a supported type: {values_dict.keys()}'
            ) from error
        if (compound.preparations[0].type
                == reaction_pb2.CompoundPreparation.CUSTOM
                and not prep_details):
            raise ValueError(
                'prep_details must be provided when CUSTOM prep is used')
    if prep_details:
        if not prep:
            raise ValueError('prep must be provided when prep_details is used')
        compound.preparations[0].details = prep_details
    if vendor:
        compound.source.vendor = vendor
    return compound