schrodinger.application.desmond.cmj module

This module provides fundamental facilities for writing a multisim driver script, for writing multisim concrete stage classes, and for dealing with protocol files.

Copyright Schrodinger, LLC. All rights reserved.

schrodinger.application.desmond.cmj.print_tonull(msg)
schrodinger.application.desmond.cmj.print_silent(msg)
schrodinger.application.desmond.cmj.print_quiet(msg)
schrodinger.application.desmond.cmj.print_verbose(msg)
schrodinger.application.desmond.cmj.print_debug(msg)
class schrodinger.application.desmond.cmj.Queue(host, max_limit=0, max_retry=0, sleep=10)

Bases: object

__init__(host, max_limit=0, max_retry=0, sleep=10)

`host’ specifies hosts and maximum numbers of jobs for each host by passing a list of (<host>, <max_jobs>) tuples.

allocate(num_cpu)
free(host, num_cpu)
reset(host, max_limit=0, max_retry=0, sleep=10)
push(job)

`job’ can be a single job object or a list of job objects. `job’s pushed into this `Queue’ object are waiting for being processed. There are two ways for a job to go: (1) it is launched to run if it has not yet run; (2) if it has finished running, it will be removed from this `Queue’ object, and `job.finish()’ will be called to terminate the job.

run()
refill_queue()
class schrodinger.application.desmond.cmj.JobStatus(code=101)

Bases: object

WAITING = 101
RUNNING = 102
SUCCESS = 103
BACKEND_ERROR = 201
PERMANENT_LICENSE_FAILURE = 202
NON_RETRIABLE_FAILURE = 299
TEMPORARY_LICENSE_FAILURE = 301
KILLED = 302
FIZZLED = 303
LAUNCH_FAILURE = 304
FILE_NOT_FOUND = 305
FILE_CORRUPT = 306
STRANDED = 307
RETRIABLE_FAILURE = 399
STRING = {101: 'is waiting for launching', 102: 'is running', 103: 'was successfully finished', 201: 'died due to backend error', 202: 'could not run due to permanent license failure', 299: 'died on unknown non-retriable failure', 301: 'died due to temporary license failure', 302: 'was killed', 303: 'fizzled', 304: 'failed to launch', 305: 'was finished, but registered output files were not found', 306: 'was finished, but an essential output file was found corrupt', 307: 'was stranded', 399: 'died on unknown retriable failure'}
__init__(code=101)
set(code, error=None)
is_good()
is_retriable()
class schrodinger.application.desmond.cmj.JobOutput

Bases: object

__init__()
__len__()

Returns the number of registered output files.

update_basedir(old_basedir, new_basedir)
add(filename, checker=None, tag=None, type='file')

`type’ can take “file” and “dir”.

remove(filename)
get(tag)
check(status)
set_struct_file(fname)
struct_file()
log_file()
class schrodinger.application.desmond.cmj.JobInput

Bases: schrodinger.application.desmond.cmj.JobOutput

__init__()
cfg_file()
incfg_file()
outcfg_file()
__len__()

Returns the number of registered output files.

add(filename, checker=None, tag=None, type='file')

`type’ can take “file” and “dir”.

check(status)
get(tag)
log_file()
remove(filename)
set_struct_file(fname)
struct_file()
update_basedir(old_basedir, new_basedir)
class schrodinger.application.desmond.cmj.RetryTimer

Bases: object

RETRY_INTERVAL_BASE = 60.0
__init__()
should_retry()
restart()
retry_interval()
num_retry()
reset()
class schrodinger.application.desmond.cmj.JobErrorHandler

Bases: object

static default(job)
static restart_for_backend_error(job)
__init__

Initialize self. See help(type(self)) for accurate signature.

class schrodinger.application.desmond.cmj.Job(jobname, parent, stage, jlaunch_cmd, dir, host_list=None, prefix=None, what=None, err_handler=<function JobErrorHandler.default>)

Bases: object

class Time(launch, start, end, num_cpu, cpu_time, duration)

Bases: object

__init__(launch, start, end, num_cpu, cpu_time, duration)
static get_time(jctrl, num_cpu)
get_proc_time()
__init__(jobname, parent, stage, jlaunch_cmd, dir, host_list=None, prefix=None, what=None, err_handler=<function JobErrorHandler.default>)
describe()
launch(host=None)

Launches the job via jobcontrol.

update()
finish()
class schrodinger.application.desmond.cmj.JobAdapter(job)

Bases: schrodinger.job.queue.BaseJob

This adapts the `Job’ class to the `que.BaseJob’ class.

__init__(job)
doCommand()
update()
finalize()
addFinalizer(function, run_dir=None)

Add a function to be invoked when the job completes successfully.

See also the add_multi_job_finalizer function.

addGroupPrereq(job)

Make all jobs connected to job prerequisites of all jobs connected to this Job.

addPrereq(job)

Add a job that is an immediate prerequisite for this one.

genAllJobs(seen=None)

A generator that yields all jobs connected to this one.

genAllPrereqs(seen=None)

A generator that yields all jobs that are prerequisites on this one.

getCommandDir()

Return the launch/command directory name. If None is returned, the job will be launched in the current directory.

getJobDJ()

Return the JobDJ instance that this job has been added to.

getPrereqs()

Return a set of all immediate prerequisites for this job.

getStatusStrings()

Return a tuple of status strings for printing by JobDJ.

The strings returned are (status, jobid, name, host).

hasStarted()

Returns True if this job has started (not waiting)

init_count = 0
isComplete()

Returns True if this job finished successfully

maxFailuresReached(msg)

This is a method that will be called after the job has failed and the maximum number of failures per JobDJ run has been reached. After invoking this method, JobDJ will raise a RuntimeError and the process will exit.

postCommand()

A method to restore things to the pre-command state.

preCommand()

A method to make pre-command changes, like cd’ing to the correct directory to run the command in.

run(*args, **kwargs)

Run the job.

The steps taken are as follows:
  1. Execute the preCommand method for things like changing the working directory.
  2. Call the doCommand to do the actual work of computation or job launching.
  3. Call the postCommand method to undo the changes from the preCommand that need to be undone.
runsLocally()

Return True if the job runs on the JobDJ control host, False if not. Jobs that run locally don’t need hosts.

There is no limit on the number of locally run jobs.

setup()

A method to do initial setup; executed after preCommand, just before doCommand.

state

Return the current state of the job.

Note that this method can be overridden by subclasses that wish to provide for restartability at a higher level than unpickling BaseJob instances. For example, by examining some external condition (e.g. presence of output files) the state DONE could be returned immediately and the job would not run.

class schrodinger.application.desmond.cmj.StageBase(should_pack=True)

Bases: schrodinger.application.desmond.picklejar.Picklable

count = 0
stage_cls = {'generic': <class 'schrodinger.application.desmond.cmj.StageBase'>}
stage_obj = {}
NAME = 'generic'
PARAM = <schrodinger.utils.sea.Map object>
__init__(should_pack=True)
describe()
check_param()
push(job)
determine()
crunch()

This is where jobs of this stage are created. This function should be overriden by the subclass.

restart_subjobs(jobs)

Subclass should override this if it supports subjob restarting.

release(is_restarting=False)

Calls the ‘crunch’ method to generate new jobs objects and submits them to the ‘QUEUE’.

capture(job)
prestage()
poststage()
hook_captured_successful_job(job)
time_stage()
pack_stage(force=False)
class schrodinger.application.desmond.cmj.Engine(opt=None)

Bases: object

JOBBE = None
__init__(opt=None)
restore_stages(print_func=<function print_quiet>)
reset(opt)

Resets this engine with the command options.

boot()
handle_jobcontrol_message()
cleanup(exit_code=0)
serialize(fh)

`fh’ is a file handler.

static deserialize(fh)

`fh’ is a file handler.

write_checkpoint(fname=None, num_retry=10)
exception schrodinger.application.desmond.cmj.StopRequest(*arg, **kwarg)

Bases: Exception

__init__(*arg, **kwarg)
args
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

exception schrodinger.application.desmond.cmj.ParseError(*arg, **kwarg)

Bases: Exception

__init__(*arg, **kwarg)
args
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

schrodinger.application.desmond.cmj.is_restartable_version(version_string)
schrodinger.application.desmond.cmj.is_restartable_build(engine)
schrodinger.application.desmond.cmj.build_stages(stage_list, out_fname=None, stage_state=[])
schrodinger.application.desmond.cmj.probe_checkpoint(fname, indent='')
schrodinger.application.desmond.cmj.escape_string(s)
schrodinger.application.desmond.cmj.append_stage(cmj_fname, stage_type, cfg_file=None, jobname=None, dir=None, compress=None, parameter={})
schrodinger.application.desmond.cmj.concatenate_relaxation_stages(raw)

Attempts to concatenate relaxation stages by finding all adjacent non-production simulate stages. If no concatenatable stages are found, None is returned. Otherwise, a new raw map with the relaxation simulate stages replaced with a single concatenate stage is returned.

Parameters:raw (sea.Map) – the raw map representing the MSJ
Returns:a new raw map representing the updated msj, or None.
Return type:sea.Map
schrodinger.application.desmond.cmj.get_concat_stages(stages, param_attr='')

Get a list of the stages that can be concatenated together, and the insertion point of the resulting concatenate stage. Stages can be concatenated if they are adjacent simulate stages with the same restraints, excluding the final production stage, which can be lambda hopping, replica exchange, or otherwise the last simulate stage.

Parameters:
  • stages (list of (sea.Map or stage.Stage)) – A list of objects representing multisim stages. For flexibility, these can be either maps or stages. For stages, a param attribute must be passed that will give the location of the param on the stage.
  • param_attr (str) – optional name of the attribute of the objects param, in case of a stage.Stage object.
schrodinger.application.desmond.cmj.restraints_incompatible(param, initial_restrain, has_permanent_restrain)

Returns whether the restrain parameters are compatible with switching during a concatenate stage. For compatibility, restrain has to differ from initial_restrain by only a scaling factor (which can include zero). Furthermore, there can be no differences between restrain and initial_restrain if permanent_restrain is not None, as there is no way to selectively scale restraints.

Parameters:
  • param (sea.Map) – the param for a given stage
  • initial_restrain (sea.Map) – the restraints for the first stage
  • has_permanent_restrain – whether or not there are restraints applied

to all stages via the permanent_restraints mechanism :type has_permanent_restrain: bool

Returns:a message declaring how the restraints are incompatible, or

an empty string if they are compatible :type: str

schrodinger.application.desmond.cmj.check_restrain_diffs(restrain, initial_restrain)

See if the differences between two restrain blocks are concatenation-compatible, meaning they are both sea.Map objects and differ only by a force constant.

Parameters:
  • restrain (sea.Map) – the restrain block for a given stage
  • initial_restrain (sea.Map) – the restraints for the first stage
Returns:

a message declaring how the restraints are incompatible, or

an empty string if they are compatible :type: str

schrodinger.application.desmond.cmj.msj2sea(fname, msj_content=None)

Parses a file as specified by ‘fname’ or a string given by ‘msj_content’ (if both are given, the former will be ignored), and returns a ‘sea.Map’ object that represents the stage settings with a structure like the following:

stage = [
{ <stage 1 settings> } { <stage 2 settings> } { <stage 3 settings> } …

]

Each stage’s name can be accessed in this way: raw.stage[1].__NAME__, where ‘raw’ is the returned ‘sea.Map’ object.

schrodinger.application.desmond.cmj.msj2sea_full(fname, msj_content=None, pset='')
schrodinger.application.desmond.cmj.parse_msj(fname, msj_content=None, pset='')

`sea.macro_dict’ must be set properly before calling this function.

schrodinger.application.desmond.cmj.write_msj(stage_list, fname=None, to_str=True)

Given a list of stages, writes out a .msj file of the name `fname’. If ‘to_str’ is True, a string will be returned. The returned string contains the contents of the .msj file. If ‘to_str’ is False and not file name is provided, then this function does nothing.

schrodinger.application.desmond.cmj.write_sea2msj(stage_list, fname=None, to_str=True)
schrodinger.application.desmond.cmj.collect_inputfile(stage_list)

Returns a list of file names.

class schrodinger.application.desmond.cmj.AslValidator

Bases: object

CTSTR = 'hydrogen\n\n\n 1 0 0 0 1 0 999 V2000\n -1.6976 2.1561 0.0000 C 0 0 0 0 0 0\nM END\n$$$$\n'
CT = None
__init__()

Initialize self. See help(type(self)) for accurate signature.

is_valid(asl)
validate(a)
schrodinger.application.desmond.cmj.validate_asl_expr(stage_list)

Validates all ASL expressions that start with the “asl:” prefix.

schrodinger.application.desmond.cmj.reg_checking(name, func)