Example #1
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')
Example #2
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)
Example #3
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)
Example #4
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)
Example #5
0
    def get_OPLS_parameters(self, molecule):
        """
        It calls Schrodinger's ffld_server to parameterize a molecule
        with OPLS.

        .. todo ::

           * Review PlopRotTemp's atom type fixes. Should we apply them here?

        Parameters
        ----------
        molecule : an offpele.topology.Molecule
            The offpele's Molecule object

        Returns
        -------
        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, epsilons, SGB_radii, vdW_radii,
            gammas, and alphas
        """

        ffld_server_exec = self.path_to_ffld_server()

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):

                self._rdkit_toolkit_wrapper.to_pdb_file(
                    molecule, tmpdir + '/molecule.pdb')

                subprocess.check_output([
                    ffld_server_exec, "-ipdb", "molecule.pdb", "-version",
                    "14", "-print_parameters", "-out_file", "parameters.txt"
                ])

                OPLS_params = self._parse_parameters('parameters.txt')

        self._add_solvent_parameters(OPLS_params)

        return OPLS_params
Example #6
0
    def compute_partial_charges(self, molecule, method='am1bcc'):
        """
        It computes the partial charges using antechamber.

        Parameters
        ----------
        molecule : an offpele.topology.Molecule
            The offpele's Molecule object
        method : str
            The name of the method to use. One of ['gasteiger', 'am1bcc'].
            If None, 'am1bcc' will be used

        Returns
        -------
        charges : simtk.unit.Quantity
            The array of partial charges

        Raises
        ------
        ChargeMethodUnavailableError if the requested charge method can not
            be handled by this toolkit
        ChargeCalculationError if the charge method is supported by this
            toolkit, but fails
        """

        SUPPORTED_CHARGE_METHODS = {
            'am1bcc': {
                'antechamber_keyword': 'bcc'
            },
            'gasteiger': {
                'antechamber_keyword': 'gas'
            }
        }

        if method not in SUPPORTED_CHARGE_METHODS:
            raise ChargeMethodUnavailableError(
                'partial_charge_method ' +
                '{} is not available from '.format(method) +
                'AmberToolsToolkitWrapper. Available charge methods are ' +
                list(SUPPORTED_CHARGE_METHODS.keys()))

        off_molecule = molecule.off_molecule

        with tempfile.TemporaryDirectory() as tmpdir:
            with temporary_cd(tmpdir):
                net_charge = off_molecule.total_charge / \
                    unit.elementary_charge

                self._rdkit_toolkit_wrapper.to_sdf_file(
                    molecule, tmpdir + '/molecule.sdf')

                subprocess.check_output([
                    "antechamber", "-i", "molecule.sdf", "-fi", "sdf", "-o",
                    "charged.ac", "-fo", "ac", "-pf", "yes", "-dr", "n", "-c",
                    SUPPORTED_CHARGE_METHODS[method]['antechamber_keyword'],
                    "-nc",
                    str(net_charge)
                ])
                # Write out just charges
                subprocess.check_output([
                    "antechamber", "-dr", "n", "-i", "charged.ac", "-fi", "ac",
                    "-o", "charged2.ac", "-fo", "ac", "-c", "wc", "-cf",
                    "charges.txt", "-pf", "yes"
                ])

                if not os.path.exists('charges.txt'):
                    # TODO: copy files into local directory to aid debugging?
                    raise ChargeCalculationError(
                        "Antechamber/sqm partial charge calculation failed on "
                        "molecule {} (SMILES {})".format(
                            off_molecule.name, off_molecule.to_smiles()))

                # Read the charges
                with open('charges.txt', 'r') as infile:
                    contents = infile.read()

                text_charges = contents.split()
                charges = np.zeros([off_molecule.n_atoms], np.float64)
                for index, token in enumerate(text_charges):
                    charges[index] = float(token)

        charges = unit.Quantity(charges, unit.elementary_charge)

        assert len(charges) == len(molecule.rdkit_molecule.GetAtoms()), \
            'Partial charge computation failed as the length of ' \
            + 'resulting partial charges does not match with the ' \
            + 'number of atoms in molecule'

        return charges
Example #7
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'