Example #1
0
    def testAppend(self):
        """Test appending to an existing trajectory."""
        fname = tempfile.mktemp(suffix='.dcd')
        pdb = app.PDBFile('systems/alanine-dipeptide-implicit.pdb')
        ff = app.ForceField('amber99sb.xml', 'tip3p.xml')
        system = ff.createSystem(pdb.topology)

        # Create a simulation and write some frames to a DCD file.

        integrator = mm.VerletIntegrator(0.001 * unit.picoseconds)
        simulation = app.Simulation(pdb.topology, system, integrator,
                                    mm.Platform.getPlatformByName('Reference'))
        dcd = app.DCDReporter(fname, 2)
        simulation.reporters.append(dcd)
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(300 * unit.kelvin)
        simulation.step(10)
        self.assertEqual(5, dcd._dcd._modelCount)
        del simulation
        del dcd
        len1 = os.stat(fname).st_size

        # Create a new simulation and have it append some more frames.

        integrator = mm.VerletIntegrator(0.001 * unit.picoseconds)
        simulation = app.Simulation(pdb.topology, system, integrator,
                                    mm.Platform.getPlatformByName('Reference'))
        dcd = app.DCDReporter(fname, 2, append=True)
        simulation.reporters.append(dcd)
        simulation.context.setPositions(pdb.positions)
        simulation.context.setVelocitiesToTemperature(300 * unit.kelvin)
        simulation.step(10)
        self.assertEqual(10, dcd._dcd._modelCount)
        len2 = os.stat(fname).st_size
        self.assertTrue(len2 - len1 > 3 * 4 * 5 * system.getNumParticles())
        del simulation
        del dcd
        os.remove(fname)
Example #2
0
    def setUp(self):
        system = mm.System()
        system.addParticle(1.0)

        for i in range(32):
            force = mm.CustomExternalForce(str(i))
            force.addParticle(0, [])
            force.setForceGroup(i)
            system.addForce(force)

        platform = mm.Platform.getPlatformByName('Reference')
        context = mm.Context(system, mm.VerletIntegrator(0), platform)
        context.setPositions([(0, 0, 0)])
        self.context = context
Example #3
0
def testModuleArguments(deviceString, precision):

    if pt.cuda.device_count() < 1 and deviceString == 'cuda:0':
        pytest.skip('A CUDA device is not available')
    if pt.cuda.device_count() < 2 and deviceString == 'cuda:1':
        pytest.skip('Two CUDA devices are not available')

    class TestModule(pt.nn.Module):
        def __init__(self, device, dtype, positions):
            super().__init__()
            self.device = device
            self.dtype = dtype
            self.register_buffer('positions', pt.tensor(positions).to(dtype))

        def forward(self, positions):
            assert self.positions.device == self.device
            assert positions.device == self.device
            assert positions.dtype == self.dtype
            assert pt.all(positions == self.positions)
            return pt.sum(positions)

    with NamedTemporaryFile() as fd:

        numParticles = 10
        system = mm.System()
        positions = np.random.rand(numParticles, 3)
        for _ in range(numParticles):
            system.addParticle(1.0)

        device = pt.device(deviceString)
        if device.type == 'cpu' or precision == 'double':
            dtype = pt.float64
        else:
            dtype = pt.float32
        module = TestModule(device, dtype, positions)
        pt.jit.script(module).save(fd.name)
        force = ot.TorchForce(fd.name)
        system.addForce(force)

        integrator = mm.VerletIntegrator(1.0)
        platform = mm.Platform.getPlatformByName(device.type.upper())
        properties = {}
        if device.type == 'cuda':
            properties['DeviceIndex'] = str(device.index)
            properties['Precision'] = precision
        context = mm.Context(system, integrator, platform, properties)

        context.setPositions(positions)
        context.getState(getEnergy=True, getForces=True)
Example #4
0
def Calculate_ParmEd_Amber(crd_file, prmtop_file, sysargs):
    #===============================#
    #|   ParmEd object creation    |#
    #===============================#
    ParmEd_ambertop = amber.AmberParm(prmtop_file, crd_file)

    system = ParmEd_ambertop.createSystem(**sysargs)

    #===============================#
    #|   OpenMM simulation setup   |#
    #===============================#
    # Keep a record of which atoms are real (not virtual sites)
    isAtom = []
    for i in range(system.getNumParticles()):
        isAtom.append(system.getParticleMass(i).value_in_unit(u.dalton) > 0.0)
    # Setting force groups enables energy components analysis
    for i, f in enumerate(system.getForces()):
        f.setForceGroup(i)
        if isinstance(f, mm.NonbondedForce):
            f.setUseDispersionCorrection(True)
    integ = mm.VerletIntegrator(1.0 * u.femtosecond)
    plat = mm.Platform.getPlatformByName('Reference')
    # Create Simulation object
    simul = app.Simulation(ParmEd_ambertop.topology, system, integ, plat)
    simul.context.setPositions(ParmEd_ambertop.positions)
    simul.context.applyConstraints(1e-12)
    # Obtain OpenMM potential energy
    state = simul.context.getState(getPositions=True,
                                   getEnergy=True,
                                   getForces=True)
    parmed_energy = state.getPotentialEnergy()
    parmed_forces = state.getForces()
    pos = np.array(state.getPositions().value_in_unit(u.angstrom)).reshape(
        -1, 3)
    # Obtain and save constrained positions
    # M = Molecule(gro_file)
    # M.xyzs[0] = pos
    # M.write('constrained.gro')
    # Print OpenMM-via-ParmEd energy components
    Ecomps_OMM = energy_components(simul)
    printcool_dictionary(Ecomps_OMM,
                         title="OpenMM energy components via ParmEd")
    parmed_forces = np.array([
        f for i, f in enumerate(
            parmed_forces.value_in_unit(u.kilojoule_per_mole / u.nanometer))
        if isAtom[i]
    ])
    return parmed_energy, parmed_forces, Ecomps_OMM
Example #5
0
    def test_createCheckpoint(self):
        system = mm.System()
        system.addParticle(1.0)
        refPositions = [(0,0,0)]

        platform = mm.Platform.getPlatformByName('Reference')
        context = mm.Context(system, mm.VerletIntegrator(0), platform)
        context.setPositions(refPositions)
        chk = context.createCheckpoint()
        # check that the return value of createCheckpoint is of type bytes (non-unicode)
        assert isinstance(chk, bytes)

        # set the positions to something random then reload the checkpoint, and
        # make sure that the positions get restored correctly
        context.setPositions([(12345, 12345, 123451)])
        context.loadCheckpoint(chk)
        newPositions = context.getState(getPositions=True).getPositions()._value

        assert newPositions == refPositions
Example #6
0
def test_local_coord_sites():
    """Make sure that the internal prep of vs positions matches that given by OpenMM."""
    if no_openmm: pytest.skip("No OpenMM modules found.")
    # make a system
    mol = app.PDBFile(os.path.join("files", "vs_mol.pdb"))
    modeller = app.Modeller(topology=mol.topology, positions=mol.positions)
    forcefield = app.ForceField(os.path.join("files", "forcefield", "vs_mol.xml"))
    modeller.addExtraParticles(forcefield)
    system = forcefield.createSystem(modeller.topology, constraints=None)
    integrator = mm.VerletIntegrator(1.0 * unit.femtoseconds)
    platform = mm.Platform.getPlatformByName("Reference")
    simulation = app.Simulation(modeller.topology, system, integrator, platform)
    simulation.context.setPositions(modeller.positions)
    # update the site positions
    simulation.context.computeVirtualSites()
    # one vs and it should be last
    vs_pos = simulation.context.getState(getPositions=True).getPositions(asNumpy=True)[-1]
    # now compute and compare
    vsinfo = PrepareVirtualSites(system=system)
    new_pos = ResetVirtualSites_fast(positions=modeller.positions, vsinfo=vsinfo)[-1]
    assert np.allclose(vs_pos._value, np.array([new_pos.x, new_pos.y, new_pos.z]))
Example #7
0
def runOneTest(testName, options):
    """Perform a single benchmarking simulation."""
    explicit = (testName not in ('gbsa', 'amoebagk'))
    amoeba = (testName in ('amoebagk', 'amoebapme'))
    apoa1 = testName.startswith('apoa1')
    amber = (testName.startswith('amber'))
    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)
    print('Ensemble: %s' % options.ensemble)
    platform = mm.Platform.getPlatformByName(options.platform)

    # Create the System.

    temperature = 300 * unit.kelvin
    if explicit:
        friction = 1 * (1 / unit.picoseconds)
    else:
        friction = 91 * (1 / unit.picoseconds)
    if amoeba:
        constraints = None
        epsilon = float(options.epsilon)
        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=options.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=options.polarization)
        for f in system.getForces():
            if isinstance(f, mm.AmoebaMultipoleForce) or isinstance(
                    f, mm.AmoebaVdwForce) or isinstance(
                        f, mm.AmoebaGeneralizedKirkwoodForce) or isinstance(
                            f, mm.AmoebaWcaDispersionForce):
                f.setForceGroup(1)
        dt = 0.002 * unit.picoseconds
        if options.ensemble == 'NVE':
            integ = mm.MTSIntegrator(dt, [(0, 2), (1, 1)])
        else:
            integ = mm.MTSLangevinIntegrator(temperature, friction, dt,
                                             [(0, 2), (1, 1)])
        positions = pdb.positions
    elif amber:
        dirname = downloadAmberSuite()
        names = {
            'amber20-dhfr': 'JAC',
            'amber20-factorix': 'FactorIX',
            'amber20-cellulose': 'Cellulose',
            'amber20-stmv': 'STMV'
        }
        fileName = names[testName]
        prmtop = app.AmberPrmtopFile(
            os.path.join(dirname, f'PME/Topologies/{fileName}.prmtop'))
        inpcrd = app.AmberInpcrdFile(
            os.path.join(dirname, f'PME/Coordinates/{fileName}.inpcrd'))
        topology = prmtop.topology
        positions = inpcrd.positions
        dt = 0.004 * unit.picoseconds
        method = app.PME
        cutoff = options.cutoff
        constraints = app.HBonds
        system = prmtop.createSystem(nonbondedMethod=method,
                                     nonbondedCutoff=cutoff,
                                     constraints=constraints)
        if options.ensemble == 'NVE':
            integ = mm.VerletIntegrator(dt)
        else:
            integ = mm.LangevinMiddleIntegrator(temperature, friction, dt)
    else:
        if apoa1:
            ff = app.ForceField('amber14/protein.ff14SB.xml',
                                'amber14/lipid17.xml', 'amber14/tip3p.xml')
            pdb = app.PDBFile('apoa1.pdb')
            if testName == 'apoa1pme':
                method = app.PME
                cutoff = options.cutoff
            elif testName == 'apoa1ljpme':
                method = app.LJPME
                cutoff = options.cutoff
            else:
                method = app.CutoffPeriodic
                cutoff = 1 * unit.nanometers
            hydrogenMass = 1.5 * unit.amu
        elif 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
            if options.ensemble == 'NVE':
                integ = mm.VerletIntegrator(dt)
            else:
                integ = mm.LangevinIntegrator(temperature, friction, dt)
        else:
            dt = 0.004 * unit.picoseconds
            constraints = app.HBonds
            if options.ensemble == 'NVE':
                integ = mm.VerletIntegrator(dt)
            else:
                integ = mm.LangevinMiddleIntegrator(temperature, friction, dt)
        positions = pdb.positions
        system = ff.createSystem(pdb.topology,
                                 nonbondedMethod=method,
                                 nonbondedCutoff=cutoff,
                                 constraints=constraints,
                                 hydrogenMass=hydrogenMass)
    if options.ensemble == 'NPT':
        system.addForce(mm.MonteCarloBarostat(1 * unit.bar, temperature, 100))
    print('Step Size: %g fs' % dt.value_in_unit(unit.femtoseconds))
    properties = {}
    initialSteps = 5
    if options.device is not None and platform.getName() in ('CUDA', 'OpenCL'):
        properties['DeviceIndex'] = options.device
        if ',' in options.device or ' ' in options.device:
            initialSteps = 250
    if options.precision is not None and platform.getName() in ('CUDA',
                                                                'OpenCL'):
        properties['Precision'] = options.precision

    # Run the simulation.

    integ.setConstraintTolerance(1e-5)
    if len(properties) > 0:
        context = mm.Context(system, integ, platform, properties)
    else:
        context = mm.Context(system, integ, platform)
    context.setPositions(positions)
    if amber:
        if inpcrd.boxVectors is not None:
            context.setPeriodicBoxVectors(*inpcrd.boxVectors)
        mm.LocalEnergyMinimizer.minimize(
            context, 100 * unit.kilojoules_per_mole / unit.nanometer)
    context.setVelocitiesToTemperature(temperature)

    steps = 20
    while True:
        time = timeIntegration(context, steps, initialSteps)
        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))
Example #8
0
    def compute(self, input_model: "AtomicInput",
                config: "TaskConfig") -> "AtomicResult":
        """
        Runs OpenMM on given structure, inputs, in vacuum.
        """
        self.found(raise_error=True)

        try:
            import openmm
            from openmm import unit
        except ImportError:
            from simtk import openmm, unit

        with capture_stdout():
            from openff.toolkit import topology as offtop

        # Failure flag
        ret_data = {"success": False}

        # generate basis, not given
        if not input_model.model.basis:
            raise InputError("Method must contain a basis set.")

        if isinstance(input_model.model.basis, BasisSet):
            raise InputError(
                "QCSchema BasisSet for model.basis not implemented since not suitable for OpenMM."
            )

        # Make sure we are using smirnoff or antechamber
        basis = input_model.model.basis.lower()
        if basis in ["smirnoff", "antechamber"]:

            with capture_stdout():
                # try and make the molecule from the cmiles
                cmiles = None
                if input_model.molecule.extras:
                    cmiles = input_model.molecule.extras.get(
                        "canonical_isomeric_explicit_hydrogen_mapped_smiles",
                        None)
                    if cmiles is None:
                        cmiles = input_model.molecule.extras.get(
                            "cmiles", {}
                        ).get(
                            "canonical_isomeric_explicit_hydrogen_mapped_smiles",
                            None)

                if cmiles is not None:
                    off_mol = offtop.Molecule.from_mapped_smiles(
                        mapped_smiles=cmiles)
                    # add the conformer
                    conformer = unit.Quantity(value=np.array(
                        input_model.molecule.geometry),
                                              unit=unit.bohr)
                    off_mol.add_conformer(conformer)
                else:
                    # Process molecule with RDKit
                    rdkit_mol = RDKitHarness._process_molecule_rdkit(
                        input_model.molecule)

                    # Create an Open Force Field `Molecule` from the RDKit Molecule
                    off_mol = offtop.Molecule(rdkit_mol)

            # now we need to create the system
            openmm_system = self._generate_openmm_system(
                molecule=off_mol,
                method=input_model.model.method,
                keywords=input_model.keywords)
        else:
            raise InputError(
                "Accepted bases are: {'smirnoff', 'antechamber', }")

        # Need an integrator for simulation even if we don't end up using it really
        integrator = openmm.VerletIntegrator(1.0 * unit.femtoseconds)

        # Set platform to CPU explicitly
        platform = openmm.Platform.getPlatformByName("CPU")

        # Set number of threads to use
        # if `nthreads` is `None`, OpenMM default of all logical cores on
        # processor will be used
        nthreads = config.ncores
        if nthreads is None:
            nthreads = os.environ.get("OPENMM_CPU_THREADS")

        if nthreads:
            properties = {"Threads": str(nthreads)}
        else:
            properties = {}

        # Initialize context
        context = openmm.Context(openmm_system, integrator, platform,
                                 properties)

        # Set positions from our Open Force Field `Molecule`
        context.setPositions(off_mol.conformers[0])

        # Compute the energy of the configuration
        state = context.getState(getEnergy=True)

        # Get the potential as a unit.Quantity, put into units of hartree
        q = state.getPotentialEnergy(
        ) / unit.hartree / unit.AVOGADRO_CONSTANT_NA

        ret_data["properties"] = {"return_energy": q}

        # Execute driver
        if input_model.driver == "energy":
            ret_data["return_result"] = ret_data["properties"]["return_energy"]

        elif input_model.driver == "gradient":
            # Compute the forces
            state = context.getState(getForces=True)

            # Get the gradient as a unit.Quantity with shape (n_atoms, 3)
            gradient = state.getForces(asNumpy=True)

            # Convert to hartree/bohr and reformat as 1D array
            q = (gradient / (unit.hartree / unit.bohr)
                 ).reshape(-1) / unit.AVOGADRO_CONSTANT_NA

            # Force to gradient
            ret_data["return_result"] = -1 * q
        else:
            raise InputError(
                f"Driver {input_model.driver} not implemented for OpenMM.")

        ret_data["success"] = True
        ret_data["extras"] = input_model.extras

        # Move several pieces up a level
        ret_data["provenance"] = Provenance(
            creator="openmm",
            version=openmm.version.short_version,
            nthreads=nthreads)

        return AtomicResult(**{**input_model.dict(), **ret_data})