def test_partial_bondorder(verbose=False): """Test setup of a molecule which activates partial bond order code.""" from openeye import oechem mol = oechem.OEMol() from openeye import oeiupac oeiupac.OEParseIUPACName(mol, 'benzene') positions = positions_from_oemol(mol) oechem.OETriposAtomNames(mol) topology = generateTopologyFromOEMol(mol) # Load forcefield from above ffxml = StringIO(ffxml_contents_noconstraints) ff = ForceField(ffxml) # Set up once using AM1BCC charges system = ff.createSystem(topology, [mol], chargeMethod='OECharges_AM1BCCSym', verbose=verbose) # Check that energy is what it ought to be -- the partial bond order # for benzene makes the energy a bit higher than it would be without it energy = get_energy(system, positions) if energy < 7.50 or energy > 7.60: raise Exception( "Partial bond order code seems to have issues, as energy for benzene is outside of tolerance in tests." ) # Set up once also without asking for charges system = ff.createSystem(topology, [mol], verbose=verbose) energy = get_energy(system, positions) # Energy is lower with user supplied charges (which in this case are zero) if energy < 4.00 or energy > 6.0: raise Exception( "Partial bond order code seems to have issues when run with user-provided charges, as energy for benzene is out of tolerance in tests." )
def check_system_creation_from_molecule(forcefield, mol, chargeMethod=None, verbose=False): """ Generate a System from the given OEMol and SMIRNOFF forcefield and check that its energy is finite. Parameters ---------- forcefield : ForceField SMIRNOFF forcefield mol : oechem.OEMol Molecule to test (need not have coordinates) chargeMethod : str, optional, default=None Charge method to use in creating system """ topology = generateTopologyFromOEMol(mol) system = forcefield.createSystem(topology, [mol], chargeMethod=chargeMethod, verbose=verbose) # Test energy computation. positions = positions_from_oemol(mol) check_energy_is_finite(system, positions)
def create_system_from_molecule(forcefield, mol, verbose=False): """ Generate a System from the given OEMol and SMIRNOFF forcefield, return the resulting System. Parameters ---------- forcefield : ForceField SMIRNOFF forcefield mol : oechem.OEMol Molecule to test (must have coordinates) Returns ---------- topology : OpenMM Topology system : OpenMM System positions : initial atomic positions (OpenMM) """ # Create system from openforcefield.utils import generateTopologyFromOEMol topology = generateTopologyFromOEMol(mol) system = forcefield.createSystem(topology, [mol], verbose=verbose) # Get positions coordinates = mol.GetCoords() natoms = len(coordinates) positions = np.zeros([natoms, 3], np.float32) for index in range(natoms): (x, y, z) = coordinates[index] positions[index, 0] = x positions[index, 1] = y positions[index, 2] = z positions = unit.Quantity(positions, unit.angstroms) return topology, system, positions
def initialize_system(dt=0.001, temperature=100, forcefield_file='forcefield/smirnoff99Frosst.offxml', smiles="C1CCCCC1"): mol = OEMol() # OEParseSmiles(mol, 'CCOCCSCC') # OEParseSmiles(mol, 'c1ccccc1') OEParseSmiles(mol, smiles) # OEParseSmiles(mol, 'C([C@@H]1[C@H]([C@@H]([C@H](C(O1)O)O)O)O)O') OEAddExplicitHydrogens(mol) masses = get_masses(mol) num_atoms = mol.NumAtoms() topology = generateTopologyFromOEMol(mol) ff = ForceField(get_data_filename(forcefield_file)) nrgs, total_params, offsets = system_builder.construct_energies( ff, mol, False) # dt = 0.0025 # friction = 10.0 # temperature = 300 # gradient descent dt = dt friction = 10.0 temperature = temperature a, b, c = get_abc_coefficents(masses, dt, friction, temperature) buf_size = estimate_buffer_size(1e-10, a) print("BUFFER SIZE", buf_size) omegaOpts = oeomega.OEOmegaOptions() omegaOpts.SetMaxConfs(1) omega = oeomega.OEOmega(omegaOpts) omega.SetStrictStereo(False) if not omega(mol): assert 0 x0 = mol_coords_to_numpy_array(mol) / 10 intg = custom_ops.Integrator_double(dt, buf_size, num_atoms, total_params, a, b, c) context = custom_ops.Context_double(nrgs, intg) x0 = minimizer.minimize_newton_cg(nrgs, x0, total_params) return nrgs, offsets, intg, context, x0, total_params
def test_parameter_completeness_check(self): """Test that proper exceptions are raised if a force field fails to assign parameters to valence terms in a molecule.""" from openeye import oechem mol = oechem.OEMol() oechem.OEParseSmiles(mol, 'CCC') oechem.OEAddExplicitHydrogens(mol) oechem.OETriposAtomNames(mol) ff = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH.ffxml')) topology = generateTopologyFromOEMol(mol) # Test nonbonded error checking by wiping out required LJ parameter params = ff.getParameter(paramID='n0001') params['smirks'] = '[#136:1]' ff.setParameter(paramID='n0001', params=params) ff.setParameter(paramID='n0002', params=params) with self.assertRaises(Exception): system = ff.createSystem(topology, [mol]) ff = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH.ffxml')) # Test bond error checking by wiping out a required bond parameter params = ff.getParameter(paramID='b0001') params['smirks'] = '[#136:1]~[*:2]' ff.setParameter(paramID='b0001', params=params) with self.assertRaises(Exception): system = ff.createSystem(topology, [mol]) ff = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH.ffxml')) # Test angle error checking by wiping out a required angle parameter params = ff.getParameter(paramID='a0001') params['smirks'] = '[#136:1]~[*:2]~[*:3]' ff.setParameter(paramID='a0001', params=params) with self.assertRaises(Exception): system = ff.createSystem(topology, [mol]) ff = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH.ffxml')) # Test torsion error checking by wiping out a required torsion parameter params = ff.getParameter(paramID='t0001') params['smirks'] = '[#136:1]~[*:2]~[*:3]~[*:4]' ff.setParameter(paramID='t0001', params=params) ff.setParameter(paramID='t0004', params=params) with self.assertRaises(Exception): system = ff.createSystem(topology, [mol]) ff = ForceField(get_data_filename('forcefield/Frosst_AlkEthOH.ffxml'))
def initialize(input_smiles, gp): train_reference_args = [] train_args = [] train_offset_idxs = [] train_charge_idxs = [] for smi_idx, smiles in enumerate(input_smiles): print("processing", smiles, smi_idx, "/", len(input_smiles)) mol = OEMol() OEParseSmiles(mol, smiles) OEAddExplicitHydrogens(mol) masses = get_masses(mol) num_atoms = mol.NumAtoms() omegaOpts = oeomega.OEOmegaOptions() omegaOpts.SetMaxConfs(1) omega = oeomega.OEOmega(omegaOpts) omega.SetStrictStereo(False) if not omega(mol): assert 0 topology = generateTopologyFromOEMol(mol) reference_forcefield_file = 'forcefield/smirnoff99Frosst_perturbed.offxml' ff = ForceField(get_data_filename(reference_forcefield_file)) params = system_builder.construct_energies(ff, mol, True) train_reference_args.append((params[0], params[1], masses, mol)) params = system_builder.construct_energies(ff, mol, False) # global_params = args[0] # nrg_params = args[1] # total_params = args[2] # masses = args[3] # mol = args[4] # charge_idxs = args[5] train_args.append((gp, params[0], params[1], masses, mol, params[3])) train_offset_idxs.append(params[2]) train_charge_idxs.append(params[3]) label_confs = [generate_conformations(a) for a in train_reference_args] return train_args, train_offset_idxs, train_charge_idxs, label_confs
def test_change_parameters(verbose=False): """Test modification of forcefield parameters.""" from openeye import oechem # Load simple OEMol ifs = oechem.oemolistream( get_data_filename('molecules/AlkEthOH_c100.mol2')) mol = oechem.OEMol() flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield ifs.SetFlavor(oechem.OEFormat_MOL2, flavor) oechem.OEReadMolecule(ifs, mol) oechem.OETriposAtomNames(mol) # Load forcefield file ffxml = get_data_filename('forcefield/Frosst_AlkEthOH.ffxml') ff = ForceField(ffxml) topology = generateTopologyFromOEMol(mol) # Create initial system system = ff.createSystem(topology, [mol], verbose=verbose) # Get initial energy before parameter modification positions = positions_from_oemol(mol) old_energy = get_energy(system, positions) # Get params for an angle params = ff.getParameter(smirks='[a,A:1]-[#6X4:2]-[a,A:3]') # Modify params params['k'] = '0.0' ff.setParameter(params, smirks='[a,A:1]-[#6X4:2]-[a,A:3]') # Write params ff.writeFile(tempfile.TemporaryFile(suffix='.ffxml')) # Make sure params changed energy! (Test whether they get rebuilt on system creation) system = ff.createSystem(topology, [mol], verbose=verbose) energy = get_energy(system, positions) if verbose: print("New energy/old energy:", energy, old_energy) if np.abs(energy - old_energy) < 0.1: raise Exception("Error: Parameter modification did not change energy.")
def new_param_energy_vac(coords, params, T=293.15): """ Return potential energies associated with specified parameter perturbations. Parameters ---------- coords: coordinates from the simulation(s) ran on the given molecule params: arbitrary length dictionary of changes in parameter across arbitrary number of states. Highest level key is the molecule AlkEthOH_ID, second level of keys are the new state, the values of each of these subkeys are a arbitrary length list of length 3 lists where the length 3 lists contain information on a parameter to change in the form: [SMIRKS, parameter type, parameter value]. I.e. : params = {'AlkEthOH_c1143':{'State 1':[['[6X4:1]-[#1:2]','k','620'],['[6X4:1]-[#6X4:2]','length','1.53'],...],'State 2':[...],...}} T: Temperature of the system. By default set to 300 K. Returns ------- E_kn: a kxN matrix of the dimensional energies associated with the forcfield parameters used as input u_kn: a kxN matrix of the dimensionless energies associated with the forcfield parameters used as input """ #------------------- # CONSTANTS #------------------- kB = 0.0083145 #Boltzmann constant (Gas constant) in kJ/(mol*K) beta = 1/(kB*T) #------------------- # PARAMETERS #------------------- params = params # Determine number of states we wish to estimate potential energies for mols = [] for i in params: mols.append(i) mol = 'monomers/'+mols[0]+'.mol2' K = len(params[mols[0]].keys()) #------------- # SYSTEM SETUP #------------- verbose = False # suppress echos from OEtoolkit functions ifs = oechem.oemolistream(mol) mol = oechem.OEMol() # This uses parm@frosst atom types, so make sure to use the forcefield-flavor reader flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield ifs.SetFlavor( oechem.OEFormat_MOL2, flavor) oechem.OEReadMolecule(ifs, mol ) # Perceive tripos types oechem.OETriposAtomNames(mol) # Load forcefield file #ffxml = 'smirnoff99Frosst_with_AllConstraints.ffxml'# #print('The forcefield being used is smirnoff99Frosst_with_AllConstraints.ffxml') ffxml = get_data_filename('forcefield/smirnoff99Frosst.ffxml') print('The forcefield being used is smirnoff99Frosst.ffxml') ff = ForceField(ffxml) # Generate a topology topology = generateTopologyFromOEMol(mol) #----------------- # MAIN #----------------- # Calculate energies E_kn = np.zeros([K,len(coords)],np.float64) u_kn = np.zeros([K,len(coords)],np.float64) for i,j in enumerate(params): AlkEthOH_id = j for k,l in enumerate(params[AlkEthOH_id]): print("Anotha one") for m,n in enumerate(params[AlkEthOH_id][l]): newparams = ff.getParameter(smirks=n[0]) newparams[n[1]]=n[2] ff.setParameter(newparams,smirks=n[0]) system = ff.createSystem(topology, [mol]) #print(newparams) for o,p in enumerate(coords): e = get_energy_vac(system,p) E_kn[k,o] = e._value u_kn[k,o] = e._value*beta return E_kn,u_kn
coordinates = mol.GetCoords() natoms = len(coordinates) positions = np.zeros([natoms, 3], np.float64) for index in range(natoms): (x, y, z) = coordinates[index] positions[index, 0] = x positions[index, 1] = y positions[index, 2] = z positions = Quantity(positions, angstroms) # Load forcefield forcefield = ForceField( get_data_filename('forcefield/smirnoff99Frosst.ffxml')) # Define system topology = generateTopologyFromOEMol(mol) params = forcefield.getParameter(smirks='[#1:1]-[#8]') params['rmin_half'] = '0.01' params['epsilon'] = '0.01' forcefield.setParameter(params, smirks='[#1:1]-[#8]') system = forcefield.createSystem(topology, [mol]) """ paramlist1 = np.array([100.,140.,60.,140.,60.])#np.arange(float(sys.argv[2]),float(sys.argv[3]),float(sys.argv[4])) paramlist2 = np.array([109.5,76.5,76.5,142.5,142.5]) #j = sys.argv[5] smirkseries = '[*:1]~[#6X4:2]-[*:3]'#sys.argv[6]#'[#6X4:1]-[#1:2]' paramtype1 = 'k'#sys.argv[7]#'length' paramtype2 = 'angle'#sys.argv[8]