mailr21601 - in /branches/relax_disp: lib/dispersion/mmq_2site.py target_functions/relax_disp.py


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by edward on November 22, 2013 - 15:58:
Author: bugman
Date: Fri Nov 22 15:58:32 2013
New Revision: 21601

URL: http://svn.gna.org/viewcvs/relax?rev=21601&view=rev
Log:
Big bug fixes for the 'MMQ 2-site' dispersion model.

The equations in Korzhnev et al., 2004 are incorrect!  This is clear when 
comparing the equations in
the paper to those implemented in the cpmg_fit source code.  The equations in 
relax have been
changed to match the correct one.

In addition, the matrix power factor must be found with the python 
math.floor() function and not
int() as the later will sometimes round up.


Modified:
    branches/relax_disp/lib/dispersion/mmq_2site.py
    branches/relax_disp/target_functions/relax_disp.py

Modified: branches/relax_disp/lib/dispersion/mmq_2site.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/relax_disp/lib/dispersion/mmq_2site.py?rev=21601&r1=21600&r2=21601&view=diff
==============================================================================
--- branches/relax_disp/lib/dispersion/mmq_2site.py (original)
+++ branches/relax_disp/lib/dispersion/mmq_2site.py Fri Nov 22 15:58:32 2013
@@ -30,6 +30,7 @@
 """
 
 # Python module imports.
+from math import floor
 from numpy import array, conj, dot, float64, log
 
 # relax module imports.
@@ -62,7 +63,7 @@
     matrix[1, 1] = -k_BA + 1.j*dw - R20B
 
 
-def r2eff_mmq_2site_mq(M0=None, F_vector=array([1, 0], float64), m1=None, 
m2=None, R20A=None, R20B=None, pA=None, pB=None, dw=None, dwH=None, 
k_AB=None, k_BA=None, inv_tcpmg=None, tcp=None, back_calc=None, 
num_points=None, power=None, n=None):
+def r2eff_mmq_2site_mq(M0=None, F_vector=array([1, 0], float64), m1=None, 
m2=None, R20A=None, R20B=None, pA=None, pB=None, dw=None, dwH=None, 
k_AB=None, k_BA=None, inv_tcpmg=None, tcp=None, back_calc=None, 
num_points=None, power=None):
     """The 2-site numerical solution to the Bloch-McConnell equation for MQ 
data.
 
     The notation used here comes from:
@@ -110,13 +111,11 @@
     @type num_points:       int
     @keyword power:         The matrix exponential power array.
     @type power:            numpy int16, rank-1 array
-    @keyword n:             The n value whereby one CPMG block is defined at 
2n.
-    @type n:                numpy int16, rank-1 array
     """
 
     # Populate the m1 and m2 matrices (only once per function call for 
speed).
-    populate_matrix(matrix=m1, R20A=R20A, R20B=R20B, dw=dw+dwH, k_AB=k_AB, 
k_BA=k_BA)     # D+ matrix component.
-    populate_matrix(matrix=m2, R20A=R20A, R20B=R20B, dw=-dw+dwH, k_AB=k_AB, 
k_BA=k_BA)    # Z- matrix component.
+    populate_matrix(matrix=m1, R20A=R20A, R20B=R20B, dw=-dw-dwH, k_AB=k_AB, 
k_BA=k_BA)     # D+ matrix component.
+    populate_matrix(matrix=m2, R20A=R20A, R20B=R20B, dw=dw-dwH, k_AB=k_AB, 
k_BA=k_BA)    # Z- matrix component.
 
     # Loop over the time points, back calculating the R2eff values.
     for i in range(num_points):
@@ -138,10 +137,24 @@
         M1_M2_M2_M1_star = dot(M1_M2_star, M2_M1_star)
         M2_M1_M1_M2_star = dot(M2_M1_star, M1_M2_star)
 
-        # Matrices for even n.
-        if n[i] % 2 == 0:
+        # Special case of 1 CPMG block - the power is zero.
+        if power[i] == 1:
+            # M2.M1
+            A = M2_M1
+
+            # M2*.M1*
+            B = M2_M1_star
+
+            # M1.M2
+            C = M1_M2
+
+            # M1*.M2*
+            D = M1_M2_star
+
+        # Matrices for even number of CPMG blocks.
+        elif power[i] % 2 == 0:
             # The power factor (only calculate once).
-            fact = int(n[i] / 2)
+            fact = int(floor(power[i] / 2))
 
             # (M1.M2.M2.M1)^(n/2)
             A = square_matrix_power(M1_M2_M2_M1, fact)
@@ -155,31 +168,31 @@
             # (M1*.M2*.M2*.M1*)^(n/2)
             D = square_matrix_power(M1_M2_M2_M1_star, fact)
 
-        # Matrices for odd n.
+        # Matrices for odd number of CPMG blocks.
         else:
             # The power factor (only calculate once).
-            fact = int((n[i] - 1) / 2)
-
-            # (M1.M2.M2.M1)^((n-1)/2).M1.M2
+            fact = int(floor((power[i] - 1) / 2))
+
+            # M2.M1.(M1.M2.M2.M1)^((n-1)/2)
             A = square_matrix_power(M1_M2_M2_M1, fact)
-            A = dot(A, M1_M2)
-
-            # (M1*.M2*.M2*.M1*)^((n-1)/2).M1*.M2*
+            A = dot(M2_M1, A)
+
+            # M2*.M1*.(M1*.M2*.M2*.M1*)^((n-1)/2)
             B = square_matrix_power(M1_M2_M2_M1_star, fact)
-            B = dot(B, M1_M2_star)
-
-            # (M2.M1.M1.M2)^((n-1)/2).M2.M1
+            B = dot(M2_M1_star, B)
+
+            # M1.M2.(M2.M1.M1.M2)^((n-1)/2)
             C = square_matrix_power(M2_M1_M1_M2, fact)
-            C = dot(C, M2_M1)
-
-            # (M2*.M1*.M1*.M2*)^((n-1)/2).M2*.M1*
+            C = dot(M1_M2, C)
+
+            # M1*.M2*.(M2*.M1*.M1*.M2*)^((n-1)/2)
             D = square_matrix_power(M2_M1_M1_M2_star, fact)
-            D = dot(D, M2_M1_star)
+            D = dot(M1_M2_star, D)
 
         # The next lines calculate the R2eff using a two-point 
approximation, i.e. assuming that the decay is mono-exponential.
-        A_B = dot(A, B)
-        C_D = dot(C, D)
-        Mx = dot(dot(F_vector, (A_B + C_D)), M0)
+        B_A = dot(B, A)
+        D_C = dot(D, C)
+        Mx = dot(dot(F_vector, (B_A + D_C)), M0)
         Mx = Mx.real / 2.0
         if Mx <= 0.0 or isNaN(Mx):
             back_calc[i] = 1e99
@@ -187,7 +200,7 @@
             back_calc[i]= -inv_tcpmg * log(Mx / pA)
 
 
-def r2eff_mmq_2site_sq_dq_zq(M0=None, F_vector=array([1, 0], float64), 
m1=None, m2=None, R20A=None, R20B=None, pA=None, pB=None, dw=None, dwH=None, 
k_AB=None, k_BA=None, inv_tcpmg=None, tcp=None, back_calc=None, 
num_points=None, power=None, n=None):
+def r2eff_mmq_2site_sq_dq_zq(M0=None, F_vector=array([1, 0], float64), 
m1=None, m2=None, R20A=None, R20B=None, pA=None, pB=None, dw=None, dwH=None, 
k_AB=None, k_BA=None, inv_tcpmg=None, tcp=None, back_calc=None, 
num_points=None, power=None):
     """The 2-site numerical solution to the Bloch-McConnell equation for SQ, 
ZQ, and DQ data.
 
     The notation used here comes from:
@@ -231,8 +244,6 @@
     @type num_points:       int
     @keyword power:         The matrix exponential power array.
     @type power:            numpy int16, rank-1 array
-    @keyword n:             The n value whereby one CPMG block is defined at 
2n.
-    @type n:                numpy int16, rank-1 array
     """
 
     # Populate the m1 and m2 matrices (only once per function call for 
speed).

Modified: branches/relax_disp/target_functions/relax_disp.py
URL: 
http://svn.gna.org/viewcvs/relax/branches/relax_disp/target_functions/relax_disp.py?rev=21601&r1=21600&r2=21601&view=diff
==============================================================================
--- branches/relax_disp/target_functions/relax_disp.py (original)
+++ branches/relax_disp/target_functions/relax_disp.py Fri Nov 22 15:58:32 
2013
@@ -230,14 +230,6 @@
                     
self.power[exp_type_index].append(zeros(self.num_disp_points[exp_type_index][frq_index],
 int16))
                     for i in 
range(self.num_disp_points[exp_type_index][frq_index]):
                         self.power[exp_type_index][frq_index][i] = 
int(round(self.cpmg_frqs[exp_type_index][frq_index][i] * 
self.relax_times[exp_type_index][frq_index]))
-
-        # The n value.
-        if model == MODEL_MMQ_2SITE:
-            self.n = []
-            for exp_type_index in range(len(values)):
-                self.n.append([])
-                for frq_index in range(len(values[exp_type_index][0])):
-                    self.n[exp_type_index].append(2 * 
self.power[exp_type_index][frq_index])
 
         # The tau_cpmg times - recalculated to avoid any user induced 
truncation in the input files.
         if model in [MODEL_MQ_CR72, MODEL_MMQ_2SITE, MODEL_NS_CPMG_2SITE_3D, 
MODEL_NS_CPMG_2SITE_3D_FULL, MODEL_NS_CPMG_2SITE_EXPANDED, 
MODEL_NS_CPMG_2SITE_STAR, MODEL_NS_CPMG_2SITE_STAR_FULL, MODEL_TSMFK01]:
@@ -968,7 +960,7 @@
                         aliased_dwH = dw_frq
 
                     # Back calculate the R2eff values for each experiment 
type.
-                    self.r2eff_mmq[exp_index](M0=self.M0, m1=self.m1, 
m2=self.m2, R20A=R20[r20_index], R20B=R20[r20_index], pA=pA, pB=pB, 
dw=aliased_dw, dwH=aliased_dwH, k_AB=k_AB, k_BA=k_BA, 
inv_tcpmg=self.inv_relax_times[exp_index][frq_index], 
tcp=self.tau_cpmg[exp_index][frq_index], 
back_calc=self.back_calc[exp_index][spin_index][frq_index], 
num_points=self.num_disp_points[exp_index][frq_index], 
power=self.power[exp_index][frq_index], n=self.n[exp_index][frq_index])
+                    self.r2eff_mmq[exp_index](M0=self.M0, m1=self.m1, 
m2=self.m2, R20A=R20[r20_index], R20B=R20[r20_index], pA=pA, pB=pB, 
dw=aliased_dw, dwH=aliased_dwH, k_AB=k_AB, k_BA=k_BA, 
inv_tcpmg=self.inv_relax_times[exp_index][frq_index], 
tcp=self.tau_cpmg[exp_index][frq_index], 
back_calc=self.back_calc[exp_index][spin_index][frq_index], 
num_points=self.num_disp_points[exp_index][frq_index], 
power=self.power[exp_index][frq_index])
 
                     # For all missing data points, set the back-calculated 
value to the measured values so that it has no effect on the chi-squared 
value.
                     for point_index in 
range(self.num_disp_points[exp_index][frq_index]):




Related Messages


Powered by MHonArc, Updated Fri Nov 22 16:40:02 2013