Skip to content
23 changes: 23 additions & 0 deletions news/test_squeeze.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* Polynomial squeeze of x-axis of morphed data

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
60 changes: 60 additions & 0 deletions tests/test_morphsqueeze.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import numpy as np
import pytest
from numpy.polynomial import Polynomial
from scipy.interpolate import interp1d


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are now going to test 3 or 4 different variants of the same thing (i.e., different representative numbers) so it is time to use @pytest.paramatrize decorator. Please see diffpy.utils tests for examples.

@pytest.mark.parametrize(
"squeeze_coeffs",
[
# The order of coefficients is [a0, a1, a2, ..., an]
# Negative cubic squeeze coefficients
[-0.2, -0.01, -0.001, -0.001],
# Positive cubic squeeze coefficients
[0.2, 0.01, 0.001, 0.001],
# Positive and negative cubic squeeze coefficients
[0.2, -0.01, 0.001, -0.001],
# Quadratic squeeze coefficients
[-0.2, 0.005, -0.003],
# Linear squeeze coefficients
[0.1, 0.3],
# 4th order squeeze coefficients
[0.2, -0.01, 0.001, -0.001, 0.0001],
],
)
def test_morphsqueeze(squeeze_coeffs):
# Uniform x-axis grid. This is the same x-axis for all data.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments in the test are not needed, just the comments summarizing the behavior above are useful.

x = np.linspace(0, 10, 1000)
# Expected uniform target
y_expected = np.sin(x)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please close this code up. Use empty lines only where they are needed for syntactic clarity.

# Create polynomial based on a list of values for polynomial coefficients
squeeze_polynomial = Polynomial(squeeze_coeffs)
# Apply squeeze parameters to uniform data to get the squeezed data
x_squeezed = x + squeeze_polynomial(x)
y_squeezed = np.sin(x_squeezed)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where the function is called, so we don't seem to be testing anything. I would expect to see something like.

morphed = SqueezeMorph(x, y)
actual_x, actual_y = morphed.xyallout

or sthg like that (not sure I have the syntax right), then

assert np.allclose(actual_y, expected_y)

I expect this to fail initially because the function is not written yet, but write an empty function with just a docstring and a signature and then import it.

Then write the code to make the test pass.

# Unsqueeze the data by interpolating back to uniform grid
y_unsqueezed = interp1d(
x_squeezed,
y_squeezed,
kind="cubic",
bounds_error=False,
fill_value="extrapolate",
)(x)
y_actual = y_unsqueezed

# Check that the unsqueezed (actual) data matches the expected data
# Including tolerance error because of extrapolation error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a no-no. You are updating the test to make it pass, but the test should express the behavior we want, then write whatever code we need to make the test pass. We don't want a loose test to pass because we haven't coded the edge-case correctly.

assert np.allclose(y_actual, y_expected, atol=1)

# This plotting code was used for the comments in the github
# PR https://github.com/diffpy/diffpy.morph/pull/180
# plt.figure(figsize=(7, 4))
# plt.plot(x, y_expected, color="black", label="Expected uniform data")
# plt.plot(x, y_squeezed, "--", color="purple", label="Squeezed data")
# plt.plot(x, y_unsqueezed, "--", color="gold", label="Unsqueezed data")
# plt.xlabel("x")
# plt.ylabel("y")
# plt.legend()
# plt.show()
Loading