def calc_hbonds(): # variables A = [] D = [] hbonds = [] d_crit = 3.5 a_crit = 30.0 for atom in mybgf.a: if selection: if "O" in atom.ffType and eval(selection): A.append(atom) if "O" in atom.ffType and eval(selection): D.append(atom) else: if "O" in atom.ffType: A.append(atom) if "O" in atom.ffType: D.append(atom) if not len(A) or not len(D): nu.die( "There are no atoms which can make H_bond (O atoms so far)!" ) # calculate hbonds for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, pbc=mytrj.pbc[t]) for ano in neigh_anos: a_atom = mybgf.getAtom(ano) h = bt.is_hbonded2(mybgf, d_atom, a_atom) # returns hbonded H coord if len(h) != 0: a = np.array([a_atom.x, a_atom.y, a_atom.z]) dist = nu.pbc_dist(a, d, mytrj.pbc[t]) u = h - d v = a - d theta = np.dot(u, v) / norm(u) / norm(v) theta = np.degrees(arccos(theta)) hbonds.append( [d_atom.aNo, a_atom.aNo, d, a, dist, theta]) return hbonds
def calc_hbonds(): # variables A = [] D = [] hbond_angles = [] d_crit = 3.5 a_crit = 30.0 for atom in mybgf.a: if selection: if "O" in atom.ffType and eval(selection): A.append(atom) if "O" in atom.ffType and eval(selection): D.append(atom) else: if "O" in atom.ffType: A.append(atom) if "O" in atom.ffType: D.append(atom) if not len(A) or not len(D): nu.die( "There are no atoms which can make H_bond (O atoms so far)!" ) # calculate hbonds for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, k=6) neigh_hbonded_coord = [] for ano in neigh_anos: a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord if bt.is_hbonded(mybgf, d_atom, a_atom): neigh_hbonded_coord.append(a) for i, j in itertools.combinations(neigh_hbonded_coord, 2): angle = nu.angle(i, d, j, radians=False) hbond_angles.append(angle) return hbond_angles
def calc_hbonds(): hbonds = [] d_crit = 3.6 if selection: for atom in mybgf.a: if "O" in atom.ffType and eval(selection): A.append(atom) if "O" in atom.ffType and eval(selection): D.append(atom) # calculate hbonds for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, pbc=mytrj.pbc[t], k=6) for ano in neigh_anos: a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord dist = nu.pbc_dist(a, d, mytrj.pbc[t]) if dist > 2.0: for ano in d_atom.CONECT: h_atom = mybgf.getAtom(ano) h = np.array([h_atom.x, h_atom.y, h_atom.z]) u = h - d v = a - d theta = np.dot(u, v) / norm(u) / norm(v) #theta = np.degrees(arccos(theta)) if -0.17364817766693034885171662676931 < theta < 1.0: hbonds.append([dist, np.degrees(theta)]) return hbonds
def calc_hbonds(mybgf, selection=""): # variables A = [] D = [] hbonds = [] d_crit = 3.5 a_crit = 30.0 for atom in mybgf.a: if selection: if "O" in atom.ffType and eval(selection): A.append(atom) if "O" in atom.ffType and eval(selection): D.append(atom) else: if "O" in atom.ffType: A.append(atom) if "O" in atom.ffType: D.append(atom) if not len(A) or not len(D): nu.die("There are no atoms which can make H_bond (O atoms so far)!") # calculate hbonds for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, pbc=mytrj.pbc[t], k=6) donors = [d_atom.aNo] + d_atom.CONECT for ano in neigh_anos: a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord acceptors = [a_atom.aNo] + a_atom.CONECT for ano in d_atom.CONECT: h_atom = mybgf.getAtom(ano) h = np.array([h_atom.x, h_atom.y, h_atom.z]) u = h - d v = a - d theta = np.dot(u, v) / norm(u) / norm(v) theta = np.degrees(arccos(theta)) if theta < a_crit: # HBond exists dist = nu.pbc_dist(a, d, mytrj.pbc[t]) dist_ah = nu.pbc_dist(d, h, mytrj.pbc[t]) # E_vdw sigma_r = O_sigma / dist sigma_r_6 = sigma_r**6 sigma_r_12 = sigma_r**12 E_vdw = 4.0 * O_epsilon * (sigma_r_12 - sigma_r_6) # E_vdw in kcal/mol # E_coul E_coul = 0.0 for i, j in itertools.product(donors, acceptors): atom1 = mybgf.getAtom(i) atom2 = mybgf.getAtom(j) a1 = [atom1.x, atom1.y, atom1.z] a2 = [atom2.x, atom2.y, atom2.z] dist_ij = nu.pbc_dist(a1, a2, mytrj.pbc[t]) E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij # E_coul in kcal/mol # E_hbond E_hbond = E_coul + E_vdw # E_hbond = E_vdw + E_coul # update for v4 # angle between H-O-H plane and O..O vector H1 = mybgf.getAtom(d_atom.CONECT[0]) h1 = [H1.x, H1.y, H1.z] # H1 H2 = mybgf.getAtom(d_atom.CONECT[1]) h2 = [H2.x, H2.y, H2.z] # H2 p = d - h1 q = d - h2 n = np.cross(p, q) # normal vector of the H1-O-H2 plane m = a - d # O..O vector alpha = np.dot(n, m) / norm(n) / norm(m) alpha = np.degrees(arcsin( alpha)) # angle between H-O-H plane and O..O vector hbonds.append([ d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond], dist_ah, alpha ]) # v4 return hbonds
def hbonds(mybgf, selection = ""): ''' This function calculates Hydrogen bonds(hbonds) between O(donor) and O(acceptor), especially for water molecules. Input: - bgf.BgfFile mybgf - string selection: a region to search donor and acceptor atoms in mybgf Output: - int n_sel_atoms: number of hbond-able atoms in the selection region - list hbonds: self-descriptive ''' # variables pbc = mybgf.CRYSTX[:3] d_crit = 3.5; a_crit = 30.0 # Chandler's criteria if selection: A = [atom for atom in mybgf.a if "O" in atom.ffType and eval(selection)] D = [atom for atom in mybgf.a if "O" in atom.ffType and eval(selection)] else: A = [atom for atom in mybgf.a if "O" in atom.ffType] D = [atom for atom in mybgf.a if "O" in atom.ffType] if not len(A) or not len(D): nu.warn("There are no atoms which can make hbonds (O atoms so far)!") return # calculate hbonds hbonds = []; for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, pbc=pbc, k=7) donors = [d_atom.aNo] + d_atom.CONECT for ano in neigh_anos: a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord acceptors = [a_atom.aNo] + a_atom.CONECT for ano in d_atom.CONECT: h_atom = mybgf.getAtom(ano) h = np.array([h_atom.x, h_atom.y, h_atom.z]) u = h - d; v = a - d; theta = np.dot(u, v) / norm(u) / norm(v); theta = np.degrees(arccos(theta)) if theta < a_crit: # HBond exists dist = nu.pbc_dist(a, d, pbc) dist_ah = nu.pbc_dist(d, h, pbc) # E_vdw sigma_r = O_sigma / dist; sigma_r_6 = sigma_r**6; sigma_r_12 = sigma_r**12 E_vdw = 4.0 * O_epsilon * (sigma_r_12 - sigma_r_6); # E_vdw in kcal/mol # E_coul E_coul = 0.0 for i, j in itertools.product(donors, acceptors): atom1 = mybgf.getAtom(i) atom2 = mybgf.getAtom(j) a1 = [atom1.x, atom1.y, atom1.z] a2 = [atom2.x, atom2.y, atom2.z] dist_ij = nu.pbc_dist(a1, a2, pbc) E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij # E_coul in kcal/mol # E_hbond E_hbond = E_coul + E_vdw # E_hbond = E_vdw + E_coul # update for v4 # angle between H-O-H plane and O..O vector #H1 = mybgf.getAtom(d_atom.CONECT[0]); h1 = [H1.x, H1.y, H1.z] # H1 #H2 = mybgf.getAtom(d_atom.CONECT[1]); h2 = [H2.x, H2.y, H2.z] # H2 #p = d - h1; q = d - h2; n = np.cross(p, q) # normal vector of the H1-O-H2 plane #m = a - d; # O..O vector #alpha = np.dot(n, m) / norm(n) / norm(m); alpha = np.degrees(arcsin(alpha)) # angle between H-O-H plane and O..O vector #hbonds.append([d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond], dist_ah, alpha]) # v4 hbonds.append([d_atom.aNo, a_atom.aNo, dist, theta, E_hbond]) # v5 return hbonds
def calc_hbonds(): # variables A = [] D = [] hbonds = [] d_crit = 3.5 a_crit = 30.0 for atom in mybgf.a: if selection: if "O" in atom.ffType and eval(selection): A.append(atom) if "O" in atom.ffType and eval(selection): D.append(atom) else: if "O" in atom.ffType: A.append(atom) if "O" in atom.ffType: D.append(atom) if not len(A) or not len(D): nu.die( "There are no atoms which can make H_bond (O atoms so far)!" ) # calculate hbonds for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, pbc=mytrj.pbc[t], k=6) donors = [d_atom.aNo] + d_atom.CONECT for ano in neigh_anos: a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord acceptors = [a_atom.aNo] + a_atom.CONECT for ano in d_atom.CONECT: h_atom = mybgf.getAtom(ano) h = np.array([h_atom.x, h_atom.y, h_atom.z]) u = h - d v = a - d theta = np.dot(u, v) / norm(u) / norm(v) theta = np.degrees(arccos(theta)) if theta < a_crit: dist = nu.pbc_dist(a, d, mytrj.pbc[t]) dist_dh = nu.pbc_dist(d, h, mytrj.pbc[t]) # E_vdw sigma_r = O_sigma / dist sigma_r_6 = sigma_r**6 sigma_r_12 = sigma_r**12 E_vdw = 4.0 * O_epsilon * (sigma_r_12 - sigma_r_6) # Evdw in kcal/mol # E_coul E_coul = 0.0 for i, j in itertools.product(donors, acceptors): atom1 = mybgf.getAtom(i) atom2 = mybgf.getAtom(j) a1 = [atom1.x, atom1.y, atom1.z] a2 = [atom2.x, atom2.y, atom2.z] dist_ij = nu.pbc_dist(a1, a2, mytrj.pbc[t]) E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij #E_coul /= 2.0 E_hbond = E_coul + E_vdw # E_hbond = E_vdw + E_coul #print("e_coul: %f, e_coul2: %f, E_coul: %f, E_vdw: %f, E_hbond: %f, O-O dist: %f, O-H dist: %f" % (e_coul, e_coul2, E_coul, E_vdw, E_hbond, dist, dist_a_dh)) #print("E_coul: %f, E_vdw: %f, E_hbond: %f, O-O dist: %f" % (E_coul, E_vdw, E_hbond, dist)) #hbonds.append([d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond]]) hbonds.append([ d_atom.aNo, a_atom.aNo, d, a, dist, theta, [E_coul, E_vdw, E_hbond], dist_dh ]) return hbonds
def hbonds(mybgf, selection = ""): ''' This function calculates Hydrogen bonds(hbonds) between O(donor) and O(acceptor), especially for water molecules. Input: - bgf.BgfFile mybgf - string selection: a region to search donor and acceptor atoms in mybgf Output: - int n_sel_atoms: number of hbond-able atoms in the selection region - list hbonds: self-descriptive ''' # variables pbc = mybgf.CRYSTX[:3] d_crit = 3.5; a_crit = 30.0 # Chandler's criteria if selection: A = [atom for atom in mybgf.a if "O" in atom.ffType and eval(selection)] D = [atom for atom in mybgf.a if "O" in atom.ffType and eval(selection)] else: A = [atom for atom in mybgf.a if "O" in atom.ffType] D = [atom for atom in mybgf.a if "O" in atom.ffType] if not len(A) or not len(D): nu.warn("There are no atoms which can make hbonds (O atoms so far)!") return # calculate hbonds hbonds = []; for d_atom in D: d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord neigh_anos = bt.get_neighbors_aNo(A, d, r=d_crit, pbc=pbc, k=5) donors = [d_atom.aNo] + d_atom.CONECT for ano in neigh_anos: a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord acceptors = [a_atom.aNo] + a_atom.CONECT for ano in d_atom.CONECT: h_atom = mybgf.getAtom(ano) h = np.array([h_atom.x, h_atom.y, h_atom.z]) u = h - d; v = a - d; theta = np.dot(u, v) / norm(u) / norm(v); theta = np.degrees(arccos(theta)) if theta < a_crit: # HBond exists # calculate pair energy as Hbond energy dist = nu.pbc_dist(a, d, pbc) dist_ah = nu.pbc_dist(d, h, pbc) # E_vdw sigma_r = O_sigma / dist; sigma_r_6 = sigma_r**6; sigma_r_12 = sigma_r**12 E_vdw = 4.0 * O_epsilon * (sigma_r_12 - sigma_r_6); # E_vdw in kcal/mol # E_coul E_coul = 0.0 for i, j in itertools.product(donors, acceptors): atom1 = mybgf.getAtom(i) atom2 = mybgf.getAtom(j) a1 = [atom1.x, atom1.y, atom1.z] a2 = [atom2.x, atom2.y, atom2.z] dist_ij = nu.pbc_dist(a1, a2, pbc) E_coul += 332.06371 * atom1.charge * atom2.charge / dist_ij # E_coul in kcal/mol # E_hbond E_hbond = E_coul + E_vdw # E_hbond = E_vdw + E_coul ''' # calculate dreiding style hbond energy: http://lammps.sandia.gov/doc/pair_hbond_dreiding.html # REMARK: tested on bulk water, ice, and confined water between MoS2 but achieved suspicious values: # 6.0 $\AA$ maximum: -7.925 kcal/mol # 8.0 $\AA$ maximum: -7.875 kcal/mol # 11.0 $\AA$ maximum: -8.025 kcal/mol # ice maximum: -8.325 kcal/mol # water maximum: -7.775 kcal/mol sigma = 2.75 # in A epsilon = 9.0 # in kcal/mol u = d - h; v = a - h; cos_theta = np.dot(u, v) / norm(u) / norm(v); #cos_theta = np.cos(theta) sigma_r = sigma / dist; sigma_r_2 = sigma_r**2; sigma_r_12 = sigma_r_2**6; sigma_r_10 = sigma_r_2**5 E_hbond = epsilon * ( 5 * sigma_r_12 - 6 * sigma_r_10 ) * cos_theta**4 ''' hbonds.append([d_atom.aNo, a_atom.aNo, dist, theta, E_hbond]) # v5 return hbonds
def hbonds(mybgf, selection=""): ''' This function calculates Hydrogen bonds(hbonds) between O(donor) and O(acceptor), especially for water molecules. Input: - bgf.BgfFile mybgf - string selection: a region to search donor and acceptor atoms in mybgf Output: - int n_sel_atoms: number of hbond-able atoms in the selection region - list hbonds: self-descriptive ''' # variables pbc = mybgf.CRYSTX[:3] d_crit = 3.5 a_crit = 30.0 # Chandler's criteria if selection: D = [ atom for atom in mybgf.a if ("O" in atom.ffType or "N" in atom.ffType or "F" in atom.ffType or "S" in atom.ffType) and eval(selection) ] A = [ atom for atom in mybgf.a if ("O" in atom.ffType or "N" in atom.ffType or "F" in atom.ffType or "S" in atom.ffType) and eval(selection) ] else: D = [ atom for atom in mybgf.a if ("O" in atom.ffType or "N" in atom.ffType or "F" in atom.ffType or "S" in atom.ffType) ] A = [ atom for atom in mybgf.a if ("O" in atom.ffType or "N" in atom.ffType or "F" in atom.ffType or "S" in atom.ffType) ] if not len(A) or not len(D): nu.warn("There are no atoms which can make hbonds!") return # calculate hbonds hbonds = [] for d_atom in tqdm.tqdm(D, ncols=120, desc='Iterating'): d = np.array([d_atom.x, d_atom.y, d_atom.z]) # donor coord donors_H = [ ano for ano in d_atom.CONECT if "H" in mybgf.getAtom(ano).ffType ] neigh_anos, distances = bt.get_neighbors_aNo( A, d, r=d_crit, pbc=pbc, k=5, return_distance=True ) # atoms within d_crit of donor will be acceptor candidates for index, ano in enumerate(neigh_anos): a_atom = mybgf.getAtom(ano) a = np.array([a_atom.x, a_atom.y, a_atom.z]) # acceptor coord for ano in donors_H: h_atom = mybgf.getAtom(ano) h = np.array([h_atom.x, h_atom.y, h_atom.z]) u = h - d v = a - d theta = np.dot(u, v) / norm(u) / norm(v) theta = np.degrees(arccos(theta)) if theta < a_crit: # HBond exists #dist = nu.pbc_dist(a, d, pbc) #dist = distances[0][index] #dist_ah = nu.pbc_dist(d, h, pbc) hbonds.append([ d_atom.aNo, a_atom.aNo, distances[0][index + 1], theta ]) # v5.2 return hbonds