Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions news/reduce-warns.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* <news item>

**Changed:**

* <news item>

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* Only give user extrapolation warning after refinement.

**Security:**

* <news item>
39 changes: 39 additions & 0 deletions src/diffpy/morph/morph_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import inspect
import sys
import warnings
from pathlib import Path

import numpy
Expand All @@ -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,
Expand Down Expand Up @@ -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,
)
7 changes: 6 additions & 1 deletion src/diffpy/morph/morphapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
44 changes: 10 additions & 34 deletions src/diffpy/morph/morphs/morphsqueeze.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
"""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

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.

Expand Down Expand Up @@ -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.
Expand All @@ -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
13 changes: 9 additions & 4 deletions tests/test_morphsqueeze.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -152,6 +156,7 @@ def test_morphsqueeze_extrapolate(
",".join(map(str, coeffs)),
f"{morph_file.as_posix()}",
f"{target_file.as_posix()}",
"--apply",
"-n",
]
)
Expand Down
Loading