diff --git a/news/reduce-warns.rst b/news/reduce-warns.rst new file mode 100644 index 0000000..d8c99b5 --- /dev/null +++ b/news/reduce-warns.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* Only give user extrapolation warning after refinement. + +**Security:** + +* diff --git a/src/diffpy/morph/morph_io.py b/src/diffpy/morph/morph_io.py index fd016af..713b572 100644 --- a/src/diffpy/morph/morph_io.py +++ b/src/diffpy/morph/morph_io.py @@ -18,6 +18,7 @@ import inspect import sys +import warnings from pathlib import Path import numpy @@ -26,6 +27,13 @@ from diffpy.morph import __save_morph_as__ +def custom_formatwarning(msg, *args, **kwargs): + return f"{msg}\n" + + +warnings.formatwarning = custom_formatwarning + + def single_morph_output( morph_inputs, morph_results, @@ -398,3 +406,34 @@ def tabulate_results(multiple_morph_results): } ) return tabulated_results + + +def handle_warnings(squeeze_morph): + if squeeze_morph is not None: + eil = squeeze_morph.extrap_index_low + eih = squeeze_morph.extrap_index_high + + if eil is not None or eih is not None: + if eih is None: + wmsg = ( + "Warning: points with grid value below " + f"{squeeze_morph.squeeze_cutoff_low} " + f"will be extrapolated." + ) + elif eil is None: + wmsg = ( + "Warning: points with grid value above " + f"{squeeze_morph.squeeze_cutoff_high} " + f"will be extrapolated." + ) + else: + wmsg = ( + "Warning: points with grid value below " + f"{squeeze_morph.squeeze_cutoff_low} and above " + f"{squeeze_morph.squeeze_cutoff_high} " + f"will be extrapolated." + ) + warnings.warn( + wmsg, + UserWarning, + ) diff --git a/src/diffpy/morph/morphapp.py b/src/diffpy/morph/morphapp.py index 9981e3a..37a028b 100755 --- a/src/diffpy/morph/morphapp.py +++ b/src/diffpy/morph/morphapp.py @@ -546,6 +546,7 @@ def single_morph( # Squeeze squeeze_poly_deg = -1 squeeze_dict_in = {} + squeeze_morph = None if opts.squeeze is not None: # Handles both list and csv input if ( @@ -570,7 +571,8 @@ def single_morph( except ValueError: parser.error(f"{coeff} could not be converted to float.") squeeze_poly_deg = len(squeeze_dict_in.keys()) - chain.append(morphs.MorphSqueeze()) + squeeze_morph = morphs.MorphSqueeze() + chain.append(squeeze_morph) config["squeeze"] = squeeze_dict_in # config["extrap_index_low"] = None # config["extrap_index_high"] = None @@ -696,6 +698,9 @@ def single_morph( else: chain(x_morph, y_morph, x_target, y_target) + # THROW ANY WARNINGS HERE + io.handle_warnings(squeeze_morph) + # Get Rw for the morph range rw = tools.getRw(chain) pcc = tools.get_pearson(chain) diff --git a/src/diffpy/morph/morphs/morphsqueeze.py b/src/diffpy/morph/morphs/morphsqueeze.py index d57957a..401d334 100644 --- a/src/diffpy/morph/morphs/morphsqueeze.py +++ b/src/diffpy/morph/morphs/morphsqueeze.py @@ -1,8 +1,6 @@ """Class MorphSqueeze -- Apply a polynomial to squeeze the morph function.""" -import warnings - import numpy as np from numpy.polynomial import Polynomial from scipy.interpolate import CubicSpline @@ -10,13 +8,6 @@ from diffpy.morph.morphs.morph import LABEL_GR, LABEL_RA, Morph -def custom_formatwarning(msg, *args, **kwargs): - return f"{msg}\n" - - -warnings.formatwarning = custom_formatwarning - - class MorphSqueeze(Morph): """Squeeze the morph function. @@ -75,6 +66,11 @@ class MorphSqueeze(Morph): # extrap_index_high: first index after interpolation region extrap_index_low = None extrap_index_high = None + squeeze_cutoff_low = None + squeeze_cutoff_high = None + + def __init__(self, config=None): + super().__init__(config) def morph(self, x_morph, y_morph, x_target, y_target): """Apply a polynomial to squeeze the morph function. @@ -87,34 +83,14 @@ def morph(self, x_morph, y_morph, x_target, y_target): coeffs = [self.squeeze[f"a{i}"] for i in range(len(self.squeeze))] squeeze_polynomial = Polynomial(coeffs) x_squeezed = self.x_morph_in + squeeze_polynomial(self.x_morph_in) + self.squeeze_cutoff_low = min(x_squeezed) + self.squeeze_cutoff_high = max(x_squeezed) self.y_morph_out = CubicSpline(x_squeezed, self.y_morph_in)( self.x_morph_in ) - low_extrap = np.where(self.x_morph_in < x_squeezed[0])[0] - high_extrap = np.where(self.x_morph_in > x_squeezed[-1])[0] + low_extrap = np.where(self.x_morph_in < self.squeeze_cutoff_low)[0] + high_extrap = np.where(self.x_morph_in > self.squeeze_cutoff_high)[0] self.extrap_index_low = low_extrap[-1] if low_extrap.size else None self.extrap_index_high = high_extrap[0] if high_extrap.size else None - below_extrap = min(x_morph) < min(x_squeezed) - above_extrap = max(x_morph) > max(x_squeezed) - if below_extrap or above_extrap: - if not above_extrap: - wmsg = ( - "Warning: points with grid value below " - f"{min(x_squeezed)} will be extrapolated." - ) - elif not below_extrap: - wmsg = ( - "Warning: points with grid value above " - f"{max(x_squeezed)} will be extrapolated." - ) - else: - wmsg = ( - "Warning: points with grid value below " - f"{min(x_squeezed)} and above {max(x_squeezed)} will be " - "extrapolated." - ) - warnings.warn( - wmsg, - UserWarning, - ) + return self.xyallout diff --git a/tests/test_morphsqueeze.py b/tests/test_morphsqueeze.py index a4b2d6b..6ab8cb0 100644 --- a/tests/test_morphsqueeze.py +++ b/tests/test_morphsqueeze.py @@ -2,6 +2,7 @@ import pytest from numpy.polynomial import Polynomial +import diffpy.morph.morphpy as morphpy from diffpy.morph.morphapp import create_option_parser, single_morph from diffpy.morph.morphs.morphsqueeze import MorphSqueeze @@ -123,16 +124,19 @@ def test_morphsqueeze_extrapolate( ): x_morph = np.linspace(0, 10, 101) y_morph = np.sin(x_morph) - x_target = x_morph - y_target = y_morph + x_target = x_morph.copy() + y_target = y_morph.copy() morph = MorphSqueeze() morph.squeeze = squeeze_coeffs coeffs = [squeeze_coeffs[f"a{i}"] for i in range(len(squeeze_coeffs))] squeeze_polynomial = Polynomial(coeffs) x_squeezed = x_morph + squeeze_polynomial(x_morph) with pytest.warns() as w: - x_morph_actual, y_morph_actual, x_target_actual, y_target_actual = ( - morph(x_morph, y_morph, x_target, y_target) + morphpy.morph_arrays( + np.array([x_morph, y_morph]).T, + np.array([x_target, y_target]).T, + squeeze=coeffs, + apply=True, ) assert len(w) == 1 assert w[0].category is UserWarning @@ -152,6 +156,7 @@ def test_morphsqueeze_extrapolate( ",".join(map(str, coeffs)), f"{morph_file.as_posix()}", f"{target_file.as_posix()}", + "--apply", "-n", ] )