Skip to content

Commit 811c86a

Browse files
authored
Ensure no warning or errors when no extrapolation occurs (#278)
* Fix scale + stretch + apply with extrap warning * Add test + news * Add more tests
1 parent 177d073 commit 811c86a

File tree

7 files changed

+165
-36
lines changed

7 files changed

+165
-36
lines changed

news/extrap_fix.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* <news item>
4+
5+
**Changed:**
6+
7+
* <news item>
8+
9+
**Deprecated:**
10+
11+
* <news item>
12+
13+
**Removed:**
14+
15+
* <news item>
16+
17+
**Fixed:**
18+
19+
* Applying a function with no extrapolation no longer produces an error.
20+
21+
**Security:**
22+
23+
* <news item>

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ authors = [
1111
maintainers = [
1212
{ name="Simon J.L. Billinge group", email="[email protected]" },
1313
]
14-
description = "Python package for manipulating and comparing PDF profiles"
14+
description = "Python package for manipulating and comparing 1D signals."
1515
keywords = ['diffpy', 'pdf', 'data interpretation']
1616
readme = "README.rst"
1717
requires-python = ">=3.11, <3.14"

src/diffpy/morph/morph_io.py

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -501,38 +501,39 @@ def tabulate_results(multiple_morph_results):
501501
def handle_extrapolation_warnings(morph):
502502
if morph is not None:
503503
extrapolation_info = morph.extrapolation_info
504-
is_extrap_low = extrapolation_info["is_extrap_low"]
505-
is_extrap_high = extrapolation_info["is_extrap_high"]
506-
cutoff_low = extrapolation_info["cutoff_low"]
507-
cutoff_high = extrapolation_info["cutoff_high"]
508-
509-
if is_extrap_low and is_extrap_high:
510-
wmsg = (
511-
"Warning: points with grid value below "
512-
f"{cutoff_low} and above "
513-
f"{cutoff_high} "
514-
f"are extrapolated."
515-
)
516-
elif is_extrap_low:
517-
wmsg = (
518-
"Warning: points with grid value below "
519-
f"{cutoff_low} "
520-
f"are extrapolated."
521-
)
522-
elif is_extrap_high:
523-
wmsg = (
524-
"Warning: points with grid value above "
525-
f"{cutoff_high} "
526-
f"are extrapolated."
527-
)
528-
else:
529-
wmsg = None
504+
if extrapolation_info is not None:
505+
is_extrap_low = extrapolation_info["is_extrap_low"]
506+
is_extrap_high = extrapolation_info["is_extrap_high"]
507+
cutoff_low = extrapolation_info["cutoff_low"]
508+
cutoff_high = extrapolation_info["cutoff_high"]
509+
510+
if is_extrap_low and is_extrap_high:
511+
wmsg = (
512+
"Warning: points with grid value below "
513+
f"{cutoff_low} and above "
514+
f"{cutoff_high} "
515+
f"are extrapolated."
516+
)
517+
elif is_extrap_low:
518+
wmsg = (
519+
"Warning: points with grid value below "
520+
f"{cutoff_low} "
521+
f"are extrapolated."
522+
)
523+
elif is_extrap_high:
524+
wmsg = (
525+
"Warning: points with grid value above "
526+
f"{cutoff_high} "
527+
f"are extrapolated."
528+
)
529+
else:
530+
wmsg = None
530531

531-
if wmsg:
532-
warnings.warn(
533-
wmsg,
534-
UserWarning,
535-
)
532+
if wmsg:
533+
warnings.warn(
534+
wmsg,
535+
UserWarning,
536+
)
536537

537538

538539
def handle_check_increase_warning(squeeze_morph):

src/diffpy/morph/morphs/morph.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def __init__(self, config=None):
124124
All configuration variables.
125125
"""
126126
# declare empty attributes
127+
self.extrapolation_info = None
127128
if config is None:
128129
config = {}
129130
self.x_morph_in = None

tests/test_morphshift.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,36 @@ def test_morphshift_extrapolate(user_filesystem, capsys, hshift, wmsg_gen):
105105
)
106106
with pytest.warns(UserWarning, match=expected_wmsg):
107107
single_morph(parser, opts, pargs, stdout_flag=False)
108+
109+
110+
def test_morphshift_no_warning(user_filesystem):
111+
# Apply a shift with no extrapolation
112+
# There should be no warning or errors produced
113+
x_morph = numpy.linspace(0, 10, 101)
114+
y_morph = numpy.sin(x_morph)
115+
x_target = x_morph.copy()
116+
y_target = y_morph.copy()
117+
morphpy.morph_arrays(
118+
numpy.array([x_morph, y_morph]).T,
119+
numpy.array([x_target, y_target]).T,
120+
hshift=0,
121+
apply=True,
122+
)
123+
124+
# CLI test
125+
morph_file, target_file = create_morph_data_file(
126+
user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target
127+
)
128+
129+
parser = create_option_parser()
130+
(opts, pargs) = parser.parse_args(
131+
[
132+
"--scale=1",
133+
"--hshift=0",
134+
f"{morph_file.as_posix()}",
135+
f"{target_file.as_posix()}",
136+
"--apply",
137+
"-n",
138+
]
139+
)
140+
single_morph(parser, opts, pargs, stdout_flag=False)

tests/test_morphsqueeze.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,44 @@ def test_morphsqueeze_extrapolate(user_filesystem, squeeze_coeffs, wmsg_gen):
174174
single_morph(parser, opts, pargs, stdout_flag=False)
175175

176176

177+
def test_morphsqueeze_no_warning(user_filesystem):
178+
# Apply a squeeze with no extrapolation
179+
# There should be no warning or errors produced
180+
squeeze_coeffs = {"a0": 0, "a1": 0}
181+
x_morph = np.linspace(0, 10, 101)
182+
y_morph = np.sin(x_morph)
183+
x_target = x_morph.copy()
184+
y_target = y_morph.copy()
185+
morph = MorphSqueeze()
186+
morph.squeeze = squeeze_coeffs
187+
coeffs = [squeeze_coeffs[f"a{i}"] for i in range(len(squeeze_coeffs))]
188+
morphpy.morph_arrays(
189+
np.array([x_morph, y_morph]).T,
190+
np.array([x_target, y_target]).T,
191+
squeeze=coeffs,
192+
apply=True,
193+
)
194+
195+
# CLI test
196+
morph_file, target_file = create_morph_data_file(
197+
user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target
198+
)
199+
200+
parser = create_option_parser()
201+
(opts, pargs) = parser.parse_args(
202+
[
203+
"--scale=1",
204+
"--squeeze",
205+
",".join(map(str, coeffs)),
206+
f"{morph_file.as_posix()}",
207+
f"{target_file.as_posix()}",
208+
"--apply",
209+
"-n",
210+
]
211+
)
212+
single_morph(parser, opts, pargs, stdout_flag=False)
213+
214+
177215
def test_non_unique_grid():
178216
# Test giving morphsqueeze a non-unique grid
179217
# Expect it to return a unique grid

tests/test_morphstretch.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,16 +101,16 @@ def test_morphshift_extrapolate(user_filesystem, stretch, wmsg_gen):
101101
y_morph = numpy.sin(x_morph)
102102
x_target = x_morph.copy()
103103
y_target = y_morph.copy()
104-
with pytest.warns() as w:
104+
with pytest.warns() as warning:
105105
morphpy.morph_arrays(
106106
numpy.array([x_morph, y_morph]).T,
107107
numpy.array([x_target, y_target]).T,
108108
stretch=stretch,
109109
apply=True,
110110
)
111-
assert len(w) == 1
112-
assert w[0].category is UserWarning
113-
actual_wmsg = str(w[0].message)
111+
assert len(warning) == 1
112+
assert warning[0].category is UserWarning
113+
actual_wmsg = str(warning[0].message)
114114
expected_wmsg = wmsg_gen([min(x_morph), max(x_morph)])
115115
assert actual_wmsg == expected_wmsg
116116

@@ -131,3 +131,36 @@ def test_morphshift_extrapolate(user_filesystem, stretch, wmsg_gen):
131131
)
132132
with pytest.warns(UserWarning, match=expected_wmsg):
133133
single_morph(parser, opts, pargs, stdout_flag=False)
134+
135+
136+
def test_morphshift_no_warning(user_filesystem):
137+
# Apply a stretch with no extrapolation
138+
# There should be no warning or errors produced
139+
x_morph = numpy.linspace(1, 10, 101)
140+
y_morph = numpy.sin(x_morph)
141+
x_target = x_morph.copy()
142+
y_target = y_morph.copy()
143+
morphpy.morph_arrays(
144+
numpy.array([x_morph, y_morph]).T,
145+
numpy.array([x_target, y_target]).T,
146+
stretch=0,
147+
apply=True,
148+
)
149+
150+
# CLI test
151+
morph_file, target_file = create_morph_data_file(
152+
user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target
153+
)
154+
155+
parser = create_option_parser()
156+
(opts, pargs) = parser.parse_args(
157+
[
158+
"--scale=1",
159+
"--stretch=0",
160+
f"{morph_file.as_posix()}",
161+
f"{target_file.as_posix()}",
162+
"--apply",
163+
"-n",
164+
]
165+
)
166+
single_morph(parser, opts, pargs, stdout_flag=False)

0 commit comments

Comments
 (0)