Esempio n. 1
0
    def test_Impact_writable_parameters(self):
        """
        It checks the Impact writable representation for angles.
        """

        # Load benzene ring
        molecule = Molecule(smiles='CC=O')

        # Parameterize
        molecule.parameterize('openff_unconstrained-1.2.0.offxml',
                              charges_method='gasteiger')

        expected_parameters = list(
            [[1, 2, 3, 78.67881492645, 128.2771922378],
             [1, 2, 7, 34.202963712735, 133.1339832262],
             [2, 1, 4, 50.00415699765, 110.81136453],
             [2, 1, 5, 50.00415699765, 110.81136453],
             [2, 1, 6, 50.00415699765, 110.81136453],
             [3, 2, 7, 34.202963712735, 133.1339832262],
             [4, 1, 5, 33.78875634641, 110.2468561538],
             [4, 1, 6, 33.78875634641, 110.2468561538],
             [5, 1, 6, 33.78875634641, 110.2468561538]])

        # Check resulting parameters
        for angle in molecule.angles:
            w_angle = WritableAngle(angle)
            w_parameters = [attr[1] for attr in list(w_angle)]
            assert w_parameters in expected_parameters, \
                'Invalid writable angle parameters {}'.format(w_parameters)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
0
    def test_Impact_writable_parameters(self):
        """
        It checks the Impact writable representation for bonds.
        """

        # Load benzene ring
        molecule = Molecule(smiles='CC=O')

        # Parameterize
        molecule.parameterize('openff_unconstrained-1.2.0.offxml',
                              charges_method='gasteiger')

        expected_parameters = list([[1, 2, 332.5750972667, 1.523640340452],
                                    [1, 4, 376.8940758588, 1.094223427522],
                                    [1, 5, 376.8940758588, 1.094223427522],
                                    [1, 6, 376.8940758588, 1.094223427522],
                                    [2, 3, 608.3286693405, 1.225108345696],
                                    [2, 7, 404.20804685, 1.085503378387]])

        # Check resulting parameters
        for bond in molecule.bonds:
            w_bond = WritableBond(bond)
            w_parameters = [attr[1] for attr in list(w_bond)]
            assert w_parameters in expected_parameters, \
                'Invalid writable bond parameters {}'.format(w_parameters)
Esempio n. 5
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'
Esempio n. 6
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'
Esempio n. 7
0
    def test_OFF_parameters(self):
        """
        It checks the standard Open Force Field parameterization for
        bonds.
        """

        MAX_THRESHOLD = 1e-3

        # Load benzene ring
        molecule = Molecule(smiles='c1ccccc1')

        # Parameterize
        molecule.parameterize('openff_unconstrained-1.2.0.offxml',
                              charges_method='gasteiger')

        # Check resulting parameters
        expected_lengths = {(0, 1): 1.389761064076,
                            (0, 5): 1.389761064076,
                            (0, 6): 1.085503378387,
                            (1, 2): 1.389761064076,
                            (1, 7): 1.085503378387,
                            (2, 3): 1.389761064076,
                            (2, 8): 1.085503378387,
                            (3, 4): 1.389761064076,
                            (3, 9): 1.085503378387,
                            (4, 5): 1.389761064076,
                            (4, 10): 1.085503378387,
                            (5, 11): 1.085503378387}

        expected_ks = {(0, 1): 672.0064645264,
                       (0, 5): 672.0064645264,
                       (0, 6): 808.4160937,
                       (1, 2): 672.0064645264,
                       (1, 7): 808.4160937,
                       (2, 3): 672.0064645264,
                       (2, 8): 808.4160937,
                       (3, 4): 672.0064645264,
                       (3, 9): 808.4160937,
                       (4, 5): 672.0064645264,
                       (4, 10): 808.4160937,
                       (5, 11): 808.4160937}

        for indexes, properties in dict(molecule.parameters['Bonds']).items():
            expected_length = unit.Quantity(expected_lengths[indexes],
                                            unit.angstrom)
            expected_k = unit.Quantity(expected_ks[indexes],
                                       unit.kilocalorie
                                       / (unit.angstrom ** 2 * unit.mole))

            assert properties.length - expected_length \
                < unit.Quantity(MAX_THRESHOLD, unit.angstrom), \
                'Invalid length for bond {} {}'.format(indexes, properties)
            assert properties.k - expected_k \
                < unit.Quantity(MAX_THRESHOLD, unit.kilocalorie
                                / (unit.angstrom ** 2 * unit.mole)), \
                'Invalid k for bond {} {}'.format(indexes, properties)
Esempio n. 8
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)
Esempio n. 9
0
    def test_Impact_writable_parameters(self):
        """
        It checks the Impact writable representation for dihedrals.
        """

        # Load benzene ring
        molecule = Molecule(smiles='CC=O')

        # Parameterize
        molecule.parameterize('openff_unconstrained-1.2.0.offxml',
                              charges_method='gasteiger')

        expected_parameters = list(
            [[3, 2, 1, 4, 0.5107183999341, 1, 1],
             [3, 2, 1, 5, 0.5107183999341, 1, 1],
             [3, 2, 1, 6, 0.5107183999341, 1, 1],
             [4, 1, 2, 7, 0.1493988458474, 1, 3],
             [5, 1, 2, 7, 0.1493988458474, 1, 3],
             [6, 1, 2, 7, 0.1493988458474, 1, 3],
             [3, 2, 1, 4, -0.0275194074427, 1, 2],
             [3, 2, 1, 5, -0.0275194074427, 1, 2],
             [3, 2, 1, 6, -0.0275194074427, 1, 2],
             [3, 2, 1, 4, -0.1057540923121, -1, 3],
             [3, 2, 1, 5, -0.1057540923121, -1, 3],
             [3, 2, 1, 6, -0.1057540923121, -1, 3]])

        # Check resulting parameters
        for proper in molecule.propers:
            w_proper = WritableProper(proper)
            w_parameters = [attr[1] for attr in list(w_proper)]
            assert w_parameters in expected_parameters, \
                'Invalid writable proper parameters {}'.format(w_parameters)

        expected_parameters = list([[1, 2, 3, 7, 1.1, -1, 2]])

        # Check resulting parameters
        for improper in molecule.impropers:
            w_improper = WritableImproper(improper)
            w_parameters = [attr[1] for attr in list(w_improper)]
            assert w_parameters in expected_parameters, \
                'Invalid writable improper parameters {}'.format(w_parameters)
Esempio n. 10
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
Esempio n. 11
0
    def test_get_Schrodinger_parameters(self):
        """
        It tests the standard methods to obtain Schrodinger parameters
        from an offpele's Molecule.
        """

        # Load benzene ring
        molecule = Molecule(smiles='c1ccccc1')
        molecule.parameterize(FORCEFIELD_NAME, charges_method='gasteiger')

        with pytest.raises(ToolkitUnavailableException):
            molecule.get_OPLS_parameters()

        molecule._OPLS_parameters = METHANE_OPLS_PARAMETERS
        _ = molecule.get_OPLS_parameters()

        molecule.add_OPLS_nonbonding_params()
        molecule.add_OPLS_bonds_and_angles()
Esempio n. 12
0
    def test_excluded_dihedrals_handler(self):
        """
        It checks the exclusion of dihedrals when generating 1-4 lists
        for PELE. This process is done internally in PELE but we
        need to mark previously those dihedrals to exclude from 1-4
        lists.
        """
        molecule = Molecule()

        # Add several dummy propers
        molecule._add_proper(
            Proper(atom1_idx=0, atom2_idx=1, atom3_idx=2, atom4_idx=3,
                   periodicity=1, prefactor=1, index=0,
                   constant=unit.Quantity(1.0, unit.kilocalorie / unit.mole)))
        molecule._add_proper(
            Proper(atom1_idx=0, atom2_idx=1, atom3_idx=2, atom4_idx=3,
                   periodicity=2, prefactor=1, index=1,
                   constant=unit.Quantity(1.0, unit.kilocalorie / unit.mole)))
        molecule._add_proper(
            Proper(atom1_idx=0, atom2_idx=1, atom3_idx=5, atom4_idx=3,
                   periodicity=2, prefactor=1, index=2,
                   constant=unit.Quantity(1.0, unit.kilocalorie / unit.mole)))
        molecule._add_proper(
            Proper(atom1_idx=0, atom2_idx=1, atom3_idx=2, atom4_idx=4,
                   periodicity=1, prefactor=1, index=3,
                   constant=unit.Quantity(1.0, unit.kilocalorie / unit.mole)))
        molecule._add_proper(
            Proper(atom1_idx=0, atom2_idx=1, atom3_idx=2, atom4_idx=5,
                   periodicity=1, prefactor=1, index=4,
                   constant=unit.Quantity(1.0, unit.kilocalorie / unit.mole)))
        molecule._add_proper(
            Proper(atom1_idx=0, atom2_idx=1, atom3_idx=2, atom4_idx=6,
                   periodicity=1, prefactor=1, index=5,
                   constant=unit.Quantity(1.0, unit.kilocalorie / unit.mole)))

        # Add one bond
        molecule._add_bond(
            Bond(atom1_idx=0, atom2_idx=4,
                 spring_constant=unit.Quantity(1.0, unit.kilocalorie
                                               / (unit.angstrom ** 2
                                                  * unit.mole)),
                 eq_dist=unit.Quantity(1.0, unit.angstrom)))

        # Add one angle
        molecule._add_angle(
            Angle(atom1_idx=0, atom2_idx=1, atom3_idx=5,
                  spring_constant=unit.Quantity(1.0, unit.kilocalorie
                                                / (unit.radian ** 2
                                                   * unit.mole)),
                  eq_angle=unit.Quantity(1.0, unit.degrees)))

        molecule._handle_excluded_propers()

        # Assertions
        for proper in molecule.propers:
            if proper.index == 0:
                assert proper.exclude is False, \
                    'Proper 0 must be INCLUDED in 1-4 list'
            elif proper.index == 1:
                assert proper.exclude is False, \
                    'Proper 1 must be INCLUDED in 1-4 list'
            elif proper.index == 2:
                assert proper.exclude is True, \
                    'Proper 2 must be EXCLUDED in 1-4 list'
            elif proper.index == 3:
                assert proper.exclude is True, \
                    'Proper 3 must be EXCLUDED in 1-4 list'
            elif proper.index == 4:
                assert proper.exclude is True, \
                    'Proper 4 must be EXCLUDED in 1-4 list'
            elif proper.index == 5:
                assert proper.exclude is False, \
                    'Proper 5 must be INCLUDED in 1-4 list'
Esempio n. 13
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)
Esempio n. 14
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')
Esempio n. 15
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)
Esempio n. 16
0
    def test_assign_Schrodinger_parameters(self):
        """
        It tests the assignment of Schrodinger parameters to offpele's
        Molecule.
        """
        def check_parameters():
            """ It checks the current parameters of the molecule. """
            for atom in molecule.atoms:
                w_atom = WritableAtom(atom)
                w_parameters = [
                    w_atom.index, w_atom.parent.index, w_atom.core,
                    w_atom.OPLS_type, w_atom.PDB_name, w_atom.unknown,
                    w_atom.sigma, w_atom.epsilon, w_atom.charge,
                    w_atom.born_radius, w_atom.SASA_radius,
                    w_atom.nonpolar_gamma, w_atom.nonpolar_alpha
                ]
                assert w_parameters in expected_nonbonding, \
                    'Invalid writable nonbonding parameters {}'.format(w_parameters)

            for bond in molecule.bonds:
                w_bond = WritableBond(bond)
                w_parameters = [attr[1] for attr in list(w_bond)]
                assert w_parameters in expected_bonds, \
                    'Invalid writable bond parameters {}'.format(w_parameters)

            for angle in molecule.angles:
                w_angle = WritableAngle(angle)
                w_parameters = [attr[1] for attr in list(w_angle)]
                assert w_parameters in expected_angles, \
                    'Invalid writable angle parameters {}'.format(w_parameters)

        # Load benzene ring
        molecule = Molecule(smiles='C')
        molecule.parameterize(FORCEFIELD_NAME)

        # Load OPLS parameters
        molecule._OPLS_parameters = METHANE_OPLS_PARAMETERS

        # Check parameters
        # First check
        expected_nonbonding = [[
            1, 0, 'M', 'OFFT', '_C1_', 0, 3.3996695084235347, 0.1094, -0.1088,
            0, 1.6998347542117673, 0, 0
        ],
                               [
                                   2, 1, 'M', 'OFFT', '_H1_', 0,
                                   2.649532787749369, 0.0157, 0.0267, 0,
                                   1.3247663938746845, 0, 0
                               ],
                               [
                                   3, 1, 'M', 'OFFT', '_H2_', 0,
                                   2.649532787749369, 0.0157, 0.0267, 0,
                                   1.3247663938746845, 0, 0
                               ],
                               [
                                   4, 1, 'M', 'OFFT', '_H3_', 0,
                                   2.649532787749369, 0.0157, 0.0267, 0,
                                   1.3247663938746845, 0, 0
                               ],
                               [
                                   5, 1, 'M', 'OFFT', '_H4_', 0,
                                   2.649532787749369, 0.0157, 0.0267, 0,
                                   1.3247663938746845, 0, 0
                               ]]

        expected_bonds = [[1, 2, 376.8940758588, 1.094223427522],
                          [1, 3, 376.8940758588, 1.094223427522],
                          [1, 4, 376.8940758588, 1.094223427522],
                          [1, 5, 376.8940758588, 1.094223427522]]

        expected_angles = [[2, 1, 3, 33.78875634641, 110.2468561538],
                           [2, 1, 4, 33.78875634641, 110.2468561538],
                           [2, 1, 5, 33.78875634641, 110.2468561538],
                           [3, 1, 4, 33.78875634641, 110.2468561538],
                           [3, 1, 5, 33.78875634641, 110.2468561538],
                           [4, 1, 5, 33.78875634641, 110.2468561538]]

        check_parameters()

        # Second check
        molecule.add_OPLS_nonbonding_params()

        expected_nonbonding = [[
            1, 0, 'M', 'CT', '_C1_', 0, 3.5, 0.066, -0.1088, 1.975, 1.75,
            0.005, -0.74168571
        ],
                               [
                                   2, 1, 'M', 'HC', '_H1_', 0, 2.5, 0.03,
                                   0.0267, 1.425, 1.25, 0.00859824, 0.268726247
                               ],
                               [
                                   3, 1, 'M', 'HC', '_H2_', 0, 2.5, 0.03,
                                   0.0267, 1.425, 1.25, 0.00859824, 0.268726247
                               ],
                               [
                                   4, 1, 'M', 'HC', '_H3_', 0, 2.5, 0.03,
                                   0.0267, 1.425, 1.25, 0.00859824, 0.268726247
                               ],
                               [
                                   5, 1, 'M', 'HC', '_H4_', 0, 2.5, 0.03,
                                   0.0267, 1.425, 1.25, 0.00859824, 0.268726247
                               ]]

        check_parameters()

        # Third check
        molecule.add_OPLS_bonds_and_angles()

        expected_bonds = [[1, 2, 340.0, 1.09], [1, 3, 340.0, 1.09],
                          [1, 4, 340.0, 1.09], [1, 5, 340.0, 1.09]]

        expected_angles = [[2, 1, 3, 33.0, 107.8], [2, 1, 4, 33.0, 107.8],
                           [2, 1, 5, 33.0, 107.8], [3, 1, 4, 33.0, 107.8],
                           [3, 1, 5, 33.0, 107.8], [4, 1, 5, 33.0, 107.8]]

        check_parameters()
Esempio n. 17
0
    def test_OFF_parameters(self):
        """
        It checks the standard Open Force Field parameterization for
        angles.
        """

        MAX_THRESHOLD = 1e-3

        # Load benzene ring
        molecule = Molecule(smiles='c1ccccc1')

        # Parameterize
        molecule.parameterize('openff_unconstrained-1.2.0.offxml',
                              charges_method='gasteiger')

        # Check resulting parameters
        expected_angles = {(0, 1, 2): 128.2771922378,
                           (0, 1, 7): 133.1339832262,
                           (0, 5, 4): 128.2771922378,
                           (0, 5, 11): 133.1339832262,
                           (1, 0, 5): 128.2771922378,
                           (1, 0, 6): 133.1339832262,
                           (1, 2, 3): 128.2771922378,
                           (1, 2, 8): 133.1339832262,
                           (2, 1, 7): 133.1339832262,
                           (2, 3, 4): 128.2771922378,
                           (2, 3, 9): 133.1339832262,
                           (3, 2, 8): 133.1339832262,
                           (3, 4, 5): 128.2771922378,
                           (3, 4, 10): 133.1339832262,
                           (4, 3, 9): 133.1339832262,
                           (4, 5, 11): 133.1339832262,
                           (5, 0, 6): 133.1339832262,
                           (5, 4, 10): 133.1339832262}

        expected_ks = {(0, 1, 2): 157.3576298529,
                       (0, 1, 7): 68.40592742547,
                       (0, 5, 4): 157.3576298529,
                       (0, 5, 11): 68.40592742547,
                       (1, 0, 5): 157.3576298529,
                       (1, 0, 6): 68.40592742547,
                       (1, 2, 3): 157.3576298529,
                       (1, 2, 8): 68.40592742547,
                       (2, 1, 7): 68.40592742547,
                       (2, 3, 4): 157.3576298529,
                       (2, 3, 9): 68.40592742547,
                       (3, 2, 8): 68.40592742547,
                       (3, 4, 5): 157.3576298529,
                       (3, 4, 10): 68.40592742547,
                       (4, 3, 9): 68.40592742547,
                       (4, 5, 11): 68.40592742547,
                       (5, 0, 6): 68.40592742547,
                       (5, 4, 10): 68.40592742547}

        for indexes, properties in dict(molecule.parameters['Angles']).items():
            expected_angle = unit.Quantity(expected_angles[indexes],
                                           unit.degree)
            expected_k = unit.Quantity(expected_ks[indexes],
                                       unit.kilocalorie
                                       / (unit.radian ** 2 * unit.mole))

            assert properties.angle - expected_angle \
                < unit.Quantity(MAX_THRESHOLD, unit.degree), \
                'Invalid length for angle {} {}'.format(indexes, properties)
            assert properties.k - expected_k \
                < unit.Quantity(MAX_THRESHOLD, unit.kilocalorie
                                / (unit.radian ** 2 * unit.mole)), \
                'Invalid k for angle {} {}'.format(indexes, properties)
Esempio n. 18
0
    def test_OFF_parameters(self):
        """
        It checks the standard Open Force Field parameterization for
        dihedrals.
        """

        MAX_THRESHOLD = 1e-3

        # Load molecule
        molecule = Molecule(smiles='C=CC(=O)O')

        # Parameterize
        molecule.parameterize('openff_unconstrained-1.2.0.offxml',
                              charges_method='gasteiger')

        # Check resulting parameters for proper torsions
        expected_ks = {(0, 1, 2, 3): [0.603518062312, 0.5248455212365],
                       (0, 1, 2, 4): [0.9350453896311],
                       (1, 2, 4, 8): [2.529110648699],
                       (2, 1, 0, 5): [5.376019778605],
                       (2, 1, 0, 6): [5.376019778605],
                       (3, 2, 1, 7): [0.9350453896311],
                       (3, 2, 4, 8): [2.237928151469, 1.23728649144],
                       (4, 2, 1, 7): [0.9350453896311],
                       (5, 0, 1, 7): [5.376019778605],
                       (6, 0, 1, 7): [5.376019778605]}

        expected_phases = {(0, 1, 2, 3): [180.0, 0.0],
                           (0, 1, 2, 4): [180.0],
                           (1, 2, 4, 8): [180.0],
                           (2, 1, 0, 5): [180.0],
                           (2, 1, 0, 6): [180.0],
                           (3, 2, 1, 7): [180.0],
                           (3, 2, 4, 8): [180.0, 0.0],
                           (4, 2, 1, 7): [180.0],
                           (5, 0, 1, 7): [180.0],
                           (6, 0, 1, 7): [180.0]}

        expected_periodicities = {(0, 1, 2, 3): [2, 3],
                                  (0, 1, 2, 4): [2],
                                  (1, 2, 4, 8): [2],
                                  (2, 1, 0, 5): [2],
                                  (2, 1, 0, 6): [2],
                                  (3, 2, 1, 7): [2],
                                  (3, 2, 4, 8): [2, 1],
                                  (4, 2, 1, 7): [2],
                                  (5, 0, 1, 7): [2],
                                  (6, 0, 1, 7): [2]}

        expected_idivfs = {(0, 1, 2, 3): [1.0, 1.0],
                           (0, 1, 2, 4): [1.0],
                           (1, 2, 4, 8): [1.0],
                           (2, 1, 0, 5): [1.0],
                           (2, 1, 0, 6): [1.0],
                           (3, 2, 1, 7): [1.0],
                           (3, 2, 4, 8): [1.0, 1.0],
                           (4, 2, 1, 7): [1.0],
                           (5, 0, 1, 7): [1.0],
                           (6, 0, 1, 7): [1.0]}

        for indexes, properties in dict(
                molecule.parameters['ProperTorsions']).items():
            for i, (k, phase, periodicity, idivf) in enumerate(
                    zip(properties.k, properties.phase,
                        properties.periodicity, properties.idivf)):
                expected_k = unit.Quantity(expected_ks[indexes][i],
                                           unit.kilocalorie / unit.mole)
                expected_phase = unit.Quantity(expected_phases[indexes][i],
                                               unit.degree)
                expected_periodicity = expected_periodicities[indexes][i]
                expected_idivf = expected_idivfs[indexes][i]

                assert k - expected_k < \
                    unit.Quantity(MAX_THRESHOLD,
                                  unit.kilocalorie / unit.mole), \
                    'Invalid k for proper torsion ' \
                    + '{} {}'.format(indexes, properties)

                assert phase - expected_phase < \
                    unit.Quantity(MAX_THRESHOLD, unit.degree), \
                    'Invalid phase for proper torsion ' \
                    + '{} {}'.format(indexes, properties)

                assert periodicity - expected_periodicity < MAX_THRESHOLD, \
                    'Invalid periodicity for proper torsion ' \
                    + '{} {}'.format(indexes, properties)

                assert idivf - expected_idivf < MAX_THRESHOLD, \
                    'Invalid idivf for proper torsion ' \
                    + '{} {}'.format(indexes, properties)

        # Check resulting parameters for improper torsions
        expected_ks = {(0, 1, 2, 7): [1.1],
                       (1, 0, 5, 6): [1.1],
                       (1, 2, 3, 4): [10.5]}

        expected_phases = {(0, 1, 2, 7): [180.0],
                           (1, 0, 5, 6): [180.0],
                           (1, 2, 3, 4): [180.0]}

        expected_periodicities = {(0, 1, 2, 7): [2],
                                  (1, 0, 5, 6): [2],
                                  (1, 2, 3, 4): [2]}

        for indexes, properties in dict(
                molecule.parameters['ImproperTorsions']).items():
            for i, (k, phase, periodicity) in enumerate(
                    zip(properties.k, properties.phase,
                        properties.periodicity)):
                expected_k = unit.Quantity(expected_ks[indexes][i],
                                           unit.kilocalorie / unit.mole)
                expected_phase = unit.Quantity(expected_phases[indexes][i],
                                               unit.degree)
                expected_periodicity = expected_periodicities[indexes][i]

                assert k - expected_k < \
                    unit.Quantity(MAX_THRESHOLD,
                                  unit.kilocalorie / unit.mole), \
                    'Invalid k for improper torsion ' \
                    + '{} {}'.format(indexes, properties)

                assert phase - expected_phase < \
                    unit.Quantity(MAX_THRESHOLD, unit.degree), \
                    'Invalid phase for improper torsion ' \
                    + '{} {}'.format(indexes, properties)

                assert periodicity - expected_periodicity < MAX_THRESHOLD, \
                    'Invalid periodicity for improper torsion ' \
                    + '{} {}'.format(indexes, properties)

            assert properties.idivf is None, \
                'Invalid idivf for improper torsion ' \
                + '{} {}'.format(indexes, properties)
Esempio n. 19
0
    def test_default_output_paths(self):
        """
        It checks the default output paths that are used for each parameter
        file from offpele.
        """

        def from_PosixPath_to_string(paths):
            """
            Convert PosixPaths to strings
            """
            return map(str, paths)

        molecule = Molecule(smiles='c1ccccc1', name='benzene', tag='BNZ')

        rotlib_path, impact_path, solvent_path = \
            handle_output_paths(molecule, '', False)

        # Convert PosixPaths to strings
        rotlib_path, impact_path, solvent_path = map(
            str, [rotlib_path, impact_path, solvent_path])

        assert rotlib_path == 'BNZ.rot.assign', 'Unexpected default ' \
            + 'rotamer library path'
        assert impact_path == 'bnzz', 'Unexpected default Impact ' \
            + 'template path'
        assert solvent_path == 'ligandParams.txt', 'Unexpected default ' \
            + 'solvent parameters path'

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                # To avoid the complain about unexistent folder
                os.mkdir('output')
                rotlib_path, impact_path, solvent_path = \
                    handle_output_paths(molecule, 'output', False)

        # Convert PosixPaths to strings
        rotlib_path, impact_path, solvent_path = map(
            str, [rotlib_path, impact_path, solvent_path])

        assert rotlib_path == 'output/BNZ.rot.assign', 'Unexpected default ' \
            + 'rotamer library path'
        assert impact_path == 'output/bnzz', 'Unexpected default Impact ' \
            + 'template path'
        assert solvent_path == 'output/ligandParams.txt', 'Unexpected ' \
            + 'default solvent parameters path'

        rotlib_path, impact_path, solvent_path = \
            handle_output_paths(molecule, '', True)

        # Convert PosixPaths to strings
        rotlib_path, impact_path, solvent_path = map(
            str, [rotlib_path, impact_path, solvent_path])

        assert rotlib_path == 'DataLocal/LigandRotamerLibs/' \
            + 'BNZ.rot.assign', 'Unexpected default rotamer library path'
        assert impact_path == 'DataLocal/Templates/OFF/Parsley/' \
            + 'HeteroAtoms/bnzz', 'Unexpected default Impact template'
        assert solvent_path == 'DataLocal/OBC/ligandParams.txt', \
            'Unexpected default solvent parameters path'

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                # To avoid the complain about unexistent folder
                os.mkdir('output')
                rotlib_path, impact_path, solvent_path = \
                    handle_output_paths(molecule, 'output', True)

        # Convert PosixPaths to strings
        rotlib_path, impact_path, solvent_path = map(
            str, [rotlib_path, impact_path, solvent_path])

        assert rotlib_path == 'output/DataLocal/LigandRotamerLibs/' \
            + 'BNZ.rot.assign', 'Unexpected default rotamer library path'
        assert impact_path == 'output/DataLocal/Templates/OFF/Parsley/' \
            + 'HeteroAtoms/bnzz', 'Unexpected default Impact template path'
        assert solvent_path == 'output/DataLocal/OBC/ligandParams.txt', \
            'Unexpected default solvent parameters path'
Esempio n. 20
0
def run_offpele(pdb_file,
                forcefield=DEFAULT_OFF_FORCEFIELD,
                resolution=DEFAULT_RESOLUTION,
                charges_method=DEFAULT_CHARGES_METHOD,
                use_OPLS_nb_params=False,
                use_OPLS_bonds_and_angles=False,
                exclude_terminal_rotamers=True,
                output=None,
                with_solvent=False,
                as_datalocal=False):
    """
    It runs offpele.

    Parameters
    ----------
    pdb_file : str
        The path to the pdb_file to parameterize with offpele
    forcefield : str
        The name of an OpenForceField's forcefield
    resolution : float
        The resolution in degrees for the rotamer library. Default is 30
    charges_method : str
        The name of the method to use to compute partial charges. Default
        is 'am1bcc'
    use_OPLS_nb_params : bool
        Whether to use Open Force Field or OPLS to obtain the
        nonbonding parameters. Please, note that this option is only
        available if a valid Schrodinger installation is found in the
        current machine. Default is False
    use_OPLS_bonds_and_angles : bool
        Whether to use OPLS to obtain the bond and angle parameters
        or not. Please, note that this option is only
        available if a valid Schrodinger installation is found in the
        current machine. Default is False
    exclude_terminal_rotamers : bool
        Whether to exclude terminal rotamers or not
    output : str
        Path where output files will be saved
    with_solvent : bool
        Whether to generate and save the solvent parameters for the input
        molecule or not
    as_datalocal : bool
        Whether to save output files following PELE's DataLocal hierarchy or
        not
    """
    print('-' * 60)
    print('Open Force Field parameterizer for PELE', offpele.__version__)
    print('-' * 60)
    print(' - General:')
    print('   - Input PDB:', pdb_file)
    print('   - Output path:', output)
    print('   - Write solvent parameters:', with_solvent)
    print('   - DataLocal-like output:', as_datalocal)
    print(' - Parameterization:')
    print('   - Force field:', forcefield)
    print('   - Charges method:', charges_method)
    print('   - Use OPLS nonbonding parameters:', use_OPLS_nb_params)
    print('   - Use OPLS bonds and angles:', use_OPLS_bonds_and_angles)
    print(' - Rotamer library:')
    print('   - Resolution:', resolution)
    print('   - Exclude terminal rotamers:', exclude_terminal_rotamers)
    print('-' * 60)

    # Supress OpenForceField toolkit warnings
    import logging
    logging.getLogger().setLevel(logging.ERROR)

    from offpele.topology import Molecule
    from offpele.template import Impact
    from offpele.solvent import OBC2

    if not output:
        output = os.getcwd()

    molecule = Molecule(pdb_file,
                        rotamer_resolution=resolution,
                        exclude_terminal_rotamers=exclude_terminal_rotamers)

    rotlib_out, impact_out, solvent_out = handle_output_paths(
        molecule, output, as_datalocal)

    rotamer_library = offpele.topology.RotamerLibrary(molecule)
    rotamer_library.to_file(rotlib_out)

    molecule.parameterize(forcefield,
                          charges_method=charges_method,
                          use_OPLS_nonbonding_params=use_OPLS_nb_params,
                          use_OPLS_bonds_and_angles=use_OPLS_bonds_and_angles)
    impact = Impact(molecule)
    impact.write(impact_out)

    if with_solvent:
        solvent = OBC2(molecule)
        solvent.to_json_file(solvent_out)

    print(' - All files were generated successfully')
    print('-' * 60)
Esempio n. 21
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"