source: sasview/test/corfunc/test/utest_corfunc.py @ 0675e6b

Last change on this file since 0675e6b was 0675e6b, checked in by Stuart Prescott <stuart@…>, 7 years ago

Fix tests to find resources without changing dir

Test resources are in the same directory (or a child directory) of the test
code so the code can locate the resources itself rather than relying on the
tests being run from a certain location. This allows the tests to be used to
test the installed code rather than the current checkout and also allows
automated test discovery with tools like py.test to be used, running all
tests at once without a runner.

  • 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.