1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for the calculation of pseudocontact shifts."""
24
25
26 from numpy import dot, sum
27
28
30 """Calculate the ensemble average PCS, using the 3D tensor.
31
32 This function calculates the average PCS for a set of XH bond vectors from a structural ensemble, using the 3D tensorial form of the alignment tensor. The formula for this ensemble average PCS value is::
33
34 _N_
35 \ T
36 <delta_ij(theta)> = > pc . djc . mu_jc . Ai . mu_jc,
37 /__
38 c=1
39
40 where:
41 - i is the alignment tensor index,
42 - j is the index over spins,
43 - c is the index over the states or multiple structures,
44 - N is the total number of states or structures,
45 - theta is the parameter vector,
46 - djc is the PCS constant for spin j and state c,
47 - pc is the population probability or weight associated with state c (equally weighted to 1/N if weights are not provided),
48 - mu_jc is the unit vector corresponding to spin j and state c,
49 - Ai is the alignment tensor.
50
51 The PCS constant is defined as::
52
53 mu0 15kT 1
54 dj = --- ----- ---- ,
55 4pi Bo**2 r**3
56
57 where:
58 - mu0 is the permeability of free space,
59 - k is Boltzmann's constant,
60 - T is the absolute temperature,
61 - Bo is the magnetic field strength,
62 - r is the distance between the paramagnetic centre (electron spin) and the nuclear spin.
63
64
65 @param dj: The PCS constants for each structure c for spin j. This should be an array with indices corresponding to c.
66 @type dj: numpy rank-1 array
67 @param vect: The electron-nuclear unit vector matrix. The first dimension corresponds to the structural index, the second dimension is the coordinates of the unit vector. The vectors should be parallel to the vector connecting the paramagnetic centre to the nuclear spin.
68 @type vect: numpy matrix
69 @param N: The total number of structures.
70 @type N: int
71 @param A: The alignment tensor.
72 @type A: numpy rank-2 3D tensor
73 @param weights: The weights for each member of the ensemble (the last member need not be supplied).
74 @type weights: numpy rank-1 array
75 @return: The average PCS value.
76 @rtype: float
77 """
78
79
80 val = 0.0
81
82
83 if weights == None:
84 pc = 1.0 / N
85 weights = [pc] * N
86
87
88 if len(weights) < N:
89 pN = 1.0 - sum(weights, axis=0)
90 weights = weights.tolist()
91 weights.append(pN)
92
93
94 for c in range(N):
95 val = val + weights[c] * dj[c] * dot(vect[c], dot(A, vect[c]))
96
97
98 return val
99
100
102 """Calculate the ensemble average PCS gradient element for Amn, using the 3D tensor.
103
104 This function calculates the average PCS gradient for a set of electron-nuclear spin unit vectors (paramagnetic to the nuclear spin) from a structural ensemble, using the 3D tensorial form of the alignment tensor. The formula for this ensemble average PCS gradient element is::
105
106 _N_
107 ddelta_ij(theta) \ T dAi
108 ---------------- = > pc . djc . mu_jc . ---- . mu_jc,
109 dAmn /__ dAmn
110 c=1
111
112 where:
113 - i is the alignment tensor index,
114 - j is the index over spins,
115 - m, the index over the first dimension of the alignment tensor m = {x, y, z}.
116 - n, the index over the second dimension of the alignment tensor n = {x, y, z},
117 - c is the index over the states or multiple structures,
118 - theta is the parameter vector,
119 - Amn is the matrix element of the alignment tensor,
120 - djc is the PCS constant for spin j and state c,
121 - N is the total number of states or structures,
122 - pc is the population probability or weight associated with state c (equally weighted to 1/N if weights are not provided),
123 - mu_jc is the unit vector corresponding to spin j and state c,
124 - dAi/dAmn is the partial derivative of the alignment tensor with respect to element Amn.
125
126
127 @param dj: The PCS constants for each structure c for spin j. This should be an array with indices corresponding to c.
128 @type dj: numpy rank-1 array
129 @param vect: The electron-nuclear unit vector matrix. The first dimension corresponds to the structural index, the second dimension is the coordinates of the unit vector. The vectors should be parallel to the vector connecting the paramagnetic centre to the nuclear spin.
130 @type vect: numpy matrix
131 @param N: The total number of structures.
132 @type N: int
133 @param dAi_dAmn: The alignment tensor derivative with respect to parameter Amn.
134 @type dAi_dAmn: numpy rank-2 3D tensor
135 @param weights: The weights for each member of the ensemble (the last member need not be supplied).
136 @type weights: numpy rank-1 array
137 @return: The average PCS gradient element.
138 @rtype: float
139 """
140
141
142 grad = 0.0
143
144
145 if weights == None:
146 pc = 1.0 / N
147 weights = [pc] * N
148
149
150 if len(weights) < N:
151 pN = 1.0 - sum(weights, axis=0)
152 weights = weights.tolist()
153 weights.append(pN)
154
155
156 for c in range(N):
157 grad = grad + weights[c] * dj[c] * dot(vect[c], dot(dAi_dAmn, vect[c]))
158
159
160 return grad
161
162
164 """Calculate the PCS, using the 3D alignment tensor.
165
166 The PCS value is::
167
168 T
169 delta_ij(theta) = dj . mu_j . Ai . mu_j,
170
171 where:
172 - i is the alignment tensor index,
173 - j is the index over spins,
174 - theta is the parameter vector,
175 - dj is the PCS constant for spin j,
176 - mu_j i the unit vector corresponding to spin j,
177 - Ai is the alignment tensor.
178
179 The PCS constant is defined as::
180
181 mu0 15kT 1
182 dj = --- ----- ---- ,
183 4pi Bo**2 r**3
184
185 where:
186 - mu0 is the permeability of free space,
187 - k is Boltzmann's constant,
188 - T is the absolute temperature,
189 - Bo is the magnetic field strength,
190 - r is the distance between the paramagnetic centre (electron spin) and the nuclear spin.
191
192
193 @param dj: The PCS constant for spin j.
194 @type dj: float
195 @param mu: The unit vector connecting the electron and nuclear spins.
196 @type mu: numpy rank-1 3D array
197 @param A: The alignment tensor.
198 @type A: numpy rank-2 3D tensor
199 @return: The PCS value.
200 @rtype: float
201 """
202
203
204 return dj * dot(mu, dot(A, mu))
205