def sterimol( session, selection, radii="UMN", showVectors=True, showRadii=True, LCorrection="FORTRAN", return_values=False ): models, attached = avoidTargets(session.logger, selection) radii = radii.lower() old_L = False if LCorrection.upper() == "FORTRAN": old_L = True model_names = [] targets = [] datas = [] info = "<pre>model\tsubstituent atom\tB1\tB2\tB3\tB4\tB5\tL\n" # if return_values: # if len(models.keys()) > 1: # raise RuntimeError("only one substituent may be selected") # if any(len(models[key]) > 1 for key in models.keys()): # raise RuntimeError("only one substituent may be selected") for model in models: rescol = ResidueCollection(model, refresh_ranks=False) for res in models[model]: for target in models[model][res]: end_atomspec = AtomSpec(attached[target].atomspec) start_atomspec = AtomSpec(target.atomspec) sub_atoms = rescol.get_fragment(start_atomspec, end_atomspec) sub = Substituent( sub_atoms, end=rescol.find_exact(end_atomspec)[0], detect=False, ) data = sub.sterimol( return_vector=True, radii=radii, old_L=old_L, ) l = np.linalg.norm(data["L"][1] - data["L"][0]) b1 = np.linalg.norm(data["B1"][1] - data["B1"][0]) b2 = np.linalg.norm(data["B2"][1] - data["B2"][0]) b3 = np.linalg.norm(data["B3"][1] - data["B3"][0]) b4 = np.linalg.norm(data["B4"][1] - data["B4"][0]) b5 = np.linalg.norm(data["B5"][1] - data["B5"][0]) if showVectors: for key, color in zip( ["B1", "B2", "B3", "B4", "B5", "L"], ["black", "green", "purple", "orange", "red", "blue"] ): start, end = data[key] s = ".color %s\n" % color s += ".note Sterimol %s\n" % key s += ".arrow %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n" % (*start, *end) stream = BytesIO(bytes(s, "utf-8")) bild_obj, status = read_bild(session, stream, "Sterimol %s" % key) session.models.add(bild_obj, parent=model) if showRadii: s = ".note radii\n" s += ".transparency 75\n" color = None for atom in sub.atoms: chix_atom = atom.chix_atom if radii == "umn": r = VDW_RADII[chix_atom.element.name] elif radii == "bondi": r = BONDI_RADII[chix_atom.element.name] if color is None or chix_atom.color != color: color = chix_atom.color rgb = [x/255. for x in chix_atom.color] rgb.pop(-1) s += ".color %f %f %f\n" % tuple(rgb) s += ".sphere %f %f %f %f\n" % (*chix_atom.coord, r) stream = BytesIO(bytes(s, "utf-8")) bild_obj, status = read_bild(session, stream, "Sterimol radii") session.models.add(bild_obj, parent=model) model_name = get_filename(model.name, include_parent_dir=False) info += "%-16s\t%-11s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n" % ( model_name, target.atomspec, b1, b2, b3, b4, b5, l ) model_names.append(model_name) targets.append(target.atomspec) datas.append(data) info = info.strip() info += "</pre>" if not return_values: session.logger.info(info, is_html=True) if return_values: return model_names, targets, datas
def main(argv): sterimol_parser = argparse.ArgumentParser( description= "calculate Boltzmann-weighted Sterimol parameters - see doi 10.1021/acscatal.8b04043", formatter_class=argparse.RawTextHelpFormatter) sterimol_parser.add_argument("infiles", metavar="input files", type=str, nargs="+", help="file containing coordinates and energy") sterimol_parser.add_argument("-if", "--input-format", type=str, default=None, choices=["log", "out", "dat"], dest="input_format", help="file format of input") sterimol_parser.add_argument( "-s", "--substituent-atom", type=str, required=True, dest="targets", help="substituent atom\n" + "1-indexed position of the starting position of the\n" + "substituent of which you are calculating sterimol\nparameters") sterimol_parser.add_argument( "-a", "--attached-to", type=str, required=True, dest="avoid", help="non-substituent atom\n" + "1-indexed position of the starting position of the atom\n" + "connected to the substituent of which you are calculating\n" + "sterimol parameters") sterimol_parser.add_argument( "-r", "--radii", type=str, default="bondi", choices=["bondi", "umn"], dest="radii", help="VDW radii to use in calculation\n" + "umn: main group vdw radii from J. Phys. Chem. A 2009, 113, 19, 5806–5812\n" + " (DOI: 10.1021/jp8111556)\n" + " transition metals are crystal radii from Batsanov, S.S. Van der Waals\n" + " Radii of Elements. Inorganic Materials 37, 871–885 (2001).\n" + " (DOI: 10.1023/A:1011625728803)\n" + "bondi: radii from J. Phys. Chem. 1964, 68, 3, 441–451 (DOI: 10.1021/j100785a001)\n" + "Default: bondi") sterimol_parser.add_argument( "-l", "--old-l", action="store_true", required=False, dest="old_L", help="approximate FORTRAN Sterimol method for determining L\n" "This is 0.4 + the ideal bond length for a target-H bond\n" "to outer VDW radii of atoms projected onto L-axis\n" "Default: L value is from VDW radii of target atom to outer\n" "VDW radii of atoms projected onto L-axis") sterimol_parser.add_argument("-t", "--temperature", type=float, default=298.15, required=False, dest="temperature", help="temperature in K\nDefault: 298.15") sterimol_parser.add_argument( "-f", "--frequency", action="store_true", default=False, required=False, dest="frequency", help="input files are frequency job output files\n" "additional average values will be calculated for ZPE, H, G, etc.") sterimol_parser.add_argument( "-w0", "--frequency-cutoff", type=float, default=100.0, required=False, dest="w0", help="cutoff frequency for quasi free energy corrections (1/cm)\n" + "Default: 100 cm^-1") sterimol_parser.add_argument("-v", "--verbose", action="store_true", default=False, required=False, dest="verbose", help="also print population") sterimol_parser.add_argument("-o", "--output", type=str, default=False, required=False, metavar="output destination", dest="outfile", help="output destination\n" + "Default: stdout") args = sterimol_parser.parse_args(args=argv) subs = [] energies = {"E": []} if args.frequency: energies["E+ZPE"] = [] energies["H(RRHO)"] = [] energies["G(RRHO)"] = [] energies["G(Quasi-RRHO)"] = [] energies["G(Quasi-Harmonic)"] = [] for infile in glob_files(args.infiles, parser=sterimol_parser): if args.input_format is not None: fr = FileReader((infile, args.input_format, infile), just_geom=False) else: fr = FileReader(infile, just_geom=False) geom = Geometry(fr) target = args.targets avoid = args.avoid end = geom.find(avoid)[0] frag = geom.get_fragment(target, stop=end) sub = Substituent(frag, end=end, detect=False) subs.append(sub) nrg = fr.other["energy"] energies["E"].append(nrg) if args.frequency: co = CompOutput(fr) dE, dH, entropy = co.therm_corr(temperature=args.temperature) rrho_dG = co.calc_G_corr(v0=0, temperature=args.temperature, method="RRHO") qrrho_dG = co.calc_G_corr(v0=args.w0, temperature=args.temperature, method="QRRHO") qharm_dG = co.calc_G_corr(v0=args.w0, temperature=args.temperature, method="QHARM") energies["E+ZPE"].append(nrg + co.ZPVE) energies["H(RRHO)"].append(nrg + dH) energies["G(RRHO)"].append(nrg + rrho_dG) energies["G(Quasi-RRHO)"].append(nrg + qrrho_dG) energies["G(Quasi-Harmonic)"].append(nrg + qharm_dG) s = "" for nrg_type in energies: energies_arr = np.array(energies[nrg_type]) energies_arr *= UNIT.HART_TO_KCAL if args.verbose and nrg_type == "E": s += "\t".join(["B1", "B2", "B3", "B4", "B5", "L", "file"]) s += "\n" for f, sub in zip(args.infiles, subs): data = sub.sterimol( radii=args.radii, old_L=args.old_L, ) s += "\t".join([ "%.2f" % data[x] for x in ["B1", "B2", "B3", "B4", "B5", "L"] ]) s += "\t%s\n" % f s += "weighted using %s:\n" % nrg_type data = Substituent.weighted_sterimol( subs, energies_arr, args.temperature, radii=args.radii, old_L=args.old_L, ) if args.verbose: coeff = boltzmann_coefficients(energies_arr, args.temperature) coeff /= sum(coeff) coeff *= 100 for f, c, e in zip(args.infiles, coeff, energies_arr): s += "%s %.1f%% (%.1f kcal/mol)\n" % (f, c, e - min(energies_arr)) s += "\t".join(["B1", "B2", "B3", "B4", "B5", "L"]) s += "\n" s += "\t".join( ["%.2f" % data[x] for x in ["B1", "B2", "B3", "B4", "B5", "L"]]) s += "\n" s += "\n" if not args.outfile: print(s) else: with open(args.outfile, "w") as f: f.write(s)
def main(argv): sterimol_parser = argparse.ArgumentParser( description="calculate B1-B5, and L sterimol parameters for substituents - see Verloop, A. and Tipker, J. (1976), Use of linear free energy related and other parameters in the study of fungicidal selectivity. Pestic. Sci., 7: 379-390.", formatter_class=argparse.RawTextHelpFormatter ) sterimol_parser.add_argument( "infile", metavar="input file", type=str, nargs="*", default=[sys.stdin], help="a coordinate file" ) sterimol_parser.add_argument( "-if", "--input-format", type=str, default=None, choices=read_types, dest="input_format", help="file format of input\nxyz is assumed if input is stdin" ) sterimol_parser.add_argument( "-s", "--substituent-atom", type=str, required=True, dest="targets", help="substituent atom\n" + "1-indexed position of the starting position of the\n" + "substituent of which you are calculating sterimol\nparameters" ) sterimol_parser.add_argument( "-a", "--attached-to", type=str, required=True, dest="avoid", help="non-substituent atom\n" + "1-indexed position of the starting position of the atom\n" + "connected to the substituent of which you are calculating\n" + "sterimol parameters" ) sterimol_parser.add_argument( "-r", "--radii", type=str, default="bondi", choices=["bondi", "umn"], dest="radii", help="VDW radii to use in calculation\n" + "umn: main group vdw radii from J. Phys. Chem. A 2009, 113, 19, 5806–5812\n" + " (DOI: 10.1021/jp8111556)\n" + " transition metals are crystal radii from Batsanov, S.S. Van der Waals\n" + " Radii of Elements. Inorganic Materials 37, 871–885 (2001).\n" + " (DOI: 10.1023/A:1011625728803)\n" + "bondi: radii from J. Phys. Chem. 1964, 68, 3, 441–451 (DOI: 10.1021/j100785a001)\n" + "Default: bondi" ) sterimol_parser.add_argument( "-l", "--old-l", action="store_true", required=False, dest="old_L", help="approximate FORTRAN Sterimol method for determining L\n" "This is 0.4 + the ideal bond length for a target-H bond\n" "Default: L value is from VDW radii of target atom to outer\n" "VDW radii of atoms projected onto L-axis" ) sterimol_parser.add_argument( "-al", "--at-L", default=[None], dest="L_value", type=lambda x: [float(v) for v in x.split(",")], help="get widths at specific L values (comma-separated)\n" "Default: use the entire ligand", ) sterimol_parser.add_argument( "-v", "--vector", action="store_true", required=False, dest="vector", help="print Chimera/ChimeraX bild file for vectors instead of parameter values" ) sterimol_parser.add_argument( "-o", "--output", type=str, default=False, required=False, metavar="output destination", dest="outfile", help="output destination\n" + "Default: stdout" ) args = sterimol_parser.parse_args(args=argv) s = "" if not args.vector: s += "B1\tB2\tB3\tB4\tB5\tL\tfile\n" for infile in glob_files(args.infile, parser=sterimol_parser): if isinstance(infile, str): if args.input_format is not None: f = FileReader((infile, args.input_format, infile)) else: f = FileReader(infile) else: if args.input_format is not None: f = FileReader(("from stdin", args.input_format, infile)) else: f = FileReader(("from stdin", "xyz", infile)) geom = Geometry(f) target = args.targets avoid = args.avoid end = geom.find(avoid)[0] frag = geom.get_fragment(target, stop=end) sub = Substituent(frag, end=end, detect=False) for val in args.L_value: data = sub.sterimol( return_vector=args.vector, radii=args.radii, old_L=args.old_L, at_L=val, ) if args.vector: for key, color in zip( ["B1", "B2", "B3", "B4", "B5", "L"], ["black", "green", "purple", "orange", "red", "blue"] ): start, end = data[key] s += ".color %s\n" % color s += ".note Sterimol %s\n" % key s += ".arrow %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n" % (*start, *end) else: s += "%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%s\n" % ( data["B1"], data["B2"], data["B3"], data["B4"], data["B5"], data["L"], infile, ) if not args.outfile: print(s) else: with open(args.outfile, "w") as f: f.write(s)