Skip to content

Commit

Permalink
Merge pull request #63 from sbillinge/gt2
Browse files Browse the repository at this point in the history
Test for correct applycutoff
  • Loading branch information
sbillinge authored Nov 11, 2024
2 parents d4c91b2 + fae69cf commit dfc8bbd
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 45 deletions.
23 changes: 23 additions & 0 deletions news/gt.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:**

* qmin/qmax limits in reciprocal space grid so qmin and qmax are not excluded

**Security:**

* <news item>
1 change: 1 addition & 0 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ codecov
coverage
pytest-cov
pytest-env
pytest-mock
6 changes: 1 addition & 5 deletions src/diffpy/fourigui/fourigui.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,11 @@ def load_cube(self):
self.slider.grid(row=0, column=0, padx=10, pady=10, sticky=tk.N + tk.E + tk.S + tk.W)

if not self.loaded:

fig, ax = plt.subplots(figsize=(4.95, 4.95))
fig = plt.gcf()
DPI = fig.get_dpi()
fig.set_size_inches(500 / float(DPI), 500 / float(DPI))

self.plane_num.set(np.shape(self.cube)[0] // 2)

if self.axis.get() == 0:
self.im = plt.imshow(self.cube[self.plane_num.get(), :, :])
elif self.axis.get() == 1:
Expand All @@ -319,7 +316,6 @@ def load_cube(self):
self.canvas.draw()
self.canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
self.loaded = True

else:
self.plot_plane()
self.transformed = False
Expand Down Expand Up @@ -485,7 +481,7 @@ def applycutoff(self):
r2_outer = qmax**2
i, j, k = np.meshgrid(np.arange(xdim), np.arange(ydim), np.arange(zdim))
r2 = (i - xdim // 2) ** 2 + (j - ydim // 2) ** 2 + (k - zdim // 2) ** 2
mask = (r2 <= r2_inner) | (r2 >= r2_outer) # True if voxel is out of range
mask = (r2 < r2_inner) | (r2 > r2_outer) # True if voxel is out of range
sphere[mask] = np.nan # therefore set to np.nan if out of range

if self.space.get():
Expand Down
40 changes: 0 additions & 40 deletions tests/integration_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import unittest
import warnings

import h5py
import numpy as np
Expand Down Expand Up @@ -98,45 +97,6 @@ def test_fft_testdataset3(self):
# then
self.assertTrue(np.allclose(result, self.test_gofr_cut_15to35px))

def test_applycutoff_range1(self):
# given
self.test_gui.plot_plane = lambda *a, **b: ()
self.test_gui.cube = self.test_sofq
self.test_gui.qminentry.insert(0, "10")
self.test_gui.qmaxentry.insert(0, "40")

# Desired behavior is nans in the arrays below qmin and above qmax. As a result, np.nanmax will generate
# runtimewarnings when it # encounters slices that are all nans. capture these so tests pass cleanly
# without warnings
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=RuntimeWarning)
# when
self.test_gui.applycutoff()
result = self.test_gui.cube

# then
self.assertTrue(np.allclose(np.nan_to_num(result), np.nan_to_num(self.test_sofq_cut_10to40px)))

def test_applycutoff_range2(self):
# given
self.test_gui.plot_plane = lambda *a, **b: ()
self.test_gui.cube = self.test_sofq
self.test_gui.qminentry.insert(0, "15")
self.test_gui.qmaxentry.insert(0, "35")

# Desired behavior is nans in the arrays below qmin and above qmax. As a result, np.nanmax will generate
# runtimewarnings when it # encounters slices that are all nans. capture these so tests pass cleanly
# without warnings
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=RuntimeWarning)
# when
self.test_gui.applycutoff()
result = self.test_gui.cube

# then
# with self.assertWarns(RuntimeWarning):
self.assertTrue(np.allclose(np.nan_to_num(result), np.nan_to_num(self.test_sofq_cut_15to35px)))


if __name__ == "__main__":
unittest.main()
78 changes: 78 additions & 0 deletions tests/unit_test.py → tests/test_fourigui.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import tkinter as tk
import unittest

import h5py
import numpy as np

from diffpy.fourigui.fourigui import Gui

Expand Down Expand Up @@ -146,5 +148,81 @@ def test_fft_111(self):
self.assertTrue(self.test_gui.transformed and self.test_gui.transcutted)


def test_applycutoff(mocker):
root = tk.Tk()
fg = Gui()
# qmin of 1 and qmax of 2 is expected to leave the central pixel and corner
# pixels as NaN's
mocker.patch.object(fg.qminentry, "get", return_value=1.0)
mocker.patch.object(fg.qmaxentry, "get", return_value=2.0)
mocker.patch.object(fg, "plot_plane") # we don't want it to plot anything so intercept
fg.cutted = False
fg.cube = np.ones((5, 5, 5))
expected_ones = np.ones((5, 5, 5))
expected_recip = np.array(
[
[
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, 1, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
],
[
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, 1, 1, 1, np.nan],
[np.nan, 1, 1, 1, np.nan],
[np.nan, 1, 1, 1, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
],
[
[np.nan, np.nan, 1, np.nan, np.nan],
[np.nan, 1, 1, 1, np.nan],
[1, 1, np.nan, 1, 1],
[np.nan, 1, 1, 1, np.nan],
[np.nan, np.nan, 1, np.nan, np.nan],
],
[
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, 1, 1, 1, np.nan],
[np.nan, 1, 1, 1, np.nan],
[np.nan, 1, 1, 1, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
],
[
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, 1, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
[np.nan, np.nan, np.nan, np.nan, np.nan],
],
]
)
# test the case where fg.space is 0
fg.applycutoff()
np.testing.assert_array_equal(fg.cube_reci, expected_ones)
np.testing.assert_array_equal(fg.cube_recicut, expected_recip)
root.destroy() # Clean up Tkinter instance

# test the case where fg.space is 1
root = tk.Tk()
fg = Gui()
# qmin of 1 and qmax of 2 is expected to leave the central pixel and corner
# pixels as NaN's
mocker.patch.object(fg.qminentry, "get", return_value=1)
mocker.patch.object(fg.qmaxentry, "get", return_value=2)
mocker.patch.object(
fg, "fft"
) # we don't want it to do the fft so intercept. Should be tested separately (fixme).
fg.cutted = False
fg.cube_reci = np.ones((5, 5, 5))
fg.cube = np.ones((5, 5, 5))
mocker.patch.object(fg.space, "get", return_value=1)
fg.applycutoff()
np.testing.assert_array_equal(fg.cube_real, expected_ones)
np.testing.assert_array_equal(fg.cube_recicut, expected_recip)
root.destroy() # Clean up Tkinter instance


if __name__ == "__main__":
unittest.main()

0 comments on commit dfc8bbd

Please sign in to comment.