def pull(self): self.nsteps += 1. yaml_builder = ExperimentBuilder(self.contents.format('yes',self.init_steps+self.nsteps*self.pull_steps)) yaml_builder.run_experiments() exp_analyzer = ExperimentAnalyzer(str(self.name)+'/experiments') analysis_data = exp_analyzer.auto_analyze() # the following is the free_energy_diff of the WHOLE simulation, need the average of the last pull_steps self.x_n = analysis_data['free_energy']['free_energy_diff'] return
def __init__(self,name,fe,error,index,simulation,color=np.random.rand(3),init_steps=2000,pull_steps=1000): super().__init__(name,fe,error,index,color) self.contents = simulation.format(self.name,'resume_simulation: {}',self.index,'{}') self.init_steps = init_steps self.pull_steps = pull_steps yaml_builder = ExperimentBuilder(self.contents.format('no',self.init_steps)) yaml_builder.run_experiments() exp_analyzer = ExperimentAnalyzer(str(self.name)+'/experiments') analysis_data = exp_analyzer.auto_analyze() self.nu_0 = analysis_data['free_energy']['free_energy_diff']
def _run_yank(directory, available_resources, setup_only): """Runs YANK within the specified directory which contains a `yank.yaml` input file. Parameters ---------- directory: str The directory within which to run yank. available_resources: ComputeResources The compute resources available to yank. setup_only: bool If true, YANK will only create and validate the setup files, but not actually run any simulations. This argument is mainly only to be used for testing purposes. Returns ------- simtk.pint.Quantity The free energy returned by yank. simtk.pint.Quantity The uncertainty in the free energy returned by yank. """ from yank.experiment import ExperimentBuilder from yank.analyze import ExperimentAnalyzer from simtk import unit as simtk_unit with temporarily_change_directory(directory): # Set the default properties on the desired platform # before calling into yank. setup_platform_with_resources(available_resources) exp_builder = ExperimentBuilder("yank.yaml") if setup_only is True: return ( 0.0 * simtk_unit.kilojoule_per_mole, 0.0 * simtk_unit.kilojoule_per_mole, ) exp_builder.run_experiments() analyzer = ExperimentAnalyzer("experiments") output = analyzer.auto_analyze() free_energy = output["free_energy"]["free_energy_diff_unit"] free_energy_uncertainty = output["free_energy"][ "free_energy_diff_error_unit"] return free_energy, free_energy_uncertainty
def __init__(self, platform_name=None, precision=None, max_n_contexts=None): """ Parameters ---------- platform_name : str, optional, default=None Name of platform, or 'fastest' if fastest platform should be automatically selected precision : str, optional, default='auto' Precision to use, or None to automatically select ('mixed' is used if supported) max_n_contexts : int, optional, default=None Maximum number of contexts to use """ # Configure ContextCache, platform and precision from yank.experiment import ExperimentBuilder self.platform = ExperimentBuilder._configure_platform( platform_name, precision) try: openmmtools.cache.global_context_cache.platform = self.platform except RuntimeError: # The cache has been already used. Empty it before switching platform. openmmtools.cache.global_context_cache.empty() openmmtools.cache.global_context_cache.platform = self.platform if max_n_contexts is not None: openmmtools.cache.global_context_cache.capacity = self.max_n_contexts
def test_yaml_syntax(path): """ Test syntax only. If successful, `ExperimentBuilder` will be able to initialize safely. """ path = EXAMPLES / path with omt.utils.temporary_cd(str(path.parent)): builder = ExperimentBuilder(script=str(path))
def run(self, platform_name=None, precision='auto', max_n_contexts=None, resume=False): """ Run the sampler for a specified number of iterations Parameters ---------- platform_name : str, optional, default=None Name of platform, or 'fastest' if fastest platform should be automatically selected precision : str, optional, default='auto' Precision to use, or None to automatically select ('mixed' is used if supported) max_n_contexts : int, optional, default=None Maximum number of contexts to use resume : bool, default=False If True, resume the simulation """ # Configure ContextCache, platform and precision from yank.experiment import ExperimentBuilder platform = ExperimentBuilder._configure_platform( platform_name, precision) try: openmmtools.cache.global_context_cache.platform = platform except RuntimeError: # The cache has been already used. Empty it before switching platform. openmmtools.cache.global_context_cache.empty() openmmtools.cache.global_context_cache.platform = platform if max_n_contexts is not None: openmmtools.cache.global_context_cache.capacity = max_n_contexts if resume: # Resume the simulation print('Storage {} exists; resuming...'.format( self.output_filename)) from yank.multistate import SAMSSampler, MultiStateReporter sampler = SAMSSampler.from_storage(self.output_filename) # Run the remainder of the simulation if sampler._iteration < self.n_iterations: # Resume sampler.run() else: # Extend sampler.extend(n_iterations=self.n_iterations) else: # Set up the simulation if it has not yet been set up if not self._setup_complete: self._setup() # Run the simulation self.simulation.run()
def test_yaml_syntax_cuda(path): """ Same as test_yaml_syntax, but removing `platform: CUDA` to avoid errors unrelated to syntax if the test machine does not have CUDA enabled """ path = EXAMPLES / path with omt.utils.temporary_cd(str(path.parent)): with open(str(path)) as f: data = yaml.load(f, Loader=YankLoader) del data['options']['platform'] builder = ExperimentBuilder(script=data)
def run_automatic_pipeline(yaml_file_path, complex_name, solvent_name): """Run YANK's automatic pipeline.""" from yank.experiment import ExperimentBuilder exp_builder = ExperimentBuilder(yaml_file_path) # Modify the output directory of the setup to be consistent # with the hardcoded paths in Fluorify and FSim. The searched # path is 'input/complex_name/complex_name.pdb' so we also # need to modify the name of the system. exp_builder.output_dir = '.' exp_builder.setup_dir = 'input' # Run the automatic pipeline. exp_builder.setup_experiments() assert len(exp_builder._db.systems ) == 1, 'Setting up multiple systems is not currently supported' system_name = next(iter(list(exp_builder._db.systems.keys()))) # Copy YANK setup files to match the Fluorify folder structure. for phase_name, user_phase_name in zip(['complex', 'solvent'], [complex_name, solvent_name]): # Create Fluorify directory structure. fluorify_phase_dir = os.path.join('input', user_phase_name) os.makedirs(fluorify_phase_dir, exist_ok=True) for extension in ['.prmtop', '.pdb']: yank_file_path = os.path.join(exp_builder.setup_dir, 'systems', system_name, phase_name + extension) fluorify_file_path = os.path.join(fluorify_phase_dir, user_phase_name + extension) shutil.copyfile(yank_file_path, fluorify_file_path)
def run_yank(job_id, n_jobs): # Direct path to where the input PDBs are pdb_dir = "./t3_dry_oct_pdbs" # Direct path to where the input XML system files are (will need to change according to what trial directory you're working in) openmm_system_dir = "./t3_dry_oct_XMLs" # Path to YANK template script (YAML file) yank_script_template_filepath = 'dry_yank.yaml' #don't need to change this # Read in YANK template script. with open(yank_script_template_filepath, 'r') as f: script_template = f.read() # Load cached status calculations. molecules_done = read_status() # Find all the molecules to run # Make a list of JUST the solute/octanol mixures (excludes the solute in water mixtures that are in the same pdb directory as the solute/octanol mixures) molecules_files_pattern = os.path.join(pdb_dir, '*_octanol_0.0_1.0_SMIRNOFF_tip3p_equil.pdb') molecule_ids = [os.path.basename(molecule_file)[:-4] for molecule_file in glob.glob(molecules_files_pattern)] # makes a list of just the system IDs (ie SM13_octanol_0.0_1.0_SMIRNOFF_tip3p_equil instead of SM13_octanol_0.0_1.0_SMIRNOFF_tip3p_equil.pdb) # Sort molecules so that parallel nodes won't make the same calculation. molecule_ids = sorted(molecule_ids) # Loop through the list of the phase 1 files, which are the solute/octanol mixtures # The phase 1 file name will be used to grab the corresponding phase 2 file # Create input files. for i, molecule_id in enumerate(molecule_ids): # Check if the job is assigned to this script and/or if we # have already completed this. if (i % n_jobs != job_id - 1 or molecule_id in molecules_done): print_and_flush('Node {}: Skipping {}'.format(job_id, molecule_id)) continue # specify phase one, which will be the solute in just octanol phase1_molecule_id = molecule_id # specify phase two, which will be the solute in just water phase2_molecule_id = phase1_molecule_id.replace("_octanol_0.0_1.0_SMIRNOFF_tip3p_equil", "_water_0.0_1.0_SMIRNOFF_tip3p_equil") # Specify the PDB and XML filepaths phase1_PDB_filepath = os.path.join(pdb_dir, phase1_molecule_id + '.pdb') #solute in octanol phase2_PDB_filepath = os.path.join(pdb_dir, phase2_molecule_id + '.pdb') #solute in water phase1_xml_filepath = os.path.join(openmm_system_dir, phase1_molecule_id[:-6] + '.xml') #solute in octanol/water phase2_xml_filepath = os.path.join(openmm_system_dir, phase2_molecule_id[:-6] + '.xml') #solute in water # Create yank script. phase1_path = str([phase1_xml_filepath, phase1_PDB_filepath]) phase2_path = str([phase2_xml_filepath, phase2_PDB_filepath]) # Load the PDB and XML files into yank script = script_template.format(experiment_dir=molecule_id, phase1_path=phase1_path, phase2_path=phase2_path) # Run YANK. print_and_flush('Node {}: Running {}'.format(job_id, molecule_id)) yaml_builder = ExperimentBuilder(script) yaml_builder.run_experiments() # Update completed molecules. update_status(molecule_id)
def main(): parser = argparse.ArgumentParser( description= 'Compute a potential of mean force (PMF) for porin permeation.') parser.add_argument('--index', dest='index', action='store', type=int, help='Index of ') parser.add_argument('--output', dest='output_filename', action='store', default='output.nc', help='output netcdf filename (default: output.nc)') args = parser.parse_args() index = args.index output_filename = args.output_filename logger = logging.getLogger(__name__) logging.root.setLevel(logging.DEBUG) logging.basicConfig(level=logging.DEBUG) yank.utils.config_root_logger(verbose=True, log_file_path=None) # Configure ContextCache, platform and precision from yank.experiment import ExperimentBuilder platform = ExperimentBuilder._configure_platform('CUDA', 'mixed') try: openmmtools.cache.global_context_cache.platform = platform except RuntimeError: # The cache has been already used. Empty it before switching platform. openmmtools.cache.global_context_cache.empty() openmmtools.cache.global_context_cache.platform = platform # Topology pdbx = app.PDBxFile('mem_prot_md_system.pdbx') # This system contains the CVforce with parameters different than zero with open('openmm_system.xml', 'r') as infile: openmm_system = XmlSerializer.deserialize(infile.read()) ####### Indexes of configurations in trajectory ############################ configs = [ 39, 141, 276, 406, 562, 668, 833, 1109, 1272, 1417, 1456, 1471, 1537, 1645, 1777, 1882 ] ####### Indexes of states for series of replica exchange simulations ####### limits = [(0, 9), (10, 19), (20, 29), (30, 39), (40, 49), (50, 59), (60, 69), (70, 79), (80, 89), (90, 99), (100, 109), (110, 119), (120, 129), (130, 139), (140, 149), (150, 159)] ####### Reading positions from mdtraj trajectory ########################### topology = md.Topology.from_openmm(pdbx.topology) t = md.load('../../steered_md/comp7/forward/seed_0/steered_forward.nc', top=topology) positions = t.openmm_positions(configs[index]) thermodynamic_state_deserialized = states.ThermodynamicState( system=openmm_system, temperature=310 * unit.kelvin, pressure=1.0 * unit.atmospheres) sampler_state = states.SamplerState( positions=positions, box_vectors=t.unitcell_vectors[configs[index], :, :] * unit.nanometer) logger.debug(type(sampler_state)) move = mcmc.LangevinDynamicsMove(timestep=2 * unit.femtosecond, collision_rate=1.0 / unit.picoseconds, n_steps=500, reassign_velocities=False) simulation = ReplicaExchangeSampler(mcmc_moves=move, number_of_iterations=1) analysis_particle_indices = topology.select( '(protein and mass > 3.0) or (resname MER and mass > 3.0)') reporter = MultiStateReporter( output_filename, checkpoint_interval=2000, analysis_particle_indices=analysis_particle_indices) first, last = limits[index] # Initialize compound thermodynamic states protocol = { 'lambda_restraints': [i / 159 for i in range(first, last + 1)], 'K_parallel': [ 1250 * unit.kilojoules_per_mole / unit.nanometer**2 for i in range(first, last + 1) ], 'Kmax': [ 500 * unit.kilojoules_per_mole / unit.nanometer**2 for i in range(first, last + 1) ], 'Kmin': [ 500 * unit.kilojoules_per_mole / unit.nanometer**2 for i in range(first, last + 1) ] } my_composable_state = MyComposableState.from_system(openmm_system) compound_states = states.create_thermodynamic_state_protocol( thermodynamic_state_deserialized, protocol=protocol, composable_states=[my_composable_state]) simulation.create(thermodynamic_states=compound_states, sampler_states=[sampler_state], storage=reporter) simulation.equilibrate(50, mcmc_moves=move) simulation.run() ts = simulation._thermodynamic_states[0] context, _ = openmmtools.cache.global_context_cache.get_context(ts) files_names = [ 'state_{}_{}.log'.format(index, i) for i in range(first, last + 1) ] files = [] for i, file in enumerate(files_names): files.append(open(file, 'w')) mpi.distribute(write_cv, range(simulation.n_replicas), context, simulation, files, send_results_to=None) for i in range(10000): simulation.extend(n_iterations=2) mpi.distribute(write_cv, range(simulation.n_replicas), context, simulation, files, send_results_to=None)
Kmin = GlobalParameterState.GlobalParameter( 'Kmin', standard_value=10 * unit.kilojoules_per_mole / unit.nanometer**2) yank.utils.config_root_logger(verbose=True, log_file_path=None) logger = logging.getLogger(__name__) logging.root.setLevel(logging.DEBUG) logging.basicConfig(level=logging.DEBUG) cv_logger = logging.getLogger(__name__) cv_logger.setLevel(logging.DEBUG) handler = logging.FileHandler('cv.log') cv_logger.addHandler(handler) from yank.experiment import ExperimentBuilder platform = ExperimentBuilder._configure_platform('CUDA', 'mixed') try: openmmtools.cache.global_context_cache.platform = platform except RuntimeError: openmmtools.cache.global_context_cache.empty() openmmtools.cache.global_context_cache.platform = platform # Topology pdb = app.PDBFile('../../../smd/porin-ligand.pdb') with open('../../../smd/openmm_system_alch.xml', 'r') as infile: openmm_system = XmlSerializer.deserialize(infile.read()) topology = md.Topology.from_openmm(pdb.topology) ligand_atoms = topology.select('(resname CM7)')
def process(self, solvated_system, port): try: opt = dict(self.opt) # Extract the solvated ligand and the solvated complex solvated_ligand = solvated_system[0] solvated_complex = solvated_system[1] # Update cube simulation parameters with the eventually molecule SD tags new_args = {dp.GetTag(): dp.GetValue() for dp in oechem.OEGetSDDataPairs(solvated_ligand) if dp.GetTag() in ["temperature", "pressure"]} if new_args: for k in new_args: try: new_args[k] = float(new_args[k]) except: pass self.log.info("Updating parameters for molecule: {}\n{}".format(solvated_ligand.GetTitle(), new_args)) opt.update(new_args) # Extract the MD data mdData_ligand = data_utils.MDData(solvated_ligand) solvated_ligand_structure = mdData_ligand.structure mdData_complex = data_utils.MDData(solvated_complex) solvated_complex_structure = mdData_complex.structure # Create the solvated OpenMM systems solvated_complex_omm_sys = solvated_complex_structure.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=opt['nonbondedCutoff'] * unit.angstroms, constraints=app.HBonds, removeCMMotion=False) solvated_ligand_omm_sys = solvated_ligand_structure.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=opt['nonbondedCutoff'] * unit.angstroms, constraints=app.HBonds, removeCMMotion=False) # Write out all the required files and set-run the Yank experiment with TemporaryDirectory() as output_directory: opt['Logger'].info("Output Directory {}".format(output_directory)) solvated_complex_structure_fn = os.path.join(output_directory, "complex.pdb") solvated_complex_structure.save(solvated_complex_structure_fn, overwrite=True) solvated_ligand_structure_fn = os.path.join(output_directory, "solvent.pdb") solvated_ligand_structure.save(solvated_ligand_structure_fn, overwrite=True) solvated_complex_omm_serialized = XmlSerializer.serialize(solvated_complex_omm_sys) solvated_complex_omm_serialized_fn = os.path.join(output_directory, "complex.xml") solvated_complex_f = open(solvated_complex_omm_serialized_fn, 'w') solvated_complex_f.write(solvated_complex_omm_serialized) solvated_complex_f.close() solvated_ligand_omm_serialized = XmlSerializer.serialize(solvated_ligand_omm_sys) solvated_ligand_omm_serialized_fn = os.path.join(output_directory, "solvent.xml") solvated_ligand_f = open(solvated_ligand_omm_serialized_fn, 'w') solvated_ligand_f.write(solvated_ligand_omm_serialized) solvated_ligand_f.close() # Build the Yank Experiment yaml_builder = ExperimentBuilder(yank_binding_template.format( verbose='yes' if opt['verbose'] else 'no', minimize='yes' if opt['minimize'] else 'no', output_directory=output_directory, timestep=opt['timestep'], nsteps_per_iteration=opt['nsteps_per_iteration'], number_iterations=opt['iterations'], temperature=opt['temperature'], pressure=opt['pressure'], complex_pdb_fn=solvated_complex_structure_fn, complex_xml_fn=solvated_complex_omm_serialized_fn, solvent_pdb_fn=solvated_ligand_structure_fn, solvent_xml_fn=solvated_ligand_omm_serialized_fn, restraints=opt['restraints'], ligand_resname=opt['ligand_resname'])) # Run Yank yaml_builder.run_experiments() exp_dir = os.path.join(output_directory, "experiments") DeltaG_binding, dDeltaG_binding, DeltaH, dDeltaH = yankutils.analyze_directory(exp_dir) protein, ligand, water, excipients = oeommutils.split(solvated_ligand, ligand_res_name=opt['ligand_resname']) # Add result to the extracted ligand in kcal/mol oechem.OESetSDData(ligand, 'DG_yank_binding', str(DeltaG_binding)) oechem.OESetSDData(ligand, 'dG_yank_binding', str(dDeltaG_binding)) self.success.emit(ligand) except Exception as e: # Attach an error message to the molecule that failed self.log.error(traceback.format_exc()) solvated_system[1].SetData('error', str(e)) # Return failed mol self.failure.emit(solvated_system[1]) return
def process(self, solvated_system, port): try: # The copy of the dictionary option as local variable # is necessary to avoid filename collisions due to # the parallel cube processes opt = dict(self.opt) # Split the complex in components protein, solute, water, excipients = oeommutils.split(solvated_system, ligand_res_name='LIG') # Update cube simulation parameters with the eventually molecule SD tags new_args = {dp.GetTag(): dp.GetValue() for dp in oechem.OEGetSDDataPairs(solute) if dp.GetTag() in ["temperature", "pressure"]} if new_args: for k in new_args: try: new_args[k] = float(new_args[k]) except: pass self.log.info("Updating parameters for molecule: {}\n{}".format(solute.GetTitle(), new_args)) opt.update(new_args) # Extract the MD data mdData = data_utils.MDData(solvated_system) solvated_structure = mdData.structure # Extract the ligand parmed structure solute_structure = solvated_structure.split()[0][0] solute_structure.box = None # Set the ligand title solute.SetTitle(solvated_system.GetTitle()) # Create the solvated and vacuum system solvated_omm_sys = solvated_structure.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=opt['nonbondedCutoff'] * unit.angstroms, constraints=app.HBonds, removeCMMotion=False) solute_omm_sys = solute_structure.createSystem(nonbondedMethod=app.NoCutoff, constraints=app.HBonds, removeCMMotion=False) # This is a note from: # https://github.com/MobleyLab/SMIRNOFF_paper_code/blob/e5012c8fdc4570ca0ec750f7ab81dd7102e813b9/scripts/create_input_files.py#L114 # Fix switching function. for force in solvated_omm_sys.getForces(): if isinstance(force, openmm.NonbondedForce): force.setUseSwitchingFunction(True) force.setSwitchingDistance((opt['nonbondedCutoff'] - 1.0) * unit.angstrom) # Write out all the required files and set-run the Yank experiment with TemporaryDirectory() as output_directory: opt['Logger'].info("Output Directory {}".format(output_directory)) solvated_structure_fn = os.path.join(output_directory, "solvated.pdb") solvated_structure.save(solvated_structure_fn, overwrite=True) solute_structure_fn = os.path.join(output_directory, "solute.pdb") solute_structure.save(solute_structure_fn, overwrite=True) solvated_omm_sys_serialized = XmlSerializer.serialize(solvated_omm_sys) solvated_omm_sys_serialized_fn = os.path.join(output_directory, "solvated.xml") solvated_f = open(solvated_omm_sys_serialized_fn, 'w') solvated_f.write(solvated_omm_sys_serialized) solvated_f.close() solute_omm_sys_serialized = XmlSerializer.serialize(solute_omm_sys) solute_omm_sys_serialized_fn = os.path.join(output_directory, "solute.xml") solute_f = open(solute_omm_sys_serialized_fn, 'w') solute_f.write(solute_omm_sys_serialized) solute_f.close() # Build the Yank Experiment yaml_builder = ExperimentBuilder(yank_solvation_template.format( verbose='yes' if opt['verbose'] else 'no', minimize='yes' if opt['minimize'] else 'no', output_directory=output_directory, timestep=opt['timestep'], nsteps_per_iteration=opt['nsteps_per_iteration'], number_iterations=opt['iterations'], temperature=opt['temperature'], pressure=opt['pressure'], solvated_pdb_fn=solvated_structure_fn, solvated_xml_fn=solvated_omm_sys_serialized_fn, solute_pdb_fn=solute_structure_fn, solute_xml_fn=solute_omm_sys_serialized_fn)) # Run Yank yaml_builder.run_experiments() exp_dir = os.path.join(output_directory, "experiments") # Calculate solvation free energy, solvation Enthalpy and their errors DeltaG_solvation, dDeltaG_solvation, DeltaH, dDeltaH = yankutils.analyze_directory(exp_dir) # # Add result to the original molecule in kcal/mol oechem.OESetSDData(solute, 'DG_yank_solv', str(DeltaG_solvation)) oechem.OESetSDData(solute, 'dG_yank_solv', str(dDeltaG_solvation)) # Emit the ligand self.success.emit(solute) except Exception as e: # Attach an error message to the molecule that failed self.log.error(traceback.format_exc()) solvated_system.SetData('error', str(e)) # Return failed mol self.failure.emit(solvated_system) return