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  """The numerical solution for the 3-site Bloch-McConnell equations for R1rho-type data, the U{NS R1rho 3-site linear<http://wiki.nmr-relax.com/NS_R1rho_3-site_linear>} and U{NS R1rho 3-site<http://wiki.nmr-relax.com/NS_R1rho_3-site>} model. 
 26   
 27  Description 
 28  =========== 
 29   
 30  This is the model of the numerical solution for the 3-site Bloch-McConnell equations.  It originates from the funNumrho.m file from the Skrynikov & Tollinger code (the sim_all.tar file U{https://web.archive.org/web/https://gna.org/support/download.php?file_id=18404} attached to U{https://web.archive.org/web/https://gna.org/task/?7712#comment5}). 
 31   
 32   
 33  References 
 34  ========== 
 35   
 36  The solution has been modified to use the from presented in: 
 37   
 38      - Korzhnev, D. M., Orekhov, V. Y., and Kay, L. E. (2005).  Off-resonance R(1rho) NMR studies of exchange dynamics in proteins with low spin-lock fields:  an application to a Fyn SH3 domain.  I{J. Am. Chem. Soc.}, B{127}, 713-721. (U{DOI: 10.1021/ja0446855<http://dx.doi.org/10.1021/ja0446855>}). 
 39   
 40   
 41  Links 
 42  ===== 
 43   
 44  More information on the NS R1rho 3-site linear model can be found in the: 
 45   
 46      - U{relax wiki<http://wiki.nmr-relax.com/NS_R1rho_3-site_linear>}, 
 47      - U{relax manual<http://www.nmr-relax.com/manual/NS_3_site_linear_R1_model.html>}, 
 48      - U{relaxation dispersion page of the relax website<http://www.nmr-relax.com/analyses/relaxation_dispersion.html#NS_R1rho_3-site_linear>}. 
 49   
 50  More information on the NS R1rho 3-site model can be found in the: 
 51   
 52      - U{relax wiki<http://wiki.nmr-relax.com/NS_R1rho_3-site>}, 
 53      - U{relax manual<http://www.nmr-relax.com/manual/NS_3_site_R1_model.html>}, 
 54      - U{relaxation dispersion page of the relax website<http://www.nmr-relax.com/analyses/relaxation_dispersion.html#NS_R1rho_3-site>}. 
 55  """ 
 56   
 57   
 58  from math import atan2, cos, log, sin 
 59  from numpy import dot 
 60   
 61   
 62  from lib.dispersion.ns_matrices import rr1rho_3d_3site 
 63  from lib.float import isNaN 
 64  from lib.linear_algebra.matrix_exponential import matrix_exponential 
 65   
 66   
 67 -def ns_r1rho_3site(M0=None, matrix=None, r1rho_prime=None, omega=None, offset=None, r1=0.0, pA=None, pB=None, pC=None, dw_AB=None, dw_AC=None, k_AB=None, k_BA=None, k_BC=None, k_CB=None, k_AC=None, k_CA=None, spin_lock_fields=None, relax_time=None, inv_relax_time=None, back_calc=None, num_points=None): 
  68      """The 3-site numerical solution to the Bloch-McConnell equation for R1rho data. 
 69   
 70      This function calculates and stores the R1rho values. 
 71   
 72   
 73      @keyword M0:                This is a vector that contains the initial magnetizations corresponding to the A and B state transverse magnetizations. 
 74      @type M0:                   numpy float64, rank-1, 7D array 
 75      @keyword matrix:            A numpy array to be populated to create the evolution matrix. 
 76      @type matrix:               numpy rank-2, 9D float64 array 
 77      @keyword r1rho_prime:       The R1rho_prime parameter value (R1rho with no exchange). 
 78      @type r1rho_prime:          float 
 79      @keyword omega:             The chemical shift for the spin in rad/s. 
 80      @type omega:                float 
 81      @keyword offset:            The spin-lock offsets for the data. 
 82      @type offset:               numpy rank-1 float array 
 83      @keyword r1:                The R1 relaxation rate. 
 84      @type r1:                   float 
 85      @keyword pA:                The population of state A. 
 86      @type pA:                   float 
 87      @keyword pB:                The population of state B. 
 88      @type pB:                   float 
 89      @keyword pC:                The population of state C. 
 90      @type pC:                   float 
 91      @keyword dw_AB:             The chemical exchange difference between states A and B in rad/s. 
 92      @type dw_AB:                float 
 93      @keyword dw_AC:             The chemical exchange difference between states A and C in rad/s. 
 94      @type dw_AC:                float 
 95      @keyword k_AB:              The rate of exchange from site A to B (rad/s). 
 96      @type k_AB:                 float 
 97      @keyword k_BA:              The rate of exchange from site B to A (rad/s). 
 98      @type k_BA:                 float 
 99      @keyword k_BC:              The rate of exchange from site B to C (rad/s). 
100      @type k_BC:                 float 
101      @keyword k_CB:              The rate of exchange from site C to B (rad/s). 
102      @type k_CB:                 float 
103      @keyword k_AC:              The rate of exchange from site A to C (rad/s). 
104      @type k_AC:                 float 
105      @keyword k_CA:              The rate of exchange from site C to A (rad/s). 
106      @type k_CA:                 float 
107      @keyword spin_lock_fields:  The R1rho spin-lock field strengths (in rad.s^-1). 
108      @type spin_lock_fields:     numpy rank-1 float array 
109      @keyword relax_time:        The total relaxation time period for each spin-lock field strength (in seconds). 
110      @type relax_time:           float 
111      @keyword inv_relax_time:    The inverse of the relaxation time period for each spin-lock field strength (in inverse seconds).  This is used for faster calculations. 
112      @type inv_relax_time:       float 
113      @keyword back_calc:         The array for holding the back calculated R2eff values.  Each element corresponds to one of the CPMG nu1 frequencies. 
114      @type back_calc:            numpy rank-1 float array 
115      @keyword num_points:        The number of points on the dispersion curve, equal to the length of the tcp and back_calc arguments. 
116      @type num_points:           int 
117      """ 
118   
119       
120      Wa = omega                   
121      Wb = omega + dw_AB           
122      Wc = omega + dw_AC           
123      W = pA*Wa + pB*Wb + pC*Wc    
124      dA = Wa - offset             
125      dB = Wb - offset             
126      dC = Wc - offset             
127      d = W - offset               
128   
129       
130      for i in range(num_points): 
131           
132          rr1rho_3d_3site(matrix=matrix, R1=r1, r1rho_prime=r1rho_prime, pA=pA, pB=pB, pC=pC, wA=dA, wB=dB, wC=dC, w1=spin_lock_fields[i], k_AB=k_AB, k_BA=k_BA, k_BC=k_BC, k_CB=k_CB, k_AC=k_AC, k_CA=k_CA) 
133   
134           
135          theta = atan2(spin_lock_fields[i], dA) 
136          M0[0] = sin(theta)     
137          M0[2] = cos(theta)     
138   
139           
140          Rexpo = matrix_exponential(matrix*relax_time) 
141   
142           
143          MA = dot(M0, dot(Rexpo, M0)) 
144   
145           
146          if MA <= 0.0 or isNaN(MA): 
147              back_calc[i] = 1e99 
148          else: 
149              back_calc[i]= -inv_relax_time * log(MA) 
 150