Hi Troels,

Have a look at this commit to the trunk:

http://www.mail-archive.com/[email protected]/msg20984.html

Clearly kex = 1e5 is one of these edge cases where all R2eff must be
set to R20 (this actually depends a little bit on dw too).  But we
probably should not catch this in the lib.dispersion modules.  It is
the model itself which should model this correctly - and I know that
some cannot.  If you use this test for the other models, you'll see
for yourself.

Regards,

Edward







On 22 May 2014 19:32, Edward d'Auvergne <[email protected]> wrote:
> Hmmm, interesting.  I might need some time thinking about the opposite
> type of unit test - the edge cases where R2eff should be Inf rather
> than R20.  It should be easy enough to create a unit test with kex set
> to something big, say 1e6, and then see what happens with and without
> the check.  But at some point you'll be fast enough that you won't see
> exchange any more, so really high kex values should also cause R2eff
> to be set to R20.  Take an extreme example of tex = 1 ns.rad^-1 (i.e.
> kex = 1/tex = 1e8).  This is the same time scale as the fast Lipari
> and Szabo model-free dynamics.  So you would see something in a
> model-free analysis but absolutely nothing in a dispersion analysis.
> I wonder if our dispersion models capture this condition correctly?
>
> Regards,
>
> Edward
>
>
> On 22 May 2014 19:19, Troels Emtekær Linnet <[email protected]> wrote:
>> I am more afraid for the cases when kex is 10000, or something similar.
>>
>> This was what happened in:
>> https://gna.org/bugs/index.php?22032
>> bug #22032: Minimisation explodes when using Grid_INC=None
>>
>> Best
>> Troels
>>
>>
>> 2014-05-22 19:03 GMT+02:00 Edward d'Auvergne <[email protected]>:
>>> Hi Troels,
>>>
>>> Now that the 'no Rex' unit tests for this LM63 model have been
>>> implemented, I tried out the following in your branch:
>>>
>>> """
>>> Index: lib/dispersion/lm63.py
>>> ===================================================================
>>> --- lib/dispersion/lm63.py      (revision 23355)
>>> +++ lib/dispersion/lm63.py      (working copy)
>>> @@ -99,11 +99,4 @@
>>>      kex_4 = 4.0 / kex
>>>
>>>      # Calculate R2eff.
>>> -    R2eff = r20 + rex * (1.0 - kex_4 * cpmg_frqs * tanh(kex / (4.0 *
>>> cpmg_frqs)))
>>> -
>>> -    # Catch errors, taking a sum over array is the fastest way to check for
>>> -    # +/- inf (infinity) and nan (not a number).
>>> -    if not isfinite(sum(R2eff)):
>>> -        R2eff = array([1e100]*num_points)
>>> -
>>> -    return R2eff
>>> \ No newline at end of file
>>> +    return r20 + rex * (1.0 - kex_4 * cpmg_frqs * tanh(kex / (4.0 *
>>> cpmg_frqs)))
>>> """
>>>
>>> This change does not effect any system or unit test in the test suite,
>>> even with the --numpy-raise flag!  The infinite condition appears to
>>> be gone now that there are 'no Rex' checks on the first lines of the
>>> R2eff calculating function.  You can do your own testing and see.  The
>>> catching of 'no Rex' at the start might allow us to remove many other
>>> checks, speeding up the code a little.
>>>
>>> Regards,
>>>
>>> Edward
>>>
>>>
>>> On 22 May 2014 18:27,  <[email protected]> wrote:
>>>> Author: tlinnet
>>>> Date: Thu May 22 18:27:42 2014
>>>> New Revision: 23349
>>>>
>>>> URL: http://svn.gna.org/viewcvs/relax?rev=23349&view=rev
>>>> Log:
>>>> Added 7 unit tests demonstrating edge case 'no Rex' failures of the model 
>>>> 'LM63'.
>>>>
>>>> This follows from the ideas in the post 
>>>> http://article.gmane.org/gmane.science.nmr.relax.devel/5858.
>>>> This is related to: task #7793: (https://gna.org/task/?7793) Speed-up of 
>>>> dispersion models.
>>>>
>>>> This is to implement catching of math domain errors, before they occur.
>>>>
>>>> These tests cover all parameter value combinations which result in no 
>>>> exchange:
>>>>
>>>>     - dw = 0.0,
>>>>     - pA = 1.0,
>>>>     - kex = 0.0,
>>>>     - dw = 0.0 and pA = 1.0,
>>>>     - dw = 0.0 and kex = 0.0,
>>>>     - pA = 1.0 and kex = 0.0,
>>>>     - dw = 0.0, pA = 1.0, and kex = 0.0.
>>>>
>>>> Modified:
>>>>     branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/__init__.py
>>>>     branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/test_lm63.py
>>>>
>>>> Modified: 
>>>> branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/__init__.py
>>>> URL: 
>>>> http://svn.gna.org/viewcvs/relax/branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/__init__.py?rev=23349&r1=23348&r2=23349&view=diff
>>>> ==============================================================================
>>>> --- branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/__init__.py 
>>>>      (original)
>>>> +++ branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/__init__.py 
>>>>      Thu May 22 18:27:42 2014
>>>> @@ -1,6 +1,7 @@
>>>>  
>>>> ###############################################################################
>>>>  #                                                                         
>>>>     #
>>>>  # Copyright (C) 2013-2014 Edward d'Auvergne                               
>>>>     #
>>>> +# Copyright (C) 2013-2014 Troels E. Linnet                                
>>>>     #
>>>>  #                                                                         
>>>>     #
>>>>  # This file is part of the program relax (http://www.nmr-relax.com).      
>>>>     #
>>>>  #                                                                         
>>>>     #
>>>> @@ -23,5 +24,6 @@
>>>>  __all__ = [
>>>>      'test___init__',
>>>>      'test_dpl94',
>>>> +    'test_lm63',
>>>>      'test_ns_cpmg_2site_expanded'
>>>>  ]
>>>>
>>>> Modified: 
>>>> branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/test_lm63.py
>>>> URL: 
>>>> http://svn.gna.org/viewcvs/relax/branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/test_lm63.py?rev=23349&r1=23348&r2=23349&view=diff
>>>> ==============================================================================
>>>> --- 
>>>> branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/test_lm63.py    
>>>>  (original)
>>>> +++ 
>>>> branches/disp_speed/test_suite/unit_tests/_lib/_dispersion/test_lm63.py    
>>>>  Thu May 22 18:27:42 2014
>>>> @@ -1,6 +1,7 @@
>>>>  
>>>> ###############################################################################
>>>>  #                                                                         
>>>>     #
>>>>  # Copyright (C) 2014 Edward d'Auvergne                                    
>>>>     #
>>>> +# Copyright (C) 2014 Troels E. Linnet                                     
>>>>     #
>>>>  #                                                                         
>>>>     #
>>>>  # This file is part of the program relax (http://www.nmr-relax.com).      
>>>>     #
>>>>  #                                                                         
>>>>     #
>>>> @@ -20,15 +21,15 @@
>>>>  
>>>> ###############################################################################
>>>>
>>>>  # Python module imports.
>>>> -from numpy import array, float64, int16, zeros
>>>> +from numpy import array, float64, int16, pi, zeros
>>>>  from unittest import TestCase
>>>>
>>>>  # relax module imports.
>>>> -from lib.dispersion.ns_cpmg_2site_expanded import 
>>>> r2eff_ns_cpmg_2site_expanded
>>>> +from lib.dispersion.lm63 import r2eff_LM63
>>>>
>>>>
>>>> -class Test_ns_cpmg_2site_expanded(TestCase):
>>>> -    """Unit tests for the lib.dispersion.ns_cpmg_2site_expanded relax 
>>>> module."""
>>>> +class Test_lm63(TestCase):
>>>> +    """Unit tests for the lib.dispersion.lm63 relax module."""
>>>>
>>>>      def setUp(self):
>>>>          """Set up for all unit tests."""
>>>> @@ -39,51 +40,59 @@
>>>>          self.dw = 0.5
>>>>          self.kex = 100.0
>>>>
>>>> +        # The spin Larmor frequencies.
>>>> +        self.sfrq = 599.8908617*1E6
>>>> +
>>>>          # Required data structures.
>>>>          self.num_points = 3
>>>> -        self.tcp = array([0.1, 0.2, 0.3], float64)
>>>> +        self.cpmg_frqs = array([[2.5, 1.25, 0.83]], float64)
>>>>          self.R2eff = zeros(3, float64)
>>>> -        self.num_cpmg = array([1, 2, 3], int16)
>>>>
>>>>
>>>>      def calc_r2eff(self):
>>>>          """Calculate and check the R2eff values."""
>>>>
>>>>          # Parameter conversions.
>>>> -        k_AB, k_BA = self.param_conversion(pA=self.pA, kex=self.kex)
>>>> +        phi_ex_scaled = self.param_conversion(pA=self.pA, dw=self.dw, 
>>>> sfrq=self.sfrq)
>>>>
>>>>          # Calculate the R2eff values.
>>>> -        R2eff = r2eff_ns_cpmg_2site_expanded(r20=self.r20, pA=self.pA, 
>>>> dw=self.dw, k_AB=k_AB, k_BA=k_BA, relax_time=0.3, inv_relax_time=1/0.3, 
>>>> tcp=self.tcp, num_points=self.num_points, num_cpmg=self.num_cpmg)
>>>> -
>>>> +        R2eff = r2eff_LM63(r20=self.r20, phi_ex=phi_ex_scaled, 
>>>> kex=self.kex, cpmg_frqs=self.cpmg_frqs, num_points=self.num_points)
>>>>          # Check all R2eff values.
>>>>          for i in range(self.num_points):
>>>>              self.assertAlmostEqual(R2eff[i], self.r20)
>>>>
>>>>
>>>> -    def param_conversion(self, pA=None, kex=None):
>>>> +    def param_conversion(self, pA=None, dw=None, sfrq=None):
>>>>          """Convert the parameters.
>>>>
>>>>          @keyword pA:    The population of state A.
>>>>          @type pA:       float
>>>> -        @keyword kex:   The rate of exchange.
>>>> -        @type kex:      float
>>>> -        @return:        The parameters {k_AB, k_BA}.
>>>> -        @rtype:         tuple of float
>>>> +        @keyword dw:    The chemical exchange difference between states A 
>>>> and B in ppm.
>>>> +        @type dw:       float
>>>> +        @keyword sfrq:  The spin Larmor frequencies in Hz.
>>>> +        @type sfrq:     float
>>>> +        @return:        The parameters phi_ex_scaled
>>>> +        @rtype:         float
>>>>          """
>>>>
>>>>          # Calculate pB.
>>>>          pB = 1.0 - pA
>>>>
>>>> -        # Exchange rates.
>>>> -        k_BA = pA * kex
>>>> -        k_AB = pB * kex
>>>> +        # Calculate spin Larmor frequencies in 2pi.
>>>> +        frqs = sfrq * 2 * pi
>>>> +
>>>> +        # The phi_ex parameter value (pA * pB * delta_omega^2).
>>>> +        phi_ex = pA * pB * dw**2
>>>> +
>>>> +        # Convert phi_ex from ppm^2 to (rad/s)^2.
>>>> +        phi_ex_scaled = phi_ex * frqs**2
>>>>
>>>>          # Return all values.
>>>> -        return k_AB, k_BA
>>>> +        return phi_ex_scaled
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex1(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when dw = 0.0."""
>>>> +    def test_lm63_no_rex1(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when dw = 
>>>> 0.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.dw = 0.0
>>>> @@ -92,8 +101,8 @@
>>>>          self.calc_r2eff()
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex2(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when pA = 1.0."""
>>>> +    def test_lm63_no_rex2(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when pA = 
>>>> 1.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.pA = 1.0
>>>> @@ -102,8 +111,8 @@
>>>>          self.calc_r2eff()
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex3(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when kex = 0.0."""
>>>> +    def test_lm63_no_rex3(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when kex = 
>>>> 0.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.kex = 0.0
>>>> @@ -112,8 +121,8 @@
>>>>          self.calc_r2eff()
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex4(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when dw = 0.0 and pA = 1.0."""
>>>> +    def test_lm63_no_rex4(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when dw = 0.0 
>>>> and pA = 1.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.pA = 1.0
>>>> @@ -123,8 +132,8 @@
>>>>          self.calc_r2eff()
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex5(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when dw = 0.0 and kex = 0.0."""
>>>> +    def test_lm63_no_rex5(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when dw = 0.0 
>>>> and kex = 0.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.dw = 0.0
>>>> @@ -134,8 +143,8 @@
>>>>          self.calc_r2eff()
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex6(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when pA = 1.0 and kex = 0.0."""
>>>> +    def test_lm63_no_rex6(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when pA = 1.0 
>>>> and kex = 0.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.pA = 1.0
>>>> @@ -145,8 +154,8 @@
>>>>          self.calc_r2eff()
>>>>
>>>>
>>>> -    def test_ns_cpmg_2site_expanded_no_rex7(self):
>>>> -        """Test the r2eff_ns_cpmg_2site_expanded() function for no 
>>>> exchange when dw = 0.0, pA = 1.0, and kex = 0.0."""
>>>> +    def test_lm63_no_rex7(self):
>>>> +        """Test the r2eff_lm63() function for no exchange when dw = 0.0, 
>>>> pA = 1.0, and kex = 0.0."""
>>>>
>>>>          # Parameter reset.
>>>>          self.dw = 0.0
>>>>
>>>>
>>>> _______________________________________________
>>>> relax (http://www.nmr-relax.com)
>>>>
>>>> This is the relax-commits mailing list
>>>> [email protected]
>>>>
>>>> To unsubscribe from this list, get a password
>>>> reminder, or change your subscription options,
>>>> visit the list information page at
>>>> https://mail.gna.org/listinfo/relax-commits
>>>
>>> _______________________________________________
>>> relax (http://www.nmr-relax.com)
>>>
>>> This is the relax-devel mailing list
>>> [email protected]
>>>
>>> To unsubscribe from this list, get a password
>>> reminder, or change your subscription options,
>>> visit the list information page at
>>> https://mail.gna.org/listinfo/relax-devel

_______________________________________________
relax (http://www.nmr-relax.com)

This is the relax-devel mailing list
[email protected]

To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-devel

Reply via email to