def _system(self, kwargs): top_filename = os.path.join(self.source + '/' + self.ligand_name, self.contents['.top']) topfile = app.GromacsTopFile( top_filename, periodicBoxVectors=self.grofile.getPeriodicBoxVectors()) return topfile.createSystem(**kwargs)
def get_topology(self): top_filename = os.path.join(self.source + '/' + self.ligand_name, self.contents['.top']) topology = app.GromacsTopFile( top_filename, periodicBoxVectors=self.grofile.getPeriodicBoxVectors()).topology return topology
def production(in_top, in_pdb, out_dcd, out_csv, temperature): temperature = temperature * u.kelvin # TODO: recycle John's simtk.unit parser pdb = app.PDBFile(in_pdb) top = app.GromacsTopFile(in_top) top.topology.setPeriodicBoxVectors(pdb.topology.getPeriodicBoxVectors()) system = top.createSystem(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(top.topology, system, integrator) simulation.context.setPositions(pdb.positions) simulation.context.setPeriodicBoxVectors( *pdb.topology.getPeriodicBoxVectors()) simulation.context.setVelocitiesToTemperature(temperature) print('Production.') simulation.reporters.append(app.DCDReporter(out_dcd, OUTPUT_FREQUENCY)) simulation.reporters.append( app.StateDataReporter(out_csv, OUTPUT_DATA_FREQUENCY, step=True, potentialEnergy=True, temperature=True, density=True)) converged = False while not converged: simulation.step(N_STEPS) d = pd.read_csv(out_csv, names=["step", "U", "Temperature", "Density"], skiprows=1) density_ts = np.array(d.Density) [t0, g, Neff] = ts.detectEquilibration(density_ts, nskip=1000) density_ts = density_ts[t0:] density_mean_stderr = density_ts.std() / np.sqrt(Neff) if density_mean_stderr < STD_ERROR_TOLERANCE: converged = True
def _build_system(self, molecule: "Ligand", input_files: Optional[List[str]] = None) -> System: # get the topfile top_file = None if input_files is not None: for file in input_files: if file.endswith(".top"): top_file = file break # if it was not given try and guess it top_file = top_file or f"{molecule.name}.top" top = app.GromacsTopFile(top_file, ) system = top.createSystem() return system
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')
# 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 print("Creating integrator") integrator = mm.LangevinIntegrator(
#!/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)
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
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(): if force.__class__.__name__ == 'NonBondedForce': force.setUseSwitchingFunction(True) force.setSwitchingDistance(1.0*units.nanometers)
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) ## # Build System logging.info('Building system objects') system = system_top.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=1.2 * units.nanometers, constraints=app.HBonds) # Add switching # Is there a better way? for force in system.getForces(): if force.__class__.__name__ == 'NonBondedForce': force.setUseSwitchingFunction(True) force.setSwitchingDistance(1.0 * units.nanometers)
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
nsteps_per_snapshot = 500000 nsteps_per_density = 500 output_pdbfile = 'output.pdb' density_outfile = 'statedata.out' ################################################################################ # MAIN ################################################################################ # Read initial snapshot pdbfile = app.PDBFile('67-66-3-liq.pdb') # Read gromacs input file and create system print('Reading gromacs topology and creating system...') top = app.GromacsTopFile( '67-66-3-liq.top', periodicBoxVectors=pdbfile.topology.getPeriodicBoxVectors(), includeDir='.') system = top.createSystem(nonbondedMethod=app.PME, nonbondedCutoff=cutoff, constraints=constraints, removeCMMotion=remove_com_motion, rigidWater=False, ewaldErrorTolerance=pme_tolerance) # Add a barostat print('Adding barostat...') barostat = openmm.MonteCarloBarostat(pressure, temperature) system.addForce(barostat) # Ensure we are using a switching function forces = {