def convert_input(self): """ Converts inputs to OpenMM readable topologies and positions. Currently supports pdb inputs as well as Amber and Gromacs input files. """ if self.system_info_format == 'pdb': # instantiate OpenMM pdb object if type(self.system_info) is list: self.pdb = OM_app.PDBFile(self.system_info[0]) elif type(self.system_info) is str: self.pdb = OM_app.PDBFile(self.system_info) # instantiate OpenMM forcefield object self.forcefield = OM_app.ForceField(self.ff, self.ff_water) self.topology = self.pdb.topology self.positions = self.pdb.positions self.PeriodicBoxVector = self.topology.getPeriodicBoxVectors() elif self.system_info_format in ['Amber', 'amber']: for fil in self.system_info: if fil.endswith('prmtop'): self.forcefield = OM_app.AmberPrmtopFile(fil) self.topology = self.forcefield.topology self.use_pdb = False if fil.endswith('pdb'): self.pdb = OM_app.PDBFile(fil) self.forcefield = OM_app.ForceField(self.ff, self.ff_water) self.topology = self.pdb.topology self.use_pdb = True if fil.endswith('inpcrd'): self.inpcrd = OM_app.AmberInpcrdFile(fil) self.positions = self.inpcrd.positions self.PeriodicBoxVector = self.inpcrd.boxVectors elif self.system_info_format in ['Gromacs', 'gromacs']: for fil in self.system_info: if 'gro' in fil: self.pdb = OM_app.GromacsGroFile(fil) for fil in self.system_info: if 'top' in fil: self.forcefield = OM_app.GromacsTopFile( fil, periodicBoxVectors=self.pdb.getPeriodicBoxVectors()) self.topology = self.forcefield.topology
def equilibrate(in_top, in_gro, out_dcd, out_pdb, temperature): temperature = temperature * u.kelvin # TODO: recycle John's simtk.unit parser gro = app.GromacsGroFile(in_gro) top = app.GromacsTopFile(in_top, unitCellDimensions=gro.getUnitCellDimensions()) system = top.createSystem(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(top.topology, system, integrator) simulation.context.setPositions(gro.positions) state = simulation.context.getState(getEnergy=True) print(state.getPotentialEnergy()) print('Minimizing.') simulation.minimizeEnergy() state = simulation.context.getState(getEnergy=True) print(state.getPotentialEnergy()) simulation.context.setVelocitiesToTemperature(temperature) print('Equilibrating.') simulation.reporters.append( app.DCDReporter(out_dcd, OUTPUT_FREQUENCY_EQUIL)) simulation.step(N_EQUIL_STEPS) # Re-write a better PDB with correct box sizes. traj = md.load(out_dcd, top=in_gro)[-1] traj.save(out_pdb)
def _load_gromacs_structure(inp): # Load structure gmxtop = app.GromacsTopFile(inp.topology) gmxgro = app.GromacsGroFile(inp.coordinates) return gmxtop, gmxgro
import simtk.openmm as mm import simtk.openmm.app as app from simtk import unit # input topology, psf, and force field files generated from CHARMM-GUI Solution Builder print('Parsing system topology and coordinates') # charmm-gui does not generate a .gro file, but it can easily be prepared in gromacs via # gmx editconf -f step3_charmm2gmx.pdb -box 7.5 7.5 7.5 -o step3_charmm2gmx.gro # gmx editconf autmatically translates coordinates to be within (0,Lx), (0,Ly), (0,Lz) coord = app.GromacsGroFile('step3_charmm2gmx.gro') topology = app.GromacsTopFile('topol.top', periodicBoxVectors=coord.getPeriodicBoxVectors()) print('Constructing sytem') # use PME for long-range electrostatics, cutoff for short-range interactions # constrain H-bonds with RATTLE, constrain water with SETTLE system = topology.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=1.2 * unit.nanometers, constraints=app.HBonds, rigidWater=True, ewaldErrorTolerance=0.0005) print('Constructing integrator') integrator = mm.LangevinIntegrator(325 * unit.kelvin, 1.0 / unit.picosecond, 2.0 * unit.femtosecond) print('Constructing and adding Barostat to system') barostat = mm.MonteCarloBarostat(1.0 * unit.bar, 5.0 * unit.kelvin, 25) system.addForce(barostat) print('Selecting MD platform')
import sys # OpenMM Imports import simtk.openmm as mm import simtk.openmm.app as app # ParmEd Imports # from parmed import load_file from parmed import unit as u from numpy import sqrt, mean # Load the Gromacs files print("Loading Gromacs files...") gro = app.GromacsGroFile("step4.1_equilibration.gro") top = app.GromacsTopFile("topol.top", periodicBoxVectors=gro.getPeriodicBoxVectors(), includeDir=".") # Create the OpenMM system print("Creating OpenMM System") system = top.createSystem( nonbondedMethod=app.PME, nonbondedCutoff=1.2 * u.nanometer, constraints=app.HBonds, # implicitSolvent=app.GBn2, # implicitSolventSaltConc=0.1*u.moles/u.liter, ) # Create the integrator to do Langevin dynamics
#!/bin/env python """ Convert {.gro,.top} to .pdb """ import os from simtk import openmm, unit from simtk.openmm import app for dir, dirs, files in os.walk('.'): prefix = '3sy7_lig_solv_GMX' gro_filename = prefix + '.gro' top_filename = prefix + '.top' pdb_filename = prefix + '.pdb' print(files) if (gro_filename in files) and (top_filename in files): grofile = app.GromacsGroFile(os.path.join(dir, gro_filename)) topfile = app.GromacsTopFile( os.path.join(dir, top_filename), periodicBoxVectors=grofile.getPeriodicBoxVectors()) with open(os.path.join(dir, pdb_filename), 'w') as outfile: app.PDBFile.writeFile(topfile.topology, grofile.positions, outfile)
# if i != anum_amber: # print i, anum_amber, anum_gro if anum_amber != anum_gro: print "Gromacs and AMBER atoms don't have the same order:", "\x1b[91m", i, anum_amber, anum_gro, "\x1b[0m" # raise RuntimeError # anumMap_amb_gro[anum_amber] = anum_gro # Run a quick MD simulation in Gromacs _exec("grompp_d -f eq.mdp -o eq.tpr") # You can set print_to_screen=True to see how fast it's going _exec("mdrun_d -nt 1 -v -stepout 10 -deffnm eq", print_to_screen=False) # LPW WARNING: This is Changed _exec("trjconv_d -s eq.tpr -f eq.trr -o eq.gro -ndec 9 -pbc mol -dump 0", stdin="0\n") # Confirm that constraints are satisfied OMM_eqgro = app.GromacsGroFile('eq.gro') OMM_prmtop = app.AmberPrmtopFile('prmtop') system = OMM_prmtop.createSystem(nonbondedMethod=app.NoCutoff) integ = mm.VerletIntegrator(1.0 * u.femtosecond) plat = mm.Platform.getPlatformByName('Reference') simul = app.Simulation(OMM_prmtop.topology, system, integ) simul.context.setPositions(OMM_eqgro.positions) simul.context.applyConstraints(1e-12) state = simul.context.getState(getPositions=True) pos = np.array(state.getPositions().value_in_unit(u.angstrom)).reshape(-1, 3) M = Molecule('eq.gro') M.xyzs[0] = pos M.write('constrained.gro') # Gromacs calculation GMX_Energy, GMX_Force, Ecomps_GMX = Calculate_GMX('constrained.gro',
def setup_binding_gromacs(args): """ Set up ligand binding free energy calculation using gromacs prmtop/inpcrd files. Parameters ---------- args : dict Command-line arguments dict from docopt. Returns ------- phases : list of str Phases (thermodynamic legs) of the calculation. systems : dict systems[phase] is the OpenMM System reference object for phase 'phase'. positions : dict positions[phase] is a set of positions (or list of positions) for initializing replicas. atom_indices : dict atom_indices[phase][component] is list of atom indices for component 'component' in phase 'phase'. """ verbose = args['--verbose'] # Implicit solvent if args['--gbsa']: implicitSolvent = getattr(app, args['--gbsa']) else: implicitSolvent = None # Select nonbonded treatment # TODO: Carefully check whether input file is periodic or not. if args['--nbmethod']: nonbondedMethod = getattr(app, args['--nbmethod']) else: nonbondedMethod = None # Constraints if args['--constraints']: constraints = getattr(app, args['--constraints']) else: constraints = None # Cutoff if args['--cutoff']: nonbondedCutoff = process_unit_bearing_argument( args, '--cutoff', unit.nanometers) else: nonbondedCutoff = None # COM removal removeCMMotion = False # Prepare phases of calculation. phase_prefixes = [ 'solvent', 'complex' ] # list of calculation phases (thermodynamic legs) to set up components = ['ligand', 'receptor', 'solvent'] # components of the binding system systems = dict( ) # systems[phase] is the System object associated with phase 'phase' positions = dict( ) # positions[phase] is a list of coordinates associated with phase 'phase' atom_indices = dict( ) # ligand_atoms[phase] is a list of ligand atom indices associated with phase 'phase' setup_directory = args[ '--setupdir'] # Directory where prmtop/inpcrd files are to be found for phase_prefix in phase_prefixes: if verbose: logger.info("reading phase %s: " % phase_prefix) # Read gromacs input files. gro_filename = os.path.join(setup_directory, '%s.gro' % phase_prefix) top_filename = os.path.join(setup_directory, '%s.top' % phase_prefix) if verbose: logger.info('reading gromacs .gro file: %s' % gro_filename) gro = app.GromacsGroFile(gro_filename) if verbose: logger.info( 'reading gromacs .top file "%s" using gromacs include directory "%s"' % (top_filename, args['--gromacsinclude'])) top = app.GromacsTopFile( top_filename, unitCellDimensions=gro.getUnitCellDimensions(), includeDir=args['--gromacsinclude']) # Assume explicit solvent. # TODO: Modify this if we can have implicit solvent. is_periodic = True phase_suffix = 'explicit' # Adjust nonbondedMethod. # TODO: Ensure that selected method is appropriate. if nonbondedMethod == None: if is_periodic: nonbondedMethod = app.CutoffPeriodic else: nonbondedMethod = app.NoCutoff # TODO: Check to make sure both prmtop and inpcrd agree on explicit/implicit. phase = '%s-%s' % (phase_prefix, phase_suffix) systems[phase] = top.createSystem(nonbondedMethod=nonbondedMethod, nonbondedCutoff=nonbondedCutoff, constraints=constraints, removeCMMotion=removeCMMotion) positions[phase] = gro.getPositions(asNumpy=True) # Check to make sure number of atoms match between prmtop and inpcrd. prmtop_natoms = systems[phase].getNumParticles() inpcrd_natoms = positions[phase].shape[0] if prmtop_natoms != inpcrd_natoms: raise Exception( "Atom number mismatch: prmtop %s has %d atoms; inpcrd %s has %d atoms." % (prmtop_filename, prmtop_natoms, inpcrd_filename, inpcrd_natoms)) # Find ligand atoms and receptor atoms. ligand_dsl = args['--ligand'] # MDTraj DSL that specifies ligand atoms atom_indices[phase] = find_components(top.topology, ligand_dsl) phases = systems.keys() return [phases, systems, positions, atom_indices]
def __init__(self, gromacs_input_path=None, ligand_resseq=None, output_filename=None, verbose=False): """Set up a SAMS permeation PMF simulation. Parameters ---------- gromacs_input_path : str, optional, default=None If specified, use gromacs files in this directory ligand_resseq : str, optional, default='MOL' Resdiue sequence id for ligand in reference PDB file output_filename : str, optional, default=None NetCDF output filename verbose : bool, optional, default=False If True, print verbose output """ # Setup general logging logging.root.setLevel(logging.DEBUG) logging.basicConfig(level=logging.DEBUG) yank.utils.config_root_logger(verbose=verbose, log_file_path=None) self._setup_complete = False # Set default parameters self.temperature = 310.0 * unit.kelvin self.pressure = 1.0 * unit.atmospheres self.collision_rate = 1.0 / unit.picoseconds self.timestep = 4.0 * unit.femtoseconds self.n_steps_per_iteration = 1250 self.n_iterations = 10000 self.checkpoint_interval = 50 self.gamma0 = 10.0 self.flatness_threshold = 10.0 self.anneal_ligand = True # Check input if gromacs_input_path is None: raise ValueError('gromacs_input_path must be specified') if ligand_resseq is None: raise ValueError('ligand_resseq must be specified') if output_filename is None: raise ValueError('output_filename must be specified') # Discover contents of the input path by suffix contents = { pathlib.Path(filename).suffix: filename for filename in os.listdir(gromacs_input_path) } gro_filename = os.path.join(gromacs_input_path, contents['.gro']) top_filename = os.path.join(gromacs_input_path, contents['.top']) pdb_filename = os.path.join(gromacs_input_path, contents['.pdb']) # Load system files print('Reading system from path: {}'.format(gromacs_input_path)) self.grofile = app.GromacsGroFile(gro_filename) self.topfile = app.GromacsTopFile( top_filename, periodicBoxVectors=self.grofile.getPeriodicBoxVectors()) self.pdbfile = app.PDBFile(pdb_filename) # Create MDTraj Trajectory for reference PDB file for use in atom selections and slicing self.mdtraj_refpdb = md.load(pdb_filename) self.mdtraj_topology = self.mdtraj_refpdb.topology self.analysis_particle_indices = self.mdtraj_topology.select( 'not water') # Store output filename self.output_filename = output_filename # Store ligand resseq self.ligand_resseq = ligand_resseq
from simtk import unit as u from simtk import openmm as mm from simtk.openmm import app import martini_openmm as martini import numpy as np # do all tests with reference platform to avoid messing # with cuda / drivers / etc platform = mm.Platform.getPlatformByName("Reference") conf = app.GromacsGroFile("minimized.gro") box_vectors = conf.getPeriodicBoxVectors() top = martini.GromacsMartiniV2TopFile("dppc.top", periodicBoxVectors=box_vectors) system = top.createSystem(nonbondedCutoff=1.1 * u.nanometer) integrator = mm.LangevinIntegrator(300 * u.kelvin, 1.0 / u.picosecond, 2 * u.femtosecond) simulation = mm.app.Simulation(top.topology, system, integrator, platform) simulation.context.setPositions(conf.getPositions()) state = simulation.context.getState(getEnergy=True, getForces=True) energy = state.getPotentialEnergy().value_in_unit(u.kilojoule_per_mole) forces = np.array(state.getForces().value_in_unit(u.kilojoule / u.nanometer / u.mole)) with open('energy.txt', 'w') as efile: print(energy, file=efile) np.savetxt('forces.txt', forces)
def gen_simulation(gro_file, psf_file, prm_file, T, P, pcoupl='iso'): print('Building system...') gro = app.GromacsGroFile(gro_file) psf = OplsPsfFile(psf_file, periodicBoxVectors=gro.getPeriodicBoxVectors()) prm = app.CharmmParameterSet(prm_file) system = psf.createSystem(prm, nonbondedMethod=app.PME, ewaldErrorTolerance=1E-5, nonbondedCutoff=1.2 * nm, constraints=app.HBonds, rigidWater=True, verbose=True) if not psf.is_drude: print('\tLangevin thermostat: 1.0/ps') integrator = mm.LangevinIntegrator(T * kelvin, 1.0 / ps, 0.001 * ps) else: print('\tDual Langevin thermostat: 10/ps, 50/ps') integrator = mm.DrudeLangevinIntegrator(T * kelvin, 10 / ps, 1 * kelvin, 50 / ps, 0.001 * ps) integrator.setMaxDrudeDistance(0.02 * nm) if pcoupl == 'iso': print('\tIsotropic barostat') system.addForce(mm.MonteCarloBarostat(P * bar, T * kelvin, 25)) elif pcoupl == 'xyz': print('\tAnisotropic barostat') system.addForce( mm.MonteCarloAnisotropicBarostat([P * bar] * 3, T * kelvin, True, True, True, 25)) elif pcoupl == 'xy': print('\tAnisotropic Barostat only for X and Y') system.addForce( mm.MonteCarloAnisotropicBarostat([P * bar] * 3, T * kelvin, True, True, False, 25)) else: print('\tNo barostat') print('Initializing simulation...') platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed'} sim = app.Simulation(psf.topology, system, integrator, platform, properties) sim.context.setPositions(gro.positions) sim.context.setVelocitiesToTemperature(T * kelvin) sim.reporters.append(GroReporter('dump.gro', 10000)) sim.reporters.append(app.DCDReporter('dump.dcd', 1000)) sim.reporters.append( app.StateDataReporter(sys.stdout, 500, step=True, temperature=True, potentialEnergy=True, kineticEnergy=True, volume=True, density=True, elapsedTime=True, speed=True, separator='\t')) state = sim.context.getState(getEnergy=True) print('Energy: ' + str(state.getPotentialEnergy())) return sim
# Slurm sets this sometimes gpu_ids = os.getenv('CUDA_VISIBLE_DEVICES') if gpu_ids: properties['DeviceIndex'] = gpu_ids elif platform_name == 'CPU': cpu_threads = os.getenv('SLURM_CPUS_PER_TASK') if cpu_threads: properties['Threads'] = cpu_threads # Split input file name fname, fext = os.path.splitext(cmd.structure) # Read structure structure = app.GromacsGroFile(cmd.structure) box_vectors = structure.getPeriodicBoxVectors() topology = app.GromacsTopFile(cmd.topology, periodicBoxVectors=box_vectors, includeDir=cmd.ffdir) # Build system & integrator logging.info('Setting up system and integrator') system = topology.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=1.2*units.nanometer, # constraints=app.HBonds, # easy on the minimizer rigidWater=True) # Add switching # Is there a better way? for force in system.getForces():
logging.info('Using {}/{} CPUs/GPUs'.format(cpu_res, num_gpu)) properties['DeviceIndex'] = gpu_res else: platform = mm.Platform.getPlatformByName('CPU') properties['Threads'] = cpu_res logging.info('Using platform: {}'.format(platform.getName())) ## # Read structure, coordinates, and force field definitions logging.info('Reading GRO file: {}'.format(user_args.gro)) if not os.path.isfile(user_args.gro): raise IOError('Could not read/open input file: {}'.format(user_args.gro)) else: rootname = os.path.basename(user_args.gro)[:-4] system_gro = app.GromacsGroFile(user_args.gro) box_vectors = system_gro.getPeriodicBoxVectors() logging.info('Reading TOP file: {}'.format(user_args.top)) logging.info('Reading FF definitions from {}'.format(user_args.ffdir)) if not os.path.isdir(user_args.ffdir): raise IOError('Could not read/open folder: {}'.format(user_args.ffdir)) if not os.path.isfile(user_args.top): raise IOError('Could not read/open input file: {}'.format(user_args.top)) else: system_top = app.GromacsTopFile(user_args.top, periodicBoxVectors=box_vectors, includeDir=user_args.ffdir) ##
def init_openmm(self, integrator_params=None, create_system_params=None): """ Method that initiates OpenMM by creating Parameters ---------- integrator_params : dict Keyword arguments passed to the simtk.openmm.openmm.LangevinIntegrator create_system_params : dict Keyword arguments passed to simtk.openmm.app.amberprmtopfile.createSystem Returns ------- system : simtk.openmm.openmm.System OpenMM system created. """ from simtk.openmm import XmlSerializer assert self.topology_format is not None, "No topology format was provided." assert self.crd_format is not None, "No coordinate format was provided." if self.topology_format.upper() in ["AMBER", "GROMACS", "CHARMM"]: assert self.top_file is not None, "Topology format is {} but no topology file was provided.".format( self.topology_format) else: raise NotImplementedError( "Topology format {} is not known.".format( self.topology_format)) assert self.crd_file is not None, "create_system flag is True but no crd_file was provided." if self.platform_name is None: logging.info("No platform set. Will use reference.") self.platform_name = "Reference" else: assert self.platform_name in [ "Reference", "CPU", "OpenCL", "CUDA" ], """create_system flag is True but no correct platform was provided.""" # Read topology if self.topology_format.upper() == "AMBER": if self.topology is None: top = app.AmberPrmtopFile(self.top_file) self.topology = top.topology elif self.topology_format.upper() == "GROMACS": if self.topology is None: top = app.GromacsTopFile(self.top_file) self.topology = top.topology elif self.topology_format.upper() == "CHARMM": if self.topology is None: top = app.CharmmPsfFile(self.top_file) self.topology = top.topology charmm_params = app.CharmmParameterSet('charmm.rtf', self.charmm_param_file) else: raise NotImplementedError( "Topology format {} is not currently supported.".format( self.topology_format)) # Read coordinate file if self.crd_format.upper() == "AMBER": crd = app.AmberInpcrdFile(self.crd_file) elif self.crd_format.upper() == "GROMACS": crd = app.GromacsGroFile(self.crd_file) elif self.crd_format.upper() == "CHARMM": crd = app.CharmmCrdFile(self.crd_file) elif self.crd_format.upper() == "PDB": crd = app.PDBFile(self.crd_file) else: raise NotImplementedError( "Coordinate format {} is not currently supported.".format( self.crd_format)) if self.system is None: if self.xml_file is None: assert create_system_params is not None, "No settings to create the system were provided." logging.info("Creating OpenMM System from {} file.".format( self.topology_format)) if self.topology_format.upper() == "CHARMM": self.system = top.createSystem(charmm_params, **create_system_params) else: self.system = top.createSystem(**create_system_params) else: logging.info("Creating OpenMM System from XML file.") xml_file = open(self.xml_file) self.system = XmlSerializer.deserializeSystem(xml_file.read()) xml_file.close() if self.integrator is None: assert integrator_params is not None, "No settings to create the integrator were provided." self.integrator = openmm.LangevinIntegrator( integrator_params['temperature'], integrator_params["frictionCoeff"], integrator_params["stepSize"]) logging.info("Creating OpenMM integrator.") if self.platform is None: self.platform = openmm.Platform.getPlatformByName( self.platform_name) logging.info("Creating OpenMM platform.") if self.context is None: self.context = openmm.Context(self.system, self.integrator, self.platform) logging.info("Creating OpenMM Context.") # Set positions in context self.context.setPositions(crd.positions) return self.system
def get_positions(self, platform=None): gro_filename = os.path.join(self.source + '/' + self.ligand_name, self.contents['.gro']) self.grofile = app.GromacsGroFile(gro_filename) return self.grofile.positions