def test3(): for i in arange(10,31,2.5): fbase = "{}_{}".format(100.,i) top = "{}.top".format(fbase) sol = "{}.sol.pdb".format(fbase) ndx = "{}.ndx".format(fbase) gromacs.grompp(f="md3.mdp", o="{}.tpr".format(fbase), c=sol, p=top, n=ndx) #@UndefinedVariable
def make_tpr(box, rrange): for radius in rrange: fbase = "{}_{}".format(box,radius) top = "{}.top".format(fbase) sol = "{}.sol.pdb".format(fbase) ndx = "{}.ndx".format(fbase) gromacs.grompp(f="md2.mdp", o="{}.tpr".format(fbase), c=sol, p=top, n=ndx) #@UndefinedVariable
def test3(): for i in arange(10, 31, 2.5): fbase = "{}_{}".format(100.0, i) top = "{}.top".format(fbase) sol = "{}.sol.pdb".format(fbase) ndx = "{}.ndx".format(fbase) gromacs.grompp(f="md3.mdp", o="{}.tpr".format(fbase), c=sol, p=top, n=ndx) # @UndefinedVariable
def do_energy_min(pdb, itpfn, outpdb="out.pdb"): # write the topology file with open("topol_em.top", "w") as fh_t: fh_t.write(HEAD_TOP_FILE) fh_t.write("#include " + '"' + itpfn + '"') fh_t.write(BOTTOM_TOP_FILE) # TODO function that checks if files are present gromacs.grompp(f="em.mdp", c=pdb, p="topol_em.top", o="em.tpr", maxwarn="99") gromacs.mdrun(s="em.tpr", c=outpdb)
def test2(a,radius,box=100.0,fbase=None): # l.test2(5.0797,15) if fbase is None: fbase = "{}_{}".format(box,radius) top = "{}.top".format(fbase) struct = "{}.pdb".format(fbase) sol = "{}.sol.pdb".format(fbase) ndx = "{}.ndx".format(fbase) origin = box/2. pts=fcc_sphere(a, radius) w=writer("{}.pdb".format(fbase)) w.CRYST1([box,box,box,90.00,90.00,90.00]) for index,atom in enumerate(pts): w.ATOM(serial=index+1, name="AU", resName="NP", resSeq=1, chainID="A", segID="AUNP", element="AU", x=atom[0]+origin, y=atom[1]+origin, z=atom[2]+origin) w.close() #make_index("{}.pdb".format(fbase), "{}.ndx".format(fbase)) with file(top, "w") as t: t.write(top_src) t.write("Au {}\n".format(pts.shape[0])) gromacs.genbox(p=top, cp=struct, cs="spc216.gro", o=sol, vdwd="0.15") #@UndefinedVariable rc,out,nothing = gromacs.make_ndx(f=sol, n=None, o=ndx, stdout=False, #@UndefinedVariable input=('', '', 'q')) gromacs.grompp(f="md2.mdp", o="{}.tpr".format(fbase), c=sol, p=top, n=ndx) #@UndefinedVariable with file("{}.sh".format(fbase), "w") as f: f.write("#!/bin/bash\n") f.write("#PBS -k o\n") f.write("#PBS -l nodes=1:ppn=12:ccvt,walltime=24:00:00\n") f.write("#PBS -M [email protected]\n") f.write("#PBS -m abe\n") f.write("#PBS -N {}\n".format(fbase)) f.write("#PBS -j oe\n") f.write("#PBS -q pg\n") f.write("#PBS -d /N/dc/scratch/somogyie/Au\n") f.write("mpirun mdrun -deffnm {}".format(fbase))
def make_tpr(box, rrange): for radius in rrange: fbase = "{}_{}".format(box, radius) top = "{}.top".format(fbase) sol = "{}.sol.pdb".format(fbase) ndx = "{}.ndx".format(fbase) gromacs.grompp(f="md2.mdp", o="{}.tpr".format(fbase), c=sol, p=top, n=ndx) #@UndefinedVariable
def _compile_tpr(self, step_name: str, geometry: GenPath = None, trajectory: GenPath = None ) -> pathlib.Path: """ Make a tpr file for the chosen step_name and associated mdp file :param step_name: Key for the mdp file from the dict mdps :param geometry: Path to the geometry to be used as input. If None, :attr:`last_geometry` will be used. :param trajectory: Path to a trajectory file from which to take the input geometry. This is useful when a full precision geometry is needed as input and a trr file can be used. If None, no trajectory will be given to grompp. :return: The Path to the tpr file """ geometry = self.last_geometry if geometry is None else geometry tpr = '{}-{}.tpr'.format(self.name, step_name) p_tpr = self._fp(tpr) self.tprs[step_name] = p_tpr rc, output, junk = gromacs.grompp(c=geometry, p=self.top, f=self.mdps[step_name], o=tpr, t=trajectory, stdout=False) # Doesn't capture output if failed? self.outputs['compile_{}'.format(step_name)] = output return p_tpr
def grompp(f, c, p, prefix="topol"): s = prefix + '.tpr' po = prefix + '.mdp' rc, output, junk = gromacs.grompp(f=f, p=p, c=c, o=s, po=po, stdout=False, stderr=False) #print(rc, output, junk) assert rc == 0, \ "grompp -o {0} -po {1} -f {2} -c {3} -p {4} failed".format(s, po, f, c, p) return s
def test_grompp(self, tmpdir): """Check if grompp can be run successfully at all""" f = self.mdp c = self.conf p = self.processed with tmpdir.as_cwd(): o = 'topol.tpr' po = 'mdout.mdp' rc, output, junk = gromacs.grompp(f=f, p=p, c=c, o=o, po=po, stdout=False, stderr=False) assert rc == 0, "grompp -f {0} -o {1} ... failed to run".format(f, o)
def test_grompp(self, tmpdir): """Check if grompp can be run successfully at all""" f = self.mdp c = self.conf p = self.processed with tmpdir.as_cwd(): o = 'topol.tpr' po = 'mdout.mdp' rc, output, junk = gromacs.grompp(f=f, p=p, c=c, o=o, po=po, stdout=False, stderr=False) assert rc == 0, "grompp -f {0} -o {1} ... failed to run".format( f, o)
def _setup_MD(dirname, deffnm='md', mdp=config.templates['md_OPLSAA.mdp'], struct=None, top='top/system.top', ndx=None, mainselection='"Protein"', qscript=config.qscript_template, qname=None, startdir=None, mdrun_opts="", budget=None, walltime=1/3., dt=0.002, runtime=1e3, **mdp_kwargs): """Generic function to set up a ``mdrun`` MD simulation. See the user functions for usage. """ if struct is None: raise ValueError('struct must be set to a input structure') structure = realpath(struct) topology = realpath(top) try: index = realpath(ndx) except AttributeError: # (that's what realpath(None) throws...) index = None # None is handled fine below qname = mdp_kwargs.pop('sgename', qname) # compatibility for old scripts qscript = mdp_kwargs.pop('sge', qscript) # compatibility for old scripts qscript_template = config.get_template(qscript) mdp_template = config.get_template(mdp) nsteps = int(float(runtime)/float(dt)) mdp = deffnm + '.mdp' tpr = deffnm + '.tpr' mainindex = deffnm + '.ndx' final_structure = deffnm + '.gro' # guess... really depends on templates,could also be DEFFNM.pdb # write the processed topology to the default output mdp_parameters = {'nsteps':nsteps, 'dt':dt, 'pp': 'processed.top'} mdp_parameters.update(mdp_kwargs) cbook.add_mdp_includes(topology, mdp_parameters) logger.info("[%(dirname)s] input mdp = %(mdp_template)r", vars()) with in_dir(dirname): if not (mdp_parameters.get('Tcoupl','').lower() == 'no' or mainselection is None): logger.info("[{dirname!s}] Automatic adjustment of T-coupling groups".format(**vars())) # make index file in almost all cases; with mainselection == None the user # takes FULL control and also has to provide the template or index groups = make_main_index(structure, selection=mainselection, oldndx=index, ndx=mainindex) natoms = {g['name']: float(g['natoms']) for g in groups} tc_group_names = ('__main__', '__environment__') # defined in make_main_index() try: x = natoms['__main__']/natoms['__environment__'] except KeyError: x = 0 # force using SYSTEM in code below wmsg = "Missing __main__ and/or __environment__ index group.\n" \ "This probably means that you have an atypical system. You can " \ "set mainselection=None and provide your own mdp and index files " \ "in order to set up temperature coupling.\n" \ "If no T-coupling is required then set Tcoupl='no'.\n" \ "For now we will just couple everything to 'System'." logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if x < 0.1: # couple everything together tau_t = firstof(mdp_parameters.pop('tau_t', 0.1)) ref_t = firstof(mdp_parameters.pop('ref_t', 300)) # combine all in one T-coupling group mdp_parameters['tc-grps'] = 'System' mdp_parameters['tau_t'] = tau_t # this overrides the commandline! mdp_parameters['ref_t'] = ref_t # this overrides the commandline! mdp_parameters['gen-temp'] = mdp_parameters.pop('gen_temp', ref_t) wmsg = "Size of __main__ is only %.1f%% of __environment__ so " \ "we use 'System' for T-coupling and ref_t = %g K and " \ "tau_t = %g 1/ps (can be changed in mdp_parameters).\n" \ % (x * 100, ref_t, tau_t) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) else: # couple protein and bath separately n_tc_groups = len(tc_group_names) tau_t = asiterable(mdp_parameters.pop('tau_t', 0.1)) ref_t = asiterable(mdp_parameters.pop('ref_t', 300)) if len(tau_t) != n_tc_groups: tau_t = n_tc_groups * [tau_t[0]] wmsg = "%d coupling constants should have been supplied for tau_t. "\ "Using %f 1/ps for all of them." % (n_tc_groups, tau_t[0]) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if len(ref_t) != n_tc_groups: ref_t = n_tc_groups * [ref_t[0]] wmsg = "%d temperatures should have been supplied for ref_t. "\ "Using %g K for all of them." % (n_tc_groups, ref_t[0]) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) mdp_parameters['tc-grps'] = tc_group_names mdp_parameters['tau_t'] = tau_t mdp_parameters['ref_t'] = ref_t mdp_parameters['gen-temp'] = mdp_parameters.pop('gen_temp', ref_t[0]) index = realpath(mainindex) if mdp_parameters.get('Tcoupl','').lower() == 'no': logger.info("Tcoupl == no: disabling all temperature coupling mdp options") mdp_parameters['tc-grps'] = "" mdp_parameters['tau_t'] = "" mdp_parameters['ref_t'] = "" mdp_parameters['gen-temp'] = "" if mdp_parameters.get('Pcoupl','').lower() == 'no': logger.info("Pcoupl == no: disabling all pressure coupling mdp options") mdp_parameters['tau_p'] = "" mdp_parameters['ref_p'] = "" mdp_parameters['compressibility'] = "" unprocessed = cbook.edit_mdp(mdp_template, new_mdp=mdp, **mdp_parameters) check_mdpargs(unprocessed) gromacs.grompp(f=mdp, p=topology, c=structure, n=index, o=tpr, **unprocessed) runscripts = qsub.generate_submit_scripts( qscript_template, deffnm=deffnm, jobname=qname, budget=budget, startdir=startdir, mdrun_opts=mdrun_opts, walltime=walltime) logger.info("[%(dirname)s] output mdp = %(mdp)r", vars()) logger.info("[%(dirname)s] output ndx = %(ndx)r", vars()) logger.info("[%(dirname)s] output tpr = %(tpr)r", vars()) logger.info("[%(dirname)s] output runscripts = %(runscripts)r", vars()) logger.info("[%(dirname)s] All files set up for a run time of %(runtime)g ps " "(dt=%(dt)g, nsteps=%(nsteps)g)" % vars()) kwargs = {'struct': realpath(os.path.join(dirname, final_structure)), # guess 'top': topology, 'ndx': index, # possibly mainindex 'qscript': runscripts, 'mainselection': mainselection, 'deffnm': deffnm, # return deffnm (tpr = deffnm.tpr!) } kwargs.update(mdp_kwargs) # return extra mdp args so that one can use them for prod run return kwargs
def energy_minimize(dirname='em', mdp=config.templates['em.mdp'], struct='solvate/ionized.gro', top='top/system.top', output='em.pdb', deffnm="em", mdrunner=None, **kwargs): """Energy minimize the system. This sets up the system (creates run input files) and also runs ``mdrun_d``. Thus it can take a while. Additional itp files should be in the same directory as the top file. Many of the keyword arguments below already have sensible values. :Keywords: *dirname* set up under directory dirname [em] *struct* input structure (gro, pdb, ...) [solvate/ionized.gro] *output* output structure (will be put under dirname) [em.pdb] *deffnm* default name for mdrun-related files [em] *top* topology file [top/system.top] *mdp* mdp file (or use the template) [templates/em.mdp] *includes* additional directories to search for itp files *mdrunner* :class:`gromacs.run.MDrunner` instance; by default we just try :func:`gromacs.mdrun_d` and :func:`gromacs.mdrun` but a MDrunner instance gives the user the ability to run mpi jobs etc. [None] *kwargs* remaining key/value pairs that should be changed in the template mdp file, eg ``nstxtcout=250, nstfout=250``. .. note:: If :func:`~gromacs.mdrun_d` is not found, the function falls back to :func:`~gromacs.mdrun` instead. """ structure = realpath(struct) topology = realpath(top) mdp_template = config.get_template(mdp) deffnm = deffnm.strip() # write the processed topology to the default output kwargs.setdefault('pp', 'processed.top') # filter some kwargs that might come through when feeding output # from previous stages such as solvate(); necessary because *all* # **kwargs must be *either* substitutions in the mdp file *or* valid # command line parameters for ``grompp``. kwargs.pop('ndx', None) # mainselection is not used but only passed through; right now we # set it to the default that is being used in all argument lists # but that is not pretty. TODO. mainselection = kwargs.pop('mainselection', '"Protein"') # only interesting when passed from solvate() qtot = kwargs.pop('qtot', 0) mdp = deffnm+'.mdp' tpr = deffnm+'.tpr' logger.info("[{dirname!s}] Energy minimization of struct={struct!r}, top={top!r}, mdp={mdp!r} ...".format(**vars())) cbook.add_mdp_includes(topology, kwargs) if qtot != 0: # At the moment this is purely user-reported and really only here because # it might get fed into the function when using the keyword-expansion pipeline # usage paradigm. wmsg = "Total charge was reported as qtot = {qtot:g} <> 0; probably a problem.".format(**vars()) logger.warn(wmsg) warnings.warn(wmsg, category=BadParameterWarning) with in_dir(dirname): unprocessed = cbook.edit_mdp(mdp_template, new_mdp=mdp, **kwargs) check_mdpargs(unprocessed) gromacs.grompp(f=mdp, o=tpr, c=structure, p=topology, **unprocessed) mdrun_args = dict(v=True, stepout=10, deffnm=deffnm, c=output) if mdrunner is None: mdrun = run.get_double_or_single_prec_mdrun() mdrun(**mdrun_args) else: if type(mdrunner) is type: # class # user wants full control and provides simulation.MDrunner **class** # NO CHECKING --- in principle user can supply any callback they like mdrun = mdrunner(**mdrun_args) mdrun.run() else: # anything with a run() method that takes mdrun arguments... try: mdrunner.run(mdrunargs=mdrun_args) except AttributeError: logger.error("mdrunner: Provide a gromacs.run.MDrunner class or instance or a callback with a run() method") raise TypeError("mdrunner: Provide a gromacs.run.MDrunner class or instance or a callback with a run() method") # em.gro --> gives 'Bad box in file em.gro' warning --- why?? # --> use em.pdb instead. if not os.path.exists(output): errmsg = "Energy minimized system NOT produced." logger.error(errmsg) raise GromacsError(errmsg) final_struct = realpath(output) logger.info("[{dirname!s}] energy minimized structure {final_struct!r}".format(**vars())) return {'struct': final_struct, 'top': topology, 'mainselection': mainselection, }
def test_harmonic_potential(): import gmx import os import myplugin cwd = os.path.dirname(__file__) water = os.path.join(cwd, 'data', 'water.gro') import shutil shutil.copy(water, './') try: # use GromacsWrapper if available import gromacs import gromacs.formats from gromacs.tools import Solvate as solvate solvate(o='water.gro', box=[5, 5, 5]) mdpparams = [('integrator', 'md'), ('nsteps', 1000), ('nstxout', 100), ('nstvout', 100), ('nstfout', 100), ('tcoupl', 'v-rescale'), ('tc-grps', 'System'), ('tau-t', 1), ('ref-t', 298)] mdp = gromacs.formats.MDP() for param, value in mdpparams: mdp[param] = value mdp.write('water.mdp') with open('input.top', 'w') as fh: fh.write("""#include "gromos43a1.ff/forcefield.itp" #include "gromos43a1.ff/spc.itp" [ system ] ; Name spc [ molecules ] ; Compound #mols SOL 4055 """) gromacs.grompp(f='water.mdp', c='water.gro', po='water.mdp', pp='water.top', o='water.tpr', p='input.top') tpr_filename = os.path.abspath('water.tpr') except: from gmx.data import tpr_filename print("Testing plugin potential with input file {}".format( os.path.abspath(tpr_filename))) md = gmx.workflow.from_tpr(tpr_filename, append_output=False) context = gmx.context.ParallelArrayContext(md) with context as session: session.run() # Create a WorkElement for the potential #potential = gmx.core.TestModule() params = {'sites': [1, 4], 'R0': 2.0, 'k': 10000.0} potential_element = gmx.workflow.WorkElement(namespace="myplugin", operation="create_restraint", params=params) # Note that we could flexibly capture accessor methods as workflow elements, too. Maybe we can # hide the extra Python bindings by letting myplugin.HarmonicRestraint automatically convert # to a WorkElement when add_dependency is called on it. potential_element.name = "harmonic_restraint" before = md.workspec.elements[md.name] md.add_dependency(potential_element) assert potential_element.name in md.workspec.elements assert potential_element.workspec is md.workspec after = md.workspec.elements[md.name] assert not before is after # Context will need to do these in __enter__ # potential = myplugin.HarmonicRestraint() # potential.set_params(1, 4, 2.0, 10000.0) context = gmx.context.ParallelArrayContext(md) with context as session: session.run()
def add_box_mutation(self): """ Function to add the solvent and run a minimization of the local amino acid with the waters included Output: system.gro -- file containing the complete system minimized after the mutation """ # Read the solvent os.system("grep ATOM {path}/solvent/solvent_{itera}.pdb | grep -v ENDMDL > {path}/solvent.pdb".format(path=self.path,itera=self.last_iteration)) # Concatenate complex and system os.system("cat {path}/complex.pdb {path}/solvent.pdb > {path}/system.pdb".format(path=self.path)) rc,sout,serr=gromacs.editconf(f=self.path+"/system.pdb", o=self.path+"/system_mod.pdb", stdout=False) os.system("mv {}/system_mod.pdb {}/system.pdb".format(self.path,self.path)) # Make an index of the system rc,sout,serr=gromacs.make_ndx(f=self.path+"/system.pdb", o=self.path+"/index.ndx", stdout=False, input=('chain {} \n q'.format(self.pep_chain))) # Copy the topol files of the target chains, which are the same always if self.target=="protein": for ch in self.chain_join: os.system("cp {}/topol_Protein_chain_{}.itp {}/system_Protein_chain_{}.itp".format(self.path,ch,self.path,ch)) if self.target=="drug": for ch in self.chain_join: os.system("cp {}/topol_Drug_chain_{}.itp {}/system_Drug_chain_{}.itp".format(self.path,ch,self.path,ch)) # Copy the topol.top to system.top os.system("cp {}/topol.top {}/system.top".format(self.path,self.path)) os.system("cp {}/complex_Protein_chain_{}.itp {}/system_Protein_chain_{}.itp".format(self.path,self.pep_chain,self.path,self.pep_chain)) os.system("sed -i 's/topol_/system_/g' {}/system.top".format(self.path)) # Select water and ions within 0.2 distance of the residue rc,sout,serr=gromacs.make_ndx(f=self.path+"/system.pdb", o=self.path+"/index.ndx", stdout=False, input=('chain {}'.format(self.pep_chain),'q')) rc,sout,serr=gromacs.select(f=self.path+"/system.pdb", n=self.path+"/index.ndx", s=self.path+"/system.pdb", on=self.path+"/index_sol.ndx", stdout=False, select="group Water_and_ions and same residue as within 0.2 of (group ch{} and resnr {})".format(self.pep_chain,self.pep_position)) # Solve the issue with atoms overlapped with the selected residue values=[x.strip() for x in open(self.path+"/index_sol.ndx")] atomsSOL=[] for i,v in enumerate(values): if i!=0: info=v.split() atomsSOL=atomsSOL+info # List of the atoms that will be deleted atomsDelete=[] # Check the overlapped atoms for a in atomsSOL: # Obtain the list of atoms from the index file bash = "awk '$2 == '{}' {{print $6','$7','$8}}' {}/system.pdb".format(a,self.path) coordinates = subprocess.check_output(['bash','-c', bash]) comp=coordinates.strip().split() comparison=[] for c in comp: comparison.append(float(c)) ndComp=np.array(comparison) distancesSOL=[] # Read the structure in biopython parser = PDBParser() structure = parser.get_structure('PEP', self.path+"/system.pdb") model = structure[0] # Check the distances with all the atoms from the selected residue for residue in model[self.pep_chain]: resC=residue.get_resname() resNumber=residue.get_full_id()[3][1] if resNumber==self.pep_position: for atom in residue: idAtom = atom.get_id() if idAtom[0].isdigit() == False: if resC=="ILE" and idAtom=="CD": idAtom="CD1" diff = atom.coord - ndComp diffValue=np.sqrt(np.sum(diff * diff)) distancesSOL.append(float(diffValue)) # Threshold to determine which atoms can be overlapped if min(distancesSOL)<1.0: if a not in atomsDelete: atomsDelete.append(a) # Selection of the final atoms that will be included in the index final_index=[] for element in atomsSOL: flag=0 for delete in atomsDelete: if abs(int(element)-int(delete))<=2: flag=1 if flag==0: final_index.append(element) # Update of the index sol file new_index=open(self.path+"/index_sol2.ndx","w") new_index.write("{}\n".format(values[0])) group=[] counter=1 for ele in final_index: if counter <15: group.append(ele) counter+=1 else: group.append(ele) new_index.write(" ".join(group)+" \n") counter=1 group=[] new_index.write(" ".join(group)+" ") new_index.close() # Update the file os.system("mv {}/index_sol2.ndx {}/index_sol.ndx".format(self.path,self.path)) ref_ndx = NDX() ref_ndx.read(self.path+"/index.ndx") bash="grep '\[' {}/index.ndx | wc -l".format(self.path) number_index = subprocess.check_output(['bash','-c', bash]) index_ref=int(number_index)-1 #index_ref=len(ref_ndx)-1 # Create the side chain index in a template file os.system("echo 'name 0 overlap' > %s/template" %self.path) os.system("echo '\"SideChain\" & \"ch{}\" & r {}' >> {}/template".format(self.pep_chain,str(self.pep_position),self.path)) os.system("echo '\"overlap\" | \"SideChain_&_ch{}_&_r_{}\"' >> {}/template".format(self.pep_chain,str(self.pep_position),self.path)) os.system("echo '\"System\" &! \"overlap_SideChain_&_ch{}_&_r_{}\"' >> {}/template".format(self.pep_chain,str(self.pep_position),self.path)) os.system("echo 'q' >> {}/template".format(self.path)) # Create an index joining both created before os.system("gmx -quiet make_ndx -f {path}/system.pdb -n {path}/index_sol.ndx {path}/index.ndx -o {path}/total_index.ndx < {path}/template".format(path=self.path)) os.system("sed -i 's/System_&_\!overlap_SideChain_&_ch{}_&_r_{}/to_block/g' {}/total_index.ndx".format(self.pep_chain,str(self.pep_position),self.path)) # Generate the gro file rc,sout,serr=gromacs.editconf(f=self.path+"/system.pdb", o=self.path+"/system.gro", stdout=False) # Prepare the files for the minimization and run rc,sout,serr=gromacs.grompp(f=self.path+"/mdp/minim_overlap.mdp", o=self.path+"/systemNEW.tpr", p=self.path+"/system.top", n=self.path+"/total_index.ndx", c=self.path+"/system.gro", stdout=False) gromacs.utilities.unlink_gmx("mdout.mdp") print("Running second minimization ...") rc,sout,serr=gromacs.mdrun(deffnm=self.path+"/systemNEW", stdout=False) # Copy the system.gro file that will be used to run the last minimization os.system("cp {}/systemNEW.gro {}/system.gro".format(self.path,self.path)) os.system("sed -i '$ d' {}/system.gro".format(self.path)) os.system("tail -n1 {path}/npt-pbc.gro >> {path}/system.gro".format(path=self.path)) # Delete temporal files os.system("rm {path}/complex.pdb {path}/solvent.pdb {path}/systemNEW* {path}/template {path}/index.ndx {path}/index_sol.ndx {path}/total_index.ndx *.itp".format(path=self.path))
def test_ensemble_potential_nompi(): """Test ensemble potential without an ensemble. Still requires ParallelArrayContext. """ import gmx import os import myplugin cwd = os.path.dirname(__file__) water = os.path.join(cwd, 'data', 'water.gro') import shutil shutil.copy(water, './') # assert False try: # use GromacsWrapper if available import gromacs import gromacs.formats from gromacs.tools import Solvate as solvate solvate(o='water.gro', box=[5, 5, 5]) mdpparams = [('integrator', 'md'), ('nsteps', 1000), ('nstxout', 100), ('nstvout', 100), ('nstfout', 100), ('tcoupl', 'v-rescale'), ('tc-grps', 'System'), ('tau-t', 1), ('ref-t', 298)] mdp = gromacs.formats.MDP() for param, value in mdpparams: mdp[param] = value mdp.write('water.mdp') with open('input.top', 'w') as fh: fh.write("""#include "gromos43a1.ff/forcefield.itp" #include "gromos43a1.ff/spc.itp" [ system ] ; Name spc [ molecules ] ; Compound #mols SOL 4055 """) gromacs.grompp(f='water.mdp', c='water.gro', po='water.mdp', pp='water.top', o='water.tpr', p='input.top') tpr_filename = os.path.abspath('water.tpr') except: from gmx.data import tpr_filename print("Testing plugin potential with input file {}".format( os.path.abspath(tpr_filename))) assert gmx.version.api_is_at_least(0, 0, 5) md = gmx.workflow.from_tpr([tpr_filename], append_output=False) # Create a WorkElement for the potential #potential = gmx.core.TestModule() params = { 'sites': [1, 4], 'nbins': 10, 'binWidth': 0.1, 'min_dist': 0., 'max_dist': 10., 'experimental': [1.] * 10, 'nsamples': 1, 'sample_period': 0.001, 'nwindows': 4, 'k': 10000., 'sigma': 1. } potential = gmx.workflow.WorkElement(namespace="myplugin", operation="ensemble_restraint", params=params) # Note that we could flexibly capture accessor methods as workflow elements, too. Maybe we can # hide the extra Python bindings by letting myplugin.HarmonicRestraint automatically convert # to a WorkElement when add_dependency is called on it. potential.name = "ensemble_restraint" md.add_dependency(potential) context = gmx.context.ParallelArrayContext(md) with context as session: session.run()
def test_failure_raises(): # unknown option with pytest.raises(gromacs.GromacsError): gromacs.grompp(y=True)
def energy_minimize(dirname='em', mdp=config.templates['em.mdp'], struct='solvate/ionized.gro', top='top/system.top', output='em.pdb', deffnm="em", mdrunner=None, **kwargs): """Energy minimize the system. This sets up the system (creates run input files) and also runs ``mdrun_d``. Thus it can take a while. Additional itp files should be in the same directory as the top file. Many of the keyword arguments below already have sensible values. :Keywords: *dirname* set up under directory dirname [em] *struct* input structure (gro, pdb, ...) [solvate/ionized.gro] *output* output structure (will be put under dirname) [em.pdb] *deffnm* default name for mdrun-related files [em] *top* topology file [top/system.top] *mdp* mdp file (or use the template) [templates/em.mdp] *includes* additional directories to search for itp files *mdrunner* :class:`gromacs.run.MDrunner` instance; by default we just try :func:`gromacs.mdrun_d` and :func:`gromacs.mdrun` but a MDrunner instance gives the user the ability to run mpi jobs etc. [None] *kwargs* remaining key/value pairs that should be changed in the template mdp file, eg ``nstxtcout=250, nstfout=250``. .. note:: If :func:`~gromacs.mdrun_d` is not found, the function falls back to :func:`~gromacs.mdrun` instead. """ structure = realpath(struct) topology = realpath(top) mdp_template = config.get_template(mdp) deffnm = deffnm.strip() # write the processed topology to the default output kwargs.setdefault('pp', 'processed.top') # filter some kwargs that might come through when feeding output # from previous stages such as solvate(); necessary because *all* # **kwargs must be *either* substitutions in the mdp file *or* valid # command line parameters for ``grompp``. kwargs.pop('ndx', None) # mainselection is not used but only passed through; right now we # set it to the default that is being used in all argument lists # but that is not pretty. TODO. mainselection = kwargs.pop('mainselection', '"Protein"') # only interesting when passed from solvate() qtot = kwargs.pop('qtot', 0) mdp = deffnm + '.mdp' tpr = deffnm + '.tpr' logger.info( "[{dirname!s}] Energy minimization of struct={struct!r}, top={top!r}, mdp={mdp!r} ..." .format(**vars())) cbook.add_mdp_includes(topology, kwargs) if qtot != 0: # At the moment this is purely user-reported and really only here because # it might get fed into the function when using the keyword-expansion pipeline # usage paradigm. wmsg = "Total charge was reported as qtot = {qtot:g} <> 0; probably a problem.".format( **vars()) logger.warn(wmsg) warnings.warn(wmsg, category=BadParameterWarning) with in_dir(dirname): unprocessed = cbook.edit_mdp(mdp_template, new_mdp=mdp, **kwargs) check_mdpargs(unprocessed) gromacs.grompp(f=mdp, o=tpr, c=structure, p=topology, **unprocessed) mdrun_args = dict(v=True, stepout=10, deffnm=deffnm, c=output) if mdrunner is None: mdrun = run.get_double_or_single_prec_mdrun() mdrun(**mdrun_args) else: if type(mdrunner) is type: # class # user wants full control and provides simulation.MDrunner **class** # NO CHECKING --- in principle user can supply any callback they like mdrun = mdrunner(**mdrun_args) mdrun.run() else: # anything with a run() method that takes mdrun arguments... try: mdrunner.run(mdrunargs=mdrun_args) except AttributeError: logger.error( "mdrunner: Provide a gromacs.run.MDrunner class or instance or a callback with a run() method" ) raise TypeError( "mdrunner: Provide a gromacs.run.MDrunner class or instance or a callback with a run() method" ) # em.gro --> gives 'Bad box in file em.gro' warning --- why?? # --> use em.pdb instead. if not os.path.exists(output): errmsg = "Energy minimized system NOT produced." logger.error(errmsg) raise GromacsError(errmsg) final_struct = realpath(output) logger.info( "[{dirname!s}] energy minimized structure {final_struct!r}".format( **vars())) return { 'struct': final_struct, 'top': topology, 'mainselection': mainselection, }
def test2(a, radius, box=100.0, fbase=None): # l.test2(5.0797,15) if fbase is None: fbase = "{}_{}".format(box, radius) top = "{}.top".format(fbase) struct = "{}.pdb".format(fbase) sol = "{}.sol.pdb".format(fbase) ndx = "{}.ndx".format(fbase) origin = box / 2. pts = fcc_sphere(a, radius) w = writer("{}.pdb".format(fbase)) w.CRYST1([box, box, box, 90.00, 90.00, 90.00]) for index, atom in enumerate(pts): w.ATOM(serial=index + 1, name="AU", resName="NP", resSeq=1, chainID="A", segID="AUNP", element="AU", x=atom[0] + origin, y=atom[1] + origin, z=atom[2] + origin) w.close() #make_index("{}.pdb".format(fbase), "{}.ndx".format(fbase)) with file(top, "w") as t: t.write(top_src) t.write("Au {}\n".format(pts.shape[0])) gromacs.genbox(p=top, cp=struct, cs="spc216.gro", o=sol, vdwd="0.15") #@UndefinedVariable rc, out, nothing = gromacs.make_ndx( f=sol, n=None, o=ndx, stdout=False, #@UndefinedVariable input=('', '', 'q')) gromacs.grompp(f="md2.mdp", o="{}.tpr".format(fbase), c=sol, p=top, n=ndx) #@UndefinedVariable with file("{}.sh".format(fbase), "w") as f: f.write("#!/bin/bash\n") f.write("#PBS -k o\n") f.write("#PBS -l nodes=1:ppn=12:ccvt,walltime=24:00:00\n") f.write("#PBS -M [email protected]\n") f.write("#PBS -m abe\n") f.write("#PBS -N {}\n".format(fbase)) f.write("#PBS -j oe\n") f.write("#PBS -q pg\n") f.write("#PBS -d /N/dc/scratch/somogyie/Au\n") f.write("mpirun mdrun -deffnm {}".format(fbase))
def _setup_MD(dirname, deffnm='md', mdp=config.templates['md_OPLSAA.mdp'], struct=None, top='top/system.top', ndx=None, mainselection='"Protein"', qscript=config.qscript_template, qname=None, startdir=None, mdrun_opts="", budget=None, walltime=1/3., dt=0.002, runtime=1e3, multi=1, **mdp_kwargs): """Generic function to set up a ``mdrun`` MD simulation. See the user functions for usage. @param qname: name of the queing system, may be None. @param multi: setup multiple concurrent simulations. These are based upon deffnm being set, and a set of mdp / tpr are created named [deffnm]0.tpr. [deffnm]1.tpr, ... """ if struct is None: raise ValueError('struct must be set to a input structure') structure = realpath(struct) topology = realpath(top) try: index = realpath(ndx) except AttributeError: # (that's what realpath(None) throws...) index = None # None is handled fine below qname = mdp_kwargs.pop('sgename', qname) # compatibility for old scripts qscript = mdp_kwargs.pop('sge', qscript) # compatibility for old scripts qscript_template = config.get_template(qscript) mdp_template = config.get_template(mdp) nsteps = int(float(runtime)/float(dt)) mainindex = deffnm + '.ndx' final_structure = deffnm + '.pdb' # guess... really depends on templates,could also be DEFFNM.pdb # write the processed topology to the default output mdp_parameters = {'nsteps':nsteps, 'dt':dt} mdp_parameters.update(mdp_kwargs) add_mdp_includes(topology, mdp_parameters) # the basic result dictionary # depending on options, various bits might be added to this. result = {'struct': realpath(os.path.join(dirname, final_structure)), # guess 'top': topology, 'ndx': index, # possibly mainindex 'mainselection': mainselection, 'deffnm': deffnm, # return deffnm (tpr = deffnm.tpr!) } with in_dir(dirname): if not (mdp_parameters.get('Tcoupl','').lower() == 'no' or mainselection is None): logger.info("[%(dirname)s] Automatic adjustment of T-coupling groups" % vars()) # make index file in almost all cases; with mainselection == None the user # takes FULL control and also has to provide the template or index groups = make_main_index(structure, selection=mainselection, oldndx=index, ndx=mainindex) natoms = dict([(g['name'], float(g['natoms'])) for g in groups]) tc_group_names = ('__main__', '__environment__') # defined in make_main_index() try: x = natoms['__main__']/natoms['__environment__'] except KeyError: x = 0 # force using SYSTEM in code below wmsg = "Missing __main__ and/or __environment__ index group.\n" \ "This probably means that you have an atypical system. You can " \ "set mainselection=None and provide your own mdp and index files " \ "in order to set up temperature coupling.\n" \ "If no T-coupling is required then set Tcoupl='no'.\n" \ "For now we will just couple everything to 'System'." logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if x < 0.1: # couple everything together tau_t = firstof(mdp_parameters.pop('tau_t', 0.1)) ref_t = firstof(mdp_parameters.pop('ref_t', 300)) # combine all in one T-coupling group mdp_parameters['tc-grps'] = 'System' mdp_parameters['tau_t'] = tau_t # this overrides the commandline! mdp_parameters['ref_t'] = ref_t # this overrides the commandline! mdp_parameters['gen-temp'] = mdp_parameters.pop('gen_temp', ref_t) wmsg = "Size of __main__ is only %.1f%% of __environment__ so " \ "we use 'System' for T-coupling and ref_t = %g K and " \ "tau_t = %g 1/ps (can be changed in mdp_parameters).\n" \ % (x * 100, ref_t, tau_t) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) else: # couple protein and bath separately n_tc_groups = len(tc_group_names) tau_t = asiterable(mdp_parameters.pop('tau_t', 0.1)) ref_t = asiterable(mdp_parameters.pop('ref_t', 300)) if len(tau_t) != n_tc_groups: tau_t = n_tc_groups * [tau_t[0]] wmsg = "%d coupling constants should have been supplied for tau_t. "\ "Using %f 1/ps for all of them." % (n_tc_groups, tau_t[0]) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if len(ref_t) != n_tc_groups: ref_t = n_tc_groups * [ref_t[0]] wmsg = "%d temperatures should have been supplied for ref_t. "\ "Using %g K for all of them." % (n_tc_groups, ref_t[0]) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) mdp_parameters['tc-grps'] = tc_group_names mdp_parameters['tau_t'] = tau_t mdp_parameters['ref_t'] = ref_t mdp_parameters['gen-temp'] = mdp_parameters.pop('gen_temp', ref_t[0]) index = realpath(mainindex) if mdp_parameters.get('Tcoupl','').lower() == 'no': logger.info("Tcoupl == no: disabling all temperature coupling mdp options") mdp_parameters['tc-grps'] = "" mdp_parameters['tau_t'] = "" mdp_parameters['ref_t'] = "" mdp_parameters['gen-temp'] = "" if mdp_parameters.get('Pcoupl','').lower() == 'no': logger.info("Pcoupl == no: disabling all pressure coupling mdp options") mdp_parameters['tau_p'] = "" mdp_parameters['ref_p'] = "" mdp_parameters['compressibility'] = "" # do multiple concurrent simulations - ensemble sampling if multi > 1: for i in range(multi): new_mdp = deffnm + str(i) + ".mdp" mdout = deffnm + "out" + str(i) + ".mdp" pp = "processed" + str(i) + ".top" tpr = deffnm + str(i) + ".tpr" # doing ensemble sampling, so give differnt seeds for each one # if we are using 32 bit gromacs, make seeds are are 32 bit even on # 64 bit machine mdp_parameters["andersen_seed"] = random.randint(0,2**31) mdp_parameters["gen_seed"] = random.randint(0,2**31) mdp_parameters["ld_seed"] = random.randint(0,2**31) unprocessed = gromacs.cbook.edit_mdp(mdp_template, new_mdp=new_mdp, **mdp_parameters) check_mdpargs(unprocessed) gromacs.grompp(f=new_mdp, p=topology, c=structure, n=index, o=tpr, po=mdout, pp=pp, **unprocessed) # only add multi to result if we really are doing multiple runs result["multi"] = multi else: new_mdp = deffnm + '.mdp' tpr = deffnm + '.tpr' unprocessed = gromacs.cbook.edit_mdp(mdp_template, new_mdp=new_mdp, **mdp_parameters) check_mdpargs(unprocessed) gromacs.grompp(f=new_mdp, p=topology, c=structure, n=index, o=tpr, po="mdout.mdp", pp="processed.top", **unprocessed) # generate scripts for queing system if requested if qname is not None: runscripts = gromacs.qsub.generate_submit_scripts( qscript_template, deffnm=deffnm, jobname=qname, budget=budget, startdir=startdir, mdrun_opts=mdrun_opts, walltime=walltime) result["qscript"] =runscripts logger.info("[%(dirname)s] All files set up for a run time of %(runtime)g ps " "(dt=%(dt)g, nsteps=%(nsteps)g)" % vars()) result.update(mdp_kwargs) # return extra mdp args so that one can use them for prod run result.pop('define', None) # but make sure that -DPOSRES does not stay... return result
def _setup_MD( dirname, deffnm="md", mdp=config.templates["md_OPLSAA.mdp"], struct=None, top="top/system.top", ndx=None, mainselection='"Protein"', qscript=config.qscript_template, qname=None, startdir=None, mdrun_opts="", budget=None, walltime=1 / 3.0, dt=0.002, runtime=1e3, **mdp_kwargs ): """Generic function to set up a ``mdrun`` MD simulation. See the user functions for usage. """ if struct is None: raise ValueError("struct must be set to a input structure") structure = realpath(struct) topology = realpath(top) try: index = realpath(ndx) except AttributeError: # (that's what realpath(None) throws...) index = None # None is handled fine below qname = mdp_kwargs.pop("sgename", qname) # compatibility for old scripts qscript = mdp_kwargs.pop("sge", qscript) # compatibility for old scripts qscript_template = config.get_template(qscript) mdp_template = config.get_template(mdp) nsteps = int(float(runtime) / float(dt)) mdp = deffnm + ".mdp" tpr = deffnm + ".tpr" mainindex = deffnm + ".ndx" final_structure = deffnm + ".gro" # guess... really depends on templates,could also be DEFFNM.pdb # write the processed topology to the default output mdp_parameters = {"nsteps": nsteps, "dt": dt, "pp": "processed.top"} mdp_parameters.update(mdp_kwargs) add_mdp_includes(topology, mdp_parameters) logger.info("[%(dirname)s] input mdp = %(mdp_template)r", vars()) with in_dir(dirname): if not (mdp_parameters.get("Tcoupl", "").lower() == "no" or mainselection is None): logger.info("[%(dirname)s] Automatic adjustment of T-coupling groups" % vars()) # make index file in almost all cases; with mainselection == None the user # takes FULL control and also has to provide the template or index groups = make_main_index(structure, selection=mainselection, oldndx=index, ndx=mainindex) natoms = dict([(g["name"], float(g["natoms"])) for g in groups]) tc_group_names = ("__main__", "__environment__") # defined in make_main_index() try: x = natoms["__main__"] / natoms["__environment__"] except KeyError: x = 0 # force using SYSTEM in code below wmsg = ( "Missing __main__ and/or __environment__ index group.\n" "This probably means that you have an atypical system. You can " "set mainselection=None and provide your own mdp and index files " "in order to set up temperature coupling.\n" "If no T-coupling is required then set Tcoupl='no'.\n" "For now we will just couple everything to 'System'." ) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if x < 0.1: # couple everything together tau_t = firstof(mdp_parameters.pop("tau_t", 0.1)) ref_t = firstof(mdp_parameters.pop("ref_t", 300)) # combine all in one T-coupling group mdp_parameters["tc-grps"] = "System" mdp_parameters["tau_t"] = tau_t # this overrides the commandline! mdp_parameters["ref_t"] = ref_t # this overrides the commandline! mdp_parameters["gen-temp"] = mdp_parameters.pop("gen_temp", ref_t) wmsg = ( "Size of __main__ is only %.1f%% of __environment__ so " "we use 'System' for T-coupling and ref_t = %g K and " "tau_t = %g 1/ps (can be changed in mdp_parameters).\n" % (x * 100, ref_t, tau_t) ) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) else: # couple protein and bath separately n_tc_groups = len(tc_group_names) tau_t = asiterable(mdp_parameters.pop("tau_t", 0.1)) ref_t = asiterable(mdp_parameters.pop("ref_t", 300)) if len(tau_t) != n_tc_groups: tau_t = n_tc_groups * [tau_t[0]] wmsg = ( "%d coupling constants should have been supplied for tau_t. " "Using %f 1/ps for all of them." % (n_tc_groups, tau_t[0]) ) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if len(ref_t) != n_tc_groups: ref_t = n_tc_groups * [ref_t[0]] wmsg = "%d temperatures should have been supplied for ref_t. " "Using %g K for all of them." % ( n_tc_groups, ref_t[0], ) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) mdp_parameters["tc-grps"] = tc_group_names mdp_parameters["tau_t"] = tau_t mdp_parameters["ref_t"] = ref_t mdp_parameters["gen-temp"] = mdp_parameters.pop("gen_temp", ref_t[0]) index = realpath(mainindex) if mdp_parameters.get("Tcoupl", "").lower() == "no": logger.info("Tcoupl == no: disabling all temperature coupling mdp options") mdp_parameters["tc-grps"] = "" mdp_parameters["tau_t"] = "" mdp_parameters["ref_t"] = "" mdp_parameters["gen-temp"] = "" if mdp_parameters.get("Pcoupl", "").lower() == "no": logger.info("Pcoupl == no: disabling all pressure coupling mdp options") mdp_parameters["tau_p"] = "" mdp_parameters["ref_p"] = "" mdp_parameters["compressibility"] = "" unprocessed = gromacs.cbook.edit_mdp(mdp_template, new_mdp=mdp, **mdp_parameters) check_mdpargs(unprocessed) gromacs.grompp(f=mdp, p=topology, c=structure, n=index, o=tpr, **unprocessed) runscripts = gromacs.qsub.generate_submit_scripts( qscript_template, deffnm=deffnm, jobname=qname, budget=budget, startdir=startdir, mdrun_opts=mdrun_opts, walltime=walltime, ) logger.info("[%(dirname)s] output mdp = %(mdp)r", vars()) logger.info("[%(dirname)s] output ndx = %(ndx)r", vars()) logger.info("[%(dirname)s] output tpr = %(tpr)r", vars()) logger.info("[%(dirname)s] output runscripts = %(runscripts)r", vars()) logger.info( "[%(dirname)s] All files set up for a run time of %(runtime)g ps " "(dt=%(dt)g, nsteps=%(nsteps)g)" % vars() ) kwargs = { "struct": realpath(os.path.join(dirname, final_structure)), # guess "top": topology, "ndx": index, # possibly mainindex "qscript": runscripts, "mainselection": mainselection, "deffnm": deffnm, # return deffnm (tpr = deffnm.tpr!) } kwargs.update(mdp_kwargs) # return extra mdp args so that one can use them for prod run return kwargs
def test_ensemble_potential_withmpi(): import gmx import os import shutil import myplugin from mpi4py import MPI rank = MPI.COMM_WORLD.Get_rank() tests_dir = os.path.dirname(__file__) water = os.path.join(tests_dir, 'data', 'water.gro') rank_dir = os.path.join(os.getcwd(), str(rank)) os.mkdir(rank_dir) shutil.copy(water, rank_dir) # In MPI, this never makes it to grompp. We should get rid of this... try: # use GromacsWrapper if available import gromacs import gromacs.formats from gromacs.tools import Solvate as solvate solvate(o=os.path.join(rank_dir, 'water.gro'), box=[5, 5, 5]) mdpparams = [('integrator', 'md'), ('nsteps', 1000), ('nstxout', 100), ('nstvout', 100), ('nstfout', 100), ('tcoupl', 'v-rescale'), ('tc-grps', 'System'), ('tau-t', 1), ('ref-t', 298)] mdp = gromacs.formats.MDP() for param, value in mdpparams: mdp[param] = value mdp.write(os.path.join(rank_dir, 'water.mdp')) with open(os.path.join(rank_dir, 'input.top'), 'w') as fh: fh.write("""#include "gromos43a1.ff/forcefield.itp" #include "gromos43a1.ff/spc.itp" [ system ] ; Name spc [ molecules ] ; Compound #mols SOL 4055 """) gromacs.grompp(f=os.path.join(rank_dir, 'water.mdp'), c=os.path.join(rank_dir, 'water.gro'), po=os.path.join(rank_dir, 'water.mdp'), pp=os.path.join(rank_dir, 'water.top'), o=os.path.join(rank_dir, 'water.tpr'), p=os.path.join(rank_dir, 'input.top')) tpr_filename = os.path.join(rank_dir, 'water.tpr') except: from gmx.data import tpr_filename logger.info("Testing plugin potential with input file {}".format( os.path.abspath(tpr_filename))) assert gmx.version.api_is_at_least(0, 0, 5) md = gmx.workflow.from_tpr([tpr_filename, tpr_filename], append_output=False) # Create a WorkElement for the potential #potential = gmx.core.TestModule() params = { 'sites': [1, 4], 'nbins': 10, 'binWidth': 0.1, 'min_dist': 0., 'max_dist': 10., 'experimental': [0.5] * 10, 'nsamples': 1, 'sample_period': 0.001, 'nwindows': 4, 'k': 10000., 'sigma': 1. } potential = gmx.workflow.WorkElement(namespace="myplugin", operation="ensemble_restraint", params=params) # Note that we could flexibly capture accessor methods as workflow elements, too. Maybe we can # hide the extra Python bindings by letting myplugin.HarmonicRestraint automatically convert # to a WorkElement when add_dependency is called on it. potential.name = "ensemble_restraint" before = md.workspec.elements[md.name] md.add_dependency(potential) context = gmx.context.ParallelArrayContext(md) with context as session: session.run()
#print(np.asarray(substract).shape) ID = substract.index(min(substract)) index.append(ID) dist.append(data[ID]) print(index) print(dist) # Generate the frames for umbrella sampling u = mda.Universe(sys.argv[2], sys.argv[3]) for ts in u.trajectory[np.array(index)[:]]: print("Frame: {0:7d}, timestep: {1:12.4f}".format(ts.frame, ts.time)) groname = "conf" + str(ts.frame) + ".gro" u.atoms.write(groname) # creating the dictionary for pairing the elements in index list and other in distance list as key:value dic = dict(zip(index, dist)) for i, key in enumerate(list(dic.keys())): if i == 2: break print(i, key, dic[key]) shutil.copy(sys.argv[5], "umbrella_cp.mdp") with fileinput.FileInput("umbrella_cp.mdp", inplace=True, backup='.bak') as file: for line in file: print(line.replace("CHANGE", str(dic[key] / 10)), end='') gromacs.grompp(f="umbrella_cp.mdp", c="conf" + str(key) + ".gro", p="topols.top", n="index.ndx", o="umbrella" + str(key) + ".tpr")
def run_minim_complex(self,run_minim=False): """ Function to run a local minimization on the side chain that was mutated Arguments: run_minim -- boolean flag that will control if the minimization is run or not Output: complex.pdb -- new complex pdb with the minimization and the new itp files """ # Get the chain with the peptide to generate a novel itp file os.system("python3 {}/src/scores/get_chains.py {}/complex.pdb {}".format(self.path_scores,self.path,self.path)) rc,sout,serr=gromacs.pdb2gmx(f=self.path+"/complex_"+self.pep_chain+".pdb", p=self.path+"/binder.top", o=self.path+"/complex_"+self.pep_chain+".gro", stdout=False, input=('6','6')) os.system("sed -i '/forcefield/d' {}/binder.top".format(self.path)) os.system("sed -i '/\[ system \]/,$d' {}/binder.top".format(self.path)) os.system("mv {}/binder.top {}/complex_Protein_chain_{}.itp".format(self.path,self.path,self.pep_chain)) rc,sout,serr=gromacs.editconf(f=self.path+"/complex_"+self.pep_chain+".gro", o=self.path+"/complex_"+self.pep_chain+".pdb", stdout=False) # Fix the amino acid nomenclature os.system("for i in ASP ARG HIS HIE HID HIP LYS GLU SER THR ASN GLN CYS CYX GLY PRO ALA VAL ILE LEU MET PHE TYR TRP; do sed -i s/\"$i \"/\"$i {}\"/g {}/complex_{}.pdb; done".format(self.pep_chain,self.path,self.pep_chain)) for i,ch in enumerate(self.chain_join): if i==0: os.system("grep ATOM {}/complex_{}.pdb > {}/complex.pdb".format(self.path,ch,self.path)) os.system("echo 'TER' >> {}/complex.pdb".format(self.path)) else: os.system("grep ATOM {}/complex_{}.pdb >> {}/complex.pdb".format(self.path,ch,self.path)) os.system("echo 'TER' >> {}/complex.pdb".format(self.path)) # Get the new complex.pdb and the peptide chain itp file and delete temporal files os.system("grep ATOM {}/complex_{}.pdb >> {}/complex.pdb".format(self.path,self.pep_chain,self.path)) os.system("echo 'TER' >> {}/complex.pdb".format(self.path)) os.system("rm {}/complex_*.pdb".format(self.path)) os.system("rm {}/complex_*.gro".format(self.path)) os.system("rm {}/chains.seq".format(self.path)) os.system("head -n -18 {}/complex_Protein_chain_{}.itp > {}/temp; mv {}/temp {}/complex_Protein_chain_{}.itp".format(self.path,self.pep_chain,self.path,self.path,self.path,self.pep_chain)) # Copy the topol files of the target chains, which are the same always # Copy the topol files of the target chains, which are the same always if self.target=="protein": for ch in self.chain_join: os.system("cp {}/topol_Protein_chain_{}.itp {}/complex_Protein_chain_{}.itp".format(self.path,ch,self.path,ch)) if self.target=="drug": for ch in self.chain_join: os.system("cp {}/topol_Drug_chain_{}.itp {}/complex_Drug_chain_{}.itp".format(self.path,ch,self.path,ch)) # Copy the topol.top to complex.top and delete all the additional atoms os.system("cp {}/topol.top {}/complex.top".format(self.path,self.path)) os.system("sed -i '/Ion/d' {}/complex.top".format(self.path)) os.system("sed -i '/SOL/d' {}/complex.top".format(self.path)) os.system("sed -i '/NA/d' {}/complex.top".format(self.path)) os.system("sed -i '/CL/d' {}/complex.top".format(self.path)) os.system("sed -i '/solvent/d' {}/complex.top".format(self.path)) os.system("sed -i 's/topol_/complex_/g' {}/complex.top".format(self.path)) # Get a pdb of the complex where an index will be created rc,sout,serr=gromacs.make_ndx(f=self.path+"/complex.pdb", o=self.path+"/reference.ndx", stdout=False, input=('q')) ref_ndx = NDX() ref_ndx.read(self.path+"/reference.ndx") #index_ref=len(ref_ndx)-1 bash="grep '\[' {}/reference.ndx | wc -l".format(self.path) number_index = subprocess.check_output(['bash','-c', bash]) index_ref=int(number_index)-1 gromacs.utilities.unlink_gmx(self.path+"/reference.ndx") # Create the side chain index input_for_ndx=() counter=index_ref input_for_ndx+=('chain {}'.format(self.pep_chain),); counter+=1 input_for_ndx+=('name {} binder'.format(counter),); input_for_ndx+=('"SideChain" & "binder"'+' & r {}'.format(self.pep_position),); counter+=1 input_for_ndx+=('"System" &! {}'.format(counter),); counter+=1 input_for_ndx+=('name {} scmut'.format(counter),); sentence="" for i,ch in enumerate(self.chain_join): if i==0: sentence=sentence+"chain {}".format(ch) else: sentence=sentence+" | chain {}".format(ch) input_for_ndx+=(sentence,); counter+=1 input_for_ndx+=('name {} target'.format(counter),) input_for_ndx+=('\"target\" | \"binder\"',); counter+=1 input_for_ndx+=('name {} complex'.format(counter),) input_for_ndx+=('q',) # Generate the index file rc,sout,serr=gromacs.make_ndx(f=self.path+"/complex.pdb", o=self.path+"/scmut.ndx", stdout=False, input=input_for_ndx) # Generate the gro file rc,sout,serr=gromacs.editconf(f=self.path+"/complex.pdb", o=self.path+"/complex.gro", stdout=False) # Add a small box for the residues os.system("sed -i '$ d' {}/complex.gro".format(self.path)) os.system('echo " 20.0 20.0 20.0" >> {path}/complex.gro'.format(path=self.path)) # Prepare the files for the minimization rc,sout,serr=gromacs.grompp(f=self.path+"/mdp/minim_scmut.mdp", o=self.path+"/complex.tpr", p=self.path+"/complex.top", n=self.path+"/scmut.ndx", c=self.path+"/complex.gro", stdout=False) gromacs.utilities.unlink_gmx("mdout.mdp") # Run the minimization of the side chain alone and the residues around it if run_minim: # Run the minimization print("Running first minimization ...") rc,sout,serr=gromacs.mdrun(deffnm=self.path+"/complex", stdout=False) # Get the complex pdb file rc,sout,serr=gromacs.trjconv(f=self.path+"/complex.gro",s=self.path+"/complex.tpr", n=self.path+"/scmut.ndx", o=self.path+"/min_complex.pdb",stdout=False,input=("complex")) os.system("rm posre.itp {path}/complex.tpr {path}/complex.top; grep -v ENDMDL {path}/min_complex.pdb | grep -v MODEL > {path}/complex.pdb; rm {path}/min_complex.pdb {path}/complex.log {path}/complex.trr {path}/complex.edr {path}/scmut.ndx".format(path=self.path))
def _setup_MD(dirname, deffnm='md', mdp=config.templates['md_OPLSAA.mdp'], struct=None, top='top/system.top', ndx=None, mainselection='"Protein"', qscript=config.qscript_template, qname=None, startdir=None, mdrun_opts="", budget=None, walltime=1 / 3., dt=0.002, runtime=1e3, **mdp_kwargs): """Generic function to set up a ``mdrun`` MD simulation. See the user functions for usage. """ if struct is None: raise ValueError('struct must be set to a input structure') structure = realpath(struct) topology = realpath(top) try: index = realpath(ndx) except AttributeError: # (that's what realpath(None) throws...) index = None # None is handled fine below qname = mdp_kwargs.pop('sgename', qname) # compatibility for old scripts qscript = mdp_kwargs.pop('sge', qscript) # compatibility for old scripts qscript_template = config.get_template(qscript) mdp_template = config.get_template(mdp) nsteps = int(float(runtime) / float(dt)) mdp = deffnm + '.mdp' tpr = deffnm + '.tpr' mainindex = deffnm + '.ndx' final_structure = deffnm + '.gro' # guess... really depends on templates,could also be DEFFNM.pdb # write the processed topology to the default output mdp_parameters = {'nsteps': nsteps, 'dt': dt, 'pp': 'processed.top'} mdp_parameters.update(mdp_kwargs) cbook.add_mdp_includes(topology, mdp_parameters) logger.info("[%(dirname)s] input mdp = %(mdp_template)r", vars()) with in_dir(dirname): if not (mdp_parameters.get('Tcoupl', '').lower() == 'no' or mainselection is None): logger.info( "[{dirname!s}] Automatic adjustment of T-coupling groups". format(**vars())) # make index file in almost all cases; with mainselection == None the user # takes FULL control and also has to provide the template or index groups = make_main_index(structure, selection=mainselection, oldndx=index, ndx=mainindex) natoms = {g['name']: float(g['natoms']) for g in groups} tc_group_names = ('__main__', '__environment__' ) # defined in make_main_index() try: x = natoms['__main__'] / natoms['__environment__'] except KeyError: x = 0 # force using SYSTEM in code below wmsg = "Missing __main__ and/or __environment__ index group.\n" \ "This probably means that you have an atypical system. You can " \ "set mainselection=None and provide your own mdp and index files " \ "in order to set up temperature coupling.\n" \ "If no T-coupling is required then set Tcoupl='no'.\n" \ "For now we will just couple everything to 'System'." logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if x < 0.1: # couple everything together tau_t = firstof(mdp_parameters.pop('tau_t', 0.1)) ref_t = firstof(mdp_parameters.pop('ref_t', 300)) # combine all in one T-coupling group mdp_parameters['tc-grps'] = 'System' mdp_parameters[ 'tau_t'] = tau_t # this overrides the commandline! mdp_parameters[ 'ref_t'] = ref_t # this overrides the commandline! mdp_parameters['gen-temp'] = mdp_parameters.pop( 'gen_temp', ref_t) wmsg = "Size of __main__ is only %.1f%% of __environment__ so " \ "we use 'System' for T-coupling and ref_t = %g K and " \ "tau_t = %g 1/ps (can be changed in mdp_parameters).\n" \ % (x * 100, ref_t, tau_t) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) else: # couple protein and bath separately n_tc_groups = len(tc_group_names) tau_t = asiterable(mdp_parameters.pop('tau_t', 0.1)) ref_t = asiterable(mdp_parameters.pop('ref_t', 300)) if len(tau_t) != n_tc_groups: tau_t = n_tc_groups * [tau_t[0]] wmsg = "%d coupling constants should have been supplied for tau_t. "\ "Using %f 1/ps for all of them." % (n_tc_groups, tau_t[0]) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) if len(ref_t) != n_tc_groups: ref_t = n_tc_groups * [ref_t[0]] wmsg = "%d temperatures should have been supplied for ref_t. "\ "Using %g K for all of them." % (n_tc_groups, ref_t[0]) logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) mdp_parameters['tc-grps'] = tc_group_names mdp_parameters['tau_t'] = tau_t mdp_parameters['ref_t'] = ref_t mdp_parameters['gen-temp'] = mdp_parameters.pop( 'gen_temp', ref_t[0]) index = realpath(mainindex) if mdp_parameters.get('Tcoupl', '').lower() == 'no': logger.info( "Tcoupl == no: disabling all temperature coupling mdp options") mdp_parameters['tc-grps'] = "" mdp_parameters['tau_t'] = "" mdp_parameters['ref_t'] = "" mdp_parameters['gen-temp'] = "" if mdp_parameters.get('Pcoupl', '').lower() == 'no': logger.info( "Pcoupl == no: disabling all pressure coupling mdp options") mdp_parameters['tau_p'] = "" mdp_parameters['ref_p'] = "" mdp_parameters['compressibility'] = "" unprocessed = cbook.edit_mdp(mdp_template, new_mdp=mdp, **mdp_parameters) check_mdpargs(unprocessed) gromacs.grompp(f=mdp, p=topology, c=structure, n=index, o=tpr, **unprocessed) runscripts = qsub.generate_submit_scripts(qscript_template, deffnm=deffnm, jobname=qname, budget=budget, startdir=startdir, mdrun_opts=mdrun_opts, walltime=walltime) logger.info("[%(dirname)s] output mdp = %(mdp)r", vars()) logger.info("[%(dirname)s] output ndx = %(ndx)r", vars()) logger.info("[%(dirname)s] output tpr = %(tpr)r", vars()) logger.info("[%(dirname)s] output runscripts = %(runscripts)r", vars()) logger.info( "[%(dirname)s] All files set up for a run time of %(runtime)g ps " "(dt=%(dt)g, nsteps=%(nsteps)g)" % vars()) kwargs = { 'struct': realpath(os.path.join(dirname, final_structure)), # guess 'top': topology, 'ndx': index, # possibly mainindex 'qscript': runscripts, 'mainselection': mainselection, 'deffnm': deffnm, # return deffnm (tpr = deffnm.tpr!) } kwargs.update( mdp_kwargs ) # return extra mdp args so that one can use them for prod run return kwargs