def get_context(self, thermodynamic_state, integrator=None): """Create a new context in the given thermodynamic state. Parameters ---------- thermodynamic_state : states.ThermodynamicState The thermodynamic state of the system. integrator : simtk.openmm.Integrator, optional The integrator to bind to the new context. If ``None``, an arbitrary integrator is used. Currently, this is a ``LangevinIntegrator`` with "V R O R V" splitting, but this might change in the future. Default is ``None``. Returns ------- context : simtk.openmm.Context The new context in the given thermodynamic system. context_integrator : simtk.openmm.Integrator The integrator bound to the context that can be used for propagation. This is identical to the ``integrator`` argument if it was passed. """ if integrator is None: integrator = integrators.LangevinIntegrator( timestep=1.0 * unit.femtoseconds, splitting="V R O R V", temperature=thermodynamic_state.temperature) context = thermodynamic_state.create_context(integrator, self.platform) return context, integrator
def get_energy_vac(system, positions): """ Return the potential energy. Parameters ---------- system : simtk.openmm.System The system to check positions : simtk.unit.Quantity of dimension (natoms,3) with units of length The positions to use Returns --------- energy """ integrator = ommtoolsints.LangevinIntegrator(293.15 * kelvin, 1./picoseconds, 1.5 * femtoseconds) platform = mm.Platform.getPlatformByName('CPU') #platform = mm.Platform.getPlatformByName('CUDA') #properties = {"CudaPrecision": "mixed","DeterministicForces": "true" } #context = mm.Context(system, integrator, platform, properties) context = mm.Context(system, integrator, platform) context.setPositions(positions)#*angstroms) state = context.getState(getEnergy=True) energy = state.getPotentialEnergy() return energy
def get_energy_vac(system, positions): """ Return the potential energy. Parameters ---------- system : simtk.openmm.System The system to check positions : simtk.unit.Quantity of dimension (natoms,3) with units of length The positions to use Returns --------- energy """ integrator = ommtoolsints.LangevinIntegrator(293.15 * kelvin, 1. / picoseconds, 1.0 * femtoseconds) platform = mm.Platform.getPlatformByName('CPU') context = mm.Context(system, integrator, platform) context.setPositions(positions) state = context.getState(getEnergy=True) energy = state.getPotentialEnergy() return energy
def run_equilibrium(system, topology, configuration, n_steps, report_interval, filename): from mdtraj.reporters import HDF5Reporter integrator = integrators.LangevinIntegrator() simulation = app.Simulation(topology, system, integrator) simulation.context.setPositions(configuration) #equilibrate a little bit: simulation.step(10000) reporter = HDF5Reporter(filename, report_interval) simulation.reporters.append(reporter) simulation.step(n_steps)
def run_equilibrium(system, topology, configuration, n_steps, report_interval, equilibration_steps, filename): from mdtraj.reporters import HDF5Reporter integrator = integrators.LangevinIntegrator() simulation = app.Simulation(topology, system, integrator) simulation.context.setPositions(configuration) openmm.LocalEnergyMinimizer.minimize(simulation.context) #equilibrate: integrator.step(equilibration_steps) print("equilibration complete") reporter = HDF5Reporter(filename, report_interval) simulation.reporters.append(reporter) simulation.step(n_steps)
def create_langevin_integrator(htf, constraint_tol): """ create lambda alchemical states, thermodynamic states, sampler states, integrator, and return context, thermostate, sampler_state, integrator """ fast_lambda_alchemical_state = RelativeAlchemicalState.from_system( htf.hybrid_system) fast_lambda_alchemical_state.set_alchemical_parameters( 0.0, LambdaProtocol(functions='default')) fast_thermodynamic_state = CompoundThermodynamicState( ThermodynamicState(htf.hybrid_system, temperature=temperature), composable_states=[fast_lambda_alchemical_state]) fast_sampler_state = SamplerState( positions=htf._hybrid_positions, box_vectors=htf.hybrid_system.getDefaultPeriodicBoxVectors()) integrator_1 = integrators.LangevinIntegrator( temperature=temperature, timestep=4.0 * unit.femtoseconds, splitting='V R O R V', measure_shadow_work=False, measure_heat=False, constraint_tolerance=constraint_tol, collision_rate=5.0 / unit.picoseconds) # mcmc_moves=mcmc.LangevinSplittingDynamicsMove(timestep = 4.0 * unit.femtoseconds, # collision_rate=5.0 / unit.picosecond, # n_steps=1, # reassign_velocities=False, # n_restart_attempts=20, # splitting="V R R R O R R R V", # constraint_tolerance=constraint_tol) #print(integrator_1.getConstraintTolerance()) fast_context, fast_integrator = cache.global_context_cache.get_context( fast_thermodynamic_state, integrator_1) fast_sampler_state.apply_to_context(fast_context) return fast_context, fast_thermodynamic_state, fast_sampler_state, fast_integrator
def initialize(self, thermodynamic_state, lambda_protocol='default', timestep=1 * unit.femtoseconds, collision_rate=1 / unit.picoseconds, temperature=300 * unit.kelvin, neq_splitting_string='V R O R V', ncmc_save_interval=None, topology=None, subset_atoms=None, measure_shadow_work=False, integrator='langevin', compute_endstate_correction=True): try: self.context_cache = cache.global_context_cache if measure_shadow_work: measure_heat = True else: measure_heat = False self.thermodynamic_state = thermodynamic_state if integrator == 'langevin': self.integrator = integrators.LangevinIntegrator( temperature=temperature, timestep=timestep, splitting=neq_splitting_string, measure_shadow_work=measure_shadow_work, measure_heat=measure_heat, constraint_tolerance=1e-6, collision_rate=collision_rate) elif integrator == 'hmc': self.integrator = integrators.HMCIntegrator( temperature=temperature, nsteps=2, timestep=timestep / 2) else: raise Exception( f"integrator {integrator} is not supported. supported integrators include {self.supported_integrators}" ) self.lambda_protocol_class = LambdaProtocol( functions=lambda_protocol) #create temperatures self.beta = 1.0 / (kB * temperature) self.temperature = temperature self.save_interval = ncmc_save_interval self.topology = topology self.subset_atoms = subset_atoms #if we have a trajectory, set up some ancillary variables: if self.topology is not None: n_atoms = self.topology.n_atoms self._trajectory_positions = [] self._trajectory_box_lengths = [] self._trajectory_box_angles = [] self.compute_endstate_correction = compute_endstate_correction if self.compute_endstate_correction: self.thermodynamic_state.set_alchemical_parameters( 0.0, lambda_protocol=self.lambda_protocol_class) first_endstate = copy.deepcopy(self.thermodynamic_state) self.thermodynamic_state.set_alchemical_parameters( 1.0, lambda_protocol=self.lambda_protocol_class) last_endstate = copy.deepcopy(self.thermodynamic_state) endstates = create_endstates(first_endstate, last_endstate) self.endstates = {0.0: endstates[0], 1.0: endstates[1]} else: self.endstates = None #set a bool variable for pass or failure self.succeed = True return True except Exception as e: _logger.error(e) self.succeed = False return False
temperature = 300. * unit.kelvin collision_rate = 1. / unit.picoseconds pressure = 1. * unit.atmospheres # Make the water box test system with a fixed pressure wbox = WaterBox(model=args.model, box_edge=box_edge, nonbondedMethod=app.PME, cutoff=10 * unit.angstrom, ewaldErrorTolerance=1E-4) wbox.system.addForce(openmm.MonteCarloBarostat(pressure, temperature)) # Create the compound integrator langevin = integrators.LangevinIntegrator(splitting=splitting, temperature=temperature, timestep=timestep, collision_rate=collision_rate, measure_shadow_work=False, measure_heat=False) ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator( splitting=splitting, temperature=temperature, timestep=timestep, collision_rate=collision_rate, measure_shadow_work=False, measure_heat=False) integrator = openmm.CompoundIntegrator() integrator.addIntegrator(langevin) integrator.addIntegrator(ncmc_langevin) # Create context if args.platform == 'CUDA':
def __init__(self, thermodynamic_state, sampler_state, nsteps, direction, splitting='V R O R V', temperature=300 * unit.kelvin, collision_rate=np.inf / unit.picoseconds, timestep=1.0 * unit.femtosecond, work_save_interval=None, top=None, subset_atoms=None, save_configuration=False, lambda_protocol='default', measure_shadow_work=False, label=None, trajectory_filename=None): _logger.debug(f"Initializing Particle...") start = time.time() self._timers = {} #instantiate timer self.label = [label] self.context_cache = cache.global_context_cache if measure_shadow_work: measure_heat = True else: measure_heat = False assert direction == 'forward' or direction == 'reverse', f"The direction of the annealing protocol ({direction}) is invalid; must be specified as 'forward' or 'reverse'" self._direction = direction #define the lambda schedule (linear) if self._direction == 'forward': self.start_lambda = 0.0 self.end_lambda = 1.0 elif self._direction == 'reverse': self.start_lambda = 1.0 self.end_lambda = 0.0 else: raise Error(f"direction must be 'forward' or 'reverse'") #create lambda protocol self._nsteps = nsteps if self._nsteps is None: self.trailblaze = True self._work_save_interval = None # this is allowed to be None, in which case, the save_config method will never be called #likewise, if work work save interval is longer than the trailblazed lambda protocol, the save_configuration method will never be called self.current_lambda = self.start_lambda self.importance_samples = 1 #including the zero state #if we opt to trailblaze, we don't define a self.lambdas linsapce #instead, we define a self.current lambda and set it to the value of the start lambda else: self.trailblaze = False self.lambdas = np.linspace(self.start_lambda, self.end_lambda, self._nsteps) self.current_index = int(0) self.current_lambda = self.lambdas[self.current_index] if work_save_interval is None: self._work_save_interval = None else: self._work_save_interval = work_save_interval #check that the work write interval is a factor of the number of steps, so we don't accidentally record the #work before the end of the protocol as the end if self._nsteps % self._work_save_interval != 0: raise ValueError( "The work writing interval must be a factor of the total number of steps" ) #create sampling objects self.sampler_state = sampler_state self.thermodynamic_state = thermodynamic_state _logger.debug(f"thermodynamic state: {self.thermodynamic_state}") self.integrator = integrators.LangevinIntegrator( temperature=temperature, timestep=timestep, splitting=splitting, measure_shadow_work=measure_shadow_work, measure_heat=measure_heat, constraint_tolerance=1e-6, collision_rate=collision_rate) #platform = openmm.Platform.getPlatformByName(platform_name) self.context = openmm.Context(self.thermodynamic_state.system, self.integrator) #self.context, self.integrator = self.context_cache.get_context(self.thermodynamic_state, integrator) _logger.debug(f"context: {self.context}") self.lambda_protocol_class = LambdaProtocol(functions=lambda_protocol) self.thermodynamic_state.set_alchemical_parameters( self.start_lambda, lambda_protocol=self.lambda_protocol_class) self.thermodynamic_state.apply_to_context(self.context) self.sampler_state.apply_to_context(self.context, ignore_velocities=True) self.context.setVelocitiesToTemperature( self.thermodynamic_state.temperature) #randomize velocities @ temp self.integrator.step(1) self.sampler_state.update_from_context(self.context) #create temperatures self._beta = 1.0 / (kB * temperature) self._temperature = temperature init_state = self.context.getState(getEnergy=True) self.initial_energy = self._beta * (init_state.getPotentialEnergy() + init_state.getKineticEnergy()) self._save_configuration = save_configuration self._measure_shadow_work = measure_shadow_work if self._save_configuration: if trajectory_filename is None: raise Exception( f"cannot save configuration when trajectory_filename is None" ) else: self._trajectory_filename = trajectory_filename #use the number of step moves plus one, since the first is always zero self._cumulative_work = [0.0] self._shadow_work = 0.0 self._heat = 0.0 self._topology = top self._subset_atoms = subset_atoms self._trajectory = None #if we have a trajectory, set up some ancillary variables: if self._topology is not None: n_atoms = self._topology.n_atoms self._trajectory_positions = [] self._trajectory_box_lengths = [] self._trajectory_box_angles = [] else: self._save_configuration = False self._timers['instantiate'] = time.time() - start self._timers['protocol'] = [] self._timers['save'] = [] #set a bool variable for pass or failure self.succeed = True self.failures = [] _logger.debug(f"Initialization complete!")
def setup_fah_run(destination_path, protein_pdb_filename, oemol=None, cache=None, restrain_rmsd=False): """ Prepare simulation Parameters ---------- destination_path : str The path to the RUN to be created protein_pdb_filename : str Path to protein PDB file oemol : openeye.oechem.OEMol, optional, default=None The molecule to parameterize, with SDData attached If None, don't include the small molecule restrain_rmsd : bool, optional, default=False If True, restrain RMSD during first equilibration phase """ # Parameters from simtk import unit, openmm protein_forcefield = 'amber14/protein.ff14SB.xml' solvent_forcefield = 'amber14/tip3p.xml' small_molecule_forcefield = 'openff-1.2.0' water_model = 'tip3p' solvent_padding = 10.0 * unit.angstrom ionic_strength = 70 * unit.millimolar # assay buffer: 20 mM HEPES pH 7.3, 1 mM TCEP, 50 mM NaCl, 0.01% Tween-20, 10% glycerol pressure = 1.0 * unit.atmospheres collision_rate = 1.0 / unit.picoseconds temperature = 300.0 * unit.kelvin timestep = 4.0 * unit.femtoseconds iterations = 1000 # 1 ns equilibration nsteps_per_iteration = 250 # Prepare phases import os system_xml_filename = os.path.join(destination_path, 'system.xml.bz2') integrator_xml_filename = os.path.join(destination_path, 'integrator.xml.bz2') state_xml_filename = os.path.join(destination_path, 'state.xml.bz2') # Check if we can skip setup openmm_files_exist = os.path.exists( system_xml_filename) and os.path.exists( state_xml_filename) and os.path.exists(integrator_xml_filename) if openmm_files_exist: return # Create barostat barostat = openmm.MonteCarloBarostat(pressure, temperature) # Create RUN directory if it does not yet exist os.makedirs(destination_path, exist_ok=True) # Load any molecule(s) molecule = None if oemol is not None: from openforcefield.topology import Molecule molecule = Molecule.from_openeye(oemol, allow_undefined_stereo=True) molecule.name = 'MOL' # Ensure residue is MOL print([res for res in molecule.to_topology().to_openmm().residues()]) # Create SystemGenerator import os from simtk.openmm import app forcefield_kwargs = { 'removeCMMotion': False, 'hydrogenMass': 3.0 * unit.amu, 'constraints': app.HBonds, 'rigidWater': True } periodic_kwargs = { 'nonbondedMethod': app.PME, 'ewaldErrorTolerance': 2.5e-04 } forcefields = [protein_forcefield, solvent_forcefield] from openmmforcefields.generators import SystemGenerator openmm_system_generator = SystemGenerator( forcefields=forcefields, molecules=molecule, small_molecule_forcefield=small_molecule_forcefield, cache=cache, barostat=barostat, forcefield_kwargs=forcefield_kwargs, periodic_forcefield_kwargs=periodic_kwargs) # Read protein print(f'Reading protein from {protein_pdb_filename}...') pdbfile = app.PDBFile(protein_pdb_filename) modeller = app.Modeller(pdbfile.topology, pdbfile.positions) if oemol is not None: # Add small molecule to the system modeller.add(molecule.to_topology().to_openmm(), molecule.conformers[0]) # DEBUG : Check residue name with open(os.path.join(destination_path, 'initial-complex.pdb'), 'wt') as outfile: app.PDBFile.writeFile(modeller.topology, modeller.positions, outfile) # Add solvent print('Adding solvent...') kwargs = {'padding': solvent_padding} modeller.addSolvent(openmm_system_generator.forcefield, model='tip3p', ionicStrength=ionic_strength, **kwargs) # Create an OpenMM system print('Creating OpenMM system...') system = openmm_system_generator.create_system(modeller.topology) # Add a virtual bond between protein and ligand to make sure they are not imaged separately if oemol is not None: import mdtraj as md mdtop = md.Topology.from_openmm( modeller.topology) # excludes solvent and ions for res in mdtop.residues: print(res) protein_atom_indices = mdtop.select( '(protein and name CA)') # protein CA atoms ligand_atom_indices = mdtop.select( '((resname MOL) and (mass > 1))') # ligand heavy atoms protein_atom_index = int(protein_atom_indices[0]) ligand_atom_index = int(ligand_atom_indices[0]) force = openmm.CustomBondForce('0') force.addBond(protein_atom_index, ligand_atom_index, []) system.addForce(force) # Add RMSD restraints if requested if restrain_rmsd: print('Adding RMSD restraint...') kB = unit.AVOGADRO_CONSTANT_NA * unit.BOLTZMANN_CONSTANT_kB kT = kB * temperature import mdtraj as md mdtop = md.Topology.from_openmm( pdbfile.topology) # excludes solvent and ions #heavy_atom_indices = mdtop.select('mass > 1') # heavy solute atoms rmsd_atom_indices = mdtop.select( '(protein and (name CA)) or ((resname MOL) and (mass > 1))' ) # CA atoms and ligand heavy atoms rmsd_atom_indices = [int(index) for index in rmsd_atom_indices] custom_cv_force = openmm.CustomCVForce('(K_RMSD/2)*RMSD^2') custom_cv_force.addGlobalParameter('K_RMSD', kT / unit.angstrom**2) rmsd_force = openmm.RMSDForce(modeller.positions, rmsd_atom_indices) custom_cv_force.addCollectiveVariable('RMSD', rmsd_force) force_index = system.addForce(custom_cv_force) # Create OpenM Context platform = openmm.Platform.getPlatformByName('OpenCL') platform.setPropertyDefaultValue('Precision', 'mixed') from openmmtools import integrators integrator = integrators.LangevinIntegrator(temperature, collision_rate, timestep) context = openmm.Context(system, integrator, platform) context.setPositions(modeller.positions) # Report initial potential energy state = context.getState(getEnergy=True) print( f'Initial potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol' ) # Store snapshots in MDTraj trajectory to examine RMSD import mdtraj as md import numpy as np mdtop = md.Topology.from_openmm(pdbfile.topology) atom_indices = mdtop.select('all') # all solute atoms protein_atom_indices = mdtop.select( 'protein and (mass > 1)') # heavy solute atoms if oemol is not None: ligand_atom_indices = mdtop.select( '(resname MOL) and (mass > 1)') # ligand heavy atoms trajectory = md.Trajectory( np.zeros([iterations + 1, len(atom_indices), 3], np.float32), mdtop) trajectory.xyz[0, :, :] = context.getState(getPositions=True).getPositions( asNumpy=True)[atom_indices] / unit.nanometers # Minimize print('Minimizing...') openmm.LocalEnergyMinimizer.minimize(context) # Equilibrate (with RMSD restraint if needed) import numpy as np from rich.progress import track import time initial_time = time.time() for iteration in track(range(iterations), 'Equilibrating...'): integrator.step(nsteps_per_iteration) trajectory.xyz[iteration + 1, :, :] = context.getState( getPositions=True).getPositions( asNumpy=True)[atom_indices] / unit.nanometers elapsed_time = (time.time() - initial_time) * unit.seconds ns_per_day = (context.getState().getTime() / elapsed_time) / (unit.nanoseconds / unit.day) print(f'Performance: {ns_per_day:8.3f} ns/day') if restrain_rmsd: # Disable RMSD restraint context.setParameter('K_RMSD', 0.0) print('Minimizing...') openmm.LocalEnergyMinimizer.minimize(context) for iteration in track(range(iterations), 'Equilibrating without RMSD restraint...'): integrator.step(nsteps_per_iteration) # Retrieve state state = context.getState(getPositions=True, getVelocities=True, getEnergy=True, getForces=True) system.setDefaultPeriodicBoxVectors(*state.getPeriodicBoxVectors()) modeller.topology.setPeriodicBoxVectors(state.getPeriodicBoxVectors()) print( f'Final potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol' ) # Equilibrate again if we restrained the RMSD if restrain_rmsd: print('Removing RMSD restraint from system...') system.removeForce(force_index) #if oemol is not None: # # Check final RMSD # print('checking RMSD...') # trajectory.superpose(trajectory, atom_indices=protein_atom_indices) # protein_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=protein_atom_indices)[-1] * 10 # Angstroms # oechem.OESetSDData(oemol, 'equil_protein_rmsd', f'{protein_rmsd:.2f} A') # ligand_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=ligand_atom_indices)[-1] * 10 # Angstroms # oechem.OESetSDData(oemol, 'equil_ligand_rmsd', f'{ligand_rmsd:.2f} A') # print('RMSD after equilibration: protein {protein_rmsd:8.2f} A | ligand {ligand_rmsd:8.3f} A') # Save as OpenMM print('Exporting for OpenMM FAH simulation...') import bz2 with bz2.open(integrator_xml_filename, 'wt') as f: f.write(openmm.XmlSerializer.serialize(integrator)) with bz2.open(state_xml_filename, 'wt') as f: f.write(openmm.XmlSerializer.serialize(state)) with bz2.open(system_xml_filename, 'wt') as f: f.write(openmm.XmlSerializer.serialize(system)) with bz2.open(os.path.join(destination_path, 'equilibrated-all.pdb.gz'), 'wt') as f: app.PDBFile.writeFile(modeller.topology, state.getPositions(), f) with open(os.path.join(destination_path, 'equilibrated-solute.pdb'), 'wt') as f: import mdtraj mdtraj_topology = mdtraj.Topology.from_openmm(modeller.topology) mdtraj_trajectory = mdtraj.Trajectory( [state.getPositions(asNumpy=True) / unit.nanometers], mdtraj_topology) selection = mdtraj_topology.select('not water') mdtraj_trajectory = mdtraj_trajectory.atom_slice(selection) app.PDBFile.writeFile(mdtraj_trajectory.topology.to_openmm(), mdtraj_trajectory.openmm_positions(0), f) if oemol is not None: # Write molecule as SDF, SMILES, and mol2 for extension in ['sdf', 'mol2', 'smi', 'csv']: filename = os.path.join(destination_path, f'molecule.{extension}') with oechem.oemolostream(filename) as ofs: oechem.OEWriteMolecule(ofs, oemol) # Clean up del context, integrator
def create_ideal_system(npert=50, nprop=1, deltachem=0.0, platform='CPU'): """ Create small box of water that can impliment ideal mixing with the SaltSwap osmostat. Parameters ---------- npert: int the number of NCMC perturbations nprop: int the number of Langevin propagation steps per NCMC perturbation. deltachem: float the difference in chemical potential between two water molecules and NaCl that has the same nonbonded parameters as two water molecules. platform: str The computational platform. Either 'CPU', 'CUDA', or 'OpenCL'. Returns ------- ncmc_swapper: saltswap.swapper the driver that can perform NCMC exchanges langevin: openmmtools.integrator the integrator for equilibrium sampling. """ # Setting the parameters of the simulation timestep = 2.0 * unit.femtoseconds box_edge = 25.0 * unit.angstrom splitting = 'V R O R V' temperature = 300. * unit.kelvin collision_rate = 1. / unit.picoseconds pressure = 1. * unit.atmospheres # Make the water box test system with a fixed pressure wbox = WaterBox(box_edge=box_edge, model='tip3p', nonbondedMethod=app.PME, cutoff=10 * unit.angstrom, ewaldErrorTolerance=1E-4) wbox.system.addForce(openmm.MonteCarloBarostat(pressure, temperature)) # Create the compound integrator langevin = integrators.LangevinIntegrator(splitting=splitting, temperature=temperature, timestep=timestep, collision_rate=collision_rate, measure_shadow_work=False, measure_heat=False) ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator( splitting=splitting, temperature=temperature, timestep=timestep, collision_rate=collision_rate, measure_shadow_work=False, measure_heat=False) integrator = openmm.CompoundIntegrator() integrator.addIntegrator(langevin) integrator.addIntegrator(ncmc_langevin) # Create context if platform == 'CUDA': platform = openmm.Platform.getPlatformByName('CUDA') platform.setPropertyDefaultValue('DeterministicForces', 'true') properties = {'CudaPrecision': 'mixed'} context = openmm.Context(wbox.system, integrator, platform, properties) elif platform == 'OpenCL': platform = openmm.Platform.getPlatformByName('OpenCL') properties = {'OpenCLPrecision': 'mixed'} context = openmm.Context(wbox.system, integrator, platform, properties) elif platform == 'CPU': platform = openmm.Platform.getPlatformByName('CPU') context = openmm.Context(wbox.system, integrator, platform) else: raise Exception('Platform name {0} not recognized.'.format( args.platform)) context.setPositions(wbox.positions) context.setVelocitiesToTemperature(temperature) # Create the swapper object for the insertion and deletion of salt ncmc_swapper = Swapper(system=wbox.system, topology=wbox.topology, temperature=temperature, delta_chem=deltachem, ncmc_integrator=ncmc_langevin, pressure=pressure, npert=npert, nprop=nprop) # Set the nonbonded parameters of the ions to be the same as water. This is critical for ideal mixing. ncmc_swapper.cation_parameters = ncmc_swapper.water_parameters ncmc_swapper.anion_parameters = ncmc_swapper.water_parameters ncmc_swapper._set_parampath() return context, ncmc_swapper, langevin
def validate_rjmc_work_variance(top_prop, positions, geometry_method=0, num_iterations=10, md_steps=250, compute_timeseries=False, md_system=None, prespecified_conformers=None): """ Arguments ---------- top_prop : perses.rjmc.topology_proposal.TopologyProposal object topology_proposal md_system : openmm.System object, default None system from which md is conducted; the default is the top_prop._old_system geometry_method : int which geometry proposal method to use 0: neglect_angles = True (this is supposed to be the zero-variance method) 1: neglect_angles = False (this will accumulate variance) 2: use_sterics = True (this is experimental) num_iterations: int number of times to run md_steps integrator md_steps: int number of md_steps to run in each num_iteration compute_timeseries = bool (default False) whether to use pymbar detectEquilibration and subsampleCorrelated data from the MD run (the potential energy is the data) prespecified_conformers = None or unit.Quantity(np.array([num_iterations, system.getNumParticles(), 3]), unit = unit.nanometers) whether to input a unit.Quantity of conformers and bypass the conformer_generation/pymbar stage; None will default conduct this phase Returns ------- conformers : unit.Quantity(np.array([num_iterations, system.getNumParticles(), 3]), unit = unit.nanometers) decorrelated positions of the md run rj_works : list work from each conformer proposal """ from openmmtools import integrators from perses.utils.openeye import smiles_to_oemol import simtk.unit as unit import simtk.openmm as openmm from openmmtools.constants import kB from perses.rjmc.geometry import FFAllAngleGeometryEngine import tqdm temperature = 300.0 * unit.kelvin # unit-bearing temperature kT = kB * temperature # unit-bearing thermal energy beta = 1.0 / kT # unit-bearing inverse thermal energy #first, we must extract the top_prop relevant quantities topology = top_prop._old_topology if md_system == None: system = top_prop._old_system else: system = md_system if prespecified_conformers == None: #now we can specify conformations from MD integrator = integrators.LangevinIntegrator( collision_rate=1.0 / unit.picosecond, timestep=4.0 * unit.femtosecond, temperature=temperature) context = openmm.Context(system, integrator) context.setPositions(positions) openmm.LocalEnergyMinimizer.minimize(context) minimized_positions = context.getState(getPositions=True).getPositions( asNumpy=True) print(f"completed initial minimization") context.setPositions(minimized_positions) zeros = np.zeros([num_iterations, int(system.getNumParticles()), 3]) conformers = unit.Quantity(zeros, unit=unit.nanometers) rps = np.zeros((num_iterations)) print(f"conducting md sampling") for iteration in tqdm.trange(num_iterations): integrator.step(md_steps) state = context.getState(getPositions=True, getEnergy=True) new_positions = state.getPositions(asNumpy=True) conformers[iteration, :, :] = new_positions rp = state.getPotentialEnergy() * beta rps[iteration] = rp del context, integrator if compute_timeseries: print(f"computing production and data correlation") from pymbar import timeseries t0, g, Neff = timeseries.detectEquilibration(rps) series = timeseries.subsampleCorrelatedData(np.arange( t0, num_iterations), g=g) print(f"production starts at index {t0} of {num_iterations}") print(f"the number of effective samples is {Neff}") indices = t0 + series print(f"the filtered indices are {indices}") else: indices = range(num_iterations) else: conformers = prespecified_conformers indices = range(len(conformers)) #now we can define a geometry_engine if geometry_method == 0: geometry_engine = FFAllAngleGeometryEngine( metadata=None, use_sterics=False, n_bond_divisions=1000, n_angle_divisions=180, n_torsion_divisions=360, verbose=True, storage=None, bond_softening_constant=1.0, angle_softening_constant=1.0, neglect_angles=True) elif geometry_method == 1: geometry_engine = FFAllAngleGeometryEngine( metadata=None, use_sterics=False, n_bond_divisions=1000, n_angle_divisions=180, n_torsion_divisions=360, verbose=True, storage=None, bond_softening_constant=1.0, angle_softening_constant=1.0, neglect_angles=False) elif geometry_method == 2: geometry_engine = FFAllAngleGeometryEngine( metadata=None, use_sterics=True, n_bond_divisions=1000, n_angle_divisions=180, n_torsion_divisions=360, verbose=True, storage=None, bond_softening_constant=1.0, angle_softening_constant=1.0, neglect_angles=False) else: raise Exception(f"there is no geometry method for {geometry_method}") rj_works = [] print(f"conducting geometry proposals...") for indx in tqdm.trange(len(indices)): index = indices[indx] print(f"index {indx}") new_positions, logp_forward = geometry_engine.propose( top_prop, conformers[index], beta) logp_backward = geometry_engine.logp_reverse(top_prop, new_positions, conformers[index], beta) print( f"\tlogp_forward, logp_backward: {logp_forward}, {logp_backward}") added_energy = geometry_engine.forward_final_context_reduced_potential - geometry_engine.forward_atoms_with_positions_reduced_potential subtracted_energy = geometry_engine.reverse_final_context_reduced_potential - geometry_engine.reverse_atoms_with_positions_reduced_potential print( f"\tadded_energy, subtracted_energy: {added_energy}, {subtracted_energy}" ) work = logp_forward - logp_backward + added_energy - subtracted_energy rj_works.append(work) print(f"\ttotal work: {work}") return conformers, rj_works
kinetic_temperature = 293.15*kelvin collision_frequency = 1./picosecond step_size = 1.*femtoseconds pressure = 1.01*bar barostat_frequency = 10 ############################################################# ############################################################# system = forcefield.createSystem(pdb.topology,mols,nonbondedMethod=PME,nonbondedCutoff=1.125*nanometers)#,ewaldErrorTolerance=1.e-5)#,constraints=HBonds) #box_vectors = AmberInpcrdFile('monomers/cyclohexane.inpcrd').boxVectors #system.setDefaultPeriodicBoxVectors(*box_vectors) integrator = ommtoolsints.LangevinIntegrator(kinetic_temperature, collision_frequency, step_size) barostat = MonteCarloBarostat(pressure, kinetic_temperature, barostat_frequency) system.addForce(barostat) #platform = mm.Platform.getPlatformByName('Reference') #properties = {'None'} platform = Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed','DeterministicForces': 'true'} simulation = Simulation(pdb.topology, system, integrator, platform, properties) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(kinetic_temperature) simulation.minimizeEnergy() #print(simulation.context.getSystem) #print(pdb.positions) netcdf_reporter = NetCDFReporter('traj_cychex_neat/Lang_2_baro10step_pme1e-5/'+name+'_'+smirkseries1+'_'+eps+epsval1+'_'+rmin+rminval1+'_'+smirkseries2+'_'+eps+epsval2+'_'+rmin+rminval2+'_wNoConstraints_1fsts.nc', traj_freq)
def create_system(args, splitting): """ Create a test system that's able to run saltswap. Parameters ---------- args: splitting: """ # Fixed simulation parameters temperature = 300.0 * unit.kelvin collision_rate = 1.0 / unit.picoseconds pressure = 1.0 * unit.atmospheres salt_concentration = args.conc * unit.molar # Get the test system and add the barostat. testobj = getattr(testsystems, args.testsystem) testsys = testobj(nonbondedMethod=app.PME, cutoff=10 * unit.angstrom, ewaldErrorTolerance=1E-4, switch_width=1.5 * unit.angstrom) testsys.system.addForce( openmm.MonteCarloBarostat(pressure, temperature)) # Create the compound integrator langevin = integrators.LangevinIntegrator( splitting=splitting, temperature=temperature, timestep=timestep, collision_rate=collision_rate, measure_shadow_work=False, measure_heat=False) ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator( splitting=splitting, temperature=temperature, timestep=timestep, collision_rate=collision_rate, measure_shadow_work=False, measure_heat=False) integrator = openmm.CompoundIntegrator() integrator.addIntegrator(langevin) integrator.addIntegrator(ncmc_langevin) # Create context if args.platform == 'CUDA': platform = openmm.Platform.getPlatformByName('CUDA') platform.setPropertyDefaultValue('DeterministicForces', 'true') properties = {'CudaPrecision': 'mixed'} context = openmm.Context(testsys.system, integrator, platform, properties) elif args.platform == 'OpenCL': platform = openmm.Platform.getPlatformByName('OpenCL') properties = {'OpenCLPrecision': 'mixed'} context = openmm.Context(testsys.system, integrator, platform, properties) elif args.platform == 'CPU': platform = openmm.Platform.getPlatformByName('CPU') context = openmm.Context(testsys.system, integrator, platform) else: raise Exception('Platform name {0} not recognized.'.format( args.platform)) context.setPositions(testsys.positions) context.setVelocitiesToTemperature(temperature) # Create the swapper object for the insertion and deletion of salt salinator = wrappers.Salinator(context=context, system=testsys.system, topology=testsys.topology, ncmc_integrator=ncmc_langevin, salt_concentration=salt_concentration, pressure=pressure, temperature=temperature, npert=npert, water_name=args.water_name) # Neutralize the system and initialize the number of salt pairs. salinator.neutralize() salinator.initialize_concentration() return salinator, langevin, integrator
epsval2 = sys.argv[8] rminval2 = sys.argv[9] param1 = forcefield.getParameter(smirks=smirkseries1) param1[eps] = epsval1 param1[rmin] = rminval1 forcefield.setParameter(param1, smirks=smirkseries1) param2 = forcefield.getParameter(smirks=smirkseries2) param2[eps] = epsval2 param2[rmin] = rminval2 forcefield.setParameter(param2, smirks=smirkseries2) #Do simulation integrator = ommtoolsints.LangevinIntegrator(temperature * kelvin, friction / picoseconds, time_step * femtoseconds) platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed', 'DeterministicForces': 'true'} simulation = app.Simulation(topology, system, integrator, platform, properties) simulation.context.setPositions(positions) simulation.context.setVelocitiesToTemperature(temperature * kelvin) netcdf_reporter = NetCDFReporter( 'traj_cychex_neat/Lang_2_baro10step_pme1e-5/' + molname[ind] + '_' + smirkseries1 + '_' + eps + epsval1 + '_' + rmin + rminval1 + '_' + smirkseries2 + '_' + eps + epsval2 + '_' + rmin + rminval2 + '_wNoConstraints_vacuum_0.8fsts.nc', trj_freq) simulation.reporters.append(netcdf_reporter) simulation.reporters.append( app.StateDataReporter(sys.stdout,