source: sasview/test/corfunc/test/utest_corfunc.py @ f53d684

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

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

  • Property mode set to 100644
File size: 4.7 KB
Line 
1"""
2Unit Tests for CorfuncCalculator class
3"""
4from __future__ import division, print_function
5
6import os.path
7import unittest
8import time
9
10import numpy as np
11
12from sas.sascalc.corfunc.corfunc_calculator import CorfuncCalculator
13from sas.sascalc.dataloader.data_info import Data1D
14
15
16def find(filename):
17    return os.path.join(os.path.dirname(__file__), filename)
18
19
20class TestCalculator(unittest.TestCase):
21
22    def setUp(self):
23        self.data = load_data()
24        # Note: to generate target values from the GUI:
25        # * load the data from test/corfunc/test/98929.txt
26        # * set qrange to (0, 0.013), (0.15, 0.24)
27        # * select fourier transform type
28        # * click Calculate Bg
29        # * click Extrapolate
30        # * click Compute Parameters
31        # * copy the Guinier and Porod values to the extrapolate function
32        # * for each graph, grab the data from DataInfo and store it in _out.txt
33        self.calculator = CorfuncCalculator(data=self.data, lowerq=0.013,
34            upperq=(0.15, 0.24))
35        self.calculator.background = 0.3
36        self.extrapolation = None
37        self.transformation = None
38        self.results = [np.loadtxt(find(filename+"_out.txt")).T[2]
39                        for filename in ("gamma1", "gamma3", "idf")]
40
41    def extrapolate(self):
42        params, extrapolation, s2 = self.calculator.compute_extrapolation()
43        # Check the extrapolation parameters
44        self.assertAlmostEqual(params['A'], 4.18970, places=5)
45        self.assertAlmostEqual(params['B'], -25469.9, places=1)
46        self.assertAlmostEqual(params['K'], 4.44660e-5, places=10)
47        #self.assertAlmostEqual(params['sigma'], 1.70181e-10, places=15)
48
49        # Ensure the extraplation tends to the background value
50        self.assertAlmostEqual(extrapolation.y[-1], self.calculator.background)
51
52        # Test extrapolation for q values between 0.02 and 0.24
53        mask = np.logical_and(self.data.x > 0.02, self.data.x < 0.24)
54        qs = self.data.x[mask]
55        iqs = self.data.y[mask]
56
57        for q, iq in zip(qs, iqs):
58            # Find the q value in the extraplation nearest to the value in
59            # the data
60            q_extrap = min(extrapolation.x, key=lambda x:abs(x-q))
61            # Find the index of this value in the extrapolation
62            index = list(extrapolation.x).index(q_extrap)
63            # Find it's corresponding intensity value
64            iq_extrap = extrapolation.y[index]
65            # Check the extrapolation agrees to the data at this point to 1 d.p
66            self.assertAlmostEqual(iq_extrap, iq, 1)
67
68        self.extrapolation = extrapolation
69
70    def transform(self):
71        self.calculator.compute_transform(self.extrapolation, 'fourier',
72            completefn=self.transform_callback)
73        # Transform is performed asynchronously; give it time to run
74        while True:
75            time.sleep(0.001)
76            if not self.calculator.transform_isrunning():
77                break
78
79    def transform_callback(self, transforms):
80        transform1, transform3, idf = transforms
81        self.assertIsNotNone(transform1)
82        self.assertAlmostEqual(transform1.y[0], 1)
83        self.assertAlmostEqual(transform1.y[-1], 0, 5)
84        self.transformation = transforms
85
86    def extract_params(self):
87        params = self.calculator.extract_parameters(self.transformation[0])
88        self.assertIsNotNone(params)
89        self.assertEqual(len(params), 6)
90        self.assertLess(abs(params['max']-75), 2.5) # L_p ~= 75
91
92    def check_transforms(self):
93        gamma1, gamma3, idf = self.transformation
94        gamma1_out, gamma3_out, idf_out = self.results
95        def compare(a, b):
96            return max(abs((a-b)/b))
97        #print("gamma1 diff", compare(gamma1.y[gamma1.x<=200.], gamma1_out))
98        #print("gamma3 diff", compare(gamma3.y[gamma3.x<=200.], gamma3_out))
99        #print("idf diff", compare(idf.y[idf.x<=200.], idf_out))
100        #self.assertLess(compare(gamma1.y[gamma1.x<=200.], gamma1_out), 1e-10)
101        #self.assertLess(compare(gamma3.y[gamma3.x<=200.], gamma3_out), 1e-10)
102        #self.assertLess(compare(idf.y[idf.x<=200.], idf_out), 1e-10)
103
104    # Ensure tests are ran in correct order;
105    # Each test depends on the one before it
106    def test_calculator(self):
107        steps = [self.extrapolate, self.transform, self.extract_params, self.check_transforms]
108        for test in steps:
109            try:
110                test()
111            except Exception as e:
112                raise
113                self.fail("{} failed ({}: {})".format(test, type(e), e))
114
115
116def load_data(filename="98929.txt"):
117    data = np.loadtxt(find(filename), dtype=np.float64)
118    q = data[:,0]
119    iq = data[:,1]
120    return Data1D(x=q, y=iq)
121
122if __name__ == '__main__':
123    unittest.main()
Note: See TracBrowser for help on using the repository browser.