示例#1
0
    def test_molecule_tag_assignment(self):
        """
        It tests the molecule tag assignment.
        """
        # Look for UNK tag when dummy Molecule is loaded
        molecule = Molecule()
        assert molecule.tag == 'UNK', 'Unexpected atom tag'

        # Look for the PDB residue name as a tag when a Molecule is loaded
        # from a PDB file
        ligand_path = get_data_file_path('ligands/BNZ.pdb')
        molecule = Molecule(ligand_path)
        assert molecule.tag == 'BNZ', 'Unexpected atom tag'

        # Look for BEN tag when a Molecule is loaded from a PDB file with
        # a custom name
        ligand_path = get_data_file_path('ligands/BNZ.pdb')
        molecule = Molecule(ligand_path, tag='BEN')
        assert molecule.tag == 'BEN', 'Unexpected atom tag'

        # Look for UNK tag when a Molecule is loaded from a SMILES tag
        molecule = Molecule(smiles='c1ccccc1')
        assert molecule.tag == 'UNK', 'Unexpected atom tag'

        # Look for BNZ tag when a Molecule is loaded from a SMILES tag with
        # a custom tag
        molecule = Molecule(smiles='c1ccccc1', tag='BNZ')
        assert molecule.tag == 'BNZ', 'Unexpected atom tag'
示例#2
0
    def test_molecule_name_assignment(self):
        """
        It tests the molecule name assignment.
        """
        # Look for an empty name when dummy Molecule is loaded
        molecule = Molecule()
        assert molecule.name == '', 'Unexpected atom name'

        # Look for the PDB name when a Molecule is loaded from a PDB file
        ligand_path = get_data_file_path('ligands/BNZ.pdb')
        molecule = Molecule(ligand_path)
        assert molecule.name == 'BNZ', 'Unexpected atom name'

        # Look for benzene name when a Molecule is loaded from a PDB file
        # with a custom name
        ligand_path = get_data_file_path('ligands/BNZ.pdb')
        molecule = Molecule(ligand_path, name='benzene')
        assert molecule.name == 'benzene', 'Unexpected atom name'

        # Look for the SMILES name when a Molecule is loaded from a SMILES tag
        molecule = Molecule(smiles='c1ccccc1')
        assert molecule.name == 'c1ccccc1', 'Unexpected atom name'

        # Look for benzene name when a Molecule is loaded from a SMILES tag
        # with a custom name
        molecule = Molecule(smiles='c1ccccc1', name='benzene')
        assert molecule.name == 'benzene', 'Unexpected atom name'
示例#3
0
    def test_bad_init_parameterization(self):
        """
        It checks that a call to the parameterize function with a Molecule
        unsuccessfully initialized raises an Exception.
        """
        FORCEFIELD_NAME = 'openff_unconstrained-1.1.1.offxml'
        LIGAND_PATH = SET_OF_LIGAND_PATHS[0]
        ligand_path = get_data_file_path(LIGAND_PATH)

        molecule = Molecule()
        with pytest.raises(Exception):
            molecule.parameterize(FORCEFIELD_NAME)

        rdkit_toolkit = RDKitToolkitWrapper()
        molecule._rdkit_molecule = rdkit_toolkit.from_pdb(ligand_path)
        molecule._off_molecule = None

        with pytest.raises(Exception):
            molecule.parameterize(FORCEFIELD_NAME)

        openforcefield_toolkit = OpenForceFieldToolkitWrapper()
        molecule._off_molecule = openforcefield_toolkit.from_rdkit(molecule)
        molecule._rdkit_molecule = None

        with pytest.raises(Exception):
            molecule.parameterize(FORCEFIELD_NAME)
示例#4
0
class OBC1(_SolventWrapper):
    """
    Implementation of the OBC1 solvent.
    """

    _ff_file = get_data_file_path('forcefields/GBSA_OBC1-1.0.offxml')
    _name = 'OBC1'

    def __init__(self, molecule):
        """
        Initializes an OBC1 object.

        Parameters
        ----------
        molecule : An offpele.topology.Molecule
            A Molecule object to be written as an Impact file
        """
        # Not implemented in PELE
        import warnings
        warnings.formatwarning = warning_on_one_line
        warnings.warn("OBC1 is not implemented in PELE", Warning)

        super().__init__(molecule)

    def _initialize_from_molecule(self):
        """
        Initializes the OBC1 solvent using an offpele's Molecule.
        """
        super()._initialize_from_molecule()
示例#5
0
    def test_OPLS_method(self):
        """It tests the OPLS method"""

        ligand_path = get_data_file_path(self.LIGAND_PATH)
        molecule = Molecule(ligand_path)

        # To avoid the use of Schrodinger Toolkit
        charges = [-0.22, 0.7, -0.12, -0.8, -0.8, -0.12, -0.12, -0.12,
                   -0.12, -0.12, -0.115, -0.115, -0.12, -0.12, -0.12,
                   -0.12, -0.12, -0.12, -0.12, -0.18, 0.06, 0.06, 0.06,
                   0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06,
                   0.06, 0.06, 0.115, 0.115, 0.06, 0.06, 0.06, 0.06, 0.06,
                   0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06, 0.06,
                   0.06, 0.06, 0.06]

        molecule._OPLS_parameters = SchrodingerToolkitWrapper.OPLSParameters(
            {'charges': [unit.Quantity(charge, unit.elementary_charge)
                         for charge in charges]})

        molecule.parameterize(FORCEFIELD_NAME, charges_method='OPLS')

        assert len(molecule.off_molecule.partial_charges) == len(charges), \
            'Size of Molecule\'s partial charges is expected to match ' \
            + 'with size of reference charges list'

        for charge, expected_charge in zip(
                molecule.off_molecule.partial_charges, charges):
            assert charge == unit.Quantity(expected_charge,
                                           unit.elementary_charge), \
                'Unexpected charge {}'.format(charge)
示例#6
0
    def test_gasteiger_method(self):
        """It tests the gasteiger method"""

        ligand_path = get_data_file_path(self.LIGAND_PATH)
        molecule = Molecule(ligand_path)
        molecule.parameterize(FORCEFIELD_NAME, charges_method='gasteiger')
        check_CHO_charges_in_molecule(molecule)
示例#7
0
    def test_offpele_default_call(self):
        LIGAND_PATH = 'ligands/BNZ.pdb'
        ligand_path = get_data_file_path(LIGAND_PATH)

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                run_offpele(ligand_path, output=tmpdir)
示例#8
0
    def _add_solvent_parameters(self, OPLS_params):
        """
        It add the solvent parameters to the OPLS parameters collection.

        Parameters
        ----------
        OPLS_params : an OPLSParameters object
            The set of lists of parameters grouped by parameter type.
            Thus, the dictionary has the following keys: atom_names,
            atom_types, charges, sigmas, and epsilons. The following
            solvent parameters will be added to the collection: SGB_radii,
            vdW_radii, gammas, alphas
        """
        solvent_data = dict()
        parameters_path = get_data_file_path('parameters/f14_sgbnp.param')

        with open(parameters_path) as f:
            for line in f:
                if line.startswith('#'):
                    continue

                fields = line.split()
                assert len(fields) > 7, 'Unexpected line with less than ' \
                    '8 fields at {}'.format(line)

                atom_type = fields[1]

                solvent_data[atom_type] = {
                    'SGB_radii': unit.Quantity(float(fields[4]),
                                               unit.angstrom),
                    'vdW_radii': unit.Quantity(float(fields[5]),
                                               unit.angstrom),
                    'gammas': float(fields[6]),
                    'alphas': float(fields[7])
                }

        parameters_to_add = defaultdict(list)
        tried = list()

        for atom_type in OPLS_params['atom_types']:
            parameters_found = False
            while (not parameters_found):
                if atom_type in solvent_data:
                    for label, value in solvent_data[atom_type].items():
                        parameters_to_add[label].append(value)
                    parameters_found = True

                else:
                    new_atom_type = self._find_similar_atom_types(
                        atom_type, tried)
                    if new_atom_type is None:
                        atom_type = 'DF'  # Set it to default
                    else:
                        tried.append(new_atom_type)
                        atom_type = new_atom_type

        for label, params in parameters_to_add.items():
            OPLS_params.add_parameters(label, params)
示例#9
0
    def test_offpele_default_call(self):
        """
        It checks the default call of offpele's main function.
        """
        LIGAND_PATH = 'ligands/BNZ.pdb'
        ligand_path = get_data_file_path(LIGAND_PATH)

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                run_offpele(ligand_path, output=tmpdir)
示例#10
0
    def test_PDB_residue_name(self):
        """
        It tests the PDB residue name and checks for consistency with
        Molecule tag.
        """
        def check_residue_name(name):
            """Check if residue names are valid in the output PDB file"""
            with open('molecule.pdb') as f:
                for line in f:
                    if line.startswith('HETATM'):
                        assert line[17:20] == name, 'Unexpected residue name'

        ligand_path = get_data_file_path('ligands/BNZ.pdb')

        # Checking tag assignation from PDB
        molecule = Molecule(ligand_path)
        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                assert molecule.tag == 'BNZ', 'Unexpected molecule tag'
                molecule.to_pdb_file('molecule.pdb')
                check_residue_name('BNZ')

        # Checking set_tag() function
        molecule = Molecule(ligand_path)
        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                molecule.set_tag('TAG')
                assert molecule.tag == 'TAG', 'Unexpected molecule tag'
                molecule.to_pdb_file('molecule.pdb')
                check_residue_name('TAG')

        # Checking default tag assignment from SMILES
        molecule = Molecule(smiles='c1ccccc1')
        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                assert molecule.tag == 'UNK', 'Unexpected molecule tag'
                molecule.to_pdb_file('molecule.pdb')
                check_residue_name('UNK')

        # Checking custom tag assignment from SMILES
        molecule = Molecule(smiles='c1ccccc1', tag='BEN')
        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                assert molecule.tag == 'BEN', 'Unexpected molecule tag'
                molecule.to_pdb_file('molecule.pdb')
                check_residue_name('BEN')

        # Checking second custom tag assignment from SMILES
        molecule = Molecule(smiles='c1ccccc1')
        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                molecule.set_tag('BNZ')
                assert molecule.tag == 'BNZ', 'Unexpected molecule tag'
                molecule.to_pdb_file('molecule.pdb')
                check_residue_name('BNZ')
示例#11
0
    def test_good_init_parameterization(self):
        """
        It checks that a call to the parameterize function with a Molecule
        successfully initialized does not raise any Exception.
        """
        FORCEFIELD_NAME = 'openff_unconstrained-1.1.1.offxml'
        LIGAND_PATH = SET_OF_LIGAND_PATHS[0]
        ligand_path = get_data_file_path(LIGAND_PATH)

        molecule = Molecule(ligand_path)
        molecule.parameterize(FORCEFIELD_NAME)
示例#12
0
    def test_offpele_custom_call(self):
        LIGAND_PATH = 'ligands/BNZ.pdb'
        ligand_path = get_data_file_path(LIGAND_PATH)

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                run_offpele(ligand_path,
                            forcefield=FORCEFIELD_NAME,
                            resolution=10,
                            charges_method='gasteiger',
                            output=tmpdir,
                            with_solvent=True,
                            as_datalocal=True)
示例#13
0
    def _find_similar_atom_types(self, atom_type, tried):
        """
        It tries to find a similar atom type, skipping the ones that have
        already been tried. It uses the definitions from the
        similarity.param file.

        Parameters
        ----------
        atom_type : str
            The atom type from which similar atom types will be searched
        tried : list[str]
            The list of atom types that have already been tried and
            will be skipped

        Returns
        -------
        new_atom_type : str
            The most similar atom type that has been found, if any.
            Otherwise, it returns None
        """

        new_atom_type = None
        best_similarity = 0
        similarity_path = get_data_file_path('parameters/similarity.param')

        with open(similarity_path) as f:
            for line in f:
                fields = line.split()
                assert len(fields) > 2, 'Unexpected number of fields at ' \
                    + 'line {}'.format(line)

                atom_type1, atom_type2, similarity = fields[0:3]
                if (atom_type == atom_type1
                        and float(similarity) > best_similarity
                        and atom_type2 not in tried):
                    best_similarity = float(similarity)
                    new_atom_type = atom_type2
                elif (atom_type == atom_type2
                      and float(similarity) > best_similarity
                      and atom_type1 not in tried):
                    best_similarity = float(similarity)
                    new_atom_type = atom_type1

        return new_atom_type
示例#14
0
    def test_OFF_to_PELE_conversion(self):
        """
        It checks the difference between dihedral equations from PELE and
        Open Force Field. Their values should match throughout all the domain.
        """

        MAX_THRESHOLD = 1e-10

        for ligand_path in SET_OF_LIGAND_PATHS:
            ligand_path = get_data_file_path(ligand_path)
            molecule = Molecule(ligand_path)
            molecule.parameterize(FORCEFIELD_NAME, charges_method='gasteiger')

            x = unit.Quantity(np.arange(0, np.pi, 0.1), unit=unit.radians)

            for PELE_proper, OFF_proper in zip(molecule.propers,
                                               molecule._OFF_propers):
                PELE_y = apply_PELE_dihedral_equation(PELE_proper, x)
                OFF_y = apply_OFF_dihedral_equation(OFF_proper, x)

                y_diff = PELE_y - OFF_y

                assert np.linalg.norm(y_diff) < MAX_THRESHOLD
示例#15
0
class OBC2(_SolventWrapper):
    """
    Implementation of the OBC2 solvent.
    """

    _ff_file = get_data_file_path('forcefields/GBSA_OBC2-1.0.offxml')
    _name = 'OBC2'

    def __init__(self, molecule):
        """
        Initializes an OBC2 object.

        Parameters
        ----------
        molecule : An offpele.topology.Molecule
            A Molecule object to be written as an Impact file

        Examples
        --------

        Generate the solvent parameters of a molecule

        >>> from offpele.topology import Molecule
        >>> from offpele.solvent import OBC2

        >>> molecule = Molecule('molecule.pdb')
        >>> solvent = OBC2(molecule)
        >>> solvent.to_json_file('molecule_solv.json')

        """
        super().__init__(molecule)

    def _initialize_from_molecule(self):
        """
        Initializes the OBC2 solvent using an offpele's Molecule.
        """
        super()._initialize_from_molecule()
示例#16
0
    def test_terminal_rotamer_filtering(self):
        """
        It tests the rotamer library builder when the terminal rotatable bonds
        are ignored.
        """
        LIGAND_PATH = 'ligands/OLC.pdb'

        ligand_path = get_data_file_path(LIGAND_PATH)
        molecule = Molecule(ligand_path, exclude_terminal_rotamers=True)

        rotamers_per_branch = molecule.rotamers

        assert len(rotamers_per_branch) == 2, "Found an invalid number " + \
            "of branches: {}".format(len(rotamers_per_branch))

        atom_list_1 = list()
        atom_list_2 = list()
        rotamers = rotamers_per_branch[0]
        for rotamer in rotamers:
            atom_list_1.append(set([rotamer.index1, rotamer.index2]))

        rotamers = rotamers_per_branch[1]
        for rotamer in rotamers:
            atom_list_2.append(set([rotamer.index1, rotamer.index2]))

        EXPECTED_INDICES_1 = [
            set([9, 10]),
            set([8, 9]),
            set([7, 8]),
            set([6, 7]),
            set([5, 6]),
            set([2, 5]),
            set([0, 2]),
            set([0, 1])
        ]

        EXPECTED_INDICES_2 = [
            set([12, 11]),
            set([12, 13]),
            set([13, 14]),
            set([14, 15]),
            set([15, 16]),
            set([16, 17]),
            set([17, 18])
        ]

        where_1 = list()
        for atom_pair in atom_list_1:
            if atom_pair in EXPECTED_INDICES_1:
                where_1.append(1)
            elif atom_pair in EXPECTED_INDICES_2:
                where_1.append(2)
            else:
                where_1.append(0)

        where_2 = list()
        for atom_pair in atom_list_2:
            if atom_pair in EXPECTED_INDICES_1:
                where_2.append(1)
            elif atom_pair in EXPECTED_INDICES_2:
                where_2.append(2)
            else:
                where_2.append(0)

        assert (all(i == 1 for i in where_1)
                and all(i == 2 for i in where_2)) or \
            (all(i == 2 for i in where_1)
             and all(i == 1 for i in where_2)), "Invalid rotamer library " + \
            "{}, {}".format(where_1, where_2)

        assert (all(i == 1 for i in where_1)
                and all(i == 2 for i in where_2)
                and len(where_1) == len(EXPECTED_INDICES_1)
                and len(where_2) == len(EXPECTED_INDICES_2)) or \
               (all(i == 2 for i in where_1)
                and all(i == 1 for i in where_2)
                and len(where_1) == len(EXPECTED_INDICES_2)
                and len(where_2) == len(EXPECTED_INDICES_1)), "Unexpected " + \
            "number of rotamers"
示例#17
0
    def test_PDB_connectivity_template(self):
        """
        It tests the initialization of an offpele's Molecule representation
        from a PDB file without connectivity and a connectivity template.
        """
        # Initialize an empty Molecule object
        molecule = Molecule()
        assert molecule.connectivity_template is None, \
            'Unexpected connectivity template'

        # Initialize a Molecule from a PDB without connectivity and
        # without a connectivity template
        ligand_path = get_data_file_path(
            'ligands/BNZ_without_connectivity.pdb')
        molecule = Molecule(ligand_path)

        expected_bond_ids = [(1, 0, False), (2, 1, False), (3, 2, False),
                             (4, 3, False), (5, 4, False), (5, 0, False),
                             (6, 0, False), (7, 1, False), (8, 2, False),
                             (9, 3, False), (10, 4, False), (11, 5, False)]

        for bond in molecule.rdkit_molecule.GetBonds():
            bond_id = (bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(),
                       bond.GetIsAromatic())
            assert bond_id in expected_bond_ids, 'Unexpected bond id ' \
                + '{}'.format(bond_id)

        # Initialize a Molecule from a PDB without connectivity but with
        # a connectivity template
        template_path = get_data_file_path('ligands/BNZ.pdb')
        template = Molecule(template_path)
        ligand_path = get_data_file_path(
            'ligands/BNZ_without_connectivity.pdb')
        molecule = Molecule(ligand_path,
                            connectivity_template=template.rdkit_molecule)

        expected_bond_ids = [(1, 0, True), (2, 1, True), (3, 2, True),
                             (4, 3, True), (5, 4, True), (5, 0, True),
                             (6, 0, False), (7, 1, False), (8, 2, False),
                             (9, 3, False), (10, 4, False), (11, 5, False)]

        for bond in molecule.rdkit_molecule.GetBonds():
            bond_id = (bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(),
                       bond.GetIsAromatic())
            assert bond_id in expected_bond_ids, 'Unexpected bond id ' \
                + '{}'.format(bond_id)

        # Initialize a Molecule from a PDB with connectivity and with
        # a connectivity template
        template_path = get_data_file_path('ligands/BNZ.pdb')
        template = Molecule(template_path)
        ligand_path = get_data_file_path('ligands/BNZ.pdb')
        molecule = Molecule(ligand_path,
                            connectivity_template=template.rdkit_molecule)

        expected_bond_ids = [(0, 1, True), (1, 2, True), (2, 3, True),
                             (3, 4, True), (4, 5, True), (0, 5, True),
                             (0, 6, False), (1, 7, False), (2, 8, False),
                             (3, 9, False), (4, 10, False), (5, 11, False)]

        for bond in molecule.rdkit_molecule.GetBonds():
            bond_id = (bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(),
                       bond.GetIsAromatic())
            assert bond_id in expected_bond_ids, 'Unexpected bond id ' \
                + '{}'.format(bond_id)