def get_double_or_single_prec_mdrun(): """Return double precision ``mdrun`` or fall back to single precision. This convenience function tries :func:`gromacs.mdrun_d` first and if it cannot run it, falls back to :func:`gromacs.mdrun` (without further checking). .. versionadded:: 0.5.1 """ try: gromacs.mdrun_d(h=True, stdout=False, stderr=False) logger.debug("using double precision gromacs.mdrun_d") return gromacs.mdrun_d except (AttributeError, GromacsError, OSError): # fall back to mdrun if no double precision binary wmsg = "No 'mdrun_d' binary found so trying 'mdrun' instead.\n"\ "(Note that energy minimization runs better with mdrun_d.)" logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) return gromacs.mdrun
def energy_minimize(dirname='em', mdp=config.templates['em.mdp'], struct='solvate/ionized.pdb', 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.pdb] *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` class; by defauly we just try :func:`gromacs.mdrun_d` and :func:`gromacs.mdrun` but a MDrunner class 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 ..." % vars()) 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." % vars() logger.warn(wmsg) warnings.warn(wmsg, category=BadParameterWarning) with in_dir(dirname): unprocessed = gromacs.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: try: gromacs.mdrun_d(**mdrun_args) except (AttributeError, OSError): # fall back to mdrun if no double precision binary wmsg = "No 'mdrun_d' binary found so trying 'mdrun' instead.\n"\ "(Note that energy minimization runs better with mdrun_d.)" logger.warn(wmsg) warnings.warn(wmsg, category=AutoCorrectionWarning) gromacs.mdrun(**mdrun_args) else: # 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() # 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" % vars()) return {'struct': final_struct, 'top': topology, 'mainselection': mainselection, }