def run(in_parms): "Runs AMBER with in_parms" parms = copy.deepcopy(in_parms) name = parms['output_name'] config = name + ".config" if util.is_same_dict_in_file(in_parms, config): print "simulation already run." return input_top = parms['topology'] new_top = name + '.top' shutil.copy(input_top, new_top) input_crd = parms['input_crds'] if input_crd.endswith('.crd'): new_crd = name + '.in.crd' else: new_crd = name + '.in.rst' shutil.copy(input_crd, new_crd) if 'n_step_minimization' in parms: rst = name + ".crd" else: rst = name + ".rst" trj = name + ".trj" vel = name + ".vel" ene = name + ".ene" inf = name + ".inf" sander_out = name + ".sander.out" sander_in = name + ".sander.in" open(sander_in, "w").write(make_sander_input_file(parms)) cmd = "sander -O -i %s -o %s -p %s -c %s -r %s -x %s -v %s -e %s -inf %s" \ % (sander_in, sander_out, new_top, new_crd, rst, trj, vel, ene, inf) if parms['constraint_pdb']: cmd += " -ref %s" % parms['constraint_pdb'].replace('.pdb', '.crd') sh_script = name + '.sh' open(sh_script, "w").write(cmd) S_IRWXU = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR os.chmod(sh_script, S_IRWXU) stopwatch = util.Timer() os.system(cmd) stopwatch.stop() open(name + '.time', 'w').write(stopwatch.str()) error_log = open(sander_out, "r").readlines() is_error = False for line in error_log: if 'FATAL' in line: is_error = True break if len(error_log) <= 1: is_error = True if not is_error: util.write_dict(in_parms, config)
def pulse(in_parms, n_step_per_pulse, reset_vel_func): config = in_parms['output_name'] + ".config" if util.is_same_dict_in_file(in_parms, config): print "simulation already run." return name = in_parms['output_name'] shutil.copy(in_parms['topology'], name + '.psf') if in_parms['constraint_pdb']: shutil.copy(in_parms['constraint_pdb'], name + '.constraint') n_pulse = in_parms['n_step_dynamics'] // n_step_per_pulse n_step_list = [n_step_per_pulse for i in range(n_pulse)] n_excess_step = in_parms['n_step_dynamics'] % n_step_per_pulse if n_excess_step > 0: n_pulse += 1 n_step_list.append(n_excess_step) pulse_in_coor = util.insert_path(in_parms['input_crds'], '..') pulse_in_vel = util.insert_path(in_parms['input_vels'], '..') stopwatch = util.Timer() pulses = ["pulse%d" % i for i in range(n_pulse)] for pulse, n_step in zip(pulses, n_step_list): util.goto_dir(pulse) pulse_parms = copy.deepcopy(in_parms) pulse_parms['topology'] = util.insert_path(in_parms['topology'], '..') pulse_parms['n_step_dynamics'] = n_step if 'constraint_pdb' in pulse_parms and pulse_parms['constraint_pdb']: pulse_parms['constraint_pdb'] = util.insert_path(in_parms['constraint_pdb'], '..') pulse_parms['input_crds'] = pulse_in_coor pulse_parms['input_vels'] = pulse_in_vel soup = SoupFromRestartFiles(pulse_parms['topology'], pulse_parms['input_crds'], pulse_parms['input_vels']) reset_vel_func(soup) pulse_parms['input_vels'] = name + ".in.vel" write_soup_to_vel(soup, pulse_parms['input_vels']) run(pulse_parms) pulse_in_coor = '../%s/%s.coor' % (pulse, name) pulse_in_vel = '../%s/%s.vel' % (pulse, name) os.chdir('..') stopwatch.stop() open(name + '.time', 'w').write(stopwatch.str()) merge_simulations(name, pulses) for pulse in pulses: os.system('rm -rf %s' % pulse) util.write_dict(in_parms, config)
def run_simulation_with_parameters(parms): """ Carries out simulations based on parms """ # For housekeeping, the parms dictionary is written to a # .config file. As an Exception is thrown if simulation failed, # the existence of an equivalent .config file is an indicator # that the simulation has already successfully run. config = parms['output_basename'] + ".config" if util.is_same_dict_in_file(parms, config): print "Skipping: simulation already run." return md_module = get_md_module(parms['force_field']) md_module.run(parms) # No exceptions were thrown - write .config file. util.write_dict(config, parms)
def run(in_parms): "Read parms and creates the appropriate NAMD input files for simulation" name = in_parms['output_name'] input = name + ".in" output = name + ".out" config = name + ".config" parms = copy.deepcopy(in_parms) if util.is_same_dict_in_file(parms, config): print "simulation already run." return shutil.copy(parms['topology'], name + '.psf') if parms['constraint_pdb']: shutil.copy(parms['constraint_pdb'], name + '.constraint') if 'force_field' in parms: if parms['force_field'] == "CHARMM": parms['parameter'] = 'parms/charmm22.parameter' parms['psf_type'] = 'paraTypeCharmm on' elif parms['force_field'] == "OPLS": parms['parameter'] = 'parms/opls.parameter' parms['psf_type'] = 'paraTypeXplor on' else: raise "Can't identify force-field" parms['module_dir'] = module_dir open(input, "w").write(make_namd_input_file(parms)) stopwatch = util.Timer() os.system("namd2 %s > %s" % (input, output)) stopwatch.stop() open(name + '.time', 'w').write(stopwatch.str()) for line in open(output, "r"): if 'ERROR' in line and 'Info' not in line: raise "NAMD failure: '%s'" % line.replace("\n", "") util.write_dict(in_parms, config)
def pulse( force_field, in_basename, basename, n_step, pulse_fn, n_step_per_pulse=100, restraint_pdb="", restraint_force=None): """ Runs a pulse simulation that uses the restart-file modification strategy to manage a steered-molecular dynamics simulation. The pulsed approacha pplies external forces in pulses, which is practically carried out be running short constant-energy simulations and directly modifying the restart velocities between each simulation. Pulse simulations has certain advantages: for instance, the system can respond to the forces between pulses, and the incredibly flexibility in applying forces. The disadvantage is the costly setup which is hopefully, mitigated by this library. Reference: Bosco K. Ho and David A. Agard (2010) "An improved strategy for generating forces in steered molecular dynamics: the mechanical unfolding of titin, e2lip3 and ubiquitin" PLoS ONE 5(9):e13068. """ # Grab the simulation prameters for a constant energy # simulation. Constant energy is preferred as we want to ensure # energy changes come only from our velocity modification. top, crds, vels = get_restart_files(in_basename) # use dummy top and crds, which will be overriden overall_config_parms = fetch_simulation_parameters( force_field, top, crds, restraint_pdb, 'constant_energy', basename, restraint_force) overall_config_parms.update({ 'input_md_name': in_basename, 'input_vels': vels, 'n_step_dynamics': n_step, 'n_step_per_snapshot': n_step_per_pulse // 2, 'n_step_per_pulse': n_step_per_pulse }) # Check if the simulation has already run as the config # file is not written until the very end config = basename + ".config" if util.is_same_dict_in_file(overall_config_parms, config): print "Skipping: pulsing simulation already run." return # The overall_config_parms will be written out at the end. # We make a copy for internal use pulse_parms = copy.deepcopy(overall_config_parms) # Calculate steps for each pulse, esp for last step n_pulse = pulse_parms['n_step_dynamics'] / n_step_per_pulse n_step_list = [n_step_per_pulse for i in range(n_pulse)] n_excess_step = pulse_parms['n_step_dynamics'] % n_step_per_pulse if n_excess_step > 0: n_pulse += 1 n_step_list.append(n_excess_step) # Prepare restart files for first step pulse_parms['topology'] = os.path.abspath(pulse_parms['topology']) in_basename = pulse_parms['input_md_name'] pulse_parms['input_md_name'] = os.path.abspath(in_basename) # Now loop through pulses timer = util.Timer() save_dir = os.getcwd() pulses = ["pulse%d" % i for i in range(n_pulse)] for pulse, n_step in zip(pulses, n_step_list): print "Pulse: %s/%d" % (pulse, n_pulse) os.chdir(save_dir) util.goto_dir(pulse) pulse_parms['n_step_dynamics'] = n_step soup = soup_from_restart_files(pulse_parms['input_md_name']) # Apply forces by modifying the velocities directly pulse_fn(soup) crds, vels = write_soup_to_crds_and_vels( force_field, soup, basename + '.pulse.in') pulse_parms['input_crds'] = crds pulse_parms['input_vels'] = vels run_simulation_with_parameters(pulse_parms) # Setup new restart files based on just-finished pulse pulse_parms['input_md_name'] = os.path.abspath(basename) os.chdir(save_dir) merge_simulations(force_field, basename, pulses) # cleanup pulses after merging util.clean_fname(*pulses) # everything worked, no exceptions thrown open(basename+'.time', 'w').write(timer.str()+'\n') util.write_dict(config, overall_config_parms)