Source code for schrodinger.application.desmond.rest_inp

"""

It prepares or runs a REST MD job.

Copyright Schrodinger, LLC. All rights reserved.

"""

import os

import schrodinger.application.desmond.cmj as cmj
import schrodinger.application.desmond.cms as cms
import schrodinger.application.desmond.envir as envir
import schrodinger.application.desmond.stage as stage  # noqa: F401
import schrodinger.job.jobcontrol as jobcontrol
import schrodinger.structutils.analyze as analyze
from schrodinger.application.desmond import constants
from schrodinger.infra import mm

EXCHANGE_PROBABILITY = 0.3


[docs]def get_rest_input(model, jobname, host, **kwargs): """ Function to prepare rest input. :type structure: `Structure` or `cms.Cms` :param structure: Structure to apply rest hot region. :type jobname: str :param jobname: jobname :type hostname: str :param hostname: hostname :type kwargs: dict :param kwargs: dictionary to set options :rtype: tuple :return: A tuple composed of (structure, msj, command) """ msj_fname = jobname + ".msj" mae_fname = jobname + ".mae" if isinstance(model, cms.Cms): mae_fname = jobname + ".cms" rest = RestInput(model, **kwargs) rest_model = rest.prepare_structure() msj_string = rest.prepare_msj() cmd = rest.prepare_command(jobname, host, msj_fname, mae_fname) return (rest_model, msj_string, cmd)
[docs]def add_rest_region(model, **kwargs): """ Function to add rest region. :type structure: `Structure` or `cms.Cms` :param structure: Structure to apply rest hot region. :type kwargs: dict :param kwargs: dictionary to set options :rtype: tuple :return: A tuple composed of (structure, msj) msj only has "replica_exchange" stage """ rest = RestInput(model, **kwargs) rest_model = rest.prepare_structure() msj_string = rest.prepare_msj() all_stages = cmj.parse_msj(None, msj_content=msj_string) all_stages = [x for x in all_stages if x.NAME == "replica_exchange"] msj_string = cmj.write_msj(all_stages, to_str=True) return (rest_model, msj_string)
[docs]def get_rest_region(model): rest_asl = f"atom.{constants.REST_HOTREGION} > 0" if isinstance(model, cms.Cms): return model.select_atom(rest_asl) else: return analyze.evaluate_asl(model, rest_asl)
[docs]class RestInput:
[docs] def __init__(self, model, **kwargs): self.model = model self.asl = "all" self.ref_temperature = 300 self.ensemble = "NPT" # or NVT self.forcefield = mm.OPLS_NAME_F16 # or OPLS_2005 self.time = 5000 self.n_replica = 2 self.trajectory_interval = 24 self.np = 2 self.update(**kwargs)
# FIXME explicitly handle values!
[docs] def update(self, **kwargs): ''' updates states of options ''' self.__dict__.update(kwargs)
[docs] def prepare_structure(self): """ Set hot region """ if isinstance(self.model, cms.Cms): for a in self.model.fsys_ct.atom: try: del a.property[constants.REST_HOTREGION] except: pass for ct in self.model.comp_ct: for a in ct.atom: try: del a.property[constants.REST_HOTREGION] except: pass # setup hot region atom property for aindex in self.model.select_atom(self.asl): self.model.atom[aindex].property[constants.REST_HOTREGION] = 1 for ct_index, atom_list in enumerate( self.model.select_atom_comp(self.asl)): for aindex in atom_list: self.model.comp_ct[ct_index].atom[aindex].property[ constants.REST_HOTREGION] = 1 else: for a in self.model.atom: try: del a.property[constants.REST_HOTREGION] except: pass for a in analyze.get_atoms_from_asl(self.model, self.asl): a.property[constants.REST_HOTREGION] = 1 return self.model
[docs] def prepare_msj(self): """ Prepare multisim file """ template_fname = os.path.join(envir.CONST.MMSHARE_DATA_DESMOND_DIR, "rest_template.msj") try: fh = open(template_fname, "r") s = fh.read() fh.close() except IOError: raise RuntimeError("reading '%s' failed." % template_fname) all_stages = cmj.parse_msj(None, msj_content=s) for stg in all_stages: if stg.NAME == "assign_forcefield": stg.param.forcefield.val = self.forcefield if stg.NAME == "simulate" and self.ensemble == "NVT": stg.param.ensemble.class_.val = self.ensemble if stg.NAME == "replica_exchange": stg.param.temperature.val = self.ref_temperature stg.param.ensemble.val = self.ensemble stg.param.time.val = self.time stg.param.replica.temperature.n_replica.val = self.n_replica stg.param.replica.temperature.exchange_probability.val = EXCHANGE_PROBABILITY stg.param.trajectory.interval.val = self.trajectory_interval if (self.n_replica % self.np): raise RuntimeError( "# replica must be multiples of # of gpu: (gpu=%d, n_replia=%d)" % (self.np, self.n_replica)) stg.param.total_proc.val = self.np # cms structure does not need build_geometry stage if isinstance(self.model, cms.Cms): all_stages = [x for x in all_stages if x.NAME != "build_geometry"] s = cmj.write_msj(all_stages, to_str=True) return s
[docs] def prepare_command(self, jobname, host, msj_fname, mae_fname): """ Prepare command line """ cmd = [os.path.join('$SCHRODINGER', 'utilities', 'multisim')] cmd += [ '-m', msj_fname, '-HOST', host + ":%d" % self.np, '-JOBNAME', jobname, '-verbose', '-mode', "umbrella", ] cmd += [ mae_fname, ] return cmd
[docs] def write(self, jobname, host): ''' writes msj and mae files ''' msj_fname = jobname + ".msj" mae_fname = jobname + ".mae" st = self.prepare_structure() st.write(mae_fname) s = self.prepare_msj() cmd = self.prepare_command(jobname, host, msj_fname, mae_fname) cmd_line = ' '.join(cmd) s += '# commandline: ' + cmd_line + '\n' fh = open(msj_fname, "w") print(s, file=fh) fh.close() return cmd, s
[docs] def run(self, jobname, host): ''' Run MD REST Job ''' cmd, s = self.write(jobname, host) job = jobcontrol.launch_job(cmd) if not job: raise RuntimeError("REST MD job submission failed.") return job