From 61732ae9282b464a1119e98ba4fddc92aff838af Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sat, 10 Feb 2024 20:39:24 +0000 Subject: [PATCH 01/11] temporary halfway point as we fix checkpointing --- devtools/data/gen-serialized-results.py | 5 + openfe/protocols/openmm_afe/base.py | 116 +++++++++++++++--- .../openmm_afe/equil_afe_settings.py | 23 ++++ .../openmm_afe/equil_solvation_afe_method.py | 37 ++++++ .../openmm_afe/AHFEProtocol_json_results.gz | Bin 35604 -> 45466 bytes .../tests/protocols/test_openmm_afe_slow.py | 17 ++- .../test_solvation_afe_tokenization.py | 4 +- 7 files changed, 175 insertions(+), 27 deletions(-) diff --git a/devtools/data/gen-serialized-results.py b/devtools/data/gen-serialized-results.py index ccc5d7285..688783b29 100644 --- a/devtools/data/gen-serialized-results.py +++ b/devtools/data/gen-serialized-results.py @@ -81,8 +81,13 @@ def generate_md_json(smc): def generate_ahfe_json(smc): settings = AbsoluteSolvationProtocol.default_settings() + settings.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond + settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond + settings.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond settings.solvent_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_simulation_settings.production_length = 500 * unit.picosecond + settings.vacuum_equil_simulation_settings.equilibration_length = 10 * unit.picosecond + settings.vacuum_equil_simulation_settings.production_length = 10 * unit.picosecond settings.vacuum_simulation_settings.equilibration_length = 10 * unit.picosecond settings.vacuum_simulation_settings.production_length = 1000 * unit.picosecond settings.lambda_settings.lambda_elec = [0.0, 0.25, 0.5, 0.75, 1.0, 1.0, diff --git a/openfe/protocols/openmm_afe/base.py b/openfe/protocols/openmm_afe/base.py index d1cb29bb2..8d9ad2a63 100644 --- a/openfe/protocols/openmm_afe/base.py +++ b/openfe/protocols/openmm_afe/base.py @@ -57,6 +57,7 @@ ThermoSettings, ) from openfe.protocols.openmm_rfe._rfe_utils import compute +from openfe.protocols.openmm_md.plain_md_methods import PlainMDProtocolUnit from ..openmm_utils import ( settings_validation, system_creation, multistate_analysis @@ -147,37 +148,108 @@ def _get_alchemical_indices(omm_top: openmm.Topology, return atom_ids - @staticmethod - def _pre_minimize(system: openmm.System, - positions: omm_unit.Quantity) -> npt.NDArray: + def _pre_equilibrate( + self, + system: openmm.System, + topology: openmm.app.Topology, + positions: omm_unit.Quantity, + settings: dict[str, SettingsBaseModel], + dry: bool + ) -> None: """ - Short CPU minization of System to avoid GPU NaNs + Run a non-alchemical equilibration to get a stable system. Parameters ---------- system : openmm.System - An OpenMM System to minimize. - positionns : openmm.unit.Quantity + An OpenMM System to equilibrate. + topologY : openmm.app.Topology + OpenMM Topology of the System. + positions : openmm.unit.Quantity Initial positions for the system. + settings : dict[str, SettingsBaseModel] + A dictionary of settings objects. Expects the + following entries: + * `engine_settings` + * `thermo_settings` + * `integrator_settings` + * `equil_simulation_settings` + * `equil_output_settings` + dry: bool + Whether or not this is a dry run. Returns ------- - minimized_positions : npt.NDArray - Minimized positions + equilibrated_positions : npt.NDArray + Equilibrated system positions """ - integrator = openmm.VerletIntegrator(0.001) - context = openmm.Context( - system, integrator, - openmm.Platform.getPlatformByName('CPU'), + # Prep the simulation object + platform = compute.get_openmm_platform( + settings['engine_settings'].compute_platform + ) + + integrator = openmm.LangevinMiddleIntegrator( + to_openmm(settings['thermo_settings'].temperature), + to_openmm(settings['integrator_settings'].langevin_collision_rate), + to_openmm(settings['integrator_settings'].timestep), + ) + + simulation = openmm.app.Simulation( + topology=topology, + system=system, + integrator=integrator, + platform=platform, ) - context.setPositions(positions) - # Do a quick 100 steps minimization, usually avoids NaNs - openmm.LocalEnergyMinimizer.minimize( - context, maxIterations=100 + + # Get the necessary number of steps + equil_steps_nvt = settings_validation.get_simsteps( + sim_length=settings['equil_simulation_settings'].equilibration_length_nvt, + timestep=settings['integrator_settings'].timestep, + mc_steps=1, + ) + + equil_steps_npt = settings_validation.get_simsteps( + sim_length=settings['equil_simulation_settings'].equilibration_length, + timestep=settings['integrator_settings'].timestep, + mc_steps=1, + ) + + prod_steps_npt = settings_validation.get_simsteps( + sim_length=settings['equil_simulation_settings'].production_length, + timestep=settings['integrator_settings'].timestep, + mc_steps=1, + ) + + if self.verbose: + logger.info("running non-alchemical equilibration MD") + + # Don't do anything if we're doing a dry run + if dry: + return positions + + # Use the _run_MD method from the PlainMDProtocolUnit + # Should in-place modify the simulation + PlainMDProtocolUnit._run_MD( + simulation=simulation, + positions=positions, + simulation_settings=settings['equil_simulation_settings'], + output_settings=settings['equil_output_settings'], + temperature=settings['thermo_settings'].temperature, + barostat_frequency=settings['integrator_settings'].barostat_frequency, + equil_steps_nvt=equil_steps_nvt, + equil_steps_npt=equil_steps_npt, + prod_steps=prod_steps_npt, + verbose=self.verbose, + shared_basepath=self.shared_basepath, ) - state = context.getState(getPositions=True) - minimized_positions = state.getPositions(asNumpy=True) - return minimized_positions + + state = simulation.context.getState(getPositions=True) + equilibrated_positions = state.getPositions(asNumpy=True) + + # cautiously delete out contexts & integrator + del simulation.context, integrator + + return equilibrated_positions def _prepare( self, verbose: bool, @@ -236,6 +308,8 @@ def _handle_settings(self): * integrator_settings : IntegratorSettings * simulation_settings : MultiStateSimulationSettings * output_settings: OutputSettings + * equil_simulation_settings: MDSimulaltionSettings + * equil_output_settings: MDOutputSettings Settings may change depending on what type of simulation you are running. Cherry pick them and return them to be available later on. @@ -872,7 +946,9 @@ def run(self, dry=False, verbose=True, ) # 6. Pre-minimize System (Test + Avoid NaNs) - positions = self._pre_minimize(omm_system, positions) + positions = self._pre_equilibrate( + omm_system, omm_topology, positions, settings, dry + ) # 7. Get lambdas lambdas = self._get_lambda_schedule(settings) diff --git a/openfe/protocols/openmm_afe/equil_afe_settings.py b/openfe/protocols/openmm_afe/equil_afe_settings.py index b1671c5de..614dea04a 100644 --- a/openfe/protocols/openmm_afe/equil_afe_settings.py +++ b/openfe/protocols/openmm_afe/equil_afe_settings.py @@ -27,6 +27,8 @@ OpenMMEngineSettings, IntegratorSettings, OutputSettings, + MDSimulationSettings, + MDOutputSettings, ) import numpy as np @@ -172,20 +174,41 @@ def must_be_positive(cls, v): """ # Simulation run settings + vacuum_equil_simulation_settings: MDSimulationSettings + """ + Pre-alchemical vacuum simulation control settings. + + Notes + ----- + The `NVT` equilibration should be set to 0 * unit.nanosecond + as it will not be run. + """ vacuum_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the vacuum transformation. """ + solvent_equil_simulation_settings: MDSimulationSettings + """ + Pre-alchemical solvent simulation control settings. + """ solvent_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the solvent transformation. """ + vacuum_equil_output_settings: MDOutputSettings + """ + Simulation output settings for the vacuum non-alchemical equilibration. + """ vacuum_output_settings: OutputSettings """ Simulation output settings for the vacuum transformation. """ + solvent_equil_output_settings: MDOutputSettings + """ + Simulation output settings for the solvent non-alchemical equilibration. + """ solvent_output_settings: OutputSettings """ Simulation output settings for the solvent transformation. diff --git a/openfe/protocols/openmm_afe/equil_solvation_afe_method.py b/openfe/protocols/openmm_afe/equil_solvation_afe_method.py index 38bec07da..12d04f3d2 100644 --- a/openfe/protocols/openmm_afe/equil_solvation_afe_method.py +++ b/openfe/protocols/openmm_afe/equil_solvation_afe_method.py @@ -51,6 +51,7 @@ from openfe.protocols.openmm_afe.equil_afe_settings import ( AbsoluteSolvationSettings, OpenMMSolvationSettings, AlchemicalSettings, LambdaSettings, + MDSimulationSettings, MDOutputSettings, MultiStateSimulationSettings, OpenMMEngineSettings, IntegratorSettings, OutputSettings, SettingsBaseModel, @@ -419,6 +420,17 @@ def _default_settings(cls): vacuum_engine_settings=OpenMMEngineSettings(), solvent_engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), + solvent_equil_simulation_settings=MDSimulationSettings( + equilibration_length_nvt=0.1 * unit.nanosecond, + equilibration_length=0.2 * unit.nanosecond, + production_length=0.5 * unit.nanosecond, + ), + solvent_equil_output_settings=MDOutputSettings( + equil_NVT_structure='equil_nvt_structure.pdb', + equil_NPT_structure='equil_npt_structure.pdb', + production_trajectory_filename='production_equil.xtc', + log_output='equil_simulation.log', + ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=1.0 * unit.nanosecond, @@ -428,6 +440,17 @@ def _default_settings(cls): output_filename='solvent.nc', checkpoint_storage_filename='solvent_checkpoint.nc', ), + vacuum_equil_simulation_settings=MDSimulationSettings( + equilibration_length_nvt=0 * unit.nanosecond, + equilibration_length=0.2 * unit.nanosecond, + production_length=0.5 * unit.nanosecond, + ), + vacuum_equil_output_settings=MDOutputSettings( + equil_NVT_structure='pre_equil_structure.pdb', + equil_NPT_structure='equil_structure.pdb', + production_trajectory_filename='production_equil.xtc', + log_output='equil_simulation.log', + ), vacuum_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=0.5 * unit.nanosecond, @@ -634,6 +657,12 @@ def _create( "passed") raise ValueError(errmsg) + # Check vacuum equilibration MD settings is 0 ns + nvt_time = self.settings.vacuum_equil_simulation_settings.equilibration_length_nvt + if not np.allclose(nvt_time, 0 * unit.nanosecond): + errmsg = "NVT equilibration cannot be run in vacuum simulation" + raise ValueError(errmsg) + # Get the name of the alchemical species alchname = alchem_comps['stateA'][0].name @@ -746,6 +775,8 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings * simulation_settings : SimulationSettings * output_settings: OutputSettings """ @@ -759,6 +790,8 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['lambda_settings'] = prot_settings.lambda_settings settings['engine_settings'] = prot_settings.vacuum_engine_settings settings['integrator_settings'] = prot_settings.integrator_settings + settings['equil_simulation_settings'] = prot_settings.vacuum_equil_simulation_settings + settings['equil_output_settings'] = prot_settings.vacuum_equil_output_settings settings['simulation_settings'] = prot_settings.vacuum_simulation_settings settings['output_settings'] = prot_settings.vacuum_output_settings @@ -830,6 +863,8 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: OutputSettings """ @@ -843,6 +878,8 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['lambda_settings'] = prot_settings.lambda_settings settings['engine_settings'] = prot_settings.solvent_engine_settings settings['integrator_settings'] = prot_settings.integrator_settings + settings['equil_simulation_settings'] = prot_settings.solvent_equil_simulation_settings + settings['equil_output_settings'] = prot_settings.solvent_equil_output_settings settings['simulation_settings'] = prot_settings.solvent_simulation_settings settings['output_settings'] = prot_settings.solvent_output_settings diff --git a/openfe/tests/data/openmm_afe/AHFEProtocol_json_results.gz b/openfe/tests/data/openmm_afe/AHFEProtocol_json_results.gz index f69eb7ebf306863f88e4ffb373b494c71175234a..8ba5caef190656c04376c00fa636109741008eab 100644 GIT binary patch literal 45466 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

;e~@KWq#8lrDEz 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 YCgcfzLjnNb-(Y|%?qc~WUU0yF0iVUr1^@s6 literal 35604 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" @pytest.fixture() @@ -85,7 +85,7 @@ def test_key_stable(self): class TestAbsoluteSolvationProtocolResult(GufeTokenizableTestsMixin): cls = openmm_afe.AbsoluteSolvationProtocolResult - key = "AbsoluteSolvationProtocolResult-55ac1971317176d6e84549601d1eed5e" + key = "AbsoluteSolvationProtocolResult-c1e7524ca8cda3921c2cbd5b512d1cf0" repr = f"<{key}>" @pytest.fixture() From 1f61e9a75bb30f83b78a284d69bc8ef76f73fd65 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 11 Feb 2024 10:58:10 +0000 Subject: [PATCH 02/11] fix MD protocol checkpointing --- .../protocols/openmm_md/plain_md_methods.py | 60 +++++++++++-------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/openfe/protocols/openmm_md/plain_md_methods.py b/openfe/protocols/openmm_md/plain_md_methods.py index 9aa96ba2a..4876d192f 100644 --- a/openfe/protocols/openmm_md/plain_md_methods.py +++ b/openfe/protocols/openmm_md/plain_md_methods.py @@ -17,6 +17,7 @@ import openmm from openff.units import unit from openff.units.openmm import from_openmm, to_openmm +from openff.models.types import FloatQuantity import openmm.unit as omm_unit from typing import Optional from openmm import app @@ -248,13 +249,14 @@ def _run_MD(simulation: openmm.app.Simulation, positions: omm_unit.Quantity, simulation_settings: MDSimulationSettings, output_settings: MDOutputSettings, - temperature: settings.ThermoSettings.temperature, - barostat_frequency: IntegratorSettings.barostat_frequency, + temperature: FloatQuantity["kelvin"], + barostat_frequency: unit.Quantity, + timestep: FloatQuantity["femtosecond"], equil_steps_nvt: int, equil_steps_npt: int, prod_steps: int, verbose=True, - shared_basepath=None): + shared_basepath=None) -> None: """ Energy minimization, Equilibration and Production MD to be reused @@ -270,10 +272,12 @@ def _run_MD(simulation: openmm.app.Simulation, Settings for MD simulation output_settings: OutputSettingsMD Settings for output of MD simulation - temperature: settings.ThermoSettings.temperature + temperature: FloatQuantity["kelvin"] temperature setting - barostat_frequency: IntegratorSettings.barostat_frequency + barostat_frequency: unit.Quantity Frequency for the barostat + timestep: FloatQuantity["femtosecond"] + Simulation integration timestep equil_steps_nvt: int number of steps for NVT equilibration equil_steps_npt: int @@ -286,9 +290,6 @@ def _run_MD(simulation: openmm.app.Simulation, shared_basepath : Pathlike, optional Where to run the calculation, defaults to current working directory - Returns - ------- - """ if shared_basepath is None: shared_basepath = pathlib.Path('.') @@ -391,16 +392,27 @@ def _run_MD(simulation: openmm.app.Simulation, logger.info("running production phase") # Setup the reporters + + # TODO: write_interval should probably not be in units of + # timestep but time - Issue #716 + write_interval = output_settings.trajectory_write_interval.m + + checkpoint_interval = settings_validation.get_simsteps( + sim_length=output_settings.checkpoint_interval, + timestep=timestep, + mc_steps=1, + ) + simulation.reporters.append(XTCReporter( file=str(shared_basepath / output_settings.production_trajectory_filename), - reportInterval=output_settings.trajectory_write_interval.m, + reportInterval=write_interval, atomSubset=selection_indices)) simulation.reporters.append(openmm.app.CheckpointReporter( file=str(shared_basepath / output_settings.checkpoint_storage_filename), - reportInterval=output_settings.checkpoint_interval.m)) + reportInterval=checkpoint_interval)) simulation.reporters.append(openmm.app.StateDataReporter( str(shared_basepath / output_settings.log_output), - output_settings.checkpoint_interval.m, + checkpoint_interval, step=True, time=True, potentialEnergy=True, @@ -417,8 +429,6 @@ def _run_MD(simulation: openmm.app.Simulation, if verbose: logger.info(f"Completed simulation in {t1 - t0} seconds") - return None - def run(self, *, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: @@ -571,17 +581,19 @@ def run(self, *, dry=False, verbose=True, try: if not dry: # pragma: no-cover - self._run_MD(simulation, - stateA_positions, - sim_settings, - output_settings, - thermo_settings.temperature, - integrator_settings.barostat_frequency, - equil_steps_nvt, - equil_steps_npt, - prod_steps, - shared_basepath=shared_basepath, - ) + self._run_MD( + simulation, + stateA_positions, + sim_settings, + output_settings, + thermo_settings.temperature, + integrator_settings.barostat_frequency, + timestep, + equil_steps_nvt, + equil_steps_npt, + prod_steps, + shared_basepath=shared_basepath, + ) finally: From 30d4559998e907ed5a31790bcd2b36bff4bcfeb8 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 11 Feb 2024 11:26:41 +0000 Subject: [PATCH 03/11] Add extra method for time to iterations conversion --- .../openmm_utils/settings_validation.py | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/openfe/protocols/openmm_utils/settings_validation.py b/openfe/protocols/openmm_utils/settings_validation.py index 2ebf6187e..49bcc4e85 100644 --- a/openfe/protocols/openmm_utils/settings_validation.py +++ b/openfe/protocols/openmm_utils/settings_validation.py @@ -100,8 +100,54 @@ def convert_steps_per_iteration( return steps_per_iteration +def convert_time_to_iterations( + time: unit.Quantity, + time_per_iteration: unit.Quantity, + check_remainder: bool = True, +) -> tuple[int, int]: + """ + Convert a set amount of time to a number of iterations. + + This method allows one to get the number of MC iterations as used + in OpenMMTools' MultiStateSampler and MultiStatereporter. + + + Parameters + --------- + time: unit.Quantity + The time to convert in a number of MC iterations. + time_per_iteration : unit.Quantity + The amount of time which each iteration takes. + check_remainder : bool + If true, raises an error if the remainder is not zero. + + Returns + ------- + iterations : int + The number of iterations covered by the input time. + remainder : int + The remainder of the input time and time_per_iteration division. + + Raises + ------ + ValueError + If ``check_remainder`` is true and the the time does not exactly + divide by the time per iteration. + """ + time_ats = round(time.to(unit.attosecond).m) + tpi_ats = round(time_per_iteration.to(unit.attosecond).m) + + iterations, remainder = divmod(time_ats, tpi_ats) + + if check_remainder and remainder: + errmsg = "Input time does not divide exactly by the time per iteration" + raise ValueError(errmsg) + + return iterations, remainder + + def convert_real_time_analysis_iterations( - simulation_settings: MultiStateSimulationSettings, + simulation_settings: MultiStateSimulationSettings, ) -> tuple[Optional[int], Optional[int]]: """Convert time units in Settings to various other units @@ -127,21 +173,23 @@ def convert_real_time_analysis_iterations( # option to turn off real time analysis return None, None - tpi_fs = round(simulation_settings.time_per_iteration.to(unit.attosecond).m) + rta_its, rem = convert_time_to_iterations( + simulation_settings.real_time_analysis_interval, + simulation_settings.time_per_iteration, + check_remainder=False, + ) - # convert real_time_analysis time to interval - # rta_its must be number of MCMC iterations - # i.e. rta_fs / tpi_fs -> number of iterations - rta_fs = round(simulation_settings.real_time_analysis_interval.to(unit.attosecond).m) - - rta_its, rem = divmod(rta_fs, tpi_fs) if rem: raise ValueError(f"real_time_analysis_interval ({simulation_settings.real_time_analysis_interval}) " f"is not divisible by time_per_iteration ({simulation_settings.time_per_iteration})") # convert RTA_minimum_time to iterations - rta_min_fs = round(simulation_settings.real_time_analysis_minimum_time.to(unit.attosecond).m) - rta_min_its, rem = divmod(rta_min_fs, tpi_fs) + rta_min_its, rem = convert_time_to_iterations( + simulation_settings.real_time_analysis_minimum_time, + simulation_settings.time_per_iteration, + check_remainder=False, + ) + if rem: raise ValueError(f"real_time_analysis_minimum_time ({simulation_settings.real_time_analysis_minimum_time}) " f"is not divisible by time_per_iteration ({simulation_settings.time_per_iteration})") @@ -150,8 +198,8 @@ def convert_real_time_analysis_iterations( def convert_target_error_from_kcal_per_mole_to_kT( - temperature, - target_error, + temperature, + target_error, ) -> float: """Convert kcal/mol target error to kT units From b771595ea9fd6e76ce16d8e9d4b482d9df1e7b81 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 11 Feb 2024 12:00:13 +0000 Subject: [PATCH 04/11] fix multistate checkpointing --- openfe/protocols/openmm_afe/base.py | 13 +- .../protocols/openmm_rfe/equil_rfe_methods.py | 12 +- .../openmm_utils/settings_validation.py | 114 ++++++++++-------- 3 files changed, 84 insertions(+), 55 deletions(-) diff --git a/openfe/protocols/openmm_afe/base.py b/openfe/protocols/openmm_afe/base.py index 8d9ad2a63..0048e0c50 100644 --- a/openfe/protocols/openmm_afe/base.py +++ b/openfe/protocols/openmm_afe/base.py @@ -608,6 +608,7 @@ def _get_reporter( self, topology: app.Topology, positions: openmm.unit.Quantity, + simulation_settings: MultiStateSimulationSettings, output_settings: OutputSettings, ) -> multistate.MultiStateReporter: """ @@ -617,6 +618,11 @@ def _get_reporter( ---------- topology : app.Topology A Topology of the system being created. + positions : openmm.unit.Quantity + Positions of the pre-alchemical simulation system. + simulation_settings : MultiStateSimulationSettings + Multistate simulation control settings, specifically containing + the amount of time per state sampling iteration. output_settings: OutputSettings Output settings for the simulations @@ -633,11 +639,15 @@ def _get_reporter( nc = self.shared_basepath / output_settings.output_filename chk = output_settings.checkpoint_storage_filename + chk_intervals = settings_validation.convert_checkpoint_interval_to_iterations( + checkpoint_interval=output_settings.checkpoint_interval, + time_per_iteration=simulation_settings.time_per_iteration, + ) reporter = multistate.MultiStateReporter( storage=nc, analysis_particle_indices=selection_indices, - checkpoint_interval=output_settings.checkpoint_interval.m, + checkpoint_interval=chk_intervals, checkpoint_storage=chk, ) @@ -970,6 +980,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'], ) diff --git a/openfe/protocols/openmm_rfe/equil_rfe_methods.py b/openfe/protocols/openmm_rfe/equil_rfe_methods.py index 8fdcb5d00..cadf8c424 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_methods.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_methods.py @@ -828,16 +828,18 @@ def run(self, *, dry=False, verbose=True, ) # a. Create the multistate reporter - # convert checkpoint_interval from time to steps - checkpoint_fs = output_settings.checkpoint_interval.to(unit.femtosecond).m - ts_fs = integrator_settings.timestep.to(unit.femtosecond).m - checkpoint_int = int(round(checkpoint_fs / ts_fs)) + # convert checkpoint_interval from time to iterations + chk_intervals = settings_validation.convert_checkpoint_interval_to_iterations( + checkpoint_interval=output_settings.checkpoint_interval, + time_per_iteration=sampler_settings.time_per_iteration, + ) + nc = shared_basepath / output_settings.output_filename chk = output_settings.checkpoint_storage_filename reporter = multistate.MultiStateReporter( storage=nc, analysis_particle_indices=selection_indices, - checkpoint_interval=checkpoint_int, + checkpoint_interval=chk_intervals, checkpoint_storage=chk, ) diff --git a/openfe/protocols/openmm_utils/settings_validation.py b/openfe/protocols/openmm_utils/settings_validation.py index 49bcc4e85..9a3fdc415 100644 --- a/openfe/protocols/openmm_utils/settings_validation.py +++ b/openfe/protocols/openmm_utils/settings_validation.py @@ -73,53 +73,19 @@ def get_simsteps(sim_length: unit.Quantity, return sim_steps -def convert_steps_per_iteration( - simulation_settings: MultiStateSimulationSettings, - integrator_settings: IntegratorSettings, -) -> int: - """Convert time per iteration to steps - - Parameters - ---------- - simulation_settings: MultiStateSimulationSettings - integrator_settings: IntegratorSettings - - Returns - ------- - steps_per_iteration : int - suitable for input to Integrator - """ - tpi_fs = round(simulation_settings.time_per_iteration.to(unit.attosecond).m) - ts_fs = round(integrator_settings.timestep.to(unit.attosecond).m) - steps_per_iteration, rem = divmod(tpi_fs, ts_fs) - - if rem: - raise ValueError(f"time_per_iteration ({simulation_settings.time_per_iteration}) " - f"not divisible by timestep ({integrator_settings.timestep})") - - return steps_per_iteration - - -def convert_time_to_iterations( +def divmod_time( time: unit.Quantity, time_per_iteration: unit.Quantity, - check_remainder: bool = True, ) -> tuple[int, int]: """ Convert a set amount of time to a number of iterations. - This method allows one to get the number of MC iterations as used - in OpenMMTools' MultiStateSampler and MultiStatereporter. - - Parameters --------- time: unit.Quantity - The time to convert in a number of MC iterations. + The time to convert. time_per_iteration : unit.Quantity The amount of time which each iteration takes. - check_remainder : bool - If true, raises an error if the remainder is not zero. Returns ------- @@ -127,23 +93,75 @@ def convert_time_to_iterations( The number of iterations covered by the input time. remainder : int The remainder of the input time and time_per_iteration division. - - Raises - ------ - ValueError - If ``check_remainder`` is true and the the time does not exactly - divide by the time per iteration. """ time_ats = round(time.to(unit.attosecond).m) tpi_ats = round(time_per_iteration.to(unit.attosecond).m) iterations, remainder = divmod(time_ats, tpi_ats) - if check_remainder and remainder: - errmsg = "Input time does not divide exactly by the time per iteration" + return iterations, remainder + + +def convert_checkpoint_interval_to_iterations( + checkpoint_interval: unit.Quantity, + time_per_iteration: unit.Quantity, +) -> int: + """ + Get the number of iterations per checkpoint interval. + + This is necessary as our input settings define checkpoints intervals in + units of time, but OpenMMTools' MultiStateReporter requires them defined + in the number of MC intervals. + + Parameters + ---------- + checkpoint_interval : unit.Quantity + The amount of time per checkpoints written. + time_per_iteration : unit.Quantity + The amount of time each MC iteration takes. + + Returns + ------- + iterations : int + The number of iterations per checkpoint. + """ + iterations, rem = divmod_time(checkpoint_interval, time_per_iteration) + + if rem: + errmsg = (f"The amount of time per checkpoint {checkpoint_interval} " + "does not evenly divide by the amount of time per " + f"state MCM move attempt {time_per_iteration}") raise ValueError(errmsg) - return iterations, remainder + return iterations + + +def convert_steps_per_iteration( + simulation_settings: MultiStateSimulationSettings, + integrator_settings: IntegratorSettings, +) -> int: + """Convert time per iteration to steps + + Parameters + ---------- + simulation_settings: MultiStateSimulationSettings + integrator_settings: IntegratorSettings + + Returns + ------- + steps_per_iteration : int + suitable for input to Integrator + """ + steps_per_iteration, rem = divmod_time( + simulation_settings.time_per_iteration, + integrator_settings.timestep + ) + + if rem: + raise ValueError(f"time_per_iteration ({simulation_settings.time_per_iteration}) " + f"not divisible by timestep ({integrator_settings.timestep})") + + return steps_per_iteration def convert_real_time_analysis_iterations( @@ -173,10 +191,9 @@ def convert_real_time_analysis_iterations( # option to turn off real time analysis return None, None - rta_its, rem = convert_time_to_iterations( + rta_its, rem = divmod_time( simulation_settings.real_time_analysis_interval, simulation_settings.time_per_iteration, - check_remainder=False, ) if rem: @@ -184,10 +201,9 @@ def convert_real_time_analysis_iterations( f"is not divisible by time_per_iteration ({simulation_settings.time_per_iteration})") # convert RTA_minimum_time to iterations - rta_min_its, rem = convert_time_to_iterations( + rta_min_its, rem = divmod_time( simulation_settings.real_time_analysis_minimum_time, simulation_settings.time_per_iteration, - check_remainder=False, ) if rem: From 5774daede6d1e65fbd7447f24afb21c458879407 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 11 Feb 2024 12:02:30 +0000 Subject: [PATCH 05/11] Revert "temporary halfway point as we fix checkpointing" This reverts commit 61732ae9282b464a1119e98ba4fddc92aff838af. --- devtools/data/gen-serialized-results.py | 5 - openfe/protocols/openmm_afe/base.py | 116 +++--------------- .../openmm_afe/equil_afe_settings.py | 23 ---- .../openmm_afe/equil_solvation_afe_method.py | 37 ------ .../openmm_afe/AHFEProtocol_json_results.gz | Bin 45466 -> 35604 bytes .../tests/protocols/test_openmm_afe_slow.py | 17 +-- .../test_solvation_afe_tokenization.py | 4 +- 7 files changed, 27 insertions(+), 175 deletions(-) diff --git a/devtools/data/gen-serialized-results.py b/devtools/data/gen-serialized-results.py index 688783b29..ccc5d7285 100644 --- a/devtools/data/gen-serialized-results.py +++ b/devtools/data/gen-serialized-results.py @@ -81,13 +81,8 @@ def generate_md_json(smc): def generate_ahfe_json(smc): settings = AbsoluteSolvationProtocol.default_settings() - settings.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond - settings.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond - settings.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond settings.solvent_simulation_settings.equilibration_length = 10 * unit.picosecond settings.solvent_simulation_settings.production_length = 500 * unit.picosecond - settings.vacuum_equil_simulation_settings.equilibration_length = 10 * unit.picosecond - settings.vacuum_equil_simulation_settings.production_length = 10 * unit.picosecond settings.vacuum_simulation_settings.equilibration_length = 10 * unit.picosecond settings.vacuum_simulation_settings.production_length = 1000 * unit.picosecond settings.lambda_settings.lambda_elec = [0.0, 0.25, 0.5, 0.75, 1.0, 1.0, diff --git a/openfe/protocols/openmm_afe/base.py b/openfe/protocols/openmm_afe/base.py index 0048e0c50..069d7d894 100644 --- a/openfe/protocols/openmm_afe/base.py +++ b/openfe/protocols/openmm_afe/base.py @@ -57,7 +57,6 @@ ThermoSettings, ) from openfe.protocols.openmm_rfe._rfe_utils import compute -from openfe.protocols.openmm_md.plain_md_methods import PlainMDProtocolUnit from ..openmm_utils import ( settings_validation, system_creation, multistate_analysis @@ -148,108 +147,37 @@ def _get_alchemical_indices(omm_top: openmm.Topology, return atom_ids - def _pre_equilibrate( - self, - system: openmm.System, - topology: openmm.app.Topology, - positions: omm_unit.Quantity, - settings: dict[str, SettingsBaseModel], - dry: bool - ) -> None: + @staticmethod + def _pre_minimize(system: openmm.System, + positions: omm_unit.Quantity) -> npt.NDArray: """ - Run a non-alchemical equilibration to get a stable system. + Short CPU minization of System to avoid GPU NaNs Parameters ---------- system : openmm.System - An OpenMM System to equilibrate. - topologY : openmm.app.Topology - OpenMM Topology of the System. - positions : openmm.unit.Quantity + An OpenMM System to minimize. + positionns : openmm.unit.Quantity Initial positions for the system. - settings : dict[str, SettingsBaseModel] - A dictionary of settings objects. Expects the - following entries: - * `engine_settings` - * `thermo_settings` - * `integrator_settings` - * `equil_simulation_settings` - * `equil_output_settings` - dry: bool - Whether or not this is a dry run. Returns ------- - equilibrated_positions : npt.NDArray - Equilibrated system positions + minimized_positions : npt.NDArray + Minimized positions """ - # Prep the simulation object - platform = compute.get_openmm_platform( - settings['engine_settings'].compute_platform - ) - - integrator = openmm.LangevinMiddleIntegrator( - to_openmm(settings['thermo_settings'].temperature), - to_openmm(settings['integrator_settings'].langevin_collision_rate), - to_openmm(settings['integrator_settings'].timestep), - ) - - simulation = openmm.app.Simulation( - topology=topology, - system=system, - integrator=integrator, - platform=platform, + integrator = openmm.VerletIntegrator(0.001) + context = openmm.Context( + system, integrator, + openmm.Platform.getPlatformByName('CPU'), ) - - # Get the necessary number of steps - equil_steps_nvt = settings_validation.get_simsteps( - sim_length=settings['equil_simulation_settings'].equilibration_length_nvt, - timestep=settings['integrator_settings'].timestep, - mc_steps=1, - ) - - equil_steps_npt = settings_validation.get_simsteps( - sim_length=settings['equil_simulation_settings'].equilibration_length, - timestep=settings['integrator_settings'].timestep, - mc_steps=1, - ) - - prod_steps_npt = settings_validation.get_simsteps( - sim_length=settings['equil_simulation_settings'].production_length, - timestep=settings['integrator_settings'].timestep, - mc_steps=1, - ) - - if self.verbose: - logger.info("running non-alchemical equilibration MD") - - # Don't do anything if we're doing a dry run - if dry: - return positions - - # Use the _run_MD method from the PlainMDProtocolUnit - # Should in-place modify the simulation - PlainMDProtocolUnit._run_MD( - simulation=simulation, - positions=positions, - simulation_settings=settings['equil_simulation_settings'], - output_settings=settings['equil_output_settings'], - temperature=settings['thermo_settings'].temperature, - barostat_frequency=settings['integrator_settings'].barostat_frequency, - equil_steps_nvt=equil_steps_nvt, - equil_steps_npt=equil_steps_npt, - prod_steps=prod_steps_npt, - verbose=self.verbose, - shared_basepath=self.shared_basepath, + context.setPositions(positions) + # Do a quick 100 steps minimization, usually avoids NaNs + openmm.LocalEnergyMinimizer.minimize( + context, maxIterations=100 ) - - state = simulation.context.getState(getPositions=True) - equilibrated_positions = state.getPositions(asNumpy=True) - - # cautiously delete out contexts & integrator - del simulation.context, integrator - - return equilibrated_positions + state = context.getState(getPositions=True) + minimized_positions = state.getPositions(asNumpy=True) + return minimized_positions def _prepare( self, verbose: bool, @@ -308,8 +236,6 @@ def _handle_settings(self): * integrator_settings : IntegratorSettings * simulation_settings : MultiStateSimulationSettings * output_settings: OutputSettings - * equil_simulation_settings: MDSimulaltionSettings - * equil_output_settings: MDOutputSettings Settings may change depending on what type of simulation you are running. Cherry pick them and return them to be available later on. @@ -956,9 +882,7 @@ def run(self, dry=False, verbose=True, ) # 6. Pre-minimize System (Test + Avoid NaNs) - positions = self._pre_equilibrate( - omm_system, omm_topology, positions, settings, dry - ) + positions = self._pre_minimize(omm_system, positions) # 7. Get lambdas lambdas = self._get_lambda_schedule(settings) diff --git a/openfe/protocols/openmm_afe/equil_afe_settings.py b/openfe/protocols/openmm_afe/equil_afe_settings.py index 614dea04a..b1671c5de 100644 --- a/openfe/protocols/openmm_afe/equil_afe_settings.py +++ b/openfe/protocols/openmm_afe/equil_afe_settings.py @@ -27,8 +27,6 @@ OpenMMEngineSettings, IntegratorSettings, OutputSettings, - MDSimulationSettings, - MDOutputSettings, ) import numpy as np @@ -174,41 +172,20 @@ def must_be_positive(cls, v): """ # Simulation run settings - vacuum_equil_simulation_settings: MDSimulationSettings - """ - Pre-alchemical vacuum simulation control settings. - - Notes - ----- - The `NVT` equilibration should be set to 0 * unit.nanosecond - as it will not be run. - """ vacuum_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the vacuum transformation. """ - solvent_equil_simulation_settings: MDSimulationSettings - """ - Pre-alchemical solvent simulation control settings. - """ solvent_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths for the solvent transformation. """ - vacuum_equil_output_settings: MDOutputSettings - """ - Simulation output settings for the vacuum non-alchemical equilibration. - """ vacuum_output_settings: OutputSettings """ Simulation output settings for the vacuum transformation. """ - solvent_equil_output_settings: MDOutputSettings - """ - Simulation output settings for the solvent non-alchemical equilibration. - """ solvent_output_settings: OutputSettings """ Simulation output settings for the solvent transformation. diff --git a/openfe/protocols/openmm_afe/equil_solvation_afe_method.py b/openfe/protocols/openmm_afe/equil_solvation_afe_method.py index 12d04f3d2..38bec07da 100644 --- a/openfe/protocols/openmm_afe/equil_solvation_afe_method.py +++ b/openfe/protocols/openmm_afe/equil_solvation_afe_method.py @@ -51,7 +51,6 @@ from openfe.protocols.openmm_afe.equil_afe_settings import ( AbsoluteSolvationSettings, OpenMMSolvationSettings, AlchemicalSettings, LambdaSettings, - MDSimulationSettings, MDOutputSettings, MultiStateSimulationSettings, OpenMMEngineSettings, IntegratorSettings, OutputSettings, SettingsBaseModel, @@ -420,17 +419,6 @@ def _default_settings(cls): vacuum_engine_settings=OpenMMEngineSettings(), solvent_engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), - solvent_equil_simulation_settings=MDSimulationSettings( - equilibration_length_nvt=0.1 * unit.nanosecond, - equilibration_length=0.2 * unit.nanosecond, - production_length=0.5 * unit.nanosecond, - ), - solvent_equil_output_settings=MDOutputSettings( - equil_NVT_structure='equil_nvt_structure.pdb', - equil_NPT_structure='equil_npt_structure.pdb', - production_trajectory_filename='production_equil.xtc', - log_output='equil_simulation.log', - ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=1.0 * unit.nanosecond, @@ -440,17 +428,6 @@ def _default_settings(cls): output_filename='solvent.nc', checkpoint_storage_filename='solvent_checkpoint.nc', ), - vacuum_equil_simulation_settings=MDSimulationSettings( - equilibration_length_nvt=0 * unit.nanosecond, - equilibration_length=0.2 * unit.nanosecond, - production_length=0.5 * unit.nanosecond, - ), - vacuum_equil_output_settings=MDOutputSettings( - equil_NVT_structure='pre_equil_structure.pdb', - equil_NPT_structure='equil_structure.pdb', - production_trajectory_filename='production_equil.xtc', - log_output='equil_simulation.log', - ), vacuum_simulation_settings=MultiStateSimulationSettings( n_replicas=14, equilibration_length=0.5 * unit.nanosecond, @@ -657,12 +634,6 @@ def _create( "passed") raise ValueError(errmsg) - # Check vacuum equilibration MD settings is 0 ns - nvt_time = self.settings.vacuum_equil_simulation_settings.equilibration_length_nvt - if not np.allclose(nvt_time, 0 * unit.nanosecond): - errmsg = "NVT equilibration cannot be run in vacuum simulation" - raise ValueError(errmsg) - # Get the name of the alchemical species alchname = alchem_comps['stateA'][0].name @@ -775,8 +746,6 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings - * equil_simulation_settings : MDSimulationSettings - * equil_output_settings : MDOutputSettings * simulation_settings : SimulationSettings * output_settings: OutputSettings """ @@ -790,8 +759,6 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['lambda_settings'] = prot_settings.lambda_settings settings['engine_settings'] = prot_settings.vacuum_engine_settings settings['integrator_settings'] = prot_settings.integrator_settings - settings['equil_simulation_settings'] = prot_settings.vacuum_equil_simulation_settings - settings['equil_output_settings'] = prot_settings.vacuum_equil_output_settings settings['simulation_settings'] = prot_settings.vacuum_simulation_settings settings['output_settings'] = prot_settings.vacuum_output_settings @@ -863,8 +830,6 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * lambda_settings : LambdaSettings * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings - * equil_simulation_settings : MDSimulationSettings - * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: OutputSettings """ @@ -878,8 +843,6 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['lambda_settings'] = prot_settings.lambda_settings settings['engine_settings'] = prot_settings.solvent_engine_settings settings['integrator_settings'] = prot_settings.integrator_settings - settings['equil_simulation_settings'] = prot_settings.solvent_equil_simulation_settings - settings['equil_output_settings'] = prot_settings.solvent_equil_output_settings settings['simulation_settings'] = prot_settings.solvent_simulation_settings settings['output_settings'] = prot_settings.solvent_output_settings diff --git a/openfe/tests/data/openmm_afe/AHFEProtocol_json_results.gz b/openfe/tests/data/openmm_afe/AHFEProtocol_json_results.gz index 8ba5caef190656c04376c00fa636109741008eab..f69eb7ebf306863f88e4ffb373b494c71175234a 100644 GIT binary patch literal 35604 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

;e~@KWq#8lrDEz zOcQD&|Mh?qnOY`;YF|bj*z*`j7Kaf;~%yZ z8_V4ReSVF~Kyu*5yX8a(hm3kIc^7QW_y;LHRQZfIlNp=b^yqgURL%Z2KBz zPMj>QSU$QVW)3~yjBQe`43Jj;;|P`{G&(uxBT^$Jr`Jn`C@Y9#rGVZS*DKk3*OiDA z!zX3WW^Ptfv<9XOen^i;{-&Ea99IAz!TEhTapr!l9Dr=Tc`Y+;IG|ttCMiP#>0Z|k zsEU%SG?j9fHjPcvl-Qv}Ya`|1$%;Il|15bZd(JYxO>~+{d^~rP?+3>DiJM6piswr0 z&SG&Zv2!`FMPi67p*GDhJTM&X4m?-z{NBFMeYgJSiT^Rjxw&Hoz_$jx6ypQL-=~g@0bzbtXhx}pwGS1)!<-*75@|1Q? ziL}0H-4o-CqU64ZP_^~7hMmgoxLLfg7$v!2yYn$2B3gJ&ezqWJKQILJ?xChC2#MI6 z2DS*f`+~RemPvfgtB*<8nC~+bjZ3Tr0Q!ajhbzBJ3ZqbC1*un5umA@gr4H_BHj_?V zNh!&y7eq z6wp@rl#cRQ9XVr88cmJKb+0%XjaqzUv2*TNd0(mHShsbuP=UpEG9_9GAwv0L3L7YX zJe>zRT3g-u!KS15ua z0FRstTxF0qNS-^;m%tj%qOnn`YZA}wwz~UT5yO52W6!E@vg-$&F9Gg%Kd3!3LgZT9 zxF_k0rMSJy0v>f#IgQKm+}T$0JaWDYp#J&9^JMaL9vjIF8%D-nEWT-#)SQp-EVv)P zT9Le;P+b-NVz&Jd9pv8FTCLR#;#_rSQi;qe6F=Qi#!?nT zp|3sqd|@>3JCqPTF&FfJ-d^&0;s@LcGbL2@h$?l>rQu?0R4t3G_wwnxkbeF`3N zrGfRtE)v8XBRw<~j?R4cqgJ>X30?tDVgB!A>XZG{d1!92InqxPi3wZ}@BpL_BvEM~ zb1U(6A(V{4;M@sfXK@nE+?0iFXW0`*u0mjNGM-Fs&zkBAbNzndfNz>tG5ZQ=dBrah zDM;7vHIWIQmT-xtBQ7XKCXG1+4#h$Fqu|CYq3AmDmR+%@18V>UEjH;Mi(p&`*ws@m z6dOh#WA`BZ#7s}MJF&}Uz=uQRcMWvY6tsLWVzlVEe0|>b%=w}=CHpM-xK5J8T)}}e zpwIa{Y(=a=oHZ*abO13{hudZ^V{W3ZhofMw@j<$^l;^2)j4@Lv;#T;=#b2^Xl| zf@hRgMeWa^Q%H4x?JKNaJkFfwsVs!tcb+hNOfR7Z&SZjXMbq+aY!sGVXuG95ymY%> z^9}+jL~>1N&o)ybGQlS49S-~}B&J#qUKr-1_5nC zg!*AW7j)tFtNd5O-GX&U?ux!A9V>)qQYVn+J2=+=`GfLTurV}}iOiX82a0SwPpudg zIQEo^;5>T&J8R3H0Pm4{ok31$lT|a9I z3hz!P=+@6t$oE@5AJXj4+FGgmV0_N)I@DT1?!yaL!SbtQ(E`UGV&yBsw^X3+k}Jlw ziiM-y%$+2bgcr=12ruF|afnr;525tjHI_QtQa`F0Zw%r(3VxM>PWLbfnpycRt&W3o zg_}0dl0rXaN)gMh3%~bFA$C8BBH`9kUvl#!LVuR9QhTvC8$z6H1$RuA=d?8hfHcCD z=Mub{wG{gYPZB|}2CFyi2qeChWc7Vd7+pu01N-gS$h@lRFNFJo%seqJLNE}JgADW| z)pj#-KJTK(u&wW?E1c&r$)J!bcsK6Xp`n*icnRy#cv{po5s^%Y7%=bF2|k1;BA|)s zc09q?*HySRKY2~gf$5R$=u0U+apeq0VRk=OyvN^!SAKTp>IQ{pOU_9*EM4QX&)h{?C~>eh}0lKMJ=zt@#oruHmf~G8~hz z@vEkNT$UVoM>!2+i@p`c099Pc*$mIH_``-s%|r5nY(fHUozyhP*8vq>epE~ti7#>B zod)ZUFepC-qjCk(S@0M_>waP)Z$)a{Re^n^+^Ab5c*wF=#|6h~BWg89ORIpf%&W z<sCV19i+qP}n%CK!^*tTtD*tX3K+mT`0=ET3MrmMR8>u>sM)|$I#o%{D)XYJ>= z_jwT)b$ChG z{lPZxI<+166p|17)-~M37(oQ^#kl+qez0x8WB(^x3D>~5n-n3V_vGv%0)&J+T6zu9 z*^3)hUFuPDtuRy3`{*29^DBuXI(IgVXx0y5=1S*D_2s6L_6`GX?2KiH@1li+&Bl`RfK7|eA1B(t4VE}?-XF-Rhqyl{kYaT#!xrpe7dHL|VI8Vi8$)Dr zmSy>i7@b6RX#t8KAk#MZ10-F5%KJIg(JNyC?!fw0MOv0+}u0%xe!CxKpYUIEDk zh}|<7HV4Q8O}4OvzAnI9^D+rrzUclr6hyhvPr;$XTt1&lY(?k1HefE zQu%80gvwl(+6*;?RsCNuW zxaYi^aZCb0ElC>Lgon%3)P+qBqOzBOhontM8&N^mP7s35o~!$AABm&^`=nxNR7sST z7Q3cqq|%i>heUTwh!sll0EK1!MO&kB$R z3@F|bP%=-)t^70u{w1Bg5vDwn#OVl#`sPRCz1Qoi3D~+~8FQP0JnDdax5f#J*-N+D z!^|=R_G|3}EI4u&+@y(g>5rj_h}eP1;OemnAX$MQy0PG;Ap--K<{T!*XpSU1`+`tW zfxSy}e{~`bFj|Mp*0+(N*DafsGsY4TA%#^%!9=mCOO8PaQh?gHsh!$^&?V*Hd?cW_ z?)=a>oJZ+j1u=!C)bmp8P^wH;Mw9gtjxDClV(i_isrexIDIZLAkletRzS9tsAg=`` zq!<*mpVMqT*A+kMmnPB5l0Za%R37J3wCHfHM1wavb!{9D$)X#3{S}9}i19Ga5HPfR z&(AV*)Ia{Z+2rd8&YXdic%@TAhidomRXtYb&QMpD3B;tWqmVX`N4$_z3tHKfp2A_6 zT{QW)7z!6%#5FtM$^Ls3!nyRuXbm542BbWK7j1?0oDBQb&2@%1x61%Q&fbvQn`^s* zp{`uC`v_9bi?^io+u+*5Ocd;WlUrsbha@52GjQn7$BxGA$Pe5$*J!N>@Mgm&M+H3r z0z>ecaB5+iZSy`Gt^EGaUwYn?ORvZSJMfz9+4!HdAQEWq zSw#<=4)jV&f@ZIUEgOUl$9dFG7O2|j=Vjf`j0HTzkyTZQ5Qf1EQ~R)*lum$2_cj$$ zS;xd63YdS?G8Vs_TsqcYGJnHZ;Nt%cW3g5K1;)bBP5n18_R{db!q~vj_v8Hk0gMGK z`wti^3_td-Ft+*MV66Q&jE#%=HyGRN^dB&`w(Y;b*nY+TYcO`b{{IAHBX9nKv2MdP z8i*Eu!C0981Y;S0QZgL>1!FanzC_knVK`E*Sh~TGc;DpC1Ga}#4~eqRnaHSy3B50r zz4)OMlGW_y;Jk+6)dLE7ZNO9FEY+0!mD&PC-*rCQwY)*l@;rPS5#Og3Z^Ac^Mr+;9 zHTn?~TERba$QViz$D)h459e@ye!{(3&~MnMTs9tE)#lLI%69Edrb_x)jkm2JxO@A&B@t(%HL&f1|UKDrk(ezobrG z5}^BH5?Sa;{Y3aI+ufB&45ug&+Srq|-Ny6oi9oBVkpmF#?oEmmZ_nwz8Lgi>REVR`tR7XeVqDTjIj#WPK<+{$aYLN-g8lg7#2%ST9uU zo^EMM++e(UCLQ5YeEG}OaaM+*!O8b-aytk%>zcX2#sQc=|E#QyZc5W68^iPeuf(uJ z+e=vX|5%Cv|2xHSi1KeK2E`T9coxbVb&zod8SVi|uU6q=&v9Z_Ls!qb9DFH}XT*@h z0}J1z_h~E`*tY`rbc;SCEEl#LR) zAr}}S1@5vPlOfMZh_FWRxQ@;j^xR5Ra)LTQ60i!m%IT+C&)`M zn30VnDb^=3RhVeReJ&0xhgLvKD!|cTECv|%KW3C_H$-Rz&UE2DBtZCr zEe*C3F`w!^nn_g@_d)Nw8p4f2cQ7OzlU6r@1;UD3!Q=oR+sW%Vc=bOCji?`d!CrV% zFtvzTF^O1Y%zsrE5h%EOqb7r%%)o-OK{RLDfgL-S%~Pwe4FlE8`B2|@3IEig1o#DW zK3w4Kr{1zi(*Z?eZ~WefOfjvEN}VkQ^V5!>V#j&*OKNuRL01C$iU@KLum=HQLZ=CA zWd$(Vl;Gi&ei6w39<r}BsyBv#~Uh^t={!O*JWVPSHCwB}Iv@H&b!AwBN zda+2hLz&dV0Y+CbdUuR_Il1aMU)b06%xTzz*kdMD-J# z$5_;N$#slQz1Yw+TjewEoTzp$cNe?7a*GjQfe`iumb9Q>Jp&~#c@Fv#0?e!UfB^9< zCl#jqs^EkwxRLLHdnJaM+|>zUOnw|ExnjDOu5t=gPT`+yy*KwFldOEiVaJD^D_qIL z6X>Z+`hT>%7LaIC7H!q^sk<$?=u)={~AhuPCQu1z-6oh(trls9xX>c>esOL79HGxPe5R~TY zY~e_eRdq;Fy3JF58T0lBVA3S_`#`>*8`Q$nbuV}dZQAMwUY4U!oMRpzu>kWau6=vO z_I$}V=$dca#f5-!S6)Heyx_Wb#<066o&8_?K1uPp2sPD^>-IMjla6wHuGJk<63l)u zh_vT;F2;^PiSky5+5m?yB~vF#%2blm3@vxCZ{cCA)^zrN&3o#cjr)SSL_Fc z9<}IJfS8}#Q|OohU>YNCEAAo*gyw@Of_wTbQK2^wR|2W!=>64%%oYS3STTFgQp#MY z61%>xy5sVwmH~N0*^|qBu9t#JZ;;nLVVZtY&i6IUEy0x=4M{6J8g-Y=3AvU7^SA?# zYcUN;c3ycra&9zpxUPTE41hZl1i!!0jLa!ht0D#3W(P7K!5#fnJY|8I*xDe${6XIh zkJ>!-^;}eV@&P-SzWExVB_J~{jIYk0lD}nW`~khxs0tuVVNiUI^O9<18~O9ny1U_C z#fD}GaNU!J=MPff)&#{X&)CCqUno+QFx~@2??lD6X0CBkI?D!KMd$wb&HTtC>bQ*{ z#>n;nAy$m37O78E?uu=~X6>ab^ugZo%;iTcQq5}){Tg|Quv0;lHx36zF=K;6W(f%& z?Rb?9SGgD{f6Sk5e`QBx99#pZz;5t;RwoK0fg2PlCE9TgJFnvi4ldfF(X^7$@v#PIlB5~O(OdXp`@-ha$ zdlaj@gK*d)I$jfW2)n)qS`&sPpxK8n(z~E+h7~Y@C|AB|utEFTYebV|R2?YPpS&Jj zMi+RXM^f3EQh!qU-gVm?%lI7~(7ds%V*8aW_PC%rODXq4UEf}1*Xfym0Wa9M6Dpw<-JX#~>V%P&=rl4Mwh(+ad+c9sB#nxv4A> z7KDb*7^20ZOe0*gheli0g`OcY^%E?<7*ka)_2JTrfH+DzMTYue4Xq;0WhxosUAzvx z#SB`anmOl28O9+Q7V$jZ-v9@-0Y(eglPn5coLiky6^I|~&a|v$lnA6`1{P)SUv@6iI~Ch6BU$_Z86Ti6^e2E|OCqskdq8 zPce1sRA{uPo^^A&g{XAUQJJgshA!j6@**B>OHEg5tb(_NQ}yK4>hD$ZN*uTqrP|BX zDxuP(3e{bS4MbxlX30>;qo`3-nJz^ho}5?wU_Il_fU3LxR3_G2+c7l^8Iq+15;Hv6 zQfVt~KjQu_`@-jc%f8^@|0es|tQ>|MG_g#xth4nxf$uz7ZLZFArpzy~h)++zC--}k zo`n7#Ua%(xeMo%`J*6@u3t?89x}_YYRhKo<)>vy)TXPrNoN~QM&%?0YWfT$qaLgE@ znv7gXBNc03KuE8`8ZlY;8@NyuWW5iWxLlZVEBR|ZCa1Z4o_hg4X#E}QL}b4uE*@=F zX6MC9kNNRzx@zZ(Gt-!mPxHfLThzbkO!kkZ7T-hIo_LBV(5@0Olu)(_CEkRCTG3uG zicnjxyEH8xzOWoo9qIGWA`Xv}Hys#@IdUccSEb%dsO`_cI+qg1-v1;PGXEeJai1Z7 zBNl~EHkX9{wn+2{e-R5ew|^rRp=cx1+hxB0nOML%h5nsbj074(v;Biu@caMdC+GrM zwEdU$7&`4}-qMf6((m<{FxB7IV+;RjJ%$LYwFY$Vo&&|vn+O6o>Ovaz@ZGgU#b_Z5 z!cRs36P^t%>~)Hbc^d#iavOuLH2)Z8}p6lYw zHo%IRU&8&t&Qo-eB-3uZhA%5-1tW_y!7haa0r%+1i-(B{2j5Y!lN7Hp;V+vAPH6*9 zR4%1<&=Q$s)LUQd5GY5Z@4TvLK_w?f0;7S7iDF%unU8Kq1hs!zIdcM~U1)LsMo4)) z0j#^dK-zN*ZUXb2U)AhaXjDy5QTTZy%`FL&v(Ec3Axp{n>4v{8$3{SCsr}9W2g@X*Gytt+Fbz^40ZO?Nz`wyi)1A^yqfOJ zmR`29^pb;`_N;Sa89Nob0=Nlp{`1<8OoHpY&TmPdeRXEIBk&UN0yfYsqQLKD9#Ahh zoRk)6jtu^v@ybBIr=04ak|ecqzXwPfTmH!^{#1yWs-a&4b-M!&S#NnTQM;70u;b%S zE{y7A3%GHDSF?ZpgHe#yzHMDf@#77CJU66Kh=GpMtY#D+z-YSKG3Z=goOTq?D6vXO z!32{_CY=AXSNVJrwt5m|f>-HenY^BAQPSzmM9@_LSwV#uwg)^nt{=TtcJH5He^ok; zWkMV@n@(2tR?_y;>P-CR1(_&a!8y^$Lgsb367Z`{b`frM?IdbE=w7^Qe{f=gK$gcO z^aoFd6LE72_=M>>*j|v8VSmF7yz7^?T+T$qWr9zRIkRLoguKsgaE^c7VPmtV$cH|W z6hG*x3gvg6vLcW2XC8S|TzT*UJXzu41O-4N%Ky$(ngWo&u()$o2(6++LY#qZl|N`* zkqci&pba1oMdgL@%8rJEVn}lZRqhD1w*T@J|Kxz{=i5jKL`l$x!5BbQ)a`b}Byu3B<*X7Le6r&g*=Xz#0)=`P_l_anHSqfdSt@lNi=-cegS1l0({c?JuD>mAz#1=5U;Zzv)2h^|orrhP-Do%2V|>Z_}M^9c1SD z?Oj~wGQ=G_KHr~BcT&ez3oL-xCi)ye`bC)g}nUf~u_lNLM;E zVDC1QT@Lp!j;qZSRFp6J~~~)zQEUu|BMD! zeBMj;vmFZi*WeyDH@y273h8S0`lLh`bpq8TnR>$eG77wGNkIl@zG(v zB-&E@jzXr2>y^%qf}*5`n-|mqMReRqjtXf5IpL2e8>oc9ukr&|6rQFgON}bWvwSPO zg?I)3PJ?-fMBF;S24$2n(+KHWP5fvysYxwhQVa@&vhxq$UtmLQn|7Q?V zO|}vZj$uyYpFv1a_db4i%RfKz1XA!F1pg|l%0%9w zw?0ARe~!!cgjje=iMDrxwv#Bwf7-Tn8}zmxkmQMmH%G_Lo($b5;-?UF4fl96wav=u z#3Gwb3iMN9`$KHfH~<#!929kP$mh8f$**+csqt!jf5d?w$qvPrh~I!PurXnNXNnaz z)y42_Q41w%j;0wF;~lHOHaT$W+odRpDO&z-0+9bQ5c^vyQZxPQxa#!Y?E`IR zRZ{ksO{R#w@`U){W&&q0671(04H(!$Qv?_N4Mht|C2)Mux)u_R_&@#K*njxD6o@p|a_6g_zLsrtZ#xZB z?%2GLwkrXR)_0JmI^(-N!DMs@mCduzR9puRr&$J=^Nnw=yUNl5Ajy>wePjjYo9fIf zq+F2MkGm&P5rH~P8hOJwHVPL&rEIka!uypRvH4^G%l2xKF({D|(tQbh3q|FV;8#ay zzmAk#e9kmc_M}e+f8VCv0ze8{OHhZ}AqQ&WCn!-jHgV=paV@F{h&4ny zYkf)NQor~60-#UzL!OVu%sx5gd!~ubKAtEl-4h0%6_&Bl-pdHRfUGX3&+GpHvUI2P zkHg=eIQx45ok3QTUw_H@lL3U~?>r-mLt_MOF#d3z(f& zsD=P?(1wC&$)@r6z#i!ZIsVFf!4HR4C%<%Poc8&58QtHWOdsyXK92%)jPsjRCQ%JAOQn1z_9Ms$p9f+)D2)JDMb>dziJuM7^~=IJBWu=!(64 z$Cr{a#4HWX`QmJt7@`-Etb&+QI+}2KfVl1Jf(sXu{ZgCWCK?1h8Y?x>d1jbn;w=Gx?59g_segQrVTzlZlu9A3$ zDw1lg_eW_@A%`y-SwJBLf9HB>;~KSg>b5(#Wbp`8<}4GaEmm2U>Arz zSzq(7`rms13yy39V3SgskIa<$dF37c2n+GOq}{#%sxW;xUCMC|#P(OngCEeKl(^%) z*2FA>nb)TIX8QharZM)KP@(0O(nRJ8zd@0XyVj`9p_U|Qs(43#_w4}MUbNQ~RtejK z{J8sy*JOsP7ifGw=5C6GA=RE$+QYWE0#uIp!(OO*1z%| z()~iZ9mPy8H@gMDlG<(Q1yrJ=!BxYO5`nKeKfZ`iGCPyS9%dwsqVP&Nv!Q>dUjU?s zFyQ%8sV~{VMp)5W0F27An-G)%yF*G39GA}ASNl~kU~ZQFO87zJF_XJ9QXRrZ80%m+ z@Q%w6GW}D`0cjV0hz-BbnrgXNyKZn<5lD)VX)G!htj z6xi|tJrRLCV#|S&Vt8$jyD9WhWzta=QBRc^J*S>Z^x{FI_N#-l;-{&BqO4B^N|sv0 z8WLN(PP?%bsQ!r|1+6??78T<%>h-a$DP6L}T~KFp=?4?00$-$5t=sX){CT$vyseAR z02$s>iTTAgCyooMc(<3noGfs#byAE~8Ir;emrQfYWV8{j;r3|u4DV^6ti?Yqo z#Hs-xl~y|`$5uV(fHF3XVCbvgsq9K5ATN+L5Xp`0xizIC;F9Rz>Qd*(zS9{Bt+E%qVw@c(aKX^(&YKdr1W3AsFX>`P)TP|MM?5>%MR*B zeTvjM)lkNQF~nKpsiN_Q?nL-fgriAwN^SVL`WnjfY~|7Vl;Y|pM(+5@K^hS_BYR~c zhFO0qAxD#L$)(>|PZK9TGTfL@oY`O}YnND!be6MEFGH$q(@dq8ohPsT)VLvf%+;4J&1Wh<%P`iDpNfu~I#^Kv*ZKXroQA9X>TV-6W)e))|bU5j#O7MmRsxCjY*sfIbm?z+Zf z(zxVwodjww=341vkvx|`1~pa#!VgQ(9K6X5Ct#NxuW4L(E=!p9rZ_6gZy!J@jdwED zX~pD+-(jr<>MO4|Him|p0D_7$wQ6O4&(w5} zf3&q7m$_IGvZ{8iR$P~>wRP1mWkkMk=$*li9PpT74N(Lq#m5FrXYT* zh^cE7nH^`=zR>CE=~fx|i*F$R7P)~-(hd!02y+;wajz=oI-b$COs4nN)y5nMT8NG| zcskQB2VJwzB7nH)t;eOk+%QTEc5`%hHmcGN_6>Ol2bAIXQx&;J%%YlusS-t z=dM^=1%$L^>st>EY@FquFH&-{iRn=l#ZfhJqYZy>`W)Fl$*uJ1Ug6;GOjCDXADu_G zUe@yC`aRvo=pNPl0sP9j_kdo&~xu-O~5|5 zaCmCm;x=`2ZgXO|3vMcMYXFYe%F=hZvj1wm>3Orj*8`%mGLyOeQ{5qdSGwFH_gV$t z&THif;Gs-WN~E`mGe2=yB)e*D(T+BDq@#H*q5yq15GVI$-OX!nYUt%yuzYv0IPGqx z{^N!9M-2shigeGji^+~-cVh;fO+IYh(}k286n8v}LAOh{Qzf6cwL!zZ>(X9w-k@DT+9`9^d9W`kU3EgjYwR&60JFjm%w7yM?PuTWi zsq0F5>>aT*vR`vMrKc+7Rjf~kKH+FrO;tN^Uu`z?{mtS^MA6uNe@Az2E{2cxbZ;p#zpe}G{@5`#!H3z%AAKlOo zb5*=&<{%Z^x!txlA19Dz+hN>x#>0(ow*~xmBp4h>kNA}Q<(C)xh#S7LM+K~IBY5AX zz&h@n4Z`70!r}dao_;brv(z4~gr{2qznDv&ZtpA3mOgbfQz)&iSd$mAb{{K`-IX>W zTy9?b%6E$s;VPQSYBTqvXVjS!b#&*FcdvE2)Ze`J9=k__Hec*LOjcC4f_P$Krcrsq zX|qK)G6F#=Q$JkjRb|t_*Gt>gIZb~3(zI}DnKy2IZ__f5N~_2)$_d9yFfi)a%0!7K z6{MxHMtm>z>S8b56|V`5C?^y0ed$N0tthd^f75i&=|hjg7C1puO>9DOq+-PIS@D#~ z9oNTN2~t?3#@Ve-UT2fzXvwTN9>EmLy8~hz52rG7afFtQXT?am^g@&v4bixzWUpt{ z;Bzu8$=;cp#>yIU19V@y2lTT|ArFzpw{=1*$S5j50WRd|87-1r!=|AVK=Z%jQx2Z6 z|A}Vcs;OdTl0Fm`@{pM@Oy5dho*nJ@Fi2xQ=$n4*COzS}kGhQu-SSE4!(^kgBhplp z?7*!RuV(qh*$g)`B0SAC0k7%!M=R*~7epVvGF@Horm&n^Q{OB@`J?tCZH^2RkHH6! zQfSJ#cGbRCXi*;6*n4Ek6Q2a$VBf)F5mTDhpOu*A;`*thvaHXQzC7aNCyqX!v;y9R zrz);iW*NKCm(R=hF+AJG;bk0`TI_A~7h`(u65WbC9Yc6-SeTYF-yK7G)#}pgBXy7R zKhHB~o)QOFV1f3=&@&`WovlG$0~@9GuaY9w`6N1H^n9p#v^3vS94}3_lW%wmI%#|q?lLympfxW8g)iOf z)WS9=`;|B1W!F~tEZhwD`fCTpI>z?2OlEaz9g{u7i&CvWODFN0UJBTJ7Y<|B-W7iF zTi%KP*N0eIpU25E9-Usnx94!hll_KExH0n(v8C^*Mo`W?&pCfs8MdqKweOr-#;Vwr zL6Uam`v%tGI|0jn+sBvF zFETawRSmI95D|}J%KGX*O}&jN)MdOc`Wnoz_5Ykl*=_7R4u!)%P1WPmSjWE8UG~TO z{0;<{ZXw+%obn6HKw|84Lfpoyim6M#V)=kYKdN^ zQ|J=^pAHtw;&6soB6aPbMbI0a3AB|*S+v1kd5KlN9TKDYhP;=}ZeMC`%4bi9Rf{{>QQNN~vt3gL1@=~Wajyaoq z;(>Opv=Sz^u|nRCxP)S+hNoFdVjC@%?HNF^anJX%q}ABL9-$rqE5fMAWTFW@P5_e9 ze|b-!5~YB$8ukJSy0WA+6`|f+XM;4-l60H+B2QN3tH1yZhZ}Oa*dl zBhGi=NZ9bM2E3m6UKmt0jlGQv#7ZnSul`(gSV(aFco z)_YG_G^Y%3b!Bn#CmU5OC0zRemkSvVJup&*ZE7FTVxz3;i-ShxQ>dMbi^q>=>|lYK zh*mInDirWifW4XBXI!PbO>@4eqihX&5o5Ik4U3Kjdo-cm=!Rc3NKwC!uYkTH-FTJK zfD+RgGLOpgi4XUd-aOH7zfK-MHE2!4T^iX)Lz!l+cX&GrQ30KCu7Vz?6h0kD?=$HI zuGwGJj!Rl66&H%^0Pp6fFy8^6p5aU@oOzq+^&8V1YAj6MQ?>|2c?3QcGq6v_3~5lM z3GjVT!uOnV3z|KxiWwp+hI+HVL8Iu#0zWnMH@xrhIDS_yd@Kj8b2YuP2Jf$meo2(vnty7bEjMgJZ%O{fo5j1>o?>r*dYRE;1>bN zEVfS42u1wDpkJ2nb->$um`ThVI$sQ-R990M(MzY9+lOu{OUa!%9!0`MZG9>Bxh6@x zXvzsKv<(`EetEUp8$w^gF?cX~_+f@lfhxq6Dq-Q4)!+x-(DkO&zJ`DKPn>g!6OP5` z3eJZPk-@$9qYN2lwPY}Jl&0(M-nwESsyi#^D2^7e_svStL^Lr*AXY$M}?17m_bZ>p`2}N#u-q>k40B1pIT0`;kQa+lIf_a81`|aek(|3xI z3!(D<9x#*jl9yfUlXFp~txq>%fm1)HMddPpI8)HR6c@8E^ZZdT!BU`l@o^?`-TKCVLk7#a>^3h( zZ^~l;B9x9kN)@6fpqm}CkA+{U$`f+Txo7(gmrKZ~E*IswuqmO5v!d0^TW_5MnDQ@H zE?kK#b#jiC<2%zI&8H4vbE)NO%deK&5taE`3^1T{5`MeOv`Nwgk(Tj*INXp%XtPkHtvT*cUpU<`s4 zn~OT8ho!51QK1T`p;T!4+(>@2QqTO7whlYPgA=x`bQ z71_KY?&iNEg5URu4ZL4BMAre4h|RmbLR7r-)1q+Uxvk!R9QO@1mOFsc_HdEis|!)| z_dZ^<|EW zNd`FX_zfAY*<3T;s^!}JybFhlLpu}=OsCf9=fI!0$Hp_+)#f50Gl~#lTM}__qHV$M z8;dfi9)EGi`_ILVEnE<53~LmLMc!c!gdmqh?x#Mu#cggmwD89W#T>HqEB8FyV1W-ek=D@au+>eIQ;0J^HV9=uXGW^TZxBbp9 ziLUZ6?~(CD$5h)4(z7b+Epd@>YqL{gZ_zJ&Fqn=zcz~Knu%K(>oMUQlf(>2Jvbh02 zkJ~So;+kGfx?_ygp>Yc8vr`yeQBMG$B-_BU99)GgZUXKaWpdJE!*6#~SdaWivVjPW z$GSpWL(q(urU-|8q`s1)6&R}N(NHwo0=GT=B1reN$Q}c{Tq2Nwt_x~wayM`ik^k+A z8Ryk_F1!i9o$7~k8<{L3HTS&5uElgjlh*!eF68{6v-Y&B&bVX1%uN;C$44#j_3mpm z9eSTCRin2piA>^#ZUg>&VJPDpx?e_A{}#}qNR)KBA1fx`pOLViNHWfGhEBPixq-z6 z?>#`vgG=27+^Df@^+40Ni#Z{zb?b`J78jsniYW!jEqeApw*4@ue;y{*lxtyDKu?(- zxbORL+#sRqQ!EmnbHcVTy0rvfx|iF-7hpaP$WJ6ALJ95~D<>w<2`p2wTs{(0N)-KtO1Q0X=20a0UxJDI-1`Fg;G+!eOQPHR07JO*%IszLc zNaHY1lS*?Q)Xx9ZUJRvD12HSTrY`eIq0SU!axz|docGtJiRgxSfjx-b0j_&&59`{a z;BnRy+d|yy5>1LLnI;CL4lV8B2$ClfG*Lffpn^?q*^6EQ@7llDlzY=)Vl9W^+~ zyi@UpX~nJ>^T(?`yC{uy#UBC7=rnnCP#Ov$b`qEfzio1STI79wR~6eEddi;Mg`JoE zkN3V|^;C&{bcDp=R6D?kSt5Y-b{SIbm{)%Y1QM?6*>!3nRgbLrrq>PK<%Zq~(ps zzc_e?(a9SZZp*1e>Ndwm?U`Ctz`;AP;5d z3T8<)THI5jF-eHQ{jJEwfLDg`qgIMOG!Ciz!9krL9M|nUQeYj3u4$Xl$OvG~GRhbd za~Bdo!=X-XAvp(t%q@&nnW%*#aa7qKs%s#_Ryx%^eG=Tc$rjNSI4wASGUD4@S<+>p ztD>Q)vni(Q77Cd@1nHlU zIME|{P%5|tM_v=kc9qLBLDSU%TKYRjng3ahCn2`;)fx@4+>xfAM61T_TQ3<=7$QI1n= zs@j^jTQkdO`e-YLxf9)SUD1zEUf4sd%{~Y{VjCDCNkGcU>x_2RNOj+Xti$hR1UYzr z{Lm-)a+8_Ly@WoKfdjreq)|s3s2WD1*Vbbf5?H9{%lkXhcvyDle7<2aa}f%@bg6gA z;z5&DY519#j-KlmjVGd^SIo{Ua~fI{1przJnxs33p*%fh#K7J*tJ65)W#iz$e6}!r zHNpL~pr8!`5e2J0m#sQHSq$or9Ea?kNUduk(_pZhvaNl9*T?PIO5g$ZD2Pv@qfPMGDN2QW!gljV``Bg-25s{c@ z7HGG8$60CUWbw~bT92Um>_Zfc@>MUUyY&4*j26s5kOFwkqsufIyJT++Wwz*NZ;<@s z%s+g|J?&HUX+=QDsd%s*g`z;{+-Pb5tmfE@k?HqYYCbGQe<0%>W6euw0pjWU)L4ai~akZ3>X)dRSi$#pn z;5m!zU<;)W(p9?j5($Q5oo*|6wW!xxQ<>n|mTaUhbKpvOzSu8Nd?=@$mBJRi4K!v@ z25K&l> z--QSiw^MDK+@fN#Lk%NI?5#qL@cpqm>JTu{P9cZ@q>Qoq8bc{TdwxMnq`WNGBt?q2 zqN{PkCPT1oNfnlXpHdALUd@#H#Z1L-q?Yawaul$-P){tQf%}W>s>~WShbcvhCet8m zqI8d}PWCsv!`i_gK@3GAQoNl&=;ve=5*cYpTKI7GRY?=8&1s6jl@8e-%tFoq;5%OF z8AklowKfe?Qw{otF^=H56hSGsHFl>9@tmfZxIV~y1SgMPm%HH2i1I7@lmlHbhf7mX zzet=oDQxD|N#4ekelvs(Ia`_8ph^m#o6U{zlKNDh=hOr5tP#HAw!CW@t6kOG6N)oi z)D=HY_$$r8ahDa)OpF)s2+`FZpw2^!CAus*HNpsOoD|uyQ9?#lDW%DA9EQD_i-{8; zsRRSNB9v$VnUV_M;xKZ$1srBPpC=IR~6L}KQ)R^FBd%niqK{5Pt2g<<;f9{qsz5#5;dHpf@p&v_qBdT6(3u&E- zLUH9MH0hJS33Tdf6VPOZbeQRy7nT3Cd_3q27*p=YMj|0H)CR7+YG!|bNpqdOE-o&5 zEi}4k9K47#=8AA?yf7&9!n7}PAwB_Kgr{w^0e0NgnYPV4E#pG?RL^9VUU5uAt?9yP zoxv&HJQG#Bz?32V5IJ8sM@KNTvYi_2Cph`^c<~uERS{fs`;cVjnOz{%q1`%D6IxRr z=!@P{ZkO=`-bj1(`IVUhQ`)QKz(sPRjElP%FjwE?4?n#&7$#j^)((n!+ zZF>iAw7$y$lN#fpK~nv}UtMQ*Nl3t?p~27DBDPXp*`96Q=5;M#Ad7RH9f6WC z_rR{}EtVL?H`7j4z3a_tx|PqW&!77t1^JdVzIKt`Ls9xo#*+GO@ht%ezNro$lDU(F zf3T;kalTBVv}d0(SP`j_fOkvW8>+cnux~1?MVK4NDfm?nrG+>rB?~3v^LJa<0 zL+VNVTTn7dS;oaJhn>6>1+=AF(S&W%&%)5kc|Antt)H0LGBbpy;pJXLFCz}?GnN-2 zI-;yLspv?Q(*mW6S`Ti+a@@dRqQR<(=U4r4*x8!IG4z=1jEGD_h`GC4cN^f7G>@s_`67-B5l1 zqjvv;_UfayJf+j9c)M2@_t7utG(Ke4FLnlR|J(jrW2KAsZsavzNSPcL>#bSbHihQ1 zPf!Z)Zgh@r>r`Lu<=HpXBKXhZI-hG8bgkh>(3@m&JMaFV61tAf5TuwvqM2dM#O0x4 zp+a@nSrG$3vs=4@ct3F3q9`qZQ4y(<)GoP!`ku}0Txp6z7r6M z41@aD`QcFsS%I+s9u4WG@}sx$6i6D(ibSdR8=i2OeU&C)TVR847VA-Cz`pjr1FFih z54pr$ixVS>!*{1W@HnhLu8P*kEWI0F%V4bOaD}u>CJ>Nq+aBTk4Jejp!-J~B*394I z?&lv;YJdVQ2RW;JfrS=h>eWzOnloKp$;d>)^ zTA8RX(L;~oRa?duk4G@^xo|8qo%izR`EX{BA_h_QodAK7LD$^% z09IOmx<$2xir;Bi@e)wE3Xx--bjE z1T>TnrSruwCJhPc%z7aG+G1h!dcBa~xnU_p)%l?bQmBMZ`6dfbM5i)cZHa#zE#tCL z{d75P6OpZKevc8jn913x$x&h5_j#sxTDV*s@P>F&%-!kNq(dd^mBd>H_lp44;zTd2 z>WTKa5O_pv`>Oi`P#!NrkOaX8X%(I_KUv><%*}U@ciI8~lf^<`?PNIy>7mq!uLs7> zkf4%aERI{e!mXt?hI!(SGg8N4L1MWltYZmD_yxr!n%Mh_9P+g>dZraA#`7n?2c)NC zvNT2C`xap_Ids`K#daEDDQKlW#OzLe8Bls%~c#E{y~#3vyBuddE9I1`{t+fR}wwr$(CGqJ6SZQJI=w#`W+uV6~ zx9Y2J|8-`CY|;~ETt1AFT{pr8sgt#jpugQySDpIOjVasA#s0^Z<9ghk7L zDTj@TnY!?&lW=g^!tlK4lS(1rMUdya|+K=2O*w*jmFyrP$> z>8HQ|_^wIZIFk^Yf>Yx8kmNnT5buN+i?2nEt7!N;mnB}{FVm*Ur9bJPyG@!2GvKhr z@l!ZmqdW$si9c#)_kyL1qJn8tv8PlBr0Xs@Gs?T;_kT=_52VC0JCs50pcffnxc+Jo zBrYv|4iUyO+V1{hhS6%C!!2b~Wb67dcTq~FkCC~KXG1C)-RDuj32QcTb;(uNnalom z8QVERLpf~1SJmv615;uABvBkdPo_k>QXnVNE2VVl9Dy~^$QV^$gM?D%qe$l&;PCzj z5JketcC^Rk(QD}wOf#J?TRl)%DTqeY2PDj=LZH5CToP_^KSfFxsl*rPnk%Y)G&zGi z%~!WCc0DucZ+ok^z-Es0{)`0-fT_aQV3_oEjgBIBRSLO!C;m;&nHH8O`rH~?#~hMK zPLnu(txb^7JeBV*j>r_RpDLs&a^D`UsCKf6d1_7MFIU#0Xt$8So)GA78iwLc-B_hF zLIyyNGh;L&7lwx;GmXPNUQpV z)xtJRtYctm)H5>^&k3-+0`($SdKjVxcbCmx&CQ<3OmR@vqn^-Uu}*R60oC)P>CBZf zhN^=T!#mXsy5%>9wAochr9Bym*oEg3NO+`jOY#i^Sz#G~R~S-F`0MQ67W$PjDqmXT ztLb!w%F&;ygX6A&I(kA%$2T0#{bzDrb1#du^=3{#iy=_?pr`Nkg^yTO=X+v{mRSp3 z{Vnq?lT<8ofn;fhVzl3TiyqSDKAX?PnJ9p<%&fe-r1aC8!@GNb?ZTLjd^Mv~OLjSz zHkbLzfD7lh>@OB=eNN=NYZVo?hNskjk(xIVZiIO zW$^I49$}mNOWXP+WPfqmf4-)eHnhmVZ*DbMbLKkGM9#amb`kd*44rxoq9kuoSL1@V zF7DN1>t=h-feAf99KZb7m3T08YSM8wVni3kDGy{79zZR)GbJ1%5JLJq5O03G_Z-)l z8^(#%$`JI>EC#6%G9|>UDe1#rU1PMdC5RHH41EWmHuVyoj-9v3j|M7o43S#UD5oxJ zg@_egeu~Y3B%{eeLa)S~+dTL!HyG4^t^pzd(Sy7n+MoKO!kqnAgmR>2r9lH6ZqCiVJJIP1K4-g zQ|{MaKm4$aAZP|Rq||VL?oprUYZ)?Q%N+WtHtIJy`H89! zLgd9qfSZcW^1q-RO3^KE8+6?g(uhgdvXWH>3<=lm3?s={e3@hs1deXTqn^OYr8kKE zckAX;bevB4!K!jW*~SS&v1krVo6z_EpQU)@r;xk^vxKUSx)Z1G`kriF!cEpolMJ|O zZAz1|WP;faIlmbEHc$^u{_d(`=c}*q4S3hISe5i`(`Z!p8*(ZiN;K4#aFCNLU8hVs zNQbp9EJU>pXZ{yMR z0+)knF}SzaNZ{G|HbsPd!a_Y3tkSKvCd-RLq>Iq^P5DUuhcywvI)92&^*?&dn2XDd0J|ED{!)7#T=OL!C3Y-_-z z;T#i1*YU$~NmxuqZEkb*N4L|X#WMhnn5l!;+6Bq)5(a!_|u+7&+Lgg{$85$ zd%KY$viyhwNP&?vEI0ASF4#{nV4)GgaVo>**!g6(Bb@{%B>#*@P8OcplU#Eyau~c7 z@WKei2N0*)H*rF(&1fJjakLZG6ERKaP!?I5XhldU0h>hde7)eX{leEGEa3C>>s&a+ zR|qY7el{%I0NEBCdWsiiY9qOEw2g$J0Z0MKZdQ9Z3zN0MI%RQt$*lQ?0kdZ?zIv2Jh$9^sy!?C%sAES$89b}>7&l)5CWybL8x#EnPfY^yXvMWTlDA-9wcQV~TiNl& zu>fG|9MqzwV2^k+gE7&p+b*gDSWxAtlV6&*e6mbyqETI5FhUH#xy|hz5F7O9L}CjL zKdCJ_{t?6Sm!vBEiDc{MTf^JD zJ`EN@@Y@&%W4Lu9|Jc75oP0G(xoC)&#L4su5gLQM7hdF*6`rCZ>s`~GT)W|!MzJ2 zLx%sp1=z^VkA!GG?;Krd&Aq}09gc7frIfIuWBlo-NmorwJg-W9P@(%UjQs?PCn(K9 zN?m_iuQv7$1gA1I>R6A&p(LyjQxucqY7er>20cfA4iK8RKhni+i{WnIr~io=5SoPt zQozMiJYFS?Gz6LDvgPm(DYBGsWQVu%%5#os{`loxE!eL^Wk!=tTm-^V;nx&Yv9sTI zDDY1PdO23rxsbD(Af5#ipx|Vn+LNSQ?Y~db({EZAXcW8=w&!3U$-}6Adwvssk~!wt zz{7LF?Xc*IJ{?uM=#rub&f;Sj?Ba$~NySUnpK|eH6N%Dvmh zkrAlRJ^0^{Rfd~|`t#gJNK#;dC50!ne(XA^2p0~V*1B2ROEi(4r*@4i^whoXz9K_QZt?^%+f+z_y)BNK;&`(g zC3t(QY)xIR!@bqfF?-A;Q#Rg-U3e?G8{b4U(x`Lmum+`&Ra3?1F7tcFIQkzBgTN+qqCu<|O>HWOl{(=|Pw(qn1Q z3t@oIw(#U*Io51jhGSOJYBJ&?u2ge4pidusb?pa&Ul4MYRP zP#EO3kva-KPz23-xQTUVtEi+I*%e99g78{%@gr6sNS$q* zl|kAg&BvnV!MV9cI-_MYMc@arB<-c5lQ>)P$6I1073^U%;yy7!71eDc2YJwcQ_diX z5WN%HMSj}!cRZ%Y4Mtrh_xc4zP6U_X2?h@WLodXvS)y5^w^*dpg_aWtVG+4By~He; z(B#hR2nVOT8Cia{y32HDM{GlH)A0!3GX%tA)J45$wHSJOo3>*!Sj~vdhZ5;W!-D$6 z0aEn|G9Z)}ngLN55eq_G@fru^n^$ip*|N zt-{XSojl)sZ;T=5K;~*r!hPGL>8+qM@FNpPoUJ8Y29;yb16};m?N2prhaS;`zWCb% zP1}i~#g2J79IBNCESWP4`)AZIGRA2qG_Y97*maYV?{bc6@hR9G z>Y7hQYQYCQolrl1n_TPfjy6yAl~KreaDOj02%0R6UQg`e0FGY6&}hj1RmKm|<4_h? zF8S$}-kj#ny*MnqDvLHgli}_rSppGaoLwpdWLP-qh`>ixlY67bFH&VUsGQ}!J4mIgNu5gerXp9B<7BK5$ojjnr~Y$A`+Ma+%j>bXQnv1}xZf7>LM zBTFW4o-Dq{PDibGmk56R4sz6wzD4odhMY^00Ix>pOZfqH)gNY7OjkrMI2Q(JR=vm} ze3``s!BOQ$Pl1E$>HjT}{nBta2;na|OHRrZuDmUlONT~SF0d$F=}}f65;%7Sy+yMe z_maRh=ezYu`{8{Te9));SCUH5YG%^yJI|yQxmpIybuNLD#k>%bu;&vI?Nd>>ef>Gm z=lfvg`0jhBS&VNi-+=;BU{Kt6`kx_r*Xu%M0`;$5$QawAba&z!o6&*gbx(3y2fY)q zl>ehZ1X7~|CGAU*hUTT(W?qzK=Bv~|+K%r7Ba<-Lz5U{qFN$sP1;v!e77}YBD<@1M zfom{gXIZwg6~}I>Rerk3?KCM6jx(szf*%3wcoBQ|sCA=!)4HTHj5dsl>}{6T0~cdq z6ZuWN?TFO~!RUPYN+QuGX1I@ypVdzJg0wtDo1=VLy$dhS;=1B(z3Qrv;a5BuVY#vm zU&H6;389msmF}Ogr5f&iwek>TE~1uyrr_4vEefx?F<5jMHqYoIt!TuMgksCV*Lz~Z zwT&73R)>!JcbrPeBrm4MVR?uWx6PHkOeh=8qAEFpA5mfQ_X2L=-|#7xi-hp2hu-36 zQlU%mO*fo0N^9 z@pi#@MI-cTm}t*~30#EaF;YGs%ub)JEzRuwTC2$R3ZVKU$_czgMtl#n04u=`u&9%u zFL932|M(+B*jH30BL!;g5jgztRNR>A5_b&SPbvHGHS`$$2$NQLwDb{08K7(fiJElh zt{WcPswUDto>XMm0|`p1$kWe8I)ZX}RW33=;Uq~=;UJkDGaCXU6Q^Q5^M-GpVIkWx z{zW?%dny-&I!gulSag3V3A#Ok>?;qX-N$QBi@Hv}K%H#&hhCd$Tvz!nRf)aRpMbT8 z*$OG4u+?Gv#Z$-Cz!M|_Bo%4LkyHOM=g`)vo0=ttMQ-6Cckxr99szTSk|<|Vv+m%P4Jd?AgE2eYId45Aj+!PKVLn23^E}fl ziCS~d#4Lg=1ri-|=E=<4*Pm%Od>&QE7K|$qbPv;{?Gk~QWYmxTqlomm#n9`N`I}d+ zJDYgD2)B6GD;U$!hfRR8!hIS+`Xl1m2!dD9i^yl9KL)JHIDsv@biDis0TtG8?6KQ6 z+u@F46-EmBt{zEffB8D~!rbfI$A zbkQBLfRBl|sLhsST-X%!O_D(%_=e#1LS2Lo?cM{sK?_yfcLdfg952IK4*$cAj*C9C zCa%MKfMIS`U7`>PTn7I>mdeOt8V0u$9g}a|cY=@|B7#Lc9l(UFbyv+#>Wn25$f{QV zx$)KD^fPW_9qvf3C)i!e7zM2gN)^wx3bq9}bRa-5%aqYEyzVUBbETp>0@NkUg+Q{d zuRMhAPXDVY#`$jdX8yR`69AKejIrl#IP7K3W@JsWf#y3WO;yR|6$4V4o(w1i_06l# zadA2ycV`d|rl)gV`3Ygk;FH&oZ}}C7E*C*;tqpKNUE{E1BRU7&L>MjQc1`>Q+&ORI zzB11|+C)CW2b)B_K+Tlp|7>1bBGj;J5lU#yoY!uTYXuuw{)w~*CcO5|f>gXv-RiXd z5j0@=2BRw!lqu;V>~J_XQK7RyvIkKIaOZ0QjKS${rDuLDJQmsWt4}Vz=A2c5;%*wn zCqjIC8tF@#bp;s1G)rV+glsuxz8u~L!1Qyp2s|57F?ZFzjP50u^boOa57|h|I?Tq= zo^`-5zf~YHH172TjEZHMlT4EtHUtr}q>T`F3;~Uw7EAz{y%$h7RDmS+<~^GFO10A9 z;t8up-%CG(Ml4!ohqlR>#Qs7TTIu;T9r{DFi0cqSE&hIvCm6=L;fqwf6IFntVK~9- zX84wA6r;itg1CB5@R&p0t1)^f+?!$wFQRE=Xr_~Mt)R8`yFvX+&f#;mQsIleV8rQ} zFdiDNfxt$}i%hsz>{ViwR{y5o{%W7CLBA1sF#3^Bk`U(97ZVRwrlmh zB|ZiJc@H{kFmi`Vti?Xo@Z8q^S|RFU-LaV6o=)({7)sgH6@u0A@yI?V zxBogaYO*_b4xdB2aNMIzgk*6fV=eiLM7kLq=vbTI%O8S5q^yq5{=pKZ^y|)a9c)lf+d<-H;fJKFYfto) zH!W|l^`m$lY;NQ3%};pGgd-&PN~AnmZxOU*JH`@{imARk=i+dep`uBe*GhCpxu~uz zeHW`b<(`jvwU|xWS~RW~OHk7edeHqSKzVhiRBv4-GAJx#ZT|hZ)D?8rC1g#~{K<-B z*c*~al?afka#_clETgAMj|Ss91`XoWDO=q=9-V*`YI9`f0}5R)g@Ba52*3Y6Io6(T z%mkQ}Q_y^1D@mN_BVAP<>4ryQ~!A{h|j$qi+C|F=Nd477n>LAm)p4)MowiM|N~2qz;e>Vg($6l|AdMupjJ zph!Wbn`#b@TWwY`n#+53++<|E)syIjRj{ldkLO*$y|o$5A07fFi;(2T)U@CpAW0fIJaV zoPj$lHr~nEJayIIF{K1OaM~RLd?n+2Oa>#2|-Ew>n5_^yoj0#1^VVCkNTe+ zg1Y;KXjGzA=}8CPFmg^Zlb_@K^+jlRB8?|y{AHk#6464o*sS=N~v=F8)^;vK;KW?P3X2Fzx%+F5mjgRwCqRQ z2pfScrtsLWlpnn6xCsGna?twW$CQ*kh5s4TWpLOWWL{Us68Wj($$KUse7SJZ7g%!qFPSN5;k#_G%dQFW)av5{GiW9D>| z>vJL2CTCR48~`V@&m(A+hh4eWcy_Ksogr4!IsQ-U)fWZs&(cCFj2Y13K?OQEtJyht zn>~6!p`b5`_WBg9z5Ytqz0f6p46U^bN#<%Cf8?**5E|~*&zJEn|&Z^?P&{YyKjk43k!lVH9KCJM?Kd04L7Bp}OmSR09tGeC^o$2lf+1 zID4%F{SVq^1LrVHiE8b>jvHS;RHl7NpsqVtP=Wo)H;0#M6T@5G34bY)M~q|cD~nn) zTg@t#NIZ_HKfTF)(JKqP9f!GKsB2GM0i>C+<(oe6FU0tm7pVL&4Y{ z7N)T-cK+?4PO(5kq6If!3S5$2InG$MPizR&pMxV#f+W$^6JXPf#R0HMuSzkNz0iz8 z1FSVdvSHe+q1>77Ia##A6q{5q;~v0nG&i|!(HbNX%QT&(*0o3o_R(0T=RV$QJ2B@E zdQ%n7Y1Z+k0P5%Y|Jh77YKRbA@Jb^I%ew%6+(iICY(f*VUd9ndbfI5|o{7|quGwuj zLAt92wx%?UcWvMwZ&iRE8v|O~_L7K|-1*w$@?HdAN|$6ceKGHGr|RB&NzjkAOZIO> zK#%OkCn1R6Kc$Dwr6)&y^%u-&-TWquTDhy@{CZQ4AmZzxw|0ApSrgu}`-5NT2Mx^q zKV2_9qLVHEI0!84tssbc-*rMRY1E`5RMM|BHUqITvCV(+6jRoVV`}eInCYXQG2|JC zJ!k*0Gqafjvv-bXd@A23YK^;m7)bUkhd3p9iBFFp+|p4xjfqd+a^}sS-EK+U9YzY&kIPI^%{dAJyjR}{h)gWpTA#x zTNcQuzDe~j05~pTuIDe8-w4ULKX66 z5W}Uu{SQL?8+!-rlr&kPS%_{R&`U9}kVTlWH*IBUtGyX zLV)HLI_SMAT&Quth3i1IZ3)Ou#H@S=Fjf6W4TEt3iaV+)bvCa5z=Jp(AHfJh1df@Y zfP^(lZ`E`n2JY|-nC*P5_^!K)MAxuj*nrSSxBfRQT+~hZ!=on<>De(=QW4C)_AWKn zMiHWjY8?H2PU)c0Y>*CRGn)INOIV%D!+qblmQy%_2*^E}%N7 z>leWe(y#oq23X(@$RhM(z6M4^h6!a}k@2GV=O=8NUz4~RHso(|@Fw}I&2H*jDVYC2 z!a;6lzON|llgmJeIo=BxB!a1m^Zqm>x&L8=HvpYcrUoLRX!mqKOQjCgBYp{^uLmgF;e|Qt}^V~zFZh65<7w@I_xb~NbK^Gns`G0sYxV4mAijPq6 z_#zm=a|k?MjlW2q)|T9k!VQIc?a@~NPnEd*?FIEZe2QBz6V#{TU(&L+ZziXxg;DxA zb8LS$cdjSdLm%xG5ztpC!ltwz4m{%j&Hpkx_(pVqfvR{0Xloqz7X#E}D?&641R?g} zHBl-L7?6wWlI#bwqi?WQ4)NUk(KqXYUp_(nAB&{k4 zowU<# zyAEk$AA!Ld<*$x#Wzt^s0T4ITxbK_`7#4)pS)Bh#D_WK+$^vzx?g7$z2QxUo zeIcnAvFU(o(IUWpn!(-_hk)V1@Leb=kSEUzFBP?I#K-I@KW9p0SW48ay)P&3{A*Sk zj~lU%aqQPlhGHmVgsARGw1#eAM<-O8LT>x4hKwU}S-(o-q+G2E_w?aQni3nC=2tyJ z!)OgCsYuu2HvKsJ*B&F~(Z{kZ0uTk(79-gW@?`Ui=#Kf=}wi9j?JURZQE!txNRd%zc@8!nSn)FK_dpbnKu}RHJg~Y>hY_pp0i?zj z?sUiZzMxLBb}GVgTCfAtDXL=%62_6g7d#{WpdLh0P*~qp9Xq9|{{k98fuw5ExP0Lb YCgcfzLjnNb-(Y|%?qc~WUU0yF0iVUr1^@s6 diff --git a/openfe/tests/protocols/test_openmm_afe_slow.py b/openfe/tests/protocols/test_openmm_afe_slow.py index 2f6624d92..8dfad8fa8 100644 --- a/openfe/tests/protocols/test_openmm_afe_slow.py +++ b/openfe/tests/protocols/test_openmm_afe_slow.py @@ -45,25 +45,18 @@ def test_openmm_run_engine(platform, # Run a really short calculation to check everything is going well s = openmm_afe.AbsoluteSolvationProtocol.default_settings() - s.protocol_repeats = 1 + s.alchemsampler_settings.n_repeats = 1 s.solvent_output_settings.output_indices = "resname UNK" - s.vacuum_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond - s.vacuum_equil_simulation_settings.production_length = 0.1 * unit.picosecond s.vacuum_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.vacuum_simulation_settings.production_length = 0.1 * unit.picosecond - s.solvent_equil_simulation_settings.equilibration_length_nvt = 0.1 * unit.picosecond - s.solvent_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond - s.solvent_equil_simulation_settings.production_length = 0.1 * unit.picosecond s.solvent_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.solvent_simulation_settings.production_length = 0.1 * unit.picosecond s.vacuum_engine_settings.compute_platform = platform s.solvent_engine_settings.compute_platform = platform - s.solvent_simulation_settings.time_per_iteration = 20 * unit.femtoseconds - s.vacuum_simulation_settings.time_per_iteration = 20 * unit.femtoseconds - s.vacuum_output_settings.checkpoint_interval = 20 * unit.femtoseconds - s.solvent_output_settings.checkpoint_interval = 20 * unit.femtoseconds - s.solvent_simulation_settings.n_replicas = 20 - s.vacuum_simulation_settings.n_replicas = 20 + s.alchemsampler_settings.steps_per_iteration = 5 * unit.timestep + s.vacuum_output_settings.checkpoint_interval = 5 * unit.timestep + s.solvent_output_settings.checkpoint_interval = 5 * unit.timestep + s.alchemsampler_settings.n_replicas = 20 s.lambda_settings.lambda_elec = \ [0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] diff --git a/openfe/tests/protocols/test_solvation_afe_tokenization.py b/openfe/tests/protocols/test_solvation_afe_tokenization.py index d73c009a5..38c2f92cd 100644 --- a/openfe/tests/protocols/test_solvation_afe_tokenization.py +++ b/openfe/tests/protocols/test_solvation_afe_tokenization.py @@ -49,7 +49,7 @@ def protocol_result(afe_solv_transformation_json): class TestAbsoluteSolvationProtocol(GufeTokenizableTestsMixin): cls = openmm_afe.AbsoluteSolvationProtocol - key = "AbsoluteSolvationProtocol-1262bf8cac922568528648aff23a6e73" + key = "AbsoluteSolvationProtocol-0d2c5a0a9c18ec7d2629ce21b983f3fe" repr = f"<{key}>" @pytest.fixture() @@ -85,7 +85,7 @@ def test_key_stable(self): class TestAbsoluteSolvationProtocolResult(GufeTokenizableTestsMixin): cls = openmm_afe.AbsoluteSolvationProtocolResult - key = "AbsoluteSolvationProtocolResult-c1e7524ca8cda3921c2cbd5b512d1cf0" + key = "AbsoluteSolvationProtocolResult-55ac1971317176d6e84549601d1eed5e" repr = f"<{key}>" @pytest.fixture() From a85855d65db5c0bbab0a45eaec3640280aded3e0 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 11 Feb 2024 12:27:36 +0000 Subject: [PATCH 06/11] Fix tests for new settings --- openfe/tests/protocols/test_openmm_afe_slow.py | 12 +++++++----- .../protocols/test_openmm_equil_rfe_protocols.py | 8 ++++---- openfe/tests/protocols/test_openmm_rfe_slow.py | 16 ++++++++-------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_afe_slow.py b/openfe/tests/protocols/test_openmm_afe_slow.py index 8dfad8fa8..020be4efa 100644 --- a/openfe/tests/protocols/test_openmm_afe_slow.py +++ b/openfe/tests/protocols/test_openmm_afe_slow.py @@ -45,7 +45,7 @@ def test_openmm_run_engine(platform, # Run a really short calculation to check everything is going well s = openmm_afe.AbsoluteSolvationProtocol.default_settings() - s.alchemsampler_settings.n_repeats = 1 + s.protocol_repeats = 1 s.solvent_output_settings.output_indices = "resname UNK" s.vacuum_simulation_settings.equilibration_length = 0.1 * unit.picosecond s.vacuum_simulation_settings.production_length = 0.1 * unit.picosecond @@ -53,10 +53,12 @@ def test_openmm_run_engine(platform, s.solvent_simulation_settings.production_length = 0.1 * unit.picosecond s.vacuum_engine_settings.compute_platform = platform s.solvent_engine_settings.compute_platform = platform - s.alchemsampler_settings.steps_per_iteration = 5 * unit.timestep - s.vacuum_output_settings.checkpoint_interval = 5 * unit.timestep - s.solvent_output_settings.checkpoint_interval = 5 * unit.timestep - s.alchemsampler_settings.n_replicas = 20 + s.vacuum_simulation_settings.time_per_iteration = 20 * unit.femtosecond + s.solvent_simulation_settings.time_per_iteration = 20 * unit.femtosecond + s.vacuum_output_settings.checkpoint_interval = 20 * unit.femtosecond + s.solvent_output_settings.checkpoint_interval = 20 * unit.femtosecond + s.vacuum_simulation_settings.n_replicas = 20 + s.solvent_simulation_settings.n_replicas = 20 s.lambda_settings.lambda_elec = \ [0.0, 0.25, 0.5, 0.75, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] diff --git a/openfe/tests/protocols/test_openmm_equil_rfe_protocols.py b/openfe/tests/protocols/test_openmm_equil_rfe_protocols.py index 1f0d3daaa..dc50dfd0f 100644 --- a/openfe/tests/protocols/test_openmm_equil_rfe_protocols.py +++ b/openfe/tests/protocols/test_openmm_equil_rfe_protocols.py @@ -557,7 +557,7 @@ def test_dry_run_ligand_system_cutoff( """ settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.solvation_settings.solvent_padding = 1.5 * unit.nanometer - settings.system_settings.nonbonded_cutoff = cutoff + settings.forcefield_settings.nonbonded_cutoff = cutoff protocol = openmm_rfe.RelativeHybridTopologyProtocol( settings=settings, @@ -565,7 +565,7 @@ def test_dry_run_ligand_system_cutoff( dag = protocol.create( stateA=benzene_system, stateB=toluene_system, - mapping={'ligand': benzene_to_toluene_mapping}, + mapping=benzene_to_toluene_mapping, ) dag_unit = list(dag.protocol_units)[0] @@ -749,7 +749,7 @@ def test_dry_run_complex(benzene_complex_system, toluene_complex_system, benzene_to_toluene_mapping, method, tmpdir): # this will be very time consuming settings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() - settings.alchemical_sampler_settings.sampler_method = method + settings.simulation_settings.sampler_method = method settings.protocol_repeats = 1 settings.output_settings.output_indices = 'protein or resname UNK' @@ -1327,7 +1327,7 @@ def tyk2_xml(tmp_path_factory): settings: openmm_rfe.RelativeHybridTopologyProtocolSettings = openmm_rfe.RelativeHybridTopologyProtocol.default_settings() settings.forcefield_settings.small_molecule_forcefield = 'openff-2.0.0' - settings.system_settings.nonbonded_method = 'nocutoff' + settings.forcefield_settings.nonbonded_method = 'nocutoff' settings.forcefield_settings.hydrogen_mass = 3.0 settings.protocol_repeats = 1 diff --git a/openfe/tests/protocols/test_openmm_rfe_slow.py b/openfe/tests/protocols/test_openmm_rfe_slow.py index 26160b7c5..54c1d6f62 100644 --- a/openfe/tests/protocols/test_openmm_rfe_slow.py +++ b/openfe/tests/protocols/test_openmm_rfe_slow.py @@ -47,11 +47,11 @@ def test_openmm_run_engine(benzene_vacuum_system, platform, s = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol.default_settings() s.simulation_settings.equilibration_length = 0.1 * unit.picosecond s.simulation_settings.production_length = 0.1 * unit.picosecond - s.alchemical_sampler_settings.steps_per_iteration = 5 * unit.timestep - s.system_settings.nonbonded_method = 'nocutoff' - s.n_repeats = 1 + s.simulation_settings.time_per_iteration = 20 * unit.femtosecond + s.forcefield_settings.nonbonded_method = 'nocutoff' + s.protocol_repeats = 1 s.engine_settings.compute_platform = platform - s.output_settings.checkpoint_interval = 5 * unit.timestep + s.output_settings.checkpoint_interval = 20 * unit.femtosecond p = openmm_rfe.RelativeHybridTopologyProtocol(s) @@ -79,7 +79,7 @@ def test_openmm_run_engine(benzene_vacuum_system, platform, assert unit_shared.exists() assert pathlib.Path(unit_shared).is_dir() checkpoint = pur.outputs['last_checkpoint'] - assert checkpoint == "checkpoint.nc" + assert checkpoint == "checkpoint.chk" assert (unit_shared / checkpoint).exists() nc = pur.outputs['nc'] assert nc == unit_shared / "simulation.nc" @@ -105,9 +105,9 @@ def test_run_eg5_sim(eg5_protein, eg5_ligands, eg5_cofactor, tmpdir): s = openfe.protocols.openmm_rfe.RelativeHybridTopologyProtocol.default_settings() s.simulation_settings.equilibration_length = 0.1 * unit.picosecond s.simulation_settings.production_length = 0.1 * unit.picosecond - s.alchemical_sampler_settings.steps_per_iteration = 5 * unit.timestep - s.n_repeats = 1 - s.output_settings.checkpoint_interval = 5 * unit.timestep + s.simulation_settings.time_per_iteration = 20 * unit.femtosecond + s.protocol_repeats = 1 + s.output_settings.checkpoint_interval = 20 * unit.femtosecond p = openmm_rfe.RelativeHybridTopologyProtocol(s) From 3e3b8c4e294b6a89d937c0b1d71e51c2e87fdbc6 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 11 Feb 2024 12:50:48 +0000 Subject: [PATCH 07/11] fix typing --- openfe/protocols/openmm_md/plain_md_methods.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/openmm_md/plain_md_methods.py b/openfe/protocols/openmm_md/plain_md_methods.py index 4876d192f..a0f442e82 100644 --- a/openfe/protocols/openmm_md/plain_md_methods.py +++ b/openfe/protocols/openmm_md/plain_md_methods.py @@ -17,7 +17,6 @@ import openmm from openff.units import unit from openff.units.openmm import from_openmm, to_openmm -from openff.models.types import FloatQuantity import openmm.unit as omm_unit from typing import Optional from openmm import app @@ -249,9 +248,9 @@ def _run_MD(simulation: openmm.app.Simulation, positions: omm_unit.Quantity, simulation_settings: MDSimulationSettings, output_settings: MDOutputSettings, - temperature: FloatQuantity["kelvin"], + temperature: unit.Quantity, barostat_frequency: unit.Quantity, - timestep: FloatQuantity["femtosecond"], + timestep: unit.Quantity, equil_steps_nvt: int, equil_steps_npt: int, prod_steps: int, From 1c2cee71bc6f2976fd68216e405f3309e9a82cf4 Mon Sep 17 00:00:00 2001 From: richard gowers Date: Tue, 13 Feb 2024 10:51:32 +0000 Subject: [PATCH 08/11] add divmod_time_and_check to save boilerplate and generate consistent error messages around time conversion --- .../openmm_utils/settings_validation.py | 79 ++++++++++++------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/openfe/protocols/openmm_utils/settings_validation.py b/openfe/protocols/openmm_utils/settings_validation.py index 9a3fdc415..0526f95f2 100644 --- a/openfe/protocols/openmm_utils/settings_validation.py +++ b/openfe/protocols/openmm_utils/settings_validation.py @@ -102,6 +102,41 @@ def divmod_time( return iterations, remainder +def divmod_time_and_check(numerator: unit.Quantity, denominator: unit.Quantity, + numerator_name: str, denominator_name: str) -> int: + """Perform a division of time, failing if there is a remainder + + For example numerator 20.0 ps and denominator 4.0 fs gives 5000 + + Parameters + ---------- + numerator, denominator : unit.Quantity + the division to perform + numerator_name, denominator_name : str + used for the error generated if there is any remainder + + Returns + ------- + iterations : int + the result of the division + + Raises + ------ + ValueError + if the division results in any remainder, will include a formatted error + message + """ + its, rem = divmod_time(numerator, denominator) + + if rem: + errmsg = (f"The {numerator_name} ({numerator}) " + "does not evenly divide by the " + f"{denominator_name} ({denominator})") + raise ValueError(errmsg) + + return its + + def convert_checkpoint_interval_to_iterations( checkpoint_interval: unit.Quantity, time_per_iteration: unit.Quantity, @@ -125,15 +160,11 @@ def convert_checkpoint_interval_to_iterations( iterations : int The number of iterations per checkpoint. """ - iterations, rem = divmod_time(checkpoint_interval, time_per_iteration) - - if rem: - errmsg = (f"The amount of time per checkpoint {checkpoint_interval} " - "does not evenly divide by the amount of time per " - f"state MCM move attempt {time_per_iteration}") - raise ValueError(errmsg) - - return iterations + return divmod_time_and_check( + checkpoint_interval, time_per_iteration, + "amount of time per checkpoint", + "amount of time per state MCM move attempt" + ) def convert_steps_per_iteration( @@ -152,17 +183,13 @@ def convert_steps_per_iteration( steps_per_iteration : int suitable for input to Integrator """ - steps_per_iteration, rem = divmod_time( + return divmod_time_and_check( simulation_settings.time_per_iteration, - integrator_settings.timestep + integrator_settings.timestep, + "time_per_iteration", + "timestep", ) - if rem: - raise ValueError(f"time_per_iteration ({simulation_settings.time_per_iteration}) " - f"not divisible by timestep ({integrator_settings.timestep})") - - return steps_per_iteration - def convert_real_time_analysis_iterations( simulation_settings: MultiStateSimulationSettings, @@ -191,25 +218,19 @@ def convert_real_time_analysis_iterations( # option to turn off real time analysis return None, None - rta_its, rem = divmod_time( + rta_its = divmod_time_and_check( simulation_settings.real_time_analysis_interval, simulation_settings.time_per_iteration, + "real_time_analysis_interval", + "time_per_iteration", ) - - if rem: - raise ValueError(f"real_time_analysis_interval ({simulation_settings.real_time_analysis_interval}) " - f"is not divisible by time_per_iteration ({simulation_settings.time_per_iteration})") - - # convert RTA_minimum_time to iterations - rta_min_its, rem = divmod_time( + rta_min_its = divmod_time_and_check( simulation_settings.real_time_analysis_minimum_time, simulation_settings.time_per_iteration, + "real_time_analysis_minimum_time", + "time_per_iteration", ) - if rem: - raise ValueError(f"real_time_analysis_minimum_time ({simulation_settings.real_time_analysis_minimum_time}) " - f"is not divisible by time_per_iteration ({simulation_settings.time_per_iteration})") - return rta_its, rta_min_its From 4fdebc62d654e60f856eb0c9370a5fb3ff40090a Mon Sep 17 00:00:00 2001 From: richard gowers Date: Tue, 13 Feb 2024 10:53:02 +0000 Subject: [PATCH 09/11] md protocol: update trajectory_write_interval to use time units was previously expressed in timesteps keeps same value of 5,000 timesteps == 20 ps (with default 4 fs timestep) fixes #716 --- openfe/protocols/openmm_md/plain_md_methods.py | 15 +++++++++++---- openfe/protocols/openmm_utils/omm_settings.py | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_md/plain_md_methods.py b/openfe/protocols/openmm_md/plain_md_methods.py index a0f442e82..d53f58412 100644 --- a/openfe/protocols/openmm_md/plain_md_methods.py +++ b/openfe/protocols/openmm_md/plain_md_methods.py @@ -32,8 +32,12 @@ settings, ChemicalSystem, SmallMoleculeComponent, ProteinComponent, SolventComponent ) +from openfe.protocols.openmm_utils.omm_settings import ( + BasePartialChargeSettings, +) from openfe.protocols.openmm_md.plain_md_settings import ( PlainMDProtocolSettings, + OpenFFPartialChargeSettings, OpenMMSolvationSettings, OpenMMEngineSettings, IntegratorSettings, MDSimulationSettings, MDOutputSettings, ) @@ -121,6 +125,7 @@ def _default_settings(cls): temperature=298.15 * unit.kelvin, pressure=1 * unit.bar, ), + partial_charge_settings=OpenFFPartialChargeSettings(), solvation_settings=OpenMMSolvationSettings(), engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), @@ -391,10 +396,12 @@ def _run_MD(simulation: openmm.app.Simulation, logger.info("running production phase") # Setup the reporters - - # TODO: write_interval should probably not be in units of - # timestep but time - Issue #716 - write_interval = output_settings.trajectory_write_interval.m + write_interval = settings_validation.divmod_time_and_check( + output_settings.trajectory_write_interval, + timestep, + "trajectory_write_interval", + "timestep", + ) checkpoint_interval = settings_validation.get_simsteps( sim_length=output_settings.checkpoint_interval, diff --git a/openfe/protocols/openmm_utils/omm_settings.py b/openfe/protocols/openmm_utils/omm_settings.py index 5968c392f..253bb6dfb 100644 --- a/openfe/protocols/openmm_utils/omm_settings.py +++ b/openfe/protocols/openmm_utils/omm_settings.py @@ -379,7 +379,7 @@ class Config: # reporter settings production_trajectory_filename = 'simulation.xtc' """Path to the storage file for analysis. Default 'simulation.xtc'.""" - trajectory_write_interval = 5000 * unit.timestep + trajectory_write_interval: FloatQuantity['picosecond'] = 20 * unit.picosecond """ Frequency to write the xtc file. Default 5000 * unit.timestep. """ From 0e99b01df79815c4c071bc72dd4d7c83992c8cdd Mon Sep 17 00:00:00 2001 From: richard gowers Date: Tue, 13 Feb 2024 11:11:07 +0000 Subject: [PATCH 10/11] remove obsolete TODO from tests checkpoint_interval isn't going to be an IntQuantity any more --- openfe/tests/protocols/test_openmm_settings.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_settings.py b/openfe/tests/protocols/test_openmm_settings.py index 622ebf5b7..c1937ab4a 100644 --- a/openfe/tests/protocols/test_openmm_settings.py +++ b/openfe/tests/protocols/test_openmm_settings.py @@ -54,8 +54,6 @@ def test_simulation_settings(self): assert s.equilibration_length == 2.5 * unit.nanosecond assert s.production_length == 10.0 * unit.nanosecond - # todo: checkpoint_interval IntQuantity - class TestEquilRFESettingsFromString: def test_alchemical_settings(self): From b43d667d494f9ec688802bbc063bcaf49c1be21a Mon Sep 17 00:00:00 2001 From: richard gowers Date: Tue, 13 Feb 2024 11:18:17 +0000 Subject: [PATCH 11/11] fixup tests for new error message on time conversion --- openfe/tests/protocols/test_openmmutils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openfe/tests/protocols/test_openmmutils.py b/openfe/tests/protocols/test_openmmutils.py index 163f64b53..f41cc5bd8 100644 --- a/openfe/tests/protocols/test_openmmutils.py +++ b/openfe/tests/protocols/test_openmmutils.py @@ -412,7 +412,7 @@ def test_convert_steps_per_iteration_failure(): timestep='3 fs' ) - with pytest.raises(ValueError, match="not divisible"): + with pytest.raises(ValueError, match="does not evenly divide"): settings_validation.convert_steps_per_iteration(sim, inty) @@ -440,7 +440,7 @@ def test_convert_real_time_analysis_iterations_interval_fail(): real_time_analysis_minimum_time='500 ps', ) - with pytest.raises(ValueError, match='not divisible'): + with pytest.raises(ValueError, match='does not evenly divide'): settings_validation.convert_real_time_analysis_iterations(sim) @@ -454,7 +454,7 @@ def test_convert_real_time_analysis_iterations_min_interval_fail(): real_time_analysis_minimum_time='500.5 ps', ) - with pytest.raises(ValueError, match='not divisible'): + with pytest.raises(ValueError, match='does not evenly divide'): settings_validation.convert_real_time_analysis_iterations(sim)