In [ ]:
import numpy as np
import matplotlib.pyplot as plt
In [ ]:
# These are perfect crystal coordinates for the nodes
Q = np.array([
[ 9.985, 17.32050808, 16.58],
[ -0.015, 34.6410162 , 16.58],
[ 29.970, 17.32050808, 16.58],
[ 9.985, 17.32050808, 33.16],
[ -0.015, 34.6410162 , 33.16],
[ 29.970, 17.32050808, 33.16],
])
In [ ]:
def get_transmat(P, Q):
def remove_com(P):
old_com = np.mean(P, axis=0)
newP = P - old_com
return newP, old_com
# get rotation vector from singular value decomposition (SVD)
def kabsch(P0, Q0):
A = np.dot(P0.transpose(), Q0)
u,s,v = np.linalg.svd(A) # a = U S V.H ... v==V.H, u==U
U = u
VT = v
V = VT.transpose()
UT = U.transpose()
d = np.sign(np.linalg.det(np.dot(V, UT)))
dmat = np.diag((1, 1, d))
rotmat = np.dot(V, np.dot(dmat, UT))
return rotmat
# remove COM
Q0, Qcom = remove_com(Q)
P0, Pcom = remove_com(P)
# get trans vector to go from P to Q
trans = Qcom-Pcom
rotmat = kabsch(P0, Q0)
# convert to 4x4 matrix
transmat = np.insert(rotmat, 3, trans, axis=1)
transmat = np.insert(transmat, 3, [0,0,0,1], axis=0)
return transmat
In [ ]:
def read_dumpfile(dumpfile):
with open(dumpfile, 'r') as fin:
data = {}
for line in fin:
if line[0]!='#':
line_chunks=line.split()
if len(line_chunks)==2:
timestep, N = map(int, line_chunks)
data[timestep] = []
if len(line_chunks)==4:
serial, x,y,z = map(float, line_chunks)
ind = int(serial) - 1
data[timestep].append([x,y,z])
return data
def rotate(xyz, transmat):
xyz1 = np.append(xyz, np.ones((len(xyz),1)), axis=1).transpose()
newxyz = np.dot(transmat, xyz1).transpose()
return newxyz[:,:-1]
node_dumpfile = '/home/vargaslo/ws/_tmp_check_system/sarin/40/MDSim_298K/4_my_nodes.dump'
nodes = read_dumpfile(node_dumpfile)
mlc_dumpfile = '/home/vargaslo/ws/_tmp_check_system/sarin/40/MDSim_298K/4_my.dump'
mlc = read_dumpfile(mlc_dumpfile)
nodes_transmat = {}
for k,v in (nodes.iteritems()):
P = np.array(v)
transmat = get_transmat(P, Q)
nodes_transmat[k] = transmat
dump = {}
for k,v in (mlc.iteritems()):
xyz = np.array(v)
transmat = nodes_transmat[k]
xyz_ = rotate(xyz, transmat)
dump[k] = xyz_
In [ ]:
def write_new_xyz(outfile):
with open(outfile, 'w') as fout:
for k in sorted(dump.iterkeys()):
v = dump[k]
N = len(v)
fout.write('{} {}\n'.format(k, N))
for ind, xyz in enumerate(v):
serial = ind+1
x,y,z = xyz
fout.write('{} {:.6f} {:.6f} {:.6f}\n'.format(serial, x, y ,z))
return
write_new_xyz(mlc_dumpfile+'.mod')