Skip to content

Commit cf8d906

Browse files
committed
test: created a test for squeeze morph using sine wave. Created function to test
1 parent d1c2695 commit cf8d906

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""class MorphSqueeze -- apply a non-linear squeeze to the morph.
2+
This morph non-linearly adjusts the x-coordinates.
3+
The y-values are then recomputed by interpolating the original data.
4+
"""
5+
6+
import numpy as np
7+
8+
from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph
9+
10+
11+
class MorphSqueeze(Morph):
12+
summary = "Squeeze morph by desired amount (non-linear transformation)"
13+
xinlabel = LABEL_RA # This label need to change to be more generic
14+
yinlabel = LABEL_GR # This label need to change to be more generic
15+
xoutlabel = LABEL_RA # This label need to change to be more generic
16+
youtlabel = LABEL_GR # This label need to change to be more generic
17+
parnames = ["squeeze"]
18+
19+
def morph(self, x_morph, y_morph, x_target, y_target):
20+
"""Resample arrays onto the specified grid using a non-linear squeeze.
21+
22+
Parameters
23+
----------
24+
x_morph : array-like
25+
The input x-values to be transformed.
26+
y_morph : array-like
27+
The input y-values.
28+
x_target, y_target : array-like
29+
The target grid arrays (left unchanged by this morph).
30+
31+
Returns
32+
-------
33+
(x_morph_out, y_morph_out, x_target, y_target)
34+
"""
35+
# Initialize the parent class to set up attributes
36+
Morph.morph(self, x_morph, y_morph, x_target, y_target)
37+
38+
# If squeeze is zero, return original output
39+
if self.squeeze == 0:
40+
return self.xyallout
41+
42+
# Compute new x positions using the non-linear squeeze transformation:
43+
new_x = self.x_morph_in + self.squeeze * np.sin(self.x_morph_in)
44+
self.x_morph_out = new_x
45+
46+
# Interpolate the y-values at the new x positions.
47+
self.y_morph_out = np.interp(new_x, self.x_morph_in, self.y_morph_in)
48+
49+
return self.xyallout
50+
51+
52+
# End of class MorphSqueeze

tests/test_morphsqueeze.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import numpy as np
2+
import pytest
3+
4+
from diffpy.morph.morphs.morphsqueeze import MorphSqueeze
5+
6+
7+
class TestMorphSqueeze:
8+
@pytest.fixture
9+
def setup(self):
10+
# Create a sine-wave for testing
11+
self.x_morph = np.linspace(0, 2 * np.pi, 1000)
12+
self.y_morph = np.sin(self.x_morph)
13+
self.x_target = self.x_morph.copy()
14+
self.y_target = self.y_morph.copy()
15+
return
16+
17+
def test_no_squeeze(self, setup):
18+
"""When squeeze is zero, the input should be unchanged."""
19+
morph = MorphSqueeze()
20+
morph.squeeze = 0.0
21+
22+
x_morph, y_morph, x_target, y_target = morph(
23+
self.x_morph, self.y_morph, self.x_target, self.y_target
24+
)
25+
26+
# Verify that the morph output matches the original input
27+
assert np.allclose(x_morph, self.x_morph)
28+
assert np.allclose(y_morph, self.y_morph)
29+
# And the target arrays remain unchanged
30+
assert np.allclose(x_target, self.x_target)
31+
assert np.allclose(y_target, self.y_target)
32+
33+
def test_morph_with_squeeze(self, setup):
34+
"""Test that with a non-zero squeeze,
35+
x_morph is transformed non-linearly."""
36+
morph = MorphSqueeze()
37+
morph.squeeze = 0.7
38+
x_new, y_new, x_target, y_target = morph(
39+
self.x_morph, self.y_morph, self.x_target, self.y_target
40+
)
41+
42+
# Check that target arrays remain unchanged
43+
assert np.allclose(self.y_target, y_target)
44+
45+
# For this test, we expect:
46+
# x_new = x_morph + squeeze_factor * sin(x_morph)
47+
expected_x = self.x_morph + morph.squeeze * np.sin(self.x_morph)
48+
expected_y = np.sin(expected_x)
49+
50+
# Allow for some tolerance because of numerical interpolation if used
51+
res = sum(np.fabs(expected_y - y_new))
52+
assert res < 1
53+
54+
55+
if __name__ == "__main__":
56+
TestMorphSqueeze()

0 commit comments

Comments
 (0)