def get_available_platforms(): from simtk.openmm import Platform platform_names = [] for i in range(Platform.getNumPlatforms()): p = Platform.getPlatform(i) name = p.getName() platform_names.append(name) return platform_names
def __init__(self, topology=None, system=None, pbc=False, platform='CUDA'): from .md import MD from .quench import Quench from .move import Move from .distance import Distance from .acceptance import Acceptance if topology is None: raise ValueError('topology is needed') if system is None: raise ValueError('system is needed') integrator = LangevinIntegrator(0 * u.kelvin, 1.0 / u.picoseconds, 2.0 * u.femtoseconds) #integrator.setConstraintTolerance(0.00001) if platform == 'CUDA': platform = Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed'} elif platform == 'CPU': platform = Platform.getPlatformByName('CPU') properties = {} self.topology = topology self.context = Context(system, integrator, platform, properties) self.n_atoms = msm.get(self.context, target='system', n_atoms=True) self.n_dof = 0 for i in range(system.getNumParticles()): if system.getParticleMass(i) > 0 * u.dalton: self.n_dof += 3 for i in range(system.getNumConstraints()): p1, p2, distance = system.getConstraintParameters(i) if system.getParticleMass( p1) > 0 * u.dalton or system.getParticleMass( p2) > 0 * u.dalton: self.n_dof -= 1 if any( type(system.getForce(i)) == CMMotionRemover for i in range(system.getNumForces())): self.n_dof -= 3 self.pbc = pbc if self.pbc: raise NotImplementedError self.md = MD(self) self.quench = Quench(self) self.move = Move(self) self.distance = Distance(self) self.acceptance = Acceptance(self)
def test_xtc_reporter_append(tmpdir, get_fn): pdb = PDBFile(get_fn('native.pdb')) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') # NO PERIODIC BOUNDARY CONDITIONS system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) xtcfile = os.path.join(tmpdir, 'traj.xtc') xtcfile_cp = os.path.join(tmpdir, 'traj_cp.xtc') checkpoint = os.path.join(tmpdir, 'checkpoint.chk') reporter = XTCReporter(xtcfile, 2) simulation.reporters.append(reporter) simulation.reporters.append(CheckpointReporter(checkpoint, 10)) simulation.step(10) reporter.close() shutil.copyfile(xtcfile, xtcfile_cp) system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.loadCheckpoint(checkpoint) reporter = XTCReporter(xtcfile, 2, append=True) simulation.reporters.append(reporter) simulation.step(10) reporter.close() xtc_traj = md.load(xtcfile, top=get_fn('native.pdb')) xtc_traj_cp = md.load(xtcfile_cp, top=get_fn('native.pdb')) eq(xtc_traj.xyz[:5], xtc_traj_cp.xyz) eq(xtc_traj.n_frames, 10) eq(xtc_traj_cp.n_frames, 5) eq(xtc_traj.time[:5], xtc_traj_cp.time)
def setup_platform_with_resources(compute_resources): """Creates an OpenMM `Platform` object which requests a set amount of compute resources (e.g with a certain number of cpus). Parameters ---------- compute_resources: ComputeResources Returns ------- Platform The created platform """ from simtk.openmm import Platform # Setup the requested platform: if compute_resources.number_of_gpus > 0: # A platform which runs on GPUs has been requested. platform_name = 'CUDA' if compute_resources.preferred_gpu_toolkit == 'CUDA' else 'OpenCL' # noinspection PyCallByClass,PyTypeChecker platform = Platform.getPlatformByName(platform_name) if compute_resources.gpu_device_indices is not None: property_platform_name = platform_name if compute_resources.preferred_gpu_toolkit == 'CUDA': property_platform_name = platform_name.lower().capitalize() platform.setPropertyDefaultValue( property_platform_name + 'DeviceIndex', compute_resources.gpu_device_indices) logging.info('Setting up an openmm platform on GPU {}'.format( compute_resources.gpu_device_indices or 0)) else: # noinspection PyCallByClass,PyTypeChecker platform = Platform.getPlatformByName('CPU') platform.setPropertyDefaultValue( 'Threads', str(compute_resources.number_of_threads)) logging.info('Setting up a simulation with {} threads'.format( compute_resources.number_of_threads)) return platform
def energy_minimization(item, platform_name='CUDA', verbose=True): from simtk.openmm import LangevinIntegrator, Platform, Context, LocalEnergyMinimizer_minimize from simtk import unit # Integrator. integrator = LangevinIntegrator(0 * unit.kelvin, 1.0 / unit.picoseconds, 2.0 * unit.femtoseconds) # Platform. platform = Platform.getPlatformByName(platform_name) # Context. context = Context(item.system, integrator, platform) context.setPositions(item.coordinates) # Minimization. if verbose == True: energy = context.getState(getEnergy=True).getPotentialEnergy() print('Potential energy before minimization: {}'.format(energy)) LocalEnergyMinimizer_minimize(context) if verbose == True: energy = context.getState(getEnergy=True).getPotentialEnergy() print('Potential energy after minimization: {}'.format(energy)) item.coordinates = context.getState(getPositions=True).getPositions( asNumpy=True) pass
def writeHeader(topology, file=sys.stdout, entry=None): """Write out the header for a PDBx/mmCIF file. Parameters ---------- topology : Topology The Topology defining the molecular system being written file : file=stdout A file to write the file to entry : str=None The entry ID to assign to the CIF file """ if entry is not None: print('data_%s' % entry, file=file) else: print('data_cell', file=file) print("# Created with OpenMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file) print('#', file=file) vectors = topology.getPeriodicBoxVectors() if vectors is not None: a, b, c, alpha, beta, gamma = computeLengthsAndAngles(vectors) RAD_TO_DEG = 180 / math.pi print('_cell.length_a %10.4f' % (a * 10), file=file) print('_cell.length_b %10.4f' % (b * 10), file=file) print('_cell.length_c %10.4f' % (c * 10), file=file) print('_cell.angle_alpha %10.4f' % (alpha * RAD_TO_DEG), file=file) print('_cell.angle_beta %10.4f' % (beta * RAD_TO_DEG), file=file) print('_cell.angle_gamma %10.4f' % (gamma * RAD_TO_DEG), file=file) print('##', file=file) print('loop_', file=file) print('_atom_site.group_PDB', file=file) print('_atom_site.id', file=file) print('_atom_site.type_symbol', file=file) print('_atom_site.label_atom_id', file=file) print('_atom_site.label_alt_id', file=file) print('_atom_site.label_comp_id', file=file) print('_atom_site.label_asym_id', file=file) print('_atom_site.label_entity_id', file=file) print('_atom_site.label_seq_id', file=file) print('_atom_site.pdbx_PDB_ins_code', file=file) print('_atom_site.Cartn_x', file=file) print('_atom_site.Cartn_y', file=file) print('_atom_site.Cartn_z', file=file) print('_atom_site.occupancy', file=file) print('_atom_site.B_iso_or_equiv', file=file) print('_atom_site.Cartn_x_esd', file=file) print('_atom_site.Cartn_y_esd', file=file) print('_atom_site.Cartn_z_esd', file=file) print('_atom_site.occupancy_esd', file=file) print('_atom_site.B_iso_or_equiv_esd', file=file) print('_atom_site.pdbx_formal_charge', file=file) print('_atom_site.auth_seq_id', file=file) print('_atom_site.auth_comp_id', file=file) print('_atom_site.auth_asym_id', file=file) print('_atom_site.auth_atom_id', file=file) print('_atom_site.pdbx_PDB_model_num', file=file)
def get_potential_energy(item, coordinates=None, platform_name='CUDA'): from simtk.openmm import LangevinIntegrator, Platform, Context from simtk import unit import numpy as np integrator = LangevinIntegrator(0.0 * unit.kelvin, 0.0 / unit.picoseconds, 2.0 * unit.femtoseconds) platform = Platform.getPlatformByName(platform_name) context = Context(item.system, integrator, platform) if coordinates is None: context.setPositions(item.coordinates) else: context.setPositions(coordinates) if item.box is not None: context.setPeriodicBoxVectors(item.box[0], item.box[1], item.box[2]) state = context.getState(getEnergy=True) potential_energy = state.getPotentialEnergy() return potential_energy
def _prep_sim(self, coords, external_forces=[]): try: from simtk.openmm import Platform, LangevinIntegrator, Vec3 from simtk.openmm.app import Modeller, ForceField, \ CutoffNonPeriodic, PME, Simulation, HBonds from simtk.unit import angstrom, nanometers, picosecond, \ kelvin, Quantity, molar except ImportError: raise ImportError( 'Please install PDBFixer and OpenMM in order to use ClustENM.') positions = Quantity([Vec3(*xyz) for xyz in coords], angstrom) modeller = Modeller(self._topology, positions) if self._sol == 'imp': forcefield = ForceField(*self._force_field) system = forcefield.createSystem(modeller.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds) if self._sol == 'exp': forcefield = ForceField(*self._force_field) modeller.addSolvent(forcefield, padding=self._padding * nanometers, ionicStrength=self._ionicStrength * molar) system = forcefield.createSystem(modeller.topology, nonbondedMethod=PME, nonbondedCutoff=1.0 * nanometers, constraints=HBonds) for force in external_forces: system.addForce(force) integrator = LangevinIntegrator(self._temp * kelvin, 1 / picosecond, 0.002 * picosecond) # precision could be mixed, but single is okay. platform = self._platform if self._platform is None else Platform.getPlatformByName( self._platform) properties = None if self._platform is None: properties = {'Precision': 'single'} elif self._platform in ['CUDA', 'OpenCL']: properties = {'Precision': 'single'} simulation = Simulation(modeller.topology, system, integrator, platform, properties) simulation.context.setPositions(modeller.positions) return simulation
def writeHeader(topology, file=sys.stdout, entry=None): """Write out the header for a PDBx/mmCIF file. Parameters ---------- topology : Topology The Topology defining the molecular system being written file : file=stdout A file to write the file to entry : str=None The entry ID to assign to the CIF file """ if entry is not None: print('data_%s' % entry, file=file) else: print('data_cell', file=file) print("# Created with OpenMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file) print('#', file=file) vectors = topology.getPeriodicBoxVectors() if vectors is not None: a, b, c, alpha, beta, gamma = computeLengthsAndAngles(vectors) RAD_TO_DEG = 180/math.pi print('_cell.length_a %10.4f' % (a*10), file=file) print('_cell.length_b %10.4f' % (b*10), file=file) print('_cell.length_c %10.4f' % (c*10), file=file) print('_cell.angle_alpha %10.4f' % (alpha*RAD_TO_DEG), file=file) print('_cell.angle_beta %10.4f' % (beta*RAD_TO_DEG), file=file) print('_cell.angle_gamma %10.4f' % (gamma*RAD_TO_DEG), file=file) print('##', file=file) print('loop_', file=file) print('_atom_site.group_PDB', file=file) print('_atom_site.id', file=file) print('_atom_site.type_symbol', file=file) print('_atom_site.label_atom_id', file=file) print('_atom_site.label_alt_id', file=file) print('_atom_site.label_comp_id', file=file) print('_atom_site.label_asym_id', file=file) print('_atom_site.label_entity_id', file=file) print('_atom_site.label_seq_id', file=file) print('_atom_site.pdbx_PDB_ins_code', file=file) print('_atom_site.Cartn_x', file=file) print('_atom_site.Cartn_y', file=file) print('_atom_site.Cartn_z', file=file) print('_atom_site.occupancy', file=file) print('_atom_site.B_iso_or_equiv', file=file) print('_atom_site.Cartn_x_esd', file=file) print('_atom_site.Cartn_y_esd', file=file) print('_atom_site.Cartn_z_esd', file=file) print('_atom_site.occupancy_esd', file=file) print('_atom_site.B_iso_or_equiv_esd', file=file) print('_atom_site.pdbx_formal_charge', file=file) print('_atom_site.auth_seq_id', file=file) print('_atom_site.auth_comp_id', file=file) print('_atom_site.auth_asym_id', file=file) print('_atom_site.auth_atom_id', file=file) print('_atom_site.pdbx_PDB_model_num', file=file)
def create_simulation(self, topology, system): self.integrator = self.create_integrator(system) if self.platform is None: simulation = Simulation(topology, system, self.integrator) else: platform = Platform.getPlatformByName(self.platform) simulation = Simulation(topology, system, self.integrator, platform) for reporter in self.reporters: simulation.reporters.append(reporter) return simulation
def run(self): """Run the process: set positions and compute energies and forces. Positions and box vectors are received from the task_queue in units of nanometers. Energies and forces are pushed to the result_queue in units of kJ/mole and kJ/mole/nm, respectively. """ from simtk import unit from simtk.openmm import Platform, Context # create the context # it is crucial to do that in the run function and not in the constructor # for some reason, the CPU platform hangs if the context is created in the constructor # see also https://github.com/openmm/openmm/issues/2602 openmm_platform = Platform.getPlatformByName(self._openmm_platform_name) self._openmm_context = Context( self._openmm_system, self._openmm_integrator, openmm_platform, self._openmm_platform_properties ) self._openmm_context.reinitialize(preserveState=True) # get tasks from the task queue for task in iter(self._task_queue.get, None): (index, positions, box_vectors, evaluate_energy, evaluate_force, evaluate_positions, evaluate_path_probability_ratio, err_handling, n_simulation_steps) = task try: # initialize state self._openmm_context.setPositions(positions) if box_vectors is not None: self._openmm_context.setPeriodicBoxVectors(box_vectors) log_path_probability_ratio = self._openmm_integrator.step(n_simulation_steps) # compute energy and forces state = self._openmm_context.getState( getEnergy=evaluate_energy, getForces=evaluate_force, getPositions=evaluate_positions ) energy = state.getPotentialEnergy().value_in_unit(unit.kilojoule_per_mole) if evaluate_energy else None forces = ( state.getForces(asNumpy=True).value_in_unit(unit.kilojoule_per_mole / unit.nanometer) if evaluate_force else None ) new_positions = state.getPositions().value_in_unit(unit.nanometers) if evaluate_positions else None except Exception as e: if err_handling == "warning": warnings.warn("Suppressed exception: {}".format(e)) elif err_handling == "exception": raise e # push energies and forces to the results queue self._result_queue.put( [index, energy, forces, new_positions, log_path_probability_ratio] )
def writeHeader(topology, file=sys.stdout): """Write out the header for a PDB file. Parameters: - topology (Topology) The Topology defining the molecular system being written - file (file=stdout) A file to write the file to """ print >>file, "REMARK 1 CREATED WITH OPENMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())) boxSize = topology.getUnitCellDimensions() if boxSize is not None: size = boxSize.value_in_unit(angstroms) print >>file, "CRYST1%9.3f%9.3f%9.3f 90.00 90.00 90.00 P 1 1 " % size
def _initialize_simulation(self): if self._initialized: self._integrator.setTemperature(self._temperature) if self._options.softcore: print self._sc_lambda_lj self._simulation.context.setParameter('qq_lambda', self._sc_lambda_coulomb) self._simulation.context.setParameter('lj_lambda', self._sc_lambda_lj) self._simulation.context.setParameter('sc_lambda', self._sc_lambda_lj) logger.debug('set sc %d %f %f %f', self._rank, self._sc_lambda_coulomb, self._sc_lambda_lj, self._sc_lambda_lj) meld_rests = _update_always_active_restraints(self._always_on_restraints, self._alpha, self._timestep, self._force_dict) _update_selectively_active_restraints(self._selectable_collections, meld_rests, self._alpha, self._timestep, self._force_dict) for force in self._force_dict.values(): if force: force.updateParametersInContext(self._simulation.context) else: self._initialized = True # we need to set the whole thing from scratch prmtop = _parm_top_from_string(self._parm_string) sys = _create_openmm_system(prmtop, self._options.cutoff, self._options.use_big_timestep, self._options.use_bigger_timestep, self._options.implicit_solvent_model, self._options.remove_com) if self._options.softcore: sys = softcore.add_soft_core(sys) if self._options.use_amap: adder = cmap.CMAPAdder(self._parm_string, self._options.amap_alpha_bias, self._options.amap_beta_bias, self._options.ccap, self._options.ncap) adder.add_to_openmm(sys) meld_rests = _add_always_active_restraints(sys, self._always_on_restraints, self._alpha, self._timestep, self._force_dict) _add_selectively_active_restraints(sys, self._selectable_collections, meld_rests, self._alpha, self._timestep, self._force_dict) self._integrator = _create_integrator(self._temperature, self._options.use_big_timestep,self._options.use_bigger_timestep) platform = Platform.getPlatformByName('CUDA') properties = {'CudaDeviceIndex': str(self._device_id)} self._simulation = _create_openmm_simulation(prmtop.topology, sys, self._integrator, platform, properties) if self._options.softcore: self._simulation.context.setParameter('qq_lambda', self._sc_lambda_coulomb) self._simulation.context.setParameter('lj_lambda', self._sc_lambda_lj) self._simulation.context.setParameter('sc_lambda', self._sc_lambda_lj) logger.debug('set sc %d %f %f %f', self._rank, self._sc_lambda_coulomb, self._sc_lambda_lj, self._sc_lambda_lj)
def __init__(self, system, integrator=None): # if strings are passed in, assume that they are paths to # xml files on disk if isinstance(system, basestring): with open(system) as f: system = XmlSerializer.deserialize(f.read()) if isinstance(integrator, basestring): with open(integrator) as f: integrator = XmlSerializer.deserialize(f.read()) if integrator is None: # this integrator isn't really necessary, but it has to be something # for the openmm API to let us serialize the state integrator = VerletIntegrator(2*femtoseconds) self.context = Context(system, integrator, Platform.getPlatformByName('Reference'))
def writeHeader(topology, file=sys.stdout): """Write out the header for a PDB file. Parameters ---------- topology : Topology The Topology defining the molecular system being written file : file=stdout A file to write the file to """ print("REMARK 1 CREATED WITH OPENMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file) vectors = topology.getPeriodicBoxVectors() if vectors is not None: a, b, c, alpha, beta, gamma = computeLengthsAndAngles(vectors) RAD_TO_DEG = 180/math.pi print("CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1 1 " % ( a*10, b*10, c*10, alpha*RAD_TO_DEG, beta*RAD_TO_DEG, gamma*RAD_TO_DEG), file=file)
def calculate_fragment_energetics(frag_no=1): """ * Create an OpenMM system with a fragment. * Calculate the energy of the system and print. :param frag_no: The number of the fragment being analysed (used to access files). """ os.chdir(f'group2/frag{frag_no}') # Necessary due to size of calculation sys.setrecursionlimit(15000) pdb = PDBFile(f'QUBE_pro_frag{frag_no}.pdb') forcefield = ForceField(f'QUBE_pro_frag{frag_no}_plus.xml') system = forcefield.createSystem( pdb.topology, nonbondedMethod=NoCutoff, ) system = apply_opls_combo(system) with open(f'QUBE_pro_frag{frag_no}_out.xml', 'w') as outfile: serialized_system = XmlSerializer.serialize(system) outfile.write(serialized_system) # Create the integrator to do Langevin dynamics integrator = LangevinIntegrator( 298.15 * unit.kelvin, # Temperature of heat bath 1.0 / unit.picoseconds, # Friction coefficient 2.0 * unit.femtoseconds, # Time step ) platform = Platform.getPlatformByName('CPU') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) print('energy from openmm library') print(simulation.context.getState(getEnergy=True).getPotentialEnergy()) structure = parmed.load_file(f'QUBE_pro_frag{frag_no}.pdb') energy_comps = parmed.openmm.energy_decomposition_system(structure, system) total_energy = 0.0 for comp in energy_comps: total_energy += comp[1] print(*comp) print(f'Total energy {total_energy: 6.6f}')
def get_platform(platform_name): if platform_name == 'fastest': platform = None else: # TODO file access control attempt = 0 retries = 500 while True: try: platform = Platform.getPlatformByName(platform_name) return platform except IndexError as e: if attempt < retries: attempt += 1 time.sleep(5 * random.random()) else: raise e
def __init__(self, system, integrator=None): # if strings are passed in, assume that they are paths to # xml files on disk if isinstance(system, basestring): with open(system) as f: system = XmlSerializer.deserialize(f.read()) if isinstance(integrator, basestring): with open(integrator) as f: integrator = XmlSerializer.deserialize(f.read()) if integrator is None: # this integrator isn't really necessary, but it has to be something # for the openmm API to let us serialize the state integrator = VerletIntegrator(2 * femtoseconds) self.context = Context(system, integrator, Platform.getPlatformByName('Reference'))
def get_platform(platform_name): attempt = 0 retries = 10 if platform_name == 'fastest': platform = None else: while True: try: platform = Platform.getPlatformByName(platform_name) return platform #except IndexError as e: except Exception as e: if attempt < retries: attempt += 1 time.sleep(5 * random.random()) else: raise e
def writeHeader(topology, file=sys.stdout): """Write out the header for a PDB file. Parameters: - topology (Topology) The Topology defining the molecular system being written - file (file=stdout) A file to write the file to """ print >> file, "REMARK 1 CREATED WITH OPENMM %s, %s" % ( Platform.getOpenMMVersion(), str(date.today())) vectors = topology.getPeriodicBoxVectors() if vectors is not None: (a, b, c) = vectors.value_in_unit(angstroms) a_length = norm(a) b_length = norm(b) c_length = norm(c) alpha = math.acos(dot(b, c) / (b_length * c_length)) * 180.0 / math.pi beta = math.acos(dot(c, a) / (c_length * a_length)) * 180.0 / math.pi gamma = math.acos(dot(a, b) / (a_length * b_length)) * 180.0 / math.pi print >> file, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1 1 " % ( a_length, b_length, c_length, alpha, beta, gamma)
""" Houses all of the "extra" test cases to run for OpenMM """ __all__ = ['testhewl', 'available_platforms'] import testhewl # Construct the list of available platforms available_platforms = [] from simtk.openmm import Platform for i in range(Platform.getNumPlatforms()): available_platforms.append(Platform.getPlatform(i).getName()) # Cleanup the namespace a bit del i, Platform
def _initialize_simulation(self): if self._initialized: # update temperature and pressure self._integrator.setTemperature(self._temperature) if self._options.enable_pressure_coupling: self._simulation.context.setParameter( self._barostat.Temperature(), self._temperature) # update all of the system transformers self._transformers_update() else: # we need to set the whole thing from scratch self._initialized = True prmtop = _parm_top_from_string(self._parm_string) # create parameter objects pme_params = PMEParams(enable=self._options.enable_pme, tolerance=self._options.pme_tolerance) pcouple_params = PressureCouplingParams( enable=self._options.enable_pressure_coupling, temperature=self._temperature, pressure=self._options.pressure, steps=self._options.pressure_coupling_update_steps) # build the system sys, barostat = _create_openmm_system( prmtop, self._options.solvation, self._options.cutoff, self._options.use_big_timestep, self._options.use_bigger_timestep, self._options.implicit_solvent_model, pme_params, pcouple_params, self._options.remove_com, self._temperature) self._barostat = barostat if self._options.use_amap: adder = cmap.CMAPAdder(self._parm_string, self._options.amap_alpha_bias, self._options.amap_beta_bias, self._options.ccap, self._options.ncap) adder.add_to_openmm(sys) # setup the transformers self._transformers_setup() if len(self._always_on_restraints) > 0: print('Not all always on restraints were handled.') for r in self._always_on_restraints: print('\t', r) raise RuntimeError( 'Not all always on restraints were handled.') if len(self._selectable_collections) > 0: print('Not all selectable restraints were handled.') for r in self._selectable_collections: print('\t', r) raise RuntimeError( 'Not all selectable restraints were handled.') sys = self._transformers_add_interactions(sys, prmtop.topology) self._transformers_finalize(sys, prmtop.topology) # create the integrator self._integrator = _create_integrator( self._temperature, self._options.use_big_timestep, self._options.use_bigger_timestep) # setup the platform platform = Platform.getPlatformByName('CUDA') properties = { 'CudaDeviceIndex': str(self._device_id), 'CudaPrecision': 'mixed' } # create the simulation object self._simulation = _create_openmm_simulation( prmtop.topology, sys, self._integrator, platform, properties) self._transformers_update()
def check_openmm_version(): from simtk.openmm import Platform if not Platform.getOpenMMVersion() >= '5.1': raise ValueError('MSMAccelerator requires OpenMM >= 5.1')
exit(1) pdb_in = sys.argv[1] mol_in = sys.argv[2] output_complex = sys.argv[3] + '_complex.pdb' output_traj_pdb = sys.argv[3] + '_traj.pdb' output_traj_dcd = sys.argv[3] + '_traj.dcd' output_min = sys.argv[3] + '_minimised.pdb' num_steps = int(sys.argv[4]) print('Processing', pdb_in, 'and', mol_in, 'with', num_steps, 'steps generating outputs', output_complex, output_min, output_traj_pdb, output_traj_dcd) # check whether we have a GPU platform and if so set the precision to mixed speed = 0 for i in range(Platform.getNumPlatforms()): p = Platform.getPlatform(i) # print(p.getName(), p.getSpeed()) if p.getSpeed() > speed: platform = p speed = p.getSpeed() if platform.getName() == 'CUDA' or platform.getName() == 'OpenCL': platform.setPropertyDefaultValue('Precision', 'mixed') print('Set precision for platform', platform.getName(), 'to mixed') # Read the molfile into RDKit, add Hs and create an openforcefield Molecule object print('Reading ligand') rdkitmol = Chem.MolFromMolFile(mol_in) print('Adding hydrogens') rdkitmolh = Chem.AddHs(rdkitmol, addCoords=True)
) system = apply_opls_combo(system, switching_distance=496.0 * unit.angstroms) with open('QUBE_pro_out.xml', 'w') as outfile: serialized_system = XmlSerializer.serialize(system) outfile.write(serialized_system) # Create the integrator to do Langevin dynamics integrator = LangevinIntegrator( 298.15 * unit.kelvin, # Temperature of heat bath 1.0 / unit.picoseconds, # Friction coefficient 2.0 * unit.femtoseconds, # Time step ) platform = Platform.getPlatformByName('CPU') simulation = app.Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) print('energy from openmm library') print(simulation.context.getState(getEnergy=True).getPotentialEnergy()) # platform.setPropertyValue(simulation.context, property='Precision', value='double') # Minimize the energy # print('Minimizing energy') # Minimize(simulation, iters=0) structure = parmed.load_file('QUBE_pro.pdb') energy_comps = parmed.openmm.energy_decomposition_system(structure, system) total_energy = 0.0
funcs = {'get_platform': [get_platform, platform], 'get_pdbfile': [get_pdbfile, pdbfile], 'get_system': [get_xml, system], 'get_integrator': [get_xml, integrator]} kfuncs = list(funcs.keys()) random.shuffle(kfuncs) returns = dict() while kfuncs: op_name = kfuncs.pop(0) func, arg = funcs[op_name] returns.update({op_name: func(arg)}) return [returns[nxt] for nxt in return_order] platformNames = [Platform.getPlatform(i).getName() for i in range(Platform.getNumPlatforms())] print(platformNames) parser = argparse.ArgumentParser() parser.add_argument('--save_traj',dest='save_traj',required=True,type=str) parser.add_argument('--md_steps',dest='md_steps',required=True,type=int) parser.add_argument('--trajstride',dest='trajstride', required=False, type=int, default=10) parser.add_argument('--idxstart',dest='idxstart',required=True,type=int) parser.add_argument('--idxend',dest='idxend',required=True,type=int) parser.add_argument('--iter',dest='iter',required=True,type=int) parser.add_argument('--path',dest='path',required=True,type=str) args = parser.parse_args() #grofile_name='start2.gro #pdb=mdtraj.load(grofile_name)
def langevin_NVT(item, time = None, saving_timestep = None, integration_timestep= 2*unit.femtoseconds, friction=1.0/unit.picoseconds, temperature=300.0*unit.kelvin, initial_coordinates=None, initial_velocities=None, platform_name='CUDA', reporters=None, tqdm=True): """Newtonian classical dynamics of a molecular system with OpenMM. The trajectory of a newtonian classical dynamics of a molecular system is obtained together with the values of potential and kinetic energy. This method is nothing but a short cut to run quick molecular dynamics with the test systems of this library by means of OpenMM. Parameters ---------- system: simtk.openmm.System Molecular system as a system class of OpenMM (see: link) friction: unit.Quantity Damping parameter of the Langevin dynamics (in units of 1/time). initial_coordinates: unit.Quantity Initial coordinates of the system as a numpy array with shape [n_particles, 3] and units of length. Where 'n_particles' is the number of particles of the system. initial_velocities: unit.Quantity Initial velocities of the system as a numpy array with shape [n_particles, 3] and units of length/time. Where 'n_particles' is the number of particles of the system. integration_timestep: unit.Quantity Time step used by the integrator of the equations of motion. The parameter needs to have units of time. saving_timestep: unit.Quantity Time step used to report the output trajectory. The parameter needs to have units of time. total_time: unit.Quantity Total runing time of the simulation. The parameter needs to have units of time. platform_name: str (default: 'CPU') Platform to run the dynamics: 'CPU', 'OPENCL' or 'CUDA' (according to those options to run OpenMM, see documentation), verbose: bool (default: True) Verbose switcher. The method will print out information if the value is True. Returns ------- time: unit.Quantity Time as numpy array of shape [n_frames] with units of picoseconds. position: unit.Quantity Positions of the systems particles in every reported frame as numpy array of shape [n_frames, n_particles, 3] with units of nanometers. velocity: unit.Quantity Velocities of the systems particles in every reported frame as numpy array of shape [n_frames, n_particles, 3] with units of nanometers/picoseconds. kinetic_energy: unit.Quantity Kinetic energy of the system in every reported frame as numpy array of shape [n_frames] with units of kilocalories/mole. potential_energy: unit.Quantity Potential energy of the system in every reported frame as numpy array of shape [n_frames] with units of kilocalories/mole. Examples -------- >>> from uibcdf_test_systems import DoubleWell >>> from uibcdf_test_systems.simulation import newtonian >>> from simtk import unit >>> double_well = DoubleWell(n_particles = 1, mass = 64 * unit.amu, Eo=4.0 * unit.kilocalories_per_mole, a=1.0 * unit.nanometers, b=0.0 * unit.kilocalories_per_mole)) >>> initial_coordinates = np.zeros([1, 3], np.float32) * unit.nanometers >>> initial_velocities = np.zeros([1, 3], np.float32) * unit.nanometers/unit.picoseconds >>> initial_coordinates[0,0] = 1.0 * unit.nanometers >>> time, position, velocity, kinetic_energy, potential_energy = langevin_NVT(double_well, >>> friction = 0.1/unit.picoseconds, >>> initial_coordinates = initial_coordinates, >>> initial_velocities = initial_velocities, >>> integration_timestep = 0.02 * unit.picoseconds, >>> saving_timestep = 0.5 * unit.picoseconds, >>> total_time = 100 * unit.picoseconds) Notes ----- See the `corresponding documentation in the user guide regarding this method <../../simulations/newtonian.html>`_. Some simple examples on how this method is used can be found in the users guide sections corresponding to `the free particle <../../systems/free_particle.html>`_, `the harmonic well potential <../../systems/harmonic_well_potential.html>`_ or `the double well potential <../../systems/double_well_potential.html>`_. """ from simtk.openmm import LangevinIntegrator, Platform, Context from simtk import unit import numpy as np # System parameters. n_particles = item.system.getNumParticles() # Integrator. integrator = LangevinIntegrator(temperature, friction, integration_timestep) # Platform. platform = Platform.getPlatformByName(platform_name) # Simulation. simulation = Simulation(item.topology, item.system, integrator, platform) # Initial Context. if initial_coordinates is None: initial_coordinates = item.coordinates simulation.context.setPositions(initial_coordinates) if initial_velocities=='zeros' or initial_velocities is None: initial_velocities = np.zeros([n_particles, 3], np.float32) * unit.nanometers/unit.picosecond simulation.context.setVelocities(initial_velocities) elif initial_velocities=='boltzmann': simulation.context.setVelocitiesToTemperature(temperature) else: simulation.context.setVelocities(initial_velocities) # Reporters. default_reporter = False tqdm_reporter = False if reporters is None: reporters = [] if saving_timestep is not None and len(reporters)==0: saving_steps_interval = int(saving_timestep/integration_timestep) default_reporter = MolSysMTTrajectoryDictReporter(saving_steps_interval, time=True, coordinates=True, potentialEnergy=True, kineticEnergy=True, box=True) reporters.append(default_reporter) for reporter in reporters: simulation.reporters.append(reporter) # Initial report initial_state = simulation.context.getState(getEnergy=True, getPositions=True, getVelocities=True) for reporter in reporters: reporter.report(simulation, initial_state) n_steps = int(time/integration_timestep) if tqdm: tqdm_reporter = TQDMReporter(100, n_steps) simulation.reporters.append(tqdm_reporter) simulation.step(n_steps) if tqdm_reporter: tqdm_reporter.finalize() if default_reporter: return default_reporter.finalize() else: pass
def subtest_mcmc_expectation(testsystem, move_set): if debug: print(testsystem.__class__.__name__) print(str(move_set)) # Test settings. temperature = 298.0 * units.kelvin nequil = 10 # number of equilibration iterations niterations = 40 # number of production iterations # Retrieve system and positions. [system, positions] = [testsystem.system, testsystem.positions] platform_name = 'Reference' from simtk.openmm import Platform platform = Platform.getPlatformByName(platform_name) # Compute properties. kB = units.BOLTZMANN_CONSTANT_kB * units.AVOGADRO_CONSTANT_NA kT = kB * temperature ndof = 3 * system.getNumParticles() - system.getNumConstraints() # Create thermodynamic state from openmmmcmc.thermodynamics import ThermodynamicState thermodynamic_state = ThermodynamicState(system=testsystem.system, temperature=temperature) # Create MCMC sampler. from openmmmcmc.mcmc import MCMCSampler sampler = MCMCSampler(thermodynamic_state, move_set=move_set, platform=platform) # Create sampler state. from openmmmcmc.mcmc import SamplerState sampler_state = SamplerState(system=testsystem.system, positions=testsystem.positions, platform=platform) # Equilibrate for iteration in range(nequil): #print("equilibration iteration %d / %d" % (iteration, nequil)) # Update sampler state. sampler_state = sampler.run(sampler_state, 1) # Accumulate statistics. x_n = np.zeros( [niterations], np.float64 ) # x_n[i] is the x position of atom 1 after iteration i, in angstroms potential_n = np.zeros( [niterations], np.float64 ) # potential_n[i] is the potential energy after iteration i, in kT kinetic_n = np.zeros( [niterations], np.float64 ) # kinetic_n[i] is the kinetic energy after iteration i, in kT temperature_n = np.zeros( [niterations], np.float64 ) # temperature_n[i] is the instantaneous kinetic temperature from iteration i, in K volume_n = np.zeros( [niterations], np.float64) # volume_n[i] is the volume from iteration i, in K for iteration in range(niterations): if debug: print("iteration %d / %d" % (iteration, niterations)) # Update sampler state. sampler_state = sampler.run(sampler_state, 1) # Get statistics. potential_energy = sampler_state.potential_energy kinetic_energy = sampler_state.kinetic_energy total_energy = sampler_state.total_energy instantaneous_temperature = kinetic_energy * 2.0 / ndof / ( units.BOLTZMANN_CONSTANT_kB * units.AVOGADRO_CONSTANT_NA) volume = sampler_state.volume #print "potential %8.1f kT | kinetic %8.1f kT | total %8.1f kT | volume %8.3f nm^3 | instantaneous temperature: %8.1f K" % (potential_energy/kT, kinetic_energy/kT, total_energy/kT, volume/(units.nanometers**3), instantaneous_temperature/units.kelvin) # Accumulate statistics. x_n[iteration] = sampler_state.positions[0, 0] / units.angstroms potential_n[iteration] = potential_energy / kT kinetic_n[iteration] = kinetic_energy / kT temperature_n[iteration] = instantaneous_temperature / units.kelvin volume_n[iteration] = volume / (units.nanometers**3) # Compute expected statistics. if ('get_potential_expectation' in dir(testsystem)): # Skip this check if the std dev is zero. skip_test = False if (potential_n.std() == 0.0): skip_test = True if debug: print("Skipping potential test since variance is zero.") if not skip_test: potential_expectation = testsystem.get_potential_expectation( thermodynamic_state) / kT potential_mean = potential_n.mean() g = timeseries.statisticalInefficiency(potential_n, fast=True) dpotential_mean = potential_n.std() / np.sqrt(niterations / g) potential_error = potential_mean - potential_expectation nsigma = abs(potential_error) / dpotential_mean test_passed = True if (nsigma > NSIGMA_CUTOFF): test_passed = False if debug or (test_passed is False): print("Potential energy expectation") print( "observed %10.5f +- %10.5f kT | expected %10.5f | error %10.5f +- %10.5f (%.1f sigma)" % (potential_mean, dpotential_mean, potential_expectation, potential_error, dpotential_mean, nsigma)) if test_passed: print("TEST PASSED") else: print("TEST FAILED") print( "----------------------------------------------------------------------------" ) if ('get_volume_expectation' in dir(testsystem)): # Skip this check if the std dev is zero. skip_test = False if (volume_n.std() == 0.0): skip_test = True if debug: print("Skipping volume test.") if not skip_test: volume_expectation = testsystem.get_volume_expectation( thermodynamic_state) / (units.nanometers**3) volume_mean = volume_n.mean() g = timeseries.statisticalInefficiency(volume_n, fast=True) dvolume_mean = volume_n.std() / np.sqrt(niterations / g) volume_error = volume_mean - volume_expectation nsigma = abs(volume_error) / dvolume_mean test_passed = True if (nsigma > NSIGMA_CUTOFF): test_passed = False if debug or (test_passed is False): print("Volume expectation") print( "observed %10.5f +- %10.5f kT | expected %10.5f | error %10.5f +- %10.5f (%.1f sigma)" % (volume_mean, dvolume_mean, volume_expectation, volume_error, dvolume_mean, nsigma)) if test_passed: print("TEST PASSED") else: print("TEST FAILED") print( "----------------------------------------------------------------------------" )
def test_reporter(tmpdir, get_fn): pdb = PDBFile(get_fn('native.pdb')) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') # NO PERIODIC BOUNDARY CONDITIONS system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) hdf5file = os.path.join(tmpdir, 'traj.h5') ncfile = os.path.join(tmpdir, 'traj.nc') dcdfile = os.path.join(tmpdir, 'traj.dcd') reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True, cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True, velocities=True) reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True) reporter3 = DCDReporter(dcdfile, 2) simulation.reporters.append(reporter) simulation.reporters.append(reporter2) simulation.reporters.append(reporter3) simulation.step(100) reporter.close() reporter2.close() reporter3.close() with HDF5TrajectoryFile(hdf5file) as f: got = f.read() eq(got.temperature.shape, (50, )) eq(got.potentialEnergy.shape, (50, )) eq(got.kineticEnergy.shape, (50, )) eq(got.coordinates.shape, (50, 22, 3)) eq(got.velocities.shape, (50, 22, 3)) eq(got.cell_lengths, None) eq(got.cell_angles, None) eq(got.time, 0.002 * 2 * (1 + np.arange(50))) assert f.topology == md.load(get_fn('native.pdb')).top with NetCDFTrajectoryFile(ncfile) as f: xyz, time, cell_lengths, cell_angles = f.read() eq(cell_lengths, None) eq(cell_angles, None) eq(time, 0.002 * 2 * (1 + np.arange(50))) hdf5_traj = md.load(hdf5file) dcd_traj = md.load(dcdfile, top=get_fn('native.pdb')) netcdf_traj = md.load(ncfile, top=get_fn('native.pdb')) # we don't have to convert units here, because md.load already # handles that assert hdf5_traj.unitcell_vectors is None eq(hdf5_traj.xyz, netcdf_traj.xyz) eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors) eq(hdf5_traj.time, netcdf_traj.time) eq(dcd_traj.xyz, hdf5_traj.xyz)
def setup_platform_with_resources(compute_resources, high_precision=False): """Creates an OpenMM `Platform` object which requests a set amount of compute resources (e.g with a certain number of cpus). Parameters ---------- compute_resources: ComputeResources The compute resources which describe which platform is most appropriate. high_precision: bool If true, a platform with the highest possible precision (double for CUDA and OpenCL, Reference for CPU only) will be returned. Returns ------- Platform The created platform """ from simtk.openmm import Platform # Setup the requested platform: if compute_resources.number_of_gpus > 0: # TODO: Make sure use mixing precision - CUDA, OpenCL. # TODO: Deterministic forces = True from openff.evaluator.backends import ComputeResources toolkit_enum = ComputeResources.GPUToolkit( compute_resources.preferred_gpu_toolkit) # A platform which runs on GPUs has been requested. platform_name = ("CUDA" if toolkit_enum == ComputeResources.GPUToolkit.CUDA else ComputeResources.GPUToolkit.OpenCL) # noinspection PyCallByClass,PyTypeChecker platform = Platform.getPlatformByName(platform_name) if compute_resources.gpu_device_indices is not None: property_platform_name = platform_name if toolkit_enum == ComputeResources.GPUToolkit.CUDA: property_platform_name = platform_name.lower().capitalize() platform.setPropertyDefaultValue( property_platform_name + "DeviceIndex", compute_resources.gpu_device_indices, ) if high_precision: platform.setPropertyDefaultValue("Precision", "double") logger.info("Setting up an openmm platform on GPU {}".format( compute_resources.gpu_device_indices or 0)) else: if not high_precision: # noinspection PyCallByClass,PyTypeChecker platform = Platform.getPlatformByName("CPU") platform.setPropertyDefaultValue( "Threads", str(compute_resources.number_of_threads)) else: # noinspection PyCallByClass,PyTypeChecker platform = Platform.getPlatformByName("Reference") logger.info("Setting up a simulation with {} threads".format( compute_resources.number_of_threads)) return platform
def _initialize_simulation(self): if self._initialized: # update temperature and pressure self._integrator.setTemperature(self._temperature) if self._options.enable_pressure_coupling: self._simulation.context.setParameter( self._barostat.Temperature(), self._temperature ) # update all of the system transformers self._transformers_update() else: # we need to set the whole thing from scratch self._initialized = True prmtop = _parm_top_from_string(self._parm_string) # create parameter objects pme_params = PMEParams( enable=self._options.enable_pme, tolerance=self._options.pme_tolerance ) pcouple_params = PressureCouplingParams( enable=self._options.enable_pressure_coupling, temperature=self._temperature, pressure=self._options.pressure, steps=self._options.pressure_coupling_update_steps, ) # build the system sys, barostat = _create_openmm_system( prmtop, self._options.solvation, self._options.cutoff, self._options.use_big_timestep, self._options.use_bigger_timestep, self._options.implicit_solvent_model, pme_params, pcouple_params, self._options.remove_com, self._temperature, self._extra_bonds, self._extra_restricted_angles, self._extra_torsions, self._options.implicitSolventSaltConc, self._options.soluteDielectric, self._options.solventDielectric, ) self._barostat = barostat if self._options.use_amap: adder = cmap.CMAPAdder( self._parm_string, self._options.amap_alpha_bias, self._options.amap_beta_bias, self._options.ccap, self._options.ncap, ) adder.add_to_openmm(sys) # setup the transformers self._transformers_setup() if len(self._always_on_restraints) > 0: print("Not all always on restraints were handled.") for r in self._always_on_restraints: print("\t", r) raise RuntimeError("Not all always on restraints were handled.") if len(self._selectable_collections) > 0: print("Not all selectable restraints were handled.") for r in self._selectable_collections: print("\t", r) raise RuntimeError("Not all selectable restraints were handled.") sys = self._transformers_add_interactions(sys, prmtop.topology) self._transformers_finalize(sys, prmtop.topology) # create the integrator self._integrator = _create_integrator( self._temperature, self._options.use_big_timestep, self._options.use_bigger_timestep, ) # setup the platform, CUDA by default and Reference for testing if self.platform == "Reference": logger.info("Using Reference platform.") platform = Platform.getPlatformByName("Reference") properties = {} elif self.platform == "CPU": logger.info("Using CPU platform.") platform = Platform.getPlatformByName("CPU") properties = {} elif self.platform == "CUDA": logger.info("Using CUDA platform.") platform = Platform.getPlatformByName("CUDA") # The plugin currently requires that we use nvcc, as # nvrtc is not able to compile code that uses the cub # library, which we use in the plugin. # We can force the use of nvcc by setting CudaCompiler. # We set it to the default value, which will reflect the # OPENMM_CUDA_COMPILER environmnet variable if set. compiler = platform.getPropertyDefaultValue("CudaCompiler") logger.debug(f"Using CUDA compiler {compiler}.") properties = { "CudaDeviceIndex": str(self._device_id), "CudaPrecision": "mixed", "CudaCompiler": compiler, } else: raise RuntimeError(f"Unknown platform {self.platform}.") # create the simulation object self._simulation = _create_openmm_simulation( prmtop.topology, sys, self._integrator, platform, properties ) self._transformers_update()
def test_reporter_subset(tmpdir, get_fn): pdb = PDBFile(get_fn('native2.pdb')) pdb.topology.setUnitCellDimensions([2, 2, 2]) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffPeriodic, nonbondedCutoff=1 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) hdf5file = os.path.join(tmpdir, 'traj.h5') ncfile = os.path.join(tmpdir, 'traj.nc') dcdfile = os.path.join(tmpdir, 'traj.dcd') xtcfile = os.path.join(tmpdir, 'traj.xtc') atomSubset = [0, 1, 2, 4, 5] reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True, cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True, velocities=True, atomSubset=atomSubset) reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True, atomSubset=atomSubset) reporter3 = DCDReporter(dcdfile, 2, atomSubset=atomSubset) reporter4 = XTCReporter(xtcfile, 2, atomSubset=atomSubset) simulation.reporters.append(reporter) simulation.reporters.append(reporter2) simulation.reporters.append(reporter3) simulation.reporters.append(reporter4) simulation.step(100) reporter.close() reporter2.close() reporter3.close() reporter4.close() t = md.load(get_fn('native.pdb')) t.restrict_atoms(atomSubset) with HDF5TrajectoryFile(hdf5file) as f: got = f.read() eq(got.temperature.shape, (50,)) eq(got.potentialEnergy.shape, (50,)) eq(got.kineticEnergy.shape, (50,)) eq(got.coordinates.shape, (50, len(atomSubset), 3)) eq(got.velocities.shape, (50, len(atomSubset), 3)) eq(got.cell_lengths, 2 * np.ones((50, 3))) eq(got.cell_angles, 90 * np.ones((50, 3))) eq(got.time, 0.002 * 2 * (1 + np.arange(50))) assert f.topology == md.load(get_fn('native.pdb'), atom_indices=atomSubset).topology with NetCDFTrajectoryFile(ncfile) as f: xyz, time, cell_lengths, cell_angles = f.read() eq(cell_lengths, 20 * np.ones((50, 3))) eq(cell_angles, 90 * np.ones((50, 3))) eq(time, 0.002 * 2 * (1 + np.arange(50))) eq(xyz.shape, (50, len(atomSubset), 3)) hdf5_traj = md.load(hdf5file) dcd_traj = md.load(dcdfile, top=hdf5_traj) netcdf_traj = md.load(ncfile, top=hdf5_traj) xtc_traj = md.load(xtcfile, top=hdf5_traj) # we don't have to convert units here, because md.load already handles that eq(hdf5_traj.xyz, netcdf_traj.xyz) eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors) eq(hdf5_traj.time, netcdf_traj.time) eq(xtc_traj.time, netcdf_traj.time) eq(dcd_traj.xyz, hdf5_traj.xyz) eq(xtc_traj.xyz, hdf5_traj.xyz) eq(dcd_traj.unitcell_vectors, hdf5_traj.unitcell_vectors)
def simulate(self, header, content): """Main method that is "executed" by the receipt of the msg_type == 'simulate' message from the server. We run some OpenMM dynamics, and then send back the results. """ self.log.info('Setting up simulation...') state, topology = self.deserialize_input(content) # set the GPU platform platform = Platform.getPlatformByName(str(self.platform)) if self.platform == 'CUDA': properties = {'CudaPrecision': 'mixed', 'CudaDeviceIndex': str(self.device_index) } elif self.platform == 'OpenCL': properties = {'OpenCLPrecision': 'mixed', 'OpenCLDeviceIndex': str(self.device_index) } else: properties = None simulation = Simulation(topology, self.system, self.integrator, platform, properties) # do the setup self.set_state(state, simulation) self.sanity_check(simulation) if self.minimize: self.log.info('minimizing...') simulation.minimizeEnergy() if self.random_initial_velocities: try: temp = simulation.integrator.getTemperature() simulation.context.setVelocitiesToTemperature(temp) except AttributeError: print "I don't know what temperature to use!!" # TODO: look through the system's forces to find an andersen # thermostate? raise pass assert content.output.protocol == 'localfs', "I'm currently only equiped for localfs output" self.log.info('adding reporters...') self.add_reporters(simulation, content.output.path) # run dynamics! self.log.info('Starting dynamics') simulation.step(self.number_of_steps) for reporter in simulation.reporters: # explicitly delete the reporters so that any open file handles # are closed. del reporter # tell the master that I'm done self.send_recv(msg_type='simulation_done', content={ 'status': 'success', 'output': { 'protocol': 'localfs', 'path': content.output.path } })
def test_reporter(tmpdir, get_fn): pdb = PDBFile(get_fn('native.pdb')) forcefield = ForceField('amber99sbildn.xml', 'amber99_obc.xml') # NO PERIODIC BOUNDARY CONDITIONS system = forcefield.createSystem(pdb.topology, nonbondedMethod=CutoffNonPeriodic, nonbondedCutoff=1.0 * nanometers, constraints=HBonds, rigidWater=True) integrator = LangevinIntegrator(300 * kelvin, 1.0 / picoseconds, 2.0 * femtoseconds) integrator.setConstraintTolerance(0.00001) platform = Platform.getPlatformByName('Reference') simulation = Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.context.setVelocitiesToTemperature(300 * kelvin) tmpdir = str(tmpdir) hdf5file = os.path.join(tmpdir, 'traj.h5') ncfile = os.path.join(tmpdir, 'traj.nc') dcdfile = os.path.join(tmpdir, 'traj.dcd') xtcfile = os.path.join(tmpdir, 'traj.xtc') reporter = HDF5Reporter(hdf5file, 2, coordinates=True, time=True, cell=True, potentialEnergy=True, kineticEnergy=True, temperature=True, velocities=True) reporter2 = NetCDFReporter(ncfile, 2, coordinates=True, time=True, cell=True) reporter3 = DCDReporter(dcdfile, 2) reporter4 = XTCReporter(xtcfile, 2) simulation.reporters.append(reporter) simulation.reporters.append(reporter2) simulation.reporters.append(reporter3) simulation.reporters.append(reporter4) simulation.step(100) reporter.close() reporter2.close() reporter3.close() reporter4.close() with HDF5TrajectoryFile(hdf5file) as f: got = f.read() eq(got.temperature.shape, (50,)) eq(got.potentialEnergy.shape, (50,)) eq(got.kineticEnergy.shape, (50,)) eq(got.coordinates.shape, (50, 22, 3)) eq(got.velocities.shape, (50, 22, 3)) eq(got.cell_lengths, None) eq(got.cell_angles, None) eq(got.time, 0.002 * 2 * (1 + np.arange(50))) assert f.topology == md.load(get_fn('native.pdb')).top with NetCDFTrajectoryFile(ncfile) as f: xyz, time, cell_lengths, cell_angles = f.read() eq(cell_lengths, None) eq(cell_angles, None) eq(time, 0.002 * 2 * (1 + np.arange(50))) hdf5_traj = md.load(hdf5file) dcd_traj = md.load(dcdfile, top=get_fn('native.pdb')) netcdf_traj = md.load(ncfile, top=get_fn('native.pdb')) xtc_traj = md.load(xtcfile, top=get_fn('native.pdb')) # we don't have to convert units here, because md.load already # handles that assert hdf5_traj.unitcell_vectors is None eq(hdf5_traj.xyz, netcdf_traj.xyz) eq(hdf5_traj.unitcell_vectors, netcdf_traj.unitcell_vectors) eq(hdf5_traj.time, netcdf_traj.time) eq(xtc_traj.time, netcdf_traj.time) eq(dcd_traj.xyz, hdf5_traj.xyz) eq(xtc_traj.xyz, dcd_traj.xyz, decimal=3)
def subtest_mcmc_expectation(testsystem, move_set): if debug: print testsystem.__class__.__name__ print str(move_set) # Test settings. temperature = 298.0 * units.kelvin pressure = 1.0 * units.atmospheres nequil = 10 # number of equilibration iterations niterations = 20 # number of production iterations # Retrieve system and positions. [system, positions] = [testsystem.system, testsystem.positions] platform_name = 'Reference' from simtk.openmm import Platform platform = Platform.getPlatformByName(platform_name) # Compute properties. kB = units.BOLTZMANN_CONSTANT_kB * units.AVOGADRO_CONSTANT_NA kT = kB * temperature ndof = 3*system.getNumParticles() - system.getNumConstraints() # Create thermodynamic state from repex.thermodynamics import ThermodynamicState thermodynamic_state = ThermodynamicState(system=testsystem.system, temperature=temperature, pressure=pressure) # Create MCMC sampler. from repex.mcmc import MCMCSampler sampler = MCMCSampler(thermodynamic_state, move_set=move_set, platform=platform) # Create sampler state. from repex.mcmc import SamplerState sampler_state = SamplerState(system=testsystem.system, positions=testsystem.positions, platform=platform) # Equilibrate for iteration in range(nequil): #print "equilibration iteration %d / %d" % (iteration, nequil) # Update sampler state. sampler_state = sampler.run(sampler_state, 1) # Accumulate statistics. x_n = np.zeros([niterations], np.float64) # x_n[i] is the x position of atom 1 after iteration i, in angstroms potential_n = np.zeros([niterations], np.float64) # potential_n[i] is the potential energy after iteration i, in kT kinetic_n = np.zeros([niterations], np.float64) # kinetic_n[i] is the kinetic energy after iteration i, in kT temperature_n = np.zeros([niterations], np.float64) # temperature_n[i] is the instantaneous kinetic temperature from iteration i, in K volume_n = np.zeros([niterations], np.float64) # volume_n[i] is the volume from iteration i, in K for iteration in range(niterations): if debug: print "iteration %d / %d" % (iteration, niterations) # Update sampler state. sampler_state = sampler.run(sampler_state, 1) # Get statistics. potential_energy = sampler_state.potential_energy kinetic_energy = sampler_state.kinetic_energy total_energy = sampler_state.total_energy instantaneous_temperature = kinetic_energy * 2.0 / ndof / (units.BOLTZMANN_CONSTANT_kB * units.AVOGADRO_CONSTANT_NA) volume = sampler_state.volume #print "potential %8.1f kT | kinetic %8.1f kT | total %8.1f kT | volume %8.3f nm^3 | instantaneous temperature: %8.1f K" % (potential_energy/kT, kinetic_energy/kT, total_energy/kT, volume/(units.nanometers**3), instantaneous_temperature/units.kelvin) # Accumulate statistics. x_n[iteration] = sampler_state.positions[0,0] / units.angstroms potential_n[iteration] = potential_energy / kT kinetic_n[iteration] = kinetic_energy / kT temperature_n[iteration] = instantaneous_temperature / units.kelvin volume_n[iteration] = volume / (units.nanometers**3) # Compute expected statistics. if ('get_potential_expectation' in dir(testsystem)): # Skip this check if the std dev is zero. skip_test = False if (potential_n.std() == 0.0): skip_test = True if debug: print "Skipping potential test since variance is zero." if not skip_test: potential_expectation = testsystem.get_potential_expectation(thermodynamic_state) / kT potential_mean = potential_n.mean() g = timeseries.statisticalInefficiency(potential_n, fast=True) dpotential_mean = potential_n.std() / np.sqrt(niterations / g) potential_error = potential_mean - potential_expectation nsigma = abs(potential_error) / dpotential_mean test_passed = True if (nsigma > NSIGMA_CUTOFF): test_passed = False if debug or (test_passed is False): print "Potential energy expectation" print "observed %10.5f +- %10.5f kT | expected %10.5f | error %10.5f +- %10.5f (%.1f sigma)" % (potential_mean, dpotential_mean, potential_expectation, potential_error, dpotential_mean, nsigma) if test_passed: print "TEST PASSED" else: print "TEST FAILED" print "----------------------------------------------------------------------------" if ('get_volume_expectation' in dir(testsystem)): # Skip this check if the std dev is zero. skip_test = False if (volume_n.std() == 0.0): skip_test = True if debug: print "Skipping volume test." if not skip_test: volume_expectation = testsystem.get_volume_expectation(thermodynamic_state) / (units.nanometers**3) volume_mean = volume_n.mean() g = timeseries.statisticalInefficiency(volume_n, fast=True) dvolume_mean = volume_n.std() / np.sqrt(niterations / g) volume_error = volume_mean - volume_expectation nsigma = abs(volume_error) / dvolume_mean test_passed = True if (nsigma > NSIGMA_CUTOFF): test_passed = False if debug or (test_passed is False): print "Volume expectation" print "observed %10.5f +- %10.5f kT | expected %10.5f | error %10.5f +- %10.5f (%.1f sigma)" % (volume_mean, dvolume_mean, volume_expectation, volume_error, dvolume_mean, nsigma) if test_passed: print "TEST PASSED" else: print "TEST FAILED" print "----------------------------------------------------------------------------"
platform_properties = { 'CUDA': [ 'Cuda_Device_Index', 'Cuda_Precision', 'Cuda_Use_Cpu_Pme', 'Cuda_Cuda_Compiler', 'Cuda_Temp_Directory', 'Cuda_Use_Blocking_Sync', 'Cuda_Deterministic_Forces' ], 'OpenCL': [ 'OpenCL_Device_Index', 'OpenCL_Precision', 'OpenCL_Use_Cpu_Pme', 'OpenCL_OpenCL_Platform_Index' ], 'CPU': ['CPU_Threads'], 'Reference': [] } platform_names = [ Platform.getPlatform(no_platform).getName() for no_platform in range(Platform.getNumPlatforms()) ] parser = argparse.ArgumentParser( description='Run an MD simulation using OpenMM') parser.add_argument('output', metavar='output/', help='the output directory', type=str) parser.add_argument('-l', '--length', dest='length', type=int,
DATA_PATH = "mixtures/amber/" RESULT_PATH = "density_simulation/" #md_platform = 'Reference' # e.g. Reference or CUDA or OpenCL md_platform = 'OpenCL' # Some file names prmtop_filename = DATA_PATH + identifier + '.prmtop' inpcrd_filename = DATA_PATH + identifier + '.inpcrd' xml_filename = RESULT_PATH + identifier + '.xml' # For serialized system #--------------MINIMIZATION---------------- MIN_TIME_STEP = 0.5 * femtoseconds MIN_STEPS = 0 # 0=Until convergence is reached MIN_TOLERANCE = 10.0 * kilojoule_per_mole MIN_PLATFORM = Platform.getPlatformByName('Reference') MIN_FRICTION = 1.0 / picoseconds #-------------------NVT-------------------- NVT_TIME_STEP = 1.0 * femtoseconds NVT_STEPS = 50000 NVT_FRICTION = 1.0 / picoseconds NVT_PLATFORM = Platform.getPlatformByName(md_platform) NVT_PROPERTIES = {'DeviceIndex': 1} # TEST if md_platform == 'CUDA': NVT_PROPERTIES = {'CudaPrecision': 'mixed'} else: NVT_PROPERTIES = {} NVT_OUTPUT_FREQ = 10000 NVT_DATA_FREQ = 10000
def writeHeader(topology, file=sys.stdout, entry=None, keepIds=False): """Write out the header for a PDBx/mmCIF file. Parameters ---------- topology : Topology The Topology defining the molecular system being written file : file=stdout A file to write the file to entry : str=None The entry ID to assign to the CIF file keepIds : bool=False If True, keep the residue and chain IDs specified in the Topology rather than generating new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of the PDBx/mmCIF format. Otherwise, the output file will be invalid. """ if entry is not None: print('data_%s' % entry, file=file) else: print('data_cell', file=file) print("# Created with OpenMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file) print('#', file=file) vectors = topology.getPeriodicBoxVectors() if vectors is not None: a, b, c, alpha, beta, gamma = computeLengthsAndAngles(vectors) RAD_TO_DEG = 180/math.pi print('_cell.length_a %10.4f' % (a*10), file=file) print('_cell.length_b %10.4f' % (b*10), file=file) print('_cell.length_c %10.4f' % (c*10), file=file) print('_cell.angle_alpha %10.4f' % (alpha*RAD_TO_DEG), file=file) print('_cell.angle_beta %10.4f' % (beta*RAD_TO_DEG), file=file) print('_cell.angle_gamma %10.4f' % (gamma*RAD_TO_DEG), file=file) print('#', file=file) # Identify bonds that should be listed in the file. bonds = [] for atom1, atom2 in topology.bonds(): if atom1.residue.name not in PDBFile._standardResidues or atom2.residue.name not in PDBFile._standardResidues: bonds.append((atom1, atom2)) elif atom1.name == 'SG' and atom2.name == 'SG' and atom1.residue.name == 'CYS' and atom2.residue.name == 'CYS': bonds.append((atom1, atom2)) if len(bonds) > 0: # Write the bond information. print('loop_', file=file) print('_struct_conn.id', file=file) print('_struct_conn.conn_type_id', file=file) print('_struct_conn.ptnr1_label_asym_id', file=file) print('_struct_conn.ptnr1_label_comp_id', file=file) print('_struct_conn.ptnr1_label_seq_id', file=file) print('_struct_conn.ptnr1_label_atom_id', file=file) print('_struct_conn.ptnr2_label_asym_id', file=file) print('_struct_conn.ptnr2_label_comp_id', file=file) print('_struct_conn.ptnr2_label_seq_id', file=file) print('_struct_conn.ptnr2_label_atom_id', file=file) chainIds = {} resIds = {} if keepIds: for chain in topology.chains(): chainIds[chain] = chain.id for res in topology.residues(): resIds[res] = res.id else: for (chainIndex, chain) in enumerate(topology.chains()): chainIds[chain] = chr(ord('A')+chainIndex%26) for (resIndex, res) in enumerate(chain.residues()): resIds[res] = resIndex+1 for i, (atom1, atom2) in enumerate(bonds): if atom1.residue.name == 'CYS' and atom2.residue.name == 'CYS': bondType = 'disulf' else: bondType = 'covale' line = "bond%d %s %s %-4s %5s %-4s %s %-4s %5s %-4s" print(line % (i+1, bondType, chainIds[atom1.residue.chain], atom1.residue.name, resIds[atom1.residue], atom1.name, chainIds[atom2.residue.chain], atom2.residue.name, resIds[atom2.residue], atom2.name), file=file) print('#', file=file) # Write the header for the atom coordinates. print('loop_', file=file) print('_atom_site.group_PDB', file=file) print('_atom_site.id', file=file) print('_atom_site.type_symbol', file=file) print('_atom_site.label_atom_id', file=file) print('_atom_site.label_alt_id', file=file) print('_atom_site.label_comp_id', file=file) print('_atom_site.label_asym_id', file=file) print('_atom_site.label_entity_id', file=file) print('_atom_site.label_seq_id', file=file) print('_atom_site.pdbx_PDB_ins_code', file=file) print('_atom_site.Cartn_x', file=file) print('_atom_site.Cartn_y', file=file) print('_atom_site.Cartn_z', file=file) print('_atom_site.occupancy', file=file) print('_atom_site.B_iso_or_equiv', file=file) print('_atom_site.Cartn_x_esd', file=file) print('_atom_site.Cartn_y_esd', file=file) print('_atom_site.Cartn_z_esd', file=file) print('_atom_site.occupancy_esd', file=file) print('_atom_site.B_iso_or_equiv_esd', file=file) print('_atom_site.pdbx_formal_charge', file=file) print('_atom_site.auth_seq_id', file=file) print('_atom_site.auth_comp_id', file=file) print('_atom_site.auth_asym_id', file=file) print('_atom_site.auth_atom_id', file=file) print('_atom_site.pdbx_PDB_model_num', file=file)
def _initialize_simulation(self): if self._initialized: # update temperature and pressure self._integrator.setTemperature(self._temperature) if self._options.enable_pressure_coupling: self._simulation.context.setParameter( self._barostat.Temperature(), self._temperature ) # update all of the system transformers self._transformers_update() else: # we need to set the whole thing from scratch self._initialized = True prmtop = _parm_top_from_string(self._parm_string) # create parameter objects pme_params = PMEParams( enable=self._options.enable_pme, tolerance=self._options.pme_tolerance ) pcouple_params = PressureCouplingParams( enable=self._options.enable_pressure_coupling, temperature=self._temperature, pressure=self._options.pressure, steps=self._options.pressure_coupling_update_steps, ) # build the system sys, barostat = _create_openmm_system( prmtop, self._options.solvation, self._options.cutoff, self._options.use_big_timestep, self._options.use_bigger_timestep, self._options.implicit_solvent_model, pme_params, pcouple_params, self._options.remove_com, self._temperature, self._extra_bonds, self._extra_restricted_angles, self._extra_torsions, self._options.implicitSolventSaltConc, self._options.soluteDielectric, self._options.solventDielectric, ) self._barostat = barostat if self._options.use_amap: adder = cmap.CMAPAdder( self._parm_string, self._options.amap_alpha_bias, self._options.amap_beta_bias, self._options.ccap, self._options.ncap, ) adder.add_to_openmm(sys) # setup the transformers self._transformers_setup() if len(self._always_on_restraints) > 0: print("Not all always on restraints were handled.") for r in self._always_on_restraints: print("\t", r) raise RuntimeError("Not all always on restraints were handled.") if len(self._selectable_collections) > 0: print("Not all selectable restraints were handled.") for r in self._selectable_collections: print("\t", r) raise RuntimeError("Not all selectable restraints were handled.") sys = self._transformers_add_interactions(sys, prmtop.topology) self._transformers_finalize(sys, prmtop.topology) # create the integrator self._integrator = _create_integrator( self._temperature, self._options.use_big_timestep, self._options.use_bigger_timestep, ) # setup the platform, CUDA by default and Reference for testing if self._test: platform = Platform.getPlatformByName("Reference") properties = {} else: platform = Platform.getPlatformByName("CUDA") properties = { "CudaDeviceIndex": str(self._device_id), "CudaPrecision": "mixed", } # create the simulation object self._simulation = _create_openmm_simulation( prmtop.topology, sys, self._integrator, platform, properties ) self._transformers_update()
membrane_barostat = MonteCarloMembraneBarostat( 1 * bar, 0.0 * bar * nanometer, 308 * kelvin, MonteCarloMembraneBarostat.XYIsotropic, MonteCarloMembraneBarostat.ZFree, 15) system_generator = SystemGenerator( forcefields=['amber/lipid17.xml', 'amber/tip3p_standard.xml'], small_molecule_forcefield='gaff-2.11', barostat=membrane_barostat, forcefield_kwargs=forcefield_kwargs, periodic_forcefield_kwargs=periodic_forcefield_kwargs) system = system_generator.create_system(pdb.topology, molecules=molecule) integrator = LangevinIntegrator(300 * kelvin, 1 / picosecond, 0.002 * picosecond) platform = Platform.getPlatformByName('CUDA') simulation = app.Simulation(pdb.topology, system, integrator, platform) simulation.context.setPositions(pdb.positions) simulation.loadState('parent.xml') simulation.reporters.append( StateDataReporter('seg.nfo', 5000, step=True, potentialEnergy=True, kineticEnergy=True, temperature=True)) simulation.reporters.append(HDF5Reporter('seg.h5', 10000)) simulation.step(50000) simulation.saveState('seg.xml')
def writeHeader(topology, file=sys.stdout, entry=None, keepIds=False): """Write out the header for a PDBx/mmCIF file. Parameters ---------- topology : Topology The Topology defining the molecular system being written file : file=stdout A file to write the file to entry : str=None The entry ID to assign to the CIF file keepIds : bool=False If True, keep the residue and chain IDs specified in the Topology rather than generating new ones. Warning: It is up to the caller to make sure these are valid IDs that satisfy the requirements of the PDBx/mmCIF format. Otherwise, the output file will be invalid. """ if entry is not None: print('data_%s' % entry, file=file) else: print('data_cell', file=file) print("# Created with OpenMM %s, %s" % (Platform.getOpenMMVersion(), str(date.today())), file=file) print('#', file=file) vectors = topology.getPeriodicBoxVectors() if vectors is not None: a, b, c, alpha, beta, gamma = computeLengthsAndAngles(vectors) RAD_TO_DEG = 180 / math.pi print('_cell.length_a %10.4f' % (a * 10), file=file) print('_cell.length_b %10.4f' % (b * 10), file=file) print('_cell.length_c %10.4f' % (c * 10), file=file) print('_cell.angle_alpha %10.4f' % (alpha * RAD_TO_DEG), file=file) print('_cell.angle_beta %10.4f' % (beta * RAD_TO_DEG), file=file) print('_cell.angle_gamma %10.4f' % (gamma * RAD_TO_DEG), file=file) print('#', file=file) # Identify bonds that should be listed in the file. bonds = [] for atom1, atom2 in topology.bonds(): if atom1.residue.name not in PDBFile._standardResidues or atom2.residue.name not in PDBFile._standardResidues: bonds.append((atom1, atom2)) elif atom1.name == 'SG' and atom2.name == 'SG' and atom1.residue.name == 'CYS' and atom2.residue.name == 'CYS': bonds.append((atom1, atom2)) if len(bonds) > 0: # Write the bond information. print('loop_', file=file) print('_struct_conn.id', file=file) print('_struct_conn.conn_type_id', file=file) print('_struct_conn.ptnr1_label_asym_id', file=file) print('_struct_conn.ptnr1_label_comp_id', file=file) print('_struct_conn.ptnr1_label_seq_id', file=file) print('_struct_conn.ptnr1_label_atom_id', file=file) print('_struct_conn.ptnr2_label_asym_id', file=file) print('_struct_conn.ptnr2_label_comp_id', file=file) print('_struct_conn.ptnr2_label_seq_id', file=file) print('_struct_conn.ptnr2_label_atom_id', file=file) chainIds = {} resIds = {} if keepIds: for chain in topology.chains(): chainIds[chain] = chain.id for res in topology.residues(): resIds[res] = res.id else: for (chainIndex, chain) in enumerate(topology.chains()): chainIds[chain] = chr(ord('A') + chainIndex % 26) for (resIndex, res) in enumerate(chain.residues()): resIds[res] = resIndex + 1 for i, (atom1, atom2) in enumerate(bonds): if atom1.residue.name == 'CYS' and atom2.residue.name == 'CYS': bondType = 'disulf' else: bondType = 'covale' line = "bond%d %s %s %-4s %5s %-4s %s %-4s %5s %-4s" print(line % (i + 1, bondType, chainIds[atom1.residue.chain], atom1.residue.name, resIds[atom1.residue], atom1.name, chainIds[atom2.residue.chain], atom2.residue.name, resIds[atom2.residue], atom2.name), file=file) print('#', file=file) # Write the header for the atom coordinates. print('loop_', file=file) print('_atom_site.group_PDB', file=file) print('_atom_site.id', file=file) print('_atom_site.type_symbol', file=file) print('_atom_site.label_atom_id', file=file) print('_atom_site.label_alt_id', file=file) print('_atom_site.label_comp_id', file=file) print('_atom_site.label_asym_id', file=file) print('_atom_site.label_entity_id', file=file) print('_atom_site.label_seq_id', file=file) print('_atom_site.pdbx_PDB_ins_code', file=file) print('_atom_site.Cartn_x', file=file) print('_atom_site.Cartn_y', file=file) print('_atom_site.Cartn_z', file=file) print('_atom_site.occupancy', file=file) print('_atom_site.B_iso_or_equiv', file=file) print('_atom_site.Cartn_x_esd', file=file) print('_atom_site.Cartn_y_esd', file=file) print('_atom_site.Cartn_z_esd', file=file) print('_atom_site.occupancy_esd', file=file) print('_atom_site.B_iso_or_equiv_esd', file=file) print('_atom_site.pdbx_formal_charge', file=file) print('_atom_site.auth_seq_id', file=file) print('_atom_site.auth_comp_id', file=file) print('_atom_site.auth_asym_id', file=file) print('_atom_site.auth_atom_id', file=file) print('_atom_site.pdbx_PDB_model_num', file=file)