Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renaming and moving some of the protocol settings #689

Merged
merged 45 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
189815e
Initial commit to rename protocol settings
hannahbaumann Jan 17, 2024
7a4266e
more settings changes
hannahbaumann Jan 18, 2024
1ed1ea9
Transfer changes in AlchemicalSamplerSettings to different protocols
hannahbaumann Jan 18, 2024
a16a91e
Change n_steps in protocols
hannahbaumann Jan 18, 2024
190eec9
Propagate changes in OutputSettings to protocols and tests
hannahbaumann Jan 18, 2024
eb238e3
change validator
hannahbaumann Jan 18, 2024
d499356
fixes new settings
hannahbaumann Jan 18, 2024
768b4b3
small changes
hannahbaumann Jan 19, 2024
d7145d8
changes protocol_repeats
hannahbaumann Jan 19, 2024
ff84000
add values to validators
hannahbaumann Jan 19, 2024
2566438
small fix
hannahbaumann Jan 19, 2024
b22c51a
change doc string minimum iterations
hannahbaumann Jan 19, 2024
2dd0faa
more renaming online_analysis to real_time and pep8 fixes
hannahbaumann Jan 19, 2024
b39e6e3
for MD protocol use mcmc_steps=1 since only used for testing the time…
hannahbaumann Jan 19, 2024
e55ce2c
changes softcore_LJ
hannahbaumann Jan 24, 2024
4d08133
Fixes protocol_repeats
hannahbaumann Jan 25, 2024
1d6f9c7
Fix get_integrator
hannahbaumann Jan 25, 2024
b5bca0d
small fixes
hannahbaumann Jan 25, 2024
a3f72d1
Move remove_com to IntegratorSettings
hannahbaumann Jan 25, 2024
ad8170f
more small fixes
hannahbaumann Jan 25, 2024
aef9156
Plain MD protocol move n_repeats from RepeatSettings to ProtocolSetti…
hannahbaumann Jan 25, 2024
c83a3c9
small fixes
hannahbaumann Jan 25, 2024
c20f5b6
Larger settings changes, suggestions
hannahbaumann Jan 26, 2024
573f271
Change unit early_termination_target_error to kcal/mol
hannahbaumann Jan 30, 2024
990667c
Merge branch 'main' into rename_settings
richardjgowers Feb 1, 2024
4a73dff
updates for new Settings
richardjgowers Feb 2, 2024
55981bb
document dev scripts for generating jsons
richardjgowers Feb 5, 2024
60a42bc
fixup usage of 'sampler_settings' in AFE base
richardjgowers Feb 5, 2024
c8acd48
clean up some imports
richardjgowers Feb 5, 2024
3aa4581
use convert_steps_per_iteration in afe base
richardjgowers Feb 5, 2024
238bedf
works on validators and unit conversions
richardjgowers Feb 5, 2024
940424f
fixup on unit conversion
richardjgowers Feb 5, 2024
e0fabfe
remove commented out SamplerSettings block
richardjgowers Feb 5, 2024
6db0c53
added tests for settings_validation conversions
richardjgowers Feb 5, 2024
8bc76b1
got kT conversion upside down
richardjgowers Feb 5, 2024
0b858df
small fixups for new settings
richardjgowers Feb 5, 2024
0fa3995
update result jsons for tests
richardjgowers Feb 5, 2024
03c4a17
shorten AHFE time in dev scripts
richardjgowers Feb 5, 2024
8457b78
Merge branch 'main' into rename_settings
richardjgowers Feb 5, 2024
5f25fd4
shorten AHFE time in dev scripts
richardjgowers Feb 5, 2024
fcf5735
update openfecli test files for new settings
richardjgowers Feb 6, 2024
cc3e22e
revert changes to gen-serialized-results.py
richardjgowers Feb 6, 2024
ae5374e
update away from nose test style
richardjgowers Feb 6, 2024
8c84c7b
fixup LambdaSettings docstrings
richardjgowers Feb 6, 2024
2a948cc
remove doc stubs for removed settings
richardjgowers Feb 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 67 additions & 42 deletions openfe/protocols/openmm_afe/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
)
from openfe.protocols.openmm_afe.equil_afe_settings import (
SolvationSettings,
AlchemicalSamplerSettings, OpenMMEngineSettings,
IntegratorSettings, SimulationSettings, LambdaSettings,
MultiStateSimulationSettings, OpenMMEngineSettings,
IntegratorSettings, LambdaSettings, OutputSettings,
ThermoSettings,
)
from openfe.protocols.openmm_rfe._rfe_utils import compute
from ..openmm_utils import (
Expand Down Expand Up @@ -234,10 +235,11 @@ def _handle_settings(self):
* solvation_settings : SolvationSettings
* alchemical_settings : AlchemicalSettings
* lambda_settings : LambdaSettings
* sampler_settings : AlchemicalSamplerSettings
* sampler_settings : MultiStateSimulationSettings
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to have sampler_settings here of could the simulations_settings just be the MultiStateSimulationsSettings?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove both sampler_settings and system_settings

* engine_settings : OpenMMEngineSettings
* integrator_settings : IntegratorSettings
* simulation_settings : SimulationSettings
* output_settings: OutputSettings

Settings may change depending on what type of simulation you are
running. Cherry pick them and return them to be available later on.
Expand Down Expand Up @@ -270,15 +272,14 @@ def _get_system_generator(
system_generator : openmmforcefields.generator.SystemGenerator
System Generator to parameterise this unit.
"""
ffcache = settings['simulation_settings'].forcefield_cache
ffcache = settings['output_settings'].forcefield_cache
if ffcache is not None:
ffcache = self.shared_basepath / ffcache

system_generator = system_creation.get_system_generator(
forcefield_settings=settings['forcefield_settings'],
thermo_settings=settings['thermo_settings'],
integrator_settings=settings['integrator_settings'],
system_settings=settings['system_settings'],
thermo_settings=settings['thermo_settings'],
cache=ffcache,
has_solvent=solvent_comp is not None,
)
Expand Down Expand Up @@ -537,7 +538,7 @@ def _get_reporter(
self,
topology: app.Topology,
positions: openmm.unit.Quantity,
simulation_settings: SimulationSettings,
output_settings: OutputSettings,
) -> multistate.MultiStateReporter:
"""
Get a MultistateReporter for the simulation you are running.
Expand All @@ -546,8 +547,8 @@ def _get_reporter(
----------
topology : app.Topology
A Topology of the system being created.
simulation_settings : SimulationSettings
Settings for the simulation.
output_settings: OutputSettings
Output settings for the simulations

Returns
-------
Expand All @@ -557,16 +558,16 @@ def _get_reporter(
mdt_top = mdt.Topology.from_openmm(topology)

selection_indices = mdt_top.select(
simulation_settings.output_indices
output_settings.output_indices
)

nc = self.shared_basepath / simulation_settings.output_filename
chk = simulation_settings.checkpoint_storage
nc = self.shared_basepath / output_settings.output_filename
chk = output_settings.checkpoint_storage_filename

reporter = multistate.MultiStateReporter(
storage=nc,
analysis_particle_indices=selection_indices,
checkpoint_interval=simulation_settings.checkpoint_interval.m,
checkpoint_interval=output_settings.checkpoint_interval.m,
checkpoint_storage=chk,
)

Expand All @@ -577,7 +578,7 @@ def _get_reporter(
mdt_top.subset(selection_indices),
)
traj.save_pdb(
self.shared_basepath / simulation_settings.output_structure
self.shared_basepath / output_settings.output_structure
)

return reporter
Expand Down Expand Up @@ -614,38 +615,46 @@ def _get_ctx_caches(

return energy_context_cache, sampler_context_cache

@staticmethod
def _get_integrator(
self,
integrator_settings: IntegratorSettings
integrator_settings: IntegratorSettings,
simulation_settings: MultiStateSimulationSettings
) -> openmmtools.mcmc.LangevinDynamicsMove:
"""
Return a LangevinDynamicsMove integrator

Parameters
----------
integrator_settings : IntegratorSettings
simulation_settings : MultiStateSimulationSettings

Returns
-------
integrator : openmmtools.mcmc.LangevinDynamicsMove
A configured integrator object.
"""
# TODO: Check this is correct
tpi_fs = simulation_settings.time_per_iteration.to(unit.femtosecond).m
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be using whatever got added to openmm_utils?

ts_fs = integrator_settings.timestep.to(unit.femtosecond).m
steps_per_iteration = int(round(tpi_fs / ts_fs))

integrator = openmmtools.mcmc.LangevinDynamicsMove(
timestep=to_openmm(integrator_settings.timestep),
collision_rate=to_openmm(integrator_settings.collision_rate),
n_steps=integrator_settings.n_steps.m,
collision_rate=to_openmm(integrator_settings.langevin_collision_rate),
n_steps=steps_per_iteration,
reassign_velocities=integrator_settings.reassign_velocities,
n_restart_attempts=integrator_settings.n_restart_attempts,
constraint_tolerance=integrator_settings.constraint_tolerance,
)

return integrator

@staticmethod
def _get_sampler(
self,
integrator: openmmtools.mcmc.LangevinDynamicsMove,
reporter: openmmtools.multistate.MultiStateReporter,
sampler_settings: AlchemicalSamplerSettings,
simulation_settings: MultiStateSimulationSettings,
thermo_settings: ThermoSettings,
cmp_states: list[ThermodynamicState],
sampler_states: list[SamplerState],
energy_context_cache: openmmtools.cache.ContextCache,
Expand All @@ -660,8 +669,10 @@ def _get_sampler(
The simulation integrator.
reporter : openmmtools.multistate.MultiStateReporter
The reporter to hook up to the sampler.
sampler_settings : AlchemicalSamplerSettings
simulation_settings : MultiStateSimulationSettings
Settings for the alchemical sampler.
thermo_settings : ThermoSettings
Thermodynamic settings
cmp_states : list[ThermodynamicState]
A list of thermodynamic states to sample.
sampler_states : list[SamplerState]
Expand All @@ -676,30 +687,37 @@ def _get_sampler(
sampler : multistate.MultistateSampler
A sampler configured for the chosen sampling method.
"""
rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations(
simulation_settings=simulation_settings,
)
et_target_err = settings_validation.convert_target_error(
thermo_settings=thermo_settings,
simulation_settings=simulation_settings,
)

# Select the right sampler
# Note: doesn't need else, settings already validates choices
if sampler_settings.sampler_method.lower() == "repex":
if simulation_settings.sampler_method.lower() == "repex":
sampler = multistate.ReplicaExchangeSampler(
mcmc_moves=integrator,
online_analysis_interval=sampler_settings.online_analysis_interval,
online_analysis_target_error=sampler_settings.online_analysis_target_error.m,
online_analysis_minimum_iterations=sampler_settings.online_analysis_minimum_iterations
online_analysis_interval=rta_its,
online_analysis_target_error=et_target_err,
online_analysis_minimum_iterations=rta_min_its
)
elif sampler_settings.sampler_method.lower() == "sams":
elif simulation_settings.sampler_method.lower() == "sams":
sampler = multistate.SAMSSampler(
mcmc_moves=integrator,
online_analysis_interval=sampler_settings.online_analysis_interval,
online_analysis_minimum_iterations=sampler_settings.online_analysis_minimum_iterations,
flatness_criteria=sampler_settings.flatness_criteria,
gamma0=sampler_settings.gamma0,
online_analysis_interval=rta_its,
online_analysis_minimum_iterations=rta_min_its,
flatness_criteria=simulation_settings.sams_flatness_criteria,
gamma0=simulation_settings.sams_gamma0,
)
elif sampler_settings.sampler_method.lower() == 'independent':
elif simulation_settings.sampler_method.lower() == 'independent':
sampler = multistate.MultiStateSampler(
mcmc_moves=integrator,
online_analysis_interval=sampler_settings.online_analysis_interval,
online_analysis_target_error=sampler_settings.online_analysis_target_error.m,
online_analysis_minimum_iterations=sampler_settings.online_analysis_minimum_iterations
online_analysis_interval=rta_its,
online_analysis_target_error=et_target_err,
online_analysis_minimum_iterations=rta_min_its,
)

sampler.create(
Expand Down Expand Up @@ -741,7 +759,10 @@ def _run_simulation(
if not a dry run.
"""
# Get the relevant simulation steps
mc_steps = settings['integrator_settings'].n_steps.m
mc_steps = settings_validation.convert_steps_per_iteration(
simulation_settings=settings['simulation_settings'],
integrator_settings=settings['integrator_settings'],
)

equil_steps = settings_validation.get_simsteps(
sim_length=settings['simulation_settings'].equilibration_length,
Expand Down Expand Up @@ -793,8 +814,8 @@ def _run_simulation(
reporter.close()

# clean up the reporter file
fns = [self.shared_basepath / settings['simulation_settings'].output_filename,
self.shared_basepath / settings['simulation_settings'].checkpoint_storage]
fns = [self.shared_basepath / settings['output_settings'].output_filename,
self.shared_basepath / settings['output_settings'].checkpoint_storage_filename]
for fn in fns:
os.remove(fn)

Expand Down Expand Up @@ -878,7 +899,7 @@ def run(self, dry=False, verbose=True,
# 11. Create the multistate reporter & create PDB
reporter = self._get_reporter(
omm_topology, positions,
settings['simulation_settings'],
settings['output_settings'],
)

# Wrap in try/finally to avoid memory leak issues
Expand All @@ -889,11 +910,15 @@ def run(self, dry=False, verbose=True,
)

# 13. Get integrator
integrator = self._get_integrator(settings['integrator_settings'])
integrator = self._get_integrator(
settings['integrator_settings'],
settings['simulation_settings'],
)

# 14. Get sampler
sampler = self._get_sampler(
integrator, reporter, settings['sampler_settings'],
integrator, reporter, settings['simulation_settings'],
settings['thermo_settings'],
cmp_states, sampler_states,
energy_ctx_cache, sampler_ctx_cache
)
Expand Down Expand Up @@ -925,8 +950,8 @@ def run(self, dry=False, verbose=True,
del integrator, sampler

if not dry:
nc = self.shared_basepath / settings['simulation_settings'].output_filename
chk = settings['simulation_settings'].checkpoint_storage
nc = self.shared_basepath / settings['output_settings'].output_filename
chk = settings['output_settings'].checkpoint_storage_filename
return {
'nc': nc,
'last_checkpoint': chk,
Expand Down
Loading
Loading