I have the following code that gets some input files and calculates some values. The issue is, the code is working for Mus_df
values 1,2,3,4,6,12
but not 5,7,8,9,10,11
. The error indicates that CCvecs
is None-type. Can you help me?
import numpy as np
import matplotlib.pyplot as plt
import math
import itertools
from math import sqrt, pi, sin, cos, asin, acos, exp
import pandas as pd
cmap1 = plt.get_cmap('tab10')
ang2au = 1.8897259886
eV2au = 3.6749322175655e-2
debye2au = 0.393456
def readParams(NpAndMol_xyz_path, Mol_xyz_path, Np_Mu_path, Nmol, t=0.0):
# read NP+pyr and pyr XYZ into pd df
# read TDMs of Ag174 NP system, select electronic states? based on cutoff for f..???
NpAndMol_xyz_tmp = pd.read_csv(
NpAndMol_xyz_path, sep='\s+', header=None, skiprows=2)
Mol_xyz_df = pd.read_csv(Mol_xyz_path, sep='\s+', header=None, skiprows=2)
Mus_tmp_df = pd.read_csv(Np_Mu_path, sep='\s+', header=None,
skiprows=2, names=['no', 'E', 'f', 'x', 'y', 'z'])
# parse NpAndMol_xyz
NpAndMol_xyz_df = NpAndMol_xyz_tmp.drop(
NpAndMol_xyz_tmp[NpAndMol_xyz_tmp[0] == 'Ag'].index)
NP_xyz = NpAndMol_xyz_tmp[NpAndMol_xyz_tmp[0] == 'Ag'].to_numpy()
MolsOnNP_xyz = np.array_split(NpAndMol_xyz_df, Nmol)
# get only xyz of TDMs
# threshold t for oscillator strength f optional
Mus_tmp_dfRed = Mus_tmp_df.loc[(Mus_tmp_df['f'] >= t)]
Mus_df = Mus_tmp_dfRed.drop(Mus_tmp_dfRed.columns[[1, 2]], axis=1)
elStateEs = Mus_tmp_dfRed['E'].tolist()
return NP_xyz, MolsOnNP_xyz, Mol_xyz_df, Mus_df, elStateEs
def getVecs(MolsOnNP_xyz, Mol_xyz_df):
Nmol = len(MolsOnNP_xyz)
CMOnNPvecs = []
NNvecs = []
RotMats = []
CCvecs = []
# get CoM of pyr molecules, CM(NP)=(0,0,0)
Mol_xyzMat = Mol_xyz_df.drop(Mol_xyz_df.columns[[0]], axis=1).to_numpy()
NNOrig = Mol_xyzMat[1, :] - Mol_xyzMat[3, :]
#testvecOrig = Mol_xyzMat[2, :] - Mol_xyzMat[5, :]
for i in range(Nmol):
MolOnNP_xyz = MolsOnNP_xyz[i]
MolOnNP_xyzMat = MolsOnNP_xyz[i].drop(
MolOnNP_xyz.columns[[0]], axis=1).to_numpy()
# compute NN vector
NsXYZ = MolOnNP_xyz[MolOnNP_xyz[0] == 'N']
NsXYZ_mat = NsXYZ.drop(NsXYZ.columns[[0]], axis=1).to_numpy()
NNOnNPvec = NsXYZ_mat[0, :] - NsXYZ_mat[1, :]
NNOnNPvec_normal = NNOnNPvec * 1/np.linalg.norm(NNOnNPvec)
CMOnNPvecTmp = (MolOnNP_xyzMat[2, :] + MolOnNP_xyzMat[5, :])*0.5
# compute CC vec parallel to TDM vector
# CCvec = MolOnNP_xyzMat[3, :] - MolOnNP_xyzMat[1, :]
CCvec = findCCVec(MolOnNP_xyz,NNOnNPvec)
# print(np.linalg.norm(CCvec))
CCvecs.append(CCvec)
#print(len(CCvecs))
NNvecs.append(NNOnNPvec)
CMOnNPvecs.append(CMOnNPvecTmp)
return CCvecs, CMOnNPvecs, NNvecs
def alignAntiParallelVec(u, v):
if np.dot(u, v) < 0:
print('antiparallel')
return -v
elif np.dot(u, v) > 0:
print('parallel')
return v
elif np.dot(u, v) == 0:
print('vectors are orthogonal')
return v
def getCoupls(CCvecs, CMOnNPvecs, Mus_df, mydist=None, printOut=False, unit='au', multiplier=1.0):
#muMolBf = np.array([0.00000, 0.78457, 0.0000])
muMolBf = np.array([0.00000, -0.8915, 0.0000])
muMolBfAbs = np.linalg.norm(muMolBf)
musNP = Mus_df[['x', 'y', 'z']].to_numpy()
print('take mu vectors from input:')
print('\n###Cluster mu (modulus) in au###')
print([np.linalg.norm(v) for v in musNP])
print('\n###Molecule mu (modulus) in au###')
print(muMolBfAbs)
elStateInds = Mus_df['no'].to_list()
Nmol = len(CCvecs)
print(Nmol)
Nel = len(Mus_df.index)
gcoupls = np.zeros((Nmol, Nel))
uvec_out = []
for i in range(Nmol):
uvec = 1/np.linalg.norm(CMOnNPvecs[i]*ang2au) * CMOnNPvecs[i]*ang2au
print(CCvecs[i])
muMolVec = CCvecs[i]*ang2au
#muMolVec = alignAntiParallelVec(uvec, CCvecs[i])
muMolSf = muMolBfAbs/np.linalg.norm(muMolVec) * muMolVec
# uvec_out.append(muMolVec)
if mydist == None:
dist = np.linalg.norm(CMOnNPvecs[i])
dist_au = dist*ang2au
print('###Calculate dip-dip distance from coordinate file###')
print('dist = {} å = {} au'.format(dist, dist_au))
else:
print('###Use custom dist###')
dist = mydist
dist_au = dist*ang2au
for j in range(len(musNP)):
gcoupls[i, j] = 1/dist_au**3 * (np.dot(musNP[j], muMolSf) -
3*np.dot(musNP[j], uvec)*np.dot(muMolSf, uvec))
# g_ij matrix, i=mol index, j=el state index
if printOut:
print('\n\n###coupling matrix g_ij; i=mol, j=el state###')
for i in range(Nmol):
for j in range(Nel):
if unit == 'ev':
print('g_{}_{} = {:.5f}, ev'.format(
i+1, j+1, gcoupls[i, j]/eV2au*multiplier))
elif unit == 'au':
print('g_{}_{} = {:.5f}'.format(
i+1, j+1, gcoupls[i, j]*multiplier))
else:
print('unknown unit!')
print('\n###metal mus###')
for i in range(Nel):
# read and print maximum TDM component
muInd = np.argmax(np.abs(musNP[i]))
print("mu_1_{} = {:.4f}".format(i+1, musNP[i][muInd]))
return gcoupls
def findCCVec(molXYZ_df,NNvec):
CsXYZ = molXYZ_df[molXYZ_df[0] == 'C']
CsXYZ_Mat = CsXYZ.drop(CsXYZ.columns[[0]], axis=1).to_numpy()
Nmols = len(CsXYZ_Mat[:])
Inds = range(Nmols)
iters = itertools.combinations(Inds,2)
failCount = 0
for iter in iters:
CCtestVec = CsXYZ_Mat[iter[0]] - CsXYZ_Mat[iter[1]]
projCCNN = CCtestVec.dot(NNvec)
if np.abs(projCCNN) <= 1e-7:
return CCtestVec
else:
failCount += 1
if failCount == Nmols:
print("No suitable CC axis found")
return None
def printEs(elist, shift=0.0):
print("omega_0 = 0.0000, ev")
for i, e in enumerate(elist):
print("omega_{} = {:.4f}, ev".format(i+2, e+shift))
def printCouplOp(MolDofs, MolTags, NElStates, elDof):
for molTag, molDof in zip(MolTags, MolDofs):
for j in range(NElStates):
print("g_{}_{} |{} F |{} S1&{}".format(
molTag, j+1, molDof, elDof, j+2))
for j in range(int(NElStates/2)):
print("omega_1 |{} S{}&{}".format(elDof, 2*j+2, 2*j+2))
print("omega_2 |{} S{}&{}".format(elDof, 2*j+3, 2*j+3))
for j in range(int(NElStates/2)):
print("omega_1 |{} S{}&{}".format(elDof, 2*j+2, 2*j+2))
print("omega_2 |{} S{}&{}".format(elDof, 2*j+3, 2*j+3))
def visVecs(cms, vecs, l=0.1, angle=0, pts = None, plotPts = False):
ax = plt.figure().add_subplot(projection='3d')
ax.view_init(30, angle)
for i in range(len(cms)):
ax.scatter(cms[i,0].tolist(),cms[i,1].tolist(),cms[i,2].tolist(),color=cmap1(i),marker='*',s=50)
ax.quiver(cms[:,0],cms[:,1], cms[:,2], vecs[:,0], vecs[:,1], vecs[:,2], length=l, normalize=True, color='black')
if plotPts:
#print(pts[:,1])
#print(pts[:,2])
#print(pts[:,3])
#ax.scatter(pts[:,1],pts[:,2],pts[:,3])
ax.scatter(pts[:,1].tolist(),pts[:,2].tolist(),pts[:,3].tolist())
plt.show()
#visVecs(np.array(CMOnNPvecs), np.array(CCvecs), l=1, angle=40)
Np_xyz , MolsOnNP_xyz, Mol_xyz_df, Mus_df, elStateEs = readParams(
'Ag147-py12.xyz', 'Pyr_xyz.dat', 'Ag147_mu_sym_e1u_xy.dat',8 , t=0.000)
CCvecs, CMOnNPvecs, NNvecs = getVecs(MolsOnNP_xyz, Mol_xyz_df)
coupls = getCoupls(CCvecs, CMOnNPvecs, Mus_df, mydist = None , printOut = True, unit = 'ev', multiplier=1.0)
The Mus_df
value is prompted in this line Np_xyz , MolsOnNP_xyz, Mol_xyz_df, Mus_df, elStateEs = readParams( 'Ag147-py12.xyz', 'Pyr_xyz.dat', 'Ag147_mu_sym_e1u_xy.dat',8 , t=0.000)
, which is set to be 8
in this case.
I tried debugging getVecs
, getCoupls
, findCCvec
functions but had no luck. Can you please help me?