Exemplo n.º 1
0
    def get_context(self, thermodynamic_state, integrator=None):
        """Create a new context in the given thermodynamic state.

        Parameters
        ----------
        thermodynamic_state : states.ThermodynamicState
            The thermodynamic state of the system.
        integrator : simtk.openmm.Integrator, optional
            The integrator to bind to the new context. If ``None``, an arbitrary
            integrator is used. Currently, this is a ``LangevinIntegrator`` with
            "V R O R V" splitting, but this might change in the future. Default
            is ``None``.

        Returns
        -------
        context : simtk.openmm.Context
            The new context in the given thermodynamic system.
        context_integrator : simtk.openmm.Integrator
            The integrator bound to the context that can be used for
            propagation. This is identical to the ``integrator`` argument
            if it was passed.

        """
        if integrator is None:
            integrator = integrators.LangevinIntegrator(
                timestep=1.0 * unit.femtoseconds,
                splitting="V R O R V",
                temperature=thermodynamic_state.temperature)
        context = thermodynamic_state.create_context(integrator, self.platform)
        return context, integrator
def get_energy_vac(system, positions):
    """
    Return the potential energy.
    Parameters
    ----------
    system : simtk.openmm.System
        The system to check
    positions : simtk.unit.Quantity of dimension (natoms,3) with units of length
        The positions to use

    Returns
    ---------
    energy
    """

    integrator = ommtoolsints.LangevinIntegrator(293.15 * kelvin, 1./picoseconds, 1.5 * femtoseconds)
    platform = mm.Platform.getPlatformByName('CPU')
    #platform = mm.Platform.getPlatformByName('CUDA')
    #properties = {"CudaPrecision": "mixed","DeterministicForces": "true" }

    #context = mm.Context(system, integrator, platform, properties)
    context = mm.Context(system, integrator, platform)
 
    context.setPositions(positions)#*angstroms)
    state = context.getState(getEnergy=True)
    energy = state.getPotentialEnergy()
    return energy
def get_energy_vac(system, positions):
    """
    Return the potential energy.
    Parameters
    ----------
    system : simtk.openmm.System
        The system to check
    positions : simtk.unit.Quantity of dimension (natoms,3) with units of length
        The positions to use

    Returns
    ---------
    energy
    """

    integrator = ommtoolsints.LangevinIntegrator(293.15 * kelvin,
                                                 1. / picoseconds,
                                                 1.0 * femtoseconds)
    platform = mm.Platform.getPlatformByName('CPU')

    context = mm.Context(system, integrator, platform)

    context.setPositions(positions)
    state = context.getState(getEnergy=True)
    energy = state.getPotentialEnergy()
    return energy
Exemplo n.º 4
0
def run_equilibrium(system, topology, configuration, n_steps, report_interval, filename):
    from mdtraj.reporters import HDF5Reporter
    integrator = integrators.LangevinIntegrator()
    simulation = app.Simulation(topology, system, integrator)
    simulation.context.setPositions(configuration)

    #equilibrate a little bit:
    simulation.step(10000)

    reporter = HDF5Reporter(filename, report_interval)
    simulation.reporters.append(reporter)
    simulation.step(n_steps)
Exemplo n.º 5
0
def run_equilibrium(system, topology, configuration, n_steps, report_interval, equilibration_steps, filename):
    from mdtraj.reporters import HDF5Reporter
    integrator = integrators.LangevinIntegrator()
    simulation = app.Simulation(topology, system, integrator)
    simulation.context.setPositions(configuration)
    openmm.LocalEnergyMinimizer.minimize(simulation.context)

    #equilibrate:
    integrator.step(equilibration_steps)

    print("equilibration complete")

    reporter = HDF5Reporter(filename, report_interval)
    simulation.reporters.append(reporter)
    simulation.step(n_steps)
Exemplo n.º 6
0
def create_langevin_integrator(htf, constraint_tol):
    """
    create lambda alchemical states, thermodynamic states, sampler states, integrator, and return context, thermostate, sampler_state, integrator
    """
    fast_lambda_alchemical_state = RelativeAlchemicalState.from_system(
        htf.hybrid_system)
    fast_lambda_alchemical_state.set_alchemical_parameters(
        0.0, LambdaProtocol(functions='default'))

    fast_thermodynamic_state = CompoundThermodynamicState(
        ThermodynamicState(htf.hybrid_system, temperature=temperature),
        composable_states=[fast_lambda_alchemical_state])

    fast_sampler_state = SamplerState(
        positions=htf._hybrid_positions,
        box_vectors=htf.hybrid_system.getDefaultPeriodicBoxVectors())

    integrator_1 = integrators.LangevinIntegrator(
        temperature=temperature,
        timestep=4.0 * unit.femtoseconds,
        splitting='V R O R V',
        measure_shadow_work=False,
        measure_heat=False,
        constraint_tolerance=constraint_tol,
        collision_rate=5.0 / unit.picoseconds)
    #     mcmc_moves=mcmc.LangevinSplittingDynamicsMove(timestep = 4.0 * unit.femtoseconds,
    #                                                              collision_rate=5.0 / unit.picosecond,
    #                                                              n_steps=1,
    #                                                              reassign_velocities=False,
    #                                                              n_restart_attempts=20,
    #                                                              splitting="V R R R O R R R V",
    #                                                              constraint_tolerance=constraint_tol)

    #print(integrator_1.getConstraintTolerance())

    fast_context, fast_integrator = cache.global_context_cache.get_context(
        fast_thermodynamic_state, integrator_1)

    fast_sampler_state.apply_to_context(fast_context)

    return fast_context, fast_thermodynamic_state, fast_sampler_state, fast_integrator
Exemplo n.º 7
0
    def initialize(self,
                   thermodynamic_state,
                   lambda_protocol='default',
                   timestep=1 * unit.femtoseconds,
                   collision_rate=1 / unit.picoseconds,
                   temperature=300 * unit.kelvin,
                   neq_splitting_string='V R O R V',
                   ncmc_save_interval=None,
                   topology=None,
                   subset_atoms=None,
                   measure_shadow_work=False,
                   integrator='langevin',
                   compute_endstate_correction=True):

        try:
            self.context_cache = cache.global_context_cache

            if measure_shadow_work:
                measure_heat = True
            else:
                measure_heat = False

            self.thermodynamic_state = thermodynamic_state
            if integrator == 'langevin':
                self.integrator = integrators.LangevinIntegrator(
                    temperature=temperature,
                    timestep=timestep,
                    splitting=neq_splitting_string,
                    measure_shadow_work=measure_shadow_work,
                    measure_heat=measure_heat,
                    constraint_tolerance=1e-6,
                    collision_rate=collision_rate)
            elif integrator == 'hmc':
                self.integrator = integrators.HMCIntegrator(
                    temperature=temperature, nsteps=2, timestep=timestep / 2)
            else:
                raise Exception(
                    f"integrator {integrator} is not supported. supported integrators include {self.supported_integrators}"
                )

            self.lambda_protocol_class = LambdaProtocol(
                functions=lambda_protocol)

            #create temperatures
            self.beta = 1.0 / (kB * temperature)
            self.temperature = temperature

            self.save_interval = ncmc_save_interval

            self.topology = topology
            self.subset_atoms = subset_atoms

            #if we have a trajectory, set up some ancillary variables:
            if self.topology is not None:
                n_atoms = self.topology.n_atoms
                self._trajectory_positions = []
                self._trajectory_box_lengths = []
                self._trajectory_box_angles = []

            self.compute_endstate_correction = compute_endstate_correction
            if self.compute_endstate_correction:
                self.thermodynamic_state.set_alchemical_parameters(
                    0.0, lambda_protocol=self.lambda_protocol_class)
                first_endstate = copy.deepcopy(self.thermodynamic_state)
                self.thermodynamic_state.set_alchemical_parameters(
                    1.0, lambda_protocol=self.lambda_protocol_class)
                last_endstate = copy.deepcopy(self.thermodynamic_state)
                endstates = create_endstates(first_endstate, last_endstate)
                self.endstates = {0.0: endstates[0], 1.0: endstates[1]}
            else:
                self.endstates = None

            #set a bool variable for pass or failure
            self.succeed = True
            return True
        except Exception as e:
            _logger.error(e)
            self.succeed = False
            return False
Exemplo n.º 8
0
    temperature = 300. * unit.kelvin
    collision_rate = 1. / unit.picoseconds
    pressure = 1. * unit.atmospheres

    # Make the water box test system with a fixed pressure
    wbox = WaterBox(model=args.model,
                    box_edge=box_edge,
                    nonbondedMethod=app.PME,
                    cutoff=10 * unit.angstrom,
                    ewaldErrorTolerance=1E-4)
    wbox.system.addForce(openmm.MonteCarloBarostat(pressure, temperature))

    # Create the compound integrator
    langevin = integrators.LangevinIntegrator(splitting=splitting,
                                              temperature=temperature,
                                              timestep=timestep,
                                              collision_rate=collision_rate,
                                              measure_shadow_work=False,
                                              measure_heat=False)
    ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator(
        splitting=splitting,
        temperature=temperature,
        timestep=timestep,
        collision_rate=collision_rate,
        measure_shadow_work=False,
        measure_heat=False)
    integrator = openmm.CompoundIntegrator()
    integrator.addIntegrator(langevin)
    integrator.addIntegrator(ncmc_langevin)

    # Create context
    if args.platform == 'CUDA':
Exemplo n.º 9
0
    def __init__(self,
                 thermodynamic_state,
                 sampler_state,
                 nsteps,
                 direction,
                 splitting='V R O R V',
                 temperature=300 * unit.kelvin,
                 collision_rate=np.inf / unit.picoseconds,
                 timestep=1.0 * unit.femtosecond,
                 work_save_interval=None,
                 top=None,
                 subset_atoms=None,
                 save_configuration=False,
                 lambda_protocol='default',
                 measure_shadow_work=False,
                 label=None,
                 trajectory_filename=None):

        _logger.debug(f"Initializing Particle...")
        start = time.time()
        self._timers = {}  #instantiate timer
        self.label = [label]

        self.context_cache = cache.global_context_cache

        if measure_shadow_work:
            measure_heat = True
        else:
            measure_heat = False

        assert direction == 'forward' or direction == 'reverse', f"The direction of the annealing protocol ({direction}) is invalid; must be specified as 'forward' or 'reverse'"

        self._direction = direction

        #define the lambda schedule (linear)
        if self._direction == 'forward':
            self.start_lambda = 0.0
            self.end_lambda = 1.0
        elif self._direction == 'reverse':
            self.start_lambda = 1.0
            self.end_lambda = 0.0
        else:
            raise Error(f"direction must be 'forward' or 'reverse'")

        #create lambda protocol
        self._nsteps = nsteps
        if self._nsteps is None:
            self.trailblaze = True
            self._work_save_interval = None  # this is allowed to be None, in which case, the save_config method will never be called
            #likewise, if work work save interval is longer than the trailblazed lambda protocol, the save_configuration method will never be called
            self.current_lambda = self.start_lambda
            self.importance_samples = 1  #including the zero state
            #if we opt to trailblaze, we don't define a self.lambdas linsapce
            #instead, we define a self.current lambda and set it to the value of the start lambda
        else:
            self.trailblaze = False
            self.lambdas = np.linspace(self.start_lambda, self.end_lambda,
                                       self._nsteps)
            self.current_index = int(0)
            self.current_lambda = self.lambdas[self.current_index]
            if work_save_interval is None:
                self._work_save_interval = None
            else:
                self._work_save_interval = work_save_interval
                #check that the work write interval is a factor of the number of steps, so we don't accidentally record the
                #work before the end of the protocol as the end
                if self._nsteps % self._work_save_interval != 0:
                    raise ValueError(
                        "The work writing interval must be a factor of the total number of steps"
                    )

        #create sampling objects
        self.sampler_state = sampler_state
        self.thermodynamic_state = thermodynamic_state
        _logger.debug(f"thermodynamic state: {self.thermodynamic_state}")
        self.integrator = integrators.LangevinIntegrator(
            temperature=temperature,
            timestep=timestep,
            splitting=splitting,
            measure_shadow_work=measure_shadow_work,
            measure_heat=measure_heat,
            constraint_tolerance=1e-6,
            collision_rate=collision_rate)
        #platform = openmm.Platform.getPlatformByName(platform_name)
        self.context = openmm.Context(self.thermodynamic_state.system,
                                      self.integrator)
        #self.context, self.integrator = self.context_cache.get_context(self.thermodynamic_state, integrator)
        _logger.debug(f"context: {self.context}")
        self.lambda_protocol_class = LambdaProtocol(functions=lambda_protocol)
        self.thermodynamic_state.set_alchemical_parameters(
            self.start_lambda, lambda_protocol=self.lambda_protocol_class)
        self.thermodynamic_state.apply_to_context(self.context)
        self.sampler_state.apply_to_context(self.context,
                                            ignore_velocities=True)
        self.context.setVelocitiesToTemperature(
            self.thermodynamic_state.temperature)  #randomize velocities @ temp
        self.integrator.step(1)
        self.sampler_state.update_from_context(self.context)

        #create temperatures
        self._beta = 1.0 / (kB * temperature)
        self._temperature = temperature

        init_state = self.context.getState(getEnergy=True)
        self.initial_energy = self._beta * (init_state.getPotentialEnergy() +
                                            init_state.getKineticEnergy())

        self._save_configuration = save_configuration
        self._measure_shadow_work = measure_shadow_work
        if self._save_configuration:
            if trajectory_filename is None:
                raise Exception(
                    f"cannot save configuration when trajectory_filename is None"
                )
            else:
                self._trajectory_filename = trajectory_filename

        #use the number of step moves plus one, since the first is always zero
        self._cumulative_work = [0.0]
        self._shadow_work = 0.0
        self._heat = 0.0

        self._topology = top
        self._subset_atoms = subset_atoms
        self._trajectory = None

        #if we have a trajectory, set up some ancillary variables:
        if self._topology is not None:
            n_atoms = self._topology.n_atoms
            self._trajectory_positions = []
            self._trajectory_box_lengths = []
            self._trajectory_box_angles = []
        else:
            self._save_configuration = False

        self._timers['instantiate'] = time.time() - start
        self._timers['protocol'] = []
        self._timers['save'] = []

        #set a bool variable for pass or failure
        self.succeed = True
        self.failures = []
        _logger.debug(f"Initialization complete!")
Exemplo n.º 10
0
def setup_fah_run(destination_path,
                  protein_pdb_filename,
                  oemol=None,
                  cache=None,
                  restrain_rmsd=False):
    """
    Prepare simulation

    Parameters
    ----------
    destination_path : str
        The path to the RUN to be created
    protein_pdb_filename : str
        Path to protein PDB file
    oemol : openeye.oechem.OEMol, optional, default=None
        The molecule to parameterize, with SDData attached
        If None, don't include the small molecule
    restrain_rmsd : bool, optional, default=False
        If True, restrain RMSD during first equilibration phase
    """
    # Parameters
    from simtk import unit, openmm
    protein_forcefield = 'amber14/protein.ff14SB.xml'
    solvent_forcefield = 'amber14/tip3p.xml'
    small_molecule_forcefield = 'openff-1.2.0'
    water_model = 'tip3p'
    solvent_padding = 10.0 * unit.angstrom
    ionic_strength = 70 * unit.millimolar  # assay buffer: 20 mM HEPES pH 7.3, 1 mM TCEP, 50 mM NaCl, 0.01% Tween-20, 10% glycerol
    pressure = 1.0 * unit.atmospheres
    collision_rate = 1.0 / unit.picoseconds
    temperature = 300.0 * unit.kelvin
    timestep = 4.0 * unit.femtoseconds
    iterations = 1000  # 1 ns equilibration
    nsteps_per_iteration = 250

    # Prepare phases
    import os
    system_xml_filename = os.path.join(destination_path, 'system.xml.bz2')
    integrator_xml_filename = os.path.join(destination_path,
                                           'integrator.xml.bz2')
    state_xml_filename = os.path.join(destination_path, 'state.xml.bz2')

    # Check if we can skip setup
    openmm_files_exist = os.path.exists(
        system_xml_filename) and os.path.exists(
            state_xml_filename) and os.path.exists(integrator_xml_filename)
    if openmm_files_exist:
        return

    # Create barostat
    barostat = openmm.MonteCarloBarostat(pressure, temperature)

    # Create RUN directory if it does not yet exist
    os.makedirs(destination_path, exist_ok=True)

    # Load any molecule(s)
    molecule = None
    if oemol is not None:
        from openforcefield.topology import Molecule
        molecule = Molecule.from_openeye(oemol, allow_undefined_stereo=True)
        molecule.name = 'MOL'  # Ensure residue is MOL
        print([res for res in molecule.to_topology().to_openmm().residues()])

    # Create SystemGenerator
    import os
    from simtk.openmm import app
    forcefield_kwargs = {
        'removeCMMotion': False,
        'hydrogenMass': 3.0 * unit.amu,
        'constraints': app.HBonds,
        'rigidWater': True
    }
    periodic_kwargs = {
        'nonbondedMethod': app.PME,
        'ewaldErrorTolerance': 2.5e-04
    }
    forcefields = [protein_forcefield, solvent_forcefield]
    from openmmforcefields.generators import SystemGenerator
    openmm_system_generator = SystemGenerator(
        forcefields=forcefields,
        molecules=molecule,
        small_molecule_forcefield=small_molecule_forcefield,
        cache=cache,
        barostat=barostat,
        forcefield_kwargs=forcefield_kwargs,
        periodic_forcefield_kwargs=periodic_kwargs)

    # Read protein
    print(f'Reading protein from {protein_pdb_filename}...')
    pdbfile = app.PDBFile(protein_pdb_filename)
    modeller = app.Modeller(pdbfile.topology, pdbfile.positions)

    if oemol is not None:
        # Add small molecule to the system
        modeller.add(molecule.to_topology().to_openmm(),
                     molecule.conformers[0])
        # DEBUG : Check residue name
        with open(os.path.join(destination_path, 'initial-complex.pdb'),
                  'wt') as outfile:
            app.PDBFile.writeFile(modeller.topology, modeller.positions,
                                  outfile)

    # Add solvent
    print('Adding solvent...')
    kwargs = {'padding': solvent_padding}
    modeller.addSolvent(openmm_system_generator.forcefield,
                        model='tip3p',
                        ionicStrength=ionic_strength,
                        **kwargs)

    # Create an OpenMM system
    print('Creating OpenMM system...')
    system = openmm_system_generator.create_system(modeller.topology)

    # Add a virtual bond between protein and ligand to make sure they are not imaged separately
    if oemol is not None:
        import mdtraj as md
        mdtop = md.Topology.from_openmm(
            modeller.topology)  # excludes solvent and ions
        for res in mdtop.residues:
            print(res)
        protein_atom_indices = mdtop.select(
            '(protein and name CA)')  # protein CA atoms
        ligand_atom_indices = mdtop.select(
            '((resname MOL) and (mass > 1))')  # ligand heavy atoms
        protein_atom_index = int(protein_atom_indices[0])
        ligand_atom_index = int(ligand_atom_indices[0])
        force = openmm.CustomBondForce('0')
        force.addBond(protein_atom_index, ligand_atom_index, [])
        system.addForce(force)

    # Add RMSD restraints if requested
    if restrain_rmsd:
        print('Adding RMSD restraint...')
        kB = unit.AVOGADRO_CONSTANT_NA * unit.BOLTZMANN_CONSTANT_kB
        kT = kB * temperature
        import mdtraj as md
        mdtop = md.Topology.from_openmm(
            pdbfile.topology)  # excludes solvent and ions
        #heavy_atom_indices = mdtop.select('mass > 1') # heavy solute atoms
        rmsd_atom_indices = mdtop.select(
            '(protein and (name CA)) or ((resname MOL) and (mass > 1))'
        )  # CA atoms and ligand heavy atoms
        rmsd_atom_indices = [int(index) for index in rmsd_atom_indices]
        custom_cv_force = openmm.CustomCVForce('(K_RMSD/2)*RMSD^2')
        custom_cv_force.addGlobalParameter('K_RMSD', kT / unit.angstrom**2)
        rmsd_force = openmm.RMSDForce(modeller.positions, rmsd_atom_indices)
        custom_cv_force.addCollectiveVariable('RMSD', rmsd_force)
        force_index = system.addForce(custom_cv_force)

    # Create OpenM Context
    platform = openmm.Platform.getPlatformByName('OpenCL')
    platform.setPropertyDefaultValue('Precision', 'mixed')
    from openmmtools import integrators
    integrator = integrators.LangevinIntegrator(temperature, collision_rate,
                                                timestep)
    context = openmm.Context(system, integrator, platform)
    context.setPositions(modeller.positions)

    # Report initial potential energy
    state = context.getState(getEnergy=True)
    print(
        f'Initial potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol'
    )

    # Store snapshots in MDTraj trajectory to examine RMSD
    import mdtraj as md
    import numpy as np
    mdtop = md.Topology.from_openmm(pdbfile.topology)
    atom_indices = mdtop.select('all')  # all solute atoms
    protein_atom_indices = mdtop.select(
        'protein and (mass > 1)')  # heavy solute atoms
    if oemol is not None:
        ligand_atom_indices = mdtop.select(
            '(resname MOL) and (mass > 1)')  # ligand heavy atoms
    trajectory = md.Trajectory(
        np.zeros([iterations + 1, len(atom_indices), 3], np.float32), mdtop)
    trajectory.xyz[0, :, :] = context.getState(getPositions=True).getPositions(
        asNumpy=True)[atom_indices] / unit.nanometers

    # Minimize
    print('Minimizing...')
    openmm.LocalEnergyMinimizer.minimize(context)

    # Equilibrate (with RMSD restraint if needed)
    import numpy as np
    from rich.progress import track
    import time
    initial_time = time.time()
    for iteration in track(range(iterations), 'Equilibrating...'):
        integrator.step(nsteps_per_iteration)
        trajectory.xyz[iteration + 1, :, :] = context.getState(
            getPositions=True).getPositions(
                asNumpy=True)[atom_indices] / unit.nanometers
    elapsed_time = (time.time() - initial_time) * unit.seconds
    ns_per_day = (context.getState().getTime() /
                  elapsed_time) / (unit.nanoseconds / unit.day)
    print(f'Performance: {ns_per_day:8.3f} ns/day')

    if restrain_rmsd:
        # Disable RMSD restraint
        context.setParameter('K_RMSD', 0.0)

        print('Minimizing...')
        openmm.LocalEnergyMinimizer.minimize(context)

        for iteration in track(range(iterations),
                               'Equilibrating without RMSD restraint...'):
            integrator.step(nsteps_per_iteration)

    # Retrieve state
    state = context.getState(getPositions=True,
                             getVelocities=True,
                             getEnergy=True,
                             getForces=True)
    system.setDefaultPeriodicBoxVectors(*state.getPeriodicBoxVectors())
    modeller.topology.setPeriodicBoxVectors(state.getPeriodicBoxVectors())
    print(
        f'Final potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol'
    )

    # Equilibrate again if we restrained the RMSD
    if restrain_rmsd:
        print('Removing RMSD restraint from system...')
        system.removeForce(force_index)

    #if oemol is not None:
    #    # Check final RMSD
    #    print('checking RMSD...')
    #    trajectory.superpose(trajectory, atom_indices=protein_atom_indices)
    #    protein_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=protein_atom_indices)[-1] * 10 # Angstroms
    #    oechem.OESetSDData(oemol, 'equil_protein_rmsd', f'{protein_rmsd:.2f} A')
    #    ligand_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=ligand_atom_indices)[-1] * 10 # Angstroms
    #    oechem.OESetSDData(oemol, 'equil_ligand_rmsd', f'{ligand_rmsd:.2f} A')
    #    print('RMSD after equilibration: protein {protein_rmsd:8.2f} A | ligand {ligand_rmsd:8.3f} A')

    # Save as OpenMM
    print('Exporting for OpenMM FAH simulation...')
    import bz2
    with bz2.open(integrator_xml_filename, 'wt') as f:
        f.write(openmm.XmlSerializer.serialize(integrator))
    with bz2.open(state_xml_filename, 'wt') as f:
        f.write(openmm.XmlSerializer.serialize(state))
    with bz2.open(system_xml_filename, 'wt') as f:
        f.write(openmm.XmlSerializer.serialize(system))
    with bz2.open(os.path.join(destination_path, 'equilibrated-all.pdb.gz'),
                  'wt') as f:
        app.PDBFile.writeFile(modeller.topology, state.getPositions(), f)
    with open(os.path.join(destination_path, 'equilibrated-solute.pdb'),
              'wt') as f:
        import mdtraj
        mdtraj_topology = mdtraj.Topology.from_openmm(modeller.topology)
        mdtraj_trajectory = mdtraj.Trajectory(
            [state.getPositions(asNumpy=True) / unit.nanometers],
            mdtraj_topology)
        selection = mdtraj_topology.select('not water')
        mdtraj_trajectory = mdtraj_trajectory.atom_slice(selection)
        app.PDBFile.writeFile(mdtraj_trajectory.topology.to_openmm(),
                              mdtraj_trajectory.openmm_positions(0), f)
    if oemol is not None:
        # Write molecule as SDF, SMILES, and mol2
        for extension in ['sdf', 'mol2', 'smi', 'csv']:
            filename = os.path.join(destination_path, f'molecule.{extension}')
            with oechem.oemolostream(filename) as ofs:
                oechem.OEWriteMolecule(ofs, oemol)

    # Clean up
    del context, integrator
Exemplo n.º 11
0
def create_ideal_system(npert=50, nprop=1, deltachem=0.0, platform='CPU'):
    """
    Create small box of water that can impliment ideal mixing with the SaltSwap osmostat.

    Parameters
    ----------
    npert: int
        the number of NCMC perturbations
    nprop: int
        the number of Langevin propagation steps per NCMC perturbation.
    deltachem: float
        the difference in chemical potential between two water molecules and NaCl that has the same nonbonded parameters
        as two water molecules.
    platform: str
        The computational platform. Either 'CPU', 'CUDA', or 'OpenCL'.

    Returns
    -------
    ncmc_swapper: saltswap.swapper
        the driver that can perform NCMC exchanges
    langevin: openmmtools.integrator
        the integrator for equilibrium sampling.
    """
    # Setting the parameters of the simulation
    timestep = 2.0 * unit.femtoseconds
    box_edge = 25.0 * unit.angstrom
    splitting = 'V R O R V'
    temperature = 300. * unit.kelvin
    collision_rate = 1. / unit.picoseconds
    pressure = 1. * unit.atmospheres

    # Make the water box test system with a fixed pressure
    wbox = WaterBox(box_edge=box_edge,
                    model='tip3p',
                    nonbondedMethod=app.PME,
                    cutoff=10 * unit.angstrom,
                    ewaldErrorTolerance=1E-4)
    wbox.system.addForce(openmm.MonteCarloBarostat(pressure, temperature))

    # Create the compound integrator
    langevin = integrators.LangevinIntegrator(splitting=splitting,
                                              temperature=temperature,
                                              timestep=timestep,
                                              collision_rate=collision_rate,
                                              measure_shadow_work=False,
                                              measure_heat=False)
    ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator(
        splitting=splitting,
        temperature=temperature,
        timestep=timestep,
        collision_rate=collision_rate,
        measure_shadow_work=False,
        measure_heat=False)
    integrator = openmm.CompoundIntegrator()
    integrator.addIntegrator(langevin)
    integrator.addIntegrator(ncmc_langevin)

    # Create context
    if platform == 'CUDA':
        platform = openmm.Platform.getPlatformByName('CUDA')
        platform.setPropertyDefaultValue('DeterministicForces', 'true')
        properties = {'CudaPrecision': 'mixed'}
        context = openmm.Context(wbox.system, integrator, platform, properties)
    elif platform == 'OpenCL':
        platform = openmm.Platform.getPlatformByName('OpenCL')
        properties = {'OpenCLPrecision': 'mixed'}
        context = openmm.Context(wbox.system, integrator, platform, properties)
    elif platform == 'CPU':
        platform = openmm.Platform.getPlatformByName('CPU')
        context = openmm.Context(wbox.system, integrator, platform)
    else:
        raise Exception('Platform name {0} not recognized.'.format(
            args.platform))

    context.setPositions(wbox.positions)
    context.setVelocitiesToTemperature(temperature)

    # Create the swapper object for the insertion and deletion of salt
    ncmc_swapper = Swapper(system=wbox.system,
                           topology=wbox.topology,
                           temperature=temperature,
                           delta_chem=deltachem,
                           ncmc_integrator=ncmc_langevin,
                           pressure=pressure,
                           npert=npert,
                           nprop=nprop)

    # Set the nonbonded parameters of the ions to be the same as water. This is critical for ideal mixing.
    ncmc_swapper.cation_parameters = ncmc_swapper.water_parameters
    ncmc_swapper.anion_parameters = ncmc_swapper.water_parameters
    ncmc_swapper._set_parampath()

    return context, ncmc_swapper, langevin
Exemplo n.º 12
0
def validate_rjmc_work_variance(top_prop,
                                positions,
                                geometry_method=0,
                                num_iterations=10,
                                md_steps=250,
                                compute_timeseries=False,
                                md_system=None,
                                prespecified_conformers=None):
    """
    Arguments
    ----------
    top_prop : perses.rjmc.topology_proposal.TopologyProposal object
        topology_proposal
    md_system : openmm.System object, default None
        system from which md is conducted; the default is the top_prop._old_system
    geometry_method : int
        which geometry proposal method to use
            0: neglect_angles = True (this is supposed to be the zero-variance method)
            1: neglect_angles = False (this will accumulate variance)
            2: use_sterics = True (this is experimental)
    num_iterations: int
        number of times to run md_steps integrator
    md_steps: int
        number of md_steps to run in each num_iteration
    compute_timeseries = bool (default False)
        whether to use pymbar detectEquilibration and subsampleCorrelated data from the MD run (the potential energy is the data)
    prespecified_conformers = None or unit.Quantity(np.array([num_iterations, system.getNumParticles(), 3]), unit = unit.nanometers)
        whether to input a unit.Quantity of conformers and bypass the conformer_generation/pymbar stage; None will default conduct this phase

    Returns
    -------
    conformers : unit.Quantity(np.array([num_iterations, system.getNumParticles(), 3]), unit = unit.nanometers)
        decorrelated positions of the md run
    rj_works : list
        work from each conformer proposal
    """
    from openmmtools import integrators
    from perses.utils.openeye import smiles_to_oemol
    import simtk.unit as unit
    import simtk.openmm as openmm
    from openmmtools.constants import kB
    from perses.rjmc.geometry import FFAllAngleGeometryEngine
    import tqdm

    temperature = 300.0 * unit.kelvin  # unit-bearing temperature
    kT = kB * temperature  # unit-bearing thermal energy
    beta = 1.0 / kT  # unit-bearing inverse thermal energy

    #first, we must extract the top_prop relevant quantities
    topology = top_prop._old_topology
    if md_system == None:
        system = top_prop._old_system
    else:
        system = md_system

    if prespecified_conformers == None:

        #now we can specify conformations from MD
        integrator = integrators.LangevinIntegrator(
            collision_rate=1.0 / unit.picosecond,
            timestep=4.0 * unit.femtosecond,
            temperature=temperature)
        context = openmm.Context(system, integrator)
        context.setPositions(positions)
        openmm.LocalEnergyMinimizer.minimize(context)
        minimized_positions = context.getState(getPositions=True).getPositions(
            asNumpy=True)
        print(f"completed initial minimization")
        context.setPositions(minimized_positions)

        zeros = np.zeros([num_iterations, int(system.getNumParticles()), 3])
        conformers = unit.Quantity(zeros, unit=unit.nanometers)
        rps = np.zeros((num_iterations))

        print(f"conducting md sampling")
        for iteration in tqdm.trange(num_iterations):
            integrator.step(md_steps)
            state = context.getState(getPositions=True, getEnergy=True)
            new_positions = state.getPositions(asNumpy=True)
            conformers[iteration, :, :] = new_positions

            rp = state.getPotentialEnergy() * beta
            rps[iteration] = rp

        del context, integrator

        if compute_timeseries:
            print(f"computing production and data correlation")
            from pymbar import timeseries
            t0, g, Neff = timeseries.detectEquilibration(rps)
            series = timeseries.subsampleCorrelatedData(np.arange(
                t0, num_iterations),
                                                        g=g)
            print(f"production starts at index {t0} of {num_iterations}")
            print(f"the number of effective samples is {Neff}")
            indices = t0 + series
            print(f"the filtered indices are {indices}")

        else:
            indices = range(num_iterations)
    else:
        conformers = prespecified_conformers
        indices = range(len(conformers))

    #now we can define a geometry_engine
    if geometry_method == 0:
        geometry_engine = FFAllAngleGeometryEngine(
            metadata=None,
            use_sterics=False,
            n_bond_divisions=1000,
            n_angle_divisions=180,
            n_torsion_divisions=360,
            verbose=True,
            storage=None,
            bond_softening_constant=1.0,
            angle_softening_constant=1.0,
            neglect_angles=True)
    elif geometry_method == 1:
        geometry_engine = FFAllAngleGeometryEngine(
            metadata=None,
            use_sterics=False,
            n_bond_divisions=1000,
            n_angle_divisions=180,
            n_torsion_divisions=360,
            verbose=True,
            storage=None,
            bond_softening_constant=1.0,
            angle_softening_constant=1.0,
            neglect_angles=False)
    elif geometry_method == 2:
        geometry_engine = FFAllAngleGeometryEngine(
            metadata=None,
            use_sterics=True,
            n_bond_divisions=1000,
            n_angle_divisions=180,
            n_torsion_divisions=360,
            verbose=True,
            storage=None,
            bond_softening_constant=1.0,
            angle_softening_constant=1.0,
            neglect_angles=False)
    else:
        raise Exception(f"there is no geometry method for {geometry_method}")

    rj_works = []
    print(f"conducting geometry proposals...")
    for indx in tqdm.trange(len(indices)):
        index = indices[indx]
        print(f"index {indx}")
        new_positions, logp_forward = geometry_engine.propose(
            top_prop, conformers[index], beta)
        logp_backward = geometry_engine.logp_reverse(top_prop, new_positions,
                                                     conformers[index], beta)
        print(
            f"\tlogp_forward, logp_backward: {logp_forward}, {logp_backward}")
        added_energy = geometry_engine.forward_final_context_reduced_potential - geometry_engine.forward_atoms_with_positions_reduced_potential
        subtracted_energy = geometry_engine.reverse_final_context_reduced_potential - geometry_engine.reverse_atoms_with_positions_reduced_potential
        print(
            f"\tadded_energy, subtracted_energy: {added_energy}, {subtracted_energy}"
        )
        work = logp_forward - logp_backward + added_energy - subtracted_energy
        rj_works.append(work)
        print(f"\ttotal work: {work}")

    return conformers, rj_works
Exemplo n.º 13
0
kinetic_temperature = 293.15*kelvin
collision_frequency = 1./picosecond
step_size = 1.*femtoseconds

pressure = 1.01*bar
barostat_frequency = 10
#############################################################
#############################################################

system = forcefield.createSystem(pdb.topology,mols,nonbondedMethod=PME,nonbondedCutoff=1.125*nanometers)#,ewaldErrorTolerance=1.e-5)#,constraints=HBonds)

#box_vectors = AmberInpcrdFile('monomers/cyclohexane.inpcrd').boxVectors
#system.setDefaultPeriodicBoxVectors(*box_vectors)


integrator = ommtoolsints.LangevinIntegrator(kinetic_temperature, collision_frequency, step_size)
barostat = MonteCarloBarostat(pressure, kinetic_temperature, barostat_frequency)
system.addForce(barostat)

#platform = mm.Platform.getPlatformByName('Reference')
#properties = {'None'}
platform = Platform.getPlatformByName('CUDA')
properties = {'CudaPrecision': 'mixed','DeterministicForces': 'true'}

simulation = Simulation(pdb.topology, system, integrator, platform, properties)
simulation.context.setPositions(pdb.positions)
simulation.context.setVelocitiesToTemperature(kinetic_temperature)
simulation.minimizeEnergy()
#print(simulation.context.getSystem)
#print(pdb.positions)
netcdf_reporter = NetCDFReporter('traj_cychex_neat/Lang_2_baro10step_pme1e-5/'+name+'_'+smirkseries1+'_'+eps+epsval1+'_'+rmin+rminval1+'_'+smirkseries2+'_'+eps+epsval2+'_'+rmin+rminval2+'_wNoConstraints_1fsts.nc', traj_freq)
Exemplo n.º 14
0
    def create_system(args, splitting):
        """
        Create a test system that's able to run saltswap.

        Parameters
        ----------
        args:
        splitting:
        """
        # Fixed simulation parameters
        temperature = 300.0 * unit.kelvin
        collision_rate = 1.0 / unit.picoseconds
        pressure = 1.0 * unit.atmospheres
        salt_concentration = args.conc * unit.molar

        # Get the test system and add the barostat.
        testobj = getattr(testsystems, args.testsystem)
        testsys = testobj(nonbondedMethod=app.PME,
                          cutoff=10 * unit.angstrom,
                          ewaldErrorTolerance=1E-4,
                          switch_width=1.5 * unit.angstrom)
        testsys.system.addForce(
            openmm.MonteCarloBarostat(pressure, temperature))

        # Create the compound integrator
        langevin = integrators.LangevinIntegrator(
            splitting=splitting,
            temperature=temperature,
            timestep=timestep,
            collision_rate=collision_rate,
            measure_shadow_work=False,
            measure_heat=False)
        ncmc_langevin = integrators.ExternalPerturbationLangevinIntegrator(
            splitting=splitting,
            temperature=temperature,
            timestep=timestep,
            collision_rate=collision_rate,
            measure_shadow_work=False,
            measure_heat=False)
        integrator = openmm.CompoundIntegrator()
        integrator.addIntegrator(langevin)
        integrator.addIntegrator(ncmc_langevin)

        # Create context
        if args.platform == 'CUDA':
            platform = openmm.Platform.getPlatformByName('CUDA')
            platform.setPropertyDefaultValue('DeterministicForces', 'true')
            properties = {'CudaPrecision': 'mixed'}
            context = openmm.Context(testsys.system, integrator, platform,
                                     properties)
        elif args.platform == 'OpenCL':
            platform = openmm.Platform.getPlatformByName('OpenCL')
            properties = {'OpenCLPrecision': 'mixed'}
            context = openmm.Context(testsys.system, integrator, platform,
                                     properties)
        elif args.platform == 'CPU':
            platform = openmm.Platform.getPlatformByName('CPU')
            context = openmm.Context(testsys.system, integrator, platform)
        else:
            raise Exception('Platform name {0} not recognized.'.format(
                args.platform))

        context.setPositions(testsys.positions)
        context.setVelocitiesToTemperature(temperature)

        # Create the swapper object for the insertion and deletion of salt
        salinator = wrappers.Salinator(context=context,
                                       system=testsys.system,
                                       topology=testsys.topology,
                                       ncmc_integrator=ncmc_langevin,
                                       salt_concentration=salt_concentration,
                                       pressure=pressure,
                                       temperature=temperature,
                                       npert=npert,
                                       water_name=args.water_name)

        # Neutralize the system and initialize the number of salt pairs.
        salinator.neutralize()
        salinator.initialize_concentration()

        return salinator, langevin, integrator
    epsval2 = sys.argv[8]
    rminval2 = sys.argv[9]

    param1 = forcefield.getParameter(smirks=smirkseries1)
    param1[eps] = epsval1
    param1[rmin] = rminval1
    forcefield.setParameter(param1, smirks=smirkseries1)

    param2 = forcefield.getParameter(smirks=smirkseries2)
    param2[eps] = epsval2
    param2[rmin] = rminval2
    forcefield.setParameter(param2, smirks=smirkseries2)

    #Do simulation
    integrator = ommtoolsints.LangevinIntegrator(temperature * kelvin,
                                                 friction / picoseconds,
                                                 time_step * femtoseconds)
    platform = mm.Platform.getPlatformByName('CUDA')
    properties = {'CudaPrecision': 'mixed', 'DeterministicForces': 'true'}
    simulation = app.Simulation(topology, system, integrator, platform,
                                properties)
    simulation.context.setPositions(positions)
    simulation.context.setVelocitiesToTemperature(temperature * kelvin)
    netcdf_reporter = NetCDFReporter(
        'traj_cychex_neat/Lang_2_baro10step_pme1e-5/' + molname[ind] + '_' +
        smirkseries1 + '_' + eps + epsval1 + '_' + rmin + rminval1 + '_' +
        smirkseries2 + '_' + eps + epsval2 + '_' + rmin + rminval2 +
        '_wNoConstraints_vacuum_0.8fsts.nc', trj_freq)
    simulation.reporters.append(netcdf_reporter)
    simulation.reporters.append(
        app.StateDataReporter(sys.stdout,