def run_without_work_accumulation( self, testsystem, parameter_name, parameter_initial, parameter_final, platform_name="Reference", name=None, ): """Compare external work accumulation between Reference and CPU platforms. """ if name is None: name = testsystem.name from openmmtools.constants import kB system, topology = testsystem.system, testsystem.topology temperature = 298.0 * unit.kelvin platform = openmm.Platform.getPlatformByName(platform_name) # TODO: Set precision and determinism if platform is ['OpenCL', 'CUDA'] nsteps = 20 kT = kB * temperature integrator = GBAOABIntegrator(temperature=temperature, external_work=False) context = openmm.Context(system, integrator, platform) context.setParameter(parameter_name, parameter_initial) context.setPositions(testsystem.positions) context.setVelocitiesToTemperature(temperature) integrator.step(1) for step in range(nsteps): lambda_value = float(step + 1) / float(nsteps) parameter_value = ( parameter_initial * (1 - lambda_value) + parameter_final * lambda_value ) initial_energy = context.getState(getEnergy=True).getPotentialEnergy() context.setParameter(parameter_name, parameter_value) final_energy = context.getState(getEnergy=True).getPotentialEnergy() integrator.step(1) del context, integrator
def run_without_work_accumulation( self, testsystem, parameter_name, parameter_initial, parameter_final, platform_name="Reference", name=None, ): """Compare external work accumulation between Reference and CPU platforms. """ if name is None: name = testsystem.name from openmmtools.constants import kB system, topology = testsystem.system, testsystem.topology temperature = 298.0 * unit.kelvin platform = openmm.Platform.getPlatformByName(platform_name) # TODO: Set precision and determinism if platform is ['OpenCL', 'CUDA'] nsteps = 20 kT = kB * temperature integrator = GBAOABIntegrator(temperature=temperature, external_work=False) context = openmm.Context(system, integrator, platform) context.setParameter(parameter_name, parameter_initial) context.setPositions(testsystem.positions) context.setVelocitiesToTemperature(temperature) integrator.step(1) for step in range(nsteps): lambda_value = float(step + 1) / float(nsteps) parameter_value = (parameter_initial * (1 - lambda_value) + parameter_final * lambda_value) initial_energy = context.getState( getEnergy=True).getPotentialEnergy() context.setParameter(parameter_name, parameter_value) final_energy = context.getState( getEnergy=True).getPotentialEnergy() integrator.step(1) del context, integrator
def compare_external_protocol_work_accumulation( self, testsystem, parameter_name, parameter_initial, parameter_final, platform_name="Reference", name=None, ): """Compare external work accumulation between Reference and CPU platforms. """ if name is None: name = testsystem.name from openmmtools.constants import kB system, topology = testsystem.system, testsystem.topology temperature = 298.0 * unit.kelvin platform = openmm.Platform.getPlatformByName(platform_name) # TODO: Set precision and determinism if platform is ['OpenCL', 'CUDA'] nsteps = 20 kT = kB * temperature integrator = GBAOABIntegrator(temperature=temperature) context = openmm.Context(system, integrator, platform) context.setParameter(parameter_name, parameter_initial) context.setPositions(testsystem.positions) context.setVelocitiesToTemperature(temperature) assert ( integrator.getGlobalVariableByName("protocol_work") == 0 ), "Protocol work should be 0 initially" integrator.step(1) assert ( integrator.getGlobalVariableByName("protocol_work") == 0 ), "There should be no protocol work." external_protocol_work = 0.0 for step in range(nsteps): lambda_value = float(step + 1) / float(nsteps) parameter_value = ( parameter_initial * (1 - lambda_value) + parameter_final * lambda_value ) initial_energy = context.getState(getEnergy=True).getPotentialEnergy() context.setParameter(parameter_name, parameter_value) final_energy = context.getState(getEnergy=True).getPotentialEnergy() external_protocol_work += (final_energy - initial_energy) / kT integrator.step(1) integrator_protocol_work = ( integrator.getGlobalVariableByName("protocol_work") * unit.kilojoules_per_mole / kT ) message = "\n" message += "protocol work discrepancy noted for %s on platform %s\n" % ( name, platform_name, ) message += ( "step %5d : external %16e kT | integrator %16e kT | difference %16e kT" % ( step, external_protocol_work, integrator_protocol_work, external_protocol_work - integrator_protocol_work, ) ) # Test relative tolerance assert ( pytest.approx(external_protocol_work, 0.001) == integrator_protocol_work ), message del context, integrator
def compare_external_protocol_work_accumulation( self, testsystem, parameter_name, parameter_initial, parameter_final, platform_name="Reference", name=None, ): """Compare external work accumulation between Reference and CPU platforms. """ if name is None: name = testsystem.name from openmmtools.constants import kB system, topology = testsystem.system, testsystem.topology temperature = 298.0 * unit.kelvin platform = openmm.Platform.getPlatformByName(platform_name) # TODO: Set precision and determinism if platform is ['OpenCL', 'CUDA'] nsteps = 20 kT = kB * temperature integrator = GBAOABIntegrator(temperature=temperature) context = openmm.Context(system, integrator, platform) context.setParameter(parameter_name, parameter_initial) context.setPositions(testsystem.positions) context.setVelocitiesToTemperature(temperature) assert (integrator.getGlobalVariableByName("protocol_work") == 0 ), "Protocol work should be 0 initially" integrator.step(1) assert (integrator.getGlobalVariableByName("protocol_work") == 0 ), "There should be no protocol work." external_protocol_work = 0.0 for step in range(nsteps): lambda_value = float(step + 1) / float(nsteps) parameter_value = (parameter_initial * (1 - lambda_value) + parameter_final * lambda_value) initial_energy = context.getState( getEnergy=True).getPotentialEnergy() context.setParameter(parameter_name, parameter_value) final_energy = context.getState( getEnergy=True).getPotentialEnergy() external_protocol_work += (final_energy - initial_energy) / kT integrator.step(1) integrator_protocol_work = ( integrator.getGlobalVariableByName("protocol_work") * unit.kilojoules_per_mole / kT) message = "\n" message += "protocol work discrepancy noted for %s on platform %s\n" % ( name, platform_name, ) message += ( "step %5d : external %16e kT | integrator %16e kT | difference %16e kT" % ( step, external_protocol_work, integrator_protocol_work, external_protocol_work - integrator_protocol_work, )) # Test relative tolerance assert (pytest.approx(external_protocol_work, 0.001) == integrator_protocol_work), message del context, integrator
def test_create_simulation(self): """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide.""" pdb = app.PDBxFile( get_test_data("glu_ala_his-solvated-minimized-renamed.cif", "testsystems/tripeptides")) forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml", "tip3p.xml") system = forcefield.createSystem( pdb.topology, nonbondedMethod=app.PME, nonbondedCutoff=1.0 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005, ) temperature = 300 * unit.kelvin integrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=False, ) ncmcintegrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=True, ) compound_integrator = mm.CompoundIntegrator() compound_integrator.addIntegrator(integrator) compound_integrator.addIntegrator(ncmcintegrator) pressure = 1.0 * unit.atmosphere system.addForce(mm.MonteCarloBarostat(pressure, temperature)) driver = ForceFieldProtonDrive( temperature, pdb.topology, system, forcefield, ["amber10-constph.xml"], pressure=pressure, perturbations_per_trial=0, ) simulation = app.ConstantPHSimulation( pdb.topology, system, compound_integrator, driver, platform=self._default_platform, ) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(temperature) # Regular MD step simulation.step(1) # Update the titration states using the uniform proposal simulation.update(1) print("Done!")
def test_create_constantphcalibration_with_reporters(self): """Test running a calibration using constant-pH with reporters.""" pdb = app.PDBxFile( get_test_data("glu_ala_his-solvated-minimized-renamed.cif", "testsystems/tripeptides")) forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml", "tip3p.xml") system = forcefield.createSystem( pdb.topology, nonbondedMethod=app.PME, nonbondedCutoff=1.0 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005, ) temperature = 300 * unit.kelvin integrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=False, ) ncmcintegrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=True, ) compound_integrator = mm.CompoundIntegrator() compound_integrator.addIntegrator(integrator) compound_integrator.addIntegrator(ncmcintegrator) pressure = 1.0 * unit.atmosphere system.addForce(mm.MonteCarloBarostat(pressure, temperature)) driver = ForceFieldProtonDrive( temperature, pdb.topology, system, forcefield, ["amber10-constph.xml"], pressure=pressure, perturbations_per_trial=2, propagations_per_step=1, ) # prep the driver for calibration driver.enable_calibration(SAMSApproach.ONESITE, group_index=-1) simulation = app.ConstantPHSimulation( pdb.topology, system, compound_integrator, driver, platform=self._default_platform, ) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(temperature) # Outputfile for reporters newname = uuid4().hex + ".nc" ncfile = netCDF4.Dataset(newname, "w") tr = TitrationReporter(ncfile, 1) mr = MetadataReporter(ncfile) nr = NCMCReporter(ncfile, 1) sr = SAMSReporter(ncfile, 1) simulation.update_reporters.append(tr) simulation.update_reporters.append(mr) simulation.update_reporters.append(nr) simulation.calibration_reporters.append(sr) simulation.step(1) # Update the titration states using the uniform proposal simulation.update(1) # Adapt the weights using binary update. simulation.adapt() # Attempt to prevent segfaults by closing files ncfile.close()
def test_create_constantphcalibration_resume(self): """Test running a calibration using constant-pH.""" pdb = app.PDBxFile( get_test_data("glu_ala_his-solvated-minimized-renamed.cif", "testsystems/tripeptides")) forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml", "tip3p.xml") system = forcefield.createSystem( pdb.topology, nonbondedMethod=app.PME, nonbondedCutoff=1.0 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005, ) temperature = 300 * unit.kelvin integrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=False, ) ncmcintegrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=True, ) compound_integrator = mm.CompoundIntegrator() compound_integrator.addIntegrator(integrator) compound_integrator.addIntegrator(ncmcintegrator) pressure = 1.0 * unit.atmosphere system.addForce(mm.MonteCarloBarostat(pressure, temperature)) driver = ForceFieldProtonDrive( temperature, pdb.topology, system, forcefield, ["amber10-constph.xml"], pressure=pressure, perturbations_per_trial=0, ) driver.enable_calibration(SAMSApproach.ONESITE, group_index=-1) simulation = app.ConstantPHSimulation( pdb.topology, system, compound_integrator, driver, platform=self._default_platform, ) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(temperature) simulation.step(1) # Update the titration states using the uniform proposal simulation.update(1) # Adapt the weights using binary update, a few times just to rack up the counters. for x in range(5): simulation.adapt() # retrieve the samsProperties # TODO use deserialize proton drive for this xml = simulation.drive.state_to_xml() driver2 = NCMCProtonDrive( temperature, pdb.topology, system, pressure=pressure, perturbations_per_trial=0, ) driver2.state_from_xml_tree(etree.fromstring(xml)) integrator2 = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=False, ) ncmcintegrator2 = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=True, ) compound_integrator2 = mm.CompoundIntegrator() compound_integrator2.addIntegrator(integrator2) compound_integrator2.addIntegrator(ncmcintegrator2) # Make a new calibration and do another step, ignore the state for this example simulation2 = app.ConstantPHSimulation( pdb.topology, system, compound_integrator2, driver2, platform=self._default_platform, ) assert (simulation2.drive.calibration_state._stage is simulation.drive.calibration_state._stage) # get going then simulation2.context.setPositions(pdb.positions) simulation2.context.setVelocitiesToTemperature(temperature) simulation2.step(1) # Update the titration states using the uniform proposal simulation2.update(1) # Adapt the weights using binary update. simulation2.adapt() assert ( simulation2.drive.calibration_state._current_adaptation == -simulation.drive.calibration_state._min_burn + 6 ), "The resumed calibration does not have the right adaptation_index"
def test_create_importance_sampling_reporters(self): """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide using importance sampling with reporters.""" pdb = app.PDBxFile( get_test_data("glu_ala_his-solvated-minimized-renamed.cif", "testsystems/tripeptides")) forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml", "tip3p.xml") system = forcefield.createSystem( pdb.topology, nonbondedMethod=app.PME, nonbondedCutoff=1.0 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005, ) temperature = 300 * unit.kelvin integrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=False, ) ncmcintegrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=True, ) compound_integrator = mm.CompoundIntegrator() compound_integrator.addIntegrator(integrator) compound_integrator.addIntegrator(ncmcintegrator) pressure = 1.0 * unit.atmosphere system.addForce(mm.MonteCarloBarostat(pressure, temperature)) driver = ForceFieldProtonDrive( temperature, pdb.topology, system, forcefield, ["amber10-constph.xml"], pressure=pressure, perturbations_per_trial=0, sampling_method=SamplingMethod.IMPORTANCE, ) simulation = app.ConstantPHSimulation( pdb.topology, system, compound_integrator, driver, platform=self._default_platform, ) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(temperature) newname = uuid4().hex + ".nc" ncfile = netCDF4.Dataset(newname, "w") tr = TitrationReporter(ncfile, 1) mr = MetadataReporter(ncfile) nr = NCMCReporter(ncfile, 1) simulation.update_reporters.append(tr) simulation.update_reporters.append(mr) simulation.update_reporters.append(nr) # Regular MD step simulation.step(1) # Update the titration states using the uniform proposal niters = 3 for x in range(niters): simulation.update(1) n_total_states = np.product( [len(group) for group in driver.titrationGroups]) assert (len(ncfile["Protons/Titration/update"][:]) == n_total_states * niters), "The wrong number of updates were recorded" work_values = np.split(ncfile["Protons/NCMC/total_work"][:], niters) init_states = ncfile["Protons/NCMC/initial_state"][:, :] assert np.all( init_states == 0), "States should all be zero at the start." first_run = work_values[0] assert np.all(np.unique(first_run) == np.sort( first_run)), "No work values should be duplicated." # Since instanteneous switching is used, this should be true for x in range(1, niters): assert np.all( np.isclose(work_values[x], first_run)), "Work should be equal for all states." # Switch state driver.set_titration_state(0, 3, updateContextParameters=True, updateIons=True) driver.set_titration_state(1, 1, updateContextParameters=True, updateIons=True) simulation.update(1) assert (ncfile["Protons/NCMC/initial_state"][-n_total_states, 0] == 3 ), "Initial state was not changed correctly." assert (ncfile["Protons/NCMC/initial_state"][-n_total_states, 1] == 1 ), "Initial state was not changed correctly." work_values = np.split(ncfile["Protons/NCMC/total_work"][:], niters + 1) assert not np.all( np.isclose(work_values[0], work_values[-1]) ), "Work values starting from different state should differ." return
def test_create_importance_sampling(self): """Instantiate a ConstantPHSimulation at 300K/1 atm for a small peptide using importance sampling.""" pdb = app.PDBxFile( get_test_data("glu_ala_his-solvated-minimized-renamed.cif", "testsystems/tripeptides")) forcefield = app.ForceField("amber10-constph.xml", "ions_tip3p.xml", "tip3p.xml") system = forcefield.createSystem( pdb.topology, nonbondedMethod=app.PME, nonbondedCutoff=1.0 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005, ) temperature = 300 * unit.kelvin integrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=False, ) ncmcintegrator = GBAOABIntegrator( temperature=temperature, collision_rate=1.0 / unit.picoseconds, timestep=2.0 * unit.femtoseconds, constraint_tolerance=1.0e-7, external_work=True, ) compound_integrator = mm.CompoundIntegrator() compound_integrator.addIntegrator(integrator) compound_integrator.addIntegrator(ncmcintegrator) pressure = 1.0 * unit.atmosphere system.addForce(mm.MonteCarloBarostat(pressure, temperature)) driver = ForceFieldProtonDrive( temperature, pdb.topology, system, forcefield, ["amber10-constph.xml"], pressure=pressure, perturbations_per_trial=0, sampling_method=SamplingMethod.IMPORTANCE, ) simulation = app.ConstantPHSimulation( pdb.topology, system, compound_integrator, driver, platform=self._default_platform, ) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(temperature) # Regular MD step simulation.step(1) # Update the titration states using the uniform proposal simulation.update(1) # Total states is 15 but proposing the same state as current does not get added to statistics. assert simulation.drive.nattempted == 14, "Not enough switch were attempted." assert simulation.drive.naccepted == 0, "No acceptance should have occurred." assert (simulation.drive.nattempted == simulation.drive.nrejected ), "The rejection count should match the number of attempts" print("Done!")