Esempio n. 1
0
def energy_decomposition_system(structure,
                                system,
                                platform=None,
                                nrg=u.kilocalories_per_mole):
    """
    This function computes the energy contribution for all of the different
    force groups.

    Parameters
    ----------
    structure : Structure
        The Structure with the coordinates for this system
    system : mm.System
        The OpenMM System object to get decomposed energies from
    platform : str
        The platform to use. Options are None (default), 'CPU', 'Reference',
        'CUDA', and 'OpenCL'. None will pick default OpenMM platform for this
        installation and computer
    nrg : energy unit, optional
        The unit to convert all energies into. Default is kcal/mol

    Returns
    -------
    energies : list of tuple
        Each entry is a tuple with the name of the force followed by its
        contribution
    """
    import simtk.openmm as mm
    # First get all of the old force groups so we can restore them
    old_groups = [f.getForceGroup() for f in system.getForces()]
    old_recip_group = []

    def _ene(context, grp):
        st = context.getState(getEnergy=True, groups=1 << grp)
        return (type(system.getForce(grp)).__name__,
                st.getPotentialEnergy().value_in_unit(nrg))

    try:
        for i, f in enumerate(system.getForces()):
            if isinstance(f, mm.NonbondedForce):
                old_recip_group.append(f.getReciprocalSpaceForceGroup())
                f.setReciprocalSpaceForceGroup(i)
            f.setForceGroup(i)
        if platform is None:
            con = mm.Context(system, mm.VerletIntegrator(0.001))
        else:
            con = mm.Context(system, mm.VerletIntegrator(0.001),
                             mm.Platform.getPlatformByName(platform))
        con.setPositions(structure.positions)
        if structure.box is not None:
            con.setPeriodicBoxVectors(*structure.box_vectors)

        return list(map(lambda x: _ene(con, x), range(system.getNumForces())))
    finally:
        idx = 0
        for grp, force in zip(old_groups, system.getForces()):
            if isinstance(force, mm.NonbondedForce):
                force.setReciprocalSpaceForceGroup(old_recip_group[idx])
                idx += 1
            force.setForceGroup(grp)
def set_thermo(system, args):
    '''
    Takes care of thermostat if needed
    '''
    if args.temperature <= 0.0:
        logger.info("This is a constant energy, constant volume (NVE) run.")
        integrator = mm.VerletIntegrator(2.0 * u.femtoseconds)
    else:
        logger.info("This is a constant temperature run at %.2f K" %
                    args.temperature)
        logger.info(
            "The stochastic thermostat collision frequency is %.2f ps^-1" %
            args.collision_rate)
        if args.integrator == "langevin":
            logger.info(
                "Creating a Langevin integrator with %.2f fs timestep." %
                args.timestep)
            integrator = mm.LangevinIntegrator(
                args.temperature * u.kelvin,
                args.collision_rate / u.picoseconds,
                args.timestep * u.femtosecond)
        elif args.integrator == "verlet":
            integrator = mm.VerletIntegrator(2.0 * u.femtoseconds)
            thermostat = mm.AndersenThermostat(
                args.temperature * u.kelvin,
                args.collision_rate / u.picosecond)
            system.addForce(thermostat)
        else:
            logger.warning("Unknown integrator, will crash now")
        add_barostat(system, args)
    return integrator
Esempio n. 3
0
    def test_round_trip(self):
        """ Test ParmEd -> OpenMM round trip with Gromacs system """
        # Use DPPC to get RB-torsions tested. Also check that it initially fails
        # with the CustomNonbondedForce
        warnings.filterwarnings('ignore', category=GromacsWarning)
        top = load_file(os.path.join(get_fn('12.DPPC'), 'topol.top'),
                        xyz=os.path.join(get_fn('12.DPPC'), 'conf.gro'))
        self.assertEqual(top.combining_rule, 'lorentz')

        system = top.createSystem()

        def bad_system():
            return openmm.load_topology(top.topology, system).createSystem()

        warnings.filterwarnings('ignore', category=OpenMMWarning)
        self.assertTrue(
            openmm.load_topology(top.topology, system).unknown_functional)
        self.assertRaises(ParmedError, bad_system)
        for i in range(len(system.getForces())):
            if isinstance(system.getForce(i), mm.CustomNonbondedForce):
                system.removeForce(i)
                break
        system2 = openmm.load_topology(top.topology, system).createSystem()
        con1 = mm.Context(system, mm.VerletIntegrator(0.001), CPU)
        con2 = mm.Context(system2, mm.VerletIntegrator(0.001), CPU)
        con1.setPositions(top.positions)
        con2.setPositions(top.positions)
        ene1 = energy_decomposition(top, con1)
        ene2 = energy_decomposition(top, con2)
        self.assertAlmostEqual(ene1['bond'], ene2['bond'])
        self.assertAlmostEqual(ene1['angle'], ene2['angle'])
        self.assertAlmostEqual(ene1['dihedral'], ene2['dihedral'])
        self.assertAlmostEqual(ene1['improper'], ene2['improper'])
        self.assertAlmostEqual(ene1['rb_torsion'], ene2['rb_torsion'])
        self.assertAlmostEqual(ene1['nonbonded'], ene2['nonbonded'])
Esempio n. 4
0
def test_mutate_quick():
    """
    Abbreviated version of test_mutate_all for travis.
    """
    import perses.rjmc.topology_proposal as topology_proposal
    import perses.rjmc.geometry as geometry
    from perses.tests.utils import compute_potential_components
    from openmmtools import testsystems as ts
    geometry_engine = geometry.FFAllAngleGeometryEngine()

    aminos = ['ALA','VAL','GLY','PHE','PRO','TRP']

    for aa in aminos:
        topology, positions = _get_capped_amino_acid(amino_acid=aa)
        modeller = app.Modeller(topology, positions)

        ff_filename = "amber99sbildn.xml"
        max_point_mutants = 1

        ff = app.ForceField(ff_filename)
        system = ff.createSystem(modeller.topology)
        chain_id = '1'

        system_generator = topology_proposal.SystemGenerator([ff_filename])

        pm_top_engine = topology_proposal.PointMutationEngine(modeller.topology, system_generator, chain_id, max_point_mutants=max_point_mutants)

        current_system = system
        current_topology = modeller.topology
        current_positions = modeller.positions
        minimize_integrator = openmm.VerletIntegrator(1.0*unit.femtosecond)
        platform = openmm.Platform.getPlatformByName("Reference")
        minimize_context = openmm.Context(current_system, minimize_integrator, platform)
        minimize_context.setPositions(current_positions)
        initial_state = minimize_context.getState(getEnergy=True)
        initial_potential = initial_state.getPotentialEnergy()
        openmm.LocalEnergyMinimizer.minimize(minimize_context)
        final_state = minimize_context.getState(getEnergy=True, getPositions=True)
        final_potential = final_state.getPotentialEnergy()
        current_positions = final_state.getPositions()
        print("Minimized initial structure from %s to %s" % (str(initial_potential), str(final_potential)))

        for k, proposed_amino in enumerate(aminos):
            pm_top_engine._allowed_mutations = [[('2',proposed_amino)]]
            pm_top_proposal = pm_top_engine.propose(current_system, current_topology)
            new_positions, logp = geometry_engine.propose(pm_top_proposal, current_positions, beta)
            new_system = pm_top_proposal.new_system
            if np.isnan(logp):
                raise Exception("NaN in the logp")
            integrator = openmm.VerletIntegrator(1*unit.femtoseconds)
            platform = openmm.Platform.getPlatformByName("Reference")
            context = openmm.Context(new_system, integrator, platform)
            context.setPositions(new_positions)
            state = context.getState(getEnergy=True)
            print(compute_potential_components(context))
            potential = state.getPotentialEnergy()
            potential_without_units = potential / potential.unit
            print(str(potential))
            if np.isnan(potential_without_units):
                raise Exception("Energy after proposal is NaN")
Esempio n. 5
0
 def testGB1Energy(self):  # HCT (uses mbondi radii internally)
     """ Compare OpenMM and CHARMM GB (igb=1) energies """
     parm = charmm_gas
     system = parm.createSystem(param22, implicitSolvent=app.HCT)
     integrator = mm.VerletIntegrator(1.0 * u.femtoseconds)
     sim = app.Simulation(parm.topology, system, integrator)
     sim.context.setPositions(charmm_gas_crds.positions)
     energies = decomposed_energy(sim.context, parm)
     self.assertAlmostEqual(energies['bond'], 1.3351, places=3)
     self.assertAlmostEqual(energies['angle'], 14.1158, places=3)
     self.assertAlmostEqual(energies['urey'], 0.3669, places=3)
     self.assertAlmostEqual(energies['dihedral'], 14.2773, places=3)
     self.assertAlmostEqual(energies['improper'], 0.3344, places=3)
     self.assertAlmostEqual(energies['cmap'], -0.5239, places=3)
     self.assertRelativeEqual(energies['nonbond'], -102.1598379, places=5)
     system = parm.createSystem(param22,
                                implicitSolvent=app.HCT,
                                implicitSolventSaltConc=1.0 * u.molar)
     integrator = mm.VerletIntegrator(1.0 * u.femtoseconds)
     sim = app.Simulation(parm.topology, system, integrator)
     sim.context.setPositions(charmm_gas_crds.positions)
     energies = decomposed_energy(sim.context, parm)
     self.assertAlmostEqual(energies['bond'], 1.3351, places=3)
     self.assertAlmostEqual(energies['angle'], 14.1158, places=3)
     self.assertAlmostEqual(energies['urey'], 0.3669, places=3)
     self.assertAlmostEqual(energies['dihedral'], 14.2773, places=3)
     self.assertAlmostEqual(energies['improper'], 0.3344, places=3)
     self.assertAlmostEqual(energies['cmap'], -0.5239, places=3)
     self.assertRelativeEqual(energies['nonbond'], -102.5012873, places=5)
Esempio n. 6
0
def testAlchemicalFactory(reference_system, coordinates, alchemical_atoms, platform_name='OpenCL'):
    """
    Compare energies of reference system and fully-interacting alchemically modified system.

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

    """

    import simtk.unit as units
    import simtk.openmm as openmm
    import time

    # Create a factory to produce alchemical intermediates.
    print "Creating alchemical factory..."
    initial_time = time.time()
    factory = AbsoluteAlchemicalFactory(reference_system, alchemical_atoms=alchemical_atoms)
    final_time = time.time()
    elapsed_time = final_time - initial_time
    print "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_name = 'Reference' # DEBUG
    platform = openmm.Platform.getPlatformByName(platform_name)
    
    # Create the perturbed system.
    print "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
    print "Computing reference energies..."
    reference_integrator = openmm.VerletIntegrator(timestep)
    reference_context = openmm.Context(reference_system, reference_integrator, platform)
    reference_context.setPositions(coordinates)
    reference_state = reference_context.getState(getEnergy=True)
    reference_potential = reference_state.getPotentialEnergy()    
    print "Computing alchemical energies..."
    alchemical_integrator = openmm.VerletIntegrator(timestep)
    alchemical_context = openmm.Context(alchemical_system, alchemical_integrator, platform)
    alchemical_context.setPositions(coordinates)
    alchemical_state = alchemical_context.getState(getEnergy=True)
    alchemical_potential = alchemical_state.getPotentialEnergy()
    delta = alchemical_potential - reference_potential 
    print "reference system       : %24.8f kcal/mol" % (reference_potential / units.kilocalories_per_mole)
    print "alchemically modified  : %24.8f kcal/mol" % (alchemical_potential / units.kilocalories_per_mole)
    print "ERROR                  : %24.8f kcal/mol" % ((alchemical_potential - reference_potential) / units.kilocalories_per_mole)
    print "elapsed alchemical time  %.3f s" % elapsed_time

    return delta
Esempio n. 7
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
Esempio n. 8
0
def compareSystemEnergies(positions,
                          systems,
                          descriptions,
                          platform="CPU",
                          precision=None):
    # Compare energies.
    timestep = 1.0 * units.femtosecond

    if platform:
        platform_name = platform.getName()
        if precision:
            if platform_name == 'CUDA':
                platform.setDefaultPropertyValue('CudaPrecision', precision)
            elif platform_name == 'OpenCL':
                platform.setDefaultPropertyValue('OpenCLPrecision', precision)

    potentials = list()
    states = list()
    for system in systems:
        integrator = openmm.VerletIntegrator(timestep)
        if platform:
            context = openmm.Context(system, integrator, platform)
        else:
            context = openmm.Context(system, integrator)
        context.setPositions(positions)
        state = context.getState(getEnergy=True, getPositions=True)
        potential = state.getPotentialEnergy()
        potentials.append(potential)
        states.append(state)
        del context, integrator

    logger.info("========")
    for i in range(len(systems)):
        logger.info(
            "%32s : %24.8f kcal/mol" %
            (descriptions[i], potentials[i] / units.kilocalories_per_mole))

        integrator = openmm.VerletIntegrator(timestep)
        if platform:
            context = openmm.Context(systems[i], integrator, platform)
        else:
            context = openmm.Context(systems[i], integrator)
        context.setPositions(positions)
        state = context.getState(getEnergy=True, getPositions=True)
        potential = state.getPotentialEnergy()
        del context, integrator

        if (i > 0):
            delta = potentials[i] - potentials[0]
            logger.info("%32s : %24.8f kcal/mol" %
                        ('ERROR', delta / units.kilocalories_per_mole))
            if (abs(delta) > MAX_DELTA):
                raise Exception(
                    "Maximum allowable deviation (%24.8f kcal/mol) exceeded; test failed."
                    % (MAX_DELTA / units.kilocalories_per_mole))

    return potentials
Esempio n. 9
0
    def _create_solvated_systems(self, database, initial_parameters):
        """
        Create the solvated systems for the GB-HCT, OBC1, or OBC2 models

        Arguments
        ---------
        database : dict
            A dictionary of the FreeSolv database, prepared with vacuum openmm systems.
        initial_parameters : dict
            A dictionary of the initial parameters for the HCT force
        """

        cid_list = database.keys()

        for (molecule_index, cid) in enumerate(cid_list):
            entry = database[cid]
            molecule = entry['molecule']
            solvent_system = copy.deepcopy(entry['system'])
            forces = {
                solvent_system.getForce(index).__class__.__name__:
                solvent_system.getForce(index)
                for index in range(solvent_system.getNumForces())
            }
            nonbonded_force = forces['NonbondedForce']
            atoms = [atom for atom in molecule.GetAtoms()]
            gbsa_force = customgbforces.GBSAGBnForce(SA='ACE')
            for (atom_index, atom) in enumerate(atoms):
                [charge, sigma,
                 epsilon] = nonbonded_force.getParticleParameters(atom_index)
                atomtype = atom.GetStringData("gbsa_type")  # GBSA atomtype
                radius = initial_parameters['%s_%s' %
                                            (atomtype,
                                             'radius')] * units.angstroms
                scalingFactor = initial_parameters['%s_%s' %
                                                   (atomtype, 'scalingFactor')]
                gbsa_force.addParticle([charge, radius, scalingFactor])
            solvent_system.addForce(gbsa_force)

            platform = openmm.Platform.getPlatformByName('CPU')
            timestep = 2.0 * units.femtosecond
            solvent_integrator = openmm.VerletIntegrator(timestep)
            solvent_context = openmm.Context(solvent_system,
                                             solvent_integrator, platform)
            entry['solvated_system'] = solvent_system
            entry['solvent_integrator'] = solvent_integrator
            entry['solvent_context'] = solvent_context

            vacuum_system = entry['system']
            vacuum_integrator = openmm.VerletIntegrator(timestep)
            vacuum_context = openmm.Context(vacuum_system, vacuum_integrator,
                                            platform)
            entry['vacuum_integrator'] = vacuum_integrator
            entry['vacuum_context'] = vacuum_context
            database[cid] = entry
        return database
Esempio n. 10
0
def compare_energy_components(rest_system,
                              other_system,
                              positions,
                              platform=REFERENCE_PLATFORM):
    """
    Get energy components of a given system
    """
    platform = configure_platform(platform)

    # Create thermodynamic state and sampler state for non-rest system
    thermostate_other = ThermodynamicState(system=other_system,
                                           temperature=temperature)

    # Create context for non-rest system
    integrator_other = openmm.VerletIntegrator(1.0 * unit.femtosecond)
    context_other = thermostate_other.create_context(integrator_other)
    context_other.setPositions(positions)

    # Get energy components for non-rest system
    components_other = [
        component[1]
        for component in compute_potential_components(context_other, beta=beta)
    ]

    # Create thermodynamic state for rest_system
    thermostate_rest = ThermodynamicState(system=rest_system,
                                          temperature=temperature)

    # Create context forrest system
    integrator_rest = openmm.VerletIntegrator(1.0 * unit.femtosecond)
    context_rest = thermostate_rest.create_context(integrator_rest)
    context_rest.setPositions(positions)

    # Get energy components for rest system
    components_rest = [
        component[1]
        for component in compute_potential_components(context_rest, beta=beta)
    ]

    # Check that bond, angle, and torsion energies match
    for other, rest in zip(components_other[:3], components_rest[:3]):
        assert np.isclose(
            [other], [rest]
        ), f"The energies do not match for the {other[0]}: {other[1]} (other system) vs. {rest[1]} (REST system)"

    # Check that nonbonded energies match
    print(components_rest)
    nonbonded_other = np.array(components_other[3:]).sum()
    nonbonded_rest = np.array(components_rest[3:]).sum()
    assert np.isclose(
        [nonbonded_other], [nonbonded_rest]
    ), f"The energies do not match for the NonbondedForce: {nonbonded_other} (other system) vs. {nonbonded_rest} (REST system)"
Esempio n. 11
0
def get_integrator(random_seed: int, args: ListOfArgs) -> mm.Integrator:
    """Helper function that returns requested integrator."""
    print("   Integrator initialization...")
    integrator = mm.VerletIntegrator(10 * simtk.unit.femtosecond)  # default integrator
    if args.SIM_RUN_SIMULATION:
        if args.SIM_INTEGRATOR_TYPE == "langevin":
            integrator = mm.LangevinIntegrator(args.SIM_TEMP, args.SIM_FRICTION_COEFF, args.SIM_TIME_STEP)
            integrator.setRandomNumberSeed(random_seed)
        elif args.SIM_INTEGRATOR_TYPE == "brownian":
            print(args.SIM_TEMP, args.SIM_FRICTION_COEFF, args.SIM_TIME_STEP)
            integrator = mm.BrownianIntegrator(args.SIM_TEMP, args.SIM_FRICTION_COEFF, args.SIM_TIME_STEP)
            integrator.setRandomNumberSeed(random_seed)
        elif args.SIM_INTEGRATOR_TYPE == "verlet":
            integrator = mm.VerletIntegrator(args.SIM_TIME_STEP)
    return integrator
Esempio n. 12
0
    def test_tip3p_constraints(self):
        """Test that TIP3P distance costraints are correctly applied."""
        # Specify TIP3P constraint distances
        tip3p_oh_distance = 0.9572  # angstrom
        tip3p_hoh_angle = 104.52  # angle
        tip3p_hh_distance = tip3p_oh_distance * np.sin(np.radians(tip3p_hoh_angle / 2)) * 2
        expected_distances = [tip3p_oh_distance, tip3p_oh_distance, tip3p_hh_distance]

        # Load TIP3P molecule
        molecule = Molecule.from_file(tip3p_molecule_filename)

        # Extract topology and positions
        topology = Topology.from_molecules(molecule)
        positions = molecule.positions

        # Create OpenMM System
        ff = ForceField(tip3p_offxml_filename)
        system = ff.create_system(topology)

        # TODO: This is probably unnecessary and we can simply check that the System has all the Constraints in their position.
        # Run dynamics.
        integrator = openmm.VerletIntegrator(2.0 * unit.femtoseconds)
        context = openmm.Context(system, integrator)
        context.setPositions(positions)
        integrator.step(50)

        # Ensure constrained distances are correct
        state = context.getState(getPositions=True)
        new_positions = state.getPositions(asNumpy=True) / unit.angstroms
        distances = []
        for atom_1, atom_2 in [(0, 1), (0, 2), (1, 2)]:  # pair of atoms O-H1, O-H2, H1-H2
            distances.append(np.linalg.norm(new_positions[atom_1] - new_positions[atom_2]))
        err_msg = 'expected distances [O-H1, O-H2, H1-H2]: {} A, new distances: {} A'
        assert np.allclose(expected_distances, distances), err_msg.format(expected_distances, distances)
Esempio n. 13
0
    def __init__(self, atoms):

        # Create a PDB file that can be read by OpenMM
        coords_to_pdb(atoms.get_positions(),
                      int(atoms.get_number_of_atoms() / 3))
        pdb = app.PDBFile("./tmp.pdb")
        os.remove('./tmp.pdb')

        cell = atoms.get_cell()

        # Make sure bond lengths are within MBPol range
        distances = atoms.get_all_distances()
        for i in range(0, len(distances), 3):
            for j in [1, 2]:
                if distances[i, i + j] > 2.5:
                    print('WARNING: rOH > 2.5 A!!!!!! ({})'.format(
                        distances[i, i + j]))
                    if atoms.get_pbc()[0]: print('Try: reconnect_monomers()')

        self.atoms = atoms

        if np.count_nonzero(cell - np.diag(np.diag(cell))) != 0:
            raise Exception('Only orthorhombic unit cells supported')

        if np.alltrue(atoms.get_pbc()):
            self.nonbondedMethod = app.PME
            if np.allclose(np.diag(cell), np.array([0, 0, 0])):
                raise Exception('Specify unit cell for PBC')
            self.boxSize = tuple(np.diag(cell)) * unit.angstrom
            pdb.topology.setUnitCellDimensions(self.boxSize)
            self.nonbondedCutoff = cell[0, 0] / 2 * unit.angstrom
        elif np.alltrue([not a for a in atoms.get_pbc()]):
            self.nonbondedMethod = app.CutoffNonPeriodic
            self.nonbondedCutoff = 1e4 * unit.angstrom
        else:
            raise Exception(
                'Only non-PBC or PBC in all euclidean directions supported')

        self.forcefield = app.ForceField(
            mbpol.__file__.replace("mbpol.py", "mbpol.xml"))
        self.system = self.forcefield.createSystem(
            pdb.topology,
            nonbondedMethod=self.nonbondedMethod,
            nonbondedCutoff=self.nonbondedCutoff)

        self.platform = mm.Platform.getPlatformByName('Reference')
        integrator = mm.VerletIntegrator(
            0.5)  # Never used but needed for context
        self.simulation = app.Simulation(pdb.topology, self.system, integrator,
                                         self.platform)
        self.set_positions(atoms)  #ASE: Angstrom , OMM : nm
        self.state = self.simulation.context.getState(getForces=True,
                                                      getEnergy=True)
        self.last_coordinates = np.array(
            pdb.positions.value_in_unit(unit.angstrom))
        self.last_coordinates = np.delete(self.last_coordinates,
                                          np.arange(3,
                                                    len(self.last_coordinates),
                                                    4),
                                          axis=0).reshape(-1, 3)
Esempio n. 14
0
    def _create_context(self, platform=None):
        """Create Integrator and Context objects if they do not already exist.
        """

        # Check if we already have a Context defined.
        if self._context:
            #if platform and (platform != self._context.getPlatform()): # TODO: Figure out why requested and cached platforms differed in tests.
            if platform and (
                    platform.getName() !=
                    self._context.getPlatform().getName()
            ):  # DEBUG: Only compare Platform names for now; change this later to incorporate GPU IDs.
                # Platform differs from the one requested; destroy it.
                logger.info((platform.getName(),
                             self._context.getPlatform().getName()))
                logger.debug(
                    "Platform differs from the one requested; destroying and recreating..."
                )
                del self._context, self._integrator
            else:
                # Cached context is what we expect; do nothing.
                return

        # Create an integrator.
        timestep = 1.0 * units.femtosecond
        self._integrator = mm.VerletIntegrator(timestep)

        # Create a new OpenMM context.
        if platform:
            self._context = mm.Context(self.system, self._integrator, platform)
        else:
            self._context = mm.Context(self.system, self._integrator)

        logger.debug("_create_context created a new integrator and context")
Esempio n. 15
0
def test_membrane_modeller():
    """Test the addition of hydrogens to a solvated DPPC molecule"""
    # pdb file corresponding to a solvated lipid molecule
    pdb = PDBFile(os.path.join(os.path.dirname(__file__), '../data/dppc/solvated-dppc.pdb'))
    modeller = MembraneModeller(pdb.topology,pdb.positions)
    modeller.modify_topology()
    forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml')
    modeller.addHydrogens(forcefield=forcefield)

    system = forcefield.createSystem(modeller.topology,
                                     nonbondedMethod=app.PME,
                                     rigidWater=True,
                                     nonbondedCutoff=1*unit.nanometer)
    integrator = mm.VerletIntegrator(0.5*unit.femtoseconds)
    platform = mm.Platform.getPlatformByName('Reference')
    simulation = app.Simulation(modeller.topology, system, integrator, platform)
    simulation.context.setPositions(modeller.positions)
    simulation.context.setVelocitiesToTemperature(300*unit.kelvin)
    # Minimize the system after adding hydrogens
    simulation.minimizeEnergy(maxIterations=200)
    # Run a few MD steps to check the system has no overlaps
    simulation.step(1000)
    state = simulation.context.getState(getEnergy=True)
    pe = state.getPotentialEnergy()._value
    assert pe < 0.0
Esempio n. 16
0
 def __init__(self, molecule, pdb, xml, combination='amber'):
     try:
         import simtk.openmm.app as app
         import simtk.openmm as mm
         import simtk.unit as u
     except ImportError:
         raise ImportError("OpenMM computation object requires the 'simtk' package. Please pip or conda install 'openmm' from omnia channel.")
     pdb = app.PDBFile(pdb)
     xmlSystem = False
     if os.path.exists(xml):
         xmlStr = open(xml).read()
         try:
             # If the user has provided an OpenMM system, we can use it directly
             system = mm.XmlSerializer.deserialize(xmlStr)
             xmlSystem = True
             logger.info("Treating the provided xml as a system XML file")
         except ValueError:
             logger.info("Treating the provided xml as a force field XML file")
     else:
         logger.info("xml file not in the current folder, treating as a force field XML file and setting up in gas phase.")
     if not xmlSystem:
         forcefield = app.ForceField(xml)
         system = forcefield.createSystem(pdb.topology, nonbondedMethod=app.NoCutoff, constraints=None, rigidWater=False)
     # apply opls combination rule if we are using it
     if combination == 'opls':
         system = self.opls(system)
     integrator = mm.VerletIntegrator(1.0*u.femtoseconds)
     platform = mm.Platform.getPlatformByName('Reference')
     self.simulation = app.Simulation(pdb.topology, system, integrator, platform)
     super(OpenMM, self).__init__(molecule)
Esempio n. 17
0
    def mm_potential(self, forcefield, top, xyz, charge=False):

        if isinstance(charge, bool):
            if (charge):
                system = forcefield.create_openmm_system(top)
            else:
                mols = [
                    Molecule(mol.reference_molecule)
                    for mol in top.topology_molecules
                ]
                for i, _ in enumerate(mols):
                    mols[i].partial_charges = simtk.unit.Quantity(
                        np.zeros(mols[i].n_atoms),
                        simtk.unit.elementary_charge)
                system = forcefield.create_openmm_system(
                    top, charge_from_molecules=mols)
        else:
            mols = [
                Molecule(mol.reference_molecule)
                for mol in top.topology_molecules
            ]
            for i, _ in enumerate(mols):
                mols[i].partial_charges = charge[i]
            system = forcefield.create_openmm_system(
                top, charge_from_molecules=mols)

        integrator = openmm.VerletIntegrator(1.0 * simtk.unit.femtoseconds)
        context = openmm.Context(system, integrator)
        context.setPositions(xyz * const.angstrom2nm)
        state = context.getState(getEnergy=True)
        energy = state.getPotentialEnergy().in_units_of(
            simtk.unit.kilocalories_per_mole)
        return energy
Esempio n. 18
0
    def g_k(self, molecule_smiles):
        """
        Retrieve or compute the g_k for the given molecule

        Parameters
        ----------
        molecule_smiles : string
            SMILES representation of the molecule

        Returns
        -------
        g_k : float
           Bias weight
        """
        if molecule_smiles in self._gk.keys():
            return self._gk[molecule_smiles]
        else:
            system, positions = self._create_implicit_solvent_openmm(
                self._mol_dict[molecule_smiles])
            timestep = 2 * units.femtoseconds
            integrator = openmm.VerletIntegrator(timestep)
            platform = openmm.Platform.getPlatformByName("CPU")
            context = openmm.Context(system, integrator, platform)
            context.setPositions(positions)
            openmm.LocalEnergyMinimizer.minimize(context)
            state = context.getState(getEnergy=True)
            g_k = state.getPotentialEnergy()
            self._gk[molecule_smiles] = g_k
            return g_k
Esempio n. 19
0
def compute_reduced_potential(thermodynamic_state: states.ThermodynamicState,
                              sampler_state: states.SamplerState) -> float:
    """
    Compute the reduced potential of the given SamplerState under the given ThermodynamicState.

    Arguments
    ----------
    thermodynamic_state : openmmtools.states.ThermodynamicState
        The thermodynamic state under which to compute the reduced potential
    sampler_state : openmmtools.states.SamplerState
        The sampler state for which to compute the reduced potential

    Returns
    -------
    reduced_potential : float
        unitless reduced potential (kT)
    """
    if type(cache.global_context_cache) == cache.DummyContextCache:
        integrator = openmm.VerletIntegrator(
            1.0)  #we won't take any steps, so use a simple integrator
        context, integrator = cache.global_context_cache.get_context(
            thermodynamic_state, integrator)
    else:
        context, integrator = cache.global_context_cache.get_context(
            thermodynamic_state)
    sampler_state.apply_to_context(context, ignore_velocities=True)
    return thermodynamic_state.reduced_potential(context)
Esempio n. 20
0
    def testForce(self):
        # Create a random cloud of particles.

        numParticles = 10
        system = mm.System()
        positions = np.random.rand(numParticles, 3)
        for i in range(numParticles):
            system.addParticle(1.0)
        force = ot.TorchForce("../../tests/central.pt")
        system.addForce(force)

        # Compute the forces and energy.

        integ = mm.VerletIntegrator(1.0)
        context = mm.Context(system, integ,
                             mm.Platform.getPlatformByName('Reference'))
        context.setPositions(positions)
        state = context.getState(getEnergy=True, getForces=True)

        # See if the energy and forces are correct.  The network defines a potential of the form E(r) = |r|^2

        expectedEnergy = np.sum(positions * positions)
        assert np.allclose(
            expectedEnergy,
            state.getPotentialEnergy().value_in_unit(unit.kilojoules_per_mole))
        assert np.allclose(-2 * positions, state.getForces(asNumpy=True))
def test_try_random_itoc():
    """
    test whether a perturbed four-atom system gives the same internal and cartesian coords when recomputed with `_internal_to_cartesian`
    and `_cartesian_to_internal` as compared to the values output by `_get_internal_from_omm`
    """
    import perses.rjmc.geometry as geometry
    geometry_engine = geometry.FFAllAngleGeometryEngine({'test': 'true'})
    import simtk.openmm as openmm
    integrator = openmm.VerletIntegrator(1.0*unit.femtoseconds)
    sys = openmm.System()
    force = openmm.CustomTorsionForce("theta")
    for i in range(4):
        sys.addParticle(1.0*unit.amu)
    force.addTorsion(0,1,2,3,[])
    sys.addForce(force)
    atom_position = unit.Quantity(np.array([ 0.10557722 ,-1.10424644 ,-1.08578826]), unit=unit.nanometers)
    bond_position = unit.Quantity(np.array([ 0.0765,  0.1  ,  -0.4005]), unit=unit.nanometers)
    angle_position = unit.Quantity(np.array([ 0.0829 , 0.0952 ,-0.2479]) ,unit=unit.nanometers)
    torsion_position = unit.Quantity(np.array([-0.057 ,  0.0951 ,-0.1863] ) ,unit=unit.nanometers)
    for i in range(1000):
        atom_position += unit.Quantity(np.random.normal(size=3), unit=unit.nanometers)
        r, theta, phi = _get_internal_from_omm(atom_position, bond_position, angle_position, torsion_position)
        recomputed_xyz, _ = geometry_engine._internal_to_cartesian(bond_position, angle_position, torsion_position, r, theta, phi)
        new_r, new_theta, new_phi = _get_internal_from_omm(recomputed_xyz,bond_position, angle_position, torsion_position)
        TOLERANCE = 1e-10
        difference = np.linalg.norm(np.array(atom_position/unit.nanometers) - np.array(recomputed_xyz/unit.nanometers))
        assert difference < TOLERANCE, f"the norm of the difference in positions recomputed with original cartesians ({difference}) is greater than tolerance of {TOLERANCE}"
        difference = np.linalg.norm(np.array([r, theta, phi]) - np.array([new_r, new_theta, new_phi]))
        assert difference < TOLERANCE, f"the norm of the difference in internals recomputed with original sphericals ({difference}) is greater than tolerance of {TOLERANCE}"
Esempio n. 22
0
def check_potential_energy(system, positions):
    """
    Compute potential energy for system and positions and ensure that it is finite.

    Parameters
    ----------
    system : simtk.openmm.System
       The system
    positions : simtk.unit.Quantity
       The positions

    """

    # Create a Context.
    timestep = 1.0 * unit.femtoseconds
    integrator = openmm.VerletIntegrator(timestep)
    context = openmm.Context(system, integrator)
    context.setPositions(positions)

    # Compute potential energy to make sure it is finite.
    openmm_state = context.getState(getEnergy=True)
    potential_energy = openmm_state.getPotentialEnergy()

    # Check if finite.
    if np.isnan(potential_energy / unit.kilocalories_per_mole):
        raise Exception("Energy is NaN.")

    # Clean up
    del context, integrator
Esempio n. 23
0
 def create_sim(self):
     self.system = self.top.createSystem(nonbondedMethod=app.NoCutoff,
                                         constraints=None)
     self.integrator = openmm.VerletIntegrator(0.001 * unit.picoseconds)
     self.simulation = app.Simulation(self.top.topology, self.system,
                                      self.integrator)
     self.simulation.context.setPositions(self.trj.openmm_positions(0))
def _create_torsion_sim(periodicity: int = 2,
                        phase=0 * omm_angle_unit,
                        k=10.0 * omm_energy_unit) -> app.Simulation:
    """Create a 4-particle OpenMM Simulation containing only a PeriodicTorsionForce"""
    system = mm.System()

    # add 4 particles of unit mass
    for _ in range(4):
        system.addParticle(1)

    # add torsion force to system
    force = mm.PeriodicTorsionForce()
    force.addTorsion(0, 1, 2, 3, periodicity, phase, k)
    system.addForce(force)

    # create openmm Simulation, which requires a Topology and Integrator
    topology = app.Topology()
    chain = topology.addChain()
    residue = topology.addResidue("torsion", chain)
    for name in ["a", "b", "c", "d"]:
        topology.addAtom(name, "C", residue)
    integrator = mm.VerletIntegrator(1.0)
    sim = app.Simulation(topology, system, integrator)

    return sim
Esempio n. 25
0
def compute_potential_components(context):
    """
    Compute potential energy, raising an exception if it is not finite.

    Parameters
    ----------
    context : simtk.openmm.Context
        The context from which to extract, System, parameters, and positions.

    """
    import copy
    system = context.getSystem()
    system = copy.deepcopy(system)
    positions = context.getState(getPositions=True).getPositions(asNumpy=True)
    parameters = context.getParameters()
    for index in range(system.getNumForces()):
        force = system.getForce(index)
        force.setForceGroup(index)

    integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds)
    platform = openmm.Platform.getPlatformByName('Reference')
    context = openmm.Context(system, integrator, platform)
    context.setPositions(positions)
    for (parameter, value) in parameters.items():
        context.setParameter(parameter, value)
    energy_components = list()
    for index in range(system.getNumForces()):
        force = system.getForce(index)
        forcename = force.__class__.__name__
        groups = 1<<index
        potential = context.getState(getEnergy=True, groups=groups).getPotentialEnergy()
        energy_components.append((forcename, potential))
    del context, integrator
    return energy_components
Esempio n. 26
0
def compute_potential(system, positions, platform=None):
    """
    Compute potential energy, raising an exception if it is not finite.

    Parameters
    ----------
    system : simtk.openmm.System
        The system object to check.
    positions : simtk.unit.Quantity of size (natoms,3) with units compatible with nanometers
        The positions to check.
    platform : simtk.openmm.Platform, optional, default=none
        If specified, this platform will be used.

    """
    integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds)
    if platform is not None:
        context = openmm.Context(system, integrator, platform)
    else:
        context = openmm.Context(system, integrator)
    context.setPositions(positions)
    context.applyConstraints(integrator.getConstraintTolerance())
    potential = context.getState(getEnergy=True).getPotentialEnergy()
    del context, integrator
    if np.isnan(potential / unit.kilocalories_per_mole):
        raise NaNException("Potential energy is NaN")
    return potential
Esempio n. 27
0
def minimize(thermodynamic_state, sampler_state, max_iterations=100):
    """
    Minimize the given system and state, up to a maximum number of steps.
    This does not return a copy of the samplerstate; it is simply an update-in-place.

    Arguments
    ----------
    thermodynamic_state : openmmtools.states.ThermodynamicState
        The state at which the system could be minimized
    sampler_state : openmmtools.states.SamplerState
        The starting state at which to minimize the system.
    max_iterations : int, optional, default 20
        The maximum number of minimization steps. Default is 100.

    Returns
    -------
    sampler_state : openmmtools.states.SamplerState
        The posititions and accompanying state following minimization
    """
    if type(cache.global_context_cache) == cache.DummyContextCache:
        integrator = openmm.VerletIntegrator(
            1.0)  #we won't take any steps, so use a simple integrator
        context, integrator = cache.global_context_cache.get_context(
            thermodynamic_state, integrator)
        _logger.debug(f"using dummy context cache")
    else:
        _logger.debug(f"using global context cache")
        context, integrator = cache.global_context_cache.get_context(
            thermodynamic_state)
    sampler_state.apply_to_context(context, ignore_velocities=True)
    openmm.LocalEnergyMinimizer.minimize(context, maxIterations=max_iterations)
    sampler_state.update_from_context(context)
Esempio n. 28
0
def check_potential_is_finite(system, positions):
    """
    Check that the potential energy is finite.

    Parameters
    ----------
    system : simtk.openmm.Syste
        System object
    positions : simtk.unit.Quantity of (natoms,3) with units compatible with angstroms
        positions

    Returns
    -------
    potential : simtk.unit.Quantity
        The potential energy.

    Raises an Exception if the potential energy is not finite.

    """
    integrator = openmm.VerletIntegrator(1 * unit.femtoseconds)
    context = openmm.Context(system, integrator)
    context.setPositions(positions)
    potential = context.getState(getEnergy=True).getPotentialEnergy()
    del context, integrator

    if np.isnan(potential / unit.kilojoules_per_mole):
        raise Exception("Potential energy is infinite.")

    return potential
Esempio n. 29
0
    def create_system(self):
        # set up the system using opls combo rules
        # Load the initial coords into the system and initialise
        forcefield = app.ForceField(self.xml_file)
        top = self.molecule.to_openmm_topology()
        positions = self.molecule.openmm_coordinates()
        # set the initial positions from the pdb
        modeller = app.Modeller(topology=top, positions=positions)

        # if there are virtual sites we need to add them here
        try:
            self.system = forcefield.createSystem(modeller.topology,
                                                  nonbondedMethod=app.NoCutoff,
                                                  constraints=None)
        except ValueError:
            print("Virtual sites were found in the xml file")
            modeller.addExtraParticles(forcefield)
            self.system = forcefield.createSystem(modeller.topology,
                                                  nonbondedMethod=app.NoCutoff,
                                                  constraints=None)

        # Use the opls combination rules.
        if self.molecule.combination == "opls":
            print("OPLS combination rules found in XML file")
            self.opls_lj()

        integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds)
        platform = openmm.Platform.getPlatformByName("Reference")
        self.simulation = app.Simulation(modeller.topology, self.system,
                                         integrator, platform)
        self.simulation.context.setPositions(modeller.positions)
Esempio n. 30
0
def test_amber_implicit(prmtop_filename, inpcrd_filename):
    logger.info("====================================================================")
    logger.info("Creating system...")

    from simtk.openmm import app
    prmtop = app.AmberPrmtopFile(prmtop_filename)
    reference_system = prmtop.createSystem(constraints=app.HBonds, nonbondedMethod=app.NoCutoff, implicitSolvent=app.OBC1)

    # Read positions.
    inpcrd = app.AmberInpcrdFile(inpcrd_filename, loadBoxVectors=False)
    positions = inpcrd.getPositions(asNumpy=True)

    # Set box vectors.
    #box_vectors = inpcrd.getBoxVectors(asNumpy=True)
    #system.setDefaultPeriodicBoxVectors(box_vectors[0], box_vectors[1], box_vectors[2])

    receptor_atoms = range(0,1326)
    ligand_atoms = range(1326, 1356)

    # Minimize.
    logger.info("Minimizing...")
    timestep = 1.0 * units.femtoseconds
    integrator = openmm.VerletIntegrator(timestep)
    context = openmm.Context(reference_system, integrator)
    context.setPositions(positions)
    openmm.LocalEnergyMinimizer.minimize(context, 1.0, 100)
    state = context.getState(getEnergy=True, getPositions=True)
    positions = state.getPositions(asNumpy=True)
    del context, integrator
    logger.info("Done.")

    alchemical_factory_check(reference_system, positions, receptor_atoms, ligand_atoms)
    #benchmark(reference_system, positions, receptor_atoms, ligand_atoms)
    logger.info("====================================================================")
    logger.info("")