# color_limit = max(abs(np.nanmin(esp_values)), abs(np.nanmax(esp_values))) # color_span = [-color_limit, color_limit] # Note that the y-axis is not set for different charge_types! If this is # desired behaviour, it could be set in a similar manner here. for charge_type in charge_types.keys(): charge_dir = output_path + charge_type # raises OSError if directory exists os.mkdir(charge_dir) if charge_types[charge_type][0] in ['.', '_']: filename = path + molecule_name + charge_types[charge_type] else: filename = path + charge_types[charge_type] update_with_charges(charge_type, filename, molecule) print("\n{0} charges:".format(charge_type.upper())) for atom in molecule: atom.print_with_charge(charge_type) # The same but to file (would be better with my Tee class from featsel) with open(charge_dir + '/charges.txt', 'w') as f: for atom in esp_cube.molecule: atom.print_with_charge(charge_type, f=f) # This is costly but was designed to be easy for many charge types, so # should be moved outside of the loop rep = calc_grid_field(esp_cube.molecule, esp_cube.field.grid, 'rep_esp', [charge_type])[0] # Change details of calculating difference here (absolute, relative) diff = difference(esp_cube.field, rep)
with open(path + "fit_points.p", 'wb') as f: pickle.dump([elem.filename for elem in calcs], f) # PART 2 --- run when the Gaussian calculations have been completed if False: with open(path + "fit_points.p", 'rb') as f: calcs = pickle.load(f) rms_list = [] charges_dict = {} color_span = [] error_color_span = [] for calc in calcs: g = resp_helpers.G09_esp(path + calc + '.esp') charges.update_with_charges(charge_type, path + calc + '.log', g.molecule) with open(path + calc + "-charges.txt", "a") as fc: for atom in g.molecule: atom.print_with_charge(charge_type, fc) if atom.label in charges_dict: charges_dict[atom.label].append(atom.charges[charge_type]) else: charges_dict[atom.label] = [atom.charges[charge_type]] min_rms, min_rrms, rep_esp_field = rms_and_rep(g.field, g.molecule, charge_type) rms_list.append(min_rms) print("\n", min_rms, file=fc) # Default given as extremal values of methane CHelpG color_span = check_color_span(g.field.values, color_span,
os.mkdir(resp_output_path) os.mkdir(min_resp_output_path) log_fn = path + molecule_name + "_" + charge_type + ".log" esp_log_fn = path + molecule_name + "_" + esp_charge_type + ".log" g = resp_helpers.G09_esp(path + esp_fn) # Both the Gaussian ESP fitting methods and other charge assignment methods may # not yield equivalent charges. As equivalent charges make more sense for force # field development, they will be used. The ESP charges are equivalenced by # performing unrestrained RESP, which will be used as a reference for the fit # minimum. Charges from the other method will be equivalenced manually by my # averaging function `resp.equivalence`. They will be scaled to obtain # different ratio charges. All the charges are calculated and printed at the # start for reference. update_with_charges(esp_charge_type, esp_log_fn, g.molecule) update_with_charges(charge_type, log_fn, g.molecule) equiv_charges = resp.equivalence(g.molecule, charge_type, path)[0] _update_molecule_with_charges(g.molecule, equiv_charges, charge_type + '_equiv') print("\nRunning unrestrained RESP to fit ESP with equivalence:") esp_equiv_molecule = resp.run_resp(path, resp_output_path + 'unrest', resp_type='unrest', esp_fn=esp_fn) charge_rrms = rms_and_rep(g.field, g.molecule, charge_type)[1] equiv_charge_rrms = rms_and_rep(g.field, g.molecule, charge_type + '_equiv')[1] esp_charge_rrms = rms_and_rep(g.field, g.molecule, esp_charge_type)[1] resp_charge_rrms = rms_and_rep(g.field, esp_equiv_molecule, 'resp')[1]
os.mkdir(resp_output_path) os.mkdir(min_resp_output_path) log_fn = path + molecule_name + "_" + charge_type + ".log" esp_log_fn = path + molecule_name + "_" + esp_charge_type + ".log" g = resp_helpers.G09_esp(path + esp_fn) # Both the Gaussian ESP fitting methods and other charge assignment methods may # not yield equivalent charges. As equivalent charges make more sense for force # field development, they will be used. The ESP charges are equivalenced by # performing unrestrained RESP, which will be used as a reference for the fit # minimum. Charges from the other method will be equivalenced manually by my # averaging function `resp.equivalence`. They will be scaled to obtain # different ratio charges. All the charges are calculated and printed at the # start for reference. update_with_charges(esp_charge_type, esp_log_fn, g.molecule) update_with_charges(charge_type, log_fn, g.molecule) equiv_charges = resp.equivalence(g.molecule, charge_type, path)[0] _update_molecule_with_charges(g.molecule, equiv_charges, charge_type+'_equiv') print("\nRunning unrestrained RESP to fit ESP with equivalence:") esp_equiv_molecule = resp.run_resp( path, resp_output_path + 'unrest', resp_type='unrest', esp_fn=esp_fn) charge_rrms = rms_and_rep(g.field, g.molecule, charge_type)[1] equiv_charge_rrms = rms_and_rep(g.field, g.molecule, charge_type + '_equiv')[1] esp_charge_rrms = rms_and_rep(g.field, g.molecule, esp_charge_type)[1] resp_charge_rrms = rms_and_rep(g.field, esp_equiv_molecule, 'resp')[1] print("\nThe molecule with {0} charges:".format(charge_type.upper())) print("RRMS: {0:.5f}".format(charge_rrms)) for atom in g.molecule:
os.mkdir(resp_output_path) levels = [1, 5, 10, 20, 30, 50, 100] print("\nRunning unrestrained RESP to fit ESP with equivalence:") esp_equiv_molecule = resp.run_resp(path, resp_output_path + 'unrest', resp_type='unrest', esp_fn=esp_fn) # Equivalence alternative charge as well (i.e. unrest RESP on its own grid) alt_esp_equiv_molecule = resp.run_resp(path, resp_output_path + 'alt_unrest', resp_type='unrest', esp_fn=alt_esp_fn, check_ivary=False) charges.update_with_charges(esp_charge_type, log_fn, g.molecule) # This should actually be called esp_charge_rms charge_rms, charge_rrms = rms_and_rep(g.field, g.molecule, esp_charge_type)[:2] resp_rms, resp_rrms = rms_and_rep(g.field, esp_equiv_molecule, 'resp')[:2] # Note that, crucially, the equivalenced alternative charges are evaluated # on the same grid as the original charges, i.e. `g.field` alt_resp_rms, alt_resp_rrms = rms_and_rep(g.field, alt_esp_equiv_molecule, 'resp')[:2] print("\nThe molecule with {0} charges:".format(esp_charge_type.upper())) print(" RMS: {0:.5f}".format(charge_rms)) print("RRMS: {0:.5f}".format(charge_rrms)) print("RMSV: {0:.5f}".format(charge_rms / charge_rrms)) for atom in g.molecule: atom.print_with_charge(esp_charge_type)