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
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