def minimise_energy_all_confs(mol, models = None, epsilon = 4, allow_undefined_stereo = True, **kwargs ): from simtk import unit from simtk.openmm import LangevinIntegrator from simtk.openmm.app import Simulation, HBonds, NoCutoff from rdkit import Chem from rdkit.Geometry import Point3D import mlddec import copy import tqdm mol = Chem.AddHs(mol, addCoords = True) if models is None: models = mlddec.load_models(epsilon) charges = mlddec.get_charges(mol, models) from openforcefield.utils.toolkits import RDKitToolkitWrapper, ToolkitRegistry from openforcefield.topology import Molecule, Topology from openforcefield.typing.engines.smirnoff import ForceField # from openforcefield.typing.engines.smirnoff.forcefield import PME import parmed import numpy as np forcefield = ForceField(get_data_filename("modified_smirnoff99Frosst.offxml")) #FIXME better way of identifying file location tmp = copy.deepcopy(mol) tmp.RemoveAllConformers() #XXX workround for speed beacuse seemingly openforcefield records all conformer informations, which takes a long time. but I think this is a ill-practice molecule = Molecule.from_rdkit(tmp, allow_undefined_stereo = allow_undefined_stereo) molecule.partial_charges = unit.Quantity(np.array(charges), unit.elementary_charge) topology = Topology.from_molecules(molecule) openmm_system = forcefield.create_openmm_system(topology, charge_from_molecules= [molecule]) structure = parmed.openmm.topsystem.load_topology(topology.to_openmm(), openmm_system) system = structure.createSystem(nonbondedMethod=NoCutoff, nonbondedCutoff=1*unit.nanometer, constraints=HBonds) integrator = LangevinIntegrator(273*unit.kelvin, 1/unit.picosecond, 0.002*unit.picoseconds) simulation = Simulation(structure.topology, system, integrator) out_mol = copy.deepcopy(mol) for i in tqdm.tqdm(range(out_mol.GetNumConformers())): conf = mol.GetConformer(i) structure.coordinates = unit.Quantity(np.array([np.array(conf.GetAtomPosition(i)) for i in range(mol.GetNumAtoms())]), unit.angstroms) simulation.context.setPositions(structure.positions) simulation.minimizeEnergy() # simulation.step(1) coords = simulation.context.getState(getPositions = True).getPositions(asNumpy = True).value_in_unit(unit.angstrom) conf = out_mol.GetConformer(i) for j in range(out_mol.GetNumAtoms()): conf.SetAtomPosition(j, Point3D(*coords[j])) return out_mol
def create_simulation(self, topology, system): self.integrator = self.create_integrator(system) if self.platform is None: simulation = Simulation(topology, system, self.integrator) else: platform = Platform.getPlatformByName(self.platform) simulation = Simulation(topology, system, self.integrator, platform) for reporter in self.reporters: simulation.reporters.append(reporter) return simulation
def minimize_energy(pdb: PDBFile, simulation: Simulation, args: ListOfArgs): if args.MINIMIZE: print('Energy minimizing...') simulation.minimizeEnergy(tolerance=0.01 * simtk.unit.kilojoules_per_mole) if not args.MINIMIZED_FILE: base, _ = os.path.splitext(args.INITIAL_STRUCTURE_PATH) minimized_file_name = f'{base}_min.pdb' else: minimized_file_name = args.MINIMIZED_FILE # TODO: Nasty fix print(f' Saving minimized structure in {minimized_file_name}') state = simulation.context.getState(getPositions=True) PDBFile.writeFile(pdb.topology, state.getPositions(), open(minimized_file_name, 'w'))
def test_xtc_reporter_append(tmpdir, get_fn): pdb = PDBFile(get_fn('native.pdb')) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') # NO PERIODIC BOUNDARY CONDITIONS system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) xtcfile = os.path.join(tmpdir, 'traj.xtc') xtcfile_cp = os.path.join(tmpdir, 'traj_cp.xtc') checkpoint = os.path.join(tmpdir, 'checkpoint.chk') reporter = XTCReporter(xtcfile, 2) simulation.reporters.append(reporter) simulation.reporters.append(CheckpointReporter(checkpoint, 10)) simulation.step(10) reporter.close() shutil.copyfile(xtcfile, xtcfile_cp) system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.loadCheckpoint(checkpoint) reporter = XTCReporter(xtcfile, 2, append=True) simulation.reporters.append(reporter) simulation.step(10) reporter.close() xtc_traj = md.load(xtcfile, top=get_fn('native.pdb')) xtc_traj_cp = md.load(xtcfile_cp, top=get_fn('native.pdb')) eq(xtc_traj.xyz[:5], xtc_traj_cp.xyz) eq(xtc_traj.n_frames, 10) eq(xtc_traj_cp.n_frames, 5) eq(xtc_traj.time[:5], xtc_traj_cp.time)
def __init__(self, prmtopFname, inpcrdFname): # prmtopFname, inpcrdFname ): self.prmtop = AmberPrmtopFile(prmtopFname) self.inpcrd = AmberInpcrdFile(inpcrdFname) # number of atoms self.natoms = self.prmtop.topology._numAtoms # todo: set up ff and simulation object self.system = self.prmtop.createSystem( nonbondedMethod=openmmff.NoCutoff) # no cutoff self.integrator = VerletIntegrator(0.001 * picosecond) self.simulation = Simulation(self.prmtop.topology, self.system, self.integrator) # Another way of setting up potential using just pdb file ( no prmtop ) # pdb = PDBFile('coords.pdb') # forcefield = ForceField('amber99sb.xml', 'tip3p.xml') # system = forcefield.createSystem(pdb.topology, nonbondedMethod=ff.NoCutoff) # integrator = VerletIntegrator(0.001*picoseconds) # simulation = Simulation(pdb.topology, system, integrator) # simulation.context.setPositions(pdb.positions) # remove units self.localCoords = self.inpcrd.positions / angstrom self.kJtokCal = kilocalories_per_mole / kilojoules_per_mole
def generate_simulation(self, system): assert isinstance(system, OmmSystem) if not self.platform: self._platform = self.create_platform( _default_rt_configuration["device"]) if not self.integrator: self.create_integrator( _amber_test_configuration) #TODO change back when figured out if (len(self.integrator_components) > 0): for component in self.integrator_components: getattr(system.system, "addForce")(component) self._simulation = Simulation( system.topology.to_openmm(), system.system, self.integrator, self.platform, ) #self.properties) initial_positions = system.initial_positions self.set_positions(initial_positions)
def _prep_sim(self, coords, external_forces=[]): try: from simtk.openmm import Platform, LangevinIntegrator, Vec3 from simtk.openmm.app import Modeller, ForceField, \ CutoffNonPeriodic, PME, Simulation, HBonds from simtk.unit import angstrom, nanometers, picosecond, \ kelvin, Quantity, molar except ImportError: raise ImportError( 'Please install PDBFixer and OpenMM in order to use ClustENM.') positions = Quantity([Vec3(*xyz) for xyz in coords], angstrom) modeller = Modeller(self._topology, positions) if self._sol == 'imp': forcefield = ForceField(*self._force_field) system = forcefield.createSystem(modeller.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds) if self._sol == 'exp': forcefield = ForceField(*self._force_field) modeller.addSolvent(forcefield, padding=self._padding * nanometers, ionicStrength=self._ionicStrength * molar) system = forcefield.createSystem(modeller.topology, nonbondedMethod=PME, nonbondedCutoff=1.0 * nanometers, constraints=HBonds) for force in external_forces: system.addForce(force) integrator = LangevinIntegrator(self._temp * kelvin, 1 / picosecond, 0.002 * picosecond) # precision could be mixed, but single is okay. platform = self._platform if self._platform is None else Platform.getPlatformByName( self._platform) properties = None if self._platform is None: properties = {'Precision': 'single'} elif self._platform in ['CUDA', 'OpenCL']: properties = {'Precision': 'single'} simulation = Simulation(modeller.topology, system, integrator, platform, properties) simulation.context.setPositions(modeller.positions) return simulation
def simulation_from_graph(self, g): """ Create simulation from moleucle """ # assign partial charge g.mol.assign_partial_charges("gasteiger") # faster # parameterize topology topology = g.mol.to_topology() # create openmm system system = self.forcefield.create_openmm_system( topology, # TODO: # figure out whether `sqm` should be so slow charge_from_molecules=[g.mol], ) # use langevin integrator integrator = openmm.LangevinIntegrator(self.temperature, self.collision_rate, self.step_size) # initialize simulation simulation = Simulation(topology=topology, system=system, integrator=integrator) import openforcefield # get conformer g.mol.generate_conformers( toolkit_registry=openforcefield.utils.RDKitToolkitWrapper(), ) # put conformer in simulation simulation.context.setPositions(g.mol.conformers[0]) # minimize energy simulation.minimizeEnergy() # set velocities simulation.context.setVelocitiesToTemperature(self.temperature) return simulation
def test_nonequilibrium_external_integrator(): """Moves the first atom during the third step of the integration and checks to see that the AlchemicalExternalLangevinIntegrator finds the correct energy change. """ testsystem = testsystems.AlanineDipeptideVacuum() functions = {'lambda_sterics': '1', 'lambda_electrostatics': '1'} factory = AbsoluteAlchemicalFactory(consistent_exceptions=False) alanine_vacuum = testsystem.system alchemical_region = AlchemicalRegion(alchemical_atoms=range(22), annihilate_electrostatics=True, annihilate_sterics=True) alanine_alchemical_system = factory.create_alchemical_system( reference_system=alanine_vacuum, alchemical_regions=alchemical_region) nsteps_neq = 6 integrator = AlchemicalExternalLangevinIntegrator( alchemical_functions=functions, timestep=0.05 * simtk.unit.femtoseconds, nsteps_neq=nsteps_neq, measure_shadow_work=False, steps_per_propagation=2) simulation = Simulation(testsystem.topology, alanine_alchemical_system, integrator) simulation.context.setPositions(testsystem.positions) for i in range(nsteps_neq): simulation.step(1) protocol_work = simulation.integrator.getGlobalVariableByName( "protocol_work") if i == 3: #perform the displacement of an atom state = simulation.context.getState(getPositions=True) pos = state.getPositions(asNumpy=True) pos[0, 1] = pos[0, 1] + 0.5 * simtk.unit.nanometers simulation.context.setPositions(pos) protocol_work = simulation.integrator.getLogAcceptanceProbability( simulation.context) print(protocol_work) #find the work done for that displacement #protocol work is around 221.0 (in kT units), so acceptance is around -221.0 assert -220.0 > protocol_work assert -223.0 < protocol_work
def __init__(self, pdb_path, offset_size=2): # OpenMM init self.pdb_path = pdb_path self.pdb = PDBFile(self.pdb_path) self.forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml') self.modeller = Modeller(self.pdb.topology, self.pdb.positions) # Remove any water that might be present in the PDB file self.modeller.deleteWater() # Add any hydrogens not present self.modeller.addHydrogens(self.forcefield) self.system = self.forcefield.createSystem(self.modeller.topology, nonbondedMethod=PME, nonbondedCutoff=1 * u.nanometer, constraints=HBonds) self.integrator = LangevinIntegrator(300 * u.kelvin, 1 / u.picosecond, 0.002 * u.picoseconds) self.simulation = Simulation(self.modeller.topology, self.system, self.integrator) self.pdb_positions = self.modeller.getPositions() # Initialize bond dictionary and positions for chemcoord self.cc_bonds = {} self.offset_size = offset_size self._init_pdb_bonds() self.set_cc_positions(self.pdb_positions) # Perform initial minimization, which updates self.pdb_positions min_energy, min_positions = self.run_simulation() # Reset the positions after the minimization self.set_cc_positions(self.pdb_positions) self.torsion_indices = self._get_torsion_indices() self.starting_positions = min_positions self.starting_torsions = np.array([ self.zmat.loc[self.torsion_indices[:, 0], 'dihedral'], self.zmat.loc[self.torsion_indices[:, 1], 'dihedral'] ]).T self.seed_offsets()
def _remove_barostat_from_simulation(topology, system, simulation, ensemble_options): _remove_barostat_from_system(system) state = simulation.context.getState(getPositions=True, getVelocities=True) positions = state.getPositions(asNumpy=True) velocities = state.getVelocities(asNumpy=True) periodic_box_vectors = state.getPeriodicBoxVectors(asNumpy=True) integrator = ensemble_options.create_integrator(system) system.setDefaultPeriodicBoxVectors(*periodic_box_vectors) simulation = Simulation(topology, system, integrator) simulation.context.setPositions(positions) simulation.context.setVelocities(velocities) return simulation
def calculate_fragment_energetics(frag_no=1): """ * Create an OpenMM system with a fragment. * Calculate the energy of the system and print. :param frag_no: The number of the fragment being analysed (used to access files). """ os.chdir(f'group2/frag{frag_no}') # Necessary due to size of calculation sys.setrecursionlimit(15000) pdb = PDBFile(f'QUBE_pro_frag{frag_no}.pdb') forcefield = ForceField(f'QUBE_pro_frag{frag_no}_plus.xml') system = forcefield.createSystem( pdb.topology, nonbondedMethod=NoCutoff, ) system = apply_opls_combo(system) with open(f'QUBE_pro_frag{frag_no}_out.xml', 'w') as outfile: serialized_system = XmlSerializer.serialize(system) outfile.write(serialized_system) # Create the integrator to do Langevin dynamics integrator = LangevinIntegrator( 298.15 * unit.kelvin, # Temperature of heat bath 1.0 / unit.picoseconds, # Friction coefficient 2.0 * unit.femtoseconds, # Time step ) platform = Platform.getPlatformByName('CPU') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) print('energy from openmm library') print(simulation.context.getState(getEnergy=True).getPotentialEnergy()) structure = parmed.load_file(f'QUBE_pro_frag{frag_no}.pdb') energy_comps = parmed.openmm.energy_decomposition_system(structure, system) total_energy = 0.0 for comp in energy_comps: total_energy += comp[1] print(*comp) print(f'Total energy {total_energy: 6.6f}')
def baseline_energy(self, g, suffix=None): if suffix is None: suffix = "_" + self.forcefield from openmmforcefields.generators import SystemGenerator # define a system generator system_generator = SystemGenerator( small_molecule_forcefield=self.forcefield, ) mol = g.mol # mol.assign_partial_charges("formal_charge") # create system system = system_generator.create_system( topology=mol.to_topology().to_openmm(), molecules=mol, ) # parameterize topology topology = g.mol.to_topology().to_openmm() integrator = openmm.LangevinIntegrator(TEMPERATURE, COLLISION_RATE, STEP_SIZE) # create simulation simulation = Simulation(topology=topology, system=system, integrator=integrator) us = [] xs = (Quantity( g.nodes["n1"].data["xyz"].detach().numpy(), esp.units.DISTANCE_UNIT, ).value_in_unit(unit.nanometer).transpose((1, 0, 2))) for x in xs: simulation.context.setPositions(x) us.append( simulation.context.getState( getEnergy=True).getPotentialEnergy().value_in_unit( esp.units.ENERGY_UNIT)) g.nodes["g"].data["u%s" % suffix] = torch.tensor(us)[None, :] return g
def setup(args: ListOfArgs) -> Tuple[PDBFile, int, Simulation]: print("Initialization...") if args.SIM_RANDOM_SEED == 0: random_seed = np.random.randint(2147483647) else: random_seed = args.SIM_RANDOM_SEED print(f" Loading initial structure: {args.INITIAL_STRUCTURE_PATH}") pdb = PDBFile(args.INITIAL_STRUCTURE_PATH) print(f" Loading forcefield file: {args.FORCEFIELD_PATH}") forcefield = ForceField(args.FORCEFIELD_PATH) print(" Building system...") system = forcefield.createSystem(pdb.topology) add_forces_to_system(system, args) integrator = get_integrator(random_seed, args) print(" Setting up simulation...") simulation = Simulation(pdb.topology, system, integrator) simulation.context.setPositions(pdb.positions) return pdb, random_seed, simulation
def simulation_from_graph(self, g): """ Create simulation from moleucle """ # assign partial charge if self.charge_method is not None: g.mol.assign_partial_charges(self.charge_method) # parameterize topology topology = g.mol.to_topology().to_openmm() generator = SystemGenerator( small_molecule_forcefield=self.forcefield, molecules=[g.mol], ) # create openmm system system = generator.create_system(topology, ) # set epsilon minimum to 0.05 kJ/mol for force in system.getForces(): if "Nonbonded" in force.__class__.__name__: force.setNonbondedMethod(openmm.NonbondedForce.NoCutoff) for particle_index in range(force.getNumParticles()): charge, sigma, epsilon = force.getParticleParameters( particle_index) if epsilon < EPSILON_MIN: force.setParticleParameters(particle_index, charge, sigma, EPSILON_MIN) # use langevin integrator integrator = openmm.LangevinIntegrator(self.temperature, self.collision_rate, self.step_size) # initialize simulation simulation = Simulation( topology=topology, system=system, integrator=integrator, platform=openmm.Platform.getPlatformByName("Reference"), ) return simulation
def _create_openmm_simulation(topology, system, integrator, platform, properties): return Simulation(topology, system, integrator, platform, properties)
def subtract_nonbonded_force_except_14( g, forcefield="gaff-1.81", ): # parameterize topology topology = g.mol.to_topology().to_openmm() generator = SystemGenerator( small_molecule_forcefield=forcefield, molecules=[g.mol], ) # create openmm system system = generator.create_system(topology, ) # use langevin integrator, although it's not super useful here integrator = openmm.LangevinIntegrator(TEMPERATURE, COLLISION_RATE, STEP_SIZE) # create simulation simulation = Simulation(topology=topology, system=system, integrator=integrator) # get forces forces = list(system.getForces()) # loop through forces for force in forces: name = force.__class__.__name__ # turn off angle if "Angle" in name: for idx in range(force.getNumAngles()): id1, id2, id3, angle, k = force.getAngleParameters(idx) force.setAngleParameters(idx, id1, id2, id3, angle, 0.0) force.updateParametersInContext(simulation.context) elif "Bond" in name: for idx in range(force.getNumBonds()): id1, id2, length, k = force.getBondParameters(idx) force.setBondParameters( idx, id1, id2, length, 0.0, ) force.updateParametersInContext(simulation.context) elif "Torsion" in name: for idx in range(force.getNumTorsions()): ( id1, id2, id3, id4, periodicity, phase, k, ) = force.getTorsionParameters(idx) force.setTorsionParameters( idx, id1, id2, id3, id4, periodicity, phase, 0.0, ) force.updateParametersInContext(simulation.context) elif "Nonbonded" in name: for exception_index in range(force.getNumExceptions()): ( p1, p2, chargeprod, sigma, epsilon, ) = force.getExceptionParameters(exception_index) force.setExceptionParameters(exception_index, p1, p2, chargeprod, sigma, 1e-8 * epsilon) force.updateParametersInContext(simulation.context) # the snapshots xs = (Quantity( g.nodes["n1"].data["xyz"].detach().numpy(), esp.units.DISTANCE_UNIT, ).value_in_unit(unit.nanometer).transpose((1, 0, 2))) # loop through the snapshots energies = [] derivatives = [] for x in xs: simulation.context.setPositions(x) state = simulation.context.getState( getEnergy=True, getParameters=True, getForces=True, ) energy = state.getPotentialEnergy().value_in_unit( esp.units.ENERGY_UNIT, ) derivative = state.getForces(asNumpy=True).value_in_unit( esp.units.FORCE_UNIT, ) energies.append(energy) derivatives.append(derivative) # put energies to a tensor energies = torch.tensor( energies, dtype=torch.get_default_dtype(), ).flatten()[None, :] derivatives = torch.tensor( np.stack(derivatives, axis=1), dtype=torch.get_default_dtype(), ) # subtract the energies g.heterograph.apply_nodes( lambda node: {"u_ref": node.data["u_ref"] - energies}, ntype="g", ) if "u_ref_prime" in g.nodes["n1"].data: g.heterograph.apply_nodes( lambda node: {"u_ref_prime": node.data["u_ref_prime"] - derivatives}, ntype="n1", ) return g
def distributeLipids(boxsize, resnames, sigmas, cutoff, mass=39.9 * unit.amu, # argon epsilon=0.238 * unit.kilocalories_per_mole, # argon, switch_width=3.4 * unit.angstrom, # argon ): nparticles = len(resnames) # Determine Lennard-Jones cutoff. cutoff = cutoff * unit.angstrom cutoff_type = openmm.NonbondedForce.CutoffPeriodic # Create an empty system object. system = openmm.System() # Periodic box vectors. a = unit.Quantity((boxsize[0] * unit.angstrom, 0 * unit.angstrom, 0 * unit.angstrom)) b = unit.Quantity((0 * unit.angstrom, boxsize[1] * unit.angstrom, 0 * unit.angstrom)) c = unit.Quantity((0 * unit.angstrom, 0 * unit.angstrom, boxsize[2] * unit.angstrom)) system.setDefaultPeriodicBoxVectors(a, b, c) # Set up periodic nonbonded interactions with a cutoff. nb = openmm.NonbondedForce() nb.setNonbondedMethod(cutoff_type) nb.setCutoffDistance(cutoff) nb.setUseDispersionCorrection(True) nb.setUseSwitchingFunction(False) if (switch_width is not None): nb.setUseSwitchingFunction(True) nb.setSwitchingDistance(cutoff - switch_width) for s in sigmas: system.addParticle(mass) nb.addParticle(0.0 * unit.elementary_charge, s * unit.angstrom, epsilon) positions = subrandom_particle_positions(nparticles, system.getDefaultPeriodicBoxVectors(), 2) # Add the nonbonded force. system.addForce(nb) # Add a restraining potential to keep atoms in z=0 energy_expression = 'k * (z^2)' force = openmm.CustomExternalForce(energy_expression) force.addGlobalParameter('k', 10) for particle_index in range(nparticles): force.addParticle(particle_index, []) system.addForce(force) # Create topology. topology = app.Topology() chain = topology.addChain() elems = ['Ar', 'Cl', 'Na'] _, idx = np.unique(resnames, return_inverse=True) for i in idx: element = app.Element.getBySymbol(elems[i]) residue = topology.addResidue(elems[i], chain) topology.addAtom(elems[i], element, residue) topology.setUnitCellDimensions(unit.Quantity(boxsize, unit.angstrom)) # Simulate it from simtk.openmm import LangevinIntegrator, VerletIntegrator from simtk.openmm.app import Simulation, PDBReporter, StateDataReporter, PDBFile from simtk.unit import kelvin, picoseconds, picosecond, angstrom from sys import stdout from mdtraj.reporters import DCDReporter nsteps = 10000 freq = 1 integrator = VerletIntegrator(0.002 * picoseconds) simulation = Simulation(topology, system, integrator) simulation.context.setPositions(positions) simulation.minimizeEnergy() # simulation.reporters.append(DCDReporter('output.dcd', 1)) # simulation.reporters.append(StateDataReporter(stdout, 1000, potentialEnergy=True, totalEnergy=True, step=True, separator=' ')) simulation.step(nsteps) state = simulation.context.getState(getPositions=True, enforcePeriodicBox=True) allfinalpos = state.getPositions(asNumpy=True).value_in_unit(angstrom) # with open('topology.pdb', 'w') as f: # PDBFile.writeFile(topology, positions, f) # from htmd.molecule.molecule import Molecule # mol = Molecule('topology.pdb') # mol.read('output.dcd') return allfinalpos
[-15 * u.angstrom, 0 * u.angstrom, 0 * u.angstrom]) system.addForce(pin_force) # Loop extrusion force le_force = mm.HarmonicBondForce() le_force.addBond( 48, 50, 1 * u.angstrom, LE_FORCE_MATRIX[2][0] * u.kilocalories_per_mole / u.angstroms**2) for i in range(2, 35): p1, p2 = 49 - i, 49 + i le_force.addBond( p1, p2, 1 * u.angstrom, LE_FORCE_MATRIX[1][0] * u.kilocalories_per_mole / u.angstroms**2) system.addForce(le_force) simulation = Simulation(pdb.topology, system, integrator) simulation.context.setPositions(pdb.positions) simulation.minimizeEnergy() simulation.reporters.append(DCDReporter('trj.dcd', 1)) simulation.reporters.append( StateDataReporter(stdout, 1000, step=True, potentialEnergy=True, temperature=True)) simulation.reporters.append( StateDataReporter(STATE_FNAME, 10, step=True, potentialEnergy=True)) simulation.step(STEPS_PER_CYCLE) for i in range(2, 35):
# OpenMM from simtk.openmm.app import AmberPrmtopFile, AmberInpcrdFile, Simulation from simtk.openmm.app import pdbfile as openmmpdb from simtk.openmm import * from simtk.unit import picosecond import simtk.openmm.app.forcefield as openmmff #from sys import stdout # ----- OpenMM # setup using inpcrd and prmtop prmtop = AmberPrmtopFile('coords.prmtop') inpcrd = AmberInpcrdFile('coords.inpcrd') system1 = prmtop.createSystem(nonbondedMethod=openmmff.NoCutoff) integrator1 = VerletIntegrator(0.001 * picosecond) simulation1 = Simulation(prmtop.topology, system1, integrator1) simulation1.context.setPositions(inpcrd.positions) # get energy ener1 = simulation1.context.getState(getEnergy=True).getPotentialEnergy() # setup using pdb and built-in amber ff pdb = openmmpdb.PDBFile('coords.pdb') forcefield = openmmff.ForceField('amber99sb.xml', 'tip3p.xml') system2 = forcefield.createSystem(pdb.topology, nonbondedMethod=openmmff.NoCutoff) integrator2 = VerletIntegrator(0.001 * picosecond) simulation2 = Simulation(pdb.topology, system2, integrator2) simulation2.context.setPositions(pdb.positions) # get energy ener2 = simulation2.context.getState(getEnergy=True).getPotentialEnergy()
def main(argdict): """ Main function for entry point checking. Expects a dictionary of command line arguments. """ # load configuration from logfile: with open(argdict["log"], 'r') as f: argdict = json.load(f) # load system initial configuration: pdb = pdb_file_nonstandard_bonds(argdict["pdb"]) print("--> input topology: ", end="") print(pdb.topology) # physical parameters of simulation: sim_temperature = argdict["temperature"] * kelvin sim_andersen_coupling = 1 / picosecond sim_pressure = ( (argdict["pressure"], argdict["pressure"], argdict["pressure"]) * bar) sim_scale_x = True sim_scale_y = True sim_scale_z = True # simulation control parameters: sim_timestep = argdict["timestep"] * femtoseconds # restraints parameters: sim_restr_fc = argdict["restr_fc"] * kilojoule_per_mole / nanometer**2 # create force field object: ff = ForceField(*argdict["ff"]) # build a simulation system from topology and force field: # (note that AMOEBA is intended to be run without constraints) # (note that mutualInducedtargetEpsilon defaults to 0.01 unlike what is # specified in the documentation which claims 0.00001) system = ff.createSystem( pdb.topology, nonbondedMethod=PME, nonbondedCutoff=argdict["nonbonded_cutoff"] * nanometer, vdwCutoff=argdict["vdw_cutoff"] * nanometer, ewaldErrorTolerance=argdict["ewald_error_tolerance"], polarisation=argdict["polarisation"], mutualInducedTargetEpsilon=argdict["mutual_induced_target_epsilon"], constraints=None, rigidWater=False, removeCMMotion=True # removes centre of mass motion ) # overwrite the polarisation method set at system creation; this is # necessary as openMM always sets polarisation method to "mutual" of the # target epsilon is specified at system creation; this way, target epsilon # is ignored for all but the mutual method multipole_force = [ f for f in system.getForces() if isinstance(f, AmoebaMultipoleForce) ][0] print("--> using polarisation method " + str(argdict["polarisation"])) if argdict["polarisation"] == "mutual": multipole_force.setPolarizationType(multipole_force.Mutual) if argdict["polarisation"] == "extrapolated": multipole_force.setPolarizationType(multipole_force.Extrapolated) if argdict["polarisation"] == "direct": multipole_force.setPolarizationType(multipole_force.Direct) # will use Andersen thermostat here: # (Inhibits particle dynamics somewhat, but little or no ergodicity # issues (from Gromacs documenation). However, only alternative is full # Langevin dynamics, which is even worse wrt dynamics. Bussi/v-rescale is # not available at the moment, it seems (it is available in tinker, but # without GPU acceleration)) system.addForce(AndersenThermostat(sim_temperature, sim_andersen_coupling)) # use anisotropic barostat: # (note that this corresponds to semiisotropic pressure coupling in Gromacs # if the pressure is identical for the x- and y/axes) # (note that by default this attempts an update every 25 steps) system.addForce( MonteCarloAnisotropicBarostat(sim_pressure, sim_temperature, sim_scale_x, sim_scale_y, sim_scale_z)) # prepare harmonic restraining potential: # (note that periodic distance is absolutely necessary here to prevent # system from blowing up, as otherwise periodic image position may be used # resulting in arbitrarily large forces) force = CustomExternalForce("k*periodicdistance(x, y, z, x0, y0, z0)^2") force.addGlobalParameter("k", sim_restr_fc) force.addPerParticleParameter("x0") force.addPerParticleParameter("y0") force.addPerParticleParameter("z0") # apply harmonic restraints to C-alphas: if argdict["restr"] == "capr": print("--> applying harmonic positional restraints to CA atoms") for atm in pdb.topology.atoms(): if atm.name == "CA": force.addParticle(atm.index, pdb.positions[atm.index]) elif argdict["restr"] == "hapr": sys.exit("Restraints mode " + str(argdict["restr"]) + "is not implemented.") elif argdict["restr"] == "none": print("--> applying no harmonic positional restraints to any atom") else: sys.exit("Restraints mode " + str(argdict["restr"]) + "is not implemented.") # add restraining force to system: system.addForce(force) # make special group for nonbonded forces: for f in system.getForces(): if (isinstance(f, AmoebaMultipoleForce) or isinstance(f, AmoebaVdwForce) or isinstance(f, AmoebaGeneralizedKirkwoodForce) or isinstance(f, AmoebaWcaDispersionForce)): f.setForceGroup(1) # select integrator: if argdict["integrator"] == "mts": # use multiple timestep RESPA integrator: print("--> using RESPA/MTS integrator") integrator = MTSIntegrator(sim_timestep, [(0, argdict["inner_ts_frac"]), (1, 1)]) if argdict["integrator"] == "verlet": # use Leapfrog Verlet integrator here: print("--> using Verlet integrator") integrator = VerletIntegrator(sim_timestep) # select a platform (should be CUDA, otherwise VERY slow): platform = Platform.getPlatformByName(argdict["platform"]) properties = { "CudaPrecision": argdict["precision"], "CudaDeviceIndex": "0" } # create simulation system: sim = Simulation(pdb.topology, system, integrator, platform, properties) # unit conversion factors: ang2nm = 0.1 # create MDA universe: u = mda.Universe(args.s, args.f) # selection for overall system will be needed to set OpenMM positions # accordingt to trajectory: allsystem = u.select_atoms("all") # get parameters to define cylinder around protein center of geometry: # (the cylinder spans the entire box in the z-direction) protein = u.select_atoms("protein") radius = str(args.r) z_margin = args.z_margin z_min = str(protein.bbox()[0, 2] - protein.center_of_geometry()[2] - z_margin) z_max = str(protein.bbox()[1, 2] - protein.center_of_geometry()[2] + z_margin) # select all solvent atoms, note that AMOEBA residue name is HOH: # (these must be updating, as water may move in and out of pore!) solvent = u.select_atoms("byres (resname HOH SOL) and cyzone " + radius + " " + z_max + " " + z_min + " protein", updating=True) solvent_ow = solvent.select_atoms("name O OW", updating=True) # lambda function for converting atomic dipoles to molecular dipoles: # (this only works on 1D arrays, hence use apply_along_axis if quantity is # vector-valued, e.g. positions and dipoles) def atomic2molecular_sum(arr): return np.bincount(allsystem.resindices, arr) def atomic2molecular_avg(arr): return np.bincount(allsystem.resindices, arr) / np.bincount( allsystem.resindices) # create lambda function for obtaining charges in vectorisable way: # (units are elementary_charge) get_atomic_charges = np.vectorize( lambda index: multipole_force.getMultipoleParameters(int(index))[ 0].value_in_unit(elementary_charge)) # obtain atomic charges: # (charges are static, so need this only once; units are elementary charge) atomic_charges = get_atomic_charges(allsystem.ix) # obtain start and end time as will as time step: dt = float(args.dt) t_start = float(args.b) t_end = float(args.e) # prepare results dictionary: res = { "t": [], "x": [], "y": [], "z": [], "indu_rho": [], "indu_costheta": [], "indu_cosphi": [], "perm_rho": [], "perm_costheta": [], "perm_cosphi": [], "mono_rho": [], "mono_costheta": [], "mono_cosphi": [], "total_rho": [], "total_costheta": [], "total_cosphi": [] } # loop over trajectory: for ts in u.trajectory: # skip all frames before starting frame: if ts.time < t_start: continue # only analyse relevant time frames: if round(ts.time, 4) % dt == 0: # inform user: print("analysing frame: " + str(ts.frame) + " at time: " + str(ts.time)) print("number of selected solvent molecules in this frame: " + str(solvent.n_residues)) # convert mda positions to OpenMM positions and set context: omm_positions = Quantity( [tuple(pos) for pos in list(allsystem.positions)], unit=angstrom) sim.context.setPositions(omm_positions) # calculate molecular positions (or molecular centre of geometry) by # averaging over all atomic positions within a residue: # (units are Angstrom in MDAnalysis!) molecular_positions = np.apply_along_axis( atomic2molecular_avg, 0, allsystem.positions) * ang2nm # calculate charge-weighted positions by multiplying the relative # atomic positions with the atomic charges (relative positions are # necessary to account for charged residues/molecules, where the # dipole moment is calculated relative to the center of geometry of # the residue): # (units are elementary charge * nanometer) atomic_charge_weighted_positions = ( allsystem.positions - molecular_positions[allsystem.resindices]) atomic_charge_weighted_positions *= (atomic_charges[np.newaxis].T * ang2nm) # obtain induced and permanent atomic dipoles from OpenMM: # (units are elementary charge * nm) atomic_dipoles_indu = np.array( multipole_force.getInducedDipoles(sim.context)) atomic_dipoles_perm = np.array( multipole_force.getLabFramePermanentDipoles(sim.context)) # convert atomic to molecular quantities and calculate total dipole: molecular_dipoles_indu = np.apply_along_axis( atomic2molecular_sum, 0, atomic_dipoles_indu) molecular_dipoles_perm = np.apply_along_axis( atomic2molecular_sum, 0, atomic_dipoles_perm) molecular_dipoles_mono = np.apply_along_axis( atomic2molecular_sum, 0, atomic_charge_weighted_positions) molecular_dipoles_total = (molecular_dipoles_indu + molecular_dipoles_perm + molecular_dipoles_mono) # convert to spherical coordinates: molecular_dipoles_indu = cartesian2spherical( molecular_dipoles_indu) molecular_dipoles_perm = cartesian2spherical( molecular_dipoles_perm) molecular_dipoles_mono = cartesian2spherical( molecular_dipoles_mono) molecular_dipoles_total = cartesian2spherical( molecular_dipoles_total) # insert into results dictionary: res["t"].append(np.repeat(ts.time, solvent.n_residues)) res["x"].append(molecular_positions[solvent_ow.resindices, 0]) res["y"].append(molecular_positions[solvent_ow.resindices, 1]) res["z"].append(molecular_positions[solvent_ow.resindices, 2]) res["indu_rho"].append( molecular_dipoles_indu[solvent_ow.resindices, 0]) res["indu_costheta"].append( molecular_dipoles_indu[solvent_ow.resindices, 1]) res["indu_cosphi"].append( molecular_dipoles_indu[solvent_ow.resindices, 2]) res["perm_rho"].append( molecular_dipoles_perm[solvent_ow.resindices, 0]) res["perm_costheta"].append( molecular_dipoles_perm[solvent_ow.resindices, 1]) res["perm_cosphi"].append( molecular_dipoles_perm[solvent_ow.resindices, 2]) res["mono_rho"].append( molecular_dipoles_mono[solvent_ow.resindices, 0]) res["mono_costheta"].append( molecular_dipoles_mono[solvent_ow.resindices, 1]) res["mono_cosphi"].append( molecular_dipoles_mono[solvent_ow.resindices, 2]) res["total_rho"].append( molecular_dipoles_total[solvent_ow.resindices, 0]) res["total_costheta"].append( molecular_dipoles_total[solvent_ow.resindices, 1]) res["total_cosphi"].append( molecular_dipoles_total[solvent_ow.resindices, 2]) # stop iterating through trajectory after end time: if ts.time > t_end: break # convert lists of arrays to arrays: for k in res.keys(): res[k] = np.concatenate(res[k]) # convert units of dipole magnitude to Debye: eNm2debye = 48.03205 res["indu_rho"] = eNm2debye * res["indu_rho"] res["perm_rho"] = eNm2debye * res["perm_rho"] res["mono_rho"] = eNm2debye * res["mono_rho"] res["total_rho"] = eNm2debye * res["total_rho"] # load spline curve data: with open(args.j, "r") as f: chap_data = json.load(f) # create spline curve from CHAP data: spline_curve = BSplineCurve(chap_data) # calculate s-coordinate from z-coordinate: res["s"] = spline_curve.z2s(res["z"]) # convert results to data frame: df_res = pd.DataFrame(res) # loop over various numbers of bins: df = [] for nbins in args.nbins: # create a temporary data frame: tmp = df_res # drop positional coordinates: tmp = tmp.drop(["x", "y", "z", "t"], axis=1) # bin by value of s-coordinate: tmp = tmp.groupby(pd.cut(tmp.s, nbins)) # aggregate variables: tmp = tmp.agg([np.mean, np.std, sem, np.size, np.median, qlo, qhi]).reset_index() # rename columns (combines variable name with aggregation method): tmp.columns = ["_".join(x) for x in tmp.columns.ravel()] # remove grouping key: tmp = tmp.drop("s_", axis=1) # add column wit number of bins: tmp["nbins"] = nbins # append to list of data frames: df.append(tmp) # combine list of data frames into single data frame: df = pd.concat(df) # write to JSON file: df.to_json(args.o, orient="records") # need to add newline for POSIX compliance: with open(args.o, "a") as f: f.write("\n")
def langevin_NVT(item, time = None, saving_timestep = None, integration_timestep= 2*unit.femtoseconds, friction=1.0/unit.picoseconds, temperature=300.0*unit.kelvin, initial_coordinates=None, initial_velocities=None, platform_name='CUDA', reporters=None, tqdm=True): """Newtonian classical dynamics of a molecular system with OpenMM. The trajectory of a newtonian classical dynamics of a molecular system is obtained together with the values of potential and kinetic energy. This method is nothing but a short cut to run quick molecular dynamics with the test systems of this library by means of OpenMM. Parameters ---------- system: simtk.openmm.System Molecular system as a system class of OpenMM (see: link) friction: unit.Quantity Damping parameter of the Langevin dynamics (in units of 1/time). initial_coordinates: unit.Quantity Initial coordinates of the system as a numpy array with shape [n_particles, 3] and units of length. Where 'n_particles' is the number of particles of the system. initial_velocities: unit.Quantity Initial velocities of the system as a numpy array with shape [n_particles, 3] and units of length/time. Where 'n_particles' is the number of particles of the system. integration_timestep: unit.Quantity Time step used by the integrator of the equations of motion. The parameter needs to have units of time. saving_timestep: unit.Quantity Time step used to report the output trajectory. The parameter needs to have units of time. total_time: unit.Quantity Total runing time of the simulation. The parameter needs to have units of time. platform_name: str (default: 'CPU') Platform to run the dynamics: 'CPU', 'OPENCL' or 'CUDA' (according to those options to run OpenMM, see documentation), verbose: bool (default: True) Verbose switcher. The method will print out information if the value is True. Returns ------- time: unit.Quantity Time as numpy array of shape [n_frames] with units of picoseconds. position: unit.Quantity Positions of the systems particles in every reported frame as numpy array of shape [n_frames, n_particles, 3] with units of nanometers. velocity: unit.Quantity Velocities of the systems particles in every reported frame as numpy array of shape [n_frames, n_particles, 3] with units of nanometers/picoseconds. kinetic_energy: unit.Quantity Kinetic energy of the system in every reported frame as numpy array of shape [n_frames] with units of kilocalories/mole. potential_energy: unit.Quantity Potential energy of the system in every reported frame as numpy array of shape [n_frames] with units of kilocalories/mole. Examples -------- >>> from uibcdf_test_systems import DoubleWell >>> from uibcdf_test_systems.simulation import newtonian >>> from simtk import unit >>> double_well = DoubleWell(n_particles = 1, mass = 64 * unit.amu, Eo=4.0 * unit.kilocalories_per_mole, a=1.0 * unit.nanometers, b=0.0 * unit.kilocalories_per_mole)) >>> initial_coordinates = np.zeros([1, 3], np.float32) * unit.nanometers >>> initial_velocities = np.zeros([1, 3], np.float32) * unit.nanometers/unit.picoseconds >>> initial_coordinates[0,0] = 1.0 * unit.nanometers >>> time, position, velocity, kinetic_energy, potential_energy = langevin_NVT(double_well, >>> friction = 0.1/unit.picoseconds, >>> initial_coordinates = initial_coordinates, >>> initial_velocities = initial_velocities, >>> integration_timestep = 0.02 * unit.picoseconds, >>> saving_timestep = 0.5 * unit.picoseconds, >>> total_time = 100 * unit.picoseconds) Notes ----- See the `corresponding documentation in the user guide regarding this method <../../simulations/newtonian.html>`_. Some simple examples on how this method is used can be found in the users guide sections corresponding to `the free particle <../../systems/free_particle.html>`_, `the harmonic well potential <../../systems/harmonic_well_potential.html>`_ or `the double well potential <../../systems/double_well_potential.html>`_. """ from simtk.openmm import LangevinIntegrator, Platform, Context from simtk import unit import numpy as np # System parameters. n_particles = item.system.getNumParticles() # Integrator. integrator = LangevinIntegrator(temperature, friction, integration_timestep) # Platform. platform = Platform.getPlatformByName(platform_name) # Simulation. simulation = Simulation(item.topology, item.system, integrator, platform) # Initial Context. if initial_coordinates is None: initial_coordinates = item.coordinates simulation.context.setPositions(initial_coordinates) if initial_velocities=='zeros' or initial_velocities is None: initial_velocities = np.zeros([n_particles, 3], np.float32) * unit.nanometers/unit.picosecond simulation.context.setVelocities(initial_velocities) elif initial_velocities=='boltzmann': simulation.context.setVelocitiesToTemperature(temperature) else: simulation.context.setVelocities(initial_velocities) # Reporters. default_reporter = False tqdm_reporter = False if reporters is None: reporters = [] if saving_timestep is not None and len(reporters)==0: saving_steps_interval = int(saving_timestep/integration_timestep) default_reporter = MolSysMTTrajectoryDictReporter(saving_steps_interval, time=True, coordinates=True, potentialEnergy=True, kineticEnergy=True, box=True) reporters.append(default_reporter) for reporter in reporters: simulation.reporters.append(reporter) # Initial report initial_state = simulation.context.getState(getEnergy=True, getPositions=True, getVelocities=True) for reporter in reporters: reporter.report(simulation, initial_state) n_steps = int(time/integration_timestep) if tqdm: tqdm_reporter = TQDMReporter(100, n_steps) simulation.reporters.append(tqdm_reporter) simulation.step(n_steps) if tqdm_reporter: tqdm_reporter.finalize() if default_reporter: return default_reporter.finalize() else: pass
def remove_molecules(self, simulation_old, system_options, ensemble_options): topology_old = simulation_old.topology system_old = simulation_old.system state = simulation_old.context.getState(getPositions=True, getVelocities=True) positions_old = state.getPositions(asNumpy=True) velocities_old = state.getVelocities(asNumpy=True) periodic_box_vectors = state.getPeriodicBoxVectors(asNumpy=True) # randomly determine which molecules are removed removed_molecules = random.sample(range(topology_old.getNumChains()), self.numVoid) # create new topology and dictionary mapping old atom indices to new atom indices removed_atoms = [] topology_new = Topology() old_to_new = {} atom_index_new = 0 for chain_index, chain_old in enumerate(topology_old.chains()): if chain_index not in removed_molecules: chain_id = chain_old.id.split('-', 1)[-1] chain_new = topology_new.addChain(id="{}-{}".format(topology_new.getNumChains()+1, chain_id)) for residue_old in chain_old.residues(): residue_new = topology_new.addResidue(residue_old.name, chain_new) for atom_old in residue_old.atoms(): topology_new.addAtom(atom_old.name, atom_old.element, residue_new) old_to_new[atom_old.index] = atom_index_new atom_index_new += 1 else: for atom_old in chain_old.atoms(): removed_atoms.append(atom_old.index) # add bonds to new topology atoms_new = list(topology_new.atoms()) for bond_old in topology_old.bonds(): atom1_index_old = bond_old[0].index atom2_index_old = bond_old[1].index try: atom1_new = atoms_new[old_to_new[atom1_index_old]] atom2_new = atoms_new[old_to_new[atom2_index_old]] topology_new.addBond(atom1_new, atom2_new) except KeyError: pass # set box vectors for topology topology_new.setPeriodicBoxVectors(periodic_box_vectors) # create system system_new = system_options.create_system_with_new_topology(topology_new) # check if old system had barostat and add to new system if applicable if self._has_barostat(system_old): barostat_old = self._get_barostat(system_old) defaultPressure = barostat_old.getDefaultPressure() defaultTemperature = barostat_old.getDefaultTemperature() frequency = barostat_old.getFrequency() if isinstance(barostat_old, MonteCarloAnisotropicBarostat): scaleX = barostat_old.getScaleX() scaleY = barostat_old.getScaleY() scaleZ = barostat_old.getScaleZ() barostat_new = MonteCarloAnisotropicBarostat(defaultPressure, defaultTemperature, scaleX, scaleY, scaleZ, frequency) else: barostat_new = MonteCarloBarostat(defaultPressure, defaultTemperature, frequency) system_new.addForce(barostat_new) barostat_new.setForceGroup(system_new.getNumForces() - 1) # create integrator integrator = ensemble_options.create_integrator() # create new positions and velocities arrays positions_new = np.delete(positions_old, removed_atoms, axis=0) velocities_new = np.delete(velocities_old, removed_atoms, axis=0) # create new simulation simulation_new = Simulation(topology_new, system_new, integrator) simulation_new.context.setPositions(positions_new) simulation_new.context.setVelocities(velocities_new) simulation_new.context.setPeriodicBoxVectors(*periodic_box_vectors) # move reporters from old simulation to new simulation while simulation_old.reporters: simulation_new.reporters.append(simulation_old.reporters.pop(0)) # create pdb file if specified if self.file is not None: PDBFile.writeFile(topology_new, positions_new, open(self.file, 'w')) return simulation_new
def simulate(self, header, content): """Main method that is "executed" by the receipt of the msg_type == 'simulate' message from the server. We run some OpenMM dynamics, and then send back the results. """ self.log.info('Setting up simulation...') state, topology = self.deserialize_input(content) # set the GPU platform platform = Platform.getPlatformByName(str(self.platform)) if self.platform == 'CUDA': properties = {'CudaPrecision': 'mixed', 'CudaDeviceIndex': str(self.device_index) } elif self.platform == 'OpenCL': properties = {'OpenCLPrecision': 'mixed', 'OpenCLDeviceIndex': str(self.device_index) } else: properties = None simulation = Simulation(topology, self.system, self.integrator, platform, properties) # do the setup self.set_state(state, simulation) self.sanity_check(simulation) if self.minimize: self.log.info('minimizing...') simulation.minimizeEnergy() if self.random_initial_velocities: try: temp = simulation.integrator.getTemperature() simulation.context.setVelocitiesToTemperature(temp) except AttributeError: print "I don't know what temperature to use!!" # TODO: look through the system's forces to find an andersen # thermostate? raise pass assert content.output.protocol == 'localfs', "I'm currently only equiped for localfs output" self.log.info('adding reporters...') self.add_reporters(simulation, content.output.path) # run dynamics! self.log.info('Starting dynamics') simulation.step(self.number_of_steps) for reporter in simulation.reporters: # explicitly delete the reporters so that any open file handles # are closed. del reporter # tell the master that I'm done self.send_recv(msg_type='simulation_done', content={ 'status': 'success', 'output': { 'protocol': 'localfs', 'path': content.output.path } })
def test_improper_recover(): from simtk import openmm, unit from simtk.openmm.app import Simulation from simtk.unit import Quantity TEMPERATURE = 500 * unit.kelvin STEP_SIZE = 1 * unit.femtosecond COLLISION_RATE = 1 / unit.picosecond system, topology, g = _create_impropers_only_system() # use langevin integrator, although it's not super useful here integrator = openmm.LangevinIntegrator( TEMPERATURE, COLLISION_RATE, STEP_SIZE ) # initialize simulation simulation = Simulation( topology=topology, system=system, integrator=integrator ) import openff.toolkit # get conformer g.mol.generate_conformers( toolkit_registry=openff.toolkit.utils.RDKitToolkitWrapper(), ) # put conformer in simulation simulation.context.setPositions(g.mol.conformers[0]) # minimize energy simulation.minimizeEnergy() # set velocities simulation.context.setVelocitiesToTemperature(TEMPERATURE) samples = [] us = [] # loop through number of samples for _ in range(10): # run MD for `self.n_steps_per_sample` steps simulation.step(10) # append samples to `samples` samples.append( simulation.context.getState(getPositions=True) .getPositions(asNumpy=True) .value_in_unit(esp.units.DISTANCE_UNIT) ) us.append( simulation.context.getState(getEnergy=True) .getPotentialEnergy() .value_in_unit(esp.units.ENERGY_UNIT) ) # put samples into an array samples = np.array(samples) us = np.array(us) # put samples into tensor samples = torch.tensor(samples, dtype=torch.float32) us = torch.tensor(us, dtype=torch.float32)[None, :, None] g.heterograph.nodes["n1"].data["xyz"] = samples.permute(1, 0, 2) # require gradient for force matching g.heterograph.nodes["n1"].data["xyz"].requires_grad = True g.heterograph.nodes["g"].data["u_ref"] = us # parametrize layer = esp.nn.dgl_legacy.gn() net = torch.nn.Sequential( esp.nn.Sequential(layer, [32, "tanh", 32, "tanh", 32, "tanh"]), esp.nn.readout.janossy.JanossyPoolingImproper( in_features=32, config=[32, "tanh"], out_features={ "k": 6, }, ), esp.mm.geometry.GeometryInGraph(), esp.mm.energy.EnergyInGraph(terms=["n4_improper"]), ) optimizer = torch.optim.Adam(net.parameters(), 1e-3) for _ in range(1500): optimizer.zero_grad() net(g.heterograph) u_ref = g.nodes["g"].data["u"] u = g.nodes["g"].data["u_ref"] loss = torch.nn.MSELoss()(u_ref, u) loss.backward() print(loss) optimizer.step() assert loss.detach().numpy().item() < 0.1
print('System has %d atoms' % modeller.topology.getNumAtoms()) with open(output_complex, 'w') as outfile: PDBFile.writeFile(modeller.topology, modeller.positions, outfile) # Create the system using the SystemGenerator system = system_generator.create_system(modeller.topology, molecules=ligand_mol) integrator = LangevinIntegrator(temperature, 1 / unit.picosecond, 0.002 * unit.picoseconds) system.addForce( openmm.MonteCarloBarostat(1 * unit.atmospheres, temperature, 25)) print('Default Periodic box:', system.getDefaultPeriodicBoxVectors()) simulation = Simulation(modeller.topology, system, integrator, platform=platform) context = simulation.context context.setPositions(modeller.positions) print('Minimising ...') simulation.minimizeEnergy() # Write out the minimised PDB. The 'enforcePeriodicBox=False' bit is important otherwise the different # components can end up in different periodic boxes resulting in really strange looking output. with open(output_min, 'w') as outfile: PDBFile.writeFile( modeller.topology, context.getState(getPositions=True, enforcePeriodicBox=False).getPositions(), file=outfile,
def test_reporter(tmpdir, get_fn): pdb = PDBFile(get_fn('native.pdb')) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') # NO PERIODIC BOUNDARY CONDITIONS system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) hdf5file = os.path.join(tmpdir, 'traj.h5') ncfile = os.path.join(tmpdir, 'traj.nc') dcdfile = os.path.join(tmpdir, 'traj.dcd') xtcfile = os.path.join(tmpdir, 'traj.xtc') reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True, cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True, velocities=True) reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True) reporter3 = DCDReporter(dcdfile, 2) reporter4 = XTCReporter(xtcfile, 2) simulation.reporters.append(reporter) simulation.reporters.append(reporter2) simulation.reporters.append(reporter3) simulation.reporters.append(reporter4) simulation.step(100) reporter.close() reporter2.close() reporter3.close() reporter4.close() with HDF5TrajectoryFile(hdf5file) as f: got = f.read() eq(got.temperature.shape, (50,)) eq(got.potentialEnergy.shape, (50,)) eq(got.kineticEnergy.shape, (50,)) eq(got.coordinates.shape, (50, 22, 3)) eq(got.velocities.shape, (50, 22, 3)) eq(got.cell_lengths, None) eq(got.cell_angles, None) eq(got.time, 0.002 * 2 * (1 + np.arange(50))) assert f.topology == md.load(get_fn('native.pdb')).top with NetCDFTrajectoryFile(ncfile) as f: xyz, time, cell_lengths, cell_angles = f.read() eq(cell_lengths, None) eq(cell_angles, None) eq(time, 0.002 * 2 * (1 + np.arange(50))) hdf5_traj = md.load(hdf5file) dcd_traj = md.load(dcdfile, top=get_fn('native.pdb')) netcdf_traj = md.load(ncfile, top=get_fn('native.pdb')) xtc_traj = md.load(xtcfile, top=get_fn('native.pdb')) # we don't have to convert units here, because md.load already # handles that assert hdf5_traj.unitcell_vectors is None eq(hdf5_traj.xyz, netcdf_traj.xyz) eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors) eq(hdf5_traj.time, netcdf_traj.time) eq(xtc_traj.time, netcdf_traj.time) eq(dcd_traj.xyz, hdf5_traj.xyz) eq(xtc_traj.xyz, dcd_traj.xyz, decimal=3)
def test_reporter_subset(tmpdir, get_fn): pdb = PDBFile(get_fn('native2.pdb')) pdb.topology.setUnitCellDimensions([2, 2, 2]) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffPeriodic, nonbondedCutoff=1 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) hdf5file = os.path.join(tmpdir, 'traj.h5') ncfile = os.path.join(tmpdir, 'traj.nc') dcdfile = os.path.join(tmpdir, 'traj.dcd') xtcfile = os.path.join(tmpdir, 'traj.xtc') atomSubset = [0, 1, 2, 4, 5] reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True, cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True, velocities=True, atomSubset=atomSubset) reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True, atomSubset=atomSubset) reporter3 = DCDReporter(dcdfile, 2, atomSubset=atomSubset) reporter4 = XTCReporter(xtcfile, 2, atomSubset=atomSubset) simulation.reporters.append(reporter) simulation.reporters.append(reporter2) simulation.reporters.append(reporter3) simulation.reporters.append(reporter4) simulation.step(100) reporter.close() reporter2.close() reporter3.close() reporter4.close() t = md.load(get_fn('native.pdb')) t.restrict_atoms(atomSubset) with HDF5TrajectoryFile(hdf5file) as f: got = f.read() eq(got.temperature.shape, (50,)) eq(got.potentialEnergy.shape, (50,)) eq(got.kineticEnergy.shape, (50,)) eq(got.coordinates.shape, (50, len(atomSubset), 3)) eq(got.velocities.shape, (50, len(atomSubset), 3)) eq(got.cell_lengths, 2 * np.ones((50, 3))) eq(got.cell_angles, 90 * np.ones((50, 3))) eq(got.time, 0.002 * 2 * (1 + np.arange(50))) assert f.topology == md.load(get_fn('native.pdb'), atom_indices=atomSubset).topology with NetCDFTrajectoryFile(ncfile) as f: xyz, time, cell_lengths, cell_angles = f.read() eq(cell_lengths, 20 * np.ones((50, 3))) eq(cell_angles, 90 * np.ones((50, 3))) eq(time, 0.002 * 2 * (1 + np.arange(50))) eq(xyz.shape, (50, len(atomSubset), 3)) hdf5_traj = md.load(hdf5file) dcd_traj = md.load(dcdfile, top=hdf5_traj) netcdf_traj = md.load(ncfile, top=hdf5_traj) xtc_traj = md.load(xtcfile, top=hdf5_traj) # we don't have to convert units here, because md.load already handles that eq(hdf5_traj.xyz, netcdf_traj.xyz) eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors) eq(hdf5_traj.time, netcdf_traj.time) eq(xtc_traj.time, netcdf_traj.time) eq(dcd_traj.xyz, hdf5_traj.xyz) eq(xtc_traj.xyz, hdf5_traj.xyz) eq(dcd_traj.unitcell_vectors, hdf5_traj.unitcell_vectors)
argsrestart = args.path + '/iter' + str(iter_found) + '_restart' + str( i) + '.npz' savedcdfile = args.path + '/iter' + str(iter_found) + '_traj' + str( i) + '.dcd' savedcdfileextend = args.path + '/iter' + str(iter_found) + '_traj' + str( i) + 'extend.dcd' a_topology_pdb = args.path + '/iter' + str(iter_found) + '_input' + str( i) + '.pdb' a_platform = 'fastest' properties = None a_system_xml = 'system-5.xml' a_integrator_xml = 'integrator-5.xml' platform, pdb, (system_xml, system), (integrator_xml, integrator) \ = read_input(a_platform, a_topology_pdb, a_system_xml, a_integrator_xml) simulation = Simulation(pdb.topology, system, integrator, platform, properties) if i == args.idxstart: pdbtop = mdtraj.load(a_topology_pdb).topology print(pdbtop) prot_Select = pdbtop.select("protein") print("prot_Select", prot_Select) print('# platform used:', simulation.context.getPlatform().getName()) print('# platforms available') for no_platform in range(Platform.getNumPlatforms()): # noinspection PyCallByClass,PyTypeChecker print('(%d) %s' % (no_platform, Platform.getPlatform(no_platform).getName())) #print(os.environ) print(Platform.getPluginLoadFailures()) print(Platform.getDefaultPluginsDirectory()) simulation.context.setPositions(pdb.positions)
def test_reporter(tmpdir, get_fn): pdb = PDBFile(get_fn('native.pdb')) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') # NO PERIODIC BOUNDARY CONDITIONS system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) hdf5file = os.path.join(tmpdir, 'traj.h5') ncfile = os.path.join(tmpdir, 'traj.nc') dcdfile = os.path.join(tmpdir, 'traj.dcd') reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True, cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True, velocities=True) reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True) reporter3 = DCDReporter(dcdfile, 2) simulation.reporters.append(reporter) simulation.reporters.append(reporter2) simulation.reporters.append(reporter3) simulation.step(100) reporter.close() reporter2.close() reporter3.close() with HDF5TrajectoryFile(hdf5file) as f: got = f.read() eq(got.temperature.shape, (50, )) eq(got.potentialEnergy.shape, (50, )) eq(got.kineticEnergy.shape, (50, )) eq(got.coordinates.shape, (50, 22, 3)) eq(got.velocities.shape, (50, 22, 3)) eq(got.cell_lengths, None) eq(got.cell_angles, None) eq(got.time, 0.002 * 2 * (1 + np.arange(50))) assert f.topology == md.load(get_fn('native.pdb')).top with NetCDFTrajectoryFile(ncfile) as f: xyz, time, cell_lengths, cell_angles = f.read() eq(cell_lengths, None) eq(cell_angles, None) eq(time, 0.002 * 2 * (1 + np.arange(50))) hdf5_traj = md.load(hdf5file) dcd_traj = md.load(dcdfile, top=get_fn('native.pdb')) netcdf_traj = md.load(ncfile, top=get_fn('native.pdb')) # we don't have to convert units here, because md.load already # handles that assert hdf5_traj.unitcell_vectors is None eq(hdf5_traj.xyz, netcdf_traj.xyz) eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors) eq(hdf5_traj.time, netcdf_traj.time) eq(dcd_traj.xyz, hdf5_traj.xyz)
print("OpenMM version:", version.version) # use heavy hydrogens and constrain all hygrogen atom-involved bonds system = prmtop.createSystem(nonbondedMethod=PME, rigidWater=True, nonbondedCutoff=1 * unit.nanometer, constraints = HBonds, removeCMMotion=False, hydrogenMass= 4 * unit.amu) system.addForce(MonteCarloBarostat(pressure, temperature)) # Set up the context for unbiased simulation integrator = mm.LangevinIntegrator(temperature, 1.0, 0.004) ## 4 fs time steps integrator.setRandomNumberSeed(trial) print(f"Random seed of this run is: {integrator.getRandomNumberSeed()}") platform = mm.Platform.getPlatformByName('OpenCL') print("Done specifying integrator and platform for simulation.") platform.setPropertyDefaultValue('Precision', 'mixed') print("Done setting the precision to mixed.") simulation = Simulation(prmtop.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) print("Done recording a context for positions.") context = simulation.context context.setVelocitiesToTemperature(temperature) print("Done assigning velocities.") storage_path = os.path.join(work_dir,'traj.nc') #potential_path = os.path.join(work_dir,'potential.txt') simulation.reporters.append(NetCDFReporter(storage_path, reportInterval=250000, coordinates=True)) #simulation.reporters.append(StateDataReporter(potential_path, 1, step=True, potentialEnergy=True)) print("Done specifying simulation.") simulation.step(steps) # Serialize state print('Serializing state to state.xml...') state = context.getState(getPositions=True, getVelocities=True, getEnergy=True, getForces=True)
value = getattr(args, v.lower()) if value: properties[args.platform + '_' + v.replace('_', '')] = value # Randomizes the order of file reading to # alleviate traffic from synchronization platform, pdb, (system_xml, system), (integrator_xml, integrator) \ = read_input(args.platform, args.topology_pdb, args.system_xml, args.integrator_xml) print('Done') print('Initialize Simulation') try: simulation = Simulation(pdb.topology, system, integrator, platform, properties) print("SIMULATION: ", simulation) except Exception: print('EXCEPTION', (socket.gethostname())) raise print('Done.') print('# platform used:', simulation.context.getPlatform().getName()) if args.verbose: print('# platforms available') for no_platform in range(Platform.getNumPlatforms()): # noinspection PyCallByClass,PyTypeChecker print('(%d) %s' %
dt = 4.0 * unit.femtoseconds Temp = 298.15 * unit.kelvin Pres = 1.01325 * unit.bar out_freq = 2500 print_freq = 50000 MD_steps = 12500000 bar_freq = int(MD_steps / print_freq) integrator = LangevinIntegrator(Temp, 1.0 / unit.picoseconds, dt) barostat = MonteCarloBarostat(Pres, Temp, 100) system.addForce(barostat) # Simulation Object simulation = Simulation(coords.topology, system, integrator, Platform.getPlatformByName('CUDA'), { 'CudaDeviceIndex': '0', 'CudaPrecision': 'single' }) simulation.context.setPositions(coords.positions) simulation.reporters.append( DCDReporter(os.path.join('simulations', 'npt_production', 'test.dcd'), out_freq, False)) simulation.reporters.append( StateDataReporter( os.path.join('simulations', 'npt_production', 'test.log'), out_freq, step=True, kineticEnergy=True, potentialEnergy=True, totalEnergy=True,