mailr21753 - /trunk/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 December 03, 2013 - 17:23:
Author: bugman
Date: Tue Dec  3 17:23:43 2013
New Revision: 21753

URL: http://svn.gna.org/viewcvs/relax?rev=21753&view=rev
Log:
Created the target functions for the 'NS MMQ 3-site' models.

This is for the 'NS MMQ 3-site' and 'NS MMQ 3-site (linear)' CPMG dispersion 
models.

This follows the tutorial for adding relaxation dispersion models at:
http://wiki.nmr-relax.com/Tutorial_for_adding_relaxation_dispersion_models_to_relax#The_target_function


Modified:
    trunk/target_functions/relax_disp.py

Modified: trunk/target_functions/relax_disp.py
URL: 
http://svn.gna.org/viewcvs/relax/trunk/target_functions/relax_disp.py?rev=21753&r1=21752&r2=21753&view=diff
==============================================================================
--- trunk/target_functions/relax_disp.py (original)
+++ trunk/target_functions/relax_disp.py Tue Dec  3 17:23:43 2013
@@ -42,6 +42,7 @@
 from lib.dispersion.ns_cpmg_2site_3d import r2eff_ns_cpmg_2site_3D
 from lib.dispersion.ns_cpmg_2site_expanded import 
r2eff_ns_cpmg_2site_expanded
 from lib.dispersion.ns_cpmg_2site_star import r2eff_ns_cpmg_2site_star
+from lib.dispersion.ns_mmq_3site import r2eff_ns_mmq_3site_mq, 
r2eff_ns_mmq_3site_sq_dq_zq
 from lib.dispersion.ns_r1rho_2site import ns_r1rho_2site
 from lib.dispersion.ns_matrices import r180x_3d
 from lib.dispersion.tp02 import r1rho_TP02
@@ -50,7 +51,7 @@
 from lib.errors import RelaxError
 from lib.float import isNaN
 from target_functions.chi2 import chi2
-from specific_analyses.relax_disp.variables import EXP_TYPE_CPMG_DQ, 
EXP_TYPE_CPMG_MQ, EXP_TYPE_CPMG_PROTON_MQ, EXP_TYPE_CPMG_PROTON_SQ, 
EXP_TYPE_CPMG_SQ, EXP_TYPE_CPMG_ZQ, EXP_TYPE_R1RHO, MODEL_CR72, 
MODEL_CR72_FULL, MODEL_DPL94, MODEL_IT99, MODEL_LIST_CPMG, MODEL_LIST_FULL, 
MODEL_LIST_MMQ, MODEL_LIST_MQ_CPMG, MODEL_LIST_R1RHO, MODEL_LM63, 
MODEL_LM63_3SITE, MODEL_M61, MODEL_M61B, MODEL_MMQ_2SITE, MODEL_MP05, 
MODEL_MQ_CR72, MODEL_NOREX, 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_NS_R1RHO_2SITE, MODEL_R2EFF, MODEL_TAP03, MODEL_TP02, MODEL_TSMFK01
+from specific_analyses.relax_disp.variables import EXP_TYPE_CPMG_DQ, 
EXP_TYPE_CPMG_MQ, EXP_TYPE_CPMG_PROTON_MQ, EXP_TYPE_CPMG_PROTON_SQ, 
EXP_TYPE_CPMG_SQ, EXP_TYPE_CPMG_ZQ, EXP_TYPE_R1RHO, MODEL_CR72, 
MODEL_CR72_FULL, MODEL_DPL94, MODEL_IT99, MODEL_LIST_CPMG, MODEL_LIST_FULL, 
MODEL_LIST_MMQ, MODEL_LIST_MQ_CPMG, MODEL_LIST_R1RHO, MODEL_LM63, 
MODEL_LM63_3SITE, MODEL_M61, MODEL_M61B, MODEL_MMQ_2SITE, MODEL_MP05, 
MODEL_MQ_CR72, MODEL_NOREX, 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_NS_MMQ_3SITE, 
MODEL_NS_MMQ_3SITE_LINEAR, MODEL_NS_R1RHO_2SITE, MODEL_R2EFF, MODEL_TAP03, 
MODEL_TP02, MODEL_TSMFK01
 
 
 class Dispersion:
@@ -84,6 +85,8 @@
             - 'NS CPMG 2-site star full':  The full numerical solution for 
the 2-site Bloch-McConnell equations for CPMG data using complex conjugate 
matrices.
             - 'NS CPMG 2-site expanded':  The numerical solution for the 
2-site Bloch-McConnell equations for CPMG data expanded using Maple by 
Nikolai Skrynnikov.
             - 'MMQ 2-site':  The numerical solution for the 2-site 
Bloch-McConnell equations for combined proton-heteronuclear SQ, ZD, DQ, and 
MQ CPMG data with R20A = R20B.
+            - 'NS MMQ 3-site linear':  The numerical solution for the 3-site 
Bloch-McConnell equations linearised with kAC = kCA = 0 for combined 
proton-heteronuclear SQ, ZD, DQ, and MQ CPMG data with R20A = R20B = R20C.
+            - 'NS MMQ 3-site':  The numerical solution for the 3-site 
Bloch-McConnell equations for combined proton-heteronuclear SQ, ZD, DQ, and 
MQ CPMG data with R20A = R20B = R20C.
 
 
         @keyword model:             The relaxation dispersion model to fit.
@@ -195,6 +198,10 @@
         self.end_index.append(self.end_index[-1] + self.num_spins)
         if model in [MODEL_IT99, MODEL_LM63_3SITE, MODEL_MQ_CR72, 
MODEL_MMQ_2SITE]:
             self.end_index.append(self.end_index[-1] + self.num_spins)
+        elif model in [MODEL_NS_MMQ_3SITE, MODEL_NS_MMQ_3SITE_LINEAR]:
+            self.end_index.append(self.end_index[-1] + self.num_spins)
+            self.end_index.append(self.end_index[-1] + self.num_spins)
+            self.end_index.append(self.end_index[-1] + self.num_spins)
 
         # Set up the matrices for the numerical solutions.
         if model in [MODEL_NS_CPMG_2SITE_STAR, 
MODEL_NS_CPMG_2SITE_STAR_FULL]:
@@ -217,6 +224,8 @@
         # This is a vector that contains the initial magnetizations 
corresponding to the A and B state transverse magnetizations.
         if model in [MODEL_MMQ_2SITE, MODEL_NS_CPMG_2SITE_STAR, 
MODEL_NS_CPMG_2SITE_STAR_FULL]:
             self.M0 = zeros(2, float64)
+        if model in [MODEL_NS_MMQ_3SITE, MODEL_NS_MMQ_3SITE_LINEAR]:
+            self.M0 = zeros(3, float64)
         if model in [MODEL_NS_CPMG_2SITE_3D, MODEL_NS_CPMG_2SITE_3D_FULL]:
             self.M0 = zeros(7, float64)
             self.M0[0] = 0.5
@@ -224,7 +233,7 @@
             self.M0 = zeros(6, float64)
 
         # Special CPMG-type data structures.
-        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]:
+        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_NS_MMQ_3SITE, 
MODEL_NS_MMQ_3SITE_LINEAR, MODEL_TSMFK01]:
             # The number of CPMG blocks.
             self.power = []
             for exp_type_index in range(self.num_exp):
@@ -267,13 +276,16 @@
                     self.spin_lock_omega1_squared[exp_type_index][frq_index] 
= self.spin_lock_omega1[exp_type_index][frq_index] ** 2
 
         # The inverted relaxation delay.
-        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_NS_R1RHO_2SITE]:
+        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_NS_MMQ_3SITE, 
MODEL_NS_MMQ_3SITE_LINEAR, MODEL_NS_R1RHO_2SITE]:
             self.inv_relax_times = 1.0 / relax_times
 
-        # Special storage matrices for the multi-quantum CPMG 2-site 
numerical model.
+        # Special storage matrices for the multi-quantum CPMG N-site 
numerical models.
         if model == MODEL_MMQ_2SITE:
             self.m1 = zeros((2, 2), complex64)
             self.m2 = zeros((2, 2), complex64)
+        elif model in [MODEL_NS_MMQ_3SITE, MODEL_NS_MMQ_3SITE_LINEAR]:
+            self.m1 = zeros((3, 3), complex64)
+            self.m2 = zeros((3, 3), complex64)
 
         # Set up the model.
         if model == MODEL_NOREX:
@@ -318,6 +330,10 @@
             self.func = self.func_mq_CR72
         if model == MODEL_MMQ_2SITE:
             self.func = self.func_mmq_2site
+        if model == MODEL_NS_MMQ_3SITE:
+            self.func = self.func_ns_mmq_3site
+        if model == MODEL_NS_MMQ_3SITE_LINEAR:
+            self.func = self.func_ns_mmq_3site_linear
 
 
     def calc_CR72_chi2(self, R20A=None, R20B=None, dw=None, pA=None, 
kex=None):
@@ -479,6 +495,121 @@
         return chi2_sum
 
 
+    def calc_ns_mmq_3site_chi2(self, R20A=None, R20B=None, R20C=None, 
dw_AB=None, dw_BC=None, dw_AC=None, dwH_AB=None, dwH_BC=None, dwH_AC=None, 
pA=None, pB=None, kex_AB=None, kex_BC=None, kex_AC=None):
+        """Calculate the chi-squared value for the 'NS MMQ 3-site' models.
+
+        @keyword R20A:      The R2 value for state A in the absence of 
exchange.
+        @type R20A:         list of float
+        @keyword R20B:      The R2 value for state B in the absence of 
exchange.
+        @type R20B:         list of float
+        @keyword R20C:      The R2 value for state C in the absence of 
exchange.
+        @type R20C:         list of float
+        @keyword dw_AB:     The chemical exchange difference between states 
A and B in rad/s.
+        @type dw_AB:        float
+        @keyword dw_BC:     The chemical exchange difference between states 
B and C in rad/s.
+        @type dw_BC:        float
+        @keyword dwH_AB:    The proton chemical exchange difference between 
states A and B in rad/s.
+        @type dwH_AB:       float
+        @keyword dwH_BC:    The proton chemical exchange difference between 
states B and C in rad/s.
+        @type dwH_BC:       float
+        @keyword pA:        The population of state A.
+        @type pA:           float
+        @keyword kex_AB:    The rate of exchange between states A and B.
+        @type kex_AB:       float
+        @keyword kex_BC:    The rate of exchange between states B and C.
+        @type kex_BC:       float
+        @keyword kex_AC:    The rate of exchange between states A and C.
+        @type kex_AC:       float
+        @return:            The chi-squared value.
+        @rtype:             float
+        """
+
+        # Once off parameter conversions.
+        pC = 1.0 - pA - pB
+        k_BA = pA * kex_AB
+        k_AB = pB * kex_AB
+        k_CA = pA * kex_AC
+        k_AC = pC * kex_AC
+        k_CB = pB * kex_BC
+        k_BC = pC * kex_BC
+        dw_AC = dw_AB + dw_BC
+        dwH_AC = dwH_AB + dwH_BC
+
+        # This is a vector that contains the initial magnetizations 
corresponding to the A and B state transverse magnetizations.
+        self.M0[0] = pA
+        self.M0[1] = pB
+        self.M0[2] = pC
+
+        # Initialise.
+        chi2_sum = 0.0
+
+        # Loop over the experiment types.
+        for exp_index in range(self.num_exp):
+            # Loop over the spins.
+            for spin_index in range(self.num_spins):
+                # Loop over the spectrometer frequencies.
+                for frq_index in range(self.num_frq):
+                    # The R20 index.
+                    r20_index = frq_index + exp_index*self.num_frq + 
spin_index*self.num_frq*self.num_exp
+
+                    # Convert dw from ppm to rad/s.
+                    dw_AB_frq = dw_AB[spin_index] * 
self.frqs[exp_index][spin_index][frq_index]
+                    dw_BC_frq = dw_BC[spin_index] * 
self.frqs[exp_index][spin_index][frq_index]
+                    dw_AC_frq = dw_AC[spin_index] * 
self.frqs[exp_index][spin_index][frq_index]
+                    dwH_AB_frq = dwH_AB[spin_index] * 
self.frqs_H[exp_index][spin_index][frq_index]
+                    dwH_BC_frq = dwH_BC[spin_index] * 
self.frqs_H[exp_index][spin_index][frq_index]
+                    dwH_AC_frq = dwH_AC[spin_index] * 
self.frqs_H[exp_index][spin_index][frq_index]
+
+                    # Alias the dw frequency combinations.
+                    aliased_dwH_AB = 0.0
+                    aliased_dwH_BC = 0.0
+                    aliased_dwH_AC = 0.0
+                    if self.exp_types[exp_index] == EXP_TYPE_CPMG_SQ:
+                        aliased_dw_AB = dw_AB_frq
+                        aliased_dw_BC = dw_BC_frq
+                        aliased_dw_AC = dw_AC_frq
+                    elif self.exp_types[exp_index] == 
EXP_TYPE_CPMG_PROTON_SQ:
+                        aliased_dw_AB = dwH_AB_frq
+                        aliased_dw_BC = dwH_BC_frq
+                        aliased_dw_AC = dwH_AC_frq
+                    elif self.exp_types[exp_index] == EXP_TYPE_CPMG_DQ:
+                        aliased_dw_AB = dw_AB_frq + dwH_AB_frq
+                        aliased_dw_BC = dw_BC_frq + dwH_BC_frq
+                        aliased_dw_AC = dw_AC_frq + dwH_AC_frq
+                    elif self.exp_types[exp_index] == EXP_TYPE_CPMG_ZQ:
+                        aliased_dw_AB = dw_AB_frq - dwH_AB_frq
+                        aliased_dw_BC = dw_BC_frq - dwH_BC_frq
+                        aliased_dw_AC = dw_AC_frq - dwH_AC_frq
+                    elif self.exp_types[exp_index] == EXP_TYPE_CPMG_MQ:
+                        aliased_dw_AB = dw_AB_frq
+                        aliased_dw_BC = dw_BC_frq
+                        aliased_dw_AC = dw_AC_frq
+                        aliased_dwH_AB = dwH_AB_frq
+                        aliased_dwH_BC = dwH_BC_frq
+                        aliased_dwH_AC = dwH_AC_frq
+                    elif self.exp_types[exp_index] == 
EXP_TYPE_CPMG_PROTON_MQ:
+                        aliased_dw_AB = dwH_AB_frq
+                        aliased_dw_BC = dwH_BC_frq
+                        aliased_dw_AC = dwH_AC_frq
+                        aliased_dwH_AB = dw_AB_frq
+                        aliased_dwH_BC = dw_BC_frq
+                        aliased_dwH_AC = dw_AC_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=R20A[r20_index], R20B=R20B[r20_index], R20C=R20C[r20_index], 
pA=pA, pB=pB, pC=pC, dw_AB=aliased_dw_AB, dw_BC=aliased_dw_BC, 
dw_AC=aliased_dw_AC, dwH_AB=aliased_dwH_AB, dwH_BC=aliased_dwH_BC, 
dwH_AC=aliased_dwH_AC, k_AB=k_AB, k_BA=k_BA, k_BC=k_BC, k_CB=k_CB, k_AC=k_AC, 
k_CA=k_CA, 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]):
+                        if 
self.missing[exp_index][spin_index][frq_index][point_index]:
+                            
self.back_calc[exp_index][spin_index][frq_index][point_index] = 
self.values[exp_index][spin_index][frq_index][point_index]
+
+                    # Calculate and return the chi-squared value.
+                    chi2_sum += 
chi2(self.values[exp_index][spin_index][frq_index], 
self.back_calc[exp_index][spin_index][frq_index], 
self.errors[exp_index][spin_index][frq_index])
+
+        # Return the total chi-squared value.
+        return chi2_sum
+
+
     def experiment_type_setup(self):
         """Check the experiment types and simplify data structures.
 
@@ -492,11 +623,22 @@
         if self.model in MODEL_LIST_MMQ:
             # Alias the r2eff functions.
             self.r2eff_mmq = []
+
+            # Loop over the experiment types.
             for exp_index in range(self.num_exp):
+                # SQ, DQ and ZQ data types.
                 if self.exp_types[exp_index] in [EXP_TYPE_CPMG_SQ, 
EXP_TYPE_CPMG_PROTON_SQ, EXP_TYPE_CPMG_DQ, EXP_TYPE_CPMG_ZQ]:
-                    self.r2eff_mmq.append(r2eff_mmq_2site_sq_dq_zq)
+                    if self.model == MODEL_MMQ_2SITE:
+                        self.r2eff_mmq.append(r2eff_mmq_2site_sq_dq_zq)
+                    else:
+                        self.r2eff_mmq.append(r2eff_ns_mmq_3site_sq_dq_zq)
+
+                # MQ data types.
                 elif self.exp_types[exp_index] in [EXP_TYPE_CPMG_MQ, 
EXP_TYPE_CPMG_PROTON_MQ]:
-                    self.r2eff_mmq.append(r2eff_mmq_2site_mq)
+                    if self.model == MODEL_MMQ_2SITE:
+                        self.r2eff_mmq.append(r2eff_mmq_2site_mq)
+                    else:
+                        self.r2eff_mmq.append(r2eff_ns_mmq_3site_mq)
 
         # The single data type models.
         else:
@@ -1250,6 +1392,63 @@
         return self.calc_ns_cpmg_2site_star_chi2(R20A=R20A, R20B=R20B, 
dw=dw, pA=pA, kex=kex)
 
 
+    def func_ns_mmq_3site(self, params):
+        """Target function for the combined SQ, ZQ, DQ and MQ 3-site MMQ 
CPMG numeric solution.
+
+        @param params:  The vector of parameter values.
+        @type params:   numpy rank-1 float array
+        @return:        The chi-squared value.
+        @rtype:         float
+        """
+
+        # Scaling.
+        if self.scaling_flag:
+            params = dot(params, self.scaling_matrix)
+
+        # Unpack the parameter values.
+        R20 = params[:self.end_index[0]]
+        dw_AB = params[self.end_index[0]:self.end_index[1]]
+        dw_BC = params[self.end_index[1]:self.end_index[2]]
+        dwH_AB = params[self.end_index[2]:self.end_index[3]]
+        dwH_BC = params[self.end_index[3]:self.end_index[4]]
+        pA = params[self.end_index[4]]
+        kex_AB = params[self.end_index[4]+1]
+        pB = params[self.end_index[4]+2]
+        kex_BC = params[self.end_index[4]+3]
+        kex_AC = params[self.end_index[4]+4]
+
+        # Calculate and return the chi-squared value.
+        return self.calc_ns_mmq_3site_chi2(R20A=R20, R20B=R20, R20C=R20, 
dw_AB=dw_AB, dw_BC=dw_BC, dwH_AB=dwH_AB, dwH_BC=dwH_BC, pA=pA, pB=pB, 
kex_AB=kex_AB, kex_BC=kex_BC, kex_AC=kex_AC)
+
+
+    def func_ns_mmq_3site_linear(self, params):
+        """Target function for the combined SQ, ZQ, DQ and MQ 3-site 
linearised MMQ CPMG numeric solution.
+
+        @param params:  The vector of parameter values.
+        @type params:   numpy rank-1 float array
+        @return:        The chi-squared value.
+        @rtype:         float
+        """
+
+        # Scaling.
+        if self.scaling_flag:
+            params = dot(params, self.scaling_matrix)
+
+        # Unpack the parameter values.
+        R20 = params[:self.end_index[0]]
+        dw_AB = params[self.end_index[0]:self.end_index[1]]
+        dw_BC = params[self.end_index[1]:self.end_index[2]]
+        dwH_AB = params[self.end_index[2]:self.end_index[3]]
+        dwH_BC = params[self.end_index[3]:self.end_index[4]]
+        pA = params[self.end_index[4]]
+        kex_AB = params[self.end_index[4]+1]
+        pB = params[self.end_index[4]+2]
+        kex_BC = params[self.end_index[4]+3]
+
+        # Calculate and return the chi-squared value.
+        return self.calc_ns_mmq_3site_chi2(R20A=R20, R20B=R20, R20C=R20, 
dw_AB=dw_AB, dw_BC=dw_BC, dwH_AB=dwH_AB, dwH_BC=dwH_BC, pA=pA, pB=pB, 
kex_AB=kex_AB, kex_BC=kex_BC, kex_AC=0.0)
+
+
     def func_ns_r1rho_2site(self, params):
         """Target function for the reduced numerical solution for the 2-site 
Bloch-McConnell equations for R1rho data.
 




Related Messages


Powered by MHonArc, Updated Tue Dec 03 17:40:01 2013