Skip to content

Commit 3908d63

Browse files
authored
raise ValueError if the the number of regression points is less than the number of parameters in _residual (#249)
* raise `ValueError` if the the number of regression points is less than the number of parameters in `_residual` * test: add test for not enough shared grid points the bad case. * chore: fix typo * chore: more concise error message * chore: fix pre-commit * fix: use a custom error to stop `leatsq` * Revert "fix: use a custom error to stop `leatsq`" This reverts commit 91fa347. * chore: fix the code indentation.
1 parent d8bb5ac commit 3908d63

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

news/enough-regression-points.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* Raise ``ValueError`` if the number of shared grid points between morphed and target functions is less than the number of parameters.
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+
* <news item>
20+
21+
**Security:**
22+
23+
* <news item>

src/diffpy/morph/refine.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,15 @@ def _residual(self, pvals):
8383
self.x_morph, self.y_morph, self.x_target, self.y_target
8484
)
8585
rvec = _y_target - _y_morph
86-
86+
if len(rvec) < len(pvals):
87+
raise ValueError(
88+
f"\nNumber of parameters (currently {len(pvals)}) cannot "
89+
"exceed the number of shared grid points "
90+
f"(currently {len(rvec)}). "
91+
"Please reduce the number of morphing parameters or "
92+
"provide new morphing and target functions with more "
93+
"shared grid points."
94+
)
8795
# If first time computing residual
8896
if self.res_length is None:
8997
self.res_length = len(rvec)
@@ -145,6 +153,9 @@ def refine(self, *args, **kw):
145153
------
146154
ValueError
147155
Exception raised if a minimum cannot be found.
156+
ValueError
157+
If the number of shared grid points between morphed function and
158+
target function is smaller than the number of parameters.
148159
"""
149160

150161
self.pars = args or self.chain.config.keys()

tests/test_refine.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,62 @@ def stretch(x, y, stretch):
181181

182182
assert res < err
183183

184+
def test_refine_grid_bad(self, user_filesystem):
185+
grid = numpy.arange(2)
186+
func = numpy.sin(grid)
187+
grid1, func1, grid2, func2 = grid, func, grid, func
188+
config = {
189+
"stretch": 0.005,
190+
"scale": 1.0,
191+
"smear": 0,
192+
}
193+
chain = MorphChain(config)
194+
refiner = Refiner(chain, grid1, func1, grid2, func2)
195+
refpars = ["stretch", "scale", "smear"]
196+
expected_error_message = (
197+
"\nNumber of parameters (currently 3) cannot "
198+
"exceed the number of shared grid points "
199+
"(currently 2). "
200+
"Please reduce the number of morphing parameters or "
201+
"provide new morphing and target functions with more "
202+
"shared grid points."
203+
)
204+
with pytest.raises(
205+
ValueError,
206+
) as error:
207+
refiner.refine(*refpars)
208+
actual_error_message = str(error.value)
209+
assert actual_error_message == expected_error_message
210+
211+
# call from command line
212+
import subprocess
213+
214+
data_dir_path = user_filesystem / "cwd_dir"
215+
morph_file = data_dir_path / "morph_data"
216+
morph_data_text = [
217+
str(grid1[i]) + " " + str(func1[i]) for i in range(len(grid1))
218+
]
219+
morph_data_text = "\n".join(morph_data_text)
220+
morph_file.write_text(morph_data_text)
221+
target_file = data_dir_path / "target_data"
222+
target_data_text = [
223+
str(grid2[i]) + " " + str(func2[i]) for i in range(len(grid2))
224+
]
225+
target_data_text = "\n".join(target_data_text)
226+
target_file.write_text(target_data_text)
227+
run_cmd = ["diffpy.morph"]
228+
for key, value in config.items():
229+
run_cmd.append(f"--{key}")
230+
run_cmd.append(f"{value}")
231+
run_cmd.extend([str(morph_file), str(target_file)])
232+
run_cmd.append("-n")
233+
result = subprocess.run(run_cmd, capture_output=True, text=True)
234+
expected_error_message = (
235+
"diffpy.morph: error: " + expected_error_message
236+
)
237+
actual_error_message = result.stderr.strip()
238+
assert actual_error_message == expected_error_message
239+
184240

185241
# End of class TestRefine
186242

0 commit comments

Comments
 (0)