From 3a64347f1f5c881d7afbee8f1f8de606e3b17fd5 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 23 Oct 2024 14:48:10 +0200 Subject: [PATCH 001/163] Initial commit SepTop settings --- .../openmm_septop/equil_septop_settings.py | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 openfe/protocols/openmm_septop/equil_septop_settings.py diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py new file mode 100644 index 000000000..7834703ce --- /dev/null +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -0,0 +1,212 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe + +"""Settings class for equilibrium SepTop Protocols using OpenMM + OpenMMTools + +This module implements the necessary settings necessary to run SepTop RBFE +calculations using OpenMM. + +See Also +-------- +openfe.protocols.openmm_septop.SepTopProtocol +""" +from gufe.settings import ( + SettingsBaseModel, + OpenMMSystemGeneratorFFSettings, + ThermoSettings, +) +from openfe.protocols.openmm_utils.omm_settings import ( + MultiStateSimulationSettings, + OpenMMSolvationSettings, + OpenMMEngineSettings, + IntegratorSettings, + OpenFFPartialChargeSettings, + MultiStateOutputSettings, + MDSimulationSettings, + MDOutputSettings, +) +import numpy as np +from pydantic.v1 import validator + + +class AlchemicalSettings(SettingsBaseModel): + """Settings for the alchemical protocol + + Empty place holder for right now. + """ + + +class LambdaSettings(SettingsBaseModel): + """Lambda schedule settings. + + Defines lists of floats to control various aspects of the alchemical + transformation. + + Notes + ----- + * In all cases a lambda value of 0 defines a fully interacting state A and + a non-interacting state B, whilst a value of 1 defines a fully interacting + state B and a non-interacting state A. + * ``lambda_elec``, `lambda_vdw``, and ``lambda_restraints`` must all be of + the same length, defining all the windows of the transformation. + + """ + lambda_elec: list[float] = [ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 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, + ] + """ + List of floats of lambda values for the electrostatics. + Zero means state A and 1 means state B. + Length of this list needs to match length of lambda_vdw and lambda_restraints. + """ + lambda_vdw: list[float] = [ + 0.0, 0.142857143, 0.285714286, 0.428571429, 0.571428571, 0.714285714, + 0.857142857, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + ] + """ + List of floats of lambda values for the van der Waals. + Zero means state A and 1 means state B. + Length of this list needs to match length of lambda_elec and lambda_restraints. + """ + lambda_restraints: list[float] = [ + 0.0, 0.05, 0.3, 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, + ] + """ + List of floats of lambda values for the restraints. + Zero means state A and 1 means state B. + Length of this list needs to match length of lambda_vdw and lambda_elec. + """ + + @validator('lambda_elec', 'lambda_vdw', 'lambda_restraints') + def must_be_between_0_and_1(cls, v): + for window in v: + if not 0 <= window <= 1: + errmsg = ("Lambda windows must be between 0 and 1, got a" + f" window with value {window}.") + raise ValueError(errmsg) + return v + + @validator('lambda_elec', 'lambda_vdw', 'lambda_restraints') + def must_be_monotonic(cls, v): + + difference = np.diff(v) + + if not all(i >= 0. for i in difference): + errmsg = f"The lambda schedule is not monotonic, got schedule {v}." + raise ValueError(errmsg) + + return v + + +# This subclasses from SettingsBaseModel as it has vacuum_forcefield and +# solvent_forcefield fields, not just a single forcefield_settings field +class SepTopSettings(SettingsBaseModel): + """ + Configuration object for ``AbsoluteSolvationProtocol``. + + See Also + -------- + openfe.protocols.openmm_afe.AbsoluteSolvationProtocol + """ + protocol_repeats: int + """ + The number of completely independent repeats of the entire sampling + process. The mean of the repeats defines the final estimate of FE + difference, while the variance between repeats is used as the uncertainty. + """ + + @validator('protocol_repeats') + def must_be_positive(cls, v): + if v <= 0: + errmsg = f"protocol_repeats must be a positive value, got {v}." + raise ValueError(errmsg) + return v + + # Inherited things + solvent_forcefield_settings: OpenMMSystemGeneratorFFSettings + vacuum_forcefield_settings: OpenMMSystemGeneratorFFSettings + """Parameters to set up the force field with OpenMM Force Fields""" + thermo_settings: ThermoSettings + """Settings for thermodynamic parameters""" + + solvation_settings: OpenMMSolvationSettings + """Settings for solvating the system.""" + + # Alchemical settings + alchemical_settings: AlchemicalSettings + """ + Alchemical protocol settings. + """ + lambda_settings: LambdaSettings + """ + Settings for controlling the lambda schedule for the different components + (vdw, elec, restraints). + """ + + # MD Engine things + vacuum_engine_settings: OpenMMEngineSettings + """ + Settings specific to the OpenMM engine, such as the compute platform + for the vacuum transformation. + """ + solvent_engine_settings: OpenMMEngineSettings + """ + Settings specific to the OpenMM engine, such as the compute platform + for the solvent transformation. + """ + + # Sampling State defining things + integrator_settings: IntegratorSettings + """ + Settings for controlling the integrator, such as the timestep and + barostat settings. + """ + + # 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: MultiStateOutputSettings + """ + Simulation output settings for the vacuum transformation. + """ + solvent_equil_output_settings: MDOutputSettings + """ + Simulation output settings for the solvent non-alchemical equilibration. + """ + solvent_output_settings: MultiStateOutputSettings + """ + Simulation output settings for the solvent transformation. + """ + partial_charge_settings: OpenFFPartialChargeSettings + """ + Settings for controlling how to assign partial charges, + including the partial charge assignment method, and the + number of conformers used to generate the partial charges. + """ From 066c47bb889bfa1c7bb40b54b21ee46267785044 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 24 Oct 2024 14:21:38 +0200 Subject: [PATCH 002/163] Initial SepTop protocol work --- openfe/protocols/openmm_septop/__init__.py | 22 + openfe/protocols/openmm_septop/base.py | 862 +++++++++++++++++ .../openmm_septop/equil_septop_method.py | 915 ++++++++++++++++++ .../openmm_septop/equil_septop_settings.py | 27 +- .../protocols/test_openmm_septop_protocol.py | 308 ++++++ 5 files changed, 2118 insertions(+), 16 deletions(-) create mode 100644 openfe/protocols/openmm_septop/__init__.py create mode 100644 openfe/protocols/openmm_septop/base.py create mode 100644 openfe/protocols/openmm_septop/equil_septop_method.py create mode 100644 openfe/tests/protocols/test_openmm_septop_protocol.py diff --git a/openfe/protocols/openmm_septop/__init__.py b/openfe/protocols/openmm_septop/__init__.py new file mode 100644 index 000000000..3da40f8dc --- /dev/null +++ b/openfe/protocols/openmm_septop/__init__.py @@ -0,0 +1,22 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Run SepTop free energy calculations using OpenMM and OpenMMTools. + +""" + +from .equil_septop_method import ( + SepTopProtocol, + SepTopSettings, + SepTopProtocolResult, + SepTopComplexUnit, + SepTopSolventUnit, +) + +__all__ = [ + "SepTopProtocol", + "SepTopSettings", + "SepTopProtocolResult", + "SepTopComplexUnit", + "SepTopSolventUnit", +] diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py new file mode 100644 index 000000000..61c91e317 --- /dev/null +++ b/openfe/protocols/openmm_septop/base.py @@ -0,0 +1,862 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +"""OpenMM Equilibrium SepTop Protocol base classes +================================================== + +Base classes for the equilibrium OpenMM SepTop free energy ProtocolUnits. + +Thist mostly implements BaseSepTopUnit whose methods can be +overriden to define different types of alchemical transformations. + +TODO +---- +* Add in all the AlchemicalFactory and AlchemicalRegion kwargs + as settings. +* Allow for a more flexible setting of Lambda regions. +""" +from __future__ import annotations + +import abc +import os +import logging + +import gufe +from gufe.components import Component +import numpy as np +import numpy.typing as npt +import openmm +from openff.units import unit +from openff.units.openmm import from_openmm, to_openmm, ensure_quantity +from openff.toolkit.topology import Molecule as OFFMolecule +from openmmtools import multistate +from openmmtools.states import (SamplerState, + ThermodynamicState, + create_thermodynamic_state_protocol,) +from openmmtools.alchemy import (AlchemicalRegion, AbsoluteAlchemicalFactory, + AlchemicalState,) +from typing import Optional +from openmm import app +from openmm import unit as omm_unit +from openmmforcefields.generators import SystemGenerator +import pathlib +from typing import Any +import openmmtools +import mdtraj as mdt + +from gufe import ( + settings, ChemicalSystem, SmallMoleculeComponent, + ProteinComponent, SolventComponent +) +from openfe.protocols.openmm_utils.omm_settings import ( + SettingsBaseModel, +) +from openfe.protocols.openmm_utils.omm_settings import ( + BasePartialChargeSettings, +) +from openfe.protocols.openmm_afe.equil_afe_settings import ( + BaseSolvationSettings, + MultiStateSimulationSettings, OpenMMEngineSettings, + IntegratorSettings, LambdaSettings, MultiStateOutputSettings, + ThermoSettings, OpenFFPartialChargeSettings, +) +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, charge_generation +) +from openfe.utils import without_oechem_backend + + +logger = logging.getLogger(__name__) + + +class BaseSepTopUnit(gufe.ProtocolUnit): + """ + Base class for ligand SepTop RBFE free energy transformations. + """ + def __init__(self, *, + protocol: gufe.Protocol, + stateA: ChemicalSystem, + stateB: ChemicalSystem, + alchemical_components: dict[str, list[Component]], + generation: int = 0, + repeat_id: int = 0, + name: Optional[str] = None,): + """ + Parameters + ---------- + protocol : gufe.Protocol + protocol used to create this Unit. Contains key information such + as the settings. + stateA : ChemicalSystem + ChemicalSystem containing the components defining the state at + lambda 0. + stateB : ChemicalSystem + ChemicalSystem containing the components defining the state at + lambda 1. + alchemical_components : dict[str, Component] + the alchemical components for each state in this Unit + name : str, optional + Human-readable identifier for this Unit + repeat_id : int, optional + Identifier for which repeat (aka replica/clone) this Unit is, + default 0 + generation : int, optional + Generation counter which keeps track of how many times this repeat + has been extended, default 0. + """ + super().__init__( + name=name, + protocol=protocol, + stateA=stateA, + stateB=stateB, + alchemical_components=alchemical_components, + repeat_id=repeat_id, + generation=generation, + ) + + @staticmethod + def _get_alchemical_indices(omm_top: openmm.Topology, + comp_resids: dict[Component, npt.NDArray], + alchem_comps: dict[str, list[Component]] + ) -> list[int]: + """ + Get a list of atom indices for all the alchemical species + + Parameters + ---------- + omm_top : openmm.Topology + Topology of OpenMM System. + comp_resids : dict[Component, npt.NDArray] + A dictionary of residues for each component in the System. + alchem_comps : dict[str, list[Component]] + A dictionary of alchemical components for each end state. + + Return + ------ + atom_ids : list[int] + A list of atom indices for the alchemical species + """ + + # concatenate a list of residue indexes for all alchemical components + residxs = np.concatenate( + [comp_resids[key] for key in alchem_comps['stateA']] + ) + + # get the alchemicical atom ids + atom_ids = [] + + for r in omm_top.residues(): + if r.index in residxs: + atom_ids.extend([at.index for at in r.atoms()]) + + return atom_ids + + def _pre_equilibrate( + self, + system: openmm.System, + topology: openmm.app.Topology, + positions: omm_unit.Quantity, + settings: dict[str, SettingsBaseModel], + dry: bool + ) -> omm_unit.Quantity: + """ + Run a non-alchemical equilibration to get a stable system. + + Parameters + ---------- + system : openmm.System + 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 + ------- + equilibrated_positions : npt.NDArray + Equilibrated system 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, + ) + + # Get the necessary number of steps + if settings['equil_simulation_settings'].equilibration_length_nvt is not None: + equil_steps_nvt = settings_validation.get_simsteps( + sim_length=settings[ + 'equil_simulation_settings'].equilibration_length_nvt, + timestep=settings['integrator_settings'].timestep, + mc_steps=1, + ) + else: + equil_steps_nvt = None + + 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, + timestep=settings['integrator_settings'].timestep, + 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 = 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, + scratch_basepath: Optional[pathlib.Path], + shared_basepath: Optional[pathlib.Path], + ): + """ + Set basepaths and do some initial logging. + + Parameters + ---------- + verbose : bool + Verbose output of the simulation progress. Output is provided via + INFO level logging. + basepath : Optional[pathlib.Path] + Optional base path to write files to. + """ + self.verbose = verbose + + if self.verbose: + self.logger.info("setting up alchemical system") + + # set basepaths + def _set_optional_path(basepath): + if basepath is None: + return pathlib.Path('.') + return basepath + + self.scratch_basepath = _set_optional_path(scratch_basepath) + self.shared_basepath = _set_optional_path(shared_basepath) + + @abc.abstractmethod + def _get_components(self) -> tuple[dict[str, list[Component]], + Optional[gufe.SolventComponent], + Optional[gufe.ProteinComponent], + dict[SmallMoleculeComponent, OFFMolecule]]: + """ + Get the relevant components to create the alchemical system with. + + Note + ---- + Must be implemented in the child class. + """ + ... + + @abc.abstractmethod + def _handle_settings(self): + """ + Get a dictionary with the following entries: + * forcefield_settings : OpenMMSystemGeneratorFFSettings + * thermo_settings : ThermoSettings + * solvation_settings : BaseSolvationSettings + * alchemical_settings : AlchemicalSettings + * lambda_settings : LambdaSettings + * engine_settings : OpenMMEngineSettings + * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings + * simulation_settings : MultiStateSimulationSettings + * output_settings : MultiStateOutputSettings + + Settings may change depending on what type of simulation you are + running. Cherry pick them and return them to be available later on. + + This method should also add various validation checks as necessary. + + Note + ---- + Must be implemented in the child class. + """ + ... + + def _get_system_generator( + self, settings: dict[str, SettingsBaseModel], + solvent_comp: Optional[SolventComponent] + ) -> SystemGenerator: + """ + Get a system generator through the system creation + utilities + + Parameters + ---------- + settings : dict[str, SettingsBaseModel] + A dictionary of settings object for the unit. + solvent_comp : Optional[SolventComponent] + The solvent component of this system, if there is one. + + Returns + ------- + system_generator : openmmforcefields.generator.SystemGenerator + System Generator to parameterise this unit. + """ + ffcache = settings['output_settings'].forcefield_cache + if ffcache is not None: + ffcache = self.shared_basepath / ffcache + + # Block out oechem backend to avoid any issues with + # smiles roundtripping between rdkit and oechem + with without_oechem_backend(): + system_generator = system_creation.get_system_generator( + forcefield_settings=settings['forcefield_settings'], + integrator_settings=settings['integrator_settings'], + thermo_settings=settings['thermo_settings'], + cache=ffcache, + has_solvent=solvent_comp is not None, + ) + return system_generator + + @staticmethod + def _assign_partial_charges( + partial_charge_settings: OpenFFPartialChargeSettings, + smc_components: dict[SmallMoleculeComponent, OFFMolecule], + ) -> None: + """ + Assign partial charges to SMCs. + + Parameters + ---------- + charge_settings : OpenFFPartialChargeSettings + Settings for controlling how the partial charges are assigned. + smc_components : dict[SmallMoleculeComponent, openff.toolkit.Molecule] + Dictionary of OpenFF Molecules to add, keyed by + SmallMoleculeComponent. + """ + for mol in smc_components.values(): + charge_generation.assign_offmol_partial_charges( + offmol=mol, + overwrite=False, + method=partial_charge_settings.partial_charge_method, + toolkit_backend=partial_charge_settings.off_toolkit_backend, + generate_n_conformers=partial_charge_settings.number_of_conformers, + nagl_model=partial_charge_settings.nagl_model, + ) + + def _get_modeller( + self, + protein_component: Optional[ProteinComponent], + solvent_component: Optional[SolventComponent], + smc_components: dict[SmallMoleculeComponent, OFFMolecule], + system_generator: SystemGenerator, + partial_charge_settings: BasePartialChargeSettings, + solvation_settings: BaseSolvationSettings + ) -> tuple[app.Modeller, dict[Component, npt.NDArray]]: + """ + Get an OpenMM Modeller object and a list of residue indices + for each component in the system. + + Parameters + ---------- + protein_component : Optional[ProteinComponent] + Protein Component, if it exists. + solvent_component : Optional[ProteinCompoinent] + Solvent Component, if it exists. + smc_components : dict[SmallMoleculeComponent, openff.toolkit.Molecule] + Dictionary of OpenFF Molecules to add, keyed by + SmallMoleculeComponent. + system_generator : openmmforcefields.generator.SystemGenerator + System Generator to parameterise this unit. + partial_charge_settings : BasePartialChargeSettings + Settings detailing how to assign partial charges to the + SMCs of the system. + solvation_settings : BaseSolvationSettings + Settings detailing how to solvate the system. + + Returns + ------- + system_modeller : app.Modeller + OpenMM Modeller object generated from ProteinComponent and + OpenFF Molecules. + comp_resids : dict[Component, npt.NDArray] + Dictionary of residue indices for each component in system. + """ + if self.verbose: + self.logger.info("Parameterizing molecules") + + # Assign partial charges to smcs + self._assign_partial_charges(partial_charge_settings, smc_components) + + # TODO: guard the following from non-RDKit backends + # force the creation of parameters for the small molecules + # this is necessary because we need to have the FF generated ahead + # of solvating the system. + # Block out oechem backend to avoid any issues with + # smiles roundtripping between rdkit and oechem + with without_oechem_backend(): + for mol in smc_components.values(): + system_generator.create_system( + mol.to_topology().to_openmm(), molecules=[mol] + ) + + # get OpenMM modeller + dictionary of resids for each component + system_modeller, comp_resids = system_creation.get_omm_modeller( + protein_comp=protein_component, + solvent_comp=solvent_component, + small_mols=smc_components, + omm_forcefield=system_generator.forcefield, + solvent_settings=solvation_settings, + ) + + return system_modeller, comp_resids + + def _get_omm_objects( + self, + system_modeller: app.Modeller, + system_generator: SystemGenerator, + smc_components: list[OFFMolecule], + ) -> tuple[app.Topology, openmm.unit.Quantity, openmm.System]: + """ + Get the OpenMM Topology, Positions and System of the + parameterised system. + + Parameters + ---------- + system_modeller : app.Modeller + OpenMM Modeller object representing the system to be + parametrized. + system_generator : SystemGenerator + SystemGenerator object to create a System with. + smc_components : list[openff.toolkit.Molecule] + A list of openff Molecules to add to the system. + + Returns + ------- + topology : app.Topology + Topology object describing the parameterized system + system : openmm.System + An OpenMM System of the alchemical system. + positionns : openmm.unit.Quantity + Positions of the system. + """ + topology = system_modeller.getTopology() + # roundtrip positions to remove vec3 issues + positions = to_openmm(from_openmm(system_modeller.getPositions())) + + # Block out oechem backend to avoid any issues with + # smiles roundtripping between rdkit and oechem + with without_oechem_backend(): + system = system_generator.create_system( + system_modeller.topology, + molecules=smc_components, + ) + return topology, system, positions + + def _get_lambda_schedule( + self, settings: dict[str, SettingsBaseModel] + ) -> dict[str, npt.NDArray]: + """ + Create the lambda schedule + + Parameters + ---------- + settings : dict[str, SettingsBaseModel] + Settings for the unit. + + Returns + ------- + lambdas : dict[str, npt.NDArray] + + TODO + ---- + * Augment this by using something akin to the RFE protocol's + LambdaProtocol + """ + lambdas = dict() + + lambda_elec = settings['lambda_settings'].lambda_elec + lambda_vdw = settings['lambda_settings'].lambda_vdw + + # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 + # means fully interacting, not stateB + lambda_elec = [1-x for x in lambda_elec] + lambda_vdw = [1-x for x in lambda_vdw] + lambdas['lambda_electrostatics'] = lambda_elec + lambdas['lambda_sterics'] = lambda_vdw + + return lambdas + + def _add_restraints(self, system, topology, settings): + """ + Placeholder method to add restraints if necessary + """ + return + + def _get_alchemical_system( + self, + topology: app.Topology, + system: openmm.System, + comp_resids: dict[Component, npt.NDArray], + alchem_comps: dict[str, list[Component]] + ): + """ + Empty placeholder for getting + an alchemically modified system and its associated factory + """ + + return + + def _get_states( + self, + alchemical_system: openmm.System, + positions: openmm.unit.Quantity, + settings: dict[str, SettingsBaseModel], + lambdas: dict[str, npt.NDArray], + solvent_comp: Optional[SolventComponent], + ) -> tuple[list[SamplerState], list[ThermodynamicState]]: + """ + Empty placeholder for getting + a list of sampler and thermodynmic states from an + input alchemical system. + """ + + return + + def _get_reporter( + self, + topology: app.Topology, + positions: openmm.unit.Quantity, + simulation_settings: MultiStateSimulationSettings, + output_settings: MultiStateOutputSettings, + ) -> multistate.MultiStateReporter: + """ + Empty placeholder for getting a MultistateReporter for the simulation you are running. + """ + + return + + def _get_ctx_caches( + self, + engine_settings: OpenMMEngineSettings + ) -> tuple[openmmtools.cache.ContextCache, openmmtools.cache.ContextCache]: + """ + Empty placeholder for getting the context caches based on the chosen platform + + """ + + return + + @staticmethod + def _get_integrator( + 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. + """ + steps_per_iteration = settings_validation.convert_steps_per_iteration( + simulation_settings, integrator_settings + ) + + integrator = openmmtools.mcmc.LangevinDynamicsMove( + timestep=to_openmm(integrator_settings.timestep), + 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( + integrator: openmmtools.mcmc.LangevinDynamicsMove, + reporter: openmmtools.multistate.MultiStateReporter, + simulation_settings: MultiStateSimulationSettings, + thermo_settings: ThermoSettings, + cmp_states: list[ThermodynamicState], + sampler_states: list[SamplerState], + energy_context_cache: openmmtools.cache.ContextCache, + sampler_context_cache: openmmtools.cache.ContextCache + ) -> multistate.MultiStateSampler: + """ + Get a sampler based on the equilibrium sampling method requested. + + Parameters + ---------- + integrator : openmmtools.mcmc.LangevinDynamicsMove + The simulation integrator. + reporter : openmmtools.multistate.MultiStateReporter + The reporter to hook up to the sampler. + 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] + A list of sampler states. + energy_context_cache : openmmtools.cache.ContextCache + Context cache for the energy states. + sampler_context_cache : openmmtool.cache.ContextCache + Context cache for the sampler states. + + Returns + ------- + 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_from_kcal_per_mole_to_kT( + thermo_settings.temperature, + simulation_settings.early_termination_target_error, + ) + + # Select the right sampler + # Note: doesn't need else, settings already validates choices + if simulation_settings.sampler_method.lower() == "repex": + sampler = multistate.ReplicaExchangeSampler( + mcmc_moves=integrator, + online_analysis_interval=rta_its, + online_analysis_target_error=et_target_err, + online_analysis_minimum_iterations=rta_min_its + ) + elif simulation_settings.sampler_method.lower() == "sams": + sampler = multistate.SAMSSampler( + mcmc_moves=integrator, + 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 simulation_settings.sampler_method.lower() == 'independent': + sampler = multistate.MultiStateSampler( + mcmc_moves=integrator, + online_analysis_interval=rta_its, + online_analysis_target_error=et_target_err, + online_analysis_minimum_iterations=rta_min_its, + ) + + sampler.create( + thermodynamic_states=cmp_states, + sampler_states=sampler_states, + storage=reporter + ) + + sampler.energy_context_cache = energy_context_cache + sampler.sampler_context_cache = sampler_context_cache + + return sampler + + def _run_simulation( + self, + sampler: multistate.MultiStateSampler, + reporter: multistate.MultiStateReporter, + settings: dict[str, SettingsBaseModel], + dry: bool + ): + """ + Empty placeholder for running the simulation. + + """ + return + + def run(self, dry=False, verbose=True, + scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: + """ + Run the SepTop free energy calculation. + + Parameters + ---------- + dry : bool + Do a dry run of the calculation, creating all necessary alchemical + system components (topology, system, sampler, etc...) but without + running the simulation, default False + verbose : bool + Verbose output of the simulation progress. Output is provided via + INFO level logging, default True + scratch_basepath : pathlib.Path + Path to the scratch (temporary) directory space. + shared_basepath : pathlib.Path + Path to the shared (persistent) directory space. + + Returns + ------- + dict + Outputs created in the basepath directory or the debug objects + (i.e. sampler) if ``dry==True``. + """ + # 0. Generaly preparation tasks + self._prepare(verbose, scratch_basepath, shared_basepath) + + # 1. Get components + alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() + + # 2. Get settings + settings = self._handle_settings() + + # 3. Get system generator + system_generator = self._get_system_generator(settings, solv_comp) + + # 4. Get modeller + system_modeller, comp_resids = self._get_modeller( + prot_comp, solv_comp, smc_comps, system_generator, + settings['charge_settings'], + settings['solvation_settings'], + ) + + # 5. Get OpenMM topology, positions and system + omm_topology, omm_system, positions = self._get_omm_objects( + system_modeller, system_generator, list(smc_comps.values()) + ) + + # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) + positions = self._pre_equilibrate( + omm_system, omm_topology, positions, settings, dry + ) + + # 7. Get lambdas + lambdas = self._get_lambda_schedule(settings) + + # # 8. Add restraints + # self._add_restraints(omm_system, omm_topology, settings) + # + # # 9. Get alchemical system + # alchem_factory, alchem_system, alchem_indices = self._get_alchemical_system( + # omm_topology, omm_system, comp_resids, alchem_comps + # ) + # + # # 10. Get compound and sampler states + # sampler_states, cmp_states = self._get_states( + # alchem_system, positions, settings, + # lambdas, solv_comp + # ) + # + # # 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 + # try: + # # 12. Get context caches + # energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( + # settings['engine_settings'] + # ) + # + # # 13. Get integrator + # integrator = self._get_integrator( + # settings['integrator_settings'], + # settings['simulation_settings'], + # ) + # + # # 14. Get sampler + # sampler = self._get_sampler( + # integrator, reporter, settings['simulation_settings'], + # settings['thermo_settings'], + # cmp_states, sampler_states, + # energy_ctx_cache, sampler_ctx_cache + # ) + # + # # 15. Run simulation + # unit_result_dict = self._run_simulation( + # sampler, reporter, settings, dry + # ) + # + # finally: + # # close reporter when you're done to prevent file handle clashes + # reporter.close() + # + # # clear GPU context + # # Note: use cache.empty() when openmmtools #690 is resolved + # for context in list(energy_ctx_cache._lru._data.keys()): + # del energy_ctx_cache._lru._data[context] + # for context in list(sampler_ctx_cache._lru._data.keys()): + # del sampler_ctx_cache._lru._data[context] + # # cautiously clear out the global context cache too + # for context in list( + # openmmtools.cache.global_context_cache._lru._data.keys()): + # del openmmtools.cache.global_context_cache._lru._data[context] + # + # del sampler_ctx_cache, energy_ctx_cache + # + # # Keep these around in a dry run so we can inspect things + # if not dry: + # del integrator, sampler + # + # if not dry: + # nc = self.shared_basepath / settings['output_settings'].output_filename + # chk = settings['output_settings'].checkpoint_storage_filename + # return { + # 'nc': nc, + # 'last_checkpoint': chk, + # **unit_result_dict, + # } + # else: + # return {'debug': {'sampler': sampler}} diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py new file mode 100644 index 000000000..8c278cecc --- /dev/null +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -0,0 +1,915 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +"""OpenMM Equilibrium SepTop RBFE Protocol --- :mod:`openfe.protocols.openmm_septop.equil_septop_method` +=============================================================================================================== + +This module implements the necessary methodology tooling to run a +Separated Topologies RBFE calculation using OpenMM tools and one of the +following alchemical sampling methods: + +* Hamiltonian Replica Exchange +* Self-adjusted mixture sampling +* Independent window sampling + +Current limitations +------------------- + +* Only small molecules are allowed to act as alchemical molecules. + Alchemically changing protein or solvent components would induce + perturbations which are too large to be handled by this Protocol. + + +Acknowledgements +---------------- + +""" +from __future__ import annotations + +import pathlib +import logging +import warnings +from collections import defaultdict +import gufe +from gufe.components import Component +import itertools +import numpy as np +import numpy.typing as npt +from openff.units import unit +from openmmtools import multistate +from typing import Optional, Union +from typing import Any, Iterable +import uuid + +from gufe import ( + settings, + ChemicalSystem, SmallMoleculeComponent, + ProteinComponent, SolventComponent +) +from openfe.protocols.openmm_septop.equil_septop_settings import ( + SepTopSettings, + OpenMMSolvationSettings, AlchemicalSettings, LambdaSettings, + MDSimulationSettings, MDOutputSettings, + MultiStateSimulationSettings, OpenMMEngineSettings, + IntegratorSettings, MultiStateOutputSettings, + OpenFFPartialChargeSettings, + SettingsBaseModel, +) +from ..openmm_utils import system_validation, settings_validation +from .base import BaseSepTopUnit +from openfe.utils import log_system_probe +from openfe.due import due, Doi + + + +due.cite(Doi("10.5281/zenodo.596622"), + description="OpenMMTools", + path="openfe.protocols.openmm_septop.equil_septop_method", + cite_module=True) + +due.cite(Doi("10.1371/journal.pcbi.1005659"), + description="OpenMM", + path="openfe.protocols.openmm_septop.equil_septop_method", + cite_module=True) + + +logger = logging.getLogger(__name__) + + +class SepTopProtocolResult(gufe.ProtocolResult): + """Dict-like container for the output of a SepTopProtocol + """ + def __init__(self, **data): + super().__init__(**data) + # TODO: Detect when we have extensions and stitch these together? + if any(len(pur_list) > 2 for pur_list + in itertools.chain(self.data['solvent'].values(), self.data['complex'].values())): + raise NotImplementedError("Can't stitch together results yet") + + def get_individual_estimates(self) -> dict[str, list[tuple[unit.Quantity, unit.Quantity]]]: + """ + Get the individual estimate of the free energies. + + Returns + ------- + dGs : dict[str, list[tuple[unit.Quantity, unit.Quantity]]] + A dictionary, keyed `solvent` and `complex for each leg + of the thermodynamic cycle, with lists of tuples containing + the individual free energy estimates and associated MBAR + uncertainties for each repeat of that simulation type. + """ + complex_dGs = [] + solv_dGs = [] + + for pus in self.data['complex'].values(): + complex_dGs.append(( + pus[0].outputs['unit_estimate'], + pus[0].outputs['unit_estimate_error'] + )) + + for pus in self.data['solvent'].values(): + solv_dGs.append(( + pus[0].outputs['unit_estimate'], + pus[0].outputs['unit_estimate_error'] + )) + + return {'solvent': solv_dGs, 'complex': complex_dGs} + + def get_estimate(self): + """Get the difference in binding free energy estimate for this calculation. + + Returns + ------- + ddG : unit.Quantity + The difference in binding free energy. + This is a Quantity defined with units. + """ + def _get_average(estimates): + # Get the unit value of the first value in the estimates + u = estimates[0][0].u + # Loop through estimates and get the free energy values + # in the unit of the first estimate + ddGs = [i[0].to(u).m for i in estimates] + + return np.average(ddGs) * u + + individual_estimates = self.get_individual_estimates() + solv_ddG = _get_average(individual_estimates['solvent']) + complex_ddG = _get_average(individual_estimates['complex']) + return solv_ddG - complex_ddG + + + def get_uncertainty(self): + """Get the relative free energy error for this calculation. + + Returns + ------- + err : unit.Quantity + The standard deviation between estimates of the relative binding free + energy. This is a Quantity defined with units. + """ + def _get_stdev(estimates): + # Get the unit value of the first value in the estimates + u = estimates[0][0].u + # Loop through estimates and get the free energy values + # in the unit of the first estimate + ddGs = [i[0].to(u).m for i in estimates] + + return np.std(ddGs) * u + + individual_estimates = self.get_individual_estimates() + solv_err = _get_stdev(individual_estimates['solvent']) + complex_err = _get_stdev(individual_estimates['complex']) + + # return the combined error + return np.sqrt(solv_err**2 + complex_err**2) + + def get_forward_and_reverse_energy_analysis(self) -> dict[str, list[Optional[dict[str, Union[npt.NDArray, unit.Quantity]]]]]: + """ + Get the reverse and forward analysis of the free energies. + + Returns + ------- + forward_reverse : dict[str, list[Optional[dict[str, Union[npt.NDArray, unit.Quantity]]]]] + A dictionary, keyed `complex` and `solvent` for each leg of the + thermodynamic cycle which each contain a list of dictionaries + containing the forward and reverse analysis of each repeat + of that simulation type. + + The forward and reverse analysis dictionaries contain: + - `fractions`: npt.NDArray + The fractions of data used for the estimates + - `forward_DDGs`, `reverse_DDGs`: unit.Quantity + The forward and reverse estimates for each fraction of data + - `forward_dDDGs`, `reverse_dDDGs`: unit.Quantity + The forward and reverse estimate uncertainty for each + fraction of data. + + If one of the cycle leg list entries is ``None``, this indicates + that the analysis could not be carried out for that repeat. This + is most likely caused by MBAR convergence issues when attempting to + calculate free energies from too few samples. + + Raises + ------ + UserWarning + * If any of the forward and reverse dictionaries are ``None`` in a + given thermodynamic cycle leg. + """ + + forward_reverse: dict[str, list[Optional[dict[str, Union[npt.NDArray, unit.Quantity]]]]] = {} + + for key in ['complex', 'solvent']: + forward_reverse[key] = [ + pus[0].outputs['forward_and_reverse_energies'] + for pus in self.data[key].values() + ] + + if None in forward_reverse[key]: + wmsg = ( + "One or more ``None`` entries were found in the forward " + f"and reverse dictionaries of the repeats of the {key} " + "calculations. This is likely caused by an MBAR convergence " + "failure caused by too few independent samples when " + "calculating the free energies of the 10% timeseries slice." + ) + warnings.warn(wmsg) + + return forward_reverse + + def get_overlap_matrices(self) -> dict[str, list[dict[str, npt.NDArray]]]: + """ + Get a the MBAR overlap estimates for all legs of the simulation. + + Returns + ------- + overlap_stats : dict[str, list[dict[str, npt.NDArray]]] + A dictionary with keys `complex` and `solvent` for each + leg of the thermodynamic cycle, which each containing a + list of dictionaries with the MBAR overlap estimates of + each repeat of that simulation type. + + The underlying MBAR dictionaries contain the following keys: + * ``scalar``: One minus the largest nontrivial eigenvalue + * ``eigenvalues``: The sorted (descending) eigenvalues of the + overlap matrix + * ``matrix``: Estimated overlap matrix of observing a sample from + state i in state j + """ + # Loop through and get the repeats and get the matrices + overlap_stats: dict[str, list[dict[str, npt.NDArray]]] = {} + + for key in ['complex', 'solvent']: + overlap_stats[key] = [ + pus[0].outputs['unit_mbar_overlap'] + for pus in self.data[key].values() + ] + + return overlap_stats + + def get_replica_transition_statistics(self) -> dict[str, list[dict[str, npt.NDArray]]]: + """ + Get the replica exchange transition statistics for all + legs of the simulation. + + Note + ---- + This is currently only available in cases where a replica exchange + simulation was run. + + Returns + ------- + repex_stats : dict[str, list[dict[str, npt.NDArray]]] + A dictionary with keys `complex` and `solvent` for each + leg of the thermodynamic cycle, which each containing + a list of dictionaries containing the replica transition + statistics for each repeat of that simulation type. + + The replica transition statistics dictionaries contain the following: + * ``eigenvalues``: The sorted (descending) eigenvalues of the + lambda state transition matrix + * ``matrix``: The transition matrix estimate of a replica switching + from state i to state j. + """ + repex_stats: dict[str, list[dict[str, npt.NDArray]]] = {} + try: + for key in ['complex', 'solvent']: + repex_stats[key] = [ + pus[0].outputs['replica_exchange_statistics'] + for pus in self.data[key].values() + ] + except KeyError: + errmsg = ("Replica exchange statistics were not found, " + "did you run a repex calculation?") + raise ValueError(errmsg) + + return repex_stats + + def get_replica_states(self) -> dict[str, list[npt.NDArray]]: + """ + Get the timeseries of replica states for all simulation legs. + + Returns + ------- + replica_states : dict[str, list[npt.NDArray]] + Dictionary keyed `complex` and `solvent` for each leg of + the thermodynamic cycle, with lists of replica states + timeseries for each repeat of that simulation type. + """ + replica_states: dict[str, list[npt.NDArray]] = { + 'complex': [], 'solvent': [] + } + + def is_file(filename: str): + p = pathlib.Path(filename) + + if not p.exists(): + errmsg = f"File could not be found {p}" + raise ValueError(errmsg) + + return p + + def get_replica_state(nc, chk): + nc = is_file(nc) + dir_path = nc.parents[0] + chk = is_file(dir_path / chk).name + + reporter = multistate.MultiStateReporter( + storage=nc, checkpoint_storage=chk, open_mode='r' + ) + + retval = np.asarray(reporter.read_replica_thermodynamic_states()) + reporter.close() + + return retval + + for key in ['complex', 'solvent']: + for pus in self.data[key].values(): + states = get_replica_state( + pus[0].outputs['nc'], + pus[0].outputs['last_checkpoint'], + ) + replica_states[key].append(states) + + return replica_states + + def equilibration_iterations(self) -> dict[str, list[float]]: + """ + Get the number of equilibration iterations for each simulation. + + Returns + ------- + equilibration_lengths : dict[str, list[float]] + Dictionary keyed `complex` and `solvent` for each leg + of the thermodynamic cycle, with lists containing the + number of equilibration iterations for each repeat + of that simulation type. + """ + equilibration_lengths: dict[str, list[float]] = {} + + for key in ['complex', 'solvent']: + equilibration_lengths[key] = [ + pus[0].outputs['equilibration_iterations'] + for pus in self.data[key].values() + ] + + return equilibration_lengths + + def production_iterations(self) -> dict[str, list[float]]: + """ + Get the number of production iterations for each simulation. + Returns the number of uncorrelated production samples for each + repeat of the calculation. + + Returns + ------- + production_lengths : dict[str, list[float]] + Dictionary keyed `complex` and `solvent` for each leg of the + thermodynamic cycle, with lists with the number + of production iterations for each repeat of that simulation + type. + """ + production_lengths: dict[str, list[float]] = {} + + for key in ['complex', 'solvent']: + production_lengths[key] = [ + pus[0].outputs['production_iterations'] + for pus in self.data[key].values() + ] + + return production_lengths + + +class SepTopProtocol(gufe.Protocol): + """ + SepTop RBFE calculations using OpenMM and OpenMMTools. + + See Also + -------- + :mod:`openfe.protocols` + :class:`openfe.protocols.openmm_septop.SepTopSettings` + :class:`openfe.protocols.openmm_septop.SepTopProtocolResult` + :class:`openfe.protocols.openmm_septop.SepTopComplexUnit` + :class:`openfe.protocols.openmm_septop.SepTopSolventUnit` + """ + result_cls = SepTopProtocolResult + _settings: SepTopSettings + + @classmethod + def _default_settings(cls): + """A dictionary of initial settings for this creating this Protocol + + These settings are intended as a suitable starting point for creating + an instance of this protocol. It is recommended, however that care is + taken to inspect and customize these before performing a Protocol. + + Returns + ------- + Settings + a set of default settings + """ + return SepTopSettings( + protocol_repeats=3, + solvent_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), + complex_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings( + nonbonded_method='nocutoff', + ), + thermo_settings=settings.ThermoSettings( + temperature=298.15 * unit.kelvin, + pressure=1 * unit.bar, + ), + alchemical_settings=AlchemicalSettings(), + lambda_settings=LambdaSettings( + ), + partial_charge_settings=OpenFFPartialChargeSettings(), + solvation_settings=OpenMMSolvationSettings(), + complex_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, + production_length=10.0 * unit.nanosecond, + ), + solvent_output_settings=MultiStateOutputSettings( + output_filename='solvent.nc', + checkpoint_storage_filename='solvent_checkpoint.nc', + ), + complex_equil_simulation_settings=MDSimulationSettings( + equilibration_length_nvt=None, + equilibration_length=0.2 * unit.nanosecond, + production_length=0.5 * unit.nanosecond, + ), + complex_equil_output_settings=MDOutputSettings( + equil_nvt_structure=None, + equil_npt_structure='equil_structure.pdb', + production_trajectory_filename='production_equil.xtc', + log_output='equil_simulation.log', + ), + complex_simulation_settings=MultiStateSimulationSettings( + n_replicas=14, + equilibration_length=0.5 * unit.nanosecond, + production_length=2.0 * unit.nanosecond, + ), + complex_output_settings=MultiStateOutputSettings( + output_filename='complex.nc', + checkpoint_storage_filename='complex_checkpoint.nc' + ), + ) + + @staticmethod + def _validate_complex_endstates( + stateA: ChemicalSystem, stateB: ChemicalSystem, + ) -> None: + """ + A complex transformation is defined (in terms of gufe components) + as starting from one or more ligands and a protein in solvent and + ending up in a state with one less ligand. + + Parameters + ---------- + stateA : ChemicalSystem + The chemical system of end state A + stateB : ChemicalSystem + The chemical system of end state B + + Raises + ------ + ValueError + If there is no SolventComponent and no ProteinComponent + in either stateA or stateB. + """ + # check that there is a protein component + if not any( + isinstance(comp, ProteinComponent) for comp in stateA.values() + ): + errmsg = "No ProteinComponent found in stateA" + raise ValueError(errmsg) + + if not any( + isinstance(comp, ProteinComponent) for comp in stateB.values() + ): + errmsg = "No ProteinComponent found in stateB" + raise ValueError(errmsg) + + # check that there is a solvent component + if not any( + isinstance(comp, SolventComponent) for comp in stateA.values() + ): + errmsg = "No SolventComponent found in stateA" + raise ValueError(errmsg) + + if not any( + isinstance(comp, SolventComponent) for comp in stateB.values() + ): + errmsg = "No SolventComponent found in stateB" + raise ValueError(errmsg) + + @staticmethod + def _validate_alchemical_components( + alchemical_components: dict[str, list[Component]] + ) -> None: + """ + Checks that the ChemicalSystem alchemical components are correct. + + Parameters + ---------- + alchemical_components : Dict[str, list[Component]] + Dictionary containing the alchemical components for + stateA and stateB. + + Raises + ------ + ValueError + * If there are no or more than one alchemical components in state A. + * If there are no or more than one alchemical components in state B. + * If there are any alchemical components that are not + SmallMoleculeComponents + + Notes + ----- + * Currently doesn't support alchemical components which are not + SmallMoleculeComponents. + * Currently doesn't support more than one alchemical component + being desolvated. + """ + + # Crash out if there are less or more than one alchemical components + # in state A and B + if len(alchemical_components['stateA']) != 1: + errmsg = ("Exactly one alchemical components must be present in stateA. " + f"Found {len(alchemical_components['stateA'])} " + "alchemical components in stateA") + raise ValueError(errmsg) + + if len(alchemical_components['stateB']) != 1: + errmsg = ("Exactly one alchemical components must be present in stateB. " + f"Found {len(alchemical_components['stateB'])} " + "alchemical components in stateB") + raise ValueError(errmsg) + + # Crash out if any of the alchemical components are not + # SmallMoleculeComponent + alchem_components_states = [alchemical_components['stateA'], alchemical_components['stateB']] + for state in alchem_components_states: + for comp in state: + if not isinstance(comp, SmallMoleculeComponent): + errmsg = ("Non SmallMoleculeComponent alchemical species " + "are not currently supported") + raise ValueError(errmsg) + + @staticmethod + def _validate_lambda_schedule( + lambda_settings: LambdaSettings, + simulation_settings: MultiStateSimulationSettings, + ) -> None: + """ + Checks that the lambda schedule is set up correctly. + + Parameters + ---------- + lambda_settings : LambdaSettings + the lambda schedule Settings + simulation_settings : MultiStateSimulationSettings + the settings for either the complex or solvent phase + + Raises + ------ + ValueError + If the number of lambda windows differs for electrostatics and sterics. + If the number of replicas does not match the number of lambda windows. + If there are states with naked charges. + Warnings + If there are non-zero values for restraints (lambda_restraints). + """ + + lambda_elec = lambda_settings.lambda_elec + lambda_vdw = lambda_settings.lambda_vdw + lambda_restraints = lambda_settings.lambda_restraints + n_replicas = simulation_settings.n_replicas + + # Ensure that all lambda components have equal amount of windows + lambda_components = [lambda_vdw, lambda_elec, lambda_restraints] + it = iter(lambda_components) + the_len = len(next(it)) + if not all(len(l) == the_len for l in it): + errmsg = ( + "Components elec, vdw, and restraints must have equal amount" + f" of lambda windows. Got {len(lambda_elec)} elec lambda" + f" windows, {len(lambda_vdw)} vdw lambda windows, and" + f"{len(lambda_restraints)} restraints lambda windows.") + raise ValueError(errmsg) + + # Ensure that number of overall lambda windows matches number of lambda + # windows for individual components + if n_replicas != len(lambda_vdw): + errmsg = (f"Number of replicas {n_replicas} does not equal the" + f" number of lambda windows {len(lambda_vdw)}") + raise ValueError(errmsg) + + # Check if there are lambda windows with naked charges + for inx, lam in enumerate(lambda_elec): + if lam < 1 and lambda_vdw[inx] == 1: + errmsg = ( + "There are states along this lambda schedule " + "where there are atoms with charges but no LJ " + f"interactions: lambda {inx}: " + f"elec {lam} vdW {lambda_vdw[inx]}") + raise ValueError(errmsg) + + # # Check if there are lambda windows with non-zero restraints + # if len([r for r in lambda_restraints if r != 0]) > 0: + # wmsg = ("Non-zero restraint lambdas applied. The absolute " + # "solvation protocol doesn't apply restraints, " + # "therefore restraints won't be applied. " + # f"Given lambda_restraints: {lambda_restraints}") + # logger.warning(wmsg) + # warnings.warn(wmsg) + + def _create( + self, + stateA: ChemicalSystem, + stateB: ChemicalSystem, + mapping: Optional[Union[gufe.ComponentMapping, list[gufe.ComponentMapping]]] = None, + extends: Optional[gufe.ProtocolDAGResult] = None, + ) -> list[gufe.ProtocolUnit]: + # TODO: extensions + if extends: # pragma: no-cover + raise NotImplementedError("Can't extend simulations yet") + + # Validate components and get alchemical components + self._validate_complex_endstates(stateA, stateB) + alchem_comps = system_validation.get_alchemical_components( + stateA, stateB, + ) + self._validate_alchemical_components(alchem_comps) + + # Validate the lambda schedule + self._validate_lambda_schedule(self.settings.lambda_settings, + self.settings.solvent_simulation_settings) + self._validate_lambda_schedule(self.settings.lambda_settings, + self.settings.complex_simulation_settings) + + # Check solvent compatibility + solv_nonbonded_method = self.settings.solvent_forcefield_settings.nonbonded_method + # Use the more complete system validation solvent checks + system_validation.validate_solvent(stateA, solv_nonbonded_method) + + # Validate protein component + system_validation.validate_protein(stateA) + + # Get the name of the alchemical species + alchname = alchem_comps['stateA'][0].name + + # Create list units for complex and solvent transforms + + solvent_units = [ + SepTopSolventUnit( + protocol=self, + stateA=stateA, + stateB=stateB, + alchemical_components=alchem_comps, + generation=0, repeat_id=int(uuid.uuid4()), + name=(f"SepTop RBFE, {alchname} solvent leg: " + f"repeat {i} generation 0"), + ) + for i in range(self.settings.protocol_repeats) + ] + + complex_units = [ + SepTopComplexUnitUnit( + # These don't really reflect the actual transform + # Should these be overriden to be ChemicalSystem{smc} -> ChemicalSystem{} ? + protocol=self, + stateA=stateA, + stateB=stateB, + alchemical_components=alchem_comps, + generation=0, repeat_id=int(uuid.uuid4()), + name=(f"SepTop RBFE, {alchname} complex leg: " + f"repeat {i} generation 0"), + ) + for i in range(self.settings.protocol_repeats) + ] + + return solvent_units + complex_units + + def _gather( + self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult] + ) -> dict[str, dict[str, Any]]: + # result units will have a repeat_id and generation + # first group according to repeat_id + unsorted_solvent_repeats = defaultdict(list) + unsorted_complex_repeats = defaultdict(list) + for d in protocol_dag_results: + pu: gufe.ProtocolUnitResult + for pu in d.protocol_unit_results: + if not pu.ok(): + continue + if pu.outputs['simtype'] == 'solvent': + unsorted_solvent_repeats[pu.outputs['repeat_id']].append(pu) + else: + unsorted_complex_repeats[pu.outputs['repeat_id']].append(pu) + + repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { + 'solvent': {}, 'complex': {}, + } + for k, v in unsorted_solvent_repeats.items(): + repeats['solvent'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) + + for k, v in unsorted_complex_repeats.items(): + repeats['complex'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) + return repeats + + +class SepTopComplexUnit(BaseSepTopUnit): + """ + Protocol Unit for the complex phase of a SepTop free energy calculation + """ + def _get_components(self): + """ + Get the relevant components for complex transformation. + + Returns + ------- + alchem_comps : dict[str, list[Component]] + A list of alchemical components + solv_comp : SolventComponent + For the gas phase transformation, None will always be returned + for the solvent component of the chemical system. + prot_comp : ProteinComponent + The protein component of the system. + small_mols : dict[Component, OpenFF Molecule] + The openff Molecules to add to the system. This + is equivalent to the alchemical components in stateA (since + we only allow for disappearing ligands). + """ + stateA = self._inputs['stateA'] + alchem_comps = self._inputs['alchemical_components'] + + off_comps = {m: m.to_openff() + for m in alchem_comps['stateA']} + + _, prot_comp, _ = system_validation.get_components(stateA) + + return alchem_comps, None, prot_comp, off_comps + + def _handle_settings(self) -> dict[str, SettingsBaseModel]: + """ + Extract the relevant settings for a complex transformation. + + Returns + ------- + settings : dict[str, SettingsBaseModel] + A dictionary with the following entries: + * forcefield_settings : OpenMMSystemGeneratorFFSettings + * thermo_settings : ThermoSettings + * charge_settings : OpenFFPartialChargeSettings + * solvation_settings : OpenMMSolvationSettings + * alchemical_settings : AlchemicalSettings + * lambda_settings : LambdaSettings + * engine_settings : OpenMMEngineSettings + * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings + * simulation_settings : SimulationSettings + * output_settings: MultiStateOutputSettings + """ + prot_settings = self._inputs['protocol'].settings + + settings = {} + settings['forcefield_settings'] = prot_settings.complex_forcefield_settings + settings['thermo_settings'] = prot_settings.thermo_settings + settings['charge_settings'] = prot_settings.partial_charge_settings + settings['solvation_settings'] = prot_settings.solvation_settings + settings['alchemical_settings'] = prot_settings.alchemical_settings + settings['lambda_settings'] = prot_settings.lambda_settings + settings['engine_settings'] = prot_settings.complex_engine_settings + settings['integrator_settings'] = prot_settings.integrator_settings + settings['equil_simulation_settings'] = prot_settings.complex_equil_simulation_settings + settings['equil_output_settings'] = prot_settings.complex_equil_output_settings + settings['simulation_settings'] = prot_settings.complex_simulation_settings + settings['output_settings'] = prot_settings.complex_output_settings + + settings_validation.validate_timestep( + settings['forcefield_settings'].hydrogen_mass, + settings['integrator_settings'].timestep + ) + + return settings + + def _execute( + self, ctx: gufe.Context, **kwargs, + ) -> dict[str, Any]: + log_system_probe(logging.INFO, paths=[ctx.scratch]) + + outputs = self.run(scratch_basepath=ctx.scratch, + shared_basepath=ctx.shared) + + return { + 'repeat_id': self._inputs['repeat_id'], + 'generation': self._inputs['generation'], + 'simtype': 'complex', + **outputs + } + + +class SepTopSolventUnit(BaseSepTopUnit): + """ + Protocol Unit for the solvent phase of an relative SepTop free energy + """ + def _get_components(self): + """ + Get the relevant components for a solvent transformation. + + Returns + ------- + alchem_comps : dict[str, Component] + A list of alchemical components + solv_comp : SolventComponent + The SolventComponent of the system + prot_comp : Optional[ProteinComponent] + The protein component of the system, if it exists. + small_mols : dict[SmallMoleculeComponent: OFFMolecule] + SmallMoleculeComponents to add to the system. + """ + stateA = self._inputs['stateA'] + alchem_comps = self._inputs['alchemical_components'] + + solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) + off_comps = {m: m.to_openff() for m in small_mols} + + # We don't need to check that solv_comp is not None, otherwise + # an error will have been raised when calling `validate_solvent` + # in the Protocol's `_create`. + # Similarly we don't need to check prot_comp since that's also + # disallowed on create + return alchem_comps, solv_comp, prot_comp, off_comps + + def _handle_settings(self) -> dict[str, SettingsBaseModel]: + """ + Extract the relevant settings for a complex transformation. + + Returns + ------- + settings : dict[str, SettingsBaseModel] + A dictionary with the following entries: + * forcefield_settings : OpenMMSystemGeneratorFFSettings + * thermo_settings : ThermoSettings + * charge_settings : OpenFFPartialChargeSettings + * solvation_settings : OpenMMSolvationSettings + * alchemical_settings : AlchemicalSettings + * lambda_settings : LambdaSettings + * engine_settings : OpenMMEngineSettings + * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings + * simulation_settings : MultiStateSimulationSettings + * output_settings: MultiStateOutputSettings + """ + prot_settings = self._inputs['protocol'].settings + + settings = {} + settings['forcefield_settings'] = prot_settings.solvent_forcefield_settings + settings['thermo_settings'] = prot_settings.thermo_settings + settings['charge_settings'] = prot_settings.partial_charge_settings + settings['solvation_settings'] = prot_settings.solvation_settings + settings['alchemical_settings'] = prot_settings.alchemical_settings + 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 + + settings_validation.validate_timestep( + settings['forcefield_settings'].hydrogen_mass, + settings['integrator_settings'].timestep + ) + + return settings + + def _execute( + self, ctx: gufe.Context, **kwargs, + ) -> dict[str, Any]: + log_system_probe(logging.INFO, paths=[ctx.scratch]) + + outputs = self.run(scratch_basepath=ctx.scratch, + shared_basepath=ctx.shared) + + return { + 'repeat_id': self._inputs['repeat_id'], + 'generation': self._inputs['generation'], + 'simtype': 'solvent', + **outputs + } diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 7834703ce..e6f56f1cf 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -126,7 +126,7 @@ def must_be_positive(cls, v): # Inherited things solvent_forcefield_settings: OpenMMSystemGeneratorFFSettings - vacuum_forcefield_settings: OpenMMSystemGeneratorFFSettings + complex_forcefield_settings: OpenMMSystemGeneratorFFSettings """Parameters to set up the force field with OpenMM Force Fields""" thermo_settings: ThermoSettings """Settings for thermodynamic parameters""" @@ -146,10 +146,10 @@ def must_be_positive(cls, v): """ # MD Engine things - vacuum_engine_settings: OpenMMEngineSettings + complex_engine_settings: OpenMMEngineSettings """ Settings specific to the OpenMM engine, such as the compute platform - for the vacuum transformation. + for the complex transformation. """ solvent_engine_settings: OpenMMEngineSettings """ @@ -165,19 +165,14 @@ def must_be_positive(cls, v): """ # Simulation run settings - vacuum_equil_simulation_settings: MDSimulationSettings + complex_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. + Pre-alchemical complex simulation control settings. """ - vacuum_simulation_settings: MultiStateSimulationSettings + complex_simulation_settings: MultiStateSimulationSettings """ Simulation control settings, including simulation lengths - for the vacuum transformation. + for the complex transformation. """ solvent_equil_simulation_settings: MDSimulationSettings """ @@ -188,13 +183,13 @@ def must_be_positive(cls, v): Simulation control settings, including simulation lengths for the solvent transformation. """ - vacuum_equil_output_settings: MDOutputSettings + complex_equil_output_settings: MDOutputSettings """ - Simulation output settings for the vacuum non-alchemical equilibration. + Simulation output settings for the complex non-alchemical equilibration. """ - vacuum_output_settings: MultiStateOutputSettings + complex_output_settings: MultiStateOutputSettings """ - Simulation output settings for the vacuum transformation. + Simulation output settings for the complex transformation. """ solvent_equil_output_settings: MDOutputSettings """ diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py new file mode 100644 index 000000000..03c5ef456 --- /dev/null +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -0,0 +1,308 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +import itertools +import json +import sys +import pytest +from unittest import mock +from openmm import NonbondedForce, CustomNonbondedForce +from openmmtools.multistate.multistatesampler import MultiStateSampler +from openff.units import unit as offunit +from openff.units.openmm import ensure_quantity, from_openmm +import mdtraj as mdt +import numpy as np +from numpy.testing import assert_allclose +import gufe +import openfe +from openfe import ChemicalSystem, SolventComponent +from openfe.protocols import openmm_septop +from openfe.protocols.openmm_septop import ( + SepTopSolventUnit, + SepTopComplexUnit, + SepTopProtocol, +) + +from openfe.protocols.openmm_utils import system_validation +from openfe.protocols.openmm_utils.charge_generation import ( + HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA +) + + +@pytest.fixture() +def default_settings(): + return SepTopProtocol.default_settings() + + +def test_create_default_settings(): + settings = SepTopProtocol.default_settings() + assert settings + + +@pytest.mark.parametrize('val', [ + {'elec': [0.0, -1], 'vdw': [0.0, 1.0], 'restraints': [0.0, 1.0]}, + {'elec': [0.0, 1.5], 'vdw': [0.0, 1.5], 'restraints': [-0.1, 1.0]} +]) +def test_incorrect_window_settings(val, default_settings): + errmsg = "Lambda windows must be between 0 and 1." + lambda_settings = default_settings.lambda_settings + with pytest.raises(ValueError, match=errmsg): + lambda_settings.lambda_elec = val['elec'] + lambda_settings.lambda_vdw = val['vdw'] + lambda_settings.lambda_restraints = val['restraints'] + + +@pytest.mark.parametrize('val', [ + {'elec': [0.0, 0.1, 0.0], 'vdw': [0.0, 1.0, 1.0], 'restraints': [0.0, 1.0, 1.0]}, +]) +def test_monotonic_lambda_windows(val, default_settings): + errmsg = "The lambda schedule is not monotonic." + lambda_settings = default_settings.lambda_settings + + with pytest.raises(ValueError, match=errmsg): + lambda_settings.lambda_elec = val['elec'] + lambda_settings.lambda_vdw = val['vdw'] + lambda_settings.lambda_restraints = val['restraints'] + + +@pytest.mark.parametrize('val', [ + {'elec': [0.0, 1.0], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_naked_charge(val, default_settings): + errmsg = ("There are states along this lambda schedule " + "where there are atoms with charges but no LJ " + f"interactions: lambda 0: " + f"elec {val['elec'][0]} vdW {val['vdw'][0]}") + default_settings.lambda_settings.lambda_elec = val['elec'] + default_settings.lambda_settings.lambda_vdw = val['vdw'] + default_settings.lambda_settings.lambda_restraints = val['restraints'] + default_settings.complex_simulation_settings.n_replicas = 2 + default_settings.solvent_simulation_settings.n_replicas = 2 + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.solvent_simulation_settings, + ) + + +@pytest.mark.parametrize('val', [ + {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_nreplicas(val, default_settings): + default_settings.lambda_settings.lambda_elec = val['elec'] + default_settings.lambda_settings.lambda_vdw = val['vdw'] + default_settings.lambda_settings.lambda_restraints = val['restraints'] + n_replicas = 3 + default_settings.complex_simulation_settings.n_replicas = n_replicas + errmsg = (f"Number of replicas {n_replicas} does not equal the" + f" number of lambda windows {len(val['vdw'])}") + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + + +@pytest.mark.parametrize('val', [ + {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_nwindows(val, default_settings): + default_settings.lambda_settings.lambda_elec = val['elec'] + default_settings.lambda_settings.lambda_vdw = val['vdw'] + default_settings.lambda_settings.lambda_restraints = val['restraints'] + n_replicas = 3 + default_settings.complex_simulation_settings.n_replicas = n_replicas + errmsg = ( + "Components elec, vdw, and restraints must have equal amount" + f" of lambda windows. Got {len(val['elec'])} elec lambda" + f" windows, {len(val['vdw'])} vdw lambda windows, and" + f"{len(val['restraints'])} restraints lambda windows.") + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + + +def test_create_default_protocol(default_settings): + # this is roughly how it should be created + protocol = SepTopProtocol( + settings=default_settings, + ) + assert protocol + + +def test_serialize_protocol(default_settings): + protocol = SepTopProtocol( + settings=default_settings, + ) + + ser = protocol.to_dict() + ret = SepTopProtocol.from_dict(ser) + assert protocol == ret + + +def test_validate_complex_endstates_protcomp_stateA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'solvent': SolventComponent() + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + with pytest.raises(ValueError, match="No ProteinComponent found in stateA"): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + +def test_validate_complex_endstates_protcomp_stateB( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'solvent': SolventComponent(), + }) + + with pytest.raises(ValueError, match="No ProteinComponent found in stateB"): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + + +def test_validate_complex_endstates_nosolvcomp_stateA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + with pytest.raises( + ValueError, match="No SolventComponent found in stateA" + ): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + +def test_validate_complex_endstates_nosolvcomp_stateB( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + }) + + with pytest.raises( + ValueError, match="No SolventComponent found in stateB" + ): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + +def test_validate_alchem_comps_missingA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + with pytest.raises(ValueError, match='one alchemical components must be present in stateA.'): + SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_validate_alchem_comps_missingB( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + with pytest.raises(ValueError, match='one alchemical components must be present in stateB.'): + SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_validate_alchem_comps_toomanyA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'toluene': benzene_modifications['toluene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'phenol': benzene_modifications['phenol'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + assert len(alchem_comps['stateA']) == 2 + + assert len(alchem_comps['stateB']) == 1 + + with pytest.raises(ValueError, match='Found 2 alchemical components in stateA'): + SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_validate_alchem_nonsmc( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'solvent': SolventComponent() + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): + SepTopProtocol._validate_alchemical_components(alchem_comps) From 08ef427ca0dcb5c774d5d5a466d1b84215c3b752 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 24 Oct 2024 14:33:40 +0200 Subject: [PATCH 003/163] Some fixes --- .../openmm_septop/equil_septop_method.py | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 8c278cecc..839e8aaeb 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -737,31 +737,30 @@ class SepTopComplexUnit(BaseSepTopUnit): """ def _get_components(self): """ - Get the relevant components for complex transformation. + Get the relevant components for a complex transformation. Returns ------- - alchem_comps : dict[str, list[Component]] + alchem_comps : dict[str, Component] A list of alchemical components solv_comp : SolventComponent - For the gas phase transformation, None will always be returned - for the solvent component of the chemical system. - prot_comp : ProteinComponent - The protein component of the system. - small_mols : dict[Component, OpenFF Molecule] - The openff Molecules to add to the system. This - is equivalent to the alchemical components in stateA (since - we only allow for disappearing ligands). + The SolventComponent of the system + prot_comp : Optional[ProteinComponent] + The protein component of the system, if it exists. + small_mols : dict[SmallMoleculeComponent: OFFMolecule] + SmallMoleculeComponents to add to the system. """ stateA = self._inputs['stateA'] alchem_comps = self._inputs['alchemical_components'] - off_comps = {m: m.to_openff() - for m in alchem_comps['stateA']} - - _, prot_comp, _ = system_validation.get_components(stateA) + solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) + small_mols = {m: m.to_openff() for m in small_mols} + # Also get alchemical smc from state B + small_mols_B = {m: m.to_openff() + for m in alchem_comps['stateB']} + small_mols = small_mols | small_mols_B - return alchem_comps, None, prot_comp, off_comps + return alchem_comps, solv_comp, prot_comp, small_mols def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ @@ -827,10 +826,18 @@ class SepTopSolventUnit(BaseSepTopUnit): """ Protocol Unit for the solvent phase of an relative SepTop free energy """ + def _get_components(self): """ Get the relevant components for a solvent transformation. + Note + ----- + The solvent portion of the transformation is the transformation of one + ligand into the other in the solvent. The only thing that + should be present is the alchemical species in state A and state B + and the SolventComponent. + Returns ------- alchem_comps : dict[str, Component] @@ -845,15 +852,20 @@ def _get_components(self): stateA = self._inputs['stateA'] alchem_comps = self._inputs['alchemical_components'] - solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) - off_comps = {m: m.to_openff() for m in small_mols} + small_mols_A = {m: m.to_openff() + for m in alchem_comps['stateA']} + small_mols_B = {m: m.to_openff() + for m in alchem_comps['stateB']} + small_mols = small_mols_A | small_mols_B + + solv_comp, _, _ = system_validation.get_components(stateA) - # We don't need to check that solv_comp is not None, otherwise + # 1. We don't need to check that solv_comp is not None, otherwise # an error will have been raised when calling `validate_solvent` # in the Protocol's `_create`. - # Similarly we don't need to check prot_comp since that's also - # disallowed on create - return alchem_comps, solv_comp, prot_comp, off_comps + # 2. ProteinComps can't be alchem_comps (for now), so will + # be returned as None + return alchem_comps, solv_comp, None, small_mols def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ From 26b4b92bab70e7bb5c20bdd4e02c1fbf03015114 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 24 Oct 2024 14:52:30 +0200 Subject: [PATCH 004/163] Implement a Setup unit and empty Run unit --- openfe/protocols/openmm_septop/__init__.py | 8 +- openfe/protocols/openmm_septop/base.py | 228 +----------------- .../openmm_septop/equil_septop_method.py | 6 +- .../protocols/test_openmm_septop_protocol.py | 4 +- 4 files changed, 20 insertions(+), 226 deletions(-) diff --git a/openfe/protocols/openmm_septop/__init__.py b/openfe/protocols/openmm_septop/__init__.py index 3da40f8dc..dc88761ce 100644 --- a/openfe/protocols/openmm_septop/__init__.py +++ b/openfe/protocols/openmm_septop/__init__.py @@ -9,14 +9,14 @@ SepTopProtocol, SepTopSettings, SepTopProtocolResult, - SepTopComplexUnit, - SepTopSolventUnit, + SepTopComplexSetupUnit, + SepTopSolventSetupUnit, ) __all__ = [ "SepTopProtocol", "SepTopSettings", "SepTopProtocolResult", - "SepTopComplexUnit", - "SepTopSolventUnit", + "SepTopComplexSetupUnit", + "SepTopSolventSetupUnit", ] diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 61c91e317..ba54cf7d7 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -71,9 +71,9 @@ logger = logging.getLogger(__name__) -class BaseSepTopUnit(gufe.ProtocolUnit): +class BaseSepTopSetupUnit(gufe.ProtocolUnit): """ - Base class for ligand SepTop RBFE free energy transformations. + Base class for the setup of ligand SepTop RBFE free energy transformations. """ def __init__(self, *, protocol: gufe.Protocol, @@ -573,158 +573,6 @@ def _get_states( return - def _get_reporter( - self, - topology: app.Topology, - positions: openmm.unit.Quantity, - simulation_settings: MultiStateSimulationSettings, - output_settings: MultiStateOutputSettings, - ) -> multistate.MultiStateReporter: - """ - Empty placeholder for getting a MultistateReporter for the simulation you are running. - """ - - return - - def _get_ctx_caches( - self, - engine_settings: OpenMMEngineSettings - ) -> tuple[openmmtools.cache.ContextCache, openmmtools.cache.ContextCache]: - """ - Empty placeholder for getting the context caches based on the chosen platform - - """ - - return - - @staticmethod - def _get_integrator( - 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. - """ - steps_per_iteration = settings_validation.convert_steps_per_iteration( - simulation_settings, integrator_settings - ) - - integrator = openmmtools.mcmc.LangevinDynamicsMove( - timestep=to_openmm(integrator_settings.timestep), - 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( - integrator: openmmtools.mcmc.LangevinDynamicsMove, - reporter: openmmtools.multistate.MultiStateReporter, - simulation_settings: MultiStateSimulationSettings, - thermo_settings: ThermoSettings, - cmp_states: list[ThermodynamicState], - sampler_states: list[SamplerState], - energy_context_cache: openmmtools.cache.ContextCache, - sampler_context_cache: openmmtools.cache.ContextCache - ) -> multistate.MultiStateSampler: - """ - Get a sampler based on the equilibrium sampling method requested. - - Parameters - ---------- - integrator : openmmtools.mcmc.LangevinDynamicsMove - The simulation integrator. - reporter : openmmtools.multistate.MultiStateReporter - The reporter to hook up to the sampler. - 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] - A list of sampler states. - energy_context_cache : openmmtools.cache.ContextCache - Context cache for the energy states. - sampler_context_cache : openmmtool.cache.ContextCache - Context cache for the sampler states. - - Returns - ------- - 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_from_kcal_per_mole_to_kT( - thermo_settings.temperature, - simulation_settings.early_termination_target_error, - ) - - # Select the right sampler - # Note: doesn't need else, settings already validates choices - if simulation_settings.sampler_method.lower() == "repex": - sampler = multistate.ReplicaExchangeSampler( - mcmc_moves=integrator, - online_analysis_interval=rta_its, - online_analysis_target_error=et_target_err, - online_analysis_minimum_iterations=rta_min_its - ) - elif simulation_settings.sampler_method.lower() == "sams": - sampler = multistate.SAMSSampler( - mcmc_moves=integrator, - 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 simulation_settings.sampler_method.lower() == 'independent': - sampler = multistate.MultiStateSampler( - mcmc_moves=integrator, - online_analysis_interval=rta_its, - online_analysis_target_error=et_target_err, - online_analysis_minimum_iterations=rta_min_its, - ) - - sampler.create( - thermodynamic_states=cmp_states, - sampler_states=sampler_states, - storage=reporter - ) - - sampler.energy_context_cache = energy_context_cache - sampler.sampler_context_cache = sampler_context_cache - - return sampler - - def _run_simulation( - self, - sampler: multistate.MultiStateSampler, - reporter: multistate.MultiStateReporter, - settings: dict[str, SettingsBaseModel], - dry: bool - ): - """ - Empty placeholder for running the simulation. - - """ - return - def run(self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: """ @@ -796,67 +644,13 @@ def run(self, dry=False, verbose=True, # lambdas, solv_comp # ) # - # # 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 - # try: - # # 12. Get context caches - # energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( - # settings['engine_settings'] - # ) - # - # # 13. Get integrator - # integrator = self._get_integrator( - # settings['integrator_settings'], - # settings['simulation_settings'], - # ) - # - # # 14. Get sampler - # sampler = self._get_sampler( - # integrator, reporter, settings['simulation_settings'], - # settings['thermo_settings'], - # cmp_states, sampler_states, - # energy_ctx_cache, sampler_ctx_cache - # ) - # - # # 15. Run simulation - # unit_result_dict = self._run_simulation( - # sampler, reporter, settings, dry - # ) # - # finally: - # # close reporter when you're done to prevent file handle clashes - # reporter.close() - # - # # clear GPU context - # # Note: use cache.empty() when openmmtools #690 is resolved - # for context in list(energy_ctx_cache._lru._data.keys()): - # del energy_ctx_cache._lru._data[context] - # for context in list(sampler_ctx_cache._lru._data.keys()): - # del sampler_ctx_cache._lru._data[context] - # # cautiously clear out the global context cache too - # for context in list( - # openmmtools.cache.global_context_cache._lru._data.keys()): - # del openmmtools.cache.global_context_cache._lru._data[context] - # - # del sampler_ctx_cache, energy_ctx_cache - # - # # Keep these around in a dry run so we can inspect things - # if not dry: - # del integrator, sampler - # - # if not dry: - # nc = self.shared_basepath / settings['output_settings'].output_filename - # chk = settings['output_settings'].checkpoint_storage_filename - # return { - # 'nc': nc, - # 'last_checkpoint': chk, - # **unit_result_dict, - # } - # else: - # return {'debug': {'sampler': sampler}} + # eventually save the serialized alchemical systems to disc to be + # picked up by the run unit + + +class BaseSepTopRunUnit(gufe.ProtocolUnit): + """ + Empty place holder + Base class for running ligand SepTop RBFE free energy transformations. + """ diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 839e8aaeb..2a04fe01d 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -55,7 +55,7 @@ SettingsBaseModel, ) from ..openmm_utils import system_validation, settings_validation -from .base import BaseSepTopUnit +from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit from openfe.utils import log_system_probe from openfe.due import due, Doi @@ -731,7 +731,7 @@ def _gather( return repeats -class SepTopComplexUnit(BaseSepTopUnit): +class SepTopComplexSetupUnit(BaseSepTopSetupUnit): """ Protocol Unit for the complex phase of a SepTop free energy calculation """ @@ -822,7 +822,7 @@ def _execute( } -class SepTopSolventUnit(BaseSepTopUnit): +class SepTopSolventSetupUnit(BaseSepTopSetupUnit): """ Protocol Unit for the solvent phase of an relative SepTop free energy """ diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 03c5ef456..e2509003f 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -17,8 +17,8 @@ from openfe import ChemicalSystem, SolventComponent from openfe.protocols import openmm_septop from openfe.protocols.openmm_septop import ( - SepTopSolventUnit, - SepTopComplexUnit, + SepTopSolventSetupUnit, + SepTopComplexSetupUnit, SepTopProtocol, ) From 3261ba25a84f3544ead0dad975e5fcc88b916f51 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 25 Oct 2024 15:59:42 +0200 Subject: [PATCH 005/163] Updating positions in the solvent and complex --- openfe/protocols/openmm_septop/base.py | 280 +++++++++++++----- .../openmm_septop/equil_septop_method.py | 92 +++++- .../openmm_septop/equil_septop_settings.py | 8 +- openfe/tests/conftest.py | 11 + .../protocols/test_openmm_septop_protocol.py | 74 +++-- 5 files changed, 352 insertions(+), 113 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index ba54cf7d7..d6f267247 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -18,22 +18,26 @@ import abc import os +import copy import logging - +import simtk +import itertools import gufe from gufe.components import Component import numpy as np import numpy.typing as npt import openmm +import mdtraj as md +import simtk.unit as omm_units from openff.units import unit from openff.units.openmm import from_openmm, to_openmm, ensure_quantity from openff.toolkit.topology import Molecule as OFFMolecule from openmmtools import multistate from openmmtools.states import (SamplerState, ThermodynamicState, - create_thermodynamic_state_protocol,) + create_thermodynamic_state_protocol, ) from openmmtools.alchemy import (AlchemicalRegion, AbsoluteAlchemicalFactory, - AlchemicalState,) + AlchemicalState, ) from typing import Optional from openmm import app from openmm import unit as omm_unit @@ -67,7 +71,6 @@ ) from openfe.utils import without_oechem_backend - logger = logging.getLogger(__name__) @@ -75,6 +78,7 @@ class BaseSepTopSetupUnit(gufe.ProtocolUnit): """ Base class for the setup of ligand SepTop RBFE free energy transformations. """ + def __init__(self, *, protocol: gufe.Protocol, stateA: ChemicalSystem, @@ -82,7 +86,7 @@ def __init__(self, *, alchemical_components: dict[str, list[Component]], generation: int = 0, repeat_id: int = 0, - name: Optional[str] = None,): + name: Optional[str] = None, ): """ Parameters ---------- @@ -154,12 +158,12 @@ 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 + self, + system: openmm.System, + topology: openmm.app.Topology, + positions: omm_unit.Quantity, + settings: dict[str, SettingsBaseModel], + dry: bool ) -> omm_unit.Quantity: """ Run a non-alchemical equilibration to get a stable system. @@ -207,7 +211,8 @@ def _pre_equilibrate( ) # Get the necessary number of steps - if settings['equil_simulation_settings'].equilibration_length_nvt is not None: + if settings[ + 'equil_simulation_settings'].equilibration_length_nvt is not None: equil_steps_nvt = settings_validation.get_simsteps( sim_length=settings[ 'equil_simulation_settings'].equilibration_length_nvt, @@ -218,7 +223,8 @@ def _pre_equilibrate( equil_steps_nvt = None equil_steps_npt = settings_validation.get_simsteps( - sim_length=settings['equil_simulation_settings'].equilibration_length, + sim_length=settings[ + 'equil_simulation_settings'].equilibration_length, timestep=settings['integrator_settings'].timestep, mc_steps=1, ) @@ -244,7 +250,8 @@ def _pre_equilibrate( simulation_settings=settings['equil_simulation_settings'], output_settings=settings['equil_output_settings'], temperature=settings['thermo_settings'].temperature, - barostat_frequency=settings['integrator_settings'].barostat_frequency, + barostat_frequency=settings[ + 'integrator_settings'].barostat_frequency, timestep=settings['integrator_settings'].timestep, equil_steps_nvt=equil_steps_nvt, equil_steps_npt=equil_steps_npt, @@ -262,9 +269,9 @@ def _pre_equilibrate( return equilibrated_positions def _prepare( - self, verbose: bool, - scratch_basepath: Optional[pathlib.Path], - shared_basepath: Optional[pathlib.Path], + self, verbose: bool, + scratch_basepath: Optional[pathlib.Path], + shared_basepath: Optional[pathlib.Path], ): """ Set basepaths and do some initial logging. @@ -295,7 +302,9 @@ def _set_optional_path(basepath): def _get_components(self) -> tuple[dict[str, list[Component]], Optional[gufe.SolventComponent], Optional[gufe.ProteinComponent], - dict[SmallMoleculeComponent, OFFMolecule]]: + dict[ + SmallMoleculeComponent, + OFFMolecule]]: """ Get the relevant components to create the alchemical system with. @@ -333,8 +342,8 @@ def _handle_settings(self): ... def _get_system_generator( - self, settings: dict[str, SettingsBaseModel], - solvent_comp: Optional[SolventComponent] + self, settings: dict[str, SettingsBaseModel], + solvent_comp: Optional[SolventComponent] ) -> SystemGenerator: """ Get a system generator through the system creation @@ -370,8 +379,8 @@ def _get_system_generator( @staticmethod def _assign_partial_charges( - partial_charge_settings: OpenFFPartialChargeSettings, - smc_components: dict[SmallMoleculeComponent, OFFMolecule], + partial_charge_settings: OpenFFPartialChargeSettings, + smc_components: dict[SmallMoleculeComponent, OFFMolecule], ) -> None: """ Assign partial charges to SMCs. @@ -390,18 +399,18 @@ def _assign_partial_charges( overwrite=False, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, - generate_n_conformers=partial_charge_settings.number_of_conformers, + generate_n_conformers=partial_charge_settings + .number_of_conformers, nagl_model=partial_charge_settings.nagl_model, ) def _get_modeller( - self, - protein_component: Optional[ProteinComponent], - solvent_component: Optional[SolventComponent], - smc_components: dict[SmallMoleculeComponent, OFFMolecule], - system_generator: SystemGenerator, - partial_charge_settings: BasePartialChargeSettings, - solvation_settings: BaseSolvationSettings + self, + protein_component: Optional[ProteinComponent], + solvent_component: SolventComponent, + smc_components: dict[SmallMoleculeComponent, OFFMolecule], + system_generator: SystemGenerator, + solvation_settings: BaseSolvationSettings ) -> tuple[app.Modeller, dict[Component, npt.NDArray]]: """ Get an OpenMM Modeller object and a list of residue indices @@ -411,8 +420,8 @@ def _get_modeller( ---------- protein_component : Optional[ProteinComponent] Protein Component, if it exists. - solvent_component : Optional[ProteinCompoinent] - Solvent Component, if it exists. + solvent_component : SolventComponent + Solvent Component. smc_components : dict[SmallMoleculeComponent, openff.toolkit.Molecule] Dictionary of OpenFF Molecules to add, keyed by SmallMoleculeComponent. @@ -435,9 +444,6 @@ def _get_modeller( if self.verbose: self.logger.info("Parameterizing molecules") - # Assign partial charges to smcs - self._assign_partial_charges(partial_charge_settings, smc_components) - # TODO: guard the following from non-RDKit backends # force the creation of parameters for the small molecules # this is necessary because we need to have the FF generated ahead @@ -462,10 +468,10 @@ def _get_modeller( return system_modeller, comp_resids def _get_omm_objects( - self, - system_modeller: app.Modeller, - system_generator: SystemGenerator, - smc_components: list[OFFMolecule], + self, + system_modeller: app.Modeller, + system_generator: SystemGenerator, + smc_components: list[OFFMolecule], ) -> tuple[app.Topology, openmm.unit.Quantity, openmm.System]: """ Get the OpenMM Topology, Positions and System of the @@ -504,7 +510,7 @@ def _get_omm_objects( return topology, system, positions def _get_lambda_schedule( - self, settings: dict[str, SettingsBaseModel] + self, settings: dict[str, SettingsBaseModel] ) -> dict[str, npt.NDArray]: """ Create the lambda schedule @@ -530,8 +536,8 @@ def _get_lambda_schedule( # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 # means fully interacting, not stateB - lambda_elec = [1-x for x in lambda_elec] - lambda_vdw = [1-x for x in lambda_vdw] + lambda_elec = [1 - x for x in lambda_elec] + lambda_vdw = [1 - x for x in lambda_vdw] lambdas['lambda_electrostatics'] = lambda_elec lambdas['lambda_sterics'] = lambda_vdw @@ -544,11 +550,11 @@ def _add_restraints(self, system, topology, settings): return def _get_alchemical_system( - self, - topology: app.Topology, - system: openmm.System, - comp_resids: dict[Component, npt.NDArray], - alchem_comps: dict[str, list[Component]] + self, + topology: app.Topology, + system: openmm.System, + comp_resids: dict[Component, npt.NDArray], + alchem_comps: dict[str, list[Component]] ): """ Empty placeholder for getting @@ -558,12 +564,12 @@ def _get_alchemical_system( return def _get_states( - self, - alchemical_system: openmm.System, - positions: openmm.unit.Quantity, - settings: dict[str, SettingsBaseModel], - lambdas: dict[str, npt.NDArray], - solvent_comp: Optional[SolventComponent], + self, + alchemical_system: openmm.System, + positions: openmm.unit.Quantity, + settings: dict[str, SettingsBaseModel], + lambdas: dict[str, npt.NDArray], + solvent_comp: Optional[SolventComponent], ) -> tuple[list[SamplerState], list[ThermodynamicState]]: """ Empty placeholder for getting @@ -573,6 +579,47 @@ def _get_states( return + + @staticmethod + def _get_mdtraj_from_openmm(omm_topology, omm_positions): + """ + Get an mdtraj object from an OpenMM topology and positions + """ + mdtraj_topology = md.Topology.from_openmm(omm_topology) + positions_in_mdtraj_format = np.array( + omm_positions / omm_units.nanometers) + mdtraj_system = md.Trajectory(positions_in_mdtraj_format, + mdtraj_topology) + return mdtraj_system + + + @staticmethod + def _get_atom_indices(omm_topology, comp_resids): + comp_atomids = {} + for key, values in comp_resids.items(): + atom_indices = [] + for residue in omm_topology.residues(): + if residue.index in values: + atom_indices.extend([atom.index for atom in residue.atoms()]) + comp_atomids[key] = atom_indices + return comp_atomids + + @staticmethod + def _update_positions( + omm_topology_A, omm_topology_B, positions_A, positions_B, + atom_indices_A, atom_indices_B, + ) -> npt.NDArray: + """ + Get new positions for the stateB after equilibration. + + Note + ---- + Must be implemented in the child class. + In the complex phase, this is achieved by aligning the proteins, + in the solvent phase, the ligand B are offset from ligand A + """ + ... + def run(self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: """ @@ -598,7 +645,7 @@ def run(self, dry=False, verbose=True, Outputs created in the basepath directory or the debug objects (i.e. sampler) if ``dry==True``. """ - # 0. Generaly preparation tasks + # 0. General preparation tasks self._prepare(verbose, scratch_basepath, shared_basepath) # 1. Get components @@ -607,34 +654,131 @@ def run(self, dry=False, verbose=True, # 2. Get settings settings = self._handle_settings() - # 3. Get system generator + # 5. Get system generator system_generator = self._get_system_generator(settings, solv_comp) - # 4. Get modeller - system_modeller, comp_resids = self._get_modeller( - prot_comp, solv_comp, smc_comps, system_generator, - settings['charge_settings'], - settings['solvation_settings'], + # 6. Get smcs for the different states and the common smcs + smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} + smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} + smc_off_both = {m: m.to_openff() for m in smc_comps + if (m not in alchem_comps["stateA"] and m not in + alchem_comps["stateB"])} + smc_comps_A = smc_off_A | smc_off_both + smc_comps_B = smc_off_B | smc_off_both + smc_comps_AB = smc_off_A | smc_off_B | smc_off_both + + # 7. Assign partial charges here to only do it once for smcs in stateA + # and stateB (hence only charge e.g. cofactors ones) + self._assign_partial_charges(settings['charge_settings'], smc_comps_AB) + + # 8. Get modeller for stateA, stateB, and stateAB + system_modeller_A, comp_resids_A = self._get_modeller( + prot_comp, solv_comp, smc_comps_A, + system_generator, settings['solvation_settings'], + ) + system_modeller_B, comp_resids_B = self._get_modeller( + prot_comp, solv_comp, smc_comps_B, + system_generator, settings['solvation_settings'], ) + # Get modeller B only ligand B + modeller_ligandB, comp_resids_B = self._get_modeller( + None, None, smc_off_B, + system_generator, settings['solvation_settings'], + ) + # Take the modeller from system A --> every water/ion should be in + # the same location + system_modeller_AB = copy.copy(system_modeller_A) + system_modeller_AB.add(modeller_ligandB.topology, + modeller_ligandB.positions) + + # We assume that modeller.add will always put the ligand B towards + # the end of the residues + resids_A = list(itertools.chain(*comp_resids_A.values())) + resids_AB = [r.index for r in system_modeller_AB.topology.residues()] + diff_resids = list(set(resids_AB) - set(resids_A)) + comp_resids_AB = comp_resids_A | {alchem_comps["stateB"][0]: np.array(diff_resids)} + # 5. Get OpenMM topology, positions and system - omm_topology, omm_system, positions = self._get_omm_objects( - system_modeller, system_generator, list(smc_comps.values()) + omm_topology_A, omm_system_A, positions_A = self._get_omm_objects( + system_modeller_A, system_generator, list(smc_comps_A.values()) ) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_A, + positions_A, + open('outputA.pdb', + 'w')) + omm_topology_B, omm_system_B, positions_B = self._get_omm_objects( + system_modeller_B, system_generator, list(smc_comps_B.values()) + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, + positions_B, + open('outputB.pdb', + 'w')) - # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) - positions = self._pre_equilibrate( - omm_system, omm_topology, positions, settings, dry + omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( + system_modeller_AB, system_generator, list(smc_comps_AB.values()) ) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, + positions_AB, + open('outputAB.pdb', 'w')) - # 7. Get lambdas - lambdas = self._get_lambda_schedule(settings) + # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) + equ_positions_A = self._pre_equilibrate( + omm_system_A, omm_topology_A, positions_A, settings, dry + ) + equ_positions_B = self._pre_equilibrate( + omm_system_B, omm_topology_B, positions_B, settings, dry + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile( + omm_topology_A, equ_positions_A, open('outputA_equ.pdb', 'w')) + simtk.openmm.app.pdbfile.PDBFile.writeFile( + omm_topology_B, equ_positions_B, open('outputB_equ.pdb', 'w')) + + # 7. Get all the right atom indices for alignments + comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) + all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) + comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) + + # Get the system A atom indices of ligand A + atom_indices_A = comp_atomids_A[alchem_comps['stateA'][0]] + # Get the system B atom indices of ligand B + atom_indices_B = comp_atomids_B[alchem_comps['stateB'][0]] + + # 8. Update the positions of system B: + # - complex: Align protein + # - solvent: Offset ligand B with respect to ligand A + updated_positions_B = self._update_positions( + omm_topology_A, omm_topology_B, equ_positions_A, equ_positions_B, + atom_indices_A, atom_indices_B) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, + updated_positions_B, + open('outputB_new.pdb', + 'w')) + + # Get atom indices for ligand A and ligand B and the solvent in the + # system AB + comp_atomids_AB = self._get_atom_indices(omm_topology_AB, comp_resids_AB) + atom_indices_AB_B = comp_atomids_AB[alchem_comps['stateB'][0]] + + # Update positions from AB system + positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A + positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, + :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] + + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, + positions_AB, + open('outputAB_new.pdb', + 'w')) + + # # 7. Get lambdas + # lambdas = self._get_lambda_schedule(settings) # # 8. Add restraints # self._add_restraints(omm_system, omm_topology, settings) # # # 9. Get alchemical system - # alchem_factory, alchem_system, alchem_indices = self._get_alchemical_system( + # alchem_factory, alchem_system, alchem_indices = + # self._get_alchemical_system( # omm_topology, omm_system, comp_resids, alchem_comps # ) # diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 2a04fe01d..dd3339d3e 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -36,8 +36,10 @@ import numpy.typing as npt from openff.units import unit from openmmtools import multistate +import mdtraj as md from typing import Optional, Union from typing import Any, Iterable +import simtk.unit as omm_units import uuid from gufe import ( @@ -75,6 +77,18 @@ logger = logging.getLogger(__name__) +def _get_mdtraj_from_openmm(omm_topology, omm_positions): + """ + Get an mdtraj object from an OpenMM topology and positions + """ + mdtraj_topology = md.Topology.from_openmm(omm_topology) + positions_in_mdtraj_format = np.array( + omm_positions / omm_units.nanometers) + mdtraj_system = md.Trajectory(positions_in_mdtraj_format, + mdtraj_topology) + return mdtraj_system + + class SepTopProtocolResult(gufe.ProtocolResult): """Dict-like container for the output of a SepTopProtocol """ @@ -437,7 +451,7 @@ def _default_settings(cls): log_output='equil_simulation.log', ), solvent_simulation_settings=MultiStateSimulationSettings( - n_replicas=14, + n_replicas=19, equilibration_length=1.0 * unit.nanosecond, production_length=10.0 * unit.nanosecond, ), @@ -457,7 +471,7 @@ def _default_settings(cls): log_output='equil_simulation.log', ), complex_simulation_settings=MultiStateSimulationSettings( - n_replicas=14, + n_replicas=19, equilibration_length=0.5 * unit.nanosecond, production_length=2.0 * unit.nanosecond, ), @@ -588,7 +602,6 @@ def _validate_lambda_schedule( ValueError If the number of lambda windows differs for electrostatics and sterics. If the number of replicas does not match the number of lambda windows. - If there are states with naked charges. Warnings If there are non-zero values for restraints (lambda_restraints). """ @@ -606,7 +619,7 @@ def _validate_lambda_schedule( errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(lambda_elec)} elec lambda" - f" windows, {len(lambda_vdw)} vdw lambda windows, and" + f" windows, {len(lambda_vdw)} vdw lambda windows, and " f"{len(lambda_restraints)} restraints lambda windows.") raise ValueError(errmsg) @@ -617,15 +630,17 @@ def _validate_lambda_schedule( f" number of lambda windows {len(lambda_vdw)}") raise ValueError(errmsg) - # Check if there are lambda windows with naked charges - for inx, lam in enumerate(lambda_elec): - if lam < 1 and lambda_vdw[inx] == 1: - errmsg = ( - "There are states along this lambda schedule " - "where there are atoms with charges but no LJ " - f"interactions: lambda {inx}: " - f"elec {lam} vdW {lambda_vdw[inx]}") - raise ValueError(errmsg) + # # Check if there are lambda windows with naked charges + # # Leaving this out for now till I've figured out how the lambda + # # scheduling works + # for inx, lam in enumerate(lambda_elec): + # if lam < 1 and lambda_vdw[inx] == 1: + # errmsg = ( + # "There are states along this lambda schedule " + # "where there are atoms with charges but no LJ " + # f"interactions: lambda {inx}: " + # f"elec {lam} vdW {lambda_vdw[inx]}") + # raise ValueError(errmsg) # # Check if there are lambda windows with non-zero restraints # if len([r for r in lambda_restraints if r != 0]) > 0: @@ -674,7 +689,7 @@ def _create( # Create list units for complex and solvent transforms solvent_units = [ - SepTopSolventUnit( + SepTopSolventSetupUnit( protocol=self, stateA=stateA, stateB=stateB, @@ -687,7 +702,7 @@ def _create( ] complex_units = [ - SepTopComplexUnitUnit( + SepTopComplexSetupUnit( # These don't really reflect the actual transform # Should these be overriden to be ChemicalSystem{smc} -> ChemicalSystem{} ? protocol=self, @@ -806,6 +821,21 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: return settings + @staticmethod + def _update_positions( + omm_topology_A, omm_topology_B, positions_A, positions_B, + atom_indices_A, atom_indices_B, + ) -> npt.NDArray: + mdtraj_complex_A = _get_mdtraj_from_openmm(omm_topology_A, positions_A) + mdtraj_complex_B = _get_mdtraj_from_openmm(omm_topology_B, positions_B) + mdtraj_complex_B.superpose(mdtraj_complex_A, + atom_indices=mdtraj_complex_A.topology.select( + 'backbone')) + # Extract updated system positions. + updated_positions_B = mdtraj_complex_B.openmm_positions(0) + + return updated_positions_B + def _execute( self, ctx: gufe.Context, **kwargs, ) -> dict[str, Any]: @@ -911,6 +941,38 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: return settings + + @staticmethod + def _update_positions( + omm_topology_A, omm_topology_B, positions_A, positions_B, + atom_indices_A, atom_indices_B, + ) -> npt.NDArray: + + # Offset ligand B from ligand A in the solvent + equ_pos_ligandA = positions_A[ + atom_indices_A[0]:atom_indices_A[-1] + 1] + equ_pos_ligandB = positions_B[ + atom_indices_B[0]:atom_indices_B[-1] + 1] + + ligand_1_radius = np.linalg.norm( + equ_pos_ligandA - equ_pos_ligandA.mean(axis=0), axis=1).max() + ligand_2_radius = np.linalg.norm( + equ_pos_ligandB - equ_pos_ligandB.mean(axis=0), axis=1).max() + ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 + ligand_offset = equ_pos_ligandA.mean(0) - equ_pos_ligandB.mean(0) + ligand_offset[0] += ligand_distance * omm_units.nanometers + # Offset the ligandB. + mdtraj_system_B = _get_mdtraj_from_openmm(omm_topology_B, + positions_B) + mdtraj_system_B.xyz[0][atom_indices_B, + :] += ligand_offset / omm_units.nanometers + + # Extract updated system positions. + updated_positions_B = mdtraj_system_B.openmm_positions(0) + + return updated_positions_B + + def _execute( self, ctx: gufe.Context, **kwargs, ) -> dict[str, Any]: diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index e6f56f1cf..af08b187c 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -52,8 +52,8 @@ class LambdaSettings(SettingsBaseModel): """ lambda_elec: list[float] = [ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 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, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.5, 0.75, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, ] """ List of floats of lambda values for the electrostatics. @@ -62,7 +62,7 @@ class LambdaSettings(SettingsBaseModel): """ lambda_vdw: list[float] = [ 0.0, 0.142857143, 0.285714286, 0.428571429, 0.571428571, 0.714285714, - 0.857142857, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 0.857142857, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 ] """ List of floats of lambda values for the van der Waals. @@ -71,7 +71,7 @@ class LambdaSettings(SettingsBaseModel): """ lambda_restraints: list[float] = [ 0.0, 0.05, 0.3, 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, 1.0, 1.0, 1.0, 1.0, ] """ List of floats of lambda values for the restraints. diff --git a/openfe/tests/conftest.py b/openfe/tests/conftest.py index 51cfb598b..9a8f691d6 100644 --- a/openfe/tests/conftest.py +++ b/openfe/tests/conftest.py @@ -192,6 +192,17 @@ def benzene_modifications(): return files +@pytest.fixture(scope='session') +def bace_ligands(): + files = {} + with importlib.resources.files('openfe.tests.data.openmm_septop') as d: + fn = str(d / 'bace1.sdf') + supp = Chem.SDMolSupplier(str(fn), removeHs=False) + for rdmol in supp: + files[rdmol.GetProp('_Name')] = SmallMoleculeComponent(rdmol) + return files + + @pytest.fixture def serialization_template(): def inner(filename): diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index e2509003f..73cb51c90 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -12,6 +12,7 @@ import mdtraj as mdt import numpy as np from numpy.testing import assert_allclose +from openff.units import unit import gufe import openfe from openfe import ChemicalSystem, SolventComponent @@ -64,31 +65,6 @@ def test_monotonic_lambda_windows(val, default_settings): lambda_settings.lambda_restraints = val['restraints'] -@pytest.mark.parametrize('val', [ - {'elec': [0.0, 1.0], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, -]) -def test_validate_lambda_schedule_naked_charge(val, default_settings): - errmsg = ("There are states along this lambda schedule " - "where there are atoms with charges but no LJ " - f"interactions: lambda 0: " - f"elec {val['elec'][0]} vdW {val['vdw'][0]}") - default_settings.lambda_settings.lambda_elec = val['elec'] - default_settings.lambda_settings.lambda_vdw = val['vdw'] - default_settings.lambda_settings.lambda_restraints = val['restraints'] - default_settings.complex_simulation_settings.n_replicas = 2 - default_settings.solvent_simulation_settings.n_replicas = 2 - with pytest.raises(ValueError, match=errmsg): - SepTopProtocol._validate_lambda_schedule( - default_settings.lambda_settings, - default_settings.complex_simulation_settings, - ) - with pytest.raises(ValueError, match=errmsg): - SepTopProtocol._validate_lambda_schedule( - default_settings.lambda_settings, - default_settings.solvent_simulation_settings, - ) - - @pytest.mark.parametrize('val', [ {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, ]) @@ -119,7 +95,7 @@ def test_validate_lambda_schedule_nwindows(val, default_settings): errmsg = ( "Components elec, vdw, and restraints must have equal amount" f" of lambda windows. Got {len(val['elec'])} elec lambda" - f" windows, {len(val['vdw'])} vdw lambda windows, and" + f" windows, {len(val['vdw'])} vdw lambda windows, and " f"{len(val['restraints'])} restraints lambda windows.") with pytest.raises(ValueError, match=errmsg): SepTopProtocol._validate_lambda_schedule( @@ -306,3 +282,49 @@ def test_validate_alchem_nonsmc( with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_setup(benzene_modifications, T4_protein_component, tmpdir): + # check system parametrisation works even if confgen fails + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_equil_simulation_settings.minimization_steps = 100 + s.solvent_equil_simulation_settings.equilibration_length_nvt = 1 * unit.picosecond + s.solvent_equil_simulation_settings.equilibration_length = 1 * unit.picosecond + s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond + s.solvation_settings.box_shape = 'dodecahedron' + s.complex_forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer + + protocol = SepTopProtocol( + settings=s, + ) + + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'toluene': benzene_modifications['toluene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first vacuum unit + dag = protocol.create( + stateA=stateA, + stateB=stateB, + mapping=None, + ) + prot_units = list(dag.protocol_units) + # solv_setup_unit = [u for u in prot_units + # if isinstance(u, SepTopSolventSetupUnit)] + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopComplexSetupUnit)] + + # with tmpdir.as_cwd(): + solv_setup_unit[0].run() + assert 4==5 + From b9c4e70f959ed2c0b9495c583f1f49a5d6a1757e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 11 Nov 2024 13:00:26 +0100 Subject: [PATCH 006/163] Add some femto utils, setup alchemical system --- openfe/protocols/openmm_septop/base.py | 9 +- openfe/protocols/openmm_septop/femto_utils.py | 346 ++++++++++++++++++ .../protocols/test_openmm_septop_protocol.py | 7 +- 3 files changed, 357 insertions(+), 5 deletions(-) create mode 100644 openfe/protocols/openmm_septop/femto_utils.py diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index d6f267247..c4400d85a 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -71,6 +71,8 @@ ) from openfe.utils import without_oechem_backend +from .femto_utils import apply_fep + logger = logging.getLogger(__name__) @@ -759,6 +761,7 @@ def run(self, dry=False, verbose=True, # system AB comp_atomids_AB = self._get_atom_indices(omm_topology_AB, comp_resids_AB) atom_indices_AB_B = comp_atomids_AB[alchem_comps['stateB'][0]] + atom_indices_AB_A = comp_atomids_AB[alchem_comps['stateA'][0]] # Update positions from AB system positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A @@ -770,8 +773,10 @@ def run(self, dry=False, verbose=True, open('outputAB_new.pdb', 'w')) - # # 7. Get lambdas - # lambdas = self._get_lambda_schedule(settings) + # 7. Get lambdas + lambdas = self._get_lambda_schedule(settings) + + apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) # # 8. Add restraints # self._add_restraints(omm_system, omm_topology, settings) diff --git a/openfe/protocols/openmm_septop/femto_utils.py b/openfe/protocols/openmm_septop/femto_utils.py new file mode 100644 index 000000000..a00bb5c9b --- /dev/null +++ b/openfe/protocols/openmm_septop/femto_utils.py @@ -0,0 +1,346 @@ +import collections +import copy +import itertools + +import numpy +import openmm +import openmm.unit + +# import femto.fe.config + +LAMBDA_VDW_LIGAND_1 = "lambda_vdw_lig_1" +"""The global parameter used to scale the vdW interactions of ligand 1.""" +LAMBDA_VDW_LIGAND_2 = "lambda_vdw_lig_2" +"""The global parameter used to scale the vdW interactions of ligand 2.""" + +LAMBDA_CHARGES_LIGAND_1 = "lambda_charges_lig_1" +"""The global parameter used to scale the electrostatic interactions of +ligand 1.""" +LAMBDA_CHARGES_LIGAND_2 = "lambda_charges_lig_2" +"""The global parameter used to scale the electrostatic interactions of +ligand 2.""" + + +_SUPPORTED_FORCES = [ + openmm.HarmonicBondForce, + openmm.HarmonicAngleForce, + openmm.PeriodicTorsionForce, + openmm.NonbondedForce, + openmm.MonteCarloBarostat, + openmm.CMMotionRemover, +] + + +def _beutler_softcore_potential(variable: str) -> str: + return ( + f"4.0 * (1.0 - {variable}) * eps * x * (x - 1.0);" + # + f"x = (sig / r_eff) ^ 6;" + # + f"r_eff = (0.5 * sig^6 * {variable} + r^6)^(1/6);" + # + f"sig = 0.5 * (sig1 + sig2);" + f"eps = sqrt(eps1 * eps2);" + ) + + +def _validate_exceptions( + force: openmm.NonbondedForce, ligand_1_idxs: set[int], ligand_2_idxs: set[int] +): + """Validate that a non-bonded force's exceptions are consistent with the + quite strict assumptions we make when setting up FEP""" + + for i in range(force.getNumExceptions()): + idx_a, idx_b, *_ = force.getExceptionParameters(i) + + if idx_a in ligand_1_idxs and idx_b in ligand_1_idxs: + continue + if idx_a in ligand_2_idxs and idx_b in ligand_2_idxs: + continue + if ( + idx_a not in ligand_1_idxs + and idx_b not in ligand_1_idxs + and idx_a not in ligand_2_idxs + and idx_b not in ligand_2_idxs + ): + continue + + raise NotImplementedError("alchemical-chemical exceptions were not expected") + + +def _convert_intramolecular_interactions( + force: openmm.NonbondedForce, + ligand_1_idxs: set[int], + ligand_2_idxs: set[int], +): + """Converts all intra-molecular interactions in alchemical molecules to exceptions + so that they won't be scaled, and excludes ligand-ligand interactions. + + This means we only need a single custom nonbonded force to handle the soft-core + vdW interactions between alchemical and non-alchemical particles. + + Args: + force: The force to modify. + ligand_1_idxs: The indices of atoms belonging to the first ligand. + ligand_2_idxs: The indices of atoms belonging to the second ligand. + """ + + existing_exceptions = { + tuple(sorted(force.getExceptionParameters(i)[:2])): i + for i in range(force.getNumExceptions()) + } + assert len(existing_exceptions) == force.getNumExceptions() + + ligand_idxs = [ligand_1_idxs, ligand_2_idxs] + + # add exceptions for intramolecular interactions + for idxs in ligand_idxs: + for idx_a, idx_b in itertools.combinations(idxs, r=2): + pair = tuple(sorted((idx_a, idx_b))) + + if pair in existing_exceptions: + continue + + charge_a, sigma_a, epsilon_a = force.getParticleParameters(idx_a) + charge_b, sigma_b, epsilon_b = force.getParticleParameters(idx_b) + + epsilon_ab = ( + numpy.sqrt((epsilon_a * epsilon_b).value_in_unit(epsilon_a.unit**2)) + * epsilon_a.unit + ) + sigma_ab = 0.5 * (sigma_a + sigma_b) + charge_ab = charge_a * charge_b + + existing_exceptions[pair] = force.addException( + *pair, charge_ab, sigma_ab, epsilon_ab + ) + + # add exceptions for ligand-ligand interactions + for idx_a, idx_b in itertools.product(ligand_1_idxs, ligand_2_idxs): + force.addException(idx_a, idx_b, 0.0, 1.0, 0.0, replace=True) + + +def _apply_lambda_charge( + force: openmm.NonbondedForce, ligand_idxs: set[int], variable: str +): + """Modifies a standard non-bonded force so that electrostatic interactions of + the specified atoms are scaled by ``variable``. + + Any alchemical-chemical interactions will be linearly scaled while chemical-chemical + and alchemical-alchemical interactions will remain unchanged. + + Args: + force: The force to modify. + ligand_idxs: The indices of atoms belonging to the ligand. + variable: The global parameter to use for scaling. + """ + + if len(ligand_idxs) == 0: + return + + force.addGlobalParameter(variable, 0.0) + + for i in range(force.getNumParticles()): + if i not in ligand_idxs: + continue + + charge, sigma, epsilon = force.getParticleParameters(i) + + if numpy.isclose(charge.value_in_unit(openmm.unit.elementary_charge), 0.0): + # We don't need to scale already zero charges + continue + + # q should be 0.0 at λ=1 and q at λ=0, so we set q - λq + force.addParticleParameterOffset(variable, i, -charge, 0.0, 0.0) + force.setParticleParameters(i, charge, sigma, epsilon) + + +def _apply_lambda_vdw( + force: openmm.NonbondedForce, + ligand_idxs: set[int], + non_ligand_idxs: set[int], + variable: str, +) -> openmm.CustomNonbondedForce | None: + """Modifies a standard non-bonded force so that vdW interactions of the specified + atoms are scaled by ``variable``. + + Any alchemical-chemical interactions will be scaled using a Beutler-style soft core + potential while chemical-chemical and alchemical-alchemical interactions will remain + unchanged. + + Args: + force: The force to modify. + ligand_idxs: The indices of the ligand atoms whose interactions should be scaled + non_ligand_idxs: The indices of the remaining atoms that can be interacted with. + variable: The global parameter to use for scaling. + + Returns: + A custom non-bonded force that contains only chemical-alchemical interactions. + """ + + if len(ligand_idxs) == 0: + return + + custom_vdw_fn = _beutler_softcore_potential(variable) + + custom_force = openmm.CustomNonbondedForce(custom_vdw_fn) + custom_force.setNonbondedMethod( + force.getNonbondedMethod() + if int(force.getNonbondedMethod()) not in {3, 4, 5} + else openmm.CustomNonbondedForce.CutoffPeriodic + ) + custom_force.setCutoffDistance(force.getCutoffDistance()) + custom_force.setSwitchingDistance(force.getSwitchingDistance()) + custom_force.setUseSwitchingFunction(force.getUseSwitchingFunction()) + custom_force.setUseLongRangeCorrection(force.getUseDispersionCorrection()) + + custom_force.addGlobalParameter(variable, 0.0) + + custom_force.addPerParticleParameter("eps") + custom_force.addPerParticleParameter("sig") + + for index in range(force.getNumParticles()): + charge, sigma, epsilon = force.getParticleParameters(index) + custom_force.addParticle([epsilon, sigma]) + + if index not in ligand_idxs: + continue + + # the intermolecular alchemical interactions will be handled by the custom + # soft-core force, so we zero them out here. + force.setParticleParameters(index, charge, sigma, epsilon * 0) + + for index in range(force.getNumExceptions()): + index_a, index_b, *_ = force.getExceptionParameters(index) + # let the exceptions be handled by the original force as we don't intend to + # annihilate those while switching off the intermolecular vdW interactions + custom_force.addExclusion(index_a, index_b) + + # alchemical-chemical + if len(non_ligand_idxs) > 0 and len(ligand_idxs) > 0: + custom_force.addInteractionGroup(ligand_idxs, non_ligand_idxs) + # alchemical-alchemical (e.g. ion pairs) + # if len(ligand_1_idxs) > 0 and len(ligand_2_idxs) > 0: + # custom_force.addInteractionGroup(ligand_1_idxs, ligand_2_idxs) + + return custom_force + + +def _apply_nonbonded_lambdas( + force: openmm.NonbondedForce, + ligand_1_idxs: set[int], + ligand_2_idxs: set[int] | None, + # config: femto.fe.config.FEP, +) -> tuple[openmm.NonbondedForce | openmm.CustomNonbondedForce, ...]: + """Modifies a standard non-bonded force so that vdW and electrostatic interactions + are scaled by ``lambda_vdw`` and ``lambda_charges`` respectively. + + Args: + force: The original non-bonded force. + ligand_1_idxs: The indices of the ligand atoms whose interactions should be + scaled by lambda. + ligand_2_idxs: The indices of the ligand atoms whose interactions should be + scaled by 1 - lambda. + config: Configuration options. + + Returns: + The modified non-bonded force containing chemical-chemical and + alchemical-alchemical interactions and two custom non-bonded force containing + only alchemical-chemical interactions for ligand 1 and 2 respectively. + """ + force = copy.deepcopy(force) + + + assert ( + force.getNumGlobalParameters() == 0 + ), "the non-bonded force should not already contain global parameters" + assert ( + force.getNumParticleParameterOffsets() == 0 + and force.getNumExceptionParameterOffsets() == 0 + ), "the non-bonded force should not already contain parameter offsets" + + ligand_2_idxs = set() if ligand_2_idxs is None else ligand_2_idxs + + _validate_exceptions(force, ligand_1_idxs, ligand_2_idxs) + _convert_intramolecular_interactions(force, ligand_1_idxs, ligand_2_idxs) + + _apply_lambda_charge(force, ligand_1_idxs, LAMBDA_CHARGES_LIGAND_1) + _apply_lambda_charge(force, ligand_2_idxs, LAMBDA_CHARGES_LIGAND_2) + + + non_ligand_indices = { + i + for i in range(force.getNumParticles()) + if i not in ligand_1_idxs and i not in ligand_2_idxs + } + + custom_force_1 = _apply_lambda_vdw( + force, ligand_1_idxs, non_ligand_indices, LAMBDA_VDW_LIGAND_1 + ) + custom_force_2 = _apply_lambda_vdw( + force, ligand_2_idxs, non_ligand_indices, LAMBDA_VDW_LIGAND_2 + ) + return force, custom_force_1, custom_force_2 + + +def apply_fep( + system: openmm.System, + ligand_1_idxs: set[int], + ligand_2_idxs: set[int] | None, + # config: femto.fe.config.FEP, +): + """Modifies an OpenMM system so that different interactions can be scaled by + corresponding lambda parameters. + + Notes: + * All intra-molecular interactions of alchemical ligands are currently replaced + with exceptions and are not scaled by lambda parameters. This will lead to + slightly different energies from the original system as cutoffs are not + applied to them by OpenMM. + * LJ vdW interactions between ligands and the rest of the system will be + replaced with a Beutler-style soft-core LJ potential with a-b-c of 1-1-6 and + alpha=0.5. + * Ligand indices **must** correspond to **all** atoms in the ligand, + alchemically modifying part of a molecule is not yet supported. + + Args: + system: The system to modify in-place. + ligand_1_idxs: The indices of the ligand atoms whose interactions should be + scaled by lambda. + ligand_2_idxs: The indices of the ligand atoms whose interactions should be + scaled by 1 - lambda. + config: Configuration options. + """ + + forces_by_type = collections.defaultdict(list) + + for force in system.getForces(): + if type(force) not in _SUPPORTED_FORCES: + raise ValueError( + f"Force type {type(force)} is not supported when alchemical modifying " + f"a system." + ) + forces_by_type[type(force)].append(force) + + updated_forces = [] + + for force_type, forces in forces_by_type.items(): + if len(forces) != 1: + raise NotImplementedError("only one force of each type is supported.") + + force = forces[0] + + if force_type == openmm.NonbondedForce: + nonbonded_forces = _apply_nonbonded_lambdas( + force, ligand_1_idxs, ligand_2_idxs, + ) + updated_forces.extend(nonbonded_forces) + else: + updated_forces.append(copy.deepcopy(force)) + + for i in reversed(range(system.getNumForces())): + system.removeForce(i) + + for force in updated_forces: + if force is not None: + system.addForce(force) \ No newline at end of file diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 73cb51c90..eca7d1848 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -293,6 +293,7 @@ def test_setup(benzene_modifications, T4_protein_component, tmpdir): s.solvent_equil_simulation_settings.equilibration_length = 1 * unit.picosecond s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond s.solvation_settings.box_shape = 'dodecahedron' + s.solvation_settings.solvent_padding = 1.5 * unit.nanometer s.complex_forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer protocol = SepTopProtocol( @@ -319,10 +320,10 @@ def test_setup(benzene_modifications, T4_protein_component, tmpdir): mapping=None, ) prot_units = list(dag.protocol_units) - # solv_setup_unit = [u for u in prot_units - # if isinstance(u, SepTopSolventSetupUnit)] solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopComplexSetupUnit)] + if isinstance(u, SepTopSolventSetupUnit)] + # solv_setup_unit = [u for u in prot_units + # if isinstance(u, SepTopComplexSetupUnit)] # with tmpdir.as_cwd(): solv_setup_unit[0].run() From 43fc5afe4d2cea3aeadf7cd9bcaab8eb30d48454 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 15 Nov 2024 15:16:26 +0100 Subject: [PATCH 007/163] Work on implementing restraints --- openfe/protocols/openmm_septop/base.py | 514 +- .../openmm_septop/equil_septop_method.py | 81 +- .../openmm_septop/equil_septop_settings.py | 29 +- .../{femto_utils.py => femto_alchemy.py} | 4 +- .../openmm_septop/femto_restraints.py | 598 ++ openfe/tests/conftest.py | 8 + openfe/tests/data/openmm_septop/__init__.py | 0 openfe/tests/data/openmm_septop/bace.pdb | 6053 +++++++++++++++++ openfe/tests/data/openmm_septop/bace1.sdf | 1919 ++++++ .../protocols/test_openmm_septop_protocol.py | 10 +- 10 files changed, 9153 insertions(+), 63 deletions(-) rename openfe/protocols/openmm_septop/{femto_utils.py => femto_alchemy.py} (99%) create mode 100644 openfe/protocols/openmm_septop/femto_restraints.py create mode 100644 openfe/tests/data/openmm_septop/__init__.py create mode 100644 openfe/tests/data/openmm_septop/bace.pdb create mode 100755 openfe/tests/data/openmm_septop/bace1.sdf diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index c4400d85a..9e312da7e 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -71,7 +71,8 @@ ) from openfe.utils import without_oechem_backend -from .femto_utils import apply_fep +from .femto_alchemy import apply_fep +from .femto_restraints import select_ligand_idxs logger = logging.getLogger(__name__) @@ -545,26 +546,6 @@ def _get_lambda_schedule( return lambdas - def _add_restraints(self, system, topology, settings): - """ - Placeholder method to add restraints if necessary - """ - return - - def _get_alchemical_system( - self, - topology: app.Topology, - system: openmm.System, - comp_resids: dict[Component, npt.NDArray], - alchem_comps: dict[str, list[Component]] - ): - """ - Empty placeholder for getting - an alchemically modified system and its associated factory - """ - - return - def _get_states( self, alchemical_system: openmm.System, @@ -574,25 +555,356 @@ def _get_states( solvent_comp: Optional[SolventComponent], ) -> tuple[list[SamplerState], list[ThermodynamicState]]: """ - Empty placeholder for getting - a list of sampler and thermodynmic states from an + Get a list of sampler and thermodynmic states from an input alchemical system. + + Parameters + ---------- + alchemical_system : openmm.System + Alchemical system to get states for. + positions : openmm.unit.Quantity + Positions of the alchemical system. + settings : dict[str, SettingsBaseModel] + A dictionary of settings for the protocol unit. + lambdas : dict[str, npt.NDArray] + A dictionary of lambda scales. + solvent_comp : Optional[SolventComponent] + The solvent component of the system, if there is one. + + Returns + ------- + sampler_states : list[SamplerState] + A list of SamplerStates for each replica in the system. + cmp_states : list[ThermodynamicState] + A list of ThermodynamicState for each replica in the system. """ + alchemical_state = AlchemicalState.from_system(alchemical_system) + # Set up the system constants + temperature = settings['thermo_settings'].temperature + pressure = settings['thermo_settings'].pressure + constants = dict() + constants['temperature'] = ensure_quantity(temperature, 'openmm') + if solvent_comp is not None: + constants['pressure'] = ensure_quantity(pressure, 'openmm') + + cmp_states = create_thermodynamic_state_protocol( + alchemical_system, protocol=lambdas, + constants=constants, composable_states=[alchemical_state], + ) - return + sampler_state = SamplerState(positions=positions) + if alchemical_system.usesPeriodicBoundaryConditions(): + box = alchemical_system.getDefaultPeriodicBoxVectors() + sampler_state.box_vectors = box + sampler_states = [sampler_state for _ in cmp_states] + + return sampler_states, cmp_states + + + def _get_reporter( + self, + topology: app.Topology, + positions: openmm.unit.Quantity, + simulation_settings: MultiStateSimulationSettings, + output_settings: MultiStateOutputSettings, + ) -> multistate.MultiStateReporter: + """ + Get a MultistateReporter for the simulation you are running. + + Parameters + ---------- + 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: MultiStateOutputSettings + Output settings for the simulations + + Returns + ------- + reporter : multistate.MultiStateReporter + The reporter for the simulation. + """ + mdt_top = mdt.Topology.from_openmm(topology) + + selection_indices = mdt_top.select( + output_settings.output_indices + ) + + 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=chk_intervals, + checkpoint_storage=chk, + ) + + # Write out the structure's PDB whilst we're here + if len(selection_indices) > 0: + traj = mdt.Trajectory( + positions[selection_indices, :], + mdt_top.subset(selection_indices), + ) + traj.save_pdb( + self.shared_basepath / output_settings.output_structure + ) + + return reporter + + + def _get_ctx_caches( + self, + engine_settings: OpenMMEngineSettings + ) -> tuple[openmmtools.cache.ContextCache, openmmtools.cache.ContextCache]: + """ + Set the context caches based on the chosen platform + + Parameters + ---------- + engine_settings : OpenMMEngineSettings, + + Returns + ------- + energy_context_cache : openmmtools.cache.ContextCache + The energy state context cache. + sampler_context_cache : openmmtools.cache.ContextCache + The sampler state context cache. + """ + platform = compute.get_openmm_platform( + engine_settings.compute_platform, + ) + + energy_context_cache = openmmtools.cache.ContextCache( + capacity=None, time_to_live=None, platform=platform, + ) + + sampler_context_cache = openmmtools.cache.ContextCache( + capacity=None, time_to_live=None, platform=platform, + ) + + return energy_context_cache, sampler_context_cache @staticmethod - def _get_mdtraj_from_openmm(omm_topology, omm_positions): + def _get_integrator( + integrator_settings: IntegratorSettings, + simulation_settings: MultiStateSimulationSettings + ) -> openmmtools.mcmc.LangevinDynamicsMove: """ - Get an mdtraj object from an OpenMM topology and positions + Return a LangevinDynamicsMove integrator + + Parameters + ---------- + integrator_settings : IntegratorSettings + simulation_settings : MultiStateSimulationSettings + + Returns + ------- + integrator : openmmtools.mcmc.LangevinDynamicsMove + A configured integrator object. """ - mdtraj_topology = md.Topology.from_openmm(omm_topology) - positions_in_mdtraj_format = np.array( - omm_positions / omm_units.nanometers) - mdtraj_system = md.Trajectory(positions_in_mdtraj_format, - mdtraj_topology) - return mdtraj_system + steps_per_iteration = settings_validation.convert_steps_per_iteration( + simulation_settings, integrator_settings + ) + + integrator = openmmtools.mcmc.LangevinDynamicsMove( + timestep=to_openmm(integrator_settings.timestep), + 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( + integrator: openmmtools.mcmc.LangevinDynamicsMove, + reporter: openmmtools.multistate.MultiStateReporter, + simulation_settings: MultiStateSimulationSettings, + thermo_settings: ThermoSettings, + cmp_states: list[ThermodynamicState], + sampler_states: list[SamplerState], + energy_context_cache: openmmtools.cache.ContextCache, + sampler_context_cache: openmmtools.cache.ContextCache + ) -> multistate.MultiStateSampler: + """ + Get a sampler based on the equilibrium sampling method requested. + + Parameters + ---------- + integrator : openmmtools.mcmc.LangevinDynamicsMove + The simulation integrator. + reporter : openmmtools.multistate.MultiStateReporter + The reporter to hook up to the sampler. + 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] + A list of sampler states. + energy_context_cache : openmmtools.cache.ContextCache + Context cache for the energy states. + sampler_context_cache : openmmtool.cache.ContextCache + Context cache for the sampler states. + + Returns + ------- + 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_from_kcal_per_mole_to_kT( + thermo_settings.temperature, + simulation_settings.early_termination_target_error, + ) + + # Select the right sampler + # Note: doesn't need else, settings already validates choices + if simulation_settings.sampler_method.lower() == "repex": + sampler = multistate.ReplicaExchangeSampler( + mcmc_moves=integrator, + online_analysis_interval=rta_its, + online_analysis_target_error=et_target_err, + online_analysis_minimum_iterations=rta_min_its + ) + elif simulation_settings.sampler_method.lower() == "sams": + sampler = multistate.SAMSSampler( + mcmc_moves=integrator, + 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 simulation_settings.sampler_method.lower() == 'independent': + sampler = multistate.MultiStateSampler( + mcmc_moves=integrator, + online_analysis_interval=rta_its, + online_analysis_target_error=et_target_err, + online_analysis_minimum_iterations=rta_min_its, + ) + + sampler.create( + thermodynamic_states=cmp_states, + sampler_states=sampler_states, + storage=reporter + ) + + sampler.energy_context_cache = energy_context_cache + sampler.sampler_context_cache = sampler_context_cache + + return sampler + + def _run_simulation( + self, + sampler: multistate.MultiStateSampler, + reporter: multistate.MultiStateReporter, + settings: dict[str, SettingsBaseModel], + dry: bool + ): + """ + Run the simulation. + + Parameters + ---------- + sampler : multistate.MultiStateSampler + The sampler associated with the simulation to run. + reporter : multistate.MultiStateReporter + The reporter associated with the sampler. + settings : dict[str, SettingsBaseModel] + The dictionary of settings for the protocol. + dry : bool + Whether or not to dry run the simulation + + Returns + ------- + unit_results_dict : Optional[dict] + A dictionary containing all the free energy results, + if not a dry run. + """ + # Get the relevant simulation steps + 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, + timestep=settings['integrator_settings'].timestep, + mc_steps=mc_steps, + ) + prod_steps = settings_validation.get_simsteps( + sim_length=settings['simulation_settings'].production_length, + timestep=settings['integrator_settings'].timestep, + mc_steps=mc_steps, + ) + + if not dry: # pragma: no-cover + # minimize + if self.verbose: + self.logger.info("minimizing systems") + sampler.minimize( + max_iterations=settings[ + 'simulation_settings'].minimization_steps + ) + # equilibrate + if self.verbose: + self.logger.info("equilibrating systems") + + sampler.equilibrate(int(equil_steps / mc_steps)) # type: ignore + + # production + if self.verbose: + self.logger.info("running production phase") + sampler.extend(int(prod_steps / mc_steps)) # type: ignore + + if self.verbose: + self.logger.info("production phase complete") + + if self.verbose: + self.logger.info("post-simulation result analysis") + + analyzer = multistate_analysis.MultistateEquilFEAnalysis( + reporter, + sampling_method=settings[ + 'simulation_settings'].sampler_method.lower(), + result_units=unit.kilocalorie_per_mole + ) + analyzer.plot(filepath=self.shared_basepath, filename_prefix="") + analyzer.close() + + return analyzer.unit_results_dict + + else: + # close reporter when you're done, prevent file handle clashes + reporter.close() + + # clean up the reporter file + 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) + + return None @staticmethod @@ -622,6 +934,33 @@ def _update_positions( """ ... + @staticmethod + def _set_positions(off_topology, positions): + off_topology.clear_positions() + off_topology.set_positions(positions) + return off_topology + + @staticmethod + def _add_restraints( + system: openmm.System, + positions: np.array, + topology: Optional[openmm.Topology], + settings, + ligand_1_ref_idx: int, + ligand_2_ref_idx: int, + ) -> openmm.System: + """ + Get new positions for the stateB after equilibration. + + Note + ---- + Must be implemented in the child class. + In the complex phase, this is achieved by aligning the proteins, + in the solvent phase, the ligand B are offset from ligand A + """ + ... + + def run(self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: """ @@ -688,6 +1027,7 @@ def run(self, dry=False, verbose=True, None, None, smc_off_B, system_generator, settings['solvation_settings'], ) + # Take the modeller from system A --> every water/ion should be in # the same location system_modeller_AB = copy.copy(system_modeller_A) @@ -773,29 +1113,111 @@ def run(self, dry=False, verbose=True, open('outputAB_new.pdb', 'w')) - # 7. Get lambdas - lambdas = self._get_lambda_schedule(settings) - + # 9. Create the alchemical system apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) - # # 8. Add restraints - # self._add_restraints(omm_system, omm_topology, settings) - # - # # 9. Get alchemical system - # alchem_factory, alchem_system, alchem_indices = - # self._get_alchemical_system( - # omm_topology, omm_system, comp_resids, alchem_comps - # ) + # 10. Apply Restraints + off_A = alchem_comps["stateA"][0].to_openff().to_topology() + lig_A_pos = positions_AB[atom_indices_AB_A[0]:atom_indices_AB_A[-1]+1, :] / omm_units.nanometers * unit.nanometer + self._set_positions(off_A, lig_A_pos) + off_A.to_file('molA.pdb') + off_B = alchem_comps["stateB"][0].to_openff().to_topology() + lig_B_pos = positions_AB[ + atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, + :] / omm_units.nanometers * unit.nanometer + self._set_positions(off_B, lig_B_pos) + off_B.to_file('molB.pdb') + + ligand_A_inxs, ligand_B_inxs = select_ligand_idxs(off_A, off_B) + + ligand_A_inxs = [atom_indices_AB_A[inx] for inx in ligand_A_inxs] + ligand_B_inxs = [atom_indices_AB_B[inx] for inx in ligand_B_inxs] + print(ligand_A_inxs) + print(ligand_B_inxs) + + system = self._add_restraints(omm_system_AB, positions_AB, settings, ligand_A_inxs, ligand_B_inxs) + print(system) + + # Here we could also apply REST + + # # 7. Get lambdas + # lambdas = self._get_lambda_schedule(settings) # # # 10. Get compound and sampler states # sampler_states, cmp_states = self._get_states( - # alchem_system, positions, settings, + # omm_system_AB, positions_AB, settings, # lambdas, solv_comp # ) # + # # 11. Create the multistate reporter & create PDB + # reporter = self._get_reporter( + # omm_topology_AB, positions_AB, + # settings['simulation_settings'], + # settings['output_settings'], + # ) + # + # # Wrap in try/finally to avoid memory leak issues + # try: + # # 12. Get context caches + # energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( + # settings['engine_settings'] + # ) + # + # # 13. Get integrator + # integrator = self._get_integrator( + # settings['integrator_settings'], + # settings['simulation_settings'], + # ) + # + # # 14. Get sampler + # sampler = self._get_sampler( + # integrator, reporter, settings['simulation_settings'], + # settings['thermo_settings'], + # cmp_states, sampler_states, + # energy_ctx_cache, sampler_ctx_cache + # ) + # + # # 15. Run simulation + # unit_result_dict = self._run_simulation( + # sampler, reporter, settings, dry + # ) + # + # finally: + # # close reporter when you're done to prevent file handle clashes + # reporter.close() + # + # # clear GPU context + # # Note: use cache.empty() when openmmtools #690 is resolved + # for context in list(energy_ctx_cache._lru._data.keys()): + # del energy_ctx_cache._lru._data[context] + # for context in list(sampler_ctx_cache._lru._data.keys()): + # del sampler_ctx_cache._lru._data[context] + # # cautiously clear out the global context cache too + # for context in list( + # openmmtools.cache.global_context_cache._lru._data.keys()): + # del openmmtools.cache.global_context_cache._lru._data[context] + # + # del sampler_ctx_cache, energy_ctx_cache + # + # # Keep these around in a dry run so we can inspect things + # if not dry: + # del integrator, sampler + # + # if not dry: + # nc = self.shared_basepath / settings[ + # 'output_settings'].output_filename + # chk = settings['output_settings'].checkpoint_storage_filename + # return { + # 'nc': nc, + # 'last_checkpoint': chk, + # **unit_result_dict, + # } + # else: + # return {'debug': {'sampler': sampler}} + # # - # eventually save the serialized alchemical systems to disc to be - # picked up by the run unit + # # eventually save the serialized alchemical systems to disc to be + # # picked up by the run unit class BaseSepTopRunUnit(gufe.ProtocolUnit): diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index dd3339d3e..7dde1919c 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -30,6 +30,7 @@ import warnings from collections import defaultdict import gufe +import openmm from gufe.components import Component import itertools import numpy as np @@ -54,13 +55,13 @@ MultiStateSimulationSettings, OpenMMEngineSettings, IntegratorSettings, MultiStateOutputSettings, OpenFFPartialChargeSettings, - SettingsBaseModel, + SettingsBaseModel, RestraintsSettings, ) from ..openmm_utils import system_validation, settings_validation -from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit +from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit, _get from openfe.utils import log_system_probe from openfe.due import due, Doi - +from .femto_restraints import select_ligand_idxs, select_receptor_idxs due.cite(Doi("10.5281/zenodo.596622"), @@ -479,6 +480,8 @@ def _default_settings(cls): output_filename='complex.nc', checkpoint_storage_filename='complex_checkpoint.nc' ), + solvent_restraints_settings=RestraintsSettings(), + complex_restraints_settings=RestraintsSettings(), ) @staticmethod @@ -797,6 +800,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * equil_output_settings : MDOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings + * restraint_settings: RestraintsSettings """ prot_settings = self._inputs['protocol'].settings @@ -813,6 +817,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['equil_output_settings'] = prot_settings.complex_equil_output_settings settings['simulation_settings'] = prot_settings.complex_simulation_settings settings['output_settings'] = prot_settings.complex_output_settings + settings['restraint_settings'] = prot_settings.complex_restraints_settings settings_validation.validate_timestep( settings['forcefield_settings'].hydrogen_mass, @@ -836,6 +841,36 @@ def _update_positions( return updated_positions_B + @staticmethod + def _add_restraints( + system: openmm.System, + positions: np.array, + topology: openmm.Topology, + settings, + ligand_1_ref_idx: int, + ligand_2_ref_idx: int, + ) -> openmm.System: + + traj = _get_mdtraj_from_openmm(topology, positions) + receptor_ref_idxs_1 = select_receptor_idxs( + traj, ligand_1, ligand_1_ref_idxs + ) + receptor_ref_idxs_2 = receptor_ref_idxs_1 + + # Remove the offset of ligand 2 atom indices. + # `ligand_2_ref_idxs` should be in the range 0:ligand_2.atoms to match + # `ligand_2` parmed.amber.AmberParm. + _ligand_2_ref_idxs = tuple( + i - len(ligand_1.atoms) for i in ligand_2_ref_idxs) + if ligand_2 is not None and not femto.fe.reference.check_receptor_idxs( + receptor, receptor_ref_idxs_1, ligand_2, _ligand_2_ref_idxs + ): + _LOGGER.info( + "selecting alternate receptor reference atoms for ligand 2") + receptor_ref_idxs_2 = femto.fe.reference.select_receptor_idxs( + receptor, ligand_2, _ligand_2_ref_idxs + + def _execute( self, ctx: gufe.Context, **kwargs, ) -> dict[str, Any]: @@ -917,6 +952,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings + * restraint_settings: RestraintsSettings """ prot_settings = self._inputs['protocol'].settings @@ -933,6 +969,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: 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 + settings['restraint_settings'] = prot_settings.solvent_restraints_settings settings_validation.validate_timestep( settings['forcefield_settings'].hydrogen_mass, @@ -972,6 +1009,44 @@ def _update_positions( return updated_positions_B + @staticmethod + def _add_restraints( + system: openmm.System, + positions, + topology, + settings, + ligand_1_ref_idx: int, + ligand_2_ref_idx: int, + ) -> openmm.System: + """Apply a distance restraints between the ligands. + + Args: + system: The OpenMM system to add the restraints to. + topology: The full topology of the complex phase. + ligand_1_ref_idx: The reference index of the first ligand. + ligand_2_ref_idx: The reference index of the second ligand. + """ + + coords = positions + + distance = np.linalg.norm( + coords[ligand_1_ref_idx] - coords[ligand_2_ref_idx]) + print(distance) + + force = openmm.HarmonicBondForce() + force.addBond( + ligand_1_ref_idx[1], + ligand_2_ref_idx[1], + distance * openmm.unit.angstrom, + settings['restraint_settings'].k_distance.m, + ) + force.setName("alignment_restraint") + force.setForceGroup(6) + + system.addForce(force) + + return system + def _execute( self, ctx: gufe.Context, **kwargs, diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index af08b187c..6f97575eb 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -25,6 +25,8 @@ MDSimulationSettings, MDOutputSettings, ) +from openff.units import unit +from openff.models.types import FloatQuantity import numpy as np from pydantic.v1 import validator @@ -36,6 +38,15 @@ class AlchemicalSettings(SettingsBaseModel): """ +class RestraintsSettings(SettingsBaseModel): + """ + Settings for the restraints. + """ + k_distance: FloatQuantity['kcal/(mol*angstrom**2)'] = 20 * unit.kilocalorie_per_mole / unit.angstrom**2 + k_theta: FloatQuantity['kcal/(mol*rad**2)'] = 20 * unit.kilocalorie_per_mole / unit.radians**2 + + + class LambdaSettings(SettingsBaseModel): """Lambda schedule settings. @@ -51,19 +62,13 @@ class LambdaSettings(SettingsBaseModel): the same length, defining all the windows of the transformation. """ - lambda_elec: list[float] = [ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.5, 0.75, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - ] + lambda_elec: list[float] = [0.0] * 8 + [0.25, 0.5, 0.75] + [1.0] * 8 """ List of floats of lambda values for the electrostatics. Zero means state A and 1 means state B. Length of this list needs to match length of lambda_vdw and lambda_restraints. """ - lambda_vdw: list[float] = [ - 0.0, 0.142857143, 0.285714286, 0.428571429, 0.571428571, 0.714285714, - 0.857142857, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 - ] + lambda_vdw: list[float] = np.linspace(1.0, 0.0, 8).tolist() + [0.0, 0.0, 0.0] + [0.0] * 8 """ List of floats of lambda values for the van der Waals. Zero means state A and 1 means state B. @@ -205,3 +210,11 @@ def must_be_positive(cls, v): including the partial charge assignment method, and the number of conformers used to generate the partial charges. """ + solvent_restraints_settings: RestraintsSettings + """ + Settings for the harmonic restraint in the solvent + """ + complex_restraints_settings: RestraintsSettings + """ + Settings for the Boresch restraints in the complex + """ diff --git a/openfe/protocols/openmm_septop/femto_utils.py b/openfe/protocols/openmm_septop/femto_alchemy.py similarity index 99% rename from openfe/protocols/openmm_septop/femto_utils.py rename to openfe/protocols/openmm_septop/femto_alchemy.py index a00bb5c9b..1d8d5b7ed 100644 --- a/openfe/protocols/openmm_septop/femto_utils.py +++ b/openfe/protocols/openmm_septop/femto_alchemy.py @@ -8,6 +8,8 @@ # import femto.fe.config +# This code was obtained and modified from https://github.com/Psivant/femto + LAMBDA_VDW_LIGAND_1 = "lambda_vdw_lig_1" """The global parameter used to scale the vdW interactions of ligand 1.""" LAMBDA_VDW_LIGAND_2 = "lambda_vdw_lig_2" @@ -343,4 +345,4 @@ def apply_fep( for force in updated_forces: if force is not None: - system.addForce(force) \ No newline at end of file + system.addForce(force) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py new file mode 100644 index 000000000..6f1e04f1b --- /dev/null +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -0,0 +1,598 @@ +"""Utilities for automatically selecting 'reference' atoms for alignment.""" + +import copy +import itertools +import logging +import typing + +import mdtraj +import networkx +import numpy +import openmm.unit +import parmed +import scipy.spatial +import scipy.spatial.distance +from .femto_utils import compute_angles, compute_dihedrals + +_COLLINEAR_THRESHOLD = 0.9 # roughly 25 degrees + +# values taken from the SepTop reference implementation at commit 7af0b4d +_ANGLE_CHECK_FORCE_CONSTANT = 20.0 * openmm.unit.kilocalorie_per_mole +_ANGLE_CHECK_T = 298.15 * openmm.unit.kelvin +_ANGLE_CHECK_RT = openmm.unit.MOLAR_GAS_CONSTANT_R * _ANGLE_CHECK_T + +_ANGLE_CHECK_FACTOR = 0.5 * _ANGLE_CHECK_FORCE_CONSTANT / _ANGLE_CHECK_RT +_ANGLE_CHECK_CUTOFF = 10.0 # units of kT + +_ANGLE_CHECK_MAX_VAR = 100.0 # units of degrees^2 + +_DIHEDRAL_CHECK_CUTOFF = 150.0 # units of degrees +_DIHEDRAL_CHECK_MAX_VAR = 300.0 # units of degrees^2 + +_RMSF_CUTOFF = 0.1 # nm + +def _is_angle_linear(coords: numpy.ndarray, idxs: tuple[int, int, int]) -> bool: + """Check if angle is within 10 kT from 0 or 180 following the SepTop reference + implementation. + + Args: + coords: The full set of coordinates. + idxs: The indices of the three atoms that form the angle. + + Returns: + True if the angle is linear, False otherwise. + """ + + angles = numpy.rad2deg( + compute_angles(coords, numpy.array([idxs])) + ) + + angle_avg_rad = numpy.deg2rad(scipy.stats.circmean(angles, low=-180.0, high=180.0)) + angle_var_deg = scipy.stats.circvar(angles, low=-180.0, high=180.0) + + check_1 = _ANGLE_CHECK_FACTOR * angle_avg_rad**2 + check_2 = _ANGLE_CHECK_FACTOR * (angle_avg_rad - numpy.pi) ** 2 + + return ( + check_1 < _ANGLE_CHECK_CUTOFF + or check_2 < _ANGLE_CHECK_CUTOFF + or angle_var_deg > _ANGLE_CHECK_MAX_VAR + ) + + +def _is_dihedral_trans(coords: numpy.ndarray, idxs: tuple[int, int, int, int]) -> bool: + """Check if a dihedral angle is within -150 and 150 degrees. + + Args: + coords: The full set of coordinates. + idxs: The indices of the four atoms that form the dihedral. + + Returns: + True if the dihedral is planar. + """ + + dihedrals = numpy.rad2deg( + compute_dihedrals(coords, numpy.array([idxs])) + ) + + dihedral_avg = scipy.stats.circmean(dihedrals, low=-180.0, high=180.0) + dihedral_var = scipy.stats.circvar(dihedrals, low=-180.0, high=180.0) + + return ( + numpy.abs(dihedral_avg) > _DIHEDRAL_CHECK_CUTOFF + or dihedral_var > _DIHEDRAL_CHECK_MAX_VAR + ) + + +def _are_collinear( + coords: numpy.ndarray, idxs: typing.Sequence[int] | None = None +) -> bool: + """Checks whether a sequence of coordinates are collinear. + + Args: + coords: The full set of coordinates, either with ``shape=(n_coords, 3)`` or + ``shape=(n_frames, n_coords, 3)``. + idxs: The sequence of indices of those coordinates to check for collinearity. + + Returns: + True if any sequential pair of vectors is collinear. + """ + + if coords.ndim == 2: + coords = coords.reshape(1, *coords.shape) + + idxs = idxs if idxs is not None else list(range(coords.shape[1])) + + for i in range(len(idxs) - 2): + v_1 = coords[:, idxs[i + 1], :] - coords[:, idxs[i], :] + v_1 /= numpy.linalg.norm(v_1, axis=-1, keepdims=True) + v_2 = coords[:, idxs[i + 2], :] - coords[:, idxs[i + 1], :] + v_2 /= numpy.linalg.norm(v_2, axis=-1, keepdims=True) + + if (numpy.abs((v_1 * v_2).sum(axis=-1)) > _COLLINEAR_THRESHOLD).any(): + return True + + return False + + +def _create_ligand_queries( + ligand, snapshots: list[openmm.unit.Quantity] | None +) -> tuple[str, str, str]: + """Selects three atoms from a ligand for use in + Boresch-likes restraints using the method described by Baumann et al. + + References: + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy + calculations using a Separated Topologies approach." (2023). + """ + + ligand_graph = networkx.from_edgelist( + [(bond.atom1_index, bond.atom2_index) + for bond in ligand.bonds + if bond.atom1.atomic_number != 1 and bond.atom2.atomic_number != 1] + ) + + all_paths = [ + path + for node_paths in networkx.shortest_path(ligand_graph).values() + for path in node_paths.values() + ] + path_lengths = {(path[0], path[-1]): len(path) for path in all_paths} + + longest_path = max(all_paths, key=len) + center_idx = longest_path[len(longest_path) // 2] + + cycles = networkx.cycle_basis(ligand_graph) + + if len(cycles) >= 1 and snapshots is not None: + top = mdtraj.Topology.from_openmm(ligand.to_openmm()) + ligand_trajectory = mdtraj.Trajectory( + snapshots, + top, + ) + ligand_trajectory.superpose(ligand_trajectory) + + rmsf = mdtraj.rmsf(ligand_trajectory, ligand_trajectory, 0) + cycles = [cycle for cycle in cycles if rmsf[cycle].max() < _RMSF_CUTOFF] + + if len(cycles) >= 1: + open_list = [atom_idx for cycle in cycles for atom_idx in cycle] + else: + open_list = [atom.idx for atom in ligand.atoms if atom.atomic_number != 1] + + distances = [path_lengths[(center_idx, atom_idx)] for atom_idx in open_list] + closest_idx = open_list[numpy.argmin(distances)] + print(closest_idx) + + if len(cycles) >= 1: + # restrict the list of reference atoms to select from to those that are in the + # same cycle as the closest atom. + cycle_idx = next( + iter(i for i, cycle in enumerate(cycles) if closest_idx in cycle) + ) + open_list = cycles[cycle_idx] + + distances = [path_lengths[(closest_idx, atom_idx)] for atom_idx in open_list] + + open_list = [ + idx + for _, idx in sorted(zip(distances, open_list, strict=True)) + if idx != closest_idx + ] + restrain_atoms = (open_list[0], closest_idx, open_list[1]) + + # TODO: check if the reference atoms are co-linear + # TODO: handle the unhappy paths of not enough atoms are found. + + return restrain_atoms + + +def select_ligand_idxs( + ligand_1, # OpenFF Topology + ligand_2, # OpenFF Topology + ligand_1_queries: tuple[str, str, str] | None = None, + ligand_2_queries: tuple[str, str, str] | None = None, +) -> tuple[tuple[int, int, int], tuple[int, int, int] | None]: + """Returns the indices of the reference atoms that may be used to align ligands. + + Args: + ligand_1: The first ligand. + ligand_2: The second ligand. + ligand_1_queries: Three (optional) indices to use to manually + select atoms from the first ligand. + ligand_2_queries: Three (optional) indices to use to manually + select atoms from the second ligand + + Returns: + The indices of the first and second ligand respectively. + """ + if ligand_1_queries is None or ligand_2_queries is None: + + if ligand_1_queries is None: + # Setting frames to None right now + # ToDo: Enable use of snapshots + ligand_1_queries = _create_ligand_queries(ligand_1, None) + if ligand_2_queries is None: + ligand_2_queries = _create_ligand_queries(ligand_2, None) + + # ligand_1_idxs = queries_to_idxs(ligand_1, ligand_1_queries) + + # ligand_2_idxs = queries_to_idxs(ligand_2, ligand_2_queries) + + return ligand_1_queries, ligand_2_queries + + +def _filter_receptor_atoms( + receptor: mdtraj.Trajectory, + ligand: mdtraj.Trajectory, + ligand_ref_idx: int, + min_helix_size: int = 8, + min_sheet_size: int = 8, + skip_residues_start: int = 20, + skip_residues_end: int = 10, + minimum_distance: openmm.unit.Quantity = 1.0 * openmm.unit.nanometers, + maximum_distance: openmm.unit.Quantity = 3.0 * openmm.unit.nanometers, +) -> list[int]: + """Select possible protein atoms for Boresch-style restraints based on + the criteria + outlined by Baumann et al. + + Args: + receptor: The receptor structure. + ligand: The ligand structure. + ligand_ref_idx: The index of the first reference ligand atom. + min_helix_size: The minimum number of residues that have to be in an + alpha-helix + for it to be considered stable. + min_sheet_size: The minimum number of residues that have to be in a + beta-sheet + for it to be considered stable. + skip_residues_start: The number of residues to skip at the start of + the protein + as these tend to be more flexible. + skip_residues_end: The number of residues to skip at the end of the + protein + as these tend to be more flexible + minimum_distance: Discard any protein atoms that are closer than + this distance + to the ligand. + maximum_distance: Discard any protein atoms that are further than + this distance + from the ligand. + + Returns: + The indices of protein atoms that should be considered for use in + Boresch-style + restraints. + """ + + assert min_helix_size >= 7, "helices must be at least 7 residues long" + assert min_sheet_size >= 7, "sheets must be at least 7 residues long" + + backbone_idxs = receptor.top.select("protein and (backbone or name CB)") + backbone: mdtraj.Trajectory = receptor.atom_slice(backbone_idxs, + inplace=False) + + structure = mdtraj.compute_dssp(backbone, simplified=True).tolist()[0] + # following the SepTop reference implementation we prefer to select from + # alpha + # helices if they are dominant in the protein, but otherwise select from + # sheets + # as well. + n_helix_residues = structure.count("H") + n_sheet_residues = structure.count("E") + + allowed_motifs = ["H"] if n_helix_residues >= n_sheet_residues else ["H", + "E"] + min_motif_size = {"H": min_helix_size, "E": min_sheet_size} + + residues_to_keep = [] + + structure = structure[skip_residues_start: -(skip_residues_end + 1)] + + for motif, idxs in itertools.groupby(enumerate(structure), lambda x: x[1]): + + idxs = [(idx + skip_residues_start, motif) for idx, motif in idxs] + + if motif not in allowed_motifs or len(idxs) < min_motif_size[motif]: + continue + # discard the first and last 3 residues of the helix / sheet + start_idx, end_idx = idxs[0][0] + 3, idxs[-1][0] - 3 + + residues_to_keep.extend( + f"resid {idx}" for idx in range(start_idx, end_idx + 1)) + rigid_backbone_idxs = backbone.top.select(" ".join(residues_to_keep)) + + if len(rigid_backbone_idxs) == 0: + raise ValueError("no suitable receptor atoms could be found") + + if backbone.n_frames > 1: + superposed = copy.deepcopy(backbone) + superposed.superpose(superposed) + + rmsf = mdtraj.rmsf(superposed, superposed, 0) # nm + + rigid_backbone_idxs = rigid_backbone_idxs[ + rmsf[rigid_backbone_idxs] < _RMSF_CUTOFF + ] + + distances = scipy.spatial.distance.cdist( + backbone.xyz[0, rigid_backbone_idxs, :], + ligand.xyz[0, [ligand_ref_idx], :] + ) + + minimum_distance = minimum_distance.value_in_unit(openmm.unit.nanometer) + maximum_distance = maximum_distance.value_in_unit(openmm.unit.nanometer) + + distance_mask = (distances > minimum_distance).all(axis=1) + distance_mask &= (distances <= maximum_distance).any(axis=1) + + return backbone_idxs[rigid_backbone_idxs[distance_mask]].tolist() + + +def _is_valid_r1( + receptor: mdtraj.Trajectory, + receptor_idx: int, + ligand: mdtraj.Trajectory, + ligand_ref_idxs: tuple[int, int, int], +) -> bool: + """Check whether a given receptor atom would be a valid 'R1' atom given the + following criteria: + + * L2,L1,R1 angle not 'close' to 0 or 180 degrees + * L3,L2,L1,R1 dihedral between -150 and 150 degrees + + Args: + receptor: The receptor structure. + receptor_idx: The index of the receptor atom to check. + ligand: The ligand structure. + ligand_ref_idxs: The three reference ligand atoms. + """ + + coords = numpy.concatenate([ligand.xyz, receptor.xyz], axis=1) + + l1, l2, l3 = ligand_ref_idxs + # r1 = receptor_idx + r1 = receptor_idx + ligand.n_atoms + + if _are_collinear(coords, (r1, l1, l2, l3)): + return False + + if _is_angle_linear(coords, (r1, l1, l2)): + return False + + if _is_dihedral_trans(coords, (r1, l1, l2, l3)): + return False + + return True + + +def _is_valid_r2( + receptor: mdtraj.Trajectory, + receptor_idx: int, + receptor_ref_idx_1: int, + ligand: mdtraj.Trajectory, + ligand_ref_idxs: tuple[int, int, int], +) -> bool: + """Check whether a given receptor atom would be a valid 'R2' atom given the + following criteria: + + * R1,R2 are further apart than 5 Angstroms + * R2,R1,L1,L2 are not collinear + * R2,R1,L1 angle not 'close' to 0 or 180 degrees + * R2,R1,L1,L2 dihedral between -150 and 150 degrees + + Args: + receptor: The receptor structure. + receptor_idx: The index of the receptor atom to check. + receptor_ref_idx_1: The index of the first receptor reference atom. + ligand: The ligand structure. + ligand_ref_idxs: The three reference ligand atoms. + """ + + coords = numpy.concatenate([ligand.xyz, receptor.xyz], axis=1) + + l1, l2, l3 = ligand_ref_idxs + r1, r2 = receptor_ref_idx_1 + ligand.n_atoms, receptor_idx + ligand.n_atoms + # r1, r2 = receptor_ref_idx_1 , receptor_idx + + if r1 == r2: + return False + + if numpy.linalg.norm(coords[:, r1, :] - coords[:, r2, :], axis=-1).mean() < 0.5: + return False + + if _are_collinear(coords, (r2, r1, l1, l2)): + return False + + if _is_angle_linear(coords, (r2, r1, l1)): + return False + + if _is_dihedral_trans(coords, (r2, r1, l1, l2)): + return False + + return True + + +def _is_valid_r3( + receptor: mdtraj.Trajectory, + receptor_idx: int, + receptor_ref_idx_1: int, + receptor_ref_idx_2: int, + ligand: mdtraj.Trajectory, + ligand_ref_idxs: tuple[int, int, int], +) -> bool: + """Check whether a given receptor atom would be a valid 'R3' atom given the + following criteria: + + * R1,R2,R3,L1 are not collinear + * R3,R2,R1,L1 dihedral between -150 and 150 degrees + + Args: + receptor: The receptor structure. + receptor_idx: The index of the receptor atom to check. + receptor_ref_idx_1: The index of the first receptor reference atom. + receptor_ref_idx_2: The index of the second receptor reference atom. + ligand: The ligand structure. + ligand_ref_idxs: The three reference ligand atoms. + """ + + coords = numpy.concatenate([ligand.xyz, receptor.xyz], axis=1) + + l1, l2, l3 = ligand_ref_idxs + r1, r2, r3 = ( + receptor_ref_idx_1 + ligand.n_atoms, + receptor_ref_idx_2 + ligand.n_atoms, + receptor_idx + ligand.n_atoms, + ) + + if len({r1, r2, r3}) != 3: + return False + + if _are_collinear(coords[[0]], (r3, r2, r1, l1)): + return False + + if _is_dihedral_trans(coords, (r3, r2, r1, l1)): + return False + + return True + + +def select_receptor_idxs( + receptor: mdtraj.Trajectory, + ligand: mdtraj.Trajectory, + ligand_ref_idxs: tuple[int, int, int], +) -> tuple[int, int, int]: + """Select possible protein atoms for Boresch-style restraints using the method + outlined by Baumann et al [1]. + + References: + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy + calculations using a Separated Topologies approach." (2023). + + Args: + receptor: The receptor structure. + ligand: The ligand structure. + ligand_ref_idxs: The indices of the three ligands atoms that will be restrained. + + Returns: + The indices of the three atoms to use for the restraint + """ + if not (isinstance(receptor, type(ligand)) or isinstance(ligand, type(receptor))): + raise ValueError("receptor and ligand must be the same type") + + assert ( + receptor.n_frames == ligand.n_frames + ), "receptor and ligand must have the same number of frames" + + receptor_idxs = _filter_receptor_atoms(receptor, ligand, ligand_ref_idxs[0]) + + valid_r1_idxs = [ + idx + for idx in receptor_idxs + if _is_valid_r1(receptor, idx, ligand, ligand_ref_idxs) + ] + + found_r1, found_r2 = next( + ( + (r1, r2) + for r1 in valid_r1_idxs + for r2 in receptor_idxs + if _is_valid_r2(receptor, r2, r1, ligand, ligand_ref_idxs) + ), + None, + ) + print(found_r1) + print(found_r2) + + if found_r1 is None or found_r2 is None: + raise ValueError("could not find valid R1 / R2 atoms") + + valid_r3_idxs = [ + idx + for idx in receptor_idxs + if _is_valid_r3(receptor, idx, found_r1, found_r2, ligand, ligand_ref_idxs) + ] + print(valid_r3_idxs) + + if len(valid_r3_idxs) == 0: + raise ValueError("could not find a valid R3 atom") + + r3_distances_per_frame = [] + + for frame_r, frame_l in zip(receptor.xyz, ligand.xyz, strict=True): + r3_r_distances = scipy.spatial.distance.cdist( + frame_r[valid_r3_idxs, :], frame_r[[found_r1, found_r2], :] + ) + r3_l_distances = scipy.spatial.distance.cdist( + frame_r[valid_r3_idxs, :], frame_l[[ligand_ref_idxs[0]], :] + ) + + r3_distances_per_frame.append(numpy.hstack([r3_r_distances, r3_l_distances])) + + # chosen to match the SepTop reference implementation at commit 3705ba5 + # max_distance = 0.8 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) + max_distance = 3 + + r3_distances_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) + + max_distance_mask = r3_distances_avg.max(axis=-1) < max_distance + r3_distances_avg = r3_distances_avg[max_distance_mask] + + valid_r3_idxs = numpy.array(valid_r3_idxs)[max_distance_mask].tolist() + + r3_distances_prod = r3_distances_avg[:, 0] * r3_distances_avg[:, 1] + found_r3 = valid_r3_idxs[r3_distances_prod.argmax()] + + return found_r1, found_r2, found_r3 + + +def check_receptor_idxs( + receptor: mdtraj.Trajectory, + receptor_idxs: tuple[int, int, int], + ligand: mdtraj.Trajectory, + ligand_ref_idxs: tuple[int, int, int], +) -> bool: + """Check if the specified receptor atoms meet the criteria for use in Boresch-style + restraints as defined by Baumann et al [1]. + + References: + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy + calculations using a Separated Topologies approach." (2023). + + Args: + receptor: The receptor structure. + receptor_idxs: The indices of the three receptor atoms that will be restrained. + ligand: The ligand structure. + ligand_ref_idxs: The indices of the three ligand atoms that will be restrained. + + Returns: + True if the atoms meet the criteria, False otherwise. + """ + if not (isinstance(receptor, type(ligand)) or isinstance(ligand, type(receptor))): + raise ValueError("receptor and ligand must be the same type") + + if isinstance(receptor, parmed.Structure) and isinstance(ligand, parmed.Structure): + receptor = _structure_to_mdtraj(receptor) + ligand = _structure_to_mdtraj(ligand) + + assert ( + receptor.n_frames == ligand.n_frames + ), "receptor and ligand must have the same number of frames" + + r1, r2, r3 = receptor_idxs + + is_valid_r1 = _is_valid_r1(receptor, r1, ligand, ligand_ref_idxs) + is_valid_r2 = _is_valid_r2(receptor, r2, r1, ligand, ligand_ref_idxs) + is_valid_r3 = _is_valid_r3(receptor, r3, r1, r2, ligand, ligand_ref_idxs) + + r3_distances_per_frame = [ + scipy.spatial.distance.cdist(frame[[r3], :], frame[[r1, r2], :]) + for frame in receptor.xyz + ] + r3_distance_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) + + max_distance = 0.8 * (receptor.unitcell_lengths[-1][0] / 2) + is_valid_distance = r3_distance_avg.max(axis=-1) < max_distance + + return is_valid_r1 and is_valid_r2 and is_valid_r3 and is_valid_distance diff --git a/openfe/tests/conftest.py b/openfe/tests/conftest.py index 9a8f691d6..7fbbe98f5 100644 --- a/openfe/tests/conftest.py +++ b/openfe/tests/conftest.py @@ -233,6 +233,14 @@ def T4_protein_component(): return comp +@pytest.fixture(scope='session') +def bace_protein_component(): + with resources.files('openfe.tests.data.openmm_septop') as d: + fn = str(d / 'bace.pdb') + comp = gufe.ProteinComponent.from_pdb_file(fn, name="BACE") + + return comp + @pytest.fixture() def eg5_protein_pdb(): diff --git a/openfe/tests/data/openmm_septop/__init__.py b/openfe/tests/data/openmm_septop/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openfe/tests/data/openmm_septop/bace.pdb b/openfe/tests/data/openmm_septop/bace.pdb new file mode 100644 index 000000000..a032ccc37 --- /dev/null +++ b/openfe/tests/data/openmm_septop/bace.pdb @@ -0,0 +1,6053 @@ +REMARK GENERATED BY TRJCONV +TITLE 6OD6(A)altA +MODEL 1 +ATOM 1 C ACE A -6 -25.006 -74.654 28.933 0.00 99.99 C +ATOM 2 O ACE A -6 -26.174 -74.741 29.237 0.00 99.99 O +ATOM 3 CH3 ACE A -6 -24.203 -75.902 28.655 0.00 99.99 C +ATOM 4 HH31 ACE A -6 -24.845 -76.787 28.778 0.00 20.00 H +ATOM 5 HH32 ACE A -6 -23.819 -75.869 27.625 0.00 20.00 H +ATOM 6 HH33 ACE A -6 -23.360 -75.961 29.359 0.00 20.00 H +ATOM 7 N THR A -5 -24.429 -73.459 28.843 1.00 83.06 N +ATOM 8 CA THR A -5 -25.094 -72.181 29.086 1.00 83.80 C +ATOM 9 C THR A -5 -24.875 -71.228 27.913 1.00 84.73 C +ATOM 10 O THR A -5 -25.648 -70.293 27.711 1.00 85.36 O +ATOM 11 CB THR A -5 -24.597 -71.525 30.391 1.00 83.62 C +ATOM 12 OG1 THR A -5 -23.171 -71.382 30.346 0.00 84.45 O +ATOM 13 CG2 THR A -5 -24.977 -72.388 31.590 0.00 83.91 C +ATOM 14 H THR A -5 -23.462 -73.433 28.589 1.00 20.00 H +ATOM 15 HA THR A -5 -26.175 -72.355 29.186 1.00 20.00 H +ATOM 16 HB THR A -5 -25.074 -70.539 30.495 1.00 20.00 H +ATOM 17 HG1 THR A -5 -22.935 -70.488 30.566 0.00 20.00 H +ATOM 18 HG21 THR A -5 -24.618 -71.911 32.514 0.00 20.00 H +ATOM 19 HG22 THR A -5 -26.071 -72.494 31.633 0.00 20.00 H +ATOM 20 HG23 THR A -5 -24.516 -73.382 31.487 0.00 20.00 H +ATOM 21 N THR A -4 -23.817 -71.467 27.141 1.00 84.55 N +ATOM 22 CA THR A -4 -23.558 -70.739 25.906 1.00 83.51 C +ATOM 23 C THR A -4 -23.330 -71.747 24.787 1.00 79.98 C +ATOM 24 O THR A -4 -23.306 -72.961 25.007 1.00 79.46 O +ATOM 25 CB THR A -4 -22.353 -69.798 26.043 1.00 82.46 C +ATOM 26 OG1 THR A -4 -21.157 -70.573 26.197 1.00 81.80 O +ATOM 27 CG2 THR A -4 -22.515 -68.880 27.249 1.00 81.31 C +ATOM 28 H THR A -4 -23.172 -72.178 27.421 1.00 20.00 H +ATOM 29 HA THR A -4 -24.440 -70.133 25.652 1.00 20.00 H +ATOM 30 HB THR A -4 -22.286 -69.180 25.135 1.00 20.00 H +ATOM 31 HG1 THR A -4 -21.385 -71.467 26.422 1.00 20.00 H +ATOM 32 HG21 THR A -4 -21.641 -68.217 27.326 1.00 20.00 H +ATOM 33 HG22 THR A -4 -23.425 -68.274 27.129 1.00 20.00 H +ATOM 34 HG23 THR A -4 -22.596 -69.487 28.163 1.00 20.00 H +ATOM 35 N GLY A -3 -23.166 -71.240 23.572 1.00 76.78 N +ATOM 36 CA GLY A -3 -22.945 -72.134 22.447 1.00 70.94 C +ATOM 37 C GLY A -3 -22.972 -71.402 21.124 1.00 65.00 C +ATOM 38 O GLY A -3 -22.606 -70.224 21.036 1.00 61.21 O +ATOM 39 H GLY A -3 -23.194 -70.250 23.431 1.00 20.00 H +ATOM 40 HA2 GLY A -3 -21.964 -72.617 22.565 1.00 20.00 H +ATOM 41 HA3 GLY A -3 -23.733 -72.901 22.444 1.00 20.00 H +ATOM 42 N SER A -2 -23.406 -72.124 20.093 1.00 63.67 N +ATOM 43 CA SER A -2 -23.430 -71.623 18.726 1.00 60.31 C +ATOM 44 C SER A -2 -24.873 -71.472 18.272 1.00 58.61 C +ATOM 45 O SER A -2 -25.628 -72.450 18.257 1.00 59.22 O +ATOM 46 CB SER A -2 -22.675 -72.560 17.785 1.00 60.87 C +ATOM 47 OG SER A -2 -22.613 -72.012 16.484 1.00 54.75 O +ATOM 48 H SER A -2 -23.731 -73.054 20.265 1.00 20.00 H +ATOM 49 HA SER A -2 -22.948 -70.635 18.692 1.00 20.00 H +ATOM 50 HB2 SER A -2 -21.653 -72.707 18.164 1.00 20.00 H +ATOM 51 HB3 SER A -2 -23.195 -73.529 17.745 1.00 20.00 H +ATOM 52 HG SER A -2 -23.490 -71.953 16.123 1.00 20.00 H +ATOM 53 N PHE A -1 -25.250 -70.252 17.902 1.00 57.91 N +ATOM 54 CA PHE A -1 -26.577 -69.994 17.361 1.00 59.48 C +ATOM 55 C PHE A -1 -26.422 -69.411 15.968 1.00 59.75 C +ATOM 56 O PHE A -1 -26.699 -68.232 15.732 1.00 59.77 O +ATOM 57 CB PHE A -1 -27.363 -69.067 18.288 1.00 60.22 C +ATOM 58 CG PHE A -1 -27.640 -69.667 19.635 1.00 60.18 C +ATOM 59 CD1 PHE A -1 -26.680 -69.636 20.636 1.00 58.55 C +ATOM 60 CD2 PHE A -1 -28.856 -70.277 19.897 1.00 59.33 C +ATOM 61 CE1 PHE A -1 -26.933 -70.198 21.876 1.00 59.65 C +ATOM 62 CE2 PHE A -1 -29.113 -70.836 21.135 1.00 60.85 C +ATOM 63 CZ PHE A -1 -28.150 -70.797 22.123 1.00 59.87 C +ATOM 64 H PHE A -1 -24.606 -69.493 17.998 1.00 20.00 H +ATOM 65 HA PHE A -1 -27.125 -70.944 17.280 1.00 20.00 H +ATOM 66 HB2 PHE A -1 -26.784 -68.143 18.430 1.00 20.00 H +ATOM 67 HB3 PHE A -1 -28.324 -68.827 17.809 1.00 20.00 H +ATOM 68 HD1 PHE A -1 -25.725 -69.169 20.446 1.00 20.00 H +ATOM 69 HD2 PHE A -1 -29.611 -70.316 19.126 1.00 20.00 H +ATOM 70 HE1 PHE A -1 -26.178 -70.167 22.648 1.00 20.00 H +ATOM 71 HE2 PHE A -1 -30.067 -71.303 21.329 1.00 20.00 H +ATOM 72 HZ PHE A -1 -28.350 -71.236 23.090 1.00 20.00 H +ATOM 73 N VAL A 0 -25.995 -70.265 15.038 1.00 57.00 N +ATOM 74 CA VAL A 0 -25.383 -69.808 13.798 1.00 57.40 C +ATOM 75 C VAL A 0 -26.389 -69.142 12.869 1.00 53.75 C +ATOM 76 O VAL A 0 -26.014 -68.281 12.065 1.00 58.61 O +ATOM 77 CB VAL A 0 -24.663 -70.995 13.123 1.00 60.49 C +ATOM 78 CG1 VAL A 0 -25.667 -71.911 12.419 1.00 58.61 C +ATOM 79 CG2 VAL A 0 -23.588 -70.509 12.172 1.00 65.29 C +ATOM 80 H VAL A 0 -26.098 -71.247 15.196 1.00 20.00 H +ATOM 81 HA VAL A 0 -24.616 -69.060 14.046 1.00 20.00 H +ATOM 82 HB VAL A 0 -24.174 -71.581 13.915 1.00 20.00 H +ATOM 83 HG11 VAL A 0 -25.132 -72.748 11.946 1.00 20.00 H +ATOM 84 HG12 VAL A 0 -26.384 -72.303 13.155 1.00 20.00 H +ATOM 85 HG13 VAL A 0 -26.207 -71.340 11.649 1.00 20.00 H +ATOM 86 HG21 VAL A 0 -23.092 -71.373 11.706 1.00 20.00 H +ATOM 87 HG22 VAL A 0 -24.045 -69.883 11.391 1.00 20.00 H +ATOM 88 HG23 VAL A 0 -22.847 -69.917 12.729 1.00 20.00 H +ATOM 89 N GLU A 1 -27.669 -69.509 12.958 1.00 46.87 N +ATOM 90 CA GLU A 1 -28.667 -68.879 12.097 1.00 46.68 C +ATOM 91 C GLU A 1 -29.004 -67.461 12.522 1.00 46.62 C +ATOM 92 O GLU A 1 -29.515 -66.688 11.704 1.00 50.85 O +ATOM 93 CB GLU A 1 -29.962 -69.690 12.059 1.00 46.55 C +ATOM 94 CG GLU A 1 -29.991 -70.723 10.972 1.00 51.02 C +ATOM 95 CD GLU A 1 -29.171 -71.926 11.343 1.00 53.26 C +ATOM 96 OE1 GLU A 1 -28.378 -72.407 10.507 1.00 50.59 O +ATOM 97 OE2 GLU A 1 -29.324 -72.379 12.493 1.00 51.82 O +ATOM 98 H GLU A 1 -27.944 -70.213 13.612 1.00 20.00 H +ATOM 99 HA GLU A 1 -28.269 -68.837 11.073 1.00 20.00 H +ATOM 100 HB2 GLU A 1 -30.082 -70.200 13.026 1.00 20.00 H +ATOM 101 HB3 GLU A 1 -30.802 -68.997 11.903 1.00 20.00 H +ATOM 102 HG2 GLU A 1 -31.032 -71.037 10.803 1.00 20.00 H +ATOM 103 HG3 GLU A 1 -29.586 -70.284 10.049 1.00 20.00 H +ATOM 104 N MET A 2 -28.750 -67.105 13.776 1.00 40.27 N +ATOM 105 CA MET A 2 -29.115 -65.786 14.264 1.00 36.21 C +ATOM 106 C MET A 2 -27.947 -64.818 14.282 1.00 39.12 C +ATOM 107 O MET A 2 -28.156 -63.620 14.493 1.00 39.42 O +ATOM 108 CB MET A 2 -29.738 -65.909 15.658 1.00 40.69 C +ATOM 109 CG MET A 2 -31.090 -66.608 15.624 1.00 41.21 C +ATOM 110 SD MET A 2 -31.937 -66.770 17.202 1.00 44.04 S +ATOM 111 CE MET A 2 -31.293 -68.329 17.799 1.00 48.68 C +ATOM 112 H MET A 2 -28.302 -67.753 14.392 1.00 20.00 H +ATOM 113 HA MET A 2 -29.883 -65.369 13.596 1.00 20.00 H +ATOM 114 HB2 MET A 2 -29.057 -66.486 16.301 1.00 20.00 H +ATOM 115 HB3 MET A 2 -29.871 -64.901 16.077 1.00 20.00 H +ATOM 116 HG2 MET A 2 -31.745 -66.039 14.948 1.00 20.00 H +ATOM 117 HG3 MET A 2 -30.935 -67.619 15.220 1.00 20.00 H +ATOM 118 HE1 MET A 2 -32.093 -68.886 18.309 1.00 20.00 H +ATOM 119 HE2 MET A 2 -30.919 -68.920 16.950 1.00 20.00 H +ATOM 120 HE3 MET A 2 -30.471 -68.140 18.505 1.00 20.00 H +ATOM 121 N VAL A 3 -26.731 -65.314 14.063 1.00 40.35 N +ATOM 122 CA VAL A 3 -25.581 -64.439 13.892 1.00 39.02 C +ATOM 123 C VAL A 3 -25.802 -63.545 12.682 1.00 40.33 C +ATOM 124 O VAL A 3 -26.155 -64.017 11.593 1.00 44.12 O +ATOM 125 CB VAL A 3 -24.295 -65.269 13.753 1.00 42.69 C +ATOM 126 CG1 VAL A 3 -23.200 -64.454 13.077 1.00 46.48 C +ATOM 127 CG2 VAL A 3 -23.835 -65.764 15.122 1.00 43.17 C +ATOM 128 H VAL A 3 -26.606 -66.305 14.015 1.00 20.00 H +ATOM 129 HA VAL A 3 -25.480 -63.799 14.781 1.00 20.00 H +ATOM 130 HB VAL A 3 -24.516 -66.144 13.124 1.00 20.00 H +ATOM 131 HG11 VAL A 3 -22.290 -65.065 12.987 1.00 20.00 H +ATOM 132 HG12 VAL A 3 -23.536 -64.148 12.075 1.00 20.00 H +ATOM 133 HG13 VAL A 3 -22.983 -63.560 13.680 1.00 20.00 H +ATOM 134 HG21 VAL A 3 -22.915 -66.356 15.008 1.00 20.00 H +ATOM 135 HG22 VAL A 3 -23.638 -64.902 15.776 1.00 20.00 H +ATOM 136 HG23 VAL A 3 -24.621 -66.391 15.568 1.00 20.00 H +ATOM 137 N ASP A 4 -25.629 -62.235 12.886 1.00 40.78 N +ATOM 138 CA ASP A 4 -25.671 -61.233 11.822 1.00 47.34 C +ATOM 139 C ASP A 4 -27.075 -61.053 11.245 1.00 49.19 C +ATOM 140 O ASP A 4 -27.229 -60.766 10.058 1.00 50.30 O +ATOM 141 CB ASP A 4 -24.666 -61.565 10.710 1.00 49.64 C +ATOM 142 CG ASP A 4 -24.356 -60.372 9.835 1.00 53.90 C +ATOM 143 OD1 ASP A 4 -24.051 -59.305 10.401 1.00 56.94 O +ATOM 144 OD2 ASP A 4 -24.426 -60.493 8.594 1.00 58.91 O +ATOM 145 H ASP A 4 -25.461 -61.922 13.821 1.00 20.00 H +ATOM 146 HA ASP A 4 -25.370 -60.267 12.253 1.00 20.00 H +ATOM 147 HB2 ASP A 4 -23.732 -61.916 11.172 1.00 20.00 H +ATOM 148 HB3 ASP A 4 -25.087 -62.364 10.081 1.00 20.00 H +ATOM 149 N ASN A 5 -28.112 -61.194 12.072 1.00 50.26 N +ATOM 150 CA ASN A 5 -29.479 -61.028 11.590 1.00 48.50 C +ATOM 151 C ASN A 5 -30.011 -59.606 11.736 1.00 45.51 C +ATOM 152 O ASN A 5 -31.161 -59.355 11.367 1.00 40.30 O +ATOM 153 CB ASN A 5 -30.431 -62.011 12.298 1.00 39.89 C +ATOM 154 CG ASN A 5 -30.514 -61.789 13.801 1.00 41.70 C +ATOM 155 OD1 ASN A 5 -29.875 -60.893 14.348 1.00 47.34 O +ATOM 156 ND2 ASN A 5 -31.316 -62.609 14.474 1.00 33.76 N +ATOM 157 H ASN A 5 -27.951 -61.416 13.034 1.00 20.00 H +ATOM 158 HA ASN A 5 -29.496 -61.275 10.518 1.00 20.00 H +ATOM 159 HB2 ASN A 5 -31.438 -61.891 11.871 1.00 20.00 H +ATOM 160 HB3 ASN A 5 -30.075 -63.035 12.115 1.00 20.00 H +ATOM 161 HD21 ASN A 5 -31.417 -62.509 15.464 1.00 20.00 H +ATOM 162 HD22 ASN A 5 -31.818 -63.326 13.990 1.00 20.00 H +ATOM 163 N LEU A 6 -29.222 -58.669 12.250 1.00 35.87 N +ATOM 164 CA LEU A 6 -29.687 -57.298 12.414 1.00 39.39 C +ATOM 165 C LEU A 6 -29.063 -56.380 11.369 1.00 47.96 C +ATOM 166 O LEU A 6 -27.891 -56.517 11.013 1.00 51.47 O +ATOM 167 CB LEU A 6 -29.375 -56.758 13.814 1.00 39.00 C +ATOM 168 CG LEU A 6 -29.989 -57.456 15.023 1.00 40.52 C +ATOM 169 CD1 LEU A 6 -29.711 -56.665 16.297 1.00 36.04 C +ATOM 170 CD2 LEU A 6 -31.482 -57.690 14.857 1.00 42.24 C +ATOM 171 H LEU A 6 -28.292 -58.909 12.529 1.00 20.00 H +ATOM 172 HA LEU A 6 -30.778 -57.274 12.278 1.00 20.00 H +ATOM 173 HB2 LEU A 6 -28.283 -56.795 13.939 1.00 20.00 H +ATOM 174 HB3 LEU A 6 -29.712 -55.711 13.839 1.00 20.00 H +ATOM 175 HG LEU A 6 -29.504 -58.438 15.125 1.00 20.00 H +ATOM 176 HD11 LEU A 6 -30.161 -57.183 17.157 1.00 20.00 H +ATOM 177 HD12 LEU A 6 -28.625 -56.582 16.447 1.00 20.00 H +ATOM 178 HD13 LEU A 6 -30.147 -55.659 16.206 1.00 20.00 H +ATOM 179 HD21 LEU A 6 -31.876 -58.194 15.752 1.00 20.00 H +ATOM 180 HD22 LEU A 6 -31.992 -56.724 14.726 1.00 20.00 H +ATOM 181 HD23 LEU A 6 -31.658 -58.321 13.973 1.00 20.00 H +ATOM 182 N ARG A 7 -29.864 -55.433 10.882 1.00 44.44 N +ATOM 183 CA ARG A 7 -29.381 -54.404 9.970 1.00 46.12 C +ATOM 184 C ARG A 7 -29.895 -53.051 10.430 1.00 45.74 C +ATOM 185 O ARG A 7 -30.754 -52.956 11.309 1.00 51.83 O +ATOM 186 CB ARG A 7 -29.818 -54.672 8.522 1.00 49.94 C +ATOM 187 CG ARG A 7 -29.081 -55.816 7.847 1.00 48.18 C +ATOM 188 CD ARG A 7 -27.655 -55.418 7.506 1.00 56.99 C +ATOM 189 NE ARG A 7 -26.883 -56.546 6.989 1.00 64.39 N +ATOM 190 CZ ARG A 7 -26.286 -57.457 7.754 1.00 62.67 C +ATOM 191 NH1 ARG A 7 -25.601 -58.450 7.201 1.00 60.26 N +ATOM 192 NH2 ARG A 7 -26.373 -57.379 9.076 1.00 56.97 N +ATOM 193 H ARG A 7 -30.827 -55.428 11.151 1.00 20.00 H +ATOM 194 HA ARG A 7 -28.281 -54.384 9.998 1.00 20.00 H +ATOM 195 HB2 ARG A 7 -30.892 -54.909 8.525 1.00 20.00 H +ATOM 196 HB3 ARG A 7 -29.645 -53.758 7.936 1.00 20.00 H +ATOM 197 HG2 ARG A 7 -29.061 -56.681 8.526 1.00 20.00 H +ATOM 198 HG3 ARG A 7 -29.610 -56.088 6.922 1.00 20.00 H +ATOM 199 HD2 ARG A 7 -27.680 -54.625 6.744 1.00 20.00 H +ATOM 200 HD3 ARG A 7 -27.165 -55.038 8.415 1.00 20.00 H +ATOM 201 HE ARG A 7 -26.798 -56.639 5.997 1.00 20.00 H +ATOM 202 HH11 ARG A 7 -25.155 -59.133 7.780 1.00 20.00 H +ATOM 203 HH12 ARG A 7 -25.531 -58.515 6.206 1.00 20.00 H +ATOM 204 HH21 ARG A 7 -25.924 -58.066 9.648 1.00 20.00 H +ATOM 205 HH22 ARG A 7 -26.887 -56.634 9.500 1.00 20.00 H +ATOM 206 N GLY A 8 -29.363 -51.995 9.826 1.00 48.16 N +ATOM 207 CA GLY A 8 -29.873 -50.666 10.090 1.00 49.22 C +ATOM 208 C GLY A 8 -29.128 -49.621 9.296 1.00 54.13 C +ATOM 209 O GLY A 8 -28.031 -49.863 8.785 1.00 60.54 O +ATOM 210 H GLY A 8 -28.605 -52.118 9.185 1.00 20.00 H +ATOM 211 HA2 GLY A 8 -30.938 -50.631 9.817 1.00 20.00 H +ATOM 212 HA3 GLY A 8 -29.762 -50.447 11.162 1.00 20.00 H +ATOM 213 N LYS A 9 -29.757 -48.454 9.189 1.00 51.26 N +ATOM 214 CA LYS A 9 -29.100 -47.266 8.674 1.00 55.97 C +ATOM 215 C LYS A 9 -28.494 -46.504 9.843 1.00 58.25 C +ATOM 216 O LYS A 9 -29.074 -46.456 10.933 1.00 61.53 O +ATOM 217 CB LYS A 9 -30.087 -46.377 7.919 1.00 61.77 C +ATOM 218 CG LYS A 9 -30.929 -47.118 6.897 1.00 63.82 C +ATOM 219 CD LYS A 9 -30.115 -47.509 5.675 1.00 66.99 C +ATOM 220 CE LYS A 9 -30.983 -48.224 4.645 1.00 66.46 C +ATOM 221 NZ LYS A 9 -31.496 -49.528 5.154 0.00 63.64 N +ATOM 222 H LYS A 9 -30.714 -48.393 9.473 1.00 20.00 H +ATOM 223 HA LYS A 9 -28.293 -47.558 7.986 1.00 20.00 H +ATOM 224 HB2 LYS A 9 -30.763 -45.911 8.651 1.00 20.00 H +ATOM 225 HB3 LYS A 9 -29.517 -45.595 7.396 1.00 20.00 H +ATOM 226 HG2 LYS A 9 -31.334 -48.029 7.362 1.00 20.00 H +ATOM 227 HG3 LYS A 9 -31.758 -46.468 6.580 1.00 20.00 H +ATOM 228 HD2 LYS A 9 -29.691 -46.602 5.220 1.00 20.00 H +ATOM 229 HD3 LYS A 9 -29.300 -48.179 5.985 1.00 20.00 H +ATOM 230 HE2 LYS A 9 -31.838 -47.580 4.393 1.00 20.00 H +ATOM 231 HE3 LYS A 9 -30.383 -48.407 3.741 1.00 20.00 H +ATOM 232 HZ1 LYS A 9 -31.955 -50.018 4.413 0.00 20.00 H +ATOM 233 HZ2 LYS A 9 -30.732 -50.077 5.494 0.00 20.00 H +ATOM 234 HZ3 LYS A 9 -32.145 -49.364 5.897 0.00 20.00 H +ATOM 235 N SER A 10 -27.315 -45.926 9.615 1.00 61.00 N +ATOM 236 CA SER A 10 -26.605 -45.217 10.672 1.00 62.58 C +ATOM 237 C SER A 10 -27.482 -44.140 11.297 1.00 62.43 C +ATOM 238 O SER A 10 -27.815 -43.143 10.648 1.00 66.54 O +ATOM 239 CB SER A 10 -25.315 -44.601 10.131 1.00 62.08 C +ATOM 240 OG SER A 10 -24.566 -43.992 11.169 0.00 58.48 O +ATOM 241 H SER A 10 -26.910 -45.980 8.702 1.00 20.00 H +ATOM 242 HA SER A 10 -26.333 -45.934 11.460 1.00 20.00 H +ATOM 243 HB2 SER A 10 -24.707 -45.391 9.665 1.00 20.00 H +ATOM 244 HB3 SER A 10 -25.568 -43.841 9.377 1.00 20.00 H +ATOM 245 HG SER A 10 -24.726 -43.056 11.168 0.00 20.00 H +ATOM 246 N GLY A 11 -27.886 -44.355 12.546 1.00 60.61 N +ATOM 247 CA GLY A 11 -28.618 -43.359 13.301 1.00 58.32 C +ATOM 248 C GLY A 11 -30.128 -43.475 13.269 1.00 58.45 C +ATOM 249 O GLY A 11 -30.810 -42.558 13.743 1.00 60.87 O +ATOM 250 H GLY A 11 -27.678 -45.233 12.978 1.00 20.00 H +ATOM 251 HA2 GLY A 11 -28.298 -43.431 14.351 1.00 20.00 H +ATOM 252 HA3 GLY A 11 -28.348 -42.370 12.902 1.00 20.00 H +ATOM 253 N GLN A 12 -30.681 -44.571 12.744 1.00 58.88 N +ATOM 254 CA GLN A 12 -32.121 -44.676 12.565 1.00 55.22 C +ATOM 255 C GLN A 12 -32.744 -45.940 13.141 1.00 57.32 C +ATOM 256 O GLN A 12 -33.975 -46.042 13.152 1.00 64.11 O +ATOM 257 CB GLN A 12 -32.475 -44.562 11.074 1.00 58.43 C +ATOM 258 CG GLN A 12 -32.361 -43.131 10.545 1.00 65.11 C +ATOM 259 CD GLN A 12 -32.628 -43.022 9.061 1.00 75.53 C +ATOM 260 OE1 GLN A 12 -32.649 -44.024 8.350 1.00 80.19 O +ATOM 261 NE2 GLN A 12 -32.837 -41.798 8.582 1.00 76.70 N +ATOM 262 H GLN A 12 -30.095 -45.333 12.469 1.00 20.00 H +ATOM 263 HA GLN A 12 -32.590 -43.821 13.074 1.00 20.00 H +ATOM 264 HB2 GLN A 12 -31.791 -45.204 10.500 1.00 20.00 H +ATOM 265 HB3 GLN A 12 -33.509 -44.908 10.931 1.00 20.00 H +ATOM 266 HG2 GLN A 12 -33.089 -42.502 11.078 1.00 20.00 H +ATOM 267 HG3 GLN A 12 -31.343 -42.764 10.745 1.00 20.00 H +ATOM 268 HE21 GLN A 12 -33.020 -41.667 7.608 1.00 20.00 H +ATOM 269 HE22 GLN A 12 -32.811 -41.009 9.196 1.00 20.00 H +ATOM 270 N GLY A 13 -31.952 -46.889 13.632 1.00 45.93 N +ATOM 271 CA GLY A 13 -32.508 -48.035 14.324 1.00 42.54 C +ATOM 272 C GLY A 13 -32.056 -49.391 13.821 1.00 44.75 C +ATOM 273 O GLY A 13 -31.856 -49.584 12.619 1.00 45.90 O +ATOM 274 H GLY A 13 -30.961 -46.811 13.523 1.00 20.00 H +ATOM 275 HA2 GLY A 13 -32.228 -47.958 15.385 1.00 20.00 H +ATOM 276 HA3 GLY A 13 -33.603 -47.988 14.230 1.00 20.00 H +ATOM 277 N TYR A 14 -31.887 -50.339 14.742 1.00 41.58 N +ATOM 278 CA TYR A 14 -31.529 -51.710 14.404 1.00 41.93 C +ATOM 279 C TYR A 14 -32.797 -52.537 14.239 1.00 39.95 C +ATOM 280 O TYR A 14 -33.649 -52.558 15.130 1.00 43.63 O +ATOM 281 CB TYR A 14 -30.648 -52.326 15.491 1.00 42.83 C +ATOM 282 CG TYR A 14 -29.245 -51.758 15.588 1.00 45.11 C +ATOM 283 CD1 TYR A 14 -28.971 -50.664 16.398 1.00 44.78 C +ATOM 284 CD2 TYR A 14 -28.189 -52.335 14.890 1.00 47.46 C +ATOM 285 CE1 TYR A 14 -27.691 -50.153 16.500 1.00 46.09 C +ATOM 286 CE2 TYR A 14 -26.902 -51.826 14.984 1.00 46.25 C +ATOM 287 CZ TYR A 14 -26.661 -50.734 15.792 1.00 47.24 C +ATOM 288 OH TYR A 14 -25.390 -50.219 15.897 1.00 49.70 O +ATOM 289 H TYR A 14 -32.011 -50.099 15.705 1.00 20.00 H +ATOM 290 HA TYR A 14 -30.974 -51.722 13.454 1.00 20.00 H +ATOM 291 HB2 TYR A 14 -31.145 -52.171 16.460 1.00 20.00 H +ATOM 292 HB3 TYR A 14 -30.565 -53.404 15.290 1.00 20.00 H +ATOM 293 HD1 TYR A 14 -29.772 -50.204 16.958 1.00 20.00 H +ATOM 294 HD2 TYR A 14 -28.375 -53.195 14.264 1.00 20.00 H +ATOM 295 HE1 TYR A 14 -27.498 -49.300 17.133 1.00 20.00 H +ATOM 296 HE2 TYR A 14 -26.095 -52.281 14.429 1.00 20.00 H +ATOM 297 HH TYR A 14 -25.397 -49.475 16.488 1.00 20.00 H +ATOM 298 N TYR A 15 -32.918 -53.228 13.111 1.00 34.45 N +ATOM 299 CA TYR A 15 -34.131 -53.975 12.814 1.00 43.63 C +ATOM 300 C TYR A 15 -33.830 -55.415 12.428 1.00 47.15 C +ATOM 301 O TYR A 15 -32.769 -55.729 11.880 1.00 47.11 O +ATOM 302 CB TYR A 15 -34.956 -53.301 11.705 1.00 39.16 C +ATOM 303 CG TYR A 15 -34.247 -53.062 10.390 1.00 37.22 C +ATOM 304 CD1 TYR A 15 -34.170 -54.060 9.426 1.00 38.79 C +ATOM 305 CD2 TYR A 15 -33.697 -51.822 10.090 1.00 39.69 C +ATOM 306 CE1 TYR A 15 -33.542 -53.835 8.207 1.00 40.59 C +ATOM 307 CE2 TYR A 15 -33.071 -51.590 8.879 1.00 41.48 C +ATOM 308 CZ TYR A 15 -32.996 -52.596 7.942 1.00 43.59 C +ATOM 309 OH TYR A 15 -32.371 -52.362 6.739 1.00 51.63 O +ATOM 310 H TYR A 15 -32.163 -53.235 12.455 1.00 20.00 H +ATOM 311 HA TYR A 15 -34.755 -53.998 13.720 1.00 20.00 H +ATOM 312 HB2 TYR A 15 -35.829 -53.938 11.503 1.00 20.00 H +ATOM 313 HB3 TYR A 15 -35.294 -52.326 12.085 1.00 20.00 H +ATOM 314 HD1 TYR A 15 -34.606 -55.027 9.628 1.00 20.00 H +ATOM 315 HD2 TYR A 15 -33.759 -51.025 10.816 1.00 20.00 H +ATOM 316 HE1 TYR A 15 -33.482 -54.624 7.472 1.00 20.00 H +ATOM 317 HE2 TYR A 15 -32.642 -50.622 8.669 1.00 20.00 H +ATOM 318 HH TYR A 15 -32.869 -52.767 6.039 1.00 20.00 H +ATOM 319 N VAL A 16 -34.796 -56.279 12.720 1.00 45.50 N +ATOM 320 CA VAL A 16 -34.743 -57.694 12.391 1.00 36.27 C +ATOM 321 C VAL A 16 -35.870 -57.994 11.414 1.00 45.56 C +ATOM 322 O VAL A 16 -36.937 -57.373 11.470 1.00 42.95 O +ATOM 323 CB VAL A 16 -34.857 -58.572 13.655 1.00 41.85 C +ATOM 324 CG1 VAL A 16 -36.231 -58.415 14.301 1.00 42.39 C +ATOM 325 CG2 VAL A 16 -34.572 -60.027 13.329 1.00 43.83 C +ATOM 326 H VAL A 16 -35.607 -55.936 13.194 1.00 20.00 H +ATOM 327 HA VAL A 16 -33.785 -57.920 11.900 1.00 20.00 H +ATOM 328 HB VAL A 16 -34.100 -58.227 14.375 1.00 20.00 H +ATOM 329 HG11 VAL A 16 -36.289 -59.049 15.198 1.00 20.00 H +ATOM 330 HG12 VAL A 16 -36.385 -57.363 14.584 1.00 20.00 H +ATOM 331 HG13 VAL A 16 -37.009 -58.720 13.586 1.00 20.00 H +ATOM 332 HG21 VAL A 16 -34.659 -60.632 14.243 1.00 20.00 H +ATOM 333 HG22 VAL A 16 -35.297 -60.384 12.583 1.00 20.00 H +ATOM 334 HG23 VAL A 16 -33.553 -60.119 12.924 1.00 20.00 H +ATOM 335 N GLU A 17 -35.624 -58.929 10.506 1.00 46.71 N +ATOM 336 CA GLU A 17 -36.665 -59.346 9.582 1.00 47.25 C +ATOM 337 C GLU A 17 -37.617 -60.310 10.275 1.00 44.32 C +ATOM 338 O GLU A 17 -37.184 -61.226 10.981 1.00 37.21 O +ATOM 339 CB GLU A 17 -36.052 -59.992 8.339 1.00 46.81 C +ATOM 340 CG GLU A 17 -37.089 -60.483 7.335 1.00 51.91 C +ATOM 341 CD GLU A 17 -36.475 -60.980 6.040 1.00 59.76 C +ATOM 342 OE1 GLU A 17 -36.038 -60.142 5.220 1.00 58.11 O +ATOM 343 OE2 GLU A 17 -36.422 -62.213 5.845 1.00 60.64 O +ATOM 344 H GLU A 17 -34.718 -59.349 10.457 1.00 20.00 H +ATOM 345 HA GLU A 17 -37.239 -58.464 9.263 1.00 20.00 H +ATOM 346 HB2 GLU A 17 -35.410 -59.250 7.842 1.00 20.00 H +ATOM 347 HB3 GLU A 17 -35.442 -60.850 8.658 1.00 20.00 H +ATOM 348 HG2 GLU A 17 -37.656 -61.307 7.792 1.00 20.00 H +ATOM 349 HG3 GLU A 17 -37.772 -59.653 7.103 1.00 20.00 H +ATOM 350 N MET A 18 -38.915 -60.090 10.086 1.00 42.05 N +ATOM 351 CA MET A 18 -39.944 -60.963 10.628 1.00 38.08 C +ATOM 352 C MET A 18 -41.027 -61.156 9.574 1.00 42.70 C +ATOM 353 O MET A 18 -41.151 -60.371 8.632 1.00 43.61 O +ATOM 354 CB MET A 18 -40.567 -60.396 11.922 1.00 38.77 C +ATOM 355 CG MET A 18 -39.574 -59.931 12.988 1.00 39.81 C +ATOM 356 SD MET A 18 -40.371 -59.212 14.441 1.00 44.70 S +ATOM 357 CE MET A 18 -41.076 -60.663 15.226 1.00 43.49 C +ATOM 358 H MET A 18 -39.194 -59.293 9.550 1.00 20.00 H +ATOM 359 HA MET A 18 -39.505 -61.944 10.860 1.00 20.00 H +ATOM 360 HB2 MET A 18 -41.194 -59.535 11.646 1.00 20.00 H +ATOM 361 HB3 MET A 18 -41.196 -61.181 12.366 1.00 20.00 H +ATOM 362 HG2 MET A 18 -38.976 -60.797 13.310 1.00 20.00 H +ATOM 363 HG3 MET A 18 -38.912 -59.174 12.542 1.00 20.00 H +ATOM 364 HE1 MET A 18 -42.060 -60.410 15.649 1.00 20.00 H +ATOM 365 HE2 MET A 18 -41.192 -61.463 14.480 1.00 20.00 H +ATOM 366 HE3 MET A 18 -40.408 -61.006 16.030 1.00 20.00 H +ATOM 367 N THR A 19 -41.798 -62.227 9.727 1.00 43.90 N +ATOM 368 CA THR A 19 -42.965 -62.478 8.893 1.00 46.71 C +ATOM 369 C THR A 19 -44.206 -62.555 9.768 1.00 46.06 C +ATOM 370 O THR A 19 -44.158 -63.084 10.883 1.00 47.91 O +ATOM 371 CB THR A 19 -42.840 -63.778 8.086 1.00 47.17 C +ATOM 372 OG1 THR A 19 -42.938 -64.901 8.969 1.00 48.71 O +ATOM 373 CG2 THR A 19 -41.518 -63.831 7.344 1.00 51.93 C +ATOM 374 H THR A 19 -41.568 -62.886 10.443 1.00 20.00 H +ATOM 375 HA THR A 19 -43.090 -61.645 8.186 1.00 20.00 H +ATOM 376 HB THR A 19 -43.657 -63.810 7.351 1.00 20.00 H +ATOM 377 HG1 THR A 19 -43.763 -64.864 9.439 1.00 20.00 H +ATOM 378 HG21 THR A 19 -41.454 -64.770 6.775 1.00 20.00 H +ATOM 379 HG22 THR A 19 -41.451 -62.978 6.653 1.00 20.00 H +ATOM 380 HG23 THR A 19 -40.690 -63.783 8.066 1.00 20.00 H +ATOM 381 N VAL A 20 -45.309 -62.014 9.257 1.00 46.73 N +ATOM 382 CA VAL A 20 -46.601 -62.061 9.926 1.00 41.74 C +ATOM 383 C VAL A 20 -47.627 -62.617 8.947 1.00 41.09 C +ATOM 384 O VAL A 20 -47.606 -62.290 7.755 1.00 40.35 O +ATOM 385 CB VAL A 20 -47.029 -60.670 10.447 1.00 42.85 C +ATOM 386 CG1 VAL A 20 -45.992 -60.113 11.408 1.00 44.45 C +ATOM 387 CG2 VAL A 20 -47.241 -59.703 9.293 1.00 46.65 C +ATOM 388 H VAL A 20 -45.248 -61.553 8.372 1.00 20.00 H +ATOM 389 HA VAL A 20 -46.539 -62.743 10.787 1.00 20.00 H +ATOM 390 HB VAL A 20 -47.981 -60.783 10.987 1.00 20.00 H +ATOM 391 HG11 VAL A 20 -46.316 -59.125 11.766 1.00 20.00 H +ATOM 392 HG12 VAL A 20 -45.882 -60.795 12.264 1.00 20.00 H +ATOM 393 HG13 VAL A 20 -45.027 -60.017 10.890 1.00 20.00 H +ATOM 394 HG21 VAL A 20 -47.544 -58.722 9.687 1.00 20.00 H +ATOM 395 HG22 VAL A 20 -46.304 -59.597 8.727 1.00 20.00 H +ATOM 396 HG23 VAL A 20 -48.028 -60.091 8.630 1.00 20.00 H +ATOM 397 N GLY A 21 -48.506 -63.482 9.446 1.00 43.40 N +ATOM 398 CA GLY A 21 -49.646 -63.919 8.667 1.00 47.41 C +ATOM 399 C GLY A 21 -49.400 -65.179 7.856 1.00 50.37 C +ATOM 400 O GLY A 21 -48.311 -65.754 7.824 1.00 49.69 O +ATOM 401 H GLY A 21 -48.378 -63.836 10.373 1.00 20.00 H +ATOM 402 HA2 GLY A 21 -50.482 -64.110 9.356 1.00 20.00 H +ATOM 403 HA3 GLY A 21 -49.920 -63.110 7.973 1.00 20.00 H +ATOM 404 N SER A 22 -50.463 -65.602 7.173 1.00 48.77 N +ATOM 405 CA SER A 22 -50.455 -66.803 6.340 1.00 48.89 C +ATOM 406 C SER A 22 -51.149 -66.478 5.028 1.00 51.12 C +ATOM 407 O SER A 22 -52.359 -66.165 5.030 1.00 45.38 O +ATOM 408 CB SER A 22 -51.151 -67.967 7.049 1.00 47.17 C +ATOM 409 OG SER A 22 -50.579 -68.211 8.319 1.00 43.41 O +ATOM 410 H SER A 22 -51.308 -65.071 7.233 1.00 20.00 H +ATOM 411 HA SER A 22 -49.416 -67.094 6.127 1.00 20.00 H +ATOM 412 HB2 SER A 22 -52.216 -67.724 7.176 1.00 20.00 H +ATOM 413 HB3 SER A 22 -51.053 -68.872 6.432 1.00 20.00 H +ATOM 414 HG SER A 22 -51.067 -67.738 8.983 1.00 20.00 H +ATOM 415 N PRO A 23 -50.448 -66.520 3.880 1.00 51.38 N +ATOM 416 CA PRO A 23 -49.014 -66.806 3.737 1.00 42.05 C +ATOM 417 C PRO A 23 -48.153 -65.677 4.330 1.00 47.05 C +ATOM 418 O PRO A 23 -48.698 -64.599 4.577 1.00 51.11 O +ATOM 419 CB PRO A 23 -48.839 -66.932 2.219 1.00 43.56 C +ATOM 420 CG PRO A 23 -49.945 -66.121 1.641 1.00 51.98 C +ATOM 421 CD PRO A 23 -51.100 -66.305 2.577 1.00 52.00 C +ATOM 422 HA PRO A 23 -48.758 -67.760 4.221 1.00 20.00 H +ATOM 423 HB2 PRO A 23 -47.862 -66.534 1.907 1.00 20.00 H +ATOM 424 HB3 PRO A 23 -48.924 -67.983 1.905 1.00 20.00 H +ATOM 425 HG2 PRO A 23 -49.658 -65.061 1.587 1.00 20.00 H +ATOM 426 HG3 PRO A 23 -50.203 -66.483 0.635 1.00 20.00 H +ATOM 427 HD2 PRO A 23 -51.705 -67.178 2.290 1.00 20.00 H +ATOM 428 HD3 PRO A 23 -51.737 -65.409 2.598 1.00 20.00 H +ATOM 429 N PRO A 24 -46.859 -65.913 4.568 1.00 45.47 N +ATOM 430 CA PRO A 24 -46.092 -64.976 5.404 1.00 42.67 C +ATOM 431 C PRO A 24 -45.835 -63.661 4.683 1.00 41.98 C +ATOM 432 O PRO A 24 -45.469 -63.641 3.505 1.00 47.05 O +ATOM 433 CB PRO A 24 -44.781 -65.726 5.682 1.00 43.26 C +ATOM 434 CG PRO A 24 -44.914 -67.078 5.030 1.00 46.20 C +ATOM 435 CD PRO A 24 -45.991 -66.958 4.003 1.00 47.13 C +ATOM 436 HA PRO A 24 -46.617 -64.786 6.352 1.00 20.00 H +ATOM 437 HB2 PRO A 24 -43.931 -65.178 5.250 1.00 20.00 H +ATOM 438 HB3 PRO A 24 -44.631 -65.840 6.766 1.00 20.00 H +ATOM 439 HG2 PRO A 24 -43.965 -67.363 4.552 1.00 20.00 H +ATOM 440 HG3 PRO A 24 -45.188 -67.835 5.780 1.00 20.00 H +ATOM 441 HD2 PRO A 24 -45.580 -66.649 3.031 1.00 20.00 H +ATOM 442 HD3 PRO A 24 -46.536 -67.907 3.886 1.00 20.00 H +ATOM 443 N GLN A 25 -46.034 -62.561 5.403 1.00 43.39 N +ATOM 444 CA GLN A 25 -45.751 -61.219 4.910 1.00 39.88 C +ATOM 445 C GLN A 25 -44.488 -60.709 5.594 1.00 40.48 C +ATOM 446 O GLN A 25 -44.453 -60.577 6.822 1.00 43.60 O +ATOM 447 CB GLN A 25 -46.929 -60.280 5.171 1.00 39.86 C +ATOM 448 CG GLN A 25 -48.212 -60.695 4.466 1.00 37.10 C +ATOM 449 CD GLN A 25 -49.377 -59.777 4.787 1.00 44.95 C +ATOM 450 OE1 GLN A 25 -49.205 -58.569 4.953 1.00 46.99 O +ATOM 451 NE2 GLN A 25 -50.571 -60.349 4.882 1.00 47.32 N +ATOM 452 H GLN A 25 -46.396 -62.660 6.330 1.00 20.00 H +ATOM 453 HA GLN A 25 -45.570 -61.258 3.826 1.00 20.00 H +ATOM 454 HB2 GLN A 25 -47.120 -60.256 6.254 1.00 20.00 H +ATOM 455 HB3 GLN A 25 -46.653 -59.273 4.825 1.00 20.00 H +ATOM 456 HG2 GLN A 25 -48.039 -60.678 3.380 1.00 20.00 H +ATOM 457 HG3 GLN A 25 -48.472 -61.717 4.780 1.00 20.00 H +ATOM 458 HE21 GLN A 25 -51.375 -59.795 5.096 1.00 20.00 H +ATOM 459 HE22 GLN A 25 -50.666 -61.334 4.740 1.00 20.00 H +ATOM 460 N THR A 26 -43.463 -60.416 4.798 1.00 41.48 N +ATOM 461 CA THR A 26 -42.169 -60.004 5.329 1.00 46.76 C +ATOM 462 C THR A 26 -42.179 -58.533 5.724 1.00 47.40 C +ATOM 463 O THR A 26 -42.702 -57.682 4.998 1.00 51.05 O +ATOM 464 CB THR A 26 -41.071 -60.253 4.295 1.00 50.57 C +ATOM 465 OG1 THR A 26 -41.081 -61.633 3.913 1.00 51.99 O +ATOM 466 CG2 THR A 26 -39.702 -59.905 4.862 1.00 47.01 C +ATOM 467 H THR A 26 -43.583 -60.480 3.807 1.00 20.00 H +ATOM 468 HA THR A 26 -41.940 -60.600 6.224 1.00 20.00 H +ATOM 469 HB THR A 26 -41.263 -59.618 3.417 1.00 20.00 H +ATOM 470 HG1 THR A 26 -40.428 -62.106 4.415 1.00 20.00 H +ATOM 471 HG21 THR A 26 -38.931 -60.092 4.100 1.00 20.00 H +ATOM 472 HG22 THR A 26 -39.683 -58.843 5.149 1.00 20.00 H +ATOM 473 HG23 THR A 26 -39.503 -60.528 5.747 1.00 20.00 H +ATOM 474 N LEU A 27 -41.594 -58.238 6.885 1.00 47.39 N +ATOM 475 CA LEU A 27 -41.463 -56.870 7.368 1.00 40.92 C +ATOM 476 C LEU A 27 -40.158 -56.726 8.142 1.00 37.40 C +ATOM 477 O LEU A 27 -39.686 -57.679 8.764 1.00 41.54 O +ATOM 478 CB LEU A 27 -42.636 -56.473 8.272 1.00 39.21 C +ATOM 479 CG LEU A 27 -44.049 -56.434 7.687 1.00 44.81 C +ATOM 480 CD1 LEU A 27 -45.073 -56.271 8.798 1.00 46.77 C +ATOM 481 CD2 LEU A 27 -44.159 -55.308 6.677 1.00 42.46 C +ATOM 482 H LEU A 27 -41.232 -58.983 7.445 1.00 20.00 H +ATOM 483 HA LEU A 27 -41.438 -56.181 6.511 1.00 20.00 H +ATOM 484 HB2 LEU A 27 -42.654 -57.188 9.108 1.00 20.00 H +ATOM 485 HB3 LEU A 27 -42.419 -55.465 8.656 1.00 20.00 H +ATOM 486 HG LEU A 27 -44.239 -57.387 7.172 1.00 20.00 H +ATOM 487 HD11 LEU A 27 -46.084 -56.244 8.365 1.00 20.00 H +ATOM 488 HD12 LEU A 27 -44.995 -57.118 9.495 1.00 20.00 H +ATOM 489 HD13 LEU A 27 -44.881 -55.332 9.339 1.00 20.00 H +ATOM 490 HD21 LEU A 27 -45.177 -55.286 6.261 1.00 20.00 H +ATOM 491 HD22 LEU A 27 -43.945 -54.349 7.172 1.00 20.00 H +ATOM 492 HD23 LEU A 27 -43.435 -55.472 5.865 1.00 20.00 H +ATOM 493 N ASN A 28 -39.584 -55.524 8.103 1.00 40.54 N +ATOM 494 CA ASN A 28 -38.448 -55.157 8.943 1.00 43.60 C +ATOM 495 C ASN A 28 -38.974 -54.498 10.212 1.00 42.61 C +ATOM 496 O ASN A 28 -39.796 -53.576 10.139 1.00 48.29 O +ATOM 497 CB ASN A 28 -37.507 -54.205 8.209 1.00 49.34 C +ATOM 498 CG ASN A 28 -36.673 -54.901 7.155 1.00 48.45 C +ATOM 499 OD1 ASN A 28 -36.405 -56.099 7.245 1.00 40.50 O +ATOM 500 ND2 ASN A 28 -36.245 -54.148 6.155 1.00 54.64 N +ATOM 501 H ASN A 28 -39.948 -54.842 7.469 1.00 20.00 H +ATOM 502 HA ASN A 28 -37.888 -56.062 9.221 1.00 20.00 H +ATOM 503 HB2 ASN A 28 -38.108 -53.423 7.722 1.00 20.00 H +ATOM 504 HB3 ASN A 28 -36.831 -53.743 8.944 1.00 20.00 H +ATOM 505 HD21 ASN A 28 -35.680 -54.549 5.434 1.00 20.00 H +ATOM 506 HD22 ASN A 28 -36.486 -53.178 6.121 1.00 20.00 H +ATOM 507 N ILE A 29 -38.502 -54.963 11.369 1.00 35.38 N +ATOM 508 CA ILE A 29 -39.090 -54.608 12.660 1.00 37.71 C +ATOM 509 C ILE A 29 -37.993 -54.120 13.600 1.00 41.61 C +ATOM 510 O ILE A 29 -37.008 -54.831 13.827 1.00 42.29 O +ATOM 511 CB ILE A 29 -39.836 -55.796 13.288 1.00 35.59 C +ATOM 512 CG1 ILE A 29 -40.949 -56.280 12.361 1.00 39.27 C +ATOM 513 CG2 ILE A 29 -40.448 -55.406 14.598 1.00 35.60 C +ATOM 514 CD1 ILE A 29 -42.011 -55.235 12.129 1.00 31.95 C +ATOM 515 H ILE A 29 -37.715 -55.579 11.353 1.00 20.00 H +ATOM 516 HA ILE A 29 -39.810 -53.789 12.515 1.00 20.00 H +ATOM 517 HB ILE A 29 -39.123 -56.618 13.449 1.00 20.00 H +ATOM 518 HG12 ILE A 29 -40.506 -56.552 11.392 1.00 20.00 H +ATOM 519 HG13 ILE A 29 -41.420 -57.167 12.811 1.00 20.00 H +ATOM 520 HG21 ILE A 29 -40.976 -56.270 15.028 1.00 20.00 H +ATOM 521 HG22 ILE A 29 -39.657 -55.078 15.289 1.00 20.00 H +ATOM 522 HG23 ILE A 29 -41.161 -54.583 14.439 1.00 20.00 H +ATOM 523 HD11 ILE A 29 -42.783 -55.639 11.457 1.00 20.00 H +ATOM 524 HD12 ILE A 29 -42.470 -54.959 13.090 1.00 20.00 H +ATOM 525 HD13 ILE A 29 -41.555 -54.345 11.671 1.00 20.00 H +ATOM 526 N LEU A 30 -38.186 -52.933 14.176 1.00 43.02 N +ATOM 527 CA LEU A 30 -37.185 -52.340 15.056 1.00 42.94 C +ATOM 528 C LEU A 30 -37.052 -53.135 16.352 1.00 48.28 C +ATOM 529 O LEU A 30 -38.050 -53.460 17.002 1.00 48.78 O +ATOM 530 CB LEU A 30 -37.563 -50.890 15.359 1.00 46.19 C +ATOM 531 CG LEU A 30 -36.706 -50.099 16.352 1.00 45.64 C +ATOM 532 CD1 LEU A 30 -35.364 -49.732 15.749 1.00 49.06 C +ATOM 533 CD2 LEU A 30 -37.430 -48.851 16.838 1.00 48.19 C +ATOM 534 H LEU A 30 -39.037 -52.438 14.001 1.00 20.00 H +ATOM 535 HA LEU A 30 -36.210 -52.343 14.547 1.00 20.00 H +ATOM 536 HB2 LEU A 30 -37.541 -50.343 14.405 1.00 20.00 H +ATOM 537 HB3 LEU A 30 -38.590 -50.899 15.753 1.00 20.00 H +ATOM 538 HG LEU A 30 -36.521 -50.744 17.224 1.00 20.00 H +ATOM 539 HD11 LEU A 30 -34.773 -49.166 16.485 1.00 20.00 H +ATOM 540 HD12 LEU A 30 -34.823 -50.649 15.472 1.00 20.00 H +ATOM 541 HD13 LEU A 30 -35.522 -49.114 14.852 1.00 20.00 H +ATOM 542 HD21 LEU A 30 -36.789 -48.307 17.548 1.00 20.00 H +ATOM 543 HD22 LEU A 30 -37.659 -48.202 15.980 1.00 20.00 H +ATOM 544 HD23 LEU A 30 -38.366 -49.141 17.338 1.00 20.00 H +ATOM 545 N VAL A 31 -35.812 -53.438 16.728 1.00 47.83 N +ATOM 546 CA VAL A 31 -35.537 -54.157 17.968 1.00 47.41 C +ATOM 547 C VAL A 31 -35.432 -53.140 19.099 1.00 50.62 C +ATOM 548 O VAL A 31 -34.558 -52.267 19.087 1.00 47.10 O +ATOM 549 CB VAL A 31 -34.258 -54.997 17.852 1.00 52.46 C +ATOM 550 CG1 VAL A 31 -33.956 -55.691 19.178 1.00 50.43 C +ATOM 551 CG2 VAL A 31 -34.399 -56.022 16.732 1.00 48.96 C +ATOM 552 H VAL A 31 -35.047 -53.165 16.145 1.00 20.00 H +ATOM 553 HA VAL A 31 -36.375 -54.834 18.188 1.00 20.00 H +ATOM 554 HB VAL A 31 -33.421 -54.326 17.610 1.00 20.00 H +ATOM 555 HG11 VAL A 31 -33.038 -56.288 19.079 1.00 20.00 H +ATOM 556 HG12 VAL A 31 -33.818 -54.935 19.965 1.00 20.00 H +ATOM 557 HG13 VAL A 31 -34.795 -56.350 19.446 1.00 20.00 H +ATOM 558 HG21 VAL A 31 -33.476 -56.617 16.660 1.00 20.00 H +ATOM 559 HG22 VAL A 31 -35.248 -56.687 16.949 1.00 20.00 H +ATOM 560 HG23 VAL A 31 -34.575 -55.502 15.779 1.00 20.00 H +ATOM 561 N ASP A 32 -36.312 -53.265 20.090 1.00 41.43 N +ATOM 562 CA ASP A 32 -36.560 -52.177 21.033 1.00 43.78 C +ATOM 563 C ASP A 32 -36.770 -52.745 22.434 1.00 41.56 C +ATOM 564 O ASP A 32 -37.857 -53.236 22.752 1.00 41.48 O +ATOM 565 CB ASP A 32 -37.766 -51.366 20.576 1.00 41.62 C +ATOM 566 CG ASP A 32 -38.013 -50.148 21.437 1.00 43.73 C +ATOM 567 OD1 ASP A 32 -39.138 -49.600 21.385 1.00 39.77 O +ATOM 568 OD2 ASP A 32 -37.086 -49.736 22.161 1.00 42.88 O +ATOM 569 H ASP A 32 -36.815 -54.123 20.191 1.00 20.00 H +ATOM 570 HA ASP A 32 -35.684 -51.512 21.057 1.00 20.00 H +ATOM 571 HB2 ASP A 32 -37.596 -51.036 19.541 1.00 20.00 H +ATOM 572 HB3 ASP A 32 -38.657 -52.010 20.614 1.00 20.00 H +ATOM 573 N THR A 33 -35.738 -52.652 23.276 1.00 40.38 N +ATOM 574 CA THR A 33 -35.851 -53.101 24.657 1.00 37.44 C +ATOM 575 C THR A 33 -36.516 -52.076 25.560 1.00 35.86 C +ATOM 576 O THR A 33 -36.688 -52.348 26.752 1.00 42.13 O +ATOM 577 CB THR A 33 -34.475 -53.449 25.226 1.00 41.31 C +ATOM 578 OG1 THR A 33 -33.651 -52.278 25.256 1.00 43.03 O +ATOM 579 CG2 THR A 33 -33.808 -54.521 24.379 1.00 45.17 C +ATOM 580 H THR A 33 -34.873 -52.268 22.953 1.00 20.00 H +ATOM 581 HA THR A 33 -36.462 -54.015 24.679 1.00 20.00 H +ATOM 582 HB THR A 33 -34.607 -53.839 26.246 1.00 20.00 H +ATOM 583 HG1 THR A 33 -33.506 -52.015 26.157 1.00 20.00 H +ATOM 584 HG21 THR A 33 -32.820 -54.760 24.800 1.00 20.00 H +ATOM 585 HG22 THR A 33 -34.433 -55.426 24.374 1.00 20.00 H +ATOM 586 HG23 THR A 33 -33.688 -54.153 23.350 1.00 20.00 H +ATOM 587 N GLY A 34 -36.896 -50.918 25.030 1.00 39.53 N +ATOM 588 CA GLY A 34 -37.516 -49.891 25.841 1.00 39.42 C +ATOM 589 C GLY A 34 -39.019 -49.783 25.682 1.00 43.53 C +ATOM 590 O GLY A 34 -39.620 -48.792 26.103 1.00 42.99 O +ATOM 591 H GLY A 34 -36.751 -50.753 24.054 1.00 20.00 H +ATOM 592 HA2 GLY A 34 -37.298 -50.109 26.897 1.00 20.00 H +ATOM 593 HA3 GLY A 34 -37.072 -48.923 25.567 1.00 20.00 H +ATOM 594 N SER A 35 -39.641 -50.788 25.073 1.00 49.58 N +ATOM 595 CA SER A 35 -41.090 -50.805 24.924 1.00 47.91 C +ATOM 596 C SER A 35 -41.556 -52.250 24.924 1.00 45.10 C +ATOM 597 O SER A 35 -40.748 -53.177 24.971 1.00 38.15 O +ATOM 598 CB SER A 35 -41.531 -50.074 23.652 1.00 46.02 C +ATOM 599 OG SER A 35 -41.161 -50.794 22.490 1.00 45.29 O +ATOM 600 H SER A 35 -39.103 -51.548 24.709 1.00 20.00 H +ATOM 601 HA SER A 35 -41.546 -50.296 25.786 1.00 20.00 H +ATOM 602 HB2 SER A 35 -42.625 -49.956 23.667 1.00 20.00 H +ATOM 603 HB3 SER A 35 -41.056 -49.082 23.626 1.00 20.00 H +ATOM 604 HG SER A 35 -40.467 -50.330 22.037 1.00 20.00 H +ATOM 605 N SER A 36 -42.878 -52.440 24.848 1.00 44.22 N +ATOM 606 CA SER A 36 -43.429 -53.774 25.049 1.00 44.43 C +ATOM 607 C SER A 36 -44.540 -54.156 24.076 1.00 39.36 C +ATOM 608 O SER A 36 -45.210 -55.169 24.302 1.00 39.95 O +ATOM 609 CB SER A 36 -43.953 -53.905 26.478 1.00 53.70 C +ATOM 610 OG SER A 36 -42.914 -53.684 27.413 1.00 64.91 O +ATOM 611 H SER A 36 -43.486 -51.670 24.654 1.00 20.00 H +ATOM 612 HA SER A 36 -42.617 -54.506 24.927 1.00 20.00 H +ATOM 613 HB2 SER A 36 -44.749 -53.163 26.640 1.00 20.00 H +ATOM 614 HB3 SER A 36 -44.360 -54.917 26.622 1.00 20.00 H +ATOM 615 HG SER A 36 -43.159 -54.054 28.253 1.00 20.00 H +ATOM 616 N ASN A 37 -44.768 -53.393 23.016 1.00 43.70 N +ATOM 617 CA ASN A 37 -45.759 -53.752 22.014 1.00 53.01 C +ATOM 618 C ASN A 37 -45.085 -54.243 20.741 1.00 52.18 C +ATOM 619 O ASN A 37 -44.004 -53.779 20.369 1.00 47.18 O +ATOM 620 CB ASN A 37 -46.676 -52.569 21.683 1.00 51.12 C +ATOM 621 CG ASN A 37 -47.680 -52.281 22.787 1.00 53.13 C +ATOM 622 OD1 ASN A 37 -47.477 -51.391 23.610 1.00 46.34 O +ATOM 623 ND2 ASN A 37 -48.777 -53.034 22.803 1.00 55.04 N +ATOM 624 H ASN A 37 -44.245 -52.548 22.903 1.00 20.00 H +ATOM 625 HA ASN A 37 -46.385 -54.567 22.406 1.00 20.00 H +ATOM 626 HB2 ASN A 37 -46.055 -51.674 21.529 1.00 20.00 H +ATOM 627 HB3 ASN A 37 -47.225 -52.797 20.758 1.00 20.00 H +ATOM 628 HD21 ASN A 37 -49.475 -52.886 23.503 1.00 20.00 H +ATOM 629 HD22 ASN A 37 -48.903 -53.748 22.115 1.00 20.00 H +ATOM 630 N PHE A 38 -45.727 -55.212 20.093 1.00 44.94 N +ATOM 631 CA PHE A 38 -45.399 -55.597 18.724 1.00 39.68 C +ATOM 632 C PHE A 38 -46.354 -54.805 17.842 1.00 45.82 C +ATOM 633 O PHE A 38 -47.532 -55.145 17.716 1.00 46.07 O +ATOM 634 CB PHE A 38 -45.529 -57.102 18.511 1.00 36.37 C +ATOM 635 CG PHE A 38 -45.125 -57.568 17.133 1.00 40.65 C +ATOM 636 CD1 PHE A 38 -44.059 -56.984 16.464 1.00 43.60 C +ATOM 637 CD2 PHE A 38 -45.799 -58.615 16.522 1.00 45.44 C +ATOM 638 CE1 PHE A 38 -43.687 -57.422 15.202 1.00 41.27 C +ATOM 639 CE2 PHE A 38 -45.429 -59.057 15.263 1.00 44.06 C +ATOM 640 CZ PHE A 38 -44.375 -58.461 14.603 1.00 45.20 C +ATOM 641 H PHE A 38 -46.465 -55.696 20.563 1.00 20.00 H +ATOM 642 HA PHE A 38 -44.367 -55.294 18.491 1.00 20.00 H +ATOM 643 HB2 PHE A 38 -44.891 -57.611 19.248 1.00 20.00 H +ATOM 644 HB3 PHE A 38 -46.579 -57.385 18.677 1.00 20.00 H +ATOM 645 HD1 PHE A 38 -43.512 -56.179 16.932 1.00 20.00 H +ATOM 646 HD2 PHE A 38 -46.622 -59.091 17.034 1.00 20.00 H +ATOM 647 HE1 PHE A 38 -42.861 -56.952 14.688 1.00 20.00 H +ATOM 648 HE2 PHE A 38 -45.967 -59.870 14.797 1.00 20.00 H +ATOM 649 HZ PHE A 38 -44.088 -58.805 13.620 1.00 20.00 H +ATOM 650 N ALA A 39 -45.856 -53.714 17.276 1.00 49.04 N +ATOM 651 CA ALA A 39 -46.662 -52.804 16.478 1.00 46.44 C +ATOM 652 C ALA A 39 -46.094 -52.758 15.070 1.00 45.99 C +ATOM 653 O ALA A 39 -44.885 -52.577 14.892 1.00 40.11 O +ATOM 654 CB ALA A 39 -46.692 -51.404 17.094 1.00 48.93 C +ATOM 655 H ALA A 39 -44.886 -53.508 17.403 1.00 20.00 H +ATOM 656 HA ALA A 39 -47.694 -53.181 16.426 1.00 20.00 H +ATOM 657 HB1 ALA A 39 -47.308 -50.741 16.469 1.00 20.00 H +ATOM 658 HB2 ALA A 39 -47.121 -51.458 18.105 1.00 20.00 H +ATOM 659 HB3 ALA A 39 -45.668 -51.007 17.151 1.00 20.00 H +ATOM 660 N VAL A 40 -46.960 -52.945 14.078 1.00 41.76 N +ATOM 661 CA VAL A 40 -46.550 -53.001 12.682 1.00 42.25 C +ATOM 662 C VAL A 40 -47.444 -52.074 11.870 1.00 48.15 C +ATOM 663 O VAL A 40 -48.653 -51.990 12.120 1.00 44.86 O +ATOM 664 CB VAL A 40 -46.601 -54.442 12.127 1.00 39.27 C +ATOM 665 CG1 VAL A 40 -45.778 -55.385 12.996 1.00 38.07 C +ATOM 666 CG2 VAL A 40 -48.034 -54.945 12.011 1.00 43.77 C +ATOM 667 H VAL A 40 -47.929 -53.051 14.299 1.00 20.00 H +ATOM 668 HA VAL A 40 -45.514 -52.641 12.597 1.00 20.00 H +ATOM 669 HB VAL A 40 -46.159 -54.432 11.120 1.00 20.00 H +ATOM 670 HG11 VAL A 40 -45.829 -56.403 12.583 1.00 20.00 H +ATOM 671 HG12 VAL A 40 -44.731 -55.048 13.013 1.00 20.00 H +ATOM 672 HG13 VAL A 40 -46.180 -55.384 14.020 1.00 20.00 H +ATOM 673 HG21 VAL A 40 -48.032 -55.971 11.614 1.00 20.00 H +ATOM 674 HG22 VAL A 40 -48.507 -54.937 13.004 1.00 20.00 H +ATOM 675 HG23 VAL A 40 -48.599 -54.290 11.331 1.00 20.00 H +ATOM 676 N GLY A 41 -46.847 -51.367 10.912 1.00 48.56 N +ATOM 677 CA GLY A 41 -47.617 -50.570 9.981 1.00 48.14 C +ATOM 678 C GLY A 41 -48.602 -51.445 9.234 1.00 44.20 C +ATOM 679 O GLY A 41 -48.236 -52.518 8.743 1.00 42.66 O +ATOM 680 H GLY A 41 -45.850 -51.387 10.835 1.00 20.00 H +ATOM 681 HA2 GLY A 41 -48.167 -49.795 10.535 1.00 20.00 H +ATOM 682 HA3 GLY A 41 -46.936 -50.093 9.261 1.00 20.00 H +ATOM 683 N ALA A 42 -49.864 -51.015 9.158 1.00 46.37 N +ATOM 684 CA ALA A 42 -50.880 -51.849 8.528 1.00 43.25 C +ATOM 685 C ALA A 42 -51.815 -51.032 7.643 1.00 47.30 C +ATOM 686 O ALA A 42 -52.943 -51.464 7.373 1.00 47.38 O +ATOM 687 CB ALA A 42 -51.676 -52.618 9.581 1.00 41.40 C +ATOM 688 H ALA A 42 -50.112 -50.122 9.533 1.00 20.00 H +ATOM 689 HA ALA A 42 -50.376 -52.588 7.887 1.00 20.00 H +ATOM 690 HB1 ALA A 42 -52.436 -53.240 9.085 1.00 20.00 H +ATOM 691 HB2 ALA A 42 -50.995 -53.261 10.158 1.00 20.00 H +ATOM 692 HB3 ALA A 42 -52.170 -51.906 10.259 1.00 20.00 H +ATOM 693 N ALA A 43 -51.371 -49.864 7.203 1.00 49.99 N +ATOM 694 CA ALA A 43 -52.081 -49.028 6.247 1.00 51.17 C +ATOM 695 C ALA A 43 -51.038 -48.187 5.528 1.00 53.39 C +ATOM 696 O ALA A 43 -49.929 -48.009 6.037 1.00 54.15 O +ATOM 697 CB ALA A 43 -53.119 -48.139 6.941 1.00 52.02 C +ATOM 698 H ALA A 43 -50.492 -49.536 7.550 1.00 20.00 H +ATOM 699 HA ALA A 43 -52.596 -49.662 5.510 1.00 20.00 H +ATOM 700 HB1 ALA A 43 -53.635 -47.522 6.190 1.00 20.00 H +ATOM 701 HB2 ALA A 43 -53.852 -48.771 7.463 1.00 20.00 H +ATOM 702 HB3 ALA A 43 -52.614 -47.486 7.668 1.00 20.00 H +ATOM 703 N PRO A 44 -51.350 -47.690 4.330 1.00 52.34 N +ATOM 704 CA PRO A 44 -50.343 -46.928 3.580 1.00 51.35 C +ATOM 705 C PRO A 44 -49.851 -45.709 4.347 1.00 51.77 C +ATOM 706 O PRO A 44 -50.550 -45.146 5.192 1.00 50.75 O +ATOM 707 CB PRO A 44 -51.086 -46.526 2.301 1.00 50.36 C +ATOM 708 CG PRO A 44 -52.127 -47.584 2.133 1.00 49.06 C +ATOM 709 CD PRO A 44 -52.553 -47.953 3.524 1.00 52.37 C +ATOM 710 HA PRO A 44 -49.489 -47.572 3.322 1.00 20.00 H +ATOM 711 HB2 PRO A 44 -51.551 -45.536 2.415 1.00 20.00 H +ATOM 712 HB3 PRO A 44 -50.401 -46.512 1.440 1.00 20.00 H +ATOM 713 HG2 PRO A 44 -52.981 -47.195 1.560 1.00 20.00 H +ATOM 714 HG3 PRO A 44 -51.706 -48.458 1.615 1.00 20.00 H +ATOM 715 HD2 PRO A 44 -53.394 -47.327 3.857 1.00 20.00 H +ATOM 716 HD3 PRO A 44 -52.840 -49.014 3.579 1.00 20.00 H +ATOM 717 N HIS A 45 -48.611 -45.316 4.042 1.00 54.81 N +ATOM 718 CA HIS A 45 -47.939 -44.185 4.662 1.00 52.12 C +ATOM 719 C HIS A 45 -46.787 -43.824 3.742 1.00 53.83 C +ATOM 720 O HIS A 45 -46.141 -44.734 3.205 1.00 57.40 O +ATOM 721 CB HIS A 45 -47.423 -44.522 6.068 1.00 51.35 C +ATOM 722 CG HIS A 45 -46.993 -43.327 6.863 1.00 55.62 C +ATOM 723 ND1 HIS A 45 -45.739 -42.765 6.747 1.00 56.03 N +ATOM 724 CD2 HIS A 45 -47.648 -42.594 7.794 1.00 55.97 C +ATOM 725 CE1 HIS A 45 -45.644 -41.734 7.568 1.00 56.26 C +ATOM 726 NE2 HIS A 45 -46.788 -41.610 8.216 1.00 56.64 N +ATOM 727 H HIS A 45 -48.114 -45.832 3.344 1.00 20.00 H +ATOM 728 HA HIS A 45 -48.627 -43.330 4.730 1.00 20.00 H +ATOM 729 HB2 HIS A 45 -48.227 -45.032 6.618 1.00 20.00 H +ATOM 730 HB3 HIS A 45 -46.561 -45.198 5.967 1.00 20.00 H +ATOM 731 HD2 HIS A 45 -48.659 -42.753 8.140 1.00 20.00 H +ATOM 732 HE1 HIS A 45 -44.778 -41.100 7.689 1.00 20.00 H +ATOM 733 HE2 HIS A 45 -46.994 -40.913 8.903 1.00 20.00 H +ATOM 734 N PRO A 46 -46.511 -42.538 3.525 1.00 56.03 N +ATOM 735 CA PRO A 46 -45.452 -42.169 2.567 1.00 55.60 C +ATOM 736 C PRO A 46 -44.086 -42.747 2.896 1.00 51.95 C +ATOM 737 O PRO A 46 -43.277 -42.944 1.981 1.00 54.91 O +ATOM 738 CB PRO A 46 -45.444 -40.633 2.627 1.00 58.61 C +ATOM 739 CG PRO A 46 -46.203 -40.272 3.877 1.00 58.30 C +ATOM 740 CD PRO A 46 -47.204 -41.361 4.069 1.00 55.22 C +ATOM 741 HA PRO A 46 -45.742 -42.484 1.554 1.00 20.00 H +ATOM 742 HB2 PRO A 46 -44.412 -40.256 2.682 1.00 20.00 H +ATOM 743 HB3 PRO A 46 -45.941 -40.212 1.741 1.00 20.00 H +ATOM 744 HG2 PRO A 46 -45.521 -40.221 4.739 1.00 20.00 H +ATOM 745 HG3 PRO A 46 -46.709 -39.303 3.752 1.00 20.00 H +ATOM 746 HD2 PRO A 46 -47.442 -41.498 5.134 1.00 20.00 H +ATOM 747 HD3 PRO A 46 -48.129 -41.152 3.511 1.00 20.00 H +ATOM 748 N PHE A 47 -43.800 -43.035 4.162 1.00 48.71 N +ATOM 749 CA PHE A 47 -42.495 -43.574 4.525 1.00 56.18 C +ATOM 750 C PHE A 47 -42.455 -45.097 4.542 1.00 56.99 C +ATOM 751 O PHE A 47 -41.368 -45.670 4.682 1.00 56.30 O +ATOM 752 CB PHE A 47 -42.061 -43.046 5.894 1.00 54.65 C +ATOM 753 CG PHE A 47 -42.007 -41.546 5.983 1.00 53.81 C +ATOM 754 CD1 PHE A 47 -41.821 -40.763 4.851 1.00 49.17 C +ATOM 755 CD2 PHE A 47 -42.145 -40.918 7.209 1.00 57.50 C +ATOM 756 CE1 PHE A 47 -41.776 -39.382 4.945 1.00 48.24 C +ATOM 757 CE2 PHE A 47 -42.100 -39.539 7.307 1.00 57.74 C +ATOM 758 CZ PHE A 47 -41.914 -38.772 6.177 1.00 53.95 C +ATOM 759 H PHE A 47 -44.487 -42.880 4.872 1.00 20.00 H +ATOM 760 HA PHE A 47 -41.757 -43.229 3.786 1.00 20.00 H +ATOM 761 HB2 PHE A 47 -42.774 -43.412 6.648 1.00 20.00 H +ATOM 762 HB3 PHE A 47 -41.059 -43.442 6.115 1.00 20.00 H +ATOM 763 HD1 PHE A 47 -41.710 -41.236 3.887 1.00 20.00 H +ATOM 764 HD2 PHE A 47 -42.290 -41.512 8.099 1.00 20.00 H +ATOM 765 HE1 PHE A 47 -41.633 -38.783 4.057 1.00 20.00 H +ATOM 766 HE2 PHE A 47 -42.211 -39.063 8.270 1.00 20.00 H +ATOM 767 HZ PHE A 47 -41.876 -37.695 6.254 1.00 20.00 H +ATOM 768 N LEU A 48 -43.601 -45.762 4.410 1.00 50.30 N +ATOM 769 CA LEU A 48 -43.674 -47.219 4.401 1.00 50.90 C +ATOM 770 C LEU A 48 -43.800 -47.707 2.963 1.00 56.48 C +ATOM 771 O LEU A 48 -44.709 -47.286 2.239 1.00 60.84 O +ATOM 772 CB LEU A 48 -44.863 -47.721 5.221 1.00 47.26 C +ATOM 773 CG LEU A 48 -44.996 -47.413 6.711 1.00 51.19 C +ATOM 774 CD1 LEU A 48 -46.285 -48.024 7.241 1.00 50.94 C +ATOM 775 CD2 LEU A 48 -43.799 -47.933 7.490 1.00 49.26 C +ATOM 776 H LEU A 48 -44.448 -45.240 4.313 1.00 20.00 H +ATOM 777 HA LEU A 48 -42.751 -47.634 4.833 1.00 20.00 H +ATOM 778 HB2 LEU A 48 -45.765 -47.315 4.739 1.00 20.00 H +ATOM 779 HB3 LEU A 48 -44.861 -48.817 5.130 1.00 20.00 H +ATOM 780 HG LEU A 48 -45.049 -46.322 6.838 1.00 20.00 H +ATOM 781 HD11 LEU A 48 -46.382 -47.803 8.314 1.00 20.00 H +ATOM 782 HD12 LEU A 48 -47.142 -47.597 6.700 1.00 20.00 H +ATOM 783 HD13 LEU A 48 -46.263 -49.114 7.092 1.00 20.00 H +ATOM 784 HD21 LEU A 48 -43.924 -47.696 8.557 1.00 20.00 H +ATOM 785 HD22 LEU A 48 -43.724 -49.023 7.363 1.00 20.00 H +ATOM 786 HD23 LEU A 48 -42.882 -47.456 7.114 1.00 20.00 H +ATOM 787 N HIS A 49 -42.899 -48.600 2.553 1.00 50.95 N +ATOM 788 CA HIS A 49 -42.996 -49.219 1.238 1.00 55.68 C +ATOM 789 C HIS A 49 -43.656 -50.592 1.276 1.00 56.10 C +ATOM 790 O HIS A 49 -43.866 -51.193 0.216 1.00 55.15 O +ATOM 791 CB HIS A 49 -41.610 -49.316 0.594 1.00 63.36 C +ATOM 792 CG HIS A 49 -41.079 -47.998 0.121 1.00 65.93 C +ATOM 793 ND1 HIS A 49 -39.844 -47.514 0.495 1.00 66.16 N +ATOM 794 CD2 HIS A 49 -41.620 -47.060 -0.693 1.00 65.98 C +ATOM 795 CE1 HIS A 49 -39.647 -46.335 -0.068 1.00 65.95 C +ATOM 796 NE2 HIS A 49 -40.709 -46.037 -0.794 1.00 67.72 N +ATOM 797 H HIS A 49 -42.143 -48.849 3.159 1.00 20.00 H +ATOM 798 HA HIS A 49 -43.613 -48.573 0.596 1.00 20.00 H +ATOM 799 HB2 HIS A 49 -40.910 -49.728 1.335 1.00 20.00 H +ATOM 800 HB3 HIS A 49 -41.673 -49.996 -0.268 1.00 20.00 H +ATOM 801 HD1 HIS A 49 -39.198 -47.982 1.098 1.00 20.00 H +ATOM 802 HD2 HIS A 49 -42.586 -47.108 -1.173 1.00 20.00 H +ATOM 803 HE1 HIS A 49 -38.767 -45.720 0.046 1.00 20.00 H +ATOM 804 N ARG A 50 -43.984 -51.092 2.465 1.00 55.45 N +ATOM 805 CA ARG A 50 -44.830 -52.264 2.624 1.00 51.05 C +ATOM 806 C ARG A 50 -45.474 -52.190 3.999 1.00 45.98 C +ATOM 807 O ARG A 50 -45.005 -51.470 4.884 1.00 46.89 O +ATOM 808 CB ARG A 50 -44.042 -53.569 2.442 1.00 50.97 C +ATOM 809 CG ARG A 50 -42.815 -53.690 3.326 1.00 49.37 C +ATOM 810 CD ARG A 50 -41.992 -54.919 2.967 1.00 49.29 C +ATOM 811 NE ARG A 50 -40.767 -54.999 3.759 1.00 51.05 N +ATOM 812 CZ ARG A 50 -39.822 -55.920 3.590 1.00 50.98 C +ATOM 813 NH1 ARG A 50 -39.958 -56.848 2.651 1.00 46.60 N +ATOM 814 NH2 ARG A 50 -38.740 -55.911 4.359 1.00 50.20 N +ATOM 815 H ARG A 50 -43.633 -50.641 3.286 1.00 20.00 H +ATOM 816 HA ARG A 50 -45.628 -52.238 1.867 1.00 20.00 H +ATOM 817 HB2 ARG A 50 -44.713 -54.410 2.669 1.00 20.00 H +ATOM 818 HB3 ARG A 50 -43.717 -53.631 1.393 1.00 20.00 H +ATOM 819 HG2 ARG A 50 -42.192 -52.792 3.199 1.00 20.00 H +ATOM 820 HG3 ARG A 50 -43.136 -53.768 4.375 1.00 20.00 H +ATOM 821 HD2 ARG A 50 -42.596 -55.819 3.153 1.00 20.00 H +ATOM 822 HD3 ARG A 50 -41.725 -54.870 1.901 1.00 20.00 H +ATOM 823 HE ARG A 50 -40.630 -54.316 4.476 1.00 20.00 H +ATOM 824 HH11 ARG A 50 -39.246 -57.539 2.524 1.00 20.00 H +ATOM 825 HH12 ARG A 50 -40.772 -56.856 2.071 1.00 20.00 H +ATOM 826 HH21 ARG A 50 -38.029 -56.603 4.230 1.00 20.00 H +ATOM 827 HH22 ARG A 50 -38.636 -55.213 5.067 1.00 20.00 H +ATOM 828 N TYR A 51 -46.567 -52.928 4.168 1.00 43.33 N +ATOM 829 CA TYR A 51 -47.274 -52.913 5.441 1.00 44.71 C +ATOM 830 C TYR A 51 -48.071 -54.200 5.600 1.00 44.00 C +ATOM 831 O TYR A 51 -48.228 -54.981 4.658 1.00 44.98 O +ATOM 832 CB TYR A 51 -48.178 -51.677 5.572 1.00 50.00 C +ATOM 833 CG TYR A 51 -49.232 -51.535 4.496 1.00 50.47 C +ATOM 834 CD1 TYR A 51 -50.497 -52.079 4.663 1.00 53.72 C +ATOM 835 CD2 TYR A 51 -48.970 -50.841 3.322 1.00 50.88 C +ATOM 836 CE1 TYR A 51 -51.467 -51.949 3.688 1.00 52.55 C +ATOM 837 CE2 TYR A 51 -49.938 -50.704 2.339 1.00 52.11 C +ATOM 838 CZ TYR A 51 -51.184 -51.262 2.529 1.00 55.97 C +ATOM 839 OH TYR A 51 -52.151 -51.131 1.557 1.00 63.72 O +ATOM 840 H TYR A 51 -46.905 -53.496 3.418 1.00 20.00 H +ATOM 841 HA TYR A 51 -46.534 -52.873 6.254 1.00 20.00 H +ATOM 842 HB2 TYR A 51 -48.689 -51.730 6.545 1.00 20.00 H +ATOM 843 HB3 TYR A 51 -47.538 -50.783 5.543 1.00 20.00 H +ATOM 844 HD1 TYR A 51 -50.728 -52.614 5.572 1.00 20.00 H +ATOM 845 HD2 TYR A 51 -47.995 -50.400 3.172 1.00 20.00 H +ATOM 846 HE1 TYR A 51 -52.444 -52.385 3.835 1.00 20.00 H +ATOM 847 HE2 TYR A 51 -49.717 -50.164 1.430 1.00 20.00 H +ATOM 848 HH TYR A 51 -51.738 -51.085 0.703 1.00 20.00 H +ATOM 849 N TYR A 52 -48.563 -54.406 6.818 1.00 41.58 N +ATOM 850 CA TYR A 52 -49.293 -55.615 7.177 1.00 40.77 C +ATOM 851 C TYR A 52 -50.707 -55.545 6.615 1.00 44.10 C +ATOM 852 O TYR A 52 -51.491 -54.666 6.992 1.00 44.30 O +ATOM 853 CB TYR A 52 -49.305 -55.752 8.698 1.00 40.87 C +ATOM 854 CG TYR A 52 -50.098 -56.899 9.291 1.00 38.16 C +ATOM 855 CD1 TYR A 52 -50.202 -58.122 8.648 1.00 38.35 C +ATOM 856 CD2 TYR A 52 -50.723 -56.754 10.522 1.00 40.71 C +ATOM 857 CE1 TYR A 52 -50.920 -59.167 9.214 1.00 43.05 C +ATOM 858 CE2 TYR A 52 -51.437 -57.787 11.091 1.00 41.57 C +ATOM 859 CZ TYR A 52 -51.537 -58.991 10.434 1.00 43.42 C +ATOM 860 OH TYR A 52 -52.253 -60.017 11.004 1.00 48.10 O +ATOM 861 H TYR A 52 -48.426 -53.703 7.516 1.00 20.00 H +ATOM 862 HA TYR A 52 -48.786 -56.492 6.749 1.00 20.00 H +ATOM 863 HB2 TYR A 52 -48.262 -55.868 9.027 1.00 20.00 H +ATOM 864 HB3 TYR A 52 -49.717 -54.819 9.110 1.00 20.00 H +ATOM 865 HD1 TYR A 52 -49.718 -58.264 7.693 1.00 20.00 H +ATOM 866 HD2 TYR A 52 -50.648 -55.812 11.045 1.00 20.00 H +ATOM 867 HE1 TYR A 52 -50.995 -60.114 8.700 1.00 20.00 H +ATOM 868 HE2 TYR A 52 -51.916 -57.651 12.049 1.00 20.00 H +ATOM 869 HH TYR A 52 -52.229 -60.776 10.433 1.00 20.00 H +ATOM 870 N GLN A 53 -51.035 -56.458 5.709 1.00 44.13 N +ATOM 871 CA GLN A 53 -52.357 -56.496 5.083 1.00 44.18 C +ATOM 872 C GLN A 53 -53.148 -57.634 5.718 1.00 44.00 C +ATOM 873 O GLN A 53 -52.996 -58.799 5.342 1.00 44.25 O +ATOM 874 CB GLN A 53 -52.241 -56.661 3.573 1.00 45.25 C +ATOM 875 CG GLN A 53 -51.624 -55.467 2.860 1.00 47.48 C +ATOM 876 CD GLN A 53 -51.635 -55.635 1.357 1.00 54.28 C +ATOM 877 OE1 GLN A 53 -52.494 -55.089 0.666 1.00 63.76 O +ATOM 878 NE2 GLN A 53 -50.686 -56.405 0.842 1.00 54.67 N +ATOM 879 H GLN A 53 -50.356 -57.143 5.445 1.00 20.00 H +ATOM 880 HA GLN A 53 -52.882 -55.551 5.290 1.00 20.00 H +ATOM 881 HB2 GLN A 53 -51.618 -57.544 3.369 1.00 20.00 H +ATOM 882 HB3 GLN A 53 -53.250 -56.823 3.165 1.00 20.00 H +ATOM 883 HG2 GLN A 53 -52.196 -54.564 3.120 1.00 20.00 H +ATOM 884 HG3 GLN A 53 -50.583 -55.352 3.197 1.00 20.00 H +ATOM 885 HE21 GLN A 53 -50.649 -56.561 -0.145 1.00 20.00 H +ATOM 886 HE22 GLN A 53 -50.007 -56.830 1.441 1.00 20.00 H +ATOM 887 N ARG A 54 -53.997 -57.289 6.688 1.00 44.18 N +ATOM 888 CA ARG A 54 -54.701 -58.310 7.455 1.00 43.28 C +ATOM 889 C ARG A 54 -55.684 -59.096 6.600 1.00 43.22 C +ATOM 890 O ARG A 54 -55.939 -60.272 6.879 1.00 40.41 O +ATOM 891 CB ARG A 54 -55.422 -57.665 8.635 1.00 46.36 C +ATOM 892 CG ARG A 54 -54.485 -57.095 9.685 1.00 51.02 C +ATOM 893 CD ARG A 54 -55.194 -56.096 10.582 1.00 46.57 C +ATOM 894 NE ARG A 54 -55.442 -54.828 9.903 1.00 47.95 N +ATOM 895 CZ ARG A 54 -56.206 -53.856 10.391 1.00 49.01 C +ATOM 896 NH1 ARG A 54 -56.805 -54.006 11.564 1.00 44.30 N +ATOM 897 NH2 ARG A 54 -56.376 -52.735 9.703 1.00 48.89 N +ATOM 898 H ARG A 54 -54.152 -56.322 6.891 1.00 20.00 H +ATOM 899 HA ARG A 54 -53.963 -59.019 7.858 1.00 20.00 H +ATOM 900 HB2 ARG A 54 -56.053 -56.849 8.253 1.00 20.00 H +ATOM 901 HB3 ARG A 54 -56.057 -58.426 9.112 1.00 20.00 H +ATOM 902 HG2 ARG A 54 -54.098 -57.918 10.303 1.00 20.00 H +ATOM 903 HG3 ARG A 54 -53.648 -56.591 9.181 1.00 20.00 H +ATOM 904 HD2 ARG A 54 -56.157 -56.524 10.898 1.00 20.00 H +ATOM 905 HD3 ARG A 54 -54.569 -55.908 11.467 1.00 20.00 H +ATOM 906 HE ARG A 54 -55.009 -54.681 9.014 1.00 20.00 H +ATOM 907 HH11 ARG A 54 -57.383 -53.275 11.927 1.00 20.00 H +ATOM 908 HH12 ARG A 54 -56.679 -54.850 12.085 1.00 20.00 H +ATOM 909 HH21 ARG A 54 -56.954 -52.006 10.069 1.00 20.00 H +ATOM 910 HH22 ARG A 54 -55.926 -52.618 8.818 1.00 20.00 H +ATOM 911 N GLN A 55 -56.234 -58.483 5.551 1.00 41.42 N +ATOM 912 CA GLN A 55 -57.235 -59.185 4.757 1.00 47.46 C +ATOM 913 C GLN A 55 -56.630 -60.294 3.904 1.00 49.21 C +ATOM 914 O GLN A 55 -57.374 -61.137 3.393 1.00 42.64 O +ATOM 915 CB GLN A 55 -58.001 -58.201 3.869 1.00 47.87 C +ATOM 916 CG GLN A 55 -57.247 -57.750 2.633 1.00 52.01 C +ATOM 917 CD GLN A 55 -56.247 -56.649 2.918 1.00 55.22 C +ATOM 918 OE1 GLN A 55 -55.920 -56.365 4.073 1.00 55.85 O +ATOM 919 NE2 GLN A 55 -55.755 -56.019 1.861 1.00 52.26 N +ATOM 920 H GLN A 55 -55.962 -57.551 5.311 1.00 20.00 H +ATOM 921 HA GLN A 55 -57.960 -59.649 5.441 1.00 20.00 H +ATOM 922 HB2 GLN A 55 -58.934 -58.686 3.545 1.00 20.00 H +ATOM 923 HB3 GLN A 55 -58.240 -57.311 4.469 1.00 20.00 H +ATOM 924 HG2 GLN A 55 -56.708 -58.614 2.217 1.00 20.00 H +ATOM 925 HG3 GLN A 55 -57.974 -57.381 1.895 1.00 20.00 H +ATOM 926 HE21 GLN A 55 -55.091 -55.281 1.983 1.00 20.00 H +ATOM 927 HE22 GLN A 55 -56.048 -56.281 0.942 1.00 20.00 H +ATOM 928 N LEU A 56 -55.310 -60.316 3.740 1.00 47.97 N +ATOM 929 CA LEU A 56 -54.642 -61.370 2.988 1.00 47.08 C +ATOM 930 C LEU A 56 -54.132 -62.503 3.868 1.00 50.69 C +ATOM 931 O LEU A 56 -53.494 -63.426 3.353 1.00 52.73 O +ATOM 932 CB LEU A 56 -53.468 -60.799 2.185 1.00 45.72 C +ATOM 933 CG LEU A 56 -53.724 -59.713 1.141 1.00 47.51 C +ATOM 934 CD1 LEU A 56 -52.466 -59.480 0.317 1.00 49.76 C +ATOM 935 CD2 LEU A 56 -54.896 -60.084 0.248 1.00 51.97 C +ATOM 936 H LEU A 56 -54.759 -59.586 4.146 1.00 20.00 H +ATOM 937 HA LEU A 56 -55.359 -61.798 2.272 1.00 20.00 H +ATOM 938 HB2 LEU A 56 -52.757 -60.381 2.913 1.00 20.00 H +ATOM 939 HB3 LEU A 56 -53.000 -61.644 1.659 1.00 20.00 H +ATOM 940 HG LEU A 56 -53.971 -58.779 1.668 1.00 20.00 H +ATOM 941 HD11 LEU A 56 -52.657 -58.697 -0.432 1.00 20.00 H +ATOM 942 HD12 LEU A 56 -51.648 -59.161 0.979 1.00 20.00 H +ATOM 943 HD13 LEU A 56 -52.183 -60.413 -0.192 1.00 20.00 H +ATOM 944 HD21 LEU A 56 -55.059 -59.288 -0.493 1.00 20.00 H +ATOM 945 HD22 LEU A 56 -54.677 -61.029 -0.271 1.00 20.00 H +ATOM 946 HD23 LEU A 56 -55.801 -60.204 0.862 1.00 20.00 H +ATOM 947 N SER A 57 -54.391 -62.464 5.169 1.00 48.18 N +ATOM 948 CA SER A 57 -53.883 -63.471 6.091 1.00 49.81 C +ATOM 949 C SER A 57 -55.026 -64.351 6.574 1.00 50.11 C +ATOM 950 O SER A 57 -55.944 -63.870 7.245 1.00 52.19 O +ATOM 951 CB SER A 57 -53.175 -62.826 7.280 1.00 46.28 C +ATOM 952 OG SER A 57 -52.932 -63.797 8.279 1.00 43.05 O +ATOM 953 H SER A 57 -54.953 -61.719 5.528 1.00 20.00 H +ATOM 954 HA SER A 57 -53.157 -64.108 5.564 1.00 20.00 H +ATOM 955 HB2 SER A 57 -52.218 -62.398 6.947 1.00 20.00 H +ATOM 956 HB3 SER A 57 -53.809 -62.028 7.693 1.00 20.00 H +ATOM 957 HG SER A 57 -52.833 -63.368 9.121 1.00 20.00 H +ATOM 958 N SER A 58 -54.950 -65.642 6.251 1.00 49.32 N +ATOM 959 CA SER A 58 -55.974 -66.585 6.677 1.00 50.61 C +ATOM 960 C SER A 58 -55.940 -66.852 8.176 1.00 49.34 C +ATOM 961 O SER A 58 -56.924 -67.366 8.718 1.00 47.67 O +ATOM 962 CB SER A 58 -55.816 -67.899 5.914 1.00 54.70 C +ATOM 963 OG SER A 58 -54.546 -68.480 6.168 1.00 54.54 O +ATOM 964 H SER A 58 -54.177 -65.968 5.707 1.00 20.00 H +ATOM 965 HA SER A 58 -56.962 -66.169 6.430 1.00 20.00 H +ATOM 966 HB2 SER A 58 -56.603 -68.598 6.233 1.00 20.00 H +ATOM 967 HB3 SER A 58 -55.914 -67.704 4.836 1.00 20.00 H +ATOM 968 HG SER A 58 -54.539 -68.858 7.040 1.00 20.00 H +ATOM 969 N THR A 59 -54.841 -66.525 8.855 1.00 42.81 N +ATOM 970 CA THR A 59 -54.704 -66.775 10.284 1.00 43.97 C +ATOM 971 C THR A 59 -54.945 -65.538 11.140 1.00 46.59 C +ATOM 972 O THR A 59 -54.773 -65.602 12.361 1.00 49.69 O +ATOM 973 CB THR A 59 -53.315 -67.354 10.589 1.00 47.71 C +ATOM 974 OG1 THR A 59 -52.325 -66.652 9.827 1.00 47.50 O +ATOM 975 CG2 THR A 59 -53.273 -68.834 10.237 1.00 46.56 C +ATOM 976 H THR A 59 -54.083 -66.093 8.366 1.00 20.00 H +ATOM 977 HA THR A 59 -55.447 -67.531 10.577 1.00 20.00 H +ATOM 978 HB THR A 59 -53.114 -67.239 11.664 1.00 20.00 H +ATOM 979 HG1 THR A 59 -52.075 -65.859 10.286 1.00 20.00 H +ATOM 980 HG21 THR A 59 -52.274 -69.236 10.460 1.00 20.00 H +ATOM 981 HG22 THR A 59 -54.026 -69.373 10.830 1.00 20.00 H +ATOM 982 HG23 THR A 59 -53.489 -68.962 9.166 1.00 20.00 H +ATOM 983 N TYR A 60 -55.345 -64.425 10.536 1.00 48.16 N +ATOM 984 CA TYR A 60 -55.605 -63.210 11.295 1.00 45.92 C +ATOM 985 C TYR A 60 -56.870 -63.355 12.131 1.00 50.50 C +ATOM 986 O TYR A 60 -57.869 -63.924 11.682 1.00 44.31 O +ATOM 987 CB TYR A 60 -55.733 -62.016 10.347 1.00 46.73 C +ATOM 988 CG TYR A 60 -56.384 -60.794 10.958 1.00 48.55 C +ATOM 989 CD1 TYR A 60 -55.680 -59.970 11.825 1.00 50.27 C +ATOM 990 CD2 TYR A 60 -57.696 -60.451 10.649 1.00 51.36 C +ATOM 991 CE1 TYR A 60 -56.266 -58.851 12.381 1.00 48.37 C +ATOM 992 CE2 TYR A 60 -58.292 -59.330 11.201 1.00 50.35 C +ATOM 993 CZ TYR A 60 -57.570 -58.532 12.065 1.00 48.39 C +ATOM 994 OH TYR A 60 -58.141 -57.411 12.624 1.00 46.13 O +ATOM 995 H TYR A 60 -55.470 -64.421 9.544 1.00 20.00 H +ATOM 996 HA TYR A 60 -54.761 -63.021 11.975 1.00 20.00 H +ATOM 997 HB2 TYR A 60 -54.724 -61.735 10.010 1.00 20.00 H +ATOM 998 HB3 TYR A 60 -56.335 -62.328 9.481 1.00 20.00 H +ATOM 999 HD1 TYR A 60 -54.655 -60.209 12.069 1.00 20.00 H +ATOM 1000 HD2 TYR A 60 -58.260 -61.070 9.967 1.00 20.00 H +ATOM 1001 HE1 TYR A 60 -55.705 -58.227 13.061 1.00 20.00 H +ATOM 1002 HE2 TYR A 60 -59.314 -59.082 10.957 1.00 20.00 H +ATOM 1003 HH TYR A 60 -59.009 -57.282 12.259 1.00 20.00 H +ATOM 1004 N ARG A 61 -56.824 -62.837 13.358 1.00 48.57 N +ATOM 1005 CA ARG A 61 -57.989 -62.798 14.235 1.00 50.59 C +ATOM 1006 C ARG A 61 -58.112 -61.405 14.832 1.00 48.23 C +ATOM 1007 O ARG A 61 -57.197 -60.933 15.515 1.00 40.49 O +ATOM 1008 CB ARG A 61 -57.900 -63.857 15.336 1.00 49.19 C +ATOM 1009 CG ARG A 61 -57.932 -65.286 14.804 1.00 51.18 C +ATOM 1010 CD ARG A 61 -58.039 -66.307 15.924 1.00 56.84 C +ATOM 1011 NE ARG A 61 -57.634 -67.640 15.484 1.00 57.99 N +ATOM 1012 CZ ARG A 61 -58.410 -68.717 15.523 1.00 54.97 C +ATOM 1013 NH1 ARG A 61 -59.646 -68.633 15.991 1.00 59.10 N +ATOM 1014 NH2 ARG A 61 -57.942 -69.884 15.103 1.00 51.16 N +ATOM 1015 H ARG A 61 -55.959 -62.461 13.690 1.00 20.00 H +ATOM 1016 HA ARG A 61 -58.892 -62.998 13.640 1.00 20.00 H +ATOM 1017 HB2 ARG A 61 -56.959 -63.710 15.886 1.00 20.00 H +ATOM 1018 HB3 ARG A 61 -58.750 -63.721 16.021 1.00 20.00 H +ATOM 1019 HG2 ARG A 61 -58.800 -65.398 14.137 1.00 20.00 H +ATOM 1020 HG3 ARG A 61 -57.008 -65.475 14.238 1.00 20.00 H +ATOM 1021 HD2 ARG A 61 -57.389 -65.994 16.755 1.00 20.00 H +ATOM 1022 HD3 ARG A 61 -59.082 -66.348 16.270 1.00 20.00 H +ATOM 1023 HE ARG A 61 -56.706 -67.749 15.128 1.00 20.00 H +ATOM 1024 HH11 ARG A 61 -60.224 -69.449 16.027 1.00 20.00 H +ATOM 1025 HH12 ARG A 61 -60.002 -67.754 16.309 1.00 20.00 H +ATOM 1026 HH21 ARG A 61 -58.522 -70.698 15.140 1.00 20.00 H +ATOM 1027 HH22 ARG A 61 -57.009 -69.951 14.749 1.00 20.00 H +ATOM 1028 N ASP A 62 -59.241 -60.753 14.562 1.00 43.61 N +ATOM 1029 CA ASP A 62 -59.491 -59.396 15.031 1.00 46.07 C +ATOM 1030 C ASP A 62 -59.889 -59.424 16.501 1.00 47.34 C +ATOM 1031 O ASP A 62 -60.880 -60.064 16.865 1.00 47.68 O +ATOM 1032 CB ASP A 62 -60.590 -58.763 14.176 1.00 47.49 C +ATOM 1033 CG ASP A 62 -60.807 -57.287 14.471 1.00 50.90 C +ATOM 1034 OD1 ASP A 62 -60.238 -56.756 15.450 1.00 52.49 O +ATOM 1035 OD2 ASP A 62 -61.556 -56.648 13.703 1.00 54.13 O +ATOM 1036 H ASP A 62 -59.943 -61.211 14.017 1.00 20.00 H +ATOM 1037 HA ASP A 62 -58.575 -58.796 14.926 1.00 20.00 H +ATOM 1038 HB2 ASP A 62 -60.313 -58.870 13.117 1.00 20.00 H +ATOM 1039 HB3 ASP A 62 -61.532 -59.299 14.365 1.00 20.00 H +ATOM 1040 N LEU A 63 -59.120 -58.732 17.349 1.00 46.48 N +ATOM 1041 CA LEU A 63 -59.461 -58.639 18.764 1.00 42.35 C +ATOM 1042 C LEU A 63 -60.504 -57.566 19.052 1.00 49.92 C +ATOM 1043 O LEU A 63 -60.984 -57.482 20.189 1.00 48.68 O +ATOM 1044 CB LEU A 63 -58.198 -58.388 19.596 1.00 44.90 C +ATOM 1045 CG LEU A 63 -57.362 -59.618 19.961 1.00 42.51 C +ATOM 1046 CD1 LEU A 63 -55.950 -59.214 20.383 1.00 45.54 C +ATOM 1047 CD2 LEU A 63 -58.045 -60.407 21.066 1.00 41.04 C +ATOM 1048 H LEU A 63 -58.300 -58.272 17.008 1.00 20.00 H +ATOM 1049 HA LEU A 63 -59.881 -59.604 19.084 1.00 20.00 H +ATOM 1050 HB2 LEU A 63 -57.553 -57.703 19.025 1.00 20.00 H +ATOM 1051 HB3 LEU A 63 -58.507 -57.904 20.534 1.00 20.00 H +ATOM 1052 HG LEU A 63 -57.286 -60.260 19.071 1.00 20.00 H +ATOM 1053 HD11 LEU A 63 -55.372 -60.114 20.639 1.00 20.00 H +ATOM 1054 HD12 LEU A 63 -55.457 -58.685 19.554 1.00 20.00 H +ATOM 1055 HD13 LEU A 63 -56.005 -58.552 21.260 1.00 20.00 H +ATOM 1056 HD21 LEU A 63 -57.436 -61.287 21.319 1.00 20.00 H +ATOM 1057 HD22 LEU A 63 -58.157 -59.770 21.956 1.00 20.00 H +ATOM 1058 HD23 LEU A 63 -59.037 -60.735 20.723 1.00 20.00 H +ATOM 1059 N ARG A 64 -60.859 -56.752 18.053 1.00 62.75 N +ATOM 1060 CA ARG A 64 -61.970 -55.801 18.137 1.00 54.71 C +ATOM 1061 C ARG A 64 -61.781 -54.816 19.293 1.00 56.88 C +ATOM 1062 O ARG A 64 -62.630 -54.674 20.176 1.00 55.70 O +ATOM 1063 CB ARG A 64 -63.312 -56.537 18.247 1.00 53.58 C +ATOM 1064 CG ARG A 64 -63.645 -57.342 17.008 1.00 50.65 C +ATOM 1065 CD ARG A 64 -64.951 -58.104 17.141 1.00 59.28 C +ATOM 1066 NE ARG A 64 -65.015 -58.929 18.344 1.00 63.13 N +ATOM 1067 CZ ARG A 64 -65.992 -58.853 19.242 1.00 66.84 C +ATOM 1068 NH1 ARG A 64 -65.975 -59.637 20.311 1.00 70.70 N +ATOM 1069 NH2 ARG A 64 -66.995 -58.003 19.061 1.00 64.88 N +ATOM 1070 H ARG A 64 -60.337 -56.795 17.201 1.00 20.00 H +ATOM 1071 HA ARG A 64 -61.992 -55.215 17.206 1.00 20.00 H +ATOM 1072 HB2 ARG A 64 -63.268 -57.220 19.108 1.00 20.00 H +ATOM 1073 HB3 ARG A 64 -64.108 -55.794 18.408 1.00 20.00 H +ATOM 1074 HG2 ARG A 64 -63.723 -56.655 16.152 1.00 20.00 H +ATOM 1075 HG3 ARG A 64 -62.834 -58.062 16.827 1.00 20.00 H +ATOM 1076 HD2 ARG A 64 -65.778 -57.379 17.170 1.00 20.00 H +ATOM 1077 HD3 ARG A 64 -65.066 -58.757 16.263 1.00 20.00 H +ATOM 1078 HE ARG A 64 -64.281 -59.590 18.501 1.00 20.00 H +ATOM 1079 HH11 ARG A 64 -66.717 -59.587 20.979 1.00 20.00 H +ATOM 1080 HH12 ARG A 64 -65.220 -60.278 20.449 1.00 20.00 H +ATOM 1081 HH21 ARG A 64 -67.736 -57.955 19.730 1.00 20.00 H +ATOM 1082 HH22 ARG A 64 -67.009 -57.411 18.255 1.00 20.00 H +ATOM 1083 N LYS A 65 -60.642 -54.126 19.264 1.00 55.67 N +ATOM 1084 CA LYS A 65 -60.322 -53.133 20.281 1.00 55.39 C +ATOM 1085 C LYS A 65 -59.197 -52.254 19.761 1.00 51.35 C +ATOM 1086 O LYS A 65 -58.177 -52.766 19.292 1.00 52.21 O +ATOM 1087 CB LYS A 65 -59.920 -53.803 21.600 1.00 62.54 C +ATOM 1088 CG LYS A 65 -59.433 -52.841 22.679 1.00 62.65 C +ATOM 1089 CD LYS A 65 -59.489 -53.491 24.051 1.00 62.63 C +ATOM 1090 CE LYS A 65 -60.903 -53.472 24.612 0.00 64.22 C +ATOM 1091 NZ LYS A 65 -61.330 -52.083 24.941 0.00 65.57 N +ATOM 1092 H LYS A 65 -59.990 -54.294 18.525 1.00 20.00 H +ATOM 1093 HA LYS A 65 -61.204 -52.502 20.466 1.00 20.00 H +ATOM 1094 HB2 LYS A 65 -60.795 -54.343 21.991 1.00 20.00 H +ATOM 1095 HB3 LYS A 65 -59.112 -54.519 21.389 1.00 20.00 H +ATOM 1096 HG2 LYS A 65 -58.395 -52.550 22.460 1.00 20.00 H +ATOM 1097 HG3 LYS A 65 -60.072 -51.946 22.678 1.00 20.00 H +ATOM 1098 HD2 LYS A 65 -59.150 -54.534 23.968 1.00 20.00 H +ATOM 1099 HD3 LYS A 65 -58.824 -52.943 24.735 1.00 20.00 H +ATOM 1100 HE2 LYS A 65 -61.592 -53.892 23.865 0.00 20.00 H +ATOM 1101 HE3 LYS A 65 -60.936 -54.084 25.525 0.00 20.00 H +ATOM 1102 HZ1 LYS A 65 -61.976 -52.104 25.704 0.00 20.00 H +ATOM 1103 HZ2 LYS A 65 -60.530 -51.540 25.197 0.00 20.00 H +ATOM 1104 HZ3 LYS A 65 -61.770 -51.672 24.143 0.00 20.00 H +ATOM 1105 N GLY A 66 -59.390 -50.939 19.836 1.00 49.30 N +ATOM 1106 CA GLY A 66 -58.365 -50.017 19.407 1.00 53.80 C +ATOM 1107 C GLY A 66 -57.312 -49.789 20.473 1.00 55.90 C +ATOM 1108 O GLY A 66 -57.447 -50.194 21.627 1.00 53.04 O +ATOM 1109 H GLY A 66 -60.255 -50.586 20.194 1.00 20.00 H +ATOM 1110 HA2 GLY A 66 -57.877 -50.424 18.509 1.00 20.00 H +ATOM 1111 HA3 GLY A 66 -58.836 -49.053 19.163 1.00 20.00 H +ATOM 1112 N VAL A 67 -56.229 -49.137 20.066 1.00 55.85 N +ATOM 1113 CA VAL A 67 -55.183 -48.737 21.000 1.00 53.38 C +ATOM 1114 C VAL A 67 -54.548 -47.455 20.482 1.00 54.17 C +ATOM 1115 O VAL A 67 -54.338 -47.288 19.277 1.00 54.36 O +ATOM 1116 CB VAL A 67 -54.142 -49.860 21.211 1.00 54.01 C +ATOM 1117 CG1 VAL A 67 -53.456 -50.226 19.904 1.00 53.71 C +ATOM 1118 CG2 VAL A 67 -53.120 -49.455 22.274 1.00 54.93 C +ATOM 1119 H VAL A 67 -56.128 -48.915 19.096 1.00 20.00 H +ATOM 1120 HA VAL A 67 -55.643 -48.519 21.975 1.00 20.00 H +ATOM 1121 HB VAL A 67 -54.677 -50.749 21.576 1.00 20.00 H +ATOM 1122 HG11 VAL A 67 -52.723 -51.026 20.086 1.00 20.00 H +ATOM 1123 HG12 VAL A 67 -54.208 -50.575 19.181 1.00 20.00 H +ATOM 1124 HG13 VAL A 67 -52.942 -49.342 19.500 1.00 20.00 H +ATOM 1125 HG21 VAL A 67 -52.389 -50.266 22.409 1.00 20.00 H +ATOM 1126 HG22 VAL A 67 -52.598 -48.542 21.952 1.00 20.00 H +ATOM 1127 HG23 VAL A 67 -53.637 -49.265 23.226 1.00 20.00 H +ATOM 1128 N TYR A 68 -54.273 -46.537 21.403 1.00 56.01 N +ATOM 1129 CA TYR A 68 -53.693 -45.240 21.085 1.00 59.40 C +ATOM 1130 C TYR A 68 -52.448 -45.060 21.939 1.00 57.63 C +ATOM 1131 O TYR A 68 -52.528 -45.138 23.170 1.00 55.68 O +ATOM 1132 CB TYR A 68 -54.709 -44.119 21.331 1.00 63.89 C +ATOM 1133 CG TYR A 68 -54.131 -42.723 21.336 1.00 69.11 C +ATOM 1134 CD1 TYR A 68 -53.418 -42.239 20.249 1.00 70.01 C +ATOM 1135 CD2 TYR A 68 -54.321 -41.879 22.422 1.00 66.23 C +ATOM 1136 CE1 TYR A 68 -52.895 -40.958 20.250 1.00 68.70 C +ATOM 1137 CE2 TYR A 68 -53.805 -40.597 22.430 1.00 68.45 C +ATOM 1138 CZ TYR A 68 -53.091 -40.141 21.341 1.00 70.91 C +ATOM 1139 OH TYR A 68 -52.571 -38.864 21.344 1.00 75.76 O +ATOM 1140 H TYR A 68 -54.474 -46.747 22.360 1.00 20.00 H +ATOM 1141 HA TYR A 68 -53.399 -45.219 20.025 1.00 20.00 H +ATOM 1142 HB2 TYR A 68 -55.471 -44.170 20.540 1.00 20.00 H +ATOM 1143 HB3 TYR A 68 -55.182 -44.296 22.308 1.00 20.00 H +ATOM 1144 HD1 TYR A 68 -53.269 -42.873 19.387 1.00 20.00 H +ATOM 1145 HD2 TYR A 68 -54.882 -42.230 23.275 1.00 20.00 H +ATOM 1146 HE1 TYR A 68 -52.335 -40.600 19.399 1.00 20.00 H +ATOM 1147 HE2 TYR A 68 -53.960 -39.955 23.285 1.00 20.00 H +ATOM 1148 HH TYR A 68 -52.792 -38.434 22.162 1.00 20.00 H +ATOM 1149 N VAL A 69 -51.312 -44.841 21.296 1.00 59.68 N +ATOM 1150 CA VAL A 69 -50.017 -44.784 21.960 1.00 58.49 C +ATOM 1151 C VAL A 69 -49.352 -43.458 21.616 1.00 55.65 C +ATOM 1152 O VAL A 69 -48.801 -43.292 20.526 1.00 53.85 O +ATOM 1153 CB VAL A 69 -49.125 -45.970 21.562 1.00 59.87 C +ATOM 1154 CG1 VAL A 69 -47.764 -45.855 22.238 1.00 59.38 C +ATOM 1155 CG2 VAL A 69 -49.793 -47.284 21.923 1.00 57.05 C +ATOM 1156 H VAL A 69 -51.345 -44.708 20.305 1.00 20.00 H +ATOM 1157 HA VAL A 69 -50.169 -44.821 23.049 1.00 20.00 H +ATOM 1158 HB VAL A 69 -48.977 -45.941 20.472 1.00 20.00 H +ATOM 1159 HG11 VAL A 69 -47.135 -46.709 21.945 1.00 20.00 H +ATOM 1160 HG12 VAL A 69 -47.278 -44.918 21.927 1.00 20.00 H +ATOM 1161 HG13 VAL A 69 -47.896 -45.854 23.330 1.00 20.00 H +ATOM 1162 HG21 VAL A 69 -49.140 -48.120 21.631 1.00 20.00 H +ATOM 1163 HG22 VAL A 69 -49.970 -47.319 23.008 1.00 20.00 H +ATOM 1164 HG23 VAL A 69 -50.753 -47.365 21.392 1.00 20.00 H +ATOM 1165 N PRO A 70 -49.388 -42.484 22.521 1.00 55.26 N +ATOM 1166 CA PRO A 70 -48.608 -41.260 22.327 1.00 58.22 C +ATOM 1167 C PRO A 70 -47.233 -41.359 22.968 1.00 60.31 C +ATOM 1168 O PRO A 70 -47.047 -41.956 24.031 1.00 59.37 O +ATOM 1169 CB PRO A 70 -49.463 -40.197 23.029 1.00 55.29 C +ATOM 1170 CG PRO A 70 -50.101 -40.949 24.148 1.00 57.14 C +ATOM 1171 CD PRO A 70 -50.335 -42.357 23.641 1.00 59.94 C +ATOM 1172 HA PRO A 70 -48.512 -41.019 21.258 1.00 20.00 H +ATOM 1173 HB2 PRO A 70 -48.836 -39.378 23.412 1.00 20.00 H +ATOM 1174 HB3 PRO A 70 -50.222 -39.789 22.346 1.00 20.00 H +ATOM 1175 HG2 PRO A 70 -49.435 -40.966 25.023 1.00 20.00 H +ATOM 1176 HG3 PRO A 70 -51.057 -40.481 24.424 1.00 20.00 H +ATOM 1177 HD2 PRO A 70 -50.118 -43.098 24.425 1.00 20.00 H +ATOM 1178 HD3 PRO A 70 -51.372 -42.482 23.295 1.00 20.00 H +ATOM 1179 N TYR A 71 -46.249 -40.785 22.290 1.00 59.80 N +ATOM 1180 CA TYR A 71 -44.916 -40.611 22.842 1.00 54.35 C +ATOM 1181 C TYR A 71 -44.649 -39.119 23.002 1.00 57.97 C +ATOM 1182 O TYR A 71 -45.493 -38.276 22.681 1.00 55.27 O +ATOM 1183 CB TYR A 71 -43.855 -41.266 21.954 1.00 51.43 C +ATOM 1184 CG TYR A 71 -44.101 -42.724 21.634 1.00 57.47 C +ATOM 1185 CD1 TYR A 71 -43.969 -43.706 22.606 1.00 61.04 C +ATOM 1186 CD2 TYR A 71 -44.438 -43.120 20.348 1.00 60.74 C +ATOM 1187 CE1 TYR A 71 -44.184 -45.045 22.306 1.00 62.63 C +ATOM 1188 CE2 TYR A 71 -44.654 -44.451 20.039 1.00 64.72 C +ATOM 1189 CZ TYR A 71 -44.526 -45.410 21.020 1.00 68.48 C +ATOM 1190 OH TYR A 71 -44.741 -46.735 20.710 1.00 72.90 O +ATOM 1191 H TYR A 71 -46.431 -40.459 21.362 1.00 20.00 H +ATOM 1192 HA TYR A 71 -44.871 -41.079 23.836 1.00 20.00 H +ATOM 1193 HB2 TYR A 71 -43.814 -40.711 21.005 1.00 20.00 H +ATOM 1194 HB3 TYR A 71 -42.885 -41.188 22.467 1.00 20.00 H +ATOM 1195 HD1 TYR A 71 -43.695 -43.424 23.612 1.00 20.00 H +ATOM 1196 HD2 TYR A 71 -44.534 -42.374 19.573 1.00 20.00 H +ATOM 1197 HE1 TYR A 71 -44.084 -45.797 23.075 1.00 20.00 H +ATOM 1198 HE2 TYR A 71 -44.922 -44.737 19.033 1.00 20.00 H +ATOM 1199 HH TYR A 71 -44.615 -47.267 21.487 1.00 20.00 H +ATOM 1200 N THR A 72 -43.456 -38.792 23.501 1.00 57.59 N +ATOM 1201 CA THR A 72 -43.103 -37.387 23.669 1.00 57.71 C +ATOM 1202 C THR A 72 -43.055 -36.679 22.321 1.00 57.24 C +ATOM 1203 O THR A 72 -43.607 -35.585 22.159 1.00 60.44 O +ATOM 1204 CB THR A 72 -41.765 -37.267 24.398 1.00 58.08 C +ATOM 1205 OG1 THR A 72 -41.807 -38.033 25.608 0.00 57.32 O +ATOM 1206 CG2 THR A 72 -41.490 -35.815 24.748 0.00 57.42 C +ATOM 1207 H THR A 72 -42.806 -39.507 23.759 1.00 20.00 H +ATOM 1208 HA THR A 72 -43.871 -36.897 24.285 1.00 20.00 H +ATOM 1209 HB THR A 72 -40.965 -37.637 23.740 1.00 20.00 H +ATOM 1210 HG1 THR A 72 -42.711 -38.171 25.865 0.00 20.00 H +ATOM 1211 HG21 THR A 72 -40.526 -35.740 25.272 0.00 20.00 H +ATOM 1212 HG22 THR A 72 -41.454 -35.216 23.826 0.00 20.00 H +ATOM 1213 HG23 THR A 72 -42.292 -35.437 25.400 0.00 20.00 H +ATOM 1214 N GLN A 73 -42.406 -37.297 21.338 1.00 58.43 N +ATOM 1215 CA GLN A 73 -42.353 -36.784 19.970 1.00 62.80 C +ATOM 1216 C GLN A 73 -42.828 -37.908 19.052 1.00 66.08 C +ATOM 1217 O GLN A 73 -42.047 -38.792 18.686 1.00 73.18 O +ATOM 1218 CB GLN A 73 -40.948 -36.311 19.610 1.00 66.64 C +ATOM 1219 CG GLN A 73 -40.838 -35.663 18.241 0.00 64.59 C +ATOM 1220 CD GLN A 73 -39.479 -35.035 17.996 0.00 64.71 C +ATOM 1221 OE1 GLN A 73 -39.345 -34.090 17.215 0.00 65.05 O +ATOM 1222 NE2 GLN A 73 -38.460 -35.563 18.662 0.00 65.06 N +ATOM 1223 H GLN A 73 -41.932 -38.153 21.545 1.00 20.00 H +ATOM 1224 HA GLN A 73 -43.045 -35.935 19.871 1.00 20.00 H +ATOM 1225 HB2 GLN A 73 -40.627 -35.578 20.365 1.00 20.00 H +ATOM 1226 HB3 GLN A 73 -40.275 -37.181 19.635 1.00 20.00 H +ATOM 1227 HG2 GLN A 73 -41.014 -36.431 17.473 0.00 20.00 H +ATOM 1228 HG3 GLN A 73 -41.607 -34.880 18.160 0.00 20.00 H +ATOM 1229 HE21 GLN A 73 -37.538 -35.195 18.539 0.00 20.00 H +ATOM 1230 HE22 GLN A 73 -38.614 -36.330 19.285 0.00 20.00 H +ATOM 1231 N GLY A 74 -44.111 -37.884 18.700 1.00 61.82 N +ATOM 1232 CA GLY A 74 -44.687 -38.923 17.869 1.00 60.75 C +ATOM 1233 C GLY A 74 -45.830 -39.663 18.536 1.00 59.80 C +ATOM 1234 O GLY A 74 -45.951 -39.659 19.765 1.00 57.38 O +ATOM 1235 H GLY A 74 -44.691 -37.133 19.016 1.00 20.00 H +ATOM 1236 HA2 GLY A 74 -45.063 -38.461 16.944 1.00 20.00 H +ATOM 1237 HA3 GLY A 74 -43.898 -39.649 17.622 1.00 20.00 H +ATOM 1238 N LYS A 75 -46.675 -40.305 17.733 1.00 62.25 N +ATOM 1239 CA LYS A 75 -47.818 -41.045 18.252 1.00 56.32 C +ATOM 1240 C LYS A 75 -48.345 -41.958 17.157 1.00 53.10 C +ATOM 1241 O LYS A 75 -48.112 -41.728 15.969 1.00 48.60 O +ATOM 1242 CB LYS A 75 -48.924 -40.103 18.745 1.00 57.79 C +ATOM 1243 CG LYS A 75 -49.549 -39.241 17.657 1.00 60.71 C +ATOM 1244 CD LYS A 75 -50.616 -38.315 18.224 1.00 61.84 C +ATOM 1245 CE LYS A 75 -51.231 -37.440 17.142 0.00 63.18 C +ATOM 1246 NZ LYS A 75 -50.238 -36.514 16.528 0.00 64.61 N +ATOM 1247 H LYS A 75 -46.521 -40.279 16.745 1.00 20.00 H +ATOM 1248 HA LYS A 75 -47.493 -41.668 19.098 1.00 20.00 H +ATOM 1249 HB2 LYS A 75 -49.719 -40.714 19.199 1.00 20.00 H +ATOM 1250 HB3 LYS A 75 -48.493 -39.436 19.507 1.00 20.00 H +ATOM 1251 HG2 LYS A 75 -48.762 -38.634 17.186 1.00 20.00 H +ATOM 1252 HG3 LYS A 75 -50.008 -39.896 16.902 1.00 20.00 H +ATOM 1253 HD2 LYS A 75 -51.409 -38.923 18.684 1.00 20.00 H +ATOM 1254 HD3 LYS A 75 -50.159 -37.669 18.988 1.00 20.00 H +ATOM 1255 HE2 LYS A 75 -51.643 -38.089 16.355 0.00 20.00 H +ATOM 1256 HE3 LYS A 75 -52.041 -36.844 17.588 0.00 20.00 H +ATOM 1257 HZ1 LYS A 75 -50.532 -35.569 16.668 0.00 20.00 H +ATOM 1258 HZ2 LYS A 75 -49.345 -36.652 16.956 0.00 20.00 H +ATOM 1259 HZ3 LYS A 75 -50.171 -36.700 15.548 0.00 20.00 H +ATOM 1260 N TRP A 76 -49.048 -43.009 17.573 1.00 54.21 N +ATOM 1261 CA TRP A 76 -49.737 -43.858 16.611 1.00 54.11 C +ATOM 1262 C TRP A 76 -50.996 -44.438 17.235 1.00 54.45 C +ATOM 1263 O TRP A 76 -51.157 -44.475 18.458 1.00 54.40 O +ATOM 1264 CB TRP A 76 -48.838 -44.983 16.068 1.00 56.22 C +ATOM 1265 CG TRP A 76 -48.243 -45.902 17.097 1.00 52.16 C +ATOM 1266 CD1 TRP A 76 -47.017 -45.788 17.677 1.00 53.45 C +ATOM 1267 CD2 TRP A 76 -48.830 -47.097 17.636 1.00 53.70 C +ATOM 1268 NE1 TRP A 76 -46.807 -46.822 18.554 1.00 56.59 N +ATOM 1269 CE2 TRP A 76 -47.905 -47.640 18.548 1.00 53.56 C +ATOM 1270 CE3 TRP A 76 -50.052 -47.754 17.443 1.00 54.98 C +ATOM 1271 CZ2 TRP A 76 -48.159 -48.810 19.265 1.00 52.67 C +ATOM 1272 CZ3 TRP A 76 -50.304 -48.915 18.159 1.00 53.45 C +ATOM 1273 CH2 TRP A 76 -49.361 -49.431 19.057 1.00 55.79 C +ATOM 1274 H TRP A 76 -49.103 -43.216 18.550 1.00 20.00 H +ATOM 1275 HA TRP A 76 -50.043 -43.238 15.755 1.00 20.00 H +ATOM 1276 HB2 TRP A 76 -49.441 -45.593 15.379 1.00 20.00 H +ATOM 1277 HB3 TRP A 76 -48.010 -44.515 15.515 1.00 20.00 H +ATOM 1278 HD1 TRP A 76 -46.310 -44.996 17.476 1.00 20.00 H +ATOM 1279 HE1 TRP A 76 -45.985 -46.957 19.108 1.00 20.00 H +ATOM 1280 HE3 TRP A 76 -50.783 -47.364 16.750 1.00 20.00 H +ATOM 1281 HZ2 TRP A 76 -47.434 -49.211 19.958 1.00 20.00 H +ATOM 1282 HZ3 TRP A 76 -51.243 -49.430 18.022 1.00 20.00 H +ATOM 1283 HH2 TRP A 76 -49.587 -50.339 19.597 1.00 20.00 H +ATOM 1284 N GLU A 77 -51.887 -44.891 16.360 1.00 57.41 N +ATOM 1285 CA GLU A 77 -53.164 -45.471 16.732 1.00 54.38 C +ATOM 1286 C GLU A 77 -53.363 -46.728 15.901 1.00 50.83 C +ATOM 1287 O GLU A 77 -52.928 -46.797 14.748 1.00 49.16 O +ATOM 1288 CB GLU A 77 -54.310 -44.470 16.499 1.00 62.74 C +ATOM 1289 CG GLU A 77 -55.611 -44.775 17.229 1.00 72.39 C +ATOM 1290 CD GLU A 77 -56.536 -43.572 17.248 1.00 74.92 C +ATOM 1291 OE1 GLU A 77 -56.386 -42.693 16.373 1.00 76.65 O +ATOM 1292 OE2 GLU A 77 -57.403 -43.494 18.143 1.00 76.67 O +ATOM 1293 H GLU A 77 -51.664 -44.829 15.387 1.00 20.00 H +ATOM 1294 HA GLU A 77 -53.151 -45.748 17.797 1.00 20.00 H +ATOM 1295 HB2 GLU A 77 -53.964 -43.478 16.825 1.00 20.00 H +ATOM 1296 HB3 GLU A 77 -54.525 -44.447 15.420 1.00 20.00 H +ATOM 1297 HG2 GLU A 77 -56.119 -45.608 16.721 1.00 20.00 H +ATOM 1298 HG3 GLU A 77 -55.380 -45.064 18.265 1.00 20.00 H +ATOM 1299 N GLY A 78 -54.001 -47.733 16.490 1.00 50.61 N +ATOM 1300 CA GLY A 78 -54.098 -48.990 15.778 1.00 53.94 C +ATOM 1301 C GLY A 78 -55.207 -49.875 16.301 1.00 52.75 C +ATOM 1302 O GLY A 78 -55.943 -49.519 17.222 1.00 48.52 O +ATOM 1303 H GLY A 78 -54.403 -47.625 17.399 1.00 20.00 H +ATOM 1304 HA2 GLY A 78 -54.289 -48.778 14.715 1.00 20.00 H +ATOM 1305 HA3 GLY A 78 -53.143 -49.526 15.880 1.00 20.00 H +ATOM 1306 N GLU A 79 -55.301 -51.053 15.691 1.00 50.75 N +ATOM 1307 CA GLU A 79 -56.344 -52.026 15.983 1.00 50.95 C +ATOM 1308 C GLU A 79 -55.702 -53.330 16.435 1.00 49.07 C +ATOM 1309 O GLU A 79 -54.820 -53.865 15.751 1.00 42.62 O +ATOM 1310 CB GLU A 79 -57.226 -52.252 14.752 1.00 53.75 C +ATOM 1311 CG GLU A 79 -57.609 -50.956 14.045 1.00 59.42 C +ATOM 1312 CD GLU A 79 -58.586 -51.154 12.899 1.00 63.52 C +ATOM 1313 OE1 GLU A 79 -58.751 -52.303 12.435 1.00 61.87 O +ATOM 1314 OE2 GLU A 79 -59.195 -50.152 12.470 1.00 63.10 O +ATOM 1315 H GLU A 79 -54.620 -51.282 14.996 1.00 20.00 H +ATOM 1316 HA GLU A 79 -56.978 -51.648 16.799 1.00 20.00 H +ATOM 1317 HB2 GLU A 79 -56.679 -52.890 14.042 1.00 20.00 H +ATOM 1318 HB3 GLU A 79 -58.147 -52.763 15.070 1.00 20.00 H +ATOM 1319 HG2 GLU A 79 -58.069 -50.281 14.782 1.00 20.00 H +ATOM 1320 HG3 GLU A 79 -56.694 -50.494 13.646 1.00 20.00 H +ATOM 1321 N LEU A 80 -56.149 -53.835 17.582 1.00 48.94 N +ATOM 1322 CA LEU A 80 -55.545 -55.012 18.193 1.00 55.43 C +ATOM 1323 C LEU A 80 -56.069 -56.298 17.565 1.00 70.15 C +ATOM 1324 O LEU A 80 -57.247 -56.408 17.220 1.00 54.57 O +ATOM 1325 CB LEU A 80 -55.813 -55.019 19.698 1.00 48.26 C +ATOM 1326 CG LEU A 80 -55.111 -53.925 20.503 1.00 50.43 C +ATOM 1327 CD1 LEU A 80 -55.540 -53.980 21.959 1.00 53.49 C +ATOM 1328 CD2 LEU A 80 -53.603 -54.071 20.379 1.00 44.67 C +ATOM 1329 H LEU A 80 -56.922 -53.394 18.038 1.00 20.00 H +ATOM 1330 HA LEU A 80 -54.456 -54.976 18.041 1.00 20.00 H +ATOM 1331 HB2 LEU A 80 -56.897 -54.906 19.848 1.00 20.00 H +ATOM 1332 HB3 LEU A 80 -55.487 -55.992 20.094 1.00 20.00 H +ATOM 1333 HG LEU A 80 -55.403 -52.948 20.089 1.00 20.00 H +ATOM 1334 HD11 LEU A 80 -55.027 -53.188 22.523 1.00 20.00 H +ATOM 1335 HD12 LEU A 80 -56.628 -53.832 22.026 1.00 20.00 H +ATOM 1336 HD13 LEU A 80 -55.277 -54.961 22.382 1.00 20.00 H +ATOM 1337 HD21 LEU A 80 -53.108 -53.280 20.961 1.00 20.00 H +ATOM 1338 HD22 LEU A 80 -53.297 -55.055 20.764 1.00 20.00 H +ATOM 1339 HD23 LEU A 80 -53.312 -53.984 19.322 1.00 20.00 H +ATOM 1340 N GLY A 81 -55.180 -57.273 17.428 1.00 47.45 N +ATOM 1341 CA GLY A 81 -55.502 -58.556 16.851 1.00 46.61 C +ATOM 1342 C GLY A 81 -54.357 -59.510 17.102 1.00 49.67 C +ATOM 1343 O GLY A 81 -53.417 -59.196 17.833 1.00 48.97 O +ATOM 1344 H GLY A 81 -54.243 -57.111 17.739 1.00 20.00 H +ATOM 1345 HA2 GLY A 81 -56.418 -58.950 17.315 1.00 20.00 H +ATOM 1346 HA3 GLY A 81 -55.658 -58.444 15.768 1.00 20.00 H +ATOM 1347 N THR A 82 -54.444 -60.694 16.498 1.00 48.31 N +ATOM 1348 CA THR A 82 -53.372 -61.677 16.590 1.00 47.72 C +ATOM 1349 C THR A 82 -53.083 -62.239 15.200 1.00 47.73 C +ATOM 1350 O THR A 82 -53.929 -62.200 14.303 1.00 43.01 O +ATOM 1351 CB THR A 82 -53.722 -62.811 17.581 1.00 47.43 C +ATOM 1352 OG1 THR A 82 -54.783 -63.606 17.038 1.00 49.01 O +ATOM 1353 CG2 THR A 82 -54.146 -62.246 18.944 1.00 49.20 C +ATOM 1354 H THR A 82 -55.264 -60.914 15.969 1.00 20.00 H +ATOM 1355 HA THR A 82 -52.461 -61.180 16.954 1.00 20.00 H +ATOM 1356 HB THR A 82 -52.826 -63.433 17.725 1.00 20.00 H +ATOM 1357 HG1 THR A 82 -55.118 -63.193 16.251 1.00 20.00 H +ATOM 1358 HG21 THR A 82 -54.388 -63.075 19.626 1.00 20.00 H +ATOM 1359 HG22 THR A 82 -53.322 -61.652 19.367 1.00 20.00 H +ATOM 1360 HG23 THR A 82 -55.031 -61.606 18.816 1.00 20.00 H +ATOM 1361 N ASP A 83 -51.851 -62.708 15.011 1.00 44.63 N +ATOM 1362 CA ASP A 83 -51.503 -63.502 13.837 1.00 49.64 C +ATOM 1363 C ASP A 83 -50.328 -64.406 14.185 1.00 48.61 C +ATOM 1364 O ASP A 83 -49.692 -64.256 15.230 1.00 54.04 O +ATOM 1365 CB ASP A 83 -51.165 -62.630 12.622 1.00 50.46 C +ATOM 1366 CG ASP A 83 -51.703 -63.221 11.325 1.00 47.00 C +ATOM 1367 OD1 ASP A 83 -51.713 -64.466 11.208 1.00 40.75 O +ATOM 1368 OD2 ASP A 83 -52.123 -62.457 10.429 1.00 44.83 O +ATOM 1369 H ASP A 83 -51.146 -62.511 15.692 1.00 20.00 H +ATOM 1370 HA ASP A 83 -52.359 -64.140 13.571 1.00 20.00 H +ATOM 1371 HB2 ASP A 83 -51.606 -61.633 12.767 1.00 20.00 H +ATOM 1372 HB3 ASP A 83 -50.071 -62.539 12.544 1.00 20.00 H +ATOM 1373 N LEU A 84 -50.046 -65.349 13.287 1.00 49.00 N +ATOM 1374 CA LEU A 84 -48.837 -66.154 13.412 1.00 48.48 C +ATOM 1375 C LEU A 84 -47.622 -65.322 13.018 1.00 52.24 C +ATOM 1376 O LEU A 84 -47.670 -64.538 12.068 1.00 53.33 O +ATOM 1377 CB LEU A 84 -48.917 -67.410 12.542 1.00 47.65 C +ATOM 1378 CG LEU A 84 -50.007 -68.432 12.880 1.00 46.25 C +ATOM 1379 CD1 LEU A 84 -49.907 -69.663 11.987 1.00 49.09 C +ATOM 1380 CD2 LEU A 84 -49.946 -68.821 14.346 1.00 50.28 C +ATOM 1381 H LEU A 84 -50.669 -65.506 12.521 1.00 20.00 H +ATOM 1382 HA LEU A 84 -48.717 -66.467 14.460 1.00 20.00 H +ATOM 1383 HB2 LEU A 84 -49.081 -67.083 11.505 1.00 20.00 H +ATOM 1384 HB3 LEU A 84 -47.948 -67.925 12.615 1.00 20.00 H +ATOM 1385 HG LEU A 84 -50.982 -67.958 12.695 1.00 20.00 H +ATOM 1386 HD11 LEU A 84 -50.701 -70.376 12.254 1.00 20.00 H +ATOM 1387 HD12 LEU A 84 -50.022 -69.363 10.935 1.00 20.00 H +ATOM 1388 HD13 LEU A 84 -48.925 -70.139 12.127 1.00 20.00 H +ATOM 1389 HD21 LEU A 84 -50.736 -69.554 14.565 1.00 20.00 H +ATOM 1390 HD22 LEU A 84 -48.964 -69.264 14.567 1.00 20.00 H +ATOM 1391 HD23 LEU A 84 -50.093 -67.926 14.969 1.00 20.00 H +ATOM 1392 N VAL A 85 -46.531 -65.479 13.763 1.00 50.81 N +ATOM 1393 CA VAL A 85 -45.359 -64.622 13.610 1.00 52.01 C +ATOM 1394 C VAL A 85 -44.106 -65.486 13.606 1.00 50.81 C +ATOM 1395 O VAL A 85 -43.981 -66.408 14.419 1.00 47.47 O +ATOM 1396 CB VAL A 85 -45.270 -63.566 14.731 1.00 51.48 C +ATOM 1397 CG1 VAL A 85 -44.043 -62.687 14.534 1.00 48.92 C +ATOM 1398 CG2 VAL A 85 -46.528 -62.719 14.786 1.00 45.79 C +ATOM 1399 H VAL A 85 -46.513 -66.206 14.449 1.00 20.00 H +ATOM 1400 HA VAL A 85 -45.420 -64.094 12.647 1.00 20.00 H +ATOM 1401 HB VAL A 85 -45.166 -64.095 15.690 1.00 20.00 H +ATOM 1402 HG11 VAL A 85 -43.993 -61.940 15.340 1.00 20.00 H +ATOM 1403 HG12 VAL A 85 -43.138 -63.311 14.556 1.00 20.00 H +ATOM 1404 HG13 VAL A 85 -44.111 -62.175 13.563 1.00 20.00 H +ATOM 1405 HG21 VAL A 85 -46.436 -61.977 15.593 1.00 20.00 H +ATOM 1406 HG22 VAL A 85 -46.664 -62.201 13.825 1.00 20.00 H +ATOM 1407 HG23 VAL A 85 -47.397 -63.365 14.980 1.00 20.00 H +ATOM 1408 N SER A 86 -43.175 -65.183 12.703 1.00 50.88 N +ATOM 1409 CA SER A 86 -41.903 -65.881 12.631 1.00 52.84 C +ATOM 1410 C SER A 86 -40.760 -64.884 12.503 1.00 49.88 C +ATOM 1411 O SER A 86 -40.956 -63.713 12.166 1.00 49.61 O +ATOM 1412 CB SER A 86 -41.862 -66.861 11.451 1.00 57.33 C +ATOM 1413 OG SER A 86 -42.825 -67.885 11.613 1.00 64.66 O +ATOM 1414 H SER A 86 -43.358 -64.448 12.050 1.00 20.00 H +ATOM 1415 HA SER A 86 -41.755 -66.456 13.557 1.00 20.00 H +ATOM 1416 HB2 SER A 86 -42.071 -66.313 10.520 1.00 20.00 H +ATOM 1417 HB3 SER A 86 -40.861 -67.313 11.393 1.00 20.00 H +ATOM 1418 HG SER A 86 -43.684 -67.497 11.732 1.00 20.00 H +ATOM 1419 N ILE A 87 -39.564 -65.373 12.788 1.00 49.19 N +ATOM 1420 CA ILE A 87 -38.324 -64.657 12.523 1.00 48.18 C +ATOM 1421 C ILE A 87 -37.461 -65.535 11.626 1.00 48.09 C +ATOM 1422 O ILE A 87 -36.825 -66.480 12.092 1.00 48.84 O +ATOM 1423 CB ILE A 87 -37.589 -64.295 13.825 1.00 52.02 C +ATOM 1424 CG1 ILE A 87 -38.537 -63.594 14.794 1.00 51.32 C +ATOM 1425 CG2 ILE A 87 -36.392 -63.408 13.523 1.00 46.65 C +ATOM 1426 CD1 ILE A 87 -37.915 -63.306 16.136 1.00 56.91 C +ATOM 1427 H ILE A 87 -39.509 -66.280 13.206 1.00 20.00 H +ATOM 1428 HA ILE A 87 -38.550 -63.725 11.984 1.00 20.00 H +ATOM 1429 HB ILE A 87 -37.231 -65.224 14.293 1.00 20.00 H +ATOM 1430 HG12 ILE A 87 -38.853 -62.641 14.344 1.00 20.00 H +ATOM 1431 HG13 ILE A 87 -39.416 -64.237 14.948 1.00 20.00 H +ATOM 1432 HG21 ILE A 87 -35.875 -63.156 14.461 1.00 20.00 H +ATOM 1433 HG22 ILE A 87 -35.700 -63.942 12.855 1.00 20.00 H +ATOM 1434 HG23 ILE A 87 -36.735 -62.484 13.034 1.00 20.00 H +ATOM 1435 HD11 ILE A 87 -38.650 -62.803 16.781 1.00 20.00 H +ATOM 1436 HD12 ILE A 87 -37.602 -64.250 16.605 1.00 20.00 H +ATOM 1437 HD13 ILE A 87 -37.039 -62.655 16.002 1.00 20.00 H +ATOM 1438 N PRO A 88 -37.424 -65.252 10.322 1.00 47.04 N +ATOM 1439 CA PRO A 88 -36.715 -66.146 9.387 1.00 47.57 C +ATOM 1440 C PRO A 88 -35.282 -66.454 9.788 1.00 47.84 C +ATOM 1441 O PRO A 88 -34.867 -67.617 9.712 1.00 46.55 O +ATOM 1442 CB PRO A 88 -36.788 -65.375 8.064 1.00 49.15 C +ATOM 1443 CG PRO A 88 -38.032 -64.542 8.189 1.00 50.97 C +ATOM 1444 CD PRO A 88 -38.102 -64.141 9.634 1.00 49.91 C +ATOM 1445 HA PRO A 88 -37.271 -67.090 9.282 1.00 20.00 H +ATOM 1446 HB2 PRO A 88 -35.902 -64.736 7.936 1.00 20.00 H +ATOM 1447 HB3 PRO A 88 -36.867 -66.068 7.213 1.00 20.00 H +ATOM 1448 HG2 PRO A 88 -37.965 -63.652 7.546 1.00 20.00 H +ATOM 1449 HG3 PRO A 88 -38.918 -65.130 7.910 1.00 20.00 H +ATOM 1450 HD2 PRO A 88 -37.576 -63.190 9.806 1.00 20.00 H +ATOM 1451 HD3 PRO A 88 -39.146 -64.048 9.968 1.00 20.00 H +ATOM 1452 N HIS A 89 -34.514 -65.458 10.219 1.00 46.36 N +ATOM 1453 CA HIS A 89 -33.174 -65.702 10.747 1.00 47.49 C +ATOM 1454 C HIS A 89 -33.242 -65.721 12.274 1.00 47.69 C +ATOM 1455 O HIS A 89 -32.675 -64.880 12.973 1.00 49.13 O +ATOM 1456 CB HIS A 89 -32.200 -64.650 10.223 1.00 48.45 C +ATOM 1457 CG HIS A 89 -32.201 -64.518 8.730 1.00 57.64 C +ATOM 1458 ND1 HIS A 89 -31.466 -65.347 7.909 1.00 60.63 N +ATOM 1459 CD2 HIS A 89 -32.845 -63.655 7.908 1.00 57.77 C +ATOM 1460 CE1 HIS A 89 -31.659 -65.003 6.649 1.00 59.51 C +ATOM 1461 NE2 HIS A 89 -32.491 -63.977 6.620 1.00 56.20 N +ATOM 1462 H HIS A 89 -34.861 -64.521 10.181 1.00 20.00 H +ATOM 1463 HA HIS A 89 -32.829 -66.689 10.407 1.00 20.00 H +ATOM 1464 HB2 HIS A 89 -32.473 -63.677 10.658 1.00 20.00 H +ATOM 1465 HB3 HIS A 89 -31.185 -64.925 10.547 1.00 20.00 H +ATOM 1466 HD1 HIS A 89 -30.878 -66.093 8.220 1.00 20.00 H +ATOM 1467 HD2 HIS A 89 -33.513 -62.861 8.209 1.00 20.00 H +ATOM 1468 HE1 HIS A 89 -31.213 -65.479 5.788 1.00 20.00 H +ATOM 1469 HE2 HIS A 89 -32.811 -63.511 5.795 1.00 20.00 H +ATOM 1470 N GLY A 90 -33.968 -66.715 12.789 1.00 47.53 N +ATOM 1471 CA GLY A 90 -34.288 -66.768 14.196 1.00 47.12 C +ATOM 1472 C GLY A 90 -34.302 -68.164 14.787 1.00 47.33 C +ATOM 1473 O GLY A 90 -33.548 -69.053 14.379 1.00 51.59 O +ATOM 1474 H GLY A 90 -34.299 -67.441 12.186 1.00 20.00 H +ATOM 1475 HA2 GLY A 90 -33.541 -66.172 14.741 1.00 20.00 H +ATOM 1476 HA3 GLY A 90 -35.285 -66.325 14.338 1.00 20.00 H +ATOM 1477 N PRO A 91 -35.174 -68.372 15.775 1.00 51.31 N +ATOM 1478 CA PRO A 91 -35.184 -69.637 16.525 1.00 55.28 C +ATOM 1479 C PRO A 91 -35.983 -70.758 15.889 1.00 60.00 C +ATOM 1480 O PRO A 91 -36.198 -71.781 16.552 1.00 58.67 O +ATOM 1481 CB PRO A 91 -35.813 -69.215 17.861 1.00 55.77 C +ATOM 1482 CG PRO A 91 -36.754 -68.124 17.483 1.00 54.14 C +ATOM 1483 CD PRO A 91 -36.124 -67.392 16.327 1.00 51.89 C +ATOM 1484 HA PRO A 91 -34.153 -69.978 16.703 1.00 20.00 H +ATOM 1485 HB2 PRO A 91 -36.353 -70.055 18.323 1.00 20.00 H +ATOM 1486 HB3 PRO A 91 -35.045 -68.846 18.556 1.00 20.00 H +ATOM 1487 HG2 PRO A 91 -37.723 -68.547 17.181 1.00 20.00 H +ATOM 1488 HG3 PRO A 91 -36.901 -67.439 18.331 1.00 20.00 H +ATOM 1489 HD2 PRO A 91 -36.881 -67.114 15.579 1.00 20.00 H +ATOM 1490 HD3 PRO A 91 -35.600 -66.489 16.673 1.00 20.00 H +ATOM 1491 N ASN A 92 -36.445 -70.594 14.648 1.00 61.15 N +ATOM 1492 CA ASN A 92 -37.055 -71.679 13.876 1.00 61.73 C +ATOM 1493 C ASN A 92 -38.385 -72.135 14.479 1.00 61.85 C +ATOM 1494 O ASN A 92 -38.723 -73.321 14.463 1.00 63.84 O +ATOM 1495 CB ASN A 92 -36.084 -72.857 13.735 1.00 59.14 C +ATOM 1496 CG ASN A 92 -36.504 -73.838 12.659 1.00 60.80 C +ATOM 1497 OD1 ASN A 92 -37.183 -73.473 11.701 1.00 64.53 O +ATOM 1498 ND2 ASN A 92 -36.107 -75.095 12.819 1.00 60.19 N +ATOM 1499 H ASN A 92 -36.371 -69.690 14.226 1.00 20.00 H +ATOM 1500 HA ASN A 92 -37.265 -71.304 12.863 1.00 20.00 H +ATOM 1501 HB2 ASN A 92 -35.088 -72.464 13.483 1.00 20.00 H +ATOM 1502 HB3 ASN A 92 -36.035 -73.389 14.696 1.00 20.00 H +ATOM 1503 HD21 ASN A 92 -36.360 -75.789 12.145 1.00 20.00 H +ATOM 1504 HD22 ASN A 92 -35.556 -75.348 13.614 1.00 20.00 H +ATOM 1505 N VAL A 93 -39.155 -71.191 15.015 1.00 57.66 N +ATOM 1506 CA VAL A 93 -40.483 -71.489 15.536 1.00 57.22 C +ATOM 1507 C VAL A 93 -41.448 -70.394 15.107 1.00 57.88 C +ATOM 1508 O VAL A 93 -41.059 -69.244 14.883 1.00 59.12 O +ATOM 1509 CB VAL A 93 -40.494 -71.647 17.074 1.00 57.12 C +ATOM 1510 CG1 VAL A 93 -39.731 -72.899 17.494 1.00 59.34 C +ATOM 1511 CG2 VAL A 93 -39.924 -70.410 17.741 1.00 53.07 C +ATOM 1512 H VAL A 93 -38.813 -70.252 15.061 1.00 20.00 H +ATOM 1513 HA VAL A 93 -40.830 -72.437 15.100 1.00 20.00 H +ATOM 1514 HB VAL A 93 -41.540 -71.760 17.395 1.00 20.00 H +ATOM 1515 HG11 VAL A 93 -39.752 -72.991 18.590 1.00 20.00 H +ATOM 1516 HG12 VAL A 93 -40.203 -73.784 17.043 1.00 20.00 H +ATOM 1517 HG13 VAL A 93 -38.688 -72.825 17.152 1.00 20.00 H +ATOM 1518 HG21 VAL A 93 -39.940 -70.541 18.833 1.00 20.00 H +ATOM 1519 HG22 VAL A 93 -38.888 -70.257 17.406 1.00 20.00 H +ATOM 1520 HG23 VAL A 93 -40.531 -69.534 17.468 1.00 20.00 H +ATOM 1521 N THR A 94 -42.718 -70.767 14.980 1.00 53.92 N +ATOM 1522 CA THR A 94 -43.790 -69.844 14.640 1.00 53.81 C +ATOM 1523 C THR A 94 -44.773 -69.797 15.798 1.00 55.55 C +ATOM 1524 O THR A 94 -45.239 -70.844 16.260 1.00 65.74 O +ATOM 1525 CB THR A 94 -44.503 -70.271 13.355 1.00 54.57 C +ATOM 1526 OG1 THR A 94 -43.564 -70.299 12.272 1.00 53.78 O +ATOM 1527 CG2 THR A 94 -45.632 -69.307 13.025 1.00 53.42 C +ATOM 1528 H THR A 94 -42.948 -71.729 15.125 1.00 20.00 H +ATOM 1529 HA THR A 94 -43.374 -68.837 14.491 1.00 20.00 H +ATOM 1530 HB THR A 94 -44.929 -71.274 13.507 1.00 20.00 H +ATOM 1531 HG1 THR A 94 -43.175 -69.439 12.167 1.00 20.00 H +ATOM 1532 HG21 THR A 94 -46.132 -69.630 12.100 1.00 20.00 H +ATOM 1533 HG22 THR A 94 -46.359 -69.298 13.850 1.00 20.00 H +ATOM 1534 HG23 THR A 94 -45.222 -68.296 12.886 1.00 20.00 H +ATOM 1535 N VAL A 95 -45.086 -68.589 16.264 1.00 51.78 N +ATOM 1536 CA VAL A 95 -45.950 -68.400 17.420 1.00 52.60 C +ATOM 1537 C VAL A 95 -47.070 -67.432 17.081 1.00 51.80 C +ATOM 1538 O VAL A 95 -46.917 -66.530 16.251 1.00 52.38 O +ATOM 1539 CB VAL A 95 -45.165 -67.885 18.648 1.00 58.59 C +ATOM 1540 CG1 VAL A 95 -44.073 -68.871 19.037 1.00 59.54 C +ATOM 1541 CG2 VAL A 95 -44.577 -66.513 18.370 1.00 59.24 C +ATOM 1542 H VAL A 95 -44.714 -67.783 15.803 1.00 20.00 H +ATOM 1543 HA VAL A 95 -46.402 -69.366 17.690 1.00 20.00 H +ATOM 1544 HB VAL A 95 -45.868 -67.797 19.490 1.00 20.00 H +ATOM 1545 HG11 VAL A 95 -43.527 -68.488 19.911 1.00 20.00 H +ATOM 1546 HG12 VAL A 95 -44.527 -69.842 19.285 1.00 20.00 H +ATOM 1547 HG13 VAL A 95 -43.376 -68.997 18.195 1.00 20.00 H +ATOM 1548 HG21 VAL A 95 -44.023 -66.165 19.254 1.00 20.00 H +ATOM 1549 HG22 VAL A 95 -43.894 -66.575 17.510 1.00 20.00 H +ATOM 1550 HG23 VAL A 95 -45.388 -65.806 18.143 1.00 20.00 H +ATOM 1551 N ARG A 96 -48.217 -67.633 17.725 0.50 52.06 N +ATOM 1552 CA ARG A 96 -49.302 -66.669 17.643 0.50 53.83 C +ATOM 1553 C ARG A 96 -49.073 -65.576 18.679 0.50 53.82 C +ATOM 1554 O ARG A 96 -48.817 -65.867 19.851 0.50 54.19 O +ATOM 1555 CB ARG A 96 -50.649 -67.349 17.865 0.50 53.29 C +ATOM 1556 CG ARG A 96 -51.819 -66.397 17.737 0.50 53.47 C +ATOM 1557 CD ARG A 96 -53.128 -67.187 17.567 0.50 52.64 C +ATOM 1558 NE ARG A 96 -53.158 -67.953 16.299 0.50 51.61 N +ATOM 1559 CZ ARG A 96 -54.039 -67.781 15.305 0.50 50.91 C +ATOM 1560 NH1 ARG A 96 -54.932 -66.831 15.448 0.50 53.73 N +ATOM 1561 NH2 ARG A 96 -54.003 -68.479 14.170 0.50 49.22 N +ATOM 1562 H ARG A 96 -48.334 -68.460 18.274 0.50 20.00 H +ATOM 1563 HA ARG A 96 -49.306 -66.207 16.645 0.50 20.00 H +ATOM 1564 HB2 ARG A 96 -50.765 -68.149 17.119 0.50 20.00 H +ATOM 1565 HB3 ARG A 96 -50.660 -67.784 18.875 0.50 20.00 H +ATOM 1566 HG2 ARG A 96 -51.884 -65.776 18.643 0.50 20.00 H +ATOM 1567 HG3 ARG A 96 -51.668 -65.751 16.860 0.50 20.00 H +ATOM 1568 HD2 ARG A 96 -53.230 -67.889 18.408 0.50 20.00 H +ATOM 1569 HD3 ARG A 96 -53.972 -66.481 17.575 0.50 20.00 H +ATOM 1570 HE ARG A 96 -52.461 -68.659 16.175 0.50 20.00 H +ATOM 1571 HH11 ARG A 96 -55.577 -66.636 14.710 0.50 20.00 H +ATOM 1572 HH12 ARG A 96 -54.967 -66.301 16.296 0.50 20.00 H +ATOM 1573 HH21 ARG A 96 -54.653 -68.276 13.438 0.50 20.00 H +ATOM 1574 HH22 ARG A 96 -53.326 -69.205 14.051 0.50 20.00 H +ATOM 1575 N ALA A 97 -49.123 -64.320 18.238 1.00 51.19 N +ATOM 1576 CA ALA A 97 -48.777 -63.191 19.089 1.00 51.89 C +ATOM 1577 C ALA A 97 -49.760 -62.052 18.869 1.00 50.30 C +ATOM 1578 O ALA A 97 -50.397 -61.946 17.819 1.00 51.91 O +ATOM 1579 CB ALA A 97 -47.344 -62.706 18.824 1.00 52.21 C +ATOM 1580 H ALA A 97 -49.407 -64.148 17.295 1.00 20.00 H +ATOM 1581 HA ALA A 97 -48.842 -63.502 20.142 1.00 20.00 H +ATOM 1582 HB1 ALA A 97 -47.117 -61.855 19.482 1.00 20.00 H +ATOM 1583 HB2 ALA A 97 -46.637 -63.524 19.026 1.00 20.00 H +ATOM 1584 HB3 ALA A 97 -47.252 -62.392 17.774 1.00 20.00 H +ATOM 1585 N ASN A 98 -49.879 -61.203 19.887 1.00 52.59 N +ATOM 1586 CA ASN A 98 -50.652 -59.979 19.753 1.00 51.30 C +ATOM 1587 C ASN A 98 -49.956 -59.030 18.787 1.00 51.04 C +ATOM 1588 O ASN A 98 -48.726 -58.929 18.769 1.00 46.85 O +ATOM 1589 CB ASN A 98 -50.831 -59.312 21.117 1.00 47.30 C +ATOM 1590 CG ASN A 98 -51.750 -60.092 22.029 1.00 50.72 C +ATOM 1591 OD1 ASN A 98 -52.812 -60.555 21.611 1.00 52.03 O +ATOM 1592 ND2 ASN A 98 -51.344 -60.249 23.283 1.00 44.03 N +ATOM 1593 H ASN A 98 -49.430 -61.410 20.756 1.00 20.00 H +ATOM 1594 HA ASN A 98 -51.647 -60.218 19.350 1.00 20.00 H +ATOM 1595 HB2 ASN A 98 -49.846 -59.226 21.599 1.00 20.00 H +ATOM 1596 HB3 ASN A 98 -51.254 -58.308 20.965 1.00 20.00 H +ATOM 1597 HD21 ASN A 98 -51.908 -60.761 23.931 1.00 20.00 H +ATOM 1598 HD22 ASN A 98 -50.474 -59.856 23.580 1.00 20.00 H +ATOM 1599 N ILE A 99 -50.747 -58.342 17.968 1.00 48.97 N +ATOM 1600 CA ILE A 99 -50.219 -57.417 16.970 1.00 48.52 C +ATOM 1601 C ILE A 99 -51.068 -56.153 16.979 1.00 52.79 C +ATOM 1602 O ILE A 99 -52.292 -56.222 16.825 1.00 51.36 O +ATOM 1603 CB ILE A 99 -50.196 -58.037 15.556 1.00 48.49 C +ATOM 1604 CG1 ILE A 99 -49.307 -59.279 15.508 1.00 52.52 C +ATOM 1605 CG2 ILE A 99 -49.708 -57.031 14.539 1.00 50.98 C +ATOM 1606 CD1 ILE A 99 -49.230 -59.916 14.142 1.00 53.58 C +ATOM 1607 H ILE A 99 -51.737 -58.463 18.038 1.00 20.00 H +ATOM 1608 HA ILE A 99 -49.188 -57.144 17.240 1.00 20.00 H +ATOM 1609 HB ILE A 99 -51.222 -58.333 15.293 1.00 20.00 H +ATOM 1610 HG12 ILE A 99 -48.291 -58.991 15.815 1.00 20.00 H +ATOM 1611 HG13 ILE A 99 -49.707 -60.020 16.215 1.00 20.00 H +ATOM 1612 HG21 ILE A 99 -49.700 -57.493 13.541 1.00 20.00 H +ATOM 1613 HG22 ILE A 99 -50.379 -56.160 14.534 1.00 20.00 H +ATOM 1614 HG23 ILE A 99 -48.690 -56.708 14.802 1.00 20.00 H +ATOM 1615 HD11 ILE A 99 -48.576 -60.799 14.185 1.00 20.00 H +ATOM 1616 HD12 ILE A 99 -50.237 -60.221 13.823 1.00 20.00 H +ATOM 1617 HD13 ILE A 99 -48.821 -59.192 13.422 1.00 20.00 H +ATOM 1618 N ALA A 100 -50.427 -55.000 17.170 1.00 48.43 N +ATOM 1619 CA ALA A 100 -51.094 -53.708 17.018 1.00 48.59 C +ATOM 1620 C ALA A 100 -50.899 -53.262 15.575 1.00 51.58 C +ATOM 1621 O ALA A 100 -49.813 -52.823 15.188 1.00 49.76 O +ATOM 1622 CB ALA A 100 -50.550 -52.686 18.010 1.00 46.85 C +ATOM 1623 H ALA A 100 -49.460 -55.019 17.425 1.00 20.00 H +ATOM 1624 HA ALA A 100 -52.171 -53.832 17.202 1.00 20.00 H +ATOM 1625 HB1 ALA A 100 -51.070 -51.727 17.871 1.00 20.00 H +ATOM 1626 HB2 ALA A 100 -50.715 -53.047 19.036 1.00 20.00 H +ATOM 1627 HB3 ALA A 100 -49.472 -52.547 17.839 1.00 20.00 H +ATOM 1628 N ALA A 101 -51.958 -53.390 14.777 1.00 48.06 N +ATOM 1629 CA ALA A 101 -51.941 -52.999 13.373 1.00 49.12 C +ATOM 1630 C ALA A 101 -52.112 -51.489 13.281 1.00 48.99 C +ATOM 1631 O ALA A 101 -53.210 -50.971 13.505 1.00 47.08 O +ATOM 1632 CB ALA A 101 -53.045 -53.729 12.613 1.00 48.87 C +ATOM 1633 H ALA A 101 -52.801 -53.771 15.158 1.00 20.00 H +ATOM 1634 HA ALA A 101 -50.972 -53.270 12.929 1.00 20.00 H +ATOM 1635 HB1 ALA A 101 -53.024 -53.427 11.555 1.00 20.00 H +ATOM 1636 HB2 ALA A 101 -52.885 -54.815 12.688 1.00 20.00 H +ATOM 1637 HB3 ALA A 101 -54.022 -53.471 13.048 1.00 20.00 H +ATOM 1638 N ILE A 102 -51.037 -50.783 12.942 1.00 47.89 N +ATOM 1639 CA ILE A 102 -51.032 -49.324 12.983 1.00 48.56 C +ATOM 1640 C ILE A 102 -51.760 -48.785 11.761 1.00 47.77 C +ATOM 1641 O ILE A 102 -51.323 -48.986 10.623 1.00 47.90 O +ATOM 1642 CB ILE A 102 -49.602 -48.774 13.054 1.00 48.11 C +ATOM 1643 CG1 ILE A 102 -48.941 -49.214 14.357 1.00 47.60 C +ATOM 1644 CG2 ILE A 102 -49.612 -47.261 12.924 1.00 48.44 C +ATOM 1645 CD1 ILE A 102 -47.443 -49.068 14.346 1.00 45.61 C +ATOM 1646 H ILE A 102 -50.210 -51.265 12.651 1.00 20.00 H +ATOM 1647 HA ILE A 102 -51.572 -48.989 13.881 1.00 20.00 H +ATOM 1648 HB ILE A 102 -49.028 -49.193 12.214 1.00 20.00 H +ATOM 1649 HG12 ILE A 102 -49.345 -48.602 15.177 1.00 20.00 H +ATOM 1650 HG13 ILE A 102 -49.187 -50.272 14.533 1.00 20.00 H +ATOM 1651 HG21 ILE A 102 -48.581 -46.881 12.977 1.00 20.00 H +ATOM 1652 HG22 ILE A 102 -50.058 -46.979 11.959 1.00 20.00 H +ATOM 1653 HG23 ILE A 102 -50.205 -46.827 13.743 1.00 20.00 H +ATOM 1654 HD11 ILE A 102 -47.035 -49.402 15.311 1.00 20.00 H +ATOM 1655 HD12 ILE A 102 -47.021 -49.682 13.537 1.00 20.00 H +ATOM 1656 HD13 ILE A 102 -47.179 -48.013 14.181 1.00 20.00 H +ATOM 1657 N THR A 103 -52.857 -48.068 12.000 1.00 48.31 N +ATOM 1658 CA THR A 103 -53.682 -47.520 10.934 1.00 51.95 C +ATOM 1659 C THR A 103 -53.528 -46.017 10.764 1.00 53.86 C +ATOM 1660 O THR A 103 -53.912 -45.489 9.714 1.00 53.40 O +ATOM 1661 CB THR A 103 -55.158 -47.844 11.194 1.00 49.73 C +ATOM 1662 OG1 THR A 103 -55.517 -47.427 12.520 1.00 48.78 O +ATOM 1663 CG2 THR A 103 -55.396 -49.341 11.055 1.00 46.81 C +ATOM 1664 H THR A 103 -53.124 -47.900 12.949 1.00 20.00 H +ATOM 1665 HA THR A 103 -53.396 -47.998 9.986 1.00 20.00 H +ATOM 1666 HB THR A 103 -55.773 -47.314 10.451 1.00 20.00 H +ATOM 1667 HG1 THR A 103 -55.497 -46.479 12.570 1.00 20.00 H +ATOM 1668 HG21 THR A 103 -56.457 -49.563 11.243 1.00 20.00 H +ATOM 1669 HG22 THR A 103 -55.129 -49.662 10.037 1.00 20.00 H +ATOM 1670 HG23 THR A 103 -54.774 -49.880 11.784 1.00 20.00 H +ATOM 1671 N GLU A 104 -52.977 -45.323 11.758 1.00 59.84 N +ATOM 1672 CA GLU A 104 -52.821 -43.877 11.706 1.00 59.08 C +ATOM 1673 C GLU A 104 -51.667 -43.493 12.619 1.00 53.17 C +ATOM 1674 O GLU A 104 -51.497 -44.088 13.686 1.00 51.94 O +ATOM 1675 CB GLU A 104 -54.112 -43.169 12.133 1.00 63.98 C +ATOM 1676 CG GLU A 104 -54.168 -41.678 11.818 1.00 71.25 C +ATOM 1677 CD GLU A 104 -55.501 -41.057 12.204 1.00 78.44 C +ATOM 1678 OE1 GLU A 104 -56.523 -41.775 12.179 1.00 78.55 O +ATOM 1679 OE2 GLU A 104 -55.526 -39.855 12.540 1.00 81.12 O +ATOM 1680 H GLU A 104 -52.659 -45.813 12.569 1.00 20.00 H +ATOM 1681 HA GLU A 104 -52.576 -43.569 10.679 1.00 20.00 H +ATOM 1682 HB2 GLU A 104 -54.954 -43.657 11.620 1.00 20.00 H +ATOM 1683 HB3 GLU A 104 -54.224 -43.292 13.220 1.00 20.00 H +ATOM 1684 HG2 GLU A 104 -53.366 -41.169 12.373 1.00 20.00 H +ATOM 1685 HG3 GLU A 104 -54.012 -41.538 10.738 1.00 20.00 H +ATOM 1686 N SER A 105 -50.880 -42.505 12.198 1.00 52.36 N +ATOM 1687 CA SER A 105 -49.701 -42.130 12.967 1.00 52.90 C +ATOM 1688 C SER A 105 -49.227 -40.747 12.547 1.00 56.02 C +ATOM 1689 O SER A 105 -49.611 -40.228 11.496 1.00 55.09 O +ATOM 1690 CB SER A 105 -48.575 -43.155 12.795 1.00 52.18 C +ATOM 1691 OG SER A 105 -48.157 -43.223 11.443 1.00 51.43 O +ATOM 1692 H SER A 105 -51.099 -42.019 11.352 1.00 20.00 H +ATOM 1693 HA SER A 105 -49.967 -42.092 14.034 1.00 20.00 H +ATOM 1694 HB2 SER A 105 -47.721 -42.860 13.422 1.00 20.00 H +ATOM 1695 HB3 SER A 105 -48.937 -44.145 13.110 1.00 20.00 H +ATOM 1696 HG SER A 105 -48.871 -42.957 10.876 1.00 20.00 H +ATOM 1697 N ASP A 106 -48.383 -40.160 13.395 1.00 57.25 N +ATOM 1698 CA ASP A 106 -47.789 -38.855 13.138 1.00 57.62 C +ATOM 1699 C ASP A 106 -46.415 -38.818 13.787 1.00 53.49 C +ATOM 1700 O ASP A 106 -46.292 -39.064 14.990 1.00 49.94 O +ATOM 1701 CB ASP A 106 -48.673 -37.725 13.682 1.00 63.67 C +ATOM 1702 CG ASP A 106 -48.215 -36.350 13.223 1.00 68.07 C +ATOM 1703 OD1 ASP A 106 -48.079 -36.148 11.997 1.00 64.38 O +ATOM 1704 OD2 ASP A 106 -47.996 -35.470 14.084 1.00 71.36 O +ATOM 1705 H ASP A 106 -48.148 -40.635 14.243 1.00 20.00 H +ATOM 1706 HA ASP A 106 -47.670 -38.713 12.054 1.00 20.00 H +ATOM 1707 HB2 ASP A 106 -49.704 -37.887 13.335 1.00 20.00 H +ATOM 1708 HB3 ASP A 106 -48.647 -37.756 14.781 1.00 20.00 H +ATOM 1709 N LYS A 107 -45.391 -38.532 12.982 1.00 54.98 N +ATOM 1710 CA LYS A 107 -44.016 -38.385 13.466 1.00 62.64 C +ATOM 1711 C LYS A 107 -43.542 -39.637 14.203 1.00 62.64 C +ATOM 1712 O LYS A 107 -42.810 -39.565 15.192 1.00 60.56 O +ATOM 1713 CB LYS A 107 -43.872 -37.146 14.355 1.00 65.95 C +ATOM 1714 CG LYS A 107 -44.214 -35.833 13.668 1.00 68.82 C +ATOM 1715 CD LYS A 107 -43.988 -34.650 14.602 1.00 69.60 C +ATOM 1716 CE LYS A 107 -44.422 -33.341 13.958 0.00 70.37 C +ATOM 1717 NZ LYS A 107 -44.210 -32.174 14.861 0.00 71.91 N +ATOM 1718 H LYS A 107 -45.569 -38.413 12.005 1.00 20.00 H +ATOM 1719 HA LYS A 107 -43.358 -38.245 12.596 1.00 20.00 H +ATOM 1720 HB2 LYS A 107 -44.540 -37.265 15.221 1.00 20.00 H +ATOM 1721 HB3 LYS A 107 -42.829 -37.091 14.701 1.00 20.00 H +ATOM 1722 HG2 LYS A 107 -43.577 -35.716 12.779 1.00 20.00 H +ATOM 1723 HG3 LYS A 107 -45.270 -35.852 13.362 1.00 20.00 H +ATOM 1724 HD2 LYS A 107 -44.569 -34.805 15.523 1.00 20.00 H +ATOM 1725 HD3 LYS A 107 -42.918 -34.589 14.850 1.00 20.00 H +ATOM 1726 HE2 LYS A 107 -43.839 -33.188 13.038 0.00 20.00 H +ATOM 1727 HE3 LYS A 107 -45.491 -33.406 13.708 0.00 20.00 H +ATOM 1728 HZ1 LYS A 107 -44.271 -31.327 14.332 0.00 20.00 H +ATOM 1729 HZ2 LYS A 107 -44.911 -32.173 15.574 0.00 20.00 H +ATOM 1730 HZ3 LYS A 107 -43.306 -32.239 15.283 0.00 20.00 H +ATOM 1731 N PHE A 108 -43.958 -40.803 13.711 1.00 58.92 N +ATOM 1732 CA PHE A 108 -43.556 -42.081 14.284 1.00 59.67 C +ATOM 1733 C PHE A 108 -42.662 -42.867 13.332 1.00 60.70 C +ATOM 1734 O PHE A 108 -41.532 -43.212 13.687 1.00 59.57 O +ATOM 1735 CB PHE A 108 -44.799 -42.901 14.668 1.00 56.71 C +ATOM 1736 CG PHE A 108 -44.493 -44.312 15.082 1.00 56.16 C +ATOM 1737 CD1 PHE A 108 -43.935 -44.585 16.321 1.00 54.12 C +ATOM 1738 CD2 PHE A 108 -44.767 -45.368 14.227 1.00 57.18 C +ATOM 1739 CE1 PHE A 108 -43.652 -45.886 16.696 1.00 55.36 C +ATOM 1740 CE2 PHE A 108 -44.488 -46.669 14.597 1.00 54.34 C +ATOM 1741 CZ PHE A 108 -43.932 -46.927 15.832 1.00 57.05 C +ATOM 1742 H PHE A 108 -44.569 -40.801 12.919 1.00 20.00 H +ATOM 1743 HA PHE A 108 -42.984 -41.891 15.204 1.00 20.00 H +ATOM 1744 HB2 PHE A 108 -45.302 -42.396 15.505 1.00 20.00 H +ATOM 1745 HB3 PHE A 108 -45.474 -42.933 13.800 1.00 20.00 H +ATOM 1746 HD1 PHE A 108 -43.719 -43.774 17.000 1.00 20.00 H +ATOM 1747 HD2 PHE A 108 -45.204 -45.171 13.259 1.00 20.00 H +ATOM 1748 HE1 PHE A 108 -43.213 -46.088 17.662 1.00 20.00 H +ATOM 1749 HE2 PHE A 108 -44.705 -47.482 13.920 1.00 20.00 H +ATOM 1750 HZ PHE A 108 -43.715 -47.944 16.124 1.00 20.00 H +ATOM 1751 N PHE A 109 -43.146 -43.167 12.130 1.00 55.55 N +ATOM 1752 CA PHE A 109 -42.295 -43.776 11.120 1.00 56.80 C +ATOM 1753 C PHE A 109 -41.271 -42.758 10.633 1.00 58.18 C +ATOM 1754 O PHE A 109 -41.589 -41.583 10.423 1.00 58.96 O +ATOM 1755 CB PHE A 109 -43.130 -44.291 9.947 1.00 54.40 C +ATOM 1756 CG PHE A 109 -44.081 -45.397 10.316 1.00 52.87 C +ATOM 1757 CD1 PHE A 109 -43.605 -46.629 10.737 1.00 51.80 C +ATOM 1758 CD2 PHE A 109 -45.452 -45.209 10.230 1.00 52.86 C +ATOM 1759 CE1 PHE A 109 -44.475 -47.647 11.075 1.00 52.24 C +ATOM 1760 CE2 PHE A 109 -46.329 -46.226 10.567 1.00 53.97 C +ATOM 1761 CZ PHE A 109 -45.841 -47.445 10.988 1.00 52.19 C +ATOM 1762 H PHE A 109 -44.104 -42.972 11.919 1.00 20.00 H +ATOM 1763 HA PHE A 109 -41.756 -44.627 11.562 1.00 20.00 H +ATOM 1764 HB2 PHE A 109 -43.715 -43.451 9.543 1.00 20.00 H +ATOM 1765 HB3 PHE A 109 -42.445 -44.667 9.173 1.00 20.00 H +ATOM 1766 HD1 PHE A 109 -42.540 -46.795 10.802 1.00 20.00 H +ATOM 1767 HD2 PHE A 109 -45.840 -44.258 9.896 1.00 20.00 H +ATOM 1768 HE1 PHE A 109 -44.090 -48.600 11.407 1.00 20.00 H +ATOM 1769 HE2 PHE A 109 -47.395 -46.065 10.500 1.00 20.00 H +ATOM 1770 HZ PHE A 109 -46.523 -48.240 11.249 1.00 20.00 H +ATOM 1771 N ILE A 110 -40.031 -43.211 10.465 1.00 55.88 N +ATOM 1772 CA ILE A 110 -38.932 -42.352 10.042 1.00 53.74 C +ATOM 1773 C ILE A 110 -38.684 -42.564 8.557 1.00 52.62 C +ATOM 1774 O ILE A 110 -38.546 -43.704 8.096 1.00 52.01 O +ATOM 1775 CB ILE A 110 -37.653 -42.629 10.851 1.00 55.71 C +ATOM 1776 CG1 ILE A 110 -37.920 -42.468 12.346 1.00 56.76 C +ATOM 1777 CG2 ILE A 110 -36.532 -41.694 10.413 1.00 55.11 C +ATOM 1778 CD1 ILE A 110 -36.704 -42.723 13.206 1.00 58.57 C +ATOM 1779 H ILE A 110 -39.846 -44.179 10.636 1.00 20.00 H +ATOM 1780 HA ILE A 110 -39.215 -41.301 10.199 1.00 20.00 H +ATOM 1781 HB ILE A 110 -37.339 -43.666 10.661 1.00 20.00 H +ATOM 1782 HG12 ILE A 110 -38.267 -41.440 12.529 1.00 20.00 H +ATOM 1783 HG13 ILE A 110 -38.708 -43.178 12.637 1.00 20.00 H +ATOM 1784 HG21 ILE A 110 -35.627 -41.906 11.001 1.00 20.00 H +ATOM 1785 HG22 ILE A 110 -36.320 -41.850 9.345 1.00 20.00 H +ATOM 1786 HG23 ILE A 110 -36.840 -40.651 10.577 1.00 20.00 H +ATOM 1787 HD11 ILE A 110 -36.969 -42.590 14.265 1.00 20.00 H +ATOM 1788 HD12 ILE A 110 -36.349 -43.751 13.043 1.00 20.00 H +ATOM 1789 HD13 ILE A 110 -35.908 -42.014 12.935 1.00 20.00 H +ATOM 1790 N ASN A 111 -38.621 -41.464 7.815 1.00 51.45 N +ATOM 1791 CA ASN A 111 -38.333 -41.517 6.390 1.00 53.73 C +ATOM 1792 C ASN A 111 -36.944 -42.098 6.152 1.00 60.17 C +ATOM 1793 O ASN A 111 -35.940 -41.530 6.593 1.00 57.74 O +ATOM 1794 CB ASN A 111 -38.440 -40.110 5.805 1.00 54.88 C +ATOM 1795 CG ASN A 111 -38.410 -40.099 4.294 1.00 59.42 C +ATOM 1796 OD1 ASN A 111 -38.334 -41.148 3.654 1.00 61.30 O +ATOM 1797 ND2 ASN A 111 -38.486 -38.908 3.712 1.00 60.89 N +ATOM 1798 H ASN A 111 -38.776 -40.576 8.248 1.00 20.00 H +ATOM 1799 HA ASN A 111 -39.072 -42.160 5.890 1.00 20.00 H +ATOM 1800 HB2 ASN A 111 -39.386 -39.661 6.141 1.00 20.00 H +ATOM 1801 HB3 ASN A 111 -37.597 -39.510 6.177 1.00 20.00 H +ATOM 1802 HD21 ASN A 111 -38.483 -38.838 2.714 1.00 20.00 H +ATOM 1803 HD22 ASN A 111 -38.546 -38.081 4.271 1.00 20.00 H +ATOM 1804 N GLY A 112 -36.888 -43.235 5.462 1.00 59.02 N +ATOM 1805 CA GLY A 112 -35.626 -43.862 5.121 1.00 54.38 C +ATOM 1806 C GLY A 112 -35.079 -44.833 6.144 1.00 57.69 C +ATOM 1807 O GLY A 112 -33.970 -45.349 5.951 1.00 59.57 O +ATOM 1808 H GLY A 112 -37.741 -43.669 5.171 1.00 20.00 H +ATOM 1809 HA2 GLY A 112 -35.764 -44.408 4.176 1.00 20.00 H +ATOM 1810 HA3 GLY A 112 -34.881 -43.066 4.978 1.00 20.00 H +ATOM 1811 N SER A 113 -35.817 -45.105 7.223 1.00 58.55 N +ATOM 1812 CA SER A 113 -35.316 -45.992 8.269 1.00 59.34 C +ATOM 1813 C SER A 113 -35.342 -47.456 7.861 1.00 56.20 C +ATOM 1814 O SER A 113 -34.631 -48.266 8.468 1.00 52.57 O +ATOM 1815 CB SER A 113 -36.127 -45.808 9.549 1.00 60.79 C +ATOM 1816 OG SER A 113 -37.437 -46.329 9.389 1.00 66.27 O +ATOM 1817 H SER A 113 -36.725 -44.696 7.316 1.00 20.00 H +ATOM 1818 HA SER A 113 -34.273 -45.721 8.490 1.00 20.00 H +ATOM 1819 HB2 SER A 113 -35.626 -46.336 10.374 1.00 20.00 H +ATOM 1820 HB3 SER A 113 -36.191 -44.736 9.786 1.00 20.00 H +ATOM 1821 HG SER A 113 -37.820 -45.985 8.591 1.00 20.00 H +ATOM 1822 N ASN A 114 -36.155 -47.810 6.867 1.00 55.79 N +ATOM 1823 CA ASN A 114 -36.289 -49.175 6.360 1.00 53.05 C +ATOM 1824 C ASN A 114 -36.898 -50.139 7.378 1.00 49.52 C +ATOM 1825 O ASN A 114 -36.837 -51.355 7.185 1.00 51.18 O +ATOM 1826 CB ASN A 114 -34.946 -49.728 5.856 1.00 58.15 C +ATOM 1827 CG ASN A 114 -35.122 -50.832 4.830 1.00 65.15 C +ATOM 1828 OD1 ASN A 114 -34.274 -51.714 4.707 1.00 66.39 O +ATOM 1829 ND2 ASN A 114 -36.218 -50.782 4.080 1.00 63.81 N +ATOM 1830 H ASN A 114 -36.710 -47.096 6.440 1.00 20.00 H +ATOM 1831 HA ASN A 114 -36.969 -49.148 5.496 1.00 20.00 H +ATOM 1832 HB2 ASN A 114 -34.376 -48.907 5.397 1.00 20.00 H +ATOM 1833 HB3 ASN A 114 -34.385 -50.129 6.713 1.00 20.00 H +ATOM 1834 HD21 ASN A 114 -36.378 -51.479 3.382 1.00 20.00 H +ATOM 1835 HD22 ASN A 114 -36.882 -50.046 4.214 1.00 20.00 H +ATOM 1836 N TRP A 115 -37.493 -49.653 8.464 1.00 48.06 N +ATOM 1837 CA TRP A 115 -38.294 -50.518 9.318 1.00 46.98 C +ATOM 1838 C TRP A 115 -39.759 -50.109 9.261 1.00 47.01 C +ATOM 1839 O TRP A 115 -40.087 -48.919 9.223 1.00 44.62 O +ATOM 1840 CB TRP A 115 -37.803 -50.559 10.777 1.00 50.09 C +ATOM 1841 CG TRP A 115 -37.618 -49.264 11.523 1.00 52.75 C +ATOM 1842 CD1 TRP A 115 -36.441 -48.600 11.712 1.00 51.52 C +ATOM 1843 CD2 TRP A 115 -38.614 -48.525 12.251 1.00 55.60 C +ATOM 1844 NE1 TRP A 115 -36.645 -47.480 12.478 1.00 50.61 N +ATOM 1845 CE2 TRP A 115 -37.968 -47.410 12.824 1.00 55.62 C +ATOM 1846 CE3 TRP A 115 -39.990 -48.687 12.457 1.00 51.08 C +ATOM 1847 CZ2 TRP A 115 -38.648 -46.461 13.586 1.00 56.26 C +ATOM 1848 CZ3 TRP A 115 -40.665 -47.739 13.218 1.00 53.54 C +ATOM 1849 CH2 TRP A 115 -39.992 -46.642 13.771 1.00 55.44 C +ATOM 1850 H TRP A 115 -37.389 -48.686 8.696 1.00 20.00 H +ATOM 1851 HA TRP A 115 -38.226 -51.543 8.925 1.00 20.00 H +ATOM 1852 HB2 TRP A 115 -38.531 -51.157 11.345 1.00 20.00 H +ATOM 1853 HB3 TRP A 115 -36.830 -51.071 10.775 1.00 20.00 H +ATOM 1854 HD1 TRP A 115 -35.486 -48.911 11.316 1.00 20.00 H +ATOM 1855 HE1 TRP A 115 -35.941 -46.821 12.741 1.00 20.00 H +ATOM 1856 HE3 TRP A 115 -40.515 -49.530 12.034 1.00 20.00 H +ATOM 1857 HZ2 TRP A 115 -38.133 -45.614 14.015 1.00 20.00 H +ATOM 1858 HZ3 TRP A 115 -41.726 -47.850 13.385 1.00 20.00 H +ATOM 1859 HH2 TRP A 115 -40.546 -45.923 14.356 1.00 20.00 H +ATOM 1860 N GLU A 116 -40.630 -51.117 9.239 1.00 53.31 N +ATOM 1861 CA GLU A 116 -42.065 -50.925 9.111 1.00 49.96 C +ATOM 1862 C GLU A 116 -42.819 -51.195 10.406 1.00 49.90 C +ATOM 1863 O GLU A 116 -44.053 -51.151 10.407 1.00 54.21 O +ATOM 1864 CB GLU A 116 -42.613 -51.820 7.990 1.00 54.82 C +ATOM 1865 CG GLU A 116 -42.153 -51.437 6.577 1.00 57.49 C +ATOM 1866 CD GLU A 116 -40.894 -52.170 6.124 1.00 59.40 C +ATOM 1867 OE1 GLU A 116 -40.723 -53.357 6.476 1.00 55.74 O +ATOM 1868 OE2 GLU A 116 -40.073 -51.551 5.413 1.00 67.99 O +ATOM 1869 H GLU A 116 -40.279 -52.051 9.314 1.00 20.00 H +ATOM 1870 HA GLU A 116 -42.255 -49.880 8.825 1.00 20.00 H +ATOM 1871 HB2 GLU A 116 -42.289 -52.853 8.187 1.00 20.00 H +ATOM 1872 HB3 GLU A 116 -43.711 -51.769 8.018 1.00 20.00 H +ATOM 1873 HG2 GLU A 116 -42.964 -51.671 5.872 1.00 20.00 H +ATOM 1874 HG3 GLU A 116 -41.951 -50.356 6.558 1.00 20.00 H +ATOM 1875 N GLY A 117 -42.118 -51.468 11.500 1.00 52.82 N +ATOM 1876 CA GLY A 117 -42.768 -51.731 12.771 1.00 47.94 C +ATOM 1877 C GLY A 117 -41.736 -51.844 13.870 1.00 49.50 C +ATOM 1878 O GLY A 117 -40.535 -51.667 13.647 1.00 46.32 O +ATOM 1879 H GLY A 117 -41.120 -51.493 11.447 1.00 20.00 H +ATOM 1880 HA2 GLY A 117 -43.458 -50.907 13.004 1.00 20.00 H +ATOM 1881 HA3 GLY A 117 -43.332 -52.673 12.703 1.00 20.00 H +ATOM 1882 N ILE A 118 -42.220 -52.148 15.073 1.00 49.96 N +ATOM 1883 CA ILE A 118 -41.374 -52.191 16.263 1.00 53.22 C +ATOM 1884 C ILE A 118 -41.658 -53.471 17.036 1.00 51.75 C +ATOM 1885 O ILE A 118 -42.822 -53.853 17.212 1.00 54.57 O +ATOM 1886 CB ILE A 118 -41.588 -50.965 17.175 1.00 54.89 C +ATOM 1887 CG1 ILE A 118 -41.191 -49.677 16.460 1.00 55.27 C +ATOM 1888 CG2 ILE A 118 -40.786 -51.099 18.461 1.00 52.47 C +ATOM 1889 CD1 ILE A 118 -41.216 -48.465 17.361 1.00 54.93 C +ATOM 1890 H ILE A 118 -43.194 -52.354 15.165 1.00 20.00 H +ATOM 1891 HA ILE A 118 -40.319 -52.203 15.953 1.00 20.00 H +ATOM 1892 HB ILE A 118 -42.656 -50.907 17.432 1.00 20.00 H +ATOM 1893 HG12 ILE A 118 -40.172 -49.797 16.063 1.00 20.00 H +ATOM 1894 HG13 ILE A 118 -41.891 -49.509 15.628 1.00 20.00 H +ATOM 1895 HG21 ILE A 118 -40.955 -50.215 19.093 1.00 20.00 H +ATOM 1896 HG22 ILE A 118 -41.107 -52.002 19.001 1.00 20.00 H +ATOM 1897 HG23 ILE A 118 -39.716 -51.178 18.219 1.00 20.00 H +ATOM 1898 HD11 ILE A 118 -40.921 -47.574 16.787 1.00 20.00 H +ATOM 1899 HD12 ILE A 118 -42.232 -48.325 17.759 1.00 20.00 H +ATOM 1900 HD13 ILE A 118 -40.513 -48.613 18.194 1.00 20.00 H +ATOM 1901 N LEU A 119 -40.597 -54.132 17.506 1.00 47.73 N +ATOM 1902 CA LEU A 119 -40.707 -55.291 18.389 1.00 48.33 C +ATOM 1903 C LEU A 119 -40.314 -54.837 19.790 1.00 48.99 C +ATOM 1904 O LEU A 119 -39.128 -54.724 20.108 1.00 48.70 O +ATOM 1905 CB LEU A 119 -39.827 -56.441 17.908 1.00 49.17 C +ATOM 1906 CG LEU A 119 -39.828 -57.690 18.790 1.00 48.01 C +ATOM 1907 CD1 LEU A 119 -41.246 -58.173 19.012 1.00 51.13 C +ATOM 1908 CD2 LEU A 119 -38.974 -58.797 18.185 1.00 50.65 C +ATOM 1909 H LEU A 119 -39.685 -53.819 17.241 1.00 20.00 H +ATOM 1910 HA LEU A 119 -41.751 -55.635 18.412 1.00 20.00 H +ATOM 1911 HB2 LEU A 119 -40.172 -56.735 16.906 1.00 20.00 H +ATOM 1912 HB3 LEU A 119 -38.793 -56.072 17.846 1.00 20.00 H +ATOM 1913 HG LEU A 119 -39.398 -57.420 19.766 1.00 20.00 H +ATOM 1914 HD11 LEU A 119 -41.233 -59.071 19.647 1.00 20.00 H +ATOM 1915 HD12 LEU A 119 -41.829 -57.382 19.507 1.00 20.00 H +ATOM 1916 HD13 LEU A 119 -41.706 -58.416 18.043 1.00 20.00 H +ATOM 1917 HD21 LEU A 119 -38.996 -59.679 18.842 1.00 20.00 H +ATOM 1918 HD22 LEU A 119 -39.371 -59.067 17.196 1.00 20.00 H +ATOM 1919 HD23 LEU A 119 -37.937 -58.444 18.080 1.00 20.00 H +ATOM 1920 N GLY A 120 -41.312 -54.571 20.626 1.00 47.28 N +ATOM 1921 CA GLY A 120 -41.053 -54.183 21.997 1.00 49.78 C +ATOM 1922 C GLY A 120 -40.744 -55.381 22.869 1.00 48.11 C +ATOM 1923 O GLY A 120 -41.611 -56.232 23.087 1.00 45.43 O +ATOM 1924 H GLY A 120 -42.256 -54.640 20.304 1.00 20.00 H +ATOM 1925 HA2 GLY A 120 -40.194 -53.496 22.017 1.00 20.00 H +ATOM 1926 HA3 GLY A 120 -41.941 -53.671 22.396 1.00 20.00 H +ATOM 1927 N LEU A 121 -39.513 -55.461 23.377 1.00 45.20 N +ATOM 1928 CA LEU A 121 -39.040 -56.633 24.103 1.00 45.03 C +ATOM 1929 C LEU A 121 -39.068 -56.464 25.617 1.00 46.39 C +ATOM 1930 O LEU A 121 -38.599 -57.355 26.331 1.00 46.69 O +ATOM 1931 CB LEU A 121 -37.617 -56.994 23.652 1.00 46.59 C +ATOM 1932 CG LEU A 121 -37.478 -57.460 22.199 1.00 46.63 C +ATOM 1933 CD1 LEU A 121 -36.022 -57.574 21.756 1.00 40.95 C +ATOM 1934 CD2 LEU A 121 -38.198 -58.786 22.004 1.00 50.66 C +ATOM 1935 H LEU A 121 -38.891 -54.687 23.255 1.00 20.00 H +ATOM 1936 HA LEU A 121 -39.691 -57.483 23.852 1.00 20.00 H +ATOM 1937 HB2 LEU A 121 -36.985 -56.103 23.783 1.00 20.00 H +ATOM 1938 HB3 LEU A 121 -37.251 -57.802 24.302 1.00 20.00 H +ATOM 1939 HG LEU A 121 -37.968 -56.712 21.558 1.00 20.00 H +ATOM 1940 HD11 LEU A 121 -35.982 -57.911 20.710 1.00 20.00 H +ATOM 1941 HD12 LEU A 121 -35.534 -56.592 21.844 1.00 20.00 H +ATOM 1942 HD13 LEU A 121 -35.500 -58.301 22.395 1.00 20.00 H +ATOM 1943 HD21 LEU A 121 -38.092 -59.111 20.958 1.00 20.00 H +ATOM 1944 HD22 LEU A 121 -37.758 -59.543 22.670 1.00 20.00 H +ATOM 1945 HD23 LEU A 121 -39.265 -58.663 22.243 1.00 20.00 H +ATOM 1946 N ALA A 122 -39.607 -55.361 26.130 1.00 49.79 N +ATOM 1947 CA ALA A 122 -39.695 -55.171 27.572 1.00 48.41 C +ATOM 1948 C ALA A 122 -40.911 -55.924 28.115 1.00 51.96 C +ATOM 1949 O ALA A 122 -41.520 -56.753 27.434 1.00 49.82 O +ATOM 1950 CB ALA A 122 -39.722 -53.684 27.911 1.00 43.90 C +ATOM 1951 H ALA A 122 -39.957 -54.652 25.517 1.00 20.00 H +ATOM 1952 HA ALA A 122 -38.798 -55.605 28.038 1.00 20.00 H +ATOM 1953 HB1 ALA A 122 -39.789 -53.557 29.002 1.00 20.00 H +ATOM 1954 HB2 ALA A 122 -38.802 -53.207 27.542 1.00 20.00 H +ATOM 1955 HB3 ALA A 122 -40.595 -53.215 27.434 1.00 20.00 H +ATOM 1956 N TYR A 123 -41.281 -55.636 29.357 1.00 45.33 N +ATOM 1957 CA TYR A 123 -42.249 -56.442 30.085 1.00 43.30 C +ATOM 1958 C TYR A 123 -43.664 -55.885 29.948 1.00 45.51 C +ATOM 1959 O TYR A 123 -43.881 -54.768 29.477 1.00 42.91 O +ATOM 1960 CB TYR A 123 -41.869 -56.523 31.560 1.00 38.96 C +ATOM 1961 CG TYR A 123 -40.562 -57.214 31.829 1.00 46.04 C +ATOM 1962 CD1 TYR A 123 -40.480 -58.598 31.839 1.00 43.44 C +ATOM 1963 CD2 TYR A 123 -39.416 -56.484 32.102 1.00 51.24 C +ATOM 1964 CE1 TYR A 123 -39.284 -59.239 32.100 1.00 44.55 C +ATOM 1965 CE2 TYR A 123 -38.216 -57.114 32.366 1.00 48.92 C +ATOM 1966 CZ TYR A 123 -38.155 -58.490 32.363 1.00 50.69 C +ATOM 1967 OH TYR A 123 -36.963 -59.132 32.629 1.00 52.45 O +ATOM 1968 H TYR A 123 -40.881 -54.838 29.808 1.00 20.00 H +ATOM 1969 HA TYR A 123 -42.244 -57.463 29.675 1.00 20.00 H +ATOM 1970 HB2 TYR A 123 -41.804 -55.498 31.955 1.00 20.00 H +ATOM 1971 HB3 TYR A 123 -42.663 -57.070 32.090 1.00 20.00 H +ATOM 1972 HD1 TYR A 123 -41.365 -59.184 31.640 1.00 20.00 H +ATOM 1973 HD2 TYR A 123 -39.462 -55.405 32.108 1.00 20.00 H +ATOM 1974 HE1 TYR A 123 -39.233 -60.318 32.098 1.00 20.00 H +ATOM 1975 HE2 TYR A 123 -37.331 -56.531 32.574 1.00 20.00 H +ATOM 1976 HH TYR A 123 -37.130 -59.907 33.153 1.00 20.00 H +ATOM 1977 N ALA A 124 -44.635 -56.673 30.417 1.00 50.57 N +ATOM 1978 CA ALA A 124 -46.036 -56.337 30.180 1.00 52.33 C +ATOM 1979 C ALA A 124 -46.437 -55.058 30.900 1.00 52.59 C +ATOM 1980 O ALA A 124 -47.375 -54.374 30.475 1.00 49.89 O +ATOM 1981 CB ALA A 124 -46.934 -57.498 30.605 1.00 53.64 C +ATOM 1982 H ALA A 124 -44.401 -57.497 30.933 1.00 20.00 H +ATOM 1983 HA ALA A 124 -46.182 -56.177 29.101 1.00 20.00 H +ATOM 1984 HB1 ALA A 124 -47.986 -57.234 30.422 1.00 20.00 H +ATOM 1985 HB2 ALA A 124 -46.674 -58.394 30.023 1.00 20.00 H +ATOM 1986 HB3 ALA A 124 -46.788 -57.701 31.676 1.00 20.00 H +ATOM 1987 N GLU A 125 -45.726 -54.704 31.977 1.00 50.64 N +ATOM 1988 CA GLU A 125 -46.155 -53.594 32.826 1.00 48.30 C +ATOM 1989 C GLU A 125 -46.263 -52.285 32.058 1.00 47.60 C +ATOM 1990 O GLU A 125 -47.029 -51.395 32.448 1.00 55.83 O +ATOM 1991 CB GLU A 125 -45.197 -53.429 34.010 1.00 57.48 C +ATOM 1992 CG GLU A 125 -45.823 -52.717 35.209 1.00 65.27 C +ATOM 1993 CD GLU A 125 -44.792 -52.243 36.209 1.00 69.33 C +ATOM 1994 OE1 GLU A 125 -44.155 -53.100 36.856 1.00 73.91 O +ATOM 1995 OE2 GLU A 125 -44.609 -51.013 36.328 1.00 66.97 O +ATOM 1996 H GLU A 125 -44.891 -55.205 32.204 1.00 20.00 H +ATOM 1997 HA GLU A 125 -47.150 -53.828 33.232 1.00 20.00 H +ATOM 1998 HB2 GLU A 125 -44.867 -54.428 34.332 1.00 20.00 H +ATOM 1999 HB3 GLU A 125 -44.327 -52.846 33.675 1.00 20.00 H +ATOM 2000 HG2 GLU A 125 -46.388 -51.846 34.846 1.00 20.00 H +ATOM 2001 HG3 GLU A 125 -46.509 -53.414 35.714 1.00 20.00 H +ATOM 2002 N ILE A 126 -45.519 -52.147 30.963 1.00 44.49 N +ATOM 2003 CA ILE A 126 -45.575 -50.946 30.147 1.00 46.63 C +ATOM 2004 C ILE A 126 -46.180 -51.212 28.771 1.00 48.36 C +ATOM 2005 O ILE A 126 -46.046 -50.386 27.866 1.00 46.98 O +ATOM 2006 CB ILE A 126 -44.181 -50.301 30.033 1.00 51.99 C +ATOM 2007 CG1 ILE A 126 -43.242 -51.201 29.238 1.00 53.08 C +ATOM 2008 CG2 ILE A 126 -43.606 -50.059 31.418 1.00 51.00 C +ATOM 2009 CD1 ILE A 126 -41.777 -50.920 29.479 1.00 57.52 C +ATOM 2010 H ILE A 126 -44.905 -52.889 30.695 1.00 20.00 H +ATOM 2011 HA ILE A 126 -46.226 -50.219 30.654 1.00 20.00 H +ATOM 2012 HB ILE A 126 -44.279 -49.337 29.512 1.00 20.00 H +ATOM 2013 HG12 ILE A 126 -43.445 -52.246 29.516 1.00 20.00 H +ATOM 2014 HG13 ILE A 126 -43.451 -51.060 28.167 1.00 20.00 H +ATOM 2015 HG21 ILE A 126 -42.611 -49.598 31.327 1.00 20.00 H +ATOM 2016 HG22 ILE A 126 -44.271 -49.386 31.979 1.00 20.00 H +ATOM 2017 HG23 ILE A 126 -43.519 -51.017 31.951 1.00 20.00 H +ATOM 2018 HD11 ILE A 126 -41.167 -51.606 28.873 1.00 20.00 H +ATOM 2019 HD12 ILE A 126 -41.551 -49.881 29.195 1.00 20.00 H +ATOM 2020 HD13 ILE A 126 -41.546 -51.067 30.544 1.00 20.00 H +ATOM 2021 N ALA A 127 -46.852 -52.348 28.593 1.00 49.78 N +ATOM 2022 CA ALA A 127 -47.554 -52.585 27.340 1.00 52.28 C +ATOM 2023 C ALA A 127 -48.800 -51.710 27.268 1.00 49.17 C +ATOM 2024 O ALA A 127 -49.457 -51.452 28.280 1.00 47.55 O +ATOM 2025 CB ALA A 127 -47.922 -54.062 27.199 1.00 49.54 C +ATOM 2026 H ALA A 127 -46.874 -53.036 29.318 1.00 20.00 H +ATOM 2027 HA ALA A 127 -46.895 -52.314 26.502 1.00 20.00 H +ATOM 2028 HB1 ALA A 127 -48.451 -54.220 26.247 1.00 20.00 H +ATOM 2029 HB2 ALA A 127 -47.006 -54.671 27.215 1.00 20.00 H +ATOM 2030 HB3 ALA A 127 -48.574 -54.359 28.034 1.00 20.00 H +ATOM 2031 N ARG A 128 -49.098 -51.215 26.068 1.00 56.11 N +ATOM 2032 CA ARG A 128 -50.337 -50.478 25.845 1.00 54.76 C +ATOM 2033 C ARG A 128 -51.361 -51.383 25.170 1.00 54.88 C +ATOM 2034 O ARG A 128 -51.002 -52.161 24.279 1.00 50.19 O +ATOM 2035 CB ARG A 128 -50.100 -49.245 24.968 1.00 54.94 C +ATOM 2036 CG ARG A 128 -49.106 -48.235 25.530 1.00 61.17 C +ATOM 2037 CD ARG A 128 -49.634 -47.564 26.782 1.00 64.34 C +ATOM 2038 NE ARG A 128 -50.724 -46.625 26.514 0.00 62.85 N +ATOM 2039 CZ ARG A 128 -50.561 -45.313 26.370 0.00 63.15 C +ATOM 2040 NH1 ARG A 128 -51.608 -44.534 26.135 0.00 63.49 N +ATOM 2041 NH2 ARG A 128 -49.350 -44.780 26.464 0.00 63.50 N +ATOM 2042 H ARG A 128 -48.462 -51.351 25.308 1.00 20.00 H +ATOM 2043 HA ARG A 128 -50.745 -50.146 26.811 1.00 20.00 H +ATOM 2044 HB2 ARG A 128 -49.724 -49.587 23.993 1.00 20.00 H +ATOM 2045 HB3 ARG A 128 -51.064 -48.734 24.830 1.00 20.00 H +ATOM 2046 HG2 ARG A 128 -48.168 -48.756 25.773 1.00 20.00 H +ATOM 2047 HG3 ARG A 128 -48.911 -47.465 24.769 1.00 20.00 H +ATOM 2048 HD2 ARG A 128 -50.002 -48.342 27.467 1.00 20.00 H +ATOM 2049 HD3 ARG A 128 -48.809 -47.015 27.260 1.00 20.00 H +ATOM 2050 HE ARG A 128 -51.650 -46.993 26.434 0.00 20.00 H +ATOM 2051 HH11 ARG A 128 -51.484 -43.547 26.029 0.00 20.00 H +ATOM 2052 HH12 ARG A 128 -52.522 -44.933 26.064 0.00 20.00 H +ATOM 2053 HH21 ARG A 128 -49.228 -43.793 26.358 0.00 20.00 H +ATOM 2054 HH22 ARG A 128 -48.559 -45.365 26.641 0.00 20.00 H +ATOM 2055 N PRO A 129 -52.656 -51.304 25.532 1.00 59.39 N +ATOM 2056 CA PRO A 129 -53.254 -50.356 26.482 1.00 59.08 C +ATOM 2057 C PRO A 129 -52.975 -50.664 27.961 1.00 59.82 C +ATOM 2058 O PRO A 129 -53.034 -49.740 28.777 1.00 68.01 O +ATOM 2059 CB PRO A 129 -54.754 -50.475 26.189 1.00 57.30 C +ATOM 2060 CG PRO A 129 -54.921 -51.853 25.663 1.00 52.54 C +ATOM 2061 CD PRO A 129 -53.683 -52.116 24.852 1.00 55.94 C +ATOM 2062 HA PRO A 129 -52.920 -49.333 26.256 1.00 20.00 H +ATOM 2063 HB2 PRO A 129 -55.342 -50.336 27.108 1.00 20.00 H +ATOM 2064 HB3 PRO A 129 -55.064 -49.732 25.439 1.00 20.00 H +ATOM 2065 HG2 PRO A 129 -55.002 -52.575 26.489 1.00 20.00 H +ATOM 2066 HG3 PRO A 129 -55.818 -51.918 25.030 1.00 20.00 H +ATOM 2067 HD2 PRO A 129 -53.418 -53.183 24.871 1.00 20.00 H +ATOM 2068 HD3 PRO A 129 -53.817 -51.790 23.810 1.00 20.00 H +ATOM 2069 N ASP A 130 -52.688 -51.919 28.299 1.00 56.31 N +ATOM 2070 CA ASP A 130 -52.343 -52.288 29.674 1.00 56.98 C +ATOM 2071 C ASP A 130 -51.612 -53.637 29.669 1.00 57.82 C +ATOM 2072 O ASP A 130 -51.280 -54.185 28.614 1.00 52.51 O +ATOM 2073 CB ASP A 130 -53.583 -52.320 30.566 1.00 62.31 C +ATOM 2074 CG ASP A 130 -54.677 -53.208 30.016 1.00 66.02 C +ATOM 2075 OD1 ASP A 130 -54.460 -54.428 29.884 1.00 70.08 O +ATOM 2076 OD2 ASP A 130 -55.769 -52.682 29.722 1.00 68.67 O +ATOM 2077 H ASP A 130 -52.708 -52.629 27.595 1.00 20.00 H +ATOM 2078 HA ASP A 130 -51.654 -51.533 30.080 1.00 20.00 H +ATOM 2079 HB2 ASP A 130 -53.292 -52.694 31.559 1.00 20.00 H +ATOM 2080 HB3 ASP A 130 -53.975 -51.297 30.660 1.00 20.00 H +ATOM 2081 N ASP A 131 -51.377 -54.178 30.873 1.00 63.20 N +ATOM 2082 CA ASP A 131 -50.557 -55.371 31.068 1.00 73.44 C +ATOM 2083 C ASP A 131 -51.290 -56.670 30.741 1.00 63.11 C +ATOM 2084 O ASP A 131 -50.681 -57.748 30.833 1.00 62.58 O +ATOM 2085 CB ASP A 131 -49.983 -55.401 32.508 1.00 75.80 C +ATOM 2086 CG ASP A 131 -51.020 -55.821 33.579 1.00 80.12 C +ATOM 2087 OD1 ASP A 131 -52.214 -56.017 33.237 1.00115.98 O +ATOM 2088 OD2 ASP A 131 -50.625 -55.966 34.758 1.00 76.43 O +ATOM 2089 H ASP A 131 -51.783 -53.743 31.677 1.00 20.00 H +ATOM 2090 HA ASP A 131 -49.697 -55.305 30.385 1.00 20.00 H +ATOM 2091 HB2 ASP A 131 -49.147 -56.115 32.534 1.00 20.00 H +ATOM 2092 HB3 ASP A 131 -49.614 -54.395 32.757 1.00 20.00 H +ATOM 2093 N SER A 132 -52.555 -56.596 30.293 1.00 86.87 N +ATOM 2094 CA SER A 132 -53.247 -57.793 29.838 1.00 57.17 C +ATOM 2095 C SER A 132 -52.867 -58.178 28.419 1.00 53.19 C +ATOM 2096 O SER A 132 -53.139 -59.314 28.004 1.00 51.22 O +ATOM 2097 CB SER A 132 -54.764 -57.607 29.916 1.00 58.28 C +ATOM 2098 OG SER A 132 -55.188 -56.531 29.090 1.00 56.09 O +ATOM 2099 H SER A 132 -53.024 -55.713 30.272 1.00 20.00 H +ATOM 2100 HA SER A 132 -52.977 -58.630 30.499 1.00 20.00 H +ATOM 2101 HB2 SER A 132 -55.257 -58.532 29.583 1.00 20.00 H +ATOM 2102 HB3 SER A 132 -55.047 -57.394 30.957 1.00 20.00 H +ATOM 2103 HG SER A 132 -55.050 -55.708 29.545 1.00 20.00 H +ATOM 2104 N LEU A 133 -52.261 -57.255 27.670 1.00 49.18 N +ATOM 2105 CA LEU A 133 -51.757 -57.532 26.328 1.00 48.82 C +ATOM 2106 C LEU A 133 -50.354 -58.103 26.459 1.00 55.70 C +ATOM 2107 O LEU A 133 -49.389 -57.374 26.707 1.00 59.81 O +ATOM 2108 CB LEU A 133 -51.744 -56.271 25.481 1.00 42.27 C +ATOM 2109 CG LEU A 133 -51.797 -56.578 23.987 1.00 48.96 C +ATOM 2110 CD1 LEU A 133 -53.223 -56.897 23.589 1.00 44.50 C +ATOM 2111 CD2 LEU A 133 -51.234 -55.446 23.155 1.00 53.40 C +ATOM 2112 H LEU A 133 -52.147 -56.334 28.044 1.00 20.00 H +ATOM 2113 HA LEU A 133 -52.399 -58.280 25.840 1.00 20.00 H +ATOM 2114 HB2 LEU A 133 -52.617 -55.657 25.747 1.00 20.00 H +ATOM 2115 HB3 LEU A 133 -50.822 -55.710 25.695 1.00 20.00 H +ATOM 2116 HG LEU A 133 -51.184 -57.473 23.804 1.00 20.00 H +ATOM 2117 HD11 LEU A 133 -53.263 -57.118 22.512 1.00 20.00 H +ATOM 2118 HD12 LEU A 133 -53.575 -57.771 24.156 1.00 20.00 H +ATOM 2119 HD13 LEU A 133 -53.867 -56.033 23.810 1.00 20.00 H +ATOM 2120 HD21 LEU A 133 -51.292 -55.710 22.089 1.00 20.00 H +ATOM 2121 HD22 LEU A 133 -51.817 -54.531 23.339 1.00 20.00 H +ATOM 2122 HD23 LEU A 133 -50.184 -55.274 23.433 1.00 20.00 H +ATOM 2123 N GLU A 134 -50.239 -59.409 26.310 1.00 49.65 N +ATOM 2124 CA GLU A 134 -48.981 -60.106 26.494 1.00 49.92 C +ATOM 2125 C GLU A 134 -47.987 -59.697 25.404 1.00 55.63 C +ATOM 2126 O GLU A 134 -48.358 -59.683 24.217 1.00 55.97 O +ATOM 2127 CB GLU A 134 -49.258 -61.605 26.468 1.00 51.56 C +ATOM 2128 CG GLU A 134 -48.079 -62.514 26.639 1.00 57.46 C +ATOM 2129 CD GLU A 134 -48.537 -63.942 26.833 1.00 60.87 C +ATOM 2130 OE1 GLU A 134 -48.378 -64.487 27.946 1.00 61.43 O +ATOM 2131 OE2 GLU A 134 -49.077 -64.514 25.864 1.00 60.24 O +ATOM 2132 H GLU A 134 -51.050 -59.938 26.061 1.00 20.00 H +ATOM 2133 HA GLU A 134 -48.554 -59.845 27.473 1.00 20.00 H +ATOM 2134 HB2 GLU A 134 -49.969 -61.826 27.278 1.00 20.00 H +ATOM 2135 HB3 GLU A 134 -49.722 -61.841 25.499 1.00 20.00 H +ATOM 2136 HG2 GLU A 134 -47.444 -62.456 25.743 1.00 20.00 H +ATOM 2137 HG3 GLU A 134 -47.501 -62.196 27.519 1.00 20.00 H +ATOM 2138 N PRO A 135 -46.754 -59.334 25.755 1.00 46.10 N +ATOM 2139 CA PRO A 135 -45.781 -58.953 24.725 1.00 43.31 C +ATOM 2140 C PRO A 135 -45.341 -60.157 23.909 1.00 43.31 C +ATOM 2141 O PRO A 135 -45.646 -61.307 24.228 1.00 48.02 O +ATOM 2142 CB PRO A 135 -44.609 -58.363 25.524 1.00 45.86 C +ATOM 2143 CG PRO A 135 -45.147 -58.102 26.899 1.00 45.16 C +ATOM 2144 CD PRO A 135 -46.208 -59.146 27.112 1.00 46.86 C +ATOM 2145 HA PRO A 135 -46.201 -58.183 24.060 1.00 20.00 H +ATOM 2146 HB2 PRO A 135 -43.775 -59.079 25.568 1.00 20.00 H +ATOM 2147 HB3 PRO A 135 -44.264 -57.426 25.063 1.00 20.00 H +ATOM 2148 HG2 PRO A 135 -44.350 -58.203 27.651 1.00 20.00 H +ATOM 2149 HG3 PRO A 135 -45.581 -57.093 26.958 1.00 20.00 H +ATOM 2150 HD2 PRO A 135 -46.983 -58.788 27.806 1.00 20.00 H +ATOM 2151 HD3 PRO A 135 -45.774 -60.080 27.498 1.00 20.00 H +ATOM 2152 N PHE A 136 -44.596 -59.874 22.839 1.00 49.18 N +ATOM 2153 CA PHE A 136 -44.208 -60.938 21.917 1.00 45.53 C +ATOM 2154 C PHE A 136 -43.362 -62.002 22.605 1.00 48.06 C +ATOM 2155 O PHE A 136 -43.620 -63.203 22.467 1.00 49.51 O +ATOM 2156 CB PHE A 136 -43.454 -60.358 20.719 1.00 49.40 C +ATOM 2157 CG PHE A 136 -42.898 -61.407 19.788 1.00 50.18 C +ATOM 2158 CD1 PHE A 136 -43.698 -61.976 18.806 1.00 51.21 C +ATOM 2159 CD2 PHE A 136 -41.576 -61.823 19.892 1.00 52.16 C +ATOM 2160 CE1 PHE A 136 -43.194 -62.941 17.957 1.00 53.61 C +ATOM 2161 CE2 PHE A 136 -41.069 -62.790 19.044 1.00 52.47 C +ATOM 2162 CZ PHE A 136 -41.880 -63.347 18.074 1.00 54.53 C +ATOM 2163 H PHE A 136 -44.303 -58.933 22.668 1.00 20.00 H +ATOM 2164 HA PHE A 136 -45.119 -61.424 21.538 1.00 20.00 H +ATOM 2165 HB2 PHE A 136 -44.145 -59.719 20.150 1.00 20.00 H +ATOM 2166 HB3 PHE A 136 -42.618 -59.750 21.096 1.00 20.00 H +ATOM 2167 HD1 PHE A 136 -44.726 -61.660 18.705 1.00 20.00 H +ATOM 2168 HD2 PHE A 136 -40.937 -61.385 20.645 1.00 20.00 H +ATOM 2169 HE1 PHE A 136 -43.828 -63.379 17.201 1.00 20.00 H +ATOM 2170 HE2 PHE A 136 -40.042 -63.109 19.139 1.00 20.00 H +ATOM 2171 HZ PHE A 136 -41.486 -64.100 17.407 1.00 20.00 H +ATOM 2172 N PHE A 137 -42.340 -61.578 23.348 1.00 46.92 N +ATOM 2173 CA PHE A 137 -41.395 -62.543 23.895 1.00 46.56 C +ATOM 2174 C PHE A 137 -42.044 -63.422 24.952 1.00 46.58 C +ATOM 2175 O PHE A 137 -41.746 -64.617 25.035 1.00 48.40 O +ATOM 2176 CB PHE A 137 -40.170 -61.829 24.468 1.00 43.42 C +ATOM 2177 CG PHE A 137 -38.958 -62.703 24.552 1.00 47.23 C +ATOM 2178 CD1 PHE A 137 -38.136 -62.871 23.451 1.00 52.02 C +ATOM 2179 CD2 PHE A 137 -38.659 -63.383 25.720 1.00 51.95 C +ATOM 2180 CE1 PHE A 137 -37.028 -63.689 23.517 1.00 53.97 C +ATOM 2181 CE2 PHE A 137 -37.547 -64.203 25.791 1.00 53.20 C +ATOM 2182 CZ PHE A 137 -36.733 -64.355 24.688 1.00 51.26 C +ATOM 2183 H PHE A 137 -42.222 -60.602 23.529 1.00 20.00 H +ATOM 2184 HA PHE A 137 -41.050 -63.196 23.080 1.00 20.00 H +ATOM 2185 HB2 PHE A 137 -39.935 -60.968 23.824 1.00 20.00 H +ATOM 2186 HB3 PHE A 137 -40.415 -61.474 25.480 1.00 20.00 H +ATOM 2187 HD1 PHE A 137 -38.365 -62.356 22.530 1.00 20.00 H +ATOM 2188 HD2 PHE A 137 -39.299 -63.272 26.583 1.00 20.00 H +ATOM 2189 HE1 PHE A 137 -36.392 -63.808 22.653 1.00 20.00 H +ATOM 2190 HE2 PHE A 137 -37.317 -64.723 26.709 1.00 20.00 H +ATOM 2191 HZ PHE A 137 -35.865 -64.995 24.741 1.00 20.00 H +ATOM 2192 N ASP A 138 -42.920 -62.850 25.778 1.00 45.59 N +ATOM 2193 CA ASP A 138 -43.678 -63.667 26.717 1.00 44.49 C +ATOM 2194 C ASP A 138 -44.416 -64.783 25.992 1.00 46.81 C +ATOM 2195 O ASP A 138 -44.387 -65.943 26.418 1.00 48.46 O +ATOM 2196 CB ASP A 138 -44.652 -62.794 27.505 1.00 48.32 C +ATOM 2197 CG ASP A 138 -43.957 -61.952 28.547 1.00 55.69 C +ATOM 2198 OD1 ASP A 138 -43.978 -62.334 29.739 1.00 60.94 O +ATOM 2199 OD2 ASP A 138 -43.364 -60.924 28.165 1.00 50.41 O +ATOM 2200 H ASP A 138 -43.057 -61.860 25.753 1.00 20.00 H +ATOM 2201 HA ASP A 138 -42.980 -64.128 27.432 1.00 20.00 H +ATOM 2202 HB2 ASP A 138 -45.175 -62.127 26.804 1.00 20.00 H +ATOM 2203 HB3 ASP A 138 -45.383 -63.445 28.007 1.00 20.00 H +ATOM 2204 N SER A 139 -45.056 -64.453 24.868 1.00 46.69 N +ATOM 2205 CA SER A 139 -45.813 -65.455 24.126 1.00 47.43 C +ATOM 2206 C SER A 139 -44.898 -66.487 23.481 1.00 48.00 C +ATOM 2207 O SER A 139 -45.238 -67.674 23.417 1.00 45.92 O +ATOM 2208 CB SER A 139 -46.677 -64.777 23.065 1.00 49.55 C +ATOM 2209 OG SER A 139 -47.694 -64.007 23.669 1.00 51.21 O +ATOM 2210 H SER A 139 -45.016 -63.512 24.532 1.00 20.00 H +ATOM 2211 HA SER A 139 -46.482 -65.982 24.822 1.00 20.00 H +ATOM 2212 HB2 SER A 139 -46.044 -64.121 22.449 1.00 20.00 H +ATOM 2213 HB3 SER A 139 -47.137 -65.547 22.428 1.00 20.00 H +ATOM 2214 HG SER A 139 -48.081 -64.498 24.384 1.00 20.00 H +ATOM 2215 N LEU A 140 -43.746 -66.049 22.971 1.00 49.03 N +ATOM 2216 CA LEU A 140 -42.818 -66.968 22.322 1.00 50.05 C +ATOM 2217 C LEU A 140 -42.324 -68.029 23.294 1.00 46.96 C +ATOM 2218 O LEU A 140 -42.267 -69.218 22.964 1.00 46.85 O +ATOM 2219 CB LEU A 140 -41.641 -66.188 21.740 1.00 52.57 C +ATOM 2220 CG LEU A 140 -40.516 -67.022 21.139 1.00 59.18 C +ATOM 2221 CD1 LEU A 140 -40.867 -67.454 19.727 1.00 60.66 C +ATOM 2222 CD2 LEU A 140 -39.225 -66.232 21.164 1.00 61.62 C +ATOM 2223 H LEU A 140 -43.516 -65.078 23.035 1.00 20.00 H +ATOM 2224 HA LEU A 140 -43.336 -67.475 21.494 1.00 20.00 H +ATOM 2225 HB2 LEU A 140 -42.032 -65.531 20.949 1.00 20.00 H +ATOM 2226 HB3 LEU A 140 -41.212 -65.576 22.547 1.00 20.00 H +ATOM 2227 HG LEU A 140 -40.385 -67.923 21.756 1.00 20.00 H +ATOM 2228 HD11 LEU A 140 -40.044 -68.054 19.311 1.00 20.00 H +ATOM 2229 HD12 LEU A 140 -41.787 -68.057 19.746 1.00 20.00 H +ATOM 2230 HD13 LEU A 140 -41.025 -66.564 19.100 1.00 20.00 H +ATOM 2231 HD21 LEU A 140 -38.416 -66.837 20.729 1.00 20.00 H +ATOM 2232 HD22 LEU A 140 -39.348 -65.310 20.577 1.00 20.00 H +ATOM 2233 HD23 LEU A 140 -38.973 -65.975 22.203 1.00 20.00 H +ATOM 2234 N VAL A 141 -41.965 -67.610 24.506 1.00 47.46 N +ATOM 2235 CA VAL A 141 -41.437 -68.547 25.493 1.00 47.42 C +ATOM 2236 C VAL A 141 -42.516 -69.523 25.949 1.00 48.27 C +ATOM 2237 O VAL A 141 -42.264 -70.725 26.095 1.00 52.02 O +ATOM 2238 CB VAL A 141 -40.822 -67.781 26.678 1.00 46.92 C +ATOM 2239 CG1 VAL A 141 -40.595 -68.714 27.856 1.00 46.89 C +ATOM 2240 CG2 VAL A 141 -39.522 -67.130 26.249 1.00 45.80 C +ATOM 2241 H VAL A 141 -42.058 -66.643 24.743 1.00 20.00 H +ATOM 2242 HA VAL A 141 -40.633 -69.133 25.024 1.00 20.00 H +ATOM 2243 HB VAL A 141 -41.526 -66.993 26.985 1.00 20.00 H +ATOM 2244 HG11 VAL A 141 -40.156 -68.150 28.692 1.00 20.00 H +ATOM 2245 HG12 VAL A 141 -41.556 -69.147 28.171 1.00 20.00 H +ATOM 2246 HG13 VAL A 141 -39.909 -69.521 27.558 1.00 20.00 H +ATOM 2247 HG21 VAL A 141 -39.087 -66.584 27.099 1.00 20.00 H +ATOM 2248 HG22 VAL A 141 -38.818 -67.905 25.912 1.00 20.00 H +ATOM 2249 HG23 VAL A 141 -39.718 -66.429 25.425 1.00 20.00 H +ATOM 2250 N LYS A 142 -43.731 -69.028 26.183 1.00 52.82 N +ATOM 2251 CA LYS A 142 -44.802 -69.905 26.647 1.00 54.66 C +ATOM 2252 C LYS A 142 -45.173 -70.950 25.600 1.00 53.12 C +ATOM 2253 O LYS A 142 -45.494 -72.094 25.943 1.00 52.97 O +ATOM 2254 CB LYS A 142 -46.033 -69.083 27.027 1.00 56.66 C +ATOM 2255 CG LYS A 142 -45.926 -68.343 28.349 1.00 59.02 C +ATOM 2256 CD LYS A 142 -47.288 -67.791 28.741 1.00 64.72 C +ATOM 2257 CE LYS A 142 -47.212 -66.857 29.937 1.00 69.64 C +ATOM 2258 NZ LYS A 142 -46.577 -65.553 29.594 1.00 75.13 N +ATOM 2259 H LYS A 142 -43.909 -68.054 26.041 1.00 20.00 H +ATOM 2260 HA LYS A 142 -44.459 -70.435 27.548 1.00 20.00 H +ATOM 2261 HB2 LYS A 142 -46.207 -68.341 26.233 1.00 20.00 H +ATOM 2262 HB3 LYS A 142 -46.894 -69.765 27.086 1.00 20.00 H +ATOM 2263 HG2 LYS A 142 -45.575 -69.036 29.128 1.00 20.00 H +ATOM 2264 HG3 LYS A 142 -45.211 -67.513 28.246 1.00 20.00 H +ATOM 2265 HD2 LYS A 142 -47.704 -67.237 27.886 1.00 20.00 H +ATOM 2266 HD3 LYS A 142 -47.951 -68.632 28.991 1.00 20.00 H +ATOM 2267 HE2 LYS A 142 -48.231 -66.669 30.305 1.00 20.00 H +ATOM 2268 HE3 LYS A 142 -46.621 -67.342 30.728 1.00 20.00 H +ATOM 2269 HZ1 LYS A 142 -46.437 -65.020 30.429 1.00 20.00 H +ATOM 2270 HZ2 LYS A 142 -45.695 -65.718 29.152 1.00 20.00 H +ATOM 2271 HZ3 LYS A 142 -47.173 -65.046 28.971 1.00 20.00 H +ATOM 2272 N GLN A 143 -45.133 -70.579 24.318 1.00 53.70 N +ATOM 2273 CA GLN A 143 -45.636 -71.466 23.273 1.00 52.26 C +ATOM 2274 C GLN A 143 -44.581 -72.444 22.776 1.00 56.15 C +ATOM 2275 O GLN A 143 -44.930 -73.482 22.203 1.00 53.11 O +ATOM 2276 CB GLN A 143 -46.181 -70.640 22.104 1.00 51.60 C +ATOM 2277 CG GLN A 143 -47.472 -69.895 22.419 1.00 49.52 C +ATOM 2278 CD GLN A 143 -47.888 -68.949 21.308 1.00 51.05 C +ATOM 2279 OE1 GLN A 143 -47.733 -69.254 20.125 1.00 50.85 O +ATOM 2280 NE2 GLN A 143 -48.414 -67.790 21.685 1.00 39.97 N +ATOM 2281 H GLN A 143 -44.756 -69.686 24.072 1.00 20.00 H +ATOM 2282 HA GLN A 143 -46.471 -72.053 23.684 1.00 20.00 H +ATOM 2283 HB2 GLN A 143 -45.417 -69.902 21.816 1.00 20.00 H +ATOM 2284 HB3 GLN A 143 -46.371 -71.319 21.260 1.00 20.00 H +ATOM 2285 HG2 GLN A 143 -48.275 -70.631 22.573 1.00 20.00 H +ATOM 2286 HG3 GLN A 143 -47.326 -69.313 23.341 1.00 20.00 H +ATOM 2287 HE21 GLN A 143 -48.702 -67.124 20.997 1.00 20.00 H +ATOM 2288 HE22 GLN A 143 -48.522 -67.583 22.657 1.00 20.00 H +ATOM 2289 N THR A 144 -43.307 -72.142 22.982 1.00 52.07 N +ATOM 2290 CA THR A 144 -42.207 -72.965 22.500 1.00 55.02 C +ATOM 2291 C THR A 144 -41.348 -73.429 23.672 1.00 57.21 C +ATOM 2292 O THR A 144 -41.674 -73.214 24.842 1.00 58.97 O +ATOM 2293 CB THR A 144 -41.355 -72.195 21.488 1.00 55.70 C +ATOM 2294 OG1 THR A 144 -40.722 -71.094 22.151 1.00 53.03 O +ATOM 2295 CG2 THR A 144 -42.221 -71.661 20.367 1.00 58.21 C +ATOM 2296 H THR A 144 -43.091 -71.310 23.493 1.00 20.00 H +ATOM 2297 HA THR A 144 -42.615 -73.855 21.999 1.00 20.00 H +ATOM 2298 HB THR A 144 -40.598 -72.874 21.068 1.00 20.00 H +ATOM 2299 HG1 THR A 144 -41.363 -70.628 22.674 1.00 20.00 H +ATOM 2300 HG21 THR A 144 -41.595 -71.111 19.649 1.00 20.00 H +ATOM 2301 HG22 THR A 144 -42.716 -72.499 19.855 1.00 20.00 H +ATOM 2302 HG23 THR A 144 -42.982 -70.985 20.782 1.00 20.00 H +ATOM 2303 N HIS A 145 -40.232 -74.074 23.334 1.00 54.11 N +ATOM 2304 CA HIS A 145 -39.227 -74.472 24.309 1.00 61.60 C +ATOM 2305 C HIS A 145 -38.047 -73.510 24.348 1.00 58.30 C +ATOM 2306 O HIS A 145 -36.966 -73.883 24.819 1.00 61.93 O +ATOM 2307 CB HIS A 145 -38.738 -75.891 24.018 1.00 66.56 C +ATOM 2308 CG HIS A 145 -39.740 -76.954 24.343 1.00 72.35 C +ATOM 2309 ND1 HIS A 145 -40.578 -77.503 23.397 1.00 74.15 N +ATOM 2310 CD2 HIS A 145 -40.040 -77.564 25.513 1.00 73.78 C +ATOM 2311 CE1 HIS A 145 -41.349 -78.410 23.970 1.00 73.67 C +ATOM 2312 NE2 HIS A 145 -41.044 -78.466 25.254 1.00 74.52 N +ATOM 2313 H HIS A 145 -40.078 -74.294 22.371 1.00 20.00 H +ATOM 2314 HA HIS A 145 -39.689 -74.476 25.307 1.00 20.00 H +ATOM 2315 HB2 HIS A 145 -38.493 -75.961 22.948 1.00 20.00 H +ATOM 2316 HB3 HIS A 145 -37.832 -76.075 24.614 1.00 20.00 H +ATOM 2317 HD1 HIS A 145 -40.599 -77.254 22.429 1.00 20.00 H +ATOM 2318 HD2 HIS A 145 -39.577 -77.377 26.471 1.00 20.00 H +ATOM 2319 HE1 HIS A 145 -42.101 -79.005 23.473 1.00 20.00 H +ATOM 2320 N VAL A 146 -38.232 -72.292 23.859 1.00 54.32 N +ATOM 2321 CA VAL A 146 -37.138 -71.314 23.805 1.00 54.50 C +ATOM 2322 C VAL A 146 -36.826 -70.830 25.212 1.00 52.99 C +ATOM 2323 O VAL A 146 -37.748 -70.429 25.947 1.00 55.93 O +ATOM 2324 CB VAL A 146 -37.516 -70.149 22.891 1.00 59.39 C +ATOM 2325 CG1 VAL A 146 -36.505 -69.027 23.018 1.00 55.56 C +ATOM 2326 CG2 VAL A 146 -37.622 -70.621 21.446 1.00 61.41 C +ATOM 2327 H VAL A 146 -39.136 -72.033 23.519 1.00 20.00 H +ATOM 2328 HA VAL A 146 -36.240 -71.799 23.396 1.00 20.00 H +ATOM 2329 HB VAL A 146 -38.500 -69.769 23.204 1.00 20.00 H +ATOM 2330 HG11 VAL A 146 -36.792 -68.198 22.355 1.00 20.00 H +ATOM 2331 HG12 VAL A 146 -36.480 -68.672 24.059 1.00 20.00 H +ATOM 2332 HG13 VAL A 146 -35.509 -69.397 22.733 1.00 20.00 H +ATOM 2333 HG21 VAL A 146 -37.894 -69.772 20.802 1.00 20.00 H +ATOM 2334 HG22 VAL A 146 -36.654 -71.031 21.122 1.00 20.00 H +ATOM 2335 HG23 VAL A 146 -38.394 -71.401 21.371 1.00 20.00 H +ATOM 2336 N PRO A 147 -35.563 -70.847 25.641 1.00 64.38 N +ATOM 2337 CA PRO A 147 -35.229 -70.340 26.975 1.00 51.54 C +ATOM 2338 C PRO A 147 -35.604 -68.873 27.127 1.00 45.03 C +ATOM 2339 O PRO A 147 -35.539 -68.092 26.176 1.00 50.56 O +ATOM 2340 CB PRO A 147 -33.715 -70.547 27.065 1.00 47.57 C +ATOM 2341 CG PRO A 147 -33.449 -71.694 26.146 1.00 47.45 C +ATOM 2342 CD PRO A 147 -34.414 -71.515 25.002 1.00 55.55 C +ATOM 2343 HA PRO A 147 -35.731 -70.935 27.752 1.00 20.00 H +ATOM 2344 HB2 PRO A 147 -33.177 -69.647 26.732 1.00 20.00 H +ATOM 2345 HB3 PRO A 147 -33.415 -70.794 28.094 1.00 20.00 H +ATOM 2346 HG2 PRO A 147 -32.411 -71.665 25.783 1.00 20.00 H +ATOM 2347 HG3 PRO A 147 -33.632 -72.650 26.659 1.00 20.00 H +ATOM 2348 HD2 PRO A 147 -34.707 -72.486 24.576 1.00 20.00 H +ATOM 2349 HD3 PRO A 147 -33.979 -70.885 24.212 1.00 20.00 H +ATOM 2350 N ASN A 148 -36.006 -68.509 28.345 1.00 42.82 N +ATOM 2351 CA ASN A 148 -36.484 -67.161 28.650 1.00 43.61 C +ATOM 2352 C ASN A 148 -35.297 -66.198 28.725 1.00 44.22 C +ATOM 2353 O ASN A 148 -34.923 -65.692 29.784 1.00 48.44 O +ATOM 2354 CB ASN A 148 -37.284 -67.176 29.945 1.00 45.23 C +ATOM 2355 CG ASN A 148 -38.023 -65.880 30.191 1.00 47.11 C +ATOM 2356 OD1 ASN A 148 -38.181 -65.058 29.287 1.00 41.99 O +ATOM 2357 ND2 ASN A 148 -38.490 -65.692 31.420 1.00 46.06 N +ATOM 2358 H ASN A 148 -35.980 -69.186 29.081 1.00 20.00 H +ATOM 2359 HA ASN A 148 -37.147 -66.824 27.840 1.00 20.00 H +ATOM 2360 HB2 ASN A 148 -38.017 -67.995 29.896 1.00 20.00 H +ATOM 2361 HB3 ASN A 148 -36.593 -67.352 30.783 1.00 20.00 H +ATOM 2362 HD21 ASN A 148 -38.993 -64.856 31.642 1.00 20.00 H +ATOM 2363 HD22 ASN A 148 -38.339 -66.386 32.124 1.00 20.00 H +ATOM 2364 N LEU A 149 -34.711 -65.935 27.558 1.00 42.00 N +ATOM 2365 CA LEU A 149 -33.481 -65.158 27.468 1.00 44.20 C +ATOM 2366 C LEU A 149 -33.276 -64.719 26.026 1.00 40.76 C +ATOM 2367 O LEU A 149 -33.540 -65.485 25.099 1.00 39.48 O +ATOM 2368 CB LEU A 149 -32.276 -65.985 27.952 1.00 45.83 C +ATOM 2369 CG LEU A 149 -30.831 -65.462 28.002 1.00 47.94 C +ATOM 2370 CD1 LEU A 149 -29.990 -66.378 28.883 1.00 48.66 C +ATOM 2371 CD2 LEU A 149 -30.175 -65.345 26.629 1.00 53.89 C +ATOM 2372 H LEU A 149 -35.128 -66.281 26.718 1.00 20.00 H +ATOM 2373 HA LEU A 149 -33.565 -64.262 28.101 1.00 20.00 H +ATOM 2374 HB2 LEU A 149 -32.518 -66.288 28.982 1.00 20.00 H +ATOM 2375 HB3 LEU A 149 -32.248 -66.874 27.306 1.00 20.00 H +ATOM 2376 HG LEU A 149 -30.846 -64.463 28.461 1.00 20.00 H +ATOM 2377 HD11 LEU A 149 -28.956 -66.005 28.919 1.00 20.00 H +ATOM 2378 HD12 LEU A 149 -30.410 -66.395 29.900 1.00 20.00 H +ATOM 2379 HD13 LEU A 149 -29.998 -67.396 28.466 1.00 20.00 H +ATOM 2380 HD21 LEU A 149 -29.149 -64.967 26.744 1.00 20.00 H +ATOM 2381 HD22 LEU A 149 -30.149 -66.335 26.149 1.00 20.00 H +ATOM 2382 HD23 LEU A 149 -30.754 -64.649 26.004 1.00 20.00 H +ATOM 2383 N PHE A 150 -32.802 -63.489 25.844 1.00 41.08 N +ATOM 2384 CA PHE A 150 -32.287 -63.057 24.553 1.00 42.35 C +ATOM 2385 C PHE A 150 -31.067 -62.178 24.787 1.00 44.61 C +ATOM 2386 O PHE A 150 -30.841 -61.671 25.886 1.00 46.36 O +ATOM 2387 CB PHE A 150 -33.349 -62.327 23.703 1.00 40.41 C +ATOM 2388 CG PHE A 150 -33.805 -61.009 24.270 1.00 40.71 C +ATOM 2389 CD1 PHE A 150 -34.873 -60.951 25.149 1.00 45.53 C +ATOM 2390 CD2 PHE A 150 -33.186 -59.825 23.900 1.00 41.43 C +ATOM 2391 CE1 PHE A 150 -35.303 -59.742 25.664 1.00 47.27 C +ATOM 2392 CE2 PHE A 150 -33.609 -58.615 24.413 1.00 42.14 C +ATOM 2393 CZ PHE A 150 -34.669 -58.573 25.296 1.00 44.96 C +ATOM 2394 H PHE A 150 -32.800 -62.847 26.611 1.00 20.00 H +ATOM 2395 HA PHE A 150 -31.961 -63.943 23.989 1.00 20.00 H +ATOM 2396 HB2 PHE A 150 -32.923 -62.143 22.705 1.00 20.00 H +ATOM 2397 HB3 PHE A 150 -34.227 -62.984 23.612 1.00 20.00 H +ATOM 2398 HD1 PHE A 150 -35.377 -61.862 25.436 1.00 20.00 H +ATOM 2399 HD2 PHE A 150 -32.362 -59.849 23.202 1.00 20.00 H +ATOM 2400 HE1 PHE A 150 -36.134 -59.713 26.353 1.00 20.00 H +ATOM 2401 HE2 PHE A 150 -33.111 -57.702 24.124 1.00 20.00 H +ATOM 2402 HZ PHE A 150 -35.001 -57.627 25.698 1.00 20.00 H +ATOM 2403 N SER A 151 -30.268 -62.021 23.738 1.00 42.68 N +ATOM 2404 CA SER A 151 -29.027 -61.270 23.822 1.00 48.46 C +ATOM 2405 C SER A 151 -28.860 -60.442 22.558 1.00 44.77 C +ATOM 2406 O SER A 151 -29.254 -60.861 21.468 1.00 44.97 O +ATOM 2407 CB SER A 151 -27.823 -62.201 24.022 1.00 41.44 C +ATOM 2408 OG SER A 151 -27.693 -63.104 22.939 1.00 45.25 O +ATOM 2409 H SER A 151 -30.528 -62.432 22.864 1.00 20.00 H +ATOM 2410 HA SER A 151 -29.076 -60.584 24.681 1.00 20.00 H +ATOM 2411 HB2 SER A 151 -26.908 -61.595 24.096 1.00 20.00 H +ATOM 2412 HB3 SER A 151 -27.961 -62.772 24.952 1.00 20.00 H +ATOM 2413 HG SER A 151 -28.050 -63.949 23.186 1.00 20.00 H +ATOM 2414 N LEU A 152 -28.270 -59.259 22.717 1.00 44.19 N +ATOM 2415 CA LEU A 152 -28.136 -58.292 21.635 1.00 43.53 C +ATOM 2416 C LEU A 152 -26.680 -57.896 21.451 1.00 43.31 C +ATOM 2417 O LEU A 152 -26.016 -57.496 22.412 1.00 46.14 O +ATOM 2418 CB LEU A 152 -28.973 -57.042 21.912 1.00 44.02 C +ATOM 2419 CG LEU A 152 -30.487 -57.230 21.871 1.00 43.57 C +ATOM 2420 CD1 LEU A 152 -31.194 -55.891 21.973 1.00 45.02 C +ATOM 2421 CD2 LEU A 152 -30.859 -57.935 20.590 1.00 39.12 C +ATOM 2422 H LEU A 152 -27.903 -59.024 23.617 1.00 20.00 H +ATOM 2423 HA LEU A 152 -28.493 -58.745 20.698 1.00 20.00 H +ATOM 2424 HB2 LEU A 152 -28.706 -56.673 22.913 1.00 20.00 H +ATOM 2425 HB3 LEU A 152 -28.707 -56.285 21.160 1.00 20.00 H +ATOM 2426 HG LEU A 152 -30.788 -57.856 22.724 1.00 20.00 H +ATOM 2427 HD11 LEU A 152 -32.282 -56.047 21.942 1.00 20.00 H +ATOM 2428 HD12 LEU A 152 -30.921 -55.403 22.920 1.00 20.00 H +ATOM 2429 HD13 LEU A 152 -30.891 -55.251 21.131 1.00 20.00 H +ATOM 2430 HD21 LEU A 152 -31.949 -58.075 20.551 1.00 20.00 H +ATOM 2431 HD22 LEU A 152 -30.537 -57.328 19.731 1.00 20.00 H +ATOM 2432 HD23 LEU A 152 -30.362 -58.916 20.554 1.00 20.00 H +ATOM 2433 N GLN A 153 -26.196 -57.992 20.215 1.00 41.47 N +ATOM 2434 CA GLN A 153 -24.906 -57.442 19.814 1.00 51.11 C +ATOM 2435 C GLN A 153 -25.162 -56.416 18.716 1.00 48.13 C +ATOM 2436 O GLN A 153 -25.475 -56.788 17.582 1.00 46.19 O +ATOM 2437 CB GLN A 153 -23.967 -58.547 19.329 1.00 51.71 C +ATOM 2438 CG GLN A 153 -22.534 -58.095 19.074 1.00 51.19 C +ATOM 2439 CD GLN A 153 -21.837 -58.927 18.011 1.00 51.88 C +ATOM 2440 OE1 GLN A 153 -22.424 -59.244 16.974 1.00 60.43 O +ATOM 2441 NE2 GLN A 153 -20.583 -59.288 18.264 1.00 47.13 N +ATOM 2442 H GLN A 153 -26.745 -58.465 19.526 1.00 20.00 H +ATOM 2443 HA GLN A 153 -24.439 -56.934 20.670 1.00 20.00 H +ATOM 2444 HB2 GLN A 153 -23.946 -59.339 20.092 1.00 20.00 H +ATOM 2445 HB3 GLN A 153 -24.371 -58.953 18.390 1.00 20.00 H +ATOM 2446 HG2 GLN A 153 -22.549 -57.045 18.745 1.00 20.00 H +ATOM 2447 HG3 GLN A 153 -21.967 -58.177 20.013 1.00 20.00 H +ATOM 2448 HE21 GLN A 153 -20.078 -59.839 17.600 1.00 20.00 H +ATOM 2449 HE22 GLN A 153 -20.145 -59.009 19.118 1.00 20.00 H +ATOM 2450 N LEU A 154 -25.056 -55.130 19.054 1.00 48.80 N +ATOM 2451 CA LEU A 154 -25.202 -54.044 18.089 1.00 49.34 C +ATOM 2452 C LEU A 154 -23.815 -53.524 17.732 1.00 46.37 C +ATOM 2453 O LEU A 154 -23.065 -53.099 18.618 1.00 41.03 O +ATOM 2454 CB LEU A 154 -26.068 -52.917 18.651 1.00 48.05 C +ATOM 2455 CG LEU A 154 -27.347 -53.318 19.390 1.00 46.72 C +ATOM 2456 CD1 LEU A 154 -28.003 -52.098 20.013 1.00 47.86 C +ATOM 2457 CD2 LEU A 154 -28.306 -54.036 18.452 1.00 39.92 C +ATOM 2458 H LEU A 154 -24.869 -54.900 20.009 1.00 20.00 H +ATOM 2459 HA LEU A 154 -25.678 -54.428 17.175 1.00 20.00 H +ATOM 2460 HB2 LEU A 154 -25.447 -52.341 19.353 1.00 20.00 H +ATOM 2461 HB3 LEU A 154 -26.361 -52.273 17.808 1.00 20.00 H +ATOM 2462 HG LEU A 154 -27.072 -54.012 20.198 1.00 20.00 H +ATOM 2463 HD11 LEU A 154 -28.920 -52.403 20.540 1.00 20.00 H +ATOM 2464 HD12 LEU A 154 -27.308 -51.632 20.727 1.00 20.00 H +ATOM 2465 HD13 LEU A 154 -28.257 -51.375 19.224 1.00 20.00 H +ATOM 2466 HD21 LEU A 154 -29.217 -54.315 19.002 1.00 20.00 H +ATOM 2467 HD22 LEU A 154 -28.571 -53.369 17.618 1.00 20.00 H +ATOM 2468 HD23 LEU A 154 -27.823 -54.943 18.058 1.00 20.00 H +ATOM 2469 N CYS A 155 -23.483 -53.538 16.439 1.00 50.72 N +ATOM 2470 CA CYS A 155 -22.088 -53.365 16.048 1.00 58.09 C +ATOM 2471 C CYS A 155 -21.714 -51.919 15.735 1.00 69.11 C +ATOM 2472 O CYS A 155 -20.612 -51.480 16.084 1.00 70.64 O +ATOM 2473 CB CYS A 155 -21.769 -54.268 14.855 1.00 54.50 C +ATOM 2474 SG CYS A 155 -21.705 -56.018 15.318 1.00 52.31 S +ATOM 2475 H CYS A 155 -24.188 -53.667 15.741 1.00 20.00 H +ATOM 2476 HA CYS A 155 -21.454 -53.693 16.885 1.00 20.00 H +ATOM 2477 HB2 CYS A 155 -22.548 -54.132 14.090 1.00 20.00 H +ATOM 2478 HB3 CYS A 155 -20.793 -53.975 14.441 1.00 20.00 H +ATOM 2479 N GLY A 156 -22.600 -51.200 14.978 1.00 71.19 N +ATOM 2480 CA GLY A 156 -22.309 -49.806 14.721 1.00 78.77 C +ATOM 2481 C GLY A 156 -21.360 -49.613 13.554 1.00 83.83 C +ATOM 2482 O GLY A 156 -20.842 -50.518 12.890 1.00 88.63 O +ATOM 2483 H GLY A 156 -23.427 -51.627 14.612 1.00 20.00 H +ATOM 2484 HA2 GLY A 156 -23.252 -49.285 14.498 1.00 20.00 H +ATOM 2485 HA3 GLY A 156 -21.854 -49.369 15.622 1.00 20.00 H +ATOM 2486 N ALA A 157 -21.167 -48.263 13.319 0.00 99.99 N +ATOM 2487 CA ALA A 157 -20.290 -47.810 12.287 0.00 99.99 C +ATOM 2488 C ALA A 157 -18.892 -47.348 12.625 0.00 99.99 C +ATOM 2489 O ALA A 157 -18.589 -46.871 13.721 0.00 99.99 O +ATOM 2490 CB ALA A 157 -20.809 -47.768 10.878 0.00 99.99 C +ATOM 2491 H ALA A 157 -21.650 -47.593 13.882 0.00 20.00 H +ATOM 2492 HA ALA A 157 -19.924 -48.835 12.132 0.00 20.00 H +ATOM 2493 HB1 ALA A 157 -20.020 -47.399 10.206 0.00 20.00 H +ATOM 2494 HB2 ALA A 157 -21.111 -48.780 10.568 0.00 20.00 H +ATOM 2495 HB3 ALA A 157 -21.678 -47.095 10.827 0.00 20.00 H +ATOM 2496 N GLY A 158 -18.004 -47.471 11.573 0.00 99.99 N +ATOM 2497 CA GLY A 158 -16.651 -47.002 11.779 0.00 99.99 C +ATOM 2498 C GLY A 158 -15.859 -47.086 10.494 0.00 99.99 C +ATOM 2499 O GLY A 158 -16.088 -47.853 9.559 0.00 99.99 O +ATOM 2500 H GLY A 158 -18.287 -47.870 10.701 0.00 20.00 H +ATOM 2501 HA2 GLY A 158 -16.678 -45.956 12.119 0.00 20.00 H +ATOM 2502 HA3 GLY A 158 -16.165 -47.624 12.545 0.00 20.00 H +ATOM 2503 N PHE A 159 -14.780 -46.223 10.547 0.00 99.99 N +ATOM 2504 CA PHE A 159 -13.845 -46.160 9.462 0.00 99.99 C +ATOM 2505 C PHE A 159 -13.012 -47.376 9.114 0.00 99.99 C +ATOM 2506 O PHE A 159 -12.491 -48.066 10.002 0.00 99.99 O +ATOM 2507 CB PHE A 159 -13.392 -44.808 8.985 0.00 99.99 C +ATOM 2508 CG PHE A 159 -14.375 -44.007 8.200 0.00 99.99 C +ATOM 2509 CD1 PHE A 159 -14.043 -43.603 6.909 0.00 99.99 C +ATOM 2510 CD2 PHE A 159 -15.582 -43.598 8.762 0.00 99.99 C +ATOM 2511 CE1 PHE A 159 -14.939 -42.833 6.167 0.00 99.99 C +ATOM 2512 CE2 PHE A 159 -16.472 -42.818 8.033 0.00 99.99 C +ATOM 2513 CZ PHE A 159 -16.156 -42.442 6.731 0.00 99.99 C +ATOM 2514 H PHE A 159 -14.650 -45.640 11.348 0.00 20.00 H +ATOM 2515 HA PHE A 159 -14.589 -46.310 8.665 0.00 20.00 H +ATOM 2516 HB2 PHE A 159 -13.115 -44.218 9.872 0.00 20.00 H +ATOM 2517 HB3 PHE A 159 -12.505 -44.958 8.352 0.00 20.00 H +ATOM 2518 HD1 PHE A 159 -13.093 -43.887 6.481 0.00 20.00 H +ATOM 2519 HD2 PHE A 159 -15.828 -43.889 9.773 0.00 20.00 H +ATOM 2520 HE1 PHE A 159 -14.693 -42.540 5.157 0.00 20.00 H +ATOM 2521 HE2 PHE A 159 -17.407 -42.506 8.475 0.00 20.00 H +ATOM 2522 HZ PHE A 159 -16.850 -41.847 6.157 0.00 20.00 H +ATOM 2523 N PRO A 160 -12.799 -47.662 7.792 0.00 99.99 N +ATOM 2524 CA PRO A 160 -13.424 -46.994 6.664 0.00 99.99 C +ATOM 2525 C PRO A 160 -14.860 -47.414 6.369 0.00 99.99 C +ATOM 2526 O PRO A 160 -15.307 -48.543 6.564 0.00 99.99 O +ATOM 2527 CB PRO A 160 -12.546 -47.356 5.473 0.00 99.99 C +ATOM 2528 CG PRO A 160 -11.932 -48.697 5.861 0.00 99.99 C +ATOM 2529 CD PRO A 160 -11.864 -48.683 7.374 0.00 99.99 C +ATOM 2530 HA PRO A 160 -13.394 -45.904 6.811 0.00 20.00 H +ATOM 2531 HB2 PRO A 160 -13.149 -47.452 4.558 0.00 20.00 H +ATOM 2532 HB3 PRO A 160 -11.764 -46.598 5.319 0.00 20.00 H +ATOM 2533 HG2 PRO A 160 -12.565 -49.526 5.512 0.00 20.00 H +ATOM 2534 HG3 PRO A 160 -10.924 -48.799 5.432 0.00 20.00 H +ATOM 2535 HD2 PRO A 160 -10.847 -48.434 7.711 0.00 20.00 H +ATOM 2536 HD3 PRO A 160 -12.156 -49.662 7.781 0.00 20.00 H +ATOM 2537 N LEU A 161 -15.563 -46.374 5.799 0.00 99.99 N +ATOM 2538 CA LEU A 161 -16.890 -46.574 5.313 0.00 99.99 C +ATOM 2539 C LEU A 161 -17.116 -47.210 3.975 0.00 99.99 C +ATOM 2540 O LEU A 161 -16.362 -47.029 3.007 0.00 99.99 O +ATOM 2541 CB LEU A 161 -18.027 -45.924 6.034 0.00 99.99 C +ATOM 2542 CG LEU A 161 -18.361 -46.571 7.334 0.00 99.99 C +ATOM 2543 CD1 LEU A 161 -18.484 -45.716 8.554 0.00 99.99 C +ATOM 2544 CD2 LEU A 161 -18.632 -48.041 7.438 0.00 99.99 C +ATOM 2545 H LEU A 161 -15.139 -45.472 5.724 0.00 20.00 H +ATOM 2546 HA LEU A 161 -17.012 -47.525 5.853 0.00 20.00 H +ATOM 2547 HB2 LEU A 161 -17.760 -44.874 6.226 0.00 20.00 H +ATOM 2548 HB3 LEU A 161 -18.916 -45.964 5.387 0.00 20.00 H +ATOM 2549 HG LEU A 161 -17.294 -46.738 7.542 0.00 20.00 H +ATOM 2550 HD11 LEU A 161 -18.734 -46.347 9.421 0.00 20.00 H +ATOM 2551 HD12 LEU A 161 -17.530 -45.201 8.739 0.00 20.00 H +ATOM 2552 HD13 LEU A 161 -19.280 -44.972 8.402 0.00 20.00 H +ATOM 2553 HD21 LEU A 161 -18.856 -48.301 8.483 0.00 20.00 H +ATOM 2554 HD22 LEU A 161 -19.491 -48.302 6.803 0.00 20.00 H +ATOM 2555 HD23 LEU A 161 -17.746 -48.601 7.103 0.00 20.00 H +ATOM 2556 N ASN A 162 -18.283 -47.946 3.904 0.00 99.99 N +ATOM 2557 CA ASN A 162 -18.733 -48.393 2.627 0.00 99.99 C +ATOM 2558 C ASN A 162 -19.399 -47.410 1.702 0.00 99.99 C +ATOM 2559 O ASN A 162 -19.059 -47.215 0.531 0.00 99.99 O +ATOM 2560 CB ASN A 162 -18.628 -49.842 2.319 0.00 99.99 C +ATOM 2561 CG ASN A 162 -18.000 -50.068 0.978 0.00 99.99 C +ATOM 2562 OD1 ASN A 162 -16.774 -50.141 0.809 0.00 99.99 O +ATOM 2563 ND2 ASN A 162 -18.941 -50.225 -0.019 0.00 99.99 N +ATOM 2564 H ASN A 162 -18.802 -48.160 4.731 0.00 20.00 H +ATOM 2565 HA ASN A 162 -17.749 -48.195 2.177 0.00 20.00 H +ATOM 2566 HB2 ASN A 162 -18.012 -50.329 3.089 0.00 20.00 H +ATOM 2567 HB3 ASN A 162 -19.635 -50.284 2.322 0.00 20.00 H +ATOM 2568 HD21 ASN A 162 -18.649 -50.412 -0.957 0.00 20.00 H +ATOM 2569 HD22 ASN A 162 -19.915 -50.151 0.196 0.00 20.00 H +ATOM 2570 N GLN A 163 -20.470 -46.774 2.305 0.00 99.99 N +ATOM 2571 CA GLN A 163 -21.244 -45.820 1.575 0.00 99.99 C +ATOM 2572 C GLN A 163 -20.887 -44.359 1.641 0.00 99.99 C +ATOM 2573 O GLN A 163 -20.672 -43.760 2.695 0.00 99.99 O +ATOM 2574 CB GLN A 163 -22.472 -46.245 0.817 0.00 99.99 C +ATOM 2575 CG GLN A 163 -22.353 -47.575 0.105 0.00 99.99 C +ATOM 2576 CD GLN A 163 -22.719 -48.695 1.039 0.00 99.99 C +ATOM 2577 OE1 GLN A 163 -21.897 -49.535 1.408 0.00 99.99 O +ATOM 2578 NE2 GLN A 163 -24.039 -48.653 1.438 0.00 99.99 N +ATOM 2579 H GLN A 163 -20.703 -46.982 3.255 0.00 20.00 H +ATOM 2580 HA GLN A 163 -20.617 -45.958 0.682 0.00 20.00 H +ATOM 2581 HB2 GLN A 163 -23.306 -46.313 1.531 0.00 20.00 H +ATOM 2582 HB3 GLN A 163 -22.694 -45.473 0.066 0.00 20.00 H +ATOM 2583 HG2 GLN A 163 -23.032 -47.586 -0.761 0.00 20.00 H +ATOM 2584 HG3 GLN A 163 -21.317 -47.712 -0.240 0.00 20.00 H +ATOM 2585 HE21 GLN A 163 -24.391 -49.340 2.073 0.00 20.00 H +ATOM 2586 HE22 GLN A 163 -24.643 -47.935 1.092 0.00 20.00 H +ATOM 2587 N SER A 164 -20.870 -43.765 0.398 0.00 99.99 N +ATOM 2588 CA SER A 164 -20.811 -42.341 0.294 0.00 99.99 C +ATOM 2589 C SER A 164 -22.080 -41.540 0.309 0.00 99.99 C +ATOM 2590 O SER A 164 -22.314 -40.635 1.120 0.00 99.99 O +ATOM 2591 CB SER A 164 -19.497 -41.650 0.136 0.00 99.99 C +ATOM 2592 OG SER A 164 -19.046 -41.801 -1.214 0.00 99.99 O +ATOM 2593 H SER A 164 -20.898 -44.328 -0.429 0.00 20.00 H +ATOM 2594 HA SER A 164 -20.734 -42.256 1.388 0.00 20.00 H +ATOM 2595 HB2 SER A 164 -19.612 -40.581 0.368 0.00 20.00 H +ATOM 2596 HB3 SER A 164 -18.761 -42.097 0.821 0.00 20.00 H +ATOM 2597 HG SER A 164 -18.707 -40.972 -1.530 0.00 20.00 H +ATOM 2598 N GLU A 165 -22.936 -41.941 -0.688 0.00 99.99 N +ATOM 2599 CA GLU A 165 -24.225 -41.358 -0.851 0.00 99.99 C +ATOM 2600 C GLU A 165 -25.347 -41.603 0.146 0.00 99.99 C +ATOM 2601 O GLU A 165 -26.307 -40.845 0.308 0.00 99.99 O +ATOM 2602 CB GLU A 165 -24.486 -40.472 -2.032 0.00 99.99 C +ATOM 2603 CG GLU A 165 -23.588 -40.816 -3.202 0.00 99.99 C +ATOM 2604 CD GLU A 165 -23.933 -39.757 -4.199 0.00 99.99 C +ATOM 2605 OE1 GLU A 165 -23.211 -38.711 -4.203 0.00 99.99 O +ATOM 2606 OE2 GLU A 165 -24.926 -40.000 -4.963 0.00 99.99 O +ATOM 2607 H GLU A 165 -22.646 -42.663 -1.316 0.00 20.00 H +ATOM 2608 HA GLU A 165 -24.549 -42.233 -1.434 0.00 20.00 H +ATOM 2609 HB2 GLU A 165 -25.535 -40.591 -2.341 0.00 20.00 H +ATOM 2610 HB3 GLU A 165 -24.307 -39.426 -1.740 0.00 20.00 H +ATOM 2611 HG2 GLU A 165 -22.527 -40.762 -2.918 0.00 20.00 H +ATOM 2612 HG3 GLU A 165 -23.812 -41.819 -3.594 0.00 20.00 H +ATOM 2613 N VAL A 166 -25.216 -42.820 0.798 0.00 99.99 N +ATOM 2614 CA VAL A 166 -26.114 -43.202 1.844 0.00 99.99 C +ATOM 2615 C VAL A 166 -25.627 -43.123 3.261 0.00 99.99 C +ATOM 2616 O VAL A 166 -24.597 -42.517 3.606 0.00 99.99 O +ATOM 2617 CB VAL A 166 -27.448 -43.718 1.474 0.00 99.99 C +ATOM 2618 CG1 VAL A 166 -28.668 -42.852 1.405 0.00 99.99 C +ATOM 2619 CG2 VAL A 166 -27.582 -45.168 1.141 0.00 99.99 C +ATOM 2620 H VAL A 166 -24.480 -43.442 0.532 0.00 20.00 H +ATOM 2621 HA VAL A 166 -26.508 -42.177 1.905 0.00 20.00 H +ATOM 2622 HB VAL A 166 -27.660 -43.938 2.531 0.00 20.00 H +ATOM 2623 HG11 VAL A 166 -29.535 -43.462 1.109 0.00 20.00 H +ATOM 2624 HG12 VAL A 166 -28.855 -42.403 2.392 0.00 20.00 H +ATOM 2625 HG13 VAL A 166 -28.510 -42.055 0.664 0.00 20.00 H +ATOM 2626 HG21 VAL A 166 -28.629 -45.391 0.888 0.00 20.00 H +ATOM 2627 HG22 VAL A 166 -26.939 -45.407 0.281 0.00 20.00 H +ATOM 2628 HG23 VAL A 166 -27.277 -45.773 2.007 0.00 20.00 H +ATOM 2629 N LEU A 167 -26.404 -43.863 4.148 0.00 99.99 N +ATOM 2630 CA LEU A 167 -25.934 -44.091 5.482 0.00 99.99 C +ATOM 2631 C LEU A 167 -24.743 -44.993 5.722 0.00 99.99 C +ATOM 2632 O LEU A 167 -24.423 -45.904 4.948 0.00 99.99 O +ATOM 2633 CB LEU A 167 -26.769 -43.618 6.625 0.00 99.99 C +ATOM 2634 CG LEU A 167 -27.006 -42.134 6.616 0.00 99.99 C +ATOM 2635 CD1 LEU A 167 -28.406 -41.617 6.619 0.00 99.99 C +ATOM 2636 CD2 LEU A 167 -25.859 -41.177 6.626 0.00 99.99 C +ATOM 2637 H LEU A 167 -27.286 -44.234 3.855 0.00 20.00 H +ATOM 2638 HA LEU A 167 -25.316 -43.181 5.483 0.00 20.00 H +ATOM 2639 HB2 LEU A 167 -27.743 -44.127 6.580 0.00 20.00 H +ATOM 2640 HB3 LEU A 167 -26.260 -43.884 7.563 0.00 20.00 H +ATOM 2641 HG LEU A 167 -27.003 -42.135 5.516 0.00 20.00 H +ATOM 2642 HD11 LEU A 167 -28.392 -40.517 6.611 0.00 20.00 H +ATOM 2643 HD12 LEU A 167 -28.934 -41.982 5.726 0.00 20.00 H +ATOM 2644 HD13 LEU A 167 -28.926 -41.970 7.522 0.00 20.00 H +ATOM 2645 HD21 LEU A 167 -26.242 -40.145 6.617 0.00 20.00 H +ATOM 2646 HD22 LEU A 167 -25.256 -41.336 7.532 0.00 20.00 H +ATOM 2647 HD23 LEU A 167 -25.234 -41.344 5.736 0.00 20.00 H +ATOM 2648 N ALA A 168 -24.097 -44.754 6.915 0.00 99.99 N +ATOM 2649 CA ALA A 168 -23.115 -45.691 7.358 0.00 99.99 C +ATOM 2650 C ALA A 168 -23.587 -47.030 7.869 0.00 99.99 C +ATOM 2651 O ALA A 168 -24.581 -47.155 8.588 0.00 99.99 O +ATOM 2652 CB ALA A 168 -21.669 -45.324 7.285 0.00 99.99 C +ATOM 2653 H ALA A 168 -24.311 -43.942 7.458 0.00 20.00 H +ATOM 2654 HA ALA A 168 -23.173 -45.277 8.376 0.00 20.00 H +ATOM 2655 HB1 ALA A 168 -21.059 -46.157 7.665 0.00 20.00 H +ATOM 2656 HB2 ALA A 168 -21.396 -45.117 6.240 0.00 20.00 H +ATOM 2657 HB3 ALA A 168 -21.486 -44.428 7.896 0.00 20.00 H +ATOM 2658 N SER A 169 -22.820 -48.088 7.405 0.00 99.99 N +ATOM 2659 CA SER A 169 -23.369 -49.405 7.502 0.00 99.99 C +ATOM 2660 C SER A 169 -23.466 -50.128 8.812 0.00 99.99 C +ATOM 2661 O SER A 169 -22.491 -50.465 9.486 0.00 99.99 O +ATOM 2662 CB SER A 169 -24.021 -50.058 6.309 0.00 99.99 C +ATOM 2663 OG SER A 169 -23.423 -49.626 5.077 0.00 99.99 O +ATOM 2664 H SER A 169 -21.912 -47.935 7.016 0.00 20.00 H +ATOM 2665 HA SER A 169 -22.399 -49.870 7.274 0.00 20.00 H +ATOM 2666 HB2 SER A 169 -23.912 -51.149 6.395 0.00 20.00 H +ATOM 2667 HB3 SER A 169 -25.089 -49.796 6.298 0.00 20.00 H +ATOM 2668 HG SER A 169 -23.135 -48.725 5.162 0.00 20.00 H +ATOM 2669 N VAL A 170 -24.781 -50.324 9.194 1.00 66.21 N +ATOM 2670 CA VAL A 170 -25.105 -50.973 10.424 1.00 63.70 C +ATOM 2671 C VAL A 170 -25.312 -52.465 10.423 1.00 60.70 C +ATOM 2672 O VAL A 170 -25.808 -53.049 9.453 1.00 53.15 O +ATOM 2673 CB VAL A 170 -25.431 -50.111 11.582 1.00 58.01 C +ATOM 2674 CG1 VAL A 170 -24.381 -49.328 12.299 1.00 59.27 C +ATOM 2675 CG2 VAL A 170 -26.860 -49.934 11.994 1.00 57.80 C +ATOM 2676 H VAL A 170 -25.518 -50.005 8.598 1.00 20.00 H +ATOM 2677 HA VAL A 170 -24.050 -51.066 10.720 1.00 20.00 H +ATOM 2678 HB VAL A 170 -25.310 -50.956 12.276 1.00 20.00 H +ATOM 2679 HG11 VAL A 170 -24.842 -48.762 13.121 1.00 20.00 H +ATOM 2680 HG12 VAL A 170 -23.625 -50.016 12.706 1.00 20.00 H +ATOM 2681 HG13 VAL A 170 -23.901 -48.631 11.597 1.00 20.00 H +ATOM 2682 HG21 VAL A 170 -26.910 -49.265 12.866 1.00 20.00 H +ATOM 2683 HG22 VAL A 170 -27.430 -49.494 11.162 1.00 20.00 H +ATOM 2684 HG23 VAL A 170 -27.290 -50.911 12.257 1.00 20.00 H +ATOM 2685 N GLY A 171 -24.988 -53.109 11.600 1.00 53.62 N +ATOM 2686 CA GLY A 171 -25.434 -54.483 11.668 1.00 48.27 C +ATOM 2687 C GLY A 171 -25.291 -55.009 13.080 1.00 50.01 C +ATOM 2688 O GLY A 171 -24.871 -54.294 13.991 1.00 55.90 O +ATOM 2689 H GLY A 171 -24.488 -52.663 12.342 1.00 20.00 H +ATOM 2690 HA2 GLY A 171 -26.490 -54.538 11.365 1.00 20.00 H +ATOM 2691 HA3 GLY A 171 -24.825 -55.097 10.988 1.00 20.00 H +ATOM 2692 N GLY A 172 -25.650 -56.273 13.260 1.00 41.69 N +ATOM 2693 CA GLY A 172 -25.520 -56.896 14.566 1.00 41.22 C +ATOM 2694 C GLY A 172 -26.268 -58.219 14.629 1.00 41.96 C +ATOM 2695 O GLY A 172 -26.595 -58.811 13.605 1.00 43.92 O +ATOM 2696 H GLY A 172 -26.013 -56.801 12.492 1.00 20.00 H +ATOM 2697 HA2 GLY A 172 -24.455 -57.077 14.771 1.00 20.00 H +ATOM 2698 HA3 GLY A 172 -25.930 -56.217 15.328 1.00 20.00 H +ATOM 2699 N SER A 173 -26.523 -58.660 15.865 1.00 37.19 N +ATOM 2700 CA SER A 173 -27.141 -59.956 16.128 1.00 38.55 C +ATOM 2701 C SER A 173 -28.148 -59.854 17.263 1.00 39.78 C +ATOM 2702 O SER A 173 -27.876 -59.219 18.287 1.00 37.84 O +ATOM 2703 CB SER A 173 -26.093 -61.015 16.492 1.00 41.99 C +ATOM 2704 OG SER A 173 -25.216 -61.272 15.422 1.00 46.80 O +ATOM 2705 H SER A 173 -26.280 -58.078 16.641 1.00 20.00 H +ATOM 2706 HA SER A 173 -27.670 -60.293 15.225 1.00 20.00 H +ATOM 2707 HB2 SER A 173 -25.509 -60.657 17.353 1.00 20.00 H +ATOM 2708 HB3 SER A 173 -26.609 -61.948 16.762 1.00 20.00 H +ATOM 2709 HG SER A 173 -24.369 -60.882 15.605 1.00 20.00 H +ATOM 2710 N MET A 174 -29.298 -60.507 17.086 1.00 42.00 N +ATOM 2711 CA MET A 174 -30.249 -60.762 18.164 1.00 41.69 C +ATOM 2712 C MET A 174 -30.375 -62.272 18.321 1.00 42.68 C +ATOM 2713 O MET A 174 -30.994 -62.937 17.485 1.00 37.83 O +ATOM 2714 CB MET A 174 -31.611 -60.133 17.880 1.00 35.72 C +ATOM 2715 CG MET A 174 -32.661 -60.528 18.919 1.00 45.46 C +ATOM 2716 SD MET A 174 -34.241 -59.675 18.777 1.00 48.86 S +ATOM 2717 CE MET A 174 -34.751 -60.166 17.135 1.00 49.74 C +ATOM 2718 H MET A 174 -29.520 -60.838 16.169 1.00 20.00 H +ATOM 2719 HA MET A 174 -29.859 -60.343 19.103 1.00 20.00 H +ATOM 2720 HB2 MET A 174 -31.503 -59.038 17.885 1.00 20.00 H +ATOM 2721 HB3 MET A 174 -31.953 -60.463 16.888 1.00 20.00 H +ATOM 2722 HG2 MET A 174 -32.847 -61.608 18.821 1.00 20.00 H +ATOM 2723 HG3 MET A 174 -32.249 -60.316 19.917 1.00 20.00 H +ATOM 2724 HE1 MET A 174 -35.849 -60.164 17.076 1.00 20.00 H +ATOM 2725 HE2 MET A 174 -34.343 -59.459 16.398 1.00 20.00 H +ATOM 2726 HE3 MET A 174 -34.374 -61.177 16.921 1.00 20.00 H +ATOM 2727 N ILE A 175 -29.782 -62.812 19.379 1.00 46.06 N +ATOM 2728 CA ILE A 175 -29.830 -64.245 19.638 1.00 44.31 C +ATOM 2729 C ILE A 175 -31.053 -64.514 20.501 1.00 46.97 C +ATOM 2730 O ILE A 175 -31.092 -64.144 21.677 1.00 47.64 O +ATOM 2731 CB ILE A 175 -28.551 -64.747 20.315 1.00 41.78 C +ATOM 2732 CG1 ILE A 175 -27.321 -64.255 19.556 1.00 39.31 C +ATOM 2733 CG2 ILE A 175 -28.561 -66.270 20.396 1.00 38.06 C +ATOM 2734 CD1 ILE A 175 -27.263 -64.732 18.125 1.00 41.13 C +ATOM 2735 H ILE A 175 -29.289 -62.219 20.016 1.00 20.00 H +ATOM 2736 HA ILE A 175 -29.951 -64.782 18.686 1.00 20.00 H +ATOM 2737 HB ILE A 175 -28.516 -64.342 21.337 1.00 20.00 H +ATOM 2738 HG12 ILE A 175 -27.330 -63.155 19.556 1.00 20.00 H +ATOM 2739 HG13 ILE A 175 -26.423 -64.615 20.079 1.00 20.00 H +ATOM 2740 HG21 ILE A 175 -27.638 -66.618 20.884 1.00 20.00 H +ATOM 2741 HG22 ILE A 175 -29.432 -66.600 20.981 1.00 20.00 H +ATOM 2742 HG23 ILE A 175 -28.620 -66.691 19.381 1.00 20.00 H +ATOM 2743 HD11 ILE A 175 -26.355 -64.340 17.644 1.00 20.00 H +ATOM 2744 HD12 ILE A 175 -27.243 -65.832 18.106 1.00 20.00 H +ATOM 2745 HD13 ILE A 175 -28.150 -64.372 17.582 1.00 20.00 H +ATOM 2746 N ILE A 176 -32.059 -65.148 19.916 1.00 49.04 N +ATOM 2747 CA ILE A 176 -33.278 -65.476 20.644 1.00 42.70 C +ATOM 2748 C ILE A 176 -33.074 -66.803 21.355 1.00 37.18 C +ATOM 2749 O ILE A 176 -32.809 -67.830 20.716 1.00 43.38 O +ATOM 2750 CB ILE A 176 -34.489 -65.533 19.704 1.00 44.21 C +ATOM 2751 CG1 ILE A 176 -34.753 -64.159 19.084 1.00 44.64 C +ATOM 2752 CG2 ILE A 176 -35.706 -66.040 20.453 1.00 45.15 C +ATOM 2753 CD1 ILE A 176 -35.349 -63.160 20.052 1.00 50.67 C +ATOM 2754 H ILE A 176 -31.980 -65.407 18.953 1.00 20.00 H +ATOM 2755 HA ILE A 176 -33.467 -64.701 21.402 1.00 20.00 H +ATOM 2756 HB ILE A 176 -34.261 -66.239 18.892 1.00 20.00 H +ATOM 2757 HG12 ILE A 176 -33.799 -63.756 18.713 1.00 20.00 H +ATOM 2758 HG13 ILE A 176 -35.450 -64.286 18.243 1.00 20.00 H +ATOM 2759 HG21 ILE A 176 -36.568 -66.077 19.771 1.00 20.00 H +ATOM 2760 HG22 ILE A 176 -35.503 -67.049 20.842 1.00 20.00 H +ATOM 2761 HG23 ILE A 176 -35.930 -65.362 21.290 1.00 20.00 H +ATOM 2762 HD11 ILE A 176 -35.510 -62.201 19.538 1.00 20.00 H +ATOM 2763 HD12 ILE A 176 -36.311 -63.541 20.426 1.00 20.00 H +ATOM 2764 HD13 ILE A 176 -34.660 -63.012 20.896 1.00 20.00 H +ATOM 2765 N GLY A 177 -33.183 -66.789 22.677 1.00 40.12 N +ATOM 2766 CA GLY A 177 -33.095 -67.999 23.460 1.00 48.89 C +ATOM 2767 C GLY A 177 -31.705 -68.444 23.848 1.00 52.95 C +ATOM 2768 O GLY A 177 -31.552 -69.575 24.322 1.00 54.23 O +ATOM 2769 H GLY A 177 -33.330 -65.917 23.144 1.00 20.00 H +ATOM 2770 HA2 GLY A 177 -33.667 -67.842 24.386 1.00 20.00 H +ATOM 2771 HA3 GLY A 177 -33.556 -68.810 22.877 1.00 20.00 H +ATOM 2772 N GLY A 178 -30.686 -67.607 23.675 1.00 47.31 N +ATOM 2773 CA GLY A 178 -29.368 -68.096 24.025 1.00 45.52 C +ATOM 2774 C GLY A 178 -28.309 -67.018 24.079 1.00 46.92 C +ATOM 2775 O GLY A 178 -28.577 -65.831 23.884 1.00 41.50 O +ATOM 2776 H GLY A 178 -30.823 -66.682 23.320 1.00 20.00 H +ATOM 2777 HA2 GLY A 178 -29.427 -68.573 25.014 1.00 20.00 H +ATOM 2778 HA3 GLY A 178 -29.065 -68.842 23.275 1.00 20.00 H +ATOM 2779 N ILE A 179 -27.089 -67.470 24.359 1.00 46.25 N +ATOM 2780 CA ILE A 179 -25.893 -66.639 24.405 1.00 39.54 C +ATOM 2781 C ILE A 179 -24.901 -67.254 23.426 1.00 41.01 C +ATOM 2782 O ILE A 179 -24.471 -68.400 23.614 1.00 46.49 O +ATOM 2783 CB ILE A 179 -25.289 -66.567 25.816 1.00 43.11 C +ATOM 2784 CG1 ILE A 179 -26.330 -66.103 26.839 1.00 43.37 C +ATOM 2785 CG2 ILE A 179 -24.067 -65.660 25.829 1.00 45.00 C +ATOM 2786 CD1 ILE A 179 -25.827 -66.137 28.272 1.00 51.62 C +ATOM 2787 H ILE A 179 -26.986 -68.446 24.551 1.00 20.00 H +ATOM 2788 HA ILE A 179 -26.135 -65.619 24.072 1.00 20.00 H +ATOM 2789 HB ILE A 179 -24.965 -67.580 26.097 1.00 20.00 H +ATOM 2790 HG12 ILE A 179 -26.621 -65.070 26.596 1.00 20.00 H +ATOM 2791 HG13 ILE A 179 -27.210 -66.759 26.763 1.00 20.00 H +ATOM 2792 HG21 ILE A 179 -23.649 -65.621 26.846 1.00 20.00 H +ATOM 2793 HG22 ILE A 179 -23.309 -66.056 25.136 1.00 20.00 H +ATOM 2794 HG23 ILE A 179 -24.359 -64.647 25.514 1.00 20.00 H +ATOM 2795 HD11 ILE A 179 -26.623 -65.793 28.949 1.00 20.00 H +ATOM 2796 HD12 ILE A 179 -25.541 -67.166 28.536 1.00 20.00 H +ATOM 2797 HD13 ILE A 179 -24.952 -65.477 28.369 1.00 20.00 H +ATOM 2798 N ASP A 180 -24.537 -66.509 22.385 1.00 37.97 N +ATOM 2799 CA ASP A 180 -23.600 -67.004 21.383 1.00 35.18 C +ATOM 2800 C ASP A 180 -22.177 -66.664 21.809 1.00 42.38 C +ATOM 2801 O ASP A 180 -21.836 -65.488 21.980 1.00 37.77 O +ATOM 2802 CB ASP A 180 -23.894 -66.423 20.002 1.00 36.87 C +ATOM 2803 CG ASP A 180 -23.089 -67.105 18.907 1.00 48.58 C +ATOM 2804 OD1 ASP A 180 -23.665 -67.920 18.155 1.00 53.42 O +ATOM 2805 OD2 ASP A 180 -21.870 -66.847 18.812 1.00 56.01 O +ATOM 2806 H ASP A 180 -24.915 -65.588 22.288 1.00 20.00 H +ATOM 2807 HA ASP A 180 -23.687 -68.099 21.320 1.00 20.00 H +ATOM 2808 HB2 ASP A 180 -24.965 -66.550 19.785 1.00 20.00 H +ATOM 2809 HB3 ASP A 180 -23.646 -65.351 20.009 1.00 20.00 H +ATOM 2810 N HIS A 181 -21.343 -67.698 21.939 1.00 43.44 N +ATOM 2811 CA HIS A 181 -20.007 -67.523 22.498 1.00 47.22 C +ATOM 2812 C HIS A 181 -19.095 -66.734 21.570 1.00 44.89 C +ATOM 2813 O HIS A 181 -18.102 -66.157 22.024 1.00 46.96 O +ATOM 2814 CB HIS A 181 -19.395 -68.892 22.798 1.00 50.13 C +ATOM 2815 CG HIS A 181 -18.548 -68.923 24.031 1.00 51.15 C +ATOM 2816 ND1 HIS A 181 -18.765 -68.535 25.336 1.00 51.11 N +ATOM 2817 CD2 HIS A 181 -17.289 -69.419 23.990 1.00 51.74 C +ATOM 2818 CE1 HIS A 181 -17.685 -68.788 26.054 1.00 50.77 C +ATOM 2819 NE2 HIS A 181 -16.775 -69.324 25.261 1.00 50.75 N +ATOM 2820 H HIS A 181 -21.639 -68.608 21.648 1.00 20.00 H +ATOM 2821 HA HIS A 181 -20.088 -66.972 23.447 1.00 20.00 H +ATOM 2822 HB2 HIS A 181 -20.213 -69.617 22.922 1.00 20.00 H +ATOM 2823 HB3 HIS A 181 -18.770 -69.187 21.942 1.00 20.00 H +ATOM 2824 HD1 HIS A 181 -19.608 -68.125 25.685 1.00 20.00 H +ATOM 2825 HD2 HIS A 181 -16.783 -69.814 23.122 1.00 20.00 H +ATOM 2826 HE1 HIS A 181 -17.567 -68.590 27.109 1.00 20.00 H +ATOM 2827 N SER A 182 -19.402 -66.700 20.276 1.00 40.74 N +ATOM 2828 CA SER A 182 -18.508 -66.060 19.321 1.00 44.72 C +ATOM 2829 C SER A 182 -18.690 -64.551 19.243 1.00 45.42 C +ATOM 2830 O SER A 182 -17.899 -63.887 18.566 1.00 48.26 O +ATOM 2831 CB SER A 182 -18.707 -66.662 17.932 1.00 47.25 C +ATOM 2832 OG SER A 182 -19.924 -66.210 17.363 1.00 54.70 O +ATOM 2833 H SER A 182 -20.253 -67.117 19.957 1.00 20.00 H +ATOM 2834 HA SER A 182 -17.470 -66.258 19.626 1.00 20.00 H +ATOM 2835 HB2 SER A 182 -17.871 -66.361 17.284 1.00 20.00 H +ATOM 2836 HB3 SER A 182 -18.731 -67.759 18.013 1.00 20.00 H +ATOM 2837 HG SER A 182 -20.649 -66.460 17.924 1.00 20.00 H +ATOM 2838 N LEU A 183 -19.695 -63.999 19.914 1.00 43.79 N +ATOM 2839 CA LEU A 183 -19.984 -62.573 19.832 1.00 45.70 C +ATOM 2840 C LEU A 183 -19.358 -61.758 20.958 1.00 44.15 C +ATOM 2841 O LEU A 183 -19.558 -60.540 20.999 1.00 40.22 O +ATOM 2842 CB LEU A 183 -21.501 -62.341 19.810 1.00 43.30 C +ATOM 2843 CG LEU A 183 -22.290 -63.130 18.762 1.00 41.74 C +ATOM 2844 CD1 LEU A 183 -23.763 -62.747 18.805 1.00 44.63 C +ATOM 2845 CD2 LEU A 183 -21.707 -62.907 17.377 1.00 41.74 C +ATOM 2846 H LEU A 183 -20.270 -64.579 20.492 1.00 20.00 H +ATOM 2847 HA LEU A 183 -19.579 -62.192 18.883 1.00 20.00 H +ATOM 2848 HB2 LEU A 183 -21.896 -62.610 20.801 1.00 20.00 H +ATOM 2849 HB3 LEU A 183 -21.674 -61.271 19.625 1.00 20.00 H +ATOM 2850 HG LEU A 183 -22.205 -64.200 19.004 1.00 20.00 H +ATOM 2851 HD11 LEU A 183 -24.314 -63.322 18.047 1.00 20.00 H +ATOM 2852 HD12 LEU A 183 -24.171 -62.970 19.802 1.00 20.00 H +ATOM 2853 HD13 LEU A 183 -23.868 -61.672 18.597 1.00 20.00 H +ATOM 2854 HD21 LEU A 183 -22.286 -63.481 16.638 1.00 20.00 H +ATOM 2855 HD22 LEU A 183 -21.753 -61.837 17.128 1.00 20.00 H +ATOM 2856 HD23 LEU A 183 -20.659 -63.242 17.362 1.00 20.00 H +ATOM 2857 N TYR A 184 -18.604 -62.378 21.864 1.00 43.71 N +ATOM 2858 CA TYR A 184 -17.946 -61.632 22.929 1.00 43.49 C +ATOM 2859 C TYR A 184 -16.613 -62.276 23.288 1.00 44.75 C +ATOM 2860 O TYR A 184 -16.322 -63.414 22.917 1.00 46.75 O +ATOM 2861 CB TYR A 184 -18.840 -61.504 24.178 1.00 42.17 C +ATOM 2862 CG TYR A 184 -19.075 -62.777 24.970 1.00 44.71 C +ATOM 2863 CD1 TYR A 184 -19.981 -63.738 24.535 1.00 49.44 C +ATOM 2864 CD2 TYR A 184 -18.423 -62.997 26.177 1.00 49.39 C +ATOM 2865 CE1 TYR A 184 -20.211 -64.892 25.266 1.00 50.86 C +ATOM 2866 CE2 TYR A 184 -18.648 -64.149 26.918 1.00 52.63 C +ATOM 2867 CZ TYR A 184 -19.544 -65.095 26.455 1.00 54.64 C +ATOM 2868 OH TYR A 184 -19.780 -66.246 27.175 1.00 55.49 O +ATOM 2869 H TYR A 184 -18.488 -63.370 21.813 1.00 20.00 H +ATOM 2870 HA TYR A 184 -17.738 -60.615 22.566 1.00 20.00 H +ATOM 2871 HB2 TYR A 184 -18.371 -60.772 24.852 1.00 20.00 H +ATOM 2872 HB3 TYR A 184 -19.820 -61.127 23.851 1.00 20.00 H +ATOM 2873 HD1 TYR A 184 -20.515 -63.582 23.610 1.00 20.00 H +ATOM 2874 HD2 TYR A 184 -17.728 -62.257 26.546 1.00 20.00 H +ATOM 2875 HE1 TYR A 184 -20.911 -65.631 24.905 1.00 20.00 H +ATOM 2876 HE2 TYR A 184 -18.126 -64.305 27.851 1.00 20.00 H +ATOM 2877 HH TYR A 184 -19.851 -66.034 28.098 1.00 20.00 H +ATOM 2878 N THR A 185 -15.790 -61.511 24.002 1.00 45.18 N +ATOM 2879 CA THR A 185 -14.557 -62.002 24.599 1.00 46.68 C +ATOM 2880 C THR A 185 -14.568 -61.658 26.081 1.00 47.56 C +ATOM 2881 O THR A 185 -15.286 -60.759 26.524 1.00 45.85 O +ATOM 2882 CB THR A 185 -13.298 -61.404 23.939 1.00 48.12 C +ATOM 2883 OG1 THR A 185 -13.293 -59.980 24.102 1.00 46.07 O +ATOM 2884 CG2 THR A 185 -13.247 -61.743 22.455 1.00 50.83 C +ATOM 2885 H THR A 185 -16.031 -60.550 24.135 1.00 20.00 H +ATOM 2886 HA THR A 185 -14.513 -63.096 24.496 1.00 20.00 H +ATOM 2887 HB THR A 185 -12.413 -61.837 24.427 1.00 20.00 H +ATOM 2888 HG1 THR A 185 -14.040 -59.718 24.628 1.00 20.00 H +ATOM 2889 HG21 THR A 185 -12.341 -61.306 22.009 1.00 20.00 H +ATOM 2890 HG22 THR A 185 -13.226 -62.836 22.329 1.00 20.00 H +ATOM 2891 HG23 THR A 185 -14.137 -61.333 21.955 1.00 20.00 H +ATOM 2892 N GLY A 186 -13.772 -62.390 26.852 1.00 44.92 N +ATOM 2893 CA GLY A 186 -13.728 -62.082 28.265 1.00 44.94 C +ATOM 2894 C GLY A 186 -14.919 -62.652 29.021 1.00 44.18 C +ATOM 2895 O GLY A 186 -15.637 -63.534 28.550 1.00 51.14 O +ATOM 2896 H GLY A 186 -13.220 -63.131 26.468 1.00 20.00 H +ATOM 2897 HA2 GLY A 186 -12.805 -62.504 28.690 1.00 20.00 H +ATOM 2898 HA3 GLY A 186 -13.722 -60.989 28.388 1.00 20.00 H +ATOM 2899 N SER A 187 -15.122 -62.120 30.223 1.00 47.76 N +ATOM 2900 CA SER A 187 -16.181 -62.600 31.097 1.00 54.62 C +ATOM 2901 C SER A 187 -17.483 -61.849 30.844 1.00 51.94 C +ATOM 2902 O SER A 187 -17.491 -60.696 30.404 1.00 42.75 O +ATOM 2903 CB SER A 187 -15.784 -62.449 32.568 1.00 58.34 C +ATOM 2904 OG SER A 187 -14.719 -63.321 32.913 1.00 65.65 O +ATOM 2905 H SER A 187 -14.533 -61.373 30.533 1.00 20.00 H +ATOM 2906 HA SER A 187 -16.356 -63.668 30.898 1.00 20.00 H +ATOM 2907 HB2 SER A 187 -15.468 -61.411 32.748 1.00 20.00 H +ATOM 2908 HB3 SER A 187 -16.655 -62.682 33.199 1.00 20.00 H +ATOM 2909 HG SER A 187 -14.189 -63.494 32.144 1.00 20.00 H +ATOM 2910 N LEU A 188 -18.591 -62.525 31.128 1.00 50.93 N +ATOM 2911 CA LEU A 188 -19.899 -61.887 31.187 1.00 46.88 C +ATOM 2912 C LEU A 188 -20.156 -61.474 32.630 1.00 46.97 C +ATOM 2913 O LEU A 188 -20.093 -62.310 33.539 1.00 54.30 O +ATOM 2914 CB LEU A 188 -20.995 -62.832 30.691 1.00 45.93 C +ATOM 2915 CG LEU A 188 -21.530 -62.692 29.264 1.00 52.18 C +ATOM 2916 CD1 LEU A 188 -22.331 -63.930 28.889 1.00 53.84 C +ATOM 2917 CD2 LEU A 188 -22.391 -61.447 29.146 1.00 54.70 C +ATOM 2918 H LEU A 188 -18.524 -63.507 31.308 1.00 20.00 H +ATOM 2919 HA LEU A 188 -19.899 -60.986 30.556 1.00 20.00 H +ATOM 2920 HB2 LEU A 188 -20.601 -63.855 30.785 1.00 20.00 H +ATOM 2921 HB3 LEU A 188 -21.854 -62.707 31.367 1.00 20.00 H +ATOM 2922 HG LEU A 188 -20.677 -62.600 28.576 1.00 20.00 H +ATOM 2923 HD11 LEU A 188 -22.713 -63.824 27.863 1.00 20.00 H +ATOM 2924 HD12 LEU A 188 -21.684 -64.817 28.949 1.00 20.00 H +ATOM 2925 HD13 LEU A 188 -23.176 -64.045 29.584 1.00 20.00 H +ATOM 2926 HD21 LEU A 188 -22.769 -61.358 28.117 1.00 20.00 H +ATOM 2927 HD22 LEU A 188 -23.239 -61.520 29.843 1.00 20.00 H +ATOM 2928 HD23 LEU A 188 -21.789 -60.560 29.393 1.00 20.00 H +ATOM 2929 N TRP A 189 -20.423 -60.191 32.846 1.00 46.93 N +ATOM 2930 CA TRP A 189 -20.711 -59.667 34.173 1.00 50.19 C +ATOM 2931 C TRP A 189 -22.168 -59.231 34.241 1.00 50.47 C +ATOM 2932 O TRP A 189 -22.636 -58.476 33.384 1.00 46.26 O +ATOM 2933 CB TRP A 189 -19.782 -58.504 34.520 1.00 50.83 C +ATOM 2934 CG TRP A 189 -18.433 -58.958 35.005 1.00 50.32 C +ATOM 2935 CD1 TRP A 189 -17.326 -59.197 34.246 1.00 51.20 C +ATOM 2936 CD2 TRP A 189 -18.056 -59.235 36.360 1.00 49.47 C +ATOM 2937 NE1 TRP A 189 -16.281 -59.599 35.043 1.00 50.45 N +ATOM 2938 CE2 TRP A 189 -16.704 -59.631 36.346 1.00 49.48 C +ATOM 2939 CE3 TRP A 189 -18.731 -59.182 37.584 1.00 52.76 C +ATOM 2940 CZ2 TRP A 189 -16.013 -59.973 37.508 1.00 51.19 C +ATOM 2941 CZ3 TRP A 189 -18.042 -59.523 38.737 1.00 57.45 C +ATOM 2942 CH2 TRP A 189 -16.698 -59.912 38.690 1.00 54.49 C +ATOM 2943 H TRP A 189 -20.426 -59.562 32.069 1.00 20.00 H +ATOM 2944 HA TRP A 189 -20.555 -60.463 34.916 1.00 20.00 H +ATOM 2945 HB2 TRP A 189 -19.642 -57.886 33.621 1.00 20.00 H +ATOM 2946 HB3 TRP A 189 -20.254 -57.901 35.310 1.00 20.00 H +ATOM 2947 HD1 TRP A 189 -17.277 -59.086 33.173 1.00 20.00 H +ATOM 2948 HE1 TRP A 189 -15.362 -59.830 34.724 1.00 20.00 H +ATOM 2949 HE3 TRP A 189 -19.767 -58.882 37.630 1.00 20.00 H +ATOM 2950 HZ2 TRP A 189 -14.976 -60.275 37.476 1.00 20.00 H +ATOM 2951 HZ3 TRP A 189 -18.551 -59.488 39.689 1.00 20.00 H +ATOM 2952 HH2 TRP A 189 -16.191 -60.170 39.608 1.00 20.00 H +ATOM 2953 N TYR A 190 -22.869 -59.691 35.273 1.00 50.64 N +ATOM 2954 CA TYR A 190 -24.317 -59.570 35.373 1.00 53.09 C +ATOM 2955 C TYR A 190 -24.707 -58.587 36.468 1.00 54.08 C +ATOM 2956 O TYR A 190 -24.194 -58.661 37.590 1.00 51.91 O +ATOM 2957 CB TYR A 190 -24.951 -60.933 35.657 1.00 48.32 C +ATOM 2958 CG TYR A 190 -24.939 -61.883 34.485 1.00 48.94 C +ATOM 2959 CD1 TYR A 190 -25.965 -61.869 33.546 1.00 50.09 C +ATOM 2960 CD2 TYR A 190 -23.914 -62.803 34.321 1.00 47.98 C +ATOM 2961 CE1 TYR A 190 -25.963 -62.734 32.474 1.00 52.08 C +ATOM 2962 CE2 TYR A 190 -23.905 -63.676 33.250 1.00 50.65 C +ATOM 2963 CZ TYR A 190 -24.934 -63.638 32.330 1.00 52.22 C +ATOM 2964 OH TYR A 190 -24.934 -64.503 31.260 1.00 54.24 O +ATOM 2965 H TYR A 190 -22.378 -60.143 36.018 1.00 20.00 H +ATOM 2966 HA TYR A 190 -24.715 -59.198 34.417 1.00 20.00 H +ATOM 2967 HB2 TYR A 190 -24.401 -61.402 36.486 1.00 20.00 H +ATOM 2968 HB3 TYR A 190 -25.997 -60.770 35.957 1.00 20.00 H +ATOM 2969 HD1 TYR A 190 -26.778 -61.167 33.660 1.00 20.00 H +ATOM 2970 HD2 TYR A 190 -23.110 -62.838 35.042 1.00 20.00 H +ATOM 2971 HE1 TYR A 190 -26.764 -62.703 31.750 1.00 20.00 H +ATOM 2972 HE2 TYR A 190 -23.098 -64.384 33.133 1.00 20.00 H +ATOM 2973 HH TYR A 190 -25.294 -64.065 30.498 1.00 20.00 H +ATOM 2974 N THR A 191 -25.625 -57.684 36.136 1.00 48.88 N +ATOM 2975 CA THR A 191 -26.280 -56.769 37.047 1.00 49.35 C +ATOM 2976 C THR A 191 -27.750 -57.150 37.196 1.00 54.15 C +ATOM 2977 O THR A 191 -28.369 -57.638 36.245 1.00 50.74 O +ATOM 2978 CB THR A 191 -26.167 -55.314 36.565 1.00 47.65 C +ATOM 2979 OG1 THR A 191 -26.521 -54.425 37.632 1.00 52.55 O +ATOM 2980 CG2 THR A 191 -27.089 -55.049 35.379 1.00 45.97 C +ATOM 2981 H THR A 191 -25.886 -57.632 35.172 1.00 20.00 H +ATOM 2982 HA THR A 191 -25.804 -56.839 38.036 1.00 20.00 H +ATOM 2983 HB THR A 191 -25.129 -55.129 36.252 1.00 20.00 H +ATOM 2984 HG1 THR A 191 -25.940 -54.568 38.370 1.00 20.00 H +ATOM 2985 HG21 THR A 191 -26.984 -54.002 35.059 1.00 20.00 H +ATOM 2986 HG22 THR A 191 -26.817 -55.715 34.547 1.00 20.00 H +ATOM 2987 HG23 THR A 191 -28.131 -55.239 35.675 1.00 20.00 H +ATOM 2988 N PRO A 192 -28.333 -56.965 38.377 1.00 55.19 N +ATOM 2989 CA PRO A 192 -29.731 -57.356 38.573 1.00 49.34 C +ATOM 2990 C PRO A 192 -30.691 -56.462 37.805 1.00 51.47 C +ATOM 2991 O PRO A 192 -30.479 -55.255 37.659 1.00 53.66 O +ATOM 2992 CB PRO A 192 -29.936 -57.207 40.086 1.00 48.98 C +ATOM 2993 CG PRO A 192 -28.565 -57.245 40.665 1.00 54.57 C +ATOM 2994 CD PRO A 192 -27.689 -56.591 39.647 1.00 54.86 C +ATOM 2995 HA PRO A 192 -29.884 -58.405 38.281 1.00 20.00 H +ATOM 2996 HB2 PRO A 192 -30.427 -56.250 40.317 1.00 20.00 H +ATOM 2997 HB3 PRO A 192 -30.544 -58.036 40.477 1.00 20.00 H +ATOM 2998 HG2 PRO A 192 -28.532 -56.691 41.615 1.00 20.00 H +ATOM 2999 HG3 PRO A 192 -28.248 -58.284 40.836 1.00 20.00 H +ATOM 3000 HD2 PRO A 192 -26.661 -56.979 39.700 1.00 20.00 H +ATOM 3001 HD3 PRO A 192 -27.676 -55.499 39.778 1.00 20.00 H +ATOM 3002 N ILE A 193 -31.750 -57.080 37.292 1.00 49.89 N +ATOM 3003 CA ILE A 193 -32.907 -56.329 36.823 1.00 48.22 C +ATOM 3004 C ILE A 193 -33.679 -55.905 38.067 1.00 51.27 C +ATOM 3005 O ILE A 193 -34.234 -56.741 38.782 1.00 54.88 O +ATOM 3006 CB ILE A 193 -33.780 -57.149 35.868 1.00 50.57 C +ATOM 3007 CG1 ILE A 193 -32.980 -57.544 34.625 1.00 45.92 C +ATOM 3008 CG2 ILE A 193 -35.010 -56.345 35.471 1.00 56.47 C +ATOM 3009 CD1 ILE A 193 -33.736 -58.442 33.668 1.00 46.25 C +ATOM 3010 H ILE A 193 -31.753 -58.078 37.227 1.00 20.00 H +ATOM 3011 HA ILE A 193 -32.568 -55.425 36.296 1.00 20.00 H +ATOM 3012 HB ILE A 193 -34.105 -58.064 36.385 1.00 20.00 H +ATOM 3013 HG12 ILE A 193 -32.698 -56.626 34.089 1.00 20.00 H +ATOM 3014 HG13 ILE A 193 -32.072 -58.072 34.951 1.00 20.00 H +ATOM 3015 HG21 ILE A 193 -35.632 -56.940 34.786 1.00 20.00 H +ATOM 3016 HG22 ILE A 193 -35.591 -56.096 36.371 1.00 20.00 H +ATOM 3017 HG23 ILE A 193 -34.696 -55.418 34.970 1.00 20.00 H +ATOM 3018 HD11 ILE A 193 -33.097 -58.680 32.805 1.00 20.00 H +ATOM 3019 HD12 ILE A 193 -34.017 -59.372 34.183 1.00 20.00 H +ATOM 3020 HD13 ILE A 193 -34.643 -57.926 33.321 1.00 20.00 H +ATOM 3021 N ARG A 194 -33.694 -54.600 38.337 1.00 55.04 N +ATOM 3022 CA ARG A 194 -34.255 -54.106 39.589 1.00 57.13 C +ATOM 3023 C ARG A 194 -35.762 -54.324 39.656 1.00 61.93 C +ATOM 3024 O ARG A 194 -36.288 -54.741 40.694 1.00 60.69 O +ATOM 3025 CB ARG A 194 -33.923 -52.627 39.749 1.00 60.30 C +ATOM 3026 CG ARG A 194 -34.136 -52.096 41.141 1.00 68.55 C +ATOM 3027 CD ARG A 194 -34.196 -50.590 41.099 1.00 71.19 C +ATOM 3028 NE ARG A 194 -34.457 -50.016 42.411 1.00 70.77 N +ATOM 3029 CZ ARG A 194 -34.885 -48.774 42.601 1.00 73.56 C +ATOM 3030 NH1 ARG A 194 -35.107 -47.985 41.558 1.00 73.23 N +ATOM 3031 NH2 ARG A 194 -35.098 -48.324 43.830 1.00 76.77 N +ATOM 3032 H ARG A 194 -33.317 -53.953 37.674 1.00 20.00 H +ATOM 3033 HA ARG A 194 -33.794 -54.651 40.426 1.00 20.00 H +ATOM 3034 HB2 ARG A 194 -32.866 -52.479 39.481 1.00 20.00 H +ATOM 3035 HB3 ARG A 194 -34.560 -52.054 39.059 1.00 20.00 H +ATOM 3036 HG2 ARG A 194 -35.081 -52.490 41.543 1.00 20.00 H +ATOM 3037 HG3 ARG A 194 -33.303 -52.412 41.786 1.00 20.00 H +ATOM 3038 HD2 ARG A 194 -33.234 -50.207 40.729 1.00 20.00 H +ATOM 3039 HD3 ARG A 194 -35.000 -50.286 40.412 1.00 20.00 H +ATOM 3040 HE ARG A 194 -34.305 -50.590 43.215 1.00 20.00 H +ATOM 3041 HH11 ARG A 194 -35.435 -47.051 41.699 1.00 20.00 H +ATOM 3042 HH12 ARG A 194 -34.946 -48.324 40.631 1.00 20.00 H +ATOM 3043 HH21 ARG A 194 -35.426 -47.390 43.971 1.00 20.00 H +ATOM 3044 HH22 ARG A 194 -34.931 -48.919 44.616 1.00 20.00 H +ATOM 3045 N ARG A 195 -36.475 -54.027 38.573 1.00 62.52 N +ATOM 3046 CA ARG A 195 -37.916 -54.232 38.524 1.00 60.26 C +ATOM 3047 C ARG A 195 -38.298 -54.618 37.105 1.00 62.09 C +ATOM 3048 O ARG A 195 -37.727 -54.102 36.141 1.00 57.68 O +ATOM 3049 CB ARG A 195 -38.674 -52.973 38.967 1.00 65.88 C +ATOM 3050 CG ARG A 195 -40.194 -53.086 38.916 1.00 67.92 C +ATOM 3051 CD ARG A 195 -40.849 -52.115 39.892 1.00 74.26 C +ATOM 3052 NE ARG A 195 -40.882 -50.744 39.392 1.00 77.66 N +ATOM 3053 CZ ARG A 195 -41.907 -50.224 38.724 1.00 77.68 C +ATOM 3054 NH1 ARG A 195 -41.864 -48.967 38.305 1.00 78.62 N +ATOM 3055 NH2 ARG A 195 -42.976 -50.966 38.472 1.00 71.23 N +ATOM 3056 H ARG A 195 -36.009 -53.653 37.771 1.00 20.00 H +ATOM 3057 HA ARG A 195 -38.191 -55.057 39.197 1.00 20.00 H +ATOM 3058 HB2 ARG A 195 -38.383 -52.746 40.003 1.00 20.00 H +ATOM 3059 HB3 ARG A 195 -38.371 -52.144 38.311 1.00 20.00 H +ATOM 3060 HG2 ARG A 195 -40.537 -52.857 37.896 1.00 20.00 H +ATOM 3061 HG3 ARG A 195 -40.487 -54.113 39.180 1.00 20.00 H +ATOM 3062 HD2 ARG A 195 -41.882 -52.446 40.077 1.00 20.00 H +ATOM 3063 HD3 ARG A 195 -40.284 -52.131 40.836 1.00 20.00 H +ATOM 3064 HE ARG A 195 -40.087 -50.162 39.562 1.00 20.00 H +ATOM 3065 HH11 ARG A 195 -42.637 -48.581 37.800 1.00 20.00 H +ATOM 3066 HH12 ARG A 195 -41.059 -48.404 38.493 1.00 20.00 H +ATOM 3067 HH21 ARG A 195 -43.747 -50.577 37.967 1.00 20.00 H +ATOM 3068 HH22 ARG A 195 -43.012 -51.915 38.787 1.00 20.00 H +ATOM 3069 N GLU A 196 -39.254 -55.535 36.978 1.00 66.25 N +ATOM 3070 CA GLU A 196 -39.646 -56.038 35.663 1.00 62.98 C +ATOM 3071 C GLU A 196 -40.675 -55.097 35.049 1.00 66.83 C +ATOM 3072 O GLU A 196 -41.884 -55.307 35.151 1.00 67.58 O +ATOM 3073 CB GLU A 196 -40.187 -57.459 35.765 1.00 62.74 C +ATOM 3074 CG GLU A 196 -39.216 -58.461 36.370 1.00 62.53 C +ATOM 3075 CD GLU A 196 -39.683 -59.894 36.196 1.00 70.07 C +ATOM 3076 OE1 GLU A 196 -40.898 -60.107 35.987 1.00 72.60 O +ATOM 3077 OE2 GLU A 196 -38.835 -60.808 36.255 1.00 71.18 O +ATOM 3078 H GLU A 196 -39.711 -55.885 37.795 1.00 20.00 H +ATOM 3079 HA GLU A 196 -38.762 -56.054 35.008 1.00 20.00 H +ATOM 3080 HB2 GLU A 196 -41.092 -57.438 36.389 1.00 20.00 H +ATOM 3081 HB3 GLU A 196 -40.447 -57.801 34.752 1.00 20.00 H +ATOM 3082 HG2 GLU A 196 -38.238 -58.346 35.880 1.00 20.00 H +ATOM 3083 HG3 GLU A 196 -39.114 -58.250 37.445 1.00 20.00 H +ATOM 3084 N TRP A 197 -40.191 -54.035 34.408 1.00 64.97 N +ATOM 3085 CA TRP A 197 -41.043 -53.213 33.554 1.00 55.76 C +ATOM 3086 C TRP A 197 -40.239 -52.771 32.337 1.00 53.82 C +ATOM 3087 O TRP A 197 -40.254 -53.445 31.303 1.00 50.12 O +ATOM 3088 CB TRP A 197 -41.640 -52.025 34.323 1.00 55.64 C +ATOM 3089 CG TRP A 197 -40.687 -51.038 34.955 1.00 56.74 C +ATOM 3090 CD1 TRP A 197 -39.416 -51.268 35.403 1.00 55.18 C +ATOM 3091 CD2 TRP A 197 -40.950 -49.654 35.193 1.00 56.49 C +ATOM 3092 NE1 TRP A 197 -38.877 -50.109 35.912 1.00 52.80 N +ATOM 3093 CE2 TRP A 197 -39.800 -49.103 35.792 1.00 55.18 C +ATOM 3094 CE3 TRP A 197 -42.052 -48.826 34.959 1.00 59.85 C +ATOM 3095 CZ2 TRP A 197 -39.723 -47.762 36.159 1.00 57.74 C +ATOM 3096 CZ3 TRP A 197 -41.975 -47.500 35.323 1.00 57.68 C +ATOM 3097 CH2 TRP A 197 -40.821 -46.979 35.918 1.00 61.30 C +ATOM 3098 H TRP A 197 -39.226 -53.796 34.514 1.00 20.00 H +ATOM 3099 HA TRP A 197 -41.880 -53.831 33.196 1.00 20.00 H +ATOM 3100 HB2 TRP A 197 -42.272 -51.464 33.619 1.00 20.00 H +ATOM 3101 HB3 TRP A 197 -42.265 -52.438 35.129 1.00 20.00 H +ATOM 3102 HD1 TRP A 197 -38.909 -52.221 35.363 1.00 20.00 H +ATOM 3103 HE1 TRP A 197 -37.962 -50.016 36.305 1.00 20.00 H +ATOM 3104 HE3 TRP A 197 -42.948 -49.219 34.501 1.00 20.00 H +ATOM 3105 HZ2 TRP A 197 -38.833 -47.355 36.616 1.00 20.00 H +ATOM 3106 HZ3 TRP A 197 -42.820 -46.851 35.146 1.00 20.00 H +ATOM 3107 HH2 TRP A 197 -40.795 -45.935 36.194 1.00 20.00 H +ATOM 3108 N TYR A 198 -39.533 -51.654 32.437 1.00 58.39 N +ATOM 3109 CA TYR A 198 -38.348 -51.514 31.619 1.00 55.59 C +ATOM 3110 C TYR A 198 -37.288 -52.490 32.126 1.00 56.54 C +ATOM 3111 O TYR A 198 -37.463 -53.173 33.140 1.00 55.83 O +ATOM 3112 CB TYR A 198 -37.804 -50.087 31.671 1.00 54.56 C +ATOM 3113 CG TYR A 198 -38.716 -48.991 31.168 1.00 56.58 C +ATOM 3114 CD1 TYR A 198 -38.757 -48.656 29.821 1.00 55.51 C +ATOM 3115 CD2 TYR A 198 -39.498 -48.257 32.047 1.00 58.79 C +ATOM 3116 CE1 TYR A 198 -39.574 -47.635 29.361 1.00 63.68 C +ATOM 3117 CE2 TYR A 198 -40.316 -47.237 31.599 1.00 65.17 C +ATOM 3118 CZ TYR A 198 -40.353 -46.930 30.258 1.00 66.77 C +ATOM 3119 OH TYR A 198 -41.170 -45.913 29.823 1.00 70.79 O +ATOM 3120 H TYR A 198 -39.812 -50.926 33.063 1.00 20.00 H +ATOM 3121 HA TYR A 198 -38.585 -51.763 30.574 1.00 20.00 H +ATOM 3122 HB2 TYR A 198 -37.560 -49.862 32.720 1.00 20.00 H +ATOM 3123 HB3 TYR A 198 -36.885 -50.059 31.067 1.00 20.00 H +ATOM 3124 HD1 TYR A 198 -38.142 -49.200 29.120 1.00 20.00 H +ATOM 3125 HD2 TYR A 198 -39.467 -48.487 33.102 1.00 20.00 H +ATOM 3126 HE1 TYR A 198 -39.601 -47.392 28.309 1.00 20.00 H +ATOM 3127 HE2 TYR A 198 -40.924 -46.683 32.299 1.00 20.00 H +ATOM 3128 HH TYR A 198 -41.461 -46.097 28.937 1.00 20.00 H +ATOM 3129 N TYR A 199 -36.170 -52.557 31.420 1.00 57.24 N +ATOM 3130 CA TYR A 199 -35.031 -53.303 31.945 1.00 54.89 C +ATOM 3131 C TYR A 199 -34.244 -52.338 32.820 1.00 52.91 C +ATOM 3132 O TYR A 199 -33.322 -51.659 32.368 1.00 52.01 O +ATOM 3133 CB TYR A 199 -34.198 -53.889 30.815 1.00 52.11 C +ATOM 3134 CG TYR A 199 -34.896 -55.015 30.093 1.00 53.08 C +ATOM 3135 CD1 TYR A 199 -34.912 -56.295 30.623 1.00 55.02 C +ATOM 3136 CD2 TYR A 199 -35.546 -54.796 28.884 1.00 54.28 C +ATOM 3137 CE1 TYR A 199 -35.549 -57.332 29.969 1.00 58.64 C +ATOM 3138 CE2 TYR A 199 -36.185 -55.827 28.221 1.00 53.16 C +ATOM 3139 CZ TYR A 199 -36.187 -57.093 28.769 1.00 54.27 C +ATOM 3140 OH TYR A 199 -36.822 -58.118 28.108 1.00 48.46 O +ATOM 3141 H TYR A 199 -36.106 -52.099 30.533 1.00 20.00 H +ATOM 3142 HA TYR A 199 -35.395 -54.128 32.575 1.00 20.00 H +ATOM 3143 HB2 TYR A 199 -33.978 -53.091 30.091 1.00 20.00 H +ATOM 3144 HB3 TYR A 199 -33.257 -54.272 31.235 1.00 20.00 H +ATOM 3145 HD1 TYR A 199 -34.418 -56.486 31.564 1.00 20.00 H +ATOM 3146 HD2 TYR A 199 -35.552 -53.805 28.456 1.00 20.00 H +ATOM 3147 HE1 TYR A 199 -35.548 -58.325 30.395 1.00 20.00 H +ATOM 3148 HE2 TYR A 199 -36.680 -55.642 27.279 1.00 20.00 H +ATOM 3149 HH TYR A 199 -37.345 -57.762 27.399 1.00 20.00 H +ATOM 3150 N GLU A 200 -34.636 -52.259 34.089 1.00 51.61 N +ATOM 3151 CA GLU A 200 -34.097 -51.261 35.002 1.00 54.89 C +ATOM 3152 C GLU A 200 -32.887 -51.817 35.740 1.00 54.92 C +ATOM 3153 O GLU A 200 -32.925 -52.935 36.266 1.00 54.62 O +ATOM 3154 CB GLU A 200 -35.156 -50.799 36.004 1.00 57.63 C +ATOM 3155 CG GLU A 200 -34.818 -49.473 36.677 1.00 58.04 C +ATOM 3156 CD GLU A 200 -35.686 -49.177 37.885 1.00 61.21 C +ATOM 3157 OE1 GLU A 200 -36.714 -49.864 38.075 1.00 63.30 O +ATOM 3158 OE2 GLU A 200 -35.333 -48.257 38.651 1.00 62.57 O +ATOM 3159 H GLU A 200 -35.321 -52.904 34.426 1.00 20.00 H +ATOM 3160 HA GLU A 200 -33.771 -50.385 34.422 1.00 20.00 H +ATOM 3161 HB2 GLU A 200 -36.112 -50.686 35.473 1.00 20.00 H +ATOM 3162 HB3 GLU A 200 -35.258 -51.569 36.783 1.00 20.00 H +ATOM 3163 HG2 GLU A 200 -33.767 -49.503 37.001 1.00 20.00 H +ATOM 3164 HG3 GLU A 200 -34.953 -48.665 35.943 1.00 20.00 H +ATOM 3165 N VAL A 201 -31.817 -51.025 35.773 1.00 60.04 N +ATOM 3166 CA VAL A 201 -30.579 -51.390 36.452 1.00 54.54 C +ATOM 3167 C VAL A 201 -30.219 -50.276 37.425 1.00 57.64 C +ATOM 3168 O VAL A 201 -30.926 -49.266 37.521 1.00 58.22 O +ATOM 3169 CB VAL A 201 -29.439 -51.636 35.447 1.00 54.46 C +ATOM 3170 CG1 VAL A 201 -29.822 -52.729 34.461 1.00 50.78 C +ATOM 3171 CG2 VAL A 201 -29.087 -50.346 34.715 1.00 59.97 C +ATOM 3172 H VAL A 201 -31.865 -50.139 35.311 1.00 20.00 H +ATOM 3173 HA VAL A 201 -30.738 -52.315 37.025 1.00 20.00 H +ATOM 3174 HB VAL A 201 -28.553 -51.969 36.008 1.00 20.00 H +ATOM 3175 HG11 VAL A 201 -28.996 -52.890 33.752 1.00 20.00 H +ATOM 3176 HG12 VAL A 201 -30.023 -53.662 35.008 1.00 20.00 H +ATOM 3177 HG13 VAL A 201 -30.724 -52.426 33.910 1.00 20.00 H +ATOM 3178 HG21 VAL A 201 -28.272 -50.539 34.002 1.00 20.00 H +ATOM 3179 HG22 VAL A 201 -29.971 -49.980 34.172 1.00 20.00 H +ATOM 3180 HG23 VAL A 201 -28.764 -49.588 35.444 1.00 20.00 H +ATOM 3181 N ILE A 202 -29.112 -50.443 38.143 1.00 55.68 N +ATOM 3182 CA ILE A 202 -28.649 -49.466 39.122 1.00 57.79 C +ATOM 3183 C ILE A 202 -27.198 -49.130 38.814 1.00 58.26 C +ATOM 3184 O ILE A 202 -26.339 -50.020 38.796 1.00 58.31 O +ATOM 3185 CB ILE A 202 -28.784 -49.985 40.562 1.00 63.80 C +ATOM 3186 CG1 ILE A 202 -30.243 -50.276 40.902 1.00 65.37 C +ATOM 3187 CG2 ILE A 202 -28.191 -48.987 41.540 1.00 63.85 C +ATOM 3188 CD1 ILE A 202 -30.453 -50.696 42.336 0.00 65.59 C +ATOM 3189 H ILE A 202 -28.574 -51.275 38.006 1.00 20.00 H +ATOM 3190 HA ILE A 202 -29.247 -48.547 39.029 1.00 20.00 H +ATOM 3191 HB ILE A 202 -28.218 -50.925 40.641 1.00 20.00 H +ATOM 3192 HG12 ILE A 202 -30.832 -49.366 40.715 1.00 20.00 H +ATOM 3193 HG13 ILE A 202 -30.599 -51.084 40.246 1.00 20.00 H +ATOM 3194 HG21 ILE A 202 -28.295 -49.372 42.565 1.00 20.00 H +ATOM 3195 HG22 ILE A 202 -27.126 -48.838 41.311 1.00 20.00 H +ATOM 3196 HG23 ILE A 202 -28.723 -48.028 41.453 1.00 20.00 H +ATOM 3197 HD11 ILE A 202 -31.522 -50.889 42.509 0.00 20.00 H +ATOM 3198 HD12 ILE A 202 -29.878 -51.612 42.538 0.00 20.00 H +ATOM 3199 HD13 ILE A 202 -30.111 -49.894 43.007 0.00 20.00 H +ATOM 3200 N ILE A 203 -26.928 -47.855 38.572 1.00 60.61 N +ATOM 3201 CA ILE A 203 -25.560 -47.368 38.431 1.00 57.74 C +ATOM 3202 C ILE A 203 -25.057 -46.943 39.805 1.00 54.69 C +ATOM 3203 O ILE A 203 -25.744 -46.215 40.528 1.00 54.64 O +ATOM 3204 CB ILE A 203 -25.505 -46.200 37.436 1.00 56.94 C +ATOM 3205 CG1 ILE A 203 -26.011 -46.645 36.063 1.00 54.86 C +ATOM 3206 CG2 ILE A 203 -24.103 -45.626 37.368 1.00 55.58 C +ATOM 3207 CD1 ILE A 203 -26.474 -45.502 35.198 1.00 61.64 C +ATOM 3208 H ILE A 203 -27.685 -47.207 38.483 1.00 20.00 H +ATOM 3209 HA ILE A 203 -24.918 -48.178 38.055 1.00 20.00 H +ATOM 3210 HB ILE A 203 -26.178 -45.412 37.805 1.00 20.00 H +ATOM 3211 HG12 ILE A 203 -25.195 -47.168 35.543 1.00 20.00 H +ATOM 3212 HG13 ILE A 203 -26.854 -47.336 36.209 1.00 20.00 H +ATOM 3213 HG21 ILE A 203 -24.082 -44.792 36.652 1.00 20.00 H +ATOM 3214 HG22 ILE A 203 -23.807 -45.262 38.363 1.00 20.00 H +ATOM 3215 HG23 ILE A 203 -23.402 -46.408 37.040 1.00 20.00 H +ATOM 3216 HD11 ILE A 203 -26.823 -45.892 34.230 1.00 20.00 H +ATOM 3217 HD12 ILE A 203 -27.298 -44.974 35.699 1.00 20.00 H +ATOM 3218 HD13 ILE A 203 -25.639 -44.806 35.033 1.00 20.00 H +ATOM 3219 N VAL A 204 -23.863 -47.395 40.175 1.00 52.35 N +ATOM 3220 CA VAL A 204 -23.328 -47.084 41.498 1.00 54.28 C +ATOM 3221 C VAL A 204 -22.129 -46.146 41.448 1.00 53.89 C +ATOM 3222 O VAL A 204 -21.751 -45.610 42.507 1.00 55.98 O +ATOM 3223 CB VAL A 204 -22.975 -48.365 42.280 1.00 57.67 C +ATOM 3224 CG1 VAL A 204 -24.165 -49.315 42.315 1.00 52.58 C +ATOM 3225 CG2 VAL A 204 -21.754 -49.045 41.693 1.00 54.98 C +ATOM 3226 H VAL A 204 -23.326 -47.953 39.542 1.00 20.00 H +ATOM 3227 HA VAL A 204 -24.116 -46.570 42.068 1.00 20.00 H +ATOM 3228 HB VAL A 204 -22.741 -48.074 43.315 1.00 20.00 H +ATOM 3229 HG11 VAL A 204 -23.895 -50.222 42.876 1.00 20.00 H +ATOM 3230 HG12 VAL A 204 -25.015 -48.819 42.807 1.00 20.00 H +ATOM 3231 HG13 VAL A 204 -24.445 -49.590 41.287 1.00 20.00 H +ATOM 3232 HG21 VAL A 204 -21.527 -49.953 42.270 1.00 20.00 H +ATOM 3233 HG22 VAL A 204 -21.953 -49.316 40.646 1.00 20.00 H +ATOM 3234 HG23 VAL A 204 -20.896 -48.359 41.737 1.00 20.00 H +ATOM 3235 N ARG A 205 -21.534 -45.907 40.284 1.00 51.33 N +ATOM 3236 CA ARG A 205 -20.358 -45.054 40.175 1.00 53.43 C +ATOM 3237 C ARG A 205 -20.123 -44.721 38.708 1.00 54.11 C +ATOM 3238 O ARG A 205 -20.397 -45.537 37.825 1.00 54.86 O +ATOM 3239 CB ARG A 205 -19.119 -45.732 40.784 1.00 52.64 C +ATOM 3240 CG ARG A 205 -17.827 -44.930 40.692 1.00 54.94 C +ATOM 3241 CD ARG A 205 -16.675 -45.684 41.356 1.00 55.67 C +ATOM 3242 NE ARG A 205 -15.361 -45.111 41.060 1.00 58.48 N +ATOM 3243 CZ ARG A 205 -14.693 -44.293 41.871 1.00 59.31 C +ATOM 3244 NH1 ARG A 205 -15.209 -43.935 43.040 1.00 55.60 N +ATOM 3245 NH2 ARG A 205 -13.504 -43.830 41.513 1.00 63.40 N +ATOM 3246 H ARG A 205 -21.906 -46.326 39.456 1.00 20.00 H +ATOM 3247 HA ARG A 205 -20.539 -44.115 40.720 1.00 20.00 H +ATOM 3248 HB2 ARG A 205 -19.325 -45.924 41.847 1.00 20.00 H +ATOM 3249 HB3 ARG A 205 -18.964 -46.688 40.262 1.00 20.00 H +ATOM 3250 HG2 ARG A 205 -17.583 -44.758 39.633 1.00 20.00 H +ATOM 3251 HG3 ARG A 205 -17.965 -43.963 41.198 1.00 20.00 H +ATOM 3252 HD2 ARG A 205 -16.827 -45.665 42.445 1.00 20.00 H +ATOM 3253 HD3 ARG A 205 -16.690 -46.725 41.002 1.00 20.00 H +ATOM 3254 HE ARG A 205 -14.935 -45.351 40.188 1.00 20.00 H +ATOM 3255 HH11 ARG A 205 -14.701 -43.320 43.644 1.00 20.00 H +ATOM 3256 HH12 ARG A 205 -16.106 -44.280 43.318 1.00 20.00 H +ATOM 3257 HH21 ARG A 205 -13.002 -43.216 42.122 1.00 20.00 H +ATOM 3258 HH22 ARG A 205 -13.108 -44.095 40.634 1.00 20.00 H +ATOM 3259 N VAL A 206 -19.617 -43.512 38.460 1.00 56.57 N +ATOM 3260 CA VAL A 206 -19.318 -43.039 37.112 1.00 58.25 C +ATOM 3261 C VAL A 206 -17.929 -42.411 37.103 1.00 60.17 C +ATOM 3262 O VAL A 206 -17.598 -41.616 37.990 1.00 59.41 O +ATOM 3263 CB VAL A 206 -20.367 -42.026 36.614 1.00 60.57 C +ATOM 3264 CG1 VAL A 206 -19.994 -41.513 35.232 1.00 56.83 C +ATOM 3265 CG2 VAL A 206 -21.756 -42.653 36.598 1.00 54.54 C +ATOM 3266 H VAL A 206 -19.434 -42.903 39.232 1.00 20.00 H +ATOM 3267 HA VAL A 206 -19.315 -43.895 36.421 1.00 20.00 H +ATOM 3268 HB VAL A 206 -20.379 -41.174 37.310 1.00 20.00 H +ATOM 3269 HG11 VAL A 206 -20.752 -40.792 34.891 1.00 20.00 H +ATOM 3270 HG12 VAL A 206 -19.012 -41.019 35.277 1.00 20.00 H +ATOM 3271 HG13 VAL A 206 -19.948 -42.357 34.528 1.00 20.00 H +ATOM 3272 HG21 VAL A 206 -22.488 -41.914 36.240 1.00 20.00 H +ATOM 3273 HG22 VAL A 206 -21.757 -43.525 35.927 1.00 20.00 H +ATOM 3274 HG23 VAL A 206 -22.025 -42.973 37.615 1.00 20.00 H +ATOM 3275 N GLU A 207 -17.127 -42.752 36.091 1.00 59.63 N +ATOM 3276 CA GLU A 207 -15.802 -42.179 35.908 1.00 63.51 C +ATOM 3277 C GLU A 207 -15.653 -41.631 34.497 1.00 59.82 C +ATOM 3278 O GLU A 207 -16.274 -42.124 33.551 1.00 59.59 O +ATOM 3279 CB GLU A 207 -14.694 -43.209 36.135 1.00 59.74 C +ATOM 3280 CG GLU A 207 -14.607 -43.807 37.516 1.00 61.57 C +ATOM 3281 CD GLU A 207 -13.621 -44.955 37.546 1.00 58.32 C +ATOM 3282 OE1 GLU A 207 -13.004 -45.215 36.493 1.00 62.19 O +ATOM 3283 OE2 GLU A 207 -13.468 -45.597 38.604 1.00 59.30 O +ATOM 3284 H GLU A 207 -17.451 -43.430 35.431 1.00 20.00 H +ATOM 3285 HA GLU A 207 -15.660 -41.353 36.620 1.00 20.00 H +ATOM 3286 HB2 GLU A 207 -14.852 -44.033 35.423 1.00 20.00 H +ATOM 3287 HB3 GLU A 207 -13.733 -42.719 35.922 1.00 20.00 H +ATOM 3288 HG2 GLU A 207 -14.279 -43.032 38.224 1.00 20.00 H +ATOM 3289 HG3 GLU A 207 -15.600 -44.177 37.812 1.00 20.00 H +ATOM 3290 N ILE A 208 -14.800 -40.620 34.362 1.00 60.03 N +ATOM 3291 CA ILE A 208 -14.356 -40.108 33.068 1.00 60.61 C +ATOM 3292 C ILE A 208 -12.838 -40.221 33.048 1.00 60.32 C +ATOM 3293 O ILE A 208 -12.146 -39.470 33.749 1.00 60.78 O +ATOM 3294 CB ILE A 208 -14.800 -38.659 32.824 1.00 60.13 C +ATOM 3295 CG1 ILE A 208 -16.311 -38.512 33.012 1.00 65.56 C +ATOM 3296 CG2 ILE A 208 -14.373 -38.206 31.433 1.00 61.72 C +ATOM 3297 CD1 ILE A 208 -17.134 -39.333 32.046 1.00 66.49 C +ATOM 3298 H ILE A 208 -14.444 -40.187 35.190 1.00 20.00 H +ATOM 3299 HA ILE A 208 -14.766 -40.738 32.265 1.00 20.00 H +ATOM 3300 HB ILE A 208 -14.298 -38.018 33.564 1.00 20.00 H +ATOM 3301 HG12 ILE A 208 -16.564 -38.826 34.035 1.00 20.00 H +ATOM 3302 HG13 ILE A 208 -16.575 -37.453 32.877 1.00 20.00 H +ATOM 3303 HG21 ILE A 208 -14.696 -37.167 31.270 1.00 20.00 H +ATOM 3304 HG22 ILE A 208 -13.278 -38.267 31.348 1.00 20.00 H +ATOM 3305 HG23 ILE A 208 -14.836 -38.857 30.677 1.00 20.00 H +ATOM 3306 HD11 ILE A 208 -18.204 -39.172 32.246 1.00 20.00 H +ATOM 3307 HD12 ILE A 208 -16.904 -39.026 31.015 1.00 20.00 H +ATOM 3308 HD13 ILE A 208 -16.893 -40.399 32.173 1.00 20.00 H +ATOM 3309 N ASN A 209 -12.319 -41.146 32.238 1.00 60.08 N +ATOM 3310 CA ASN A 209 -10.882 -41.432 32.192 1.00 58.64 C +ATOM 3311 C ASN A 209 -10.335 -41.713 33.588 1.00 57.26 C +ATOM 3312 O ASN A 209 -9.271 -41.227 33.974 1.00 58.38 O +ATOM 3313 CB ASN A 209 -10.111 -40.293 31.522 1.00 58.48 C +ATOM 3314 CG ASN A 209 -9.578 -40.677 30.159 1.00 61.61 C +ATOM 3315 OD1 ASN A 209 -9.904 -41.738 29.627 1.00 62.58 O +ATOM 3316 ND2 ASN A 209 -8.760 -39.810 29.580 1.00 59.16 N +ATOM 3317 H ASN A 209 -12.933 -41.663 31.641 1.00 20.00 H +ATOM 3318 HA ASN A 209 -10.729 -42.337 31.586 1.00 20.00 H +ATOM 3319 HB2 ASN A 209 -10.784 -39.431 31.407 1.00 20.00 H +ATOM 3320 HB3 ASN A 209 -9.264 -40.014 32.166 1.00 20.00 H +ATOM 3321 HD21 ASN A 209 -8.382 -40.007 28.675 1.00 20.00 H +ATOM 3322 HD22 ASN A 209 -8.521 -38.959 30.048 1.00 20.00 H +ATOM 3323 N GLY A 210 -11.078 -42.508 34.356 1.00 56.07 N +ATOM 3324 CA GLY A 210 -10.691 -42.865 35.701 1.00 55.87 C +ATOM 3325 C GLY A 210 -11.070 -41.871 36.775 1.00 58.48 C +ATOM 3326 O GLY A 210 -11.057 -42.232 37.959 1.00 55.88 O +ATOM 3327 H GLY A 210 -11.934 -42.871 33.988 1.00 20.00 H +ATOM 3328 HA2 GLY A 210 -11.167 -43.826 35.946 1.00 20.00 H +ATOM 3329 HA3 GLY A 210 -9.597 -42.982 35.719 1.00 20.00 H +ATOM 3330 N GLN A 211 -11.417 -40.640 36.413 1.00 60.27 N +ATOM 3331 CA GLN A 211 -11.710 -39.596 37.388 1.00 62.52 C +ATOM 3332 C GLN A 211 -13.161 -39.707 37.843 1.00 64.23 C +ATOM 3333 O GLN A 211 -14.084 -39.601 37.028 1.00 59.84 O +ATOM 3334 CB GLN A 211 -11.430 -38.216 36.795 1.00 62.13 C +ATOM 3335 CG GLN A 211 -11.600 -37.075 37.774 1.00 67.96 C +ATOM 3336 CD GLN A 211 -10.892 -35.818 37.316 1.00 74.64 C +ATOM 3337 OE1 GLN A 211 -10.439 -35.015 38.131 1.00 79.16 O +ATOM 3338 NE2 GLN A 211 -10.785 -35.644 36.004 1.00 75.81 N +ATOM 3339 H GLN A 211 -11.479 -40.422 35.439 1.00 20.00 H +ATOM 3340 HA GLN A 211 -11.062 -39.731 38.266 1.00 20.00 H +ATOM 3341 HB2 GLN A 211 -10.394 -38.203 36.426 1.00 20.00 H +ATOM 3342 HB3 GLN A 211 -12.121 -38.055 35.954 1.00 20.00 H +ATOM 3343 HG2 GLN A 211 -12.673 -36.858 37.882 1.00 20.00 H +ATOM 3344 HG3 GLN A 211 -11.188 -37.379 38.747 1.00 20.00 H +ATOM 3345 HE21 GLN A 211 -10.321 -34.835 35.643 1.00 20.00 H +ATOM 3346 HE22 GLN A 211 -11.168 -36.322 35.377 1.00 20.00 H +ATOM 3347 N ASP A 212 -13.353 -39.912 39.145 1.00 67.68 N +ATOM 3348 CA ASP A 212 -14.691 -40.044 39.709 1.00 65.71 C +ATOM 3349 C ASP A 212 -15.498 -38.766 39.501 1.00 62.61 C +ATOM 3350 O ASP A 212 -15.020 -37.663 39.785 1.00 59.39 O +ATOM 3351 CB ASP A 212 -14.583 -40.371 41.199 1.00 65.98 C +ATOM 3352 CG ASP A 212 -15.930 -40.584 41.850 1.00 65.42 C +ATOM 3353 OD1 ASP A 212 -16.911 -40.838 41.122 1.00 64.83 O +ATOM 3354 OD2 ASP A 212 -16.008 -40.495 43.094 1.00 64.64 O +ATOM 3355 H ASP A 212 -12.560 -39.977 39.751 1.00 20.00 H +ATOM 3356 HA ASP A 212 -15.216 -40.872 39.210 1.00 20.00 H +ATOM 3357 HB2 ASP A 212 -13.987 -41.288 41.315 1.00 20.00 H +ATOM 3358 HB3 ASP A 212 -14.075 -39.537 41.706 1.00 20.00 H +ATOM 3359 N LEU A 213 -16.735 -38.918 39.007 1.00 61.52 N +ATOM 3360 CA LEU A 213 -17.616 -37.765 38.845 1.00 64.07 C +ATOM 3361 C LEU A 213 -18.100 -37.240 40.192 1.00 66.17 C +ATOM 3362 O LEU A 213 -18.390 -36.044 40.319 1.00 67.68 O +ATOM 3363 CB LEU A 213 -18.801 -38.129 37.943 1.00 67.37 C +ATOM 3364 CG LEU A 213 -19.300 -37.073 36.950 1.00 71.47 C +ATOM 3365 CD1 LEU A 213 -18.194 -36.649 35.997 1.00 72.92 C +ATOM 3366 CD2 LEU A 213 -20.495 -37.608 36.171 1.00 74.61 C +ATOM 3367 H LEU A 213 -17.057 -39.828 38.747 1.00 20.00 H +ATOM 3368 HA LEU A 213 -17.054 -36.959 38.351 1.00 20.00 H +ATOM 3369 HB2 LEU A 213 -18.508 -39.014 37.360 1.00 20.00 H +ATOM 3370 HB3 LEU A 213 -19.645 -38.386 38.600 1.00 20.00 H +ATOM 3371 HG LEU A 213 -19.625 -36.190 37.520 1.00 20.00 H +ATOM 3372 HD11 LEU A 213 -18.581 -35.893 35.298 1.00 20.00 H +ATOM 3373 HD12 LEU A 213 -17.358 -36.223 36.572 1.00 20.00 H +ATOM 3374 HD13 LEU A 213 -17.842 -37.524 35.431 1.00 20.00 H +ATOM 3375 HD21 LEU A 213 -20.844 -36.842 35.462 1.00 20.00 H +ATOM 3376 HD22 LEU A 213 -20.197 -38.511 35.618 1.00 20.00 H +ATOM 3377 HD23 LEU A 213 -21.307 -37.857 36.870 1.00 20.00 H +ATOM 3378 N LYS A 214 -18.223 -38.124 41.189 1.00 69.44 N +ATOM 3379 CA LYS A 214 -18.277 -37.745 42.607 1.00 72.83 C +ATOM 3380 C LYS A 214 -19.606 -37.084 42.988 1.00 75.69 C +ATOM 3381 O LYS A 214 -19.640 -35.979 43.530 1.00 73.06 O +ATOM 3382 CB LYS A 214 -17.092 -36.842 42.971 1.00 76.28 C +ATOM 3383 CG LYS A 214 -16.706 -36.870 44.437 1.00 79.36 C +ATOM 3384 CD LYS A 214 -15.474 -36.016 44.691 0.00 81.29 C +ATOM 3385 CE LYS A 214 -15.097 -36.022 46.164 0.00 83.32 C +ATOM 3386 NZ LYS A 214 -13.904 -35.176 46.444 0.00 84.57 N +ATOM 3387 H LYS A 214 -18.281 -39.095 40.956 1.00 20.00 H +ATOM 3388 HA LYS A 214 -18.185 -38.662 43.208 1.00 20.00 H +ATOM 3389 HB2 LYS A 214 -16.221 -37.163 42.381 1.00 20.00 H +ATOM 3390 HB3 LYS A 214 -17.354 -35.807 42.705 1.00 20.00 H +ATOM 3391 HG2 LYS A 214 -17.543 -36.482 45.037 1.00 20.00 H +ATOM 3392 HG3 LYS A 214 -16.492 -37.908 44.733 1.00 20.00 H +ATOM 3393 HD2 LYS A 214 -14.634 -36.414 44.104 0.00 20.00 H +ATOM 3394 HD3 LYS A 214 -15.683 -34.982 44.378 0.00 20.00 H +ATOM 3395 HE2 LYS A 214 -15.947 -35.640 46.749 0.00 20.00 H +ATOM 3396 HE3 LYS A 214 -14.877 -37.056 46.469 0.00 20.00 H +ATOM 3397 HZ1 LYS A 214 -13.693 -35.209 47.421 0.00 20.00 H +ATOM 3398 HZ2 LYS A 214 -13.123 -35.519 45.922 0.00 20.00 H +ATOM 3399 HZ3 LYS A 214 -14.095 -34.232 46.176 0.00 20.00 H +ATOM 3400 N MET A 215 -20.706 -37.783 42.724 1.00 77.97 N +ATOM 3401 CA MET A 215 -22.030 -37.323 43.112 1.00 76.06 C +ATOM 3402 C MET A 215 -22.695 -38.353 44.014 1.00 73.12 C +ATOM 3403 O MET A 215 -22.234 -39.492 44.142 1.00 71.71 O +ATOM 3404 CB MET A 215 -22.914 -37.062 41.884 1.00 76.76 C +ATOM 3405 CG MET A 215 -22.298 -36.116 40.865 1.00 76.73 C +ATOM 3406 SD MET A 215 -23.199 -36.039 39.304 1.00 76.94 S +ATOM 3407 CE MET A 215 -24.778 -35.370 39.830 1.00 79.22 C +ATOM 3408 H MET A 215 -20.620 -38.655 42.242 1.00 20.00 H +ATOM 3409 HA MET A 215 -21.936 -36.382 43.673 1.00 20.00 H +ATOM 3410 HB2 MET A 215 -23.109 -38.024 41.388 1.00 20.00 H +ATOM 3411 HB3 MET A 215 -23.864 -36.628 42.228 1.00 20.00 H +ATOM 3412 HG2 MET A 215 -22.272 -35.106 41.301 1.00 20.00 H +ATOM 3413 HG3 MET A 215 -21.271 -36.452 40.657 1.00 20.00 H +ATOM 3414 HE1 MET A 215 -25.423 -35.217 38.952 1.00 20.00 H +ATOM 3415 HE2 MET A 215 -25.262 -36.075 40.522 1.00 20.00 H +ATOM 3416 HE3 MET A 215 -24.617 -34.408 40.339 1.00 20.00 H +ATOM 3417 N ASP A 216 -23.774 -37.930 44.666 1.00 75.63 N +ATOM 3418 CA ASP A 216 -24.653 -38.885 45.320 1.00 81.18 C +ATOM 3419 C ASP A 216 -25.124 -39.890 44.278 1.00 78.58 C +ATOM 3420 O ASP A 216 -25.668 -39.509 43.237 1.00 80.49 O +ATOM 3421 CB ASP A 216 -25.842 -38.164 45.953 1.00 87.60 C +ATOM 3422 CG ASP A 216 -26.550 -39.004 46.997 1.00 91.49 C +ATOM 3423 OD1 ASP A 216 -26.513 -40.247 46.892 1.00 90.04 O +ATOM 3424 OD2 ASP A 216 -27.145 -38.415 47.925 1.00 91.04 O +ATOM 3425 H ASP A 216 -23.981 -36.952 44.706 1.00 20.00 H +ATOM 3426 HA ASP A 216 -24.102 -39.420 46.108 1.00 20.00 H +ATOM 3427 HB2 ASP A 216 -25.480 -37.242 46.431 1.00 20.00 H +ATOM 3428 HB3 ASP A 216 -26.561 -37.909 45.160 1.00 20.00 H +ATOM 3429 N CYS A 217 -24.893 -41.179 44.541 1.00 75.34 N +ATOM 3430 CA CYS A 217 -25.154 -42.168 43.500 1.00 75.74 C +ATOM 3431 C CYS A 217 -26.634 -42.299 43.166 1.00 74.41 C +ATOM 3432 O CYS A 217 -26.969 -42.921 42.155 1.00 74.45 O +ATOM 3433 CB CYS A 217 -24.579 -43.533 43.885 1.00 78.29 C +ATOM 3434 SG CYS A 217 -25.288 -44.308 45.346 1.00 79.47 S +ATOM 3435 H CYS A 217 -24.547 -41.461 45.436 1.00 20.00 H +ATOM 3436 HA CYS A 217 -24.639 -41.844 42.584 1.00 20.00 H +ATOM 3437 HB2 CYS A 217 -24.733 -44.214 43.035 1.00 20.00 H +ATOM 3438 HB3 CYS A 217 -23.501 -43.405 44.062 1.00 20.00 H +ATOM 3439 N LYS A 218 -27.528 -41.730 43.976 1.00 75.59 N +ATOM 3440 CA LYS A 218 -28.931 -41.671 43.573 1.00 73.75 C +ATOM 3441 C LYS A 218 -29.126 -40.799 42.341 1.00 70.62 C +ATOM 3442 O LYS A 218 -30.038 -41.047 41.545 1.00 73.72 O +ATOM 3443 CB LYS A 218 -29.800 -41.150 44.717 1.00 76.72 C +ATOM 3444 CG LYS A 218 -30.060 -42.134 45.839 1.00 77.28 C +ATOM 3445 CD LYS A 218 -31.003 -41.508 46.857 1.00 79.66 C +ATOM 3446 CE LYS A 218 -31.379 -42.467 47.974 0.00 78.20 C +ATOM 3447 NZ LYS A 218 -30.199 -42.876 48.785 0.00 79.25 N +ATOM 3448 H LYS A 218 -27.240 -41.346 44.853 1.00 20.00 H +ATOM 3449 HA LYS A 218 -29.271 -42.688 43.326 1.00 20.00 H +ATOM 3450 HB2 LYS A 218 -29.301 -40.269 45.147 1.00 20.00 H +ATOM 3451 HB3 LYS A 218 -30.771 -40.852 44.296 1.00 20.00 H +ATOM 3452 HG2 LYS A 218 -30.518 -43.046 45.428 1.00 20.00 H +ATOM 3453 HG3 LYS A 218 -29.109 -42.390 46.329 1.00 20.00 H +ATOM 3454 HD2 LYS A 218 -30.511 -40.629 47.299 1.00 20.00 H +ATOM 3455 HD3 LYS A 218 -31.921 -41.193 46.339 1.00 20.00 H +ATOM 3456 HE2 LYS A 218 -32.109 -41.974 48.633 0.00 20.00 H +ATOM 3457 HE3 LYS A 218 -31.833 -43.366 47.531 0.00 20.00 H +ATOM 3458 HZ1 LYS A 218 -30.489 -43.068 49.723 0.00 20.00 H +ATOM 3459 HZ2 LYS A 218 -29.791 -43.698 48.388 0.00 20.00 H +ATOM 3460 HZ3 LYS A 218 -29.525 -42.137 48.789 0.00 20.00 H +ATOM 3461 N GLU A 219 -28.288 -39.774 42.167 1.00 69.10 N +ATOM 3462 CA GLU A 219 -28.431 -38.894 41.011 1.00 69.24 C +ATOM 3463 C GLU A 219 -28.237 -39.651 39.707 1.00 67.12 C +ATOM 3464 O GLU A 219 -28.841 -39.297 38.688 1.00 68.17 O +ATOM 3465 CB GLU A 219 -27.435 -37.738 41.102 1.00 71.38 C +ATOM 3466 CG GLU A 219 -27.584 -36.900 42.355 1.00 75.78 C +ATOM 3467 CD GLU A 219 -28.835 -36.047 42.342 0.00 75.12 C +ATOM 3468 OE1 GLU A 219 -29.239 -35.598 41.248 0.00 75.17 O +ATOM 3469 OE2 GLU A 219 -29.418 -35.833 43.424 0.00 75.88 O +ATOM 3470 H GLU A 219 -27.559 -39.609 42.832 1.00 20.00 H +ATOM 3471 HA GLU A 219 -29.445 -38.469 41.011 1.00 20.00 H +ATOM 3472 HB2 GLU A 219 -26.417 -38.155 41.083 1.00 20.00 H +ATOM 3473 HB3 GLU A 219 -27.581 -37.085 40.229 1.00 20.00 H +ATOM 3474 HG2 GLU A 219 -27.625 -37.572 43.225 1.00 20.00 H +ATOM 3475 HG3 GLU A 219 -26.709 -36.240 42.443 1.00 20.00 H +ATOM 3476 N TYR A 220 -27.402 -40.692 39.718 1.00 62.58 N +ATOM 3477 CA TYR A 220 -27.216 -41.501 38.522 1.00 60.62 C +ATOM 3478 C TYR A 220 -28.469 -42.288 38.151 1.00 61.03 C +ATOM 3479 O TYR A 220 -28.612 -42.685 36.990 1.00 63.48 O +ATOM 3480 CB TYR A 220 -26.042 -42.462 38.716 1.00 58.51 C +ATOM 3481 CG TYR A 220 -24.726 -41.797 39.077 1.00 60.80 C +ATOM 3482 CD1 TYR A 220 -24.279 -40.666 38.406 1.00 59.44 C +ATOM 3483 CD2 TYR A 220 -23.930 -42.309 40.092 1.00 63.15 C +ATOM 3484 CE1 TYR A 220 -23.072 -40.063 38.737 1.00 60.62 C +ATOM 3485 CE2 TYR A 220 -22.726 -41.714 40.430 1.00 67.12 C +ATOM 3486 CZ TYR A 220 -22.301 -40.592 39.751 1.00 65.29 C +ATOM 3487 OH TYR A 220 -21.101 -40.001 40.087 1.00 66.09 O +ATOM 3488 H TYR A 220 -26.901 -40.918 40.553 1.00 20.00 H +ATOM 3489 HA TYR A 220 -26.972 -40.837 37.680 1.00 20.00 H +ATOM 3490 HB2 TYR A 220 -26.303 -43.163 39.522 1.00 20.00 H +ATOM 3491 HB3 TYR A 220 -25.898 -43.019 37.779 1.00 20.00 H +ATOM 3492 HD1 TYR A 220 -24.881 -40.248 37.613 1.00 20.00 H +ATOM 3493 HD2 TYR A 220 -24.256 -43.188 40.628 1.00 20.00 H +ATOM 3494 HE1 TYR A 220 -22.739 -39.185 38.203 1.00 20.00 H +ATOM 3495 HE2 TYR A 220 -22.122 -42.128 41.223 1.00 20.00 H +ATOM 3496 HH TYR A 220 -21.196 -39.056 40.065 1.00 20.00 H +ATOM 3497 N ASN A 221 -29.377 -42.525 39.100 1.00 62.68 N +ATOM 3498 CA ASN A 221 -30.558 -43.349 38.860 1.00 66.00 C +ATOM 3499 C ASN A 221 -31.856 -42.607 39.171 1.00 68.45 C +ATOM 3500 O ASN A 221 -32.839 -43.222 39.588 1.00 69.69 O +ATOM 3501 CB ASN A 221 -30.498 -44.646 39.670 1.00 62.99 C +ATOM 3502 CG ASN A 221 -29.164 -45.358 39.549 1.00 64.78 C +ATOM 3503 OD1 ASN A 221 -28.828 -45.904 38.498 1.00 61.99 O +ATOM 3504 ND2 ASN A 221 -28.401 -45.367 40.636 1.00 64.51 N +ATOM 3505 H ASN A 221 -29.244 -42.124 40.007 1.00 20.00 H +ATOM 3506 HA ASN A 221 -30.579 -43.624 37.795 1.00 20.00 H +ATOM 3507 HB2 ASN A 221 -30.673 -44.406 40.729 1.00 20.00 H +ATOM 3508 HB3 ASN A 221 -31.289 -45.320 39.311 1.00 20.00 H +ATOM 3509 HD21 ASN A 221 -27.515 -45.830 40.621 1.00 20.00 H +ATOM 3510 HD22 ASN A 221 -28.713 -44.911 41.469 1.00 20.00 H +ATOM 3511 N TYR A 222 -31.882 -41.294 38.973 1.00 65.11 N +ATOM 3512 CA TYR A 222 -33.086 -40.502 39.202 1.00 69.38 C +ATOM 3513 C TYR A 222 -33.710 -40.156 37.853 1.00 69.49 C +ATOM 3514 O TYR A 222 -33.122 -39.406 37.067 1.00 68.03 O +ATOM 3515 CB TYR A 222 -32.783 -39.237 40.001 1.00 79.09 C +ATOM 3516 CG TYR A 222 -33.998 -38.360 40.115 1.00 86.76 C +ATOM 3517 CD1 TYR A 222 -35.048 -38.719 40.942 1.00 87.26 C +ATOM 3518 CD2 TYR A 222 -34.113 -37.195 39.371 1.00 87.23 C +ATOM 3519 CE1 TYR A 222 -36.173 -37.938 41.044 1.00 89.12 C +ATOM 3520 CE2 TYR A 222 -35.237 -36.403 39.465 1.00 87.39 C +ATOM 3521 CZ TYR A 222 -36.266 -36.779 40.304 1.00 89.70 C +ATOM 3522 OH TYR A 222 -37.397 -36.000 40.407 1.00 93.18 O +ATOM 3523 H TYR A 222 -31.052 -40.834 38.658 1.00 20.00 H +ATOM 3524 HA TYR A 222 -33.810 -41.104 39.772 1.00 20.00 H +ATOM 3525 HB2 TYR A 222 -32.450 -39.521 41.010 1.00 20.00 H +ATOM 3526 HB3 TYR A 222 -31.983 -38.677 39.495 1.00 20.00 H +ATOM 3527 HD1 TYR A 222 -34.981 -39.630 41.518 1.00 20.00 H +ATOM 3528 HD2 TYR A 222 -33.311 -36.904 38.709 1.00 20.00 H +ATOM 3529 HE1 TYR A 222 -36.980 -38.230 41.700 1.00 20.00 H +ATOM 3530 HE2 TYR A 222 -35.312 -35.494 38.886 1.00 20.00 H +ATOM 3531 HH TYR A 222 -37.148 -35.085 40.466 1.00 20.00 H +ATOM 3532 N ASP A 223 -34.911 -40.673 37.596 1.00 66.22 N +ATOM 3533 CA ASP A 223 -35.668 -41.451 38.577 1.00 67.50 C +ATOM 3534 C ASP A 223 -35.618 -42.943 38.268 1.00 69.94 C +ATOM 3535 O ASP A 223 -36.261 -43.752 38.941 1.00 71.40 O +ATOM 3536 CB ASP A 223 -37.118 -40.975 38.630 1.00 71.13 C +ATOM 3537 CG ASP A 223 -37.800 -41.024 37.276 1.00 72.56 C +ATOM 3538 OD1 ASP A 223 -37.092 -41.132 36.253 1.00 75.01 O +ATOM 3539 OD2 ASP A 223 -39.047 -40.945 37.238 1.00 74.64 O +ATOM 3540 H ASP A 223 -35.313 -40.523 36.693 1.00 20.00 H +ATOM 3541 HA ASP A 223 -35.224 -41.295 39.571 1.00 20.00 H +ATOM 3542 HB2 ASP A 223 -37.674 -41.618 39.328 1.00 20.00 H +ATOM 3543 HB3 ASP A 223 -37.135 -39.938 38.995 1.00 20.00 H +ATOM 3544 N LYS A 224 -34.852 -43.294 37.239 1.00 69.93 N +ATOM 3545 CA LYS A 224 -34.632 -44.686 36.876 1.00 67.71 C +ATOM 3546 C LYS A 224 -33.446 -44.752 35.925 1.00 65.22 C +ATOM 3547 O LYS A 224 -33.059 -43.753 35.313 1.00 67.68 O +ATOM 3548 CB LYS A 224 -35.879 -45.312 36.236 1.00 67.18 C +ATOM 3549 CG LYS A 224 -36.200 -44.782 34.847 1.00 69.45 C +ATOM 3550 CD LYS A 224 -37.503 -45.361 34.306 1.00 71.01 C +ATOM 3551 CE LYS A 224 -37.883 -44.727 32.970 1.00 67.53 C +ATOM 3552 NZ LYS A 224 -38.221 -43.279 33.092 1.00 71.05 N +ATOM 3553 H LYS A 224 -34.413 -42.578 36.697 1.00 20.00 H +ATOM 3554 HA LYS A 224 -34.384 -45.262 37.780 1.00 20.00 H +ATOM 3555 HB2 LYS A 224 -35.721 -46.398 36.163 1.00 20.00 H +ATOM 3556 HB3 LYS A 224 -36.740 -45.110 36.890 1.00 20.00 H +ATOM 3557 HG2 LYS A 224 -36.291 -43.687 34.896 1.00 20.00 H +ATOM 3558 HG3 LYS A 224 -35.380 -45.052 34.165 1.00 20.00 H +ATOM 3559 HD2 LYS A 224 -37.382 -46.445 34.166 1.00 20.00 H +ATOM 3560 HD3 LYS A 224 -38.307 -45.173 35.033 1.00 20.00 H +ATOM 3561 HE2 LYS A 224 -37.035 -44.833 32.277 1.00 20.00 H +ATOM 3562 HE3 LYS A 224 -38.756 -45.259 32.564 1.00 20.00 H +ATOM 3563 HZ1 LYS A 224 -38.891 -43.032 32.392 1.00 20.00 H +ATOM 3564 HZ2 LYS A 224 -38.605 -43.102 33.998 1.00 20.00 H +ATOM 3565 HZ3 LYS A 224 -37.393 -42.732 32.968 1.00 20.00 H +ATOM 3566 N SER A 225 -32.861 -45.941 35.828 1.00 61.47 N +ATOM 3567 CA SER A 225 -31.796 -46.232 34.877 1.00 59.96 C +ATOM 3568 C SER A 225 -32.203 -47.470 34.094 1.00 59.96 C +ATOM 3569 O SER A 225 -32.444 -48.525 34.688 1.00 61.03 O +ATOM 3570 CB SER A 225 -30.458 -46.454 35.588 1.00 58.41 C +ATOM 3571 OG SER A 225 -29.871 -45.227 35.983 1.00 62.56 O +ATOM 3572 H SER A 225 -33.167 -46.672 36.438 1.00 20.00 H +ATOM 3573 HA SER A 225 -31.686 -45.391 34.177 1.00 20.00 H +ATOM 3574 HB2 SER A 225 -30.626 -47.074 36.481 1.00 20.00 H +ATOM 3575 HB3 SER A 225 -29.772 -46.975 34.904 1.00 20.00 H +ATOM 3576 HG SER A 225 -29.350 -45.362 36.766 1.00 20.00 H +ATOM 3577 N ILE A 226 -32.294 -47.342 32.769 1.00 58.11 N +ATOM 3578 CA ILE A 226 -32.775 -48.429 31.929 1.00 57.20 C +ATOM 3579 C ILE A 226 -31.815 -48.656 30.769 1.00 55.23 C +ATOM 3580 O ILE A 226 -30.983 -47.808 30.433 1.00 54.25 O +ATOM 3581 CB ILE A 226 -34.202 -48.171 31.392 1.00 58.15 C +ATOM 3582 CG1 ILE A 226 -34.175 -47.073 30.330 1.00 57.24 C +ATOM 3583 CG2 ILE A 226 -35.151 -47.805 32.526 1.00 55.51 C +ATOM 3584 CD1 ILE A 226 -35.464 -46.955 29.542 1.00 59.42 C +ATOM 3585 H ILE A 226 -32.025 -46.478 32.343 1.00 20.00 H +ATOM 3586 HA ILE A 226 -32.806 -49.351 32.528 1.00 20.00 H +ATOM 3587 HB ILE A 226 -34.563 -49.098 30.923 1.00 20.00 H +ATOM 3588 HG12 ILE A 226 -33.984 -46.112 30.829 1.00 20.00 H +ATOM 3589 HG13 ILE A 226 -33.357 -47.290 29.627 1.00 20.00 H +ATOM 3590 HG21 ILE A 226 -36.157 -47.627 32.119 1.00 20.00 H +ATOM 3591 HG22 ILE A 226 -35.190 -48.630 33.252 1.00 20.00 H +ATOM 3592 HG23 ILE A 226 -34.791 -46.894 33.026 1.00 20.00 H +ATOM 3593 HD11 ILE A 226 -35.369 -46.148 28.801 1.00 20.00 H +ATOM 3594 HD12 ILE A 226 -35.666 -47.905 29.026 1.00 20.00 H +ATOM 3595 HD13 ILE A 226 -36.293 -46.727 30.228 1.00 20.00 H +ATOM 3596 N VAL A 227 -31.954 -49.830 30.160 1.00 55.07 N +ATOM 3597 CA VAL A 227 -31.153 -50.265 29.022 1.00 53.20 C +ATOM 3598 C VAL A 227 -32.090 -50.352 27.824 1.00 52.83 C +ATOM 3599 O VAL A 227 -32.998 -51.191 27.800 1.00 51.59 O +ATOM 3600 CB VAL A 227 -30.474 -51.613 29.297 1.00 54.27 C +ATOM 3601 CG1 VAL A 227 -29.689 -52.076 28.084 1.00 48.74 C +ATOM 3602 CG2 VAL A 227 -29.585 -51.511 30.532 1.00 48.75 C +ATOM 3603 H VAL A 227 -32.654 -50.456 30.505 1.00 20.00 H +ATOM 3604 HA VAL A 227 -30.375 -49.517 28.809 1.00 20.00 H +ATOM 3605 HB VAL A 227 -31.260 -52.355 29.502 1.00 20.00 H +ATOM 3606 HG11 VAL A 227 -29.211 -53.042 28.303 1.00 20.00 H +ATOM 3607 HG12 VAL A 227 -30.370 -52.189 27.228 1.00 20.00 H +ATOM 3608 HG13 VAL A 227 -28.916 -51.332 27.842 1.00 20.00 H +ATOM 3609 HG21 VAL A 227 -29.104 -52.482 30.719 1.00 20.00 H +ATOM 3610 HG22 VAL A 227 -28.813 -50.745 30.366 1.00 20.00 H +ATOM 3611 HG23 VAL A 227 -30.197 -51.231 31.402 1.00 20.00 H +ATOM 3612 N ASP A 228 -31.876 -49.499 26.824 1.00 52.45 N +ATOM 3613 CA ASP A 228 -32.873 -49.258 25.780 1.00 54.40 C +ATOM 3614 C ASP A 228 -32.218 -49.281 24.401 1.00 53.01 C +ATOM 3615 O ASP A 228 -31.535 -48.328 24.017 1.00 54.10 O +ATOM 3616 CB ASP A 228 -33.578 -47.929 26.030 1.00 55.30 C +ATOM 3617 CG ASP A 228 -34.644 -47.623 24.995 1.00 57.42 C +ATOM 3618 OD1 ASP A 228 -35.096 -46.459 24.936 1.00 60.04 O +ATOM 3619 OD2 ASP A 228 -35.026 -48.541 24.240 1.00 61.80 O +ATOM 3620 H ASP A 228 -31.006 -49.007 26.785 1.00 20.00 H +ATOM 3621 HA ASP A 228 -33.627 -50.058 25.815 1.00 20.00 H +ATOM 3622 HB2 ASP A 228 -34.052 -47.964 27.022 1.00 20.00 H +ATOM 3623 HB3 ASP A 228 -32.828 -47.125 26.010 1.00 20.00 H +ATOM 3624 N SER A 229 -32.464 -50.352 23.641 1.00 50.62 N +ATOM 3625 CA SER A 229 -31.954 -50.429 22.278 1.00 49.51 C +ATOM 3626 C SER A 229 -32.717 -49.537 21.308 1.00 51.13 C +ATOM 3627 O SER A 229 -32.288 -49.396 20.158 1.00 51.61 O +ATOM 3628 CB SER A 229 -31.995 -51.871 21.772 1.00 52.28 C +ATOM 3629 OG SER A 229 -33.329 -52.298 21.564 1.00 47.45 O +ATOM 3630 H SER A 229 -33.004 -51.108 24.011 1.00 20.00 H +ATOM 3631 HA SER A 229 -30.903 -50.104 22.278 1.00 20.00 H +ATOM 3632 HB2 SER A 229 -31.445 -51.935 20.822 1.00 20.00 H +ATOM 3633 HB3 SER A 229 -31.519 -52.527 22.516 1.00 20.00 H +ATOM 3634 HG SER A 229 -33.597 -52.081 20.679 1.00 20.00 H +ATOM 3635 N GLY A 230 -33.833 -48.950 21.727 1.00 52.64 N +ATOM 3636 CA GLY A 230 -34.587 -48.022 20.912 1.00 53.64 C +ATOM 3637 C GLY A 230 -34.179 -46.575 21.065 1.00 58.14 C +ATOM 3638 O GLY A 230 -34.915 -45.680 20.635 1.00 54.55 O +ATOM 3639 H GLY A 230 -34.167 -49.159 22.646 1.00 20.00 H +ATOM 3640 HA2 GLY A 230 -34.455 -48.306 19.858 1.00 20.00 H +ATOM 3641 HA3 GLY A 230 -35.649 -48.110 21.185 1.00 20.00 H +ATOM 3642 N THR A 231 -33.029 -46.317 21.683 1.00 52.19 N +ATOM 3643 CA THR A 231 -32.495 -44.974 21.847 1.00 53.63 C +ATOM 3644 C THR A 231 -31.061 -44.973 21.354 1.00 52.92 C +ATOM 3645 O THR A 231 -30.304 -45.903 21.645 1.00 53.65 O +ATOM 3646 CB THR A 231 -32.551 -44.523 23.311 1.00 53.49 C +ATOM 3647 OG1 THR A 231 -33.917 -44.414 23.728 1.00 54.98 O +ATOM 3648 CG2 THR A 231 -31.863 -43.172 23.486 1.00 54.91 C +ATOM 3649 H THR A 231 -32.506 -47.085 22.053 1.00 20.00 H +ATOM 3650 HA THR A 231 -33.079 -44.267 21.240 1.00 20.00 H +ATOM 3651 HB THR A 231 -32.028 -45.268 23.928 1.00 20.00 H +ATOM 3652 HG1 THR A 231 -34.273 -45.282 23.879 1.00 20.00 H +ATOM 3653 HG21 THR A 231 -31.915 -42.868 24.542 1.00 20.00 H +ATOM 3654 HG22 THR A 231 -30.810 -43.255 23.179 1.00 20.00 H +ATOM 3655 HG23 THR A 231 -32.368 -42.420 22.863 1.00 20.00 H +ATOM 3656 N THR A 232 -30.694 -43.944 20.596 1.00 53.01 N +ATOM 3657 CA THR A 232 -29.318 -43.848 20.128 1.00 59.39 C +ATOM 3658 C THR A 232 -28.376 -43.490 21.269 1.00 59.85 C +ATOM 3659 O THR A 232 -27.389 -44.191 21.518 1.00 60.35 O +ATOM 3660 CB THR A 232 -29.210 -42.812 19.013 1.00 57.34 C +ATOM 3661 OG1 THR A 232 -29.927 -43.267 17.860 1.00 58.20 O +ATOM 3662 CG2 THR A 232 -27.754 -42.598 18.646 1.00 51.87 C +ATOM 3663 H THR A 232 -31.359 -43.240 20.348 1.00 20.00 H +ATOM 3664 HA THR A 232 -29.009 -44.822 19.721 1.00 20.00 H +ATOM 3665 HB THR A 232 -29.632 -41.861 19.370 1.00 20.00 H +ATOM 3666 HG1 THR A 232 -29.324 -43.375 17.134 1.00 20.00 H +ATOM 3667 HG21 THR A 232 -27.684 -41.850 17.842 1.00 20.00 H +ATOM 3668 HG22 THR A 232 -27.202 -42.241 19.528 1.00 20.00 H +ATOM 3669 HG23 THR A 232 -27.319 -43.548 18.302 1.00 20.00 H +ATOM 3670 N ASN A 233 -28.690 -42.424 21.994 1.00 57.95 N +ATOM 3671 CA ASN A 233 -27.738 -41.752 22.862 1.00 54.80 C +ATOM 3672 C ASN A 233 -27.616 -42.419 24.223 1.00 55.41 C +ATOM 3673 O ASN A 233 -28.499 -43.150 24.677 1.00 57.83 O +ATOM 3674 CB ASN A 233 -28.147 -40.295 23.077 1.00 57.96 C +ATOM 3675 CG ASN A 233 -27.966 -39.449 21.839 1.00 59.34 C +ATOM 3676 OD1 ASN A 233 -27.559 -39.939 20.788 1.00 59.14 O +ATOM 3677 ND2 ASN A 233 -28.274 -38.162 21.958 1.00 59.90 N +ATOM 3678 H ASN A 233 -29.623 -42.067 21.941 1.00 20.00 H +ATOM 3679 HA ASN A 233 -26.747 -41.762 22.385 1.00 20.00 H +ATOM 3680 HB2 ASN A 233 -29.207 -40.267 23.370 1.00 20.00 H +ATOM 3681 HB3 ASN A 233 -27.531 -39.872 23.885 1.00 20.00 H +ATOM 3682 HD21 ASN A 233 -28.178 -37.550 21.173 1.00 20.00 H +ATOM 3683 HD22 ASN A 233 -28.602 -37.805 22.833 1.00 20.00 H +ATOM 3684 N LEU A 234 -26.486 -42.145 24.872 1.00 56.03 N +ATOM 3685 CA LEU A 234 -26.392 -42.226 26.321 1.00 57.02 C +ATOM 3686 C LEU A 234 -27.049 -40.970 26.880 1.00 57.78 C +ATOM 3687 O LEU A 234 -26.539 -39.859 26.695 1.00 60.67 O +ATOM 3688 CB LEU A 234 -24.936 -42.340 26.766 1.00 55.53 C +ATOM 3689 CG LEU A 234 -24.706 -42.306 28.278 1.00 56.49 C +ATOM 3690 CD1 LEU A 234 -25.477 -43.426 28.954 1.00 55.61 C +ATOM 3691 CD2 LEU A 234 -23.220 -42.385 28.622 1.00 56.43 C +ATOM 3692 H LEU A 234 -25.678 -41.876 24.348 1.00 20.00 H +ATOM 3693 HA LEU A 234 -26.944 -43.107 26.682 1.00 20.00 H +ATOM 3694 HB2 LEU A 234 -24.538 -43.292 26.384 1.00 20.00 H +ATOM 3695 HB3 LEU A 234 -24.378 -41.504 26.319 1.00 20.00 H +ATOM 3696 HG LEU A 234 -25.092 -41.348 28.658 1.00 20.00 H +ATOM 3697 HD11 LEU A 234 -25.302 -43.389 30.039 1.00 20.00 H +ATOM 3698 HD12 LEU A 234 -26.552 -43.306 28.751 1.00 20.00 H +ATOM 3699 HD13 LEU A 234 -25.136 -44.395 28.561 1.00 20.00 H +ATOM 3700 HD21 LEU A 234 -23.094 -42.358 29.714 1.00 20.00 H +ATOM 3701 HD22 LEU A 234 -22.802 -43.323 28.228 1.00 20.00 H +ATOM 3702 HD23 LEU A 234 -22.694 -41.531 28.171 1.00 20.00 H +ATOM 3703 N ARG A 235 -28.194 -41.136 27.533 1.00 58.42 N +ATOM 3704 CA ARG A 235 -28.951 -40.026 28.093 1.00 59.35 C +ATOM 3705 C ARG A 235 -28.810 -40.034 29.608 1.00 60.36 C +ATOM 3706 O ARG A 235 -28.955 -41.078 30.251 1.00 59.15 O +ATOM 3707 CB ARG A 235 -30.427 -40.106 27.680 1.00 61.35 C +ATOM 3708 CG ARG A 235 -30.610 -40.196 26.167 1.00 61.05 C +ATOM 3709 CD ARG A 235 -32.070 -40.097 25.708 1.00 64.39 C +ATOM 3710 NE ARG A 235 -32.647 -38.768 25.901 1.00 63.42 N +ATOM 3711 CZ ARG A 235 -33.757 -38.532 26.594 1.00 71.81 C +ATOM 3712 NH1 ARG A 235 -34.419 -39.538 27.150 1.00 71.69 N +ATOM 3713 NH2 ARG A 235 -34.211 -37.292 26.723 1.00 74.36 N +ATOM 3714 H ARG A 235 -28.551 -42.063 27.645 1.00 20.00 H +ATOM 3715 HA ARG A 235 -28.539 -39.079 27.712 1.00 20.00 H +ATOM 3716 HB2 ARG A 235 -30.874 -40.998 28.142 1.00 20.00 H +ATOM 3717 HB3 ARG A 235 -30.944 -39.206 28.044 1.00 20.00 H +ATOM 3718 HG2 ARG A 235 -30.045 -39.376 25.701 1.00 20.00 H +ATOM 3719 HG3 ARG A 235 -30.205 -41.160 25.826 1.00 20.00 H +ATOM 3720 HD2 ARG A 235 -32.117 -40.346 24.638 1.00 20.00 H +ATOM 3721 HD3 ARG A 235 -32.666 -40.823 26.280 1.00 20.00 H +ATOM 3722 HE ARG A 235 -32.178 -37.988 25.486 1.00 20.00 H +ATOM 3723 HH11 ARG A 235 -35.258 -39.361 27.665 1.00 20.00 H +ATOM 3724 HH12 ARG A 235 -34.079 -40.474 27.055 1.00 20.00 H +ATOM 3725 HH21 ARG A 235 -35.050 -37.118 27.238 1.00 20.00 H +ATOM 3726 HH22 ARG A 235 -33.714 -36.532 26.305 1.00 20.00 H +ATOM 3727 N LEU A 236 -28.520 -38.861 30.169 1.00 61.20 N +ATOM 3728 CA LEU A 236 -28.187 -38.716 31.574 1.00 61.69 C +ATOM 3729 C LEU A 236 -29.051 -37.641 32.221 1.00 62.21 C +ATOM 3730 O LEU A 236 -29.412 -36.652 31.569 1.00 63.72 O +ATOM 3731 CB LEU A 236 -26.705 -38.347 31.747 1.00 60.80 C +ATOM 3732 CG LEU A 236 -25.689 -39.305 31.135 1.00 55.73 C +ATOM 3733 CD1 LEU A 236 -24.314 -38.660 31.109 1.00 62.54 C +ATOM 3734 CD2 LEU A 236 -25.662 -40.596 31.929 1.00 53.89 C +ATOM 3735 H LEU A 236 -28.532 -38.042 29.595 1.00 20.00 H +ATOM 3736 HA LEU A 236 -28.369 -39.668 32.093 1.00 20.00 H +ATOM 3737 HB2 LEU A 236 -26.551 -37.359 31.288 1.00 20.00 H +ATOM 3738 HB3 LEU A 236 -26.500 -38.287 32.826 1.00 20.00 H +ATOM 3739 HG LEU A 236 -25.994 -39.530 30.102 1.00 20.00 H +ATOM 3740 HD11 LEU A 236 -23.589 -39.359 30.666 1.00 20.00 H +ATOM 3741 HD12 LEU A 236 -24.352 -37.740 30.507 1.00 20.00 H +ATOM 3742 HD13 LEU A 236 -24.005 -38.414 32.136 1.00 20.00 H +ATOM 3743 HD21 LEU A 236 -24.928 -41.285 31.485 1.00 20.00 H +ATOM 3744 HD22 LEU A 236 -25.379 -40.380 32.970 1.00 20.00 H +ATOM 3745 HD23 LEU A 236 -26.659 -41.060 31.909 1.00 20.00 H +ATOM 3746 N PRO A 237 -29.397 -37.811 33.496 1.00 62.90 N +ATOM 3747 CA PRO A 237 -30.120 -36.754 34.212 1.00 63.87 C +ATOM 3748 C PRO A 237 -29.375 -35.427 34.155 1.00 66.85 C +ATOM 3749 O PRO A 237 -28.158 -35.382 33.961 1.00 64.15 O +ATOM 3750 CB PRO A 237 -30.206 -37.295 35.641 1.00 62.96 C +ATOM 3751 CG PRO A 237 -30.195 -38.775 35.467 1.00 66.22 C +ATOM 3752 CD PRO A 237 -29.301 -39.050 34.287 1.00 64.46 C +ATOM 3753 HA PRO A 237 -31.133 -36.631 33.800 1.00 20.00 H +ATOM 3754 HB2 PRO A 237 -29.342 -36.965 36.237 1.00 20.00 H +ATOM 3755 HB3 PRO A 237 -31.135 -36.965 36.129 1.00 20.00 H +ATOM 3756 HG2 PRO A 237 -29.797 -39.263 36.369 1.00 20.00 H +ATOM 3757 HG3 PRO A 237 -31.212 -39.144 35.269 1.00 20.00 H +ATOM 3758 HD2 PRO A 237 -29.663 -39.915 33.711 1.00 20.00 H +ATOM 3759 HD3 PRO A 237 -28.266 -39.232 34.611 1.00 20.00 H +ATOM 3760 N LYS A 238 -30.132 -34.342 34.337 1.00 69.04 N +ATOM 3761 CA LYS A 238 -29.609 -32.998 34.108 1.00 74.70 C +ATOM 3762 C LYS A 238 -28.331 -32.740 34.899 1.00 73.02 C +ATOM 3763 O LYS A 238 -27.332 -32.262 34.349 1.00 72.83 O +ATOM 3764 CB LYS A 238 -30.685 -31.970 34.456 1.00 79.89 C +ATOM 3765 CG LYS A 238 -30.276 -30.522 34.248 0.00 80.08 C +ATOM 3766 CD LYS A 238 -31.456 -29.594 34.486 0.00 82.10 C +ATOM 3767 CE LYS A 238 -31.067 -28.138 34.308 0.00 83.71 C +ATOM 3768 NZ LYS A 238 -30.050 -27.706 35.305 0.00 84.28 N +ATOM 3769 H LYS A 238 -31.079 -34.452 34.637 1.00 20.00 H +ATOM 3770 HA LYS A 238 -29.372 -32.889 33.039 1.00 20.00 H +ATOM 3771 HB2 LYS A 238 -31.565 -32.170 33.827 1.00 20.00 H +ATOM 3772 HB3 LYS A 238 -30.953 -32.101 35.515 1.00 20.00 H +ATOM 3773 HG2 LYS A 238 -29.469 -30.269 34.952 0.00 20.00 H +ATOM 3774 HG3 LYS A 238 -29.916 -30.392 33.217 0.00 20.00 H +ATOM 3775 HD2 LYS A 238 -32.254 -29.840 33.770 0.00 20.00 H +ATOM 3776 HD3 LYS A 238 -31.825 -29.742 35.512 0.00 20.00 H +ATOM 3777 HE2 LYS A 238 -30.654 -28.002 33.298 0.00 20.00 H +ATOM 3778 HE3 LYS A 238 -31.965 -27.514 34.424 0.00 20.00 H +ATOM 3779 HZ1 LYS A 238 -30.166 -26.732 35.500 0.00 20.00 H +ATOM 3780 HZ2 LYS A 238 -30.167 -28.230 36.148 0.00 20.00 H +ATOM 3781 HZ3 LYS A 238 -29.134 -27.865 34.937 0.00 20.00 H +ATOM 3782 N LYS A 239 -28.339 -33.063 36.191 1.00 79.32 N +ATOM 3783 CA LYS A 239 -27.165 -32.790 37.016 1.00 75.38 C +ATOM 3784 C LYS A 239 -25.998 -33.698 36.647 1.00 76.65 C +ATOM 3785 O LYS A 239 -24.833 -33.288 36.727 1.00 79.03 O +ATOM 3786 CB LYS A 239 -27.519 -32.937 38.495 1.00 78.88 C +ATOM 3787 CG LYS A 239 -28.575 -31.956 38.980 0.00 82.02 C +ATOM 3788 CD LYS A 239 -28.015 -30.547 39.126 0.00 84.82 C +ATOM 3789 CE LYS A 239 -29.039 -29.611 39.752 0.00 86.75 C +ATOM 3790 NZ LYS A 239 -28.512 -28.229 39.922 0.00 88.02 N +ATOM 3791 H LYS A 239 -29.147 -33.492 36.595 1.00 20.00 H +ATOM 3792 HA LYS A 239 -26.850 -31.750 36.847 1.00 20.00 H +ATOM 3793 HB2 LYS A 239 -27.893 -33.958 38.661 1.00 20.00 H +ATOM 3794 HB3 LYS A 239 -26.605 -32.781 39.086 1.00 20.00 H +ATOM 3795 HG2 LYS A 239 -29.402 -31.937 38.255 0.00 20.00 H +ATOM 3796 HG3 LYS A 239 -28.951 -32.292 39.957 0.00 20.00 H +ATOM 3797 HD2 LYS A 239 -27.121 -30.581 39.766 0.00 20.00 H +ATOM 3798 HD3 LYS A 239 -27.740 -30.165 38.132 0.00 20.00 H +ATOM 3799 HE2 LYS A 239 -29.927 -29.574 39.104 0.00 20.00 H +ATOM 3800 HE3 LYS A 239 -29.322 -30.006 40.739 0.00 20.00 H +ATOM 3801 HZ1 LYS A 239 -29.265 -27.574 39.856 0.00 20.00 H +ATOM 3802 HZ2 LYS A 239 -28.076 -28.146 40.818 0.00 20.00 H +ATOM 3803 HZ3 LYS A 239 -27.840 -28.038 39.206 0.00 20.00 H +ATOM 3804 N VAL A 240 -26.286 -34.932 36.237 1.00 73.94 N +ATOM 3805 CA VAL A 240 -25.219 -35.845 35.841 1.00 73.25 C +ATOM 3806 C VAL A 240 -24.643 -35.431 34.496 1.00 71.07 C +ATOM 3807 O VAL A 240 -23.421 -35.411 34.305 1.00 67.38 O +ATOM 3808 CB VAL A 240 -25.732 -37.295 35.815 1.00 70.04 C +ATOM 3809 CG1 VAL A 240 -24.619 -38.249 35.414 1.00 66.87 C +ATOM 3810 CG2 VAL A 240 -26.300 -37.670 37.170 1.00 67.76 C +ATOM 3811 H VAL A 240 -27.239 -35.234 36.200 1.00 20.00 H +ATOM 3812 HA VAL A 240 -24.412 -35.789 36.586 1.00 20.00 H +ATOM 3813 HB VAL A 240 -26.536 -37.363 35.068 1.00 20.00 H +ATOM 3814 HG11 VAL A 240 -25.005 -39.279 35.401 1.00 20.00 H +ATOM 3815 HG12 VAL A 240 -24.251 -37.983 34.412 1.00 20.00 H +ATOM 3816 HG13 VAL A 240 -23.795 -38.175 36.139 1.00 20.00 H +ATOM 3817 HG21 VAL A 240 -26.664 -38.708 37.141 1.00 20.00 H +ATOM 3818 HG22 VAL A 240 -25.515 -37.578 37.935 1.00 20.00 H +ATOM 3819 HG23 VAL A 240 -27.133 -36.996 37.417 1.00 20.00 H +ATOM 3820 N PHE A 241 -25.515 -35.088 33.547 1.00 67.68 N +ATOM 3821 CA PHE A 241 -25.069 -34.673 32.222 1.00 67.31 C +ATOM 3822 C PHE A 241 -24.134 -33.470 32.299 1.00 70.03 C +ATOM 3823 O PHE A 241 -23.094 -33.430 31.632 1.00 77.54 O +ATOM 3824 CB PHE A 241 -26.286 -34.362 31.348 1.00 68.56 C +ATOM 3825 CG PHE A 241 -25.948 -33.663 30.066 1.00 69.41 C +ATOM 3826 CD1 PHE A 241 -25.440 -34.370 28.989 1.00 69.46 C +ATOM 3827 CD2 PHE A 241 -26.146 -32.298 29.931 1.00 73.22 C +ATOM 3828 CE1 PHE A 241 -25.130 -33.728 27.806 1.00 69.84 C +ATOM 3829 CE2 PHE A 241 -25.836 -31.653 28.752 1.00 74.86 C +ATOM 3830 CZ PHE A 241 -25.327 -32.369 27.688 1.00 72.75 C +ATOM 3831 H PHE A 241 -26.494 -35.116 33.748 1.00 20.00 H +ATOM 3832 HA PHE A 241 -24.519 -35.503 31.755 1.00 20.00 H +ATOM 3833 HB2 PHE A 241 -26.789 -35.309 31.104 1.00 20.00 H +ATOM 3834 HB3 PHE A 241 -26.971 -33.721 31.923 1.00 20.00 H +ATOM 3835 HD1 PHE A 241 -25.285 -35.435 29.075 1.00 20.00 H +ATOM 3836 HD2 PHE A 241 -26.548 -31.733 30.759 1.00 20.00 H +ATOM 3837 HE1 PHE A 241 -24.733 -34.291 26.974 1.00 20.00 H +ATOM 3838 HE2 PHE A 241 -25.992 -30.588 28.662 1.00 20.00 H +ATOM 3839 HZ PHE A 241 -25.083 -31.865 26.764 1.00 20.00 H +ATOM 3840 N GLU A 242 -24.498 -32.472 33.106 1.00 69.38 N +ATOM 3841 CA GLU A 242 -23.672 -31.274 33.218 1.00 68.39 C +ATOM 3842 C GLU A 242 -22.296 -31.596 33.787 1.00 66.86 C +ATOM 3843 O GLU A 242 -21.280 -31.106 33.283 1.00 66.68 O +ATOM 3844 CB GLU A 242 -24.382 -30.225 34.071 1.00 70.60 C +ATOM 3845 CG GLU A 242 -25.584 -29.587 33.386 1.00 71.83 C +ATOM 3846 CD GLU A 242 -26.346 -28.663 34.308 0.00 76.60 C +ATOM 3847 OE1 GLU A 242 -25.716 -28.083 35.216 0.00 79.16 O +ATOM 3848 OE2 GLU A 242 -27.575 -28.525 34.128 0.00 78.74 O +ATOM 3849 H GLU A 242 -25.342 -32.545 33.637 1.00 20.00 H +ATOM 3850 HA GLU A 242 -23.530 -30.850 32.213 1.00 20.00 H +ATOM 3851 HB2 GLU A 242 -24.726 -30.707 34.998 1.00 20.00 H +ATOM 3852 HB3 GLU A 242 -23.661 -29.431 34.316 1.00 20.00 H +ATOM 3853 HG2 GLU A 242 -25.232 -29.010 32.519 1.00 20.00 H +ATOM 3854 HG3 GLU A 242 -26.261 -30.384 33.045 1.00 20.00 H +ATOM 3855 N ALA A 243 -22.240 -32.425 34.830 1.00 65.69 N +ATOM 3856 CA ALA A 243 -20.949 -32.826 35.383 1.00 63.04 C +ATOM 3857 C ALA A 243 -20.136 -33.622 34.369 1.00 63.92 C +ATOM 3858 O ALA A 243 -18.920 -33.440 34.252 1.00 62.90 O +ATOM 3859 CB ALA A 243 -21.152 -33.632 36.665 1.00 60.36 C +ATOM 3860 H ALA A 243 -23.085 -32.773 35.235 1.00 20.00 H +ATOM 3861 HA ALA A 243 -20.378 -31.921 35.640 1.00 20.00 H +ATOM 3862 HB1 ALA A 243 -20.174 -33.928 37.071 1.00 20.00 H +ATOM 3863 HB2 ALA A 243 -21.685 -33.016 37.404 1.00 20.00 H +ATOM 3864 HB3 ALA A 243 -21.744 -34.532 36.442 1.00 20.00 H +ATOM 3865 N ALA A 244 -20.794 -34.510 33.622 1.00 66.06 N +ATOM 3866 CA ALA A 244 -20.072 -35.349 32.670 1.00 65.09 C +ATOM 3867 C ALA A 244 -19.475 -34.517 31.542 1.00 66.79 C +ATOM 3868 O ALA A 244 -18.333 -34.739 31.126 1.00 68.59 O +ATOM 3869 CB ALA A 244 -20.997 -36.432 32.112 1.00 66.59 C +ATOM 3870 H ALA A 244 -21.785 -34.601 33.714 1.00 20.00 H +ATOM 3871 HA ALA A 244 -19.246 -35.849 33.196 1.00 20.00 H +ATOM 3872 HB1 ALA A 244 -20.442 -37.056 31.397 1.00 20.00 H +ATOM 3873 HB2 ALA A 244 -21.366 -37.059 32.937 1.00 20.00 H +ATOM 3874 HB3 ALA A 244 -21.849 -35.959 31.601 1.00 20.00 H +ATOM 3875 N VAL A 245 -20.233 -33.543 31.044 1.00 68.40 N +ATOM 3876 CA VAL A 245 -19.765 -32.743 29.915 1.00 70.73 C +ATOM 3877 C VAL A 245 -18.571 -31.888 30.319 1.00 71.11 C +ATOM 3878 O VAL A 245 -17.624 -31.712 29.543 1.00 72.13 O +ATOM 3879 CB VAL A 245 -20.919 -31.892 29.353 1.00 74.12 C +ATOM 3880 CG1 VAL A 245 -20.390 -30.806 28.436 1.00 76.85 C +ATOM 3881 CG2 VAL A 245 -21.894 -32.782 28.611 1.00 69.76 C +ATOM 3882 H VAL A 245 -21.130 -33.357 31.446 1.00 20.00 H +ATOM 3883 HA VAL A 245 -19.435 -33.424 29.117 1.00 20.00 H +ATOM 3884 HB VAL A 245 -21.444 -31.418 30.196 1.00 20.00 H +ATOM 3885 HG11 VAL A 245 -21.230 -30.212 28.047 1.00 20.00 H +ATOM 3886 HG12 VAL A 245 -19.708 -30.152 28.998 1.00 20.00 H +ATOM 3887 HG13 VAL A 245 -19.848 -31.267 27.597 1.00 20.00 H +ATOM 3888 HG21 VAL A 245 -22.717 -32.172 28.211 1.00 20.00 H +ATOM 3889 HG22 VAL A 245 -21.374 -33.285 27.782 1.00 20.00 H +ATOM 3890 HG23 VAL A 245 -22.299 -33.537 29.301 1.00 20.00 H +ATOM 3891 N LYS A 246 -18.594 -31.344 31.535 1.00 71.20 N +ATOM 3892 CA LYS A 246 -17.464 -30.555 32.012 1.00 71.27 C +ATOM 3893 C LYS A 246 -16.198 -31.402 32.088 1.00 70.24 C +ATOM 3894 O LYS A 246 -15.107 -30.945 31.727 1.00 66.58 O +ATOM 3895 CB LYS A 246 -17.798 -29.942 33.374 1.00 73.50 C +ATOM 3896 CG LYS A 246 -16.699 -29.089 33.978 1.00 76.76 C +ATOM 3897 CD LYS A 246 -17.196 -28.388 35.233 1.00 80.37 C +ATOM 3898 CE LYS A 246 -16.048 -27.804 36.040 1.00 80.73 C +ATOM 3899 NZ LYS A 246 -16.526 -27.093 37.259 1.00 83.81 N +ATOM 3900 H LYS A 246 -19.391 -31.478 32.124 1.00 20.00 H +ATOM 3901 HA LYS A 246 -17.281 -29.732 31.305 1.00 20.00 H +ATOM 3902 HB2 LYS A 246 -18.692 -29.313 33.255 1.00 20.00 H +ATOM 3903 HB3 LYS A 246 -18.017 -30.762 34.073 1.00 20.00 H +ATOM 3904 HG2 LYS A 246 -15.844 -29.731 34.237 1.00 20.00 H +ATOM 3905 HG3 LYS A 246 -16.382 -28.334 33.243 1.00 20.00 H +ATOM 3906 HD2 LYS A 246 -17.877 -27.575 34.942 1.00 20.00 H +ATOM 3907 HD3 LYS A 246 -17.737 -29.114 35.857 1.00 20.00 H +ATOM 3908 HE2 LYS A 246 -15.377 -28.621 36.346 1.00 20.00 H +ATOM 3909 HE3 LYS A 246 -15.496 -27.093 35.408 1.00 20.00 H +ATOM 3910 HZ1 LYS A 246 -15.742 -26.725 37.760 1.00 20.00 H +ATOM 3911 HZ2 LYS A 246 -17.132 -26.344 36.992 1.00 20.00 H +ATOM 3912 HZ3 LYS A 246 -17.025 -27.733 37.844 1.00 20.00 H +ATOM 3913 N SER A 247 -16.331 -32.651 32.540 1.00 70.82 N +ATOM 3914 CA SER A 247 -15.168 -33.526 32.657 1.00 66.83 C +ATOM 3915 C SER A 247 -14.656 -33.961 31.292 1.00 67.47 C +ATOM 3916 O SER A 247 -13.441 -34.066 31.084 1.00 68.95 O +ATOM 3917 CB SER A 247 -15.510 -34.744 33.513 1.00 66.28 C +ATOM 3918 OG SER A 247 -14.356 -35.529 33.755 1.00 68.02 O +ATOM 3919 H SER A 247 -17.235 -32.990 32.801 1.00 20.00 H +ATOM 3920 HA SER A 247 -14.361 -32.975 33.162 1.00 20.00 H +ATOM 3921 HB2 SER A 247 -15.923 -34.405 34.474 1.00 20.00 H +ATOM 3922 HB3 SER A 247 -16.258 -35.355 32.987 1.00 20.00 H +ATOM 3923 HG SER A 247 -13.715 -35.370 33.072 1.00 20.00 H +ATOM 3924 N ILE A 248 -15.565 -34.224 30.351 1.00 65.36 N +ATOM 3925 CA ILE A 248 -15.152 -34.606 29.002 1.00 63.55 C +ATOM 3926 C ILE A 248 -14.467 -33.441 28.301 1.00 64.16 C +ATOM 3927 O ILE A 248 -13.505 -33.630 27.546 1.00 65.51 O +ATOM 3928 CB ILE A 248 -16.358 -35.117 28.192 1.00 62.38 C +ATOM 3929 CG1 ILE A 248 -16.945 -36.364 28.845 1.00 61.70 C +ATOM 3930 CG2 ILE A 248 -15.953 -35.410 26.757 1.00 58.36 C +ATOM 3931 CD1 ILE A 248 -18.216 -36.845 28.196 1.00 59.05 C +ATOM 3932 H ILE A 248 -16.538 -34.159 30.571 1.00 20.00 H +ATOM 3933 HA ILE A 248 -14.426 -35.429 29.076 1.00 20.00 H +ATOM 3934 HB ILE A 248 -17.128 -34.331 28.185 1.00 20.00 H +ATOM 3935 HG12 ILE A 248 -16.199 -37.170 28.788 1.00 20.00 H +ATOM 3936 HG13 ILE A 248 -17.158 -36.136 29.900 1.00 20.00 H +ATOM 3937 HG21 ILE A 248 -16.827 -35.773 26.196 1.00 20.00 H +ATOM 3938 HG22 ILE A 248 -15.573 -34.490 26.288 1.00 20.00 H +ATOM 3939 HG23 ILE A 248 -15.166 -36.179 26.748 1.00 20.00 H +ATOM 3940 HD11 ILE A 248 -18.578 -37.743 28.718 1.00 20.00 H +ATOM 3941 HD12 ILE A 248 -18.979 -36.055 28.254 1.00 20.00 H +ATOM 3942 HD13 ILE A 248 -18.020 -37.089 27.142 1.00 20.00 H +ATOM 3943 N LYS A 249 -14.964 -32.222 28.515 1.00 68.00 N +ATOM 3944 CA LYS A 249 -14.297 -31.043 27.974 1.00 71.65 C +ATOM 3945 C LYS A 249 -12.874 -30.925 28.502 1.00 68.01 C +ATOM 3946 O LYS A 249 -11.931 -30.701 27.736 1.00 66.64 O +ATOM 3947 CB LYS A 249 -15.086 -29.783 28.324 1.00 77.31 C +ATOM 3948 CG LYS A 249 -16.357 -29.553 27.533 1.00 75.65 C +ATOM 3949 CD LYS A 249 -17.224 -28.552 28.279 1.00 81.29 C +ATOM 3950 CE LYS A 249 -18.164 -27.791 27.362 1.00 84.26 C +ATOM 3951 NZ LYS A 249 -19.106 -26.949 28.158 1.00 85.07 N +ATOM 3952 H LYS A 249 -15.801 -32.115 29.051 1.00 20.00 H +ATOM 3953 HA LYS A 249 -14.252 -31.127 26.878 1.00 20.00 H +ATOM 3954 HB2 LYS A 249 -15.358 -29.841 29.388 1.00 20.00 H +ATOM 3955 HB3 LYS A 249 -14.427 -28.917 28.161 1.00 20.00 H +ATOM 3956 HG2 LYS A 249 -16.107 -29.156 26.538 1.00 20.00 H +ATOM 3957 HG3 LYS A 249 -16.901 -30.503 27.423 1.00 20.00 H +ATOM 3958 HD2 LYS A 249 -17.823 -29.094 29.026 1.00 20.00 H +ATOM 3959 HD3 LYS A 249 -16.569 -27.830 28.788 1.00 20.00 H +ATOM 3960 HE2 LYS A 249 -17.574 -27.143 26.696 1.00 20.00 H +ATOM 3961 HE3 LYS A 249 -18.741 -28.508 26.760 1.00 20.00 H +ATOM 3962 HZ1 LYS A 249 -19.357 -26.138 27.629 1.00 20.00 H +ATOM 3963 HZ2 LYS A 249 -19.928 -27.477 28.369 1.00 20.00 H +ATOM 3964 HZ3 LYS A 249 -18.663 -26.667 29.009 1.00 20.00 H +ATOM 3965 N ALA A 250 -12.703 -31.063 29.818 1.00 68.63 N +ATOM 3966 CA ALA A 250 -11.382 -30.883 30.412 1.00 71.87 C +ATOM 3967 C ALA A 250 -10.405 -31.950 29.934 1.00 70.05 C +ATOM 3968 O ALA A 250 -9.226 -31.659 29.696 1.00 71.27 O +ATOM 3969 CB ALA A 250 -11.486 -30.889 31.937 1.00 72.23 C +ATOM 3970 H ALA A 250 -13.484 -31.291 30.400 1.00 20.00 H +ATOM 3971 HA ALA A 250 -10.988 -29.903 30.105 1.00 20.00 H +ATOM 3972 HB1 ALA A 250 -10.486 -30.753 32.374 1.00 20.00 H +ATOM 3973 HB2 ALA A 250 -12.143 -30.069 32.263 1.00 20.00 H +ATOM 3974 HB3 ALA A 250 -11.905 -31.850 32.272 1.00 20.00 H +ATOM 3975 N ALA A 251 -10.874 -33.189 29.781 1.00 68.44 N +ATOM 3976 CA ALA A 251 -9.983 -34.260 29.346 1.00 66.79 C +ATOM 3977 C ALA A 251 -9.579 -34.102 27.886 1.00 66.57 C +ATOM 3978 O ALA A 251 -8.484 -34.523 27.499 1.00 64.14 O +ATOM 3979 CB ALA A 251 -10.644 -35.620 29.570 1.00 68.38 C +ATOM 3980 H ALA A 251 -11.837 -33.384 29.965 1.00 20.00 H +ATOM 3981 HA ALA A 251 -9.068 -34.226 29.955 1.00 20.00 H +ATOM 3982 HB1 ALA A 251 -9.963 -36.418 29.239 1.00 20.00 H +ATOM 3983 HB2 ALA A 251 -10.866 -35.748 30.640 1.00 20.00 H +ATOM 3984 HB3 ALA A 251 -11.579 -35.673 28.993 1.00 20.00 H +ATOM 3985 N SER A 252 -10.434 -33.494 27.067 1.00 65.43 N +ATOM 3986 CA SER A 252 -10.171 -33.315 25.645 1.00 65.13 C +ATOM 3987 C SER A 252 -9.694 -31.908 25.315 1.00 70.26 C +ATOM 3988 O SER A 252 -9.844 -31.459 24.174 1.00 67.40 O +ATOM 3989 CB SER A 252 -11.428 -33.649 24.839 1.00 64.30 C +ATOM 3990 OG SER A 252 -12.542 -32.928 25.337 1.00 60.38 O +ATOM 3991 H SER A 252 -11.292 -33.146 27.443 1.00 20.00 H +ATOM 3992 HA SER A 252 -9.382 -34.018 25.342 1.00 20.00 H +ATOM 3993 HB2 SER A 252 -11.264 -33.380 23.785 1.00 20.00 H +ATOM 3994 HB3 SER A 252 -11.631 -34.727 24.915 1.00 20.00 H +ATOM 3995 HG SER A 252 -12.807 -33.292 26.174 1.00 20.00 H +ATOM 3996 N SER A 253 -9.110 -31.209 26.289 1.00 77.08 N +ATOM 3997 CA SER A 253 -8.876 -29.778 26.145 1.00 80.32 C +ATOM 3998 C SER A 253 -7.729 -29.435 25.205 1.00 82.48 C +ATOM 3999 O SER A 253 -7.473 -28.246 24.991 1.00 84.10 O +ATOM 4000 CB SER A 253 -8.617 -29.151 27.515 1.00 78.89 C +ATOM 4001 OG SER A 253 -7.345 -29.534 28.008 1.00 74.70 O +ATOM 4002 H SER A 253 -8.829 -31.673 27.129 1.00 20.00 H +ATOM 4003 HA SER A 253 -9.788 -29.317 25.738 1.00 20.00 H +ATOM 4004 HB2 SER A 253 -8.654 -28.055 27.424 1.00 20.00 H +ATOM 4005 HB3 SER A 253 -9.393 -29.487 28.219 1.00 20.00 H +ATOM 4006 HG SER A 253 -7.429 -30.333 28.516 1.00 20.00 H +ATOM 4007 N THR A 254 -7.029 -30.423 24.646 1.00 80.20 N +ATOM 4008 CA THR A 254 -6.005 -30.098 23.659 1.00 81.98 C +ATOM 4009 C THR A 254 -6.610 -29.584 22.361 1.00 80.08 C +ATOM 4010 O THR A 254 -5.896 -28.981 21.553 1.00 78.66 O +ATOM 4011 CB THR A 254 -5.115 -31.309 23.374 1.00 82.60 C +ATOM 4012 OG1 THR A 254 -5.927 -32.425 22.996 1.00 80.65 O +ATOM 4013 CG2 THR A 254 -4.301 -31.661 24.609 1.00 82.98 C +ATOM 4014 H THR A 254 -7.204 -31.374 24.900 1.00 20.00 H +ATOM 4015 HA THR A 254 -5.365 -29.303 24.068 1.00 20.00 H +ATOM 4016 HB THR A 254 -4.425 -31.053 22.557 1.00 20.00 H +ATOM 4017 HG1 THR A 254 -6.194 -32.330 22.089 1.00 20.00 H +ATOM 4018 HG21 THR A 254 -3.665 -32.532 24.394 1.00 20.00 H +ATOM 4019 HG22 THR A 254 -3.668 -30.805 24.887 1.00 20.00 H +ATOM 4020 HG23 THR A 254 -4.981 -31.900 25.440 1.00 20.00 H +ATOM 4021 N GLU A 255 -7.904 -29.809 22.148 1.00 83.87 N +ATOM 4022 CA GLU A 255 -8.648 -29.210 21.051 1.00 83.84 C +ATOM 4023 C GLU A 255 -9.948 -28.637 21.595 1.00 84.04 C +ATOM 4024 O GLU A 255 -10.598 -29.250 22.447 1.00 78.95 O +ATOM 4025 CB GLU A 255 -8.939 -30.226 19.936 1.00 81.56 C +ATOM 4026 CG GLU A 255 -7.731 -30.587 19.082 1.00 83.13 C +ATOM 4027 CD GLU A 255 -8.071 -31.571 17.978 1.00 83.12 C +ATOM 4028 OE1 GLU A 255 -9.265 -31.691 17.628 1.00 82.07 O +ATOM 4029 OE2 GLU A 255 -7.144 -32.232 17.463 1.00 80.86 O +ATOM 4030 H GLU A 255 -8.389 -30.420 22.773 1.00 20.00 H +ATOM 4031 HA GLU A 255 -8.059 -28.387 20.620 1.00 20.00 H +ATOM 4032 HB2 GLU A 255 -9.319 -31.147 20.401 1.00 20.00 H +ATOM 4033 HB3 GLU A 255 -9.711 -29.802 19.278 1.00 20.00 H +ATOM 4034 HG2 GLU A 255 -7.335 -29.668 18.625 1.00 20.00 H +ATOM 4035 HG3 GLU A 255 -6.963 -31.035 19.729 1.00 20.00 H +ATOM 4036 N LYS A 256 -10.313 -27.452 21.116 1.00 87.00 N +ATOM 4037 CA LYS A 256 -11.532 -26.781 21.542 1.00 87.83 C +ATOM 4038 C LYS A 256 -12.588 -26.887 20.452 1.00 85.48 C +ATOM 4039 O LYS A 256 -12.279 -26.799 19.260 1.00 85.19 O +ATOM 4040 CB LYS A 256 -11.267 -25.311 21.874 1.00 91.33 C +ATOM 4041 CG LYS A 256 -10.335 -25.092 23.054 1.00 93.09 C +ATOM 4042 CD LYS A 256 -10.952 -25.574 24.356 1.00 94.62 C +ATOM 4043 CE LYS A 256 -10.044 -25.264 25.536 1.00 97.43 C +ATOM 4044 NZ LYS A 256 -10.566 -25.837 26.809 1.00 96.59 N +ATOM 4045 H LYS A 256 -9.729 -27.005 20.438 1.00 20.00 H +ATOM 4046 HA LYS A 256 -11.918 -27.273 22.447 1.00 20.00 H +ATOM 4047 HB2 LYS A 256 -10.820 -24.834 20.989 1.00 20.00 H +ATOM 4048 HB3 LYS A 256 -12.230 -24.831 22.103 1.00 20.00 H +ATOM 4049 HG2 LYS A 256 -9.400 -25.644 22.877 1.00 20.00 H +ATOM 4050 HG3 LYS A 256 -10.116 -24.017 23.140 1.00 20.00 H +ATOM 4051 HD2 LYS A 256 -11.919 -25.071 24.504 1.00 20.00 H +ATOM 4052 HD3 LYS A 256 -11.109 -26.661 24.299 1.00 20.00 H +ATOM 4053 HE2 LYS A 256 -9.048 -25.687 25.338 1.00 20.00 H +ATOM 4054 HE3 LYS A 256 -9.964 -24.172 25.645 1.00 20.00 H +ATOM 4055 HZ1 LYS A 256 -9.886 -25.718 27.532 1.00 20.00 H +ATOM 4056 HZ2 LYS A 256 -11.410 -25.366 27.065 1.00 20.00 H +ATOM 4057 HZ3 LYS A 256 -10.753 -26.811 26.684 1.00 20.00 H +ATOM 4058 N PHE A 257 -13.834 -27.085 20.870 1.00 84.87 N +ATOM 4059 CA PHE A 257 -14.959 -27.242 19.966 1.00 83.27 C +ATOM 4060 C PHE A 257 -16.062 -26.258 20.330 1.00 81.59 C +ATOM 4061 O PHE A 257 -16.154 -25.825 21.485 1.00 81.40 O +ATOM 4062 CB PHE A 257 -15.512 -28.672 20.017 1.00 82.87 C +ATOM 4063 CG PHE A 257 -14.457 -29.734 19.911 1.00 83.66 C +ATOM 4064 CD1 PHE A 257 -13.803 -29.966 18.712 1.00 84.60 C +ATOM 4065 CD2 PHE A 257 -14.124 -30.506 21.011 1.00 85.10 C +ATOM 4066 CE1 PHE A 257 -12.831 -30.946 18.614 1.00 86.20 C +ATOM 4067 CE2 PHE A 257 -13.156 -31.488 20.919 1.00 82.15 C +ATOM 4068 CZ PHE A 257 -12.509 -31.708 19.719 1.00 84.13 C +ATOM 4069 H PHE A 257 -14.005 -27.128 21.854 1.00 20.00 H +ATOM 4070 HA PHE A 257 -14.632 -27.034 18.936 1.00 20.00 H +ATOM 4071 HB2 PHE A 257 -16.043 -28.805 20.971 1.00 20.00 H +ATOM 4072 HB3 PHE A 257 -16.218 -28.801 19.184 1.00 20.00 H +ATOM 4073 HD1 PHE A 257 -14.055 -29.375 17.844 1.00 20.00 H +ATOM 4074 HD2 PHE A 257 -14.627 -30.339 21.952 1.00 20.00 H +ATOM 4075 HE1 PHE A 257 -12.325 -31.114 17.675 1.00 20.00 H +ATOM 4076 HE2 PHE A 257 -12.906 -32.083 21.785 1.00 20.00 H +ATOM 4077 HZ PHE A 257 -11.752 -32.475 19.645 1.00 20.00 H +ATOM 4078 N PRO A 258 -16.908 -25.875 19.372 1.00 87.90 N +ATOM 4079 CA PRO A 258 -17.991 -24.939 19.687 1.00 89.58 C +ATOM 4080 C PRO A 258 -18.949 -25.530 20.708 1.00 87.61 C +ATOM 4081 O PRO A 258 -19.103 -26.748 20.814 1.00 86.77 O +ATOM 4082 CB PRO A 258 -18.680 -24.720 18.335 1.00 88.88 C +ATOM 4083 CG PRO A 258 -17.646 -25.085 17.321 1.00 89.58 C +ATOM 4084 CD PRO A 258 -16.869 -26.205 17.936 1.00 89.58 C +ATOM 4085 HA PRO A 258 -17.587 -23.986 20.058 1.00 20.00 H +ATOM 4086 HB2 PRO A 258 -19.563 -25.369 18.240 1.00 20.00 H +ATOM 4087 HB3 PRO A 258 -18.983 -23.669 18.219 1.00 20.00 H +ATOM 4088 HG2 PRO A 258 -18.123 -25.414 16.386 1.00 20.00 H +ATOM 4089 HG3 PRO A 258 -16.989 -24.227 17.115 1.00 20.00 H +ATOM 4090 HD2 PRO A 258 -17.348 -27.175 17.739 1.00 20.00 H +ATOM 4091 HD3 PRO A 258 -15.835 -26.223 17.561 1.00 20.00 H +ATOM 4092 N ASP A 259 -19.594 -24.643 21.469 1.00 84.06 N +ATOM 4093 CA ASP A 259 -20.538 -25.091 22.487 1.00 85.85 C +ATOM 4094 C ASP A 259 -21.666 -25.922 21.888 1.00 88.76 C +ATOM 4095 O ASP A 259 -22.222 -26.796 22.567 1.00 88.52 O +ATOM 4096 CB ASP A 259 -21.106 -23.887 23.235 1.00 91.47 C +ATOM 4097 CG ASP A 259 -20.081 -23.220 24.123 0.00 92.36 C +ATOM 4098 OD1 ASP A 259 -18.900 -23.147 23.720 0.00 92.55 O +ATOM 4099 OD2 ASP A 259 -20.458 -22.760 25.223 0.00 93.47 O +ATOM 4100 H ASP A 259 -19.429 -23.665 21.340 1.00 20.00 H +ATOM 4101 HA ASP A 259 -20.003 -25.719 23.214 1.00 20.00 H +ATOM 4102 HB2 ASP A 259 -21.466 -23.153 22.499 1.00 20.00 H +ATOM 4103 HB3 ASP A 259 -21.947 -24.224 23.859 1.00 20.00 H +ATOM 4104 N GLY A 260 -22.013 -25.668 20.623 1.00 87.49 N +ATOM 4105 CA GLY A 260 -23.085 -26.414 19.986 1.00 85.20 C +ATOM 4106 C GLY A 260 -22.739 -27.867 19.731 1.00 82.93 C +ATOM 4107 O GLY A 260 -23.633 -28.709 19.607 1.00 76.53 O +ATOM 4108 H GLY A 260 -21.531 -24.958 20.110 1.00 20.00 H +ATOM 4109 HA2 GLY A 260 -23.971 -26.376 20.637 1.00 20.00 H +ATOM 4110 HA3 GLY A 260 -23.317 -25.937 19.022 1.00 20.00 H +ATOM 4111 N PHE A 261 -21.446 -28.183 19.645 1.00 80.40 N +ATOM 4112 CA PHE A 261 -21.031 -29.576 19.529 1.00 77.95 C +ATOM 4113 C PHE A 261 -21.443 -30.365 20.764 1.00 74.25 C +ATOM 4114 O PHE A 261 -21.997 -31.465 20.661 1.00 69.16 O +ATOM 4115 CB PHE A 261 -19.519 -29.647 19.313 1.00 79.79 C +ATOM 4116 CG PHE A 261 -18.955 -31.035 19.408 1.00 77.59 C +ATOM 4117 CD1 PHE A 261 -19.159 -31.953 18.389 1.00 72.50 C +ATOM 4118 CD2 PHE A 261 -18.218 -31.423 20.514 1.00 74.49 C +ATOM 4119 CE1 PHE A 261 -18.639 -33.231 18.473 1.00 72.76 C +ATOM 4120 CE2 PHE A 261 -17.699 -32.701 20.605 1.00 71.10 C +ATOM 4121 CZ PHE A 261 -17.909 -33.605 19.584 1.00 68.57 C +ATOM 4122 H PHE A 261 -20.756 -27.459 19.660 1.00 20.00 H +ATOM 4123 HA PHE A 261 -21.523 -30.025 18.654 1.00 20.00 H +ATOM 4124 HB2 PHE A 261 -19.293 -29.249 18.313 1.00 20.00 H +ATOM 4125 HB3 PHE A 261 -19.031 -29.022 20.075 1.00 20.00 H +ATOM 4126 HD1 PHE A 261 -19.731 -31.666 17.519 1.00 20.00 H +ATOM 4127 HD2 PHE A 261 -18.047 -30.719 21.315 1.00 20.00 H +ATOM 4128 HE1 PHE A 261 -18.803 -33.936 17.671 1.00 20.00 H +ATOM 4129 HE2 PHE A 261 -17.129 -32.992 21.475 1.00 20.00 H +ATOM 4130 HZ PHE A 261 -17.503 -34.603 19.654 1.00 20.00 H +ATOM 4131 N TRP A 262 -21.194 -29.802 21.946 1.00 78.30 N +ATOM 4132 CA TRP A 262 -21.506 -30.500 23.185 1.00 75.38 C +ATOM 4133 C TRP A 262 -23.004 -30.601 23.439 1.00 72.65 C +ATOM 4134 O TRP A 262 -23.425 -31.423 24.259 1.00 69.43 O +ATOM 4135 CB TRP A 262 -20.812 -29.808 24.355 1.00 73.24 C +ATOM 4136 CG TRP A 262 -19.319 -29.798 24.218 1.00 75.37 C +ATOM 4137 CD1 TRP A 262 -18.527 -28.724 23.940 1.00 81.32 C +ATOM 4138 CD2 TRP A 262 -18.442 -30.923 24.342 1.00 74.71 C +ATOM 4139 NE1 TRP A 262 -17.207 -29.107 23.893 1.00 76.16 N +ATOM 4140 CE2 TRP A 262 -17.128 -30.453 24.136 1.00 76.90 C +ATOM 4141 CE3 TRP A 262 -18.638 -32.279 24.613 1.00 73.37 C +ATOM 4142 CZ2 TRP A 262 -16.019 -31.293 24.190 1.00 76.08 C +ATOM 4143 CZ3 TRP A 262 -17.537 -33.112 24.666 1.00 74.92 C +ATOM 4144 CH2 TRP A 262 -16.244 -32.616 24.456 1.00 73.02 C +ATOM 4145 H TRP A 262 -20.788 -28.889 21.982 1.00 20.00 H +ATOM 4146 HA TRP A 262 -21.108 -31.524 23.119 1.00 20.00 H +ATOM 4147 HB2 TRP A 262 -21.167 -28.768 24.410 1.00 20.00 H +ATOM 4148 HB3 TRP A 262 -21.077 -30.336 25.283 1.00 20.00 H +ATOM 4149 HD1 TRP A 262 -18.885 -27.718 23.780 1.00 20.00 H +ATOM 4150 HE1 TRP A 262 -16.432 -28.502 23.711 1.00 20.00 H +ATOM 4151 HE3 TRP A 262 -19.632 -32.669 24.778 1.00 20.00 H +ATOM 4152 HZ2 TRP A 262 -15.020 -30.915 24.028 1.00 20.00 H +ATOM 4153 HZ3 TRP A 262 -17.676 -34.163 24.873 1.00 20.00 H +ATOM 4154 HH2 TRP A 262 -15.405 -33.294 24.505 1.00 20.00 H +ATOM 4155 N LEU A 263 -23.816 -29.791 22.765 1.00 78.73 N +ATOM 4156 CA LEU A 263 -25.266 -29.913 22.849 1.00 79.81 C +ATOM 4157 C LEU A 263 -25.836 -30.853 21.793 1.00 78.91 C +ATOM 4158 O LEU A 263 -27.053 -31.072 21.765 1.00 77.56 O +ATOM 4159 CB LEU A 263 -25.925 -28.534 22.719 1.00 83.51 C +ATOM 4160 CG LEU A 263 -25.517 -27.469 23.738 1.00 88.02 C +ATOM 4161 CD1 LEU A 263 -26.125 -26.130 23.355 1.00 90.20 C +ATOM 4162 CD2 LEU A 263 -25.939 -27.868 25.145 1.00 87.08 C +ATOM 4163 H LEU A 263 -23.421 -29.079 22.185 1.00 20.00 H +ATOM 4164 HA LEU A 263 -25.529 -30.318 23.837 1.00 20.00 H +ATOM 4165 HB2 LEU A 263 -25.685 -28.145 21.719 1.00 20.00 H +ATOM 4166 HB3 LEU A 263 -27.012 -28.677 22.806 1.00 20.00 H +ATOM 4167 HG LEU A 263 -24.421 -27.372 23.718 1.00 20.00 H +ATOM 4168 HD11 LEU A 263 -25.828 -25.368 24.091 1.00 20.00 H +ATOM 4169 HD12 LEU A 263 -25.765 -25.836 22.358 1.00 20.00 H +ATOM 4170 HD13 LEU A 263 -27.222 -26.217 23.339 1.00 20.00 H +ATOM 4171 HD21 LEU A 263 -25.634 -27.086 25.856 1.00 20.00 H +ATOM 4172 HD22 LEU A 263 -27.032 -27.988 25.180 1.00 20.00 H +ATOM 4173 HD23 LEU A 263 -25.457 -28.819 25.417 1.00 20.00 H +ATOM 4174 N GLY A 264 -24.989 -31.414 20.931 1.00 79.19 N +ATOM 4175 CA GLY A 264 -25.454 -32.293 19.878 1.00 82.61 C +ATOM 4176 C GLY A 264 -26.040 -31.588 18.677 1.00 83.05 C +ATOM 4177 O GLY A 264 -26.759 -32.216 17.892 1.00 81.79 O +ATOM 4178 H GLY A 264 -24.011 -31.224 21.013 1.00 20.00 H +ATOM 4179 HA2 GLY A 264 -24.602 -32.899 19.537 1.00 20.00 H +ATOM 4180 HA3 GLY A 264 -26.228 -32.952 20.299 1.00 20.00 H +ATOM 4181 N GLU A 265 -25.747 -30.301 18.499 1.00 84.52 N +ATOM 4182 CA GLU A 265 -26.354 -29.513 17.435 1.00 86.46 C +ATOM 4183 C GLU A 265 -25.416 -29.237 16.267 1.00 84.67 C +ATOM 4184 O GLU A 265 -25.880 -28.757 15.229 1.00 80.77 O +ATOM 4185 CB GLU A 265 -26.872 -28.180 17.995 1.00 87.53 C +ATOM 4186 CG GLU A 265 -27.908 -28.333 19.102 1.00 90.30 C +ATOM 4187 CD GLU A 265 -28.350 -27.001 19.684 1.00 94.27 C +ATOM 4188 OE1 GLU A 265 -27.487 -26.124 19.899 1.00 98.16 O +ATOM 4189 OE2 GLU A 265 -29.564 -26.829 19.922 1.00 95.35 O +ATOM 4190 H GLU A 265 -25.091 -29.863 19.114 1.00 20.00 H +ATOM 4191 HA GLU A 265 -27.221 -30.066 17.043 1.00 20.00 H +ATOM 4192 HB2 GLU A 265 -26.016 -27.618 18.397 1.00 20.00 H +ATOM 4193 HB3 GLU A 265 -27.328 -27.612 17.170 1.00 20.00 H +ATOM 4194 HG2 GLU A 265 -28.789 -28.846 18.690 1.00 20.00 H +ATOM 4195 HG3 GLU A 265 -27.473 -28.942 19.908 1.00 20.00 H +ATOM 4196 N GLN A 266 -24.123 -29.531 16.399 1.00 83.27 N +ATOM 4197 CA GLN A 266 -23.164 -29.235 15.344 1.00 79.61 C +ATOM 4198 C GLN A 266 -22.158 -30.372 15.231 1.00 78.81 C +ATOM 4199 O GLN A 266 -21.862 -31.058 16.212 1.00 79.32 O +ATOM 4200 CB GLN A 266 -22.449 -27.899 15.606 1.00 82.22 C +ATOM 4201 CG GLN A 266 -21.667 -27.358 14.420 0.00 83.31 C +ATOM 4202 CD GLN A 266 -20.957 -26.058 14.735 0.00 86.00 C +ATOM 4203 OE1 GLN A 266 -19.791 -25.879 14.387 0.00 86.52 O +ATOM 4204 NE2 GLN A 266 -21.661 -25.139 15.387 0.00 87.56 N +ATOM 4205 H GLN A 266 -23.804 -29.965 17.242 1.00 20.00 H +ATOM 4206 HA GLN A 266 -23.698 -29.153 14.386 1.00 20.00 H +ATOM 4207 HB2 GLN A 266 -23.207 -27.153 15.886 1.00 20.00 H +ATOM 4208 HB3 GLN A 266 -21.749 -28.042 16.442 1.00 20.00 H +ATOM 4209 HG2 GLN A 266 -20.917 -28.106 14.122 0.00 20.00 H +ATOM 4210 HG3 GLN A 266 -22.365 -27.186 13.587 0.00 20.00 H +ATOM 4211 HE21 GLN A 266 -21.245 -24.258 15.614 0.00 20.00 H +ATOM 4212 HE22 GLN A 266 -22.607 -25.328 15.651 0.00 20.00 H +ATOM 4213 N LEU A 267 -21.643 -30.572 14.020 1.00 77.47 N +ATOM 4214 CA LEU A 267 -20.680 -31.630 13.748 1.00 72.65 C +ATOM 4215 C LEU A 267 -19.257 -31.089 13.799 1.00 75.01 C +ATOM 4216 O LEU A 267 -18.986 -29.977 13.338 1.00 76.68 O +ATOM 4217 CB LEU A 267 -20.933 -32.260 12.377 1.00 74.26 C +ATOM 4218 CG LEU A 267 -22.300 -32.867 12.060 1.00 73.45 C +ATOM 4219 CD1 LEU A 267 -22.293 -33.441 10.653 1.00 72.81 C +ATOM 4220 CD2 LEU A 267 -22.667 -33.936 13.073 1.00 75.99 C +ATOM 4221 H LEU A 267 -21.927 -29.975 13.270 1.00 20.00 H +ATOM 4222 HA LEU A 267 -20.779 -32.415 14.512 1.00 20.00 H +ATOM 4223 HB2 LEU A 267 -20.751 -31.476 11.628 1.00 20.00 H +ATOM 4224 HB3 LEU A 267 -20.192 -33.063 12.254 1.00 20.00 H +ATOM 4225 HG LEU A 267 -23.054 -32.067 12.107 1.00 20.00 H +ATOM 4226 HD11 LEU A 267 -23.278 -33.876 10.429 1.00 20.00 H +ATOM 4227 HD12 LEU A 267 -22.074 -32.640 9.932 1.00 20.00 H +ATOM 4228 HD13 LEU A 267 -21.522 -34.222 10.580 1.00 20.00 H +ATOM 4229 HD21 LEU A 267 -23.653 -34.356 12.823 1.00 20.00 H +ATOM 4230 HD22 LEU A 267 -21.912 -34.736 13.052 1.00 20.00 H +ATOM 4231 HD23 LEU A 267 -22.702 -33.491 14.078 1.00 20.00 H +ATOM 4232 N VAL A 268 -18.350 -31.886 14.364 1.00 72.97 N +ATOM 4233 CA VAL A 268 -16.917 -31.613 14.328 1.00 73.05 C +ATOM 4234 C VAL A 268 -16.273 -32.594 13.361 1.00 68.79 C +ATOM 4235 O VAL A 268 -16.620 -33.782 13.340 1.00 68.55 O +ATOM 4236 CB VAL A 268 -16.291 -31.710 15.733 1.00 76.30 C +ATOM 4237 CG1 VAL A 268 -14.776 -31.807 15.643 1.00 73.13 C +ATOM 4238 CG2 VAL A 268 -16.684 -30.501 16.564 1.00 79.72 C +ATOM 4239 H VAL A 268 -18.667 -32.710 14.835 1.00 20.00 H +ATOM 4240 HA VAL A 268 -16.752 -30.594 13.949 1.00 20.00 H +ATOM 4241 HB VAL A 268 -16.675 -32.617 16.224 1.00 20.00 H +ATOM 4242 HG11 VAL A 268 -14.352 -31.875 16.656 1.00 20.00 H +ATOM 4243 HG12 VAL A 268 -14.500 -32.703 15.069 1.00 20.00 H +ATOM 4244 HG13 VAL A 268 -14.381 -30.913 15.139 1.00 20.00 H +ATOM 4245 HG21 VAL A 268 -16.232 -30.580 17.564 1.00 20.00 H +ATOM 4246 HG22 VAL A 268 -16.325 -29.585 16.071 1.00 20.00 H +ATOM 4247 HG23 VAL A 268 -17.779 -30.462 16.659 1.00 20.00 H +ATOM 4248 N CYS A 269 -15.341 -32.100 12.546 1.00 68.12 N +ATOM 4249 CA CYS A 269 -14.764 -32.883 11.465 1.00 70.22 C +ATOM 4250 C CYS A 269 -13.246 -32.899 11.559 1.00 69.30 C +ATOM 4251 O CYS A 269 -12.630 -32.007 12.147 1.00 77.74 O +ATOM 4252 CB CYS A 269 -15.166 -32.332 10.091 1.00 74.95 C +ATOM 4253 SG CYS A 269 -16.943 -32.170 9.812 1.00 82.02 S +ATOM 4254 H CYS A 269 -15.028 -31.160 12.682 1.00 20.00 H +ATOM 4255 HA CYS A 269 -15.125 -33.919 11.537 1.00 20.00 H +ATOM 4256 HB2 CYS A 269 -14.712 -31.336 9.979 1.00 20.00 H +ATOM 4257 HB3 CYS A 269 -14.762 -33.008 9.323 1.00 20.00 H +ATOM 4258 N TRP A 270 -12.653 -33.929 10.960 1.00 66.82 N +ATOM 4259 CA TRP A 270 -11.213 -34.023 10.787 1.00 67.44 C +ATOM 4260 C TRP A 270 -10.926 -34.597 9.408 1.00 70.22 C +ATOM 4261 O TRP A 270 -11.799 -35.184 8.764 1.00 74.85 O +ATOM 4262 CB TRP A 270 -10.554 -34.900 11.863 1.00 68.20 C +ATOM 4263 CG TRP A 270 -10.569 -34.314 13.238 1.00 68.46 C +ATOM 4264 CD1 TRP A 270 -9.679 -33.420 13.758 1.00 66.55 C +ATOM 4265 CD2 TRP A 270 -11.512 -34.594 14.278 1.00 67.00 C +ATOM 4266 NE1 TRP A 270 -10.015 -33.119 15.056 1.00 65.75 N +ATOM 4267 CE2 TRP A 270 -11.138 -33.826 15.399 1.00 67.66 C +ATOM 4268 CE3 TRP A 270 -12.641 -35.415 14.369 1.00 64.21 C +ATOM 4269 CZ2 TRP A 270 -11.849 -33.858 16.597 1.00 67.14 C +ATOM 4270 CZ3 TRP A 270 -13.348 -35.445 15.558 1.00 62.02 C +ATOM 4271 CH2 TRP A 270 -12.949 -34.672 16.656 1.00 64.34 C +ATOM 4272 H TRP A 270 -13.225 -34.673 10.613 1.00 20.00 H +ATOM 4273 HA TRP A 270 -10.772 -33.017 10.844 1.00 20.00 H +ATOM 4274 HB2 TRP A 270 -11.086 -35.862 11.894 1.00 20.00 H +ATOM 4275 HB3 TRP A 270 -9.506 -35.069 11.573 1.00 20.00 H +ATOM 4276 HD1 TRP A 270 -8.833 -33.009 13.227 1.00 20.00 H +ATOM 4277 HE1 TRP A 270 -9.521 -32.487 15.653 1.00 20.00 H +ATOM 4278 HE3 TRP A 270 -12.955 -36.014 13.527 1.00 20.00 H +ATOM 4279 HZ2 TRP A 270 -11.545 -33.264 17.446 1.00 20.00 H +ATOM 4280 HZ3 TRP A 270 -14.222 -36.075 15.641 1.00 20.00 H +ATOM 4281 HH2 TRP A 270 -13.522 -34.719 17.570 1.00 20.00 H +ATOM 4282 N GLN A 271 -9.688 -34.408 8.958 1.00 69.82 N +ATOM 4283 CA GLN A 271 -9.247 -35.018 7.713 1.00 71.00 C +ATOM 4284 C GLN A 271 -9.405 -36.529 7.806 1.00 73.47 C +ATOM 4285 O GLN A 271 -9.101 -37.132 8.840 1.00 76.19 O +ATOM 4286 CB GLN A 271 -7.791 -34.641 7.429 1.00 73.41 C +ATOM 4287 CG GLN A 271 -7.308 -34.993 6.030 1.00 74.38 C +ATOM 4288 CD GLN A 271 -5.902 -34.493 5.759 0.00 70.35 C +ATOM 4289 OE1 GLN A 271 -5.106 -34.325 6.682 0.00 69.60 O +ATOM 4290 NE2 GLN A 271 -5.593 -34.243 4.491 0.00 69.66 N +ATOM 4291 H GLN A 271 -9.053 -33.840 9.482 1.00 20.00 H +ATOM 4292 HA GLN A 271 -9.870 -34.651 6.884 1.00 20.00 H +ATOM 4293 HB2 GLN A 271 -7.685 -33.555 7.566 1.00 20.00 H +ATOM 4294 HB3 GLN A 271 -7.153 -35.166 8.155 1.00 20.00 H +ATOM 4295 HG2 GLN A 271 -7.321 -36.087 5.917 1.00 20.00 H +ATOM 4296 HG3 GLN A 271 -7.991 -34.540 5.296 1.00 20.00 H +ATOM 4297 HE21 GLN A 271 -4.682 -33.904 4.256 0.00 20.00 H +ATOM 4298 HE22 GLN A 271 -6.271 -34.394 3.772 0.00 20.00 H +ATOM 4299 N ALA A 272 -9.909 -37.129 6.727 1.00 72.56 N +ATOM 4300 CA ALA A 272 -10.279 -38.540 6.733 1.00 71.08 C +ATOM 4301 C ALA A 272 -9.145 -39.410 7.249 1.00 70.54 C +ATOM 4302 O ALA A 272 -8.016 -39.338 6.758 1.00 72.89 O +ATOM 4303 CB ALA A 272 -10.681 -38.982 5.326 1.00 72.85 C +ATOM 4304 H ALA A 272 -10.037 -36.597 5.890 1.00 20.00 H +ATOM 4305 HA ALA A 272 -11.146 -38.679 7.395 1.00 20.00 H +ATOM 4306 HB1 ALA A 272 -10.958 -40.046 5.341 1.00 20.00 H +ATOM 4307 HB2 ALA A 272 -11.539 -38.384 4.985 1.00 20.00 H +ATOM 4308 HB3 ALA A 272 -9.835 -38.833 4.639 1.00 20.00 H +ATOM 4309 N GLY A 273 -9.454 -40.227 8.257 1.00 71.27 N +ATOM 4310 CA GLY A 273 -8.477 -41.104 8.865 1.00 64.10 C +ATOM 4311 C GLY A 273 -7.678 -40.497 9.997 1.00 65.38 C +ATOM 4312 O GLY A 273 -6.965 -41.233 10.692 1.00 68.57 O +ATOM 4313 H GLY A 273 -10.392 -40.234 8.604 1.00 20.00 H +ATOM 4314 HA2 GLY A 273 -9.008 -41.984 9.258 1.00 20.00 H +ATOM 4315 HA3 GLY A 273 -7.771 -41.421 8.083 1.00 20.00 H +ATOM 4316 N THR A 274 -7.775 -39.186 10.219 1.00 67.40 N +ATOM 4317 CA THR A 274 -6.955 -38.505 11.211 1.00 68.44 C +ATOM 4318 C THR A 274 -7.731 -38.148 12.472 1.00 69.98 C +ATOM 4319 O THR A 274 -7.301 -37.267 13.226 1.00 70.10 O +ATOM 4320 CB THR A 274 -6.330 -37.249 10.604 1.00 70.75 C +ATOM 4321 OG1 THR A 274 -7.334 -36.237 10.461 1.00 69.15 O +ATOM 4322 CG2 THR A 274 -5.749 -37.566 9.239 1.00 70.65 C +ATOM 4323 H THR A 274 -8.433 -38.653 9.687 1.00 20.00 H +ATOM 4324 HA THR A 274 -6.134 -39.176 11.504 1.00 20.00 H +ATOM 4325 HB THR A 274 -5.524 -36.896 11.265 1.00 20.00 H +ATOM 4326 HG1 THR A 274 -8.172 -36.645 10.276 1.00 20.00 H +ATOM 4327 HG21 THR A 274 -5.302 -36.657 8.810 1.00 20.00 H +ATOM 4328 HG22 THR A 274 -4.976 -38.342 9.341 1.00 20.00 H +ATOM 4329 HG23 THR A 274 -6.548 -37.929 8.576 1.00 20.00 H +ATOM 4330 N THR A 275 -8.856 -38.805 12.714 1.00 68.50 N +ATOM 4331 CA THR A 275 -9.646 -38.522 13.903 1.00 64.55 C +ATOM 4332 C THR A 275 -8.825 -38.826 15.152 1.00 61.67 C +ATOM 4333 O THR A 275 -8.344 -39.959 15.306 1.00 58.07 O +ATOM 4334 CB THR A 275 -10.930 -39.343 13.905 1.00 62.27 C +ATOM 4335 OG1 THR A 275 -11.648 -39.105 12.690 1.00 65.46 O +ATOM 4336 CG2 THR A 275 -11.801 -38.949 15.090 1.00 55.54 C +ATOM 4337 H THR A 275 -9.166 -39.505 12.071 1.00 20.00 H +ATOM 4338 HA THR A 275 -9.915 -37.456 13.916 1.00 20.00 H +ATOM 4339 HB THR A 275 -10.672 -40.409 13.991 1.00 20.00 H +ATOM 4340 HG1 THR A 275 -11.739 -38.169 12.554 1.00 20.00 H +ATOM 4341 HG21 THR A 275 -12.724 -39.547 15.082 1.00 20.00 H +ATOM 4342 HG22 THR A 275 -11.253 -39.134 16.025 1.00 20.00 H +ATOM 4343 HG23 THR A 275 -12.055 -37.881 15.019 1.00 20.00 H +ATOM 4344 N PRO A 276 -8.630 -37.858 16.058 1.00 58.52 N +ATOM 4345 CA PRO A 276 -7.725 -38.052 17.210 1.00 60.85 C +ATOM 4346 C PRO A 276 -8.442 -38.678 18.402 1.00 56.41 C +ATOM 4347 O PRO A 276 -8.730 -38.026 19.416 1.00 56.42 O +ATOM 4348 CB PRO A 276 -7.253 -36.623 17.489 1.00 61.59 C +ATOM 4349 CG PRO A 276 -8.461 -35.790 17.163 1.00 65.96 C +ATOM 4350 CD PRO A 276 -9.211 -36.505 16.048 1.00 59.13 C +ATOM 4351 HA PRO A 276 -6.866 -38.676 16.923 1.00 20.00 H +ATOM 4352 HB2 PRO A 276 -6.964 -36.502 18.544 1.00 20.00 H +ATOM 4353 HB3 PRO A 276 -6.404 -36.355 16.843 1.00 20.00 H +ATOM 4354 HG2 PRO A 276 -9.104 -35.695 18.050 1.00 20.00 H +ATOM 4355 HG3 PRO A 276 -8.150 -34.790 16.827 1.00 20.00 H +ATOM 4356 HD2 PRO A 276 -10.290 -36.539 16.258 1.00 20.00 H +ATOM 4357 HD3 PRO A 276 -9.041 -36.011 15.080 1.00 20.00 H +ATOM 4358 N TRP A 277 -8.745 -39.973 18.280 1.00 53.86 N +ATOM 4359 CA TRP A 277 -9.511 -40.661 19.314 1.00 54.40 C +ATOM 4360 C TRP A 277 -8.850 -40.543 20.680 1.00 53.23 C +ATOM 4361 O TRP A 277 -9.536 -40.462 21.705 1.00 51.56 O +ATOM 4362 CB TRP A 277 -9.684 -42.134 18.944 1.00 52.20 C +ATOM 4363 CG TRP A 277 -10.328 -42.377 17.612 1.00 58.51 C +ATOM 4364 CD1 TRP A 277 -9.722 -42.846 16.484 1.00 60.68 C +ATOM 4365 CD2 TRP A 277 -11.704 -42.167 17.270 1.00 53.03 C +ATOM 4366 NE1 TRP A 277 -10.634 -42.941 15.460 1.00 53.55 N +ATOM 4367 CE2 TRP A 277 -11.858 -42.527 15.916 1.00 54.33 C +ATOM 4368 CE3 TRP A 277 -12.820 -41.705 17.976 1.00 56.56 C +ATOM 4369 CZ2 TRP A 277 -13.083 -42.443 15.254 1.00 54.75 C +ATOM 4370 CZ3 TRP A 277 -14.040 -41.621 17.314 1.00 50.32 C +ATOM 4371 CH2 TRP A 277 -14.158 -41.987 15.968 1.00 52.57 C +ATOM 4372 H TRP A 277 -8.443 -40.477 17.471 1.00 20.00 H +ATOM 4373 HA TRP A 277 -10.511 -40.207 19.378 1.00 20.00 H +ATOM 4374 HB2 TRP A 277 -8.689 -42.603 18.934 1.00 20.00 H +ATOM 4375 HB3 TRP A 277 -10.306 -42.610 19.716 1.00 20.00 H +ATOM 4376 HD1 TRP A 277 -8.677 -43.105 16.406 1.00 20.00 H +ATOM 4377 HE1 TRP A 277 -10.436 -43.260 14.533 1.00 20.00 H +ATOM 4378 HE3 TRP A 277 -12.736 -41.419 19.014 1.00 20.00 H +ATOM 4379 HZ2 TRP A 277 -13.180 -42.727 14.217 1.00 20.00 H +ATOM 4380 HZ3 TRP A 277 -14.910 -41.268 17.847 1.00 20.00 H +ATOM 4381 HH2 TRP A 277 -15.119 -41.908 15.482 1.00 20.00 H +ATOM 4382 N ASN A 278 -7.515 -40.509 20.716 1.00 55.78 N +ATOM 4383 CA ASN A 278 -6.822 -40.647 21.992 1.00 56.21 C +ATOM 4384 C ASN A 278 -6.982 -39.414 22.877 1.00 57.23 C +ATOM 4385 O ASN A 278 -6.844 -39.513 24.100 1.00 56.71 O +ATOM 4386 CB ASN A 278 -5.342 -40.943 21.758 1.00 55.91 C +ATOM 4387 CG ASN A 278 -4.597 -39.760 21.180 1.00 59.52 C +ATOM 4388 OD1 ASN A 278 -4.529 -39.590 19.965 1.00 58.00 O +ATOM 4389 ND2 ASN A 278 -4.029 -38.935 22.051 1.00 66.46 N +ATOM 4390 H ASN A 278 -6.993 -40.389 19.872 1.00 20.00 H +ATOM 4391 HA ASN A 278 -7.252 -41.503 22.532 1.00 20.00 H +ATOM 4392 HB2 ASN A 278 -4.881 -41.215 22.719 1.00 20.00 H +ATOM 4393 HB3 ASN A 278 -5.258 -41.788 21.059 1.00 20.00 H +ATOM 4394 HD21 ASN A 278 -3.521 -38.138 21.726 1.00 20.00 H +ATOM 4395 HD22 ASN A 278 -4.109 -39.111 23.032 1.00 20.00 H +ATOM 4396 N ILE A 279 -7.286 -38.249 22.302 1.00 55.35 N +ATOM 4397 CA ILE A 279 -7.441 -37.073 23.150 1.00 56.97 C +ATOM 4398 C ILE A 279 -8.784 -37.069 23.863 1.00 57.50 C +ATOM 4399 O ILE A 279 -8.968 -36.311 24.821 1.00 61.70 O +ATOM 4400 CB ILE A 279 -7.245 -35.780 22.341 1.00 61.98 C +ATOM 4401 CG1 ILE A 279 -8.458 -35.521 21.450 1.00 67.61 C +ATOM 4402 CG2 ILE A 279 -5.977 -35.860 21.512 1.00 57.74 C +ATOM 4403 CD1 ILE A 279 -8.317 -34.282 20.615 1.00 68.62 C +ATOM 4404 H ILE A 279 -7.405 -38.184 21.311 1.00 20.00 H +ATOM 4405 HA ILE A 279 -6.657 -37.098 23.921 1.00 20.00 H +ATOM 4406 HB ILE A 279 -7.148 -34.943 23.048 1.00 20.00 H +ATOM 4407 HG12 ILE A 279 -8.591 -36.383 20.779 1.00 20.00 H +ATOM 4408 HG13 ILE A 279 -9.347 -35.414 22.090 1.00 20.00 H +ATOM 4409 HG21 ILE A 279 -5.852 -34.928 20.941 1.00 20.00 H +ATOM 4410 HG22 ILE A 279 -5.112 -36.000 22.177 1.00 20.00 H +ATOM 4411 HG23 ILE A 279 -6.047 -36.710 20.817 1.00 20.00 H +ATOM 4412 HD11 ILE A 279 -9.218 -34.151 19.998 1.00 20.00 H +ATOM 4413 HD12 ILE A 279 -8.192 -33.409 21.273 1.00 20.00 H +ATOM 4414 HD13 ILE A 279 -7.437 -34.378 19.962 1.00 20.00 H +ATOM 4415 N PHE A 280 -9.726 -37.907 23.432 1.00 56.86 N +ATOM 4416 CA PHE A 280 -11.023 -38.015 24.086 1.00 55.35 C +ATOM 4417 C PHE A 280 -10.989 -39.097 25.164 1.00 55.33 C +ATOM 4418 O PHE A 280 -10.338 -40.131 24.986 1.00 54.66 O +ATOM 4419 CB PHE A 280 -12.117 -38.341 23.070 1.00 57.00 C +ATOM 4420 CG PHE A 280 -12.460 -37.197 22.156 1.00 58.59 C +ATOM 4421 CD1 PHE A 280 -13.380 -36.235 22.543 1.00 58.82 C +ATOM 4422 CD2 PHE A 280 -11.871 -37.089 20.906 1.00 59.48 C +ATOM 4423 CE1 PHE A 280 -13.702 -35.183 21.703 1.00 58.92 C +ATOM 4424 CE2 PHE A 280 -12.189 -36.037 20.061 1.00 61.24 C +ATOM 4425 CZ PHE A 280 -13.105 -35.084 20.461 1.00 64.44 C +ATOM 4426 H PHE A 280 -9.537 -38.480 22.635 1.00 20.00 H +ATOM 4427 HA PHE A 280 -11.270 -37.056 24.565 1.00 20.00 H +ATOM 4428 HB2 PHE A 280 -11.777 -39.187 22.454 1.00 20.00 H +ATOM 4429 HB3 PHE A 280 -13.025 -38.630 23.619 1.00 20.00 H +ATOM 4430 HD1 PHE A 280 -13.851 -36.307 23.512 1.00 20.00 H +ATOM 4431 HD2 PHE A 280 -11.156 -37.833 20.587 1.00 20.00 H +ATOM 4432 HE1 PHE A 280 -14.420 -34.440 22.018 1.00 20.00 H +ATOM 4433 HE2 PHE A 280 -11.721 -35.963 19.091 1.00 20.00 H +ATOM 4434 HZ PHE A 280 -13.354 -34.263 19.805 1.00 20.00 H +ATOM 4435 N PRO A 281 -11.691 -38.885 26.271 1.00 54.33 N +ATOM 4436 CA PRO A 281 -11.640 -39.841 27.378 1.00 54.08 C +ATOM 4437 C PRO A 281 -12.572 -41.026 27.179 1.00 55.29 C +ATOM 4438 O PRO A 281 -13.496 -41.010 26.363 1.00 55.38 O +ATOM 4439 CB PRO A 281 -12.083 -38.998 28.576 1.00 54.85 C +ATOM 4440 CG PRO A 281 -13.026 -38.013 27.985 1.00 55.23 C +ATOM 4441 CD PRO A 281 -12.469 -37.682 26.619 1.00 56.74 C +ATOM 4442 HA PRO A 281 -10.611 -40.197 27.535 1.00 20.00 H +ATOM 4443 HB2 PRO A 281 -12.588 -39.621 29.329 1.00 20.00 H +ATOM 4444 HB3 PRO A 281 -11.223 -38.490 29.037 1.00 20.00 H +ATOM 4445 HG2 PRO A 281 -14.031 -38.451 27.894 1.00 20.00 H +ATOM 4446 HG3 PRO A 281 -13.076 -37.108 28.608 1.00 20.00 H +ATOM 4447 HD2 PRO A 281 -11.823 -36.793 26.662 1.00 20.00 H +ATOM 4448 HD3 PRO A 281 -13.278 -37.512 25.894 1.00 20.00 H +ATOM 4449 N VAL A 282 -12.298 -42.074 27.955 1.00 53.84 N +ATOM 4450 CA VAL A 282 -13.236 -43.177 28.083 1.00 53.99 C +ATOM 4451 C VAL A 282 -14.272 -42.838 29.148 1.00 56.32 C +ATOM 4452 O VAL A 282 -14.076 -41.962 29.995 1.00 56.71 O +ATOM 4453 CB VAL A 282 -12.513 -44.492 28.414 1.00 52.74 C +ATOM 4454 CG1 VAL A 282 -11.506 -44.828 27.337 1.00 50.53 C +ATOM 4455 CG2 VAL A 282 -11.841 -44.395 29.773 1.00 53.92 C +ATOM 4456 H VAL A 282 -11.434 -42.102 28.457 1.00 20.00 H +ATOM 4457 HA VAL A 282 -13.762 -43.312 27.126 1.00 20.00 H +ATOM 4458 HB VAL A 282 -13.263 -45.296 28.454 1.00 20.00 H +ATOM 4459 HG11 VAL A 282 -10.999 -45.771 27.590 1.00 20.00 H +ATOM 4460 HG12 VAL A 282 -12.024 -44.938 26.373 1.00 20.00 H +ATOM 4461 HG13 VAL A 282 -10.763 -44.020 27.265 1.00 20.00 H +ATOM 4462 HG21 VAL A 282 -11.328 -45.342 29.997 1.00 20.00 H +ATOM 4463 HG22 VAL A 282 -11.108 -43.575 29.762 1.00 20.00 H +ATOM 4464 HG23 VAL A 282 -12.600 -44.198 30.544 1.00 20.00 H +ATOM 4465 N ILE A 283 -15.394 -43.546 29.104 1.00 56.98 N +ATOM 4466 CA ILE A 283 -16.496 -43.326 30.030 1.00 58.74 C +ATOM 4467 C ILE A 283 -16.839 -44.657 30.674 1.00 58.04 C +ATOM 4468 O ILE A 283 -17.088 -45.648 29.975 1.00 56.88 O +ATOM 4469 CB ILE A 283 -17.722 -42.721 29.333 1.00 63.35 C +ATOM 4470 CG1 ILE A 283 -17.356 -41.377 28.722 1.00 71.58 C +ATOM 4471 CG2 ILE A 283 -18.865 -42.560 30.318 1.00 60.38 C +ATOM 4472 CD1 ILE A 283 -18.485 -40.719 28.036 1.00 71.97 C +ATOM 4473 H ILE A 283 -15.486 -44.258 28.408 1.00 20.00 H +ATOM 4474 HA ILE A 283 -16.172 -42.632 30.819 1.00 20.00 H +ATOM 4475 HB ILE A 283 -18.040 -43.401 28.529 1.00 20.00 H +ATOM 4476 HG12 ILE A 283 -17.001 -40.714 29.525 1.00 20.00 H +ATOM 4477 HG13 ILE A 283 -16.548 -41.534 27.992 1.00 20.00 H +ATOM 4478 HG21 ILE A 283 -19.735 -42.126 29.803 1.00 20.00 H +ATOM 4479 HG22 ILE A 283 -19.136 -43.544 30.729 1.00 20.00 H +ATOM 4480 HG23 ILE A 283 -18.553 -41.894 31.136 1.00 20.00 H +ATOM 4481 HD11 ILE A 283 -18.151 -39.757 27.620 1.00 20.00 H +ATOM 4482 HD12 ILE A 283 -18.846 -41.365 27.222 1.00 20.00 H +ATOM 4483 HD13 ILE A 283 -19.299 -40.545 28.755 1.00 20.00 H +ATOM 4484 N SER A 284 -16.863 -44.678 31.999 1.00 56.50 N +ATOM 4485 CA SER A 284 -17.105 -45.892 32.761 1.00 57.29 C +ATOM 4486 C SER A 284 -18.362 -45.730 33.601 1.00 57.17 C +ATOM 4487 O SER A 284 -18.522 -44.726 34.302 1.00 61.21 O +ATOM 4488 CB SER A 284 -15.905 -46.223 33.654 1.00 56.10 C +ATOM 4489 OG SER A 284 -14.761 -46.503 32.872 1.00 58.43 O +ATOM 4490 H SER A 284 -16.708 -43.824 32.495 1.00 20.00 H +ATOM 4491 HA SER A 284 -17.258 -46.731 32.067 1.00 20.00 H +ATOM 4492 HB2 SER A 284 -15.694 -45.364 34.308 1.00 20.00 H +ATOM 4493 HB3 SER A 284 -16.145 -47.102 34.270 1.00 20.00 H +ATOM 4494 HG SER A 284 -13.980 -46.248 33.349 1.00 20.00 H +ATOM 4495 N LEU A 285 -19.255 -46.710 33.507 1.00 56.92 N +ATOM 4496 CA LEU A 285 -20.383 -46.854 34.414 1.00 53.83 C +ATOM 4497 C LEU A 285 -20.166 -48.109 35.246 1.00 53.70 C +ATOM 4498 O LEU A 285 -19.916 -49.186 34.692 1.00 53.80 O +ATOM 4499 CB LEU A 285 -21.711 -46.957 33.656 1.00 53.38 C +ATOM 4500 CG LEU A 285 -22.094 -45.914 32.604 1.00 54.87 C +ATOM 4501 CD1 LEU A 285 -23.488 -46.208 32.057 1.00 53.32 C +ATOM 4502 CD2 LEU A 285 -22.024 -44.505 33.171 1.00 55.18 C +ATOM 4503 H LEU A 285 -19.146 -47.383 32.775 1.00 20.00 H +ATOM 4504 HA LEU A 285 -20.429 -45.986 35.088 1.00 20.00 H +ATOM 4505 HB2 LEU A 285 -21.706 -47.931 33.145 1.00 20.00 H +ATOM 4506 HB3 LEU A 285 -22.507 -46.945 34.415 1.00 20.00 H +ATOM 4507 HG LEU A 285 -21.377 -45.987 31.773 1.00 20.00 H +ATOM 4508 HD11 LEU A 285 -23.753 -45.453 31.302 1.00 20.00 H +ATOM 4509 HD12 LEU A 285 -23.498 -47.207 31.596 1.00 20.00 H +ATOM 4510 HD13 LEU A 285 -24.218 -46.177 32.879 1.00 20.00 H +ATOM 4511 HD21 LEU A 285 -22.304 -43.781 32.392 1.00 20.00 H +ATOM 4512 HD22 LEU A 285 -22.718 -44.417 34.020 1.00 20.00 H +ATOM 4513 HD23 LEU A 285 -20.999 -44.298 33.512 1.00 20.00 H +ATOM 4514 N TYR A 286 -20.245 -47.967 36.565 1.00 53.50 N +ATOM 4515 CA TYR A 286 -20.219 -49.102 37.478 1.00 52.35 C +ATOM 4516 C TYR A 286 -21.652 -49.555 37.731 1.00 53.02 C +ATOM 4517 O TYR A 286 -22.504 -48.744 38.110 1.00 57.15 O +ATOM 4518 CB TYR A 286 -19.546 -48.742 38.804 1.00 50.55 C +ATOM 4519 CG TYR A 286 -18.039 -48.573 38.745 1.00 51.48 C +ATOM 4520 CD1 TYR A 286 -17.466 -47.484 38.106 1.00 51.57 C +ATOM 4521 CD2 TYR A 286 -17.191 -49.490 39.356 1.00 53.14 C +ATOM 4522 CE1 TYR A 286 -16.088 -47.318 38.059 1.00 48.74 C +ATOM 4523 CE2 TYR A 286 -15.808 -49.334 39.317 1.00 49.36 C +ATOM 4524 CZ TYR A 286 -15.264 -48.245 38.666 1.00 49.03 C +ATOM 4525 OH TYR A 286 -13.898 -48.072 38.616 1.00 50.76 O +ATOM 4526 H TYR A 286 -20.325 -47.046 36.945 1.00 20.00 H +ATOM 4527 HA TYR A 286 -19.664 -49.932 37.017 1.00 20.00 H +ATOM 4528 HB2 TYR A 286 -19.980 -47.796 39.159 1.00 20.00 H +ATOM 4529 HB3 TYR A 286 -19.770 -49.541 39.526 1.00 20.00 H +ATOM 4530 HD1 TYR A 286 -18.104 -46.750 37.636 1.00 20.00 H +ATOM 4531 HD2 TYR A 286 -17.614 -50.340 39.871 1.00 20.00 H +ATOM 4532 HE1 TYR A 286 -15.662 -46.466 37.549 1.00 20.00 H +ATOM 4533 HE2 TYR A 286 -15.165 -50.060 39.793 1.00 20.00 H +ATOM 4534 HH TYR A 286 -13.696 -47.144 38.610 1.00 20.00 H +ATOM 4535 N LEU A 287 -21.916 -50.841 37.526 1.00 49.54 N +ATOM 4536 CA LEU A 287 -23.239 -51.405 37.744 1.00 55.89 C +ATOM 4537 C LEU A 287 -23.231 -52.320 38.961 1.00 60.93 C +ATOM 4538 O LEU A 287 -22.222 -52.962 39.269 1.00 50.25 O +ATOM 4539 CB LEU A 287 -23.719 -52.185 36.516 1.00 53.36 C +ATOM 4540 CG LEU A 287 -23.780 -51.380 35.218 1.00 55.57 C +ATOM 4541 CD1 LEU A 287 -23.997 -52.298 34.030 1.00 56.44 C +ATOM 4542 CD2 LEU A 287 -24.870 -50.321 35.293 1.00 61.83 C +ATOM 4543 H LEU A 287 -21.181 -51.441 37.211 1.00 20.00 H +ATOM 4544 HA LEU A 287 -23.952 -50.589 37.931 1.00 20.00 H +ATOM 4545 HB2 LEU A 287 -23.033 -53.031 36.360 1.00 20.00 H +ATOM 4546 HB3 LEU A 287 -24.729 -52.566 36.728 1.00 20.00 H +ATOM 4547 HG LEU A 287 -22.814 -50.870 35.087 1.00 20.00 H +ATOM 4548 HD11 LEU A 287 -24.038 -51.701 33.107 1.00 20.00 H +ATOM 4549 HD12 LEU A 287 -23.166 -53.016 33.965 1.00 20.00 H +ATOM 4550 HD13 LEU A 287 -24.944 -52.843 34.156 1.00 20.00 H +ATOM 4551 HD21 LEU A 287 -24.897 -49.754 34.351 1.00 20.00 H +ATOM 4552 HD22 LEU A 287 -25.843 -50.807 35.456 1.00 20.00 H +ATOM 4553 HD23 LEU A 287 -24.658 -49.636 36.127 1.00 20.00 H +ATOM 4554 N MET A 288 -24.372 -52.377 39.645 1.00 64.28 N +ATOM 4555 CA MET A 288 -24.508 -53.248 40.806 1.00 62.60 C +ATOM 4556 C MET A 288 -24.302 -54.705 40.404 1.00 56.34 C +ATOM 4557 O MET A 288 -24.785 -55.155 39.362 1.00 49.67 O +ATOM 4558 CB MET A 288 -25.886 -53.061 41.446 1.00 63.25 C +ATOM 4559 CG MET A 288 -26.148 -53.956 42.650 1.00 65.55 C +ATOM 4560 SD MET A 288 -27.869 -53.946 43.193 1.00 68.30 S +ATOM 4561 CE MET A 288 -27.919 -52.484 44.230 1.00 60.12 C +ATOM 4562 H MET A 288 -25.147 -51.814 39.358 1.00 20.00 H +ATOM 4563 HA MET A 288 -23.743 -52.982 41.550 1.00 20.00 H +ATOM 4564 HB2 MET A 288 -25.975 -52.014 41.770 1.00 20.00 H +ATOM 4565 HB3 MET A 288 -26.651 -53.276 40.685 1.00 20.00 H +ATOM 4566 HG2 MET A 288 -25.873 -54.987 42.384 1.00 20.00 H +ATOM 4567 HG3 MET A 288 -25.518 -53.612 43.483 1.00 20.00 H +ATOM 4568 HE1 MET A 288 -28.955 -52.295 44.548 1.00 20.00 H +ATOM 4569 HE2 MET A 288 -27.286 -52.641 45.116 1.00 20.00 H +ATOM 4570 HE3 MET A 288 -27.546 -51.619 43.662 1.00 20.00 H +ATOM 4571 N GLY A 289 -23.553 -55.441 41.228 1.00 53.49 N +ATOM 4572 CA GLY A 289 -23.248 -56.826 40.943 1.00 53.48 C +ATOM 4573 C GLY A 289 -24.296 -57.767 41.507 1.00 53.65 C +ATOM 4574 O GLY A 289 -25.298 -57.356 42.092 1.00 56.40 O +ATOM 4575 H GLY A 289 -23.194 -55.025 42.063 1.00 20.00 H +ATOM 4576 HA2 GLY A 289 -23.199 -56.962 39.853 1.00 20.00 H +ATOM 4577 HA3 GLY A 289 -22.273 -57.074 41.387 1.00 20.00 H +ATOM 4578 N GLU A 290 -24.049 -59.066 41.317 1.00 53.70 N +ATOM 4579 CA GLU A 290 -24.965 -60.071 41.846 1.00 56.69 C +ATOM 4580 C GLU A 290 -24.635 -60.440 43.288 1.00 61.02 C +ATOM 4581 O GLU A 290 -25.520 -60.877 44.032 1.00 61.93 O +ATOM 4582 CB GLU A 290 -24.956 -61.317 40.956 1.00 60.53 C +ATOM 4583 CG GLU A 290 -25.664 -61.122 39.618 1.00 58.97 C +ATOM 4584 CD GLU A 290 -26.433 -62.354 39.169 1.00 66.66 C +ATOM 4585 OE1 GLU A 290 -25.827 -63.237 38.527 1.00 67.84 O +ATOM 4586 OE2 GLU A 290 -27.644 -62.441 39.464 1.00 67.14 O +ATOM 4587 H GLU A 290 -23.235 -59.350 40.811 1.00 20.00 H +ATOM 4588 HA GLU A 290 -25.984 -59.658 41.831 1.00 20.00 H +ATOM 4589 HB2 GLU A 290 -23.910 -61.595 40.758 1.00 20.00 H +ATOM 4590 HB3 GLU A 290 -25.456 -62.134 41.497 1.00 20.00 H +ATOM 4591 HG2 GLU A 290 -26.370 -60.284 39.714 1.00 20.00 H +ATOM 4592 HG3 GLU A 290 -24.910 -60.881 38.854 1.00 20.00 H +ATOM 4593 N VAL A 291 -23.393 -60.252 43.700 1.00 60.55 N +ATOM 4594 CA VAL A 291 -22.952 -60.555 45.055 1.00 59.80 C +ATOM 4595 C VAL A 291 -23.043 -59.290 45.893 1.00 64.01 C +ATOM 4596 O VAL A 291 -22.949 -58.168 45.380 1.00 68.63 O +ATOM 4597 CB VAL A 291 -21.522 -61.143 45.029 1.00 59.32 C +ATOM 4598 CG1 VAL A 291 -20.898 -61.188 46.417 1.00 59.75 C +ATOM 4599 CG2 VAL A 291 -21.544 -62.534 44.422 1.00 60.89 C +ATOM 4600 H VAL A 291 -22.726 -59.885 43.052 1.00 20.00 H +ATOM 4601 HA VAL A 291 -23.622 -61.309 45.493 1.00 20.00 H +ATOM 4602 HB VAL A 291 -20.900 -60.497 44.392 1.00 20.00 H +ATOM 4603 HG11 VAL A 291 -19.885 -61.612 46.351 1.00 20.00 H +ATOM 4604 HG12 VAL A 291 -20.843 -60.169 46.827 1.00 20.00 H +ATOM 4605 HG13 VAL A 291 -21.515 -61.816 47.076 1.00 20.00 H +ATOM 4606 HG21 VAL A 291 -20.524 -62.944 44.407 1.00 20.00 H +ATOM 4607 HG22 VAL A 291 -22.193 -63.187 45.025 1.00 20.00 H +ATOM 4608 HG23 VAL A 291 -21.932 -62.479 43.394 1.00 20.00 H +ATOM 4609 N THR A 292 -23.265 -59.472 47.194 1.00 64.78 N +ATOM 4610 CA THR A 292 -23.288 -58.349 48.118 1.00 65.69 C +ATOM 4611 C THR A 292 -21.973 -57.582 48.063 1.00 62.58 C +ATOM 4612 O THR A 292 -20.889 -58.174 48.117 1.00 68.64 O +ATOM 4613 CB THR A 292 -23.544 -58.847 49.538 1.00 68.04 C +ATOM 4614 OG1 THR A 292 -24.572 -59.846 49.521 1.00 70.84 O +ATOM 4615 CG2 THR A 292 -23.981 -57.697 50.427 1.00 69.26 C +ATOM 4616 H THR A 292 -23.419 -60.397 47.541 1.00 20.00 H +ATOM 4617 HA THR A 292 -24.102 -57.664 47.839 1.00 20.00 H +ATOM 4618 HB THR A 292 -22.611 -59.272 49.938 1.00 20.00 H +ATOM 4619 HG1 THR A 292 -25.423 -59.425 49.500 1.00 20.00 H +ATOM 4620 HG21 THR A 292 -24.162 -58.069 51.446 1.00 20.00 H +ATOM 4621 HG22 THR A 292 -23.191 -56.932 50.451 1.00 20.00 H +ATOM 4622 HG23 THR A 292 -24.906 -57.256 50.028 1.00 20.00 H +ATOM 4623 N ASN A 293 -22.077 -56.256 47.946 1.00 56.82 N +ATOM 4624 CA ASN A 293 -20.936 -55.339 47.985 1.00 61.72 C +ATOM 4625 C ASN A 293 -19.976 -55.533 46.817 1.00 59.46 C +ATOM 4626 O ASN A 293 -18.795 -55.188 46.920 1.00 60.94 O +ATOM 4627 CB ASN A 293 -20.172 -55.451 49.312 1.00 61.64 C +ATOM 4628 CG ASN A 293 -21.016 -55.056 50.507 1.00 67.86 C +ATOM 4629 OD1 ASN A 293 -22.014 -54.347 50.375 1.00 68.76 O +ATOM 4630 ND2 ASN A 293 -20.610 -55.508 51.686 1.00 69.73 N +ATOM 4631 H ASN A 293 -22.990 -55.865 47.824 1.00 20.00 H +ATOM 4632 HA ASN A 293 -21.324 -54.312 47.921 1.00 20.00 H +ATOM 4633 HB2 ASN A 293 -19.843 -56.493 49.442 1.00 20.00 H +ATOM 4634 HB3 ASN A 293 -19.293 -54.792 49.269 1.00 20.00 H +ATOM 4635 HD21 ASN A 293 -21.121 -55.275 52.514 1.00 20.00 H +ATOM 4636 HD22 ASN A 293 -19.793 -56.082 51.747 1.00 20.00 H +ATOM 4637 N GLN A 294 -20.450 -56.084 45.707 1.00 57.89 N +ATOM 4638 CA GLN A 294 -19.644 -56.211 44.503 1.00 56.09 C +ATOM 4639 C GLN A 294 -20.287 -55.425 43.373 1.00 60.69 C +ATOM 4640 O GLN A 294 -21.512 -55.444 43.210 1.00 67.25 O +ATOM 4641 CB GLN A 294 -19.474 -57.676 44.081 1.00 53.73 C +ATOM 4642 CG GLN A 294 -18.304 -58.391 44.736 1.00 62.10 C +ATOM 4643 CD GLN A 294 -18.052 -59.756 44.122 1.00 65.39 C +ATOM 4644 OE1 GLN A 294 -18.475 -60.030 42.997 1.00 63.75 O +ATOM 4645 NE2 GLN A 294 -17.362 -60.619 44.858 1.00 66.91 N +ATOM 4646 H GLN A 294 -21.391 -56.423 45.698 1.00 20.00 H +ATOM 4647 HA GLN A 294 -18.645 -55.791 44.691 1.00 20.00 H +ATOM 4648 HB2 GLN A 294 -20.396 -58.217 44.341 1.00 20.00 H +ATOM 4649 HB3 GLN A 294 -19.327 -57.704 42.991 1.00 20.00 H +ATOM 4650 HG2 GLN A 294 -17.400 -57.776 44.616 1.00 20.00 H +ATOM 4651 HG3 GLN A 294 -18.521 -58.519 45.807 1.00 20.00 H +ATOM 4652 HE21 GLN A 294 -17.167 -61.534 44.504 1.00 20.00 H +ATOM 4653 HE22 GLN A 294 -17.038 -60.354 45.766 1.00 20.00 H +ATOM 4654 N SER A 295 -19.453 -54.725 42.606 1.00 53.69 N +ATOM 4655 CA SER A 295 -19.868 -54.093 41.366 1.00 50.26 C +ATOM 4656 C SER A 295 -18.875 -54.457 40.274 1.00 49.71 C +ATOM 4657 O SER A 295 -17.758 -54.909 40.541 1.00 60.86 O +ATOM 4658 CB SER A 295 -19.965 -52.563 41.501 1.00 51.38 C +ATOM 4659 OG SER A 295 -18.718 -52.000 41.875 1.00 48.47 O +ATOM 4660 H SER A 295 -18.501 -54.631 42.896 1.00 20.00 H +ATOM 4661 HA SER A 295 -20.858 -54.475 41.077 1.00 20.00 H +ATOM 4662 HB2 SER A 295 -20.276 -52.137 40.536 1.00 20.00 H +ATOM 4663 HB3 SER A 295 -20.714 -52.318 42.268 1.00 20.00 H +ATOM 4664 HG SER A 295 -18.438 -52.372 42.703 1.00 20.00 H +ATOM 4665 N PHE A 296 -19.308 -54.286 39.034 1.00 46.27 N +ATOM 4666 CA PHE A 296 -18.415 -54.327 37.891 1.00 45.27 C +ATOM 4667 C PHE A 296 -18.582 -53.016 37.140 1.00 47.97 C +ATOM 4668 O PHE A 296 -19.447 -52.202 37.465 1.00 53.02 O +ATOM 4669 CB PHE A 296 -18.692 -55.540 36.991 1.00 45.67 C +ATOM 4670 CG PHE A 296 -20.045 -55.522 36.342 1.00 47.70 C +ATOM 4671 CD1 PHE A 296 -21.165 -55.981 37.018 1.00 48.53 C +ATOM 4672 CD2 PHE A 296 -20.193 -55.060 35.047 1.00 51.17 C +ATOM 4673 CE1 PHE A 296 -22.410 -55.969 36.411 1.00 53.07 C +ATOM 4674 CE2 PHE A 296 -21.433 -55.048 34.435 1.00 54.34 C +ATOM 4675 CZ PHE A 296 -22.540 -55.501 35.118 1.00 53.19 C +ATOM 4676 H PHE A 296 -20.283 -54.123 38.880 1.00 20.00 H +ATOM 4677 HA PHE A 296 -17.376 -54.393 38.245 1.00 20.00 H +ATOM 4678 HB2 PHE A 296 -17.929 -55.565 36.199 1.00 20.00 H +ATOM 4679 HB3 PHE A 296 -18.614 -56.450 37.604 1.00 20.00 H +ATOM 4680 HD1 PHE A 296 -21.066 -56.352 38.028 1.00 20.00 H +ATOM 4681 HD2 PHE A 296 -19.329 -54.704 34.506 1.00 20.00 H +ATOM 4682 HE1 PHE A 296 -23.277 -56.325 36.947 1.00 20.00 H +ATOM 4683 HE2 PHE A 296 -21.533 -54.684 33.423 1.00 20.00 H +ATOM 4684 HZ PHE A 296 -23.510 -55.490 34.643 1.00 20.00 H +ATOM 4685 N ARG A 297 -17.735 -52.792 36.144 1.00 48.94 N +ATOM 4686 CA ARG A 297 -17.786 -51.558 35.378 1.00 51.49 C +ATOM 4687 C ARG A 297 -17.650 -51.862 33.897 1.00 50.02 C +ATOM 4688 O ARG A 297 -16.902 -52.754 33.490 1.00 48.89 O +ATOM 4689 CB ARG A 297 -16.697 -50.561 35.815 1.00 54.55 C +ATOM 4690 CG ARG A 297 -15.402 -50.650 35.031 1.00 54.74 C +ATOM 4691 CD ARG A 297 -14.325 -49.773 35.618 1.00 57.18 C +ATOM 4692 NE ARG A 297 -13.000 -50.173 35.158 1.00 56.09 N +ATOM 4693 CZ ARG A 297 -11.893 -50.024 35.878 1.00 54.77 C +ATOM 4694 NH1 ARG A 297 -11.959 -49.488 37.091 1.00 50.70 N +ATOM 4695 NH2 ARG A 297 -10.726 -50.422 35.392 1.00 58.20 N +ATOM 4696 H ARG A 297 -17.050 -53.484 35.916 1.00 20.00 H +ATOM 4697 HA ARG A 297 -18.763 -51.079 35.539 1.00 20.00 H +ATOM 4698 HB2 ARG A 297 -17.098 -49.543 35.699 1.00 20.00 H +ATOM 4699 HB3 ARG A 297 -16.469 -50.746 36.875 1.00 20.00 H +ATOM 4700 HG2 ARG A 297 -15.054 -51.693 35.038 1.00 20.00 H +ATOM 4701 HG3 ARG A 297 -15.592 -50.334 33.995 1.00 20.00 H +ATOM 4702 HD2 ARG A 297 -14.509 -48.731 35.316 1.00 20.00 H +ATOM 4703 HD3 ARG A 297 -14.361 -49.849 36.715 1.00 20.00 H +ATOM 4704 HE ARG A 297 -12.920 -50.583 34.249 1.00 20.00 H +ATOM 4705 HH11 ARG A 297 -11.128 -49.385 37.638 1.00 20.00 H +ATOM 4706 HH12 ARG A 297 -12.840 -49.188 37.458 1.00 20.00 H +ATOM 4707 HH21 ARG A 297 -9.895 -50.319 35.939 1.00 20.00 H +ATOM 4708 HH22 ARG A 297 -10.676 -50.826 34.479 1.00 20.00 H +ATOM 4709 N ILE A 298 -18.405 -51.115 33.102 1.00 50.24 N +ATOM 4710 CA ILE A 298 -18.337 -51.169 31.651 1.00 51.83 C +ATOM 4711 C ILE A 298 -17.792 -49.835 31.167 1.00 52.39 C +ATOM 4712 O ILE A 298 -18.126 -48.778 31.715 1.00 53.04 O +ATOM 4713 CB ILE A 298 -19.713 -51.481 31.033 1.00 49.37 C +ATOM 4714 CG1 ILE A 298 -20.708 -50.368 31.352 1.00 55.36 C +ATOM 4715 CG2 ILE A 298 -20.237 -52.806 31.562 1.00 47.01 C +ATOM 4716 CD1 ILE A 298 -22.098 -50.636 30.839 1.00 53.17 C +ATOM 4717 H ILE A 298 -19.055 -50.482 33.523 1.00 20.00 H +ATOM 4718 HA ILE A 298 -17.637 -51.962 31.348 1.00 20.00 H +ATOM 4719 HB ILE A 298 -19.600 -51.553 29.941 1.00 20.00 H +ATOM 4720 HG12 ILE A 298 -20.758 -50.249 32.444 1.00 20.00 H +ATOM 4721 HG13 ILE A 298 -20.344 -49.435 30.897 1.00 20.00 H +ATOM 4722 HG21 ILE A 298 -21.219 -53.018 31.114 1.00 20.00 H +ATOM 4723 HG22 ILE A 298 -19.533 -53.610 31.299 1.00 20.00 H +ATOM 4724 HG23 ILE A 298 -20.338 -52.750 32.656 1.00 20.00 H +ATOM 4725 HD11 ILE A 298 -22.756 -49.796 31.105 1.00 20.00 H +ATOM 4726 HD12 ILE A 298 -22.070 -50.748 29.745 1.00 20.00 H +ATOM 4727 HD13 ILE A 298 -22.484 -51.561 31.292 1.00 20.00 H +ATOM 4728 N THR A 299 -16.940 -49.885 30.150 1.00 52.39 N +ATOM 4729 CA THR A 299 -16.202 -48.715 29.699 1.00 53.45 C +ATOM 4730 C THR A 299 -16.342 -48.592 28.193 1.00 52.56 C +ATOM 4731 O THR A 299 -16.020 -49.532 27.461 1.00 49.21 O +ATOM 4732 CB THR A 299 -14.726 -48.817 30.097 1.00 53.65 C +ATOM 4733 OG1 THR A 299 -14.616 -48.787 31.525 1.00 51.14 O +ATOM 4734 CG2 THR A 299 -13.929 -47.675 29.501 1.00 54.47 C +ATOM 4735 H THR A 299 -16.801 -50.756 29.678 1.00 20.00 H +ATOM 4736 HA THR A 299 -16.626 -47.813 30.165 1.00 20.00 H +ATOM 4737 HB THR A 299 -14.325 -49.766 29.712 1.00 20.00 H +ATOM 4738 HG1 THR A 299 -14.800 -47.909 31.839 1.00 20.00 H +ATOM 4739 HG21 THR A 299 -12.874 -47.768 29.799 1.00 20.00 H +ATOM 4740 HG22 THR A 299 -14.004 -47.709 28.404 1.00 20.00 H +ATOM 4741 HG23 THR A 299 -14.330 -46.718 29.867 1.00 20.00 H +ATOM 4742 N ILE A 300 -16.824 -47.443 27.734 1.00 53.94 N +ATOM 4743 CA ILE A 300 -16.959 -47.179 26.311 1.00 55.54 C +ATOM 4744 C ILE A 300 -15.936 -46.131 25.901 1.00 56.27 C +ATOM 4745 O ILE A 300 -15.350 -45.425 26.727 1.00 55.31 O +ATOM 4746 CB ILE A 300 -18.379 -46.725 25.925 1.00 57.32 C +ATOM 4747 CG1 ILE A 300 -18.714 -45.410 26.626 1.00 57.79 C +ATOM 4748 CG2 ILE A 300 -19.394 -47.803 26.262 1.00 55.73 C +ATOM 4749 CD1 ILE A 300 -19.881 -44.681 26.008 1.00 53.87 C +ATOM 4750 H ILE A 300 -17.102 -46.738 28.387 1.00 20.00 H +ATOM 4751 HA ILE A 300 -16.740 -48.103 25.756 1.00 20.00 H +ATOM 4752 HB ILE A 300 -18.401 -46.554 24.839 1.00 20.00 H +ATOM 4753 HG12 ILE A 300 -18.956 -45.627 27.677 1.00 20.00 H +ATOM 4754 HG13 ILE A 300 -17.831 -44.756 26.580 1.00 20.00 H +ATOM 4755 HG21 ILE A 300 -20.400 -47.461 25.979 1.00 20.00 H +ATOM 4756 HG22 ILE A 300 -19.150 -48.722 25.708 1.00 20.00 H +ATOM 4757 HG23 ILE A 300 -19.366 -48.008 27.342 1.00 20.00 H +ATOM 4758 HD11 ILE A 300 -20.065 -43.748 26.560 1.00 20.00 H +ATOM 4759 HD12 ILE A 300 -19.652 -44.446 24.958 1.00 20.00 H +ATOM 4760 HD13 ILE A 300 -20.777 -45.317 26.055 1.00 20.00 H +ATOM 4761 N LEU A 301 -15.738 -46.029 24.599 1.00 54.78 N +ATOM 4762 CA LEU A 301 -14.741 -45.186 23.970 1.00 54.36 C +ATOM 4763 C LEU A 301 -15.391 -44.043 23.209 1.00 54.55 C +ATOM 4764 O LEU A 301 -16.620 -44.029 22.997 1.00 51.49 O +ATOM 4765 CB LEU A 301 -13.880 -46.024 23.015 1.00 54.22 C +ATOM 4766 CG LEU A 301 -13.343 -47.364 23.522 1.00 52.56 C +ATOM 4767 CD1 LEU A 301 -12.500 -48.019 22.443 1.00 50.61 C +ATOM 4768 CD2 LEU A 301 -12.539 -47.191 24.800 1.00 49.12 C +ATOM 4769 H LEU A 301 -16.322 -46.577 24.000 1.00 20.00 H +ATOM 4770 HA LEU A 301 -14.084 -44.760 24.742 1.00 20.00 H +ATOM 4771 HB2 LEU A 301 -14.489 -46.232 22.123 1.00 20.00 H +ATOM 4772 HB3 LEU A 301 -13.012 -45.410 22.732 1.00 20.00 H +ATOM 4773 HG LEU A 301 -14.200 -48.019 23.738 1.00 20.00 H +ATOM 4774 HD11 LEU A 301 -12.116 -48.982 22.811 1.00 20.00 H +ATOM 4775 HD12 LEU A 301 -13.117 -48.188 21.548 1.00 20.00 H +ATOM 4776 HD13 LEU A 301 -11.656 -47.361 22.187 1.00 20.00 H +ATOM 4777 HD21 LEU A 301 -12.169 -48.171 25.136 1.00 20.00 H +ATOM 4778 HD22 LEU A 301 -11.686 -46.523 24.609 1.00 20.00 H +ATOM 4779 HD23 LEU A 301 -13.180 -46.754 25.580 1.00 20.00 H +ATOM 4780 N PRO A 302 -14.621 -43.040 22.779 1.00 55.58 N +ATOM 4781 CA PRO A 302 -15.173 -42.024 21.875 1.00 54.96 C +ATOM 4782 C PRO A 302 -15.669 -42.594 20.562 1.00 55.94 C +ATOM 4783 O PRO A 302 -16.489 -41.950 19.898 1.00 57.71 O +ATOM 4784 CB PRO A 302 -14.001 -41.055 21.659 1.00 55.16 C +ATOM 4785 CG PRO A 302 -12.784 -41.802 22.103 1.00 52.02 C +ATOM 4786 CD PRO A 302 -13.246 -42.701 23.199 1.00 53.78 C +ATOM 4787 HA PRO A 302 -15.995 -41.487 22.372 1.00 20.00 H +ATOM 4788 HB2 PRO A 302 -13.919 -40.781 20.597 1.00 20.00 H +ATOM 4789 HB3 PRO A 302 -14.137 -40.146 22.263 1.00 20.00 H +ATOM 4790 HG2 PRO A 302 -12.370 -42.391 21.271 1.00 20.00 H +ATOM 4791 HG3 PRO A 302 -12.019 -41.104 22.475 1.00 20.00 H +ATOM 4792 HD2 PRO A 302 -13.244 -42.180 24.168 1.00 20.00 H +ATOM 4793 HD3 PRO A 302 -12.618 -43.601 23.266 1.00 20.00 H +ATOM 4794 N GLN A 303 -15.198 -43.775 20.157 1.00 53.72 N +ATOM 4795 CA GLN A 303 -15.765 -44.421 18.981 1.00 52.19 C +ATOM 4796 C GLN A 303 -17.232 -44.776 19.181 1.00 51.15 C +ATOM 4797 O GLN A 303 -17.951 -44.976 18.196 1.00 48.87 O +ATOM 4798 CB GLN A 303 -14.962 -45.671 18.623 1.00 52.23 C +ATOM 4799 CG GLN A 303 -13.648 -45.379 17.925 1.00 54.38 C +ATOM 4800 CD GLN A 303 -12.472 -45.266 18.881 1.00 50.42 C +ATOM 4801 OE1 GLN A 303 -12.641 -45.023 20.075 1.00 52.29 O +ATOM 4802 NE2 GLN A 303 -11.270 -45.458 18.354 1.00 45.16 N +ATOM 4803 H GLN A 303 -14.456 -44.217 20.661 1.00 20.00 H +ATOM 4804 HA GLN A 303 -15.700 -43.725 18.131 1.00 20.00 H +ATOM 4805 HB2 GLN A 303 -14.746 -46.221 19.551 1.00 20.00 H +ATOM 4806 HB3 GLN A 303 -15.575 -46.298 17.959 1.00 20.00 H +ATOM 4807 HG2 GLN A 303 -13.443 -46.192 17.213 1.00 20.00 H +ATOM 4808 HG3 GLN A 303 -13.746 -44.429 17.379 1.00 20.00 H +ATOM 4809 HE21 GLN A 303 -10.456 -45.408 18.933 1.00 20.00 H +ATOM 4810 HE22 GLN A 303 -11.177 -45.653 17.378 1.00 20.00 H +ATOM 4811 N GLN A 304 -17.689 -44.854 20.431 1.00 50.35 N +ATOM 4812 CA GLN A 304 -19.089 -45.109 20.736 1.00 50.06 C +ATOM 4813 C GLN A 304 -19.902 -43.824 20.844 1.00 55.92 C +ATOM 4814 O GLN A 304 -21.020 -43.753 20.325 1.00 55.14 O +ATOM 4815 CB GLN A 304 -19.214 -45.913 22.035 1.00 50.62 C +ATOM 4816 CG GLN A 304 -19.086 -47.416 21.855 1.00 50.27 C +ATOM 4817 CD GLN A 304 -17.661 -47.855 21.591 1.00 51.32 C +ATOM 4818 OE1 GLN A 304 -16.768 -47.633 22.410 1.00 49.51 O +ATOM 4819 NE2 GLN A 304 -17.440 -48.482 20.443 1.00 48.73 N +ATOM 4820 H GLN A 304 -17.046 -44.733 21.187 1.00 20.00 H +ATOM 4821 HA GLN A 304 -19.522 -45.714 19.925 1.00 20.00 H +ATOM 4822 HB2 GLN A 304 -18.424 -45.580 22.724 1.00 20.00 H +ATOM 4823 HB3 GLN A 304 -20.199 -45.702 22.478 1.00 20.00 H +ATOM 4824 HG2 GLN A 304 -19.443 -47.911 22.770 1.00 20.00 H +ATOM 4825 HG3 GLN A 304 -19.712 -47.723 21.004 1.00 20.00 H +ATOM 4826 HE21 GLN A 304 -16.518 -48.795 20.214 1.00 20.00 H +ATOM 4827 HE22 GLN A 304 -18.195 -48.641 19.807 1.00 20.00 H +ATOM 4828 N TYR A 305 -19.373 -42.801 21.513 1.00 52.83 N +ATOM 4829 CA TYR A 305 -20.181 -41.611 21.750 1.00 54.05 C +ATOM 4830 C TYR A 305 -19.926 -40.487 20.753 1.00 55.00 C +ATOM 4831 O TYR A 305 -20.612 -39.462 20.818 1.00 56.65 O +ATOM 4832 CB TYR A 305 -20.008 -41.105 23.196 1.00 55.36 C +ATOM 4833 CG TYR A 305 -18.637 -40.618 23.633 1.00 56.09 C +ATOM 4834 CD1 TYR A 305 -18.187 -39.347 23.301 1.00 55.52 C +ATOM 4835 CD2 TYR A 305 -17.831 -41.399 24.453 1.00 55.79 C +ATOM 4836 CE1 TYR A 305 -16.948 -38.888 23.732 1.00 61.67 C +ATOM 4837 CE2 TYR A 305 -16.595 -40.948 24.889 1.00 58.00 C +ATOM 4838 CZ TYR A 305 -16.159 -39.693 24.525 1.00 60.23 C +ATOM 4839 OH TYR A 305 -14.932 -39.246 24.958 1.00 61.81 O +ATOM 4840 H TYR A 305 -18.432 -42.849 21.849 1.00 20.00 H +ATOM 4841 HA TYR A 305 -21.237 -41.899 21.642 1.00 20.00 H +ATOM 4842 HB2 TYR A 305 -20.709 -40.269 23.334 1.00 20.00 H +ATOM 4843 HB3 TYR A 305 -20.288 -41.932 23.865 1.00 20.00 H +ATOM 4844 HD1 TYR A 305 -18.810 -38.704 22.698 1.00 20.00 H +ATOM 4845 HD2 TYR A 305 -18.175 -42.377 24.757 1.00 20.00 H +ATOM 4846 HE1 TYR A 305 -16.605 -37.904 23.447 1.00 20.00 H +ATOM 4847 HE2 TYR A 305 -15.976 -41.578 25.511 1.00 20.00 H +ATOM 4848 HH TYR A 305 -14.497 -39.936 25.445 1.00 20.00 H +ATOM 4849 N LEU A 306 -18.976 -40.650 19.838 1.00 54.44 N +ATOM 4850 CA LEU A 306 -18.840 -39.769 18.683 1.00 58.90 C +ATOM 4851 C LEU A 306 -19.411 -40.523 17.489 1.00 60.82 C +ATOM 4852 O LEU A 306 -18.811 -41.493 17.016 1.00 56.78 O +ATOM 4853 CB LEU A 306 -17.385 -39.366 18.446 1.00 54.70 C +ATOM 4854 CG LEU A 306 -16.692 -38.558 19.544 1.00 56.92 C +ATOM 4855 CD1 LEU A 306 -15.243 -38.316 19.158 1.00 60.47 C +ATOM 4856 CD2 LEU A 306 -17.415 -37.242 19.792 1.00 53.91 C +ATOM 4857 H LEU A 306 -18.330 -41.405 19.945 1.00 20.00 H +ATOM 4858 HA LEU A 306 -19.436 -38.858 18.843 1.00 20.00 H +ATOM 4859 HB2 LEU A 306 -16.806 -40.290 18.301 1.00 20.00 H +ATOM 4860 HB3 LEU A 306 -17.355 -38.765 17.525 1.00 20.00 H +ATOM 4861 HG LEU A 306 -16.712 -39.147 20.473 1.00 20.00 H +ATOM 4862 HD11 LEU A 306 -14.745 -37.735 19.948 1.00 20.00 H +ATOM 4863 HD12 LEU A 306 -14.730 -39.281 19.035 1.00 20.00 H +ATOM 4864 HD13 LEU A 306 -15.204 -37.757 18.212 1.00 20.00 H +ATOM 4865 HD21 LEU A 306 -16.897 -36.682 20.584 1.00 20.00 H +ATOM 4866 HD22 LEU A 306 -17.421 -36.647 18.867 1.00 20.00 H +ATOM 4867 HD23 LEU A 306 -18.450 -37.445 20.104 1.00 20.00 H +ATOM 4868 N ARG A 307 -20.578 -40.093 17.015 1.00 62.62 N +ATOM 4869 CA ARG A 307 -21.230 -40.960 16.043 1.00 59.89 C +ATOM 4870 C ARG A 307 -21.058 -40.419 14.637 1.00 60.35 C +ATOM 4871 O ARG A 307 -21.301 -39.228 14.398 1.00 66.40 O +ATOM 4872 CB ARG A 307 -22.709 -41.123 16.377 1.00 60.43 C +ATOM 4873 CG ARG A 307 -22.912 -41.622 17.792 1.00 64.07 C +ATOM 4874 CD ARG A 307 -24.327 -42.080 18.043 1.00 74.57 C +ATOM 4875 NE ARG A 307 -24.696 -43.259 17.268 1.00 76.43 N +ATOM 4876 CZ ARG A 307 -24.293 -44.496 17.544 1.00 72.62 C +ATOM 4877 NH1 ARG A 307 -24.696 -45.503 16.783 1.00 66.58 N +ATOM 4878 NH2 ARG A 307 -23.479 -44.729 18.567 1.00 73.62 N +ATOM 4879 H ARG A 307 -20.983 -39.227 17.309 1.00 20.00 H +ATOM 4880 HA ARG A 307 -20.762 -41.954 16.085 1.00 20.00 H +ATOM 4881 HB2 ARG A 307 -23.209 -40.149 16.267 1.00 20.00 H +ATOM 4882 HB3 ARG A 307 -23.155 -41.845 15.677 1.00 20.00 H +ATOM 4883 HG2 ARG A 307 -22.230 -42.467 17.970 1.00 20.00 H +ATOM 4884 HG3 ARG A 307 -22.675 -40.807 18.491 1.00 20.00 H +ATOM 4885 HD2 ARG A 307 -24.433 -42.317 19.112 1.00 20.00 H +ATOM 4886 HD3 ARG A 307 -25.012 -41.260 17.779 1.00 20.00 H +ATOM 4887 HE ARG A 307 -25.292 -43.129 16.476 1.00 20.00 H +ATOM 4888 HH11 ARG A 307 -24.387 -46.433 16.980 1.00 20.00 H +ATOM 4889 HH12 ARG A 307 -25.309 -45.333 16.011 1.00 20.00 H +ATOM 4890 HH21 ARG A 307 -23.173 -45.661 18.760 1.00 20.00 H +ATOM 4891 HH22 ARG A 307 -23.172 -43.972 19.144 1.00 20.00 H +ATOM 4892 N PRO A 308 -20.646 -41.273 13.701 1.00 57.83 N +ATOM 4893 CA PRO A 308 -20.279 -40.794 12.363 1.00 60.59 C +ATOM 4894 C PRO A 308 -21.489 -40.353 11.558 1.00 59.51 C +ATOM 4895 O PRO A 308 -22.557 -40.966 11.613 1.00 57.34 O +ATOM 4896 CB PRO A 308 -19.603 -42.012 11.724 1.00 59.76 C +ATOM 4897 CG PRO A 308 -20.184 -43.178 12.446 1.00 60.87 C +ATOM 4898 CD PRO A 308 -20.435 -42.722 13.851 1.00 58.41 C +ATOM 4899 HA PRO A 308 -19.558 -39.967 12.434 1.00 20.00 H +ATOM 4900 HB2 PRO A 308 -19.832 -42.066 10.649 1.00 20.00 H +ATOM 4901 HB3 PRO A 308 -18.513 -41.971 11.865 1.00 20.00 H +ATOM 4902 HG2 PRO A 308 -21.127 -43.488 11.972 1.00 20.00 H +ATOM 4903 HG3 PRO A 308 -19.477 -44.020 12.440 1.00 20.00 H +ATOM 4904 HD2 PRO A 308 -21.327 -43.209 14.271 1.00 20.00 H +ATOM 4905 HD3 PRO A 308 -19.567 -42.930 14.494 1.00 20.00 H +ATOM 4906 N VAL A 309 -21.253 -39.194 10.862 1.00 66.42 N +ATOM 4907 CA VAL A 309 -22.249 -38.582 10.044 1.00 70.20 C +ATOM 4908 C VAL A 309 -22.006 -38.575 8.560 1.00 71.88 C +ATOM 4909 O VAL A 309 -20.966 -38.153 8.049 1.00 71.60 O +ATOM 4910 CB VAL A 309 -23.413 -37.893 10.661 1.00 69.50 C +ATOM 4911 CG1 VAL A 309 -24.171 -36.862 9.897 1.00 68.49 C +ATOM 4912 CG2 VAL A 309 -23.841 -38.164 12.077 1.00 67.59 C +ATOM 4913 H VAL A 309 -20.353 -38.765 10.930 1.00 20.00 H +ATOM 4914 HA VAL A 309 -22.811 -39.525 9.974 1.00 20.00 H +ATOM 4915 HB VAL A 309 -24.088 -38.679 10.293 1.00 20.00 H +ATOM 4916 HG11 VAL A 309 -24.989 -36.472 10.520 1.00 20.00 H +ATOM 4917 HG12 VAL A 309 -23.495 -36.039 9.622 1.00 20.00 H +ATOM 4918 HG13 VAL A 309 -24.588 -37.315 8.985 1.00 20.00 H +ATOM 4919 HG21 VAL A 309 -24.719 -37.546 12.319 1.00 20.00 H +ATOM 4920 HG22 VAL A 309 -24.101 -39.227 12.184 1.00 20.00 H +ATOM 4921 HG23 VAL A 309 -23.018 -37.916 12.763 1.00 20.00 H +ATOM 4922 N GLU A 310 -23.062 -39.100 7.843 0.00 99.99 N +ATOM 4923 CA GLU A 310 -22.932 -39.196 6.428 0.00 99.99 C +ATOM 4924 C GLU A 310 -23.132 -37.980 5.577 0.00 99.99 C +ATOM 4925 O GLU A 310 -24.128 -37.256 5.652 0.00 99.99 O +ATOM 4926 CB GLU A 310 -22.627 -40.527 5.795 0.00 99.99 C +ATOM 4927 CG GLU A 310 -21.160 -40.916 5.922 0.00 99.99 C +ATOM 4928 CD GLU A 310 -20.819 -41.467 7.288 0.00 99.99 C +ATOM 4929 OE1 GLU A 310 -21.747 -42.016 7.961 0.00 99.99 O +ATOM 4930 OE2 GLU A 310 -19.608 -41.331 7.646 0.00 99.99 O +ATOM 4931 H GLU A 310 -23.895 -39.404 8.304 0.00 20.00 H +ATOM 4932 HA GLU A 310 -21.857 -38.976 6.503 0.00 20.00 H +ATOM 4933 HB2 GLU A 310 -23.239 -41.299 6.285 0.00 20.00 H +ATOM 4934 HB3 GLU A 310 -22.886 -40.477 4.727 0.00 20.00 H +ATOM 4935 HG2 GLU A 310 -20.932 -41.682 5.167 0.00 20.00 H +ATOM 4936 HG3 GLU A 310 -20.542 -40.024 5.738 0.00 20.00 H +ATOM 4937 N ASP A 311 -22.044 -37.737 4.770 0.00 99.99 N +ATOM 4938 CA ASP A 311 -21.888 -36.527 4.018 0.00 99.99 C +ATOM 4939 C ASP A 311 -21.344 -36.656 2.615 0.00 99.99 C +ATOM 4940 O ASP A 311 -20.162 -36.960 2.404 0.00 99.99 O +ATOM 4941 CB ASP A 311 -22.077 -35.234 4.740 0.00 99.99 C +ATOM 4942 CG ASP A 311 -22.097 -33.981 3.927 0.00 99.99 C +ATOM 4943 OD1 ASP A 311 -22.781 -33.966 2.866 0.00 99.99 O +ATOM 4944 OD2 ASP A 311 -21.449 -32.994 4.416 0.00 99.99 O +ATOM 4945 H ASP A 311 -21.331 -38.435 4.705 0.00 20.00 H +ATOM 4946 HA ASP A 311 -22.932 -36.545 3.670 0.00 20.00 H +ATOM 4947 HB2 ASP A 311 -23.036 -35.293 5.276 0.00 20.00 H +ATOM 4948 HB3 ASP A 311 -21.257 -35.141 5.467 0.00 20.00 H +ATOM 4949 N VAL A 312 -22.275 -36.459 1.616 0.00 99.99 N +ATOM 4950 CA VAL A 312 -21.854 -36.466 0.244 0.00 99.99 C +ATOM 4951 C VAL A 312 -20.913 -35.414 -0.284 0.00 99.99 C +ATOM 4952 O VAL A 312 -19.948 -35.660 -1.018 0.00 99.99 O +ATOM 4953 CB VAL A 312 -22.399 -37.500 -0.673 0.00 99.99 C +ATOM 4954 CG1 VAL A 312 -23.800 -37.385 -1.179 0.00 99.99 C +ATOM 4955 CG2 VAL A 312 -21.543 -38.642 -1.119 0.00 99.99 C +ATOM 4956 H VAL A 312 -23.237 -36.313 1.847 0.00 20.00 H +ATOM 4957 HA VAL A 312 -21.004 -37.118 0.495 0.00 20.00 H +ATOM 4958 HB VAL A 312 -22.750 -38.089 0.187 0.00 20.00 H +ATOM 4959 HG11 VAL A 312 -24.023 -38.236 -1.840 0.00 20.00 H +ATOM 4960 HG12 VAL A 312 -24.498 -37.389 -0.329 0.00 20.00 H +ATOM 4961 HG13 VAL A 312 -23.911 -36.446 -1.741 0.00 20.00 H +ATOM 4962 HG21 VAL A 312 -22.121 -39.295 -1.789 0.00 20.00 H +ATOM 4963 HG22 VAL A 312 -20.663 -38.255 -1.654 0.00 20.00 H +ATOM 4964 HG23 VAL A 312 -21.213 -39.218 -0.241 0.00 20.00 H +ATOM 4965 N ALA A 313 -21.233 -34.145 0.139 0.00 99.99 N +ATOM 4966 CA ALA A 313 -20.252 -33.110 0.058 0.00 99.99 C +ATOM 4967 C ALA A 313 -19.091 -33.046 1.024 0.00 99.99 C +ATOM 4968 O ALA A 313 -18.207 -32.185 1.005 0.00 99.99 O +ATOM 4969 CB ALA A 313 -20.438 -32.027 -0.969 0.00 99.99 C +ATOM 4970 H ALA A 313 -22.145 -33.948 0.500 0.00 20.00 H +ATOM 4971 HA ALA A 313 -19.655 -33.704 -0.649 0.00 20.00 H +ATOM 4972 HB1 ALA A 313 -19.604 -31.312 -0.904 0.00 20.00 H +ATOM 4973 HB2 ALA A 313 -20.459 -32.474 -1.973 0.00 20.00 H +ATOM 4974 HB3 ALA A 313 -21.386 -31.502 -0.781 0.00 20.00 H +ATOM 4975 N THR A 314 -19.136 -34.072 1.944 0.00 99.99 N +ATOM 4976 CA THR A 314 -18.129 -34.288 2.926 0.00 99.99 C +ATOM 4977 C THR A 314 -17.043 -35.313 2.770 0.00 99.99 C +ATOM 4978 O THR A 314 -16.398 -35.757 3.729 0.00 99.99 O +ATOM 4979 CB THR A 314 -18.241 -33.601 4.236 0.00 99.99 C +ATOM 4980 OG1 THR A 314 -18.673 -34.333 5.352 0.00 99.99 O +ATOM 4981 CG2 THR A 314 -17.941 -32.144 4.416 0.00 99.99 C +ATOM 4982 H THR A 314 -19.916 -34.697 1.919 0.00 20.00 H +ATOM 4983 HA THR A 314 -17.493 -33.490 2.514 0.00 20.00 H +ATOM 4984 HB THR A 314 -17.195 -33.852 4.466 0.00 20.00 H +ATOM 4985 HG1 THR A 314 -19.493 -33.972 5.670 0.00 20.00 H +ATOM 4986 HG21 THR A 314 -18.094 -31.865 5.469 0.00 20.00 H +ATOM 4987 HG22 THR A 314 -16.897 -31.947 4.132 0.00 20.00 H +ATOM 4988 HG23 THR A 314 -18.612 -31.550 3.779 0.00 20.00 H +ATOM 4989 N SER A 315 -16.782 -35.679 1.469 1.00 98.19 N +ATOM 4990 CA SER A 315 -16.033 -36.876 1.222 1.00 93.06 C +ATOM 4991 C SER A 315 -14.640 -37.154 1.720 1.00 91.42 C +ATOM 4992 O SER A 315 -14.229 -38.296 1.985 1.00 92.16 O +ATOM 4993 CB SER A 315 -16.569 -37.882 0.248 1.00 92.45 C +ATOM 4994 OG SER A 315 -17.957 -38.141 0.490 0.00 92.60 O +ATOM 4995 H SER A 315 -17.110 -35.119 0.708 1.00 20.00 H +ATOM 4996 HA SER A 315 -16.490 -37.394 2.077 1.00 20.00 H +ATOM 4997 HB2 SER A 315 -16.449 -37.492 -0.774 1.00 20.00 H +ATOM 4998 HB3 SER A 315 -16.004 -38.820 0.351 1.00 20.00 H +ATOM 4999 HG SER A 315 -18.276 -37.554 1.166 0.00 20.00 H +ATOM 5000 N GLN A 316 -13.836 -36.034 1.773 1.00 89.06 N +ATOM 5001 CA GLN A 316 -12.474 -36.158 2.276 1.00 89.60 C +ATOM 5002 C GLN A 316 -12.370 -35.936 3.781 1.00 88.92 C +ATOM 5003 O GLN A 316 -11.256 -35.954 4.316 1.00 88.14 O +ATOM 5004 CB GLN A 316 -11.549 -35.179 1.540 1.00 90.37 C +ATOM 5005 CG GLN A 316 -11.384 -35.474 0.053 0.00 88.44 C +ATOM 5006 CD GLN A 316 -10.315 -34.612 -0.599 0.00 90.32 C +ATOM 5007 OE1 GLN A 316 -10.013 -33.515 -0.129 0.00 91.82 O +ATOM 5008 NE2 GLN A 316 -9.732 -35.112 -1.683 0.00 90.39 N +ATOM 5009 H GLN A 316 -14.184 -35.147 1.469 1.00 20.00 H +ATOM 5010 HA GLN A 316 -12.115 -37.176 2.064 1.00 20.00 H +ATOM 5011 HB2 GLN A 316 -11.964 -34.166 1.647 1.00 20.00 H +ATOM 5012 HB3 GLN A 316 -10.556 -35.221 2.012 1.00 20.00 H +ATOM 5013 HG2 GLN A 316 -11.106 -36.531 -0.068 0.00 20.00 H +ATOM 5014 HG3 GLN A 316 -12.343 -35.287 -0.452 0.00 20.00 H +ATOM 5015 HE21 GLN A 316 -9.017 -34.592 -2.151 0.00 20.00 H +ATOM 5016 HE22 GLN A 316 -10.008 -36.008 -2.031 0.00 20.00 H +ATOM 5017 N ASP A 317 -13.490 -35.737 4.472 1.00 83.89 N +ATOM 5018 CA ASP A 317 -13.507 -35.497 5.909 1.00 82.40 C +ATOM 5019 C ASP A 317 -14.390 -36.520 6.611 1.00 80.15 C +ATOM 5020 O ASP A 317 -15.423 -36.936 6.075 1.00 79.85 O +ATOM 5021 CB ASP A 317 -14.015 -34.086 6.235 1.00 82.17 C +ATOM 5022 CG ASP A 317 -12.974 -33.016 5.989 1.00 85.06 C +ATOM 5023 OD1 ASP A 317 -11.818 -33.362 5.665 1.00 85.32 O +ATOM 5024 OD2 ASP A 317 -13.318 -31.822 6.126 1.00 88.32 O +ATOM 5025 H ASP A 317 -14.361 -35.753 3.981 1.00 20.00 H +ATOM 5026 HA ASP A 317 -12.485 -35.593 6.304 1.00 20.00 H +ATOM 5027 HB2 ASP A 317 -14.892 -33.874 5.606 1.00 20.00 H +ATOM 5028 HB3 ASP A 317 -14.308 -34.054 7.295 1.00 20.00 H +ATOM 5029 N ASP A 318 -13.974 -36.927 7.810 1.00 78.66 N +ATOM 5030 CA ASP A 318 -14.811 -37.702 8.718 1.00 72.54 C +ATOM 5031 C ASP A 318 -15.424 -36.738 9.728 1.00 69.54 C +ATOM 5032 O ASP A 318 -14.700 -35.974 10.375 1.00 71.20 O +ATOM 5033 CB ASP A 318 -14.007 -38.788 9.438 1.00 72.59 C +ATOM 5034 CG ASP A 318 -13.371 -39.785 8.487 1.00 72.18 C +ATOM 5035 OD1 ASP A 318 -13.873 -39.948 7.354 1.00 73.77 O +ATOM 5036 OD2 ASP A 318 -12.369 -40.416 8.885 1.00 71.82 O +ATOM 5037 H ASP A 318 -13.047 -36.690 8.100 1.00 20.00 H +ATOM 5038 HA ASP A 318 -15.622 -38.183 8.152 1.00 20.00 H +ATOM 5039 HB2 ASP A 318 -13.211 -38.305 10.023 1.00 20.00 H +ATOM 5040 HB3 ASP A 318 -14.681 -39.332 10.116 1.00 20.00 H +ATOM 5041 N CYS A 319 -16.748 -36.764 9.857 1.00 67.56 N +ATOM 5042 CA CYS A 319 -17.465 -35.865 10.752 1.00 68.00 C +ATOM 5043 C CYS A 319 -18.319 -36.667 11.724 1.00 61.49 C +ATOM 5044 O CYS A 319 -18.741 -37.786 11.422 1.00 58.68 O +ATOM 5045 CB CYS A 319 -18.347 -34.883 9.972 1.00 77.68 C +ATOM 5046 SG CYS A 319 -17.466 -33.841 8.779 1.00 83.99 S +ATOM 5047 H CYS A 319 -17.271 -37.425 9.319 1.00 20.00 H +ATOM 5048 HA CYS A 319 -16.737 -35.282 11.335 1.00 20.00 H +ATOM 5049 HB2 CYS A 319 -19.103 -35.465 9.424 1.00 20.00 H +ATOM 5050 HB3 CYS A 319 -18.847 -34.224 10.697 1.00 20.00 H +ATOM 5051 N TYR A 320 -18.578 -36.084 12.896 1.00 63.65 N +ATOM 5052 CA TYR A 320 -19.195 -36.815 13.995 1.00 65.50 C +ATOM 5053 C TYR A 320 -20.105 -35.911 14.814 1.00 64.55 C +ATOM 5054 O TYR A 320 -19.908 -34.695 14.879 1.00 70.33 O +ATOM 5055 CB TYR A 320 -18.139 -37.421 14.934 1.00 64.33 C +ATOM 5056 CG TYR A 320 -17.092 -38.265 14.247 1.00 62.44 C +ATOM 5057 CD1 TYR A 320 -15.951 -37.689 13.707 1.00 62.05 C +ATOM 5058 CD2 TYR A 320 -17.239 -39.640 14.151 1.00 58.51 C +ATOM 5059 CE1 TYR A 320 -14.992 -38.457 13.080 1.00 61.50 C +ATOM 5060 CE2 TYR A 320 -16.284 -40.417 13.528 1.00 56.60 C +ATOM 5061 CZ TYR A 320 -15.163 -39.822 12.995 1.00 62.58 C +ATOM 5062 OH TYR A 320 -14.210 -40.596 12.375 1.00 67.60 O +ATOM 5063 H TYR A 320 -18.343 -35.120 13.023 1.00 20.00 H +ATOM 5064 HA TYR A 320 -19.801 -37.637 13.586 1.00 20.00 H +ATOM 5065 HB2 TYR A 320 -17.628 -36.596 15.452 1.00 20.00 H +ATOM 5066 HB3 TYR A 320 -18.658 -38.052 15.671 1.00 20.00 H +ATOM 5067 HD1 TYR A 320 -15.811 -36.620 13.779 1.00 20.00 H +ATOM 5068 HD2 TYR A 320 -18.116 -40.111 14.571 1.00 20.00 H +ATOM 5069 HE1 TYR A 320 -14.113 -37.992 12.658 1.00 20.00 H +ATOM 5070 HE2 TYR A 320 -16.415 -41.487 13.459 1.00 20.00 H +ATOM 5071 HH TYR A 320 -13.385 -40.126 12.353 1.00 20.00 H +ATOM 5072 N LYS A 321 -21.088 -36.533 15.464 1.00 64.98 N +ATOM 5073 CA LYS A 321 -21.992 -35.866 16.390 1.00 66.86 C +ATOM 5074 C LYS A 321 -21.781 -36.409 17.798 1.00 65.03 C +ATOM 5075 O LYS A 321 -21.630 -37.620 17.992 1.00 64.80 O +ATOM 5076 CB LYS A 321 -23.457 -36.057 15.973 1.00 68.91 C +ATOM 5077 CG LYS A 321 -24.475 -35.712 17.067 1.00 74.51 C +ATOM 5078 CD LYS A 321 -25.915 -35.854 16.577 1.00 79.20 C +ATOM 5079 CE LYS A 321 -26.921 -35.642 17.707 1.00 83.62 C +ATOM 5080 NZ LYS A 321 -28.333 -35.634 17.223 1.00 87.37 N +ATOM 5081 H LYS A 321 -21.212 -37.513 15.307 1.00 20.00 H +ATOM 5082 HA LYS A 321 -21.774 -34.788 16.397 1.00 20.00 H +ATOM 5083 HB2 LYS A 321 -23.654 -35.413 15.103 1.00 20.00 H +ATOM 5084 HB3 LYS A 321 -23.600 -37.110 15.689 1.00 20.00 H +ATOM 5085 HG2 LYS A 321 -24.322 -36.389 17.920 1.00 20.00 H +ATOM 5086 HG3 LYS A 321 -24.311 -34.673 17.389 1.00 20.00 H +ATOM 5087 HD2 LYS A 321 -26.099 -35.107 15.791 1.00 20.00 H +ATOM 5088 HD3 LYS A 321 -26.052 -36.864 16.163 1.00 20.00 H +ATOM 5089 HE2 LYS A 321 -26.804 -36.454 18.440 1.00 20.00 H +ATOM 5090 HE3 LYS A 321 -26.709 -34.677 18.191 1.00 20.00 H +ATOM 5091 HZ1 LYS A 321 -28.885 -35.045 17.813 1.00 20.00 H +ATOM 5092 HZ2 LYS A 321 -28.362 -35.287 16.286 1.00 20.00 H +ATOM 5093 HZ3 LYS A 321 -28.698 -36.565 17.245 1.00 20.00 H +ATOM 5094 N PHE A 322 -21.764 -35.505 18.775 1.00 66.13 N +ATOM 5095 CA PHE A 322 -21.671 -35.890 20.178 1.00 63.56 C +ATOM 5096 C PHE A 322 -23.002 -36.485 20.621 1.00 66.39 C +ATOM 5097 O PHE A 322 -24.050 -35.846 20.481 1.00 64.92 O +ATOM 5098 CB PHE A 322 -21.303 -34.667 21.016 1.00 64.81 C +ATOM 5099 CG PHE A 322 -21.070 -34.959 22.473 1.00 65.93 C +ATOM 5100 CD1 PHE A 322 -19.988 -35.724 22.881 1.00 63.30 C +ATOM 5101 CD2 PHE A 322 -21.910 -34.428 23.440 1.00 66.69 C +ATOM 5102 CE1 PHE A 322 -19.766 -35.978 24.220 1.00 63.23 C +ATOM 5103 CE2 PHE A 322 -21.690 -34.677 24.783 1.00 65.90 C +ATOM 5104 CZ PHE A 322 -20.615 -35.452 25.173 1.00 60.85 C +ATOM 5105 H PHE A 322 -21.816 -34.534 18.540 1.00 20.00 H +ATOM 5106 HA PHE A 322 -20.886 -36.651 20.301 1.00 20.00 H +ATOM 5107 HB2 PHE A 322 -20.383 -34.230 20.601 1.00 20.00 H +ATOM 5108 HB3 PHE A 322 -22.123 -33.937 20.938 1.00 20.00 H +ATOM 5109 HD1 PHE A 322 -19.310 -36.126 22.142 1.00 20.00 H +ATOM 5110 HD2 PHE A 322 -22.746 -33.813 23.141 1.00 20.00 H +ATOM 5111 HE1 PHE A 322 -18.928 -36.589 24.522 1.00 20.00 H +ATOM 5112 HE2 PHE A 322 -22.358 -34.266 25.526 1.00 20.00 H +ATOM 5113 HZ PHE A 322 -20.439 -35.646 26.221 1.00 20.00 H +ATOM 5114 N ALA A 323 -22.971 -37.710 21.146 1.00 60.80 N +ATOM 5115 CA ALA A 323 -24.194 -38.461 21.403 1.00 61.71 C +ATOM 5116 C ALA A 323 -24.388 -38.776 22.880 1.00 62.04 C +ATOM 5117 O ALA A 323 -24.906 -39.836 23.233 1.00 60.51 O +ATOM 5118 CB ALA A 323 -24.223 -39.743 20.577 1.00 58.53 C +ATOM 5119 H ALA A 323 -22.088 -38.124 21.369 1.00 20.00 H +ATOM 5120 HA ALA A 323 -25.048 -37.846 21.083 1.00 20.00 H +ATOM 5121 HB1 ALA A 323 -25.152 -40.293 20.786 1.00 20.00 H +ATOM 5122 HB2 ALA A 323 -24.179 -39.491 19.507 1.00 20.00 H +ATOM 5123 HB3 ALA A 323 -23.359 -40.369 20.842 1.00 20.00 H +ATOM 5124 N ILE A 324 -23.964 -37.872 23.754 1.00 64.66 N +ATOM 5125 CA ILE A 324 -24.372 -37.872 25.151 1.00 64.18 C +ATOM 5126 C ILE A 324 -25.264 -36.662 25.355 1.00 65.41 C +ATOM 5127 O ILE A 324 -24.907 -35.548 24.956 1.00 65.17 O +ATOM 5128 CB ILE A 324 -23.169 -37.837 26.105 1.00 63.33 C +ATOM 5129 CG1 ILE A 324 -22.209 -38.973 25.776 1.00 64.92 C +ATOM 5130 CG2 ILE A 324 -23.633 -37.956 27.547 1.00 61.99 C +ATOM 5131 CD1 ILE A 324 -20.999 -38.957 26.625 1.00 64.43 C +ATOM 5132 H ILE A 324 -23.337 -37.160 23.439 1.00 20.00 H +ATOM 5133 HA ILE A 324 -24.957 -38.779 25.362 1.00 20.00 H +ATOM 5134 HB ILE A 324 -22.644 -36.879 25.977 1.00 20.00 H +ATOM 5135 HG12 ILE A 324 -22.731 -39.930 25.924 1.00 20.00 H +ATOM 5136 HG13 ILE A 324 -21.902 -38.882 24.723 1.00 20.00 H +ATOM 5137 HG21 ILE A 324 -22.761 -37.929 28.217 1.00 20.00 H +ATOM 5138 HG22 ILE A 324 -24.305 -37.118 27.786 1.00 20.00 H +ATOM 5139 HG23 ILE A 324 -24.170 -38.907 27.682 1.00 20.00 H +ATOM 5140 HD11 ILE A 324 -20.344 -39.795 26.346 1.00 20.00 H +ATOM 5141 HD12 ILE A 324 -20.462 -38.008 26.480 1.00 20.00 H +ATOM 5142 HD13 ILE A 324 -21.291 -39.056 27.681 1.00 20.00 H +ATOM 5143 N SER A 325 -26.425 -36.876 25.964 1.00 68.91 N +ATOM 5144 CA SER A 325 -27.430 -35.828 26.015 1.00 66.83 C +ATOM 5145 C SER A 325 -28.208 -35.924 27.317 1.00 65.98 C +ATOM 5146 O SER A 325 -28.036 -36.854 28.107 1.00 64.29 O +ATOM 5147 CB SER A 325 -28.362 -35.908 24.804 1.00 66.40 C +ATOM 5148 OG SER A 325 -28.927 -37.202 24.694 1.00 65.94 O +ATOM 5149 H SER A 325 -26.608 -37.762 26.389 1.00 20.00 H +ATOM 5150 HA SER A 325 -26.927 -34.850 25.990 1.00 20.00 H +ATOM 5151 HB2 SER A 325 -29.169 -35.170 24.920 1.00 20.00 H +ATOM 5152 HB3 SER A 325 -27.789 -35.685 23.892 1.00 20.00 H +ATOM 5153 HG SER A 325 -28.550 -37.770 25.356 1.00 20.00 H +ATOM 5154 N GLN A 326 -29.073 -34.938 27.524 1.00 69.51 N +ATOM 5155 CA GLN A 326 -29.797 -34.783 28.774 1.00 73.01 C +ATOM 5156 C GLN A 326 -31.135 -35.504 28.712 1.00 72.03 C +ATOM 5157 O GLN A 326 -31.782 -35.558 27.662 1.00 70.90 O +ATOM 5158 CB GLN A 326 -30.013 -33.301 29.086 1.00 77.42 C +ATOM 5159 CG GLN A 326 -30.803 -33.043 30.362 1.00 78.81 C +ATOM 5160 CD GLN A 326 -30.930 -31.570 30.693 1.00 83.42 C +ATOM 5161 OE1 GLN A 326 -29.951 -30.824 30.655 1.00 85.79 O +ATOM 5162 NE2 GLN A 326 -32.145 -31.142 31.021 1.00 84.26 N +ATOM 5163 H GLN A 326 -29.232 -34.277 26.791 1.00 20.00 H +ATOM 5164 HA GLN A 326 -29.206 -35.223 29.591 1.00 20.00 H +ATOM 5165 HB2 GLN A 326 -29.028 -32.822 29.187 1.00 20.00 H +ATOM 5166 HB3 GLN A 326 -30.557 -32.847 28.245 1.00 20.00 H +ATOM 5167 HG2 GLN A 326 -31.812 -33.463 30.240 1.00 20.00 H +ATOM 5168 HG3 GLN A 326 -30.294 -33.547 31.197 1.00 20.00 H +ATOM 5169 HE21 GLN A 326 -32.291 -30.180 31.250 1.00 20.00 H +ATOM 5170 HE22 GLN A 326 -32.913 -31.782 31.039 1.00 20.00 H +ATOM 5171 N SER A 327 -31.540 -36.060 29.847 1.00 72.97 N +ATOM 5172 CA SER A 327 -32.808 -36.754 29.975 1.00 75.40 C +ATOM 5173 C SER A 327 -33.587 -36.189 31.152 1.00 78.79 C +ATOM 5174 O SER A 327 -33.004 -35.821 32.177 1.00 77.42 O +ATOM 5175 CB SER A 327 -32.594 -38.254 30.164 1.00 71.78 C +ATOM 5176 OG SER A 327 -33.756 -38.871 30.691 1.00 66.36 O +ATOM 5177 H SER A 327 -30.946 -35.998 30.649 1.00 20.00 H +ATOM 5178 HA SER A 327 -33.400 -36.602 29.061 1.00 20.00 H +ATOM 5179 HB2 SER A 327 -32.355 -38.709 29.191 1.00 20.00 H +ATOM 5180 HB3 SER A 327 -31.756 -38.413 30.859 1.00 20.00 H +ATOM 5181 HG SER A 327 -33.511 -39.656 31.166 1.00 20.00 H +ATOM 5182 N SER A 328 -34.906 -36.116 30.991 1.00 79.85 N +ATOM 5183 CA SER A 328 -35.807 -35.734 32.068 1.00 86.09 C +ATOM 5184 C SER A 328 -36.442 -36.936 32.749 1.00 83.11 C +ATOM 5185 O SER A 328 -37.212 -36.760 33.700 1.00 86.76 O +ATOM 5186 CB SER A 328 -36.903 -34.806 31.536 1.00 90.74 C +ATOM 5187 OG SER A 328 -36.345 -33.633 30.973 1.00 94.71 O +ATOM 5188 H SER A 328 -35.293 -36.332 30.095 1.00 20.00 H +ATOM 5189 HA SER A 328 -35.236 -35.179 32.826 1.00 20.00 H +ATOM 5190 HB2 SER A 328 -37.480 -35.336 30.764 1.00 20.00 H +ATOM 5191 HB3 SER A 328 -37.570 -34.525 32.364 1.00 20.00 H +ATOM 5192 HG SER A 328 -35.478 -33.825 30.636 1.00 20.00 H +ATOM 5193 N THR A 329 -36.131 -38.152 32.296 1.00 76.14 N +ATOM 5194 CA THR A 329 -36.784 -39.360 32.787 1.00 72.87 C +ATOM 5195 C THR A 329 -35.787 -40.390 33.300 1.00 70.31 C +ATOM 5196 O THR A 329 -36.106 -41.582 33.355 1.00 64.57 O +ATOM 5197 CB THR A 329 -37.649 -39.979 31.689 1.00 72.83 C +ATOM 5198 OG1 THR A 329 -36.838 -40.243 30.536 1.00 72.96 O +ATOM 5199 CG2 THR A 329 -38.783 -39.036 31.308 1.00 77.63 C +ATOM 5200 H THR A 329 -35.424 -38.238 31.594 1.00 20.00 H +ATOM 5201 HA THR A 329 -37.446 -39.087 33.622 1.00 20.00 H +ATOM 5202 HB THR A 329 -38.081 -40.917 32.067 1.00 20.00 H +ATOM 5203 HG1 THR A 329 -36.657 -39.428 30.082 1.00 20.00 H +ATOM 5204 HG21 THR A 329 -39.394 -39.497 30.518 1.00 20.00 H +ATOM 5205 HG22 THR A 329 -39.410 -38.842 32.190 1.00 20.00 H +ATOM 5206 HG23 THR A 329 -38.363 -38.088 30.941 1.00 20.00 H +ATOM 5207 N GLY A 330 -34.590 -39.963 33.667 1.00 69.55 N +ATOM 5208 CA GLY A 330 -33.584 -40.875 34.162 1.00 66.75 C +ATOM 5209 C GLY A 330 -32.565 -41.235 33.103 1.00 64.12 C +ATOM 5210 O GLY A 330 -32.578 -40.740 31.974 1.00 65.13 O +ATOM 5211 H GLY A 330 -34.377 -38.988 33.600 1.00 20.00 H +ATOM 5212 HA2 GLY A 330 -33.063 -40.402 35.008 1.00 20.00 H +ATOM 5213 HA3 GLY A 330 -34.079 -41.796 34.504 1.00 20.00 H +ATOM 5214 N THR A 331 -31.660 -42.127 33.491 1.00 71.06 N +ATOM 5215 CA THR A 331 -30.588 -42.550 32.601 1.00 61.52 C +ATOM 5216 C THR A 331 -31.104 -43.537 31.564 1.00 57.99 C +ATOM 5217 O THR A 331 -31.830 -44.479 31.888 1.00 52.41 O +ATOM 5218 CB THR A 331 -29.450 -43.197 33.391 1.00 59.60 C +ATOM 5219 OG1 THR A 331 -28.970 -42.281 34.382 1.00 59.98 O +ATOM 5220 CG2 THR A 331 -28.311 -43.577 32.460 1.00 59.81 C +ATOM 5221 H THR A 331 -31.716 -42.515 34.411 1.00 20.00 H +ATOM 5222 HA THR A 331 -30.187 -41.672 32.074 1.00 20.00 H +ATOM 5223 HB THR A 331 -29.831 -44.108 33.875 1.00 20.00 H +ATOM 5224 HG1 THR A 331 -28.950 -42.711 35.229 1.00 20.00 H +ATOM 5225 HG21 THR A 331 -27.501 -44.041 33.042 1.00 20.00 H +ATOM 5226 HG22 THR A 331 -28.676 -44.290 31.706 1.00 20.00 H +ATOM 5227 HG23 THR A 331 -27.932 -42.675 31.958 1.00 20.00 H +ATOM 5228 N VAL A 332 -30.711 -43.327 30.313 1.00 55.30 N +ATOM 5229 CA VAL A 332 -31.024 -44.239 29.222 1.00 55.48 C +ATOM 5230 C VAL A 332 -29.704 -44.727 28.643 1.00 53.38 C +ATOM 5231 O VAL A 332 -28.971 -43.953 28.015 1.00 54.27 O +ATOM 5232 CB VAL A 332 -31.883 -43.575 28.138 1.00 55.74 C +ATOM 5233 CG1 VAL A 332 -32.250 -44.592 27.070 1.00 58.37 C +ATOM 5234 CG2 VAL A 332 -33.131 -42.957 28.741 1.00 56.34 C +ATOM 5235 H VAL A 332 -30.177 -42.506 30.111 1.00 20.00 H +ATOM 5236 HA VAL A 332 -31.574 -45.106 29.617 1.00 20.00 H +ATOM 5237 HB VAL A 332 -31.290 -42.776 27.669 1.00 20.00 H +ATOM 5238 HG11 VAL A 332 -32.865 -44.107 26.298 1.00 20.00 H +ATOM 5239 HG12 VAL A 332 -31.332 -44.989 26.612 1.00 20.00 H +ATOM 5240 HG13 VAL A 332 -32.818 -45.416 27.528 1.00 20.00 H +ATOM 5241 HG21 VAL A 332 -33.729 -42.488 27.946 1.00 20.00 H +ATOM 5242 HG22 VAL A 332 -33.726 -43.740 29.234 1.00 20.00 H +ATOM 5243 HG23 VAL A 332 -32.842 -42.195 29.480 1.00 20.00 H +ATOM 5244 N MET A 333 -29.398 -46.004 28.854 1.00 52.82 N +ATOM 5245 CA MET A 333 -28.222 -46.623 28.246 1.00 55.17 C +ATOM 5246 C MET A 333 -28.628 -47.119 26.867 1.00 54.99 C +ATOM 5247 O MET A 333 -29.100 -48.244 26.697 1.00 56.22 O +ATOM 5248 CB MET A 333 -27.683 -47.748 29.122 1.00 56.62 C +ATOM 5249 CG MET A 333 -27.090 -47.264 30.438 1.00 61.92 C +ATOM 5250 SD MET A 333 -27.042 -48.509 31.743 1.00 62.83 S +ATOM 5251 CE MET A 333 -25.793 -49.633 31.130 1.00 62.66 C +ATOM 5252 H MET A 333 -29.988 -46.555 29.444 1.00 20.00 H +ATOM 5253 HA MET A 333 -27.433 -45.866 28.127 1.00 20.00 H +ATOM 5254 HB2 MET A 333 -28.508 -48.440 29.346 1.00 20.00 H +ATOM 5255 HB3 MET A 333 -26.900 -48.280 28.562 1.00 20.00 H +ATOM 5256 HG2 MET A 333 -26.060 -46.927 30.247 1.00 20.00 H +ATOM 5257 HG3 MET A 333 -27.693 -46.416 30.795 1.00 20.00 H +ATOM 5258 HE1 MET A 333 -25.537 -50.361 31.914 1.00 20.00 H +ATOM 5259 HE2 MET A 333 -26.180 -50.165 30.248 1.00 20.00 H +ATOM 5260 HE3 MET A 333 -24.894 -49.064 30.850 1.00 20.00 H +ATOM 5261 N GLY A 334 -28.455 -46.253 25.875 1.00 56.86 N +ATOM 5262 CA GLY A 334 -28.850 -46.536 24.513 1.00 57.01 C +ATOM 5263 C GLY A 334 -27.758 -47.198 23.706 1.00 54.52 C +ATOM 5264 O GLY A 334 -26.861 -47.855 24.240 1.00 53.95 O +ATOM 5265 H GLY A 334 -28.034 -45.369 26.078 1.00 20.00 H +ATOM 5266 HA2 GLY A 334 -29.724 -47.203 24.533 1.00 20.00 H +ATOM 5267 HA3 GLY A 334 -29.123 -45.589 24.023 1.00 20.00 H +ATOM 5268 N ALA A 335 -27.841 -47.015 22.386 1.00 52.58 N +ATOM 5269 CA ALA A 335 -26.877 -47.632 21.479 1.00 51.61 C +ATOM 5270 C ALA A 335 -25.453 -47.197 21.785 1.00 52.85 C +ATOM 5271 O ALA A 335 -24.509 -47.960 21.557 1.00 53.04 O +ATOM 5272 CB ALA A 335 -27.226 -47.297 20.025 1.00 47.58 C +ATOM 5273 H ALA A 335 -28.574 -46.447 22.013 1.00 20.00 H +ATOM 5274 HA ALA A 335 -26.931 -48.724 21.595 1.00 20.00 H +ATOM 5275 HB1 ALA A 335 -26.493 -47.768 19.354 1.00 20.00 H +ATOM 5276 HB2 ALA A 335 -28.232 -47.676 19.793 1.00 20.00 H +ATOM 5277 HB3 ALA A 335 -27.204 -46.206 19.885 1.00 20.00 H +ATOM 5278 N VAL A 336 -25.280 -45.977 22.298 1.00 55.61 N +ATOM 5279 CA VAL A 336 -23.945 -45.506 22.666 1.00 57.51 C +ATOM 5280 C VAL A 336 -23.295 -46.484 23.634 1.00 57.95 C +ATOM 5281 O VAL A 336 -22.124 -46.852 23.489 1.00 61.23 O +ATOM 5282 CB VAL A 336 -24.016 -44.082 23.250 1.00 60.21 C +ATOM 5283 CG1 VAL A 336 -22.684 -43.688 23.879 1.00 56.67 C +ATOM 5284 CG2 VAL A 336 -24.395 -43.099 22.164 1.00 58.12 C +ATOM 5285 H VAL A 336 -26.070 -45.379 22.432 1.00 20.00 H +ATOM 5286 HA VAL A 336 -23.324 -45.465 21.759 1.00 20.00 H +ATOM 5287 HB VAL A 336 -24.792 -44.064 24.030 1.00 20.00 H +ATOM 5288 HG11 VAL A 336 -22.758 -42.670 24.288 1.00 20.00 H +ATOM 5289 HG12 VAL A 336 -22.438 -44.391 24.688 1.00 20.00 H +ATOM 5290 HG13 VAL A 336 -21.894 -43.719 23.114 1.00 20.00 H +ATOM 5291 HG21 VAL A 336 -24.444 -42.085 22.587 1.00 20.00 H +ATOM 5292 HG22 VAL A 336 -23.640 -43.126 21.365 1.00 20.00 H +ATOM 5293 HG23 VAL A 336 -25.377 -43.371 21.750 1.00 20.00 H +ATOM 5294 N ILE A 337 -24.057 -46.938 24.627 1.00 58.20 N +ATOM 5295 CA ILE A 337 -23.551 -47.951 25.546 1.00 56.31 C +ATOM 5296 C ILE A 337 -23.514 -49.318 24.870 1.00 52.67 C +ATOM 5297 O ILE A 337 -22.469 -49.976 24.821 1.00 50.41 O +ATOM 5298 CB ILE A 337 -24.399 -47.985 26.829 1.00 58.55 C +ATOM 5299 CG1 ILE A 337 -24.201 -46.700 27.638 1.00 60.82 C +ATOM 5300 CG2 ILE A 337 -24.065 -49.221 27.652 1.00 58.59 C +ATOM 5301 CD1 ILE A 337 -22.783 -46.513 28.155 1.00 60.82 C +ATOM 5302 H ILE A 337 -24.984 -46.581 24.744 1.00 20.00 H +ATOM 5303 HA ILE A 337 -22.522 -47.687 25.831 1.00 20.00 H +ATOM 5304 HB ILE A 337 -25.457 -48.044 26.535 1.00 20.00 H +ATOM 5305 HG12 ILE A 337 -24.452 -45.843 26.995 1.00 20.00 H +ATOM 5306 HG13 ILE A 337 -24.884 -46.724 28.500 1.00 20.00 H +ATOM 5307 HG21 ILE A 337 -24.679 -49.231 28.565 1.00 20.00 H +ATOM 5308 HG22 ILE A 337 -24.275 -50.124 27.059 1.00 20.00 H +ATOM 5309 HG23 ILE A 337 -23.000 -49.202 27.926 1.00 20.00 H +ATOM 5310 HD11 ILE A 337 -22.720 -45.573 28.723 1.00 20.00 H +ATOM 5311 HD12 ILE A 337 -22.518 -47.356 28.810 1.00 20.00 H +ATOM 5312 HD13 ILE A 337 -22.085 -46.475 27.306 1.00 20.00 H +ATOM 5313 N MET A 338 -24.654 -49.759 24.328 1.00 51.20 N +ATOM 5314 CA MET A 338 -24.792 -51.144 23.882 1.00 49.07 C +ATOM 5315 C MET A 338 -23.824 -51.505 22.764 1.00 47.59 C +ATOM 5316 O MET A 338 -23.469 -52.679 22.613 1.00 47.69 O +ATOM 5317 CB MET A 338 -26.229 -51.411 23.429 1.00 49.05 C +ATOM 5318 CG MET A 338 -27.279 -51.231 24.516 1.00 51.84 C +ATOM 5319 SD MET A 338 -28.948 -51.713 24.026 1.00 50.89 S +ATOM 5320 CE MET A 338 -28.750 -53.468 23.724 1.00 47.55 C +ATOM 5321 H MET A 338 -25.425 -49.131 24.226 1.00 20.00 H +ATOM 5322 HA MET A 338 -24.582 -51.807 24.734 1.00 20.00 H +ATOM 5323 HB2 MET A 338 -26.464 -50.719 22.607 1.00 20.00 H +ATOM 5324 HB3 MET A 338 -26.287 -52.447 23.064 1.00 20.00 H +ATOM 5325 HG2 MET A 338 -26.985 -51.841 25.383 1.00 20.00 H +ATOM 5326 HG3 MET A 338 -27.298 -50.169 24.804 1.00 20.00 H +ATOM 5327 HE1 MET A 338 -29.644 -54.004 24.074 1.00 20.00 H +ATOM 5328 HE2 MET A 338 -28.617 -53.642 22.646 1.00 20.00 H +ATOM 5329 HE3 MET A 338 -27.866 -53.836 24.266 1.00 20.00 H +ATOM 5330 N GLU A 339 -23.389 -50.531 21.966 1.00 47.66 N +ATOM 5331 CA GLU A 339 -22.510 -50.871 20.853 1.00 46.76 C +ATOM 5332 C GLU A 339 -21.107 -51.252 21.303 1.00 46.16 C +ATOM 5333 O GLU A 339 -20.336 -51.792 20.499 1.00 46.36 O +ATOM 5334 CB GLU A 339 -22.450 -49.720 19.853 1.00 51.42 C +ATOM 5335 CG GLU A 339 -23.678 -49.650 18.968 1.00 50.57 C +ATOM 5336 CD GLU A 339 -23.690 -48.435 18.072 1.00 55.39 C +ATOM 5337 OE1 GLU A 339 -22.645 -47.760 17.970 1.00 53.34 O +ATOM 5338 OE2 GLU A 339 -24.751 -48.158 17.470 1.00 52.07 O +ATOM 5339 H GLU A 339 -23.661 -49.582 22.128 1.00 20.00 H +ATOM 5340 HA GLU A 339 -22.936 -51.740 20.330 1.00 20.00 H +ATOM 5341 HB2 GLU A 339 -22.362 -48.775 20.409 1.00 20.00 H +ATOM 5342 HB3 GLU A 339 -21.564 -49.854 19.215 1.00 20.00 H +ATOM 5343 HG2 GLU A 339 -23.708 -50.551 18.338 1.00 20.00 H +ATOM 5344 HG3 GLU A 339 -24.571 -49.622 19.609 1.00 20.00 H +ATOM 5345 N GLY A 340 -20.751 -50.984 22.560 1.00 47.85 N +ATOM 5346 CA GLY A 340 -19.487 -51.486 23.060 1.00 49.82 C +ATOM 5347 C GLY A 340 -19.529 -52.930 23.502 1.00 46.59 C +ATOM 5348 O GLY A 340 -18.471 -53.538 23.701 1.00 44.47 O +ATOM 5349 H GLY A 340 -21.350 -50.443 23.151 1.00 20.00 H +ATOM 5350 HA2 GLY A 340 -18.737 -51.391 22.261 1.00 20.00 H +ATOM 5351 HA3 GLY A 340 -19.186 -50.870 23.920 1.00 20.00 H +ATOM 5352 N PHE A 341 -20.726 -53.506 23.625 1.00 47.33 N +ATOM 5353 CA PHE A 341 -20.890 -54.724 24.399 1.00 45.99 C +ATOM 5354 C PHE A 341 -21.865 -55.698 23.755 1.00 46.10 C +ATOM 5355 O PHE A 341 -22.684 -55.345 22.903 1.00 43.05 O +ATOM 5356 CB PHE A 341 -21.361 -54.400 25.818 1.00 48.00 C +ATOM 5357 CG PHE A 341 -20.565 -53.313 26.470 1.00 53.95 C +ATOM 5358 CD1 PHE A 341 -19.274 -53.551 26.910 1.00 51.90 C +ATOM 5359 CD2 PHE A 341 -21.098 -52.046 26.623 1.00 50.92 C +ATOM 5360 CE1 PHE A 341 -18.535 -52.548 27.502 1.00 51.52 C +ATOM 5361 CE2 PHE A 341 -20.366 -51.040 27.216 1.00 51.71 C +ATOM 5362 CZ PHE A 341 -19.078 -51.291 27.654 1.00 52.30 C +ATOM 5363 H PHE A 341 -21.520 -53.094 23.179 1.00 20.00 H +ATOM 5364 HA PHE A 341 -19.914 -55.226 24.477 1.00 20.00 H +ATOM 5365 HB2 PHE A 341 -22.414 -54.084 25.773 1.00 20.00 H +ATOM 5366 HB3 PHE A 341 -21.277 -55.310 26.430 1.00 20.00 H +ATOM 5367 HD1 PHE A 341 -18.841 -54.533 26.788 1.00 20.00 H +ATOM 5368 HD2 PHE A 341 -22.100 -51.843 26.274 1.00 20.00 H +ATOM 5369 HE1 PHE A 341 -17.531 -52.748 27.846 1.00 20.00 H +ATOM 5370 HE2 PHE A 341 -20.797 -50.057 27.338 1.00 20.00 H +ATOM 5371 HZ PHE A 341 -18.500 -50.504 28.114 1.00 20.00 H +ATOM 5372 N TYR A 342 -21.724 -56.948 24.177 1.00 41.79 N +ATOM 5373 CA TYR A 342 -22.722 -57.989 23.997 1.00 42.20 C +ATOM 5374 C TYR A 342 -23.552 -58.015 25.274 1.00 43.50 C +ATOM 5375 O TYR A 342 -23.011 -58.240 26.363 1.00 40.02 O +ATOM 5376 CB TYR A 342 -22.040 -59.333 23.741 1.00 40.82 C +ATOM 5377 CG TYR A 342 -22.934 -60.500 23.377 1.00 41.87 C +ATOM 5378 CD1 TYR A 342 -24.065 -60.336 22.583 1.00 41.17 C +ATOM 5379 CD2 TYR A 342 -22.612 -61.783 23.797 1.00 43.37 C +ATOM 5380 CE1 TYR A 342 -24.860 -61.423 22.241 1.00 44.00 C +ATOM 5381 CE2 TYR A 342 -23.397 -62.869 23.462 1.00 43.49 C +ATOM 5382 CZ TYR A 342 -24.522 -62.685 22.686 1.00 48.30 C +ATOM 5383 OH TYR A 342 -25.297 -63.774 22.357 1.00 46.85 O +ATOM 5384 H TYR A 342 -20.876 -57.189 24.649 1.00 20.00 H +ATOM 5385 HA TYR A 342 -23.375 -57.747 23.145 1.00 20.00 H +ATOM 5386 HB2 TYR A 342 -21.327 -59.191 22.916 1.00 20.00 H +ATOM 5387 HB3 TYR A 342 -21.493 -59.607 24.655 1.00 20.00 H +ATOM 5388 HD1 TYR A 342 -24.328 -59.351 22.228 1.00 20.00 H +ATOM 5389 HD2 TYR A 342 -21.728 -61.936 24.399 1.00 20.00 H +ATOM 5390 HE1 TYR A 342 -25.739 -61.281 21.629 1.00 20.00 H +ATOM 5391 HE2 TYR A 342 -23.131 -63.857 23.806 1.00 20.00 H +ATOM 5392 HH TYR A 342 -26.181 -63.487 22.162 1.00 20.00 H +ATOM 5393 N VAL A 343 -24.847 -57.746 25.148 1.00 39.18 N +ATOM 5394 CA VAL A 343 -25.723 -57.528 26.294 1.00 40.83 C +ATOM 5395 C VAL A 343 -26.708 -58.686 26.372 1.00 46.39 C +ATOM 5396 O VAL A 343 -27.446 -58.950 25.414 1.00 45.18 O +ATOM 5397 CB VAL A 343 -26.452 -56.179 26.195 1.00 38.85 C +ATOM 5398 CG1 VAL A 343 -27.349 -55.968 27.405 1.00 42.85 C +ATOM 5399 CG2 VAL A 343 -25.448 -55.045 26.059 1.00 38.49 C +ATOM 5400 H VAL A 343 -25.238 -57.691 24.229 1.00 20.00 H +ATOM 5401 HA VAL A 343 -25.120 -57.525 27.214 1.00 20.00 H +ATOM 5402 HB VAL A 343 -27.083 -56.194 25.294 1.00 20.00 H +ATOM 5403 HG11 VAL A 343 -27.862 -54.999 27.317 1.00 20.00 H +ATOM 5404 HG12 VAL A 343 -28.095 -56.775 27.453 1.00 20.00 H +ATOM 5405 HG13 VAL A 343 -26.739 -55.978 28.320 1.00 20.00 H +ATOM 5406 HG21 VAL A 343 -25.984 -54.087 25.989 1.00 20.00 H +ATOM 5407 HG22 VAL A 343 -24.788 -55.033 26.939 1.00 20.00 H +ATOM 5408 HG23 VAL A 343 -24.846 -55.195 25.151 1.00 20.00 H +ATOM 5409 N VAL A 344 -26.736 -59.362 27.515 1.00 46.32 N +ATOM 5410 CA VAL A 344 -27.569 -60.542 27.713 1.00 49.21 C +ATOM 5411 C VAL A 344 -28.741 -60.154 28.602 1.00 45.65 C +ATOM 5412 O VAL A 344 -28.561 -59.828 29.779 1.00 41.69 O +ATOM 5413 CB VAL A 344 -26.769 -61.702 28.318 1.00 53.34 C +ATOM 5414 CG1 VAL A 344 -27.702 -62.857 28.659 1.00 55.28 C +ATOM 5415 CG2 VAL A 344 -25.693 -62.154 27.348 1.00 44.25 C +ATOM 5416 H VAL A 344 -26.162 -59.049 28.271 1.00 20.00 H +ATOM 5417 HA VAL A 344 -27.966 -60.870 26.741 1.00 20.00 H +ATOM 5418 HB VAL A 344 -26.288 -61.352 29.243 1.00 20.00 H +ATOM 5419 HG11 VAL A 344 -27.120 -63.684 29.092 1.00 20.00 H +ATOM 5420 HG12 VAL A 344 -28.454 -62.518 29.386 1.00 20.00 H +ATOM 5421 HG13 VAL A 344 -28.206 -63.203 27.745 1.00 20.00 H +ATOM 5422 HG21 VAL A 344 -25.125 -62.986 27.791 1.00 20.00 H +ATOM 5423 HG22 VAL A 344 -26.162 -62.488 26.411 1.00 20.00 H +ATOM 5424 HG23 VAL A 344 -25.012 -61.316 27.139 1.00 20.00 H +ATOM 5425 N PHE A 345 -29.945 -60.197 28.038 1.00 49.35 N +ATOM 5426 CA PHE A 345 -31.172 -59.950 28.792 1.00 54.19 C +ATOM 5427 C PHE A 345 -31.657 -61.295 29.315 1.00 50.10 C +ATOM 5428 O PHE A 345 -32.464 -61.981 28.689 1.00 43.84 O +ATOM 5429 CB PHE A 345 -32.212 -59.254 27.923 1.00 49.28 C +ATOM 5430 CG PHE A 345 -31.775 -57.906 27.425 1.00 44.04 C +ATOM 5431 CD1 PHE A 345 -30.929 -57.797 26.333 1.00 41.83 C +ATOM 5432 CD2 PHE A 345 -32.209 -56.748 28.047 1.00 44.24 C +ATOM 5433 CE1 PHE A 345 -30.525 -56.558 25.870 1.00 40.46 C +ATOM 5434 CE2 PHE A 345 -31.809 -55.504 27.585 1.00 44.78 C +ATOM 5435 CZ PHE A 345 -30.965 -55.412 26.496 1.00 49.55 C +ATOM 5436 H PHE A 345 -30.013 -60.406 27.062 1.00 20.00 H +ATOM 5437 HA PHE A 345 -30.946 -59.302 29.652 1.00 20.00 H +ATOM 5438 HB2 PHE A 345 -32.423 -59.894 27.054 1.00 20.00 H +ATOM 5439 HB3 PHE A 345 -33.130 -59.125 28.515 1.00 20.00 H +ATOM 5440 HD1 PHE A 345 -30.581 -58.691 25.837 1.00 20.00 H +ATOM 5441 HD2 PHE A 345 -32.866 -56.815 28.901 1.00 20.00 H +ATOM 5442 HE1 PHE A 345 -29.865 -56.489 25.018 1.00 20.00 H +ATOM 5443 HE2 PHE A 345 -32.157 -54.607 28.076 1.00 20.00 H +ATOM 5444 HZ PHE A 345 -30.650 -54.444 26.136 1.00 20.00 H +ATOM 5445 N ASP A 346 -31.138 -61.676 30.479 1.00 50.53 N +ATOM 5446 CA ASP A 346 -31.432 -62.966 31.101 1.00 48.54 C +ATOM 5447 C ASP A 346 -32.690 -62.799 31.941 1.00 46.69 C +ATOM 5448 O ASP A 346 -32.631 -62.543 33.143 1.00 45.49 O +ATOM 5449 CB ASP A 346 -30.244 -63.435 31.936 1.00 52.99 C +ATOM 5450 CG ASP A 346 -30.439 -64.819 32.527 1.00 56.63 C +ATOM 5451 OD1 ASP A 346 -31.548 -65.384 32.417 1.00 53.83 O +ATOM 5452 OD2 ASP A 346 -29.467 -65.350 33.105 1.00 55.31 O +ATOM 5453 H ASP A 346 -30.517 -61.050 30.951 1.00 20.00 H +ATOM 5454 HA ASP A 346 -31.628 -63.714 30.319 1.00 20.00 H +ATOM 5455 HB2 ASP A 346 -29.350 -63.451 31.295 1.00 20.00 H +ATOM 5456 HB3 ASP A 346 -30.092 -62.721 32.759 1.00 20.00 H +ATOM 5457 N ARG A 347 -33.849 -62.956 31.298 1.00 48.66 N +ATOM 5458 CA ARG A 347 -35.112 -62.781 32.007 1.00 46.44 C +ATOM 5459 C ARG A 347 -35.359 -63.903 33.011 1.00 43.29 C +ATOM 5460 O ARG A 347 -35.991 -63.681 34.050 1.00 43.07 O +ATOM 5461 CB ARG A 347 -36.263 -62.686 31.004 1.00 47.01 C +ATOM 5462 CG ARG A 347 -36.229 -61.437 30.138 1.00 48.20 C +ATOM 5463 CD ARG A 347 -36.859 -61.684 28.776 1.00 51.57 C +ATOM 5464 NE ARG A 347 -38.263 -62.084 28.853 1.00 49.64 N +ATOM 5465 CZ ARG A 347 -39.291 -61.245 28.759 1.00 54.43 C +ATOM 5466 NH1 ARG A 347 -39.083 -59.945 28.587 1.00 51.42 N +ATOM 5467 NH2 ARG A 347 -40.533 -61.706 28.834 1.00 52.27 N +ATOM 5468 H ARG A 347 -33.852 -63.194 30.327 1.00 20.00 H +ATOM 5469 HA ARG A 347 -35.074 -61.833 32.564 1.00 20.00 H +ATOM 5470 HB2 ARG A 347 -36.220 -63.565 30.344 1.00 20.00 H +ATOM 5471 HB3 ARG A 347 -37.210 -62.693 31.563 1.00 20.00 H +ATOM 5472 HG2 ARG A 347 -36.782 -60.634 30.647 1.00 20.00 H +ATOM 5473 HG3 ARG A 347 -35.183 -61.129 29.997 1.00 20.00 H +ATOM 5474 HD2 ARG A 347 -36.792 -60.757 28.187 1.00 20.00 H +ATOM 5475 HD3 ARG A 347 -36.296 -62.482 28.270 1.00 20.00 H +ATOM 5476 HE ARG A 347 -38.464 -63.055 28.985 1.00 20.00 H +ATOM 5477 HH11 ARG A 347 -39.860 -59.320 28.515 1.00 20.00 H +ATOM 5478 HH12 ARG A 347 -38.149 -59.591 28.530 1.00 20.00 H +ATOM 5479 HH21 ARG A 347 -41.306 -61.075 28.761 1.00 20.00 H +ATOM 5480 HH22 ARG A 347 -40.696 -62.684 28.963 1.00 20.00 H +ATOM 5481 N ALA A 348 -34.872 -65.112 32.720 1.00 45.59 N +ATOM 5482 CA ALA A 348 -35.094 -66.236 33.626 1.00 49.80 C +ATOM 5483 C ALA A 348 -34.456 -65.992 34.989 1.00 54.63 C +ATOM 5484 O ALA A 348 -35.040 -66.327 36.026 1.00 54.94 O +ATOM 5485 CB ALA A 348 -34.555 -67.528 33.011 1.00 46.04 C +ATOM 5486 H ALA A 348 -34.352 -65.249 31.877 1.00 20.00 H +ATOM 5487 HA ALA A 348 -36.177 -66.360 33.776 1.00 20.00 H +ATOM 5488 HB1 ALA A 348 -34.729 -68.365 33.703 1.00 20.00 H +ATOM 5489 HB2 ALA A 348 -35.072 -67.725 32.061 1.00 20.00 H +ATOM 5490 HB3 ALA A 348 -33.476 -67.424 32.826 1.00 20.00 H +ATOM 5491 N ARG A 349 -33.262 -65.397 35.010 1.00 54.34 N +ATOM 5492 CA ARG A 349 -32.546 -65.133 36.253 1.00 53.29 C +ATOM 5493 C ARG A 349 -32.546 -63.651 36.624 1.00 50.96 C +ATOM 5494 O ARG A 349 -31.743 -63.228 37.463 1.00 49.47 O +ATOM 5495 CB ARG A 349 -31.116 -65.671 36.167 1.00 52.00 C +ATOM 5496 CG ARG A 349 -31.043 -67.189 36.022 1.00 54.76 C +ATOM 5497 CD ARG A 349 -29.611 -67.683 35.832 1.00 62.76 C +ATOM 5498 NE ARG A 349 -28.832 -67.683 37.070 1.00 66.14 N +ATOM 5499 CZ ARG A 349 -27.623 -68.225 37.187 1.00 69.05 C +ATOM 5500 NH1 ARG A 349 -27.054 -68.811 36.141 1.00 68.01 N +ATOM 5501 NH2 ARG A 349 -26.981 -68.187 38.347 1.00 72.65 N +ATOM 5502 H ARG A 349 -32.844 -65.123 34.144 1.00 20.00 H +ATOM 5503 HA ARG A 349 -33.053 -65.675 37.065 1.00 20.00 H +ATOM 5504 HB2 ARG A 349 -30.624 -65.214 35.296 1.00 20.00 H +ATOM 5505 HB3 ARG A 349 -30.580 -65.383 37.083 1.00 20.00 H +ATOM 5506 HG2 ARG A 349 -31.460 -67.652 36.929 1.00 20.00 H +ATOM 5507 HG3 ARG A 349 -31.640 -67.490 35.149 1.00 20.00 H +ATOM 5508 HD2 ARG A 349 -29.645 -68.710 35.440 1.00 20.00 H +ATOM 5509 HD3 ARG A 349 -29.109 -67.029 35.103 1.00 20.00 H +ATOM 5510 HE ARG A 349 -29.233 -67.249 37.877 1.00 20.00 H +ATOM 5511 HH11 ARG A 349 -26.146 -69.221 36.230 1.00 20.00 H +ATOM 5512 HH12 ARG A 349 -27.533 -68.843 35.264 1.00 20.00 H +ATOM 5513 HH21 ARG A 349 -26.073 -68.599 38.430 1.00 20.00 H +ATOM 5514 HH22 ARG A 349 -27.405 -67.747 39.139 1.00 20.00 H +ATOM 5515 N LYS A 350 -33.436 -62.862 36.015 1.00 47.48 N +ATOM 5516 CA LYS A 350 -33.692 -61.473 36.410 1.00 51.33 C +ATOM 5517 C LYS A 350 -32.391 -60.677 36.536 1.00 50.31 C +ATOM 5518 O LYS A 350 -32.104 -60.050 37.560 1.00 50.78 O +ATOM 5519 CB LYS A 350 -34.501 -61.427 37.710 1.00 56.00 C +ATOM 5520 CG LYS A 350 -35.292 -60.138 37.944 1.00 60.20 C +ATOM 5521 CD LYS A 350 -36.098 -60.220 39.237 1.00 63.33 C +ATOM 5522 CE LYS A 350 -36.776 -58.897 39.570 1.00 66.31 C +ATOM 5523 NZ LYS A 350 -37.530 -58.949 40.858 1.00 71.02 N +ATOM 5524 H LYS A 350 -33.956 -63.239 35.248 1.00 20.00 H +ATOM 5525 HA LYS A 350 -34.298 -60.996 35.625 1.00 20.00 H +ATOM 5526 HB2 LYS A 350 -35.214 -62.265 37.696 1.00 20.00 H +ATOM 5527 HB3 LYS A 350 -33.802 -61.554 38.550 1.00 20.00 H +ATOM 5528 HG2 LYS A 350 -34.591 -59.292 38.009 1.00 20.00 H +ATOM 5529 HG3 LYS A 350 -35.980 -59.980 37.100 1.00 20.00 H +ATOM 5530 HD2 LYS A 350 -36.869 -60.997 39.126 1.00 20.00 H +ATOM 5531 HD3 LYS A 350 -35.421 -60.490 40.061 1.00 20.00 H +ATOM 5532 HE2 LYS A 350 -36.006 -58.115 39.643 1.00 20.00 H +ATOM 5533 HE3 LYS A 350 -37.477 -58.646 38.761 1.00 20.00 H +ATOM 5534 HZ1 LYS A 350 -38.054 -58.105 40.972 1.00 20.00 H +ATOM 5535 HZ2 LYS A 350 -38.154 -59.730 40.847 1.00 20.00 H +ATOM 5536 HZ3 LYS A 350 -36.887 -59.047 41.617 1.00 20.00 H +ATOM 5537 N ARG A 351 -31.593 -60.719 35.473 1.00 50.16 N +ATOM 5538 CA ARG A 351 -30.295 -60.066 35.461 1.00 54.08 C +ATOM 5539 C ARG A 351 -29.951 -59.696 34.027 1.00 54.57 C +ATOM 5540 O ARG A 351 -30.515 -60.241 33.074 1.00 51.45 O +ATOM 5541 CB ARG A 351 -29.209 -60.969 36.061 1.00 49.89 C +ATOM 5542 CG ARG A 351 -29.041 -62.286 35.311 1.00 49.75 C +ATOM 5543 CD ARG A 351 -28.029 -63.221 35.968 1.00 48.00 C +ATOM 5544 NE ARG A 351 -27.720 -64.370 35.117 1.00 46.38 N +ATOM 5545 CZ ARG A 351 -26.749 -65.248 35.356 1.00 52.83 C +ATOM 5546 NH1 ARG A 351 -25.976 -65.117 36.427 1.00 52.55 N +ATOM 5547 NH2 ARG A 351 -26.546 -66.257 34.517 1.00 53.19 N +ATOM 5548 H ARG A 351 -31.895 -61.214 34.658 1.00 20.00 H +ATOM 5549 HA ARG A 351 -30.345 -59.143 36.057 1.00 20.00 H +ATOM 5550 HB2 ARG A 351 -28.251 -60.428 36.036 1.00 20.00 H +ATOM 5551 HB3 ARG A 351 -29.477 -61.193 37.104 1.00 20.00 H +ATOM 5552 HG2 ARG A 351 -30.015 -62.795 35.273 1.00 20.00 H +ATOM 5553 HG3 ARG A 351 -28.702 -62.066 34.288 1.00 20.00 H +ATOM 5554 HD2 ARG A 351 -27.102 -62.662 36.162 1.00 20.00 H +ATOM 5555 HD3 ARG A 351 -28.445 -63.584 36.919 1.00 20.00 H +ATOM 5556 HE ARG A 351 -28.278 -64.505 34.298 1.00 20.00 H +ATOM 5557 HH11 ARG A 351 -25.244 -65.777 36.599 1.00 20.00 H +ATOM 5558 HH12 ARG A 351 -26.125 -64.359 37.062 1.00 20.00 H +ATOM 5559 HH21 ARG A 351 -25.813 -66.914 34.693 1.00 20.00 H +ATOM 5560 HH22 ARG A 351 -27.126 -66.360 33.709 1.00 20.00 H +ATOM 5561 N ILE A 352 -29.023 -58.754 33.882 1.00 51.58 N +ATOM 5562 CA ILE A 352 -28.551 -58.294 32.578 1.00 51.74 C +ATOM 5563 C ILE A 352 -27.033 -58.432 32.538 1.00 48.76 C +ATOM 5564 O ILE A 352 -26.330 -57.841 33.370 1.00 50.84 O +ATOM 5565 CB ILE A 352 -28.967 -56.844 32.288 1.00 51.16 C +ATOM 5566 CG1 ILE A 352 -30.481 -56.711 32.181 1.00 57.82 C +ATOM 5567 CG2 ILE A 352 -28.337 -56.367 31.001 1.00 45.77 C +ATOM 5568 CD1 ILE A 352 -30.922 -55.321 31.763 1.00 62.49 C +ATOM 5569 H ILE A 352 -28.630 -58.341 34.704 1.00 20.00 H +ATOM 5570 HA ILE A 352 -28.977 -58.936 31.793 1.00 20.00 H +ATOM 5571 HB ILE A 352 -28.615 -56.208 33.113 1.00 20.00 H +ATOM 5572 HG12 ILE A 352 -30.845 -57.434 31.436 1.00 20.00 H +ATOM 5573 HG13 ILE A 352 -30.924 -56.940 33.161 1.00 20.00 H +ATOM 5574 HG21 ILE A 352 -28.643 -55.329 30.805 1.00 20.00 H +ATOM 5575 HG22 ILE A 352 -27.242 -56.416 31.089 1.00 20.00 H +ATOM 5576 HG23 ILE A 352 -28.668 -57.009 30.171 1.00 20.00 H +ATOM 5577 HD11 ILE A 352 -32.020 -55.287 31.703 1.00 20.00 H +ATOM 5578 HD12 ILE A 352 -30.572 -54.587 32.504 1.00 20.00 H +ATOM 5579 HD13 ILE A 352 -30.494 -55.081 30.779 1.00 20.00 H +ATOM 5580 N GLY A 353 -26.530 -59.191 31.567 1.00 45.65 N +ATOM 5581 CA GLY A 353 -25.101 -59.423 31.442 1.00 48.09 C +ATOM 5582 C GLY A 353 -24.464 -58.515 30.406 1.00 48.39 C +ATOM 5583 O GLY A 353 -25.080 -58.162 29.403 1.00 49.09 O +ATOM 5584 H GLY A 353 -27.152 -59.612 30.907 1.00 20.00 H +ATOM 5585 HA2 GLY A 353 -24.625 -59.238 32.416 1.00 20.00 H +ATOM 5586 HA3 GLY A 353 -24.936 -60.470 31.146 1.00 20.00 H +ATOM 5587 N PHE A 354 -23.212 -58.147 30.669 1.00 46.36 N +ATOM 5588 CA PHE A 354 -22.409 -57.322 29.781 1.00 45.68 C +ATOM 5589 C PHE A 354 -21.072 -58.003 29.538 1.00 47.23 C +ATOM 5590 O PHE A 354 -20.482 -58.580 30.459 1.00 46.12 O +ATOM 5591 CB PHE A 354 -22.164 -55.928 30.373 1.00 47.80 C +ATOM 5592 CG PHE A 354 -23.402 -55.093 30.511 1.00 47.29 C +ATOM 5593 CD1 PHE A 354 -24.251 -55.262 31.590 1.00 47.58 C +ATOM 5594 CD2 PHE A 354 -23.706 -54.125 29.571 1.00 43.70 C +ATOM 5595 CE1 PHE A 354 -25.394 -54.488 31.718 1.00 45.13 C +ATOM 5596 CE2 PHE A 354 -24.837 -53.347 29.695 1.00 41.54 C +ATOM 5597 CZ PHE A 354 -25.684 -53.530 30.770 1.00 48.82 C +ATOM 5598 H PHE A 354 -22.800 -58.456 31.526 1.00 20.00 H +ATOM 5599 HA PHE A 354 -22.926 -57.206 28.817 1.00 20.00 H +ATOM 5600 HB2 PHE A 354 -21.717 -56.050 31.371 1.00 20.00 H +ATOM 5601 HB3 PHE A 354 -21.459 -55.394 29.719 1.00 20.00 H +ATOM 5602 HD1 PHE A 354 -24.021 -56.004 32.340 1.00 20.00 H +ATOM 5603 HD2 PHE A 354 -23.048 -53.977 28.728 1.00 20.00 H +ATOM 5604 HE1 PHE A 354 -26.056 -54.635 32.559 1.00 20.00 H +ATOM 5605 HE2 PHE A 354 -25.060 -52.595 28.952 1.00 20.00 H +ATOM 5606 HZ PHE A 354 -26.572 -52.924 30.868 1.00 20.00 H +ATOM 5607 N ALA A 355 -20.598 -57.932 28.299 1.00 44.72 N +ATOM 5608 CA ALA A 355 -19.283 -58.440 27.951 1.00 45.69 C +ATOM 5609 C ALA A 355 -18.767 -57.629 26.776 1.00 47.09 C +ATOM 5610 O ALA A 355 -19.542 -57.050 26.009 1.00 46.79 O +ATOM 5611 CB ALA A 355 -19.316 -59.935 27.617 1.00 42.07 C +ATOM 5612 H ALA A 355 -21.163 -57.517 27.586 1.00 20.00 H +ATOM 5613 HA ALA A 355 -18.600 -58.292 28.801 1.00 20.00 H +ATOM 5614 HB1 ALA A 355 -18.302 -60.276 27.360 1.00 20.00 H +ATOM 5615 HB2 ALA A 355 -19.682 -60.497 28.489 1.00 20.00 H +ATOM 5616 HB3 ALA A 355 -19.987 -60.105 26.763 1.00 20.00 H +ATOM 5617 N VAL A 356 -17.442 -57.572 26.661 1.00 45.58 N +ATOM 5618 CA VAL A 356 -16.819 -56.848 25.560 1.00 44.25 C +ATOM 5619 C VAL A 356 -17.290 -57.438 24.247 1.00 43.39 C +ATOM 5620 O VAL A 356 -17.080 -58.632 23.977 1.00 42.84 O +ATOM 5621 CB VAL A 356 -15.294 -56.902 25.667 1.00 44.53 C +ATOM 5622 CG1 VAL A 356 -14.672 -56.313 24.412 1.00 41.91 C +ATOM 5623 CG2 VAL A 356 -14.826 -56.165 26.909 1.00 41.61 C +ATOM 5624 H VAL A 356 -16.867 -58.031 27.338 1.00 20.00 H +ATOM 5625 HA VAL A 356 -17.130 -55.794 25.599 1.00 20.00 H +ATOM 5626 HB VAL A 356 -14.988 -57.956 25.748 1.00 20.00 H +ATOM 5627 HG11 VAL A 356 -13.576 -56.353 24.492 1.00 20.00 H +ATOM 5628 HG12 VAL A 356 -14.997 -56.892 23.535 1.00 20.00 H +ATOM 5629 HG13 VAL A 356 -14.993 -55.267 24.300 1.00 20.00 H +ATOM 5630 HG21 VAL A 356 -13.729 -56.212 26.972 1.00 20.00 H +ATOM 5631 HG22 VAL A 356 -15.145 -55.114 26.853 1.00 20.00 H +ATOM 5632 HG23 VAL A 356 -15.265 -56.635 27.801 1.00 20.00 H +ATOM 5633 N SER A 357 -17.934 -56.623 23.418 1.00 44.39 N +ATOM 5634 CA SER A 357 -18.432 -57.096 22.136 1.00 44.76 C +ATOM 5635 C SER A 357 -17.281 -57.419 21.196 1.00 41.93 C +ATOM 5636 O SER A 357 -16.324 -56.654 21.079 1.00 42.38 O +ATOM 5637 CB SER A 357 -19.338 -56.051 21.491 1.00 43.26 C +ATOM 5638 OG SER A 357 -19.576 -56.354 20.127 1.00 46.18 O +ATOM 5639 H SER A 357 -18.079 -55.669 23.680 1.00 20.00 H +ATOM 5640 HA SER A 357 -19.019 -58.013 22.292 1.00 20.00 H +ATOM 5641 HB2 SER A 357 -20.298 -56.028 22.027 1.00 20.00 H +ATOM 5642 HB3 SER A 357 -18.856 -55.065 21.561 1.00 20.00 H +ATOM 5643 HG SER A 357 -20.487 -56.184 19.919 1.00 20.00 H +ATOM 5644 N ALA A 358 -17.391 -58.548 20.502 1.00 42.95 N +ATOM 5645 CA ALA A 358 -16.382 -58.929 19.522 1.00 40.91 C +ATOM 5646 C ALA A 358 -16.424 -58.101 18.242 1.00 48.79 C +ATOM 5647 O ALA A 358 -15.526 -58.251 17.409 1.00 57.47 O +ATOM 5648 CB ALA A 358 -16.521 -60.408 19.154 1.00 43.18 C +ATOM 5649 H ALA A 358 -18.178 -59.145 20.655 1.00 20.00 H +ATOM 5650 HA ALA A 358 -15.389 -58.792 19.974 1.00 20.00 H +ATOM 5651 HB1 ALA A 358 -15.752 -60.676 18.414 1.00 20.00 H +ATOM 5652 HB2 ALA A 358 -16.392 -61.024 20.056 1.00 20.00 H +ATOM 5653 HB3 ALA A 358 -17.519 -60.587 18.727 1.00 20.00 H +ATOM 5654 N CYS A 359 -17.435 -57.256 18.040 1.00 42.62 N +ATOM 5655 CA CYS A 359 -17.518 -56.467 16.817 1.00 45.62 C +ATOM 5656 C CYS A 359 -17.422 -54.969 17.059 1.00 45.50 C +ATOM 5657 O CYS A 359 -17.631 -54.194 16.120 1.00 48.88 O +ATOM 5658 CB CYS A 359 -18.817 -56.772 16.054 1.00 51.46 C +ATOM 5659 SG CYS A 359 -20.315 -56.096 16.805 1.00 61.22 S +ATOM 5660 H CYS A 359 -18.146 -57.162 18.737 1.00 20.00 H +ATOM 5661 HA CYS A 359 -16.680 -56.752 16.164 1.00 20.00 H +ATOM 5662 HB2 CYS A 359 -18.724 -56.355 15.040 1.00 20.00 H +ATOM 5663 HB3 CYS A 359 -18.929 -57.865 15.992 1.00 20.00 H +ATOM 5664 N HIS A 360 -17.095 -54.540 18.274 1.00 43.85 N +ATOM 5665 CA HIS A 360 -17.195 -53.126 18.599 1.00 46.06 C +ATOM 5666 C HIS A 360 -16.067 -52.332 17.948 1.00 43.98 C +ATOM 5667 O HIS A 360 -14.954 -52.827 17.739 1.00 44.07 O +ATOM 5668 CB HIS A 360 -17.192 -52.914 20.114 1.00 44.48 C +ATOM 5669 CG HIS A 360 -15.835 -52.990 20.740 1.00 50.56 C +ATOM 5670 ND1 HIS A 360 -15.286 -54.170 21.192 1.00 48.29 N +ATOM 5671 CD2 HIS A 360 -14.922 -52.026 21.006 1.00 56.30 C +ATOM 5672 CE1 HIS A 360 -14.091 -53.932 21.702 1.00 54.25 C +ATOM 5673 NE2 HIS A 360 -13.847 -52.638 21.602 1.00 54.55 N +ATOM 5674 H HIS A 360 -16.780 -55.190 18.965 1.00 20.00 H +ATOM 5675 HA HIS A 360 -18.148 -52.740 18.208 1.00 20.00 H +ATOM 5676 HB2 HIS A 360 -17.614 -51.920 20.324 1.00 20.00 H +ATOM 5677 HB3 HIS A 360 -17.827 -53.687 20.572 1.00 20.00 H +ATOM 5678 HD1 HIS A 360 -15.724 -55.068 21.142 1.00 20.00 H +ATOM 5679 HD2 HIS A 360 -15.021 -50.972 20.790 1.00 20.00 H +ATOM 5680 HE1 HIS A 360 -13.427 -54.670 22.128 1.00 20.00 H +ATOM 5681 N VAL A 361 -16.382 -51.082 17.613 1.00 42.98 N +ATOM 5682 CA VAL A 361 -15.436 -50.203 16.938 1.00 43.45 C +ATOM 5683 C VAL A 361 -14.413 -49.693 17.941 1.00 45.30 C +ATOM 5684 O VAL A 361 -14.770 -49.183 19.012 1.00 48.79 O +ATOM 5685 CB VAL A 361 -16.178 -49.039 16.263 1.00 42.26 C +ATOM 5686 CG1 VAL A 361 -15.200 -48.117 15.559 1.00 45.42 C +ATOM 5687 CG2 VAL A 361 -17.233 -49.568 15.297 1.00 45.13 C +ATOM 5688 H VAL A 361 -17.295 -50.736 17.831 1.00 20.00 H +ATOM 5689 HA VAL A 361 -14.906 -50.771 16.159 1.00 20.00 H +ATOM 5690 HB VAL A 361 -16.691 -48.463 17.047 1.00 20.00 H +ATOM 5691 HG11 VAL A 361 -15.750 -47.292 15.083 1.00 20.00 H +ATOM 5692 HG12 VAL A 361 -14.489 -47.708 16.292 1.00 20.00 H +ATOM 5693 HG13 VAL A 361 -14.651 -48.682 14.791 1.00 20.00 H +ATOM 5694 HG21 VAL A 361 -17.754 -48.723 14.823 1.00 20.00 H +ATOM 5695 HG22 VAL A 361 -16.747 -50.180 14.523 1.00 20.00 H +ATOM 5696 HG23 VAL A 361 -17.959 -50.183 15.848 1.00 20.00 H +ATOM 5697 N HIS A 362 -13.133 -49.823 17.604 1.00 45.68 N +ATOM 5698 CA HIS A 362 -12.070 -49.264 18.427 1.00 50.94 C +ATOM 5699 C HIS A 362 -10.825 -49.066 17.571 1.00 50.90 C +ATOM 5700 O HIS A 362 -10.832 -49.304 16.360 1.00 52.56 O +ATOM 5701 CB HIS A 362 -11.785 -50.157 19.637 1.00 51.28 C +ATOM 5702 CG HIS A 362 -11.311 -51.530 19.278 1.00 52.95 C +ATOM 5703 ND1 HIS A 362 -12.172 -52.549 18.932 1.00 53.25 N +ATOM 5704 CD2 HIS A 362 -10.064 -52.055 19.221 1.00 51.30 C +ATOM 5705 CE1 HIS A 362 -11.476 -53.642 18.673 1.00 51.42 C +ATOM 5706 NE2 HIS A 362 -10.195 -53.370 18.845 1.00 51.18 N +ATOM 5707 H HIS A 362 -12.895 -50.316 16.767 1.00 20.00 H +ATOM 5708 HA HIS A 362 -12.388 -48.279 18.799 1.00 20.00 H +ATOM 5709 HB2 HIS A 362 -11.011 -49.673 20.250 1.00 20.00 H +ATOM 5710 HB3 HIS A 362 -12.711 -50.252 20.223 1.00 20.00 H +ATOM 5711 HD1 HIS A 362 -13.168 -52.473 18.884 1.00 20.00 H +ATOM 5712 HD2 HIS A 362 -9.140 -51.537 19.432 1.00 20.00 H +ATOM 5713 HE1 HIS A 362 -11.885 -54.595 18.372 1.00 20.00 H +ATOM 5714 N ASP A 363 -9.750 -48.619 18.213 1.00 46.93 N +ATOM 5715 CA ASP A 363 -8.477 -48.372 17.555 1.00 47.30 C +ATOM 5716 C ASP A 363 -7.415 -49.324 18.100 1.00 47.38 C +ATOM 5717 O ASP A 363 -7.681 -50.176 18.955 1.00 42.55 O +ATOM 5718 CB ASP A 363 -8.055 -46.908 17.717 1.00 53.64 C +ATOM 5719 CG ASP A 363 -7.966 -46.476 19.169 1.00 54.13 C +ATOM 5720 OD1 ASP A 363 -7.057 -46.948 19.886 1.00 55.85 O +ATOM 5721 OD2 ASP A 363 -8.800 -45.646 19.593 1.00 54.04 O +ATOM 5722 H ASP A 363 -9.820 -48.444 19.195 1.00 20.00 H +ATOM 5723 HA ASP A 363 -8.590 -48.572 16.479 1.00 20.00 H +ATOM 5724 HB2 ASP A 363 -7.068 -46.773 17.250 1.00 20.00 H +ATOM 5725 HB3 ASP A 363 -8.792 -46.272 17.206 1.00 20.00 H +ATOM 5726 N GLU A 364 -6.190 -49.165 17.594 1.00 49.44 N +ATOM 5727 CA GLU A 364 -5.135 -50.121 17.910 1.00 54.77 C +ATOM 5728 C GLU A 364 -4.759 -50.100 19.384 1.00 52.74 C +ATOM 5729 O GLU A 364 -4.238 -51.093 19.900 1.00 59.10 O +ATOM 5730 CB GLU A 364 -3.903 -49.847 17.049 1.00 54.23 C +ATOM 5731 CG GLU A 364 -4.059 -50.240 15.588 0.00 53.20 C +ATOM 5732 CD GLU A 364 -2.774 -50.082 14.802 0.00 54.73 C +ATOM 5733 OE1 GLU A 364 -1.887 -49.327 15.251 0.00 55.96 O +ATOM 5734 OE2 GLU A 364 -2.649 -50.719 13.735 0.00 54.57 O +ATOM 5735 H GLU A 364 -5.995 -48.388 16.996 1.00 20.00 H +ATOM 5736 HA GLU A 364 -5.494 -51.132 17.669 1.00 20.00 H +ATOM 5737 HB2 GLU A 364 -3.684 -48.770 17.094 1.00 20.00 H +ATOM 5738 HB3 GLU A 364 -3.057 -50.411 17.469 1.00 20.00 H +ATOM 5739 HG2 GLU A 364 -4.375 -51.292 15.538 0.00 20.00 H +ATOM 5740 HG3 GLU A 364 -4.831 -49.603 15.132 0.00 20.00 H +ATOM 5741 N PHE A 365 -5.037 -49.001 20.082 1.00 50.70 N +ATOM 5742 CA PHE A 365 -4.506 -48.800 21.420 1.00 52.49 C +ATOM 5743 C PHE A 365 -5.549 -48.805 22.526 1.00 55.99 C +ATOM 5744 O PHE A 365 -5.176 -48.959 23.691 1.00 50.73 O +ATOM 5745 CB PHE A 365 -3.712 -47.488 21.473 1.00 51.33 C +ATOM 5746 CG PHE A 365 -2.592 -47.430 20.471 1.00 58.21 C +ATOM 5747 CD1 PHE A 365 -1.464 -48.220 20.631 1.00 54.88 C +ATOM 5748 CD2 PHE A 365 -2.672 -46.600 19.363 1.00 62.36 C +ATOM 5749 CE1 PHE A 365 -0.435 -48.181 19.712 1.00 54.60 C +ATOM 5750 CE2 PHE A 365 -1.642 -46.557 18.440 1.00 63.90 C +ATOM 5751 CZ PHE A 365 -0.522 -47.349 18.617 1.00 57.12 C +ATOM 5752 H PHE A 365 -5.623 -48.299 19.677 1.00 20.00 H +ATOM 5753 HA PHE A 365 -3.799 -49.615 21.633 1.00 20.00 H +ATOM 5754 HB2 PHE A 365 -4.402 -46.654 21.275 1.00 20.00 H +ATOM 5755 HB3 PHE A 365 -3.285 -47.379 22.481 1.00 20.00 H +ATOM 5756 HD1 PHE A 365 -1.390 -48.875 21.486 1.00 20.00 H +ATOM 5757 HD2 PHE A 365 -3.546 -45.982 19.219 1.00 20.00 H +ATOM 5758 HE1 PHE A 365 0.438 -48.802 19.851 1.00 20.00 H +ATOM 5759 HE2 PHE A 365 -1.713 -45.905 17.582 1.00 20.00 H +ATOM 5760 HZ PHE A 365 0.283 -47.315 17.898 1.00 20.00 H +ATOM 5761 N ARG A 366 -6.829 -48.652 22.207 1.00 52.06 N +ATOM 5762 CA ARG A 366 -7.872 -48.720 23.217 1.00 53.00 C +ATOM 5763 C ARG A 366 -8.991 -49.640 22.755 1.00 51.93 C +ATOM 5764 O ARG A 366 -9.295 -49.727 21.563 1.00 51.05 O +ATOM 5765 CB ARG A 366 -8.442 -47.331 23.544 1.00 54.00 C +ATOM 5766 CG ARG A 366 -7.768 -46.670 24.722 1.00 62.41 C +ATOM 5767 CD ARG A 366 -8.592 -45.532 25.282 1.00 61.01 C +ATOM 5768 NE ARG A 366 -9.055 -44.614 24.248 1.00 59.34 N +ATOM 5769 CZ ARG A 366 -9.205 -43.308 24.434 1.00 55.93 C +ATOM 5770 NH1 ARG A 366 -8.914 -42.771 25.612 1.00 52.52 N +ATOM 5771 NH2 ARG A 366 -9.634 -42.538 23.443 1.00 54.10 N +ATOM 5772 H ARG A 366 -7.080 -48.487 21.253 1.00 20.00 H +ATOM 5773 HA ARG A 366 -7.447 -49.137 24.142 1.00 20.00 H +ATOM 5774 HB2 ARG A 366 -8.316 -46.686 22.662 1.00 20.00 H +ATOM 5775 HB3 ARG A 366 -9.513 -47.438 23.770 1.00 20.00 H +ATOM 5776 HG2 ARG A 366 -7.617 -47.421 25.512 1.00 20.00 H +ATOM 5777 HG3 ARG A 366 -6.793 -46.277 24.398 1.00 20.00 H +ATOM 5778 HD2 ARG A 366 -9.468 -45.952 25.798 1.00 20.00 H +ATOM 5779 HD3 ARG A 366 -7.976 -44.972 26.001 1.00 20.00 H +ATOM 5780 HE ARG A 366 -9.272 -44.990 23.347 1.00 20.00 H +ATOM 5781 HH11 ARG A 366 -9.018 -41.786 25.752 1.00 20.00 H +ATOM 5782 HH12 ARG A 366 -8.590 -43.351 26.360 1.00 20.00 H +ATOM 5783 HH21 ARG A 366 -9.738 -41.553 23.584 1.00 20.00 H +ATOM 5784 HH22 ARG A 366 -9.854 -42.942 22.555 1.00 20.00 H +ATOM 5785 N THR A 367 -9.581 -50.353 23.711 0.50 49.94 N +ATOM 5786 CA THR A 367 -10.766 -51.162 23.470 0.50 49.73 C +ATOM 5787 C THR A 367 -11.800 -50.856 24.542 0.50 49.33 C +ATOM 5788 O THR A 367 -11.491 -50.273 25.584 0.50 50.58 O +ATOM 5789 CB THR A 367 -10.468 -52.675 23.478 0.50 49.58 C +ATOM 5790 OG1 THR A 367 -9.971 -53.067 24.765 0.50 48.81 O +ATOM 5791 CG2 THR A 367 -9.457 -53.045 22.406 0.50 48.86 C +ATOM 5792 H THR A 367 -9.194 -50.332 24.633 0.50 20.00 H +ATOM 5793 HA THR A 367 -11.192 -50.901 22.490 0.50 20.00 H +ATOM 5794 HB THR A 367 -11.406 -53.209 23.268 0.50 20.00 H +ATOM 5795 HG1 THR A 367 -10.693 -53.360 25.308 0.50 20.00 H +ATOM 5796 HG21 THR A 367 -9.267 -54.128 22.438 0.50 20.00 H +ATOM 5797 HG22 THR A 367 -9.855 -52.772 21.417 0.50 20.00 H +ATOM 5798 HG23 THR A 367 -8.517 -52.502 22.586 0.50 20.00 H +ATOM 5799 N ALA A 368 -13.041 -51.248 24.272 1.00 48.28 N +ATOM 5800 CA ALA A 368 -14.063 -51.210 25.302 1.00 42.16 C +ATOM 5801 C ALA A 368 -13.778 -52.321 26.307 1.00 46.57 C +ATOM 5802 O ALA A 368 -13.078 -53.290 26.012 1.00 41.41 O +ATOM 5803 CB ALA A 368 -15.459 -51.364 24.694 1.00 37.40 C +ATOM 5804 H ALA A 368 -13.272 -51.571 23.354 1.00 20.00 H +ATOM 5805 HA ALA A 368 -14.018 -50.245 25.827 1.00 20.00 H +ATOM 5806 HB1 ALA A 368 -16.213 -51.332 25.494 1.00 20.00 H +ATOM 5807 HB2 ALA A 368 -15.642 -50.544 23.984 1.00 20.00 H +ATOM 5808 HB3 ALA A 368 -15.525 -52.327 24.167 1.00 20.00 H +ATOM 5809 N ALA A 369 -14.307 -52.173 27.516 1.00 44.08 N +ATOM 5810 CA ALA A 369 -13.915 -53.080 28.583 1.00 45.75 C +ATOM 5811 C ALA A 369 -15.068 -53.352 29.533 1.00 44.38 C +ATOM 5812 O ALA A 369 -15.944 -52.512 29.743 1.00 47.47 O +ATOM 5813 CB ALA A 369 -12.724 -52.532 29.387 1.00 45.55 C +ATOM 5814 H ALA A 369 -14.969 -51.444 27.691 1.00 20.00 H +ATOM 5815 HA ALA A 369 -13.607 -54.038 28.139 1.00 20.00 H +ATOM 5816 HB1 ALA A 369 -12.459 -53.244 30.182 1.00 20.00 H +ATOM 5817 HB2 ALA A 369 -11.863 -52.393 28.717 1.00 20.00 H +ATOM 5818 HB3 ALA A 369 -12.999 -51.567 29.837 1.00 20.00 H +ATOM 5819 N VAL A 370 -15.044 -54.553 30.100 1.00 46.80 N +ATOM 5820 CA VAL A 370 -15.902 -54.952 31.206 1.00 48.41 C +ATOM 5821 C VAL A 370 -15.003 -55.615 32.240 1.00 49.65 C +ATOM 5822 O VAL A 370 -14.378 -56.642 31.952 1.00 52.56 O +ATOM 5823 CB VAL A 370 -17.015 -55.911 30.759 1.00 48.06 C +ATOM 5824 CG1 VAL A 370 -17.917 -56.245 31.924 1.00 43.89 C +ATOM 5825 CG2 VAL A 370 -17.814 -55.300 29.618 1.00 43.90 C +ATOM 5826 H VAL A 370 -14.395 -55.226 29.744 1.00 20.00 H +ATOM 5827 HA VAL A 370 -16.365 -54.062 31.657 1.00 20.00 H +ATOM 5828 HB VAL A 370 -16.547 -56.839 30.399 1.00 20.00 H +ATOM 5829 HG11 VAL A 370 -18.709 -56.932 31.590 1.00 20.00 H +ATOM 5830 HG12 VAL A 370 -17.327 -56.725 32.719 1.00 20.00 H +ATOM 5831 HG13 VAL A 370 -18.372 -55.322 32.312 1.00 20.00 H +ATOM 5832 HG21 VAL A 370 -18.606 -55.998 29.309 1.00 20.00 H +ATOM 5833 HG22 VAL A 370 -18.268 -54.355 29.953 1.00 20.00 H +ATOM 5834 HG23 VAL A 370 -17.146 -55.104 28.766 1.00 20.00 H +ATOM 5835 N GLU A 371 -14.916 -55.019 33.427 0.50 49.21 N +ATOM 5836 CA GLU A 371 -13.992 -55.482 34.452 0.50 49.52 C +ATOM 5837 C GLU A 371 -14.684 -55.536 35.805 0.50 49.05 C +ATOM 5838 O GLU A 371 -15.617 -54.776 36.080 0.50 46.70 O +ATOM 5839 CB GLU A 371 -12.753 -54.575 34.544 0.50 50.67 C +ATOM 5840 CG GLU A 371 -11.966 -54.443 33.246 0.50 54.24 C +ATOM 5841 CD GLU A 371 -11.194 -55.701 32.887 0.50 55.57 C +ATOM 5842 OE1 GLU A 371 -10.993 -56.559 33.772 0.50 59.58 O +ATOM 5843 OE2 GLU A 371 -10.782 -55.828 31.715 0.50 57.09 O +ATOM 5844 H GLU A 371 -15.502 -54.232 33.620 0.50 20.00 H +ATOM 5845 HA GLU A 371 -13.653 -56.497 34.198 0.50 20.00 H +ATOM 5846 HB2 GLU A 371 -13.084 -53.571 34.848 0.50 20.00 H +ATOM 5847 HB3 GLU A 371 -12.082 -54.988 35.312 0.50 20.00 H +ATOM 5848 HG2 GLU A 371 -12.670 -54.220 32.431 0.50 20.00 H +ATOM 5849 HG3 GLU A 371 -11.252 -53.613 33.352 0.50 20.00 H +ATOM 5850 N GLY A 372 -14.205 -56.442 36.652 1.00 49.57 N +ATOM 5851 CA GLY A 372 -14.724 -56.601 37.991 1.00 52.99 C +ATOM 5852 C GLY A 372 -13.958 -57.661 38.758 1.00 51.20 C +ATOM 5853 O GLY A 372 -13.096 -58.353 38.205 1.00 46.21 O +ATOM 5854 H GLY A 372 -13.458 -57.035 36.351 1.00 20.00 H +ATOM 5855 HA2 GLY A 372 -14.640 -55.642 38.524 1.00 20.00 H +ATOM 5856 HA3 GLY A 372 -15.782 -56.896 37.932 1.00 20.00 H +ATOM 5857 N PRO A 373 -14.259 -57.824 40.056 1.00 50.52 N +ATOM 5858 CA PRO A 373 -15.234 -57.087 40.860 1.00 50.76 C +ATOM 5859 C PRO A 373 -14.636 -55.878 41.569 1.00 57.01 C +ATOM 5860 O PRO A 373 -13.416 -55.716 41.612 1.00 55.93 O +ATOM 5861 CB PRO A 373 -15.682 -58.131 41.879 1.00 52.51 C +ATOM 5862 CG PRO A 373 -14.430 -58.916 42.128 1.00 50.75 C +ATOM 5863 CD PRO A 373 -13.697 -58.962 40.806 1.00 52.28 C +ATOM 5864 HA PRO A 373 -16.090 -56.774 40.244 1.00 20.00 H +ATOM 5865 HB2 PRO A 373 -16.040 -57.654 42.803 1.00 20.00 H +ATOM 5866 HB3 PRO A 373 -16.475 -58.772 41.466 1.00 20.00 H +ATOM 5867 HG2 PRO A 373 -13.812 -58.419 42.890 1.00 20.00 H +ATOM 5868 HG3 PRO A 373 -14.677 -59.934 42.463 1.00 20.00 H +ATOM 5869 HD2 PRO A 373 -12.614 -58.838 40.953 1.00 20.00 H +ATOM 5870 HD3 PRO A 373 -13.890 -59.910 40.283 1.00 20.00 H +ATOM 5871 N PHE A 374 -15.500 -55.037 42.130 1.00 59.32 N +ATOM 5872 CA PHE A 374 -15.075 -53.884 42.908 1.00 59.29 C +ATOM 5873 C PHE A 374 -15.898 -53.807 44.182 1.00 61.39 C +ATOM 5874 O PHE A 374 -17.117 -54.000 44.157 1.00 64.85 O +ATOM 5875 CB PHE A 374 -15.228 -52.581 42.119 1.00 57.48 C +ATOM 5876 CG PHE A 374 -14.502 -52.576 40.805 1.00 59.05 C +ATOM 5877 CD1 PHE A 374 -13.140 -52.316 40.745 1.00 52.20 C +ATOM 5878 CD2 PHE A 374 -15.184 -52.823 39.628 1.00 57.99 C +ATOM 5879 CE1 PHE A 374 -12.476 -52.309 39.532 1.00 55.38 C +ATOM 5880 CE2 PHE A 374 -14.527 -52.816 38.413 1.00 56.97 C +ATOM 5881 CZ PHE A 374 -13.173 -52.559 38.363 1.00 57.46 C +ATOM 5882 H PHE A 374 -16.479 -55.204 42.013 1.00 20.00 H +ATOM 5883 HA PHE A 374 -14.016 -54.000 43.183 1.00 20.00 H +ATOM 5884 HB2 PHE A 374 -16.298 -52.418 41.924 1.00 20.00 H +ATOM 5885 HB3 PHE A 374 -14.838 -51.756 42.733 1.00 20.00 H +ATOM 5886 HD1 PHE A 374 -12.593 -52.117 41.655 1.00 20.00 H +ATOM 5887 HD2 PHE A 374 -16.245 -53.024 39.659 1.00 20.00 H +ATOM 5888 HE1 PHE A 374 -11.415 -52.109 39.497 1.00 20.00 H +ATOM 5889 HE2 PHE A 374 -15.074 -53.012 37.502 1.00 20.00 H +ATOM 5890 HZ PHE A 374 -12.658 -52.553 37.414 1.00 20.00 H +ATOM 5891 N VAL A 375 -15.225 -53.525 45.294 1.00 56.93 N +ATOM 5892 CA VAL A 375 -15.911 -53.355 46.567 1.00 58.75 C +ATOM 5893 C VAL A 375 -16.670 -52.036 46.556 1.00 61.94 C +ATOM 5894 O VAL A 375 -16.073 -50.961 46.681 1.00 62.90 O +ATOM 5895 CB VAL A 375 -14.924 -53.415 47.747 1.00 57.42 C +ATOM 5896 CG1 VAL A 375 -15.620 -53.005 49.038 1.00 59.53 C +ATOM 5897 CG2 VAL A 375 -14.344 -54.812 47.877 1.00 51.92 C +ATOM 5898 H VAL A 375 -14.231 -53.428 45.255 1.00 20.00 H +ATOM 5899 HA VAL A 375 -16.640 -54.169 46.693 1.00 20.00 H +ATOM 5900 HB VAL A 375 -14.104 -52.709 47.550 1.00 20.00 H +ATOM 5901 HG11 VAL A 375 -14.904 -53.052 49.872 1.00 20.00 H +ATOM 5902 HG12 VAL A 375 -16.000 -51.978 48.939 1.00 20.00 H +ATOM 5903 HG13 VAL A 375 -16.459 -53.689 49.236 1.00 20.00 H +ATOM 5904 HG21 VAL A 375 -13.641 -54.841 48.723 1.00 20.00 H +ATOM 5905 HG22 VAL A 375 -15.157 -55.532 48.052 1.00 20.00 H +ATOM 5906 HG23 VAL A 375 -13.813 -55.076 46.951 1.00 20.00 H +ATOM 5907 N THR A 376 -17.987 -52.109 46.391 1.00 65.07 N +ATOM 5908 CA THR A 376 -18.854 -50.942 46.457 1.00 67.62 C +ATOM 5909 C THR A 376 -19.892 -51.189 47.539 1.00 70.15 C +ATOM 5910 O THR A 376 -20.718 -52.100 47.414 1.00 74.91 O +ATOM 5911 CB THR A 376 -19.533 -50.669 45.113 1.00 73.55 C +ATOM 5912 OG1 THR A 376 -18.562 -50.729 44.061 1.00 77.36 O +ATOM 5913 CG2 THR A 376 -20.170 -49.289 45.119 1.00 73.13 C +ATOM 5914 H THR A 376 -18.399 -53.003 46.214 1.00 20.00 H +ATOM 5915 HA THR A 376 -18.260 -50.058 46.734 1.00 20.00 H +ATOM 5916 HB THR A 376 -20.316 -51.424 44.950 1.00 20.00 H +ATOM 5917 HG1 THR A 376 -17.717 -50.450 44.393 1.00 20.00 H +ATOM 5918 HG21 THR A 376 -20.654 -49.104 44.149 1.00 20.00 H +ATOM 5919 HG22 THR A 376 -20.922 -49.236 45.920 1.00 20.00 H +ATOM 5920 HG23 THR A 376 -19.395 -48.528 45.292 1.00 20.00 H +ATOM 5921 N LEU A 377 -19.845 -50.387 48.595 1.00 70.50 N +ATOM 5922 CA LEU A 377 -20.760 -50.547 49.713 1.00 72.06 C +ATOM 5923 C LEU A 377 -21.992 -49.669 49.527 1.00 78.83 C +ATOM 5924 O LEU A 377 -21.977 -48.681 48.788 1.00 83.38 O +ATOM 5925 CB LEU A 377 -20.064 -50.202 51.030 1.00 69.44 C +ATOM 5926 CG LEU A 377 -18.655 -50.773 51.200 1.00 69.12 C +ATOM 5927 CD1 LEU A 377 -18.067 -50.385 52.551 1.00 72.28 C +ATOM 5928 CD2 LEU A 377 -18.656 -52.283 51.022 1.00 70.40 C +ATOM 5929 H LEU A 377 -19.164 -49.655 48.622 1.00 20.00 H +ATOM 5930 HA LEU A 377 -21.089 -51.596 49.763 1.00 20.00 H +ATOM 5931 HB2 LEU A 377 -19.996 -49.106 51.101 1.00 20.00 H +ATOM 5932 HB3 LEU A 377 -20.686 -50.585 51.852 1.00 20.00 H +ATOM 5933 HG LEU A 377 -18.018 -50.339 50.416 1.00 20.00 H +ATOM 5934 HD11 LEU A 377 -17.056 -50.808 52.646 1.00 20.00 H +ATOM 5935 HD12 LEU A 377 -18.015 -49.289 52.627 1.00 20.00 H +ATOM 5936 HD13 LEU A 377 -18.706 -50.778 53.355 1.00 20.00 H +ATOM 5937 HD21 LEU A 377 -17.633 -52.668 51.149 1.00 20.00 H +ATOM 5938 HD22 LEU A 377 -19.316 -52.740 51.774 1.00 20.00 H +ATOM 5939 HD23 LEU A 377 -19.020 -52.533 50.014 1.00 20.00 H +ATOM 5940 N ASP A 378 -23.067 -50.048 50.216 1.00 79.01 N +ATOM 5941 CA ASP A 378 -24.318 -49.289 50.224 1.00 80.11 C +ATOM 5942 C ASP A 378 -24.830 -49.058 48.805 1.00 82.25 C +ATOM 5943 O ASP A 378 -25.123 -47.932 48.396 1.00 87.32 O +ATOM 5944 CB ASP A 378 -24.146 -47.963 50.967 1.00 78.88 C +ATOM 5945 CG ASP A 378 -23.660 -48.153 52.390 1.00 80.37 C +ATOM 5946 OD1 ASP A 378 -24.281 -48.945 53.131 1.00 83.97 O +ATOM 5947 OD2 ASP A 378 -22.648 -47.523 52.764 1.00 84.50 O +ATOM 5948 H ASP A 378 -23.017 -50.890 50.753 1.00 20.00 H +ATOM 5949 HA ASP A 378 -25.078 -49.876 50.762 1.00 20.00 H +ATOM 5950 HB2 ASP A 378 -23.414 -47.347 50.424 1.00 20.00 H +ATOM 5951 HB3 ASP A 378 -25.116 -47.444 50.992 1.00 20.00 H +ATOM 5952 N MET A 379 -24.932 -50.150 48.045 1.00 76.42 N +ATOM 5953 CA MET A 379 -25.382 -50.049 46.663 1.00 76.42 C +ATOM 5954 C MET A 379 -26.896 -49.956 46.553 1.00 80.66 C +ATOM 5955 O MET A 379 -27.404 -49.355 45.600 1.00 83.51 O +ATOM 5956 CB MET A 379 -24.876 -51.240 45.850 1.00 72.23 C +ATOM 5957 CG MET A 379 -23.410 -51.167 45.469 1.00 67.37 C +ATOM 5958 SD MET A 379 -22.924 -52.542 44.408 1.00 62.51 S +ATOM 5959 CE MET A 379 -23.325 -53.938 45.456 1.00 65.01 C +ATOM 5960 H MET A 379 -24.698 -51.044 48.427 1.00 20.00 H +ATOM 5961 HA MET A 379 -24.956 -49.136 46.221 1.00 20.00 H +ATOM 5962 HB2 MET A 379 -25.031 -52.152 46.445 1.00 20.00 H +ATOM 5963 HB3 MET A 379 -25.468 -51.300 44.925 1.00 20.00 H +ATOM 5964 HG2 MET A 379 -23.228 -50.223 44.934 1.00 20.00 H +ATOM 5965 HG3 MET A 379 -22.802 -51.193 46.386 1.00 20.00 H +ATOM 5966 HE1 MET A 379 -22.771 -54.825 45.114 1.00 20.00 H +ATOM 5967 HE2 MET A 379 -23.045 -53.709 46.495 1.00 20.00 H +ATOM 5968 HE3 MET A 379 -24.405 -54.138 45.403 1.00 20.00 H +ATOM 5969 N GLU A 380 -27.632 -50.546 47.498 1.00 81.90 N +ATOM 5970 CA GLU A 380 -29.082 -50.381 47.493 1.00 78.32 C +ATOM 5971 C GLU A 380 -29.476 -48.928 47.714 1.00 77.91 C +ATOM 5972 O GLU A 380 -30.558 -48.506 47.288 1.00 85.12 O +ATOM 5973 CB GLU A 380 -29.727 -51.278 48.551 1.00 77.36 C +ATOM 5974 CG GLU A 380 -29.909 -52.727 48.123 0.00 74.02 C +ATOM 5975 CD GLU A 380 -28.598 -53.482 48.018 0.00 74.33 C +ATOM 5976 OE1 GLU A 380 -27.727 -53.297 48.895 0.00 75.26 O +ATOM 5977 OE2 GLU A 380 -28.437 -54.261 47.055 0.00 73.81 O +ATOM 5978 H GLU A 380 -27.192 -51.098 48.206 1.00 20.00 H +ATOM 5979 HA GLU A 380 -29.468 -50.690 46.510 1.00 20.00 H +ATOM 5980 HB2 GLU A 380 -29.092 -51.262 49.449 1.00 20.00 H +ATOM 5981 HB3 GLU A 380 -30.717 -50.865 48.795 1.00 20.00 H +ATOM 5982 HG2 GLU A 380 -30.547 -53.234 48.862 0.00 20.00 H +ATOM 5983 HG3 GLU A 380 -30.403 -52.743 47.140 0.00 20.00 H +ATOM 5984 N ASP A 381 -28.614 -48.147 48.369 1.00 74.17 N +ATOM 5985 CA ASP A 381 -28.905 -46.730 48.562 1.00 75.10 C +ATOM 5986 C ASP A 381 -28.968 -45.982 47.240 1.00 74.42 C +ATOM 5987 O ASP A 381 -29.650 -44.958 47.142 1.00 78.58 O +ATOM 5988 CB ASP A 381 -27.856 -46.086 49.467 1.00 77.23 C +ATOM 5989 CG ASP A 381 -27.969 -46.542 50.900 1.00 78.46 C +ATOM 5990 OD1 ASP A 381 -28.852 -47.377 51.186 1.00 90.72 O +ATOM 5991 OD2 ASP A 381 -27.175 -46.065 51.742 1.00 81.36 O +ATOM 5992 H ASP A 381 -27.765 -48.535 48.729 1.00 20.00 H +ATOM 5993 HA ASP A 381 -29.883 -46.633 49.055 1.00 20.00 H +ATOM 5994 HB2 ASP A 381 -26.856 -46.350 49.091 1.00 20.00 H +ATOM 5995 HB3 ASP A 381 -27.984 -44.994 49.433 1.00 20.00 H +ATOM 5996 N CYS A 382 -28.266 -46.472 46.217 1.00 67.68 N +ATOM 5997 CA CYS A 382 -28.214 -45.767 44.942 1.00 67.99 C +ATOM 5998 C CYS A 382 -29.539 -45.806 44.198 1.00 70.95 C +ATOM 5999 O CYS A 382 -29.714 -45.066 43.225 1.00 71.39 O +ATOM 6000 CB CYS A 382 -27.108 -46.352 44.065 1.00 64.20 C +ATOM 6001 SG CYS A 382 -25.468 -46.264 44.825 1.00 69.28 S +ATOM 6002 H CYS A 382 -27.770 -47.333 46.326 1.00 20.00 H +ATOM 6003 HA CYS A 382 -27.967 -44.713 45.134 1.00 20.00 H +ATOM 6004 HB2 CYS A 382 -27.343 -47.408 43.864 1.00 20.00 H +ATOM 6005 HB3 CYS A 382 -27.083 -45.795 43.117 1.00 20.00 H +ATOM 6006 N GLY A 383 -30.471 -46.653 44.628 1.00 73.16 N +ATOM 6007 CA GLY A 383 -31.746 -46.753 43.940 1.00 71.32 C +ATOM 6008 C GLY A 383 -32.705 -45.665 44.398 1.00 76.28 C +ATOM 6009 O GLY A 383 -32.873 -45.430 45.597 1.00 75.43 O +ATOM 6010 H GLY A 383 -30.292 -47.224 45.429 1.00 20.00 H +ATOM 6011 HA2 GLY A 383 -31.579 -46.651 42.858 1.00 20.00 H +ATOM 6012 HA3 GLY A 383 -32.192 -47.736 44.151 1.00 20.00 H +ATOM 6013 N TYR A 384 -33.357 -45.016 43.437 1.00 81.46 N +ATOM 6014 CA TYR A 384 -34.386 -44.035 43.766 1.00 84.09 C +ATOM 6015 C TYR A 384 -35.623 -44.792 44.224 1.00 81.17 C +ATOM 6016 O TYR A 384 -36.384 -45.320 43.412 1.00 75.34 O +ATOM 6017 CB TYR A 384 -34.687 -43.141 42.571 1.00 86.26 C +ATOM 6018 CG TYR A 384 -35.716 -42.086 42.890 1.00 89.03 C +ATOM 6019 CD1 TYR A 384 -35.429 -41.056 43.775 1.00 92.14 C +ATOM 6020 CD2 TYR A 384 -36.974 -42.122 42.315 1.00 88.82 C +ATOM 6021 CE1 TYR A 384 -36.367 -40.090 44.075 1.00 96.00 C +ATOM 6022 CE2 TYR A 384 -37.920 -41.161 42.606 1.00 91.13 C +ATOM 6023 CZ TYR A 384 -37.611 -40.146 43.488 1.00 94.49 C +ATOM 6024 OH TYR A 384 -38.544 -39.184 43.786 1.00 98.58 O +ATOM 6025 H TYR A 384 -33.140 -45.202 42.479 1.00 20.00 H +ATOM 6026 HA TYR A 384 -34.035 -43.403 44.596 1.00 20.00 H +ATOM 6027 HB2 TYR A 384 -33.757 -42.645 42.258 1.00 20.00 H +ATOM 6028 HB3 TYR A 384 -35.064 -43.766 41.748 1.00 20.00 H +ATOM 6029 HD1 TYR A 384 -34.454 -41.010 44.237 1.00 20.00 H +ATOM 6030 HD2 TYR A 384 -37.220 -42.917 41.626 1.00 20.00 H +ATOM 6031 HE1 TYR A 384 -36.127 -39.295 44.766 1.00 20.00 H +ATOM 6032 HE2 TYR A 384 -38.896 -41.203 42.146 1.00 20.00 H +ATOM 6033 HH TYR A 384 -38.415 -38.883 44.678 1.00 20.00 H +ATOM 6034 N ASN A 385 -35.826 -44.841 45.533 1.00 86.52 N +ATOM 6035 CA ASN A 385 -36.824 -45.713 46.134 1.00 88.18 C +ATOM 6036 C ASN A 385 -38.248 -45.275 45.812 1.00 88.96 C +ATOM 6037 O ASN A 385 -38.868 -45.804 44.877 1.00 91.58 O +ATOM 6038 CB ASN A 385 -36.601 -45.773 47.645 1.00 86.85 C +ATOM 6039 CG ASN A 385 -35.171 -46.142 47.997 1.00 86.88 C +ATOM 6040 OD1 ASN A 385 -34.762 -47.294 47.847 1.00 89.16 O +ATOM 6041 ND2 ASN A 385 -34.400 -45.162 48.454 1.00 90.91 N +ATOM 6042 OXT ASN A 385 -38.841 -44.300 46.553 0.00 99.99 O +ATOM 6043 H ASN A 385 -35.274 -44.258 46.129 1.00 20.00 H +ATOM 6044 HA ASN A 385 -36.688 -46.729 45.736 1.00 20.00 H +ATOM 6045 HB2 ASN A 385 -36.829 -44.787 48.077 1.00 20.00 H +ATOM 6046 HB3 ASN A 385 -37.278 -46.527 48.074 1.00 20.00 H +ATOM 6047 HD21 ASN A 385 -33.446 -45.346 48.692 1.00 20.00 H +ATOM 6048 HD22 ASN A 385 -34.773 -44.240 48.560 1.00 20.00 H +TER +ENDMDL diff --git a/openfe/tests/data/openmm_septop/bace1.sdf b/openfe/tests/data/openmm_septop/bace1.sdf new file mode 100755 index 000000000..9d4510e89 --- /dev/null +++ b/openfe/tests/data/openmm_septop/bace1.sdf @@ -0,0 +1,1919 @@ +lig_02 + -OEChem-01092314203D + + 37 39 0 1 0 0 0 0 0999 V2000 + -38.0090 -45.6315 19.1393 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9692 -45.1638 17.2217 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2004 -46.0152 17.8190 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7492 -44.0607 16.6787 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.6155 -44.8304 16.6899 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.6132 -45.2875 17.8281 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.2008 -45.1247 17.4552 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3683 -45.7328 19.5198 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6278 -45.0833 16.8841 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.3241 -45.4655 18.5293 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8478 -46.5876 22.5205 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9995 -44.7608 21.7798 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.7192 -44.0071 22.0925 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.7803 -46.0487 20.9633 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.0746 -46.8925 21.0561 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.9031 -45.8991 17.4539 N 0 0 0 0 0 0 0 0 0 0 0 0 + -34.4728 -43.8844 16.2757 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.7506 -46.9116 21.5963 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.0324 -47.5182 23.0029 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.3177 -44.8022 15.6093 F 0 0 0 0 0 0 0 0 0 0 0 0 + -41.6313 -45.4746 18.8190 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.6579 -44.9875 23.1728 S 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2332 -45.7867 19.8872 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.7339 -44.9813 16.4745 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4136 -46.8925 18.4228 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4263 -43.2813 16.3387 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.5860 -44.7195 16.3733 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5093 -44.9964 22.7248 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6767 -44.0894 21.2351 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1722 -43.7361 21.1858 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9602 -43.0733 22.6095 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2025 -47.2948 22.0687 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0496 -47.7469 20.3704 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9727 -46.3045 20.8405 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.7379 -47.8855 21.3012 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.0923 -48.4785 22.6827 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3461 -47.2767 23.7080 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 6 2 0 0 0 0 + 1 8 1 0 0 0 0 + 2 9 2 0 0 0 0 + 2 10 1 0 0 0 0 + 3 7 2 0 0 0 0 + 3 16 1 0 0 0 0 + 4 7 1 0 0 0 0 + 4 17 2 0 0 0 0 + 5 16 2 0 0 0 0 + 5 17 1 0 0 0 0 + 6 7 1 0 0 0 0 + 6 9 1 0 0 0 0 + 8 10 2 0 0 0 0 + 8 14 1 0 0 0 0 + 9 20 1 0 0 0 0 + 10 21 1 0 0 0 0 + 11 18 2 0 0 0 0 + 11 19 1 0 0 0 0 + 11 22 1 0 0 0 0 + 12 13 1 0 0 0 0 + 12 14 1 0 0 0 0 + 13 22 1 0 0 0 0 + 14 15 1 0 0 0 0 + 14 18 1 0 0 0 0 + 1 23 1 0 0 0 0 + 2 24 1 0 0 0 0 + 3 25 1 0 0 0 0 + 4 26 1 0 0 0 0 + 5 27 1 0 0 0 0 + 12 28 1 0 0 0 0 + 12 29 1 0 0 0 0 + 13 30 1 0 0 0 0 + 13 31 1 0 0 0 0 + 15 32 1 0 0 0 0 + 15 33 1 0 0 0 0 + 15 34 1 0 0 0 0 + 18 35 1 0 0 0 0 + 19 36 1 0 0 0 0 + 19 37 1 0 0 0 0 +M CHG 1 18 1 +M END + +> +6.62 + +> +10.1016/j.bmcl.2014.03.025 + +$$$$ +lig_03 + -OEChem-01092314203D + + 46 48 0 1 0 0 0 0 0999 V2000 + -40.2894 -45.1922 17.1437 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.8755 -43.5891 16.1635 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9570 -45.0093 16.7949 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.1870 -43.8214 16.5751 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6231 -45.6070 18.4292 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.8677 -44.4732 16.5294 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2912 -45.6509 19.0219 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4859 -45.8276 17.7124 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9293 -45.2091 17.7295 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5239 -44.9494 17.3479 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6354 -45.8804 19.3886 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.1639 -45.5934 17.3089 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1002 -44.3596 22.0710 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0437 -46.6125 22.3411 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.3449 -45.0979 21.6611 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0369 -46.3315 20.8006 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.2885 -47.2376 20.8042 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.1106 -44.6010 23.5395 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.3289 -47.5216 18.4188 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0880 -45.2300 22.6328 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9426 -47.1431 21.4084 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1105 -47.4728 22.9155 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9970 -43.1406 22.0100 O 0 0 0 0 0 0 0 0 0 0 0 0 + -33.0853 -46.3852 17.6003 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0705 -45.0057 16.4133 H 0 0 0 0 0 0 0 0 0 0 0 0 + -34.6443 -42.7210 15.5535 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.7301 -44.7001 15.7770 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.9496 -43.1044 16.2770 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.6775 -45.7047 18.6673 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.8488 -44.2845 16.2005 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5047 -45.7946 19.7601 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7323 -46.7091 18.2989 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8384 -45.3941 22.5962 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0197 -44.4036 21.1470 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4478 -47.6654 21.8018 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1729 -48.0777 20.1104 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.2018 -46.6939 20.5409 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6816 -45.3260 24.2321 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3260 -44.1288 22.9446 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.6224 -43.8468 24.1467 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.3727 -48.0301 18.5710 H 0 0 0 0 0 0 0 0 0 0 0 0 + -34.0058 -48.2259 17.9242 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.7103 -47.2260 19.4018 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8631 -48.1311 21.1746 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4025 -47.1613 23.5726 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.1131 -48.4642 22.6858 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 3 2 0 0 0 0 + 1 5 1 0 0 0 0 + 2 4 2 0 0 0 0 + 2 6 1 0 0 0 0 + 3 9 1 0 0 0 0 + 4 10 1 0 0 0 0 + 5 11 2 0 0 0 0 + 6 12 2 0 0 0 0 + 7 9 2 0 0 0 0 + 7 11 1 0 0 0 0 + 8 10 2 0 0 0 0 + 8 12 1 0 0 0 0 + 9 10 1 0 0 0 0 + 11 16 1 0 0 0 0 + 12 24 1 0 0 0 0 + 13 15 1 0 0 0 0 + 13 20 1 0 0 0 0 + 13 23 2 0 0 0 0 + 14 20 1 0 0 0 0 + 14 21 2 0 0 0 0 + 14 22 1 0 0 0 0 + 15 16 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 21 1 0 0 0 0 + 18 20 1 0 0 0 0 + 19 24 1 0 0 0 0 + 1 25 1 0 0 0 0 + 2 26 1 0 0 0 0 + 3 27 1 0 0 0 0 + 4 28 1 0 0 0 0 + 5 29 1 0 0 0 0 + 6 30 1 0 0 0 0 + 7 31 1 0 0 0 0 + 8 32 1 0 0 0 0 + 15 33 1 0 0 0 0 + 15 34 1 0 0 0 0 + 17 35 1 0 0 0 0 + 17 36 1 0 0 0 0 + 17 37 1 0 0 0 0 + 18 38 1 0 0 0 0 + 18 39 1 0 0 0 0 + 18 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 19 42 1 0 0 0 0 + 19 43 1 0 0 0 0 + 21 44 1 0 0 0 0 + 22 45 1 0 0 0 0 + 22 46 1 0 0 0 0 +M CHG 1 21 1 +M END + +> +6.57 + +> +10.1021/ml3001165 + +$$$$ +lig_04 + -OEChem-01092314203D + + 45 48 0 1 0 0 0 0 0999 V2000 + -40.0554 -44.9369 16.8653 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6879 -44.9360 16.5904 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5143 -45.3373 18.1202 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.8835 -44.2396 20.7233 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2382 -45.7361 18.8253 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.5043 -46.2378 17.9050 C 0 0 0 0 0 0 0 0 0 0 0 0 + -42.1548 -43.4338 21.8456 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.8128 -44.4326 16.3875 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.6967 -45.2709 16.6992 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.7793 -45.3356 17.5704 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3607 -45.3345 17.2854 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6057 -45.7369 19.1002 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.1453 -46.2120 17.6119 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8581 -45.0688 21.1270 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6541 -46.1701 22.5163 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6206 -45.3486 23.2769 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0989 -46.1665 20.4463 C 0 0 1 0 0 0 0 0 0 0 0 0 + -40.9476 -47.4293 20.3138 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.9070 -46.9824 17.8402 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.4982 -44.3773 16.0773 N 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3734 -43.7244 22.8891 N 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5995 -44.7181 22.4193 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8949 -46.5220 21.2540 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.5592 -46.5307 23.1735 N 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2865 -47.0805 18.2005 O 0 0 0 0 0 0 0 0 0 0 0 0 + -40.7628 -44.6260 16.1019 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.3457 -44.6209 15.6073 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.5816 -45.3348 18.3259 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.3653 -44.2230 19.7566 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5348 -46.0493 19.5941 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.8873 -46.9646 18.6179 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.8913 -42.6498 21.9472 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4274 -43.7013 15.8702 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.6463 -45.2054 16.4332 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1715 -45.9692 23.9916 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1024 -44.5489 23.8183 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3046 -47.7389 21.2947 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.3510 -48.2313 19.8820 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.8025 -47.2336 19.6685 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.3329 -47.7359 18.3850 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.5369 -45.9826 18.0808 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.8068 -47.1573 16.7664 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1812 -47.0979 20.8139 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4206 -46.2456 24.1379 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8486 -47.0954 22.7189 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 3 1 0 0 0 0 + 2 10 1 0 0 0 0 + 3 12 2 0 0 0 0 + 4 7 1 0 0 0 0 + 4 14 2 0 0 0 0 + 5 10 2 0 0 0 0 + 5 12 1 0 0 0 0 + 6 11 2 0 0 0 0 + 6 13 1 0 0 0 0 + 7 21 2 0 0 0 0 + 8 11 1 0 0 0 0 + 8 20 2 0 0 0 0 + 9 13 2 0 0 0 0 + 9 20 1 0 0 0 0 + 10 11 1 0 0 0 0 + 12 17 1 0 0 0 0 + 13 25 1 0 0 0 0 + 14 17 1 0 0 0 0 + 14 22 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 23 2 0 0 0 0 + 15 24 1 0 0 0 0 + 16 22 1 0 0 0 0 + 17 18 1 0 0 0 0 + 17 23 1 0 0 0 0 + 19 25 1 0 0 0 0 + 21 22 1 0 0 0 0 + 1 26 1 0 0 0 0 + 2 27 1 0 0 0 0 + 3 28 1 0 0 0 0 + 4 29 1 0 0 0 0 + 5 30 1 0 0 0 0 + 6 31 1 0 0 0 0 + 7 32 1 0 0 0 0 + 8 33 1 0 0 0 0 + 9 34 1 0 0 0 0 + 16 35 1 0 0 0 0 + 16 36 1 0 0 0 0 + 18 37 1 0 0 0 0 + 18 38 1 0 0 0 0 + 18 39 1 0 0 0 0 + 19 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 19 42 1 0 0 0 0 + 23 43 1 0 0 0 0 + 24 44 1 0 0 0 0 + 24 45 1 0 0 0 0 +M CHG 1 23 1 +M END + +> +6.96 + +> +4,7-Dihydropyrazolo[1,5-a]pyrazin-6-yl-amine derivatives as β-secretase inhibitors and their preparation and use for the treatment of diseases by: Trabanco-Suarez, Andres Avelino; Tresadern, Gary John; Delgado-Jimenez, FranciscaWorld Intellectual Property Organization, WO2012038438 A1 2012-03-29 | Language: English, Database: CAplus + +$$$$ +lig_05 + -OEChem-01092314203D + + 39 41 0 1 0 0 0 0 0999 V2000 + -40.2181 -45.1963 17.2016 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8778 -45.0934 16.8387 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5708 -45.4986 18.5168 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2434 -45.5906 19.1072 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.9933 -44.0766 16.6239 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4865 -46.0919 17.8440 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.7112 -44.8910 16.7092 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8618 -45.2818 17.7857 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4396 -45.1507 17.4150 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5924 -45.7182 19.4967 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.6452 -43.9548 16.2770 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.1401 -45.9569 17.4940 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0378 -46.6230 22.4156 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9699 -45.2314 22.9120 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9744 -44.7401 21.7887 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9644 -46.0257 20.9503 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.3198 -46.7392 21.1008 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9636 -46.9617 21.5216 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1520 -47.4731 22.9162 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6346 -44.3200 22.0359 O 0 0 0 0 0 0 0 0 0 0 0 0 + -34.1345 -42.6300 15.3050 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9985 -47.1237 18.0388 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -40.9924 -45.0365 16.4568 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6378 -44.8633 15.8029 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.6286 -45.5509 18.7554 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4620 -45.7157 19.8544 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7003 -43.3221 16.2825 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7962 -46.9421 18.4497 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.6633 -44.7912 16.4383 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.4137 -45.1594 23.9116 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.9279 -44.9028 22.9859 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4939 -43.9282 21.2673 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4816 -44.8828 22.7514 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4710 -47.0713 22.1351 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3715 -47.6323 20.4672 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.1610 -46.0864 20.8446 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9629 -47.9314 21.2161 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4668 -47.1726 23.6007 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.1483 -48.4436 22.6228 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 3 1 0 0 0 0 + 2 8 1 0 0 0 0 + 3 10 2 0 0 0 0 + 4 8 2 0 0 0 0 + 4 10 1 0 0 0 0 + 5 9 2 0 0 0 0 + 5 11 1 0 0 0 0 + 6 9 1 0 0 0 0 + 6 12 2 0 0 0 0 + 7 11 2 0 0 0 0 + 7 12 1 0 0 0 0 + 8 9 1 0 0 0 0 + 10 16 1 0 0 0 0 + 11 21 1 0 0 0 0 + 12 22 1 0 0 0 0 + 13 14 1 0 0 0 0 + 13 18 2 0 0 0 0 + 13 19 1 0 0 0 0 + 14 20 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 20 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 18 1 0 0 0 0 + 1 23 1 0 0 0 0 + 2 24 1 0 0 0 0 + 3 25 1 0 0 0 0 + 4 26 1 0 0 0 0 + 5 27 1 0 0 0 0 + 6 28 1 0 0 0 0 + 7 29 1 0 0 0 0 + 14 30 1 0 0 0 0 + 14 31 1 0 0 0 0 + 15 32 1 0 0 0 0 + 15 33 1 0 0 0 0 + 17 34 1 0 0 0 0 + 17 35 1 0 0 0 0 + 17 36 1 0 0 0 0 + 18 37 1 0 0 0 0 + 19 38 1 0 0 0 0 + 19 39 1 0 0 0 0 +M CHG 1 18 1 +M END + +> +5.95 + +> +Preparation of 5,6-dihydro-2H-[1,4]oxazin-3-yl-amine derivatives useful as therapeutic inhibitors of β-secretase (BACE) By: Trabanco-Suarez, Andres Avelino; Rombouts, Frederik Jan Rita; Tresadern, Gary John; Van Gool, Michiel Luc Maria; Macdonald, Gregor James; Martinez Lamenca, Carolina; Gijsen, Henricus Jacobus MariaWorld Intellectual Property Organization, WO2011154431 A1 2011-12-15 | Language: English, Database: CAplus + +$$$$ +lig_06 + -OEChem-01092314203D + + 42 45 0 1 0 0 0 0 0999 V2000 + -40.1582 -45.2247 17.3301 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8476 -45.0908 16.8719 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4148 -45.5005 18.6747 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0695 -43.4695 21.8948 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0475 -45.5261 19.0957 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.9935 -43.9743 16.5045 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.3738 -45.9720 17.7035 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.6773 -44.6924 16.5416 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1683 -43.0249 22.8811 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.7656 -45.2353 17.7493 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3726 -45.0662 17.3035 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3631 -45.6557 19.5850 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.6591 -43.7948 16.1324 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.0436 -45.7796 17.3281 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9489 -44.8434 21.9051 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0031 -47.4752 22.3314 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.6222 -46.4306 23.3018 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5657 -45.9324 21.0767 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.0298 -46.1329 21.5004 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5357 -44.0289 23.4917 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0401 -45.1146 22.8842 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8828 -47.2312 21.3602 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.4123 -48.6490 22.5098 N 0 0 0 0 0 0 0 0 0 0 0 0 + -34.2217 -42.4379 15.1689 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -32.8446 -46.8946 17.8559 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -40.9850 -45.1068 16.6352 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6846 -44.8741 15.8185 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4516 -45.5836 18.9854 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.7000 -42.8763 21.2486 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2189 -45.6312 19.7964 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7385 -43.2462 16.1884 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6344 -46.8326 18.3176 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.6397 -44.5444 16.2548 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9431 -42.0122 23.1803 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0888 -46.6234 24.2737 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5336 -46.4012 23.4256 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1022 -46.3779 22.5665 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4949 -46.9610 20.9521 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.6316 -45.2318 21.3323 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0948 -48.0176 20.7508 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7472 -48.7827 23.2641 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.6101 -49.4276 21.8925 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 3 1 0 0 0 0 + 2 10 1 0 0 0 0 + 3 12 2 0 0 0 0 + 4 9 1 0 0 0 0 + 4 15 2 0 0 0 0 + 5 10 2 0 0 0 0 + 5 12 1 0 0 0 0 + 6 11 2 0 0 0 0 + 6 13 1 0 0 0 0 + 7 11 1 0 0 0 0 + 7 14 2 0 0 0 0 + 8 13 2 0 0 0 0 + 8 14 1 0 0 0 0 + 9 20 2 0 0 0 0 + 10 11 1 0 0 0 0 + 12 18 1 0 0 0 0 + 13 24 1 0 0 0 0 + 14 25 1 0 0 0 0 + 15 18 1 0 0 0 0 + 15 21 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 22 2 0 0 0 0 + 16 23 1 0 0 0 0 + 17 21 1 0 0 0 0 + 18 19 1 0 0 0 0 + 18 22 1 0 0 0 0 + 20 21 1 0 0 0 0 + 1 26 1 0 0 0 0 + 2 27 1 0 0 0 0 + 3 28 1 0 0 0 0 + 4 29 1 0 0 0 0 + 5 30 1 0 0 0 0 + 6 31 1 0 0 0 0 + 7 32 1 0 0 0 0 + 8 33 1 0 0 0 0 + 9 34 1 0 0 0 0 + 17 35 1 0 0 0 0 + 17 36 1 0 0 0 0 + 19 37 1 0 0 0 0 + 19 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 22 40 1 0 0 0 0 + 23 41 1 0 0 0 0 + 23 42 1 0 0 0 0 +M CHG 1 22 1 +M END + +> +6.83 + +> +4,7-Dihydropyrazolo[1,5-a]pyrazin-6-yl-amine derivatives as β-secretase inhibitors and their preparation and use for the treatment of diseases by: Trabanco-Suarez, Andres Avelino; Tresadern, Gary John; Delgado-Jimenez, Francisca^?World Intellectual Property Organization, WO2012038438 A1 2012-03-29 | Language: English, Database: CAplus + +$$$$ +lig_07 + -OEChem-01092314203D + + 42 45 0 1 0 0 0 0 0999 V2000 + -40.1853 -45.2236 17.1561 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8417 -45.1130 16.8105 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5502 -45.5374 18.4642 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2297 -45.6216 19.0844 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.9620 -44.0919 16.6242 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4608 -46.1044 17.8512 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.6802 -44.9041 16.7249 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.0778 -43.7889 23.6837 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1753 -43.3854 22.9550 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8361 -45.3033 17.7689 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4116 -45.1659 17.4132 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5815 -45.7580 19.4543 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.6123 -43.9694 16.2856 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.1130 -45.9688 17.5090 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8508 -45.5605 22.8009 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0693 -46.9005 22.3437 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9150 -44.7397 21.7307 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9669 -46.0516 20.9058 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.3726 -46.6701 21.0588 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8800 -45.1459 23.5836 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6705 -44.5382 22.4340 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0464 -47.1015 21.4574 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.2773 -47.8522 22.8168 N 0 0 0 0 0 0 0 0 0 0 0 0 + -34.0980 -42.6468 15.3130 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9756 -47.1360 18.0609 Cl 0 0 0 0 0 0 0 0 0 0 0 0 + -40.9522 -45.0593 16.4048 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.5911 -44.8754 15.7789 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.6107 -45.5921 18.6898 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4584 -45.7453 19.8419 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6678 -43.3394 16.2764 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7737 -46.9540 18.4559 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.6311 -44.8044 16.4592 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4222 -43.1717 24.2795 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6360 -42.4214 22.7956 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0970 -43.8560 21.1068 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6803 -44.7464 22.5168 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.5396 -46.9939 22.0935 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4909 -47.5555 20.4233 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.1663 -45.9576 20.8102 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1630 -48.0587 21.1347 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5485 -47.6376 23.4895 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3883 -48.8136 22.5159 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 3 1 0 0 0 0 + 2 10 1 0 0 0 0 + 3 12 2 0 0 0 0 + 4 10 2 0 0 0 0 + 4 12 1 0 0 0 0 + 5 11 2 0 0 0 0 + 5 13 1 0 0 0 0 + 6 11 1 0 0 0 0 + 6 14 2 0 0 0 0 + 7 13 2 0 0 0 0 + 7 14 1 0 0 0 0 + 8 9 2 0 0 0 0 + 8 20 1 0 0 0 0 + 9 21 1 0 0 0 0 + 10 11 1 0 0 0 0 + 12 18 1 0 0 0 0 + 13 24 1 0 0 0 0 + 14 25 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 20 2 0 0 0 0 + 15 21 1 0 0 0 0 + 16 22 2 0 0 0 0 + 16 23 1 0 0 0 0 + 17 18 1 0 0 0 0 + 17 21 1 0 0 0 0 + 18 19 1 0 0 0 0 + 18 22 1 0 0 0 0 + 1 26 1 0 0 0 0 + 2 27 1 0 0 0 0 + 3 28 1 0 0 0 0 + 4 29 1 0 0 0 0 + 5 30 1 0 0 0 0 + 6 31 1 0 0 0 0 + 7 32 1 0 0 0 0 + 8 33 1 0 0 0 0 + 9 34 1 0 0 0 0 + 17 35 1 0 0 0 0 + 17 36 1 0 0 0 0 + 19 37 1 0 0 0 0 + 19 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 22 40 1 0 0 0 0 + 23 41 1 0 0 0 0 + 23 42 1 0 0 0 0 +M CHG 1 22 1 +M END + +> +5.67 + +> +Preparation of 5,6-dihydro-imidazo[1,2-a]pyrazin-8-ylamine derivatives as beta-secretase inhibitors By: Trabanco-Suarez, Andres Avelino; Delgado-Jimenez, Francisca; Vega Ramiro, Juan Antonio; Tresadern, Gary John; Gijsen, Henricus Jacobus Maria; Oehlrich, DanielWorld Intellectual Property Organization, WO2012085038 A1 2012-06-28 + +$$$$ +lig_11 + -OEChem-01092314203D + + 47 50 0 1 0 0 0 0 0999 V2000 + -34.2682 -44.3482 16.0497 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.4070 -45.0810 17.2283 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.3941 -43.8099 15.4264 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6717 -45.2757 17.7837 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6587 -44.0046 15.9817 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2297 -44.9930 16.9141 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4897 -45.1962 17.4719 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2505 -45.0769 19.1185 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7975 -44.7375 17.1604 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1091 -44.9395 17.7369 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5158 -45.2685 19.6992 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6319 -45.3496 18.8552 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9160 -44.2713 21.9588 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9818 -46.2798 22.6098 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1401 -45.3790 21.6194 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6728 -45.3888 21.1918 C 0 0 1 0 0 0 0 0 0 0 0 0 + -42.0563 -46.1036 20.6195 C 0 0 0 0 0 0 0 0 0 0 0 0 + -43.5180 -45.8439 21.0202 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.8376 -47.6230 20.5740 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.0447 -44.1736 23.6727 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9335 -44.9184 22.7887 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9715 -46.6070 21.6804 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1892 -47.2122 23.2297 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1039 -43.0681 21.8770 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9123 -45.5627 19.2947 O 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2833 -44.1952 15.6184 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.5304 -45.4987 17.7146 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2866 -43.2380 14.5094 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7633 -45.8492 18.7031 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5271 -43.5785 15.4850 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1382 -44.8833 15.8362 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3595 -45.2460 16.8218 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3680 -45.0303 19.7543 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2514 -45.8035 22.6256 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4736 -44.3332 21.6868 H 0 0 0 0 0 0 0 0 0 0 0 0 + -44.1766 -46.3502 20.3219 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7121 -44.7765 20.9963 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.6877 -46.2235 22.0227 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.5161 -48.0636 19.8496 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0309 -48.0447 21.5559 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8119 -47.8313 20.2846 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5171 -44.0627 24.6599 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0945 -44.7174 23.7801 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8515 -43.1788 23.2450 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1602 -47.5668 21.4033 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5059 -46.8927 23.8758 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3295 -48.1701 23.0082 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 3 1 0 0 0 0 + 2 4 1 0 0 0 0 + 3 5 2 0 0 0 0 + 4 9 2 0 0 0 0 + 5 9 1 0 0 0 0 + 6 7 2 0 0 0 0 + 6 10 1 0 0 0 0 + 7 12 1 0 0 0 0 + 8 10 2 0 0 0 0 + 8 11 1 0 0 0 0 + 9 10 1 0 0 0 0 + 11 12 2 0 0 0 0 + 11 16 1 0 0 0 0 + 12 25 1 0 0 0 0 + 13 16 1 0 0 0 0 + 13 21 1 0 0 0 0 + 13 24 2 0 0 0 0 + 14 21 1 0 0 0 0 + 14 22 2 0 0 0 0 + 14 23 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 17 1 0 0 0 0 + 16 22 1 0 0 0 0 + 17 18 1 0 0 0 0 + 17 19 1 0 0 0 0 + 17 25 1 0 0 0 0 + 20 21 1 0 0 0 0 + 1 26 1 0 0 0 0 + 2 27 1 0 0 0 0 + 3 28 1 0 0 0 0 + 4 29 1 0 0 0 0 + 5 30 1 0 0 0 0 + 6 31 1 0 0 0 0 + 7 32 1 0 0 0 0 + 8 33 1 0 0 0 0 + 15 34 1 0 0 0 0 + 15 35 1 0 0 0 0 + 18 36 1 0 0 0 0 + 18 37 1 0 0 0 0 + 18 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 19 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 20 42 1 0 0 0 0 + 20 43 1 0 0 0 0 + 20 44 1 0 0 0 0 + 22 45 1 0 0 0 0 + 23 46 1 0 0 0 0 + 23 47 1 0 0 0 0 +M CHG 1 22 1 +M END + +> +455 + +> +10.1021/jm4002154 + +$$$$ +lig_13 + -OEChem-01092314203D + + 48 51 0 1 0 0 0 0 0999 V2000 + -33.2652 -45.8563 17.7205 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.3048 -43.5774 15.6028 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.2044 -44.2521 16.1255 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5843 -43.8109 16.1158 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2916 -44.9925 16.9342 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5536 -45.1949 17.4992 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6691 -45.4106 17.6625 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.3103 -45.1263 19.1185 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.3860 -45.1685 17.1591 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7949 -44.7298 17.1593 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1393 -44.9556 17.7322 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5741 -45.3226 19.7058 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6942 -45.3723 18.8764 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9089 -44.3599 21.9429 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9597 -46.3841 22.5163 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1683 -45.4225 21.6511 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.7113 -45.4587 21.1987 C 0 0 1 0 0 0 0 0 0 0 0 0 + -42.1196 -46.1030 20.6517 C 0 0 0 0 0 0 0 0 0 0 0 0 + -43.5659 -45.7880 21.0665 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9580 -47.6288 20.5967 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8757 -44.2879 23.4548 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.3619 -46.4147 18.1879 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8740 -45.0239 22.6896 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0202 -46.6925 21.6603 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1414 -47.3306 23.0784 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0907 -43.1545 21.8858 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9721 -45.5649 19.3259 O 0 0 0 0 0 0 0 0 0 0 0 0 + -35.1681 -42.8587 14.7998 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2151 -44.0515 15.7227 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4143 -43.2460 15.6963 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2254 -44.8722 15.8552 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4267 -45.2195 16.8522 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7883 -46.1407 18.4626 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4379 -45.0828 19.7693 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2733 -45.8652 22.6502 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4733 -44.3708 21.7473 H 0 0 0 0 0 0 0 0 0 0 0 0 + -44.2797 -46.2135 20.3518 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7432 -44.7059 21.0662 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7957 -46.1780 22.0636 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.7238 -48.0740 19.9503 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0466 -48.0773 21.5915 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.9999 -47.9272 20.1619 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3716 -43.7540 24.2692 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.1260 -44.9651 23.8687 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3772 -43.5731 22.7933 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2557 -47.6489 21.4089 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3777 -47.0801 23.7001 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2812 -48.3199 22.8878 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 9 1 0 0 0 0 + 1 22 3 0 0 0 0 + 2 3 2 0 0 0 0 + 2 4 1 0 0 0 0 + 3 9 1 0 0 0 0 + 4 10 2 0 0 0 0 + 5 6 2 0 0 0 0 + 5 11 1 0 0 0 0 + 6 13 1 0 0 0 0 + 7 9 2 0 0 0 0 + 7 10 1 0 0 0 0 + 8 11 2 0 0 0 0 + 8 12 1 0 0 0 0 + 10 11 1 0 0 0 0 + 12 13 2 0 0 0 0 + 12 17 1 0 0 0 0 + 13 27 1 0 0 0 0 + 14 17 1 0 0 0 0 + 14 23 1 0 0 0 0 + 14 26 2 0 0 0 0 + 15 23 1 0 0 0 0 + 15 24 2 0 0 0 0 + 15 25 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 18 1 0 0 0 0 + 17 24 1 0 0 0 0 + 18 19 1 0 0 0 0 + 18 20 1 0 0 0 0 + 18 27 1 0 0 0 0 + 21 23 1 0 0 0 0 + 2 28 1 0 0 0 0 + 3 29 1 0 0 0 0 + 4 30 1 0 0 0 0 + 5 31 1 0 0 0 0 + 6 32 1 0 0 0 0 + 7 33 1 0 0 0 0 + 8 34 1 0 0 0 0 + 16 35 1 0 0 0 0 + 16 36 1 0 0 0 0 + 19 37 1 0 0 0 0 + 19 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 20 40 1 0 0 0 0 + 20 41 1 0 0 0 0 + 20 42 1 0 0 0 0 + 21 43 1 0 0 0 0 + 21 44 1 0 0 0 0 + 21 45 1 0 0 0 0 + 24 46 1 0 0 0 0 + 25 47 1 0 0 0 0 + 25 48 1 0 0 0 0 +M CHG 1 24 1 +M END + +> +94 + +> +10.1021/jm4002154 + +$$$$ +lig_16 + -OEChem-01092314203D + + 51 54 0 1 0 0 0 0 0999 V2000 + -39.2331 -44.9942 16.9142 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6629 -44.0057 15.9801 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6745 -45.2767 17.7813 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4927 -45.1974 17.4728 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.3988 -43.8111 15.4237 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.4103 -45.0822 17.2249 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2526 -45.0777 19.1181 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8008 -44.7385 17.1590 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1120 -44.9405 17.7363 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5175 -45.2692 19.6995 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6341 -45.3506 18.8562 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.2725 -44.3493 16.0460 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9165 -44.2717 21.9586 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9817 -46.2800 22.6094 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1407 -45.3796 21.6207 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6736 -45.3894 21.1922 C 0 0 1 0 0 0 0 0 0 0 0 0 + -42.0574 -46.1044 20.6214 C 0 0 0 0 0 0 0 0 0 0 0 0 + -43.5188 -45.8448 21.0229 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.8387 -47.6238 20.5761 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.0441 -44.1736 23.6714 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.9306 -44.7375 16.1904 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9334 -44.9186 22.7880 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9719 -46.6074 21.6806 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1886 -47.2122 23.2290 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1045 -43.0685 21.8767 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9143 -45.5637 19.2965 O 0 0 0 0 0 0 0 0 0 0 0 0 + -33.0393 -44.1598 15.5026 O 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1422 -44.8846 15.8363 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5314 -43.5799 15.4833 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7654 -45.8504 18.7006 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3629 -45.2474 16.8232 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2978 -43.2395 14.5051 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.5364 -45.5040 17.7139 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3697 -45.0309 19.7533 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2514 -45.8039 22.6270 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4742 -44.3338 21.6881 H 0 0 0 0 0 0 0 0 0 0 0 0 + -44.1779 -46.3513 20.3251 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7131 -44.7774 20.9990 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.6880 -46.2242 22.0256 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.5176 -48.0646 19.8521 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0313 -48.0454 21.5581 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8130 -47.8321 20.2860 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.5160 -44.0625 24.6589 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0938 -44.7172 23.7783 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8513 -43.1788 23.2434 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.0079 -44.5111 15.6507 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.0680 -45.8195 16.2609 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.8756 -44.3130 17.1957 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1608 -47.5673 21.4038 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5050 -46.8926 23.8746 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3291 -48.1702 23.0077 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 4 2 0 0 0 0 + 1 9 1 0 0 0 0 + 2 5 2 0 0 0 0 + 2 8 1 0 0 0 0 + 3 6 1 0 0 0 0 + 3 8 2 0 0 0 0 + 4 11 1 0 0 0 0 + 5 12 1 0 0 0 0 + 6 12 2 0 0 0 0 + 7 9 2 0 0 0 0 + 7 10 1 0 0 0 0 + 8 9 1 0 0 0 0 + 10 11 2 0 0 0 0 + 10 16 1 0 0 0 0 + 11 26 1 0 0 0 0 + 12 27 1 0 0 0 0 + 13 16 1 0 0 0 0 + 13 22 1 0 0 0 0 + 13 25 2 0 0 0 0 + 14 22 1 0 0 0 0 + 14 23 2 0 0 0 0 + 14 24 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 17 1 0 0 0 0 + 16 23 1 0 0 0 0 + 17 18 1 0 0 0 0 + 17 19 1 0 0 0 0 + 17 26 1 0 0 0 0 + 20 22 1 0 0 0 0 + 21 27 1 0 0 0 0 + 1 28 1 0 0 0 0 + 2 29 1 0 0 0 0 + 3 30 1 0 0 0 0 + 4 31 1 0 0 0 0 + 5 32 1 0 0 0 0 + 6 33 1 0 0 0 0 + 7 34 1 0 0 0 0 + 15 35 1 0 0 0 0 + 15 36 1 0 0 0 0 + 18 37 1 0 0 0 0 + 18 38 1 0 0 0 0 + 18 39 1 0 0 0 0 + 19 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 19 42 1 0 0 0 0 + 20 43 1 0 0 0 0 + 20 44 1 0 0 0 0 + 20 45 1 0 0 0 0 + 21 46 1 0 0 0 0 + 21 47 1 0 0 0 0 + 21 48 1 0 0 0 0 + 23 49 1 0 0 0 0 + 24 50 1 0 0 0 0 + 24 51 1 0 0 0 0 +M CHG 1 23 1 +M END + +> +7197 + +> +10.1021/jm4002154 + +$$$$ +lig_1a + -OEChem-01092314203D + + 37 39 0 1 0 0 0 0 0999 V2000 + -40.5651 -45.2426 17.4631 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3154 -45.0579 16.8765 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2913 -45.1190 19.0612 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5457 -45.2917 19.6705 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6797 -45.3754 18.8510 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1775 -45.0023 17.6751 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8910 -44.2680 21.9028 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9598 -46.2749 22.5630 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1306 -45.3615 21.6253 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6726 -45.3897 21.1676 C 0 0 1 0 0 0 0 0 0 0 0 0 + -42.0733 -46.0923 20.6549 C 0 0 0 0 0 0 0 0 0 0 0 0 + -43.5241 -45.8148 21.0820 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.8679 -47.6141 20.6266 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.9837 -44.1619 23.5762 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8967 -44.9116 22.7214 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9712 -46.6068 21.6589 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1621 -47.2051 23.1796 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0708 -43.0645 21.8078 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9525 -45.5714 19.3199 O 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4780 -44.7615 16.8844 Br 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4485 -45.2942 16.8316 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2459 -44.9641 15.7961 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3967 -45.0704 19.6788 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2246 -45.7700 22.6398 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4540 -44.3120 21.6836 H 0 0 0 0 0 0 0 0 0 0 0 0 + -44.2014 -46.3253 20.4048 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7102 -44.7461 21.0470 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.6763 -46.1787 22.0932 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.5649 -48.0590 19.9227 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0442 -48.0201 21.6182 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8501 -47.8349 20.3190 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4346 -44.0331 24.5712 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0359 -44.7121 23.6716 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7914 -43.1749 23.1303 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1736 -47.5686 21.3995 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4630 -46.8823 23.8068 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3148 -48.1647 22.9746 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 5 1 0 0 0 0 + 2 6 1 0 0 0 0 + 3 4 1 0 0 0 0 + 3 6 2 0 0 0 0 + 4 5 2 0 0 0 0 + 4 10 1 0 0 0 0 + 5 19 1 0 0 0 0 + 6 20 1 0 0 0 0 + 7 10 1 0 0 0 0 + 7 15 1 0 0 0 0 + 7 18 2 0 0 0 0 + 8 15 1 0 0 0 0 + 8 16 2 0 0 0 0 + 8 17 1 0 0 0 0 + 9 10 1 0 0 0 0 + 9 11 1 0 0 0 0 + 10 16 1 0 0 0 0 + 11 12 1 0 0 0 0 + 11 13 1 0 0 0 0 + 11 19 1 0 0 0 0 + 14 15 1 0 0 0 0 + 1 21 1 0 0 0 0 + 2 22 1 0 0 0 0 + 3 23 1 0 0 0 0 + 9 24 1 0 0 0 0 + 9 25 1 0 0 0 0 + 12 26 1 0 0 0 0 + 12 27 1 0 0 0 0 + 12 28 1 0 0 0 0 + 13 29 1 0 0 0 0 + 13 30 1 0 0 0 0 + 13 31 1 0 0 0 0 + 14 32 1 0 0 0 0 + 14 33 1 0 0 0 0 + 14 34 1 0 0 0 0 + 16 35 1 0 0 0 0 + 17 36 1 0 0 0 0 + 17 37 1 0 0 0 0 +M CHG 1 16 1 +M END + +> +36830 + +> +10.1021/jm4002154 + +$$$$ +lig_32 + -OEChem-01092314203D + + 46 49 0 1 0 0 0 0 0999 V2000 + -34.3135 -45.2077 17.1876 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.1973 -44.2951 16.1500 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1764 -45.0011 16.9541 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4542 -45.1821 17.4918 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.5656 -45.4789 17.7323 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2381 -45.1951 19.1528 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.3543 -43.6914 15.6932 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0382 -45.0149 17.7732 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5193 -45.3544 19.7145 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6249 -45.3728 18.8641 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6860 -44.8194 17.2216 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8939 -44.3714 21.9499 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9558 -46.3933 22.5507 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1544 -45.4253 21.6300 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6895 -45.4757 21.2056 C 0 0 1 0 0 0 0 0 0 0 0 0 + -42.0923 -46.0925 20.6093 C 0 0 0 0 0 0 0 0 0 0 0 0 + -43.5439 -45.7704 21.0003 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9410 -47.6194 20.5506 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8680 -44.2891 23.4685 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5864 -43.9319 16.1983 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8638 -45.0312 22.7065 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0139 -46.7075 21.6935 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1447 -47.3366 23.1280 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0749 -43.1663 21.8840 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9143 -45.5454 19.2901 O 0 0 0 0 0 0 0 0 0 0 0 0 + -33.4324 -45.7079 17.5781 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2326 -44.0649 15.7136 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0846 -44.8594 15.8793 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3151 -45.1774 16.8279 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6446 -46.1977 18.5425 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3767 -45.1829 19.8192 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.3216 -42.9701 14.8835 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2830 -45.8704 22.6252 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4515 -44.3711 21.7241 H 0 0 0 0 0 0 0 0 0 0 0 0 + -44.2483 -46.1902 20.2729 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7158 -44.6876 21.0018 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7926 -46.1628 21.9919 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.6909 -48.0552 19.8797 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0619 -48.0718 21.5404 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.9725 -47.9242 20.1444 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3730 -43.6990 24.2373 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.1567 -44.9674 23.9434 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3255 -43.6246 22.7896 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2564 -47.6658 21.4559 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3797 -47.0817 23.7462 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2893 -48.3276 22.9503 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 5 1 0 0 0 0 + 2 7 1 0 0 0 0 + 3 4 2 0 0 0 0 + 3 8 1 0 0 0 0 + 4 10 1 0 0 0 0 + 5 11 2 0 0 0 0 + 6 8 2 0 0 0 0 + 6 9 1 0 0 0 0 + 7 20 2 0 0 0 0 + 8 11 1 0 0 0 0 + 9 10 2 0 0 0 0 + 9 15 1 0 0 0 0 + 10 25 1 0 0 0 0 + 11 20 1 0 0 0 0 + 12 15 1 0 0 0 0 + 12 21 1 0 0 0 0 + 12 24 2 0 0 0 0 + 13 21 1 0 0 0 0 + 13 22 2 0 0 0 0 + 13 23 1 0 0 0 0 + 14 15 1 0 0 0 0 + 14 16 1 0 0 0 0 + 15 22 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 18 1 0 0 0 0 + 16 25 1 0 0 0 0 + 19 21 1 0 0 0 0 + 1 26 1 0 0 0 0 + 2 27 1 0 0 0 0 + 3 28 1 0 0 0 0 + 4 29 1 0 0 0 0 + 5 30 1 0 0 0 0 + 6 31 1 0 0 0 0 + 7 32 1 0 0 0 0 + 14 33 1 0 0 0 0 + 14 34 1 0 0 0 0 + 17 35 1 0 0 0 0 + 17 36 1 0 0 0 0 + 17 37 1 0 0 0 0 + 18 38 1 0 0 0 0 + 18 39 1 0 0 0 0 + 18 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 19 42 1 0 0 0 0 + 19 43 1 0 0 0 0 + 22 44 1 0 0 0 0 + 23 45 1 0 0 0 0 + 23 46 1 0 0 0 0 +M CHG 1 22 1 +M END + +> +2363 + +> +10.1021/jm4002154 + +$$$$ +lig_36 + -OEChem-01092314203D + + 51 54 0 1 0 0 0 0 0999 V2000 + -33.3279 -45.7707 17.6348 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.3998 -46.3455 18.1337 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3623 -44.9664 16.9291 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6159 -45.1795 17.5073 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.7353 -45.3707 17.6195 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.3573 -45.1090 19.1034 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.3685 -44.1917 16.0671 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6394 -43.8034 16.0925 C 0 0 0 0 0 0 0 0 0 0 0 0 + -34.4709 -45.1099 17.0961 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2034 -44.9303 17.7156 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8686 -44.7049 17.1328 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6121 -45.3134 19.7042 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.7399 -45.3646 18.8857 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9218 -44.3592 21.9394 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9699 -46.3859 22.4991 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1845 -45.4214 21.6644 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.7320 -45.4554 21.1980 C 0 0 1 0 0 0 0 0 0 0 0 0 + -42.1446 -46.1034 20.6742 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.2930 -47.0584 18.7654 C 0 0 0 0 0 0 0 0 0 0 0 0 + -43.5870 -45.7897 21.1020 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9812 -47.6288 20.6169 C 0 0 0 0 0 0 0 0 0 0 0 0 + -36.8845 -44.2944 23.4477 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4271 -43.5344 15.5474 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8820 -45.0264 22.6768 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0361 -46.6906 21.6487 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.1488 -47.3352 23.0523 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1025 -43.1534 21.8874 O 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0120 -45.5655 19.3470 O 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3070 -44.8405 15.8501 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4959 -45.2072 16.8697 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.8328 -46.1007 18.4221 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4775 -45.0666 19.7444 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.4127 -43.9428 15.6166 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4503 -43.2283 15.6535 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2792 -45.8642 22.6644 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4899 -44.3700 21.7632 H 0 0 0 0 0 0 0 0 0 0 0 0 + -30.3321 -46.6732 18.4135 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.3281 -46.9448 19.8531 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.3393 -48.1268 18.5347 H 0 0 0 0 0 0 0 0 0 0 0 0 + -44.3063 -46.2155 20.3930 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.7647 -44.7078 21.1026 H 0 0 0 0 0 0 0 0 0 0 0 0 + -43.8078 -46.1798 22.1009 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.7546 -48.0752 19.9804 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0559 -48.0778 21.6126 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0285 -47.9254 20.1692 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3876 -43.7131 24.2246 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.1744 -44.9792 23.9152 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3408 -43.6226 22.7771 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2740 -47.6464 21.3970 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.3793 -47.0878 23.6680 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2915 -48.3238 22.8598 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 3 0 0 0 0 + 1 9 1 0 0 0 0 + 2 19 1 0 0 0 0 + 3 4 2 0 0 0 0 + 3 10 1 0 0 0 0 + 4 13 1 0 0 0 0 + 5 9 2 0 0 0 0 + 5 11 1 0 0 0 0 + 6 10 2 0 0 0 0 + 6 12 1 0 0 0 0 + 7 9 1 0 0 0 0 + 7 23 2 0 0 0 0 + 8 11 2 0 0 0 0 + 8 23 1 0 0 0 0 + 10 11 1 0 0 0 0 + 12 13 2 0 0 0 0 + 12 17 1 0 0 0 0 + 13 28 1 0 0 0 0 + 14 17 1 0 0 0 0 + 14 24 1 0 0 0 0 + 14 27 2 0 0 0 0 + 15 24 1 0 0 0 0 + 15 25 2 0 0 0 0 + 15 26 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 18 1 0 0 0 0 + 17 25 1 0 0 0 0 + 18 20 1 0 0 0 0 + 18 21 1 0 0 0 0 + 18 28 1 0 0 0 0 + 22 24 1 0 0 0 0 + 3 29 1 0 0 0 0 + 4 30 1 0 0 0 0 + 5 31 1 0 0 0 0 + 6 32 1 0 0 0 0 + 7 33 1 0 0 0 0 + 8 34 1 0 0 0 0 + 16 35 1 0 0 0 0 + 16 36 1 0 0 0 0 + 19 37 1 0 0 0 0 + 19 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 20 40 1 0 0 0 0 + 20 41 1 0 0 0 0 + 20 42 1 0 0 0 0 + 21 43 1 0 0 0 0 + 21 44 1 0 0 0 0 + 21 45 1 0 0 0 0 + 22 46 1 0 0 0 0 + 22 47 1 0 0 0 0 + 22 48 1 0 0 0 0 + 25 49 1 0 0 0 0 + 26 50 1 0 0 0 0 + 26 51 1 0 0 0 0 +M CHG 1 25 1 +M END + +> +10 + +> +10.1021/jm4002154 + +$$$$ +lig_41 + -OEChem-01092314203D + + 46 48 0 1 0 0 0 0 0999 V2000 + -38.2269 -44.7624 17.0644 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5768 -44.5604 17.3339 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9747 -45.7935 19.2369 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.7872 -44.9903 16.2699 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.3168 -46.9590 18.0273 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3311 -45.5899 19.5373 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4150 -45.3730 18.0184 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1109 -44.9604 18.5558 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.8108 -45.5729 16.9887 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.2907 -46.3793 17.3147 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0510 -44.5866 21.6645 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1501 -44.1974 22.5768 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1360 -46.3214 22.6404 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2167 -45.1406 16.8330 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.8976 -45.8944 20.9271 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.2115 -46.6866 20.8698 C 0 0 0 0 0 0 0 0 0 0 0 0 + -28.9955 -46.2409 16.8105 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0969 -42.8186 23.1387 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.5914 -46.5646 17.8782 N 0 0 0 0 0 0 0 0 0 0 0 0 + -31.5065 -45.3848 16.4240 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9577 -46.7625 21.6877 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.2805 -47.1014 23.2819 N 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0320 -45.5918 17.8569 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.5234 -44.4383 15.8785 O 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1330 -45.0306 22.9992 O 0 0 0 0 0 0 0 0 0 0 0 0 + -30.0246 -46.8714 17.5613 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4001 -44.6793 18.7929 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8080 -42.4628 23.4036 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8496 -44.4315 16.1044 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.2096 -44.0702 16.6005 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3159 -46.2480 19.9740 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9477 -44.1873 15.5603 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.1509 -47.7573 18.7400 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8464 -43.9105 21.3610 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.5254 -47.0029 21.8713 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0879 -47.5958 20.2679 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0376 -46.1147 20.4371 H 0 0 0 0 0 0 0 0 0 0 0 0 + -28.0512 -46.7143 17.0942 H 0 0 0 0 0 0 0 0 0 0 0 0 + -28.9272 -45.1748 17.0516 H 0 0 0 0 0 0 0 0 0 0 0 0 + -29.1419 -46.3914 15.7358 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6583 -42.7566 24.0732 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.4899 -42.0818 22.4310 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9129 -47.7558 21.4763 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2235 -48.0917 23.0753 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6741 -46.7092 23.9930 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.5838 -46.1108 18.6096 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 7 1 0 0 0 0 + 2 8 1 0 0 0 0 + 3 6 1 0 0 0 0 + 3 7 2 0 0 0 0 + 4 9 2 0 0 0 0 + 4 20 1 0 0 0 0 + 5 10 1 0 0 0 0 + 5 19 2 0 0 0 0 + 6 8 2 0 0 0 0 + 6 15 1 0 0 0 0 + 7 23 1 0 0 0 0 + 8 27 1 0 0 0 0 + 9 14 1 0 0 0 0 + 9 19 1 0 0 0 0 + 10 20 2 0 0 0 0 + 10 26 1 0 0 0 0 + 11 12 2 0 0 0 0 + 11 15 1 0 0 0 0 + 12 18 1 0 0 0 0 + 12 25 1 0 0 0 0 + 13 21 2 0 0 0 0 + 13 22 1 0 0 0 0 + 13 25 1 0 0 0 0 + 14 23 1 0 0 0 0 + 14 24 2 0 0 0 0 + 15 16 1 0 0 0 0 + 15 21 1 0 0 0 0 + 17 26 1 0 0 0 0 + 18 28 1 0 0 0 0 + 1 29 1 0 0 0 0 + 2 30 1 0 0 0 0 + 3 31 1 0 0 0 0 + 4 32 1 0 0 0 0 + 5 33 1 0 0 0 0 + 11 34 1 0 0 0 0 + 16 35 1 0 0 0 0 + 16 36 1 0 0 0 0 + 16 37 1 0 0 0 0 + 17 38 1 0 0 0 0 + 17 39 1 0 0 0 0 + 17 40 1 0 0 0 0 + 18 41 1 0 0 0 0 + 18 42 1 0 0 0 0 + 21 43 1 0 0 0 0 + 22 44 1 0 0 0 0 + 22 45 1 0 0 0 0 + 23 46 1 0 0 0 0 +M CHG 1 21 1 +M END + +> +6.62 + +> +10.1021/acs.jmedchem.8b00002 + +$$$$ +lig_45 + -OEChem-01092314203D + + 43 45 0 1 0 0 0 0 0999 V2000 + -38.2195 -44.8055 17.0642 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5671 -44.6062 17.3433 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9274 -45.8168 19.2363 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.8326 -44.7993 16.0919 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.2882 -45.6183 19.5460 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3800 -45.3986 18.0108 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0843 -44.9987 18.5703 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.8186 -45.3799 16.8575 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.9738 -46.2686 17.3935 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0155 -44.5986 21.6655 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1273 -44.2021 22.5865 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1011 -46.3206 22.6634 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2295 -45.0628 16.7765 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.8536 -45.9118 20.9393 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.1694 -46.7041 20.8953 C 0 0 0 0 0 0 0 0 0 0 0 0 + -30.8639 -47.0676 17.9426 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0931 -42.8220 23.1470 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2567 -46.3121 17.6985 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9118 -46.7694 21.7052 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.2460 -47.0957 23.3110 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.9846 -45.5803 17.8219 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6415 -44.3664 15.8554 O 0 0 0 0 0 0 0 0 0 0 0 0 + -31.6442 -45.3616 16.4260 O 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1109 -45.0294 23.0224 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3720 -44.7195 18.8185 F 0 0 0 0 0 0 0 0 0 0 0 0 + -29.6731 -46.7122 17.3861 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8091 -42.4454 23.4058 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8708 -44.4795 16.0927 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.2080 -44.1230 16.6125 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2604 -46.2602 19.9725 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.8113 -44.0353 15.3295 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8114 -43.9270 21.3525 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4770 -47.0147 21.9006 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0530 -47.6162 20.2969 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9996 -46.1334 20.4680 H 0 0 0 0 0 0 0 0 0 0 0 0 + -31.0203 -48.1300 17.7385 H 0 0 0 0 0 0 0 0 0 0 0 0 + -30.7824 -46.9210 19.0222 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6519 -42.7678 24.0836 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5018 -42.0916 22.4413 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8603 -47.7628 21.4962 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.1824 -48.0855 23.1030 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6478 -46.7015 24.0276 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4985 -46.0857 18.5602 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 6 1 0 0 0 0 + 2 7 1 0 0 0 0 + 3 5 1 0 0 0 0 + 3 6 2 0 0 0 0 + 4 8 2 0 0 0 0 + 4 23 1 0 0 0 0 + 5 7 2 0 0 0 0 + 5 14 1 0 0 0 0 + 6 21 1 0 0 0 0 + 7 25 1 0 0 0 0 + 8 13 1 0 0 0 0 + 8 18 1 0 0 0 0 + 9 16 1 0 0 0 0 + 9 18 2 0 0 0 0 + 9 23 1 0 0 0 0 + 10 11 2 0 0 0 0 + 10 14 1 0 0 0 0 + 11 17 1 0 0 0 0 + 11 24 1 0 0 0 0 + 12 19 2 0 0 0 0 + 12 20 1 0 0 0 0 + 12 24 1 0 0 0 0 + 13 21 1 0 0 0 0 + 13 22 2 0 0 0 0 + 14 15 1 0 0 0 0 + 14 19 1 0 0 0 0 + 16 26 1 0 0 0 0 + 17 27 1 0 0 0 0 + 1 28 1 0 0 0 0 + 2 29 1 0 0 0 0 + 3 30 1 0 0 0 0 + 4 31 1 0 0 0 0 + 10 32 1 0 0 0 0 + 15 33 1 0 0 0 0 + 15 34 1 0 0 0 0 + 15 35 1 0 0 0 0 + 16 36 1 0 0 0 0 + 16 37 1 0 0 0 0 + 17 38 1 0 0 0 0 + 17 39 1 0 0 0 0 + 19 40 1 0 0 0 0 + 20 41 1 0 0 0 0 + 20 42 1 0 0 0 0 + 21 43 1 0 0 0 0 +M CHG 1 19 1 +M END + +> +7.32 + +> +10.1021/acs.jmedchem.8b00002 + +$$$$ +lig_67 + -OEChem-01092314203D + + 48 50 0 1 0 0 0 0 0999 V2000 + -38.1986 -44.7279 17.0306 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5465 -44.5151 17.3023 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9581 -45.7840 19.1932 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.7541 -44.9904 16.2592 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.3064 -46.9624 18.0197 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3098 -45.5627 19.4988 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3934 -45.3552 17.9797 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.0830 -44.9185 18.5225 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.7860 -45.5696 16.9685 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.2723 -46.3866 17.3159 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1808 -46.3253 22.6421 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.1891 -45.1309 16.8037 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1407 -44.6357 21.6789 C 0 0 1 0 0 0 0 0 0 0 0 0 + -38.8211 -44.1050 22.2297 C 0 0 1 0 0 0 0 0 0 0 0 0 + -39.8943 -45.9153 20.8681 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.1730 -46.7582 20.7373 C 0 0 0 0 0 0 0 0 0 0 0 0 + -28.9721 -46.2585 16.8315 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0243 -42.8457 23.0550 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.5779 -46.5628 17.8595 N 0 0 0 0 0 0 0 0 0 0 0 0 + -31.4764 -45.3906 16.4240 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9439 -46.7526 21.6370 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.3490 -47.1276 23.2894 N 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0123 -45.5842 17.8199 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.4868 -44.4226 15.8509 O 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2113 -45.0641 23.0848 O 0 0 0 0 0 0 0 0 0 0 0 0 + -30.0107 -46.8851 17.5725 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.3731 -44.6411 18.7585 F 0 0 0 0 0 0 0 0 0 0 0 0 + -40.9542 -44.9286 22.7335 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.7991 -42.3847 23.4334 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8179 -44.3943 16.0727 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1765 -44.0186 16.5706 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3060 -46.2595 19.9234 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9054 -44.1858 15.5493 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.1499 -47.7612 18.7340 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.6523 -43.8688 21.0873 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1129 -43.8742 21.4259 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4954 -47.1343 21.7155 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.0033 -47.6329 20.0982 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0081 -46.1916 20.3159 H 0 0 0 0 0 0 0 0 0 0 0 0 + -28.0331 -46.7385 17.1213 H 0 0 0 0 0 0 0 0 0 0 0 0 + -28.8996 -45.1937 17.0765 H 0 0 0 0 0 0 0 0 0 0 0 0 + -29.1109 -46.4050 15.7552 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5953 -43.0404 23.9671 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.5111 -42.0561 22.4760 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.8503 -47.7351 21.3924 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2607 -48.1041 23.0329 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7838 -46.7634 24.0480 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.5706 -46.1117 18.5706 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 7 1 0 0 0 0 + 2 8 1 0 0 0 0 + 3 6 1 0 0 0 0 + 3 7 2 0 0 0 0 + 4 9 2 0 0 0 0 + 4 20 1 0 0 0 0 + 5 10 1 0 0 0 0 + 5 19 2 0 0 0 0 + 6 8 2 0 0 0 0 + 6 15 1 0 0 0 0 + 7 23 1 0 0 0 0 + 8 27 1 0 0 0 0 + 9 12 1 0 0 0 0 + 9 19 1 0 0 0 0 + 10 20 2 0 0 0 0 + 10 26 1 0 0 0 0 + 11 21 2 0 0 0 0 + 11 22 1 0 0 0 0 + 11 25 1 0 0 0 0 + 12 23 1 0 0 0 0 + 12 24 2 0 0 0 0 + 13 14 1 0 0 0 0 + 13 15 1 0 0 0 0 + 13 28 1 0 0 0 0 + 14 18 1 0 0 0 0 + 14 25 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 21 1 0 0 0 0 + 17 26 1 0 0 0 0 + 18 29 1 0 0 0 0 + 1 30 1 0 0 0 0 + 2 31 1 0 0 0 0 + 3 32 1 0 0 0 0 + 4 33 1 0 0 0 0 + 5 34 1 0 0 0 0 + 13 35 1 0 0 0 0 + 14 36 1 0 0 0 0 + 16 37 1 0 0 0 0 + 16 38 1 0 0 0 0 + 16 39 1 0 0 0 0 + 17 40 1 0 0 0 0 + 17 41 1 0 0 0 0 + 17 42 1 0 0 0 0 + 18 43 1 0 0 0 0 + 18 44 1 0 0 0 0 + 21 45 1 0 0 0 0 + 22 46 1 0 0 0 0 + 22 47 1 0 0 0 0 + 23 48 1 0 0 0 0 +M CHG 1 21 1 +M END + +> +7.75 + +> +10.1021/acs.jmedchem.8b00011 + +$$$$ +lig_69 + -OEChem-01092314203D + + 52 55 0 1 0 0 0 0 0999 V2000 + -38.3102 -44.6858 17.0132 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6543 -44.4823 17.3124 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0379 -45.7876 19.1493 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.8431 -44.9774 16.2381 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.4539 -46.9534 18.0133 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3828 -45.5739 19.4848 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4926 -45.3299 17.9379 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1715 -44.9090 18.5352 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.8936 -45.5432 16.9290 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.4018 -46.3907 17.3283 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1702 -46.5120 22.5561 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2912 -45.0907 16.7523 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4340 -42.3260 23.4313 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.3750 -42.8627 24.4674 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.6819 -44.2430 22.2290 C 0 0 1 0 0 0 0 0 0 0 0 0 + -40.0585 -44.6755 21.7274 C 0 0 1 0 0 0 0 0 0 0 0 0 + -39.9257 -45.9426 20.8679 C 0 0 1 0 0 0 0 0 0 0 0 0 + -38.7415 -42.9502 23.0047 C 0 0 0 0 0 0 0 0 0 0 0 0 + -41.2530 -46.7111 20.7766 C 0 0 0 0 0 0 0 0 0 0 0 0 + -29.0941 -46.2999 16.8983 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.7140 -46.5385 17.8251 N 0 0 0 0 0 0 0 0 0 0 0 0 + -31.5744 -45.3943 16.4293 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9901 -46.8592 21.5646 N 0 3 0 0 0 0 0 0 0 0 0 0 + -37.3730 -47.3811 23.1597 N 0 0 0 0 0 0 0 0 0 0 0 0 + -36.1143 -45.5493 17.7646 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.5814 -44.3763 15.8025 O 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1050 -45.2651 23.0312 O 0 0 0 0 0 0 0 0 0 0 0 0 + -30.1553 -46.9065 17.6136 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4551 -44.6275 18.7998 F 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8386 -44.9492 22.8114 F 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6981 -42.0334 22.5719 F 0 0 0 0 0 0 0 0 0 0 0 0 + -27.9596 -46.9310 17.3033 F 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9402 -44.3297 16.0591 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.2964 -43.9702 16.6019 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3717 -46.2734 19.8600 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9706 -44.1717 15.5251 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.3211 -47.7514 18.7333 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3377 -41.2515 23.3392 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5166 -42.8735 23.2494 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0717 -43.7541 25.0016 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9120 -42.1467 25.0768 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0129 -44.0621 21.3798 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.5519 -43.8667 21.1771 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.5447 -47.1055 21.7572 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1621 -47.5695 20.1000 H 0 0 0 0 0 0 0 0 0 0 0 0 + -42.0774 -46.0870 20.4211 H 0 0 0 0 0 0 0 0 0 0 0 0 + -28.9945 -45.2386 17.1470 H 0 0 0 0 0 0 0 0 0 0 0 0 + -29.1950 -46.4519 15.8191 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9594 -47.8349 21.2798 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3526 -48.3548 22.8802 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.7706 -47.0727 23.9146 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6680 -46.0826 18.5089 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 2 0 0 0 0 + 1 7 1 0 0 0 0 + 2 8 1 0 0 0 0 + 3 6 1 0 0 0 0 + 3 7 2 0 0 0 0 + 4 9 2 0 0 0 0 + 4 22 1 0 0 0 0 + 5 10 1 0 0 0 0 + 5 21 2 0 0 0 0 + 6 8 2 0 0 0 0 + 6 17 1 0 0 0 0 + 7 25 1 0 0 0 0 + 8 29 1 0 0 0 0 + 9 12 1 0 0 0 0 + 9 21 1 0 0 0 0 + 10 22 2 0 0 0 0 + 10 28 1 0 0 0 0 + 11 23 2 0 0 0 0 + 11 24 1 0 0 0 0 + 11 27 1 0 0 0 0 + 12 25 1 0 0 0 0 + 12 26 2 0 0 0 0 + 13 14 1 0 0 0 0 + 13 18 1 0 0 0 0 + 14 18 1 0 0 0 0 + 15 16 1 0 0 0 0 + 15 18 1 0 0 0 0 + 15 27 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 30 1 0 0 0 0 + 17 19 1 0 0 0 0 + 17 23 1 0 0 0 0 + 18 31 1 0 0 0 0 + 20 28 1 0 0 0 0 + 20 32 1 0 0 0 0 + 1 33 1 0 0 0 0 + 2 34 1 0 0 0 0 + 3 35 1 0 0 0 0 + 4 36 1 0 0 0 0 + 5 37 1 0 0 0 0 + 13 38 1 0 0 0 0 + 13 39 1 0 0 0 0 + 14 40 1 0 0 0 0 + 14 41 1 0 0 0 0 + 15 42 1 0 0 0 0 + 16 43 1 0 0 0 0 + 19 44 1 0 0 0 0 + 19 45 1 0 0 0 0 + 19 46 1 0 0 0 0 + 20 47 1 0 0 0 0 + 20 48 1 0 0 0 0 + 23 49 1 0 0 0 0 + 24 50 1 0 0 0 0 + 24 51 1 0 0 0 0 + 25 52 1 0 0 0 0 +M CHG 1 23 1 +M END + +> +7.69 + +> +10.1021/acs.jmedchem.8b00011 + +$$$$ +lig_74 + -OEChem-01092314203D + + 45 48 0 1 0 0 0 0 0999 V2000 + -29.8986 -46.6441 17.3497 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.5877 -45.2101 16.2984 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2805 -44.7195 17.1426 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6232 -44.5082 17.4349 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9166 -44.8258 16.1613 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9997 -45.7627 19.3052 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.2706 -46.8151 17.9247 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3803 -43.9268 23.4564 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.2524 -46.2242 17.1916 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3509 -45.5492 19.6316 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4535 -45.3375 18.0800 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1397 -44.9086 18.6638 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1905 -44.8571 22.8522 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.8633 -45.4777 16.9414 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1441 -46.2798 22.6333 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2927 -45.1037 16.8335 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.3902 -44.7179 21.8007 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9335 -45.9673 20.9954 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.1570 -46.8828 20.7721 C 0 0 0 0 0 0 0 0 0 0 0 0 + -28.7980 -46.9875 17.4797 N 0 0 0 0 0 0 0 0 0 0 0 0 + -33.5705 -46.4623 17.8230 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.9661 -42.6859 23.3732 N 0 0 0 0 0 0 0 0 0 0 0 0 + -39.1313 -42.8186 22.7429 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9895 -46.8083 21.7942 N 0 3 0 0 0 0 0 0 0 0 0 0 + -39.2452 -44.1120 22.4346 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2378 -47.0744 23.2955 N 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0706 -45.5588 17.8863 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6499 -44.4284 15.8757 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4333 -44.6519 18.9038 F 0 0 0 0 0 0 0 0 0 0 0 0 + -30.8193 -44.7246 15.7151 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8785 -44.4054 16.1907 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.2656 -44.0332 16.7082 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2035 -44.0462 15.4711 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3624 -46.2679 20.0159 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.0093 -47.6023 18.6164 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.4301 -44.1376 23.9244 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8587 -43.9929 21.1189 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1169 -45.0217 22.5686 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.5740 -47.1821 21.7450 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9213 -46.3394 20.1972 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8473 -47.7791 20.2147 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2261 -48.0612 23.1338 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.5905 -46.6654 23.9387 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6036 -46.1021 18.5839 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0075 -47.8018 21.6815 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 9 1 0 0 0 0 + 1 20 3 0 0 0 0 + 2 5 2 0 0 0 0 + 2 9 1 0 0 0 0 + 3 4 2 0 0 0 0 + 3 11 1 0 0 0 0 + 4 12 1 0 0 0 0 + 5 14 1 0 0 0 0 + 6 10 1 0 0 0 0 + 6 11 2 0 0 0 0 + 7 9 2 0 0 0 0 + 7 21 1 0 0 0 0 + 8 13 2 0 0 0 0 + 8 22 1 0 0 0 0 + 10 12 2 0 0 0 0 + 10 18 1 0 0 0 0 + 11 27 1 0 0 0 0 + 12 29 1 0 0 0 0 + 13 15 1 0 0 0 0 + 13 25 1 0 0 0 0 + 14 16 1 0 0 0 0 + 14 21 2 0 0 0 0 + 15 24 2 0 0 0 0 + 15 26 1 0 0 0 0 + 16 27 1 0 0 0 0 + 16 28 2 0 0 0 0 + 17 18 1 0 0 0 0 + 17 25 1 0 0 0 0 + 18 19 1 0 0 0 0 + 18 24 1 0 0 0 0 + 22 23 2 0 0 0 0 + 23 25 1 0 0 0 0 + 2 30 1 0 0 0 0 + 3 31 1 0 0 0 0 + 4 32 1 0 0 0 0 + 5 33 1 0 0 0 0 + 6 34 1 0 0 0 0 + 7 35 1 0 0 0 0 + 8 36 1 0 0 0 0 + 17 37 1 0 0 0 0 + 17 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 19 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 26 42 1 0 0 0 0 + 26 43 1 0 0 0 0 + 27 44 1 0 0 0 0 + 24 45 1 0 0 0 0 +M CHG 1 24 1 +M END + +> +8.7 + +> +10.1021/acsmedchemlett.9b00181 + +$$$$ +lig_81 + -OEChem-01092314203D + + 45 48 0 1 0 0 0 0 0999 V2000 + -29.8991 -46.6444 17.3498 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.5880 -45.2092 16.2997 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2803 -44.7175 17.1436 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6235 -44.5074 17.4340 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.9168 -44.8244 16.1631 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.0005 -45.7575 19.3081 C 0 0 0 0 0 0 0 0 0 0 0 0 + -32.2711 -46.8151 17.9250 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.0485 -42.8007 22.7748 C 0 0 0 0 0 0 0 0 0 0 0 0 + -31.2529 -46.2240 17.1922 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.3521 -45.5442 19.6329 C 0 0 0 0 0 0 0 0 0 0 0 0 + -37.4536 -45.3336 18.0825 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.1408 -44.9069 18.6628 C 0 0 0 0 0 0 0 0 0 0 0 0 + -33.8636 -45.4764 16.9430 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.2345 -44.8187 22.8526 C 0 0 0 0 0 0 0 0 0 0 0 0 + -38.1576 -46.2394 22.6464 C 0 0 0 0 0 0 0 0 0 0 0 0 + -35.2928 -45.1019 16.8354 C 0 0 0 0 0 0 0 0 0 0 0 0 + -40.4180 -44.7168 21.7933 C 0 0 0 0 0 0 0 0 0 0 0 0 + -39.9371 -45.9630 20.9952 C 0 0 1 0 0 0 0 0 0 0 0 0 + -41.1466 -46.8959 20.7665 C 0 0 0 0 0 0 0 0 0 0 0 0 + -28.7986 -46.9881 17.4796 N 0 0 0 0 0 0 0 0 0 0 0 0 + -33.5710 -46.4617 17.8239 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8875 -42.7445 23.3970 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3729 -44.0340 23.4583 N 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9871 -46.7880 21.8050 N 0 3 0 0 0 0 0 0 0 0 0 0 + -39.2924 -44.0810 22.4313 N 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2387 -47.0061 23.3224 N 0 0 0 0 0 0 0 0 0 0 0 0 + -36.0706 -45.5553 17.8892 N 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6500 -44.4278 15.8767 O 0 0 0 0 0 0 0 0 0 0 0 0 + -41.4358 -44.6547 18.8997 F 0 0 0 0 0 0 0 0 0 0 0 0 + -30.8196 -44.7235 15.7166 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.8775 -44.4039 16.1919 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.2657 -44.0341 16.7060 H 0 0 0 0 0 0 0 0 0 0 0 0 + -33.2036 -44.0443 15.4734 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.3635 -46.2614 20.0200 H 0 0 0 0 0 0 0 0 0 0 0 0 + -32.0099 -47.6030 18.6160 H 0 0 0 0 0 0 0 0 0 0 0 0 + -39.6965 -41.9604 22.5737 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8975 -44.0052 21.1051 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.1423 -45.0309 22.5592 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.5669 -47.1969 21.7374 H 0 0 0 0 0 0 0 0 0 0 0 0 + -41.9138 -46.3651 20.1837 H 0 0 0 0 0 0 0 0 0 0 0 0 + -40.8206 -47.7901 20.2151 H 0 0 0 0 0 0 0 0 0 0 0 0 + -37.2030 -47.9938 23.1702 H 0 0 0 0 0 0 0 0 0 0 0 0 + -36.6059 -46.5762 23.9664 H 0 0 0 0 0 0 0 0 0 0 0 0 + -35.6035 -46.0974 18.5878 H 0 0 0 0 0 0 0 0 0 0 0 0 + -38.9890 -47.7823 21.6980 H 0 0 0 0 0 0 0 0 0 0 0 0 + 1 9 1 0 0 0 0 + 1 20 3 0 0 0 0 + 2 5 2 0 0 0 0 + 2 9 1 0 0 0 0 + 3 4 2 0 0 0 0 + 3 11 1 0 0 0 0 + 4 12 1 0 0 0 0 + 5 13 1 0 0 0 0 + 6 10 1 0 0 0 0 + 6 11 2 0 0 0 0 + 7 9 2 0 0 0 0 + 7 21 1 0 0 0 0 + 8 22 2 0 0 0 0 + 8 25 1 0 0 0 0 + 10 12 2 0 0 0 0 + 10 18 1 0 0 0 0 + 11 27 1 0 0 0 0 + 12 29 1 0 0 0 0 + 13 16 1 0 0 0 0 + 13 21 2 0 0 0 0 + 14 15 1 0 0 0 0 + 14 23 2 0 0 0 0 + 14 25 1 0 0 0 0 + 15 24 2 0 0 0 0 + 15 26 1 0 0 0 0 + 16 27 1 0 0 0 0 + 16 28 2 0 0 0 0 + 17 18 1 0 0 0 0 + 17 25 1 0 0 0 0 + 18 19 1 0 0 0 0 + 18 24 1 0 0 0 0 + 22 23 1 0 0 0 0 + 2 30 1 0 0 0 0 + 3 31 1 0 0 0 0 + 4 32 1 0 0 0 0 + 5 33 1 0 0 0 0 + 6 34 1 0 0 0 0 + 7 35 1 0 0 0 0 + 8 36 1 0 0 0 0 + 17 37 1 0 0 0 0 + 17 38 1 0 0 0 0 + 19 39 1 0 0 0 0 + 19 40 1 0 0 0 0 + 19 41 1 0 0 0 0 + 26 42 1 0 0 0 0 + 26 43 1 0 0 0 0 + 27 44 1 0 0 0 0 + 24 45 1 0 0 0 0 +M CHG 1 24 1 +M END + +> +7.97 + +> +10.1021/acsmedchemlett.9b00181 + +$$$$ diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index eca7d1848..727b088c9 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -284,7 +284,7 @@ def test_validate_alchem_nonsmc( SepTopProtocol._validate_alchemical_components(alchem_comps) -def test_setup(benzene_modifications, T4_protein_component, tmpdir): +def test_setup(bace_ligands, bace_protein_component, tmpdir): # check system parametrisation works even if confgen fails s = SepTopProtocol.default_settings() s.protocol_repeats = 1 @@ -301,14 +301,14 @@ def test_setup(benzene_modifications, T4_protein_component, tmpdir): ) stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, + 'lig_02': bace_ligands['lig_02'], + 'protein': bace_protein_component, 'solvent': SolventComponent(), }) stateB = ChemicalSystem({ - 'toluene': benzene_modifications['toluene'], - 'protein': T4_protein_component, + 'lig_03': bace_ligands['lig_03'], + 'protein': bace_protein_component, 'solvent': SolventComponent(), }) From d8ff3b17bb3e36cf14045d4338ca022727110183 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 10:28:02 +0100 Subject: [PATCH 008/163] Some more changes --- openfe/protocols/openmm_septop/base.py | 2 ++ .../openmm_septop/equil_septop_method.py | 30 ++++++++++--------- .../protocols/test_openmm_septop_protocol.py | 6 ++-- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 9e312da7e..c0f8a6ddf 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -945,6 +945,8 @@ def _add_restraints( system: openmm.System, positions: np.array, topology: Optional[openmm.Topology], + ligand_1: SmallMoleculeComponent, + ligand_2: SmallMoleculeComponent, settings, ligand_1_ref_idx: int, ligand_2_ref_idx: int, diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 7dde1919c..58d37c708 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -58,7 +58,7 @@ SettingsBaseModel, RestraintsSettings, ) from ..openmm_utils import system_validation, settings_validation -from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit, _get +from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit from openfe.utils import log_system_probe from openfe.due import due, Doi from .femto_restraints import select_ligand_idxs, select_receptor_idxs @@ -846,29 +846,29 @@ def _add_restraints( system: openmm.System, positions: np.array, topology: openmm.Topology, + ligand_1, + ligand_2, settings, ligand_1_ref_idx: int, ligand_2_ref_idx: int, ) -> openmm.System: traj = _get_mdtraj_from_openmm(topology, positions) + ligand_1_mdtraj_top = md.Topology.from_openmm(ligand_1.to_openff().to_topology().to_openmm()) + ligand_1_mdtraj_pos = np.array( + ligand_1.to_openff().to_topology().get_positions() / openmm.unit.nanometers) + ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1_mdtraj_top, ligand_1_mdtraj_pos) receptor_ref_idxs_1 = select_receptor_idxs( - traj, ligand_1, ligand_1_ref_idxs + traj, ligand_1_mdtraj, ligand_1_ref_idx ) + print(receptor_ref_idxs_1) receptor_ref_idxs_2 = receptor_ref_idxs_1 - # Remove the offset of ligand 2 atom indices. - # `ligand_2_ref_idxs` should be in the range 0:ligand_2.atoms to match - # `ligand_2` parmed.amber.AmberParm. - _ligand_2_ref_idxs = tuple( - i - len(ligand_1.atoms) for i in ligand_2_ref_idxs) - if ligand_2 is not None and not femto.fe.reference.check_receptor_idxs( - receptor, receptor_ref_idxs_1, ligand_2, _ligand_2_ref_idxs - ): - _LOGGER.info( - "selecting alternate receptor reference atoms for ligand 2") - receptor_ref_idxs_2 = femto.fe.reference.select_receptor_idxs( - receptor, ligand_2, _ligand_2_ref_idxs + # if ligand_2 is not None and not femto.fe.reference.check_receptor_idxs( + # receptor, receptor_ref_idxs_1, ligand_2, _ligand_2_ref_idxs + # ): + # receptor_ref_idxs_2 = femto.fe.reference.select_receptor_idxs( + # receptor, ligand_2, _ligand_2_ref_idxs def _execute( @@ -1014,6 +1014,8 @@ def _add_restraints( system: openmm.System, positions, topology, + ligand_1, + ligand_2, settings, ligand_1_ref_idx: int, ligand_2_ref_idx: int, diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 727b088c9..cd5a64b7c 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -288,7 +288,7 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): # check system parametrisation works even if confgen fails s = SepTopProtocol.default_settings() s.protocol_repeats = 1 - s.solvent_equil_simulation_settings.minimization_steps = 100 + s.solvent_equil_simulation_settings.minimization_steps = 1 s.solvent_equil_simulation_settings.equilibration_length_nvt = 1 * unit.picosecond s.solvent_equil_simulation_settings.equilibration_length = 1 * unit.picosecond s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond @@ -322,8 +322,8 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] - # solv_setup_unit = [u for u in prot_units - # if isinstance(u, SepTopComplexSetupUnit)] + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopComplexSetupUnit)] # with tmpdir.as_cwd(): solv_setup_unit[0].run() From 57536892f4b10c8584b6664f4e662160a65b4723 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 10:59:02 +0100 Subject: [PATCH 009/163] Add some femto utils --- openfe/protocols/openmm_septop/femto_utils.py | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 openfe/protocols/openmm_septop/femto_utils.py diff --git a/openfe/protocols/openmm_septop/femto_utils.py b/openfe/protocols/openmm_septop/femto_utils.py new file mode 100644 index 000000000..710f0930e --- /dev/null +++ b/openfe/protocols/openmm_septop/femto_utils.py @@ -0,0 +1,130 @@ +"""Common functions for computing the internal coordinates (e.g. bond lengths).""" + +import numpy + + +def compute_bond_vectors( + coords: numpy.ndarray, idxs: numpy.ndarray +) -> tuple[numpy.ndarray, numpy.ndarray]: + """Computes the vectors between each atom pair specified by the ``idxs`` as + well as their norms. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)``. + idxs: The indices of the coordinates to compute the distances between with + ``shape=(n_pairs, 2)``. + + Returns: + A tuple of the vectors with shape=``shape=(n_pairs, 3)`` and norms with + ``shape=(n_pairs,)``. + """ + + if len(idxs) == 0: + return numpy.ndarray([]), numpy.ndarray([]) + + directions = coords[idxs[:, 1]] - coords[idxs[:, 0]] + distances = numpy.linalg.norm(directions, axis=1) + + return directions, distances + + +def compute_distances(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarray: + """Computes the distances between each pair of coordinates. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)``. + idxs: The indices of the coordinates to compute the distances between with + ``shape=(n_pairs, 2)``. + + Returns: + The distances with ``shape=(n_pairs,)``. + """ + + return compute_bond_vectors(coords, idxs)[1] + + +def compute_angles(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarray: + """Computes the angles [rad] between each specified triplet of indices. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)`` or + ``shape=(n_frames, n_coords, 3)``. + idxs: The indices of the coordinates to compute the angles between with + ``shape=(n_pairs, 3)``. + + Returns: + The angles with ``shape=(n_pairs,)`` or ``shape=(n_frames, n_pairs)``. + """ + + if len(idxs) == 0: + return numpy.ndarray([]) + + is_batched = coords.ndim == 3 + + if not is_batched: + coords = coords[None, :, :] + + vector_ab = coords[:, idxs[:, 1]] - coords[:, idxs[:, 0]] + vector_ac = coords[:, idxs[:, 1]] - coords[:, idxs[:, 2]] + + # tan theta = sin theta / cos theta + # + # ||a x b|| = ||a|| ||b|| sin theta + # a . b = ||a|| ||b|| cos theta + # + # => tan theta = (a x b) / (a . b) + angles = numpy.arctan2( + numpy.linalg.norm(numpy.cross(vector_ab, vector_ac, axis=-1), axis=-1), + (vector_ab * vector_ac).sum(axis=-1), + ) + + if not is_batched: + angles = angles[0] + + return angles + + +def compute_dihedrals(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarray: + """Computes the angles [rad] between each specified quartet of indices. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)`` or + ``shape=(n_frames, n_coords, 3)``. + idxs: The indices of the coordinates to compute the dihedrals between with + ``shape=(n_pairs, 4)``. + + Returns: + The dihedrals with ``shape=(n_pairs,)`` or ``shape=(n_frames, n_pairs)``. + """ + + if len(idxs) == 0: + return numpy.ndarray([]) + + is_batched = coords.ndim == 3 + + if not is_batched: + coords = coords[None, :, :] + + vector_ab = coords[:, idxs[:, 0]] - coords[:, idxs[:, 1]] + vector_cb = coords[:, idxs[:, 2]] - coords[:, idxs[:, 1]] + vector_cd = coords[:, idxs[:, 2]] - coords[:, idxs[:, 3]] + + vector_ab_cross_cb = numpy.cross(vector_ab, vector_cb, axis=-1) + vector_cb_cross_cd = numpy.cross(vector_cb, vector_cd, axis=-1) + + vector_cb_norm = numpy.linalg.norm(vector_cb, axis=-1)[:, :, None] + + y = ( + numpy.cross(vector_ab_cross_cb, vector_cb_cross_cd, axis=-1) + * vector_cb + / vector_cb_norm + ).sum(axis=-1) + + x = (vector_ab_cross_cb * vector_cb_cross_cd).sum(axis=-1) + + phi = numpy.arctan2(y, x) + + if not is_batched: + phi = phi[0] + + return phi \ No newline at end of file From 3a719631ae6a6107a8685ae638ef5b6ec7602cbc Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 12:17:16 +0100 Subject: [PATCH 010/163] Some fixes for the restraints --- openfe/protocols/openmm_septop/base.py | 15 +++++++----- .../openmm_septop/equil_septop_method.py | 23 ++++++++++--------- .../protocols/test_openmm_septop_protocol.py | 2 +- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index c0f8a6ddf..887594922 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -945,11 +945,11 @@ def _add_restraints( system: openmm.System, positions: np.array, topology: Optional[openmm.Topology], - ligand_1: SmallMoleculeComponent, - ligand_2: SmallMoleculeComponent, - settings, - ligand_1_ref_idx: int, - ligand_2_ref_idx: int, + ligand_1: Optional[OFFMolecule.Topology], + ligand_2: Optional[OFFMolecule.Topology], + settings: Optional, + ligand_1_ref_idxs: list[int], + ligand_2_ref_idxs: list[int], ) -> openmm.System: """ Get new positions for the stateB after equilibration. @@ -1137,7 +1137,10 @@ def run(self, dry=False, verbose=True, print(ligand_A_inxs) print(ligand_B_inxs) - system = self._add_restraints(omm_system_AB, positions_AB, settings, ligand_A_inxs, ligand_B_inxs) + system = self._add_restraints( + omm_system_AB, positions_AB, omm_topology_AB, + off_A, off_B, + settings, ligand_A_inxs, ligand_B_inxs) print(system) # Here we could also apply REST diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 58d37c708..84732135f 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -849,17 +849,17 @@ def _add_restraints( ligand_1, ligand_2, settings, - ligand_1_ref_idx: int, - ligand_2_ref_idx: int, + ligand_1_ref_idxs: list[int], + ligand_2_ref_idxs: list[int], ) -> openmm.System: traj = _get_mdtraj_from_openmm(topology, positions) - ligand_1_mdtraj_top = md.Topology.from_openmm(ligand_1.to_openff().to_topology().to_openmm()) + ligand_1_mdtraj_top = md.Topology.from_openmm(ligand_1.to_openmm()) ligand_1_mdtraj_pos = np.array( - ligand_1.to_openff().to_topology().get_positions() / openmm.unit.nanometers) + ligand_1.get_positions() / openmm.unit.nanometers) ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1_mdtraj_top, ligand_1_mdtraj_pos) receptor_ref_idxs_1 = select_receptor_idxs( - traj, ligand_1_mdtraj, ligand_1_ref_idx + traj, ligand_1_mdtraj, ligand_1_ref_idxs ) print(receptor_ref_idxs_1) receptor_ref_idxs_2 = receptor_ref_idxs_1 @@ -870,6 +870,7 @@ def _add_restraints( # receptor_ref_idxs_2 = femto.fe.reference.select_receptor_idxs( # receptor, ligand_2, _ligand_2_ref_idxs + return system def _execute( self, ctx: gufe.Context, **kwargs, @@ -1017,8 +1018,8 @@ def _add_restraints( ligand_1, ligand_2, settings, - ligand_1_ref_idx: int, - ligand_2_ref_idx: int, + ligand_1_ref_idxs: list[int], + ligand_2_ref_idxs: list[int], ) -> openmm.System: """Apply a distance restraints between the ligands. @@ -1030,15 +1031,15 @@ def _add_restraints( """ coords = positions - + # Taking the middle reference atom distance = np.linalg.norm( - coords[ligand_1_ref_idx] - coords[ligand_2_ref_idx]) + coords[ligand_1_ref_idxs[1]] - coords[ligand_2_ref_idxs[1]]) print(distance) force = openmm.HarmonicBondForce() force.addBond( - ligand_1_ref_idx[1], - ligand_2_ref_idx[1], + ligand_1_ref_idxs[1], + ligand_2_ref_idxs[1], distance * openmm.unit.angstrom, settings['restraint_settings'].k_distance.m, ) diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index cd5a64b7c..2d1a1b3be 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -293,7 +293,7 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): s.solvent_equil_simulation_settings.equilibration_length = 1 * unit.picosecond s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond s.solvation_settings.box_shape = 'dodecahedron' - s.solvation_settings.solvent_padding = 1.5 * unit.nanometer + s.solvation_settings.solvent_padding = 1.2 * unit.nanometer s.complex_forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer protocol = SepTopProtocol( From 0b6d7baf80ea0e8d6212cb71a202e482fd36aa21 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 12:28:41 +0100 Subject: [PATCH 011/163] Create separate solvation settings for solvent and complex --- openfe/protocols/openmm_septop/equil_septop_method.py | 9 ++++++--- openfe/protocols/openmm_septop/equil_septop_settings.py | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 84732135f..70a3ab309 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -436,7 +436,10 @@ def _default_settings(cls): lambda_settings=LambdaSettings( ), partial_charge_settings=OpenFFPartialChargeSettings(), - solvation_settings=OpenMMSolvationSettings(), + solvent_solvation_settings=OpenMMSolvationSettings( + solvent_padding=1.5 * unit.nanometer + ), + complex_solvation_settings=OpenMMSolvationSettings(), complex_engine_settings=OpenMMEngineSettings(), solvent_engine_settings=OpenMMEngineSettings(), integrator_settings=IntegratorSettings(), @@ -808,7 +811,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['forcefield_settings'] = prot_settings.complex_forcefield_settings settings['thermo_settings'] = prot_settings.thermo_settings settings['charge_settings'] = prot_settings.partial_charge_settings - settings['solvation_settings'] = prot_settings.solvation_settings + settings['solvation_settings'] = prot_settings.complex_solvation_settings settings['alchemical_settings'] = prot_settings.alchemical_settings settings['lambda_settings'] = prot_settings.lambda_settings settings['engine_settings'] = prot_settings.complex_engine_settings @@ -961,7 +964,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: settings['forcefield_settings'] = prot_settings.solvent_forcefield_settings settings['thermo_settings'] = prot_settings.thermo_settings settings['charge_settings'] = prot_settings.partial_charge_settings - settings['solvation_settings'] = prot_settings.solvation_settings + settings['solvation_settings'] = prot_settings.solvent_solvation_settings settings['alchemical_settings'] = prot_settings.alchemical_settings settings['lambda_settings'] = prot_settings.lambda_settings settings['engine_settings'] = prot_settings.solvent_engine_settings diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 6f97575eb..0d875cfcd 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -136,8 +136,11 @@ def must_be_positive(cls, v): thermo_settings: ThermoSettings """Settings for thermodynamic parameters""" - solvation_settings: OpenMMSolvationSettings - """Settings for solvating the system.""" + solvent_solvation_settings: OpenMMSolvationSettings + """Settings for solvating the solvent system.""" + + complex_solvation_settings: OpenMMSolvationSettings + """Settings for solvating the complex system.""" # Alchemical settings alchemical_settings: AlchemicalSettings From 6894cd9f4a8582dd47a2bc5270a078bec3a1e865 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 13:12:18 +0100 Subject: [PATCH 012/163] Testing some things --- openfe/protocols/openmm_septop/base.py | 6 +++++- .../openmm_septop/equil_septop_method.py | 15 +++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 887594922..40c830c64 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1106,9 +1106,13 @@ def run(self, dry=False, verbose=True, atom_indices_AB_A = comp_atomids_AB[alchem_comps['stateA'][0]] # Update positions from AB system + print(atom_indices_AB_B) + print(atom_indices_B) + print(len(positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :])) + print(len(updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1])) positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, - :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] + :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1, :] simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, positions_AB, diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 70a3ab309..782565315 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -995,16 +995,23 @@ def _update_positions( equ_pos_ligandB = positions_B[ atom_indices_B[0]:atom_indices_B[-1] + 1] + # Get the mdtraj system of ligand B and the unit cell + unit_cell = omm_topology_A.getPeriodicBoxVectors() + unit_cell = [i[inx] for inx, i in enumerate(unit_cell)] + mdtraj_system_B = _get_mdtraj_from_openmm(omm_topology_B, + positions_B) + ligand_1_radius = np.linalg.norm( equ_pos_ligandA - equ_pos_ligandA.mean(axis=0), axis=1).max() ligand_2_radius = np.linalg.norm( equ_pos_ligandB - equ_pos_ligandB.mean(axis=0), axis=1).max() - ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 + # ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 + ligand_distance = (ligand_1_radius + ligand_2_radius) * min(unit_cell) / 2 ligand_offset = equ_pos_ligandA.mean(0) - equ_pos_ligandB.mean(0) - ligand_offset[0] += ligand_distance * omm_units.nanometers + ligand_offset[0] += ligand_distance + print(ligand_offset) + # Offset the ligandB. - mdtraj_system_B = _get_mdtraj_from_openmm(omm_topology_B, - positions_B) mdtraj_system_B.xyz[0][atom_indices_B, :] += ligand_offset / omm_units.nanometers From 107d60346afeab448dde43af5c66e462766b0572 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 13:27:10 +0100 Subject: [PATCH 013/163] Testing some things --- openfe/protocols/openmm_septop/base.py | 4 +++- openfe/protocols/openmm_septop/equil_septop_method.py | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 40c830c64..38bf6962b 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1082,6 +1082,8 @@ def run(self, dry=False, verbose=True, comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) + print(comp_atomids_B) + print(alchem_comps['stateB'][0]) # Get the system A atom indices of ligand A atom_indices_A = comp_atomids_A[alchem_comps['stateA'][0]] @@ -1112,7 +1114,7 @@ def run(self, dry=False, verbose=True, print(len(updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1])) positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, - :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1, :] + :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, positions_AB, diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 782565315..d2673030a 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1005,8 +1005,10 @@ def _update_positions( equ_pos_ligandA - equ_pos_ligandA.mean(axis=0), axis=1).max() ligand_2_radius = np.linalg.norm( equ_pos_ligandB - equ_pos_ligandB.mean(axis=0), axis=1).max() - # ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 - ligand_distance = (ligand_1_radius + ligand_2_radius) * min(unit_cell) / 2 + ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 * unit.nanometer + if ligand_distance.m > min(unit_cell.m) / 2: + ligand_distance = min(unit_cell) / 2 + ligand_offset = equ_pos_ligandA.mean(0) - equ_pos_ligandB.mean(0) ligand_offset[0] += ligand_distance print(ligand_offset) From 2a017d5ae5d76627ea0541599b37424d49ef81b6 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 13:42:42 +0100 Subject: [PATCH 014/163] Fix comp_resids_B --- openfe/protocols/openmm_septop/base.py | 6 ++++-- openfe/protocols/openmm_septop/equil_septop_method.py | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 38bf6962b..f24bfa045 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1025,7 +1025,7 @@ def run(self, dry=False, verbose=True, ) # Get modeller B only ligand B - modeller_ligandB, comp_resids_B = self._get_modeller( + modeller_ligandB, comp_resids_ligB = self._get_modeller( None, None, smc_off_B, system_generator, settings['solvation_settings'], ) @@ -1082,8 +1082,10 @@ def run(self, dry=False, verbose=True, comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) + print(comp_resids_A) + print(comp_resids_A) + print(comp_resids_B) print(comp_atomids_B) - print(alchem_comps['stateB'][0]) # Get the system A atom indices of ligand A atom_indices_A = comp_atomids_A[alchem_comps['stateA'][0]] diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index d2673030a..dcaa365e3 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1005,8 +1005,8 @@ def _update_positions( equ_pos_ligandA - equ_pos_ligandA.mean(axis=0), axis=1).max() ligand_2_radius = np.linalg.norm( equ_pos_ligandB - equ_pos_ligandB.mean(axis=0), axis=1).max() - ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 * unit.nanometer - if ligand_distance.m > min(unit_cell.m) / 2: + ligand_distance = (ligand_1_radius + ligand_2_radius) * 1.5 * omm_units.nanometer + if ligand_distance > min(unit_cell) / 2: ligand_distance = min(unit_cell) / 2 ligand_offset = equ_pos_ligandA.mean(0) - equ_pos_ligandB.mean(0) From 74a98186d0e0b5342b1fdeb6b14ee21ed7d6e0c8 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 13:55:58 +0100 Subject: [PATCH 015/163] Fix restraints complex mdtraj --- openfe/protocols/openmm_septop/base.py | 18 +++++++++--------- .../openmm_septop/equil_septop_method.py | 4 +++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index f24bfa045..62854578b 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -992,6 +992,7 @@ def run(self, dry=False, verbose=True, self._prepare(verbose, scratch_basepath, shared_basepath) # 1. Get components + self.logger.info("Creating and setting up the OpenMM systems") alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() # 2. Get settings @@ -1067,6 +1068,7 @@ def run(self, dry=False, verbose=True, open('outputAB.pdb', 'w')) # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) + self.logger.info("Pre-equilibrating the systems") equ_positions_A = self._pre_equilibrate( omm_system_A, omm_topology_A, positions_A, settings, dry ) @@ -1082,10 +1084,6 @@ def run(self, dry=False, verbose=True, comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) - print(comp_resids_A) - print(comp_resids_A) - print(comp_resids_B) - print(comp_atomids_B) # Get the system A atom indices of ligand A atom_indices_A = comp_atomids_A[alchem_comps['stateA'][0]] @@ -1110,10 +1108,6 @@ def run(self, dry=False, verbose=True, atom_indices_AB_A = comp_atomids_AB[alchem_comps['stateA'][0]] # Update positions from AB system - print(atom_indices_AB_B) - print(atom_indices_B) - print(len(positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :])) - print(len(updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1])) positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] @@ -1124,6 +1118,7 @@ def run(self, dry=False, verbose=True, 'w')) # 9. Create the alchemical system + self.logger.info("Creating the alchemical system and applying restraints") apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) # 10. Apply Restraints @@ -1149,7 +1144,12 @@ def run(self, dry=False, verbose=True, omm_system_AB, positions_AB, omm_topology_AB, off_A, off_B, settings, ligand_A_inxs, ligand_B_inxs) - print(system) + # Check that the restraints are correctly applied by running a short equilibration + equ_positions_restraints = self._pre_equilibrate( + system, omm_topology_AB, positions_AB, settings, dry + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile( + omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) # Here we could also apply REST diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index dcaa365e3..dcad372cb 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -857,10 +857,12 @@ def _add_restraints( ) -> openmm.System: traj = _get_mdtraj_from_openmm(topology, positions) + ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1.to_openmm(), ligand_1.get_positions()) ligand_1_mdtraj_top = md.Topology.from_openmm(ligand_1.to_openmm()) ligand_1_mdtraj_pos = np.array( ligand_1.get_positions() / openmm.unit.nanometers) - ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1_mdtraj_top, ligand_1_mdtraj_pos) + ligand_1_mdtraj = md.Trajectory(ligand_1_mdtraj_pos, + ligand_1_mdtraj_top) receptor_ref_idxs_1 = select_receptor_idxs( traj, ligand_1_mdtraj, ligand_1_ref_idxs ) From 427aee4ea9bc6b660e6e0940a5320dd3d24a795d Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 19 Nov 2024 14:38:58 +0100 Subject: [PATCH 016/163] Update restraint selection --- openfe/protocols/openmm_septop/equil_septop_method.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index dcad372cb..db2baf440 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -858,11 +858,11 @@ def _add_restraints( traj = _get_mdtraj_from_openmm(topology, positions) ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1.to_openmm(), ligand_1.get_positions()) - ligand_1_mdtraj_top = md.Topology.from_openmm(ligand_1.to_openmm()) - ligand_1_mdtraj_pos = np.array( - ligand_1.get_positions() / openmm.unit.nanometers) - ligand_1_mdtraj = md.Trajectory(ligand_1_mdtraj_pos, - ligand_1_mdtraj_top) + # Convert ligand indices to the indices in the ligand (start with zero) + # CAVE: We're assuming here that the atom order did not change! + # This needs to be tested!!! + ligand_1_ref_idxs = [inx for inx, i in enumerate(ligand_1_ref_idxs)] + # Select the reference indices in the receptor receptor_ref_idxs_1 = select_receptor_idxs( traj, ligand_1_mdtraj, ligand_1_ref_idxs ) From 8b882143bcf17b24f41632761e089f67660cd6bb Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 20 Nov 2024 13:20:24 +0100 Subject: [PATCH 017/163] More edits Boresch restraints --- .../openmm_septop/equil_septop_method.py | 49 +++++- .../openmm_septop/equil_septop_settings.py | 5 +- .../openmm_septop/femto_constants.py | 49 ++++++ .../protocols/openmm_septop/femto_geometry.py | 130 +++++++++++++++ .../openmm_septop/femto_restraints.py | 156 +++++++++++++++++- openfe/protocols/openmm_septop/femto_utils.py | 46 +++++- 6 files changed, 416 insertions(+), 19 deletions(-) create mode 100644 openfe/protocols/openmm_septop/femto_constants.py create mode 100644 openfe/protocols/openmm_septop/femto_geometry.py diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index db2baf440..7107d1cdc 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -61,7 +61,12 @@ from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit from openfe.utils import log_system_probe from openfe.due import due, Doi -from .femto_restraints import select_ligand_idxs, select_receptor_idxs +from .femto_restraints import ( + select_receptor_idxs, + check_receptor_idxs, + create_boresch_restraint, +) +from .femto_utils import assign_force_groups due.cite(Doi("10.5281/zenodo.596622"), @@ -483,8 +488,13 @@ def _default_settings(cls): output_filename='complex.nc', checkpoint_storage_filename='complex_checkpoint.nc' ), - solvent_restraints_settings=RestraintsSettings(), - complex_restraints_settings=RestraintsSettings(), + solvent_restraints_settings=RestraintsSettings( + k_distance=1000 * unit.kilojoule_per_mole / unit.nanometer**2, + k_theta=None, + ), + complex_restraints_settings=RestraintsSettings( + k_distance=8368.0 * unit.kilojoule_per_mole / unit.nanometer ** 2 + ), ) @staticmethod @@ -862,6 +872,7 @@ def _add_restraints( # CAVE: We're assuming here that the atom order did not change! # This needs to be tested!!! ligand_1_ref_idxs = [inx for inx, i in enumerate(ligand_1_ref_idxs)] + ligand_2_ref_idxs = [inx for inx, i in enumerate(ligand_2_ref_idxs)] # Select the reference indices in the receptor receptor_ref_idxs_1 = select_receptor_idxs( traj, ligand_1_mdtraj, ligand_1_ref_idxs @@ -869,11 +880,31 @@ def _add_restraints( print(receptor_ref_idxs_1) receptor_ref_idxs_2 = receptor_ref_idxs_1 - # if ligand_2 is not None and not femto.fe.reference.check_receptor_idxs( - # receptor, receptor_ref_idxs_1, ligand_2, _ligand_2_ref_idxs - # ): - # receptor_ref_idxs_2 = femto.fe.reference.select_receptor_idxs( - # receptor, ligand_2, _ligand_2_ref_idxs + + if not check_receptor_idxs( + traj, receptor_ref_idxs_1, ligand_2, ligand_2_ref_idxs + ): + receptor_ref_idxs_2 = select_receptor_idxs( + traj, ligand_2, ligand_2_ref_idxs) + print(receptor_ref_idxs_2) + + force_A = create_boresch_restraint( + receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] + ligand_1_ref_idxs, + positions, + settings["restraint_settings"], + ) + system.addForce(force_A) + force_B = create_boresch_restraint( + receptor_ref_idxs_2[::-1], + # expects [r3, r2, r1], not [r1, r2, r3] + ligand_2_ref_idxs, + positions, + settings["restraint_settings"], + ) + system.addForce(force_B) + + assign_force_groups(system) return system @@ -1054,7 +1085,7 @@ def _add_restraints( force.addBond( ligand_1_ref_idxs[1], ligand_2_ref_idxs[1], - distance * openmm.unit.angstrom, + distance * openmm.unit.nanometers, settings['restraint_settings'].k_distance.m, ) force.setName("alignment_restraint") diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 0d875cfcd..bfaab023e 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -29,6 +29,7 @@ from openff.models.types import FloatQuantity import numpy as np from pydantic.v1 import validator +from typing import Optional class AlchemicalSettings(SettingsBaseModel): @@ -42,8 +43,8 @@ class RestraintsSettings(SettingsBaseModel): """ Settings for the restraints. """ - k_distance: FloatQuantity['kcal/(mol*angstrom**2)'] = 20 * unit.kilocalorie_per_mole / unit.angstrom**2 - k_theta: FloatQuantity['kcal/(mol*rad**2)'] = 20 * unit.kilocalorie_per_mole / unit.radians**2 + k_distance: FloatQuantity['kcal/(mol*angstrom**2)'] = 1000 * unit.kilojoule_per_mole / unit.nanometer**2 + k_theta: Optional[FloatQuantity['kcal/(mol*rad**2)']] = 20 * unit.kilocalorie_per_mole / unit.radians**2 diff --git a/openfe/protocols/openmm_septop/femto_constants.py b/openfe/protocols/openmm_septop/femto_constants.py new file mode 100644 index 000000000..69356b699 --- /dev/null +++ b/openfe/protocols/openmm_septop/femto_constants.py @@ -0,0 +1,49 @@ +"""Constant values such as common force groups and names.""" + +import enum + +LIGAND_1_RESIDUE_NAME = "L1" +"""The standard residue name to assign to ligand 1 of a FE calculation.""" +LIGAND_2_RESIDUE_NAME = "R1" +"""The standard residue name to assign to ligand 2 of a FE calculation.""" + + +class OpenMMForceGroup(enum.IntEnum): + """Standard force groups to assign to common OpenMM forces to make them easier to + identify.""" + + BOND = 0 + ANGLE = 1 + DIHEDRAL = 2 + + NONBONDED = 3 + + COM_RESTRAINT = 4 + POSITION_RESTRAINT = 5 + ALIGNMENT_RESTRAINT = 6 + + BAROSTAT = 7 + + ATM = 8 + + OTHER = 16 + + +class OpenMMForceName(str, enum.Enum): + """Standard names use for common OpenMM forces to make them easier to identify.""" + + COM_RESTRAINT = "com-restraint" + POSITION_RESTRAINT = "position-restraint" + ALIGNMENT_RESTRAINT = "alignment-restraint" + + +class OpenMMPlatform(str, enum.Enum): + """The available OpenMM platforms to run using.""" + + REFERENCE = "Reference" + CPU = "CPU" + OPENCL = "OpenCL" + CUDA = "CUDA" + + def __str__(self): + return self.value \ No newline at end of file diff --git a/openfe/protocols/openmm_septop/femto_geometry.py b/openfe/protocols/openmm_septop/femto_geometry.py new file mode 100644 index 000000000..710f0930e --- /dev/null +++ b/openfe/protocols/openmm_septop/femto_geometry.py @@ -0,0 +1,130 @@ +"""Common functions for computing the internal coordinates (e.g. bond lengths).""" + +import numpy + + +def compute_bond_vectors( + coords: numpy.ndarray, idxs: numpy.ndarray +) -> tuple[numpy.ndarray, numpy.ndarray]: + """Computes the vectors between each atom pair specified by the ``idxs`` as + well as their norms. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)``. + idxs: The indices of the coordinates to compute the distances between with + ``shape=(n_pairs, 2)``. + + Returns: + A tuple of the vectors with shape=``shape=(n_pairs, 3)`` and norms with + ``shape=(n_pairs,)``. + """ + + if len(idxs) == 0: + return numpy.ndarray([]), numpy.ndarray([]) + + directions = coords[idxs[:, 1]] - coords[idxs[:, 0]] + distances = numpy.linalg.norm(directions, axis=1) + + return directions, distances + + +def compute_distances(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarray: + """Computes the distances between each pair of coordinates. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)``. + idxs: The indices of the coordinates to compute the distances between with + ``shape=(n_pairs, 2)``. + + Returns: + The distances with ``shape=(n_pairs,)``. + """ + + return compute_bond_vectors(coords, idxs)[1] + + +def compute_angles(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarray: + """Computes the angles [rad] between each specified triplet of indices. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)`` or + ``shape=(n_frames, n_coords, 3)``. + idxs: The indices of the coordinates to compute the angles between with + ``shape=(n_pairs, 3)``. + + Returns: + The angles with ``shape=(n_pairs,)`` or ``shape=(n_frames, n_pairs)``. + """ + + if len(idxs) == 0: + return numpy.ndarray([]) + + is_batched = coords.ndim == 3 + + if not is_batched: + coords = coords[None, :, :] + + vector_ab = coords[:, idxs[:, 1]] - coords[:, idxs[:, 0]] + vector_ac = coords[:, idxs[:, 1]] - coords[:, idxs[:, 2]] + + # tan theta = sin theta / cos theta + # + # ||a x b|| = ||a|| ||b|| sin theta + # a . b = ||a|| ||b|| cos theta + # + # => tan theta = (a x b) / (a . b) + angles = numpy.arctan2( + numpy.linalg.norm(numpy.cross(vector_ab, vector_ac, axis=-1), axis=-1), + (vector_ab * vector_ac).sum(axis=-1), + ) + + if not is_batched: + angles = angles[0] + + return angles + + +def compute_dihedrals(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarray: + """Computes the angles [rad] between each specified quartet of indices. + + Args: + coords: The coordinates with ``shape=(n_coords, 3)`` or + ``shape=(n_frames, n_coords, 3)``. + idxs: The indices of the coordinates to compute the dihedrals between with + ``shape=(n_pairs, 4)``. + + Returns: + The dihedrals with ``shape=(n_pairs,)`` or ``shape=(n_frames, n_pairs)``. + """ + + if len(idxs) == 0: + return numpy.ndarray([]) + + is_batched = coords.ndim == 3 + + if not is_batched: + coords = coords[None, :, :] + + vector_ab = coords[:, idxs[:, 0]] - coords[:, idxs[:, 1]] + vector_cb = coords[:, idxs[:, 2]] - coords[:, idxs[:, 1]] + vector_cd = coords[:, idxs[:, 2]] - coords[:, idxs[:, 3]] + + vector_ab_cross_cb = numpy.cross(vector_ab, vector_cb, axis=-1) + vector_cb_cross_cd = numpy.cross(vector_cb, vector_cd, axis=-1) + + vector_cb_norm = numpy.linalg.norm(vector_cb, axis=-1)[:, :, None] + + y = ( + numpy.cross(vector_ab_cross_cb, vector_cb_cross_cd, axis=-1) + * vector_cb + / vector_cb_norm + ).sum(axis=-1) + + x = (vector_ab_cross_cb * vector_cb_cross_cd).sum(axis=-1) + + phi = numpy.arctan2(y, x) + + if not is_batched: + phi = phi[0] + + return phi \ No newline at end of file diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 6f1e04f1b..382c9f959 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -13,6 +13,7 @@ import scipy.spatial import scipy.spatial.distance from .femto_utils import compute_angles, compute_dihedrals +from .femto_geometry import compute_distances, compute_angles, compute_dihedrals _COLLINEAR_THRESHOLD = 0.9 # roughly 25 degrees @@ -502,8 +503,6 @@ def select_receptor_idxs( ), None, ) - print(found_r1) - print(found_r2) if found_r1 is None or found_r2 is None: raise ValueError("could not find valid R1 / R2 atoms") @@ -513,7 +512,6 @@ def select_receptor_idxs( for idx in receptor_idxs if _is_valid_r3(receptor, idx, found_r1, found_r2, ligand, ligand_ref_idxs) ] - print(valid_r3_idxs) if len(valid_r3_idxs) == 0: raise ValueError("could not find a valid R3 atom") @@ -572,10 +570,6 @@ def check_receptor_idxs( if not (isinstance(receptor, type(ligand)) or isinstance(ligand, type(receptor))): raise ValueError("receptor and ligand must be the same type") - if isinstance(receptor, parmed.Structure) and isinstance(ligand, parmed.Structure): - receptor = _structure_to_mdtraj(receptor) - ligand = _structure_to_mdtraj(ligand) - assert ( receptor.n_frames == ligand.n_frames ), "receptor and ligand must have the same number of frames" @@ -596,3 +590,151 @@ def check_receptor_idxs( is_valid_distance = r3_distance_avg.max(axis=-1) < max_distance return is_valid_r1 and is_valid_r2 and is_valid_r3 and is_valid_distance + + +_BORESCH_ENERGY_FN = ( + "0.5 * E;" + "E = k_dist_a * (distance(p3,p4) - dist_0) ^ 2" + " + k_theta_a * (angle(p2,p3,p4) - theta_a_0) ^ 2" + " + k_theta_b * (angle(p3,p4,p5) - theta_b_0) ^ 2" + " + k_phi_a * (d_phi_a_wrap) ^ 2" + " + k_phi_b * (d_phi_b_wrap) ^ 2" + " + k_phi_c * (d_phi_c_wrap) ^ 2;" + # compute the periodic dihedral delta (e.g. distance between -180 and 180 is 0) + "d_phi_a_wrap = d_phi_a - floor(d_phi_a / (2.0 * pi) + 0.5) * (2.0 * pi);" + "d_phi_a = dihedral(p1,p2,p3,p4) - phi_a_0;" + "d_phi_b_wrap = d_phi_b - floor(d_phi_b / (2.0 * pi) + 0.5) * (2.0 * pi);" + "d_phi_b = dihedral(p2,p3,p4,p5) - phi_b_0;" + "d_phi_c_wrap = d_phi_c - floor(d_phi_c / (2.0 * pi) + 0.5) * (2.0 * pi);" + "d_phi_c = dihedral(p3,p4,p5,p6) - phi_c_0;" + f"pi = {numpy.pi}" +).replace(" ", "") + + +_ANGSTROM = openmm.unit.angstrom +_RADIANS = openmm.unit.radian + + +class _BoreschGeometry(typing.NamedTuple): + dist_0: openmm.unit.Quantity + + theta_a_0: openmm.unit.Quantity + theta_b_0: openmm.unit.Quantity + + phi_a_0: openmm.unit.Quantity + phi_b_0: openmm.unit.Quantity + phi_c_0: openmm.unit.Quantity + + +def _compute_boresch_geometry( + receptor_atoms: tuple[int, int, int], + ligand_atoms: tuple[int, int, int], + coords: openmm.unit.Quantity, +) -> _BoreschGeometry: + """Computes the equilibrium distances, angles, and dihedrals used by a Boresch + restraint.""" + + r1, r2, r3 = receptor_atoms + l1, l2, l3 = ligand_atoms + + coords = coords.value_in_unit(openmm.unit.angstrom) + + dist_0 = ( + compute_distances(coords, numpy.array([[r3, l1]])) + * _ANGSTROM + ) + + theta_a_0 = ( + compute_angles(coords, numpy.array([[r2, r3, l1]])) + * _RADIANS + ) + theta_b_0 = ( + compute_angles(coords, numpy.array([[r3, l1, l2]])) + * _RADIANS + ) + + phi_a_0 = ( + compute_dihedrals( + coords, numpy.array([[r1, r2, r3, l1]]) + ) + * _RADIANS + ) + phi_b_0 = ( + compute_dihedrals( + coords, numpy.array([[r2, r3, l1, l2]]) + ) + * _RADIANS + ) + phi_c_0 = ( + compute_dihedrals( + coords, numpy.array([[r3, l1, l2, l3]]) + ) + * _RADIANS + ) + + return _BoreschGeometry(dist_0, theta_a_0, theta_b_0, phi_a_0, phi_b_0, phi_c_0) + + +def create_boresch_restraint( + receptor_atoms: tuple[int, int, int], + ligand_atoms: tuple[int, int, int], + coords: openmm.unit.Quantity, + restraints_settings, + ctx_parameter: str | None = None, +) -> openmm.CustomCompoundBondForce: + """Creates a Boresch restraint force useful in aligning a receptor and ligand. + + Args: + settings: RestraintSettings + receptor_atoms: The indices of the receptor atoms to restrain. + ligand_atoms: The indices of the ligand atoms to restrain. + coords: The coordinates of the *full* system. + ctx_parameter: An optional context parameter to use to scale the strength of + the restraint. + + Returns: + The restraint force. + """ + n_particles = 6 # 3 receptor + 3 ligand + + energy_fn = _BORESCH_ENERGY_FN + + # if ctx_parameter is not None: + # energy_fn = f"{ctx_parameter} * {energy_fn}" + + force = openmm.CustomCompoundBondForce(n_particles, energy_fn) + + # if ctx_parameter is not None: + # force.addGlobalParameter(ctx_parameter, 1.0) + + geometry = _compute_boresch_geometry(receptor_atoms, ligand_atoms, coords) + + # Scale the k_theta_a + distance_0 = 5.0 # based on original SepTop implementation. + scale = (geometry.dist_0 / distance_0) ** 2 + + parameters = [] + + for key, value in [ + ("k_dist_a", restraints_settings.k_distance), + ("k_theta_a", restraints_settings.k_theta * scale), + ("k_theta_b", restraints_settings.k_theta), + ("k_phi_a", restraints_settings.k_theta), + ("k_phi_b", restraints_settings.k_theta), + ("k_phi_c", restraints_settings.k_theta), + ("dist_0", geometry.dist_0), + ("theta_a_0", geometry.theta_a_0), + ("theta_b_0", geometry.theta_b_0), + ("phi_a_0", geometry.phi_a_0), + ("phi_b_0", geometry.phi_b_0), + ("phi_c_0", geometry.phi_c_0), + ]: + force.addPerBondParameter(key) + parameters.append(value.value_in_unit_system(openmm.unit.md_unit_system)) + + force.addBond(receptor_atoms + ligand_atoms, parameters) + force.setUsesPeriodicBoundaryConditions(False) + force.setName("alignment-restraint") + force.setForceGroup(6) + + return force diff --git a/openfe/protocols/openmm_septop/femto_utils.py b/openfe/protocols/openmm_septop/femto_utils.py index 710f0930e..fb0869465 100644 --- a/openfe/protocols/openmm_septop/femto_utils.py +++ b/openfe/protocols/openmm_septop/femto_utils.py @@ -1,6 +1,11 @@ """Common functions for computing the internal coordinates (e.g. bond lengths).""" import numpy +import openmm +import openmm.app +import openmm.unit + +from .femto_constants import OpenMMForceGroup, OpenMMForceName, OpenMMPlatform def compute_bond_vectors( @@ -127,4 +132,43 @@ def compute_dihedrals(coords: numpy.ndarray, idxs: numpy.ndarray) -> numpy.ndarr if not is_batched: phi = phi[0] - return phi \ No newline at end of file + return phi + +def assign_force_groups(system: openmm.System): + """Assign standard force groups to forces in a system. + + Notes: + * COM, alignment, and position restraints are detected by their name. If their + name is not set to a ``OpenMMForceName``, they will be assigned a force group + of ``OTHER``. + + Args: + system: The system to modify in-place. + """ + + force: openmm.Force + + for force in system.getForces(): + if force.getName() == OpenMMForceName.COM_RESTRAINT: + force.setForceGroup(OpenMMForceGroup.COM_RESTRAINT) + elif force.getName() == OpenMMForceName.ALIGNMENT_RESTRAINT: + force.setForceGroup(OpenMMForceGroup.ALIGNMENT_RESTRAINT) + elif force.getName().startswith(OpenMMForceName.POSITION_RESTRAINT): + force.setForceGroup(OpenMMForceGroup.POSITION_RESTRAINT) + + elif isinstance(force, openmm.HarmonicBondForce): + force.setForceGroup(OpenMMForceGroup.BOND) + elif isinstance(force, openmm.HarmonicAngleForce): + force.setForceGroup(OpenMMForceGroup.ANGLE) + elif isinstance( + force, (openmm.PeriodicTorsionForce, openmm.CustomTorsionForce) + ): + force.setForceGroup(OpenMMForceGroup.DIHEDRAL) + elif isinstance(force, (openmm.NonbondedForce, openmm.CustomNonbondedForce)): + force.setForceGroup(OpenMMForceGroup.NONBONDED) + elif isinstance(force, openmm.ATMForce): + force.setForceGroup(OpenMMForceGroup.ATM) + elif isinstance(force, openmm.MonteCarloBarostat): + force.setForceGroup(OpenMMForceGroup.BAROSTAT) + else: + force.setForceGroup(OpenMMForceGroup.OTHER) \ No newline at end of file From 52992d8eeb478a5dd027a5fbee69923d6e8d18ef Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 20 Nov 2024 13:38:20 +0100 Subject: [PATCH 018/163] Change type check restraints --- openfe/protocols/openmm_septop/equil_septop_method.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 7107d1cdc..b7dfa9f74 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -868,6 +868,8 @@ def _add_restraints( traj = _get_mdtraj_from_openmm(topology, positions) ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1.to_openmm(), ligand_1.get_positions()) + ligand_2_mdtraj = _get_mdtraj_from_openmm(ligand_2.to_openmm(), + ligand_2.get_positions()) # Convert ligand indices to the indices in the ligand (start with zero) # CAVE: We're assuming here that the atom order did not change! # This needs to be tested!!! @@ -882,7 +884,7 @@ def _add_restraints( if not check_receptor_idxs( - traj, receptor_ref_idxs_1, ligand_2, ligand_2_ref_idxs + traj, receptor_ref_idxs_1, ligand_2_mdtraj, ligand_2_ref_idxs ): receptor_ref_idxs_2 = select_receptor_idxs( traj, ligand_2, ligand_2_ref_idxs) From 5a90c55cf10f66cb8e8fca2cb0e188f766461440 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 20 Nov 2024 14:02:20 +0100 Subject: [PATCH 019/163] Changes unitcell lengths --- .../openmm_septop/equil_septop_method.py | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index b7dfa9f74..47d80c961 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -91,7 +91,8 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): positions_in_mdtraj_format = np.array( omm_positions / omm_units.nanometers) mdtraj_system = md.Trajectory(positions_in_mdtraj_format, - mdtraj_topology) + mdtraj_topology, + unitcell_vectors=omm_topology.getPeriodicBoxVectors()) return mdtraj_system @@ -157,7 +158,6 @@ def _get_average(estimates): complex_ddG = _get_average(individual_estimates['complex']) return solv_ddG - complex_ddG - def get_uncertainty(self): """Get the relative free energy error for this calculation. @@ -817,20 +817,22 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ prot_settings = self._inputs['protocol'].settings - settings = {} - settings['forcefield_settings'] = prot_settings.complex_forcefield_settings - settings['thermo_settings'] = prot_settings.thermo_settings - settings['charge_settings'] = prot_settings.partial_charge_settings - settings['solvation_settings'] = prot_settings.complex_solvation_settings - settings['alchemical_settings'] = prot_settings.alchemical_settings - settings['lambda_settings'] = prot_settings.lambda_settings - settings['engine_settings'] = prot_settings.complex_engine_settings - settings['integrator_settings'] = prot_settings.integrator_settings - settings['equil_simulation_settings'] = prot_settings.complex_equil_simulation_settings - settings['equil_output_settings'] = prot_settings.complex_equil_output_settings - settings['simulation_settings'] = prot_settings.complex_simulation_settings - settings['output_settings'] = prot_settings.complex_output_settings - settings['restraint_settings'] = prot_settings.complex_restraints_settings + settings = { + 'forcefield_settings': prot_settings.complex_forcefield_settings, + 'thermo_settings': prot_settings.thermo_settings, + 'charge_settings': prot_settings.partial_charge_settings, + 'solvation_settings': prot_settings.complex_solvation_settings, + 'alchemical_settings': prot_settings.alchemical_settings, + 'lambda_settings': prot_settings.lambda_settings, + 'engine_settings': prot_settings.complex_engine_settings, + 'integrator_settings': prot_settings.integrator_settings, + 'equil_simulation_settings': + prot_settings.complex_equil_simulation_settings, + 'equil_output_settings': + prot_settings.complex_equil_output_settings, + 'simulation_settings': prot_settings.complex_simulation_settings, + 'output_settings': prot_settings.complex_output_settings, + 'restraint_settings': prot_settings.complex_restraints_settings} settings_validation.validate_timestep( settings['forcefield_settings'].hydrogen_mass, @@ -882,7 +884,6 @@ def _add_restraints( print(receptor_ref_idxs_1) receptor_ref_idxs_2 = receptor_ref_idxs_1 - if not check_receptor_idxs( traj, receptor_ref_idxs_1, ligand_2_mdtraj, ligand_2_ref_idxs ): @@ -1035,6 +1036,8 @@ def _update_positions( unit_cell = [i[inx] for inx, i in enumerate(unit_cell)] mdtraj_system_B = _get_mdtraj_from_openmm(omm_topology_B, positions_B) + print(mdtraj_system_B.unitcell_vectors) + print(mdtraj_system_B.unitcell_lengths) ligand_1_radius = np.linalg.norm( equ_pos_ligandA - equ_pos_ligandA.mean(axis=0), axis=1).max() From b4ffd2bea94610c23852111ae67d8b2da744223c Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 20 Nov 2024 14:20:33 +0100 Subject: [PATCH 020/163] Small test unit cell --- openfe/protocols/openmm_septop/equil_septop_method.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 47d80c961..37b3d7e16 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -90,9 +90,11 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): mdtraj_topology = md.Topology.from_openmm(omm_topology) positions_in_mdtraj_format = np.array( omm_positions / omm_units.nanometers) + unit_cell = omm_topology.getPeriodicBoxVectors() + unit_cell_length = [i[inx] for inx, i in enumerate(unit_cell)] mdtraj_system = md.Trajectory(positions_in_mdtraj_format, mdtraj_topology, - unitcell_vectors=omm_topology.getPeriodicBoxVectors()) + unitcell_lengths=unit_cell_length) return mdtraj_system From 0e32007cca9e534cdeb954dc42fa5c434a842a66 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 13:05:09 +0100 Subject: [PATCH 021/163] Update unit cell length --- openfe/protocols/openmm_septop/equil_septop_method.py | 7 ++++--- openfe/protocols/openmm_septop/femto_restraints.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 37b3d7e16..8b7c546ed 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -90,8 +90,10 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): mdtraj_topology = md.Topology.from_openmm(omm_topology) positions_in_mdtraj_format = np.array( omm_positions / omm_units.nanometers) - unit_cell = omm_topology.getPeriodicBoxVectors() - unit_cell_length = [i[inx] for inx, i in enumerate(unit_cell)] + unit_cell = omm_topology.getPeriodicBoxVectors() / omm_units.nanometers + print(unit_cell) + unit_cell_length = np.array([i[inx] for inx, i in enumerate(unit_cell)]) + print(unit_cell_length) mdtraj_system = md.Trajectory(positions_in_mdtraj_format, mdtraj_topology, unitcell_lengths=unit_cell_length) @@ -1038,7 +1040,6 @@ def _update_positions( unit_cell = [i[inx] for inx, i in enumerate(unit_cell)] mdtraj_system_B = _get_mdtraj_from_openmm(omm_topology_B, positions_B) - print(mdtraj_system_B.unitcell_vectors) print(mdtraj_system_B.unitcell_lengths) ligand_1_radius = np.linalg.norm( diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 382c9f959..9f950b96e 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -529,8 +529,8 @@ def select_receptor_idxs( r3_distances_per_frame.append(numpy.hstack([r3_r_distances, r3_l_distances])) # chosen to match the SepTop reference implementation at commit 3705ba5 - # max_distance = 0.8 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) - max_distance = 3 + max_distance = 0.8 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) + # max_distance = 3 r3_distances_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) From 90b1679f422de1012f07e453b233c9957ef69b47 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 13:38:13 +0100 Subject: [PATCH 022/163] Update unit cell length2 --- openfe/protocols/openmm_septop/equil_septop_method.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 8b7c546ed..83321f554 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -93,6 +93,8 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): unit_cell = omm_topology.getPeriodicBoxVectors() / omm_units.nanometers print(unit_cell) unit_cell_length = np.array([i[inx] for inx, i in enumerate(unit_cell)]) + if not unit_cell_length: + unit_cell_length = None print(unit_cell_length) mdtraj_system = md.Trajectory(positions_in_mdtraj_format, mdtraj_topology, @@ -1040,7 +1042,6 @@ def _update_positions( unit_cell = [i[inx] for inx, i in enumerate(unit_cell)] mdtraj_system_B = _get_mdtraj_from_openmm(omm_topology_B, positions_B) - print(mdtraj_system_B.unitcell_lengths) ligand_1_radius = np.linalg.norm( equ_pos_ligandA - equ_pos_ligandA.mean(axis=0), axis=1).max() From 3ca733da06775ae466ef9c7371071b5477b6e522 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 13:47:20 +0100 Subject: [PATCH 023/163] small fix --- openfe/protocols/openmm_septop/equil_septop_method.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 83321f554..b37becc0a 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -93,7 +93,7 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): unit_cell = omm_topology.getPeriodicBoxVectors() / omm_units.nanometers print(unit_cell) unit_cell_length = np.array([i[inx] for inx, i in enumerate(unit_cell)]) - if not unit_cell_length: + if not unit_cell_length.all(): unit_cell_length = None print(unit_cell_length) mdtraj_system = md.Trajectory(positions_in_mdtraj_format, From 82da7c82f70f3d6f3a3c984f32af56948f5c7799 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 14:16:37 +0100 Subject: [PATCH 024/163] More changes restraints --- .../openmm_septop/equil_septop_method.py | 19 +++++++++++-------- .../openmm_septop/equil_septop_settings.py | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index b37becc0a..6f09c2a00 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -90,11 +90,10 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): mdtraj_topology = md.Topology.from_openmm(omm_topology) positions_in_mdtraj_format = np.array( omm_positions / omm_units.nanometers) + unit_cell = omm_topology.getPeriodicBoxVectors() / omm_units.nanometers print(unit_cell) unit_cell_length = np.array([i[inx] for inx, i in enumerate(unit_cell)]) - if not unit_cell_length.all(): - unit_cell_length = None print(unit_cell_length) mdtraj_system = md.Trajectory(positions_in_mdtraj_format, mdtraj_topology, @@ -870,14 +869,18 @@ def _add_restraints( ligand_1, ligand_2, settings, - ligand_1_ref_idxs: list[int], - ligand_2_ref_idxs: list[int], + ligand_1_ref_idxs: tuple[int, int, int], + ligand_2_ref_idxs: tuple[int, int, int], ) -> openmm.System: - + # Get mdtraj object for system traj = _get_mdtraj_from_openmm(topology, positions) - ligand_1_mdtraj = _get_mdtraj_from_openmm(ligand_1.to_openmm(), ligand_1.get_positions()) - ligand_2_mdtraj = _get_mdtraj_from_openmm(ligand_2.to_openmm(), - ligand_2.get_positions()) + # Get mdtraj object for ligands + ligand_1_mdtraj = md.Trajectory( + np.array(ligand_1.get_positions() / omm_units.nanometers), + md.Topology.from_openmm(ligand_1.to_openmm())) + ligand_2_mdtraj = md.Trajectory( + np.array(ligand_2.get_positions() / omm_units.nanometers), + md.Topology.from_openmm(ligand_2.to_openmm())) # Convert ligand indices to the indices in the ligand (start with zero) # CAVE: We're assuming here that the atom order did not change! # This needs to be tested!!! diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index bfaab023e..aa0f508e8 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -43,8 +43,8 @@ class RestraintsSettings(SettingsBaseModel): """ Settings for the restraints. """ - k_distance: FloatQuantity['kcal/(mol*angstrom**2)'] = 1000 * unit.kilojoule_per_mole / unit.nanometer**2 - k_theta: Optional[FloatQuantity['kcal/(mol*rad**2)']] = 20 * unit.kilocalorie_per_mole / unit.radians**2 + k_distance: FloatQuantity['kJ/(mol*nanometers**2)'] = 1000 * unit.kilojoule_per_mole / unit.nanometer**2 + k_theta: Optional[FloatQuantity['kJ/(mol*rad**2)']] = 83.68 * unit.kilojoule_per_mole / unit.radians**2 From df637bc62c9f99f3deef9bccba843434732bd6ef Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 14:33:21 +0100 Subject: [PATCH 025/163] Print statements to help troubleshoot restraints --- openfe/protocols/openmm_septop/equil_septop_method.py | 2 +- openfe/protocols/openmm_septop/femto_restraints.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 6f09c2a00..c1fddea39 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -897,7 +897,7 @@ def _add_restraints( traj, receptor_ref_idxs_1, ligand_2_mdtraj, ligand_2_ref_idxs ): receptor_ref_idxs_2 = select_receptor_idxs( - traj, ligand_2, ligand_2_ref_idxs) + traj, ligand_2_mdtraj, ligand_2_ref_idxs) print(receptor_ref_idxs_2) force_A = create_boresch_restraint( diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 9f950b96e..94a20bf3e 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -588,6 +588,7 @@ def check_receptor_idxs( max_distance = 0.8 * (receptor.unitcell_lengths[-1][0] / 2) is_valid_distance = r3_distance_avg.max(axis=-1) < max_distance + print(is_valid_r1, is_valid_r2, is_valid_r3, is_valid_distance) return is_valid_r1 and is_valid_r2 and is_valid_r3 and is_valid_distance From c4671e40e9bbee388cb86f21349b6d22411fcc7f Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 14:58:25 +0100 Subject: [PATCH 026/163] Update indices --- openfe/protocols/openmm_septop/base.py | 23 +++++++++++-------- .../openmm_septop/equil_septop_method.py | 15 ++++++------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 62854578b..007bb74db 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -948,8 +948,10 @@ def _add_restraints( ligand_1: Optional[OFFMolecule.Topology], ligand_2: Optional[OFFMolecule.Topology], settings: Optional, - ligand_1_ref_idxs: list[int], - ligand_2_ref_idxs: list[int], + ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology + ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology + ligand_1_idxs: tuple[int, int, int], # indices from the full topology + ligand_2_idxs: tuple[int, int, int], # indices from the full topology ) -> openmm.System: """ Get new positions for the stateB after equilibration. @@ -1133,17 +1135,19 @@ def run(self, dry=False, verbose=True, self._set_positions(off_B, lig_B_pos) off_B.to_file('molB.pdb') - ligand_A_inxs, ligand_B_inxs = select_ligand_idxs(off_A, off_B) + ligand_A_ref_inxs, ligand_B_ref_inxs = select_ligand_idxs(off_A, off_B) - ligand_A_inxs = [atom_indices_AB_A[inx] for inx in ligand_A_inxs] - ligand_B_inxs = [atom_indices_AB_B[inx] for inx in ligand_B_inxs] + ligand_A_inxs = tuple([atom_indices_AB_A[inx] for inx in ligand_A_ref_inxs]) + ligand_B_inxs = tuple([atom_indices_AB_B[inx] for inx in ligand_B_ref_inxs]) print(ligand_A_inxs) print(ligand_B_inxs) system = self._add_restraints( omm_system_AB, positions_AB, omm_topology_AB, off_A, off_B, - settings, ligand_A_inxs, ligand_B_inxs) + settings, + ligand_A_ref_inxs, ligand_B_ref_inxs, + ligand_A_inxs, ligand_B_inxs) # Check that the restraints are correctly applied by running a short equilibration equ_positions_restraints = self._pre_equilibrate( system, omm_topology_AB, positions_AB, settings, dry @@ -1153,9 +1157,10 @@ def run(self, dry=False, verbose=True, # Here we could also apply REST - # # 7. Get lambdas - # lambdas = self._get_lambda_schedule(settings) - # + # 7. Get lambdas + lambdas = self._get_lambda_schedule(settings) + print(lambdas) + # # 10. Get compound and sampler states # sampler_states, cmp_states = self._get_states( # omm_system_AB, positions_AB, settings, diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index c1fddea39..65b942403 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -871,7 +871,10 @@ def _add_restraints( settings, ligand_1_ref_idxs: tuple[int, int, int], ligand_2_ref_idxs: tuple[int, int, int], + ligand_1_idxs: tuple[int, int, int], + ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: + # Get mdtraj object for system traj = _get_mdtraj_from_openmm(topology, positions) # Get mdtraj object for ligands @@ -881,11 +884,7 @@ def _add_restraints( ligand_2_mdtraj = md.Trajectory( np.array(ligand_2.get_positions() / omm_units.nanometers), md.Topology.from_openmm(ligand_2.to_openmm())) - # Convert ligand indices to the indices in the ligand (start with zero) - # CAVE: We're assuming here that the atom order did not change! - # This needs to be tested!!! - ligand_1_ref_idxs = [inx for inx, i in enumerate(ligand_1_ref_idxs)] - ligand_2_ref_idxs = [inx for inx, i in enumerate(ligand_2_ref_idxs)] + # Select the reference indices in the receptor receptor_ref_idxs_1 = select_receptor_idxs( traj, ligand_1_mdtraj, ligand_1_ref_idxs @@ -902,7 +901,7 @@ def _add_restraints( force_A = create_boresch_restraint( receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] - ligand_1_ref_idxs, + ligand_1_idxs, positions, settings["restraint_settings"], ) @@ -910,7 +909,7 @@ def _add_restraints( force_B = create_boresch_restraint( receptor_ref_idxs_2[::-1], # expects [r3, r2, r1], not [r1, r2, r3] - ligand_2_ref_idxs, + ligand_2_idxs, positions, settings["restraint_settings"], ) @@ -1077,6 +1076,8 @@ def _add_restraints( settings, ligand_1_ref_idxs: list[int], ligand_2_ref_idxs: list[int], + ligand_1_idxs: tuple[int, int, int], + ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: """Apply a distance restraints between the ligands. From ae1a2b4f56063f3814f9f6688c981553150c14c6 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 15:21:23 +0100 Subject: [PATCH 027/163] Fix units --- .../openmm_septop/equil_septop_settings.py | 6 +++--- .../protocols/test_openmm_septop_protocol.py | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index aa0f508e8..a1ffdc502 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -30,6 +30,7 @@ import numpy as np from pydantic.v1 import validator from typing import Optional +import openmm.unit as omm_unit class AlchemicalSettings(SettingsBaseModel): @@ -43,9 +44,8 @@ class RestraintsSettings(SettingsBaseModel): """ Settings for the restraints. """ - k_distance: FloatQuantity['kJ/(mol*nanometers**2)'] = 1000 * unit.kilojoule_per_mole / unit.nanometer**2 - k_theta: Optional[FloatQuantity['kJ/(mol*rad**2)']] = 83.68 * unit.kilojoule_per_mole / unit.radians**2 - + k_distance: FloatQuantity['kJ/(mol*nanometers**2)'] = 1000 * omm_unit.kilojoule_per_mole / omm_unit.nanometer**2 + k_theta: Optional[FloatQuantity['kJ/(mol*rad**2)']] = 83.68 * omm_unit.kilojoule_per_mole / omm_unit.radians ** 2 class LambdaSettings(SettingsBaseModel): diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 2d1a1b3be..3586ccf26 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -13,14 +13,15 @@ import numpy as np from numpy.testing import assert_allclose from openff.units import unit +from openfe.protocols.openmm_septop import gufe import openfe from openfe import ChemicalSystem, SolventComponent -from openfe.protocols import openmm_septop from openfe.protocols.openmm_septop import ( SepTopSolventSetupUnit, SepTopComplexSetupUnit, SepTopProtocol, + femto_restraints ) from openfe.protocols.openmm_utils import system_validation @@ -284,6 +285,21 @@ def test_validate_alchem_nonsmc( SepTopProtocol._validate_alchemical_components(alchem_comps) +# def test_create_boresch_restraint( +# bace_ligands, bace_protein_component +# ): +# Would have to create the OpenMM system to get the positions +# receptor_ref_idxs_1 = (492, 510, 3822) +# ligand_1_idxs = (6053, 6048, 6055) +# +# force_A = femto_restraints.create_boresch_restraint( +# receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] +# ligand_1_idxs, +# positions, +# settings["restraint_settings"], +# ) + + def test_setup(bace_ligands, bace_protein_component, tmpdir): # check system parametrisation works even if confgen fails s = SepTopProtocol.default_settings() From 5ca9923cf84b8d84e063f884fd6ea455b1ca198f Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 15:30:22 +0100 Subject: [PATCH 028/163] Update units --- .../openmm_septop/equil_septop_method.py | 13 +++++++++++-- .../openmm_septop/equil_septop_settings.py | 4 ++-- .../protocols/openmm_septop/femto_restraints.py | 15 ++++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 65b942403..dec589f31 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -67,6 +67,7 @@ create_boresch_restraint, ) from .femto_utils import assign_force_groups +from openff.units.openmm import to_openmm due.cite(Doi("10.5281/zenodo.596622"), @@ -899,11 +900,18 @@ def _add_restraints( traj, ligand_2_mdtraj, ligand_2_ref_idxs) print(receptor_ref_idxs_2) + # Convert restraint units to openmm + k_distance = to_openmm(settings["restraint_settings"].k_distance) + print(k_distance) + k_theta = to_openmm(settings["restraint_settings"].k_theta) + print(k_theta) + force_A = create_boresch_restraint( receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] ligand_1_idxs, positions, - settings["restraint_settings"], + k_distance, + k_theta ) system.addForce(force_A) force_B = create_boresch_restraint( @@ -911,7 +919,8 @@ def _add_restraints( # expects [r3, r2, r1], not [r1, r2, r3] ligand_2_idxs, positions, - settings["restraint_settings"], + k_distance, + k_theta ) system.addForce(force_B) diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index a1ffdc502..02491be5e 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -44,8 +44,8 @@ class RestraintsSettings(SettingsBaseModel): """ Settings for the restraints. """ - k_distance: FloatQuantity['kJ/(mol*nanometers**2)'] = 1000 * omm_unit.kilojoule_per_mole / omm_unit.nanometer**2 - k_theta: Optional[FloatQuantity['kJ/(mol*rad**2)']] = 83.68 * omm_unit.kilojoule_per_mole / omm_unit.radians ** 2 + k_distance: FloatQuantity['kJ/(mol*nanometers**2)'] = 1000 * unit.kilojoule_per_mole / unit.nanometer**2 + k_theta: Optional[FloatQuantity['kJ/(mol*rad**2)']] = 83.68 * unit.kilojoule_per_mole / unit.radians ** 2 class LambdaSettings(SettingsBaseModel): diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 94a20bf3e..3abbc9d8a 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -680,7 +680,8 @@ def create_boresch_restraint( receptor_atoms: tuple[int, int, int], ligand_atoms: tuple[int, int, int], coords: openmm.unit.Quantity, - restraints_settings, + k_distance, + k_theta, ctx_parameter: str | None = None, ) -> openmm.CustomCompoundBondForce: """Creates a Boresch restraint force useful in aligning a receptor and ligand. @@ -717,12 +718,12 @@ def create_boresch_restraint( parameters = [] for key, value in [ - ("k_dist_a", restraints_settings.k_distance), - ("k_theta_a", restraints_settings.k_theta * scale), - ("k_theta_b", restraints_settings.k_theta), - ("k_phi_a", restraints_settings.k_theta), - ("k_phi_b", restraints_settings.k_theta), - ("k_phi_c", restraints_settings.k_theta), + ("k_dist_a", k_distance), + ("k_theta_a", k_theta * scale), + ("k_theta_b", k_theta), + ("k_phi_a", k_theta), + ("k_phi_b", k_theta), + ("k_phi_c", k_theta), ("dist_0", geometry.dist_0), ("theta_a_0", geometry.theta_a_0), ("theta_b_0", geometry.theta_b_0), From ca725617109bcd7c3d4fd4c01591c9dc64868d7e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 21 Nov 2024 16:48:39 +0100 Subject: [PATCH 029/163] Small fixes --- .../protocols/openmm_septop/equil_septop_method.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index dec589f31..d445f6f34 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -31,6 +31,7 @@ from collections import defaultdict import gufe import openmm +import openmm.unit from gufe.components import Component import itertools import numpy as np @@ -499,7 +500,7 @@ def _default_settings(cls): k_theta=None, ), complex_restraints_settings=RestraintsSettings( - k_distance=8368.0 * unit.kilojoule_per_mole / unit.nanometer ** 2 + k_distance=8368.0 * unit.kilojoule_per_mole / unit.nanometer**2 ), ) @@ -1100,15 +1101,17 @@ def _add_restraints( coords = positions # Taking the middle reference atom distance = np.linalg.norm( - coords[ligand_1_ref_idxs[1]] - coords[ligand_2_ref_idxs[1]]) + coords[ligand_1_idxs[1]] - coords[ligand_2_idxs[1]]) print(distance) + k_distance = to_openmm(settings['restraint_settings'].k_distance) + force = openmm.HarmonicBondForce() force.addBond( - ligand_1_ref_idxs[1], - ligand_2_ref_idxs[1], + ligand_1_idxs[1], + ligand_2_idxs[1], distance * openmm.unit.nanometers, - settings['restraint_settings'].k_distance.m, + k_distance, ) force.setName("alignment_restraint") force.setForceGroup(6) From fe1bad617505a152854e6e56d3421e1e656b55c8 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 22 Nov 2024 11:39:26 +0100 Subject: [PATCH 030/163] Change lambda settings --- openfe/protocols/openmm_septop/base.py | 21 ++++---- .../openmm_septop/equil_septop_method.py | 36 ++++++------- .../openmm_septop/equil_septop_settings.py | 53 ++++++++++++++----- .../protocols/test_openmm_septop_protocol.py | 44 +++++++-------- 4 files changed, 90 insertions(+), 64 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 007bb74db..7eecdf9cb 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -534,15 +534,18 @@ def _get_lambda_schedule( """ lambdas = dict() - lambda_elec = settings['lambda_settings'].lambda_elec - lambda_vdw = settings['lambda_settings'].lambda_vdw - - # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 - # means fully interacting, not stateB - lambda_elec = [1 - x for x in lambda_elec] - lambda_vdw = [1 - x for x in lambda_vdw] - lambdas['lambda_electrostatics'] = lambda_elec - lambdas['lambda_sterics'] = lambda_vdw + lambdas['lambda_electrostatics_ligandA'] = settings[ + 'lambda_settings'].lambda_elec_ligandA + lambdas['lambda_sterics_ligandA'] = settings[ + 'lambda_settings'].lambda_vdw_ligandA + lambdas['lambda_restraints_ligandA'] = settings[ + 'lambda_settings'].lambda_restraints_ligandA + lambdas['lambda_electrostatics_ligandB'] = settings[ + 'lambda_settings'].lambda_elec_ligandB + lambdas['lambda_sterics_ligandB'] = settings[ + 'lambda_settings'].lambda_vdw_ligandB + lambdas['lambda_restraints_ligandB'] = settings[ + 'lambda_settings'].lambda_restraints_ligandB return lambdas diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index d445f6f34..bf43b5781 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -449,7 +449,7 @@ def _default_settings(cls): ), partial_charge_settings=OpenFFPartialChargeSettings(), solvent_solvation_settings=OpenMMSolvationSettings( - solvent_padding=1.5 * unit.nanometer + solvent_padding=1.8 * unit.nanometer ), complex_solvation_settings=OpenMMSolvationSettings(), complex_engine_settings=OpenMMEngineSettings(), @@ -629,28 +629,35 @@ def _validate_lambda_schedule( If there are non-zero values for restraints (lambda_restraints). """ - lambda_elec = lambda_settings.lambda_elec - lambda_vdw = lambda_settings.lambda_vdw - lambda_restraints = lambda_settings.lambda_restraints + lambda_elec_ligandA = lambda_settings.lambda_elec_ligandA + lambda_elec_ligandB = lambda_settings.lambda_elec_ligandB + lambda_vdw_ligandA = lambda_settings.lambda_vdw_ligandA + lambda_vdw_ligandB = lambda_settings.lambda_vdw_ligandB + lambda_restraints_ligandA = lambda_settings.lambda_restraints_ligandA + lambda_restraints_ligandB = lambda_settings.lambda_restraints_ligandB n_replicas = simulation_settings.n_replicas # Ensure that all lambda components have equal amount of windows - lambda_components = [lambda_vdw, lambda_elec, lambda_restraints] + lambda_components = [lambda_vdw_ligandA, lambda_vdw_ligandB, + lambda_elec_ligandA, lambda_elec_ligandB, + lambda_restraints_ligandA, lambda_restraints_ligandB] it = iter(lambda_components) the_len = len(next(it)) if not all(len(l) == the_len for l in it): errmsg = ( "Components elec, vdw, and restraints must have equal amount" - f" of lambda windows. Got {len(lambda_elec)} elec lambda" - f" windows, {len(lambda_vdw)} vdw lambda windows, and " - f"{len(lambda_restraints)} restraints lambda windows.") + f" of lambda windows. Got {len(lambda_elec_ligandA)} and " + f"{len(lambda_elec_ligandB)} elec lambda windows, " + f"{len(lambda_vdw_ligandA)} and {len(lambda_vdw_ligandB)} vdw " + f"lambda windows, and {len(lambda_restraints_ligandA)} and " + f"{len(lambda_restraints_ligandB)} restraints lambda windows.") raise ValueError(errmsg) # Ensure that number of overall lambda windows matches number of lambda # windows for individual components - if n_replicas != len(lambda_vdw): + if n_replicas != len(lambda_vdw_ligandB): errmsg = (f"Number of replicas {n_replicas} does not equal the" - f" number of lambda windows {len(lambda_vdw)}") + f" number of lambda windows {len(lambda_vdw_ligandB)}") raise ValueError(errmsg) # # Check if there are lambda windows with naked charges @@ -665,15 +672,6 @@ def _validate_lambda_schedule( # f"elec {lam} vdW {lambda_vdw[inx]}") # raise ValueError(errmsg) - # # Check if there are lambda windows with non-zero restraints - # if len([r for r in lambda_restraints if r != 0]) > 0: - # wmsg = ("Non-zero restraint lambdas applied. The absolute " - # "solvation protocol doesn't apply restraints, " - # "therefore restraints won't be applied. " - # f"Given lambda_restraints: {lambda_restraints}") - # logger.warning(wmsg) - # warnings.warn(wmsg) - def _create( self, stateA: ChemicalSystem, diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 02491be5e..40c6dd598 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -63,29 +63,52 @@ class LambdaSettings(SettingsBaseModel): the same length, defining all the windows of the transformation. """ - lambda_elec: list[float] = [0.0] * 8 + [0.25, 0.5, 0.75] + [1.0] * 8 + lambda_elec_ligandA: list[float] = [0.0] * 8 + [0.25, 0.5, 0.75] + [1.0] * 8 """ - List of floats of lambda values for the electrostatics. - Zero means state A and 1 means state B. + List of floats of the lambda values for the electrostatics of ligand A. + Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_restraints. """ - lambda_vdw: list[float] = np.linspace(1.0, 0.0, 8).tolist() + [0.0, 0.0, 0.0] + [0.0] * 8 + lambda_elec_ligandB: list[float] = [1.0] * 8 + [0.75, 0.5, 0.25] + [0.0] * 8 """ - List of floats of lambda values for the van der Waals. - Zero means state A and 1 means state B. + List of floats of the lambda values for the electrostatics of ligand B. + Zero means fully interacting and 1 means fully decoupled. + Length of this list needs to match length of lambda_vdw and + lambda_restraints. + """ + lambda_vdw_ligandA: list[float] = [0.0] * 8 + [ + 0.00, 0.0, 0.00] + np.linspace(0.0, 1.0, 8).tolist() + """ + List of floats of lambda values for the van der Waals of ligand A. + Zero means fully interacting and 1 means fully decoupled. + Length of this list needs to match length of lambda_elec and + lambda_restraints. + """ + lambda_vdw_ligandB: list[float] = np.linspace(1.0, 0.0, 8).tolist() + [ + 0.0, 0.0, 0.0] + [0.0] * 8 + """ + List of floats of lambda values for the van der Waals of ligand B. + Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_elec and lambda_restraints. """ - lambda_restraints: list[float] = [ - 0.0, 0.05, 0.3, 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, - ] + lambda_restraints_ligandA: list[float] = [ + 0.0, 0.05, 0.1, 0.3, 0.5, 0.75, 1.0, 1.0] + [1.0] * 3 + [1.0] * 8 + """ + List of floats of lambda values for the restraints of ligand A. + Zero means fully interacting and 1 means fully decoupled. + Length of this list needs to match length of lambda_vdw and lambda_elec. + """ + lambda_restraints_ligandB: list[float] = [1.0] * 8 + [1.0] * 3 + [ + 1.0, 0.95, 0.9, 0.7, 0.5, 0.25, 0.0, 0.0] """ - List of floats of lambda values for the restraints. - Zero means state A and 1 means state B. + List of floats of lambda values for the restraints of ligand B. + Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_elec. """ - @validator('lambda_elec', 'lambda_vdw', 'lambda_restraints') + @validator('lambda_elec_ligandA', 'lambda_elec_ligandB', + 'lambda_vdw_ligandA', 'lambda_vdw_ligandB', + 'lambda_restraints_ligandA', 'lambda_restraints_ligandB') def must_be_between_0_and_1(cls, v): for window in v: if not 0 <= window <= 1: @@ -94,7 +117,9 @@ def must_be_between_0_and_1(cls, v): raise ValueError(errmsg) return v - @validator('lambda_elec', 'lambda_vdw', 'lambda_restraints') + @validator('lambda_elec_ligandA', 'lambda_elec_ligandB', + 'lambda_vdw_ligandA', 'lambda_vdw_ligandB', + 'lambda_restraints_ligandA', 'lambda_restraints_ligandB') def must_be_monotonic(cls, v): difference = np.diff(v) diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 3586ccf26..daa9d357b 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -13,7 +13,6 @@ import numpy as np from numpy.testing import assert_allclose from openff.units import unit -from openfe.protocols.openmm_septop import gufe import openfe from openfe import ChemicalSystem, SolventComponent @@ -48,9 +47,9 @@ def test_incorrect_window_settings(val, default_settings): errmsg = "Lambda windows must be between 0 and 1." lambda_settings = default_settings.lambda_settings with pytest.raises(ValueError, match=errmsg): - lambda_settings.lambda_elec = val['elec'] - lambda_settings.lambda_vdw = val['vdw'] - lambda_settings.lambda_restraints = val['restraints'] + lambda_settings.lambda_elec_ligandA = val['elec'] + lambda_settings.lambda_vdw_ligandA = val['vdw'] + lambda_settings.lambda_restraints_ligandA = val['restraints'] @pytest.mark.parametrize('val', [ @@ -61,18 +60,22 @@ def test_monotonic_lambda_windows(val, default_settings): lambda_settings = default_settings.lambda_settings with pytest.raises(ValueError, match=errmsg): - lambda_settings.lambda_elec = val['elec'] - lambda_settings.lambda_vdw = val['vdw'] - lambda_settings.lambda_restraints = val['restraints'] + lambda_settings.lambda_elec_ligandA = val['elec'] + lambda_settings.lambda_vdw_ligandA = val['vdw'] + lambda_settings.lambda_restraints_ligandA = val['restraints'] @pytest.mark.parametrize('val', [ {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, ]) def test_validate_lambda_schedule_nreplicas(val, default_settings): - default_settings.lambda_settings.lambda_elec = val['elec'] - default_settings.lambda_settings.lambda_vdw = val['vdw'] - default_settings.lambda_settings.lambda_restraints = val['restraints'] + default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] + default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandB = val[ + 'restraints'] n_replicas = 3 default_settings.complex_simulation_settings.n_replicas = n_replicas errmsg = (f"Number of replicas {n_replicas} does not equal the" @@ -88,16 +91,14 @@ def test_validate_lambda_schedule_nreplicas(val, default_settings): {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, ]) def test_validate_lambda_schedule_nwindows(val, default_settings): - default_settings.lambda_settings.lambda_elec = val['elec'] - default_settings.lambda_settings.lambda_vdw = val['vdw'] - default_settings.lambda_settings.lambda_restraints = val['restraints'] + default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] n_replicas = 3 default_settings.complex_simulation_settings.n_replicas = n_replicas errmsg = ( - "Components elec, vdw, and restraints must have equal amount" - f" of lambda windows. Got {len(val['elec'])} elec lambda" - f" windows, {len(val['vdw'])} vdw lambda windows, and " - f"{len(val['restraints'])} restraints lambda windows.") + "Components elec, vdw, and restraints must have equal amount of lambda " + "windows. Got 3 and 19 elec lambda windows") with pytest.raises(ValueError, match=errmsg): SepTopProtocol._validate_lambda_schedule( default_settings.lambda_settings, @@ -308,9 +309,8 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): s.solvent_equil_simulation_settings.equilibration_length_nvt = 1 * unit.picosecond s.solvent_equil_simulation_settings.equilibration_length = 1 * unit.picosecond s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond - s.solvation_settings.box_shape = 'dodecahedron' - s.solvation_settings.solvent_padding = 1.2 * unit.nanometer - s.complex_forcefield_settings.nonbonded_cutoff = 0.9 * unit.nanometer + s.solvent_solvation_settings.box_shape = 'dodecahedron' + s.solvent_solvation_settings.solvent_padding = 1.5 * unit.nanometer protocol = SepTopProtocol( settings=s, @@ -338,8 +338,8 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units if isinstance(u, SepTopSolventSetupUnit)] - solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopComplexSetupUnit)] + # solv_setup_unit = [u for u in prot_units + # if isinstance(u, SepTopComplexSetupUnit)] # with tmpdir.as_cwd(): solv_setup_unit[0].run() From e4713a483a32b067690557f64b4b33f0d570cab3 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 26 Nov 2024 10:32:39 +0100 Subject: [PATCH 031/163] Serialize system --- openfe/protocols/openmm_septop/base.py | 65 +++++++++++++++++++-- openfe/protocols/openmm_septop/utils.py | 76 +++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 openfe/protocols/openmm_septop/utils.py diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 7eecdf9cb..03790cf81 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -57,6 +57,8 @@ from openfe.protocols.openmm_utils.omm_settings import ( BasePartialChargeSettings, ) +from openfe.protocols.openmm_rfe._rfe_utils.compute import get_openmm_platform + from openfe.protocols.openmm_afe.equil_afe_settings import ( BaseSolvationSettings, MultiStateSimulationSettings, OpenMMEngineSettings, @@ -73,6 +75,7 @@ from .femto_alchemy import apply_fep from .femto_restraints import select_ligand_idxs +from .utils import serialize, deserialize logger = logging.getLogger(__name__) @@ -1151,12 +1154,12 @@ def run(self, dry=False, verbose=True, settings, ligand_A_ref_inxs, ligand_B_ref_inxs, ligand_A_inxs, ligand_B_inxs) - # Check that the restraints are correctly applied by running a short equilibration - equ_positions_restraints = self._pre_equilibrate( - system, omm_topology_AB, positions_AB, settings, dry - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) + # # Check that the restraints are correctly applied by running a short equilibration + # equ_positions_restraints = self._pre_equilibrate( + # system, omm_topology_AB, positions_AB, settings, dry + # ) + # simtk.openmm.app.pdbfile.PDBFile.writeFile( + # omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) # Here we could also apply REST @@ -1164,6 +1167,56 @@ def run(self, dry=False, verbose=True, lambdas = self._get_lambda_schedule(settings) print(lambdas) + # 13. Get integrator + integrator = self._get_integrator( + settings['integrator_settings'], + settings['simulation_settings'], + ) + + # Set up context + platform = get_openmm_platform( + settings.engine_settings.compute_platform) + context = openmm.Context(system, integrator, platform) + context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) + context.setPositions(positions_AB) + + try: + # SERIALIZE SYSTEM, STATE, INTEGRATOR + # need to set velocities to temperature so serialized state + # features velocities, + # which is important for usability by the Folding@Home openmm-core + thermodynamic_settings = settings['thermo_settings'] + temperature = to_openmm(thermodynamic_settings.temperature) + context.setVelocitiesToTemperature(temperature) + + # state needs to include positions, forces, velocities, and energy + # to be usable by the Folding@Home openmm-core + state_ = context.getState( + getPositions=True, getForces=True, getVelocities=True, + getEnergy=True + ) + system_ = context.getSystem() + integrator_ = context.getIntegrator() + + system_outfile = shared_basepath / "system.xml.bz2" + state_outfile = shared_basepath / "state.xml.bz2" + integrator_outfile = shared_basepath / "integrator.xml.bz2" + + # Serialize system, state and integrator + serialize(system_, system_outfile) + serialize(state_, state_outfile) + serialize(integrator_, integrator_outfile) + + finally: + # Explicit cleanup for GPU resources + del context, integrator + + return { + "system": system_outfile, + "state": state_outfile, + "integrator": integrator_outfile, + } + # # 10. Get compound and sampler states # sampler_states, cmp_states = self._get_states( # omm_system_AB, positions_AB, settings, diff --git a/openfe/protocols/openmm_septop/utils.py b/openfe/protocols/openmm_septop/utils.py new file mode 100644 index 000000000..c6317ef8c --- /dev/null +++ b/openfe/protocols/openmm_septop/utils.py @@ -0,0 +1,76 @@ +import os +import pathlib + + +def serialize(item, filename: pathlib.Path): + """ + Serialize an OpenMM System, State, or Integrator. + + Parameters + ---------- + item : System, State, or Integrator + The thing to be serialized + filename : str + The filename to serialize to + """ + from openmm import XmlSerializer + + # Create parent directory if it doesn't exist + filename_basedir = filename.parent + if not filename_basedir.exists(): + os.makedirs(filename_basedir) + + if filename.suffix == ".gz": + import gzip + + with gzip.open(filename, mode="wb") as outfile: + serialized_thing = XmlSerializer.serialize(item) + outfile.write(serialized_thing.encode()) + if filename.suffix == ".bz2": + import bz2 + + with bz2.open(filename, mode="wb") as outfile: + serialized_thing = XmlSerializer.serialize(item) + outfile.write(serialized_thing.encode()) + else: + with open(filename, mode="w") as outfile: + serialized_thing = XmlSerializer.serialize(item) + outfile.write(serialized_thing) + + +def deserialize(filename: pathlib.Path): + """ + Deserialize an OpenMM System, State, or Integrator. + + Parameters + ---------- + item : System, State, or Integrator + The thing to be serialized + filename : str + The filename to serialize to + """ + from openmm import XmlSerializer + + # Create parent directory if it doesn't exist + filename_basedir = filename.parent + if not filename_basedir.exists(): + os.makedirs(filename_basedir) + + if filename.suffix == ".gz": + import gzip + + with gzip.open(filename, mode="rb") as infile: + serialized_thing = infile.read().decode() + item = XmlSerializer.deserialize(serialized_thing) + if filename.suffix == ".bz2": + import bz2 + + with bz2.open(filename, mode="rb") as infile: + serialized_thing = infile.read().decode() + item = XmlSerializer.deserialize(serialized_thing) + else: + with open(filename) as infile: + serialized_thing = infile.read() + item = XmlSerializer.deserialize(serialized_thing) + + return item \ No newline at end of file From 9eb40d22af765b949bc1696c30ba20faa319ed80 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 26 Nov 2024 10:41:10 +0100 Subject: [PATCH 032/163] small fix --- openfe/protocols/openmm_septop/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 03790cf81..0e7bdcb66 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1175,7 +1175,7 @@ def run(self, dry=False, verbose=True, # Set up context platform = get_openmm_platform( - settings.engine_settings.compute_platform) + settings['engine_settings'].compute_platform) context = openmm.Context(system, integrator, platform) context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) context.setPositions(positions_AB) From 6f53741a7114fbe1cd957e3e53ee9c6bd1ce9c74 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 26 Nov 2024 13:27:52 +0100 Subject: [PATCH 033/163] Only store system, topology --- openfe/protocols/openmm_septop/base.py | 101 +++++++++++++------------ 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 0e7bdcb66..b1775ffff 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1120,9 +1120,10 @@ def run(self, dry=False, verbose=True, positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] + topology_file = shared_basepath / 'topology.pdb' simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, positions_AB, - open('outputAB_new.pdb', + open(topology_file, 'w')) # 9. Create the alchemical system @@ -1163,58 +1164,62 @@ def run(self, dry=False, verbose=True, # Here we could also apply REST - # 7. Get lambdas - lambdas = self._get_lambda_schedule(settings) - print(lambdas) + system_outfile = shared_basepath / "system.xml.bz2" - # 13. Get integrator - integrator = self._get_integrator( - settings['integrator_settings'], - settings['simulation_settings'], - ) - - # Set up context - platform = get_openmm_platform( - settings['engine_settings'].compute_platform) - context = openmm.Context(system, integrator, platform) - context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) - context.setPositions(positions_AB) - - try: - # SERIALIZE SYSTEM, STATE, INTEGRATOR - # need to set velocities to temperature so serialized state - # features velocities, - # which is important for usability by the Folding@Home openmm-core - thermodynamic_settings = settings['thermo_settings'] - temperature = to_openmm(thermodynamic_settings.temperature) - context.setVelocitiesToTemperature(temperature) - - # state needs to include positions, forces, velocities, and energy - # to be usable by the Folding@Home openmm-core - state_ = context.getState( - getPositions=True, getForces=True, getVelocities=True, - getEnergy=True - ) - system_ = context.getSystem() - integrator_ = context.getIntegrator() - - system_outfile = shared_basepath / "system.xml.bz2" - state_outfile = shared_basepath / "state.xml.bz2" - integrator_outfile = shared_basepath / "integrator.xml.bz2" - - # Serialize system, state and integrator - serialize(system_, system_outfile) - serialize(state_, state_outfile) - serialize(integrator_, integrator_outfile) + # Serialize system, state and integrator + serialize(system, system_outfile) - finally: - # Explicit cleanup for GPU resources - del context, integrator + # # 7. Get lambdas + # lambdas = self._get_lambda_schedule(settings) + # print(lambdas) + # + # # 13. Get integrator + # integrator = self._get_integrator( + # settings['integrator_settings'], + # settings['simulation_settings'], + # ) + # + # # Set up context + # platform = get_openmm_platform( + # settings['engine_settings'].compute_platform) + # context = openmm.Context(system, integrator, platform) + # context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) + # context.setPositions(positions_AB) + # + # try: + # # SERIALIZE SYSTEM, STATE, INTEGRATOR + # # need to set velocities to temperature so serialized state + # # features velocities, + # # which is important for usability by the Folding@Home openmm-core + # thermodynamic_settings = settings['thermo_settings'] + # temperature = to_openmm(thermodynamic_settings.temperature) + # context.setVelocitiesToTemperature(temperature) + # + # # state needs to include positions, forces, velocities, and energy + # # to be usable by the Folding@Home openmm-core + # state_ = context.getState( + # getPositions=True, getForces=True, getVelocities=True, + # getEnergy=True + # ) + # system_ = context.getSystem() + # integrator_ = context.getIntegrator() + # + # system_outfile = shared_basepath / "system.xml.bz2" + # state_outfile = shared_basepath / "state.xml.bz2" + # integrator_outfile = shared_basepath / "integrator.xml.bz2" + # + # # Serialize system, state and integrator + # serialize(system_, system_outfile) + # serialize(state_, state_outfile) + # serialize(integrator_, integrator_outfile) + # + # finally: + # # Explicit cleanup for GPU resources + # del context, integrator return { "system": system_outfile, - "state": state_outfile, - "integrator": integrator_outfile, + "topology": topology_file, } # # 10. Get compound and sampler states From 0a5206ca8c19008efbe97ba4845fa711577ef87c Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 26 Nov 2024 13:59:47 +0100 Subject: [PATCH 034/163] Start of run unit --- openfe/protocols/openmm_septop/base.py | 43 ++++++++++++++++++- .../openmm_septop/equil_septop_method.py | 8 +++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index b1775ffff..e088e52c8 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -65,6 +65,7 @@ IntegratorSettings, LambdaSettings, MultiStateOutputSettings, ThermoSettings, OpenFFPartialChargeSettings, ) +from openfe.protocols.openmm_septop.equil_septop_settings import SepTopSettings from openfe.protocols.openmm_rfe._rfe_utils import compute from openfe.protocols.openmm_md.plain_md_methods import PlainMDProtocolUnit from ..openmm_utils import ( @@ -1301,6 +1302,46 @@ def run(self, dry=False, verbose=True, class BaseSepTopRunUnit(gufe.ProtocolUnit): """ - Empty place holder Base class for running ligand SepTop RBFE free energy transformations. """ + + def _execute(self, ctx: gufe.Context, *, protocol, setup, **inputs, + ) -> dict[str, Any]: + """ + Execute the simulation part of the Gromacs MD protocol. + + Parameters + ---------- + ctx : gufe.protocols.protocolunit.Context + The gufe context for the unit. + protocol : gufe.protocols.Protocol + The Protocol used to create this Unit. Contains key + information + such as the settings. + setup : gufe.protocols.ProtocolUnit + The SetupUnit + + Returns + ------- + dict : dict[str, str] + Dictionary with paths to ... + """ + log_system_probe(logging.INFO, paths=[ctx.scratch]) + + if ctx.shared is None: + # use cwd + shared_basepath = pathlib.Path(".") + else: + shared_basepath = ctx.shared + + protocol_settings: SepTopSettings = self._inputs[ + "protocol"].settings + serialized_system = setup.outputs["system"] + serialized_topology = setup.outputs["topology"] + + system = deserialize(serialized_system) + topology = simtk.openmm.app.pdbfile.PDBFile(serialized_topology).topology + + print(system, topology) + + return diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index bf43b5781..54631ef22 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -435,7 +435,7 @@ def _default_settings(cls): a set of default settings """ return SepTopSettings( - protocol_repeats=3, + protocol_repeats=1, solvent_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), complex_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings( nonbonded_method='nocutoff', @@ -1133,3 +1133,9 @@ def _execute( 'simtype': 'solvent', **outputs } + + +class SepTopSolventRunUnit(BaseSepTopRunUnit): + """ + Protocol Unit for the solvent phase of an relative SepTop free energy + """ From 5d0c10f9c346494007f627b6c24606cfa521da22 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 26 Nov 2024 14:11:03 +0100 Subject: [PATCH 035/163] Add run unit to create method --- .../openmm_septop/equil_septop_method.py | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 54631ef22..4d0622882 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -709,7 +709,7 @@ def _create( # Create list units for complex and solvent transforms - solvent_units = [ + solvent_setup = [ SepTopSolventSetupUnit( protocol=self, stateA=stateA, @@ -722,10 +722,19 @@ def _create( for i in range(self.settings.protocol_repeats) ] - complex_units = [ + solvent_run = [ + SepTopSolventRunUnit( + protocol=self, + setup=solvent_setup[i], + generation=0, repeat_id=int(uuid.uuid4()), + name=(f"SepTop RBFE, {alchname} solvent leg: " + f"repeat {i} generation 0"), + ) + for i in range(self.settings.protocol_repeats) + ] + + complex_setup = [ SepTopComplexSetupUnit( - # These don't really reflect the actual transform - # Should these be overriden to be ChemicalSystem{smc} -> ChemicalSystem{} ? protocol=self, stateA=stateA, stateB=stateB, @@ -737,7 +746,18 @@ def _create( for i in range(self.settings.protocol_repeats) ] - return solvent_units + complex_units + complex_run = [ + SepTopComplexRunUnit( + protocol=self, + setup=complex_setup[i], + generation=0, repeat_id=int(uuid.uuid4()), + name=(f"SepTop RBFE, {alchname} complex leg: " + f"repeat {i} generation 0"), + ) + for i in range(self.settings.protocol_repeats) + ] + + return solvent_setup + solvent_run + complex_setup + complex_run def _gather( self, protocol_dag_results: Iterable[gufe.ProtocolDAGResult] @@ -1139,3 +1159,9 @@ class SepTopSolventRunUnit(BaseSepTopRunUnit): """ Protocol Unit for the solvent phase of an relative SepTop free energy """ + + +class SepTopComplexRunUnit(BaseSepTopRunUnit): + """ + Protocol Unit for the solvent phase of an relative SepTop free energy + """ From 8cafbe844dd713f02506d9385a796fa46bf469e3 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 26 Nov 2024 14:16:04 +0100 Subject: [PATCH 036/163] Add missing import --- openfe/protocols/openmm_septop/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index e088e52c8..5e0621089 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -57,6 +57,7 @@ from openfe.protocols.openmm_utils.omm_settings import ( BasePartialChargeSettings, ) +from openfe.utils import log_system_probe from openfe.protocols.openmm_rfe._rfe_utils.compute import get_openmm_platform from openfe.protocols.openmm_afe.equil_afe_settings import ( From 2829604192b0ce2bd3d3a823b13e91f89bc8c55b Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 13:35:31 +0100 Subject: [PATCH 037/163] Write run unit --- openfe/protocols/openmm_septop/base.py | 1381 +++++++++-------- .../openmm_septop/equil_septop_method.py | 206 ++- .../openmm_septop/equil_septop_settings.py | 5 +- .../protocols/openmm_septop/femto_alchemy.py | 8 +- .../openmm_septop/femto_restraints.py | 9 +- openfe/protocols/openmm_septop/utils.py | 337 +++- 6 files changed, 1252 insertions(+), 694 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 5e0621089..f05d8a4f9 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -36,8 +36,7 @@ from openmmtools.states import (SamplerState, ThermodynamicState, create_thermodynamic_state_protocol, ) -from openmmtools.alchemy import (AlchemicalRegion, AbsoluteAlchemicalFactory, - AlchemicalState, ) +from .utils import AlchemicalState from typing import Optional from openmm import app from openmm import unit as omm_unit @@ -78,6 +77,7 @@ from .femto_alchemy import apply_fep from .femto_restraints import select_ligand_idxs from .utils import serialize, deserialize +from .femto_equilibrate import create_state_dicts logger = logging.getLogger(__name__) @@ -517,796 +517,744 @@ def _get_omm_objects( ) return topology, system, positions - def _get_lambda_schedule( - self, settings: dict[str, SettingsBaseModel] - ) -> dict[str, npt.NDArray]: + @staticmethod + def _get_atom_indices(omm_topology, comp_resids): + comp_atomids = {} + for key, values in comp_resids.items(): + atom_indices = [] + for residue in omm_topology.residues(): + if residue.index in values: + atom_indices.extend([atom.index for atom in residue.atoms()]) + comp_atomids[key] = atom_indices + return comp_atomids + + @staticmethod + def _update_positions( + omm_topology_A, omm_topology_B, positions_A, positions_B, + atom_indices_A, atom_indices_B, + ) -> npt.NDArray: """ - Create the lambda schedule + Get new positions for the stateB after equilibration. - Parameters - ---------- - settings : dict[str, SettingsBaseModel] - Settings for the unit. + Note + ---- + Must be implemented in the child class. + In the complex phase, this is achieved by aligning the proteins, + in the solvent phase, the ligand B are offset from ligand A + """ + ... - Returns - ------- - lambdas : dict[str, npt.NDArray] + @staticmethod + def _set_positions(off_topology, positions): + off_topology.clear_positions() + off_topology.set_positions(positions) + return off_topology + + @staticmethod + def _add_restraints( + system: openmm.System, + positions: np.array, + topology: Optional[openmm.Topology], + ligand_1: Optional[OFFMolecule.Topology], + ligand_2: Optional[OFFMolecule.Topology], + settings: Optional, + ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology + ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology + ligand_1_idxs: tuple[int, int, int], # indices from the full topology + ligand_2_idxs: tuple[int, int, int], # indices from the full topology + ) -> openmm.System: + """ + Get new positions for the stateB after equilibration. - TODO + Note ---- - * Augment this by using something akin to the RFE protocol's - LambdaProtocol + Must be implemented in the child class. + In the complex phase, this is achieved by aligning the proteins, + in the solvent phase, the ligand B are offset from ligand A """ - lambdas = dict() - - lambdas['lambda_electrostatics_ligandA'] = settings[ - 'lambda_settings'].lambda_elec_ligandA - lambdas['lambda_sterics_ligandA'] = settings[ - 'lambda_settings'].lambda_vdw_ligandA - lambdas['lambda_restraints_ligandA'] = settings[ - 'lambda_settings'].lambda_restraints_ligandA - lambdas['lambda_electrostatics_ligandB'] = settings[ - 'lambda_settings'].lambda_elec_ligandB - lambdas['lambda_sterics_ligandB'] = settings[ - 'lambda_settings'].lambda_vdw_ligandB - lambdas['lambda_restraints_ligandB'] = settings[ - 'lambda_settings'].lambda_restraints_ligandB - - return lambdas + ... - def _get_states( - self, - alchemical_system: openmm.System, - positions: openmm.unit.Quantity, - settings: dict[str, SettingsBaseModel], - lambdas: dict[str, npt.NDArray], - solvent_comp: Optional[SolventComponent], - ) -> tuple[list[SamplerState], list[ThermodynamicState]]: + + def run(self, dry=False, verbose=True, + scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: """ - Get a list of sampler and thermodynmic states from an - input alchemical system. + Run the SepTop free energy calculation. Parameters ---------- - alchemical_system : openmm.System - Alchemical system to get states for. - positions : openmm.unit.Quantity - Positions of the alchemical system. - settings : dict[str, SettingsBaseModel] - A dictionary of settings for the protocol unit. - lambdas : dict[str, npt.NDArray] - A dictionary of lambda scales. - solvent_comp : Optional[SolventComponent] - The solvent component of the system, if there is one. + dry : bool + Do a dry run of the calculation, creating all necessary alchemical + system components (topology, system, sampler, etc...) but without + running the simulation, default False + verbose : bool + Verbose output of the simulation progress. Output is provided via + INFO level logging, default True + scratch_basepath : pathlib.Path + Path to the scratch (temporary) directory space. + shared_basepath : pathlib.Path + Path to the shared (persistent) directory space. Returns ------- - sampler_states : list[SamplerState] - A list of SamplerStates for each replica in the system. - cmp_states : list[ThermodynamicState] - A list of ThermodynamicState for each replica in the system. + dict + Outputs created in the basepath directory or the debug objects + (i.e. sampler) if ``dry==True``. """ - alchemical_state = AlchemicalState.from_system(alchemical_system) - # Set up the system constants - temperature = settings['thermo_settings'].temperature - pressure = settings['thermo_settings'].pressure - constants = dict() - constants['temperature'] = ensure_quantity(temperature, 'openmm') - if solvent_comp is not None: - constants['pressure'] = ensure_quantity(pressure, 'openmm') - - cmp_states = create_thermodynamic_state_protocol( - alchemical_system, protocol=lambdas, - constants=constants, composable_states=[alchemical_state], - ) - - sampler_state = SamplerState(positions=positions) - if alchemical_system.usesPeriodicBoundaryConditions(): - box = alchemical_system.getDefaultPeriodicBoxVectors() - sampler_state.box_vectors = box - - sampler_states = [sampler_state for _ in cmp_states] + # 0. General preparation tasks + self._prepare(verbose, scratch_basepath, shared_basepath) - return sampler_states, cmp_states + # 1. Get components + self.logger.info("Creating and setting up the OpenMM systems") + alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() + # 2. Get settings + settings = self._handle_settings() - def _get_reporter( - self, - topology: app.Topology, - positions: openmm.unit.Quantity, - simulation_settings: MultiStateSimulationSettings, - output_settings: MultiStateOutputSettings, - ) -> multistate.MultiStateReporter: - """ - Get a MultistateReporter for the simulation you are running. + # 5. Get system generator + system_generator = self._get_system_generator(settings, solv_comp) - Parameters - ---------- - 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: MultiStateOutputSettings - Output settings for the simulations + # 6. Get smcs for the different states and the common smcs + smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} + smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} + smc_off_both = {m: m.to_openff() for m in smc_comps + if (m not in alchem_comps["stateA"] and m not in + alchem_comps["stateB"])} + smc_comps_A = smc_off_A | smc_off_both + smc_comps_B = smc_off_B | smc_off_both + smc_comps_AB = smc_off_A | smc_off_B | smc_off_both - Returns - ------- - reporter : multistate.MultiStateReporter - The reporter for the simulation. - """ - mdt_top = mdt.Topology.from_openmm(topology) + # 7. Assign partial charges here to only do it once for smcs in stateA + # and stateB (hence only charge e.g. cofactors ones) + self._assign_partial_charges(settings['charge_settings'], smc_comps_AB) - selection_indices = mdt_top.select( - output_settings.output_indices + # 8. Get modeller for stateA, stateB, and stateAB + system_modeller_A, comp_resids_A = self._get_modeller( + prot_comp, solv_comp, smc_comps_A, + system_generator, settings['solvation_settings'], ) - - 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, + system_modeller_B, comp_resids_B = self._get_modeller( + prot_comp, solv_comp, smc_comps_B, + system_generator, settings['solvation_settings'], ) - reporter = multistate.MultiStateReporter( - storage=nc, - analysis_particle_indices=selection_indices, - checkpoint_interval=chk_intervals, - checkpoint_storage=chk, + # Get modeller B only ligand B + modeller_ligandB, comp_resids_ligB = self._get_modeller( + None, None, smc_off_B, + system_generator, settings['solvation_settings'], ) - # Write out the structure's PDB whilst we're here - if len(selection_indices) > 0: - traj = mdt.Trajectory( - positions[selection_indices, :], - mdt_top.subset(selection_indices), - ) - traj.save_pdb( - self.shared_basepath / output_settings.output_structure - ) - - return reporter - - - def _get_ctx_caches( - self, - engine_settings: OpenMMEngineSettings - ) -> tuple[openmmtools.cache.ContextCache, openmmtools.cache.ContextCache]: - """ - Set the context caches based on the chosen platform + # Take the modeller from system A --> every water/ion should be in + # the same location + system_modeller_AB = copy.copy(system_modeller_A) + system_modeller_AB.add(modeller_ligandB.topology, + modeller_ligandB.positions) - Parameters - ---------- - engine_settings : OpenMMEngineSettings, + # We assume that modeller.add will always put the ligand B towards + # the end of the residues + resids_A = list(itertools.chain(*comp_resids_A.values())) + resids_AB = [r.index for r in system_modeller_AB.topology.residues()] + diff_resids = list(set(resids_AB) - set(resids_A)) + comp_resids_AB = comp_resids_A | {alchem_comps["stateB"][0]: np.array(diff_resids)} - Returns - ------- - energy_context_cache : openmmtools.cache.ContextCache - The energy state context cache. - sampler_context_cache : openmmtools.cache.ContextCache - The sampler state context cache. - """ - platform = compute.get_openmm_platform( - engine_settings.compute_platform, + # 5. Get OpenMM topology, positions and system + omm_topology_A, omm_system_A, positions_A = self._get_omm_objects( + system_modeller_A, system_generator, list(smc_comps_A.values()) ) - - energy_context_cache = openmmtools.cache.ContextCache( - capacity=None, time_to_live=None, platform=platform, + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_A, + positions_A, + open('outputA.pdb', + 'w')) + omm_topology_B, omm_system_B, positions_B = self._get_omm_objects( + system_modeller_B, system_generator, list(smc_comps_B.values()) ) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, + positions_B, + open('outputB.pdb', + 'w')) - sampler_context_cache = openmmtools.cache.ContextCache( - capacity=None, time_to_live=None, platform=platform, + omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( + system_modeller_AB, system_generator, list(smc_comps_AB.values()) ) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, + positions_AB, + open('outputAB.pdb', 'w')) - return energy_context_cache, sampler_context_cache - - @staticmethod - def _get_integrator( - integrator_settings: IntegratorSettings, - simulation_settings: MultiStateSimulationSettings - ) -> openmmtools.mcmc.LangevinDynamicsMove: + # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) + self.logger.info("Pre-equilibrating the systems") + equ_positions_A = self._pre_equilibrate( + omm_system_A, omm_topology_A, positions_A, settings, dry + ) + equ_positions_B = self._pre_equilibrate( + omm_system_B, omm_topology_B, positions_B, settings, dry + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile( + omm_topology_A, equ_positions_A, open('outputA_equ.pdb', 'w')) + simtk.openmm.app.pdbfile.PDBFile.writeFile( + omm_topology_B, equ_positions_B, open('outputB_equ.pdb', 'w')) + + # 7. Get all the right atom indices for alignments + comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) + all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) + comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) + + # Get the system A atom indices of ligand A + atom_indices_A = comp_atomids_A[alchem_comps['stateA'][0]] + # Get the system B atom indices of ligand B + atom_indices_B = comp_atomids_B[alchem_comps['stateB'][0]] + + # 8. Update the positions of system B: + # - complex: Align protein + # - solvent: Offset ligand B with respect to ligand A + updated_positions_B = self._update_positions( + omm_topology_A, omm_topology_B, equ_positions_A, equ_positions_B, + atom_indices_A, atom_indices_B) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, + updated_positions_B, + open('outputB_new.pdb', + 'w')) + + # Get atom indices for ligand A and ligand B and the solvent in the + # system AB + comp_atomids_AB = self._get_atom_indices(omm_topology_AB, comp_resids_AB) + atom_indices_AB_B = comp_atomids_AB[alchem_comps['stateB'][0]] + atom_indices_AB_A = comp_atomids_AB[alchem_comps['stateA'][0]] + + # Update positions from AB system + positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A + positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, + :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] + + topology_file = shared_basepath / 'topology.pdb' + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, + positions_AB, + open(topology_file, + 'w')) + + # 9. Create the alchemical system + self.logger.info("Creating the alchemical system and applying restraints") + apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) + + # 10. Apply Restraints + off_A = alchem_comps["stateA"][0].to_openff().to_topology() + lig_A_pos = positions_AB[atom_indices_AB_A[0]:atom_indices_AB_A[-1]+1, :] / omm_units.nanometers * unit.nanometer + self._set_positions(off_A, lig_A_pos) + off_A.to_file('molA.pdb') + off_B = alchem_comps["stateB"][0].to_openff().to_topology() + lig_B_pos = positions_AB[ + atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, + :] / omm_units.nanometers * unit.nanometer + self._set_positions(off_B, lig_B_pos) + off_B.to_file('molB.pdb') + + ligand_A_ref_inxs, ligand_B_ref_inxs = select_ligand_idxs(off_A, off_B) + + ligand_A_inxs = tuple([atom_indices_AB_A[inx] for inx in ligand_A_ref_inxs]) + ligand_B_inxs = tuple([atom_indices_AB_B[inx] for inx in ligand_B_ref_inxs]) + print(ligand_A_inxs) + print(ligand_B_inxs) + + system = self._add_restraints( + omm_system_AB, positions_AB, omm_topology_AB, + off_A, off_B, + settings, + ligand_A_ref_inxs, ligand_B_ref_inxs, + ligand_A_inxs, ligand_B_inxs) + # # Check that the restraints are correctly applied by running a short equilibration + # equ_positions_restraints = self._pre_equilibrate( + # system, omm_topology_AB, positions_AB, settings, dry + # ) + # simtk.openmm.app.pdbfile.PDBFile.writeFile( + # omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) + + # Here we could also apply REST + + system_outfile = shared_basepath / "system.xml.bz2" + + # Serialize system, state and integrator + serialize(system, system_outfile) + + # # Set up context + # platform = get_openmm_platform( + # settings['engine_settings'].compute_platform) + # context = openmm.Context(system, integrator, platform) + # context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) + # context.setPositions(positions_AB) + # + # try: + # # SERIALIZE SYSTEM, STATE, INTEGRATOR + # # need to set velocities to temperature so serialized state + # # features velocities, + # # which is important for usability by the Folding@Home openmm-core + # thermodynamic_settings = settings['thermo_settings'] + # temperature = to_openmm(thermodynamic_settings.temperature) + # context.setVelocitiesToTemperature(temperature) + # + # # state needs to include positions, forces, velocities, and energy + # # to be usable by the Folding@Home openmm-core + # state_ = context.getState( + # getPositions=True, getForces=True, getVelocities=True, + # getEnergy=True + # ) + # system_ = context.getSystem() + # integrator_ = context.getIntegrator() + # + # system_outfile = shared_basepath / "system.xml.bz2" + # state_outfile = shared_basepath / "state.xml.bz2" + # integrator_outfile = shared_basepath / "integrator.xml.bz2" + # + # # Serialize system, state and integrator + # serialize(system_, system_outfile) + # serialize(state_, state_outfile) + # serialize(integrator_, integrator_outfile) + # + # finally: + # # Explicit cleanup for GPU resources + # del context, integrator + + return { + "system": system_outfile, + "topology": topology_file, + } + + +class BaseSepTopRunUnit(gufe.ProtocolUnit): + """ + Base class for running ligand SepTop RBFE free energy transformations. + """ + + @abc.abstractmethod + def _get_components(self) -> tuple[dict[str, list[Component]], + Optional[gufe.SolventComponent], + Optional[gufe.ProteinComponent], + dict[ + SmallMoleculeComponent, + OFFMolecule]]: """ - Return a LangevinDynamicsMove integrator + Get the relevant components to create the alchemical system with. - Parameters - ---------- - integrator_settings : IntegratorSettings - simulation_settings : MultiStateSimulationSettings + Note + ---- + Must be implemented in the child class. + """ + ... - Returns - ------- - integrator : openmmtools.mcmc.LangevinDynamicsMove - A configured integrator object. + + @abc.abstractmethod + def _handle_settings(self): """ - steps_per_iteration = settings_validation.convert_steps_per_iteration( - simulation_settings, integrator_settings - ) + Get a dictionary with the following entries: + * forcefield_settings : OpenMMSystemGeneratorFFSettings + * thermo_settings : ThermoSettings + * solvation_settings : BaseSolvationSettings + * alchemical_settings : AlchemicalSettings + * lambda_settings : LambdaSettings + * engine_settings : OpenMMEngineSettings + * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings + * simulation_settings : MultiStateSimulationSettings + * output_settings : MultiStateOutputSettings - integrator = openmmtools.mcmc.LangevinDynamicsMove( - timestep=to_openmm(integrator_settings.timestep), - 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, - ) + Settings may change depending on what type of simulation you are + running. Cherry pick them and return them to be available later on. - return integrator + This method should also add various validation checks as necessary. - @staticmethod - def _get_sampler( - integrator: openmmtools.mcmc.LangevinDynamicsMove, - reporter: openmmtools.multistate.MultiStateReporter, - simulation_settings: MultiStateSimulationSettings, - thermo_settings: ThermoSettings, - cmp_states: list[ThermodynamicState], - sampler_states: list[SamplerState], - energy_context_cache: openmmtools.cache.ContextCache, - sampler_context_cache: openmmtools.cache.ContextCache - ) -> multistate.MultiStateSampler: + Note + ---- + Must be implemented in the child class. """ - Get a sampler based on the equilibrium sampling method requested. + ... + + + def _get_lambda_schedule( + self, settings: dict[str, SettingsBaseModel] + ) -> dict[str, npt.NDArray]: + """ + Create the lambda schedule Parameters ---------- - integrator : openmmtools.mcmc.LangevinDynamicsMove - The simulation integrator. - reporter : openmmtools.multistate.MultiStateReporter - The reporter to hook up to the sampler. - 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] - A list of sampler states. - energy_context_cache : openmmtools.cache.ContextCache - Context cache for the energy states. - sampler_context_cache : openmmtool.cache.ContextCache - Context cache for the sampler states. + settings : dict[str, SettingsBaseModel] + Settings for the unit. Returns ------- - 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_from_kcal_per_mole_to_kT( - thermo_settings.temperature, - simulation_settings.early_termination_target_error, - ) - - # Select the right sampler - # Note: doesn't need else, settings already validates choices - if simulation_settings.sampler_method.lower() == "repex": - sampler = multistate.ReplicaExchangeSampler( - mcmc_moves=integrator, - online_analysis_interval=rta_its, - online_analysis_target_error=et_target_err, - online_analysis_minimum_iterations=rta_min_its - ) - elif simulation_settings.sampler_method.lower() == "sams": - sampler = multistate.SAMSSampler( - mcmc_moves=integrator, - 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 simulation_settings.sampler_method.lower() == 'independent': - sampler = multistate.MultiStateSampler( - mcmc_moves=integrator, - online_analysis_interval=rta_its, - online_analysis_target_error=et_target_err, - online_analysis_minimum_iterations=rta_min_its, - ) - - sampler.create( - thermodynamic_states=cmp_states, - sampler_states=sampler_states, - storage=reporter - ) + lambdas : dict[str, npt.NDArray] - sampler.energy_context_cache = energy_context_cache - sampler.sampler_context_cache = sampler_context_cache + Note + ---- + Must be implemented in the child class. + """ + ... - return sampler - def _run_simulation( + def _get_states( self, - sampler: multistate.MultiStateSampler, - reporter: multistate.MultiStateReporter, + alchemical_system: openmm.System, + positions: openmm.unit.Quantity, settings: dict[str, SettingsBaseModel], - dry: bool - ): + lambdas: dict[str, npt.NDArray], + solvent_comp: Optional[SolventComponent], + ) -> tuple[list[SamplerState], list[ThermodynamicState]]: """ - Run the simulation. + Get a list of sampler and thermodynmic states from an + input alchemical system. Parameters ---------- - sampler : multistate.MultiStateSampler - The sampler associated with the simulation to run. - reporter : multistate.MultiStateReporter - The reporter associated with the sampler. + alchemical_system : openmm.System + Alchemical system to get states for. + positions : openmm.unit.Quantity + Positions of the alchemical system. settings : dict[str, SettingsBaseModel] - The dictionary of settings for the protocol. - dry : bool - Whether or not to dry run the simulation + A dictionary of settings for the protocol unit. + lambdas : dict[str, npt.NDArray] + A dictionary of lambda scales. + solvent_comp : Optional[SolventComponent] + The solvent component of the system, if there is one. Returns ------- - unit_results_dict : Optional[dict] - A dictionary containing all the free energy results, - if not a dry run. + sampler_states : list[SamplerState] + A list of SamplerStates for each replica in the system. + cmp_states : list[ThermodynamicState] + A list of ThermodynamicState for each replica in the system. """ - # Get the relevant simulation steps - mc_steps = settings_validation.convert_steps_per_iteration( - simulation_settings=settings['simulation_settings'], - integrator_settings=settings['integrator_settings'], - ) + alchemical_state = AlchemicalState.from_system(alchemical_system) + # Set up the system constants + temperature = settings['thermo_settings'].temperature + pressure = settings['thermo_settings'].pressure + constants = dict() + constants['temperature'] = ensure_quantity(temperature, 'openmm') + if solvent_comp is not None: + constants['pressure'] = ensure_quantity(pressure, 'openmm') - equil_steps = settings_validation.get_simsteps( - sim_length=settings['simulation_settings'].equilibration_length, - timestep=settings['integrator_settings'].timestep, - mc_steps=mc_steps, - ) - prod_steps = settings_validation.get_simsteps( - sim_length=settings['simulation_settings'].production_length, - timestep=settings['integrator_settings'].timestep, - mc_steps=mc_steps, + cmp_states = create_thermodynamic_state_protocol( + alchemical_system, protocol=lambdas, + constants=constants, + composable_states=[alchemical_state], ) - if not dry: # pragma: no-cover - # minimize - if self.verbose: - self.logger.info("minimizing systems") - sampler.minimize( - max_iterations=settings[ - 'simulation_settings'].minimization_steps - ) - # equilibrate - if self.verbose: - self.logger.info("equilibrating systems") - - sampler.equilibrate(int(equil_steps / mc_steps)) # type: ignore - - # production - if self.verbose: - self.logger.info("running production phase") - sampler.extend(int(prod_steps / mc_steps)) # type: ignore - - if self.verbose: - self.logger.info("production phase complete") - - if self.verbose: - self.logger.info("post-simulation result analysis") - - analyzer = multistate_analysis.MultistateEquilFEAnalysis( - reporter, - sampling_method=settings[ - 'simulation_settings'].sampler_method.lower(), - result_units=unit.kilocalorie_per_mole - ) - analyzer.plot(filepath=self.shared_basepath, filename_prefix="") - analyzer.close() - - return analyzer.unit_results_dict - - else: - # close reporter when you're done, prevent file handle clashes - reporter.close() + sampler_state = SamplerState(positions=positions) + if alchemical_system.usesPeriodicBoundaryConditions(): + box = alchemical_system.getDefaultPeriodicBoxVectors() + sampler_state.box_vectors = box - # clean up the reporter file - 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) + sampler_states = [sampler_state for _ in cmp_states] - return None + return sampler_states, cmp_states + def _get_reporter( + self, + topology: app.Topology, + positions: openmm.unit.Quantity, + simulation_settings: MultiStateSimulationSettings, + output_settings: MultiStateOutputSettings, + shared_basepath: pathlib.Path, + ) -> multistate.MultiStateReporter: + """ + Get a MultistateReporter for the simulation you are running. - @staticmethod - def _get_atom_indices(omm_topology, comp_resids): - comp_atomids = {} - for key, values in comp_resids.items(): - atom_indices = [] - for residue in omm_topology.residues(): - if residue.index in values: - atom_indices.extend([atom.index for atom in residue.atoms()]) - comp_atomids[key] = atom_indices - return comp_atomids + Parameters + ---------- + 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: MultiStateOutputSettings + Output settings for the simulations + shared_basepath: pathlib.Path - @staticmethod - def _update_positions( - omm_topology_A, omm_topology_B, positions_A, positions_B, - atom_indices_A, atom_indices_B, - ) -> npt.NDArray: + Returns + ------- + reporter : multistate.MultiStateReporter + The reporter for the simulation. """ - Get new positions for the stateB after equilibration. + mdt_top = mdt.Topology.from_openmm(topology) - Note - ---- - Must be implemented in the child class. - In the complex phase, this is achieved by aligning the proteins, - in the solvent phase, the ligand B are offset from ligand A - """ - ... + selection_indices = mdt_top.select( + output_settings.output_indices + ) - @staticmethod - def _set_positions(off_topology, positions): - off_topology.clear_positions() - off_topology.set_positions(positions) - return off_topology + nc = 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, + ) - @staticmethod - def _add_restraints( - system: openmm.System, - positions: np.array, - topology: Optional[openmm.Topology], - ligand_1: Optional[OFFMolecule.Topology], - ligand_2: Optional[OFFMolecule.Topology], - settings: Optional, - ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology - ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology - ligand_1_idxs: tuple[int, int, int], # indices from the full topology - ligand_2_idxs: tuple[int, int, int], # indices from the full topology - ) -> openmm.System: - """ - Get new positions for the stateB after equilibration. + reporter = multistate.MultiStateReporter( + storage=nc, + analysis_particle_indices=selection_indices, + checkpoint_interval=chk_intervals, + checkpoint_storage=chk, + ) - Note - ---- - Must be implemented in the child class. - In the complex phase, this is achieved by aligning the proteins, - in the solvent phase, the ligand B are offset from ligand A - """ - ... + # Write out the structure's PDB whilst we're here + if len(selection_indices) > 0: + traj = mdt.Trajectory( + positions[selection_indices, :], + mdt_top.subset(selection_indices), + ) + traj.save_pdb( + shared_basepath / output_settings.output_structure + ) + return reporter - def run(self, dry=False, verbose=True, - scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: + + def _get_ctx_caches( + self, + engine_settings: OpenMMEngineSettings + ) -> tuple[openmmtools.cache.ContextCache, openmmtools.cache.ContextCache]: """ - Run the SepTop free energy calculation. + Set the context caches based on the chosen platform Parameters ---------- - dry : bool - Do a dry run of the calculation, creating all necessary alchemical - system components (topology, system, sampler, etc...) but without - running the simulation, default False - verbose : bool - Verbose output of the simulation progress. Output is provided via - INFO level logging, default True - scratch_basepath : pathlib.Path - Path to the scratch (temporary) directory space. - shared_basepath : pathlib.Path - Path to the shared (persistent) directory space. + engine_settings : OpenMMEngineSettings, Returns ------- - dict - Outputs created in the basepath directory or the debug objects - (i.e. sampler) if ``dry==True``. + energy_context_cache : openmmtools.cache.ContextCache + The energy state context cache. + sampler_context_cache : openmmtools.cache.ContextCache + The sampler state context cache. """ - # 0. General preparation tasks - self._prepare(verbose, scratch_basepath, shared_basepath) + platform = compute.get_openmm_platform( + engine_settings.compute_platform, + ) - # 1. Get components - self.logger.info("Creating and setting up the OpenMM systems") - alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() + energy_context_cache = openmmtools.cache.ContextCache( + capacity=None, time_to_live=None, platform=platform, + ) - # 2. Get settings - settings = self._handle_settings() + sampler_context_cache = openmmtools.cache.ContextCache( + capacity=None, time_to_live=None, platform=platform, + ) - # 5. Get system generator - system_generator = self._get_system_generator(settings, solv_comp) + return energy_context_cache, sampler_context_cache - # 6. Get smcs for the different states and the common smcs - smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} - smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} - smc_off_both = {m: m.to_openff() for m in smc_comps - if (m not in alchem_comps["stateA"] and m not in - alchem_comps["stateB"])} - smc_comps_A = smc_off_A | smc_off_both - smc_comps_B = smc_off_B | smc_off_both - smc_comps_AB = smc_off_A | smc_off_B | smc_off_both + @staticmethod + def _get_integrator( + integrator_settings: IntegratorSettings, + simulation_settings: MultiStateSimulationSettings + ) -> openmmtools.mcmc.LangevinDynamicsMove: + """ + Return a LangevinDynamicsMove integrator - # 7. Assign partial charges here to only do it once for smcs in stateA - # and stateB (hence only charge e.g. cofactors ones) - self._assign_partial_charges(settings['charge_settings'], smc_comps_AB) + Parameters + ---------- + integrator_settings : IntegratorSettings + simulation_settings : MultiStateSimulationSettings - # 8. Get modeller for stateA, stateB, and stateAB - system_modeller_A, comp_resids_A = self._get_modeller( - prot_comp, solv_comp, smc_comps_A, - system_generator, settings['solvation_settings'], - ) - system_modeller_B, comp_resids_B = self._get_modeller( - prot_comp, solv_comp, smc_comps_B, - system_generator, settings['solvation_settings'], + Returns + ------- + integrator : openmmtools.mcmc.LangevinDynamicsMove + A configured integrator object. + """ + steps_per_iteration = settings_validation.convert_steps_per_iteration( + simulation_settings, integrator_settings ) - # Get modeller B only ligand B - modeller_ligandB, comp_resids_ligB = self._get_modeller( - None, None, smc_off_B, - system_generator, settings['solvation_settings'], + integrator = openmmtools.mcmc.LangevinDynamicsMove( + timestep=to_openmm(integrator_settings.timestep), + 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, ) - # Take the modeller from system A --> every water/ion should be in - # the same location - system_modeller_AB = copy.copy(system_modeller_A) - system_modeller_AB.add(modeller_ligandB.topology, - modeller_ligandB.positions) - - # We assume that modeller.add will always put the ligand B towards - # the end of the residues - resids_A = list(itertools.chain(*comp_resids_A.values())) - resids_AB = [r.index for r in system_modeller_AB.topology.residues()] - diff_resids = list(set(resids_AB) - set(resids_A)) - comp_resids_AB = comp_resids_A | {alchem_comps["stateB"][0]: np.array(diff_resids)} + return integrator - # 5. Get OpenMM topology, positions and system - omm_topology_A, omm_system_A, positions_A = self._get_omm_objects( - system_modeller_A, system_generator, list(smc_comps_A.values()) - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_A, - positions_A, - open('outputA.pdb', - 'w')) - omm_topology_B, omm_system_B, positions_B = self._get_omm_objects( - system_modeller_B, system_generator, list(smc_comps_B.values()) - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, - positions_B, - open('outputB.pdb', - 'w')) + @staticmethod + def _get_sampler( + integrator: openmmtools.mcmc.LangevinDynamicsMove, + reporter: openmmtools.multistate.MultiStateReporter, + simulation_settings: MultiStateSimulationSettings, + thermo_settings: ThermoSettings, + cmp_states: list[ThermodynamicState], + sampler_states: list[SamplerState], + energy_context_cache: openmmtools.cache.ContextCache, + sampler_context_cache: openmmtools.cache.ContextCache + ) -> multistate.MultiStateSampler: + """ + Get a sampler based on the equilibrium sampling method requested. - omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( - system_modeller_AB, system_generator, list(smc_comps_AB.values()) - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, - positions_AB, - open('outputAB.pdb', 'w')) + Parameters + ---------- + integrator : openmmtools.mcmc.LangevinDynamicsMove + The simulation integrator. + reporter : openmmtools.multistate.MultiStateReporter + The reporter to hook up to the sampler. + 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] + A list of sampler states. + energy_context_cache : openmmtools.cache.ContextCache + Context cache for the energy states. + sampler_context_cache : openmmtool.cache.ContextCache + Context cache for the sampler states. - # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) - self.logger.info("Pre-equilibrating the systems") - equ_positions_A = self._pre_equilibrate( - omm_system_A, omm_topology_A, positions_A, settings, dry - ) - equ_positions_B = self._pre_equilibrate( - omm_system_B, omm_topology_B, positions_B, settings, dry + Returns + ------- + 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_from_kcal_per_mole_to_kT( + thermo_settings.temperature, + simulation_settings.early_termination_target_error, ) - simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_A, equ_positions_A, open('outputA_equ.pdb', 'w')) - simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_B, equ_positions_B, open('outputB_equ.pdb', 'w')) - - # 7. Get all the right atom indices for alignments - comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) - all_atom_ids_A = list(itertools.chain(*comp_atomids_A.values())) - comp_atomids_B = self._get_atom_indices(omm_topology_B, comp_resids_B) - # Get the system A atom indices of ligand A - atom_indices_A = comp_atomids_A[alchem_comps['stateA'][0]] - # Get the system B atom indices of ligand B - atom_indices_B = comp_atomids_B[alchem_comps['stateB'][0]] + # Select the right sampler + # Note: doesn't need else, settings already validates choices + if simulation_settings.sampler_method.lower() == "repex": + sampler = multistate.ReplicaExchangeSampler( + mcmc_moves=integrator, + online_analysis_interval=rta_its, + online_analysis_target_error=et_target_err, + online_analysis_minimum_iterations=rta_min_its + ) + elif simulation_settings.sampler_method.lower() == "sams": + sampler = multistate.SAMSSampler( + mcmc_moves=integrator, + 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 simulation_settings.sampler_method.lower() == 'independent': + sampler = multistate.MultiStateSampler( + mcmc_moves=integrator, + online_analysis_interval=rta_its, + online_analysis_target_error=et_target_err, + online_analysis_minimum_iterations=rta_min_its, + ) - # 8. Update the positions of system B: - # - complex: Align protein - # - solvent: Offset ligand B with respect to ligand A - updated_positions_B = self._update_positions( - omm_topology_A, omm_topology_B, equ_positions_A, equ_positions_B, - atom_indices_A, atom_indices_B) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, - updated_positions_B, - open('outputB_new.pdb', - 'w')) + sampler.create( + thermodynamic_states=cmp_states, + sampler_states=sampler_states, + storage=reporter + ) - # Get atom indices for ligand A and ligand B and the solvent in the - # system AB - comp_atomids_AB = self._get_atom_indices(omm_topology_AB, comp_resids_AB) - atom_indices_AB_B = comp_atomids_AB[alchem_comps['stateB'][0]] - atom_indices_AB_A = comp_atomids_AB[alchem_comps['stateA'][0]] + sampler.energy_context_cache = energy_context_cache + sampler.sampler_context_cache = sampler_context_cache - # Update positions from AB system - positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A - positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, - :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] + return sampler - topology_file = shared_basepath / 'topology.pdb' - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, - positions_AB, - open(topology_file, - 'w')) + def _run_simulation( + self, + sampler: multistate.MultiStateSampler, + reporter: multistate.MultiStateReporter, + settings: dict[str, SettingsBaseModel], + dry: bool, + verbose: bool, + shared_basepath: pathlib.Path, + ): + """ + Run the simulation. - # 9. Create the alchemical system - self.logger.info("Creating the alchemical system and applying restraints") - apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) + Parameters + ---------- + sampler : multistate.MultiStateSampler + The sampler associated with the simulation to run. + reporter : multistate.MultiStateReporter + The reporter associated with the sampler. + settings : dict[str, SettingsBaseModel] + The dictionary of settings for the protocol. + dry : bool + Whether or not to dry run the simulation - # 10. Apply Restraints - off_A = alchem_comps["stateA"][0].to_openff().to_topology() - lig_A_pos = positions_AB[atom_indices_AB_A[0]:atom_indices_AB_A[-1]+1, :] / omm_units.nanometers * unit.nanometer - self._set_positions(off_A, lig_A_pos) - off_A.to_file('molA.pdb') - off_B = alchem_comps["stateB"][0].to_openff().to_topology() - lig_B_pos = positions_AB[ - atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, - :] / omm_units.nanometers * unit.nanometer - self._set_positions(off_B, lig_B_pos) - off_B.to_file('molB.pdb') + Returns + ------- + unit_results_dict : Optional[dict] + A dictionary containing all the free energy results, + if not a dry run. + """ + # Get the relevant simulation steps + mc_steps = settings_validation.convert_steps_per_iteration( + simulation_settings=settings['simulation_settings'], + integrator_settings=settings['integrator_settings'], + ) - ligand_A_ref_inxs, ligand_B_ref_inxs = select_ligand_idxs(off_A, off_B) + equil_steps = settings_validation.get_simsteps( + sim_length=settings['simulation_settings'].equilibration_length, + timestep=settings['integrator_settings'].timestep, + mc_steps=mc_steps, + ) + prod_steps = settings_validation.get_simsteps( + sim_length=settings['simulation_settings'].production_length, + timestep=settings['integrator_settings'].timestep, + mc_steps=mc_steps, + ) - ligand_A_inxs = tuple([atom_indices_AB_A[inx] for inx in ligand_A_ref_inxs]) - ligand_B_inxs = tuple([atom_indices_AB_B[inx] for inx in ligand_B_ref_inxs]) - print(ligand_A_inxs) - print(ligand_B_inxs) + if not dry: # pragma: no-cover + # minimize + if verbose: + self.logger.info("minimizing systems") + sampler.minimize( + max_iterations=settings[ + 'simulation_settings'].minimization_steps + ) + # equilibrate + if verbose: + self.logger.info("equilibrating systems") - system = self._add_restraints( - omm_system_AB, positions_AB, omm_topology_AB, - off_A, off_B, - settings, - ligand_A_ref_inxs, ligand_B_ref_inxs, - ligand_A_inxs, ligand_B_inxs) - # # Check that the restraints are correctly applied by running a short equilibration - # equ_positions_restraints = self._pre_equilibrate( - # system, omm_topology_AB, positions_AB, settings, dry - # ) - # simtk.openmm.app.pdbfile.PDBFile.writeFile( - # omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) + sampler.equilibrate(int(equil_steps / mc_steps)) # type: ignore - # Here we could also apply REST + # production + if verbose: + self.logger.info("running production phase") + sampler.extend(int(prod_steps / mc_steps)) # type: ignore - system_outfile = shared_basepath / "system.xml.bz2" + if self.verbose: + self.logger.info("production phase complete") - # Serialize system, state and integrator - serialize(system, system_outfile) + if verbose: + self.logger.info("post-simulation result analysis") - # # 7. Get lambdas - # lambdas = self._get_lambda_schedule(settings) - # print(lambdas) - # - # # 13. Get integrator - # integrator = self._get_integrator( - # settings['integrator_settings'], - # settings['simulation_settings'], - # ) - # - # # Set up context - # platform = get_openmm_platform( - # settings['engine_settings'].compute_platform) - # context = openmm.Context(system, integrator, platform) - # context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) - # context.setPositions(positions_AB) - # - # try: - # # SERIALIZE SYSTEM, STATE, INTEGRATOR - # # need to set velocities to temperature so serialized state - # # features velocities, - # # which is important for usability by the Folding@Home openmm-core - # thermodynamic_settings = settings['thermo_settings'] - # temperature = to_openmm(thermodynamic_settings.temperature) - # context.setVelocitiesToTemperature(temperature) - # - # # state needs to include positions, forces, velocities, and energy - # # to be usable by the Folding@Home openmm-core - # state_ = context.getState( - # getPositions=True, getForces=True, getVelocities=True, - # getEnergy=True - # ) - # system_ = context.getSystem() - # integrator_ = context.getIntegrator() - # - # system_outfile = shared_basepath / "system.xml.bz2" - # state_outfile = shared_basepath / "state.xml.bz2" - # integrator_outfile = shared_basepath / "integrator.xml.bz2" - # - # # Serialize system, state and integrator - # serialize(system_, system_outfile) - # serialize(state_, state_outfile) - # serialize(integrator_, integrator_outfile) - # - # finally: - # # Explicit cleanup for GPU resources - # del context, integrator + analyzer = multistate_analysis.MultistateEquilFEAnalysis( + reporter, + sampling_method=settings[ + 'simulation_settings'].sampler_method.lower(), + result_units=unit.kilocalorie_per_mole + ) + analyzer.plot(filepath=shared_basepath, filename_prefix="") + analyzer.close() - return { - "system": system_outfile, - "topology": topology_file, - } + return analyzer.unit_results_dict - # # 10. Get compound and sampler states - # sampler_states, cmp_states = self._get_states( - # omm_system_AB, positions_AB, settings, - # lambdas, solv_comp - # ) - # - # # 11. Create the multistate reporter & create PDB - # reporter = self._get_reporter( - # omm_topology_AB, positions_AB, - # settings['simulation_settings'], - # settings['output_settings'], - # ) - # - # # Wrap in try/finally to avoid memory leak issues - # try: - # # 12. Get context caches - # energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( - # settings['engine_settings'] - # ) - # - # # 13. Get integrator - # integrator = self._get_integrator( - # settings['integrator_settings'], - # settings['simulation_settings'], - # ) - # - # # 14. Get sampler - # sampler = self._get_sampler( - # integrator, reporter, settings['simulation_settings'], - # settings['thermo_settings'], - # cmp_states, sampler_states, - # energy_ctx_cache, sampler_ctx_cache - # ) - # - # # 15. Run simulation - # unit_result_dict = self._run_simulation( - # sampler, reporter, settings, dry - # ) - # - # finally: - # # close reporter when you're done to prevent file handle clashes - # reporter.close() - # - # # clear GPU context - # # Note: use cache.empty() when openmmtools #690 is resolved - # for context in list(energy_ctx_cache._lru._data.keys()): - # del energy_ctx_cache._lru._data[context] - # for context in list(sampler_ctx_cache._lru._data.keys()): - # del sampler_ctx_cache._lru._data[context] - # # cautiously clear out the global context cache too - # for context in list( - # openmmtools.cache.global_context_cache._lru._data.keys()): - # del openmmtools.cache.global_context_cache._lru._data[context] - # - # del sampler_ctx_cache, energy_ctx_cache - # - # # Keep these around in a dry run so we can inspect things - # if not dry: - # del integrator, sampler - # - # if not dry: - # nc = self.shared_basepath / settings[ - # 'output_settings'].output_filename - # chk = settings['output_settings'].checkpoint_storage_filename - # return { - # 'nc': nc, - # 'last_checkpoint': chk, - # **unit_result_dict, - # } - # else: - # return {'debug': {'sampler': sampler}} - # - # - # # eventually save the serialized alchemical systems to disc to be - # # picked up by the run unit + else: + # close reporter when you're done, prevent file handle clashes + reporter.close() + # clean up the reporter file + fns = [shared_basepath / settings[ + 'output_settings'].output_filename, + shared_basepath / settings[ + 'output_settings'].checkpoint_storage_filename] + for fn in fns: + os.remove(fn) -class BaseSepTopRunUnit(gufe.ProtocolUnit): - """ - Base class for running ligand SepTop RBFE free energy transformations. - """ + return None - def _execute(self, ctx: gufe.Context, *, protocol, setup, **inputs, + def _execute( + self, ctx: gufe.Context, *, setup, verbose=True, **kwargs, ) -> dict[str, Any]: """ Execute the simulation part of the Gromacs MD protocol. @@ -1328,21 +1276,92 @@ def _execute(self, ctx: gufe.Context, *, protocol, setup, **inputs, Dictionary with paths to ... """ log_system_probe(logging.INFO, paths=[ctx.scratch]) - + dry=False if ctx.shared is None: # use cwd shared_basepath = pathlib.Path(".") else: shared_basepath = ctx.shared - protocol_settings: SepTopSettings = self._inputs[ - "protocol"].settings + settings = self._handle_settings() + alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() serialized_system = setup.outputs["system"] serialized_topology = setup.outputs["topology"] system = deserialize(serialized_system) - topology = simtk.openmm.app.pdbfile.PDBFile(serialized_topology).topology + pdb = simtk.openmm.app.pdbfile.PDBFile(str(serialized_topology)) + positions = pdb.getPositions(asNumpy=True) + lambdas = self._get_lambda_schedule(settings) + + # 10. Get compound and sampler states + sampler_states, cmp_states = self._get_states( + system, positions, settings, + lambdas, solv_comp + ) + + # 11. Create the multistate reporter & create PDB + reporter = self._get_reporter( + pdb.topology, positions, + settings['simulation_settings'], + settings['output_settings'], + shared_basepath, + ) + + # Wrap in try/finally to avoid memory leak issues + try: + # 12. Get context caches + energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( + settings['engine_settings'] + ) - print(system, topology) + # 13. Get integrator + integrator = self._get_integrator( + settings['integrator_settings'], + settings['simulation_settings'], + ) + + # 14. Get sampler + sampler = self._get_sampler( + integrator, reporter, settings['simulation_settings'], + settings['thermo_settings'], + cmp_states, sampler_states, + energy_ctx_cache, sampler_ctx_cache + ) + + # 15. Run simulation + unit_result_dict = self._run_simulation( + sampler, reporter, settings, dry, verbose, shared_basepath + ) + + finally: + # close reporter when you're done to prevent file handle clashes + reporter.close() - return + # clear GPU context + # Note: use cache.empty() when openmmtools #690 is resolved + for context in list(energy_ctx_cache._lru._data.keys()): + del energy_ctx_cache._lru._data[context] + for context in list(sampler_ctx_cache._lru._data.keys()): + del sampler_ctx_cache._lru._data[context] + # cautiously clear out the global context cache too + for context in list( + openmmtools.cache.global_context_cache._lru._data.keys()): + del openmmtools.cache.global_context_cache._lru._data[context] + + del sampler_ctx_cache, energy_ctx_cache + + # Keep these around in a dry run so we can inspect things + if not dry: + del integrator, sampler + + if not dry: + nc = shared_basepath / settings[ + 'output_settings'].output_filename + chk = settings['output_settings'].checkpoint_storage_filename + return { + 'nc': nc, + 'last_checkpoint': chk, + **unit_result_dict, + } + else: + return {'debug': {'sampler': sampler}} diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 4d0622882..7d4a22e2d 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -725,6 +725,9 @@ def _create( solvent_run = [ SepTopSolventRunUnit( protocol=self, + stateA=stateA, + stateB=stateB, + alchemical_components=alchem_comps, setup=solvent_setup[i], generation=0, repeat_id=int(uuid.uuid4()), name=(f"SepTop RBFE, {alchname} solvent leg: " @@ -930,7 +933,8 @@ def _add_restraints( ligand_1_idxs, positions, k_distance, - k_theta + k_theta, + "lambda_restraints_ligandA", ) system.addForce(force_A) force_B = create_boresch_restraint( @@ -939,7 +943,8 @@ def _add_restraints( ligand_2_idxs, positions, k_distance, - k_theta + k_theta, + "lambda_restraints_ligandB", ) system.addForce(force_B) @@ -1159,9 +1164,206 @@ class SepTopSolventRunUnit(BaseSepTopRunUnit): """ Protocol Unit for the solvent phase of an relative SepTop free energy """ + def _get_components(self): + """ + Get the relevant components for a solvent transformation. + + Note + ----- + The solvent portion of the transformation is the transformation of one + ligand into the other in the solvent. The only thing that + should be present is the alchemical species in state A and state B + and the SolventComponent. + + Returns + ------- + alchem_comps : dict[str, Component] + A list of alchemical components + solv_comp : SolventComponent + The SolventComponent of the system + prot_comp : Optional[ProteinComponent] + The protein component of the system, if it exists. + small_mols : dict[SmallMoleculeComponent: OFFMolecule] + SmallMoleculeComponents to add to the system. + """ + stateA = self._inputs['stateA'] + alchem_comps = self._inputs['alchemical_components'] + + small_mols_A = {m: m.to_openff() + for m in alchem_comps['stateA']} + small_mols_B = {m: m.to_openff() + for m in alchem_comps['stateB']} + small_mols = small_mols_A | small_mols_B + + solv_comp, _, _ = system_validation.get_components(stateA) + + # 1. We don't need to check that solv_comp is not None, otherwise + # an error will have been raised when calling `validate_solvent` + # in the Protocol's `_create`. + # 2. ProteinComps can't be alchem_comps (for now), so will + # be returned as None + return alchem_comps, solv_comp, None, small_mols + + + def _handle_settings(self) -> dict[str, SettingsBaseModel]: + """ + Extract the relevant settings for a complex transformation. + + Returns + ------- + settings : dict[str, SettingsBaseModel] + A dictionary with the following entries: + * forcefield_settings : OpenMMSystemGeneratorFFSettings + * thermo_settings : ThermoSettings + * charge_settings : OpenFFPartialChargeSettings + * solvation_settings : OpenMMSolvationSettings + * alchemical_settings : AlchemicalSettings + * lambda_settings : LambdaSettings + * engine_settings : OpenMMEngineSettings + * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings + * simulation_settings : MultiStateSimulationSettings + * output_settings: MultiStateOutputSettings + * restraint_settings: RestraintsSettings + """ + prot_settings = self._inputs['protocol'].settings + + settings = {} + settings['forcefield_settings'] = prot_settings.solvent_forcefield_settings + settings['thermo_settings'] = prot_settings.thermo_settings + settings['charge_settings'] = prot_settings.partial_charge_settings + settings['solvation_settings'] = prot_settings.solvent_solvation_settings + settings['alchemical_settings'] = prot_settings.alchemical_settings + 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 + settings['restraint_settings'] = prot_settings.solvent_restraints_settings + + settings_validation.validate_timestep( + settings['forcefield_settings'].hydrogen_mass, + settings['integrator_settings'].timestep + ) + + return settings + + def _get_lambda_schedule( + self, settings: dict[str, SettingsBaseModel] + ) -> dict[str, npt.NDArray]: + lambdas = dict() + + lambdas['lambda_electrostatics_ligandA'] = settings[ + 'lambda_settings'].lambda_elec_ligandA + lambdas['lambda_sterics_ligandA'] = settings[ + 'lambda_settings'].lambda_vdw_ligandA + lambdas['lambda_electrostatics_ligandB'] = settings[ + 'lambda_settings'].lambda_elec_ligandB + lambdas['lambda_sterics_ligandB'] = settings[ + 'lambda_settings'].lambda_vdw_ligandB + + return lambdas class SepTopComplexRunUnit(BaseSepTopRunUnit): """ Protocol Unit for the solvent phase of an relative SepTop free energy """ + def _get_components(self): + """ + Get the relevant components for a complex transformation. + + Returns + ------- + alchem_comps : dict[str, Component] + A list of alchemical components + solv_comp : SolventComponent + The SolventComponent of the system + prot_comp : Optional[ProteinComponent] + The protein component of the system, if it exists. + small_mols : dict[SmallMoleculeComponent: OFFMolecule] + SmallMoleculeComponents to add to the system. + """ + stateA = self._inputs['stateA'] + alchem_comps = self._inputs['alchemical_components'] + + solv_comp, prot_comp, small_mols = system_validation.get_components(stateA) + small_mols = {m: m.to_openff() for m in small_mols} + # Also get alchemical smc from state B + small_mols_B = {m: m.to_openff() + for m in alchem_comps['stateB']} + small_mols = small_mols | small_mols_B + + return alchem_comps, solv_comp, prot_comp, small_mols + + + def _handle_settings(self) -> dict[str, SettingsBaseModel]: + """ + Extract the relevant settings for a complex transformation. + + Returns + ------- + settings : dict[str, SettingsBaseModel] + A dictionary with the following entries: + * forcefield_settings : OpenMMSystemGeneratorFFSettings + * thermo_settings : ThermoSettings + * charge_settings : OpenFFPartialChargeSettings + * solvation_settings : OpenMMSolvationSettings + * alchemical_settings : AlchemicalSettings + * lambda_settings : LambdaSettings + * engine_settings : OpenMMEngineSettings + * integrator_settings : IntegratorSettings + * equil_simulation_settings : MDSimulationSettings + * equil_output_settings : MDOutputSettings + * simulation_settings : SimulationSettings + * output_settings: MultiStateOutputSettings + * restraint_settings: RestraintsSettings + """ + prot_settings = self._inputs['protocol'].settings + + settings = { + 'forcefield_settings': prot_settings.complex_forcefield_settings, + 'thermo_settings': prot_settings.thermo_settings, + 'charge_settings': prot_settings.partial_charge_settings, + 'solvation_settings': prot_settings.complex_solvation_settings, + 'alchemical_settings': prot_settings.alchemical_settings, + 'lambda_settings': prot_settings.lambda_settings, + 'engine_settings': prot_settings.complex_engine_settings, + 'integrator_settings': prot_settings.integrator_settings, + 'equil_simulation_settings': + prot_settings.complex_equil_simulation_settings, + 'equil_output_settings': + prot_settings.complex_equil_output_settings, + 'simulation_settings': prot_settings.complex_simulation_settings, + 'output_settings': prot_settings.complex_output_settings, + 'restraint_settings': prot_settings.complex_restraints_settings} + + settings_validation.validate_timestep( + settings['forcefield_settings'].hydrogen_mass, + settings['integrator_settings'].timestep + ) + + return settings + + def _get_lambda_schedule( + self, settings: dict[str, SettingsBaseModel] + ) -> dict[str, npt.NDArray]: + lambdas = dict() + + lambdas['lambda_electrostatics_ligandA'] = settings[ + 'lambda_settings'].lambda_elec_ligandA + lambdas['lambda_sterics_ligandA'] = settings[ + 'lambda_settings'].lambda_vdw_ligandA + lambdas['lambda_restraints_ligandA'] = settings[ + 'lambda_settings'].lambda_restraints_ligandA + lambdas['lambda_electrostatics_ligandB'] = settings[ + 'lambda_settings'].lambda_elec_ligandB + lambdas['lambda_sterics_ligandB'] = settings[ + 'lambda_settings'].lambda_vdw_ligandB + lambdas['lambda_restraints_ligandB'] = settings[ + 'lambda_settings'].lambda_restraints_ligandB + + return lambdas \ No newline at end of file diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 40c6dd598..848bdecfa 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -92,7 +92,9 @@ class LambdaSettings(SettingsBaseModel): Length of this list needs to match length of lambda_elec and lambda_restraints. """ lambda_restraints_ligandA: list[float] = [ - 0.0, 0.05, 0.1, 0.3, 0.5, 0.75, 1.0, 1.0] + [1.0] * 3 + [1.0] * 8 + 0.0, 0.05, 0.1, 0.3, 0.5, + 0.75, 1.0, 1.0] + [ + 1.0] * 3 + [1.0] * 8 """ List of floats of lambda values for the restraints of ligand A. Zero means fully interacting and 1 means fully decoupled. @@ -106,6 +108,7 @@ class LambdaSettings(SettingsBaseModel): Length of this list needs to match length of lambda_vdw and lambda_elec. """ + @validator('lambda_elec_ligandA', 'lambda_elec_ligandB', 'lambda_vdw_ligandA', 'lambda_vdw_ligandB', 'lambda_restraints_ligandA', 'lambda_restraints_ligandB') diff --git a/openfe/protocols/openmm_septop/femto_alchemy.py b/openfe/protocols/openmm_septop/femto_alchemy.py index 1d8d5b7ed..fa3abc7f5 100644 --- a/openfe/protocols/openmm_septop/femto_alchemy.py +++ b/openfe/protocols/openmm_septop/femto_alchemy.py @@ -10,15 +10,15 @@ # This code was obtained and modified from https://github.com/Psivant/femto -LAMBDA_VDW_LIGAND_1 = "lambda_vdw_lig_1" +LAMBDA_VDW_LIGAND_1 = "lambda_sterics_ligandA" """The global parameter used to scale the vdW interactions of ligand 1.""" -LAMBDA_VDW_LIGAND_2 = "lambda_vdw_lig_2" +LAMBDA_VDW_LIGAND_2 = "lambda_sterics_ligandB" """The global parameter used to scale the vdW interactions of ligand 2.""" -LAMBDA_CHARGES_LIGAND_1 = "lambda_charges_lig_1" +LAMBDA_CHARGES_LIGAND_1 = "lambda_electrostatics_ligandA" """The global parameter used to scale the electrostatic interactions of ligand 1.""" -LAMBDA_CHARGES_LIGAND_2 = "lambda_charges_lig_2" +LAMBDA_CHARGES_LIGAND_2 = "lambda_electrostatics_ligandB" """The global parameter used to scale the electrostatic interactions of ligand 2.""" diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 3abbc9d8a..bbba6c281 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -701,13 +701,14 @@ def create_boresch_restraint( energy_fn = _BORESCH_ENERGY_FN - # if ctx_parameter is not None: - # energy_fn = f"{ctx_parameter} * {energy_fn}" + if ctx_parameter is not None: + energy_fn = f"{ctx_parameter} * {energy_fn}" force = openmm.CustomCompoundBondForce(n_particles, energy_fn) - # if ctx_parameter is not None: - # force.addGlobalParameter(ctx_parameter, 1.0) + if ctx_parameter is not None: + print(ctx_parameter) + force.addGlobalParameter(ctx_parameter, 1.0) geometry = _compute_boresch_geometry(receptor_atoms, ligand_atoms, coords) diff --git a/openfe/protocols/openmm_septop/utils.py b/openfe/protocols/openmm_septop/utils.py index c6317ef8c..ed6400acf 100644 --- a/openfe/protocols/openmm_septop/utils.py +++ b/openfe/protocols/openmm_septop/utils.py @@ -1,6 +1,10 @@ import os import pathlib - +from openmmtools import states +from openmmtools.alchemy import ( + AlchemicalStateError, AlchemicalRegion, + AlchemicalFunction, AbsoluteAlchemicalFactory, +) def serialize(item, filename: pathlib.Path): """ @@ -73,4 +77,333 @@ def deserialize(filename: pathlib.Path): serialized_thing = infile.read() item = XmlSerializer.deserialize(serialized_thing) - return item \ No newline at end of file + return item + + +class AlchemicalState(states.GlobalParameterState): + """Represent an alchemical state. + + The alchemical parameters modify the Hamiltonian and affect the + computation of the energy. Alchemical parameters that have value + None are considered undefined, which means that applying this + state to System and Context that have that parameter as a global + variable will raise an AlchemicalStateError. + + Parameters + ---------- + parameters_name_suffix : str, optional + If specified, the state will control a modified version of the global + parameters with the name ``parameter_name + '_' + parameters_name_suffix``. + When this is the case, the normal parameters are not accessible. + lambda_sterics : float, optional + Scaling factor for ligand sterics (Lennard-Jones and Halgren) + interactions (default is 1.0). + lambda_electrostatics : float, optional + Scaling factor for ligand charges, intrinsic Born radii, and surface + area term (default is 1.0). + lambda_bonds : float, optional + Scaling factor for alchemically-softened bonds (default is 1.0). + lambda_angles : float, optional + Scaling factor for alchemically-softened angles (default is 1.0). + lambda_torsions : float, optional + Scaling factor for alchemically-softened torsions (default is 1.0). + + Attributes + ---------- + lambda_sterics + lambda_electrostatics + lambda_bonds + lambda_angles + lambda_torsions + + Examples + -------- + Create an alchemically modified system. + + >>> from openmmtools import testsystems + >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + >>> alanine_vacuum = testsystems.AlanineDipeptideVacuum().system + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=range(22)) + >>> alanine_alchemical_system = factory.create_alchemical_system(reference_system=alanine_vacuum, + ... alchemical_regions=alchemical_region) + + Create a completely undefined alchemical state. + + >>> alchemical_state = AlchemicalState() + >>> print(alchemical_state.lambda_sterics) + None + >>> alchemical_state.apply_to_system(alanine_alchemical_system) + Traceback (most recent call last): + ... + openmmtools.alchemy.AlchemicalStateError: The system parameter lambda_electrostatics is not defined in this state. + + Create an AlchemicalState that matches the parameters defined in + the System. + + >>> alchemical_state = AlchemicalState.from_system(alanine_alchemical_system) + >>> alchemical_state.lambda_sterics + 1.0 + >>> alchemical_state.lambda_electrostatics + 1.0 + >>> print(alchemical_state.lambda_angles) + None + + AlchemicalState implement the IComposableState interface, so it can be + used with CompoundThermodynamicState. All the alchemical parameters are + accessible through the compound state. + + >>> import openmm + >>> from openmm import unit + >>> thermodynamic_state = states.ThermodynamicState(system=alanine_alchemical_system, + ... temperature=300*unit.kelvin) + >>> compound_state = states.CompoundThermodynamicState(thermodynamic_state=thermodynamic_state, + ... composable_states=[alchemical_state]) + >>> compound_state.lambda_sterics + 1.0 + + You can control the parameters in the OpenMM Context in this state by + setting the state attributes. + + >>> compound_state.lambda_sterics = 0.5 + >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) + >>> context = compound_state.create_context(integrator) + >>> context.getParameter('lambda_sterics') + 0.5 + >>> compound_state.lambda_sterics = 1.0 + >>> compound_state.apply_to_context(context) + >>> context.getParameter('lambda_sterics') + 1.0 + + You can express the alchemical parameters as a mathematical expression + involving alchemical variables. Here is an example for a two-stage function. + + >>> compound_state.set_alchemical_variable('lambda', 1.0) + >>> compound_state.lambda_sterics = AlchemicalFunction('step_hm(lambda - 0.5) + 2*lambda * step_hm(0.5 - lambda)') + >>> compound_state.lambda_electrostatics = AlchemicalFunction('2*(lambda - 0.5) * step(lambda - 0.5)') + >>> for l in [0.0, 0.25, 0.5, 0.75, 1.0]: + ... compound_state.set_alchemical_variable('lambda', l) + ... print(compound_state.lambda_sterics) + 0.0 + 0.5 + 1.0 + 1.0 + 1.0 + + """ + + _GLOBAL_PARAMETER_ERROR = AlchemicalStateError + + # ------------------------------------------------------------------------- + # Lambda properties + # ------------------------------------------------------------------------- + + class _LambdaParameter(states.GlobalParameterState.GlobalParameter): + """A global parameter in the interval [0, 1] with standard value 1.""" + + def __init__(self, parameter_name): + super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) + + @staticmethod + def lambda_validator(self, instance, parameter_value): + if parameter_value is None: + return parameter_value + if not (0.0 <= parameter_value <= 1.0): + raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) + return float(parameter_value) + + lambda_sterics_ligandA = _LambdaParameter('lambda_sterics_ligandA') + lambda_electrostatics_ligandB = _LambdaParameter( + 'lambda_electrostatics_ligandB') + lambda_sterics_ligandB = _LambdaParameter('lambda_sterics_ligandB') + lambda_electrostatics_ligandA = _LambdaParameter( + 'lambda_electrostatics_ligandA') + lambda_restraints_ligandA = _LambdaParameter('lambda_restraints_ligandA') + lambda_restraints_ligandB = _LambdaParameter('lambda_restraints_ligandB') + lambda_bonds = _LambdaParameter('lambda_bonds') + lambda_angles = _LambdaParameter('lambda_angles') + lambda_torsions = _LambdaParameter('lambda_torsions') + + @classmethod + def from_system(cls, system, *args, **kwargs): + """Constructor reading the state from an alchemical system. + + Parameters + ---------- + system : openmm.System + An alchemically modified system in a defined alchemical state. + parameters_name_suffix : str, optional + If specified, the state will search for a modified + version of the alchemical parameters with the name + ``parameter_name + '_' + parameters_name_suffix``. + + Returns + ------- + The AlchemicalState object representing the alchemical state of + the system. + + Raises + ------ + AlchemicalStateError + If the same parameter has different values in the system, or + if the system has no lambda parameters. + + """ + # The function is redefined here only to provide more specific documentation for this method. + return super().from_system(system, *args, **kwargs) + + def set_alchemical_parameters(self, new_value): + """Set all defined lambda parameters to the given value. + + The undefined parameters (i.e. those being set to None) remain + undefined. + + Parameters + ---------- + new_value : float + The new value for all defined parameters. + + """ + for parameter_name in self._parameters: + if self._parameters[parameter_name] is not None: + setattr(self, parameter_name, new_value) + + # ------------------------------------------------------------------------- + # Function variables + # ------------------------------------------------------------------------- + + def get_function_variable(self, variable_name): + """Return the value of the function variable. + + Function variables are variables entering mathematical expressions + specified with ``AlchemicalFunction``, which can be use to enslave + a lambda parameter to arbitrary variables. + + Parameters + ---------- + variable_name : str + The name of the function variable. + + Returns + ------- + variable_value : float + The value of the function variable. + + """ + # The function is redefined here only to provide more specific documentation for this method. + return super().get_function_variable(variable_name) + + def set_function_variable(self, variable_name, new_value): + """Set the value of the function variable. + + Function variables are variables entering mathematical expressions + specified with ``AlchemicalFunction``, which can be use to enslave + a lambda parameter to arbitrary variables. + + Parameters + ---------- + variable_name : str + The name of the function variable. + new_value : float + The new value for the variable. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().set_function_variable(variable_name, new_value) + + def get_alchemical_variable(self, variable_name): + """Return the value of the alchemical parameter. + + .. warning: + This is deprecated. Use ``get_function_variable`` instead. + + Parameters + ---------- + variable_name : str + The name of the alchemical variable. + + Returns + ------- + variable_value : float + The value of the alchemical variable. + """ + import warnings + warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' + 'Use AlchemicalState.get_function_variable instead.') + return super().get_function_variable(variable_name) + + def set_alchemical_variable(self, variable_name, new_value): + """Set the value of the alchemical variable. + + .. warning: + This is deprecated. Use ``set_function_variable`` instead. + + Parameters + ---------- + variable_name : str + The name of the alchemical variable. + new_value : float + The new value for the variable. + + """ + import warnings + warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' + 'Use AlchemicalState.get_function_variable instead.') + super().set_function_variable(variable_name, new_value) + + # ------------------------------------------------------------------------- + # IComposableState interface + # ------------------------------------------------------------------------- + + def apply_to_system(self, system): + """Set the alchemical state of the system to this. + + Parameters + ---------- + system : openmm.System + The system to modify. + + Raises + ------ + AlchemicalStateError + If the system does not have the required lambda global variables. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().apply_to_system(system) + + def check_system_consistency(self, system): + """Check if the system is in this alchemical state. + + It raises a AlchemicalStateError if the system is not consistent + with the alchemical state. + + Parameters + ---------- + system : openmm.System + The system to test. + + Raises + ------ + AlchemicalStateError + If the system is not consistent with this state. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().check_system_consistency(system) + + def apply_to_context(self, context): + """Put the Context into this AlchemicalState. + + Parameters + ---------- + context : openmm.Context + The context to set. + + Raises + ------ + AlchemicalStateError + If the context does not have the required lambda global variables. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().apply_to_context(context) From 52eef2e42297b62ca66d693377e438eb3a655663 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 13:40:34 +0100 Subject: [PATCH 038/163] Remove unnecessary import --- openfe/protocols/openmm_septop/base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index f05d8a4f9..f46fa52e7 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -77,7 +77,6 @@ from .femto_alchemy import apply_fep from .femto_restraints import select_ligand_idxs from .utils import serialize, deserialize -from .femto_equilibrate import create_state_dicts logger = logging.getLogger(__name__) From eda32c2136e7678e78aea50c5b299c1a6a602487 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 13:49:33 +0100 Subject: [PATCH 039/163] Remove verbose --- openfe/protocols/openmm_septop/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index f46fa52e7..a9644ac09 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1221,7 +1221,7 @@ def _run_simulation( self.logger.info("running production phase") sampler.extend(int(prod_steps / mc_steps)) # type: ignore - if self.verbose: + if verbose: self.logger.info("production phase complete") if verbose: From 7663e2da7ad225df4cf63f82daf2b2e836c6cf2d Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 14:05:44 +0100 Subject: [PATCH 040/163] Add states to run unit --- openfe/protocols/openmm_septop/base.py | 9 +++------ openfe/protocols/openmm_septop/equil_septop_method.py | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index a9644ac09..c81039e20 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1256,18 +1256,15 @@ def _execute( self, ctx: gufe.Context, *, setup, verbose=True, **kwargs, ) -> dict[str, Any]: """ - Execute the simulation part of the Gromacs MD protocol. + Execute the simulation part of the SepTop protocol. Parameters ---------- ctx : gufe.protocols.protocolunit.Context The gufe context for the unit. - protocol : gufe.protocols.Protocol - The Protocol used to create this Unit. Contains key - information - such as the settings. setup : gufe.protocols.ProtocolUnit The SetupUnit + verbose: bool Returns ------- @@ -1275,7 +1272,7 @@ def _execute( Dictionary with paths to ... """ log_system_probe(logging.INFO, paths=[ctx.scratch]) - dry=False + dry = False if ctx.shared is None: # use cwd shared_basepath = pathlib.Path(".") diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 7d4a22e2d..e55c013b3 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -752,6 +752,9 @@ def _create( complex_run = [ SepTopComplexRunUnit( protocol=self, + stateA=stateA, + stateB=stateB, + alchemical_components=alchem_comps, setup=complex_setup[i], generation=0, repeat_id=int(uuid.uuid4()), name=(f"SepTop RBFE, {alchname} complex leg: " From 1551bc297c048c6eb1787a7546663550165ebbeb Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 14:13:08 +0100 Subject: [PATCH 041/163] Add simtype --- openfe/protocols/openmm_septop/base.py | 60 +++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index c81039e20..5914ec41d 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -837,6 +837,54 @@ def _get_components(self) -> tuple[dict[str, list[Component]], """ ... + @staticmethod + def _detect_phase(state_a, state_b): + """ + Detect phase according to the components in the input chemical state. + + Complex state is assumed if both states have ligands and protein + components. + + Solvent state is assumed + + Vacuum state is assumed if only either a ligand or a protein is present + in each of the states. + + Parameters + ---------- + state_a : gufe.state.State + Source state for the alchemical transformation. + state_b : gufe.state.State + Destination state for the alchemical transformation. + + Returns + ------- + phase : str + Phase name. "vacuum", "solvent" or "complex". + component_keys : list[str] + List of component keys to extract from states. + """ + states = (state_a, state_b) + # where to store the data to be returned + + # Order of phases is important! We have to check complex first and + # solvent second. + key_options = { + "complex": ["ligand", "protein", "solvent"], + "solvent": ["ligand", "solvent"], + "vacuum": ["ligand"], + } + for phase, keys in key_options.items(): + if all([key in state for state in states for key in keys]): + detected_phase = phase + break + else: + raise ValueError( + "Could not detect phase from system states. Make sure the " + "component in both systems match." + ) + + return detected_phase @abc.abstractmethod def _handle_settings(self): @@ -1279,6 +1327,10 @@ def _execute( else: shared_basepath = ctx.shared + phase = self._detect_phase( + self._inputs['stateA'], self._inputs['stateA'] + ) # infer phase from systems and components + print(phase) settings = self._handle_settings() alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() serialized_system = setup.outputs["system"] @@ -1355,9 +1407,15 @@ def _execute( 'output_settings'].output_filename chk = settings['output_settings'].checkpoint_storage_filename return { + 'repeat_id': self._inputs['repeat_id'], + 'generation': self._inputs['generation'], + 'simtype': phase, 'nc': nc, 'last_checkpoint': chk, **unit_result_dict, } else: - return {'debug': {'sampler': sampler}} + return { + 'repeat_id': self._inputs['repeat_id'], + 'generation': self._inputs['generation'], + 'debug': {'sampler': sampler}} From eebff503c548dc0cea9835c11f441f2de4e6ad11 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 14:33:20 +0100 Subject: [PATCH 042/163] Remove nocutoff --- openfe/protocols/openmm_septop/base.py | 3 ++- openfe/protocols/openmm_septop/equil_septop_method.py | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 5914ec41d..09fd2e8c5 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -863,6 +863,8 @@ def _detect_phase(state_a, state_b): Phase name. "vacuum", "solvent" or "complex". component_keys : list[str] List of component keys to extract from states. + + Code obtained from feflow/protocols/nonequilibrium_cycling.py """ states = (state_a, state_b) # where to store the data to be returned @@ -913,7 +915,6 @@ def _handle_settings(self): """ ... - def _get_lambda_schedule( self, settings: dict[str, SettingsBaseModel] ) -> dict[str, npt.NDArray]: diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index e55c013b3..7b5f00b57 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -437,9 +437,7 @@ def _default_settings(cls): return SepTopSettings( protocol_repeats=1, solvent_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), - complex_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings( - nonbonded_method='nocutoff', - ), + complex_forcefield_settings=settings.OpenMMSystemGeneratorFFSettings(), thermo_settings=settings.ThermoSettings( temperature=298.15 * unit.kelvin, pressure=1 * unit.bar, From 4a5922d1427b653eef1717d09b41a4cac8781760 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 16:16:50 +0100 Subject: [PATCH 043/163] Small fixes --- openfe/protocols/openmm_septop/base.py | 38 ------------------- .../openmm_septop/equil_septop_method.py | 19 +++++----- .../openmm_septop/equil_septop_settings.py | 2 +- .../openmm_septop/femto_restraints.py | 1 - 4 files changed, 11 insertions(+), 49 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 09fd2e8c5..0257dfd95 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -772,44 +772,6 @@ def run(self, dry=False, verbose=True, # Serialize system, state and integrator serialize(system, system_outfile) - # # Set up context - # platform = get_openmm_platform( - # settings['engine_settings'].compute_platform) - # context = openmm.Context(system, integrator, platform) - # context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors()) - # context.setPositions(positions_AB) - # - # try: - # # SERIALIZE SYSTEM, STATE, INTEGRATOR - # # need to set velocities to temperature so serialized state - # # features velocities, - # # which is important for usability by the Folding@Home openmm-core - # thermodynamic_settings = settings['thermo_settings'] - # temperature = to_openmm(thermodynamic_settings.temperature) - # context.setVelocitiesToTemperature(temperature) - # - # # state needs to include positions, forces, velocities, and energy - # # to be usable by the Folding@Home openmm-core - # state_ = context.getState( - # getPositions=True, getForces=True, getVelocities=True, - # getEnergy=True - # ) - # system_ = context.getSystem() - # integrator_ = context.getIntegrator() - # - # system_outfile = shared_basepath / "system.xml.bz2" - # state_outfile = shared_basepath / "state.xml.bz2" - # integrator_outfile = shared_basepath / "integrator.xml.bz2" - # - # # Serialize system, state and integrator - # serialize(system_, system_outfile) - # serialize(state_, state_outfile) - # serialize(integrator_, integrator_outfile) - # - # finally: - # # Explicit cleanup for GPU resources - # del context, integrator - return { "system": system_outfile, "topology": topology_file, diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 7b5f00b57..596831455 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -703,7 +703,8 @@ def _create( system_validation.validate_protein(stateA) # Get the name of the alchemical species - alchname = alchem_comps['stateA'][0].name + alchname_A = alchem_comps['stateA'][0].name + alchname_B = alchem_comps['stateB'][0].name # Create list units for complex and solvent transforms @@ -714,8 +715,8 @@ def _create( stateB=stateB, alchemical_components=alchem_comps, generation=0, repeat_id=int(uuid.uuid4()), - name=(f"SepTop RBFE, {alchname} solvent leg: " - f"repeat {i} generation 0"), + name=(f"SepTop RBFE Setup, transformation {alchname_A} to " + f"{alchname_B}, solvent leg: repeat {i} generation 0"), ) for i in range(self.settings.protocol_repeats) ] @@ -728,8 +729,8 @@ def _create( alchemical_components=alchem_comps, setup=solvent_setup[i], generation=0, repeat_id=int(uuid.uuid4()), - name=(f"SepTop RBFE, {alchname} solvent leg: " - f"repeat {i} generation 0"), + name=(f"SepTop RBFE Run, transformation {alchname_A} to " + f"{alchname_B}, solvent leg: repeat {i} generation 0"), ) for i in range(self.settings.protocol_repeats) ] @@ -741,8 +742,8 @@ def _create( stateB=stateB, alchemical_components=alchem_comps, generation=0, repeat_id=int(uuid.uuid4()), - name=(f"SepTop RBFE, {alchname} complex leg: " - f"repeat {i} generation 0"), + name=(f"SepTop RBFE Setup, transformation {alchname_A} to " + f"{alchname_B}, complex leg: repeat {i} generation 0"), ) for i in range(self.settings.protocol_repeats) ] @@ -755,8 +756,8 @@ def _create( alchemical_components=alchem_comps, setup=complex_setup[i], generation=0, repeat_id=int(uuid.uuid4()), - name=(f"SepTop RBFE, {alchname} complex leg: " - f"repeat {i} generation 0"), + name=(f"SepTop RBFE Run, transformation {alchname_A} to " + f"{alchname_B}, complex leg: repeat {i} generation 0"), ) for i in range(self.settings.protocol_repeats) ] diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 848bdecfa..45a4bfb74 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -127,7 +127,7 @@ def must_be_monotonic(cls, v): difference = np.diff(v) - if not all(i >= 0. for i in difference): + if not all(i >= 0. for i in difference) or not all(i <= 0. for i in difference): errmsg = f"The lambda schedule is not monotonic, got schedule {v}." raise ValueError(errmsg) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index bbba6c281..3959bb6bb 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -707,7 +707,6 @@ def create_boresch_restraint( force = openmm.CustomCompoundBondForce(n_particles, energy_fn) if ctx_parameter is not None: - print(ctx_parameter) force.addGlobalParameter(ctx_parameter, 1.0) geometry = _compute_boresch_geometry(receptor_atoms, ligand_atoms, coords) From bcaefd8bbe63173068d26492f93abdf6f772b2da Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 16:36:03 +0100 Subject: [PATCH 044/163] Change monotonic check --- openfe/protocols/openmm_septop/equil_septop_settings.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 45a4bfb74..379a2c065 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -127,7 +127,9 @@ def must_be_monotonic(cls, v): difference = np.diff(v) - if not all(i >= 0. for i in difference) or not all(i <= 0. for i in difference): + monotonic = np.all(difference <= 0) or np.all(difference >= 0) + + if not monotonic: errmsg = f"The lambda schedule is not monotonic, got schedule {v}." raise ValueError(errmsg) From 23aecb5bce4f08e676edce427b88c1bf8ca68827 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 27 Nov 2024 17:29:11 +0100 Subject: [PATCH 045/163] Put troubleshooting pdb files in the sharedbase path for now --- openfe/protocols/openmm_septop/base.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 0257dfd95..6ecd9a799 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -661,14 +661,14 @@ def run(self, dry=False, verbose=True, ) simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_A, positions_A, - open('outputA.pdb', + open(shared_basepath / 'outputA.pdb', 'w')) omm_topology_B, omm_system_B, positions_B = self._get_omm_objects( system_modeller_B, system_generator, list(smc_comps_B.values()) ) simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, positions_B, - open('outputB.pdb', + open(shared_basepath / 'outputB.pdb', 'w')) omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( @@ -676,7 +676,7 @@ def run(self, dry=False, verbose=True, ) simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, positions_AB, - open('outputAB.pdb', 'w')) + open(shared_basepath / 'outputAB.pdb', 'w')) # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") @@ -687,9 +687,9 @@ def run(self, dry=False, verbose=True, omm_system_B, omm_topology_B, positions_B, settings, dry ) simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_A, equ_positions_A, open('outputA_equ.pdb', 'w')) + omm_topology_A, equ_positions_A, open(shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_B, equ_positions_B, open('outputB_equ.pdb', 'w')) + omm_topology_B, equ_positions_B, open(shared_basepath / 'outputB_equ.pdb', 'w')) # 7. Get all the right atom indices for alignments comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) @@ -709,7 +709,7 @@ def run(self, dry=False, verbose=True, atom_indices_A, atom_indices_B) simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, updated_positions_B, - open('outputB_new.pdb', + open(shared_basepath / 'outputB_new.pdb', 'w')) # Get atom indices for ligand A and ligand B and the solvent in the @@ -737,13 +737,11 @@ def run(self, dry=False, verbose=True, off_A = alchem_comps["stateA"][0].to_openff().to_topology() lig_A_pos = positions_AB[atom_indices_AB_A[0]:atom_indices_AB_A[-1]+1, :] / omm_units.nanometers * unit.nanometer self._set_positions(off_A, lig_A_pos) - off_A.to_file('molA.pdb') off_B = alchem_comps["stateB"][0].to_openff().to_topology() lig_B_pos = positions_AB[ atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :] / omm_units.nanometers * unit.nanometer self._set_positions(off_B, lig_B_pos) - off_B.to_file('molB.pdb') ligand_A_ref_inxs, ligand_B_ref_inxs = select_ligand_idxs(off_A, off_B) From 27e1ea74a7a2bc818cf5f340c04f0e7a378176a2 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 28 Nov 2024 12:13:59 +0100 Subject: [PATCH 046/163] Fix scaling restraints --- openfe/protocols/openmm_septop/femto_restraints.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 3959bb6bb..96f9f8e5e 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -710,11 +710,11 @@ def create_boresch_restraint( force.addGlobalParameter(ctx_parameter, 1.0) geometry = _compute_boresch_geometry(receptor_atoms, ligand_atoms, coords) - + print(geometry.dist_0) # Scale the k_theta_a - distance_0 = 5.0 # based on original SepTop implementation. + distance_0 = 0.5 # based on original SepTop implementation. scale = (geometry.dist_0 / distance_0) ** 2 - + print(scale) parameters = [] for key, value in [ @@ -734,6 +734,8 @@ def create_boresch_restraint( force.addPerBondParameter(key) parameters.append(value.value_in_unit_system(openmm.unit.md_unit_system)) + print(parameters) + force.addBond(receptor_atoms + ligand_atoms, parameters) force.setUsesPeriodicBoundaryConditions(False) force.setName("alignment-restraint") From 026a0ef87bebd4fa5a9fffed5b2fee251a4af879 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 28 Nov 2024 13:19:55 +0100 Subject: [PATCH 047/163] Update boresch scaling --- openfe/protocols/openmm_septop/femto_restraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 96f9f8e5e..9affee4ea 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -712,7 +712,7 @@ def create_boresch_restraint( geometry = _compute_boresch_geometry(receptor_atoms, ligand_atoms, coords) print(geometry.dist_0) # Scale the k_theta_a - distance_0 = 0.5 # based on original SepTop implementation. + distance_0 = 5.0 * _ANGSTROM # based on original SepTop implementation. scale = (geometry.dist_0 / distance_0) ** 2 print(scale) parameters = [] From a78481f5d2b52eca9be1f53f95394c72c826a83e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 28 Nov 2024 16:03:51 +0100 Subject: [PATCH 048/163] testing something --- openfe/protocols/openmm_septop/femto_restraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 9affee4ea..46a71a28c 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -719,7 +719,7 @@ def create_boresch_restraint( for key, value in [ ("k_dist_a", k_distance), - ("k_theta_a", k_theta * scale), + ("k_theta_a", k_theta * 10), ("k_theta_b", k_theta), ("k_phi_a", k_theta), ("k_phi_b", k_theta), From b262a9e307f08a72a7467a5265e8181b2a35b14a Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 2 Dec 2024 13:40:47 +0100 Subject: [PATCH 049/163] Test out not doing a preequ --- openfe/protocols/openmm_septop/base.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 6ecd9a799..3b980ece0 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -680,12 +680,14 @@ def run(self, dry=False, verbose=True, # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") - equ_positions_A = self._pre_equilibrate( - omm_system_A, omm_topology_A, positions_A, settings, dry - ) - equ_positions_B = self._pre_equilibrate( - omm_system_B, omm_topology_B, positions_B, settings, dry - ) + # equ_positions_A = self._pre_equilibrate( + # omm_system_A, omm_topology_A, positions_A, settings, dry + # ) + # equ_positions_B = self._pre_equilibrate( + # omm_system_B, omm_topology_B, positions_B, settings, dry + # ) + equ_positions_A = positions_A + equ_positions_B = positions_B simtk.openmm.app.pdbfile.PDBFile.writeFile( omm_topology_A, equ_positions_A, open(shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( From 063c59a1248f53d1e89b4e40b28b81617848af60 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 2 Dec 2024 15:17:38 +0100 Subject: [PATCH 050/163] Change min length solvent --- openfe/protocols/openmm_septop/equil_septop_method.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 596831455..85f20b125 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -466,6 +466,7 @@ def _default_settings(cls): ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=19, + minimization_steps=10000, equilibration_length=1.0 * unit.nanosecond, production_length=10.0 * unit.nanosecond, ), From 702b639b7b24db2e9a5f0fe0f3c3df2365953f43 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 3 Dec 2024 11:19:56 +0100 Subject: [PATCH 051/163] Change phase detection --- openfe/protocols/openmm_septop/base.py | 9 +++++---- openfe/protocols/openmm_septop/equil_septop_method.py | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 3b980ece0..f6b6a3319 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1290,12 +1290,13 @@ def _execute( else: shared_basepath = ctx.shared - phase = self._detect_phase( - self._inputs['stateA'], self._inputs['stateA'] - ) # infer phase from systems and components - print(phase) settings = self._handle_settings() alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() + if prot_comp: + phase = "complex" + else: + phase = "solvent" + print(phase) serialized_system = setup.outputs["system"] serialized_topology = setup.outputs["topology"] diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 85f20b125..bb119f338 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -129,12 +129,14 @@ def get_individual_estimates(self) -> dict[str, list[tuple[unit.Quantity, unit.Q solv_dGs = [] for pus in self.data['complex'].values(): + print(pus) complex_dGs.append(( pus[0].outputs['unit_estimate'], pus[0].outputs['unit_estimate_error'] )) for pus in self.data['solvent'].values(): + print(pus) solv_dGs.append(( pus[0].outputs['unit_estimate'], pus[0].outputs['unit_estimate_error'] From 13c7724a298ef8b801f7776048864090b538bfae Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 3 Dec 2024 14:06:54 +0100 Subject: [PATCH 052/163] Adding print statements for debugging --- openfe/protocols/openmm_septop/femto_restraints.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 46a71a28c..ec4caae98 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -531,15 +531,21 @@ def select_receptor_idxs( # chosen to match the SepTop reference implementation at commit 3705ba5 max_distance = 0.8 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) # max_distance = 3 + print('max_distance', max_distance) r3_distances_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) + print(r3_distances_avg) max_distance_mask = r3_distances_avg.max(axis=-1) < max_distance + print(max_distance_mask) r3_distances_avg = r3_distances_avg[max_distance_mask] + print(r3_distances_avg) valid_r3_idxs = numpy.array(valid_r3_idxs)[max_distance_mask].tolist() + print(valid_r3_idxs) r3_distances_prod = r3_distances_avg[:, 0] * r3_distances_avg[:, 1] + print(r3_distances_prod) found_r3 = valid_r3_idxs[r3_distances_prod.argmax()] return found_r1, found_r2, found_r3 From 6b393d5a8f404dcf3367381bccd91010f64a3571 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 4 Dec 2024 10:24:48 +0100 Subject: [PATCH 053/163] Add print statements to help debug --- openfe/protocols/openmm_septop/base.py | 10 +++++----- openfe/protocols/openmm_septop/equil_septop_method.py | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index f6b6a3319..f38759335 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -759,11 +759,11 @@ def run(self, dry=False, verbose=True, ligand_A_ref_inxs, ligand_B_ref_inxs, ligand_A_inxs, ligand_B_inxs) # # Check that the restraints are correctly applied by running a short equilibration - # equ_positions_restraints = self._pre_equilibrate( - # system, omm_topology_AB, positions_AB, settings, dry - # ) - # simtk.openmm.app.pdbfile.PDBFile.writeFile( - # omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) + equ_positions_restraints = self._pre_equilibrate( + system, omm_topology_AB, positions_AB, settings, dry + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile( + omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) # Here we could also apply REST diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index bb119f338..154a79dfd 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -772,16 +772,22 @@ def _gather( ) -> dict[str, dict[str, Any]]: # result units will have a repeat_id and generation # first group according to repeat_id + print("Gathering results test1") unsorted_solvent_repeats = defaultdict(list) unsorted_complex_repeats = defaultdict(list) for d in protocol_dag_results: + print(d) pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: + print(pu) if not pu.ok(): + print('PU not ok') continue if pu.outputs['simtype'] == 'solvent': + print('Getting solvent pus') unsorted_solvent_repeats[pu.outputs['repeat_id']].append(pu) else: + print('Getting complex pus') unsorted_complex_repeats[pu.outputs['repeat_id']].append(pu) repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { @@ -792,6 +798,7 @@ def _gather( for k, v in unsorted_complex_repeats.items(): repeats['complex'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) + print(repeats) return repeats From f86601e9fa738eb2f16cfadb95be49795d204399 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 4 Dec 2024 10:56:27 +0100 Subject: [PATCH 054/163] Save prequ file --- openfe/protocols/openmm_septop/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index f38759335..d86ca4a16 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -763,7 +763,7 @@ def run(self, dry=False, verbose=True, system, omm_topology_AB, positions_AB, settings, dry ) simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_AB, equ_positions_restraints, open('outputAB_restrained.pdb', 'w')) + omm_topology_AB, equ_positions_restraints, open(shared_basepath / 'outputAB_restrained.pdb', 'w')) # Here we could also apply REST From 737298529898d8c950313983c0d0798b7c3d6b61 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 4 Dec 2024 11:26:15 +0100 Subject: [PATCH 055/163] Run short equ --- openfe/protocols/openmm_septop/base.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index d86ca4a16..ad94a04d1 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -725,12 +725,6 @@ def run(self, dry=False, verbose=True, positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] - topology_file = shared_basepath / 'topology.pdb' - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, - positions_AB, - open(topology_file, - 'w')) - # 9. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) @@ -762,8 +756,11 @@ def run(self, dry=False, verbose=True, equ_positions_restraints = self._pre_equilibrate( system, omm_topology_AB, positions_AB, settings, dry ) - simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_AB, equ_positions_restraints, open(shared_basepath / 'outputAB_restrained.pdb', 'w')) + topology_file = shared_basepath / 'topology.pdb' + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, + equ_positions_restraints, + open(topology_file, + 'w')) # Here we could also apply REST From 3e848a6e1f7bd7484c337c545df04f1d0d98690a Mon Sep 17 00:00:00 2001 From: IAlibay Date: Wed, 4 Dec 2024 13:24:29 +0000 Subject: [PATCH 056/163] first pass at abstract classes --- .../protocols/openmm_utils/omm_restraints.py | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 openfe/protocols/openmm_utils/omm_restraints.py diff --git a/openfe/protocols/openmm_utils/omm_restraints.py b/openfe/protocols/openmm_utils/omm_restraints.py new file mode 100644 index 000000000..2a62d30ae --- /dev/null +++ b/openfe/protocols/openmm_utils/omm_restraints.py @@ -0,0 +1,64 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Classes for applying restraints to OpenMM Systems. + +Acknowledgements +---------------- +Many of the classes here are at least in part inspired, if not taken from +`Yank `_ and +`OpenMMTools `_. + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from typing import Optional, Union + +from openmmtools.states import GlobalParameterState + + +class RestraintParameterState(GlobalParameterState): + """ + Composable state to control `lambda_restraints` OpenMM Force parameters. + + See :class:`openmmtools.states.GlobalParameterState` for more details. + + Parameters + ---------- + parameters_name_suffix : Optional[str] + If specified, the state will control a modified version of the parameter + ``lambda_restraints_{parameters_name_suffix}` instead of just ``lambda_restraints``. + lambda_restraints : Optional[float] + The strength of the restraint. If defined, must be between 0 and 1. + + Acknowledgement + --------------- + Partially reproduced from Yank. + """ + + lambda_restraints = GlobalParameterState.GlobalParameter('lambda_restraints', standard_value=1.0) + + @lambda_restraints.validator + def lambda_restraints(self, instance, new_value): + if new_value is not None and not (0.0 <= new_value <= 1.0): + errmsg = ("lambda_restraints must be between 0.0 and 1.0, " + f"got {new_value}") + raise ValueError(errmsg) + # Not crashing out on None to match upstream behaviour + return new_value + + +class BaseHostGuestRestraints(abc.ABC): + """ + An abstract base class for defining objects that apply a restraint between + two entities (referred to as a Host and a Guest). + + + TODO + ---- + Add some examples here. + """ + def __init__(self, host_atoms: list[int], guest_atoms: list[int], restraint_settings: SettingBaseModel, restraint_geometry: BaseRestraintGeometry): + From a401c98c306f4b7600b4ee712830d1b15955c7b3 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 4 Dec 2024 15:11:30 +0100 Subject: [PATCH 057/163] Update gather to separate setup and run results --- openfe/protocols/openmm_septop/base.py | 154 +++++++++++------- .../openmm_septop/equil_septop_method.py | 35 +++- .../openmm_septop/femto_restraints.py | 7 - 3 files changed, 120 insertions(+), 76 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index ad94a04d1..95a18483d 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -573,6 +573,66 @@ def _add_restraints( """ ... + def get_smc_comps(self, alchem_comps, smc_comps): + # 6. Get smcs for the different states and the common smcs + smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} + smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} + smc_off_both = {m: m.to_openff() for m in smc_comps + if (m not in alchem_comps["stateA"] and m not in + alchem_comps["stateB"])} + smc_comps_A = smc_off_A | smc_off_both + smc_comps_B = smc_off_B | smc_off_both + smc_comps_AB = smc_off_A | smc_off_B | smc_off_both + + return smc_comps_A, smc_comps_B, smc_comps_AB, smc_off_B + + def get_system( + self, solv_comp, prot_comp, smc_comp, settings): + # 5. Get system generator + system_generator = self._get_system_generator(settings, solv_comp) + + # 8. Get modeller for stateA, stateB, and stateAB + system_modeller, comp_resids = self._get_modeller( + prot_comp, solv_comp, smc_comp, + system_generator, settings['solvation_settings'], + ) + + # 5. Get OpenMM topology, positions and system + omm_topology, omm_system, positions = self._get_omm_objects( + system_modeller, system_generator, list(smc_comp.values()) + ) + + return omm_system, omm_topology, positions, system_modeller, comp_resids + + + def get_system_AB( + self, solv_comp, system_modeller_A, smc_comps_AB, smc_off_B, settings, shared_basepath): + # 5. Get system generator + system_generator = self._get_system_generator(settings, solv_comp) + + # Get modeller B only ligand B + modeller_ligandB, comp_resids_ligB = self._get_modeller( + None, None, smc_off_B, + system_generator, settings['solvation_settings'], + ) + + # Take the modeller from system A --> every water/ion should be in + # the same location + system_modeller_AB = copy.copy(system_modeller_A) + system_modeller_AB.add(modeller_ligandB.topology, + modeller_ligandB.positions) + + omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( + system_modeller_AB, system_generator, list(smc_comps_AB.values()) + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, + positions_AB, + open( + shared_basepath / 'outputAB.pdb', + 'w')) + + return omm_system_AB, omm_topology_AB, positions_AB, system_modeller_AB + def run(self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: @@ -605,89 +665,59 @@ def run(self, dry=False, verbose=True, # 1. Get components self.logger.info("Creating and setting up the OpenMM systems") alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() + smc_comps_A, smc_comps_B, smc_comps_AB, smc_off_B = self.get_smc_comps( + alchem_comps, smc_comps) # 2. Get settings settings = self._handle_settings() - # 5. Get system generator - system_generator = self._get_system_generator(settings, solv_comp) - - # 6. Get smcs for the different states and the common smcs - smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} - smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} - smc_off_both = {m: m.to_openff() for m in smc_comps - if (m not in alchem_comps["stateA"] and m not in - alchem_comps["stateB"])} - smc_comps_A = smc_off_A | smc_off_both - smc_comps_B = smc_off_B | smc_off_both - smc_comps_AB = smc_off_A | smc_off_B | smc_off_both - # 7. Assign partial charges here to only do it once for smcs in stateA # and stateB (hence only charge e.g. cofactors ones) self._assign_partial_charges(settings['charge_settings'], smc_comps_AB) - # 8. Get modeller for stateA, stateB, and stateAB - system_modeller_A, comp_resids_A = self._get_modeller( - prot_comp, solv_comp, smc_comps_A, - system_generator, settings['solvation_settings'], - ) - system_modeller_B, comp_resids_B = self._get_modeller( - prot_comp, solv_comp, smc_comps_B, - system_generator, settings['solvation_settings'], + # # Get the OpenMM systems + omm_system_A, omm_topology_A, positions_A, modeller_A, comp_resids_A = self.get_system( + solv_comp, + prot_comp, + smc_comps_A, + settings, ) - # Get modeller B only ligand B - modeller_ligandB, comp_resids_ligB = self._get_modeller( - None, None, smc_off_B, - system_generator, settings['solvation_settings'], + omm_system_B, omm_topology_B, positions_B, modeller_B, comp_resids_B = self.get_system( + solv_comp, + prot_comp, + smc_comps_B, + settings, ) - # Take the modeller from system A --> every water/ion should be in - # the same location - system_modeller_AB = copy.copy(system_modeller_A) - system_modeller_AB.add(modeller_ligandB.topology, - modeller_ligandB.positions) + omm_system_AB, omm_topology_AB, positions_AB, modeller_AB = self.get_system_AB( + solv_comp, + modeller_A, + smc_comps_AB, + smc_off_B, + settings, + shared_basepath + ) # We assume that modeller.add will always put the ligand B towards # the end of the residues resids_A = list(itertools.chain(*comp_resids_A.values())) - resids_AB = [r.index for r in system_modeller_AB.topology.residues()] + resids_AB = [r.index for r in modeller_AB.topology.residues()] diff_resids = list(set(resids_AB) - set(resids_A)) - comp_resids_AB = comp_resids_A | {alchem_comps["stateB"][0]: np.array(diff_resids)} + comp_resids_AB = comp_resids_A | { + alchem_comps["stateB"][0]: np.array(diff_resids)} - # 5. Get OpenMM topology, positions and system - omm_topology_A, omm_system_A, positions_A = self._get_omm_objects( - system_modeller_A, system_generator, list(smc_comps_A.values()) - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_A, - positions_A, - open(shared_basepath / 'outputA.pdb', - 'w')) - omm_topology_B, omm_system_B, positions_B = self._get_omm_objects( - system_modeller_B, system_generator, list(smc_comps_B.values()) - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, - positions_B, - open(shared_basepath / 'outputB.pdb', - 'w')) - - omm_topology_AB, omm_system_AB, positions_AB = self._get_omm_objects( - system_modeller_AB, system_generator, list(smc_comps_AB.values()) - ) - simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, - positions_AB, - open(shared_basepath / 'outputAB.pdb', 'w')) # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") - # equ_positions_A = self._pre_equilibrate( - # omm_system_A, omm_topology_A, positions_A, settings, dry - # ) - # equ_positions_B = self._pre_equilibrate( - # omm_system_B, omm_topology_B, positions_B, settings, dry - # ) - equ_positions_A = positions_A - equ_positions_B = positions_B + equ_positions_A = self._pre_equilibrate( + omm_system_A, omm_topology_A, positions_A, settings, dry + ) + equ_positions_B = self._pre_equilibrate( + omm_system_B, omm_topology_B, positions_B, settings, dry + ) + # equ_positions_A = positions_A + # equ_positions_B = positions_B simtk.openmm.app.pdbfile.PDBFile.writeFile( omm_topology_A, equ_positions_A, open(shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 154a79dfd..5416e6c10 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -773,8 +773,10 @@ def _gather( # result units will have a repeat_id and generation # first group according to repeat_id print("Gathering results test1") - unsorted_solvent_repeats = defaultdict(list) - unsorted_complex_repeats = defaultdict(list) + unsorted_solvent_repeats_setup = defaultdict(list) + unsorted_solvent_repeats_run = defaultdict(list) + unsorted_complex_repeats_setup = defaultdict(list) + unsorted_complex_repeats_run = defaultdict(list) for d in protocol_dag_results: print(d) pu: gufe.ProtocolUnitResult @@ -785,18 +787,37 @@ def _gather( continue if pu.outputs['simtype'] == 'solvent': print('Getting solvent pus') - unsorted_solvent_repeats[pu.outputs['repeat_id']].append(pu) + if 'Run' in pu.name: + print('Run') + unsorted_solvent_repeats_run[ + pu.outputs['repeat_id']].append(pu) + elif 'Setup' in pu.name: + print('Setup') + unsorted_solvent_repeats_setup[ + pu.outputs['repeat_id']].append(pu) else: print('Getting complex pus') - unsorted_complex_repeats[pu.outputs['repeat_id']].append(pu) + if 'Run' in pu.name: + print('Run') + unsorted_solvent_repeats_run[ + pu.outputs['repeat_id']].append(pu) + elif 'Setup' in pu.name: + print('Setup') + unsorted_solvent_repeats_setup[ + pu.outputs['repeat_id']].append(pu) repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { - 'solvent': {}, 'complex': {}, + 'solvent_setup': {}, 'solvent': {}, + 'complex_setup': {}, 'complex': {}, } - for k, v in unsorted_solvent_repeats.items(): + for k, v in unsorted_solvent_repeats_setup.items(): + repeats['solvent_setup'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) + for k, v in unsorted_solvent_repeats_run.items(): repeats['solvent'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) - for k, v in unsorted_complex_repeats.items(): + for k, v in unsorted_complex_repeats_setup.items(): + repeats['complex_setup'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) + for k, v in unsorted_complex_repeats_run.items(): repeats['complex'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) print(repeats) return repeats diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index ec4caae98..994708f63 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -530,22 +530,15 @@ def select_receptor_idxs( # chosen to match the SepTop reference implementation at commit 3705ba5 max_distance = 0.8 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) - # max_distance = 3 - print('max_distance', max_distance) r3_distances_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) - print(r3_distances_avg) max_distance_mask = r3_distances_avg.max(axis=-1) < max_distance - print(max_distance_mask) r3_distances_avg = r3_distances_avg[max_distance_mask] - print(r3_distances_avg) valid_r3_idxs = numpy.array(valid_r3_idxs)[max_distance_mask].tolist() - print(valid_r3_idxs) r3_distances_prod = r3_distances_avg[:, 0] * r3_distances_avg[:, 1] - print(r3_distances_prod) found_r3 = valid_r3_idxs[r3_distances_prod.argmax()] return found_r1, found_r2, found_r3 From c2e2d8a82b0391bf9b537ded13703cebeeed2986 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 5 Dec 2024 09:38:14 +0100 Subject: [PATCH 058/163] Fix gather --- openfe/protocols/openmm_septop/base.py | 81 ++++++------------- .../openmm_septop/equil_septop_method.py | 4 +- .../protocols/test_openmm_septop_protocol.py | 6 +- 3 files changed, 28 insertions(+), 63 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 95a18483d..1c88e5b89 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -80,6 +80,7 @@ logger = logging.getLogger(__name__) +from openmmtools.tests.test_alchemy import compare_system_energies class BaseSepTopSetupUnit(gufe.ProtocolUnit): """ @@ -696,7 +697,7 @@ def run(self, dry=False, verbose=True, smc_comps_AB, smc_off_B, settings, - shared_basepath + self.shared_basepath ) # We assume that modeller.add will always put the ligand B towards @@ -719,9 +720,9 @@ def run(self, dry=False, verbose=True, # equ_positions_A = positions_A # equ_positions_B = positions_B simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_A, equ_positions_A, open(shared_basepath / 'outputA_equ.pdb', 'w')) + omm_topology_A, equ_positions_A, open(self.shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( - omm_topology_B, equ_positions_B, open(shared_basepath / 'outputB_equ.pdb', 'w')) + omm_topology_B, equ_positions_B, open(self.shared_basepath / 'outputB_equ.pdb', 'w')) # 7. Get all the right atom indices for alignments comp_atomids_A = self._get_atom_indices(omm_topology_A, comp_resids_A) @@ -741,7 +742,7 @@ def run(self, dry=False, verbose=True, atom_indices_A, atom_indices_B) simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_B, updated_positions_B, - open(shared_basepath / 'outputB_new.pdb', + open(self.shared_basepath / 'outputB_new.pdb', 'w')) # Get atom indices for ligand A and ligand B and the solvent in the @@ -757,7 +758,22 @@ def run(self, dry=False, verbose=True, # 9. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") + ref_system = copy.copy(omm_system_AB) apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) + alchemical_regions = openmmtools.alchemy.AlchemicalRegion( + alchemical_atoms=atom_indices_AB_A + atom_indices_AB_B) + print(alchemical_regions) + print(openmmtools.tests.test_alchemy.compute_energy(omm_system_A, + positions_A)) + print(openmmtools.tests.test_alchemy.compute_energy(omm_system_B, + positions_B)) + print(openmmtools.tests.test_alchemy.compute_energy(ref_system, + positions_AB)) + print(openmmtools.tests.test_alchemy.compute_energy(omm_system_AB, + positions_AB)) + compare_system_energies( + ref_system, omm_system_AB, alchemical_regions, positions_AB) + # 10. Apply Restraints off_A = alchem_comps["stateA"][0].to_openff().to_topology() @@ -786,7 +802,7 @@ def run(self, dry=False, verbose=True, equ_positions_restraints = self._pre_equilibrate( system, omm_topology_AB, positions_AB, settings, dry ) - topology_file = shared_basepath / 'topology.pdb' + topology_file = self.shared_basepath / 'topology.pdb' simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, equ_positions_restraints, open(topology_file, @@ -794,7 +810,7 @@ def run(self, dry=False, verbose=True, # Here we could also apply REST - system_outfile = shared_basepath / "system.xml.bz2" + system_outfile = self.shared_basepath / "system.xml.bz2" # Serialize system, state and integrator serialize(system, system_outfile) @@ -826,57 +842,6 @@ def _get_components(self) -> tuple[dict[str, list[Component]], """ ... - @staticmethod - def _detect_phase(state_a, state_b): - """ - Detect phase according to the components in the input chemical state. - - Complex state is assumed if both states have ligands and protein - components. - - Solvent state is assumed - - Vacuum state is assumed if only either a ligand or a protein is present - in each of the states. - - Parameters - ---------- - state_a : gufe.state.State - Source state for the alchemical transformation. - state_b : gufe.state.State - Destination state for the alchemical transformation. - - Returns - ------- - phase : str - Phase name. "vacuum", "solvent" or "complex". - component_keys : list[str] - List of component keys to extract from states. - - Code obtained from feflow/protocols/nonequilibrium_cycling.py - """ - states = (state_a, state_b) - # where to store the data to be returned - - # Order of phases is important! We have to check complex first and - # solvent second. - key_options = { - "complex": ["ligand", "protein", "solvent"], - "solvent": ["ligand", "solvent"], - "vacuum": ["ligand"], - } - for phase, keys in key_options.items(): - if all([key in state for state in states for key in keys]): - detected_phase = phase - break - else: - raise ValueError( - "Could not detect phase from system states. Make sure the " - "component in both systems match." - ) - - return detected_phase - @abc.abstractmethod def _handle_settings(self): """ @@ -1323,7 +1288,7 @@ def _execute( phase = "complex" else: phase = "solvent" - print(phase) + serialized_system = setup.outputs["system"] serialized_topology = setup.outputs["topology"] diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 5416e6c10..f04112c17 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -799,11 +799,11 @@ def _gather( print('Getting complex pus') if 'Run' in pu.name: print('Run') - unsorted_solvent_repeats_run[ + unsorted_complex_repeats_run[ pu.outputs['repeat_id']].append(pu) elif 'Setup' in pu.name: print('Setup') - unsorted_solvent_repeats_setup[ + unsorted_complex_repeats_setup[ pu.outputs['repeat_id']].append(pu) repeats: dict[str, dict[str, list[gufe.ProtocolUnitResult]]] = { diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index daa9d357b..ad0d3547d 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -305,9 +305,9 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): # check system parametrisation works even if confgen fails s = SepTopProtocol.default_settings() s.protocol_repeats = 1 - s.solvent_equil_simulation_settings.minimization_steps = 1 - s.solvent_equil_simulation_settings.equilibration_length_nvt = 1 * unit.picosecond - s.solvent_equil_simulation_settings.equilibration_length = 1 * unit.picosecond + s.solvent_equil_simulation_settings.minimization_steps = 10 + s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond + s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond s.solvent_solvation_settings.box_shape = 'dodecahedron' s.solvent_solvation_settings.solvent_padding = 1.5 * unit.nanometer From ef050e5ab47fc228d98d6fba00476b331c46ab3d Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 5 Dec 2024 15:31:32 +0000 Subject: [PATCH 059/163] A start at restraints and forces --- openfe/protocols/openmm_utils/omm_forces.py | 134 +++++++++++++ .../protocols/openmm_utils/omm_restraints.py | 187 +++++++++++++++++- 2 files changed, 315 insertions(+), 6 deletions(-) create mode 100644 openfe/protocols/openmm_utils/omm_forces.py diff --git a/openfe/protocols/openmm_utils/omm_forces.py b/openfe/protocols/openmm_utils/omm_forces.py new file mode 100644 index 000000000..e9246b694 --- /dev/null +++ b/openfe/protocols/openmm_utils/omm_forces.py @@ -0,0 +1,134 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Custom OpenMM Forces + +TODO +---- +* Add relevant duecredit entries. +""" +import numpy as np +import openmm + + +def get_boresch_energy_function( + control_parameter: str, + K_r: float, r_aA0: float, + K_thetaA: float, theta_A0: float, + K_thetaB: float, theta_B0: float, + K_phiA: float, phi_A0: float, + K_phiB: float, phi_B0: float, + K_phiC: float, phi_C0: float +) -> str: + energy_function = ( + f"{control_parameter} * E; " + "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " + "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " + "+ (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + (K_phiC/2)*dphi_C^2; " + "dphi_A = dA - floor(dA/(2*pi)+0.5)*(2*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; " + "dphi_B = dB - floor(dB/(2*pi)+0.5)*(2*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; " + "dphi_C = dC - floor(dC/(2*pi)+0.5)*(2*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; " + f"pi = {np.pi}; " + f"K_r = {K_r}; " + f"r_aA0 = {r_aA0}; " + f"K_thetaA = {K_thetaA}; " + f"theta_A0 = {theta_A0}; " + f"K_thetaB = {K_thetaB}; " + f"theta_B0 = {theta_B0}; " + f"K_phiA = {K_phiA}; " + f"phi_A0 = {phi_A0}; " + f"K_phiB = {K_phiB}; " + f"phi_B0 = {phi_B0}; " + f"K_phiC = {K_phiC}; " + f"phi_C0 = {phi_C0}; " + ) + return energy_function + + +def get_periodic_boresch_energy_function( + control_parameter: str, + K_r: float, r_aA0: float, + K_thetaA: float, theta_A0: float, + K_thetaB: float, theta_B0: float, + K_phiA: float, phi_A0: float, + K_phiB: float, phi_B0: float, + K_phiC: float, phi_C0: float +) -> str: + energy_function = ( + f"{control_parameter} * E; " + "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " + "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " + "+ (K_phiA/2)*uphi_A + (K_phiB/2)*uphi_B + (K_phiC/2)*uphi_C; " + "uphi_A = (1-cos(dA)); dA = dihedral(p1,p2,p3,p4) - phi_A0; " + "uphi_B = (1-cos(dB)); dB = dihedral(p2,p3,p4,p5) - phi_B0; " + "uphi_C = (1-cos(dC)); dC = dihedral(p3,p4,p5,p6) - phi_C0; " + f"pi = {np.pi}; " + f"K_r = {K_r}; " + f"r_aA0 = {r_aA0}; " + f"K_thetaA = {K_thetaA}; " + f"theta_A0 = {theta_A0}; " + f"K_thetaB = {K_thetaB}; " + f"theta_B0 = {theta_B0}; " + f"K_phiA = {K_phiA}; " + f"phi_A0 = {phi_A0}; " + f"K_phiB = {K_phiB}; " + f"phi_B0 = {phi_B0}; " + f"K_phiC = {K_phiC}; " + f"phi_C0 = {phi_C0}; " + ) + return energy_function + + +def get_custom_compound_bond_force( + n_particles: int = 6, energy_function: str = BORESCH_ENERGY_FUNCTION +): + """ + Return an OpenMM CustomCompoundForce + + TODO + ---- + Change this to a direct subclass like openmmtools.force. + + Acknowledgements + ---------------- + Boresch-like energy functions are reproduced from `Yank `_ + """ + return openmm.CustomCompoundBondForce(n_particles, energy_function) + + +def add_force_in_separate_group( + system: openmm.System, + force: openmm.Force, +): + """ + Add force to a System in a separate force group. + + Parameters + ---------- + system : openmm.System + System to add the Force to. + force : openmm.Force + The Force to add to the System. + + Raises + ------ + ValueError + If all 32 force groups are occupied. + + + TODO + ---- + Unlike the original Yank implementation, we assume that + all 32 force groups will not be filled. Should this be an issue + we can consider just separating it from NonbondedForce. + + Acknowledgements + ---------------- + Mostly reproduced from `Yank `_. + """ + available_force_groups = set(range(32)) + for force in system.getForces(): + available_force_groups.discard(force.getForceGroup()) + + force.setForceGroup(min(available_force_groups)) + system.addForce(force) diff --git a/openfe/protocols/openmm_utils/omm_restraints.py b/openfe/protocols/openmm_utils/omm_restraints.py index 2a62d30ae..f678428c8 100644 --- a/openfe/protocols/openmm_utils/omm_restraints.py +++ b/openfe/protocols/openmm_utils/omm_restraints.py @@ -14,9 +14,28 @@ * Add relevant duecredit entries. """ import abc -from typing import Optional, Union +from typing import Optional, Union, Callable -from openmmtools.states import GlobalParameterState +import openmm +from openmmtools.forces import ( + HarmonicRestraintForce, + HarmonicRestraintBondForce, + FlatBottomRestraintForce, + FlatBottomRestraintBondForce, +) +from openmmtools.states import GlobalParameterState, ThermodynamicState + +from gufe.settings.models import SettingsBaseModel +from openfe.protocols.openmm_utils.omm_forces import ( + get_custom_compound_bond_force, + add_force_in_separate_group, + get_boresch_energy_function, + get_periodic_boresch_energy_function, +) + + +class BaseRestraintGeometry: + pass class RestraintParameterState(GlobalParameterState): @@ -38,13 +57,16 @@ class RestraintParameterState(GlobalParameterState): Partially reproduced from Yank. """ - lambda_restraints = GlobalParameterState.GlobalParameter('lambda_restraints', standard_value=1.0) + lambda_restraints = GlobalParameterState.GlobalParameter( + "lambda_restraints", standard_value=1.0 + ) @lambda_restraints.validator def lambda_restraints(self, instance, new_value): if new_value is not None and not (0.0 <= new_value <= 1.0): - errmsg = ("lambda_restraints must be between 0.0 and 1.0, " - f"got {new_value}") + errmsg = ( + "lambda_restraints must be between 0.0 and 1.0, " f"got {new_value}" + ) raise ValueError(errmsg) # Not crashing out on None to match upstream behaviour return new_value @@ -60,5 +82,158 @@ class BaseHostGuestRestraints(abc.ABC): ---- Add some examples here. """ - def __init__(self, host_atoms: list[int], guest_atoms: list[int], restraint_settings: SettingBaseModel, restraint_geometry: BaseRestraintGeometry): + def __init__( + self, + host_atoms: list[int], + guest_atoms: list[int], + restraint_settings: SettingsBaseModel, + restraint_geometry: BaseRestraintGeometry, + controlling_parameter_name: str = "lambda_restraints", + ): + self.host_atoms = host_atoms + self.guest_atoms = guest_atoms + self.settings = restraint_settings + self.geometry = restraint_geometry + self._verify_input() + + @abc.abstractmethod + def _verify_inputs(self): + pass + + @abc.abstractmethod + def add_force(self, thermodynamic_state: ThermodynamicState): + pass + + @abc.abstractmethod + def get_standard_state_correction(self, thermodynamic_state: ThermodynamicState): + pass + + @abc.abstractmethod + def _get_force(self): + pass + + +class SingleBondMixin: + def _verify_input(self): + if len(self.host_atoms) != 1 or len(self.guest_atoms) != 1: + errmsg = ( + "host_atoms and guest_atoms must only include a single index " + f"each, got {len(host_atoms)} and " + f"{len(guest_atoms)} respectively." + ) + raise ValueError(errmsg) + super()._verify_inputs() + + +class BaseRadialllySymmetricRestraintForce(BaseHostGuestRestraints): + def _verify_inputs(self) -> None: + if not isinstance(self.settings, BaseDistanceRestraintSettings): + errmsg = f"Incorrect settings type {self.settings} passed through" + raise ValueError(errmsg) + if not isinstance(self.geometry, DistanceRestraintGeometry): + errmsg = f"Incorrect geometry type {self.geometry} passed through" + raise ValueError(errmsg) + + def add_force(self, thermodynamic_state: ThermodynamicState) -> None: + force = self._get_force() + force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) + # Note .system is a call to get_system() so it's returning a copy + system = thermodynamic_state.system + add_force_in_separate_group(system, force) + thermodynamic_state.system = system + + def get_standard_state_correction( + self, thermodynamic_state: ThermodynamicState + ) -> float: + force = self._get_force() + return force.compute_standard_state_correction( + thermodynamic_state, volume="system" + ) + + def _get_force(self): + raise NotImplementedError("only implemented in child classes") + + +class HarmonicBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): + def _get_force(self) -> openmm.Force: + return HarmonicRestraintBondForce( + spring_constant=self.settings.spring_constant, + restrained_atom_index1=self.host_atoms[0], + restrained_atom_index2=self.guest_atoms[0], + controlling_parameter_name=self.controlling_parameter_name, + ) + + +class FlatBottomBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): + def _get_force(self) -> openmm.Force: + return FlatBottomRestraintBondForce( + spring_constant=self.settings.spring_constant, + well_radius=self.settings.well_radius, + restrained_atom_index1=self.host_atoms[0], + restrained_atom_index2=self.guest_atoms[0], + controlling_parameter_name=self.controlling_parameter_name, + ) + + +class CentroidHarmonicRestraint(BaseRadialllySymmetricRestraintForce): + def _get_force(self) -> openmm.Force: + return HarmonicRestraintForce( + spring_constant=self.settings.spring_constant, + restrained_atom_index1=self.host_atoms, + restrained_atom_index2=self.guest_atoms, + controlling_parameter_name=self.controlling_parameter_name, + ) + + +class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): + def _get_force(self): + return FlatBottomRestraintBondForce( + spring_constant=self.settings.spring_constant, + well_radius=self.settings.well_radius, + restrained_atom_index1=self.host_atoms, + restrained_atom_index2=self.guest_atoms, + controlling_parameter_name=self.controlling_parameter_name, + ) + + +class BoreschRestraint(BaseHostGuestRestraints): + _EFUNC_METHOD: Callable = get_boresch_energy_function + def _verify_inputs(self) -> None: + if not isinstance(self.settings, BoreschRestraintSettings): + errmsg = f"Incorrect settings type {self.settings} passed through" + raise ValueError(errmsg) + if not isinstance(self.geometry, BoreschRestraintGeometry): + errmsg = f"Incorrect geometry type {self.geometry} passed through" + raise ValueError(errmsg) + + def add_force(self, thermodynamic_state: ThermodynamicState) -> None: + force = self._get_force() + force.addGlobalParameter(self.controlling_parameter_name, 1.0) + force.addBond(self.host_atoms + self.guest_atoms, []) + force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) + # Note .system is a call to get_system() so it's returning a copy + system = thermodynamic_state.system + add_force_in_separate_group(system, force) + thermodynamic_state.system = system + + def _get_force(self) -> openmm.Force: + efunc = _EFUNC_METHOD( + self.controlling_parameter_name, + self.settings.K_r, + self.geometry.r_aA0, + self.settings.K_thetaA, + self.geometry.theta_A0, + self.settings.K_thetaB, + self.geometry.theta_B0, + self.settings.K_phiA, + self.geometry.phi_A0, + self.settings.K_phiB, + self.geometry.phi_B0, + self.settings.K_phiC, + self.geometry.phi_C0, + ) + + return get_custom_compound_bond_force( + n_particles=6, energy_function=efunc + ) From 588a1d246845afbdaa95f2e842df99a2feff7f4c Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 6 Dec 2024 11:19:04 +0100 Subject: [PATCH 060/163] Testing out using the openmmtools alchemical factory instead of femto --- .../protocols/openmm_septop/alchemy_copy.py | 2538 +++++++++++++++++ openfe/protocols/openmm_septop/base.py | 51 +- .../openmm_septop/equil_septop_method.py | 54 +- openfe/protocols/openmm_septop/femto_utils.py | 86 +- openfe/protocols/openmm_septop/utils.py | 654 ++--- openfe/tests/protocols/test_femto_fep.py | 488 ++++ 6 files changed, 3497 insertions(+), 374 deletions(-) create mode 100644 openfe/protocols/openmm_septop/alchemy_copy.py create mode 100644 openfe/tests/protocols/test_femto_fep.py diff --git a/openfe/protocols/openmm_septop/alchemy_copy.py b/openfe/protocols/openmm_septop/alchemy_copy.py new file mode 100644 index 000000000..5751950d8 --- /dev/null +++ b/openfe/protocols/openmm_septop/alchemy_copy.py @@ -0,0 +1,2538 @@ +#!/usr/bin/python + +# ============================================================================= +# MODULE DOCSTRING +# ============================================================================= + +""" +Alchemical factory for free energy calculations that operates directly on OpenMM System objects. + +DESCRIPTION + +This module contains enumerative factories for generating alchemically-modified System objects +usable for the calculation of free energy differences of hydration or ligand binding. + +* `AbsoluteAlchemicalFactory` uses fused elecrostatic and steric alchemical modifications. + +""" + +# TODO +# - Generalize treatment of nonbonded sterics/electrostatics intra-alchemical +# forces to support arbitrary mixing rules. Can we eliminate decoupling to something simpler? +# - Add support for other GBSA models. +# - Add functions for the automatic optimization of alchemical states? +# - Can we store serialized form of Force objects so that we can save time in reconstituting +# Force objects when we make copies? We can even manipulate the XML representation directly. +# - Allow protocols to automatically be resized to arbitrary number of states, to +# allow number of states to be enlarged to be an integral multiple of number of GPUs. +# - Finish AMOEBA support. +# - Can alchemically-modified System objects share unmodified Force objects to avoid overhead +# of duplicating Forces that are not modified? +# - Add support for arbitrary softcore reprogramming of all Custom*Force classes + + +# ============================================================================= +# GLOBAL IMPORTS +# ============================================================================= +import copy +import logging +import collections +import itertools +import re + +import numpy as np +try: + import openmm + from openmm import unit +except ImportError: # OpenMM < 7.6 + from simtk import openmm, unit + +from openmmtools import states, forcefactories, utils +from openmmtools.constants import ONE_4PI_EPS0 + +logger = logging.getLogger(__name__) + + +# ============================================================================= +# ALCHEMICAL STATE +# ============================================================================= + +class AlchemicalStateError(states.GlobalParameterError): + """Error raised by an AlchemicalState.""" + pass + + +class AlchemicalFunction(states.GlobalParameterFunction): + """A function of alchemical variables. + + Parameters + ---------- + expression : str + A mathematical expression involving alchemical variables. + + Examples + -------- + >>> alchemical_state = AlchemicalState(lambda_sterics=1.0, lambda_angles=1.0) + >>> alchemical_state.set_alchemical_variable('lambda', 0.5) + >>> alchemical_state.set_alchemical_variable('lambda2', 1.0) + >>> alchemical_state.lambda_sterics = AlchemicalFunction('lambda**2') + >>> alchemical_state.lambda_sterics + 0.25 + >>> alchemical_state.lambda_angles = AlchemicalFunction('(lambda + lambda2) / 2') + >>> alchemical_state.lambda_angles + 0.75 + + """ + # This class just provides an alternative name to GlobalParameterFunction. + pass + + +class AlchemicalState(states.GlobalParameterState): + """Represent an alchemical state. + + The alchemical parameters modify the Hamiltonian and affect the + computation of the energy. Alchemical parameters that have value + None are considered undefined, which means that applying this + state to System and Context that have that parameter as a global + variable will raise an AlchemicalStateError. + + Parameters + ---------- + parameters_name_suffix : str, optional + If specified, the state will control a modified version of the global + parameters with the name ``parameter_name + '_' + parameters_name_suffix``. + When this is the case, the normal parameters are not accessible. + lambda_sterics : float, optional + Scaling factor for ligand sterics (Lennard-Jones and Halgren) + interactions (default is 1.0). + lambda_electrostatics : float, optional + Scaling factor for ligand charges, intrinsic Born radii, and surface + area term (default is 1.0). + lambda_bonds : float, optional + Scaling factor for alchemically-softened bonds (default is 1.0). + lambda_angles : float, optional + Scaling factor for alchemically-softened angles (default is 1.0). + lambda_torsions : float, optional + Scaling factor for alchemically-softened torsions (default is 1.0). + + Attributes + ---------- + lambda_sterics + lambda_electrostatics + lambda_bonds + lambda_angles + lambda_torsions + + Examples + -------- + Create an alchemically modified system. + + >>> from openmmtools import testsystems + >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + >>> alanine_vacuum = testsystems.AlanineDipeptideVacuum().system + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=range(22)) + >>> alanine_alchemical_system = factory.create_alchemical_system(reference_system=alanine_vacuum, + ... alchemical_regions=alchemical_region) + + Create a completely undefined alchemical state. + + >>> alchemical_state = AlchemicalState() + >>> print(alchemical_state.lambda_sterics) + None + >>> alchemical_state.apply_to_system(alanine_alchemical_system) + Traceback (most recent call last): + ... + openmmtools.alchemy.AlchemicalStateError: The system parameter lambda_electrostatics is not defined in this state. + + Create an AlchemicalState that matches the parameters defined in + the System. + + >>> alchemical_state = AlchemicalState.from_system(alanine_alchemical_system) + >>> alchemical_state.lambda_sterics + 1.0 + >>> alchemical_state.lambda_electrostatics + 1.0 + >>> print(alchemical_state.lambda_angles) + None + + AlchemicalState implement the IComposableState interface, so it can be + used with CompoundThermodynamicState. All the alchemical parameters are + accessible through the compound state. + + >>> import openmm + >>> from openmm import unit + >>> thermodynamic_state = states.ThermodynamicState(system=alanine_alchemical_system, + ... temperature=300*unit.kelvin) + >>> compound_state = states.CompoundThermodynamicState(thermodynamic_state=thermodynamic_state, + ... composable_states=[alchemical_state]) + >>> compound_state.lambda_sterics + 1.0 + + You can control the parameters in the OpenMM Context in this state by + setting the state attributes. + + >>> compound_state.lambda_sterics = 0.5 + >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) + >>> context = compound_state.create_context(integrator) + >>> context.getParameter('lambda_sterics') + 0.5 + >>> compound_state.lambda_sterics = 1.0 + >>> compound_state.apply_to_context(context) + >>> context.getParameter('lambda_sterics') + 1.0 + + You can express the alchemical parameters as a mathematical expression + involving alchemical variables. Here is an example for a two-stage function. + + >>> compound_state.set_alchemical_variable('lambda', 1.0) + >>> compound_state.lambda_sterics = AlchemicalFunction('step_hm(lambda - 0.5) + 2*lambda * step_hm(0.5 - lambda)') + >>> compound_state.lambda_electrostatics = AlchemicalFunction('2*(lambda - 0.5) * step(lambda - 0.5)') + >>> for l in [0.0, 0.25, 0.5, 0.75, 1.0]: + ... compound_state.set_alchemical_variable('lambda', l) + ... print(compound_state.lambda_sterics) + 0.0 + 0.5 + 1.0 + 1.0 + 1.0 + + """ + + _GLOBAL_PARAMETER_ERROR = AlchemicalStateError + + # ------------------------------------------------------------------------- + # Lambda properties + # ------------------------------------------------------------------------- + + class _LambdaParameter(states.GlobalParameterState.GlobalParameter): + """A global parameter in the interval [0, 1] with standard value 1.""" + + def __init__(self, parameter_name): + super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) + + @staticmethod + def lambda_validator(self, instance, parameter_value): + if parameter_value is None: + return parameter_value + if not (0.0 <= parameter_value <= 1.0): + raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) + return float(parameter_value) + + lambda_sterics = _LambdaParameter('lambda_sterics') + lambda_electrostatics = _LambdaParameter('lambda_electrostatics') + lambda_bonds = _LambdaParameter('lambda_bonds') + lambda_angles = _LambdaParameter('lambda_angles') + lambda_torsions = _LambdaParameter('lambda_torsions') + + @classmethod + def from_system(cls, system, *args, **kwargs): + """Constructor reading the state from an alchemical system. + + Parameters + ---------- + system : openmm.System + An alchemically modified system in a defined alchemical state. + parameters_name_suffix : str, optional + If specified, the state will search for a modified + version of the alchemical parameters with the name + ``parameter_name + '_' + parameters_name_suffix``. + + Returns + ------- + The AlchemicalState object representing the alchemical state of + the system. + + Raises + ------ + AlchemicalStateError + If the same parameter has different values in the system, or + if the system has no lambda parameters. + + """ + # The function is redefined here only to provide more specific documentation for this method. + return super().from_system(system, *args, **kwargs) + + def set_alchemical_parameters(self, new_value): + """Set all defined lambda parameters to the given value. + + The undefined parameters (i.e. those being set to None) remain + undefined. + + Parameters + ---------- + new_value : float + The new value for all defined parameters. + + """ + for parameter_name in self._parameters: + if self._parameters[parameter_name] is not None: + setattr(self, parameter_name, new_value) + + # ------------------------------------------------------------------------- + # Function variables + # ------------------------------------------------------------------------- + + def get_function_variable(self, variable_name): + """Return the value of the function variable. + + Function variables are variables entering mathematical expressions + specified with ``AlchemicalFunction``, which can be use to enslave + a lambda parameter to arbitrary variables. + + Parameters + ---------- + variable_name : str + The name of the function variable. + + Returns + ------- + variable_value : float + The value of the function variable. + + """ + # The function is redefined here only to provide more specific documentation for this method. + return super().get_function_variable(variable_name) + + def set_function_variable(self, variable_name, new_value): + """Set the value of the function variable. + + Function variables are variables entering mathematical expressions + specified with ``AlchemicalFunction``, which can be use to enslave + a lambda parameter to arbitrary variables. + + Parameters + ---------- + variable_name : str + The name of the function variable. + new_value : float + The new value for the variable. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().set_function_variable(variable_name, new_value) + + def get_alchemical_variable(self, variable_name): + """Return the value of the alchemical parameter. + + .. warning: + This is deprecated. Use ``get_function_variable`` instead. + + Parameters + ---------- + variable_name : str + The name of the alchemical variable. + + Returns + ------- + variable_value : float + The value of the alchemical variable. + """ + import warnings + warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' + 'Use AlchemicalState.get_function_variable instead.') + return super().get_function_variable(variable_name) + + def set_alchemical_variable(self, variable_name, new_value): + """Set the value of the alchemical variable. + + .. warning: + This is deprecated. Use ``set_function_variable`` instead. + + Parameters + ---------- + variable_name : str + The name of the alchemical variable. + new_value : float + The new value for the variable. + + """ + import warnings + warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' + 'Use AlchemicalState.get_function_variable instead.') + super().set_function_variable(variable_name, new_value) + + # ------------------------------------------------------------------------- + # IComposableState interface + # ------------------------------------------------------------------------- + + def apply_to_system(self, system): + """Set the alchemical state of the system to this. + + Parameters + ---------- + system : openmm.System + The system to modify. + + Raises + ------ + AlchemicalStateError + If the system does not have the required lambda global variables. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().apply_to_system(system) + + def check_system_consistency(self, system): + """Check if the system is in this alchemical state. + + It raises a AlchemicalStateError if the system is not consistent + with the alchemical state. + + Parameters + ---------- + system : openmm.System + The system to test. + + Raises + ------ + AlchemicalStateError + If the system is not consistent with this state. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().check_system_consistency(system) + + def apply_to_context(self, context): + """Put the Context into this AlchemicalState. + + Parameters + ---------- + context : openmm.Context + The context to set. + + Raises + ------ + AlchemicalStateError + If the context does not have the required lambda global variables. + + """ + # The function is redefined here only to provide more specific documentation for this method. + super().apply_to_context(context) + + +# ============================================================================= +# ALCHEMICAL REGION +# ============================================================================= + +_ALCHEMICAL_REGION_ARGS = collections.OrderedDict([ + ('alchemical_atoms', None), + ('alchemical_bonds', None), + ('alchemical_angles', None), + ('alchemical_torsions', None), + ('annihilate_electrostatics', True), + ('annihilate_sterics', False), + ('softcore_alpha', 0.5), ('softcore_a', 1), ('softcore_b', 1), ('softcore_c', 6), + ('softcore_beta', 0.0), ('softcore_d', 1), ('softcore_e', 1), ('softcore_f', 2), + ('name', None) +]) + + +# The class is just a way to document the namedtuple. +class AlchemicalRegion(collections.namedtuple('AlchemicalRegion', _ALCHEMICAL_REGION_ARGS.keys())): + """Alchemical region. + + This is a namedtuple used to tell the AbsoluteAlchemicalFactory which + region of the system to alchemically modify and how. + + Parameters + ---------- + alchemical_atoms : list of int, optional + List of atoms to be designated for which the nonbonded forces (both + sterics and electrostatics components) have to be alchemically + modified (default is None). + alchemical_bonds : bool or list of int, optional + If a list of bond indices are specified, these HarmonicBondForce + entries are softened with 'lambda_bonds'. If set to True, this list + is auto-generated to include all bonds involving any alchemical + atoms (default is None). + alchemical_angles : bool or list of int, optional + If a list of angle indices are specified, these HarmonicAngleForce + entries are softened with 'lambda_angles'. If set to True, this + list is auto-generated to include all angles involving any alchemical + atoms (default is None). + alchemical_torsions : bool or list of int, optional + If a list of torsion indices are specified, these PeriodicTorsionForce + entries are softened with 'lambda_torsions'. If set to True, this list + is auto-generated to include al proper torsions involving any alchemical + atoms. Improper torsions are not softened (default is None). + annihilate_electrostatics : bool, optional + If True, electrostatics should be annihilated, rather than decoupled + (default is True). + annihilate_sterics : bool, optional + If True, sterics (Lennard-Jones or Halgren potential) will be annihilated, + rather than decoupled (default is False). + softcore_alpha : float, optional + Alchemical softcore parameter for Lennard-Jones (default is 0.5). + softcore_a, softcore_b, softcore_c : float, optional + Parameters modifying softcore Lennard-Jones form. Introduced in + Eq. 13 of Ref. [1] (default is 1). + softcore_beta : float, optional + Alchemical softcore parameter for electrostatics. Set this to zero + to recover standard electrostatic scaling (default is 0.0). + softcore_d, softcore_e, softcore_f : float, optional + Parameters modifying softcore electrostatics form (default is 1). + + Notes + ----- + The parameters softcore_e and softcore_f determine the effective distance + between point charges according to + + r_eff = sigma*((softcore_beta*(lambda_electrostatics-1)^softcore_e + (r/sigma)^softcore_f))^(1/softcore_f) + + References + ---------- + [1] Pham TT and Shirts MR. Identifying low variance pathways for free + energy calculations of molecular transformations in solution phase. + JCP 135:034114, 2011. http://dx.doi.org/10.1063/1.3607597 + + """ +AlchemicalRegion.__new__.__defaults__ = tuple(_ALCHEMICAL_REGION_ARGS.values()) + + +# ============================================================================= +# ABSOLUTE ALCHEMICAL FACTORY +# ============================================================================= + +class AbsoluteAlchemicalFactory(object): + """Factory of alchemically modified OpenMM Systems. + + The context parameters created are: + - softcore_alpha: factor controlling softcore lengthscale for Lennard-Jones + - softcore_beta: factor controlling softcore lengthscale for Coulomb + - softcore_a: softcore Lennard-Jones parameter from Eq. 13 of Ref [1] + - softcore_b: softcore Lennard-Jones parameter from Eq. 13 of Ref [1] + - softcore_c: softcore Lennard-Jones parameter from Eq. 13 of Ref [1] + - softcore_d: softcore electrostatics parameter + - softcore_e: softcore electrostatics parameter + - softcore_f: softcore electrostatics parameter + + Parameters + ---------- + consistent_exceptions : bool, optional, default = False + If True, the same functional form of the System's nonbonded + method will be use to determine the electrostatics contribution + to the potential energy of 1,4 exceptions instead of the + classical q1*q2/(4*epsilon*epsilon0*pi*r). + switch_width : float, optional, default = 1.0 * angstroms + Default switch width for electrostatics in periodic cutoff systems + used in alchemical interactions only. + alchemical_pme_treatment : str, optional, default = 'exact' + Controls how alchemical region electrostatics are treated when PME is used. + Options are ['direct-space', 'coulomb', 'exact']. + - 'direct-space' only models the direct space contribution + - 'coulomb' includes switched Coulomb interaction + - 'exact' includes also the reciprocal space contribution, but it's + only possible to annihilate the charges and the softcore parameters + controlling the electrostatics are deactivated. Also, with this + method, modifying the global variable `lambda_electrostatics` is + not sufficient to control the charges. The recommended way to change + them is through the `AlchemicalState` class. + alchemical_rf_treatment : str, optional, default = 'switched' + Controls how alchemical region electrostatics are treated when RF is used + Options are ['switched', 'shifted'] + 'switched' sets c_rf = 0 for all reaction-field interactions and ensures continuity with a switch + 'shifted' retains c_rf != 0 but can give erroneous results for hydration free energies + disable_alchemical_dispersion_correction : bool, optional, default=False + If True, the long-range dispersion correction will not be included for the alchemical + region to avoid the need to recompute the correction (a CPU operation that takes ~ 0.5 s) + every time 'lambda_sterics' is changed. If using nonequilibrium protocols, it is recommended + that this be set to True since this can lead to enormous (100x) slowdowns if the correction + must be recomputed every time step. + split_alchemical_forces : bool, optional, default=True + If True, forces that are altered to different alchemical variables + will be split in different force groups. All non-alchemical forces + will maintain their original force group. If more than 32 force + groups are required, an error is thrown. + + Examples + -------- + + Create an alchemical factory to alchemically modify OpenMM System objects. + + >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + + Create an alchemically modified version of p-xylene in T4 lysozyme L99A in GBSA. + + >>> # Create a reference system. + >>> from openmmtools import testsystems + >>> reference_system = testsystems.LysozymeImplicit().system + >>> # Alchemically soften the pxylene atoms + >>> pxylene_atoms = range(2603,2621) # p-xylene + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=pxylene_atoms) + >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) + + Alchemically modify one water in a water box. + + >>> reference_system = testsystems.WaterBox().system + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0, 1, 2]) + >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) + + Alchemically modify some angles and torsions in alanine dipeptide and + annihilate both sterics and electrostatics. + + >>> reference_system = testsystems.AlanineDipeptideVacuum().system + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0], alchemical_torsions=[0,1,2], + ... alchemical_angles=[0,1,2], annihilate_sterics=True, + ... annihilate_electrostatics=True) + >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) + + Alchemically modify a bond, angles, and torsions in toluene by automatically + selecting bonds involving alchemical atoms. + + >>> toluene_implicit = testsystems.TolueneImplicit() + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0,1], alchemical_torsions=True, + ... alchemical_angles=True, annihilate_sterics=True) + >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) + + Once the alchemical system is created, you can modify its Hamiltonian + through AlchemicalState + + >>> alchemical_state = AlchemicalState.from_system(alchemical_system) + >>> alchemical_state.lambda_sterics + 1.0 + >>> alchemical_state.lambda_electrostatics = 0.5 + >>> alchemical_state.apply_to_system(alchemical_system) + + You can also modify its Hamiltonian directly into a context + + >>> import openmm + >>> from openmm import unit + >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) + >>> context = openmm.Context(alchemical_system, integrator) + >>> alchemical_state.set_alchemical_parameters(0.0) # Set all lambda to 0 + >>> alchemical_state.apply_to_context(context) + + Neglecting the long-range dispersion correction for the alchemical region + (for nonequilibrium switching, for example) requires instantiating a factory + with the appropriate options: + + >>> new_factory = AbsoluteAlchemicalFactory(consistent_exceptions=False, disable_alchemical_dispersion_correction=True) + >>> reference_system = testsystems.WaterBox().system + >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0, 1, 2]) + >>> alchemical_system = new_factory.create_alchemical_system(reference_system, alchemical_region) + + References + ---------- + [1] Pham TT and Shirts MR. Identifying low variance pathways for free + energy calculations of molecular transformations in solution phase. + JCP 135:034114, 2011. http://dx.doi.org/10.1063/1.3607597 + + """ + + # ------------------------------------------------------------------------- + # Public interface + # ------------------------------------------------------------------------- + + def __init__(self, consistent_exceptions=False, switch_width=1.0*unit.angstroms, + alchemical_pme_treatment='exact', alchemical_rf_treatment='switched', + disable_alchemical_dispersion_correction=False, split_alchemical_forces=True): + + self.consistent_exceptions = consistent_exceptions + self.switch_width = switch_width + self.alchemical_pme_treatment = alchemical_pme_treatment + self.alchemical_rf_treatment = alchemical_rf_treatment + self.disable_alchemical_dispersion_correction = disable_alchemical_dispersion_correction + self.split_alchemical_forces = split_alchemical_forces + + def create_alchemical_system(self, reference_system, alchemical_regions, + alchemical_regions_interactions=frozenset()): + """Create an alchemically modified version of the reference system. + + To alter the alchemical state of the returned system use AlchemicalState. + + Parameters + ---------- + reference_system : openmm.System + The system to use as a reference for the creation of the + alchemical system. This will not be modified. + alchemical_regions : AlchemicalRegion + The region of the reference system to alchemically soften. + alchemical_regions_interactions : Set[Tuple[int, int]], optional + Set of alchemical region index pairs for interacting regions. + By default, all alchemical regions interact only with the + non-alchemical environment. + + Returns + ------- + alchemical_system : openmm.System + Alchemically-modified version of reference_system. + + """ + if alchemical_regions_interactions != frozenset(): + raise NotImplementedError('Interactions between alchemical regions is untested') + + logger.debug(f'Dictionary of interacting alchemical regions: {alchemical_regions_interactions}') + if isinstance(alchemical_regions, AlchemicalRegion): + alchemical_regions = [alchemical_regions] + logger.debug(f'Using {len(alchemical_regions)} alchemical regions') + + # Resolve alchemical regions. + alchemical_regions = [self._resolve_alchemical_region(reference_system, alchemical_region) + for alchemical_region in alchemical_regions] + + # Check for duplicate alchemical atoms/bonds/angles/torsions. + all_alchemical_elements = {element_type: set() for element_type in ['atoms', 'bonds', 'angles', 'torsions']} + + for alchemical_region in alchemical_regions: + for element_type, all_elements in all_alchemical_elements.items(): + # Ignore None alchemical elements. + region_elements = getattr(alchemical_region, 'alchemical_' + element_type) + if region_elements is None: + continue + + # Check if there are duplicates with previous regions. + duplicate_elements = all_elements & region_elements + if len(duplicate_elements) > 0: + raise ValueError('Two regions have duplicate {}.'.format(element_type)) + + # Update all alchemical elements. + all_alchemical_elements[element_type].update(region_elements) + + # Check for duplicate names + alchemical_region_names = {alchemical_region.name for alchemical_region in alchemical_regions} + if len(alchemical_region_names) != len(alchemical_regions): + raise ValueError('Two alchemical regions have the same name') + + # Record timing statistics. + timer = utils.Timer() + timer.start('Create alchemically modified system') + + # Build alchemical system to modify. This copies particles, vsites, + # constraints, box vectors and all the forces. We'll later remove + # the forces that we remodel to be alchemically modified. + alchemical_system = copy.deepcopy(reference_system) + + # Check that there are no virtual sites to alchemically modify. + for alchemical_region in alchemical_regions: + for particle_index in alchemical_region.alchemical_atoms: + if reference_system.isVirtualSite(particle_index): + raise ValueError(f'Virtual atoms in region {alchemical_region.name}. ' + 'Alchemically modified virtual sites are not supported') + + # Modify forces as appropriate. We delete the forces that + # have been processed modified at the end of the for loop. + forces_to_remove = [] + alchemical_forces_by_lambda = {} + for force_index, reference_force in enumerate(reference_system.getForces()): + # TODO switch to functools.singledispatch when we drop Python2 support + reference_force_name = reference_force.__class__.__name__ + alchemical_force_creator_name = '_alchemically_modify_{}'.format(reference_force_name) + print(alchemical_force_creator_name) + try: + alchemical_force_creator_func = getattr(self, alchemical_force_creator_name) + except AttributeError as e: + pass + else: + # The reference system force will be deleted. + forces_to_remove.append(force_index) + # Collect all the Force objects modeling the reference force. + alchemical_forces = alchemical_force_creator_func(reference_force, alchemical_regions, + alchemical_regions_interactions) + for lambda_variable_name, lambda_forces in alchemical_forces.items(): + try: + alchemical_forces_by_lambda[lambda_variable_name].extend(lambda_forces) + except KeyError: + alchemical_forces_by_lambda[lambda_variable_name] = lambda_forces + + # Remove original forces that have been alchemically modified. + print(forces_to_remove) + for force_index in reversed(forces_to_remove): + alchemical_system.removeForce(force_index) + print(alchemical_forces_by_lambda) + # Add forces and split groups if necessary. + self._add_alchemical_forces(alchemical_system, alchemical_forces_by_lambda) + + # Record timing statistics. + timer.stop('Create alchemically modified system') + timer.report_timing() + + # If the System uses a NonbondedForce, replace its NonbondedForce implementation of reaction field + # with a Custom*Force implementation that uses c_rf = 0. + # NOTE: This adds an additional CustomNonbondedForce + if self.alchemical_rf_treatment == 'switched': + forcefactories.replace_reaction_field(alchemical_system, return_copy=False, + switch_width=self.switch_width) + + return alchemical_system + + @classmethod + def get_energy_components(cls, alchemical_system, alchemical_state, positions, platform=None): + """Compute potential energy of the alchemical system by Force. + + This can be useful for debug and analysis. + + Parameters + ---------- + alchemical_system : openmm.AlchemicalSystem + An alchemically modified system. + alchemical_state : AlchemicalState + The alchemical state to set the Context to. + positions : openmm.unit.Quantity of dimension (natoms, 3) + Coordinates to use for energy test (units of distance). + platform : openmm.Platform, optional + The OpenMM platform to use to compute the energy. If None, + OpenMM tries to select the fastest available. + + Returns + ------- + energy_components : dict str: openmm.unit.Quantity + A string label describing the role of the force associated to + its contribution to the potential energy. + + """ + # Find and label all forces. + force_labels = cls._find_force_components(alchemical_system) + assert len(force_labels) <= 32, ("The alchemical system has more than 32 force groups; " + "can't compute individual force component energies.") + + # Create deep copy of alchemical system. + system = copy.deepcopy(alchemical_system) + + # Separate all forces into separate force groups. + for force_index, force in enumerate(system.getForces()): + force.setForceGroup(force_index) + + # Create a Context in the given state. + integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds) + if platform is None: + context = openmm.Context(system, integrator) + else: + context = openmm.Context(system, integrator, platform) + context.setPositions(positions) + alchemical_state.apply_to_context(context) + + # Get energy components + energy_components = collections.OrderedDict() + for force_label, force_index in force_labels.items(): + energy_components[force_label] = context.getState(getEnergy=True, + groups=2**force_index).getPotentialEnergy() + + # Clean up + del context, integrator + return energy_components + + # ------------------------------------------------------------------------- + # Internal usage: AlchemicalRegion + # ------------------------------------------------------------------------- + + @classmethod + def _resolve_alchemical_region(cls, system, alchemical_region): + """Return a new AlchemicalRegion with sets of bonds/angles/torsions resolved. + + Also transform any list of indices into a frozenset. + + Parameters + ---------- + system : openmm.System + The system. + alchemical_region : AlchemicalRegion + The alchemical region of the system. + + Returns + ------- + AlchemicalRegion + A new AlchemicalRegion object in which all alchemical_X (where X is + atoms, bonds, angles, or torsions) have been converted to a frozenset + of indices that belong to the System. + + Raises + ------ + ValueError + If the indices in the AlchemicalRegion can't be found in the system. + + """ + # TODO move to AlchemicalRegion? + # TODO process also custom forces? (also in _build_alchemical_X_list methods) + # Find and cache the reference forces. + reference_forces = {force.__class__.__name__: force for force in system.getForces()} + + # Count number of particles, angles, etc. in system. Atoms + # must be processed first since the others build on that. + reference_counts = collections.OrderedDict([ + ('atom', system.getNumParticles()), + ('bond', reference_forces['HarmonicBondForce'].getNumBonds() + if 'HarmonicBondForce' in reference_forces else 0), + ('angle', reference_forces['HarmonicAngleForce'].getNumAngles() + if 'HarmonicAngleForce' in reference_forces else 0), + ('torsion', reference_forces['PeriodicTorsionForce'].getNumTorsions() + if 'PeriodicTorsionForce' in reference_forces else 0) + ]) + + # Transform named tuple to dict for easy modification. + alchemical_region = alchemical_region._asdict() + + for region in reference_counts: + region_name = 'alchemical_' + region + 's' + region_indices = alchemical_region[region_name] + + # Convert None and False to empty lists. + if region_indices is None or region_indices is False: + region_indices = set() + + # Automatically build indices list if True. + elif region_indices is True: + if reference_counts[region] == 0: + region_indices = set() + else: + # TODO switch to functools.singledispatch when drop Python2 + builder_function = getattr(cls, '_build_alchemical_{}_list'.format(region)) + region_indices = builder_function(alchemical_region['alchemical_atoms'], + reference_forces, system) + + # Convert numpy arrays to Python lists since SWIG + # have problems with np.int (see openmm#1650). + elif isinstance(region_indices, np.ndarray): + region_indices = region_indices.tolist() + + # Convert to set and update alchemical region. + region_indices = frozenset(region_indices) + alchemical_region[region_name] = region_indices + + # Check that the given indices are in the system. + indices_diff = region_indices - set(range(reference_counts[region])) + if len(indices_diff) > 0: + err_msg = 'Indices {} in {} cannot be found in the system' + raise ValueError(err_msg.format(indices_diff, region_name)) + + # Check that an alchemical region is defined. + total_alchemically_modified = 0 + for region in reference_counts: + total_alchemically_modified += len(alchemical_region['alchemical_' + region + 's']) + if total_alchemically_modified == 0: + raise ValueError('The AlchemicalRegion is empty.') + + # Return a new AlchemicalRegion with the resolved indices lists. + return AlchemicalRegion(**alchemical_region) + + @staticmethod + def _tabulate_bonds(system): + """ + Tabulate bonds for the specified system. + + Parameters + ---------- + system : openmm.System + The system for which bonds are to be tabulated. + + Returns + ------- + bonds : list of set + bonds[i] is the set of bonds to atom i + + TODO: + * Could we use a Topology object to simplify this? + + """ + bonds = [set() for _ in range(system.getNumParticles())] + + forces = {system.getForce(index).__class__.__name__: system.getForce(index) + for index in range(system.getNumForces())} + + # Process HarmonicBondForce + bond_force = forces['HarmonicBondForce'] + for bond_index in range(bond_force.getNumBonds()): + [particle1, particle2, r, K] = bond_force.getBondParameters(bond_index) + bonds[particle1].add(particle2) + bonds[particle2].add(particle1) + # Process constraints. + for constraint_index in range(system.getNumConstraints()): + [particle1, particle2, r] = system.getConstraintParameters(constraint_index) + bonds[particle1].add(particle2) + bonds[particle2].add(particle1) + + # TODO: Process CustomBondForce? + + return bonds + + @classmethod + def _build_alchemical_torsion_list(cls, alchemical_atoms, reference_forces, system): + """ + Build a list of proper torsion indices that involve any alchemical atom. + + Parameters + ---------- + alchemical_atoms : set of int + The set of alchemically modified atoms. + reference_forces : dict str: force + A dictionary of cached forces in the system accessible by names. + system : openmm.System + The system. + + Returns + ------- + torsion_list : list of int + The list of torsion indices that should be alchemically softened + + """ + + # Tabulate all bonds + bonds = cls._tabulate_bonds(system) + + def is_bonded(i, j): + if j in bonds[i]: + return True + return False + + def is_proper_torsion(i, j, k, l): + if is_bonded(i, j) and is_bonded(j, k) and is_bonded(k, l): + return True + return False + + # Create a list of proper torsions that involve any alchemical atom. + torsion_list = list() + force = reference_forces['PeriodicTorsionForce'] + for torsion_index in range(force.getNumTorsions()): + particle1, particle2, particle3, particle4, periodicity, phase, k = force.getTorsionParameters(torsion_index) + if set([particle1, particle2, particle3, particle4]).intersection(alchemical_atoms): + if is_proper_torsion(particle1, particle2, particle3, particle4): + torsion_list.append(torsion_index) + + return torsion_list + + @staticmethod + def _build_alchemical_angle_list(alchemical_atoms, reference_forces, system): + """ + Build a list of angle indices that involve any alchemical atom. + + Parameters + ---------- + alchemical_atoms : set of int + The set of alchemically modified atoms. + reference_forces : dict str: force + A dictionary of cached forces in the system accessible by names. + system : openmm.System + The system (unused). + + Returns + ------- + angle_list : list of int + The list of angle indices that should be alchemically softened + + """ + angle_list = list() + force = reference_forces['HarmonicAngleForce'] + for angle_index in range(force.getNumAngles()): + [particle1, particle2, particle3, theta0, K] = force.getAngleParameters(angle_index) + if set([particle1, particle2, particle3]).intersection(alchemical_atoms): + angle_list.append(angle_index) + + return angle_list + + @staticmethod + def _build_alchemical_bond_list(alchemical_atoms, reference_forces, system): + """ + Build a list of bond indices that involve any alchemical atom, allowing a list of bonds to override. + + Parameters + ---------- + alchemical_atoms : set of int + The set of alchemically modified atoms. + reference_forces : dict str: force + A dictionary of cached forces in the system accessible by names. + system : openmm.System + The system (unused). + + Returns + ------- + bond_list : list of int + The list of bond indices that should be alchemically softened + + """ + bond_list = list() + force = reference_forces['HarmonicBondForce'] + for bond_index in range(force.getNumBonds()): + [particle1, particle2, r, K] = force.getBondParameters(bond_index) + if set([particle1, particle2]).intersection(alchemical_atoms): + bond_list.append(bond_index) + + return bond_list + + # ------------------------------------------------------------------------- + # Internal usage: Alchemical forces + # ------------------------------------------------------------------------- + + def _add_alchemical_forces(self, alchemical_system, alchemical_forces_by_lambda): + """Add the forces to the alchemical system and eventually split the force groups.""" + # OpenMM can have a maximum of 32 groups. + available_force_groups = set(range(32)) + + # Add non-alchemical groups. New forces will have force group 0, and we don't + # want to modify the force group of forces that have been copied from the reference. + non_alchemical_forces = alchemical_forces_by_lambda.pop('', []) + for non_alchemical_force in non_alchemical_forces: + alchemical_system.addForce(non_alchemical_force) + + # Find which force groups are still available for alchemical forces. + for force in alchemical_system.getForces(): + available_force_groups.discard(force.getForceGroup()) + + # Check if there are enough force groups to split alchemical forces. + if (self.split_alchemical_forces and + len(available_force_groups) < len(alchemical_forces_by_lambda)): + raise RuntimeError('There are not enough force groups to split alchemical forces.\n' + 'Consider merging some non-alchemical forces in a single group ' + 'or set split_alchemical_forces to False.') + + # Add the alchemical forces in a deterministic way (just to be safe). + for lambda_variable in sorted(alchemical_forces_by_lambda): + if self.split_alchemical_forces: + # Assign to these forces the smallest force group index available. + force_group = min(available_force_groups) + available_force_groups.remove(force_group) + for force in alchemical_forces_by_lambda[lambda_variable]: + if self.split_alchemical_forces: + force.setForceGroup(force_group) + alchemical_system.addForce(force) + + @staticmethod + def _are_straddling_noninteracting_regions(particles, alchemical_regions, alchemical_regions_interactions): + """Test if a set of particles are in two regions simultaneously and if these regions are interacting. + + Parameters + ---------- + particles: set + Set of particles to check if they are in two noninteracting alchemical regions. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the torsions to test. + alchemical_regions_interactions : Set[Tuple[int, int]], optional + Set of alchemical region index pairs for interacting regions. + By default, all alchemical regions interact only with the + non-alchemical environment. + + """ + for i, alchemical_region_A in enumerate(alchemical_regions): + if alchemical_region_A.alchemical_atoms.intersection(particles): + j = 0 + while j < i: + alchemical_region_B = alchemical_regions[j] + if alchemical_region_B.alchemical_atoms.intersection(particles): + if {i, j} in alchemical_regions_interactions: + return False + else: + return True + j += 1 + return False + + @classmethod + def _alchemically_modify_PeriodicTorsionForce(cls, reference_force, alchemical_regions, alchemical_regions_interactions): + """Create alchemically-modified version of PeriodicTorsionForce. + + Parameters + ---------- + reference_force : openmm.PeriodicTorsionForce + The reference PeriodicTorsionForce to be alchemically modify. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the torsions to + alchemically modify. + alchemical_regions_interactions : Set[Tuple[int, int]], optional + Set of alchemical region index pairs for interacting regions. + By default, all alchemical regions interact only with the + non-alchemical environment. + + Returns + ------- + force : openmm.PeriodicTorsionForce + The force responsible for the non-alchemical torsions. + custom_force : openmm.CustomTorsionForce + The force responsible for the alchemically-softened torsions. + This will not be present if there are not alchemical torsions + in alchemical_region. + + """ + alchemical_forces = {} + all_alchemical_torsions = set() + + # Don't create a force if there are no alchemical torsions. + for alchemical_region in alchemical_regions: + all_alchemical_torsions.update(alchemical_region.alchemical_torsions) + if len(all_alchemical_torsions) == 0: + return {'': [copy.deepcopy(reference_force)]} + + # Create PeriodicTorsionForce to handle unmodified torsions. + force = openmm.PeriodicTorsionForce() + force.setForceGroup(reference_force.getForceGroup()) + for torsion_index in range(reference_force.getNumTorsions()): + particle1, particle2, particle3, particle4, periodicity, phase, k = reference_force.getTorsionParameters( + torsion_index) + particles = set((particle1, particle2, particle3, particle4)) + + # We don't connect through a torsion two particles that belong + # to two different and noninteracting alchemical regions. + are_straddling = cls._are_straddling_noninteracting_regions( + particles, alchemical_regions, alchemical_regions_interactions) + if (torsion_index not in all_alchemical_torsions) and (not are_straddling): + force.addTorsion(particle1, particle2, particle3, particle4, periodicity, phase, k) + + # Update the returned value with the non-alchemical force. + alchemical_forces[''] = [force] + + # Create CustomTorsionForce to handle alchemically modified torsions. + for alchemical_region in alchemical_regions: + # This region may not have torsions to modify. + if len(alchemical_region.alchemical_torsions) == 0: + continue + + # Check if the lambda variable needs a suffix to identify the region. + lambda_variable_name = 'lambda_torsions' + if alchemical_region.name is not None: + lambda_variable_name += '_' + alchemical_region.name + + # Create CustomTorsionForce to handle alchemically modified torsions. + energy_function = f"{lambda_variable_name}*k*(1+cos(periodicity*theta-phase))" + custom_force = openmm.CustomTorsionForce(energy_function) + custom_force.addGlobalParameter(lambda_variable_name, 1.0) + custom_force.addPerTorsionParameter('periodicity') + custom_force.addPerTorsionParameter('phase') + custom_force.addPerTorsionParameter('k') + + # Process reference torsions. + for torsion_index in sorted(alchemical_region.alchemical_torsions): + # Retrieve parameters. + particle1, particle2, particle3, particle4, periodicity, phase, k = reference_force.getTorsionParameters(torsion_index) + # Create torsions. + custom_force.addTorsion(particle1, particle2, particle3, particle4, [periodicity, phase, k]) + + # Update the returned value with the alchemical force. + alchemical_forces.update({lambda_variable_name: [custom_force]}) + + return alchemical_forces + + @classmethod + def _alchemically_modify_HarmonicAngleForce(cls, reference_force, alchemical_regions, alchemical_regions_interactions): + """Create alchemically-modified version of HarmonicAngleForce + + Parameters + ---------- + reference_force : openmm.HarmonicAngleForce + The reference HarmonicAngleForce to be alchemically modify. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the angles to + alchemically modify. + alchemical_regions_interactions : Set[Tuple[int, int]], optional + Set of alchemical region index pairs for interacting regions. + By default, all alchemical regions interact only with the + non-alchemical environment. + + Returns + ------- + force : openmm.HarmonicAngleForce + The force responsible for the non-alchemical angles. + custom_force : openmm.CustomAngleForce + The force responsible for the alchemically-softened angles. + This will not be present if there are not alchemical angles + in alchemical_region. + + """ + alchemical_forces = {} + all_alchemical_angles = set() + # Don't create a force if there are no alchemical angles. + for alchemical_region in alchemical_regions: + all_alchemical_angles.update(alchemical_region.alchemical_angles) + if len(all_alchemical_angles) == 0: + return {'': [copy.deepcopy(reference_force)]} + + # Create standard HarmonicAngleForce to handle unmodified angles. + force = openmm.HarmonicAngleForce() + force.setForceGroup(reference_force.getForceGroup()) + for angle_index in range(reference_force.getNumAngles()): + [particle1, particle2, particle3, theta0, K] = reference_force.getAngleParameters(angle_index) + particles = set((particle1, particle2, particle3)) + + # We don't connect through an angle two particles that belong + # to two different and noninteracting alchemical regions. + are_straddling = cls._are_straddling_noninteracting_regions( + particles, alchemical_regions, alchemical_regions_interactions) + if (angle_index not in all_alchemical_angles) and (not are_straddling): + force.addAngle(particle1, particle2, particle3, theta0, K) + + # Update the returned value with the non-alchemical force. + alchemical_forces[''] = [force] + + # Create CustomAngleForce to handle alchemically modified angles. + for alchemical_region in alchemical_regions: + # This region may not have angles to modify. + if len(alchemical_region.alchemical_angles) == 0: + continue + + # Check if the lambda variable needs a suffix to identify the region. + lambda_variable_name = 'lambda_angles' + if alchemical_region.name is not None: + lambda_variable_name += '_' + alchemical_region.name + + # Create CustomAngleForce to handle alchemically modified angles. + energy_function = f"{lambda_variable_name}*(K/2)*(theta-theta0)^2;" + custom_force = openmm.CustomAngleForce(energy_function) + custom_force.addGlobalParameter(lambda_variable_name, 1.0) + custom_force.addPerAngleParameter('theta0') + custom_force.addPerAngleParameter('K') + + # Process reference angles. + for angle_index in sorted(alchemical_region.alchemical_angles): + [particle1, particle2, particle3, theta0, K] = reference_force.getAngleParameters(angle_index) + custom_force.addAngle(particle1, particle2, particle3, [theta0, K]) + + # Update the returned value with the alchemical force. + alchemical_forces.update({lambda_variable_name: [custom_force]}) + + return alchemical_forces + + @classmethod + def _alchemically_modify_HarmonicBondForce(cls, reference_force, alchemical_regions, alchemical_regions_interactions): + """Create alchemically-modified version of HarmonicBondForce + + Parameters + ---------- + reference_force : openmm.HarmonicBondForce + The reference HarmonicBondForce to be alchemically modify. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the bonds to + alchemically modify. + alchemical_regions_interactions : Set[Tuple[int, int]], optional + Set of alchemical region index pairs for interacting regions. + By default, all alchemical regions interact only with the + non-alchemical environment. + + Returns + ------- + force : openmm.HarmonicBondForce + The force responsible for the non-alchemical bonds. + custom_force : openmm.CustomBondForce + The force responsible for the alchemically-softened bonds. + This will not be present if there are not alchemical bonds + in alchemical_region. + + """ + alchemical_forces = {} + all_alchemical_bonds = set() + + # Don't create a force if there are no alchemical bonds. + for alchemical_region in alchemical_regions: + all_alchemical_bonds.update(alchemical_region.alchemical_bonds) + if len(all_alchemical_bonds) == 0: + return {'': [copy.deepcopy(reference_force)]} + + # Create standard HarmonicBondForce to handle unmodified bonds. + force = openmm.HarmonicBondForce() + force.setForceGroup(reference_force.getForceGroup()) + for bond_index in range(reference_force.getNumBonds()): + [particle1, particle2, theta0, K] = reference_force.getBondParameters(bond_index) + particles = set((particle1, particle2)) + + # We don't connect through a bond two particles that belong + # to two different and noninteracting alchemical regions. + are_straddling = cls._are_straddling_noninteracting_regions( + particles, alchemical_regions, alchemical_regions_interactions) + if (bond_index not in all_alchemical_bonds) and (not are_straddling): + force.addBond(particle1, particle2, theta0, K) + + # Update the returned value with the non-alchemical force. + alchemical_forces[''] = [force] + + for alchemical_region in alchemical_regions: + # This region may not have bonds to modify. + if len(alchemical_region.alchemical_bonds) == 0: + continue + + # Check if the lambda variable needs a suffix to identify the region. + lambda_variable_name = 'lambda_bonds' + if alchemical_region.name is not None: + lambda_variable_name += '_' + alchemical_region.name + + # Define force here so that it is over writen saving only one copy. + # Create CustomBondForce to handle alchemically modified bonds. + energy_function = f"{lambda_variable_name}*(K/2)*(r-r0)^2;" + custom_force = openmm.CustomBondForce(energy_function) + custom_force.addGlobalParameter(lambda_variable_name, 1.0) + custom_force.addPerBondParameter('r0') + custom_force.addPerBondParameter('K') + # Process reference bonds. + for bond_index in sorted(alchemical_region.alchemical_bonds): + [particle1, particle2, theta0, K] = reference_force.getBondParameters(bond_index) + custom_force.addBond(particle1, particle2, [theta0, K]) + + # Update the returned value with the alchemical force. + alchemical_forces.update({lambda_variable_name: [custom_force]}) + + return alchemical_forces + + def _get_sterics_energy_expressions(self, lambda_variable_suffixes): + """Return the energy expressions for sterics. + + Parameters + ---------- + lambda_variable_suffixes : List[str] + A list with suffixes for the global variable "lambda_sterics" that + will control the energy. If no suffix is necessary (i.e. there are + no multiple alchemical regions) just set lambda_variable_suffixes[0] = ''. + If the list has more than one element, the energy is controlled by + the multiplication of lambda_sterics_suffix1 * lambda_sterics_suffix2. + """ + + # Sterics mixing rules. + if lambda_variable_suffixes[0] == '': + lambda_variable_name = 'lambda_sterics' + else: + if len(lambda_variable_suffixes) > 1: + lambda_variable_name = 'lambda_sterics{0}*lambda_sterics{1}'.format( + lambda_variable_suffixes[0], lambda_variable_suffixes[1]) + else: + lambda_variable_name = 'lambda_sterics{}'.format(lambda_variable_suffixes[0]) + + sterics_mixing_rules = ('epsilon = sqrt(epsilon1*epsilon2);' # Mixing rule for epsilon. + 'sigma = 0.5*(sigma1 + sigma2);') # Mixing rule for sigma. + + # Soft-core Lennard-Jones. + exceptions_sterics_energy_expression = ('U_sterics;' + 'U_sterics = (({0})^softcore_a)*4*epsilon*x*(x-1.0);' + 'x = (sigma/reff_sterics)^6;' + # Effective softcore distance for sterics. + 'reff_sterics = sigma*((softcore_alpha*(1.0-({0}))^softcore_b + (r/sigma)^softcore_c))^(1/softcore_c);')\ + .format(lambda_variable_name) + # Define energy expression for electrostatics. + return sterics_mixing_rules, exceptions_sterics_energy_expression + + def _get_electrostatics_energy_expressions(self, reference_force, lambda_variable_suffixes): + """Return the energy expressions for electrostatics. + + This private function assumes self._alchemical_pme_treatment != 'exact' + as there's no electrostatics CustomNondondedForce in this case, and + lambda_electrostatics is modeled through an offset parameter in a + NonbondedForce. + + Parameters + ---------- + lambda_variable_suffixes : List[str] + A list with suffixes for the global variable "lambda_electrostatics" that + will control the energy. If no suffix is necessary (i.e. there are + no multiple alchemical regions) just set lambda_variable_suffixes[0] = ''. + If the list has more than one element, the energy is controlled by + the multiplication of lambda_electrostatics_suffix1 * lambda_electrostatics_suffix2. + """ + if lambda_variable_suffixes[0] == '': + lambda_variable_name = 'lambda_electrostatics' + else: + if len(lambda_variable_suffixes) > 1: + lambda_variable_name = 'lambda_electrostatics{0}*lambda_electrostatics{1}'.format( + lambda_variable_suffixes[0], lambda_variable_suffixes[1]) + else: + lambda_variable_name = 'lambda_electrostatics{}'.format(lambda_variable_suffixes[0]) + + # The final expression will be prefix + method + suffix. + electrostatics_prefix = ('U_electrostatics;' + 'U_electrostatics=(({})^softcore_d)*ONE_4PI_EPS0*chargeprod').format(lambda_variable_name) + + # Effective softcore distance for electrostatics (common to all methods). + electrostatics_suffix = ('reff_electrostatics = sigma*((softcore_beta*(1.0-({0}))^softcore_e + (r/sigma)^softcore_f))^(1/softcore_f);' + 'ONE_4PI_EPS0 = {1};').format(lambda_variable_name, ONE_4PI_EPS0) # Already in OpenMM units. + + # Define mixing rules. + electrostatics_mixing_rules = ('chargeprod = charge1*charge2;' # Mixing rule for charges. + 'sigma = 0.5*(sigma1 + sigma2);') # Mixing rule for sigma. + + # Standard Coulomb expression with softened core. This is used + # - When the nonbonded method of the reference force is NoCutoff. + # - When alchemical_pme_treatment is set to 'coulomb'. + # - With 1-4 exceptions, unless self.consistent_exceptions is True. + coulomb_expression = '/reff_electrostatics;' + + # Select electrostatics functional form based on nonbonded method. + nonbonded_method = reference_force.getNonbondedMethod() + + # Soft-core Coulomb. + if nonbonded_method in [openmm.NonbondedForce.NoCutoff]: + electrostatics_method_expression = coulomb_expression + # Reaction-field electrostatics. + elif nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic, openmm.NonbondedForce.CutoffNonPeriodic]: + electrostatics_method_expression = self._get_reaction_field_unique_expression(reference_force) + # PME electrostatics. + elif nonbonded_method in [openmm.NonbondedForce.PME, openmm.NonbondedForce.Ewald]: + # Ewald direct-space electrostatics. + if self.alchemical_pme_treatment == 'direct-space': + electrostatics_method_expression = self._get_pme_direct_space_unique_expression(reference_force) + # Use switched standard Coulomb potential, following MTS scheme described in + # http://dx.doi.org/10.1063/1.1385159 + elif self.alchemical_pme_treatment == 'coulomb': + electrostatics_method_expression = coulomb_expression + else: + raise ValueError("Unknown alchemical_pme_treatment scheme '{}'".format(self.alchemical_pme_treatment)) + else: + raise ValueError("Nonbonded method {} not supported yet.".format(nonbonded_method)) + + # Define energy expression for 1,4 electrostatic exceptions. + exceptions_electrostatics_energy_expression = electrostatics_prefix + if self.consistent_exceptions: + exceptions_electrostatics_energy_expression += electrostatics_method_expression + else: + exceptions_electrostatics_energy_expression += coulomb_expression + exceptions_electrostatics_energy_expression += electrostatics_suffix + + # Define energy expression for electrostatics. + electrostatics_energy_expression = (electrostatics_prefix + electrostatics_method_expression + + electrostatics_suffix + electrostatics_mixing_rules) + + return electrostatics_energy_expression, exceptions_electrostatics_energy_expression + + def _get_reaction_field_unique_expression(self, reference_force): + """Unique part of the expression for reaction-field electrostatics. + + Parameters + ---------- + reference_force : openmm.NonbondedForce + The reference force including the reaction-field parameters. + + Returns + ------- + rf_expression : str + The unique expression for reaction-field electrostatics. + + See Also + -------- + _get_nonbonded_energy_expressions + """ + epsilon_solvent = reference_force.getReactionFieldDielectric() + r_cutoff = reference_force.getCutoffDistance() + + # Determine reaction fields parameters. + k_rf = r_cutoff**(-3) * ((epsilon_solvent - 1) / (2*epsilon_solvent + 1)) + if self.alchemical_rf_treatment == 'switched': + c_rf = 0.0 / unit.nanometers + elif self.alchemical_rf_treatment == 'shifted': + # WARNING: Setting c_rf != 0 can cause large errors in DeltaG for hydration free energies + c_rf = r_cutoff**(-1) * ((3*epsilon_solvent) / (2*epsilon_solvent + 1)) + else: + raise ValueError("Unknown alchemical_rf_treatment scheme '{}'".format(self.alchemical_rf_treatment)) + + k_rf = k_rf.value_in_unit_system(unit.md_unit_system) + c_rf = c_rf.value_in_unit_system(unit.md_unit_system) + rf_expression = ('*(reff_electrostatics^(-1) + k_rf*reff_electrostatics^2 - c_rf);' + 'k_rf = {k_rf};' + 'c_rf = {c_rf};').format(k_rf=k_rf, c_rf=c_rf) + return rf_expression + + def _get_pme_direct_space_unique_expression(self, reference_force): + """Unique part of the expression for Ewald direct-space electrostatics. + + Parameters + ---------- + reference_force : openmm.NonbondedForce + The reference force including the Ewald parameters. + + Returns + ------- + rf_expression : str + The unique expression for Ewald direct-space electrostatics. + + See Also + -------- + _get_nonbonded_energy_expressions + """ + # Determine PME parameters. + [alpha_ewald, nx, ny, nz] = reference_force.getPMEParameters() + if (alpha_ewald/alpha_ewald.unit) == 0.0: + # If alpha is 0.0, alpha_ewald is computed by OpenMM from from the error tolerance. + tol = reference_force.getEwaldErrorTolerance() + alpha_ewald = (1.0/reference_force.getCutoffDistance()) * np.sqrt(-np.log(2.0*tol)) + + alpha_ewald = alpha_ewald.value_in_unit_system(unit.md_unit_system) + pme_expression = ("*erfc(alpha_ewald*reff_electrostatics)/reff_electrostatics;" + "alpha_ewald = {};").format(alpha_ewald) + return pme_expression + + def _alchemically_modify_NonbondedForce(self, reference_force, alchemical_regions, alchemical_regions_interactions): + """Create alchemically-modified version of NonbondedForce. + + Parameters + ---------- + reference_force : openmm.NonbondedForce + The reference NonbondedForce to be alchemically modify. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the atoms to + alchemically modify. + alchemical_regions_interactions : Set[Tuple[int, int]], optional + Set of alchemical region index pairs for interacting regions. + By default, all alchemical regions interact only with the + non-alchemical environment. + + Returns + ------- + nonbonded_force : openmm.NonbondedForce + The force responsible for interactions and exceptions of non-alchemical atoms. + aa_sterics_custom_nonbonded_force : openmm.CustomNonbondedForce + The force responsible for sterics interactions of alchemical/alchemical atoms. + aa_electrostatics_custom_nonbonded_force : openmm.CustomNonbondedForce + The force responsible for electrostatics interactions of alchemical/alchemical + atoms. + na_sterics_custom_nonbonded_force : openmm.CustomNonbondedForce + The force responsible for sterics interactions of non-alchemical/alchemical atoms. + na_electrostatics_custom_nonbonded_force : openmm.CustomNonbondedForce + The force responsible for electrostatics interactions of non-alchemical/alchemical + atoms. + aa_sterics_custom_bond_force : openmm.CustomBondForce + The force responsible for sterics exceptions of alchemical/alchemical atoms. + aa_electrostatics_custom_bond_force : openmm.CustomBondForce + The force responsible for electrostatics exceptions of alchemical/alchemical + atoms. + na_sterics_custom_bond_force : openmm.CustomBondForce + The force responsible for sterics exceptions of non-alchemical/alchemical atoms. + na_electrostatics_custom_bond_force : openmm.CustomBondForce + The force responsible for electrostatics exceptions of non-alchemical/alchemical + atoms. + + References + ---------- + [1] Pham TT and Shirts MR. Identifying low variance pathways for free + energy calculations of molecular transformations in solution phase. + JCP 135:034114, 2011. http://dx.doi.org/10.1063/1.3607597 + + """ + # TODO Change softcore_beta to a dimensionless scalar to multiply some intrinsic length-scale, like Lennard-Jones alpha. + # TODO Try using a single, common "reff" effective softcore distance for both Lennard-Jones and Coulomb. + + forces_by_lambda = {} + all_alchemical_atoms = set() + + # Don't create a force if there are no alchemical atoms. + for alchemical_region in alchemical_regions: + if not len(alchemical_region.alchemical_atoms) == 0: + all_alchemical_atoms.update(alchemical_region.alchemical_atoms) + + # Don't create a force if there are no alchemical atoms. + if len(all_alchemical_atoms) == 0: + return {'': [copy.deepcopy(reference_force)]} + + # Create a set of all the non-alchemical atoms only. + all_atomset = set(range(reference_force.getNumParticles())) + nonalchemical_atomset = all_atomset.difference(all_alchemical_atoms) + + # ------------------------------------------------------------- + # Perform tasks that do not need to be repeated for all regions. + # ------------------------------------------------------------- + + # Define energy expression for electrostatics based on nonbonded method. + nonbonded_method = reference_force.getNonbondedMethod() + is_ewald_method = nonbonded_method in [openmm.NonbondedForce.Ewald, + openmm.NonbondedForce.PME] + is_rf_method = nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic, + openmm.NonbondedForce.CutoffNonPeriodic] + is_periodic_method = is_ewald_method or nonbonded_method == openmm.NonbondedForce.CutoffPeriodic + use_exact_pme_treatment = is_ewald_method and self.alchemical_pme_treatment == 'exact' + + # Warn about reaction field. + if is_rf_method: + logger.warning('Reaction field support is still experimental. For free energy ' + 'calculations in explicit solvent, we suggest using PME for now.') + + # Check that PME treatment is supported with the region's parameters. + if use_exact_pme_treatment: + for alchemical_region in alchemical_regions: + err_msg = ' not supported with exact treatment of Ewald electrostatics.' + if not alchemical_region.annihilate_electrostatics: + raise ValueError('Decoupled electrostatics is' + err_msg) + if self.consistent_exceptions: + raise ValueError('Consistent exceptions are' + err_msg) + if (alchemical_region.softcore_beta, alchemical_region.softcore_d, alchemical_region.softcore_e) != (0, 1, 1): + raise ValueError('Softcore electrostatics is' + err_msg) + + # Create a copy of the NonbondedForce to handle particle interactions and + # 1,4 exceptions between non-alchemical/non-alchemical atoms (nn). + nonbonded_force = copy.deepcopy(reference_force) + + # Fix any issues in reference force with Lennard-Jones sigma = 0 (epsilon = 0), + # which should have sigma > 0. + for particle_index in range(reference_force.getNumParticles()): + # Retrieve parameters. + [charge, sigma, epsilon] = reference_force.getParticleParameters(particle_index) + # Check particle sigma is not zero. + if sigma == 0.0 * unit.angstrom: + warning_msg = 'particle %d has Lennard-Jones sigma = 0 (charge=%s, sigma=%s, epsilon=%s); setting sigma=1A' + logger.warning(warning_msg % (particle_index, str(charge), str(sigma), str(epsilon))) + sigma = 1.0 * unit.angstrom + # Fix it. + nonbonded_force.setParticleParameters(particle_index, charge, sigma, epsilon) + + # Same for the exceptions. + for exception_index in range(reference_force.getNumExceptions()): + # Retrieve parameters. + [iatom, jatom, chargeprod, sigma, epsilon] = reference_force.getExceptionParameters(exception_index) + # Check particle sigma is not zero. + if sigma == 0.0 * unit.angstrom: + warning_msg = 'exception %d has Lennard-Jones sigma = 0 (iatom=%d, jatom=%d, chargeprod=%s, sigma=%s, epsilon=%s); setting sigma=1A' + logger.warning(warning_msg % (exception_index, iatom, jatom, str(chargeprod), str(sigma), str(epsilon))) + sigma = 1.0 * unit.angstrom + # Fix it. + nonbonded_force.setExceptionParameters(exception_index, iatom, jatom, chargeprod, sigma, epsilon) + + if use_exact_pme_treatment: + # Exclude noninteracting alchemical regions from seeing each other in the nonbonded + for x, y in itertools.combinations(range(len(alchemical_regions)), 2): + if (x, y) not in alchemical_regions_interactions: + for atom1 in alchemical_regions[x].alchemical_atoms: + for atom2 in alchemical_regions[y].alchemical_atoms: + nonbonded_force.addException(atom1, atom2, 0.0, 1.0, 0.0, True) + else: + region_names = (alchemical_regions[x].name, alchemical_regions[y].name) + logger.debug(f'Adding a exact PME electrostatic interaction group between groups {region_names}.') + del region_names + + # With exact PME treatment, particle electrostatics is handled through offset parameters. + for alchemical_region in alchemical_regions: + if alchemical_region.name is None: + nonbonded_force.addGlobalParameter('lambda_electrostatics', 1.0) + else: + nonbonded_force.addGlobalParameter(f'lambda_electrostatics_{alchemical_region.name}', 1.0) + + # Make of list of all single and double permutations of alchemical regions. + single_regions = [[alchemical_region] for alchemical_region in alchemical_regions] + if len(alchemical_regions_interactions) == 0: + pair_regions = [] + else: + # Only generate pairs of alchemical regions specified by alchemical_regions_interactions. + pair_regions = [[alchemical_regions[x[0]], alchemical_regions[x[1]]] for x in + alchemical_regions_interactions] + + # Iterate over all single and double permutations of alchemical regions to build all interactions. + for alchemical_regions_pairs in single_regions+pair_regions: + # Make a list of region names for the alchemical regions interactions which are being built. + lambda_var_suffixes = [] + for alchemical_region in alchemical_regions_pairs: + if alchemical_region.name is None: + lambda_var_suffixes.append('') + else: + lambda_var_suffixes.append('_' + alchemical_region.name) + + # -------------------------------------------------- + # Determine energy expression for all custom forces + # -------------------------------------------------- + + # Get steric energy expressions. + sterics_mixing_rules, exceptions_sterics_energy_expression = self._get_sterics_energy_expressions(lambda_var_suffixes) + + # Define energy expression for sterics. + sterics_energy_expression = exceptions_sterics_energy_expression + sterics_mixing_rules + + if not use_exact_pme_treatment: + # There's no CustomNonbondedForce that models electrostatics if we use exact + # PME treatment. Electrostatics is modeled through offset parameters. + energy_expressions = self._get_electrostatics_energy_expressions(reference_force, lambda_var_suffixes) + (electrostatics_energy_expression, + exceptions_electrostatics_energy_expression) = energy_expressions # Unpack tuple. + + # ------------------------------------------------------------ + # Create and configure all forces to add to alchemical system + # ------------------------------------------------------------ + + # Interactions and exceptions will be distributed according to the following table. + + # -------------------------------------------------------------------------------------------------- + # FORCE | INTERACTION GROUP | + # -------------------------------------------------------------------------------------------------- + # nonbonded_force (unmodified) | all interactions nonalchemical/nonalchemical | + # | all exceptions nonalchemical/nonalchemical | + # -------------------------------------------------------------------------------------------------- + # aa_sterics_custom_nonbonded_force | sterics interactions alchemical/alchemical | + # -------------------------------------------------------------------------------------------------- + # aa_electrostatics_custom_nonbonded_force | electrostatics interactions alchemical/alchemical | + # | (only without exact PME treatment) | + # -------------------------------------------------------------------------------------------------- + # na_sterics_custom_nonbonded_force | sterics interactions non-alchemical/alchemical | + # -------------------------------------------------------------------------------------------------- + # na_electrostatics_custom_nonbonded_force | electrostatics interactions non-alchemical/alchemical | + # | (only without exact PME treatment) | + # -------------------------------------------------------------------------------------------------- + # aa_sterics_custom_bond_force | sterics exceptions alchemical/alchemical | + # -------------------------------------------------------------------------------------------------- + # aa_electrostatics_custom_bond_force | electrostatics exceptions alchemical/alchemical | + # | (only without exact PME treatment) | + # -------------------------------------------------------------------------------------------------- + # na_sterics_custom_bond_force | sterics exceptions non-alchemical/alchemical | + # -------------------------------------------------------------------------------------------------- + # na_electrostatics_custom_bond_force | electrostatics exceptions non-alchemical/alchemical | + # | (only without exact PME treatment) | + # -------------------------------------------------------------------------------------------------- + + def create_force(force_cls, energy_expression, lambda_variable_name, lambda_var_suffixes, is_lambda_controlled): + """Shortcut to create a lambda-controlled custom forces.""" + if is_lambda_controlled: + force = force_cls(energy_expression) + for suffix in lambda_var_suffixes: + name = (lambda_variable_name + suffix) + force.addGlobalParameter(name, 1.0) + else: # fix lambda variable to 1.0 + for suffix in lambda_var_suffixes: + name = (lambda_variable_name + suffix) + energy_expression = energy_expression + name + '=1.0;' + force = force_cls(energy_expression) + return force + + # Create CustomNonbondedForces to handle sterics particle interactions between + # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda + # to 1.0 for decoupled interactions in alchemical/alchemical force. + if len(lambda_var_suffixes) > 1: + aa_sterics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, sterics_energy_expression, + 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) + all_sterics_custom_nonbonded_forces = [aa_sterics_custom_nonbonded_force] + else: + na_sterics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, sterics_energy_expression, + 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) + aa_sterics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, sterics_energy_expression, + 'lambda_sterics', lambda_var_suffixes, alchemical_region.annihilate_sterics) + all_sterics_custom_nonbonded_forces = [na_sterics_custom_nonbonded_force, aa_sterics_custom_nonbonded_force] + + # Add parameters and configure CustomNonbondedForces to match reference force. + for force in all_sterics_custom_nonbonded_forces: + force.addPerParticleParameter("sigma") # Lennard-Jones sigma + force.addPerParticleParameter("epsilon") # Lennard-Jones epsilon + force.setUseSwitchingFunction(nonbonded_force.getUseSwitchingFunction()) + force.setCutoffDistance(nonbonded_force.getCutoffDistance()) + force.setSwitchingDistance(nonbonded_force.getSwitchingDistance()) + if self.disable_alchemical_dispersion_correction: + force.setUseLongRangeCorrection(False) + else: + force.setUseLongRangeCorrection(nonbonded_force.getUseDispersionCorrection()) + + if is_periodic_method: + force.setNonbondedMethod(openmm.CustomNonbondedForce.CutoffPeriodic) + else: + force.setNonbondedMethod(nonbonded_force.getNonbondedMethod()) + + if use_exact_pme_treatment: + #electrostatics are handled by offset + all_electrostatics_custom_nonbonded_forces = [] + else: + # Create CustomNonbondedForces to handle electrostatics particle interactions between + # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda + # to 1.0 for decoupled interactions in alchemical/alchemical force. + if len(lambda_var_suffixes) > 1: + aa_electrostatics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, electrostatics_energy_expression, + 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) + all_electrostatics_custom_nonbonded_forces = [aa_electrostatics_custom_nonbonded_force] + else: + na_electrostatics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, electrostatics_energy_expression, + 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) + aa_electrostatics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, electrostatics_energy_expression, + 'lambda_electrostatics', lambda_var_suffixes, alchemical_region.annihilate_electrostatics) + all_electrostatics_custom_nonbonded_forces = [na_electrostatics_custom_nonbonded_force, + aa_electrostatics_custom_nonbonded_force] + + # Common parameters and configuration for electrostatics CustomNonbondedForces. + for force in all_electrostatics_custom_nonbonded_forces: + force.addPerParticleParameter("charge") # partial charge + force.addPerParticleParameter("sigma") # Lennard-Jones sigma + if ((is_ewald_method and self.alchemical_pme_treatment == 'coulomb') or + (is_rf_method and self.alchemical_rf_treatment == 'switched')): + # Use switching function for alchemical electrostatics to ensure force continuity at cutoff. + force.setUseSwitchingFunction(True) + else: + force.setUseSwitchingFunction(False) + force.setSwitchingDistance(nonbonded_force.getCutoffDistance() - self.switch_width) + force.setCutoffDistance(nonbonded_force.getCutoffDistance()) + force.setUseLongRangeCorrection(False) # long-range dispersion correction is meaningless for electrostatics + if is_periodic_method: + force.setNonbondedMethod(openmm.CustomNonbondedForce.CutoffPeriodic) + else: + force.setNonbondedMethod(nonbonded_force.getNonbondedMethod()) + + # Create CustomBondForces to handle sterics 1,4 exceptions interactions between + # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda + # to 1.0 for decoupled interactions in alchemical/alchemical force. + if len(lambda_var_suffixes) > 1: + aa_sterics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_sterics_energy_expression, + 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) + all_sterics_custom_bond_forces = [aa_sterics_custom_bond_force] + else: + na_sterics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_sterics_energy_expression, + 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) + aa_sterics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_sterics_energy_expression, + 'lambda_sterics', lambda_var_suffixes, alchemical_region.annihilate_sterics) + all_sterics_custom_bond_forces = [na_sterics_custom_bond_force, aa_sterics_custom_bond_force] + + for force in all_sterics_custom_bond_forces: + force.addPerBondParameter("sigma") # Lennard-Jones effective sigma + force.addPerBondParameter("epsilon") # Lennard-Jones effective epsilon + + # With exact PME treatment, exception electrostatics is handled through offset parameters. + if use_exact_pme_treatment: + all_electrostatics_custom_bond_forces = [] + else: + # Create CustomBondForces to handle electrostatics 1,4 exceptions interactions between + # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda + # to 1.0 for decoupled interactions in alchemical/alchemical force. + if len(lambda_var_suffixes) > 1: + aa_electrostatics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_electrostatics_energy_expression, + 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) + all_electrostatics_custom_bond_forces = [aa_electrostatics_custom_bond_force] + else: + na_electrostatics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_electrostatics_energy_expression, + 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) + aa_electrostatics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_electrostatics_energy_expression, + 'lambda_electrostatics', lambda_var_suffixes, alchemical_region.annihilate_electrostatics) + all_electrostatics_custom_bond_forces = [na_electrostatics_custom_bond_force, aa_electrostatics_custom_bond_force] + # Create CustomBondForce to handle exceptions for electrostatics + for force in all_electrostatics_custom_bond_forces: + force.addPerBondParameter("chargeprod") # charge product + force.addPerBondParameter("sigma") # Lennard-Jones effective sigma + + # ------------------------------------------------------------------------------- + # Distribute particle interactions contributions in appropriate nonbonded forces + # ------------------------------------------------------------------------------- + + # Create atom groups. + alchemical_atomsets = [region.alchemical_atoms for region in alchemical_regions_pairs] + + # Copy NonbondedForce particle terms for alchemically-modified particles + # to CustomNonbondedForces, and/or add the charge offsets for exact PME. + # On CUDA, for efficiency reasons, all nonbonded forces (custom and not) + # must have the same particles. + for particle_index in range(nonbonded_force.getNumParticles()): + # Retrieve nonbonded parameters. + [charge, sigma, epsilon] = nonbonded_force.getParticleParameters(particle_index) + # Set sterics parameters in CustomNonbondedForces. + for force in all_sterics_custom_nonbonded_forces: + force.addParticle([sigma, epsilon]) + # Set electrostatics parameters in CustomNonbondedForces. + for force in all_electrostatics_custom_nonbonded_forces: + force.addParticle([charge, sigma]) + # Set offset parameters in NonbondedForce. + if use_exact_pme_treatment and particle_index in alchemical_atomsets[0] and len(lambda_var_suffixes) == 1: + nonbonded_force.addParticleParameterOffset('lambda_electrostatics{}'.format(lambda_var_suffixes[0]), + particle_index, charge, 0.0, 0.0) + + # Turn off interactions contribution from alchemically-modified particles in unmodified + # NonbondedForce that will be handled by all other forces + for particle_index in range(nonbonded_force.getNumParticles()): + # Retrieve parameters. + [charge, sigma, epsilon] = nonbonded_force.getParticleParameters(particle_index) + # Even with exact treatment of the PME electrostatics, we turn off + # the NonbondedForce charge which is modeled by the offset parameter. + if particle_index in alchemical_atomsets[0]: + nonbonded_force.setParticleParameters(particle_index, abs(0.0*charge), sigma, abs(0*epsilon)) + # Restrict interaction evaluation of CustomNonbondedForces to their respective atom groups. + # Sterics + if len(lambda_var_suffixes) == 1: + logger.debug('Adding steric interaction groups between {} and the environment.'.format(lambda_var_suffixes[0])) + na_sterics_custom_nonbonded_force.addInteractionGroup(nonalchemical_atomset, alchemical_atomsets[0]) + + logger.debug('Adding a steric interaction group between group {0} and {1}.'.format(lambda_var_suffixes[0], + lambda_var_suffixes[-1])) + aa_sterics_custom_nonbonded_force.addInteractionGroup(alchemical_atomsets[0], alchemical_atomsets[-1]) + + # Electrostatics + if not use_exact_pme_treatment: + if len(lambda_var_suffixes) == 1: + logger.debug('Adding electrostatic interaction groups between {} and the environment.'.format(lambda_var_suffixes[0])) + na_electrostatics_custom_nonbonded_force.addInteractionGroup(nonalchemical_atomset, alchemical_atomsets[0]) + + logger.debug('Adding a electrostatic interaction group between group {0} and {1}.'.format(lambda_var_suffixes[0], + lambda_var_suffixes[-1])) + aa_electrostatics_custom_nonbonded_force.addInteractionGroup(alchemical_atomsets[0], alchemical_atomsets[-1]) + + else: + # Using the nonbonded force to handle electrostatics + # and the "interaction groups" in the nonbonded have already been handled by exclusions. + pass + + # --------------------------------------------------------------- + # Distribute exceptions contributions in appropriate bond forces + # --------------------------------------------------------------- + all_custom_nonbonded_forces = all_sterics_custom_nonbonded_forces + all_electrostatics_custom_nonbonded_forces + # Move all NonbondedForce exception terms for alchemically-modified particles to CustomBondForces. + for exception_index in range(nonbonded_force.getNumExceptions()): + # Retrieve parameters. + iatom, jatom, chargeprod, sigma, epsilon = nonbonded_force.getExceptionParameters(exception_index) + + # Exclude this atom pair in CustomNonbondedForces. All nonbonded forces + # must have the same number of exceptions/exclusions on CUDA platform. + for force in all_custom_nonbonded_forces: + force.addExclusion(iatom, jatom) + + # Check if this is an exception or an exclusion + is_exception_epsilon = abs(epsilon.value_in_unit_system(unit.md_unit_system)) > 0.0 + is_exception_chargeprod = abs(chargeprod.value_in_unit_system(unit.md_unit_system)) > 0.0 + + # Check how many alchemical atoms we have in the exception. + if len(lambda_var_suffixes) > 1: + # Pair of interacting alchemical regions, therefore they are both alchemical or neither alchemical. + both_alchemical = ((iatom in alchemical_atomsets[0] and jatom in alchemical_atomsets[1]) or + (jatom in alchemical_atomsets[0] and iatom in alchemical_atomsets[1])) + only_one_alchemical = False + #The condition of at_least_one_alchemical is treated only once per single + # region so we don't repeat it when dealing with pairs of interacting regions. + at_least_one_alchemical = False + + if use_exact_pme_treatment and both_alchemical and is_exception_chargeprod: + # Exceptions here should be scaled by lam0*lam1. + # This can be implemented in the future using a CustomBondForce. + raise ValueError('Cannot have exception that straddles two alchemical regions') + + else: + # Single alchemical region. + both_alchemical = iatom in alchemical_atomsets[0] and jatom in alchemical_atomsets[0] + at_least_one_alchemical = iatom in alchemical_atomsets[0] or jatom in alchemical_atomsets[0] + only_one_alchemical = at_least_one_alchemical and not both_alchemical + + # If this is an electrostatic exception and we're using exact PME, + # we just have to add the exception offset to the NonbondedForce. + if use_exact_pme_treatment and at_least_one_alchemical and is_exception_chargeprod: + nonbonded_force.addExceptionParameterOffset('lambda_electrostatics{}'.format(lambda_var_suffixes[0]), + exception_index, chargeprod, 0.0, 0.0) + + # If exception (and not exclusion), add special CustomBondForce terms to + # handle alchemically-modified Lennard-Jones and electrostatics exceptions + if both_alchemical: + if is_exception_epsilon: + aa_sterics_custom_bond_force.addBond(iatom, jatom, [sigma, epsilon]) + if is_exception_chargeprod and not use_exact_pme_treatment: + aa_electrostatics_custom_bond_force.addBond(iatom, jatom, [chargeprod, sigma]) + + # When this is a single region we model the exception between alchemical + # and non-alchemical particles using a single custom bond. + elif only_one_alchemical: + if is_exception_epsilon: + na_sterics_custom_bond_force.addBond(iatom, jatom, [sigma, epsilon]) + if is_exception_chargeprod and not use_exact_pme_treatment: + na_electrostatics_custom_bond_force.addBond(iatom, jatom, [chargeprod, sigma]) + # else: both particles are non-alchemical, leave them in the unmodified NonbondedForce + + # Turn off all exception contributions from alchemical atoms in the NonbondedForce + # modelling non-alchemical atoms only. We need to do it only once per single + # region so we don't repeat it when dealing with pairs of interacting regions. + if at_least_one_alchemical: + nonbonded_force.setExceptionParameters(exception_index, iatom, jatom, + abs(0.0*chargeprod), sigma, abs(0.0*epsilon)) + # Add global parameters to forces. + def add_global_parameters(force): + force.addGlobalParameter('softcore_alpha', alchemical_region.softcore_alpha) + force.addGlobalParameter('softcore_beta', alchemical_region.softcore_beta) + force.addGlobalParameter('softcore_a', alchemical_region.softcore_a) + force.addGlobalParameter('softcore_b', alchemical_region.softcore_b) + force.addGlobalParameter('softcore_c', alchemical_region.softcore_c) + force.addGlobalParameter('softcore_d', alchemical_region.softcore_d) + force.addGlobalParameter('softcore_e', alchemical_region.softcore_e) + force.addGlobalParameter('softcore_f', alchemical_region.softcore_f) + + all_custom_forces = (all_custom_nonbonded_forces + + all_sterics_custom_bond_forces + + all_electrostatics_custom_bond_forces) + for force in all_custom_forces: + add_global_parameters(force) + # With exact treatment of PME electrostatics, the NonbondedForce + # is affected by lambda electrostatics as well. + if 'lambda_sterics{}'.format(lambda_var_suffixes[0]) in forces_by_lambda: + forces_by_lambda['lambda_electrostatics{}'.format(lambda_var_suffixes[0])].extend(all_electrostatics_custom_nonbonded_forces + all_electrostatics_custom_bond_forces) + forces_by_lambda['lambda_sterics{}'.format(lambda_var_suffixes[0])].extend(all_sterics_custom_nonbonded_forces + all_sterics_custom_bond_forces) + else: + forces_by_lambda['lambda_electrostatics{}'.format(lambda_var_suffixes[0])] = all_electrostatics_custom_nonbonded_forces + all_electrostatics_custom_bond_forces + forces_by_lambda['lambda_sterics{}'.format(lambda_var_suffixes[0])] = all_sterics_custom_nonbonded_forces + all_sterics_custom_bond_forces + # CAVE: I modified this, pushed this into the inner loop, was one level up + if use_exact_pme_treatment: + forces_by_lambda['lambda_electrostatics{}'.format(lambda_var_suffixes[0])].append(nonbonded_force) + else: + forces_by_lambda[''] = [nonbonded_force] + return forces_by_lambda + + def _alchemically_modify_CustomNonbondedForce(self, reference_force, _, __): + """NYI: Create alchemically-modified version of a CustomNonbondedForce generated from the LennardJonesGenerator. + + When working, this will correctly modify the CustomNonbondedForce made by the OpenMM forcefield.py file's + "LennardJonesGenerator" function which creates tabulated potentials for the C6 and C12 interactions + (i.e. Acoef = 4es^12 and Bcoef = 4es^6) + + However, this has not been implemented as there are some technical problems which need to be resolved + both in this code (flow of converting "native" nonbonded interactions from multiple forces (NB + CustomNB) + into alchemical forces) and in the science (How do you softcore potential a "A/r^12 - B/r^6" form where A and B + are tabulated?). + + + See https://github.com/choderalab/openmmtools/issues/510 for more details on this problem. + + """ + # See https://github.com/openmm/openmm/blob/be19e0222ddf66f612016a3c1f687161a53c2396/wrappers/python/openmm/app/forcefield.py#L2548-L2572 + lj_generator_expression = 'acoef(type1, type2)/r^12 - bcoef(type1, type2)/r^6' + reference_energy_expression = reference_force.getEnergyFunction() + if lj_generator_expression in reference_energy_expression: + error_msg = (f"Unsupported Native Lennard Jones representation!\n" + f"There is a CustomNonbondedForce which contains the energy function:\n" + f"\t{lj_generator_expression}\n" + f"Which is likely from the OpenMM forcefield.py file for Tabulated Lennard Jones functions" + f"such as the CHARMM36 FF. Supporting this type of LJ representation is not yet implemented.\n" + f"See https://github.com/choderalab/openmmtools/issues/510 for more details." + ) + raise NotImplementedError(error_msg) + # Don't create a force if you made it here (remove when implemented) + return {'': [copy.deepcopy(reference_force)]} + + def _alchemically_modify_AmoebaMultipoleForce(self, reference_force, alchemical_region, _): + if len(alchemical_region) > 1: + raise NotImplementedError("Multiple regions does not work with AmoebaMultipoleForce") + else: + alchemical_region = alchemical_region[0] + raise Exception("Not implemented; needs CustomMultipleForce") + + def _alchemically_modify_AmoebaVdwForce(self, reference_force, alchemical_region, _): + """Create alchemically-modified version of AmoebaVdwForce. + + Not implemented. + + TODO + ---- + * Supported periodic boundary conditions need to be handled correctly. + * Exceptions/exclusions need to be dealt with. + + """ + # This feature is incompletely implemented, so raise an exception. + if len(alchemical_region) > 1: + raise NotImplementedError("Multiple regions does not work with AmoebaVdwForce") + else: + alchemical_region = alchemical_region[0] + raise NotImplementedError('Alchemical modification of Amoeba VdW Forces is not supported.') + + # Softcore Halgren potential from Eq. 3 of + # Shi, Y., Jiao, D., Schnieders, M.J., and Ren, P. (2009). Trypsin-ligand binding free + # energy calculation with AMOEBA. Conf Proc IEEE Eng Med Biol Soc 2009, 2328-2331. + energy_expression = 'lambda^5 * epsilon * (1.07^7 / (0.7*(1-lambda)^2+(rho+0.07)^7)) * (1.12 / (0.7*(1-lambda)^2 + rho^7 + 0.12) - 2);' + energy_expression += 'epsilon = 4*epsilon1*epsilon2 / (sqrt(epsilon1) + sqrt(epsilon2))^2;' + energy_expression += 'rho = r / R0;' + energy_expression += 'R0 = (R01^3 + R02^3) / (R01^2 + R02^2);' + energy_expression += 'lambda = vdw_lambda * (ligand1*(1-ligand2) + ligand2*(1-ligand1)) + ligand1*ligand2;' + energy_expression += 'vdw_lambda = %f;' % vdw_lambda + + softcore_force = openmm.CustomNonbondedForce(energy_expression) + softcore_force.addPerParticleParameter('epsilon') + softcore_force.addPerParticleParameter('R0') + softcore_force.addPerParticleParameter('ligand') + + for particle_index in range(system.getNumParticles()): + # Retrieve parameters from vdW force. + [parentIndex, sigma, epsilon, reductionFactor] = force.getParticleParameters(particle_index) + # Add parameters to CustomNonbondedForce. + if particle_index in alchemical_region.alchemical_atoms: + softcore_force.addParticle([epsilon, sigma, 1]) + else: + softcore_force.addParticle([epsilon, sigma, 0]) + + # Deal with exclusions. + excluded_atoms = force.getParticleExclusions(particle_index) + for jatom in excluded_atoms: + if (particle_index < jatom): + softcore_force.addExclusion(particle_index, jatom) + + # Make sure periodic boundary conditions are treated the same way. + # TODO: Handle PBC correctly. + softcore_force.setNonbondedMethod( openmm.CustomNonbondedForce.CutoffPeriodic ) + softcore_force.setCutoffDistance( force.getCutoff() ) + + # Turn off vdW interactions for alchemically-modified atoms. + for particle_index in ligand_atoms: + # Retrieve parameters. + [parentIndex, sigma, epsilon, reductionFactor] = force.getParticleParameters(particle_index) + epsilon = 1.0e-6 * epsilon # TODO: For some reason, we cannot set epsilon to 0. + force.setParticleParameters(particle_index, parentIndex, sigma, epsilon, reductionFactor) + + # Deal with exceptions here. + # TODO + + return [softcore_force] + + @staticmethod + def _alchemically_modify_GBSAOBCForce(reference_force, alchemical_region, _, sasa_model='ACE'): + """Create alchemically-modified version of GBSAOBCForce. + + Parameters + ---------- + reference_force : openmm.GBSAOBCForce + The reference GBSAOBCForce to be alchemically modify. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the atoms to + alchemically modify. + sasa_model : str, optional, default='ACE' + Solvent accessible surface area model. + + Returns + ------- + custom_force : openmm.CustomGBForce + The alchemical version of the reference force. + + TODO + ---- + * Add support for all types of GBSA forces supported by OpenMM. + * Can we more generally modify any CustomGBSAForce? + + """ + if len(alchemical_region) > 1: + raise NotImplementedError("Multiple regions does not work with GBSAOBCForce") + else: + alchemical_region = alchemical_region[0] + + # TODO make sasa_model a Factory attribute? + custom_force = openmm.CustomGBForce() + + # Add per-particle parameters. + custom_force.addGlobalParameter("lambda_electrostatics", 1.0) + custom_force.addPerParticleParameter("charge") + custom_force.addPerParticleParameter("radius") + custom_force.addPerParticleParameter("scale") + custom_force.addPerParticleParameter("alchemical") + + # Set nonbonded method. + custom_force.setNonbondedMethod(reference_force.getNonbondedMethod()) + custom_force.setCutoffDistance(reference_force.getCutoffDistance()) + + # Add global parameters. + custom_force.addGlobalParameter("solventDielectric", reference_force.getSolventDielectric()) + custom_force.addGlobalParameter("soluteDielectric", reference_force.getSoluteDielectric()) + custom_force.addGlobalParameter("offset", 0.009) + + custom_force.addComputedValue("I", "(lambda_electrostatics*alchemical2 + (1-alchemical2))*step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r+C);" + "U=r+sr2;" + "C=2*(1/or1-1/L)*step(sr2-r-or1);" + "L=max(or1, D);" + "D=abs(r-sr2);" + "sr2 = scale2*or2;" + "or1 = radius1-offset; or2 = radius2-offset", openmm.CustomGBForce.ParticlePairNoExclusions) + + custom_force.addComputedValue("B", "1/(1/or-tanh(psi-0.8*psi^2+4.85*psi^3)/radius);" + "psi=I*or; or=radius-offset", openmm.CustomGBForce.SingleParticle) + + custom_force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*(lambda_electrostatics*alchemical+(1-alchemical))*charge^2/B", openmm.CustomGBForce.SingleParticle) + if sasa_model == 'ACE': + custom_force.addEnergyTerm("(lambda_electrostatics*alchemical+(1-alchemical))*28.3919551*(radius+0.14)^2*(radius/B)^6", openmm.CustomGBForce.SingleParticle) + + custom_force.addEnergyTerm("-138.935485*(1/soluteDielectric-1/solventDielectric)*(lambda_electrostatics*alchemical1+(1-alchemical1))*charge1*(lambda_electrostatics*alchemical2+(1-alchemical2))*charge2/f;" + "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", openmm.CustomGBForce.ParticlePairNoExclusions); + + # Add particle parameters. + for particle_index in range(reference_force.getNumParticles()): + # Retrieve parameters. + [charge, radius, scaling_factor] = reference_force.getParticleParameters(particle_index) + # Set particle parameters. + if particle_index in alchemical_region.alchemical_atoms: + parameters = [charge, radius, scaling_factor, 1.0] + else: + parameters = [charge, radius, scaling_factor, 0.0] + custom_force.addParticle(parameters) + + return {'lambda_electrostatics': [custom_force]} + + def _alchemically_modify_CustomGBForce(self, reference_force, alchemical_region, _): + """Create alchemically-modified version of CustomGBForce. + + The GB functions are meta-programmed using the following rules: + - 'lambda_electrostatics' is added as a global parameter. + - 'alchemical' is added as a per-particle parameter. All atoms in + the alchemical group have this parameter set to 1; otherwise 0. + - Any single-particle energy term (`CustomGBForce.SingleParticle`) + is scaled by `(lambda_electrostatics*alchemical+(1-alchemical))` + - Any two-particle energy term (`CustomGBForce.ParticlePairNoExclusions`) + has charge 1 (`charge1`) replaced by `(lambda_electrostatics*alchemical1+(1-alchemical1))*charge1` + and charge 2 (`charge2`) replaced by `(lambda_electrostatics*alchemical2+(1-alchemical2))*charge2`. + - Any single-particle computed value (`CustomGBForce.SingleParticle`) + remains unmodified + - Any two-particle computed value (`CustomGBForce.ParticlePairNoExclusions`) + is scaled by `(lambda_electrostatics*alchemical2 + (1-alchemical2))` + + Scaling of a term should always prepend and capture the value with + an intermediate variable. For example, prepending `scaling * unscaled; unscaled =` + will capture the value of the expression as `unscaled` and multiple by `scaled`. + This avoids the need to identify the head expression and add parentheses. + + .. warning:: + This may not work correctly for all GB models. + + Parameters + ---------- + reference_force : openmm.GBSAOBCForce + The reference GBSAOBCForce to be alchemically modify. + alchemical_region : AlchemicalRegion + The alchemical region containing the indices of the atoms to + alchemically modify. + + Returns + ------- + custom_force : openmm.CustomGBForce + The alchemical version of the reference force. + + """ + if len(alchemical_region) > 1: + raise NotImplementedError("Multiple regions does not work with CustomGBForce") + else: + alchemical_region = alchemical_region[0] + + custom_force = openmm.CustomGBForce() + + # Add global parameters + for index in range(reference_force.getNumGlobalParameters()): + name = reference_force.getGlobalParameterName(index) + default_value = reference_force.getGlobalParameterDefaultValue(index) + custom_force.addGlobalParameter(name, default_value) + custom_force.addGlobalParameter("lambda_electrostatics", 1.0) + + # Add per-particle parameters. + for index in range(reference_force.getNumPerParticleParameters()): + name = reference_force.getPerParticleParameterName(index) + custom_force.addPerParticleParameter(name) + custom_force.addPerParticleParameter("alchemical") + + # Set nonbonded methods. + custom_force.setNonbondedMethod(reference_force.getNonbondedMethod()) + custom_force.setCutoffDistance(reference_force.getCutoffDistance()) + + # Add computations. + for index in range(reference_force.getNumComputedValues()): + name, expression, computation_type = reference_force.getComputedValueParameters(index) + + # Alter expression for particle pair terms only. + if computation_type is not openmm.CustomGBForce.SingleParticle: + prepend = ('alchemical_scaling*unscaled; ' + 'alchemical_scaling = (lambda_electrostatics*alchemical2 + (1-alchemical2)); ' + 'unscaled = ') + expression = prepend + expression + + custom_force.addComputedValue(name, expression, computation_type) + + # Add energy terms. + for index in range(reference_force.getNumEnergyTerms()): + expression, computation_type = reference_force.getEnergyTermParameters(index) + + # Alter expressions + if computation_type is openmm.CustomGBForce.SingleParticle: + prepend = ('alchemical_scaling*unscaled; ' + 'alchemical_scaling = (lambda_electrostatics*alchemical + (1-alchemical)); ' + 'unscaled = ') + expression = prepend + expression + else: + expression = expression.replace('charge1', 'alchemically_scaled_charge1') + expression = expression.replace('charge2', 'alchemically_scaled_charge2') + expression += ' ; alchemically_scaled_charge1 = (lambda_electrostatics*alchemical1+(1-alchemical1)) * charge1;' + expression += ' ; alchemically_scaled_charge2 = (lambda_electrostatics*alchemical2+(1-alchemical2)) * charge2;' + + custom_force.addEnergyTerm(expression, computation_type) + + # Add particle parameters + for particle_index in range(reference_force.getNumParticles()): + parameters = reference_force.getParticleParameters(particle_index) + # Append alchemical parameter + parameters = list(parameters) + if particle_index in alchemical_region.alchemical_atoms: + parameters.append(1.0) + else: + parameters.append(0.0) + custom_force.addParticle(parameters) + + # Add tabulated functions + for function_index in range(reference_force.getNumTabulatedFunctions()): + name = reference_force.getTabulatedFunctionName(function_index) + function = reference_force.getTabulatedFunction(function_index) + function_copy = copy.deepcopy(function) + custom_force.addTabulatedFunction(name, function_copy) + + # Add exclusions + for exclusion_index in range(reference_force.getNumExclusions()): + [particle1, particle2] = reference_force.getExclusionParticles(exclusion_index) + custom_force.addExclusion(particle1, particle2) + + return {'lambda_electrostatics': [custom_force]} + + # ------------------------------------------------------------------------- + # Internal usage: Infer force labels + # ------------------------------------------------------------------------- + + @staticmethod + def _find_force_components(alchemical_system): + """Return force labels and indices for each force.""" + def add_label(label, index): + assert label not in force_labels + force_labels[label] = index + + def check_parameter(custom_force, parameter): + for parameter_id in range(custom_force.getNumGlobalParameters()): + parameter_name = custom_force.getGlobalParameterName(parameter_id) + if parameter_name.startswith(parameter): + region_name = parameter_name[len(parameter)+1:] if len(parameter_name) > len(parameter) else None + return [True, region_name] + return [False, None] + + def check_energy_expression(custom_force, parameter): + try: + energy_expression = custom_force.getEnergyFunction() + except AttributeError: # CustomGBForce + found = False + for index in range(custom_force.getNumEnergyTerms()): + expression, _ = custom_force.getEnergyTermParameters(index) + if parameter in expression: + found = True + break + return [found, ''] # CustomGBForce will not have a parameter suffix + found = parameter in energy_expression + if not found: + return [found, ''] # param not found and by extension no parameter suffix + #Look for parameter suffix + p = re.compile(r'{}_([A-Za-z0-9]+)'.format(parameter)) + try: + suffix = p.search(energy_expression).group(1) + return [found, suffix] + except AttributeError: + return [found, ''] # no parameter suffix found + + force_labels = {} + nonbonded_forces = {} + sterics_bond_forces = {} + electro_bond_forces = {} + + # We save CustomBondForces and CustomNonbondedForces used for nonbonded + # forces and exceptions to distinguish them later + for force_index, force in enumerate(alchemical_system.getForces()): + if isinstance(force, openmm.CustomAngleForce): + parameter_found, region_name = check_parameter(force, 'lambda_angles') + if parameter_found: + label = 'alchemically modified HarmonicAngleForce' + if region_name is not None: + label = label + ' for region ' + region_name + add_label(label, force_index) + + elif isinstance(force, openmm.CustomBondForce) and check_parameter(force, 'lambda_bonds')[0]: + #Need extra check for 'lambda_bonds' in the if to differntiate from exceptions + parameter_found, region_name = check_parameter(force, 'lambda_bonds') + if parameter_found: + label = 'alchemically modified HarmonicBondForce' + if region_name is not None: + label = label + ' for region ' + region_name + add_label(label, force_index) + + elif isinstance(force, openmm.CustomTorsionForce): + parameter_found, region_name = check_parameter(force, 'lambda_torsions') + if parameter_found: + label = 'alchemically modified PeriodicTorsionForce' + if region_name is not None: + label = label + ' for region ' + region_name + add_label(label, force_index) + + elif isinstance(force, openmm.CustomGBForce): + parameter_found, _ = check_parameter(force, 'lambda_electrostatics') + if parameter_found: + #No multi region for GBForce + if check_energy_expression(force, 'unscaled')[0]: + add_label('alchemically modified CustomGBForce', force_index) + else: + add_label('alchemically modified GBSAOBCForce', force_index) + + elif isinstance(force, openmm.CustomBondForce): + parameter_found, region_type_suffix = check_energy_expression(force, 'lambda') + if parameter_found: + _, region_name_suffix = check_energy_expression(force, 'lambda_{}'.format(region_type_suffix)) + if region_type_suffix == 'sterics': + if region_name_suffix in sterics_bond_forces: + sterics_bond_forces[region_name_suffix].append([force_index, force]) + else: + sterics_bond_forces[region_name_suffix] = [[force_index, force]] + if region_type_suffix == 'electrostatics': + if region_name_suffix in electro_bond_forces: + electro_bond_forces[region_name_suffix].append([force_index, force]) + else: + electro_bond_forces[region_name_suffix] = [[force_index, force]] + + elif (isinstance(force, openmm.CustomNonbondedForce) and force.getEnergyFunction() == '0.0;' and + force.getGlobalParameterName(0) == 'lambda_electrostatics'): + add_label('CustomNonbondedForce holding alchemical atoms unmodified charges', force_index) + + elif isinstance(force, openmm.CustomNonbondedForce): + parameter_found, region_type_suffix = check_energy_expression(force, 'lambda') + if parameter_found: + _, region_name_suffix = check_energy_expression(force, 'lambda_{}'.format(region_type_suffix)) + if region_type_suffix == 'sterics': + if region_name_suffix in nonbonded_forces: + nonbonded_forces[region_name_suffix].append(['sterics', force_index, force]) + else: + nonbonded_forces[region_name_suffix] = [['sterics', force_index, force]] + if region_type_suffix == 'electrostatics': + if region_name_suffix in nonbonded_forces: + nonbonded_forces[region_name_suffix].append(['electrostatics', force_index, force]) + else: + nonbonded_forces[region_name_suffix] = [['electrostatics', force_index, force]] + else: + add_label('unmodified ' + force.__class__.__name__, force_index) + + # Differentiate between na/aa nonbonded forces. + alchemical_atoms_by_region = {} + for region_name, forces in nonbonded_forces.items(): + for force_type, force_index, force in forces: + if region_name == '': + label = 'alchemically modified NonbondedForce for {}alchemical/alchemical ' + force_type + else: + label = 'alchemically modified NonbondedForce for {}alchemical/alchemical ' + force_type +\ + ' for region ' + region_name + interacting_atoms, alchemical_atoms = force.getInteractionGroupParameters(0) + alchemical_atoms_by_region[region_name] = [interacting_atoms, alchemical_atoms] + if interacting_atoms == alchemical_atoms: # alchemical-alchemical atoms + add_label(label.format(''), force_index) + else: + add_label(label.format('non-'), force_index) + + # Initialize sterics_bond_forces or electro_bond_forces for regions which did not have forces, as empty lists + for k in sterics_bond_forces.keys(): + if k in electro_bond_forces: + pass + else: + electro_bond_forces[k] = [] + for k in electro_bond_forces.keys(): + if k in sterics_bond_forces: + pass + else: + sterics_bond_forces[k] = [] + + # Differentiate between na/aa bond forces for exceptions. + for (region_name, sterics_forces), electro_forces in zip(sterics_bond_forces.items(), electro_bond_forces.values()): + if len(sterics_forces) == 0: + continue + for force_type, bond_forces in [('sterics', sterics_forces), ('electrostatics', electro_forces)]: + # With exact PME there are no CustomBondForces modeling electrostatics exceptions. + if force_type == 'electrostatics' and len(bond_forces) == 0: + continue + # Otherwise there should be two CustomBondForce. + assert len(bond_forces) == 2 + if region_name == '': + label = 'alchemically modified BondForce for {}alchemical/alchemical ' + force_type + ' exceptions' + else: + label = 'alchemically modified BondForce for {}alchemical/alchemical ' + force_type +\ + ' exceptions for region ' + region_name + + # Sort forces by number of bonds. + bond_forces = sorted(bond_forces, key=lambda x: x[1].getNumBonds()) + (force_index1, force1), (force_index2, force2) = bond_forces + + # Check if both define their parameters (with decoupling the lambda + # parameter doesn't exist in the alchemical-alchemical force) + parameter_name = 'lambda_' + force_type + if region_name != '': + parameter_name = parameter_name + '_{}'.format(region_name) + interacting_atoms, alchemical_atoms = alchemical_atoms_by_region[region_name] + + if check_parameter(force1, parameter_name)[0] != check_parameter(force2, parameter_name)[0]: + if check_parameter(force1, parameter_name)[0]: + add_label(label.format('non-'), force_index1) + add_label(label.format(''), force_index2) + else: + add_label(label.format(''), force_index1) + add_label(label.format('non-'), force_index2) + + # If they are both empty they are identical and any label works. + elif force1.getNumBonds() == 0 and force2.getNumBonds() == 0: + add_label(label.format(''), force_index1) + add_label(label.format('non-'), force_index2) + + # We check that the bond atoms are both alchemical or not. + else: + atom_i, atom_j, _ = force2.getBondParameters(0) + both_alchemical = atom_i in alchemical_atoms and atom_j in alchemical_atoms + if both_alchemical: + add_label(label.format(''), force_index2) + add_label(label.format('non-'), force_index1) + else: + add_label(label.format('non-'), force_index2) + add_label(label.format(''), force_index1) + return force_labels + + +if __name__ == '__main__': + import doctest + doctest.testmod() + # doctest.run_docstring_examples(AlchemicalFunction, globals()) \ No newline at end of file diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 1c88e5b89..65d04a866 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -36,7 +36,7 @@ from openmmtools.states import (SamplerState, ThermodynamicState, create_thermodynamic_state_protocol, ) -from .utils import AlchemicalState +# from .utils import AlchemicalState from typing import Optional from openmm import app from openmm import unit as omm_unit @@ -80,8 +80,6 @@ logger = logging.getLogger(__name__) -from openmmtools.tests.test_alchemy import compare_system_energies - class BaseSepTopSetupUnit(gufe.ProtocolUnit): """ Base class for the setup of ligand SepTop RBFE free energy transformations. @@ -634,7 +632,6 @@ def get_system_AB( return omm_system_AB, omm_topology_AB, positions_AB, system_modeller_AB - def run(self, dry=False, verbose=True, scratch_basepath=None, shared_basepath=None) -> dict[str, Any]: """ @@ -711,14 +708,14 @@ def run(self, dry=False, verbose=True, # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") - equ_positions_A = self._pre_equilibrate( - omm_system_A, omm_topology_A, positions_A, settings, dry - ) - equ_positions_B = self._pre_equilibrate( - omm_system_B, omm_topology_B, positions_B, settings, dry - ) - # equ_positions_A = positions_A - # equ_positions_B = positions_B + # equ_positions_A = self._pre_equilibrate( + # omm_system_A, omm_topology_A, positions_A, settings, dry + # ) + # equ_positions_B = self._pre_equilibrate( + # omm_system_B, omm_topology_B, positions_B, settings, dry + # ) + equ_positions_A = positions_A + equ_positions_B = positions_B simtk.openmm.app.pdbfile.PDBFile.writeFile( omm_topology_A, equ_positions_A, open(self.shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( @@ -758,22 +755,18 @@ def run(self, dry=False, verbose=True, # 9. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") - ref_system = copy.copy(omm_system_AB) - apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) - alchemical_regions = openmmtools.alchemy.AlchemicalRegion( - alchemical_atoms=atom_indices_AB_A + atom_indices_AB_B) - print(alchemical_regions) - print(openmmtools.tests.test_alchemy.compute_energy(omm_system_A, - positions_A)) - print(openmmtools.tests.test_alchemy.compute_energy(omm_system_B, - positions_B)) - print(openmmtools.tests.test_alchemy.compute_energy(ref_system, - positions_AB)) - print(openmmtools.tests.test_alchemy.compute_energy(omm_system_AB, - positions_AB)) - compare_system_energies( - ref_system, omm_system_AB, alchemical_regions, positions_AB) - + # apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) + + # Alternatively use AbsoluteAlchemicalFactory from openmmtools + from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory, AlchemicalRegion + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=atom_indices_AB_A, name='ligandA') + alchemical_region_B = AlchemicalRegion( + alchemical_atoms=atom_indices_AB_B, name='ligandB') + alchemical_system = factory.create_alchemical_system( + omm_system_AB, [alchemical_region_A, alchemical_region_B]) + omm_system_AB = alchemical_system # 10. Apply Restraints off_A = alchem_comps["stateA"][0].to_openff().to_topology() @@ -944,6 +937,8 @@ def _get_states( sampler_state.box_vectors = box sampler_states = [sampler_state for _ in cmp_states] + potentials = [state.getPotentialEnergy() for state in sampler_states] + print(potentials) return sampler_states, cmp_states diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index f04112c17..0d2212e48 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1290,14 +1290,21 @@ def _get_lambda_schedule( lambdas = dict() - lambdas['lambda_electrostatics_ligandA'] = settings[ - 'lambda_settings'].lambda_elec_ligandA - lambdas['lambda_sterics_ligandA'] = settings[ - 'lambda_settings'].lambda_vdw_ligandA - lambdas['lambda_electrostatics_ligandB'] = settings[ - 'lambda_settings'].lambda_elec_ligandB - lambdas['lambda_sterics_ligandB'] = settings[ - 'lambda_settings'].lambda_vdw_ligandB + lambda_elec_A = settings['lambda_settings'].lambda_elec_ligandA + lambda_vdw_A = settings['lambda_settings'].lambda_vdw_ligandA + lambda_elec_B = settings['lambda_settings'].lambda_elec_ligandB + lambda_vdw_B = settings['lambda_settings'].lambda_vdw_ligandB + + # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 + # means fully interacting, not stateB + lambda_elec_A = [1 - x for x in lambda_elec_A] + lambda_vdw_A = [1 - x for x in lambda_vdw_A] + lambda_elec_B = [1 - x for x in lambda_elec_B] + lambda_vdw_B = [1 - x for x in lambda_vdw_B] + lambdas['lambda_electrostatics_ligandA'] = lambda_elec_A + lambdas['lambda_sterics_ligandA'] = lambda_vdw_A + lambdas['lambda_electrostatics_ligandB'] = lambda_elec_B + lambdas['lambda_sterics_ligandB'] = lambda_vdw_B return lambdas @@ -1386,17 +1393,28 @@ def _get_lambda_schedule( ) -> dict[str, npt.NDArray]: lambdas = dict() - lambdas['lambda_electrostatics_ligandA'] = settings[ - 'lambda_settings'].lambda_elec_ligandA - lambdas['lambda_sterics_ligandA'] = settings[ - 'lambda_settings'].lambda_vdw_ligandA - lambdas['lambda_restraints_ligandA'] = settings[ + lambda_elec_A = settings['lambda_settings'].lambda_elec_ligandA + lambda_vdw_A = settings['lambda_settings'].lambda_vdw_ligandA + lambda_elec_B = settings['lambda_settings'].lambda_elec_ligandB + lambda_vdw_B = settings['lambda_settings'].lambda_vdw_ligandB + lambda_restraints_A = settings[ 'lambda_settings'].lambda_restraints_ligandA - lambdas['lambda_electrostatics_ligandB'] = settings[ - 'lambda_settings'].lambda_elec_ligandB - lambdas['lambda_sterics_ligandB'] = settings[ - 'lambda_settings'].lambda_vdw_ligandB - lambdas['lambda_restraints_ligandB'] = settings[ + lambda_restraints_B = settings[ 'lambda_settings'].lambda_restraints_ligandB + # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 + # means fully interacting, not stateB + lambda_elec_A = [1 - x for x in lambda_elec_A] + lambda_vdw_A = [1 - x for x in lambda_vdw_A] + lambda_elec_B = [1 - x for x in lambda_elec_B] + lambda_vdw_B = [1 - x for x in lambda_vdw_B] + lambda_restraints_A = [1 - x for x in lambda_restraints_A] + lambda_restraints_B = [1 - x for x in lambda_restraints_B] + lambdas['lambda_electrostatics_ligandA'] = lambda_elec_A + lambdas['lambda_sterics_ligandA'] = lambda_vdw_A + lambdas['lambda_electrostatics_ligandB'] = lambda_elec_B + lambdas['lambda_sterics_ligandB'] = lambda_vdw_B + lambdas['lambda_restraints_ligandA'] = lambda_restraints_A + lambdas['lambda_restraints_ligandB'] = lambda_restraints_B + return lambdas \ No newline at end of file diff --git a/openfe/protocols/openmm_septop/femto_utils.py b/openfe/protocols/openmm_septop/femto_utils.py index fb0869465..7d52d0e5e 100644 --- a/openfe/protocols/openmm_septop/femto_utils.py +++ b/openfe/protocols/openmm_septop/femto_utils.py @@ -171,4 +171,88 @@ def assign_force_groups(system: openmm.System): elif isinstance(force, openmm.MonteCarloBarostat): force.setForceGroup(OpenMMForceGroup.BAROSTAT) else: - force.setForceGroup(OpenMMForceGroup.OTHER) \ No newline at end of file + force.setForceGroup(OpenMMForceGroup.OTHER) + +def is_close( + v1: openmm.unit.Quantity, + v2: openmm.unit.Quantity, + rtol=1.0e-5, + atol=1.0e-8, + equal_nan=False, +) -> bool | numpy.ndarray: + """Compares if two unit wrapped values are close using ``numpy.is_close``""" + + if not v1.unit.is_compatible(v2.unit): + return False + + return numpy.isclose( + v1.value_in_unit(v1.unit), + v2.value_in_unit(v1.unit), + atol=atol, + rtol=rtol, + equal_nan=equal_nan, + ) + + +def all_close( + v1: openmm.unit.Quantity, + v2: openmm.unit.Quantity, + rtol=1.0e-5, + atol=1.0e-8, + equal_nan=False, +) -> bool: + """Compares if all values in two unit wrapped array are close using + ``numpy.allclose`` + """ + + if not v1.unit.is_compatible(v2.unit): + return False + + if v1.shape != v2.shape: + return False + + return numpy.allclose( + v1.value_in_unit(v1.unit), + v2.value_in_unit(v1.unit), + atol=atol, + rtol=rtol, + equal_nan=equal_nan, + ) + +def compute_energy( + system: openmm.System, + positions: openmm.unit.Quantity, + box_vectors: openmm.unit.Quantity | None, + context_params: dict[str, float] | None = None, + platform: OpenMMPlatform = OpenMMPlatform.REFERENCE, + groups: int | set[int] = -1, +) -> openmm.unit.Quantity: + """Computes the potential energy of a system at a given set of positions. + + Args: + system: The system to compute the energy of. + positions: The positions to compute the energy at. + box_vectors: The box vectors to use if any. + context_params: Any global context parameters to set. + platform: The platform to use. + groups: The force groups to include in the energy calculation. + + Returns: + The computed energy. + """ + context_params = context_params if context_params is not None else {} + + context = openmm.Context( + system, + openmm.VerletIntegrator(0.0001 * openmm.unit.femtoseconds), + openmm.Platform.getPlatformByName(str(platform)), + ) + + for key, value in context_params.items(): + context.setParameter(key, value) + + if box_vectors is not None: + context.setPeriodicBoxVectors(*box_vectors) + context.setPositions(positions) + + return context.getState(getEnergy=True, groups=groups).getPotentialEnergy() \ No newline at end of file diff --git a/openfe/protocols/openmm_septop/utils.py b/openfe/protocols/openmm_septop/utils.py index ed6400acf..fa8a9ac14 100644 --- a/openfe/protocols/openmm_septop/utils.py +++ b/openfe/protocols/openmm_septop/utils.py @@ -80,330 +80,330 @@ def deserialize(filename: pathlib.Path): return item -class AlchemicalState(states.GlobalParameterState): - """Represent an alchemical state. - - The alchemical parameters modify the Hamiltonian and affect the - computation of the energy. Alchemical parameters that have value - None are considered undefined, which means that applying this - state to System and Context that have that parameter as a global - variable will raise an AlchemicalStateError. - - Parameters - ---------- - parameters_name_suffix : str, optional - If specified, the state will control a modified version of the global - parameters with the name ``parameter_name + '_' + parameters_name_suffix``. - When this is the case, the normal parameters are not accessible. - lambda_sterics : float, optional - Scaling factor for ligand sterics (Lennard-Jones and Halgren) - interactions (default is 1.0). - lambda_electrostatics : float, optional - Scaling factor for ligand charges, intrinsic Born radii, and surface - area term (default is 1.0). - lambda_bonds : float, optional - Scaling factor for alchemically-softened bonds (default is 1.0). - lambda_angles : float, optional - Scaling factor for alchemically-softened angles (default is 1.0). - lambda_torsions : float, optional - Scaling factor for alchemically-softened torsions (default is 1.0). - - Attributes - ---------- - lambda_sterics - lambda_electrostatics - lambda_bonds - lambda_angles - lambda_torsions - - Examples - -------- - Create an alchemically modified system. - - >>> from openmmtools import testsystems - >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - >>> alanine_vacuum = testsystems.AlanineDipeptideVacuum().system - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=range(22)) - >>> alanine_alchemical_system = factory.create_alchemical_system(reference_system=alanine_vacuum, - ... alchemical_regions=alchemical_region) - - Create a completely undefined alchemical state. - - >>> alchemical_state = AlchemicalState() - >>> print(alchemical_state.lambda_sterics) - None - >>> alchemical_state.apply_to_system(alanine_alchemical_system) - Traceback (most recent call last): - ... - openmmtools.alchemy.AlchemicalStateError: The system parameter lambda_electrostatics is not defined in this state. - - Create an AlchemicalState that matches the parameters defined in - the System. - - >>> alchemical_state = AlchemicalState.from_system(alanine_alchemical_system) - >>> alchemical_state.lambda_sterics - 1.0 - >>> alchemical_state.lambda_electrostatics - 1.0 - >>> print(alchemical_state.lambda_angles) - None - - AlchemicalState implement the IComposableState interface, so it can be - used with CompoundThermodynamicState. All the alchemical parameters are - accessible through the compound state. - - >>> import openmm - >>> from openmm import unit - >>> thermodynamic_state = states.ThermodynamicState(system=alanine_alchemical_system, - ... temperature=300*unit.kelvin) - >>> compound_state = states.CompoundThermodynamicState(thermodynamic_state=thermodynamic_state, - ... composable_states=[alchemical_state]) - >>> compound_state.lambda_sterics - 1.0 - - You can control the parameters in the OpenMM Context in this state by - setting the state attributes. - - >>> compound_state.lambda_sterics = 0.5 - >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) - >>> context = compound_state.create_context(integrator) - >>> context.getParameter('lambda_sterics') - 0.5 - >>> compound_state.lambda_sterics = 1.0 - >>> compound_state.apply_to_context(context) - >>> context.getParameter('lambda_sterics') - 1.0 - - You can express the alchemical parameters as a mathematical expression - involving alchemical variables. Here is an example for a two-stage function. - - >>> compound_state.set_alchemical_variable('lambda', 1.0) - >>> compound_state.lambda_sterics = AlchemicalFunction('step_hm(lambda - 0.5) + 2*lambda * step_hm(0.5 - lambda)') - >>> compound_state.lambda_electrostatics = AlchemicalFunction('2*(lambda - 0.5) * step(lambda - 0.5)') - >>> for l in [0.0, 0.25, 0.5, 0.75, 1.0]: - ... compound_state.set_alchemical_variable('lambda', l) - ... print(compound_state.lambda_sterics) - 0.0 - 0.5 - 1.0 - 1.0 - 1.0 - - """ - - _GLOBAL_PARAMETER_ERROR = AlchemicalStateError - - # ------------------------------------------------------------------------- - # Lambda properties - # ------------------------------------------------------------------------- - - class _LambdaParameter(states.GlobalParameterState.GlobalParameter): - """A global parameter in the interval [0, 1] with standard value 1.""" - - def __init__(self, parameter_name): - super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) - - @staticmethod - def lambda_validator(self, instance, parameter_value): - if parameter_value is None: - return parameter_value - if not (0.0 <= parameter_value <= 1.0): - raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) - return float(parameter_value) - - lambda_sterics_ligandA = _LambdaParameter('lambda_sterics_ligandA') - lambda_electrostatics_ligandB = _LambdaParameter( - 'lambda_electrostatics_ligandB') - lambda_sterics_ligandB = _LambdaParameter('lambda_sterics_ligandB') - lambda_electrostatics_ligandA = _LambdaParameter( - 'lambda_electrostatics_ligandA') - lambda_restraints_ligandA = _LambdaParameter('lambda_restraints_ligandA') - lambda_restraints_ligandB = _LambdaParameter('lambda_restraints_ligandB') - lambda_bonds = _LambdaParameter('lambda_bonds') - lambda_angles = _LambdaParameter('lambda_angles') - lambda_torsions = _LambdaParameter('lambda_torsions') - - @classmethod - def from_system(cls, system, *args, **kwargs): - """Constructor reading the state from an alchemical system. - - Parameters - ---------- - system : openmm.System - An alchemically modified system in a defined alchemical state. - parameters_name_suffix : str, optional - If specified, the state will search for a modified - version of the alchemical parameters with the name - ``parameter_name + '_' + parameters_name_suffix``. - - Returns - ------- - The AlchemicalState object representing the alchemical state of - the system. - - Raises - ------ - AlchemicalStateError - If the same parameter has different values in the system, or - if the system has no lambda parameters. - - """ - # The function is redefined here only to provide more specific documentation for this method. - return super().from_system(system, *args, **kwargs) - - def set_alchemical_parameters(self, new_value): - """Set all defined lambda parameters to the given value. - - The undefined parameters (i.e. those being set to None) remain - undefined. - - Parameters - ---------- - new_value : float - The new value for all defined parameters. - - """ - for parameter_name in self._parameters: - if self._parameters[parameter_name] is not None: - setattr(self, parameter_name, new_value) - - # ------------------------------------------------------------------------- - # Function variables - # ------------------------------------------------------------------------- - - def get_function_variable(self, variable_name): - """Return the value of the function variable. - - Function variables are variables entering mathematical expressions - specified with ``AlchemicalFunction``, which can be use to enslave - a lambda parameter to arbitrary variables. - - Parameters - ---------- - variable_name : str - The name of the function variable. - - Returns - ------- - variable_value : float - The value of the function variable. - - """ - # The function is redefined here only to provide more specific documentation for this method. - return super().get_function_variable(variable_name) - - def set_function_variable(self, variable_name, new_value): - """Set the value of the function variable. - - Function variables are variables entering mathematical expressions - specified with ``AlchemicalFunction``, which can be use to enslave - a lambda parameter to arbitrary variables. - - Parameters - ---------- - variable_name : str - The name of the function variable. - new_value : float - The new value for the variable. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().set_function_variable(variable_name, new_value) - - def get_alchemical_variable(self, variable_name): - """Return the value of the alchemical parameter. - - .. warning: - This is deprecated. Use ``get_function_variable`` instead. - - Parameters - ---------- - variable_name : str - The name of the alchemical variable. - - Returns - ------- - variable_value : float - The value of the alchemical variable. - """ - import warnings - warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' - 'Use AlchemicalState.get_function_variable instead.') - return super().get_function_variable(variable_name) - - def set_alchemical_variable(self, variable_name, new_value): - """Set the value of the alchemical variable. - - .. warning: - This is deprecated. Use ``set_function_variable`` instead. - - Parameters - ---------- - variable_name : str - The name of the alchemical variable. - new_value : float - The new value for the variable. - - """ - import warnings - warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' - 'Use AlchemicalState.get_function_variable instead.') - super().set_function_variable(variable_name, new_value) - - # ------------------------------------------------------------------------- - # IComposableState interface - # ------------------------------------------------------------------------- - - def apply_to_system(self, system): - """Set the alchemical state of the system to this. - - Parameters - ---------- - system : openmm.System - The system to modify. - - Raises - ------ - AlchemicalStateError - If the system does not have the required lambda global variables. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().apply_to_system(system) - - def check_system_consistency(self, system): - """Check if the system is in this alchemical state. - - It raises a AlchemicalStateError if the system is not consistent - with the alchemical state. - - Parameters - ---------- - system : openmm.System - The system to test. - - Raises - ------ - AlchemicalStateError - If the system is not consistent with this state. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().check_system_consistency(system) - - def apply_to_context(self, context): - """Put the Context into this AlchemicalState. - - Parameters - ---------- - context : openmm.Context - The context to set. - - Raises - ------ - AlchemicalStateError - If the context does not have the required lambda global variables. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().apply_to_context(context) +# class AlchemicalState(states.GlobalParameterState): +# """Represent an alchemical state. +# +# The alchemical parameters modify the Hamiltonian and affect the +# computation of the energy. Alchemical parameters that have value +# None are considered undefined, which means that applying this +# state to System and Context that have that parameter as a global +# variable will raise an AlchemicalStateError. +# +# Parameters +# ---------- +# parameters_name_suffix : str, optional +# If specified, the state will control a modified version of the global +# parameters with the name ``parameter_name + '_' + parameters_name_suffix``. +# When this is the case, the normal parameters are not accessible. +# lambda_sterics : float, optional +# Scaling factor for ligand sterics (Lennard-Jones and Halgren) +# interactions (default is 1.0). +# lambda_electrostatics : float, optional +# Scaling factor for ligand charges, intrinsic Born radii, and surface +# area term (default is 1.0). +# lambda_bonds : float, optional +# Scaling factor for alchemically-softened bonds (default is 1.0). +# lambda_angles : float, optional +# Scaling factor for alchemically-softened angles (default is 1.0). +# lambda_torsions : float, optional +# Scaling factor for alchemically-softened torsions (default is 1.0). +# +# Attributes +# ---------- +# lambda_sterics +# lambda_electrostatics +# lambda_bonds +# lambda_angles +# lambda_torsions +# +# Examples +# -------- +# Create an alchemically modified system. +# +# >>> from openmmtools import testsystems +# >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) +# >>> alanine_vacuum = testsystems.AlanineDipeptideVacuum().system +# >>> alchemical_region = AlchemicalRegion(alchemical_atoms=range(22)) +# >>> alanine_alchemical_system = factory.create_alchemical_system(reference_system=alanine_vacuum, +# ... alchemical_regions=alchemical_region) +# +# Create a completely undefined alchemical state. +# +# >>> alchemical_state = AlchemicalState() +# >>> print(alchemical_state.lambda_sterics) +# None +# >>> alchemical_state.apply_to_system(alanine_alchemical_system) +# Traceback (most recent call last): +# ... +# openmmtools.alchemy.AlchemicalStateError: The system parameter lambda_electrostatics is not defined in this state. +# +# Create an AlchemicalState that matches the parameters defined in +# the System. +# +# >>> alchemical_state = AlchemicalState.from_system(alanine_alchemical_system) +# >>> alchemical_state.lambda_sterics +# 1.0 +# >>> alchemical_state.lambda_electrostatics +# 1.0 +# >>> print(alchemical_state.lambda_angles) +# None +# +# AlchemicalState implement the IComposableState interface, so it can be +# used with CompoundThermodynamicState. All the alchemical parameters are +# accessible through the compound state. +# +# >>> import openmm +# >>> from openmm import unit +# >>> thermodynamic_state = states.ThermodynamicState(system=alanine_alchemical_system, +# ... temperature=300*unit.kelvin) +# >>> compound_state = states.CompoundThermodynamicState(thermodynamic_state=thermodynamic_state, +# ... composable_states=[alchemical_state]) +# >>> compound_state.lambda_sterics +# 1.0 +# +# You can control the parameters in the OpenMM Context in this state by +# setting the state attributes. +# +# >>> compound_state.lambda_sterics = 0.5 +# >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) +# >>> context = compound_state.create_context(integrator) +# >>> context.getParameter('lambda_sterics') +# 0.5 +# >>> compound_state.lambda_sterics = 1.0 +# >>> compound_state.apply_to_context(context) +# >>> context.getParameter('lambda_sterics') +# 1.0 +# +# You can express the alchemical parameters as a mathematical expression +# involving alchemical variables. Here is an example for a two-stage function. +# +# >>> compound_state.set_alchemical_variable('lambda', 1.0) +# >>> compound_state.lambda_sterics = AlchemicalFunction('step_hm(lambda - 0.5) + 2*lambda * step_hm(0.5 - lambda)') +# >>> compound_state.lambda_electrostatics = AlchemicalFunction('2*(lambda - 0.5) * step(lambda - 0.5)') +# >>> for l in [0.0, 0.25, 0.5, 0.75, 1.0]: +# ... compound_state.set_alchemical_variable('lambda', l) +# ... print(compound_state.lambda_sterics) +# 0.0 +# 0.5 +# 1.0 +# 1.0 +# 1.0 +# +# """ +# +# _GLOBAL_PARAMETER_ERROR = AlchemicalStateError +# +# # ------------------------------------------------------------------------- +# # Lambda properties +# # ------------------------------------------------------------------------- +# +# class _LambdaParameter(states.GlobalParameterState.GlobalParameter): +# """A global parameter in the interval [0, 1] with standard value 1.""" +# +# def __init__(self, parameter_name): +# super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) +# +# @staticmethod +# def lambda_validator(self, instance, parameter_value): +# if parameter_value is None: +# return parameter_value +# if not (0.0 <= parameter_value <= 1.0): +# raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) +# return float(parameter_value) +# +# lambda_sterics_ligandA = _LambdaParameter('lambda_sterics_ligandA') +# lambda_electrostatics_ligandB = _LambdaParameter( +# 'lambda_electrostatics_ligandB') +# lambda_sterics_ligandB = _LambdaParameter('lambda_sterics_ligandB') +# lambda_electrostatics_ligandA = _LambdaParameter( +# 'lambda_electrostatics_ligandA') +# lambda_restraints_ligandA = _LambdaParameter('lambda_restraints_ligandA') +# lambda_restraints_ligandB = _LambdaParameter('lambda_restraints_ligandB') +# lambda_bonds = _LambdaParameter('lambda_bonds') +# lambda_angles = _LambdaParameter('lambda_angles') +# lambda_torsions = _LambdaParameter('lambda_torsions') +# +# @classmethod +# def from_system(cls, system, *args, **kwargs): +# """Constructor reading the state from an alchemical system. +# +# Parameters +# ---------- +# system : openmm.System +# An alchemically modified system in a defined alchemical state. +# parameters_name_suffix : str, optional +# If specified, the state will search for a modified +# version of the alchemical parameters with the name +# ``parameter_name + '_' + parameters_name_suffix``. +# +# Returns +# ------- +# The AlchemicalState object representing the alchemical state of +# the system. +# +# Raises +# ------ +# AlchemicalStateError +# If the same parameter has different values in the system, or +# if the system has no lambda parameters. +# +# """ +# # The function is redefined here only to provide more specific documentation for this method. +# return super().from_system(system, *args, **kwargs) +# +# def set_alchemical_parameters(self, new_value): +# """Set all defined lambda parameters to the given value. +# +# The undefined parameters (i.e. those being set to None) remain +# undefined. +# +# Parameters +# ---------- +# new_value : float +# The new value for all defined parameters. +# +# """ +# for parameter_name in self._parameters: +# if self._parameters[parameter_name] is not None: +# setattr(self, parameter_name, new_value) +# +# # ------------------------------------------------------------------------- +# # Function variables +# # ------------------------------------------------------------------------- +# +# def get_function_variable(self, variable_name): +# """Return the value of the function variable. +# +# Function variables are variables entering mathematical expressions +# specified with ``AlchemicalFunction``, which can be use to enslave +# a lambda parameter to arbitrary variables. +# +# Parameters +# ---------- +# variable_name : str +# The name of the function variable. +# +# Returns +# ------- +# variable_value : float +# The value of the function variable. +# +# """ +# # The function is redefined here only to provide more specific documentation for this method. +# return super().get_function_variable(variable_name) +# +# def set_function_variable(self, variable_name, new_value): +# """Set the value of the function variable. +# +# Function variables are variables entering mathematical expressions +# specified with ``AlchemicalFunction``, which can be use to enslave +# a lambda parameter to arbitrary variables. +# +# Parameters +# ---------- +# variable_name : str +# The name of the function variable. +# new_value : float +# The new value for the variable. +# +# """ +# # The function is redefined here only to provide more specific documentation for this method. +# super().set_function_variable(variable_name, new_value) +# +# def get_alchemical_variable(self, variable_name): +# """Return the value of the alchemical parameter. +# +# .. warning: +# This is deprecated. Use ``get_function_variable`` instead. +# +# Parameters +# ---------- +# variable_name : str +# The name of the alchemical variable. +# +# Returns +# ------- +# variable_value : float +# The value of the alchemical variable. +# """ +# import warnings +# warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' +# 'Use AlchemicalState.get_function_variable instead.') +# return super().get_function_variable(variable_name) +# +# def set_alchemical_variable(self, variable_name, new_value): +# """Set the value of the alchemical variable. +# +# .. warning: +# This is deprecated. Use ``set_function_variable`` instead. +# +# Parameters +# ---------- +# variable_name : str +# The name of the alchemical variable. +# new_value : float +# The new value for the variable. +# +# """ +# import warnings +# warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' +# 'Use AlchemicalState.get_function_variable instead.') +# super().set_function_variable(variable_name, new_value) +# +# # ------------------------------------------------------------------------- +# # IComposableState interface +# # ------------------------------------------------------------------------- +# +# def apply_to_system(self, system): +# """Set the alchemical state of the system to this. +# +# Parameters +# ---------- +# system : openmm.System +# The system to modify. +# +# Raises +# ------ +# AlchemicalStateError +# If the system does not have the required lambda global variables. +# +# """ +# # The function is redefined here only to provide more specific documentation for this method. +# super().apply_to_system(system) +# +# def check_system_consistency(self, system): +# """Check if the system is in this alchemical state. +# +# It raises a AlchemicalStateError if the system is not consistent +# with the alchemical state. +# +# Parameters +# ---------- +# system : openmm.System +# The system to test. +# +# Raises +# ------ +# AlchemicalStateError +# If the system is not consistent with this state. +# +# """ +# # The function is redefined here only to provide more specific documentation for this method. +# super().check_system_consistency(system) +# +# def apply_to_context(self, context): +# """Put the Context into this AlchemicalState. +# +# Parameters +# ---------- +# context : openmm.Context +# The context to set. +# +# Raises +# ------ +# AlchemicalStateError +# If the context does not have the required lambda global variables. +# +# """ +# # The function is redefined here only to provide more specific documentation for this method. +# super().apply_to_context(context) diff --git a/openfe/tests/protocols/test_femto_fep.py b/openfe/tests/protocols/test_femto_fep.py new file mode 100644 index 000000000..f5d391956 --- /dev/null +++ b/openfe/tests/protocols/test_femto_fep.py @@ -0,0 +1,488 @@ +import numpy +import openmm +import openmm.app +import openmm.unit +import pytest + +from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close +from openfe.protocols.openmm_septop.femto_alchemy import ( + LAMBDA_CHARGES_LIGAND_1, + LAMBDA_CHARGES_LIGAND_2, + LAMBDA_VDW_LIGAND_1, + LAMBDA_VDW_LIGAND_2, + _convert_intramolecular_interactions, + apply_fep, +) +from openfe.protocols.openmm_septop.alchemy_copy import ( + AlchemicalRegion, + AbsoluteAlchemicalFactory, +) + +KJ_PER_MOL = openmm.unit.kilojoule_per_mole + + +E_CHARGE = 1.602176634e-19 * openmm.unit.coulomb +EPSILON0 = ( + 1e-6 + * 8.8541878128e-12 + / (openmm.unit.AVOGADRO_CONSTANT_NA * E_CHARGE**2) + * openmm.unit.farad + / openmm.unit.meter +) +ONE_4PI_EPS0 = 1 / (4 * numpy.pi * EPSILON0) * EPSILON0.unit * 10.0 # nm -> angstrom + + +def compute_interaction_energy( + epsilon, + sigma, + charge, + distance, + lambda_vdw: float = 1.0, + lambda_charges: float = 1.0, +): + r_electrostatics = distance + r_vdw = (0.5 * sigma**6 * (1.0 - lambda_vdw) + distance**6) ** (1.0 / 6.0) + + return ( + # vdw + 4.0 * lambda_vdw * epsilon * ((sigma / r_vdw) ** 12 - (sigma / r_vdw) ** 6) + # electrostatics + + ONE_4PI_EPS0 * lambda_charges * charge / r_electrostatics + ) * KJ_PER_MOL + + +@pytest.fixture +def three_particle_system(): + force = openmm.NonbondedForce() + force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) + force.setUseDispersionCorrection(False) + + charges = 0.1, 0.2, -0.3 + sigmas = 1.1, 1.2, 1.3 + epsilons = 210, 220, 230 + + force.addParticle(charges[0], sigmas[0] * openmm.unit.angstrom, epsilons[0]) + force.addParticle(charges[1], sigmas[1] * openmm.unit.angstrom, epsilons[1]) + force.addParticle(charges[2], sigmas[2] * openmm.unit.angstrom, epsilons[2]) + + system = openmm.System() + system.addParticle(1.0) + system.addParticle(1.0) + system.addParticle(1.0) + system.addForce(force) + + distances = [[0.0, 4.0, 3.0], [4.0, 0.0, 5.0], [3.0, 5.0, 0.0]] + + def interaction_energy_fn( + idx_a, idx_b, lambda_vdw: float = 1.0, lambda_charges: float = 1.0 + ): + epsilon = numpy.sqrt(epsilons[idx_a] * epsilons[idx_b]) + sigma = 0.5 * (sigmas[idx_a] + sigmas[idx_b]) + charge = charges[idx_a] * charges[idx_b] + + return compute_interaction_energy( + epsilon, sigma, charge, distances[idx_a][idx_b], lambda_vdw, lambda_charges + ) + + coords = ( + numpy.array( + [[0.0, 0.0, 0.0], [distances[0][1], 0.0, 0.0], [0.0, distances[0][2], 0.0]] + ) + * openmm.unit.angstrom + ) + + return system, coords, interaction_energy_fn + + +class TestNonbondedInteractions: + def test_convert_intramolecular_interactions(self): + system = openmm.System() + system.addParticle(1.0) + system.addParticle(1.0) + system.addParticle(1.0) + system.addParticle(1.0) + system.addParticle(1.0) + + bond_force = openmm.HarmonicBondForce() + bond_force.addBond(0, 1, 1.0 * openmm.unit.angstrom, 1.0) + bond_force.addBond(1, 2, 1.0 * openmm.unit.angstrom, 1.0) + bond_force.addBond(2, 3, 1.0 * openmm.unit.angstrom, 1.0) + bond_force.addBond(3, 4, 1.0 * openmm.unit.angstrom, 1.0) + system.addForce(bond_force) + + epsilons = (numpy.arange(5) * 10.0 + 200.0).tolist() + sigmas = (numpy.arange(5) / 10.0 + 1.0).tolist() + + charges = (numpy.arange(5) / 10.0).tolist() + + force = openmm.NonbondedForce() + + for i in range(5): + force.addParticle(charges[i], sigmas[i], epsilons[i]) + + for i, j in [ + (0, 1), + (0, 2), + (0, 3), + (1, 2), + (1, 3), + (1, 4), + (2, 3), + (2, 4), + (3, 4), + ]: + force.addException( + i, + j, + charges[i] * charges[j], + 0.5 * (sigmas[i] + sigmas[j]), + numpy.sqrt(epsilons[i] * epsilons[j]), + ) + + system.addForce(force) + + coords = ( + numpy.array( + [ + [0.0, 0.0, 0.0], + [1.0, 1.0, 0.0], + [2.0, 0.0, 0.0], + [3.0, 1.0, 0.0], + [4.0, 0.0, 0.0], + ] + ) + * openmm.unit.angstrom + ) + + existing_exclusions = [ + force.getExceptionParameters(i) for i in range(force.getNumExceptions()) + ] + energy_0 = compute_energy(system, coords, None) + + # we expect a 1-5 exclusion to be added. + _convert_intramolecular_interactions(force, {0, 1, 2, 3, 4}, set()) + + modified_exclusions = [ + force.getExceptionParameters(i) for i in range(force.getNumExceptions()) + ] + assert len(modified_exclusions) == len(existing_exclusions) + 1 + + for i in range(len(existing_exclusions)): + assert existing_exclusions[i][0] == modified_exclusions[i][0] + assert existing_exclusions[i][1] == modified_exclusions[i][1] + + assert all( + is_close(v_a, v_b) + for v_a, v_b in zip( + existing_exclusions[i][2:], modified_exclusions[i][2:], strict=True + ) + ) + + assert modified_exclusions[-1][:2] == [0, 4] + + energy_1 = compute_energy(system, coords, None) + + assert is_close(energy_0, energy_1) + + def test_one_ligand(self, three_particle_system): + """Test scaling the nonbonded interactions of single particles.""" + + system, coords, energy_fn = three_particle_system + + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=[0], name='ligandA') + alchemical_system = factory.create_alchemical_system( + system, [alchemical_region_A]) + energy_0_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 1.0, + LAMBDA_CHARGES_LIGAND_1: 1.0, + }, + ) + + apply_fep(system, {0}, set()) + + # expect lig_1 + solvent, lig_1 + lig_2 and lig_2 + solvent interaction when + # lambda=0 + energy_0 = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.0, + LAMBDA_CHARGES_LIGAND_1: 0.0, + }, + ) + expected_energy_0 = energy_fn(0, 2) + energy_fn(0, 1) + energy_fn(1, 2) + print(expected_energy_0, energy_0, energy_0_openmm) + assert is_close(energy_0, expected_energy_0) + assert is_close(energy_0_openmm, expected_energy_0) + + # expect only lig_2 + solvent interaction when lambda=1 + energy_1 = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 1.0, + LAMBDA_CHARGES_LIGAND_1: 1.0, + }, + ) + energy_1_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.0, + LAMBDA_CHARGES_LIGAND_1: 0.0, + }, + ) + expected_energy_1 = energy_fn(1, 2) + assert is_close(energy_1, expected_energy_1) + assert is_close(energy_1_openmm, expected_energy_1) + + # expect all particles to interact but only lig - solvent interactions to be + # scaled + energy_05 = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.5, + LAMBDA_CHARGES_LIGAND_1: 0.5, + }, + ) + energy_05_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.5, + LAMBDA_CHARGES_LIGAND_1: 0.5, + }, + ) + expected_energy_05 = ( + energy_fn(1, 2) + energy_fn(0, 2, 0.5, 0.5) + energy_fn(0, 1, 0.5, 0.5) + ) + assert is_close(energy_05, expected_energy_05) + assert is_close(energy_05_openmm, expected_energy_05) + + def test_two_ligands(self, three_particle_system): + """Test scaling the nonbonded interactions of single particles.""" + + system, coords, energy_fn = three_particle_system + + # Do it the openmm way + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=[0], name='ligandA') + alchemical_region_B = AlchemicalRegion( + alchemical_atoms=[1], name='ligandB') + alchemical_system = factory.create_alchemical_system( + system, [alchemical_region_A, alchemical_region_B]) + energy_0_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 1.0, + LAMBDA_CHARGES_LIGAND_1: 1.0, + LAMBDA_VDW_LIGAND_2: 0.0, + LAMBDA_CHARGES_LIGAND_2: 0.0, + }, + ) + + apply_fep(system, {0}, {1}) + # expect only lig_1 + solvent interaction when lambda=0 + energy_0 = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.0, + LAMBDA_CHARGES_LIGAND_1: 0.0, + LAMBDA_VDW_LIGAND_2: 1.0, + LAMBDA_CHARGES_LIGAND_2: 1.0, + }, + ) + expected_energy_0 = energy_fn(0, 2) + print(energy_0, energy_0_openmm, expected_energy_0) + assert is_close(energy_0, expected_energy_0) + assert is_close(energy_0_openmm, expected_energy_0) + + # expect only lig_2 + solvent interaction when lambda=1 + + energy_1 = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 1.0, + LAMBDA_CHARGES_LIGAND_1: 1.0, + LAMBDA_VDW_LIGAND_2: 0.0, + LAMBDA_CHARGES_LIGAND_2: 0.0, + }, + ) + + energy_1_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.0, + LAMBDA_CHARGES_LIGAND_1: 0.0, + LAMBDA_VDW_LIGAND_2: 1.0, + LAMBDA_CHARGES_LIGAND_2: 1.0, + }, + ) + print(energy_1_openmm) + expected_energy_1 = energy_fn(1, 2) + assert is_close(energy_1, expected_energy_1) + assert is_close(energy_1_openmm, expected_energy_1) + + # expect lig_1 + solvent and lig_2 + solvent interaction when lambda=0.5 + # but no lig_1 + lig_2 interaction by default + energy_05 = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.5, + LAMBDA_CHARGES_LIGAND_1: 0.5, + LAMBDA_VDW_LIGAND_2: 0.5, + LAMBDA_CHARGES_LIGAND_2: 0.5, + }, + ) + energy_05_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.5, + LAMBDA_CHARGES_LIGAND_1: 0.5, + LAMBDA_VDW_LIGAND_2: 0.5, + LAMBDA_CHARGES_LIGAND_2: 0.5, + }, + ) + print(energy_05_openmm) + print(energy_fn(0,1)) + expected_energy_05 = energy_fn(0, 2, 0.5, 0.5) + energy_fn(1, 2, 0.5, 0.5) + assert is_close(energy_05, expected_energy_05) + assert is_close(energy_05_openmm, expected_energy_05) + assert 4==5 + + def test_two_ligands_charges(self, three_particle_system): + """Test scaling the nonbonded interactions of single particles.""" + + system, coords, energy_fn = three_particle_system + + # Do it the openmm way + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=[0], name='ligandA') + alchemical_region_B = AlchemicalRegion( + alchemical_atoms=[1], name='ligandB') + alchemical_system = factory.create_alchemical_system( + system, [alchemical_region_A, alchemical_region_B]) + energy_openmm = compute_energy( + alchemical_system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 1.0, + LAMBDA_CHARGES_LIGAND_1: 0.8, + LAMBDA_VDW_LIGAND_2: 1.0, + LAMBDA_CHARGES_LIGAND_2: 0.2, + }, + ) + + apply_fep(system, {0}, {1}) + # expect only lig_1 + solvent interaction when lambda=0 + energy = compute_energy( + system, + coords, + None, + { + LAMBDA_VDW_LIGAND_1: 0.0, + LAMBDA_CHARGES_LIGAND_1: 0.2, + LAMBDA_VDW_LIGAND_2: 0.0, + LAMBDA_CHARGES_LIGAND_2: 0.8, + }, + ) + assert is_close(energy, energy_openmm) + + # def test_exception(self, three_particle_system): + # """Test that 1-n exceptions are properly created.""" + # + # system, coords, energy_fn = three_particle_system + # + # factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + # alchemical_region_A = AlchemicalRegion( + # alchemical_atoms=[0, 1], name='ligandA') + # # alchemical_region_B = AlchemicalRegion( + # # alchemical_atoms=[1], name='ligandB') + # alchemical_system = factory.create_alchemical_system( + # system, [alchemical_region_A]) + # + # apply_fep(system, {0, 1}, set()) + # + # for lambda_value in [0.0, 0.5, 1.0]: + # energy = compute_energy( + # system, + # coords, + # None, + # { + # LAMBDA_VDW_LIGAND_1: 1.0 - lambda_value, + # LAMBDA_CHARGES_LIGAND_1: 1.0 - lambda_value, + # }, + # ) + # energy_openmm = compute_energy( + # alchemical_system, + # coords, + # None, + # { + # LAMBDA_VDW_LIGAND_1: lambda_value, + # LAMBDA_CHARGES_LIGAND_1: lambda_value, + # }, + # ) + # expected_energy = ( + # energy_fn(0, 2, lambda_value, lambda_value) + # + energy_fn(1, 2, lambda_value, lambda_value) + # + energy_fn(0, 1, 1.0, 1.0) + # ) + # print(lambda_value, expected_energy, energy, energy_openmm) + # assert is_close(energy, expected_energy) + # assert is_close(energy_openmm, expected_energy) + # + # def test_existing_exception(self, three_particle_system): + # """Test that existing exceptions aren't changed.""" + # + # system, coords, energy_fn = three_particle_system + # + # charge, sigma, epsilon = 0.4, 1.4, 2.4 + # + # force: openmm.NonbondedForce = next(iter(system.getForces())) + # force.addException(0, 1, charge, sigma * openmm.unit.angstrom, epsilon) + # + # apply_fep(system, {0, 1}, set()) + # + # for lambda_value in [0.0, 0.5, 1.0]: + # energy = compute_energy( + # system, + # coords, + # None, + # { + # LAMBDA_VDW_LIGAND_1: 1.0 - lambda_value, + # LAMBDA_CHARGES_LIGAND_1: 1.0 - lambda_value, + # }, + # ) + # expected_energy = ( + # energy_fn(0, 2, lambda_value, lambda_value) + # + energy_fn(1, 2, lambda_value, lambda_value) + # + compute_interaction_energy(epsilon, sigma, charge, 4.0, 1.0, 1.0) + # ) + # assert is_close(energy, expected_energy) \ No newline at end of file From b7f7a5050f8c9405365a638b60666027087bd54f Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 6 Dec 2024 14:04:37 +0100 Subject: [PATCH 061/163] Add imports --- openfe/protocols/openmm_septop/base.py | 3 ++- openfe/tests/protocols/test_femto_fep.py | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 65d04a866..ccfc0d97f 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -77,6 +77,7 @@ from .femto_alchemy import apply_fep from .femto_restraints import select_ligand_idxs from .utils import serialize, deserialize +from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory, AlchemicalRegion, AlchemicalState logger = logging.getLogger(__name__) @@ -758,7 +759,7 @@ def run(self, dry=False, verbose=True, # apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) # Alternatively use AbsoluteAlchemicalFactory from openmmtools - from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory, AlchemicalRegion + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alchemical_region_A = AlchemicalRegion( alchemical_atoms=atom_indices_AB_A, name='ligandA') diff --git a/openfe/tests/protocols/test_femto_fep.py b/openfe/tests/protocols/test_femto_fep.py index f5d391956..ecf75d962 100644 --- a/openfe/tests/protocols/test_femto_fep.py +++ b/openfe/tests/protocols/test_femto_fep.py @@ -368,12 +368,9 @@ def test_two_ligands(self, three_particle_system): LAMBDA_CHARGES_LIGAND_2: 0.5, }, ) - print(energy_05_openmm) - print(energy_fn(0,1)) expected_energy_05 = energy_fn(0, 2, 0.5, 0.5) + energy_fn(1, 2, 0.5, 0.5) assert is_close(energy_05, expected_energy_05) assert is_close(energy_05_openmm, expected_energy_05) - assert 4==5 def test_two_ligands_charges(self, three_particle_system): """Test scaling the nonbonded interactions of single particles.""" From 420f3e56d6321a2df49f06a865fefc628e771d87 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 6 Dec 2024 16:24:15 +0000 Subject: [PATCH 062/163] Add boresch restraint class --- openfe/protocols/openmm_utils/omm_forces.py | 42 +------- .../protocols/openmm_utils/omm_restraints.py | 95 ++++++++++++++----- 2 files changed, 76 insertions(+), 61 deletions(-) diff --git a/openfe/protocols/openmm_utils/omm_forces.py b/openfe/protocols/openmm_utils/omm_forces.py index e9246b694..3ad9d0aa6 100644 --- a/openfe/protocols/openmm_utils/omm_forces.py +++ b/openfe/protocols/openmm_utils/omm_forces.py @@ -13,46 +13,22 @@ def get_boresch_energy_function( control_parameter: str, - K_r: float, r_aA0: float, - K_thetaA: float, theta_A0: float, - K_thetaB: float, theta_B0: float, - K_phiA: float, phi_A0: float, - K_phiB: float, phi_B0: float, - K_phiC: float, phi_C0: float ) -> str: energy_function = ( f"{control_parameter} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " "+ (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + (K_phiC/2)*dphi_C^2; " - "dphi_A = dA - floor(dA/(2*pi)+0.5)*(2*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; " - "dphi_B = dB - floor(dB/(2*pi)+0.5)*(2*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; " - "dphi_C = dC - floor(dC/(2*pi)+0.5)*(2*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; " + "dphi_A = dA - floor(dA/(2.0*pi)+0.5)*(2.0*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; " + "dphi_B = dB - floor(dB/(2.0*pi)+0.5)*(2.0*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; " + "dphi_C = dC - floor(dC/(2.0*pi)+0.5)*(2.0*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; " f"pi = {np.pi}; " - f"K_r = {K_r}; " - f"r_aA0 = {r_aA0}; " - f"K_thetaA = {K_thetaA}; " - f"theta_A0 = {theta_A0}; " - f"K_thetaB = {K_thetaB}; " - f"theta_B0 = {theta_B0}; " - f"K_phiA = {K_phiA}; " - f"phi_A0 = {phi_A0}; " - f"K_phiB = {K_phiB}; " - f"phi_B0 = {phi_B0}; " - f"K_phiC = {K_phiC}; " - f"phi_C0 = {phi_C0}; " ) return energy_function def get_periodic_boresch_energy_function( control_parameter: str, - K_r: float, r_aA0: float, - K_thetaA: float, theta_A0: float, - K_thetaB: float, theta_B0: float, - K_phiA: float, phi_A0: float, - K_phiB: float, phi_B0: float, - K_phiC: float, phi_C0: float ) -> str: energy_function = ( f"{control_parameter} * E; " @@ -63,18 +39,6 @@ def get_periodic_boresch_energy_function( "uphi_B = (1-cos(dB)); dB = dihedral(p2,p3,p4,p5) - phi_B0; " "uphi_C = (1-cos(dC)); dC = dihedral(p3,p4,p5,p6) - phi_C0; " f"pi = {np.pi}; " - f"K_r = {K_r}; " - f"r_aA0 = {r_aA0}; " - f"K_thetaA = {K_thetaA}; " - f"theta_A0 = {theta_A0}; " - f"K_thetaB = {K_thetaB}; " - f"theta_B0 = {theta_B0}; " - f"K_phiA = {K_phiA}; " - f"phi_A0 = {phi_A0}; " - f"K_phiB = {K_phiB}; " - f"phi_B0 = {phi_B0}; " - f"K_phiC = {K_phiC}; " - f"phi_C0 = {phi_C0}; " ) return energy_function diff --git a/openfe/protocols/openmm_utils/omm_restraints.py b/openfe/protocols/openmm_utils/omm_restraints.py index f678428c8..d03b1f195 100644 --- a/openfe/protocols/openmm_utils/omm_restraints.py +++ b/openfe/protocols/openmm_utils/omm_restraints.py @@ -16,7 +16,9 @@ import abc from typing import Optional, Union, Callable +import numpy as np import openmm +from openmm import unit as omm_unit from openmmtools.forces import ( HarmonicRestraintForce, HarmonicRestraintBondForce, @@ -24,6 +26,7 @@ FlatBottomRestraintBondForce, ) from openmmtools.states import GlobalParameterState, ThermodynamicState +from openff.units.openmm import to_openmm from gufe.settings.models import SettingsBaseModel from openfe.protocols.openmm_utils.omm_forces import ( @@ -143,7 +146,7 @@ def add_force(self, thermodynamic_state: ThermodynamicState) -> None: add_force_in_separate_group(system, force) thermodynamic_state.system = system - def get_standard_state_correction( + def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState ) -> float: force = self._get_force() @@ -157,8 +160,9 @@ def _get_force(self): class HarmonicBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): def _get_force(self) -> openmm.Force: + spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintBondForce( - spring_constant=self.settings.spring_constant, + spring_constant=spring_constant, restrained_atom_index1=self.host_atoms[0], restrained_atom_index2=self.guest_atoms[0], controlling_parameter_name=self.controlling_parameter_name, @@ -167,9 +171,11 @@ def _get_force(self) -> openmm.Force: class FlatBottomBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): def _get_force(self) -> openmm.Force: + spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( - spring_constant=self.settings.spring_constant, - well_radius=self.settings.well_radius, + spring_constant=spring_constant, + well_radius=well_radius, restrained_atom_index1=self.host_atoms[0], restrained_atom_index2=self.guest_atoms[0], controlling_parameter_name=self.controlling_parameter_name, @@ -178,8 +184,9 @@ def _get_force(self) -> openmm.Force: class CentroidHarmonicRestraint(BaseRadialllySymmetricRestraintForce): def _get_force(self) -> openmm.Force: + spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintForce( - spring_constant=self.settings.spring_constant, + spring_constant=spring_constant, restrained_atom_index1=self.host_atoms, restrained_atom_index2=self.guest_atoms, controlling_parameter_name=self.controlling_parameter_name, @@ -188,9 +195,11 @@ def _get_force(self) -> openmm.Force: class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): def _get_force(self): + spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( - spring_constant=self.settings.spring_constant, - well_radius=self.settings.well_radius, + spring_constant=spring_constant, + well_radius=well_radius, restrained_atom_index1=self.host_atoms, restrained_atom_index2=self.guest_atoms, controlling_parameter_name=self.controlling_parameter_name, @@ -209,8 +218,6 @@ def _verify_inputs(self) -> None: def add_force(self, thermodynamic_state: ThermodynamicState) -> None: force = self._get_force() - force.addGlobalParameter(self.controlling_parameter_name, 1.0) - force.addBond(self.host_atoms + self.guest_atoms, []) force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system @@ -220,20 +227,64 @@ def add_force(self, thermodynamic_state: ThermodynamicState) -> None: def _get_force(self) -> openmm.Force: efunc = _EFUNC_METHOD( self.controlling_parameter_name, - self.settings.K_r, - self.geometry.r_aA0, - self.settings.K_thetaA, - self.geometry.theta_A0, - self.settings.K_thetaB, - self.geometry.theta_B0, - self.settings.K_phiA, - self.geometry.phi_A0, - self.settings.K_phiB, - self.geometry.phi_B0, - self.settings.K_phiC, - self.geometry.phi_C0, ) - return get_custom_compound_bond_force( + force = get_custom_compound_bond_force( n_particles=6, energy_function=efunc ) + + param_values = [] + + parameter_dict = { + 'K_r': self.settings.K_r, + 'r_aA0': self.geometry.r_aA0, + 'K_thetaA': self.settings.K_thetaA, + 'theta_A0': self.geometry.theta_A0, + 'K_thetaB': self.settings.K_thetaB, + 'theta_B0': self.geometry.theta_B0, + 'K_phiA': self.settings.K_phiA, + 'phi_A0': self.geometry.phi_A0, + 'K_phiB': self.settings.K_phiB, + 'phi_B0': self.geometry.phi_B0, + 'K_phiC': self.settings.K_phiC, + 'phi_C0': self.geometry.phi_C0, + } + for key, val in parameter_dict.items(): + param_values.append(to_openmm(val).value_in_unit_system(omm_unit.md_unit_system)) + force.addPerBondParameter(key) + + force.addGlobalParameter(self.controlling_parameter_name, 1.0) + force.addBond(self.host_atoms + self.guest_atoms, param_values) + return force + + def get_standard_state_correction( + self, thermodynamic_state: ThermodynamicState + ) -> float: + + StandardV = 1660.53928 * unit.angstroms**3 + kt = from_openmm(thermodynamic_state.kT) + + # distances + r_aA0 = self.geometry.r_aA0.to('nm') + sin_thetaA0 = np.sin(self.geometry.theta_A0.to('radians')) + sin_thetaB0 = np.sin(self.geometry.theta_B0.to('radians')) + + # restraint energies + K_r = self.settings.K_r.to('kilojoule_per_mole') + K_thetaA = self.settings.K_thetaA.to('kilojoule_per_mole') + k_thetaB = self.settings.K_thetaB.to('kilojoule_per_mole') + K_phiA = self.settings.K_phiA.to('kilojoule_per_mole') + K_phiB = self.settings.K_phiB.to('kilojoule_per_mole') + K_phiC = self.settings.K_phiC.to('kilojoule_per_mole') + + numerator1 = 8.0 * (np.pi**2) * StandardV + denum1 = (r_aA0**2) * sin_thetaA0 * sin_thetaB0 + numerator2 = np.sqrt(K_r * K_thetaA * K_thetaB * K_phiA * K_phiB * K_phiC) + denum2 = (2.0 * np.pi * kt)**3 + + dG = -kt * np.log((numerator1/denum1) * (numerator2/denum2)) + + return dG + + +# TODO - implement periodic torsion Boresch restraint From 2e2b52e38a44c636fb431c0544c12503de59e0cf Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 6 Dec 2024 16:35:00 +0000 Subject: [PATCH 063/163] Fix units --- openfe/protocols/openmm_utils/omm_restraints.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openfe/protocols/openmm_utils/omm_restraints.py b/openfe/protocols/openmm_utils/omm_restraints.py index d03b1f195..104b07a4a 100644 --- a/openfe/protocols/openmm_utils/omm_restraints.py +++ b/openfe/protocols/openmm_utils/omm_restraints.py @@ -261,7 +261,7 @@ def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState ) -> float: - StandardV = 1660.53928 * unit.angstroms**3 + StandardV = 1.66053928 * unit.nanometer**3 kt = from_openmm(thermodynamic_state.kT) # distances @@ -270,12 +270,12 @@ def get_standard_state_correction( sin_thetaB0 = np.sin(self.geometry.theta_B0.to('radians')) # restraint energies - K_r = self.settings.K_r.to('kilojoule_per_mole') - K_thetaA = self.settings.K_thetaA.to('kilojoule_per_mole') - k_thetaB = self.settings.K_thetaB.to('kilojoule_per_mole') - K_phiA = self.settings.K_phiA.to('kilojoule_per_mole') - K_phiB = self.settings.K_phiB.to('kilojoule_per_mole') - K_phiC = self.settings.K_phiC.to('kilojoule_per_mole') + K_r = self.settings.K_r.to('kilojoule_per_mole / nm ** 2') + K_thetaA = self.settings.K_thetaA.to('kilojoule_per_mole / radians ** 2') + k_thetaB = self.settings.K_thetaB.to('kilojoule_per_mole / radians ** 2') + K_phiA = self.settings.K_phiA.to('kilojoule_per_mole / radians ** 2') + K_phiB = self.settings.K_phiB.to('kilojoule_per_mole / radians ** 2') + K_phiC = self.settings.K_phiC.to('kilojoule_per_mole / radians ** 2') numerator1 = 8.0 * (np.pi**2) * StandardV denum1 = (r_aA0**2) * sin_thetaA0 * sin_thetaB0 From 4159e69c77f22f3703ef21aa30dc428c61e86444 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 9 Dec 2024 09:20:18 +0100 Subject: [PATCH 064/163] Adapt Lambda states --- openfe/protocols/openmm_septop/alchemy_copy.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/alchemy_copy.py b/openfe/protocols/openmm_septop/alchemy_copy.py index 5751950d8..b1efc7305 100644 --- a/openfe/protocols/openmm_septop/alchemy_copy.py +++ b/openfe/protocols/openmm_septop/alchemy_copy.py @@ -218,8 +218,10 @@ def lambda_validator(self, instance, parameter_value): raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) return float(parameter_value) - lambda_sterics = _LambdaParameter('lambda_sterics') - lambda_electrostatics = _LambdaParameter('lambda_electrostatics') + lambda_sterics = _LambdaParameter('lambda_sterics_ligandA') + lambda_sterics = _LambdaParameter('lambda_sterics_ligandB') + lambda_electrostatics = _LambdaParameter('lambda_electrostatics_ligandA') + lambda_electrostatics = _LambdaParameter('lambda_electrostatics_ligandB') lambda_bonds = _LambdaParameter('lambda_bonds') lambda_angles = _LambdaParameter('lambda_angles') lambda_torsions = _LambdaParameter('lambda_torsions') From 1ce8dba0997066377a831b2ec9f170949405567e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 9 Dec 2024 09:25:21 +0100 Subject: [PATCH 065/163] Add individual lambda restraints --- openfe/protocols/openmm_septop/alchemy_copy.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/alchemy_copy.py b/openfe/protocols/openmm_septop/alchemy_copy.py index b1efc7305..23db6d478 100644 --- a/openfe/protocols/openmm_septop/alchemy_copy.py +++ b/openfe/protocols/openmm_septop/alchemy_copy.py @@ -218,10 +218,12 @@ def lambda_validator(self, instance, parameter_value): raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) return float(parameter_value) - lambda_sterics = _LambdaParameter('lambda_sterics_ligandA') - lambda_sterics = _LambdaParameter('lambda_sterics_ligandB') - lambda_electrostatics = _LambdaParameter('lambda_electrostatics_ligandA') - lambda_electrostatics = _LambdaParameter('lambda_electrostatics_ligandB') + lambda_sterics_ligandA = _LambdaParameter('lambda_sterics_ligandA') + lambda_sterics_ligandB = _LambdaParameter('lambda_sterics_ligandB') + lambda_electrostatics_ligandA = _LambdaParameter('lambda_electrostatics_ligandA') + lambda_electrostatics_ligandB = _LambdaParameter('lambda_electrostatics_ligandB') + lambda_restraints_ligandA = _LambdaParameter('lambda_restraints_ligandA') + lambda_restraints_ligandB = _LambdaParameter('lambda_restraints_ligandB') lambda_bonds = _LambdaParameter('lambda_bonds') lambda_angles = _LambdaParameter('lambda_angles') lambda_torsions = _LambdaParameter('lambda_torsions') From 97f0285c0d6bc000363f8681cdc966e670228b93 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 9 Dec 2024 09:28:22 +0100 Subject: [PATCH 066/163] Small FIx --- openfe/protocols/openmm_septop/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index ccfc0d97f..addba2221 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -938,8 +938,8 @@ def _get_states( sampler_state.box_vectors = box sampler_states = [sampler_state for _ in cmp_states] - potentials = [state.getPotentialEnergy() for state in sampler_states] - print(potentials) + # potentials = [state.getPotentialEnergy() for state in sampler_states] + # print(potentials) return sampler_states, cmp_states From 51ebfac2673eedd3abbd71c7ea1bebf878119acf Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 9 Dec 2024 11:49:26 +0100 Subject: [PATCH 067/163] Fix restraints sign --- openfe/protocols/openmm_septop/base.py | 18 +++++++++--------- .../openmm_septop/equil_septop_method.py | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index addba2221..34746081e 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -47,7 +47,7 @@ import mdtraj as mdt from gufe import ( - settings, ChemicalSystem, SmallMoleculeComponent, + ChemicalSystem, SmallMoleculeComponent, ProteinComponent, SolventComponent ) from openfe.protocols.openmm_utils.omm_settings import ( @@ -57,7 +57,6 @@ BasePartialChargeSettings, ) from openfe.utils import log_system_probe -from openfe.protocols.openmm_rfe._rfe_utils.compute import get_openmm_platform from openfe.protocols.openmm_afe.equil_afe_settings import ( BaseSolvationSettings, @@ -77,10 +76,15 @@ from .femto_alchemy import apply_fep from .femto_restraints import select_ligand_idxs from .utils import serialize, deserialize -from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory, AlchemicalRegion, AlchemicalState +from openfe.protocols.openmm_septop.alchemy_copy import ( + AbsoluteAlchemicalFactory, + AlchemicalRegion, + AlchemicalState, +) logger = logging.getLogger(__name__) + class BaseSepTopSetupUnit(gufe.ProtocolUnit): """ Base class for the setup of ligand SepTop RBFE free energy transformations. @@ -218,8 +222,7 @@ def _pre_equilibrate( ) # Get the necessary number of steps - if settings[ - 'equil_simulation_settings'].equilibration_length_nvt is not None: + if settings['equil_simulation_settings'].equilibration_length_nvt is not None: equil_steps_nvt = settings_validation.get_simsteps( sim_length=settings[ 'equil_simulation_settings'].equilibration_length_nvt, @@ -406,8 +409,7 @@ def _assign_partial_charges( overwrite=False, method=partial_charge_settings.partial_charge_method, toolkit_backend=partial_charge_settings.off_toolkit_backend, - generate_n_conformers=partial_charge_settings - .number_of_conformers, + generate_n_conformers=partial_charge_settings.number_of_conformers, nagl_model=partial_charge_settings.nagl_model, ) @@ -604,7 +606,6 @@ def get_system( return omm_system, omm_topology, positions, system_modeller, comp_resids - def get_system_AB( self, solv_comp, system_modeller_A, smc_comps_AB, smc_off_B, settings, shared_basepath): # 5. Get system generator @@ -706,7 +707,6 @@ def run(self, dry=False, verbose=True, comp_resids_AB = comp_resids_A | { alchem_comps["stateB"][0]: np.array(diff_resids)} - # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") # equ_positions_A = self._pre_equilibrate( diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 0d2212e48..01c8398a0 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1408,8 +1408,8 @@ def _get_lambda_schedule( lambda_vdw_A = [1 - x for x in lambda_vdw_A] lambda_elec_B = [1 - x for x in lambda_elec_B] lambda_vdw_B = [1 - x for x in lambda_vdw_B] - lambda_restraints_A = [1 - x for x in lambda_restraints_A] - lambda_restraints_B = [1 - x for x in lambda_restraints_B] + # lambda_restraints_A = [1 - x for x in lambda_restraints_A] + # lambda_restraints_B = [1 - x for x in lambda_restraints_B] lambdas['lambda_electrostatics_ligandA'] = lambda_elec_A lambdas['lambda_sterics_ligandA'] = lambda_vdw_A lambdas['lambda_electrostatics_ligandB'] = lambda_elec_B From 76c5fcfe845250b527ab815cda89e204daedc206 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 9 Dec 2024 12:25:46 +0000 Subject: [PATCH 068/163] Fix correction return in kj/mole --- openfe/protocols/openmm_utils/omm_restraints.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/openfe/protocols/openmm_utils/omm_restraints.py b/openfe/protocols/openmm_utils/omm_restraints.py index 104b07a4a..915d51d3c 100644 --- a/openfe/protocols/openmm_utils/omm_restraints.py +++ b/openfe/protocols/openmm_utils/omm_restraints.py @@ -12,6 +12,7 @@ TODO ---- * Add relevant duecredit entries. +* Add Periodic Torsion Boresch class """ import abc from typing import Optional, Union, Callable @@ -26,7 +27,8 @@ FlatBottomRestraintBondForce, ) from openmmtools.states import GlobalParameterState, ThermodynamicState -from openff.units.openmm import to_openmm +from openff.units.openmm import to_openmm, from_openmm +from openff.units import unit from gufe.settings.models import SettingsBaseModel from openfe.protocols.openmm_utils.omm_forces import ( @@ -148,11 +150,13 @@ def add_force(self, thermodynamic_state: ThermodynamicState) -> None: def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState - ) -> float: + ) -> unit.Quantity: force = self._get_force() - return force.compute_standard_state_correction( + corr = force.compute_standard_state_correction( thermodynamic_state, volume="system" ) + dg = corr * thermodynamic_state.kT + return from_openmm(dg).to('kilojoule_per_mole') def _get_force(self): raise NotImplementedError("only implemented in child classes") @@ -194,7 +198,7 @@ def _get_force(self) -> openmm.Force: class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): - def _get_force(self): + def _get_force(self) -> openmm.Force: spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( @@ -259,7 +263,7 @@ def _get_force(self) -> openmm.Force: def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState - ) -> float: + ) -> unit.Quantity: StandardV = 1.66053928 * unit.nanometer**3 kt = from_openmm(thermodynamic_state.kT) @@ -285,6 +289,3 @@ def get_standard_state_correction( dG = -kt * np.log((numerator1/denum1) * (numerator2/denum2)) return dG - - -# TODO - implement periodic torsion Boresch restraint From e9cd918c60a9d3053f2459acb61b37cead9f2579 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 9 Dec 2024 12:57:04 +0000 Subject: [PATCH 069/163] Add more restraint API bits --- .../openmm_utils/restraints/__init__.py | 0 .../openmm_utils/restraints/geometry.py | 56 +++++++++++++++++++ .../{ => restraints}/omm_forces.py | 0 .../{ => restraints}/omm_restraints.py | 34 +++++------ 4 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 openfe/protocols/openmm_utils/restraints/__init__.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry.py rename openfe/protocols/openmm_utils/{ => restraints}/omm_forces.py (100%) rename openfe/protocols/openmm_utils/{ => restraints}/omm_restraints.py (90%) diff --git a/openfe/protocols/openmm_utils/restraints/__init__.py b/openfe/protocols/openmm_utils/restraints/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openfe/protocols/openmm_utils/restraints/geometry.py b/openfe/protocols/openmm_utils/restraints/geometry.py new file mode 100644 index 000000000..3d1f37a10 --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/geometry.py @@ -0,0 +1,56 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + + +class BaseRestraintGeometry(BaseModel, abc.ABC): + class Config: + arbitrary_types_allowed = True + + +class HostGuestRestraintGeometry(BaseRestraintGeometry): + """ + An ordered list of guest atoms to restrain. + + Note + ---- + The order matters! It will be used to define the underlying + force. + """ + guest_atoms: list[int] + """ + An ordered list of host atoms to restrain. + + Note + ---- + The order matters! It will be used to define the underlying + force. + """ + host_atoms: list[int] + + @validator("guest_atoms", "host_atoms") + def positive_idxs(cls, v): + if any([i < 0 for i in v]): + errmsg = "negative indices passed" + raise ValueError(errmsg) + return v + + +class BondDistanceRestraintGeoemtry(HostGuestRestraintGeometry): + @validator("host_atoms", "guest_atoms") + def single_atoms(cls, v): + if len(v) != 1: + errmsg = ( + "Host and guest atom lists must only include a single atom, " + f"got {len(v)} atoms." + ) + raise ValueError(errmsg) + return v diff --git a/openfe/protocols/openmm_utils/omm_forces.py b/openfe/protocols/openmm_utils/restraints/omm_forces.py similarity index 100% rename from openfe/protocols/openmm_utils/omm_forces.py rename to openfe/protocols/openmm_utils/restraints/omm_forces.py diff --git a/openfe/protocols/openmm_utils/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/omm_restraints.py similarity index 90% rename from openfe/protocols/openmm_utils/omm_restraints.py rename to openfe/protocols/openmm_utils/restraints/omm_restraints.py index 915d51d3c..0bfb6eb80 100644 --- a/openfe/protocols/openmm_utils/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/omm_restraints.py @@ -90,14 +90,10 @@ class BaseHostGuestRestraints(abc.ABC): def __init__( self, - host_atoms: list[int], - guest_atoms: list[int], restraint_settings: SettingsBaseModel, restraint_geometry: BaseRestraintGeometry, controlling_parameter_name: str = "lambda_restraints", ): - self.host_atoms = host_atoms - self.guest_atoms = guest_atoms self.settings = restraint_settings self.geometry = restraint_geometry self._verify_input() @@ -121,7 +117,7 @@ def _get_force(self): class SingleBondMixin: def _verify_input(self): - if len(self.host_atoms) != 1 or len(self.guest_atoms) != 1: + if len(self.geometry.host_atoms) != 1 or len(self.geometry.guest_atoms) != 1: errmsg = ( "host_atoms and guest_atoms must only include a single index " f"each, got {len(host_atoms)} and " @@ -148,7 +144,7 @@ def add_force(self, thermodynamic_state: ThermodynamicState) -> None: add_force_in_separate_group(system, force) thermodynamic_state.system = system - def get_standard_state_correction( + def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState ) -> unit.Quantity: force = self._get_force() @@ -164,48 +160,48 @@ def _get_force(self): class HarmonicBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): def _get_force(self) -> openmm.Force: - spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintBondForce( spring_constant=spring_constant, - restrained_atom_index1=self.host_atoms[0], - restrained_atom_index2=self.guest_atoms[0], + restrained_atom_index1=self.geometry.host_atoms[0], + restrained_atom_index2=self.geometry.guest_atoms[0], controlling_parameter_name=self.controlling_parameter_name, ) class FlatBottomBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): def _get_force(self) -> openmm.Force: - spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, - restrained_atom_index1=self.host_atoms[0], - restrained_atom_index2=self.guest_atoms[0], + restrained_atom_index1=self.geometry.host_atoms[0], + restrained_atom_index2=self.geometry.guest_atoms[0], controlling_parameter_name=self.controlling_parameter_name, ) class CentroidHarmonicRestraint(BaseRadialllySymmetricRestraintForce): def _get_force(self) -> openmm.Force: - spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintForce( spring_constant=spring_constant, - restrained_atom_index1=self.host_atoms, - restrained_atom_index2=self.guest_atoms, + restrained_atom_index1=self.geometry.host_atoms, + restrained_atom_index2=self.geometry.guest_atoms, controlling_parameter_name=self.controlling_parameter_name, ) class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): def _get_force(self) -> openmm.Force: - spring_constant = to_openmm(self.settings.sprint_constant).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, - restrained_atom_index1=self.host_atoms, - restrained_atom_index2=self.guest_atoms, + restrained_atom_index1=self.geometry.host_atoms, + restrained_atom_index2=self.geometry.guest_atoms, controlling_parameter_name=self.controlling_parameter_name, ) @@ -258,7 +254,7 @@ def _get_force(self) -> openmm.Force: force.addPerBondParameter(key) force.addGlobalParameter(self.controlling_parameter_name, 1.0) - force.addBond(self.host_atoms + self.guest_atoms, param_values) + force.addBond(self.geometry.host_atoms + self.geometry.guest_atoms, param_values) return force def get_standard_state_correction( From f1bbd8a440fd254f2b1eb0dfa17f1326e605a11e Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 9 Dec 2024 15:50:07 +0000 Subject: [PATCH 070/163] move some things around --- openfe/protocols/openmm_utils/restraints/omm_restraints.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/omm_restraints.py index 0bfb6eb80..599230ccc 100644 --- a/openfe/protocols/openmm_utils/restraints/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/omm_restraints.py @@ -5,7 +5,7 @@ Acknowledgements ---------------- -Many of the classes here are at least in part inspired, if not taken from +Many of the classes here are at least in part inspired from `Yank `_ and `OpenMMTools `_. @@ -39,10 +39,6 @@ ) -class BaseRestraintGeometry: - pass - - class RestraintParameterState(GlobalParameterState): """ Composable state to control `lambda_restraints` OpenMM Force parameters. From bd69a8be2b4caa024bc86d3be232fbc3031defb8 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 10 Dec 2024 14:20:47 +0100 Subject: [PATCH 071/163] More tests and fixes --- openfe/protocols/openmm_septop/base.py | 8 +- .../openmm_septop/equil_septop_method.py | 175 +++++++++------ .../openmm_septop/equil_septop_settings.py | 23 +- openfe/protocols/openmm_utils/omm_settings.py | 8 +- openfe/tests/conftest.py | 11 + .../protocols/test_openmm_septop_protocol.py | 207 +++++++++++++----- 6 files changed, 295 insertions(+), 137 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 34746081e..506ee0e93 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -27,7 +27,6 @@ import numpy as np import numpy.typing as npt import openmm -import mdtraj as md import simtk.unit as omm_units from openff.units import unit from openff.units.openmm import from_openmm, to_openmm, ensure_quantity @@ -36,7 +35,6 @@ from openmmtools.states import (SamplerState, ThermodynamicState, create_thermodynamic_state_protocol, ) -# from .utils import AlchemicalState from typing import Optional from openmm import app from openmm import unit as omm_unit @@ -1109,12 +1107,10 @@ 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( + rta_its, rta_min_its = settings_validation.convert_real_time_analysis_iterations( simulation_settings=simulation_settings, ) - et_target_err = \ - settings_validation.convert_target_error_from_kcal_per_mole_to_kT( + et_target_err = settings_validation.convert_target_error_from_kcal_per_mole_to_kT( thermo_settings.temperature, simulation_settings.early_termination_target_error, ) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 01c8398a0..dd272c8a0 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1,6 +1,7 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe -"""OpenMM Equilibrium SepTop RBFE Protocol --- :mod:`openfe.protocols.openmm_septop.equil_septop_method` +"""OpenMM Equilibrium SepTop RBFE Protocol --- + :mod:`openfe.protocols.openmm_septop.equil_septop_method` =============================================================================================================== This module implements the necessary methodology tooling to run a @@ -21,7 +22,10 @@ Acknowledgements ---------------- - +This Protocol is based on, and leverages components originating from +the SepTop implementation from the Mobleylab +(https://github.com/MobleyLab/SeparatedTopologies) as well as +femto (https://github.com/Psivant/femto). """ from __future__ import annotations @@ -56,7 +60,7 @@ MultiStateSimulationSettings, OpenMMEngineSettings, IntegratorSettings, MultiStateOutputSettings, OpenFFPartialChargeSettings, - SettingsBaseModel, RestraintsSettings, + SettingsBaseModel, SolventRestraintsSettings, ComplexRestraintsSettings ) from ..openmm_utils import system_validation, settings_validation from .base import BaseSepTopSetupUnit, BaseSepTopRunUnit @@ -69,6 +73,7 @@ ) from .femto_utils import assign_force_groups from openff.units.openmm import to_openmm +from rdkit import Chem due.cite(Doi("10.5281/zenodo.596622"), @@ -94,14 +99,47 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): omm_positions / omm_units.nanometers) unit_cell = omm_topology.getPeriodicBoxVectors() / omm_units.nanometers - print(unit_cell) unit_cell_length = np.array([i[inx] for inx, i in enumerate(unit_cell)]) - print(unit_cell_length) mdtraj_system = md.Trajectory(positions_in_mdtraj_format, mdtraj_topology, unitcell_lengths=unit_cell_length) return mdtraj_system +def _check_alchemical_charge_difference( + ligandA: SmallMoleculeComponent, + ligandB: SmallMoleculeComponent, +): + """ + Checks and returns the difference in formal charge between state A + and B. + + Raises + ------ + ValueError + * If a change in net charge is detected. + + Parameters + ---------- + ligandA: SmallMoleculeComponent + ligandB: SmallMoleculeComponent + """ + chg_A = Chem.rdmolops.GetFormalCharge( + ligandA.to_rdkit() + ) + chg_B = Chem.rdmolops.GetFormalCharge( + ligandB.to_rdkit() + ) + + difference = chg_A - chg_B + + if abs(difference) != 0: + errmsg = ( + f"A charge difference of {difference} is observed " + "between the end states. Unfortunately this protocol " + "currently does not support net charge changes.") + raise ValueError(errmsg) + + return class SepTopProtocolResult(gufe.ProtocolResult): """Dict-like container for the output of a SepTopProtocol @@ -129,14 +167,12 @@ def get_individual_estimates(self) -> dict[str, list[tuple[unit.Quantity, unit.Q solv_dGs = [] for pus in self.data['complex'].values(): - print(pus) complex_dGs.append(( pus[0].outputs['unit_estimate'], pus[0].outputs['unit_estimate_error'] )) for pus in self.data['solvent'].values(): - print(pus) solv_dGs.append(( pus[0].outputs['unit_estimate'], pus[0].outputs['unit_estimate_error'] @@ -457,18 +493,18 @@ def _default_settings(cls): integrator_settings=IntegratorSettings(), solvent_equil_simulation_settings=MDSimulationSettings( equilibration_length_nvt=0.1 * unit.nanosecond, - equilibration_length=0.2 * unit.nanosecond, + equilibration_length=0.1 * unit.nanosecond, production_length=0.5 * unit.nanosecond, ), solvent_equil_output_settings=MDOutputSettings( - equil_nvt_structure='equil_nvt_structure.pdb', + equil_nvt_structure=None, equil_npt_structure='equil_npt_structure.pdb', - production_trajectory_filename='production_equil.xtc', + production_trajectory_filename=None, log_output='equil_simulation.log', ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=19, - minimization_steps=10000, + minimization_steps=5000, equilibration_length=1.0 * unit.nanosecond, production_length=10.0 * unit.nanosecond, ), @@ -477,30 +513,29 @@ def _default_settings(cls): checkpoint_storage_filename='solvent_checkpoint.nc', ), complex_equil_simulation_settings=MDSimulationSettings( - equilibration_length_nvt=None, - equilibration_length=0.2 * unit.nanosecond, + equilibration_length_nvt=0.1 * unit.nanosecond, + equilibration_length=0.1 * unit.nanosecond, production_length=0.5 * unit.nanosecond, ), complex_equil_output_settings=MDOutputSettings( equil_nvt_structure=None, equil_npt_structure='equil_structure.pdb', - production_trajectory_filename='production_equil.xtc', + production_trajectory_filename=None, log_output='equil_simulation.log', ), complex_simulation_settings=MultiStateSimulationSettings( n_replicas=19, - equilibration_length=0.5 * unit.nanosecond, - production_length=2.0 * unit.nanosecond, + equilibration_length=1.0 * unit.nanosecond, + production_length=10.0 * unit.nanosecond, ), complex_output_settings=MultiStateOutputSettings( output_filename='complex.nc', checkpoint_storage_filename='complex_checkpoint.nc' ), - solvent_restraints_settings=RestraintsSettings( + solvent_restraints_settings=SolventRestraintsSettings( k_distance=1000 * unit.kilojoule_per_mole / unit.nanometer**2, - k_theta=None, ), - complex_restraints_settings=RestraintsSettings( + complex_restraints_settings=ComplexRestraintsSettings( k_distance=8368.0 * unit.kilojoule_per_mole / unit.nanometer**2 ), ) @@ -573,6 +608,7 @@ def _validate_alchemical_components( * If there are no or more than one alchemical components in state B. * If there are any alchemical components that are not SmallMoleculeComponents + * If a change in net charge between the alchemical components is detected. Notes ----- @@ -606,6 +642,11 @@ def _validate_alchemical_components( "are not currently supported") raise ValueError(errmsg) + # Raise an error if there is a change in netcharge + _check_alchemical_charge_difference( + alchemical_components['stateA'][0], + alchemical_components['stateB'][0]) + @staticmethod def _validate_lambda_schedule( lambda_settings: LambdaSettings, @@ -661,17 +702,22 @@ def _validate_lambda_schedule( f" number of lambda windows {len(lambda_vdw_ligandB)}") raise ValueError(errmsg) - # # Check if there are lambda windows with naked charges - # # Leaving this out for now till I've figured out how the lambda - # # scheduling works - # for inx, lam in enumerate(lambda_elec): - # if lam < 1 and lambda_vdw[inx] == 1: - # errmsg = ( - # "There are states along this lambda schedule " - # "where there are atoms with charges but no LJ " - # f"interactions: lambda {inx}: " - # f"elec {lam} vdW {lambda_vdw[inx]}") - # raise ValueError(errmsg) + # Check if there are lambda windows with naked charges + for inx, lam in enumerate(lambda_elec_ligandA): + if lam < 1 and lambda_vdw_ligandA[inx] == 1: + errmsg = ( + "There are states along this lambda schedule " + "where there are atoms with charges but no LJ " + f"interactions: Ligand A: lambda {inx}: " + f"elec {lam} vdW {lambda_vdw_ligandA[inx]}") + raise ValueError(errmsg) + if lambda_elec_ligandB[inx] < 1 and lambda_vdw_ligandB[inx] == 1: + errmsg = ( + "There are states along this lambda schedule " + "where there are atoms with charges but no LJ interactions" + f": Ligand B: lambda {inx}: elec {lambda_elec_ligandB[inx]}" + f" vdW {lambda_vdw_ligandB[inx]}") + raise ValueError(errmsg) def _create( self, @@ -1070,20 +1116,22 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ prot_settings = self._inputs['protocol'].settings - settings = {} - settings['forcefield_settings'] = prot_settings.solvent_forcefield_settings - settings['thermo_settings'] = prot_settings.thermo_settings - settings['charge_settings'] = prot_settings.partial_charge_settings - settings['solvation_settings'] = prot_settings.solvent_solvation_settings - settings['alchemical_settings'] = prot_settings.alchemical_settings - 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 - settings['restraint_settings'] = prot_settings.solvent_restraints_settings + settings = { + 'forcefield_settings': prot_settings.solvent_forcefield_settings, + 'thermo_settings': prot_settings.thermo_settings, + 'charge_settings': prot_settings.partial_charge_settings, + 'solvation_settings': prot_settings.solvent_solvation_settings, + 'alchemical_settings': prot_settings.alchemical_settings, + 'lambda_settings': prot_settings.lambda_settings, + 'engine_settings': prot_settings.solvent_engine_settings, + 'integrator_settings': prot_settings.integrator_settings, + 'equil_simulation_settings': + prot_settings.solvent_equil_simulation_settings, + 'equil_output_settings': + prot_settings.solvent_equil_output_settings, + 'simulation_settings': prot_settings.solvent_simulation_settings, + 'output_settings': prot_settings.solvent_output_settings, + 'restraint_settings': prot_settings.solvent_restraints_settings} settings_validation.validate_timestep( settings['forcefield_settings'].hydrogen_mass, @@ -1124,8 +1172,7 @@ def _update_positions( print(ligand_offset) # Offset the ligandB. - mdtraj_system_B.xyz[0][atom_indices_B, - :] += ligand_offset / omm_units.nanometers + mdtraj_system_B.xyz[0][atom_indices_B, :] += ligand_offset / omm_units.nanometers # Extract updated system positions. updated_positions_B = mdtraj_system_B.openmm_positions(0) @@ -1176,7 +1223,6 @@ def _add_restraints( return system - def _execute( self, ctx: gufe.Context, **kwargs, ) -> dict[str, Any]: @@ -1237,7 +1283,6 @@ def _get_components(self): # be returned as None return alchem_comps, solv_comp, None, small_mols - def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a complex transformation. @@ -1262,20 +1307,22 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ prot_settings = self._inputs['protocol'].settings - settings = {} - settings['forcefield_settings'] = prot_settings.solvent_forcefield_settings - settings['thermo_settings'] = prot_settings.thermo_settings - settings['charge_settings'] = prot_settings.partial_charge_settings - settings['solvation_settings'] = prot_settings.solvent_solvation_settings - settings['alchemical_settings'] = prot_settings.alchemical_settings - 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 - settings['restraint_settings'] = prot_settings.solvent_restraints_settings + settings = { + 'forcefield_settings': prot_settings.solvent_forcefield_settings, + 'thermo_settings': prot_settings.thermo_settings, + 'charge_settings': prot_settings.partial_charge_settings, + 'solvation_settings': prot_settings.solvent_solvation_settings, + 'alchemical_settings': prot_settings.alchemical_settings, + 'lambda_settings': prot_settings.lambda_settings, + 'engine_settings': prot_settings.solvent_engine_settings, + 'integrator_settings': prot_settings.integrator_settings, + 'equil_simulation_settings': + prot_settings.solvent_equil_simulation_settings, + 'equil_output_settings': + prot_settings.solvent_equil_output_settings, + 'simulation_settings': prot_settings.solvent_simulation_settings, + 'output_settings': prot_settings.solvent_output_settings, + 'restraint_settings': prot_settings.solvent_restraints_settings} settings_validation.validate_timestep( settings['forcefield_settings'].hydrogen_mass, @@ -1308,6 +1355,7 @@ def _get_lambda_schedule( return lambdas + class SepTopComplexRunUnit(BaseSepTopRunUnit): """ Protocol Unit for the solvent phase of an relative SepTop free energy @@ -1339,7 +1387,6 @@ def _get_components(self): return alchem_comps, solv_comp, prot_comp, small_mols - def _handle_settings(self) -> dict[str, SettingsBaseModel]: """ Extract the relevant settings for a complex transformation. @@ -1417,4 +1464,4 @@ def _get_lambda_schedule( lambdas['lambda_restraints_ligandA'] = lambda_restraints_A lambdas['lambda_restraints_ligandB'] = lambda_restraints_B - return lambdas \ No newline at end of file + return lambdas diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 379a2c065..7de637ab3 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -29,8 +29,6 @@ from openff.models.types import FloatQuantity import numpy as np from pydantic.v1 import validator -from typing import Optional -import openmm.unit as omm_unit class AlchemicalSettings(SettingsBaseModel): @@ -45,7 +43,22 @@ class RestraintsSettings(SettingsBaseModel): Settings for the restraints. """ k_distance: FloatQuantity['kJ/(mol*nanometers**2)'] = 1000 * unit.kilojoule_per_mole / unit.nanometer**2 - k_theta: Optional[FloatQuantity['kJ/(mol*rad**2)']] = 83.68 * unit.kilojoule_per_mole / unit.radians ** 2 + + +class SolventRestraintsSettings(RestraintsSettings): + """ + Settings for the harmonic restraint in the solvent + """ + + +class ComplexRestraintsSettings(RestraintsSettings): + """ + Settings for the Boresch restraints in the complex + """ + class Config: + arbitrary_types_allowed = True + + k_theta: FloatQuantity['kJ/(mol*rad**2)'] = 83.68 * unit.kilojoule_per_mole / unit.radians ** 2 class LambdaSettings(SettingsBaseModel): @@ -244,11 +257,11 @@ def must_be_positive(cls, v): including the partial charge assignment method, and the number of conformers used to generate the partial charges. """ - solvent_restraints_settings: RestraintsSettings + solvent_restraints_settings: SolventRestraintsSettings """ Settings for the harmonic restraint in the solvent """ - complex_restraints_settings: RestraintsSettings + complex_restraints_settings: ComplexRestraintsSettings """ Settings for the Boresch restraints in the complex """ diff --git a/openfe/protocols/openmm_utils/omm_settings.py b/openfe/protocols/openmm_utils/omm_settings.py index d52db9b41..bfeb3e014 100644 --- a/openfe/protocols/openmm_utils/omm_settings.py +++ b/openfe/protocols/openmm_utils/omm_settings.py @@ -625,16 +625,16 @@ class Config: arbitrary_types_allowed = True # reporter settings - production_trajectory_filename = 'simulation.xtc' + production_trajectory_filename: Optional[str] = 'simulation.xtc' """Path to the storage file for analysis. Default 'simulation.xtc'.""" trajectory_write_interval: FloatQuantity['picosecond'] = 20 * unit.picosecond """ Frequency to write the xtc file. Default 5000 * unit.timestep. """ - preminimized_structure = 'system.pdb' + preminimized_structure: Optional[str] = 'system.pdb' """Path to the pdb file of the full pre-minimized system. Default 'system.pdb'.""" - minimized_structure = 'minimized.pdb' + minimized_structure: Optional[str] = 'minimized.pdb' """Path to the pdb file of the system after minimization. Only the specified atom subset is saved. Default 'minimized.pdb'.""" equil_nvt_structure: Optional[str] = 'equil_nvt.pdb' @@ -643,7 +643,7 @@ class Config: equil_npt_structure: Optional[str] = 'equil_npt.pdb' """Path to the pdb file of the system after NPT equilibration. Only the specified atom subset is saved. Default 'equil_npt.pdb'.""" - log_output = 'simulation.log' + log_output: Optional[str] = 'simulation.log' """ Filename for writing the log of the MD simulation, including timesteps, energies, density, etc. diff --git a/openfe/tests/conftest.py b/openfe/tests/conftest.py index 7fbbe98f5..02ab91c64 100644 --- a/openfe/tests/conftest.py +++ b/openfe/tests/conftest.py @@ -192,6 +192,17 @@ def benzene_modifications(): return files +@pytest.fixture(scope='session') +def charged_benzene_modifications(): + files = {} + with importlib.resources.files('openfe.tests.data.openmm_rfe') as d: + fn = str(d / 'charged_benzenes.sdf') + supp = Chem.SDMolSupplier(str(fn), removeHs=False) + for rdmol in supp: + files[rdmol.GetProp('_Name')] = SmallMoleculeComponent(rdmol) + return files + + @pytest.fixture(scope='session') def bace_ligands(): files = {} diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index ad0d3547d..fd596101d 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -20,8 +20,10 @@ SepTopSolventSetupUnit, SepTopComplexSetupUnit, SepTopProtocol, - femto_restraints + femto_restraints, ) +from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference + from openfe.protocols.openmm_utils import system_validation from openfe.protocols.openmm_utils.charge_generation import ( @@ -106,6 +108,37 @@ def test_validate_lambda_schedule_nwindows(val, default_settings): ) +@pytest.mark.parametrize('val', [ + {'elec': [1.0, 0.5], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_nakedcharge(val, default_settings): + default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandA = val[ + 'restraints'] + default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandB = val[ + 'restraints'] + n_replicas = 2 + default_settings.complex_simulation_settings.n_replicas = n_replicas + default_settings.solvent_simulation_settings.n_replicas = n_replicas + errmsg = ( + "There are states along this lambda schedule " + "where there are atoms with charges but no LJ " + "interactions: Ligand A: l") + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.solvent_simulation_settings, + ) + + def test_create_default_protocol(default_settings): # this is roughly how it should be created protocol = SepTopProtocol( @@ -124,6 +157,79 @@ def test_serialize_protocol(default_settings): assert protocol == ret +def test_create_independent_repeat_ids( + benzene_complex_system, toluene_complex_system, +): + # if we create two dags each with 3 repeats, they should give 6 repeat_ids + # this allows multiple DAGs in flight for one Transformation that don't clash on gather + settings = SepTopProtocol.default_settings() + # Default protocol is 1 repeat, change to 3 repeats + settings.protocol_repeats = 3 + protocol = SepTopProtocol( + settings=settings, + ) + + dag1 = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + dag2 = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + # print([u for u in dag1.protocol_units]) + repeat_ids = set() + for u in dag1.protocol_units: + repeat_ids.add(u.inputs['repeat_id']) + for u in dag2.protocol_units: + repeat_ids.add(u.inputs['repeat_id']) + + # There are 4 units per repeat per DAG: 4 * 3 * 2 = 24 + assert len(repeat_ids) == 24 + + +def test_check_alchem_charge_diff(charged_benzene_modifications): + errmsg = "A charge difference of 1" + with pytest.raises(ValueError, match=errmsg): + _check_alchemical_charge_difference( + charged_benzene_modifications["benzene"], + charged_benzene_modifications["benzoic_acid"], + ) + + +def test_charge_error_create( + charged_benzene_modifications, T4_protein_component, +): + # if we create two dags each with 3 repeats, they should give 6 repeat_ids + # this allows multiple DAGs in flight for one Transformation that don't clash on gather + settings = SepTopProtocol.default_settings() + # Default protocol is 1 repeat, change to 3 repeats + settings.protocol_repeats = 3 + protocol = SepTopProtocol( + settings=settings, + ) + stateA = ChemicalSystem({ + 'benzene': charged_benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent() + }) + + stateB = ChemicalSystem({ + 'benzoic': charged_benzene_modifications['benzoic_acid'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + errmsg = "A charge difference of 1" + with pytest.raises(ValueError, match=errmsg): + protocol.create( + stateA=stateA, + stateB=stateB, + mapping=None, + ) + + def test_validate_complex_endstates_protcomp_stateA( benzene_modifications, T4_protein_component, ): @@ -285,63 +391,48 @@ def test_validate_alchem_nonsmc( with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): SepTopProtocol._validate_alchemical_components(alchem_comps) - -# def test_create_boresch_restraint( -# bace_ligands, bace_protein_component -# ): -# Would have to create the OpenMM system to get the positions -# receptor_ref_idxs_1 = (492, 510, 3822) -# ligand_1_idxs = (6053, 6048, 6055) # -# force_A = femto_restraints.create_boresch_restraint( -# receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] -# ligand_1_idxs, -# positions, -# settings["restraint_settings"], +# def test_setup(bace_ligands, bace_protein_component, tmpdir): +# # check system parametrisation works even if confgen fails +# s = SepTopProtocol.default_settings() +# s.protocol_repeats = 1 +# s.solvent_equil_simulation_settings.minimization_steps = 10 +# s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond +# s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond +# s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond +# s.solvent_solvation_settings.box_shape = 'dodecahedron' +# s.solvent_solvation_settings.solvent_padding = 1.5 * unit.nanometer +# +# protocol = SepTopProtocol( +# settings=s, # ) - - -def test_setup(bace_ligands, bace_protein_component, tmpdir): - # check system parametrisation works even if confgen fails - s = SepTopProtocol.default_settings() - s.protocol_repeats = 1 - s.solvent_equil_simulation_settings.minimization_steps = 10 - s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond - s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond - s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond - s.solvent_solvation_settings.box_shape = 'dodecahedron' - s.solvent_solvation_settings.solvent_padding = 1.5 * unit.nanometer - - protocol = SepTopProtocol( - settings=s, - ) - - stateA = ChemicalSystem({ - 'lig_02': bace_ligands['lig_02'], - 'protein': bace_protein_component, - 'solvent': SolventComponent(), - }) - - stateB = ChemicalSystem({ - 'lig_03': bace_ligands['lig_03'], - 'protein': bace_protein_component, - 'solvent': SolventComponent(), - }) - - # Create DAG from protocol, get the vacuum and solvent units - # and eventually dry run the first vacuum unit - dag = protocol.create( - stateA=stateA, - stateB=stateB, - mapping=None, - ) - prot_units = list(dag.protocol_units) - solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopSolventSetupUnit)] - # solv_setup_unit = [u for u in prot_units - # if isinstance(u, SepTopComplexSetupUnit)] - - # with tmpdir.as_cwd(): - solv_setup_unit[0].run() - assert 4==5 +# +# stateA = ChemicalSystem({ +# 'lig_02': bace_ligands['lig_02'], +# 'protein': bace_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'lig_03': bace_ligands['lig_03'], +# 'protein': bace_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# # Create DAG from protocol, get the vacuum and solvent units +# # and eventually dry run the first vacuum unit +# dag = protocol.create( +# stateA=stateA, +# stateB=stateB, +# mapping=None, +# ) +# prot_units = list(dag.protocol_units) +# solv_setup_unit = [u for u in prot_units +# if isinstance(u, SepTopSolventSetupUnit)] +# # solv_setup_unit = [u for u in prot_units +# # if isinstance(u, SepTopComplexSetupUnit)] +# +# # with tmpdir.as_cwd(): +# solv_setup_unit[0].run() +# assert 4==5 From b4c06ba720619283c2717532f3e799a6fd0603e0 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 10 Dec 2024 16:50:08 +0100 Subject: [PATCH 072/163] More updates --- .../protocols/openmm_md/plain_md_methods.py | 43 +++--- openfe/protocols/openmm_septop/base.py | 49 +++++-- .../openmm_septop/equil_septop_method.py | 136 ++++++++++++++---- .../protocols/test_openmm_septop_protocol.py | 88 ++++++------ 4 files changed, 206 insertions(+), 110 deletions(-) diff --git a/openfe/protocols/openmm_md/plain_md_methods.py b/openfe/protocols/openmm_md/plain_md_methods.py index 1ac147714..1001660fe 100644 --- a/openfe/protocols/openmm_md/plain_md_methods.py +++ b/openfe/protocols/openmm_md/plain_md_methods.py @@ -432,26 +432,29 @@ def _run_MD(simulation: openmm.app.Simulation, mc_steps=1, ) - simulation.reporters.append(XTCReporter( - file=str(shared_basepath / output_settings.production_trajectory_filename), - reportInterval=write_interval, - atomSubset=selection_indices)) - simulation.reporters.append(openmm.app.CheckpointReporter( - file=str(shared_basepath / output_settings.checkpoint_storage_filename), - reportInterval=checkpoint_interval)) - simulation.reporters.append(openmm.app.StateDataReporter( - str(shared_basepath / output_settings.log_output), - checkpoint_interval, - step=True, - time=True, - potentialEnergy=True, - kineticEnergy=True, - totalEnergy=True, - temperature=True, - volume=True, - density=True, - speed=True, - )) + if output_settings.production_trajectory_filename: + simulation.reporters.append(XTCReporter( + file=str(shared_basepath / output_settings.production_trajectory_filename), + reportInterval=write_interval, + atomSubset=selection_indices)) + if output_settings.checkpoint_storage_filename: + simulation.reporters.append(openmm.app.CheckpointReporter( + file=str(shared_basepath / output_settings.checkpoint_storage_filename), + reportInterval=checkpoint_interval)) + if output_settings.log_output: + simulation.reporters.append(openmm.app.StateDataReporter( + str(shared_basepath / output_settings.log_output), + checkpoint_interval, + step=True, + time=True, + potentialEnergy=True, + kineticEnergy=True, + totalEnergy=True, + temperature=True, + volume=True, + density=True, + speed=True, + )) t0 = time.time() simulation.step(prod_steps) t1 = time.time() diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 506ee0e93..d1a709627 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -130,16 +130,17 @@ def __init__(self, *, ) @staticmethod - def _get_alchemical_indices(omm_top: openmm.Topology, - comp_resids: dict[Component, npt.NDArray], - alchem_comps: dict[str, list[Component]] - ) -> list[int]: + def _get_alchemical_indices( + omm_top: openmm.app.Topology, + comp_resids: dict[Component, npt.NDArray], + alchem_comps: dict[str, list[Component]] + ) -> list[int]: """ Get a list of atom indices for all the alchemical species Parameters ---------- - omm_top : openmm.Topology + omm_top : openmm.app.Topology Topology of OpenMM System. comp_resids : dict[Component, npt.NDArray] A dictionary of residues for each component in the System. @@ -350,7 +351,8 @@ def _handle_settings(self): ... def _get_system_generator( - self, settings: dict[str, SettingsBaseModel], + self, + settings: dict[str, SettingsBaseModel], solvent_comp: Optional[SolventComponent] ) -> SystemGenerator: """ @@ -517,7 +519,10 @@ def _get_omm_objects( return topology, system, positions @staticmethod - def _get_atom_indices(omm_topology, comp_resids): + def _get_atom_indices( + omm_topology: app.Topology, + comp_resids: dict[Component, npt.NDArray], + ): comp_atomids = {} for key, values in comp_resids.items(): atom_indices = [] @@ -529,9 +534,13 @@ def _get_atom_indices(omm_topology, comp_resids): @staticmethod def _update_positions( - omm_topology_A, omm_topology_B, positions_A, positions_B, - atom_indices_A, atom_indices_B, - ) -> npt.NDArray: + omm_topology_A: openmm.app.Topology, + omm_topology_B: openmm.app.Topology, + positions_A: simtk.unit.Quantity, + positions_B: simtk.unit.Quantity, + atom_indices_A: Optional[list], + atom_indices_B: Optional[list], + ) -> simtk.unit.Quantity: """ Get new positions for the stateB after equilibration. @@ -544,7 +553,10 @@ def _update_positions( ... @staticmethod - def _set_positions(off_topology, positions): + def _set_positions( + off_topology: OFFMolecule.Topology, + positions: unit.Quantity, + ) -> OFFMolecule.Topology: off_topology.clear_positions() off_topology.set_positions(positions) return off_topology @@ -552,11 +564,11 @@ def _set_positions(off_topology, positions): @staticmethod def _add_restraints( system: openmm.System, - positions: np.array, - topology: Optional[openmm.Topology], + positions: simtk.unit.Quantity, + topology: Optional[openmm.app.Topology], ligand_1: Optional[OFFMolecule.Topology], ligand_2: Optional[OFFMolecule.Topology], - settings: Optional, + settings: Optional[dict[str, SettingsBaseModel]], ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology ligand_1_idxs: tuple[int, int, int], # indices from the full topology @@ -573,7 +585,14 @@ def _add_restraints( """ ... - def get_smc_comps(self, alchem_comps, smc_comps): + @staticmethod + def get_smc_comps( + alchem_comps: dict[str, list[Component]], + smc_comps: dict[SmallMoleculeComponent,OFFMolecule], + ) -> tuple[dict[SmallMoleculeComponent,OFFMolecule], + dict[SmallMoleculeComponent,OFFMolecule], + dict[SmallMoleculeComponent,OFFMolecule], + dict[SmallMoleculeComponent,OFFMolecule]]: # 6. Get smcs for the different states and the common smcs smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index dd272c8a0..b4b8e01b4 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -36,16 +36,18 @@ import gufe import openmm import openmm.unit +import simtk +import simtk.unit as omm_units from gufe.components import Component import itertools import numpy as np import numpy.typing as npt from openff.units import unit +from openff.toolkit.topology import Molecule as OFFMolecule from openmmtools import multistate import mdtraj as md from typing import Optional, Union from typing import Any, Iterable -import simtk.unit as omm_units import uuid from gufe import ( @@ -92,11 +94,21 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): """ - Get an mdtraj object from an OpenMM topology and positions + Get an mdtraj object from an OpenMM topology and positions. + + Parameters + ---------- + omm_topology: openmm.app.Topology + The OpenMM topology + omm_positions: simtk.unit.Quantity + The OpenMM positions + + Returns + ------- + mdtraj_system: md.Trajectory """ mdtraj_topology = md.Topology.from_openmm(omm_topology) - positions_in_mdtraj_format = np.array( - omm_positions / omm_units.nanometers) + positions_in_mdtraj_format = omm_positions.value_in_unit(omm_units.nanometers) unit_cell = omm_topology.getPeriodicBoxVectors() / omm_units.nanometers unit_cell_length = np.array([i[inx] for inx, i in enumerate(unit_cell)]) @@ -105,6 +117,7 @@ def _get_mdtraj_from_openmm(omm_topology, omm_positions): unitcell_lengths=unit_cell_length) return mdtraj_system + def _check_alchemical_charge_difference( ligandA: SmallMoleculeComponent, ligandB: SmallMoleculeComponent, @@ -141,6 +154,7 @@ def _check_alchemical_charge_difference( return + class SepTopProtocolResult(gufe.ProtocolResult): """Dict-like container for the output of a SepTopProtocol """ @@ -818,37 +832,27 @@ def _gather( ) -> dict[str, dict[str, Any]]: # result units will have a repeat_id and generation # first group according to repeat_id - print("Gathering results test1") unsorted_solvent_repeats_setup = defaultdict(list) unsorted_solvent_repeats_run = defaultdict(list) unsorted_complex_repeats_setup = defaultdict(list) unsorted_complex_repeats_run = defaultdict(list) for d in protocol_dag_results: - print(d) pu: gufe.ProtocolUnitResult for pu in d.protocol_unit_results: - print(pu) if not pu.ok(): - print('PU not ok') continue if pu.outputs['simtype'] == 'solvent': - print('Getting solvent pus') if 'Run' in pu.name: - print('Run') unsorted_solvent_repeats_run[ pu.outputs['repeat_id']].append(pu) elif 'Setup' in pu.name: - print('Setup') unsorted_solvent_repeats_setup[ pu.outputs['repeat_id']].append(pu) else: - print('Getting complex pus') if 'Run' in pu.name: - print('Run') unsorted_complex_repeats_run[ pu.outputs['repeat_id']].append(pu) elif 'Setup' in pu.name: - print('Setup') unsorted_complex_repeats_setup[ pu.outputs['repeat_id']].append(pu) @@ -865,7 +869,6 @@ def _gather( repeats['complex_setup'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) for k, v in unsorted_complex_repeats_run.items(): repeats['complex'][str(k)] = sorted(v, key=lambda x: x.outputs['generation']) - print(repeats) return repeats @@ -952,7 +955,27 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: def _update_positions( omm_topology_A, omm_topology_B, positions_A, positions_B, atom_indices_A, atom_indices_B, - ) -> npt.NDArray: + ) -> simtk.unit.Quantity: + """ + Aligns the protein from complex B onto the protein from complex A and + updates the positions of complex B. + + Parameters + ---------- + omm_topology_A: openmm.app.Topology + OpenMM topology from complex A + omm_topology_B: openmm.app.Topology + OpenMM topology from complex B + positions_A: simtk.unit.Quantity + Positions of the system in state A + positions_B: simtk.unit.Quantity + Positions of the system in state B + + Returns + ------- + updated_positions_B: simtk.unit.Quantity + Updated positions of the complex B + """ mdtraj_complex_A = _get_mdtraj_from_openmm(omm_topology_A, positions_A) mdtraj_complex_B = _get_mdtraj_from_openmm(omm_topology_B, positions_B) mdtraj_complex_B.superpose(mdtraj_complex_A, @@ -966,16 +989,47 @@ def _update_positions( @staticmethod def _add_restraints( system: openmm.System, - positions: np.array, - topology: openmm.Topology, - ligand_1, - ligand_2, - settings, + positions: simtk.unit.Quantity, + topology: Optional[openmm.app.Topology], + ligand_1: Optional[OFFMolecule.Topology], + ligand_2: Optional[OFFMolecule.Topology], + settings: dict[str, SettingsBaseModel], ligand_1_ref_idxs: tuple[int, int, int], ligand_2_ref_idxs: tuple[int, int, int], ligand_1_idxs: tuple[int, int, int], ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: + """ + Adds Boresch restraints to the system. + + Parameters + ---------- + system: openmm.System + The OpenMM system where the restraints will be applied to. + positions: simtk.unit.Quantity + The positions of the OpenMM system + topology: openmm.app.Topology + The OpenMM topology of the system + ligand_1: OFFMolecule.Topology + The topology of the OpenFF Molecule of ligand A + ligand_2: OFFMolecule.Topology + The topology of the OpenFF Molecule of ligand B + settings: dict[str, SettingsBaseModel] + The settings dict + ligand_1_ref_idxs: tuple[int, int, int] + indices from the ligand A topology + ligand_2_ref_idxs: tuple[int, int, int] + indices from the ligand B topology + ligand_1_idxs: tuple[int, int, int] + indices from the ligand A in the full topology + ligand_1_idxs: tuple[int, int, int] + indices from the ligand B in the full topology + + Returns + ------- + system: openmm.System + The OpenMM system with the added restraints forces + """ # Get mdtraj object for system traj = _get_mdtraj_from_openmm(topology, positions) @@ -1003,9 +1057,7 @@ def _add_restraints( # Convert restraint units to openmm k_distance = to_openmm(settings["restraint_settings"].k_distance) - print(k_distance) k_theta = to_openmm(settings["restraint_settings"].k_theta) - print(k_theta) force_A = create_boresch_restraint( receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] @@ -1145,7 +1197,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: def _update_positions( omm_topology_A, omm_topology_B, positions_A, positions_B, atom_indices_A, atom_indices_B, - ) -> npt.NDArray: + ) -> simtk.unit.Quantity: # Offset ligand B from ligand A in the solvent equ_pos_ligandA = positions_A[ @@ -1169,7 +1221,6 @@ def _update_positions( ligand_offset = equ_pos_ligandA.mean(0) - equ_pos_ligandB.mean(0) ligand_offset[0] += ligand_distance - print(ligand_offset) # Offset the ligandB. mdtraj_system_B.xyz[0][atom_indices_B, :] += ligand_offset / omm_units.nanometers @@ -1192,13 +1243,36 @@ def _add_restraints( ligand_1_idxs: tuple[int, int, int], ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: - """Apply a distance restraints between the ligands. + """ + Apply the distance restraint between the ligands. - Args: - system: The OpenMM system to add the restraints to. - topology: The full topology of the complex phase. - ligand_1_ref_idx: The reference index of the first ligand. - ligand_2_ref_idx: The reference index of the second ligand. + Parameters + ---------- + system: openmm.System + The OpenMM system where the restraints will be applied to. + positions: simtk.unit.Quantity + The positions of the OpenMM system + topology: openmm.app.Topology + The OpenMM topology of the system + ligand_1: OFFMolecule.Topology + The topology of the OpenFF Molecule of ligand A + ligand_2: OFFMolecule.Topology + The topology of the OpenFF Molecule of ligand B + settings: dict[str, SettingsBaseModel] + The settings dict + ligand_1_ref_idxs: tuple[int, int, int] + indices from the ligand A topology + ligand_2_ref_idxs: tuple[int, int, int] + indices from the ligand B topology + ligand_1_idxs: tuple[int, int, int] + indices from the ligand A in the full topology + ligand_1_idxs: tuple[int, int, int] + indices from the ligand B in the full topology + + Returns + ------- + system: openmm.System + The OpenMM system with the added restraints forces """ coords = positions diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index fd596101d..78782ed08 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -391,48 +391,48 @@ def test_validate_alchem_nonsmc( with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): SepTopProtocol._validate_alchemical_components(alchem_comps) -# -# def test_setup(bace_ligands, bace_protein_component, tmpdir): -# # check system parametrisation works even if confgen fails -# s = SepTopProtocol.default_settings() -# s.protocol_repeats = 1 -# s.solvent_equil_simulation_settings.minimization_steps = 10 -# s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond -# s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond -# s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond -# s.solvent_solvation_settings.box_shape = 'dodecahedron' -# s.solvent_solvation_settings.solvent_padding = 1.5 * unit.nanometer -# -# protocol = SepTopProtocol( -# settings=s, -# ) -# -# stateA = ChemicalSystem({ -# 'lig_02': bace_ligands['lig_02'], -# 'protein': bace_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'lig_03': bace_ligands['lig_03'], -# 'protein': bace_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# # Create DAG from protocol, get the vacuum and solvent units -# # and eventually dry run the first vacuum unit -# dag = protocol.create( -# stateA=stateA, -# stateB=stateB, -# mapping=None, -# ) -# prot_units = list(dag.protocol_units) -# solv_setup_unit = [u for u in prot_units -# if isinstance(u, SepTopSolventSetupUnit)] -# # solv_setup_unit = [u for u in prot_units -# # if isinstance(u, SepTopComplexSetupUnit)] -# -# # with tmpdir.as_cwd(): -# solv_setup_unit[0].run() -# assert 4==5 + +def test_setup(bace_ligands, bace_protein_component, tmpdir): + # check system parametrisation works even if confgen fails + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_equil_simulation_settings.minimization_steps = 100 + s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond + s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond + s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond + s.solvent_solvation_settings.box_shape = 'dodecahedron' + s.solvent_solvation_settings.solvent_padding = 1.8 * unit.nanometer + + protocol = SepTopProtocol( + settings=s, + ) + + stateA = ChemicalSystem({ + 'lig_02': bace_ligands['lig_02'], + 'protein': bace_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'lig_03': bace_ligands['lig_03'], + 'protein': bace_protein_component, + 'solvent': SolventComponent(), + }) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first vacuum unit + dag = protocol.create( + stateA=stateA, + stateB=stateB, + mapping=None, + ) + prot_units = list(dag.protocol_units) + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + # solv_setup_unit = [u for u in prot_units + # if isinstance(u, SepTopComplexSetupUnit)] + + # with tmpdir.as_cwd(): + solv_setup_unit[0].run() + assert 4==5 From e6dae2f4180f2f87320351c84ea71a18896a1155 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 11 Dec 2024 09:42:50 +0100 Subject: [PATCH 073/163] Update compute location --- openfe/protocols/openmm_septop/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index d1a709627..dd8a98b37 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -63,7 +63,7 @@ ThermoSettings, OpenFFPartialChargeSettings, ) from openfe.protocols.openmm_septop.equil_septop_settings import SepTopSettings -from openfe.protocols.openmm_rfe._rfe_utils import compute +from openfe.protocols.openmm_utils import omm_compute from openfe.protocols.openmm_md.plain_md_methods import PlainMDProtocolUnit from ..openmm_utils import ( settings_validation, system_creation, From 782de903d0dff4ac3ea56d92cc676073b1989b75 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 11 Dec 2024 09:44:57 +0100 Subject: [PATCH 074/163] Small fix --- openfe/protocols/openmm_septop/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index dd8a98b37..9fd3f85d7 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -203,7 +203,7 @@ def _pre_equilibrate( Equilibrated system positions """ # Prep the simulation object - platform = compute.get_openmm_platform( + platform = omm_compute.get_openmm_platform( settings['engine_settings'].compute_platform ) @@ -1040,7 +1040,7 @@ def _get_ctx_caches( sampler_context_cache : openmmtools.cache.ContextCache The sampler state context cache. """ - platform = compute.get_openmm_platform( + platform = omm_compute.get_openmm_platform( engine_settings.compute_platform, ) From 14ae69f11e4a7fdcfec22de5ab76f68bef106a2e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 11 Dec 2024 10:19:04 +0100 Subject: [PATCH 075/163] Adding some more docstrings --- openfe/protocols/openmm_septop/base.py | 77 ++++++++++++++++--- .../protocols/test_openmm_septop_protocol.py | 1 - 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 9fd3f85d7..5e1e1dba0 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -557,6 +557,9 @@ def _set_positions( off_topology: OFFMolecule.Topology, positions: unit.Quantity, ) -> OFFMolecule.Topology: + """ + Updates the positions of an OFFMolecule.Topology + """ off_topology.clear_positions() off_topology.set_positions(positions) return off_topology @@ -606,7 +609,33 @@ def get_smc_comps( return smc_comps_A, smc_comps_B, smc_comps_AB, smc_off_B def get_system( - self, solv_comp, prot_comp, smc_comp, settings): + self, + solv_comp: SolventComponent, + prot_comp: ProteinComponent, + smc_comp: dict[SmallMoleculeComponent,OFFMolecule], + settings: dict[str, SettingsBaseModel], + ): + """ + Creates an OpenMM system, topology, positions, modeller and also + residue IDs of the different components + + Parameters + ---------- + solv_comp: SolventComponent + prot_comp: Optional[ProteinComponent] + smc_comp: dict[SmallMoleculeComponent,OFFMolecule] + settings: dict[str, SettingsBaseModel] + A dictionary of settings object for the unit. + + Returns + ------- + omm_system: app.System + omm_topology: app.Topology + positions: simtk.unit.Quantity + system_modeller: app.Modeller + comp_resids: dict[Component, npt.NDArray] + A dictionary of residues for each component in the System. + """ # 5. Get system generator system_generator = self._get_system_generator(settings, solv_comp) @@ -624,7 +653,34 @@ def get_system( return omm_system, omm_topology, positions, system_modeller, comp_resids def get_system_AB( - self, solv_comp, system_modeller_A, smc_comps_AB, smc_off_B, settings, shared_basepath): + self, + solv_comp: SolventComponent, + system_modeller_A: app.Modeller, + smc_comps_AB: dict[SmallMoleculeComponent,OFFMolecule], + smc_off_B: dict[SmallMoleculeComponent,OFFMolecule], + settings: dict[str, SettingsBaseModel], + shared_basepath: pathlib.Path, + ): + """ + Creates an OpenMM system, topology, positions, and modeller. + + Parameters + ---------- + solv_comp: SolventComponent + system_modeller_A: app.Modeller + smc_comps_AB: dict[SmallMoleculeComponent,OFFMolecule] + smc_off_B: dict[SmallMoleculeComponent,OFFMolecule] + settings: dict[str, SettingsBaseModel] + A dictionary of settings object for the unit. + shared_basepath: pathlib.Path + + Returns + ------- + omm_system_AB: app.System + omm_topology_AB: app.Topology + positions_AB: simtk.unit.Quantity + system_modeller_AB: app.Modeller + """ # 5. Get system generator system_generator = self._get_system_generator(settings, solv_comp) @@ -726,14 +782,13 @@ def run(self, dry=False, verbose=True, # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") - # equ_positions_A = self._pre_equilibrate( - # omm_system_A, omm_topology_A, positions_A, settings, dry - # ) - # equ_positions_B = self._pre_equilibrate( - # omm_system_B, omm_topology_B, positions_B, settings, dry - # ) - equ_positions_A = positions_A - equ_positions_B = positions_B + equ_positions_A = self._pre_equilibrate( + omm_system_A, omm_topology_A, positions_A, settings, dry + ) + equ_positions_B = self._pre_equilibrate( + omm_system_B, omm_topology_B, positions_B, settings, dry + ) + simtk.openmm.app.pdbfile.PDBFile.writeFile( omm_topology_A, equ_positions_A, open(self.shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( @@ -819,7 +874,7 @@ def run(self, dry=False, verbose=True, open(topology_file, 'w')) - # Here we could also apply REST + # ToDo: also apply REST system_outfile = self.shared_basepath / "system.xml.bz2" diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 78782ed08..6136c4b32 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -434,5 +434,4 @@ def test_setup(bace_ligands, bace_protein_component, tmpdir): # with tmpdir.as_cwd(): solv_setup_unit[0].run() - assert 4==5 From ac452e9df96f2c8ae23536be702e6939b1e98769 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Wed, 11 Dec 2024 11:52:04 +0000 Subject: [PATCH 076/163] Some changes --- .../openmm_utils/restraints/geometry.py | 54 +++++++++++++++---- .../openmm_utils/restraints/omm_restraints.py | 4 +- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry.py b/openfe/protocols/openmm_utils/restraints/geometry.py index 3d1f37a10..14e1cd289 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry.py +++ b/openfe/protocols/openmm_utils/restraints/geometry.py @@ -10,6 +10,10 @@ import abc from pydantic.v1 import BaseModel, validator +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.lib.distances import calc_bonds + class BaseRestraintGeometry(BaseModel, abc.ABC): class Config: @@ -25,6 +29,7 @@ class HostGuestRestraintGeometry(BaseRestraintGeometry): The order matters! It will be used to define the underlying force. """ + guest_atoms: list[int] """ An ordered list of host atoms to restrain. @@ -44,13 +49,42 @@ def positive_idxs(cls, v): return v -class BondDistanceRestraintGeoemtry(HostGuestRestraintGeometry): - @validator("host_atoms", "guest_atoms") - def single_atoms(cls, v): - if len(v) != 1: - errmsg = ( - "Host and guest atom lists must only include a single atom, " - f"got {len(v)} atoms." - ) - raise ValueError(errmsg) - return v +class CentroidDistanceMixin: + def get_distance(self, topology, coordinates) -> unit.Quantity: + u = mda.Universe(topology, coordinates) + ag1 = u.atoms[self.host_atoms] + ag2 = u.atoms[self.guest_atoms] + bond = calc_bonds( + ag1.center_of_mass(), ag2.center_of_mass(), u.atoms.dimensions + ) + # convert to float so we avoid having a np.float64 + return float(bond) * unit.angstrom + + +def _check_single_atoms(value): + if len(value) != 1: + errmsg = ( + "Host and guest atom lists must only include a single atom, " + f"got {len(value)} atoms." + ) + raise ValueError(errmsg) + return value + + +class BondDistanceMixin: + def get_distance(self, topology, coordinates) -> unit.Quantity: + u = mda.Universe(topology, coordinates) + at1 = u.atoms[self.host_atoms[0]] + at2 = u.atoms[self.guest_atoms[0]] + bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) + # convert to float so we avoid having a np.float64 value + return float(bond) * unit.angstrom + + +class CentroidDistanceRestraintGeometry(HostGuestRestraintGeometry, CentroidDistanceMixin): + pass + + +class BondDistanceRestraintGeoemtry(HostGuestRestraintGeometry, BondDistanceMixin): + _check_host_atoms: classmethod = validator("host_atoms", allow_reuse=True)(_check_single_atoms) + _check_guest_atoms: classmethod = validator("guest_atoms", allow_reuse=True)(_check_single_atoms) diff --git a/openfe/protocols/openmm_utils/restraints/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/omm_restraints.py index 599230ccc..ab5f4e821 100644 --- a/openfe/protocols/openmm_utils/restraints/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/omm_restraints.py @@ -168,7 +168,7 @@ def _get_force(self) -> openmm.Force: class FlatBottomBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): def _get_force(self) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) - well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm(self.geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, @@ -192,7 +192,7 @@ def _get_force(self) -> openmm.Force: class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): def _get_force(self) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) - well_radius = to_openmm(self.settings.well_radius).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm(self.geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, From a19c86cae5100520cef62a87de7a6dcd44cb5050 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 12:03:52 +0000 Subject: [PATCH 077/163] refactor restraints --- .../openmm_utils/restraints/geometry.py | 90 ----- .../restraints/geometry/__init__.py | 0 .../openmm_utils/restraints/geometry/base.py | 50 +++ .../restraints/geometry/boresch.py | 66 ++++ .../restraints/geometry/flatbottom.py | 90 +++++ .../restraints/geometry/harmonic.py | 94 +++++ .../openmm_utils/restraints/geometry/utils.py | 360 ++++++++++++++++++ .../restraints/openmm/__init__.py | 0 .../restraints/{ => openmm}/omm_forces.py | 0 .../restraints/{ => openmm}/omm_restraints.py | 0 .../openmm_utils/restraints/search.py | 360 ++++++++++++++++++ 11 files changed, 1020 insertions(+), 90 deletions(-) delete mode 100644 openfe/protocols/openmm_utils/restraints/geometry.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry/__init__.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry/base.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry/boresch.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry/harmonic.py create mode 100644 openfe/protocols/openmm_utils/restraints/geometry/utils.py create mode 100644 openfe/protocols/openmm_utils/restraints/openmm/__init__.py rename openfe/protocols/openmm_utils/restraints/{ => openmm}/omm_forces.py (100%) rename openfe/protocols/openmm_utils/restraints/{ => openmm}/omm_restraints.py (100%) create mode 100644 openfe/protocols/openmm_utils/restraints/search.py diff --git a/openfe/protocols/openmm_utils/restraints/geometry.py b/openfe/protocols/openmm_utils/restraints/geometry.py deleted file mode 100644 index 14e1cd289..000000000 --- a/openfe/protocols/openmm_utils/restraints/geometry.py +++ /dev/null @@ -1,90 +0,0 @@ -# This code is part of OpenFE and is licensed under the MIT license. -# For details, see https://github.com/OpenFreeEnergy/openfe -""" -Restraint Geometry classes - -TODO ----- -* Add relevant duecredit entries. -""" -import abc -from pydantic.v1 import BaseModel, validator - -from openff.units import unit -import MDAnalysis as mda -from MDAnalysis.lib.distances import calc_bonds - - -class BaseRestraintGeometry(BaseModel, abc.ABC): - class Config: - arbitrary_types_allowed = True - - -class HostGuestRestraintGeometry(BaseRestraintGeometry): - """ - An ordered list of guest atoms to restrain. - - Note - ---- - The order matters! It will be used to define the underlying - force. - """ - - guest_atoms: list[int] - """ - An ordered list of host atoms to restrain. - - Note - ---- - The order matters! It will be used to define the underlying - force. - """ - host_atoms: list[int] - - @validator("guest_atoms", "host_atoms") - def positive_idxs(cls, v): - if any([i < 0 for i in v]): - errmsg = "negative indices passed" - raise ValueError(errmsg) - return v - - -class CentroidDistanceMixin: - def get_distance(self, topology, coordinates) -> unit.Quantity: - u = mda.Universe(topology, coordinates) - ag1 = u.atoms[self.host_atoms] - ag2 = u.atoms[self.guest_atoms] - bond = calc_bonds( - ag1.center_of_mass(), ag2.center_of_mass(), u.atoms.dimensions - ) - # convert to float so we avoid having a np.float64 - return float(bond) * unit.angstrom - - -def _check_single_atoms(value): - if len(value) != 1: - errmsg = ( - "Host and guest atom lists must only include a single atom, " - f"got {len(value)} atoms." - ) - raise ValueError(errmsg) - return value - - -class BondDistanceMixin: - def get_distance(self, topology, coordinates) -> unit.Quantity: - u = mda.Universe(topology, coordinates) - at1 = u.atoms[self.host_atoms[0]] - at2 = u.atoms[self.guest_atoms[0]] - bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) - # convert to float so we avoid having a np.float64 value - return float(bond) * unit.angstrom - - -class CentroidDistanceRestraintGeometry(HostGuestRestraintGeometry, CentroidDistanceMixin): - pass - - -class BondDistanceRestraintGeoemtry(HostGuestRestraintGeometry, BondDistanceMixin): - _check_host_atoms: classmethod = validator("host_atoms", allow_reuse=True)(_check_single_atoms) - _check_guest_atoms: classmethod = validator("guest_atoms", allow_reuse=True)(_check_single_atoms) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/__init__.py b/openfe/protocols/openmm_utils/restraints/geometry/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openfe/protocols/openmm_utils/restraints/geometry/base.py b/openfe/protocols/openmm_utils/restraints/geometry/base.py new file mode 100644 index 000000000..21a714cde --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/geometry/base.py @@ -0,0 +1,50 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.lib.distances import calc_bonds, calc_angles + + +class BaseRestraintGeometry(BaseModel, abc.ABC): + class Config: + arbitrary_types_allowed = True + + +class HostGuestRestraintGeometry(BaseRestraintGeometry): + """ + An ordered list of guest atoms to restrain. + + Note + ---- + The order matters! It will be used to define the underlying + force. + """ + + guest_atoms: list[int] + """ + An ordered list of host atoms to restrain. + + Note + ---- + The order matters! It will be used to define the underlying + force. + """ + host_atoms: list[int] + + @validator("guest_atoms", "host_atoms") + def positive_idxs(cls, v): + if any([i < 0 for i in v]): + errmsg = "negative indices passed" + raise ValueError(errmsg) + return v + diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py new file mode 100644 index 000000000..822382b9c --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -0,0 +1,66 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.lib.distances import calc_bonds, calc_angles + +from .base import HostGuestRestraintGeometry + + +class BoreschRestraintGeometry(HostGuestRestraintGeometry): + """ + A class that defines the restraint geometry for a Boresch restraint. + + The restraint is defined by the following: + + H0 G2 + - - + - - + H1 - - H2 -- G0 - - G1 + + Where HX represents the X index of ``host_atoms`` and GX + the X index of ``guest_atoms``. + """ + def get_bond_distance(self, topology, coordinates) -> unit.Quantity: + u = mda.Universe(topology, coordinates) + at1 = u.atoms[host_atoms[2]] + at2 = u.atoms[guest_atoms[0]] + bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) + # convert to float so we avoid having a np.float64 + return float(bond) * unit.angstrom + + def get_angles(self, topology, coordinates) -> unit.Quantity: + u = mda.Universe(topology, coordinates) + at1 = u.atoms[host_atoms[1]] + at2 = u.atoms[host_atoms[2]] + at3 = u.atoms[guest_atoms[0]] + at4 = u.atoms[guest_atoms[1]] + + angleA = calc_angles(at1.position, at2.position, at3.position, u.atoms.dimensions) + angleB = calc_angles(at2.position, at3.position, at4.position, u.atoms.dimensions) + return angleA, angleB + + def get_dihedrals(self, topology, coordinates) -> unit.Quantity: + u = mda.Universe(topology, coordinates) + at1 = u.atoms[host_atoms[0]] + at2 = u.atoms[host_atoms[1]] + at3 = u.atoms[host_atoms[2]] + at4 = u.atoms[guest_atoms[0]] + at5 = u.atoms[guest_atoms[1]] + at6 = u.atoms[guest_atoms[2]] + + dihA = calc_dihedrals(at1.position, at2.position, at3.position, at4.position, u.atoms.dimensions) + dihB = calc_dihedrals(at2.position, at3.position, at4.position, at5.position, u.atoms.dimensions) + dihC = calc_dihedrals(at3.position, at4.position, at5.position, at6.position, u.atoms.dimensions) + + return dihA, dihB, dihC diff --git a/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py b/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py new file mode 100644 index 000000000..c7e987736 --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py @@ -0,0 +1,90 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + +import numpy as np +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.analysis.base import AnalysisBase +from MDAnalysis.lib.distances import calc_bonds, calc_angles + +from .harmonic import ( + DistanceRestraintGeometry, + _get_selection, +) + + +class FlatBottomDistanceGeometry(DistanceRestraintGeometry): + """ + A geometry class for a flat bottom distance restraint between two groups + of atoms. + """ + + well_radius: FloatQuantity["nanometer"] + + +class COMDistanceAnalysis(AnalysisBase): + """ + Get a timeseries of COM distances between two AtomGroups + + Parameters + ---------- + group1 : MDAnalysis.AtomGroup + Atoms defining the first centroid. + group2 : MDANalysis.AtomGroup + Atoms defining the second centroid. + """ + + _analysis_algorithm_is_parallelizable = False + + def __init__(self, host_atoms, guest_atoms, search_distance, **kwargs): + super().__init__(host_atoms.universe.trajectory, **kwargs) + + self.ag1 = group1 + self.ag2 = group2 + + def _prepare(self): + self.results.distances = np.zeros(self.n_frames) + + def _single_frame(self): + com_dist = calc_bonds( + self.ag1.center_of_mass(), + self.ag2.center_of_mass(), + box=self.ag1.universe.dimensions, + ) + self.results.distances[self._frame_index] = com_dist + + def _conclude(self): + pass + + +def get_flatbottom_distance_restraint( + topology: Union[str, openmm.app.Topology], + trajectory: pathlib.Path, + topology_format: Optional[str] = None, + host_atoms: Optional[list[int]] = None, + guest_atoms: Optional[list[int]] = None, + host_selection: Optional[str] = None, + guest_selection: Optional[str] = None, + padding: unit.Quantity = 0.5 * unit.nanometer, +) -> FlatBottomDistanceGeometry: + u = mda.Universe(topology, trajectory, topology_format=topology_format) + + guest_ag = _get_selection(u, guest_atoms, guest_selection) + host_ag = _get_selection(u, host_atoms, host_selection) + + com_dists = COMDistanceAnalysis(guest_ag, host_ag) + com_dists.run() + + well_radius = com_dists.results.distances.max() * unit.angstrom + padding + return FlatBottomDistanceGeometry( + guest_atoms=guest_atoms, host_atoms=host_atoms, well_radius=well_radius + ) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py b/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py new file mode 100644 index 000000000..36e7a61a7 --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py @@ -0,0 +1,94 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.lib.distances import calc_bonds, calc_angles +from rdkit import Chem + +from .base import HostGuestRestraintGeometry +from .utils import _get_central_atom_idx + + +class DistanceRestraintGeometry(HostGuestRestraintGeometry): + """ + A geometry class for a distance restraint between two groups of atoms. + """ + + def get_distance(self, topology, coordinates) -> unit.Quantity: + u = mda.Universe(topology, coordinates) + ag1 = u.atoms[self.host_atoms] + ag2 = u.atoms[self.guest_atoms] + bond = calc_bonds( + ag1.center_of_mass(), ag2.center_of_mass(), box=u.atoms.dimensions + ) + # convert to float so we avoid having a np.float64 + return float(bond) * unit.angstrom + + +def _get_selection(universe, atom_list, selection): + if atom_list is None: + if selection is None: + raise ValueError( + "one of either the atom lists or selections must be defined" + ) + + ag = universe.select_atoms(selection) + else: + ag = universe.atoms[atom_list] + + return ag + + +def get_distance_restraint( + topology: Union[str, openmm.app.Topology], + trajectory: pathlib.Path, + topology_format: Optional[str] = None, + host_atoms: Optional[list[int]] = None, + guest_atoms: Optional[list[int]] = None, + host_selection: Optional[str] = None, + guest_selection: Optional[str] = None, +) -> DistanceRestraintGeometry: + u = mda.Universe(topology, trajectory, topology_format=topology_format) + + guest_ag = _get_selection(u, guest_atoms, guest_selection) + host_ag = _get_selection(u, host_atoms, host_selection) + + return DistanceRestraintGeometry(guest_atoms=guest_atoms, host_atoms=host_atoms) + + +def get_molecule_centers_restraint( + topology: Union[str, openmm.app.Topology], + trajectory: pathlib.Path, + molA_rdmol: Chem.Mol, + molB_rdmol: Chem.Mol, + molA_idxs: list[int], + molB_idxs: list[int], + topology_format: Optional[str] = None, +): + # We assume that the mol idxs are ordered + centerA = molA_idxs[_get_central_atom_idx(molA_rdmol)] + centerB = molB_idxs[_get_central_atom_idx(molB_rdmol)] + + u = mda.Universe(topology, trajectory, topology_format=topology_format) + guest_ag = _get_selection( + u, + [centerA], + None, + ) + guest_ag = _get_selection( + u, + [centerB], + None, + ) + + return DistsanceRestraintGeometry(guest_atoms=guest_atoms, host_atoms=host_atoms) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py new file mode 100644 index 000000000..6b3d94eb7 --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -0,0 +1,360 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Search methods for generating Geometry objects + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + +from openff.toolkit import Molecule as OFFMol +from openff.units import unit +import networkx as nx +import MDAnalysis as mda +from MDAnalysis.analysis.base import AnalysisBase +from MDAnalysis.lib.distances import calc_bonds, calc_angles + + +def _get_aromatic_atom_idxs(rdmol) -> list[int]: + """ + Helper method to get aromatic atoms idxs + in a RDKit Molecule + + Parameters + ---------- + rdmol : ??? + RDKit Molecule + + Returns + ------- + list[int] + A list of the aromatic atom idxs + """ + idxs = [ + at.GetIdx() for at in rdmol.GetAtoms() + if at.GetIsAromatic() + ] + return idxs + + +def _get_heavy_atom_idxs(rdmol) -> list[int]: + """ + Get idxs of heavy atoms in an RDKit Molecule + + Parameters + ---------- + rmdol : ??? + + Returns + ------- + list[int] + A list of heavy atom idxs + """ + idxs = [ + at.GetIdx() for at in rdmol.GetAtoms() + if at.GetAtomicNum() > 1 + ] + return idxs + + +def _get_central_atom_idx(rdmol) -> int: + offmol = OFFMol(rdmol, allow_undefined_stereo=True) + # We take the zero-th entry if there are multiple center + # atoms (e.g. equal likelihood centers) + center = nx.center(offmol.to_networkx())[0] + return center + + +def _sort_by_distance_from_target(rdmol, target_idx: int, atom_idxs: list[int]) -> list[int]: + """ + Sort a list of atoms by their distance from a target atom. + + Parameters + ---------- + target_idx : int + The idx of the target atom. + atom_idxs : list[int] + The idx values of the atoms to sort. + rdmol : ??? + RDKit Molecule the atoms belong to + + Returns + ------- + list[int] + The input atom idxs sorted by their distance from the target atom. + """ + distances = [] + + conformer = rdmol.GetConformer() + # Get the target atom position + target_pos = conformer.GetAtomPosition(target_idx) + + for idx in atom_idxs: + pos = conformer.GetAtomPosition(idx) + distances.append(((target_pos - pos).Length(), idx)) + + return [i[1] for i in sorted(distances)] + + +def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): + angles = [] + + # Get the base atom and its neighbors + at1 = rdmol.GetAtomWithIdx(atom_idx) + at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] + + # We loop at2 and at3 through the sorted atom_pool in order to get + # a list of angles in the branch that are sorted by how close the atoms + # are from the central atom + for at2 in atom_pool: + if at2 in at1_neighbors: + at2_neighbors = [ + at.GetIdx() + for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() + ] + for at3 in atom_pool: + if at3 != atom_idx and at3 in at2_neighbors: + angles.append((atom_idx, at2, at3)) + return angles + + +def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: + """ + Get a list of ligand anchor atoms (e.g. l1, l2, and l3 of an orientational restraint). + + Parameters + ---------- + rdmol : ??? + Molecule object for the ligand to apply a restraint to. + + Returns + ------- + angles : list[tuple[int, int, int]] + A list of ligand atom triples denoting the possible l1, l2, and l3 + restraint atoms. Ordered by likelihood of restraint-ability. + """ + # Find the central atom + center = _get_central_atom_idx(rdmol) + + # Get a pool of potential anchor atoms looking for aromatic atoms + anchor_pool = _get_aromatic_atoms(rdmol) + + # If there are not enough aromatic atoms, then default to heavy atoms + if len(anchor_pool) < 3: + anchor_pool = _get_heavy_atoms(rdmol) + + # Raise an error if we have less than 3 anchors + if len(anchor_pool) < 3: + errmsg = f"Too few potential ligand anchor atoms, {len(anchor_pool)}" + raise ValueError(errmsg) + + # Sort the pool of anchor atoms by their distance from the central atom + sorted_anchor_pool = _sort_by_distance_from_target(rdmol, center, anchor_pool) + + # Get a list of ligand anchor angle atoms + angles = [] + for atom in sorted_anchor_pool: + angles.extend( + _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) + ) + + +def get_host_anchors(positions, topology, exclude_resids: list[int], lig_anchor_idx: int, selection: str): + """ + Get a list of host anchor atomss sorted by their distance from a ligand anchor atom. + + Parameters + ---------- + positions : openmm.unit.Quantity + Positions of the input system + topology : openmm.app.Topology + OpenMM Topology for input system + exclude_resids : list[int] + List of residue numbers to exclude from host selection + lig_anchor_idx : int + The index of the l1 ligand anchor. + selection : str + Selection string for the host atoms. + """ + # Create an mdtraj trajectory to manipulate + # First fetch the box vectors and pass them as lengths and angles + vectors = from_openmm(topology.getPeriodicBoxVectors()) + a, b, c, alpha, beta, gamma = mdt.utils.box_vectors_to_lengths_and_angles(vectors[0].m, vectors[1].m, vectors[2].m) + + traj = mdt.Trajectory( + positions[np.newaxis, ...], + mdt.Topology.from_openmm(topology) + ) + + # Get all the potential protein atoms matching the selection + host_sel = traj.topology.select(selection) + + # Get residues to exclude from the selection + exclude_sel = np.array([ + at.index for at in + chain(*[traj.topology.residue(i).atoms for i in exclude_resids]) + ]) + + # Remove exclusion + anchors = host_sel[np.isin(host_sel, exclude_sel, invert=True)] + + # Compute distanecs from ligand l1 anchor atom + pairs = np.vstack((anchors, np.array([lig_anchor_idx for _ in range(len(anchors))]))).T + + distances = mdt.compute_distances(traj, pairs, periodic=True) + + return np.array([pairs[i][0] for i in np.argsort(distances[0])]) + + +def is_collinear(positions, atoms, threshold=0.9): + """ + Check whether any sequential vectors in a sequence of atoms are collinear. + + Parameters + ---------- + positions : openmm.unit.Quantity + System positions. + atoms : list[int] + The indices of the atoms to test. + threshold : float + Atoms are not collinear if their sequential vector separation dot + products are less than ``threshold``. Default 0.9. + + Returns + ------- + result : bool + Returns True if any sequential pair of vectors is collinear; False otherwise. + + Notes + ----- + Originally from Yank, with modifications from Separated Topologies + """ + results = False + for i in range(len(atoms) - 2): + v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] + v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] + normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) + result = result or (np.abs(normalized_inner_product) > threshold) + return result + + +def check_angle(angle, force_constant=83.68): + """ + Check whether the chosen angle is less than 10 kT from 0 or 180 + + Parameters + ---------- + angle : float + The angle to check in degrees. + force_constant : float + Force constant of the angle. + + Note + ---- + We assume the temperature to be 298.15 Kelvin. + """ + # TODO: convert this to unit.Quantity so we don't end up with + # conversion errors + RT = 8.31445985 * 0.001 * 298.15 + # check if angle is <10kT from 0 or 180 + check1 = 0.5 * force_constant * np.power((angle - 0.0) / 180.0 * np.pi, 2) + check2 = 0.5 * force_constant * np.power((angle - 180.0) / 180.0 * np.pi, 2) + ang_check_1 = check1 / RT + ang_check_2 = check2 / RT + if ang_check_1 < 10.0 or ang_check_2 < 10.0: + return False + return True + + + + +class FindHostAtoms(AnalysisBase): + """ + Class filter host atoms based on their distance + from a set of guest atoms. + + Parameters + ---------- + host_atoms : MDAnalysis.AtomGroup + Initial selection of host atoms to filter from. + guest_atoms : MDANalysis.AtomGroup + Selection of guest atoms to search around. + search_distance: unit.Quantity + Distance to filter atoms within. + """ + _analysis_algorithm_is_parallelizable = False + + def __init__(self, host_atoms, guest_atoms, search_distance, **kwargs): + super().__init__(host_atoms.universe.trajectory, **kwargs) + + self.host_ag = host_atoms + self.guest_ag = guest_atoms + self.cutoff = search_distance.to('angstrom').m + + def _prepare(self): + self.results.host_idxs = set() + + def _single_frame(self): + pairs = capped_distance( + reference=self.host_ag.positions, + configuration=self.guest_ag.positions, + max_cutoff=self.cutoff, + min_cutoff=None + box=self.guest_ag.universe.dimensions, + return_distances=False) + + host_idxs = [self.guest_ag.atoms[p].index for p in pairs[:, 1]] + self.results.host_idxs.update(set(host_idxs)) + + def _conclude(self): + pass + + +def find_host_atoms(topology, trajectory, host_selection, guest_selection, cutoff) -> mda.AtomGroup: + """ + Get an AtomGroup of the host atoms based on their distances from the guest atoms. + """ + u = mda.Universe(topology, trajectory) + + def _get_selection(selection): + """ + If it's a str, call select_atoms, if not a list of atom idxs + """ + if isinstance(selection, str): + ag = u.select_atoms(host_selection) + else: + ag = u.atoms[host_ag] + return ag + + host_ag = _get_selection(host_selection) + guest_ag = _get_selection(guest_selection) + + finder = FindHostAtoms(host_ag, guest_ag, cutoff) + finder.run() + + return u.atoms[list(finder.results.host_idxs)] + +def get_molecule_center_idx(atomgroup): + offmol = Molecule(atomgroup.convert_to("RDKIT"), allow_undefined_stereo=True) + # Check if the molecule is whole, otherwise throw an error. + nx = offmol.to_networkx() + + +def get_distance_restraint(topology, trajectory, host_atoms, guest_atoms, host_selection, guest_selection): + u = mda.Universe(topology, trajectory) + + if guest_atoms is None: + if guest_selection is None: + raise ValueError("one of guest_atoms or guest_selections must be defined") + guest_ag = u.select_atoms(guest_selection) + else: + + + if host_atoms is None: + if host_selection is None: + raise ValueError("one of host_atoms or host_selection must be defined") + + host_ag = u.select_atoms(host_selection) diff --git a/openfe/protocols/openmm_utils/restraints/openmm/__init__.py b/openfe/protocols/openmm_utils/restraints/openmm/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openfe/protocols/openmm_utils/restraints/omm_forces.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py similarity index 100% rename from openfe/protocols/openmm_utils/restraints/omm_forces.py rename to openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py diff --git a/openfe/protocols/openmm_utils/restraints/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py similarity index 100% rename from openfe/protocols/openmm_utils/restraints/omm_restraints.py rename to openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py diff --git a/openfe/protocols/openmm_utils/restraints/search.py b/openfe/protocols/openmm_utils/restraints/search.py new file mode 100644 index 000000000..6b3d94eb7 --- /dev/null +++ b/openfe/protocols/openmm_utils/restraints/search.py @@ -0,0 +1,360 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Search methods for generating Geometry objects + +TODO +---- +* Add relevant duecredit entries. +""" +import abc +from pydantic.v1 import BaseModel, validator + +from openff.toolkit import Molecule as OFFMol +from openff.units import unit +import networkx as nx +import MDAnalysis as mda +from MDAnalysis.analysis.base import AnalysisBase +from MDAnalysis.lib.distances import calc_bonds, calc_angles + + +def _get_aromatic_atom_idxs(rdmol) -> list[int]: + """ + Helper method to get aromatic atoms idxs + in a RDKit Molecule + + Parameters + ---------- + rdmol : ??? + RDKit Molecule + + Returns + ------- + list[int] + A list of the aromatic atom idxs + """ + idxs = [ + at.GetIdx() for at in rdmol.GetAtoms() + if at.GetIsAromatic() + ] + return idxs + + +def _get_heavy_atom_idxs(rdmol) -> list[int]: + """ + Get idxs of heavy atoms in an RDKit Molecule + + Parameters + ---------- + rmdol : ??? + + Returns + ------- + list[int] + A list of heavy atom idxs + """ + idxs = [ + at.GetIdx() for at in rdmol.GetAtoms() + if at.GetAtomicNum() > 1 + ] + return idxs + + +def _get_central_atom_idx(rdmol) -> int: + offmol = OFFMol(rdmol, allow_undefined_stereo=True) + # We take the zero-th entry if there are multiple center + # atoms (e.g. equal likelihood centers) + center = nx.center(offmol.to_networkx())[0] + return center + + +def _sort_by_distance_from_target(rdmol, target_idx: int, atom_idxs: list[int]) -> list[int]: + """ + Sort a list of atoms by their distance from a target atom. + + Parameters + ---------- + target_idx : int + The idx of the target atom. + atom_idxs : list[int] + The idx values of the atoms to sort. + rdmol : ??? + RDKit Molecule the atoms belong to + + Returns + ------- + list[int] + The input atom idxs sorted by their distance from the target atom. + """ + distances = [] + + conformer = rdmol.GetConformer() + # Get the target atom position + target_pos = conformer.GetAtomPosition(target_idx) + + for idx in atom_idxs: + pos = conformer.GetAtomPosition(idx) + distances.append(((target_pos - pos).Length(), idx)) + + return [i[1] for i in sorted(distances)] + + +def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): + angles = [] + + # Get the base atom and its neighbors + at1 = rdmol.GetAtomWithIdx(atom_idx) + at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] + + # We loop at2 and at3 through the sorted atom_pool in order to get + # a list of angles in the branch that are sorted by how close the atoms + # are from the central atom + for at2 in atom_pool: + if at2 in at1_neighbors: + at2_neighbors = [ + at.GetIdx() + for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() + ] + for at3 in atom_pool: + if at3 != atom_idx and at3 in at2_neighbors: + angles.append((atom_idx, at2, at3)) + return angles + + +def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: + """ + Get a list of ligand anchor atoms (e.g. l1, l2, and l3 of an orientational restraint). + + Parameters + ---------- + rdmol : ??? + Molecule object for the ligand to apply a restraint to. + + Returns + ------- + angles : list[tuple[int, int, int]] + A list of ligand atom triples denoting the possible l1, l2, and l3 + restraint atoms. Ordered by likelihood of restraint-ability. + """ + # Find the central atom + center = _get_central_atom_idx(rdmol) + + # Get a pool of potential anchor atoms looking for aromatic atoms + anchor_pool = _get_aromatic_atoms(rdmol) + + # If there are not enough aromatic atoms, then default to heavy atoms + if len(anchor_pool) < 3: + anchor_pool = _get_heavy_atoms(rdmol) + + # Raise an error if we have less than 3 anchors + if len(anchor_pool) < 3: + errmsg = f"Too few potential ligand anchor atoms, {len(anchor_pool)}" + raise ValueError(errmsg) + + # Sort the pool of anchor atoms by their distance from the central atom + sorted_anchor_pool = _sort_by_distance_from_target(rdmol, center, anchor_pool) + + # Get a list of ligand anchor angle atoms + angles = [] + for atom in sorted_anchor_pool: + angles.extend( + _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) + ) + + +def get_host_anchors(positions, topology, exclude_resids: list[int], lig_anchor_idx: int, selection: str): + """ + Get a list of host anchor atomss sorted by their distance from a ligand anchor atom. + + Parameters + ---------- + positions : openmm.unit.Quantity + Positions of the input system + topology : openmm.app.Topology + OpenMM Topology for input system + exclude_resids : list[int] + List of residue numbers to exclude from host selection + lig_anchor_idx : int + The index of the l1 ligand anchor. + selection : str + Selection string for the host atoms. + """ + # Create an mdtraj trajectory to manipulate + # First fetch the box vectors and pass them as lengths and angles + vectors = from_openmm(topology.getPeriodicBoxVectors()) + a, b, c, alpha, beta, gamma = mdt.utils.box_vectors_to_lengths_and_angles(vectors[0].m, vectors[1].m, vectors[2].m) + + traj = mdt.Trajectory( + positions[np.newaxis, ...], + mdt.Topology.from_openmm(topology) + ) + + # Get all the potential protein atoms matching the selection + host_sel = traj.topology.select(selection) + + # Get residues to exclude from the selection + exclude_sel = np.array([ + at.index for at in + chain(*[traj.topology.residue(i).atoms for i in exclude_resids]) + ]) + + # Remove exclusion + anchors = host_sel[np.isin(host_sel, exclude_sel, invert=True)] + + # Compute distanecs from ligand l1 anchor atom + pairs = np.vstack((anchors, np.array([lig_anchor_idx for _ in range(len(anchors))]))).T + + distances = mdt.compute_distances(traj, pairs, periodic=True) + + return np.array([pairs[i][0] for i in np.argsort(distances[0])]) + + +def is_collinear(positions, atoms, threshold=0.9): + """ + Check whether any sequential vectors in a sequence of atoms are collinear. + + Parameters + ---------- + positions : openmm.unit.Quantity + System positions. + atoms : list[int] + The indices of the atoms to test. + threshold : float + Atoms are not collinear if their sequential vector separation dot + products are less than ``threshold``. Default 0.9. + + Returns + ------- + result : bool + Returns True if any sequential pair of vectors is collinear; False otherwise. + + Notes + ----- + Originally from Yank, with modifications from Separated Topologies + """ + results = False + for i in range(len(atoms) - 2): + v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] + v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] + normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) + result = result or (np.abs(normalized_inner_product) > threshold) + return result + + +def check_angle(angle, force_constant=83.68): + """ + Check whether the chosen angle is less than 10 kT from 0 or 180 + + Parameters + ---------- + angle : float + The angle to check in degrees. + force_constant : float + Force constant of the angle. + + Note + ---- + We assume the temperature to be 298.15 Kelvin. + """ + # TODO: convert this to unit.Quantity so we don't end up with + # conversion errors + RT = 8.31445985 * 0.001 * 298.15 + # check if angle is <10kT from 0 or 180 + check1 = 0.5 * force_constant * np.power((angle - 0.0) / 180.0 * np.pi, 2) + check2 = 0.5 * force_constant * np.power((angle - 180.0) / 180.0 * np.pi, 2) + ang_check_1 = check1 / RT + ang_check_2 = check2 / RT + if ang_check_1 < 10.0 or ang_check_2 < 10.0: + return False + return True + + + + +class FindHostAtoms(AnalysisBase): + """ + Class filter host atoms based on their distance + from a set of guest atoms. + + Parameters + ---------- + host_atoms : MDAnalysis.AtomGroup + Initial selection of host atoms to filter from. + guest_atoms : MDANalysis.AtomGroup + Selection of guest atoms to search around. + search_distance: unit.Quantity + Distance to filter atoms within. + """ + _analysis_algorithm_is_parallelizable = False + + def __init__(self, host_atoms, guest_atoms, search_distance, **kwargs): + super().__init__(host_atoms.universe.trajectory, **kwargs) + + self.host_ag = host_atoms + self.guest_ag = guest_atoms + self.cutoff = search_distance.to('angstrom').m + + def _prepare(self): + self.results.host_idxs = set() + + def _single_frame(self): + pairs = capped_distance( + reference=self.host_ag.positions, + configuration=self.guest_ag.positions, + max_cutoff=self.cutoff, + min_cutoff=None + box=self.guest_ag.universe.dimensions, + return_distances=False) + + host_idxs = [self.guest_ag.atoms[p].index for p in pairs[:, 1]] + self.results.host_idxs.update(set(host_idxs)) + + def _conclude(self): + pass + + +def find_host_atoms(topology, trajectory, host_selection, guest_selection, cutoff) -> mda.AtomGroup: + """ + Get an AtomGroup of the host atoms based on their distances from the guest atoms. + """ + u = mda.Universe(topology, trajectory) + + def _get_selection(selection): + """ + If it's a str, call select_atoms, if not a list of atom idxs + """ + if isinstance(selection, str): + ag = u.select_atoms(host_selection) + else: + ag = u.atoms[host_ag] + return ag + + host_ag = _get_selection(host_selection) + guest_ag = _get_selection(guest_selection) + + finder = FindHostAtoms(host_ag, guest_ag, cutoff) + finder.run() + + return u.atoms[list(finder.results.host_idxs)] + +def get_molecule_center_idx(atomgroup): + offmol = Molecule(atomgroup.convert_to("RDKIT"), allow_undefined_stereo=True) + # Check if the molecule is whole, otherwise throw an error. + nx = offmol.to_networkx() + + +def get_distance_restraint(topology, trajectory, host_atoms, guest_atoms, host_selection, guest_selection): + u = mda.Universe(topology, trajectory) + + if guest_atoms is None: + if guest_selection is None: + raise ValueError("one of guest_atoms or guest_selections must be defined") + guest_ag = u.select_atoms(guest_selection) + else: + + + if host_atoms is None: + if host_selection is None: + raise ValueError("one of host_atoms or host_selection must be defined") + + host_ag = u.select_atoms(host_selection) From 20dd1dcce9f6608d0fe5b3d37fcd257709f4a109 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 14:02:05 +0000 Subject: [PATCH 078/163] add some angle checks --- .../openmm_utils/restraints/geometry/utils.py | 132 +++++++++++++++++- 1 file changed, 126 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index 6b3d94eb7..80b7c3372 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -12,20 +12,22 @@ from openff.toolkit import Molecule as OFFMol from openff.units import unit +from openff.units.types import FloatQuantity import networkx as nx +from rdkit import Chem import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.lib.distances import calc_bonds, calc_angles -def _get_aromatic_atom_idxs(rdmol) -> list[int]: +def get_aromatic_atom_idxs(rdmol: Chem.Mol) -> list[int]: """ Helper method to get aromatic atoms idxs in a RDKit Molecule Parameters ---------- - rdmol : ??? + rdmol : Chem.Mol RDKit Molecule Returns @@ -40,13 +42,13 @@ def _get_aromatic_atom_idxs(rdmol) -> list[int]: return idxs -def _get_heavy_atom_idxs(rdmol) -> list[int]: +def get_heavy_atom_idxs(rdmol: Chem.Mol) -> list[int]: """ Get idxs of heavy atoms in an RDKit Molecule Parameters ---------- - rmdol : ??? + rmdol : Chem.Mol Returns ------- @@ -60,14 +62,132 @@ def _get_heavy_atom_idxs(rdmol) -> list[int]: return idxs -def _get_central_atom_idx(rdmol) -> int: +def get_central_atom_idx(rdmol: Chem.Mol) -> int: + """ + Get the central atom in an rdkit Molecule. + + Parameters + ---------- + rdmol : Chem.Mol + RDKit Molcule to query + + Returns + ------- + center : int + Index of central atom in Molecule + + Note + ---- + If there are equal likelihood centers, will return + the first entry. + """ + # TODO: switch to a manual conversion to avoid an OpenFF dependency offmol = OFFMol(rdmol, allow_undefined_stereo=True) + nx_mol = offmol.to_networkx() + if not nx.is_weakly_connected(nx_mol): + errmsg = "A disconnected molecule was passed, cannot find the center" + raise ValueError(errmsg) + # We take the zero-th entry if there are multiple center # atoms (e.g. equal likelihood centers) - center = nx.center(offmol.to_networkx())[0] + center = nx.center(nx_mol)[0] return center +def is_collinear(positions, atoms, threshold=0.9): + """ + Check whether any sequential vectors in a sequence of atoms are collinear. + + Parameters + ---------- + positions : openmm.unit.Quantity + System positions. + atoms : list[int] + The indices of the atoms to test. + threshold : float + Atoms are not collinear if their sequential vector separation dot + products are less than ``threshold``. Default 0.9. + + Returns + ------- + result : bool + Returns True if any sequential pair of vectors is collinear; False otherwise. + + Notes + ----- + Originally from Yank, with modifications from Separated Topologies + """ + results = False + for i in range(len(atoms) - 2): + v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] + v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] + normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) + result = result or (np.abs(normalized_inner_product) > threshold) + return result + + +def check_angle_energy( + angle: FloatQuantity['radians'], + force_constant: FloatQuantity['unit.kilojoule_per_mole / unit.radians**2'] = 83.68 * unit.kilojoule_per_mole / unit.radians**2, + temperature: FloatQuantity['kelvin'] = 298.15 * unit.kelvin +) -> bool: + """ + Check whether the chosen angle is less than 10 kT from 0 or 180 + + Parameters + ---------- + angle : unit.Quantity + The angle to check in units compatible with radians. + force_constant : unit.Quantity + Force constant of the angle in units compatible with kilojoule_per_mole / radians ** 2. + temperature: unit.Quantity + The system temperature in units compatible with Kelvin. + + Note + ---- + We assume the temperature to be 298.15 Kelvin. + """ + # Convert things + angle_rads = angle.to('radians') + frc_const = force_constant.to('unit.kilojoule_per_mole / unit.radians**2') + temp_kelvin = temperature.to('kelvin') + RT = 8.31445985 * 0.001 * temp_kelvin + + # check if angle is <10kT from 0 or 180 + check1 = 0.5 * frc_const * np.power((angle - 0.0), 2) + check2 = 0.5 * frc_const * np.power((angle - np.pi), 2) + ang_check_1 = check1 / RT + ang_check_2 = check2 / RT + if ang_check_1 < 10.0 or ang_check_2 < 10.0: + return False + return True + + +def check_dihedral_bounds( + dihedral: FloatQuantity['radians'] + lower_cutoff: FloatQuantity['radians'] = 2.618 * unit.radians, + upper_cutoff: FloatQuantity['radians'] = -2.6.18 * unit.radians, +): + """ + Check that a dihedral does not exceed the bounds set by + lower_cutoff and upper_cutoff. + + Parameters + ---------- + dihedral : unit.Quantity + Dihedral in units compatible with radians. + lower_cutoff : unit.Quantity + Dihedral lower cutoff in units compatible with radians. + upper_cutoff : unit.Quantity + Dihedral upper cutoff in units compatible with radians. + """ + if (dihedral < lower_cutoff) or (dihedral > upper_cutoff): + return False + return True + + + + def _sort_by_distance_from_target(rdmol, target_idx: int, atom_idxs: list[int]) -> list[int]: """ Sort a list of atoms by their distance from a target atom. From 9ab74a8225d7efc511fac79975abd5a2f795b5de Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 14:19:39 +0000 Subject: [PATCH 079/163] only construct with settings --- .../restraints/openmm/omm_restraints.py | 111 ++++++++++-------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py index ab5f4e821..e53e828d5 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py @@ -87,40 +87,42 @@ class BaseHostGuestRestraints(abc.ABC): def __init__( self, restraint_settings: SettingsBaseModel, - restraint_geometry: BaseRestraintGeometry, controlling_parameter_name: str = "lambda_restraints", ): self.settings = restraint_settings - self.geometry = restraint_geometry - self._verify_input() + self._verify_settings() @abc.abstractmethod - def _verify_inputs(self): + def _verify_settings(self): pass @abc.abstractmethod - def add_force(self, thermodynamic_state: ThermodynamicState): + def _verify_geometry(self, geometry): pass @abc.abstractmethod - def get_standard_state_correction(self, thermodynamic_state: ThermodynamicState): + def add_force(self, thermodynamic_state: ThermodynamicState, geometry: BaseRestraintGeometry): pass @abc.abstractmethod - def _get_force(self): + def get_standard_state_correction(self, thermodynamic_state: ThermodynamicState, geometry: BaseRestraintGeometry): + pass + + @abc.abstractmethod + def _get_force(self, geometry: BaseRestraintGeometry): pass class SingleBondMixin: - def _verify_input(self): - if len(self.geometry.host_atoms) != 1 or len(self.geometry.guest_atoms) != 1: + def _verify_geometry(self, geometry: BaseRestraintGeometry): + if len(geometry.host_atoms) != 1 or len(geometry.guest_atoms) != 1: errmsg = ( "host_atoms and guest_atoms must only include a single index " f"each, got {len(host_atoms)} and " f"{len(guest_atoms)} respectively." ) raise ValueError(errmsg) - super()._verify_inputs() + super()._verify_geometry(geometry) class BaseRadialllySymmetricRestraintForce(BaseHostGuestRestraints): @@ -128,12 +130,15 @@ def _verify_inputs(self) -> None: if not isinstance(self.settings, BaseDistanceRestraintSettings): errmsg = f"Incorrect settings type {self.settings} passed through" raise ValueError(errmsg) - if not isinstance(self.geometry, DistanceRestraintGeometry): - errmsg = f"Incorrect geometry type {self.geometry} passed through" + + def _verify_geometry(self, geometry: DistanceRestraintGeometry) + if not isinstance(geometry, DistanceRestraintGeometry): + errmsg = f"Incorrect geometry class type {geometry} passed through" raise ValueError(errmsg) - def add_force(self, thermodynamic_state: ThermodynamicState) -> None: - force = self._get_force() + def add_force(self, thermodynamic_state: ThermodynamicState, geometry: DistanceRestraintGeometry) -> None: + self._verify_geometry(geometry) + force = self._get_force(geometry) force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system @@ -141,87 +146,92 @@ def add_force(self, thermodynamic_state: ThermodynamicState) -> None: thermodynamic_state.system = system def get_standard_state_correction( - self, thermodynamic_state: ThermodynamicState + self, + thermodynamic_state: ThermodynamicState, + geometry: DistanceRestraintGeometry, ) -> unit.Quantity: - force = self._get_force() + self._verify_geometry(geometry) + force = self._get_force(geometry) corr = force.compute_standard_state_correction( thermodynamic_state, volume="system" ) dg = corr * thermodynamic_state.kT return from_openmm(dg).to('kilojoule_per_mole') - def _get_force(self): + def _get_force(self, geometry: DistanceRestraintGeometry): raise NotImplementedError("only implemented in child classes") class HarmonicBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): - def _get_force(self) -> openmm.Force: + def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintBondForce( spring_constant=spring_constant, - restrained_atom_index1=self.geometry.host_atoms[0], - restrained_atom_index2=self.geometry.guest_atoms[0], + restrained_atom_index1=geometry.host_atoms[0], + restrained_atom_index2=geometry.guest_atoms[0], controlling_parameter_name=self.controlling_parameter_name, ) class FlatBottomBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): - def _get_force(self) -> openmm.Force: + def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) - well_radius = to_openmm(self.geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, - restrained_atom_index1=self.geometry.host_atoms[0], - restrained_atom_index2=self.geometry.guest_atoms[0], + restrained_atom_index1=geometry.host_atoms[0], + restrained_atom_index2=geometry.guest_atoms[0], controlling_parameter_name=self.controlling_parameter_name, ) class CentroidHarmonicRestraint(BaseRadialllySymmetricRestraintForce): - def _get_force(self) -> openmm.Force: + def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintForce( spring_constant=spring_constant, - restrained_atom_index1=self.geometry.host_atoms, - restrained_atom_index2=self.geometry.guest_atoms, + restrained_atom_index1=geometry.host_atoms, + restrained_atom_index2=geometry.guest_atoms, controlling_parameter_name=self.controlling_parameter_name, ) class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): - def _get_force(self) -> openmm.Force: + def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) - well_radius = to_openmm(self.geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, - restrained_atom_index1=self.geometry.host_atoms, - restrained_atom_index2=self.geometry.guest_atoms, + restrained_atom_index1=geometry.host_atoms, + restrained_atom_index2=geometry.guest_atoms, controlling_parameter_name=self.controlling_parameter_name, ) class BoreschRestraint(BaseHostGuestRestraints): - _EFUNC_METHOD: Callable = get_boresch_energy_function - def _verify_inputs(self) -> None: + def _verify_settings(self) -> None: if not isinstance(self.settings, BoreschRestraintSettings): errmsg = f"Incorrect settings type {self.settings} passed through" raise ValueError(errmsg) - if not isinstance(self.geometry, BoreschRestraintGeometry): - errmsg = f"Incorrect geometry type {self.geometry} passed through" + + def _verify_geometry(self, geometry: BoreschRestraintGeometry): + if not isinstance(geometry, BoreschRestraintGeometry): + errmsg = f"Incorrect geometry class type {geometry} passed through" raise ValueError(errmsg) - def add_force(self, thermodynamic_state: ThermodynamicState) -> None: - force = self._get_force() + def add_force(self, thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry) -> None: + _verify_geometry(geometry) + force = self._get_force(geometry) force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system add_force_in_separate_group(system, force) thermodynamic_state.system = system - def _get_force(self) -> openmm.Force: - efunc = _EFUNC_METHOD( + def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: + efunc = get_boresch_energy_function( self.controlling_parameter_name, ) @@ -233,37 +243,38 @@ def _get_force(self) -> openmm.Force: parameter_dict = { 'K_r': self.settings.K_r, - 'r_aA0': self.geometry.r_aA0, + 'r_aA0': geometry.r_aA0, 'K_thetaA': self.settings.K_thetaA, - 'theta_A0': self.geometry.theta_A0, + 'theta_A0': geometry.theta_A0, 'K_thetaB': self.settings.K_thetaB, - 'theta_B0': self.geometry.theta_B0, + 'theta_B0': geometry.theta_B0, 'K_phiA': self.settings.K_phiA, - 'phi_A0': self.geometry.phi_A0, + 'phi_A0': geometry.phi_A0, 'K_phiB': self.settings.K_phiB, - 'phi_B0': self.geometry.phi_B0, + 'phi_B0': geometry.phi_B0, 'K_phiC': self.settings.K_phiC, - 'phi_C0': self.geometry.phi_C0, + 'phi_C0': geometry.phi_C0, } for key, val in parameter_dict.items(): param_values.append(to_openmm(val).value_in_unit_system(omm_unit.md_unit_system)) force.addPerBondParameter(key) force.addGlobalParameter(self.controlling_parameter_name, 1.0) - force.addBond(self.geometry.host_atoms + self.geometry.guest_atoms, param_values) + force.addBond(geometry.host_atoms + geometry.guest_atoms, param_values) return force def get_standard_state_correction( - self, thermodynamic_state: ThermodynamicState + self, thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry ) -> unit.Quantity: + self._verify_geometry(geometry) StandardV = 1.66053928 * unit.nanometer**3 kt = from_openmm(thermodynamic_state.kT) # distances - r_aA0 = self.geometry.r_aA0.to('nm') - sin_thetaA0 = np.sin(self.geometry.theta_A0.to('radians')) - sin_thetaB0 = np.sin(self.geometry.theta_B0.to('radians')) + r_aA0 = geometry.r_aA0.to('nm') + sin_thetaA0 = np.sin(geometry.theta_A0.to('radians')) + sin_thetaB0 = np.sin(geometry.theta_B0.to('radians')) # restraint energies K_r = self.settings.K_r.to('kilojoule_per_mole / nm ** 2') From e4c25e159eaa72dd38c1ef29185bf7da2bcf7262 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 12 Dec 2024 15:34:56 +0100 Subject: [PATCH 080/163] AlchemicalFactory changes --- .../protocols/openmm_septop/alchemy_copy.py | 1 + openfe/protocols/openmm_septop/base.py | 4 - .../protocols/openmm_septop/femto_alchemy.py | 9 +- openfe/tests/protocols/test_femto_fep.py | 485 ------------------ .../protocols/test_openmm_septop_protocol.py | 137 +++-- 5 files changed, 104 insertions(+), 532 deletions(-) delete mode 100644 openfe/tests/protocols/test_femto_fep.py diff --git a/openfe/protocols/openmm_septop/alchemy_copy.py b/openfe/protocols/openmm_septop/alchemy_copy.py index 23db6d478..75a7856c9 100644 --- a/openfe/protocols/openmm_septop/alchemy_copy.py +++ b/openfe/protocols/openmm_septop/alchemy_copy.py @@ -2423,6 +2423,7 @@ def check_energy_expression(custom_force, parameter): parameter_found, region_type_suffix = check_energy_expression(force, 'lambda') if parameter_found: _, region_name_suffix = check_energy_expression(force, 'lambda_{}'.format(region_type_suffix)) + print(region_name_suffix) if region_type_suffix == 'sterics': if region_name_suffix in sterics_bond_forces: sterics_bond_forces[region_name_suffix].append([force_index, force]) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 5e1e1dba0..9360d6bd2 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -71,7 +71,6 @@ ) from openfe.utils import without_oechem_backend -from .femto_alchemy import apply_fep from .femto_restraints import select_ligand_idxs from .utils import serialize, deserialize from openfe.protocols.openmm_septop.alchemy_copy import ( @@ -828,9 +827,6 @@ def run(self, dry=False, verbose=True, # 9. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") - # apply_fep(omm_system_AB, atom_indices_AB_A, atom_indices_AB_B) - - # Alternatively use AbsoluteAlchemicalFactory from openmmtools factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alchemical_region_A = AlchemicalRegion( diff --git a/openfe/protocols/openmm_septop/femto_alchemy.py b/openfe/protocols/openmm_septop/femto_alchemy.py index fa3abc7f5..4c1b6b33f 100644 --- a/openfe/protocols/openmm_septop/femto_alchemy.py +++ b/openfe/protocols/openmm_septop/femto_alchemy.py @@ -1,6 +1,7 @@ import collections import copy import itertools +from typing import List, Any import numpy import openmm @@ -9,6 +10,7 @@ # import femto.fe.config # This code was obtained and modified from https://github.com/Psivant/femto +from openmm import NonbondedForce, CustomNonbondedForce LAMBDA_VDW_LIGAND_1 = "lambda_sterics_ligandA" """The global parameter used to scale the vdW interactions of ligand 1.""" @@ -181,7 +183,7 @@ def _apply_lambda_vdw( """ if len(ligand_idxs) == 0: - return + return None custom_vdw_fn = _beutler_softcore_potential(variable) @@ -232,7 +234,6 @@ def _apply_nonbonded_lambdas( force: openmm.NonbondedForce, ligand_1_idxs: set[int], ligand_2_idxs: set[int] | None, - # config: femto.fe.config.FEP, ) -> tuple[openmm.NonbondedForce | openmm.CustomNonbondedForce, ...]: """Modifies a standard non-bonded force so that vdW and electrostatic interactions are scaled by ``lambda_vdw`` and ``lambda_charges`` respectively. @@ -243,7 +244,6 @@ def _apply_nonbonded_lambdas( scaled by lambda. ligand_2_idxs: The indices of the ligand atoms whose interactions should be scaled by 1 - lambda. - config: Configuration options. Returns: The modified non-bonded force containing chemical-chemical and @@ -289,7 +289,6 @@ def apply_fep( system: openmm.System, ligand_1_idxs: set[int], ligand_2_idxs: set[int] | None, - # config: femto.fe.config.FEP, ): """Modifies an OpenMM system so that different interactions can be scaled by corresponding lambda parameters. @@ -324,7 +323,7 @@ def apply_fep( ) forces_by_type[type(force)].append(force) - updated_forces = [] + updated_forces: list[NonbondedForce | CustomNonbondedForce | Any] = [] for force_type, forces in forces_by_type.items(): if len(forces) != 1: diff --git a/openfe/tests/protocols/test_femto_fep.py b/openfe/tests/protocols/test_femto_fep.py deleted file mode 100644 index ecf75d962..000000000 --- a/openfe/tests/protocols/test_femto_fep.py +++ /dev/null @@ -1,485 +0,0 @@ -import numpy -import openmm -import openmm.app -import openmm.unit -import pytest - -from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close -from openfe.protocols.openmm_septop.femto_alchemy import ( - LAMBDA_CHARGES_LIGAND_1, - LAMBDA_CHARGES_LIGAND_2, - LAMBDA_VDW_LIGAND_1, - LAMBDA_VDW_LIGAND_2, - _convert_intramolecular_interactions, - apply_fep, -) -from openfe.protocols.openmm_septop.alchemy_copy import ( - AlchemicalRegion, - AbsoluteAlchemicalFactory, -) - -KJ_PER_MOL = openmm.unit.kilojoule_per_mole - - -E_CHARGE = 1.602176634e-19 * openmm.unit.coulomb -EPSILON0 = ( - 1e-6 - * 8.8541878128e-12 - / (openmm.unit.AVOGADRO_CONSTANT_NA * E_CHARGE**2) - * openmm.unit.farad - / openmm.unit.meter -) -ONE_4PI_EPS0 = 1 / (4 * numpy.pi * EPSILON0) * EPSILON0.unit * 10.0 # nm -> angstrom - - -def compute_interaction_energy( - epsilon, - sigma, - charge, - distance, - lambda_vdw: float = 1.0, - lambda_charges: float = 1.0, -): - r_electrostatics = distance - r_vdw = (0.5 * sigma**6 * (1.0 - lambda_vdw) + distance**6) ** (1.0 / 6.0) - - return ( - # vdw - 4.0 * lambda_vdw * epsilon * ((sigma / r_vdw) ** 12 - (sigma / r_vdw) ** 6) - # electrostatics - + ONE_4PI_EPS0 * lambda_charges * charge / r_electrostatics - ) * KJ_PER_MOL - - -@pytest.fixture -def three_particle_system(): - force = openmm.NonbondedForce() - force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) - force.setUseDispersionCorrection(False) - - charges = 0.1, 0.2, -0.3 - sigmas = 1.1, 1.2, 1.3 - epsilons = 210, 220, 230 - - force.addParticle(charges[0], sigmas[0] * openmm.unit.angstrom, epsilons[0]) - force.addParticle(charges[1], sigmas[1] * openmm.unit.angstrom, epsilons[1]) - force.addParticle(charges[2], sigmas[2] * openmm.unit.angstrom, epsilons[2]) - - system = openmm.System() - system.addParticle(1.0) - system.addParticle(1.0) - system.addParticle(1.0) - system.addForce(force) - - distances = [[0.0, 4.0, 3.0], [4.0, 0.0, 5.0], [3.0, 5.0, 0.0]] - - def interaction_energy_fn( - idx_a, idx_b, lambda_vdw: float = 1.0, lambda_charges: float = 1.0 - ): - epsilon = numpy.sqrt(epsilons[idx_a] * epsilons[idx_b]) - sigma = 0.5 * (sigmas[idx_a] + sigmas[idx_b]) - charge = charges[idx_a] * charges[idx_b] - - return compute_interaction_energy( - epsilon, sigma, charge, distances[idx_a][idx_b], lambda_vdw, lambda_charges - ) - - coords = ( - numpy.array( - [[0.0, 0.0, 0.0], [distances[0][1], 0.0, 0.0], [0.0, distances[0][2], 0.0]] - ) - * openmm.unit.angstrom - ) - - return system, coords, interaction_energy_fn - - -class TestNonbondedInteractions: - def test_convert_intramolecular_interactions(self): - system = openmm.System() - system.addParticle(1.0) - system.addParticle(1.0) - system.addParticle(1.0) - system.addParticle(1.0) - system.addParticle(1.0) - - bond_force = openmm.HarmonicBondForce() - bond_force.addBond(0, 1, 1.0 * openmm.unit.angstrom, 1.0) - bond_force.addBond(1, 2, 1.0 * openmm.unit.angstrom, 1.0) - bond_force.addBond(2, 3, 1.0 * openmm.unit.angstrom, 1.0) - bond_force.addBond(3, 4, 1.0 * openmm.unit.angstrom, 1.0) - system.addForce(bond_force) - - epsilons = (numpy.arange(5) * 10.0 + 200.0).tolist() - sigmas = (numpy.arange(5) / 10.0 + 1.0).tolist() - - charges = (numpy.arange(5) / 10.0).tolist() - - force = openmm.NonbondedForce() - - for i in range(5): - force.addParticle(charges[i], sigmas[i], epsilons[i]) - - for i, j in [ - (0, 1), - (0, 2), - (0, 3), - (1, 2), - (1, 3), - (1, 4), - (2, 3), - (2, 4), - (3, 4), - ]: - force.addException( - i, - j, - charges[i] * charges[j], - 0.5 * (sigmas[i] + sigmas[j]), - numpy.sqrt(epsilons[i] * epsilons[j]), - ) - - system.addForce(force) - - coords = ( - numpy.array( - [ - [0.0, 0.0, 0.0], - [1.0, 1.0, 0.0], - [2.0, 0.0, 0.0], - [3.0, 1.0, 0.0], - [4.0, 0.0, 0.0], - ] - ) - * openmm.unit.angstrom - ) - - existing_exclusions = [ - force.getExceptionParameters(i) for i in range(force.getNumExceptions()) - ] - energy_0 = compute_energy(system, coords, None) - - # we expect a 1-5 exclusion to be added. - _convert_intramolecular_interactions(force, {0, 1, 2, 3, 4}, set()) - - modified_exclusions = [ - force.getExceptionParameters(i) for i in range(force.getNumExceptions()) - ] - assert len(modified_exclusions) == len(existing_exclusions) + 1 - - for i in range(len(existing_exclusions)): - assert existing_exclusions[i][0] == modified_exclusions[i][0] - assert existing_exclusions[i][1] == modified_exclusions[i][1] - - assert all( - is_close(v_a, v_b) - for v_a, v_b in zip( - existing_exclusions[i][2:], modified_exclusions[i][2:], strict=True - ) - ) - - assert modified_exclusions[-1][:2] == [0, 4] - - energy_1 = compute_energy(system, coords, None) - - assert is_close(energy_0, energy_1) - - def test_one_ligand(self, three_particle_system): - """Test scaling the nonbonded interactions of single particles.""" - - system, coords, energy_fn = three_particle_system - - factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - alchemical_region_A = AlchemicalRegion( - alchemical_atoms=[0], name='ligandA') - alchemical_system = factory.create_alchemical_system( - system, [alchemical_region_A]) - energy_0_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 1.0, - LAMBDA_CHARGES_LIGAND_1: 1.0, - }, - ) - - apply_fep(system, {0}, set()) - - # expect lig_1 + solvent, lig_1 + lig_2 and lig_2 + solvent interaction when - # lambda=0 - energy_0 = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.0, - LAMBDA_CHARGES_LIGAND_1: 0.0, - }, - ) - expected_energy_0 = energy_fn(0, 2) + energy_fn(0, 1) + energy_fn(1, 2) - print(expected_energy_0, energy_0, energy_0_openmm) - assert is_close(energy_0, expected_energy_0) - assert is_close(energy_0_openmm, expected_energy_0) - - # expect only lig_2 + solvent interaction when lambda=1 - energy_1 = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 1.0, - LAMBDA_CHARGES_LIGAND_1: 1.0, - }, - ) - energy_1_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.0, - LAMBDA_CHARGES_LIGAND_1: 0.0, - }, - ) - expected_energy_1 = energy_fn(1, 2) - assert is_close(energy_1, expected_energy_1) - assert is_close(energy_1_openmm, expected_energy_1) - - # expect all particles to interact but only lig - solvent interactions to be - # scaled - energy_05 = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.5, - LAMBDA_CHARGES_LIGAND_1: 0.5, - }, - ) - energy_05_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.5, - LAMBDA_CHARGES_LIGAND_1: 0.5, - }, - ) - expected_energy_05 = ( - energy_fn(1, 2) + energy_fn(0, 2, 0.5, 0.5) + energy_fn(0, 1, 0.5, 0.5) - ) - assert is_close(energy_05, expected_energy_05) - assert is_close(energy_05_openmm, expected_energy_05) - - def test_two_ligands(self, three_particle_system): - """Test scaling the nonbonded interactions of single particles.""" - - system, coords, energy_fn = three_particle_system - - # Do it the openmm way - factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - alchemical_region_A = AlchemicalRegion( - alchemical_atoms=[0], name='ligandA') - alchemical_region_B = AlchemicalRegion( - alchemical_atoms=[1], name='ligandB') - alchemical_system = factory.create_alchemical_system( - system, [alchemical_region_A, alchemical_region_B]) - energy_0_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 1.0, - LAMBDA_CHARGES_LIGAND_1: 1.0, - LAMBDA_VDW_LIGAND_2: 0.0, - LAMBDA_CHARGES_LIGAND_2: 0.0, - }, - ) - - apply_fep(system, {0}, {1}) - # expect only lig_1 + solvent interaction when lambda=0 - energy_0 = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.0, - LAMBDA_CHARGES_LIGAND_1: 0.0, - LAMBDA_VDW_LIGAND_2: 1.0, - LAMBDA_CHARGES_LIGAND_2: 1.0, - }, - ) - expected_energy_0 = energy_fn(0, 2) - print(energy_0, energy_0_openmm, expected_energy_0) - assert is_close(energy_0, expected_energy_0) - assert is_close(energy_0_openmm, expected_energy_0) - - # expect only lig_2 + solvent interaction when lambda=1 - - energy_1 = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 1.0, - LAMBDA_CHARGES_LIGAND_1: 1.0, - LAMBDA_VDW_LIGAND_2: 0.0, - LAMBDA_CHARGES_LIGAND_2: 0.0, - }, - ) - - energy_1_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.0, - LAMBDA_CHARGES_LIGAND_1: 0.0, - LAMBDA_VDW_LIGAND_2: 1.0, - LAMBDA_CHARGES_LIGAND_2: 1.0, - }, - ) - print(energy_1_openmm) - expected_energy_1 = energy_fn(1, 2) - assert is_close(energy_1, expected_energy_1) - assert is_close(energy_1_openmm, expected_energy_1) - - # expect lig_1 + solvent and lig_2 + solvent interaction when lambda=0.5 - # but no lig_1 + lig_2 interaction by default - energy_05 = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.5, - LAMBDA_CHARGES_LIGAND_1: 0.5, - LAMBDA_VDW_LIGAND_2: 0.5, - LAMBDA_CHARGES_LIGAND_2: 0.5, - }, - ) - energy_05_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.5, - LAMBDA_CHARGES_LIGAND_1: 0.5, - LAMBDA_VDW_LIGAND_2: 0.5, - LAMBDA_CHARGES_LIGAND_2: 0.5, - }, - ) - expected_energy_05 = energy_fn(0, 2, 0.5, 0.5) + energy_fn(1, 2, 0.5, 0.5) - assert is_close(energy_05, expected_energy_05) - assert is_close(energy_05_openmm, expected_energy_05) - - def test_two_ligands_charges(self, three_particle_system): - """Test scaling the nonbonded interactions of single particles.""" - - system, coords, energy_fn = three_particle_system - - # Do it the openmm way - factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - alchemical_region_A = AlchemicalRegion( - alchemical_atoms=[0], name='ligandA') - alchemical_region_B = AlchemicalRegion( - alchemical_atoms=[1], name='ligandB') - alchemical_system = factory.create_alchemical_system( - system, [alchemical_region_A, alchemical_region_B]) - energy_openmm = compute_energy( - alchemical_system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 1.0, - LAMBDA_CHARGES_LIGAND_1: 0.8, - LAMBDA_VDW_LIGAND_2: 1.0, - LAMBDA_CHARGES_LIGAND_2: 0.2, - }, - ) - - apply_fep(system, {0}, {1}) - # expect only lig_1 + solvent interaction when lambda=0 - energy = compute_energy( - system, - coords, - None, - { - LAMBDA_VDW_LIGAND_1: 0.0, - LAMBDA_CHARGES_LIGAND_1: 0.2, - LAMBDA_VDW_LIGAND_2: 0.0, - LAMBDA_CHARGES_LIGAND_2: 0.8, - }, - ) - assert is_close(energy, energy_openmm) - - # def test_exception(self, three_particle_system): - # """Test that 1-n exceptions are properly created.""" - # - # system, coords, energy_fn = three_particle_system - # - # factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - # alchemical_region_A = AlchemicalRegion( - # alchemical_atoms=[0, 1], name='ligandA') - # # alchemical_region_B = AlchemicalRegion( - # # alchemical_atoms=[1], name='ligandB') - # alchemical_system = factory.create_alchemical_system( - # system, [alchemical_region_A]) - # - # apply_fep(system, {0, 1}, set()) - # - # for lambda_value in [0.0, 0.5, 1.0]: - # energy = compute_energy( - # system, - # coords, - # None, - # { - # LAMBDA_VDW_LIGAND_1: 1.0 - lambda_value, - # LAMBDA_CHARGES_LIGAND_1: 1.0 - lambda_value, - # }, - # ) - # energy_openmm = compute_energy( - # alchemical_system, - # coords, - # None, - # { - # LAMBDA_VDW_LIGAND_1: lambda_value, - # LAMBDA_CHARGES_LIGAND_1: lambda_value, - # }, - # ) - # expected_energy = ( - # energy_fn(0, 2, lambda_value, lambda_value) - # + energy_fn(1, 2, lambda_value, lambda_value) - # + energy_fn(0, 1, 1.0, 1.0) - # ) - # print(lambda_value, expected_energy, energy, energy_openmm) - # assert is_close(energy, expected_energy) - # assert is_close(energy_openmm, expected_energy) - # - # def test_existing_exception(self, three_particle_system): - # """Test that existing exceptions aren't changed.""" - # - # system, coords, energy_fn = three_particle_system - # - # charge, sigma, epsilon = 0.4, 1.4, 2.4 - # - # force: openmm.NonbondedForce = next(iter(system.getForces())) - # force.addException(0, 1, charge, sigma * openmm.unit.angstrom, epsilon) - # - # apply_fep(system, {0, 1}, set()) - # - # for lambda_value in [0.0, 0.5, 1.0]: - # energy = compute_energy( - # system, - # coords, - # None, - # { - # LAMBDA_VDW_LIGAND_1: 1.0 - lambda_value, - # LAMBDA_CHARGES_LIGAND_1: 1.0 - lambda_value, - # }, - # ) - # expected_energy = ( - # energy_fn(0, 2, lambda_value, lambda_value) - # + energy_fn(1, 2, lambda_value, lambda_value) - # + compute_interaction_energy(epsilon, sigma, charge, 4.0, 1.0, 1.0) - # ) - # assert is_close(energy, expected_energy) \ No newline at end of file diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py index 6136c4b32..f7c934a72 100644 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ b/openfe/tests/protocols/test_openmm_septop_protocol.py @@ -3,7 +3,10 @@ import itertools import json import sys + +import openmmtools.alchemy import pytest +import importlib from unittest import mock from openmm import NonbondedForce, CustomNonbondedForce from openmmtools.multistate.multistatesampler import MultiStateSampler @@ -15,6 +18,7 @@ from openff.units import unit import gufe import openfe +import simtk from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_septop import ( SepTopSolventSetupUnit, @@ -22,13 +26,17 @@ SepTopProtocol, femto_restraints, ) +from openfe.protocols.openmm_septop.utils import deserialize from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference - +from openmmtools.states import (SamplerState, + ThermodynamicState, + create_thermodynamic_state_protocol, ) from openfe.protocols.openmm_utils import system_validation from openfe.protocols.openmm_utils.charge_generation import ( HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA ) +from openfe.protocols.openmm_septop.alchemy_copy import AlchemicalState @pytest.fixture() @@ -392,46 +400,99 @@ def test_validate_alchem_nonsmc( SepTopProtocol._validate_alchemical_components(alchem_comps) -def test_setup(bace_ligands, bace_protein_component, tmpdir): - # check system parametrisation works even if confgen fails - s = SepTopProtocol.default_settings() - s.protocol_repeats = 1 - s.solvent_equil_simulation_settings.minimization_steps = 100 - s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond - s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond - s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond - s.solvent_solvation_settings.box_shape = 'dodecahedron' - s.solvent_solvation_settings.solvent_padding = 1.8 * unit.nanometer +@pytest.fixture(scope='session') +def bace_reference_xml(): + with importlib.resources.files('openfe.tests.data.openmm_septop') as d: + f = d / 'system.xml.bz2' + return deserialize(f) - protocol = SepTopProtocol( - settings=s, - ) +@pytest.fixture(scope='session') +def bace_reference_positions(): + with importlib.resources.files('openfe.tests.data.openmm_septop') as d: + f = d / 'topology.pdb' + pdb = simtk.openmm.app.pdbfile.PDBFile(str(f)) + positions = pdb.getPositions(asNumpy=True) + return positions - stateA = ChemicalSystem({ - 'lig_02': bace_ligands['lig_02'], - 'protein': bace_protein_component, - 'solvent': SolventComponent(), - }) - stateB = ChemicalSystem({ - 'lig_03': bace_ligands['lig_03'], - 'protein': bace_protein_component, - 'solvent': SolventComponent(), - }) +def test_reference_alchemical_system(bace_reference_xml, bace_reference_positions): + settings = SepTopProtocol.default_settings() + alchemical_state = AlchemicalState.from_system(bace_reference_xml) + print(alchemical_state.lambda_sterics_ligandA) + print(alchemical_state.lambda_electrostatics_ligandA) + # Remove harmonic distance restraint for now + bace_reference_xml.removeForce(13) + + from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory + energy = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandA' + aa_A = 'alchemically modified NonbondedForce for alchemical/alchemical sterics for region ligandA' + na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandB' + aa_B = 'alchemically modified NonbondedForce for alchemical/alchemical sterics for region ligandB' + print(energy) + print(energy[na_B]) + alchemical_state.lambda_electrostatics_ligandA = 0.2 + alchemical_state.lambda_electrostatics_ligandB = 0.8 + energy_05 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + print(energy_05) + print(energy_05[na_B]) - # Create DAG from protocol, get the vacuum and solvent units - # and eventually dry run the first vacuum unit - dag = protocol.create( - stateA=stateA, - stateB=stateB, - mapping=None, + alchemical_state.lambda_sterics_ligandA = 0.5 + energy_05_2 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions ) - prot_units = list(dag.protocol_units) - solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopSolventSetupUnit)] - # solv_setup_unit = [u for u in prot_units - # if isinstance(u, SepTopComplexSetupUnit)] - - # with tmpdir.as_cwd(): - solv_setup_unit[0].run() + print(energy_05_2) + + assert energy[na_A] != energy_05[na_A] + assert energy[aa_A] == energy_05[aa_A] + assert energy[na_B] == energy_05[na_B] + assert energy[aa_B] == energy_05[aa_B] + + +# def test_setup(bace_ligands, bace_protein_component, tmpdir): +# # check system parametrisation works even if confgen fails +# s = SepTopProtocol.default_settings() +# s.protocol_repeats = 1 +# s.solvent_equil_simulation_settings.minimization_steps = 100 +# s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond +# s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond +# s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond +# s.solvent_solvation_settings.box_shape = 'dodecahedron' +# s.solvent_solvation_settings.solvent_padding = 1.8 * unit.nanometer +# +# protocol = SepTopProtocol( +# settings=s, +# ) +# +# stateA = ChemicalSystem({ +# 'lig_02': bace_ligands['lig_02'], +# 'protein': bace_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'lig_03': bace_ligands['lig_03'], +# 'protein': bace_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# # Create DAG from protocol, get the vacuum and solvent units +# # and eventually dry run the first vacuum unit +# dag = protocol.create( +# stateA=stateA, +# stateB=stateB, +# mapping=None, +# ) +# prot_units = list(dag.protocol_units) +# solv_setup_unit = [u for u in prot_units +# if isinstance(u, SepTopSolventSetupUnit)] +# # solv_setup_unit = [u for u in prot_units +# # if isinstance(u, SepTopComplexSetupUnit)] +# +# # with tmpdir.as_cwd(): +# solv_setup_unit[0].run() From 8f2e1e03dd613caf1f91df2d07d61e9751a03c3d Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 14:35:33 +0000 Subject: [PATCH 081/163] Add more checks to utilities --- .../openmm_utils/restraints/geometry/utils.py | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index 80b7c3372..30e81123f 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -10,9 +10,12 @@ import abc from pydantic.v1 import BaseModel, validator +import numpy as np +from scipy.stats import circvar, circmean, circstd + from openff.toolkit import Molecule as OFFMol from openff.units import unit -from openff.units.types import FloatQuantity +from openff.models.types import FloatQuantity, ArrayQuantity import networkx as nx from rdkit import Chem import MDAnalysis as mda @@ -132,7 +135,7 @@ def check_angle_energy( temperature: FloatQuantity['kelvin'] = 298.15 * unit.kelvin ) -> bool: """ - Check whether the chosen angle is less than 10 kT from 0 or 180 + Check whether the chosen angle is less than 10 kT from 0 or pi radians Parameters ---------- @@ -143,6 +146,12 @@ def check_angle_energy( temperature: unit.Quantity The system temperature in units compatible with Kelvin. + + Returns + ------- + bool + If the angle is less than 10 kT from 0 or pi radians + Note ---- We assume the temperature to be 298.15 Kelvin. @@ -167,7 +176,7 @@ def check_dihedral_bounds( dihedral: FloatQuantity['radians'] lower_cutoff: FloatQuantity['radians'] = 2.618 * unit.radians, upper_cutoff: FloatQuantity['radians'] = -2.6.18 * unit.radians, -): +) -> bool: """ Check that a dihedral does not exceed the bounds set by lower_cutoff and upper_cutoff. @@ -180,12 +189,42 @@ def check_dihedral_bounds( Dihedral lower cutoff in units compatible with radians. upper_cutoff : unit.Quantity Dihedral upper cutoff in units compatible with radians. + + Returns + ------- + bool + ``True`` if the dihedral is within the upper and lower + cutoff bounds. """ if (dihedral < lower_cutoff) or (dihedral > upper_cutoff): return False return True +def check_angular_variance( + angles: ArrayQuantity['radians'] + width: FloatQuantity['radians'] +) -> bool: + """ + Check that the variance of a list of ``angles`` does not exceed + a given ``width`` + + Parameters + ---------- + angles : ArrayLike[unit.Quantity] + An array of angles in units compatible with radians. + width : unit.Quantity + The width to check the variance against, in units compatible with radians. + + Returns + ------- + bool + ``True`` if the variance of the angles is less than the width. + + """ + array = angles.to('radians').m + variance = circvar(array) + return not (variance * unit.radians > width) def _sort_by_distance_from_target(rdmol, target_idx: int, atom_idxs: list[int]) -> list[int]: From 0a480aa0771f7112b9c92647877c7f02c5bc6a50 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 21:14:59 +0000 Subject: [PATCH 082/163] host finding code --- .../restraints/geometry/boresch.py | 213 +++++++++++++++- .../openmm_utils/restraints/geometry/utils.py | 240 ++++++++++-------- 2 files changed, 337 insertions(+), 116 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index 822382b9c..d6241f3d7 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -10,6 +10,8 @@ import abc from pydantic.v1 import BaseModel, validator +from rdkit import Chem + from openff.units import unit import MDAnalysis as mda from MDAnalysis.lib.distances import calc_bonds, calc_angles @@ -31,6 +33,7 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): Where HX represents the X index of ``host_atoms`` and GX the X index of ``guest_atoms``. """ + def get_bond_distance(self, topology, coordinates) -> unit.Quantity: u = mda.Universe(topology, coordinates) at1 = u.atoms[host_atoms[2]] @@ -46,8 +49,12 @@ def get_angles(self, topology, coordinates) -> unit.Quantity: at3 = u.atoms[guest_atoms[0]] at4 = u.atoms[guest_atoms[1]] - angleA = calc_angles(at1.position, at2.position, at3.position, u.atoms.dimensions) - angleB = calc_angles(at2.position, at3.position, at4.position, u.atoms.dimensions) + angleA = calc_angles( + at1.position, at2.position, at3.position, u.atoms.dimensions + ) + angleB = calc_angles( + at2.position, at3.position, at4.position, u.atoms.dimensions + ) return angleA, angleB def get_dihedrals(self, topology, coordinates) -> unit.Quantity: @@ -59,8 +66,204 @@ def get_dihedrals(self, topology, coordinates) -> unit.Quantity: at5 = u.atoms[guest_atoms[1]] at6 = u.atoms[guest_atoms[2]] - dihA = calc_dihedrals(at1.position, at2.position, at3.position, at4.position, u.atoms.dimensions) - dihB = calc_dihedrals(at2.position, at3.position, at4.position, at5.position, u.atoms.dimensions) - dihC = calc_dihedrals(at3.position, at4.position, at5.position, at6.position, u.atoms.dimensions) + dihA = calc_dihedrals( + at1.position, at2.position, at3.position, at4.position, u.atoms.dimensions + ) + dihB = calc_dihedrals( + at2.position, at3.position, at4.position, at5.position, u.atoms.dimensions + ) + dihC = calc_dihedrals( + at3.position, at4.position, at5.position, at6.position, u.atoms.dimensions + ) return dihA, dihB, dihC + + +def _sort_by_distance_from_atom( + rdmol: Chem.Mol, target_idx: int, atom_idxs: Iterable[int] +) -> list[int]: + """ + Sort a list of RDMol atoms by their distance from a target atom. + + Parameters + ---------- + target_idx : int + The idx of the atom to measure from. + atom_idxs : list[int] + The idx values of the atoms to sort. + rdmol : Chem.Mol + RDKit Molecule the atoms belong to + + Returns + ------- + list[int] + The input atom idxs sorted by their distance from the target atom. + """ + distances = [] + + conformer = rdmol.GetConformer() + # Get the target atom position + target_pos = conformer.GetAtomPosition(target_idx) + + for idx in atom_idxs: + pos = conformer.GetAtomPosition(idx) + distances.append(((target_pos - pos).Length(), idx)) + + return [i[1] for i in sorted(distances)] + + +def _get_bonded_angles_from_pool( + rdmol: Chem.Mol, atom_idx: int, atom_pool: list[int] +) -> list[tuple[int, int, int]]: + """ + Get all bonded angles starting from ``atom_idx`` from a pool of atoms. + + Parameters + ---------- + rdmol : Chem.Mol + The RDKit Molecule + atom_idx : int + The index of the atom to search angles from. + atom_pool : list[int] + The list of indices to pick possible angle partners from. + + Returns + ------- + list[tuple[int, int, int]] + A list of tuples containing all the angles. + """ + angles = [] + + # Get the base atom and its neighbors + at1 = rdmol.GetAtomWithIdx(atom_idx) + at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] + + # We loop at2 and at3 through the sorted atom_pool in order to get + # a list of angles in the branch that are sorted by how close the atoms + # are from the central atom + for at2 in atom_pool: + if at2 in at1_neighbors: + at2_neighbors = [ + at.GetIdx() for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() + ] + for at3 in atom_pool: + if at3 != atom_idx and at3 in at2_neighbors: + angles.append((atom_idx, at2, at3)) + return angles + + +def get_small_molecule_atom_candidates( + topology: Union[str, openmm.app.Topology], + trajectory: Union[str, pathlib.Path], + rdmol: Chem.Mol, + ligand_idxs: list[int], + rmsf_cutoff: unit.Quantity = 1 * unit.angstrom, + angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, +): + """ + Get a list of potential ligand atom choices for a Boresch restraint + being applied to a given small molecule. + + TODO: remember to update the RDMol with the last frame positions + """ + if isinstance(topology, openmm.app.Topology): + topology_format = "OPENMMTOPOLOGY" + else: + topology_format = None + + u = mda.Universe(topology, trajectory, topology_format=topology_format) + ligand_ag = u.atoms[ligand_idxs] + + # 0. Get the ligand RMSF + rmsf = get_local_rmsf(ligand_ag) + u.trajectory[-1] # forward to the last frame + + # 1. Get the pool of atoms to work with + # TODO: move to a helper function to make it easier to test + # Get a list of all the aromatic rings + # Note: no need to keep track of rings because we'll filter by + # bonded terms after, so if we only keep rings then all the bonded + # atoms should be within the same ring system. + atom_pool = set() + for ring in get_aromatic_rings(rdmol): + max_rmsf = rmsf[list(ring)].max() + if max_rmsf < rmsf_cutoff: + atom_pool.update(ring) + + # if we don't have enough atoms just get all the heavy atoms + if len(atom_pool) < 3: + heavy_atoms = get_heavy_atom_idxs(rdmol) + atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) + if len(atom_pool) < 3: + errmsg = ( + "No suitable ligand atoms for " "the boresch restraint could be found" + ) + raise ValueError(errmsg) + + # 2. Get the central atom + center = get_central_atom_idx(rdmol) + + # 3. Sort the atom pool based on their distance from the center + sorted_anchor_pool = _sort_by_distance_from_atom(rdmol, center, anchor_pool) + + # 4. Get a list of probable angles + angles_list = [] + for atom in sorted_anchor_pool: + angles = _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) + for angle in _angles: + angle_ag = ligand_ag.atoms[angle] + collinear = is_collinear(ligand_ag.positions, angle) + angle_value = ( + calc_angle( + angle_ag.atoms[0].position, + angle_ag.atoms[1].position, + angle_ag.atoms[2].position, + box=angle_ag.universe.dimensions, + ) + * unit.radians + ) + energy = check_angle_energy( + angle_value, angle_force_constant, 298.15 * unit.kelvin + ) + if not collinear and energy: + angles_list.append(angle) + + return angles_list + + +def get_host_atom_candidates( + topology: Union[str, openmm.app.Topology], + trajectory: Union[str, pathlib.Path], + host_idxs: list[int], + l1_idx: int, + host_selection: str, + dssp_filter: bool = False, + rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, + min_distance: unit.Quantity = 10 * unit.nanometer, + max_distance: unit.Quantity = 30 * unit.nanometer, + angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, +): + if isinstance(topology, openmm.app.Topology): + topology_format = "OPENMMTOPOLOGY" + else: + topology_format = None + + u = mda.Universe(topology, trajectory, topology_format=topology_format) + protein_ag1 = u.atoms[host_idxs] + protein_ag2 = protein_ag.select_atoms(protein_selection) + + # 0. TODO: implement DSSP filter + # Should be able to just call MDA's DSSP method, but will need to catch an exception + if dssp_filter: + raise NotImplementedError("DSSP filtering is not currently implemented") + + # 1. Get the RMSF & filter + rmsf = get_local_rmsf(sub_protein_ag) + protein_ag3 = sub_protein_ag.atoms[rmsf[heavy_atoms] < rmsf_cutoff] + + # 2. Search of atoms within the min/max cutoff + atom_finder = FindHostAtoms( + protein_ag3, u.atoms[l1_idx], min_search_distance, max_search_distance + ) + atom_finder.run() + return atom_finder.results.host_idxs diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index 30e81123f..c8226af0d 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -20,8 +20,37 @@ from rdkit import Chem import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase +from MDAnalysis.analysis.rmsf import RMSF from MDAnalysis.lib.distances import calc_bonds, calc_angles +from openfe_analysis.transformations import Aligner, NoJump + + +def get_aromatic_rings(rdmol: Chem.Mol) -> list[tuple[int, ...]]: + """ + Get a list of tuples with the indices for each ring in an rdkit Molecule. + + Parameters + ---------- + rdmol : Chem.Mol + RDKit Molecule + + Returns + ------- + list[tuple[int]] + List of tuples for each ring. + """ + ringinfo = rdmol.GetRingInfo() + arom_idxs = get_aromatic_atom_idxs(rdmol) + + aromatic_rings = [] + + for ring in ringinfo.AtomRings(): + if all(a in aroms for a in ring): + aromatic_rings.append(ring) + + return aromatic_rings + def get_aromatic_atom_idxs(rdmol: Chem.Mol) -> list[int]: """ @@ -38,10 +67,7 @@ def get_aromatic_atom_idxs(rdmol: Chem.Mol) -> list[int]: list[int] A list of the aromatic atom idxs """ - idxs = [ - at.GetIdx() for at in rdmol.GetAtoms() - if at.GetIsAromatic() - ] + idxs = [at.GetIdx() for at in rdmol.GetAtoms() if at.GetIsAromatic()] return idxs @@ -58,10 +84,7 @@ def get_heavy_atom_idxs(rdmol: Chem.Mol) -> list[int]: list[int] A list of heavy atom idxs """ - idxs = [ - at.GetIdx() for at in rdmol.GetAtoms() - if at.GetAtomicNum() > 1 - ] + idxs = [at.GetIdx() for at in rdmol.GetAtoms() if at.GetAtomicNum() > 1] return idxs @@ -124,15 +147,19 @@ def is_collinear(positions, atoms, threshold=0.9): for i in range(len(atoms) - 2): v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] - normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) + normalized_inner_product = np.dot(v1, v2) / np.sqrt( + np.dot(v1, v1) * np.dot(v2, v2) + ) result = result or (np.abs(normalized_inner_product) > threshold) return result def check_angle_energy( - angle: FloatQuantity['radians'], - force_constant: FloatQuantity['unit.kilojoule_per_mole / unit.radians**2'] = 83.68 * unit.kilojoule_per_mole / unit.radians**2, - temperature: FloatQuantity['kelvin'] = 298.15 * unit.kelvin + angle: FloatQuantity["radians"], + force_constant: FloatQuantity["unit.kilojoule_per_mole / unit.radians**2"] = 83.68 + * unit.kilojoule_per_mole + / unit.radians**2, + temperature: FloatQuantity["kelvin"] = 298.15 * unit.kelvin, ) -> bool: """ Check whether the chosen angle is less than 10 kT from 0 or pi radians @@ -157,9 +184,9 @@ def check_angle_energy( We assume the temperature to be 298.15 Kelvin. """ # Convert things - angle_rads = angle.to('radians') - frc_const = force_constant.to('unit.kilojoule_per_mole / unit.radians**2') - temp_kelvin = temperature.to('kelvin') + angle_rads = angle.to("radians") + frc_const = force_constant.to("unit.kilojoule_per_mole / unit.radians**2") + temp_kelvin = temperature.to("kelvin") RT = 8.31445985 * 0.001 * temp_kelvin # check if angle is <10kT from 0 or 180 @@ -167,15 +194,15 @@ def check_angle_energy( check2 = 0.5 * frc_const * np.power((angle - np.pi), 2) ang_check_1 = check1 / RT ang_check_2 = check2 / RT - if ang_check_1 < 10.0 or ang_check_2 < 10.0: + if ang_check_1 < 10.0 or ang_check_2 < 10.0: return False return True def check_dihedral_bounds( - dihedral: FloatQuantity['radians'] - lower_cutoff: FloatQuantity['radians'] = 2.618 * unit.radians, - upper_cutoff: FloatQuantity['radians'] = -2.6.18 * unit.radians, + dihedral: FloatQuantity["radians"], + lower_cutoff: FloatQuantity["radians"] = 2.618 * unit.radians, + upper_cutoff: FloatQuantity["radians"] = -2.618 * unit.radians, ) -> bool: """ Check that a dihedral does not exceed the bounds set by @@ -202,8 +229,7 @@ def check_dihedral_bounds( def check_angular_variance( - angles: ArrayQuantity['radians'] - width: FloatQuantity['radians'] + angles: ArrayQuantity["radians"], width: FloatQuantity["radians"] ) -> bool: """ Check that the variance of a list of ``angles`` does not exceed @@ -222,45 +248,14 @@ def check_angular_variance( ``True`` if the variance of the angles is less than the width. """ - array = angles.to('radians').m + array = angles.to("radians").m variance = circvar(array) return not (variance * unit.radians > width) -def _sort_by_distance_from_target(rdmol, target_idx: int, atom_idxs: list[int]) -> list[int]: - """ - Sort a list of atoms by their distance from a target atom. - - Parameters - ---------- - target_idx : int - The idx of the target atom. - atom_idxs : list[int] - The idx values of the atoms to sort. - rdmol : ??? - RDKit Molecule the atoms belong to - - Returns - ------- - list[int] - The input atom idxs sorted by their distance from the target atom. - """ - distances = [] - - conformer = rdmol.GetConformer() - # Get the target atom position - target_pos = conformer.GetAtomPosition(target_idx) - - for idx in atom_idxs: - pos = conformer.GetAtomPosition(idx) - distances.append(((target_pos - pos).Length(), idx)) - - return [i[1] for i in sorted(distances)] - - def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): angles = [] - + # Get the base atom and its neighbors at1 = rdmol.GetAtomWithIdx(atom_idx) at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] @@ -271,8 +266,7 @@ def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): for at2 in atom_pool: if at2 in at1_neighbors: at2_neighbors = [ - at.GetIdx() - for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() + at.GetIdx() for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() ] for at3 in atom_pool: if at3 != atom_idx and at3 in at2_neighbors: @@ -283,12 +277,12 @@ def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: """ Get a list of ligand anchor atoms (e.g. l1, l2, and l3 of an orientational restraint). - + Parameters ---------- rdmol : ??? Molecule object for the ligand to apply a restraint to. - + Returns ------- angles : list[tuple[int, int, int]] @@ -304,7 +298,7 @@ def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: # If there are not enough aromatic atoms, then default to heavy atoms if len(anchor_pool) < 3: anchor_pool = _get_heavy_atoms(rdmol) - + # Raise an error if we have less than 3 anchors if len(anchor_pool) < 3: errmsg = f"Too few potential ligand anchor atoms, {len(anchor_pool)}" @@ -316,15 +310,15 @@ def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: # Get a list of ligand anchor angle atoms angles = [] for atom in sorted_anchor_pool: - angles.extend( - _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) - ) + angles.extend(_get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool)) -def get_host_anchors(positions, topology, exclude_resids: list[int], lig_anchor_idx: int, selection: str): +def get_host_anchors( + positions, topology, exclude_resids: list[int], lig_anchor_idx: int, selection: str +): """ Get a list of host anchor atomss sorted by their distance from a ligand anchor atom. - + Parameters ---------- positions : openmm.unit.Quantity @@ -341,30 +335,35 @@ def get_host_anchors(positions, topology, exclude_resids: list[int], lig_anchor_ # Create an mdtraj trajectory to manipulate # First fetch the box vectors and pass them as lengths and angles vectors = from_openmm(topology.getPeriodicBoxVectors()) - a, b, c, alpha, beta, gamma = mdt.utils.box_vectors_to_lengths_and_angles(vectors[0].m, vectors[1].m, vectors[2].m) - + a, b, c, alpha, beta, gamma = mdt.utils.box_vectors_to_lengths_and_angles( + vectors[0].m, vectors[1].m, vectors[2].m + ) + traj = mdt.Trajectory( - positions[np.newaxis, ...], - mdt.Topology.from_openmm(topology) + positions[np.newaxis, ...], mdt.Topology.from_openmm(topology) ) - + # Get all the potential protein atoms matching the selection host_sel = traj.topology.select(selection) - + # Get residues to exclude from the selection - exclude_sel = np.array([ - at.index for at in - chain(*[traj.topology.residue(i).atoms for i in exclude_resids]) - ]) - + exclude_sel = np.array( + [ + at.index + for at in chain(*[traj.topology.residue(i).atoms for i in exclude_resids]) + ] + ) + # Remove exclusion anchors = host_sel[np.isin(host_sel, exclude_sel, invert=True)] - + # Compute distanecs from ligand l1 anchor atom - pairs = np.vstack((anchors, np.array([lig_anchor_idx for _ in range(len(anchors))]))).T - + pairs = np.vstack( + (anchors, np.array([lig_anchor_idx for _ in range(len(anchors))])) + ).T + distances = mdt.compute_distances(traj, pairs, periodic=True) - + return np.array([pairs[i][0] for i in np.argsort(distances[0])]) @@ -395,7 +394,9 @@ def is_collinear(positions, atoms, threshold=0.9): for i in range(len(atoms) - 2): v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] - normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) + normalized_inner_product = np.dot(v1, v2) / np.sqrt( + np.dot(v1, v1) * np.dot(v2, v2) + ) result = result or (np.abs(normalized_inner_product) > threshold) return result @@ -403,7 +404,7 @@ def is_collinear(positions, atoms, threshold=0.9): def check_angle(angle, force_constant=83.68): """ Check whether the chosen angle is less than 10 kT from 0 or 180 - + Parameters ---------- angle : float @@ -417,19 +418,17 @@ def check_angle(angle, force_constant=83.68): """ # TODO: convert this to unit.Quantity so we don't end up with # conversion errors - RT = 8.31445985 * 0.001 * 298.15 + RT = 8.31445985 * 0.001 * 298.15 # check if angle is <10kT from 0 or 180 check1 = 0.5 * force_constant * np.power((angle - 0.0) / 180.0 * np.pi, 2) check2 = 0.5 * force_constant * np.power((angle - 180.0) / 180.0 * np.pi, 2) ang_check_1 = check1 / RT ang_check_2 = check2 / RT - if ang_check_1 < 10.0 or ang_check_2 < 10.0: + if ang_check_1 < 10.0 or ang_check_2 < 10.0: return False return True - - class FindHostAtoms(AnalysisBase): """ Class filter host atoms based on their distance @@ -441,17 +440,28 @@ class FindHostAtoms(AnalysisBase): Initial selection of host atoms to filter from. guest_atoms : MDANalysis.AtomGroup Selection of guest atoms to search around. - search_distance: unit.Quantity - Distance to filter atoms within. + min_search_distance: unit.Quantity + Minimum distance to filter atoms within. + max_search_distance: unit.Quantity + Maximum distance to filter atoms within. """ + _analysis_algorithm_is_parallelizable = False - def __init__(self, host_atoms, guest_atoms, search_distance, **kwargs): + def __init__( + self, + host_atoms, + guest_atoms, + min_search_distance, + max_search_distance, + **kwargs, + ): super().__init__(host_atoms.universe.trajectory, **kwargs) self.host_ag = host_atoms self.guest_ag = guest_atoms - self.cutoff = search_distance.to('angstrom').m + self.min_cutoff = min_search_distance.to("angstrom").m + self.max_cutoff = max_search_distance.to("angstrom").m def _prepare(self): self.results.host_idxs = set() @@ -460,19 +470,22 @@ def _single_frame(self): pairs = capped_distance( reference=self.host_ag.positions, configuration=self.guest_ag.positions, - max_cutoff=self.cutoff, - min_cutoff=None + max_cutoff=self.max_cutoff, + min_cutoff=self.min_cutoff, box=self.guest_ag.universe.dimensions, - return_distances=False) + return_distances=False, + ) - host_idxs = [self.guest_ag.atoms[p].index for p in pairs[:, 1]] + host_idxs = [self.guest_ag.atoms[p].ix for p in pairs[:, 1]] self.results.host_idxs.update(set(host_idxs)) def _conclude(self): - pass + self.results.host_idxs = np.array(self.results.host_idxs) -def find_host_atoms(topology, trajectory, host_selection, guest_selection, cutoff) -> mda.AtomGroup: +def find_host_atoms( + topology, trajectory, host_selection, guest_selection, cutoff +) -> mda.AtomGroup: """ Get an AtomGroup of the host atoms based on their distances from the guest atoms. """ @@ -487,7 +500,7 @@ def _get_selection(selection): else: ag = u.atoms[host_ag] return ag - + host_ag = _get_selection(host_selection) guest_ag = _get_selection(guest_selection) @@ -496,24 +509,29 @@ def _get_selection(selection): return u.atoms[list(finder.results.host_idxs)] -def get_molecule_center_idx(atomgroup): - offmol = Molecule(atomgroup.convert_to("RDKIT"), allow_undefined_stereo=True) - # Check if the molecule is whole, otherwise throw an error. - nx = offmol.to_networkx() +def get_local_rmsf(atomgroup: mda.AtomGroup): + """ + Get the RMSF of an AtomGroup when aligned upon itself. -def get_distance_restraint(topology, trajectory, host_atoms, guest_atoms, host_selection, guest_selection): - u = mda.Universe(topology, trajectory) + Parameters + ---------- + atomgroup : MDAnalysis.AtomGroup - if guest_atoms is None: - if guest_selection is None: - raise ValueError("one of guest_atoms or guest_selections must be defined") - guest_ag = u.select_atoms(guest_selection) - else: + Return + ------ + rmsf + ArrayQuantity of RMSF values. + """ + # First let's copy our Universe + copy_u = atomgroup.universe.copy() + ag = copy_u.atoms[atomgroup.atoms.ix] + nojump = NoJump(ag) + align = Aligner(ag) - if host_atoms is None: - if host_selection is None: - raise ValueError("one of host_atoms or host_selection must be defined") + copy_u.trajectory.add_transformations(nojump, align) - host_ag = u.select_atoms(host_selection) + rmsf = RMSF(ag) + rmsf.run() + return rmsf.results.rmsf * unit.angstrom From 7a7be903a62ca03ecfa76326e621636e78cb9537 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 21:21:30 +0000 Subject: [PATCH 083/163] fix up weird black wrapping --- .../openmm_utils/restraints/geometry/utils.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index c8226af0d..82e7e621f 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -26,6 +26,10 @@ from openfe_analysis.transformations import Aligner, NoJump +DEFAULT_ANGLE_FRC_CONSTANT = 83.68 * unit.kilojoule_per_mole / unit.radians**2 +ANGLE_FRC_CONSTANT_TYPE = FloatQuantity["unit.kilojoule_per_mole / unit.radians**2"] + + def get_aromatic_rings(rdmol: Chem.Mol) -> list[tuple[int, ...]]: """ Get a list of tuples with the indices for each ring in an rdkit Molecule. @@ -156,9 +160,7 @@ def is_collinear(positions, atoms, threshold=0.9): def check_angle_energy( angle: FloatQuantity["radians"], - force_constant: FloatQuantity["unit.kilojoule_per_mole / unit.radians**2"] = 83.68 - * unit.kilojoule_per_mole - / unit.radians**2, + force_constant: ANGLE_FRC_CONSTANT_TYPE = DEFAULT_ANGLE_FRC_CONSTANT, temperature: FloatQuantity["kelvin"] = 298.15 * unit.kelvin, ) -> bool: """ @@ -170,10 +172,9 @@ def check_angle_energy( The angle to check in units compatible with radians. force_constant : unit.Quantity Force constant of the angle in units compatible with kilojoule_per_mole / radians ** 2. - temperature: unit.Quantity + temperature : unit.Quantity The system temperature in units compatible with Kelvin. - Returns ------- bool From 733f3b3c681a1112d081e043f7866cb198fbf3aa Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 21:47:56 +0000 Subject: [PATCH 084/163] remove old search file, add more changes to boresch search --- .../restraints/geometry/boresch.py | 111 ++++-- .../openmm_utils/restraints/search.py | 360 ------------------ 2 files changed, 83 insertions(+), 388 deletions(-) delete mode 100644 openfe/protocols/openmm_utils/restraints/search.py diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index d6241f3d7..a35c4f5a9 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -15,6 +15,8 @@ from openff.units import unit import MDAnalysis as mda from MDAnalysis.lib.distances import calc_bonds, calc_angles +import numpy as np +import numpy.typing as npt from .base import HostGuestRestraintGeometry @@ -152,19 +154,84 @@ def _get_bonded_angles_from_pool( return angles -def get_small_molecule_atom_candidates( +def _get_atom_pool(rdmol: Chem.Mol, rmsf: npt.NDArray) -> Optional[set[int]]: + """ + Filter atoms based on rmsf & rings, defaulting to heavy atoms if + there are not enough. + + Parameters + ---------- + rdmol : Chem.Mol + The RDKit Molecule to search through + rmsf : npt.NDArray + A 1-D array of RMSF values for each atom. + + Returns + ------- + atom_pool : Optional[set[int]] + """ + # Get a list of all the aromatic rings + # Note: no need to keep track of rings because we'll filter by + # bonded terms after, so if we only keep rings then all the bonded + # atoms should be within the same ring system. + atom_pool = set() + for ring in get_aromatic_rings(rdmol): + max_rmsf = rmsf[list(ring)].max() + if max_rmsf < rmsf_cutoff: + atom_pool.update(ring) + + # if we don't have enough atoms just get all the heavy atoms + if len(atom_pool) < 3: + heavy_atoms = get_heavy_atom_idxs(rdmol) + atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) + if len(atom_pool) < 3: + return None + + return atom_pool + + +def get_small_molecule_guest_atom_candidates( topology: Union[str, openmm.app.Topology], trajectory: Union[str, pathlib.Path], rdmol: Chem.Mol, ligand_idxs: list[int], rmsf_cutoff: unit.Quantity = 1 * unit.angstrom, - angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, -): + angle_force_constant: unit.Quantity = 83.68 * unit.kilojoule_per_mole / unit.radians**2, +) -> list[tuple[int]]: """ Get a list of potential ligand atom choices for a Boresch restraint being applied to a given small molecule. - TODO: remember to update the RDMol with the last frame positions + Parameters + ---------- + topology : Union[str, openmm.app.Topology] + The topology of the system. + trajectory : Union[str, pathlib.Path] + A path to the system's coordinate trajectory. + rdmol : Chem.Mol + An RDKit Molecule representing the small molecule ordered in + the same way as it is listed in the topology. + ligand_idxs : list[int] + The ligand indices in the topology. + rmsf_cutoff : unit.Quantity + The RMSF filter cut-off. + angle_force_constant : unit.Quantity + The force constant for the l1-l2-l3 atom angle. + + Returns + ------- + angle_list : list[tuple[int]] + A list of tuples for each valid l1, l2, l3 angle. If ``None``, no + angles could be found. + + Raises + ------ + ValueError + If no suitable ligand atoms could be found. + + TODO + ---- + Remember to update the RDMol with the last frame positions. """ if isinstance(topology, openmm.app.Topology): topology_format = "OPENMMTOPOLOGY" @@ -179,26 +246,12 @@ def get_small_molecule_atom_candidates( u.trajectory[-1] # forward to the last frame # 1. Get the pool of atoms to work with - # TODO: move to a helper function to make it easier to test - # Get a list of all the aromatic rings - # Note: no need to keep track of rings because we'll filter by - # bonded terms after, so if we only keep rings then all the bonded - # atoms should be within the same ring system. - atom_pool = set() - for ring in get_aromatic_rings(rdmol): - max_rmsf = rmsf[list(ring)].max() - if max_rmsf < rmsf_cutoff: - atom_pool.update(ring) + atom_pool = _get_atom_pool(rdmol: Chem.Mol, rmsf: npt.NDArray) - # if we don't have enough atoms just get all the heavy atoms - if len(atom_pool) < 3: - heavy_atoms = get_heavy_atom_idxs(rdmol) - atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) - if len(atom_pool) < 3: - errmsg = ( - "No suitable ligand atoms for " "the boresch restraint could be found" - ) - raise ValueError(errmsg) + if atom_pool is None: + # We don't have enough atoms so we raise an error + errmsg = "No suitable ligand atoms were found for the restraint" + raise ValueError(errmsg) # 2. Get the central atom center = get_central_atom_idx(rdmol) @@ -211,7 +264,7 @@ def get_small_molecule_atom_candidates( for atom in sorted_anchor_pool: angles = _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) for angle in _angles: - angle_ag = ligand_ag.atoms[angle] + angle_ag = ligand_ag.atoms[list(angle)] collinear = is_collinear(ligand_ag.positions, angle) angle_value = ( calc_angle( @@ -219,8 +272,7 @@ def get_small_molecule_atom_candidates( angle_ag.atoms[1].position, angle_ag.atoms[2].position, box=angle_ag.universe.dimensions, - ) - * unit.radians + ) * unit.radians ) energy = check_angle_energy( angle_value, angle_force_constant, 298.15 * unit.kelvin @@ -239,10 +291,13 @@ def get_host_atom_candidates( host_selection: str, dssp_filter: bool = False, rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, - min_distance: unit.Quantity = 10 * unit.nanometer, - max_distance: unit.Quantity = 30 * unit.nanometer, + min_distance: unit.Quantity = 1 * unit.nanometer, + max_distance: unit.Quantity = 3 * unit.nanometer, angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, ): + """ + + """ if isinstance(topology, openmm.app.Topology): topology_format = "OPENMMTOPOLOGY" else: diff --git a/openfe/protocols/openmm_utils/restraints/search.py b/openfe/protocols/openmm_utils/restraints/search.py deleted file mode 100644 index 6b3d94eb7..000000000 --- a/openfe/protocols/openmm_utils/restraints/search.py +++ /dev/null @@ -1,360 +0,0 @@ -# This code is part of OpenFE and is licensed under the MIT license. -# For details, see https://github.com/OpenFreeEnergy/openfe -""" -Search methods for generating Geometry objects - -TODO ----- -* Add relevant duecredit entries. -""" -import abc -from pydantic.v1 import BaseModel, validator - -from openff.toolkit import Molecule as OFFMol -from openff.units import unit -import networkx as nx -import MDAnalysis as mda -from MDAnalysis.analysis.base import AnalysisBase -from MDAnalysis.lib.distances import calc_bonds, calc_angles - - -def _get_aromatic_atom_idxs(rdmol) -> list[int]: - """ - Helper method to get aromatic atoms idxs - in a RDKit Molecule - - Parameters - ---------- - rdmol : ??? - RDKit Molecule - - Returns - ------- - list[int] - A list of the aromatic atom idxs - """ - idxs = [ - at.GetIdx() for at in rdmol.GetAtoms() - if at.GetIsAromatic() - ] - return idxs - - -def _get_heavy_atom_idxs(rdmol) -> list[int]: - """ - Get idxs of heavy atoms in an RDKit Molecule - - Parameters - ---------- - rmdol : ??? - - Returns - ------- - list[int] - A list of heavy atom idxs - """ - idxs = [ - at.GetIdx() for at in rdmol.GetAtoms() - if at.GetAtomicNum() > 1 - ] - return idxs - - -def _get_central_atom_idx(rdmol) -> int: - offmol = OFFMol(rdmol, allow_undefined_stereo=True) - # We take the zero-th entry if there are multiple center - # atoms (e.g. equal likelihood centers) - center = nx.center(offmol.to_networkx())[0] - return center - - -def _sort_by_distance_from_target(rdmol, target_idx: int, atom_idxs: list[int]) -> list[int]: - """ - Sort a list of atoms by their distance from a target atom. - - Parameters - ---------- - target_idx : int - The idx of the target atom. - atom_idxs : list[int] - The idx values of the atoms to sort. - rdmol : ??? - RDKit Molecule the atoms belong to - - Returns - ------- - list[int] - The input atom idxs sorted by their distance from the target atom. - """ - distances = [] - - conformer = rdmol.GetConformer() - # Get the target atom position - target_pos = conformer.GetAtomPosition(target_idx) - - for idx in atom_idxs: - pos = conformer.GetAtomPosition(idx) - distances.append(((target_pos - pos).Length(), idx)) - - return [i[1] for i in sorted(distances)] - - -def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): - angles = [] - - # Get the base atom and its neighbors - at1 = rdmol.GetAtomWithIdx(atom_idx) - at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] - - # We loop at2 and at3 through the sorted atom_pool in order to get - # a list of angles in the branch that are sorted by how close the atoms - # are from the central atom - for at2 in atom_pool: - if at2 in at1_neighbors: - at2_neighbors = [ - at.GetIdx() - for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() - ] - for at3 in atom_pool: - if at3 != atom_idx and at3 in at2_neighbors: - angles.append((atom_idx, at2, at3)) - return angles - - -def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: - """ - Get a list of ligand anchor atoms (e.g. l1, l2, and l3 of an orientational restraint). - - Parameters - ---------- - rdmol : ??? - Molecule object for the ligand to apply a restraint to. - - Returns - ------- - angles : list[tuple[int, int, int]] - A list of ligand atom triples denoting the possible l1, l2, and l3 - restraint atoms. Ordered by likelihood of restraint-ability. - """ - # Find the central atom - center = _get_central_atom_idx(rdmol) - - # Get a pool of potential anchor atoms looking for aromatic atoms - anchor_pool = _get_aromatic_atoms(rdmol) - - # If there are not enough aromatic atoms, then default to heavy atoms - if len(anchor_pool) < 3: - anchor_pool = _get_heavy_atoms(rdmol) - - # Raise an error if we have less than 3 anchors - if len(anchor_pool) < 3: - errmsg = f"Too few potential ligand anchor atoms, {len(anchor_pool)}" - raise ValueError(errmsg) - - # Sort the pool of anchor atoms by their distance from the central atom - sorted_anchor_pool = _sort_by_distance_from_target(rdmol, center, anchor_pool) - - # Get a list of ligand anchor angle atoms - angles = [] - for atom in sorted_anchor_pool: - angles.extend( - _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) - ) - - -def get_host_anchors(positions, topology, exclude_resids: list[int], lig_anchor_idx: int, selection: str): - """ - Get a list of host anchor atomss sorted by their distance from a ligand anchor atom. - - Parameters - ---------- - positions : openmm.unit.Quantity - Positions of the input system - topology : openmm.app.Topology - OpenMM Topology for input system - exclude_resids : list[int] - List of residue numbers to exclude from host selection - lig_anchor_idx : int - The index of the l1 ligand anchor. - selection : str - Selection string for the host atoms. - """ - # Create an mdtraj trajectory to manipulate - # First fetch the box vectors and pass them as lengths and angles - vectors = from_openmm(topology.getPeriodicBoxVectors()) - a, b, c, alpha, beta, gamma = mdt.utils.box_vectors_to_lengths_and_angles(vectors[0].m, vectors[1].m, vectors[2].m) - - traj = mdt.Trajectory( - positions[np.newaxis, ...], - mdt.Topology.from_openmm(topology) - ) - - # Get all the potential protein atoms matching the selection - host_sel = traj.topology.select(selection) - - # Get residues to exclude from the selection - exclude_sel = np.array([ - at.index for at in - chain(*[traj.topology.residue(i).atoms for i in exclude_resids]) - ]) - - # Remove exclusion - anchors = host_sel[np.isin(host_sel, exclude_sel, invert=True)] - - # Compute distanecs from ligand l1 anchor atom - pairs = np.vstack((anchors, np.array([lig_anchor_idx for _ in range(len(anchors))]))).T - - distances = mdt.compute_distances(traj, pairs, periodic=True) - - return np.array([pairs[i][0] for i in np.argsort(distances[0])]) - - -def is_collinear(positions, atoms, threshold=0.9): - """ - Check whether any sequential vectors in a sequence of atoms are collinear. - - Parameters - ---------- - positions : openmm.unit.Quantity - System positions. - atoms : list[int] - The indices of the atoms to test. - threshold : float - Atoms are not collinear if their sequential vector separation dot - products are less than ``threshold``. Default 0.9. - - Returns - ------- - result : bool - Returns True if any sequential pair of vectors is collinear; False otherwise. - - Notes - ----- - Originally from Yank, with modifications from Separated Topologies - """ - results = False - for i in range(len(atoms) - 2): - v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] - v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] - normalized_inner_product = np.dot(v1, v2) / np.sqrt(np.dot(v1, v1) * np.dot(v2, v2)) - result = result or (np.abs(normalized_inner_product) > threshold) - return result - - -def check_angle(angle, force_constant=83.68): - """ - Check whether the chosen angle is less than 10 kT from 0 or 180 - - Parameters - ---------- - angle : float - The angle to check in degrees. - force_constant : float - Force constant of the angle. - - Note - ---- - We assume the temperature to be 298.15 Kelvin. - """ - # TODO: convert this to unit.Quantity so we don't end up with - # conversion errors - RT = 8.31445985 * 0.001 * 298.15 - # check if angle is <10kT from 0 or 180 - check1 = 0.5 * force_constant * np.power((angle - 0.0) / 180.0 * np.pi, 2) - check2 = 0.5 * force_constant * np.power((angle - 180.0) / 180.0 * np.pi, 2) - ang_check_1 = check1 / RT - ang_check_2 = check2 / RT - if ang_check_1 < 10.0 or ang_check_2 < 10.0: - return False - return True - - - - -class FindHostAtoms(AnalysisBase): - """ - Class filter host atoms based on their distance - from a set of guest atoms. - - Parameters - ---------- - host_atoms : MDAnalysis.AtomGroup - Initial selection of host atoms to filter from. - guest_atoms : MDANalysis.AtomGroup - Selection of guest atoms to search around. - search_distance: unit.Quantity - Distance to filter atoms within. - """ - _analysis_algorithm_is_parallelizable = False - - def __init__(self, host_atoms, guest_atoms, search_distance, **kwargs): - super().__init__(host_atoms.universe.trajectory, **kwargs) - - self.host_ag = host_atoms - self.guest_ag = guest_atoms - self.cutoff = search_distance.to('angstrom').m - - def _prepare(self): - self.results.host_idxs = set() - - def _single_frame(self): - pairs = capped_distance( - reference=self.host_ag.positions, - configuration=self.guest_ag.positions, - max_cutoff=self.cutoff, - min_cutoff=None - box=self.guest_ag.universe.dimensions, - return_distances=False) - - host_idxs = [self.guest_ag.atoms[p].index for p in pairs[:, 1]] - self.results.host_idxs.update(set(host_idxs)) - - def _conclude(self): - pass - - -def find_host_atoms(topology, trajectory, host_selection, guest_selection, cutoff) -> mda.AtomGroup: - """ - Get an AtomGroup of the host atoms based on their distances from the guest atoms. - """ - u = mda.Universe(topology, trajectory) - - def _get_selection(selection): - """ - If it's a str, call select_atoms, if not a list of atom idxs - """ - if isinstance(selection, str): - ag = u.select_atoms(host_selection) - else: - ag = u.atoms[host_ag] - return ag - - host_ag = _get_selection(host_selection) - guest_ag = _get_selection(guest_selection) - - finder = FindHostAtoms(host_ag, guest_ag, cutoff) - finder.run() - - return u.atoms[list(finder.results.host_idxs)] - -def get_molecule_center_idx(atomgroup): - offmol = Molecule(atomgroup.convert_to("RDKIT"), allow_undefined_stereo=True) - # Check if the molecule is whole, otherwise throw an error. - nx = offmol.to_networkx() - - -def get_distance_restraint(topology, trajectory, host_atoms, guest_atoms, host_selection, guest_selection): - u = mda.Universe(topology, trajectory) - - if guest_atoms is None: - if guest_selection is None: - raise ValueError("one of guest_atoms or guest_selections must be defined") - guest_ag = u.select_atoms(guest_selection) - else: - - - if host_atoms is None: - if host_selection is None: - raise ValueError("one of host_atoms or host_selection must be defined") - - host_ag = u.select_atoms(host_selection) From 96decfffe7036ab5cff19ad4453517957a3291dd Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 22:19:34 +0000 Subject: [PATCH 085/163] Remove duplicate methods --- .../restraints/geometry/boresch.py | 34 ++- .../openmm_utils/restraints/geometry/utils.py | 218 ++++-------------- 2 files changed, 75 insertions(+), 177 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index a35c4f5a9..cf14b73aa 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -37,6 +37,13 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): """ def get_bond_distance(self, topology, coordinates) -> unit.Quantity: + """ + Get the H2 - G0 distance + + Parameters + ---------- + topology : + """ u = mda.Universe(topology, coordinates) at1 = u.atoms[host_atoms[2]] at2 = u.atoms[guest_atoms[0]] @@ -293,10 +300,30 @@ def get_host_atom_candidates( rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, min_distance: unit.Quantity = 1 * unit.nanometer, max_distance: unit.Quantity = 3 * unit.nanometer, - angle_force_constant=83.68 * unit.kilojoule_per_mole / unit.radians**2, ): """ + Get a list of suitable host atoms. + Parameters + ---------- + topology : Union[str, openmm.app.Topology] + The topology of the system. + trajectory : Union[str, pathlib.Path] + A path to the system's coordinate trajectory. + host_idxs : list[int] + A list of the host indices in the system topology. + l1_idx : int + The index of the proposed l1 binding atom. + host_selection : str + An MDAnalysis selection string to fileter the host by. + dssp_filter : bool + Whether or not to apply a DSSP filter on the host selection. + rmsf_cutoff : uni.Quantity + The maximum RMSF value allowwed for any candidate host atom. + min_distance : unit.Quantity + The minimum search distance around l1 for suitable candidate atoms. + max_distance : unit.Quantity + The maximum search distance around l1 for suitable candidate atoms. """ if isinstance(topology, openmm.app.Topology): topology_format = "OPENMMTOPOLOGY" @@ -322,3 +349,8 @@ def get_host_atom_candidates( ) atom_finder.run() return atom_finder.results.host_idxs + + +def select_boresch_atoms( + +): diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index 82e7e621f..a74e83ed3 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -11,6 +11,7 @@ from pydantic.v1 import BaseModel, validator import numpy as np +import numpy.typing as npt from scipy.stats import circvar, circmean, circstd from openff.toolkit import Molecule as OFFMol @@ -22,6 +23,7 @@ from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.analysis.rmsf import RMSF from MDAnalysis.lib.distances import calc_bonds, calc_angles +from MDAnalysis.coordinates.memory import MemoryReader from openfe_analysis.transformations import Aligner, NoJump @@ -30,6 +32,46 @@ ANGLE_FRC_CONSTANT_TYPE = FloatQuantity["unit.kilojoule_per_mole / unit.radians**2"] +def _get_mda_coord_format(coordinates: Union[str, npt.NDArray]) -> Optional[MemoryReader]: + """ + Helper to set the coordinate format to MemoryReader + if the coordinates are an NDArray. + + Parameters + ---------- + coordinates : Union[str, npt.NDArray] + + Returns + ------- + Optional[MemoryReader] + Either the MemoryReader class or None. + """ + if isinstance(coordinates, npt.NDArray): + return MemoryReader + else: + return None + +def _get_mda_topology_format(topology: Union[str, openmm.app.Topology]) -> Optional[str]: + """ + Helper to set the topology format to OPENMMTOPOLOGY + if the topology is an openmm.app.Topology. + + Parameters + ---------- + topology : Union[str, openmm.app.Topology] + + + Returns + ------- + Optional[str] + The string `OPENMMTOPOLOGY` or None. + """ + if isinstance(topology, openmm.app.Topology): + return "OPENMMTOPOLOGY" + else: + return None + + def get_aromatic_rings(rdmol: Chem.Mol) -> list[tuple[int, ...]]: """ Get a list of tuples with the indices for each ring in an rdkit Molecule. @@ -254,182 +296,6 @@ def check_angular_variance( return not (variance * unit.radians > width) -def _get_bonded_angles_from_pool(rdmol, atom_idx, atom_pool): - angles = [] - - # Get the base atom and its neighbors - at1 = rdmol.GetAtomWithIdx(atom_idx) - at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] - - # We loop at2 and at3 through the sorted atom_pool in order to get - # a list of angles in the branch that are sorted by how close the atoms - # are from the central atom - for at2 in atom_pool: - if at2 in at1_neighbors: - at2_neighbors = [ - at.GetIdx() for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() - ] - for at3 in atom_pool: - if at3 != atom_idx and at3 in at2_neighbors: - angles.append((atom_idx, at2, at3)) - return angles - - -def get_ligand_anchor_atoms(rdmol) -> list[tuple[int, int, int]]: - """ - Get a list of ligand anchor atoms (e.g. l1, l2, and l3 of an orientational restraint). - - Parameters - ---------- - rdmol : ??? - Molecule object for the ligand to apply a restraint to. - - Returns - ------- - angles : list[tuple[int, int, int]] - A list of ligand atom triples denoting the possible l1, l2, and l3 - restraint atoms. Ordered by likelihood of restraint-ability. - """ - # Find the central atom - center = _get_central_atom_idx(rdmol) - - # Get a pool of potential anchor atoms looking for aromatic atoms - anchor_pool = _get_aromatic_atoms(rdmol) - - # If there are not enough aromatic atoms, then default to heavy atoms - if len(anchor_pool) < 3: - anchor_pool = _get_heavy_atoms(rdmol) - - # Raise an error if we have less than 3 anchors - if len(anchor_pool) < 3: - errmsg = f"Too few potential ligand anchor atoms, {len(anchor_pool)}" - raise ValueError(errmsg) - - # Sort the pool of anchor atoms by their distance from the central atom - sorted_anchor_pool = _sort_by_distance_from_target(rdmol, center, anchor_pool) - - # Get a list of ligand anchor angle atoms - angles = [] - for atom in sorted_anchor_pool: - angles.extend(_get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool)) - - -def get_host_anchors( - positions, topology, exclude_resids: list[int], lig_anchor_idx: int, selection: str -): - """ - Get a list of host anchor atomss sorted by their distance from a ligand anchor atom. - - Parameters - ---------- - positions : openmm.unit.Quantity - Positions of the input system - topology : openmm.app.Topology - OpenMM Topology for input system - exclude_resids : list[int] - List of residue numbers to exclude from host selection - lig_anchor_idx : int - The index of the l1 ligand anchor. - selection : str - Selection string for the host atoms. - """ - # Create an mdtraj trajectory to manipulate - # First fetch the box vectors and pass them as lengths and angles - vectors = from_openmm(topology.getPeriodicBoxVectors()) - a, b, c, alpha, beta, gamma = mdt.utils.box_vectors_to_lengths_and_angles( - vectors[0].m, vectors[1].m, vectors[2].m - ) - - traj = mdt.Trajectory( - positions[np.newaxis, ...], mdt.Topology.from_openmm(topology) - ) - - # Get all the potential protein atoms matching the selection - host_sel = traj.topology.select(selection) - - # Get residues to exclude from the selection - exclude_sel = np.array( - [ - at.index - for at in chain(*[traj.topology.residue(i).atoms for i in exclude_resids]) - ] - ) - - # Remove exclusion - anchors = host_sel[np.isin(host_sel, exclude_sel, invert=True)] - - # Compute distanecs from ligand l1 anchor atom - pairs = np.vstack( - (anchors, np.array([lig_anchor_idx for _ in range(len(anchors))])) - ).T - - distances = mdt.compute_distances(traj, pairs, periodic=True) - - return np.array([pairs[i][0] for i in np.argsort(distances[0])]) - - -def is_collinear(positions, atoms, threshold=0.9): - """ - Check whether any sequential vectors in a sequence of atoms are collinear. - - Parameters - ---------- - positions : openmm.unit.Quantity - System positions. - atoms : list[int] - The indices of the atoms to test. - threshold : float - Atoms are not collinear if their sequential vector separation dot - products are less than ``threshold``. Default 0.9. - - Returns - ------- - result : bool - Returns True if any sequential pair of vectors is collinear; False otherwise. - - Notes - ----- - Originally from Yank, with modifications from Separated Topologies - """ - results = False - for i in range(len(atoms) - 2): - v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] - v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] - normalized_inner_product = np.dot(v1, v2) / np.sqrt( - np.dot(v1, v1) * np.dot(v2, v2) - ) - result = result or (np.abs(normalized_inner_product) > threshold) - return result - - -def check_angle(angle, force_constant=83.68): - """ - Check whether the chosen angle is less than 10 kT from 0 or 180 - - Parameters - ---------- - angle : float - The angle to check in degrees. - force_constant : float - Force constant of the angle. - - Note - ---- - We assume the temperature to be 298.15 Kelvin. - """ - # TODO: convert this to unit.Quantity so we don't end up with - # conversion errors - RT = 8.31445985 * 0.001 * 298.15 - # check if angle is <10kT from 0 or 180 - check1 = 0.5 * force_constant * np.power((angle - 0.0) / 180.0 * np.pi, 2) - check2 = 0.5 * force_constant * np.power((angle - 180.0) / 180.0 * np.pi, 2) - ang_check_1 = check1 / RT - ang_check_2 = check2 / RT - if ang_check_1 < 10.0 or ang_check_2 < 10.0: - return False - return True - - class FindHostAtoms(AnalysisBase): """ Class filter host atoms based on their distance From 2d97de82dc762f5f294e503282efcbe7bb0f03bf Mon Sep 17 00:00:00 2001 From: Irfan Alibay Date: Thu, 12 Dec 2024 22:21:50 +0000 Subject: [PATCH 086/163] Apply suggestions from code review --- .../openmm_utils/restraints/openmm/omm_restraints.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py index e53e828d5..a3fe777d3 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py @@ -125,7 +125,7 @@ def _verify_geometry(self, geometry: BaseRestraintGeometry): super()._verify_geometry(geometry) -class BaseRadialllySymmetricRestraintForce(BaseHostGuestRestraints): +class BaseRadiallySymmetricRestraintForce(BaseHostGuestRestraints): def _verify_inputs(self) -> None: if not isinstance(self.settings, BaseDistanceRestraintSettings): errmsg = f"Incorrect settings type {self.settings} passed through" @@ -162,7 +162,7 @@ def _get_force(self, geometry: DistanceRestraintGeometry): raise NotImplementedError("only implemented in child classes") -class HarmonicBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): +class HarmonicBondRestraint(BaseRadiallySymmetricRestraintForce, SingleBondMixin): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintBondForce( @@ -173,7 +173,7 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: ) -class FlatBottomBondRestraint(BaseRadialllySymmetricRestraintForce, SingleBondMixin): +class FlatBottomBondRestraint(BaseRadiallySymmetricRestraintForce, SingleBondMixin): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) @@ -186,7 +186,7 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: ) -class CentroidHarmonicRestraint(BaseRadialllySymmetricRestraintForce): +class CentroidHarmonicRestraint(BaseRadiallySymmetricRestraintForce): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintForce( @@ -197,7 +197,7 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: ) -class CentroidFlatBottomRestraint(BaseRadialllySymmetricRestraintForce): +class CentroidFlatBottomRestraint(BaseRadiallySymmetricRestraintForce): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) From 116ba64b0cb29acf69124a7743fc74c2d24815c7 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Thu, 12 Dec 2024 22:33:09 +0000 Subject: [PATCH 087/163] Add some more docstring --- .../restraints/geometry/boresch.py | 72 ++++++++++++------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index cf14b73aa..cfaf443dc 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -35,23 +35,48 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): Where HX represents the X index of ``host_atoms`` and GX the X index of ``guest_atoms``. """ - - def get_bond_distance(self, topology, coordinates) -> unit.Quantity: + def get_bond_distance( + self, + topology: Union[str, openmm.app.Topology], + coordinates: Union[str, npt.NDArray], + ) -> unit.Quantity: """ - Get the H2 - G0 distance + Get the H2 - G0 distance. Parameters ---------- - topology : + topology : Union[str, openmm.app.Topology] + coordinates : Union[str, npt.NDArray] + A coordinate file or NDArray in frame-atom-coordinate + order in Angstrom. """ - u = mda.Universe(topology, coordinates) + u = mda.Universe( + topology, + coordinates, + format=_get_mda_coord_format(coordinates), + topology_format=_get_mda_topology_format(topology) + ) at1 = u.atoms[host_atoms[2]] at2 = u.atoms[guest_atoms[0]] bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) # convert to float so we avoid having a np.float64 return float(bond) * unit.angstrom - def get_angles(self, topology, coordinates) -> unit.Quantity: + def get_angles( + self, + topology: Union[str, openmm.app.Topology], + coordinates: Union[str, npt.NDArray], + ) -> unit.Quantity: + """ + Get the H1-H2-G0, and H2-G0-G1 angles. + + Parameters + ---------- + topology : Union[str, openmm.app.Topology] + coordinates : Union[str, npt.NDArray] + A coordinate file or NDArray in frame-atom-coordinate + order in Angstrom. + """ u = mda.Universe(topology, coordinates) at1 = u.atoms[host_atoms[1]] at2 = u.atoms[host_atoms[2]] @@ -66,7 +91,21 @@ def get_angles(self, topology, coordinates) -> unit.Quantity: ) return angleA, angleB - def get_dihedrals(self, topology, coordinates) -> unit.Quantity: + def get_dihedrals( + self, + topology: Union[str, openmm.app.Topology], + coordinates: Union[str, npt.NDArray], + ) -> unit.Quantity: + """ + Get the H0-H1-H2-G0, H1-H2-G0-G1, and H2-G0-G1-G2 dihedrals. + + Parameters + ---------- + topology : Union[str, openmm.app.Topology] + coordinates : Union[str, npt.NDArray] + A coordinate file or NDArray in frame-atom-coordinate + order in Angstrom. + """ u = mda.Universe(topology, coordinates) at1 = u.atoms[host_atoms[0]] at2 = u.atoms[host_atoms[1]] @@ -84,7 +123,6 @@ def get_dihedrals(self, topology, coordinates) -> unit.Quantity: dihC = calc_dihedrals( at3.position, at4.position, at5.position, at6.position, u.atoms.dimensions ) - return dihA, dihB, dihC @@ -203,7 +241,6 @@ def get_small_molecule_guest_atom_candidates( rdmol: Chem.Mol, ligand_idxs: list[int], rmsf_cutoff: unit.Quantity = 1 * unit.angstrom, - angle_force_constant: unit.Quantity = 83.68 * unit.kilojoule_per_mole / unit.radians**2, ) -> list[tuple[int]]: """ Get a list of potential ligand atom choices for a Boresch restraint @@ -222,8 +259,6 @@ def get_small_molecule_guest_atom_candidates( The ligand indices in the topology. rmsf_cutoff : unit.Quantity The RMSF filter cut-off. - angle_force_constant : unit.Quantity - The force constant for the l1-l2-l3 atom angle. Returns ------- @@ -271,20 +306,9 @@ def get_small_molecule_guest_atom_candidates( for atom in sorted_anchor_pool: angles = _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) for angle in _angles: + # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] - collinear = is_collinear(ligand_ag.positions, angle) - angle_value = ( - calc_angle( - angle_ag.atoms[0].position, - angle_ag.atoms[1].position, - angle_ag.atoms[2].position, - box=angle_ag.universe.dimensions, - ) * unit.radians - ) - energy = check_angle_energy( - angle_value, angle_force_constant, 298.15 * unit.kelvin - ) - if not collinear and energy: + if not is_collinear(ligand_ag.positions, angle): angles_list.append(angle) return angles_list From 9ae60da278e4c54eaf2f98feaf2387bef09a76a7 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 13 Dec 2024 01:20:40 +0000 Subject: [PATCH 088/163] Add minimized vectors on the collinear checks --- .../restraints/geometry/boresch.py | 181 +++++++++++++++--- .../openmm_utils/restraints/geometry/utils.py | 26 ++- 2 files changed, 168 insertions(+), 39 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index cfaf443dc..363e22c6b 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -8,13 +8,15 @@ * Add relevant duecredit entries. """ import abc +import pathlib from pydantic.v1 import BaseModel, validator from rdkit import Chem from openff.units import unit import MDAnalysis as mda -from MDAnalysis.lib.distances import calc_bonds, calc_angles +from MDANalysis.analysis.base import AnalysisBase +from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals import numpy as np import numpy.typing as npt @@ -37,8 +39,8 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): """ def get_bond_distance( self, - topology: Union[str, openmm.app.Topology], - coordinates: Union[str, npt.NDArray], + topology: Union[str, pathlib.Path, openmm.app.Topology], + coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ Get the H2 - G0 distance. @@ -64,8 +66,8 @@ def get_bond_distance( def get_angles( self, - topology: Union[str, openmm.app.Topology], - coordinates: Union[str, npt.NDArray], + topology: Union[str, pathlib.Path, openmm.app.Topology], + coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ Get the H1-H2-G0, and H2-G0-G1 angles. @@ -77,7 +79,12 @@ def get_angles( A coordinate file or NDArray in frame-atom-coordinate order in Angstrom. """ - u = mda.Universe(topology, coordinates) + u = mda.Universe( + topology, + coordinates, + format=_get_mda_coord_format(coordinates), + topology_format=_get_mda_topology_format(topology) + ) at1 = u.atoms[host_atoms[1]] at2 = u.atoms[host_atoms[2]] at3 = u.atoms[guest_atoms[0]] @@ -93,8 +100,8 @@ def get_angles( def get_dihedrals( self, - topology: Union[str, openmm.app.Topology], - coordinates: Union[str, npt.NDArray], + topology: Union[str, pathlib.Path, openmm.app.Topology], + coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ Get the H0-H1-H2-G0, H1-H2-G0-G1, and H2-G0-G1-G2 dihedrals. @@ -106,7 +113,12 @@ def get_dihedrals( A coordinate file or NDArray in frame-atom-coordinate order in Angstrom. """ - u = mda.Universe(topology, coordinates) + u = mda.Universe( + topology, + coordinates, + format=_get_mda_coord_format(coordinates), + topology_format=_get_mda_topology_format(topology) + ) at1 = u.atoms[host_atoms[0]] at2 = u.atoms[host_atoms[1]] at3 = u.atoms[host_atoms[2]] @@ -235,12 +247,12 @@ def _get_atom_pool(rdmol: Chem.Mol, rmsf: npt.NDArray) -> Optional[set[int]]: return atom_pool -def get_small_molecule_guest_atom_candidates( - topology: Union[str, openmm.app.Topology], +def get_guest_atom_candidates( + topology: Union[str, pathlib.Path, openmm.app.Topology], trajectory: Union[str, pathlib.Path], rdmol: Chem.Mol, - ligand_idxs: list[int], - rmsf_cutoff: unit.Quantity = 1 * unit.angstrom, + guest_idxs: list[int], + rmsf_cutoff: unit.Quantity = 1 * unit.nanometer, ) -> list[tuple[int]]: """ Get a list of potential ligand atom choices for a Boresch restraint @@ -255,7 +267,7 @@ def get_small_molecule_guest_atom_candidates( rdmol : Chem.Mol An RDKit Molecule representing the small molecule ordered in the same way as it is listed in the topology. - ligand_idxs : list[int] + guest_idxs : list[int] The ligand indices in the topology. rmsf_cutoff : unit.Quantity The RMSF filter cut-off. @@ -275,13 +287,14 @@ def get_small_molecule_guest_atom_candidates( ---- Remember to update the RDMol with the last frame positions. """ - if isinstance(topology, openmm.app.Topology): - topology_format = "OPENMMTOPOLOGY" - else: - topology_format = None + u = mda.Universe( + topology, + coordinates, + format=_get_mda_coord_format(coordinates), + topology_format=_get_mda_topology_format(topology) + ) - u = mda.Universe(topology, trajectory, topology_format=topology_format) - ligand_ag = u.atoms[ligand_idxs] + ligand_ag = u.atoms[guest_idxs] # 0. Get the ligand RMSF rmsf = get_local_rmsf(ligand_ag) @@ -308,14 +321,20 @@ def get_small_molecule_guest_atom_candidates( for angle in _angles: # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] - if not is_collinear(ligand_ag.positions, angle): - angles_list.append(angle) + if not is_collinear(ligand_ag.positions, angle, u.dimensions): + angles_list.append( + ( + angle_ag.atoms[0].ix, + angle_ag.atoms[1].ix, + angle_ag.atoms[2].ix + ) + ) return angles_list def get_host_atom_candidates( - topology: Union[str, openmm.app.Topology], + topology: Union[str, pathlib.Path, openmm.app.Topology], trajectory: Union[str, pathlib.Path], host_idxs: list[int], l1_idx: int, @@ -349,12 +368,13 @@ def get_host_atom_candidates( max_distance : unit.Quantity The maximum search distance around l1 for suitable candidate atoms. """ - if isinstance(topology, openmm.app.Topology): - topology_format = "OPENMMTOPOLOGY" - else: - topology_format = None + u = mda.Universe( + topology, + coordinates, + format=_get_mda_coord_format(coordinates), + topology_format=_get_mda_topology_format(topology) + ) - u = mda.Universe(topology, trajectory, topology_format=topology_format) protein_ag1 = u.atoms[host_idxs] protein_ag2 = protein_ag.select_atoms(protein_selection) @@ -375,6 +395,107 @@ def get_host_atom_candidates( return atom_finder.results.host_idxs -def select_boresch_atoms( +class EvaluateH2Atoms(AnalysisBase): + """ + Class to evaluate the suitability of a set of host atoms + as a H2 atom (i.e. bonded to the guest G0 atom). + + Parameters + ---------- + guest_atoms: MDAnalysis.AtomGroup + The guest atoms representing G0-G1-G2. + host_atom_pool: MDAnalysis.AtomGroup + The pool of atoms to pick a H2 from. + angle_force_constant : unit.Quantity + The force constant for the H2-G0-G1 angle. + """ + + +def find_boresch_restraint( + topology: Union[str, pathlib.Path, openmm.app.Topology], + trajectory: Union[str, pathlib.Path], + guest_rdmol: Chem.Mol, + guest_idxs: list[int], + host_idxs: list[int], + guest_restraint_atom_idxs: Optional[list[int]] = None, + host_restraint_atoms_idxs Optional[list[int]] = None, + host_selection: str = 'all', + dssp_filter: bool = False, + rmsf_custoff: unit.Quantity = 0.1 * unit.nanometer, + host_min_distance: unit.Quantity = 1 * unit.nanometer, + host_max_distance: unit.Quantity = 3 * unit.nanometer, +) -> BoreschRestraintGeometry: + """ + Find suitable Boresch-style restraints between a host and guest entity. + + Parameters + ---------- + ... + + Returns + ------- + ... + """ + u = mda.Universe( + topology, + coordinates, + format=_get_mda_coord_format(coordinates), + topology_format=_get_mda_topology_format(topology) + ) + u.trajectory[-1] # Work with the final frame + + if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): + # In this case assume the picked atoms were intentional / representative + # of the input and go with it + guest_ag = u.select_atoms[guest_idxs] + guest_angle = (at.ix for at in guest_ag.atoms[guest_restraint_atom_idxs]) + host_ag = u.select_atoms[host_idxs] + host_angle = (at.ix for at in host_ag.atoms[host_restraint_atoms_idxs]) + # TODO sort out the return on this + return BoreschRestraintGeometry(...) + + if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): + # This is not an intended outcome, crash out here + errmsg = ( + "both ``guest_restraints_atoms_idxs`` and ``host_restraint_atoms_idxs`` " + "must be set or both must be None. " + f"Got {guest_restraint_atoms_idxs} and {host_atoms_restraint_atoms_idxs}" + ) + raise ValueError(errmsg) + + # Fetch the guest angles + guest_angles = get_guest_atom_candidates( + topology=topology, + trajectory=trajectory, + rdmol=guest_rdmol, + guest_idxs=guest_idxs, + rmsf_cutoff=rmsf_cutoff, + ) + + guest_angle = guest_angles[0] + + # Fetch the host atom pool + host_pool = get_host_atom_candidates( + topology=topology, + trajectory=trajectory, + host_idxs=host_idxs, + l1_idx=guest_angle[0], + host_selection=host_selection, + dssp_filter=dssp_filter, + rmsf_cutoff=rmsf_custoff, + min_distance=host_min_distance, + max_distance=host_max_distance, + ) + + # Get the guest angle atomgroup + guest_ag = u.atoms[list(guest_angle)] + + # Find all suitable H2 idxs + h2_idxs = [] + for i in host_pool: + host2_at = u.atoms[i] + pos = np.vstack((at.position, guest_ag.positions)) + angle = calc_angles(pos[0], pos[1], pos[2], box=u.dimensions) * unit.radians + dihed = calc_dihedrals(pos[0], pos[1], pos[2], pos[3], box=u.dimensions) * unit.radians + collinear = is_collinear(positions, [0, 1, 2, 3]) -): diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index a74e83ed3..a1f983621 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -22,7 +22,7 @@ import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.analysis.rmsf import RMSF -from MDAnalysis.lib.distances import calc_bonds, calc_angles +from MDAnalysis.lib.distances import calc_bonds, calc_angles, minimize_vectors from MDAnalysis.coordinates.memory import MemoryReader from openfe_analysis.transformations import Aligner, NoJump @@ -166,19 +166,21 @@ def get_central_atom_idx(rdmol: Chem.Mol) -> int: return center -def is_collinear(positions, atoms, threshold=0.9): +def is_collinear(positions, atoms, dimensions=None, threshold=0.9): """ Check whether any sequential vectors in a sequence of atoms are collinear. Parameters ---------- positions : openmm.unit.Quantity - System positions. + System positions. atoms : list[int] - The indices of the atoms to test. + The indices of the atoms to test. + dimensions : Optional[npt.NDArray] + The dimensions of the system to minimize vectors. threshold : float - Atoms are not collinear if their sequential vector separation dot - products are less than ``threshold``. Default 0.9. + Atoms are not collinear if their sequential vector separation dot + products are less than ``threshold``. Default 0.9. Returns ------- @@ -187,12 +189,18 @@ def is_collinear(positions, atoms, threshold=0.9): Notes ----- - Originally from Yank, with modifications from Separated Topologies + Originally from Yank. """ results = False for i in range(len(atoms) - 2): - v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] - v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] + v1 = minimize_vectors( + positions[atoms[i + 1], :] - positions[atoms[i], :], + box=dimensions, + ) + v2 = minimize_vectors( + positions[atoms[i + 2], :] - positions[atoms[i + 1], :], + box=dimensions, + ) normalized_inner_product = np.dot(v1, v2) / np.sqrt( np.dot(v1, v1) * np.dot(v2, v2) ) From e780a94737ae4e7004a2a4cceed1ad96f6a25dcd Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 13 Dec 2024 14:36:55 +0100 Subject: [PATCH 089/163] Add slow energy test --- .../protocols/openmm_septop/alchemy_copy.py | 4 - openfe/protocols/openmm_septop/femto_utils.py | 1 - openfe/tests/protocols/test_openmm_septop.py | 507 ++++++++++++++++++ .../protocols/test_openmm_septop_protocol.py | 498 ----------------- .../protocols/test_openmm_septop_slow.py | 188 +++++++ 5 files changed, 695 insertions(+), 503 deletions(-) create mode 100644 openfe/tests/protocols/test_openmm_septop.py delete mode 100644 openfe/tests/protocols/test_openmm_septop_protocol.py create mode 100644 openfe/tests/protocols/test_openmm_septop_slow.py diff --git a/openfe/protocols/openmm_septop/alchemy_copy.py b/openfe/protocols/openmm_septop/alchemy_copy.py index 75a7856c9..12ce7f2d1 100644 --- a/openfe/protocols/openmm_septop/alchemy_copy.py +++ b/openfe/protocols/openmm_septop/alchemy_copy.py @@ -721,7 +721,6 @@ def create_alchemical_system(self, reference_system, alchemical_regions, # TODO switch to functools.singledispatch when we drop Python2 support reference_force_name = reference_force.__class__.__name__ alchemical_force_creator_name = '_alchemically_modify_{}'.format(reference_force_name) - print(alchemical_force_creator_name) try: alchemical_force_creator_func = getattr(self, alchemical_force_creator_name) except AttributeError as e: @@ -739,10 +738,8 @@ def create_alchemical_system(self, reference_system, alchemical_regions, alchemical_forces_by_lambda[lambda_variable_name] = lambda_forces # Remove original forces that have been alchemically modified. - print(forces_to_remove) for force_index in reversed(forces_to_remove): alchemical_system.removeForce(force_index) - print(alchemical_forces_by_lambda) # Add forces and split groups if necessary. self._add_alchemical_forces(alchemical_system, alchemical_forces_by_lambda) @@ -2423,7 +2420,6 @@ def check_energy_expression(custom_force, parameter): parameter_found, region_type_suffix = check_energy_expression(force, 'lambda') if parameter_found: _, region_name_suffix = check_energy_expression(force, 'lambda_{}'.format(region_type_suffix)) - print(region_name_suffix) if region_type_suffix == 'sterics': if region_name_suffix in sterics_bond_forces: sterics_bond_forces[region_name_suffix].append([force_index, force]) diff --git a/openfe/protocols/openmm_septop/femto_utils.py b/openfe/protocols/openmm_septop/femto_utils.py index 7d52d0e5e..c8064d0e5 100644 --- a/openfe/protocols/openmm_septop/femto_utils.py +++ b/openfe/protocols/openmm_septop/femto_utils.py @@ -184,7 +184,6 @@ def is_close( if not v1.unit.is_compatible(v2.unit): return False - return numpy.isclose( v1.value_in_unit(v1.unit), v2.value_in_unit(v1.unit), diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py new file mode 100644 index 000000000..9884c138c --- /dev/null +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -0,0 +1,507 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +import itertools +import json +import sys + +import openmmtools.alchemy +import pytest +import importlib +from unittest import mock +from openmm import NonbondedForce, CustomNonbondedForce +from openmmtools.multistate.multistatesampler import MultiStateSampler +from openff.units import unit as offunit +from openff.units.openmm import ensure_quantity, from_openmm +import mdtraj as mdt +import numpy as np +from numpy.testing import assert_allclose +from openff.units import unit +import gufe +import openfe +import simtk +from openfe import ChemicalSystem, SolventComponent +from openfe.protocols.openmm_septop import ( + SepTopSolventSetupUnit, + SepTopComplexSetupUnit, + SepTopProtocol, + femto_restraints, +) +from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close +from openfe.protocols.openmm_septop.utils import deserialize +from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference +from openmmtools.states import (SamplerState, + ThermodynamicState, + create_thermodynamic_state_protocol, ) + +from openfe.protocols.openmm_utils import system_validation +from openfe.protocols.openmm_utils.charge_generation import ( + HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA +) +from openfe.protocols.openmm_septop.alchemy_copy import AlchemicalState + + +@pytest.fixture() +def default_settings(): + return SepTopProtocol.default_settings() + + +def test_create_default_settings(): + settings = SepTopProtocol.default_settings() + assert settings + + +# @pytest.mark.parametrize('val', [ +# {'elec': [0.0, -1], 'vdw': [0.0, 1.0], 'restraints': [0.0, 1.0]}, +# {'elec': [0.0, 1.5], 'vdw': [0.0, 1.5], 'restraints': [-0.1, 1.0]} +# ]) +# def test_incorrect_window_settings(val, default_settings): +# errmsg = "Lambda windows must be between 0 and 1." +# lambda_settings = default_settings.lambda_settings +# with pytest.raises(ValueError, match=errmsg): +# lambda_settings.lambda_elec_ligandA = val['elec'] +# lambda_settings.lambda_vdw_ligandA = val['vdw'] +# lambda_settings.lambda_restraints_ligandA = val['restraints'] +# +# +# @pytest.mark.parametrize('val', [ +# {'elec': [0.0, 0.1, 0.0], 'vdw': [0.0, 1.0, 1.0], 'restraints': [0.0, 1.0, 1.0]}, +# ]) +# def test_monotonic_lambda_windows(val, default_settings): +# errmsg = "The lambda schedule is not monotonic." +# lambda_settings = default_settings.lambda_settings +# +# with pytest.raises(ValueError, match=errmsg): +# lambda_settings.lambda_elec_ligandA = val['elec'] +# lambda_settings.lambda_vdw_ligandA = val['vdw'] +# lambda_settings.lambda_restraints_ligandA = val['restraints'] +# +# +# @pytest.mark.parametrize('val', [ +# {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, +# ]) +# def test_validate_lambda_schedule_nreplicas(val, default_settings): +# default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] +# default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] +# default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] +# default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] +# default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] +# default_settings.lambda_settings.lambda_restraints_ligandB = val[ +# 'restraints'] +# n_replicas = 3 +# default_settings.complex_simulation_settings.n_replicas = n_replicas +# errmsg = (f"Number of replicas {n_replicas} does not equal the" +# f" number of lambda windows {len(val['vdw'])}") +# with pytest.raises(ValueError, match=errmsg): +# SepTopProtocol._validate_lambda_schedule( +# default_settings.lambda_settings, +# default_settings.complex_simulation_settings, +# ) +# +# +# @pytest.mark.parametrize('val', [ +# {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, +# ]) +# def test_validate_lambda_schedule_nwindows(val, default_settings): +# default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] +# default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] +# default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] +# n_replicas = 3 +# default_settings.complex_simulation_settings.n_replicas = n_replicas +# errmsg = ( +# "Components elec, vdw, and restraints must have equal amount of lambda " +# "windows. Got 3 and 19 elec lambda windows") +# with pytest.raises(ValueError, match=errmsg): +# SepTopProtocol._validate_lambda_schedule( +# default_settings.lambda_settings, +# default_settings.complex_simulation_settings, +# ) +# +# +# @pytest.mark.parametrize('val', [ +# {'elec': [1.0, 0.5], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, +# ]) +# def test_validate_lambda_schedule_nakedcharge(val, default_settings): +# default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] +# default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] +# default_settings.lambda_settings.lambda_restraints_ligandA = val[ +# 'restraints'] +# default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] +# default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] +# default_settings.lambda_settings.lambda_restraints_ligandB = val[ +# 'restraints'] +# n_replicas = 2 +# default_settings.complex_simulation_settings.n_replicas = n_replicas +# default_settings.solvent_simulation_settings.n_replicas = n_replicas +# errmsg = ( +# "There are states along this lambda schedule " +# "where there are atoms with charges but no LJ " +# "interactions: Ligand A: l") +# with pytest.raises(ValueError, match=errmsg): +# SepTopProtocol._validate_lambda_schedule( +# default_settings.lambda_settings, +# default_settings.complex_simulation_settings, +# ) +# with pytest.raises(ValueError, match=errmsg): +# SepTopProtocol._validate_lambda_schedule( +# default_settings.lambda_settings, +# default_settings.solvent_simulation_settings, +# ) +# +# +# def test_create_default_protocol(default_settings): +# # this is roughly how it should be created +# protocol = SepTopProtocol( +# settings=default_settings, +# ) +# assert protocol +# +# +# def test_serialize_protocol(default_settings): +# protocol = SepTopProtocol( +# settings=default_settings, +# ) +# +# ser = protocol.to_dict() +# ret = SepTopProtocol.from_dict(ser) +# assert protocol == ret +# +# +# def test_create_independent_repeat_ids( +# benzene_complex_system, toluene_complex_system, +# ): +# # if we create two dags each with 3 repeats, they should give 6 repeat_ids +# # this allows multiple DAGs in flight for one Transformation that don't clash on gather +# settings = SepTopProtocol.default_settings() +# # Default protocol is 1 repeat, change to 3 repeats +# settings.protocol_repeats = 3 +# protocol = SepTopProtocol( +# settings=settings, +# ) +# +# dag1 = protocol.create( +# stateA=benzene_complex_system, +# stateB=toluene_complex_system, +# mapping=None, +# ) +# dag2 = protocol.create( +# stateA=benzene_complex_system, +# stateB=toluene_complex_system, +# mapping=None, +# ) +# # print([u for u in dag1.protocol_units]) +# repeat_ids = set() +# for u in dag1.protocol_units: +# repeat_ids.add(u.inputs['repeat_id']) +# for u in dag2.protocol_units: +# repeat_ids.add(u.inputs['repeat_id']) +# +# # There are 4 units per repeat per DAG: 4 * 3 * 2 = 24 +# assert len(repeat_ids) == 24 +# +# +# def test_check_alchem_charge_diff(charged_benzene_modifications): +# errmsg = "A charge difference of 1" +# with pytest.raises(ValueError, match=errmsg): +# _check_alchemical_charge_difference( +# charged_benzene_modifications["benzene"], +# charged_benzene_modifications["benzoic_acid"], +# ) +# +# +# def test_charge_error_create( +# charged_benzene_modifications, T4_protein_component, +# ): +# # if we create two dags each with 3 repeats, they should give 6 repeat_ids +# # this allows multiple DAGs in flight for one Transformation that don't clash on gather +# settings = SepTopProtocol.default_settings() +# # Default protocol is 1 repeat, change to 3 repeats +# settings.protocol_repeats = 3 +# protocol = SepTopProtocol( +# settings=settings, +# ) +# stateA = ChemicalSystem({ +# 'benzene': charged_benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent() +# }) +# +# stateB = ChemicalSystem({ +# 'benzoic': charged_benzene_modifications['benzoic_acid'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# errmsg = "A charge difference of 1" +# with pytest.raises(ValueError, match=errmsg): +# protocol.create( +# stateA=stateA, +# stateB=stateB, +# mapping=None, +# ) +# +# +# def test_validate_complex_endstates_protcomp_stateA( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'solvent': SolventComponent() +# }) +# +# stateB = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# with pytest.raises(ValueError, match="No ProteinComponent found in stateA"): +# SepTopProtocol._validate_complex_endstates(stateA, stateB) +# +# +# def test_validate_complex_endstates_protcomp_stateB( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'solvent': SolventComponent(), +# }) +# +# with pytest.raises(ValueError, match="No ProteinComponent found in stateB"): +# SepTopProtocol._validate_complex_endstates(stateA, stateB) +# +# +# +# def test_validate_complex_endstates_nosolvcomp_stateA( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# }) +# +# stateB = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# with pytest.raises( +# ValueError, match="No SolventComponent found in stateA" +# ): +# SepTopProtocol._validate_complex_endstates(stateA, stateB) +# +# +# def test_validate_complex_endstates_nosolvcomp_stateB( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# }) +# +# with pytest.raises( +# ValueError, match="No SolventComponent found in stateB" +# ): +# SepTopProtocol._validate_complex_endstates(stateA, stateB) +# +# +# def test_validate_alchem_comps_missingA( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) +# +# with pytest.raises(ValueError, match='one alchemical components must be present in stateA.'): +# SepTopProtocol._validate_alchemical_components(alchem_comps) +# +# +# def test_validate_alchem_comps_missingB( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) +# +# with pytest.raises(ValueError, match='one alchemical components must be present in stateB.'): +# SepTopProtocol._validate_alchemical_components(alchem_comps) +# +# +# def test_validate_alchem_comps_toomanyA( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'toluene': benzene_modifications['toluene'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# stateB = ChemicalSystem({ +# 'phenol': benzene_modifications['phenol'], +# 'protein': T4_protein_component, +# 'solvent': SolventComponent(), +# }) +# +# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) +# +# assert len(alchem_comps['stateA']) == 2 +# +# assert len(alchem_comps['stateB']) == 1 +# +# with pytest.raises(ValueError, match='Found 2 alchemical components in stateA'): +# SepTopProtocol._validate_alchemical_components(alchem_comps) +# +# +# def test_validate_alchem_nonsmc( +# benzene_modifications, T4_protein_component, +# ): +# stateA = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'solvent': SolventComponent() +# }) +# +# stateB = ChemicalSystem({ +# 'benzene': benzene_modifications['benzene'], +# 'protein': T4_protein_component +# }) +# +# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) +# +# with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): +# SepTopProtocol._validate_alchemical_components(alchem_comps) + + +@pytest.fixture(scope='session') +def bace_reference_xml(): + with importlib.resources.files('openfe.tests.data.openmm_septop') as d: + f = d / 'system.xml.bz2' + return deserialize(f) + +@pytest.fixture(scope='session') +def bace_reference_positions(): + with importlib.resources.files('openfe.tests.data.openmm_septop') as d: + f = d / 'topology.pdb' + pdb = simtk.openmm.app.pdbfile.PDBFile(str(f)) + positions = pdb.getPositions(asNumpy=True) + return positions + + +def test_reference_alchemical_system(bace_reference_xml, bace_reference_positions): + # Remove Boresch forces + # bace_reference_xml.removeForce(14) + bace_reference_xml.removeForce(13) + alchemical_state = AlchemicalState.from_system(bace_reference_xml) + + from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory + + energy = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandA' + na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandB' + nonbonded = 'unmodified NonbondedForce' + + # Lambda 0: LigandA sterics on, elec on, ligand B sterics off, elec off + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 0 + alchemical_state.lambda_electrostatics_ligandA = 1 + alchemical_state.lambda_electrostatics_ligandB = 0 + energy_0 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + + # Lambda 7: LigandA sterics on, elec on, ligand B sterics on, elec off + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 1 + alchemical_state.lambda_electrostatics_ligandB = 0 + energy_7 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + + # Lambda 8: LigandA sterics on, elec partially on, + # ligand B sterics on, elec partially on + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 0.75 + alchemical_state.lambda_electrostatics_ligandB = 0.25 + energy_8 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + + # Lambda 12: LigandA sterics on, elec off, ligand B sterics on, elec on + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 0 + alchemical_state.lambda_electrostatics_ligandB = 1 + energy_12 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + + # Lambda 13: LigandA sterics partially on, elec off, ligand B sterics on, elec on + alchemical_state.lambda_sterics_ligandA = 0.857142857 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 0 + alchemical_state.lambda_electrostatics_ligandB = 1 + energy_13 = AbsoluteAlchemicalFactory.get_energy_components( + bace_reference_xml, alchemical_state, bace_reference_positions + ) + + for key, value in energy.items(): + if key == na_A: + assert is_close(value, energy_0[key]) + assert is_close(value, energy_7[key]) + assert is_close(value, energy_8[key]) + assert is_close(value, energy_12[key]) + assert not is_close(value, energy_13[key]) + elif key == na_B: + assert not is_close(value, energy_0[key]) + assert energy_0[key].value_in_unit(simtk.unit.kilojoule_per_mole) == 0 + assert is_close(value, energy_7[key]) + assert is_close(value, energy_8[key]) + assert is_close(value, energy_12[key]) + assert is_close(value, energy_13[key]) + elif key == nonbonded: + assert not is_close(value, energy_0[key]) + assert is_close(energy_0[key], energy_7[key]) + assert not is_close(energy_0[key], energy_8[key]) + assert not is_close(energy_0[key], energy_12[key]) + assert not is_close(energy_0[key], energy_13[key]) + else: + assert is_close(value, energy_0[key]) + assert is_close(value, energy_7[key]) + assert is_close(value, energy_8[key]) + assert is_close(value, energy_12[key]) + assert is_close(value, energy_13[key]) + assert 4==5 + diff --git a/openfe/tests/protocols/test_openmm_septop_protocol.py b/openfe/tests/protocols/test_openmm_septop_protocol.py deleted file mode 100644 index f7c934a72..000000000 --- a/openfe/tests/protocols/test_openmm_septop_protocol.py +++ /dev/null @@ -1,498 +0,0 @@ -# This code is part of OpenFE and is licensed under the MIT license. -# For details, see https://github.com/OpenFreeEnergy/openfe -import itertools -import json -import sys - -import openmmtools.alchemy -import pytest -import importlib -from unittest import mock -from openmm import NonbondedForce, CustomNonbondedForce -from openmmtools.multistate.multistatesampler import MultiStateSampler -from openff.units import unit as offunit -from openff.units.openmm import ensure_quantity, from_openmm -import mdtraj as mdt -import numpy as np -from numpy.testing import assert_allclose -from openff.units import unit -import gufe -import openfe -import simtk -from openfe import ChemicalSystem, SolventComponent -from openfe.protocols.openmm_septop import ( - SepTopSolventSetupUnit, - SepTopComplexSetupUnit, - SepTopProtocol, - femto_restraints, -) -from openfe.protocols.openmm_septop.utils import deserialize -from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference -from openmmtools.states import (SamplerState, - ThermodynamicState, - create_thermodynamic_state_protocol, ) - -from openfe.protocols.openmm_utils import system_validation -from openfe.protocols.openmm_utils.charge_generation import ( - HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA -) -from openfe.protocols.openmm_septop.alchemy_copy import AlchemicalState - - -@pytest.fixture() -def default_settings(): - return SepTopProtocol.default_settings() - - -def test_create_default_settings(): - settings = SepTopProtocol.default_settings() - assert settings - - -@pytest.mark.parametrize('val', [ - {'elec': [0.0, -1], 'vdw': [0.0, 1.0], 'restraints': [0.0, 1.0]}, - {'elec': [0.0, 1.5], 'vdw': [0.0, 1.5], 'restraints': [-0.1, 1.0]} -]) -def test_incorrect_window_settings(val, default_settings): - errmsg = "Lambda windows must be between 0 and 1." - lambda_settings = default_settings.lambda_settings - with pytest.raises(ValueError, match=errmsg): - lambda_settings.lambda_elec_ligandA = val['elec'] - lambda_settings.lambda_vdw_ligandA = val['vdw'] - lambda_settings.lambda_restraints_ligandA = val['restraints'] - - -@pytest.mark.parametrize('val', [ - {'elec': [0.0, 0.1, 0.0], 'vdw': [0.0, 1.0, 1.0], 'restraints': [0.0, 1.0, 1.0]}, -]) -def test_monotonic_lambda_windows(val, default_settings): - errmsg = "The lambda schedule is not monotonic." - lambda_settings = default_settings.lambda_settings - - with pytest.raises(ValueError, match=errmsg): - lambda_settings.lambda_elec_ligandA = val['elec'] - lambda_settings.lambda_vdw_ligandA = val['vdw'] - lambda_settings.lambda_restraints_ligandA = val['restraints'] - - -@pytest.mark.parametrize('val', [ - {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, -]) -def test_validate_lambda_schedule_nreplicas(val, default_settings): - default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] - default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandB = val[ - 'restraints'] - n_replicas = 3 - default_settings.complex_simulation_settings.n_replicas = n_replicas - errmsg = (f"Number of replicas {n_replicas} does not equal the" - f" number of lambda windows {len(val['vdw'])}") - with pytest.raises(ValueError, match=errmsg): - SepTopProtocol._validate_lambda_schedule( - default_settings.lambda_settings, - default_settings.complex_simulation_settings, - ) - - -@pytest.mark.parametrize('val', [ - {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, -]) -def test_validate_lambda_schedule_nwindows(val, default_settings): - default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] - n_replicas = 3 - default_settings.complex_simulation_settings.n_replicas = n_replicas - errmsg = ( - "Components elec, vdw, and restraints must have equal amount of lambda " - "windows. Got 3 and 19 elec lambda windows") - with pytest.raises(ValueError, match=errmsg): - SepTopProtocol._validate_lambda_schedule( - default_settings.lambda_settings, - default_settings.complex_simulation_settings, - ) - - -@pytest.mark.parametrize('val', [ - {'elec': [1.0, 0.5], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, -]) -def test_validate_lambda_schedule_nakedcharge(val, default_settings): - default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandA = val[ - 'restraints'] - default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandB = val[ - 'restraints'] - n_replicas = 2 - default_settings.complex_simulation_settings.n_replicas = n_replicas - default_settings.solvent_simulation_settings.n_replicas = n_replicas - errmsg = ( - "There are states along this lambda schedule " - "where there are atoms with charges but no LJ " - "interactions: Ligand A: l") - with pytest.raises(ValueError, match=errmsg): - SepTopProtocol._validate_lambda_schedule( - default_settings.lambda_settings, - default_settings.complex_simulation_settings, - ) - with pytest.raises(ValueError, match=errmsg): - SepTopProtocol._validate_lambda_schedule( - default_settings.lambda_settings, - default_settings.solvent_simulation_settings, - ) - - -def test_create_default_protocol(default_settings): - # this is roughly how it should be created - protocol = SepTopProtocol( - settings=default_settings, - ) - assert protocol - - -def test_serialize_protocol(default_settings): - protocol = SepTopProtocol( - settings=default_settings, - ) - - ser = protocol.to_dict() - ret = SepTopProtocol.from_dict(ser) - assert protocol == ret - - -def test_create_independent_repeat_ids( - benzene_complex_system, toluene_complex_system, -): - # if we create two dags each with 3 repeats, they should give 6 repeat_ids - # this allows multiple DAGs in flight for one Transformation that don't clash on gather - settings = SepTopProtocol.default_settings() - # Default protocol is 1 repeat, change to 3 repeats - settings.protocol_repeats = 3 - protocol = SepTopProtocol( - settings=settings, - ) - - dag1 = protocol.create( - stateA=benzene_complex_system, - stateB=toluene_complex_system, - mapping=None, - ) - dag2 = protocol.create( - stateA=benzene_complex_system, - stateB=toluene_complex_system, - mapping=None, - ) - # print([u for u in dag1.protocol_units]) - repeat_ids = set() - for u in dag1.protocol_units: - repeat_ids.add(u.inputs['repeat_id']) - for u in dag2.protocol_units: - repeat_ids.add(u.inputs['repeat_id']) - - # There are 4 units per repeat per DAG: 4 * 3 * 2 = 24 - assert len(repeat_ids) == 24 - - -def test_check_alchem_charge_diff(charged_benzene_modifications): - errmsg = "A charge difference of 1" - with pytest.raises(ValueError, match=errmsg): - _check_alchemical_charge_difference( - charged_benzene_modifications["benzene"], - charged_benzene_modifications["benzoic_acid"], - ) - - -def test_charge_error_create( - charged_benzene_modifications, T4_protein_component, -): - # if we create two dags each with 3 repeats, they should give 6 repeat_ids - # this allows multiple DAGs in flight for one Transformation that don't clash on gather - settings = SepTopProtocol.default_settings() - # Default protocol is 1 repeat, change to 3 repeats - settings.protocol_repeats = 3 - protocol = SepTopProtocol( - settings=settings, - ) - stateA = ChemicalSystem({ - 'benzene': charged_benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent() - }) - - stateB = ChemicalSystem({ - 'benzoic': charged_benzene_modifications['benzoic_acid'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - errmsg = "A charge difference of 1" - with pytest.raises(ValueError, match=errmsg): - protocol.create( - stateA=stateA, - stateB=stateB, - mapping=None, - ) - - -def test_validate_complex_endstates_protcomp_stateA( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'solvent': SolventComponent() - }) - - stateB = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - with pytest.raises(ValueError, match="No ProteinComponent found in stateA"): - SepTopProtocol._validate_complex_endstates(stateA, stateB) - - -def test_validate_complex_endstates_protcomp_stateB( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - stateB = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'solvent': SolventComponent(), - }) - - with pytest.raises(ValueError, match="No ProteinComponent found in stateB"): - SepTopProtocol._validate_complex_endstates(stateA, stateB) - - - -def test_validate_complex_endstates_nosolvcomp_stateA( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - }) - - stateB = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - with pytest.raises( - ValueError, match="No SolventComponent found in stateA" - ): - SepTopProtocol._validate_complex_endstates(stateA, stateB) - - -def test_validate_complex_endstates_nosolvcomp_stateB( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - stateB = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - }) - - with pytest.raises( - ValueError, match="No SolventComponent found in stateB" - ): - SepTopProtocol._validate_complex_endstates(stateA, stateB) - - -def test_validate_alchem_comps_missingA( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - stateB = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - alchem_comps = system_validation.get_alchemical_components(stateA, stateB) - - with pytest.raises(ValueError, match='one alchemical components must be present in stateA.'): - SepTopProtocol._validate_alchemical_components(alchem_comps) - - -def test_validate_alchem_comps_missingB( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - stateB = ChemicalSystem({ - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - alchem_comps = system_validation.get_alchemical_components(stateA, stateB) - - with pytest.raises(ValueError, match='one alchemical components must be present in stateB.'): - SepTopProtocol._validate_alchemical_components(alchem_comps) - - -def test_validate_alchem_comps_toomanyA( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'toluene': benzene_modifications['toluene'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - stateB = ChemicalSystem({ - 'phenol': benzene_modifications['phenol'], - 'protein': T4_protein_component, - 'solvent': SolventComponent(), - }) - - alchem_comps = system_validation.get_alchemical_components(stateA, stateB) - - assert len(alchem_comps['stateA']) == 2 - - assert len(alchem_comps['stateB']) == 1 - - with pytest.raises(ValueError, match='Found 2 alchemical components in stateA'): - SepTopProtocol._validate_alchemical_components(alchem_comps) - - -def test_validate_alchem_nonsmc( - benzene_modifications, T4_protein_component, -): - stateA = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'solvent': SolventComponent() - }) - - stateB = ChemicalSystem({ - 'benzene': benzene_modifications['benzene'], - 'protein': T4_protein_component - }) - - alchem_comps = system_validation.get_alchemical_components(stateA, stateB) - - with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): - SepTopProtocol._validate_alchemical_components(alchem_comps) - - -@pytest.fixture(scope='session') -def bace_reference_xml(): - with importlib.resources.files('openfe.tests.data.openmm_septop') as d: - f = d / 'system.xml.bz2' - return deserialize(f) - -@pytest.fixture(scope='session') -def bace_reference_positions(): - with importlib.resources.files('openfe.tests.data.openmm_septop') as d: - f = d / 'topology.pdb' - pdb = simtk.openmm.app.pdbfile.PDBFile(str(f)) - positions = pdb.getPositions(asNumpy=True) - return positions - - -def test_reference_alchemical_system(bace_reference_xml, bace_reference_positions): - settings = SepTopProtocol.default_settings() - alchemical_state = AlchemicalState.from_system(bace_reference_xml) - print(alchemical_state.lambda_sterics_ligandA) - print(alchemical_state.lambda_electrostatics_ligandA) - # Remove harmonic distance restraint for now - bace_reference_xml.removeForce(13) - - from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory - energy = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions - ) - na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandA' - aa_A = 'alchemically modified NonbondedForce for alchemical/alchemical sterics for region ligandA' - na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandB' - aa_B = 'alchemically modified NonbondedForce for alchemical/alchemical sterics for region ligandB' - print(energy) - print(energy[na_B]) - alchemical_state.lambda_electrostatics_ligandA = 0.2 - alchemical_state.lambda_electrostatics_ligandB = 0.8 - energy_05 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions - ) - print(energy_05) - print(energy_05[na_B]) - - alchemical_state.lambda_sterics_ligandA = 0.5 - energy_05_2 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions - ) - print(energy_05_2) - - assert energy[na_A] != energy_05[na_A] - assert energy[aa_A] == energy_05[aa_A] - assert energy[na_B] == energy_05[na_B] - assert energy[aa_B] == energy_05[aa_B] - - -# def test_setup(bace_ligands, bace_protein_component, tmpdir): -# # check system parametrisation works even if confgen fails -# s = SepTopProtocol.default_settings() -# s.protocol_repeats = 1 -# s.solvent_equil_simulation_settings.minimization_steps = 100 -# s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond -# s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond -# s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond -# s.solvent_solvation_settings.box_shape = 'dodecahedron' -# s.solvent_solvation_settings.solvent_padding = 1.8 * unit.nanometer -# -# protocol = SepTopProtocol( -# settings=s, -# ) -# -# stateA = ChemicalSystem({ -# 'lig_02': bace_ligands['lig_02'], -# 'protein': bace_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'lig_03': bace_ligands['lig_03'], -# 'protein': bace_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# # Create DAG from protocol, get the vacuum and solvent units -# # and eventually dry run the first vacuum unit -# dag = protocol.create( -# stateA=stateA, -# stateB=stateB, -# mapping=None, -# ) -# prot_units = list(dag.protocol_units) -# solv_setup_unit = [u for u in prot_units -# if isinstance(u, SepTopSolventSetupUnit)] -# # solv_setup_unit = [u for u in prot_units -# # if isinstance(u, SepTopComplexSetupUnit)] -# -# # with tmpdir.as_cwd(): -# solv_setup_unit[0].run() - diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py new file mode 100644 index 000000000..6cf461cf1 --- /dev/null +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -0,0 +1,188 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +import itertools +import json +import sys + +import openmmtools.alchemy +import pytest +import importlib +from unittest import mock +from openmm import NonbondedForce, CustomNonbondedForce +from openmmtools.multistate.multistatesampler import MultiStateSampler +from openff.units import unit as offunit +from openff.units.openmm import ensure_quantity, from_openmm +import mdtraj as mdt +import numpy as np +from numpy.testing import assert_allclose +from openff.units import unit +import gufe +import openfe +import simtk +from openfe import ChemicalSystem, SolventComponent +from openfe.protocols.openmm_septop import ( + SepTopSolventSetupUnit, + SepTopComplexSetupUnit, + SepTopProtocol, + femto_restraints, +) +from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close +from openfe.protocols.openmm_septop.utils import deserialize +from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference +from openmmtools.states import (SamplerState, + ThermodynamicState, + create_thermodynamic_state_protocol, ) + +from openfe.protocols.openmm_utils import system_validation +from openfe.protocols.openmm_utils.charge_generation import ( + HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA +) +from openfe.protocols.openmm_septop.alchemy_copy import AlchemicalState + + +@pytest.fixture() +def default_settings(): + return SepTopProtocol.default_settings() + + +def compare_energies(alchemical_system, positions): + + alchemical_state = AlchemicalState.from_system(alchemical_system) + + from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory + + energy = AbsoluteAlchemicalFactory.get_energy_components( + alchemical_system, alchemical_state, positions + ) + na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandA' + na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandB' + nonbonded = 'unmodified NonbondedForce' + + # Lambda 0: LigandA sterics on, elec on, ligand B sterics off, elec off + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 0 + alchemical_state.lambda_electrostatics_ligandA = 1 + alchemical_state.lambda_electrostatics_ligandB = 0 + energy_0 = AbsoluteAlchemicalFactory.get_energy_components( + alchemical_system, alchemical_state, positions + ) + + # Lambda 7: LigandA sterics on, elec on, ligand B sterics on, elec off + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 1 + alchemical_state.lambda_electrostatics_ligandB = 0 + energy_7 = AbsoluteAlchemicalFactory.get_energy_components( + alchemical_system, alchemical_state, positions + ) + + # Lambda 8: LigandA sterics on, elec partially on, + # ligand B sterics on, elec partially on + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 0.75 + alchemical_state.lambda_electrostatics_ligandB = 0.25 + energy_8 = AbsoluteAlchemicalFactory.get_energy_components( + alchemical_system, alchemical_state, positions + ) + + # Lambda 12: LigandA sterics on, elec off, ligand B sterics on, elec on + alchemical_state.lambda_sterics_ligandA = 1 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 0 + alchemical_state.lambda_electrostatics_ligandB = 1 + energy_12 = AbsoluteAlchemicalFactory.get_energy_components( + alchemical_system, alchemical_state, positions + ) + + # Lambda 13: LigandA sterics partially on, elec off, ligand B sterics on, elec on + alchemical_state.lambda_sterics_ligandA = 0.857142857 + alchemical_state.lambda_sterics_ligandB = 1 + alchemical_state.lambda_electrostatics_ligandA = 0 + alchemical_state.lambda_electrostatics_ligandB = 1 + energy_13 = AbsoluteAlchemicalFactory.get_energy_components( + alchemical_system, alchemical_state, positions + ) + + return na_A, na_B, nonbonded, energy, energy_0, energy_7, energy_8, energy_12, energy_13 + + +def test_lambda_energies(bace_ligands, bace_protein_component, tmpdir): + # check system parametrisation works even if confgen fails + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_equil_simulation_settings.minimization_steps = 100 + s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond + s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond + s.solvent_equil_simulation_settings.production_length = 1 * unit.picosecond + s.solvent_solvation_settings.box_shape = 'dodecahedron' + s.solvent_solvation_settings.solvent_padding = 1.8 * unit.nanometer + + protocol = SepTopProtocol( + settings=s, + ) + + stateA = ChemicalSystem({ + 'lig_02': bace_ligands['lig_02'], + 'protein': bace_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'lig_03': bace_ligands['lig_03'], + 'protein': bace_protein_component, + 'solvent': SolventComponent(), + }) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first vacuum unit + dag = protocol.create( + stateA=stateA, + stateB=stateB, + mapping=None, + ) + prot_units = list(dag.protocol_units) + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + + with tmpdir.as_cwd(): + output = solv_setup_unit[0].run() + system = output["system"] + alchemical_system = deserialize(system) + topology = output["topology"] + pdb = simtk.openmm.app.pdbfile.PDBFile(str(topology)) + positions = pdb.getPositions(asNumpy=True) + + # Remove Harmonic restraint force solvent + system.removeForce(13) + + na_A, na_B, nonbonded, energy, energy_0, energy_7, energy_8, \ + energy_12, energy_13 = compare_energies(alchemical_system, positions) + + for key, value in energy.items(): + if key == na_A: + assert is_close(value, energy_0[key]) + assert is_close(value, energy_7[key]) + assert is_close(value, energy_8[key]) + assert is_close(value, energy_12[key]) + assert not is_close(value, energy_13[key]) + elif key == na_B: + assert not is_close(value, energy_0[key]) + assert energy_0[key].value_in_unit( + simtk.unit.kilojoule_per_mole) == 0 + assert is_close(value, energy_7[key]) + assert is_close(value, energy_8[key]) + assert is_close(value, energy_12[key]) + assert is_close(value, energy_13[key]) + elif key == nonbonded: + assert not is_close(value, energy_0[key]) + assert is_close(energy_0[key], energy_7[key]) + assert not is_close(energy_0[key], energy_8[key]) + assert not is_close(energy_0[key], energy_12[key]) + assert not is_close(energy_0[key], energy_13[key]) + else: + assert is_close(value, energy_0[key]) + assert is_close(value, energy_7[key]) + assert is_close(value, energy_8[key]) + assert is_close(value, energy_12[key]) + assert is_close(value, energy_13[key]) From b5cdaf4424c9948eca37dfe2e329947b412593c9 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 13 Dec 2024 14:38:03 +0100 Subject: [PATCH 090/163] Move energy test to slow --- openfe/tests/protocols/test_openmm_septop.py | 782 ++++++++----------- 1 file changed, 338 insertions(+), 444 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 9884c138c..07870738d 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -50,458 +50,352 @@ def test_create_default_settings(): assert settings -# @pytest.mark.parametrize('val', [ -# {'elec': [0.0, -1], 'vdw': [0.0, 1.0], 'restraints': [0.0, 1.0]}, -# {'elec': [0.0, 1.5], 'vdw': [0.0, 1.5], 'restraints': [-0.1, 1.0]} -# ]) -# def test_incorrect_window_settings(val, default_settings): -# errmsg = "Lambda windows must be between 0 and 1." -# lambda_settings = default_settings.lambda_settings -# with pytest.raises(ValueError, match=errmsg): -# lambda_settings.lambda_elec_ligandA = val['elec'] -# lambda_settings.lambda_vdw_ligandA = val['vdw'] -# lambda_settings.lambda_restraints_ligandA = val['restraints'] -# -# -# @pytest.mark.parametrize('val', [ -# {'elec': [0.0, 0.1, 0.0], 'vdw': [0.0, 1.0, 1.0], 'restraints': [0.0, 1.0, 1.0]}, -# ]) -# def test_monotonic_lambda_windows(val, default_settings): -# errmsg = "The lambda schedule is not monotonic." -# lambda_settings = default_settings.lambda_settings -# -# with pytest.raises(ValueError, match=errmsg): -# lambda_settings.lambda_elec_ligandA = val['elec'] -# lambda_settings.lambda_vdw_ligandA = val['vdw'] -# lambda_settings.lambda_restraints_ligandA = val['restraints'] -# -# -# @pytest.mark.parametrize('val', [ -# {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, -# ]) -# def test_validate_lambda_schedule_nreplicas(val, default_settings): -# default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] -# default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] -# default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] -# default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] -# default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] -# default_settings.lambda_settings.lambda_restraints_ligandB = val[ -# 'restraints'] -# n_replicas = 3 -# default_settings.complex_simulation_settings.n_replicas = n_replicas -# errmsg = (f"Number of replicas {n_replicas} does not equal the" -# f" number of lambda windows {len(val['vdw'])}") -# with pytest.raises(ValueError, match=errmsg): -# SepTopProtocol._validate_lambda_schedule( -# default_settings.lambda_settings, -# default_settings.complex_simulation_settings, -# ) -# -# -# @pytest.mark.parametrize('val', [ -# {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, -# ]) -# def test_validate_lambda_schedule_nwindows(val, default_settings): -# default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] -# default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] -# default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] -# n_replicas = 3 -# default_settings.complex_simulation_settings.n_replicas = n_replicas -# errmsg = ( -# "Components elec, vdw, and restraints must have equal amount of lambda " -# "windows. Got 3 and 19 elec lambda windows") -# with pytest.raises(ValueError, match=errmsg): -# SepTopProtocol._validate_lambda_schedule( -# default_settings.lambda_settings, -# default_settings.complex_simulation_settings, -# ) -# -# -# @pytest.mark.parametrize('val', [ -# {'elec': [1.0, 0.5], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, -# ]) -# def test_validate_lambda_schedule_nakedcharge(val, default_settings): -# default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] -# default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] -# default_settings.lambda_settings.lambda_restraints_ligandA = val[ -# 'restraints'] -# default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] -# default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] -# default_settings.lambda_settings.lambda_restraints_ligandB = val[ -# 'restraints'] -# n_replicas = 2 -# default_settings.complex_simulation_settings.n_replicas = n_replicas -# default_settings.solvent_simulation_settings.n_replicas = n_replicas -# errmsg = ( -# "There are states along this lambda schedule " -# "where there are atoms with charges but no LJ " -# "interactions: Ligand A: l") -# with pytest.raises(ValueError, match=errmsg): -# SepTopProtocol._validate_lambda_schedule( -# default_settings.lambda_settings, -# default_settings.complex_simulation_settings, -# ) -# with pytest.raises(ValueError, match=errmsg): -# SepTopProtocol._validate_lambda_schedule( -# default_settings.lambda_settings, -# default_settings.solvent_simulation_settings, -# ) -# -# -# def test_create_default_protocol(default_settings): -# # this is roughly how it should be created -# protocol = SepTopProtocol( -# settings=default_settings, -# ) -# assert protocol -# -# -# def test_serialize_protocol(default_settings): -# protocol = SepTopProtocol( -# settings=default_settings, -# ) -# -# ser = protocol.to_dict() -# ret = SepTopProtocol.from_dict(ser) -# assert protocol == ret -# -# -# def test_create_independent_repeat_ids( -# benzene_complex_system, toluene_complex_system, -# ): -# # if we create two dags each with 3 repeats, they should give 6 repeat_ids -# # this allows multiple DAGs in flight for one Transformation that don't clash on gather -# settings = SepTopProtocol.default_settings() -# # Default protocol is 1 repeat, change to 3 repeats -# settings.protocol_repeats = 3 -# protocol = SepTopProtocol( -# settings=settings, -# ) -# -# dag1 = protocol.create( -# stateA=benzene_complex_system, -# stateB=toluene_complex_system, -# mapping=None, -# ) -# dag2 = protocol.create( -# stateA=benzene_complex_system, -# stateB=toluene_complex_system, -# mapping=None, -# ) -# # print([u for u in dag1.protocol_units]) -# repeat_ids = set() -# for u in dag1.protocol_units: -# repeat_ids.add(u.inputs['repeat_id']) -# for u in dag2.protocol_units: -# repeat_ids.add(u.inputs['repeat_id']) -# -# # There are 4 units per repeat per DAG: 4 * 3 * 2 = 24 -# assert len(repeat_ids) == 24 -# -# -# def test_check_alchem_charge_diff(charged_benzene_modifications): -# errmsg = "A charge difference of 1" -# with pytest.raises(ValueError, match=errmsg): -# _check_alchemical_charge_difference( -# charged_benzene_modifications["benzene"], -# charged_benzene_modifications["benzoic_acid"], -# ) -# -# -# def test_charge_error_create( -# charged_benzene_modifications, T4_protein_component, -# ): -# # if we create two dags each with 3 repeats, they should give 6 repeat_ids -# # this allows multiple DAGs in flight for one Transformation that don't clash on gather -# settings = SepTopProtocol.default_settings() -# # Default protocol is 1 repeat, change to 3 repeats -# settings.protocol_repeats = 3 -# protocol = SepTopProtocol( -# settings=settings, -# ) -# stateA = ChemicalSystem({ -# 'benzene': charged_benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent() -# }) -# -# stateB = ChemicalSystem({ -# 'benzoic': charged_benzene_modifications['benzoic_acid'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# errmsg = "A charge difference of 1" -# with pytest.raises(ValueError, match=errmsg): -# protocol.create( -# stateA=stateA, -# stateB=stateB, -# mapping=None, -# ) -# -# -# def test_validate_complex_endstates_protcomp_stateA( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'solvent': SolventComponent() -# }) -# -# stateB = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# with pytest.raises(ValueError, match="No ProteinComponent found in stateA"): -# SepTopProtocol._validate_complex_endstates(stateA, stateB) -# -# -# def test_validate_complex_endstates_protcomp_stateB( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'solvent': SolventComponent(), -# }) -# -# with pytest.raises(ValueError, match="No ProteinComponent found in stateB"): -# SepTopProtocol._validate_complex_endstates(stateA, stateB) -# -# -# -# def test_validate_complex_endstates_nosolvcomp_stateA( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# }) -# -# stateB = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# with pytest.raises( -# ValueError, match="No SolventComponent found in stateA" -# ): -# SepTopProtocol._validate_complex_endstates(stateA, stateB) -# -# -# def test_validate_complex_endstates_nosolvcomp_stateB( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# }) -# -# with pytest.raises( -# ValueError, match="No SolventComponent found in stateB" -# ): -# SepTopProtocol._validate_complex_endstates(stateA, stateB) -# -# -# def test_validate_alchem_comps_missingA( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) -# -# with pytest.raises(ValueError, match='one alchemical components must be present in stateA.'): -# SepTopProtocol._validate_alchemical_components(alchem_comps) -# -# -# def test_validate_alchem_comps_missingB( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) -# -# with pytest.raises(ValueError, match='one alchemical components must be present in stateB.'): -# SepTopProtocol._validate_alchemical_components(alchem_comps) -# -# -# def test_validate_alchem_comps_toomanyA( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'toluene': benzene_modifications['toluene'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# stateB = ChemicalSystem({ -# 'phenol': benzene_modifications['phenol'], -# 'protein': T4_protein_component, -# 'solvent': SolventComponent(), -# }) -# -# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) -# -# assert len(alchem_comps['stateA']) == 2 -# -# assert len(alchem_comps['stateB']) == 1 -# -# with pytest.raises(ValueError, match='Found 2 alchemical components in stateA'): -# SepTopProtocol._validate_alchemical_components(alchem_comps) -# -# -# def test_validate_alchem_nonsmc( -# benzene_modifications, T4_protein_component, -# ): -# stateA = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'solvent': SolventComponent() -# }) -# -# stateB = ChemicalSystem({ -# 'benzene': benzene_modifications['benzene'], -# 'protein': T4_protein_component -# }) -# -# alchem_comps = system_validation.get_alchemical_components(stateA, stateB) -# -# with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): -# SepTopProtocol._validate_alchemical_components(alchem_comps) - - -@pytest.fixture(scope='session') -def bace_reference_xml(): - with importlib.resources.files('openfe.tests.data.openmm_septop') as d: - f = d / 'system.xml.bz2' - return deserialize(f) - -@pytest.fixture(scope='session') -def bace_reference_positions(): - with importlib.resources.files('openfe.tests.data.openmm_septop') as d: - f = d / 'topology.pdb' - pdb = simtk.openmm.app.pdbfile.PDBFile(str(f)) - positions = pdb.getPositions(asNumpy=True) - return positions - - -def test_reference_alchemical_system(bace_reference_xml, bace_reference_positions): - # Remove Boresch forces - # bace_reference_xml.removeForce(14) - bace_reference_xml.removeForce(13) - alchemical_state = AlchemicalState.from_system(bace_reference_xml) - - from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory - - energy = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions - ) - na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandA' - na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandB' - nonbonded = 'unmodified NonbondedForce' - - # Lambda 0: LigandA sterics on, elec on, ligand B sterics off, elec off - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 0 - alchemical_state.lambda_electrostatics_ligandA = 1 - alchemical_state.lambda_electrostatics_ligandB = 0 - energy_0 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions +@pytest.mark.parametrize('val', [ + {'elec': [0.0, -1], 'vdw': [0.0, 1.0], 'restraints': [0.0, 1.0]}, + {'elec': [0.0, 1.5], 'vdw': [0.0, 1.5], 'restraints': [-0.1, 1.0]} +]) +def test_incorrect_window_settings(val, default_settings): + errmsg = "Lambda windows must be between 0 and 1." + lambda_settings = default_settings.lambda_settings + with pytest.raises(ValueError, match=errmsg): + lambda_settings.lambda_elec_ligandA = val['elec'] + lambda_settings.lambda_vdw_ligandA = val['vdw'] + lambda_settings.lambda_restraints_ligandA = val['restraints'] + + +@pytest.mark.parametrize('val', [ + {'elec': [0.0, 0.1, 0.0], 'vdw': [0.0, 1.0, 1.0], 'restraints': [0.0, 1.0, 1.0]}, +]) +def test_monotonic_lambda_windows(val, default_settings): + errmsg = "The lambda schedule is not monotonic." + lambda_settings = default_settings.lambda_settings + + with pytest.raises(ValueError, match=errmsg): + lambda_settings.lambda_elec_ligandA = val['elec'] + lambda_settings.lambda_vdw_ligandA = val['vdw'] + lambda_settings.lambda_restraints_ligandA = val['restraints'] + + +@pytest.mark.parametrize('val', [ + {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_nreplicas(val, default_settings): + default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] + default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandB = val[ + 'restraints'] + n_replicas = 3 + default_settings.complex_simulation_settings.n_replicas = n_replicas + errmsg = (f"Number of replicas {n_replicas} does not equal the" + f" number of lambda windows {len(val['vdw'])}") + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + + +@pytest.mark.parametrize('val', [ + {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_nwindows(val, default_settings): + default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] + n_replicas = 3 + default_settings.complex_simulation_settings.n_replicas = n_replicas + errmsg = ( + "Components elec, vdw, and restraints must have equal amount of lambda " + "windows. Got 3 and 19 elec lambda windows") + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + + +@pytest.mark.parametrize('val', [ + {'elec': [1.0, 0.5], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, +]) +def test_validate_lambda_schedule_nakedcharge(val, default_settings): + default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandA = val[ + 'restraints'] + default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] + default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] + default_settings.lambda_settings.lambda_restraints_ligandB = val[ + 'restraints'] + n_replicas = 2 + default_settings.complex_simulation_settings.n_replicas = n_replicas + default_settings.solvent_simulation_settings.n_replicas = n_replicas + errmsg = ( + "There are states along this lambda schedule " + "where there are atoms with charges but no LJ " + "interactions: Ligand A: l") + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.complex_simulation_settings, + ) + with pytest.raises(ValueError, match=errmsg): + SepTopProtocol._validate_lambda_schedule( + default_settings.lambda_settings, + default_settings.solvent_simulation_settings, + ) + + +def test_create_default_protocol(default_settings): + # this is roughly how it should be created + protocol = SepTopProtocol( + settings=default_settings, ) + assert protocol - # Lambda 7: LigandA sterics on, elec on, ligand B sterics on, elec off - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 1 - alchemical_state.lambda_electrostatics_ligandB = 0 - energy_7 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions + +def test_serialize_protocol(default_settings): + protocol = SepTopProtocol( + settings=default_settings, ) - # Lambda 8: LigandA sterics on, elec partially on, - # ligand B sterics on, elec partially on - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 0.75 - alchemical_state.lambda_electrostatics_ligandB = 0.25 - energy_8 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions + ser = protocol.to_dict() + ret = SepTopProtocol.from_dict(ser) + assert protocol == ret + + +def test_create_independent_repeat_ids( + benzene_complex_system, toluene_complex_system, +): + # if we create two dags each with 3 repeats, they should give 6 repeat_ids + # this allows multiple DAGs in flight for one Transformation that don't clash on gather + settings = SepTopProtocol.default_settings() + # Default protocol is 1 repeat, change to 3 repeats + settings.protocol_repeats = 3 + protocol = SepTopProtocol( + settings=settings, ) - # Lambda 12: LigandA sterics on, elec off, ligand B sterics on, elec on - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 0 - alchemical_state.lambda_electrostatics_ligandB = 1 - energy_12 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions + dag1 = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + dag2 = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, ) + # print([u for u in dag1.protocol_units]) + repeat_ids = set() + for u in dag1.protocol_units: + repeat_ids.add(u.inputs['repeat_id']) + for u in dag2.protocol_units: + repeat_ids.add(u.inputs['repeat_id']) + + # There are 4 units per repeat per DAG: 4 * 3 * 2 = 24 + assert len(repeat_ids) == 24 + - # Lambda 13: LigandA sterics partially on, elec off, ligand B sterics on, elec on - alchemical_state.lambda_sterics_ligandA = 0.857142857 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 0 - alchemical_state.lambda_electrostatics_ligandB = 1 - energy_13 = AbsoluteAlchemicalFactory.get_energy_components( - bace_reference_xml, alchemical_state, bace_reference_positions +def test_check_alchem_charge_diff(charged_benzene_modifications): + errmsg = "A charge difference of 1" + with pytest.raises(ValueError, match=errmsg): + _check_alchemical_charge_difference( + charged_benzene_modifications["benzene"], + charged_benzene_modifications["benzoic_acid"], + ) + + +def test_charge_error_create( + charged_benzene_modifications, T4_protein_component, +): + # if we create two dags each with 3 repeats, they should give 6 repeat_ids + # this allows multiple DAGs in flight for one Transformation that don't clash on gather + settings = SepTopProtocol.default_settings() + # Default protocol is 1 repeat, change to 3 repeats + settings.protocol_repeats = 3 + protocol = SepTopProtocol( + settings=settings, ) + stateA = ChemicalSystem({ + 'benzene': charged_benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent() + }) + + stateB = ChemicalSystem({ + 'benzoic': charged_benzene_modifications['benzoic_acid'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + errmsg = "A charge difference of 1" + with pytest.raises(ValueError, match=errmsg): + protocol.create( + stateA=stateA, + stateB=stateB, + mapping=None, + ) + + +def test_validate_complex_endstates_protcomp_stateA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'solvent': SolventComponent() + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + with pytest.raises(ValueError, match="No ProteinComponent found in stateA"): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + +def test_validate_complex_endstates_protcomp_stateB( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'solvent': SolventComponent(), + }) + + with pytest.raises(ValueError, match="No ProteinComponent found in stateB"): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + + +def test_validate_complex_endstates_nosolvcomp_stateA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + with pytest.raises( + ValueError, match="No SolventComponent found in stateA" + ): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + +def test_validate_complex_endstates_nosolvcomp_stateB( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + }) + + with pytest.raises( + ValueError, match="No SolventComponent found in stateB" + ): + SepTopProtocol._validate_complex_endstates(stateA, stateB) + + +def test_validate_alchem_comps_missingA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + with pytest.raises(ValueError, match='one alchemical components must be present in stateA.'): + SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_validate_alchem_comps_missingB( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + with pytest.raises(ValueError, match='one alchemical components must be present in stateB.'): + SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_validate_alchem_comps_toomanyA( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'toluene': benzene_modifications['toluene'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'phenol': benzene_modifications['phenol'], + 'protein': T4_protein_component, + 'solvent': SolventComponent(), + }) + + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + + assert len(alchem_comps['stateA']) == 2 + + assert len(alchem_comps['stateB']) == 1 + + with pytest.raises(ValueError, match='Found 2 alchemical components in stateA'): + SepTopProtocol._validate_alchemical_components(alchem_comps) + + +def test_validate_alchem_nonsmc( + benzene_modifications, T4_protein_component, +): + stateA = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'solvent': SolventComponent() + }) + + stateB = ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'protein': T4_protein_component + }) - for key, value in energy.items(): - if key == na_A: - assert is_close(value, energy_0[key]) - assert is_close(value, energy_7[key]) - assert is_close(value, energy_8[key]) - assert is_close(value, energy_12[key]) - assert not is_close(value, energy_13[key]) - elif key == na_B: - assert not is_close(value, energy_0[key]) - assert energy_0[key].value_in_unit(simtk.unit.kilojoule_per_mole) == 0 - assert is_close(value, energy_7[key]) - assert is_close(value, energy_8[key]) - assert is_close(value, energy_12[key]) - assert is_close(value, energy_13[key]) - elif key == nonbonded: - assert not is_close(value, energy_0[key]) - assert is_close(energy_0[key], energy_7[key]) - assert not is_close(energy_0[key], energy_8[key]) - assert not is_close(energy_0[key], energy_12[key]) - assert not is_close(energy_0[key], energy_13[key]) - else: - assert is_close(value, energy_0[key]) - assert is_close(value, energy_7[key]) - assert is_close(value, energy_8[key]) - assert is_close(value, energy_12[key]) - assert is_close(value, energy_13[key]) - assert 4==5 + alchem_comps = system_validation.get_alchemical_components(stateA, stateB) + with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): + SepTopProtocol._validate_alchemical_components(alchem_comps) From ee984b4a41ed7b06cb3586dbea32faca59e2671f Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 13 Dec 2024 14:48:41 +0100 Subject: [PATCH 091/163] Fix energy test --- openfe/tests/protocols/test_openmm_septop_slow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 6cf461cf1..2628ed110 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -107,6 +107,9 @@ def compare_energies(alchemical_system, positions): return na_A, na_B, nonbonded, energy, energy_0, energy_7, energy_8, energy_12, energy_13 +# @pytest.mark.integration # takes too long to be a slow test ~ 4 mins locally +# @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation +# @pytest.mark.parametrize('platform', ['CPU', 'CUDA']) def test_lambda_energies(bace_ligands, bace_protein_component, tmpdir): # check system parametrisation works even if confgen fails s = SepTopProtocol.default_settings() @@ -154,7 +157,7 @@ def test_lambda_energies(bace_ligands, bace_protein_component, tmpdir): positions = pdb.getPositions(asNumpy=True) # Remove Harmonic restraint force solvent - system.removeForce(13) + alchemical_system.removeForce(13) na_A, na_B, nonbonded, energy, energy_0, energy_7, energy_8, \ energy_12, energy_13 = compare_energies(alchemical_system, positions) From 8796be2473263e491921d2a1e8991440c035f15b Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 13 Dec 2024 15:01:16 +0100 Subject: [PATCH 092/163] Fix off molecule --- openfe/protocols/openmm_septop/base.py | 15 ++++++++------- .../openmm_septop/equil_septop_method.py | 6 ++++-- .../protocols/openmm_septop/femto_restraints.py | 12 ++++-------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 9360d6bd2..ffdff1ac8 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -553,23 +553,24 @@ def _update_positions( @staticmethod def _set_positions( - off_topology: OFFMolecule.Topology, + off_molecule: OFFMolecule, positions: unit.Quantity, - ) -> OFFMolecule.Topology: + ) -> OFFMolecule: """ Updates the positions of an OFFMolecule.Topology """ + off_topology = off_molecule.to_topology() off_topology.clear_positions() off_topology.set_positions(positions) - return off_topology + return off_molecule @staticmethod def _add_restraints( system: openmm.System, positions: simtk.unit.Quantity, topology: Optional[openmm.app.Topology], - ligand_1: Optional[OFFMolecule.Topology], - ligand_2: Optional[OFFMolecule.Topology], + ligand_1: Optional[OFFMolecule], + ligand_2: Optional[OFFMolecule], settings: Optional[dict[str, SettingsBaseModel]], ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology @@ -838,10 +839,10 @@ def run(self, dry=False, verbose=True, omm_system_AB = alchemical_system # 10. Apply Restraints - off_A = alchem_comps["stateA"][0].to_openff().to_topology() + off_A = alchem_comps["stateA"][0].to_openff() lig_A_pos = positions_AB[atom_indices_AB_A[0]:atom_indices_AB_A[-1]+1, :] / omm_units.nanometers * unit.nanometer self._set_positions(off_A, lig_A_pos) - off_B = alchem_comps["stateB"][0].to_openff().to_topology() + off_B = alchem_comps["stateB"][0].to_openff() lig_B_pos = positions_AB[ atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, :] / omm_units.nanometers * unit.nanometer diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index b4b8e01b4..506206c7f 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -991,8 +991,8 @@ def _add_restraints( system: openmm.System, positions: simtk.unit.Quantity, topology: Optional[openmm.app.Topology], - ligand_1: Optional[OFFMolecule.Topology], - ligand_2: Optional[OFFMolecule.Topology], + ligand_1: Optional[OFFMolecule], + ligand_2: Optional[OFFMolecule], settings: dict[str, SettingsBaseModel], ligand_1_ref_idxs: tuple[int, int, int], ligand_2_ref_idxs: tuple[int, int, int], @@ -1034,6 +1034,8 @@ def _add_restraints( # Get mdtraj object for system traj = _get_mdtraj_from_openmm(topology, positions) # Get mdtraj object for ligands + ligand_1 = ligand_1.to_topology() + ligand_2 = ligand_2.to_topology() ligand_1_mdtraj = md.Trajectory( np.array(ligand_1.get_positions() / omm_units.nanometers), md.Topology.from_openmm(ligand_1.to_openmm())) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 994708f63..1d074ce33 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -189,8 +189,8 @@ def _create_ligand_queries( def select_ligand_idxs( - ligand_1, # OpenFF Topology - ligand_2, # OpenFF Topology + ligand_1, # OpenFF Molecule + ligand_2, # OpenFF Molecule ligand_1_queries: tuple[str, str, str] | None = None, ligand_2_queries: tuple[str, str, str] | None = None, ) -> tuple[tuple[int, int, int], tuple[int, int, int] | None]: @@ -212,13 +212,9 @@ def select_ligand_idxs( if ligand_1_queries is None: # Setting frames to None right now # ToDo: Enable use of snapshots - ligand_1_queries = _create_ligand_queries(ligand_1, None) + ligand_1_queries = _create_ligand_queries(ligand_1.to_topology(), None) if ligand_2_queries is None: - ligand_2_queries = _create_ligand_queries(ligand_2, None) - - # ligand_1_idxs = queries_to_idxs(ligand_1, ligand_1_queries) - - # ligand_2_idxs = queries_to_idxs(ligand_2, ligand_2_queries) + ligand_2_queries = _create_ligand_queries(ligand_2.to_topology(), None) return ligand_1_queries, ligand_2_queries From 3cce308a8548df90305d7ce11c03f128dee6cc0d Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sat, 14 Dec 2024 00:07:26 +0000 Subject: [PATCH 093/163] add host atom finding routine --- .../restraints/geometry/boresch.py | 277 +++++++++++++++--- .../openmm_utils/restraints/geometry/utils.py | 20 +- 2 files changed, 259 insertions(+), 38 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index 363e22c6b..41bd3b3b7 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -19,6 +19,7 @@ from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals import numpy as np import numpy.typing as npt +from scipy.stats import circmean from .base import HostGuestRestraintGeometry @@ -29,10 +30,10 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): The restraint is defined by the following: - H0 G2 + H2 G2 - - - - - H1 - - H2 -- G0 - - G1 + H1 - - H0 -- G0 - - G1 Where HX represents the X index of ``host_atoms`` and GX the X index of ``guest_atoms``. @@ -43,7 +44,7 @@ def get_bond_distance( coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ - Get the H2 - G0 distance. + Get the H0 - G0 distance. Parameters ---------- @@ -58,7 +59,7 @@ def get_bond_distance( format=_get_mda_coord_format(coordinates), topology_format=_get_mda_topology_format(topology) ) - at1 = u.atoms[host_atoms[2]] + at1 = u.atoms[host_atoms[0]] at2 = u.atoms[guest_atoms[0]] bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) # convert to float so we avoid having a np.float64 @@ -70,7 +71,7 @@ def get_angles( coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ - Get the H1-H2-G0, and H2-G0-G1 angles. + Get the H1-H0-G0, and H0-G0-G1 angles. Parameters ---------- @@ -86,7 +87,7 @@ def get_angles( topology_format=_get_mda_topology_format(topology) ) at1 = u.atoms[host_atoms[1]] - at2 = u.atoms[host_atoms[2]] + at2 = u.atoms[host_atoms[0]] at3 = u.atoms[guest_atoms[0]] at4 = u.atoms[guest_atoms[1]] @@ -104,7 +105,7 @@ def get_dihedrals( coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ - Get the H0-H1-H2-G0, H1-H2-G0-G1, and H2-G0-G1-G2 dihedrals. + Get the H2-H1-H0-G0, H1-H0-G0-G1, and H0-G0-G1-G2 dihedrals. Parameters ---------- @@ -119,9 +120,9 @@ def get_dihedrals( format=_get_mda_coord_format(coordinates), topology_format=_get_mda_topology_format(topology) ) - at1 = u.atoms[host_atoms[0]] + at1 = u.atoms[host_atoms[2]] at2 = u.atoms[host_atoms[1]] - at3 = u.atoms[host_atoms[2]] + at3 = u.atoms[host_atoms[0]] at4 = u.atoms[guest_atoms[0]] at5 = u.atoms[guest_atoms[1]] at6 = u.atoms[guest_atoms[2]] @@ -275,7 +276,7 @@ def get_guest_atom_candidates( Returns ------- angle_list : list[tuple[int]] - A list of tuples for each valid l1, l2, l3 angle. If ``None``, no + A list of tuples for each valid G0, G1, G2 angle. If ``None``, no angles could be found. Raises @@ -343,7 +344,7 @@ def get_host_atom_candidates( rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, min_distance: unit.Quantity = 1 * unit.nanometer, max_distance: unit.Quantity = 3 * unit.nanometer, -): +) -> npt.NDArray: """ Get a list of suitable host atoms. @@ -367,6 +368,11 @@ def get_host_atom_candidates( The minimum search distance around l1 for suitable candidate atoms. max_distance : unit.Quantity The maximum search distance around l1 for suitable candidate atoms. + + Return + ------ + NDArray + Array of host atom indexes """ u = mda.Universe( topology, @@ -395,20 +401,212 @@ def get_host_atom_candidates( return atom_finder.results.host_idxs -class EvaluateH2Atoms(AnalysisBase): +class EvaluateHostAtoms1(AnalysisBase): """ Class to evaluate the suitability of a set of host atoms - as a H2 atom (i.e. bonded to the guest G0 atom). + as H1 atoms (i.e. the second host atom). Parameters ---------- - guest_atoms: MDAnalysis.AtomGroup - The guest atoms representing G0-G1-G2. - host_atom_pool: MDAnalysis.AtomGroup - The pool of atoms to pick a H2 from. + reference : MDAnalysis.AtomGroup + The reference preceeding three atoms. + host_atom_pool : MDAnalysis.AtomGroup + The pool of atoms to pick an atom from. + minimum_distance : unit.Quantity + The minimum distance from the bound reference atom. angle_force_constant : unit.Quantity - The force constant for the H2-G0-G1 angle. + The force constant for the angle. + temperature : unit.Quantity + The system temperature in Kelvin """ + def __init__( + self, + reference, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + **kwargs + ): + super().__init__(reference.universe.trajectory, **kwargs) + + if len(reference) != 3: + errmsg = "Incorrect number of reference atoms passed" + raise ValueError(errmsg) + + self.reference = reference + self.host_atom_pool = host_atom_pool + self.minimum_distance = minimum_distance.to('angstrom').m + self.angle_force_constant = angle_force_constant + self.temperature = temperature + + def _prepare(self): + self.results.distances = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.angles = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.dihedrals = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.collinear = np.empty( + (len(self.host_atom_pool), self.n_frames), + dtype=bool, + ) + self.results.valid = np.empty( + len(self.host_atom_pool), + dtype=bool, + ) + + def _single_frame(self): + for i, at in enumerate(self.host_atom_pool): + distance = calc_bonds( + at.position, + self.reference.atoms[0].position, + box=self.reference.dimensions, + ) + angle = calc_angles( + at.position, + self.reference.atoms[0].position, + self.reference.atoms[1].position, + box=self.reference.dimensions, + ) + dihedral = calc_dihedrals( + at.position, + self.reference.atoms[0].position, + self.reference.atoms[1].position, + self.reference.atoms[2].position, + box=self.reference.dimensions + ) + collinear = is_collinear( + positions=np.vstack((at.position, self.reference.positions)), + dimensions=self.reference.dimensions, + ) + self.results.distances[i][self._frame_index] = distance + self.results.angles[i][self._frame_index] = angle + self.results.dihedrals[i][self._frame_index] = dihedral + self.results.collinear[i][self._frame_index] = collinear + + def _conclude(self): + for i, at in enumerate(self.host_atom_pool): + distance_bounds = all( + self.results.distances[i] > self.minimum_distance + ) + mean_angle = circmean(self.results.angles[i], high=np.pi, low=0) + angle_bounds = check_angle_not_flat( + angle=mean_angle * unit.radians, + force_constant=self.angle_force_constant, + temperature=self.temperature, + ) + angle_variance = check_angular_variance( + self.results.angles[i] * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=0 * unit.radians, + width=1.745 * unit.radians, + ) + mean_dihed = circmean(self.results.dihedrals[i], high=np.pi, low=-np.pi) + dihed_bounds = check_dihedral_bounds(mean_dihed) + dihed_variance = check_angular_variance( + self.results.dihedrals[i] * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=-np.pi * unit.radians, + width=5.23 * unit.radians, + ) + not_collinear = not all(self.results.collinear[i]) + if all([distance_bounds, angle_bounds, angle_variance, dihed_bounds, dihed_variance, not_collinear]): + self.results.valid[i] = True + + +class EvaluateHostAtoms2(EvaluateH21Atoms): + def _prepare(self): + self.results.distances1 = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.ditances2 = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.dihedrals = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.collinear = np.empty( + (len(self.host_atom_pool), self.n_frames), + dtype=bool, + ) + self.results.valid = np.empty( + len(self.host_atom_pool), + dtype=bool, + ) + + def _single_frame(self): + for i, at in enumerate(self.host_atom_pool): + distance1 = calc_bonds( + at.position, + self.reference.atoms[0].position, + box=self.reference.dimensions, + ) + distance2 = calc_bonds( + at.position, + self.reference.atoms[1].position, + box=self.reference.dimensions, + ) + dihedral = calc_dihedrals( + at.position, + self.reference.atoms[0].position, + self.reference.atoms[1].position, + self.reference.atoms[2].position, + box=self.reference.dimensions + ) + collinear = is_collinear( + positions=np.vstack((at.position, self.reference.positions)), + dimensions=self.reference.dimensions, + ) + self.results.distances1[i][self._frame_index] = distance + self.results.distances2[i][self._frame_index] = angle + self.results.dihedrals[i][self._frame_index] = dihedral + self.results.collinear[i][self._frame_index] = collinear + + def _conclude(self): + for i, at in enumerate(self.host_atom_pool): + distance1_bounds = all( + self.results.distances1[i] > self.minimum_distance + ) + distance2_bounds = all( + self.results.distances2[i] > self.minimum_distance + ) + mean_dihed = circmean(self.results.dihedrals[i], high=np.pi, low=-np.pi) + dihed_bounds = check_dihedral_bounds(mean_dihed) + dihed_variance = check_angular_variance( + self.results.dihedrals[i] * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=-np.pi * unit.radians, + width=5.23 * unit.radians, + ) + not_collinear = not all(self.results.collinear[i]) + if all([distance1_bounds, distance2_bounds, dihed_bounds, dihed_variance, not_collinear]): + self.results.valid[i] = True + + +def _find_host_angle(g0g1g2_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature): + h0_eval = EvaluateHAtoms1(g0g1g2_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature) + h0_eval.run() + + for i, valid_h0 in enumerate(h0_eval.results.valid): + if valid_h0: + g1g2h0_atoms = g0g1g2_atoms.atoms[1:] + host_atom_pool.atoms[i] + h1_eval = EvaluateHAtoms1(g1g2h0_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature) + for j, valid_h1 in enumerate(h1_eval.results.valid): + g2h0h1_atoms = g1g2h0_atoms.atoms[1:] + host_atom_pool.atoms[j] + h2_eval = EvaluateHAtoms2(g2h0h1_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature) + + if any(h2_eval.ressults.valid): + d1_avgs = [d.mean() for d in h2_eval.results.distances1] + d2_avgs = [d.mean() for d in h2_eval.results.distances2] + dsum_avgs = d1_avgs + d2_avgs + k = dsum_avgs.argmin() + + return host_atom_pool.atoms[[i, j, k]].ix + return None def find_boresch_restraint( @@ -424,6 +622,8 @@ def find_boresch_restraint( rmsf_custoff: unit.Quantity = 0.1 * unit.nanometer, host_min_distance: unit.Quantity = 1 * unit.nanometer, host_max_distance: unit.Quantity = 3 * unit.nanometer, + angle_force_constant: unit.Quantity = 83.68 * unit.kilojoule_per_mole / unit.radians**2, + temperature: unit.Quantity = 298.15 * unit.kelvin, ) -> BoreschRestraintGeometry: """ Find suitable Boresch-style restraints between a host and guest entity. @@ -448,11 +648,11 @@ def find_boresch_restraint( # In this case assume the picked atoms were intentional / representative # of the input and go with it guest_ag = u.select_atoms[guest_idxs] - guest_angle = (at.ix for at in guest_ag.atoms[guest_restraint_atom_idxs]) + guest_angle = [at.ix for at in guest_ag.atoms[guest_restraint_atom_idxs]] host_ag = u.select_atoms[host_idxs] - host_angle = (at.ix for at in host_ag.atoms[host_restraint_atoms_idxs]) + host_angle = [at.ix for at in host_ag.atoms[host_restraint_atoms_idxs]] # TODO sort out the return on this - return BoreschRestraintGeometry(...) + return BoreschRestraintGeometry(host_atoms=host_angle, guest_atoms=guest_angle) if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): # This is not an intended outcome, crash out here @@ -463,7 +663,7 @@ def find_boresch_restraint( ) raise ValueError(errmsg) - # Fetch the guest angles + # 1. Fetch the guest angles guest_angles = get_guest_atom_candidates( topology=topology, trajectory=trajectory, @@ -472,9 +672,14 @@ def find_boresch_restraint( rmsf_cutoff=rmsf_cutoff, ) + if len(guest_angles) != 0: + errmsg = "No suitable ligand atoms found for the restraint." + raise ValueError(errmsg) + + # We pick the first angle / ligand atom set as the one to use guest_angle = guest_angles[0] - # Fetch the host atom pool + # 2. We next fetch the host atom pool host_pool = get_host_atom_candidates( topology=topology, trajectory=trajectory, @@ -487,15 +692,21 @@ def find_boresch_restraint( max_distance=host_max_distance, ) - # Get the guest angle atomgroup - guest_ag = u.atoms[list(guest_angle)] + # 3. We then loop through the guest angles to find suitable host atoms + for guest_angle in guest_angles: + host_angle = _find_host_angle( + g0g1g2_atoms=u.atoms[list(guest_angle)], + host_atom_pool=u.atoms[host_pool], + minimum_distance=0.5 * unit.nanometer, + angle_force_constant=angle_force_constant, + temperature=temperature, + ) + # continue if it's empty, otherwise stop + if host_angle is not None: + break - # Find all suitable H2 idxs - h2_idxs = [] - for i in host_pool: - host2_at = u.atoms[i] - pos = np.vstack((at.position, guest_ag.positions)) - angle = calc_angles(pos[0], pos[1], pos[2], box=u.dimensions) * unit.radians - dihed = calc_dihedrals(pos[0], pos[1], pos[2], pos[3], box=u.dimensions) * unit.radians - collinear = is_collinear(positions, [0, 1, 2, 3]) + if host_angle is None: + errmsg = "No suitable host atoms could be found" + raise ValueError(errmsg) + return BoreschRestraintGeometry(host_atoms=host_angle, guest_atoms=guest_angle) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index a1f983621..96a665ee5 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -208,7 +208,7 @@ def is_collinear(positions, atoms, dimensions=None, threshold=0.9): return result -def check_angle_energy( +def check_angle_not_flat( angle: FloatQuantity["radians"], force_constant: ANGLE_FRC_CONSTANT_TYPE = DEFAULT_ANGLE_FRC_CONSTANT, temperature: FloatQuantity["kelvin"] = 298.15 * unit.kelvin, @@ -228,7 +228,7 @@ def check_angle_energy( Returns ------- bool - If the angle is less than 10 kT from 0 or pi radians + False if the angle is less than 10 kT from 0 or pi radians Note ---- @@ -280,7 +280,10 @@ def check_dihedral_bounds( def check_angular_variance( - angles: ArrayQuantity["radians"], width: FloatQuantity["radians"] + angles: ArrayQuantity["radians"], width: FloatQuantity["radians"], + upper_bound: FloatQuantity['radians'], + lower_bound: FloatQuantity['radians'], + width: FloatQuantity['radians'], ) -> bool: """ Check that the variance of a list of ``angles`` does not exceed @@ -290,6 +293,10 @@ def check_angular_variance( ---------- angles : ArrayLike[unit.Quantity] An array of angles in units compatible with radians. + upper_bound: FloatQuantity['radians'] + The upper bound in the angle range. + lower_bound: FloatQuantity['radians'] + The lower bound in the angle range. width : unit.Quantity The width to check the variance against, in units compatible with radians. @@ -299,8 +306,11 @@ def check_angular_variance( ``True`` if the variance of the angles is less than the width. """ - array = angles.to("radians").m - variance = circvar(array) + variance = circvar( + angles.to("radians").m, + high=upper_bound.to("radians").m, + low=lower_bound.to("radians").m + ) return not (variance * unit.radians > width) From 9171d3992e2418f1453e0888cf48ec2661c2bc25 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sat, 14 Dec 2024 00:12:14 +0000 Subject: [PATCH 094/163] autoformatting --- .../restraints/geometry/boresch.py | 133 ++++++++++-------- .../openmm_utils/restraints/geometry/utils.py | 24 ++-- 2 files changed, 93 insertions(+), 64 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index 41bd3b3b7..844817f52 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -38,9 +38,10 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): Where HX represents the X index of ``host_atoms`` and GX the X index of ``guest_atoms``. """ + def get_bond_distance( self, - topology: Union[str, pathlib.Path, openmm.app.Topology], + topology: Union[str, pathlib.Path, openmm.app.Topology], coordinates: Union[str, pathlib.Path, npt.NDArray], ) -> unit.Quantity: """ @@ -57,7 +58,7 @@ def get_bond_distance( topology, coordinates, format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology) + topology_format=_get_mda_topology_format(topology), ) at1 = u.atoms[host_atoms[0]] at2 = u.atoms[guest_atoms[0]] @@ -84,7 +85,7 @@ def get_angles( topology, coordinates, format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology) + topology_format=_get_mda_topology_format(topology), ) at1 = u.atoms[host_atoms[1]] at2 = u.atoms[host_atoms[0]] @@ -118,7 +119,7 @@ def get_dihedrals( topology, coordinates, format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology) + topology_format=_get_mda_topology_format(topology), ) at1 = u.atoms[host_atoms[2]] at2 = u.atoms[host_atoms[1]] @@ -292,7 +293,7 @@ def get_guest_atom_candidates( topology, coordinates, format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology) + topology_format=_get_mda_topology_format(topology), ) ligand_ag = u.atoms[guest_idxs] @@ -302,7 +303,7 @@ def get_guest_atom_candidates( u.trajectory[-1] # forward to the last frame # 1. Get the pool of atoms to work with - atom_pool = _get_atom_pool(rdmol: Chem.Mol, rmsf: npt.NDArray) + atom_pool = _get_atom_pool(rdmol, rmsf) if atom_pool is None: # We don't have enough atoms so we raise an error @@ -324,11 +325,7 @@ def get_guest_atom_candidates( angle_ag = ligand_ag.atoms[list(angle)] if not is_collinear(ligand_ag.positions, angle, u.dimensions): angles_list.append( - ( - angle_ag.atoms[0].ix, - angle_ag.atoms[1].ix, - angle_ag.atoms[2].ix - ) + (angle_ag.atoms[0].ix, angle_ag.atoms[1].ix, angle_ag.atoms[2].ix) ) return angles_list @@ -378,7 +375,7 @@ def get_host_atom_candidates( topology, coordinates, format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology) + topology_format=_get_mda_topology_format(topology), ) protein_ag1 = u.atoms[host_idxs] @@ -419,6 +416,7 @@ class EvaluateHostAtoms1(AnalysisBase): temperature : unit.Quantity The system temperature in Kelvin """ + def __init__( self, reference, @@ -426,7 +424,7 @@ def __init__( minimum_distance, angle_force_constant, temperature, - **kwargs + **kwargs, ): super().__init__(reference.universe.trajectory, **kwargs) @@ -436,20 +434,14 @@ def __init__( self.reference = reference self.host_atom_pool = host_atom_pool - self.minimum_distance = minimum_distance.to('angstrom').m + self.minimum_distance = minimum_distance.to("angstrom").m self.angle_force_constant = angle_force_constant self.temperature = temperature def _prepare(self): - self.results.distances = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.angles = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.dihedrals = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) + self.results.distances = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.angles = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.collinear = np.empty( (len(self.host_atom_pool), self.n_frames), dtype=bool, @@ -477,7 +469,7 @@ def _single_frame(self): self.reference.atoms[0].position, self.reference.atoms[1].position, self.reference.atoms[2].position, - box=self.reference.dimensions + box=self.reference.dimensions, ) collinear = is_collinear( positions=np.vstack((at.position, self.reference.positions)), @@ -490,9 +482,7 @@ def _single_frame(self): def _conclude(self): for i, at in enumerate(self.host_atom_pool): - distance_bounds = all( - self.results.distances[i] > self.minimum_distance - ) + distance_bounds = all(self.results.distances[i] > self.minimum_distance) mean_angle = circmean(self.results.angles[i], high=np.pi, low=0) angle_bounds = check_angle_not_flat( angle=mean_angle * unit.radians, @@ -514,21 +504,24 @@ def _conclude(self): width=5.23 * unit.radians, ) not_collinear = not all(self.results.collinear[i]) - if all([distance_bounds, angle_bounds, angle_variance, dihed_bounds, dihed_variance, not_collinear]): + if all( + [ + distance_bounds, + angle_bounds, + angle_variance, + dihed_bounds, + dihed_variance, + not_collinear, + ] + ): self.results.valid[i] = True class EvaluateHostAtoms2(EvaluateH21Atoms): def _prepare(self): - self.results.distances1 = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.ditances2 = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.dihedrals = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) + self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.ditances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.collinear = np.empty( (len(self.host_atom_pool), self.n_frames), dtype=bool, @@ -555,7 +548,7 @@ def _single_frame(self): self.reference.atoms[0].position, self.reference.atoms[1].position, self.reference.atoms[2].position, - box=self.reference.dimensions + box=self.reference.dimensions, ) collinear = is_collinear( positions=np.vstack((at.position, self.reference.positions)), @@ -568,12 +561,8 @@ def _single_frame(self): def _conclude(self): for i, at in enumerate(self.host_atom_pool): - distance1_bounds = all( - self.results.distances1[i] > self.minimum_distance - ) - distance2_bounds = all( - self.results.distances2[i] > self.minimum_distance - ) + distance1_bounds = all(self.results.distances1[i] > self.minimum_distance) + distance2_bounds = all(self.results.distances2[i] > self.minimum_distance) mean_dihed = circmean(self.results.dihedrals[i], high=np.pi, low=-np.pi) dihed_bounds = check_dihedral_bounds(mean_dihed) dihed_variance = check_angular_variance( @@ -583,21 +572,49 @@ def _conclude(self): width=5.23 * unit.radians, ) not_collinear = not all(self.results.collinear[i]) - if all([distance1_bounds, distance2_bounds, dihed_bounds, dihed_variance, not_collinear]): + if all( + [ + distance1_bounds, + distance2_bounds, + dihed_bounds, + dihed_variance, + not_collinear, + ] + ): self.results.valid[i] = True -def _find_host_angle(g0g1g2_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature): - h0_eval = EvaluateHAtoms1(g0g1g2_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature) +def _find_host_angle( + g0g1g2_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature +): + h0_eval = EvaluateHAtoms1( + g0g1g2_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) h0_eval.run() for i, valid_h0 in enumerate(h0_eval.results.valid): if valid_h0: g1g2h0_atoms = g0g1g2_atoms.atoms[1:] + host_atom_pool.atoms[i] - h1_eval = EvaluateHAtoms1(g1g2h0_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature) + h1_eval = EvaluateHAtoms1( + g1g2h0_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) for j, valid_h1 in enumerate(h1_eval.results.valid): g2h0h1_atoms = g1g2h0_atoms.atoms[1:] + host_atom_pool.atoms[j] - h2_eval = EvaluateHAtoms2(g2h0h1_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature) + h2_eval = EvaluateHAtoms2( + g2h0h1_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) if any(h2_eval.ressults.valid): d1_avgs = [d.mean() for d in h2_eval.results.distances1] @@ -616,13 +633,15 @@ def find_boresch_restraint( guest_idxs: list[int], host_idxs: list[int], guest_restraint_atom_idxs: Optional[list[int]] = None, - host_restraint_atoms_idxs Optional[list[int]] = None, - host_selection: str = 'all', + host_restraint_atoms_idxs: Optional[list[int]] = None, + host_selection: str = "all", dssp_filter: bool = False, rmsf_custoff: unit.Quantity = 0.1 * unit.nanometer, host_min_distance: unit.Quantity = 1 * unit.nanometer, host_max_distance: unit.Quantity = 3 * unit.nanometer, - angle_force_constant: unit.Quantity = 83.68 * unit.kilojoule_per_mole / unit.radians**2, + angle_force_constant: unit.Quantity = ( + 83.68 * unit.kilojoule_per_mole / unit.radians**2 + ), temperature: unit.Quantity = 298.15 * unit.kelvin, ) -> BoreschRestraintGeometry: """ @@ -640,11 +659,13 @@ def find_boresch_restraint( topology, coordinates, format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology) + topology_format=_get_mda_topology_format(topology), ) u.trajectory[-1] # Work with the final frame - if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): + if (guest_restraint_atoms_idxs is not None) and ( + host_restraint_atoms_idxs is not None + ): # In this case assume the picked atoms were intentional / representative # of the input and go with it guest_ag = u.select_atoms[guest_idxs] @@ -654,7 +675,9 @@ def find_boresch_restraint( # TODO sort out the return on this return BoreschRestraintGeometry(host_atoms=host_angle, guest_atoms=guest_angle) - if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): + if (guest_restraint_atoms_idxs is not None) ^ ( + host_restraint_atoms_idxs is not None + ): # This is not an intended outcome, crash out here errmsg = ( "both ``guest_restraints_atoms_idxs`` and ``host_restraint_atoms_idxs`` " diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index 96a665ee5..91ce61e8b 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -32,7 +32,9 @@ ANGLE_FRC_CONSTANT_TYPE = FloatQuantity["unit.kilojoule_per_mole / unit.radians**2"] -def _get_mda_coord_format(coordinates: Union[str, npt.NDArray]) -> Optional[MemoryReader]: +def _get_mda_coord_format( + coordinates: Union[str, npt.NDArray] +) -> Optional[MemoryReader]: """ Helper to set the coordinate format to MemoryReader if the coordinates are an NDArray. @@ -51,7 +53,10 @@ def _get_mda_coord_format(coordinates: Union[str, npt.NDArray]) -> Optional[Memo else: return None -def _get_mda_topology_format(topology: Union[str, openmm.app.Topology]) -> Optional[str]: + +def _get_mda_topology_format( + topology: Union[str, openmm.app.Topology] +) -> Optional[str]: """ Helper to set the topology format to OPENMMTOPOLOGY if the topology is an openmm.app.Topology. @@ -59,7 +64,7 @@ def _get_mda_topology_format(topology: Union[str, openmm.app.Topology]) -> Optio Parameters ---------- topology : Union[str, openmm.app.Topology] - + Returns ------- @@ -177,7 +182,7 @@ def is_collinear(positions, atoms, dimensions=None, threshold=0.9): atoms : list[int] The indices of the atoms to test. dimensions : Optional[npt.NDArray] - The dimensions of the system to minimize vectors. + The dimensions of the system to minimize vectors. threshold : float Atoms are not collinear if their sequential vector separation dot products are less than ``threshold``. Default 0.9. @@ -280,10 +285,11 @@ def check_dihedral_bounds( def check_angular_variance( - angles: ArrayQuantity["radians"], width: FloatQuantity["radians"], - upper_bound: FloatQuantity['radians'], - lower_bound: FloatQuantity['radians'], - width: FloatQuantity['radians'], + angles: ArrayQuantity["radians"], + width: FloatQuantity["radians"], + upper_bound: FloatQuantity["radians"], + lower_bound: FloatQuantity["radians"], + width: FloatQuantity["radians"], ) -> bool: """ Check that the variance of a list of ``angles`` does not exceed @@ -309,7 +315,7 @@ def check_angular_variance( variance = circvar( angles.to("radians").m, high=upper_bound.to("radians").m, - low=lower_bound.to("radians").m + low=lower_bound.to("radians").m, ) return not (variance * unit.radians > width) From 033a1e44aadfbf330531b0443842b6f21095e6ec Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sat, 14 Dec 2024 01:21:39 +0000 Subject: [PATCH 095/163] various fixes --- .../restraints/geometry/__init__.py | 4 + .../openmm_utils/restraints/geometry/base.py | 5 - .../restraints/geometry/boresch.py | 170 +++++++++++------- .../restraints/geometry/flatbottom.py | 16 +- .../restraints/geometry/harmonic.py | 33 ++-- .../openmm_utils/restraints/geometry/utils.py | 56 +++--- .../restraints/openmm/omm_forces.py | 2 +- .../restraints/openmm/omm_restraints.py | 108 +++++++---- 8 files changed, 236 insertions(+), 158 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/__init__.py b/openfe/protocols/openmm_utils/restraints/geometry/__init__.py index e69de29bb..1c1b4c56a 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/__init__.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/__init__.py @@ -0,0 +1,4 @@ +from .base import BaseRestraintGeometry +from .harmonic import DistanceRestraintGeometry +from .flatbottom import FlatBottomDistanceGeometry +from .boresch import BoreschRestraintGeometry diff --git a/openfe/protocols/openmm_utils/restraints/geometry/base.py b/openfe/protocols/openmm_utils/restraints/geometry/base.py index 21a714cde..5db9225ac 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/base.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/base.py @@ -10,10 +10,6 @@ import abc from pydantic.v1 import BaseModel, validator -from openff.units import unit -import MDAnalysis as mda -from MDAnalysis.lib.distances import calc_bonds, calc_angles - class BaseRestraintGeometry(BaseModel, abc.ABC): class Config: @@ -47,4 +43,3 @@ def positive_idxs(cls, v): errmsg = "negative indices passed" raise ValueError(errmsg) return v - diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py index 844817f52..0d6806611 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/boresch.py @@ -7,21 +7,34 @@ ---- * Add relevant duecredit entries. """ -import abc import pathlib -from pydantic.v1 import BaseModel, validator +from typing import Union, Optional, Iterable from rdkit import Chem +import openmm from openff.units import unit import MDAnalysis as mda -from MDANalysis.analysis.base import AnalysisBase +from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals import numpy as np import numpy.typing as npt from scipy.stats import circmean from .base import HostGuestRestraintGeometry +from .utils import ( + _get_mda_coord_format, + _get_mda_topology_format, + get_aromatic_rings, + get_heavy_atom_idxs, + get_central_atom_idx, + is_collinear, + check_angular_variance, + check_dihedral_bounds, + check_angle_not_flat, + FindHostAtoms, + get_local_rmsf +) class BoreschRestraintGeometry(HostGuestRestraintGeometry): @@ -60,8 +73,8 @@ def get_bond_distance( format=_get_mda_coord_format(coordinates), topology_format=_get_mda_topology_format(topology), ) - at1 = u.atoms[host_atoms[0]] - at2 = u.atoms[guest_atoms[0]] + at1 = u.atoms[self.host_atoms[0]] + at2 = u.atoms[self.guest_atoms[0]] bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) # convert to float so we avoid having a np.float64 return float(bond) * unit.angstrom @@ -87,10 +100,10 @@ def get_angles( format=_get_mda_coord_format(coordinates), topology_format=_get_mda_topology_format(topology), ) - at1 = u.atoms[host_atoms[1]] - at2 = u.atoms[host_atoms[0]] - at3 = u.atoms[guest_atoms[0]] - at4 = u.atoms[guest_atoms[1]] + at1 = u.atoms[self.host_atoms[1]] + at2 = u.atoms[self.host_atoms[0]] + at3 = u.atoms[self.guest_atoms[0]] + at4 = u.atoms[self.guest_atoms[1]] angleA = calc_angles( at1.position, at2.position, at3.position, u.atoms.dimensions @@ -121,21 +134,24 @@ def get_dihedrals( format=_get_mda_coord_format(coordinates), topology_format=_get_mda_topology_format(topology), ) - at1 = u.atoms[host_atoms[2]] - at2 = u.atoms[host_atoms[1]] - at3 = u.atoms[host_atoms[0]] - at4 = u.atoms[guest_atoms[0]] - at5 = u.atoms[guest_atoms[1]] - at6 = u.atoms[guest_atoms[2]] + at1 = u.atoms[self.host_atoms[2]] + at2 = u.atoms[self.host_atoms[1]] + at3 = u.atoms[self.host_atoms[0]] + at4 = u.atoms[self.guest_atoms[0]] + at5 = u.atoms[self.guest_atoms[1]] + at6 = u.atoms[self.guest_atoms[2]] dihA = calc_dihedrals( - at1.position, at2.position, at3.position, at4.position, u.atoms.dimensions + at1.position, at2.position, at3.position, at4.position, + box=u.dimensions ) dihB = calc_dihedrals( - at2.position, at3.position, at4.position, at5.position, u.atoms.dimensions + at2.position, at3.position, at4.position, at5.position, + box=u.dimensions ) dihC = calc_dihedrals( - at3.position, at4.position, at5.position, at6.position, u.atoms.dimensions + at3.position, at4.position, at5.position, at6.position, + box=u.dimensions ) return dihA, dihB, dihC @@ -213,7 +229,11 @@ def _get_bonded_angles_from_pool( return angles -def _get_atom_pool(rdmol: Chem.Mol, rmsf: npt.NDArray) -> Optional[set[int]]: +def _get_atom_pool( + rdmol: Chem.Mol, + rmsf: npt.NDArray, + rmsf_cutoff: unit.Quantity +) -> Optional[set[int]]: """ Filter atoms based on rmsf & rings, defaulting to heavy atoms if there are not enough. @@ -291,8 +311,8 @@ def get_guest_atom_candidates( """ u = mda.Universe( topology, - coordinates, - format=_get_mda_coord_format(coordinates), + trajectory, + format=_get_mda_coord_format(trajectory), topology_format=_get_mda_topology_format(topology), ) @@ -314,18 +334,22 @@ def get_guest_atom_candidates( center = get_central_atom_idx(rdmol) # 3. Sort the atom pool based on their distance from the center - sorted_anchor_pool = _sort_by_distance_from_atom(rdmol, center, anchor_pool) + sorted_atom_pool = _sort_by_distance_from_atom(rdmol, center, atom_pool) # 4. Get a list of probable angles angles_list = [] - for atom in sorted_anchor_pool: - angles = _get_bonded_angles_from_pool(rdmol, atom, sorted_anchor_pool) - for angle in _angles: + for atom in sorted_atom_pool: + angles = _get_bonded_angles_from_pool(rdmol, atom, sorted_atom_pool) + for angle in angles: # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] if not is_collinear(ligand_ag.positions, angle, u.dimensions): angles_list.append( - (angle_ag.atoms[0].ix, angle_ag.atoms[1].ix, angle_ag.atoms[2].ix) + ( + angle_ag.atoms[0].ix, + angle_ag.atoms[1].ix, + angle_ag.atoms[2].ix + ) ) return angles_list @@ -373,26 +397,29 @@ def get_host_atom_candidates( """ u = mda.Universe( topology, - coordinates, - format=_get_mda_coord_format(coordinates), + trajectory, + format=_get_mda_coord_format(trajectory), topology_format=_get_mda_topology_format(topology), ) - protein_ag1 = u.atoms[host_idxs] - protein_ag2 = protein_ag.select_atoms(protein_selection) + host_ag1 = u.atoms[host_idxs] + host_ag2 = host_ag1.select_atoms(host_selection) # 0. TODO: implement DSSP filter - # Should be able to just call MDA's DSSP method, but will need to catch an exception + # Should be able to just call MDA's DSSP method + # but will need to catch an exception if dssp_filter: - raise NotImplementedError("DSSP filtering is not currently implemented") + raise NotImplementedError( + "DSSP filtering is not currently implemented" + ) # 1. Get the RMSF & filter - rmsf = get_local_rmsf(sub_protein_ag) - protein_ag3 = sub_protein_ag.atoms[rmsf[heavy_atoms] < rmsf_cutoff] + rmsf = get_local_rmsf(host_ag2) + protein_ag3 = host_ag2.atoms[rmsf < rmsf_cutoff] # 2. Search of atoms within the min/max cutoff atom_finder = FindHostAtoms( - protein_ag3, u.atoms[l1_idx], min_search_distance, max_search_distance + protein_ag3, u.atoms[l1_idx], min_distance, max_distance ) atom_finder.run() return atom_finder.results.host_idxs @@ -439,9 +466,15 @@ def __init__( self.temperature = temperature def _prepare(self): - self.results.distances = np.zeros((len(self.host_atom_pool), self.n_frames)) - self.results.angles = np.zeros((len(self.host_atom_pool), self.n_frames)) - self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.distances = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.angles = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.dihedrals = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) self.results.collinear = np.empty( (len(self.host_atom_pool), self.n_frames), dtype=bool, @@ -517,7 +550,7 @@ def _conclude(self): self.results.valid[i] = True -class EvaluateHostAtoms2(EvaluateH21Atoms): +class EvaluateHostAtoms2(EvaluateHostAtoms1): def _prepare(self): self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.ditances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) @@ -554,8 +587,8 @@ def _single_frame(self): positions=np.vstack((at.position, self.reference.positions)), dimensions=self.reference.dimensions, ) - self.results.distances1[i][self._frame_index] = distance - self.results.distances2[i][self._frame_index] = angle + self.results.distances1[i][self._frame_index] = distance1 + self.results.distances2[i][self._frame_index] = distance2 self.results.dihedrals[i][self._frame_index] = dihedral self.results.collinear[i][self._frame_index] = collinear @@ -585,9 +618,13 @@ def _conclude(self): def _find_host_angle( - g0g1g2_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature + g0g1g2_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature ): - h0_eval = EvaluateHAtoms1( + h0_eval = EvaluateHostAtoms1( g0g1g2_atoms, host_atom_pool, minimum_distance, @@ -599,7 +636,7 @@ def _find_host_angle( for i, valid_h0 in enumerate(h0_eval.results.valid): if valid_h0: g1g2h0_atoms = g0g1g2_atoms.atoms[1:] + host_atom_pool.atoms[i] - h1_eval = EvaluateHAtoms1( + h1_eval = EvaluateHostAtoms1( g1g2h0_atoms, host_atom_pool, minimum_distance, @@ -608,7 +645,7 @@ def _find_host_angle( ) for j, valid_h1 in enumerate(h1_eval.results.valid): g2h0h1_atoms = g1g2h0_atoms.atoms[1:] + host_atom_pool.atoms[j] - h2_eval = EvaluateHAtoms2( + h2_eval = EvaluateHostAtoms2( g2h0h1_atoms, host_atom_pool, minimum_distance, @@ -632,11 +669,11 @@ def find_boresch_restraint( guest_rdmol: Chem.Mol, guest_idxs: list[int], host_idxs: list[int], - guest_restraint_atom_idxs: Optional[list[int]] = None, + guest_restraint_atoms_idxs: Optional[list[int]] = None, host_restraint_atoms_idxs: Optional[list[int]] = None, host_selection: str = "all", dssp_filter: bool = False, - rmsf_custoff: unit.Quantity = 0.1 * unit.nanometer, + rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, host_min_distance: unit.Quantity = 1 * unit.nanometer, host_max_distance: unit.Quantity = 3 * unit.nanometer, angle_force_constant: unit.Quantity = ( @@ -657,32 +694,35 @@ def find_boresch_restraint( """ u = mda.Universe( topology, - coordinates, - format=_get_mda_coord_format(coordinates), + trajectory, + format=_get_mda_coord_format(trajectory), topology_format=_get_mda_topology_format(topology), ) u.trajectory[-1] # Work with the final frame - if (guest_restraint_atoms_idxs is not None) and ( - host_restraint_atoms_idxs is not None - ): - # In this case assume the picked atoms were intentional / representative - # of the input and go with it + if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): # fmt: skip + # In this case assume the picked atoms were intentional / + # representative of the input and go with it guest_ag = u.select_atoms[guest_idxs] - guest_angle = [at.ix for at in guest_ag.atoms[guest_restraint_atom_idxs]] + guest_angle = [ + at.ix for at in guest_ag.atoms[guest_restraint_atoms_idxs] + ] host_ag = u.select_atoms[host_idxs] - host_angle = [at.ix for at in host_ag.atoms[host_restraint_atoms_idxs]] + host_angle = [ + at.ix for at in host_ag.atoms[host_restraint_atoms_idxs] + ] # TODO sort out the return on this - return BoreschRestraintGeometry(host_atoms=host_angle, guest_atoms=guest_angle) + return BoreschRestraintGeometry( + host_atoms=host_angle, guest_atoms=guest_angle + ) - if (guest_restraint_atoms_idxs is not None) ^ ( - host_restraint_atoms_idxs is not None - ): + if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): # fmt: skip # This is not an intended outcome, crash out here errmsg = ( - "both ``guest_restraints_atoms_idxs`` and ``host_restraint_atoms_idxs`` " + "both ``guest_restraints_atoms_idxs`` and " + "``host_restraint_atoms_idxs`` " "must be set or both must be None. " - f"Got {guest_restraint_atoms_idxs} and {host_atoms_restraint_atoms_idxs}" + f"Got {guest_restraint_atoms_idxs} and {host_restraint_atoms_idxs}" ) raise ValueError(errmsg) @@ -710,7 +750,7 @@ def find_boresch_restraint( l1_idx=guest_angle[0], host_selection=host_selection, dssp_filter=dssp_filter, - rmsf_cutoff=rmsf_custoff, + rmsf_cutoff=rmsf_cutoff, min_distance=host_min_distance, max_distance=host_max_distance, ) @@ -732,4 +772,6 @@ def find_boresch_restraint( errmsg = "No suitable host atoms could be found" raise ValueError(errmsg) - return BoreschRestraintGeometry(host_atoms=host_angle, guest_atoms=guest_angle) + return BoreschRestraintGeometry( + host_atoms=host_angle, guest_atoms=guest_angle + ) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py b/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py index c7e987736..c9007dd59 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py @@ -7,14 +7,15 @@ ---- * Add relevant duecredit entries. """ -import abc -from pydantic.v1 import BaseModel, validator - +import pathlib +from typing import Union, Optional import numpy as np +from openmm import app from openff.units import unit +from openff.models.types import FloatQuantity import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase -from MDAnalysis.lib.distances import calc_bonds, calc_angles +from MDAnalysis.lib.distances import calc_bonds from .harmonic import ( DistanceRestraintGeometry, @@ -27,7 +28,6 @@ class FlatBottomDistanceGeometry(DistanceRestraintGeometry): A geometry class for a flat bottom distance restraint between two groups of atoms. """ - well_radius: FloatQuantity["nanometer"] @@ -45,8 +45,8 @@ class COMDistanceAnalysis(AnalysisBase): _analysis_algorithm_is_parallelizable = False - def __init__(self, host_atoms, guest_atoms, search_distance, **kwargs): - super().__init__(host_atoms.universe.trajectory, **kwargs) + def __init__(self, group1, group2, **kwargs): + super().__init__(group1.universe.trajectory, **kwargs) self.ag1 = group1 self.ag2 = group2 @@ -67,7 +67,7 @@ def _conclude(self): def get_flatbottom_distance_restraint( - topology: Union[str, openmm.app.Topology], + topology: Union[str, app.Topology], trajectory: pathlib.Path, topology_format: Optional[str] = None, host_atoms: Optional[list[int]] = None, diff --git a/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py b/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py index 36e7a61a7..770f86bcb 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py @@ -7,12 +7,12 @@ ---- * Add relevant duecredit entries. """ -import abc -from pydantic.v1 import BaseModel, validator - +import pathlib +from typing import Union, Optional +from openmm import app from openff.units import unit import MDAnalysis as mda -from MDAnalysis.lib.distances import calc_bonds, calc_angles +from MDAnalysis.lib.distances import calc_bonds from rdkit import Chem from .base import HostGuestRestraintGeometry @@ -50,7 +50,7 @@ def _get_selection(universe, atom_list, selection): def get_distance_restraint( - topology: Union[str, openmm.app.Topology], + topology: Union[str, app.Topology], trajectory: pathlib.Path, topology_format: Optional[str] = None, host_atoms: Optional[list[int]] = None, @@ -61,34 +61,25 @@ def get_distance_restraint( u = mda.Universe(topology, trajectory, topology_format=topology_format) guest_ag = _get_selection(u, guest_atoms, guest_selection) + guest_atoms = [a.ix for a in guest_ag] host_ag = _get_selection(u, host_atoms, host_selection) + host_atoms = [a.ix for a in host_ag] - return DistanceRestraintGeometry(guest_atoms=guest_atoms, host_atoms=host_atoms) + return DistanceRestraintGeometry( + guest_atoms=guest_atoms, host_atoms=host_atoms + ) def get_molecule_centers_restraint( - topology: Union[str, openmm.app.Topology], - trajectory: pathlib.Path, molA_rdmol: Chem.Mol, molB_rdmol: Chem.Mol, molA_idxs: list[int], molB_idxs: list[int], - topology_format: Optional[str] = None, ): # We assume that the mol idxs are ordered centerA = molA_idxs[_get_central_atom_idx(molA_rdmol)] centerB = molB_idxs[_get_central_atom_idx(molB_rdmol)] - u = mda.Universe(topology, trajectory, topology_format=topology_format) - guest_ag = _get_selection( - u, - [centerA], - None, - ) - guest_ag = _get_selection( - u, - [centerB], - None, + return DistanceRestraintGeometry( + guest_atoms=[centerA], host_atoms=[centerB] ) - - return DistsanceRestraintGeometry(guest_atoms=guest_atoms, host_atoms=host_atoms) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/openmm_utils/restraints/geometry/utils.py index 91ce61e8b..7d6906650 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/openmm_utils/restraints/geometry/utils.py @@ -7,29 +7,26 @@ ---- * Add relevant duecredit entries. """ -import abc -from pydantic.v1 import BaseModel, validator - +from typing import Union, Optional import numpy as np import numpy.typing as npt -from scipy.stats import circvar, circmean, circstd +from scipy.stats import circvar +import openmm from openff.toolkit import Molecule as OFFMol from openff.units import unit -from openff.models.types import FloatQuantity, ArrayQuantity import networkx as nx from rdkit import Chem import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase -from MDAnalysis.analysis.rmsf import RMSF -from MDAnalysis.lib.distances import calc_bonds, calc_angles, minimize_vectors +from MDAnalysis.analysis.rms import RMSF +from MDAnalysis.lib.distances import minimize_vectors, capped_distance from MDAnalysis.coordinates.memory import MemoryReader from openfe_analysis.transformations import Aligner, NoJump DEFAULT_ANGLE_FRC_CONSTANT = 83.68 * unit.kilojoule_per_mole / unit.radians**2 -ANGLE_FRC_CONSTANT_TYPE = FloatQuantity["unit.kilojoule_per_mole / unit.radians**2"] def _get_mda_coord_format( @@ -97,7 +94,7 @@ def get_aromatic_rings(rdmol: Chem.Mol) -> list[tuple[int, ...]]: aromatic_rings = [] for ring in ringinfo.AtomRings(): - if all(a in aroms for a in ring): + if all(a in arom_idxs for a in ring): aromatic_rings.append(ring) return aromatic_rings @@ -190,13 +187,14 @@ def is_collinear(positions, atoms, dimensions=None, threshold=0.9): Returns ------- result : bool - Returns True if any sequential pair of vectors is collinear; False otherwise. + Returns True if any sequential pair of vectors is collinear; + False otherwise. Notes ----- Originally from Yank. """ - results = False + result = False for i in range(len(atoms) - 2): v1 = minimize_vectors( positions[atoms[i + 1], :] - positions[atoms[i], :], @@ -214,9 +212,9 @@ def is_collinear(positions, atoms, dimensions=None, threshold=0.9): def check_angle_not_flat( - angle: FloatQuantity["radians"], - force_constant: ANGLE_FRC_CONSTANT_TYPE = DEFAULT_ANGLE_FRC_CONSTANT, - temperature: FloatQuantity["kelvin"] = 298.15 * unit.kelvin, + angle: unit.Quantity, + force_constant: unit.Quantity = DEFAULT_ANGLE_FRC_CONSTANT, + temperature: unit.Quantity = 298.15 * unit.kelvin, ) -> bool: """ Check whether the chosen angle is less than 10 kT from 0 or pi radians @@ -246,8 +244,8 @@ def check_angle_not_flat( RT = 8.31445985 * 0.001 * temp_kelvin # check if angle is <10kT from 0 or 180 - check1 = 0.5 * frc_const * np.power((angle - 0.0), 2) - check2 = 0.5 * frc_const * np.power((angle - np.pi), 2) + check1 = 0.5 * frc_const * np.power((angle_rads - 0.0), 2) + check2 = 0.5 * frc_const * np.power((angle_rads - np.pi), 2) ang_check_1 = check1 / RT ang_check_2 = check2 / RT if ang_check_1 < 10.0 or ang_check_2 < 10.0: @@ -256,9 +254,9 @@ def check_angle_not_flat( def check_dihedral_bounds( - dihedral: FloatQuantity["radians"], - lower_cutoff: FloatQuantity["radians"] = 2.618 * unit.radians, - upper_cutoff: FloatQuantity["radians"] = -2.618 * unit.radians, + dihedral: unit.Quantity, + lower_cutoff: unit.Quantity = 2.618 * unit.radians, + upper_cutoff: unit.Quantity = -2.618 * unit.radians, ) -> bool: """ Check that a dihedral does not exceed the bounds set by @@ -285,11 +283,10 @@ def check_dihedral_bounds( def check_angular_variance( - angles: ArrayQuantity["radians"], - width: FloatQuantity["radians"], - upper_bound: FloatQuantity["radians"], - lower_bound: FloatQuantity["radians"], - width: FloatQuantity["radians"], + angles: unit.Quantity, + upper_bound: unit.Quantity, + lower_bound: unit.Quantity, + width: unit.Quantity, ) -> bool: """ Check that the variance of a list of ``angles`` does not exceed @@ -299,12 +296,13 @@ def check_angular_variance( ---------- angles : ArrayLike[unit.Quantity] An array of angles in units compatible with radians. - upper_bound: FloatQuantity['radians'] - The upper bound in the angle range. - lower_bound: FloatQuantity['radians'] - The lower bound in the angle range. + upper_bound: unit.Quantity + The upper bound in the angle range in radians compatible units. + lower_bound: unit.Quantity + The lower bound in the angle range in radians compatible units. width : unit.Quantity - The width to check the variance against, in units compatible with radians. + The width to check the variance against, in units compatible with + radians. Returns ------- diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py index 3ad9d0aa6..9c288515d 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py +++ b/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py @@ -44,7 +44,7 @@ def get_periodic_boresch_energy_function( def get_custom_compound_bond_force( - n_particles: int = 6, energy_function: str = BORESCH_ENERGY_FUNCTION + energy_function: str, n_particles: int = 6, ): """ Return an OpenMM CustomCompoundForce diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py index a3fe777d3..2b8898a22 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py @@ -15,7 +15,6 @@ * Add Periodic Torsion Boresch class """ import abc -from typing import Optional, Union, Callable import numpy as np import openmm @@ -31,11 +30,16 @@ from openff.units import unit from gufe.settings.models import SettingsBaseModel -from openfe.protocols.openmm_utils.omm_forces import ( + +from openfe.protocols.openmm_utils.restraints.geometry import ( + BaseRestraintGeometry, + DistanceRestraintGeometry, + BoreschRestraintGeometry +) +from .omm_forces import ( get_custom_compound_bond_force, add_force_in_separate_group, get_boresch_energy_function, - get_periodic_boresch_energy_function, ) @@ -49,7 +53,8 @@ class RestraintParameterState(GlobalParameterState): ---------- parameters_name_suffix : Optional[str] If specified, the state will control a modified version of the parameter - ``lambda_restraints_{parameters_name_suffix}` instead of just ``lambda_restraints``. + ``lambda_restraints_{parameters_name_suffix}` instead of just + ``lambda_restraints``. lambda_restraints : Optional[float] The strength of the restraint. If defined, must be between 0 and 1. @@ -66,7 +71,8 @@ class RestraintParameterState(GlobalParameterState): def lambda_restraints(self, instance, new_value): if new_value is not None and not (0.0 <= new_value <= 1.0): errmsg = ( - "lambda_restraints must be between 0.0 and 1.0, " f"got {new_value}" + "lambda_restraints must be between 0.0 and 1.0 " + f"and got {new_value}" ) raise ValueError(errmsg) # Not crashing out on None to match upstream behaviour @@ -101,11 +107,19 @@ def _verify_geometry(self, geometry): pass @abc.abstractmethod - def add_force(self, thermodynamic_state: ThermodynamicState, geometry: BaseRestraintGeometry): + def add_force( + self, + thermodynamic_state: ThermodynamicState, + geometry: BaseRestraintGeometry + ): pass @abc.abstractmethod - def get_standard_state_correction(self, thermodynamic_state: ThermodynamicState, geometry: BaseRestraintGeometry): + def get_standard_state_correction( + self, + thermodynamic_state: ThermodynamicState, + geometry: BaseRestraintGeometry + ): pass @abc.abstractmethod @@ -118,8 +132,8 @@ def _verify_geometry(self, geometry: BaseRestraintGeometry): if len(geometry.host_atoms) != 1 or len(geometry.guest_atoms) != 1: errmsg = ( "host_atoms and guest_atoms must only include a single index " - f"each, got {len(host_atoms)} and " - f"{len(guest_atoms)} respectively." + f"each, got {len(geometry.host_atoms)} and " + f"{len(geometry.guest_atoms)} respectively." ) raise ValueError(errmsg) super()._verify_geometry(geometry) @@ -127,19 +141,25 @@ def _verify_geometry(self, geometry: BaseRestraintGeometry): class BaseRadiallySymmetricRestraintForce(BaseHostGuestRestraints): def _verify_inputs(self) -> None: - if not isinstance(self.settings, BaseDistanceRestraintSettings): + if not isinstance(self.settings, DistanceRestraintSettings): errmsg = f"Incorrect settings type {self.settings} passed through" raise ValueError(errmsg) - def _verify_geometry(self, geometry: DistanceRestraintGeometry) + def _verify_geometry(self, geometry: DistanceRestraintGeometry): if not isinstance(geometry, DistanceRestraintGeometry): errmsg = f"Incorrect geometry class type {geometry} passed through" raise ValueError(errmsg) - def add_force(self, thermodynamic_state: ThermodynamicState, geometry: DistanceRestraintGeometry) -> None: + def add_force( + self, + thermodynamic_state: ThermodynamicState, + geometry: DistanceRestraintGeometry + ) -> None: self._verify_geometry(geometry) force = self._get_force(geometry) - force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) + force.setUsesPeriodicBoundaryConditions( + thermodynamic_state.is_periodic + ) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system add_force_in_separate_group(system, force) @@ -162,9 +182,13 @@ def _get_force(self, geometry: DistanceRestraintGeometry): raise NotImplementedError("only implemented in child classes") -class HarmonicBondRestraint(BaseRadiallySymmetricRestraintForce, SingleBondMixin): +class HarmonicBondRestraint( + BaseRadiallySymmetricRestraintForce, SingleBondMixin +): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: - spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm( + self.settings.spring_constant + ).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintBondForce( spring_constant=spring_constant, restrained_atom_index1=geometry.host_atoms[0], @@ -173,10 +197,16 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: ) -class FlatBottomBondRestraint(BaseRadiallySymmetricRestraintForce, SingleBondMixin): +class FlatBottomBondRestraint( + BaseRadiallySymmetricRestraintForce, SingleBondMixin +): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: - spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) - well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm( + self.settings.spring_constant + ).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm( + geometry.well_radius + ).value_in_unit_system(omm_unit.md_unit_system) return FlatBottomRestraintBondForce( spring_constant=spring_constant, well_radius=well_radius, @@ -188,7 +218,9 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: class CentroidHarmonicRestraint(BaseRadiallySymmetricRestraintForce): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: - spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) + spring_constant = to_openmm( + self.settings.spring_constant + ).value_in_unit_system(omm_unit.md_unit_system) return HarmonicRestraintForce( spring_constant=spring_constant, restrained_atom_index1=geometry.host_atoms, @@ -199,9 +231,13 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: class CentroidFlatBottomRestraint(BaseRadiallySymmetricRestraintForce): def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: - spring_constant = to_openmm(self.settings.spring_constant).value_in_unit_system(omm_unit.md_unit_system) - well_radius = to_openmm(geometry.well_radius).value_in_unit_system(omm_unit.md_unit_system) - return FlatBottomRestraintBondForce( + spring_constant = to_openmm( + self.settings.spring_constant + ).value_in_unit_system(omm_unit.md_unit_system) + well_radius = to_openmm( + geometry.well_radius + ).value_in_unit_system(omm_unit.md_unit_system) + return FlatBottomRestraintForce( spring_constant=spring_constant, well_radius=well_radius, restrained_atom_index1=geometry.host_atoms, @@ -221,10 +257,16 @@ def _verify_geometry(self, geometry: BoreschRestraintGeometry): errmsg = f"Incorrect geometry class type {geometry} passed through" raise ValueError(errmsg) - def add_force(self, thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry) -> None: - _verify_geometry(geometry) + def add_force( + self, + thermodynamic_state: ThermodynamicState, + geometry: BoreschRestraintGeometry + ) -> None: + self._verify_geometry(geometry) force = self._get_force(geometry) - force.setUsesPeriodicBoundaryConditions(thermodynamic_state.is_periodic) + force.setUsesPeriodicBoundaryConditions( + thermodynamic_state.is_periodic + ) # Note .system is a call to get_system() so it's returning a copy system = thermodynamic_state.system add_force_in_separate_group(system, force) @@ -236,7 +278,7 @@ def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: ) force = get_custom_compound_bond_force( - n_particles=6, energy_function=efunc + energy_function=efunc, n_particles=6, ) param_values = [] @@ -256,7 +298,9 @@ def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: 'phi_C0': geometry.phi_C0, } for key, val in parameter_dict.items(): - param_values.append(to_openmm(val).value_in_unit_system(omm_unit.md_unit_system)) + param_values.append( + to_openmm(val).value_in_unit_system(omm_unit.md_unit_system) + ) force.addPerBondParameter(key) force.addGlobalParameter(self.controlling_parameter_name, 1.0) @@ -264,7 +308,9 @@ def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: return force def get_standard_state_correction( - self, thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry + self, + thermodynamic_state: ThermodynamicState, + geometry: BoreschRestraintGeometry ) -> unit.Quantity: self._verify_geometry(geometry) @@ -279,14 +325,16 @@ def get_standard_state_correction( # restraint energies K_r = self.settings.K_r.to('kilojoule_per_mole / nm ** 2') K_thetaA = self.settings.K_thetaA.to('kilojoule_per_mole / radians ** 2') - k_thetaB = self.settings.K_thetaB.to('kilojoule_per_mole / radians ** 2') + K_thetaB = self.settings.K_thetaB.to('kilojoule_per_mole / radians ** 2') K_phiA = self.settings.K_phiA.to('kilojoule_per_mole / radians ** 2') K_phiB = self.settings.K_phiB.to('kilojoule_per_mole / radians ** 2') K_phiC = self.settings.K_phiC.to('kilojoule_per_mole / radians ** 2') numerator1 = 8.0 * (np.pi**2) * StandardV denum1 = (r_aA0**2) * sin_thetaA0 * sin_thetaB0 - numerator2 = np.sqrt(K_r * K_thetaA * K_thetaB * K_phiA * K_phiB * K_phiC) + numerator2 = np.sqrt( + K_r * K_thetaA * K_thetaB * K_phiA * K_phiB * K_phiC + ) denum2 = (2.0 * np.pi * kt)**3 dG = -kt * np.log((numerator1/denum1) * (numerator2/denum2)) From fe1308ee4beff476e6d5e0cb967991fa538cb1c1 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sat, 14 Dec 2024 02:00:19 +0000 Subject: [PATCH 096/163] docstring drive --- .../restraints/openmm/omm_forces.py | 13 +++++ .../restraints/openmm/omm_restraints.py | 48 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py index 9c288515d..52cbbec98 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py +++ b/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py @@ -14,6 +14,19 @@ def get_boresch_energy_function( control_parameter: str, ) -> str: + """ + Return a Boresch-style energy function for a CustomCompoundForce. + + Parameters + ---------- + control_parameter : str + A string for the lambda scaling control parameter + + Returns + ------- + str + The energy function string. + """ energy_function = ( f"{control_parameter} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py index 2b8898a22..18f9f2f34 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py +++ b/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py @@ -96,14 +96,21 @@ def __init__( controlling_parameter_name: str = "lambda_restraints", ): self.settings = restraint_settings + self.controlling_parameter_name = controlling_parameter_name self._verify_settings() @abc.abstractmethod def _verify_settings(self): + """ + Method for validating the settings passed on object construction. + """ pass @abc.abstractmethod def _verify_geometry(self, geometry): + """ + Method for validating that the geometry object passed is correct. + """ pass @abc.abstractmethod @@ -112,6 +119,18 @@ def add_force( thermodynamic_state: ThermodynamicState, geometry: BaseRestraintGeometry ): + """ + Method for in-place adding a force to the System of a + ThermodynamicState. + + Parameters + ---------- + thermodymamic_state : ThermodynamicState + The ThermodynamicState with a System to inplace modify with the + new force. + geometry : BaseRestraintGeometry + A geometry object defining the restraint parameters. + """ pass @abc.abstractmethod @@ -119,7 +138,24 @@ def get_standard_state_correction( self, thermodynamic_state: ThermodynamicState, geometry: BaseRestraintGeometry - ): + ) -> unit.Quantity: + """ + Get the standard state correction for the Force. + + Parameters + ---------- + thermodymamic_state : ThermodynamicState + The ThermodynamicState with a System to inplace modify with the + new force. + geometry : BaseRestraintGeometry + A geometry object defining the restraint parameters. + + Returns + ------- + correction : unit.Quantity + The standard state correction free energy in units compatible + with kilojoule per mole. + """ pass @abc.abstractmethod @@ -304,7 +340,15 @@ def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: force.addPerBondParameter(key) force.addGlobalParameter(self.controlling_parameter_name, 1.0) - force.addBond(geometry.host_atoms + geometry.guest_atoms, param_values) + atoms = [ + geometry.host_atoms[2], + geometry.host_atoms[1], + geometry.host_atoms[0], + geometry.guest_atoms[0], + geometry.guest_atoms[1], + geometry.guest_atoms[2], + ] + force.addBond(atoms, param_values) return force def get_standard_state_correction( From d71b9616055f95c4211bc460afead1446430115e Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 15 Dec 2024 22:59:44 +0000 Subject: [PATCH 097/163] Migrate to restraint_utils --- .../restraints/geometry/harmonic.py | 85 ---- .../__init__.py | 0 .../geometry/__init__.py | 0 .../geometry/base.py | 3 + .../geometry/boresch.py | 289 +++++++++++--- .../geometry/flatbottom.py | 51 ++- .../restraint_utils/geometry/harmonic.py | 144 +++++++ .../geometry/utils.py | 83 ++-- .../openmm/__init__.py | 0 .../openmm/omm_forces.py | 22 +- .../openmm/omm_restraints.py | 371 ++++++++++++++++-- openfe/tests/protocols/restraints/__init__.py | 0 .../restraints/test_geometry_base.py | 25 ++ .../restraints/test_omm_restraints.py | 31 ++ .../restraints/test_openmm_forces.py | 115 ++++++ 15 files changed, 1000 insertions(+), 219 deletions(-) delete mode 100644 openfe/protocols/openmm_utils/restraints/geometry/harmonic.py rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/__init__.py (100%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/geometry/__init__.py (100%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/geometry/base.py (94%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/geometry/boresch.py (74%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/geometry/flatbottom.py (58%) create mode 100644 openfe/protocols/restraint_utils/geometry/harmonic.py rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/geometry/utils.py (88%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/openmm/__init__.py (100%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/openmm/omm_forces.py (85%) rename openfe/protocols/{openmm_utils/restraints => restraint_utils}/openmm/omm_restraints.py (50%) create mode 100644 openfe/tests/protocols/restraints/__init__.py create mode 100644 openfe/tests/protocols/restraints/test_geometry_base.py create mode 100644 openfe/tests/protocols/restraints/test_omm_restraints.py create mode 100644 openfe/tests/protocols/restraints/test_openmm_forces.py diff --git a/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py b/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py deleted file mode 100644 index 770f86bcb..000000000 --- a/openfe/protocols/openmm_utils/restraints/geometry/harmonic.py +++ /dev/null @@ -1,85 +0,0 @@ -# This code is part of OpenFE and is licensed under the MIT license. -# For details, see https://github.com/OpenFreeEnergy/openfe -""" -Restraint Geometry classes - -TODO ----- -* Add relevant duecredit entries. -""" -import pathlib -from typing import Union, Optional -from openmm import app -from openff.units import unit -import MDAnalysis as mda -from MDAnalysis.lib.distances import calc_bonds -from rdkit import Chem - -from .base import HostGuestRestraintGeometry -from .utils import _get_central_atom_idx - - -class DistanceRestraintGeometry(HostGuestRestraintGeometry): - """ - A geometry class for a distance restraint between two groups of atoms. - """ - - def get_distance(self, topology, coordinates) -> unit.Quantity: - u = mda.Universe(topology, coordinates) - ag1 = u.atoms[self.host_atoms] - ag2 = u.atoms[self.guest_atoms] - bond = calc_bonds( - ag1.center_of_mass(), ag2.center_of_mass(), box=u.atoms.dimensions - ) - # convert to float so we avoid having a np.float64 - return float(bond) * unit.angstrom - - -def _get_selection(universe, atom_list, selection): - if atom_list is None: - if selection is None: - raise ValueError( - "one of either the atom lists or selections must be defined" - ) - - ag = universe.select_atoms(selection) - else: - ag = universe.atoms[atom_list] - - return ag - - -def get_distance_restraint( - topology: Union[str, app.Topology], - trajectory: pathlib.Path, - topology_format: Optional[str] = None, - host_atoms: Optional[list[int]] = None, - guest_atoms: Optional[list[int]] = None, - host_selection: Optional[str] = None, - guest_selection: Optional[str] = None, -) -> DistanceRestraintGeometry: - u = mda.Universe(topology, trajectory, topology_format=topology_format) - - guest_ag = _get_selection(u, guest_atoms, guest_selection) - guest_atoms = [a.ix for a in guest_ag] - host_ag = _get_selection(u, host_atoms, host_selection) - host_atoms = [a.ix for a in host_ag] - - return DistanceRestraintGeometry( - guest_atoms=guest_atoms, host_atoms=host_atoms - ) - - -def get_molecule_centers_restraint( - molA_rdmol: Chem.Mol, - molB_rdmol: Chem.Mol, - molA_idxs: list[int], - molB_idxs: list[int], -): - # We assume that the mol idxs are ordered - centerA = molA_idxs[_get_central_atom_idx(molA_rdmol)] - centerB = molB_idxs[_get_central_atom_idx(molB_rdmol)] - - return DistanceRestraintGeometry( - guest_atoms=[centerA], host_atoms=[centerB] - ) diff --git a/openfe/protocols/openmm_utils/restraints/__init__.py b/openfe/protocols/restraint_utils/__init__.py similarity index 100% rename from openfe/protocols/openmm_utils/restraints/__init__.py rename to openfe/protocols/restraint_utils/__init__.py diff --git a/openfe/protocols/openmm_utils/restraints/geometry/__init__.py b/openfe/protocols/restraint_utils/geometry/__init__.py similarity index 100% rename from openfe/protocols/openmm_utils/restraints/geometry/__init__.py rename to openfe/protocols/restraint_utils/geometry/__init__.py diff --git a/openfe/protocols/openmm_utils/restraints/geometry/base.py b/openfe/protocols/restraint_utils/geometry/base.py similarity index 94% rename from openfe/protocols/openmm_utils/restraints/geometry/base.py rename to openfe/protocols/restraint_utils/geometry/base.py index 5db9225ac..0ca6ae200 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/base.py +++ b/openfe/protocols/restraint_utils/geometry/base.py @@ -12,6 +12,9 @@ class BaseRestraintGeometry(BaseModel, abc.ABC): + """ + A base class for a restraint geometry. + """ class Config: arbitrary_types_allowed = True diff --git a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py similarity index 74% rename from openfe/protocols/openmm_utils/restraints/geometry/boresch.py rename to openfe/protocols/restraint_utils/geometry/boresch.py index 0d6806611..6e740f48d 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -14,6 +14,7 @@ import openmm from openff.units import unit +from openff.models.types import FloatQuantity import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals @@ -51,107 +52,137 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): Where HX represents the X index of ``host_atoms`` and GX the X index of ``guest_atoms``. """ + r_aA0: FloatQuantity['nanometer'] + """ + The equilibrium distance between H0 and G0. + """ + theta_A0: FloatQuantity['radians'] + """ + The equilibrium angle value between H1, H0, and G0. + """ + theta_B0: FloatQuantity['radians'] + """ + The equilibrium angle value between H0, G0, and G1. + """ + phi_A0: FloatQuantity['radians'] + """ + The equilibrium dihedral value between H2, H1, H0, and G0. + """ + phi_B0: FloatQuantity['radians'] + + """ + The equilibrium dihedral value between H1, H0, G0, and G1. + """ + phi_C0: FloatQuantity['radians'] + + """ + The equilibrium dihedral value between H0, G0, G1, and G2. + """ def get_bond_distance( self, - topology: Union[str, pathlib.Path, openmm.app.Topology], - coordinates: Union[str, pathlib.Path, npt.NDArray], + universe: mda.Universe, ) -> unit.Quantity: """ Get the H0 - G0 distance. Parameters ---------- - topology : Union[str, openmm.app.Topology] - coordinates : Union[str, npt.NDArray] - A coordinate file or NDArray in frame-atom-coordinate - order in Angstrom. + universe : mda.Universe + A Universe representing the system of interest. + + Returns + ------- + bond : unit.Quantity + The H0-G0 distance. """ - u = mda.Universe( - topology, - coordinates, - format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology), + at1 = universe.atoms[self.host_atoms[0]] + at2 = universe.atoms[self.guest_atoms[0]] + bond = calc_bonds( + at1.position, + at2.position, + box=universe.atoms.dimensions ) - at1 = u.atoms[self.host_atoms[0]] - at2 = u.atoms[self.guest_atoms[0]] - bond = calc_bonds(at1.position, at2.position, u.atoms.dimensions) # convert to float so we avoid having a np.float64 return float(bond) * unit.angstrom def get_angles( self, - topology: Union[str, pathlib.Path, openmm.app.Topology], - coordinates: Union[str, pathlib.Path, npt.NDArray], - ) -> unit.Quantity: + universe: mda.Universe, + ) -> tuple[unit.Quantity, unit.Quantity]: """ Get the H1-H0-G0, and H0-G0-G1 angles. Parameters ---------- - topology : Union[str, openmm.app.Topology] - coordinates : Union[str, npt.NDArray] - A coordinate file or NDArray in frame-atom-coordinate - order in Angstrom. + universe : mda.Universe + A Universe representing the system of interest. + + Returns + ------- + angleA : unit.Quantity + The H1-H0-G0 angle. + angleB : unit.Quantity + The H0-G0-G1 angle. """ - u = mda.Universe( - topology, - coordinates, - format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology), - ) - at1 = u.atoms[self.host_atoms[1]] - at2 = u.atoms[self.host_atoms[0]] - at3 = u.atoms[self.guest_atoms[0]] - at4 = u.atoms[self.guest_atoms[1]] + at1 = universe.atoms[self.host_atoms[1]] + at2 = universe.atoms[self.host_atoms[0]] + at3 = universe.atoms[self.guest_atoms[0]] + at4 = universe.atoms[self.guest_atoms[1]] angleA = calc_angles( - at1.position, at2.position, at3.position, u.atoms.dimensions + at1.position, + at2.position, + at3.position, + box=universe.atoms.dimensions ) angleB = calc_angles( - at2.position, at3.position, at4.position, u.atoms.dimensions + at2.position, + at3.position, + at4.position, + box=universe.atoms.dimensions ) return angleA, angleB def get_dihedrals( self, - topology: Union[str, pathlib.Path, openmm.app.Topology], - coordinates: Union[str, pathlib.Path, npt.NDArray], - ) -> unit.Quantity: + universe: mda.Universe, + ) -> tuple[unit.Quantity, unit.Quantity, unit.Quantity]: """ Get the H2-H1-H0-G0, H1-H0-G0-G1, and H0-G0-G1-G2 dihedrals. Parameters ---------- - topology : Union[str, openmm.app.Topology] - coordinates : Union[str, npt.NDArray] - A coordinate file or NDArray in frame-atom-coordinate - order in Angstrom. + universe : mda.Universe + A Universe representing the system of interest. + + Returns + ------- + dihA : unit.Quantity + The H2-H1-H0-G0 angle. + dihB : unit.Quantity + The H1-H0-G0-G1 angle. + dihC : unit.Quantity + The H0-G0-G1-G2 angle. """ - u = mda.Universe( - topology, - coordinates, - format=_get_mda_coord_format(coordinates), - topology_format=_get_mda_topology_format(topology), - ) - at1 = u.atoms[self.host_atoms[2]] - at2 = u.atoms[self.host_atoms[1]] - at3 = u.atoms[self.host_atoms[0]] - at4 = u.atoms[self.guest_atoms[0]] - at5 = u.atoms[self.guest_atoms[1]] - at6 = u.atoms[self.guest_atoms[2]] + at1 = universe.atoms[self.host_atoms[2]] + at2 = universe.atoms[self.host_atoms[1]] + at3 = universe.atoms[self.host_atoms[0]] + at4 = universe.atoms[self.guest_atoms[0]] + at5 = universe.atoms[self.guest_atoms[1]] + at6 = universe.atoms[self.guest_atoms[2]] dihA = calc_dihedrals( at1.position, at2.position, at3.position, at4.position, - box=u.dimensions + box=universe.dimensions ) dihB = calc_dihedrals( at2.position, at3.position, at4.position, at5.position, - box=u.dimensions + box=universe.dimensions ) dihC = calc_dihedrals( at3.position, at4.position, at5.position, at6.position, - box=u.dimensions + box=universe.dimensions ) return dihA, dihB, dihC @@ -307,7 +338,7 @@ def get_guest_atom_candidates( TODO ---- - Remember to update the RDMol with the last frame positions. + Should the RDMol have a specific frame position? """ u = mda.Universe( topology, @@ -663,6 +694,66 @@ def _find_host_angle( return None +def _get_restraint_distances( + atomgroup: mda.AtomGroup +) -> tuple[unit.Quantity]: + """ + Get the bond, angle, and dihedral distances for an input atomgroup + defining the six atoms for a Boresch-like restraint. + + The atoms must be in the order of H0, H1, H2, G0, G1, G2. + + Parameters + ---------- + atomgroup : mda.AtomGroup + An AtomGroup defining the restrained atoms in order. + + Returns + ------- + bond : unit.Quantity + The H0-G0 bond value. + angle1 : unit.Quantity + The H1-H0-G0 angle value. + angle2 : unit.Quantity + The H0-G0-G1 angle value. + dihed1 : unit.Quantity + The H2-H1-H0-G0 dihedral value. + dihed2 : unit.Quantity + The H1-H0-G0-G1 dihedral value. + dihed3 : unit.Quantity + The H0-G0-G1-G2 dihedral value. + """ + + bond = calc_bonds( + atomgroup.atoms[0].position, + atomgroup.atoms[3], + box=atomgroup.dimensions + ) + + angles = [] + for idx_set in [[1, 0, 3], [0, 3, 4]]: + angle = calc_angles( + atomgroup.atoms[idx_set[0]].position, + atomgroup.atoms[idx_set[1]].position, + atomgroup.atoms[idx_set[2]].position, + box=atomgroup.dimensions, + ) + angles.append(angle * unit.radians) + + dihedrals = [] + for idx_set in [[2, 1, 0, 3], [1, 0, 3, 4], [0, 3, 4, 5]]: + dihed = calc_dihedrals( + atomgroup.atoms[idx_set[0]].position, + atomgroup.atoms[idx_set[1]].position, + atomgroup.atoms[idx_set[2]].position, + atomgroup.atoms[idx_set[3]].position, + box=atomgroup.dimensions, + ) + dihedrals.append(dihed * unit.radians) + + return bond, angles[0], angles[1], dihedrals[0], dihedrals[1], dihedrals[2] + + def find_boresch_restraint( topology: Union[str, pathlib.Path, openmm.app.Topology], trajectory: Union[str, pathlib.Path], @@ -682,15 +773,60 @@ def find_boresch_restraint( temperature: unit.Quantity = 298.15 * unit.kelvin, ) -> BoreschRestraintGeometry: """ - Find suitable Boresch-style restraints between a host and guest entity. + Find suitable Boresch-style restraints between a host and guest entity + based on the approach of Baumann et al. [1] with some modifications. Parameters ---------- - ... + topology : Union[str, pathlib.Path, openmm.app.Topology] + A topology of the system. + trajectory : Union[str, pathlib.Path] + A path to a coordinate trajectory file. + guest_rdmol : Chem.Mol + An RDKit Mol for the guest molecule. + guest_idxs : list[int] + Indices in the topology for the guest molecule. + host_idxs : list[int] + Indices in the topology for the host molecule. + guest_restraint_atoms_idxs : Optional[list[int]] + User selected indices of the guest molecule itself (i.e. indexed + starting a 0 for the guest molecule). This overrides the + restraint search and a restraint using these indices will + be retruned. Must be defined alongside ``host_restraint_atoms_idxs``. + host_restraint_atoms_idxs : Optional[list[int]] + User selected indices of the host molecule itself (i.e. indexed + starting a 0 for the hosts molecule). This overrides the + restraint search and a restraint using these indices will + be returnned. Must be defined alongside ``guest_restraint_atoms_idxs``. + host_selection : str + An MDAnalysis selection string to sub-select the host atoms. + dssp_filter : bool + Whether or not to filter the host atoms by their secondary structure. + rmsf_cutoff : unit.Quantity + The cutoff value for atom root mean square fluction. Atoms with RMSF + values above this cutoff will be disregarded. + Must be in units compatible with nanometer. + host_min_distance : unit.Quantity + The minimum distance between any host atom and the guest G0 atom. + Must be in units compatible with nanometer. + host_max_distance : unit.Quantity + The maximum distance between any host atom and the guest G0 atom. + Must be in units compatible with nanometer. + angle_force_constant : unit.Quantity + The force constant for the G1-G0-H0 and G0-H0-H1 angles. Must be + in units compatible with kilojoule / mole / radians ** 2. + temperature : unit.Quantity + The system temperature in units compatible with Kelvin. Returns ------- - ... + BoreschRestraintGeometry + An object defining the parameters of the Boresch-like restraint. + + References + ---------- + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy + calculations using a Separated Topologies approach." (2023). """ u = mda.Universe( topology, @@ -698,7 +834,6 @@ def find_boresch_restraint( format=_get_mda_coord_format(trajectory), topology_format=_get_mda_topology_format(topology), ) - u.trajectory[-1] # Work with the final frame if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): # fmt: skip # In this case assume the picked atoms were intentional / @@ -711,9 +846,23 @@ def find_boresch_restraint( host_angle = [ at.ix for at in host_ag.atoms[host_restraint_atoms_idxs] ] - # TODO sort out the return on this + + # Set the equilibrium values as those of the final frame + u.trajectory[-1] + atomgroup = u.atoms[host_angle + guest_angle] + bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( + atomgroup + ) + return BoreschRestraintGeometry( - host_atoms=host_angle, guest_atoms=guest_angle + host_atoms=host_angle, + guest_atoms=guest_angle, + r_aA0=bond, + theta_A0=ang1, + theta_B0=ang2, + phi_A0=dih1, + phi_B0=dih2, + phi_C0=dih3 ) if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): # fmt: skip @@ -772,6 +921,20 @@ def find_boresch_restraint( errmsg = "No suitable host atoms could be found" raise ValueError(errmsg) + # Set the equilibrium values as those of the final frame + u.trajectory[-1] + atomgroup = u.atoms[host_angle + guest_angle] + bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( + atomgroup + ) + return BoreschRestraintGeometry( - host_atoms=host_angle, guest_atoms=guest_angle + host_atoms=host_angle, + guest_atoms=guest_angle, + r_aA0=bond, + theta_A0=ang1, + theta_B0=ang2, + phi_A0=dih1, + phi_B0=dih2, + phi_C0=dih3 ) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py b/openfe/protocols/restraint_utils/geometry/flatbottom.py similarity index 58% rename from openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py rename to openfe/protocols/restraint_utils/geometry/flatbottom.py index c9007dd59..3b4599f56 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/flatbottom.py +++ b/openfe/protocols/restraint_utils/geometry/flatbottom.py @@ -19,9 +19,10 @@ from .harmonic import ( DistanceRestraintGeometry, - _get_selection, ) +from .utils import _get_mda_topology_format, _get_mda_selection + class FlatBottomDistanceGeometry(DistanceRestraintGeometry): """ @@ -42,7 +43,6 @@ class COMDistanceAnalysis(AnalysisBase): group2 : MDANalysis.AtomGroup Atoms defining the second centroid. """ - _analysis_algorithm_is_parallelizable = False def __init__(self, group1, group2, **kwargs): @@ -68,18 +68,55 @@ def _conclude(self): def get_flatbottom_distance_restraint( topology: Union[str, app.Topology], - trajectory: pathlib.Path, - topology_format: Optional[str] = None, + trajectory: Union[str, pathlib.Path], host_atoms: Optional[list[int]] = None, guest_atoms: Optional[list[int]] = None, host_selection: Optional[str] = None, guest_selection: Optional[str] = None, padding: unit.Quantity = 0.5 * unit.nanometer, ) -> FlatBottomDistanceGeometry: - u = mda.Universe(topology, trajectory, topology_format=topology_format) + """ + Get a FlatBottomDistanceGeometry by analyzing the COM distance + change between two sets of atoms. + + The ``well_radius`` is defined as the maximum COM distance plus + ``padding``. + + Parameters + ---------- + topology : Union[str, app.Topology] + A topology defining the system. + trajectory : Union[str, pathlib.Path] + A coordinate trajectory for the system. + host_atoms : Optional[list[int]] + A list of host atoms indices. Either ``host_atoms`` or + ``host_selection`` must be defined. + guest_atoms : Optional[list[int]] + A list of guest atoms indices. Either ``guest_atoms`` or + ``guest_selection`` must be defined. + host_selection : Optional[str] + An MDAnalysis selection string to define the host atoms. + Either ``host_atoms`` or ``host_selection`` must be defined. + guest_selection : Optional[str] + An MDAnalysis selection string to define the guest atoms. + Either ``guest_atoms`` or ``guest_selection`` must be defined. + padding : unit.Quantity + A padding value to add to the ``well_radius`` definition. + Must be in units compatible with nanometers. + + Returns + ------- + FlatBottomDistanceGeometry + An object defining a flat bottom restraint geometry. + """ + u = mda.Universe( + topology, + trajectory, + topology_format=_get_mda_topology_format(topology) + ) - guest_ag = _get_selection(u, guest_atoms, guest_selection) - host_ag = _get_selection(u, host_atoms, host_selection) + guest_ag = _get_mda_selection(u, guest_atoms, guest_selection) + host_ag = _get_mda_selection(u, host_atoms, host_selection) com_dists = COMDistanceAnalysis(guest_ag, host_ag) com_dists.run() diff --git a/openfe/protocols/restraint_utils/geometry/harmonic.py b/openfe/protocols/restraint_utils/geometry/harmonic.py new file mode 100644 index 000000000..197a8bc44 --- /dev/null +++ b/openfe/protocols/restraint_utils/geometry/harmonic.py @@ -0,0 +1,144 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +import pathlib +from typing import Union, Optional +from openmm import app +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.lib.distances import calc_bonds +from rdkit import Chem + +from .base import HostGuestRestraintGeometry +from .utils import ( + get_central_atom_idx, + _get_mda_selection, + _get_mda_topology_format, +) + + +class DistanceRestraintGeometry(HostGuestRestraintGeometry): + """ + A geometry class for a distance restraint between two groups of atoms. + """ + + def get_distance(self, universe: mda.Universe) -> unit.Quantity: + """ + Get the center of mass distance between the host and guest atoms. + + Parameters + ---------- + universe : mda.Universe + A Universe representing the system of interest. + + Returns + ------- + bond : unit.Quantity + The center of mass distance between the two groups of atoms. + """ + ag1 = universe.atoms[self.host_atoms] + ag2 = universe.atoms[self.guest_atoms] + bond = calc_bonds( + ag1.center_of_mass(), + ag2.center_of_mass(), + box=universe.atoms.dimensions + ) + # convert to float so we avoid having a np.float64 + return float(bond) * unit.angstrom + + +def get_distance_restraint( + topology: Union[str, pathlib.Path, app.Topology], + trajectory: Union[str, pathlib.Path], + host_atoms: Optional[list[int]] = None, + guest_atoms: Optional[list[int]] = None, + host_selection: Optional[str] = None, + guest_selection: Optional[str] = None, +) -> DistanceRestraintGeometry: + """ + Get a DistanceRestraintGeometry between two groups of atoms. + + You can either select the groups by passing through a set of indices + or an MDAnalysis selection. + + Parameters + ---------- + topology : Union[str, pathlib.Path, app.Topology] + A path or object defining the system topology. + trajectory : Union[str, pathlib.Path] + Coordinates for the system. + host_atoms : Optional[list[int]] + A list of host atoms indices. Either ``host_atoms`` or + ``host_selection`` must be defined. + guest_atoms : Optional[list[int]] + A list of guest atoms indices. Either ``guest_atoms`` or + ``guest_selection`` must be defined. + host_selection : Optional[str] + An MDAnalysis selection string to define the host atoms. + Either ``host_atoms`` or ``host_selection`` must be defined. + guest_selection : Optional[str] + An MDAnalysis selection string to define the guest atoms. + Either ``guest_atoms`` or ``guest_selection`` must be defined. + + Returns + ------- + DistanceRestraintGeometry + An object that defines a distance restraint geometry. + """ + u = mda.Universe( + topology, + trajectory, + topology_format=_get_mda_topology_format(topology) + ) + + guest_ag = _get_mda_selection(u, guest_atoms, guest_selection) + guest_atoms = [a.ix for a in guest_ag] + host_ag = _get_mda_selection(u, host_atoms, host_selection) + host_atoms = [a.ix for a in host_ag] + + return DistanceRestraintGeometry( + guest_atoms=guest_atoms, host_atoms=host_atoms + ) + + +def get_molecule_centers_restraint( + molA_rdmol: Chem.Mol, + molB_rdmol: Chem.Mol, + molA_idxs: list[int], + molB_idxs: list[int], +): + """ + Get a DistanceRestraintGeometry between the central atoms of + two molecules. + + Parameters + ---------- + molA_rdmol : Chem.Mol + An RDKit Molecule for the first molecule. + molB_rdmol : Chem.Mol + An RDKit Molecule for the first molecule. + molA_idxs : list[int] + The indices of the first molecule in the system. Note we assume these + to be sorted in the same order as the input rdmol. + molB_idxs : list[int] + The indices of the first molecule in the system. Note we assume these + to be sorted in the same order as the input rdmol. + + Returns + ------- + DistanceRestraintGeometry + An object that defines a distance restraint geometry. + """ + # We assume that the mol idxs are ordered + centerA = molA_idxs[get_central_atom_idx(molA_rdmol)] + centerB = molB_idxs[get_central_atom_idx(molB_rdmol)] + + return DistanceRestraintGeometry( + guest_atoms=[centerA], host_atoms=[centerB] + ) diff --git a/openfe/protocols/openmm_utils/restraints/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py similarity index 88% rename from openfe/protocols/openmm_utils/restraints/geometry/utils.py rename to openfe/protocols/restraint_utils/geometry/utils.py index 7d6906650..4b734b410 100644 --- a/openfe/protocols/openmm_utils/restraints/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -22,13 +22,59 @@ from MDAnalysis.analysis.rms import RMSF from MDAnalysis.lib.distances import minimize_vectors, capped_distance from MDAnalysis.coordinates.memory import MemoryReader +from MDAnalysis.transformations.nojump import NoJump -from openfe_analysis.transformations import Aligner, NoJump +from openfe_analysis.transformations import Aligner DEFAULT_ANGLE_FRC_CONSTANT = 83.68 * unit.kilojoule_per_mole / unit.radians**2 +def _get_mda_selection( + universe: mda.Universe, + atom_list: Optional[list[int]], + selection: Optional[str] +) -> mda.AtomGroup: + """ + Return an AtomGroup based on either a list of atom indices or an + mdanalysis string selection. + + Parameters + ---------- + universe : mda.Universe + The MDAnalysis Universe to get the AtomGroup from. + atom_list : Optional[list[int]] + A list of atom indices. + selection : Optional[str] + An MDAnalysis selection string. + + Returns + ------- + ag : mda.AtomGroup + An atom group selected from the inputs. + + Raises + ------ + ValueError + If both ``atom_list`` and ``selection`` are ``None`` + or are defined. + """ + if atom_list is None: + if selection is None: + raise ValueError( + "one of either the atom lists or selections must be defined" + ) + + ag = universe.select_atoms(selection) + else: + if selection is not None: + raise ValueError( + "both atom_list and selection cannot be defined together" + ) + ag = universe.atoms[atom_list] + return ag + + def _get_mda_coord_format( coordinates: Union[str, npt.NDArray] ) -> Optional[MemoryReader]: @@ -224,7 +270,8 @@ def check_angle_not_flat( angle : unit.Quantity The angle to check in units compatible with radians. force_constant : unit.Quantity - Force constant of the angle in units compatible with kilojoule_per_mole / radians ** 2. + Force constant of the angle in units compatible with + kilojoule_per_mole / radians ** 2. temperature : unit.Quantity The system temperature in units compatible with Kelvin. @@ -334,7 +381,6 @@ class FindHostAtoms(AnalysisBase): max_search_distance: unit.Quantity Maximum distance to filter atoms within. """ - _analysis_algorithm_is_parallelizable = False def __init__( @@ -372,34 +418,7 @@ def _conclude(self): self.results.host_idxs = np.array(self.results.host_idxs) -def find_host_atoms( - topology, trajectory, host_selection, guest_selection, cutoff -) -> mda.AtomGroup: - """ - Get an AtomGroup of the host atoms based on their distances from the guest atoms. - """ - u = mda.Universe(topology, trajectory) - - def _get_selection(selection): - """ - If it's a str, call select_atoms, if not a list of atom idxs - """ - if isinstance(selection, str): - ag = u.select_atoms(host_selection) - else: - ag = u.atoms[host_ag] - return ag - - host_ag = _get_selection(host_selection) - guest_ag = _get_selection(guest_selection) - - finder = FindHostAtoms(host_ag, guest_ag, cutoff) - finder.run() - - return u.atoms[list(finder.results.host_idxs)] - - -def get_local_rmsf(atomgroup: mda.AtomGroup): +def get_local_rmsf(atomgroup: mda.AtomGroup) -> unit.Quantity: """ Get the RMSF of an AtomGroup when aligned upon itself. @@ -416,7 +435,7 @@ def get_local_rmsf(atomgroup: mda.AtomGroup): copy_u = atomgroup.universe.copy() ag = copy_u.atoms[atomgroup.atoms.ix] - nojump = NoJump(ag) + nojump = NoJump() align = Aligner(ag) copy_u.trajectory.add_transformations(nojump, align) diff --git a/openfe/protocols/openmm_utils/restraints/openmm/__init__.py b/openfe/protocols/restraint_utils/openmm/__init__.py similarity index 100% rename from openfe/protocols/openmm_utils/restraints/openmm/__init__.py rename to openfe/protocols/restraint_utils/openmm/__init__.py diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py b/openfe/protocols/restraint_utils/openmm/omm_forces.py similarity index 85% rename from openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py rename to openfe/protocols/restraint_utils/openmm/omm_forces.py index 52cbbec98..2947c8e03 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_forces.py +++ b/openfe/protocols/restraint_utils/openmm/omm_forces.py @@ -43,6 +43,20 @@ def get_boresch_energy_function( def get_periodic_boresch_energy_function( control_parameter: str, ) -> str: + """ + Return a Boresch-style energy function with a periodic torsion for a + CustomCompoundForce. + + Parameters + ---------- + control_parameter : str + A string for the lambda scaling control parameter + + Returns + ------- + str + The energy function string. + """ energy_function = ( f"{control_parameter} * E; " "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " @@ -104,8 +118,12 @@ def add_force_in_separate_group( Mostly reproduced from `Yank `_. """ available_force_groups = set(range(32)) - for force in system.getForces(): - available_force_groups.discard(force.getForceGroup()) + for existing_force in system.getForces(): + available_force_groups.discard(existing_force.getForceGroup()) + + if len(available_force_groups) == 0: + errmsg = "No available force groups could be found" + raise ValueError(errmsg) force.setForceGroup(min(available_force_groups)) system.addForce(force) diff --git a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py b/openfe/protocols/restraint_utils/openmm/omm_restraints.py similarity index 50% rename from openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py rename to openfe/protocols/restraint_utils/openmm/omm_restraints.py index 18f9f2f34..c77b1cd0b 100644 --- a/openfe/protocols/openmm_utils/restraints/openmm/omm_restraints.py +++ b/openfe/protocols/restraint_utils/openmm/omm_restraints.py @@ -31,7 +31,7 @@ from gufe.settings.models import SettingsBaseModel -from openfe.protocols.openmm_utils.restraints.geometry import ( +from openfe.protocols.restraint_utils.geometry import ( BaseRestraintGeometry, DistanceRestraintGeometry, BoreschRestraintGeometry @@ -87,22 +87,20 @@ class BaseHostGuestRestraints(abc.ABC): TODO ---- - Add some examples here. + Add some developer examples here. """ def __init__( self, restraint_settings: SettingsBaseModel, - controlling_parameter_name: str = "lambda_restraints", ): self.settings = restraint_settings - self.controlling_parameter_name = controlling_parameter_name - self._verify_settings() + self._verify_inputs() @abc.abstractmethod - def _verify_settings(self): + def _verify_inputs(self): """ - Method for validating the settings passed on object construction. + Method for validating that the inputs to the class are correct. """ pass @@ -117,10 +115,11 @@ def _verify_geometry(self, geometry): def add_force( self, thermodynamic_state: ThermodynamicState, - geometry: BaseRestraintGeometry + geometry: BaseRestraintGeometry, + controlling_parameter_name: str, ): """ - Method for in-place adding a force to the System of a + Method for in-place adding the Force to the System of a ThermodynamicState. Parameters @@ -130,6 +129,8 @@ def add_force( new force. geometry : BaseRestraintGeometry A geometry object defining the restraint parameters. + controlling_parameter_name : str + The name of the controlling parameter for the Force. """ pass @@ -140,7 +141,8 @@ def get_standard_state_correction( geometry: BaseRestraintGeometry ) -> unit.Quantity: """ - Get the standard state correction for the Force. + Get the standard state correction for the Force when + applied to the input ThermodynamicState. Parameters ---------- @@ -159,11 +161,23 @@ def get_standard_state_correction( pass @abc.abstractmethod - def _get_force(self, geometry: BaseRestraintGeometry): + def _get_force( + self, + geometry: BaseRestraintGeometry, + controlling_parameter_name: str, + ): + """ + Helper method to get the relevant OpenMM Force for this + class, given an input geometry. + """ pass class SingleBondMixin: + """ + A mixin to extend geometry checks for Forces that can only hold + a single atom. + """ def _verify_geometry(self, geometry: BaseRestraintGeometry): if len(geometry.host_atoms) != 1 or len(geometry.guest_atoms) != 1: errmsg = ( @@ -176,6 +190,12 @@ def _verify_geometry(self, geometry: BaseRestraintGeometry): class BaseRadiallySymmetricRestraintForce(BaseHostGuestRestraints): + """ + A base class for all radially symmetic Forces acting between + two sets of atoms. + + Must be subclassed. + """ def _verify_inputs(self) -> None: if not isinstance(self.settings, DistanceRestraintSettings): errmsg = f"Incorrect settings type {self.settings} passed through" @@ -189,10 +209,25 @@ def _verify_geometry(self, geometry: DistanceRestraintGeometry): def add_force( self, thermodynamic_state: ThermodynamicState, - geometry: DistanceRestraintGeometry + geometry: DistanceRestraintGeometry, + controlling_parameter_name: str = "lambda_restraints", ) -> None: + """ + Method for in-place adding the Force to the System of the + given ThermodynamicState. + + Parameters + ---------- + thermodymamic_state : ThermodynamicState + The ThermodynamicState with a System to inplace modify with the + new force. + geometry : BaseRestraintGeometry + A geometry object defining the restraint parameters. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + """ self._verify_geometry(geometry) - force = self._get_force(geometry) + force = self._get_force(geometry, controlling_parameter_name) force.setUsesPeriodicBoundaryConditions( thermodynamic_state.is_periodic ) @@ -206,6 +241,24 @@ def get_standard_state_correction( thermodynamic_state: ThermodynamicState, geometry: DistanceRestraintGeometry, ) -> unit.Quantity: + """ + Get the standard state correction for the Force when + applied to the input ThermodynamicState. + + Parameters + ---------- + thermodymamic_state : ThermodynamicState + The ThermodynamicState with a System to inplace modify with the + new force. + geometry : BaseRestraintGeometry + A geometry object defining the restraint parameters. + + Returns + ------- + correction : unit.Quantity + The standard state correction free energy in units compatible + with kilojoule per mole. + """ self._verify_geometry(geometry) force = self._get_force(geometry) corr = force.compute_standard_state_correction( @@ -214,14 +267,50 @@ def get_standard_state_correction( dg = corr * thermodynamic_state.kT return from_openmm(dg).to('kilojoule_per_mole') - def _get_force(self, geometry: DistanceRestraintGeometry): + def _get_force( + self, + geometry: DistanceRestraintGeometry, + controlling_parameter_name: str + ): raise NotImplementedError("only implemented in child classes") class HarmonicBondRestraint( BaseRadiallySymmetricRestraintForce, SingleBondMixin ): - def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: + """ + A class to add a harmonic restraint between two atoms + in an OpenMM system. + + The restraint is defined as a + :class:`openmmtools.forces.HarmonicRestraintBondForce`. + + Notes + ----- + * Settings must contain a ``spring_constant`` for the + Force in units compatible with kilojoule/mole. + """ + def _get_force( + self, + geometry: DistanceRestraintGeometry, + controlling_parameter_name: str, + ) -> openmm.Force: + """ + Get the HarmonicRestraintBondForce given an input geometry. + + Parameters + ---------- + geometry : DistanceRestraintGeometry + A geometry class that defines how the Force is applied. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + + Returns + ------- + HarmonicRestraintBondForce + An OpenMM Force that applies a harmonic restraint between + two atoms. + """ spring_constant = to_openmm( self.settings.spring_constant ).value_in_unit_system(omm_unit.md_unit_system) @@ -229,14 +318,46 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant=spring_constant, restrained_atom_index1=geometry.host_atoms[0], restrained_atom_index2=geometry.guest_atoms[0], - controlling_parameter_name=self.controlling_parameter_name, + controlling_parameter_name=controlling_parameter_name, ) class FlatBottomBondRestraint( BaseRadiallySymmetricRestraintForce, SingleBondMixin ): - def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: + """ + A class to add a flat bottom restraint between two atoms + in an OpenMM system. + + The restraint is defined as a + :class:`openmmtools.forces.FlatBottomRestraintBondForce`. + + Notes + ----- + * Settings must contain a ``spring_constant`` for the + Force in units compatible with kilojoule/mole. + """ + def _get_force( + self, + geometry: DistanceRestraintGeometry, + controlling_parameter_name: str, + ) -> openmm.Force: + """ + Get the FlatBottomRestraintBondForce given an input geometry. + + Parameters + ---------- + geometry : DistanceRestraintGeometry + A geometry class that defines how the Force is applied. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + + Returns + ------- + FlatBottomRestraintBondForce + An OpenMM Force that applies a flat bottom restraint between + two atoms. + """ spring_constant = to_openmm( self.settings.spring_constant ).value_in_unit_system(omm_unit.md_unit_system) @@ -248,12 +369,44 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: well_radius=well_radius, restrained_atom_index1=geometry.host_atoms[0], restrained_atom_index2=geometry.guest_atoms[0], - controlling_parameter_name=self.controlling_parameter_name, + controlling_parameter_name=controlling_parameter_name, ) class CentroidHarmonicRestraint(BaseRadiallySymmetricRestraintForce): - def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: + """ + A class to add a harmonic restraint between the centroid of + two sets of atoms in an OpenMM system. + + The restraint is defined as a + :class:`openmmtools.forces.HarmonicRestraintForce`. + + Notes + ----- + * Settings must contain a ``spring_constant`` for the + Force in units compatible with kilojoule/mole. + """ + def _get_force( + self, + geometry: DistanceRestraintGeometry, + controlling_parameter_name: str, + ) -> openmm.Force: + """ + Get the HarmonicRestraintForce given an input geometry. + + Parameters + ---------- + geometry : DistanceRestraintGeometry + A geometry class that defines how the Force is applied. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + + Returns + ------- + HarmonicRestraintForce + An OpenMM Force that applies a harmonic restraint between + the centroid of two sets of atoms. + """ spring_constant = to_openmm( self.settings.spring_constant ).value_in_unit_system(omm_unit.md_unit_system) @@ -261,12 +414,44 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: spring_constant=spring_constant, restrained_atom_index1=geometry.host_atoms, restrained_atom_index2=geometry.guest_atoms, - controlling_parameter_name=self.controlling_parameter_name, + controlling_parameter_name=controlling_parameter_name, ) class CentroidFlatBottomRestraint(BaseRadiallySymmetricRestraintForce): - def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: + """ + A class to add a flat bottom restraint between the centroid + of two sets of atoms in an OpenMM system. + + The restraint is defined as a + :class:`openmmtools.forces.FlatBottomRestraintForce`. + + Notes + ----- + * Settings must contain a ``spring_constant`` for the + Force in units compatible with kilojoule/mole. + """ + def _get_force( + self, + geometry: DistanceRestraintGeometry, + controlling_parameter_name: str, + ) -> openmm.Force: + """ + Get the FlatBottomRestraintForce given an input geometry. + + Parameters + ---------- + geometry : DistanceRestraintGeometry + A geometry class that defines how the Force is applied. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + + Returns + ------- + FlatBottomRestraintForce + An OpenMM Force that applies a flat bottom restraint between + the centroid of two sets of atoms. + """ spring_constant = to_openmm( self.settings.spring_constant ).value_in_unit_system(omm_unit.md_unit_system) @@ -278,17 +463,80 @@ def _get_force(self, geometry: DistanceRestraintGeometry) -> openmm.Force: well_radius=well_radius, restrained_atom_index1=geometry.host_atoms, restrained_atom_index2=geometry.guest_atoms, - controlling_parameter_name=self.controlling_parameter_name, + controlling_parameter_name=controlling_parameter_name, ) class BoreschRestraint(BaseHostGuestRestraints): - def _verify_settings(self) -> None: + """ + A class to add a Boresch-like restraint between six atoms, + + The restraint is defined as a + :class:`openmmtools.forces.CustomCompoundForce` with the + following energy function: + + lambda_control_parameter * E; + E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 + + (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 + + (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + + (K_phiC/2)*dphi_C^2; + dphi_A = dA - floor(dA/(2.0*pi)+0.5)*(2.0*pi); + dA = dihedral(p1,p2,p3,p4) - phi_A0; + dphi_B = dB - floor(dB/(2.0*pi)+0.5)*(2.0*pi); + dB = dihedral(p2,p3,p4,p5) - phi_B0; + dphi_C = dC - floor(dC/(2.0*pi)+0.5)*(2.0*pi); + dC = dihedral(p3,p4,p5,p6) - phi_C0; + + Where p1, p2, p3, p4, p5, p6 represent host atoms 2, 1, 0, + and guest atoms 0, 1, 2 respectively. + + ``lambda_control_parameter`` is a control parameter for + scaling the Force. + + ``K_r`` is defined as the bond spring constant between + p3 and p4 and must be provided in the settings in units + compatible with kilojoule / mole. + + ``r_aA0`` is the equilibrium distance of the bond between + p3 and p4. This must be provided by the Geometry class in + units compatiblle with nanometer. + + ``K_thetaA`` and ``K_thetaB`` are the spring constants for the angles + formed by (p2, p3, p4) and (p3, p4, p5). They must be provided in the + settings in units compatible with kilojoule / mole / radians**2. + + ``theta_A0`` and ``theta_B0`` are the equilibrium values for angles + (p2, p3, p4) and (p3, p4, p5). They must be provided by the + Geometry class in units compatible with radians. + + ``phi_A0``, ``phi_B0``, and ``phi_C0`` are the equilibrium constants + for the dihedrals formed by (p1, p2, p3, p4), (p2, p3, p4, p5), and + (p3, p4, p5, p6). They must be provided in the settings in units + compatible with kilojoule / mole / radians ** 2. + + ``phi_A0``, ``phi_B0``, and ``phi_C0`` are the equilibrium values + for the dihedrals formed by (p1, p2, p3, p4), (p2, p3, p4, p5), and + (p3, p4, p5, p6). They must be provided in the Geometry class in + units compatible with radians. + + + Notes + ----- + * Settings must define the ``K_r`` (d) + """ + def _verify_inputs(self) -> None: + """ + Method for validating that the geometry object is correct. + """ if not isinstance(self.settings, BoreschRestraintSettings): errmsg = f"Incorrect settings type {self.settings} passed through" raise ValueError(errmsg) def _verify_geometry(self, geometry: BoreschRestraintGeometry): + """ + Method for validating that the geometry object is correct. + """ if not isinstance(geometry, BoreschRestraintGeometry): errmsg = f"Incorrect geometry class type {geometry} passed through" raise ValueError(errmsg) @@ -296,10 +544,28 @@ def _verify_geometry(self, geometry: BoreschRestraintGeometry): def add_force( self, thermodynamic_state: ThermodynamicState, - geometry: BoreschRestraintGeometry + geometry: BoreschRestraintGeometry, + controlling_parameter_name: str, ) -> None: + """ + Method for in-place adding the Boresch CustomCompoundForce + to the System of the given ThermodynamicState. + + Parameters + ---------- + thermodymamic_state : ThermodynamicState + The ThermodynamicState with a System to inplace modify with the + new force. + geometry : BaseRestraintGeometry + A geometry object defining the restraint parameters. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + """ self._verify_geometry(geometry) - force = self._get_force(geometry) + force = self._get_force( + geometry, + controlling_parameter_name, + ) force.setUsesPeriodicBoundaryConditions( thermodynamic_state.is_periodic ) @@ -308,10 +574,29 @@ def add_force( add_force_in_separate_group(system, force) thermodynamic_state.system = system - def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: - efunc = get_boresch_energy_function( - self.controlling_parameter_name, - ) + def _get_force( + self, + geometry: BoreschRestraintGeometry, + controlling_parameter_name: str + ) -> openmm.CustomCompoundBondForce: + """ + Get the CustomCompoundForce with a Boresch-like energy function + given an input geometry. + + Parameters + ---------- + geometry : DistanceRestraintGeometry + A geometry class that defines how the Force is applied. + controlling_parameter_name : str + The name of the controlling parameter for the Force. + + Returns + ------- + CustomCompoundForce + An OpenMM CustomCompoundForce that applies a Boresch-like + restraint between 6 atoms. + """ + efunc = get_boresch_energy_function(controlling_parameter_name) force = get_custom_compound_bond_force( energy_function=efunc, n_particles=6, @@ -339,7 +624,7 @@ def _get_force(self, geometry: BoreschRestraintGeometry) -> openmm.Force: ) force.addPerBondParameter(key) - force.addGlobalParameter(self.controlling_parameter_name, 1.0) + force.addGlobalParameter(controlling_parameter_name, 1.0) atoms = [ geometry.host_atoms[2], geometry.host_atoms[1], @@ -356,6 +641,32 @@ def get_standard_state_correction( thermodynamic_state: ThermodynamicState, geometry: BoreschRestraintGeometry ) -> unit.Quantity: + """ + Get the standard state correction for the Boresch-like + restraint when applied to the input ThermodynamicState. + + The correction is calculated using the analytical method + as defined by Boresch et al. [1] + + Parameters + ---------- + thermodymamic_state : ThermodynamicState + The ThermodynamicState with a System to inplace modify with the + new force. + geometry : BaseRestraintGeometry + A geometry object defining the restraint parameters. + + Returns + ------- + correction : unit.Quantity + The standard state correction free energy in units compatible + with kilojoule per mole. + + References + ---------- + [1] Boresch S, Tettinger F, Leitgeb M, Karplus M. J Phys Chem B. 107:9535, 2003. + http://dx.doi.org/10.1021/jp0217839 + """ self._verify_geometry(geometry) StandardV = 1.66053928 * unit.nanometer**3 diff --git a/openfe/tests/protocols/restraints/__init__.py b/openfe/tests/protocols/restraints/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openfe/tests/protocols/restraints/test_geometry_base.py b/openfe/tests/protocols/restraints/test_geometry_base.py new file mode 100644 index 000000000..139c57dc5 --- /dev/null +++ b/openfe/tests/protocols/restraints/test_geometry_base.py @@ -0,0 +1,25 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe + +import pytest + +from openfe.protocols.restraint_utils.geometry.base import ( + HostGuestRestraintGeometry +) + + +def test_hostguest_geometry(): + """ + A very basic will it build test. + """ + geom = HostGuestRestraintGeometry(guest_atoms=[1, 2, 3], host_atoms=[4]) + + assert isinstance(geom, HostGuestRestraintGeometry) + + +def test_hostguest_positiveidxs_validator(): + """ + Check that the validator is working as intended. + """ + with pytest.raises(ValueError, match="negative indices passed"): + geom = HostGuestRestraintGeometry(guest_atoms=[-1, 1], host_atoms=[0]) diff --git a/openfe/tests/protocols/restraints/test_omm_restraints.py b/openfe/tests/protocols/restraints/test_omm_restraints.py new file mode 100644 index 000000000..0e346f9c5 --- /dev/null +++ b/openfe/tests/protocols/restraints/test_omm_restraints.py @@ -0,0 +1,31 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe + +import pytest + +from openfe.protocols.restraint_utils.openmm.omm_restraints import ( + RestraintParameterState, +) + + +def test_parameter_state_default(): + param_state = RestraintParameterState() + assert param_state.lambda_restraints is None + + +@pytest.mark.parametrize('suffix', [None, 'foo']) +@pytest.mark.parametrize('lambda_var', [0, 0.5, 1.0]) +def test_parameter_state_suffix(suffix, lambda_var): + param_state = RestraintParameterState( + parameters_name_suffix=suffix, lambda_restraints=lambda_var + ) + + if suffix is not None: + param_name = f'lambda_restraints_{suffix}' + else: + param_name = 'lambda_restraints' + + assert getattr(param_state, param_name) == lambda_var + assert len(param_state._parameters.keys()) == 1 + assert param_state._parameters[param_name] == lambda_var + assert param_state._parameters_name_suffix == suffix diff --git a/openfe/tests/protocols/restraints/test_openmm_forces.py b/openfe/tests/protocols/restraints/test_openmm_forces.py new file mode 100644 index 000000000..cd2a7f21e --- /dev/null +++ b/openfe/tests/protocols/restraints/test_openmm_forces.py @@ -0,0 +1,115 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe + +import pytest +import numpy as np +import openmm +from openfe.protocols.restraint_utils.openmm.omm_forces import ( + get_boresch_energy_function, + get_periodic_boresch_energy_function, + get_custom_compound_bond_force, + add_force_in_separate_group, +) + + +@pytest.mark.parametrize('param', ['foo', 'bar']) +def test_boresch_energy_function(param): + """ + Base regression test for the energy function + """ + fn = get_boresch_energy_function(param) + assert fn == ( + f"{param} * E; " + "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " + "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " + "+ (K_phiA/2)*dphi_A^2 + (K_phiB/2)*dphi_B^2 + (K_phiC/2)*dphi_C^2; " + "dphi_A = dA - floor(dA/(2.0*pi)+0.5)*(2.0*pi); dA = dihedral(p1,p2,p3,p4) - phi_A0; " + "dphi_B = dB - floor(dB/(2.0*pi)+0.5)*(2.0*pi); dB = dihedral(p2,p3,p4,p5) - phi_B0; " + "dphi_C = dC - floor(dC/(2.0*pi)+0.5)*(2.0*pi); dC = dihedral(p3,p4,p5,p6) - phi_C0; " + f"pi = {np.pi}; " + ) + + +@pytest.mark.parametrize('param', ['foo', 'bar']) +def test_periodic_boresch_energy_function(param): + """ + Base regression test for the energy function + """ + fn = get_periodic_boresch_energy_function(param) + assert fn == ( + f"{param} * E; " + "E = (K_r/2)*(distance(p3,p4) - r_aA0)^2 " + "+ (K_thetaA/2)*(angle(p2,p3,p4)-theta_A0)^2 + (K_thetaB/2)*(angle(p3,p4,p5)-theta_B0)^2 " + "+ (K_phiA/2)*uphi_A + (K_phiB/2)*uphi_B + (K_phiC/2)*uphi_C; " + "uphi_A = (1-cos(dA)); dA = dihedral(p1,p2,p3,p4) - phi_A0; " + "uphi_B = (1-cos(dB)); dB = dihedral(p2,p3,p4,p5) - phi_B0; " + "uphi_C = (1-cos(dC)); dC = dihedral(p3,p4,p5,p6) - phi_C0; " + f"pi = {np.pi}; " + ) + + +@pytest.mark.parametrize('num_atoms', [6, 20]) +def test_custom_compound_force(num_atoms): + fn = get_boresch_energy_function('lambda_restraints') + force = get_custom_compound_bond_force(fn, num_atoms) + + # Check we have the right object + assert isinstance(force, openmm.CustomCompoundBondForce) + + # Check the energy function + assert force.getEnergyFunction() == fn + + # Check the number of particles + assert force.getNumParticlesPerBond() == num_atoms + + +@pytest.mark.parametrize('groups, expected', [ + [[0, 1, 2, 3, 4], 5], + [[1, 2, 3, 4, 5], 0], +]) +def test_add_force_in_separate_group(groups, expected): + # Create an empty system + system = openmm.System() + + # Create some forces with some force groups + base_forces = [ + openmm.NonbondedForce(), + openmm.HarmonicBondForce(), + openmm.HarmonicAngleForce(), + openmm.PeriodicTorsionForce(), + openmm.CMMotionRemover(), + ] + + for force, group in zip(base_forces, groups): + force.setForceGroup(group) + + [system.addForce(force) for force in base_forces] + + # Get your CustomCompoundBondForce + fn = get_boresch_energy_function('lambda_restraints') + new_force = get_custom_compound_bond_force(fn, 6) + # new_force.setForceGroup(5) + # system.addForce(new_force) + add_force_in_separate_group(system=system, force=new_force) + + # Loop through and check that we go assigned the expected force group + for force in system.getForces(): + if isinstance(force, openmm.CustomCompoundBondForce): + assert force.getForceGroup() == expected + + +def test_add_too_many_force_groups(): + # Create a system + system = openmm.System() + + # Fill it upu with 32 forces with different groups + for i in range(32): + f = openmm.HarmonicBondForce() + f.setForceGroup(i) + system.addForce(f) + + # Now try to add another force + with pytest.raises(ValueError, match="No available force group"): + add_force_in_separate_group( + system=system, force=openmm.HarmonicBondForce() + ) \ No newline at end of file From c914b18c63026524de550303f8662819c354bcd0 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 16 Dec 2024 09:22:31 +0000 Subject: [PATCH 098/163] base for restraint settings --- openfe/protocols/restraint_utils/settings.py | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 openfe/protocols/restraint_utils/settings.py diff --git a/openfe/protocols/restraint_utils/settings.py b/openfe/protocols/restraint_utils/settings.py new file mode 100644 index 000000000..0c12aef17 --- /dev/null +++ b/openfe/protocols/restraint_utils/settings.py @@ -0,0 +1,23 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Settings for adding restraints. +""" +from typing import Optional, Literal +from openff.units import unit +from openff.models.types import FloatQuantity, ArrayQuantity + +from gufe.settings import ( + SettingsBaseModel, +) + + +from pydantic.v1 import validator + + +class BaseRestraintSettings(SettingsBaseModel): + """ + Base class for RestraintSettings objects. + """ + class Config: + arbitrary_types_allowed = True From d24a5a5a6909c35b906c3c9a42d1d15f929fac0b Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 16 Dec 2024 11:20:14 +0000 Subject: [PATCH 099/163] Fix up some things --- .../restraint_utils/geometry/boresch.py | 237 ++++++------------ .../restraint_utils/geometry/harmonic.py | 26 -- 2 files changed, 82 insertions(+), 181 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py index 6e740f48d..2b0cd2313 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -79,113 +79,6 @@ class BoreschRestraintGeometry(HostGuestRestraintGeometry): The equilibrium dihedral value between H0, G0, G1, and G2. """ - def get_bond_distance( - self, - universe: mda.Universe, - ) -> unit.Quantity: - """ - Get the H0 - G0 distance. - - Parameters - ---------- - universe : mda.Universe - A Universe representing the system of interest. - - Returns - ------- - bond : unit.Quantity - The H0-G0 distance. - """ - at1 = universe.atoms[self.host_atoms[0]] - at2 = universe.atoms[self.guest_atoms[0]] - bond = calc_bonds( - at1.position, - at2.position, - box=universe.atoms.dimensions - ) - # convert to float so we avoid having a np.float64 - return float(bond) * unit.angstrom - - def get_angles( - self, - universe: mda.Universe, - ) -> tuple[unit.Quantity, unit.Quantity]: - """ - Get the H1-H0-G0, and H0-G0-G1 angles. - - Parameters - ---------- - universe : mda.Universe - A Universe representing the system of interest. - - Returns - ------- - angleA : unit.Quantity - The H1-H0-G0 angle. - angleB : unit.Quantity - The H0-G0-G1 angle. - """ - at1 = universe.atoms[self.host_atoms[1]] - at2 = universe.atoms[self.host_atoms[0]] - at3 = universe.atoms[self.guest_atoms[0]] - at4 = universe.atoms[self.guest_atoms[1]] - - angleA = calc_angles( - at1.position, - at2.position, - at3.position, - box=universe.atoms.dimensions - ) - angleB = calc_angles( - at2.position, - at3.position, - at4.position, - box=universe.atoms.dimensions - ) - return angleA, angleB - - def get_dihedrals( - self, - universe: mda.Universe, - ) -> tuple[unit.Quantity, unit.Quantity, unit.Quantity]: - """ - Get the H2-H1-H0-G0, H1-H0-G0-G1, and H0-G0-G1-G2 dihedrals. - - Parameters - ---------- - universe : mda.Universe - A Universe representing the system of interest. - - Returns - ------- - dihA : unit.Quantity - The H2-H1-H0-G0 angle. - dihB : unit.Quantity - The H1-H0-G0-G1 angle. - dihC : unit.Quantity - The H0-G0-G1-G2 angle. - """ - at1 = universe.atoms[self.host_atoms[2]] - at2 = universe.atoms[self.host_atoms[1]] - at3 = universe.atoms[self.host_atoms[0]] - at4 = universe.atoms[self.guest_atoms[0]] - at5 = universe.atoms[self.guest_atoms[1]] - at6 = universe.atoms[self.guest_atoms[2]] - - dihA = calc_dihedrals( - at1.position, at2.position, at3.position, at4.position, - box=universe.dimensions - ) - dihB = calc_dihedrals( - at2.position, at3.position, at4.position, at5.position, - box=universe.dimensions - ) - dihC = calc_dihedrals( - at3.position, at4.position, at5.position, at6.position, - box=universe.dimensions - ) - return dihA, dihB, dihC - def _sort_by_distance_from_atom( rdmol: Chem.Mol, target_idx: int, atom_idxs: Iterable[int] @@ -220,7 +113,7 @@ def _sort_by_distance_from_atom( return [i[1] for i in sorted(distances)] -def _get_bonded_angles_from_pool( +def _bonded_angles_from_pool( rdmol: Chem.Mol, atom_idx: int, atom_pool: list[int] ) -> list[tuple[int, int, int]]: """ @@ -300,7 +193,7 @@ def _get_atom_pool( return atom_pool -def get_guest_atom_candidates( +def find_guest_atom_candidates( topology: Union[str, pathlib.Path, openmm.app.Topology], trajectory: Union[str, pathlib.Path], rdmol: Chem.Mol, @@ -370,7 +263,7 @@ def get_guest_atom_candidates( # 4. Get a list of probable angles angles_list = [] for atom in sorted_atom_pool: - angles = _get_bonded_angles_from_pool(rdmol, atom, sorted_atom_pool) + angles = _bonded_angles_from_pool(rdmol, atom, sorted_atom_pool) for angle in angles: # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] @@ -386,7 +279,7 @@ def get_guest_atom_candidates( return angles_list -def get_host_atom_candidates( +def find_host_atom_candidates( topology: Union[str, pathlib.Path, openmm.app.Topology], trajectory: Union[str, pathlib.Path], host_idxs: list[int], @@ -459,7 +352,7 @@ def get_host_atom_candidates( class EvaluateHostAtoms1(AnalysisBase): """ Class to evaluate the suitability of a set of host atoms - as H1 atoms (i.e. the second host atom). + as either H0 or H1 atoms (i.e. the first and second host atoms). Parameters ---------- @@ -474,7 +367,6 @@ class EvaluateHostAtoms1(AnalysisBase): temperature : unit.Quantity The system temperature in Kelvin """ - def __init__( self, reference, @@ -582,6 +474,23 @@ def _conclude(self): class EvaluateHostAtoms2(EvaluateHostAtoms1): + """ + Class to evaluate the suitability of a set of host atoms + as H2 atoms (i.e. the third host atoms). + + Parameters + ---------- + reference : MDAnalysis.AtomGroup + The reference preceeding three atoms. + host_atom_pool : MDAnalysis.AtomGroup + The pool of atoms to pick an atom from. + minimum_distance : unit.Quantity + The minimum distance from the bound reference atom. + angle_force_constant : unit.Quantity + The force constant for the angle. + temperature : unit.Quantity + The system temperature in Kelvin + """ def _prepare(self): self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.ditances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) @@ -648,15 +557,36 @@ def _conclude(self): self.results.valid[i] = True -def _find_host_angle( - g0g1g2_atoms, - host_atom_pool, - minimum_distance, - angle_force_constant, - temperature -): +def _find_host_anchor( + guest_atoms: mda.AtomGroup, + host_atom_pool: mda.AtomGroup, + minimum_distance: unit.Quantity, + angle_force_constant: unit.Quantity, + temperature: unit.Quantity +) -> Optional[list[int]]: + """ + Find suitable atoms for the H0-H1-H2 portion of the restraint. + + Parameters + ---------- + guest_atoms : mda.AtomGroup + The guest anchor atoms for G0-G1-G2 + host_atom_pool : mda.AtomGroup + The host atoms to search from. + minimum_distance : unit.Quantity + The minimum distance to pick host atoms from each other. + angle_force_constant : unit.Quantity + The force constant for the G1-G0-H0 and G0-H0-H1 angles. + temperature : unit.Quantity + The target system temperature. + + Returns + ------- + Optional[list[int]] + A list of indices for a selected combination of H0, H1, and H2. + """ h0_eval = EvaluateHostAtoms1( - g0g1g2_atoms, + guest_atoms, host_atom_pool, minimum_distance, angle_force_constant, @@ -666,7 +596,7 @@ def _find_host_angle( for i, valid_h0 in enumerate(h0_eval.results.valid): if valid_h0: - g1g2h0_atoms = g0g1g2_atoms.atoms[1:] + host_atom_pool.atoms[i] + g1g2h0_atoms = guest_atoms.atoms[1:] + host_atom_pool.atoms[i] h1_eval = EvaluateHostAtoms1( g1g2h0_atoms, host_atom_pool, @@ -690,7 +620,7 @@ def _find_host_angle( dsum_avgs = d1_avgs + d2_avgs k = dsum_avgs.argmin() - return host_atom_pool.atoms[[i, j, k]].ix + return list(host_atom_pool.atoms[[i, j, k]].ix) return None @@ -839,24 +769,24 @@ def find_boresch_restraint( # In this case assume the picked atoms were intentional / # representative of the input and go with it guest_ag = u.select_atoms[guest_idxs] - guest_angle = [ + guest_anchor = [ at.ix for at in guest_ag.atoms[guest_restraint_atoms_idxs] ] host_ag = u.select_atoms[host_idxs] - host_angle = [ + host_anchor = [ at.ix for at in host_ag.atoms[host_restraint_atoms_idxs] ] # Set the equilibrium values as those of the final frame u.trajectory[-1] - atomgroup = u.atoms[host_angle + guest_angle] + atomgroup = u.atoms[host_anchor + guest_anchor] bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( atomgroup ) return BoreschRestraintGeometry( - host_atoms=host_angle, - guest_atoms=guest_angle, + host_atoms=host_anchor, + guest_atoms=guest_anchor, r_aA0=bond, theta_A0=ang1, theta_B0=ang2, @@ -875,8 +805,8 @@ def find_boresch_restraint( ) raise ValueError(errmsg) - # 1. Fetch the guest angles - guest_angles = get_guest_atom_candidates( + # 1. Fetch the guest anchors + guest_anchors = find_guest_atom_candidates( topology=topology, trajectory=trajectory, rdmol=guest_rdmol, @@ -884,53 +814,50 @@ def find_boresch_restraint( rmsf_cutoff=rmsf_cutoff, ) - if len(guest_angles) != 0: + if len(guest_anchors) != 0: errmsg = "No suitable ligand atoms found for the restraint." raise ValueError(errmsg) - # We pick the first angle / ligand atom set as the one to use - guest_angle = guest_angles[0] - - # 2. We next fetch the host atom pool - host_pool = get_host_atom_candidates( - topology=topology, - trajectory=trajectory, - host_idxs=host_idxs, - l1_idx=guest_angle[0], - host_selection=host_selection, - dssp_filter=dssp_filter, - rmsf_cutoff=rmsf_cutoff, - min_distance=host_min_distance, - max_distance=host_max_distance, - ) + # 2. We then loop through the guest anchors to find suitable host atoms + for guest_anchor in guest_anchors: + # We next fetch the host atom pool + host_pool = find_host_atom_candidates( + topology=topology, + trajectory=trajectory, + host_idxs=host_idxs, + l1_idx=guest_anchor, + host_selection=host_selection, + dssp_filter=dssp_filter, + rmsf_cutoff=rmsf_cutoff, + min_distance=host_min_distance, + max_distance=host_max_distance, + ) - # 3. We then loop through the guest angles to find suitable host atoms - for guest_angle in guest_angles: - host_angle = _find_host_angle( - g0g1g2_atoms=u.atoms[list(guest_angle)], + host_anchor = _find_host_anchor( + guest_atoms=u.atoms[list(guest_anchor)], host_atom_pool=u.atoms[host_pool], minimum_distance=0.5 * unit.nanometer, angle_force_constant=angle_force_constant, temperature=temperature, ) # continue if it's empty, otherwise stop - if host_angle is not None: + if host_anchor is not None: break - if host_angle is None: + if host_anchor is None: errmsg = "No suitable host atoms could be found" raise ValueError(errmsg) # Set the equilibrium values as those of the final frame u.trajectory[-1] - atomgroup = u.atoms[host_angle + guest_angle] + atomgroup = u.atoms[host_anchor + guest_anchor] bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( atomgroup ) return BoreschRestraintGeometry( - host_atoms=host_angle, - guest_atoms=guest_angle, + host_atoms=host_anchor, + guest_atoms=guest_anchor, r_aA0=bond, theta_A0=ang1, theta_B0=ang2, diff --git a/openfe/protocols/restraint_utils/geometry/harmonic.py b/openfe/protocols/restraint_utils/geometry/harmonic.py index 197a8bc44..81e2f22b2 100644 --- a/openfe/protocols/restraint_utils/geometry/harmonic.py +++ b/openfe/protocols/restraint_utils/geometry/harmonic.py @@ -10,9 +10,7 @@ import pathlib from typing import Union, Optional from openmm import app -from openff.units import unit import MDAnalysis as mda -from MDAnalysis.lib.distances import calc_bonds from rdkit import Chem from .base import HostGuestRestraintGeometry @@ -28,30 +26,6 @@ class DistanceRestraintGeometry(HostGuestRestraintGeometry): A geometry class for a distance restraint between two groups of atoms. """ - def get_distance(self, universe: mda.Universe) -> unit.Quantity: - """ - Get the center of mass distance between the host and guest atoms. - - Parameters - ---------- - universe : mda.Universe - A Universe representing the system of interest. - - Returns - ------- - bond : unit.Quantity - The center of mass distance between the two groups of atoms. - """ - ag1 = universe.atoms[self.host_atoms] - ag2 = universe.atoms[self.guest_atoms] - bond = calc_bonds( - ag1.center_of_mass(), - ag2.center_of_mass(), - box=universe.atoms.dimensions - ) - # convert to float so we avoid having a np.float64 - return float(bond) * unit.angstrom - def get_distance_restraint( topology: Union[str, pathlib.Path, app.Topology], From 6c628dda81e77429674a5e84dd57709202ce3510 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 16 Dec 2024 13:57:40 +0100 Subject: [PATCH 100/163] Subclass Parameterstate --- openfe/protocols/openmm_septop/base.py | 15 +- openfe/protocols/openmm_septop/utils.py | 408 +++++------------------- 2 files changed, 92 insertions(+), 331 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index ffdff1ac8..88b24dba3 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -72,11 +72,10 @@ from openfe.utils import without_oechem_backend from .femto_restraints import select_ligand_idxs -from .utils import serialize, deserialize -from openfe.protocols.openmm_septop.alchemy_copy import ( +from .utils import serialize, deserialize, SepTopParameterState +from openmmtools.alchemy import ( AbsoluteAlchemicalFactory, AlchemicalRegion, - AlchemicalState, ) logger = logging.getLogger(__name__) @@ -986,7 +985,15 @@ def _get_states( cmp_states : list[ThermodynamicState] A list of ThermodynamicState for each replica in the system. """ - alchemical_state = AlchemicalState.from_system(alchemical_system) + # alchemical_state = AlchemicalState.from_system(alchemical_system) + alchemical_state = SepTopParameterState( + lambda_sterics_A=1.0, + lambda_electrostatics_A=1.0, + lambda_restraints_A=1.0, + lambda_sterics_B=1.0, + lambda_electrostatics_B=1.0, + lambda_restraints_B=1.0, + ) # Set up the system constants temperature = settings['thermo_settings'].temperature pressure = settings['thermo_settings'].pressure diff --git a/openfe/protocols/openmm_septop/utils.py b/openfe/protocols/openmm_septop/utils.py index fa8a9ac14..7fb9a139f 100644 --- a/openfe/protocols/openmm_septop/utils.py +++ b/openfe/protocols/openmm_septop/utils.py @@ -5,6 +5,7 @@ AlchemicalStateError, AlchemicalRegion, AlchemicalFunction, AbsoluteAlchemicalFactory, ) +from openmmtools.states import GlobalParameterState def serialize(item, filename: pathlib.Path): """ @@ -80,330 +81,83 @@ def deserialize(filename: pathlib.Path): return item -# class AlchemicalState(states.GlobalParameterState): -# """Represent an alchemical state. -# -# The alchemical parameters modify the Hamiltonian and affect the -# computation of the energy. Alchemical parameters that have value -# None are considered undefined, which means that applying this -# state to System and Context that have that parameter as a global -# variable will raise an AlchemicalStateError. -# -# Parameters -# ---------- -# parameters_name_suffix : str, optional -# If specified, the state will control a modified version of the global -# parameters with the name ``parameter_name + '_' + parameters_name_suffix``. -# When this is the case, the normal parameters are not accessible. -# lambda_sterics : float, optional -# Scaling factor for ligand sterics (Lennard-Jones and Halgren) -# interactions (default is 1.0). -# lambda_electrostatics : float, optional -# Scaling factor for ligand charges, intrinsic Born radii, and surface -# area term (default is 1.0). -# lambda_bonds : float, optional -# Scaling factor for alchemically-softened bonds (default is 1.0). -# lambda_angles : float, optional -# Scaling factor for alchemically-softened angles (default is 1.0). -# lambda_torsions : float, optional -# Scaling factor for alchemically-softened torsions (default is 1.0). -# -# Attributes -# ---------- -# lambda_sterics -# lambda_electrostatics -# lambda_bonds -# lambda_angles -# lambda_torsions -# -# Examples -# -------- -# Create an alchemically modified system. -# -# >>> from openmmtools import testsystems -# >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) -# >>> alanine_vacuum = testsystems.AlanineDipeptideVacuum().system -# >>> alchemical_region = AlchemicalRegion(alchemical_atoms=range(22)) -# >>> alanine_alchemical_system = factory.create_alchemical_system(reference_system=alanine_vacuum, -# ... alchemical_regions=alchemical_region) -# -# Create a completely undefined alchemical state. -# -# >>> alchemical_state = AlchemicalState() -# >>> print(alchemical_state.lambda_sterics) -# None -# >>> alchemical_state.apply_to_system(alanine_alchemical_system) -# Traceback (most recent call last): -# ... -# openmmtools.alchemy.AlchemicalStateError: The system parameter lambda_electrostatics is not defined in this state. -# -# Create an AlchemicalState that matches the parameters defined in -# the System. -# -# >>> alchemical_state = AlchemicalState.from_system(alanine_alchemical_system) -# >>> alchemical_state.lambda_sterics -# 1.0 -# >>> alchemical_state.lambda_electrostatics -# 1.0 -# >>> print(alchemical_state.lambda_angles) -# None -# -# AlchemicalState implement the IComposableState interface, so it can be -# used with CompoundThermodynamicState. All the alchemical parameters are -# accessible through the compound state. -# -# >>> import openmm -# >>> from openmm import unit -# >>> thermodynamic_state = states.ThermodynamicState(system=alanine_alchemical_system, -# ... temperature=300*unit.kelvin) -# >>> compound_state = states.CompoundThermodynamicState(thermodynamic_state=thermodynamic_state, -# ... composable_states=[alchemical_state]) -# >>> compound_state.lambda_sterics -# 1.0 -# -# You can control the parameters in the OpenMM Context in this state by -# setting the state attributes. -# -# >>> compound_state.lambda_sterics = 0.5 -# >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) -# >>> context = compound_state.create_context(integrator) -# >>> context.getParameter('lambda_sterics') -# 0.5 -# >>> compound_state.lambda_sterics = 1.0 -# >>> compound_state.apply_to_context(context) -# >>> context.getParameter('lambda_sterics') -# 1.0 -# -# You can express the alchemical parameters as a mathematical expression -# involving alchemical variables. Here is an example for a two-stage function. -# -# >>> compound_state.set_alchemical_variable('lambda', 1.0) -# >>> compound_state.lambda_sterics = AlchemicalFunction('step_hm(lambda - 0.5) + 2*lambda * step_hm(0.5 - lambda)') -# >>> compound_state.lambda_electrostatics = AlchemicalFunction('2*(lambda - 0.5) * step(lambda - 0.5)') -# >>> for l in [0.0, 0.25, 0.5, 0.75, 1.0]: -# ... compound_state.set_alchemical_variable('lambda', l) -# ... print(compound_state.lambda_sterics) -# 0.0 -# 0.5 -# 1.0 -# 1.0 -# 1.0 -# -# """ -# -# _GLOBAL_PARAMETER_ERROR = AlchemicalStateError -# -# # ------------------------------------------------------------------------- -# # Lambda properties -# # ------------------------------------------------------------------------- -# -# class _LambdaParameter(states.GlobalParameterState.GlobalParameter): -# """A global parameter in the interval [0, 1] with standard value 1.""" -# -# def __init__(self, parameter_name): -# super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) -# -# @staticmethod -# def lambda_validator(self, instance, parameter_value): -# if parameter_value is None: -# return parameter_value -# if not (0.0 <= parameter_value <= 1.0): -# raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) -# return float(parameter_value) -# -# lambda_sterics_ligandA = _LambdaParameter('lambda_sterics_ligandA') -# lambda_electrostatics_ligandB = _LambdaParameter( -# 'lambda_electrostatics_ligandB') -# lambda_sterics_ligandB = _LambdaParameter('lambda_sterics_ligandB') -# lambda_electrostatics_ligandA = _LambdaParameter( -# 'lambda_electrostatics_ligandA') -# lambda_restraints_ligandA = _LambdaParameter('lambda_restraints_ligandA') -# lambda_restraints_ligandB = _LambdaParameter('lambda_restraints_ligandB') -# lambda_bonds = _LambdaParameter('lambda_bonds') -# lambda_angles = _LambdaParameter('lambda_angles') -# lambda_torsions = _LambdaParameter('lambda_torsions') -# -# @classmethod -# def from_system(cls, system, *args, **kwargs): -# """Constructor reading the state from an alchemical system. -# -# Parameters -# ---------- -# system : openmm.System -# An alchemically modified system in a defined alchemical state. -# parameters_name_suffix : str, optional -# If specified, the state will search for a modified -# version of the alchemical parameters with the name -# ``parameter_name + '_' + parameters_name_suffix``. -# -# Returns -# ------- -# The AlchemicalState object representing the alchemical state of -# the system. -# -# Raises -# ------ -# AlchemicalStateError -# If the same parameter has different values in the system, or -# if the system has no lambda parameters. -# -# """ -# # The function is redefined here only to provide more specific documentation for this method. -# return super().from_system(system, *args, **kwargs) -# -# def set_alchemical_parameters(self, new_value): -# """Set all defined lambda parameters to the given value. -# -# The undefined parameters (i.e. those being set to None) remain -# undefined. -# -# Parameters -# ---------- -# new_value : float -# The new value for all defined parameters. -# -# """ -# for parameter_name in self._parameters: -# if self._parameters[parameter_name] is not None: -# setattr(self, parameter_name, new_value) -# -# # ------------------------------------------------------------------------- -# # Function variables -# # ------------------------------------------------------------------------- -# -# def get_function_variable(self, variable_name): -# """Return the value of the function variable. -# -# Function variables are variables entering mathematical expressions -# specified with ``AlchemicalFunction``, which can be use to enslave -# a lambda parameter to arbitrary variables. -# -# Parameters -# ---------- -# variable_name : str -# The name of the function variable. -# -# Returns -# ------- -# variable_value : float -# The value of the function variable. -# -# """ -# # The function is redefined here only to provide more specific documentation for this method. -# return super().get_function_variable(variable_name) -# -# def set_function_variable(self, variable_name, new_value): -# """Set the value of the function variable. -# -# Function variables are variables entering mathematical expressions -# specified with ``AlchemicalFunction``, which can be use to enslave -# a lambda parameter to arbitrary variables. -# -# Parameters -# ---------- -# variable_name : str -# The name of the function variable. -# new_value : float -# The new value for the variable. -# -# """ -# # The function is redefined here only to provide more specific documentation for this method. -# super().set_function_variable(variable_name, new_value) -# -# def get_alchemical_variable(self, variable_name): -# """Return the value of the alchemical parameter. -# -# .. warning: -# This is deprecated. Use ``get_function_variable`` instead. -# -# Parameters -# ---------- -# variable_name : str -# The name of the alchemical variable. -# -# Returns -# ------- -# variable_value : float -# The value of the alchemical variable. -# """ -# import warnings -# warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' -# 'Use AlchemicalState.get_function_variable instead.') -# return super().get_function_variable(variable_name) -# -# def set_alchemical_variable(self, variable_name, new_value): -# """Set the value of the alchemical variable. -# -# .. warning: -# This is deprecated. Use ``set_function_variable`` instead. -# -# Parameters -# ---------- -# variable_name : str -# The name of the alchemical variable. -# new_value : float -# The new value for the variable. -# -# """ -# import warnings -# warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' -# 'Use AlchemicalState.get_function_variable instead.') -# super().set_function_variable(variable_name, new_value) -# -# # ------------------------------------------------------------------------- -# # IComposableState interface -# # ------------------------------------------------------------------------- -# -# def apply_to_system(self, system): -# """Set the alchemical state of the system to this. -# -# Parameters -# ---------- -# system : openmm.System -# The system to modify. -# -# Raises -# ------ -# AlchemicalStateError -# If the system does not have the required lambda global variables. -# -# """ -# # The function is redefined here only to provide more specific documentation for this method. -# super().apply_to_system(system) -# -# def check_system_consistency(self, system): -# """Check if the system is in this alchemical state. -# -# It raises a AlchemicalStateError if the system is not consistent -# with the alchemical state. -# -# Parameters -# ---------- -# system : openmm.System -# The system to test. -# -# Raises -# ------ -# AlchemicalStateError -# If the system is not consistent with this state. -# -# """ -# # The function is redefined here only to provide more specific documentation for this method. -# super().check_system_consistency(system) -# -# def apply_to_context(self, context): -# """Put the Context into this AlchemicalState. -# -# Parameters -# ---------- -# context : openmm.Context -# The context to set. -# -# Raises -# ------ -# AlchemicalStateError -# If the context does not have the required lambda global variables. -# -# """ -# # The function is redefined here only to provide more specific documentation for this method. -# super().apply_to_context(context) +class SepTopParameterState(GlobalParameterState): + """ + Composable state to control lambda parameters for two ligands. + See :class:`openmmtools.states.GlobalParameterState` for more details. + Parameters + ---------- + parameters_name_suffix : Optional[str] + If specified, the state will control a modified version of the parameter + ``lambda_restraints_{parameters_name_suffix}` instead of just + ``lambda_restraints``. + lambda_sterics_A : Optional[float] + The value for the vdW interactions for ligand A. + If defined, must be between 0 and 1. + lambda_electrosterics_A : Optional[float] + The value for the electrostatics interactions for ligand A. + If defined, must be between 0 and 1. + lambda_restraints_A : Optional[float] + The strength of the restraint for ligand A. + If defined, must be between 0 and 1. + lambda_bonds_A : Optional[float] + The value for modifying bonds for ligand A. + If defined, must be between 0 and 1. + lambda_angles_A : Optional[float] + The value for modifying angles for ligand A. + If defined, must be between 0 and 1. + lambda_dihedrals_A : Optional[float] + The value for modifying dihedrals for ligand A. + If defined, must be between 0 and 1. + lambda_sterics_B : Optional[float] + The value for the vdW interactions for ligand B. + If defined, must be between 0 and 1. + lambda_electrosterics_B : Optional[float] + The value for the electrostatics interactions for ligand B. + If defined, must be between 0 and 1. + lambda_restraints_B : Optional[float] + The strength of the restraint for ligand B. + If defined, must be between 0 and 1. + lambda_bonds_B : Optional[float] + The value for modifying bonds for ligand B. + If defined, must be between 0 and 1. + lambda_angles_B : Optional[float] + The value for modifying angles for ligand B. + If defined, must be between 0 and 1. + lambda_dihedrals_B : Optional[float] + The value for modifying dihedrals for ligand B. + If defined, must be between 0 and 1. + """ + + class _LambdaParameter(states.GlobalParameterState.GlobalParameter): + """A global parameter in the interval [0, 1] with standard + value 1.""" + + def __init__(self, parameter_name): + super().__init__(parameter_name, standard_value=1.0, + validator=self.lambda_validator) + + @staticmethod + def lambda_validator(self, instance, parameter_value): + if parameter_value is None: + return parameter_value + if not (0.0 <= parameter_value <= 1.0): + raise ValueError('{} must be between 0 and 1.'.format( + self.parameter_name)) + return float(parameter_value) + + # Lambda parameters for ligand A + lambda_sterics_A = _LambdaParameter('lambda_sterics_A') + lambda_electrostatics_A = _LambdaParameter('lambda_electrostatics_A') + lambda_restraints_A = _LambdaParameter('lambda_restraints_A') + lambda_bonds_A = _LambdaParameter('lambda_bonds_A') + lambda_angles_A = _LambdaParameter('lambda_angles_A') + lambda_torsions_A = _LambdaParameter('lambda_torsions_A') + + # Lambda parameters for ligand B + lambda_sterics_B = _LambdaParameter('lambda_sterics_B') + lambda_electrostatics_B = _LambdaParameter('lambda_electrostatics_B') + lambda_restraints_B = _LambdaParameter('lambda_restraints_B') + lambda_bonds_B = _LambdaParameter('lambda_bonds_B') + lambda_angles_B = _LambdaParameter('lambda_angles_B') + lambda_torsions_B = _LambdaParameter('lambda_torsions_B') From 92690d8b91d81c6dfadc8562ddaebf7e260a26a6 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 16 Dec 2024 14:14:41 +0100 Subject: [PATCH 101/163] Change AlchemicalRegion name --- openfe/protocols/openmm_septop/base.py | 4 ++-- openfe/protocols/openmm_septop/equil_septop_method.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 88b24dba3..0f3282274 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -830,9 +830,9 @@ def run(self, dry=False, verbose=True, factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alchemical_region_A = AlchemicalRegion( - alchemical_atoms=atom_indices_AB_A, name='ligandA') + alchemical_atoms=atom_indices_AB_A, name='A') alchemical_region_B = AlchemicalRegion( - alchemical_atoms=atom_indices_AB_B, name='ligandB') + alchemical_atoms=atom_indices_AB_B, name='B') alchemical_system = factory.create_alchemical_system( omm_system_AB, [alchemical_region_A, alchemical_region_B]) omm_system_AB = alchemical_system diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 506206c7f..ef1258f75 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -923,7 +923,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * equil_output_settings : MDOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings - * restraint_settings: RestraintsSettings + * restraint_settings: ComplexRestraintsSettings """ prot_settings = self._inputs['protocol'].settings @@ -1166,7 +1166,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings - * restraint_settings: RestraintsSettings + * restraint_settings: SolventRestraintsSettings """ prot_settings = self._inputs['protocol'].settings @@ -1379,7 +1379,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * equil_output_settings : MDOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings - * restraint_settings: RestraintsSettings + * restraint_settings: SolventRestraintsSettings """ prot_settings = self._inputs['protocol'].settings @@ -1483,7 +1483,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * equil_output_settings : MDOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings - * restraint_settings: RestraintsSettings + * restraint_settings: ComplexRestraintsSettings """ prot_settings = self._inputs['protocol'].settings From 2d1eba4f026f67c43bbc5f03271e5de47c79d655 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 16 Dec 2024 14:25:22 +0100 Subject: [PATCH 102/163] Update restraint lambda parameter --- openfe/protocols/openmm_septop/equil_septop_method.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index ef1258f75..0a749e496 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1067,7 +1067,7 @@ def _add_restraints( positions, k_distance, k_theta, - "lambda_restraints_ligandA", + "lambda_restraints_A", ) system.addForce(force_A) force_B = create_boresch_restraint( @@ -1077,7 +1077,7 @@ def _add_restraints( positions, k_distance, k_theta, - "lambda_restraints_ligandB", + "lambda_restraints_B", ) system.addForce(force_B) From 3849778b328d2625794c109fff09e5a017bef22e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 16 Dec 2024 14:52:35 +0100 Subject: [PATCH 103/163] Update settings --- .../openmm_septop/equil_septop_method.py | 87 +++++++++---------- .../openmm_septop/equil_septop_settings.py | 24 ++--- openfe/tests/protocols/test_openmm_septop.py | 42 ++++----- .../protocols/test_openmm_septop_slow.py | 44 +++++----- 4 files changed, 98 insertions(+), 99 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 0a749e496..3e6ea85c4 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -685,52 +685,52 @@ def _validate_lambda_schedule( If there are non-zero values for restraints (lambda_restraints). """ - lambda_elec_ligandA = lambda_settings.lambda_elec_ligandA - lambda_elec_ligandB = lambda_settings.lambda_elec_ligandB - lambda_vdw_ligandA = lambda_settings.lambda_vdw_ligandA - lambda_vdw_ligandB = lambda_settings.lambda_vdw_ligandB - lambda_restraints_ligandA = lambda_settings.lambda_restraints_ligandA - lambda_restraints_ligandB = lambda_settings.lambda_restraints_ligandB + lambda_elec_A = lambda_settings.lambda_elec_A + lambda_elec_B = lambda_settings.lambda_elec_B + lambda_vdw_A = lambda_settings.lambda_vdw_A + lambda_vdw_B = lambda_settings.lambda_vdw_B + lambda_restraints_A = lambda_settings.lambda_restraints_A + lambda_restraints_B = lambda_settings.lambda_restraints_B n_replicas = simulation_settings.n_replicas # Ensure that all lambda components have equal amount of windows - lambda_components = [lambda_vdw_ligandA, lambda_vdw_ligandB, - lambda_elec_ligandA, lambda_elec_ligandB, - lambda_restraints_ligandA, lambda_restraints_ligandB] + lambda_components = [lambda_vdw_A, lambda_vdw_B, + lambda_elec_A, lambda_elec_B, + lambda_restraints_A, lambda_restraints_B] it = iter(lambda_components) the_len = len(next(it)) if not all(len(l) == the_len for l in it): errmsg = ( "Components elec, vdw, and restraints must have equal amount" - f" of lambda windows. Got {len(lambda_elec_ligandA)} and " - f"{len(lambda_elec_ligandB)} elec lambda windows, " - f"{len(lambda_vdw_ligandA)} and {len(lambda_vdw_ligandB)} vdw " - f"lambda windows, and {len(lambda_restraints_ligandA)} and " - f"{len(lambda_restraints_ligandB)} restraints lambda windows.") + f" of lambda windows. Got {len(lambda_elec_A)} and " + f"{len(lambda_elec_B)} elec lambda windows, " + f"{len(lambda_vdw_A)} and {len(lambda_vdw_B)} vdw " + f"lambda windows, and {len(lambda_restraints_A)} and " + f"{len(lambda_restraints_B)} restraints lambda windows.") raise ValueError(errmsg) # Ensure that number of overall lambda windows matches number of lambda # windows for individual components - if n_replicas != len(lambda_vdw_ligandB): + if n_replicas != len(lambda_vdw_B): errmsg = (f"Number of replicas {n_replicas} does not equal the" - f" number of lambda windows {len(lambda_vdw_ligandB)}") + f" number of lambda windows {len(lambda_vdw_B)}") raise ValueError(errmsg) # Check if there are lambda windows with naked charges - for inx, lam in enumerate(lambda_elec_ligandA): - if lam < 1 and lambda_vdw_ligandA[inx] == 1: + for inx, lam in enumerate(lambda_elec_A): + if lam < 1 and lambda_vdw_A[inx] == 1: errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ " f"interactions: Ligand A: lambda {inx}: " - f"elec {lam} vdW {lambda_vdw_ligandA[inx]}") + f"elec {lam} vdW {lambda_vdw_A[inx]}") raise ValueError(errmsg) - if lambda_elec_ligandB[inx] < 1 and lambda_vdw_ligandB[inx] == 1: + if lambda_elec_B[inx] < 1 and lambda_vdw_B[inx] == 1: errmsg = ( "There are states along this lambda schedule " "where there are atoms with charges but no LJ interactions" - f": Ligand B: lambda {inx}: elec {lambda_elec_ligandB[inx]}" - f" vdW {lambda_vdw_ligandB[inx]}") + f": Ligand B: lambda {inx}: elec {lambda_elec_B[inx]}" + f" vdW {lambda_vdw_B[inx]}") raise ValueError(errmsg) def _create( @@ -1413,10 +1413,10 @@ def _get_lambda_schedule( lambdas = dict() - lambda_elec_A = settings['lambda_settings'].lambda_elec_ligandA - lambda_vdw_A = settings['lambda_settings'].lambda_vdw_ligandA - lambda_elec_B = settings['lambda_settings'].lambda_elec_ligandB - lambda_vdw_B = settings['lambda_settings'].lambda_vdw_ligandB + lambda_elec_A = settings['lambda_settings'].lambda_elec_A + lambda_vdw_A = settings['lambda_settings'].lambda_vdw_A + lambda_elec_B = settings['lambda_settings'].lambda_elec_B + lambda_vdw_B = settings['lambda_settings'].lambda_vdw_B # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 # means fully interacting, not stateB @@ -1424,10 +1424,10 @@ def _get_lambda_schedule( lambda_vdw_A = [1 - x for x in lambda_vdw_A] lambda_elec_B = [1 - x for x in lambda_elec_B] lambda_vdw_B = [1 - x for x in lambda_vdw_B] - lambdas['lambda_electrostatics_ligandA'] = lambda_elec_A - lambdas['lambda_sterics_ligandA'] = lambda_vdw_A - lambdas['lambda_electrostatics_ligandB'] = lambda_elec_B - lambdas['lambda_sterics_ligandB'] = lambda_vdw_B + lambdas['lambda_electrostatics_A'] = lambda_elec_A + lambdas['lambda_sterics_A'] = lambda_vdw_A + lambdas['lambda_electrostatics_B'] = lambda_elec_B + lambdas['lambda_sterics_B'] = lambda_vdw_B return lambdas @@ -1516,14 +1516,14 @@ def _get_lambda_schedule( ) -> dict[str, npt.NDArray]: lambdas = dict() - lambda_elec_A = settings['lambda_settings'].lambda_elec_ligandA - lambda_vdw_A = settings['lambda_settings'].lambda_vdw_ligandA - lambda_elec_B = settings['lambda_settings'].lambda_elec_ligandB - lambda_vdw_B = settings['lambda_settings'].lambda_vdw_ligandB + lambda_elec_A = settings['lambda_settings'].lambda_elec_A + lambda_vdw_A = settings['lambda_settings'].lambda_vdw_A + lambda_elec_B = settings['lambda_settings'].lambda_elec_B + lambda_vdw_B = settings['lambda_settings'].lambda_vdw_B lambda_restraints_A = settings[ - 'lambda_settings'].lambda_restraints_ligandA + 'lambda_settings'].lambda_restraints_A lambda_restraints_B = settings[ - 'lambda_settings'].lambda_restraints_ligandB + 'lambda_settings'].lambda_restraints_B # Reverse lambda schedule since in AbsoluteAlchemicalFactory 1 # means fully interacting, not stateB @@ -1531,13 +1531,12 @@ def _get_lambda_schedule( lambda_vdw_A = [1 - x for x in lambda_vdw_A] lambda_elec_B = [1 - x for x in lambda_elec_B] lambda_vdw_B = [1 - x for x in lambda_vdw_B] - # lambda_restraints_A = [1 - x for x in lambda_restraints_A] - # lambda_restraints_B = [1 - x for x in lambda_restraints_B] - lambdas['lambda_electrostatics_ligandA'] = lambda_elec_A - lambdas['lambda_sterics_ligandA'] = lambda_vdw_A - lambdas['lambda_electrostatics_ligandB'] = lambda_elec_B - lambdas['lambda_sterics_ligandB'] = lambda_vdw_B - lambdas['lambda_restraints_ligandA'] = lambda_restraints_A - lambdas['lambda_restraints_ligandB'] = lambda_restraints_B + + lambdas['lambda_electrostatics_A'] = lambda_elec_A + lambdas['lambda_sterics_A'] = lambda_vdw_A + lambdas['lambda_electrostatics_B'] = lambda_elec_B + lambdas['lambda_sterics_B'] = lambda_vdw_B + lambdas['lambda_restraints_A'] = lambda_restraints_A + lambdas['lambda_restraints_B'] = lambda_restraints_B return lambdas diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index 7de637ab3..cce48f29f 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -76,20 +76,20 @@ class LambdaSettings(SettingsBaseModel): the same length, defining all the windows of the transformation. """ - lambda_elec_ligandA: list[float] = [0.0] * 8 + [0.25, 0.5, 0.75] + [1.0] * 8 + lambda_elec_A: list[float] = [0.0] * 8 + [0.25, 0.5, 0.75] + [1.0] * 8 """ List of floats of the lambda values for the electrostatics of ligand A. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_restraints. """ - lambda_elec_ligandB: list[float] = [1.0] * 8 + [0.75, 0.5, 0.25] + [0.0] * 8 + lambda_elec_B: list[float] = [1.0] * 8 + [0.75, 0.5, 0.25] + [0.0] * 8 """ List of floats of the lambda values for the electrostatics of ligand B. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_restraints. """ - lambda_vdw_ligandA: list[float] = [0.0] * 8 + [ + lambda_vdw_A: list[float] = [0.0] * 8 + [ 0.00, 0.0, 0.00] + np.linspace(0.0, 1.0, 8).tolist() """ List of floats of lambda values for the van der Waals of ligand A. @@ -97,14 +97,14 @@ class LambdaSettings(SettingsBaseModel): Length of this list needs to match length of lambda_elec and lambda_restraints. """ - lambda_vdw_ligandB: list[float] = np.linspace(1.0, 0.0, 8).tolist() + [ + lambda_vdw_B: list[float] = np.linspace(1.0, 0.0, 8).tolist() + [ 0.0, 0.0, 0.0] + [0.0] * 8 """ List of floats of lambda values for the van der Waals of ligand B. Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_elec and lambda_restraints. """ - lambda_restraints_ligandA: list[float] = [ + lambda_restraints_A: list[float] = [ 0.0, 0.05, 0.1, 0.3, 0.5, 0.75, 1.0, 1.0] + [ 1.0] * 3 + [1.0] * 8 @@ -113,7 +113,7 @@ class LambdaSettings(SettingsBaseModel): Zero means fully interacting and 1 means fully decoupled. Length of this list needs to match length of lambda_vdw and lambda_elec. """ - lambda_restraints_ligandB: list[float] = [1.0] * 8 + [1.0] * 3 + [ + lambda_restraints_B: list[float] = [1.0] * 8 + [1.0] * 3 + [ 1.0, 0.95, 0.9, 0.7, 0.5, 0.25, 0.0, 0.0] """ List of floats of lambda values for the restraints of ligand B. @@ -122,9 +122,9 @@ class LambdaSettings(SettingsBaseModel): """ - @validator('lambda_elec_ligandA', 'lambda_elec_ligandB', - 'lambda_vdw_ligandA', 'lambda_vdw_ligandB', - 'lambda_restraints_ligandA', 'lambda_restraints_ligandB') + @validator('lambda_elec_A', 'lambda_elec_B', + 'lambda_vdw_A', 'lambda_vdw_B', + 'lambda_restraints_A', 'lambda_restraints_B') def must_be_between_0_and_1(cls, v): for window in v: if not 0 <= window <= 1: @@ -133,9 +133,9 @@ def must_be_between_0_and_1(cls, v): raise ValueError(errmsg) return v - @validator('lambda_elec_ligandA', 'lambda_elec_ligandB', - 'lambda_vdw_ligandA', 'lambda_vdw_ligandB', - 'lambda_restraints_ligandA', 'lambda_restraints_ligandB') + @validator('lambda_elec_A', 'lambda_elec_B', + 'lambda_vdw_A', 'lambda_vdw_B', + 'lambda_restraints_A', 'lambda_restraints_B') def must_be_monotonic(cls, v): difference = np.diff(v) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 07870738d..16c55bb47 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -58,9 +58,9 @@ def test_incorrect_window_settings(val, default_settings): errmsg = "Lambda windows must be between 0 and 1." lambda_settings = default_settings.lambda_settings with pytest.raises(ValueError, match=errmsg): - lambda_settings.lambda_elec_ligandA = val['elec'] - lambda_settings.lambda_vdw_ligandA = val['vdw'] - lambda_settings.lambda_restraints_ligandA = val['restraints'] + lambda_settings.lambda_elec_A = val['elec'] + lambda_settings.lambda_vdw_A = val['vdw'] + lambda_settings.lambda_restraints_A = val['restraints'] @pytest.mark.parametrize('val', [ @@ -71,21 +71,21 @@ def test_monotonic_lambda_windows(val, default_settings): lambda_settings = default_settings.lambda_settings with pytest.raises(ValueError, match=errmsg): - lambda_settings.lambda_elec_ligandA = val['elec'] - lambda_settings.lambda_vdw_ligandA = val['vdw'] - lambda_settings.lambda_restraints_ligandA = val['restraints'] + lambda_settings.lambda_elec_A = val['elec'] + lambda_settings.lambda_vdw_A = val['vdw'] + lambda_settings.lambda_restraints_A = val['restraints'] @pytest.mark.parametrize('val', [ {'elec': [1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, ]) def test_validate_lambda_schedule_nreplicas(val, default_settings): - default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] - default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandB = val[ + default_settings.lambda_settings.lambda_elec_A = val['elec'] + default_settings.lambda_settings.lambda_vdw_A = val['vdw'] + default_settings.lambda_settings.lambda_restraints_A = val['restraints'] + default_settings.lambda_settings.lambda_elec_B = val['elec'] + default_settings.lambda_settings.lambda_vdw_B = val['vdw'] + default_settings.lambda_settings.lambda_restraints_B = val[ 'restraints'] n_replicas = 3 default_settings.complex_simulation_settings.n_replicas = n_replicas @@ -102,9 +102,9 @@ def test_validate_lambda_schedule_nreplicas(val, default_settings): {'elec': [1.0, 1.0, 1.0], 'vdw': [0.0, 1.0], 'restraints': [0.0, 0.0]}, ]) def test_validate_lambda_schedule_nwindows(val, default_settings): - default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandA = val['restraints'] + default_settings.lambda_settings.lambda_elec_A = val['elec'] + default_settings.lambda_settings.lambda_vdw_A = val['vdw'] + default_settings.lambda_settings.lambda_restraints_A = val['restraints'] n_replicas = 3 default_settings.complex_simulation_settings.n_replicas = n_replicas errmsg = ( @@ -121,13 +121,13 @@ def test_validate_lambda_schedule_nwindows(val, default_settings): {'elec': [1.0, 0.5], 'vdw': [1.0, 1.0], 'restraints': [0.0, 0.0]}, ]) def test_validate_lambda_schedule_nakedcharge(val, default_settings): - default_settings.lambda_settings.lambda_elec_ligandA = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandA = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandA = val[ + default_settings.lambda_settings.lambda_elec_A = val['elec'] + default_settings.lambda_settings.lambda_vdw_A = val['vdw'] + default_settings.lambda_settings.lambda_restraints_A = val[ 'restraints'] - default_settings.lambda_settings.lambda_elec_ligandB = val['elec'] - default_settings.lambda_settings.lambda_vdw_ligandB = val['vdw'] - default_settings.lambda_settings.lambda_restraints_ligandB = val[ + default_settings.lambda_settings.lambda_elec_B = val['elec'] + default_settings.lambda_settings.lambda_vdw_B = val['vdw'] + default_settings.lambda_settings.lambda_restraints_B = val[ 'restraints'] n_replicas = 2 default_settings.complex_simulation_settings.n_replicas = n_replicas diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 2628ed110..9c810f3b8 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -54,52 +54,52 @@ def compare_energies(alchemical_system, positions): energy = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) - na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandA' - na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region ligandB' + na_A = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region A' + na_B = 'alchemically modified NonbondedForce for non-alchemical/alchemical sterics for region B' nonbonded = 'unmodified NonbondedForce' # Lambda 0: LigandA sterics on, elec on, ligand B sterics off, elec off - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 0 - alchemical_state.lambda_electrostatics_ligandA = 1 - alchemical_state.lambda_electrostatics_ligandB = 0 + alchemical_state.lambda_sterics_A = 1 + alchemical_state.lambda_sterics_B = 0 + alchemical_state.lambda_electrostatics_A = 1 + alchemical_state.lambda_electrostatics_B = 0 energy_0 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 7: LigandA sterics on, elec on, ligand B sterics on, elec off - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 1 - alchemical_state.lambda_electrostatics_ligandB = 0 + alchemical_state.lambda_sterics_A = 1 + alchemical_state.lambda_sterics_B = 1 + alchemical_state.lambda_electrostatics_A = 1 + alchemical_state.lambda_electrostatics_B = 0 energy_7 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 8: LigandA sterics on, elec partially on, # ligand B sterics on, elec partially on - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 0.75 - alchemical_state.lambda_electrostatics_ligandB = 0.25 + alchemical_state.lambda_sterics_A = 1 + alchemical_state.lambda_sterics_B = 1 + alchemical_state.lambda_electrostatics_A = 0.75 + alchemical_state.lambda_electrostatics_B = 0.25 energy_8 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 12: LigandA sterics on, elec off, ligand B sterics on, elec on - alchemical_state.lambda_sterics_ligandA = 1 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 0 - alchemical_state.lambda_electrostatics_ligandB = 1 + alchemical_state.lambda_sterics_A = 1 + alchemical_state.lambda_sterics_B = 1 + alchemical_state.lambda_electrostatics_A = 0 + alchemical_state.lambda_electrostatics_B = 1 energy_12 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) # Lambda 13: LigandA sterics partially on, elec off, ligand B sterics on, elec on - alchemical_state.lambda_sterics_ligandA = 0.857142857 - alchemical_state.lambda_sterics_ligandB = 1 - alchemical_state.lambda_electrostatics_ligandA = 0 - alchemical_state.lambda_electrostatics_ligandB = 1 + alchemical_state.lambda_sterics_A = 0.857142857 + alchemical_state.lambda_sterics_B = 1 + alchemical_state.lambda_electrostatics_A = 0 + alchemical_state.lambda_electrostatics_B = 1 energy_13 = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions ) From 4dd16afd3b3a84a0a98c01d67ffc21b497099f1f Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 16 Dec 2024 13:55:48 +0000 Subject: [PATCH 104/163] Add restraint settings --- .../restraint_utils/openmm/omm_restraints.py | 10 +- openfe/protocols/restraint_utils/settings.py | 116 +++++++++++++++++- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/openfe/protocols/restraint_utils/openmm/omm_restraints.py b/openfe/protocols/restraint_utils/openmm/omm_restraints.py index c77b1cd0b..0eaaa9585 100644 --- a/openfe/protocols/restraint_utils/openmm/omm_restraints.py +++ b/openfe/protocols/restraint_utils/openmm/omm_restraints.py @@ -288,7 +288,7 @@ class HarmonicBondRestraint( Notes ----- * Settings must contain a ``spring_constant`` for the - Force in units compatible with kilojoule/mole. + Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, @@ -335,7 +335,7 @@ class FlatBottomBondRestraint( Notes ----- * Settings must contain a ``spring_constant`` for the - Force in units compatible with kilojoule/mole. + Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, @@ -384,7 +384,7 @@ class CentroidHarmonicRestraint(BaseRadiallySymmetricRestraintForce): Notes ----- * Settings must contain a ``spring_constant`` for the - Force in units compatible with kilojoule/mole. + Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, @@ -429,7 +429,7 @@ class CentroidFlatBottomRestraint(BaseRadiallySymmetricRestraintForce): Notes ----- * Settings must contain a ``spring_constant`` for the - Force in units compatible with kilojoule/mole. + Force in units compatible with kilojoule/mole/nm**2. """ def _get_force( self, @@ -510,7 +510,7 @@ class BoreschRestraint(BaseHostGuestRestraints): (p2, p3, p4) and (p3, p4, p5). They must be provided by the Geometry class in units compatible with radians. - ``phi_A0``, ``phi_B0``, and ``phi_C0`` are the equilibrium constants + ``phi_A0``, ``phi_B0``, and ``phi_C0`` are the equilibrium force constants for the dihedrals formed by (p1, p2, p3, p4), (p2, p3, p4, p5), and (p3, p4, p5, p6). They must be provided in the settings in units compatible with kilojoule / mole / radians ** 2. diff --git a/openfe/protocols/restraint_utils/settings.py b/openfe/protocols/restraint_utils/settings.py index 0c12aef17..66998debb 100644 --- a/openfe/protocols/restraint_utils/settings.py +++ b/openfe/protocols/restraint_utils/settings.py @@ -2,22 +2,130 @@ # For details, see https://github.com/OpenFreeEnergy/openfe """ Settings for adding restraints. + +TODO +---- +* Rename from host/guest to molA/molB? """ from typing import Optional, Literal from openff.units import unit from openff.models.types import FloatQuantity, ArrayQuantity - +from pydantic.v1 import validator from gufe.settings import ( SettingsBaseModel, ) -from pydantic.v1 import validator - - class BaseRestraintSettings(SettingsBaseModel): """ Base class for RestraintSettings objects. """ class Config: arbitrary_types_allowed = True + + +class DistanceRestraintSettings(BaseRestraintSettings): + """ + Settings defining a distance restraint between + two groups of atoms defined as ``host`` and ``guest``. + """ + spring_constant: FloatQuantity['kilojoule_per_mole / nm ** 2'] + """ + The distance restraint potential spring constant. + """ + host_atoms: Optional[list[int]] = None + """ + The indices of the host component atoms to restrain. + If defined, these will override any automatic selection. + """ + guest_atoms: Optional[list[int]] = None + """ + The indices of the guest component atoms to restraint. + If defined, these will override any automatic selection. + """ + central_atoms_only: bool = False + """ + Whether to apply the restraint solely to the central atoms + of each group. + + Note: this can only be applied if ``host`` and ``guest`` + represent small molecules. + """ + + +class FlatBottomRestraintSettings(DistanceRestraintSettings): + """ + Settings to define a flat bottom restraint between two + groups of atoms named ``host`` and ``guest``. + """ + well_radius: Optional[FloatQuantity['nm']] = None + """ + The distance at which the harmonic restraint is imposed + in units of distance. + """ + + +class BoreschRestraintSettings(BaseRestraintSettings): + """ + Settings to define a Boresch-style restraint between + two groups of atoms named ``host`` and ``guest``. + + The restraint is defined in the following manner: + + H2 G2 + - - + - - + H1 - - H0 -- G0 - - G1 + + Where HX represents the X index of ``host_atoms`` + and GX the X indexx of ``guest_atoms``. + + By default, the Boresch-like restraint will be + obtained using a modified version of the + search algorithm implemented by Baumann et al. [1]. + + If ``guest_atoms`` and ``host_atoms`` are defined, + these indices will be used instead. + + References + ---------- + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free + energy calculations using a Separated Topologies approach." (2023). + """ + K_r: FloatQuantity['kilojoule_per_mole / nm ** 2'] + """ + The bond spring constant between H0 and G0. + """ + K_thetaA: FloatQuantity['kilojoule_per_mole / radians ** 2'] + """ + The spring constant for the angle formed by H1-H0-G0. + """ + K_thetaB: FloatQuantity['kilojoule_per_mole / radians ** 2'] + """ + The spring constant for the angle formed by H0-G0-G1. + """ + phi_A0: FloatQuantity['kilojoule_per_mole / radians ** 2'] + """ + The equilibrium force constant for the dihedral formed by + H2-H1-H0-G0. + """ + phi_B0: FloatQuantity['kilojoule_per_mole / radians ** 2'] + """ + The equilibrium force constant for the dihedral formed by + H1-H0-G0-G1. + """ + phi_C0: FloatQuantity['kilojoule_per_mole / radians ** 2'] + """ + The equilibrium force constant for the dihedral formed by + H0-G0-G1-G2. + """ + host_atoms: Optional[list[int]] = None + """ + The indices of the host component atoms to restrain. + If defined, these will override any automatic selection. + """ + guest_atoms: Optional[list[int]] = None + """ + The indices of the guest component atoms to restraint. + If defined, these will override any automatic selection. + """ \ No newline at end of file From ec0d01de87de97dd88feb4add9e360c8bc901c7c Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 16 Dec 2024 13:57:01 +0000 Subject: [PATCH 105/163] Add missing settings imports --- openfe/protocols/restraint_utils/openmm/omm_restraints.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openfe/protocols/restraint_utils/openmm/omm_restraints.py b/openfe/protocols/restraint_utils/openmm/omm_restraints.py index 0eaaa9585..8df9cb837 100644 --- a/openfe/protocols/restraint_utils/openmm/omm_restraints.py +++ b/openfe/protocols/restraint_utils/openmm/omm_restraints.py @@ -36,6 +36,12 @@ DistanceRestraintGeometry, BoreschRestraintGeometry ) + +from openfe.protocols.restraint_utils.settings import ( + DistanceRestraintSettings, + BoreschRestraintSettings, +) + from .omm_forces import ( get_custom_compound_bond_force, add_force_in_separate_group, From d989feb773e18a9a94b69a6a3c63178b57db2e44 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 16 Dec 2024 15:26:29 +0100 Subject: [PATCH 106/163] Change alchemical state def --- openfe/protocols/openmm_septop/base.py | 11 ++--------- openfe/tests/protocols/test_openmm_septop_slow.py | 7 +++---- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 0f3282274..80c2e2b75 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -985,15 +985,8 @@ def _get_states( cmp_states : list[ThermodynamicState] A list of ThermodynamicState for each replica in the system. """ - # alchemical_state = AlchemicalState.from_system(alchemical_system) - alchemical_state = SepTopParameterState( - lambda_sterics_A=1.0, - lambda_electrostatics_A=1.0, - lambda_restraints_A=1.0, - lambda_sterics_B=1.0, - lambda_electrostatics_B=1.0, - lambda_restraints_B=1.0, - ) + alchemical_state = SepTopParameterState.from_system(alchemical_system) + # Set up the system constants temperature = settings['thermo_settings'].temperature pressure = settings['thermo_settings'].pressure diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 9c810f3b8..6d33a9fc4 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -27,7 +27,7 @@ femto_restraints, ) from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close -from openfe.protocols.openmm_septop.utils import deserialize +from openfe.protocols.openmm_septop.utils import deserialize, SepTopParameterState from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference from openmmtools.states import (SamplerState, ThermodynamicState, @@ -37,7 +37,6 @@ from openfe.protocols.openmm_utils.charge_generation import ( HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA ) -from openfe.protocols.openmm_septop.alchemy_copy import AlchemicalState @pytest.fixture() @@ -47,9 +46,9 @@ def default_settings(): def compare_energies(alchemical_system, positions): - alchemical_state = AlchemicalState.from_system(alchemical_system) + alchemical_state = SepTopParameterState.from_system(alchemical_system) - from openfe.protocols.openmm_septop.alchemy_copy import AbsoluteAlchemicalFactory + from openmmtools.alchemy import AbsoluteAlchemicalFactory energy = AbsoluteAlchemicalFactory.get_energy_components( alchemical_system, alchemical_state, positions From 6311a9240d9f1a6283fad561c67bd6306a3c7257 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 17 Dec 2024 09:08:50 +0100 Subject: [PATCH 107/163] Remove copy of AlchemicalFactory --- .../protocols/openmm_septop/alchemy_copy.py | 2539 ----------------- 1 file changed, 2539 deletions(-) delete mode 100644 openfe/protocols/openmm_septop/alchemy_copy.py diff --git a/openfe/protocols/openmm_septop/alchemy_copy.py b/openfe/protocols/openmm_septop/alchemy_copy.py deleted file mode 100644 index 12ce7f2d1..000000000 --- a/openfe/protocols/openmm_septop/alchemy_copy.py +++ /dev/null @@ -1,2539 +0,0 @@ -#!/usr/bin/python - -# ============================================================================= -# MODULE DOCSTRING -# ============================================================================= - -""" -Alchemical factory for free energy calculations that operates directly on OpenMM System objects. - -DESCRIPTION - -This module contains enumerative factories for generating alchemically-modified System objects -usable for the calculation of free energy differences of hydration or ligand binding. - -* `AbsoluteAlchemicalFactory` uses fused elecrostatic and steric alchemical modifications. - -""" - -# TODO -# - Generalize treatment of nonbonded sterics/electrostatics intra-alchemical -# forces to support arbitrary mixing rules. Can we eliminate decoupling to something simpler? -# - Add support for other GBSA models. -# - Add functions for the automatic optimization of alchemical states? -# - Can we store serialized form of Force objects so that we can save time in reconstituting -# Force objects when we make copies? We can even manipulate the XML representation directly. -# - Allow protocols to automatically be resized to arbitrary number of states, to -# allow number of states to be enlarged to be an integral multiple of number of GPUs. -# - Finish AMOEBA support. -# - Can alchemically-modified System objects share unmodified Force objects to avoid overhead -# of duplicating Forces that are not modified? -# - Add support for arbitrary softcore reprogramming of all Custom*Force classes - - -# ============================================================================= -# GLOBAL IMPORTS -# ============================================================================= -import copy -import logging -import collections -import itertools -import re - -import numpy as np -try: - import openmm - from openmm import unit -except ImportError: # OpenMM < 7.6 - from simtk import openmm, unit - -from openmmtools import states, forcefactories, utils -from openmmtools.constants import ONE_4PI_EPS0 - -logger = logging.getLogger(__name__) - - -# ============================================================================= -# ALCHEMICAL STATE -# ============================================================================= - -class AlchemicalStateError(states.GlobalParameterError): - """Error raised by an AlchemicalState.""" - pass - - -class AlchemicalFunction(states.GlobalParameterFunction): - """A function of alchemical variables. - - Parameters - ---------- - expression : str - A mathematical expression involving alchemical variables. - - Examples - -------- - >>> alchemical_state = AlchemicalState(lambda_sterics=1.0, lambda_angles=1.0) - >>> alchemical_state.set_alchemical_variable('lambda', 0.5) - >>> alchemical_state.set_alchemical_variable('lambda2', 1.0) - >>> alchemical_state.lambda_sterics = AlchemicalFunction('lambda**2') - >>> alchemical_state.lambda_sterics - 0.25 - >>> alchemical_state.lambda_angles = AlchemicalFunction('(lambda + lambda2) / 2') - >>> alchemical_state.lambda_angles - 0.75 - - """ - # This class just provides an alternative name to GlobalParameterFunction. - pass - - -class AlchemicalState(states.GlobalParameterState): - """Represent an alchemical state. - - The alchemical parameters modify the Hamiltonian and affect the - computation of the energy. Alchemical parameters that have value - None are considered undefined, which means that applying this - state to System and Context that have that parameter as a global - variable will raise an AlchemicalStateError. - - Parameters - ---------- - parameters_name_suffix : str, optional - If specified, the state will control a modified version of the global - parameters with the name ``parameter_name + '_' + parameters_name_suffix``. - When this is the case, the normal parameters are not accessible. - lambda_sterics : float, optional - Scaling factor for ligand sterics (Lennard-Jones and Halgren) - interactions (default is 1.0). - lambda_electrostatics : float, optional - Scaling factor for ligand charges, intrinsic Born radii, and surface - area term (default is 1.0). - lambda_bonds : float, optional - Scaling factor for alchemically-softened bonds (default is 1.0). - lambda_angles : float, optional - Scaling factor for alchemically-softened angles (default is 1.0). - lambda_torsions : float, optional - Scaling factor for alchemically-softened torsions (default is 1.0). - - Attributes - ---------- - lambda_sterics - lambda_electrostatics - lambda_bonds - lambda_angles - lambda_torsions - - Examples - -------- - Create an alchemically modified system. - - >>> from openmmtools import testsystems - >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - >>> alanine_vacuum = testsystems.AlanineDipeptideVacuum().system - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=range(22)) - >>> alanine_alchemical_system = factory.create_alchemical_system(reference_system=alanine_vacuum, - ... alchemical_regions=alchemical_region) - - Create a completely undefined alchemical state. - - >>> alchemical_state = AlchemicalState() - >>> print(alchemical_state.lambda_sterics) - None - >>> alchemical_state.apply_to_system(alanine_alchemical_system) - Traceback (most recent call last): - ... - openmmtools.alchemy.AlchemicalStateError: The system parameter lambda_electrostatics is not defined in this state. - - Create an AlchemicalState that matches the parameters defined in - the System. - - >>> alchemical_state = AlchemicalState.from_system(alanine_alchemical_system) - >>> alchemical_state.lambda_sterics - 1.0 - >>> alchemical_state.lambda_electrostatics - 1.0 - >>> print(alchemical_state.lambda_angles) - None - - AlchemicalState implement the IComposableState interface, so it can be - used with CompoundThermodynamicState. All the alchemical parameters are - accessible through the compound state. - - >>> import openmm - >>> from openmm import unit - >>> thermodynamic_state = states.ThermodynamicState(system=alanine_alchemical_system, - ... temperature=300*unit.kelvin) - >>> compound_state = states.CompoundThermodynamicState(thermodynamic_state=thermodynamic_state, - ... composable_states=[alchemical_state]) - >>> compound_state.lambda_sterics - 1.0 - - You can control the parameters in the OpenMM Context in this state by - setting the state attributes. - - >>> compound_state.lambda_sterics = 0.5 - >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) - >>> context = compound_state.create_context(integrator) - >>> context.getParameter('lambda_sterics') - 0.5 - >>> compound_state.lambda_sterics = 1.0 - >>> compound_state.apply_to_context(context) - >>> context.getParameter('lambda_sterics') - 1.0 - - You can express the alchemical parameters as a mathematical expression - involving alchemical variables. Here is an example for a two-stage function. - - >>> compound_state.set_alchemical_variable('lambda', 1.0) - >>> compound_state.lambda_sterics = AlchemicalFunction('step_hm(lambda - 0.5) + 2*lambda * step_hm(0.5 - lambda)') - >>> compound_state.lambda_electrostatics = AlchemicalFunction('2*(lambda - 0.5) * step(lambda - 0.5)') - >>> for l in [0.0, 0.25, 0.5, 0.75, 1.0]: - ... compound_state.set_alchemical_variable('lambda', l) - ... print(compound_state.lambda_sterics) - 0.0 - 0.5 - 1.0 - 1.0 - 1.0 - - """ - - _GLOBAL_PARAMETER_ERROR = AlchemicalStateError - - # ------------------------------------------------------------------------- - # Lambda properties - # ------------------------------------------------------------------------- - - class _LambdaParameter(states.GlobalParameterState.GlobalParameter): - """A global parameter in the interval [0, 1] with standard value 1.""" - - def __init__(self, parameter_name): - super().__init__(parameter_name, standard_value=1.0, validator=self.lambda_validator) - - @staticmethod - def lambda_validator(self, instance, parameter_value): - if parameter_value is None: - return parameter_value - if not (0.0 <= parameter_value <= 1.0): - raise ValueError('{} must be between 0 and 1.'.format(self.parameter_name)) - return float(parameter_value) - - lambda_sterics_ligandA = _LambdaParameter('lambda_sterics_ligandA') - lambda_sterics_ligandB = _LambdaParameter('lambda_sterics_ligandB') - lambda_electrostatics_ligandA = _LambdaParameter('lambda_electrostatics_ligandA') - lambda_electrostatics_ligandB = _LambdaParameter('lambda_electrostatics_ligandB') - lambda_restraints_ligandA = _LambdaParameter('lambda_restraints_ligandA') - lambda_restraints_ligandB = _LambdaParameter('lambda_restraints_ligandB') - lambda_bonds = _LambdaParameter('lambda_bonds') - lambda_angles = _LambdaParameter('lambda_angles') - lambda_torsions = _LambdaParameter('lambda_torsions') - - @classmethod - def from_system(cls, system, *args, **kwargs): - """Constructor reading the state from an alchemical system. - - Parameters - ---------- - system : openmm.System - An alchemically modified system in a defined alchemical state. - parameters_name_suffix : str, optional - If specified, the state will search for a modified - version of the alchemical parameters with the name - ``parameter_name + '_' + parameters_name_suffix``. - - Returns - ------- - The AlchemicalState object representing the alchemical state of - the system. - - Raises - ------ - AlchemicalStateError - If the same parameter has different values in the system, or - if the system has no lambda parameters. - - """ - # The function is redefined here only to provide more specific documentation for this method. - return super().from_system(system, *args, **kwargs) - - def set_alchemical_parameters(self, new_value): - """Set all defined lambda parameters to the given value. - - The undefined parameters (i.e. those being set to None) remain - undefined. - - Parameters - ---------- - new_value : float - The new value for all defined parameters. - - """ - for parameter_name in self._parameters: - if self._parameters[parameter_name] is not None: - setattr(self, parameter_name, new_value) - - # ------------------------------------------------------------------------- - # Function variables - # ------------------------------------------------------------------------- - - def get_function_variable(self, variable_name): - """Return the value of the function variable. - - Function variables are variables entering mathematical expressions - specified with ``AlchemicalFunction``, which can be use to enslave - a lambda parameter to arbitrary variables. - - Parameters - ---------- - variable_name : str - The name of the function variable. - - Returns - ------- - variable_value : float - The value of the function variable. - - """ - # The function is redefined here only to provide more specific documentation for this method. - return super().get_function_variable(variable_name) - - def set_function_variable(self, variable_name, new_value): - """Set the value of the function variable. - - Function variables are variables entering mathematical expressions - specified with ``AlchemicalFunction``, which can be use to enslave - a lambda parameter to arbitrary variables. - - Parameters - ---------- - variable_name : str - The name of the function variable. - new_value : float - The new value for the variable. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().set_function_variable(variable_name, new_value) - - def get_alchemical_variable(self, variable_name): - """Return the value of the alchemical parameter. - - .. warning: - This is deprecated. Use ``get_function_variable`` instead. - - Parameters - ---------- - variable_name : str - The name of the alchemical variable. - - Returns - ------- - variable_value : float - The value of the alchemical variable. - """ - import warnings - warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' - 'Use AlchemicalState.get_function_variable instead.') - return super().get_function_variable(variable_name) - - def set_alchemical_variable(self, variable_name, new_value): - """Set the value of the alchemical variable. - - .. warning: - This is deprecated. Use ``set_function_variable`` instead. - - Parameters - ---------- - variable_name : str - The name of the alchemical variable. - new_value : float - The new value for the variable. - - """ - import warnings - warnings.warn('AlchemicalState.get_alchemical_variable is deprecated. ' - 'Use AlchemicalState.get_function_variable instead.') - super().set_function_variable(variable_name, new_value) - - # ------------------------------------------------------------------------- - # IComposableState interface - # ------------------------------------------------------------------------- - - def apply_to_system(self, system): - """Set the alchemical state of the system to this. - - Parameters - ---------- - system : openmm.System - The system to modify. - - Raises - ------ - AlchemicalStateError - If the system does not have the required lambda global variables. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().apply_to_system(system) - - def check_system_consistency(self, system): - """Check if the system is in this alchemical state. - - It raises a AlchemicalStateError if the system is not consistent - with the alchemical state. - - Parameters - ---------- - system : openmm.System - The system to test. - - Raises - ------ - AlchemicalStateError - If the system is not consistent with this state. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().check_system_consistency(system) - - def apply_to_context(self, context): - """Put the Context into this AlchemicalState. - - Parameters - ---------- - context : openmm.Context - The context to set. - - Raises - ------ - AlchemicalStateError - If the context does not have the required lambda global variables. - - """ - # The function is redefined here only to provide more specific documentation for this method. - super().apply_to_context(context) - - -# ============================================================================= -# ALCHEMICAL REGION -# ============================================================================= - -_ALCHEMICAL_REGION_ARGS = collections.OrderedDict([ - ('alchemical_atoms', None), - ('alchemical_bonds', None), - ('alchemical_angles', None), - ('alchemical_torsions', None), - ('annihilate_electrostatics', True), - ('annihilate_sterics', False), - ('softcore_alpha', 0.5), ('softcore_a', 1), ('softcore_b', 1), ('softcore_c', 6), - ('softcore_beta', 0.0), ('softcore_d', 1), ('softcore_e', 1), ('softcore_f', 2), - ('name', None) -]) - - -# The class is just a way to document the namedtuple. -class AlchemicalRegion(collections.namedtuple('AlchemicalRegion', _ALCHEMICAL_REGION_ARGS.keys())): - """Alchemical region. - - This is a namedtuple used to tell the AbsoluteAlchemicalFactory which - region of the system to alchemically modify and how. - - Parameters - ---------- - alchemical_atoms : list of int, optional - List of atoms to be designated for which the nonbonded forces (both - sterics and electrostatics components) have to be alchemically - modified (default is None). - alchemical_bonds : bool or list of int, optional - If a list of bond indices are specified, these HarmonicBondForce - entries are softened with 'lambda_bonds'. If set to True, this list - is auto-generated to include all bonds involving any alchemical - atoms (default is None). - alchemical_angles : bool or list of int, optional - If a list of angle indices are specified, these HarmonicAngleForce - entries are softened with 'lambda_angles'. If set to True, this - list is auto-generated to include all angles involving any alchemical - atoms (default is None). - alchemical_torsions : bool or list of int, optional - If a list of torsion indices are specified, these PeriodicTorsionForce - entries are softened with 'lambda_torsions'. If set to True, this list - is auto-generated to include al proper torsions involving any alchemical - atoms. Improper torsions are not softened (default is None). - annihilate_electrostatics : bool, optional - If True, electrostatics should be annihilated, rather than decoupled - (default is True). - annihilate_sterics : bool, optional - If True, sterics (Lennard-Jones or Halgren potential) will be annihilated, - rather than decoupled (default is False). - softcore_alpha : float, optional - Alchemical softcore parameter for Lennard-Jones (default is 0.5). - softcore_a, softcore_b, softcore_c : float, optional - Parameters modifying softcore Lennard-Jones form. Introduced in - Eq. 13 of Ref. [1] (default is 1). - softcore_beta : float, optional - Alchemical softcore parameter for electrostatics. Set this to zero - to recover standard electrostatic scaling (default is 0.0). - softcore_d, softcore_e, softcore_f : float, optional - Parameters modifying softcore electrostatics form (default is 1). - - Notes - ----- - The parameters softcore_e and softcore_f determine the effective distance - between point charges according to - - r_eff = sigma*((softcore_beta*(lambda_electrostatics-1)^softcore_e + (r/sigma)^softcore_f))^(1/softcore_f) - - References - ---------- - [1] Pham TT and Shirts MR. Identifying low variance pathways for free - energy calculations of molecular transformations in solution phase. - JCP 135:034114, 2011. http://dx.doi.org/10.1063/1.3607597 - - """ -AlchemicalRegion.__new__.__defaults__ = tuple(_ALCHEMICAL_REGION_ARGS.values()) - - -# ============================================================================= -# ABSOLUTE ALCHEMICAL FACTORY -# ============================================================================= - -class AbsoluteAlchemicalFactory(object): - """Factory of alchemically modified OpenMM Systems. - - The context parameters created are: - - softcore_alpha: factor controlling softcore lengthscale for Lennard-Jones - - softcore_beta: factor controlling softcore lengthscale for Coulomb - - softcore_a: softcore Lennard-Jones parameter from Eq. 13 of Ref [1] - - softcore_b: softcore Lennard-Jones parameter from Eq. 13 of Ref [1] - - softcore_c: softcore Lennard-Jones parameter from Eq. 13 of Ref [1] - - softcore_d: softcore electrostatics parameter - - softcore_e: softcore electrostatics parameter - - softcore_f: softcore electrostatics parameter - - Parameters - ---------- - consistent_exceptions : bool, optional, default = False - If True, the same functional form of the System's nonbonded - method will be use to determine the electrostatics contribution - to the potential energy of 1,4 exceptions instead of the - classical q1*q2/(4*epsilon*epsilon0*pi*r). - switch_width : float, optional, default = 1.0 * angstroms - Default switch width for electrostatics in periodic cutoff systems - used in alchemical interactions only. - alchemical_pme_treatment : str, optional, default = 'exact' - Controls how alchemical region electrostatics are treated when PME is used. - Options are ['direct-space', 'coulomb', 'exact']. - - 'direct-space' only models the direct space contribution - - 'coulomb' includes switched Coulomb interaction - - 'exact' includes also the reciprocal space contribution, but it's - only possible to annihilate the charges and the softcore parameters - controlling the electrostatics are deactivated. Also, with this - method, modifying the global variable `lambda_electrostatics` is - not sufficient to control the charges. The recommended way to change - them is through the `AlchemicalState` class. - alchemical_rf_treatment : str, optional, default = 'switched' - Controls how alchemical region electrostatics are treated when RF is used - Options are ['switched', 'shifted'] - 'switched' sets c_rf = 0 for all reaction-field interactions and ensures continuity with a switch - 'shifted' retains c_rf != 0 but can give erroneous results for hydration free energies - disable_alchemical_dispersion_correction : bool, optional, default=False - If True, the long-range dispersion correction will not be included for the alchemical - region to avoid the need to recompute the correction (a CPU operation that takes ~ 0.5 s) - every time 'lambda_sterics' is changed. If using nonequilibrium protocols, it is recommended - that this be set to True since this can lead to enormous (100x) slowdowns if the correction - must be recomputed every time step. - split_alchemical_forces : bool, optional, default=True - If True, forces that are altered to different alchemical variables - will be split in different force groups. All non-alchemical forces - will maintain their original force group. If more than 32 force - groups are required, an error is thrown. - - Examples - -------- - - Create an alchemical factory to alchemically modify OpenMM System objects. - - >>> factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) - - Create an alchemically modified version of p-xylene in T4 lysozyme L99A in GBSA. - - >>> # Create a reference system. - >>> from openmmtools import testsystems - >>> reference_system = testsystems.LysozymeImplicit().system - >>> # Alchemically soften the pxylene atoms - >>> pxylene_atoms = range(2603,2621) # p-xylene - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=pxylene_atoms) - >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) - - Alchemically modify one water in a water box. - - >>> reference_system = testsystems.WaterBox().system - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0, 1, 2]) - >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) - - Alchemically modify some angles and torsions in alanine dipeptide and - annihilate both sterics and electrostatics. - - >>> reference_system = testsystems.AlanineDipeptideVacuum().system - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0], alchemical_torsions=[0,1,2], - ... alchemical_angles=[0,1,2], annihilate_sterics=True, - ... annihilate_electrostatics=True) - >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) - - Alchemically modify a bond, angles, and torsions in toluene by automatically - selecting bonds involving alchemical atoms. - - >>> toluene_implicit = testsystems.TolueneImplicit() - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0,1], alchemical_torsions=True, - ... alchemical_angles=True, annihilate_sterics=True) - >>> alchemical_system = factory.create_alchemical_system(reference_system, alchemical_region) - - Once the alchemical system is created, you can modify its Hamiltonian - through AlchemicalState - - >>> alchemical_state = AlchemicalState.from_system(alchemical_system) - >>> alchemical_state.lambda_sterics - 1.0 - >>> alchemical_state.lambda_electrostatics = 0.5 - >>> alchemical_state.apply_to_system(alchemical_system) - - You can also modify its Hamiltonian directly into a context - - >>> import openmm - >>> from openmm import unit - >>> integrator = openmm.VerletIntegrator(1.0*unit.femtosecond) - >>> context = openmm.Context(alchemical_system, integrator) - >>> alchemical_state.set_alchemical_parameters(0.0) # Set all lambda to 0 - >>> alchemical_state.apply_to_context(context) - - Neglecting the long-range dispersion correction for the alchemical region - (for nonequilibrium switching, for example) requires instantiating a factory - with the appropriate options: - - >>> new_factory = AbsoluteAlchemicalFactory(consistent_exceptions=False, disable_alchemical_dispersion_correction=True) - >>> reference_system = testsystems.WaterBox().system - >>> alchemical_region = AlchemicalRegion(alchemical_atoms=[0, 1, 2]) - >>> alchemical_system = new_factory.create_alchemical_system(reference_system, alchemical_region) - - References - ---------- - [1] Pham TT and Shirts MR. Identifying low variance pathways for free - energy calculations of molecular transformations in solution phase. - JCP 135:034114, 2011. http://dx.doi.org/10.1063/1.3607597 - - """ - - # ------------------------------------------------------------------------- - # Public interface - # ------------------------------------------------------------------------- - - def __init__(self, consistent_exceptions=False, switch_width=1.0*unit.angstroms, - alchemical_pme_treatment='exact', alchemical_rf_treatment='switched', - disable_alchemical_dispersion_correction=False, split_alchemical_forces=True): - - self.consistent_exceptions = consistent_exceptions - self.switch_width = switch_width - self.alchemical_pme_treatment = alchemical_pme_treatment - self.alchemical_rf_treatment = alchemical_rf_treatment - self.disable_alchemical_dispersion_correction = disable_alchemical_dispersion_correction - self.split_alchemical_forces = split_alchemical_forces - - def create_alchemical_system(self, reference_system, alchemical_regions, - alchemical_regions_interactions=frozenset()): - """Create an alchemically modified version of the reference system. - - To alter the alchemical state of the returned system use AlchemicalState. - - Parameters - ---------- - reference_system : openmm.System - The system to use as a reference for the creation of the - alchemical system. This will not be modified. - alchemical_regions : AlchemicalRegion - The region of the reference system to alchemically soften. - alchemical_regions_interactions : Set[Tuple[int, int]], optional - Set of alchemical region index pairs for interacting regions. - By default, all alchemical regions interact only with the - non-alchemical environment. - - Returns - ------- - alchemical_system : openmm.System - Alchemically-modified version of reference_system. - - """ - if alchemical_regions_interactions != frozenset(): - raise NotImplementedError('Interactions between alchemical regions is untested') - - logger.debug(f'Dictionary of interacting alchemical regions: {alchemical_regions_interactions}') - if isinstance(alchemical_regions, AlchemicalRegion): - alchemical_regions = [alchemical_regions] - logger.debug(f'Using {len(alchemical_regions)} alchemical regions') - - # Resolve alchemical regions. - alchemical_regions = [self._resolve_alchemical_region(reference_system, alchemical_region) - for alchemical_region in alchemical_regions] - - # Check for duplicate alchemical atoms/bonds/angles/torsions. - all_alchemical_elements = {element_type: set() for element_type in ['atoms', 'bonds', 'angles', 'torsions']} - - for alchemical_region in alchemical_regions: - for element_type, all_elements in all_alchemical_elements.items(): - # Ignore None alchemical elements. - region_elements = getattr(alchemical_region, 'alchemical_' + element_type) - if region_elements is None: - continue - - # Check if there are duplicates with previous regions. - duplicate_elements = all_elements & region_elements - if len(duplicate_elements) > 0: - raise ValueError('Two regions have duplicate {}.'.format(element_type)) - - # Update all alchemical elements. - all_alchemical_elements[element_type].update(region_elements) - - # Check for duplicate names - alchemical_region_names = {alchemical_region.name for alchemical_region in alchemical_regions} - if len(alchemical_region_names) != len(alchemical_regions): - raise ValueError('Two alchemical regions have the same name') - - # Record timing statistics. - timer = utils.Timer() - timer.start('Create alchemically modified system') - - # Build alchemical system to modify. This copies particles, vsites, - # constraints, box vectors and all the forces. We'll later remove - # the forces that we remodel to be alchemically modified. - alchemical_system = copy.deepcopy(reference_system) - - # Check that there are no virtual sites to alchemically modify. - for alchemical_region in alchemical_regions: - for particle_index in alchemical_region.alchemical_atoms: - if reference_system.isVirtualSite(particle_index): - raise ValueError(f'Virtual atoms in region {alchemical_region.name}. ' - 'Alchemically modified virtual sites are not supported') - - # Modify forces as appropriate. We delete the forces that - # have been processed modified at the end of the for loop. - forces_to_remove = [] - alchemical_forces_by_lambda = {} - for force_index, reference_force in enumerate(reference_system.getForces()): - # TODO switch to functools.singledispatch when we drop Python2 support - reference_force_name = reference_force.__class__.__name__ - alchemical_force_creator_name = '_alchemically_modify_{}'.format(reference_force_name) - try: - alchemical_force_creator_func = getattr(self, alchemical_force_creator_name) - except AttributeError as e: - pass - else: - # The reference system force will be deleted. - forces_to_remove.append(force_index) - # Collect all the Force objects modeling the reference force. - alchemical_forces = alchemical_force_creator_func(reference_force, alchemical_regions, - alchemical_regions_interactions) - for lambda_variable_name, lambda_forces in alchemical_forces.items(): - try: - alchemical_forces_by_lambda[lambda_variable_name].extend(lambda_forces) - except KeyError: - alchemical_forces_by_lambda[lambda_variable_name] = lambda_forces - - # Remove original forces that have been alchemically modified. - for force_index in reversed(forces_to_remove): - alchemical_system.removeForce(force_index) - # Add forces and split groups if necessary. - self._add_alchemical_forces(alchemical_system, alchemical_forces_by_lambda) - - # Record timing statistics. - timer.stop('Create alchemically modified system') - timer.report_timing() - - # If the System uses a NonbondedForce, replace its NonbondedForce implementation of reaction field - # with a Custom*Force implementation that uses c_rf = 0. - # NOTE: This adds an additional CustomNonbondedForce - if self.alchemical_rf_treatment == 'switched': - forcefactories.replace_reaction_field(alchemical_system, return_copy=False, - switch_width=self.switch_width) - - return alchemical_system - - @classmethod - def get_energy_components(cls, alchemical_system, alchemical_state, positions, platform=None): - """Compute potential energy of the alchemical system by Force. - - This can be useful for debug and analysis. - - Parameters - ---------- - alchemical_system : openmm.AlchemicalSystem - An alchemically modified system. - alchemical_state : AlchemicalState - The alchemical state to set the Context to. - positions : openmm.unit.Quantity of dimension (natoms, 3) - Coordinates to use for energy test (units of distance). - platform : openmm.Platform, optional - The OpenMM platform to use to compute the energy. If None, - OpenMM tries to select the fastest available. - - Returns - ------- - energy_components : dict str: openmm.unit.Quantity - A string label describing the role of the force associated to - its contribution to the potential energy. - - """ - # Find and label all forces. - force_labels = cls._find_force_components(alchemical_system) - assert len(force_labels) <= 32, ("The alchemical system has more than 32 force groups; " - "can't compute individual force component energies.") - - # Create deep copy of alchemical system. - system = copy.deepcopy(alchemical_system) - - # Separate all forces into separate force groups. - for force_index, force in enumerate(system.getForces()): - force.setForceGroup(force_index) - - # Create a Context in the given state. - integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds) - if platform is None: - context = openmm.Context(system, integrator) - else: - context = openmm.Context(system, integrator, platform) - context.setPositions(positions) - alchemical_state.apply_to_context(context) - - # Get energy components - energy_components = collections.OrderedDict() - for force_label, force_index in force_labels.items(): - energy_components[force_label] = context.getState(getEnergy=True, - groups=2**force_index).getPotentialEnergy() - - # Clean up - del context, integrator - return energy_components - - # ------------------------------------------------------------------------- - # Internal usage: AlchemicalRegion - # ------------------------------------------------------------------------- - - @classmethod - def _resolve_alchemical_region(cls, system, alchemical_region): - """Return a new AlchemicalRegion with sets of bonds/angles/torsions resolved. - - Also transform any list of indices into a frozenset. - - Parameters - ---------- - system : openmm.System - The system. - alchemical_region : AlchemicalRegion - The alchemical region of the system. - - Returns - ------- - AlchemicalRegion - A new AlchemicalRegion object in which all alchemical_X (where X is - atoms, bonds, angles, or torsions) have been converted to a frozenset - of indices that belong to the System. - - Raises - ------ - ValueError - If the indices in the AlchemicalRegion can't be found in the system. - - """ - # TODO move to AlchemicalRegion? - # TODO process also custom forces? (also in _build_alchemical_X_list methods) - # Find and cache the reference forces. - reference_forces = {force.__class__.__name__: force for force in system.getForces()} - - # Count number of particles, angles, etc. in system. Atoms - # must be processed first since the others build on that. - reference_counts = collections.OrderedDict([ - ('atom', system.getNumParticles()), - ('bond', reference_forces['HarmonicBondForce'].getNumBonds() - if 'HarmonicBondForce' in reference_forces else 0), - ('angle', reference_forces['HarmonicAngleForce'].getNumAngles() - if 'HarmonicAngleForce' in reference_forces else 0), - ('torsion', reference_forces['PeriodicTorsionForce'].getNumTorsions() - if 'PeriodicTorsionForce' in reference_forces else 0) - ]) - - # Transform named tuple to dict for easy modification. - alchemical_region = alchemical_region._asdict() - - for region in reference_counts: - region_name = 'alchemical_' + region + 's' - region_indices = alchemical_region[region_name] - - # Convert None and False to empty lists. - if region_indices is None or region_indices is False: - region_indices = set() - - # Automatically build indices list if True. - elif region_indices is True: - if reference_counts[region] == 0: - region_indices = set() - else: - # TODO switch to functools.singledispatch when drop Python2 - builder_function = getattr(cls, '_build_alchemical_{}_list'.format(region)) - region_indices = builder_function(alchemical_region['alchemical_atoms'], - reference_forces, system) - - # Convert numpy arrays to Python lists since SWIG - # have problems with np.int (see openmm#1650). - elif isinstance(region_indices, np.ndarray): - region_indices = region_indices.tolist() - - # Convert to set and update alchemical region. - region_indices = frozenset(region_indices) - alchemical_region[region_name] = region_indices - - # Check that the given indices are in the system. - indices_diff = region_indices - set(range(reference_counts[region])) - if len(indices_diff) > 0: - err_msg = 'Indices {} in {} cannot be found in the system' - raise ValueError(err_msg.format(indices_diff, region_name)) - - # Check that an alchemical region is defined. - total_alchemically_modified = 0 - for region in reference_counts: - total_alchemically_modified += len(alchemical_region['alchemical_' + region + 's']) - if total_alchemically_modified == 0: - raise ValueError('The AlchemicalRegion is empty.') - - # Return a new AlchemicalRegion with the resolved indices lists. - return AlchemicalRegion(**alchemical_region) - - @staticmethod - def _tabulate_bonds(system): - """ - Tabulate bonds for the specified system. - - Parameters - ---------- - system : openmm.System - The system for which bonds are to be tabulated. - - Returns - ------- - bonds : list of set - bonds[i] is the set of bonds to atom i - - TODO: - * Could we use a Topology object to simplify this? - - """ - bonds = [set() for _ in range(system.getNumParticles())] - - forces = {system.getForce(index).__class__.__name__: system.getForce(index) - for index in range(system.getNumForces())} - - # Process HarmonicBondForce - bond_force = forces['HarmonicBondForce'] - for bond_index in range(bond_force.getNumBonds()): - [particle1, particle2, r, K] = bond_force.getBondParameters(bond_index) - bonds[particle1].add(particle2) - bonds[particle2].add(particle1) - # Process constraints. - for constraint_index in range(system.getNumConstraints()): - [particle1, particle2, r] = system.getConstraintParameters(constraint_index) - bonds[particle1].add(particle2) - bonds[particle2].add(particle1) - - # TODO: Process CustomBondForce? - - return bonds - - @classmethod - def _build_alchemical_torsion_list(cls, alchemical_atoms, reference_forces, system): - """ - Build a list of proper torsion indices that involve any alchemical atom. - - Parameters - ---------- - alchemical_atoms : set of int - The set of alchemically modified atoms. - reference_forces : dict str: force - A dictionary of cached forces in the system accessible by names. - system : openmm.System - The system. - - Returns - ------- - torsion_list : list of int - The list of torsion indices that should be alchemically softened - - """ - - # Tabulate all bonds - bonds = cls._tabulate_bonds(system) - - def is_bonded(i, j): - if j in bonds[i]: - return True - return False - - def is_proper_torsion(i, j, k, l): - if is_bonded(i, j) and is_bonded(j, k) and is_bonded(k, l): - return True - return False - - # Create a list of proper torsions that involve any alchemical atom. - torsion_list = list() - force = reference_forces['PeriodicTorsionForce'] - for torsion_index in range(force.getNumTorsions()): - particle1, particle2, particle3, particle4, periodicity, phase, k = force.getTorsionParameters(torsion_index) - if set([particle1, particle2, particle3, particle4]).intersection(alchemical_atoms): - if is_proper_torsion(particle1, particle2, particle3, particle4): - torsion_list.append(torsion_index) - - return torsion_list - - @staticmethod - def _build_alchemical_angle_list(alchemical_atoms, reference_forces, system): - """ - Build a list of angle indices that involve any alchemical atom. - - Parameters - ---------- - alchemical_atoms : set of int - The set of alchemically modified atoms. - reference_forces : dict str: force - A dictionary of cached forces in the system accessible by names. - system : openmm.System - The system (unused). - - Returns - ------- - angle_list : list of int - The list of angle indices that should be alchemically softened - - """ - angle_list = list() - force = reference_forces['HarmonicAngleForce'] - for angle_index in range(force.getNumAngles()): - [particle1, particle2, particle3, theta0, K] = force.getAngleParameters(angle_index) - if set([particle1, particle2, particle3]).intersection(alchemical_atoms): - angle_list.append(angle_index) - - return angle_list - - @staticmethod - def _build_alchemical_bond_list(alchemical_atoms, reference_forces, system): - """ - Build a list of bond indices that involve any alchemical atom, allowing a list of bonds to override. - - Parameters - ---------- - alchemical_atoms : set of int - The set of alchemically modified atoms. - reference_forces : dict str: force - A dictionary of cached forces in the system accessible by names. - system : openmm.System - The system (unused). - - Returns - ------- - bond_list : list of int - The list of bond indices that should be alchemically softened - - """ - bond_list = list() - force = reference_forces['HarmonicBondForce'] - for bond_index in range(force.getNumBonds()): - [particle1, particle2, r, K] = force.getBondParameters(bond_index) - if set([particle1, particle2]).intersection(alchemical_atoms): - bond_list.append(bond_index) - - return bond_list - - # ------------------------------------------------------------------------- - # Internal usage: Alchemical forces - # ------------------------------------------------------------------------- - - def _add_alchemical_forces(self, alchemical_system, alchemical_forces_by_lambda): - """Add the forces to the alchemical system and eventually split the force groups.""" - # OpenMM can have a maximum of 32 groups. - available_force_groups = set(range(32)) - - # Add non-alchemical groups. New forces will have force group 0, and we don't - # want to modify the force group of forces that have been copied from the reference. - non_alchemical_forces = alchemical_forces_by_lambda.pop('', []) - for non_alchemical_force in non_alchemical_forces: - alchemical_system.addForce(non_alchemical_force) - - # Find which force groups are still available for alchemical forces. - for force in alchemical_system.getForces(): - available_force_groups.discard(force.getForceGroup()) - - # Check if there are enough force groups to split alchemical forces. - if (self.split_alchemical_forces and - len(available_force_groups) < len(alchemical_forces_by_lambda)): - raise RuntimeError('There are not enough force groups to split alchemical forces.\n' - 'Consider merging some non-alchemical forces in a single group ' - 'or set split_alchemical_forces to False.') - - # Add the alchemical forces in a deterministic way (just to be safe). - for lambda_variable in sorted(alchemical_forces_by_lambda): - if self.split_alchemical_forces: - # Assign to these forces the smallest force group index available. - force_group = min(available_force_groups) - available_force_groups.remove(force_group) - for force in alchemical_forces_by_lambda[lambda_variable]: - if self.split_alchemical_forces: - force.setForceGroup(force_group) - alchemical_system.addForce(force) - - @staticmethod - def _are_straddling_noninteracting_regions(particles, alchemical_regions, alchemical_regions_interactions): - """Test if a set of particles are in two regions simultaneously and if these regions are interacting. - - Parameters - ---------- - particles: set - Set of particles to check if they are in two noninteracting alchemical regions. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the torsions to test. - alchemical_regions_interactions : Set[Tuple[int, int]], optional - Set of alchemical region index pairs for interacting regions. - By default, all alchemical regions interact only with the - non-alchemical environment. - - """ - for i, alchemical_region_A in enumerate(alchemical_regions): - if alchemical_region_A.alchemical_atoms.intersection(particles): - j = 0 - while j < i: - alchemical_region_B = alchemical_regions[j] - if alchemical_region_B.alchemical_atoms.intersection(particles): - if {i, j} in alchemical_regions_interactions: - return False - else: - return True - j += 1 - return False - - @classmethod - def _alchemically_modify_PeriodicTorsionForce(cls, reference_force, alchemical_regions, alchemical_regions_interactions): - """Create alchemically-modified version of PeriodicTorsionForce. - - Parameters - ---------- - reference_force : openmm.PeriodicTorsionForce - The reference PeriodicTorsionForce to be alchemically modify. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the torsions to - alchemically modify. - alchemical_regions_interactions : Set[Tuple[int, int]], optional - Set of alchemical region index pairs for interacting regions. - By default, all alchemical regions interact only with the - non-alchemical environment. - - Returns - ------- - force : openmm.PeriodicTorsionForce - The force responsible for the non-alchemical torsions. - custom_force : openmm.CustomTorsionForce - The force responsible for the alchemically-softened torsions. - This will not be present if there are not alchemical torsions - in alchemical_region. - - """ - alchemical_forces = {} - all_alchemical_torsions = set() - - # Don't create a force if there are no alchemical torsions. - for alchemical_region in alchemical_regions: - all_alchemical_torsions.update(alchemical_region.alchemical_torsions) - if len(all_alchemical_torsions) == 0: - return {'': [copy.deepcopy(reference_force)]} - - # Create PeriodicTorsionForce to handle unmodified torsions. - force = openmm.PeriodicTorsionForce() - force.setForceGroup(reference_force.getForceGroup()) - for torsion_index in range(reference_force.getNumTorsions()): - particle1, particle2, particle3, particle4, periodicity, phase, k = reference_force.getTorsionParameters( - torsion_index) - particles = set((particle1, particle2, particle3, particle4)) - - # We don't connect through a torsion two particles that belong - # to two different and noninteracting alchemical regions. - are_straddling = cls._are_straddling_noninteracting_regions( - particles, alchemical_regions, alchemical_regions_interactions) - if (torsion_index not in all_alchemical_torsions) and (not are_straddling): - force.addTorsion(particle1, particle2, particle3, particle4, periodicity, phase, k) - - # Update the returned value with the non-alchemical force. - alchemical_forces[''] = [force] - - # Create CustomTorsionForce to handle alchemically modified torsions. - for alchemical_region in alchemical_regions: - # This region may not have torsions to modify. - if len(alchemical_region.alchemical_torsions) == 0: - continue - - # Check if the lambda variable needs a suffix to identify the region. - lambda_variable_name = 'lambda_torsions' - if alchemical_region.name is not None: - lambda_variable_name += '_' + alchemical_region.name - - # Create CustomTorsionForce to handle alchemically modified torsions. - energy_function = f"{lambda_variable_name}*k*(1+cos(periodicity*theta-phase))" - custom_force = openmm.CustomTorsionForce(energy_function) - custom_force.addGlobalParameter(lambda_variable_name, 1.0) - custom_force.addPerTorsionParameter('periodicity') - custom_force.addPerTorsionParameter('phase') - custom_force.addPerTorsionParameter('k') - - # Process reference torsions. - for torsion_index in sorted(alchemical_region.alchemical_torsions): - # Retrieve parameters. - particle1, particle2, particle3, particle4, periodicity, phase, k = reference_force.getTorsionParameters(torsion_index) - # Create torsions. - custom_force.addTorsion(particle1, particle2, particle3, particle4, [periodicity, phase, k]) - - # Update the returned value with the alchemical force. - alchemical_forces.update({lambda_variable_name: [custom_force]}) - - return alchemical_forces - - @classmethod - def _alchemically_modify_HarmonicAngleForce(cls, reference_force, alchemical_regions, alchemical_regions_interactions): - """Create alchemically-modified version of HarmonicAngleForce - - Parameters - ---------- - reference_force : openmm.HarmonicAngleForce - The reference HarmonicAngleForce to be alchemically modify. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the angles to - alchemically modify. - alchemical_regions_interactions : Set[Tuple[int, int]], optional - Set of alchemical region index pairs for interacting regions. - By default, all alchemical regions interact only with the - non-alchemical environment. - - Returns - ------- - force : openmm.HarmonicAngleForce - The force responsible for the non-alchemical angles. - custom_force : openmm.CustomAngleForce - The force responsible for the alchemically-softened angles. - This will not be present if there are not alchemical angles - in alchemical_region. - - """ - alchemical_forces = {} - all_alchemical_angles = set() - # Don't create a force if there are no alchemical angles. - for alchemical_region in alchemical_regions: - all_alchemical_angles.update(alchemical_region.alchemical_angles) - if len(all_alchemical_angles) == 0: - return {'': [copy.deepcopy(reference_force)]} - - # Create standard HarmonicAngleForce to handle unmodified angles. - force = openmm.HarmonicAngleForce() - force.setForceGroup(reference_force.getForceGroup()) - for angle_index in range(reference_force.getNumAngles()): - [particle1, particle2, particle3, theta0, K] = reference_force.getAngleParameters(angle_index) - particles = set((particle1, particle2, particle3)) - - # We don't connect through an angle two particles that belong - # to two different and noninteracting alchemical regions. - are_straddling = cls._are_straddling_noninteracting_regions( - particles, alchemical_regions, alchemical_regions_interactions) - if (angle_index not in all_alchemical_angles) and (not are_straddling): - force.addAngle(particle1, particle2, particle3, theta0, K) - - # Update the returned value with the non-alchemical force. - alchemical_forces[''] = [force] - - # Create CustomAngleForce to handle alchemically modified angles. - for alchemical_region in alchemical_regions: - # This region may not have angles to modify. - if len(alchemical_region.alchemical_angles) == 0: - continue - - # Check if the lambda variable needs a suffix to identify the region. - lambda_variable_name = 'lambda_angles' - if alchemical_region.name is not None: - lambda_variable_name += '_' + alchemical_region.name - - # Create CustomAngleForce to handle alchemically modified angles. - energy_function = f"{lambda_variable_name}*(K/2)*(theta-theta0)^2;" - custom_force = openmm.CustomAngleForce(energy_function) - custom_force.addGlobalParameter(lambda_variable_name, 1.0) - custom_force.addPerAngleParameter('theta0') - custom_force.addPerAngleParameter('K') - - # Process reference angles. - for angle_index in sorted(alchemical_region.alchemical_angles): - [particle1, particle2, particle3, theta0, K] = reference_force.getAngleParameters(angle_index) - custom_force.addAngle(particle1, particle2, particle3, [theta0, K]) - - # Update the returned value with the alchemical force. - alchemical_forces.update({lambda_variable_name: [custom_force]}) - - return alchemical_forces - - @classmethod - def _alchemically_modify_HarmonicBondForce(cls, reference_force, alchemical_regions, alchemical_regions_interactions): - """Create alchemically-modified version of HarmonicBondForce - - Parameters - ---------- - reference_force : openmm.HarmonicBondForce - The reference HarmonicBondForce to be alchemically modify. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the bonds to - alchemically modify. - alchemical_regions_interactions : Set[Tuple[int, int]], optional - Set of alchemical region index pairs for interacting regions. - By default, all alchemical regions interact only with the - non-alchemical environment. - - Returns - ------- - force : openmm.HarmonicBondForce - The force responsible for the non-alchemical bonds. - custom_force : openmm.CustomBondForce - The force responsible for the alchemically-softened bonds. - This will not be present if there are not alchemical bonds - in alchemical_region. - - """ - alchemical_forces = {} - all_alchemical_bonds = set() - - # Don't create a force if there are no alchemical bonds. - for alchemical_region in alchemical_regions: - all_alchemical_bonds.update(alchemical_region.alchemical_bonds) - if len(all_alchemical_bonds) == 0: - return {'': [copy.deepcopy(reference_force)]} - - # Create standard HarmonicBondForce to handle unmodified bonds. - force = openmm.HarmonicBondForce() - force.setForceGroup(reference_force.getForceGroup()) - for bond_index in range(reference_force.getNumBonds()): - [particle1, particle2, theta0, K] = reference_force.getBondParameters(bond_index) - particles = set((particle1, particle2)) - - # We don't connect through a bond two particles that belong - # to two different and noninteracting alchemical regions. - are_straddling = cls._are_straddling_noninteracting_regions( - particles, alchemical_regions, alchemical_regions_interactions) - if (bond_index not in all_alchemical_bonds) and (not are_straddling): - force.addBond(particle1, particle2, theta0, K) - - # Update the returned value with the non-alchemical force. - alchemical_forces[''] = [force] - - for alchemical_region in alchemical_regions: - # This region may not have bonds to modify. - if len(alchemical_region.alchemical_bonds) == 0: - continue - - # Check if the lambda variable needs a suffix to identify the region. - lambda_variable_name = 'lambda_bonds' - if alchemical_region.name is not None: - lambda_variable_name += '_' + alchemical_region.name - - # Define force here so that it is over writen saving only one copy. - # Create CustomBondForce to handle alchemically modified bonds. - energy_function = f"{lambda_variable_name}*(K/2)*(r-r0)^2;" - custom_force = openmm.CustomBondForce(energy_function) - custom_force.addGlobalParameter(lambda_variable_name, 1.0) - custom_force.addPerBondParameter('r0') - custom_force.addPerBondParameter('K') - # Process reference bonds. - for bond_index in sorted(alchemical_region.alchemical_bonds): - [particle1, particle2, theta0, K] = reference_force.getBondParameters(bond_index) - custom_force.addBond(particle1, particle2, [theta0, K]) - - # Update the returned value with the alchemical force. - alchemical_forces.update({lambda_variable_name: [custom_force]}) - - return alchemical_forces - - def _get_sterics_energy_expressions(self, lambda_variable_suffixes): - """Return the energy expressions for sterics. - - Parameters - ---------- - lambda_variable_suffixes : List[str] - A list with suffixes for the global variable "lambda_sterics" that - will control the energy. If no suffix is necessary (i.e. there are - no multiple alchemical regions) just set lambda_variable_suffixes[0] = ''. - If the list has more than one element, the energy is controlled by - the multiplication of lambda_sterics_suffix1 * lambda_sterics_suffix2. - """ - - # Sterics mixing rules. - if lambda_variable_suffixes[0] == '': - lambda_variable_name = 'lambda_sterics' - else: - if len(lambda_variable_suffixes) > 1: - lambda_variable_name = 'lambda_sterics{0}*lambda_sterics{1}'.format( - lambda_variable_suffixes[0], lambda_variable_suffixes[1]) - else: - lambda_variable_name = 'lambda_sterics{}'.format(lambda_variable_suffixes[0]) - - sterics_mixing_rules = ('epsilon = sqrt(epsilon1*epsilon2);' # Mixing rule for epsilon. - 'sigma = 0.5*(sigma1 + sigma2);') # Mixing rule for sigma. - - # Soft-core Lennard-Jones. - exceptions_sterics_energy_expression = ('U_sterics;' - 'U_sterics = (({0})^softcore_a)*4*epsilon*x*(x-1.0);' - 'x = (sigma/reff_sterics)^6;' - # Effective softcore distance for sterics. - 'reff_sterics = sigma*((softcore_alpha*(1.0-({0}))^softcore_b + (r/sigma)^softcore_c))^(1/softcore_c);')\ - .format(lambda_variable_name) - # Define energy expression for electrostatics. - return sterics_mixing_rules, exceptions_sterics_energy_expression - - def _get_electrostatics_energy_expressions(self, reference_force, lambda_variable_suffixes): - """Return the energy expressions for electrostatics. - - This private function assumes self._alchemical_pme_treatment != 'exact' - as there's no electrostatics CustomNondondedForce in this case, and - lambda_electrostatics is modeled through an offset parameter in a - NonbondedForce. - - Parameters - ---------- - lambda_variable_suffixes : List[str] - A list with suffixes for the global variable "lambda_electrostatics" that - will control the energy. If no suffix is necessary (i.e. there are - no multiple alchemical regions) just set lambda_variable_suffixes[0] = ''. - If the list has more than one element, the energy is controlled by - the multiplication of lambda_electrostatics_suffix1 * lambda_electrostatics_suffix2. - """ - if lambda_variable_suffixes[0] == '': - lambda_variable_name = 'lambda_electrostatics' - else: - if len(lambda_variable_suffixes) > 1: - lambda_variable_name = 'lambda_electrostatics{0}*lambda_electrostatics{1}'.format( - lambda_variable_suffixes[0], lambda_variable_suffixes[1]) - else: - lambda_variable_name = 'lambda_electrostatics{}'.format(lambda_variable_suffixes[0]) - - # The final expression will be prefix + method + suffix. - electrostatics_prefix = ('U_electrostatics;' - 'U_electrostatics=(({})^softcore_d)*ONE_4PI_EPS0*chargeprod').format(lambda_variable_name) - - # Effective softcore distance for electrostatics (common to all methods). - electrostatics_suffix = ('reff_electrostatics = sigma*((softcore_beta*(1.0-({0}))^softcore_e + (r/sigma)^softcore_f))^(1/softcore_f);' - 'ONE_4PI_EPS0 = {1};').format(lambda_variable_name, ONE_4PI_EPS0) # Already in OpenMM units. - - # Define mixing rules. - electrostatics_mixing_rules = ('chargeprod = charge1*charge2;' # Mixing rule for charges. - 'sigma = 0.5*(sigma1 + sigma2);') # Mixing rule for sigma. - - # Standard Coulomb expression with softened core. This is used - # - When the nonbonded method of the reference force is NoCutoff. - # - When alchemical_pme_treatment is set to 'coulomb'. - # - With 1-4 exceptions, unless self.consistent_exceptions is True. - coulomb_expression = '/reff_electrostatics;' - - # Select electrostatics functional form based on nonbonded method. - nonbonded_method = reference_force.getNonbondedMethod() - - # Soft-core Coulomb. - if nonbonded_method in [openmm.NonbondedForce.NoCutoff]: - electrostatics_method_expression = coulomb_expression - # Reaction-field electrostatics. - elif nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic, openmm.NonbondedForce.CutoffNonPeriodic]: - electrostatics_method_expression = self._get_reaction_field_unique_expression(reference_force) - # PME electrostatics. - elif nonbonded_method in [openmm.NonbondedForce.PME, openmm.NonbondedForce.Ewald]: - # Ewald direct-space electrostatics. - if self.alchemical_pme_treatment == 'direct-space': - electrostatics_method_expression = self._get_pme_direct_space_unique_expression(reference_force) - # Use switched standard Coulomb potential, following MTS scheme described in - # http://dx.doi.org/10.1063/1.1385159 - elif self.alchemical_pme_treatment == 'coulomb': - electrostatics_method_expression = coulomb_expression - else: - raise ValueError("Unknown alchemical_pme_treatment scheme '{}'".format(self.alchemical_pme_treatment)) - else: - raise ValueError("Nonbonded method {} not supported yet.".format(nonbonded_method)) - - # Define energy expression for 1,4 electrostatic exceptions. - exceptions_electrostatics_energy_expression = electrostatics_prefix - if self.consistent_exceptions: - exceptions_electrostatics_energy_expression += electrostatics_method_expression - else: - exceptions_electrostatics_energy_expression += coulomb_expression - exceptions_electrostatics_energy_expression += electrostatics_suffix - - # Define energy expression for electrostatics. - electrostatics_energy_expression = (electrostatics_prefix + electrostatics_method_expression + - electrostatics_suffix + electrostatics_mixing_rules) - - return electrostatics_energy_expression, exceptions_electrostatics_energy_expression - - def _get_reaction_field_unique_expression(self, reference_force): - """Unique part of the expression for reaction-field electrostatics. - - Parameters - ---------- - reference_force : openmm.NonbondedForce - The reference force including the reaction-field parameters. - - Returns - ------- - rf_expression : str - The unique expression for reaction-field electrostatics. - - See Also - -------- - _get_nonbonded_energy_expressions - """ - epsilon_solvent = reference_force.getReactionFieldDielectric() - r_cutoff = reference_force.getCutoffDistance() - - # Determine reaction fields parameters. - k_rf = r_cutoff**(-3) * ((epsilon_solvent - 1) / (2*epsilon_solvent + 1)) - if self.alchemical_rf_treatment == 'switched': - c_rf = 0.0 / unit.nanometers - elif self.alchemical_rf_treatment == 'shifted': - # WARNING: Setting c_rf != 0 can cause large errors in DeltaG for hydration free energies - c_rf = r_cutoff**(-1) * ((3*epsilon_solvent) / (2*epsilon_solvent + 1)) - else: - raise ValueError("Unknown alchemical_rf_treatment scheme '{}'".format(self.alchemical_rf_treatment)) - - k_rf = k_rf.value_in_unit_system(unit.md_unit_system) - c_rf = c_rf.value_in_unit_system(unit.md_unit_system) - rf_expression = ('*(reff_electrostatics^(-1) + k_rf*reff_electrostatics^2 - c_rf);' - 'k_rf = {k_rf};' - 'c_rf = {c_rf};').format(k_rf=k_rf, c_rf=c_rf) - return rf_expression - - def _get_pme_direct_space_unique_expression(self, reference_force): - """Unique part of the expression for Ewald direct-space electrostatics. - - Parameters - ---------- - reference_force : openmm.NonbondedForce - The reference force including the Ewald parameters. - - Returns - ------- - rf_expression : str - The unique expression for Ewald direct-space electrostatics. - - See Also - -------- - _get_nonbonded_energy_expressions - """ - # Determine PME parameters. - [alpha_ewald, nx, ny, nz] = reference_force.getPMEParameters() - if (alpha_ewald/alpha_ewald.unit) == 0.0: - # If alpha is 0.0, alpha_ewald is computed by OpenMM from from the error tolerance. - tol = reference_force.getEwaldErrorTolerance() - alpha_ewald = (1.0/reference_force.getCutoffDistance()) * np.sqrt(-np.log(2.0*tol)) - - alpha_ewald = alpha_ewald.value_in_unit_system(unit.md_unit_system) - pme_expression = ("*erfc(alpha_ewald*reff_electrostatics)/reff_electrostatics;" - "alpha_ewald = {};").format(alpha_ewald) - return pme_expression - - def _alchemically_modify_NonbondedForce(self, reference_force, alchemical_regions, alchemical_regions_interactions): - """Create alchemically-modified version of NonbondedForce. - - Parameters - ---------- - reference_force : openmm.NonbondedForce - The reference NonbondedForce to be alchemically modify. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the atoms to - alchemically modify. - alchemical_regions_interactions : Set[Tuple[int, int]], optional - Set of alchemical region index pairs for interacting regions. - By default, all alchemical regions interact only with the - non-alchemical environment. - - Returns - ------- - nonbonded_force : openmm.NonbondedForce - The force responsible for interactions and exceptions of non-alchemical atoms. - aa_sterics_custom_nonbonded_force : openmm.CustomNonbondedForce - The force responsible for sterics interactions of alchemical/alchemical atoms. - aa_electrostatics_custom_nonbonded_force : openmm.CustomNonbondedForce - The force responsible for electrostatics interactions of alchemical/alchemical - atoms. - na_sterics_custom_nonbonded_force : openmm.CustomNonbondedForce - The force responsible for sterics interactions of non-alchemical/alchemical atoms. - na_electrostatics_custom_nonbonded_force : openmm.CustomNonbondedForce - The force responsible for electrostatics interactions of non-alchemical/alchemical - atoms. - aa_sterics_custom_bond_force : openmm.CustomBondForce - The force responsible for sterics exceptions of alchemical/alchemical atoms. - aa_electrostatics_custom_bond_force : openmm.CustomBondForce - The force responsible for electrostatics exceptions of alchemical/alchemical - atoms. - na_sterics_custom_bond_force : openmm.CustomBondForce - The force responsible for sterics exceptions of non-alchemical/alchemical atoms. - na_electrostatics_custom_bond_force : openmm.CustomBondForce - The force responsible for electrostatics exceptions of non-alchemical/alchemical - atoms. - - References - ---------- - [1] Pham TT and Shirts MR. Identifying low variance pathways for free - energy calculations of molecular transformations in solution phase. - JCP 135:034114, 2011. http://dx.doi.org/10.1063/1.3607597 - - """ - # TODO Change softcore_beta to a dimensionless scalar to multiply some intrinsic length-scale, like Lennard-Jones alpha. - # TODO Try using a single, common "reff" effective softcore distance for both Lennard-Jones and Coulomb. - - forces_by_lambda = {} - all_alchemical_atoms = set() - - # Don't create a force if there are no alchemical atoms. - for alchemical_region in alchemical_regions: - if not len(alchemical_region.alchemical_atoms) == 0: - all_alchemical_atoms.update(alchemical_region.alchemical_atoms) - - # Don't create a force if there are no alchemical atoms. - if len(all_alchemical_atoms) == 0: - return {'': [copy.deepcopy(reference_force)]} - - # Create a set of all the non-alchemical atoms only. - all_atomset = set(range(reference_force.getNumParticles())) - nonalchemical_atomset = all_atomset.difference(all_alchemical_atoms) - - # ------------------------------------------------------------- - # Perform tasks that do not need to be repeated for all regions. - # ------------------------------------------------------------- - - # Define energy expression for electrostatics based on nonbonded method. - nonbonded_method = reference_force.getNonbondedMethod() - is_ewald_method = nonbonded_method in [openmm.NonbondedForce.Ewald, - openmm.NonbondedForce.PME] - is_rf_method = nonbonded_method in [openmm.NonbondedForce.CutoffPeriodic, - openmm.NonbondedForce.CutoffNonPeriodic] - is_periodic_method = is_ewald_method or nonbonded_method == openmm.NonbondedForce.CutoffPeriodic - use_exact_pme_treatment = is_ewald_method and self.alchemical_pme_treatment == 'exact' - - # Warn about reaction field. - if is_rf_method: - logger.warning('Reaction field support is still experimental. For free energy ' - 'calculations in explicit solvent, we suggest using PME for now.') - - # Check that PME treatment is supported with the region's parameters. - if use_exact_pme_treatment: - for alchemical_region in alchemical_regions: - err_msg = ' not supported with exact treatment of Ewald electrostatics.' - if not alchemical_region.annihilate_electrostatics: - raise ValueError('Decoupled electrostatics is' + err_msg) - if self.consistent_exceptions: - raise ValueError('Consistent exceptions are' + err_msg) - if (alchemical_region.softcore_beta, alchemical_region.softcore_d, alchemical_region.softcore_e) != (0, 1, 1): - raise ValueError('Softcore electrostatics is' + err_msg) - - # Create a copy of the NonbondedForce to handle particle interactions and - # 1,4 exceptions between non-alchemical/non-alchemical atoms (nn). - nonbonded_force = copy.deepcopy(reference_force) - - # Fix any issues in reference force with Lennard-Jones sigma = 0 (epsilon = 0), - # which should have sigma > 0. - for particle_index in range(reference_force.getNumParticles()): - # Retrieve parameters. - [charge, sigma, epsilon] = reference_force.getParticleParameters(particle_index) - # Check particle sigma is not zero. - if sigma == 0.0 * unit.angstrom: - warning_msg = 'particle %d has Lennard-Jones sigma = 0 (charge=%s, sigma=%s, epsilon=%s); setting sigma=1A' - logger.warning(warning_msg % (particle_index, str(charge), str(sigma), str(epsilon))) - sigma = 1.0 * unit.angstrom - # Fix it. - nonbonded_force.setParticleParameters(particle_index, charge, sigma, epsilon) - - # Same for the exceptions. - for exception_index in range(reference_force.getNumExceptions()): - # Retrieve parameters. - [iatom, jatom, chargeprod, sigma, epsilon] = reference_force.getExceptionParameters(exception_index) - # Check particle sigma is not zero. - if sigma == 0.0 * unit.angstrom: - warning_msg = 'exception %d has Lennard-Jones sigma = 0 (iatom=%d, jatom=%d, chargeprod=%s, sigma=%s, epsilon=%s); setting sigma=1A' - logger.warning(warning_msg % (exception_index, iatom, jatom, str(chargeprod), str(sigma), str(epsilon))) - sigma = 1.0 * unit.angstrom - # Fix it. - nonbonded_force.setExceptionParameters(exception_index, iatom, jatom, chargeprod, sigma, epsilon) - - if use_exact_pme_treatment: - # Exclude noninteracting alchemical regions from seeing each other in the nonbonded - for x, y in itertools.combinations(range(len(alchemical_regions)), 2): - if (x, y) not in alchemical_regions_interactions: - for atom1 in alchemical_regions[x].alchemical_atoms: - for atom2 in alchemical_regions[y].alchemical_atoms: - nonbonded_force.addException(atom1, atom2, 0.0, 1.0, 0.0, True) - else: - region_names = (alchemical_regions[x].name, alchemical_regions[y].name) - logger.debug(f'Adding a exact PME electrostatic interaction group between groups {region_names}.') - del region_names - - # With exact PME treatment, particle electrostatics is handled through offset parameters. - for alchemical_region in alchemical_regions: - if alchemical_region.name is None: - nonbonded_force.addGlobalParameter('lambda_electrostatics', 1.0) - else: - nonbonded_force.addGlobalParameter(f'lambda_electrostatics_{alchemical_region.name}', 1.0) - - # Make of list of all single and double permutations of alchemical regions. - single_regions = [[alchemical_region] for alchemical_region in alchemical_regions] - if len(alchemical_regions_interactions) == 0: - pair_regions = [] - else: - # Only generate pairs of alchemical regions specified by alchemical_regions_interactions. - pair_regions = [[alchemical_regions[x[0]], alchemical_regions[x[1]]] for x in - alchemical_regions_interactions] - - # Iterate over all single and double permutations of alchemical regions to build all interactions. - for alchemical_regions_pairs in single_regions+pair_regions: - # Make a list of region names for the alchemical regions interactions which are being built. - lambda_var_suffixes = [] - for alchemical_region in alchemical_regions_pairs: - if alchemical_region.name is None: - lambda_var_suffixes.append('') - else: - lambda_var_suffixes.append('_' + alchemical_region.name) - - # -------------------------------------------------- - # Determine energy expression for all custom forces - # -------------------------------------------------- - - # Get steric energy expressions. - sterics_mixing_rules, exceptions_sterics_energy_expression = self._get_sterics_energy_expressions(lambda_var_suffixes) - - # Define energy expression for sterics. - sterics_energy_expression = exceptions_sterics_energy_expression + sterics_mixing_rules - - if not use_exact_pme_treatment: - # There's no CustomNonbondedForce that models electrostatics if we use exact - # PME treatment. Electrostatics is modeled through offset parameters. - energy_expressions = self._get_electrostatics_energy_expressions(reference_force, lambda_var_suffixes) - (electrostatics_energy_expression, - exceptions_electrostatics_energy_expression) = energy_expressions # Unpack tuple. - - # ------------------------------------------------------------ - # Create and configure all forces to add to alchemical system - # ------------------------------------------------------------ - - # Interactions and exceptions will be distributed according to the following table. - - # -------------------------------------------------------------------------------------------------- - # FORCE | INTERACTION GROUP | - # -------------------------------------------------------------------------------------------------- - # nonbonded_force (unmodified) | all interactions nonalchemical/nonalchemical | - # | all exceptions nonalchemical/nonalchemical | - # -------------------------------------------------------------------------------------------------- - # aa_sterics_custom_nonbonded_force | sterics interactions alchemical/alchemical | - # -------------------------------------------------------------------------------------------------- - # aa_electrostatics_custom_nonbonded_force | electrostatics interactions alchemical/alchemical | - # | (only without exact PME treatment) | - # -------------------------------------------------------------------------------------------------- - # na_sterics_custom_nonbonded_force | sterics interactions non-alchemical/alchemical | - # -------------------------------------------------------------------------------------------------- - # na_electrostatics_custom_nonbonded_force | electrostatics interactions non-alchemical/alchemical | - # | (only without exact PME treatment) | - # -------------------------------------------------------------------------------------------------- - # aa_sterics_custom_bond_force | sterics exceptions alchemical/alchemical | - # -------------------------------------------------------------------------------------------------- - # aa_electrostatics_custom_bond_force | electrostatics exceptions alchemical/alchemical | - # | (only without exact PME treatment) | - # -------------------------------------------------------------------------------------------------- - # na_sterics_custom_bond_force | sterics exceptions non-alchemical/alchemical | - # -------------------------------------------------------------------------------------------------- - # na_electrostatics_custom_bond_force | electrostatics exceptions non-alchemical/alchemical | - # | (only without exact PME treatment) | - # -------------------------------------------------------------------------------------------------- - - def create_force(force_cls, energy_expression, lambda_variable_name, lambda_var_suffixes, is_lambda_controlled): - """Shortcut to create a lambda-controlled custom forces.""" - if is_lambda_controlled: - force = force_cls(energy_expression) - for suffix in lambda_var_suffixes: - name = (lambda_variable_name + suffix) - force.addGlobalParameter(name, 1.0) - else: # fix lambda variable to 1.0 - for suffix in lambda_var_suffixes: - name = (lambda_variable_name + suffix) - energy_expression = energy_expression + name + '=1.0;' - force = force_cls(energy_expression) - return force - - # Create CustomNonbondedForces to handle sterics particle interactions between - # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda - # to 1.0 for decoupled interactions in alchemical/alchemical force. - if len(lambda_var_suffixes) > 1: - aa_sterics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, sterics_energy_expression, - 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) - all_sterics_custom_nonbonded_forces = [aa_sterics_custom_nonbonded_force] - else: - na_sterics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, sterics_energy_expression, - 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) - aa_sterics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, sterics_energy_expression, - 'lambda_sterics', lambda_var_suffixes, alchemical_region.annihilate_sterics) - all_sterics_custom_nonbonded_forces = [na_sterics_custom_nonbonded_force, aa_sterics_custom_nonbonded_force] - - # Add parameters and configure CustomNonbondedForces to match reference force. - for force in all_sterics_custom_nonbonded_forces: - force.addPerParticleParameter("sigma") # Lennard-Jones sigma - force.addPerParticleParameter("epsilon") # Lennard-Jones epsilon - force.setUseSwitchingFunction(nonbonded_force.getUseSwitchingFunction()) - force.setCutoffDistance(nonbonded_force.getCutoffDistance()) - force.setSwitchingDistance(nonbonded_force.getSwitchingDistance()) - if self.disable_alchemical_dispersion_correction: - force.setUseLongRangeCorrection(False) - else: - force.setUseLongRangeCorrection(nonbonded_force.getUseDispersionCorrection()) - - if is_periodic_method: - force.setNonbondedMethod(openmm.CustomNonbondedForce.CutoffPeriodic) - else: - force.setNonbondedMethod(nonbonded_force.getNonbondedMethod()) - - if use_exact_pme_treatment: - #electrostatics are handled by offset - all_electrostatics_custom_nonbonded_forces = [] - else: - # Create CustomNonbondedForces to handle electrostatics particle interactions between - # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda - # to 1.0 for decoupled interactions in alchemical/alchemical force. - if len(lambda_var_suffixes) > 1: - aa_electrostatics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, electrostatics_energy_expression, - 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) - all_electrostatics_custom_nonbonded_forces = [aa_electrostatics_custom_nonbonded_force] - else: - na_electrostatics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, electrostatics_energy_expression, - 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) - aa_electrostatics_custom_nonbonded_force = create_force(openmm.CustomNonbondedForce, electrostatics_energy_expression, - 'lambda_electrostatics', lambda_var_suffixes, alchemical_region.annihilate_electrostatics) - all_electrostatics_custom_nonbonded_forces = [na_electrostatics_custom_nonbonded_force, - aa_electrostatics_custom_nonbonded_force] - - # Common parameters and configuration for electrostatics CustomNonbondedForces. - for force in all_electrostatics_custom_nonbonded_forces: - force.addPerParticleParameter("charge") # partial charge - force.addPerParticleParameter("sigma") # Lennard-Jones sigma - if ((is_ewald_method and self.alchemical_pme_treatment == 'coulomb') or - (is_rf_method and self.alchemical_rf_treatment == 'switched')): - # Use switching function for alchemical electrostatics to ensure force continuity at cutoff. - force.setUseSwitchingFunction(True) - else: - force.setUseSwitchingFunction(False) - force.setSwitchingDistance(nonbonded_force.getCutoffDistance() - self.switch_width) - force.setCutoffDistance(nonbonded_force.getCutoffDistance()) - force.setUseLongRangeCorrection(False) # long-range dispersion correction is meaningless for electrostatics - if is_periodic_method: - force.setNonbondedMethod(openmm.CustomNonbondedForce.CutoffPeriodic) - else: - force.setNonbondedMethod(nonbonded_force.getNonbondedMethod()) - - # Create CustomBondForces to handle sterics 1,4 exceptions interactions between - # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda - # to 1.0 for decoupled interactions in alchemical/alchemical force. - if len(lambda_var_suffixes) > 1: - aa_sterics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_sterics_energy_expression, - 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) - all_sterics_custom_bond_forces = [aa_sterics_custom_bond_force] - else: - na_sterics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_sterics_energy_expression, - 'lambda_sterics', lambda_var_suffixes, is_lambda_controlled=True) - aa_sterics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_sterics_energy_expression, - 'lambda_sterics', lambda_var_suffixes, alchemical_region.annihilate_sterics) - all_sterics_custom_bond_forces = [na_sterics_custom_bond_force, aa_sterics_custom_bond_force] - - for force in all_sterics_custom_bond_forces: - force.addPerBondParameter("sigma") # Lennard-Jones effective sigma - force.addPerBondParameter("epsilon") # Lennard-Jones effective epsilon - - # With exact PME treatment, exception electrostatics is handled through offset parameters. - if use_exact_pme_treatment: - all_electrostatics_custom_bond_forces = [] - else: - # Create CustomBondForces to handle electrostatics 1,4 exceptions interactions between - # non-alchemical/alchemical atoms (na) and alchemical/alchemical atoms (aa). Fix lambda - # to 1.0 for decoupled interactions in alchemical/alchemical force. - if len(lambda_var_suffixes) > 1: - aa_electrostatics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_electrostatics_energy_expression, - 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) - all_electrostatics_custom_bond_forces = [aa_electrostatics_custom_bond_force] - else: - na_electrostatics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_electrostatics_energy_expression, - 'lambda_electrostatics', lambda_var_suffixes, is_lambda_controlled=True) - aa_electrostatics_custom_bond_force = create_force(openmm.CustomBondForce, exceptions_electrostatics_energy_expression, - 'lambda_electrostatics', lambda_var_suffixes, alchemical_region.annihilate_electrostatics) - all_electrostatics_custom_bond_forces = [na_electrostatics_custom_bond_force, aa_electrostatics_custom_bond_force] - # Create CustomBondForce to handle exceptions for electrostatics - for force in all_electrostatics_custom_bond_forces: - force.addPerBondParameter("chargeprod") # charge product - force.addPerBondParameter("sigma") # Lennard-Jones effective sigma - - # ------------------------------------------------------------------------------- - # Distribute particle interactions contributions in appropriate nonbonded forces - # ------------------------------------------------------------------------------- - - # Create atom groups. - alchemical_atomsets = [region.alchemical_atoms for region in alchemical_regions_pairs] - - # Copy NonbondedForce particle terms for alchemically-modified particles - # to CustomNonbondedForces, and/or add the charge offsets for exact PME. - # On CUDA, for efficiency reasons, all nonbonded forces (custom and not) - # must have the same particles. - for particle_index in range(nonbonded_force.getNumParticles()): - # Retrieve nonbonded parameters. - [charge, sigma, epsilon] = nonbonded_force.getParticleParameters(particle_index) - # Set sterics parameters in CustomNonbondedForces. - for force in all_sterics_custom_nonbonded_forces: - force.addParticle([sigma, epsilon]) - # Set electrostatics parameters in CustomNonbondedForces. - for force in all_electrostatics_custom_nonbonded_forces: - force.addParticle([charge, sigma]) - # Set offset parameters in NonbondedForce. - if use_exact_pme_treatment and particle_index in alchemical_atomsets[0] and len(lambda_var_suffixes) == 1: - nonbonded_force.addParticleParameterOffset('lambda_electrostatics{}'.format(lambda_var_suffixes[0]), - particle_index, charge, 0.0, 0.0) - - # Turn off interactions contribution from alchemically-modified particles in unmodified - # NonbondedForce that will be handled by all other forces - for particle_index in range(nonbonded_force.getNumParticles()): - # Retrieve parameters. - [charge, sigma, epsilon] = nonbonded_force.getParticleParameters(particle_index) - # Even with exact treatment of the PME electrostatics, we turn off - # the NonbondedForce charge which is modeled by the offset parameter. - if particle_index in alchemical_atomsets[0]: - nonbonded_force.setParticleParameters(particle_index, abs(0.0*charge), sigma, abs(0*epsilon)) - # Restrict interaction evaluation of CustomNonbondedForces to their respective atom groups. - # Sterics - if len(lambda_var_suffixes) == 1: - logger.debug('Adding steric interaction groups between {} and the environment.'.format(lambda_var_suffixes[0])) - na_sterics_custom_nonbonded_force.addInteractionGroup(nonalchemical_atomset, alchemical_atomsets[0]) - - logger.debug('Adding a steric interaction group between group {0} and {1}.'.format(lambda_var_suffixes[0], - lambda_var_suffixes[-1])) - aa_sterics_custom_nonbonded_force.addInteractionGroup(alchemical_atomsets[0], alchemical_atomsets[-1]) - - # Electrostatics - if not use_exact_pme_treatment: - if len(lambda_var_suffixes) == 1: - logger.debug('Adding electrostatic interaction groups between {} and the environment.'.format(lambda_var_suffixes[0])) - na_electrostatics_custom_nonbonded_force.addInteractionGroup(nonalchemical_atomset, alchemical_atomsets[0]) - - logger.debug('Adding a electrostatic interaction group between group {0} and {1}.'.format(lambda_var_suffixes[0], - lambda_var_suffixes[-1])) - aa_electrostatics_custom_nonbonded_force.addInteractionGroup(alchemical_atomsets[0], alchemical_atomsets[-1]) - - else: - # Using the nonbonded force to handle electrostatics - # and the "interaction groups" in the nonbonded have already been handled by exclusions. - pass - - # --------------------------------------------------------------- - # Distribute exceptions contributions in appropriate bond forces - # --------------------------------------------------------------- - all_custom_nonbonded_forces = all_sterics_custom_nonbonded_forces + all_electrostatics_custom_nonbonded_forces - # Move all NonbondedForce exception terms for alchemically-modified particles to CustomBondForces. - for exception_index in range(nonbonded_force.getNumExceptions()): - # Retrieve parameters. - iatom, jatom, chargeprod, sigma, epsilon = nonbonded_force.getExceptionParameters(exception_index) - - # Exclude this atom pair in CustomNonbondedForces. All nonbonded forces - # must have the same number of exceptions/exclusions on CUDA platform. - for force in all_custom_nonbonded_forces: - force.addExclusion(iatom, jatom) - - # Check if this is an exception or an exclusion - is_exception_epsilon = abs(epsilon.value_in_unit_system(unit.md_unit_system)) > 0.0 - is_exception_chargeprod = abs(chargeprod.value_in_unit_system(unit.md_unit_system)) > 0.0 - - # Check how many alchemical atoms we have in the exception. - if len(lambda_var_suffixes) > 1: - # Pair of interacting alchemical regions, therefore they are both alchemical or neither alchemical. - both_alchemical = ((iatom in alchemical_atomsets[0] and jatom in alchemical_atomsets[1]) or - (jatom in alchemical_atomsets[0] and iatom in alchemical_atomsets[1])) - only_one_alchemical = False - #The condition of at_least_one_alchemical is treated only once per single - # region so we don't repeat it when dealing with pairs of interacting regions. - at_least_one_alchemical = False - - if use_exact_pme_treatment and both_alchemical and is_exception_chargeprod: - # Exceptions here should be scaled by lam0*lam1. - # This can be implemented in the future using a CustomBondForce. - raise ValueError('Cannot have exception that straddles two alchemical regions') - - else: - # Single alchemical region. - both_alchemical = iatom in alchemical_atomsets[0] and jatom in alchemical_atomsets[0] - at_least_one_alchemical = iatom in alchemical_atomsets[0] or jatom in alchemical_atomsets[0] - only_one_alchemical = at_least_one_alchemical and not both_alchemical - - # If this is an electrostatic exception and we're using exact PME, - # we just have to add the exception offset to the NonbondedForce. - if use_exact_pme_treatment and at_least_one_alchemical and is_exception_chargeprod: - nonbonded_force.addExceptionParameterOffset('lambda_electrostatics{}'.format(lambda_var_suffixes[0]), - exception_index, chargeprod, 0.0, 0.0) - - # If exception (and not exclusion), add special CustomBondForce terms to - # handle alchemically-modified Lennard-Jones and electrostatics exceptions - if both_alchemical: - if is_exception_epsilon: - aa_sterics_custom_bond_force.addBond(iatom, jatom, [sigma, epsilon]) - if is_exception_chargeprod and not use_exact_pme_treatment: - aa_electrostatics_custom_bond_force.addBond(iatom, jatom, [chargeprod, sigma]) - - # When this is a single region we model the exception between alchemical - # and non-alchemical particles using a single custom bond. - elif only_one_alchemical: - if is_exception_epsilon: - na_sterics_custom_bond_force.addBond(iatom, jatom, [sigma, epsilon]) - if is_exception_chargeprod and not use_exact_pme_treatment: - na_electrostatics_custom_bond_force.addBond(iatom, jatom, [chargeprod, sigma]) - # else: both particles are non-alchemical, leave them in the unmodified NonbondedForce - - # Turn off all exception contributions from alchemical atoms in the NonbondedForce - # modelling non-alchemical atoms only. We need to do it only once per single - # region so we don't repeat it when dealing with pairs of interacting regions. - if at_least_one_alchemical: - nonbonded_force.setExceptionParameters(exception_index, iatom, jatom, - abs(0.0*chargeprod), sigma, abs(0.0*epsilon)) - # Add global parameters to forces. - def add_global_parameters(force): - force.addGlobalParameter('softcore_alpha', alchemical_region.softcore_alpha) - force.addGlobalParameter('softcore_beta', alchemical_region.softcore_beta) - force.addGlobalParameter('softcore_a', alchemical_region.softcore_a) - force.addGlobalParameter('softcore_b', alchemical_region.softcore_b) - force.addGlobalParameter('softcore_c', alchemical_region.softcore_c) - force.addGlobalParameter('softcore_d', alchemical_region.softcore_d) - force.addGlobalParameter('softcore_e', alchemical_region.softcore_e) - force.addGlobalParameter('softcore_f', alchemical_region.softcore_f) - - all_custom_forces = (all_custom_nonbonded_forces + - all_sterics_custom_bond_forces + - all_electrostatics_custom_bond_forces) - for force in all_custom_forces: - add_global_parameters(force) - # With exact treatment of PME electrostatics, the NonbondedForce - # is affected by lambda electrostatics as well. - if 'lambda_sterics{}'.format(lambda_var_suffixes[0]) in forces_by_lambda: - forces_by_lambda['lambda_electrostatics{}'.format(lambda_var_suffixes[0])].extend(all_electrostatics_custom_nonbonded_forces + all_electrostatics_custom_bond_forces) - forces_by_lambda['lambda_sterics{}'.format(lambda_var_suffixes[0])].extend(all_sterics_custom_nonbonded_forces + all_sterics_custom_bond_forces) - else: - forces_by_lambda['lambda_electrostatics{}'.format(lambda_var_suffixes[0])] = all_electrostatics_custom_nonbonded_forces + all_electrostatics_custom_bond_forces - forces_by_lambda['lambda_sterics{}'.format(lambda_var_suffixes[0])] = all_sterics_custom_nonbonded_forces + all_sterics_custom_bond_forces - # CAVE: I modified this, pushed this into the inner loop, was one level up - if use_exact_pme_treatment: - forces_by_lambda['lambda_electrostatics{}'.format(lambda_var_suffixes[0])].append(nonbonded_force) - else: - forces_by_lambda[''] = [nonbonded_force] - return forces_by_lambda - - def _alchemically_modify_CustomNonbondedForce(self, reference_force, _, __): - """NYI: Create alchemically-modified version of a CustomNonbondedForce generated from the LennardJonesGenerator. - - When working, this will correctly modify the CustomNonbondedForce made by the OpenMM forcefield.py file's - "LennardJonesGenerator" function which creates tabulated potentials for the C6 and C12 interactions - (i.e. Acoef = 4es^12 and Bcoef = 4es^6) - - However, this has not been implemented as there are some technical problems which need to be resolved - both in this code (flow of converting "native" nonbonded interactions from multiple forces (NB + CustomNB) - into alchemical forces) and in the science (How do you softcore potential a "A/r^12 - B/r^6" form where A and B - are tabulated?). - - - See https://github.com/choderalab/openmmtools/issues/510 for more details on this problem. - - """ - # See https://github.com/openmm/openmm/blob/be19e0222ddf66f612016a3c1f687161a53c2396/wrappers/python/openmm/app/forcefield.py#L2548-L2572 - lj_generator_expression = 'acoef(type1, type2)/r^12 - bcoef(type1, type2)/r^6' - reference_energy_expression = reference_force.getEnergyFunction() - if lj_generator_expression in reference_energy_expression: - error_msg = (f"Unsupported Native Lennard Jones representation!\n" - f"There is a CustomNonbondedForce which contains the energy function:\n" - f"\t{lj_generator_expression}\n" - f"Which is likely from the OpenMM forcefield.py file for Tabulated Lennard Jones functions" - f"such as the CHARMM36 FF. Supporting this type of LJ representation is not yet implemented.\n" - f"See https://github.com/choderalab/openmmtools/issues/510 for more details." - ) - raise NotImplementedError(error_msg) - # Don't create a force if you made it here (remove when implemented) - return {'': [copy.deepcopy(reference_force)]} - - def _alchemically_modify_AmoebaMultipoleForce(self, reference_force, alchemical_region, _): - if len(alchemical_region) > 1: - raise NotImplementedError("Multiple regions does not work with AmoebaMultipoleForce") - else: - alchemical_region = alchemical_region[0] - raise Exception("Not implemented; needs CustomMultipleForce") - - def _alchemically_modify_AmoebaVdwForce(self, reference_force, alchemical_region, _): - """Create alchemically-modified version of AmoebaVdwForce. - - Not implemented. - - TODO - ---- - * Supported periodic boundary conditions need to be handled correctly. - * Exceptions/exclusions need to be dealt with. - - """ - # This feature is incompletely implemented, so raise an exception. - if len(alchemical_region) > 1: - raise NotImplementedError("Multiple regions does not work with AmoebaVdwForce") - else: - alchemical_region = alchemical_region[0] - raise NotImplementedError('Alchemical modification of Amoeba VdW Forces is not supported.') - - # Softcore Halgren potential from Eq. 3 of - # Shi, Y., Jiao, D., Schnieders, M.J., and Ren, P. (2009). Trypsin-ligand binding free - # energy calculation with AMOEBA. Conf Proc IEEE Eng Med Biol Soc 2009, 2328-2331. - energy_expression = 'lambda^5 * epsilon * (1.07^7 / (0.7*(1-lambda)^2+(rho+0.07)^7)) * (1.12 / (0.7*(1-lambda)^2 + rho^7 + 0.12) - 2);' - energy_expression += 'epsilon = 4*epsilon1*epsilon2 / (sqrt(epsilon1) + sqrt(epsilon2))^2;' - energy_expression += 'rho = r / R0;' - energy_expression += 'R0 = (R01^3 + R02^3) / (R01^2 + R02^2);' - energy_expression += 'lambda = vdw_lambda * (ligand1*(1-ligand2) + ligand2*(1-ligand1)) + ligand1*ligand2;' - energy_expression += 'vdw_lambda = %f;' % vdw_lambda - - softcore_force = openmm.CustomNonbondedForce(energy_expression) - softcore_force.addPerParticleParameter('epsilon') - softcore_force.addPerParticleParameter('R0') - softcore_force.addPerParticleParameter('ligand') - - for particle_index in range(system.getNumParticles()): - # Retrieve parameters from vdW force. - [parentIndex, sigma, epsilon, reductionFactor] = force.getParticleParameters(particle_index) - # Add parameters to CustomNonbondedForce. - if particle_index in alchemical_region.alchemical_atoms: - softcore_force.addParticle([epsilon, sigma, 1]) - else: - softcore_force.addParticle([epsilon, sigma, 0]) - - # Deal with exclusions. - excluded_atoms = force.getParticleExclusions(particle_index) - for jatom in excluded_atoms: - if (particle_index < jatom): - softcore_force.addExclusion(particle_index, jatom) - - # Make sure periodic boundary conditions are treated the same way. - # TODO: Handle PBC correctly. - softcore_force.setNonbondedMethod( openmm.CustomNonbondedForce.CutoffPeriodic ) - softcore_force.setCutoffDistance( force.getCutoff() ) - - # Turn off vdW interactions for alchemically-modified atoms. - for particle_index in ligand_atoms: - # Retrieve parameters. - [parentIndex, sigma, epsilon, reductionFactor] = force.getParticleParameters(particle_index) - epsilon = 1.0e-6 * epsilon # TODO: For some reason, we cannot set epsilon to 0. - force.setParticleParameters(particle_index, parentIndex, sigma, epsilon, reductionFactor) - - # Deal with exceptions here. - # TODO - - return [softcore_force] - - @staticmethod - def _alchemically_modify_GBSAOBCForce(reference_force, alchemical_region, _, sasa_model='ACE'): - """Create alchemically-modified version of GBSAOBCForce. - - Parameters - ---------- - reference_force : openmm.GBSAOBCForce - The reference GBSAOBCForce to be alchemically modify. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the atoms to - alchemically modify. - sasa_model : str, optional, default='ACE' - Solvent accessible surface area model. - - Returns - ------- - custom_force : openmm.CustomGBForce - The alchemical version of the reference force. - - TODO - ---- - * Add support for all types of GBSA forces supported by OpenMM. - * Can we more generally modify any CustomGBSAForce? - - """ - if len(alchemical_region) > 1: - raise NotImplementedError("Multiple regions does not work with GBSAOBCForce") - else: - alchemical_region = alchemical_region[0] - - # TODO make sasa_model a Factory attribute? - custom_force = openmm.CustomGBForce() - - # Add per-particle parameters. - custom_force.addGlobalParameter("lambda_electrostatics", 1.0) - custom_force.addPerParticleParameter("charge") - custom_force.addPerParticleParameter("radius") - custom_force.addPerParticleParameter("scale") - custom_force.addPerParticleParameter("alchemical") - - # Set nonbonded method. - custom_force.setNonbondedMethod(reference_force.getNonbondedMethod()) - custom_force.setCutoffDistance(reference_force.getCutoffDistance()) - - # Add global parameters. - custom_force.addGlobalParameter("solventDielectric", reference_force.getSolventDielectric()) - custom_force.addGlobalParameter("soluteDielectric", reference_force.getSoluteDielectric()) - custom_force.addGlobalParameter("offset", 0.009) - - custom_force.addComputedValue("I", "(lambda_electrostatics*alchemical2 + (1-alchemical2))*step(r+sr2-or1)*0.5*(1/L-1/U+0.25*(r-sr2^2/r)*(1/(U^2)-1/(L^2))+0.5*log(L/U)/r+C);" - "U=r+sr2;" - "C=2*(1/or1-1/L)*step(sr2-r-or1);" - "L=max(or1, D);" - "D=abs(r-sr2);" - "sr2 = scale2*or2;" - "or1 = radius1-offset; or2 = radius2-offset", openmm.CustomGBForce.ParticlePairNoExclusions) - - custom_force.addComputedValue("B", "1/(1/or-tanh(psi-0.8*psi^2+4.85*psi^3)/radius);" - "psi=I*or; or=radius-offset", openmm.CustomGBForce.SingleParticle) - - custom_force.addEnergyTerm("-0.5*138.935485*(1/soluteDielectric-1/solventDielectric)*(lambda_electrostatics*alchemical+(1-alchemical))*charge^2/B", openmm.CustomGBForce.SingleParticle) - if sasa_model == 'ACE': - custom_force.addEnergyTerm("(lambda_electrostatics*alchemical+(1-alchemical))*28.3919551*(radius+0.14)^2*(radius/B)^6", openmm.CustomGBForce.SingleParticle) - - custom_force.addEnergyTerm("-138.935485*(1/soluteDielectric-1/solventDielectric)*(lambda_electrostatics*alchemical1+(1-alchemical1))*charge1*(lambda_electrostatics*alchemical2+(1-alchemical2))*charge2/f;" - "f=sqrt(r^2+B1*B2*exp(-r^2/(4*B1*B2)))", openmm.CustomGBForce.ParticlePairNoExclusions); - - # Add particle parameters. - for particle_index in range(reference_force.getNumParticles()): - # Retrieve parameters. - [charge, radius, scaling_factor] = reference_force.getParticleParameters(particle_index) - # Set particle parameters. - if particle_index in alchemical_region.alchemical_atoms: - parameters = [charge, radius, scaling_factor, 1.0] - else: - parameters = [charge, radius, scaling_factor, 0.0] - custom_force.addParticle(parameters) - - return {'lambda_electrostatics': [custom_force]} - - def _alchemically_modify_CustomGBForce(self, reference_force, alchemical_region, _): - """Create alchemically-modified version of CustomGBForce. - - The GB functions are meta-programmed using the following rules: - - 'lambda_electrostatics' is added as a global parameter. - - 'alchemical' is added as a per-particle parameter. All atoms in - the alchemical group have this parameter set to 1; otherwise 0. - - Any single-particle energy term (`CustomGBForce.SingleParticle`) - is scaled by `(lambda_electrostatics*alchemical+(1-alchemical))` - - Any two-particle energy term (`CustomGBForce.ParticlePairNoExclusions`) - has charge 1 (`charge1`) replaced by `(lambda_electrostatics*alchemical1+(1-alchemical1))*charge1` - and charge 2 (`charge2`) replaced by `(lambda_electrostatics*alchemical2+(1-alchemical2))*charge2`. - - Any single-particle computed value (`CustomGBForce.SingleParticle`) - remains unmodified - - Any two-particle computed value (`CustomGBForce.ParticlePairNoExclusions`) - is scaled by `(lambda_electrostatics*alchemical2 + (1-alchemical2))` - - Scaling of a term should always prepend and capture the value with - an intermediate variable. For example, prepending `scaling * unscaled; unscaled =` - will capture the value of the expression as `unscaled` and multiple by `scaled`. - This avoids the need to identify the head expression and add parentheses. - - .. warning:: - This may not work correctly for all GB models. - - Parameters - ---------- - reference_force : openmm.GBSAOBCForce - The reference GBSAOBCForce to be alchemically modify. - alchemical_region : AlchemicalRegion - The alchemical region containing the indices of the atoms to - alchemically modify. - - Returns - ------- - custom_force : openmm.CustomGBForce - The alchemical version of the reference force. - - """ - if len(alchemical_region) > 1: - raise NotImplementedError("Multiple regions does not work with CustomGBForce") - else: - alchemical_region = alchemical_region[0] - - custom_force = openmm.CustomGBForce() - - # Add global parameters - for index in range(reference_force.getNumGlobalParameters()): - name = reference_force.getGlobalParameterName(index) - default_value = reference_force.getGlobalParameterDefaultValue(index) - custom_force.addGlobalParameter(name, default_value) - custom_force.addGlobalParameter("lambda_electrostatics", 1.0) - - # Add per-particle parameters. - for index in range(reference_force.getNumPerParticleParameters()): - name = reference_force.getPerParticleParameterName(index) - custom_force.addPerParticleParameter(name) - custom_force.addPerParticleParameter("alchemical") - - # Set nonbonded methods. - custom_force.setNonbondedMethod(reference_force.getNonbondedMethod()) - custom_force.setCutoffDistance(reference_force.getCutoffDistance()) - - # Add computations. - for index in range(reference_force.getNumComputedValues()): - name, expression, computation_type = reference_force.getComputedValueParameters(index) - - # Alter expression for particle pair terms only. - if computation_type is not openmm.CustomGBForce.SingleParticle: - prepend = ('alchemical_scaling*unscaled; ' - 'alchemical_scaling = (lambda_electrostatics*alchemical2 + (1-alchemical2)); ' - 'unscaled = ') - expression = prepend + expression - - custom_force.addComputedValue(name, expression, computation_type) - - # Add energy terms. - for index in range(reference_force.getNumEnergyTerms()): - expression, computation_type = reference_force.getEnergyTermParameters(index) - - # Alter expressions - if computation_type is openmm.CustomGBForce.SingleParticle: - prepend = ('alchemical_scaling*unscaled; ' - 'alchemical_scaling = (lambda_electrostatics*alchemical + (1-alchemical)); ' - 'unscaled = ') - expression = prepend + expression - else: - expression = expression.replace('charge1', 'alchemically_scaled_charge1') - expression = expression.replace('charge2', 'alchemically_scaled_charge2') - expression += ' ; alchemically_scaled_charge1 = (lambda_electrostatics*alchemical1+(1-alchemical1)) * charge1;' - expression += ' ; alchemically_scaled_charge2 = (lambda_electrostatics*alchemical2+(1-alchemical2)) * charge2;' - - custom_force.addEnergyTerm(expression, computation_type) - - # Add particle parameters - for particle_index in range(reference_force.getNumParticles()): - parameters = reference_force.getParticleParameters(particle_index) - # Append alchemical parameter - parameters = list(parameters) - if particle_index in alchemical_region.alchemical_atoms: - parameters.append(1.0) - else: - parameters.append(0.0) - custom_force.addParticle(parameters) - - # Add tabulated functions - for function_index in range(reference_force.getNumTabulatedFunctions()): - name = reference_force.getTabulatedFunctionName(function_index) - function = reference_force.getTabulatedFunction(function_index) - function_copy = copy.deepcopy(function) - custom_force.addTabulatedFunction(name, function_copy) - - # Add exclusions - for exclusion_index in range(reference_force.getNumExclusions()): - [particle1, particle2] = reference_force.getExclusionParticles(exclusion_index) - custom_force.addExclusion(particle1, particle2) - - return {'lambda_electrostatics': [custom_force]} - - # ------------------------------------------------------------------------- - # Internal usage: Infer force labels - # ------------------------------------------------------------------------- - - @staticmethod - def _find_force_components(alchemical_system): - """Return force labels and indices for each force.""" - def add_label(label, index): - assert label not in force_labels - force_labels[label] = index - - def check_parameter(custom_force, parameter): - for parameter_id in range(custom_force.getNumGlobalParameters()): - parameter_name = custom_force.getGlobalParameterName(parameter_id) - if parameter_name.startswith(parameter): - region_name = parameter_name[len(parameter)+1:] if len(parameter_name) > len(parameter) else None - return [True, region_name] - return [False, None] - - def check_energy_expression(custom_force, parameter): - try: - energy_expression = custom_force.getEnergyFunction() - except AttributeError: # CustomGBForce - found = False - for index in range(custom_force.getNumEnergyTerms()): - expression, _ = custom_force.getEnergyTermParameters(index) - if parameter in expression: - found = True - break - return [found, ''] # CustomGBForce will not have a parameter suffix - found = parameter in energy_expression - if not found: - return [found, ''] # param not found and by extension no parameter suffix - #Look for parameter suffix - p = re.compile(r'{}_([A-Za-z0-9]+)'.format(parameter)) - try: - suffix = p.search(energy_expression).group(1) - return [found, suffix] - except AttributeError: - return [found, ''] # no parameter suffix found - - force_labels = {} - nonbonded_forces = {} - sterics_bond_forces = {} - electro_bond_forces = {} - - # We save CustomBondForces and CustomNonbondedForces used for nonbonded - # forces and exceptions to distinguish them later - for force_index, force in enumerate(alchemical_system.getForces()): - if isinstance(force, openmm.CustomAngleForce): - parameter_found, region_name = check_parameter(force, 'lambda_angles') - if parameter_found: - label = 'alchemically modified HarmonicAngleForce' - if region_name is not None: - label = label + ' for region ' + region_name - add_label(label, force_index) - - elif isinstance(force, openmm.CustomBondForce) and check_parameter(force, 'lambda_bonds')[0]: - #Need extra check for 'lambda_bonds' in the if to differntiate from exceptions - parameter_found, region_name = check_parameter(force, 'lambda_bonds') - if parameter_found: - label = 'alchemically modified HarmonicBondForce' - if region_name is not None: - label = label + ' for region ' + region_name - add_label(label, force_index) - - elif isinstance(force, openmm.CustomTorsionForce): - parameter_found, region_name = check_parameter(force, 'lambda_torsions') - if parameter_found: - label = 'alchemically modified PeriodicTorsionForce' - if region_name is not None: - label = label + ' for region ' + region_name - add_label(label, force_index) - - elif isinstance(force, openmm.CustomGBForce): - parameter_found, _ = check_parameter(force, 'lambda_electrostatics') - if parameter_found: - #No multi region for GBForce - if check_energy_expression(force, 'unscaled')[0]: - add_label('alchemically modified CustomGBForce', force_index) - else: - add_label('alchemically modified GBSAOBCForce', force_index) - - elif isinstance(force, openmm.CustomBondForce): - parameter_found, region_type_suffix = check_energy_expression(force, 'lambda') - if parameter_found: - _, region_name_suffix = check_energy_expression(force, 'lambda_{}'.format(region_type_suffix)) - if region_type_suffix == 'sterics': - if region_name_suffix in sterics_bond_forces: - sterics_bond_forces[region_name_suffix].append([force_index, force]) - else: - sterics_bond_forces[region_name_suffix] = [[force_index, force]] - if region_type_suffix == 'electrostatics': - if region_name_suffix in electro_bond_forces: - electro_bond_forces[region_name_suffix].append([force_index, force]) - else: - electro_bond_forces[region_name_suffix] = [[force_index, force]] - - elif (isinstance(force, openmm.CustomNonbondedForce) and force.getEnergyFunction() == '0.0;' and - force.getGlobalParameterName(0) == 'lambda_electrostatics'): - add_label('CustomNonbondedForce holding alchemical atoms unmodified charges', force_index) - - elif isinstance(force, openmm.CustomNonbondedForce): - parameter_found, region_type_suffix = check_energy_expression(force, 'lambda') - if parameter_found: - _, region_name_suffix = check_energy_expression(force, 'lambda_{}'.format(region_type_suffix)) - if region_type_suffix == 'sterics': - if region_name_suffix in nonbonded_forces: - nonbonded_forces[region_name_suffix].append(['sterics', force_index, force]) - else: - nonbonded_forces[region_name_suffix] = [['sterics', force_index, force]] - if region_type_suffix == 'electrostatics': - if region_name_suffix in nonbonded_forces: - nonbonded_forces[region_name_suffix].append(['electrostatics', force_index, force]) - else: - nonbonded_forces[region_name_suffix] = [['electrostatics', force_index, force]] - else: - add_label('unmodified ' + force.__class__.__name__, force_index) - - # Differentiate between na/aa nonbonded forces. - alchemical_atoms_by_region = {} - for region_name, forces in nonbonded_forces.items(): - for force_type, force_index, force in forces: - if region_name == '': - label = 'alchemically modified NonbondedForce for {}alchemical/alchemical ' + force_type - else: - label = 'alchemically modified NonbondedForce for {}alchemical/alchemical ' + force_type +\ - ' for region ' + region_name - interacting_atoms, alchemical_atoms = force.getInteractionGroupParameters(0) - alchemical_atoms_by_region[region_name] = [interacting_atoms, alchemical_atoms] - if interacting_atoms == alchemical_atoms: # alchemical-alchemical atoms - add_label(label.format(''), force_index) - else: - add_label(label.format('non-'), force_index) - - # Initialize sterics_bond_forces or electro_bond_forces for regions which did not have forces, as empty lists - for k in sterics_bond_forces.keys(): - if k in electro_bond_forces: - pass - else: - electro_bond_forces[k] = [] - for k in electro_bond_forces.keys(): - if k in sterics_bond_forces: - pass - else: - sterics_bond_forces[k] = [] - - # Differentiate between na/aa bond forces for exceptions. - for (region_name, sterics_forces), electro_forces in zip(sterics_bond_forces.items(), electro_bond_forces.values()): - if len(sterics_forces) == 0: - continue - for force_type, bond_forces in [('sterics', sterics_forces), ('electrostatics', electro_forces)]: - # With exact PME there are no CustomBondForces modeling electrostatics exceptions. - if force_type == 'electrostatics' and len(bond_forces) == 0: - continue - # Otherwise there should be two CustomBondForce. - assert len(bond_forces) == 2 - if region_name == '': - label = 'alchemically modified BondForce for {}alchemical/alchemical ' + force_type + ' exceptions' - else: - label = 'alchemically modified BondForce for {}alchemical/alchemical ' + force_type +\ - ' exceptions for region ' + region_name - - # Sort forces by number of bonds. - bond_forces = sorted(bond_forces, key=lambda x: x[1].getNumBonds()) - (force_index1, force1), (force_index2, force2) = bond_forces - - # Check if both define their parameters (with decoupling the lambda - # parameter doesn't exist in the alchemical-alchemical force) - parameter_name = 'lambda_' + force_type - if region_name != '': - parameter_name = parameter_name + '_{}'.format(region_name) - interacting_atoms, alchemical_atoms = alchemical_atoms_by_region[region_name] - - if check_parameter(force1, parameter_name)[0] != check_parameter(force2, parameter_name)[0]: - if check_parameter(force1, parameter_name)[0]: - add_label(label.format('non-'), force_index1) - add_label(label.format(''), force_index2) - else: - add_label(label.format(''), force_index1) - add_label(label.format('non-'), force_index2) - - # If they are both empty they are identical and any label works. - elif force1.getNumBonds() == 0 and force2.getNumBonds() == 0: - add_label(label.format(''), force_index1) - add_label(label.format('non-'), force_index2) - - # We check that the bond atoms are both alchemical or not. - else: - atom_i, atom_j, _ = force2.getBondParameters(0) - both_alchemical = atom_i in alchemical_atoms and atom_j in alchemical_atoms - if both_alchemical: - add_label(label.format(''), force_index2) - add_label(label.format('non-'), force_index1) - else: - add_label(label.format('non-'), force_index2) - add_label(label.format(''), force_index1) - return force_labels - - -if __name__ == '__main__': - import doctest - doctest.testmod() - # doctest.run_docstring_examples(AlchemicalFunction, globals()) \ No newline at end of file From bc489e379982e2b2147a9f5187332826109086c6 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 17 Dec 2024 09:11:05 +0100 Subject: [PATCH 108/163] Remove femto alchemy --- .../protocols/openmm_septop/femto_alchemy.py | 347 ------------------ 1 file changed, 347 deletions(-) delete mode 100644 openfe/protocols/openmm_septop/femto_alchemy.py diff --git a/openfe/protocols/openmm_septop/femto_alchemy.py b/openfe/protocols/openmm_septop/femto_alchemy.py deleted file mode 100644 index 4c1b6b33f..000000000 --- a/openfe/protocols/openmm_septop/femto_alchemy.py +++ /dev/null @@ -1,347 +0,0 @@ -import collections -import copy -import itertools -from typing import List, Any - -import numpy -import openmm -import openmm.unit - -# import femto.fe.config - -# This code was obtained and modified from https://github.com/Psivant/femto -from openmm import NonbondedForce, CustomNonbondedForce - -LAMBDA_VDW_LIGAND_1 = "lambda_sterics_ligandA" -"""The global parameter used to scale the vdW interactions of ligand 1.""" -LAMBDA_VDW_LIGAND_2 = "lambda_sterics_ligandB" -"""The global parameter used to scale the vdW interactions of ligand 2.""" - -LAMBDA_CHARGES_LIGAND_1 = "lambda_electrostatics_ligandA" -"""The global parameter used to scale the electrostatic interactions of -ligand 1.""" -LAMBDA_CHARGES_LIGAND_2 = "lambda_electrostatics_ligandB" -"""The global parameter used to scale the electrostatic interactions of -ligand 2.""" - - -_SUPPORTED_FORCES = [ - openmm.HarmonicBondForce, - openmm.HarmonicAngleForce, - openmm.PeriodicTorsionForce, - openmm.NonbondedForce, - openmm.MonteCarloBarostat, - openmm.CMMotionRemover, -] - - -def _beutler_softcore_potential(variable: str) -> str: - return ( - f"4.0 * (1.0 - {variable}) * eps * x * (x - 1.0);" - # - f"x = (sig / r_eff) ^ 6;" - # - f"r_eff = (0.5 * sig^6 * {variable} + r^6)^(1/6);" - # - f"sig = 0.5 * (sig1 + sig2);" - f"eps = sqrt(eps1 * eps2);" - ) - - -def _validate_exceptions( - force: openmm.NonbondedForce, ligand_1_idxs: set[int], ligand_2_idxs: set[int] -): - """Validate that a non-bonded force's exceptions are consistent with the - quite strict assumptions we make when setting up FEP""" - - for i in range(force.getNumExceptions()): - idx_a, idx_b, *_ = force.getExceptionParameters(i) - - if idx_a in ligand_1_idxs and idx_b in ligand_1_idxs: - continue - if idx_a in ligand_2_idxs and idx_b in ligand_2_idxs: - continue - if ( - idx_a not in ligand_1_idxs - and idx_b not in ligand_1_idxs - and idx_a not in ligand_2_idxs - and idx_b not in ligand_2_idxs - ): - continue - - raise NotImplementedError("alchemical-chemical exceptions were not expected") - - -def _convert_intramolecular_interactions( - force: openmm.NonbondedForce, - ligand_1_idxs: set[int], - ligand_2_idxs: set[int], -): - """Converts all intra-molecular interactions in alchemical molecules to exceptions - so that they won't be scaled, and excludes ligand-ligand interactions. - - This means we only need a single custom nonbonded force to handle the soft-core - vdW interactions between alchemical and non-alchemical particles. - - Args: - force: The force to modify. - ligand_1_idxs: The indices of atoms belonging to the first ligand. - ligand_2_idxs: The indices of atoms belonging to the second ligand. - """ - - existing_exceptions = { - tuple(sorted(force.getExceptionParameters(i)[:2])): i - for i in range(force.getNumExceptions()) - } - assert len(existing_exceptions) == force.getNumExceptions() - - ligand_idxs = [ligand_1_idxs, ligand_2_idxs] - - # add exceptions for intramolecular interactions - for idxs in ligand_idxs: - for idx_a, idx_b in itertools.combinations(idxs, r=2): - pair = tuple(sorted((idx_a, idx_b))) - - if pair in existing_exceptions: - continue - - charge_a, sigma_a, epsilon_a = force.getParticleParameters(idx_a) - charge_b, sigma_b, epsilon_b = force.getParticleParameters(idx_b) - - epsilon_ab = ( - numpy.sqrt((epsilon_a * epsilon_b).value_in_unit(epsilon_a.unit**2)) - * epsilon_a.unit - ) - sigma_ab = 0.5 * (sigma_a + sigma_b) - charge_ab = charge_a * charge_b - - existing_exceptions[pair] = force.addException( - *pair, charge_ab, sigma_ab, epsilon_ab - ) - - # add exceptions for ligand-ligand interactions - for idx_a, idx_b in itertools.product(ligand_1_idxs, ligand_2_idxs): - force.addException(idx_a, idx_b, 0.0, 1.0, 0.0, replace=True) - - -def _apply_lambda_charge( - force: openmm.NonbondedForce, ligand_idxs: set[int], variable: str -): - """Modifies a standard non-bonded force so that electrostatic interactions of - the specified atoms are scaled by ``variable``. - - Any alchemical-chemical interactions will be linearly scaled while chemical-chemical - and alchemical-alchemical interactions will remain unchanged. - - Args: - force: The force to modify. - ligand_idxs: The indices of atoms belonging to the ligand. - variable: The global parameter to use for scaling. - """ - - if len(ligand_idxs) == 0: - return - - force.addGlobalParameter(variable, 0.0) - - for i in range(force.getNumParticles()): - if i not in ligand_idxs: - continue - - charge, sigma, epsilon = force.getParticleParameters(i) - - if numpy.isclose(charge.value_in_unit(openmm.unit.elementary_charge), 0.0): - # We don't need to scale already zero charges - continue - - # q should be 0.0 at λ=1 and q at λ=0, so we set q - λq - force.addParticleParameterOffset(variable, i, -charge, 0.0, 0.0) - force.setParticleParameters(i, charge, sigma, epsilon) - - -def _apply_lambda_vdw( - force: openmm.NonbondedForce, - ligand_idxs: set[int], - non_ligand_idxs: set[int], - variable: str, -) -> openmm.CustomNonbondedForce | None: - """Modifies a standard non-bonded force so that vdW interactions of the specified - atoms are scaled by ``variable``. - - Any alchemical-chemical interactions will be scaled using a Beutler-style soft core - potential while chemical-chemical and alchemical-alchemical interactions will remain - unchanged. - - Args: - force: The force to modify. - ligand_idxs: The indices of the ligand atoms whose interactions should be scaled - non_ligand_idxs: The indices of the remaining atoms that can be interacted with. - variable: The global parameter to use for scaling. - - Returns: - A custom non-bonded force that contains only chemical-alchemical interactions. - """ - - if len(ligand_idxs) == 0: - return None - - custom_vdw_fn = _beutler_softcore_potential(variable) - - custom_force = openmm.CustomNonbondedForce(custom_vdw_fn) - custom_force.setNonbondedMethod( - force.getNonbondedMethod() - if int(force.getNonbondedMethod()) not in {3, 4, 5} - else openmm.CustomNonbondedForce.CutoffPeriodic - ) - custom_force.setCutoffDistance(force.getCutoffDistance()) - custom_force.setSwitchingDistance(force.getSwitchingDistance()) - custom_force.setUseSwitchingFunction(force.getUseSwitchingFunction()) - custom_force.setUseLongRangeCorrection(force.getUseDispersionCorrection()) - - custom_force.addGlobalParameter(variable, 0.0) - - custom_force.addPerParticleParameter("eps") - custom_force.addPerParticleParameter("sig") - - for index in range(force.getNumParticles()): - charge, sigma, epsilon = force.getParticleParameters(index) - custom_force.addParticle([epsilon, sigma]) - - if index not in ligand_idxs: - continue - - # the intermolecular alchemical interactions will be handled by the custom - # soft-core force, so we zero them out here. - force.setParticleParameters(index, charge, sigma, epsilon * 0) - - for index in range(force.getNumExceptions()): - index_a, index_b, *_ = force.getExceptionParameters(index) - # let the exceptions be handled by the original force as we don't intend to - # annihilate those while switching off the intermolecular vdW interactions - custom_force.addExclusion(index_a, index_b) - - # alchemical-chemical - if len(non_ligand_idxs) > 0 and len(ligand_idxs) > 0: - custom_force.addInteractionGroup(ligand_idxs, non_ligand_idxs) - # alchemical-alchemical (e.g. ion pairs) - # if len(ligand_1_idxs) > 0 and len(ligand_2_idxs) > 0: - # custom_force.addInteractionGroup(ligand_1_idxs, ligand_2_idxs) - - return custom_force - - -def _apply_nonbonded_lambdas( - force: openmm.NonbondedForce, - ligand_1_idxs: set[int], - ligand_2_idxs: set[int] | None, -) -> tuple[openmm.NonbondedForce | openmm.CustomNonbondedForce, ...]: - """Modifies a standard non-bonded force so that vdW and electrostatic interactions - are scaled by ``lambda_vdw`` and ``lambda_charges`` respectively. - - Args: - force: The original non-bonded force. - ligand_1_idxs: The indices of the ligand atoms whose interactions should be - scaled by lambda. - ligand_2_idxs: The indices of the ligand atoms whose interactions should be - scaled by 1 - lambda. - - Returns: - The modified non-bonded force containing chemical-chemical and - alchemical-alchemical interactions and two custom non-bonded force containing - only alchemical-chemical interactions for ligand 1 and 2 respectively. - """ - force = copy.deepcopy(force) - - - assert ( - force.getNumGlobalParameters() == 0 - ), "the non-bonded force should not already contain global parameters" - assert ( - force.getNumParticleParameterOffsets() == 0 - and force.getNumExceptionParameterOffsets() == 0 - ), "the non-bonded force should not already contain parameter offsets" - - ligand_2_idxs = set() if ligand_2_idxs is None else ligand_2_idxs - - _validate_exceptions(force, ligand_1_idxs, ligand_2_idxs) - _convert_intramolecular_interactions(force, ligand_1_idxs, ligand_2_idxs) - - _apply_lambda_charge(force, ligand_1_idxs, LAMBDA_CHARGES_LIGAND_1) - _apply_lambda_charge(force, ligand_2_idxs, LAMBDA_CHARGES_LIGAND_2) - - - non_ligand_indices = { - i - for i in range(force.getNumParticles()) - if i not in ligand_1_idxs and i not in ligand_2_idxs - } - - custom_force_1 = _apply_lambda_vdw( - force, ligand_1_idxs, non_ligand_indices, LAMBDA_VDW_LIGAND_1 - ) - custom_force_2 = _apply_lambda_vdw( - force, ligand_2_idxs, non_ligand_indices, LAMBDA_VDW_LIGAND_2 - ) - return force, custom_force_1, custom_force_2 - - -def apply_fep( - system: openmm.System, - ligand_1_idxs: set[int], - ligand_2_idxs: set[int] | None, -): - """Modifies an OpenMM system so that different interactions can be scaled by - corresponding lambda parameters. - - Notes: - * All intra-molecular interactions of alchemical ligands are currently replaced - with exceptions and are not scaled by lambda parameters. This will lead to - slightly different energies from the original system as cutoffs are not - applied to them by OpenMM. - * LJ vdW interactions between ligands and the rest of the system will be - replaced with a Beutler-style soft-core LJ potential with a-b-c of 1-1-6 and - alpha=0.5. - * Ligand indices **must** correspond to **all** atoms in the ligand, - alchemically modifying part of a molecule is not yet supported. - - Args: - system: The system to modify in-place. - ligand_1_idxs: The indices of the ligand atoms whose interactions should be - scaled by lambda. - ligand_2_idxs: The indices of the ligand atoms whose interactions should be - scaled by 1 - lambda. - config: Configuration options. - """ - - forces_by_type = collections.defaultdict(list) - - for force in system.getForces(): - if type(force) not in _SUPPORTED_FORCES: - raise ValueError( - f"Force type {type(force)} is not supported when alchemical modifying " - f"a system." - ) - forces_by_type[type(force)].append(force) - - updated_forces: list[NonbondedForce | CustomNonbondedForce | Any] = [] - - for force_type, forces in forces_by_type.items(): - if len(forces) != 1: - raise NotImplementedError("only one force of each type is supported.") - - force = forces[0] - - if force_type == openmm.NonbondedForce: - nonbonded_forces = _apply_nonbonded_lambdas( - force, ligand_1_idxs, ligand_2_idxs, - ) - updated_forces.extend(nonbonded_forces) - else: - updated_forces.append(copy.deepcopy(force)) - - for i in reversed(range(system.getNumForces())): - system.removeForce(i) - - for force in updated_forces: - if force is not None: - system.addForce(force) From 228c1c9cde12315527f0cb13e04089e9c4eef7e6 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 17 Dec 2024 10:09:17 +0100 Subject: [PATCH 109/163] Remove unnecessary file --- .../openmm_septop/femto_constants.py | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 openfe/protocols/openmm_septop/femto_constants.py diff --git a/openfe/protocols/openmm_septop/femto_constants.py b/openfe/protocols/openmm_septop/femto_constants.py deleted file mode 100644 index 69356b699..000000000 --- a/openfe/protocols/openmm_septop/femto_constants.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Constant values such as common force groups and names.""" - -import enum - -LIGAND_1_RESIDUE_NAME = "L1" -"""The standard residue name to assign to ligand 1 of a FE calculation.""" -LIGAND_2_RESIDUE_NAME = "R1" -"""The standard residue name to assign to ligand 2 of a FE calculation.""" - - -class OpenMMForceGroup(enum.IntEnum): - """Standard force groups to assign to common OpenMM forces to make them easier to - identify.""" - - BOND = 0 - ANGLE = 1 - DIHEDRAL = 2 - - NONBONDED = 3 - - COM_RESTRAINT = 4 - POSITION_RESTRAINT = 5 - ALIGNMENT_RESTRAINT = 6 - - BAROSTAT = 7 - - ATM = 8 - - OTHER = 16 - - -class OpenMMForceName(str, enum.Enum): - """Standard names use for common OpenMM forces to make them easier to identify.""" - - COM_RESTRAINT = "com-restraint" - POSITION_RESTRAINT = "position-restraint" - ALIGNMENT_RESTRAINT = "alignment-restraint" - - -class OpenMMPlatform(str, enum.Enum): - """The available OpenMM platforms to run using.""" - - REFERENCE = "Reference" - CPU = "CPU" - OPENCL = "OpenCL" - CUDA = "CUDA" - - def __str__(self): - return self.value \ No newline at end of file From a727ec28e6b670ac37378b904c13f20ac117d425 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 17 Dec 2024 10:10:04 +0100 Subject: [PATCH 110/163] Small fixes --- openfe/protocols/openmm_septop/base.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 80c2e2b75..456f7c71e 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -829,13 +829,14 @@ def run(self, dry=False, verbose=True, self.logger.info("Creating the alchemical system and applying restraints") factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + # Alchemical Region for ligand A alchemical_region_A = AlchemicalRegion( alchemical_atoms=atom_indices_AB_A, name='A') + # Alchemical Region for ligand B alchemical_region_B = AlchemicalRegion( alchemical_atoms=atom_indices_AB_B, name='B') alchemical_system = factory.create_alchemical_system( omm_system_AB, [alchemical_region_A, alchemical_region_B]) - omm_system_AB = alchemical_system # 10. Apply Restraints off_A = alchem_comps["stateA"][0].to_openff() @@ -855,7 +856,7 @@ def run(self, dry=False, verbose=True, print(ligand_B_inxs) system = self._add_restraints( - omm_system_AB, positions_AB, omm_topology_AB, + alchemical_system, positions_AB, omm_topology_AB, off_A, off_B, settings, ligand_A_ref_inxs, ligand_B_ref_inxs, From e19db658d11f53722a32d936e4e57e8d18cb455a Mon Sep 17 00:00:00 2001 From: IAlibay Date: Tue, 17 Dec 2024 11:31:16 +0000 Subject: [PATCH 111/163] Settings and some tests for them --- .../restraint_utils/geometry/base.py | 2 +- openfe/protocols/restraint_utils/settings.py | 22 +++++- .../protocols/restraints/test_settings.py | 77 +++++++++++++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 openfe/tests/protocols/restraints/test_settings.py diff --git a/openfe/protocols/restraint_utils/geometry/base.py b/openfe/protocols/restraint_utils/geometry/base.py index 0ca6ae200..798befd45 100644 --- a/openfe/protocols/restraint_utils/geometry/base.py +++ b/openfe/protocols/restraint_utils/geometry/base.py @@ -42,7 +42,7 @@ class HostGuestRestraintGeometry(BaseRestraintGeometry): @validator("guest_atoms", "host_atoms") def positive_idxs(cls, v): - if any([i < 0 for i in v]): + if v is not None and any([i < 0 for i in v]): errmsg = "negative indices passed" raise ValueError(errmsg) return v diff --git a/openfe/protocols/restraint_utils/settings.py b/openfe/protocols/restraint_utils/settings.py index 66998debb..0a06714c0 100644 --- a/openfe/protocols/restraint_utils/settings.py +++ b/openfe/protocols/restraint_utils/settings.py @@ -52,6 +52,13 @@ class DistanceRestraintSettings(BaseRestraintSettings): represent small molecules. """ + @validator("guest_atoms", "host_atoms") + def positive_idxs(cls, v): + if v is not None and any([i < 0 for i in v]): + errmsg = "negative indices passed" + raise ValueError(errmsg) + return v + class FlatBottomRestraintSettings(DistanceRestraintSettings): """ @@ -63,6 +70,12 @@ class FlatBottomRestraintSettings(DistanceRestraintSettings): The distance at which the harmonic restraint is imposed in units of distance. """ + @validator("well_radius") + def positive_value(cls, v): + if v is not None and v.m < 0: + errmsg = f"well radius cannot be negative {v}" + raise ValueError(errmsg) + return v class BoreschRestraintSettings(BaseRestraintSettings): @@ -128,4 +141,11 @@ class BoreschRestraintSettings(BaseRestraintSettings): """ The indices of the guest component atoms to restraint. If defined, these will override any automatic selection. - """ \ No newline at end of file + """ + + @validator("guest_atoms", "host_atoms") + def positive_idxs_list(cls, v): + if v is not None and any([i < 0 for i in v]): + errmsg = "negative indices passed" + raise ValueError(errmsg) + return v \ No newline at end of file diff --git a/openfe/tests/protocols/restraints/test_settings.py b/openfe/tests/protocols/restraints/test_settings.py new file mode 100644 index 000000000..49ed0dca0 --- /dev/null +++ b/openfe/tests/protocols/restraints/test_settings.py @@ -0,0 +1,77 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Test the restraint settings. +""" +import pytest +import numpy as np +import openmm +from openff.units import unit +from openfe.protocols.restraint_utils.settings import ( + DistanceRestraintSettings, + FlatBottomRestraintSettings, + BoreschRestraintSettings, +) + + +def test_distance_restraint_settings_default(): + """ + Basic settings regression test + """ + settings = DistanceRestraintSettings( + spring_constant=10 * unit.kilojoule_per_mole / unit.nm ** 2, + ) + assert settings.central_atoms_only is False + assert isinstance(settings, DistanceRestraintSettings) + + +def test_distance_restraint_negative_idxs(): + """ + Check that an error is raised if you have negative + atom indices in host atoms. + """ + with pytest.raises(ValueError, match="negative indices passed"): + _ = DistanceRestraintSettings( + spring_constant=10 * unit.kilojoule_per_mole / unit.nm ** 2, + host_atoms=[-1, 0, 2], + guest_atoms=[0, 1, 2], + ) + + +def test_flatbottom_restraint_settings_default(): + """ + Basic settings regression test + """ + settings = FlatBottomRestraintSettings( + spring_constant=10 * unit.kilojoule_per_mole / unit.nm ** 2, + well_radius=1*unit.nanometer, + ) + assert isinstance(settings, FlatBottomRestraintSettings) + + +def test_flatbottom_restraint_negative_well(): + """ + Check that an error is raised if you have a negative + well radius. + """ + with pytest.raises(ValueError, match="negative indices passed"): + _ = DistanceRestraintSettings( + spring_constant=10 * unit.kilojoule_per_mole / unit.nm ** 2, + host_atoms=[-1, 0, 2], + guest_atoms=[0, 1, 2], + ) + + +def test_boresch_restraint_settings_default(): + """ + Basic settings regression test + """ + settings = BoreschRestraintSettings( + K_r=10 * unit.kilojoule_per_mole / unit.nm ** 2, + K_thetaA=10 * unit.kilojoule_per_mole / unit.radians ** 2, + K_thetaB=10 * unit.kilojoule_per_mole / unit.radians ** 2, + phi_A0=10 * unit.kilojoule_per_mole / unit.radians ** 2, + phi_B0=10 * unit.kilojoule_per_mole / unit.radians ** 2, + phi_C0=10 * unit.kilojoule_per_mole / unit.radians ** 2, + ) + assert isinstance(settings, BoreschRestraintSettings) From 854d1c6e0255ba30af6388f6322da3ce9ee4d90f Mon Sep 17 00:00:00 2001 From: IAlibay Date: Tue, 17 Dec 2024 11:40:38 +0000 Subject: [PATCH 112/163] negative idxs test --- .../protocols/restraints/test_settings.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/openfe/tests/protocols/restraints/test_settings.py b/openfe/tests/protocols/restraints/test_settings.py index 49ed0dca0..82660cfaf 100644 --- a/openfe/tests/protocols/restraints/test_settings.py +++ b/openfe/tests/protocols/restraints/test_settings.py @@ -75,3 +75,21 @@ def test_boresch_restraint_settings_default(): phi_C0=10 * unit.kilojoule_per_mole / unit.radians ** 2, ) assert isinstance(settings, BoreschRestraintSettings) + + +def test_boresch_restraint_negative_idxs(): + """ + Check that the positive_idxs_list validator is + working as expected. + """ + with pytest.raises(ValueError, match='negative indices'): + settings = BoreschRestraintSettings( + K_r=10 * unit.kilojoule_per_mole / unit.nm ** 2, + K_thetaA=10 * unit.kilojoule_per_mole / unit.radians ** 2, + K_thetaB=10 * unit.kilojoule_per_mole / unit.radians ** 2, + phi_A0=10 * unit.kilojoule_per_mole / unit.radians ** 2, + phi_B0=10 * unit.kilojoule_per_mole / unit.radians ** 2, + phi_C0=10 * unit.kilojoule_per_mole / unit.radians ** 2, + host_atoms=[-1, 0], + guest_atoms=[0, 1], + ) From 9b53cd28043537ede777c169999844b628a9e490 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Tue, 17 Dec 2024 11:56:13 +0000 Subject: [PATCH 113/163] addressing some mypy issues --- .../restraint_utils/geometry/boresch.py | 21 +++++++++++-------- .../restraint_utils/geometry/flatbottom.py | 12 ++++++++++- .../restraint_utils/geometry/utils.py | 4 ++-- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py index 2b0cd2313..8a4eaaceb 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -168,6 +168,9 @@ def _get_atom_pool( The RDKit Molecule to search through rmsf : npt.NDArray A 1-D array of RMSF values for each atom. + rmsf_cutoff : unit.Quantity + The rmsf cutoff value for selecting atoms in units compatible with + nanometer. Returns ------- @@ -177,7 +180,7 @@ def _get_atom_pool( # Note: no need to keep track of rings because we'll filter by # bonded terms after, so if we only keep rings then all the bonded # atoms should be within the same ring system. - atom_pool = set() + atom_pool: set[tuple[int]] = set() for ring in get_aromatic_rings(rdmol): max_rmsf = rmsf[list(ring)].max() if max_rmsf < rmsf_cutoff: @@ -195,7 +198,7 @@ def _get_atom_pool( def find_guest_atom_candidates( topology: Union[str, pathlib.Path, openmm.app.Topology], - trajectory: Union[str, pathlib.Path], + trajectory: Union[str, pathlib.Path, npt.NDArray], rdmol: Chem.Mol, guest_idxs: list[int], rmsf_cutoff: unit.Quantity = 1 * unit.nanometer, @@ -208,7 +211,7 @@ def find_guest_atom_candidates( ---------- topology : Union[str, openmm.app.Topology] The topology of the system. - trajectory : Union[str, pathlib.Path] + trajectory : Union[str, pathlib.Path, npt.NDArray] A path to the system's coordinate trajectory. rdmol : Chem.Mol An RDKit Molecule representing the small molecule ordered in @@ -247,7 +250,7 @@ def find_guest_atom_candidates( u.trajectory[-1] # forward to the last frame # 1. Get the pool of atoms to work with - atom_pool = _get_atom_pool(rdmol, rmsf) + atom_pool = _get_atom_pool(rdmol, rmsf, rmsf_cutoff) if atom_pool is None: # We don't have enough atoms so we raise an error @@ -281,7 +284,7 @@ def find_guest_atom_candidates( def find_host_atom_candidates( topology: Union[str, pathlib.Path, openmm.app.Topology], - trajectory: Union[str, pathlib.Path], + trajectory: Union[str, pathlib.Path, npt.NDArray], host_idxs: list[int], l1_idx: int, host_selection: str, @@ -297,8 +300,8 @@ def find_host_atom_candidates( ---------- topology : Union[str, openmm.app.Topology] The topology of the system. - trajectory : Union[str, pathlib.Path] - A path to the system's coordinate trajectory. + trajectory : Union[str, pathlib.Path, npt.NDArray] + The system's coordinate trajectory. host_idxs : list[int] A list of the host indices in the system topology. l1_idx : int @@ -615,8 +618,8 @@ def _find_host_anchor( ) if any(h2_eval.ressults.valid): - d1_avgs = [d.mean() for d in h2_eval.results.distances1] - d2_avgs = [d.mean() for d in h2_eval.results.distances2] + d1_avgs = np.array([d.mean() for d in h2_eval.results.distances1]) + d2_avgs = np.array([d.mean() for d in h2_eval.results.distances2]) dsum_avgs = d1_avgs + d2_avgs k = dsum_avgs.argmin() diff --git a/openfe/protocols/restraint_utils/geometry/flatbottom.py b/openfe/protocols/restraint_utils/geometry/flatbottom.py index 3b4599f56..c5e975401 100644 --- a/openfe/protocols/restraint_utils/geometry/flatbottom.py +++ b/openfe/protocols/restraint_utils/geometry/flatbottom.py @@ -117,11 +117,21 @@ def get_flatbottom_distance_restraint( guest_ag = _get_mda_selection(u, guest_atoms, guest_selection) host_ag = _get_mda_selection(u, host_atoms, host_selection) + guest_idxs = [a.ix for a in guest_ag] + host_idxs = [a.ix for a in host_ag] + + if len(host_idxs) == 0 or len(guest_idxs) == 0: + errmsg = ( + "no atoms found in either the host or guest atom groups" + f"host_atoms: {host_idxs}" + f"guest_atoms: {guest_idxs}" + ) + raise ValueError(errmsg) com_dists = COMDistanceAnalysis(guest_ag, host_ag) com_dists.run() well_radius = com_dists.results.distances.max() * unit.angstrom + padding return FlatBottomDistanceGeometry( - guest_atoms=guest_atoms, host_atoms=host_atoms, well_radius=well_radius + guest_atoms=guest_idxs, host_atoms=host_idxs, well_radius=well_radius ) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 4b734b410..988a31cfe 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -76,7 +76,7 @@ def _get_mda_selection( def _get_mda_coord_format( - coordinates: Union[str, npt.NDArray] + coordinates: Union[str, pathlib.Path, npt.NDArray] ) -> Optional[MemoryReader]: """ Helper to set the coordinate format to MemoryReader @@ -84,7 +84,7 @@ def _get_mda_coord_format( Parameters ---------- - coordinates : Union[str, npt.NDArray] + coordinates : Union[str, pathlib.Path, npt.NDArray] Returns ------- From 32e541f9e9958a8ffcdc41a7f1d8ed23bc3dce4b Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 17 Dec 2024 14:56:18 +0100 Subject: [PATCH 114/163] Some fixes --- openfe/protocols/openmm_septop/base.py | 27 +++++----- .../openmm_septop/femto_constants.py | 49 +++++++++++++++++++ 2 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 openfe/protocols/openmm_septop/femto_constants.py diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 456f7c71e..607050e10 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -476,17 +476,17 @@ def _get_modeller( def _get_omm_objects( self, - system_modeller: app.Modeller, + system_modeller: openmm.app.Modeller, system_generator: SystemGenerator, smc_components: list[OFFMolecule], - ) -> tuple[app.Topology, openmm.unit.Quantity, openmm.System]: + ) -> tuple[openmm.app.Topology, openmm.unit.Quantity, openmm.System]: """ Get the OpenMM Topology, Positions and System of the parameterised system. Parameters ---------- - system_modeller : app.Modeller + system_modeller : openmm.app.Modeller OpenMM Modeller object representing the system to be parametrized. system_generator : SystemGenerator @@ -496,11 +496,11 @@ def _get_omm_objects( Returns ------- - topology : app.Topology + topology : openmm.app.Topology Topology object describing the parameterized system system : openmm.System An OpenMM System of the alchemical system. - positionns : openmm.unit.Quantity + positions : openmm.unit.Quantity Positions of the system. """ topology = system_modeller.getTopology() @@ -518,7 +518,7 @@ def _get_omm_objects( @staticmethod def _get_atom_indices( - omm_topology: app.Topology, + omm_topology: openmm.app.Topology, comp_resids: dict[Component, npt.NDArray], ): comp_atomids = {} @@ -654,7 +654,7 @@ def get_system( def get_system_AB( self, solv_comp: SolventComponent, - system_modeller_A: app.Modeller, + system_modeller_A: openmm.app.Modeller, smc_comps_AB: dict[SmallMoleculeComponent,OFFMolecule], smc_off_B: dict[SmallMoleculeComponent,OFFMolecule], settings: dict[str, SettingsBaseModel], @@ -675,10 +675,10 @@ def get_system_AB( Returns ------- - omm_system_AB: app.System - omm_topology_AB: app.Topology + omm_system_AB: openmm.System + omm_topology_AB: openmm.app.Topology positions_AB: simtk.unit.Quantity - system_modeller_AB: app.Modeller + system_modeller_AB: openmm.app.Modeller """ # 5. Get system generator system_generator = self._get_system_generator(settings, solv_comp) @@ -740,14 +740,13 @@ def run(self, dry=False, verbose=True, smc_comps_A, smc_comps_B, smc_comps_AB, smc_off_B = self.get_smc_comps( alchem_comps, smc_comps) - # 2. Get settings + # 3. Get settings settings = self._handle_settings() - # 7. Assign partial charges here to only do it once for smcs in stateA - # and stateB (hence only charge e.g. cofactors ones) + # 4. Assign partial charges self._assign_partial_charges(settings['charge_settings'], smc_comps_AB) - # # Get the OpenMM systems + # 5. Get the OpenMM systems omm_system_A, omm_topology_A, positions_A, modeller_A, comp_resids_A = self.get_system( solv_comp, prot_comp, diff --git a/openfe/protocols/openmm_septop/femto_constants.py b/openfe/protocols/openmm_septop/femto_constants.py new file mode 100644 index 000000000..69356b699 --- /dev/null +++ b/openfe/protocols/openmm_septop/femto_constants.py @@ -0,0 +1,49 @@ +"""Constant values such as common force groups and names.""" + +import enum + +LIGAND_1_RESIDUE_NAME = "L1" +"""The standard residue name to assign to ligand 1 of a FE calculation.""" +LIGAND_2_RESIDUE_NAME = "R1" +"""The standard residue name to assign to ligand 2 of a FE calculation.""" + + +class OpenMMForceGroup(enum.IntEnum): + """Standard force groups to assign to common OpenMM forces to make them easier to + identify.""" + + BOND = 0 + ANGLE = 1 + DIHEDRAL = 2 + + NONBONDED = 3 + + COM_RESTRAINT = 4 + POSITION_RESTRAINT = 5 + ALIGNMENT_RESTRAINT = 6 + + BAROSTAT = 7 + + ATM = 8 + + OTHER = 16 + + +class OpenMMForceName(str, enum.Enum): + """Standard names use for common OpenMM forces to make them easier to identify.""" + + COM_RESTRAINT = "com-restraint" + POSITION_RESTRAINT = "position-restraint" + ALIGNMENT_RESTRAINT = "alignment-restraint" + + +class OpenMMPlatform(str, enum.Enum): + """The available OpenMM platforms to run using.""" + + REFERENCE = "Reference" + CPU = "CPU" + OPENCL = "OpenCL" + CUDA = "CUDA" + + def __str__(self): + return self.value \ No newline at end of file From a7d7b2e48e27f7afd6d7cae0428343f28c4725b4 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 17 Dec 2024 15:24:27 +0100 Subject: [PATCH 115/163] Update tests --- openfe/tests/protocols/test_openmm_septop.py | 263 +++++++++++++++--- .../protocols/test_openmm_septop_slow.py | 21 -- 2 files changed, 230 insertions(+), 54 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 16c55bb47..7d68f8263 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -1,43 +1,31 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe -import itertools -import json -import sys - -import openmmtools.alchemy import pytest -import importlib -from unittest import mock -from openmm import NonbondedForce, CustomNonbondedForce -from openmmtools.multistate.multistatesampler import MultiStateSampler -from openff.units import unit as offunit -from openff.units.openmm import ensure_quantity, from_openmm -import mdtraj as mdt -import numpy as np -from numpy.testing import assert_allclose -from openff.units import unit -import gufe -import openfe -import simtk from openfe import ChemicalSystem, SolventComponent -from openfe.protocols.openmm_septop import ( - SepTopSolventSetupUnit, - SepTopComplexSetupUnit, - SepTopProtocol, - femto_restraints, -) -from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close -from openfe.protocols.openmm_septop.utils import deserialize +from openfe.protocols.openmm_septop import SepTopProtocol from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference -from openmmtools.states import (SamplerState, - ThermodynamicState, - create_thermodynamic_state_protocol, ) - from openfe.protocols.openmm_utils import system_validation -from openfe.protocols.openmm_utils.charge_generation import ( - HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA +import numpy +import openmm +import openmm.app +import openmm.unit + +from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close +from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory + + +KJ_PER_MOL = openmm.unit.kilojoule_per_mole + + +E_CHARGE = 1.602176634e-19 * openmm.unit.coulomb +EPSILON0 = ( + 1e-6 + * 8.8541878128e-12 + / (openmm.unit.AVOGADRO_CONSTANT_NA * E_CHARGE**2) + * openmm.unit.farad + / openmm.unit.meter ) -from openfe.protocols.openmm_septop.alchemy_copy import AlchemicalState +ONE_4PI_EPS0 = 1 / (4 * numpy.pi * EPSILON0) * EPSILON0.unit * 10.0 # nm -> angstrom @pytest.fixture() @@ -399,3 +387,212 @@ def test_validate_alchem_nonsmc( with pytest.raises(ValueError, match='Non SmallMoleculeComponent'): SepTopProtocol._validate_alchemical_components(alchem_comps) + + +### Tests for the alchemical systems. This tests were modified from +### femto (https://github.com/Psivant/femto/tree/main) +def compute_interaction_energy( + epsilon, + sigma, + charge, + distance, + lambda_vdw: float = 1.0, + lambda_charges: float = 1.0, +): + r_electrostatics = distance + r_vdw = (0.5 * sigma**6 * (1.0 - lambda_vdw) + distance**6) ** (1.0 / 6.0) + + return ( + # vdw + 4.0 * lambda_vdw * epsilon * ((sigma / r_vdw) ** 12 - (sigma / r_vdw) ** 6) + # electrostatics + + ONE_4PI_EPS0 * lambda_charges * charge / r_electrostatics + ) * KJ_PER_MOL + + +@pytest.fixture +def three_particle_system(): + force = openmm.NonbondedForce() + force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) + force.setUseDispersionCorrection(False) + + charges = 0.1, 0.2, -0.3 + sigmas = 1.1, 1.2, 1.3 + epsilons = 210, 220, 230 + + force.addParticle(charges[0], sigmas[0] * openmm.unit.angstrom, epsilons[0]) + force.addParticle(charges[1], sigmas[1] * openmm.unit.angstrom, epsilons[1]) + force.addParticle(charges[2], sigmas[2] * openmm.unit.angstrom, epsilons[2]) + + system = openmm.System() + system.addParticle(1.0) + system.addParticle(1.0) + system.addParticle(1.0) + system.addForce(force) + + distances = [[0.0, 4.0, 3.0], [4.0, 0.0, 5.0], [3.0, 5.0, 0.0]] + + def interaction_energy_fn( + idx_a, idx_b, lambda_vdw: float = 1.0, lambda_charges: float = 1.0 + ): + epsilon = numpy.sqrt(epsilons[idx_a] * epsilons[idx_b]) + sigma = 0.5 * (sigmas[idx_a] + sigmas[idx_b]) + charge = charges[idx_a] * charges[idx_b] + + return compute_interaction_energy( + epsilon, sigma, charge, distances[idx_a][idx_b], lambda_vdw, lambda_charges + ) + + coords = ( + numpy.array( + [[0.0, 0.0, 0.0], [distances[0][1], 0.0, 0.0], [0.0, distances[0][2], 0.0]] + ) + * openmm.unit.angstrom + ) + + return system, coords, interaction_energy_fn + + +class TestNonbondedInteractions: + def test_one_ligand(self, three_particle_system): + """Test scaling the nonbonded interactions of single particles.""" + + system, coords, energy_fn = three_particle_system + + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=[0], name='A') + alchemical_system = factory.create_alchemical_system( + system, [alchemical_region_A]) + + energy_0 = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 1.0, + 'lambda_electrostatics_A': 1.0, + }, + ) + + # expect lig_1 + solvent, lig_1 + lig_2 and lig_2 + solvent + # interaction when + # lambda=0 + expected_energy_0 = energy_fn(0, 2) + energy_fn(0, 1) + energy_fn(1, 2) + assert is_close(energy_0, expected_energy_0) + + # expect only lig_2 + solvent interaction when lambda=1 + energy_1 = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 0.0, + 'lambda_electrostatics_A': 0.0, + }, + ) + expected_energy_1 = energy_fn(1, 2) + assert is_close(energy_1, expected_energy_1) + + # expect all particles to interact but only lig - solvent interactions to be + # scaled + energy_05 = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 0.5, + 'lambda_electrostatics_A': 0.5, + }, + ) + expected_energy_05 = ( + energy_fn(1, 2) + energy_fn(0, 2, 0.5, 0.5) + energy_fn(0, 1, 0.5, 0.5) + ) + assert is_close(energy_05, expected_energy_05) + + def test_two_ligands(self, three_particle_system): + """Test scaling the nonbonded interactions of single particles.""" + + system, coords, energy_fn = three_particle_system + + # Do it the openmm way + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=[0], name='A') + alchemical_region_B = AlchemicalRegion( + alchemical_atoms=[1], name='B') + alchemical_system = factory.create_alchemical_system( + system, [alchemical_region_A, alchemical_region_B]) + energy_0 = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 1.0, + 'lambda_electrostatics_A': 1.0, + 'lambda_sterics_B': 0.0, + 'lambda_electrostatics_B': 0.0, + }, + ) + + # expect only lig_1 + solvent interaction when lambda=0 + expected_energy_0 = energy_fn(0, 2) + assert is_close(energy_0, expected_energy_0) + + # expect only lig_2 + solvent interaction when lambda=1 + energy_1 = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 0.0, + 'lambda_electrostatics_A': 0.0, + 'lambda_sterics_B': 1.0, + 'lambda_electrostatics_B': 1.0, + }, + ) + expected_energy_1 = energy_fn(1, 2) + assert is_close(energy_1, expected_energy_1) + + # expect lig_1 + solvent and lig_2 + solvent interaction when lambda=0.5 + # but no lig_1 + lig_2 interaction by default + energy_05 = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 0.5, + 'lambda_electrostatics_A': 0.5, + 'lambda_sterics_B': 0.5, + 'lambda_electrostatics_B': 0.5, + }, + ) + expected_energy_05 = energy_fn(0, 2, 0.5, 0.5) + energy_fn(1, 2, 0.5, 0.5) + assert is_close(energy_05, expected_energy_05) + + def test_two_ligands_charges(self, three_particle_system): + """Test scaling the nonbonded interactions of single particles.""" + + system, coords, energy_fn = three_particle_system + + # Do it the openmm way + factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) + alchemical_region_A = AlchemicalRegion( + alchemical_atoms=[0], name='A') + alchemical_region_B = AlchemicalRegion( + alchemical_atoms=[1], name='B') + alchemical_system = factory.create_alchemical_system( + system, [alchemical_region_A, alchemical_region_B]) + energy = compute_energy( + alchemical_system, + coords, + None, + { + 'lambda_sterics_A': 1.0, + 'lambda_electrostatics_A': 0.8, + 'lambda_sterics_B': 1.0, + 'lambda_electrostatics_B': 0.2, + }, + ) + expected_energy = energy_fn(0, 2, 1.0, 0.8) + energy_fn(1, 2, 1.0, 0.2) + assert is_close(energy, expected_energy) diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 6d33a9fc4..35f1aeb0e 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -4,17 +4,7 @@ import json import sys -import openmmtools.alchemy import pytest -import importlib -from unittest import mock -from openmm import NonbondedForce, CustomNonbondedForce -from openmmtools.multistate.multistatesampler import MultiStateSampler -from openff.units import unit as offunit -from openff.units.openmm import ensure_quantity, from_openmm -import mdtraj as mdt -import numpy as np -from numpy.testing import assert_allclose from openff.units import unit import gufe import openfe @@ -22,21 +12,10 @@ from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_septop import ( SepTopSolventSetupUnit, - SepTopComplexSetupUnit, SepTopProtocol, - femto_restraints, ) from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close from openfe.protocols.openmm_septop.utils import deserialize, SepTopParameterState -from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference -from openmmtools.states import (SamplerState, - ThermodynamicState, - create_thermodynamic_state_protocol, ) - -from openfe.protocols.openmm_utils import system_validation -from openfe.protocols.openmm_utils.charge_generation import ( - HAS_NAGL, HAS_OPENEYE, HAS_ESPALOMA -) @pytest.fixture() From ac9f1a8621b568780aecb885fd778b1fb0c1e89f Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 19 Dec 2024 15:37:25 +0100 Subject: [PATCH 116/163] Add tests protocol results --- .../SepTopProtocol_json_results.gz | Bin 0 -> 1970885 bytes openfe/tests/protocols/conftest.py | 14 ++ openfe/tests/protocols/test_openmm_septop.py | 234 +++++++++++++++++- 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 openfe/tests/data/openmm_septop/SepTopProtocol_json_results.gz diff --git a/openfe/tests/data/openmm_septop/SepTopProtocol_json_results.gz b/openfe/tests/data/openmm_septop/SepTopProtocol_json_results.gz new file mode 100644 index 0000000000000000000000000000000000000000..192a1640244710716560efbf9f2ca5b579e8c461 GIT binary patch literal 1970885 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�F?+k<2@(Lo5s+?k^SR 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�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
    8xG^V@jKR*>X0bX!7c0*#AenSW;!djdS<8 zU`+!s^egh&xyZkUs5`LjkdE=Xb5ojC?McA@ftv*t~u_#?z%0Z|O zhnrp|++~5wx{c@eQ~v$0vouJ$!PX6{E zv#zxaB}UegcHu--EhpOcWJZbZZ^(G8JF^K!_$C$WK}O1;@cJWO%?sz3x;Wcv8!Hp!hb6gt&8OE$VrJHO5nCC`EK zlm++xle5{1OcuRAk|?EriS^Ct@|Gb(qk~02-_I(wIsFDol$g7}%%*Vq;)T%7jLqoM z*K&tO@~Gr1w|DfpDe5kC_(w&O7t6*c_4)C6fojdTtp6XEBKvvz))*hcOjNU~+(cngWq zvzS=S`?v*lA&nYK6cxEw6SHEXMdlGtYw>r&=*!o~BUsFXT{xf1z?%^Jscn1Uk3g2V zh)5BYhMnJ~T)yk~`GUE}VD~K*#mK{G*-<}az9H5~Jw6aMu#$3h6z;KBWautZ2+M0( zsATf3o9%+kZ`;iFxj&KTm^D_v%G6u_X}%Qxeoc4o^nHqK9ycJ~m1i$iwl{zblr{tM zS&V)+IB7nRS7sOOXMAdK4rAz)bs&28sCwl7J>K?tuoW%%VjoS0WfYcyRhDHmTcmGg zo>GxxcU>@xXQ}zd$xt`m`S`?|QZRHkV(pkB5*aaU{6bG=F<(L6Cw2Axi)%O{)PFvs=gbRaH!=@{--2i>U)hy*SBs`c z+cSYpLq~=vX)fIk67D34G79R{xrkbmU&wxPL8g=x_lH;;ezRG`I)TO~G%6N418W0?FD8K?X6 ze3CgIc`8`H0{0W&Rv(Wa%_)w5L-mm~LFyUrd+<}P!GZo`xcve7a9^(UgdLyJ!hnmo zHAy_W4J?kVs3))UDz1Ruu=tn<#fI#dgjl;}K9x&DBCr@wR|KYd>qu|9oU#usVISK0 z+`nYl`l5b>eC6&B3mK#BNTVrD*dmMaa%B=lhKt(#z^B3mN#p!kqIz_f!=_tdR~Hpf zDg}CDBD#ujpjj-;c`s!39{esn^;l;I_p9A0rt?w+^HRp+N)ax(e+5crvpoJ8cHJOY zf;YD22ix36&|LzgYD0@!z)HT%Z6K4A8B8*gfX}h%ugP;ToS3cVHQ+vm<}Nj#IPt#dgL!4|YUFCW1Ruwcwr5)mMwkq&dtoUIh3 zkJ-g9rTwWgB+IQ9Mk=3nO0h~#Cl(JnVSa=v+Valn}ZpT5K(5=$1}l^I|`^L%xXhT?6o9nACmL?*!IBXtXN zSlv-3L4bsrwscYMBDy;fZ5dlFCYot(^JCn``h0(RXqP8-ORNRZk(@IicHCfbAFTNe zsWFNBceRMITPGe=gnK)S098P$zYbj+5%M8?O1Dz*Z+c*&1cwEjkUGTjJxErKJ%{oF zrx5jjL{vTt6fZzBLu@v=^d2{FtpDLw(R5d^Y&35A^tsC&uEF^0j)55{SF({fbWQri}s+}M%_M3 z09f5j6|&$8+f~f=&2WCyoB*QYPehcJ5bOFqU*;1^Pl!!b6rh0m{JyoXqq1Ld+V2*G z=xD&{izDR1KYTooa4*n|>lvSCW1zV#T=}fBHqr$59SaOFWd0F$Nb`=UnCb6+CC^DB zLyOgseM7rn1&oAUXAJMdc#` zw?v?gjYTuIMumlQx|gIOO=2}T8;K%%c@VR`9~@`~FaHNb=JaDYXw)cCbMDla?II-i zE{OL^unRm)kD=}_*|YE8NuHCec#1lzM!ZLEH^}*ARP=6qn|#H+_ftoe`Sgg9$)e~T zf_wdhsQl&2Hj3tBksjCNZo*^WmHBgx!Tg(0b6{Oqb&q}xZy$HD+9U%@XdA=iv3$4r`P6OWxv@b{wIm-_qp%?h#Z5J4ug3=}3 zH#2WN65E(NuUVtBVVB9B_eyVu(gMQ=g@J@wp{h?g>S1qUq`Vbt2odcLPmnCCJ&T@|{(#Ut5-wmi>p@Liyp zN|L{J*bQ_9rxx3N+uO_k9;r&UjAc)7oQ>)n@b!U;4q+SdiG`B;#-c?WqC!|zjuhS2qbuu-;J1id-sUn1$+EE$dj?Y_ z{qE3TXZNry*ep?WUkcMaLB4#!D7=^1VD+8YB-ph7$`f;)9dtj9x7$Z(3RwJDAjS-NVYSir+D zKJys&xK)FB^1o{PFXck|2ZDH-v3!Kv$0EL|7e3@qgJfS|jrlx^Y!#UO(O^LLm(|lV zm5qr7RWz3?isFr$x}EjorZBAMBA#TFdo&U`54M*~r))O``cxiaf&x#SGN&e@g5-&q zGgIQfIpy~O^}1f*Hq(?8FLB0MJpb<5bcQIR$fRdT6ij8Qzw+b_84_%mgVN9x_hpex zs_*;<^T8_(Es1+BBWE?vMX*j8zoHLs;9Lf7<)8ZDZ1wZ@^NL+Z)MXns z{}RJG%mDc1T>8*0g@D`7ic0(cDAJX4@!wwJpmN{uL8v}TpNmjk=)W(7SvVdVb49<0 zP}&Z&gB?tVyoBf2A3eZ_Da-oBxk|@sK&G~7Pvbc>%Ko4BLuQ3Qf82zDZu116fIODc zsAsYZXyNORxIl`qVY78jJ@on`@<~ZsUBH;3h_J#j6LYQf>s@;rlR=qp;HudnIC%kP z>HH0kfa!b=CovcXxN0%S`nhUUyDDQdO#}>tuxp~r{AQ(h_%)F}0RogaS1H~{60^u6 zC3yPuvaFM&(pkoR7?4`rX-04=f7E=9O4N6eC^Y*?22MvjXQ;TL&l9ZmS* z)TqhX>gL2GeuZUX~JBdGa?~AuFQ!&kNay}0U>$GBp^FvZ@6t9W=9R_j!0f=qK{+yUJPSZ z=;3JlcHse6zusrwb-S#%R{Di~#7Fy&#Bj)w6*(Ab(v=bekESnDcQOSQ;bFOwCnnP| z`5G}H$-qj{US=&s%D~EN9xmU?BQ|-7VwH1KTbFg#$Dt2PV+lXMGL)f-{}qhzQ`lwPn{f$^bNm3_s$A4WYHQj^v^%Sa~1a>%7!4_ zEA#6Q%Z!Q6K^?jNcxIajzra+RCGRZ;Gc+7wUlP^H zQ>JZi?eLs31UO?iq;8GU_yPu>D2u|Q!~}dj5LkmM(kPGyTty0cMBbT4*~w8&bD|-X zKFX~%ANfB}Ql;aB;yncioqpouk6;n3E2x(%$moKDM;AL=HuTfTUQ@!|7wec`O6RoOKm*Q+Q}8loB6?aQ++%MkeRtf1 zT{YL4ZS95IdiafY=dT>Rp)dWV#=9+{&=?_%phY10uC8&GOXP9xLG`~I~)J3 zgqyLCf&}#jJ*=*;We`fhRD%?<(4*ydm<`?#4~vN`;Au8LB0yJqr#}^WOyK|aD^m24 zBbOdM14B&9Uq{}+qd=33BIyzCjL>r#g}5)Byc7u$m4Tyl!p1;5DVg_amj|OR=3apj z@2{+by{TonlkJeX8<073D#?cyC5!I-klVy+1-98SYvMY@B{Hgke1TLPuXZ6ruMyQo z3fC>GWm5)_#QC~ESaoLga@3CR=}VD%#XT>+sxflNTg1Jba}L9IM5;-~;f8}n)4U{m zHbP^5A(C04%n(4By0+BKpA_|ilR5_-&?Z}`4&ywkVgg#w?tU;XOFt1ZN}VEmJ!d$Q z7JE&OtY*B)hvvlvS42zmLeSD3IrK|Gf z4TulA=?dn4CetuAreSEcY$074%#>%7<4Uj)`ET%y6cuwCdpKd=PV>pU{x@Oy@B+p;s$Xulx^^>JVM3N{t&@tK=MVdA=66|=-c8o$+F62uIZXKO!e;Z7ASSV zbObf2-k zusf?)KNPiQZJ+ZFqcd5wq0Zf#(I90V+A9zbJ}Rj+t(tn7*#YJn3%9i|@KT0L8jR!; zqR}zmkCAMHboJTT4}KX^KYJn5@g9cmAc`Gf*zy1CZpWY9UZq~Y4vy(!1pxH#oJPf}LtP|P8^#^!~6oK^MqP2v-~4NTk3 zc$781Gj}n3IL1x~2HHm}C{WJf5%xX)KoaT9v3d-wR;IC$quV?RT^=epZA4>5V@(0F z!1)P}E9OpkZN!Ew484bjmBy@IlTEjUBP07f4Fw|Pm+4@>n$xtZ|D8ym=u*X5n%shg z#-o~vD{Nm%-{bZW6kMA{)!oUxs%jf+>=x#!LIQQy1S$8-1o<~e?qWECQ#<8BK4Ge2 zOE`-eOm}rWx0nDc7ol+xJMQ{W%{@YDNzWd2<$Rb3*0{d}Z0!Vb?5F{``y&RG^f5O> zY@xcE{TLG{AvYVLe}!cRl|kREm+PeqH0-@#)PA9eUW8{e2`6oZM9=3e-S@Cxsm@*& zb0F_DyVbX)!EpB!djT@!=kF-qDn4o#LJ945)%QqZKbT97eFrSmY~Fc5VY&xNk2FqG zWu16>5FkUg_LxeZ95FZ|?~70xgItaeBDA*RuyH=X`1G;;w#Uh)TX~V2qgfzF1qmIu z`GOwC?kAE2F^F!CQ<~^MIo zH}?O)Yu#UyINt3tLuot1s7c+(@%ES^PhNF~fSSatJYG>X)Hu*xj zK0&^9Rm6>36R1Q|I$tj-|4`2!(R*;3j04HN5vN5?;ow;Kxt9Gv%$wjM)t8tkyp&v|1A}CbE_!Q9n;DA z%jQwk<52{L4Kj#>qxa1v;qs8@n+c>R_ply%GGN$jHj5RY&)W+$DETW4uqnsd{NcBFc){5!B@L7v_kmu0_aBVi zGgx0<2;7Xg3`KAy#~sGqhbcL&TT7c@x1gJ){%ydeIwNL>PtFq4%23Ln6 zh$M!pSW<@N8oezjbN&ylc1rhgL#n*3y7)GXjisOQq%{>gZ~Tf1SNi5``_t%u?mmmy z0(L|V~VGE10> z1-3MZX?hy$n+!$meklZiu*PYDd$pK>V7sg*tk(qg^vDMMI{7O^;#oP&EXPw4p)602 zX;Ixz?{fXeLn|F~&!mm6d6jfgBRghQw9!Ov!XJL+dw;5%vB4Hw`Y}SB45e#$MzI$0 zZO|mI9eyoDGAq4y9}C!geL|caL3zZ27}5M;MvGM}ww~ISy;nQi1q9P<^kzilD$IYD z+1Q|)XI_c*MpJA{P2NG<+cLWwWW#`9(*(o#L3&$mI+a=p_965*Ng~FE;%t>{qtZw7 z6PH2Mh@DOl7oV%1z>4A;HleZC_AtGU{pqo#@&OO>U4iHni_)~=g41W|c{|qTeuZHf zwsE?}Zb#lZ>Ls)yotK`WJroxbmbnn%vTOG>`Ym&1aLO*WBJ0J%Xux8GY5YL3$cWkE z-(650DkH#>O^F?m(QEL>f!Wxn878_{WLUZYAnLD=68<(e8%`SgWhlC0&dc3>6UCKd z-)kP=z!FFXq?JZ4CLTL#U20zAn~GTXDGl!0xAEAwb*`yL#&>$Ie&KIavxL13{p~np z1L+`XIQ*c}D3OmbHbu!Kph$vF(Z;L?*P(ljGt<>M&{`)0eZkaTKAIuK84!2VPLz)1SmruM59W7 z?Nz#`-Y-V4y-Fr!oBur-Tg(BtN&2wUJI6!O%n0?vfqjmItGbSK_`5Ct!JuuN{Iik-@s+_U~@hs5Q&(70L z66I7_#xx66ArF-waee~(>E;Z5jVaI$Dv-|P9V=W(ht_pH#Ao1hkYuH>hP{ee~p z%dg~EfWv7#4>b$P&lrKy6mfs!(%Jks-kH($Jm?hi8v%4%lW(}c)Q9OBf%|k^OIvKQH8Y2GrEWpjitogZ+bsLJ9LD!x%)U{wwu-R(AJ~3v7{NIvCnXOPFTU0 zX}siBm>_jVJP^r?Elb9@W2#^K38T0yV5_Pk{CqA3vo+}rGTBVAmEw^wYMFkN2wb1R zBZonT9t#KdTV5qeB1KFFh6;NL(pi;Bj_m|!2z&3cQ6?%=Z{-^D&{KdE9+ugqH1v0< zVPQv|c*Jso+{BMZbdc>D#7K{2^rJ=r*<+ep`52|}ZZGl)s}!d`*sLz7RwLOs6{%~89XJ@zX$ z;m5_|(4>Cd9AxK>4`dByy{&S<6K(gGwhH=ujt3GYxx|2qid1&%iI7GY20xL2m1kIa z+z3Cz5A6q3&uT`q*=-B!n=z`v-pGtE*N<#4#dURR^dsGm+d}%K| z2R&May8qzmT{cQvpG`j^!Y0@;@b@t4N*hd_x843Gf{D>UAYQ3c=D}V95irrDJ`cIb z-^Stf^&sG!WKm`oAO?)1vP3VR@#y#cIoksM1Br!MaO9#$XMGLb$Cu|c&cKX42^D3e2DDW(DJ>Z=b_JB{ZQD&rk6vWOnFxht*BR2Y{hX3p|&j z3u0RZZ%v$DWg`z`epQX&BC2L@whA%7>JaLryxkc8P}%g4B!jD|x6UA2xRs@7aPdrt zN+!Wijy|8r^lXTN-CL>%*gf$=W7?K(_jcF=LZcF$l+W|3zkN`~bd#LEl?QR|Qn^t% zpB1Lnm>=*M-$D7W7xvI8{dXz}_&_GxitiL_A6P-o0Zas&eFpjno@g5=ha(0IS<9p? zp5^E(4Mb1fwDqG#EFT2zBU`FLk7i79?jL0<_8}@ZA+~Fya0r~;8rf0Wp_@M^4@1lZ znviP0Qn`<{CkQpLt(HO(wYZTG%;{g>mW+8$W*cNZ`ju3I-x#zU1G8fhPsV_g&+50_ z8s*Y7fZ35@eJ4O6;WB~w=JGjgj=o+V^FjhZhTAF zBZfT>~IunbB0MD3q{QpHzJ z?t#tSY(c#H9<-=j$CjvM6~^GAS1w|){USY)zsKlEY-xsp*oAgO3yC%zLas4{oKCcR zXHxcnIgMS9mwpn}8(DXW9EnU_@*eH;Q76{LD7Uhm-#kk+AH=4Bq%yxKrp$Cd(S8El zY_WLZrimvbX)Zb$yhfk9Z~9m8%gRPr<9%oI0}LU{9Mg3cr9Vp3ne`gc16$s`rk<+3 z`_&D8u;>4g2*xDLnFNg4kM9(-r*i~$G3L5{9n{}C9P;w44Q_S630?e>F~w1OSnTEm z8uIDw#Lzy&+zG4qb8ne<37Fs+ndh4d2`rK=6wy$h+VP+qffi*#NUWwA&Y9YrV?#~A zqJM=`K)6@R*;$+Mq(`9|@EmOphBCP1qbb^y%tO4xazgsGOo7QK=U}gSV?&6~$s?X^ z`_ahW7?mb?^|ga*p-E)&V9i4b`lHbV<5x~JO@j!6_s3EVbzpE{e{3Y=&MV3O67908 z4?3h(pa6fj^K(uM=(Pp$N*ZPN{Z!%phh7ybHeqLjWa71T4YDsLo&V0yxhHPp{E{;H z%v9)hdxMMu2}2Yst{*5cKVlRvi#iggexjE<@&wR!_fB%cdn~awtoyD}u6-w5? zTnyD%@s~UhuJPEaS6jc?RS-VhTyaxsN zely^M?7%SRi*Qfv{QY9bDfgxT#_NA7 z`Dio;dbfRqyc?_=iu?cdQQA#y0$AKM0K+tox zFpFBN4AfdYUvPfhm^bC;xc`qdSLtL$(eCNsqESaISn~}I5p&`@0gM6ccU88sDnI$ zrrKc}g;D=tN{H39C&oAyy3^ihG1p(z=6(Fq$!O21`F- z*r!t@Gl*D=tivXzphn+_LO0GPo{Ulid^=VYbht z1)R#2I4+LAtO# zyRo6ut*PJ|1v5P;uw&Gyb!(mmBMkwJWQP?|IwiQ9r5{mm*j--`?RW=|aov-4VTK)x zh?dV~8?=R8>O?mLd2s2$12*(-xFk7q=SrDuOvLjX_Z(OF^>`lD^II}(6G}yG9 zL6pAns8uu3P%P2@Rf&@iVM(`#Ob!7punogwK-P7a|X4-frT0t-z8FIjx9emmnTP6}ix|ImF zqNU2wv+2&3rjI!wkC|EMF<=W# znj31Ci%O^W{iN)~YxZEGS3y_EE102m|9yFwPS2c2=YXA;a#T+duc0#*U!p}Xk08Y= z!*XFJuloR=uyGF9j064WtE|g#7w|AWv&vIJ z_cw1}`pFnk>AC;Zcr9!TaURR-Gjpj}_$ytz_e0`ZZ#xkPTp2H~*@;Xya4ax08M#_~ ze-q7}W!Ee7NJa;S=6Xu(MVi1$UF9`P?}0`nYSA&;Y3PRgcoIlmWAUfL(QG3PDjE94 zb$>*~sEQo3pW3l2rtXA%c_Y2N9o8ta62JiiBPMy$FuPv;&xtUcqNp1S&%VlYv>EZY zpB80D_94VI+4aMXB#Trb%+pQVCA}XOkRa;IMnvm;+|3dH(RK9e7#QO{wD)Lpm75g_ zx;E%o&|V1F@%1U7`$a{~g*t3_3(HmZFy;gtYpBv$uRPr47VNUJp<@H>$L3j$ZE3GgcL6ig5pRVGTg4&fIPZ!6cZ zz*^Dj`ArJLZ_rGwm+_aH`A&hBH~Vwq6K{qW3_z~{8-?D79`+msCfjoxd8liwYBbq_ z@4#%+K>0h>2wdfNiio!mzQY1$+Jxbi^NQBZd?4c=sF?qy8}{|GMwlvzOBNw6xj~%us~bDGUrmPX47V7R%h+JcOk@6aL-RuYF+l*? zgm8}Cx7!b!LR#jsW>1WHYKC2W>%RAoFxy||VYZWms(AICm>XNS2NrwcGZ=aPCd;~Hu74vj>3(?NI=}+IytR#2Gy1&)mGf+hIQwL zUEegW@%y7G^K&dl`qqv4uCn92r*TUtnvQemwvckpY%N9%<1zPZH&vn7AUYG`fn`OJ zSZ)kRZfV}T+Yaroxapqdw^$IeN9lIBLhUlk>>u2Y;N#2*W>WO%Km=~5;zt?a=059Ii7gxYs%uudcl57+^ct=U zE^lGmG0XLBLUUnWH7$FG;H_J1Pr-O$H?UAv{X57-o-UYbH=C3etM61Py5}FH$)Pvb zp*CjR(*v07{m9vAm)C48mK)#_&%tfPBS&a9QOvIM@f6Kukp~8iQ5+d@*g84T_&2s| z@iweIF*)Um`?E;QIVc zX73kELw*$vO-8JnTug`*b+Njfb40^3)3#pUu&>m!_iWYN^tpbtooMB2U$=wWO+dnu zy!7TuvilETuMB=+tDvpGLLlmN9A4Ab=e@OS zo8v&3NN1?S`~J;M6!@^h8MYuxS#Z*A zpn-n{aKwK`!gssv1ZE+&oAg7kb|W|A1(xXp%66BWOp#rIqb>9fw##BL8?X(@-@K9z z{}&jSpxfquXlH`OvKIS*Mw;*>WZ0LBB2)uv8o&PL8C&2P+jnNN2+LMt_QpKFGKvfy z$;TP!;W}ROrGC-|3tX}QM2!{0n*QAhL@SI&NRPZ=h5awGsXgj9Ria$ zqj{P#93{!qY*-i6Oe>JLi4i$&xZdrXyrfQs`xjoBs;zBX@NMb;CLpQ^tG-hiW7I5z zQM9@LKfh9$(}ip;en-Vfk2>^NWbyK^WZ+3m(B^K|nd`e~eT)+KXRb^si<5;53gLk^ z;l=(w-i=q$*dd{;8Vy+*e0(UoQ7i4&SjE2HZj>lvng>hB3VyZ&QIR*#4e!qq4=uJT z9>pm=Y)YwOf%Wn96#Wv}f(XxTwn5+uc zb|L4LE_A}<*$kN-$v~7x_{Y^s{pQ(}f$1kO6P2;IWf_ffQ_0Q3vliP`V3U z+{aD9Qp|pz$gnNPvR+)7fRj8%V3B31*H}h3+TVWbn8Z`{rovBMpPQ(;ae~_(Yw~Ot=bAk^-(b;!`Lfp%oF&;6+fRHY((RIK z5gg}e>Qa`IgjOOHTB7@ee2N2h{Q)>C1bPLc&HDa2>bkCLT(9f^@T>z2NJq|&P{Xrm zCf)Z0QX)R%Qf&dmQqU+Qj$0iszm)7sD6*YWs_(pOuk!0FmCD+?L5IOwSL(1#c((4t zCkCr^)HTb*A?x=5W|d5gf7g3GVWmbBHXf*Ptxc|KqYgCC1 z_zddpy(d99#jAdV+RhTFm^kG4idP;wV=-#B=(Opr;+~PqBdicn-HhYD?%%;0upF9A z(UVnTQ3|v+(X~*<#+$&%A1PewhK&II1WPcjM{iJ|)|HwqZd5E_bp=64i6j>VCpr-` zKi>@N+|TedU?|xqGVElHYg70~(BSLmxT`4A43*ZZCoT(rM4D}}Hpb)!QPiYeV32`U z_}!>tPMUf-_0G7HDcaU6*UcT=!U1VdOq*h3D4A%oy12nYAq{!}45*n09U}RKZb%?h zf;UdSS0iw46kzhRVxF%xo_(Y1{C|k7q3vZQ_0w!`;3p!GaaZ}*6rr@`){PzF1_R#1 zCQV!fpwkr{w<^0TV4HnlHKuNOWg;iv))j3vmLq7KWj(T)OpJ9IlzlY;?s~L~`7<<$ ziK%ZX{-7Rrw7L7bkQ<8`qXP(t!B@HxU3$n3_>ZDaYp+(a9;`AiBJ4KJ{w!dIwdZiR zsw|vwi>|_GNa18xx7jzybY+0o#bjCIwdxm3dOcyiw^6k!E3oP7>(r8T<3{ITH`wbKQE|O` zgjy9{%M)f?7j0V8oPA5K5C-LcEsxN!+eb3%7J74iaxW=DclX8M+AyTR*w0VudYlHOyl9(D{ebnG#hPog;gqanEo*k3nE^} zyZ>P}VA9m?RX!zyd8(UWctg3%v6i%4Z<33QTI<7lmi6K-C&u$eoWp`^yicQUaS zSbcL!OrWAl9nbf3fw2Zlb($6xFIn2rc553U>2(L)CoAk~K3VIu zg8Nj^B+I6#(E*~V$>(d++Ra1YiN)3%tic&2Hb1yhDJ=DCqv6U6DL+zK*#E9nueK8y zSus%+1@|hj(oUt7p2<;SZm5fI+h2B{2xVSsJ=R`b8LDE_gM>B6YCD+$yCv6^F@e={ zk!aq)Ihg!VDJljR>{9gG8fc_j?4m_&UNXpr4A4qUmLiTC6SY1|w$K zJ$VV@>C(GzETlxAGB#nq6|4B9u95JA_QfqH(zgChCHu?DHvYncHdzYLl>Q7dSF&y< zvdsD7|0ui82D@pd`&Uv(BMGr@mA86J5<(5Vh2jc4K!6Y+K;XB(yVmI5~22BWcQ+GqThg2X`(=$aKuo{uZkp%o@9D4Jz98gDyB5O%UpAK2!DASZk|_IEOi0 z6{c}pjK)ce*PfyHEEeCbcG7u|9NUnZGge@Io^~$sW>>N1=g3maN$OIU^6+lGD;EI` z(uGD9EWhhewH5xmIMZtL=D94h%V5>@3XNK8f9F{-5y!ui*e`yjWbjE|r)uT*|F*KZ zsZcctxswa!@RT}eXTrAl7m-D@+ERvX**;CTYsQZ@he%XH_EdHpNgS;E-4ddZ2#g#1 z?j3Tra{h_c)Rw?nMTI7O0f&Og*wR%?GfP@w^XrJ2T5baiVqR1$4$vF^87LAgWh=sE zqtRTel5MOSI}zAfj=L};%pR%TBGFk@9$}sHbvWn82TW54P4{9{2ig`eVupb18xd#c zuxF|)rrC4=iJ!NzVwmI6E#?X|E+ zcJ3_?*R!e@YlDeA*zDImO&bknyo=RQCOmqOj-)Kib@E_V;)uPp5Px+B`vt17=DEt?XIRH%1}t4W<&|Fb2TH?ROJP!(Tk+YNm(=*hlku?^yASVd^1pUVFFws>ogw_x zOrF#$c%q5k=;yAa2n2Z*RV;Ty=9|MIY6+uqW-*b-S-54+P1>SAoo!b9EtED)$v=}x z_*}(l#MjUm36Z2`4!)pMe>$)jvlFnxv2$$YesBb=;m<~dnImWxVX~i^rfjM?>+gY~X%Ekw#JUp@S11(U&?_G%`NAdXidj+c%cB11FpPKbL_#U!h>9ni0^B{VgD zUK2I8(X~7FED!$(9b?&)9>ON!m@EsMjZTsYRR1wCEsf;jxCqK(0pt#A3h-~v;kc>qzwP*wF8n(N=847GttAY(Vn#@zhk8%i5dqEzN;Hi)Y{gP72 zbG+2>>H3i}Yq3ts@`UpSHk~rc1F)Y3Cpw4TA@fhZ#NE7|!As8W;rSL)0wn>Ej zSeGhvJbXNqTd~r}uEv*U8|HuO(qxDWbZlFXHy3dX8I))1bf}@l)CuFb&oU8jqyN{s z1)akPIPXe;j+!nLla|4{vl22PuvGJZXxb5Id^>X&@`2ZcW47x_h{WF z7VCY9^fIP}TT@q9mcQpe!9rtiiWjW94n4VoW2R}M_h90QY0|G&UE*ds#;C_QN7CdlgS7nq>N17E1<5ACVjEV8xz@F`!AlS?pUZB*@J@84kOxsB zyQQAm5xWn)TuwzEzunGGEFOv!v0HAqFfI)rS(bLyPa>ROO&uM>&)K5njA*cCJiYVS z&^S3nR025{d5=fCZ}^CxDZHps&1I%eR3sG}Q!Qn4*;owq@a~+VM}}8f;Lc!$(j)2i zKJarn-f^b+t%iLMz;H2!Z?nO(Kg% zw3sKvhsKM;{=n_<5&=u)b*->`A8rkzf7Q9WFx9X^TV;1;wCuoY zr3ji8(KOiX(TrC%PKL{%L5IRvK#3h-FoHiLC={GtF3p3K`Y_#;$no490; zGA;Dj`vq8pD-deZ47hHWa^t(ejjxME(Xd*mwrRVOxhq1FNbMfg&1~k@38Ml7hKw3m zt4p-Nd)fxI{8(tvtk+H1DmK&;Cz&?C*sXrBXm9|g&(d=>*yjEbyq z`z6bJ_1Lz^GH$&%9g%(N)tSPPb})dVXcY>%8x<+FYZ8sUMtH$=wZ~W|{CkZ}>s>*0 zs{m#of22OwFL?Z0g;Kcy<}S)e{kswAIF^T*f!j;_)B!94el-~~>oU+4UOsZLN1<6Q zu0nKiVgQGwsJhv%0y*_XB6xQbk8QH~`m@bP?t>gF-2krW|ykO^&sG%r|GqwGvgVJPQXx-HL`4gTPjMnM8u%Zz7a1m%-?WSRqfww&~ zw!g_n4gau$I~DG8)-5He_|ha0YdgQ0-tZ(aLzqf?NF}dL;7G&)l1`rQcaj zfG_;wBe&m{sp>IGH-BF8!3P@BTOc?{a2BhOwr3l zDsR?h7PFPQ#Hw(KLDcd?G|?%E(Ymbgb;I@h84S`43N@p!(%81|`vr|z9E;#F+^ZY; zisL+11`28LL=w3kt~@~wIDBoPxUYn8h-n78I`j=!Qi_MaudZhFRbe;I4Jy* z;%YH#cKA9*Iyg730G6#-xU1ng+NEgGQ-N^Ue{0&R5ZgmggwY=|w^k0d@0Ye}jlzx8 z^1~xk11*>3r}0xaeHDk7)s!%JHQBnpDy`zm2KRwk{@$!7!h_XnZZF{%h&i_owmj&x z-Rrl_p zezc<+h&Hnuy}Jk~-;I#AN#na1y^%^^92LA+<2j}^DBT$-5Kp3hCDw?>i;K#T19`JW z85BJ$jNTv+6%k0Q-Ug2Vv zm2@&>md)scalM7D%e7_uUnOSyz@t82v0p{pHi5LjXh8?dJgWH*b{sPfKVL;2)V|1x z_|MT3u>u(9JOIPkN#?l8k3hoKe*bJL?=XBYc)nEWkE!4=VPoIDX~kn=P?!%yl7*va zay%`@A%t9<8$CosJeVQ6wgAD#ZM!sa(T#(t)v$)u#P+ThMLC|Lq6KlZ_^!YcE}gdN zi=9%h0Eh=TD{gOUD_`2R!-T_E7a%y%DHO-fOxn9UY4B28mwb=-EhOSOE<4dpZ1{uN zKrCL@g$(v~(_h<31Wsi#%wTnwO-=alR+)hxfVtLjg}T0o~U?T?-n-v(ceccFEkSJ>Ivay$fnLX&*T|VDFU@j(ly=UYbJEed^bb zBEI+0`m(}uO~{3Ac)lv>=`w2`iZ{@ge2SN@`thpUN z#;%DU4ryq*$5T@~G;g9IG%U+FaF#FjO>Fyhv~EwbuZSm9u#3WSvP zWdt+%!niH}0WnD=BWo>LheK9-H*bhkoBMG$jYthO9)7>DGc8miCok}9HE|g?cp0Ns zevR5XS71zm)3VUrRg|Y9+G|AGBnT{a&GLhGao{B=g9xh*P12Jr+lwkjhex#gFy?VA zZKGzY5~iEU6=sI1?i_%^sj$Y!sJoO{RLn|}?kzIWWXnY=@+svT-b7mPB_QCkl1V!t z511^P753U9#u^2Tp|%juve-ZiXfk%Mw5Tid9waBK6hu7Zw|d8`Ap-%m4i+~ZMb5F{ zj&9^X_Dpr}7klt!Yo%OR1B;ZZJDVs9xcUxWgRxu|0Y1Gkv%1wjW0&cB+(L83GKO~w zs|x>$$E~gce77dHdX}d^+@i!* zk$#P|1PnbJ`bBHydIen>yHGz!Cs$t}++l&HJU@h&&KapTGErErcq6o@CXl0D!^E56 zhIWbMFvN80W<``M@IPgi=-GA)>7SC7AN5???nYHsunKG*-G~j0UE%i~4P*Z-SHu?Z z^A|{pRJ$lmmL{)js4Yq7s4I}mZTO8eJ7C4TW0x$^X;6e(H(uz7X~ONB7T$n*81Kj< zAki>YwEh4&K*qlj#=5o;{zt$(R}Wuf$jLVg&pHuyxI(=IrWOr`IhQ8YMv1PevipeN zxgq$r@@BoX9EiMIR8?P!5PRkM4E6-)##^P)1v$EBG(7MxvT&#kTL{oeHR`N`#bmLs zZU{$MX5{CBGSMld;QXxL{+(loq?=n83tZPG1_#J3Y97gbdX#N}~>2MW)*><^fZKG67aI zWVfay7i(U`IsCB!J5C#v4kRZ$&=s{mj$q(WP8*nkZU58zeF@I*T`%E3#Z-+u+(d^A zV_Q0w5Ug_%{DlG(B7v&}vHU>%$=YWe67J9jpr%Z)Vk{n|w)K+xdK6O4=Qy>DE#?iG zWb0U|q@IhKlRH9m-RB`Rbg*FyXjBcd9gG>8~h0sgxPdvOuVU= zs%aSg(`D3Fm*jq(==fKxeWFS8Z*^BLb#1J^#`3qHq&6_&N{1PNlEH7>0BpkUPVGg<=yw$C z-1VYy_pq~XS00h9NOe-lq1FEv**m(C$Hlt0^8G$MVHQ;H`FOtl7j5G-m+j8&p|51P zEZ&7(qcD%zBy?i<*??kDNZH2xyJRlXjPJiGg&y8`1p_zJo|&*KcCOWRM_&1(nlw37wrb3A z<~@aX89i{D`4pH6>|{aQs2$vc=;ZF9nM`z}3lkX*%0Ppbzs(rsZrjOeH54oV20~2q zR(9rxP#!eYTn!z;(V0|Bcce{-3eY_R!4%ZJ&zJ5NBD^W$A?EC);h%xDNnvM_B z?;eQRuv&pEN8_DE8^p&;I1r!>)EU|AT~c7>0t+G~Dv-fb@T9ciy4BhFm9aiCHR^;1-D93bQR@tvFrWykK z!O1~MD<#p4woJWdfoGgHvocDFm9NC~undbTG`vK9CGT_e)R-3PpW! zkLG@hKr+wCf<>xT43{tc=o8ZjufWgAD|nJJd#zsH^;1N;RMjK-R=zI7pd@e3;nQ3+ zmXOK0ubV;`H~&BPfO+ltk}B~a0B=zmjqPSxsVTTb!^p{#kHQ@)fcx4V%171Ih>13D z8^3rmT=M|)54xnEV zF%X*WBF%{N`ZjYe+BKTt6hbBwVWDH2^{sN7Yx)TexhP#}TpxZSDXg#raV+6oA$d+J zD&*C}BrIwx*w0lP_LN*F@(fk(d*Dwt-WdeM(XiTOB)qpls;`#XNO)tBUXE@(#lSTT zdUliIOz+aRN(8G3H!x6{#st`Ws~Ni_X`uTMPU8@9J<1pMd=#izk_O4vx-bs*UW%(Vd9b-qX*4IoBVQ`!kx#WhD46>CsY`~z`iEKLz zb;h|2cZS^+;6^zC9=_+ru*=h-%JHtUuNZcs4BX1pcgS%Tg zT2uShj`rP`BUf$WWO;IhBF_A`UWMtkFi15jwO@ptbD<HE3pU@YNU~sn4fYn}p26_xx@4KT zTlX%o@D1{BvBh_*%jvLLmw|#))9HWm2;OwW&x#%Ddm*!~mOS*?p}vNncv^6912%bt z0YjFl#8w$5X#$h;mdr|$7=1)5%2FHk?7BYi?uuY$+TDOHs1Jh=FPF@0*nwTcOqV>6 z0uvgWT26cFA7-;#6MFHtNPb5x?WOV)vV8Yopv)rc^Z&={6}Ey5^25z)vcgACwCP#> z!>>{pR1JHF8fN$95y>qm`&M8j*sgiv%cV%)w14U6moDHTw*q|O)%m9vAF;F1QAGjj z!^%M0aIr-U9fOeG7Tp%8O5>>D8ZY{UehgpoXF#IeFsyC@o+D4B_~5@pU2TS?*ZjBr zJgMH;$XQy9x6F~e0ZogBsV69(Dp-HqF&zG}G`nTC?Tzh_yvMagh$4F_b%%fTqw~SA zZcCF5GWEs(33~oC&Fe`++X(3dI+B29^22dJx13$eTQB0RR}+god}c#tt|E4xRApws zZsFBAo1{oJv%(K##fIOh;K~?%_4AyDq~X(0n7^9E=<8 zf}wBBGAbp^FDERMJH_JIERf_sO&=#Da(x{7e}cX}@u?jA z9g#;f1!q3L-KSp0H%2fQ*wMtF^?zTcLLSbk%Dlwy+i;!p&$O3l%bhm7>6>c1UI!I7 zp_l#o58KgCiV96>`PP&Paxu>l%dB=dUe5c2~F`%A@n2Gx+W z-8_Ca3bq}P3dYZ5^mcj1@N-FnS3Mp;v=A~i_`dcaYb%qGp?DMMF>2;y78>|>@3O-Q zuL-7W3hYi9`~4=(W*3Nag(Pg09j-B%Z+g9N`d=Ngb@88&J6>CjGZ1gm68jnIibHZg z^f*iDv~k`f^0$cU?lpBEJc37Eu@l2YFk)tspw_)?Y_m~M?lA46FPY&@vOIBL%6n)$ z(5o;nCWiVpr9 zZdw{q=&QpaWP#>92<>Juy-9~*w5X(N`(9^!mX?#X1x{(4GFNY;xx(60~mHexIupiPmz6;?rS?Wa$kmZnY*Lu;|Z!kplcP)rtQ`MaT8 z9x}i59e}E6J-CTVWXGy{=jX}d(5-XOTl4Nox>&W>BxK>LW#C_vmD|7@Gy$6r3VOJp zpFxGzcu$m(+vK=q?I7z`MQT!zmAe+SvTM!y5>ZVHOjt;Q&j%DNV()4p53{RT<)!SS z%xjY0%2uUL+ljs=(@UF^HT|%*IAkT^!&eb4!!g@-9?pNh^|gxJN&-zykmE^4VWJJ* z@UXczI2ColV|b1}p0TfW0 z+IG49=CkeSfc#;n`YpKfsfjG{>){bRiXhTW-{z9&kS=>19_D#;Vq`EnU&D3%hD-?a zcv`tzNDjT3@gT>j^Mj3V9zG;yLn6l`&(MJj88S=E4qDpF*=g<1u16b%FkJLb9+7sS z{dFU2Xqq|&o}|g!Z`*r}dDfk1%tJm~?c!6Z6tU7s4K`OwAX5DL9x~##cS5Nn!;$?6 z;#2O=@570s6z8R*YrO|Db^dxVoddjt?e<~?c7tYw{SHq8((3l?^UvWE7T&BAtRg$g zy9}9%lc!b#R;_%VXuWMErIi zDQVk&C?|+rgy{8cD}a}so&Rib?RF-@$V0W-0zn{e&D^r)l2GS!gDwivsULf}0K9rw)^ET4nMcmLKcFoohr^ zp4t(B;gJqDiH1`hhgW#UB>z5~g1ue!^$bb^c?%|ypLQV5oLmlrLs}VjQv4+1ZBxM; zO4Z!tZP=X}AO?5X4b{&M>EkCkF(xpEeiU7PsNw=Huz93mI4cp)Qqq2Ey2C`PYFJnn znd!smpR*L`qD&l}Qs2l~QA8?*)eS;&I@yDeYO;6~uYd?yKYV^}L-!n(O=`Z>EcEUD zjm$^4^v)hRBC1@3szt76=wQ$YcGq~-CUh!&CMsgF@ze_t&o*u^NX*0S%Bh>=foMpw zR;CNDkw7E-z6l^`SMA#!QyaQY=9{=Ro_{!(mMB&?s;-|ZydFjt^34Qb?<)ob7NQ#~ zb+G--F|2z;x>}KSKc0LAz^NZm`Xml(cq}Wm+I}&gPZfpkT;P2g^bYOfreO$j;`zIU zR+HlqL`W`jjF4;8`yU{k@)msyo7v7GH=#!`rCI(99>Q7NM8%RPb%8Mp2JM%+UH=?y z%RGWvG6T7Ji>HY?y8OShu5^C#!@2kviIG&qy9mdf#s2N{Nnvk{>&WX4$2{i4%|oq# z8Nz!HCL``k4_eAO(eMhep#NLt5`*8eLzLqDMP{GP|e=QBZ=ME`Ap>7RI@N) zQRYtcpT+j8S|polatTJS&xT!*9OVRY-qSAX+2osXBEKGRLr_KkMmAc)1{^+K)4n8m zi=h`1VrxT=m7NfNARhc?0t`pd9S!Q-z#J0?v-ewA0eZ1;w&()Eam9jY_ub1BXXX_H z5{YJRp+amIKL4sr3@i0`7gv--F8h%~VFg`9Jz6j(?qK$93_YmOgh=@6m(oX$Xp|jq z-PGfmkd7*#kfEt5Otnqk>NG`0GKjaURXk5I z1cBcLp?n7ee-3Y6BmO)eH;TfcMqpm$8MAeVsE>DqHunpfBep!br z$c!?+e?6x8!N3utlzfi(X3KVSbI%OJcMZnhtf-4? z#QwW8A^B8>YnAlX)%6mvO)^jompPw{MkJYu#J(8OCdq2qaLOx4jmPTahd(U+x|s+v zw*GsL`SQZ z_sT7wz*~|?SHQFq1enOie3jGo#D|G)vDG{FlHZ!Do%;p^$EkO0+@`#U_oMQj;fWo{ zqxro*gG^@8yv!p4?eniT*cz53;&R-JEbY_fxqTsiSc3jgDngNN#g@BzmUfQwP8uF= zI-IuH*}yFLZ&qF~J!!uYnF@wHJP*6q#^r8T5*-ZuANK7R{y{{u$ms1Xk#fb(cI&AC zT1Q=`C*+<8p2+*-Nu5LwceU6%t5LYJaiHwfvilZKRs}z*0#=~J`?R$x7H<)ryv0?TW~%m*p(5&^SQ_y8-Z0TfCQG+^P+bOPB(hzy5eh_tu9P z>59_M?@lYh*82MqtkH;K^@faZ%psUB63gzjSjI=TTeXIFHoK>Evqec0{<2IE-&GMNex`g`KV^D_%?n4;_Q zeiIHPzV83CGhMcZ`YJhdyQ9$eJV7G~PAujJB)^Zs)j;Dl){gn>z8tFCcpF!j8HMmX-7x3PLS#G(KaVMP_>Fi`x7)^D{96nXR%a~U|j*0^a(1V%g zseb(!=9^?&+#)hy{Os~A;y)`xWT$Ks&IaDo!=GsiB-^jyoslf;lkk>02_@u_g!ZDz zMV8UOe*9}!%uCZ6y&+RaiVm73*#5kDWAMbDE2@YNAf(UxCZbtG47VHl}X2a(3qTU2K0y0P9U~-n1z%GOgN= zVlIMNdE@W6Bdo}IHxoKlrceHJFxw`XT@~ybGt2QFZj_&3deNA81$TwjDkhs3v?XYs zfmEu?OA$W=P9MmbK%0)D2S@U9ZHKp>iZ^}X(pZ}=U~SaFI(*KFU>1`3)=gnU5U;RS zt)+0pEHLtupAU@ye1Yhlq`{CE@7c=eN4zdsTH%q*$C&K13ibe*rZy}1r6z8kRW0W5 zP+%+Hu6F$55&T4+hpAA9^Z!KXyQ9t9E{gQ#Z9|*fbXeNqkWG54`+F?c(Kq1tCK|B7 zwlfPoTq}oBoB@!Bumk&BbT3(Xz)Uz|RiS&2AT85Z>%zs9#0uxmFRG0mFS9-H|N1@;cV3urI~!p5oRD9oM2jRjEH1b8Z87d*LA&~W@0 zct~wsr(38f*3s|Ij($~o>jw?XM>7x4M0&D}wV&;AWR-tCgko4MX-$QfuD?GNA;Dhy zROkc7NPBJ}oT8&FdsFd~i3;@!wJ_S;_38qyVo`v$sEelw;sFU%FTobL3jlRG^A*l% zqA1myvSu>8#YS~N%JX$1gfxtz62Vpot6NMV-)r0^R(Z{NJ^k=IYLLJLoAJ^HZ#U$x zJO8hn8BWD|>h%*A$&Fcg$rwzFbvwFjdUOqIb`eQ`*YRMx3Ut}N3xjdCW!iqUV#&-Z z5Sf@|>%q#m%T$-?+iL?Itin-g7UDH-UTTsZ8K2tnALAKg1!m5>aGL>zPq3z{(ur6Q z&uIsiY2JKMk3`VftCBp29O&zQmBtF@qm;6VS*?O9B2v1^l~z)Q)01_B9+F8ez2VKbC9e`8}i;OF?+Kj2OW;Q zhif=of`Q8G-O|)4r01Useu}2^-Q%eWK)Mjb=d0fRN-Y*Mi z7a@sjIhKtmU!p&qcn~Z!_cg90334~x1k!E@g zr>qWcA`5xKP#6J0X3;nIl6)V_FjgC5(5}MZ0%n?=x*uLSQB@%=n zV3nc)caa(gS0k9mBWd26scb(;N*uL#tk~H46@|65YxKmdoO=_dMmODd+X~ox4vz!; zeFMWw^q6Xo1xb;#TzZ~6)710E#nJ~|)n`ZNgL{u}R_25aO{WY^!R zgavGW9+h9aC;`{bNXfc-$K<7QXte2@=>eYM3JLRk$822KtVO0}Fgd&&Y#xX^yL30b zMAhVx9z0;!@#S@CX>Qh9+NfqMR{f4By(-WfWMr#^XYv&eTw`KHsBSGb{IzmZbW!NM zkFC%m>`}6f{J>g4VO2}*mcwyQ^DIpz6V0yG;o(i(ewv@Om+&}9mMyzllBYTT#lLe` zz>xI?@tr80#hTPfd=n<{68h~{QEDE-7l|3(Efar4?}l7XTcoW?hA1gQ4y1*y$&fuA z{)u&qi8PZl8>;6mG;LQE(pd&;stRL^!q0V_0v351836-jJ*D%7R|*CgC}yv1zpP;z z6$oY?xf6H?Pvc|PbFbHNdbXb9BWQMHoz6oRD|rr&c}p1@&qp|2CHo(a*-DMJJr?_E z76X6AnZU|yE%wO}Dt~~bpfP{e1VAZUi9YDIzIeh@OY=X$RE;bC+PO3*PujfzJ9Fm7 z$`^OGW8fvHQ)~rZ>0D{W|EdmJscWj;YK?`B7FsWxt!(tbZ=wsDa_9${-R&m)&`Z&& zs|PRzrqy0m31u1vyjYeN(V?q7Hq?d*hQKUuNFv9AO3ysMy&ch+>8@_Jrx@mdSoO&s zO{lahI0Hf7KA>>uY`IUve-GrC*8M-drof2OJz8C}7sbnedG!K%xCtHEoVYtSo#7p_`^LesjWPjI>|#70q+b{y&(xI9$Lvl=}(4g&SM zVwOx5A%L+s4@8`ZI6I(qm`DwxhfL~TdbFY;p>prgwv%pPq)fqS>adUXQTe#E@j1h9 z)*_X8I5#emg=rS03D4>~bO-gN`9Bd)c37Pqn0n^c5Vh7e_NS->lo(~7-tHeFJ}|;r zp->Bg(arZLEmaGWS#Y`zd_UXp|22Ny4}T8rxk=QqLFXx(GpgVVsw@Ps!*yv_k{{T9 zY7u;E=7n@2ES&(W9i)T1ZH4JFtzVy`1;o-fUmljaL<|e?C-3Azitewz7a?B!BS8)5 z1vgB|=t9clAXD4y+Gy(G4FWs*7EKW<94>@P<{b4C=*=ud8|)pjpGLPfm?4^Kd^ts8 zHb`&xN>(AVj~L>}wH)+M#3#$;+x0$0q4~8*P;Ea%dyCcXwEIZRfEh}~gX7mp#6f7f zOa}()5Ny^ZdcaJ>&WC(;RBE5^b|UFiAV*$`WvawsjQQkn%czL!9&%9;)Ki`Nd5BnU zFh9$36lIEe>G;UT1w4hgpEPb5A6S2jWR`??*^v%Ce1Nbma&Huc$RmiGyg#BY$MByH za{_&wkuN$_1r@(|?btR@9)kU+4U{HO99nz=Zh2H{+5(aHQM^n1R`9y=w%!7Fj;FCW z2_q2RKGEpvIE{(O<}ev1@TN!NN7mA<$^CQqK!VEI?5^j3p2;(qLVR`N4FW6oU(et* zSof12naXHR?o;Ckq*YkWjwr79J%PrU4DU@4&xk<>$-S3sa`4rm zt&%><-^BA-K?-;MB631{1PM`2P1IT|ao5!T5fOJ77Luxv*PpVQ7ExHcIHIto;a?dR zBN0s0D3YKLzymKhc4(2UdkiJ-Fmz=C3z}s~DcQV!U>TX}u#yav-a4YbQ;!{4xFctv zgZAubRkxN=vM07H^rVwNtIQvgiQb^78Z25pJTassG<5UT|BrY$doDeOIn$2L@nIsw zhVcrUkmsEXd@7qAQ~j&4>^jQw$~N5kCuf%7aO1FqAHKbE#Yah0Bn|R|QhMKG3)g7E zYTOhI*3egetHlH*QZziy=oEOuv;0=ODDBKi-iYo}vfFp{{0;wI%28kyJvV{4p1HN3 z;daPV+u_U(FB6ypI2jlkJ|EE#5PP^dbL*HP_hwi;Ys#_^1$oZu042vUvC-ujl<5g* z@fBbqKQrM|tml!iGlvve_DxUTt;83bSP*xZt zJc)(3*+sOWSb6DFjLc!93}Ut^lpo+3CZ|lc@V=bhnU}FMfCc<4GMFU9OC3|5ojz>0 zX1q49<5X)EyC=RTtu(<7uNrkELdn*4YicSYs?(bc5$3Ynj+y-1pGMvTqOf$K-#Q6rTSfDc%rhivcQ%xw1DNK zQ?ECEFeAUA#;($|kmya6PL8B@<~LJ<)C=j$kb4arDZ3)~>Io!YenPS}^XDZPvNj)X zo+j`>AU$!op<~Iy0Q;vbr0g6lq|Wt!3L~}|HM&#HH*>hhmGu=FV}!o)L*vCSa!73v zYX4%#pd{x?TO^`)gY*{kOjQQfJsf& zt9b5gV_x4M+wnE84<+9R!{_HP2a(BJ`&Un7v4B65W*xqgF|+quhCj5&5z(y-dDEVyMkACrvpO!L8sTT4U>Lc?*sz{`$w|N# z`3&Zdb~1h(R(pJ$dG_%7h#y|hL288D5A(LA-}&o^Ss85xZ^&!Qr%d1W$OhL9f2idV z$Y8+J0r!r%cl?=1$P6W`mtk>f3!)?4qh@*c}f_bHFq~C-Ft{NWe8Zr5_*}ro{hcfECOV5(UeSe`T zD(_!K-Y`COB{$f1Sz&_Sx=+!$UJ7z=lgwz}LC1H-wB4-z+necYhm8EZuXq?cvD&)I z51!Hmh8=5xZ2AIJindJ|9w;F)o5gLAi}chqqyK^IiHOVSG=T>Zp*U%^Jt`t44mJjady*STZGj*9xenZc?<8v#~e z;#RP^O{{fW7)R${7v0#V<@@;5z(I=S3BDN_{g{ugZ|+A)mOrs6h`G&whclG!)^{Fw z%`(X;_Tb)BiKYyFym8oz^it@TcmprvgFA0U9P`gkPUz)({RG~bGVO{?PWm)~eP~-4 zGXGStd(?%PO9qgJ&Oe4h(>vxR92z!H$3G`&>o0ewUJM7p$TKtqNRCZ_vHd7w*tzLv z0j(U$7!g51emUKK1rm~9KT1og&m>uBf_?!qH4HCrENkbzr<82T&>losa6NJ*aK?1i77Mqss9L|PJ&nr9-G1Zf#AHLGDVd7(ON z+5}9JdzbIQKJ!-K8?sS1X`}AUOs2LY42Q))-F^1%57NWMS9O2*NH2$`ofpoKaB3rz5flr;o z%!VcZSeEq_QFM4;*I<;v&UZ^JM-d|ozso^sOq6wnXQK(CF6M%_w{$*74K=~qbx02+ zZO$&A2=f)StcBj!yBPY4Qqp1o5&ybf!{V}v#Xdl{6XA{H(nN4ROB~Wqo=wzs_1#g) z>V5tPV~%QjMW)VoUOJ9SN4)Cc^+ZDaeU3LML&|o`V|wUSAlXdZWGl?h5wwvLm6#%z zfqCxzn~iFyYbVb!`OGDvu8o931TzP(Tk*X8H%AN)oOd!ITZigS0$kl^N2WFCIyBqO zpO-|u2@$TH7+AEf38s|wQ_I4kx-A(wJKe14xm$`jD??n=7@n~7<(wbg!eZoTBTG;2 z@o^p=5k;4M)ScpHE{RaHLb7%|ru6ne6DGSHXhL|}j1viLra%*gZ-M^qOP9s^* z5}_oofk!16XCjZ;4_*yrc$z;n0h{&nCC1S`zRd|ZX0-cp68Ir4lA(9 z7gE!aq$}wgyw{RHC5sU$wb!a69{c)U#BU>r|B4hVD%uOUmUB4bC2!&ByQSUG z_VIN`9`TE{1BajaBU8DG?$A!V4uf5YmZdT;!!H?x!p}!(vU1izhllT~`0((#kS3aF zQ&XnlPTfkL!{DJ=ePO@7suP?=U!aZ2m@NL2Z55TIAL=mBH|VgKdGilon|gfH*kfvE z`=!P9Q}^-+_2f&KxV3QGnG{)?Ihv-J@RHharD_bwlYJV&yeXU1^85%g9drYnP@$*PubilQXb?j7H7g^kT4uKVS!F z9MvZX*kHlA>m?1e)FDElPlz4_D)4UC@7en_#~db2fIP(OjAgff@ET*|!~IKQb~k63 zgNxj0y{M{;I`5U*u=HvsBTaV1>vI`1ua`ft zL(R`Fl9YEL8aF{Gc0e;m&k`~4C9;BP4${Aur zY07u_Y`s@%gw!(-KT2u$aLiadi^Fd>$#klG;RG-4L*3y|Tmb zqnR@~-&v%5vC0s<9(nUA-0%sk#fswTW!WBgGi;hyiA zkkgS+dyQ^kj)o-yJ2_^+$^Qhjj$QQa3^%08g*@D~>$j^0T{Rjd!?{)j%Dqs)ZOe?` z!?RVHXP3jY8p!*|Bmh|olUwC@d+EkiM>G-hD<~%edUg(>E>?w9+etw54-vfuZ18u5;BU@mE;wQBjdT`MwG7rJT&t7IyFBhWa#&c8rCu(~>0+!LGyS1SDoO05lr#(?QI zAXd9aX(K*gi73c}PvNk?i0d5vo)XM(c_Usw-8xmsJ%tQ3${pRev2=biWZ)anOckt!WC3`Vo#^o6AzYQT zCEx=@)>;WqH$Sl*gS8BHC=d@R4e*WLmoiSfyE1ZeSOm@$Y7)ObPgz8>C_uW2+;pLu zi*g)$!StbT%FEm3%6L#xJ}F;nghWNM^I5d`2N9Qa)2el%P_-^#&zdK57NAI0U1VKI zfnJh*!7ashF_YcD;$~Jb-=q6!!hza;4798Dn(n3d@vaWa?P zXGT%i$|=k$qdLS`L@jrP8U^+!oZrYMXaz(o%)j74v_3I`h5?JHFV7d4v{l6s-I+X6 zP*HaGjgo0gjZ>OX^dEsoq^V}|;^77MP%ZpVQ4_#n;_yP%5#RT5DRppOY6!Lf zs=NYX$wWU;$V4ZWIYtZNNXN!sgEE!9T8Niqv@k`=CzhZnDwqSCC~p6RW)Zs@sc0!# z9-2QYzMGwwrwl`ap1(-=N6h*f6a9<{%=9*b+F6LbVmSfnYnBOE*6^K52G6Fd!aZZ& zZn==in;gh_;6UCYJ3E*WY!+~A9vBUFA7{blDi@gw)AZVj4Fu{%Ccv*TH*FbiZaG=+ z0xH39IQ>ip%iN#5J%Z*LZ^3rJQpcAtg^9}O2_LDN!^wtc_qPx9)C^x;*bvdSffX_` zRWiGq5Kq3EGJ!t;p$P*^1l!mqu_qMu^yL*Om9?7r%!c0vLnS)>pra3SU7D~1lv7dO zpMZJ~vr@>g8NlQ;}uM5Nh_hMFyWnU zwVYBEbWNkv>dO5KWZe2WXgAB-kM<5dU(Vdux0RKTnLEZ3e^+E$xtF#(WziHTQ)}|~ zZ}5n5xo`sE3ZpfdUEE3}kIsGS42w9x!au=#j+rr^pG?FsN8S5~eb%6TmOgpAm{Qv7 zEPziZ7Xw|cnjA<_g#mCR!oe80j2;ds+?w#1GI8vly)U zZ~_p5zpk;#nEKEsa`=aGcR$4<59JYDK4n#T#S(UtwpXeL_TPqoqp7g$C=Y&CSxw3(63=XlY9gDJDG;DK7d_H(Lis>%&*Q6Hlr$+DXL z3{Mu8)s!evbkD#-nh1|#HBp0Dg$S}$YT9J-9EiG!Oh}(SJ1QTej)0hKj`K>6PB%lw zh%uR5HJ^Z<^)ob?l^1;%r`5x!oEvF z7yH#wxgomFu$40Bje}W8u>G~C-h+Nw&U#Pu)v_JVyydOr$c1`WSBTdO zS@U;Czs^RbqDr&z#% z0=avLk~lfaXd2~>oAPC=+M^y7jB57t^8YjInl$A@WQSv^tnW*DF1(8_nzB2OCKz0t z5Cr%RvkVMcces?0QpcixN}27;G&%O~3LHa;GJ=b+tz=8Nnk;Xio5LGijD5~bMg)eS zsBMs}scy6_k^ioTG8K;zqU*ukRAA0luIK?!)ZNSb@HS@_ie- zgjIywc*!qi)Q-EA$r~rD3M@;eA)ot)X61$J;3|$%&sV~mQb6HhsUX!A8aNR_s>u3c z6hN-p1Gv)`5WY+F{1Zu}ZZ?;bg%J;SYqaUCP2lEu5=6-^*{e2}yF7z=N%M&VH&5A) z!jO=lxSodp zulyk`?_yn#1)5yC6-M7Anyff^1%{@%h5?)@RH7Zjzj4)n$)q$3tfnfwcvE`2+5x7k zrjE22d`d9D?x(ZOZh6^@v3pVDIZEgbi^aZ~G;f1ZGyKXb+-`&KZW)}_;!p?vf0qpq zF&19L1TI#GI(X@&!>)=Q2E3WJ_vLp&tfW4EwwR*U$r79_MBqqXBVSIQ0+;-k72IU_ zG;*&^v4)I;oKQku07{P~JVVBR3T+84agA6`5PZ z!0)f42q$q>M#eLa{%?b4(;SyC428~Hcs-6w0R=S=#a_^NP~zY<;fDW=x>J7^nKTew z(mMK&uCrnx%9MSO&zgo&5ZATrATz0$&X(MNO zk;xo8Tq6n{Gjd*ssxws*_&(Ta6z1BZ6TrAGy81XuZr=ved6M>rhE~0T9ouF9Z3BvH zh7WUOMUENvj=e!WzX7k9L|(XHRa@ceZXVUGd*zmGPyW_9Bwe8Ro#Uw*fmbH<&QGm8 zCn+n>PV6|7Uq?8>crFtQj8g^vw4nkXlUv+D_HQC# z1_Ju47kFe6AXh))*JKFfVs=uRR#pYhZo1W4h6I1+)qHkFaWPXTw8u%M9+h6Fphg}_{NU$R$adXz}In2erP#}@SgOg~X`r1ju zLJeRdR-E5Sq?ZD9evn64rFO1Ajk6vQe~6;Uhayl}F|N5^+KERvKurI(Z!e-DUB-*A zf|9V4;%6B$I}wIYh(aq2d|%w&4k$qzdyz0>#D=xY=Th#IN`d;3ot|UgTy^N$mox3 zyxe~P3`t{}8ti0e<_GfSvDyAYcC>9#b-|)COp4(%X6@aRXOQOLu>g1j?Wo*2(MPSD z$)ua!{qUO{&IDFVlVc)F{j4&0gn16;4s9fcKMDzcb~ujW z?xy|LkB9?F{JIJZ8(E}V)$$9(y)pR8AP*_xqRM01uB#1jTFcRE=BPR(S?}LXUKEg| zEy9y+cE2A)JVS-n(&SxVsxt&WZ#jc72}uDD!ynGh1a?!u1E4u}^K^I!M9_kt4b0-` z7HJg@#?Gh}E>UpvV3rt&mw#-(%iA1)Thxf5v2y|;oo`c5` zadv9KCeSxuJe*2yh=IufT18;aw9`5d?HKdJpt_dL=$gpR{98&?^!nU`ZJ<|o1aYtt zb-b0h1FbOa>moRIW{@enZv*;1$NSpGnuTqmT+h$%(^7j^;~k;4{XUv7#M^g^2R4B1 zUzrgNDg>Ffaq{H@JLh`}F#xKt;Sq3vJbOUBgD=6W)qndJ&l?3&$ho<3S`I+Mt1x zK)F4LdJ<&_oT0fHk<3n{eDyF906{>$zr$KE&Fw~-i#WL_cIWhL4G3aYS5yT*$Hs}= zPxn@q%4_<6RKLBmRro(eVJNfgtr?o8;c};h`ZxQBoZ;r;ozOK0Yv;J>`MfD``aZ826yylB*A*6!h@u8kUPu7B@jMD*_pQ)lsjjU4!6+ zMDQQ!Ju$e)#vOR)sbe zxDU95N1$lB!_^HbRT<-js^&qd`f9pHhLY@el_cG+CF+x)_>yO+Ok{`kBD8w#4IvM; zFh2E$N>5#n!+){bi|q)v5b;h?3ZTiP7PFqCzFKyDCR3tKU$>UykQ1R}ev&|^`sO|@ zSsXqQh{H`49sYo@0p+kYMKl|ifL)jO^FVPdMt}Q$38=m2$iU73KEs0$=4SKuA|f_@Ne|FT?vQZW3~V{Pcp39e zz2duL7oMY?u7?T# z?O6$mQt1tZ=Cg`?zV|vqL$*uUwh7vBSj99~Tr+=2qXhpRm=ocUyG8;Zaf-EVUgvl% zzcjFa)Q!^?ICzS5czsJ(;8q}s6;y7I-t!MI@`bb02Fxe9Fs;~27h*5t4SZ&>($cr5 zaR2Ia;u&UP#|>Sa@NJ>S?13n=s;tG(kOklN8`#RGv}<^f8J(_H@Sx~GHMqNfmP4Et z17WVuLg~2n)Wq5sOOZYRxPKFI`X0F}_B^v7+T}&wJX^s?Yl+arb9rXtuzj@;>T1Fh znnvO~R+yw<{BhXyz)IzHnBFjH(Q1iKnw;AX$*|49Rnw-F@qZ~cPI(t_4fdvY3r*_$ z51h2v2fIl6(^aQt-lSN_L|E9w4G>_Q+0TVwaSD?I)6Afw&8Vg~Y4{drZi2OS>ZMGQ zjR2MBsOvz8#W;yI#&{wo$nD>lCDGP$f-v5QH8M{#)6)MLtpXi!J)uth3*7!JX#NTs zN7fO1rc}|{?H54Av%J|SD4Bxrq@0SfxjdESJ5fO}wB9*Q>PboCX2UZJq+zyB!!Gz` zrW{xJ`Ov|Lhaz4@T|UBfGwHWwj-|!JXfnIN$gaY)H?XcUX$5BWDMeHHnTIey+~`0C z&rE@@PRh!j>yX1E{^6!VdH4rJ?$-%S>)VhNwBPnkkeq~Uo2#1_%L|Cu)N-;A?)h|^ zb;n-EM87FM8f|E0Sv;7agxy5&^ss&~X59ZfYX9~&+%X9t4BEBC(`lslmKmq%mJr+H z%xAdaeN-f-?mVwZ8-7WwLEM)attwUdeAt!hTZbG z)UihlOqo+2<`KH9o>FaiBpV`?H}{{IXoGe_A;xYV%w~$75z&e{;N8=b;WTRO1W6-~ z&qbcfE7fNwVvjJo``V=d~3GO>e+F zBpfV&P1o9dgRZ~ub87T%8F`L#$n)2VU<;X7An+|^>6ze;9>=cliPuEB<$`9NjcsuO zYmKSICyBRzampx%vrfdATd)Y_FN9&E3Vlt<0CS8P@mw63czmZv7mR?$IthsMaT zNW~;gs_Sv3(-n*|Fh=-MISmU2Tt77f{568{)A5ij!0LX8bUAm6(-OhYaE|b}kZi*3 z2KeyAgtT^R(cI6KQ<(@d4F5lyDxoZJOIQUG4RXryMu3T4D8sLUxn z787kTsx|CK07t}) zbE|ccx@)ENXR0#Ie_KT(U!W03;Xqd+%KyuFwCTp_AWxScy_guI!_qR_`FeTEchKXL zasz$q!sTJ*q#Pm`5~O~|7s!CRS{_E~%?pgFYCrvwNVfuoE+mZT<@&;oDijh`VAp09 zm~x(4JLdS5s>-KAepKifEfS0{KVWNhTKrN?h<93UT8qX&LdoSpR_vmZ=dk;r$S3WM zspEbv<_t$8U=h!Rl`fmes`x%%UZrb~MY@SE`vjavYKi`m=!{Y0m5YovA`~E}M-1xg z@J3=xuA_6q&{{i!Gkht7`Au9dFb%4qRW6%min}3UPlb@f)!_v;v6LT$c8wQ>H+f0(<&i$v{3GNI=soCU(kYqdkqz9qfeaJG z0WHFidEZ=)gGHPJOOF2!1E1TD23Jd)obDTR3J6egq{UF{|9XiIX+X|gh~7VnzLycW z@NKmCEq)^xcrO#-jWiN{?CI*VTr@USO8g&TAl{zwPvH(?41s-!721`ELXu_zScade zDE%-`EpNj1%aK_FnQ!i2n-58ZVmPNiN)RNA!~ywp0=-QmVA4^=_{n1UR&ruYAuJjV*eZOk2H(3^UL zYq*-peOcAm`dej!&y12`BQzk62IW?;Q>L2L9n$-?l$Vo8H%@GWi!+M*M?anp8eC5;@s zj^34pUv@$I*lzBcg9O@p*kcoUl&q6!7*~I_qWN>R5(+CYr_dJ$;) zc9$Q)g3Y%I8sF;K()VXD^HmvUbm9D0Ea&@WxiE+4a;(7ZVyD z4<#&bkBob_41%xVlo$Eidz9(qE3EGtFGcQPj56J#f~-2HtFUU6eWH@gPu4Li1TWge z)8|3U#B3 z&M_9L?nO-}&Z-^CZ2vQCEJmhP3Fa?gw5*z{S-=fV9r$;acEaVAi$G~=Gy=38cXMHKi1nS!3V{fBJ({u;0jg!G zLyg1#BYe<*bo*Y{;ZEeOBbVuXqQgy;4l+8t(KvUii)?+b@p4Z>-^FLPqL>_izsfvY z$8WzzlaqFvS=c%y3-bzN+s&M;96WBRTun8J-92W<*lIV?;pp z%4sn_PEXY8OjUFpw+PhXy>9ya` zEk*!YQZ?)FfYbKxy`}Aw4Nsiob*r|*O$@Kv+yk;)8dP$K+XQeoFJ+a??2cdCrJ1bA zdW>CAAUI+VmSm%S?#FB&jc=oKWwj^U)JzP2u)}oA2vjeuZ+0^NSR}JKcz3OoxW}{* zr98mC?b{|LwSX;Iu(fTFFUD?5DOpTafb()~r-VxxtPN)jYNs8rXDiC(=J3Rf7+SB$ zt49Pge$vdv&2VR!c-AT;$e6d-wd>M$>aNJfwp)n8qA|Ekm#^dIOXt5wsvn9s3*8ro z-`R0~$2a!y&rl_$8Hak3b z)l(GC--bX>@ZLq}9=cGPX6}(o3+)?ygKQuSeBrhK$jqoUxseSp0O z;yLlJNZxLfw`T_W4GtB~>nx&3nxYrGj~Nd&9wkvI6gdb~WpOyUd51F)YA293mjlBC z7cPdz=0)p&qO1`-U~kR{WmuuE2}UGzvzsZX@pt`_da$BasJ zkUXf6`5w_F;OhAa-@2H!S6<$)BXvn3fgnfLdUZ&25RhfEe5MY2D$$mt-E6JPz3$42 zZE!A4sASlNt?%&oRxwH`MZgsiLkM`=WfXLIxic~J9BDArlD54oBj^s&caY;NM}7mn zSnvC=HOG;J-SXvja9emfo_n)6;o0RoW-7xKI0yc1Vkk-%D%p}`>h;-k66pgNWJ}WT zw`FRq_;Rz5Yzf)nHBw8Dumi?j_;4>$uE49!%hW~A7-`cl_H49@|0Z9R+*Yfi-_yHg z_*9Fu-&V@9-&}$0j{3}{otHibU0@gG2Dr?+x%pSyQH`x#;C|9JEE-(Q2d;M#*l%p` zVI|7Pyj|4Z+2L)^V5Ut^s~T}j6Q8DXd*$|ee_LcGjo=NbDc!8k56UmpaPhQ>8Y>`W z%h*slTR*P|no;%&ym=Jn4Dkq?PhgK? z!4OX0kr!vJ-uw!HxO7^&xft2=?LB+X<@5%BW#SC&bI5RPQvyX8 z@=%>c?$xZ`o5E(IV9NxmM{E(})3Kfx^u!tQInmZ8r>4wSWZLCBStomCTX=ToVrBMD z<9|Ow*u(a=`(DJcO!q_CYvel3S0awo%J+e%Rp(!121(YS!opG&!>f?;hoOS2YBx^7 zJOzQ6=-Zn(zq7ORyWjG9BRj^0SQd2Xe{YvoJG6D`5KNS;zO!TJp}oE%@(^nEWD;2^ z*=;HK*g^pBp?SedVZIP?NqAr}J4~E|&m{Pu`t7!%K2euV3%Z}70KUig@^+7X0P|>` zIYoYGniBOw%w*;K-@!sx9j)==I4T;cGZj#vLe9lFqHu+aeGKkQRL6q_rE3PHJhZ3O zPf($k;w_99Ojc_R|I&bLQLXW%nqgzBxu=kw>Nw^rtGL&u+VeFG++g|9;V$4?9mf#R+k*A?XXnP$)odScW06_8y* zBW{N@t0#fo2z<1OL>S}}O}u(lAQXNCV?y+rTXQ~|;p6UbB9Ra(ijxlDCYnkDU~s6sE*p!0}s`VXf7HD8JN$3)$PFMwWiA7Xx9l}%hWFp+nT>=<5!gw$rm zZSQdR_>!+9yB6XB`qC5hqX+4A$a_A)&k=R)t20!5iGxWFyg1%g56h^SM}8F%4T>^A zn5Pn`51eWJI{xi38?LgN)%r*^_{;&#l62(RDfG2WmdU34D`G&c zhQw}BmJG31V0{|B0`q_|rSIa`$ltDMlHz`j+N_hWVM`|ym`#2}Qy4F>Arb|@9VA}i zFVSMwL#qoFj8P`}LZ{#Gd$B#}y>$r#MoO*PHJ0NtRC_lo%MECyog?_u@+4}+%(2?8 zFvqL{t6HPsXeIVC1Q#)!QneCmOnK-18ZT9=o2)~W6~CKhLA9UsY8X9<71cH7R+B%Q zOwMeYIgn>C_V68*AB*ramg4{Oi29))rvl~Y@8&>DIX?6_!Xv*r z)%ZI^U6p0+&fcGJZudQgb>^y%AdD|cvqZ#l!|#^}NU$;()dF9f5-tcAs$GFJxh6RF zsFLDjOSn>C>X3mfHsyQ~2eQzWD=vyG2#i`nUnGuSWW3eIljowMq=2eGb38%^o|J=r z&~p;|b+NLJ9sGb*v(QV|j07(e`Z#97pbn}_;{|UCAEz(aGx?nT`)-bG$`^bZGPFJXKPU(7AE#d>2ZAbS&r6 zNiy%gjff%#7rpy?>7QvULf)ZONX*7fClYnYowLQWBfK6R;VKOit`?H+&CfQEfsLPF z7?)3JwtMMMr3>HDb|4_hEJQvS{^+aI=oC5;c@qf^nG=G#>SUl$+c``}SnVy(MnLAO zP~LZ^)Dmd}suDc(=h*HB)28KitXstWBiI=f%loG|0aMWu?LfJ34_f$#4ygo8inUIH zO=dMmWkL3ae+RaEbyFV-)ud?<{{Yc$^U?JJ-T;^8+>fKS8`uWvFy8QS%aiWh5exhm z9fqRE$54*wTGRQe7gG-CTRRhP(Bd1=PZY~z+COa{juey2tY|M(y*r33juT13sZ_u) z&kG||`{ps-OT(Ln3zIBRW%Mi^z9$UaJaK_|It!6sVRIc53{XqN8mP@mMARnJczp|t zt4%x69TRrZ)Uv05lu$;TY`~P~$0oR?Li2>$4xh^-6m4iB-ix+1-CU;HrfiWZu-O2P z$1!bDYvL=c16E+1{;Zc1V`FK1KU{=6S=MDEUac8s&QaZ>h8yw-Vl{`Xyx|cBEwedx z(ZgW=@^wz0=wA>HY#pGe13!LJ&nn6NTQ?-T0AC9ePAlOgOK%Z>^fQ=e(=%&>Z%56k zgD6<`3kZ$;w0kmMcK!|@YWJXW`x@4oC_T7d+OskYuoH$ng(A8v!~4^G=?TG2CuClX zTzHVM!fCBFoEhn1tqe^7Hglpl+#QgF!N9qHTLvoI)i?Kl=wR8+E+?p*+Q4^daoIXF zlX$BH1W6IPyXI_v3{yZ)MR^N?gCBJqqE4|NtlurH>T}Z+S2qkO*{{3ikkfd*E(>R! z+#6$Y6ROPT`w{;YA~gIqj*ZqDNy-zQrY7ix>sr=KcO0;}e0xEgnsL=W)PJz@lwx%e zKJ2R4D+zu$550hS%Gg0PUSHVGG2Y-qrIQ{uinaRw> zD~T771t~687-1VjZR)(FN5QAE^>j9RI-zD3sn(%JhjzD^!ae#KJSw3cSByPCKVXi5 z9J_gT6ag4gUgCXBqLH*nn{zGl%LhAPD()xiZ`qpp*@iF^ZFPZ{4WoM*ezTa!+pZ;V zt62j4vdg>tvE5=DJK-tjZ8bC}_RV+Ey<+8?BhCUHY&sTgRYg$8=qb~(i78BvTb5Cq z!2J~{Sb$yY&;0KwLF#h;bGFbs30VOdCc6&VHciZRMMPQET+OJ%Dws8R(&EdEt@B9tPFz-H1+ zIqtZ$j=83WiO?7G(b1&tdnM0eSXDkl!K&$Bm2CR=kzkZ<<~_LYb#eId6o2dR|7XUy zt{9Q+$eQMTg@N2{TxUHP^-3L;qffW z0nCnGt!*IN+6#pMPc&laSKQJO!wSUO?3hI-xN^-LEwezo1%hBB)$5ZD3zfZwnKf0X z53OEJKp^dgp66dU(G9DKpjlZRav(a9f$N z*A9^{v^|XnK4H=7DNe2nitgqNfc->Ls27)btWrqz<4zull#n&$gIzYv;=K~~=$`!=CYINQU|xUBThvHVKBaJZ3z-T?F29)s z1HHX(#?cE02U*msPG&nrl23tKf56ej>MR`=dT=85(vGFivI(^d5DfdyDCw|QulesK z&FD>;GUquyEOl#gmdc@_;v{OE3tp-#(yjP=-rrJy5K`YuSp)X`E zlz&l&Bg4wt<%pGL#!T1REv=jUHBbl>LRNG#BS5TnJe6vA?fV- zHjV$N5gWh~THV%!W zepd9Xye}CIX48BOI$^pqP2itqr{ITjjckv*cYVt%tL_n&wIIIb8;AB<`Nez{Bxvk+ z07h7a;rUW5daIf(TY}y}MB{60T41pXG$Em3y99UOFIL#A2}Jv>KBhZ6nJKhl4=-+3 zMfRUey-o<89c~Y{50B02+Toymz>6TpUZR;x(q4totuy-S*5Ry!tBEZKkfC+&2n~y4 z*&{lLKKv&D$=KELpIDp9RDF6I7Mq7PF>Xh)7ES^|kv9tOsgM7>NkvpXlX`c%Pk?M? zl_Y%|71zQ+WYQzfyaBr&bbwV{i~{uB88MpMfi7B|l+ZIv2E<*xYiHWOK>O3Y{~UJu z^auOau*&z!2_He8!SKefT?F#kx;@)Y9Dc4rg_ys&0jrw!(C{e$0x`LAMglnG(RWR9>}9&J0Il&)0gjC4J3qmRP3Q4&umA zHQ5z(aHL=Mkyk^SJN^)ilSG>zd2Px$A-qXRV#Z<)o|1V2wgJPLG;(X9Kunakz{50t zF&m`n)4^SQP(iP zCFCBPKs{ioOGMa08}}5|)X_EQXop6Q!Eff>A=19X<#20J9lSI}i!%H^OWfSUSl6g$ z)~80r+&s`HeS<9|=jawT^Ms?0z8Z3UE7oVf&Twr~OX!9SUUNt9lxEY{;r~NKFge36 zlP$gVF@D^&!_vcC%o1S)Kf@Q{Aj;&%HX-{(4l~27zcv(E#`eTS;T^sJD};IldtQ*< zHuY?WW~hgs64#AkAQ*mQh^&Tm9{mDg50rWX4ggL(xyvZiyAaXUC&b_K>JbZ_vUaNi zjyxLO7(P`^A;yN0&h~9b;9I!(%!q1^Od85qY;!L?fzZ9~zpUzMx*1%g6gm9;fei<0 z`d9q7H*wN_L=s{3{^mnoeC<82BIi@1#l0a>!fFLe*IuF|^&21QJdzFF_5FZ6zWbt^{K z4PH**-9FvtP9%tylt%Ut9Zv&W7ac^ z74~()loO?n>OZ`LRck<~jF~selcAc}oW`w7wn!&<4N~eL*m@in>1aLw@Q+p&PW|0R8DkjQ4FK>sXr@ukRm`2;KNna_>&$fLLBVPP7I^Mdm zKoPYF8~);B4ej=eoxgH5dKqaom$4t#OT$22`L-+bVLH#(5rh(j{QNf2mPv(UCbqc? zF7Zldih1mN5bI>5nSx-@5TzmqHld0p;S&25^=TDgq%%rJ~0*6|uwntZ}VW&F4pAeOuk3oisIL3YUv@qZjQ* zk@fH~Due1w- zz+f=t%$Y|@UAU?2{N}L@FUB8!hN3owH1QI&jyjO~Oqmaqn27XZY4C_WT_vucVPq*6 zV)trai!jjIR-=FM?;BxCIL=SxOfU=k+cgLF;&jKQXVJ_tY1((Ias%t}$_nF2M35`= zwK(gpV~vE`3?+&Ja%Eu1gL$#)*K{2Nepdz1A7SC@xY<^oyA2JVk4cBujXFokWUK~w z?s(;rAxodwJ`s6MYKTS`g@LYYTJR720W#{SFzL>~`f`;-n5i)6Fh!#NPO1YeOR}50 zw3F8P%VZ8>>bKc2m|qlTVA8L*5BN_c02?HKqeUO*{b5Ozj>FB6Y)Wo;<;!wxUUkc} z>7}ejJcX7sQ@ACE0)x|SQv#NWlG&FlJIg-&J{V#?%BN|GMNq75>-zbr1O<#S6PYz) zL@^2I!Y#hyE}`634~L^UtEF&ZlN zhaXf27n?P#0j>1?5mCYH>m?ZjN}u_i@SkT`$_kO;X@=k`o6)pq>uq!|H-<}zd3h7o zP*>vqk2zGU41y_sL>;_Gen~2d(jJ>qDu7Fy^=5b#)4_Hn?9z^}T^HxpqJ!<`*er;? z=EC+DhTn7$2siavgQPT3y6kXX5_{K$`~@qp@uAmo$>>C%C(T={_3nt@c(l+F<{a}eXz6-A;C1;(na`ppq}m6`Wy`Ymmz z|Bkr;0(Q@G1XZxy;0rH{W+hy^f@4LM^=)LCjj#OSnNdJkR>f}FB_^(2u(U9|Avih= zc-$f**5(4vEAeeiM6>+F(7jc)S}l+a$1W3D#hfG}i@e$f=~ZAw&#tLpk9Lmb=yPPE zW0`Sx?Ae%!oe-C_PQ{3%kt(r=-m+&9@Z62=;a1hd8Dv(U7CezJhXlb_u$0pQd(#XU z{vFKjWD2ZC^`{bpZ*f->oE@;%QO&;$%;Lj&CP1 zl(;9=^Xs42gxZYL87eHhx!MhuN`WBxIINWK+GV5*6tAaS@_|)IL$4MX!x? zSBi@=%6!uWBZvX* zsM`vh9X;wY#DM)AMin>Tthp#bVYU5AE zDAvrYc$7h7{fTh_8o-s*fEDI;3oN~wr}n8rJOi~S-H0p(f?dKi zpINUk{KR4;y6Vj=5haj01Iq1m?PC{qpv3Q;3``>3#R+>QyZ8Q@O|i&{A-XBF_(I0B zJ1j0(ma!AoR%!<~VUqT`dQsr*e-lixzi+3+WEfEr>lWs~E#<5LjT1%_Re0B*nK%gb zKxB+z?e-@R!fZJ+iz}S;La0 za+**%I#F(fXtgAgu96C#2qlc9ADrt8o?+LK{WW0~xSxO-8RA7XHQksMcmA?gVd2F<^dC5u2rgLoa0OO*i@{8J??U+O+4; z@sK3g^JWO8=@NyOUkbjNRXTn!*YouAm*Gs>k+tA3ErJw>u9>3xu0u~1mP+iiHMQe@ zmGN{pCfOui)%OY@46^wZ0 zR4}N)V32A5cJqYi)Yp=L%3!}xOitn|!>_W@!k_aeM^>0ba`R67a|S58f%1dnJ`4R*W{Ix6%$5Uh}JQCA^Bf&$8BqO8p--U<^srb;*=P9vF= zwwF7GS4kt^XVT9emF_X1*;}X(t-;Ly!poB49WfEk7jk!o5;hYUN^^Cs|gf)h@X`EB4*Wl%CYpn!i@0utq35^8tkXVyXzL^lM~GlCd(|;^Kx}g)IQCLWg*+mo3_dX z^|AEfqeT1J)3mZZ=~>6?&jorwN-?t;9BS|{vA#2r99mL_*CI48Wjg9NwAXAeXAbz2 zEm;C8;(x(-9JWlu>@_N33JZHQ+4s_K9i`a&5>LLher}$+n|{f8PW*pp_#msc3>J0Y z@uU;Fz<>B%=pmmp#G7zvbzb*|U)XlEu_# zim(!MJ0b056mJ`HFSH?)Wupcqx~cG)VZ(^Gk!J~G{ViFOMOu(8VCfXmP=S_Yq9fmI z!XEj^qBni}47?;Mg6C>ZSyjCdO`us@mx$}t*^I-I{+ein(~quR3U-`xKo;B(i9|NK zg-V$Fj8n{t!T$B|H-&qdO1t=p-=NUVOMnCb?ey)G<^IQw=n#9+pUO`Ar9t{R29RH6 zHr4n`oHEq~+f$?8v_o3MM=E#=Zs1~Jm?B4O*Vnu*vf4!Vh(<~*5*%ELA$on?-+G*K z7$ZW2r1#`LvzD=0`Pbn2b6g-6wLFWX=WO&F6Huk$Q!U0=ViG#oTUsXLFGrIOtDeE| zBYY92l9GAIW_c|U_Q&BNLU!>~YS#~cv$QV78qp72mY<_@tg{FTj73JM%adh|%JRYV6oBWdhgju?Q%_(`hJd|fJ zK^>mkU5a58Flw^P%y8b7kN)`l)b%B!pAJd@Z7r^pW0$*YQN@@(fnSHPn;~ZS1`CufXV&P{OHcbH|-OLMFk{Vz$ zbOcevR$>u))(<_R*nqK2d$7k|LuRa`tp7?kQxVpf z&F0Mn{1sz&8TY_xBYZpL!3Lg`&Sl6|Nj2f3wsbOr!*oC8hnkAuK2#jkdn; zjhsaE2BxeO?g$yhvRXwpVRKfYX%J19VV<@%OM(1dkf21xHK!#%r=f7_mRBbXhha7i zJd9fpBeV!qBV?s+A9|{~+2KLh55WvWRO@Uaujzk^G_k0}7kDwT$nDu1r3IdE=JGx| z(QTj#?%s$QMPP9mxVl(O%46>74L?GeV1y0@g1lMXd_Kz(77pUGXf!27D!ff|0|DE+1U7qcqr%Eefv$DoUnbZ=Cag95*59v6+ogr%M&V~JT;7_4{wlUu*zqC7daa+h#W_H$*a%`Aa6#pSd&|!EYpTnkt;Ne zwS4++$&#dxp=95LqmCJ6twCrYJIqP`!zdNZEsfG4vbI`DkhUGtpz4V9QT#xeJ>Hv9pVIGN!7K51Aw!Pc9&U-CRky zO3%;QFTR(G9NsL=3bM|L7$pG?S!llNzha)AmtLFcoK3#Ic#4Nq*n23de-(rds|@-T ziNDM!$J1Bv4yb@`mgf!m%>wZkf(4$65F`oiid>d!w!vQtAZM>uF5dJ$= zOBNTb1KwWR&$)~x;si&HPoV*-BV0^CMGgOz%Y@a7oX`;y6QjsrP##fvhtj`Y_D}U+ zhA`}h*lo!|MTX`Ov7_mK4+~+1N7kWNl${J1e!8@&3IsqgB7=QG|VZb^*R!_l>)zlwR2WmwBRQ@4X9~A!zX8Q+N&Cwrd#Gr|Mgt((o&W?zI&{&z86R zr&wz6Ygr{OlUN9m&l8<2b9onD_UpgyH`(SEgR@2hbN`cP*j1)}6a1F&a|q|aESbyO zTd=BDsi>QuQJI5&A*Vp+iDWpIYZ+!&`GAaBxg!Oda(^*=&%Qi@)Rp$#S(_x(m(7ND z4e9gbp9D)o>jUcZjLoBQpxbD)dbIHB3SGXFK;4e)W(H34QuDsl5Y7UQU9puKtbj4SrCe6Sf-9xFpWl^8vv@QLWcZbn( z`z7_sj>&s@0_)T`3@Hru+TU*@%+dOJt=qr3!p}o-?sS6)0 zM#jE4veap*aMSycW1=ga7>djncP&m`H+a2l)b4@hNugnX!JtursFZ{;;P}VEdSG^I zlgX&MfbpEqXfsEuU4V$8PmFOkt6rg%)KsKf!)rsTCOsPv5 zYTQ`~)+SNHi@}1Z)O4Q6DGmP?GmDjTJdp)wp75J7?cCdcHLwO|jJXTJy^U;K9u4)A zrDRH(4PE!i|h#a$`?@HgA3DR8zaxg}#kHL}Fn8Nqx z*ezLR%>0zwI0!HJ@zFI>MU>BEiaG$l4TG|{UA>Ubj{r}{wl_6`tVrtPpPk z$2x=2V{=jRyo?{?SD80Z9l}uBe*7n+p||hF_!xt}@+H194R^~G#iZjFnz8D6ukmdy z{Bl=Iovxjv#Bk?^m-z@rH_v3d@K}<#X<@L9NbycviC~#pyDxGMez+n~5*2!LGS{e1 z=7y=F@&JD(Okho)I+J;+63p+*NEULc?_@aZF6nx|io8Ms9VHgZ-G#~OfWhnhR5}Wy z>n#4BhaEGG$M5Dgo8)(*xR^2W2&BwRf_HMI#YY;i8MVES@c>)Y3$@U~(m4E=GH=Gr z>{=L}Zt1g3r?H1YdYCdJhpU2yq?`@cOA|))8XK`C_j??>wc`HS+-kb@6!2VBBEQB> zWeL?^u1!U20brY8X_EIyLaRb!FOBWn5hSwCZQ!LxbNixCS;!#kH}AtQ!2=jRA(e~r z&DhFCJ65ZS4`EC*=g_y5CE8;gadcDHk8-E!POZagJs4ku_yQJ1Rg=Rbrm_b@2)SV( z@x8Jn=%{Xp*Rn?HhG>MsnfhqW=H2Y`+ToNV%AKVdb@txdXml%M*o>0O5ov+lF7 z1%ukKf8u)6JmJfgt#XEcJKWtDS{#BB$ni$iDlzK(k-_xkJN`NvRoh4nk*tgE6T33e z&%P!YL&xUQ9~)qsPgx9+!*8QpKeEiSD%IiRsBO&a?`5`FB#4XgE=99O&AC=ZI*#LC!;g#u8@xD ziOdv=9W8?sQDy@1WLbXVH)VKc6osuo2qq#Fu0f$RGZp>?)+Mc>LD|vQrYsT|BRyxQ zzJU=>Ro;gXZ-cSHcFl+9<{0`(SSSd4R?x?Mz2aWGmc=M0DT5M&ybrxKX$E#9%Cd)v@y{*uw8`O9WxE-0rxLtLtrf$fF!kA^&dlL(QOknb0=-juq1J&{Qq_Mw)H zPtrBY(B3q&PWj4P#~W;QZ`9=t6VKb0=^Z*5=REGPH&Gs@o90 zBgs)$PtDw~^n$`HotgkK>oK@xm5Ad1v_4c4=5D@vKbrZdqKTw)gg8yE<>?970`mT;*30l?`Xo?JZh+d>32MTNsWmgimY*w4Lx-F|2A?Lv9X!yp4sp z?w^y0(ZQ1Q&LQxei1z5|7Wd$;h<>%GAl5yosi-sO4$=X=oRWz_5`&4t$YqEBG}~!( zSf9a_U!Q--NId(n&d0Uo3Mm?f4l{D{zu-xq*EAvvyw*; zg`Y2X%yMN{i_owS{0P&gUfX#ui2mqk$&rCs^#k#{n27M2A07Z8W zA092YGVY4?c8PH@^deQJ;I#~+Ci3mp)H}l@ssE7S1Tp4&v^|BOLF+dem#AudhL3J; z8fJ^6u{#+}B3K0sM+-=t*q2_R&RZGsika^miA$w7?MC9eNgsMRVkLfAom0t>@ z1+Ju0#>632cyF6nXOH3}hoM(8Catf4Ju`#HRkK&JvXp!!{BlVKs1{{!lFK)pMXW;? zY=DS97dM>;VEEF+cw0$ZZM^6`8Ig~DH1eB(|R2e z^P|DYQw0C0tSpA$y4quC5ZA)qF|24mgH?)Wxo=xz7i45Y&eDbY6U)pix^2^}Zrv>X z5)I`1UCGqsL##&9D1SuVG8X+N-=WZ>;juv&y-cXO13A5x$KLn*W-d6dKpXP5 z<)9lN6JC`u$nL2uE?15)4tvF>DNlhubjw*{n5Xg#+l)D|;aE+7b2GGg3+ByTn3)ZC zKi$g!a7|-YN_h^=x|KWz2SSqI3P)Y4!Fu~8mR%eM;dpnv++V{Q5We^XNJ^I2c4yER zQi}ef-#p%P6kgq=FmNsIU1TA@d%(+c{O7Kw4_V&B*cy6TiEL||AauT<8Ce;RsK8^x z2X{$k1F7JjVJ^Hi%z=TJM)#8@kzU^OpCDdR(Ho-12oBxsl%}U0+b-(EWq5&0B5%Lk6;|M*-ECZ zo7k79i4YXa65?y;(YhdXwskJE9Xzlg`KDX&Gg5$U;F-fmf;O-NO(Jn54_ISA9Gw*F z*Qg0}*u+nzOgBAup{SmQeP5%rF@?1hWyX-P-^t9a_+yV+GU15s+gViqeGxtulp5w5 zd}QcCw9n!r>mJ0I9{&PGn6=U?+}cYk6~#YUgp<;(o?s8j)k;J90U zTHV<@R<%b)ph}EH1zYqdL#9SBkJoA)0*4Yhh`Vns(_U=3ln>^9GN5Q zW{0J3lgbd$@Q4J{wY&jCBNmGz+dCP)wv=c5Fy1KtH=Mi`1#9LVQHz@qJ=ZgTj_dkb>5h%T5eHatp!=i#2Bi}BY@;={vzXpeC{9Zo~tMO{QRu5oxV~_5TSCG`Ov}xF>o8wCB;=IGO?yW1g`LdqG zJsJ45{?=QnQ9m$i5Y=Yrk7#r3m;3y*c%eJMt%+R-HrlT{h9JQHyPXT{M^XRy%JBW;hhZX^IQmgT7yJ&cM+_}MK04nBez z=|;t0K7eU44KlxFH<@T~)wC`x<}$PucB#Z`i!xbn|2>mEPD+9cca7PR06ol{^=>8u)9lwRfNDGp`az{Aho`j< zH;T`2Y*>SMC1qY( z!kDB=vaXLfsA~r_ZldCC7*NiNN$>DXEDaJu=xbS#CnKfXF5vuae2A{PRhk@;U5JfX zr8i9j(xL10D>={2Sc+f4q2Q!`vba`#X5HT^S=j#@k+X<*ILwi3R(rfziPx92X4WEy zle`h_pO0)42d`XE2WMan)23rv+@6YzfTl-9diOE^y_c^$C5yvkqsYi=wARBK`hx8x z$QA8vG5nv|opjM_Ka-hTLDoDxhn1<;nYamZ`@%Yp;8YNnGHE`F8EQNWz~$z5?E7~3 zxrC$#Z{#k|fh6zUM2AY5yUs1#0`*4klGUBk)80|O9*`G?IqY*;^@+-Y+bn8Xgs5c~ z=gg`#uCmpDt?ut2iL_PKkXTo!A z-E%iVLl^W0k*KPM7zhJ7_1)c)UUvSmqK3wVs?7oh)j*l={iT**z6AIKH_0$;6Ln#@ zTS9~TYYV;eUWQ-Sp@uiHsCgOKrX8vq*@pe3x|*{7&O|QmFSrb1*v#X!V6OYyq`VFAZ;(HKf&p1`xqiMw zuY?wqllIndR}@ceTii*h zk3=|Go3j>O9~yxE@3s#j^jOMh7?mi!ZRNVKKv-F*_b~Tu z)q}rHekPkm)$3DXfc?++PW#b5lYHBlFTsT+HY4coqm!_TUgua~$Tl{7^iDh|GL!yPxXB-E+#nleug+* zChd#EMAAE9xB1yTuwQC@V9>Z?w#L2z5CLgr>|M{XqxWR3SsTdVWqTQ2r{P{mqJ9Gq z{SM46y4@&c5qf!;s=x};*u4(xPR!Qi4aRoNKtW!l>RaG=+I~fd36Hy4H|?Qr^fe5f zVFHJdVqZri-;VDbmB0aMSjzz#YkF3t5FD^V!8;fVHDCTRrXf_s{4WE5|Mp!ZK&Pwg zK11t(oT7T=q2jbc+s$CgW&uRqO=+bM4^kvOB75KyO%$W#qTpCUp(#L=d2a(O!6799 zb#{RLwq-aAPuX=a9J>knS!s*J@H5m*4kOTFby$zYE=VN-S+II0k1)e)cd_onQUIMh zn21;mgS1i&<_i~bd6LBhZhlZc+pN3LP$nS{-3(#)Hni&C6uwNBA>$}HDfvoXWgJg0 zgy@3{qfkeFKxBA$=zKyL`(t5b!L+WHkqHw0q;S{2ykFty@^z^iq2GY#ux=S70xRSc zSino1UzJo_T&!od_`T{@WS@}n^g{5EsL+$^h6O!bg-dT)!p+;=wGumd&^1Ya0ub^IFmP_B4 zX{dX)2-Hr>QvMniofq~TOpzY~OS~o;>KYiHItX9+rPuv#+BLSPr-eIssB|YTscKZN z^T7p}3_%~&Sg2$Ygty|c@lM4sZNFAJ<#%u5y@r2Rv8&^yM_M(QJ8}u(`Q!4G{&*)N z6HQdt2Cnmi46rdLcMoXs=`*lS&3o42g>N=t33YuG3i2sFCyBQ!mh!NPGL?Nh_UVTd zMP+f+b;zE;&+EQ+PR?NLkLB0#pyiz(46d6lV4^X1nJ@dF`82{DvR=YBA(x_^V4OSMi z^&2RHq>C&3P+{H-AM(ZiDJr`PB%)xEz9twR#1rhZU0p5N%rLj!DU~WinVQFOlCsYy zf+_WgCnI^jyX78zgae;85$6%Pv)t{x-B0+7Fr}(z%|bAA&46eR<0JejEO&w(<5UI4 z9|_l*|D_^SLXfsiCL;S_Gjr~j!{_Z*Rq`BWWCuIU!d2AWF0C;5N5)J-9Y$ViQ4odv z-hRn&+NFD)~ZlUnN`_2n6j==zp_Un1uLC? zMa$PhD zxgs1I29SB;TRW-l3vJ*xP9kseOa@L?gmkN-Jc07pbMe*z^?S$vhQ&7O%1=+D36Z=i z1vtR%OP1Mnjqk6+#J*mko1++`{D<$rbF_ZgvY}=z8j0k|UD!Dmc01aljHK4M!2m|U!66`cD6Ux zFS12Z8xy3onJnixzf-l_wA#_nDW5o4-+?SKVJj9}0$~ypl|@zS5yPex%IK@Y4|PGr zML~j}K9y}Dz_5Dh4~&kMevKkcFu+-`+O#RPT{4!eJd?My5Rz>V0`i>}$#k_~so9<`zhqxG(q z8c4b}t0$_^+tenzM;(@|9(1xwQ&}SHcSKTc*(fEoiRt{hng9b1zsGJ$%xf>)sjucn znmB6|&WEzs6oqpijZL$f!T)rn?vH#G!{&;IzrwqoaTpE%Ze`BhhIt9bWCUt?AiO0k zJGn?D%jRX+zASB>P=PsDAG?)$9;x5=U!{t%&{W;D%@C&8lTeOihmbK z;olQsO-2D-82F@=GM_IDa4&!%5-3YDH5bWui=wZL;H?aO$Ar4}Q>s>C>1bP9QqgJP8~x7E@_tX2Wi$gIZ>oBNrS zn8kXT2JSTrF!lAJ8~#sdZ)OymM2YVgaD!`yd6%b=e_c%6tivER3~ZyGzeXhjUaz>$ z6Je+D2NGsz>;K2aJ-4lqpF%L60`TA&D%e>Us|3%g1ZmB3uC{=Yg-27o9N34cf;fL# zFiUBdb**g7-SA;Nnr1Gw#S4*%XO>S0xI+PtNKg=+9qEomX_nT7(l#)>K9r%X@MqJ_ zb>{io03T7eDCPsGVeMCT$(vOmx5S2(z<(dSqI5{{*au4^5xS80V{_P(=Ok0F$C^7r z^$nj1e`bD2T_1r!jh+5BU+6;SEF28xZjPM9$e~!5R*0sWV?K=`uAkhB#AEp4OoIQQ zmt-iNwi;FgUX|{{qxE!>&U%S@4lkc5i}yibTFX3qVg|>HVw!&qZ}Dog#hcKre*-fG zQ#cqN={+#&Wb?qeQWqi1a1>}S6NM(}&a9qmTQT5iV^|r<$hR>KfqmieK>UP${z8#r zEMrux7)@4IE;q5V`>32Oqooh=KHgZ{iwvz( zXhI%cBLTjIqh!i*JzGuG$z0=!^k9i5TOc&KGux6E6^OY>(%R1tK^T<$yjyfiG0E--s3 z3qlD1@NQ5!lDjgd&8<1t437U|b4Znty>yiL+dO7!KwrXS4l6o1aEXErFLF^Mz62xF z$?cmYZ|L(mm5g8D>4{F$vLwlKd3-LY73n{L`^Oyh^B85P7Rrq3yf5>Kx36UG0JP1g z{0W>aQD4Q$0cRy3e=VXM%^QdqGh9oH(vdKbB+wo4FJhW8iA1R8GIQSOsrC=hML6Hf zX(7cKT?RA9hQuc;x|*HBUG5ONNpJJdJrvQ%>NI}fn8e}!*_9DKvoc3~a(ePN?YOw<6D z8}ZZZaDn|;2Z)~EPHnNASX%!Le9G*i4jpCfz|XBbrs|YIb<-q?Guiige!7XWm~Vs0 zGlt1(TxLh|{}uv`O_&{ng=}F8$&;Do9X)annX!_Qd{Zm#Np40PnxIM;y1B1F+@dRH z_}nt1PTf)#!+LBUER?82Lq_X$F9voJi(8~?V5(HTetDB?J*Y3UmBTiOa01bpPk4C# zRpE)efhES#G$>3m(TvUSImoxpt6hQ@K)!vy?DNv5ttjA&q{ytwQR`6_7QZS~UA+gR zn@Q~=c)-+y`zxc9Z=5}?wS;{whq!y#Tc zkUPaLT^Hv|wpshAI5gS&doms)7|&Pd%(}J=%jIok;(ZLcS+yd0_m01~?MOOk6BE3W z&r^|+;b(CMg7`n+U1$*^^fU0Lqq>Ll6K?-iu?<*g>bVSTc^FN7HoYqC8eYIuHu(a! zK-(u5FTt(wr7ZGfG|RM&+va>C1S|q`g1KwvFtbG9=`4i_=PUFE+5P`1dgB)Ar8t&x z%b)LCd4vYU29bz7+w-&q;(w>vr)(jkDuuhpU%$ZDHywp)6brK534i_=z^TUG>n7l| zS;BM7RDU(UWamcm0v>ca7ZfT*zPXf!Ph<<(1DeZ}$xn3CyR4Jm!@xakZrUGnmu`g+r476X7PBtC?j^EGEFxU{5F^gGsHuooYmo5{#t7EIbSB!o)Z zpf$!`DH8R97g$}=G<><2SBa1&lZZzV*NOeX+|G&9QH40q#7*9%L6zMS51o}NuJL|J z%=ApjFdc0T#$*KHmyzvY#_;co;x2Y!@@5{W!kQiotPgilUL-)zXqYiQx{IM*5`6Ta z#C%2p9)3Sh1Ak}({6SZk44?E8wXg#={{0qH>kRLb=)XIBV`Vl#l+W3WyrUc$tHkra z%jaoFt;5Ek*!4OAh}gVrp3z(Sa~Lzhe1&GLMM2-mU1=u|F3X0{)J=GVuCMVsWoHWf z(t+5TS+Jr#fCXf6Vz1VYg*WL&?(*_OO#oIxQc+Kq7mmFyR zO0=ql{Hm59I%YW415xs&Z6h7z+GZU2q^abx1H0EKUQF!chLfZaUTD}&Mf zw@(7iJ*@mxQ&Uiv5^o;WG)Vo~a`Uh$<^;I(IjOEZ(MD?eb@5MRxl@N0i_S}an1})l zb6Rg+)xQuXZ+0+LqVAtdGI3qG>IGvER0Hu2GHN%(KyV7B67~<>Kh36w{U>D+SqSJ_ z@r$6@hX%4$7)Ds}?x|czdz|0c~V#QYerG|%s%(7~ot_XY0 zyv;(M!MIvQH`O3QCL}FSUID|bBnoDtAcQ!n@sArTtSTrhUDb02*MS|xVGhGr{Si0a zfE=5rnE|9ge_#h=z3^ni!{`+h*ug9cUGco9Y}bhdA;K@~QGfiT(%_rR{S+boZNA@gjGQj8Ecd$KRT_N6ey z@a^POGh^;|MDSzH0L(t3(HLF{H$i2}@#-|;0WRBzM_6U4UXgnznm_F6yI7zW8M0`n z+VDO9M)Z1p2N1hF<&GLeMF55c%ht3*$f$Oa1&1mpBU5zZB|kmyb+8*W0Cg$W6Xu-A ztcrUORczvtP!0=_9@As;$|y%bg_k`Xot=g&Qwx6V9FUjpGgxmP82EpAdQqq6x1X*O z!uW;ETUVnGpY8T>6_1Ua|By(-O7_)wt;7H!zj=v@MR-P{s861eHl}4+AbtOztOY4! z>rp}&xw+gjD>IdnI}sBWUT<5}En{*^e=PFTl>Uye%u#*QFfn)z(!LCzT#I}U-;U}T zv4$h*?YJg9goc8=1gO3n4VK86W&7<4P7-q~gcZV@=}~mE#?@hg`WGo@X1>ozY3>35 z-VARQSo4%%;~Jh*?<`U$OEZ8a8#4535zbd6D}Agbt*nQeU+~}K zP->8PnqeC@`0d?i!(@PtF~Mby7MWsLmBtayC)jOY;sOZ2x^LM z`>#yF5gr`SJ@G11ZfCow_gq@gvJlwRB|3in{ogE%YhPVSAE35FIkz*n!=J^EvK#)& z-DDX8b)V8{Z|Ckay=z*VGJJIn=Qc9+4$;bF5R+er@qD0%33VGt!OigHp9s$}@lFr@ zI-4wxS$GW|W{_3l&4^^^;aB!uE?(yQC%IJB3x=Edr&5>4<#eqg8 zjZxU;T`xQq9Hnk22;VydUq^BMGo`gD!Rfo2_%@DAQ7R&Eb$Oyx?Vf0&&5Hp zr^v<2Vyo2&VqV9=&Xt6kx9&x%%{*^~Ff`g9$=3{ckfs!+oF*#UjjSNjEXL*MZQ$w$ z;`VRq_&&k3eWG@ZDcrinD1zlXcIfJJpy~zt_WK+jp_D8Y)pp+IXuqSNGOQq=q ze+Gg{^A)4K!<1=pr8F07_!#ykWVM)W2#{b&{#CoubofmO%fQ-T@IV#Kd-=Ixp8YCl z;bb&FTggu9j&nD?@8S>V#&Fnis3gRZM@hXmAZ;qh4O!0oqp~*uV6#^ ze%qk$Ll(z{ud{%>1cKw3QLqDF>osB?c*y&))`1Nt~jS=IbiO z-eF~jS<+R^vx$mpFYsIN>IAviVs0aWXU|LJAAhowe(5$(8MH-$`w#J@rqj^`MQ<~Z z`IE%D(>3@AZVRIiXfvZo#)I4t6;`C1u$xhxK-9M3#)MG%pIA{%v8%FBW-aP>Uifuz z^}{Kobq=R0QAd@REL-ygdBM~ceTs|1;#s0~R2(QTK-Sqc=Wti4IvIvv+$`ZhzLY^J z#j~uy2625^07GUogW(IUjHz>Tq1+`x#m^Ef&N7y1ZG_cSK$c9x|BTb9o8jSRkaUM7 zMCPs8W;qEJ!Pw~(-S4pxd_PMkJ8GOcbsg{FUBF^MdwDvL+JwqQmXc{gmf$2T(X6JL zOb!1IsN1A_)1T;6Wjb6J21`4EoX`?`c#cijP0{&hB;anLHe;MU?n2-}-<|&~N|mV( ztdbBslkeIY)1@6o7=D9R2#rSkow}!tc5=hAG#J-W=*)QC04oIrKd*dlOFvW3XQ-k1wf6blwZ&qqam7Pzd( zS`br{_fiQR^)i1lKgGB60GQNRlyj@eybl&fkB9ixhvW}ye<~om{;G(lGlI+w`JlS`cMFF1x?$KYT2me z^B#art#eU15u9NgGfV(9dnRCRc8rivk^)kYM}~8xtG9b{BhKphL)(Uc~%%1 ze9Vf@w#VUZM{i+77T{<^R6H`WLMVT;#CnZh+|PY=UvrS>@R+6aW@5Sj3o;zdm?1w4 z32ZinbPh7pnAc%N&A3M$>Po%lG>)(nata+2{tAtxO@i{K%$-Ef+qK=fuV2Yj1bYL)z;E3t$25@>7Yf_FJp!6lZJK{912c5lmonx!%HO$!kLNc(;r)6sbCjs$ zs;n%F#&oqz)Xo8Iar$JuEg3o{Fx@24u+6awk9$OIM&9HF`=C}KR6RVX*{0lu!*_aQ z|I-zL72P^lLpvUcSIYDT8>Mk*c6>Ze}H%wS5jfE}c+ zP$+5PVDX~l?a8nn6~F|;mk@%H=u})x<;uiBRmSU!F#2FA6RlSl&NNaRWIr;&T7Afx zEA6)SHKe+_>+xyswGmSRql{>ZZLjTF)F==|GK21wEQm#?Qgz$3=InD!`?7dOw}g#! z>e-*mVPR}?f1oEoba)mrl9VRM4;*2Z-ox-@RG20MTIrCm1~ww~Cy0|JOTT3C$kkR* z>3HrrQ_K>~u0XFiYLT&3s$#Dt1anM!upVy_9f|%xbhcOevC+ovA z*ag4ucVUOw@hwK-NS6N|{!qKp63t_kbKUm(x4Hn9subedG; zt0Eou%xAbnO8dRWQ%CGDx7sdMX<5_kYUyq#Mrl?;I}p9tyMWM6RQ@2=%sT9~JVcqA zjl)L}tYovs02jeez4oVP+xA5Vxt#C$VVFZ!tss(;=qZKBmym!4lt1kF#jdNBP*AE~AdAI2~ zyK6F3x*!3nkpCwc=?n@(NP+l61`ilM+sm?B+>v#FaYm^8z48M2&V#*EoR6@*as!@c`$y%z?Pk2fxfm*l-Y~EBDFVP%`|0y>0$rE@etJ>Tn(rA*mp8}4 zFtr#M{AXY6QunAq=&s^1$dPiJhm7{qc`NDtWF%+&7^exW=BpB$v^>OhVT{Rv8;ju+ zFYl${WL=oEs?qyJ##Df(VcMD3f()S12Ni0OfA#&u#aylS$`hvfdJgZ-8$8OUSv8hf zzZ)fNuH&FA$@V3G`OM2Lvp^fXljvc@f|6n#!#mqr?v^nF(n%%q@P#DUxkcLK=$^PD z!fTea|Ay5&cB4K-?-A5O-}=`uFOm*z8xux#0%=jW)u(kyQv>1bo~rs0Zi;V9swavX zKCY|Ov6dqZcR6+tN)YYwh4LE=Gs-ZagGd=Hk9U%Re6LLeXxkG}vH~=Hv1dXzMl`HZ z4B!gBj8#mSJCThs*1JIX-!yB%f15raWz;iu_(LGPXGxL@;csR=a5LZIJo3Z8gRl*1 z>PW_87R`;)Y*A68gOZk_4teBw)#-$i&qu7NWB$8*q%|lrSs^ba1kJ|`0L>uUU#-WfNs}XfR z)K6}o#tMFfnVJ#G9D91Qe3Uyrx8VB1T+FHwhxZYMVL#rtgYLsT!+|7JGdb=*ON1A0 z-!4$CL)eI^W;ez6+Voz&BzN&#KECn3u<1jTVm`iKSSa^n)UC9B4+X#i>*b3*3SRWD zF!5e>f4Y4YSh|Y2}N9(p;;1=;0AfS%h)`3+&{MwGngD?k7CrZ*a!C{Ma9B zD4EXqIsOmR{bqpF|14=9V;JAT0>IUS{U10F!a*4&zMkXVZIzXEqgrU@FO>&2n61Lt zT;oP{<$35bI!x2f>X%02CvlBDnLG@o@jegzawa%LVUA29n+1%{=pl-1-_#QALPp$wTb@KZ7q9#mkzYj8vc_>7KG6YEoEloJHdrJ!K&G-T9h%y zq;MWynb%hBCmLwTj0YX?sl4nD@$~zp#PzH|V;!`KnS84XkSv-weP1H+Bnp$QL~gA> zZQjW;n4vzmTWa=MkSV$Wqju<)g;Ond66iqLJu7k6xuZpo+~b|4#kU1ZUGU@60$8$HC6 zoiux8vR`x&wtx`jxfUcQ(R^q(if6xvJWLd;DO0wL&Z?H|8>`BAj)tXczccMFPbe~^!>feim1za2}9Mj261ew)PEaznl%Xw9sydq=ogJM*(EI6 z;RD#cScg!zB|T+(H8Q#x*2!Jsp8wkqPtBeV)LNpZ&Py@Wp+&`862DqPS3EQ<=B*4;j3{BLSN$1(@2 z&2g<282z1n^O*Jx>>sYwU3h&8wf}Y3-aCBzM4dP&Dc<`$y1?D2#E#Yq!8&N0;`80| zB+%Hc5QT(|9bo{Kgm%5Z@@YYN*2{o4Zyd_%=1A_-Oi`V4Yj}xbX%)UUl6^A4CawT^ z0vWvFE9(;=x_t`1y8(-75|-sl8C~-%@1?P|9l~~1=G)T^+6-YkZ?-5vLQ={Wp zMO$>zhpgO4HSNwS+m^&gIlPRbo;j;Dj-ktB7fGPD9oaFgWy;@DZDsDvZ=gwdd`KRV z$iPWqk4Msv2?U3)%tQfLWfgrT&#-|=OM@^5PK_CSsa7)l$?cJ?7IrIvVUST3yIPjw zG-o`UuSyGM-F1kf9sz?v9h%YpLKYl5uE2oiK6JAwY58&3Fj)e;j_z;$3)|M{oZ8R1wHh5YJYMwZhqR zQc84fi9Ou~>S<=obnptA>d=Kq12ds6ucinC(2lYcdL4v^(t;#<6@Q4eU=~ol#*59A zon|H~q%gB_hS3&=w<*b;w))4_L>hzti7faANpjy`y1cw3u8*E!+{G#*uQNAgrApz9 zDyeIOKv>w3ycJQSURLVndk#WO3xtMet-KAIz81THW#qmS-AZh# zs>e`d(xN`zBNJGh;Sr2V4$xS#4pAlhY3hF0uC-hZ55vp5mVo5&f)THZs|y=1=4T?0 z(Dw4%fzYur`GQ-aAc&R#4h(nuadZ;eYiEvT6M9&8+P1TkWe;#z*#}@Y8lL&_hcl3 z%c*7er|2S1L&edqCw#I*?>DhjtWh~a36NSvXrvk zOL1R09u z31_5?zb0jXqZ)o2VY4F-VXoa{zdD@K4=+3wP#*q+0btu(|H%D+%r*jSD`p~A$>{l8 z^Le5;Yi*0S7>6KZm93hYf4w*Dm7 z&O~ZlP6iJEIr~-{zK#B>8OH0@u;J`ps%yEb^*t`)gigcLFqVp>_!kq|TGF@SjSe7jiL+6W|08c+Pn%8!<*QRZF|`QQOM8agJ#jj|E(A2~im3F$Fc5=!%DO zZNcLDwUh@lK2H~%cU_W(JA4w*YpX>RK^*>zo#7R5tP0mf#OP>)u09oa`H^Bhk&&#h z*t%Z`DpFqRYvaVU=wsmP&1nI46`aizOkF#d0n8dGzw$GK8d1h${>K`o#=Dsd`=CWz zUZJVOna|Kkwv4^rNeR;!m)iudP4|DD3T?mk!?7epg-pd!xzq5cN`^P@k~1rcIQ3@& z79`=UgUIVFQW z@8P*J<)sFX<94YcxkG*sZ^DvBJ3P8=Y`*X{&k_zFFGR#95<9TEX{Wl9UDRAe-5g|j z%(d}g^M^PvN11F}Y}ugf>$ZULSo7w<0XUs!v97_Yfk#9gp4Y2VLr9;>bbVVo__Bh> zw0S`pLgbAf8+2&vywp*tjb%dM&GzeRwYcfl!uV8`mtYX zSGYQC%@w^CDjb^%VVhc~U&CUX)`CM@o_bJgiF=qv&hY!WYyiR6SNI5~Z>#VK3!CJY zJbU9BSf2zz=-MQA>I%?HtO;Zh&WL8@|C=*L{eYQS4nBl)V?tA!Wr7&+j;w}For9`K zGqG)@t7zJ_$Ro6+k>SRCdQO3gW-{RpRA(_?@ zaw|A9W;`Ja@dS;U_;mXeQ5ToNfv1PMl;Q21q)=VWRYZp0CVxHjzlIuu$(F~mX;y}> z?;gUYjWJ{Wv1Rq8=8W{8PGU2%{82&>{BdAxmRSf^T1kbxgMp(n{!~QFr-Q-R!z3Mx zH4dMwU})Z^bK;U7IVZMBQa+xLneW!=B%8+YT$KTdPfewb5(G5w6 z^aEpGyLp(hin@Fy+*i68Gm-$0vABi9BTJUNnv5BLw@$xY+ruMxJ>S|+9)5)FI7nKz zaB$XWl%Nw-7T~e}gF)H(Y+4!A0=!gfHvzHy2t=7BEUE_P?SoBQa==a^Pjw~poQNmE zp&%}XRn}g&kN{5Gan&3i!Jt=F?&EfvnCTrja%`cyRwUU%O*Y-S{GI$QfY+_>)g7E_ z8hF3Fnre69!dnUCy+vJ33)r??X`4GT`XWTDPXtVsZDcI3wwZwC zOIh0F$;n+xatmrjv<>E&#;AyO536brHYZq8cHq4myozji{B}ZViqu*k=-USq0{cM< zN+g@aXm_$8ww43%mJRuha>i&_-Yw7*BvI%-(EU^YNX9hdCWVvXQ#~a}9daEqmQ3Lf zUqq8#hv3|N+lFL%Q5F%~4(+SpQA!}`-gW3Y_e2Cx!R}L=^6d6h5zGW>P#zQl1pHp@ zV65!gshK)@RA32U8zpZa5kyfttXj%cb-LmG-MH4tYaPaI(c_U~_hg;zQ1a3oNsbe6 zc3A}7|8m;{Mg8IV4SP){wERwwpict!1~4@ z8{f*97=!J1HY?&*FtrGVhbFC^(-*I#G7R(+;_~G7H5r$nRLyaKQ7#Vj9f zcKDyTY!(;TN#}vI;EWvmPJxlPsaH6BF_26r@rKn3PI&^fze|&MDIRw}2aKR32(oyg z!H9h)o%JoUq}?e>itJ;tfKAY9`*XD6EX$*n&N-a20p5Um8sE!tNOmCWRy&l$w{7J@ zU{qRraL`QXcD5+Y7PI*RmtUDckMLyGiY#}h1m;;;Uz@Q7MvBq|?)>=o)hN|7!nTb5Xw7; z{?leI;xqKdXlJ{9l>yF?#N5p0*O=d+^@L~l?3E5}+GsOY8F->W=T2f#u%!fbW1izN z=r@?+9Ts1$u&W>iC>A|x0=v?C$F7DMrdP>>%phLxPGg=F$BP4q5a2sS{IpEj>TA$0 zC6;29^>%^l&b;P_uRA;`G?zHZu!P6OTDz`7S9{aJ=3Z$RW8@7;y2-BF;2T6ODfdc? zN~H+>Fci-CbCf;1T6~`xX?QlhdVruip2%eBXtmrk0ksA8Au-*oB10#9Oc&SpyXEF8 z4vkTib@Lrgc9U7SDP}u^?wv=yq~gE3cww?|+S|yWjxk^_2IUO8poT3}MBhkjRobp? z>Ks>Y!gqP!Sp88~3bQd}Q_Jv{8Rw)itY);V)}SoX!6Ju|Xx4pWPJC(@r8(PIq=9q+;Wb2YfW9T$KHd{BR;{y(+zA&ev2kN+(1wK zz%iYu|Fo6nEdpld{ID%?F>qZUQslRPyo_#EdjBtSafk0M4@*|cnAI|#73XOhJY*E8 zdB}JS3nV!;Q>CT+wbKPpYo<1l-H z7*oJ#h|wf@{<7S!K5Kf>Vv8jS296zG{}uE^mC{%oB7 z4?=x1faSL};r?OHM|m(YJui6j2rF#SR(LA>W6<=qfLwVl11C|4y%Q@aHjs|DqYpN_ z9kF?A3;OV@?#OF@X4GT2M|-R<#bZuz>mE@h-OMqF#DZ9VVMf#}eEa#9!kPCWA8$3y zDFT|B6;ur$=nrTP_k!%_E9R3T1}gcp%?>ERL=ifPn!uKKQm`<;Z-?bXb`*}bnZs^^ ztozPle*b9DBy`eyqy!%`<%B9KJ63S)PUu4tffW+>EsUCOAmU9dQ^28+B%7j7}fou53Kq z$`5SHSQZ*wMq3>;in7T6_2)c+Pn7|A_Fo27K;55iQP=%fR81CM$RQqt!&>}?-YS!O zU4)iyBL*f^CsgMTQ}cR?GU+}@fHj`hGCX6wu4_MPl$i~7qpf{VwC_nl}60`%##L=MUih-$)=rt^t9%KP$&=zL)a zm?^F`k{qxDc&nr_%#Tk;9*O02ENWQw5j@V1B`bmvwiSQMLleBECqYY zC67fhEuX?p@k4S0LH1)pvn<=!+1{=R8rU)cDQ%KF+V;x!MtI9Ef!FWF3240z|2tS_NXcilvH>ek6>lX9hcEd$f!{(d4< zG}^}B4YmIIGu-Bp>g_f5tuq*;i94x^Jk&lQ$Qq>E!}IY68qTXt8gmj^gJrQ|8gFUE5E z9|+1Oz~*r4c)jKx4UrEYSx*_;2=QTiQRMr!r;sBX0ViEa#HN0gF7`@v{*W4BGcb36 z3^~lqc*Yz5`QM>&LF6J|;H?M1qi4Hzh~`iC*C<~M3X7EdzDN1qF2l<+wc4*lAt=Paw|lmL z_OMATkm2f7t;^fr&GsS(773Rq8V70V6mqdxi%z8#Y{>kQJQg|D(QyV^DQ5S;h_O`| zNNlv@Bx6n_1rujt`0z^Bhp-h?fn_k6HLP<#ceB>8>QVhJb;bwD>MVd>BN$tobKn02 zne<5XEfMS_yv?orA|=q-(ZIv!D>RA7t<>f_%r~gla;l$ga+NR=x5~fSFTIGW(+LWK zH?zhB&bY&Hoq8KW-li2ayE>X}yY0Wc)CsMAez=i&A&Oeh(*3uLMqVy6+MWi;SsHiV>F? z9$l?VR-aI;ZovFD3CG{?T`fY5suKQSU0ZbBe&@2_!+FzA6ztr!u|5oI*W{{I-p`=`gtQ}DQxRr?Qz-f-`Gd$Avts?|BHkGhQFv~qZ zkw@qd-;Zm0|2&sVtyC5BmcbM(X!dnHy8fBOgVV48HN?sLJju0y+Ly8wPG%NM`Y!S(LiN4%!*XC2UbYv0}oi z^B`H1G%j19#mLA4hEE}5H#IolTY>NM5Xp%xGSm#YjS>i{6|HV)YgnX2v4E_PP0P28 zEU15F_LLwkL4)a^JLi?Ra4Mv=+J^BQtFo<&^`ixz$2zOujh8& zadejp<=%eby)JV5b_43>m}Rwt1eb-O=(K1(O(P9{4{!gRE^QBx5l@3Gr5 zDwL8z;aC5jjzl=8Kumv@WY8o)K1Xh(1U+O%{X73E7@<%XKVkzC-5_6P5j)rWqEoRT z0(~xWbv4Jc1a}>##qvYN0_PUDw<@j2R2^Cq8;Htx5AB0>*{@&Jl|$yJy>2uCxG#Cb zUqTc7eP|X~d)r~Z4vvkyX+!J048fV8zTNFa|EoJQ8>f}SzzJ|UcA}jtmuqGUZjPaY z2%dBW+paPI_wcz{P9uSSZ^W^ow#W}Myj9;@w>h0St_W}FE(2RNZh0&H3awshRSown zm74$L5e(o_%kVs~i%|>SiaSB_E!_pg*&l^tT8B=gRbZcCB892UjQZXyB3RTS=z;1XpC8hxxfoSBkkUHEj1Rmn+Ju#u*FLm!ct+M6!Sfb3mdmxY@?>fvSgjeGi zo9mpH5ra!g4w1@6{tKx&s?fv(!>N@Br3k*S(y)tS}lybX#2brsB>cXrQp zWs=_wSqzHW$^;2#9d>*jXW{bBn+z0)xSgA;+Bg`K#oY^c!@j*9 zz-a~@^9_gqGX&d(-!8>`+w`zgv=lmYr&CA!Ql^t({^PPqjId){UK@d58l&1exK2qg1BD_bV8bhjcQ`eZlh4c6pz{UYk-|EUud_ZiB`UhiyKU zXXrx9>r9)}J?bfibII4JqLPI%S$&-rR1I&nL|d7F07uVZ@$h?v$S?KpEHpw`U`LfqEc@ZIjk?4^90@{5G}Gxw?oTVE34df zGrN5D%sKmTWN0F3ZUi?^7Z3GwSOb>VZ)Y<4xTvoRJ~}L01Cumr5wMG}WdyfwX5QdU zb=el@OR{4e%8{k3%$pT#AT?Ug!a*@{>W!>RI&7OQQSwxPdHBx?A7=h67ufvaCs-Rm z7@i4&%#b;S7^V!c@hK=Z`ocTd6Wzk6bh8=tithT0(KZd5aI7hhx0h=(ncXZ!X>gbn zhD4wVn+RTV)txW$j=uavc1(wSS2L9`>b=17EXPf}mr4A~b$OX!njAjZ!XaaD0l!gb zKqk>RxrA||_!+Erl*{+hg|{h*r1gtgim+9d30mBU4MZ`Ed1-}ne5Bh)Q@EG2BLg$@ z@T!+I!E5@Nf#7ZyRr>QtNe};jE+TA3r-M;o z2M6agM0*1!uOUVEr|h7=vkBFC8&}^9Jk+oc3DudKW@52~w}`;_@1k|D`y~l=;v&d# z9Arc6ss$%5mXn@X9$_Q=WH(2RqE@nAj--hc>72wq)$To&-Vd-VHrTm`gHJDpdY%pr zd1=HLF>52~f)ltQ(p>q0!3Os>jU0Z0f$5sbd;QoORA1b|>9Lrb-%MBrnw-1tJ#~%E z&NovryvV1|(K@xAit9X%z4>L`o1m!C6=9-ZU3SBMMkb)q5laZpoEGw3HEFi}WOJ;Q zVNOX76SvtQ`YubcHw;gb`IC@Bk;!|oJ7bteotGxS>9r?ImV>0#MLlu+b2+10{k)O} z-~Nj%i@LaPkNi46mGv`xSo~=1+2iPyY8rF1v_r-I6aLFqOuA`dRVYm5$V(#c2E36d zkqfJE-eso=jpPdnJ7+M((OnWUvp%Ya63N16Kl-S1gsU2UiJAbMzh^RN(ywu=m9js* zy1=!dvF^X^7;Bxa>1<^lBH9GRSa;#_WY*$eOWu>zKZLKr@QF2C$=U&ay+{CLyod~+ z?-Pb73It8|FLYIx6sl~#m%vWK8kM(YOVx5++OW0Z zV_xk_@fS(XlT3CPd^F-)}Wr+R^yoRr~@$WRimn zZNOkv_N&cy*|)V`FsV3s+IW7F~u1q`I--r>3hgA+e4vWOETjsu$6p9;$0nsGb z6f1m$I*k!?FFa^iYox)8IB}(UJXeNRUix}X86^8!oULRGxE+~vvzUUT$^Cp|dKwHf znH7{R8W#z$i=ZIvSl1aC<|M^aRf+h*@PC9Hm)BU2mi%{u-uOg@PvYro=WLkzP1yvK zLw*5rjvaT3Q~)O|JqzGHmH`zz+P>rAt?zLg*)?9RZ*M+8Ykhz5@1N#YZ|76tml~d< z4|LHKHiGdM#0@zS5Wc~NmGalM-8T3GS?J+=3@ZGL9!JrH?JbYc%2EYKq+(70RN0@<)aA5B(F20+70?oQJ zG%K039oJm5mUs0M29De(&`CTWA$9^gsF!76=F(rsFpyO)T(A5#DzX>nAnnY%{!Rv& z)~AZaOA<*zetyQdo?XxF41-5UsmyE1-eZe)=-;gW^*%}*n~g1^@$Cb!QMg5cL3 zF`QAt+?hCmt{5FVhCX#m7@NWYpLt2+Z11CFVuZPo^;~J!%-QB#*d_CkzsaB)KK@3g z*(yL2jAvE{7ZqkysS)9~FM|5Rf#9%tTwO+k{J7BcL4L<^VRfHh|9LFAWR~*_zaSJw zI?_El)lwtV1UqK`TSjxPLH9y=K#9Nuo1DPUG!gWZjJVy=1~Z;^9!o57VAvE4*uS`C zqyCaI@TOAnQITk!8(_>V%ywDUf?DOi%$uISivR~mw3w06Kfqx}2+A!=XV=vewY?Q) zQxXVnS6bD6t`2Wtag;R0R9fXr%dP+rAMY54qG7^u+G8^?0uVqJEKUTy9U%yZX2Oe( z^gXODuw#CBz0sN!Y2}hg0Lp`Ca_KUjYo-dXxCAmC7MdYv@|BEkxw3BI%e5IGpH`++IM_T^=J zC2u8;c_V~zR)(d|1f4n&uMjb$2?*Ik&G-%F8l&U+d<6Yka63mhPYaHrQn|p1y82Nrh-Qk+^1bS*zqux8@xwx6#aHCR5M^F$00L@gNaz zmm~DtyxH#K#bJAZ2PV5**NH)(Z1+&FNITq?wt3h{;9(r)Z}GrIt)xl@#ONCdGHA9+ zq|71I#oeqlRezDmn0DkSvHyWRmenU^IS2t0*Sy6$hTUw<@v<@(`>`AZ7J}PHbvrHu z%8!qLHY=}Ad!!h+p&*t6&VMYns=Dm{o6@tx3d^~|`{FZ^eoB@&>;a67Zz#IFL95fIQsrq90dX- zwwU`MfF#?p1TP?7Ob#3qWp;PgUXZjx2Vi*NZ~tbxdZ)X(s=8YkNXVx=dDeJbzdoz_ zsH^pjg*yZ_cBU6s{d@K>W3pb?MR9@o7Si zn?Kjn>`gtCZqm^+JY>=yyl5Ubra57@22y_A=)8#{Yr8={&Kb|BG_L}6Z~f#QO!&_mN{+opP@{!$i4N3O!%cPL=CyK!@qba zCbgW`cHh~^D_yY3!uHC;2>0*AUQM~6y=HS>|H`>eZ)8B-@&91wqH%&BKy>uxZ^eG; zY48Sr&+YU%>~$Ch&^}s7D}Gu(l3h#{ft@5JG;DfQzJ!rtLYN=%9{qMU2*oY$+a_2n z#)%d<{y3~z)m#JKvoot$az89CtaGWge7k;^+XS3 zbp_0eKJ+>_l-B|#fqC&Dq=~c-fUbuAxouqJmUmsedk+1(9#LoYIMBs8hvMxA@;daL zUP!q|t6KE(k(A0iN%yH=t#zV_uZt}5hr65#`d!aH4g;eLR%EgyKoY%IyV~Pm zsQ&{ za@+s7pI;oX!7aJZ)a3@X1cY_ z;ymZR(=7D@3H>$pQj0~ndxY6G93!mya|Yu}Qj6cW8IN&- zPwd=b?4|MZ19HBxhCp<~nAvGmJj#?u{9A6e{eC8aZNE3(2?d6lkG#<>f8x|1$fcO( zkLY8~c2qK1TCFznIZ1URxdTXVi#Z!Tu8Vh*`9YbUY*kjlt|2Ye!^#;=J~-t042Z08 zm@OE8)klHs1B;n1o?UpAc-aqnc~21wl#T?)_0RJ|;RS1}cyx@kv%s*rP=2#hG@B@J z(VGgT9CdG7P5z#kpSP>Ec*|*JY$+5434Y%bee6>^VY{ng*|3Z20s82DI04D_I$fxx z&9kr3>`SEY@n%Dtn+x~0s^^Y7svRA&9(n3prFp@PD2j3D?Nfbv7jM|hNwn2JVS7_! z2X=D7IL-V$F_xlRYJTI~vfsD)LDEC?i}z&b5}@AjgA*$9CtbXowE4YV$ugo{#d#&n zGg~e=3+E^A3(jWtW*W6iTL;OHp-}#LTB~3-#%04E!p(Y@M04owb9UyxXmODCqIOss z96!^|BZ{1U=AVJ$`W&WRbdyg?UAj?lZ#-(f(UVE)TUxBVIDB3b`-CFdREC8Pc8+S& zZ~m{9v?`7V`p%7Xhe9Etj;oWhb7CzQdGm7Gcp~mA)^>a2)7vus##thGK=)e<$zD>OX+! z%p2lP3U%u7I+xhJd!N0pC7Wlh#e4x@*-M>siujk7OK%K#np+Iy@nZL+h3WX+b*0zYbBm@uY2}qfRKk-$3N_oMd;!0N1TeKPxOdN zUg)hI^5pTs9dSbyyd#umIXp(~CRLYn0h{TTvM(<~J(XMDKC#snk3i}E*jmuI5d5XB zNwc5Re&p9(&oXPr2tAOdJ1QoJ(dsYmjIy+MCTl-bg=`Wa;JnD`{J?)!Pil+pNs=@@ z9_${`9C*BgbfH$>Z#y;O*IEq&IZUlt5$8GGoW306aRz{1| z71{Y_&oC3tU8`1F_b5OAsr$JQY$`e*uC7Old05y{xWt^jbHH9ApV@~P=`xe1q0l4M z?);JboCmP>pY7HH3#hs_8}TNDPjZf#Ewy<_Qfj6J1Xaj~0o!)U`qgjhVK3`1-Z5y` zGV=9iVP&G{7g{|hI$AdUyMc!9hBOcgQXK5^Pv2P$7iX}`rJMXA7iHZyR-x=&@^j6R zQj|k78c8JUT-&~Fisz0GGuuw-d1#(j^~^ep8^z%2uCgt^ZpO|JYyBqynM!&;mp{Ta-p9%`<&Omv5? zj;zn@ZPy7Q_+LA(6j@pig$cLrTAqQii`LggqIhcbr1QaNR?nT#>w0N%D`%OT4UK1G z*fmEuu}*JCv+2fG=pJAyi`6*s=`*XvB;(SfUC!GV*wq$X=k?;gwo~-Ep+}EI?flGM z4S1`vox#g{(QW72i%^>5)SgH7q;t<6{g#!XN8x*rsC4+9{fw4;(Rk!n-_A>0(j{Mo zDea^2m3ZTT+m@HLE{?P2{lgl4PVL*Kp7HpbF4)b&s~aX=r22lJ%M_N{-DXX&eQC8; zHrX`&KI;+tt+o5JhwI0-($MUM9_@06`?Xa%4S&>yGU~*Q%87p}&KhQ#!qOTD@ky^)^~lNW+!og0vVo}f+{vES zr@$Fp`mwaJ2E*|VSo8;h>eWBwk3=16x6q|K37i{yu@==jvl`lMYdQ9;7BO~@WRp|1 zbT{dJF{ov})PcNih6~H5aA#0pqbn*qaG!zT21eTz}hRJJx2KWP)m6ao-Bk z11Lv^=~DT#r7k)Y#^d2=Yr5RMwW)P##Yy+w=Q@PPGIaf)9#zSloGh(mitHNm`o3og z+rDp2wB$9M%&g3np8P9UnlX4k8mlJJa@}rnWID+aKiqf2JwObtGFfw*>Pe={WK(qL z=oUGU@d12ec36F;40NdaS?UTO<%k;@k++#1;WgNV-yUly$|LdF&P!np{eB(6*M~dc5}c zWf!;7;&FF^zq0?$5wE{Ka#BF|t<9F)S^i7S<@gLR*HLV2`14ASsO+&8IOwM7fw(WG zOWnUIzN5=yw(Wise@E;tZ3qpM)fr~Ui@Y=pVZYD_?ByE!GfN}ab3<@3Uq zdgheM>kqavi`soZR$ZVzJe}P#H>C1+w#q?@BTsc`2ze@2^MLV}wbg{q#<>_)J$EVn z!djf%!`Vh1$Up0KrH!4k;lf_`jCJyXeLG^6&Q~4-#H`i((ysG{tVa#<_rqOLMrQWR zNGi{Cb1-JJO&soSeSY`O*75OI*WJlkciJBxZ@qPA>*I^{RlhoWus%IspY>-~TZ-m% zy|_Nn6wj`g{q}tG@0Z)>fSB8ex4!N#E?4Wbw+2A^!|>s9ee(7AZ*SfCe(Umdb<$ss zMIDW_=j+SW)#~g1c%UCYe$@SG{Cw6w>+H`DPVSALhrb=q*Jtygu#4f};op+&w7he= zKItw1c|H8w$?Cg)__wQz>z?W6V`$F}x~Y5M>E_tav4#L*EhyDFNIGFTz`2} ze4f8t{Y{4O)lKoqOV(c|FI9h%;PI<&Jb`(I3%L0VwAoJ{ff1gi<1(Dqd7I`*QDFFT zkSi~~PLtBc-w<9@b!Ee=8{x<9*IDkFKwUs8_dhEVy8-!)8<5tCXZ(XBkQ7Od8gR2A z7#on(vMpnF5;l0?MQ;tOBZ=;`6L+2tJLUf-+C2 z5ZwS@R16c|0I%RLQ$NO+H^pb|%hg{dFW3Kq6XKiT)0e|%IU|C<9zLlWgwK9!_@?-6 z8^Y4WFD^$4)twj_s}Sr=gsz z!Jo#KIjtDV$(_ay<>XA?^NjiC&dpey+kx?$J8t7QcihH$YvxF?R z(Q7;96$xHGU8eN1eQViC;H77Xj0KaI_91U`s0WHpwSHGs32`auk!8Q&?CXHAUsb$C@ij zdiLm5OQk={zc&*+gILbR#%cg=#$bK|ms}mMTjsmlF#a&{stBEozqd`u;O|r#?Im=q z2ZzztZajDkfr=9ps?D(~qe^u)4)t4oq5QD5=C!glwWI=g#S@YXw4Gg<6!kFc^drTf z>Yk+Nfv)Ev7Lpgb%>9E4BL~Uyvvik{rB7krYj>oKk9aVb5D5yfFfRx^}JxM zU#bGTOfVPC!RpX0ASudgdpowfS-MQjRZHIv$Er|<8oFEjC#(`2S+o(pnsZP#w_ndqCtZ6iM2=Fw}2w(1Ob z!1KLb{jDxuGpYKE?x8Z3v>9=G>tNpmFBi>1&r3GZ4jOrI{{ojka1jEpUI;z4y~<2< zMc-9o@`ZY7Ef-wx+tk{)*fc7MmbtFH`@l>&>}!oZxt(69h8-rg8@jaTS@Wo>T04Tc zR(4hJ#*j~Tv$^Vo&ZA{7b7mER30e(%?b-9ETPNRsqE|L6$nfc=*GzQO&>rY;s?H;j zEVu72Ketz2u;00{x%j18OCVqu*%06Y$$~StpQ2to5M?Sl&NxSfb3a3nbXstX&Yai;m?> zy(NLe6-*!G;DGpbaJ!x_H}yQd16efn(mc0@0grvtzuM@$7V0a^Dr5tk6>nOLIkU|{ zjBJwI8333wTAP71Gz)d8Fn2LUlW2)khj2L9H**z@*26J$ZWRybM>ymq)v*zWex8bZ z(!$=8xUXqkf)gU1Y&P+zsFXn>}4VMk$EQfX`-bY2C8g-O{R#t<&|%`NjGi zdw9$d0A4Y&r8GXA&HnPV9V~?T)j@aW*#2ZpPWdIQx|F zjo5(-HQ?kcOUl_{ZupTHL2mSsm_WwH6T1Xws~ClQz3lHHk0$l?{JjTdGJLAG%lZe- zx9YSzIr(sX($B9?`kQ!Ijkr^d^Y~efi9D6P_$>%n*=AQMu|K7wgsHze=0qsp#Agy1nfC3j#O=h}iCQ5Tg2yfz?(jX?fv2#iDa`+@KGRnli zBEH7>8@Io$^M5Bk%~EC=`}Od{_zg__+rQWX$M{M%4O9}Tb(Ao z=C(*vOA8A@Phb)RHMe$6Sz0wFkTV6WlRD2nM3mckWgzRqTw9Tq#tq(G>K2KZVP@Xj zc^lyMB;m(^&SuDr8GPHNwQA%@Co?3CM zTFbrAP9iWJcEsIA<7nCO8#@OPYm2{1t&CPp|M=<^P(^OM32Zg^T$^}oma37xPBls= zI0fBrpM&97TcQ5(vCXwhg9XMzrW4y>HqW)1{$G$kG1H^pS$gzz_J42KegR_Ky6thH z(}b3%U>E@Yt+QRP*|?uuX3Lu-j`U0Lso7G6lE0@-lm2#{Bdm1>T^=3-@T-T_~M#h#6vtm0YENwd| z7%Z1n;o5W6?_@}G(%oEaQU@{8G^{JTijS#*0d(=&PBFJc3mHeXyOeDQ1e0M`t1#tx zmkn|xvdr7odWK9hNde{<+hYI{$v5exs%%)llig`gP;JTorHA!H&5#$$|D{`A+1boQ z*9+)%$$IWUf%Xc9#SXcX2-c_?GC(Y0iOn?rbriF%7t5}gmB6)W3ZftV19fvkG}K zDU!u~w*=0HrM}p^HHcD@ftGb`(#YSvDxH^11Poz73T zvtfzaPV(&}i?MGLJ5s?~hZv(xE_`#%GdX8;DO=W*!rDhTqlYrQx~2@yJi(eASTh1= z8erA^oDyF8MwIQ!QcpDKtX7=WbhFB9P9e=HnK{L;^vzZ9g4NhjyJjt;i&YikC zDk8xW9R1PNLuQP2FawjZ^N}?VXV^SkW&alQ@L1_Zf8KXj$E(HoDQ&BI;F&>~vbx9z zUQP$$&YQLwxTLJxCL0-|98k~tvwq4dl8oi7udmLpbzY61qs-BCy*j;majph!lNDwB z3Yk8}dXA6hC*9?x&d0L8Tz&g-clDeO(E0H7WHnPGu(~{+UtbPu)mtX#$@uRh-9>+S zeR6eqeEEERadn)%c`;k|$6(HfKe9J3hc&HV96#>QKV6^e+$fLxtLyW>oUN|zmCHd| zl5W0C%B;w`bk;R}*7QX_8+N<4u8+H`q3!2a$H|+}jqPtwPqt^@Wn1GAUaim9C+lY~ ze)E0XbY%N{G22qvUM{bOE#dfTr9{B#+@ibc)xVIw+5f_JZgsiVWo~6jR@_UodujD) zQoWU@Z)N#*UFL0GsIl$O7Qb%wWw|{_f0egeoM?~9gVyu)$vCo~sF@MO`dkxUPXBd1 zK-fGtM1E{B%-dlDEV5zsF6wevp^9SIG0H*y%3)uwswPW@MX&J*a$E`Va(p)bPvY}W zuFn*gw@JS2yF6bk7Jadt*UfyEqtD%j&pe2Uk=POu$UT#)9%^u?RwFx{UB+JqRq2$C(4Q>)rhgkFIOk)d3UnD zSoO!}{l)RP%*$gk)Of7wy6B&+F0U@erDbb<-k&X(>ieZ?Icm*ue{r$CAZ<#=jlUi* zD|wsc)zG?Mqfw``?&5eoF#1V%u9|c?RMTB-+ylz89k?$aj}Y}ZNd0Qyy|25I>;97R z*4d)FxaeL`&N{n3J%1rKcd=pJ<;l9cstUCQjaG`$?vb|29{A#ls}Meu>SougldIL) zrC8(1AUkLG(vcRf7=Ksy&2+AA6Yx~}vfg<|-D9*K8q`qDrT#bd2i(nWGXT zxD0*y*B|f0ofPgkJGHrG_W38La9dOVR_y#A+Dll8wWFgiR6rm^Pj&sjo<4;tU}kj?)RWTCq;trrzC49^Qc$>QM}D~f zy$k#7Ai)=_Z+|W39}T|0tN>)shkN$brDVs{tYhc63ah@m~}95 zg5?3?51!1c1?0{74D}`)7gGPX@)zawC z=SmN*BNCHadAR+3sb6}C@h$5i76;#nMW&I;|4Cd|cZ~HfRfS1lSiaR~ayTtqI4+t8b>#Q#7 z7qSXK$SP3jhwA2P6Ve7(tL1IAquivxa=Dy8y?XJ{-rN8F5xxEWt^Z1Q)~KUAbF5K? zMlJVYmRFuxspW_>pRJWIz&y2-IPfIILO-4auSSBW8R(Gy6Gr*=_qY3d1IApcUkS|3`pAH z@^hu=pJh7`w^FJohlO_MR5bGv-r@z9I`{;R;NTJsetpa4&yf6XX{u~<)tE&AFW@Hi zHy{6{RbFUa+p6>KqSo)}94arrxz6xcS-Jm`<>x>H$#MFnqSPi0NYMg5wmpQAfb|G^ z+mvwfP@mu(re&(%uUDr5=x4J4uVXmR6xIX3u-v9qbF4!%>RYwS&-^Q}qnelbyMF<8 zJkjrs!Dq-mm8lRb2!ZGuz=1wN8{FWHx@G(N>mR5iC+v;O=7DmVueG7Ag!hK^YnnPe zT=fV2C^^i3t&DXL(bLcWc=V1buAM`IPw-l8>d)T+hx{HC*7+ab?m;^UE}zxGm%#Ve zt9Sm#FtU!O0&dl8yn@p$90jybccyYHrHkb|{|Qs~-}D<={(?*g>agB=-Bd?b0Pzxx zv`MX%y1;^p7#w-wNZ0IWje&w%(E-2}a3Y&6-o5+J-~I6#mbFxI8l20(X20lk8a!Ae zL3UazUF}l8bo{xgYiQ+cN3kw=5%=9cO@XkQrrFN+6$Hv<$1qOnFK|BW`g>m)hK2;p zU`qW2;%=7t1iCs<~|L8kT`W2ZT#Os@8$&^?JIt zUsMDgR=NY85Q{&+#XMJkZOWZLDIrXBy2;leFsa*lS6f!TGyQ>*hJRBH>mV`%LIt3i z4MZq5?T(650JVbV$`%q=LpTF;N2kn&WPLLbEU*FTI#N6E0F-bLQ(CAT=FQ@kk$;JG z*>k9rHubn=)W@BMmvsK~GI>{>5&GIvAtkdbV7^QR#4U30VbaQB{c@@)7yOCl`OfS6 zPnRD;=Ie0-xq?pRU%)@BUubrs%_kSX`$3&jJDo2Uv}cQRe7yxw98DJhIJhnvoZucb zK#&9t?(Xgy+!kBhf+x5I4ekVY4em~Gm*5V!`TncBy1J{Yt?ub*+4tsk_ml27J=aLR zYpn8YTcKuNb#kvWWVFgGP4U0(I%0Y5fG4$PP@(rCM(Z{$NioI#w=zS2E%4d9((@ zS|0~Q5l7_&@D7UYl{c)lq>Ou1yc(zAoXYcyx)%}=u8~QtqoZ|Y7Jn}@U0;8cSs;E3 z|4NPQ>^z*+(OIcEEQR-}%e&U%-S~5_H|(1aR>nkE7e8#MnQx8aYAS52P6KeqeX8LK z3sIR>)(dkk6K!FyrLVz@ugJGvQrKK!)7H~%6=T9^jmJSD)_%4+P+YfW*1qDaC>`{! zCg1BuoK5Vn<^@HWk;(=Z)C7>CtjcAEUGE^1zTZPr3jKb#h6LtsJAi}PH>HHnuQd2H znY5%k_Ke`yR+z%@wn_8)rwr)8t^3wWz3{f1I)km}vALwH_A6qOdIxV3X{XJyl|RQY zhl`7X*SEu%73T}Kzen{%GNBm^vz}UKgavyMjd4g0pR-hdI&|EY{}d$Cx3KY^8tdQj zy^h?;U0!?;3HiY?Pw>Z;AZqK>&dFyoHsJU3IU(MYUBPDWScRfOztlw3^(I&l5tY2M z!gcU(fecZceX{&AzIM8$^<15))t)9)S(rr+XZK3|a%8oaINSR1v?EjKY%J?~z;yR< zc4yWG$KP*1`1?7( z+yB+^s{^}3&9h(VN*1`x)cn))%Ku_hX{5Wx`eod>|hd1V9bfS*8TgvM1 z^OLiaGmw8V{HP5$A*6#{^w!0G>R+Q*`HuM8!E;RqD|_Ktp*{6)@=osppfI}(N2*2E z_P!r5^{WV%X25Is4(S@{RWs*!#{iT zsReY=@ejDQ?jXgdm794sSpMkcH-G;D<9WG8eM23FW#n&b`yYa_k8UB_2n@G@k_+~6 z%l~kc_Y*LokzPx=G5PA-(R#>Q5mTvABmfdObk%HoAi#iR`jakFdWN5TpLz4XKCs^MJ`Bgn_8(juK3^( z%l24m>xnPOGTqGbyQI9djF@=ZqUTeReQKTk>aMslo!ct9z0c8@Q2QU^bRLbTMxj?% zU%$P?$Jm>*Ph?TeA6*+iw&+!`DX2Tgf21$99FX?gvjM$+Uv0}PZFiXx@;(~-&mi_b8nb!^X`!|K{3TJ1~UoYCQmRXTp2X8WvW z>%YakWIszTeKB)l=DD-_`Pzd?-qF~4sEBDqJVy{qHYA{Q+`#DIeV6O)UzH^?SZ9T%nJvMxTqX2>!#jssaw#)bAepl0{o7nPG*Ez%1 zCcVPGt;gj*Sy^BEx_*_;die^)f@$p@Bv(9ag z;p1RcY)MS~aY_H|bKGt{$dx$kz3ASY8DpMNKHk4}9cBEcVs5yA_z-HYb=uBHDH~7> z$KVWeSW9{|2%Zd_M%8}&x^yljD0fyn%l?&3t{!TZ>AaU~`|LD6Ut&-0-`HV}_P|2_ z^g4#3IsOey#vYkEjH zX&}0(^;wudtdp54t3Ok?XG(IhLbDG&H}l9Lc6?qFF08y6_Zd@2 z%l7JyK7Sh(bvN{4H+}ee*5)Z{$pTjQccH#b-~e=!#!mayd5s1CGd8*^PY1l}cqq(D z{=20#!||D?4EF9!{4ZgeeQIk=%BfttjOB)i^(?3tj&$ zz4@^|zNe6RtG-#quwO`}Pp?KktyMZ!N$_W-E`3E&$4p*Zx1&VlPF29qxPiE z&ZZrk?c!;%1iwVNSX)6{bNA(V@vsc@6zeham|&HxA79@PYFpE<&U$WrKs&0vJlYa} zy|!tDtqk2-|20y*#j_S|eEMj4=(l;$?TtIhwiKXT%c++-HpHrzqxu4UjY-Gwria_= zyyo%mP)ep7?|X7g7D4Uk=FF`h=~vrPl|%=bJZBk|yF#iY7OQ>W5lrvaRzmm67rU20 zvMX7&S1tuM?Mre0=9gyj2f>=(H6NRfX9tXzG{?t6Rr`m)?ahH)P3isusCEl`@jlNo{rlA=!SDkLg8lGUV+jl&E;JpB{c=RIMu^fiXx&K)KGY~VZ|AM&|8 z5@p+qy}HC62w{HKY6^c{mFLsXELYI{a}YtSr9jK4kRV1_w^dtN`66E~ejCehO013_ zi_~@G&?ILivr)ILxmWE}@KKPQRa`acq;u-&l4ZDu-!u1^U|?0-<6_g9!Da>OL2#;& za?N)iqBH41K+hHvW)r3yh)sg4!0G{ZAb2B&8sbbg>7hmTIS|8 z_vSU%e2=8!pK8(~_nx1IFRyuZUJ={td>&Jb8 z#O_n>{5zcvLa+x17s)Y1H~Du`n{RuHeX995ZJMCNK4dS{7jN?5<y=e^a@EKd*8Mu?BT_|0*?|oegApdenP#ZPdsUEt#fBxu> z(xTt(hbBw-;L~Gn*K_`Bc%icQG94yXyPxYMI=TAt)WlVv=#VhB3npqZPm&z&9(n** z)L7{>y9@J)!t^33m`|>67VLYm!!BF<<;C2;5XIuT@9r7rBRl$~fKCp0S$d<)+x@+l zQKJUeFxJ62GQy@J-IC#u{QB@#pN*?S8fWManjg1GY;&JKUX`2QnO+b#T@DDX4f%bb z^_YpXHe7wpr?kB&xyK8W$-D{L6l#Gs5%0{&UU?=4#OEiys<`B-}=u z*+=E^I|D(!b8#F1UJQh{?*?RK7ndT8ScvmcvHB9w40omGm-djR>)|j z5UxTKm8Vs`XqvU^)Z>wOmCNUw-i6~X$J{Kv$*JRd`tWo{r2}z zYWp71V5&+lcn>AK{7lO?uWm;;9nbbV*Oe1S{Y}5-F$b|^i{ixI{y4U zfkJ-l7I40}l6kHLH`U5!6<5~!-VOK{*CCYTh+nv(sSvlu|AZwt*o9m7e>#PMtSRO6 zO{2|5kP#;y;+H&C*q2k3nA%@ZtDzLoJqsWNtsT(As6`z;D#5xwl3Wkyaq~Y4m}xHX zzz-|%m^@{6-QpJ#9|q*AaxZ5duFLtR7D-~tb4Z_SPW`+W_1O8pJZ3DEoL|RzawOR& zCPMU8_kGUyVy}Rh?StjmvY28Ct|9Unda0}88Y~Rm^)D9zHul$7$CIU)=oU%-4s@PL zK4rhh+ZEMesspDt$b;LOje_YsvCU>W8{WQz?Wo4wKx7Ne-H2Z`Psa}+ey-Q zcy6GRdRgPZS~i4Yl!Rimkb&-Ii)_u$pk4rh3D7TyNjYDPBBBebA}JTyZR67}l&Qrj+?ZPXm3gLIFO z!0-mL*<c-;d*scBeI0AfEEAeAt{W=p;nr-mfZx@yKVNx&GDcIhudS)*SX) z%I@A`Dbvosz@z>P{Lj-y9ka~cx(GkKZxfH}g2{heZ?;|OGuk^NRY<<}_0{w1$+uUv z*ID%z*CI$?tAWli!u;ch`VXurq2~7w(?um3`@#Qz9yrajXqO{or~)13yACz!qw4e) zHfhA(shp+AauYTSw&PhstNiyjxNS8D=V@+d0=~@$+?zY}XsiEo#NkZoJ-u-8-ckQH ze7J@q;-rttG3 zLFK}cmpwniW^EZcCKA=I6rbXi(I-hsYPN>iEQFV_dHI2nMK4W zOYu&b#UO0(oYomhwg2+NM*iZn_rnamtAs6QT&Tql47^>|LMt2=r$a0Zq(_UFcB)|0 z{S_v%u~^4J*%DJ~jOR~y&{s*?=$$N!+-sw|aTZ5}!WeaSDf(Op*{@sp{4y3b$q2g< zRYZE~(eHSwmjr`|hrnFJr%4ZyM&-X9`K*8Ya28lthXho?k9DloYqNO3d3IVTCdZbO zb@qV}eLlFz9wp75CTY0YWmYJTvCZwR^Zzw+L(tw8JV<^P_y2Hq*4nOBxkmVmKQ+mf zS>TYBwY`PV$fV8>ec$om#)R2uSsn7lsU1EeNLby);kFbT7zHB~J+sj+y@?pJdpKO~jJ{7@k++Re4qTvx6#XzxrtYEOFZ zOYB?pFiYg-w6wIm#9;sH^y>uD*7#b`^G2-qR);^=lVq+vP9$$_cr4AP{7{qrg)wV< zQCe%&Am%ido3*MX<>Bu_d|egW!=+rZSEr-t9z}`Ggd=m)TW2=0)#kiWYzK*t@+%uR zc$vAWt>nz4qdOwR%w+O=B6O1up`XMriSi{b88NoRV(8S4kHo%=@Bdhtk7yUU(k7fR z5q5N~froQOsoEG~#!IPLr+YU{Q?Whd62O9eU5ESzR`rlf)HtCZhO~dw(YCMbAgPesdS=_MQ5FBbM3${^DlGj1aP8U*k^b8-5wwL(A zl&nFE-H@^aFTI0a!}iajtOi!{yPs%W)!y21WTVFhtWZp=2Um=JS}PF+w)zVOhuFbG zXdZ-ohokKH1s}hz)l7a}!^DT;J{ce;2%^T;VB^NqAoq$0;YORv<7>-CI;gIb*(Skf za7jiG6jYP^_KoDWhJtyWmQ5dj{U=YYng%PH=WqoIn&;4DzyXC+jDj4Ly1w5j9+;(K z733c`E+)sC$yv#V4sj!V_(*wSBsBjE1evr2u8hRQmhxO8STH zofXVmp;eVgW{JM|Z^3SD+uw&<(Cd|VXIL-6!(WhZ!9%*;?dV=MuHrYXf_{WdWJgIi z1)KC2BRf)TZVFn^9#%@ano9mg+jfO#E)6A`_7s$8cp7kQ0tpMxM&4C6)`m9YG*oJ} z@E>8kX%&e^6OuEmk_c_`5@^zB9TwGUw`nD(Y_iSa!4kE-6X{O$!&S*?6+ME^63`M4 zE?E^z5K!4;UG*!*W=L=f8IY`h^94tc%Y1{5FYq0=_2yFs!^16^e`^6VHoDNZ+VmMM zeTiQvc+)4}h#&QP^o(rhy@4}LEmBv*f~q(CJTDY4oyLA+u#bUseB^-=!A=}0E()@?D8E+xebNS&NyS52{Cx2!^an1Qo|_kNxvF zhg;K>Y$kTaRl?r4cWqY)J2GqnYeqraR&V`MWP+>#Zp7e^>-(5J0*-IOyXcIg6O-Pt zb;j!zOD9rL_2JrKW`F&xTl+MpBpZ{Qq2)|?D2+v8GIX9K&%$Tm?8A?dK;7ia5SOkj zmVWH_)3wYQjKlQyAVYAfolX$URkXAWKe=@Yn)>t>wSdHirU3_&(Ag)`oOo-(w7{P% z-@`RR1Y9PIo;=R*EO13MCoF*eJ=+-ct(QNPw0tP6xECEU&Q!P&&dLw7))7RDD8(&T zK`Dh8CXxQxbFrhvv>qvs1mDQLeJvMc<*e{FmtyiW*OSjr$Xo=)!uU`sM(I zR#MhB344@Ewed$`nm8L@p7zxgCp01Oe4WeMCtyDaUf-q;C$BA>^_x~A!df4d3_z=q(*nzV9x{VDx}YX(R5StZxLiA(-==Q&kBkpD1-!5IC+YQf@XcMsacXwv@aZ!~3`&17ln!{vg1+ZO0hUDcX_#0MPVY z(2xKLCSD03K)U+V5F!NM#tEOUSQ7P}?xFTatSQX8;A+nMx zK0VXrSSd3td>n?vdZPlj}+AJ04wS1p3`UwW>r4*??i8Ni045oH=C} zJ<7(N+Kw?iLFJyLBaF8nJVEsUC7txT=*>4c7F*rn#S{T@0o*#tA$sZc+#8<))$*id zGVA&{-Cx47+jquQ_fq8{`Yi}RGbiQVDU@ikI|wfJxp;)m#JJl<12-ZSA{dYe)C;%_ zs~~njwpJ?$MU-~l#L-h;J5eL1t?Z`zYFlR{UQtyq!M3{NDzK_9yPbx4bg~H1XuRs= zh(#TOsb_+KE8ygFov1pl$=0@I_dNuL(OgLgf+G4CE`m` z;ZjoG3+3Qxe?wXiRzun#u4OaP}1n&2Y0u8WgY>|f$R&7T(iS4)_&YCt1J?_xiGUp$r!g#vsf z1wa=rVZ)&%!`fR&nc;{yQ)LyO>Xn{Abmq=_~DcxzqL!P!Y&WoETJY&^C}AoV7viMZGBaD4g*1pYLSEUTG3;bPY6?;Q8+lPd zV3VsQzU3CqL%*%w#Okz77e>*4Rn@55vGN%gdK9qPt+)G&wtqtmSD`qy+QhI~YVeiCVEpmTyS_ z+!Ttiny#NS_~Xqq=Py$z_ka5cL)$a!C)Vd!@2?hdanXh;(PGk1Y$#K<4y8Ko4y|On zab!ZF`fbwKw)*X~spK*jx{;l{AF!1_08>cR^P&rtB|Rn=(W@9dQ4wbXeuPIwZ4VKjv?p=B<->L z4od|P1kCF1d(u;?NT5C;@9pDFGBJ;8iFSj+H| zf|{x6d0&Ln8Zzn=lJKq(&Zlt=v0{7@f+Oz&?_`VG zDg3}?cc?r_2V%z=zBqt%O=g_~tdYbkca@Q zc6TN4PT5AS+53jagCY4;>TEiQh5c=^g2V5Z&B>>wG|6IEI**S?DgD_N4!4P_JTO86 zqwA+d9;CkAz}Wae?D~_>6Y|)2*k?JprMS}fyfxcp2eo$l>WhkOclX<6KYocZRZ>Uz z9J0=Ngbaxbk)u#NK(pm*>>@UaNkyFJWHcMpoKA`eo_w6=erj&^o^DLh3XvCk4vo`W zMysof!Y?Q)AS@`dJ={a**0?0Bl%F74Kh8_>Ni!Q;6?h1ETUU z@=hy(CxCuAiB|$~BVX_h33oK~@?T^8 zou2Nb6B5wLKG`dz0dR~T+Za(GW}ZU1h;>qDVYZ#;5sEYq5g}G{EJA!+Uk?iQGC10R zF`{WS$GT}_h^aj)oFjvm7$_!Pkr1-2l~E@hY3;eWhO{NLUFKC}(vACkB^Jqd@h>;G z!DL?3h}vZTueg~Y;8x~v^NVBRg@eckHzzi8udDy z?(>aEtM7TI;r}8mU2bVn`Is5Uk8D~ezUtG|_1RgZ#Za7ZY@G9MHqK8hUBiu zxzN{VCJlh17z<$f>V1r^@Ytc{yD_I>SvGmLQnm`h0TzdY&8wQoiO6>4eR_hTLmvPhN?dmPSb4n=I5J#RbQUhDu(J7^mMc_J~+hr zQ&0ja$jkVFiP1I+1`f-@pmO*@E0Z=R=7%Np!xez3DpUuuRUw2pNMmz5qO!07lApu5 z<(MPi=p@ZG8rj2f-%Kr`O_{Q>MEIB}=a2pSJI;)U1M5&#D9`(Jg2Yaw@C?v&LlxKc zU|no(3JyQ2NkvjMocXtGd^e*wMBNiEMJ#NPkM>?La#4kD@)w0N@uETlowccW8?@C7c<}jd@6zW(jdth<(g%6yVJQA&1k(-i z(9a>OZRKAWJD=~;ObqkT<4^FSR(wKt%;!UQ>?ZF9d|Xf!L_a5f>Bf^gwBaZ!v~oC721FBR`MdY$Z3z3CaPlT9`;iuaT%ci zp_%Pd#r|2@S^Ub62h~_%>9G~^?k3#{*FjcsxoEU>%-V`kg>=7d*!VPDBBssviOlQC zI~hu!fqw2zOd~zGCt%MF*$E%Ldr~7RI&C+)r12^s?Rwve5D%)q{A}dCh&cHfIjqZ{ zw+Ur)&^)reyZ;PWr*NqK8~;WKB^j#f?l-Uk6UVvB4~P(lqpxrTs_m4Pq>a$+#k@b8 zOItt{;hr&YIT%IW`RQU4iTwk;5a7@cB_<=r^p>|1(?y8LI<6b>BuXoZD0tHlUCXcE$!W!GrvYX*@P#Zw_P@ZtT zYEASuIXUa_e~%h7Y}jljoU~61S0lzo97hYW67GjscRQ|?vp4AfOLbAP&-~v(0cV(=n4` zuJvwv`nKlhX&$V3o#x8f`O=J?9MJ_73^PJttiUH~@HjxxO2R(<7lt93@*!=*q=x)= z^-xo<32M?#yQ-TNKzW3wjsJO5FR08zBFatA*g1`%Q_(PDg#t(sgYgrlc7i+7o6=B| zEq{;ry^K>V>TMI01FOl7#wkv#tFqMpa+Q!hVIg~4cv2^?f-s^wOKL>ycQ^>OR359c z$Fm^tC z*(kDH5qbjppL;MJYZgKQ>%i}N7tFfIG(#6$y2zvet|}7L$mUdrt}G0wS0~*C7&vd^ zzy#706gr@{t^cM?V!L;a0ESX!VZ+z-2#xyHT=#Hn^5Ji46Sk*9 zY^(NZvstkz_}wCqCrf3;!oTR_h~6CGVBeLHs)p?^(o)gPLyI5XBd`{mWP=CS^r^($ z&k{V758ElY?fM=-=vP-VJ4i|=1d zKNCR#WhUHhCylS5s>~F*DdE6&)a) zHUqjA=-`n1d5MJC=Z1j5^9MAF6pCvA_VHO9s45a+stFG;S|t+9mcioMyYpcZd5?~5 z%h4)3Yf0|&Ayh%VEZRS(=%E&XFih}*YbBIHIypWiqG-TR3>F}VFYpN{6I)IOEO6p* zPV(r{JGF%zW7vveqq4jrrZGETTD9Q=y`!dMg=>7VRFOVd_RVY@FJU8>$)nB3o7gY; zHO9VFNr)^+Z!d#8J7qf5siwnAoqw`6?iC0}Lx7JNu(KROU<2F0x8G zlLRK1my7kp;SG8?QH)37QmusqGzuc}Y+(L^m|@qqb?{p3MKX%asUA)|;}(hZ#lsW7 za2FbnsgO;xwa5_9yy2`N*p)RD2*jK9NckJri2>I6oXKh+Z82 z1}nPwGkW$LY?UV(#FPREqS9eO(Df`~1AB=M3J`7+lE?ETY03b%qdF@CK-Aw^!v{Jk zZD3gtSJANqW-$%H0f%`w0Ivd*$uCf^*91rOK2JR-bvTGK zK{=k2FMppzU4b-tz3$E%8*rxE+mAL=+m<6^$ZlubK{D#74MGMIPQq|H<>2NDBTUU; z8uw(MkWZg+gu3|(#VP(WvJ_%SLXWNKB=}N|(No2({oDAU(km?JP4U#RY9=y;ET5zU zVFRVCSB?)OnE{kA=TO3g6JRf(Cy7(^rg&mgBKAcgGcp;Zp_1BrF~FcdPKJ@gU8xwg zB4bf+i3bxBvr+Xfcw%?`9D+mU;5QHp-#Didjf@?DSThdB(Sed+cOJAaD-emM@)pSk zs2~f!_#XNva39@sd~E(;s6kxcHQ-igAtcx>pET}1qrWHhAret^8AJfCXi0>C(#dTD zU1T58VH1im6c&^G6}^Whcn;<$-|2pG_ZkzhCs za4m8L_ZK%FvqxXJgzF8V&SlaK`oWZvnbm0eC1;sTR8CQ~01SY;f-B5EDF73k_c=;< z9V;${Kh7}^P(}%?J<3B?wuX(TlaHGGNmJ=n>KDpw4W&O_UD^~0S+9aMPTQ>IrW0|_ z09lbXJgi}Z3yLv_DY`{{HzVzrt_9z0@&gR-aJ!fTBHqCS6emj)hi8E9ZVt2a0lHZ- zcE2VIAf<+>FBNQuwQy zxe77pyX4_vOJz+DJMR~!k>S%W=sC)}*+L@A-}}gtCq7*zPV&_6%GVQJrkMf4WTX$TN+1Ma0KKFovuw^5fRL}?g z_EzM4wpG1$tnP^ZL7m+j@zSdOrsZUU&NXPs&CQN@)h{--z&2my;ElgY3pv^cZ%_U;-$bTvnqhQ^)0vMCO;fN$IVs1vnjL1&j+5~3tVZ1 zz49C%qr&oJ9H$ND{z+3yq~%P!R+YqAJPHdWEPu`836e=nzaO@&Nk?GnJQ$q{XR2!F zO2o1tlK~GvSHnE)gn;ZGYT%BL^=3(Q-P98w&gsKRc)at|gq^8L4+-vNq}?(W=Gxz+ z`qtcKcR;woK4#5PO}ybm_}+CH1K4kPYlYoxygURe27e(`n}{HXe4C*i@0(uQJ+bAe z;6%m@)H)zxjkJ$aqH|I{r}`ppvzYNI{Ours$%*$xZ%aka7x);-kR5RhT^Jn{6oN>{ z?noN#ak?UIkGk{CWk3aTY(4-vmqMi=geG7gi6wxH=~Ui2eE96KsgxMr=Bbn{-lE#@ zP)fWs7sPKAjG<7Lxfxk!C8O6h{%Zpi&!-U8Kmdc)-Ok>It(h+h1xC)Yb4v}FEF_0x z^|TYOoqqpiMteI&z?-B>s*VQHyg-JK-q4C}SFvGJh51Hc@g2(s8-;B$7aBV+X!ht* zq2FH<{|%Kt@%VsJEEk4R;g1|!FQBt* z2L`@22?;AEk`^|An;F~9sIo5Xf3eBiP-9tVrm*BblC>`y->%fifH>9vWCl&qh4B5q z`Io}U&MG?+0b65z{ieRLuZ;Qd<)$;jL(4f@)chn0BJ88 zgc)Hr(of@+z=xd6L5I?KK2)drKNH=``61XbWb$P_?95|PA6|~3Tgz5nE*g{0H&|?t z>M$j6PZf(P=6TZi;^$UijBL{$+ZOW&6!y7arZlqcCZS7sSi9LbD;U5Q=-n+2d)B;bXLzQkj+fD7vz1R>zvxE)JHxNvD> zd7r)4mS$=~o;DlvN7di>M7aN|j2B=wZNi1lB zn)3r#T6b9NX}1#afw=mNJe~v*{VCX;>H1GfFf|@aF(@W@+~3hLjOE3)WF#P2g;ck2 zRdn*l^$3nvP!_HbjSq3OsRM#l^PI4HYMSa&E_aLH6A-wdP_XQ_N>_{&^yx7f>Wv@( z8reVk^h5`v_#9xE(5yL<_xt+vV8f%D;Quo3;`G+0$YPC~u!?+wW}Gwc!onX-{xum( z-~OGzyc=iUyu)H-K14e541n1!p}NbrE2C4kY`zreazNJ#RO9T!=_FPqJs?nq8!g%^^frPd4wNJQZav+L9W-PN{|6jhD`GaH`xk`yT; zGk)+lvbfs6VRJ@F%o_+OdG~yXC$Tf$g8tpyN&l29>-+mf-ujW#TpqCp&1|0!(>XcUBdTu}R<`3Ek@!*#7& zm zOlBZreck1Ptc!|4C#)C^dt>01%y4=K6I}@>fJLgw?rXY_Fo0L>Gvp)=A0G3LO4L;k z8#@SXU1U93eX@!&ydJu!DZY|5IgNaXmpnquL{jZ~s$ z19<4gpkUsL&a8Z>mqZG-rSx)?u+bS8wox#Ck#tmXfYgtW0P6!C$)5BeAQFeOe>>DU#*9CZoBt`Art^`b`^b z`I|QUf5FS!RD5;XNL^|Ctg1)0=o2Id!-g4p1lhF`+N^NVr{GRO8*6mvzwD!HEe5r!8H)Odq@l;yFAG$4wANq;r$R>!W4C#NCdRYn12& zTW`C0(_2p-qqnu zYjRZy$AKGI@4x{tzGzCU7YHI!N&v%HeDGTRgB+byh_>r-vqN2kh!QfqeVuW~p9LoR zM@{AHk0{|2LEm8rPfH^F1k~WvtHQ9hFCC>?!&PqvT*r3N_bNP6cNHl8RS3^GgbFrDOq>7a6e54 znVL%xk87;J<3nbnv`*sUotSR!8I;x8&&Y?J#5Ql7)f#YV2C?cImx*xDd$l)hNLiRP zOkkM0BcYG;^&Px%jZ<~pl5jXH{>5g=FUcmxE(`~64&>Zua~KOzmE0K6tnhU;CA@DC zU2x~^FGBdG$y@Q@RP_AR+C+1b;GVFBKk{YWuu7Oe0oac%i}y9=QZo1K@J-=Cq~>n(Y(%=-$<@))z#knN(7UXwOo>C^u4fH`IQ8VnIq&YUD#}^~ zDlH5+ktqjZvJg^eL)tB|N&?8%KO=)7n3O4`K9tCb!EEqdDAlGmT{_LrDLPfuE4bLk zyixq!A;1+Efhc=X6IL+aXb4425*=cX^hG`M^#lLU08t~ePNt}-yObD6W9wwG z{@(#DPAAEI4NFgTCqqLrb{;lHm2gK7StLIbfzZ0>casuGZRs;I^NBTjFp34TNLAx- zy%wjG$uulbmY%rRBf8$>gWf%KPIJ53%`2UCLHIQ426gf?efSX|Ns>L-umz^d8QW$&5TsZ)6*ex|NX##XPNIe?&TiSqd+zR!X2+>w=!EgCe zP^j1KHYdWm{Tax;a5+jujrFw#(ht}q`)fmHo!%c&0$JD0uz{-w$D}A2yk)8FIiXeJyf$UfHlI z#lobh7$I5Lc=QtNur3n`X?in35QSHO79>?Tzwl#Z@eis`IHD6X!apP^z2B_~d72sp zskx55bfuG$l;uXjD7n}occtil#_C@o4&+_Z_G)ED*BG~Oo*p5jme1TY^t5~@@3mzS zgy#kw&nAxMFrn&kNv90Ch-G;#uc26XL>XL&ft-V8RK0RYQ&T^9Ubc1qa^^d; z;KS>hUJxRu-Owx7=Xm+!sH06Skp8YGEM$x54Fl9RKO;+Qe#ZJ22I5%}1G8zO1C6}p z)OsdPPgB8YfhQc$W}r3BYYDCWmi(m_njQIl&?UPya@RJZDPVDutC$#SljHFVD{yU9 z6q)7>)3iAt=I`J~8K_2C@->LJ0uJP>A5h*4r0n5|BKvrlrtgTRd=;e(-{K>I>mnv; z!teRZ731a-v@v=L!W|?QjRPd{jS4eEYifYfKO-65FfnPYQ331Rf&`Qnb|lVmf2?9W z-x*F%1od`0vUOI4g8v&oiY85%6Cn2_-l?#!OgF)oz=8{DaLGw zl-rMPfJ7kYuG}~vH&AV>k1i~C|L$`Yu05-0Sv76UH2D4dHJO=BONCn#tX`)ygp_J= z)E1~bi0j5EkD&_WR|vz>a!TwMcC2`j3r->GJ!~cfuG29n2|Es;VlN#-#F0x49+vSq zV^+C0-=hy28@5W5S=(S#eHOi6p?yrc`CrpLdDGi`zV?1vck z;gCym_5h3DvL!jU^GcJ9n3RMFzCah_J{*>U2stFj%}=NV|GyO6b7DAS7i!CAY-3OC zmf1caCAiuTer|3x+55}?!PR$0HPv-nClDb#f+U~m-;VEl$GG?Vu`|xuIcaC_z1CcF&Xc3csS}E* zeKcVv&~}EOUbSl}*6nz}?=>(tFB>MF%2(=$=8-=BkA10aY&s7Xeukw1$}HK{z(Xe` zmLr=Bm%QDdBf?N+9?dMUvI~$vahW;vsybKV%a{xHjqj|>pV!C#9t^ta4p&Y4a18YQ zddK+8YW7_)Vx5N{+i^|-OIB$*W4?tzUA-2%z{g(u-LpVf=N!mAR?=?~sVP~U0R`_) zl}BFsdA&5y;W9mJufOp}4+DC3O0suU3W6h-5h9(|I6FA~KE-obBb?XJ*xuGq#3LC| ztT|aB2!yg{rJQ~l@f^rhJ42kC(;B+|V?2jAA9&sB%#?bVri`emLa94)yt7q{bK&t; zhoqebVK$RB-Znx?{RBklo*P8<-b+Uargr^L@NE|DJckn|ETK8AqGQ2UZNd2B;!+Tn#iCq*^i(8ezwVV`H`=GAG z5YV@s@t8+Vn;F+~S`?eBlh9&#n$C9hyir-$YxeqPPFXXsaj!n~L)d-iXNv)hb6sIS zh$kR(*6dh>5%+21UXf23AYl5Zv9k)~rY#9D_=~(?1!+3s)iX;qxR9$Cy!tGWRrSML z17=vW*Zs@-FdIm~6T|GfT+zF|KYNe=vah%O5U=qmQ|;Ot9BwX8^tjkU=t*Zyaj6b{ zX%wvW3H!5?r41=(uc1F-Bf|oR9bIHWgg$xkJLF%S5Pr1H$p`N84ZK#YR_vi#yVIGf z#~O@~EjB=nDAfIewBY|;*XGFZ_YCVM8n-$5Yy6flyB4Wok;PK`7@! zkH2mT6IAWjl;t9rT>6xCFYL2g&WqlNE0BMxby2ukiPOi$*aHF$&7Ng2nZ5j~;^-rQ z25Ve$iSbhl2HaazavTMxwT-W)$RDbaRywv~?T^$RznAFDM&Tx@@Z(m@emGLlGb=a| zkC@?fMfg|6&PFnZ!hcQ|gSF4}iTFJTvOaejE2dL~z?YQ16gcM@_=6jALU%Yx+; zNmqr8TTSQ16#i+{S@?-I{lMu;TltcCP1a=Jwm63Te?Mk|`1;WOwDH+1m`tw>hSDYw zUPSo=tDfx;?2L8f%t>sh3jyXlwX#6LMS2vn9anj&gg3@3!AxjvT?z&Nm}7zp`ZKG> zwmbDcU!xhS!v6*?Fr&r>aI?JkRrGy&@PKb*stHCMGjTg@VnIJYGx0hPaq3AH;!|4K zDe$K*-?5SJB_2Wo9yqZAlq6Rg{Ni$ux0b2L??>NXP(H+r!T#n$50DROy#U|c$N@ua zkHCsCWnvL!wU$W4Ib{Rw%eu-%0IRWWokLeUoPO9*2bsC2ih_;nu?L7%NTCRh*`fYo zXLb;<>GaSqb?#MCX{Q&oXb5Zb@jDj^UtBK@FWnh*=eB(u+9mS;11!IPY2fO=04r^@ z0QuQ~uCYr5rO*Xx#sAw>9@7xlqe1sIuR*q_BN;Pp>@NoIJ_UGiSe?1*s;AZ`fX1UX z!AKcQ*q@9iHL|LTP<5k7{#Rr&ndfI~0StG}{0G%Pq3#2ZFC+N(FkpL}xXbzM)mk{E z4B)CgPM4C!A*pGgCi(4@BHZzTp8%IE?0GE$OP1urib?VX(3-KP9Eh-I1vj0)$)2&# zANCqOcXkuxl!`XG78v>%`HnVAPX(XKXu1KbDH!v3kW$WT3t?MeUDF02q=DyLE(rpMO zC~ndziWSu;+)ft;n>LSP{jH+2gP`L!>w?1{cKBlnFJqW~c4mu1=I*m&N1rG${3+II z_AV0Z{~{DVr_kFH@Ch##L2|l3#G`I-f9OLx|70Q8HPx?j{qv&(F#$3d%d2;S`QEc3 z&wha(7kd-1?nGPmxF;ysjr*su0`9(?fhwN+6@*+N`U?|D4)AGxL$*M9y_Zmd%j6UV z@6!R|#lZslXWl~azwVw65PQ^wMV!l3WC(yAngGyGp@IG}8tC^C6b|>h!g{S1=odY| zXpmpZnUVi|?`5|&pL(k~Ec}J5CDh_tN?hq}mh~k*YzN5`?l0vmPOfS%OGDSTFx>6& zF8KaY0wFnlMcshe&u#@wMk($9F~fWm{C_qGm?dhKF6X7?*x`Szg+fNMd{RqB7uUIb z7Mw*H{H0xy#++=kvk|7xl6~@1gd-URJ!JHl)TDkG33G?(EY%jjDe;pb&@d7SXVhQ=Q;L8$NqincDn>%m|z_Mb9Mc~C7VL~sbJ`WA=xN&>5O?*C%YCIKjjPrY{`z%(f=omF|0=cDacU-P=f;-uYCp65-X%3)FK7{InG3TgG9h~~GH~|Je zMfAEA$H#yo<>{7CHWcidZXI3Nrw$H5kn}~b;}KUWwCSrQif(ao$f;mJ49iDC;aexn zApz|GH;5&^L%}WGSyf^hbxs4ObZ&0_xbQLin{8YM25^)jJQ&23FWDmZ1Gfb}5D@%$ zcJ7xaoM%+|nZMVc78Jp7gT`Pd5L`%*OgZuAa2mC4SaVz$*r*<@(rL&RHsR5;(H=UZIS1xHlU*Z=;okFb zJ@$t8Eag9g5fcow)rASCt>bkDfM2-1;6Kf?|53>;JmJ0^f|z394@hRAp{`GPo@g|) z^&eM3Q;2pk4&pDm0&Ym%fTg2Ud z$6xa7C&Ma4@R8Mt;vnRp7gNsE=30LLM|^<`la&%xohS%di^0Kv>YAtldifEaVA9SB zVop?>lc4=6(YveK=g^-dc^P7uv_DHG=mxr_u_MP~!FgPkb4p`JQDd_wT7ReuCCuXd zXirgNZ{iy*<&fyaSsZ>^`<$r)*cq4YzQ);5DH8fLe%^?qTe`3Erd|B&(GOYF!4r?D z7W3$IkivfA6(u2saeu z4myWB;2`deh2UJU0sokJT(v*LQn^;VygA?0B=>>P+jt9$H>+9Q0gZa!j<@BD_$4Pg z^HhnQ9e)I1!D<#@(%MTQbe_GR#StIgNwA|V{`pb}!tY=yB%r(Zr9c?i`Kb}h3G4m+ znF`nAoPM2~(RPK1SKnYD^*sRvNmmajl{-6{Z6(>X*?%iS+Kb*4WpHSxmLdYK4CjKM z^6wpk42C&}8uZ=crtJsg^jxNhiSi5ttg+#QeqM zx%Ce{P}jdgt!I});gWZ+Y)df+R3HS=6C9~H!anvL{IwCG8sN#rBeMltmrDat|B`f& z9{O|v>x;^I`Hf8~i41mRo1PMuj6BPL`Yx4a*7L(x<;cVDJFomw_4zJ6yZ>C~O!&Xu zleS?ih9mQ~Bn7l~G^T^JZ(GXaKVPEbxhX|=pEy4|fhuk1;24k}+Z}TcwK}$}k1MWl zqukK@<|-ombF0o1zZ|+n@E4`1o{tm3GE}&+a&3<()^63UNw>%88|%(2*IF8pO^UC>ug z(z$rnGaOFxz$CXD$1g~ohrTJ-z{jms3JHJSca+<97{46zKz7Dy)KY!3aF?yHZ-WWH#fwapISGJeRbB?FyNk*lP)hxI!n>0Au(eg@#p`_vmTH8~>} zWh}bGjDAqwN{?HIa}KyITf7X*L7H5Whwb_ma2W-%35;9c$9ps%y$GQc+mAX zh{i?0Jv*J&Ipyl?<5YX{49HnNDB|9c^kn*8^W_PKelrIoR5pMP7fgEx16=u-?~SNb z8U2I1n-QG$Hxy$FSJOJ)XB7#d!-^REDT_^7Tb^mK`EMcc#c$Un2`4@^i*)U&k!CFX z%$JqFKe@4AhcJ1xPi#C>Y3I#Q8TMR9 z=A{hfJK3&<@-g@6X1S%v%a5fKMZUBS56 ztmyxM-PGjSV1%`+<9Bi~9r7Iv?dpR4te&_TR?j%q(L!OIhwIEr30D>6;VI;1;a7s& z@WV-EPs;-0&G;&jkIIWpFqhZ{=Lh$kJ-26Rr|lQGjX5}N_jJlJY&-dDK_hAG6+Uf< zJ;yZgH$Sg#Zq3mZF)}VMAlxQAS|tgF4VOi_hI*%7TS1n$Y$7$$=uwgD5Raij1vdC_ z;!w*by#JtZBeKR`k8)>#GR0z~%p|{jX<<+k%<&i*1v*W}7H%cspA~;TqSw9gBCq94 zT!t`JONE-Sg+fg@XausY=GYkwiQ4gtbBCDY%T$%PZ4lh)-G;E}WAUf>H_6hb32FW` z(xs0j#7S+*`*5p07TcqB&@B3ieTrEd)-NdrO-XQkBA{_Kk6s+hm$b%(^KDJPeusZ; zOph4ZkUhklDns6Xwejfl2S4YSJ2*m642RJ^6ar@iy4PSnq5xA zhorCE30|R`ayzHRov19aN+D6cH*c6yga@J=Z{9K`ia{U1*RSnMKp&_w4N7jA1$96l zJZ0!yQ)(ALXoOr{uKB(F3|+PR42|7;W&tl}dAn~}DNYQjY!M^&pd?ue6@?D9$%PHI zNneIEB6bL<2Cv#kGd}P!GOmklo)V;rWDpD;`j*PPf7mY#CX^rUO=XjLRi?V&Ft15*s2N zrA-@Uxy2_wgmb=V(`c#5i~kx=aZj)=YFJeFA@80oG;x;NnN3k>^)|-pl4Gve=<o||NhLpZ9rHYhQu##(U?>f(ez+=DTd!Q3bEhD;S zZC>U_P64-1($A&`Tb`--){03?HJ>vPzS5}y=W!+?q-HDAuHTv8%K38l-GeR5G_7~h zOQO*;ft{tZbfbUL;!*1lvyLWYU?)^G8qMn41&B<_fivIwzuYajA@kss$H-oJ*9a?V zr@F5ogwg&gAL*c)5%1DlqQV~*yi=_y*e~jJAAch8hU7~tdjpr(6yDvQd1hl*Q%v|1_vyv85%3|b-U@~cKm#f3S$h#@eF4p&y_;KHx zW&?+WZi_pMjMeu%1yRL*KEe9*h2bgY!7+zXr%VlLp zjV7pla!qFW8VcDmeM(GDE`?unIjceN{9d5NEb`tZ_9r-4vRHTU37=LG7=Vb%8^0Hy z`-U48DFrU3^!XlGK5tx$7~?(xP=R|hro%E>1TC|oD_R^o!8kH42|es<^J8>WM3{uTbM4REzU1c8e65x zjUw9iap7)k|FkMW$$8gm*A-OSb!^Ds%BhS7zG^)eeLFV1^Uk}H$>q)>%2sZ(C)tuD z@g;+F{)bClJBF6mb9MA^_;SL(=+VJHkj`MksOTE?91hexE&6{M7kT#+{mt7}XwFs-kmXL?!B3A*Bt@$0>8G(8Pkws~)nAtOS&P`#GrF}Ut2%R*O{7CJ z`bGCa;)S2PmS8$nY2eGVm_sPM@1~>#3a&+4B1#`Csqk@dvAqb#d7>1r3fR{A@K=3?lx-o3yHjoa@tASsvbK&dgSl7z&S zd!H3}et?Z7$Jl|(ab({$x?$#grow}^Rr^CyGuN-pu2PTAHE#L`?^%lrM9?kuJah--C!*g% zujg_*B28qb&{+GHR)rvHXJ%-V0j^}RM}3lmTB&S!Y4=i=UL#8`X%(8XoVDlw+XJ1; z&5v@ZyMeDdB|}(;=6Jc*>FE{vQaFd!Sp15l1+t3X`%xByH+mTaX}c7QDiEj!zJy~r zI!Cq^(B<+@R^-0>7oHXR?tC6bNRfZLd;3^Ve_|$WFscqg~1*FyG_6&?^aZ**#d}3E(s$S4-S$QT#D*^lvtF` z=na|xV5g#S6|!r5|FCpKQn3HZE+O~%Ix^+lUW?gG6u_kKLN_b=mmAH#Clyq-UH(Kr zs5iYe8s70<;o*FU@%2XWfD5Pw0wn@K2zrX)Lmj)cc7D#3g0sb0BIqznK2RBK=9Ol^ z=3`mmiyukp<||04?&S+yd{>u=s)>cFOdnl?(2}**sb4- z;;RRx8`nOBv8Q{N%09k$aXO*!kz)0g=ZKlNSGdpJydMy)(QlI}8RXwf!U0v4F_1r)&gjLlg z7iSLS&EenlGm=llGf5dR(WNHAb*=#;Nj!(^hJZ)6@DW*YsY$dZltgWI7|-^q4JXYJ zHe<{^lX%}hr!OnMnDpP?7q1(S}!Pryuc0J0CBBZuXetGPsWDGdFOfJ?8kTFTdda z_ukUNjDmYpXblqmD3}atlWdM)wd>TOjWIXDZ9^U+r`vM{^U=E1NPmvtaj`s>;!wy) zXiY5@UL23o0MB!|KUc7rs9TMB&Cy`?|8)ebJ%7(?HsXDFa0_}R%&gPj6{OPd%ZMv- z#tUE!tVh)GEOjBmpSvT@a?IN9HLAWg_~e@6LTQD3Z9iBlMtWS6xtG~+*|nKDb;`SZ z;<729wOr-1^6)77oW};!iiu+mX^DM@q;{@qeGj|}zi^ZL*3dCKRyz+xI;WgzE?ngT z2YBC1*5=bHa+uYr{k(owFPsYJ2}rpu$C^L!da~FDaaEHmW&za>^+bP@D}KWsYW&1D zP^^3TpZ|bLZg1S>b;GPrEogspYB7+sYJh9}2}6ceb76K3sS8_8;hm_$ft<(7*CtCc zM~073kmY7kIX&7kp&|r27(Y=54-(I-1`h-3#)dB--kf7|=vBvyPa$S_O%t5&F!jcS!mV4>VYLr5 z;k6GiU7ik-NgMFodVQRqIETQXj%%fFzvepHE-1OB3JG`xw>gvZk`A>BC+>p4fz(%g zP}Go62g(%Y!VBjQSB-p+S9vxc|C9`e#|O~)D+SvA^C|;&RpJyP(p*?z;glsZrMtBl zx6C}5wKvU=<}+f8zjQjZ7%DbSA7HW1>E0d2iclO+zusvW|K;v_Sdy^%t?e&&`7FrH zsozS!+`Zp-1bC0RedT+n?v)=k%b?WTeB)nZB7h7*xL1(UhLuc5FQTC4^m5ZB`9)pM;Z4y zTpc#7Xu7qvCCWdGpQXZc4fv29lSn#)h^x!gI+3A^Rq=s2(Th|D+sPcfS-=v+pvTq7d3KWW0f zx-c*{4Gn_f_ghiamF6~q-GA5bUlWkuRmP9*sJ;dMfb0ZpBWs_QV`y= zJ?vmf$qEIl_;*D~{;~y}*HV0qbN7l9;Iq`v33JY36B)u?x=UUTL!|y3 z@RcDQeqX~^JvfJ?67phHog!ZvUFTnEQawjsF)S{Selug-`4V}W`MCn40$ur#^Hd0+ z5Uc@(@Vdp12$$+ymeJZK++<9!M0md*0AEoVlu>a@zWS-IAr(LW=K57Jqb<0fbxVD1 zjqmH<>b34r$4kwi>F6vmI3v$UOGJXi zi?oy8`y1A2Cl{0U#@WiX)}j5C`l+lM-tJ`Z4?7t805%N#O?6$00M&Dkv)_PmVQ=vn|Draz}d$}1>rmBL1p)*_t zH^SY5cXB)eIE<)zBZ?|EEreK1*pt2Ys-kqs`s>LAl+)Lfzc-p>XVG8RjpD#qUQ((|yGy0~?CR&i&oUC}9O|X$b3iwz zN(p`ncae1NpU}8g*Q3ro&Vg2saz68>GRg8KmvTO&MR|nEvdU!Qp5mQ=%{CAX*F6+l z1>{^nW#X`S1zpa_nr}>mkc^4&a^ob_`f;V5b{{johM{OC4f&b%KiKGNaj{>9FnAGw z7m!l&0HE|N0DvOHw&y(mcH7o)eS_J1s@Q+S)@U7RVz^EtqohT5pEJc%yS_AI^s(}j z-OQ=e-Y#I;m<_1={a8R_D`zd?2dTFX^G9MDPJO<|dK9zM%)C~d>Xc?TE52q4$i!li zJ?A0$agh<(TobKBDj738DIe@-^UI*ZQ*gW4mADeU3?fUjD=XKf5pJq(g}rnq3=HM| zBuSI`{W1tE6^;T`?^~(mT!v++iYFv5B0S$qGuid3bn{jQ4D7zT?S0rR=rJUc)_|$n zbi=6-HR0=S_?ZJ2fR$@0w{%z;l5DXD(5-HD*swl5ID?+bymUnkLHXHgqtAP#+679R zY58qWLUhyjKrrF^N(6Z`Pjr(YCh7vHt%{aVMZiw>e?<436cxICpAa`u2g6SE@~5@a zt2A`(gnMGvHE6|Zxj92hvlco?L^Oo6v8Y3etq$8b0&U`iH;N zINQ2xA8qhC$Yv1Fmwqh7tILtCb`{4UHWkP4KmK4$*BEny7XqOR;tj?S&lXQHKX*%; zdl9A29v|IKs3+_Z&Zx2tQu= z(!OQIv>G9+h^UmMy#wHoC|!x8A#W4{m@;)Ac^e z!AYfj!SecT3o?-l%e@Y2-?hJGCbj*`US+w&x~-G1MbmAqE6ztnp&5KSTfRnw%`1z$ zpEC98S#qO^8hDCx!(&BcvDd#?J{K}GT{My5s!z)n7w*;;$fenP%qf)3-9!6m_oo(f zChLmh?q7L$r4kNa>|T9XA@{_4g))}y?F^#+K(KmpCFxz}(iVmPma%W#XhuuGw9Q2{up$=s>m+ zFhJQN)cIb^+!vHz%!m9(J9-dG=&(_*KRdGCKM?S5qT^Le*E@bXD+3yr2|)a}cSJf# zWw?jnq+-^PZlj#AmvEDmS zg});H`3O!>ck2d@*8VaU<>d?^dX^dUzd$e(vz8f8Z9vNjALLgWidkQM! zPe?kQNR7tvW6FUUzYZP0p7iblRiM-Wt?E2S?gp%mtFMJ{8h8Z6_#Lkp#S(^@86TiE`**iG=hR zQfwF4ZLVk$ATAaI`h6h%y1TxbY~YOO-u(-^`aQS{!7c;dH{QLlA}08JcKZ+N>Gogq zsRQEBId7J2Ii1U5cTOzk?tMUoz2yU-r~VpH#u7kXnXvwpu5$--|I1wy&KQIq*?b}=okOfsu{Ih8mgW~ z&PWP!djdgXa1Cj)xI^gJ^omnmADC7M%#b~jdhqJ7zWrV5at6q8-d2|_+5iEthJ^C( z!2O9{c!jYkON4Fbtq0nA>-Roeh5CFwY1>J{B`u0d4$UhniJnN6HFN>O#wP?cxqUM_ zcJU6=JFL0(?SEd2o9HZent>!(8r-D5{`)~}q~_Um6SIZf$P+4I2DmCZC9GI*Bj-;Z zv>D8i0O?{ZqxSytJKAqZhw!93o;NZe&$GbUwL(>vT_!U?NT8eW5K1k2rv#G+RMmAf z*3}&-K`i{Jl_1Set~*mMvYH7z@gtLbe_Ui4XL#a=CJmWT87j7Z6 zQ*=9m_&NS)L1yZ^Q@qD^gGn){T`!S=wxnCy+Oz1+-21oke&o9Kqr&ape#ZqPWlOlD z{V6){wDUT&Outb60GTqim%~+Uh&zMyn4MxPYP-#G;|PV-^R-|6=m;S6rXWAkL0A|& zdjCGY>N1$jMUfittYI{cWSM^5KS~d8wY8vqVRt5z`lFQK(%yDon>2U0eQHSFwEDvQ zP9cZ=LgibQ^e{O4&5){2DEm#WDC3$7AjoeWL~9KX_Ff{>sWATDVR6P7&jLW<6pAQ! zas+zY!uLLp2R}o%sz)3aq|jl?fQ|6q><1@fqd^n4Jx-4!P4#S`L{e=^lYB0eGjf=9 zgG4!tt{!wksxEC4P_96fkykQpFcVO>&?11>(>gSlSN_z;sUAyI;3%>+Dmvd)~#{c^aP_GPXCT zU%mGGX>#RVeWL`ufceaBoc#rGKMuO=oHju(BS4y0$Z@QCJD-^~u=93i8EtKn*`7mJ zFTS8S_~;n{No8cROlM1JSY+$}n?K8P6|CKp&Lz3jrJ+3<=uc}#&KUT_h!C%Xy^|^X zj?Z2eQyKb(g1P{8^Mv?6`lf9Y3CEAwv@2y;N$clcN(+TMf@}Kq7(JpRUohpc7RTG^ z*2=sd77vg&9l^UYeK}qn9a)O^W%?4j4K^C5B9OxadqORLiah#iUy-av{1o?3Bd1ol z>B{M&^!_K<$D;4EL7kxlJ-9yh)z#$_o}*H93;unC+loudyWws&l`R4Vdu-yMi4Dr8 zFDpHIoWQ+#UcLM2p`<%3>8JVTq{!jcxQpBz0S?sVx! zoa+9+4jid9_J;hMkL4~+Fz8B(ph1_&Sh~L>QkmsL==Rgmhr@RJ8ZA2IB5<8y+#bV% zjv~56hZpc%p*vq01!vZ?l`RP73|_eYnh0cy(C%NT`UOLSs*Af`nR>M>{Vi5RxEzH? zz^P1Dh2m1cNQj8vle+in#D_iE2d_43ZbqdF?Eywp?)WfxAgaWv-k&~-{TefOpiG+s z4}E0aKljA+ohsU_fIjK+zKPiNkmH!iIq5A=)@FKEdK7~yP?u4w`bI^jvdaNRz2952<^u-fLSjfwn+x5pjq-vG>vg{YK7`m1J+>Vnw}j{Y8+te!u~B-M$fZ|^ z;@tDt(dtx4=TApv%j=z#60o|ww}p@NpSwiw{nQzT?=uX0P8d{^G!5xN|Hv>1BGQsx zK;N>Bpj8WVeC`~p%daaV8>p8Dwq?OM_;Dx+?1PuoR%-gxh3DJX!g_i_b8ZbCD?R%Y z3Up1V6r6{b_Bfol=eDTH6vy_C-$zP*boMAz+;FI#P3C4z|bBXT7EtGr1fADfQT|@ zu*g7zU71D0J~$z%#g=Y#oi|Hq(os_?x6=WOzq}S2wsa{3;k`K1V*Wi{Z+gvp$5o$&B0+L>!v^Nf>@?yjJOIPc}y{nHiV#2qD|KWL@f(>uoo>-nVF4c_^?-SF)rjZvYHoq3iQ(#b{*?s!tf zxLaTWY5of3pIg$wI2d#9^AoA#)9Z2(u0!1>mq?|0C9Bzva#>G+XlJ)q@7XrH;xa^L z8z#F%JGc%RRFiF8`D;dOU6H;;-i|IqZ(X`*CA(`8S#Y21!m$btsr~P>s8NcDPiadrDHH2uYcg)D;I7E3_eJ2wV|lD>_*NrLpUNBUZm zqn*J)o#-^aDU-Hais91JYue-j(vpdVXG_h8EgIaU4*X)y-ZHl-ONjf?477f+JqP$Y zS6PgAF({N+IglRwBCP^6rLn}B!1M#|r}?#y3mg2n1zdxc1S&XA?`*|Zg|eI6DWZhu zu?^}q_ne3Rl?0Gh)e=}+(#}^Vw7l~bUDf4Y-k6GJDTc$n`+pzX)xIM_qLKW5$Io`L zlx!W0RC;}47cy3&v#C4$AyA2cmrrJF#}NDQ_TUqIvoCG^Hal*5&+ya zOKWxN9z(+R2IAkFuXQHKES_HcMnk|r2GJWj)9!UUz~%Qr%z3Q)-1@I4MTmr1NfMAj zY<3ms779IaR(f_p9m_69o%V3D7I2-2KC0~~H*Z{rX7M;bgRCWvrHXzA@1{Klf$h%R zRr;&e)I#qdGnM_yvC_VfwTC0AqMzcSCtM+(wL`pBCsGoe0yQg9PsRKcg;*JK8!iPx zTRcC8D(!n5-Xq#AlxY^vWX>pA!r86-fmAQ|q*j}0lc9;wA#?jCVo-joTM$^02y&I5 z?O-;gn(+VC2!{DUQF1j0qr0-0I^clAw0FfBx^Tdt;U6v;c-bAsBR&Sr=_9$+50@JMoFHbpCw`MgO0tXfORg$F`Y& zS1N6<3|;fz65v?rREO~dz(6^eMFi5!?hHEMglfdam%#$ik{{n57Zj;Q`mOU7s5&E! zE0>Y}mI4j%M1LL((QL`blN_UowWP7?wz>x8=iR3l8;(^2d~}I|oKdR_`W>$2rmAaz z%ZM&3EgM!hUgbkQ%RXAyy2dMh6W9T7mJ&K{mU3Z5DQ^L4))1xq7918?(=BWNw;xj= z(%y5Up?9{q*^5 zaffL$LtDivi3}q24NvDYJ?f(w+W48FOpp*pwrLKJCr1r}yB%G2BrcU!Pv4kf_+s2v z(s+>7a;t>D0(yQQq@-s}tiYc+V>Jkp((YG4f`!tGnb3sAC*IyGn={t_AYr={vUgbS znOb_@rfb<0Pq|fn7>8Q7aSfqxiIR@aAm8=NsGR?9?^ktbjitXLe}z(6D3865Y7Ph=NV-umk_8=Ex{!(vU@uilqm8NEEiaW;|wUrW_Y zZa*2Xf(B&H3_W&lp=Yo~{Y}CJWa^?^gwnD+kj>pZfyWA761*JO@c%F4Dd5LfFTv90(#A3VtUkjyKkss22)L%8v}8pZ>VhM zBinGM2#@J+JCczkENcW)TM3@JyuDFVHjSw&pQ{$!&lJ%&&&P;k!EySg4!>VEGiR5s za4!Dnwp`Jl`i=)Cuo~;=^f~F`Ijkh$U-S-*jvk~bXri-z(QH3ulSrT*QK(>=09TMS z9Y%mp(-g3K=e!eDdp-f{hr0YCm?>JN%IpTIUM`iu8>+8tyN7r%lNieDjUZLuO&SiOA*%xa%Oxc}Z$dfbT7)}&5WyYOW3+eZ&r<9T@Qet%X3 zn0shn479^C3Mf!6{zHy6tr})3&ZTnEk8?lU=-R6Eud~6| z3xCWCg1n|{i|fxFB;rRX+w>6hkMKAqZcazF7jzk=mCG**wQ`;9S`*Lm*M z6%KdUaEpM4Sv_ztyG>@kg&N7|Qp!}z=GOn(b(;R6Ib!e8EMlHfAYbX(0z*jU+<>BozSCr8!HnFv>trnC#FjtXBm(Ht$M*?`T*v>IJOsnvNea6y$AD(Ps^R0=MP$kYPj7%c^+EWp~4^8 ztHlvDs-ah`Ufg-wo-#4)fY2_YTOT0(|Ipx}bio;^mYOrCgV_AR=U|0I&78PxhlbY(Lr;gxH_63r<)>npnuwc^C3q6atwV zgk5|2A|KYKBap&VC7>8I7&fj~!lV4t(Xx*M% zND#LxJ!7*!72d-;?1VHKcA^zVb~FP9sL8Jg1AAOrC}Jb=Xg0cQ@3#D$1%$-Uj@%T< z^m8koeM3uU?e3=#!7RFl3cw_B4?7Z17CM9T(O$|-3 z%qtGr_WRxDBLQ1RAQ5oy zI#8gWkoUvD^8P`AZ|}Ka0huoifs@#|k?#!8nw~GeT6^2$HDQ2e?l=L=9p?)qXwA4_ zd1*Qsg#U+2^0Bpolsk4`)BL|I(>_Bx8PHg47l9@h%Vty2NVwg72rN`-2a1pZ&7Oiv zMgiqWJ&w2nEHv3{ejkYQ&w7tyzC=|tEb;j*U_2=82+JG#B$8Yl~{1`t_*^IF2v!$s(jY?t+3$d{TKS@a> zouvhO!ekH>80s<)nlL_;<*2rqd*7cm3@u)pth%@M3L_k0&O##i!95_me%kf9q1Tgf zqh{4-T#zX&q}YbrL;rdhKHvYDGVDrpuQNFjyg35cL|G1G45L?=G2e=KfO}N~d0jqVI9+h}>-anY zO`W0SS5*3~Cdp0NHMKBU+P1~%o1S2+CwIGxH~0PD5)*LMw0 zNvi8hAGCm(vAjO}+sGBVNk8j_|0H_GkLC3MCoZ+B<2O6o5gvKzT)3RkywLR%`mMeC zu>Nl)1iz1Wp}-$Gm@PCvWkJ4?cgJKDX&GyiIfKN*ZnF z@rquUwbHc%$qXSk)piV&#jPA5nEL#|RMT1_5eKYz)IKsMa9^V59Vm^0{z<9SWY{6h zt$Lc@)^sxO_|C0)`F$sp*LIrq4L3Am5DwL}#VZt!0cyJARumooHoUVNF#QMqKqK5z zq^4DNiU!`=F3Ci=$WmNxNuyg5FM)dLGY@UuSfLy2`&ttghZOaM5v5aUH_0IJo(zyoT1Z^BKl;xag(QFvg+%^ z)0cK$7n8^bp9*jBwEqbO#Oqt^G5BJYKn$gSact(03<#{MQap|rMD{ttV-NidM0MVIkL0nx72=Z4GJ zmBywL+yu&%!BI-aY9hc@>W)PEP?(~*CK6V-4h(dpgPXVA&w16i%m0z|p@cAYTfR~h z*xMljFOc~k7DjWxD8zybk4}23NDD(FT9BRb*Ms}P(lHZ47mNtC3OFsR`*oCafQw8< zZbU~XuL!Q%?Rpmd4-Z=r|35tJ2j{uS06jv)R}%kS+7~J)vSaXDuY#tKyn@{HpGpNP zjAf*AmUar8&S+dT--Rf(^py|O<({R?dC$}5fkeGiis{ho8}cH9lisH&j2*F>WGjC@ zQlA(Kv2Is~^*bWzHudo{IV7zD@jRdN$_55nK+qfx-e-8jg+ZF2t!R)GZ3Va`7#Mgs zz)r{lpov_)eoFZBYd!mnR!-VR4>F&N9U_<9wp_&xjTcAK{jZjqR(c}pMXaV<6zy`S zUj}*O79%pFq63Q6U{hmm7jVs$=dO1=67p$59KIoE_89+KLInzXs;$2{h<_fvP)xtU zvaRJp(#^UM^c;*j>w=T5KX|!qC$5vKoTZ;;QBe^Gwx<8=PH=5 zF+NmFq}SqqNppxvHwvKz8iiDxR1)}fi;vdBKTTKdZXNCFL572N7;HM6a52eG!IcPB z)5F?K(pG0^*Q_KQ{$F1VG!Gk%=^}Ya85q*<=e@vf6+X5FRLSfMm`8L@S~ECFU{7Mw zrxoD4wDKEwFB*8A`b@!K#{@QUAsgIY0^(E}eyy-U^t#KJl%X9}( zro=K0!F~*oorq--A?sJDaTbV;CzT_&XEBi{C9nb)%<=u7BCmeB88hht>!0+%RlQKe z8kg{)h$L;HNKL-}*jGHXMa&u`-iYqgbCa;+^Pw+n##B4W(t+zy zXQ>&mp-E(l(F%|tBV?T=--ph~lo?%L#`4O_(ErbwTJ5*mpj{J``Xrib>U+1`Z)0LY zFDM~XpIFYN8941)T>5Lxh*#R)b^Hs4GyxbY4Uc&qy~&;X#T;Gz>5XdgEz|#q{g3Mp zVlH6Sb@pF`=#9t8ctfm26Gm>!(7BADVW8Dg9=!y*iS#!dnXS1jFizkb4j03r2viT- z#~~T8E$W$Q2hp5W;GEr)UFB?2Pj`)w>he_EnOSf9uHg}_cg_G-9Nkxp_jL~s^?NIV z-EX$mudOVrS7(Usb8G3=n%4QY_36gZpb&bwMCdB0@ar!S0d$r=02-KclcqYb(uhVE zOJxrPg+NFw?8saec7ffjOrI?ef=A6Bkg1zBgp?>b;U*7Cztp1jKILWHY3Y!b25Ar^WFX20NK1>9bf-uRX;h>H>5veR62$L4U+>TH zJC5HU56;E2JFe?G&#UfrG^v5+yRmbFUVp=b8Rc<}V!T7rj-tlCz;B zz-PqIr)dg1WB5_~aqWc@Ba_EBJ1iR=ooBBwUZ~OZ938I94}>KYI@b>=^Jyf61ic@b z1(R7!`nPa7O@RVGa)Vf?ZxNPl40*A0! zK542Qq;CHn9;TsX)>?zor{Owu`7UkRXuN7x>%kzJEXnseK-R5W9(FtRO-8Cjg1Df=amSdm+FD^{=E6 zN$>ELZd!05wEc0puEv`dKgOq+_DTgjCnTUlt{`0J7d#=s`+np&wyO3H)Eaby4jtpk z{P!z+@ivtNhM?j7mBC#1%Q@pe-t1ihNXdbx;=HG+q@3=tVX zuS-eq=*u~H7S(}hUNYz_OPLUwUkkIZ4f0Uo_2B9J)%+DyewBlevKTz`OR&Myb}MO) z8~v7!q*Ey4?%3m?8*02jo*CuifkqD z`(xtqa}hCyPa`dgQuDMDizMFyls|`@v{sM${U|Ft*>4Xh_0AyiGp%vKh=`fe2mr(w@L{;3?5*wA}Pw$sG?dOGG5?4kcm*Z8s6X&$hQt zkqZ=>UkP)52E^CKBLfb~fe$8e<=p36fP{H|a#eWCba5|rL%S^GF|U2GSxjiVs{LHB zdGWR{-Irxv`}Jr!l~%tm%^-{sOfAS!m$OSUxrKsV+rd8&-f*DBo-%PJ?h7e#EL%mr z9oVI*WXZd`BWqtg$chVMWUq;hCKu3jY$a#Us~PFE9_;dZJr$atd*Ymm8&19x9j@J} z`dc=yQ>(W^=zjaGa+dZVt(S8C_NkxAmE~V1 zp2`JPp860vf?^nSWw9hv@q02Ns!PQ@%4y+3iwDqJc1tOx&;|A!zL(=2XP{r}H{SNL z&#H(Jh{XItXALpGoA(QR=WQKU@tYD?AwTJfi^e>{W%yz!V*BZ)t}6w*I*^9a6#;H` z-(B`G`z}%rv>0#q+JK7I-CiWob}y0?T-Xmn@{vwAcK~J7E#CX^m~N*so%hOa-g8>q z1LXOm{~tdSDfAQA%S}->Fw)pzrk&riApDa;P-4*!zwh!j+|zhZaPi%|#CYcM>bv=G zqH|wb&0;!(K>GCvoB+V|bM?2g7y5nhfu+iMiyo`?*4Y2vxC`Cg z`UWR1^H05AK5yYr6?Aefl*lMkd0wr-(fUXAvlK#iBWXewItLz5rR_g0Rs}kac|cN= zC)I(L%`wH1mb4C(Wj^D^NaEEEj_kc;$y>jm%qtH0*Ntr}^y+$yyJ+0CmVsNgH~3lr z`Lg8$j(2P$XrNiH@d61>$d5Y6y1ayN&?;VzA;}D=uk&;w2)~PZoR&@Ti= z98`h5Fcw+i>+ddqCbGN5z4(!n^M_3W=q>JJBWQO^8N?Nq$oAr@2$?}+PXcJ{dE4$^ zFR=~XGQ?Gn1%1WEA8`F#`7g^GMfRXw8U7D#KXLlWU#vHATF)b~%ePi2^DU1e-P<@_ zYH;ZnxtcK0ZzZq}3BI|l_pYhi_{Ej!?>NQOlp%OG-7$T>^%R21-ckD%qcLgBg7>|Q zigc$;Ta0w4odjI;6RmR&ffXWFe9x3!6IUhvJKh64MWqqW4{|JkxDt;`S=cdc{;~N6 z@><}+IecUDXaBm6%pZ#!{d}4G5%jWC-)7t15LFig@%S5M0sk_>IUpk(6uR>feKqq1 zE-TsgoPc>l3|SnU&GVjkOcl8?>jbo-$x;QMCY-B^F0XStka%B=yeT$QSAjnC`BdiC z%#T$6d8wunL1@GJHN{;2-1ZU>P_cA-+EbC&=BjuDPX-26Itc((G_Hz*OO6y1YJ1+9 zi2OI@7J>aikub>rm7}2$pd8H`WT17wnqC~B4lSH_n4KmKmBR{+8)$p<5UYRlg|RZ0$iCm6>?B#NiPpucc{>-E#|dpHORxmKYB z4VGL)xa)-?Xqt|sqy=YheBqHyerIaO;^F5;s{!id!CB)uMv}>3BC^X|1X=rZ1S0_m z_dhmr;B4eO;`sZdMVXv+o3C-bX)6gYuO0NMQU)$_#kB3yDbEMk{niT1LrUmuV@uBODWK*4BN%Dxu2mRM3D=gP zJmFiOJ^$Yc;iuDh)GyQsle6sf~k5~+&<<~_?- zv}&s!lmm2agHG;$T@H){jnskiBu4k2-aY#LFhm+bzv-+r=>D>CD6W$IY` z@Z%iKb2?PF=9ID)Qx*Y{lB*z6q705@I7tLx?F#|9!7jePS(K+OhjsgJhA(U0gdncz zcOeYv8JEq?>reVeu@;_j^5Rlo*< zIX=R11vV!N$=vSRKW@Z&4|>ud0_}mr6^G}CgC~Mhr5jdb-+p+Aipax?@LrQNJ))o9{R43jC&BsWpego<(uKB2Di4z zmPh_LT%tyBjxAVxH2#dr5_Zd`+H~tUNr-lgV_M6_h5(jFX z@x-|E#b0Zwpag~IDFyFBLIz`2`(|68>G1B$C>O5dsesI4a|J)|`+1`n#8%Yw3*ery z(bEOp1|g!Vn0VR;A2>lLG$`krzw`ZRORQ&WR$~@Tu;PD(efq($#=$#Xd)_av`8GeJ zY?)Igwiq!RQ5ChYY$VlLPRNj&6?{qhX_fSs;3zIQF?X8`FrK6_`Y zjJQSW%wOJdD@?2 zj%ZzBVgkATJD0z5I+^#Y0|M$c`Et~eb|HGV}W6Kr?-ou!0_$L#<)sZg&GQ86cd`kC=Le10t zB*CTrd%JCXepB@C=)U*elkGY8>V6y(Q2q^Pgd$JXfp>EcoN5#{VNVR+EEbzH7x>}8 zZM50w=8us~7Z2%m;OCbsf6w6Y2p$3F8;vxpAm1Kk9)z?;cjc)fz@Zva7DNgix#3eo zTBz9my#DJe;rOf~9@o0?57l6KS(h1`gwmPDf8;wpLeWwl^V7K8VA~emMgd=@aVRKn z{h}HLFp_{0WXC^Hqd|h?&;vi0?Qxj@95{dz92CH}Q&jf#;7aVB{cCi;-;}O2{!AD* zHY_T67MSLzfA6qr2bbFP&jHP_BI{o(My*#XldhXTRP&#Q2LGp1ZIU2Eav^G&`Icz) z^Yz*FnK>kG{m_A>LeSHMTUxa;a$7I&0 z+a5jboIf5R+Flb+rgR>?T&39G_>_=q-_sBp=c%zUXvieTn7nG zM*tKfZ7SFgSviVz67m552g`c41@kQrtn?W^Q3Q0_h8np!{H+gKy+=Yt#jskT->M;K zb8JPoQR^agUI`e^UkT{1%O8|^mN+j@x&8Z>cNlQ)N!yHJOX503n3PZeC}o^t3Q^c_ zYGHp+ag#vklr(}xjf=>g16c^t$W^VgH%UBhb{xG2o`Y>LbpTONBcIhjr=<42;Nt7( z1KuL8&E(J}s5)nQ;`-0}JYS$fo})^@lraKRR(qd$lTfqyhn@A8Sw`ylkdQ}?I14qR z#Oe8i)`!vMLHBVUsGe&=v~Zs27@yd)Hd&o%gVJ6+0I~QMH#o;u|0{E9w4j;Oz98N> zolOg0_P}Fh!~OlWK1pKXi03x23UZcBGkJGCOg9_QGs zQS&-DBEj0DD30{Y0yrTd`@O zcVgkxm1&$Dz93Qvt{cYW_c)TJph}-z*?ljlBHF-DAKXJWftm$=>;69=6wPu@jD5jE zZ{3d%;++J3b4^4w%Y8)CULQ0zlj(+E5EeF8++Cg7Zt~)B89sh;8Bgo>J5(%jot_-T zeCxQO!lUcgBE~XEIiI-pB+5^UE{r`n@4Q_2yZ-m`@8#^@{mws?e~+lL-e4F0{>kZF z+4{LBFZ<-^ymOTO^6dP{Wz*l2lN`aHU%{(Oe=W}%rB3(uX7(-?Jl+nRIXgW3 zTOxRyDd4nbMB@!bv4%`Y+(Ltx@m12Ht zJY)K?;n7e2YQ5>Fjd*QF2YjOQ;F}KXZ8U-D6d#q*M zO6b>0@y~A43d_a*Tq7ZuvcuKW{07M4l`nVx{zlT=BA_CstNM9}zd3NvrsyWq)0ojS z_a4y^0X*&wcF&@l^4|{m5+HO&PME_=W8USfl3Opo2wa>y8U@*8b*l^u5-^5kvE!*e zaE6gbL_hJLP}#fG|GxE_h$^O5#XDl`uo#j1-jlIS*DSkRhbG|iNGH;U<>*YOd-MG_ zXW>|d$i<5v*}s>sQeVgkSS~Ke*XsX>Q>X|gC%JQWCPwngi~KaaINWM@?@M zhv061@YpuVo$s51a!$!v-I*~PXJ0*dm5IR6nttx(1nQfi!s}%_*VsRA7B?n7`Ek|B z8U<>iF13E=S_+Zhx!7dzWswfO-#f9{qQNc>E3H$kxT41HM2K2>U@FwfY`d1X1JgU; zsUy&@p0A2QcGtv3y~SCjqLUcnB>SCegJo;LZ3DtdlmDaVvB838Cmm@ z`KyU|WCB=T8!F_IOIByf*ih+2c=yMg&J;^KY6CK}%Q{U}s%Rr8(;{Y2++n);gHu5% zGf(5f+@q7(QK%r)qzJz^Mc(Rw&(9u>jk{Moz46)e-1Es#@#eM~9rB$z-;6Hj52}KY z&|M-mr)fqqfi?{Z$bYwfa zJls2{4zrP#D$8Qo#12Y_wHne0ntil2OI*~Neo+(idhiW_&(QXLbbQa3sXy#;aB-os zsBFEk#1bFY{6EHUR+j$Rzwh;fmho;uI%pQ$57$18tkxVjXM3BRah*?0l-d-f-W-Vi z$i7i`Mk`O#k`w3K#YK@gUi|?6ZgI_c`OZ7ejGi-bOEKm~!~Dj#c-JdFLhS_~?U!-B z)QYT7OMi3=a!z|s70x_ixKyLVLj&{Ed@V5Qu7V!(Ex)Si_@w$-mD<$7(v8)%I|2s9 z<)4&}3VSOTWhBS6hKtEk#)t=Gv$4z8{0y zLC*QQ_EHFQ<@JPF-o@Z$BGDF+vM8z}W`lo&D+y#Ek!`R+|7`anxSpMXRAR~1;~(H! zj$$C&`M_&q{5q!QB(gZFV^m|@TRn`g;AOqW6mzlqw%kEO>z65FiDUr?Yku)S=J=`! z+*F+`aXhOGa<@iJN8(j(%+&qj=#25E3W(oFGCOhoGO)zoZ~`(NPKVM)Lq#5Uyc*Xx zh0lpIkp01!P^J+&+M}D8i=()!4FuU&viTr0?Rt^V``plDFh-7oS}FEtvpgO-nCgf= zx4Ui|&m|kw;-xKzxpKOm?oL3fi%$H?I6LceQ|obSfht+OP@F^XL$nW}d7({NlLt?C zr+K|3bjU2;=rykr`imizXo^2uD;j&E$Fvx%6`$-uW5oS6yh}tS$4XkWxIaH_a6*d? z+v78e7nVhhrVxLT_D>y8d>kP4w^M&)#mk{~PTcGkC}f)Q06XSRw&a zIIAnNTXK%6^B~iV%2`?5eO0*Y=_|_=r)N6hSKP*V7kwB|W&17>PhUj6G>5sqRnE`; zpB=#WoU~SKZPb`!2GiYH2B-9IL*H;^LXq9+-ULE*$g-%HAsXfhU!4!AT~52Rm%ctj zWaugzqO?@;EuBUf$f!1f_QGN*xO(HFB3z((MJKX5%0RO3AHO|BkMD-UQ3W418lmWR z&MpeKOz5IY2vAc;qlG#^2=43wwk1y7c6vy>y5>*FK z0Xu%OpGso&8m!Bw$7NnIGWlL+@E1x~$!33wx3vKkpPR0P^apiZe9ZZTuf4>3Haxgk zAXGwZ)Sq_!$xpd zDzZnbs+RtZ%s+Bt9E)?+FJ@p-j3rR?9ic9Yid9}4mbevz_=2O)lEq^Fmi)S(qBKlvl!p40Lw=I0QZXQC*IyK()S+Z(llrg#=R_rosh%>BMS==M2|6A z+*_XH`;mOwql5NjWhCogG#QGE`PIU|Y^m~OFNisUFUY+tO4Vs)0}`YkzrreS^2a4h z`6`<~Qpx9?Mo8QyD+_MW>?SZ)T}LXTyH^ZgKoJ*xDxBwdLP|Hqm5qJVjZkt91mz(r zWoi#TKml|#Civ+6NXBif@g*w@i%F2-(z0!TQ{LE93;z;gY9Ms`jr0$^9yY3NXq8g&gB1aj(NA?Q~`NmS=}*Kde!-ZkABLM%eJ>ZO33C>TTz~8RkjgVYJIj}g=&TO z!Htr`D(>BFV^jwZf$K&YKP1BkygQ5J&bTiSfEw0Yt6UlE?k1b7dIwl1h)404ro1a= z@R|;ysWD&h<`UeS`yY&dFUKLUqs(QTfEDb((7kwd=krf-YaspR>NB*UY4vNYh^2Y^wQIJLGyTOve%9pzDx6C?&TTsq|E+= z8KcL9cqOLBM1>%~d9O^3X??Sd)R7^-4$?@N%kcJr62-Q^Q6ri&*U!-$zvTJk5NM^QtQIT+OGrp&PKR(JM zyq1_{M%Qp@k`|Toh{c~ghTOHdxdAunthJj}c|f&8?9f>*ZT%96(H%eLN)`aL&;pBa zDuH(1MF85y$~Uf?S;Btd2D3$a1Aw5mmTJQ^j@uBhv}gf?q6>Q$BgfRx$Flvb__tM+LWXBf0AK_jl+3;Os>47wY*6z4g-S4b z>?wnFztd3Y(QPC#-ptfFH-wr6?Z+y4v#Q{m8N57C%{<|-(XT_eM2(P~PssS54B%oR zR)*-)3?B3;iB*_M@yeVM9P$F_B%XBqw1}Sn!dEY$+fom*v%CEtFp$Yl|97X$_une| z&dhF`4jOh_3PKwCoZs&TOjs2Xx{Yht4CXX!y!T5^D{*>nMCLYL>wTj>km_+rNYm$O zE0T`Ae)^Z^4LDb$!bq6?C|w*j{c-`ysZ6ds!&A*v(b#Xy2@4N9o1K_`X#SA=Zz-d zk(dr5l|EJfn=>^fS^$#q!q9fh)$;j+w-6H^q!QOp>798(s?C2qLtC|EE~2BM z^LK@Ub~UFHa?f1OP=1d_eapM>hlB~U%XN=vd>=BB33WogD`)}^7tc6Q(kF8?wqS+> zyPnU}DI0qgkPcRaQskku+c+W4iUSJcrdu*sjrm)p=JZB`iu#ut6B*Std}{OOth0b2 zW!@W@Qh2iGWtu|r8}JC9Ga_o=EhE$*AbcS*xqMA(xJ6Xmb7l{czXfRsLH|S=?27hA zSisy9K7_7(V)iTbqI3!HBWKaHrNil$s5@9yAYs&!fSj$m8*e8=Z60BJD>t-Lh<4^_ z){?qk2|=jC48W}5Lk&MqK}}4!j|t|-Y|;xOD!%qR z>MEaEDumRl{-`|hNZGI#>|*)Tjs)PR$KS3)228m)stnQ2f7Z~>eih}Qk+Pu)>pbf7 zoa6O+)b>sFuE2w0=D_3mg9kc%c3H+Vefzxc>tvm&#gKr7TEgp zohL8B0v_@X=Neo9*8m_s&Mv(8P@5*DLZ{ZUsVh|A#YYygu;Ew+3DqYGcz9JYrt_`~r}`8Y`d!^SEVYZ&s5= z+zbB3_sGBG01JpR-Kk3aTeaH)HbemhU#o%76X}vghzCsTA{P_b1TfUPU@&|fnaOH+ zYkcTQDO+~&&KnRL?Ubp^6#4`_=M#F5+sR?19HLa^qz6E>!n9tRUo_w z4~L8fmbX~(Z09LDa2lIB!OZ zF^Qv9%zxh^yONbt0eu+>KK>f!@n-g?_hGy7n)7;#{n}SG^GfoFCaNCM-(wr<7&?(q z&zeZy{6O$E@6|~&u!QBYI?;^I0Xo)WJ)8qCYt$Btmj^vtW5P!Vqbe?q`L!PQQnc8uo-3MxQY@yT!-q408uDU^csCs7tYDmoxYVMinvCCf#-4#~*VA%y4;c8mn!>}=8sc^R%Q1Wu)ea?V z(d%AzOjXl--3=2WG^CpjdQ_;N$5k#+Y?uPG8W>=kM97Zmr>zuzcY(?~GGvpdsC1#n z5UigKR~Qs{r!4}nj3J8Y;$oAGOEFmnmfF6iZ(~P%ZrG$&>)zUI!z3w`$GPfLBxUtj z8ru2P#OXx$i27lk8lvfKB*r<5=%ghc(2sXiKxZ2X!NH96!Mlq zx%F;odDp~)=^zcq%M!IYpoO$F+WZm`HtwnIs&?0v+vIMY4TuWSWW?sIVt(=0TGgUX zvyi@gb)=~F3507D_mc1c9L}G)rQOp!fneQlPTQIGK6S4C4b|%#d}@S4rp{IaJ4DqbGW!qcr(bv!a(x_fSZ<7S?UzCqN1m1d zW!)bpERUPxv-NarSkA->{2H;Ttf~#;c_m`@9Ldi!vt5v-Wy%`a8aLOlck)(Arc}Vu zP7{;EFA!kX2VWx4NUN(dZjak8b}!`8;Hp9|Ac`B1JtMEg{dPx<=sNkddjyl%wX)8B zK$@d_4A@V|gTKJ_O--jX+@LcV-LR2PKa}|_uPg&bb#YaZVVc%0|M1oro6H1uS@7PEZRC+4qkMJUt422D)^PI6IlOYp*|L#zd~@jhKU zxd7NdH>(NKHa{n*sYEwSXWb7Nx7|o`)L*|vAmh!^rC2V@xdn>W&P?pXw_svRmwxQ_ zECz4u1k9E(y#ihtjhZVbiBrm1Ub~Pp-O>#MwR!Gs=}Ks3lD6*+&dXdjcX>~tK3*uZCBqvG|Dd{aS2572XZrPXK&%=xmZCuNc>~;S9!`eOF zbZAY=4B|!xas^AwBjDxU3fr7{itg&Gw0ohMWx5OTLh)!Vv3jRsM@^8$N}_C2%pOpw zwpbxQ+d&#`9SMJw4%bz*>Vip1Psy_2xN{y?qIXMvO0gRwQw()^l7dLCT)1=n0`gHNvuG# zbG`{q#Mzbx4>wkDd7s{zm~N9xEc8d!E?Gd|1xBl9RqR3nDH+Dg#t?4J^1V^3h=A1C zN0v4d@ptC5SMp4N?X@lH2-pFpuY=e7P`wRx4$L2u3Io8jjXQDTa+Pcu(k=m#2k>UI zrIn!6SPEP4+4e2%mG$y`ea^G68njhU%D>%(CZ+D2av!j4-*LJ-@L~N=x!uy?;E)nCuS4KdiV)yRaOnjUSV3^i$1AwE9*dFDr$!S4J2dn)q=qY&bmxBdwaqBG z-=)|O2=npz0)F-aa`oARZl#GM_{h3HN^TGa$)rD#Kx3G4r)Ayy6&7yGpurcSyc*+%3XU>~>tBc-_* zora?^lz_%e8KjB_Ios>Eqb_dD6fMd~18bx&1$0JSZnjZ-W%EAr#^)us8&WvgVi)qV z?E+9HtHI?-!GK=YX5KV-D|eG730h-6hgb(cx{gzhd(UijWa}B8)tuBWG5QVi!z6PG zDYW=l&X9A`g^0ACX?!8{&AszGr9i&VYf)25+P-0aY<~bWbxYFSZbh9=CQm>d_aA|| z9YmqTu3ADRL+G>DDOJ1sh#O(+nk+1HhAROsHWPggKJ?8ENT5@%M2flF5W6+J-l?bx z8F!-Ne$Cy+x@tBnXauBEUWVtoQH1^m;iuwx0JdNNwA|FB(%grv>DBM>d_ujn9x@^!^lSrAJ(yPTa=kK6iLt{sy{=_t|AaKlmtp@j3lykM z6EpC-4T29!rb)9c!k1dK0PK-uVvpUp*mU0zf@#_oLA0_k}4H~HESl-0m!7w@;lMfVBmCPgDqj51UPqzik+^l0{Yqzj`y(MzItI&cbc zY4@lt&NWtYykv}9evrxvNx4=Iy`2mnw3!iEJ%+zfll)Tj+Iby7#u*j&8f-nF4dG7Y zWxMBkUGqi1HD&cQzw;%e_--5GhV@e1eBhP)NJ#|Crh!@vStVO3R%e?Ve1}bU-lFyj zK2BTUbT%{7SdXPxyPFN4#diLgIAJoC#b20IYyt;gc((Rqb&c!KIUCMl`c_LYR4SHG z%XKRoK%ci;8Ni?zvdm%a6-ypyB_2$o;BPIoCUh3DJBkxQi4hdD5V||UO2 zf{)uv+lzxyjRuv@Ay|FyTGCZN6g{^kG^Uy~NgBQgmwkD_Z0JPuXfVuWU^|uiSYL{6 zLAkpy(qdP;XJ8f>)q^Y?TWP${;6<*ntJbK6I(w|{Oax}`Wh*=7>JC*&B~PN3JSfA) zXaccOcRW1EjdPWh8V|hceD^p(iY}WMlQmkgQ$rbM#Q(5Si*s5dg)(x}`oy1p+ykm5 zD}7uLcTw+AsL$z4)ZkHuZEyf$-qUes>iawBc?n=kqFn*%6Nr%OQs^B0xdr%5SYoAa zw4KwzOkSL;j>cMNPv9*fbiW(jwCF3qNuE?+Sj$fR5m1MIv#EK(ocG-91uF4*@}~89 z1Ipc6-mHZfRM>{&(vrOl(5pT2elzC$u+8u-aGg(0AK}JFhME@G?ObY zmh~B@%*6%po7%w!H>v}`?PY&bRoj7*6YrG@!zowsV*G~O`fX;itXHDyg4mt`s1Ti- zwhiQFaT~(50|;6WDmLLhvf*0hhTKO<9CSMZ`zR9+fc!46KEkg~lCIy4-fIqcox`s~ z1~Av36E!TuN9~q=rKH9#hyn^70fajb8pL3_G~+!Rcb=IYASqQEcBb2tx^?MF*L)U-W31UZ7An9Udws!uaJ3xzl5?8y`_**y2`yr-h(G%n ztcaIiuV&9tobcxG?jG+!cRpGtdS1!<&=8$j88;W=9X$Yy;)~R%xXoeUPc%nQPLR$i zA?-#zaE8SPAP=Hg3lNc%9?a(OWB|QavoR6~)TUj~VRi&SA{Ze4dZPw4j@_eiSch5z zxYztJcMT`6)>2)Tx~OZ5MZ-(1Xw1|HflV%Y$0lG$6XJ6+^i3?GjXQTs6SLx1J}0MQ zhmDc$d0f#6fP=xFX=SbNDT9tr#&cxfmVWc+@CB8(F zBtOR7iFoG*Jkxf>ieMSk--Mxg@PJv8z;xL}Psw4#JrFgg6fbv^xImmvdnz6*%_wRx zk~@Dt7^M^4Fg_X=D>wtpV~PBa#0fqp5liUHywz)eTLdA9$% zV|=X2BHa7QWX|IoNEL$LB|=`Ge>TAeF!^Fnz|mf)fZE44qQ$dqKq?ms$OrJ0x&A_) z6&~Iaed{kN53s7Se;D^wQPF3Fe=<_BmHW!vLdE#K=jJK?N7}W z^!=d$o5Q>uSAU~Al z%+M~r8YLZ5SU1!xU0aBzR3Yfgv>SMoE_1XBU*f0d_VF9!wzbBBaK%68ICdQ>gnp)e zR|Np6x1>0_Lh9`OkPNR7+Dxr{->b4p_ZEsxY~9@z%97u0huh-05FD>K7I56hDI%Z? z?XSj18PSd=bRrvXQ1bks+0Zu()>lJmX52Z@&DMJKf&+5Ol*u3Jy4ri zN5Bg&#(AK#pE1#5H+^lT#)FfUyr0BrTX=hQgS*}~+YT660$)m+`8?p)isQfqz#ZR7 zNA;j|8KE`!0Umv3#;5y|bfJAr|M09OIuqOHfxERZ&VvdJXQ0b|ZGwS0s0XX9hy*1o z9pKH{Q`!iQXs+P)^h@n(5ah^pHB-fxryd zrBwkQJp{BmTa}J$DdFyOZtv9g1>HlhtwH`XsF-7D8;HMj+v#LXBaTY}MH~}^-PNG4 zJ}bq(s0(O;-8N5WZ4BlnyMf?Gy4OnRGk)X;JroOgk&b(2mBR{!DkoFcJ`a zJ7Cu@fJYQ2neZQhIJi~{lmPZ2iir{9E_RI!=R~B+08j$Vx#z>MGess=@-fZ~ncLj% z0Ne~|H~1h-*wJrNYTP*rdayx%E?JAS&Czk#(X-#At6SYsQ}o5O(e z487EiUZLt6`NnJ8)dN4c27V2<7Qi;nroHfh`Zq`?iJF-ST-ez$@rlDuoU%x;8goz*;~aiXF8*RNwkIG%X-RXORl_LwOqE zhs5m%H(<&P)1J=I7Xbs}CQoo-3qM;ax?to1(m{uN8qv_lg5t8=+Dr-@3vp&iERqLa zUkEz=6QdgG_9;1riV}3ZID~?iz`C#0@e?UpEh@(0@K| zbF@X@3!nefIDcf?kO_Mx*1-q2L5QVr6t_2pA<(Y5h51n z-4C@?+&pYz#T{*k*H3Nrg%GX9^kkO7cT0-dTjzYA-F&jP(p6mQ4_?aiOKB%dq%X|Ft4{3 zg8ocffG<1xD>df6I1n#_L@jiBl7l6bW=nYu1VYNNMlQI~52m$m8QMMb2KuFbSnbgk z7jXRy`HwsDh4Tiz)Kj~m+jjOn`wpItfF7E61Oe zPXE9XI$DEVBggpy`pjp1lP{Uangh{s!w(+t8i>1 z1bx=~CWt}isd5@ls?q(pxY24=!!}E*I3`_8+Y_Z)96W4?@u?uN&4`(z(XqxM@1C1Mp1;9t%CP!?Lz;0zNoK57u+70o$;S-Sldk{B zo^)Ut_6CRuF~}l%Vk)8MeE@eh1fV0^|Moa5M{m>|@^}U$0!BnjG}f->Xxq^=3a9%R zI1DTR>uiay)`4vUpOSIDUx)fc4m5u27TR?+AWQ_sx?BL_Lh&C(c;uZvjV>Q68qleeHLCozr zu#kjpnb^wV#EvE>XbIv~$QDP!1? z&}x~#z|xagn-SMD7}uTG_ABta4Nf+}s)qQU#Ymw$`D_>7fuW4^96mGvMBcC27@a+( zz0wTb=iUX-R2<4M{sk_dCeykKmlg1(WLCV$u#A3z3)oIEr`llx?HfIDdUd?>5qMY! zAZbyOIQ2Q}_W>kO)&Kw->qqzW*>L`ZE9hrr|#*1NtL7+8kri*Wra**y?3?e&@ZkAu|5|8DTaXx9O;q!qk5j&dkGB z(g)M4iJMNb(j#-TZBg(csTWc_OP7Crj@J^rKda217+2#zWML7#^X<;3;WbX$V}W3$ zEEWfC@0*-GX)r0Wv+X^Z`i;-OE;M%5S6>ol{ZO;uO)1nY!jOygJxX7d&8s5zcI3+* zA~Mxb|C|{4mXl=M9o}kxIh<#tm(s-y`MZ-r))?8;m@29{!epZGs-cAZvxd633&|sR zx~HaXAN*z&zx9Fkm2n8=$|pkS9*mCxBW=ZKSNY75>l4w%S46J{CFtErygY>LUuA_< zh4WWDMJXtaNgvtcnr5y`K zEk#2AF?bxc0yrf>%@PBM7ua29RTI70!hH1}P#2?!4N?2ZFGE!nx$Sn0K`DGFuM4?z zuSQ?+t5y>m;w}t)i&jneTn;fe!O`JF4P1?t_~x*0Vu4EG5GF~TQP}z81A4WY0oOUj zT~Wd$mvhs4f|}7O#RfA%5a|`q`XnZcm9sQ$G8gN7oXFr|Ju&j794^da#n-95Q5a5m zUQ#sVZ7p9PS$-FvKBBODwaazxy^FeQoIw+-F#SFJaV^*-3&(W-?lEPGpb?{Gled1_Y*)34Zx=?c@SIURQCa#4HVrm_>GgJy*J81j^8SkD03 zm`eD`f$&UGk*Ah5?fUIBH8Xm(?i( zV=ODMH5#eh$qtYiJ_Eld{cUIPt6^Qe7SV zxU3lodgeOz!pPe|kVGp)zYD>EKb^<#EhrO#+ZjgPayw%0@Wx~lZ_A+~yGE^6R|~!p z$sRdNJ!3(VHEZI7^H4p9fdLWE>NLdc}oYDditIl z$L(aQAtFq5H*7({4|y9K$JF=}D-%L#=dcZ@zdsZ;of+9ATjFnZ$K zBW!lP6o%_pbEpsAeNb>%)?38Xnz=*|qSZU>F13aW%Xk&b>^~*Phi3h*30EU88p6;& zkj1*&2&I$4KD-WWi_jux)6&pz6dRCA)F%v7H)`t%d#=?)HI$JLpN80x2-}7QlLYQ@ z2j2?89D#hEp3|=Q!G31CDWl-~)K&s<$1+<2%+Thp50)bbz1+a#f26qpGNaTdm)e zc1L83I%S550*lP9Kp;|wGN2EmPpGNa;yh#)ZTQG&%ydFc6lOM^(qHLY$;Q?-Cuha%?t)f1dtb58lR@7?ayjwF)**>uM#?%RtSp9YsD9 z_J6m6Mw`9?FHu9!1mN@$viK%spt#fsjxe`dcVv_ zQBwPgS;lj-fw$?r9c+9HZQS{rQmt=@1>+U)8W`?Z&`60@*!8%|I6L5@+MUy1(La`r zz1jfA3F+l}=}#MIg>RA@rdwj9_^X>S@mcQECir+|Jx+-Whb!#%waO$CNh%}SphptD zl`|iuj4f6(%Q}eP#VO#u!ZviHTnK1%8ksu{<;qZ0 z#Y%6T#~Tio`f%-Ty-Ge;nWG}3DM>OG_OH$9;_(>};tED>eT;fTme9m|;_ETV&Ma@X zh(-Sh3)5}1bib+%ki}k|d|z1TD+%yoV0nq-cc0n7#kAyUw+*n7M0Pp?-VIc5h`oX7 zh@J3WyH7H{`p(`|hi^t>WUOxRRXxT~AapE}SRNtL;=}@~h{WSy1;p2j?bsIC;k8$@ODuHL(3^q$sV11r?ZpCaCMh-}o5eyi7F#iPfj=H9oq8KNx zj>3e^gFzzN^N*#|oSf2j7@m7M!zmmGdG1nRKPdX)Wr=@M>bkH{B?1T`^~D}L|RTc4j$V~(mMvU)K|@WnhGAR+AH{1<^Vh>3##jBqSz{sPr5eh7`sIar6{H*=*=P*IUU03x4rD0b~-!O`9%2X*W+*9v z!gdvA|8Y$fS$tLgQeeH8pJP<{(HXao3t@V9&;U{LbkuZH#E=A=9SbvKiVH(eX2F#e zOOtr#8jm@}$+5AKWAdaB^`L3NbU;R)>za>e9aZCqPP)Rx)i=Y`-l^Ad7+@Go)j&ok zktpyUY>=0&Ps=dD!FL84shcMJ*7*TIq28_YNBBrJfVFi?Phg4N^L&)vU=OHK>1dZ$ zZc#D<4$wDUyoiBT;Ju>xEBKK;?~XUH9JcZk9vbT0a~Mbs&Z_l%VB+}%(2{^#+xZbe z#afYluO=%oPRmD>_1>&*zq+E;(fpPSwquuJ&k>`=M623R=sN_YHn@xs8SeQPniMIdGrlzS}x;jp2|In@!`dcxQu)x1S)h0)~(2EnsZSq_G&V z*z7AAN3aOJmaKYcwv0?KU&Tzo>eN>MUYQnL{?3BwzYb{VZ_|-S+)>Q!O(4BR0WKTx zRrj_>3qzy@bg3U-3Hl54hmM&+^g`opAJ}Fgg-vmmqES(fF<&%5Gfuhp{NN$fRCH1g z>Tyf@(hP2-&rZ{)zZ(psJ~RjIN-Hrqmi7*eay#-Hux%ISUnG88`?<97Zv`Xf>c?g_ zqVu=zO_c?A*7X5+n)EOK1SS%}OYO$}QB#ts1!+-nv$L96=t)&^Jdj9Q$)2DYscKBD z;*m_EQ(|@sG_gI{oGC# zfB*(Vie@3br!VaaC#hNg8N(egveLH6!HcRdhpMGBh70_~`wBQvE6C7W;(fR+l;o{0 zX%>OJdvi;jwC_M~fO0I9=gV9vA0fj^b_h?i{lKzC3m4$bs!X#Sk;>f!rKguxyz&*G zhNAe_)JxnH^7?25P4^OgEMw*-w75bm$pI2hICx9(O@}0vfxH@mE2tb#)BNPh=f%@J zI2tve^x_XAY=_dOrP8{;z`!JuOrF+2>`P*e=vQ4ERvBeYX)FUFELo2kyA-3GmA zSreS$6&Jl*b->m&g4;4|iugr=5bBC0sG&q09Le2^ZDIE|DVI9MJx@j>0w{k(t9$q1u`xh zJj7GWuHYmp#rxkOltNsW3nuhpW*}@F+(gVFGgyk~bNrRTgx2+~RFbxj@vi}&NQB0f z9XmajNP8PZsYpS~%e&(+53tjpg!#)?*+Q)bPWj4`{v@)K!L&q*UAPfX2Y z(3o3h9R5w4O~{2Hp8Ke5nD_EC(P!j(jC!L02SlnNzNGtm*FPg700I_=N5cc>3Ju!grKmh`dGV4#oPfd;xqMxeZUXX_~< zJ8+f_6#M3~{s(v-fODp|J`%|%Cpf8|Y|y~=K8Ko#tJB^v-CPVhi*O{9OP*u2z4 z3|L<`;t&>GksF||n9Cv-ka5FQn*(%qD{ecCr6};%01^x(KxqVJ+hFu%4|6vOClq-3 z67X~fziLY!63NT;zn;#_f6bP|eU%#rxMxm~jqq=iTOJ&wC3SE2t?5baAoLB$mJL1N zsj;~c|IuKh5oN48ozTU>=6w25GptD%XiK!rj%-O1kAhr(J);A7*ZZ>7X(V87je!Ej zOdu>@pHyVRD8}qG;E4fu7ApB1oVhUTw4_M=Y;-LM*&?bJ<@Nr)yZ#Qz!Wsfz6j2l93W?M)57z9ZVg?idFtNtd$L= zx4y#JX18MPIjt~4=Xj$9V|q&i#bSaSN|RSap#ij3L+Df*a*;aviXvt}Mrz(QB<*H* zjj%nJ-CLUMZ)RDfr4nMd8VMsPdk(C*YG}yR?j`bWr_iormpg;k_W6+cqMHC}RyG5n zr=V+qk^z{sXcCl(b+*DmlaRqn>p`~*8x)*3<{!u2wU4^p5r-*zE_{T zL3W%K5XkC;O7V7s1pz$344{=a54>s#;2+Atab{rxWVuviN#9_>s19eVdyv0UFah{} zPk0)K`Irl6hmg07d@&x4(2F)@ljk$H36XDJ3Ae#vIwLIimtWaweLdH~n4mn6qKxBxYzyBCd-L;o}3K~sIETM6hI1oO+QAb9|AclXR z7vNO7oqCd_1qIJ;#7{79wV$(TU|7Ed10L$&>E8busOVwn{d_im`R1HV8{q~>>9M}~ zDW(?ar)GLPq@<1u!1YLw65mK?+GN1a=I5LV^nW%>cmsOFm|NyeX)YeJJk%XLe~kn-gNpS5V(XiX}|!u24zjJ zli?5B2XOs-V6|LREe>c;YFhv8BBdM{*!*Ct?SPfj`BgZe1MFO^oCRA%9ho5*Qd4D#T>6K+2WVg5N^j*C`}<^Bj-&>+9uKYqqEifVC;IyS$=;dz-I2WwT9)NBm+CB#L4vhJh-*m%kX9!kGDZt-1E!@JPnZnS}v z*{r-lUlgAbMaQXva-OoIOh-@T~tQi`?&o#S{Rh2&cEUu&@Th9CVS3 zq)5_JStb^jG)gc%AD^W^*4`2VC}ZRFO`l6z!w*TY@xdk!?RumEv>ihrTZZ9(`1m5( zzo^+!(+3RrSlCBe=2*ZDnACEYi=we)ZaagAc*e$|?kbO*f z@}kKr)FGeRF~E?^(a~)5Utw{H(JolA+q&-^lJl+#dC#xV2|*w(qb8ZgEfW`Y;71V? z@1UQ%92b)giCz!q-@NqfE?M065415V_KwZ3_wSE@YAgx2Lhv?33&JP`O2(ztG2tZ} zHpOE#TO&r{CetXqgxDKLoi^= zvwTluOL8%*bX_LgkRxT*!yWpPdL=oqN$zMt;@i&^0FF)O9**6m7je6TQqtyN1#gpV zLdq@=KqjT_RE+)Zb}0eU8;&7(@AbSq#UPd9&u#ylk6S`uq$JA}b=g5w4=~!BcU37j91bdPNn`wkKL_IQxqrbqFn0%MM##i6;3)*_TVA8|#@J>jlEV#)=GKAmqh@uqf{lC%p%FGISF@Q1A5q8vT76%l$-$tJY^*B%T0L`UaRu)$wmDInx zpmM}?Ytb$~gjYlB6$rajs|!7a#4k1}v^&$VnnG4E4OsHT9|ChqirD-Qo*<9}Wy|0p z-riS$CKL)ID;OUzy+MUOLQ^0PRKdn+WwH}^!RvO3!L5PtCSw1%6~dcBUliW!_r0Ej zYEHX`Wd7q**(^C;|JODB%Z#?hJwU?<=_`-h5F!ASHXZ0JRcgo?OCVYR9pT|Dw8m_3 zv6o&yLbDv?Mm+VGsez3%j>0E_PDJcu584_QOIUs}15imQ0S_1hKnE!jf7oJKg#pNA z%!_1=RDRPKqz0HDxne*=SndxZFa^003|{i)&j6;P>2O;^~7LObhG)WCcg_ z)(3i`f*nv)R2krxKoI!f9|C6Q7&e5#06r|g{`Hh2hGOwI>*NAOo#8Rq#8bwvbG$5Z zaWOY@N6i(~3Y{ztx)9o_aBto`ffyjqF)7_8C}H)!Qm0Ctu-&WYm2}V$m6?w0o=8`aPom;5f#~-w{-{C%FJp!+A&%2h^y?3*fwi;^1K3L^a@=iLLaoD43;Qk5F{7s!Bs6Hp~pR%C4RMn!#u#nP^S zWv3^S3cUu_HsSt!8#wb`$+y5XdeI|<8pmrH07FQ)Dsa{m+bI#8s!a$MJe(4_us7c( z1tz(?XktaeyTs?Bz2{S|G(dnAp#~$<(E>dddLf>_hbqrF))^%#PaG7-KD|iU4*Fg8l+0qHD?Qp)ks6ZOu3y4EPgo zZxqlLh?!YH#X)ig6?81gR!IWX5G}G(xDg!z%dSfYwxmE60AZYNIOta3CXyf*4!Whw zBM0ALI9v68K|@8e|Co_1Vf2*Z>ka${2Zm@#Fpn;M1m}D}k1fUk_SS6SQ_`dLgI}@U;DE zP+_|W?EZrf7hj>j^LTKM9OwKVO7)Qe5{sn0=`9_wZppCFj+{=26g$!aa?m~@BaT_h zILQkN$x)KLEMuEuDOU?Qe0!Ic1`bRMWgGd*8_!c0rw&MQ*IV$SZ_Be% z)#9NV>n^GP&ucTHL3ylUnP+xzM$MDkT&G5&JQY0X8pCEvi zjdf#J(}zA6E=I&5!IzJLRF7&PfA&2Ks0 zPvoVA1aDw=!X$Y}qpk%YDMl#f@f~x6;s6U=!X6XB)dSeVGX%&1V zt^|0Rpcx?543rNfECY!Vns>+$XE2oIp5*ns&Zt z_45s8J!Y4An!l9~0634#1i8VQxPk}>@a0z)jX*g(`80P4#Xw?6T@is!n?=)Aad2wh zn2XT@rId0c04rJU%42AN%cDqLDTt%jzQ6>_Kg>uX?tqyN_-EDY}$Ky481jM=s z^R}Z<$dfsg%otd|0U)3dk;JFp4Q%?rsmMk^!#;eD+mM4WAvDZC<3B!Lp+-ggkgCpH zh2Wu04YpG$sym=UmjdV?A6btKjG5BhjyT$(#HOuYw05wg^9%=iy{tzhfs^D25 z*a49Ddsm2Ux+Md#$eyqYS%5k6iVK(BYfx2NQb(&2HbnLGPLg*8>nk?KUKouGo~~pH zw`XrxvQ{Dek;1KBo;>p7G)i!_;NUQlloEzl>hYTO__%Idb^Kn+HQJI(&vkOw@guNu z%9elzpw^F>uYU{jk`z@j3;+i?`Cgu?@xZgzt9Jp-6>}*vH6oT{>N(h@4Xip7CE$mF zx`q5OSvjg^K?BL^AnOF-Z1KmlO)KGBlrK~7yj*{&lWPb}?srAHx1muSV@3{U4ZZbO z-2v8HCVHN|?Pw4K1&H6%l9|^8=c6@*TSk;40Cp69b1N2^^$@;{mE%QAm{n7kI2+!S zqmzUDt)q@9^C0^>+8N+mCM7DxUNZP?-CoJ|NLj88-ce57NreJ}ht#`_Kg@=}DWgcc zbqY;^Lrb@#1|*zN8Oq|om$i3L6fFsZa&(43x58ks<)oh(*6GItNdO=>$|x5*9j7f- zyqjg~$jUl(R6Sdp8f!IG(kXkmQqz=^xkY(TO-<6wJ{$HF)lFbCtbW7E{j#*?TCwNa z0Xw=6My*7Gy|if6W4y=0&o6@In*-$48y_Q*QE2N;#jlzmh{B*SB+o|+M{=2-2cz99 zz9O`_7|&8811yXPv;5_go56sfFB}3<93E20)dqno0^F8jHh;?s_~MpumpRb$q-%vO z!TP*m?$xo|6A(Xyr7|)bgM|%CC4gJ4)4QS7Jh5oku{z}ybfyG<&2s$batZ*9naS4# zh#9quEG02IHEu)rFSz6$U>f>dK*)fe9dCbLiX;qROs05%F+Y4JLoZ9LXzw1|{m1*YyRmWBSuIORrKr)HubJ@=t8af-ihmj}9 z!}4`#e08~UER)g}|K}C}q_8q6MHc|T+8szT*5l(~Q2`j7uYA6G)Daa+Mwht(2v%Vj|+|1E=odG@vQn`P8cxZagIBJGNYB@>nUqW>m zQ3+#aEH#CkYWfmWwcPd2D8l~~y8=v_j2l(fB1O%32x9%ftN*PzyP&O}V5Fpv8u~poR$HD(H^D zVDpFrlzcXl@Ga&GmK!(+G;`horNd=0C z@1HaIl$f_D)Cl63UeFNKbfKAyalYoFeV5mntXReS>3@nUfD#b^h z&@=Osf-qoWIQkl{Rhgr(1>uRkDLHTfz~*`dDWCdxl1!1?LcvCK>vS_%E+8?6N}#U< z0dNZLAH&=;YyhK)nl3oGe+VRdRA73ZAfM^Kl?SmPkWhrs_Qz)+aY^qvoC6zzv}pSZ zpd_d<{z>~x@0AKTII^t|5MFQ`a5HvcR&Wj*MiXQly>c9Mc1kI@;K>hSFoPWcfhi{m zTB+H}ipPxO6X*mm+2LmF*ceHt3eN!=fc|-dUy}-`QTf(M<~n&RTCNKs~xl zXV_*+Kae&|?P^cm9)YxmplsSv+7W<-v*6GpQkvjC|8siZ7R$e96M)r_*+TP_A?uKK_aB=7w>tq}P^{QZau5xHDS$(u z9F@9(2=ryTOz*LI@4ChSkUt>IN~^b&9F++75Bg$-P<(=Z4M_fh`^So1q4OC@rZX@u zLuqN@1)Qdy;9DDtn|)N&Z}-_ip+WIM0d63{Bo9j=-u}n(frpRUu?LbH>hbs^6^EFH zBE!LgXqKXtq%C2f-=M#~R|nq?ffA_z=lS*tv))04X@Qptg3bU$H4PA!+W}D^Cqf0p zXZ9sY{Jg0lE3tx${ZpyTdBWY31~nFEDB1PaVZ`D-)v*ic)||Jxp&|< zAPT(IeFyHCNF8Z~O$DO@PTVIq%X=c`m8WMfb9D{h=WjDhaSR8%uA~ zTi_mRq{eN1frDf(Iyg?<928Chy-{>2!7-AHSKYgGC9ws~R<&%efcQ?MN8$gEjq|JG zXg+WwCgr<(@kk6P+T*EQ{)>K;2uMX)?vRso=1R;VRW5!EnhE$(n&sH#Y&y*o&Oj+! zLJ7nOQZSegLD8xvhFjdpOHi(dtRy+W2U>kVGv4WLUI$19a+nwRfNmB4*@)p4^HncU z%|HeMP0m4e?*M3=Kx%XYidGyM^;^8(;FmH5IpEfx4@<5*M_TY{G}dNS*ng+(+Dg5u z$0h`}XAfk12I;D49X|t6RL81B-e-B4?2s`DoHuu-_aGcg4qOi^9_ZqR1%YDa1S@-W zB#K6KyYw^L3jINX6ofZJW4)2_8>z07;PJCjd7Qn^YTpl^fpM;_1HyRI9+q_yII0)` zu6g7pytIMn6}V?o{}nk#=)-E%p`_i3LP8RV-R-Dh0i&2JnF$(WtqSskl=)7_&v06w zpn4x`#C?i2yN^m{s)7xHALv!pu6YPmWI+ei0mKAgP_Yrdb0ofDRN#oq-$>p>y5&8E zvoVhg6eoHpCI=Sx^%*T0@4Iv$Dgf2!C1z7Ar+w^BhH?3IG{y= zx|F`n%XEf>m9Imw8QkZfkE*|codQ4=9L|@A07n73r8hXqw?cP9A&ex6Okt<{6CXE_ zTI5(pouR9r*B1aq$Q|eB4Xk+HQAFatOYcGE1sSIkF|&3ckW0w>VE+bxf!PY2rj<9Y zz5L*=5tRyWdp=cQg1fF%WBe9OcH;{8zs3bS4N4$82Z$MGjT;EaN&%$eRQeKM&^*N@ zMv%{dq_-56oM^+gsawj%SS67hsTkD@Jw36T3m8yj0U$UB!UB)YKmbo_$L6*+?$V+G z4+z@;b;JfYko_N;r%Ogz51~|+c|!zC5l}~X+OV~;V+!nI!qe6+b(%qPjTQY;b18q-0EK4B=4{|Ko zr0g7>M*0o*-3F(KcmH|JXFLRrE^H<`yFt|r5J`f#hFQC^&26;#*8lRdATtA;g90Um z@9=(TC$$Et=RtGiGrb`jNRs9+G0s1}$UV)kuqRX^xEUf)q!n1u*67k?FtV8!!ASuj z^FIq3njwVcbF3)QfAYT>@_~JB3j}Z#T)Ey9kV=4oYjd<9>0Z0XOK7(?7-I+7Ag zBZloaq!uiUsy>8S=QJ`$1mC-@74Erv(WCJ%{DH3oCCfJ;pZrFuMVLi|5A=L zuXzk!sZ9vsKBFjfV5E;*IHim9zf!mwV=$NaBddf{S7B<>2G}i1Ax6KaRpzx*FsKB8l5o+^bX^$b{k2pqX~F+x3QAsq!+n7;l+MKt9EXK)?c$ z;kU|w?S+BcLYrJ58lvDp>?O;(1)2Ciz~S+IWKZ)@*CYqF$W|VRX+C2X`%iR?2HMYm z5EB<#r9j`7SJ#C6E)ep(@w+A=EfK2S5Uh1@r`1v-6@a0VD)awE7`dg;ftggmheJmWz)dZ*M*8r;rSd?3k8(DC~hD z`kNM(Lmoqwy+~`-5aKaM2EZG`*&RK?G0e{wn2zSQ@kVV%y;?P+*b#`S*eke}C8M!1|W=XK`a^OL!by_u`n zhSK@^i*w7`i$4={h2<(4HZ9lt_9}!uzZY5>uKH?v3K#q?dbS073jem$ATQIluRhfH z)*k)c&FC>S^z#-q_&ZxFu4DMu>z;9Mtt@E85e`zSXU_mJ|elf`?f)~C#)$Z)>pI{38+{^-zl z^rVE!Z^UqbgxKca_45{l?pag#rT^}!Ue04m#N!D#;R%_^DSG5=U-lq2gWP1MU zX|!CP4cH?Zi0Co`#E&&Is@9)u3UAxR`C3fqoNK9Vo|cc5lWEXYvZ(frXUue2r}jjz zIx}<_6bK)k&`DHBU%nLga5tWQnD_h?RqJ^HTUp32;WCwwM|bR(<|3m9yywq1Pc-%4 zl1|Ixj1E}lk9z~lkKs9Agdm20YxZI9TguM)?TpQTM)w2U&P{FKMGIbg=)GYxh*kL{ z9vdxB8Bx%*tkRnkwQQZLct9E}6!v6BoZplN-uiT8C6l0aKQEKzLk>&BxOJ-Ak;IB< zG2)YV%jkKaM-;J9hFPyGUu7GoN*= zP`7wEJJ;Zwo_)R)vsF5^B29hhaxSG{Gh;tLoNS{fF%8pbpnPhRnsNCE)o4FRfAw=$ zdO+!bT6I)ey#9d;{A<^aY}(cJzIod4ebp)SR$0Z__vYs&*DvgCav0GL)(MVqen)BX z$iML|QMp0Vms(yYZxe>?4CdmF=g*etv)_to514*d#Lf5Cv-pzz+D%MvAY#9z$0#Q6 zs`9B;wt?3?>os+B)YWlu^U{*8)P=g1DV+)I8?{Th!_5Z+)7Vq__Vn z>BV=aYHUbYc{8Wa*ZWbGJR^_bN@pX)8STiBDx!4BlGmDEyw|g$DyoiI!E^EPa){+k z&yq_fJBO2Abb-At^+K$nz{1~lanq?d{k@#0cXlI$-vf%W|So7{7^$Fg9hqCot z4XF|3xs`9Nk6$*br7>j?cgC)Igjtn*=C7xc#AIfnpVIGc!}j4SjXx2Qf=X$lC+jB5 z)f3|SrmO43N?YCS54=63%yxcHBi<+{#3cq;)V|$Xc97s4R5HA-(zEvkfq~cKm@Jcd z@_boG$}c8jHPVUF8?V-Lwz*SKrR}XGR4P|%J>L$f+%y*?a=VSKM;sz3xXX@uR4%*) zi77)wh8|EJ6Qqc@82s)eI9#pdz3@4I!SaOd&$xomB$*iP)p>Dz%Ff2yLz^$vbDYyS zPucBAKRml^TR0;9=JY_tFGMF(g4pPa{UXwAZi8P>lkd#-#Pw9hnY+OGo9Qrrx?O4Db7&yhX+c>y)_AZotn+H z(PP}~W<$D1Tt9Zyw@ZIqbuRTLm#nljO;}k|hJPnKS_mJQ8Gde_O9lQ_L%;3;_n9pd zatXUMm4Y`V`~Kz6bg}$z?c5)COnd+3=d|2v9r-g)bdEO;_QaK`c;>lS08>MxXqt^* zxu`%Y%iYt5oUasTxI(#&2cK;#;czpgjJ`FaY{or?nbAK}T@ybua68!MD|gh(Z(8J3 zDX=s@#bAoU#|3Zcri+zX_ut}4 z_fGx3U*}#AV5?1Ld_1I2FNFB>4)#VrSKkr;*8gH<$e@KqkXFSJr}n|^WE$C-&HAa- z`B_O-kUGqcNMc>So)3qe=xguW=#E)^V+d-Fu) z#qZn;sy$)D61yiMW3$cWxODmYInI@KKGe(-v%jAW)6&%Soy_}x^gLxhmO7kl<*%Gs z7_v@SICWBh%Zdu@+)Z3xJ~?h0@EclN-L@FLL*RB+QNfWn*dBi1^E;I*-!dY!!>57Z z{F58Z7c)$>XvbDOXd${#GJ&(YV)B7VMOg1%kNuAAx7d|+3r}Am*(JHWsRJjG2!kIi zwafw}0_^5FQ=1|NpThZnf6!SFnGSrgt?l!-p2m5pNvJ#CdebaU#g#~4!*><&tMQxp z#gC!dMKxPDt@ZTVhev}SaQa1+sB7q0TO)B+_^S9;I`#DeG*390Lj&0s%@|Hkcd#|m z?bV2W3wckf{xiPZa-G8=LD$;EL|dDBaB#&o7$Zohdbav!X|1WR`gh){`JvR}(q7ZJ zIQo{4o1gQG&IU1&`5lbEY0ANdvc?-hE4AZi?9U=+?3U{tJ0=GStA<0JRhqai6nBrZ z%4CH^gPzfdPfED+SRTH0lh}KtJ78>*Wp?SoJ=;sw{a|+u$JDA+ljYNszl=}bF3np+ zos4L&xwtRq>YZtD0+^5i*b^EPEF7hxV(ntiK9(Jy+& zvoI8ZWJ-PSbc)NqTiK!&{Z#0w@$guUXvf2-%#tFdY_*7V{v#W437Yvm9=^pW@g5&F zWrE$tuZUSD-=JJCz7UNg`S|p4N_axE8U2IxC_O1OE zGYPR-y4;K7x#p3`g;Z1^5l&U?(72*Hna=Tpwtlq_lM|v=zhmBjLJ>}UFp(ZbKR>~U02j1 zBxj@FDv9P~yz_r?*^gwph&3e_8l=9BH=vRJU1GXXM?5T3zCIu> zdpe`r6|3FkLm`z^#OFvU!Hpuff5!>>jBK^mytUk7da-{LWZ+lY7d3}w{~gf!LvJ%H zyTFg7{q<1Ol7gn8R_C+jEAI#C@l^Q|CE^WIDa&Y2{xk#MYRRJT+pZwOd#Im(hhtWnT8+rVKmug=!C~x+d+?@jhN%pGM3L^7 zr){!@Uq0DR1*-IveI3A+nIH;R&NIG}2=PUqzpNED+541S-t%Cf$i-YLaA3!&!@GJ! z>1sJT<3hC_cR`>{vnH=EHgE0TKxO@l>5~(4fzSI3KS~R?v+h|HFO3>0Byv^++9@Q_Wku_jXSpWNH$e8V~A^u8Vi6Hx* z>__XOl%q4dMP_Li>zkw39tIn-l(uv0JIqplHhNnTSD^u;8h_q5wzmYIAM4UHMQ8Q9 z{M%exd?okj@Il+yh{I{DE~c=2&D?FV?bD23_UU$t8FzTq|4ch!$N7AH%{=y#L2HJ#{wplsa5BZrbcw{=j}hM?t#sG=uhJv2)F#{KW*C2#?=cDX z-l_lR&AX+u)(dg&%MPABS_0d#la)XFdvLNEuZw2@i8t0hT|@yGI7(pIZ7&v ze6fsc-CZp|+I0zHo3GonudH!~1n= z`3v^3mY^{)>8G@nk!q$nleom5@q?Pl)Y6F@8kIPQHKw zmxL|nmFc}^SNo-JwJ&^gw^_Vj$d3;2f5krE8+fpic(x)~?8^{|Z|z;HbcGZChX7A< zcH0o<_MnGzzp%Ic#H3ItR6!%vpvWN2vB#HO)TCXz<~Y>QOet}JozAA*WTJvJk(%qs zjyfLbh~aZ=!ppC2hx@YB?zmij@nN6UI(08g{#11>icix>@Gylc;HQkcTVdis*;yvX zqWb0mzm6xxVwKQ*&p(4#)43$**w(#`>Zi#EpB+rRW4o9C%o_STLgab+@F`x7)7{SxD?v# z%_Ul|Z4j&AF+B36scc(R;L29&TfjH?9m^f%-8mO6-Enuy^33Q!B|own<;a;LG@a8g zvMI70a-k`Y8at?oEb$eiD4YIEcy}r9{SLolSe)UJ<})mEf&`l45UO+HW=zc}sPCa5niWjo+I5W8ea z!n7kAcW4)4Alf~?_rz!LyM*BQvTZ;rr)@Rm^>L!~RX(L#h_(0!iTUXuZ8?!?>_NfN zwx!q0d3>U@1icm$LQ?aQoZ|a+f{yyi3jz+-s(ml3 zISb3uMr%4BCG1Vjb}uWoRS!9-8ad*n;eKfS`-V@AtIN_@-RHj6smIm;JEu=WKY`Oi z_rN6lFTXE0Uy1MWQto+u`@Hs=OYoCe;>P;H+T=pWD31on4gDj zEwyAm|FHZX8H_MFT5Zc18fxk!(PzuER=(Qw5^Tv-FYj0!ob8o$@mbL8)eZ_f%h{|a z^xBr;_~tq0F4nmVKNe5hs&Kh5e$Cq0P|M2N5_L4Hl;LBdk(dqhNyB(ySB&o{od|&VtY#LTKP;Yn=)*J^O_UEPe;gZqWja~XJzAkmC-vs z4`d5*PEfwI`1vGHXh0}Mryyu5XfdnMWj3SU?Wh!^x49{^q9@blp9vY<1AMBNrcJ-DQ}fva;7<_{V>YR*Zg) zZp^Vhy*7$C6IfcVwSf=S^0SQ+c?pdf{m~pVUd0PIjk^-4zO_L7!ofjYZO6;kZ??FbVP>(JBkE4SS#}m6(SBLwv>ESN}{ZeZ;G@oC5 zRm=Bwb>EY|JI!odlbF)?wWq(LAwo3qd(=Z(Qnu?Uc&_t@8pA1=G&a`p3&P)Wt|He# z4X0XMb|Zq~QND{Qr>z^rhoVP)*Nfo){Jr>AV3g;e^C4yA>!)SAwXoj74m{@3Q#-1H z7Wb!mHwaLU7iy-?XZ@1_2(OFov#urMG0FEUw1wZ%BVL*dD-0+< zIz7GkNv2@!%$=rt%P6CsKUY8hJr@#}Yqh+u|59IsCr>- z@4sKD3>e>^9EToIlZK0rd>T_0FH^~h7Hgur-`f29iD;9axz>KWzH+!+zC<5CXMnz* zfquDq<+ip7A_K>gE5NPPk5a3zmo#T!!zv*MYj<6f#W*Wr;x(~AS`8n}i5O@!M9#_eXt)`C@9;R$%|_8s zQ+8%JdldK#TWfoHwX%pE@9}S%lB9V|El44sZApI!<~vlfkT4|hc8oQkxT<<8anxa7 zd>o$iTU1#4L4we88c#l<1tkzcs=|M=*9uhDSnmIcST}bC?Pa8+})HwP!qEm-l&>W!sCHhVRX{ z?&o@kIS$l`qw?1Ccb@9QL?tE|oA;fX(DMYL&AUfZLVtTPu=b2r2GFFxrZiSoJ++_5 zKUurr$J`9lZ8i*=b{rJqj45!Jyhqipm>bSM4R7&HKK|M8iwEVCWLx=dbI3TeJWsq~ zd2`%Sg4H79t2mR3PD_Np`@WyapJ}7nqup&%50fgb!ws))V$)hkG z9e!i)wDfzYbu9BguCn!eGUhQWAKoIupgH~#^pF|+H>NB^|1^*e(UxlzZ*;gfr#+;k z-v1sIUTZs8^M22UbV%7CIn?p>DsxZZ{%GDnuaeUE>FmYl>z@jn{`Wr&V|wai47N-% zQ%5=pt79UF+~EHXp)ab?Yu`dk3D*3#hI%%H4#;Q`MCN2Z5rlc0eJu?>@4YU~%Q79$ z(jyaXa32s&gk5^JDIVp8r*`QMO}`tR7Z*67*uPqtw$`KOYgWs;KHYfLpu(Ry-&`it zGUF-K8B!cRx!Gm3EmvRiJNI7^qdCt`=KGfqcI`$?demRpGh&+~u14I|8k6P^?Z*|l z#D)`?0t#_=>RdF0BOE73^sc3}YccEbm4z3iwzq@eAJd=F)a3pZ)gFDk zRU}*yi*q6ntC*Z2W9(*La~OP_tv6WnNkyOa1+#S5Z2_U)BDqVO?aZfP&Qo2sChp^l z75C_6CC^DMK3&VwvR|S%F#CIR8u9-otkTo2xUL5@cB@}uV@_J z`?UI+HtM1K-Qw+1M@g7wB#|`!x@@6@7dNf0m8%4yX$aM!CX1->gQfi=DRC>xy%9FU zFb@`5vx`6tu?mgUCi*?K`zH<&6++_k&YR2e8LZYbySsz5VKSnyN7E_pf!;e(qT3{m zKdz*=w%CvD-k^KzPCHa<#3+fPbX|XTOrKXZZur#WaOII6{5)dprB*6(@Y-Jt4EMrp z;r3D94No1%?I2oDARmf*-4K=__OT8(!8@7rWu8F2eVL(bmQl@fn;q@6#*qkH+O4~v zdTEz^_#eCYUv?ZOX5i2D)~vQvmUy^Ogtg4+rn}=GdNVe@>WR__Gd|s8z33lJrV!i7%R_vc+2R7lVP>sC20ecxy{OF2HodLKRw&z^4 zK&SDN|CrIhcy zhe;fDDo37yoR>@WmOw=fHFmNDBN{$PvFI>LnE&d@Pfx$xF61}bJ|Aeb)KxO`r9!h_ z%E`d0vwGGR&F=poC-djq=UNI-nBTQGOzz9K2}6lk&h!YIt|9skeq}FkZBdWwFKlc% z=J!)JQSbCWeex?}ZPbU7I*7<}c3|%9vUVa2-~4bR`~hY~O<8W#rbVcGl2!aXhAGPM z0Y{qYer@~cE649aatoAjq7%WZtHbYS4BabFuj)#!BJ+Q4g7Q`@HC4RkZ2pnB^^?xd zZpl)luyj-V0fnaJyrih`)9Sz~&K6AI4aFNX!!s zx^a*_TE+-W@FLU(PxpTzKcY{))>f_K_lg2NK zKjDn0T3_vt71?>{@e)bFdFGDYA>odk)3^~%Se(LT@y+1PeLm_ZB>1bwQyd>&id0ZsI?qE&; zF$aHiHzRZ?)ee{x=q1peyFV&T;(t<_H*t~(~-eg(N@`nA2UPA`qEwa9`i)&mIluAl6VOGFO6H4~jN zaZ63hzv$3=GnHGzuYrpC{<`%Gd_NV>4 z&ePFTZ@x{Jlvyx4^&z#PO!IWgrw>cNM1&(N>nL}Pw0v%v9Ad!;Rf7w+?_%1gQ|x`3 z8as{pamu;#Yj#=5VvDVIO;^C_%WywO|vJ0JB?ef z<@5Pedd;QAB+eZBu?%6a2l8^ews-KkTr}QiHk|!~dxBV$_S|0wUGCW}0YF?vR#^6g(9r07*>?Pcr`@$b9yL^iRZQGhX^CR!u559)=H0<0Im*8+J zo+DF=_yzXA=Y}h9seTPLnMgd)pvyV+vYCY4a zYWnnPxnuM&r{TK?_e=3pG1iRW(3Ri&dq|V@`LGOJ`@$l=er$)t>5=E2ogZIE+IO6+ zs;k^<5HIeg2{-mJljpOMzSPN5yf^2Wd3J}H`DLNTT}#CHX>>l(RJaVyn1=ajvJB-P zmnW+3$DJ6!*?#XCeqNbk{GO+k#Qd6`{6uN&mYvrz`*yoUC&3+vbPbp`rjR13~zQu7mz#t#_G@RV%xO}3)eq?_`mpA z)Sk|KiN_eb!%-^MSz=Pa6h^0kY5c(Z@e$zTBofnW$H!eFhYj}mui4UdPw_J+iE8)G}@Lf*+2(L6lF7Ut>V8*83MdIts7-P%nbBMGvt+rpzs zrcvrzg-+GkMyOfYCvLW8?_5OeYkm6X{F>Tt=g!O37~@?B+MC=6nay}AQjF7^kg8j8 zU7hCflYcdnXq6!z#?vEmhd3cs9+Z+2r~J9OLk#}g_UCKCscu6Za>! zu%*{2mB*U(#6|U=F_3QNtr%0zsa%Y=eG#2D9oC`Zse9zlK?fYzrY5he$>aeJEgEXa zwe9UlBJ#ustIgz1iT&PG3K=WLsygc-)wftvu#TChl>ca z7+HCdD8MS6xLV%7mA?;l(Rb+^B8Ql%?~-fwKcdIoYYooKrB%ELv1J~okna>3kup!^Z&D&XEAPt|bU)+OtF*HxC1v;?< zDh6n!Q~nQT&G~JAGdU>)oA6znR4?uwtY^B@ta6*j_WV3p%rs@3YB#8#1Ks?Jh+S^J zG@M9MFt}8Hvy0a#!=2{a>D`v*7>#G*=$AU1|A*W)dh*2)q+iE9>-iPB#;?_8p2*!+ zhZJTJS;wHEN=5+t26|$yUyVzBPv68q+v%-A`SY#m9dC+VRsBjd`f2}U5r%?Mug)=ZFJyEhIZ=(&PQwFw>V2C1B6e+_k0>Un zo9vta?rDJ1<@oWFxWQ`9Z9%@c3idengvK%K6aP0zzuzYF_~9&*Q5K(aY%Q8$;+i?E z!(~V$XzyAl;3OvB)Xjdlf%#?}0B}$^Mul8F<`~Q-KJ#iyrrG}A!A`QY(DHxzje&U4 zG2d(3cXBtRJqD8X)#(&8gClTpvTsQ6U|Y+}8>ay^mpDHoH+^uCWk%(Wo3ebejVspq zix^}3Qho#R|DxX{`sU|$PO9a57g0FReAjaq7r={Hu$QMB9RcDU41NL0>I?_9KdwCB ztfR*IisJnD+sZ1fBj?4GVjSa+FU^o}>}K8vTdePIvL{}KQ}_h3$SMsw=`FZAe=r6i^Jbh>%OAj#Q_lt*{8|SU3fvDc7Ie2E({KY4lDKV z(rPkv!9=IJj?d;{rbX?jhiUSsW*bBv*XPVG+A8&OGrYV3x7oh0)ftc6$QiOfJsm78TJjPB|P|RKIvgu zGsc(d}K`2?`{7k08+>y7() zW?raM+0%2^oy(ri*=o`8;nH(2K{K{^O!Zz+%0=+;b8!kw!$?;xhECtMntz@2%G!5l zd|`Kb#(Roy7Sl80hk^a1FSi?-lG?aehcUQVI<3XXQ?-dS;$(;q#iciU$M|kJUl3l* zL}5gK8`8PBk;Mp_g$5X=kE`$eq2TavtJj%51vXlqno6Gc(3|*IFPQqLM|~|le{eJx z2i^w#XWSD`Xu)aS@`mT^4b$|f{9)MoOh?a?7PmfXHlg)NK&{nWIm}*EZaUAsbp30q zzUrGiE!Fz+w|nBlo|A~Y>uAm!8M2V%;rOF`*1kJOR7K#kNpG?-Y1SR?2i~)qt4Alz znP+Vhv;26MWEhQa^j&zRzKnPL$g%aeReGR#JX^regM`ad((={(>dtDKp7-qavovGN zHeO}8a94HpkdQ@V3;9ge@OWF|=5+CIecdZPHqoP!4pjXaFZf>cTaW&{vo{wfc^wbO zNN}1P%ef}E_g8r^&L6GL%uQ4rmy-ybMMrONoVlGTR(s#f++4k?dUMYD_WRK6)c-Mb zk%LoCv|-z#tL7KcM+}?gg^%hy+d?;ut=2AyB=05;_~%w#x`lstozB+BeW;WEVA#hg z=q3fC_Qw#%obP4Ab1zThEJM4l;WXlA{x@;xQl!YkXW4;XS)op3X;ka$vH4k0&d$#X zF$#Uu7NjRCXUUo{lqseNxwtYorV&`jb*LCarGFgV+SA*A11_ilt#papX5eLuBYa{nw zzlW_&6oPta~<)zh^7<&Zku4#S*r%iqTHmHg4D->!2<$rH01 zI^g=wX6pRZV%%J0;;{NAoZ%E-^{9jjThKk^W*n9_{h!|^J$ht(woYx2V}9Pg_p_Bx z%BmUH=bQWP%~oeT+zovdolTRV%dg^HjeNvC88DJTyDgqV8-G3b)jWwjD2><>5qfP0 zKf@Q>F_Gl#HZZ)fF*f6rCmxnz!Pa=e$$sq+U3}StFwIgsFby&rVti=ato>o`*$1iC zM)fod@8*2s`giH$N4GwF#&6)GKy$}#@|(D&;FNtfFI5+feSD%9Un73}^jYpuZ&&O8 zhXbxk;w}5wMPk=gnpkr<%mjMu{WXh4_+{*sT|d+v7yCZi5@z#_N`g_eH{O!FUp|jP zZ^2g;XUHt(Y`a~fwGPo*F(hz^^-uQQTTA7dM*_VT2g4*p>!qL(=6X+87?A!=Pz3II zigPu)6LJ`B3C*l^=NDbb=dK+(JAjQ!qp$5JF&w!%{?69w$$q$LhxE?-SrX{_#i7w7 zL~i12KN;})r`kn~wCJYyQZDnRzM7vCJhiHhw9~YjZd`$XdTko8B)>n#sAakrcIe|F z2|o0r=8!zgX!WP(>YEGoseoE(a4>usx+Ha1j$Pb-T-^0FZBFkhSan@zo6`#XuX6_u;{ftjX zH6K%?*_qI#4$mA#M1R>7Vu1JYBE#eWcQ-CKH;dWJq3fa%{efex^v{|!YHr_!`Y=E1 z7~|9{=hXH(LpC|?hvjmHm`nXWUt^@BePWW%7!-$rbjog#V0=|ccm>z27{Ph^KtM*>w#fDcb=}6*Hy^tE6=2iy@ID6LZ6l$1W;n*gd zv*#^Bbz;YVf49=ZA6Q-ciJ@Hoa?oy``t5!b*UoI=+r;>tC~3mLG2Za2*x?Zk&;`>$8LJq3O8%_xJ18 zusgE`cKTHa_3oe<)A)5Iqv|T2P`LUcQ}>nj(zz)7*c4lV3Qs+GztSzw&Et@FYgFu&j+l-ke*~P5h5c z;^}=Hsq~b;Ugi8f<6LLK!Z;`&*kponHtSPV_4$qO5{x~4$nXV@vX_sZU4lq&$Y_tn z%|jlQ`T}huwl4SVI8{5NM_e^--$IGLewK5qAts8byumh;JN<0PrS83E9Rr@m=?zv@ z?Hqxe2@YDECDzDa)3qR|^Ha{j_xV+l*_?eM3z*XgZhvYBjIu16I!{NbDSMRC)`Ag#hRx# zWgdUMp(pP5t7lo(_WoSrOhyvBjY*aim(M9(f6E2ObW5l8qv_uG2UBu-Lv4(Hr6jwY zwpeap--OTIBxd<8arnI&7l@0n2km05baBZ}OC$?kRglWO7wHIC|HR(fYekSJ(-%546boM$N=Vp*?_{8*)3{j-6Mce#|1^LeMa?$@dK08A@ zEa_-Vph~IeFR5s-@ZeeiLY;^zJNtsKrpuV%!ygK zwRN?Y$ba0NLVoU5!^6zm*t4l4#+)Y0I+JYt`IRi1WblkEJLFJc_F?Y<1aGS zr&fFB@!20Q-l2YLuFiK%Df)EY)gqKGmb>wpW*O6vG_moUOq2-8zO)mW`BnAn|M4a7{1m6zS7es|)0x|*ak_r;MU19^M@6^( z4B3p`95En5jov5@!ti9AwP=jDq9uzk>=$uZ^(B>@8`*i|Eg8-!li`_zH0I2U|DCW+p|t1Z*GaC z5T#7BAuj7r{w>zeqU7Oh71>Vr*xv~O07v{{5o@2lHI}=H?Gx!K`tj^lReBdA=Bv2~ zu#}4ILj3fV3e}>u1Mm69n}ON5J;)z>D(U%&w#Dq0$Y zd~(A|9drkO3G|t==aGwhzn{_Y*~PCUNv8U6({1{}m*z>5qVwx3^az&xv=gOdsmCq& z!FliWbw$xhC6mM#&*FC9cF*PqlaDpiM{d4GN_dF6m`g?8(dp<}o|BYi@1pGd)`gbQ zQ8VFDFIZukz@)YDtdwZ!DXv?o!JKt41*x9a&*qr6lu`3#p$+3;MgIMwi&v(cHJC~Tu2e}2DlGmC#6^)Q)a{um>}XzsoNd<&5E z_i&ctX0nsGZ?a#!KP>;+O?l#CW@B`8cX0LPo9)7u4e%L^?i>YjzK_GW?o!&jCpOsi zImf(hbGG~^;=7)GR86zd~m-+_JUV)xXf@P1$|Aa`k06K2n|Nvt2g{G z2g%ua)KE6~qII_Z#Y(fw!N%y@M^#vl2ink< z{P~EFV(`~=`4o+vI{8}qoZ!)42Y}^u9Afp^CQXOj-ux#u|Ga8S{(EvrX4<=mV%4ua zqE~54p3&^)>1p;9N4;LVMq6X~l5Wv?wI!o&7| ziBzR>&h(UCDcr~BF~XzbAH>5UI0N%%PNa96{@e)s6d?DL)?PT*U!Hm$QE(7?@U*Ki zMV(I32}hx2##(MP9$Kw^9JWr29-Qp)L~aswsIr`zM^oqjN3rwL!%9_iq=fZ|8Rfl} zG;=&3872Eq_A>Ip{cm5uZhO1dNBZdmTb1xkGqhB=dzPpv1+GIzCOgdkH7UQjF}rj7 zz8zn(&9B3#c5t2F#q+b>m`K>fN7*Zikq@0NBBiCi@@z-eDZ3bAR`Er*oAcB+3wL%_ z&wuu@36)bXdoP+a@yFQjc?euomCkFIi{_Oje?4<1bBc>+KDqg8Ht>*v&B1GA!SRW= zNto?AzR^OlJGN2Oa|hDpF-{~&(t&vAq%txrvM=*2oVIbwqSvPWVz-T^ndQ}VHWZ)z zKT-NDV)f)n1?V7D`Gdv9?a6IrwiIu0nfd<^e2r=(6nb~?@$}ovm92@f<&%T#gDtg> z?tsRA7kAbZzkxRw_i%PTSHF9Ga93M(+jj8K#2?OmuBX)_HBR!AS;aRKgKL02txu;X z@oF1!zn{Br;+@gz&tYL!5W<-46V(iH$9RV_ripX8t9#NzJea&p?j5VV-`6O-#=gT*wV{_u*YakW-Ubt7o;G)oMB)-PN2)dyC} zwW-OBXBQTTh>wT3^O@{HbkM{!QgE-%;#Qgsg?K(n@`atT1C(PSIsV{OHfM zGzYdK))$(yTWslTYNs&<*JDD`$4`{vfRFv;u8XOQ;)`dwh-&l5a)ayBOrEZ7xz9Pd z!6$XuWSGA4-uTOS)m3<0L>1Q0M=a_m9xQ!plLBm0ckz{x>H8|O4PERma$UV+^^wcx zZ&u$kou7q>>)%)h(sK&u4=GRcFUr5R^}Ax_F|TkiX>|stlZ0L-^V9Du`651Lj?`41 z-YZ@)y;t!yHYFVWJr;XyOD%Z$(&!@YN$s zP+^6$Bk>_#e&9Wt#tADaotp9c@mwW!_nzhQoe5muZFK#-yy3X@JJ{Jx)4k{Sg@k(+ zW1;5^7kn^IWq3ljKg*yz{fqCyI7!{mJMW5#biaJIlx?OQ0VWSSY~wx5i)8Coeb_PR zK}hmqu?b0!9)BA%?`FX>WB2&EP3n(sd@0KATP)(ERQd4vsMdzZabcoJzOSqy8Tnl7 z?(hX-PirtuNo+Dt9=Q6e-D^%S(C*>_NS8g2z9XQ;^A$~=Oy$l<5nAMbgPJG4f-CB( zoAF8DdVH^b>WGwoEkD&iSWVA3Uc9)6=5#R&Gd_%QnoTd{SqMAs4Rd@;hMP)Xto2c6x2+upkx5Fzrh1{C5w;Y@C-sap5 z-^5GOSo8kVpdZ*CT`iMJf?;QLc8Q`6Q9SUxKa?Y(Rh(AHw>vR zdZ4EFX665y_#JZpU5Sln-0>DXQIWU`T?8wr3otzcKXXdr)btAzJ9{5)?9Ce-9*&n1 z@hyz{fy^%YPjc3{;K!y_xse&-TLRG|mW6IuzuQUQq4d!sR}wt@I7H!t&t4zZ?;oYX z2fvP+nXpTX4{@cL1J&q`+l#BmFGqHm9o>$ez%{$lY9Y$~MTCecf^H4${lPB`s=ODh zFT^>~*b zuzVPONOWCPjW0x$~=s(KKldi@)5R@S=fBKRs2os`ICrR9%m3TJ;mGl>@2G_9d--~(UUDk6`x03t3u+$Ciinc zXx2#5=J`xE88f@X$f^R$6`4hSE^Yg^X!}y4@dw5<9q;xtCR3-2XEn=m-9vXEX3mBD~@&KmiZ)3)XTUH{7%+hkh5zfeJ&z8h3vY&QP-j@UbWPg5pL$M#-60!INkA zAm2uW9UncU4%^|;psn!oBM{6e?zbP$D2dModcZFFdL`l~3{VO4up~i^9smvf#krxK zDiRx^ZA7x=e6%&3JR?>?KmJ+ZW?@G2jbvwu(PbH`T^BZQ$_rEy$}ag_CW4?>!-3L- zU8M1TvAMi1GVs5RbC3uidmRhrm<3}W1hiNYMz;bDw`tU}nXYU6b_#iu;np+_!4GBs z1by*84f`U`CS1}sCMVAudKKDj_tl~9VSp%iW-2wHkES6O7zTbhR=HoJjd)gr{URsGM_4qCm&?PKL>}nUu`CQh z(eFY3>O>c5SW|kFN0cA2KwPvyOe1FYkzNr0?~tOcS<0Zp<0{b_8s>XP{DXf!izfYm zw~I}K1y7{6`K<`(FcIT%ooQz6dsqmz<-^@8z)~zr^-qsoewa;FEk(2q$*b%-G%r3+ z__uXbp;4{QDVxOMk3_rC@B$)~);om|mv%M$fbm>m0qVYhd8WON{5Qj*NJC=All2y6 z$1PeA*F6rO;#Bx~nST5r7|7yzZ{S^~3jM=hOC1RRXR7UPg@=B+sPtGlr)pHFGMtxL znxJ2k_7YYKbP(J&Gp$_TAxj4rmC2k+Ja!0k74q+`Ln;y*%#l@b39-y z4>gb12XEnY%B;(+V{w!PFzryuG;7m^J(E#8M{t*!X>59wZbsOigfvoOJ77r}=lA#n zp2VADohw-s_w1DA@ewR)qP*{1x(Fv5VE?yJuBRg1WQ(ivy+mIO8N5pH--00$oNRnN&aW+QWHyGx$PE0*{j{y{4%`@n|9+3wRBYfw=4IN) zz|Y19tX9X_;7;ERx`EQISogShhSzTSH%x8DsFOecXgrRaUa2}?d=v;2y@{Ur$@dJ>y*_DM~JRYH~)z7L(BB3 z*OyG=sqbKHI&FwS4r(<2dAYQathi2!_qC4US!=$l;)-cV7DXaj@LB|0*~x5ut%QA# zXbIBTp^I1e$YZ~n#;GzH=MDlLpzOyyIqfDM@jWMp-C4YMy^i}x8VM7$UuM%$duTL};%~ z)G~Z4Z=rI+G25XTy0VZG7*w$`Qh_fp_N`9Bw=bK?mppC{|B$am2rak$>vH*PY63Rk zM+@GyMkkh42sN>}Tk@8(rr#ej1?B)awmk!M_m_Btn&pBxZVj%xbCm|M9p*bm6}3mO zqY~*1Nw=>DIgAWb-3n{eXBg?CPI!>1qoa4xu2!Mls*%w$EaW>^6YyH}Hds3KUlC0C zysxB-;)=lyt?(}2$`n};2^Xc?we=|7vc+pWj};YM)?ZC;m)`B7&ox5Hl_uob7$x{C zsvQ`TwfvsB`fV#)fWjIJ#duLO(81d5T7m1z+e_^Qj>C$){pGpIOR9Tyuyg)nQs_Eoc_`I+za~ z)tzECm%+L_kCQtp4U|8QSTJ0f1o!q4t3NDvZej?+LIAnt+^nVA;Jv_%oDzi>l1Wod$QhL+HFt0Knxx*E}3d@0kEUw@zT6K z9Qxa|y;z4v8GC-e2o>(^Z#jw|)lSB7TXBfGSlEa1&uF%94Y_EL=+e>`1__}5PjoJl z@IRKgIV-nN5~JVE6Zg?~hClycKC(q0VI-KPgAfeK(ZFFoP0y@aW7*SQ6_+;HW~@+c>QQmT5->M;DM78<4s+fb#5OIvee<{14P;C zdmSwj020ro${@k+gg{3t%{^eF9W{Lo&oGIUtEi<`da7v9oU*ERTs^moPW_x=EF~TG z>X6QEbYz4bXJX_xv9B;TNC@E?(6$Vj9ew-(QLGj=F2gcTvv9GUXQjzr^&1A9m~|g! zVT#-Mz?Iwb)cYb+S3zL7fu+9gWp-E@RU~W1SJ$QF{&>bO5 zRtD?Gc-&akB7@>ET3vZ>PBT{fXeyKNae?fm^qPKWkw}H1+rxNXkRgx(I-6rlJz44M zR%7Q0OU-x%?%a0u`X%l`+F=dFCw20jx7!jd{$_!ntcJwm7uLXnJa*-=MYt;NrzPyMf<|B&i-3W8n34nu0R-uYN z;~U$Jd%~_s=Y^XZPhrxNv5yE^9^GHt4*P3VCz`{Ju-a!^RhNFcZro3I{uRH3mX~5b95)TC}+_ z=k#p4ipLVA%0=SeZQkd*aFr!$Lw2EH?iP`imPJ1PTJWuVA}U4$lgM_5Jrhm7w<=qX zA`GWwNk_p56v&cRQjR!EpH2Z-2ijrzXZdV4N+tY=3+TpXLmml?x9Ix)dHI!Mcby=t zDx3%*q<${8dLa<~B4SfneEw@}(>d`oTm!oD`|WsrkgI&#xKzdA|5=o*vKsHWM2RkT z!()!)+jELA2|70co$RpjEZxbgFb_y?frXdk;B?r*joE|Udd@N2{xcg|MLNUS6hJSH zP#{r4Y}^bCA^Hlr`e^`bo(^QRIMpMg0~^;& zWW%y6k9Rrj-70KJ(;IdJOsSpvm4~t2dv#7RUw@)LPQ*EP-v4PFQN(cR85y{; z48B|0@uCk#wL))AHB$ELB5TU1vD!GaC#c;1?{KYG@oc5osA8R{aXN$Mv+{oK!%2k@ zgl9{J9T>Do+^vB-t*3L#rB3oj9$dSvE(m4kMK7m64=xBKbsuTH&+`y(mt#h(?UgF$qOcGSTTa;U~&_f`=GQclK*r2j8H_Ltub? zF5>-vXcd68Dks?b!hxm94Ji3QGP>2fgq0U`Ld39De@)sjf;vti0I>MY5)j`M216!?OQlHN_~< zE%R(LK-M@X9Oxkj*6w!gEnypYkkj~<|1`SXEOF`zcm#_UWieTyLrsHzKkNYc3nX(pE$3zr z_TADwokVHu3R6*bP1yz0z?dlVXvu?xe|I?!z2Y_|j%%GwnLXdHOOm=A#OxBWbC9mX zFrTk%$P@Npq^8tAQ%e=rqDWij`P#^z-9j~HciB%NcV$*eXQ*r@_$P0`oU#q(Rh zTzrl)$Zmmj8d7)=bWa&Xu7|y?uam`8h5%57NhnvDm^F3(aXBmSM`N$)j7&68qvZ^ZQi3 zx6L;d@*9dEdzt8seJ^2#dC?2_fSK6MmWeiaUnlJLuQA!f*~1p260h}?HGCb8zoD`% zbqBy-WN-`slA|?{Nc##q-;nyD%SC1MmG%`5ju`u~iJSi0Z@5vE0*9Fp!HUfC^~&aJ zX>$;o=-P){ZG`h#kNcK$Z}l38G5v*NHn-!%N6*n)wMkIrQ=3jMZoand!9V2FG=YjI zgLdl#gG+7shd2c!6jII50EIdIS608<<{w9Pdk2@s2J64a+w}dHc`o{uPYUG|S!co-MU)W!+eM`5x+=wXkh> z2R>!O7~d*JteW9v&>6SN2Z|b=p;GAW9HY&97%;V4my5VScM)d5_RZ&0DK|gRm8_kv zllp8)54h;4jzY_@jqN5W`MhL&Sl^3KZRCo~aY?WFI@!uR#ckh6F#ABFDT`~e-CT%o zYlXIoW=>oA{fMWDh0SRfpf)3KZKfJp*DV|v%(l!?94EB&KRcHS8^c4)(ufT89Vr&q zjz&bTCo+QmFFDAgu^2C|n5F&qevM%OvvbFMmsiZ|B}W~HkBIhJ5sQAk(^9mZRIYE) z(2wL5tlE{P5XsuR{NEzLd(WcgDI$kr4ZD{jL#tT=w-RR3kiQX4agm{ni=~K~7(&qX zxxdPb^7hO#yRy)KZjrhK{gpwQ zp&Qe?7V-poc|1keFdIzDxj$ssqya>Gaw3o{YFD9qV4q^RyGe-lWFm)+0{ZA*vuxKu zp5~it<}#7WdH5XtgPIlR$V6Jj)WIj9jdOme4W`z)Vr7#W6{8~yLc6K zmraF`6S?28Wbrxd!t_6jxsKAdF_WsT@)!j(4;l#r(VEXg5t<}@tRo_3!aSH$a47<> z^+oqMVYpulip(3QV9v?Tm*eeZm3McmY!r11N{P=fZq%e6oOm5fvO~#foJG4tUDug_ zlNV~ji4tCng3IH>2*XcS%X=`({mZQU9v>IF%VZI#iD*d~BqMk(R*rVfzAwW{;sQ3# z0V4^k>MZ5Vpw?~O@+TOIQXu4@CRw_=+hO6A4aoljp2Ld*gyd9lRQk`a5<4dBwB5qL z&a886v3Mg*Grvh&k=$?5WI79Q@}D)PBFzjDTe_QES^WRUU1MiRZ;E)Gf}ByD!H+vl z!yB+Ln`N{+{S%yT-rzMdX~SLHB>DW!EWC zTQd``Tmk^gBJ|AE<2!HLTH__GuTe0~1yN2)dL%MwO^?KHSP5W{F^myg@!z-|tYto7 z-`R$Qqd#G()dte%-!%F2*!pI@2f=Cq?S`=qO0FLZ$BL0{mdr?Ywk7*pEh%a*ed zMN?2G!~Q?m#gZy=Zk+qiMQa*>DKApD^wE(xS*)L$e_Cu*d8o=O-sZ31|9EW95qGeP zAbr{=hXP`oHtbr>OY+B5+fPJ0acZmou9S?8@ItDoO|(cX7Up%Iu>-j2ux}Eg)@jJ( zy0B%jT79H|V^O-Mkb_Vi4u?S|++~r=x*5*z=luKMWNDCejjbC-t=2IQ&ZvUUi78+~ z4%=ujYCy^l7%C<9cOzWLW?gF$ON^`~ZR3fmT23_0@r)AP-;nWGcV-=p@J%rIgpAAo z;~thQsl_eue1^ba_;+~AQIQ~$FC~q!27%{{>$c7_O1)VRc$kLqs~izz1Jfrgw@L1l zq0p($S+db}+WAeED0z;Qr!2VlpPbEBWHRrmk2xBy z%wBAc?L|gLT4CE)MwgYZrh=Z;wGs}K%OC78-fRwUmB^f4E2-fZq$Wr!Dx`B5nFzmR zoVD}2#5VH(K$0yJ$D2!xp2ft5ypLN@7t*M)L{aX7nwS+64Kj}eT8qCEMxR?>9>HQB z?85n6MBapMZRGEG1z@eMKN3)Ej#M_EHuO#smDj6 z23At88iaeS73te66vFaG7Al#1YiGM4^P48KeeTcXIcAO3Z!-0kf9jUP->>P;y}nP8 z&Ep2dyYlSS()I?BfzoC`K8w-s8Ye9T@`~(={fy5I&S4ClvJOP=AC!;$zsK9&MO)E= zFLr~;u#CbYvdXfIW`p#t%u~u8cGm^7c$S)PoD6m2o&UhzIz{HpVvizPXm37R(x~7b~~uTX}{>IdM`5 zZ6%7E_+_4_+Bc@Ou<(N7x^Lx6s|Ck$JX~LY(2HT*bj_1LPn1y=`djQem36#?2F+Jr!v2 z;#P@`;>93^>=-6LMaJp>JfCFFN1h7SufYGrx7Ekv$8(C~-%x!dO^|BF`yTx4G&nGP z47WcZAKsBGJz>XZv@qZbZcP%8ZX$~#E9!BTD~A=(8x|k)pxBTdlMrjWbW^!BBmx`a z>GH@_Zyo7%>nQus6852;&;3h=tuN|F$XD+Fu#hp@jx?Imge@{Ju9YTHWW1=&4}30M zkTlMpC8|evIc(Y$c6Ct!r9z-LCZa2k2b#sg>^dQ<58!v{smD4y_+RZ#G3^Qw%u5+B zmx^%7|0_~5o8|G(uQGn!;10q?NsugP=J zADgY_HQ+yn<}Nj%R zpuj>m-GI7=QJQ~=J!s969?^Nv@LyscYfIN8Zm5=SwS9llAW>zIYvv_%NyC9ClluOCQw*2AZ1HCTwsAq*DN& zw5q0t=@l6_kJ;5S9V5)`0Y&mQh~#Cl(bgFqIZqy)?{lWWqn8*&V#(tBG6O7V?pFJ0 zDBcF!!935;WCCnHQok^l%6rNrh>$STmd=Y^M7PJHEn};}L^I88euCRrpYJa(+2u*? z5^Di;B9XD9K2-f_D)R@Hm+e*aPtrPc4!o8gh4qY1&@)$m)TPcJ$-8WH!{Q^!% z9b)+bB&)`reQ|+Ph=xBRDxU?47a*A-Hftxn$ITn-Q`{<=?h2NT#!Zi&hpl3B7=MK{ zI@X3N@DMf2<2q@=yXE!HBg9+bFqR;W=F76#g_16YDDfuS-N*BcmKg5S3bQxwu|f6t zju^RU_RDS5?TZ9})z4He3$CzT`Rt+@&L1=F<6m&q*Rf^VNZUL;GJvjD%fh4DZ9^_TYv4q_n5olv$(TuH7Vd0$aBxy*KST)W@qKIA|#BA>e`ZpFR# zQwOE_^Z_H2MbXn5HDru3JzK<;;6Nk^?XmCFwbRl zx+-*mi$}5vO>v&#;M+(ul_Y;{u^Z?JPA#_kwzpUKJyMly8OxsHIBV5uM!Xls{;@CO z0GoaZEhdvZ-LFHvKZ-p2f7Y=)Pfa`;m$cBQyfC#3pztrzngl%~wlS|=q(I>&4%|Y) zxS2>E9p$5zEBB~EH8DcRi#fy1r%TZy!PiGBI)rV+Cl*TX8;cgP9~8o>a-_j+J-V{a z2!4yW<&Bd`NS2Ki*fW?a>Gzkyb@n!v1)C*`{!4M1C&-sC7=`yT8?3$)n*^KoUvX@% zvxDyE@pk(dO(DzSsJ#6%7Y9_mIe~{8PM#cGZn@BBdY3Mb9rJj z2YL7)5|r=JcQKeZ!vQy<>;#?WJmY9T>cZ1Y0ssF5&s&9V!8D+WfoLReOX1}H14#Up zUX@M$!RiiOR9U)eBVWM7Fh27H_qbJqdHla}`!D4}h6jRpnz4L@+s7ilsTLvRPlIG% zVU78G5ZTHx`=h~t{x7SeGo_7*1ywYcYY@d7HFY~1#!X>Z&qX}RD0gTiavtm;nNHbm z3iP==!UP4LI%Q7HfC`c)V$Mv7|Mpba2h{6&f!j<|QoO_&XYu^|XVV#?0YxS~Lk7WA zmijA>-;g1}`Z*{KO>tin$)x%&e9-klX=q8@a~V0San7T4%J>ySc*8aJM)D7+ab{|j z$;R`Mno&U<4IRD0tBD01-o+UoVccY5-V8kHrnoyH)Q=8tj4=!Fgsv2k)`U5%{sreU za4Y}R^=Hdpwx3t*I-)Myu=)Qmtiud|U(clv-9iYs!>p*Z|4$-aIT!!!B@Qb8{SJic zqx885)rI~Sg)j@pLu0P!_Yg|kezw1Z>EH@@j{VVne3-JVUz{s-tOjIioAxxGL!<2f z=`dtg2=w|82D;4?dS#AHpy4&N`a#YehZhUi*dDqRdNRzG< z7&k*bv`um}%}l{_(-j&W zRjyiR@B%sx(yXO8eCR8>XiHj9!rqC{FVzc6z>5}o;l9%w{6mpP$e&s{80i~+i|(Bj zX2=F>$k0Fk2+!592T|5X>2~oEs3J`uJ((b)aM4F%it`_gJALBS^Na@7u3*f;WSySF zbExtE@yy13oEa1QFo^(Qmi zMEDh^+AMi*Fqom?2p1($ojhfl=FSe!DPn+g=!R5{Q5v7a;1gw0c$AocuLlBaP(>O! z(txW-L5IjY^C&w$s%cI%hSEp5wff`m2TH1RIiYw*;Gok_eDX0Yf^`LTas?S(aPa72 zN6QMHL0!c^5A1`n#AJ}^G^#xmnt)Cwt84*Nm} z&WcEAJ~Vurh&{AxfwOaYV0-2DsGAb5tu5PwYth|(meL8 zU~#&SM4WX)HVaV#pjSY&$1q#e#nC05A9q6FNz#oiwja^mfeKl99lvwwm|(v$dMWtF zRxp`t&z%%=28|ADAJ^(T?C)XKqZMe3EBY&UQgx^~QDI)w2B3>~osV_QucmX_O{4+m z#3^_gGZ7uF5$>?Jl)gI-VV91}H)o|?v;vaib#5dJ0td7Mj`%7$1g=fL`CE% zov<;`PD5@oE<`^a@dJq;TD`S~g_>Nu00$gH>l%El2J6j$Vq?>;8Ges~RJRyhYs0 zIp;8ZPo$b;9DX=hG|fx0XCpM`S0b4e%JdP0scTF9{7F$SIH_~c0d2Cy>M+iuDkh)> z?e2QxvJ4X;qtq#~H**<89Zm?_WN;YzR&`S0+I6cuwC ziy#_P->6q2x?M)Fac}LA}y4i%!`k(`^^T^m$p}VE#j@>l{x|XOLCPw&S0Enzprq2YYN};s z2be1?+}6IpOBpU{FybUcqhr3GAlU}#>a(#Q!ZM_Oc0#5TJPh4I6g$GOvC2Vc+8qB$3V>t0%x}Wf~g} z-R4o~@{)qn4rr`stSLekI6vX#lDQK>8?hk^L+_zsr7^2FWz%ip$jClVLxBkSWjg3q zbDCBSzZ2;bU8*=slV7mdcvLfS#qCS!d;A`Pf@`y=x;?&ERc&L1-NFJ@NTlwXAmyH! zApaW4T?|KXYNtGK6Q(M*gtM5zbXUi7iwUrD9vc_2||FNdI`4sR&lH3L*cxw=KMOz-Oo zbwV%n1r)4ivtKVtP4kIPu1>vWrE7u9v>sMSbQoXB@(te1O^et7}}iI1?7rG1q_q>SAlW_5WsCR@Ty>f}(UITrg@!4#KoZ4_au6IdPwHSmdEdQ0_h4gbcHW_r68K%eWQ7_-S`0*NDs^ zn?bca;D_G#FhYK+QaEq3HF!%Nx1 zmCV@xJr#8Gt0>Yv)5-a3=26t)Q3Qq!GKhnt_w7~T@{s4738bg^ea>ziw-PVqtO}@d*7=@ePk=FT z?wo}O>w#s=?)Tea0e*RgD~p2E@~Hd6z(5AC5D6+7@G1BUfxvseLo*Ib}M$=_grburfF$KT=M z1!t?2G*EWj2YU7We=v5>V0|tZxEXO7^5{yAJB<4eQ*v6rmNvn3j_zq4B3I)GP=#ih z>6G+qp#mgUW#{ zVMT>2eRH<`Y4kt$pG9l|JEH5AZO}Cx+R#JOwQ?~WYF8ibGoQPTz%D{vkfTLn(S@4~ zZ#&&3RaBqt+4o^kHr@bSKF!Ybs1tU$`M^#J1>F=0WSTa9qHch7k#kCfrJrnqJn2(} zw6_^AEiha#X3Ce@A}CrX#M2?3{Ju!B%N0dQbO=n&$uKSzF&)vGzY!q} zEus*T??s|=#Q!}oOPKNnwlo;h^wiil8H(D&QV0NHjne}6YCZ$Oc3DqcuLht&vvQc3!&4HWEJv4VQQgn)bN$CdD;;ysq>Zk5m9&FKcFd}11{1jne}t9q!l`b? z1{-YY#|UvUl&;|!`C7y`QImppgtZXKtn}J{EMoKZ32}A=FMDvFkEmpDE1ZrFM zUd?P55KO(%n-P(#F#lO*V~uW}c_mgGO|dOCc?WH8%j|BD4LyQQ6Aa_~>20~`RB9#I z``F_oi5Tnivt_c4N;jCFVHre)*y#ju@wxITtSGKw9UFUX57S%NpB`H(@ADwvb%;)} zC`}VDIDM9$w_|PoR~VLI8>e0DcI2I-UP2?%dFdJ2L&HMC!U+K`yLR88-!fMQr|e=Y zvYs!D1}sLHCJYpdjF>I{{RP#basXJeDX|A+^cwuJZ#MR+`-$!q8I~>pi29p@guji= zhLgsA5sR*v^K$>9iQ;nD_nHSdumq9;X{C{iiN_waE;X<5O+~E#lm>TQwDH(?b*`yH z#&>$Ieid$1vxL2g{p~np1L+`XIDEgrz~MBWmoy8>FBpN+6mfs!(%Jks!I{zZJm?hi8v%4% zlW+LHRF~2<1YPv8^+^&*+s$b2+d(o#zsH7wN~t1~!bJbX0|bMhXE8L@^H_*)MYZ~h z^X`3yN|3CC+Hh2{!{vVmc48?k=1$MKd>7VOGqqkC-J?g(-`!ynUF3cyxZS?HP!cxo zjdNxCgLNdR(gm~!m(vcHn_+N61*RX13hRu9)KMoJQZkeHE2M$2ieFuQvE=;Gc*>KD zyGKqSbLlGyH*2%@21y%u(K}LdvEb>m%Ozv*d4~R!g+a^?I327LJpV}5)rC905ic}6>+L}Mv2|C=sM&<-6TZSFqKnC)k^ zxMb_myI9f;(b#9WJtwT-YcyW+Do&6(BOZw4#g-*w+%Yw*{e)3m zjZ8LEY^8W4j9R82Bm&oG@W^41p(nzD{Z>#(l1LGgfuX`)f^=48;;@|n4PozHGs;9| z>aARZi#-KM;bD!nkBq?Dl*gUrBikA7?b}gocJ0p|0XwZG!ZDO zrlHBlU!k5~f##^)%^v#|oABd&aml29-5g}+jSplsX1%R)z+-I>m$nM}e2E7VCAq|a zii%XW>xqy?8wWp;fR$%hd0f|L=?r!em2l`w7U)ZkOu)MrIc#$euTYi&8EDWb{ct`# z)CzZ_j^D-Go4V$EMmJ87XZnOqs#|ba+H<4qfd6ZZb+)AQmXD6DPeB*-KK)#p z>roPlx6q^0D%hcd*yT%m={e}oD%AZ4Pw%o(n(A!&5d&<39RvRWqpq~U)Op+OuLm$O z8VJNIb;>;0OCSO!n$)|Pi~M~YUSIbD&Pf(!W)Wh*I4TSD@)?hQ*PXL1;MYhj%z`6V zL^|th=s&(Zry0kef=tNHyepFa)GE12$%eLZ{2msWjD4j=cX$*#JC%kEw{wVMQH<0h zG%u`r-g>@gXC?+MrFE(O4IF$w9K4t8E>h?CzQ{}(U2Tr}bKR_9-1O~B7^s9MRO0yv zk3wdLet)SvRD1v!+O)uP4qXu2DtK$+^eSq381t(t1Q$^?JJ~A4{HkK8lk#?B{6l5a zKb8!xrrtV(Y~faxqQ=EDAu5>!KRNn*BGa=W3ifZQB4BTe7doVEX?Jgj-6J$A(MkC{ zull3xS&Rr@uD(ADpv>NjRp5Qwu|MkKiI;H^AEWLxo_d>sNS$T@(C zV6)FaH-IPF2Fj%o1BR?+(iYDg`bs^~Q$KCps1eIYQTxc2s?nnvQ=ErK*@}G$6`K&- zHG^;noZTAPQP`oIKPL}E%mkW{>abES#M%>t8rW7#A&DB?NC@T(uWw7nJSVdavJU-9 zDj{qPT8@F)u>ns;kCV^pxBMD8X&S)n$hf`}ppf_+rC>LXUX%k(JY3!ufe^(+6`~}L0%u+6jOw4v$$B@qqzRoLdt1O{#9 z?K@y<*fuO;Qa(}p7oJq|m6Lm5b2nQM@2&$aD%L|wRI&>AlO4FJ33ef{w-o3h-s=fQo55BkO|B(pBB+Quvj5&<&6tkxt0=pP>U7LUjo{@PzR7hZvY@vwy>eP-0 zipOZ&C+xDZ8y)i0H2IKQM!J~I{C-QFOhK*AWs8rBcwm>)3;mqi_kQ$Nwm9eDz1yL&G= zVZOx!iA}~!kYnP7>=0NYZkCAtSbwlz0zdA^}sdWU4n+9N<=25rkU~+PB zf{feBBQ{trKgC3PdLn6hPabAbYZZ}Ni{}f@j~nx*{2c%Pk>)C$tjL=^9h~%!?clQR z3x-yfX`eXE&YND!Hpa|eBU15l!+xO67-RcINQu{$Ofrmi&deRBdsfikDSwx z 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

    MJ}6QkWG#>1(XXk%q~RA4rX%5kDN*E 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 z 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

    +&jj#n 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 ptDAaam}6Po}YvyYr%N0 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 HK9K(d+Kd4# literal 0 HcmV?d00001 diff --git a/openfe/tests/protocols/conftest.py b/openfe/tests/protocols/conftest.py index 743352215..a90f6969d 100644 --- a/openfe/tests/protocols/conftest.py +++ b/openfe/tests/protocols/conftest.py @@ -234,6 +234,20 @@ def md_json() -> str: return f.read().decode() # type: ignore +@pytest.fixture +def septop_json() -> str: + """ + string of a SepTop result (BACE ligand lig_03 to lig_0) generated by quickrun + + generated with gen-serialized-results.py + """ + d = resources.files('openfe.tests.data.openmm_septop') + fname = "SepTopProtocol_json_results.gz" + + with gzip.open((d / fname).as_posix(), 'r') as f: # type: ignore + return f.read().decode() # type: ignore + + RFE_OUTPUT = pooch.create( path=pooch.os_cache("openfe_analysis"), base_url="doi:10.6084/m9.figshare.24101655", diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 7d68f8263..67b1f1f46 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -1,14 +1,29 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe +import pathlib + import pytest + +import openfe.protocols.openmm_septop from openfe import ChemicalSystem, SolventComponent -from openfe.protocols.openmm_septop import SepTopProtocol +from openfe.protocols.openmm_septop import ( + SepTopProtocol, + SepTopComplexSetupUnit, + SepTopSolventSetupUnit, + SepTopProtocolResult, +) from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference from openfe.protocols.openmm_utils import system_validation import numpy import openmm import openmm.app import openmm.unit +from openff.units import unit as offunit +import gufe +from unittest import mock +import json +import itertools +import numpy as np from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory @@ -596,3 +611,220 @@ def test_two_ligands_charges(self, three_particle_system): ) expected_energy = energy_fn(0, 2, 1.0, 0.8) + energy_fn(1, 2, 1.0, 0.2) assert is_close(energy, expected_energy) + + +@pytest.fixture +def benzene_toluene_dag(benzene_complex_system, toluene_complex_system): + s = SepTopProtocol.default_settings() + + protocol = SepTopProtocol(settings=s) + + return protocol.create(stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None) + + +def test_unit_tagging(benzene_toluene_dag, tmpdir): + # test that executing the units includes correct gen and repeat info + + dag_units = benzene_toluene_dag.protocol_units + + with ( + mock.patch('openfe.protocols.openmm_septop.equil_septop_method.SepTopComplexSetupUnit.run', + return_value={'system': 'system.xml.bz2', 'topology': + 'topology.pdb'}), + # mock.patch( + # 'openfe.protocols.openmm_septop.equil_septop_method' + # '.SepTopComplexRunUnit.execute', + # return_value={'nc': 'file.nc', 'last_checkpoint': 'chck.nc'}, + # ), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopSolventSetupUnit.run', + return_value={'system': 'system.xml.bz2', 'topology': + 'topology.pdb'}), + # mock.patch( + # 'openfe.protocols.openmm_septop.equil_septop_method' + # '.SepTopSolventRunUnit.execute', + # return_value={'nc': 'file.nc', 'last_checkpoint': 'chck.nc'}), + ): + results = [] + # For right now only testing the two SetupUnits + #ToDo: Add tests for RunUnits + for u in dag_units[:2]: + ret = u.execute(context=gufe.Context(tmpdir, tmpdir)) + results.append(ret) + + solv_repeats = set() + complex_repeats = set() + for ret in results: + assert isinstance(ret, gufe.ProtocolUnitResult) + assert ret.outputs['generation'] == 0 + if ret.outputs['simtype'] == 'complex': + complex_repeats.add(ret.outputs['repeat_id']) + else: + solv_repeats.add(ret.outputs['repeat_id']) + # Repeat ids are random ints so just check their lengths + assert len(complex_repeats) == len(solv_repeats) == 1 + + +# def test_gather(benzene_toluene_dag, tmpdir): +# # check that .gather behaves as expected +# with ( +# mock.patch( +# 'openfe.protocols.openmm_septop.equil_septop_method' +# '.SepTopComplexSetupUnit.run', +# return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': +# 'topology.pdb'}), +# # mock.patch( +# # 'openfe.protocols.openmm_septop.equil_septop_method' +# # '.SepTopComplexRunUnit.execute', +# # return_value={'nc': 'file.nc', 'last_checkpoint': 'chck.nc'}, +# # ), +# mock.patch( +# 'openfe.protocols.openmm_septop.equil_septop_method' +# '.SepTopSolventSetupUnit.run', +# return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': +# 'topology.pdb'}), +# # mock.patch( +# # 'openfe.protocols.openmm_septop.equil_septop_method' +# # '.SepTopSolventRunUnit.execute', +# # return_value={'nc': 'file.nc', 'last_checkpoint': +# # 'chck.nc'}), +# ): +# dagres = gufe.protocols.execute_DAG(benzene_toluene_dag, +# shared_basedir=tmpdir, +# scratch_basedir=tmpdir, +# keep_shared=True) +# +# protocol = SepTopProtocol( +# settings=SepTopProtocol.default_settings(), +# ) +# +# res = protocol.gather([dagres]) +# +# assert isinstance(res, openfe.protocols.openmm_septop.SepTopProtocolResult) + + +class TestProtocolResult: + @pytest.fixture() + def protocolresult(self, septop_json): + d = json.loads(septop_json, + cls=gufe.tokenization.JSON_HANDLER.decoder) + + pr = openfe.ProtocolResult.from_dict(d['protocol_result']) + + return pr + + def test_reload_protocol_result(self, septop_json): + d = json.loads(septop_json, + cls=gufe.tokenization.JSON_HANDLER.decoder) + + pr = SepTopProtocolResult.from_dict(d[ + 'protocol_result']) + + assert pr + + def test_get_estimate(self, protocolresult): + est = protocolresult.get_estimate() + + assert est + assert est.m == pytest.approx(-3.03, abs=0.5) + assert isinstance(est, offunit.Quantity) + assert est.is_compatible_with(offunit.kilojoule_per_mole) + + def test_get_uncertainty(self, protocolresult): + est = protocolresult.get_uncertainty() + + assert est.m == pytest.approx(0.0, abs=0.2) + assert isinstance(est, offunit.Quantity) + assert est.is_compatible_with(offunit.kilojoule_per_mole) + + def test_get_individual(self, protocolresult): + inds = protocolresult.get_individual_estimates() + + assert isinstance(inds, dict) + assert isinstance(inds['solvent'], list) + assert isinstance(inds['complex'], list) + assert len(inds['solvent']) == len(inds['complex']) == 1 + for e, u in itertools.chain(inds['solvent'], inds['complex']): + assert e.is_compatible_with(offunit.kilojoule_per_mole) + assert u.is_compatible_with(offunit.kilojoule_per_mole) + + #ToDo: Add Results from longer test run that has this analysis + + # @pytest.mark.parametrize('key', ['solvent', 'complex']) + # def test_get_forwards_etc(self, key, protocolresult): + # far = protocolresult.get_forward_and_reverse_energy_analysis() + # + # assert isinstance(far, dict) + # assert isinstance(far[key], list) + # far1 = far[key][0] + # assert isinstance(far1, dict) + # + # for k in ['fractions', 'forward_DGs', 'forward_dDGs', + # 'reverse_DGs', 'reverse_dDGs']: + # assert k in far1 + # + # if k == 'fractions': + # assert isinstance(far1[k], np.ndarray) + # + # @pytest.mark.parametrize('key', ['solvent', 'complex']) + # def test_get_frwd_reverse_none_return(self, key, protocolresult): + # # fetch the first result of type key + # data = [i for i in protocolresult.data[key].values()][0][0] + # # set the output to None + # data.outputs['forward_and_reverse_energies'] = None + # + # # now fetch the analysis results and expect a warning + # wmsg = ("were found in the forward and reverse dictionaries " + # f"of the repeats of the {key}") + # with pytest.warns(UserWarning, match=wmsg): + # protocolresult.get_forward_and_reverse_energy_analysis() + # + @pytest.mark.parametrize('key', ['solvent', 'complex']) + def test_get_overlap_matrices(self, key, protocolresult): + ovp = protocolresult.get_overlap_matrices() + + assert isinstance(ovp, dict) + assert isinstance(ovp[key], list) + assert len(ovp[key]) == 1 + + ovp1 = ovp[key][0] + assert isinstance(ovp1['matrix'], np.ndarray) + assert ovp1['matrix'].shape == (19, 19) + + @pytest.mark.parametrize('key', ['solvent', 'complex']) + def test_get_replica_transition_statistics(self, key, protocolresult): + rpx = protocolresult.get_replica_transition_statistics() + + assert isinstance(rpx, dict) + assert isinstance(rpx[key], list) + assert len(rpx[key]) == 1 + rpx1 = rpx[key][0] + assert 'eigenvalues' in rpx1 + assert 'matrix' in rpx1 + assert rpx1['eigenvalues'].shape == (19,) + assert rpx1['matrix'].shape == (19, 19) + + @pytest.mark.parametrize('key', ['solvent', 'complex']) + def test_equilibration_iterations(self, key, protocolresult): + eq = protocolresult.equilibration_iterations() + + assert isinstance(eq, dict) + assert isinstance(eq[key], list) + assert len(eq[key]) == 1 + assert all(isinstance(v, float) for v in eq[key]) + + @pytest.mark.parametrize('key', ['solvent', 'complex']) + def test_production_iterations(self, key, protocolresult): + prod = protocolresult.production_iterations() + + assert isinstance(prod, dict) + assert isinstance(prod[key], list) + assert len(prod[key]) == 1 + assert all(isinstance(v, float) for v in prod[key]) + + def test_filenotfound_replica_states(self, protocolresult): + errmsg = "File could not be found" + + with pytest.raises(ValueError, match=errmsg): + protocolresult.get_replica_states() From de35e3f9445798e8d38f8c574e9e603f3050ead8 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 20 Dec 2024 02:10:28 +0000 Subject: [PATCH 117/163] Addressing reviews --- .../restraint_utils/geometry/boresch.py | 61 +++++++++++++++---- .../restraint_utils/geometry/harmonic.py | 4 +- .../restraint_utils/geometry/utils.py | 11 +++- .../restraint_utils/openmm/omm_restraints.py | 7 ++- 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py index 8a4eaaceb..4fb4b45b9 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -114,7 +114,10 @@ def _sort_by_distance_from_atom( def _bonded_angles_from_pool( - rdmol: Chem.Mol, atom_idx: int, atom_pool: list[int] + rdmol: Chem.Mol, + atom_idx: int, + atom_pool: list[int], + aromatic_only: bool, ) -> list[tuple[int, int, int]]: """ Get all bonded angles starting from ``atom_idx`` from a pool of atoms. @@ -127,11 +130,19 @@ def _bonded_angles_from_pool( The index of the atom to search angles from. atom_pool : list[int] The list of indices to pick possible angle partners from. + aromatic_only : bool + Prune any angles that include non-aromatic bonds. Returns ------- list[tuple[int, int, int]] A list of tuples containing all the angles. + + Notes + ----- + * In the original SepTop code at3 is picked as directly bonded to at1. + By comparison here we instead follow the case that at3 is bonded to + at2 but not bonded to at1. """ angles = [] @@ -150,14 +161,28 @@ def _bonded_angles_from_pool( for at3 in atom_pool: if at3 != atom_idx and at3 in at2_neighbors: angles.append((atom_idx, at2, at3)) + + if aromatic_only: + aromatic_rings = get_aromatic_rings(rdmol) + + def _belongs_to_ring(angle, aromatic_rings): + for ring in aromatic_rings: + if all(a in ring for a in angle): + return True + return False + + for angle in angles: + if not _belongs_to_ring(angle, aromatic_rings): + angles.remove(angle) + return angles -def _get_atom_pool( +def _get_guest_atom_pool( rdmol: Chem.Mol, rmsf: npt.NDArray, rmsf_cutoff: unit.Quantity -) -> Optional[set[int]]: +) -> tuple[Optional[set[int]], bool]: """ Filter atoms based on rmsf & rings, defaulting to heavy atoms if there are not enough. @@ -175,12 +200,16 @@ def _get_atom_pool( Returns ------- atom_pool : Optional[set[int]] + A pool of candidate atoms. + ring_atoms_only : bool + True if only ring atoms were selected. """ # Get a list of all the aromatic rings # Note: no need to keep track of rings because we'll filter by # bonded terms after, so if we only keep rings then all the bonded # atoms should be within the same ring system. atom_pool: set[tuple[int]] = set() + ring_atoms_only: bool = True for ring in get_aromatic_rings(rdmol): max_rmsf = rmsf[list(ring)].max() if max_rmsf < rmsf_cutoff: @@ -188,12 +217,13 @@ def _get_atom_pool( # if we don't have enough atoms just get all the heavy atoms if len(atom_pool) < 3: + ring_atoms_only = False heavy_atoms = get_heavy_atom_idxs(rdmol) atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) if len(atom_pool) < 3: - return None + return None, False - return atom_pool + return atom_pool, ring_atoms_only def find_guest_atom_candidates( @@ -250,7 +280,7 @@ def find_guest_atom_candidates( u.trajectory[-1] # forward to the last frame # 1. Get the pool of atoms to work with - atom_pool = _get_atom_pool(rdmol, rmsf, rmsf_cutoff) + atom_pool, rings_only = _get_guest_atom_pool(rdmol, rmsf, rmsf_cutoff) if atom_pool is None: # We don't have enough atoms so we raise an error @@ -266,7 +296,12 @@ def find_guest_atom_candidates( # 4. Get a list of probable angles angles_list = [] for atom in sorted_atom_pool: - angles = _bonded_angles_from_pool(rdmol, atom, sorted_atom_pool) + angles = _bonded_angles_from_pool( + rdmol=rdmol, + atom_idx=atom, + atom_pool=sorted_atom_pool, + aromatic_only=rings_only, + ) for angle in angles: # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] @@ -342,11 +377,11 @@ def find_host_atom_candidates( # 1. Get the RMSF & filter rmsf = get_local_rmsf(host_ag2) - protein_ag3 = host_ag2.atoms[rmsf < rmsf_cutoff] + host_ag3 = host_ag2.atoms[rmsf < rmsf_cutoff] # 2. Search of atoms within the min/max cutoff atom_finder = FindHostAtoms( - protein_ag3, u.atoms[l1_idx], min_distance, max_distance + host_ag3, u.atoms[l1_idx], min_distance, max_distance ) atom_finder.run() return atom_finder.results.host_idxs @@ -599,9 +634,9 @@ def _find_host_anchor( for i, valid_h0 in enumerate(h0_eval.results.valid): if valid_h0: - g1g2h0_atoms = guest_atoms.atoms[1:] + host_atom_pool.atoms[i] + g1g0h0_atoms = guest_atoms.atoms[:2] + host_atom_pool.atoms[i] h1_eval = EvaluateHostAtoms1( - g1g2h0_atoms, + g1g0h0_atoms, host_atom_pool, minimum_distance, angle_force_constant, @@ -617,7 +652,7 @@ def _find_host_anchor( temperature, ) - if any(h2_eval.ressults.valid): + if any(h2_eval.results.valid): d1_avgs = np.array([d.mean() for d in h2_eval.results.distances1]) d2_avgs = np.array([d.mean() for d in h2_eval.results.distances2]) dsum_avgs = d1_avgs + d2_avgs @@ -828,7 +863,7 @@ def find_boresch_restraint( topology=topology, trajectory=trajectory, host_idxs=host_idxs, - l1_idx=guest_anchor, + l1_idx=guest_anchor[0], host_selection=host_selection, dssp_filter=dssp_filter, rmsf_cutoff=rmsf_cutoff, diff --git a/openfe/protocols/restraint_utils/geometry/harmonic.py b/openfe/protocols/restraint_utils/geometry/harmonic.py index 81e2f22b2..1cc8fb0e0 100644 --- a/openfe/protocols/restraint_utils/geometry/harmonic.py +++ b/openfe/protocols/restraint_utils/geometry/harmonic.py @@ -96,12 +96,12 @@ def get_molecule_centers_restraint( molA_rdmol : Chem.Mol An RDKit Molecule for the first molecule. molB_rdmol : Chem.Mol - An RDKit Molecule for the first molecule. + An RDKit Molecule for the second molecule. molA_idxs : list[int] The indices of the first molecule in the system. Note we assume these to be sorted in the same order as the input rdmol. molB_idxs : list[int] - The indices of the first molecule in the system. Note we assume these + The indices of the second molecule in the system. Note we assume these to be sorted in the same order as the input rdmol. Returns diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 988a31cfe..d27e3156e 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -8,6 +8,7 @@ * Add relevant duecredit entries. """ from typing import Union, Optional +from itertools import combinations import numpy as np import numpy.typing as npt from scipy.stats import circvar @@ -134,14 +135,22 @@ def get_aromatic_rings(rdmol: Chem.Mol) -> list[tuple[int, ...]]: list[tuple[int]] List of tuples for each ring. """ + ringinfo = rdmol.GetRingInfo() arom_idxs = get_aromatic_atom_idxs(rdmol) aromatic_rings = [] + # Add to the aromatic_rings list if all the atoms in a ring are aromatic for ring in ringinfo.AtomRings(): if all(a in arom_idxs for a in ring): - aromatic_rings.append(ring) + aromatic_rings.append(set(ring)) + + # Reduce the ring list by merging any rings that have colliding atoms + for x, y in combinations(aromatic_rings, 2): + if not x.isdisjoint(y): + x.update(y) + aromatic_rings.remove(y) return aromatic_rings diff --git a/openfe/protocols/restraint_utils/openmm/omm_restraints.py b/openfe/protocols/restraint_utils/openmm/omm_restraints.py index 8df9cb837..352bbd9bd 100644 --- a/openfe/protocols/restraint_utils/openmm/omm_restraints.py +++ b/openfe/protocols/restraint_utils/openmm/omm_restraints.py @@ -62,13 +62,16 @@ class RestraintParameterState(GlobalParameterState): ``lambda_restraints_{parameters_name_suffix}` instead of just ``lambda_restraints``. lambda_restraints : Optional[float] - The strength of the restraint. If defined, must be between 0 and 1. + The scaling parameter for the restraint. If defined, + must be between 0 and 1. In most cases, a value of 1 indicates that the + restraint is fully turned on, whilst a value of 0 indicates that it is + innactive. Acknowledgement --------------- Partially reproduced from Yank. """ - + # We set the standard system to a fully interacting restraint lambda_restraints = GlobalParameterState.GlobalParameter( "lambda_restraints", standard_value=1.0 ) From d1d1b04eb5d9659fb44cf573c6c549d55014eb9d Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 20 Dec 2024 10:29:33 +0100 Subject: [PATCH 118/163] debug failing test --- openfe/tests/protocols/test_openmm_septop.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 67b1f1f46..55d08493d 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -656,6 +656,8 @@ def test_unit_tagging(benzene_toluene_dag, tmpdir): solv_repeats = set() complex_repeats = set() for ret in results: + print(ret) + print(ret.outputs) assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs['generation'] == 0 if ret.outputs['simtype'] == 'complex': From 153ffec504a8c890eb3a9eb54cf04c349015597d Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 20 Dec 2024 11:01:18 +0100 Subject: [PATCH 119/163] Test restraints closer --- openfe/protocols/openmm_septop/femto_restraints.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 1d074ce33..c9600655e 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -525,8 +525,9 @@ def select_receptor_idxs( r3_distances_per_frame.append(numpy.hstack([r3_r_distances, r3_l_distances])) # chosen to match the SepTop reference implementation at commit 3705ba5 - max_distance = 0.8 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) - + # Edit to make them be closer + max_distance = 0.5 * (receptor.unitcell_lengths.mean(axis=0).min(axis=-1) / 2) + print(max_distance) r3_distances_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) max_distance_mask = r3_distances_avg.max(axis=-1) < max_distance From 9efab61f63f21b22751fbe39c2da2739f7341772 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 20 Dec 2024 11:02:41 +0100 Subject: [PATCH 120/163] Test restraints closer 2 --- openfe/protocols/openmm_septop/femto_restraints.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index c9600655e..ae2a82f0d 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -582,7 +582,8 @@ def check_receptor_idxs( ] r3_distance_avg = numpy.stack(r3_distances_per_frame).mean(axis=0) - max_distance = 0.8 * (receptor.unitcell_lengths[-1][0] / 2) + max_distance = 0.5 * (receptor.unitcell_lengths[-1][0] / 2) + print(max_distance) is_valid_distance = r3_distance_avg.max(axis=-1) < max_distance print(is_valid_r1, is_valid_r2, is_valid_r3, is_valid_distance) From 7c502c76e03b0f5977636a94ee39e8d16f3789ec Mon Sep 17 00:00:00 2001 From: IAlibay Date: Tue, 7 Jan 2025 17:54:55 +0000 Subject: [PATCH 121/163] Add a todo from last year --- openfe/protocols/openmm_rfe/equil_rfe_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_rfe/equil_rfe_methods.py b/openfe/protocols/openmm_rfe/equil_rfe_methods.py index 2b80370e0..b74bd3342 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_methods.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_methods.py @@ -692,7 +692,7 @@ def run(self, *, dry=False, verbose=True, # Extract relevant settings protocol_settings: RelativeHybridTopologyProtocolSettings = self._inputs['protocol'].settings stateA = self._inputs['stateA'] - stateB = self._inputs['stateB'] + stateB = self._inputs['stateB'] # TODO: open an issue about this not being used. mapping = self._inputs['ligandmapping'] forcefield_settings: settings.OpenMMSystemGeneratorFFSettings = protocol_settings.forcefield_settings From a61268bbdc2f6aa3d99dd1d8d93d4885b93aca4e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 8 Jan 2025 10:31:16 +0100 Subject: [PATCH 122/163] Fix tests --- openfe/protocols/openmm_septop/femto_restraints.py | 2 +- openfe/tests/protocols/test_openmm_septop.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index ae2a82f0d..6cbf4279b 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -716,7 +716,7 @@ def create_boresch_restraint( for key, value in [ ("k_dist_a", k_distance), - ("k_theta_a", k_theta * 10), + ("k_theta_a", k_theta * 2), ("k_theta_b", k_theta), ("k_phi_a", k_theta), ("k_phi_b", k_theta), diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 55d08493d..186856296 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -626,6 +626,7 @@ def test_unit_tagging(benzene_toluene_dag, tmpdir): # test that executing the units includes correct gen and repeat info dag_units = benzene_toluene_dag.protocol_units + print(dag_units) with ( mock.patch('openfe.protocols.openmm_septop.equil_septop_method.SepTopComplexSetupUnit.run', @@ -649,15 +650,14 @@ def test_unit_tagging(benzene_toluene_dag, tmpdir): results = [] # For right now only testing the two SetupUnits #ToDo: Add tests for RunUnits - for u in dag_units[:2]: - ret = u.execute(context=gufe.Context(tmpdir, tmpdir)) - results.append(ret) + for u in dag_units: + if isinstance(u, SepTopSolventSetupUnit) or isinstance(u, SepTopComplexSetupUnit): + ret = u.execute(context=gufe.Context(tmpdir, tmpdir)) + results.append(ret) solv_repeats = set() complex_repeats = set() for ret in results: - print(ret) - print(ret.outputs) assert isinstance(ret, gufe.ProtocolUnitResult) assert ret.outputs['generation'] == 0 if ret.outputs['simtype'] == 'complex': From 91599f099974fd74ac393713866ea78801cd7779 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 8 Jan 2025 10:44:07 +0100 Subject: [PATCH 123/163] Some mypy fixes --- openfe/protocols/openmm_septop/equil_septop_method.py | 8 ++++---- openfe/protocols/openmm_septop/femto_restraints.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 3e6ea85c4..492db1160 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -993,7 +993,7 @@ def _add_restraints( topology: Optional[openmm.app.Topology], ligand_1: Optional[OFFMolecule], ligand_2: Optional[OFFMolecule], - settings: dict[str, SettingsBaseModel], + settings: Optional[dict[str, SettingsBaseModel]], ligand_1_ref_idxs: tuple[int, int, int], ligand_2_ref_idxs: tuple[int, int, int], ligand_1_idxs: tuple[int, int, int], @@ -1239,9 +1239,9 @@ def _add_restraints( topology, ligand_1, ligand_2, - settings, - ligand_1_ref_idxs: list[int], - ligand_2_ref_idxs: list[int], + settings: Optional[dict[str, SettingsBaseModel]], + ligand_1_ref_idxs: tuple[int, int, int], + ligand_2_ref_idxs: tuple[int, int, int], ligand_1_idxs: tuple[int, int, int], ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 6cbf4279b..cc3f6e77d 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -193,7 +193,7 @@ def select_ligand_idxs( ligand_2, # OpenFF Molecule ligand_1_queries: tuple[str, str, str] | None = None, ligand_2_queries: tuple[str, str, str] | None = None, -) -> tuple[tuple[int, int, int], tuple[int, int, int] | None]: +) -> tuple[tuple[int, int, int], tuple[int, int, int]]: """Returns the indices of the reference atoms that may be used to align ligands. Args: From a046e86d2296bf6eaca8b7f859fb069fa5333011 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 8 Jan 2025 11:02:53 +0100 Subject: [PATCH 124/163] small fixes --- openfe/protocols/openmm_septop/base.py | 8 ++++---- openfe/protocols/openmm_septop/equil_septop_method.py | 10 +++++----- openfe/protocols/openmm_septop/femto_restraints.py | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 607050e10..df3723ef5 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -567,10 +567,10 @@ def _set_positions( def _add_restraints( system: openmm.System, positions: simtk.unit.Quantity, - topology: Optional[openmm.app.Topology], - ligand_1: Optional[OFFMolecule], - ligand_2: Optional[OFFMolecule], - settings: Optional[dict[str, SettingsBaseModel]], + topology: openmm.app.Topology, + ligand_1: OFFMolecule, + ligand_2: OFFMolecule, + settings: dict[str, SettingsBaseModel], ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology ligand_1_idxs: tuple[int, int, int], # indices from the full topology diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 492db1160..a8d497883 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -990,10 +990,10 @@ def _update_positions( def _add_restraints( system: openmm.System, positions: simtk.unit.Quantity, - topology: Optional[openmm.app.Topology], - ligand_1: Optional[OFFMolecule], - ligand_2: Optional[OFFMolecule], - settings: Optional[dict[str, SettingsBaseModel]], + topology: openmm.app.Topology, + ligand_1: OFFMolecule, + ligand_2: OFFMolecule, + settings: dict[str, SettingsBaseModel], ligand_1_ref_idxs: tuple[int, int, int], ligand_2_ref_idxs: tuple[int, int, int], ligand_1_idxs: tuple[int, int, int], @@ -1239,7 +1239,7 @@ def _add_restraints( topology, ligand_1, ligand_2, - settings: Optional[dict[str, SettingsBaseModel]], + settings: dict[str, SettingsBaseModel], ligand_1_ref_idxs: tuple[int, int, int], ligand_2_ref_idxs: tuple[int, int, int], ligand_1_idxs: tuple[int, int, int], diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index cc3f6e77d..384b2e48b 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -118,7 +118,7 @@ def _are_collinear( def _create_ligand_queries( ligand, snapshots: list[openmm.unit.Quantity] | None -) -> tuple[str, str, str]: +) -> tuple[int, int, int]: """Selects three atoms from a ligand for use in Boresch-likes restraints using the method described by Baumann et al. @@ -283,18 +283,18 @@ def _filter_receptor_atoms( "E"] min_motif_size = {"H": min_helix_size, "E": min_sheet_size} - residues_to_keep = [] + residues_to_keep: list[int | None] = [] structure = structure[skip_residues_start: -(skip_residues_end + 1)] for motif, idxs in itertools.groupby(enumerate(structure), lambda x: x[1]): - idxs = [(idx + skip_residues_start, motif) for idx, motif in idxs] + idxs_new = [(idx + skip_residues_start, motif) for idx, motif in idxs] - if motif not in allowed_motifs or len(idxs) < min_motif_size[motif]: + if motif not in allowed_motifs or len(idxs_new) < min_motif_size[motif]: continue # discard the first and last 3 residues of the helix / sheet - start_idx, end_idx = idxs[0][0] + 3, idxs[-1][0] - 3 + start_idx, end_idx = idxs_new[0][0] + 3, idxs_new[-1][0] - 3 residues_to_keep.extend( f"resid {idx}" for idx in range(start_idx, end_idx + 1)) From 8d8e56d0ea79fd3ac79bd1100bf1edd6bcac4e9e Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 8 Jan 2025 11:15:51 +0100 Subject: [PATCH 125/163] More mypy fixes --- openfe/protocols/openmm_septop/base.py | 13 ++++++------- openfe/protocols/openmm_septop/femto_restraints.py | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index df3723ef5..bc39b2b4a 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -611,7 +611,7 @@ def get_system( self, solv_comp: SolventComponent, prot_comp: ProteinComponent, - smc_comp: dict[SmallMoleculeComponent,OFFMolecule], + smc_comp: dict[SmallMoleculeComponent, OFFMolecule], settings: dict[str, SettingsBaseModel], ): """ @@ -655,8 +655,8 @@ def get_system_AB( self, solv_comp: SolventComponent, system_modeller_A: openmm.app.Modeller, - smc_comps_AB: dict[SmallMoleculeComponent,OFFMolecule], - smc_off_B: dict[SmallMoleculeComponent,OFFMolecule], + smc_comps_AB: dict[SmallMoleculeComponent, OFFMolecule], + smc_off_B: dict[SmallMoleculeComponent, OFFMolecule], settings: dict[str, SettingsBaseModel], shared_basepath: pathlib.Path, ): @@ -822,7 +822,7 @@ def run(self, dry=False, verbose=True, # Update positions from AB system positions_AB[all_atom_ids_A[0]:all_atom_ids_A[-1] + 1, :] = equ_positions_A positions_AB[atom_indices_AB_B[0]:atom_indices_AB_B[-1] + 1, - :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] + :] = updated_positions_B[atom_indices_B[0]:atom_indices_B[-1] + 1] # 9. Create the alchemical system self.logger.info("Creating the alchemical system and applying restraints") @@ -931,6 +931,7 @@ def _handle_settings(self): """ ... + @abc.abstractmethod def _get_lambda_schedule( self, settings: dict[str, SettingsBaseModel] ) -> dict[str, npt.NDArray]: @@ -952,7 +953,6 @@ def _get_lambda_schedule( """ ... - def _get_states( self, alchemical_system: openmm.System, @@ -986,7 +986,7 @@ def _get_states( A list of ThermodynamicState for each replica in the system. """ alchemical_state = SepTopParameterState.from_system(alchemical_system) - + # Set up the system constants temperature = settings['thermo_settings'].temperature pressure = settings['thermo_settings'].pressure @@ -1073,7 +1073,6 @@ def _get_reporter( return reporter - def _get_ctx_caches( self, engine_settings: OpenMMEngineSettings diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 384b2e48b..25cd2120e 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -191,8 +191,8 @@ def _create_ligand_queries( def select_ligand_idxs( ligand_1, # OpenFF Molecule ligand_2, # OpenFF Molecule - ligand_1_queries: tuple[str, str, str] | None = None, - ligand_2_queries: tuple[str, str, str] | None = None, + ligand_1_queries: tuple[int, int, int] | None = None, + ligand_2_queries: tuple[int, int, int] | None = None, ) -> tuple[tuple[int, int, int], tuple[int, int, int]]: """Returns the indices of the reference atoms that may be used to align ligands. @@ -283,7 +283,7 @@ def _filter_receptor_atoms( "E"] min_motif_size = {"H": min_helix_size, "E": min_sheet_size} - residues_to_keep: list[int | None] = [] + residues_to_keep: list[str | None] = [] structure = structure[skip_residues_start: -(skip_residues_end + 1)] From 6dafe6bb73cb2acdbb9167ac59ff9f469568c0d2 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 8 Jan 2025 12:38:21 +0100 Subject: [PATCH 126/163] Add gather test --- openfe/protocols/openmm_septop/base.py | 1 + .../openmm_septop/femto_restraints.py | 3 +- openfe/tests/protocols/test_openmm_septop.py | 143 ++++++++++-------- 3 files changed, 81 insertions(+), 66 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index bc39b2b4a..4b930c127 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1317,6 +1317,7 @@ def _run_simulation( return None + def _execute( self, ctx: gufe.Context, *, setup, verbose=True, **kwargs, ) -> dict[str, Any]: diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 25cd2120e..535bf2c60 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -298,7 +298,8 @@ def _filter_receptor_atoms( residues_to_keep.extend( f"resid {idx}" for idx in range(start_idx, end_idx + 1)) - rigid_backbone_idxs = backbone.top.select(" ".join(residues_to_keep)) + if residues_to_keep: + rigid_backbone_idxs = backbone.top.select(" ".join(residues_to_keep)) if len(rigid_backbone_idxs) == 0: raise ValueError("no suitable receptor atoms could be found") diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 186856296..41db5ceb1 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -624,37 +624,42 @@ def benzene_toluene_dag(benzene_complex_system, toluene_complex_system): def test_unit_tagging(benzene_toluene_dag, tmpdir): # test that executing the units includes correct gen and repeat info - dag_units = benzene_toluene_dag.protocol_units - print(dag_units) - with ( - mock.patch('openfe.protocols.openmm_septop.equil_septop_method.SepTopComplexSetupUnit.run', - return_value={'system': 'system.xml.bz2', 'topology': - 'topology.pdb'}), - # mock.patch( - # 'openfe.protocols.openmm_septop.equil_septop_method' - # '.SepTopComplexRunUnit.execute', - # return_value={'nc': 'file.nc', 'last_checkpoint': 'chck.nc'}, - # ), - mock.patch( - 'openfe.protocols.openmm_septop.equil_septop_method' - '.SepTopSolventSetupUnit.run', - return_value={'system': 'system.xml.bz2', 'topology': - 'topology.pdb'}), - # mock.patch( - # 'openfe.protocols.openmm_septop.equil_septop_method' - # '.SepTopSolventRunUnit.execute', - # return_value={'nc': 'file.nc', 'last_checkpoint': 'chck.nc'}), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopComplexSetupUnit.run', + return_value={'system': pathlib.Path('system.xml.bz2'), + 'topology': + 'topology.pdb'}), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopComplexRunUnit._execute', + return_value={'repeat_id': 0, + 'generation': 0, + 'simtype': 'complex', + 'nc': 'file.nc', + 'last_checkpoint': 'chck.nc'}, + ), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopSolventSetupUnit.run', + return_value={'system': pathlib.Path('system.xml.bz2'), + 'topology': + 'topology.pdb'}), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopSolventRunUnit._execute', + return_value={'repeat_id': 0, + 'generation': 0, + 'simtype': 'solvent', + 'nc': 'file.nc', + 'last_checkpoint': 'chck.nc'}), ): results = [] - # For right now only testing the two SetupUnits - #ToDo: Add tests for RunUnits for u in dag_units: - if isinstance(u, SepTopSolventSetupUnit) or isinstance(u, SepTopComplexSetupUnit): - ret = u.execute(context=gufe.Context(tmpdir, tmpdir)) - results.append(ret) - + ret = u.execute(context=gufe.Context(tmpdir, tmpdir)) + results.append(ret) solv_repeats = set() complex_repeats = set() for ret in results: @@ -665,45 +670,53 @@ def test_unit_tagging(benzene_toluene_dag, tmpdir): else: solv_repeats.add(ret.outputs['repeat_id']) # Repeat ids are random ints so just check their lengths - assert len(complex_repeats) == len(solv_repeats) == 1 - - -# def test_gather(benzene_toluene_dag, tmpdir): -# # check that .gather behaves as expected -# with ( -# mock.patch( -# 'openfe.protocols.openmm_septop.equil_septop_method' -# '.SepTopComplexSetupUnit.run', -# return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': -# 'topology.pdb'}), -# # mock.patch( -# # 'openfe.protocols.openmm_septop.equil_septop_method' -# # '.SepTopComplexRunUnit.execute', -# # return_value={'nc': 'file.nc', 'last_checkpoint': 'chck.nc'}, -# # ), -# mock.patch( -# 'openfe.protocols.openmm_septop.equil_septop_method' -# '.SepTopSolventSetupUnit.run', -# return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': -# 'topology.pdb'}), -# # mock.patch( -# # 'openfe.protocols.openmm_septop.equil_septop_method' -# # '.SepTopSolventRunUnit.execute', -# # return_value={'nc': 'file.nc', 'last_checkpoint': -# # 'chck.nc'}), -# ): -# dagres = gufe.protocols.execute_DAG(benzene_toluene_dag, -# shared_basedir=tmpdir, -# scratch_basedir=tmpdir, -# keep_shared=True) -# -# protocol = SepTopProtocol( -# settings=SepTopProtocol.default_settings(), -# ) -# -# res = protocol.gather([dagres]) -# -# assert isinstance(res, openfe.protocols.openmm_septop.SepTopProtocolResult) + # Length is two, one for Setup, one for the Run Unit + assert len(complex_repeats) == len(solv_repeats) == 2 + + +def test_gather(benzene_toluene_dag, tmpdir): + # check that .gather behaves as expected + with ( + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopComplexSetupUnit.run', + return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': + 'topology.pdb'}), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopComplexRunUnit._execute', + return_value={'repeat_id': 0, + 'generation': 0, + 'simtype': 'complex', + 'nc': 'file.nc', + 'last_checkpoint': 'chck.nc'}, + ), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopSolventSetupUnit.run', + return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': + 'topology.pdb'}), + mock.patch( + 'openfe.protocols.openmm_septop.equil_septop_method' + '.SepTopSolventRunUnit._execute', + return_value={'repeat_id': 0, + 'generation': 0, + 'simtype': 'solvent', + 'nc': 'file.nc', + 'last_checkpoint': 'chck.nc'}), + ): + dagres = gufe.protocols.execute_DAG(benzene_toluene_dag, + shared_basedir=tmpdir, + scratch_basedir=tmpdir, + keep_shared=True) + + protocol = SepTopProtocol( + settings=SepTopProtocol.default_settings(), + ) + + res = protocol.gather([dagres]) + + assert isinstance(res, openfe.protocols.openmm_septop.SepTopProtocolResult) class TestProtocolResult: From b24ea6b945a2dc6370569bd8835f3fd66c3a5a9b Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 10 Jan 2025 15:25:18 +0100 Subject: [PATCH 127/163] Some restaints updates --- openfe/protocols/openmm_septop/femto_restraints.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 535bf2c60..05a45ff09 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -163,7 +163,6 @@ def _create_ligand_queries( distances = [path_lengths[(center_idx, atom_idx)] for atom_idx in open_list] closest_idx = open_list[numpy.argmin(distances)] - print(closest_idx) if len(cycles) >= 1: # restrict the list of reference atoms to select from to those that are in the @@ -708,16 +707,14 @@ def create_boresch_restraint( force.addGlobalParameter(ctx_parameter, 1.0) geometry = _compute_boresch_geometry(receptor_atoms, ligand_atoms, coords) - print(geometry.dist_0) # Scale the k_theta_a distance_0 = 5.0 * _ANGSTROM # based on original SepTop implementation. scale = (geometry.dist_0 / distance_0) ** 2 - print(scale) parameters = [] for key, value in [ ("k_dist_a", k_distance), - ("k_theta_a", k_theta * 2), + ("k_theta_a", k_theta * 2 * 10), ("k_theta_b", k_theta), ("k_phi_a", k_theta), ("k_phi_b", k_theta), From ee11781c9ab9d7f46d86af9af830519c99c8cd4c Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 13 Jan 2025 14:31:33 +0100 Subject: [PATCH 128/163] Dry run and make run function in the RunUnit --- openfe/protocols/openmm_septop/__init__.py | 2 + openfe/protocols/openmm_septop/base.py | 197 +++++++++++++++--- .../openmm_septop/equil_septop_method.py | 40 ++++ openfe/tests/protocols/test_openmm_septop.py | 27 +++ 4 files changed, 238 insertions(+), 28 deletions(-) diff --git a/openfe/protocols/openmm_septop/__init__.py b/openfe/protocols/openmm_septop/__init__.py index dc88761ce..6f806ce8a 100644 --- a/openfe/protocols/openmm_septop/__init__.py +++ b/openfe/protocols/openmm_septop/__init__.py @@ -11,6 +11,8 @@ SepTopProtocolResult, SepTopComplexSetupUnit, SepTopSolventSetupUnit, + SepTopSolventRunUnit, + SepTopComplexRunUnit, ) __all__ = [ diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 4b930c127..072d60208 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -590,11 +590,11 @@ def _add_restraints( @staticmethod def get_smc_comps( alchem_comps: dict[str, list[Component]], - smc_comps: dict[SmallMoleculeComponent,OFFMolecule], - ) -> tuple[dict[SmallMoleculeComponent,OFFMolecule], - dict[SmallMoleculeComponent,OFFMolecule], - dict[SmallMoleculeComponent,OFFMolecule], - dict[SmallMoleculeComponent,OFFMolecule]]: + smc_comps: dict[SmallMoleculeComponent, OFFMolecule], + ) -> tuple[dict[SmallMoleculeComponent, OFFMolecule], + dict[SmallMoleculeComponent, OFFMolecule], + dict[SmallMoleculeComponent, OFFMolecule], + dict[SmallMoleculeComponent, OFFMolecule]]: # 6. Get smcs for the different states and the common smcs smc_off_A = {m: m.to_openff() for m in alchem_comps['stateA']} smc_off_B = {m: m.to_openff() for m in alchem_comps['stateB']} @@ -888,6 +888,37 @@ class BaseSepTopRunUnit(gufe.ProtocolUnit): Base class for running ligand SepTop RBFE free energy transformations. """ + def _prepare( + self, verbose: bool, + scratch_basepath: Optional[pathlib.Path], + shared_basepath: Optional[pathlib.Path], + ): + """ + Set basepaths and do some initial logging. + + Parameters + ---------- + verbose : bool + Verbose output of the simulation progress. Output is provided via + INFO level logging. + basepath : Optional[pathlib.Path] + Optional base path to write files to. + """ + self.verbose = verbose + + if self.verbose: + self.logger.info("setting up alchemical system") + + # set basepaths + def _set_optional_path(basepath): + if basepath is None: + return pathlib.Path('.') + return basepath + + self.scratch_basepath = _set_optional_path(scratch_basepath) + self.shared_basepath = _set_optional_path(shared_basepath) + + @abc.abstractmethod def _get_components(self) -> tuple[dict[str, list[Component]], Optional[gufe.SolventComponent], @@ -1018,7 +1049,6 @@ def _get_reporter( positions: openmm.unit.Quantity, simulation_settings: MultiStateSimulationSettings, output_settings: MultiStateOutputSettings, - shared_basepath: pathlib.Path, ) -> multistate.MultiStateReporter: """ Get a MultistateReporter for the simulation you are running. @@ -1047,7 +1077,7 @@ def _get_reporter( output_settings.output_indices ) - nc = shared_basepath / output_settings.output_filename + 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, @@ -1068,7 +1098,7 @@ def _get_reporter( mdt_top.subset(selection_indices), ) traj.save_pdb( - shared_basepath / output_settings.output_structure + self.shared_basepath / output_settings.output_structure ) return reporter @@ -1308,18 +1338,18 @@ def _run_simulation( reporter.close() # clean up the reporter file - fns = [shared_basepath / settings[ + fns = [self.shared_basepath / settings[ 'output_settings'].output_filename, - shared_basepath / settings[ + self.shared_basepath / settings[ 'output_settings'].checkpoint_storage_filename] for fn in fns: os.remove(fn) return None - - def _execute( - self, ctx: gufe.Context, *, setup, verbose=True, **kwargs, + def run( + self, serialized_system, serialized_topology, dry=False, verbose=True, + scratch_basepath=None, shared_basepath=None, ) -> dict[str, Any]: """ Execute the simulation part of the SepTop protocol. @@ -1337,23 +1367,14 @@ def _execute( dict : dict[str, str] Dictionary with paths to ... """ - log_system_probe(logging.INFO, paths=[ctx.scratch]) - dry = False - if ctx.shared is None: - # use cwd - shared_basepath = pathlib.Path(".") - else: - shared_basepath = ctx.shared + # 0. General preparation tasks + self._prepare(verbose, scratch_basepath, shared_basepath) + + # 1. Get components + self.logger.info("Running the SepTop simulation.") settings = self._handle_settings() alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() - if prot_comp: - phase = "complex" - else: - phase = "solvent" - - serialized_system = setup.outputs["system"] - serialized_topology = setup.outputs["topology"] system = deserialize(serialized_system) pdb = simtk.openmm.app.pdbfile.PDBFile(str(serialized_topology)) @@ -1371,7 +1392,7 @@ def _execute( pdb.topology, positions, settings['simulation_settings'], settings['output_settings'], - shared_basepath, + # shared_basepath, ) # Wrap in try/finally to avoid memory leak issues @@ -1438,3 +1459,123 @@ def _execute( 'repeat_id': self._inputs['repeat_id'], 'generation': self._inputs['generation'], 'debug': {'sampler': sampler}} + + # def _execute( + # self, ctx: gufe.Context, *, setup, dry=False, verbose=True, **kwargs, + # ) -> dict[str, Any]: + # """ + # Execute the simulation part of the SepTop protocol. + # + # Parameters + # ---------- + # ctx : gufe.protocols.protocolunit.Context + # The gufe context for the unit. + # setup : gufe.protocols.ProtocolUnit + # The SetupUnit + # verbose: bool + # + # Returns + # ------- + # dict : dict[str, str] + # Dictionary with paths to ... + # """ + # log_system_probe(logging.INFO, paths=[ctx.scratch]) + # if ctx.shared is None: + # # use cwd + # shared_basepath = pathlib.Path(".") + # else: + # shared_basepath = ctx.shared + # + # settings = self._handle_settings() + # alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() + # if prot_comp: + # phase = "complex" + # else: + # phase = "solvent" + # + # serialized_system = setup.outputs["system"] + # serialized_topology = setup.outputs["topology"] + # + # system = deserialize(serialized_system) + # pdb = simtk.openmm.app.pdbfile.PDBFile(str(serialized_topology)) + # positions = pdb.getPositions(asNumpy=True) + # lambdas = self._get_lambda_schedule(settings) + # + # # 10. Get compound and sampler states + # sampler_states, cmp_states = self._get_states( + # system, positions, settings, + # lambdas, solv_comp + # ) + # + # # 11. Create the multistate reporter & create PDB + # reporter = self._get_reporter( + # pdb.topology, positions, + # settings['simulation_settings'], + # settings['output_settings'], + # shared_basepath, + # ) + # + # # Wrap in try/finally to avoid memory leak issues + # try: + # # 12. Get context caches + # energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( + # settings['engine_settings'] + # ) + # + # # 13. Get integrator + # integrator = self._get_integrator( + # settings['integrator_settings'], + # settings['simulation_settings'], + # ) + # + # # 14. Get sampler + # sampler = self._get_sampler( + # integrator, reporter, settings['simulation_settings'], + # settings['thermo_settings'], + # cmp_states, sampler_states, + # energy_ctx_cache, sampler_ctx_cache + # ) + # + # # 15. Run simulation + # unit_result_dict = self._run_simulation( + # sampler, reporter, settings, dry, verbose, shared_basepath + # ) + # + # finally: + # # close reporter when you're done to prevent file handle clashes + # reporter.close() + # + # # clear GPU context + # # Note: use cache.empty() when openmmtools #690 is resolved + # for context in list(energy_ctx_cache._lru._data.keys()): + # del energy_ctx_cache._lru._data[context] + # for context in list(sampler_ctx_cache._lru._data.keys()): + # del sampler_ctx_cache._lru._data[context] + # # cautiously clear out the global context cache too + # for context in list( + # openmmtools.cache.global_context_cache._lru._data.keys()): + # del openmmtools.cache.global_context_cache._lru._data[context] + # + # del sampler_ctx_cache, energy_ctx_cache + # + # # Keep these around in a dry run so we can inspect things + # if not dry: + # del integrator, sampler + # + # if not dry: + # nc = shared_basepath / settings[ + # 'output_settings'].output_filename + # chk = settings['output_settings'].checkpoint_storage_filename + # return { + # 'repeat_id': self._inputs['repeat_id'], + # 'generation': self._inputs['generation'], + # 'simtype': phase, + # 'nc': nc, + # 'last_checkpoint': chk, + # **unit_result_dict, + # } + # else: + # return { + # 'repeat_id': self._inputs['repeat_id'], + # 'generation': self._inputs['generation'], + # 'debug': {'sampler': sampler}} diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index a8d497883..9c44a4a73 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1431,6 +1431,26 @@ def _get_lambda_schedule( return lambdas + def _execute( + self, ctx: gufe.Context, *, setup, **kwargs, + ) -> dict[str, Any]: + log_system_probe(logging.INFO, paths=[ctx.scratch]) + + serialized_system = setup.outputs["system"] + serialized_topology = setup.outputs["topology"] + outputs = self.run( + serialized_system, + serialized_topology, + scratch_basepath=ctx.scratch, + shared_basepath=ctx.shared) + + return { + 'repeat_id': self._inputs['repeat_id'], + 'generation': self._inputs['generation'], + 'simtype': 'solvent', + **outputs + } + class SepTopComplexRunUnit(BaseSepTopRunUnit): """ @@ -1540,3 +1560,23 @@ def _get_lambda_schedule( lambdas['lambda_restraints_B'] = lambda_restraints_B return lambdas + + def _execute( + self, ctx: gufe.Context, *, setup, **kwargs, + ) -> dict[str, Any]: + log_system_probe(logging.INFO, paths=[ctx.scratch]) + + serialized_system = setup.outputs["system"] + serialized_topology = setup.outputs["topology"] + outputs = self.run( + serialized_system, + serialized_topology, + scratch_basepath=ctx.scratch, + shared_basepath=ctx.shared) + + return { + 'repeat_id': self._inputs['repeat_id'], + 'generation': self._inputs['generation'], + 'simtype': 'complex', + **outputs + } diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 41db5ceb1..405aaaecb 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -10,6 +10,7 @@ SepTopProtocol, SepTopComplexSetupUnit, SepTopSolventSetupUnit, + SepTopSolventRunUnit, SepTopProtocolResult, ) from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference @@ -22,6 +23,7 @@ import gufe from unittest import mock import json +import mdtraj as md import itertools import numpy as np @@ -622,6 +624,31 @@ def benzene_toluene_dag(benzene_complex_system, toluene_complex_system): return protocol.create(stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None) +def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): + + prot_units = list(benzene_toluene_dag.protocol_units) + + assert len(prot_units) == 4 + + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + sol_run_unit = [u for u in prot_units + if isinstance(u, SepTopSolventRunUnit)] + + assert len(solv_setup_unit) == 1 + assert len(sol_run_unit) == 1 + + with tmpdir.as_cwd(): + solv_setup_output = solv_setup_unit[0].run(dry=True) + serialized_topology = solv_setup_output['topology'] + serialized_system = solv_setup_output['system'] + pdb = md.load_pdb(serialized_topology) + assert pdb.n_atoms == 4481 + solv_run = sol_run_unit[0].run( + serialized_system, serialized_topology, dry=True)['debug']['sampler'] + assert solv_run.is_periodic + + def test_unit_tagging(benzene_toluene_dag, tmpdir): # test that executing the units includes correct gen and repeat info dag_units = benzene_toluene_dag.protocol_units From 06b04a23f5031b5a7bccbc432dce1a75aef2bcd4 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 13 Jan 2025 14:33:34 +0100 Subject: [PATCH 129/163] Delete commented out parts --- openfe/protocols/openmm_septop/base.py | 133 ++----------------------- 1 file changed, 7 insertions(+), 126 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 072d60208..33724d19c 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1352,14 +1352,16 @@ def run( scratch_basepath=None, shared_basepath=None, ) -> dict[str, Any]: """ - Execute the simulation part of the SepTop protocol. + Run the simulation part of the SepTop protocol. Parameters ---------- - ctx : gufe.protocols.protocolunit.Context - The gufe context for the unit. - setup : gufe.protocols.ProtocolUnit - The SetupUnit + serialized_system: pathlib.Path + Path to the serialized OpenMM system + serialized_topology: pathlib.Path + Path to the serialized topology of the system + dry: bool + Whether or not to run a dry run verbose: bool Returns @@ -1392,7 +1394,6 @@ def run( pdb.topology, positions, settings['simulation_settings'], settings['output_settings'], - # shared_basepath, ) # Wrap in try/finally to avoid memory leak issues @@ -1459,123 +1460,3 @@ def run( 'repeat_id': self._inputs['repeat_id'], 'generation': self._inputs['generation'], 'debug': {'sampler': sampler}} - - # def _execute( - # self, ctx: gufe.Context, *, setup, dry=False, verbose=True, **kwargs, - # ) -> dict[str, Any]: - # """ - # Execute the simulation part of the SepTop protocol. - # - # Parameters - # ---------- - # ctx : gufe.protocols.protocolunit.Context - # The gufe context for the unit. - # setup : gufe.protocols.ProtocolUnit - # The SetupUnit - # verbose: bool - # - # Returns - # ------- - # dict : dict[str, str] - # Dictionary with paths to ... - # """ - # log_system_probe(logging.INFO, paths=[ctx.scratch]) - # if ctx.shared is None: - # # use cwd - # shared_basepath = pathlib.Path(".") - # else: - # shared_basepath = ctx.shared - # - # settings = self._handle_settings() - # alchem_comps, solv_comp, prot_comp, smc_comps = self._get_components() - # if prot_comp: - # phase = "complex" - # else: - # phase = "solvent" - # - # serialized_system = setup.outputs["system"] - # serialized_topology = setup.outputs["topology"] - # - # system = deserialize(serialized_system) - # pdb = simtk.openmm.app.pdbfile.PDBFile(str(serialized_topology)) - # positions = pdb.getPositions(asNumpy=True) - # lambdas = self._get_lambda_schedule(settings) - # - # # 10. Get compound and sampler states - # sampler_states, cmp_states = self._get_states( - # system, positions, settings, - # lambdas, solv_comp - # ) - # - # # 11. Create the multistate reporter & create PDB - # reporter = self._get_reporter( - # pdb.topology, positions, - # settings['simulation_settings'], - # settings['output_settings'], - # shared_basepath, - # ) - # - # # Wrap in try/finally to avoid memory leak issues - # try: - # # 12. Get context caches - # energy_ctx_cache, sampler_ctx_cache = self._get_ctx_caches( - # settings['engine_settings'] - # ) - # - # # 13. Get integrator - # integrator = self._get_integrator( - # settings['integrator_settings'], - # settings['simulation_settings'], - # ) - # - # # 14. Get sampler - # sampler = self._get_sampler( - # integrator, reporter, settings['simulation_settings'], - # settings['thermo_settings'], - # cmp_states, sampler_states, - # energy_ctx_cache, sampler_ctx_cache - # ) - # - # # 15. Run simulation - # unit_result_dict = self._run_simulation( - # sampler, reporter, settings, dry, verbose, shared_basepath - # ) - # - # finally: - # # close reporter when you're done to prevent file handle clashes - # reporter.close() - # - # # clear GPU context - # # Note: use cache.empty() when openmmtools #690 is resolved - # for context in list(energy_ctx_cache._lru._data.keys()): - # del energy_ctx_cache._lru._data[context] - # for context in list(sampler_ctx_cache._lru._data.keys()): - # del sampler_ctx_cache._lru._data[context] - # # cautiously clear out the global context cache too - # for context in list( - # openmmtools.cache.global_context_cache._lru._data.keys()): - # del openmmtools.cache.global_context_cache._lru._data[context] - # - # del sampler_ctx_cache, energy_ctx_cache - # - # # Keep these around in a dry run so we can inspect things - # if not dry: - # del integrator, sampler - # - # if not dry: - # nc = shared_basepath / settings[ - # 'output_settings'].output_filename - # chk = settings['output_settings'].checkpoint_storage_filename - # return { - # 'repeat_id': self._inputs['repeat_id'], - # 'generation': self._inputs['generation'], - # 'simtype': phase, - # 'nc': nc, - # 'last_checkpoint': chk, - # **unit_result_dict, - # } - # else: - # return { - # 'repeat_id': self._inputs['repeat_id'], - # 'generation': self._inputs['generation'], - # 'debug': {'sampler': sampler}} From fd81c70071e99896a0a1959448452d06c679fab0 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 13 Jan 2025 16:19:32 +0100 Subject: [PATCH 130/163] Add test for user charges --- openfe/tests/protocols/test_openmm_septop.py | 215 ++++++++++++++++++- 1 file changed, 214 insertions(+), 1 deletion(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 405aaaecb..eca70f378 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -9,6 +9,7 @@ from openfe.protocols.openmm_septop import ( SepTopProtocol, SepTopComplexSetupUnit, + SepTopComplexRunUnit, SepTopSolventSetupUnit, SepTopSolventRunUnit, SepTopProtocolResult, @@ -16,6 +17,9 @@ from openfe.protocols.openmm_septop.equil_septop_method import _check_alchemical_charge_difference from openfe.protocols.openmm_utils import system_validation import numpy +from numpy.testing import assert_allclose +from math import sqrt +from openfe.protocols.openmm_septop.utils import deserialize import openmm import openmm.app import openmm.unit @@ -29,6 +33,7 @@ from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory +from openff.units.openmm import ensure_quantity, from_openmm KJ_PER_MOL = openmm.unit.kilojoule_per_mole @@ -634,9 +639,14 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in prot_units if isinstance(u, SepTopSolventRunUnit)] - + complex_setup_unit = [u for u in prot_units + if isinstance(u, SepTopComplexSetupUnit)] + complex_run_unit = [u for u in prot_units + if isinstance(u, SepTopComplexRunUnit)] assert len(solv_setup_unit) == 1 assert len(sol_run_unit) == 1 + assert len(complex_setup_unit) == 1 + assert len(complex_run_unit) == 1 with tmpdir.as_cwd(): solv_setup_output = solv_setup_unit[0].run(dry=True) @@ -648,6 +658,209 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): serialized_system, serialized_topology, dry=True)['debug']['sampler'] assert solv_run.is_periodic + complex_setup_output = complex_setup_unit[0].run(dry=True) + serialized_topology = complex_setup_output['topology'] + serialized_system = complex_setup_output['system'] + pdb = md.load_pdb(serialized_topology) + assert pdb.n_atoms == 37555 + complex_run = complex_run_unit[0].run( + serialized_system, serialized_topology, dry=True)['debug'][ + 'sampler'] + assert complex_run.is_periodic + + +def test_dry_run_benzene_toluene_tip4p( + benzene_complex_system, toluene_complex_system, tmpdir): + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_forcefield_settings.forcefields = [ + "amber/ff14SB.xml", # ff14SB protein force field + "amber/tip4pew_standard.xml", # FF we are testsing with the fun VS + "amber/phosaa10.xml", # Handles THE TPO + ] + s.solvent_solvation_settings.solvent_model = 'tip4pew' + s.integrator_settings.reassign_velocities = True + + protocol = SepTopProtocol(settings=s) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first solvent unit + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + + prot_units = list(dag.protocol_units) + + assert len(prot_units) == 4 + + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + sol_run_unit = [u for u in prot_units + if isinstance(u, SepTopSolventRunUnit)] + + assert len(solv_setup_unit) == 1 + assert len(sol_run_unit) == 1 + + with tmpdir.as_cwd(): + solv_setup_output = solv_setup_unit[0].run(dry=True) + serialized_topology = solv_setup_output['topology'] + serialized_system = solv_setup_output['system'] + solv_run = sol_run_unit[0].run( + serialized_system, serialized_topology, dry=True)['debug']['sampler'] + assert solv_run.is_periodic + + +def test_dry_run_benzene_toluene_noncubic( + benzene_complex_system, toluene_complex_system, tmpdir): + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_solvation_settings.solvent_padding = 1.5 * offunit.nanometer + s.solvent_solvation_settings.box_shape = 'dodecahedron' + + protocol = SepTopProtocol(settings=s) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first solvent unit + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + + prot_units = list(dag.protocol_units) + + assert len(prot_units) == 4 + + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + + assert len(solv_setup_unit) == 1 + + with tmpdir.as_cwd(): + solv_setup_output = solv_setup_unit[0].run(dry=True) + serialized_system = solv_setup_output['system'] + system = deserialize(serialized_system) + vectors = system.getDefaultPeriodicBoxVectors() + width = float(from_openmm(vectors)[0][0].to('nanometer').m) + + # dodecahedron has the following shape: + # [width, 0, 0], [0, width, 0], [0.5, 0.5, 0.5 * sqrt(2)] * width + + expected_vectors = [ + [width, 0, 0], + [0, width, 0], + [0.5 * width, 0.5 * width, + 0.5 * sqrt(2) * width], + ] * offunit.nanometer + assert_allclose( + expected_vectors, + from_openmm(vectors) + ) + + +def test_dry_run_solv_user_charges_benzene_toluene( + benzene_modifications, T4_protein_component, tmpdir): + """ + Create a test system with fictitious user supplied charges and + ensure that they are properly passed through to the constructed + alchemical system. + """ + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + + protocol = SepTopProtocol(settings=s) + + def assign_fictitious_charges(offmol): + """ + Get a random array of fake partial charges for your offmol. + """ + rand_arr = np.random.randint(1, 10, size=offmol.n_atoms) / 100 + rand_arr[-1] = -sum(rand_arr[:-1]) + return rand_arr * offunit.elementary_charge + + def check_partial_charges(offmol): + offmol_pchgs = assign_fictitious_charges(offmol) + offmol.partial_charges = offmol_pchgs + smc = openfe.SmallMoleculeComponent.from_openff(offmol) + + # check propchgs + prop_chgs = smc.to_dict()['molprops'][ + 'atom.dprop.PartialCharge'] + prop_chgs = np.array(prop_chgs.split(), dtype=float) + np.testing.assert_allclose(prop_chgs, offmol_pchgs) + return smc, prop_chgs + + benzene_offmol = benzene_modifications['benzene'].to_openff() + toluene_offmol = benzene_modifications['toluene'].to_openff() + + benzene_smc, benzene_charge = check_partial_charges(benzene_offmol) + toluene_smc, toluene_charge = check_partial_charges(toluene_offmol) + + # Create ChemicalSystems + stateA = ChemicalSystem({ + 'benzene': benzene_smc, + 'T4l': T4_protein_component, + 'solvent': SolventComponent(), + }) + + stateB = ChemicalSystem({ + 'toluene': toluene_smc, + 'T4l': T4_protein_component, + 'solvent': SolventComponent(), + }) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first solvent unit + dag = protocol.create(stateA=stateA, stateB=stateB, mapping=None,) + prot_units = list(dag.protocol_units) + + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + complex_setup_unit = [u for u in prot_units + if isinstance(u, SepTopComplexSetupUnit)] + + # check sol_unit charges + with tmpdir.as_cwd(): + serialized_system = solv_setup_unit[0].run(dry=True)['system'] + system = deserialize(serialized_system) + nonbond = [f for f in system.getForces() + if isinstance(f, openmm.NonbondedForce)] + assert len(nonbond) == 1 + + # loop through the 12 benzene atoms + # partial charge is stored in the offset + for i in range(12): + offsets = nonbond[0].getParticleParameterOffset(i) + c = ensure_quantity(offsets[2], 'openff') + assert pytest.approx(c) == benzene_charge[i] + # loop through 15 toluene atoms + for inx, i in enumerate(range(12, 27)): + offsets = nonbond[0].getParticleParameterOffset(i) + c = ensure_quantity(offsets[2], 'openff') + assert pytest.approx(c) == toluene_charge[inx] + + # check complex_unit charges + with tmpdir.as_cwd(): + serialized_system = complex_setup_unit[0].run(dry=True)['system'] + system = deserialize(serialized_system) + nonbond = [f for f in system.getForces() + if isinstance(f, openmm.NonbondedForce)] + assert len(nonbond) == 1 + + # loop through the 12 benzene atoms + # partial charge is stored in the offset + for i in range(12): + offsets = nonbond[0].getParticleParameterOffset(i) + c = ensure_quantity(offsets[2], 'openff') + assert pytest.approx(c) == benzene_charge[i] + # loop through 15 toluene atoms + for inx, i in enumerate(range(12, 27)): + offsets = nonbond[0].getParticleParameterOffset(i) + c = ensure_quantity(offsets[2], 'openff') + assert pytest.approx(c) == toluene_charge[inx] + def test_unit_tagging(benzene_toluene_dag, tmpdir): # test that executing the units includes correct gen and repeat info From f26f8866e58a8e8e2e4a14c1b473e0a9e497d999 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 14 Jan 2025 08:59:03 +0100 Subject: [PATCH 131/163] Small test --- openfe/tests/protocols/test_openmm_septop.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index eca70f378..be7b516a4 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -651,9 +651,10 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): with tmpdir.as_cwd(): solv_setup_output = solv_setup_unit[0].run(dry=True) serialized_topology = solv_setup_output['topology'] + print(serialized_topology) serialized_system = solv_setup_output['system'] - pdb = md.load_pdb(serialized_topology) - assert pdb.n_atoms == 4481 + # pdb = md.load_pdb(serialized_topology) + # assert pdb.n_atoms == 4481 solv_run = sol_run_unit[0].run( serialized_system, serialized_topology, dry=True)['debug']['sampler'] assert solv_run.is_periodic From 69e6d8c29c94422e14420d66edbaacc22104d0cc Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 14 Jan 2025 09:35:27 +0100 Subject: [PATCH 132/163] Small fix --- openfe/tests/protocols/test_openmm_septop.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index be7b516a4..6a06202ac 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -651,10 +651,7 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): with tmpdir.as_cwd(): solv_setup_output = solv_setup_unit[0].run(dry=True) serialized_topology = solv_setup_output['topology'] - print(serialized_topology) serialized_system = solv_setup_output['system'] - # pdb = md.load_pdb(serialized_topology) - # assert pdb.n_atoms == 4481 solv_run = sol_run_unit[0].run( serialized_system, serialized_topology, dry=True)['debug']['sampler'] assert solv_run.is_periodic @@ -662,8 +659,6 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): complex_setup_output = complex_setup_unit[0].run(dry=True) serialized_topology = complex_setup_output['topology'] serialized_system = complex_setup_output['system'] - pdb = md.load_pdb(serialized_topology) - assert pdb.n_atoms == 37555 complex_run = complex_run_unit[0].run( serialized_system, serialized_topology, dry=True)['debug'][ 'sampler'] From 4f59bc57002338eca677c65a46b11fa6dd459241 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 14 Jan 2025 11:02:51 +0100 Subject: [PATCH 133/163] Add more tests --- openfe/protocols/openmm_septop/base.py | 7 +- openfe/tests/protocols/test_openmm_septop.py | 27 ++++- .../protocols/test_openmm_septop_slow.py | 111 +++++++++++++++++- 3 files changed, 130 insertions(+), 15 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 33724d19c..e04c7ea86 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -1444,19 +1444,14 @@ def run( del integrator, sampler if not dry: - nc = shared_basepath / settings[ + nc = self.shared_basepath / settings[ 'output_settings'].output_filename chk = settings['output_settings'].checkpoint_storage_filename return { - 'repeat_id': self._inputs['repeat_id'], - 'generation': self._inputs['generation'], - 'simtype': phase, 'nc': nc, 'last_checkpoint': chk, **unit_result_dict, } else: return { - 'repeat_id': self._inputs['repeat_id'], - 'generation': self._inputs['generation'], 'debug': {'sampler': sampler}} diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 6a06202ac..f5f711495 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -858,6 +858,27 @@ def check_partial_charges(offmol): assert pytest.approx(c) == toluene_charge[inx] +def test_high_timestep(benzene_complex_system, toluene_complex_system, tmpdir): + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_forcefield_settings.hydrogen_mass = 1.0 + s.complex_forcefield_settings.hydrogen_mass = 1.0 + + protocol = SepTopProtocol(settings=s) + + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + prot_units = list(dag.protocol_units) + + with tmpdir.as_cwd(): + errmsg = "too large for hydrogen mass" + with pytest.raises(ValueError, match=errmsg): + prot_units[0].run(dry=True) + + def test_unit_tagging(benzene_toluene_dag, tmpdir): # test that executing the units includes correct gen and repeat info dag_units = benzene_toluene_dag.protocol_units @@ -866,8 +887,7 @@ def test_unit_tagging(benzene_toluene_dag, tmpdir): 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopComplexSetupUnit.run', return_value={'system': pathlib.Path('system.xml.bz2'), - 'topology': - 'topology.pdb'}), + 'topology': 'topology.pdb'}), mock.patch( 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopComplexRunUnit._execute', @@ -881,8 +901,7 @@ def test_unit_tagging(benzene_toluene_dag, tmpdir): 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopSolventSetupUnit.run', return_value={'system': pathlib.Path('system.xml.bz2'), - 'topology': - 'topology.pdb'}), + 'topology': 'topology.pdb'}), mock.patch( 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopSolventRunUnit._execute', diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 35f1aeb0e..9b6674cd9 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -1,12 +1,9 @@ # This code is part of OpenFE and is licensed under the MIT license. # For details, see https://github.com/OpenFreeEnergy/openfe -import itertools -import json -import sys import pytest from openff.units import unit -import gufe +from gufe.protocols import execute_DAG import openfe import simtk from openfe import ChemicalSystem, SolventComponent @@ -17,6 +14,10 @@ from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close from openfe.protocols.openmm_septop.utils import deserialize, SepTopParameterState +from openmm import Platform +import os +import pathlib + @pytest.fixture() def default_settings(): @@ -86,7 +87,7 @@ def compare_energies(alchemical_system, positions): # @pytest.mark.integration # takes too long to be a slow test ~ 4 mins locally -# @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation +@pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation # @pytest.mark.parametrize('platform', ['CPU', 'CUDA']) def test_lambda_energies(bace_ligands, bace_protein_component, tmpdir): # check system parametrisation works even if confgen fails @@ -167,3 +168,103 @@ def test_lambda_energies(bace_ligands, bace_protein_component, tmpdir): assert is_close(value, energy_8[key]) assert is_close(value, energy_12[key]) assert is_close(value, energy_13[key]) + + +@pytest.fixture +def available_platforms() -> set[str]: + return {Platform.getPlatform(i).getName() for i in range(Platform.getNumPlatforms())} + + +@pytest.fixture +def set_openmm_threads_1(): + # for vacuum sims, we want to limit threads to one + # this fixture sets OPENMM_CPU_THREADS='1' for a single test, then reverts to previously held value + previous: str | None = os.environ.get('OPENMM_CPU_THREADS') + + try: + os.environ['OPENMM_CPU_THREADS'] = '1' + yield + finally: + if previous is None: + del os.environ['OPENMM_CPU_THREADS'] + else: + os.environ['OPENMM_CPU_THREADS'] = previous + + +@pytest.mark.integration # takes too long to be a slow test ~ 4 mins locally +@pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation +@pytest.mark.parametrize('platform', ['CPU', 'CUDA']) +def test_openmm_run_engine(platform, + available_platforms, + benzene_modifications, + T4_protein_component, + set_openmm_threads_1, tmpdir): + if platform not in available_platforms: + pytest.skip(f"OpenMM Platform: {platform} not available") + + # Run a really short calculation to check everything is going well + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_output_settings.output_indices = "resname UNK" + s.complex_equil_simulation_settings.equilibration_length = 0.1 * unit.picosecond + s.complex_equil_simulation_settings.production_length = 0.1 * unit.picosecond + s.complex_simulation_settings.equilibration_length = 0.1 * unit.picosecond + s.complex_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.complex_engine_settings.compute_platform = platform + s.solvent_engine_settings.compute_platform = platform + s.complex_simulation_settings.time_per_iteration = 20 * unit.femtosecond + s.solvent_simulation_settings.time_per_iteration = 20 * unit.femtosecond + s.complex_output_settings.checkpoint_interval = 20 * unit.femtosecond + s.solvent_output_settings.checkpoint_interval = 20 * unit.femtosecond + + protocol = SepTopProtocol( + settings=s, + ) + + stateA = openfe.ChemicalSystem({ + 'benzene': benzene_modifications['benzene'], + 'T4L': T4_protein_component, + 'solvent': openfe.SolventComponent() + }) + + stateB = openfe.ChemicalSystem({ + 'toluene': benzene_modifications['toluene'], + 'T4L': T4_protein_component, + 'solvent': openfe.SolventComponent(), + }) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first solvent unit + dag = protocol.create( + stateA=stateA, + stateB=stateB, + mapping=None, + ) + + cwd = pathlib.Path(str(tmpdir)) + r = execute_DAG(dag, shared_basedir=cwd, scratch_basedir=cwd, + keep_shared=True) + + assert r.ok() + for pur in r.protocol_unit_results: + unit_shared = tmpdir / f"shared_{pur.source_key}_attempt_0" + assert unit_shared.exists() + assert pathlib.Path(unit_shared).is_dir() + checkpoint = pur.outputs['last_checkpoint'] + assert checkpoint == f"{pur.outputs['simtype']}_checkpoint.nc" + assert (unit_shared / checkpoint).exists() + nc = pur.outputs['nc'] + assert nc == unit_shared / f"{pur.outputs['simtype']}.nc" + assert nc.exists() + + # Test results methods that need files present + results = protocol.gather([r]) + states = results.get_replica_states() + assert len(states.items()) == 2 + assert len(states['solvent']) == 1 + assert states['solvent'][0].shape[1] == 19 \ No newline at end of file From 101f49a7867a64e2d8bbe11d6a6f5f6b5f488ac4 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 14 Jan 2025 11:44:56 +0100 Subject: [PATCH 134/163] More tests --- .../openmm_septop/femto_restraints.py | 2 +- openfe/tests/protocols/test_openmm_septop.py | 25 ++++++++++++++++--- .../protocols/test_openmm_septop_slow.py | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 05a45ff09..5f5d2884e 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -297,7 +297,7 @@ def _filter_receptor_atoms( residues_to_keep.extend( f"resid {idx}" for idx in range(start_idx, end_idx + 1)) - if residues_to_keep: + if len(residues_to_keep) > 0: rigid_backbone_idxs = backbone.top.select(" ".join(residues_to_keep)) if len(rigid_backbone_idxs) == 0: diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index f5f711495..6ac4b3c9b 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -23,6 +23,7 @@ import openmm import openmm.app import openmm.unit +from openmmtools.multistate.multistatesampler import MultiStateSampler from openff.units import unit as offunit import gufe from unittest import mock @@ -34,6 +35,7 @@ from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory from openff.units.openmm import ensure_quantity, from_openmm +from openmm import MonteCarloBarostat KJ_PER_MOL = openmm.unit.kilojoule_per_mole @@ -652,17 +654,32 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): solv_setup_output = solv_setup_unit[0].run(dry=True) serialized_topology = solv_setup_output['topology'] serialized_system = solv_setup_output['system'] - solv_run = sol_run_unit[0].run( + solv_sampler = sol_run_unit[0].run( serialized_system, serialized_topology, dry=True)['debug']['sampler'] - assert solv_run.is_periodic + assert solv_sampler.is_periodic + assert isinstance(solv_sampler, MultiStateSampler) + assert isinstance(solv_sampler._thermodynamic_states[0].barostat, + MonteCarloBarostat) + assert solv_sampler._thermodynamic_states[1].pressure == 1 * openmm.unit.bar + # Check we have the right number of atoms in the PDB + pdb = md.load_pdb('hybrid_system.pdb') + assert pdb.n_atoms == 35 complex_setup_output = complex_setup_unit[0].run(dry=True) serialized_topology = complex_setup_output['topology'] serialized_system = complex_setup_output['system'] - complex_run = complex_run_unit[0].run( + complex_sampler = complex_run_unit[0].run( serialized_system, serialized_topology, dry=True)['debug'][ 'sampler'] - assert complex_run.is_periodic + assert complex_sampler.is_periodic + assert isinstance(complex_sampler, MultiStateSampler) + assert isinstance(complex_sampler._thermodynamic_states[0].barostat, + MonteCarloBarostat) + assert complex_sampler._thermodynamic_states[ + 1].pressure == 1 * openmm.unit.bar + # Check we have the right number of atoms in the PDB + pdb = md.load_pdb('hybrid_system.pdb') + assert pdb.n_atoms == 2713 def test_dry_run_benzene_toluene_tip4p( diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 9b6674cd9..98074702e 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -191,7 +191,7 @@ def set_openmm_threads_1(): os.environ['OPENMM_CPU_THREADS'] = previous -@pytest.mark.integration # takes too long to be a slow test ~ 4 mins locally +@pytest.mark.integration @pytest.mark.flaky(reruns=3) # pytest-rerunfailures; we can get bad minimisation @pytest.mark.parametrize('platform', ['CPU', 'CUDA']) def test_openmm_run_engine(platform, From 98059a0451e615207c1573ccf1f1620fd4b9dd5a Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 14 Jan 2025 13:48:35 +0100 Subject: [PATCH 135/163] Add tests for cutoff and pressure --- .../openmm_septop/femto_restraints.py | 2 +- openfe/tests/protocols/test_openmm_septop.py | 124 +++++++++++++++--- 2 files changed, 105 insertions(+), 21 deletions(-) diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 5f5d2884e..623dc762c 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -282,7 +282,7 @@ def _filter_receptor_atoms( "E"] min_motif_size = {"H": min_helix_size, "E": min_sheet_size} - residues_to_keep: list[str | None] = [] + residues_to_keep: list = [] structure = structure[skip_residues_start: -(skip_residues_end + 1)] diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 6ac4b3c9b..3d3e5eabc 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -35,8 +35,10 @@ from openfe.protocols.openmm_septop.femto_utils import compute_energy, is_close from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory from openff.units.openmm import ensure_quantity, from_openmm -from openmm import MonteCarloBarostat - +from openmm import ( + app, XmlSerializer, MonteCarloBarostat, + NonbondedForce, CustomNonbondedForce +) KJ_PER_MOL = openmm.unit.kilojoule_per_mole @@ -287,7 +289,6 @@ def test_validate_complex_endstates_protcomp_stateB( SepTopProtocol._validate_complex_endstates(stateA, stateB) - def test_validate_complex_endstates_nosolvcomp_stateA( benzene_modifications, T4_protein_component, ): @@ -413,8 +414,8 @@ def test_validate_alchem_nonsmc( SepTopProtocol._validate_alchemical_components(alchem_comps) -### Tests for the alchemical systems. This tests were modified from -### femto (https://github.com/Psivant/femto/tree/main) +# Tests for the alchemical systems. This tests were modified from +# femto (https://github.com/Psivant/femto/tree/main) def compute_interaction_energy( epsilon, sigma, @@ -628,7 +629,11 @@ def benzene_toluene_dag(benzene_complex_system, toluene_complex_system): protocol = SepTopProtocol(settings=s) - return protocol.create(stateA=benzene_complex_system, stateB=toluene_complex_system, mapping=None) + return protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): @@ -638,13 +643,13 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): assert len(prot_units) == 4 solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopSolventSetupUnit)] + if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in prot_units - if isinstance(u, SepTopSolventRunUnit)] + if isinstance(u, SepTopSolventRunUnit)] complex_setup_unit = [u for u in prot_units - if isinstance(u, SepTopComplexSetupUnit)] + if isinstance(u, SepTopComplexSetupUnit)] complex_run_unit = [u for u in prot_units - if isinstance(u, SepTopComplexRunUnit)] + if isinstance(u, SepTopComplexRunUnit)] assert len(solv_setup_unit) == 1 assert len(sol_run_unit) == 1 assert len(complex_setup_unit) == 1 @@ -682,6 +687,86 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): assert pdb.n_atoms == 2713 +@pytest.mark.parametrize('pressure', + [1.0 * openmm.unit.bar, + 0.9 * openmm.unit.bar, + 1.1 * openmm.unit.bar] + ) +def test_dry_run_ligand_system_pressure( + pressure, benzene_complex_system, toluene_complex_system, tmpdir +): + """ + Test that the right nonbonded cutoff is propagated to the system. + """ + settings = SepTopProtocol.default_settings() + settings.thermo_settings.pressure = pressure + + protocol = SepTopProtocol( + settings=settings, + ) + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + dag_units = list(dag.protocol_units) + # Only check the cutoff for the Solvent SetUp Unit + solv_setup_unit = [u for u in dag_units + if isinstance(u, SepTopSolventSetupUnit)] + sol_run_unit = [u for u in dag_units + if isinstance(u, SepTopSolventRunUnit)] + with tmpdir.as_cwd(): + solv_setup_output = solv_setup_unit[0].run(dry=True) + serialized_topology = solv_setup_output['topology'] + serialized_system = solv_setup_output['system'] + solv_sampler = sol_run_unit[0].run( + serialized_system, serialized_topology, dry=True)['debug']['sampler'] + # CAVE: The pressure does not fully equal the pressure in the settings, + # likely because the second ligand that is inserted in the first system + # slightly changes the pressure? + assert is_close(solv_sampler._thermodynamic_states[1].pressure, pressure) + + +@pytest.mark.parametrize('cutoff', + [1.0 * offunit.nanometer, + 12.0 * offunit.angstrom, + 0.9 * offunit.nanometer] + ) +def test_dry_run_ligand_system_cutoff( + cutoff, benzene_complex_system, toluene_complex_system, tmpdir +): + """ + Test that the right nonbonded cutoff is propagated to the system. + """ + settings = SepTopProtocol.default_settings() + settings.solvent_solvation_settings.solvent_padding = 1.5 * offunit.nanometer + settings.solvent_forcefield_settings.nonbonded_cutoff = cutoff + + protocol = SepTopProtocol( + settings=settings, + ) + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + dag_units = list(dag.protocol_units) + # Only check the cutoff for the Solvent SetUp Unit + solv_setup_unit = [u for u in dag_units + if isinstance(u, SepTopSolventSetupUnit)] + + with tmpdir.as_cwd(): + serialized_system = solv_setup_unit[0].run(dry=True)['system'] + system = deserialize(serialized_system) + nbfs = [f for f in system.getForces() if + isinstance(f, CustomNonbondedForce) or + isinstance(f, NonbondedForce)] + + for f in nbfs: + f_cutoff = from_openmm(f.getCutoffDistance()) + assert f_cutoff == cutoff + + def test_dry_run_benzene_toluene_tip4p( benzene_complex_system, toluene_complex_system, tmpdir): s = SepTopProtocol.default_settings() @@ -709,9 +794,9 @@ def test_dry_run_benzene_toluene_tip4p( assert len(prot_units) == 4 solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopSolventSetupUnit)] + if isinstance(u, SepTopSolventSetupUnit)] sol_run_unit = [u for u in prot_units - if isinstance(u, SepTopSolventRunUnit)] + if isinstance(u, SepTopSolventRunUnit)] assert len(solv_setup_unit) == 1 assert len(sol_run_unit) == 1 @@ -747,7 +832,7 @@ def test_dry_run_benzene_toluene_noncubic( assert len(prot_units) == 4 solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopSolventSetupUnit)] + if isinstance(u, SepTopSolventSetupUnit)] assert len(solv_setup_unit) == 1 @@ -830,9 +915,9 @@ def check_partial_charges(offmol): prot_units = list(dag.protocol_units) solv_setup_unit = [u for u in prot_units - if isinstance(u, SepTopSolventSetupUnit)] + if isinstance(u, SepTopSolventSetupUnit)] complex_setup_unit = [u for u in prot_units - if isinstance(u, SepTopComplexSetupUnit)] + if isinstance(u, SepTopComplexSetupUnit)] # check sol_unit charges with tmpdir.as_cwd(): @@ -953,7 +1038,7 @@ def test_gather(benzene_toluene_dag, tmpdir): 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopComplexSetupUnit.run', return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': - 'topology.pdb'}), + 'topology.pdb'}), mock.patch( 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopComplexRunUnit._execute', @@ -967,7 +1052,7 @@ def test_gather(benzene_toluene_dag, tmpdir): 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopSolventSetupUnit.run', return_value={'system': pathlib.Path('system.xml.bz2'), 'topology': - 'topology.pdb'}), + 'topology.pdb'}), mock.patch( 'openfe.protocols.openmm_septop.equil_septop_method' '.SepTopSolventRunUnit._execute', @@ -1005,8 +1090,7 @@ def test_reload_protocol_result(self, septop_json): d = json.loads(septop_json, cls=gufe.tokenization.JSON_HANDLER.decoder) - pr = SepTopProtocolResult.from_dict(d[ - 'protocol_result']) + pr = SepTopProtocolResult.from_dict(d['protocol_result']) assert pr @@ -1036,7 +1120,7 @@ def test_get_individual(self, protocolresult): assert e.is_compatible_with(offunit.kilojoule_per_mole) assert u.is_compatible_with(offunit.kilojoule_per_mole) - #ToDo: Add Results from longer test run that has this analysis + # ToDo: Add Results from longer test run that has this analysis # @pytest.mark.parametrize('key', ['solvent', 'complex']) # def test_get_forwards_etc(self, key, protocolresult): From 0bd8b7dc91c6f24a3ecee57dbdbb3b21b5c07843 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 16 Jan 2025 12:55:52 +0100 Subject: [PATCH 136/163] Add tests for reference xml --- .../tests/data/openmm_septop/system.xml.bz2 | Bin 0 -> 95150 bytes openfe/tests/protocols/test_openmm_septop.py | 77 ++++++++++++++++-- 2 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 openfe/tests/data/openmm_septop/system.xml.bz2 diff --git a/openfe/tests/data/openmm_septop/system.xml.bz2 b/openfe/tests/data/openmm_septop/system.xml.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..962405f54e1c0dc8b2cd3085f76d6f1a19d18035 GIT binary patch literal 95150 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

    hg~% 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 T!REr;nE7{(g#9?i@w@*6p>BdX literal 0 HcmV?d00001 diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 3d3e5eabc..977f4cb56 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -39,6 +39,7 @@ app, XmlSerializer, MonteCarloBarostat, NonbondedForce, CustomNonbondedForce ) +from importlib import resources KJ_PER_MOL = openmm.unit.kilojoule_per_mole @@ -688,9 +689,9 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): @pytest.mark.parametrize('pressure', - [1.0 * openmm.unit.bar, - 0.9 * openmm.unit.bar, - 1.1 * openmm.unit.bar] + [1.0 * openmm.unit.atmosphere, + 0.9 * openmm.unit.atmosphere, + 1.1 * openmm.unit.atmosphere] ) def test_dry_run_ligand_system_pressure( pressure, benzene_complex_system, toluene_complex_system, tmpdir @@ -721,10 +722,8 @@ def test_dry_run_ligand_system_pressure( serialized_system = solv_setup_output['system'] solv_sampler = sol_run_unit[0].run( serialized_system, serialized_topology, dry=True)['debug']['sampler'] - # CAVE: The pressure does not fully equal the pressure in the settings, - # likely because the second ligand that is inserted in the first system - # slightly changes the pressure? - assert is_close(solv_sampler._thermodynamic_states[1].pressure, pressure) + + assert solv_sampler._thermodynamic_states[1].pressure == pressure @pytest.mark.parametrize('cutoff', @@ -981,6 +980,70 @@ def test_high_timestep(benzene_complex_system, toluene_complex_system, tmpdir): prot_units[0].run(dry=True) +@pytest.fixture +def T4L_xml(benzene_complex_system, toluene_complex_system, tmp_path_factory): + s = SepTopProtocol.default_settings() + + protocol = SepTopProtocol(settings=s) + + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + # Get the SepTopSolventSetupUnit + prot_units = list(dag.protocol_units) + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + + tmp = tmp_path_factory.mktemp('xml_reg') + + dryrun = solv_setup_unit[0].run(dry=True, shared_basepath=tmp) + + system = dryrun['system'] + return deserialize(system) + + +@pytest.fixture +def T4L_reference_xml(): + with resources.files('openfe.tests.data.openmm_septop') as d: + f = d / 'system.xml.bz2' + return deserialize(pathlib.Path(f)) + + +# @pytest.mark.slow +class TestT4LXmlRegression: + """Generates SepTop system XML (solvent) and performs regression test""" + @staticmethod + def test_particles(T4L_xml, T4L_reference_xml): + nr_particles = T4L_xml.getNumParticles() + nr_particles_ref = T4L_reference_xml.getNumParticles() + assert nr_particles == nr_particles_ref + particle_masses = [T4L_xml.getParticleMass(i) for i in range(nr_particles)] + particle_masses_ref = [T4L_reference_xml.getParticleMass(i) for i in range(nr_particles)] + assert particle_masses + + for a, b in zip(particle_masses, particle_masses_ref): + assert a == b + + @staticmethod + def test_constraints(T4L_xml, T4L_reference_xml): + nr_constraints = T4L_xml.getNumConstraints() + nr_constraints_ref = T4L_reference_xml.getNumConstraints() + assert nr_constraints == nr_constraints_ref + constraints = [T4L_xml.getConstraintParameters(i) for i in range(nr_constraints)] + constraints_ref = [T4L_reference_xml.getConstraintParameters(i) for i in range(nr_constraints)] + assert constraints + + for a, b in zip(constraints, constraints_ref): + # Particle 1 + assert a[0] == b[0] + # Particle 2 + assert a[1] == b[1] + # Constraint Quantity + assert a[2] == b[2] + + def test_unit_tagging(benzene_toluene_dag, tmpdir): # test that executing the units includes correct gen and repeat info dag_units = benzene_toluene_dag.protocol_units From 7faae6ed328cd3e0c10cbcb1b8714b55c3b73eaf Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 16 Jan 2025 17:04:05 +0100 Subject: [PATCH 137/163] Test distance solvent restraint in dry run --- openfe/tests/protocols/test_openmm_septop.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 977f4cb56..e2a75644d 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -3,7 +3,7 @@ import pathlib import pytest - +import math import openfe.protocols.openmm_septop from openfe import ChemicalSystem, SolventComponent from openfe.protocols.openmm_septop import ( @@ -658,6 +658,14 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): with tmpdir.as_cwd(): solv_setup_output = solv_setup_unit[0].run(dry=True) + pdb = md.load_pdb('topology.pdb') + print(pdb.n_atoms) + assert pdb.n_atoms == 4481 + central_atoms = np.array([[2, 4475]], dtype=np.int32) + distance = md.compute_distances(pdb, central_atoms)[0][0] + print(distance) + print(type(distance)) + assert np.isclose(distance, 0.76336) serialized_topology = solv_setup_output['topology'] serialized_system = solv_setup_output['system'] solv_sampler = sol_run_unit[0].run( From 3fa964f93476dc797a22f2089066867175008157 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Mon, 20 Jan 2025 17:08:47 +0100 Subject: [PATCH 138/163] Add slow test for solvent restraints --- openfe/tests/protocols/test_openmm_septop.py | 2 - .../protocols/test_openmm_septop_slow.py | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index e2a75644d..8bef0eb60 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -663,8 +663,6 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): assert pdb.n_atoms == 4481 central_atoms = np.array([[2, 4475]], dtype=np.int32) distance = md.compute_distances(pdb, central_atoms)[0][0] - print(distance) - print(type(distance)) assert np.isclose(distance, 0.76336) serialized_topology = solv_setup_output['topology'] serialized_system = solv_setup_output['system'] diff --git a/openfe/tests/protocols/test_openmm_septop_slow.py b/openfe/tests/protocols/test_openmm_septop_slow.py index 98074702e..48485bd61 100644 --- a/openfe/tests/protocols/test_openmm_septop_slow.py +++ b/openfe/tests/protocols/test_openmm_septop_slow.py @@ -17,6 +17,8 @@ from openmm import Platform import os import pathlib +import mdtraj as md +import numpy as np @pytest.fixture() @@ -267,4 +269,46 @@ def test_openmm_run_engine(platform, states = results.get_replica_states() assert len(states.items()) == 2 assert len(states['solvent']) == 1 - assert states['solvent'][0].shape[1] == 19 \ No newline at end of file + assert states['solvent'][0].shape[1] == 19 + + +@pytest.mark.integration +@pytest.mark.flaky(reruns=1) # pytest-rerunfailures; we can get bad minimisation +@pytest.mark.parametrize('platform', ['CPU', 'CUDA']) +def test_restraints_solvent(platform, + available_platforms, + benzene_complex_system, + toluene_complex_system, + set_openmm_threads_1, tmpdir): + if platform not in available_platforms: + pytest.skip(f"OpenMM Platform: {platform} not available") + + # Run a really short calculation to check everything is going well + s = SepTopProtocol.default_settings() + s.protocol_repeats = 1 + s.solvent_equil_simulation_settings.equilibration_length_nvt = 10 * unit.picosecond + s.solvent_equil_simulation_settings.equilibration_length = 10 * unit.picosecond + s.solvent_equil_simulation_settings.production_length = 10 * unit.picosecond + s.solvent_engine_settings.compute_platform = platform + + protocol = SepTopProtocol( + settings=s, + ) + + # Create DAG from protocol, get the vacuum and solvent units + # and eventually dry run the first solvent unit + dag = protocol.create( + stateA=benzene_complex_system, + stateB=toluene_complex_system, + mapping=None, + ) + prot_units = list(dag.protocol_units) + solv_setup_unit = [u for u in prot_units + if isinstance(u, SepTopSolventSetupUnit)] + solv_setup_output = solv_setup_unit[0].run() + pdb = md.load_pdb('topology.pdb') + assert pdb.n_atoms == 4481 + central_atoms = np.array([[2, 4475]], dtype=np.int32) + distance = md.compute_distances(pdb, central_atoms)[0][0] + # For right now just checking that ligands at least somewhat apart + assert distance > 0.5 \ No newline at end of file From fc1f316cc4be8826f163fa09635f9deca6e5e8b9 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Tue, 21 Jan 2025 13:57:58 +0000 Subject: [PATCH 139/163] Update to address review comments --- .../restraint_utils/geometry/boresch.py | 120 ++++++++++++------ .../restraint_utils/geometry/utils.py | 19 ++- 2 files changed, 96 insertions(+), 43 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py index 4fb4b45b9..cce049f4a 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -20,7 +20,6 @@ from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals import numpy as np import numpy.typing as npt -from scipy.stats import circmean from .base import HostGuestRestraintGeometry from .utils import ( @@ -162,7 +161,7 @@ def _bonded_angles_from_pool( if at3 != atom_idx and at3 in at2_neighbors: angles.append((atom_idx, at2, at3)) - if aromatic_only: + if aromatic_only: # TODO: move this to its own method? aromatic_rings = get_aromatic_rings(rdmol) def _belongs_to_ring(angle, aromatic_rings): @@ -342,7 +341,7 @@ def find_host_atom_candidates( l1_idx : int The index of the proposed l1 binding atom. host_selection : str - An MDAnalysis selection string to fileter the host by. + An MDAnalysis selection string to filter the host by. dssp_filter : bool Whether or not to apply a DSSP filter on the host selection. rmsf_cutoff : uni.Quantity @@ -364,8 +363,10 @@ def find_host_atom_candidates( topology_format=_get_mda_topology_format(topology), ) - host_ag1 = u.atoms[host_idxs] - host_ag2 = host_ag1.select_atoms(host_selection) + # Get an AtomGroup for the host based on the input host indices + host_ag = u.atoms[host_idxs] + # Filter the host AtomGroup based on ``host_selection` + selected_host_ag = host_ag.select_atoms(host_selection) # 0. TODO: implement DSSP filter # Should be able to just call MDA's DSSP method @@ -375,13 +376,13 @@ def find_host_atom_candidates( "DSSP filtering is not currently implemented" ) - # 1. Get the RMSF & filter - rmsf = get_local_rmsf(host_ag2) - host_ag3 = host_ag2.atoms[rmsf < rmsf_cutoff] + # 1. Get the RMSF & filter to create a new AtomGroup + rmsf = get_local_rmsf(selected_host_ag) + filtered_host_ag = selected_host_ag.atoms[rmsf < rmsf_cutoff] # 2. Search of atoms within the min/max cutoff atom_finder = FindHostAtoms( - host_ag3, u.atoms[l1_idx], min_distance, max_distance + filtered_host_ag, u.atoms[l1_idx], min_distance, max_distance ) atom_finder.run() return atom_finder.results.host_idxs @@ -444,6 +445,8 @@ def _prepare(self): len(self.host_atom_pool), dtype=bool, ) + # Set everything to False to begin with + self.results.valid = False def _single_frame(self): for i, at in enumerate(self.host_atom_pool): @@ -476,12 +479,18 @@ def _single_frame(self): def _conclude(self): for i, at in enumerate(self.host_atom_pool): - distance_bounds = all(self.results.distances[i] > self.minimum_distance) - mean_angle = circmean(self.results.angles[i], high=np.pi, low=0) - angle_bounds = check_angle_not_flat( - angle=mean_angle * unit.radians, - force_constant=self.angle_force_constant, - temperature=self.temperature, + # Check distances + distance_bounds = all( + self.results.distances[i] > self.minimum_distance + ) + # Check angles + angle_bounds = all( + check_angle_not_flat( + angle=angle * unit.radians, + force_constant=self.angle_force_constant, + temperature=self.temperature + ) + for angle in self.results.angles ) angle_variance = check_angular_variance( self.results.angles[i] * unit.radians, @@ -489,8 +498,11 @@ def _conclude(self): lower_bound=0 * unit.radians, width=1.745 * unit.radians, ) - mean_dihed = circmean(self.results.dihedrals[i], high=np.pi, low=-np.pi) - dihed_bounds = check_dihedral_bounds(mean_dihed) + # Check dihedrals + dihed_bounds = all( + check_dihedral_bounds(dihed * unit.radians) + for dihed in self.results.dihedrals + ) dihed_variance = check_angular_variance( self.results.dihedrals[i] * unit.radians, upper_bound=np.pi * unit.radians, @@ -541,6 +553,8 @@ def _prepare(self): len(self.host_atom_pool), dtype=bool, ) + # Default to valid == False + self.results.valid = False def _single_frame(self): for i, at in enumerate(self.host_atom_pool): @@ -572,10 +586,16 @@ def _single_frame(self): def _conclude(self): for i, at in enumerate(self.host_atom_pool): - distance1_bounds = all(self.results.distances1[i] > self.minimum_distance) - distance2_bounds = all(self.results.distances2[i] > self.minimum_distance) - mean_dihed = circmean(self.results.dihedrals[i], high=np.pi, low=-np.pi) - dihed_bounds = check_dihedral_bounds(mean_dihed) + distance1_bounds = all( + self.results.distances1[i] > self.minimum_distance + ) + distance2_bounds = all( + self.results.distances2[i] > self.minimum_distance + ) + dihed_bounds = all( + check_dihedral_bounds(dihed * unit.radians) + for dihed in self.results.dihedrals + ) dihed_variance = check_angular_variance( self.results.dihedrals[i] * unit.radians, upper_bound=np.pi * unit.radians, @@ -623,6 +643,7 @@ def _find_host_anchor( Optional[list[int]] A list of indices for a selected combination of H0, H1, and H2. """ + # Evalulate the host_atom_pool for suitability as H0 atoms h0_eval = EvaluateHostAtoms1( guest_atoms, host_atom_pool, @@ -633,32 +654,52 @@ def _find_host_anchor( h0_eval.run() for i, valid_h0 in enumerate(h0_eval.results.valid): + # If valid H0 atom, evaluate rest of host_atom_pool for suitability + # as H1 atoms. if valid_h0: - g1g0h0_atoms = guest_atoms.atoms[:2] + host_atom_pool.atoms[i] + h0g0g1_atoms = host_atom_pool.atoms[i] + guest_atoms.atoms[:2] h1_eval = EvaluateHostAtoms1( - g1g0h0_atoms, + h0g0g1_atoms, host_atom_pool, minimum_distance, angle_force_constant, temperature, ) for j, valid_h1 in enumerate(h1_eval.results.valid): - g2h0h1_atoms = g1g2h0_atoms.atoms[1:] + host_atom_pool.atoms[j] - h2_eval = EvaluateHostAtoms2( - g2h0h1_atoms, - host_atom_pool, - minimum_distance, - angle_force_constant, - temperature, - ) - - if any(h2_eval.results.valid): - d1_avgs = np.array([d.mean() for d in h2_eval.results.distances1]) - d2_avgs = np.array([d.mean() for d in h2_eval.results.distances2]) - dsum_avgs = d1_avgs + d2_avgs - k = dsum_avgs.argmin() + # If valid H1 atom, evaluate rest of host_atom_pool for + # suitability as H2 atoms + if valid_h1: + h1h0g0_atoms = host_atom_pool.atoms[j] + h0g0g1_atoms.atoms[:2] + h2_eval = EvaluateHostAtoms2( + h1h0g0_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) - return list(host_atom_pool.atoms[[i, j, k]].ix) + if any(h2_eval.results.valid): + # Get the sum of the average distances (dsum_avgs) + # for all the host_atom_pool atoms + distance1_avgs = np.array( + [d.mean() for d in h2_eval.results.distances1] + ) + distance2_avgs = np.array( + [d.mean() for d in h2_eval.results.distances2] + ) + dsum_avgs = distance1_avgs + distance2_avgs + + # Now filter by validity as H2 atom + h2_dsum_avgs = [ + (idx, val) for idx, val in enumerate(dsum_avgs) + if h2_eval.results.valid[idx] + ] + + # Get the index of the H2 atom with the lowest + # average distance + k = sorted(h2_dsum_avgs, key=lambda x: x[1])[0][0] + + return list(host_atom_pool.atoms[[i, j, k]].ix) return None @@ -822,6 +863,9 @@ def find_boresch_restraint( atomgroup ) + # TODO: add checks to warn if this is a badly picked + # set of atoms. + return BoreschRestraintGeometry( host_atoms=host_anchor, guest_atoms=guest_anchor, diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index d27e3156e..6793f924d 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -202,7 +202,7 @@ def get_central_atom_idx(rdmol: Chem.Mol) -> int: Returns ------- - center : int + int Index of central atom in Molecule Note @@ -213,14 +213,23 @@ def get_central_atom_idx(rdmol: Chem.Mol) -> int: # TODO: switch to a manual conversion to avoid an OpenFF dependency offmol = OFFMol(rdmol, allow_undefined_stereo=True) nx_mol = offmol.to_networkx() + if not nx.is_weakly_connected(nx_mol): errmsg = "A disconnected molecule was passed, cannot find the center" raise ValueError(errmsg) - # We take the zero-th entry if there are multiple center - # atoms (e.g. equal likelihood centers) - center = nx.center(nx_mol)[0] - return center + # Get a list of all shortest paths + shortest_paths = [ + path + for node_paths in nx.shortest_path(nx_mol).values() + for path in node_paths.values() + ] + + # Get the longest of these paths (returns first instance) + longest_path = max(shortest_paths, key=len) + + # Return the index of the central atom + return longest_path[len(longest_path) // 2] def is_collinear(positions, atoms, dimensions=None, threshold=0.9): From 98ff0c812b9dcdb3c1fe0a1662e61a05ae4a411d Mon Sep 17 00:00:00 2001 From: IAlibay Date: Tue, 21 Jan 2025 14:01:24 +0000 Subject: [PATCH 140/163] Last review comment --- openfe/protocols/restraint_utils/geometry/utils.py | 4 ++++ openfe/protocols/restraint_utils/settings.py | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 6793f924d..bc9ea625b 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -301,6 +301,10 @@ def check_angle_not_flat( Note ---- We assume the temperature to be 298.15 Kelvin. + + Acknowledgements + ---------------- + This code was initially contributed by Vytautas Gapsys. """ # Convert things angle_rads = angle.to("radians") diff --git a/openfe/protocols/restraint_utils/settings.py b/openfe/protocols/restraint_utils/settings.py index 0a06714c0..efe9c33f6 100644 --- a/openfe/protocols/restraint_utils/settings.py +++ b/openfe/protocols/restraint_utils/settings.py @@ -7,9 +7,8 @@ ---- * Rename from host/guest to molA/molB? """ -from typing import Optional, Literal -from openff.units import unit -from openff.models.types import FloatQuantity, ArrayQuantity +from typing import Optional +from openff.models.types import FloatQuantity from pydantic.v1 import validator from gufe.settings import ( SettingsBaseModel, From e39cdd3944e6fa3ef888c851df3b4f0d1a70be28 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Wed, 22 Jan 2025 11:54:52 +0000 Subject: [PATCH 141/163] Various fixes --- .../restraint_utils/geometry/boresch.py | 33 +++++++++++-------- .../restraint_utils/geometry/utils.py | 24 +++++++++----- .../restraints/test_geometry_harmonic.py | 23 +++++++++++++ .../restraints/test_omm_restraints.py | 2 +- .../protocols/restraints/test_settings.py | 4 +-- 5 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 openfe/tests/protocols/restraints/test_geometry_harmonic.py diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py index cce049f4a..03c8f385a 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -382,7 +382,10 @@ def find_host_atom_candidates( # 2. Search of atoms within the min/max cutoff atom_finder = FindHostAtoms( - filtered_host_ag, u.atoms[l1_idx], min_distance, max_distance + host_atoms=filtered_host_ag, + guest_atoms=u.atoms[l1_idx], + min_search_distance=min_distance, + max_search_distance=max_distance, ) atom_finder.run() return atom_finder.results.host_idxs @@ -446,7 +449,7 @@ def _prepare(self): dtype=bool, ) # Set everything to False to begin with - self.results.valid = False + self.results.valid[:] = False def _single_frame(self): for i, at in enumerate(self.host_atom_pool): @@ -470,6 +473,7 @@ def _single_frame(self): ) collinear = is_collinear( positions=np.vstack((at.position, self.reference.positions)), + atoms=[0, 1, 2, 3], dimensions=self.reference.dimensions, ) self.results.distances[i][self._frame_index] = distance @@ -490,7 +494,7 @@ def _conclude(self): force_constant=self.angle_force_constant, temperature=self.temperature ) - for angle in self.results.angles + for angle in self.results.angles[i] ) angle_variance = check_angular_variance( self.results.angles[i] * unit.radians, @@ -501,7 +505,7 @@ def _conclude(self): # Check dihedrals dihed_bounds = all( check_dihedral_bounds(dihed * unit.radians) - for dihed in self.results.dihedrals + for dihed in self.results.dihedrals[i] ) dihed_variance = check_angular_variance( self.results.dihedrals[i] * unit.radians, @@ -543,7 +547,7 @@ class EvaluateHostAtoms2(EvaluateHostAtoms1): """ def _prepare(self): self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) - self.results.ditances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.distances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) self.results.collinear = np.empty( (len(self.host_atom_pool), self.n_frames), @@ -554,7 +558,7 @@ def _prepare(self): dtype=bool, ) # Default to valid == False - self.results.valid = False + self.results.valid[:] = False def _single_frame(self): for i, at in enumerate(self.host_atom_pool): @@ -577,6 +581,7 @@ def _single_frame(self): ) collinear = is_collinear( positions=np.vstack((at.position, self.reference.positions)), + atoms=[0, 1, 2, 3], dimensions=self.reference.dimensions, ) self.results.distances1[i][self._frame_index] = distance1 @@ -594,7 +599,7 @@ def _conclude(self): ) dihed_bounds = all( check_dihedral_bounds(dihed * unit.radians) - for dihed in self.results.dihedrals + for dihed in self.results.dihedrals[i] ) dihed_variance = check_angular_variance( self.results.dihedrals[i] * unit.radians, @@ -665,6 +670,7 @@ def _find_host_anchor( angle_force_constant, temperature, ) + h1_eval.run() for j, valid_h1 in enumerate(h1_eval.results.valid): # If valid H1 atom, evaluate rest of host_atom_pool for # suitability as H2 atoms @@ -677,6 +683,7 @@ def _find_host_anchor( angle_force_constant, temperature, ) + h2_eval.run() if any(h2_eval.results.valid): # Get the sum of the average distances (dsum_avgs) @@ -732,12 +739,11 @@ def _get_restraint_distances( dihed3 : unit.Quantity The H0-G0-G1-G2 dihedral value. """ - bond = calc_bonds( atomgroup.atoms[0].position, - atomgroup.atoms[3], + atomgroup.atoms[3].position, box=atomgroup.dimensions - ) + ) * unit.angstroms angles = [] for idx_set in [[1, 0, 3], [0, 3, 4]]: @@ -896,13 +902,14 @@ def find_boresch_restraint( rmsf_cutoff=rmsf_cutoff, ) - if len(guest_anchors) != 0: + if len(guest_anchors) == 0: errmsg = "No suitable ligand atoms found for the restraint." raise ValueError(errmsg) # 2. We then loop through the guest anchors to find suitable host atoms for guest_anchor in guest_anchors: # We next fetch the host atom pool + # Note: return is a set, so need to convert it later on host_pool = find_host_atom_candidates( topology=topology, trajectory=trajectory, @@ -917,7 +924,7 @@ def find_boresch_restraint( host_anchor = _find_host_anchor( guest_atoms=u.atoms[list(guest_anchor)], - host_atom_pool=u.atoms[host_pool], + host_atom_pool=u.atoms[list(host_pool)], minimum_distance=0.5 * unit.nanometer, angle_force_constant=angle_force_constant, temperature=temperature, @@ -932,7 +939,7 @@ def find_boresch_restraint( # Set the equilibrium values as those of the final frame u.trajectory[-1] - atomgroup = u.atoms[host_anchor + guest_anchor] + atomgroup = u.atoms[list(host_anchor) + list(guest_anchor)] bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( atomgroup ) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index bc9ea625b..2872fb3a1 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -11,6 +11,7 @@ from itertools import combinations import numpy as np import numpy.typing as npt +import pathlib from scipy.stats import circvar import openmm @@ -92,7 +93,7 @@ def _get_mda_coord_format( Optional[MemoryReader] Either the MemoryReader class or None. """ - if isinstance(coordinates, npt.NDArray): + if isinstance(coordinates, np.ndarray): return MemoryReader else: return None @@ -214,7 +215,7 @@ def get_central_atom_idx(rdmol: Chem.Mol) -> int: offmol = OFFMol(rdmol, allow_undefined_stereo=True) nx_mol = offmol.to_networkx() - if not nx.is_weakly_connected(nx_mol): + if not nx.is_weakly_connected(nx_mol.to_directed()): errmsg = "A disconnected molecule was passed, cannot find the center" raise ValueError(errmsg) @@ -317,15 +318,15 @@ def check_angle_not_flat( check2 = 0.5 * frc_const * np.power((angle_rads - np.pi), 2) ang_check_1 = check1 / RT ang_check_2 = check2 / RT - if ang_check_1 < 10.0 or ang_check_2 < 10.0: + if ang_check_1.m < 10.0 or ang_check_2.m < 10.0: return False return True def check_dihedral_bounds( dihedral: unit.Quantity, - lower_cutoff: unit.Quantity = 2.618 * unit.radians, - upper_cutoff: unit.Quantity = -2.618 * unit.radians, + lower_cutoff: unit.Quantity = -2.618 * unit.radians, + upper_cutoff: unit.Quantity = 2.618 * unit.radians, ) -> bool: """ Check that a dihedral does not exceed the bounds set by @@ -415,8 +416,13 @@ def __init__( ): super().__init__(host_atoms.universe.trajectory, **kwargs) - self.host_ag = host_atoms - self.guest_ag = guest_atoms + def get_atomgroup(ag): + if ag._is_group: + return ag + return mda.AtomGroup([ag]) + + self.host_ag = get_atomgroup(host_atoms) + self.guest_ag = get_atomgroup(guest_atoms) self.min_cutoff = min_search_distance.to("angstrom").m self.max_cutoff = max_search_distance.to("angstrom").m @@ -433,11 +439,11 @@ def _single_frame(self): return_distances=False, ) - host_idxs = [self.guest_ag.atoms[p].ix for p in pairs[:, 1]] + host_idxs = [self.host_ag.atoms[p].ix for p in pairs[:, 0]] self.results.host_idxs.update(set(host_idxs)) def _conclude(self): - self.results.host_idxs = np.array(self.results.host_idxs) + self.results.host_idxs = np.array(list(self.results.host_idxs)) def get_local_rmsf(atomgroup: mda.AtomGroup) -> unit.Quantity: diff --git a/openfe/tests/protocols/restraints/test_geometry_harmonic.py b/openfe/tests/protocols/restraints/test_geometry_harmonic.py new file mode 100644 index 000000000..80c0e8134 --- /dev/null +++ b/openfe/tests/protocols/restraints/test_geometry_harmonic.py @@ -0,0 +1,23 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe + +import pytest + +from openfe.protocols.restraint_utils.geometry.harmonic import ( + DistanceRestraintGeometry +) + + +def test_hostguest_geometry(): + """ + A very basic will it build test. + """ + geom = DistanceRestraintGeometry(guest_atoms=[1, 2, 3], host_atoms=[4]) + + assert isinstance(geom, DistanceRestraintGeometry) + + +def test_get_distance_restraint(): + """ + Check that you get a distance restraint. + """ diff --git a/openfe/tests/protocols/restraints/test_omm_restraints.py b/openfe/tests/protocols/restraints/test_omm_restraints.py index 0e346f9c5..0315d5b51 100644 --- a/openfe/tests/protocols/restraints/test_omm_restraints.py +++ b/openfe/tests/protocols/restraints/test_omm_restraints.py @@ -28,4 +28,4 @@ def test_parameter_state_suffix(suffix, lambda_var): assert getattr(param_state, param_name) == lambda_var assert len(param_state._parameters.keys()) == 1 assert param_state._parameters[param_name] == lambda_var - assert param_state._parameters_name_suffix == suffix + assert param_state._parameters_name_suffix == suffix \ No newline at end of file diff --git a/openfe/tests/protocols/restraints/test_settings.py b/openfe/tests/protocols/restraints/test_settings.py index 82660cfaf..7c027df79 100644 --- a/openfe/tests/protocols/restraints/test_settings.py +++ b/openfe/tests/protocols/restraints/test_settings.py @@ -4,8 +4,6 @@ Test the restraint settings. """ import pytest -import numpy as np -import openmm from openff.units import unit from openfe.protocols.restraint_utils.settings import ( DistanceRestraintSettings, @@ -83,7 +81,7 @@ def test_boresch_restraint_negative_idxs(): working as expected. """ with pytest.raises(ValueError, match='negative indices'): - settings = BoreschRestraintSettings( + _ = BoreschRestraintSettings( K_r=10 * unit.kilojoule_per_mole / unit.nm ** 2, K_thetaA=10 * unit.kilojoule_per_mole / unit.radians ** 2, K_thetaB=10 * unit.kilojoule_per_mole / unit.radians ** 2, From 46465fbaba0c7cb40aab26c6c34f938fc1677fae Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Thu, 23 Jan 2025 11:23:46 +0100 Subject: [PATCH 142/163] Small changes --- openfe/protocols/openmm_septop/equil_septop_settings.py | 4 +++- openfe/protocols/openmm_septop/femto_restraints.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index cce48f29f..e969bded7 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -58,7 +58,9 @@ class ComplexRestraintsSettings(RestraintsSettings): class Config: arbitrary_types_allowed = True - k_theta: FloatQuantity['kJ/(mol*rad**2)'] = 83.68 * unit.kilojoule_per_mole / unit.radians ** 2 + # k_theta: FloatQuantity['kJ/(mol*rad**2)'] = 83.68 * unit.kilojoule_per_mole / unit.radians ** 2 + k_theta: FloatQuantity[ + 'kJ/(mol*rad**2)'] = 836.8 * unit.kilojoule_per_mole / unit.radians ** 2 class LambdaSettings(SettingsBaseModel): diff --git a/openfe/protocols/openmm_septop/femto_restraints.py b/openfe/protocols/openmm_septop/femto_restraints.py index 623dc762c..486677fd7 100644 --- a/openfe/protocols/openmm_septop/femto_restraints.py +++ b/openfe/protocols/openmm_septop/femto_restraints.py @@ -714,7 +714,7 @@ def create_boresch_restraint( for key, value in [ ("k_dist_a", k_distance), - ("k_theta_a", k_theta * 2 * 10), + ("k_theta_a", k_theta * 2), ("k_theta_b", k_theta), ("k_phi_a", k_theta), ("k_phi_b", k_theta), From 7906641524732b9d1a38b865bfc34056f1ddfca3 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 24 Jan 2025 01:23:03 +0000 Subject: [PATCH 143/163] Now with DSSP! --- .../restraint_utils/geometry/boresch.py | 61 ++++++++++++++++++- .../restraint_utils/geometry/utils.py | 14 +++-- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py index 03c8f385a..56a8f55e1 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ b/openfe/protocols/restraint_utils/geometry/boresch.py @@ -7,6 +7,7 @@ ---- * Add relevant duecredit entries. """ +import itertools import pathlib from typing import Union, Optional, Iterable @@ -17,6 +18,7 @@ from openff.models.types import FloatQuantity import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase +from MDAnalysis.analysis.dssp import DSSP from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals import numpy as np import numpy.typing as npt @@ -372,9 +374,62 @@ def find_host_atom_candidates( # Should be able to just call MDA's DSSP method # but will need to catch an exception if dssp_filter: - raise NotImplementedError( - "DSSP filtering is not currently implemented" - ) + # TODO: make this a method + # We use "host_ag" to get the entire host + protein_ag = host_ag.select_atoms('protein') + if len(protein_ag) < 50: + # TODO: make this not fail but warn? + errmsg = "Insufficient protein residues were found - cannot run DSSP filter" + raise ValueError(errmsg) + + # Split by fragments + if not hasattr(protein_ag, 'bonds'): + protein_ag.guess_bonds() + + fragments = protein_ag.fragments + + structure = [] + helix_count = 0 + sheet_count = 0 + for frag in fragments: + # Note: will want to always skip the first and last residues because that trips up DSSP + # TODO: make the skip a user-supplied thing + chain = frag.residues[10:-10].atoms + # Run on the last frame + dssp = DSSP(chain).run(start=-1) + + # Tag each residue motif by its resindex + dssp_results = [ + (motif, resid) for motif, resid in + zip(dssp.results.dssp[0], chain.residues.resindices) + ] + + helix_count += list(dssp.results.dssp[0]).count('H') + sheet_count += list(dssp.results.dssp[0]).count('E') + + for _, group in itertools.groupby(dssp_results, lambda x: x[0]): + structure.append(list(group)) + + allowed_motifs = ['H'] + if helix_count < sheet_count: + allowed_motifs.append('E') + + allowed_residxs = [] + for motif_chain in structure: + # TODO: make the value of a "stable sheet/helix" user selectable + if motif_chain[0][0] in allowed_motifs and len(motif_chain) > 7: + # TODO: make the amount of residues to remove at the edges user + # selectable? + allowed_residxs.extend( + [residue[1] for residue in motif_chain[3:-3]] + ) + + # Resindexes at key at the Universe scale not atomgroup + allowed_atoms = protein_ag.universe.residues[allowed_residxs].atoms + + # Pick up all the atoms that intersect the initial selection and + # those allowed. + selected_host_ag = selected_host_ag.intersection(allowed_atoms) # 1. Get the RMSF & filter to create a new AtomGroup rmsf = get_local_rmsf(selected_host_ag) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 2872fb3a1..d821474ef 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -427,20 +427,24 @@ def get_atomgroup(ag): self.max_cutoff = max_search_distance.to("angstrom").m def _prepare(self): - self.results.host_idxs = set() + self.results.host_idxs = set(self.host_ag.atoms.ix) def _single_frame(self): pairs = capped_distance( - reference=self.host_ag.positions, - configuration=self.guest_ag.positions, + reference=self.guest_ag.positions, + configuration=self.host_ag.positions, max_cutoff=self.max_cutoff, min_cutoff=self.min_cutoff, box=self.guest_ag.universe.dimensions, return_distances=False, ) - host_idxs = [self.host_ag.atoms[p].ix for p in pairs[:, 0]] - self.results.host_idxs.update(set(host_idxs)) + host_idxs = set(self.host_ag.atoms[p].ix for p in pairs[:, 1]) + + # Only keep indices that fit the distance criteria + self.results.host_idxs = self.results.host_idxs.intersection( + host_idxs + ) def _conclude(self): self.results.host_idxs = np.array(list(self.results.host_idxs)) From a52f93bfb73f043b9cb76695f8467cfe921fb55f Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 24 Jan 2025 07:45:37 +0000 Subject: [PATCH 144/163] the big refactor --- .../restraint_utils/geometry/boresch.py | 1011 ----------------- .../geometry/boresch/__init__.py | 4 + .../geometry/boresch/geometry.py | 298 +++++ .../restraint_utils/geometry/boresch/guest.py | 251 ++++ .../restraint_utils/geometry/boresch/host.py | 416 +++++++ .../restraint_utils/geometry/flatbottom.py | 25 +- .../restraint_utils/geometry/harmonic.py | 24 +- .../restraint_utils/geometry/utils.py | 141 ++- 8 files changed, 1121 insertions(+), 1049 deletions(-) delete mode 100644 openfe/protocols/restraint_utils/geometry/boresch.py create mode 100644 openfe/protocols/restraint_utils/geometry/boresch/__init__.py create mode 100644 openfe/protocols/restraint_utils/geometry/boresch/geometry.py create mode 100644 openfe/protocols/restraint_utils/geometry/boresch/guest.py create mode 100644 openfe/protocols/restraint_utils/geometry/boresch/host.py diff --git a/openfe/protocols/restraint_utils/geometry/boresch.py b/openfe/protocols/restraint_utils/geometry/boresch.py deleted file mode 100644 index 56a8f55e1..000000000 --- a/openfe/protocols/restraint_utils/geometry/boresch.py +++ /dev/null @@ -1,1011 +0,0 @@ -# This code is part of OpenFE and is licensed under the MIT license. -# For details, see https://github.com/OpenFreeEnergy/openfe -""" -Restraint Geometry classes - -TODO ----- -* Add relevant duecredit entries. -""" -import itertools -import pathlib -from typing import Union, Optional, Iterable - -from rdkit import Chem - -import openmm -from openff.units import unit -from openff.models.types import FloatQuantity -import MDAnalysis as mda -from MDAnalysis.analysis.base import AnalysisBase -from MDAnalysis.analysis.dssp import DSSP -from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals -import numpy as np -import numpy.typing as npt - -from .base import HostGuestRestraintGeometry -from .utils import ( - _get_mda_coord_format, - _get_mda_topology_format, - get_aromatic_rings, - get_heavy_atom_idxs, - get_central_atom_idx, - is_collinear, - check_angular_variance, - check_dihedral_bounds, - check_angle_not_flat, - FindHostAtoms, - get_local_rmsf -) - - -class BoreschRestraintGeometry(HostGuestRestraintGeometry): - """ - A class that defines the restraint geometry for a Boresch restraint. - - The restraint is defined by the following: - - H2 G2 - - - - - - - H1 - - H0 -- G0 - - G1 - - Where HX represents the X index of ``host_atoms`` and GX - the X index of ``guest_atoms``. - """ - r_aA0: FloatQuantity['nanometer'] - """ - The equilibrium distance between H0 and G0. - """ - theta_A0: FloatQuantity['radians'] - """ - The equilibrium angle value between H1, H0, and G0. - """ - theta_B0: FloatQuantity['radians'] - """ - The equilibrium angle value between H0, G0, and G1. - """ - phi_A0: FloatQuantity['radians'] - """ - The equilibrium dihedral value between H2, H1, H0, and G0. - """ - phi_B0: FloatQuantity['radians'] - - """ - The equilibrium dihedral value between H1, H0, G0, and G1. - """ - phi_C0: FloatQuantity['radians'] - - """ - The equilibrium dihedral value between H0, G0, G1, and G2. - """ - - -def _sort_by_distance_from_atom( - rdmol: Chem.Mol, target_idx: int, atom_idxs: Iterable[int] -) -> list[int]: - """ - Sort a list of RDMol atoms by their distance from a target atom. - - Parameters - ---------- - target_idx : int - The idx of the atom to measure from. - atom_idxs : list[int] - The idx values of the atoms to sort. - rdmol : Chem.Mol - RDKit Molecule the atoms belong to - - Returns - ------- - list[int] - The input atom idxs sorted by their distance from the target atom. - """ - distances = [] - - conformer = rdmol.GetConformer() - # Get the target atom position - target_pos = conformer.GetAtomPosition(target_idx) - - for idx in atom_idxs: - pos = conformer.GetAtomPosition(idx) - distances.append(((target_pos - pos).Length(), idx)) - - return [i[1] for i in sorted(distances)] - - -def _bonded_angles_from_pool( - rdmol: Chem.Mol, - atom_idx: int, - atom_pool: list[int], - aromatic_only: bool, -) -> list[tuple[int, int, int]]: - """ - Get all bonded angles starting from ``atom_idx`` from a pool of atoms. - - Parameters - ---------- - rdmol : Chem.Mol - The RDKit Molecule - atom_idx : int - The index of the atom to search angles from. - atom_pool : list[int] - The list of indices to pick possible angle partners from. - aromatic_only : bool - Prune any angles that include non-aromatic bonds. - - Returns - ------- - list[tuple[int, int, int]] - A list of tuples containing all the angles. - - Notes - ----- - * In the original SepTop code at3 is picked as directly bonded to at1. - By comparison here we instead follow the case that at3 is bonded to - at2 but not bonded to at1. - """ - angles = [] - - # Get the base atom and its neighbors - at1 = rdmol.GetAtomWithIdx(atom_idx) - at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] - - # We loop at2 and at3 through the sorted atom_pool in order to get - # a list of angles in the branch that are sorted by how close the atoms - # are from the central atom - for at2 in atom_pool: - if at2 in at1_neighbors: - at2_neighbors = [ - at.GetIdx() for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() - ] - for at3 in atom_pool: - if at3 != atom_idx and at3 in at2_neighbors: - angles.append((atom_idx, at2, at3)) - - if aromatic_only: # TODO: move this to its own method? - aromatic_rings = get_aromatic_rings(rdmol) - - def _belongs_to_ring(angle, aromatic_rings): - for ring in aromatic_rings: - if all(a in ring for a in angle): - return True - return False - - for angle in angles: - if not _belongs_to_ring(angle, aromatic_rings): - angles.remove(angle) - - return angles - - -def _get_guest_atom_pool( - rdmol: Chem.Mol, - rmsf: npt.NDArray, - rmsf_cutoff: unit.Quantity -) -> tuple[Optional[set[int]], bool]: - """ - Filter atoms based on rmsf & rings, defaulting to heavy atoms if - there are not enough. - - Parameters - ---------- - rdmol : Chem.Mol - The RDKit Molecule to search through - rmsf : npt.NDArray - A 1-D array of RMSF values for each atom. - rmsf_cutoff : unit.Quantity - The rmsf cutoff value for selecting atoms in units compatible with - nanometer. - - Returns - ------- - atom_pool : Optional[set[int]] - A pool of candidate atoms. - ring_atoms_only : bool - True if only ring atoms were selected. - """ - # Get a list of all the aromatic rings - # Note: no need to keep track of rings because we'll filter by - # bonded terms after, so if we only keep rings then all the bonded - # atoms should be within the same ring system. - atom_pool: set[tuple[int]] = set() - ring_atoms_only: bool = True - for ring in get_aromatic_rings(rdmol): - max_rmsf = rmsf[list(ring)].max() - if max_rmsf < rmsf_cutoff: - atom_pool.update(ring) - - # if we don't have enough atoms just get all the heavy atoms - if len(atom_pool) < 3: - ring_atoms_only = False - heavy_atoms = get_heavy_atom_idxs(rdmol) - atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) - if len(atom_pool) < 3: - return None, False - - return atom_pool, ring_atoms_only - - -def find_guest_atom_candidates( - topology: Union[str, pathlib.Path, openmm.app.Topology], - trajectory: Union[str, pathlib.Path, npt.NDArray], - rdmol: Chem.Mol, - guest_idxs: list[int], - rmsf_cutoff: unit.Quantity = 1 * unit.nanometer, -) -> list[tuple[int]]: - """ - Get a list of potential ligand atom choices for a Boresch restraint - being applied to a given small molecule. - - Parameters - ---------- - topology : Union[str, openmm.app.Topology] - The topology of the system. - trajectory : Union[str, pathlib.Path, npt.NDArray] - A path to the system's coordinate trajectory. - rdmol : Chem.Mol - An RDKit Molecule representing the small molecule ordered in - the same way as it is listed in the topology. - guest_idxs : list[int] - The ligand indices in the topology. - rmsf_cutoff : unit.Quantity - The RMSF filter cut-off. - - Returns - ------- - angle_list : list[tuple[int]] - A list of tuples for each valid G0, G1, G2 angle. If ``None``, no - angles could be found. - - Raises - ------ - ValueError - If no suitable ligand atoms could be found. - - TODO - ---- - Should the RDMol have a specific frame position? - """ - u = mda.Universe( - topology, - trajectory, - format=_get_mda_coord_format(trajectory), - topology_format=_get_mda_topology_format(topology), - ) - - ligand_ag = u.atoms[guest_idxs] - - # 0. Get the ligand RMSF - rmsf = get_local_rmsf(ligand_ag) - u.trajectory[-1] # forward to the last frame - - # 1. Get the pool of atoms to work with - atom_pool, rings_only = _get_guest_atom_pool(rdmol, rmsf, rmsf_cutoff) - - if atom_pool is None: - # We don't have enough atoms so we raise an error - errmsg = "No suitable ligand atoms were found for the restraint" - raise ValueError(errmsg) - - # 2. Get the central atom - center = get_central_atom_idx(rdmol) - - # 3. Sort the atom pool based on their distance from the center - sorted_atom_pool = _sort_by_distance_from_atom(rdmol, center, atom_pool) - - # 4. Get a list of probable angles - angles_list = [] - for atom in sorted_atom_pool: - angles = _bonded_angles_from_pool( - rdmol=rdmol, - atom_idx=atom, - atom_pool=sorted_atom_pool, - aromatic_only=rings_only, - ) - for angle in angles: - # Check that the angle is at least not collinear - angle_ag = ligand_ag.atoms[list(angle)] - if not is_collinear(ligand_ag.positions, angle, u.dimensions): - angles_list.append( - ( - angle_ag.atoms[0].ix, - angle_ag.atoms[1].ix, - angle_ag.atoms[2].ix - ) - ) - - return angles_list - - -def find_host_atom_candidates( - topology: Union[str, pathlib.Path, openmm.app.Topology], - trajectory: Union[str, pathlib.Path, npt.NDArray], - host_idxs: list[int], - l1_idx: int, - host_selection: str, - dssp_filter: bool = False, - rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, - min_distance: unit.Quantity = 1 * unit.nanometer, - max_distance: unit.Quantity = 3 * unit.nanometer, -) -> npt.NDArray: - """ - Get a list of suitable host atoms. - - Parameters - ---------- - topology : Union[str, openmm.app.Topology] - The topology of the system. - trajectory : Union[str, pathlib.Path, npt.NDArray] - The system's coordinate trajectory. - host_idxs : list[int] - A list of the host indices in the system topology. - l1_idx : int - The index of the proposed l1 binding atom. - host_selection : str - An MDAnalysis selection string to filter the host by. - dssp_filter : bool - Whether or not to apply a DSSP filter on the host selection. - rmsf_cutoff : uni.Quantity - The maximum RMSF value allowwed for any candidate host atom. - min_distance : unit.Quantity - The minimum search distance around l1 for suitable candidate atoms. - max_distance : unit.Quantity - The maximum search distance around l1 for suitable candidate atoms. - - Return - ------ - NDArray - Array of host atom indexes - """ - u = mda.Universe( - topology, - trajectory, - format=_get_mda_coord_format(trajectory), - topology_format=_get_mda_topology_format(topology), - ) - - # Get an AtomGroup for the host based on the input host indices - host_ag = u.atoms[host_idxs] - # Filter the host AtomGroup based on ``host_selection` - selected_host_ag = host_ag.select_atoms(host_selection) - - # 0. TODO: implement DSSP filter - # Should be able to just call MDA's DSSP method - # but will need to catch an exception - if dssp_filter: - # TODO: make this a method - # We use "host_ag" to get the entire host - protein_ag = host_ag.select_atoms('protein') - if len(protein_ag) < 50: - # TODO: make this not fail but warn? - errmsg = "Insufficient protein residues were found - cannot run DSSP filter" - raise ValueError(errmsg) - - # Split by fragments - if not hasattr(protein_ag, 'bonds'): - protein_ag.guess_bonds() - - fragments = protein_ag.fragments - - structure = [] - helix_count = 0 - sheet_count = 0 - for frag in fragments: - # Note: will want to always skip the first and last residues because that trips up DSSP - # TODO: make the skip a user-supplied thing - chain = frag.residues[10:-10].atoms - # Run on the last frame - dssp = DSSP(chain).run(start=-1) - - # Tag each residue motif by its resindex - dssp_results = [ - (motif, resid) for motif, resid in - zip(dssp.results.dssp[0], chain.residues.resindices) - ] - - helix_count += list(dssp.results.dssp[0]).count('H') - sheet_count += list(dssp.results.dssp[0]).count('E') - - for _, group in itertools.groupby(dssp_results, lambda x: x[0]): - structure.append(list(group)) - - allowed_motifs = ['H'] - if helix_count < sheet_count: - allowed_motifs.append('E') - - allowed_residxs = [] - for motif_chain in structure: - # TODO: make the value of a "stable sheet/helix" user selectable - if motif_chain[0][0] in allowed_motifs and len(motif_chain) > 7: - # TODO: make the amount of residues to remove at the edges user - # selectable? - allowed_residxs.extend( - [residue[1] for residue in motif_chain[3:-3]] - ) - - # Resindexes at key at the Universe scale not atomgroup - allowed_atoms = protein_ag.universe.residues[allowed_residxs].atoms - - # Pick up all the atoms that intersect the initial selection and - # those allowed. - selected_host_ag = selected_host_ag.intersection(allowed_atoms) - - # 1. Get the RMSF & filter to create a new AtomGroup - rmsf = get_local_rmsf(selected_host_ag) - filtered_host_ag = selected_host_ag.atoms[rmsf < rmsf_cutoff] - - # 2. Search of atoms within the min/max cutoff - atom_finder = FindHostAtoms( - host_atoms=filtered_host_ag, - guest_atoms=u.atoms[l1_idx], - min_search_distance=min_distance, - max_search_distance=max_distance, - ) - atom_finder.run() - return atom_finder.results.host_idxs - - -class EvaluateHostAtoms1(AnalysisBase): - """ - Class to evaluate the suitability of a set of host atoms - as either H0 or H1 atoms (i.e. the first and second host atoms). - - Parameters - ---------- - reference : MDAnalysis.AtomGroup - The reference preceeding three atoms. - host_atom_pool : MDAnalysis.AtomGroup - The pool of atoms to pick an atom from. - minimum_distance : unit.Quantity - The minimum distance from the bound reference atom. - angle_force_constant : unit.Quantity - The force constant for the angle. - temperature : unit.Quantity - The system temperature in Kelvin - """ - def __init__( - self, - reference, - host_atom_pool, - minimum_distance, - angle_force_constant, - temperature, - **kwargs, - ): - super().__init__(reference.universe.trajectory, **kwargs) - - if len(reference) != 3: - errmsg = "Incorrect number of reference atoms passed" - raise ValueError(errmsg) - - self.reference = reference - self.host_atom_pool = host_atom_pool - self.minimum_distance = minimum_distance.to("angstrom").m - self.angle_force_constant = angle_force_constant - self.temperature = temperature - - def _prepare(self): - self.results.distances = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.angles = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.dihedrals = np.zeros( - (len(self.host_atom_pool), self.n_frames) - ) - self.results.collinear = np.empty( - (len(self.host_atom_pool), self.n_frames), - dtype=bool, - ) - self.results.valid = np.empty( - len(self.host_atom_pool), - dtype=bool, - ) - # Set everything to False to begin with - self.results.valid[:] = False - - def _single_frame(self): - for i, at in enumerate(self.host_atom_pool): - distance = calc_bonds( - at.position, - self.reference.atoms[0].position, - box=self.reference.dimensions, - ) - angle = calc_angles( - at.position, - self.reference.atoms[0].position, - self.reference.atoms[1].position, - box=self.reference.dimensions, - ) - dihedral = calc_dihedrals( - at.position, - self.reference.atoms[0].position, - self.reference.atoms[1].position, - self.reference.atoms[2].position, - box=self.reference.dimensions, - ) - collinear = is_collinear( - positions=np.vstack((at.position, self.reference.positions)), - atoms=[0, 1, 2, 3], - dimensions=self.reference.dimensions, - ) - self.results.distances[i][self._frame_index] = distance - self.results.angles[i][self._frame_index] = angle - self.results.dihedrals[i][self._frame_index] = dihedral - self.results.collinear[i][self._frame_index] = collinear - - def _conclude(self): - for i, at in enumerate(self.host_atom_pool): - # Check distances - distance_bounds = all( - self.results.distances[i] > self.minimum_distance - ) - # Check angles - angle_bounds = all( - check_angle_not_flat( - angle=angle * unit.radians, - force_constant=self.angle_force_constant, - temperature=self.temperature - ) - for angle in self.results.angles[i] - ) - angle_variance = check_angular_variance( - self.results.angles[i] * unit.radians, - upper_bound=np.pi * unit.radians, - lower_bound=0 * unit.radians, - width=1.745 * unit.radians, - ) - # Check dihedrals - dihed_bounds = all( - check_dihedral_bounds(dihed * unit.radians) - for dihed in self.results.dihedrals[i] - ) - dihed_variance = check_angular_variance( - self.results.dihedrals[i] * unit.radians, - upper_bound=np.pi * unit.radians, - lower_bound=-np.pi * unit.radians, - width=5.23 * unit.radians, - ) - not_collinear = not all(self.results.collinear[i]) - if all( - [ - distance_bounds, - angle_bounds, - angle_variance, - dihed_bounds, - dihed_variance, - not_collinear, - ] - ): - self.results.valid[i] = True - - -class EvaluateHostAtoms2(EvaluateHostAtoms1): - """ - Class to evaluate the suitability of a set of host atoms - as H2 atoms (i.e. the third host atoms). - - Parameters - ---------- - reference : MDAnalysis.AtomGroup - The reference preceeding three atoms. - host_atom_pool : MDAnalysis.AtomGroup - The pool of atoms to pick an atom from. - minimum_distance : unit.Quantity - The minimum distance from the bound reference atom. - angle_force_constant : unit.Quantity - The force constant for the angle. - temperature : unit.Quantity - The system temperature in Kelvin - """ - def _prepare(self): - self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) - self.results.distances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) - self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) - self.results.collinear = np.empty( - (len(self.host_atom_pool), self.n_frames), - dtype=bool, - ) - self.results.valid = np.empty( - len(self.host_atom_pool), - dtype=bool, - ) - # Default to valid == False - self.results.valid[:] = False - - def _single_frame(self): - for i, at in enumerate(self.host_atom_pool): - distance1 = calc_bonds( - at.position, - self.reference.atoms[0].position, - box=self.reference.dimensions, - ) - distance2 = calc_bonds( - at.position, - self.reference.atoms[1].position, - box=self.reference.dimensions, - ) - dihedral = calc_dihedrals( - at.position, - self.reference.atoms[0].position, - self.reference.atoms[1].position, - self.reference.atoms[2].position, - box=self.reference.dimensions, - ) - collinear = is_collinear( - positions=np.vstack((at.position, self.reference.positions)), - atoms=[0, 1, 2, 3], - dimensions=self.reference.dimensions, - ) - self.results.distances1[i][self._frame_index] = distance1 - self.results.distances2[i][self._frame_index] = distance2 - self.results.dihedrals[i][self._frame_index] = dihedral - self.results.collinear[i][self._frame_index] = collinear - - def _conclude(self): - for i, at in enumerate(self.host_atom_pool): - distance1_bounds = all( - self.results.distances1[i] > self.minimum_distance - ) - distance2_bounds = all( - self.results.distances2[i] > self.minimum_distance - ) - dihed_bounds = all( - check_dihedral_bounds(dihed * unit.radians) - for dihed in self.results.dihedrals[i] - ) - dihed_variance = check_angular_variance( - self.results.dihedrals[i] * unit.radians, - upper_bound=np.pi * unit.radians, - lower_bound=-np.pi * unit.radians, - width=5.23 * unit.radians, - ) - not_collinear = not all(self.results.collinear[i]) - if all( - [ - distance1_bounds, - distance2_bounds, - dihed_bounds, - dihed_variance, - not_collinear, - ] - ): - self.results.valid[i] = True - - -def _find_host_anchor( - guest_atoms: mda.AtomGroup, - host_atom_pool: mda.AtomGroup, - minimum_distance: unit.Quantity, - angle_force_constant: unit.Quantity, - temperature: unit.Quantity -) -> Optional[list[int]]: - """ - Find suitable atoms for the H0-H1-H2 portion of the restraint. - - Parameters - ---------- - guest_atoms : mda.AtomGroup - The guest anchor atoms for G0-G1-G2 - host_atom_pool : mda.AtomGroup - The host atoms to search from. - minimum_distance : unit.Quantity - The minimum distance to pick host atoms from each other. - angle_force_constant : unit.Quantity - The force constant for the G1-G0-H0 and G0-H0-H1 angles. - temperature : unit.Quantity - The target system temperature. - - Returns - ------- - Optional[list[int]] - A list of indices for a selected combination of H0, H1, and H2. - """ - # Evalulate the host_atom_pool for suitability as H0 atoms - h0_eval = EvaluateHostAtoms1( - guest_atoms, - host_atom_pool, - minimum_distance, - angle_force_constant, - temperature, - ) - h0_eval.run() - - for i, valid_h0 in enumerate(h0_eval.results.valid): - # If valid H0 atom, evaluate rest of host_atom_pool for suitability - # as H1 atoms. - if valid_h0: - h0g0g1_atoms = host_atom_pool.atoms[i] + guest_atoms.atoms[:2] - h1_eval = EvaluateHostAtoms1( - h0g0g1_atoms, - host_atom_pool, - minimum_distance, - angle_force_constant, - temperature, - ) - h1_eval.run() - for j, valid_h1 in enumerate(h1_eval.results.valid): - # If valid H1 atom, evaluate rest of host_atom_pool for - # suitability as H2 atoms - if valid_h1: - h1h0g0_atoms = host_atom_pool.atoms[j] + h0g0g1_atoms.atoms[:2] - h2_eval = EvaluateHostAtoms2( - h1h0g0_atoms, - host_atom_pool, - minimum_distance, - angle_force_constant, - temperature, - ) - h2_eval.run() - - if any(h2_eval.results.valid): - # Get the sum of the average distances (dsum_avgs) - # for all the host_atom_pool atoms - distance1_avgs = np.array( - [d.mean() for d in h2_eval.results.distances1] - ) - distance2_avgs = np.array( - [d.mean() for d in h2_eval.results.distances2] - ) - dsum_avgs = distance1_avgs + distance2_avgs - - # Now filter by validity as H2 atom - h2_dsum_avgs = [ - (idx, val) for idx, val in enumerate(dsum_avgs) - if h2_eval.results.valid[idx] - ] - - # Get the index of the H2 atom with the lowest - # average distance - k = sorted(h2_dsum_avgs, key=lambda x: x[1])[0][0] - - return list(host_atom_pool.atoms[[i, j, k]].ix) - return None - - -def _get_restraint_distances( - atomgroup: mda.AtomGroup -) -> tuple[unit.Quantity]: - """ - Get the bond, angle, and dihedral distances for an input atomgroup - defining the six atoms for a Boresch-like restraint. - - The atoms must be in the order of H0, H1, H2, G0, G1, G2. - - Parameters - ---------- - atomgroup : mda.AtomGroup - An AtomGroup defining the restrained atoms in order. - - Returns - ------- - bond : unit.Quantity - The H0-G0 bond value. - angle1 : unit.Quantity - The H1-H0-G0 angle value. - angle2 : unit.Quantity - The H0-G0-G1 angle value. - dihed1 : unit.Quantity - The H2-H1-H0-G0 dihedral value. - dihed2 : unit.Quantity - The H1-H0-G0-G1 dihedral value. - dihed3 : unit.Quantity - The H0-G0-G1-G2 dihedral value. - """ - bond = calc_bonds( - atomgroup.atoms[0].position, - atomgroup.atoms[3].position, - box=atomgroup.dimensions - ) * unit.angstroms - - angles = [] - for idx_set in [[1, 0, 3], [0, 3, 4]]: - angle = calc_angles( - atomgroup.atoms[idx_set[0]].position, - atomgroup.atoms[idx_set[1]].position, - atomgroup.atoms[idx_set[2]].position, - box=atomgroup.dimensions, - ) - angles.append(angle * unit.radians) - - dihedrals = [] - for idx_set in [[2, 1, 0, 3], [1, 0, 3, 4], [0, 3, 4, 5]]: - dihed = calc_dihedrals( - atomgroup.atoms[idx_set[0]].position, - atomgroup.atoms[idx_set[1]].position, - atomgroup.atoms[idx_set[2]].position, - atomgroup.atoms[idx_set[3]].position, - box=atomgroup.dimensions, - ) - dihedrals.append(dihed * unit.radians) - - return bond, angles[0], angles[1], dihedrals[0], dihedrals[1], dihedrals[2] - - -def find_boresch_restraint( - topology: Union[str, pathlib.Path, openmm.app.Topology], - trajectory: Union[str, pathlib.Path], - guest_rdmol: Chem.Mol, - guest_idxs: list[int], - host_idxs: list[int], - guest_restraint_atoms_idxs: Optional[list[int]] = None, - host_restraint_atoms_idxs: Optional[list[int]] = None, - host_selection: str = "all", - dssp_filter: bool = False, - rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, - host_min_distance: unit.Quantity = 1 * unit.nanometer, - host_max_distance: unit.Quantity = 3 * unit.nanometer, - angle_force_constant: unit.Quantity = ( - 83.68 * unit.kilojoule_per_mole / unit.radians**2 - ), - temperature: unit.Quantity = 298.15 * unit.kelvin, -) -> BoreschRestraintGeometry: - """ - Find suitable Boresch-style restraints between a host and guest entity - based on the approach of Baumann et al. [1] with some modifications. - - Parameters - ---------- - topology : Union[str, pathlib.Path, openmm.app.Topology] - A topology of the system. - trajectory : Union[str, pathlib.Path] - A path to a coordinate trajectory file. - guest_rdmol : Chem.Mol - An RDKit Mol for the guest molecule. - guest_idxs : list[int] - Indices in the topology for the guest molecule. - host_idxs : list[int] - Indices in the topology for the host molecule. - guest_restraint_atoms_idxs : Optional[list[int]] - User selected indices of the guest molecule itself (i.e. indexed - starting a 0 for the guest molecule). This overrides the - restraint search and a restraint using these indices will - be retruned. Must be defined alongside ``host_restraint_atoms_idxs``. - host_restraint_atoms_idxs : Optional[list[int]] - User selected indices of the host molecule itself (i.e. indexed - starting a 0 for the hosts molecule). This overrides the - restraint search and a restraint using these indices will - be returnned. Must be defined alongside ``guest_restraint_atoms_idxs``. - host_selection : str - An MDAnalysis selection string to sub-select the host atoms. - dssp_filter : bool - Whether or not to filter the host atoms by their secondary structure. - rmsf_cutoff : unit.Quantity - The cutoff value for atom root mean square fluction. Atoms with RMSF - values above this cutoff will be disregarded. - Must be in units compatible with nanometer. - host_min_distance : unit.Quantity - The minimum distance between any host atom and the guest G0 atom. - Must be in units compatible with nanometer. - host_max_distance : unit.Quantity - The maximum distance between any host atom and the guest G0 atom. - Must be in units compatible with nanometer. - angle_force_constant : unit.Quantity - The force constant for the G1-G0-H0 and G0-H0-H1 angles. Must be - in units compatible with kilojoule / mole / radians ** 2. - temperature : unit.Quantity - The system temperature in units compatible with Kelvin. - - Returns - ------- - BoreschRestraintGeometry - An object defining the parameters of the Boresch-like restraint. - - References - ---------- - [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy - calculations using a Separated Topologies approach." (2023). - """ - u = mda.Universe( - topology, - trajectory, - format=_get_mda_coord_format(trajectory), - topology_format=_get_mda_topology_format(topology), - ) - - if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): # fmt: skip - # In this case assume the picked atoms were intentional / - # representative of the input and go with it - guest_ag = u.select_atoms[guest_idxs] - guest_anchor = [ - at.ix for at in guest_ag.atoms[guest_restraint_atoms_idxs] - ] - host_ag = u.select_atoms[host_idxs] - host_anchor = [ - at.ix for at in host_ag.atoms[host_restraint_atoms_idxs] - ] - - # Set the equilibrium values as those of the final frame - u.trajectory[-1] - atomgroup = u.atoms[host_anchor + guest_anchor] - bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( - atomgroup - ) - - # TODO: add checks to warn if this is a badly picked - # set of atoms. - - return BoreschRestraintGeometry( - host_atoms=host_anchor, - guest_atoms=guest_anchor, - r_aA0=bond, - theta_A0=ang1, - theta_B0=ang2, - phi_A0=dih1, - phi_B0=dih2, - phi_C0=dih3 - ) - - if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): # fmt: skip - # This is not an intended outcome, crash out here - errmsg = ( - "both ``guest_restraints_atoms_idxs`` and " - "``host_restraint_atoms_idxs`` " - "must be set or both must be None. " - f"Got {guest_restraint_atoms_idxs} and {host_restraint_atoms_idxs}" - ) - raise ValueError(errmsg) - - # 1. Fetch the guest anchors - guest_anchors = find_guest_atom_candidates( - topology=topology, - trajectory=trajectory, - rdmol=guest_rdmol, - guest_idxs=guest_idxs, - rmsf_cutoff=rmsf_cutoff, - ) - - if len(guest_anchors) == 0: - errmsg = "No suitable ligand atoms found for the restraint." - raise ValueError(errmsg) - - # 2. We then loop through the guest anchors to find suitable host atoms - for guest_anchor in guest_anchors: - # We next fetch the host atom pool - # Note: return is a set, so need to convert it later on - host_pool = find_host_atom_candidates( - topology=topology, - trajectory=trajectory, - host_idxs=host_idxs, - l1_idx=guest_anchor[0], - host_selection=host_selection, - dssp_filter=dssp_filter, - rmsf_cutoff=rmsf_cutoff, - min_distance=host_min_distance, - max_distance=host_max_distance, - ) - - host_anchor = _find_host_anchor( - guest_atoms=u.atoms[list(guest_anchor)], - host_atom_pool=u.atoms[list(host_pool)], - minimum_distance=0.5 * unit.nanometer, - angle_force_constant=angle_force_constant, - temperature=temperature, - ) - # continue if it's empty, otherwise stop - if host_anchor is not None: - break - - if host_anchor is None: - errmsg = "No suitable host atoms could be found" - raise ValueError(errmsg) - - # Set the equilibrium values as those of the final frame - u.trajectory[-1] - atomgroup = u.atoms[list(host_anchor) + list(guest_anchor)] - bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( - atomgroup - ) - - return BoreschRestraintGeometry( - host_atoms=host_anchor, - guest_atoms=guest_anchor, - r_aA0=bond, - theta_A0=ang1, - theta_B0=ang2, - phi_A0=dih1, - phi_B0=dih2, - phi_C0=dih3 - ) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/__init__.py b/openfe/protocols/restraint_utils/geometry/boresch/__init__.py new file mode 100644 index 000000000..64bb4e73f --- /dev/null +++ b/openfe/protocols/restraint_utils/geometry/boresch/__init__.py @@ -0,0 +1,4 @@ +from geometry import ( + BoreschRestraintGeometry, + find_boresch_restraint, +) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/geometry.py b/openfe/protocols/restraint_utils/geometry/boresch/geometry.py new file mode 100644 index 000000000..0640ecf21 --- /dev/null +++ b/openfe/protocols/restraint_utils/geometry/boresch/geometry.py @@ -0,0 +1,298 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +from typing import Optional + +from rdkit import Chem + +from openff.units import unit +from openff.models.types import FloatQuantity +import MDAnalysis as mda +from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals + +from openfe.protocols.restraint_utils.geometry.base import ( + HostGuestRestraintGeometry +) +from .guest import find_guest_atom_candidates +from .host import find_host_atom_candidates, find_host_anchor + + +class BoreschRestraintGeometry(HostGuestRestraintGeometry): + """ + A class that defines the restraint geometry for a Boresch restraint. + + The restraint is defined by the following: + + H2 G2 + - - + - - + H1 - - H0 -- G0 - - G1 + + Where HX represents the X index of ``host_atoms`` and GX + the X index of ``guest_atoms``. + """ + r_aA0: FloatQuantity['nanometer'] + """ + The equilibrium distance between H0 and G0. + """ + theta_A0: FloatQuantity['radians'] + """ + The equilibrium angle value between H1, H0, and G0. + """ + theta_B0: FloatQuantity['radians'] + """ + The equilibrium angle value between H0, G0, and G1. + """ + phi_A0: FloatQuantity['radians'] + """ + The equilibrium dihedral value between H2, H1, H0, and G0. + """ + phi_B0: FloatQuantity['radians'] + + """ + The equilibrium dihedral value between H1, H0, G0, and G1. + """ + phi_C0: FloatQuantity['radians'] + + """ + The equilibrium dihedral value between H0, G0, G1, and G2. + """ + + +def _get_restraint_distances( + atomgroup: mda.AtomGroup +) -> tuple[unit.Quantity]: + """ + Get the bond, angle, and dihedral distances for an input atomgroup + defining the six atoms for a Boresch-like restraint. + + The atoms must be in the order of H0, H1, H2, G0, G1, G2. + + Parameters + ---------- + atomgroup : mda.AtomGroup + An AtomGroup defining the restrained atoms in order. + + Returns + ------- + bond : unit.Quantity + The H0-G0 bond value. + angle1 : unit.Quantity + The H1-H0-G0 angle value. + angle2 : unit.Quantity + The H0-G0-G1 angle value. + dihed1 : unit.Quantity + The H2-H1-H0-G0 dihedral value. + dihed2 : unit.Quantity + The H1-H0-G0-G1 dihedral value. + dihed3 : unit.Quantity + The H0-G0-G1-G2 dihedral value. + """ + bond = calc_bonds( + atomgroup.atoms[0].position, + atomgroup.atoms[3].position, + box=atomgroup.dimensions + ) * unit.angstroms + + angles = [] + for idx_set in [[1, 0, 3], [0, 3, 4]]: + angle = calc_angles( + atomgroup.atoms[idx_set[0]].position, + atomgroup.atoms[idx_set[1]].position, + atomgroup.atoms[idx_set[2]].position, + box=atomgroup.dimensions, + ) + angles.append(angle * unit.radians) + + dihedrals = [] + for idx_set in [[2, 1, 0, 3], [1, 0, 3, 4], [0, 3, 4, 5]]: + dihed = calc_dihedrals( + atomgroup.atoms[idx_set[0]].position, + atomgroup.atoms[idx_set[1]].position, + atomgroup.atoms[idx_set[2]].position, + atomgroup.atoms[idx_set[3]].position, + box=atomgroup.dimensions, + ) + dihedrals.append(dihed * unit.radians) + + return bond, angles[0], angles[1], dihedrals[0], dihedrals[1], dihedrals[2] + + +def find_boresch_restraint( + universe: mda.Universe, + guest_rdmol: Chem.Mol, + guest_idxs: list[int], + host_idxs: list[int], + guest_restraint_atoms_idxs: Optional[list[int]] = None, + host_restraint_atoms_idxs: Optional[list[int]] = None, + host_selection: str = "all", + dssp_filter: bool = False, + rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, + host_min_distance: unit.Quantity = 1 * unit.nanometer, + host_max_distance: unit.Quantity = 3 * unit.nanometer, + angle_force_constant: unit.Quantity = ( + 83.68 * unit.kilojoule_per_mole / unit.radians**2 + ), + temperature: unit.Quantity = 298.15 * unit.kelvin, +) -> BoreschRestraintGeometry: + """ + Find suitable Boresch-style restraints between a host and guest entity + based on the approach of Baumann et al. [1] with some modifications. + + Parameters + ---------- + universe : mda.Universe + An MDAnalysis Universe defining the system and its coordinates. + guest_rdmol : Chem.Mol + An RDKit Mol for the guest molecule. + guest_idxs : list[int] + Indices in the topology for the guest molecule. + host_idxs : list[int] + Indices in the topology for the host molecule. + guest_restraint_atoms_idxs : Optional[list[int]] + User selected indices of the guest molecule itself (i.e. indexed + starting a 0 for the guest molecule). This overrides the + restraint search and a restraint using these indices will + be retruned. Must be defined alongside ``host_restraint_atoms_idxs``. + host_restraint_atoms_idxs : Optional[list[int]] + User selected indices of the host molecule itself (i.e. indexed + starting a 0 for the hosts molecule). This overrides the + restraint search and a restraint using these indices will + be returnned. Must be defined alongside ``guest_restraint_atoms_idxs``. + host_selection : str + An MDAnalysis selection string to sub-select the host atoms. + dssp_filter : bool + Whether or not to filter the host atoms by their secondary structure. + rmsf_cutoff : unit.Quantity + The cutoff value for atom root mean square fluction. Atoms with RMSF + values above this cutoff will be disregarded. + Must be in units compatible with nanometer. + host_min_distance : unit.Quantity + The minimum distance between any host atom and the guest G0 atom. + Must be in units compatible with nanometer. + host_max_distance : unit.Quantity + The maximum distance between any host atom and the guest G0 atom. + Must be in units compatible with nanometer. + angle_force_constant : unit.Quantity + The force constant for the G1-G0-H0 and G0-H0-H1 angles. Must be + in units compatible with kilojoule / mole / radians ** 2. + temperature : unit.Quantity + The system temperature in units compatible with Kelvin. + + Returns + ------- + BoreschRestraintGeometry + An object defining the parameters of the Boresch-like restraint. + + References + ---------- + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy + calculations using a Separated Topologies approach." (2023). + """ + if (guest_restraint_atoms_idxs is not None) and (host_restraint_atoms_idxs is not None): # fmt: skip + # In this case assume the picked atoms were intentional / + # representative of the input and go with it + guest_ag = universe.select_atoms[guest_idxs] + guest_anchor = [ + at.ix for at in guest_ag.atoms[guest_restraint_atoms_idxs] + ] + host_ag = universe.select_atoms[host_idxs] + host_anchor = [ + at.ix for at in host_ag.atoms[host_restraint_atoms_idxs] + ] + + # Set the equilibrium values as those of the final frame + universe.trajectory[-1] + atomgroup = universe.atoms[host_anchor + guest_anchor] + bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( + atomgroup + ) + + # TODO: add checks to warn if this is a badly picked + # set of atoms. + return BoreschRestraintGeometry( + host_atoms=host_anchor, + guest_atoms=guest_anchor, + r_aA0=bond, + theta_A0=ang1, + theta_B0=ang2, + phi_A0=dih1, + phi_B0=dih2, + phi_C0=dih3 + ) + + if (guest_restraint_atoms_idxs is not None) ^ (host_restraint_atoms_idxs is not None): # fmt: skip + # This is not an intended outcome, crash out here + errmsg = ( + "both ``guest_restraints_atoms_idxs`` and " + "``host_restraint_atoms_idxs`` " + "must be set or both must be None. " + f"Got {guest_restraint_atoms_idxs} and {host_restraint_atoms_idxs}" + ) + raise ValueError(errmsg) + + # 1. Fetch the guest anchors + guest_anchors = find_guest_atom_candidates( + universe=universe, + rdmol=guest_rdmol, + guest_idxs=guest_idxs, + rmsf_cutoff=rmsf_cutoff, + ) + + if len(guest_anchors) == 0: + errmsg = "No suitable ligand atoms found for the restraint." + raise ValueError(errmsg) + + # 2. We then loop through the guest anchors to find suitable host atoms + for guest_anchor in guest_anchors: + # We next fetch the host atom pool + # Note: return is a set, so need to convert it later on + host_pool = find_host_atom_candidates( + universe=universe, + host_idxs=host_idxs, + l1_idx=guest_anchor[0], + host_selection=host_selection, + dssp_filter=dssp_filter, + rmsf_cutoff=rmsf_cutoff, + min_distance=host_min_distance, + max_distance=host_max_distance, + ) + + host_anchor = find_host_anchor( + guest_atoms=universe.atoms[list(guest_anchor)], + host_atom_pool=universe.atoms[list(host_pool)], + minimum_distance=0.5 * unit.nanometer, + angle_force_constant=angle_force_constant, + temperature=temperature, + ) + # continue if it's empty, otherwise stop + if host_anchor is not None: + break + + if host_anchor is None: + errmsg = "No suitable host atoms could be found" + raise ValueError(errmsg) + + # Set the equilibrium values as those of the final frame + universe.trajectory[-1] + atomgroup = universe.atoms[list(host_anchor) + list(guest_anchor)] + bond, ang1, ang2, dih1, dih2, dih3 = _get_restraint_distances( + atomgroup + ) + + return BoreschRestraintGeometry( + host_atoms=host_anchor, + guest_atoms=guest_anchor, + r_aA0=bond, + theta_A0=ang1, + theta_B0=ang2, + phi_A0=dih1, + phi_B0=dih2, + phi_C0=dih3 + ) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/guest.py b/openfe/protocols/restraint_utils/geometry/boresch/guest.py new file mode 100644 index 000000000..02eb7d667 --- /dev/null +++ b/openfe/protocols/restraint_utils/geometry/boresch/guest.py @@ -0,0 +1,251 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +from typing import Optional, Iterable + +from rdkit import Chem + +from openff.units import unit +import MDAnalysis as mda +import numpy.typing as npt + +from openfe.protocols.restraint_utils.geometry.utils import ( + get_aromatic_rings, + get_heavy_atom_idxs, + get_central_atom_idx, + is_collinear, + get_local_rmsf, +) + + +def _sort_by_distance_from_atom( + rdmol: Chem.Mol, target_idx: int, atom_idxs: Iterable[int] +) -> list[int]: + """ + Sort a list of RDMol atoms by their distance from a target atom. + + Parameters + ---------- + target_idx : int + The idx of the atom to measure from. + atom_idxs : list[int] + The idx values of the atoms to sort. + rdmol : Chem.Mol + RDKit Molecule the atoms belong to + + Returns + ------- + list[int] + The input atom idxs sorted by their distance from the target atom. + """ + distances = [] + + conformer = rdmol.GetConformer() + # Get the target atom position + target_pos = conformer.GetAtomPosition(target_idx) + + for idx in atom_idxs: + pos = conformer.GetAtomPosition(idx) + distances.append(((target_pos - pos).Length(), idx)) + + return [i[1] for i in sorted(distances)] + + +def _bonded_angles_from_pool( + rdmol: Chem.Mol, + atom_idx: int, + atom_pool: list[int], + aromatic_only: bool, +) -> list[tuple[int, int, int]]: + """ + Get all bonded angles starting from ``atom_idx`` from a pool of atoms. + + Parameters + ---------- + rdmol : Chem.Mol + The RDKit Molecule + atom_idx : int + The index of the atom to search angles from. + atom_pool : list[int] + The list of indices to pick possible angle partners from. + aromatic_only : bool + Prune any angles that include non-aromatic bonds. + + Returns + ------- + list[tuple[int, int, int]] + A list of tuples containing all the angles. + + Notes + ----- + * In the original SepTop code at3 is picked as directly bonded to at1. + By comparison here we instead follow the case that at3 is bonded to + at2 but not bonded to at1. + """ + angles = [] + + # Get the base atom and its neighbors + at1 = rdmol.GetAtomWithIdx(atom_idx) + at1_neighbors = [at.GetIdx() for at in at1.GetNeighbors()] + + # We loop at2 and at3 through the sorted atom_pool in order to get + # a list of angles in the branch that are sorted by how close the atoms + # are from the central atom + for at2 in atom_pool: + if at2 in at1_neighbors: + at2_neighbors = [ + at.GetIdx() for at in rdmol.GetAtomWithIdx(at2).GetNeighbors() + ] + for at3 in atom_pool: + if at3 != atom_idx and at3 in at2_neighbors: + angles.append((atom_idx, at2, at3)) + + if aromatic_only: # TODO: move this to its own method? + aromatic_rings = get_aromatic_rings(rdmol) + + def _belongs_to_ring(angle, aromatic_rings): + for ring in aromatic_rings: + if all(a in ring for a in angle): + return True + return False + + for angle in angles: + if not _belongs_to_ring(angle, aromatic_rings): + angles.remove(angle) + + return angles + + +def _get_guest_atom_pool( + rdmol: Chem.Mol, + rmsf: npt.NDArray, + rmsf_cutoff: unit.Quantity +) -> tuple[Optional[set[int]], bool]: + """ + Filter atoms based on rmsf & rings, defaulting to heavy atoms if + there are not enough. + + Parameters + ---------- + rdmol : Chem.Mol + The RDKit Molecule to search through + rmsf : npt.NDArray + A 1-D array of RMSF values for each atom. + rmsf_cutoff : unit.Quantity + The rmsf cutoff value for selecting atoms in units compatible with + nanometer. + + Returns + ------- + atom_pool : Optional[set[int]] + A pool of candidate atoms. + ring_atoms_only : bool + True if only ring atoms were selected. + """ + # Get a list of all the aromatic rings + # Note: no need to keep track of rings because we'll filter by + # bonded terms after, so if we only keep rings then all the bonded + # atoms should be within the same ring system. + atom_pool: set[tuple[int]] = set() + ring_atoms_only: bool = True + for ring in get_aromatic_rings(rdmol): + max_rmsf = rmsf[list(ring)].max() + if max_rmsf < rmsf_cutoff: + atom_pool.update(ring) + + # if we don't have enough atoms just get all the heavy atoms + if len(atom_pool) < 3: + ring_atoms_only = False + heavy_atoms = get_heavy_atom_idxs(rdmol) + atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) + if len(atom_pool) < 3: + return None, False + + return atom_pool, ring_atoms_only + + +def find_guest_atom_candidates( + universe: mda.Universe, + rdmol: Chem.Mol, + guest_idxs: list[int], + rmsf_cutoff: unit.Quantity = 1 * unit.nanometer, +) -> list[tuple[int]]: + """ + Get a list of potential ligand atom choices for a Boresch restraint + being applied to a given small molecule. + + Parameters + ---------- + universe : mda.Universe + An MDAnalysis Universe defining the system and its coordinates. + rdmol : Chem.Mol + An RDKit Molecule representing the small molecule ordered in + the same way as it is listed in the topology. + guest_idxs : list[int] + The ligand indices in the topology. + rmsf_cutoff : unit.Quantity + The RMSF filter cut-off. + + Returns + ------- + angle_list : list[tuple[int]] + A list of tuples for each valid G0, G1, G2 angle. If ``None``, no + angles could be found. + + Raises + ------ + ValueError + If no suitable ligand atoms could be found. + + TODO + ---- + Should the RDMol have a specific frame position? + """ + ligand_ag = universe.atoms[guest_idxs] + + # 0. Get the ligand RMSF + rmsf = get_local_rmsf(ligand_ag) + universe.trajectory[-1] # forward to the last frame + + # 1. Get the pool of atoms to work with + atom_pool, rings_only = _get_guest_atom_pool(rdmol, rmsf, rmsf_cutoff) + + if atom_pool is None: + # We don't have enough atoms so we raise an error + errmsg = "No suitable ligand atoms were found for the restraint" + raise ValueError(errmsg) + + # 2. Get the central atom + center = get_central_atom_idx(rdmol) + + # 3. Sort the atom pool based on their distance from the center + sorted_atom_pool = _sort_by_distance_from_atom(rdmol, center, atom_pool) + + # 4. Get a list of probable angles + angles_list = [] + for atom in sorted_atom_pool: + angles = _bonded_angles_from_pool( + rdmol=rdmol, + atom_idx=atom, + atom_pool=sorted_atom_pool, + aromatic_only=rings_only, + ) + for angle in angles: + # Check that the angle is at least not collinear + angle_ag = ligand_ag.atoms[list(angle)] + if not is_collinear(ligand_ag.positions, angle, u.dimensions): + angles_list.append( + ( + angle_ag.atoms[0].ix, + angle_ag.atoms[1].ix, + angle_ag.atoms[2].ix + ) + ) + + return angles_list diff --git a/openfe/protocols/restraint_utils/geometry/boresch/host.py b/openfe/protocols/restraint_utils/geometry/boresch/host.py new file mode 100644 index 000000000..6adaec250 --- /dev/null +++ b/openfe/protocols/restraint_utils/geometry/boresch/host.py @@ -0,0 +1,416 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe +""" +Restraint Geometry classes + +TODO +---- +* Add relevant duecredit entries. +""" +from typing import Optional +import warnings + +from openff.units import unit +import MDAnalysis as mda +from MDAnalysis.analysis.base import AnalysisBase +from MDAnalysis.lib.distances import calc_bonds, calc_angles, calc_dihedrals +import numpy as np +import numpy.typing as npt + +from openfe.protocols.restraint_utils.geometry.utils import ( + is_collinear, + check_angular_variance, + check_dihedral_bounds, + check_angle_not_flat, + FindHostAtoms, + get_local_rmsf, + stable_secondary_structure_selection +) + + +def find_host_atom_candidates( + universe: mda.Universe, + host_idxs: list[int], + l1_idx: int, + host_selection: str, + dssp_filter: bool = False, + rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, + min_distance: unit.Quantity = 1 * unit.nanometer, + max_distance: unit.Quantity = 3 * unit.nanometer, +) -> npt.NDArray: + """ + Get a list of suitable host atoms. + + Parameters + ---------- + universe : mda.Universe + An MDAnalysis Universe defining the system and its coordinates. + host_idxs : list[int] + A list of the host indices in the system topology. + l1_idx : int + The index of the proposed l1 binding atom. + host_selection : str + An MDAnalysis selection string to filter the host by. + dssp_filter : bool + Whether or not to apply a DSSP filter on the host selection. + rmsf_cutoff : uni.Quantity + The maximum RMSF value allowwed for any candidate host atom. + min_distance : unit.Quantity + The minimum search distance around l1 for suitable candidate atoms. + max_distance : unit.Quantity + The maximum search distance around l1 for suitable candidate atoms. + + Return + ------ + NDArray + Array of host atom indexes + """ + # Get an AtomGroup for the host based on the input host indices + host_ag = universe.atoms[host_idxs] + # If requested, filter the host atoms based on if their residues exist + # within stable secondary structures. + if dssp_filter: + try: + host_ag = stable_secondary_structure_selection(host_ag) + except ValueError: + wmsg = ( + "DSSP filtering was requested but either insufficient " + "protein residues were found or the DSSP calculation failed." + ) + warnings.warn(wmsg) + + # Filter the host AtomGroup based on ``host_selection` + selected_host_ag = host_ag.select_atoms(host_selection) + + # 1. Get the RMSF & filter to create a new AtomGroup + rmsf = get_local_rmsf(selected_host_ag) + filtered_host_ag = selected_host_ag.atoms[rmsf < rmsf_cutoff] + + # 2. Search of atoms within the min/max cutoff + atom_finder = FindHostAtoms( + host_atoms=filtered_host_ag, + guest_atoms=universe.atoms[l1_idx], + min_search_distance=min_distance, + max_search_distance=max_distance, + ) + atom_finder.run() + return atom_finder.results.host_idxs + + +class EvaluateHostAtoms1(AnalysisBase): + """ + Class to evaluate the suitability of a set of host atoms + as either H0 or H1 atoms (i.e. the first and second host atoms). + + Parameters + ---------- + reference : MDAnalysis.AtomGroup + The reference preceeding three atoms. + host_atom_pool : MDAnalysis.AtomGroup + The pool of atoms to pick an atom from. + minimum_distance : unit.Quantity + The minimum distance from the bound reference atom. + angle_force_constant : unit.Quantity + The force constant for the angle. + temperature : unit.Quantity + The system temperature in Kelvin + """ + def __init__( + self, + reference, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + **kwargs, + ): + super().__init__(reference.universe.trajectory, **kwargs) + + if len(reference) != 3: + errmsg = "Incorrect number of reference atoms passed" + raise ValueError(errmsg) + + self.reference = reference + self.host_atom_pool = host_atom_pool + self.minimum_distance = minimum_distance.to("angstrom").m + self.angle_force_constant = angle_force_constant + self.temperature = temperature + + def _prepare(self): + self.results.distances = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.angles = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.dihedrals = np.zeros( + (len(self.host_atom_pool), self.n_frames) + ) + self.results.collinear = np.empty( + (len(self.host_atom_pool), self.n_frames), + dtype=bool, + ) + self.results.valid = np.empty( + len(self.host_atom_pool), + dtype=bool, + ) + # Set everything to False to begin with + self.results.valid[:] = False + + def _single_frame(self): + for i, at in enumerate(self.host_atom_pool): + distance = calc_bonds( + at.position, + self.reference.atoms[0].position, + box=self.reference.dimensions, + ) + angle = calc_angles( + at.position, + self.reference.atoms[0].position, + self.reference.atoms[1].position, + box=self.reference.dimensions, + ) + dihedral = calc_dihedrals( + at.position, + self.reference.atoms[0].position, + self.reference.atoms[1].position, + self.reference.atoms[2].position, + box=self.reference.dimensions, + ) + collinear = is_collinear( + positions=np.vstack((at.position, self.reference.positions)), + atoms=[0, 1, 2, 3], + dimensions=self.reference.dimensions, + ) + self.results.distances[i][self._frame_index] = distance + self.results.angles[i][self._frame_index] = angle + self.results.dihedrals[i][self._frame_index] = dihedral + self.results.collinear[i][self._frame_index] = collinear + + def _conclude(self): + for i, at in enumerate(self.host_atom_pool): + # Check distances + distance_bounds = all( + self.results.distances[i] > self.minimum_distance + ) + # Check angles + angle_bounds = all( + check_angle_not_flat( + angle=angle * unit.radians, + force_constant=self.angle_force_constant, + temperature=self.temperature + ) + for angle in self.results.angles[i] + ) + angle_variance = check_angular_variance( + self.results.angles[i] * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=0 * unit.radians, + width=1.745 * unit.radians, + ) + # Check dihedrals + dihed_bounds = all( + check_dihedral_bounds(dihed * unit.radians) + for dihed in self.results.dihedrals[i] + ) + dihed_variance = check_angular_variance( + self.results.dihedrals[i] * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=-np.pi * unit.radians, + width=5.23 * unit.radians, + ) + not_collinear = not all(self.results.collinear[i]) + if all( + [ + distance_bounds, + angle_bounds, + angle_variance, + dihed_bounds, + dihed_variance, + not_collinear, + ] + ): + self.results.valid[i] = True + + +class EvaluateHostAtoms2(EvaluateHostAtoms1): + """ + Class to evaluate the suitability of a set of host atoms + as H2 atoms (i.e. the third host atoms). + + Parameters + ---------- + reference : MDAnalysis.AtomGroup + The reference preceeding three atoms. + host_atom_pool : MDAnalysis.AtomGroup + The pool of atoms to pick an atom from. + minimum_distance : unit.Quantity + The minimum distance from the bound reference atom. + angle_force_constant : unit.Quantity + The force constant for the angle. + temperature : unit.Quantity + The system temperature in Kelvin + """ + def _prepare(self): + self.results.distances1 = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.distances2 = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.dihedrals = np.zeros((len(self.host_atom_pool), self.n_frames)) + self.results.collinear = np.empty( + (len(self.host_atom_pool), self.n_frames), + dtype=bool, + ) + self.results.valid = np.empty( + len(self.host_atom_pool), + dtype=bool, + ) + # Default to valid == False + self.results.valid[:] = False + + def _single_frame(self): + for i, at in enumerate(self.host_atom_pool): + distance1 = calc_bonds( + at.position, + self.reference.atoms[0].position, + box=self.reference.dimensions, + ) + distance2 = calc_bonds( + at.position, + self.reference.atoms[1].position, + box=self.reference.dimensions, + ) + dihedral = calc_dihedrals( + at.position, + self.reference.atoms[0].position, + self.reference.atoms[1].position, + self.reference.atoms[2].position, + box=self.reference.dimensions, + ) + collinear = is_collinear( + positions=np.vstack((at.position, self.reference.positions)), + atoms=[0, 1, 2, 3], + dimensions=self.reference.dimensions, + ) + self.results.distances1[i][self._frame_index] = distance1 + self.results.distances2[i][self._frame_index] = distance2 + self.results.dihedrals[i][self._frame_index] = dihedral + self.results.collinear[i][self._frame_index] = collinear + + def _conclude(self): + for i, at in enumerate(self.host_atom_pool): + distance1_bounds = all( + self.results.distances1[i] > self.minimum_distance + ) + distance2_bounds = all( + self.results.distances2[i] > self.minimum_distance + ) + dihed_bounds = all( + check_dihedral_bounds(dihed * unit.radians) + for dihed in self.results.dihedrals[i] + ) + dihed_variance = check_angular_variance( + self.results.dihedrals[i] * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=-np.pi * unit.radians, + width=5.23 * unit.radians, + ) + not_collinear = not all(self.results.collinear[i]) + if all( + [ + distance1_bounds, + distance2_bounds, + dihed_bounds, + dihed_variance, + not_collinear, + ] + ): + self.results.valid[i] = True + + +def find_host_anchor( + guest_atoms: mda.AtomGroup, + host_atom_pool: mda.AtomGroup, + minimum_distance: unit.Quantity, + angle_force_constant: unit.Quantity, + temperature: unit.Quantity +) -> Optional[list[int]]: + """ + Find suitable atoms for the H0-H1-H2 portion of the restraint. + + Parameters + ---------- + guest_atoms : mda.AtomGroup + The guest anchor atoms for G0-G1-G2 + host_atom_pool : mda.AtomGroup + The host atoms to search from. + minimum_distance : unit.Quantity + The minimum distance to pick host atoms from each other. + angle_force_constant : unit.Quantity + The force constant for the G1-G0-H0 and G0-H0-H1 angles. + temperature : unit.Quantity + The target system temperature. + + Returns + ------- + Optional[list[int]] + A list of indices for a selected combination of H0, H1, and H2. + """ + # Evalulate the host_atom_pool for suitability as H0 atoms + h0_eval = EvaluateHostAtoms1( + guest_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) + h0_eval.run() + + for i, valid_h0 in enumerate(h0_eval.results.valid): + # If valid H0 atom, evaluate rest of host_atom_pool for suitability + # as H1 atoms. + if valid_h0: + h0g0g1_atoms = host_atom_pool.atoms[i] + guest_atoms.atoms[:2] + h1_eval = EvaluateHostAtoms1( + h0g0g1_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) + h1_eval.run() + for j, valid_h1 in enumerate(h1_eval.results.valid): + # If valid H1 atom, evaluate rest of host_atom_pool for + # suitability as H2 atoms + if valid_h1: + h1h0g0_atoms = host_atom_pool.atoms[j] + h0g0g1_atoms.atoms[:2] + h2_eval = EvaluateHostAtoms2( + h1h0g0_atoms, + host_atom_pool, + minimum_distance, + angle_force_constant, + temperature, + ) + h2_eval.run() + + if any(h2_eval.results.valid): + # Get the sum of the average distances (dsum_avgs) + # for all the host_atom_pool atoms + distance1_avgs = np.array( + [d.mean() for d in h2_eval.results.distances1] + ) + distance2_avgs = np.array( + [d.mean() for d in h2_eval.results.distances2] + ) + dsum_avgs = distance1_avgs + distance2_avgs + + # Now filter by validity as H2 atom + h2_dsum_avgs = [ + (idx, val) for idx, val in enumerate(dsum_avgs) + if h2_eval.results.valid[idx] + ] + + # Get the index of the H2 atom with the lowest + # average distance + k = sorted(h2_dsum_avgs, key=lambda x: x[1])[0][0] + + return list(host_atom_pool.atoms[[i, j, k]].ix) + return None diff --git a/openfe/protocols/restraint_utils/geometry/flatbottom.py b/openfe/protocols/restraint_utils/geometry/flatbottom.py index c5e975401..1f88fbf59 100644 --- a/openfe/protocols/restraint_utils/geometry/flatbottom.py +++ b/openfe/protocols/restraint_utils/geometry/flatbottom.py @@ -7,10 +7,8 @@ ---- * Add relevant duecredit entries. """ -import pathlib -from typing import Union, Optional +from typing import Optional import numpy as np -from openmm import app from openff.units import unit from openff.models.types import FloatQuantity import MDAnalysis as mda @@ -21,7 +19,7 @@ DistanceRestraintGeometry, ) -from .utils import _get_mda_topology_format, _get_mda_selection +from .utils import _get_mda_selection class FlatBottomDistanceGeometry(DistanceRestraintGeometry): @@ -67,8 +65,7 @@ def _conclude(self): def get_flatbottom_distance_restraint( - topology: Union[str, app.Topology], - trajectory: Union[str, pathlib.Path], + universe: mda.Universe, host_atoms: Optional[list[int]] = None, guest_atoms: Optional[list[int]] = None, host_selection: Optional[str] = None, @@ -84,10 +81,8 @@ def get_flatbottom_distance_restraint( Parameters ---------- - topology : Union[str, app.Topology] - A topology defining the system. - trajectory : Union[str, pathlib.Path] - A coordinate trajectory for the system. + universe : mda.Universe + An MDAnalysis Universe defining the system and its coordinates. host_atoms : Optional[list[int]] A list of host atoms indices. Either ``host_atoms`` or ``host_selection`` must be defined. @@ -109,14 +104,8 @@ def get_flatbottom_distance_restraint( FlatBottomDistanceGeometry An object defining a flat bottom restraint geometry. """ - u = mda.Universe( - topology, - trajectory, - topology_format=_get_mda_topology_format(topology) - ) - - guest_ag = _get_mda_selection(u, guest_atoms, guest_selection) - host_ag = _get_mda_selection(u, host_atoms, host_selection) + guest_ag = _get_mda_selection(universe, guest_atoms, guest_selection) + host_ag = _get_mda_selection(universe, host_atoms, host_selection) guest_idxs = [a.ix for a in guest_ag] host_idxs = [a.ix for a in host_ag] diff --git a/openfe/protocols/restraint_utils/geometry/harmonic.py b/openfe/protocols/restraint_utils/geometry/harmonic.py index 1cc8fb0e0..838724deb 100644 --- a/openfe/protocols/restraint_utils/geometry/harmonic.py +++ b/openfe/protocols/restraint_utils/geometry/harmonic.py @@ -7,9 +7,7 @@ ---- * Add relevant duecredit entries. """ -import pathlib -from typing import Union, Optional -from openmm import app +from typing import Optional import MDAnalysis as mda from rdkit import Chem @@ -17,7 +15,6 @@ from .utils import ( get_central_atom_idx, _get_mda_selection, - _get_mda_topology_format, ) @@ -28,8 +25,7 @@ class DistanceRestraintGeometry(HostGuestRestraintGeometry): def get_distance_restraint( - topology: Union[str, pathlib.Path, app.Topology], - trajectory: Union[str, pathlib.Path], + universe: mda.Universe, host_atoms: Optional[list[int]] = None, guest_atoms: Optional[list[int]] = None, host_selection: Optional[str] = None, @@ -43,10 +39,8 @@ def get_distance_restraint( Parameters ---------- - topology : Union[str, pathlib.Path, app.Topology] - A path or object defining the system topology. - trajectory : Union[str, pathlib.Path] - Coordinates for the system. + universe : mda.Universe + An MDAnalysis Universe defining the system and its coordinates. host_atoms : Optional[list[int]] A list of host atoms indices. Either ``host_atoms`` or ``host_selection`` must be defined. @@ -65,15 +59,9 @@ def get_distance_restraint( DistanceRestraintGeometry An object that defines a distance restraint geometry. """ - u = mda.Universe( - topology, - trajectory, - topology_format=_get_mda_topology_format(topology) - ) - - guest_ag = _get_mda_selection(u, guest_atoms, guest_selection) + guest_ag = _get_mda_selection(universe, guest_atoms, guest_selection) guest_atoms = [a.ix for a in guest_ag] - host_ag = _get_mda_selection(u, host_atoms, host_selection) + host_ag = _get_mda_selection(universe, host_atoms, host_selection) host_atoms = [a.ix for a in host_ag] return DistanceRestraintGeometry( diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index d821474ef..4e7170e63 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -8,11 +8,12 @@ * Add relevant duecredit entries. """ from typing import Union, Optional -from itertools import combinations +from itertools import combinations, groupby import numpy as np import numpy.typing as npt import pathlib from scipy.stats import circvar +import warnings import openmm from openff.toolkit import Molecule as OFFMol @@ -22,6 +23,7 @@ import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase from MDAnalysis.analysis.rms import RMSF +from MDAnalysis.analysis.dssp import DSSP from MDAnalysis.lib.distances import minimize_vectors, capped_distance from MDAnalysis.coordinates.memory import MemoryReader from MDAnalysis.transformations.nojump import NoJump @@ -441,7 +443,8 @@ def _single_frame(self): host_idxs = set(self.host_ag.atoms[p].ix for p in pairs[:, 1]) - # Only keep indices that fit the distance criteria + # We do an intersection as we go along to prune atoms that don't pass + # the distance selection criteria self.results.host_idxs = self.results.host_idxs.intersection( host_idxs ) @@ -475,3 +478,137 @@ def get_local_rmsf(atomgroup: mda.AtomGroup) -> unit.Quantity: rmsf = RMSF(ag) rmsf.run() return rmsf.results.rmsf * unit.angstrom + + +def stable_secondary_structure_selection( + atomgroup: mda.AtomGroup, + trim_chain_start: int = 10, + trim_chain_end: int = 10, + min_structure_size: int = 8, + trim_structure_ends: int = 3, +) -> mda.AtomGroup: + """ + Select all atoms in a given AtomGroup which belong to residues with a + stable secondary structure as defined by Baumann et al.[1] + + The selection algorithm works in the following manner: + 1. Protein residues are selected from the ``atomgroup``. + 2. If there are fewer than 30 protein residues, raise an error. + 3. Split the protein residues by fragment, guessing bonds if necessary. + 4. Discard the first ``trim_chain_start`` and the last + ``trim_chain_end`` residues per fragment. + 5. Run DSSP using the last trajectory frame on the remaining + fragment residues. + 6. Extract all contiguous structure units that are longer than + ``min_structure_size``, removing ``trim_structure_ends`` + residues from each end of the structure. + 7. For all extract structures, if there are more beta-sheet + residues than there are alpha-helix residues, then allow + residues to be selected from either structure type. If not, + then only allow alpha-helix residues. + 8. Select all atoms in the ``atomgroup`` that belong to residues + from extracted structure units of the selected structure type. + + Parameters + ---------- + atomgroup : mda.AtomgGroup + The AtomGroup to select atoms from. + trim_chain_start: int + The number of residues to trim from the start of each + protein chain. Default 10. + trim_chain_end : int + The number of residues to trim from the end of each + protein chain. Default 10. + min_structure_size : int + The minimum number of residues needed in a given + secondary structure unit to be considered stable. Default 8. + trim_structure_ends : int + The number of residues to trim from the end of each + secondary structure units. Default 3. + + Returns + ------- + AtomGroup + An AtomGroup containing all the atoms from the input AtomGroup + which belong to stable secondary structure residues. + + Raises + ------ + ValueError + If fewer than 30 protein residues are present in the input + ``atomgroup``. + UserWarning + If there are no bonds for the protein atoms in the input + host residue. In this case, the bonds will be guessed + using a simple distance metric. + + Notes + ----- + * This selection algorithm assumes contiguous & ordered residues. + * We recommend always trimming at least one residue at the ends of + each chain using ``trim_chain_start`` and ``trim_chain_end`` to + avoid issues with capping residues. + * DSSP assignement is done on the final frame of the trajectory. + + References + ---------- + [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy + calculations using a Separated Topologies approach." (2023). + """ + # We use "host_ag" to get the entire host + protein_ag = atomgroup.select_atoms('protein') + if len(protein_ag.residues) < 30: + # TODO: make this not fail but warn? + errmsg = ("Insufficient protein residues were found -" + " cannot run DSSP filter") + raise ValueError(errmsg) + + # We need to split by fragments to account for multiple chains + # To do this, we need bonds! + if not hasattr(protein_ag, 'bonds'): + wmsg = ( + "No bounds found in input Universe, " + "will attempt to guess for DSSP assignment" + ) + warnings.warn(wmsg) + protein_ag.guess_bonds() + + structures = [] # container for all contiguous secondary structure units + structure_residue_counts = {'H': 0, 'E': 0, '-': 0} + for frag in protein_ag.fragments: + chain = frag.residues[trim_chain_start:-trim_chain_end].atoms + # Run on the last frame + dssp = DSSP(chain).run(start=-1) + + # Tag each residue structure by its resindex + dssp_results = [ + (structure, resid) for structure, resid in + zip(dssp.results.dssp[0], chain.residues.resindices) + ] + + for _, group_iter in groupby(dssp_results, lambda x: x[0]): + group = list(group_iter) + if len(group) > min_structure_size: + structures.append( + group[trim_structure_ends:-trim_structure_ends] + ) + num_residues = len(group) - (2 * trim_structure_ends) + structure_residue_counts[group[0][0]] += num_residues + + # If we have fewer alpha-helix residues than beta-sheet residues + # then we allow picking from beta-sheets too. + allowed_structures = ['H'] + if structure_residue_counts['H'] < structure_residue_counts['E']: + allowed_structures.append('E') + + allowed_residxs = [] + for structure in structures: + if structure[0][0] in allowed_structures: + allowed_residxs.extend([residue[1] for residue in structure]) + + # Resindexes are keyed at the Universe scale not AtomGroup + allowed_atoms = atomgroup.universe.residues[allowed_residxs].atoms + + # Pick up all the atoms that intersect the initial selection and + # those allowed. + return atomgroup.intersection(allowed_atoms) From e166c70b2c8ca9d0251ea71292b2fbdf9bb28509 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Fri, 24 Jan 2025 07:48:50 +0000 Subject: [PATCH 145/163] fix imports --- openfe/protocols/restraint_utils/geometry/boresch/__init__.py | 2 +- openfe/protocols/restraint_utils/geometry/boresch/guest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/__init__.py b/openfe/protocols/restraint_utils/geometry/boresch/__init__.py index 64bb4e73f..57c306c58 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch/__init__.py +++ b/openfe/protocols/restraint_utils/geometry/boresch/__init__.py @@ -1,4 +1,4 @@ -from geometry import ( +from .geometry import ( BoreschRestraintGeometry, find_boresch_restraint, ) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/guest.py b/openfe/protocols/restraint_utils/geometry/boresch/guest.py index 02eb7d667..445a4e74d 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch/guest.py +++ b/openfe/protocols/restraint_utils/geometry/boresch/guest.py @@ -239,7 +239,7 @@ def find_guest_atom_candidates( for angle in angles: # Check that the angle is at least not collinear angle_ag = ligand_ag.atoms[list(angle)] - if not is_collinear(ligand_ag.positions, angle, u.dimensions): + if not is_collinear(ligand_ag.positions, angle, universe.dimensions): angles_list.append( ( angle_ag.atoms[0].ix, From f89a8c8ce8361a0e4b6aa38c80f609448a04afa8 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 26 Jan 2025 00:28:16 +0000 Subject: [PATCH 146/163] Fix up secondary structure filtering & add chain selection --- .../restraint_utils/geometry/boresch/guest.py | 5 +- .../restraint_utils/geometry/boresch/host.py | 28 ++- .../restraint_utils/geometry/utils.py | 215 ++++++++++++------ 3 files changed, 167 insertions(+), 81 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/guest.py b/openfe/protocols/restraint_utils/geometry/boresch/guest.py index 445a4e74d..8c3490dd2 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch/guest.py +++ b/openfe/protocols/restraint_utils/geometry/boresch/guest.py @@ -13,6 +13,7 @@ from openff.units import unit import MDAnalysis as mda +import numpy as np import numpy.typing as npt from openfe.protocols.restraint_utils.geometry.utils import ( @@ -152,7 +153,7 @@ def _get_guest_atom_pool( # Note: no need to keep track of rings because we'll filter by # bonded terms after, so if we only keep rings then all the bonded # atoms should be within the same ring system. - atom_pool: set[tuple[int]] = set() + atom_pool: set[int] = set() ring_atoms_only: bool = True for ring in get_aromatic_rings(rdmol): max_rmsf = rmsf[list(ring)].max() @@ -162,7 +163,7 @@ def _get_guest_atom_pool( # if we don't have enough atoms just get all the heavy atoms if len(atom_pool) < 3: ring_atoms_only = False - heavy_atoms = get_heavy_atom_idxs(rdmol) + heavy_atoms = np.array(get_heavy_atom_idxs(rdmol)) atom_pool = set(heavy_atoms[rmsf[heavy_atoms] < rmsf_cutoff]) if len(atom_pool) < 3: return None, False diff --git a/openfe/protocols/restraint_utils/geometry/boresch/host.py b/openfe/protocols/restraint_utils/geometry/boresch/host.py index 6adaec250..56f015241 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch/host.py +++ b/openfe/protocols/restraint_utils/geometry/boresch/host.py @@ -67,20 +67,34 @@ def find_host_atom_candidates( """ # Get an AtomGroup for the host based on the input host indices host_ag = universe.atoms[host_idxs] + + # Filter the host AtomGroup based on ``host_selection` + selected_host_ag = host_ag.select_atoms(host_selection) + # If requested, filter the host atoms based on if their residues exist # within stable secondary structures. if dssp_filter: - try: - host_ag = stable_secondary_structure_selection(host_ag) - except ValueError: + # TODO: allow user-supplied kwargs here + stable_ag = stable_secondary_structure_selection(selected_host_ag) + + if len(stable_ag) < 20: wmsg = ( - "DSSP filtering was requested but either insufficient " - "protein residues were found or the DSSP calculation failed." + "Secondary structure filtering: " + "Too few atoms found via secondary strcuture filtering will " + "try to only select all residues in protein chains instead." ) warnings.warn(wmsg) + stable_ag = protein_chain_selection(selected_host_ag) - # Filter the host AtomGroup based on ``host_selection` - selected_host_ag = host_ag.select_atoms(host_selection) + if len(stable_ag) < 20: + wmsg = ( + "Secondary structure filtering: " + "Too few atoms found in protein residue chains, will just " + "use all atoms." + ) + warnings.warn(wmsg) + else: + selected_host_ag = stable_ag # 1. Get the RMSF & filter to create a new AtomGroup rmsf = get_local_rmsf(selected_host_ag) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 4e7170e63..aadbadc0e 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -11,11 +11,9 @@ from itertools import combinations, groupby import numpy as np import numpy.typing as npt -import pathlib from scipy.stats import circvar import warnings -import openmm from openff.toolkit import Molecule as OFFMol from openff.units import unit import networkx as nx @@ -25,7 +23,6 @@ from MDAnalysis.analysis.rms import RMSF from MDAnalysis.analysis.dssp import DSSP from MDAnalysis.lib.distances import minimize_vectors, capped_distance -from MDAnalysis.coordinates.memory import MemoryReader from MDAnalysis.transformations.nojump import NoJump from openfe_analysis.transformations import Aligner @@ -79,51 +76,6 @@ def _get_mda_selection( return ag -def _get_mda_coord_format( - coordinates: Union[str, pathlib.Path, npt.NDArray] -) -> Optional[MemoryReader]: - """ - Helper to set the coordinate format to MemoryReader - if the coordinates are an NDArray. - - Parameters - ---------- - coordinates : Union[str, pathlib.Path, npt.NDArray] - - Returns - ------- - Optional[MemoryReader] - Either the MemoryReader class or None. - """ - if isinstance(coordinates, np.ndarray): - return MemoryReader - else: - return None - - -def _get_mda_topology_format( - topology: Union[str, openmm.app.Topology] -) -> Optional[str]: - """ - Helper to set the topology format to OPENMMTOPOLOGY - if the topology is an openmm.app.Topology. - - Parameters - ---------- - topology : Union[str, openmm.app.Topology] - - - Returns - ------- - Optional[str] - The string `OPENMMTOPOLOGY` or None. - """ - if isinstance(topology, openmm.app.Topology): - return "OPENMMTOPOLOGY" - else: - return None - - def get_aromatic_rings(rdmol: Chem.Mol) -> list[tuple[int, ...]]: """ Get a list of tuples with the indices for each ring in an rdkit Molecule. @@ -235,13 +187,18 @@ def get_central_atom_idx(rdmol: Chem.Mol) -> int: return longest_path[len(longest_path) // 2] -def is_collinear(positions, atoms, dimensions=None, threshold=0.9): +def is_collinear( + positions: npt.ArrayLike, + atoms: list[int], + dimensions=None, + threshold=0.9 +): """ Check whether any sequential vectors in a sequence of atoms are collinear. Parameters ---------- - positions : openmm.unit.Quantity + positions : npt.ArrayLike System positions. atoms : list[int] The indices of the atoms to test. @@ -261,6 +218,15 @@ def is_collinear(positions, atoms, dimensions=None, threshold=0.9): ----- Originally from Yank. """ + if len(atoms) < 3: + raise ValueError("Too few atoms passed for co-linearity test") + if len(positions) < len(atoms) or len(positions) < max(atoms) + 1: + errmsg = "atoms indices do not match the positions array passed" + raise ValueError(errmsg) + if not all(isinstance(x, int) for x in atoms): + errmsg = "atoms is not a list of index integers" + raise ValueError(errmsg) + result = False for i in range(len(atoms) - 2): v1 = minimize_vectors( @@ -480,12 +446,37 @@ def get_local_rmsf(atomgroup: mda.AtomGroup) -> unit.Quantity: return rmsf.results.rmsf * unit.angstrom +def _atomgroup_has_bonds( + atomgroup: Union[mda.Atomgroup, mda.Universe] +) -> bool: + """ + Check if all residues in an AtomGroup or Univese has bonds. + + Parameters + ---------- + atomgroup : Union[mda.Atomgroup, mda.Universe] + Either an MDAnalysis AtomGroup or Universe to check for bonds. + + Returns + ------- + bool + True if all residues contain at least one bond, False otherwise. + """ + if not hasattr(atomgroup, 'bonds'): + return False + + if not all(len(r.atoms.bonds) > 0 for r in atomgroup.residues): + return False + + return True + + def stable_secondary_structure_selection( atomgroup: mda.AtomGroup, trim_chain_start: int = 10, trim_chain_end: int = 10, - min_structure_size: int = 8, - trim_structure_ends: int = 3, + min_structure_size: int = 6, + trim_structure_ends: int = 2, ) -> mda.AtomGroup: """ Select all atoms in a given AtomGroup which belong to residues with a @@ -528,15 +519,12 @@ def stable_secondary_structure_selection( Returns ------- - AtomGroup + AtomGroup : mda.AtomGroup An AtomGroup containing all the atoms from the input AtomGroup which belong to stable secondary structure residues. Raises ------ - ValueError - If fewer than 30 protein residues are present in the input - ``atomgroup``. UserWarning If there are no bonds for the protein atoms in the input host residue. In this case, the bonds will be guessed @@ -555,30 +543,44 @@ def stable_secondary_structure_selection( [1] Baumann, Hannah M., et al. "Broadening the scope of binding free energy calculations using a Separated Topologies approach." (2023). """ - # We use "host_ag" to get the entire host - protein_ag = atomgroup.select_atoms('protein') - if len(protein_ag.residues) < 30: - # TODO: make this not fail but warn? - errmsg = ("Insufficient protein residues were found -" - " cannot run DSSP filter") - raise ValueError(errmsg) + # First let's copy our Universe so we don't overwrite its current state + copy_u = atomgroup.universe.copy() + + # Create an AtomGroup that contains all the protein residues in the + # input Universe - we will filter by what matches in the atomgroup later + copy_protein_ag = copy_u.select_atoms('protein').atoms # We need to split by fragments to account for multiple chains # To do this, we need bonds! - if not hasattr(protein_ag, 'bonds'): - wmsg = ( - "No bounds found in input Universe, " - "will attempt to guess for DSSP assignment" - ) + if not _atomgroup_has_bonds(copy_protein_ag, 'bonds'): + wmsg = "No bonds found in input Universe, will attept to guess them." warnings.warn(wmsg) protein_ag.guess_bonds() structures = [] # container for all contiguous secondary structure units + # Counter for each residue type found structure_residue_counts = {'H': 0, 'E': 0, '-': 0} - for frag in protein_ag.fragments: + # THe minimum length any chain must have + min_chain_length = trim_chain_start + trim_chain_end + min_structure_size + + # Loop over each continually bonded section (i.e. chain) of the protein + for frag in copy_protein_ag.fragments: + # If this fragment is too small, skip processing it + if len(frag.residues) < min_chain_length: + continue + + # Trim the chain ends chain = frag.residues[trim_chain_start:-trim_chain_end].atoms - # Run on the last frame - dssp = DSSP(chain).run(start=-1) + + try: + # Run on the last frame + # TODO: maybe filter out any residue that changes secondary + # structure during the trajectory + dssp = DSSP(chain).run(start=-1) + except ValueError: + # DSSP may fail if it doesn't recognise the system's atom names + # or non-canonical residues are included, in this case just skip + continue # Tag each residue structure by its resindex dssp_results = [ @@ -586,9 +588,10 @@ def stable_secondary_structure_selection( zip(dssp.results.dssp[0], chain.residues.resindices) ] + # Group by contiguous secondary structure for _, group_iter in groupby(dssp_results, lambda x: x[0]): group = list(group_iter) - if len(group) > min_structure_size: + if len(group) >= min_structure_size: structures.append( group[trim_structure_ends:-trim_structure_ends] ) @@ -612,3 +615,71 @@ def stable_secondary_structure_selection( # Pick up all the atoms that intersect the initial selection and # those allowed. return atomgroup.intersection(allowed_atoms) + + +def protein_chain_selection( + atomgroup: mda.AtomGroup, + trim_chain_start: int = 10, + trim_chain_end: int = 10, +) -> mda.AtomGroup: + """ + Return a sub-selection of the input AtomGroup which belongs to protein + chains trimmed by ``trim_chain_start`` and ``trim_chain_end``. + + Protein chains are defined as any continuously bonded part of system with + at least 30 residues which match the ``protein`` selection of MDAnalysis. + + Parameters + ---------- + atomgroup : mda.AtomgGroup + The AtomGroup to select atoms from. + trim_chain_start: int + The number of residues to trim from the start of each + protein chain. Default 10. + trim_chain_end : int + The number of residues to trim from the end of each + protein chain. Default 10. + + Returns + ------- + atomgroup : mda.AtomGroup + An AtomGroup containing all the atoms from the input AtomGroup + which belong to protein chains. + """ + # First let's copy our Universe so we don't overwrite its current state + copy_u = atomgroup.universe.copy() + + # Create an AtomGroup that contains all the protein residues in the + # input Universe - we will filter by what matches in the atomgroup later + copy_protein_ag = copy_u.select_atoms('protein').atoms + + # We need to split by fragments to account for multiple chains + # To do this, we need bonds! + if not _atomgroup_has_bonds(copy_protein_ag, 'bonds'): + wmsg = ( + "No bonds found in input Universe, will attept to guess them." + ) + warnings.warn(wmsg) + protein_ag.guess_bonds() + + copy_chains_ags_list = [] + + # Loop over each continually bonded section (i.e. chain) of the protein + for frag in copy_protein_ag.fragments: + # If this chain is less than 30 residues, it's probably a peptide + if len(frag.residues) < 30: + continue + + chain = frag.residues[trim_chain_start:-trim_chain_end].atoms + copy_chain_ags_list.append(chain) + + # Create a single atomgroup from all chains + copy_chains_ag = sum(copy_chain_ags_list) + + # Now get a list of all the chain atoms in the original Universe + # Resindexes are keyed at the Universe scale not AtomGroup + chain_atoms = atomgroup.universe.atoms[copy_chains_ag.atoms.ix] + + # Return all atoms at the intersection of the input atomgroup and + # the chains atomgroup + return atomgroup.intersection(chain_atoms) From 2af07c8532bfeb38a5e039c240a84a81eeeb7e1c Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 26 Jan 2025 04:32:30 +0000 Subject: [PATCH 147/163] Add angle wrapping method --- .../restraint_utils/geometry/utils.py | 48 ++++++++++--- openfe/tests/conftest.py | 2 +- .../restraints/test_geometry_utils.py | 67 +++++++++++++++++++ 3 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 openfe/tests/protocols/restraints/test_geometry_utils.py diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index aadbadc0e..67f6e2427 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -32,9 +32,9 @@ def _get_mda_selection( - universe: mda.Universe, - atom_list: Optional[list[int]], - selection: Optional[str] + universe: Union[mda.Universe, mda.AtomGroup], + atom_list: Optional[list[int]] = None, + selection: Optional[str] = None, ) -> mda.AtomGroup: """ Return an AtomGroup based on either a list of atom indices or an @@ -42,8 +42,8 @@ def _get_mda_selection( Parameters ---------- - universe : mda.Universe - The MDAnalysis Universe to get the AtomGroup from. + universe : Union[mda.Universe, mda.AtomGroup] + The MDAnalysis Universe or AtomGroup to get the AtomGroup from. atom_list : Optional[list[int]] A list of atom indices. selection : Optional[str] @@ -244,6 +244,28 @@ def is_collinear( return result +def _wrap_angle(angle: unit.Quantity) -> unit.Quantity: + """ + Wrap an angle to -pi to pi radians. + + Parameters + ---------- + angle : unit.Quantity + An angle in radians compatible units. + + Returns + ------- + unit.Quantity + The angle in units of radians wrapped. + + Notes + ----- + Print automatically converts the angle to radians + as it passes it through arctan2. + """ + return np.arctan2(np.sin(angle), np.cos(angle)) + + def check_angle_not_flat( angle: unit.Quantity, force_constant: unit.Quantity = DEFAULT_ANGLE_FRC_CONSTANT, @@ -276,7 +298,7 @@ def check_angle_not_flat( This code was initially contributed by Vytautas Gapsys. """ # Convert things - angle_rads = angle.to("radians") + angle_rads = _wrap_angle(angle) frc_const = force_constant.to("unit.kilojoule_per_mole / unit.radians**2") temp_kelvin = temperature.to("kelvin") RT = 8.31445985 * 0.001 * temp_kelvin @@ -298,7 +320,10 @@ def check_dihedral_bounds( ) -> bool: """ Check that a dihedral does not exceed the bounds set by - lower_cutoff and upper_cutoff. + lower_cutoff and upper_cutoff on a -pi to pi range. + + All angles and cutoffs are wrapped to -pi to pi before + applying the check. Parameters ---------- @@ -315,7 +340,10 @@ def check_dihedral_bounds( ``True`` if the dihedral is within the upper and lower cutoff bounds. """ - if (dihedral < lower_cutoff) or (dihedral > upper_cutoff): + dihed = _wrap_angle(dihedral) + lower = _wrap_angle(lower_cutoff) + upper = _wrap_angle(upper_cutoff) + if (dihed < lower) or (dihed > upper): return False return True @@ -348,6 +376,8 @@ def check_angular_variance( ``True`` if the variance of the angles is less than the width. """ + # scipy circ methods already recasts internally so we shouldn't + # need to wrap the angles variance = circvar( angles.to("radians").m, high=upper_bound.to("radians").m, @@ -447,7 +477,7 @@ def get_local_rmsf(atomgroup: mda.AtomGroup) -> unit.Quantity: def _atomgroup_has_bonds( - atomgroup: Union[mda.Atomgroup, mda.Universe] + atomgroup: Union[mda.AtomGroup, mda.Universe] ) -> bool: """ Check if all residues in an AtomGroup or Univese has bonds. diff --git a/openfe/tests/conftest.py b/openfe/tests/conftest.py index 51cfb598b..4ca8933f1 100644 --- a/openfe/tests/conftest.py +++ b/openfe/tests/conftest.py @@ -223,7 +223,7 @@ def T4_protein_component(): return comp -@pytest.fixture() +@pytest.fixture(scope='session') def eg5_protein_pdb(): with resources.files('openfe.tests.data.eg5') as d: yield str(d / 'eg5_protein.pdb') diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py new file mode 100644 index 000000000..edec100c5 --- /dev/null +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -0,0 +1,67 @@ +# This code is part of OpenFE and is licensed under the MIT license. +# For details, see https://github.com/OpenFreeEnergy/openfe + +import pytest + +import MDAnalysis as mda +from openff.units import unit + +from openfe.protocols.restraint_utils.geometry.utils import ( + _get_mda_selection, + check_dihedral_bounds, +) + + + +@pytest.fixture(scope='module') +def eg5_pdb_universe(eg5_protein_pdb): + return mda.Universe(eg5_protein_pdb) + + +def test_mda_selection_none_error(eg5_pdb_universe): + with pytest.raises(ValueError, match="one of either"): + _ = _get_mda_selection(eg5_pdb_universe) + + +def test_mda_selection_both_args_error(eg5_pdb_universe): + with pytest.raises(ValueError, match="both atom_list and"): + _ = _get_mda_selection( + eg5_pdb_universe, + atom_list=[0, 1, 2, 3], + selection="all" + ) + + +def test_mda_selection_universe_atom_list(eg5_pdb_universe): + test_ag = _get_mda_selection(eg5_pdb_universe, atom_list=[0, 1, 2]) + assert eg5_pdb_universe.atoms[[0, 1, 2]] == test_ag + + +def test_mda_selection_atomgroup_string(eg5_pdb_universe): + test_ag = _get_mda_selection(eg5_pdb_universe.atoms, selection='all') + assert test_ag == eg5_pdb_universe.atoms + + +@pytest.mark.parametrize('dihed, expected', [ + [3 * unit.radians, False], + [0 * unit.radians, True], + [-3 * unit.radians, False], + [300 * unit.degrees, True], + [181 * unit.degrees, False], +]) +def test_check_dihedral_bounds(dihed, expected): + ret = check_dihedral_bounds(dihed) + assert ret == expected + + +@pytest.mark.parametrize('dihed, lower, upper, expected', [ + [3 * unit.radians, -3.1 * unit.radians, 3.1 * unit.radians, True], + [300 * unit.degrees, -61 * unit.degrees, 301 * unit.degrees, True], + [300 * unit.degrees, 299 * unit.degrees, -61 * unit.degrees, False] +]) +def test_check_dihedral_bounds_defined(dihed, lower, upper, expected): + ret = check_dihedral_bounds( + dihed, lower_cutoff=lower, upper_cutoff=upper + ) + + assert ret == expected From aa6f338fb7582b0b209d8b888aba9fbfd1c6dcc0 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 26 Jan 2025 21:23:05 +0000 Subject: [PATCH 148/163] Add more tests --- .../restraints/test_geometry_utils.py | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index edec100c5..2bcf208d2 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -3,11 +3,17 @@ import pytest +import itertools +from rdkit import Chem import MDAnalysis as mda from openff.units import unit +import numpy as np from openfe.protocols.restraint_utils.geometry.utils import ( _get_mda_selection, + get_aromatic_rings, + get_aromatic_atom_idxs, + _wrap_angle, check_dihedral_bounds, ) @@ -42,6 +48,67 @@ def test_mda_selection_atomgroup_string(eg5_pdb_universe): assert test_ag == eg5_pdb_universe.atoms +@pytest.mark.parametrize('smiles, expected', [ + ['C1CCCCC1', []], + ['[C@@H]1([C@@H]([C@@H](OC([C@@H]1O)O)C(=O)O)O)O', []], + ['C1=CC=CC=C1', [6]], + ['C1=CC2C=CC1C=C2', [8]], + ['C1CC2=CC=CC=C2C1', [6]], + ['C1=COC=C1', [5]], + ['C1=CC=C2C=CC=CC2=C1', [10]], + ['C1=CC=C(C=C1)C2=CC=CC=C2', [6, 6]], + ['C1=CC=C(C=C1)C(C2=CC=CC=C2)(C3=CC=CC=C3Cl)N4C=CN=C4', [6, 6, 6, 5]] +]) +def test_aromatic_rings(smiles, expected): + mol = Chem.AddHs(Chem.MolFromSmiles(smiles)) + + # get the rings + rings = get_aromatic_rings(mol) + + # check we have the right number of rings & their size + for i, r in enumerate(rings): + assert len(r) == expected[i] + + # check that there is no overlap in atom between each ring + for x, y in itertools.combinations(rings, 2): + assert x.isdisjoint(y) + + # get the aromatic idx + arom_idxs = get_aromatic_atom_idxs(mol) + + # Check that all the ring indices are aromatic + assert all(idx in arom_idxs for idx in itertools.chain(*rings)) + + # Also check the lengths match + assert sum(len(r) for r in rings) == len(arom_idxs) + + # Finallly check that all the arom_idxs are actually aromatic + for idx in arom_idxs: + at = mol.GetAtomWithIdx(idx) + assert at.GetIsAromatic() + + +def test_wrap_angle_degrees(): + for i in range(0, 361, 1): + angle = _wrap_angle(i * unit.degrees) + if i > 180: + expected = ((i - 360) * unit.degrees).to('radians').m + else: + expected = (i * unit.degrees).to('radians').m + + assert angle.m == pytest.approx(expected) + + +@pytest.mark.parametrize('angle, expected', [ + [0 * unit.radians, 0 * unit.radians], + [1 * unit.radians, 1 * unit.radians], + [4 * unit.radians, 4 - (2 * np.pi) * unit.radians], + [-4 * unit.radians, -4 + (2 * np.pi) * unit.radians], +]) +def test_wrap_angle_radians(angle, expected): + assert _wrap_angle(angle) == pytest.approx(expected) + + @pytest.mark.parametrize('dihed, expected', [ [3 * unit.radians, False], [0 * unit.radians, True], @@ -63,5 +130,4 @@ def test_check_dihedral_bounds_defined(dihed, lower, upper, expected): ret = check_dihedral_bounds( dihed, lower_cutoff=lower, upper_cutoff=upper ) - assert ret == expected From 3428b39ba112bb1af352de2a406dc28c5e684273 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 26 Jan 2025 21:48:46 +0000 Subject: [PATCH 149/163] Add tests for heavy atom getter --- .../restraints/test_geometry_utils.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index 2bcf208d2..fa240cf8c 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -13,6 +13,7 @@ _get_mda_selection, get_aromatic_rings, get_aromatic_atom_idxs, + get_heavy_atom_idxs, _wrap_angle, check_dihedral_bounds, ) @@ -87,6 +88,27 @@ def test_aromatic_rings(smiles, expected): at = mol.GetAtomWithIdx(idx) assert at.GetIsAromatic() +@pytest.mark.parametrize('smiles, nheavy, nlight', [ + ['C1CCCCC1', 6, 12], + ['[C@@H]1([C@@H]([C@@H](OC([C@@H]1O)O)C(=O)O)O)O', 13, 10], + ['C1=CC=CC=C1', 6, 6], + ['C1=CC2C=CC1C=C2', 8, 8], + ['C1CC2=CC=CC=C2C1', 9, 10], + ['C1=COC=C1', 5, 4], + ['C1=CC=C2C=CC=CC2=C1', 10, 8], + ['C1=CC=C(C=C1)C2=CC=CC=C2', 12, 10], + ['C1=CC=C(C=C1)C(C2=CC=CC=C2)(C3=CC=CC=C3Cl)N4C=CN=C4', 25, 17] +]) +def test_heavy_atoms(smiles, nheavy, nlight): + mol = Chem.AddHs(Chem.MolFromSmiles(smiles)) + + n_atoms = len(list(mol.GetAtoms())) + + heavy_atoms = get_heavy_atom_idxs(mol) + + assert len(heavy_atoms) == nheavy + assert n_atoms == nheavy + nlight + def test_wrap_angle_degrees(): for i in range(0, 361, 1): From d2b0a3d9f012c74c01d050a499c5ea30d6f7839e Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 26 Jan 2025 21:53:13 +0000 Subject: [PATCH 150/163] Add extra test --- openfe/tests/protocols/restraints/test_geometry_utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index fa240cf8c..7ff2e1062 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -106,6 +106,11 @@ def test_heavy_atoms(smiles, nheavy, nlight): heavy_atoms = get_heavy_atom_idxs(mol) + # check all the heavy atoms are indeed heavy + for idx in heavy_atoms: + at = mol.GetAtomWithIdx(idx) + assert at.GetAtomicNum() > 1 + assert len(heavy_atoms) == nheavy assert n_atoms == nheavy + nlight From 3ef083ded1e89c6505912babbd752ef2cd7c7958 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Sun, 26 Jan 2025 22:33:08 +0000 Subject: [PATCH 151/163] Add some extra tests --- .../restraints/test_geometry_utils.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index 7ff2e1062..f67e12ad8 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -14,6 +14,8 @@ get_aromatic_rings, get_aromatic_atom_idxs, get_heavy_atom_idxs, + get_central_atom_idx, + is_collinear, _wrap_angle, check_dihedral_bounds, ) @@ -115,6 +117,34 @@ def test_heavy_atoms(smiles, nheavy, nlight): assert n_atoms == nheavy + nlight +def test_central_atom_disconnected(): + mol = Chem.AddHs(Chem.MolFromSmiles('C.C')) + + with pytest.raises(ValueError, match='disconnected molecule'): + _ = get_central_atom_idx(mol) + + +def test_collinear_too_few_atoms(): + with pytest.raises(ValueError, match='Too few atoms passed'): + _ = is_collinear(None, [1, 2], None) + + +def test_collinear_index_match_error_length(): + with pytest.raises(ValueError, match='indices do not match'): + _ = is_collinear( + positions=np.zeros((3, 3)), + atoms=[0, 1, 2, 3], + ) + + +def test_collinear_index_match_error_index(): + with pytest.raises(ValueError, match='indices do not match'): + _ = is_collinear( + positions=np.zeros((3, 3)), + atoms=[1, 2, 3], + ) + + def test_wrap_angle_degrees(): for i in range(0, 361, 1): angle = _wrap_angle(i * unit.degrees) From 7eb86560ac406cd4f7daaf9ea35f51f3d386cad6 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 27 Jan 2025 00:33:57 +0000 Subject: [PATCH 152/163] Add collinearity tests & better explanation of code --- .../restraint_utils/geometry/utils.py | 21 +++++++++------- .../restraints/test_geometry_utils.py | 24 +++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 67f6e2427..db827a03e 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -196,6 +196,13 @@ def is_collinear( """ Check whether any sequential vectors in a sequence of atoms are collinear. + Approach: for each sequential set of 3 atoms (defined as A, B, and C), + calculates the nomralized inner product (i.e. cos^-1(angle)) between + vectors AB adn BC. If the absolute value of this inner product is + close to 1 (i.e. an angle of 0 radians), then the three atoms are + considered as colinear. You can use ``threshold`` to define how close + to 1 is considered "flat". + Parameters ---------- positions : npt.ArrayLike @@ -229,14 +236,12 @@ def is_collinear( result = False for i in range(len(atoms) - 2): - v1 = minimize_vectors( - positions[atoms[i + 1], :] - positions[atoms[i], :], - box=dimensions, - ) - v2 = minimize_vectors( - positions[atoms[i + 2], :] - positions[atoms[i + 1], :], - box=dimensions, - ) + v1 = positions[atoms[i + 1], :] - positions[atoms[i], :] + v2 = positions[atoms[i + 2], :] - positions[atoms[i + 1], :] + if dimensions is not None: + v1 = minimize_vectors(v1, box=dimensions) + v2 = minimize_vectors(v2, box=dimensions) + normalized_inner_product = np.dot(v1, v2) / np.sqrt( np.dot(v1, v1) * np.dot(v2, v2) ) diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index f67e12ad8..2ba91377b 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -145,6 +145,30 @@ def test_collinear_index_match_error_index(): ) +@pytest.mark.parametrize('arr, truth', [ + [[[0, 0, -1], [1, 0, 0], [2, 0, 2]], True], + [[[0, 1, -1], [1, 0, 0], [2, 0, 2]], False], + [[[0, 1, -1], [1, 1, 0], [2, 1, 2]], True], + [[[0, 0, -1], [1, 1, 0], [2, 2, 2]], True], + [[[0, 0, -1], [1, 0, 0], [2, 0, 2]], True], + [[[2, 0, -1], [1, 0, 0], [0, 0, 2]], True], + [[[0, 0, 1], [0, 0, 0], [0, 0, 2]], True], + [[[1, 1, 1], [0, 0, 0], [2, 2, 2]], True] +]) +def test_is_collinear_three_atoms(arr, truth): + assert is_collinear(np.array(arr), [0, 1, 2]) == truth + + +@pytest.mark.parametrize('arr, truth', [ + [[[0, 0, -1], [1, 0, 0], [2, 0, 2], [3, 0, 4]], True], + [[[0, 0, -1], [1, 0, 0], [2, 0, 2], [3, 0, 2]], True], + [[[0, 0, 1], [1, 0, 0], [2, 0, 2], [3, 0, 4]], True], + [[[0, 1, -1], [1, 0, 0], [2, 0, 2], [3, 0, 2]], False], +]) +def test_is_collinear_four_atoms(arr, truth): + assert is_collinear(np.array(arr), [0, 1, 2, 3]) == truth + + def test_wrap_angle_degrees(): for i in range(0, 361, 1): angle = _wrap_angle(i * unit.degrees) From e91121190f71bad26a2fe8e1f8f7b40b643c9e6e Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 27 Jan 2025 01:48:27 +0000 Subject: [PATCH 153/163] Add tests and fix a few things --- .../restraint_utils/geometry/utils.py | 6 +-- .../restraints/test_geometry_utils.py | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index db827a03e..114ae2e94 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -695,7 +695,7 @@ def protein_chain_selection( "No bonds found in input Universe, will attept to guess them." ) warnings.warn(wmsg) - protein_ag.guess_bonds() + copy_protein_ag.guess_bonds() copy_chains_ags_list = [] @@ -706,10 +706,10 @@ def protein_chain_selection( continue chain = frag.residues[trim_chain_start:-trim_chain_end].atoms - copy_chain_ags_list.append(chain) + copy_chains_ags_list.append(chain) # Create a single atomgroup from all chains - copy_chains_ag = sum(copy_chain_ags_list) + copy_chains_ag = sum(copy_chains_ags_list) # Now get a list of all the chain atoms in the original Universe # Resindexes are keyed at the Universe scale not AtomGroup diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index 2ba91377b..15ee21115 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -18,6 +18,7 @@ is_collinear, _wrap_angle, check_dihedral_bounds, + _atomgroup_has_bonds, ) @@ -117,6 +118,26 @@ def test_heavy_atoms(smiles, nheavy, nlight): assert n_atoms == nheavy + nlight +@pytest.mark.parametrize('smiles, idx', [ + ['C1CCCCC1', 2], + ['[C@@H]1([C@@H]([C@@H](OC([C@@H]1O)O)C(=O)O)O)O', 3], + ['C1=CC=CC=C1', 2], + ['C1=CC2C=CC1C=C2', 2], + ['C1CC2=CC=CC=C2C1', 2], + ['C1=COC=C1', 4], + ['C1=CC=C2C=CC=CC2=C1', 3], + ['C1=CC=C(C=C1)C2=CC=CC=C2', 6], + ['C1=CC=C(C=C1)C(C2=CC=CC=C2)(C3=CC=CC=C3Cl)N4C=CN=C4', 6], + ['OC(COc1ccc(cc1)CC(=O)N)CNC(C)C', 3], +]) +def test_central_idx(smiles, idx): + """ + Regression tests for getting central atom idx. + """ + rdmol = Chem.AddHs(Chem.MolFromSmiles(smiles)) + assert get_central_atom_idx(rdmol) == idx + + def test_central_atom_disconnected(): mol = Chem.AddHs(Chem.MolFromSmiles('C.C')) @@ -212,3 +233,23 @@ def test_check_dihedral_bounds_defined(dihed, lower, upper, expected): dihed, lower_cutoff=lower, upper_cutoff=upper ) assert ret == expected + + +def test_atomgroup_has_bonds(eg5_protein_pdb): + # Creating a new universe because we'll modify this one + u = mda.Universe(eg5_protein_pdb) + + # PDB has water bonds + assert len(u.bonds) == 14 + assert _atomgroup_has_bonds(u) is False + assert _atomgroup_has_bonds(u.select_atoms('resname HOH')) is True + + # Delete the topoplogy attr and everything is false + u.del_TopologyAttr('bonds') + assert _atomgroup_has_bonds(u) is False + assert _atomgroup_has_bonds(u.select_atoms('resname HOH')) is False + + # Guess some bonds back + ag = u.atoms[:100] + ag.guess_bonds() + assert _atomgroup_has_bonds(ag) is True From 0c2f1026aad1a3f0742907ef9128a950dc233b44 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Mon, 27 Jan 2025 02:44:26 +0000 Subject: [PATCH 154/163] Angle variance tests --- .../restraint_utils/geometry/utils.py | 2 +- .../restraints/test_geometry_utils.py | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 114ae2e94..4ca5de7a4 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -365,7 +365,7 @@ def check_angular_variance( Parameters ---------- - angles : ArrayLike[unit.Quantity] + angles : ArrayLike unit.Quantity An array of angles in units compatible with radians. upper_bound: unit.Quantity The upper bound in the angle range in radians compatible units. diff --git a/openfe/tests/protocols/restraints/test_geometry_utils.py b/openfe/tests/protocols/restraints/test_geometry_utils.py index 15ee21115..4f8047ea0 100644 --- a/openfe/tests/protocols/restraints/test_geometry_utils.py +++ b/openfe/tests/protocols/restraints/test_geometry_utils.py @@ -16,8 +16,10 @@ get_heavy_atom_idxs, get_central_atom_idx, is_collinear, + check_angle_not_flat, _wrap_angle, check_dihedral_bounds, + check_angular_variance, _atomgroup_has_bonds, ) @@ -211,6 +213,26 @@ def test_wrap_angle_radians(angle, expected): assert _wrap_angle(angle) == pytest.approx(expected) +@pytest.mark.parametrize('limit, force, temperature', [ + [0.7695366605411506, 83.68, 298.15], + [0.8339791717799163, 83.68, 350.0], + [0.5441445910402979, 167.36, 298.15] +]) +def test_angle_not_flat(limit, force, temperature): + limit = limit * unit.radians + force = force * unit.kilojoule_per_mole / unit.radians ** 2 + temperature = temperature * unit.kelvin + + # test upper + assert check_angle_not_flat(limit + 0.01, force, temperature) + assert not check_angle_not_flat(limit - 0.01, force, temperature) + + # test lower + limit = np.pi - limit + assert check_angle_not_flat(limit - 0.01, force, temperature) + assert not check_angle_not_flat(limit + 0.01, force, temperature) + + @pytest.mark.parametrize('dihed, expected', [ [3 * unit.radians, False], [0 * unit.radians, True], @@ -235,6 +257,28 @@ def test_check_dihedral_bounds_defined(dihed, lower, upper, expected): assert ret == expected +def test_angular_variance(): + """ + Manual check with for an input number of angles with + a known variance of 0.36216 + """ + angles = [0, 1, 2, 6] + + assert check_angular_variance( + angles=angles * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=-np.pi * unit.radians, + width=0.37 * unit.radians + ) + + assert not check_angular_variance( + angles=angles * unit.radians, + upper_bound=np.pi * unit.radians, + lower_bound=-np.pi * unit.radians, + width=0.35 * unit.radians + ) + + def test_atomgroup_has_bonds(eg5_protein_pdb): # Creating a new universe because we'll modify this one u = mda.Universe(eg5_protein_pdb) From 7f1067485d1b389b8651d3425b88b2c894e742fa Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 29 Jan 2025 10:48:06 +0100 Subject: [PATCH 155/163] First step towards using omm-restraints class --- openfe/protocols/openmm_septop/base.py | 33 ++++--- .../openmm_septop/equil_septop_method.py | 94 +++++++++---------- .../geometry/boresch/__init__.py | 1 + .../geometry/boresch/geometry.py | 2 +- .../restraint_utils/geometry/utils.py | 4 +- 5 files changed, 67 insertions(+), 67 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index e04c7ea86..2b918d9ef 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -77,6 +77,8 @@ AbsoluteAlchemicalFactory, AlchemicalRegion, ) +import MDAnalysis as mda +from openfe.protocols.restraint_utils.geometry.boresch import find_boresch_restraint logger = logging.getLogger(__name__) @@ -566,15 +568,13 @@ def _set_positions( @staticmethod def _add_restraints( system: openmm.System, - positions: simtk.unit.Quantity, - topology: openmm.app.Topology, - ligand_1: OFFMolecule, - ligand_2: OFFMolecule, + u: mda.Universe, + ligand_1: RDKitMolecule, + ligand_2: RDKitMolecule, + ligand_1_inxs: list[int], + ligand_2_inxs: list[int], + protein_inxs: Optional[list[int]], settings: dict[str, SettingsBaseModel], - ligand_1_ref_idxs: tuple[int, int, int], # indices from the ligand topology - ligand_2_ref_idxs: tuple[int, int, int], # indices from the ligand topology - ligand_1_idxs: tuple[int, int, int], # indices from the full topology - ligand_2_idxs: tuple[int, int, int], # indices from the full topology ) -> openmm.System: """ Get new positions for the stateB after equilibration. @@ -853,13 +853,20 @@ def run(self, dry=False, verbose=True, ligand_B_inxs = tuple([atom_indices_AB_B[inx] for inx in ligand_B_ref_inxs]) print(ligand_A_inxs) print(ligand_B_inxs) - + u = mda.Universe(omm_topology_AB, modeller_AB) + if prot_comp: + protein_idxs = comp_atomids_AB[prot_comp] + else: + protein_idxs = None system = self._add_restraints( - alchemical_system, positions_AB, omm_topology_AB, - off_A, off_B, + alchemical_system, u, + alchem_comps["stateA"][0].to_rdkit(), + alchem_comps["stateB"][0].to_rdkit(), + comp_atomids_AB[alchem_comps["stateA"][0]], + comp_atomids_AB[alchem_comps["stateB"][0]], + protein_idxs, settings, - ligand_A_ref_inxs, ligand_B_ref_inxs, - ligand_A_inxs, ligand_B_inxs) + ) # # Check that the restraints are correctly applied by running a short equilibration equ_positions_restraints = self._pre_equilibrate( system, omm_topology_AB, positions_AB, settings, dry diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 9c44a4a73..cd7c7b16c 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -76,6 +76,9 @@ from .femto_utils import assign_force_groups from openff.units.openmm import to_openmm from rdkit import Chem +import MDAnalysis as mda +from openfe.protocols.restraint_utils.geometry.boresch import ( + find_boresch_restraint, find_guest_atom_candidates) due.cite(Doi("10.5281/zenodo.596622"), @@ -989,15 +992,13 @@ def _update_positions( @staticmethod def _add_restraints( system: openmm.System, - positions: simtk.unit.Quantity, - topology: openmm.app.Topology, - ligand_1: OFFMolecule, - ligand_2: OFFMolecule, + u, + ligand_1, + ligand_2, + ligand_1_inxs: tuple[int], + ligand_2_inxs: tuple[int], + protein_inxs: tuple[int], settings: dict[str, SettingsBaseModel], - ligand_1_ref_idxs: tuple[int, int, int], - ligand_2_ref_idxs: tuple[int, int, int], - ligand_1_idxs: tuple[int, int, int], - ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: """ Adds Boresch restraints to the system. @@ -1031,53 +1032,44 @@ def _add_restraints( The OpenMM system with the added restraints forces """ - # Get mdtraj object for system - traj = _get_mdtraj_from_openmm(topology, positions) - # Get mdtraj object for ligands - ligand_1 = ligand_1.to_topology() - ligand_2 = ligand_2.to_topology() - ligand_1_mdtraj = md.Trajectory( - np.array(ligand_1.get_positions() / omm_units.nanometers), - md.Topology.from_openmm(ligand_1.to_openmm())) - ligand_2_mdtraj = md.Trajectory( - np.array(ligand_2.get_positions() / omm_units.nanometers), - md.Topology.from_openmm(ligand_2.to_openmm())) - - # Select the reference indices in the receptor - receptor_ref_idxs_1 = select_receptor_idxs( - traj, ligand_1_mdtraj, ligand_1_ref_idxs - ) - print(receptor_ref_idxs_1) - receptor_ref_idxs_2 = receptor_ref_idxs_1 - - if not check_receptor_idxs( - traj, receptor_ref_idxs_1, ligand_2_mdtraj, ligand_2_ref_idxs - ): - receptor_ref_idxs_2 = select_receptor_idxs( - traj, ligand_2_mdtraj, ligand_2_ref_idxs) - print(receptor_ref_idxs_2) - + boresch_A = find_boresch_restraint( + u, + ligand_1, + ligand_1_inxs, + protein_inxs, + host_selection='name C or name CA or name CB or name N or name O', + dssp_filter=True) + + boresch_B = find_boresch_restraint( + u, + ligand_2, + ligand_2_inxs, + protein_inxs, + host_selection='name C or name CA or name CB or name N or name O', + dssp_filter=True) + print(boresch_A) + print(boresch_B) # Convert restraint units to openmm k_distance = to_openmm(settings["restraint_settings"].k_distance) k_theta = to_openmm(settings["restraint_settings"].k_theta) force_A = create_boresch_restraint( - receptor_ref_idxs_1[::-1], # expects [r3, r2, r1], not [r1, r2, r3] - ligand_1_idxs, - positions, + boresch_A.host_atoms[::-1], # expects [r3, r2, r1], not [r1, r2, r3] + boresch_A.guest_atoms, + u.atoms.positions * omm_units.angstrom, k_distance, k_theta, "lambda_restraints_A", ) system.addForce(force_A) force_B = create_boresch_restraint( - receptor_ref_idxs_2[::-1], + boresch_B.host_atoms[::-1], # expects [r3, r2, r1], not [r1, r2, r3] - ligand_2_idxs, - positions, + boresch_B.guest_atoms, + u.atoms.positions * omm_units.angstrom, k_distance, k_theta, - "lambda_restraints_B", + "lambda_restraints_A", ) system.addForce(force_B) @@ -1235,15 +1227,13 @@ def _update_positions( @staticmethod def _add_restraints( system: openmm.System, - positions, - topology, + u, ligand_1, ligand_2, + ligand_1_inxs: tuple[int], + ligand_2_inxs: tuple[int], + protein_inxs, settings: dict[str, SettingsBaseModel], - ligand_1_ref_idxs: tuple[int, int, int], - ligand_2_ref_idxs: tuple[int, int, int], - ligand_1_idxs: tuple[int, int, int], - ligand_2_idxs: tuple[int, int, int], ) -> openmm.System: """ Apply the distance restraint between the ligands. @@ -1277,18 +1267,20 @@ def _add_restraints( The OpenMM system with the added restraints forces """ - coords = positions + coords = u.atoms.positions + ligand_idxs_A = find_guest_atom_candidates(u, ligand_1, ligand_1_inxs) + ligand_idxs_B = find_guest_atom_candidates(u, ligand_2, ligand_2_inxs) # Taking the middle reference atom distance = np.linalg.norm( - coords[ligand_1_idxs[1]] - coords[ligand_2_idxs[1]]) + coords[ligand_idxs_A[0][0]] - coords[ligand_idxs_B[0][0]]) print(distance) k_distance = to_openmm(settings['restraint_settings'].k_distance) force = openmm.HarmonicBondForce() force.addBond( - ligand_1_idxs[1], - ligand_2_idxs[1], + ligand_idxs_A[0][0], + ligand_idxs_B[0][0], distance * openmm.unit.nanometers, k_distance, ) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/__init__.py b/openfe/protocols/restraint_utils/geometry/boresch/__init__.py index 57c306c58..ab3c38cfc 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch/__init__.py +++ b/openfe/protocols/restraint_utils/geometry/boresch/__init__.py @@ -1,4 +1,5 @@ from .geometry import ( BoreschRestraintGeometry, find_boresch_restraint, + find_guest_atom_candidates, ) diff --git a/openfe/protocols/restraint_utils/geometry/boresch/geometry.py b/openfe/protocols/restraint_utils/geometry/boresch/geometry.py index 0640ecf21..8449967db 100644 --- a/openfe/protocols/restraint_utils/geometry/boresch/geometry.py +++ b/openfe/protocols/restraint_utils/geometry/boresch/geometry.py @@ -135,7 +135,7 @@ def find_boresch_restraint( dssp_filter: bool = False, rmsf_cutoff: unit.Quantity = 0.1 * unit.nanometer, host_min_distance: unit.Quantity = 1 * unit.nanometer, - host_max_distance: unit.Quantity = 3 * unit.nanometer, + host_max_distance: unit.Quantity = 2 * unit.nanometer, angle_force_constant: unit.Quantity = ( 83.68 * unit.kilojoule_per_mole / unit.radians**2 ), diff --git a/openfe/protocols/restraint_utils/geometry/utils.py b/openfe/protocols/restraint_utils/geometry/utils.py index 4ca5de7a4..36fec7c0f 100644 --- a/openfe/protocols/restraint_utils/geometry/utils.py +++ b/openfe/protocols/restraint_utils/geometry/utils.py @@ -587,7 +587,7 @@ def stable_secondary_structure_selection( # We need to split by fragments to account for multiple chains # To do this, we need bonds! - if not _atomgroup_has_bonds(copy_protein_ag, 'bonds'): + if not _atomgroup_has_bonds(copy_protein_ag): wmsg = "No bonds found in input Universe, will attept to guess them." warnings.warn(wmsg) protein_ag.guess_bonds() @@ -690,7 +690,7 @@ def protein_chain_selection( # We need to split by fragments to account for multiple chains # To do this, we need bonds! - if not _atomgroup_has_bonds(copy_protein_ag, 'bonds'): + if not _atomgroup_has_bonds(copy_protein_ag): wmsg = ( "No bonds found in input Universe, will attept to guess them." ) From 74c88ab999d1c151472e718f8154cdaf417dddf8 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 29 Jan 2025 10:50:35 +0100 Subject: [PATCH 156/163] Small fixes --- openfe/protocols/openmm_septop/equil_septop_method.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index cd7c7b16c..9a5accf23 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1069,7 +1069,7 @@ def _add_restraints( u.atoms.positions * omm_units.angstrom, k_distance, k_theta, - "lambda_restraints_A", + "lambda_restraints_B", ) system.addForce(force_B) @@ -1281,7 +1281,7 @@ def _add_restraints( force.addBond( ligand_idxs_A[0][0], ligand_idxs_B[0][0], - distance * openmm.unit.nanometers, + distance * openmm.unit.angstrom, k_distance, ) force.setName("alignment_restraint") From 956f3f9048dc493fbca1297c4eb7fa462f5630de Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 29 Jan 2025 11:13:23 +0100 Subject: [PATCH 157/163] Fix type --- openfe/protocols/openmm_septop/equil_septop_method.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 9a5accf23..49dec5b31 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -1270,17 +1270,19 @@ def _add_restraints( coords = u.atoms.positions ligand_idxs_A = find_guest_atom_candidates(u, ligand_1, ligand_1_inxs) ligand_idxs_B = find_guest_atom_candidates(u, ligand_2, ligand_2_inxs) - # Taking the middle reference atom + # Taking the first reference atom + ref_A = int(ligand_idxs_A[0][0]) + ref_B = int(ligand_idxs_B[0][0]) distance = np.linalg.norm( - coords[ligand_idxs_A[0][0]] - coords[ligand_idxs_B[0][0]]) + coords[ref_A] - coords[ref_B]) print(distance) k_distance = to_openmm(settings['restraint_settings'].k_distance) force = openmm.HarmonicBondForce() force.addBond( - ligand_idxs_A[0][0], - ligand_idxs_B[0][0], + ref_A, + ref_B, distance * openmm.unit.angstrom, k_distance, ) From 0516aad1f6c48061740d42530006b8c5817234c6 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 29 Jan 2025 12:50:51 +0100 Subject: [PATCH 158/163] Fix atom selection solvent restraints --- openfe/protocols/openmm_septop/equil_septop_method.py | 9 ++++----- openfe/tests/protocols/test_openmm_septop.py | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 49dec5b31..630908692 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -79,6 +79,7 @@ import MDAnalysis as mda from openfe.protocols.restraint_utils.geometry.boresch import ( find_boresch_restraint, find_guest_atom_candidates) +from openfe.protocols.restraint_utils.geometry.utils import get_central_atom_idx due.cite(Doi("10.5281/zenodo.596622"), @@ -1268,11 +1269,9 @@ def _add_restraints( """ coords = u.atoms.positions - ligand_idxs_A = find_guest_atom_candidates(u, ligand_1, ligand_1_inxs) - ligand_idxs_B = find_guest_atom_candidates(u, ligand_2, ligand_2_inxs) - # Taking the first reference atom - ref_A = int(ligand_idxs_A[0][0]) - ref_B = int(ligand_idxs_B[0][0]) + ref_A = ligand_1_inxs[get_central_atom_idx(ligand_1)] + ref_B = ligand_2_inxs[get_central_atom_idx(ligand_2)] + print(ref_A, ref_B) distance = np.linalg.norm( coords[ref_A] - coords[ref_B]) print(distance) diff --git a/openfe/tests/protocols/test_openmm_septop.py b/openfe/tests/protocols/test_openmm_septop.py index 8bef0eb60..21de8a9b4 100644 --- a/openfe/tests/protocols/test_openmm_septop.py +++ b/openfe/tests/protocols/test_openmm_septop.py @@ -659,7 +659,6 @@ def test_dry_run_benzene_toluene(benzene_toluene_dag, tmpdir): with tmpdir.as_cwd(): solv_setup_output = solv_setup_unit[0].run(dry=True) pdb = md.load_pdb('topology.pdb') - print(pdb.n_atoms) assert pdb.n_atoms == 4481 central_atoms = np.array([[2, 4475]], dtype=np.int32) distance = md.compute_distances(pdb, central_atoms)[0][0] From 9166110db63af2caecbca6a66094dfdbf290a303 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Wed, 29 Jan 2025 13:04:22 +0100 Subject: [PATCH 159/163] Fix modeller positions --- openfe/protocols/openmm_septop/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 2b918d9ef..bdea43fa9 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -853,7 +853,9 @@ def run(self, dry=False, verbose=True, ligand_B_inxs = tuple([atom_indices_AB_B[inx] for inx in ligand_B_ref_inxs]) print(ligand_A_inxs) print(ligand_B_inxs) + modeller_AB.positions = positions_AB u = mda.Universe(omm_topology_AB, modeller_AB) + print(u) if prot_comp: protein_idxs = comp_atomids_AB[prot_comp] else: From e22c7031b5ed7bea24f8fb095436a0e53b417dcf Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 31 Jan 2025 10:59:46 +0100 Subject: [PATCH 160/163] Use separate structures for getting Boresch restraints --- openfe/protocols/openmm_septop/base.py | 21 +++++++---- .../openmm_septop/equil_septop_method.py | 36 ++++++++++++------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index bdea43fa9..37711e06c 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -271,6 +271,7 @@ def _pre_equilibrate( state = simulation.context.getState(getPositions=True) equilibrated_positions = state.getPositions(asNumpy=True) + print(simulation.context.getPositions(asNumpy=True)) # cautiously delete out contexts & integrator del simulation.context, integrator @@ -568,12 +569,15 @@ def _set_positions( @staticmethod def _add_restraints( system: openmm.System, - u: mda.Universe, + u_A: mda.Universe, + u_B: mda.Universe, ligand_1: RDKitMolecule, ligand_2: RDKitMolecule, ligand_1_inxs: list[int], ligand_2_inxs: list[int], + ligand_2_inxs_B: list[int], protein_inxs: Optional[list[int]], + positions_AB: omm_unit.Quantity, settings: dict[str, SettingsBaseModel], ) -> openmm.System: """ @@ -853,20 +857,25 @@ def run(self, dry=False, verbose=True, ligand_B_inxs = tuple([atom_indices_AB_B[inx] for inx in ligand_B_ref_inxs]) print(ligand_A_inxs) print(ligand_B_inxs) + # Update the positions in the modeller + modeller_A.positions = equ_positions_A + modeller_B.positions = updated_positions_B modeller_AB.positions = positions_AB - u = mda.Universe(omm_topology_AB, modeller_AB) - print(u) + u_A = mda.Universe(omm_topology_A, modeller_A) + u_B = mda.Universe(omm_topology_B, modeller_B) if prot_comp: protein_idxs = comp_atomids_AB[prot_comp] else: protein_idxs = None system = self._add_restraints( - alchemical_system, u, + alchemical_system, u_A, u_B, alchem_comps["stateA"][0].to_rdkit(), alchem_comps["stateB"][0].to_rdkit(), - comp_atomids_AB[alchem_comps["stateA"][0]], - comp_atomids_AB[alchem_comps["stateB"][0]], + atom_indices_AB_A, + atom_indices_AB_B, + atom_indices_B, protein_idxs, + positions_AB, settings, ) # # Check that the restraints are correctly applied by running a short equilibration diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 630908692..d757c39c7 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -993,12 +993,15 @@ def _update_positions( @staticmethod def _add_restraints( system: openmm.System, - u, + u_A, + u_B, ligand_1, ligand_2, ligand_1_inxs: tuple[int], ligand_2_inxs: tuple[int], + ligand_2_inxs_B: tuple[int], protein_inxs: tuple[int], + positions_AB: omm_units.Quantity, settings: dict[str, SettingsBaseModel], ) -> openmm.System: """ @@ -1034,7 +1037,7 @@ def _add_restraints( """ boresch_A = find_boresch_restraint( - u, + u_A, ligand_1, ligand_1_inxs, protein_inxs, @@ -1042,14 +1045,19 @@ def _add_restraints( dssp_filter=True) boresch_B = find_boresch_restraint( - u, + u_B, ligand_2, - ligand_2_inxs, + ligand_2_inxs_B, protein_inxs, host_selection='name C or name CA or name CB or name N or name O', dssp_filter=True) print(boresch_A) print(boresch_B) + print(boresch_B.guest_atoms) + # We have to update the indices for ligand B to match the AB complex + new_boresch_B_indices = [ligand_2_inxs_B.index(i) for i in boresch_B.guest_atoms] + boresch_B.guest_atoms = [ligand_2_inxs[i] for i in new_boresch_B_indices] + print(boresch_B.guest_atoms) # Convert restraint units to openmm k_distance = to_openmm(settings["restraint_settings"].k_distance) k_theta = to_openmm(settings["restraint_settings"].k_theta) @@ -1057,7 +1065,7 @@ def _add_restraints( force_A = create_boresch_restraint( boresch_A.host_atoms[::-1], # expects [r3, r2, r1], not [r1, r2, r3] boresch_A.guest_atoms, - u.atoms.positions * omm_units.angstrom, + positions_AB, k_distance, k_theta, "lambda_restraints_A", @@ -1067,7 +1075,7 @@ def _add_restraints( boresch_B.host_atoms[::-1], # expects [r3, r2, r1], not [r1, r2, r3] boresch_B.guest_atoms, - u.atoms.positions * omm_units.angstrom, + positions_AB, k_distance, k_theta, "lambda_restraints_B", @@ -1228,12 +1236,15 @@ def _update_positions( @staticmethod def _add_restraints( system: openmm.System, - u, + u_A, + u_B, ligand_1, ligand_2, ligand_1_inxs: tuple[int], ligand_2_inxs: tuple[int], + ligand_2_inxs_B: tuple[int], protein_inxs, + positions_AB, settings: dict[str, SettingsBaseModel], ) -> openmm.System: """ @@ -1268,12 +1279,13 @@ def _add_restraints( The OpenMM system with the added restraints forces """ - coords = u.atoms.positions + coords_A = u_A.atoms.positions + coords_B = u_B.atoms.positions ref_A = ligand_1_inxs[get_central_atom_idx(ligand_1)] - ref_B = ligand_2_inxs[get_central_atom_idx(ligand_2)] - print(ref_A, ref_B) + ref_B = ligand_2_inxs_B[get_central_atom_idx(ligand_2)] + print(ref_A, ref_B, ligand_2_inxs[ligand_2_inxs_B.index(ref_B)]) distance = np.linalg.norm( - coords[ref_A] - coords[ref_B]) + coords_A[ref_A] - coords_B[ref_B]) print(distance) k_distance = to_openmm(settings['restraint_settings'].k_distance) @@ -1281,7 +1293,7 @@ def _add_restraints( force = openmm.HarmonicBondForce() force.addBond( ref_A, - ref_B, + ligand_2_inxs[ligand_2_inxs_B.index(ref_B)], distance * openmm.unit.angstrom, k_distance, ) From 13769c6b912718e3322774998eaf735917053efe Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 31 Jan 2025 11:19:33 +0100 Subject: [PATCH 161/163] Add equil traj output --- openfe/protocols/openmm_septop/equil_septop_method.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index d757c39c7..0ccc9c5fd 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -538,7 +538,7 @@ def _default_settings(cls): complex_equil_output_settings=MDOutputSettings( equil_nvt_structure=None, equil_npt_structure='equil_structure.pdb', - production_trajectory_filename=None, + production_trajectory_filename='equil_npt.xtc', log_output='equil_simulation.log', ), complex_simulation_settings=MultiStateSimulationSettings( From 55156872e015582c7650a17a7e42b9d435fa8ff5 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Fri, 31 Jan 2025 12:08:18 +0100 Subject: [PATCH 162/163] Add traj output equil --- openfe/protocols/openmm_septop/base.py | 3 +-- openfe/protocols/openmm_septop/equil_septop_method.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 37711e06c..7b8825c5d 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -268,10 +268,8 @@ def _pre_equilibrate( verbose=self.verbose, shared_basepath=self.shared_basepath, ) - state = simulation.context.getState(getPositions=True) equilibrated_positions = state.getPositions(asNumpy=True) - print(simulation.context.getPositions(asNumpy=True)) # cautiously delete out contexts & integrator del simulation.context, integrator @@ -791,6 +789,7 @@ def run(self, dry=False, verbose=True, omm_system_B, omm_topology_B, positions_B, settings, dry ) + simtk.openmm.app.pdbfile.PDBFile.writeFile( omm_topology_A, equ_positions_A, open(self.shared_basepath / 'outputA_equ.pdb', 'w')) simtk.openmm.app.pdbfile.PDBFile.writeFile( diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 0ccc9c5fd..70fbc001f 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -517,7 +517,7 @@ def _default_settings(cls): solvent_equil_output_settings=MDOutputSettings( equil_nvt_structure=None, equil_npt_structure='equil_npt_structure.pdb', - production_trajectory_filename=None, + production_trajectory_filename='equil_npt.xtc', log_output='equil_simulation.log', ), solvent_simulation_settings=MultiStateSimulationSettings( From c00083298312539949ca926d59963d3ac7e01801 Mon Sep 17 00:00:00 2001 From: hannahbaumann Date: Tue, 4 Feb 2025 11:47:06 +0100 Subject: [PATCH 163/163] Subclass MDOutputSettings for SepTop --- openfe/protocols/openmm_septop/base.py | 43 +++++++++++++--- .../openmm_septop/equil_septop_method.py | 26 +++++----- .../openmm_septop/equil_septop_settings.py | 51 ++++++++++++++++++- 3 files changed, 98 insertions(+), 22 deletions(-) diff --git a/openfe/protocols/openmm_septop/base.py b/openfe/protocols/openmm_septop/base.py index 7b8825c5d..e137826e6 100644 --- a/openfe/protocols/openmm_septop/base.py +++ b/openfe/protocols/openmm_septop/base.py @@ -173,6 +173,7 @@ def _pre_equilibrate( topology: openmm.app.Topology, positions: omm_unit.Quantity, settings: dict[str, SettingsBaseModel], + state: str, dry: bool ) -> omm_unit.Quantity: """ @@ -194,6 +195,8 @@ def _pre_equilibrate( * `integrator_settings` * `equil_simulation_settings` * `equil_output_settings` + state: str + The state that is pre_equilibrates, either 'A' or 'B'. dry: bool Whether or not this is a dry run. @@ -250,6 +253,32 @@ def _pre_equilibrate( # Don't do anything if we're doing a dry run if dry: return positions + unfrozen_outsettings = settings['equil_output_settings'].unfrozen_copy() + + if state == 'A' or state == 'B': + if unfrozen_outsettings.production_trajectory_filename: + unfrozen_outsettings.production_trajectory_filename = ( + unfrozen_outsettings.production_trajectory_filename + f'_state{state}.xtc') + if unfrozen_outsettings.preminimized_structure: + unfrozen_outsettings.preminimized_structure = ( + unfrozen_outsettings.preminimized_structure + f'_state{state}.pdb') + if unfrozen_outsettings.minimized_structure: + unfrozen_outsettings.minimized_structure = ( + unfrozen_outsettings.minimized_structure + f'_state{state}.pdb') + if unfrozen_outsettings.equil_nvt_structure: + unfrozen_outsettings.equil_nvt_structure = ( + unfrozen_outsettings.equil_nvt_structure + f'_state{state}.pdb') + if unfrozen_outsettings.equil_npt_structure: + unfrozen_outsettings.equil_npt_structure = ( + unfrozen_outsettings.equil_npt_structure + f'_state{state}.pdb') + if unfrozen_outsettings.log_output: + unfrozen_outsettings.log_output = ( + unfrozen_outsettings.log_output + f'_state{state}.log') + print(unfrozen_outsettings) + else: + errmsg = f"Only 'A' and 'B' are accepted as states. Got {state}" + raise ValueError(errmsg) + # Use the _run_MD method from the PlainMDProtocolUnit # Should in-place modify the simulation @@ -257,7 +286,7 @@ def _pre_equilibrate( simulation=simulation, positions=positions, simulation_settings=settings['equil_simulation_settings'], - output_settings=settings['equil_output_settings'], + output_settings=unfrozen_outsettings, temperature=settings['thermo_settings'].temperature, barostat_frequency=settings[ 'integrator_settings'].barostat_frequency, @@ -783,10 +812,10 @@ def run(self, dry=False, verbose=True, # 6. Pre-equilbrate System (Test + Avoid NaNs + get stable system) self.logger.info("Pre-equilibrating the systems") equ_positions_A = self._pre_equilibrate( - omm_system_A, omm_topology_A, positions_A, settings, dry + omm_system_A, omm_topology_A, positions_A, settings, 'A', dry ) equ_positions_B = self._pre_equilibrate( - omm_system_B, omm_topology_B, positions_B, settings, dry + omm_system_B, omm_topology_B, positions_B, settings, 'B', dry ) @@ -878,12 +907,12 @@ def run(self, dry=False, verbose=True, settings, ) # # Check that the restraints are correctly applied by running a short equilibration - equ_positions_restraints = self._pre_equilibrate( - system, omm_topology_AB, positions_AB, settings, dry - ) + # equ_positions_restraints = self._pre_equilibrate( + # system, omm_topology_AB, positions_AB, settings, dry + # ) topology_file = self.shared_basepath / 'topology.pdb' simtk.openmm.app.pdbfile.PDBFile.writeFile(omm_topology_AB, - equ_positions_restraints, + positions_AB, open(topology_file, 'w')) diff --git a/openfe/protocols/openmm_septop/equil_septop_method.py b/openfe/protocols/openmm_septop/equil_septop_method.py index 70fbc001f..8837e3e6c 100644 --- a/openfe/protocols/openmm_septop/equil_septop_method.py +++ b/openfe/protocols/openmm_septop/equil_septop_method.py @@ -58,7 +58,7 @@ from openfe.protocols.openmm_septop.equil_septop_settings import ( SepTopSettings, OpenMMSolvationSettings, AlchemicalSettings, LambdaSettings, - MDSimulationSettings, MDOutputSettings, + MDSimulationSettings, SepTopEquilOutputSettings, MultiStateSimulationSettings, OpenMMEngineSettings, IntegratorSettings, MultiStateOutputSettings, OpenFFPartialChargeSettings, @@ -514,11 +514,11 @@ def _default_settings(cls): equilibration_length=0.1 * unit.nanosecond, production_length=0.5 * unit.nanosecond, ), - solvent_equil_output_settings=MDOutputSettings( + solvent_equil_output_settings=SepTopEquilOutputSettings( equil_nvt_structure=None, - equil_npt_structure='equil_npt_structure.pdb', - production_trajectory_filename='equil_npt.xtc', - log_output='equil_simulation.log', + equil_npt_structure='equil_npt_structure', + production_trajectory_filename='equil_npt', + log_output='equil_simulation', ), solvent_simulation_settings=MultiStateSimulationSettings( n_replicas=19, @@ -535,11 +535,11 @@ def _default_settings(cls): equilibration_length=0.1 * unit.nanosecond, production_length=0.5 * unit.nanosecond, ), - complex_equil_output_settings=MDOutputSettings( + complex_equil_output_settings=SepTopEquilOutputSettings( equil_nvt_structure=None, - equil_npt_structure='equil_structure.pdb', - production_trajectory_filename='equil_npt.xtc', - log_output='equil_simulation.log', + equil_npt_structure='equil_structure', + production_trajectory_filename='equil_npt', + log_output='equil_simulation', ), complex_simulation_settings=MultiStateSimulationSettings( n_replicas=19, @@ -924,7 +924,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings - * equil_output_settings : MDOutputSettings + * equil_output_settings : SepTopEquilOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: ComplexRestraintsSettings @@ -1164,7 +1164,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings - * equil_output_settings : MDOutputSettings + * equil_output_settings : SepTopEquilOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: SolventRestraintsSettings @@ -1381,7 +1381,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings - * equil_output_settings : MDOutputSettings + * equil_output_settings : SepTopEquilOutputSettings * simulation_settings : MultiStateSimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: SolventRestraintsSettings @@ -1505,7 +1505,7 @@ def _handle_settings(self) -> dict[str, SettingsBaseModel]: * engine_settings : OpenMMEngineSettings * integrator_settings : IntegratorSettings * equil_simulation_settings : MDSimulationSettings - * equil_output_settings : MDOutputSettings + * equil_output_settings : SepTopEquilOutputSettings * simulation_settings : SimulationSettings * output_settings: MultiStateOutputSettings * restraint_settings: ComplexRestraintsSettings diff --git a/openfe/protocols/openmm_septop/equil_septop_settings.py b/openfe/protocols/openmm_septop/equil_septop_settings.py index e969bded7..8bf523f69 100644 --- a/openfe/protocols/openmm_septop/equil_septop_settings.py +++ b/openfe/protocols/openmm_septop/equil_septop_settings.py @@ -29,6 +29,7 @@ from openff.models.types import FloatQuantity import numpy as np from pydantic.v1 import validator +from typing import Optional class AlchemicalSettings(SettingsBaseModel): @@ -151,6 +152,52 @@ def must_be_monotonic(cls, v): return v +class SepTopEquilOutputSettings(MDOutputSettings): + # reporter settings + output_indices = 'all' + production_trajectory_filename: Optional[str] = 'simulation' + """ + Basename for the path to the storage file for analysis. The protocol will + append a '_stateA.xtc' and a '_stateB.xtc' for the output files of the + respective endstates. Default 'simulation'. + """ + trajectory_write_interval: FloatQuantity['picosecond'] = 20 * unit.picosecond + """ + Frequency to write the xtc file. Default 20 * unit.picosecond. + """ + preminimized_structure: Optional[str] = 'system' + """ + Basename for the path to the pdb file of the full pre-minimized systems. + The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output + files of the respective endstates. Default 'system'. + """ + minimized_structure: Optional[str] = 'minimized' + """ + Basename for the path to the pdb file of the systems after minimization. + The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output + files of the respective endstates. Default 'minimized'. + """ + equil_nvt_structure: Optional[str] = 'equil_nvt' + """ + Basename for the path to the pdb file of the systems after NVT equilibration. + The protocol will append a '_stateA' and a '_stateB' for the output files + of the respective endstates. Default 'equil_nvt.pdb'. + """ + equil_npt_structure: Optional[str] = 'equil_npt' + """ + Basename for the path to the pdb file of the systems after NPT equilibration. + The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output + files of the respective endstates. Default 'equil_npt'. + """ + log_output: Optional[str] = 'simulation' + """ + Basename for the filename for writing the log of the MD simulation, + including timesteps, energies, density, etc. + The protocol will append a '_stateA.pdb' and a '_stateB.pdb' for the output + files of the respective endstates. Default 'simulation'. + """ + + # This subclasses from SettingsBaseModel as it has vacuum_forcefield and # solvent_forcefield fields, not just a single forcefield_settings field class SepTopSettings(SettingsBaseModel): @@ -237,7 +284,7 @@ def must_be_positive(cls, v): Simulation control settings, including simulation lengths for the solvent transformation. """ - complex_equil_output_settings: MDOutputSettings + complex_equil_output_settings: SepTopEquilOutputSettings """ Simulation output settings for the complex non-alchemical equilibration. """ @@ -245,7 +292,7 @@ def must_be_positive(cls, v): """ Simulation output settings for the complex transformation. """ - solvent_equil_output_settings: MDOutputSettings + solvent_equil_output_settings: SepTopEquilOutputSettings """ Simulation output settings for the solvent non-alchemical equilibration. """

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