1
- """
2
- The squeeze morph is used to correct for small non-linear geometric distortions
3
- from detectors that are not effectively corrected during calibration, such as
4
- individual module misalignment or tilt. This squeezing is applied as:
5
- x_squeezed = x + squeeze_0 + squeeze_1 * x**2 + squeeze_2 * x**3
6
-
7
- The squeeze distortions that we might encounter practically are going to be
8
- very small. Furthermore, large values for the squeezing parameters lead to
9
- missing values during interpolation. Therefore is important to use small
10
- squeezing values to avoid error or unphysical results.
11
- Safe bounds for the squeezing parameters are:
12
- squeeze_0 [-0.2, 0.2]
13
- squeeze_1 [-0.001, 0.001]
14
- squeeze_2 [-0.0001, 0.0001]
15
- Values outside these bounds should be used carefully.
16
- Note that these bounds are established for an x-axis that goes from 0 to 10.
17
- """
18
-
19
- import matplotlib .pyplot as plt
20
1
import numpy as np
2
+ import pytest
3
+ from numpy .polynomial import Polynomial
21
4
from scipy .interpolate import interp1d
22
5
23
6
24
- def test_morphsqueeze ():
25
- """
26
- Test that we can unsqueeze squeezed data.
27
- The test inputs are an expected uniform target (e.g. synchrotron data)
28
- and a squeezed version of the target (e.g. XFEL data). The squeezed data
29
- is created by applying a nonlinear distortion to the uniform target.
30
- Both input data are in the same uniform x-axis grid.
31
- Then we unsqueeze the squeezed data by doing the inverse transformation
32
- using interpolatiion.
33
- Finally we check that the unsqueezed data matches the expected uniform
34
- target.
35
- """
36
-
7
+ @pytest .mark .parametrize (
8
+ "squeeze_coeffs" ,
9
+ [
10
+ # The order of coefficients is [a0, a1, a2, ..., an]
11
+ # Negative cubic squeeze coefficients
12
+ [- 0.2 , - 0.01 , - 0.001 , - 0.001 ],
13
+ # Positive cubic squeeze coefficients
14
+ [0.2 , 0.01 , 0.001 , 0.001 ],
15
+ # Positive and negative cubic squeeze coefficients
16
+ [0.2 , - 0.01 , 0.001 , - 0.001 ],
17
+ # Quadratic squeeze coefficients
18
+ [- 0.2 , 0.005 , - 0.003 ],
19
+ # Linear squeeze coefficients
20
+ [0.1 , 0.3 ],
21
+ # 4th order squeeze coefficients
22
+ [0.2 , - 0.01 , 0.001 , - 0.001 , 0.0001 ],
23
+ ],
24
+ )
25
+ def test_morphsqueeze (squeeze_coeffs ):
37
26
# Uniform x-axis grid. This is the same x-axis for all data.
38
27
x = np .linspace (0 , 10 , 1000 )
39
28
# Expected uniform target
40
29
y_expected = np .sin (x )
41
30
31
+ # Create polynomial based on a list of values for polynomial coefficients
32
+ squeeze_polynomial = Polynomial (squeeze_coeffs )
42
33
# Apply squeeze parameters to uniform data to get the squeezed data
43
- # Include squeeze_0 for squeezes with offset
44
- squeeze_0 = 0.2
45
- squeeze_1 = - 0.001
46
- squeeze_2 = - 0.001
47
- x_squeezed = x + squeeze_0 + squeeze_1 * x ** 2 + squeeze_2 * x ** 3
34
+ x_squeezed = x + squeeze_polynomial (x )
48
35
y_squeezed = np .sin (x_squeezed )
49
36
50
37
# Unsqueeze the data by interpolating back to uniform grid
51
- # y_unsqueezed = np.interp(x, x_squeezed, y_squeezed)
52
38
y_unsqueezed = interp1d (
53
39
x_squeezed ,
54
40
y_squeezed ,
@@ -59,16 +45,16 @@ def test_morphsqueeze():
59
45
y_actual = y_unsqueezed
60
46
61
47
# Check that the unsqueezed (actual) data matches the expected data
62
- # Including tolerance error because I was having issues
63
- # with y_actual == y_expected. I think is because interpolation?
64
- assert np . allclose ( y_actual , y_expected , atol = 100 )
65
-
66
- # Plot to verify what we are doing
67
- plt .figure (figsize = (7 , 4 ))
68
- plt .plot (x , y_expected , color = "black" , label = "Expected uniform data" )
69
- plt .plot (x , y_squeezed , "--" , color = "purple" , label = "Squeezed data" )
70
- plt .plot (x , y_unsqueezed , "--" , color = "gold" , label = "Unsqueezed data" )
71
- plt .xlabel ("x" )
72
- plt .ylabel ("y" )
73
- plt .legend ()
74
- plt .show ()
48
+ # Including tolerance error because of extrapolation error
49
+ assert np . allclose ( y_actual , y_expected , atol = 1 )
50
+
51
+ # This plotting code was used for the comments in the github
52
+ # PR https://github.com/diffpy/diffpy.morph/pull/180
53
+ # plt.figure(figsize=(7, 4))
54
+ # plt.plot(x, y_expected, color="black", label="Expected uniform data")
55
+ # plt.plot(x, y_squeezed, "--", color="purple", label="Squeezed data")
56
+ # plt.plot(x, y_unsqueezed, "--", color="gold", label="Unsqueezed data")
57
+ # plt.xlabel("x")
58
+ # plt.ylabel("y")
59
+ # plt.legend()
60
+ # plt.show()
0 commit comments