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

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since b699768 was b699768, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 8 years ago

Initial commit of the refactored SasCalc? module.

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