def test_reporters_pbc(self): """ Test NetCDF and ASCII restart and trajectory reporters (w/ PBC) """ systemsolv = load_file(self.get_fn('ildn.solv.top'), xyz=self.get_fn('ildn.solv.gro')) system = systemsolv.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=8 * u.angstroms) integrator = mm.LangevinIntegrator(300 * u.kelvin, 5.0 / u.picoseconds, 1.0 * u.femtoseconds) sim = app.Simulation(systemsolv.topology, system, integrator, CPU) sim.context.setPositions(systemsolv.positions) sim.reporters.extend([ NetCDFReporter(self.get_fn('traj.nc', written=True), 1, vels=True, frcs=True), MdcrdReporter(self.get_fn('traj.mdcrd', written=True), 1), RestartReporter(self.get_fn('restart.ncrst', written=True), 1, netcdf=True), RestartReporter(self.get_fn('restart.rst7', written=True), 1), StateDataReporter(self.get_fn('state.o', written=True), 1, volume=True, density=True, systemMass=1) ]) sim.step(5) for reporter in sim.reporters: reporter.finalize() ntraj = NetCDFTraj.open_old(self.get_fn('traj.nc', written=True)) atraj = AmberMdcrd(self.get_fn('traj.mdcrd', written=True), len(systemsolv.atoms), True, mode='r') nrst = NetCDFRestart.open_old( self.get_fn('restart.ncrst', written=True)) arst = AmberAsciiRestart(self.get_fn('restart.rst7', written=True), 'r') self.assertEqual(ntraj.frame, 5) self.assertEqual(atraj.frame, 5) self.assertTrue(ntraj.hasvels) self.assertTrue(ntraj.hasfrcs) for i in range(ntraj.frame): for x1, x2 in zip(ntraj.box[i], atraj.box[i]): self.assertAlmostEqual(x1, x2, places=3) self.assertEqual(len(nrst.box), 6) self.assertEqual(len(arst.box), 6) # Make sure the EnergyMinimizerReporter does not fail f = StringIO() rep = EnergyMinimizerReporter(f, volume=True) rep.report(sim) rep.finalize()
def main( paramfile='params.in', overrides={}, quiktest=False, deviceid=None, progressreport=True, soluteRes=[0], lambdaLJ=1.0, lambdaQ=1.0 ): #simtime=2.0, T=298.0, NPT=True, LJcut=10.0, tail=True, useLJPME=False, rigidH2O=True, device=0, quiktest=False): # === PARSE === # args = mdparse.SimulationOptions(paramfile, overrides) # Files gromacs.GROMACS_TOPDIR = args.topdir top_file = args.topfile box_file = args.grofile defines = {} cont = args.cont args.force_active('chkxml', val='chk_{:02n}.xml'.format(cont), msg='first one') args.force_active('chkpdb', val='chk_{:02n}.pdb'.format(cont), msg='first one') if cont > 0: args.force_active('incoord', val='chk_{:02n}.xml'.format(cont - 1), msg='continuing') args.force_active('outpdb', val='output_{:02n}.pdb'.format(cont), msg='continuing') args.force_active('outnetcdf', val='output_{:02n}.nc'.format(cont), msg='continuing') args.force_active('logfile', val='thermo.log_{:02n}'.format(cont), msg='continuing') args.force_active('outdcd', val='output_{:02n}.dcd'.format(cont), msg='continuing') incoord = args.incoord out_pdb = args.outpdb out_netcdf = args.outnetcdf out_dcd = args.outdcd molecTopology = 'topology.pdb' out_nowater = 'output_nowater.nc' out_nowater_dcd = 'output_nowater.dcd' logfile = args.logfile checkpointxml = args.chkxml checkpointpdb = args.chkpdb checkpointchk = 'chk_{:02n}.chk'.format(cont) # Parameters #Temp = args.temperature #K #Pressure = 1 #bar #barostatfreq = 25 #time steps #fric = args.collision_rate #1/ps dt = args.timestep #fs if args.use_fs_interval: reportfreq = int(args.report_interval / dt) netcdffreq = int(args.netcdf_report_interval / dt) #5e4 dcdfreq = int(args.dcd_report_interval / dt) pdbfreq = int(args.pdb_report_interval / dt) checkfreq = int(args.checkpoint_interval / dt) #simtime = int( simtime ) #nanoseconds; make sure division is whole... no remainders... blocksteps = int(args.block_interval / dt) #1e6, steps per block of simulation nblocks = args.nblocks #aiming for 1 block is 1ns else: reportfreq = args.report_interval netcdffreq = args.netcdf_report_interval dcdfreq = args.dcd_report_interval pdbfreq = args.pdb_report_interval checkfreq = args.checkpoint_interval blocksteps = args.block_interval nblocks = args.nblocks if quiktest == True: reportfreq = 1 blocksteps = 10 nblocks = 2 # === Start Making System === # start = time.time() top = gromacs.GromacsTopologyFile(top_file, defines=defines) gro = gromacs.GromacsGroFile.parse(box_file) top.box = gro.box logger.info("Took {}s to create topology".format(time.time() - start)) print(top) constr = { None: None, "None": None, "HBonds": app.HBonds, "HAngles": app.HAngles, "AllBonds": app.AllBonds }[args.constraints] start = time.time() system = top.createSystem(nonbondedMethod=app.PME, ewaldErrorTolerance=args.ewald_error_tolerance, nonbondedCutoff=args.nonbonded_cutoff * u.nanometers, rigidWater=args.rigid_water, constraints=constr) logger.info("Took {}s to create system".format(time.time() - start)) nbm = { "NoCutoff": mm.NonbondedForce.NoCutoff, "CutoffNonPeriodic": mm.NonbondedForce.CutoffNonPeriodic, "Ewald": mm.NonbondedForce.Ewald, "PME": mm.NonbondedForce.PME, "LJPME": mm.NonbondedForce.LJPME }[args.nonbonded_method] ftmp = [ f for ii, f in enumerate(system.getForces()) if isinstance(f, mm.NonbondedForce) ] fnb = ftmp[0] fnb.setNonbondedMethod(nbm) logger.info("Nonbonded method ({},{})".format(args.nonbonded_method, fnb.getNonbondedMethod())) if (not args.dispersion_correction) or (args.nonbonded_method == "LJPME"): logger.info("Turning off tail correction...") fnb.setUseDispersionCorrection(False) logger.info("Check dispersion correction flag: {}".format( fnb.getUseDispersionCorrection())) # --- execute custom forcefield code --- """ if customff: logger.info("Using customff: [{}]".format(customff)) with open(customff,'r') as f: ffcode = f.read() exec(ffcode,globals(),locals()) #python 3, need to pass in globals to allow exec to modify them (i.e. the system object) #print(sys.path) #sys.path.insert(1,'.') #exec("import {}".format(".".join(customff.split(".")[:-1]))) else: logger.info("--- No custom ff code provided ---") fExts=[f for f in system.getForces() if isinstance(f,mm.CustomExternalForce)] logger.info("External forces added: {}".format(fExts)) """ soluteIndices = [] soluteResidues = soluteRes #list of residues to alchemify. modified s.t. soluteRes is already a list #parmed gromacs topology for ir, res in enumerate(top.residues): if ir in soluteResidues: for atom in res.atoms: soluteIndices.append(atom.idx) print("Solute residue: {}".format( [top.residues[ir].atoms for ir in soluteResidues])) print("Solute Indices: {}".format(soluteIndices)) #if using openmm topology. unfortunately don't know how to convert from parmed to openmm#: #topology = parmed.openmm.load_topology(top.topology) #print(type(topology)) #for ir,res in topology.residues(): # if ir in soluteResidues: # for atom in res.atoms: # soluteIndices.append(atom.index) alch = alchemifyIons.alchemist(system, lambdaLJ, lambdaQ) alch.setupSolute(soluteIndices) print(system.getForces()) # === Integrator, Barostat, Additional Constraints === # integrator = set_thermo(system, args) if not hasattr(args, 'constraints') or (str(args.constraints) == "None" and args.rigidwater == False): args.deactivate('constraint_tolerance', "There are no constraints in this system") else: logger.info("Setting constraint tolerance to %.3e" % args.constraint_tolerance) integrator.setConstraintTolerance(args.constraint_tolerance) # === Make Platform === # logger.info("Setting Platform to %s" % str(args.platform)) try: platform = mm.Platform.getPlatformByName(args.platform) except: logger.info( "Warning: %s platform not found, going to Reference platform \x1b[91m(slow)\x1b[0m" % args.platform) args.force_active('platform', "Reference", "The %s platform was not found." % args.platform) platform = mm.Platform.getPlatformByName("Reference") if deviceid is not None or deviceid >= 0: args.force_active('device', deviceid, msg="Using cmdline-input deviceid") if 'device' in args.ActiveOptions and (platform.getName() == "OpenCL" or platform.getName() == "CUDA"): device = str(args.device) # The device may be set using an environment variable or the input file. #if 'CUDA_DEVICE' in os.environ.keys(): #os.environ.has_key('CUDA_DEVICE'): # device = os.environ.get('CUDA_DEVICE',str(args.device)) #elif 'CUDA_DEVICE_INDEX' in os.environ.keys(): #os.environ.has_key('CUDA_DEVICE_INDEX'): # device = os.environ.get('CUDA_DEVICE_INDEX',str(args.device)) #else: # device = str(args.device) if device != None: logger.info("Setting Device to %s" % str(device)) #platform.setPropertyDefaultValue("CudaDevice", device) if platform.getName() == "CUDA": platform.setPropertyDefaultValue("CudaDeviceIndex", device) elif platform.getName() == "OpenCL": print("set OpenCL device to {}".format(device)) platform.setPropertyDefaultValue("OpenCLDeviceIndex", device) else: logger.info("Using the default (fastest) device") else: logger.info( "Using the default (fastest) device, or not using CUDA nor OpenCL") if "Precision" in platform.getPropertyNames() and ( platform.getName() == "OpenCL" or platform.getName() == "CUDA"): platform.setPropertyDefaultValue("Precision", args.cuda_precision) else: logger.info("Not setting precision") args.deactivate( "cuda_precision", msg="Platform does not support setting cuda_precision.") # === Create Simulation === # logger.info("Creating the Simulation object") start = time.time() # Get the number of forces and set each force to a different force group number. nfrc = system.getNumForces() if args.integrator != 'mtsvvvr': for i in range(nfrc): system.getForce(i).setForceGroup(i) ''' for i in range(nfrc): # Set vdW switching function manually. f = system.getForce(i) if f.__class__.__name__ == 'NonbondedForce': #f.setUseSwitchingFunction(False) #f.setSwitchingDistance(1.0*u.nanometers) if 'vdw_switch' in args.ActiveOptions and args.vdw_switch: f.setUseSwitchingFunction(True) f.setSwitchingDistance(args.switch_distance) ''' #create simulation object if args.platform != None: simulation = app.Simulation(top.topology, system, integrator, platform) else: simulation = app.Simulation(top.topology, system, integrator) topomm = mdtraj.Topology.from_openmm(simulation.topology) logger.info("System topology: {}".format(topomm)) #print platform we're using mdparse.printcool_dictionary( { i: simulation.context.getPlatform().getPropertyValue( simulation.context, i) for i in simulation.context.getPlatform().getPropertyNames() }, title="Platform %s has properties:" % simulation.context.getPlatform().getName()) logger.info("--== PME parameters ==--") ftmp = [ f for ii, f in enumerate(simulation.system.getForces()) if isinstance(f, mm.NonbondedForce) ] fnb = ftmp[0] if fnb.getNonbondedMethod() == 4: #check for PME PMEparam = fnb.getPMEParametersInContext(simulation.context) logger.info(fnb.getPMEParametersInContext(simulation.context)) if fnb.getNonbondedMethod() == 5: #check for LJPME PMEparam = fnb.getLJPMEParametersInContext(simulation.context) logger.info(fnb.getLJPMEParametersInContext(simulation.context)) #nmeshx = int(PMEparam[1]*1.5) #nmeshy = int(PMEparam[2]*1.5) #nmeshz = int(PMEparam[3]*1.5) #fnb.setPMEParameters(PMEparam[0],nmeshx,nmeshy,nmeshz) #logger.info(fnb.getPMEParametersInContext(simulation.context)) # Print out some more information about the system logger.info("--== System Information ==--") logger.info("Number of particles : %i" % simulation.context.getSystem().getNumParticles()) logger.info("Number of constraints : %i" % simulation.context.getSystem().getNumConstraints()) for f in simulation.context.getSystem().getForces(): if f.__class__.__name__ == 'NonbondedForce': method_names = [ "NoCutoff", "CutoffNonPeriodic", "CutoffPeriodic", "Ewald", "PME", "LJPME" ] logger.info("Nonbonded method : %s" % method_names[f.getNonbondedMethod()]) logger.info("Number of particles : %i" % f.getNumParticles()) logger.info("Number of exceptions : %i" % f.getNumExceptions()) if f.getNonbondedMethod() > 0: logger.info("Nonbonded cutoff : %.3f nm" % (f.getCutoffDistance() / u.nanometer)) if f.getNonbondedMethod() >= 3: logger.info("Ewald error tolerance : %.3e" % (f.getEwaldErrorTolerance())) logger.info("LJ switching function : %i" % f.getUseSwitchingFunction()) if f.getUseSwitchingFunction(): logger.info("LJ switching distance : %.3f nm" % (f.getSwitchingDistance() / u.nanometer)) # Print the sample input file here. for line in args.record(): print(line) print("Took {}s to make and setup simulation object".format(time.time() - start)) #============================# #| Initialize & Eq/Warm-Up |# #============================# p = simulation.context.getPlatform() if p.getName() == "CUDA" or p.getName() == "OpenCL": print("simulation platform: {}".format(p.getName())) print(p.getPropertyNames()) print(p.getPropertyValue(simulation.context, 'DeviceName')) print("Device Index: {}".format( p.getPropertyValue(simulation.context, 'DeviceIndex'))) if os.path.exists(args.restart_filename) and args.read_restart: print("Restarting simulation from the restart file.") print("Currently is filler") else: # Set initial positions. if incoord.split(".")[-1] == "pdb": pdb = app.PDBFile(incoord) #pmd.load_file(incoord) simulation.context.setPositions(pdb.positions) print('Set positions from pdb, {}'.format(incoord)) molecTopology = incoord elif incoord.split(".")[-1] == "xyz": traj = mdtraj.load(incoord, top=mdtraj.Topology.from_openmm( simulation.topology)) simulation.context.setPositions(traj.openmm_positions(0)) elif incoord.split(".")[-1] == "xml": simulation.loadState(incoord) print('Set positions from xml, {}'.format(incoord)) else: logger.info("Error, can't handle input coordinate filetype") if args.constraint_tolerance > 0.0: simulation.context.applyConstraints( args.constraint_tolerance ) #applies constraints in current frame. logger.info("Initial potential energy is: {}".format( simulation.context.getState(getEnergy=True).getPotentialEnergy())) if args.integrator != 'mtsvvvr': eda = mdparse.EnergyDecomposition(simulation) eda_kcal = OrderedDict([(i, "%10.4f" % (j / 4.184)) for i, j in eda.items()]) mdparse.printcool_dictionary( eda_kcal, title="Energy Decomposition (kcal/mol)") # Minimize the energy. if args.minimize: logger.info("Minimization start, the energy is: {}".format( simulation.context.getState( getEnergy=True).getPotentialEnergy())) simulation.minimizeEnergy() logger.info("Minimization done, the energy is {}".format( simulation.context.getState( getEnergy=True).getPotentialEnergy())) positions = simulation.context.getState( getPositions=True).getPositions() logger.info("Minimized geometry is written to 'minimized.pdb'") app.PDBFile.writeModel(simulation.topology, positions, open('minimized.pdb', 'w')) # Assign velocities. if args.gentemp > 0.0: logger.info( "Generating velocities corresponding to Maxwell distribution at %.2f K" % args.gentemp) simulation.context.setVelocitiesToTemperature(args.gentemp * u.kelvin) # Equilibrate. logger.info("--== Equilibrating (%i steps, %.2f ps) ==--" % (args.equilibrate, args.equilibrate * args.timestep * u.femtosecond / u.picosecond)) if args.report_interval > 0: # Append the ProgressReport for equilibration run. simulation.reporters.append( mdparse.ProgressReport(args, sys.stdout, args.report_interval, simulation, args.equilibrate)) simulation.reporters[-1].t00 = time.time() logger.info("Progress will be reported every %i steps" % args.report_interval) # This command actually does all of the computation. simulation.step(args.equilibrate) if args.report_interval > 0: # Get rid of the ProgressReport because we'll make a new one. simulation.reporters.pop() first = args.equilibrate #============================# #| Production MD simulation |# #============================# logger.info( "--== Production (%i blocks, %i steps total, %.2f ps total) ==--" % (nblocks, nblocks * blocksteps, nblocks * blocksteps * args.timestep * u.femtosecond / u.picosecond)) #===========================================# #| Add reporters for production simulation |# #===========================================# print("===== registering reporters and runnning =====") if args.report_interval > 0: logger.info("Thermo and Progress will be reported every %i steps" % args.report_interval) #simulation.reporters.append(ProgressReport(sys.stdout, args.report_interval, simulation, args.production, first)) mdparse.bak(logfile) simulation.reporters.append( app.StateDataReporter(logfile, reportfreq, step=True, potentialEnergy=True, kineticEnergy=True, temperature=True, volume=True, density=True, speed=True)) #simulation.reporters.append(app.StateDataReporter(stdout, reportfreq, step=True, # potentialEnergy=True, kineticEnergy=True, temperature=True, volume=True, density=True, speed=True)) if progressreport: simulation.reporters.append( mdparse.ProgressReport(args, sys.stdout, reportfreq, simulation, nblocks * blocksteps, first=args.equilibrate)) Prog = simulation.reporters[-1] if args.pdb_report_interval > 0: mdparse.bak(out_pdb) logger.info("PDB Reporter will write to %s every %i steps" % (out_pdb, pdbfreq)) simulation.reporters.append(app.PDBReporter(out_pdb, pdbfreq)) if args.netcdf_report_interval > 0: mdparse.bak(out_netcdf) logger.info("netcdf Reporter will write to %s every %i steps" % (out_netcdf, netcdffreq)) simulation.reporters.append( NetCDFReporter(out_netcdf, netcdffreq, crds=True, vels=args.netcdf_vels, frcs=args.netcdf_frcs)) ''' mdparse.bak(out_nowater) logger.info("netcdf Reporter will write a no-water coordinate file %s every %i steps" %(out_nowater,netcdffreq)) #toptraj = mdtraj.load(molecTopology) #top = toptraj.top top = mdtraj.Topology.from_openmm(simulation.topology) sel = [atom.index for residue in top.residues for atom in residue.atoms if (residue.name!="SOL") and (residue.name!="HOH")] simulation.reporters.append(mdtraj.reporters.NetCDFReporter(out_nowater, netcdffreq, atomSubset = sel)) ''' if args.dcd_report_interval > 0: mdparse.bak(out_dcd) logger.info("dcd Reporter will write to %s every %i steps" % (out_dcd, dcdfreq)) simulation.reporters.append( mdtraj.reporters.DCDReporter(out_dcd, dcdfreq)) ''' mdparse.bak(out_nowater_dcd) logger.info("dcd Reporter will write a no-water coordinate file %s every %i steps" %(out_nowater_dcd, dcdfreq)) #toptraj = mdtraj.load(molecTopology) #top = toptraj.top top = mdtraj.Topology.from_openmm(simulation.topology) sel = [atom.index for residue in top.residues for atom in residue.atoms if (residue.name!="SOL") and (residue.name!="HOH")] simulation.reporters.append(mdtraj.reporters.DCDReporter(out_nowater_dcd, dcdfreq, atomSubset = sel)) #write out a nowater.pdb as topology input top2 = top.subset(sel) xyz0 = np.zeros([len(sel),3]) traj2 = mdtraj.Trajectory(xyz0,topology=top2) traj2.save('output_nowater_top.pdb') top2omm = top2.to_openmm() ''' if args.checkpoint_interval > 0: simulation.reporters.append( app.CheckpointReporter(checkpointchk, checkfreq)) #simulation.reporters.append(app.DCDReporter(out_dcd, writefreq)) #simulation.reporters.append(mdtraj.reporters.HDF5Reporter(out_hdf5, writefreq, velocities=True)) #============================# #| Finally Run! |# #============================# t1 = time.time() if progressreport: Prog.t00 = t1 #simulation.step(args.production) for iblock in range(0, nblocks): logger.info("Starting block {}".format(iblock)) start = time.time() simulation.step(blocksteps) end = time.time() logger.info('Took {} seconds for block {}'.format(end - start, iblock)) simulation.saveState(checkpointxml) positions = simulation.context.getState( getPositions=True, enforcePeriodicBox=True).getPositions() app.PDBFile.writeFile(simulation.topology, positions, open(checkpointpdb, 'w'))
def doSimDynamics(top, systemRef, integratorRef, platform, prop, temperature, scalexy=False, inBulk=False, state=None, pos=None, vels=None, nSteps=10000000): #Input a topology object, reference system, integrator, platform, platform properties, #and optionally state file, positions, or velocities #If state is specified including positions and velocities and pos and vels are not None, the #positions and velocities from the provided state will be overwritten #Does NPT, stopping periodically to run NVE to compute dynamics #Only the NPT simulation will be saved, not the NVE #Copy the reference system and integrator objects system = copy.deepcopy(systemRef) integrator = copy.deepcopy(integratorRef) #For NPT, add the barostat as a force #If not in bulk, use anisotropic barostat if not inBulk: system.addForce( mm.MonteCarloAnisotropicBarostat( (1.0, 1.0, 1.0) * u.bar, temperature, #Temperature should be SAME as for thermostat scalexy, #Set with flag for flexibility scalexy, True, #Only scale in z-direction 250 #Time-steps between MC moves )) #If in bulk, have to use isotropic barostat to avoid any weird effects with box changing dimensions else: system.addForce(mm.MonteCarloBarostat(1.0 * u.bar, temperature, 250)) #Create new simulation object for NPT simulation sim = app.Simulation(top.topology, system, integrator, platform, prop, state) #Also create copies and simulation object for the NVE we will be running systemNVE = copy.deepcopy(systemRef) integratorNVE = mm.VerletIntegrator(2.0 * u.femtoseconds) integratorNVE.setConstraintTolerance(1.0E-08) simNVE = app.Simulation(top.topology, systemNVE, integratorNVE, platform, prop) #Set the particle positions in the NPT simulation if pos is not None: sim.context.setPositions(pos) #Apply constraints before starting the simulation sim.context.applyConstraints(1.0E-08) #Check starting energy decomposition if want #decompEnergy(sim.system, sim.context.getState(getPositions=True)) #Initialize velocities if not specified if vels is not None: sim.context.setVelocities(vels) else: try: testvel = sim.context.getState(getVelocities=True).getVelocities() print( "Velocities included in state, starting with 1st particle: %s" % str(testvel[0])) #If all the velocities are zero, then set them to the temperature if not np.any(testvel.value_in_unit(u.nanometer / u.picosecond)): print( "Had velocities, but they were all zero, so setting based on temperature." ) sim.context.setVelocitiesToTemperature(temperature) except: print("Could not find velocities, setting with temperature") sim.context.setVelocitiesToTemperature(temperature) #Set up the reporter to output energies, volume, etc. sim.reporters.append( app.StateDataReporter( 'prod_out.txt', #Where to write - can be stdout or file name (default .csv, I prefer .txt) 500, #Number of steps between writes step=True, #Write step number time=True, #Write simulation time potentialEnergy=True, #Write potential energy kineticEnergy=True, #Write kinetic energy totalEnergy=True, #Write total energy temperature=True, #Write temperature volume=True, #Write volume density=False, #Write density speed=True, #Estimate of simulation speed separator= ' ' #Default is comma, but can change if want (I like spaces) )) #Set up reporter for printing coordinates (trajectory) sim.reporters.append( NetCDFReporter( 'prod.nc', #File name to write trajectory to 500, #Number of steps between writes crds=True, #Write coordinates vels=True, #Write velocities frcs=False #Write forces )) #Identify solute indices and water oxygen indices soluteInds = [] owInds = [] hw1Inds = [] hw2Inds = [] for res in top.residues: if res.name not in ['OTM', 'CTM', 'STM', 'NTM', 'SOL']: for atom in res.atoms: soluteInds.append(atom.idx) elif res.name == 'SOL': for atom in res.atoms: if atom.name == 'OW': owInds.append(atom.idx) elif atom.name == 'HW1': hw1Inds.append(atom.idx) elif atom.name == 'HW2': hw2Inds.append(atom.idx) print("Solute indices:") print(soluteInds) #print("Water oxygen indices:") #print(owInds) #print("Water hydrogen (1st) indices:") #print(hw1Inds) #print("Water hydrogen (2nd) indices:") #print(hw2Inds) #Define cutoffs for solute solvation shells solShell1Cut = 0.55 #nanometers from all solute atoms (including hydrogens) solShell2Cut = 0.85 #Create array to store the dynamic information of interest every 0.2 ps (100 steps) for 50 ps calcSteps = 100 calcTotSteps = 25000 numWats = np.zeros( (int(calcTotSteps / calcSteps) + 1, 2) ) #Number waters that started in shell that are in shell at later time dipCorrs = np.zeros((int(calcTotSteps / calcSteps) + 1, 2)) #Dipole correlation in both solute shells #Start running dynamics print("\nRunning NPT simulation with interspersed NVE to find dynamics...") sim.context.setTime(0.0) stepChunk = 5000 #Run NVE for 50 ps to find dynamics every 10 ps countSteps = 0 while countSteps < nSteps: countSteps += stepChunk sim.step(stepChunk) #Record the simulation state so can kick off the NVE simulation thisState = sim.context.getState(getPositions=True, getVelocities=True) #Get solute and water oxygen coordinates after wrapping around the solute coords = thisState.getPositions(asNumpy=True) boxDims = np.diagonal(thisState.getPeriodicBoxVectors(asNumpy=True)) wrapCOM = np.average(coords[soluteInds], axis=0) coords = wl.reimage(coords, wrapCOM, boxDims) - wrapCOM solCoords = coords[soluteInds] owCoords = coords[owInds] hw1Coords = coords[hw1Inds] hw2Coords = coords[hw2Inds] #Figure out which waters are in the solute solvation shells shell1BoolMat = wl.nearneighbors(solCoords, owCoords, boxDims, 0.0, solShell1Cut) shell1Bool = np.array(np.sum(shell1BoolMat, axis=0), dtype=bool) shell2BoolMat = wl.nearneighbors(solCoords, owCoords, boxDims, solShell1Cut, solShell2Cut) shell2Bool = np.array(np.sum(shell2BoolMat, axis=0), dtype=bool) #Count number of waters in each shell (will need for averaging) thisCount1 = int(np.sum(shell1Bool)) thisCount2 = int(np.sum(shell2Bool)) #print("Found %i waters in shell1"%thisCount1) #print("Found %i waters in shell2"%thisCount2) #Loop over waters in shells and compute dipole vectors as references refDipoles1 = np.zeros((thisCount1, 3)) refDipoles2 = np.zeros((thisCount2, 3)) for k, pos in enumerate(owCoords[shell1Bool]): thisOHvecs = wl.reimage( [hw1Coords[shell1Bool][k], hw2Coords[shell1Bool][k]], pos, boxDims) - pos thisDip = -0.5 * (thisOHvecs[0] + thisOHvecs[1]) refDipoles1[k] = thisDip / np.linalg.norm(thisDip) for k, pos in enumerate(owCoords[shell2Bool]): thisOHvecs = wl.reimage( [hw1Coords[shell2Bool][k], hw2Coords[shell2Bool][k]], pos, boxDims) - pos thisDip = -0.5 * (thisOHvecs[0] + thisOHvecs[1]) refDipoles2[k] = thisDip / np.linalg.norm(thisDip) #Set up the NVE simulation simNVE.context.setState(thisState) simNVE.context.setTime(0.0) #Loop over taking steps to computed dynamics countStepsNVE = 0 while countStepsNVE <= calcTotSteps: calcState = simNVE.context.getState(getPositions=True) #Get solute and water oxygen coordinates after wrapping around the solute coords = calcState.getPositions(asNumpy=True) wrapCOM = np.average(coords[soluteInds], axis=0) coords = wl.reimage(coords, wrapCOM, boxDims) - wrapCOM solCoords = coords[soluteInds] owCoords = coords[owInds] hw1Coords = coords[hw1Inds] hw2Coords = coords[hw2Inds] #Count waters that started in each shell that are now in the shell at this time #No absorbing boundaries thisbool1Mat = wl.nearneighbors(solCoords, owCoords, boxDims, 0.0, solShell1Cut) thisbool1 = np.array(np.sum(thisbool1Mat, axis=0), dtype=bool) thisbool2Mat = wl.nearneighbors(solCoords, owCoords, boxDims, solShell1Cut, solShell2Cut) thisbool2 = np.array(np.sum(thisbool2Mat, axis=0), dtype=bool) numWats[int(countStepsNVE / calcSteps), 0] += int(np.sum(thisbool1 * shell1Bool)) numWats[int(countStepsNVE / calcSteps), 1] += int(np.sum(thisbool2 * shell2Bool)) #Loop over waters in shells and compute dipole vectors for this configuration #Adding to sum that we will normalize to find average at each time point for k, pos in enumerate(owCoords[shell1Bool]): thisOHvecs = wl.reimage( [hw1Coords[shell1Bool][k], hw2Coords[shell1Bool][k]], pos, boxDims) - pos thisDip = -0.5 * (thisOHvecs[0] + thisOHvecs[1]) thisDip /= np.linalg.norm(thisDip) dipCorrs[int(countStepsNVE / calcSteps), 0] += (np.dot(thisDip, refDipoles1[k]) / float(thisCount1)) for k, pos in enumerate(owCoords[shell2Bool]): thisOHvecs = wl.reimage( [hw1Coords[shell2Bool][k], hw2Coords[shell2Bool][k]], pos, boxDims) - pos thisDip = -0.5 * (thisOHvecs[0] + thisOHvecs[1]) thisDip /= np.linalg.norm(thisDip) dipCorrs[int(countStepsNVE / calcSteps), 1] += (np.dot(thisDip, refDipoles2[k]) / float(thisCount2)) simNVE.step(calcSteps) countStepsNVE += calcSteps #Finish normalizing dipole correlations (really cosine of angle between dipole vector at different times) numWats /= float(int(nSteps / stepChunk)) dipCorrs /= float(int(nSteps / stepChunk)) print("Normalizing factor for finding averages: %f" % float(int(nSteps / stepChunk))) #And save the final state of the NPT simulation in case we want to extend it sim.saveState('nptDynamicsState.xml') #And return the dipole correlations and times at which they were computed timeVals = 0.002 * np.arange(0.0, calcTotSteps + 0.0001, calcSteps) return numWats, dipCorrs, timeVals
# Define the platform to use; CUDA, OpenCL, CPU, or Reference. Or do not specify # the platform to use the default (fastest) platform platform = mm.Platform.getPlatformByName('CUDA') prop = dict(CudaPrecision='mixed') # Use mixed single/double precision # Create the Simulation object sim = app.Simulation(top.topology, system, integrator, platform, prop) # Set the particle positions sim.context.setPositions(top.positions) # Minimize the energy print('Minimizing energy') sim.minimizeEnergy(maxIterations=500) # Set up the reporters to report energies and coordinates every 100 steps sim.reporters.append( app.StateDataReporter(sys.stdout, 100, step=True, potentialEnergy=True, kineticEnergy=True, temperature=True, volume=True, density=True)) sim.reporters.append(NetCDFReporter('dhfr_pme.nc', 100, crds=True)) # Run dynamics print('Running dynamics') sim.step(10000)
def test_reporters(self): """ Test NetCDF and ASCII restart and trajectory reporters (no PBC) """ with self.assertRaises(ValueError): NetCDFReporter(self.get_fn('blah', written=True), 1, crds=False) with self.assertRaises(ValueError): MdcrdReporter(self.get_fn('blah', written=True), 1, crds=False) with self.assertRaises(ValueError): MdcrdReporter(self.get_fn('blah', written=True), 1, crds=True, vels=True) system = self.amber_gas.createSystem() integrator = mm.LangevinIntegrator(300 * u.kelvin, 5.0 / u.picoseconds, 1.0 * u.femtoseconds) sim = app.Simulation(self.amber_gas.topology, system, integrator, platform=CPU) sim.context.setPositions(self.amber_gas.positions) sim.reporters.extend([ NetCDFReporter(self.get_fn('traj1.nc', written=True), 10), NetCDFReporter(self.get_fn('traj2.nc', written=True), 10, vels=True), NetCDFReporter(self.get_fn('traj3.nc', written=True), 10, frcs=True), NetCDFReporter(self.get_fn('traj4.nc', written=True), 10, vels=True, frcs=True), NetCDFReporter(self.get_fn('traj5.nc', written=True), 10, crds=False, vels=True), NetCDFReporter(self.get_fn('traj6.nc', written=True), 10, crds=False, frcs=True), NetCDFReporter(self.get_fn('traj7.nc', written=True), 10, crds=False, vels=True, frcs=True), MdcrdReporter(self.get_fn('traj1.mdcrd', written=True), 10), MdcrdReporter(self.get_fn('traj2.mdcrd', written=True), 10, crds=False, vels=True), MdcrdReporter(self.get_fn('traj3.mdcrd', written=True), 10, crds=False, frcs=True), RestartReporter(self.get_fn('restart.ncrst', written=True), 10, write_multiple=True, netcdf=True), RestartReporter(self.get_fn('restart.rst7', written=True), 10), ]) sim.step(500) for reporter in sim.reporters: reporter.finalize() self.assertEqual(len(os.listdir(self._temporary_directory.name)), 61) ntraj = [ NetCDFTraj.open_old(self.get_fn('traj1.nc', written=True)), NetCDFTraj.open_old(self.get_fn('traj2.nc', written=True)), NetCDFTraj.open_old(self.get_fn('traj3.nc', written=True)), NetCDFTraj.open_old(self.get_fn('traj4.nc', written=True)), NetCDFTraj.open_old(self.get_fn('traj5.nc', written=True)), NetCDFTraj.open_old(self.get_fn('traj6.nc', written=True)), NetCDFTraj.open_old(self.get_fn('traj7.nc', written=True)) ] atraj = [ AmberMdcrd(self.get_fn('traj1.mdcrd', written=True), self.amber_gas.ptr('natom'), hasbox=False, mode='r'), AmberMdcrd(self.get_fn('traj2.mdcrd', written=True), self.amber_gas.ptr('natom'), hasbox=False, mode='r'), AmberMdcrd(self.get_fn('traj3.mdcrd', written=True), self.amber_gas.ptr('natom'), hasbox=False, mode='r'), ] for traj in ntraj: self.assertEqual(traj.frame, 50) self.assertEqual(traj.Conventions, 'AMBER') self.assertEqual(traj.ConventionVersion, '1.0') self.assertEqual(traj.application, 'AmberTools') self.assertEqual(traj.program, 'ParmEd') self.assertFalse(traj.hasbox) self.assertTrue(ntraj[0].hascrds) self.assertFalse(ntraj[0].hasvels) self.assertFalse(ntraj[0].hasfrcs) self.assertTrue(ntraj[1].hascrds) self.assertTrue(ntraj[1].hasvels) self.assertFalse(ntraj[1].hasfrcs) self.assertTrue(ntraj[2].hascrds) self.assertFalse(ntraj[2].hasvels) self.assertTrue(ntraj[2].hasfrcs) self.assertTrue(ntraj[3].hascrds) self.assertTrue(ntraj[3].hasvels) self.assertTrue(ntraj[3].hasfrcs) self.assertFalse(ntraj[4].hascrds) self.assertTrue(ntraj[4].hasvels) self.assertFalse(ntraj[4].hasfrcs) self.assertFalse(ntraj[5].hascrds) self.assertFalse(ntraj[5].hasvels) self.assertTrue(ntraj[5].hasfrcs) self.assertFalse(ntraj[6].hascrds) self.assertTrue(ntraj[6].hasvels) self.assertTrue(ntraj[6].hasfrcs) for i in (0, 2, 3, 4, 5, 6): ntraj[i].close() # still need the 2nd for traj in atraj: traj.close() # Now test the NetCDF restart files fn = self.get_fn('restart.ncrst.%d', written=True) for i, j in enumerate(range(10, 501, 10)): ncrst = NetCDFRestart.open_old(fn % j) self.assertEqual(ncrst.coordinates.shape, (1, 25, 3)) self.assertEqual(ncrst.velocities.shape, (1, 25, 3)) np.testing.assert_allclose(ncrst.coordinates[0], ntraj[1].coordinates[i]) np.testing.assert_allclose(ncrst.velocities[0], ntraj[1].velocities[i], rtol=1e-6) # Now test the ASCII restart file f = AmberAsciiRestart(self.get_fn('restart.rst7', written=True), 'r') # Compare to ncrst and make sure it's the same data np.testing.assert_allclose(ncrst.coordinates, f.coordinates, atol=1e-3) np.testing.assert_allclose(ncrst.velocities, f.velocities, rtol=1e-3) # Make sure the EnergyMinimizerReporter does not fail f = StringIO() rep = EnergyMinimizerReporter(f) rep.report(sim, frame=10) rep.finalize()
def test_openmm_cb6but_sim(num_rests=0, guest_pos='guest_inside'): path = './cb6-but_test/' + guest_pos + '/' topology = 'cb6-but-dum.prmtop' coordinates = 'cb6-but-dum.rst7' if num_rests > 0: md_out = 'cb6_but_openmm_rest_{:02d}.csv'.format(num_rests) traj_out = 'cb6_but_openmm_rest_{:02d}.nc'.format(num_rests) else: md_out = 'cb6_but_openmm.csv' traj_out = 'cb6_but_openmm.nc' structure = pmd.load_file(path + topology, path + coordinates, structure=True) traj = pt.load(path + coordinates, path + topology) host = ":CB6" guest = ":BUT" H = [host + "@C7", host + "@C31", host + "@C19"] G = [guest + "@C", guest + "@C3"] D = [":DM1", ":DM2", ":DM3"] H_i = [0, 0, 0] G_i = [0, 0] D_i = [0, 0, 0] # Get indices for atom masks for i, mask in enumerate(H): H_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0] for i, mask in enumerate(G): G_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0] for i, mask in enumerate(D): D_i[i] = utils.index_from_mask(structure, mask, amber_index=False)[0] # Set mass of Dummy atoms to 0 so they are non-interacting for i, atom in enumerate(structure.atoms): if atom.name == 'DUM': atom.mass = 0.0 topology_0m = 'cb6-but-dum-0m.prmtop' coordinates_0m = 'cb6-but-dum-0m.rst7' structure.save(path + topology_0m, overwrite=True) structure.save(path + coordinates_0m, overwrite=True) prmtop = app.AmberPrmtopFile(path + topology_0m) inpcrd = app.AmberInpcrdFile(path + coordinates_0m) settings = { 'nonbonded_method': app.NoCutoff, 'temperature': 298.15 * unit.kelvin, 'friction': 1 / unit.picosecond, 'timestep': 0.002 * unit.picosecond, 'implicit_solvent': app.HCT, 'dist_fc': 5.0, 'angle_fc': 100.0, 'numsteps': 500000, } system = prmtop.createSystem( nonbondedMethod=settings['nonbonded_method'], implicitSolvent=settings['implicit_solvent'], removeCMMotion=False, ) integrator = LangevinIntegrator(settings['temperature'], settings['friction'], settings['timestep']) # Create Positional Restraints for Dummy atoms pos_restraint = mm.CustomExternalForce('k*((x-x0)^2+(y-y0)^2+(z-z0)^2)') pos_restraint.addGlobalParameter( 'k', 50.0 * unit.kilocalories_per_mole / unit.angstroms**2) pos_restraint.addPerParticleParameter('x0') pos_restraint.addPerParticleParameter('y0') pos_restraint.addPerParticleParameter('z0') for i, atom in enumerate(structure.positions): if structure.atoms[i].name == 'DUM': pos_restraint.addParticle(i, atom.value_in_unit(unit.nanometers)) static_restraints = [] # Create Distance Restraint static_distance_rest = [D[0], H[0]] static_init_dist = pt.distance(traj, D[0] + ' ' + H[0])[0] dist_restraint = mm.CustomBondForce('k*(r-r0)^2') dist_restraint.addPerBondParameter('k') dist_restraint.addPerBondParameter('r0') r0 = static_init_dist * unit.angstroms k = settings['dist_fc'] * unit.kilocalories_per_mole / unit.angstroms**2 dist_restraint.addBond(D_i[0], H_i[0], [k, r0]) static_restraints.append(dist_restraint) # Create Angle Restraint 1 static_angle_rest_1 = [D[1], D[0], H[0]] static_init_angle_1 = pt.angle(traj, D[1] + ' ' + D[0] + ' ' + H[0])[0] angle_restraint_1 = mm.CustomAngleForce('0.5*k*(theta-theta0)^2') angle_restraint_1.addPerAngleParameter('k') angle_restraint_1.addPerAngleParameter('theta0') theta0 = static_init_angle_1 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 angle_restraint_1.addAngle(D_i[1], D_i[0], H_i[0], [k, theta0]) static_restraints.append(angle_restraint_1) # Create Dihedral Restraint 1 static_dihedral_rest_1 = [D[2], D[1], D[0], H[0]] static_init_dihedral_1 = pt.dihedral( traj, D[2] + ' ' + D[1] + ' ' + D[0] + ' ' + H[0])[0] dihedral_restraint_1 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2') dihedral_restraint_1.addPerTorsionParameter('k') dihedral_restraint_1.addPerTorsionParameter('theta0') theta0 = static_init_dihedral_1 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 dihedral_restraint_1.addTorsion(D_i[2], D_i[1], D_i[0], H_i[0], [k, theta0]) static_restraints.append(dihedral_restraint_1) # Create Angle Restraint 2 static_angle_rest_2 = [D[0], H[0], H[1]] static_init_angle_2 = pt.angle(traj, D[0] + ' ' + H[0] + ' ' + H[1])[0] angle_restraint_2 = mm.CustomAngleForce('0.5*k*(theta-theta0)^2') angle_restraint_2.addPerAngleParameter('k') angle_restraint_2.addPerAngleParameter('theta0') theta0 = static_init_angle_2 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 angle_restraint_2.addAngle(D_i[0], H_i[0], H_i[1], [k, theta0]) static_restraints.append(angle_restraint_2) # Create Dihedral Restraint 2 static_dihedral_rest_2 = [D[1], D[0], H[0], H[1]] static_init_dihedral_2 = pt.dihedral( traj, D[1] + ' ' + D[0] + ' ' + H[0] + ' ' + H[1])[0] dihedral_restraint_2 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2') dihedral_restraint_2.addPerTorsionParameter('k') dihedral_restraint_2.addPerTorsionParameter('theta0') theta0 = static_init_dihedral_2 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 dihedral_restraint_2.addTorsion(D_i[1], D_i[0], H_i[0], H_i[1], [k, theta0]) static_restraints.append(dihedral_restraint_2) # Create Dihedral Restraint 3 static_dihedral_rest_3 = [D[0], H[0], H[1], H[2]] static_init_dihedral_3 = pt.dihedral( traj, D[0] + ' ' + H[0] + ' ' + H[1] + ' ' + H[2])[0] dihedral_restraint_3 = mm.CustomTorsionForce('0.5*k*(theta-theta0)^2') dihedral_restraint_3.addPerTorsionParameter('k') dihedral_restraint_3.addPerTorsionParameter('theta0') theta0 = static_init_dihedral_3 * unit.degrees k = settings['angle_fc'] * unit.kilocalories_per_mole / unit.radians**2 dihedral_restraint_3.addTorsion(D_i[0], H_i[0], H_i[1], H_i[2], [k, theta0]) static_restraints.append(dihedral_restraint_3) #system.addForce(pos_restraint) if num_rests > 0: for rest in static_restraints[0:num_rests]: system.addForce(rest) simulation = app.Simulation(prmtop.topology, system, integrator, mm.Platform.getPlatformByName('CPU')) simulation.context.setPositions(inpcrd.positions) simulation.reporters.append(NetCDFReporter(path + traj_out, 250)) simulation.reporters.append( app.StateDataReporter(path + md_out, 250, step=True, time=True, potentialEnergy=True, kineticEnergy=True, totalEnergy=True, temperature=True, volume=True, density=True)) simulation.step(settings['numsteps'])
2.0*u.femtoseconds, # Time step ) # Define the platform to use; CUDA, OpenCL, CPU, or Reference. Or do not specify # the platform to use the default (fastest) platform platform = mm.Platform.getPlatformByName('CUDA') prop = dict(CudaPrecision='mixed') # Use mixed single/double precision # Create the Simulation object sim = app.Simulation(top.topology, system, integrator, platform, prop) # Set the particle positions sim.context.setPositions(top.positions) # Minimize the energy print('Minimizing energy') sim.minimizeEnergy(maxIterations=500) # Set up the reporters to report energies and coordinates every 100 steps sim.reporters.append( app.StateDataReporter(sys.stdout, 100, step=True, potentialEnergy=True, kineticEnergy=True, temperature=True) ) sim.reporters.append( NetCDFReporter('dhfr_gb.nc', 100, crds=True) ) # Run dynamics print('Running dynamics') sim.step(10000)
static_restraints.append(angle_restraint_g2) for rest in static_restraints + guest_restraints: system.addForce(rest) #system.addForce(barostat) #platforms = [ mm.Platform.getPlatform(index).getName() for index in range(mm.Platform.getNumPlatforms()) ] simulation = app.Simulation(prmtop.topology, system, integrator, mm.Platform.getPlatformByName('OpenCL')) simulation.context.setPositions(inpcrd.positions) simulation.minimizeEnergy() simulation.context.setVelocities(inpcrd.velocities) simulation.reporters.append( NetCDFReporter(path + window + '/' + settings["traj_file"], settings["write_freq"])) simulation.reporters.append( app.StateDataReporter(path + window + "/openmm_prod.log", settings["write_freq"], step=True, potentialEnergy=True, temperature=True, speed=True)) simulation.reporters.append( RestartReporter(path + window + "/openmm_prod.rst7", settings["num_steps"])) simulation.step(settings["num_steps"])
def main(targetVol, tol=1e-4, paramfile='params.in', overrides={}, quiktest=False, deviceid=None, progressreport=True): #simtime=2.0, T=298.0, NPT=True, LJcut=10.0, tail=True, useLJPME=False, rigidH2O=True, device=0, quiktest=False): logger.info("This protocol runs NPT until a target volume is achieved, with given tolerance.") logger.info("Make sure you prescribe pressure and barsostat freq!") # === PARSE === # args = mdparse.SimulationOptions(paramfile, overrides) # === forced parameters special to this protocol === # args.force_active('cont', val=-1, msg="targetVolume protocol, don't use continue flag") args.force_active('equilibrate', val=args.nbarostat*5, msg="targetVolume protocol, just minor warmup") args.force_active('grofile', val="targetVolume.gro", msg="default input gro file with box size for targetVolumeProtocol") if 'incoord' in overrides: args.force_active('incoord', val=overrides['incoord'], msg="user-supplied incoord overrides that in parameter file") if 'pressure' in overrides: args.force_active('pressure', val=overrides['pressure'], msg="user-supplied pressure overrides that in parameter file") if 'nbarostat' in overrides: args.force_active('nbarostat', val=overrides['nbarostat'], msg="user-supplied nbarostat overrides that in parameter file") if args.pressure <= 0.0: logger.info("WARNING: parameter file did not have valid pressure, using default 1.0 bar and nbarostat=25") args.force_active('pressure', val=1.0, msg="Parameter file did not have valid pressure, using default 1.0bar") args.force_active('nbarostat', val=25, msg="Parameter file did not have valid nbarostat, using default 25") elif args.nbarostat <= 0: logger.info("WARNING: parameter file has invalid nbarostat, using default 25") args.force_active('nbarostat', val=25, msg="Parameter file did not have valid nbarostat, using default 25") if args.temperature <= 0.0: logger.info("NPT must have valid thermostat, but temperature not supplied, using default 298K") args.force_active('nbarostat', val=298.0, msg="NPT needs thermostat, but temperature invalid. using default 298.0K") args.force_active('use_fs_interval', val=False, msg="target Vol protocol based on nbarostat time step intervals") args.force_active('report_interval', val=10*args.nbarostat, msg="target Vol protocol based on nbarostat time step intervals") args.force_active('pdb_report_interval', val=0, msg="don't keep track of pdb") args.force_active('netcdf_report_interval', val=0, msg="don't keep trajectory") args.force_active('checkpoint_interval', val=0, msg="don't write .chk files") args.force_active('block_interval', val=10*args.nbarostat, msg="target Vol protocol based on nbarostat intervals") args.force_active('nblocks', val = 5e4, msg="cap the number of barostat moves to try") args.deactivate('outpdb', "not writing pdb trajectory") args.deactivate('outnetcdf', "not writing netcdf trajectory") #args.force_active('outnetcdf', val="targetVolume.nc", "target Volume trajectory writes") args.force_active('logfile', val="targetVolume.log", msg="target Volume protocol log") args.force_active('chkxml', val="targetVolume.xml", msg="target Volume protocol xml") args.force_active('chkpdb', val="targetVolume.pdb", msg="target Volume protocol pdb") # === Files === # gromacs.GROMACS_TOPDIR = args.topdir top_file = args.topfile box_file = args.grofile defines = {} cont = args.cont ''' args.force_active('chkxml',val='chk_{:02n}.xml'.format(cont),msg='first one') args.force_active('chkpdb',val='chk_{:02n}.pdb'.format(cont),msg='first one') if cont > 0: args.force_active('incoord',val='chk_{:02n}.xml'.format(cont-1),msg='continuing') args.force_active('outpdb',val='output_{:02n}.pdb'.format(cont),msg='continuing') args.force_active('outnetcdf',val='output_{:02n}.nc'.format(cont),msg='continuing') args.force_active('logfile',val='thermo.log_{:02n}'.format(cont),msg='continuing') ''' incoord = args.incoord out_pdb = args.outpdb out_netcdf = args.outnetcdf logfile = args.logfile checkpointxml = args.chkxml checkpointpdb = args.chkpdb checkpointchk = 'chk_{:02n}.chk'.format(cont) # Parameters #Temp = args.temperature #K #Pressure = 1 #bar #barostatfreq = 25 #time steps #fric = args.collision_rate #1/ps dt = args.timestep #fs if args.use_fs_interval: reportfreq = int(args.report_interval/dt) netcdffreq = int(args.netcdf_report_interval/dt) #5e4 pdbfreq = int(args.pdb_report_interval/dt) checkfreq = int(args.checkpoint_interval/dt) #simtime = int( simtime ) #nanoseconds; make sure division is whole... no remainders... blocksteps = int(args.block_interval/dt) #1e6, steps per block of simulation nblocks = args.nblocks #aiming for 1 block is 1ns else: reportfreq = args.report_interval netcdffreq = args.netcdf_report_interval pdbfreq = args.pdb_report_interval checkfreq = args.checkpoint_interval blocksteps = args.block_interval nblocks = args.nblocks if quiktest==True: reportfreq = 1 blocksteps = 10 nblocks = 2 # === Start Making System === # top = gromacs.GromacsTopologyFile(top_file, defines=defines) gro = gromacs.GromacsGroFile.parse(box_file) top.box = gro.box constr = {None: None, "None":None,"HBonds":app.HBonds,"HAngles":app.HAngles,"AllBonds":app.AllBonds}[args.constraints] system = top.createSystem(nonbondedMethod=app.PME, ewaldErrorTolerance = args.ewald_error_tolerance, nonbondedCutoff=args.nonbonded_cutoff*u.nanometers, rigidWater = args.rigid_water, constraints = constr) nbm = {"NoCutoff":mm.NonbondedForce.NoCutoff, "CutoffNonPeriodic":mm.NonbondedForce.CutoffNonPeriodic, "Ewald":mm.NonbondedForce.Ewald, "PME":mm.NonbondedForce.PME, "LJPME":mm.NonbondedForce.LJPME}[args.nonbonded_method] ftmp = [f for ii, f in enumerate(system.getForces()) if isinstance(f,mm.NonbondedForce)] fnb = ftmp[0] fnb.setNonbondedMethod(nbm) logger.info("Nonbonded method ({},{})".format(args.nonbonded_method, fnb.getNonbondedMethod()) ) if (not args.dispersion_correction) or (args.nonbonded_method=="LJPME"): logger.info("Turning off tail correction...") fnb.setUseDispersionCorrection(False) logger.info("Check dispersion flag: {}".format(fnb.getUseDispersionCorrection()) ) # === Integrator, Barostat, Additional Constraints === # integrator = set_thermo(system,args) if not hasattr(args,'constraints') or (str(args.constraints) == "None" and args.rigidwater == False): args.deactivate('constraint_tolerance',"There are no constraints in this system") else: logger.info("Setting constraint tolerance to %.3e" % args.constraint_tolerance) integrator.setConstraintTolerance(args.constraint_tolerance) # === Make Platform === # logger.info("Setting Platform to %s" % str(args.platform)) try: platform = mm.Platform.getPlatformByName(args.platform) except: logger.info("Warning: %s platform not found, going to Reference platform \x1b[91m(slow)\x1b[0m" % args.platform) args.force_active('platform',"Reference","The %s platform was not found." % args.platform) platform = mm.Platform.getPlatformByName("Reference") if deviceid is not None or deviceid>=0: args.force_active('device',deviceid,msg="Using cmdline-input deviceid") if 'device' in args.ActiveOptions and (platform.getName()=="OpenCL" or platform.getName()=="CUDA"): device = str(args.device) # The device may be set using an environment variable or the input file. #if 'CUDA_DEVICE' in os.environ.keys(): #os.environ.has_key('CUDA_DEVICE'): # device = os.environ.get('CUDA_DEVICE',str(args.device)) #elif 'CUDA_DEVICE_INDEX' in os.environ.keys(): #os.environ.has_key('CUDA_DEVICE_INDEX'): # device = os.environ.get('CUDA_DEVICE_INDEX',str(args.device)) #else: # device = str(args.device) if device != None: logger.info("Setting Device to %s" % str(device)) #platform.setPropertyDefaultValue("CudaDevice", device) platform.setPropertyDefaultValue("CudaDeviceIndex", device) #platform.setPropertyDefaultValue("OpenCLDeviceIndex", device) else: logger.info("Using the default (fastest) device") else: logger.info("Using the default (fastest) device, or not using CUDA nor OpenCL") if "CudaPrecision" in platform.getPropertyNames() and (platform.getName()=="OpenCL" or platform.getName()=="CUDA"): platform.setPropertyDefaultValue("CudaPrecision", args.cuda_precision) else: logger.info("Not setting precision") args.deactivate("cuda_precision",msg="Platform does not support setting cuda_precision.") # === Create Simulation === # logger.info("Creating the Simulation object") # Get the number of forces and set each force to a different force group number. nfrc = system.getNumForces() if args.integrator != 'mtsvvvr': for i in range(nfrc): system.getForce(i).setForceGroup(i) ''' for i in range(nfrc): # Set vdW switching function manually. f = system.getForce(i) if f.__class__.__name__ == 'NonbondedForce': if 'vdw_switch' in args.ActiveOptions and args.vdw_switch: f.setUseSwitchingFunction(True) f.setSwitchingDistance(args.switch_distance) ''' #create simulation object if args.platform != None: simulation = app.Simulation(top.topology, system, integrator, platform) else: simulation = app.Simulation(top.topology, system, integrator) #print platform we're using mdparse.printcool_dictionary({i:simulation.context.getPlatform().getPropertyValue(simulation.context,i) for i in simulation.context.getPlatform().getPropertyNames()},title="Platform %s has properties:" % simulation.context.getPlatform().getName()) # Print out some more information about the system logger.info("--== System Information ==--") logger.info("Number of particles : %i" % simulation.context.getSystem().getNumParticles()) logger.info("Number of constraints : %i" % simulation.context.getSystem().getNumConstraints()) for f in simulation.context.getSystem().getForces(): if f.__class__.__name__ == 'NonbondedForce': method_names = ["NoCutoff", "CutoffNonPeriodic", "CutoffPeriodic", "Ewald", "PME", "LJPME"] logger.info("Nonbonded method : %s" % method_names[f.getNonbondedMethod()]) logger.info("Number of particles : %i" % f.getNumParticles()) logger.info("Number of exceptions : %i" % f.getNumExceptions()) if f.getNonbondedMethod() > 0: logger.info("Nonbonded cutoff : %.3f nm" % (f.getCutoffDistance() / u.nanometer)) if f.getNonbondedMethod() >= 3: logger.info("Ewald error tolerance : %.3e" % (f.getEwaldErrorTolerance())) logger.info("LJ switching function : %i" % f.getUseSwitchingFunction()) if f.getUseSwitchingFunction(): logger.info("LJ switching distance : %.3f nm" % (f.getSwitchingDistance() / u.nanometer)) # Print the sample input file here. for line in args.record(): print(line) #============================# #| Initialize & Eq/Warm-Up |# #============================# p = simulation.context.getPlatform() if p.getName()=="CUDA" or p.getName()=="OpenCL": print("simulation platform: {}".format(p.getName()) ) print(p.getPropertyNames()) print(p.getPropertyValue(simulation.context,'DeviceName')) print("Device Index: {}".format(p.getPropertyValue(simulation.context,'DeviceIndex'))) if os.path.exists(args.restart_filename) and args.read_restart: print("Restarting simulation from the restart file.") print("Currently is filler") else: # Set initial positions. if incoord.split(".")[1]=="pdb": pdb = pmd.load_file(incoord) simulation.context.setPositions(pdb.positions) elif incoord.split(".")[1]=="xml": simulation.loadState(incoord) else: logger.info("Error, can't handle input coordinate filetype") simulation.context.applyConstraints(args.constraint_tolerance) #applies constraints in current frame. logger.info("Initial potential energy is: {}".format(simulation.context.getState(getEnergy=True).getPotentialEnergy()) ) if args.integrator != 'mtsvvvr': eda = mdparse.EnergyDecomposition(simulation) eda_kcal = OrderedDict([(i, "%10.4f" % (j/4.184)) for i, j in eda.items()]) mdparse.printcool_dictionary(eda_kcal, title="Energy Decomposition (kcal/mol)") # Minimize the energy. if args.minimize: logger.info("Minimization start, the energy is:", simulation.context.getState(getEnergy=True).getPotentialEnergy()) simulation.minimizeEnergy() logger.info("Minimization done, the energy is", simulation.context.getState(getEnergy=True).getPotentialEnergy()) positions = simulation.context.getState(getPositions=True).getPositions() logger.info("Minimized geometry is written to 'minimized.pdb'") app.PDBFile.writeModel(simulation.topology, positions, open('minimized.pdb','w')) # Assign velocities. if args.gentemp > 0.0: logger.info("Generating velocities corresponding to Maxwell distribution at %.2f K" % args.gentemp) simulation.context.setVelocitiesToTemperature(args.gentemp * u.kelvin) # Equilibrate. logger.info("--== Equilibrating (%i steps, %.2f ps) ==--" % (args.equilibrate, args.equilibrate * args.timestep * u.femtosecond / u.picosecond)) if args.report_interval > 0: # Append the ProgressReport for equilibration run. simulation.reporters.append(mdparse.ProgressReport(args, sys.stdout, args.report_interval, simulation, args.equilibrate)) simulation.reporters[-1].t00 = time.time() logger.info("Progress will be reported every %i steps" % args.report_interval) # This command actually does all of the computation. simulation.step(args.equilibrate) if args.report_interval > 0: # Get rid of the ProgressReport because we'll make a new one. simulation.reporters.pop() first = args.equilibrate #============================# #| Production MD simulation |# #============================# logger.info("--== Production (%i blocks, %i steps total, %.2f ps total) ==--" % (nblocks, nblocks*blocksteps, nblocks*blocksteps * args.timestep * u.femtosecond / u.picosecond)) #===========================================# #| Add reporters for production simulation |# #===========================================# print("===== registering reporters and runnning =====") if args.report_interval > 0: logger.info("Thermo and Progress will be reported every %i steps" % args.report_interval) #simulation.reporters.append(ProgressReport(sys.stdout, args.report_interval, simulation, args.production, first)) mdparse.bak(logfile) simulation.reporters.append(app.StateDataReporter(logfile, reportfreq, step=True, potentialEnergy=True, kineticEnergy=True, temperature=True, volume=True, density=True, speed=True)) #simulation.reporters.append(app.StateDataReporter(stdout, reportfreq, step=True, # potentialEnergy=True, kineticEnergy=True, temperature=True, volume=True, density=True, speed=True)) if progressreport: simulation.reporters.append(mdparse.ProgressReport(args, sys.stdout, reportfreq, simulation, nblocks*blocksteps, first=args.equilibrate)) Prog = simulation.reporters[-1] if args.pdb_report_interval > 0: mdparse.bak(out_pdb) logger.info("PDB Reporter will write to %s every %i steps" % (out_pdb, pdbfreq)) simulation.reporters.append(app.PDBReporter(out_pdb, pdbfreq)) if args.netcdf_report_interval > 0: mdparse.bak(out_netcdf) logger.info("netcdf Reporter will write to %s every %i steps" %(out_netcdf, netcdffreq)) simulation.reporters.append(NetCDFReporter(out_netcdf, netcdffreq, crds=True, vels=args.netcdf_vels, frcs=args.netcdf_frcs)) if args.checkpoint_interval > 0: simulation.reporters.append(app.CheckpointReporter(checkpointchk, checkfreq)) #simulation.reporters.append(app.DCDReporter(out_dcd, writefreq)) #simulation.reporters.append(mdtraj.reporters.HDF5Reporter(out_hdf5, writefreq, velocities=True)) #============================# #| Finally Run! |# #============================# t1 = time.time() if progressreport: Prog.t00 = t1 #simulation.step(args.production) if simulation.topology.getUnitCellDimensions() != None : box_vectors = simulation.context.getState().getPeriodicBoxVectors() volume = mdparse.compute_volume(box_vectors) / u.nanometer**3 iblock = 0 err = abs(volume - targetVol)/targetVol while err > tol and iblock < nblocks: logger.info("Starting block {}".format(iblock)) start = time.time() simulation.step(blocksteps) end = time.time() logger.info('Took {} seconds for block {}'.format(end-start,iblock)) if simulation.topology.getUnitCellDimensions() != None : box_vectors = simulation.context.getState().getPeriodicBoxVectors() volume = mdparse.compute_volume(box_vectors) / u.nanometer**3 print("Volume is {}, targeting {}".format(volume, targetVol)) with open("finalL.txt",'w') as f: f.write("{}".format(volume**(1.0/3.0))) err = abs(volume - targetVol)/targetVol iblock = iblock+1 #avoid frequent writes, only write at the end simulation.saveState(checkpointxml) positions = simulation.context.getState(getPositions=True, enforcePeriodicBox=True).getPositions() app.PDBFile.writeFile(simulation.topology, positions, open(checkpointpdb, 'w'))