def ics_get_ptorsions(ics_st, adj_list, xcc, epslin=5.0): '''epslin in degrees''' ics_pt = [] for at2, at3 in ics_st: x2 = fncs.xyz(xcc, at2) x3 = fncs.xyz(xcc, at3) bondedto2 = list(adj_list[at2]) bondedto3 = list(adj_list[at3]) bondedto2.remove(at3) bondedto3.remove(at2) if len(bondedto2) == 0: continue if len(bondedto3) == 0: continue for at1 in bondedto2: x1 = fncs.xyz(xcc, at1) for at4 in bondedto3: if at1 == at4: continue x4 = fncs.xyz(xcc, at4) # the two angles angA = fncs.rad2deg(fncs.angle(x1, x2, x3)) angB = fncs.rad2deg(fncs.angle(x2, x3, x4)) # linear? booleanA = angA < epslin or angA > 180 - epslin booleanB = angB < epslin or angB > 180 - epslin if booleanA or booleanB: continue ptorsion = (at1, at2, at3, at4) ics_pt.append(ptorsion) return ics_pt
def wilson_getBC(xcc, all_ics): numics = count_ics(all_ics) ics_st, ics_ab, ics_lb, ics_it, ics_pt = unmerge_ics(all_ics) # unit bond vectors natoms = fncs.howmanyatoms(xcc) bvecs = wilson_bvecs(xcc) # initialize matrices wilsonB = [[0.0 for row in range(numics)] for col in range(3 * natoms)] wilsonB, wilsonC = [], [] # B and C: stretchings for atoms in ics_st: row_B, matrix_C = wilson_stretch(bvecs, atoms, natoms) wilsonB += row_B wilsonC += matrix_C # B and C: angular bendings for atoms in ics_ab: row_B, matrix_C = wilson_abend(bvecs, atoms, natoms) wilsonB += row_B wilsonC += matrix_C # B and C: linear bendings for atoms in ics_lb: i, j, k = atoms r_m = np.array(fncs.xyz(xcc, i)) r_o = np.array(fncs.xyz(xcc, j)) r_n = np.array(fncs.xyz(xcc, k)) row_B, matrix_C = wilson_lbend(r_m, r_o, r_n, atoms, natoms) wilsonB += row_B wilsonC += matrix_C # B and C: torsions (proper and improper) for atoms in ics_it + ics_pt: row_B, matrix_C = wilson_torsion(bvecs, atoms, natoms) wilsonB += row_B wilsonC += matrix_C return np.matrix(wilsonB), [np.matrix(ll) for ll in wilsonC]
def distance_2fragments(frg1, frg2, xcc): min_dist = float("inf") pair = (None, None) for at1 in frg1: x1 = fncs.xyz(xcc, at1) for at2 in frg2: x2 = fncs.xyz(xcc, at2) dist = fncs.distance(x1, x2) if dist < min_dist: min_dist = dist pair = (at1, at2) return min_dist, pair
def ics_classify_bends(xcc, ic_3ats, eps_lin=5.0): ics_lb = [] ics_ab = [] thetas = {} for at1, at2, at3 in ic_3ats: x1 = fncs.xyz(xcc, at1) x2 = fncs.xyz(xcc, at2) x3 = fncs.xyz(xcc, at3) theta = abs(fncs.rad2deg(fncs.angle(x1, x2, x3))) if theta < eps_lin or theta > 180 - eps_lin: ics_lb.append((at1, at2, at3)) else: ics_ab.append((at1, at2, at3)) thetas[(at1, at2, at3)] = theta return ics_lb, ics_ab, thetas
def rst2xyz(rst, xyz, onlyhess=True, Eref=None): tpath, tcommon, drst = read_rst(rst) thelist = [(data[0], label) for (label, data) in drst.items()] thelist.sort() (ch, mtp, atonums, masses, mu) = tcommon symbols = fncs.atonums2symbols(atonums) natoms = len(symbols) string = "" for s_i, label in thelist: s_i, E_i, xms_i, gms_i, Fms_i, v0_i, v1_i, t_i = drst[label] if onlyhess and Fms_i is None: continue if Eref is not None: E_i = (E_i - Eref) * KCALMOL energy = "%+.4f kcal/mol" % E_i else: energy = "%+.6f hartree" % E_i string += " %i\n" % natoms string += " * E = %s ; s = %7.4f (%s)\n" % (energy, s_i, label) xcc_i = fncs.ms2cc_x(xms_i, masses, mu) for idx, symbol in enumerate(symbols): x, y, z = fncs.xyz(xcc_i, idx) x *= ANGSTROM y *= ANGSTROM z *= ANGSTROM string += " %2s %+10.6f %+10.6f %+10.6f\n" % (symbol, x, y, z) write_file(xyz, string)
def ics_value(xcc, ic): ''' ic = (ic_type,ic_atoms)''' if type(ic) == type("string"): ic_type, ic_atoms = string2ic(ic) else: ic_type, ic_atoms = ic if ic_type == "st": return fncs.distance(*(fncs.xyz(xcc, at) for at in ic_atoms)) if ic_type == "ab": return fncs.angle(*(fncs.xyz(xcc, at) for at in ic_atoms)) if ic_type == "lb": return fncs.angle(*(fncs.xyz(xcc, at) for at in ic_atoms)) if ic_type == "it": return fncs.dihedral(*(fncs.xyz(xcc, at) for at in ic_atoms)) if ic_type == "pt": return fncs.dihedral(*(fncs.xyz(xcc, at) for at in ic_atoms))
def wilson_bvecs(xcc): ''' This functions calculates the distance between each pair of atoms (dij) and also the unit bond vector eij = (rj - ri)/dij ''' nat = fncs.howmanyatoms(xcc) bond_vectors = {} for ii in range(nat): ri = np.array(fncs.xyz(xcc, ii)) for jj in range(ii + 1, nat): rj = np.array(fncs.xyz(xcc, jj)) eij = rj - ri dij = np.linalg.norm(eij) eij = eij / dij bond_vectors[(ii, jj)] = (eij, dij) bond_vectors[(jj, ii)] = (-eij, dij) return bond_vectors
def puckering_rjs(xvec, atoms_in_ring): ''' JACS 1975, 97:6, 1354-1358; eq (4) ''' gc = np.array(fncs.get_centroid(xvec, atoms_in_ring)) list_Rj = [] for at in atoms_in_ring: rj = np.array(fncs.xyz(xvec, at)) Rj = rj - gc list_Rj.append(Rj) return list_Rj, gc
def write_molden(filename, xcc, symbs, freqs, evecs): '''evecs NOT in mass-scaled!''' natoms = len(symbs) nfreqs = len(freqs) STRING = "[Molden Format]\n" STRING += "[FR-COORD] # Coordinates in bohr\n" for at in range(natoms): symbol = symbs[at] x, y, z = fncs.xyz(xcc, at) STRING += " %2s %+11.6f %+11.6f %+11.6f \n" % (symbol, x, y, z) if freqs not in [None, []]: STRING += "[FREQ] # Frequencies in cm^-1\n" for idx in range(nfreqs): freq = fncs.afreq2cm(freqs[idx]) STRING += " %9.4f\n" % freq if evecs not in [None, []]: STRING += "[FR-NORM-COORD] # Displacements in bohr\n" for idx in range(nfreqs): STRING += "vibration %i\n" % (idx + 1) evec = evecs[idx] for at in range(natoms): vx, vy, vz = fncs.xyz(evec, at) STRING += " %+9.3f %+9.3f %+9.3f\n" % (vx, vy, vz) write_file(filename, STRING)
def write_gtsfile(xcc, atonums, ch, mtp, E, pgroup, rotsigma, gcc, Fcc, gtsfile, freqs=None, level=""): if gcc is None: gcc = [] if Fcc is None: Fcc = [] if freqs is None: freqs = [] nat = len(atonums) str_gts = "" # Write atomic numbers and cartesian coordinates if level != "": str_gts += "# level: %s\n" % level str_gts += "# Atomic number and non-scaled cartesian coordinates [bohr]\n" str_gts += "start_cc\n" for at in range(nat): atonum = atonums[at] xx, yy, zz = fncs.xyz(xcc, at) str_gts += " %03i %+15.8E %+15.8E %+15.8E\n" % (atonum, xx, yy, zz) str_gts += "end_cc\n\n" # Write basic data str_gts += "# Charge, multiplicity, energy [hartree],\n" str_gts += "# point group and rotational symmetry number\n" str_gts += "start_basic\n" str_gts += " charge %i\n" % ch str_gts += " multiplicity %i\n" % mtp str_gts += " energy %-+16.8f # Total energy in hartree\n" % E str_gts += " pointgroup %-5s # Point group\n" % pgroup str_gts += " rotsigma %-5i # Rotational sigma\n" % rotsigma str_gts += "end_basic\n\n" # Write cartesian gradiend if len(gcc) != 0: str_gts += "# Non-scaled cartesian gradient [hartree/bohr]\n" str_gts += "start_grad\n" for at in range(nat): gxx, gyy, gzz = fncs.xyz(gcc, at) str_gts += " %+15.8E %+15.8E %+15.8E\n" % (gxx, gyy, gzz) str_gts += "end_grad\n\n" # Write force constant matrix (i.e. hessian matrix) if len(Fcc) != 0: if len(Fcc) == 3 * nat: # not in triangular form Fcc = matrix2lowt(Fcc) str_gts += "# Low triangular part of force constant (hessian) matrix [hartree/bohr^2]\n" str_gts += "# i.e.: F_11, F_21, F_22, F_13, F_23, F_33...\n" str_gts += "start_hess\n" for idx in range(0, len(Fcc), 5): line = " ".join(["%+15.8E" % Fij for Fij in Fcc[idx:idx + 5]]) str_gts += " %s\n" % line str_gts += "end_hess\n\n" # Write freqs elif len(freqs) != 0: str_gts += "start_freqs\n" for idx in range(0, len(freqs), 5): line = " ".join(["%7.2f" % (freq) for freq in freqs[idx:idx + 5]]) str_gts += " %s\n" % line str_gts += "end_freqs\n\n" # write write_file(gtsfile, str_gts)
def info_string(self,ib=0): root_mass = sum(fncs.symbols2masses(self._symbols)) string = "mol. formula : %s\n"%self._mform string += "num atoms : %i\n"%self._natoms string += "num vib dof : %i\n"%self._nvdof string += "charge : %i\n"%self._ch string += "multiplicity : %i\n"%self._mtp string += "electronic energy (V0): %.8f hartree\n"%self._V0 string += "total mass [root] : %.4f amu\n"%(root_mass *AMU) string += "total mass : %.4f amu\n"%(self._mass*AMU) if self._pgroup is not None: string += "point group : %s\n"%(self._pgroup) if self._rotsigma is not None: string += "rot sym num : %i\n"%(self._rotsigma) string += "Cartesian coordinates (Angstrom):\n" for at,symbol in enumerate(self._symbols): mass = self._masses[at]*AMU x,y,z = fncs.xyz(self._xcc,at) x *= ANGSTROM y *= ANGSTROM z *= ANGSTROM string += " %2s %+10.6f %+10.6f %+10.6f [%7.3f amu]\n"%(symbol,x,y,z,mass) #if True: try: str2 = "moments and product of inertia (au):\n" if len(self._imoms) == 1: str2 += " %+10.3E\n"%self._imoms[0] if len(self._imoms) == 3: prodinert = self._imoms[0]*self._imoms[1]*self._imoms[2] dataline = (self._imoms[0],self._imoms[1],self._imoms[2],prodinert) str2 += " %+10.3E %+10.3E %+10.3E [%10.3E]\n"%dataline string += str2 except: pass try: str2 = "vibrational frequencies [1/cm] (scaled by %.3f):\n"%self._fscal for idx in range(0,len(self._ccfreqs),6): str2 += " %s\n"%(" ".join("%8.2f"%fncs.afreq2cm(freq) \ for freq in self._ccfreqs[idx:idx+6])) if len(self._ccfreqs) != 0: string += str2 except: pass try: str2 = "individual zero-point energies [kcal/mol]:\n" for idx in range(0,len(self._cczpes),6): str2 += " %s\n"%(" ".join("%8.2f"%(zpe*KCALMOL) \ for zpe in self._cczpes[idx:idx+6])) zpe_au = self._cczpe zpe_kcal = self._cczpe * KCALMOL zpe_eV = self._cczpe * EV zpe_cm = self._cczpe * H2CM str2 += "vibrational zero-point energy (ZPE): %+14.8f hartree = \n"%zpe_au str2 += " %+14.2f kcal/mol = \n"%zpe_kcal str2 += " %+14.2f eV = \n"%zpe_eV str2 += " %+14.2f cm^-1 \n"%zpe_cm #str2 += "zero-point energy (zpe) : %+14.8f hartree = %.2f kcal/mol = %.3f eV\n"%(zpe_au,zpe_kcal,zpe_eV) str2 += "electronic energy + ZPE (V1) : %+14.8f hartree\n"%self._ccV1 if self._cczpe != 0.0: string += str2 except: pass # add blank spaces string = "\n".join([" "*ib+line for line in string.split("\n")]) return string