Пример #1
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)
Пример #2
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)
Пример #3
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)
Пример #4
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)
Пример #5
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)
Пример #6
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)
Пример #7
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()
Пример #8
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)
Пример #9
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)
Пример #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
Пример #11
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)
Пример #12
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)
Пример #13
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)
Пример #14
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()