-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrmsd.py
More file actions
119 lines (92 loc) · 3.07 KB
/
rmsd.py
File metadata and controls
119 lines (92 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/python
from __future__ import print_function
import sys
import subprocess
import os
from itertools import *
import math as M
import numpy as np
import matplotlib.pyplot as plt
#Defining the arguments or file input
if len(sys.argv) == 2:
qcin = sys.argv[1]
qc_base = qcin.split('.')[0]
else:
print ('Incorrect filetype')
sys.exit()
#Defining important functions
def get_contents(filename):
"""
Function to read the content of a file
"""
with open(filename, 'r') as f:
contents = f.readlines()
return contents
def All_Coordinates(qcin):
"""
A comprehensive function to pull out XYZ coordinates from an XYZ trajectory file
"""
qc_input = get_contents(qcin)
temp =[]
Coords =[]
for line in qc_input:
data = line.split()
if len(data) >= 4:
temp.append([float(i) for i in data[1:4]])
else:
if len(temp) !=0:
Coords.append(temp)
temp =[]
return Coords
def Align_to_Ref(Ref, Coords):
"""
Function that aligns a coordinate to a reference in order to minimise the RMSD
"""
#find the center of each coordinates
center_0 = np.mean(Ref, axis=0)
center_1 = np.mean(Coords, axis=0)
#Center each coordinate
centered_ref = Ref - center_0
coord_to_com = Coords - center_1
# Find the rotation that will align coord to Ref
#Computation of the covariance matrix
M = np.dot(np.transpose(coord_to_com),centered_ref)
#M = coord_1.transpose().dot(coord_0)
#computing the SVD of the covariance matrix
U,S, V_H = np.linalg.svd(M)
#Decide whether we need to correct our rotation matrix to ensure a right-handed coordinate system
d = (np.linalg.det(U) * np.linalg.det(V_H)) < 0.0
if d:
S[-1] = -S[-1]
U[:, -1] = -U[:, -1]
#Compute rotation matrix
Rotation_Matrix = np.dot(U, V_H)
# Align the two sets of coordinates and calculate the RMSD
aligned_coords = coord_to_com.dot(Rotation_Matrix)
return aligned_coords, centered_ref
def RMSD(Ref, Coords):
"""
Function that computes the RMSD between two coordinates
"""
aligned_coords, centered_ref = Align_to_Ref(Ref, Coords)
distance = list(map(lambda i, j :np.linalg.norm(i-j)**2 ,aligned_coords, centered_ref))
rmsd = M.sqrt(sum(distance)/float(len(centered_ref)))
return rmsd
#Main part of the program
#Read trajectory coordinates
Coordinates= All_Coordinates(qcin)
#computing pairwise RMSD
rmsd= starmap(RMSD, product(Coordinates, Coordinates))
#reshaping 1D list into numpy matrix for easy density plot
distance= np.array(list(rmsd)).reshape(len(Coordinates), len(Coordinates))
#Plotting pairwise RMSD
ticks =np.arange(0, len(distance)+1, 1000)
label = np.arange(0, len(ticks), 1)
plt.imshow(distance , cmap='viridis', origin='lower')
plt.xlabel(r'Time (ps)')
plt.ylabel(r'Time (ps)')
plt.xticks(ticks, label)
plt.yticks(ticks, label)
plt.colorbar(label=r'RMSD ($\AA$)')
plt.savefig('RMSD.png',dpi=2000, bbox_inches = 'tight')
#plt.show()