def export_frame_coordinates(topology, trajectory, nframe, output=None): """ Extract a single frame structure from a trajectory. """ if output is None: basename, ext = os.path.splitext(trajectory) output = '{}.frame{}.inpcrd'.format(basename, nframe) # ParmEd sometimes struggles with certain PRMTOP files if os.path.splitext(topology)[1] in ('.top', '.prmtop'): top = AmberPrmtopFile(topology) mdtop = mdtraj.Topology.from_openmm(top.topology) traj = mdtraj.load_frame(trajectory, int(nframe), top=mdtop) structure = parmed.openmm.load_topology(top.topology, system=top.createSystem()) structure.box_vectors = top.topology.getPeriodicBoxVectors() else: # standard protocol (the topology is loaded twice, though) traj = mdtraj.load_frame(trajectory, int(nframe), top=topology) structure = parmed.load_file(topology) structure.positions = traj.openmm_positions(0) if traj.unitcell_vectors is not None: # if frame provides box vectors, use those structure.box_vectors = traj.openmm_boxes(0) structure.save(output, overwrite=True)
def __init__(self, ff_type=None, system_file=None, **kwargs): """Two pathways can be used starting from FF-specific files or OpenMM XML system. Additional kwargs are variously used depending on the forcefield / pathway that was chosen. supported ff_type ----------------- amber :: give a prmtop and an inpcrd openmm :: give an XML file for the system supported kwargs ---------------- topology :: system-specific or not depending on FF coordinates :: source of coordinates for initial state """ assert (ff_type is None) or (system_file is None) # This dict will store the API calls # along with atom groups and force # parameters needed to generate all # the given restraints self._restraints = dict() self._topology = None topofile = kwargs.get("topology", None) coordfile = kwargs.get("coordinates", None) if ff_type is not None: if ff_type.lower() == "amber": prmtop = AmberPrmtopFile(topofile) inpcrd = AmberInpcrdFile(coordfile) self.system = prmtop.createSystem( nonbondedMethod=NoCutoff ) #CutoffNonPeriodic - according to Ada, this would be good bc its what amber does - preliminary tests show that this hurts small/medium proteins self._topology = Topology.from_openmm(prmtop.topology) self._positions = inpcrd elif system_file is not None: self.load_xml(system_file) if topofile: if topofile.endswith(".pdb"): # this line is a bit silly but Topology class # doesn't seem to directly load PDB so keeps # the imports clean self._topology = Topology.from_openmm( PDBFile(topofile).topology) else: # Inspect and set ff_type # TODO ff_type as instance attribute pass
class OpenMMAmberPotential(BasePotential): """ OpenMM V(r) = Amber """ 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 copyToLocalCoords(self, coords): """ copy to local coords -- deprecated """ # copy to local coords for i in range(self.natoms): self.localCoords[i] = Vec3(coords[3*i], coords[3*i+1] , coords[3*i+2] ) # ''' ------------------------------------------------------------------- ''' def getEnergy(self, coords): """ returns energy in kcal/mol """ # using unit.Quantity is 5 times faster than calling copyToLocalCoords! coordinates = unit.Quantity( coords.reshape(self.natoms,3) , angstrom) self.simulation.context.setPositions( coordinates ) # attach units to coordinates before computing energy self.simulation.context.setPositions(coordinates) potE = self.simulation.context.getState(getEnergy=True).getPotentialEnergy() # remove units from potE and then convert to kcal/mol to be consistent with GMIN return potE / kilojoules_per_mole / self.kJtokCal #''' ------------------------------------------------------------------- ''' def getEnergyGradient(self, coords): """ returns energy and gradient in kcal/mol and kcal/mol/angstrom""" coordinates = unit.Quantity( coords.reshape(self.natoms,3) , angstrom) self.simulation.context.setPositions( coordinates ) # get pot energy potE = self.simulation.context.getState(getEnergy=True).getPotentialEnergy() E = potE / kilojoules_per_mole /self.kJtokCal # get forces forcee = self.simulation.context.getState(getForces=True).getForces(asNumpy=True) # xply to -1 to convert gradient ; divide by 10 to convert to kJ/mol/angstroms grad = -forcee / ( kilojoules_per_mole / nanometer ) / 10 / self.kJtokCal # todo - 10 is hardcoded # remove units before returning return E, grad.reshape(-1)
#from sys import stdout # energy from GMIN GMIN.initialize() # reads coords.inpcrd and coords.prmtop pot = gminpot.GMINPotential(GMIN) coords = pot.getCoords() enerGmin = pot.getEnergy(coords)*4.184 # ----- 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()
""" from __future__ import print_function # 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
experiment = 'p18_CDK6_hcyclinD_CRBN' receptor = 'CDK6' ligand = '03123' trial = 0 work_dir = f'/home/guoj1/data_projects/BSJ_inhibitors/fresh_simulations/{experiment}/h_{ligand}_long{trial}' temperature = 400.15 * unit.kelvin pressure = 1.0 * unit.atmospheres steps = 250000000 ## 1000 ns # load prm or crd files of the minimized and equilibrated protein prmtop = AmberPrmtopFile(f'../03123_long0/complex_prep/02.ante.tleap/{ligand}_{receptor}.com.wat.leap.prmtop') pdb = PDBFile(f'../03123_long0/{ligand}_{receptor}_holo_equi.pdb') 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
class OpenMMAmberPotential(BasePotential): """ OpenMM V(r) = Amber """ 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 copyToLocalCoords(self, coords): """ copy to local coords -- deprecated """ # copy to local coords for i in range(self.natoms): self.localCoords[i] = Vec3(coords[3 * i], coords[3 * i + 1], coords[3 * i + 2]) # ''' ------------------------------------------------------------------- ''' def getEnergy(self, coords): """ returns energy in kcal/mol """ # using unit.Quantity is 5 times faster than calling copyToLocalCoords! coordinates = unit.Quantity(coords.reshape(self.natoms, 3), angstrom) self.simulation.context.setPositions(coordinates) # attach units to coordinates before computing energy self.simulation.context.setPositions(coordinates) potE = self.simulation.context.getState( getEnergy=True).getPotentialEnergy() # remove units from potE and then convert to kcal/mol to be consistent with GMIN ee = potE / kilojoules_per_mole / self.kJtokCal return float(ee) # ''' ------------------------------------------------------------------- ''' def getEnergyGradient(self, coords): """ returns energy and gradient in kcal/mol and kcal/mol/angstrom""" coordinates = unit.Quantity(coords.reshape(self.natoms, 3), angstrom) self.simulation.context.setPositions(coordinates) # get pot energy potE = self.simulation.context.getState( getEnergy=True).getPotentialEnergy() E = potE / kilojoules_per_mole / self.kJtokCal # get forces forcee = self.simulation.context.getState(getForces=True).getForces( asNumpy=True) # xply to -1 to convert gradient ; divide by 10 to convert to kJ/mol/angstroms grad = -forcee / (kilojoules_per_mole / nanometer ) / 10 / self.kJtokCal # todo - 10 is hardcoded # remove units before returning grad = np.array(grad, dtype=float) return float(E), grad.reshape(-1)
atom_indxs += [atom.index for atom in trj.top.atoms if atom.residue.resSeq == ref] ri = np.array(atom_indxs) wi = np.array([atom.index for atom in trj.topology.atoms if (atom.residue.is_water and (atom.element.symbol == 'O'))]) ki = np.array([i.index for i in trj.top.atoms_by_name('K+')]) all_i = np.concatenate((ri,wi,ki)) table, bonds = trj.topology.to_dataframe() data = table.T[all_i].T return data start_time = time.time() prmtop = AmberPrmtopFile(args.prmtop) platform = mm.Platform.getPlatformByName('CPU') system = prmtop.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=2.0*unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005) system.addForce(mm.MonteCarloBarostat(1*unit.atmospheres, 300*unit.kelvin)) integrator = mm.LangevinIntegrator(300*unit.kelvin, 1.0/unit.picoseconds, 2.0*unit.femtoseconds) integrator.setConstraintTolerance(0.00001) simulation = app.Simulation(prmtop.topology, system, integrator, platform) trj = mdtraj.load(args.trj, top=args.prmtop) datumz = [] for tndx, frame in enumerate(trj): if tndx == 0: indices = relevant_indices(frame) num_indx = indices.index