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

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since aa1db44 was 9a5097c, checked in by andyfaff, 7 years ago

MAINT: import numpy as np

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