Beispiel #1
0
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,
            }
Beispiel #2
0
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
Beispiel #3
0
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