Пример #1
0
def simulate_implicit(model_directory, variants=None, gpuid=0, rank=0):
    print "-------------------------------------------------------------------------"
    print "gpuid %d rank %d directory %s" % (gpuid, rank, model_directory)
    print "-------------------------------------------------------------------------"

    # Choose platform.
    platform = mm.Platform.getPlatformByName(platform_name)

    # Set GPU id.
    platform.setPropertyDefaultValue('CudaDeviceIndex', '%d' % gpuid)
    platform.setPropertyDefaultValue('OpenCLDeviceIndex', '%d' % gpuid)

    # Only simulate models that are unique following filtering by clustering.
    unique_by_clustering = os.path.exists(
        os.path.join(model_directory, 'unique_by_clustering'))
    if not unique_by_clustering: return

    os.chdir(model_directory)

    # Check to make sure the initial model file is present.
    model_filename = os.path.join(model_directory, 'model.pdb')
    if not os.path.exists(model_filename): return

    # Pass if this simulation has already been run.
    pdb_filename = os.path.join(model_directory, 'implicit-refined.pdb')
    if os.path.exists(pdb_filename): return

    if verbose: print "Reading model..."
    pdb = app.PDBFile(model_filename)

    # Add missing protons.
    modeller = app.Modeller(pdb.topology, pdb.positions)
    modeller.addHydrogens(forcefield, pH=pH, variants=variants)
    topology = modeller.getTopology()
    positions = modeller.getPositions()

    if verbose: print "Constructing System object..."
    if cutoff is None:
        system = forcefield.createSystem(topology,
                                         nonbondedMethod=app.NoCutoff,
                                         constraints=app.HBonds)
    else:
        system = forcefield.createSystem(topology,
                                         nonbondedMethod=app.CutoffNonPeriodic,
                                         nonbondedCutoff=cutoff,
                                         constraints=app.HBonds)

    if verbose: print "Creating Context..."
    integrator = mm.LangevinIntegrator(temperature, collision_rate, timestep)
    context = mm.Context(system, integrator, platform)
    context.setPositions(positions)

    if verbose: print "Minimizing structure..."
    mm.LocalEnergyMinimizer.minimize(context, minimization_tolerance,
                                     minimization_steps)

    if write_trajectory:
        # Open trajectory for writing.
        if verbose: print "Opening trajectory for writing..."
        trajectory_filename = os.path.join(model_directory,
                                           'implicit-trajectory.pdb')
        trajectory_outfile = open(trajectory_filename, 'w')
        app.PDBFile.writeHeader(topology, file=trajectory_outfile)

    # Open energy trajectory for writing
    energy_filename = os.path.join(model_directory, 'implicit-energies.txt')
    energy_outfile = open(energy_filename, 'w')
    energy_outfile.write(
        '# iteration | simulation time (ps) | potential_energy (kT) | kinetic_energy (kT) | ns per day\n'
    )

    if verbose: print "Running dynamics..."
    import time
    initial_time = time.time()
    for iteration in range(niterations):
        # integrate dynamics
        integrator.step(nsteps_per_iteration)
        # get current state
        state = context.getState(getEnergy=True, getPositions=True)
        simulation_time = state.getTime()
        potential_energy = state.getPotentialEnergy()
        kinetic_energy = state.getKineticEnergy()
        final_time = time.time()
        elapsed_time = (final_time - initial_time) * units.seconds
        ns_per_day = (simulation_time / elapsed_time) / (units.nanoseconds /
                                                         units.day)
        if verbose:
            print "  %8.1f ps : potential %8.3f kT | kinetic %8.3f kT | %.3f ns/day | %.3f s remain" % (
                simulation_time / units.picoseconds, potential_energy / kT,
                kinetic_energy / kT, ns_per_day, elapsed_time *
                (niterations - iteration - 1) /
                (iteration + 1) / units.seconds)

        # Check energies are still finite.
        import numpy
        if numpy.isnan(potential_energy / kT) or numpy.isnan(
                kinetic_energy / kT):
            raise Exception("Potential or kinetic energies are nan.")

        if write_trajectory:
            app.PDBFile.writeModel(topology,
                                   state.getPositions(),
                                   file=trajectory_outfile,
                                   modelIndex=iteration)

        # write data
        energy_outfile.write(
            "  %8d %8.1f %8.3f %8.3f %.3f\n" %
            (iteration, simulation_time / units.picoseconds,
             potential_energy / kT, kinetic_energy / kT, ns_per_day))
        energy_outfile.flush()

    if write_trajectory:
        app.PDBFile.writeFooter(topology, file=trajectory_outfile)
        trajectory_outfile.close()

    energy_outfile.close()

    # Write final PDB file.
    pdb_outfile = open(pdb_filename, 'w')
    app.PDBFile.writeHeader(topology, file=pdb_outfile)
    app.PDBFile.writeFile(topology, state.getPositions(), file=pdb_outfile)
    app.PDBFile.writeFooter(topology, file=pdb_outfile)
    pdb_outfile.close()

    os.chdir(original_directory)
Пример #2
0
def test_install():
    eps = np.finfo(float).eps

    print()
    print("openmm version:", mm.Platform.getOpenMMVersion())
    print('openmm git revision:', mm.version.git_revision)
    print("Meld Version:", meld.__version__)
    print("meldplugin version:", meldplugin.__version__)
    print()

    system, coords = create_test_system_and_coords()

    n_platform = mm.Platform.getNumPlatforms()
    print("There are", n_platform, "platforms available:")
    print()

    forces = [None] * n_platform
    energies = [None] * n_platform
    platform_errors = dict()

    for i in range(n_platform):
        platform = mm.Platform.getPlatform(i)
        print(i+1, platform.getName(), end=" ")
        integrator = mm.LangevinIntegrator(300., 1.0, 0.002)

        try:
            context = mm.Context(system, integrator, platform)
            context.setPositions(coords)
            state = context.getState(getForces=True, getEnergy=True)
            forces[i] = state.getForces(asNumpy=True).value_in_unit(u.kilojoule_per_mole / u.nanometer)
            energies[i] = state.getPotentialEnergy().value_in_unit(u.kilojoule_per_mole)
            print("- successfully computed forces.")
        except:
            print("- failed.")
            platform_errors[platform.getName()] = sys.exc_info()[1]

    for platform, error in platform_errors.items():
        print()
        print(platform, "platform error:", error)

    if n_platform > 1:
        print()
        print("Median differences between platforms:")
        print()
        for i in range(n_platform):
            if forces[i] is None:
                continue
            for j in range(i+1, n_platform):
                if forces[j] is None:
                    continue

                forces_close = np.allclose(forces[i], forces[j], atol=1e-4, rtol=1e-4)
                median_force_error = np.median(np.abs(forces[i] - forces[j]))
                max_force_error = np.max(np.abs(forces[i] - forces[j]))

                energies_close = np.allclose(energies[i], energies[j])
                energy_error = np.abs(energies[i] - energies[j])

                name_i = mm.Platform.getPlatform(i).getName()
                name_j = mm.Platform.getPlatform(j).getName()

                if not forces_close or not energies_close:
                    msg = "** LARGE DIFFERENCE **"
                else:
                    msg = "** OK **"

                print(f"{name_i} vs {name_j}")
                print(f"\tenergy diff: {energy_error:g}")
                print(f"\tenegy good: {energies_close}")
                print(f"\tmedian force diff: {median_force_error:g}")
                print(f"\tmax force diff: {max_force_error:g}")
                print(f"\tforce good: {forces_close}")
                print(f"\t{msg}")
                print()
Пример #3
0
def overlap_check():
    """
    BUGS TO REPORT:
    * Even if epsilon = 0, energy of two overlapping atoms is 'nan'.
    * Periodicity in 'nan' if dr = 0.1 even in nonperiodic system
    """

    # Create a reference system.

    logger.info("Creating Lennard-Jones cluster system...")
    #[reference_system, positions] = testsystems.LennardJonesFluid()
    #receptor_atoms = [0]
    #ligand_atoms = [1]

    system_container = testsystems.LysozymeImplicit()
    (reference_system,
     positions) = system_container.system, system_container.positions
    receptor_atoms = range(0, 2603)  # T4 lysozyme L99A
    ligand_atoms = range(2603, 2621)  # p-xylene

    unit = positions.unit
    positions = units.Quantity(np.array(positions / unit), unit)

    factory = AbsoluteAlchemicalFactory(reference_system,
                                        ligand_atoms=ligand_atoms)
    alchemical_state = AlchemicalState(0.00, 0.00, 0.00, 1.0)

    # Create the perturbed system.
    logger.info("Creating alchemically-modified state...")
    alchemical_system = factory.createPerturbedSystem(alchemical_state)
    # Compare energies.
    timestep = 1.0 * units.femtosecond
    logger.info("Computing reference energies...")
    integrator = openmm.VerletIntegrator(timestep)
    context = openmm.Context(reference_system, integrator)
    context.setPositions(positions)
    state = context.getState(getEnergy=True)
    reference_potential = state.getPotentialEnergy()
    del state, context, integrator
    logger.info(reference_potential)
    logger.info("Computing alchemical energies...")
    integrator = openmm.VerletIntegrator(timestep)
    context = openmm.Context(alchemical_system, integrator)
    dr = 0.1 * units.angstroms  # TODO: Why does 0.1 cause periodic 'nan's?
    a = receptor_atoms[-1]
    b = ligand_atoms[-1]
    delta = positions[a, :] - positions[b, :]
    for k in range(3):
        positions[ligand_atoms, k] += delta[k]
    for i in range(30):
        r = dr * i
        positions[ligand_atoms, 0] += dr

        context.setPositions(positions)
        state = context.getState(getEnergy=True)
        alchemical_potential = state.getPotentialEnergy()
        logger.info("%8.3f A : %f " %
                    (r / units.angstroms,
                     alchemical_potential / units.kilocalories_per_mole))
    del state, context, integrator

    return
Пример #4
0
def relax_structure(temperature,
                    system,
                    positions,
                    nequil=1000,
                    n_steps_per_iteration=250,
                    platform_name='OpenCL',
                    timestep=2. * unit.femtosecond,
                    collision_rate=90. / unit.picosecond):
    """
    arguments
        temperature : simtk.unit.Quantity with units compatible with kelvin
            temperature of simulation
        system : openmm.System
            system object for simulation
        positions : simtk.unit.Quantity of shape (natoms,3) with units compatible with nanometers
            Positions of the atoms in the system
        nequil : int, default = 1000
            number of equilibration applications
        n_steps_per_iteration : int, default = 250
            numper of steps per nequil
        platform name : str default='OpenCL'
            platform to run openmm on. OpenCL is best as this is what is used on FAH
        timestep : simtk.unit.Quantity, default = 2*unit.femtosecond
            timestep for equilibration NOT for production
        collision_rate : simtk.unit.Quantity, default=90./unit.picosecond

    return
        state : openmm.State
            state of simulation (getEnergy=True, getForces=True, getPositions=True, getVelocities=True, getParameters=True)
    """

    from openmmtools.integrators import LangevinIntegrator
    _logger.info(f'Starting to relax')
    integrator = LangevinIntegrator(temperature=temperature,
                                    timestep=timestep,
                                    collision_rate=collision_rate)
    platform = openmm.Platform.getPlatformByName(platform_name)

    # prepare the plaform
    if platform_name in ['CUDA', 'OpenCL']:
        platform.setPropertyDefaultValue('Precision', 'mixed')
    if platform_name in ['CUDA']:
        platform.setPropertyDefaultValue('DeterministicForces', 'true')
    context = openmm.Context(system, integrator, platform)
    context.setPeriodicBoxVectors(*system.getDefaultPeriodicBoxVectors())
    context.setPositions(positions)

    _logger.info(f'Starting to minimise')
    openmm.LocalEnergyMinimizer.minimize(context)

    # Equilibrate
    _logger.info(f'set velocities to temperature')
    context.setVelocitiesToTemperature(temperature)
    _logger.info(
        f'Starting to equilibrate for {nequil*n_steps_per_iteration*timestep}')
    integrator.step(nequil * n_steps_per_iteration)
    context.setVelocitiesToTemperature(temperature)
    state = context.getState(getEnergy=True,
                             getForces=True,
                             getPositions=True,
                             getVelocities=True,
                             getParameters=True)
    _logger.info(f'Relax done')

    del context, integrator
    return state
Пример #5
0
def run_alchemical_langevin_integrator(nsteps=0,
                                       splitting="O { V R H R V } O"):
    """Check that the AlchemicalLangevinSplittingIntegrator reproduces the analytical free energy difference for a harmonic oscillator deformation, using BAR.
    Up to 6*sigma is tolerated for error.
    The total work (protocol work + shadow work) is used.
    """

    #max deviation from the calculated free energy
    NSIGMA_MAX = 6
    n_iterations = 100  # number of forward and reverse protocols

    # These are the alchemical functions that will be used to control the system
    temperature = 298.0 * unit.kelvin
    sigma = 1.0 * unit.angstrom  # stddev of harmonic oscillator
    kT = kB * temperature  # thermal energy
    beta = 1.0 / kT  # inverse thermal energy
    K = kT / sigma**2  # spring constant corresponding to sigma
    mass = 39.948 * unit.amu
    period = unit.sqrt(mass / K)  # period of harmonic oscillator
    timestep = period / 20.0
    collision_rate = 1.0 / period
    dF_analytical = 1.0
    parameters = dict()
    parameters['testsystems_HarmonicOscillator_x0'] = (0 * sigma, 2 * sigma)
    parameters['testsystems_HarmonicOscillator_U0'] = (0 * kT, 1 * kT)
    forward_functions = {
        name: '(1-lambda)*%f + lambda*%f' %
        (value[0].value_in_unit_system(unit.md_unit_system),
         value[1].value_in_unit_system(unit.md_unit_system))
        for (name, value) in parameters.items()
    }
    reverse_functions = {
        name: '(1-lambda)*%f + lambda*%f' %
        (value[1].value_in_unit_system(unit.md_unit_system),
         value[0].value_in_unit_system(unit.md_unit_system))
        for (name, value) in parameters.items()
    }

    # Create harmonic oscillator testsystem
    testsystem = testsystems.HarmonicOscillator(K=K, mass=mass)
    system = testsystem.system
    positions = testsystem.positions

    # Get equilibrium samples from initial and final states
    burn_in = 5 * 20  # 5 periods
    thinning = 5 * 20  # 5 periods

    # Collect forward and reverse work values
    w_f = np.zeros([n_iterations], np.float64)
    w_r = np.zeros([n_iterations], np.float64)
    platform = openmm.Platform.getPlatformByName("Reference")
    for direction in ['forward', 'reverse']:
        positions = testsystem.positions
        for iteration in range(n_iterations):
            # Generate equilibrium sample
            equilibrium_integrator = GHMCIntegrator(
                temperature=temperature,
                collision_rate=collision_rate,
                timestep=timestep)
            equilibrium_context = openmm.Context(system,
                                                 equilibrium_integrator,
                                                 platform)
            for (name, value) in parameters.items():
                if direction == 'forward':
                    equilibrium_context.setParameter(
                        name,
                        value[0].value_in_unit_system(unit.md_unit_system))
                else:
                    equilibrium_context.setParameter(
                        name,
                        value[1].value_in_unit_system(unit.md_unit_system))
            equilibrium_context.setPositions(positions)
            equilibrium_integrator.step(thinning)
            positions = equilibrium_context.getState(
                getPositions=True).getPositions(asNumpy=True)
            del equilibrium_context, equilibrium_integrator
            # Generate nonequilibrium work sample
            if direction == 'forward':
                alchemical_functions = forward_functions
            else:
                alchemical_functions = reverse_functions
            nonequilibrium_integrator = AlchemicalNonequilibriumLangevinIntegrator(
                temperature=temperature,
                collision_rate=collision_rate,
                timestep=timestep,
                alchemical_functions=alchemical_functions,
                splitting=splitting,
                nsteps_neq=nsteps,
                measure_shadow_work=True)
            nonequilibrium_context = openmm.Context(system,
                                                    nonequilibrium_integrator,
                                                    platform)
            nonequilibrium_context.setPositions(positions)
            if nsteps == 0:
                nonequilibrium_integrator.step(
                    1)  # need to execute at least one step
            else:
                nonequilibrium_integrator.step(nsteps)
            if direction == 'forward':
                w_f[iteration] = nonequilibrium_integrator.get_total_work(
                    dimensionless=True)
            else:
                w_r[iteration] = nonequilibrium_integrator.get_total_work(
                    dimensionless=True)
            del nonequilibrium_context, nonequilibrium_integrator

    dF, ddF = pymbar.BAR(w_f, w_r)
    nsigma = np.abs(dF - dF_analytical) / ddF
    print(
        "analytical DeltaF: {:12.4f}, DeltaF: {:12.4f}, dDeltaF: {:12.4f}, nsigma: {:12.1f}"
        .format(dF_analytical, dF, ddF, nsigma))
    if nsigma > NSIGMA_MAX:
        raise Exception(
            "The free energy difference for the nonequilibrium switching for splitting '%s' and %d steps is not zero within statistical error."
            % (splitting, nsteps))
Пример #6
0
            ncfile.variables['positions'][iteration - 1, :, :],
            units.angstroms)

    # Continue
    print timestep.in_units_of(units.femtosecond)
    print temperature.in_units_of(units.kelvin)
    print collision_rate.in_units_of(units.picosecond**-1)
    ghmc_integrator = GHMCIntegrator(timestep=timestep,
                                     temperature=temperature,
                                     collision_rate=collision_rate)
    ghmc_global_variables = {
        ghmc_integrator.getGlobalVariableName(index): index
        for index in range(ghmc_integrator.getNumGlobalVariables())
    }

    context = openmm.Context(system, ghmc_integrator, platform)
    context.setPositions(coordinates)

    state = context.getState(getPositions=True)

    while (iteration < niterations):

        # DEBUG
        context.setVelocitiesToTemperature(temperature)

        print "iteration %5d / %5d" % (iteration, niterations)
        print 'coordinates: ', coordinates[0, :] / units.angstrom
        initial_time = time.time()

        # Generate a new configuration.
        initial_distance = norm(coordinates[1, :] - coordinates[0, :])
Пример #7
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
Пример #8
0
UNITS = UNIT_NAMES

# orchestration parameters
N_WALKERS = 48

## System and OpenMMRunner

# make the test system from openmmtools
test_sys = LennardJonesPair()

# make the integrator
integrator = omm.LangevinIntegrator(TEMPERATURE, FRICTION_COEFFICIENT,
                                    STEP_SIZE)

# make a context and set the positions
context = omm.Context(test_sys.system, copy(integrator))
context.setPositions(test_sys.positions)

# get the data from this context so we have a state to start the
# simulation with
get_state_kwargs = dict(GET_STATE_KWARG_DEFAULTS)
init_sim_state = context.getState(**get_state_kwargs)
init_state = OpenMMState(init_sim_state)

# initialize the runner
runner = OpenMMRunner(test_sys.system,
                      test_sys.topology,
                      integrator,
                      platform=PLATFORM)

testsystem = testsystems.DHFRExplicit(hydrogenMass=hydrogenMass, cutoff=cutoff)
system, positions = testsystem.system, testsystem.positions

positions = lb_loader.pre_equil(system, positions, temperature)

platform_properties = dict(CudaPrecision="mixed")
steps_per_hmc = 17
timestep = 1.5 * u.femtoseconds
hmc_integrators.guess_force_groups(system, nonbonded=1, fft=1, others=0)
factor = 1
groups = [(0, 2), (1, 1)]

integrator = hmc_integrators.GHMCRESPA(temperature, steps_per_hmc, timestep,
                                       collision_rate, groups)
context = mm.Context(system, integrator, platform, platform_properties)
context.setPositions(positions)
context.setVelocitiesToTemperature(temperature)

integrator.step(1)
integrator.step(n_steps)
integrator.vstep(5)

platform_properties = dict(CudaPrecision="single")
steps_per_hmc = 17
timestep = 1.5 * u.femtoseconds
hmc_integrators.guess_force_groups(system, nonbonded=1, fft=1, others=0)
factor = 1
groups = [(0, 2), (1, 1)]

integrator = hmc_integrators.GHMCRESPA(temperature, steps_per_hmc, timestep,
Пример #10
0
def openmm_energy(prm,
                  structure,
                  coords,
                  box=None,
                  cutoff=None,
                  switch_dist=None):
    import parmed
    from simtk import unit
    from simtk import openmm
    from simtk.openmm import app
    from parmed.amber import AmberParm

    if box is not None and not np.all(box == 0):
        if cutoff is None:
            raise RuntimeError(
                "You need to provide a cutoff when passing a box")
        a = unit.Quantity(
            (box[0] * unit.angstrom, 0 * unit.angstrom, 0 * unit.angstrom))
        b = unit.Quantity(
            (0 * unit.angstrom, box[1] * unit.angstrom, 0 * unit.angstrom))
        c = unit.Quantity(
            (0 * unit.angstrom, 0 * unit.angstrom, box[2] * unit.angstrom))
        structure.box_vectors = (a, b, c)
        if isinstance(structure, AmberParm):
            system = structure.createSystem(
                nonbondedMethod=app.CutoffPeriodic,
                nonbondedCutoff=0 if cutoff is None else cutoff *
                unit.angstrom,
                switchDistance=0 if switch_dist is None else switch_dist *
                unit.angstrom,
            )
        else:
            system = structure.createSystem(
                prm,
                nonbondedMethod=app.CutoffPeriodic,
                nonbondedCutoff=0 if cutoff is None else cutoff *
                unit.angstrom,
                switchDistance=0 if switch_dist is None else switch_dist *
                unit.angstrom,
            )
        system.setDefaultPeriodicBoxVectors(a, b, c)
    else:
        if isinstance(structure, AmberParm):
            system = structure.createSystem()
        else:
            system = structure.createSystem(prm)

    disableDispersionCorrection(system)
    integrator = openmm.LangevinIntegrator(300 * unit.kelvin,
                                           1 / unit.picoseconds,
                                           2 * unit.femtoseconds)
    platform = openmm.Platform.getPlatformByName("CUDA")
    properties = {"CudaPrecision": "double"}
    context = openmm.Context(system, integrator, platform, properties)

    # Run OpenMM with given coordinates
    context.setPositions(coords * unit.angstrom)
    energies = parmed.openmm.energy_decomposition(structure, context)
    state = context.getState(getForces=True)
    forces = state.getForces(asNumpy=True).value_in_unit(
        unit.kilocalories_per_mole / unit.angstrom)
    if "angle" not in energies:
        energies["angle"] = 0
    if "dihedral" not in energies:
        energies["dihedral"] = 0
    if "improper" not in energies:
        energies["improper"] = 0

    return energies, forces
Пример #11
0
            e_l, e_k,
            a_l, a_k,
            tf.constant([0.0], dtype=tf.float32),
            tf.constant([0.0], dtype=tf.float32),
            bond_idxs, angle_idxs, tf.constant([[0, 0, 0, 0]], dtype=tf.int64),
            xyz)

    
    jacobian_hat = tape.gradient(u, xyz)
    '''

    for idx in range(sys.getNumForces()):
        force = sys.getForce(idx)
        force.setForceGroup(idx)

    context = openmm.Context(sys, openmm.VerletIntegrator(0.001))

    context.setPositions(xyz * 1.0)

    force = sys.getForce(2)
    force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff)
    force.updateParametersInContext(context)
    # print(context.getState(getEnergy=True, groups=1<<2).getPotentialEnergy())

    traj = tf.concat([
        traj,
        tf.concat([
            context.getState(getVelocities=True, getForces=True).getForces(
                asNumpy=True)._value, jacobian
        ],
                  axis=1)
Пример #12
0
def compare_energies(mol_name="naphthalene", ref_mol_name="benzene"):
    """
    Make an atom map where the molecule at either lambda endpoint is identical, and check that the energies are also the same.
    """
    from perses.rjmc.topology_proposal import SmallMoleculeSetProposalEngine, TopologyProposal
    from perses.annihilation.new_relative import HybridTopologyFactory
    import simtk.openmm as openmm

    from perses.tests.utils import createOEMolFromIUPAC, createSystemFromIUPAC

    mol_name = "naphthalene"
    ref_mol_name = "benzene"

    mol = createOEMolFromIUPAC(mol_name)
    m, system, positions, topology = createSystemFromIUPAC(mol_name)

    refmol = createOEMolFromIUPAC(ref_mol_name)

    #map one of the rings
    atom_map = SmallMoleculeSetProposalEngine._get_mol_atom_map(mol, refmol)

    #now use the mapped atoms to generate a new and old system with identical atoms mapped. This will result in the
    #same molecule with the same positions for lambda=0 and 1, and ensures a contiguous atom map
    effective_atom_map = {value: value for value in atom_map.values()}

    #make a topology proposal with the appropriate data:
    top_proposal = TopologyProposal(new_topology=topology,
                                    new_system=system,
                                    old_topology=topology,
                                    old_system=system,
                                    new_to_old_atom_map=effective_atom_map,
                                    new_chemical_state_key="n1",
                                    old_chemical_state_key='n2')

    factory = HybridTopologyFactory(top_proposal, positions, positions)

    alchemical_system = factory.hybrid_system
    alchemical_positions = factory.hybrid_positions

    integrator = openmm.VerletIntegrator(1)
    platform = openmm.Platform.getPlatformByName("Reference")
    context = openmm.Context(alchemical_system, integrator, platform)

    context.setPositions(alchemical_positions)

    functions = {
        'lambda_sterics':
        '2*lambda * step(0.5 - lambda) + (1.0 - step(0.5 - lambda))',
        'lambda_electrostatics': '2*(lambda - 0.5) * step(lambda - 0.5)',
        'lambda_bonds': 'lambda',
        'lambda_angles': 'lambda',
        'lambda_torsions': 'lambda'
    }

    #set all to zero
    for parm in functions.keys():
        context.setParameter(parm, 0.0)

    initial_energy = context.getState(getEnergy=True).getPotentialEnergy()

    #set all to one
    for parm in functions.keys():
        context.setParameter(parm, 1.0)

    final_energy = context.getState(getEnergy=True).getPotentialEnergy()

    if np.abs(final_energy -
              initial_energy) > 1.0e-6 * unit.kilojoule_per_mole:
        raise Exception(
            "The energy at the endpoints was not equal for molecule %s" %
            mol_name)
Пример #13
0
def runOneTest(testName, options):
    """Perform a single benchmarking simulation."""
    explicit = (testName in ('rf', 'pme', 'amoebapme'))
    amoeba = (testName in ('amoebagk', 'amoebapme'))
    hydrogenMass = None
    print()
    if amoeba:
        print('Test: %s (epsilon=%g)' % (testName, options.epsilon))
    elif testName == 'pme':
        print('Test: pme (cutoff=%g)' % options.cutoff)
    else:
        print('Test: %s' % testName)
    platform = mm.Platform.getPlatformByName(options.platform)
    
    # Create the System.
    
    if amoeba:
        constraints = None
        epsilon = float(options.epsilon)
        if epsilon == 0:
            polarization = 'direct'
        else:
            polarization = 'mutual'
        if explicit:
            ff = app.ForceField('amoeba2009.xml')
            pdb = app.PDBFile('5dfr_solv-cube_equil.pdb')
            cutoff = 0.7*unit.nanometers
            vdwCutoff = 0.9*unit.nanometers
            system = ff.createSystem(pdb.topology, nonbondedMethod=app.PME, nonbondedCutoff=cutoff, vdwCutoff=vdwCutoff, constraints=constraints, ewaldErrorTolerance=0.00075, mutualInducedTargetEpsilon=epsilon, polarization=polarization)
        else:
            ff = app.ForceField('amoeba2009.xml', 'amoeba2009_gk.xml')
            pdb = app.PDBFile('5dfr_minimized.pdb')
            cutoff = 2.0*unit.nanometers
            vdwCutoff = 1.2*unit.nanometers
            system = ff.createSystem(pdb.topology, nonbondedMethod=app.NoCutoff, constraints=constraints, mutualInducedTargetEpsilon=epsilon, polarization=polarization)
        dt = 0.001*unit.picoseconds
    else:
        if explicit:
            ff = app.ForceField('amber99sb.xml', 'tip3p.xml')
            pdb = app.PDBFile('5dfr_solv-cube_equil.pdb')
            if testName == 'pme':
                method = app.PME
                cutoff = options.cutoff
            else:
                method = app.CutoffPeriodic
                cutoff = 1*unit.nanometers
        else:
            ff = app.ForceField('amber99sb.xml', 'amber99_obc.xml')
            pdb = app.PDBFile('5dfr_minimized.pdb')
            method = app.CutoffNonPeriodic
            cutoff = 2*unit.nanometers
        if options.heavy:
            dt = 0.005*unit.picoseconds
            constraints = app.AllBonds
            hydrogenMass = 4*unit.amu
        else:
            dt = 0.002*unit.picoseconds
            constraints = app.HBonds
            hydrogenMass = None
        system = ff.createSystem(pdb.topology, nonbondedMethod=method, nonbondedCutoff=cutoff, constraints=constraints, hydrogenMass=hydrogenMass)
    print('Step Size: %g fs' % dt.value_in_unit(unit.femtoseconds))
    properties = {}
    if options.device is not None:
        if platform.getName() == 'CUDA':
            properties['CudaDeviceIndex'] = options.device
        elif platform.getName() == 'OpenCL':
            properties['OpenCLDeviceIndex'] = options.device
    if options.precision is not None:
        if platform.getName() == 'CUDA':
            properties['CudaPrecision'] = options.precision
        elif platform.getName() == 'OpenCL':
            properties['OpenCLPrecision'] = options.device
    
    # Run the simulation.
    
    integ = mm.LangevinIntegrator(300*unit.kelvin, 91*(1/unit.picoseconds), dt)
    integ.setConstraintTolerance(1e-5)
    if len(properties) > 0:
        context = mm.Context(system, integ, platform, properties)
    else:
        context = mm.Context(system, integ, platform)
    context.setPositions(pdb.positions)
    context.setVelocitiesToTemperature(300*unit.kelvin)
    steps = 20
    while True:
        time = timeIntegration(context, steps)
        if time >= 0.5*options.seconds:
            break
        if time < 0.5:
            steps = int(steps*1.0/time) # Integrate enough steps to get a reasonable estimate for how many we'll need.
        else:
            steps = int(steps*options.seconds/time)
    print('Integrated %d steps in %g seconds' % (steps, time))
    print('%g ns/day' % (dt*steps*86400/time).value_in_unit(unit.nanoseconds))
Пример #14
0
    def __init__(self, modelName='Dimer'):

        self.energy_unit = unit.kilojoule_per_mole

        self.modelName = modelName
        if (self.modelName == 'Dimer'):

            self.testsystem = self.createDimer()
            name = self.testsystem
            self.modelname = str(name)

        elif (self.modelName == 'Lemon'):

            self.testsystem = self.createLemon()
            name = self.testsystem
            self.modelname = str(name)

        elif (self.modelName == 'Thomson'):

            self.testsystem = self.createThomson()
            name = self.testsystem
            self.modelname = str(name)

        elif (self.modelName == 'Alanine'):

            #AlanineDipeptideVacuum

            from openmmtools.testsystems import AlanineDipeptideVacuum  #TolueneVacuum#SrcImplicit#AlanineDipeptideVacuum#LennardJonesCluster#AlanineDipeptideVacuum#HarmonicOscillator#Diatom #AlanineDipeptideVacuum#Diatom

            name = AlanineDipeptideVacuum
            self.modelname = str(name)

            #ala2
            self.testsystem = name(constraints=None)

        elif (self.modelName == 'LJCluster'):
            ## LJ cluster
            from openmmtools.testsystems import LennardJonesCluster
            name = LennardJonesCluster

            self.testsystem = name(nx=2, ny=2, nz=1, constraints=None)
        else:
            print("In class Model(): modelName not found")

        (self.system,
         self.positions) = self.testsystem.system, self.testsystem.positions

        dummy_integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds)

        self.context = openmm.Context(self.system, dummy_integrator)
        self.context.setPositions(self.positions)

        if (self.modelName == 'Alanine'):
            # adjust periodic box
            ## TBD this should be moved inside the integrator class
            maxval = np.max(
                np.abs(
                    np.vstack(self.positions.value_in_unit(
                        self.positions.unit))))
            self.boxsize = 10.0 * maxval
            print('Maximal position value in one direction is ' + repr(maxval))
            print('PBC box size set to ' + repr(self.boxsize))
            self.edge = self.boxsize * self.testsystem.positions.unit
            self.testsystem.system.setDefaultPeriodicBoxVectors(
                [self.edge, 0, 0], [0, self.edge, 0], [0, 0, self.edge])

        # if(relax == 1):
        #     self.context.minimizeEnergy(tolerance=2.0)

        self.x_unit = self.positions.unit
        self.force_unit = unit.kilocalorie_per_mole / self.x_unit
        self.time_unit = unit.femtosecond
        self.velocity_unit = self.x_unit / self.time_unit
        self.mass_unit = unit.amu
        self.temperature_unit = unit.kelvin

        self.kB_const = kB

        self.masses = 1.0 * self.mass_unit

        self.fixOneParticle = 0

        #save Topology
        openmm.app.PDBFile.writeFile(self.testsystem.topology, self.positions,
                                     open(self.modelName + '.pdb', 'w'))
Пример #15
0
    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(wbox.system, integrator, platform, properties)
    elif args.platform == 'OpenCL':
        platform = openmm.Platform.getPlatformByName('OpenCL')
        properties = {'OpenCLPrecision': 'mixed'}
        context = openmm.Context(wbox.system, integrator, platform, properties)
    elif args.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 salinator object for the insertion and deletion of salt
    salinator = wrappers.Salinator(context=context, system=wbox.system, topology=wbox.topology,
Пример #16
0
def setup_fah_run(destination_path,
                  protein_pdb_filename,
                  oemol=None,
                  cache=None,
                  restrain_rmsd=False,
                  biounit='monomer'):
    """
    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
    biounit : str, optional, default='monomer'
        'monomer' or 'dimer'
    """
    # Parameters
    from simtk import unit, openmm
    protein_forcefield = 'amber14/protein.ff14SB.xml'
    solvent_forcefield = 'amber14/tip3p.xml'
    small_molecule_forcefield = 'openff-1.3.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
    nsteps_per_snapshot = 250000  # 1 ns
    nsnapshots_per_wu = 20  # number of snapshots per WU

    # 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
    molecules = []
    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()])
        molecules = [molecule]

    # 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=molecules,
        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])

    # Extract protein and molecule chains and indices before adding solvent
    import mdtraj as md
    mdtop = md.Topology.from_openmm(
        modeller.topology)  # excludes solvent and ions
    protein_atom_indices = mdtop.select('protein and (mass > 1)')
    molecule_atom_indices = mdtop.select(
        '(not protein) and (not water) and (mass > 1)')
    protein_chainids = list(
        set([
            atom.residue.chain.index for atom in mdtop.atoms
            if atom.index in protein_atom_indices
        ]))
    n_protein_chains = len(protein_chainids)
    protein_chain_atom_indices = dict()
    for chainid in protein_chainids:
        protein_chain_atom_indices[chainid] = mdtop.select(
            f'protein and chainid {chainid}')

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

    # Write initial model and select atom subsets and chains
    import bz2
    with bz2.open(os.path.join(destination_path, 'initial-model.pdb.bz2'),
                  'wt') as outfile:
        app.PDBFile.writeFile(modeller.topology,
                              modeller.positions,
                              outfile,
                              keepIds=True)

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

    #
    # Add virtual bonds to ensure protein subunits and ligand are imaged together
    #

    virtual_bond_force = openmm.CustomBondForce('0')
    system.addForce(virtual_bond_force)

    # Add a virtual bond between protein chains
    if (n_protein_chains > 1):
        chainid = protein_chainids[0]
        iatom = protein_chain_atom_indices[chainid][0]
        for chainid in protein_chainids[1:]:
            jatom = protein_chain_atom_indices[chainid][0]
            print(f'Creating virtual bond between atoms {iatom} and {jatom}')
            virtual_bond_force.addBond(int(iatom), int(jatom), [])

    # Add a virtual bond between protein and ligand to make sure they are not imaged separately
    if oemol is not None:
        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])
        print(
            f'Creating virtual bond between atoms {protein_atom_index} and {ligand_atom_index}'
        )
        virtual_bond_force.addBond(int(protein_atom_index),
                                   int(ligand_atom_index), [])

    # Add RMSD restraints if requested
    if restrain_rmsd:
        print('Adding RMSD restraint...')
        kB = unit.AVOGADRO_CONSTANT_NA * unit.BOLTZMANN_CONSTANT_kB
        kT = kB * temperature
        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.bz2'),
                  'wt') as f:
        app.PDBFile.writeFile(modeller.topology,
                              state.getPositions(),
                              f,
                              keepIds=True)
    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,
                              keepIds=True)
    with open(os.path.join(destination_path, 'core.xml'), 'wt') as f:
        f.write(f'<config>\n')
        f.write(
            f'  <numSteps>{nsteps_per_snapshot * nsnapshots_per_wu}</numSteps>\n'
        )
        f.write(f'  <xtcFreq>{nsteps_per_snapshot}</xtcFreq>\n')
        f.write(f'  <precision>mixed</precision>\n')
        f.write(
            f'  <xtcAtoms>{",".join([str(index) for index in selection])}</xtcAtoms>\n'
        )
        f.write(f'</config>\n')
    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
Пример #17
0
def run():
    # Create initial model system, topology, and positions.
    smiles_list = ["CC", "CCC", "CCCC"]

    initial_molecule = smiles_to_oemol("CC")
    molecules = [Molecule.from_openeye(initial_molecule)]

    system_generator = SystemGenerator(molecules=molecules)

    initial_sys, initial_pos, initial_top = OEMol_to_omm_ff(
        initial_molecule, system_generator)

    smiles = "CC"
    stats = {ms: 0 for ms in smiles_list}
    # Run parameters
    temperature = 300.0 * unit.kelvin  # temperature
    pressure = 1.0 * unit.atmospheres  # pressure
    collision_rate = 5.0 / unit.picoseconds  # collision rate for Langevin dynamics

    # Create proposal metadata, such as the list of molecules to sample (SMILES here)
    # proposal_metadata = {"smiles_list": smiles_list}
    list_of_oemols = []
    for smile in smiles_list:
        oemol = smiles_to_oemol(smile)
        list_of_oemols.append(oemol)

    transformation = topology_proposal.SmallMoleculeSetProposalEngine(
        list_of_oemols=list_of_oemols, system_generator=system_generator)
    # transformation = topology_proposal.SingleSmallMolecule(proposal_metadata)

    # Initialize weight calculation engine, along with its metadata
    bias_calculator = bias_engine.MinimizedPotentialBias(smiles_list)

    # Initialize NCMC engines.
    switching_timestep = (1.0 * unit.femtosecond
                          )  # Timestep for NCMC velocity Verlet integrations
    switching_nsteps = 10  # Number of steps to use in NCMC integration
    switching_functions = {  # Functional schedules to use in terms of `lambda`, which is switched from 0->1 for creation and 1->0 for deletion
        "lambda_sterics": "lambda",
        "lambda_electrostatics": "lambda",
        "lambda_bonds": "lambda",
        "lambda_angles": "sqrt(lambda)",
        "lambda_torsions": "lambda",
    }
    ncmc_engine = ncmc_switching.NCMCEngine(
        temperature=temperature,
        timestep=switching_timestep,
        nsteps=switching_nsteps,
        functions=switching_functions,
    )

    # Initialize GeometryEngine
    geometry_metadata = {"data": 0}  # currently ignored
    geometry_engine = geometry.FFAllAngleGeometryEngine(geometry_metadata)

    # Run a number of iterations.
    niterations = 50
    system = initial_sys
    topology = initial_top
    positions = initial_pos
    current_log_weight = bias_calculator.g_k(smiles)
    n_accepted = 0
    propagate = True
    for i in range(niterations):
        # Store old (system, topology, positions).

        # Propose a transformation from one chemical species to another.
        state_metadata = {"molecule_smiles": smiles}
        top_proposal = transformation.propose(
            system, topology, positions, state_metadata)  # Get a new molecule

        # QUESTION: What about instead initializing StateWeight once, and then using
        # log_state_weight = state_weight.computeLogStateWeight(new_topology, new_system, new_metadata)?
        log_weight = bias_calculator.g_k(
            top_proposal.metadata["molecule_smiles"])

        # Perform alchemical transformation.

        # Alchemically eliminate atoms being removed.

        [ncmc_old_positions,
         ncmc_elimination_logp] = ncmc_engine.integrate(top_proposal,
                                                        positions,
                                                        direction="delete")

        # Generate coordinates for new atoms and compute probability ratio of old and new probabilities.
        # QUESTION: Again, maybe we want to have the geometry engine initialized once only?
        geometry_proposal = geometry_engine.propose(
            top_proposal.new_to_old_atom_map,
            top_proposal.new_system,
            system,
            ncmc_old_positions,
        )

        # Alchemically introduce new atoms.
        [ncmc_new_positions, ncmc_introduction_logp
         ] = ncmc_engine.integrate(top_proposal,
                                   geometry_proposal.new_positions,
                                   direction="insert")

        # Compute total log acceptance probability, including all components.
        logp_accept = (top_proposal.logp_proposal + geometry_proposal.logp +
                       ncmc_elimination_logp + ncmc_introduction_logp +
                       log_weight / log_weight.unit -
                       current_log_weight / current_log_weight.unit)

        # Accept or reject.
        if ((logp_accept >= 0.0) or
            (np.random.uniform() < np.exp(logp_accept))) and not np.any(
                np.isnan(ncmc_new_positions)):
            # Accept.
            n_accepted += 1
            (system, topology, positions, current_log_weight, smiles) = (
                top_proposal.new_system,
                top_proposal.new_topology,
                ncmc_new_positions,
                log_weight,
                top_proposal.metadata["molecule_smiles"],
            )
        else:
            # Reject.
            logging.debug("reject")
        stats[smiles] += 1
        print(positions)
        if propagate:
            p_system = copy.deepcopy(system)
            integrator = openmm.LangevinIntegrator(temperature, collision_rate,
                                                   switching_timestep)
            context = openmm.Context(p_system, integrator)
            context.setPositions(positions)
            print(context.getState(getEnergy=True).getPotentialEnergy())
            integrator.step(1000)
            state = context.getState(getPositions=True)
            positions = state.getPositions(asNumpy=True)
            del context, integrator, p_system

    print("The total number accepted was %d out of %d iterations" %
          (n_accepted, niterations))
    print(stats)
n_steps = 3000
temperature = 300. * u.kelvin
collision_rate = 1.0 / u.picoseconds
timestep = 2.0 * u.femtoseconds
steps_per_hmc = 12
k_max = 2

testsystem = testsystems.WaterBox(
    box_edge=3.18 * u.nanometers)  # Around 1060 molecules of water
system = testsystem.system
positions = testsystem.positions

integrator = mm.LangevinIntegrator(temperature, 1.0 / u.picoseconds,
                                   0.25 * u.femtoseconds)
context = mm.Context(testsystem.system, integrator)
context.setPositions(testsystem.positions)
context.setVelocitiesToTemperature(temperature)
integrator.step(5000)
positions = context.getState(getPositions=True).getPositions()

integrator = hmc_integrators.GHMC2(temperature, steps_per_hmc, timestep,
                                   collision_rate)
context = mm.Context(system, integrator)
context.setPositions(positions)
context.setVelocitiesToTemperature(temperature)

for i in range(1000):
    data = []
    for j in range(10):
        integrator.step(1)
Пример #19
0
#platform = cpu
#platform = opencl
platform = cuda


n_steps = 5000
temperature = 300. * u.kelvin

#testsystem = testsystems.WaterBox(box_edge=3.18 * u.nanometers)  # Around 1060 molecules of water
testsystem = testsystems.FlexibleWaterBox(box_edge=3.18 * u.nanometers)  # Around 1060 molecules of water
#testsystem = testsystems.AlanineDipeptideExplicit()
system = testsystem.system

integrator = mm.LangevinIntegrator(temperature, 0.25 / u.picoseconds, 0.25 * u.femtoseconds)
#integrator = hmc_integrators.RandomTimestepGHMC(temperature, 12, 0.25 * u.femtoseconds)
context = mm.Context(testsystem.system, integrator, platform)
context.setPositions(testsystem.positions)
context.setVelocitiesToTemperature(temperature)
integrator.step(5000)
positions = context.getState(getPositions=True).getPositions()

def test_hmc(timestep, steps_per_hmc):
    timestep = timestep * u.femtoseconds
    integrator = hmc_integrators.RandomTimestepGHMC(temperature, steps_per_hmc, timestep)
    context = mm.Context(system, integrator, platform)
    context.setPositions(positions)
    context.setVelocitiesToTemperature(temperature)
    integrator.step(n_steps)
    return integrator.acceptance_rate

#timestep_list = np.linspace(1.5, 2.25, 2)
Пример #20
0
    def _computeStandardStateCorrection(self):
        """
        Compute the standard state correction for the arbitrary restraint energy function.
        
        RETURN VALUES

        DeltaG (float) - computed standard-state correction in dimensionless units (kT);

        NOTE

        Equivalent to the free energy of releasing restraints and confining into a box of standard state size.
                
        """

        r_min = 0 * units.nanometers
        r_max = 100 * units.nanometers  # TODO: Use maximum distance between atoms?

        # Create a System object containing two particles connected by the reference force
        system = openmm.System()
        system.addParticle(1.0 * units.amu)
        system.addParticle(1.0 * units.amu)
        force = self._createRestraintForce(0, 1)
        system.addForce(force)

        # Create a Reference context to evaluate energies on the CPU.
        integrator = openmm.VerletIntegrator(1.0 * units.femtoseconds)
        platform = openmm.Platform.getPlatformByName('Reference')
        context = openmm.Context(system, integrator, platform)

        # Set default positions.
        positions = units.Quantity(numpy.zeros([2, 3]), units.nanometers)
        context.setPositions(positions)

        # Create a function to compute integrand as a function of interparticle separation.
        beta = self.beta

        def integrand(r):
            """
            ARGUMENTS
            
            r (float) - interparticle separation in nanometers
            
            RETURNS

            dI (float) - contribution to integrand (in nm^2)
            """
            positions[1, 0] = r * units.nanometers
            context.setPositions(positions)
            state = context.getState(getEnergy=True)
            potential = state.getPotentialEnergy()
            dI = 4.0 * math.pi * r**2 * math.exp(-beta * potential)
            return dI

        (shell_volume, shell_volume_error) = scipy.integrate.quad(
            lambda r: integrand(r), r_min / units.nanometers, r_max /
            units.nanometers) * units.nanometers**3  # integrate shell volume
        logger.debug("shell_volume = %f nm^3" %
                     (shell_volume / units.nanometers**3))

        # Compute standard-state volume for a single molecule in a box of size (1 L) / (avogadros number)
        liter = 1000.0 * units.centimeters**3  # one liter
        box_volume = liter / (units.AVOGADRO_CONSTANT_NA * units.mole
                              )  # standard state volume
        logger.debug("box_volume = %f nm^3" %
                     (box_volume / units.nanometers**3))

        # Compute standard state correction for releasing shell restraints into standard-state box (in units of kT).
        DeltaG = -math.log(box_volume / shell_volume)
        logger.debug("Standard state correction: %.3f kT" % DeltaG)

        # Return standard state correction (in kT).
        return DeltaG
Пример #21
0
# Add a barostat
# print('Adding barostat...')
# barostat = openmm.MonteCarloBarostat(pressure, temperature)
# system.addForce(barostat)

# Serialize integrator
print('Serializing integrator to %s' % integrator_xml_filename)
integrator = openmm.LangevinIntegrator(temperature, collision_rate, timestep)
with open(integrator_xml_filename, 'w') as outfile:
    xml = openmm.XmlSerializer.serialize(integrator)
    outfile.write(xml)
    
# Minimize
print('Minimizing energy...')
context = openmm.Context(system, integrator)
context.setPositions(modeller.positions)
print('  initial : %8.3f kcal/mol' % (context.getState(getEnergy=True).getPotentialEnergy()/unit.kilocalories_per_mole))
openmm.LocalEnergyMinimizer.minimize(context)
print('  final   : %8.3f kcal/mol' % (context.getState(getEnergy=True).getPotentialEnergy()/unit.kilocalories_per_mole))
with open(minimized_pdb_filename, 'w') as outfile:
    app.PDBFile.writeFile(modeller.topology, context.getState(getPositions=True,enforcePeriodicBox=True).getPositions(), file=outfile, keepIds=True)
    
# Equilibrate
print('Equilibrating...')
initial_time = time.time()
for iteration in progressbar.progressbar(range(niterations)):
    integrator.step(nsteps)
elapsed_time = (time.time() - initial_time) * unit.seconds
simulation_time = niterations * nsteps * timestep
print('    Equilibration took %.3f s for %.3f ns (%8.3f ns/day)' % (elapsed_time / unit.seconds, simulation_time / unit.nanoseconds, simulation_time / elapsed_time * unit.day / unit.nanoseconds))
Пример #22
0
    def __init__(self,
                 topology,
                 system,
                 integrator,
                 platform=None,
                 platformProperties=None,
                 state=None):
        """Create a Simulation.

        Parameters
        ----------
        topology : Topology
            A Topology describing the the system to simulate
        system : System or XML file name
            The OpenMM System object to simulate (or the name of an XML file
            with a serialized System)
        integrator : Integrator or XML file name
            The OpenMM Integrator to use for simulating the System (or the name
            of an XML file with a serialized System)
        platform : Platform=None
            If not None, the OpenMM Platform to use
        platformProperties : map=None
            If not None, a set of platform-specific properties to pass to the
            Context's constructor
        state : XML file name=None
            The name of an XML file containing a serialized State. If not None,
            the information stored in state will be transferred to the generated
            Simulation object.
        """
        self.topology = topology
        ## The System being simulated
        if isinstance(system, string_types):
            with open(system, 'r') as f:
                self.system = mm.XmlSerializer.deserialize(f.read())
        else:
            self.system = system
        ## The Integrator used to advance the simulation
        if isinstance(integrator, string_types):
            with open(integrator, 'r') as f:
                self.integrator = mm.XmlSerializer.deserialize(f.read())
        else:
            self.integrator = integrator
        ## The index of the current time step
        self.currentStep = 0
        ## A list of reporters to invoke during the simulation
        self.reporters = []
        if platform is None:
            ## The Context containing the current state of the simulation
            self.context = mm.Context(self.system, self.integrator)
        elif platformProperties is None:
            self.context = mm.Context(self.system, self.integrator, platform)
        else:
            self.context = mm.Context(self.system, self.integrator, platform,
                                      platformProperties)
        if state is not None:
            with open(state, 'r') as f:
                self.context.setState(mm.XmlSerializer.deserialize(f.read()))
        ## Determines whether or not we are using PBC. Try from the System first,
        ## fall back to Topology if that doesn't work
        try:
            self._usesPBC = self.system.usesPeriodicBoundaryConditions()
        except Exception:  # OpenMM just raises Exception if it's not implemented everywhere
            self._usesPBC = topology.getUnitCellDimensions() is not None
Пример #23
0
    def test_ncmc_update_parameters_in_context(self):
        """
        Testing that the protocol work is correctly calculated in cases when the parameters are updated using
        context.updateParametersInContext() and the integrator is a compound integrator. The NCMC scheme tested below
        is based on the one used by the saltswap and protons code-bases.
        """
        from simtk.openmm import app
        from openmmtools.constants import kB

        size = 20.0
        temperature = 298.0 * unit.kelvin
        kT = kB * temperature
        nonbonded_method = 'CutoffPeriodic'
        platform_name = 'CPU'
        timestep = 1. * unit.femtoseconds
        collision_rate = 90. / unit.picoseconds

        wbox = testsystems.WaterBox(box_edge=size * unit.angstrom,
                                    cutoff=9. * unit.angstrom,
                                    nonbondedMethod=getattr(
                                        app, nonbonded_method))

        integrator = integrators.ExternalPerturbationLangevinIntegrator(
            splitting="V R O R V",
            temperature=temperature,
            timestep=timestep,
            collision_rate=collision_rate)

        # Create context
        platform = openmm.Platform.getPlatformByName(platform_name)
        context = openmm.Context(wbox.system, integrator, platform)
        context.setPositions(wbox.positions)
        context.setPositions(wbox.positions)
        context.setVelocitiesToTemperature(temperature)

        def switchoff(force, context, frac=0.9):
            force.setParticleParameters(0,
                                        charge=-0.834 * frac,
                                        sigma=0.3150752406575124 * frac,
                                        epsilon=0.635968 * frac)
            force.setParticleParameters(1,
                                        charge=0.417 * frac,
                                        sigma=0,
                                        epsilon=1 * frac)
            force.setParticleParameters(2,
                                        charge=0.417 * frac,
                                        sigma=0,
                                        epsilon=1 * frac)
            force.updateParametersInContext(context)

        def switchon(force, context):
            force.setParticleParameters(0,
                                        charge=-0.834,
                                        sigma=0.3150752406575124,
                                        epsilon=0.635968)
            force.setParticleParameters(1, charge=0.417, sigma=0, epsilon=1)
            force.setParticleParameters(2, charge=0.417, sigma=0, epsilon=1)
            force.updateParametersInContext(context)

        force = wbox.system.getForce(2)  # Non-bonded force.

        # Number of NCMC steps
        nsteps = 20
        niterations = 3

        for i in range(niterations):
            external_protocol_work = 0.0
            integrator.reset_protocol_work()
            integrator.step(1)
            for step in range(nsteps):
                fraction = float(step + 1) / float(nsteps)
                initial_energy = context.getState(
                    getEnergy=True).getPotentialEnergy()
                switchoff(force, context, frac=fraction)
                final_energy = context.getState(
                    getEnergy=True).getPotentialEnergy()
                external_protocol_work += (final_energy - initial_energy) / kT
                integrator.step(1)
            integrator_protocol_work = integrator.get_protocol_work(
                dimensionless=True)
            assert abs(external_protocol_work -
                       integrator_protocol_work) < 1.E-5
            # Return to unperturbed state
            switchon(force, context)
Пример #24
0
    def createContext(self, integrator=None, platform=None):
        """
        Create an OpenMM Context object from the current sampler state.

        Parameters
        ----------
        integrator : simtk.openmm.Integrator, optional, default=None
           The integrator to use for Context creation.
           If not specified, a VerletIntegrator with 1 fs timestep is created.
        platform : simtk.openmm.Platform, optional, default=None
           If specified, the Platform to use for context creation.

        Returns
        -------
        context : simtk.openmm.Context
           The created OpenMM Context object

        Notes
        -----
        If the selected or default platform fails, the CPU and Reference platforms will be tried, in that order.        

        Examples
        --------

        Create a context for a system with periodic box vectors.
        
        >>> # Create a test system
        >>> from openmmtools import testsystems
        >>> test = testsystems.LennardJonesFluid()
        >>> # Create a sampler state manually.
        >>> box_vectors = test.system.getDefaultPeriodicBoxVectors()
        >>> sampler_state = SamplerState(positions=test.positions, box_vectors=box_vectors, system=test.system)
        >>> # Create a Context.
        >>> import simtk.openmm as mm
        >>> import simtk.unit as u
        >>> integrator = mm.VerletIntegrator(1.0*u.femtoseconds)
        >>> context = sampler_state.createContext(integrator)
        >>> # Clean up.
        >>> del context

        Create a context for a system without periodic box vectors.

        >>> # Create a test system
        >>> from openmmtools import testsystems
        >>> test = testsystems.LennardJonesCluster()
        >>> # Create a sampler state manually.
        >>> sampler_state = SamplerState(positions=test.positions, system=test.system)
        >>> # Create a Context.
        >>> import simtk.openmm as mm
        >>> import simtk.unit as u
        >>> integrator = mm.VerletIntegrator(1.0*u.femtoseconds)
        >>> context = sampler_state.createContext(integrator)
        >>> # Clean up.
        >>> del context

        TODO
        ----
        * Generalize fallback platform order to [CUDA, OpenCL, CPU, Reference] ordering.

        """

        if not self.system:
            raise Exception(
                "SamplerState must have a 'system' object specified to create a Context"
            )

        # Use a Verlet integrator if none is specified.
        if integrator is None:
            integrator = mm.VerletIntegrator(1.0 * u.femtoseconds)

        # Create a Context.
        if platform:
            context = mm.Context(self.system, integrator, platform)
        else:
            context = mm.Context(self.system, integrator)

        # Set box vectors, if specified.
        if (self.box_vectors is not None):
            try:
                # try tuple of box vectors
                context.setPeriodicBoxVectors(self.box_vectors[0],
                                              self.box_vectors[1],
                                              self.box_vectors[2])
            except:
                # try numpy 3x3 matrix of box vectors
                context.setPeriodicBoxVectors(self.box_vectors[0, :],
                                              self.box_vectors[1, :],
                                              self.box_vectors[2, :])

        # Set positions.
        context.setPositions(self.positions)

        # Set velocities, if specified.
        if (self.velocities is not None):
            context.setVelocities(self.velocities)

        return context
Пример #25
0
import simtk.openmm as mm
from simtk import unit as u
from openmmtools import hmc_integrators, testsystems
pd.set_option('display.width', 1000)

collision_rate = 10000.0 / u.picoseconds
temperature = 25. * u.kelvin

testsystem = testsystems.LennardJonesFluid()

system, positions = testsystem.system, testsystem.positions
system.addForce(mm.MonteCarloBarostat(1.0 * u.atmospheres, temperature, 50))

integrator = mm.LangevinIntegrator(temperature, 1.0 / u.picoseconds,
                                   0.5 * u.femtoseconds)
context = mm.Context(system, integrator)
context.setPositions(positions)
context.setPeriodicBoxVectors(*boxes)
context.setVelocitiesToTemperature(temperature)
integrator.step(25000)
positions = context.getState(getPositions=True).getPositions()

x = []
for i in range(1000):
    state = context.getState(getParameters=True, getPositions=True)
    positions = state.getPositions(asNumpy=True) / u.nanometers
    boxes = state.getPeriodicBoxVectors(asNumpy=True) / u.nanometers
    x.append(boxes[0][0] / u.nanometer)
    print(x[-1])
    integrator.step(1000)
Пример #26
0
# Creación del sistema.
system = mm.System()
for ii in range(n_particles):
    system.addParticle(mass)

# Creación del integrador.
friction = 5.0 / unit.picosecond  # fricción del sistema (0.0/unit.picoseconds si no queremos fricción)
integrator = mm.LangevinIntegrator(temperature, friction, integration_timestep)

# Creación de la plataforma.
platform_name = 'CUDA'
platform = mm.Platform.getPlatformByName(platform_name)

# Creación del contexto.
context = mm.Context(system, integrator, platform)
context.setPositions(initial_positions)
context.setVelocities(initial_velocities)

# Creación de arrays reporteros del tiempo, la posición y la velocidad.
times = np.zeros([n_cicles], np.float32) * unit.picoseconds
positions = np.zeros([n_cicles, n_particles, 3], np.float32) * unit.nanometers
velocities = np.zeros([n_cicles, n_particles, 3],
                      np.float32) * unit.nanometers / unit.picosecond
kinetic_energy = np.zeros([n_cicles], np.float32) * unit.kilocalories_per_mole
potential_energy = np.zeros([n_cicles],
                            np.float32) * unit.kilocalories_per_mole

# Almacenamiento en reporteros de las condiciones iniciales para tiempo 0
state = context.getState(getPositions=True, getVelocities=True, getEnergy=True)
times[0] = state.getTime()
Пример #27
0
def benchmark(reference_system,
              positions,
              receptor_atoms,
              ligand_atoms,
              platform_name=None,
              annihilate_electrostatics=True,
              annihilate_sterics=False,
              nsteps=500):
    """
    Benchmark performance relative to unmodified system.

    ARGUMENTS
    
    reference_system (simtk.openmm.System) - the reference System object to compare with
    positions - the positions to assess energetics for
    receptor_atoms (list of int) - the list of receptor atoms 
    ligand_atoms (list of int) - the list of ligand atoms to alchemically modify

    """

    # Create a factory to produce alchemical intermediates.
    logger.info("Creating alchemical factory...")
    initial_time = time.time()
    factory = AbsoluteAlchemicalFactory(
        reference_system,
        ligand_atoms=ligand_atoms,
        annihilate_electrostatics=annihilate_electrostatics,
        annihilate_sterics=annihilate_sterics)
    final_time = time.time()
    elapsed_time = final_time - initial_time
    logger.info("AbsoluteAlchemicalFactory initialization took %.3f s" %
                elapsed_time)

    # Create an alchemically-perturbed state corresponding to nearly fully-interacting.
    # NOTE: We use a lambda slightly smaller than 1.0 because the AlchemicalFactory does not use Custom*Force softcore versions if lambda = 1.0 identically.
    lambda_value = 1.0 - 1.0e-6
    alchemical_state = AlchemicalState(0.00, lambda_value, lambda_value,
                                       lambda_value)

    platform = None
    if platform_name:
        platform = openmm.Platform.getPlatformByName(platform_name)

    # Create the perturbed system.
    logger.info("Creating alchemically-modified state...")
    initial_time = time.time()
    alchemical_system = factory.createPerturbedSystem(alchemical_state)
    final_time = time.time()
    elapsed_time = final_time - initial_time
    # Compare energies.
    timestep = 1.0 * units.femtosecond
    logger.info("Computing reference energies...")
    reference_integrator = openmm.VerletIntegrator(timestep)
    if platform:
        reference_context = openmm.Context(reference_system,
                                           reference_integrator, platform)
    else:
        reference_context = openmm.Context(reference_system,
                                           reference_integrator)
    reference_context.setPositions(positions)
    reference_state = reference_context.getState(getEnergy=True)
    reference_potential = reference_state.getPotentialEnergy()
    logger.info("Computing alchemical energies...")
    alchemical_integrator = openmm.VerletIntegrator(timestep)
    if platform:
        alchemical_context = openmm.Context(alchemical_system,
                                            alchemical_integrator, platform)
    else:
        alchemical_context = openmm.Context(alchemical_system,
                                            alchemical_integrator)
    alchemical_context.setPositions(positions)
    alchemical_state = alchemical_context.getState(getEnergy=True)
    alchemical_potential = alchemical_state.getPotentialEnergy()
    delta = alchemical_potential - reference_potential

    # Make sure all kernels are compiled.
    reference_integrator.step(1)
    alchemical_integrator.step(1)

    # Time simulations.
    logger.info("Simulating reference system...")
    initial_time = time.time()
    reference_integrator.step(nsteps)
    reference_state = reference_context.getState(getEnergy=True)
    reference_potential = reference_state.getPotentialEnergy()
    final_time = time.time()
    reference_time = final_time - initial_time
    logger.info("Simulating alchemical system...")
    initial_time = time.time()
    alchemical_integrator.step(nsteps)
    alchemical_state = alchemical_context.getState(getEnergy=True)
    alchemical_potential = alchemical_state.getPotentialEnergy()
    final_time = time.time()
    alchemical_time = final_time - initial_time

    logger.info("TIMINGS")
    logger.info(
        "reference system       : %12.3f s for %8d steps (%12.3f ms/step)" %
        (reference_time, nsteps, reference_time / nsteps * 1000))
    logger.info(
        "alchemical system      : %12.3f s for %8d steps (%12.3f ms/step)" %
        (alchemical_time, nsteps, alchemical_time / nsteps * 1000))
    logger.info(
        "alchemical simulation is %12.3f x slower than unperturbed system" %
        (alchemical_time / reference_time))

    return delta
Пример #28
0
def run(platform_name, deviceid, two):
    not_obs = [True, True]

    system, coordinates = wcadimer.WCADimer()
    print("Time step: ",
          (wcadimer.stable_timestep * 2.0).in_units_of(units.femtoseconds))

    # Minimization
    platform = openmm.Platform.getPlatformByName('Reference')

    print('Minimizing energy...')
    coordinates = minimize(platform, system, coordinates)
    print('Separation distance: {}'.format(
        norm(coordinates[1, :] - coordinates[0, :]) / units.angstroms))

    print('Equilibrating...')
    platform = openmm.Platform.getPlatformByName(platform_name)

    if platform_name == 'CUDA':
        platform.setPropertyDefaultValue('CudaDeviceIndex', '%d' % deviceid)
        platform.setPropertyDefaultValue('CudaPrecision', 'mixed')
    elif platform_name == 'OpenCL':
        platform.setPropertyDefaultValue('OpenCLDeviceIndex', '%d' % deviceid)
        platform.setPropertyDefaultValue('OpenCLPrecision', 'mixed')

    integrator = openmm.LangevinIntegrator(wcadimer.temperature,
                                           wcadimer.collision_rate,
                                           2.0 * wcadimer.stable_timestep)

    context = openmm.Context(system, integrator, platform)
    context.setPositions(coordinates)
    context.setVelocitiesToTemperature(wcadimer.temperature)

    if two:
        while not_obs[0] or not_obs[1]:
            integrator.step(5000)

            state = context.getState(getPositions=True)
            coordinates = state.getPositions(asNumpy=True)
            sep_dist = norm(coordinates[1, :] -
                            coordinates[0, :]) / units.angstroms
            print('Separation distance: {}'.format(sep_dist))
            if sep_dist < 5.7:
                not_obs[0] = False
                tag = '_a'
                sep_dist_a = sep_dist
            else:
                not_obs[1] = False
                tag = '_b'
                sep_dist_b = sep_dist

            if not os.path.isdir('bstates'):
                os.makedirs('bstates')

            np.savez_compressed('bstates/init_coords{}.npz'.format(tag),
                                coord=coordinates / units.nanometers)

        print(sep_dist_a, sep_dist_b)

    else:
        integrator.step(5000)

        state = context.getState(getPositions=True)
        coordinates = state.getPositions(asNumpy=True)
        print('Separation distance: {}'.format(
            norm(coordinates[1, :] - coordinates[0, :]) / units.angstroms))

        if not os.path.isdir('bstates'):
            os.makedirs('bstates')
            np.save('bstates/init_coords.npy', coordinates / units.nanometers)
Пример #29
0
 def addMissingAtoms(self):
     """Add all missing heavy atoms, as specified by the missingAtoms, missingTerminals, and missingResidues fields."""
     
     # Create a Topology that 1) adds missing atoms, 2) removes all hydrogens, and 3) removes unknown molecules.
     
     (newTopology, newPositions, newAtoms, existingAtomMap) = self._addAtomsToTopology(True, True)
     if len(newAtoms) > 0:
         
         # Create a System for energy minimizing it.
         
         res = list(newTopology.residues())
         forcefield = self._createForceField(newTopology, False)
         system = forcefield.createSystem(newTopology)
         
         # Set any previously existing atoms to be massless, they so won't move.
         
         for atom in existingAtomMap.itervalues():
             system.setParticleMass(atom.index, 0.0)
         
         # If any heavy atoms were omitted, add them back to avoid steric clashes.
         
         nonbonded = [f for f in system.getForces() if isinstance(f, mm.CustomNonbondedForce)][0]
         for atom in self.topology.atoms():
             if atom.element not in (None, hydrogen) and atom not in existingAtomMap:
                 system.addParticle(0.0)
                 nonbonded.addParticle([])
                 newPositions.append(self.positions[atom.index])
         
         # For efficiency, only compute interactions that involve a new atom.
         
         nonbonded.addInteractionGroup([atom.index for atom in newAtoms], range(system.getNumParticles()))
         
         # Do an energy minimization.
         
         integrator = mm.LangevinIntegrator(300*unit.kelvin, 10/unit.picosecond, 5*unit.femtosecond)
         context = mm.Context(system, integrator)
         context.setPositions(newPositions)
         mm.LocalEnergyMinimizer.minimize(context)
         state = context.getState(getPositions=True)
         nearest = self._findNearestDistance(context, newTopology, newAtoms)
         if nearest < 0.15:
             
             # Some atoms are very close together.  Run some dynamics while slowly increasing the strength of the
             # repulsive interaction to try to improve the result.
             
             for i in range(10):
                 context.setParameter('C', 0.15*(i+1))
                 integrator.step(200)
                 d = self._findNearestDistance(context, newTopology, newAtoms)
                 if d > nearest:
                     nearest = d
                     state = context.getState(getPositions=True)
                     if nearest >= 0.15:
                         break
             context.setState(state)
             state = context.getState(getPositions=True)
         
         # Now create a new Topology, including all atoms from the original one and adding the missing atoms.
         
         (newTopology2, newPositions2, newAtoms2, existingAtomMap2) = self._addAtomsToTopology(False, False)
         
         # Copy over the minimized positions for the new atoms.
         
         for a1, a2 in zip(newAtoms, newAtoms2):
             newPositions2[a2.index] = state.getPositions()[a1.index]
         self.topology = newTopology2
         self.positions = newPositions2
Пример #30
0
def run():
    import sys
    if sys.argv[1] == 'dhfr':
        [system, positions, testsystem_name] = dhfr()
    elif sys.argv[1] == 'tip3p':
        [system, positions, testsystem_name] = tip3p()

    precision = sys.argv[2]
    platform_name = sys.argv[3]

    print('%s %s : contains %d particles' %
          (testsystem_name, precision, system.getNumParticles()))
    print('')

    # Remove CMMotionRemover and barostat
    indices_to_remove = list()
    for index in range(system.getNumForces()):
        force = system.getForce(index)
        force_name = force.__class__.__name__
        print(force_name)
        if force_name in ['MonteCarloBarostat', 'CMMotionRemover']:
            print('Removing %s (force index %d)' % (force_name, index))
            indices_to_remove.append(index)
    indices_to_remove.reverse()
    for index in indices_to_remove:
        system.removeForce(index)
    print('')

    # Add barostat
    barostat = openmm.MonteCarloBarostat(pressure, temperature, frequency)

    # Create OpenMM context
    print('Creating context...')
    from openmmtools import integrators
    integrator = integrators.VelocityVerletIntegrator(timestep)
    integrator.setConstraintTolerance(1.0e-8)
    platform = openmm.Platform.getPlatformByName(platform_name)
    platform.setPropertyDefaultValue('Precision', precision)
    if platform_name == 'CUDA':
        platform.setPropertyDefaultValue('DeterministicForces', 'true')
        print('Using deterministic forces...')
    context = openmm.Context(system, integrator, platform)

    context.setPositions(positions)
    print('')

    # Get PME parameters
    print('Retrieving PME parameters...')
    for force in system.getForces():
        if force.__class__.__name__ == 'NonbondedForce':
            nbforce = force
            break
    pme_parameters = nbforce.getPMEParametersInContext(context)
    print(pme_parameters)

    # Flush
    sys.stdout.flush()

    # Equilibrate with barostat
    print('equilibrating...')
    barostat.setFrequency(frequency)
    from progressbar import Percentage, Bar, ETA, RotatingMarker
    widgets = [
        'equilibration: ',
        Percentage(), ' ',
        Bar(marker=RotatingMarker()), ' ',
        ETA()
    ]
    progress = ProgressBar(widgets=widgets)
    for iteration in progress(range(nequil)):
        context.setVelocitiesToTemperature(temperature)
        integrator.step(nequilsteps)

    # Get positions, velocities, and box vectors
    print('')
    state = context.getState(getPositions=True, getVelocities=True)
    box_vectors = state.getPeriodicBoxVectors()
    positions = state.getPositions(asNumpy=True)
    velocities = state.getVelocities(asNumpy=True)
    del context, integrator

    # Remove CMMotionRemover and barostat
    indices_to_remove = list()
    for index in range(system.getNumForces()):
        force = system.getForce(index)
        force_name = force.__class__.__name__
        print(force_name)
        if force_name in ['MonteCarloBarostat', 'CMMotionRemover']:
            print('Removing %s (force index %d)' % (force_name, index))
            indices_to_remove.append(index)
    indices_to_remove.reverse()
    for index in indices_to_remove:
        system.removeForce(index)

    #
    integrator = integrators.VelocityVerletIntegrator(timestep)
    integrator.setConstraintTolerance(1.0e-8)
    context = openmm.Context(system, integrator, platform)
    context.setPeriodicBoxVectors(*box_vectors)
    context.setPositions(positions)
    context.setVelocities(velocities)

    # Open NetCDF file for writing.
    ncfile = netcdf.Dataset(
        'work-%s-%s-%s.nc' % (testsystem_name, precision, platform_name), 'w')
    ncfile.createDimension('nwork', 0)  # extensible dimension
    ncfile.createDimension('nworkvals', nworkvals + 1)
    ncfile.createVariable('work', np.float32, ('nwork', 'nworkvals'))
    work = np.zeros([nwork, nworkvals + 1], np.float32)
    for i in range(nwork):
        context.setVelocitiesToTemperature(temperature)
        integrator.step(nequilsteps)  # equilibrate
        state = context.getState(getEnergy=True)
        initial_energy = state.getPotentialEnergy() + state.getKineticEnergy()
        widgets = [
            'Work %5d / %5d: ' % (i, nwork),
            Percentage(), ' ',
            Bar(marker=RotatingMarker()), ' ',
            ETA()
        ]
        progress = ProgressBar(widgets=widgets)
        for workval in progress(range(nworkvals)):
            integrator.step(nworksteps)
            state = context.getState(getEnergy=True)
            current_energy = state.getPotentialEnergy(
            ) + state.getKineticEnergy()
            work[i, workval + 1] = (current_energy - initial_energy) / kT
            ncfile.variables['work'][i, workval + 1] = work[i, workval + 1]
        print(work[i, :])
        ncfile.sync()