def setup_fah_run(destination_path, protein_pdb_filename, oemol=None, cache=None, restrain_rmsd=False, biounit='monomer'): """ Prepare simulation Parameters ---------- destination_path : str The path to the RUN to be created protein_pdb_filename : str Path to protein PDB file oemol : openeye.oechem.OEMol, optional, default=None The molecule to parameterize, with SDData attached If None, don't include the small molecule restrain_rmsd : bool, optional, default=False If True, restrain RMSD during first equilibration phase biounit : str, optional, default='monomer' 'monomer' or 'dimer' """ # Parameters from simtk import unit, openmm protein_forcefield = 'amber14/protein.ff14SB.xml' solvent_forcefield = 'amber14/tip3p.xml' small_molecule_forcefield = 'openff-1.3.0' water_model = 'tip3p' solvent_padding = 10.0 * unit.angstrom ionic_strength = 70 * unit.millimolar # assay buffer: 20 mM HEPES pH 7.3, 1 mM TCEP, 50 mM NaCl, 0.01% Tween-20, 10% glycerol pressure = 1.0 * unit.atmospheres collision_rate = 1.0 / unit.picoseconds temperature = 300.0 * unit.kelvin timestep = 4.0 * unit.femtoseconds iterations = 1000 # 1 ns equilibration nsteps_per_iteration = 250 nsteps_per_snapshot = 250000 # 1 ns nsnapshots_per_wu = 20 # number of snapshots per WU # Prepare phases import os system_xml_filename = os.path.join(destination_path, 'system.xml.bz2') integrator_xml_filename = os.path.join(destination_path, 'integrator.xml.bz2') state_xml_filename = os.path.join(destination_path, 'state.xml.bz2') # Check if we can skip setup openmm_files_exist = os.path.exists( system_xml_filename) and os.path.exists( state_xml_filename) and os.path.exists(integrator_xml_filename) if openmm_files_exist: return # Create barostat barostat = openmm.MonteCarloBarostat(pressure, temperature) # Create RUN directory if it does not yet exist os.makedirs(destination_path, exist_ok=True) # Load any molecule(s) molecule = None molecules = [] if oemol is not None: from openforcefield.topology import Molecule molecule = Molecule.from_openeye(oemol, allow_undefined_stereo=True) molecule.name = 'MOL' # Ensure residue is MOL print([res for res in molecule.to_topology().to_openmm().residues()]) molecules = [molecule] # Create SystemGenerator import os from simtk.openmm import app forcefield_kwargs = { 'removeCMMotion': False, 'hydrogenMass': 3.0 * unit.amu, 'constraints': app.HBonds, 'rigidWater': True } periodic_kwargs = { 'nonbondedMethod': app.PME, 'ewaldErrorTolerance': 2.5e-04 } forcefields = [protein_forcefield, solvent_forcefield] from openmmforcefields.generators import SystemGenerator openmm_system_generator = SystemGenerator( forcefields=forcefields, molecules=molecules, small_molecule_forcefield=small_molecule_forcefield, cache=cache, barostat=barostat, forcefield_kwargs=forcefield_kwargs, periodic_forcefield_kwargs=periodic_kwargs) # Read protein print(f'Reading protein from {protein_pdb_filename}...') pdbfile = app.PDBFile(protein_pdb_filename) modeller = app.Modeller(pdbfile.topology, pdbfile.positions) if oemol is not None: # Add small molecule to the system modeller.add(molecule.to_topology().to_openmm(), molecule.conformers[0]) # Extract protein and molecule chains and indices before adding solvent import mdtraj as md mdtop = md.Topology.from_openmm( modeller.topology) # excludes solvent and ions protein_atom_indices = mdtop.select('protein and (mass > 1)') molecule_atom_indices = mdtop.select( '(not protein) and (not water) and (mass > 1)') protein_chainids = list( set([ atom.residue.chain.index for atom in mdtop.atoms if atom.index in protein_atom_indices ])) n_protein_chains = len(protein_chainids) protein_chain_atom_indices = dict() for chainid in protein_chainids: protein_chain_atom_indices[chainid] = mdtop.select( f'protein and chainid {chainid}') # Add solvent print('Adding solvent...') kwargs = {'padding': solvent_padding} modeller.addSolvent(openmm_system_generator.forcefield, model='tip3p', ionicStrength=ionic_strength, **kwargs) # Write initial model and select atom subsets and chains import bz2 with bz2.open(os.path.join(destination_path, 'initial-model.pdb.bz2'), 'wt') as outfile: app.PDBFile.writeFile(modeller.topology, modeller.positions, outfile, keepIds=True) # Create an OpenMM system print('Creating OpenMM system...') system = openmm_system_generator.create_system(modeller.topology) # # Add virtual bonds to ensure protein subunits and ligand are imaged together # virtual_bond_force = openmm.CustomBondForce('0') system.addForce(virtual_bond_force) # Add a virtual bond between protein chains if (n_protein_chains > 1): chainid = protein_chainids[0] iatom = protein_chain_atom_indices[chainid][0] for chainid in protein_chainids[1:]: jatom = protein_chain_atom_indices[chainid][0] print(f'Creating virtual bond between atoms {iatom} and {jatom}') virtual_bond_force.addBond(int(iatom), int(jatom), []) # Add a virtual bond between protein and ligand to make sure they are not imaged separately if oemol is not None: ligand_atom_indices = mdtop.select( '((resname MOL) and (mass > 1))') # ligand heavy atoms protein_atom_index = int(protein_atom_indices[0]) ligand_atom_index = int(ligand_atom_indices[0]) print( f'Creating virtual bond between atoms {protein_atom_index} and {ligand_atom_index}' ) virtual_bond_force.addBond(int(protein_atom_index), int(ligand_atom_index), []) # Add RMSD restraints if requested if restrain_rmsd: print('Adding RMSD restraint...') kB = unit.AVOGADRO_CONSTANT_NA * unit.BOLTZMANN_CONSTANT_kB kT = kB * temperature rmsd_atom_indices = mdtop.select( '(protein and (name CA)) or ((resname MOL) and (mass > 1))' ) # CA atoms and ligand heavy atoms rmsd_atom_indices = [int(index) for index in rmsd_atom_indices] custom_cv_force = openmm.CustomCVForce('(K_RMSD/2)*RMSD^2') custom_cv_force.addGlobalParameter('K_RMSD', kT / unit.angstrom**2) rmsd_force = openmm.RMSDForce(modeller.positions, rmsd_atom_indices) custom_cv_force.addCollectiveVariable('RMSD', rmsd_force) force_index = system.addForce(custom_cv_force) # Create OpenM Context platform = openmm.Platform.getPlatformByName('OpenCL') platform.setPropertyDefaultValue('Precision', 'mixed') from openmmtools import integrators integrator = integrators.LangevinIntegrator(temperature, collision_rate, timestep) context = openmm.Context(system, integrator, platform) context.setPositions(modeller.positions) # Report initial potential energy state = context.getState(getEnergy=True) print( f'Initial potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol' ) # Store snapshots in MDTraj trajectory to examine RMSD import mdtraj as md import numpy as np mdtop = md.Topology.from_openmm(pdbfile.topology) atom_indices = mdtop.select('all') # all solute atoms protein_atom_indices = mdtop.select( 'protein and (mass > 1)') # heavy solute atoms if oemol is not None: ligand_atom_indices = mdtop.select( '(resname MOL) and (mass > 1)') # ligand heavy atoms trajectory = md.Trajectory( np.zeros([iterations + 1, len(atom_indices), 3], np.float32), mdtop) trajectory.xyz[0, :, :] = context.getState(getPositions=True).getPositions( asNumpy=True)[atom_indices] / unit.nanometers # Minimize print('Minimizing...') openmm.LocalEnergyMinimizer.minimize(context) # Equilibrate (with RMSD restraint if needed) import numpy as np from rich.progress import track import time initial_time = time.time() for iteration in track(range(iterations), 'Equilibrating...'): integrator.step(nsteps_per_iteration) trajectory.xyz[iteration + 1, :, :] = context.getState( getPositions=True).getPositions( asNumpy=True)[atom_indices] / unit.nanometers elapsed_time = (time.time() - initial_time) * unit.seconds ns_per_day = (context.getState().getTime() / elapsed_time) / (unit.nanoseconds / unit.day) print(f'Performance: {ns_per_day:8.3f} ns/day') if restrain_rmsd: # Disable RMSD restraint context.setParameter('K_RMSD', 0.0) print('Minimizing...') openmm.LocalEnergyMinimizer.minimize(context) for iteration in track(range(iterations), 'Equilibrating without RMSD restraint...'): integrator.step(nsteps_per_iteration) # Retrieve state state = context.getState(getPositions=True, getVelocities=True, getEnergy=True, getForces=True) system.setDefaultPeriodicBoxVectors(*state.getPeriodicBoxVectors()) modeller.topology.setPeriodicBoxVectors(state.getPeriodicBoxVectors()) print( f'Final potential energy is {state.getPotentialEnergy()/unit.kilocalories_per_mole:.3f} kcal/mol' ) # Equilibrate again if we restrained the RMSD if restrain_rmsd: print('Removing RMSD restraint from system...') system.removeForce(force_index) #if oemol is not None: # # Check final RMSD # print('checking RMSD...') # trajectory.superpose(trajectory, atom_indices=protein_atom_indices) # protein_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=protein_atom_indices)[-1] * 10 # Angstroms # oechem.OESetSDData(oemol, 'equil_protein_rmsd', f'{protein_rmsd:.2f} A') # ligand_rmsd = md.rmsd(trajectory, trajectory[-1], atom_indices=ligand_atom_indices)[-1] * 10 # Angstroms # oechem.OESetSDData(oemol, 'equil_ligand_rmsd', f'{ligand_rmsd:.2f} A') # print('RMSD after equilibration: protein {protein_rmsd:8.2f} A | ligand {ligand_rmsd:8.3f} A') # Save as OpenMM print('Exporting for OpenMM FAH simulation...') import bz2 with bz2.open(integrator_xml_filename, 'wt') as f: f.write(openmm.XmlSerializer.serialize(integrator)) with bz2.open(state_xml_filename, 'wt') as f: f.write(openmm.XmlSerializer.serialize(state)) with bz2.open(system_xml_filename, 'wt') as f: f.write(openmm.XmlSerializer.serialize(system)) with bz2.open(os.path.join(destination_path, 'equilibrated-all.pdb.bz2'), 'wt') as f: app.PDBFile.writeFile(modeller.topology, state.getPositions(), f, keepIds=True) with open(os.path.join(destination_path, 'equilibrated-solute.pdb'), 'wt') as f: import mdtraj mdtraj_topology = mdtraj.Topology.from_openmm(modeller.topology) mdtraj_trajectory = mdtraj.Trajectory( [state.getPositions(asNumpy=True) / unit.nanometers], mdtraj_topology) selection = mdtraj_topology.select('not water') mdtraj_trajectory = mdtraj_trajectory.atom_slice(selection) app.PDBFile.writeFile(mdtraj_trajectory.topology.to_openmm(), mdtraj_trajectory.openmm_positions(0), f, keepIds=True) with open(os.path.join(destination_path, 'core.xml'), 'wt') as f: f.write(f'<config>\n') f.write( f' <numSteps>{nsteps_per_snapshot * nsnapshots_per_wu}</numSteps>\n' ) f.write(f' <xtcFreq>{nsteps_per_snapshot}</xtcFreq>\n') f.write(f' <precision>mixed</precision>\n') f.write( f' <xtcAtoms>{",".join([str(index) for index in selection])}</xtcAtoms>\n' ) f.write(f'</config>\n') if oemol is not None: # Write molecule as SDF, SMILES, and mol2 for extension in ['sdf', 'mol2', 'smi', 'csv']: filename = os.path.join(destination_path, f'molecule.{extension}') with oechem.oemolostream(filename) as ofs: oechem.OEWriteMolecule(ofs, oemol) # Clean up del context, integrator
def __init__(self, protein_pdb_filename, ligand_file, old_ligand_index, new_ligand_index, forcefield_files, pressure=1.0 * unit.atmosphere, temperature=300.0 * unit.kelvin, solvent_padding=9.0 * unit.angstroms): """ Initialize a NonequilibriumFEPSetup object Parameters ---------- protein_pdb_filename : str The name of the protein pdb file ligand_file : str the name of the ligand file (any openeye supported format) ligand_smiles : list of two str The SMILES strings representing the two ligands forcefield_files : list of str The list of ffxml files that contain the forcefields that will be used pressure : Quantity, units of pressure Pressure to use in the barostat temperature : Quantity, units of temperature Temperature to use for the Langevin integrator solvent_padding : Quantity, units of length The amount of padding to use when adding solvent """ self._protein_pdb_filename = protein_pdb_filename self._pressure = pressure self._temperature = temperature self._barostat_period = 50 self._padding = solvent_padding self._ligand_file = ligand_file self._old_ligand_index = old_ligand_index self._new_ligand_index = new_ligand_index self._old_ligand_oemol = self.load_sdf(self._ligand_file, index=self._old_ligand_index) self._new_ligand_oemol = self.load_sdf(self._ligand_file, index=self._new_ligand_index) self._old_ligand_positions = extractPositionsFromOEMOL( self._old_ligand_oemol) ffxml = forcefield_generators.generateForceFieldFromMolecules( [self._old_ligand_oemol, self._new_ligand_oemol]) self._old_ligand_oemol.SetTitle("MOL") self._new_ligand_oemol.SetTitle("MOL") self._new_ligand_smiles = oechem.OECreateSmiString( self._new_ligand_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) #self._old_ligand_smiles = '[H]c1c(c(c(c(c1N([H])c2nc3c(c(n2)OC([H])([H])C4(C(C(C(C(C4([H])[H])([H])[H])([H])[H])([H])[H])([H])[H])[H])nc(n3[H])[H])[H])[H])S(=O)(=O)C([H])([H])[H])[H]' self._old_ligand_smiles = oechem.OECreateSmiString( self._old_ligand_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) print(self._new_ligand_smiles) print(self._old_ligand_smiles) self._old_ligand_topology = forcefield_generators.generateTopologyFromOEMol( self._old_ligand_oemol) self._old_ligand_md_topology = md.Topology.from_openmm( self._old_ligand_topology) self._new_ligand_topology = forcefield_generators.generateTopologyFromOEMol( self._new_ligand_oemol) self._new_liands_md_topology = md.Topology.from_openmm( self._new_ligand_topology) protein_pdbfile = open(self._protein_pdb_filename, 'r') pdb_file = app.PDBFile(protein_pdbfile) protein_pdbfile.close() self._protein_topology_old = pdb_file.topology self._protein_md_topology_old = md.Topology.from_openmm( self._protein_topology_old) self._protein_positions_old = pdb_file.positions self._forcefield = app.ForceField(*forcefield_files) self._forcefield.loadFile(StringIO(ffxml)) print("Generated forcefield") self._complex_md_topology_old = self._protein_md_topology_old.join( self._old_ligand_md_topology) self._complex_topology_old = self._complex_md_topology_old.to_openmm() n_atoms_complex_old = self._complex_topology_old.getNumAtoms() n_atoms_protein_old = self._protein_topology_old.getNumAtoms() self._complex_positions_old = unit.Quantity(np.zeros( [n_atoms_complex_old, 3]), unit=unit.nanometers) self._complex_positions_old[: n_atoms_protein_old, :] = self._protein_positions_old self._complex_positions_old[ n_atoms_protein_old:, :] = self._old_ligand_positions if pressure is not None: barostat = openmm.MonteCarloBarostat(self._pressure, self._temperature, self._barostat_period) self._system_generator = SystemGenerator( forcefield_files, barostat=barostat, forcefield_kwargs={'nonbondedMethod': app.PME}) else: self._system_generator = SystemGenerator(forcefield_files) #self._complex_proposal_engine = TwoMoleculeSetProposalEngine(self._old_ligand_smiles, self._new_ligand_smiles, self._system_generator, residue_name="MOL") self._complex_proposal_engine = TwoMoleculeSetProposalEngine( self._old_ligand_oemol, self._new_ligand_oemol, self._system_generator, residue_name="MOL") self._geometry_engine = FFAllAngleGeometryEngine() self._complex_topology_old_solvated, self._complex_positions_old_solvated, self._complex_system_old_solvated = self._solvate_system( self._complex_topology_old, self._complex_positions_old) self._complex_md_topology_old_solvated = md.Topology.from_openmm( self._complex_topology_old_solvated) print(self._complex_proposal_engine._smiles_list) beta = 1.0 / (kB * temperature) self._complex_topology_proposal = self._complex_proposal_engine.propose( self._complex_system_old_solvated, self._complex_topology_old_solvated) self._complex_positions_new_solvated, _ = self._geometry_engine.propose( self._complex_topology_proposal, self._complex_positions_old_solvated, beta) #now generate the equivalent objects for the solvent phase. First, generate the ligand-only topologies and atom map self._solvent_topology_proposal, self._old_solvent_positions = self._generate_ligand_only_topologies( self._complex_positions_old_solvated, self._complex_positions_new_solvated) self._new_solvent_positions, _ = self._geometry_engine.propose( self._solvent_topology_proposal, self._old_solvent_positions, beta)
def simulationSpawner(self, protocol, label='NPT', kind='equilibration', index=0): self.energy=self.simulation.context.getState(getEnergy=True).getTotalEnergy() print(f'Spwaning new simulation:') print(f'\tSystem total energy: {self.energy}') if kind == 'minimization': self.simulation.minimizeEnergy() self.structures['minimization']=self.writePDB(self.topology, self.positions, name='minimization') print(f'\tPerforming energy minimization: {Ei}') else: name=f'{kind}_{label}' trj_file=f'{self.workdir}/{kind}_{label}' #If there are user defined costum forces try: if protocol['restrained_sets']: self.system=self.setRestraints(protocol['restrained_sets']) except KeyError: pass if label == 'NPT': #TODO: frequency is hardcoded to 25, make it go away. Check units throughout! print(f'\tAdding MC barostat for {name} ensemble') self.system.addForce(omm.MonteCarloBarostat(self.pressure, self.temperature, 25)) self.simulation.context.setPositions(self.positions) if index == 1 and kind == 'equilibration': print(f'\tFirst equilibration run {name}. Assigning velocities to {self.temperature}') self.simulation.context.setVelocitiesToTemperature(self.temperature) # Define reporters self.simulation.reporters.append(DCDReporter(f'{trj_file}.dcd', protocol['report'])) self.simulation.reporters.append(HDF5Reporter(f'{trj_file}.h5', protocol['report'], atomSubset=self.trj_indices)) self.simulation.reporters.append(app.StateDataReporter(f'{trj_file}.csv', protocol['report'], step=True, totalEnergy=True, temperature=True, density=True, progress=True, remainingTime=True, speed=True, totalSteps=protocol['step'], separator='\t')) positions_first = self.simulation.context.getState(getPositions=True).getPositions() self.structures['f{name}_ref']=self.writePDB(self.simulation.topology, positions_first, name=f'{name}_0') ############# ## WARNIN ## ############# trj_time=protocol['step']*self.dt print(f'\t{kind} simulation in {label} ensemble ({trj_time})...') self.simulation.step(protocol['step']) ############# ## WARNOUT ## ############# print(f'\t{kind} simulation in {label} ensemble ({trj_time}) completed.') self.structures[f'{name}']=self.writePDB(self.simulation.topology, self.positions, name='{name}') state=self.simulation.context.getState(getPositions=True, getVelocities=True, getEnergy=True) self.positions = state.getPositions() self.velocities = state.getVelocities() self.energy=state.getPotentialEnergy() #Remove Costum forces (always initialized in next run) if label == 'NPT': self.system=self.forceHandler(self.system, kinds=['CustomExternalForce', 'MonteCarloBarostat']) elif label == 'NVT': self.system=self.forceHandler(self.system, kinds=['CustomExternalForce']) return self.simulation
for x in range(RUNSid): # prepare system and integrator system = prmtop.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=1.0 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005) integrator = mm.LangevinIntegrator(TEMPid * unit.kelvin, 1.0 / unit.picoseconds, 2.0 * unit.femtoseconds) integrator.setConstraintTolerance(0.00001) thermostat = mm.AndersenThermostat(TEMPid * unit.kelvin, 1 / unit.picosecond) system.addForce(thermostat) barostat = mm.MonteCarloBarostat(1.0 * unit.bar, TEMPid * unit.kelvin, 25) system.addForce(barostat) # prepare simulation platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed', 'DeviceIndex': '0'} simulation = app.Simulation(prmtop.topology, system, integrator, platform, properties) simulation.context.setPositions(inpcrd.positions) # minimize print('Minimizing...') simulation.minimizeEnergy() # equilibrate for 100 steps simulation.context.setVelocitiesToTemperature(TEMPid * unit.kelvin)
# Get the coordinates from the PDB crd = app.CharmmCrdFile('ubi_cubi.crd') # in case a crd file instead of pdb is used # Load the parameter set. lib = '/home/xuyou/toppar/' # FULL path of force field topology and parameter files params = app.CharmmParameterSet(lib+'top_all36_prot.rtf', lib+'par_all36m_prot.prm', lib+'toppar_water_ions.str') platform = mm.Platform.getPlatformByName('CUDA') # make sure the GPU is used. Others: Reference, CPU & OpenCL system = psf.createSystem(params, nonbondedMethod=app.LJPME, nonbondedCutoff=0.9*nanometer, ewaldErrorTolerance = 0.0001, constraints=app.HBonds) # The error tolerance is roughly equal to the fractional error in the forces due to truncating the Ewald summation. Default 0.0005. # The default vdwCutoff is as nonbondedCutof, so fswitch or fshift? system.addForce(mm.AndersenThermostat(temp*kelvin, 1/picosecond)) # thermostat: temperature and collision frequency system.addForce(mm.MonteCarloBarostat(pressure*bar, temp*kelvin)) # The barostat does not itself do anything to regulate the temperature integrator = mm.VerletIntegrator(0.002*picoseconds) # 2 fs time step simulation = app.Simulation(psf.topology, system, integrator, platform) # simulation.context.setPositions(pdb.getPositions()) # speicify the initial positions simulation.context.setPositions(crd.positions) # in case the crd file is used simulation.minimizeEnergy(maxIterations = 100) # default tolerance=10*kJ/mol, maxIterations: until converged if start > 0: # restart from the positions and velocities restart=str(start-1) with open(trjPath+jobname+'.'+restart+'.rst', 'r') as f: # the .rst file should only be used if .chk restart file cannot be loaded simulation.context.setState(mm.XmlSerializer.deserialize(f.read())) nsavcrd=50000 # save coordinates every 100 ps
def generate_solvated_hybrid_test_topology(current_mol_name="naphthalene", proposed_mol_name="benzene", current_mol_smiles=None, proposed_mol_smiles=None, vacuum=False, render_atom_mapping=False, atom_expression=['Hybridization'], bond_expression=['Hybridization']): """ This function will generate a topology proposal, old positions, and new positions with a geometry proposal (either vacuum or solvated) given a set of input iupacs or smiles. The function will (by default) read the iupac names first. If they are set to None, then it will attempt to read a set of current and new smiles. An atom mapping pdf will be generated if specified. Arguments ---------- current_mol_name : str, optional name of the first molecule proposed_mol_name : str, optional name of the second molecule current_mol_smiles : str (default None) current mol smiles proposed_mol_smiles : str (default None) proposed mol smiles vacuum: bool (default False) whether to render a vacuum or solvated topology_proposal render_atom_mapping : bool (default False) whether to render the atom map of the current_mol_name and proposed_mol_name atom_expression : list(str), optional list of atom mapping criteria bond_expression : list(str), optional list of bond mapping criteria Returns ------- topology_proposal : perses.rjmc.topology_proposal The topology proposal representing the transformation current_positions : np.array, unit-bearing The positions of the initial system new_positions : np.array, unit-bearing The positions of the new system """ import simtk.openmm.app as app from openmoltools import forcefield_generators from openeye import oechem from openmoltools.openeye import iupac_to_oemol, generate_conformers, smiles_to_oemol from openmoltools import forcefield_generators import perses.utils.openeye as openeye from perses.utils.data import get_data_filename from perses.rjmc.topology_proposal import TopologyProposal, SmallMoleculeSetProposalEngine import simtk.unit as unit from perses.rjmc.geometry import FFAllAngleGeometryEngine from perses.utils.openeye import generate_expression from openmmforcefields.generators import SystemGenerator from openforcefield.topology import Molecule atom_expr = generate_expression(atom_expression) bond_expr = generate_expression(bond_expression) if current_mol_name != None and proposed_mol_name != None: try: old_oemol, new_oemol = iupac_to_oemol( current_mol_name), iupac_to_oemol(proposed_mol_name) old_smiles = oechem.OECreateSmiString( old_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) new_smiles = oechem.OECreateSmiString( new_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) except: raise Exception( f"either {current_mol_name} or {proposed_mol_name} is not compatible with 'iupac_to_oemol' function!" ) elif current_mol_smiles != None and proposed_mol_smiles != None: try: old_oemol, new_oemol = smiles_to_oemol( current_mol_smiles), smiles_to_oemol(proposed_mol_smiles) old_smiles = oechem.OECreateSmiString( old_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) new_smiles = oechem.OECreateSmiString( new_oemol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens) except: raise Exception(f"the variables are not compatible") else: raise Exception( f"either current_mol_name and proposed_mol_name must be specified as iupacs OR current_mol_smiles and proposed_mol_smiles must be specified as smiles strings." ) old_oemol, old_system, old_positions, old_topology = openeye.createSystemFromSMILES( old_smiles, title="MOL") #correct the old positions old_positions = openeye.extractPositionsFromOEMol(old_oemol) old_positions = old_positions.in_units_of(unit.nanometers) new_oemol, new_system, new_positions, new_topology = openeye.createSystemFromSMILES( new_smiles, title="NEW") ffxml = forcefield_generators.generateForceFieldFromMolecules( [old_oemol, new_oemol]) old_oemol.SetTitle('MOL') new_oemol.SetTitle('MOL') old_topology = forcefield_generators.generateTopologyFromOEMol(old_oemol) new_topology = forcefield_generators.generateTopologyFromOEMol(new_oemol) if not vacuum: nonbonded_method = app.PME barostat = openmm.MonteCarloBarostat(1.0 * unit.atmosphere, 300.0 * unit.kelvin, 50) else: nonbonded_method = app.NoCutoff barostat = None forcefield_files = ['amber14/protein.ff14SB.xml', 'amber14/tip3p.xml'] forcefield_kwargs = { 'removeCMMotion': False, 'ewaldErrorTolerance': 1e-4, 'constraints': app.HBonds, 'hydrogenMass': 4 * unit.amus } periodic_forcefield_kwargs = {'nonbondedMethod': nonbonded_method} small_molecule_forcefield = 'gaff-2.11' system_generator = SystemGenerator( forcefields=forcefield_files, barostat=barostat, forcefield_kwargs=forcefield_kwargs, periodic_forcefield_kwargs=periodic_forcefield_kwargs, small_molecule_forcefield=small_molecule_forcefield, molecules=[ Molecule.from_openeye(mol) for mol in [old_oemol, new_oemol] ], cache=None) proposal_engine = SmallMoleculeSetProposalEngine([old_oemol, new_oemol], system_generator, residue_name='MOL', atom_expr=atom_expr, bond_expr=bond_expr, allow_ring_breaking=True) geometry_engine = FFAllAngleGeometryEngine(metadata=None, use_sterics=False, n_bond_divisions=1000, n_angle_divisions=180, n_torsion_divisions=360, verbose=True, storage=None, bond_softening_constant=1.0, angle_softening_constant=1.0, neglect_angles=False) if not vacuum: #now to solvate modeller = app.Modeller(old_topology, old_positions) hs = [ atom for atom in modeller.topology.atoms() if atom.element.symbol in ['H'] and atom.residue.name not in ['MOL', 'OLD', 'NEW'] ] modeller.delete(hs) modeller.addHydrogens(forcefield=system_generator.forcefield) modeller.addSolvent(system_generator.forcefield, model='tip3p', padding=9.0 * unit.angstroms) solvated_topology = modeller.getTopology() solvated_positions = modeller.getPositions() solvated_positions = unit.quantity.Quantity(value=np.array([ list(atom_pos) for atom_pos in solvated_positions.value_in_unit_system(unit.md_unit_system) ]), unit=unit.nanometers) solvated_system = system_generator.create_system(solvated_topology) #now to create proposal top_proposal = proposal_engine.propose( current_system=solvated_system, current_topology=solvated_topology, current_mol_id=0, proposed_mol_id=1) new_positions, _ = geometry_engine.propose(top_proposal, solvated_positions, beta) if render_atom_mapping: from perses.utils.smallmolecules import render_atom_mapping print( f"new_to_old: {proposal_engine.non_offset_new_to_old_atom_map}" ) render_atom_mapping(f"{old_smiles}to{new_smiles}.png", old_oemol, new_oemol, proposal_engine.non_offset_new_to_old_atom_map) return top_proposal, solvated_positions, new_positions else: vacuum_system = system_generator.create_system(old_topology) top_proposal = proposal_engine.propose(current_system=vacuum_system, current_topology=old_topology, current_mol_id=0, proposed_mol_id=1) new_positions, _ = geometry_engine.propose(top_proposal, old_positions, beta) if render_atom_mapping: from perses.utils.smallmolecules import render_atom_mapping print(f"new_to_old: {top_proposal._new_to_old_atom_map}") render_atom_mapping(f"{old_smiles}to{new_smiles}.png", old_oemol, new_oemol, top_proposal._new_to_old_atom_map) return top_proposal, old_positions, new_positions
import pandas as pd import lb_loader import simtk.openmm.app as app import numpy as np import simtk.openmm as mm from simtk import unit as u from openmmtools import hmc_integrators, testsystems pd.set_option('display.width', 1000) collision_rate = 10000.0 / u.picoseconds temperature = 25. * u.kelvin testsystem = testsystems.LennardJonesFluid() system, positions = testsystem.system, testsystem.positions system.addForce(mm.MonteCarloBarostat(1.0 * u.atmospheres, temperature, 50)) integrator = mm.LangevinIntegrator(temperature, 1.0 / u.picoseconds, 0.5 * u.femtoseconds) context = mm.Context(system, integrator) context.setPositions(positions) context.setPeriodicBoxVectors(*boxes) context.setVelocitiesToTemperature(temperature) integrator.step(25000) positions = context.getState(getPositions=True).getPositions() x = [] for i in range(1000): state = context.getState(getParameters=True, getPositions=True) positions = state.getPositions(asNumpy=True) / u.nanometers boxes = state.getPeriodicBoxVectors(asNumpy=True) / u.nanometers
kB = unit.BOLTZMANN_CONSTANT_kB * unit.AVOGADRO_CONSTANT_NA temperature = 300.0 * unit.kelvin pressure = 1.0 * unit.atmosphere #### Integrator friction = 1.0 / unit.picosecond step_size = 2.0 * unit.femtoseconds integrator = LangevinIntegrator(temperature, friction, step_size) integrator.setConstraintTolerance(0.00001) #### Barostat barostat_interval = 25 barostat = mm.MonteCarloBarostat(pressure, temperature, barostat_interval) system.addForce(barostat) #### Platform platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed'} #### Simulation simulation = app.Simulation(topology, system, integrator, platform, properties) #### Initial Conditions positions = m3t.get(pdb, coordinates=True) simulation.context.setPositions(positions)
def apply(self, thermodynamic_state, sampler_state, platform=None): """ Apply the MCMC move. Parameters ---------- thermodynamic_state : ThermodynamicState The thermodynamic state to use when applying the MCMC move sampler_state : SamplerState The sampler state to apply the move to platform : simtk.openmm.Platform, optional, default = None If not None, the specified platform will be used. Returns ------- updated_sampler_state : SamplerState The updated sampler state Examples -------- >>> # Create a test system >>> from openmmtools import testsystems >>> test = testsystems.LennardJonesFluid() >>> # Create a sampler state. >>> sampler_state = SamplerState(system=test.system, positions=test.positions, box_vectors=test.system.getDefaultPeriodicBoxVectors()) >>> # Create a thermodynamic state. >>> from thermodynamics import ThermodynamicState >>> thermodynamic_state = ThermodynamicState(system=test.system, temperature=298*u.kelvin, pressure=1*u.atmospheres) >>> # Create a Monte Carlo Barostat move. >>> move = MonteCarloBarostatMove(nattempts=5) >>> # Perform one update of the sampler state. >>> updated_sampler_state = move.apply(thermodynamic_state, sampler_state) """ timer = Timer() # Make sure system contains a barostat. system = sampler_state.system forces = { system.getForce(index).__class__.__name__: system.getForce(index) for index in range(system.getNumForces()) } old_barostat_frequency = None if 'MonteCarloBarostat' in forces: force = forces['MonteCarloBarostat'] force.setTemperature(thermodynamic_state.temperature) old_barostat_frequency = force.getFrequency() force.setFrequency(1) parameter_name = force.Pressure() else: # Add MonteCarloBarostat. force = mm.MonteCarloBarostat(thermodynamic_state.pressure, thermodynamic_state.temperature, 1) system.addForce(force) parameter_name = force.Pressure() # Create integrator. integrator = integrators.DummyIntegrator() # Random number seed. seed = np.random.randint(_RANDOM_SEED_MAX) force.setRandomNumberSeed(seed) # Create context. timer.start("Context Creation") context = sampler_state.createContext(integrator, platform=platform) timer.stop("Context Creation") # Set pressure. context.setParameter(parameter_name, thermodynamic_state.pressure) # Run update. # Note that ONE step of this integrator is equal to self.nsteps of velocity Verlet dynamics followed by Metropolis accept/reject. timer.start("step(1)") integrator.step(self.nattempts) timer.stop("step(1)") # Get sampler state. timer.start("update_sampler_state") updated_sampler_state = SamplerState.createFromContext(context) timer.stop("update_sampler_state") # DEBUG #print thermodynamics.volume(updated_sampler_state.box_vectors) # Clean up. del context # Restore frequency of barostat. if old_barostat_frequency: force.setFrequency(old_barostat_frequency) timer.report_timing() # Return updated sampler state. return updated_sampler_state
temperature = 300. pressure = 1.0 * u.atmospheres ionicStrength = 0.05 * u.molar pdb = app.PDBFile("./%s_fixed.pdb" % code) modeller = app.Modeller(pdb.topology, pdb.positions) modeller.addSolvent(ff, padding=padding, ionicStrength=ionicStrength) topology = modeller.topology positions = modeller.positions system = ff.createSystem(topology, nonbondedMethod=app.PME, nonbondedCutoff=cutoff, constraints=app.HBonds) integrator = mm.LangevinIntegrator(temperature, 1.0 / u.picoseconds, 1.0 * u.femtoseconds) system.addForce(mm.MonteCarloBarostat(pressure, temperature, 25)) simulation = app.Simulation(topology, system, integrator) simulation.context.setPositions(positions) print('Minimizing...') simulation.minimizeEnergy() simulation.context.setVelocitiesToTemperature(temperature) print('Equilibrating...') simulation.step(50000) state = simulation.context.getState(getPositions=True, getParameters=True) positions = state.getPositions() vectors = state.getPeriodicBoxVectors() vectors = tuple([v[i] / u.nanometers for (i,v) in enumerate(vectors)]) vectors = u.Quantity(vectors, u.nanometer) topology.setUnitCellDimensions(vectors)
def solvate_and_minimize(topology, positions, phase=''): """ Solvate the given system and minimize. Parameters ---------- topology : simtk.openmm.Topology The topology positions : simtk.unit.Quantity of numpy.array of (natoms,3) with units compatible with nanometer. The positions phase : string, optional, default='' The phase prefix to prepend to written files. Returns ------- topology : simtk.openmm.app.Topology The new Topology object system : simtk.openm.System The solvated system. positions : simtk.unit.Quantity of dimension natoms x 3 with units compatible with angstroms The minimized positions. """ # Solvate (if desired) and create system. logger.info("Solvating...") forcefield = app.ForceField(*ffxmls) modeller = app.Modeller(topology, positions) modeller.addHydrogens(forcefield=forcefield, pH=pH) # DEBUG if is_periodic: # Add solvent if in a periodic box. modeller.addSolvent(forcefield, padding=padding, model=water_name) system = forcefield.createSystem(modeller.topology, nonbondedMethod=nonbonded_method, nonbondedCutoff=nonbonded_cutoff, constraints=constraints) if is_periodic: system.addForce( openmm.MonteCarloBarostat(pressure, temperature, barostat_frequency)) logger.info("System has %d atoms." % system.getNumParticles()) # DEBUG print "modeller.topology.chains(): %s" % str( [chain.id for chain in modeller.topology.chains()]) # Serialize to XML files. logger.info("Serializing to XML...") system_filename = os.path.join(workdir, 'system.xml') write_file(system_filename, openmm.XmlSerializer.serialize(system)) if minimize: # Create simulation. logger.info("Creating simulation...") errorTol = 0.001 integrator = openmm.VariableLangevinIntegrator(temperature, collision_rate, errorTol) simulation = app.Simulation(modeller.topology, system, integrator) simulation.context.setPositions(modeller.positions) # Print potential energy. potential = simulation.context.getState( getEnergy=True).getPotentialEnergy() logger.info("Potential energy is %12.3f kcal/mol" % (potential / unit.kilocalories_per_mole)) # Write modeller positions. logger.info("Writing modeller output...") filename = os.path.join(workdir, phase + 'modeller.pdb') app.PDBFile.writeFile(simulation.topology, modeller.positions, open(filename, 'w')) # Minimize energy. logger.info("Minimizing energy...") simulation.minimizeEnergy(maxIterations=max_minimization_iterations) #integrator.step(max_minimization_iterations) state = simulation.context.getState(getEnergy=True) potential_energy = state.getPotentialEnergy() if np.isnan(potential_energy / unit.kilocalories_per_mole): raise Exception("Potential energy is NaN after minimization.") logger.info("Potential energy after minimiziation: %.3f kcal/mol" % (potential_energy / unit.kilocalories_per_mole)) modeller.positions = simulation.context.getState( getPositions=True).getPositions() # Print potential energy. potential = simulation.context.getState( getEnergy=True).getPotentialEnergy() logger.info("Potential energy is %12.3f kcal/mol" % (potential / unit.kilocalories_per_mole)) # Write minimized positions. filename = os.path.join(workdir, phase + 'minimized.pdb') app.PDBFile.writeFile(simulation.topology, modeller.positions, open(filename, 'w')) # Clean up del simulation # Return the modeller instance. return [modeller.topology, system, modeller.positions]
def _build_sim(self): #set step length if self.hmr: self.step_length = 0.004 * unit.picoseconds else: self.step_length = 0.002 * unit.picoseconds if self.constraints in ['HBonds', 'HAngles', 'Allbonds']: print('setting {} constraints'.format(self.constraints)) constraints_object = eval("app.%s" % self.constraints) else: print('did not set any constraints') constraints_object = None self.system = self.parmed_structure.createSystem( nonbondedMethod=self.nonbonded_method, nonbondedCutoff=self.nonbonded_cutoff * unit.angstroms, constraints=constraints_object, hydrogenMass=4.0 * unit.amu if self.hmr else None) if self.implicit_solvent_model: self.set_implicit_solvent_model(self.implicit_solvent_model, self.nonbonded_cutoff) if self.pressure: if self.membrane: barostat_force = mm.MonteCarloMembraneBarostat( 1 * unit.bar, 200 * unit.bar * unit.nanometer, self.temperature * unit.kelvin, mm.MonteCarloMembraneBarostat.XYIsotropic, mm.MonteCarloMembraneBarostat.ZFree) else: barostat_force = mm.MonteCarloBarostat( self.pressure * unit.atmospheres, self.temperature * unit.kelvin, 25) self.system.addForce(barostat_force) if self.atoms_to_restrain is not None: self.set_positional_restraints(self.atoms_to_restrain) if self.atoms_to_freeze is not None: self.freeze_atom_selection(self.atoms_to_freeze) #get integrator if self.integrator not in ['Langevin', 'Verlet']: raise ValueError('{} integrator type not supported'.format( self.integrator)) if self.integrator == 'Langevin': self.integrator = mm.LangevinIntegrator( self.temperature * unit.kelvin, 1 / unit.picoseconds, self.step_length) if self.integrator == 'Verlet': integrator = mm.VerletIntegrator(self.step_length) if self.platform: self.platform = mm.Platform.getPlatformByName(self.platform) self.simulation = app.Simulation(self.parmed_structure.topology, self.system, self.integrator, platform=self.platform) else: self.simulation = app.Simulation(self.parmed_structure.topology, self.system, self.integrator) self.simulation.context.setPositions(self.positions) if self.box_vectors is not None: self.simulation.context.setPeriodicBoxVectors( self.box_vectors[0], self.box_vectors[1], self.box_vectors[2]) if self.velocities is not None: print('found velocities, restarting from previous simulation') self.simulation.context.setVelocities(self.velocities) else: print('assigning random velocity distribution with temperature {}'. format(self.temperature)) self.simulation.context.setVelocitiesToTemperature( self.temperature * unit.kelvin)
def openmm_simulate_amber_npt(pdb_file, top_file, check_point=None, GPU_index=0, output_traj="output.dcd", output_log="output.log", output_cm=None, temperature=300, report_time=10*u.picoseconds, sim_time=10*u.nanoseconds): """ Start and run an OpenMM NVT simulation with Langevin integrator at 2 fs time step and 300 K. The cutoff distance for nonbonded interactions were set at 1.0 nm, which commonly used along with Amber force field. Long-range nonbonded interactions were handled with PME. Parameters ---------- top_file : topology file (.top, .prmtop, ...) This is the topology file discribe all the interactions within the MD system. pdb_file : coordinates file (.gro, .pdb, ...) This is the molecule configuration file contains all the atom position and PBC (periodic boundary condition) box in the system. GPU_index : Int or Str The device # of GPU to use for running the simulation. Use Strings, '0,1' for example, to use more than 1 GPU output_traj : the trajectory file (.dcd) This is the file stores all the coordinates information of the MD simulation results. output_log : the log file (.log) This file stores the MD simulation status, such as steps, time, potential energy, temperature, speed, etc. report_time : 10 ps The program writes its information to the output every 10 ps by default sim_time : 10 ns The timespan of the simulation trajectory """ top = pmd.load_file(top_file, xyz = pdb_file) system = top.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=1*u.nanometer, constraints=app.HBonds) dt = 0.002*u.picoseconds integrator = omm.LangevinIntegrator(temperature*u.kelvin, 1/u.picosecond, dt) system.addForce(omm.MonteCarloBarostat(1*u.bar, temperature*u.kelvin)) try: platform = omm.Platform_getPlatformByName("CUDA") properties = {'DeviceIndex': str(GPU_index), 'CudaPrecision': 'mixed'} except Exception: platform = omm.Platform_getPlatformByName("OpenCL") properties = {'DeviceIndex': str(GPU_index)} simulation = app.Simulation(top.topology, system, integrator, platform, properties) simulation.context.setPositions(top.positions) simulation.minimizeEnergy() report_freq = int(report_time/dt) simulation.context.setVelocitiesToTemperature(10*u.kelvin, random.randint(1, 10000)) simulation.reporters.append(app.DCDReporter(output_traj, report_freq)) if output_cm: simulation.reporters.append(ContactMapReporter(output_cm, report_freq)) simulation.reporters.append(app.StateDataReporter(output_log, report_freq, step=True, time=True, speed=True, potentialEnergy=True, temperature=True, totalEnergy=True)) simulation.reporters.append(app.CheckpointReporter('checkpnt.chk', report_freq)) if check_point: simulation.loadCheckpoint(check_point) nsteps = int(sim_time/dt) simulation.step(nsteps)
P = 1 * u.atmosphere ts = 0.002 * u.picoseconds sstep = 100 nstep = 1000000 prmtop = app.AmberPrmtopFile('../complex.prmtop') inpcrd = app.AmberInpcrdFile('../complex.inpcrd') system = prmtop.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=10 * u.angstrom, switchDistance=9 * u.angstrom, constraints=app.HBonds) integrator = mm.LangevinIntegrator(T_i, 1 / u.picosecond, ts) barostat = mm.MonteCarloBarostat(P, T) simulation = app.Simulation(prmtop.topology, system, integrator) simulation.reporters.append(app.DCDReporter('output.dcd', 1000)) simulation.reporters.append( app.StateDataReporter('state.out', 1000, step=True, potentialEnergy=True, temperature=True)) simulation.context.setPositions(inpcrd.positions) simulation.context.setPeriodicBoxVectors(*inpcrd.boxVectors) simulation.minimizeEnergy()
# Thermodynamic and simulation control parameters temperature = 300.0 * unit.kelvin collision_rate = 90.0 / unit.picoseconds pressure = 1.0 * unit.atmospheres timestep = 2.0 * unit.femtoseconds equil_steps = 1500 # Load AMBER files prmtop = app.AmberPrmtopFile('prmtop') inpcrd = app.AmberInpcrdFile('inpcrd') # Initialize system, including a barostat system = prmtop.createSystem(nonbondedMethod=app.CutoffPeriodic, nonbondedCutoff=1.0 * unit.nanometer, constraints=app.HBonds) system.addForce(openmm.MonteCarloBarostat(pressure, temperature)) box_vectors = inpcrd.getBoxVectors(asNumpy=True) system.setDefaultPeriodicBoxVectors(box_vectors[0], box_vectors[1], box_vectors[2]) # Create the integrator and context integrator = openmm.LangevinIntegrator(temperature, collision_rate, timestep) context = openmm.Context(system, integrator) context.setPositions(inpcrd.positions) # Minimize the system openmm.LocalEnergyMinimizer.minimize(context) # Briefly thermalize. integrator.step(equil_steps)
def generate_atp(phase='vacuum'): """ modify the AlanineDipeptideVacuum test system to be parametrized with amber14ffsb in vac or solvent (tip3p) """ import openmmtools.testsystems as ts from openmmforcefields.generators import SystemGenerator atp = ts.AlanineDipeptideVacuum(constraints=app.HBonds, hydrogenMass=4 * unit.amus) forcefield_files = [ 'gaff.xml', 'amber14/protein.ff14SB.xml', 'amber14/tip3p.xml' ] if phase == 'vacuum': barostat = None system_generator = SystemGenerator( forcefield_files, barostat=barostat, forcefield_kwargs={ 'removeCMMotion': False, 'ewaldErrorTolerance': 1e-4, 'constraints': app.HBonds, 'hydrogenMass': 4 * unit.amus }, nonperiodic_forcefield_kwargs={'nonbondedMethod': app.NoCutoff}, small_molecule_forcefield='gaff-2.11', molecules=None, cache=None) atp.system = system_generator.create_system( atp.topology) #update the parametrization scheme to amberff14sb elif phase == 'solvent': barostat = openmm.MonteCarloBarostat(1.0 * unit.atmosphere, 300 * unit.kelvin, 50) system_generator = SystemGenerator( forcefield_files, barostat=barostat, forcefield_kwargs={ 'removeCMMotion': False, 'ewaldErrorTolerance': 1e-4, 'nonbondedMethod': app.PME, 'constraints': app.HBonds, 'hydrogenMass': 4 * unit.amus }, small_molecule_forcefield='gaff-2.11', molecules=None, cache=None) if phase == 'solvent': modeller = app.Modeller(atp.topology, atp.positions) modeller.addSolvent(system_generator._forcefield, model='tip3p', padding=9 * unit.angstroms, ionicStrength=0.15 * unit.molar) solvated_topology = modeller.getTopology() solvated_positions = modeller.getPositions() # canonicalize the solvated positions: turn tuples into np.array atp.positions = unit.quantity.Quantity(value=np.array([ list(atom_pos) for atom_pos in solvated_positions.value_in_unit_system(unit.md_unit_system) ]), unit=unit.nanometers) atp.topology = solvated_topology atp.system = system_generator.create_system(atp.topology) return atp, system_generator
print('\n=== Periodic Box ===') periodic_box_vectors = [[box_L, 0., 0.], [0., box_L, 0.], [0., 0., box_L]] print(periodic_box_vectors) top.setPeriodicBoxVectors(periodic_box_vectors * unit.nanometer) print('\n=== Making System ===') system = forcefield.createSystem(top, nonbondedMethod=nonbonded_method, nonbondedCutoff=nonbonded_cutoff, ewaldErrorTolerance=ewald_tol, rigidWater=True, constraints=None) integrator = mm.LangevinIntegrator(temperature * unit.kelvin, friction, dt * unit.picosecond) barostat = mm.MonteCarloBarostat(pressure * unit.bar, temperature * unit.kelvin, barostatfreq) #barostat = mm.MonteCarloBarostat( pressure, temperature, barostatfreq ) if run_npt: system.addForce(barostat) if use_gpu: platform = mm.Platform.getPlatformByName('OpenCL') properties = {'DeviceIndex': '1', 'Precision': 'mixed'} else: platform = mm.Platform.getPlatformByName('CPU') properties = {'Threads': '1'} simulation = app.Simulation(top, system, integrator, platform, properties) # === Get initial configuration === out_pdb_filename = PackMol(nMols, chainPDBs, box_L, box_L, box_L)
def main(): prmtop_filename = '/lustre/atlas/scratch/farkaspall/chm126/inspire-data/nilotinib/e255k/build/e255k-complex.top' crd_filename = '/lustre/atlas/scratch/farkaspall/chm126/inspire-data/nilotinib/e255k/build/e255k-complex.inpcrd' prmtop = AmberParm(prmtop_filename, crd_filename) system = prmtop.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=10 * unit.angstrom, constraints=app.HBonds, switchDistance=8 * unit.angstrom) temperature = 300 * unit.kelvin pressure = 1 * unit.atmosphere collision_rate = 5 / unit.picosecond timestep = 2 * unit.femtosecond integrator = openmm.LangevinIntegrator(temperature, collision_rate, timestep) barostat = openmm.MonteCarloBarostat(temperature, pressure) system.addForce(barostat) restrain = True if restrain: restrained_atoms = mdtraj.Topology.from_openmm( prmtop.topology).select("protein and not type H").tolist() K = 4.0 * unit.kilocalorie / (unit.angstrom**2 * unit.mole) energy_expression = '(K/2)*periodicdistance(x, y, z, x0, y0, z0)^2' restraint_force = openmm.CustomExternalForce(energy_expression) restraint_force.addGlobalParameter('K', K) restraint_force.addPerParticleParameter('x0') restraint_force.addPerParticleParameter('y0') restraint_force.addPerParticleParameter('z0') for index in restrained_atoms: parameters = prmtop.positions[index].value_in_unit_system( unit.md_unit_system) restraint_force.addParticle(index, parameters) system.addForce(restraint_force) system.setDefaultPeriodicBoxVectors(*prmtop.box_vectors) simulation = app.Simulation(prmtop.topology, system, integrator) simulation.context.setPositions(prmtop.positions) simulation.context.setVelocitiesToTemperature(temperature) print('System contains {} atoms.'.format(system.getNumParticles())) print('Using platform "{}".'.format( simulation.context.getPlatform().getName())) print('Minimizing energy to avoid clashes.') simulation.minimizeEnergy(maxIterations=100) print('Initial potential energy is {}'.format( simulation.context.getState(getEnergy=True).getPotentialEnergy())) # Warm up the integrator to compile kernels, etc print('Warming up integrator to trigger kernel compilation...') simulation.step(10) # Time integration print('Time: {}'.format(time.strftime('%H:%M:%S'))) print('Benchmarking...') nsteps = 20000 initial_time = time.time() integrator.step(nsteps) final_time = time.time() elapsed_time = (final_time - initial_time) * unit.seconds simulated_time = nsteps * timestep performance = (simulated_time / elapsed_time) print('Time: {}'.format(time.strftime('%H:%M:%S'))) print('Completed {} steps in {}.'.format(nsteps, elapsed_time)) print('Performance is {} ns/day'.format(performance / (unit.nanoseconds / unit.day))) print('Final potential energy is {}'.format( simulation.context.getState(getEnergy=True).getPotentialEnergy()))
def __init__( self, receptor_filename, ligand_filename, mutation_chain_id, mutation_residue_id, proposed_residue, phase='complex', conduct_endstate_validation=False, ligand_index=0, forcefield_files=[ 'amber14/protein.ff14SB.xml', 'amber14/tip3p.xml' ], barostat=openmm.MonteCarloBarostat(1.0 * unit.atmosphere, temperature, 50), forcefield_kwargs={ 'removeCMMotion': False, 'ewaldErrorTolerance': 1e-4, 'constraints': app.HBonds, 'hydrogenMass': 4 * unit.amus }, periodic_forcefield_kwargs={'nonbondedMethod': app.PME}, small_molecule_forcefields='gaff-2.11', **kwargs): """ arguments receptor_filename : str path to receptor; .pdb ligand_filename : str path to ligand of interest; .sdf or .pdb mutation_chain_id : str name of the chain to be mutated mutation_residue_id : str residue id to change proposed_residue : str three letter code of the residue to mutate to phase : str, default complex if phase == vacuum, then the complex will not be solvated with water; else, it will be solvated with tip3p conduct_endstate_validation : bool, default True whether to conduct an endstate validation of the hybrid topology factory ligand_index : int, default 0 which ligand to use forcefield_files : list of str, default ['amber14/protein.ff14SB.xml', 'amber14/tip3p.xml'] forcefield files for proteins and solvent barostat : openmm.MonteCarloBarostat, default openmm.MonteCarloBarostat(1.0 * unit.atmosphere, 300 * unit.kelvin, 50) barostat to use forcefield_kwargs : dict, default {'removeCMMotion': False, 'ewaldErrorTolerance': 1e-4, 'nonbondedMethod': app.NoCutoff, 'constraints' : app.HBonds, 'hydrogenMass' : 4 * unit.amus} forcefield kwargs for system parametrization periodic_forcefield_kwargs : dict default {'nonbondedMethod':app.PME} small_molecule_forcefields : str, default 'gaff-2.11' the forcefield string for small molecule parametrization TODO : allow argument for separate apo structure if it exists separately allow argument for specator ligands besides the 'ligand_filename' """ from openforcefield.topology import Molecule from openmmforcefields.generators import SystemGenerator # first thing to do is make a complex and apo... pdbfile = open(receptor_filename, 'r') pdb = app.PDBFile(pdbfile) pdbfile.close() receptor_positions, receptor_topology, receptor_md_topology = pdb.positions, pdb.topology, md.Topology.from_openmm( pdb.topology) receptor_topology = receptor_md_topology.to_openmm() receptor_n_atoms = receptor_md_topology.n_atoms molecules = [] ligand_mol = createOEMolFromSDF(ligand_filename, index=ligand_index) ligand_mol = generate_unique_atom_names(ligand_mol) molecules.append( Molecule.from_openeye(ligand_mol, allow_undefined_stereo=False)) ligand_positions, ligand_topology = extractPositionsFromOEMol( ligand_mol), forcefield_generators.generateTopologyFromOEMol( ligand_mol) ligand_md_topology = md.Topology.from_openmm(ligand_topology) ligand_n_atoms = ligand_md_topology.n_atoms #now create a complex complex_md_topology = receptor_md_topology.join(ligand_md_topology) complex_topology = complex_md_topology.to_openmm() complex_positions = unit.Quantity(np.zeros( [receptor_n_atoms + ligand_n_atoms, 3]), unit=unit.nanometers) complex_positions[:receptor_n_atoms, :] = receptor_positions complex_positions[receptor_n_atoms:, :] = ligand_positions #now for a system_generator self.system_generator = SystemGenerator( forcefields=forcefield_files, barostat=barostat, forcefield_kwargs=forcefield_kwargs, periodic_forcefield_kwargs=periodic_forcefield_kwargs, small_molecule_forcefield=small_molecule_forcefields, molecules=molecules, cache=None) #create complex and apo inputs... complex_topology, complex_positions, complex_system = self._solvate( complex_topology, complex_positions, 'tip3p', phase=phase) apo_topology, apo_positions, apo_system = self._solvate( receptor_topology, receptor_positions, 'tip3p', phase='phase') geometry_engine = FFAllAngleGeometryEngine( metadata=None, use_sterics=False, n_bond_divisions=100, n_angle_divisions=180, n_torsion_divisions=360, verbose=True, storage=None, bond_softening_constant=1.0, angle_softening_constant=1.0, neglect_angles=False, use_14_nonbondeds=True) #run pipeline... htfs = [] for (top, pos, sys) in zip([complex_topology, apo_topology], [complex_positions, apo_positions], [complex_system, apo_system]): point_mutation_engine = PointMutationEngine( wildtype_topology=top, system_generator=self.system_generator, chain_id= mutation_chain_id, #denote the chain id allowed to mutate (it's always a string variable) max_point_mutants=1, residues_allowed_to_mutate=[ mutation_residue_id ], #the residue ids allowed to mutate allowed_mutations=[ (mutation_residue_id, proposed_residue) ], #the residue ids allowed to mutate with the three-letter code allowed to change aggregate=True) #always allow aggregation topology_proposal = point_mutation_engine.propose(sys, top) new_positions, logp_proposal = geometry_engine.propose( topology_proposal, pos, beta) logp_reverse = geometry_engine.logp_reverse( topology_proposal, new_positions, pos, beta) forward_htf = HybridTopologyFactory( topology_proposal=topology_proposal, current_positions=pos, new_positions=new_positions, use_dispersion_correction=False, functions=None, softcore_alpha=None, bond_softening_constant=1.0, angle_softening_constant=1.0, soften_only_new=False, neglected_new_angle_terms=[], neglected_old_angle_terms=[], softcore_LJ_v2=True, softcore_electrostatics=True, softcore_LJ_v2_alpha=0.85, softcore_electrostatics_alpha=0.3, softcore_sigma_Q=1.0, interpolate_old_and_new_14s=False, omitted_terms=None) if not topology_proposal.unique_new_atoms: assert geometry_engine.forward_final_context_reduced_potential == None, f"There are no unique new atoms but the geometry_engine's final context reduced potential is not None (i.e. {self._geometry_engine.forward_final_context_reduced_potential})" assert geometry_engine.forward_atoms_with_positions_reduced_potential == None, f"There are no unique new atoms but the geometry_engine's forward atoms-with-positions-reduced-potential in not None (i.e. { self._geometry_engine.forward_atoms_with_positions_reduced_potential})" vacuum_added_valence_energy = 0.0 else: added_valence_energy = geometry_engine.forward_final_context_reduced_potential - geometry_engine.forward_atoms_with_positions_reduced_potential if not topology_proposal.unique_old_atoms: assert geometry_engine.reverse_final_context_reduced_potential == None, f"There are no unique old atoms but the geometry_engine's final context reduced potential is not None (i.e. {self._geometry_engine.reverse_final_context_reduced_potential})" assert geometry_engine.reverse_atoms_with_positions_reduced_potential == None, f"There are no unique old atoms but the geometry_engine's atoms-with-positions-reduced-potential in not None (i.e. { self._geometry_engine.reverse_atoms_with_positions_reduced_potential})" subtracted_valence_energy = 0.0 else: subtracted_valence_energy = geometry_engine.reverse_final_context_reduced_potential - geometry_engine.reverse_atoms_with_positions_reduced_potential if conduct_endstate_validation: zero_state_error, one_state_error = validate_endstate_energies( forward_htf._topology_proposal, forward_htf, added_valence_energy, subtracted_valence_energy, beta=beta, ENERGY_THRESHOLD=ENERGY_THRESHOLD) else: pass htfs.append(forward_htf) self.complex_htf = htfs[0] self.apo_htf = htfs[1]
#box = complex_solv.box; #print("Starting with new velocities ...."); printfile = sys.stdout; # Create the integrator to do Langevin dynamics integrator = mm.LangevinIntegrator( tempi*u.kelvin, # Temperature of heat bath 1.0/u.picoseconds, # Friction coefficient # 2.0*u.femtoseconds, # Time step stepLen # Time step ) # Add Force Barostat to the system if simType == 'npt': system.addForce(mm.MonteCarloBarostat(pressureAtm*u.atmospheres, tempK*u.kelvin, 25)) # Apply restraints if restraints : print("RESTRAINT mask applied to: {}" "\tRestraint weight: {}".format(restraintAtom, restraintWt* u.kilocalories_per_mole/u.angstroms**2)) # Select atom to restraint print("Type of restraint atoms: {}".format(restraintType)) # define the custom force to restrain atoms to their starting positions force_restr = mm.CustomExternalForce('k_restr*periodicdistance(x, y, z, x0, y0, z0)^2') # Add the restraint weight as a global parameter in kcal/mol/A^2 force_restr.addGlobalParameter("k_restr", restraintWt*u.kilocalories_per_mole/u.angstroms**2) # Define the target xyz coords for the restraint as per-atom (per-particle) parameters force_restr.addPerParticleParameter("x0")
print(pdb_filename) if os.path.exists(output_pdb): continue ff = app.ForceField('%s.xml' % ff_name, '%s.xml' % water_name) pdb = app.PDBFile(pdb_filename) modeller = app.Modeller(pdb.topology, pdb.positions) modeller.addSolvent(ff, model=base_waters[water_name], padding=padding) topology = modeller.getTopology() positions = modeller.getPositions() system = ff.createSystem(topology, nonbondedMethod=app.PME, nonbondedCutoff=cutoff, constraints=app.HBonds) integrator = mm.LangevinIntegrator(temperature, friction, timestep) system.addForce(mm.MonteCarloBarostat(pressure, temperature, barostat_frequency)) simulation = app.Simulation(topology, system, integrator) simulation.context.setPositions(positions) print('Minimizing...') simulation.minimizeEnergy() simulation.context.setVelocitiesToTemperature(temperature) print('Running.') simulation.reporters.append(app.PDBReporter(output_pdb, equilibrate_output_frequency)) simulation.reporters.append(app.DCDReporter(output_dcd, equilibrate_output_frequency)) simulation.step(n_equil_steps) del simulation del system t = md.load(output_dcd, top=output_pdb)
from __future__ import print_function from simtk.openmm import app import simtk.openmm as mm from simtk import unit from sys import stdout prmtop = app.AmberPrmtopFile('../equib/ade_D_ala.prmtop') inpcrd = app.AmberInpcrdFile('../equib/ade_D_ala.inpcrd') system = prmtop.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=1.0*unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005) integrator = mm.LangevinIntegrator(300*unit.kelvin, 1.0/unit.picoseconds, 2.0*unit.femtoseconds) integrator.setConstraintTolerance(0.00001) system.addForce(mm.MonteCarloBarostat(1*unit.atmospheres, 300*unit.kelvin, 25)) platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed', 'CudaDeviceIndex': '0'} simulation = app.Simulation(prmtop.topology, system, integrator, platform, properties) simulation.loadState('../equib/equilibrated.xml') simulation.context.setVelocitiesToTemperature(300*unit.kelvin) total_steps = 500000000 simulation.reporters.append(app.DCDReporter('trajectory002.dcd', 5000)) simulation.reporters.append(app.StateDataReporter('prod002.dat', 50000, step=True, time=True, potentialEnergy=True, kineticEnergy=True, totalEnergy=True, temperature=True, volume=True, density=True, progress=True, remainingTime=True, speed=True, totalSteps=total_steps, separator=',')) simulation.reporters.append(app.CheckpointReporter('checkpnt002.chk', 50000))
ff = app.ForceField(which_forcefield, which_water) pdb = app.PDBFile(pdb_filename) topology = pdb.topology positions = pdb.positions system = ff.createSystem(topology, nonbondedMethod=app.PME, nonbondedCutoff=cutoff, constraints=app.HBonds) integrator = mm.LangevinIntegrator(temperature, equil_friction, equil_timestep) system.addForce( mm.MonteCarloBarostat(pressure, temperature, barostat_frequency)) simulation = app.Simulation(topology, system, integrator) simulation.context.setPositions(positions) print('Minimizing...') simulation.minimizeEnergy() simulation.context.setVelocitiesToTemperature(temperature) print('Equilibrating...') simulation.step(discard_steps) # Don't even save the first XXX ps simulation.reporters.append(app.DCDReporter(dcd_filename, output_frequency)) simulation.reporters.append(app.PDBReporter(out_pdb_filename, n_steps - 1)) simulation.reporters.append( app.StateDataReporter(open(log_filename, 'w'),
def apply_barostat(self): if not self.system.usesPeriodicBoundaryConditions(): raise ValueError('Barostat can only be used with PBC conditions.') self.system.addForce(mm.MonteCarloBarostat(self.pressure*u.bar, self.temperature*u.kelvin, self.barostat_interval))
# Create output directory output_prefix = "./output/" + chosen_ligand os.makedirs(output_prefix, exist_ok=True) print("--> Directory ", output_prefix, " created ") # Set file names integrator_xml_filename = "integrator_2fs.xml" state_xml_filename = "pr_output_state.xml" state_pdb_filename = "pr_output_state.pdb" system_xml_filename = "pr_output_system.xml" checkpoint_filename = "pr_output_checkpoint.chk" traj_output_filename = "pr_output_traj.xtc" # Define the barostat for the system barostat = mm.MonteCarloBarostat(pressure, temperature) # Read in equilibrated system (PDB) pdb = PDBFile(input_pdb) # Deserialize system file and load system with open(input_system, 'r') as f: system = XmlSerializer.deserialize(f.read()) # Make and serialize integrator - Langevin dynamics print("Serializing integrator to %s" % os.path.join(output_prefix, integrator_xml_filename)) integrator = mm.LangevinIntegrator( temperature, collision_rate, timestep # Friction coefficient
def generate_solvated_hybrid_test_topology(current_mol_name="naphthalene", proposed_mol_name="benzene"): """ Generate a test solvated topology proposal, current positions, and new positions triplet from two IUPAC molecule names. Parameters ---------- current_mol_name : str, optional name of the first molecule proposed_mol_name : str, optional name of the second molecule Returns ------- topology_proposal : perses.rjmc.topology_proposal The topology proposal representing the transformation current_positions : np.array, unit-bearing The positions of the initial system new_positions : np.array, unit-bearing The positions of the new system """ import simtk.openmm.app as app from openmoltools import forcefield_generators from openeye import oechem from perses.rjmc.topology_proposal import SystemGenerator, SmallMoleculeSetProposalEngine from perses.rjmc import geometry from perses.utils.data import get_data_filename current_mol, unsolv_old_system, pos_old, top_old = createSystemFromIUPAC(current_mol_name) proposed_mol = iupac_to_oemol(proposed_mol_name) proposed_mol.SetTitle("MOL") initial_smiles = oechem.OEMolToSmiles(current_mol) final_smiles = oechem.OEMolToSmiles(proposed_mol) gaff_xml_filename = get_data_filename("data/gaff.xml") forcefield = app.ForceField(gaff_xml_filename, 'tip3p.xml') forcefield.registerTemplateGenerator(forcefield_generators.gaffTemplateGenerator) modeller = app.Modeller(top_old, pos_old) modeller.addSolvent(forcefield, model='tip3p', padding=9.0*unit.angstrom) solvated_topology = modeller.getTopology() solvated_positions = modeller.getPositions() solvated_system = forcefield.createSystem(solvated_topology, nonbondedMethod=app.PME, removeCMMotion=False) barostat = openmm.MonteCarloBarostat(1.0*unit.atmosphere, temperature, 50) solvated_system.addForce(barostat) gaff_filename = get_data_filename('data/gaff.xml') system_generator = SystemGenerator([gaff_filename, 'amber99sbildn.xml', 'tip3p.xml'], barostat=barostat, forcefield_kwargs={'removeCMMotion': False},periodic_forcefield_kwargs={'nonbondedMethod': app.PME}) geometry_engine = geometry.FFAllAngleGeometryEngine() canonicalized_smiles_list = [SmallMoleculeSetProposalEngine.canonicalize_smiles(smiles) for smiles in [initial_smiles, final_smiles]] proposal_engine = SmallMoleculeSetProposalEngine( canonicalized_smiles_list, system_generator, residue_name="MOL") #generate topology proposal topology_proposal = proposal_engine.propose(solvated_system, solvated_topology) #generate new positions with geometry engine new_positions, _ = geometry_engine.propose(topology_proposal, solvated_positions, beta) return topology_proposal, solvated_positions, new_positions
#now run the simulations for k in range(nstates): print("*******************Lambda %.2f*******************" % lambdas[k]) #create the lambda folderse if it does not exist if not os.path.exists("lambda-%.2f" % lambdas[k]): os.makedirs("lambda-%.2f" % lambdas[k]) simfile = open("lambda-%.2f/simfile.csv" % lambdas[k],"w") if (k==0): #at lambda 0.0 initialize the system #when we are at the very first iteration of lambda 0, create all the initial system #create an alchemical system alchemical_system = set_lambda_electrostatics(reference_system,[0],lambdas[k]) #add barostat alchemical_barostat = openmm.MonteCarloBarostat(pressure, temperature, 25) alchemical_system.addForce(alchemical_barostat) #add the thermostat alchemical_thermostat = openmm.AndersenThermostat(temperature, collision_rate) alchemical_system.addForce(alchemical_thermostat) #define the Verlet integrator alchemical_integrator = openmm.VerletIntegrator(timestep) #set the simulation alchemical_simulation = app.Simulation(base.topology, alchemical_system,alchemical_integrator,platform,properties) #set the positions based on the coordinate files alchemical_simulation.context.setPositions(base.positions) alchemical_simulation.context.setVelocitiesToTemperature(temperature) else: #if we are doing the other iterations or lambdas, recrate the system, based on the temporary/previous #alchemical system alchemical_system = set_lambda_electrostatics(reference_system,[0],lambdas[k])
def equilibrateSystem(pdbfile, psffile, outpdb, numsteps=30000, minimplatform='CPU', equilplatform='CUDA', device=0, temp=300, minimize=500000, minimizetol=100, charmmfolder=None): pdb = Molecule(pdbfile) watcoo = pdb.get('coords', 'water') celld = unit.Quantity((watcoo.max(axis=0) - watcoo.min(axis=0)).squeeze(), unit=unit.angstrom) psf = app.CharmmPsfFile(psffile) pdb = app.PDBFile(pdbfile) psf.setBox(celld[0], celld[1], celld[2]) params = _readCharmmParameters(charmmfolder, defaultCharmmFiles) system = psf.createSystem(params, nonbondedMethod=app.PME, nonbondedCutoff=1 * unit.nanometer, constraints=app.HBonds) system.addForce( mm.MonteCarloBarostat(1 * unit.atmospheres, temp * unit.kelvin, 25)) platform, prop = _getPlatform(minimplatform, device) integrator = mm.LangevinIntegrator(temp * unit.kelvin, 1 / unit.picosecond, 0.002 * unit.picoseconds) simulation = app.Simulation(psf.topology, system, integrator, platform, prop) simulation.context.setPositions(pdb.positions) # Perform minimization _printEnergies(simulation, 'Energy before minimization') simulation.minimizeEnergy(tolerance=minimizetol * unit.kilojoule / unit.mole, maxIterations=minimize) _printEnergies(simulation, 'Energy after minimization') # Copy coordinates from miminization context to equilibration context state = simulation.context.getState(getPositions=True) pos = state.getPositions() # Set up the equilibration simulation platform, prop = _getPlatform(equilplatform, device) integrator = mm.LangevinIntegrator(temp * unit.kelvin, 1 / unit.picosecond, 0.002 * unit.picoseconds) simulation = app.Simulation(psf.topology, system, integrator, platform, prop) simulation.context.setPositions(pos) # Generate initial velocities simulation.context.setVelocitiesToTemperature(temp) from htmd.membranebuilder.pdbreporter import PDBReporter simulation.reporters.append( PDBReporter(outpdb, numsteps, enforcePeriodicBox=False)) simulation.reporters.append( app.StateDataReporter(stdout, int(numsteps / 10), step=True, potentialEnergy=True, kineticEnergy=True, totalEnergy=True, temperature=True, progress=True, speed=True, remainingTime=True, totalSteps=numsteps, separator='\t')) simulation.step(numsteps)
def equilibration_NPT(self, protocol, index=0): eq_trj=f'{self.workdir}/equilibration_NPT' if protocol['restrained_sets']: #call to setRestraints, returns updated system. Check protocol['restrained_sets'] definitions on setSimulation. self.system=self.setRestraints(protocol['restrained_sets']) # add MC barostat for NPT self.system.addForce(omm.MonteCarloBarostat(self.pressure, self.temperature, 25)) #TODO: force is hardcoded, make it go away. Check units throughout! self.simulation.context.setPositions(self.positions) if index == 0: self.simulation.context.setVelocitiesToTemperature(self.temperature) # Define reporters self.simulation.reporters.append(DCDReporter(f'{eq_trj}.dcd', protocol['report'])) self.simulation.reporters.append(HDF5Reporter(f'{eq_trj}.h5', protocol['report'], atomSubset=self.trj_indices)) self.simulation.reporters.append(app.StateDataReporter(f'{eq_trj}.csv', protocol['report'], step=True, totalEnergy=True, temperature=True, density=True, progress=True, remainingTime=True, speed=True, totalSteps=protocol['step'], separator='\t')) positions_first = self.simulation.context.getState(getPositions=True).getPositions() self.writePDB(self.simulation.topology, positions_first, name='equilibration_NPT_0') ############# ## WARNIN ## ############# trj_time=protocol['step']*self.dt print(f"Restrained NPT equilibration ({trj_time})...") self.simulation.step(protocol['step']) ############# ## WARNOUT ## ############# state=self.simulation.context.getState(getPositions=True, getVelocities=True, getEnergy=True) self.positions = state.getPositions() self.velocities = state.getVelocities() self.energy=state.getPotentialEnergy() print('NPT equilibration finished.') self.EQ_NPT_PDB=self.writePDB(self.simulation.topology, self.positions, name='equilibration_NPT') self.system=self.forceHandler(self.system, kinds=['CustomExternalForce', 'MonteCarloBarostat']) return self.simulation
#----------------------------------------------------------------------------- # Load up custom residue definitions. This is necessary for OpenMM to recognize # the unnnatural amino acid that I'm using. app.Topology.loadBondDefinitions('../residues-nle.xml') pdb = app.PDBFile(NATIVE) forcefield = app.ForceField('amber99sbildn.xml', 'tip3p.xml', '../amber99sbildn-nle.xml') modeller = app.Modeller(pdb.topology, pdb.positions) modeller.addSolvent(forcefield, model='tip3p', boxSize=BOX_SIZE, ionicStrength=40*unit.millimolar) system = forcefield.createSystem(modeller.topology, nonbondedMethod=app.PME, nonbondedCutoff=9.5*unit.angstroms, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005) system.addForce(mm.MonteCarloBarostat(1*unit.atmosphere, TEMPERATURE, 25)) integrator = mm.LangevinIntegrator(TEMPERATURE, 1.0/unit.picoseconds, TIMESTEP) integrator.setConstraintTolerance(0.00001) platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed'} simulation = app.Simulation(modeller.topology, system, integrator, platform, properties) simulation.context.setPositions(modeller.positions) print 'Setting Velocities' simulation.context.setVelocitiesToTemperature(TEMPERATURE) print 'Adding reporters' simulation.reporters.append(HDF5Reporter(OUT_FN, REPORT_INTERVAL)) simulation.reporters.append(ProgressReporter(sys.stdout, REPORT_INTERVAL, N_STEPS))