source: sasview/Invariant/test/utest_data_handling.py @ 8ee56a9

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 8ee56a9 was c75a8ed, checked in by Mathieu Doucet <doucetm@…>, 15 years ago

invariant: added unit tests for specific surface and volume fraction. Minor fixes.

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