def prep_for_fitting(self, molecule: Ligand) -> List[str]:
        """
        For the given ligand prep the input files ready for torsion profile fitting.

        Args:
            molecule: The molecule object that we need to prep for fitting, this should have qm reference data stored in molecule.qm_scans.

        Note:
            We assume we are already in the targets folder.

        Returns:
            A list of target folder names made by this target.

        Raises:
            MissingReferenceData: If the molecule does not have any torsion drive reference data saved in molecule.qm_scans.
        """
        # make sure we have data
        if not molecule.qm_scans:
            raise MissingReferenceData(
                f"Can not prepare a forcebalance fitting target for {molecule.name} as the reference data is missing!"
            )

        # write out the qdata and other input files for each scan
        target_folders = []
        # keep track of where we start
        base_folder = os.getcwd()

        # loop over each scanned bond and make a target folder
        for scan in molecule.qm_scans:
            task_name = (
                f"{self.target_name}_{scan.central_bond[0]}_{scan.central_bond[1]}"
            )
            target_folders.append(task_name)
            make_and_change_into(name=task_name)
            # make the pdb topology file
            if molecule.has_ub_terms():
                molecule._to_ub_pdb(file_name="molecule")
            else:
                molecule.to_file(file_name="molecule.pdb")
            # write the qdata file
            export_torsiondrive_data(molecule=molecule, tdrive_data=scan)
            # make the metadata
            self.make_metadata(torsiondrive_data=scan)
            # now move back to the base
            os.chdir(base_folder)

        return target_folders
Exemple #2
0
    def _get_prmtop(self, molecule: Ligand) -> str:
        """Method to run Antechamber, parmchk2 and tleap."""

        # file paths when moving in and out of temp locations
        cwd = os.getcwd()
        mol2 = os.path.abspath(f"{molecule.name}.mol2")
        frcmod_file = os.path.abspath(f"{molecule.name}.frcmod")
        prmtop_file = os.path.abspath(f"{molecule.name}.prmtop")
        inpcrd_file = os.path.abspath(f"{molecule.name}.inpcrd")
        ant_log = os.path.abspath("Antechamber.log")

        # Call Antechamber
        # Do this in a temp directory as it produces a lot of files
        with TemporaryDirectory() as temp:
            os.chdir(temp)
            molecule.to_file(file_name="in.sdf")

            # Call Antechamber
            cmd = f"antechamber -i in.sdf -fi sdf -o out.mol2 -fo mol2 -s 2 -m {molecule.multiplicity} -c bcc -nc {molecule.charge} -pf yes"

            with open("ante_log.txt", "w+") as log:
                sp.run(cmd, shell=True, stdout=log, stderr=log)

            # Ensure command worked
            try:
                # Copy the gaff mol2 and antechamber file back
                shutil.copy("ante_log.txt", cwd)
                shutil.copy("out.mol2", mol2)
            except FileNotFoundError:
                os.chdir(cwd)
                raise FileNotFoundError(
                    "Antechamber could not convert this file type; is it a valid pdb?"
                )

            os.chdir(cwd)

        # Work in temp directory due to the amount of files made by antechamber
        with TemporaryDirectory() as temp:
            os.chdir(temp)
            shutil.copy(mol2, "out.mol2")

            # Run parmchk
            with open("Antechamber.log", "a") as log:
                sp.run(
                    f"parmchk2 -i out.mol2 -f mol2 -o out.frcmod -s {self.force_field}",
                    shell=True,
                    stdout=log,
                    stderr=log,
                )

            # Ensure command worked
            if not os.path.exists("out.frcmod"):
                raise FileNotFoundError(
                    "out.frcmod not found parmchk2 failed!")

            # Now get the files back from the temp folder
            shutil.copy("out.mol2", mol2)
            shutil.copy("out.frcmod", frcmod_file)
            shutil.copy("Antechamber.log", ant_log)

        # Now we need to run tleap to get the prmtop and inpcrd files
        with TemporaryDirectory() as temp:
            os.chdir(temp)
            shutil.copy(mol2, "in.mol2")
            shutil.copy(frcmod_file, "in.frcmod")
            shutil.copy(ant_log, "Antechamber.log")

            # make tleap command file
            with open("tleap_commands", "w+") as tleap:
                tleap.write("""source oldff/leaprc.ff99SB
                               source leaprc.gaff
                               LIG = loadmol2 in.mol2
                               check LIG
                               loadamberparams in.frcmod
                               saveamberparm LIG out.prmtop out.inpcrd
                               quit""")

            # Now run tleap
            with open("Antechamber.log", "a") as log:
                sp.run("tleap -f tleap_commands",
                       shell=True,
                       stdout=log,
                       stderr=log)

            # Check results present
            if not os.path.exists("out.prmtop") or not os.path.exists(
                    "out.inpcrd"):
                raise FileNotFoundError(
                    "Neither out.prmtop nor out.inpcrd found; tleap failed!")

            shutil.copy("Antechamber.log", ant_log)
            shutil.copy("out.prmtop", prmtop_file)
            shutil.copy("out.inpcrd", inpcrd_file)
            os.chdir(cwd)

        # Now give the file names to parametrisation method
        prmtop = f"{molecule.name}.prmtop"
        return prmtop