def test_molecule(molecule_name, tripos_mol2_filename, charge_method="bcc"): """Create a GAFF molecule via LEAP and ffXML and compare force terms. Parameters ---------- molecule_name : str Name of the molecule tripos_mol2_filename : str Filename of input mol2 file charge_method : str, default="bcc" If None, use charges in existing MOL2. Otherwise, use a charge model when running antechamber. """ # Generate GAFF parameters. amber = import_("openmoltools.amber") (gaff_mol2_filename, frcmod_filename) = amber.run_antechamber(molecule_name, tripos_mol2_filename, charge_method=charge_method) # Create simulations. simulation_ffxml = create_ffxml_simulation(molecule_name, gaff_mol2_filename, frcmod_filename) simulation_leap = create_leap_simulation(molecule_name, gaff_mol2_filename, frcmod_filename) # Compare simulations. syscheck = system_checker.SystemChecker(simulation_ffxml, simulation_leap) syscheck.check_force_parameters() groups0, groups1 = syscheck.check_energy_groups() energy0, energy1 = syscheck.check_energies()
def compare_system_energies(topology0, topology1, system0, system1, positions0, positions1=None, label0="AMBER system", label1="SMIRNOFF system", verbose=True, skip_assert=False, skip_improper=False): """ Given two OpenMM systems, check that their energies and component-wise energies are consistent, and return these. The same positions will be used for both systems unless a second set of positions is provided. Parameters ---------- topology0 : OpenMM Topology Topology of first system topology1 : OpenMM Topology Topology of second system system0 : OpenMM System First system for comparison (usually from AMBER) system1 : OpenMM System Second system for comparison (usually from SMIRNOFF) positions0 : simtk.unit.Quantity wrapped Positions to use for energy evaluation comparison positions1 (optional) : simtk.unit.Quantity wrapped (optional) Positions to use for second OpenMM system; original positions are used if this is not provided label0 (optional) : str String labeling system0 for output. Default, "AMBER system" label1 (optional) : str String labeling system1 for output. Default, "SMIRNOFF system" verbose (optional) : bool Print out info on energies, True/False (default True) skip_assert (optional) : bool Skip assertion that energies must be equal within specified tolerance. Default False. skip_improper (optional) : bool Skip detailed checking of force terms on impropers (helpful here if comparing with AMBER force fields using different definitions of impropers.) Default False. Returns ---------- groups0 : dict As returned by openmoltools.system_checker.check_energy_groups, a dictionary with keys "bond", "angle", "nb", "torsion" and values corresponding to the energies of these components for the first simulation object groups1 : dict As returned by openmoltools.system_checker.check_energy_groups, a dictionary with keys "bond", "angle", "nb", "torsion" and values corresponding to the energies of these components for the second simulation object energy0 : simtk.unit.Quantity Energy of first system energy1 : simtk.unit.Quantity Energy of second system TO DO: Allow energy extraction/comparison of terms specified by particular SMARTS queries i.e. for specific bond, angle, or torsional terms. """ # Create integrator timestep = 1.0 * unit.femtoseconds integrator0 = simtk.openmm.VerletIntegrator(timestep) integrator1 = simtk.openmm.VerletIntegrator(timestep) # Grab second positions if positions1 == None: positions1 = copy.deepcopy(positions0) # Create simulations platform = simtk.openmm.Platform.getPlatformByName("Reference") simulation0 = app.Simulation(topology0, system0, integrator0, platform=platform) simulation0.context.setPositions(positions0) simulation1 = app.Simulation(topology1, system1, integrator1, platform=platform) simulation1.context.setPositions(positions1) # Print what torsions were found if verbose if verbose: # Build list of atoms for debugging info atoms0 = [atom for atom in simulation0.topology.atoms()] atoms1 = [atom for atom in simulation1.topology.atoms()] # Loop over first system and print torsion info for force in simulation0.system.getForces(): if type(force) == mm.PeriodicTorsionForce: print( "Num (type) \t Num (type) \t Num (type) \t Num (type) \t per \t phase \t k0" ) for k in range(force.getNumTorsions()): i0, i1, i2, i3, per, phase, k0 = force.getTorsionParameters( k) print( "%3s (%3s)- %3s (%3s)- \t %s (%3s)- \t %3s (%3s)- \t %f \t %f \t %f " % (i0, atoms0[i0].name, i1, atoms0[i1].name, i2, atoms0[i2].name, i3, atoms0[i3].name, per, phase / unit.degree, k0 / unit.kilojoule_per_mole)) for force in simulation1.system.getForces(): if type(force) == mm.PeriodicTorsionForce: print( "Num (type) \t Num (type) \t Num (type) \t Num (type) \t per \t phase \t k0" ) for k in range(force.getNumTorsions()): i0, i1, i2, i3, per, phase, k0 = force.getTorsionParameters( k) print( "%3s (%3s)- %3s (%3s)- %3s (%3s)- %3s (%3s) - %f \t %f \t %f " % (i0, atoms1[i0].name, i1, atoms1[i1].name, i2, atoms1[i2].name, i3, atoms1[i3].name, per, phase / unit.degree, k0 / unit.kilojoule_per_mole)) # Do energy comparison, print info if desired syscheck = system_checker.SystemChecker(simulation0, simulation1) if not skip_assert: # Only check force terms if we want to make sure energies are identical syscheck.check_force_parameters(skipImpropers=skip_improper) groups0, groups1 = syscheck.check_energy_groups(skip_assert=skip_assert) energy0, energy1 = syscheck.check_energies(skip_assert=skip_assert) if verbose: print("Energy of %s: " % label0, energy0) print("Energy of %s: " % label1, energy1) print("\nComponents of %s:" % label0) for key in groups0.keys(): print("%s: " % key, groups0[key]) print("\nComponents of %s:" % label1) for key in groups1.keys(): print("%s: " % key, groups1[key]) # Return return groups0, groups1, energy0, energy1
prmtop = app.AmberPrmtopFile("%s/%s.prmtop" % (ligand_path, ligand_name)) inpcrt = app.AmberInpcrdFile("%s/%s.inpcrd" % (ligand_path, ligand_name)) system_prm = prmtop.createSystem(nonbondedMethod=app.NoCutoff, nonbondedCutoff=1.0 * u.nanometers, constraints=None) mol2 = gafftools.Mol2Parser("%s/%s.mol2" % (ligand_path, ligand_name)) top, xyz = mol2.to_openmm() forcefield = app.ForceField("%s/%s.xml" % (ligand_path, ligand_name)) system_xml = forcefield.createSystem(top, nonbondedMethod=app.NoCutoff, nonbondedCutoff=1.0 * u.nanometers, constraints=None) integrator_xml = mm.LangevinIntegrator(temperature, friction, timestep) simulation_xml = app.Simulation(top, system_xml, integrator_xml) simulation_xml.context.setPositions(xyz) integrator_prm = mm.LangevinIntegrator(temperature, friction, timestep) simulation_prm = app.Simulation(prmtop.topology, system_prm, integrator_prm) simulation_prm.context.setPositions(xyz) checker = system_checker.SystemChecker(simulation_xml, simulation_prm) checker.check_force_parameters() energy0, energy1 = checker.check_energies() abs((energy0 - energy1) / u.kilojoules_per_mole)