source: sasview/test/sasinvariant/test/utest_data_handling.py @ f53d684

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since f53d684 was f53d684, checked in by Paul Kienzle <pkienzle@…>, 6 years ago

Make tests work from any directory and functional without special runner script (#124)

  • Property mode set to 100644
File size: 26.7 KB
RevLine 
[46d50ca]1"""
2This software was developed by the University of Tennessee as part of the
3Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
4project funded by the US National Science Foundation.
5
6See the license text in license.txt
7
8copyright 2010, University of Tennessee
9"""
[f53d684]10
11import os.path
[46d50ca]12import unittest
[9a5097c]13import math
14import numpy as np
[b699768]15from sas.sascalc.dataloader.loader import  Loader
16from sas.sascalc.dataloader.data_info import Data1D
17
18from sas.sascalc.invariant import invariant
[f53d684]19
20
21def find(filename):
22    return os.path.join(os.path.dirname(__file__), filename)
23
24
[46d50ca]25class TestLinearFit(unittest.TestCase):
26    """
27        Test Line fit
28    """
29    def setUp(self):
[9a5097c]30        x = np.asarray([1.,2.,3.,4.,5.,6.,7.,8.,9.])
31        y = np.asarray([1.,2.,3.,4.,5.,6.,7.,8.,9.])
[46d50ca]32        dy = y/10.0
33       
34        self.data = Data1D(x=x,y=y,dy=dy)
35       
36    def test_fit_linear_data(self):
37        """
38            Simple linear fit
39        """
40       
41        # Create invariant object. Background and scale left as defaults.
[aafa962]42        fit = invariant.Extrapolator(data=self.data)
[bdd162f]43        #a,b = fit.fit()
44        p, dp = fit.fit()
[46d50ca]45
46        # Test results
[bdd162f]47        self.assertAlmostEquals(p[0], 1.0, 5)
48        self.assertAlmostEquals(p[1], 0.0, 5)
[46d50ca]49
50    def test_fit_linear_data_with_noise(self):
51        """
52            Simple linear fit with noise
53        """
54        import random, math
55       
56        for i in range(len(self.data.y)):
[bdd162f]57            self.data.y[i] = self.data.y[i]+.1*(random.random()-0.5)
[46d50ca]58           
59        # Create invariant object. Background and scale left as defaults.
[aafa962]60        fit = invariant.Extrapolator(data=self.data)
[bdd162f]61        p, dp = fit.fit()
[46d50ca]62
63        # Test results
[bdd162f]64        self.assertTrue(math.fabs(p[0]-1.0)<0.05)
65        self.assertTrue(math.fabs(p[1])<0.1)       
66       
67    def test_fit_with_fixed_parameter(self):
68        """
69            Linear fit for y=ax+b where a is fixed.
70        """
71        # Create invariant object. Background and scale left as defaults.
72        fit = invariant.Extrapolator(data=self.data)
73        p, dp = fit.fit(power=-1.0)
74
75        # Test results
76        self.assertAlmostEquals(p[0], 1.0, 5)
77        self.assertAlmostEquals(p[1], 0.0, 5)
78
79    def test_fit_linear_data_with_noise_and_fixed_par(self):
80        """
81            Simple linear fit with noise
82        """
83        import random, math
84       
85        for i in range(len(self.data.y)):
86            self.data.y[i] = self.data.y[i]+.1*(random.random()-0.5)
87           
88        # Create invariant object. Background and scale left as defaults.
89        fit = invariant.Extrapolator(data=self.data)
90        p, dp = fit.fit(power=-1.0)
91
92        # Test results
93        self.assertTrue(math.fabs(p[0]-1.0)<0.05)
94        self.assertTrue(math.fabs(p[1])<0.1)       
95       
96
97
[46d50ca]98class TestInvariantCalculator(unittest.TestCase):
99    """
[bdd162f]100        Test main functionality of the Invariant calculator
[46d50ca]101    """
102    def setUp(self):
[f53d684]103        data = Loader().load(find("latex_smeared_slit.xml"))
[be577e7]104        self.data = data[0]
[8a9f699]105        self.data.dxl = None
[46d50ca]106       
107    def test_initial_data_processing(self):
108        """
109            Test whether the background and scale are handled properly
110            when creating an InvariantCalculator object
111        """
112        length = len(self.data.x)
113        self.assertEqual(length, len(self.data.y))
114        inv = invariant.InvariantCalculator(self.data)
115       
116        self.assertEqual(length, len(inv._data.x))
117        self.assertEqual(inv._data.x[0], self.data.x[0])
118
119        # Now the same thing with a background value
120        bck = 0.1
121        inv = invariant.InvariantCalculator(self.data, background=bck)
122        self.assertEqual(inv._background, bck)
123       
124        self.assertEqual(length, len(inv._data.x))
125        self.assertEqual(inv._data.y[0]+bck, self.data.y[0])
126       
127        # Now the same thing with a scale value
128        scale = 0.1
129        inv = invariant.InvariantCalculator(self.data, scale=scale)
130        self.assertEqual(inv._scale, scale)
131       
132        self.assertEqual(length, len(inv._data.x))
133        self.assertAlmostEqual(inv._data.y[0]/scale, self.data.y[0],7)
134       
135   
136    def test_incompatible_data_class(self):
137        """
138            Check that only classes that inherit from Data1D are allowed as data.
139        """
140        class Incompatible():
141            pass
142        self.assertRaises(ValueError, invariant.InvariantCalculator, Incompatible())
[bdd162f]143       
144    def test_error_treatment(self):
[9a5097c]145        x = np.asarray(np.asarray([0,1,2,3]))
146        y = np.asarray(np.asarray([1,1,1,1]))
[bdd162f]147       
148        # These are all the values of the dy array that would cause
149        # us to set all dy values to 1.0 at __init__ time.
150        dy_list = [ [], None, [0,0,0,0] ]
151       
152        for dy in dy_list:
153            data = Data1D(x=x, y=y, dy=dy)
154            inv = invariant.InvariantCalculator(data)
155            self.assertEqual(len(inv._data.x), len(inv._data.dy))
156            self.assertEqual(len(inv._data.dy), 4)
157            for i in range(4):
158                self.assertEqual(inv._data.dy[i],1)
159               
160    def test_qstar_low_q_guinier(self):
161        """
162            Test low-q extrapolation with a Guinier
163        """
164        inv = invariant.InvariantCalculator(self.data)
165       
166        # Basic sanity check
167        _qstar = inv.get_qstar()
168        qstar, dqstar = inv.get_qstar_with_error()
169        self.assertEqual(qstar, _qstar)
170       
171        # Low-Q Extrapolation
172        # Check that the returned invariant is what we expect given
173        # the result we got without extrapolation
174        inv.set_extrapolation('low', npts=10, function='guinier')
175        qs_extr, dqs_extr = inv.get_qstar_with_error('low')
176        delta_qs_extr, delta_dqs_extr = inv.get_qstar_low()
177       
178        self.assertEqual(qs_extr, _qstar+delta_qs_extr)
179        self.assertEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_extr*delta_dqs_extr))
180       
181        # We don't expect the extrapolated invariant to be very far from the
182        # result without extrapolation. Let's test for a result within 10%.
183        self.assertTrue(math.fabs(qs_extr-qstar)/qstar<0.1)
184       
185        # Check that the two results are consistent within errors
186        # Note that the error on the extrapolated value takes into account
187        # a systematic error for the fact that we may not know the shape of I(q) at low Q.
188        self.assertTrue(math.fabs(qs_extr-qstar)<dqs_extr)
189       
190    def test_qstar_low_q_power_law(self):
191        """
192            Test low-q extrapolation with a power law
193        """
194        inv = invariant.InvariantCalculator(self.data)
195       
196        # Basic sanity check
197        _qstar = inv.get_qstar()
198        qstar, dqstar = inv.get_qstar_with_error()
199        self.assertEqual(qstar, _qstar)
200       
201        # Low-Q Extrapolation
202        # Check that the returned invariant is what we expect given
203        inv.set_extrapolation('low', npts=10, function='power_law')
204        qs_extr, dqs_extr = inv.get_qstar_with_error('low')
205        delta_qs_extr, delta_dqs_extr = inv.get_qstar_low()
206       
[8c9ffde]207        # A fit using SasView gives 0.0655 for the value of the exponent
[bdd162f]208        self.assertAlmostEqual(inv._low_extrapolation_function.power, 0.0655, 3)
209       
210        if False:
211            npts = len(inv._data.x)-1
212            import matplotlib.pyplot as plt
213            plt.loglog(inv._data.x[:npts], inv._data.y[:npts], 'o', label='Original data', markersize=10)
214            plt.loglog(inv._data.x[:npts], inv._low_extrapolation_function.evaluate_model(inv._data.x[:npts]), 'r', label='Fitted line')
215            plt.legend()
216            plt.show()       
217       
218        self.assertEqual(qs_extr, _qstar+delta_qs_extr)
[6574940a]219        self.assertAlmostEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_extr*delta_dqs_extr), 15)
[bdd162f]220       
221        # We don't expect the extrapolated invariant to be very far from the
222        # result without extrapolation. Let's test for a result within 10%.
223        self.assertTrue(math.fabs(qs_extr-qstar)/qstar<0.1)
224       
225        # Check that the two results are consistent within errors
226        # Note that the error on the extrapolated value takes into account
227        # a systematic error for the fact that we may not know the shape of I(q) at low Q.
228        self.assertTrue(math.fabs(qs_extr-qstar)<dqs_extr)
229       
230    def test_qstar_high_q(self):
231        """
232            Test high-q extrapolation
233        """
234        inv = invariant.InvariantCalculator(self.data)
235       
236        # Basic sanity check
237        _qstar = inv.get_qstar()
238        qstar, dqstar = inv.get_qstar_with_error()
239        self.assertEqual(qstar, _qstar)
240       
241        # High-Q Extrapolation
242        # Check that the returned invariant is what we expect given
243        # the result we got without extrapolation
244        inv.set_extrapolation('high', npts=20, function='power_law')
245        qs_extr, dqs_extr = inv.get_qstar_with_error('high')
246        delta_qs_extr, delta_dqs_extr = inv.get_qstar_high()
247       
[8c9ffde]248        # From previous analysis using SasView, we expect an exponent of about 3
[bdd162f]249        self.assertTrue(math.fabs(inv._high_extrapolation_function.power-3)<0.1)
250       
251        self.assertEqual(qs_extr, _qstar+delta_qs_extr)
[c4f79f0]252        self.assertAlmostEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_extr*delta_dqs_extr), 10)
[bdd162f]253       
254        # We don't expect the extrapolated invariant to be very far from the
255        # result without extrapolation. Let's test for a result within 10%.
256        #TODO: verify whether this test really makes sense
257        #self.assertTrue(math.fabs(qs_extr-qstar)/qstar<0.1)
258       
259        # Check that the two results are consistent within errors
260        self.assertTrue(math.fabs(qs_extr-qstar)<dqs_extr)
261               
262    def test_qstar_full_q(self):
263        """
264            Test high-q extrapolation
265        """
266        inv = invariant.InvariantCalculator(self.data)
267       
268        # Basic sanity check
269        _qstar = inv.get_qstar()
270        qstar, dqstar = inv.get_qstar_with_error()
271        self.assertEqual(qstar, _qstar)
272       
273        # High-Q Extrapolation
274        # Check that the returned invariant is what we expect given
275        # the result we got without extrapolation
276        inv.set_extrapolation('low',  npts=10, function='guinier')
277        inv.set_extrapolation('high', npts=20, function='power_law')
278        qs_extr, dqs_extr = inv.get_qstar_with_error('both')
279        delta_qs_low, delta_dqs_low = inv.get_qstar_low()
280        delta_qs_hi,  delta_dqs_hi = inv.get_qstar_high()
281       
282        self.assertAlmostEqual(qs_extr, _qstar+delta_qs_low+delta_qs_hi, 8)
[97700d7]283        self.assertAlmostEqual(dqs_extr, math.sqrt(dqstar*dqstar + delta_dqs_low*delta_dqs_low \
284                                             + delta_dqs_hi*delta_dqs_hi), 8)
[bdd162f]285       
286        # We don't expect the extrapolated invariant to be very far from the
287        # result without extrapolation. Let's test for a result within 10%.
288        #TODO: verify whether this test really makes sense
289        #self.assertTrue(math.fabs(qs_extr-qstar)/qstar<0.1)
290       
291        # Check that the two results are consistent within errors
292        self.assertTrue(math.fabs(qs_extr-qstar)<dqs_extr)
293       
[c75a8ed]294        def _check_values(to_check, reference, tolerance=0.05):
295            self.assertTrue( math.fabs(to_check-reference)/reference < tolerance, msg="Tested value = "+str(to_check) )
296           
297        # The following values should be replaced by values pulled from IGOR
298        # Volume Fraction:
299        v, dv = inv.get_volume_fraction_with_error(1, None)
300        _check_values(v, 1.88737914186e-15)
301
302        v_l, dv_l = inv.get_volume_fraction_with_error(1, 'low')
303        _check_values(v_l, 1.94289029309e-15)
304
305        v_h, dv_h = inv.get_volume_fraction_with_error(1, 'high')
306        _check_values(v_h, 6.99440505514e-15)
307       
308        v_b, dv_b = inv.get_volume_fraction_with_error(1, 'both')
309        _check_values(v_b, 6.99440505514e-15)
310       
311        # Specific Surface:
312        s, ds = inv.get_surface_with_error(1, 1, None)
313        _check_values(s, 3.1603095786e-09)
314
315        s_l, ds_l = inv.get_surface_with_error(1, 1, 'low')
316        _check_values(s_l, 3.1603095786e-09)
317
318        s_h, ds_h = inv.get_surface_with_error(1, 1, 'high')
319        _check_values(s_h, 3.1603095786e-09)
320       
321        s_b, ds_b = inv.get_surface_with_error(1, 1, 'both')
322        _check_values(s_b, 3.1603095786e-09)
323       
324       
[bdd162f]325    def test_bad_parameter_name(self):
326        """
327            The set_extrapolation method checks that the name of the extrapolation
328            function and the name of the q-range to extrapolate (high/low) is
329            recognized.
330        """
331        inv = invariant.InvariantCalculator(self.data)
332        self.assertRaises(ValueError, inv.set_extrapolation, 'low', npts=4, function='not_a_name')
333        self.assertRaises(ValueError, inv.set_extrapolation, 'not_a_range', npts=4, function='guinier')
334        self.assertRaises(ValueError, inv.set_extrapolation, 'high', npts=4, function='guinier')
[46d50ca]335   
[6939bd4]336   
337class TestGuinierExtrapolation(unittest.TestCase):
338    """
339        Generate a Guinier distribution and verify that the extrapolation
340        produce the correct ditribution.
341    """
342   
343    def setUp(self):
344        """
345            Generate a Guinier distribution. After extrapolating, we will
346            verify that we obtain the scale and rg parameters
347        """
348        self.scale = 1.5
[aafa962]349        self.rg = 30.0
[9a5097c]350        x = np.arange(0.0001, 0.1, 0.0001)
351        y = np.asarray([self.scale * math.exp( -(q*self.rg)**2 / 3.0 ) for q in x])
[6939bd4]352        dy = y*.1
353        self.data = Data1D(x=x, y=y, dy=dy)
354       
355    def test_low_q(self):
356        """
357            Invariant with low-Q extrapolation
358        """
359        # Create invariant object. Background and scale left as defaults.
360        inv = invariant.InvariantCalculator(data=self.data)
361        # Set the extrapolation parameters for the low-Q range
362        inv.set_extrapolation(range='low', npts=20, function='guinier')
363       
364        self.assertEqual(inv._low_extrapolation_npts, 20)
[aafa962]365        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier)
[6939bd4]366       
367        # Data boundaries for fiiting
368        qmin = inv._data.x[0]
369        qmax = inv._data.x[inv._low_extrapolation_npts - 1]
370       
371        # Extrapolate the low-Q data
[bdd162f]372        inv._fit(model=inv._low_extrapolation_function,
[6939bd4]373                          qmin=qmin,
374                          qmax=qmax,
375                          power=inv._low_extrapolation_power)
[bdd162f]376        self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6)
377        self.assertAlmostEqual(self.rg, inv._low_extrapolation_function.radius, 6)
[6939bd4]378   
379
380class TestPowerLawExtrapolation(unittest.TestCase):
381    """
382        Generate a power law distribution and verify that the extrapolation
383        produce the correct ditribution.
384    """
385   
386    def setUp(self):
387        """
388            Generate a power law distribution. After extrapolating, we will
389            verify that we obtain the scale and m parameters
390        """
391        self.scale = 1.5
392        self.m = 3.0
[9a5097c]393        x = np.arange(0.0001, 0.1, 0.0001)
394        y = np.asarray([self.scale * math.pow(q ,-1.0*self.m) for q in x])
[6939bd4]395        dy = y*.1
396        self.data = Data1D(x=x, y=y, dy=dy)
397       
398    def test_low_q(self):
399        """
400            Invariant with low-Q extrapolation
401        """
402        # Create invariant object. Background and scale left as defaults.
403        inv = invariant.InvariantCalculator(data=self.data)
404        # Set the extrapolation parameters for the low-Q range
405        inv.set_extrapolation(range='low', npts=20, function='power_law')
406       
407        self.assertEqual(inv._low_extrapolation_npts, 20)
[aafa962]408        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.PowerLaw)
[6939bd4]409       
410        # Data boundaries for fitting
411        qmin = inv._data.x[0]
412        qmax = inv._data.x[inv._low_extrapolation_npts - 1]
413       
414        # Extrapolate the low-Q data
[bdd162f]415        inv._fit(model=inv._low_extrapolation_function,
[6939bd4]416                          qmin=qmin,
417                          qmax=qmax,
418                          power=inv._low_extrapolation_power)
419       
[bdd162f]420        self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6)
421        self.assertAlmostEqual(self.m, inv._low_extrapolation_function.power, 6)
[aafa962]422       
423class TestLinearization(unittest.TestCase):
424   
425    def test_guinier_incompatible_length(self):
426        g = invariant.Guinier()
[76c1727]427        data_in = Data1D(x=[1], y=[1,2], dy=None)
428        self.assertRaises(AssertionError, g.linearize_data, data_in)
429        data_in = Data1D(x=[1,1], y=[1,2], dy=[1])
430        self.assertRaises(AssertionError, g.linearize_data, data_in)
[aafa962]431   
432    def test_linearization(self):
433        """
434            Check that the linearization process filters out points
435            that can't be transformed
436        """
[9a5097c]437        x = np.asarray(np.asarray([0,1,2,3]))
438        y = np.asarray(np.asarray([1,1,1,1]))
[aafa962]439        g = invariant.Guinier()
[76c1727]440        data_in = Data1D(x=x, y=y)
441        data_out = g.linearize_data(data_in)
442        x_out, y_out, dy_out = data_out.x, data_out.y, data_out.dy
[aafa962]443        self.assertEqual(len(x_out), 3)
444        self.assertEqual(len(y_out), 3)
445        self.assertEqual(len(dy_out), 3)
[bdd162f]446       
447    def test_allowed_bins(self):
[9a5097c]448        x = np.asarray(np.asarray([0,1,2,3]))
449        y = np.asarray(np.asarray([1,1,1,1]))
450        dy = np.asarray(np.asarray([1,1,1,1]))
[bdd162f]451        g = invariant.Guinier()
452        data = Data1D(x=x, y=y, dy=dy)
453        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])
454
455        data = Data1D(x=y, y=x, dy=dy)
456        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])
[97603c0]457
[bdd162f]458        data = Data1D(x=dy, y=y, dy=x)
459        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])
[97603c0]460   
461class TestDataExtraLow(unittest.TestCase):
462    """
463        Generate a Guinier distribution and verify that the extrapolation
464        produce the correct ditribution. Tested if the data generated by the
465        invariant calculator is correct
466    """
467   
468    def setUp(self):
469        """
470            Generate a Guinier distribution. After extrapolating, we will
471            verify that we obtain the scale and rg parameters
472        """
473        self.scale = 1.5
474        self.rg = 30.0
[9a5097c]475        x = np.arange(0.0001, 0.1, 0.0001)
476        y = np.asarray([self.scale * math.exp( -(q*self.rg)**2 / 3.0 ) for q in x])
[97603c0]477        dy = y*.1
478        self.data = Data1D(x=x, y=y, dy=dy)
479       
480    def test_low_q(self):
481        """
482            Invariant with low-Q extrapolation with no slit smear
483        """
484        # Create invariant object. Background and scale left as defaults.
485        inv = invariant.InvariantCalculator(data=self.data)
486        # Set the extrapolation parameters for the low-Q range
[bdd162f]487        inv.set_extrapolation(range='low', npts=10, function='guinier')
[97603c0]488       
[bdd162f]489        self.assertEqual(inv._low_extrapolation_npts, 10)
[97603c0]490        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier)
491       
492        # Data boundaries for fiiting
493        qmin = inv._data.x[0]
494        qmax = inv._data.x[inv._low_extrapolation_npts - 1]
495       
496        # Extrapolate the low-Q data
[bdd162f]497        inv._fit(model=inv._low_extrapolation_function,
[97603c0]498                          qmin=qmin,
499                          qmax=qmax,
500                          power=inv._low_extrapolation_power)
[bdd162f]501        self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6)
502        self.assertAlmostEqual(self.rg, inv._low_extrapolation_function.radius, 6)
[97603c0]503       
504        qstar = inv.get_qstar(extrapolation='low')
505        test_y = inv._low_extrapolation_function.evaluate_model(x=self.data.x)
506        for i in range(len(self.data.x)):
[c75a8ed]507            value  = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i]
[97603c0]508            self.assert_(value < 0.001)
509           
[76c1727]510class TestDataExtraLowSlitGuinier(unittest.TestCase):
511    """
512        for a smear data, test that the fitting go through
[c75a8ed]513        real data for atleast the 2 first points
[76c1727]514    """
515   
516    def setUp(self):
517        """
518            Generate a Guinier distribution. After extrapolating, we will
519            verify that we obtain the scale and rg parameters
520        """
521        self.scale = 1.5
522        self.rg = 30.0
[9a5097c]523        x = np.arange(0.0001, 0.1, 0.0001)
524        y = np.asarray([self.scale * math.exp( -(q*self.rg)**2 / 3.0 ) for q in x])
[76c1727]525        dy = y*.1
526        self.data = Data1D(x=x, y=y, dy=dy)
527        self.npts = len(x)-10
528       
529    def test_low_q(self):
530        """
531            Invariant with low-Q extrapolation with slit smear
532        """
533        # Create invariant object. Background and scale left as defaults.
534        inv = invariant.InvariantCalculator(data=self.data)
535        # Set the extrapolation parameters for the low-Q range
536        inv.set_extrapolation(range='low', npts=self.npts, function='guinier')
537       
538        self.assertEqual(inv._low_extrapolation_npts, self.npts)
[97603c0]539        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier)
540       
541        # Data boundaries for fiiting
542        qmin = inv._data.x[0]
543        qmax = inv._data.x[inv._low_extrapolation_npts - 1]
544       
545        # Extrapolate the low-Q data
[bdd162f]546        inv._fit(model=inv._low_extrapolation_function,
[97603c0]547                          qmin=qmin,
548                          qmax=qmax,
549                          power=inv._low_extrapolation_power)
550     
551       
552        qstar = inv.get_qstar(extrapolation='low')
[c75a8ed]553
[76c1727]554        test_y = inv._low_extrapolation_function.evaluate_model(x=self.data.x[:inv._low_extrapolation_npts])
[c75a8ed]555        self.assert_(len(test_y) == len(self.data.y[:inv._low_extrapolation_npts]))
[97603c0]556       
[76c1727]557        for i in range(inv._low_extrapolation_npts):
[c75a8ed]558            value  = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i]
[97603c0]559            self.assert_(value < 0.001)
560           
[76c1727]561    def test_low_data(self):
562        """
563            Invariant with low-Q extrapolation with slit smear
564        """
565        # Create invariant object. Background and scale left as defaults.
566        inv = invariant.InvariantCalculator(data=self.data)
567        # Set the extrapolation parameters for the low-Q range
568        inv.set_extrapolation(range='low', npts=self.npts, function='guinier')
569       
570        self.assertEqual(inv._low_extrapolation_npts, self.npts)
571        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier)
572       
573        # Data boundaries for fiiting
574        qmin = inv._data.x[0]
575        qmax = inv._data.x[inv._low_extrapolation_npts - 1]
576       
577        # Extrapolate the low-Q data
[bdd162f]578        inv._fit(model=inv._low_extrapolation_function,
[76c1727]579                          qmin=qmin,
580                          qmax=qmax,
581                          power=inv._low_extrapolation_power)
582     
583       
584        qstar = inv.get_qstar(extrapolation='low')
585        #Compution the y 's coming out of the invariant when computing extrapolated
586        #low data . expect the fit engine to have been already called and the guinier
587        # to have the radius and the scale fitted
[c75a8ed]588        data_in_range = inv.get_extra_data_low(q_start=self.data.x[0], 
589                                               npts = inv._low_extrapolation_npts) 
[76c1727]590        test_y = data_in_range.y
[c75a8ed]591        self.assert_(len(test_y) == len(self.data.y[:inv._low_extrapolation_npts]))
[76c1727]592        for i in range(inv._low_extrapolation_npts):
[c75a8ed]593            value  = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i]
[76c1727]594            self.assert_(value < 0.001)   
[c75a8ed]595       
[97603c0]596           
[76c1727]597class TestDataExtraHighSlitPowerLaw(unittest.TestCase):
598    """
599        for a smear data, test that the fitting go through
[c75a8ed]600        real data for atleast the 2 first points
[76c1727]601    """
602   
603    def setUp(self):
604        """
605            Generate a Guinier distribution. After extrapolating, we will
606            verify that we obtain the scale and rg parameters
607        """
608        self.scale = 1.5
609        self.m = 3.0
[9a5097c]610        x = np.arange(0.0001, 0.1, 0.0001)
611        y = np.asarray([self.scale * math.pow(q ,-1.0*self.m) for q in x])
[76c1727]612        dy = y*.1
613        self.data = Data1D(x=x, y=y, dy=dy)
614        self.npts = 20
615       
616    def test_high_q(self):
617        """
618            Invariant with high-Q extrapolation with slit smear
619        """
620        # Create invariant object. Background and scale left as defaults.
621        inv = invariant.InvariantCalculator(data=self.data)
622        # Set the extrapolation parameters for the low-Q range
623        inv.set_extrapolation(range='high', npts=self.npts, function='power_law')
624       
625        self.assertEqual(inv._high_extrapolation_npts, self.npts)
626        self.assertEqual(inv._high_extrapolation_function.__class__, invariant.PowerLaw)
627       
628        # Data boundaries for fiiting
629        xlen = len(self.data.x)
630        start =  xlen - inv._high_extrapolation_npts
631        qmin = inv._data.x[start]
632        qmax = inv._data.x[xlen-1]
633       
634        # Extrapolate the high-Q data
[bdd162f]635        inv._fit(model=inv._high_extrapolation_function,
[76c1727]636                          qmin=qmin,
637                          qmax=qmax,
638                          power=inv._high_extrapolation_power)
639     
640       
641        qstar = inv.get_qstar(extrapolation='high')
642       
643        test_y = inv._high_extrapolation_function.evaluate_model(x=self.data.x[start: ])
[c75a8ed]644        self.assert_(len(test_y) == len(self.data.y[start:]))
[76c1727]645       
646        for i in range(len(self.data.x[start:])):
[c75a8ed]647            value  = math.fabs(test_y[i]-self.data.y[start+i])/self.data.y[start+i]
[76c1727]648            self.assert_(value < 0.001)
649           
650    def test_high_data(self):
651        """
652            Invariant with low-Q extrapolation with slit smear
653        """
654        # Create invariant object. Background and scale left as defaults.
655        inv = invariant.InvariantCalculator(data=self.data)
656        # Set the extrapolation parameters for the low-Q range
657        inv.set_extrapolation(range='high', npts=self.npts, function='power_law')
658       
659        self.assertEqual(inv._high_extrapolation_npts, self.npts)
660        self.assertEqual(inv._high_extrapolation_function.__class__, invariant.PowerLaw)
661       
662        # Data boundaries for fiiting
663        xlen = len(self.data.x)
664        start =  xlen - inv._high_extrapolation_npts
665        qmin = inv._data.x[start]
666        qmax = inv._data.x[xlen-1]
667       
668        # Extrapolate the high-Q data
[bdd162f]669        inv._fit(model=inv._high_extrapolation_function,
[76c1727]670                          qmin=qmin,
671                          qmax=qmax,
672                          power=inv._high_extrapolation_power)
673     
674        qstar = inv.get_qstar(extrapolation='high')
675       
[c75a8ed]676        data_in_range= inv.get_extra_data_high(q_end = max(self.data.x),
677                                               npts = inv._high_extrapolation_npts) 
[76c1727]678        test_y = data_in_range.y
[c75a8ed]679        self.assert_(len(test_y) == len(self.data.y[start:]))
680        temp = self.data.y[start:]
[76c1727]681       
682        for i in range(len(self.data.x[start:])):
683            value  = math.fabs(test_y[i]- temp[i])/temp[i]
[c75a8ed]684            self.assert_(value < 0.001)               
Note: See TracBrowser for help on using the repository browser.