Source code for simbad.mr.molrep_mr

#!/usr/bin/env ccp4-python
"""Module to run molrep on a model"""

__author__ = "Adam Simpkin"
__date__ = "02 May 2017"
__version__ = "1.0"

import os
import shutil

from pyjob import cexec


[docs]def check_contrast(logfile): """Check the logfile of the job for the contrast value Parameters ---------- logfile : str Path to the logfile Returns ------- float Contrast score in log file """ with open(logfile, 'r') as f: for line in f: if "Contrast =" in line: return float(line.split()[-1]) else: return 0.0
[docs]class Molrep(object): """Class to run Molrep Attributes ---------- enant : bool Specify whether to try enantimorphic space groups hklin : str Path to input hkl file logfile : str Path to output log file pdbin : str Path to the input pdb file pdbout : str Path to the output pdb file space_group : str The space group of the input hkl file work_dir : str Path to the working directory were you want MOLREP to run Example ------- >>> from simbad.mr.molrep_mr import Molrep >>> molrep = Molrep('<enant>', '<hklin>', '<logfile>', '<nmol>', '<pdbin>', '<pdbout>', '<space_group>', '<work_dir>') >>> molrep.run() Files relating to the MOLREP run will be contained within the work_dir however the location of the output pdb and logfile can be specified. """ def __init__(self, enant, hklin, logfile, nmol, pdbin, pdbout, space_group, work_dir): self._enant = None self._hklin = None self._logfile = None self._nmol = None self._pdbin = None self._pdbout = None self._work_dir = None self._space_group = None self.enant = enant self.hklin = hklin self.logfile = logfile self.nmol = nmol self.pdbin = pdbin self.pdbout = pdbout self.space_group = space_group self.work_dir = work_dir self.sg_codes = {"P31": "144", "P32": "145", "P3112": "151", "P3212": "153", "P3121": "152", "P3221": "154", "P41": "76", "P43": "78", "P4122": "91", "P4322": "95", "P41212": "92", "P43212": "96", "P61": "169", "P65": "170", "P62": "171", "P64": "172", "P6122": "178", "P6522": "179", "P6222": "180", "P6422": "181", "P4332": "212", "P4132": "213"} self.enant_sg = {"144": "145", "145": "144", "151": "153", "153": "151", "152": "154", "154": "152", "76": "78", "78": "76", "91": "95", "95": "91", "92": "96", "96": "92", "169": "170", "170": "169", "171": "172", "172": "171", "178": "179", "179": "178", "180": "181", "181": "180", "212": "213", "213": "212"} @property def enant(self): """Whether to check for enantimophic space groups""" return self._enant @enant.setter def enant(self, enant): """Define whether to check for enantiomorphic space groups""" self._enant = enant @property def hklin(self): """The input hkl file""" return self._hklin @hklin.setter def hklin(self, hklin): """Define the input hkl file""" self._hklin = hklin @property def logfile(self): """The logfile output""" return self._logfile @logfile.setter def logfile(self, logfile): """Define the output logfile""" self._logfile = logfile @property def nmol(self): """The number of molecules to look for""" return self._nmol @nmol.setter def nmol(self, nmol): """Define the number of molecules to look for""" self._nmol = nmol @property def pdbin(self): """The input pdb file""" return self._pdbin @pdbin.setter def pdbin(self, pdbin): """Define the input pdb file""" self._pdbin = pdbin @property def pdbout(self): """The output pdb file""" return self._pdbout @pdbout.setter def pdbout(self, pdbout): """Define the output pdb file""" self._pdbout = pdbout @property def space_group(self): """The input space group""" return self._space_group @space_group.setter def space_group(self, space_group): """Define the input space group""" self._space_group = space_group @property def work_dir(self): """The path to the working directory""" return self._work_dir @work_dir.setter def work_dir(self, work_dir): """Define the working directory""" self._work_dir = work_dir
[docs] def run(self): """Function to run molecular replacement using MOLREP Returns ------- file The output pdb from MOLREP """ # Make a note of the current working directory current_work_dir = os.getcwd() # Change to the MOLREP working directory if os.path.exists(self.work_dir): os.chdir(self.work_dir) else: os.makedirs(self.work_dir) os.chdir(self.work_dir) # Copy hklin and pdbin to working dire for efficient running of MOLREP hklin = os.path.join(self.work_dir, os.path.basename(self.hklin)) shutil.copyfile(self.hklin, hklin) pdbin = os.path.join(self.work_dir, os.path.basename(self.pdbin)) shutil.copyfile(self.pdbin, pdbin) logfile = os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(self.space_group)) key = 'NMON {0}'.format(self.nmol) Molrep.molrep(hklin, pdbin, key, logfile) # Move output pdb to specified name if os.path.isfile(os.path.join(self.work_dir, "molrep.pdb")): shutil.move(os.path.join(self.work_dir, "molrep.pdb"), os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(self.space_group))) if self.enant and self.space_group in self.sg_codes: hklin_sg_code = self.sg_codes[self.space_group] enant_sg_code = self.enant_sg[hklin_sg_code] key = 'NMON {0}'.format(self.nmol) + os.linesep + 'NOSG {0}'.format(enant_sg_code) logfile = os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(enant_sg_code)) self.molrep(hklin, pdbin, key, logfile) # Move output pdb to specified name if os.path.isfile(os.path.join(self.work_dir, "molrep.pdb")): shutil.move(os.path.join(self.work_dir, "molrep.pdb"), os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(enant_sg_code))) contrast_1 = check_contrast(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(self.space_group))) contrast_2 = check_contrast(logfile) if contrast_1 > contrast_2: # Move output pdb to specified name if os.path.isfile(os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(self.space_group))): shutil.move(os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(self.space_group)), self.pdbout) # Move log file to specified name if os.path.isfile(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(self.space_group))): shutil.move(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(self.space_group)), self.logfile) elif contrast_2 > contrast_1: # Move output pdb to specified name if os.path.isfile(os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(enant_sg_code))): shutil.move(os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(enant_sg_code)), self.pdbout) # Move log file to specified name if os.path.isfile(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(enant_sg_code))): shutil.move(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(enant_sg_code)), self.logfile) else: # Move output pdb to specified name if os.path.isfile(os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(self.space_group))): shutil.move(os.path.join(self.work_dir, 'molrep_out_{0}.pdb'.format(self.space_group)), self.pdbout) # Move log file to specified name if os.path.isfile(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(self.space_group))): shutil.move(os.path.join(self.work_dir, 'molrep_out_{0}.log'.format(self.space_group)), self.logfile) # Return to original working directory os.chdir(current_work_dir) # Delete any files copied across if os.path.isfile(os.path.join(self.work_dir, os.path.basename(self.hklin))): os.remove(os.path.join(self.work_dir, os.path.basename(self.hklin))) if os.path.isfile(os.path.join(self.work_dir, os.path.basename(self.pdbin))): os.remove(os.path.join(self.work_dir, os.path.basename(self.pdbin))) return
[docs] @ staticmethod def molrep(hklin, pdbin, key, logfile): """Function to run molecular replacement using MOLREP Parameters ---------- hklin : str Path to input hkl file pdbin : str Path to input pdb file key : str MOLREP keywords logfile : Path to output log file Returns ------- file The output pdb from MOLREP file The output log file """ cmd = ["molrep", "-f", hklin, "-m", pdbin] stdout = cexec(cmd, stdin=key) with open(logfile, 'w') as f_out: f_out.write(stdout)
if __name__ == '__main__': import argparse parser = argparse.ArgumentParser(description='Runs MR using MOLREP', prefix_chars="-") group = parser.add_argument_group() group.add_argument('-enant', help="Try enantimorph space groups <True|False>") group.add_argument('-hklin', type=str, help="Path the input hkl file") group.add_argument('-logfile', type=str, help="Path to the ouput log file") group.add_argument('-nmol', type=int, help="The predicted number of molecules to build") group.add_argument('-pdbin', type=str, help="Path to the input pdb file") group.add_argument('-pdbout', type=str, help="Path to the output pdb file") group.add_argument('-space_group', type=str, help="The input space group") group.add_argument('-work_dir', type=str, help="Path to the working directory") args = parser.parse_args() if args.enant.lower() == 'true': enant = True elif args.enant.lower() == 'false': enant = False else: raise RuntimeError("Incorrect input for '-enant', use 'True' or 'False'") molrep = Molrep(enant, args.hklin, args.logfile, args.nmol, args.pdbin, args.pdbout, args.space_group, args.work_dir) molrep.run()