def _addPositionalHarmonicRestraints(self, sys): go = [] for (fcounter, conn, tables, offset) in self._localVars(): if not self._hasTable('posre_harm_term', tables): go.append(False) else: go.append(True) if go[fcounter] and (not self._hasTable('posre_harm_param', tables)): raise IOError( 'DMS file lacks posre_harm_param table even though posre_harm_term table is present.' ) return if not any(go): return if self._verbose: print("Using positional harmonic restraints.") force = mm.CustomExternalForce( "hkx*(x-x0)^2+hky*(y-y0)^2+hkz*(z-z0)^2") force.addPerParticleParameter("x0") force.addPerParticleParameter("y0") force.addPerParticleParameter("z0") force.addPerParticleParameter("hkx") force.addPerParticleParameter("hky") force.addPerParticleParameter("hkz") sys.addForce(force) q = """SELECT p0, x0, y0, z0, fcx, fcy, fcz FROM posre_harm_term INNER JOIN posre_harm_param ON posre_harm_term.param=posre_harm_param.id""" for (fcounter, conn, tables, offset) in self._localVars(): if not go[fcounter]: continue for p0, x0, y0, z0, fcx, fcy, fcz in conn.execute(q): p0 += offset x0d = (x0 * angstrom).value_in_unit(nanometer) y0d = (y0 * angstrom).value_in_unit(nanometer) z0d = (z0 * angstrom).value_in_unit(nanometer) hfcxd = (0.5 * fcx * kilocalorie_per_mole / angstrom**2).value_in_unit(kilojoule_per_mole / (nanometer**2)) hfcyd = (0.5 * fcy * kilocalorie_per_mole / angstrom**2).value_in_unit(kilojoule_per_mole / (nanometer**2)) hfczd = (0.5 * fcz * kilocalorie_per_mole / angstrom**2).value_in_unit(kilojoule_per_mole / (nanometer**2)) force.addParticle(p0, [x0d, y0d, z0d, hfcxd, hfcyd, hfczd])
def setUp(self): system = mm.System() system.addParticle(1.0) for i in range(32): force = mm.CustomExternalForce(str(i)) force.addParticle(0, []) force.setForceGroup(i) system.addForce(force) platform = mm.Platform.getPlatformByName('Reference') context = mm.Context(system, mm.VerletIntegrator(0), platform) context.setPositions([(0, 0, 0)]) self.context = context
def minimize_potential_energy( chimera, ff: str, output: str = "/tmp/build", keep_output_files=True, cuda=False, restraint_backbone: bool = True ) -> Tuple[unit.quantity.Quantity, Chimera]: """ :param chimera: A chimera object where to perform the minimization :param forcefield: The forcefield to use for the minimization. Select between "amber" and "charmm" :param output: A folder where to keep the files. If not provided they will be stored in the /tmp folder and later removed. :param cuda: Whether to use GPU acceleration :param restraint_backbone: Keep the backbone atoms constraint in space :return: The chimera object that was minimized and the potential energy value. """ if not os.path.exists(output): os.mkdir(output) smol = prepare_protein(chimera) smol.write(f"{output}/protein.pdb") pdb = PDBFile(f"{output}/protein.pdb") parm = load_file(f"{output}/protein.pdb") modeller = Modeller(pdb.topology, pdb.positions) if ff == 'amber': forcefield = ForceField('amber14-all.xml', 'amber14/tip3pfb.xml') if ff == 'charmm': forcefield = ForceField('charmm36.xml', 'charmm36/tip3p-pme-b.xml') modeller.addSolvent(forcefield, padding=1.0 * unit.nanometer) system = forcefield.createSystem(modeller.topology, nonbondedMethod=PME, nonbondedCutoff=1 * unit.nanometer, constraints=HBonds) if restraint_backbone: # Applies an external force on backbone atoms # This allows the backbone to stay rigid, while severe clashes can still be resolved force = mm.CustomExternalForce("k*((x-x0)^2+(y-y0)^2+(z-z0)^2)") force.addGlobalParameter( "k", 5.0 * unit.kilocalories_per_mole / unit.angstroms**2) force.addPerParticleParameter("x0") force.addPerParticleParameter("y0") force.addPerParticleParameter("z0") for idx, atom_crd in enumerate(parm.positions): if idx >= len(parm.atoms): continue if parm.atoms[idx] in ('CA', 'C', 'N'): force.addParticle(idx, atom_crd.value_in_unit(unit.nanometers)) system.addForce(force) integrator = mm.LangevinIntegrator(temperature, friction, error_tolerance) simulation = Simulation(modeller.topology, system, integrator) simulation.context.setPositions(modeller.positions) # Get pre-minimization energy (scoring) state = simulation.context.getState(getEnergy=True, getForces=True) pre_energy = state.getPotentialEnergy().in_units_of( unit.kilocalories_per_mole) logger.info(f"Energy before minimization {pre_energy}") # Setup CPU minimization integrator.setConstraintTolerance(distance_tolerance) simulation.minimizeEnergy() post_position = simulation.context.getState( getPositions=True).getPositions() post_state = simulation.context.getState(getEnergy=True, getForces=True) if cuda: min_coords = simulation.context.getState(getPositions=True) platform = mm.Platform.getPlatformByName('CUDA') properties = {'CudaPrecision': 'mixed'} gpu_integrator = mm.VariableLangevinIntegrator(temperature, friction, error_tolerance) gpu_integrator.setConstraintTolerance(distance_tolerance) gpu_min = Simulation(modeller.topology, system, gpu_integrator, platform, properties) gpu_min.context.setPositions(min_coords.getPositions()) gpu_min.minimizeEnergy() post_position = gpu_min.context.getState( getPositions=True).getPositions() post_state = gpu_min.context.getState(getEnergy=True, getForces=True) post_energy = post_state.getPotentialEnergy().in_units_of( unit.kilocalories_per_mole) logger.info(f"Energy after minimization {post_energy}") PDBFile.writeFile(modeller.topology, post_position, open(f"{output}/structure_minimized.pdb", 'w'), keepIds=True) min_mol = Chimera(filename=f"{output}/structure_minimized.pdb") if keep_output_files is False: shutil.rmtree(output) return post_energy, min_mol
s.bonds = s.bonds.append(extra_bonds) # Check that the bonds correspond with the correct molecule s.bonds = s.bonds[( s.bonds['molecule'] == s.atom_list['residue_name'].loc[s.bonds['i']]. values) | s.bonds['molecule'].isin(['Actin-ADP', 'ABP', 'CaMKII'])] print(s.system.getDefaultPeriodicBoxVectors()) s.setForces(BundleConstraint=aligned, PlaneConstraint=system2D, CaMKII_Force=camkii_force) top = openmm.app.PDBxFile(f'{Sname}.cif') coord = openmm.app.PDBxFile(f'{Sname}.cif') #Add external force external_force = openmm.CustomExternalForce( "k_spring*(z-Z_A1)^2+k_spring*(y-y_A1)^2+k_spring*(x-x_A1)^2") external_force.addGlobalParameter('k_spring', 10) A1 = coord.getPositions()[-2] Z_A1 = A1[2] external_force.addGlobalParameter('x_A1', A1[0]) external_force.addGlobalParameter('y_A1', A1[1]) external_force.addGlobalParameter('Z_A1', A1[2]) external_force.addParticle(int(s.atom_list.index[-2])) # Add external force external_force2 = openmm.CustomExternalForce( "k_spring*(z-Z_A2)^2+k_spring*(y-y_A2)^2+k_spring*(x-x_A2)^2") # s.atom_list[(s.atom_list['atom_name'] == 'A2') & # (s.atom_list['chain_index'] == 1) & # (s.atom_list['residue_index'] == 999)] A2 = coord.getPositions()[-1]