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 r"""The Carver and Richards (1972) 2-site all time scale exchange U{CR72<http://wiki.nmr-relax.com/CR72>} and U{CR72 full<http://wiki.nmr-relax.com/CR72_full>} models.
26
27 Description
28 ===========
29
30 This module is for the function, gradient and Hessian of the U{CR72<http://wiki.nmr-relax.com/CR72>} and U{CR72 full<http://wiki.nmr-relax.com/CR72_full>} models.
31
32
33 References
34 ==========
35
36 The model is named after the reference:
37
38 - Carver, J. P. and Richards, R. E. (1972). General 2-site solution for chemical exchange produced dependence of T2 upon Carr-Purcell pulse separation. I{J. Magn. Reson.}, B{6}, 89-105. (U{DOI: 10.1016/0022-2364(72)90090-X<http://dx.doi.org/10.1016/0022-2364(72)90090-X>}).
39
40
41 Equations
42 =========
43
44 The equation used is::
45
46 R2eff = 1/2 [ R2A0 + R2B0 + kex - 2.nu_cpmg.cosh^-1 (D+.cosh(eta+) - D-.cos(eta-)) ] ,
47
48 where::
49
50 1 / Psi + 2delta_omega^2 \
51 D+/- = - | +/-1 + -------------------- | ,
52 2 \ sqrt(Psi^2 + zeta^2) /
53
54 1
55 eta+/- = 2^(-3/2) . -------- sqrt(+/-Psi + sqrt(Psi^2 + zeta^2)) ,
56 nu_cpmg
57
58 Psi = (R2A0 - R2B0 - pA.kex + pB.kex)^2 - delta_omega^2 + 4pA.pB.kex^2 ,
59
60 zeta = 2delta_omega (R2A0 - R2B0 - pA.kex + pB.kex).
61
62 kex is the chemical exchange rate constant, pA and pB are the populations of states A and B, and delta_omega is the chemical shift difference between the two states in ppm.
63
64
65 CR72 model
66 ----------
67
68 Importantly for the implementation of this model, it is assumed that R2A0 and R2B0 are identical. This simplifies some of the equations to::
69
70 R2eff = R20 + kex/2 - nu_cpmg.cosh^-1 (D+.cosh(eta+) - D-.cos(eta-) ,
71
72 where::
73
74 Psi = kex^2 - delta_omega^2 ,
75
76 zeta = -2delta_omega (pA.kex - pB.kex).
77
78
79 Links
80 =====
81
82 More information on the CR72 model can be found in the:
83
84 - U{relax wiki<http://wiki.nmr-relax.com/CR72>},
85 - U{relax manual<http://www.nmr-relax.com/manual/The_reduced_CR72_2_site_CPMG_model.html>},
86 - U{relaxation dispersion page of the relax website<http://www.nmr-relax.com/analyses/relaxation_dispersion.html#CR72>}.
87
88 More information on the CR72 full model can be found in the:
89
90 - U{relax wiki<http://wiki.nmr-relax.com/CR72_full>},
91 - U{relax manual<http://www.nmr-relax.com/manual/The_full_CR72_2_site_CPMG_model.html>},
92 - U{relaxation dispersion page of the relax website<http://www.nmr-relax.com/analyses/relaxation_dispersion.html#CR72_full>}.
93 """
94
95
96 from numpy import arccosh, cos, cosh, isfinite, fabs, min, max, multiply, sqrt, subtract, sum
97 from numpy.ma import fix_invalid, masked_greater_equal, masked_where
98
99
100 eta_scale = 2.0**(-3.0/2.0)
101
102
103 -def r2eff_CR72(r20a=None, r20a_orig=None, r20b=None, r20b_orig=None, pA=None, dw=None, dw_orig=None, kex=None, cpmg_frqs=None, back_calc=None):
104 """Calculate the R2eff values for the CR72 model.
105
106 See the module docstring for details.
107
108
109 @keyword r20a: The R20 parameter value of state A (R2 with no exchange).
110 @type r20a: numpy float array of rank [NE][NS][NM][NO][ND]
111 @keyword r20a_orig: The R20 parameter value of state A (R2 with no exchange). This is only for faster checking of zero value, which result in no exchange.
112 @type r20a_orig: numpy float array of rank-1
113 @keyword r20b: The R20 parameter value of state B (R2 with no exchange).
114 @type r20b: numpy float array of rank [NE][NS][NM][NO][ND]
115 @keyword r20b_orig: The R20 parameter value of state B (R2 with no exchange). This is only for faster checking of zero value, which result in no exchange.
116 @type r20b_orig: numpy float array of rank-1
117 @keyword pA: The population of state A.
118 @type pA: float
119 @keyword dw: The chemical exchange difference between states A and B in rad/s.
120 @type dw: numpy array of rank [NE][NS][NM][NO][ND]
121 @keyword dw_orig: The chemical exchange difference between states A and B in ppm. This is only for faster checking of zero value, which result in no exchange.
122 @type dw_orig: numpy float array of rank-1
123 @keyword kex: The kex parameter value (the exchange rate in rad/s).
124 @type kex: float
125 @keyword cpmg_frqs: The CPMG nu1 frequencies.
126 @type cpmg_frqs: numpy float array of rank [NE][NS][NM][NO][ND]
127 @keyword back_calc: The array for holding the back calculated R2eff values. Each element corresponds to one of the CPMG nu1 frequencies.
128 @type back_calc: numpy float array of rank [NE][NS][NM][NO][ND]
129 """
130
131
132 t_dw_zero = False
133 t_max_etapos = False
134
135
136
137 if kex == 0.0 or pA == 1.0:
138 back_calc[:] = r20a
139 return
140
141
142 if min(fabs(dw_orig)) == 0.0:
143 t_dw_zero = True
144 mask_dw_zero = masked_where(dw == 0.0, dw)
145
146
147 pB = 1.0 - pA
148
149
150 dw2 = dw**2
151 r20_kex = (r20a + r20b + kex) / 2.0
152 k_BA = pA * kex
153 k_AB = pB * kex
154
155
156 if sum(r20a_orig - r20b_orig) != 0.0:
157 fact = r20a - r20b - k_BA + k_AB
158 Psi = fact**2 - dw2 + 4.0*k_BA*k_AB
159 zeta = 2.0*dw * fact
160 else:
161 Psi = kex**2 - dw2
162 zeta = -2.0*dw * (k_BA - k_AB)
163
164
165 sqrt_psi2_zeta2 = sqrt(Psi**2 + zeta**2)
166
167
168 D_part = (0.5*Psi + dw2) / sqrt_psi2_zeta2
169 Dpos = 0.5 + D_part
170 Dneg = -0.5 + D_part
171
172
173 eta_fact = eta_scale / cpmg_frqs
174 etapos = eta_fact * sqrt(Psi + sqrt_psi2_zeta2)
175 etaneg = eta_fact * sqrt(-Psi + sqrt_psi2_zeta2)
176
177
178
179 if max(etapos) > 700:
180 t_max_etapos = True
181 mask_max_etapos = masked_greater_equal(etapos, 700.0)
182
183 etapos[mask_max_etapos.mask] = 1.0
184
185
186 fact = Dpos * cosh(etapos) - Dneg * cos(etaneg)
187 if min(fact) < 1.0:
188 back_calc[:] = r20_kex
189 return
190
191
192 multiply(cpmg_frqs, arccosh(fact), out=back_calc)
193 subtract(r20_kex, back_calc, out=back_calc)
194
195
196
197 if t_dw_zero:
198 back_calc[mask_dw_zero.mask] = r20a[mask_dw_zero.mask]
199
200
201 if t_max_etapos:
202 back_calc[mask_max_etapos.mask] = r20a[mask_max_etapos.mask]
203
204
205
206 if not isfinite(sum(back_calc)):
207
208 fix_invalid(back_calc, copy=False, fill_value=1e100)
209