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
201import numpy as np
2+ import pytest
3+ from numpy .polynomial import Polynomial
214from scipy .interpolate import interp1d
225
236
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 ):
3726 # Uniform x-axis grid. This is the same x-axis for all data.
3827 x = np .linspace (0 , 10 , 1000 )
3928 # Expected uniform target
4029 y_expected = np .sin (x )
4130
31+ # Create polynomial based on a list of values for polynomial coefficients
32+ squeeze_polynomial = Polynomial (squeeze_coeffs )
4233 # 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 )
4835 y_squeezed = np .sin (x_squeezed )
4936
5037 # Unsqueeze the data by interpolating back to uniform grid
51- # y_unsqueezed = np.interp(x, x_squeezed, y_squeezed)
5238 y_unsqueezed = interp1d (
5339 x_squeezed ,
5440 y_squeezed ,
@@ -59,16 +45,16 @@ def test_morphsqueeze():
5945 y_actual = y_unsqueezed
6046
6147 # 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