source: sasview/Invariant/test/utest_data_handling.py @ 2e3f9e3

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 2e3f9e3 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
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 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.
33        fit = invariant.Extrapolator(data=self.data)
34        #a,b = fit.fit()
35        p, dp = fit.fit()
36
37        # Test results
38        self.assertAlmostEquals(p[0], 1.0, 5)
39        self.assertAlmostEquals(p[1], 0.0, 5)
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)):
48            self.data.y[i] = self.data.y[i]+.1*(random.random()-0.5)
49           
50        # Create invariant object. Background and scale left as defaults.
51        fit = invariant.Extrapolator(data=self.data)
52        p, dp = fit.fit()
53
54        # Test results
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
89class TestInvariantCalculator(unittest.TestCase):
90    """
91        Test main functionality of the Invariant calculator
92    """
93    def setUp(self):
94        self.data = Loader().load("latex_smeared_slit.xml")
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())
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       
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       
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')
324   
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
338        self.rg = 30.0
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)
354        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.Guinier)
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
361        inv._fit(model=inv._low_extrapolation_function,
362                          qmin=qmin,
363                          qmax=qmax,
364                          power=inv._low_extrapolation_power)
365        self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6)
366        self.assertAlmostEqual(self.rg, inv._low_extrapolation_function.radius, 6)
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)
397        self.assertEqual(inv._low_extrapolation_function.__class__, invariant.PowerLaw)
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
404        inv._fit(model=inv._low_extrapolation_function,
405                          qmin=qmin,
406                          qmax=qmax,
407                          power=inv._low_extrapolation_power)
408       
409        self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6)
410        self.assertAlmostEqual(self.m, inv._low_extrapolation_function.power, 6)
411       
412class TestLinearization(unittest.TestCase):
413   
414    def test_guinier_incompatible_length(self):
415        g = invariant.Guinier()
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)
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()
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
432        self.assertEqual(len(x_out), 3)
433        self.assertEqual(len(y_out), 3)
434        self.assertEqual(len(dy_out), 3)
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])
446
447        data = Data1D(x=dy, y=y, dy=x)
448        self.assertEqual(g.get_allowed_bins(data), [False, True, True, True])
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
476        inv.set_extrapolation(range='low', npts=10, function='guinier')
477       
478        self.assertEqual(inv._low_extrapolation_npts, 10)
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
486        inv._fit(model=inv._low_extrapolation_function,
487                          qmin=qmin,
488                          qmax=qmax,
489                          power=inv._low_extrapolation_power)
490        self.assertAlmostEqual(self.scale, inv._low_extrapolation_function.scale, 6)
491        self.assertAlmostEqual(self.rg, inv._low_extrapolation_function.radius, 6)
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)):
496            value  = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i]
497            self.assert_(value < 0.001)
498           
499class TestDataExtraLowSlitGuinier(unittest.TestCase):
500    """
501        for a smear data, test that the fitting go through
502        real data for atleast the 2 first points
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)
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
535        inv._fit(model=inv._low_extrapolation_function,
536                          qmin=qmin,
537                          qmax=qmax,
538                          power=inv._low_extrapolation_power)
539     
540       
541        qstar = inv.get_qstar(extrapolation='low')
542
543        test_y = inv._low_extrapolation_function.evaluate_model(x=self.data.x[:inv._low_extrapolation_npts])
544        self.assert_(len(test_y) == len(self.data.y[:inv._low_extrapolation_npts]))
545       
546        for i in range(inv._low_extrapolation_npts):
547            value  = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i]
548            self.assert_(value < 0.001)
549           
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
567        inv._fit(model=inv._low_extrapolation_function,
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
577        data_in_range = inv.get_extra_data_low(q_start=self.data.x[0], 
578                                               npts = inv._low_extrapolation_npts) 
579        test_y = data_in_range.y
580        self.assert_(len(test_y) == len(self.data.y[:inv._low_extrapolation_npts]))
581        for i in range(inv._low_extrapolation_npts):
582            value  = math.fabs(test_y[i]-self.data.y[i])/self.data.y[i]
583            self.assert_(value < 0.001)   
584       
585           
586class TestDataExtraHighSlitPowerLaw(unittest.TestCase):
587    """
588        for a smear data, test that the fitting go through
589        real data for atleast the 2 first points
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
624        inv._fit(model=inv._high_extrapolation_function,
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: ])
633        self.assert_(len(test_y) == len(self.data.y[start:]))
634       
635        for i in range(len(self.data.x[start:])):
636            value  = math.fabs(test_y[i]-self.data.y[start+i])/self.data.y[start+i]
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
658        inv._fit(model=inv._high_extrapolation_function,
659                          qmin=qmin,
660                          qmax=qmax,
661                          power=inv._high_extrapolation_power)
662     
663        qstar = inv.get_qstar(extrapolation='high')
664       
665        data_in_range= inv.get_extra_data_high(q_end = max(self.data.x),
666                                               npts = inv._high_extrapolation_npts) 
667        test_y = data_in_range.y
668        self.assert_(len(test_y) == len(self.data.y[start:]))
669        temp = self.data.y[start:]
670       
671        for i in range(len(self.data.x[start:])):
672            value  = math.fabs(test_y[i]- temp[i])/temp[i]
673            self.assert_(value < 0.001)               
674                     
Note: See TracBrowser for help on using the repository browser.