From 5d88cf6595e67cb923d007397e4c907c8b85bd76 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sat, 14 Dec 2024 23:45:12 -0500 Subject: [PATCH 1/8] Remove 2 wavelength warnings with test_tth_to_q func --- tests/conftest.py | 9 +++++++ tests/test_transforms.py | 51 +++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c0767b49..44f66178 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -36,3 +36,12 @@ def _load(filename): @pytest.fixture def do_minimal_tth(): return DiffractionObject(wavelength=2 * np.pi, xarray=np.array([30, 60]), yarray=np.array([1, 2]), xtype="tth") + +@pytest.fixture +def wavelength_warning_msg(): + return ( + "No wavelength has been specified. You can continue to use the DiffractionObject, but " + "some of its powerful features will not be available. " + "To specify a wavelength, if you have do = DiffractionObject(xarray, yarray, 'tth'), " + "you may set do.wavelength = 1.54 for a wavelength of 1.54 angstroms." +) \ No newline at end of file diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 909026e6..e9bb54bf 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -5,6 +5,7 @@ from diffpy.utils.transforms import d_to_q, d_to_tth, q_to_d, q_to_tth, tth_to_d, tth_to_q + params_q_to_tth = [ # UC1: Empty q values, no wavelength, return empty arrays (None, np.empty((0)), np.empty((0))), @@ -23,16 +24,10 @@ @pytest.mark.parametrize("wavelength, q, expected_tth", params_q_to_tth) -def test_q_to_tth(wavelength, q, expected_tth): - - wavelength_warning_emsg = ( - "No wavelength has been specified. You can continue to use the DiffractionObject, but " - "some of its powerful features will not be available. " - "To specify a wavelength, if you have do = DiffractionObject(xarray, yarray, 'tth'), " - "you may set do.wavelength = 1.54 for a wavelength of 1.54 angstroms." - ) +def test_q_to_tth(wavelength, q, expected_tth, wavelength_warning_msg): + if wavelength is None: - with pytest.warns(UserWarning, match=re.escape(wavelength_warning_emsg)): + with pytest.warns(UserWarning, match=re.escape(wavelength_warning_msg)): actual_tth = q_to_tth(q, wavelength) else: actual_tth = q_to_tth(q, wavelength) @@ -66,7 +61,7 @@ def test_q_to_tth_bad(q, wavelength, expected_error_type, expected_error_msg): q_to_tth(wavelength, q) -params_tth_to_q = [ +test_tth_t_q_params = [ # UC0: User specified empty tth values (without wavelength) (None, np.array([]), np.array([])), # UC1: User specified empty tth values (with wavelength) @@ -86,31 +81,38 @@ def test_q_to_tth_bad(q, wavelength, expected_error_type, expected_error_msg): ), ] - -@pytest.mark.parametrize("wavelength, tth, expected_q", params_tth_to_q) -def test_tth_to_q(wavelength, tth, expected_q): - actual_q = tth_to_q(tth, wavelength) +@pytest.mark.parametrize("wavelength, tth, expected_q", test_tth_t_q_params) +def test_tth_to_q(wavelength, tth, expected_q, wavelength_warning_msg): + if wavelength is None: + with pytest.warns(UserWarning, match=re.escape(wavelength_warning_msg)): + actual_q = tth_to_q(tth, wavelength) + else: + actual_q = tth_to_q(tth, wavelength) + assert np.allclose(actual_q, expected_q) - -params_tth_to_q_bad = [ +tth_to_q_bad_params = [ # UC0: user specified an invalid tth value of > 180 degrees (without wavelength) ( - [None, np.array([0, 30, 60, 90, 120, 181])], - [ValueError, "Two theta exceeds 180 degrees. Please check the input values for errors."], + None, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", ), # UC1: user specified an invalid tth value of > 180 degrees (with wavelength) ( - [4 * np.pi, np.array([0, 30, 60, 90, 120, 181])], - [ValueError, "Two theta exceeds 180 degrees. Please check the input values for errors."], + 4 * np.pi, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", ), ] -@pytest.mark.parametrize("inputs, expected", params_tth_to_q_bad) -def test_tth_to_q_bad(inputs, expected): - with pytest.raises(expected[0], match=expected[1]): - tth_to_q(inputs[1], inputs[0]) +@pytest.mark.parametrize("wavelength, tth, expected_error_type, expected_error_msg", tth_to_q_bad_params) +def test_tth_to_q_bad(wavelength, tth, expected_error_type, expected_error_msg): + with pytest.raises(expected_error_type, match=expected_error_msg): + tth_to_q(tth, wavelength) params_q_to_d = [ @@ -212,6 +214,7 @@ def test_tth_to_d_bad(inputs, expected): @pytest.mark.parametrize("inputs, expected", params_d_to_tth) def test_d_to_tth(inputs, expected): actual = d_to_tth(inputs[1], inputs[0]) + assert np.allclose(expected, actual) From 73d8ada4e489a7f84c5bb6f8f0ecc5ecaf695d23 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 00:00:43 -0500 Subject: [PATCH 2/8] Refactor transform tests, pass variables to parameters --- tests/conftest.py | 11 ++-- tests/test_transforms.py | 136 ++++++++++++++++++++------------------- 2 files changed, 77 insertions(+), 70 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 44f66178..866dce39 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -37,11 +37,12 @@ def _load(filename): def do_minimal_tth(): return DiffractionObject(wavelength=2 * np.pi, xarray=np.array([30, 60]), yarray=np.array([1, 2]), xtype="tth") + @pytest.fixture def wavelength_warning_msg(): return ( - "No wavelength has been specified. You can continue to use the DiffractionObject, but " - "some of its powerful features will not be available. " - "To specify a wavelength, if you have do = DiffractionObject(xarray, yarray, 'tth'), " - "you may set do.wavelength = 1.54 for a wavelength of 1.54 angstroms." -) \ No newline at end of file + "No wavelength has been specified. You can continue to use the DiffractionObject, but " + "some of its powerful features will not be available. " + "To specify a wavelength, if you have do = DiffractionObject(xarray, yarray, 'tth'), " + "you may set do.wavelength = 1.54 for a wavelength of 1.54 angstroms." + ) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index e9bb54bf..177745f1 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -5,7 +5,6 @@ from diffpy.utils.transforms import d_to_q, d_to_tth, q_to_d, q_to_tth, tth_to_d, tth_to_q - params_q_to_tth = [ # UC1: Empty q values, no wavelength, return empty arrays (None, np.empty((0)), np.empty((0))), @@ -35,7 +34,7 @@ def test_q_to_tth(wavelength, q, expected_tth, wavelength_warning_msg): assert np.allclose(expected_tth, actual_tth) -params_q_to_tth_bad = [ +test_q_to_tth_bad_params = [ # UC1: user specified invalid q values that result in tth > 180 degrees ( 4 * np.pi, @@ -55,7 +54,7 @@ def test_q_to_tth(wavelength, q, expected_tth, wavelength_warning_msg): ] -@pytest.mark.parametrize("q, wavelength, expected_error_type, expected_error_msg", params_q_to_tth_bad) +@pytest.mark.parametrize("q, wavelength, expected_error_type, expected_error_msg", test_q_to_tth_bad_params) def test_q_to_tth_bad(q, wavelength, expected_error_type, expected_error_msg): with pytest.raises(expected_error_type, match=expected_error_msg): q_to_tth(wavelength, q) @@ -81,6 +80,7 @@ def test_q_to_tth_bad(q, wavelength, expected_error_type, expected_error_msg): ), ] + @pytest.mark.parametrize("wavelength, tth, expected_q", test_tth_t_q_params) def test_tth_to_q(wavelength, tth, expected_q, wavelength_warning_msg): if wavelength is None: @@ -88,10 +88,11 @@ def test_tth_to_q(wavelength, tth, expected_q, wavelength_warning_msg): actual_q = tth_to_q(tth, wavelength) else: actual_q = tth_to_q(tth, wavelength) - + assert np.allclose(actual_q, expected_q) -tth_to_q_bad_params = [ + +test_tth_to_q_bad_params = [ # UC0: user specified an invalid tth value of > 180 degrees (without wavelength) ( None, @@ -109,138 +110,143 @@ def test_tth_to_q(wavelength, tth, expected_q, wavelength_warning_msg): ] -@pytest.mark.parametrize("wavelength, tth, expected_error_type, expected_error_msg", tth_to_q_bad_params) +@pytest.mark.parametrize("wavelength, tth, expected_error_type, expected_error_msg", test_tth_to_q_bad_params) def test_tth_to_q_bad(wavelength, tth, expected_error_type, expected_error_msg): with pytest.raises(expected_error_type, match=expected_error_msg): tth_to_q(tth, wavelength) -params_q_to_d = [ +test_q_to_d_params = [ # UC1: User specified empty q values - ([np.array([])], np.array([])), + (np.array([]), np.array([])), # UC2: User specified valid q values ( - [np.array([0, 1 * np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi, 5 * np.pi])], + np.array([0, 1 * np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi, 5 * np.pi]), np.array([np.inf, 2, 1, 0.66667, 0.5, 0.4]), ), ] -@pytest.mark.parametrize("inputs, expected", params_q_to_d) -def test_q_to_d(inputs, expected): - actual = q_to_d(inputs[0]) - assert np.allclose(actual, expected) +@pytest.mark.parametrize("q, expected_d", test_q_to_d_params) +def test_q_to_d(q, expected_d): + actual_d = q_to_d(q) + assert np.allclose(actual_d, expected_d) -params_d_to_q = [ +test_d_to_q_params = [ # UC1: User specified empty d values - ([np.array([])], np.array([])), + (np.array([]), np.array([])), # UC2: User specified valid d values ( - [np.array([5 * np.pi, 4 * np.pi, 3 * np.pi, 2 * np.pi, np.pi, 0])], + np.array([5 * np.pi, 4 * np.pi, 3 * np.pi, 2 * np.pi, np.pi, 0]), np.array([0.4, 0.5, 0.66667, 1, 2, np.inf]), ), ] -@pytest.mark.parametrize("inputs, expected", params_d_to_q) -def test_d_to_q(inputs, expected): - actual = d_to_q(inputs[0]) - assert np.allclose(actual, expected) +@pytest.mark.parametrize("d, expected_q", test_d_to_q_params) +def test_d_to_q(d, expected_q): + actual_q = d_to_q(d) + assert np.allclose(actual_q, expected_q) -params_tth_to_d = [ +test_tth_to_d_params = [ # UC0: User specified empty tth values (without wavelength) - ([None, np.array([])], np.array([])), + (None, np.array([]), np.array([])), # UC1: User specified empty tth values (with wavelength) - ([4 * np.pi, np.array([])], np.array([])), + (4 * np.pi, np.array([]), np.array([])), # UC2: User specified valid tth values between 0-180 degrees (without wavelength) ( - [None, np.array([0, 30, 60, 90, 120, 180])], + None, + np.array([0, 30, 60, 90, 120, 180]), np.array([0, 1, 2, 3, 4, 5]), ), # UC3: User specified valid tth values between 0-180 degrees (with wavelength) ( - [4 * np.pi, np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0])], + 4 * np.pi, + np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0]), np.array([np.inf, 24.27636, 12.56637, 8.88577, 7.25520, 6.28319]), ), ] -@pytest.mark.parametrize("inputs, expected", params_tth_to_d) -def test_tth_to_d(inputs, expected): - actual = tth_to_d(inputs[1], inputs[0]) - assert np.allclose(actual, expected) +@pytest.mark.parametrize("wavelength, tth, expected_d", test_tth_to_d_params) +def test_tth_to_d(wavelength, tth, expected_d): + actual_d = tth_to_d(tth, wavelength) + assert np.allclose(actual_d, expected_d) -params_tth_to_d_bad = [ +test_tth_to_d_invalid_params = [ # UC1: user specified an invalid tth value of > 180 degrees (without wavelength) ( - [None, np.array([0, 30, 60, 90, 120, 181])], - [ValueError, "Two theta exceeds 180 degrees. Please check the input values for errors."], + None, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", ), # UC2: user specified an invalid tth value of > 180 degrees (with wavelength) ( - [4 * np.pi, np.array([0, 30, 60, 90, 120, 181])], - [ValueError, "Two theta exceeds 180 degrees. Please check the input values for errors."], + 4 * np.pi, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", ), ] -@pytest.mark.parametrize("inputs, expected", params_tth_to_d_bad) -def test_tth_to_d_bad(inputs, expected): - with pytest.raises(expected[0], match=expected[1]): - tth_to_d(inputs[1], inputs[0]) +@pytest.mark.parametrize("wavelength, tth, expected_error_type, expected_error_msg", test_tth_to_d_invalid_params) +def test_tth_to_d_invalid(wavelength, tth, expected_error_type, expected_error_msg): + with pytest.raises(expected_error_type, match=expected_error_msg): + tth_to_d(tth, wavelength) -params_d_to_tth = [ +test_d_to_tth_params = [ # UC1: Empty d values, no wavelength, return empty arrays - ([None, np.empty((0))], np.empty((0))), + (None, np.empty((0)), np.empty((0))), # UC2: Empty d values, wavelength specified, return empty arrays - ([4 * np.pi, np.empty((0))], np.empty(0)), + (4 * np.pi, np.empty((0)), np.empty(0)), # UC3: User specified valid d values, no wavelength, return empty arrays ( - [None, np.array([1, 0.8, 0.6, 0.4, 0.2, 0])], + None, + np.array([1, 0.8, 0.6, 0.4, 0.2, 0]), np.array([0, 1, 2, 3, 4, 5]), ), # UC4: User specified valid d values (with wavelength) ( - [4 * np.pi, np.array([4 * np.pi, 4 / np.sqrt(2) * np.pi, 4 / np.sqrt(3) * np.pi])], + 4 * np.pi, + np.array([4 * np.pi, 4 / np.sqrt(2) * np.pi, 4 / np.sqrt(3) * np.pi]), np.array([60.0, 90.0, 120.0]), ), ] -@pytest.mark.parametrize("inputs, expected", params_d_to_tth) -def test_d_to_tth(inputs, expected): - actual = d_to_tth(inputs[1], inputs[0]) +@pytest.mark.parametrize("wavelength, d, expected_tth", test_d_to_tth_params) +def test_d_to_tth(wavelength, d, expected_tth): + actual_tth = d_to_tth(d, wavelength) + assert np.allclose(actual_tth, expected_tth) - assert np.allclose(expected, actual) - -params_d_to_tth_bad = [ +test_d_to_tth_bad_params = [ # UC1: user specified invalid d values that result in tth > 180 degrees ( - [4 * np.pi, np.array([1.2, 1, 0.8, 0.6, 0.4, 0.2])], - [ - ValueError, - "The supplied input array and wavelength will result in an impossible two-theta. " - "Please check these values and re-instantiate the DiffractionObject with correct values.", - ], + 4 * np.pi, + np.array([1.2, 1, 0.8, 0.6, 0.4, 0.2]), + ValueError, + "The supplied input array and wavelength will result in an impossible two-theta. " + "Please check these values and re-instantiate the DiffractionObject with correct values.", ), # UC2: user specified a wrong wavelength that result in tth > 180 degrees ( - [100, np.array([1, 0.8, 0.6, 0.4, 0.2, 0])], - [ - ValueError, - "The supplied input array and wavelength will result in an impossible two-theta. " - "Please check these values and re-instantiate the DiffractionObject with correct values.", - ], + 100, + np.array([1, 0.8, 0.6, 0.4, 0.2, 0]), + ValueError, + "The supplied input array and wavelength will result in an impossible two-theta. " + "Please check these values and re-instantiate the DiffractionObject with correct values.", ), ] -@pytest.mark.parametrize("inputs, expected", params_d_to_tth_bad) -def test_d_to_tth_bad(inputs, expected): - with pytest.raises(expected[0], match=expected[1]): - d_to_tth(inputs[1], inputs[0]) +@pytest.mark.parametrize("wavelength, d, expected_error_type, expected_error_msg", test_d_to_tth_bad_params) +def test_d_to_tth_bad(wavelength, d, expected_error_type, expected_error_msg): + with pytest.raises(expected_error_type, match=expected_error_msg): + d_to_tth(d, wavelength) From 5e395388634b268b0d9f81b8d3dc7e4d2a7cd43f Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 00:16:16 -0500 Subject: [PATCH 3/8] Remove the use of extra variable for params to prevent global scope in the file --- tests/conftest.py | 8 + tests/test_transforms.py | 327 +++++++++++++++++++-------------------- 2 files changed, 164 insertions(+), 171 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 866dce39..6d23ba55 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -46,3 +46,11 @@ def wavelength_warning_msg(): "To specify a wavelength, if you have do = DiffractionObject(xarray, yarray, 'tth'), " "you may set do.wavelength = 1.54 for a wavelength of 1.54 angstroms." ) + + +@pytest.fixture +def invalid_q_or_d_or_wavelength_error_msg(): + return ( + "The supplied input array and wavelength will result in an impossible two-theta. " + "Please check these values and re-instantiate the DiffractionObject with correct values." + ) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 177745f1..4ebb8a73 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -5,24 +5,25 @@ from diffpy.utils.transforms import d_to_q, d_to_tth, q_to_d, q_to_tth, tth_to_d, tth_to_q -params_q_to_tth = [ - # UC1: Empty q values, no wavelength, return empty arrays - (None, np.empty((0)), np.empty((0))), - # UC2: Empty q values, wavelength specified, return empty arrays - (4 * np.pi, np.empty((0)), np.empty(0)), - # UC3: User specified valid q values, no wavelength, return empty arrays - ( - None, - np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), - np.array([0, 1, 2, 3, 4, 5]), - ), - # UC4: User specified valid q values (with wavelength) - # expected tth values are 2*arcsin(q) in degrees - (4 * np.pi, np.array([0, 1 / np.sqrt(2), 1.0]), np.array([0, 90.0, 180.0])), -] - -@pytest.mark.parametrize("wavelength, q, expected_tth", params_q_to_tth) +@pytest.mark.parametrize( + "wavelength, q, expected_tth", + [ + # UC1: Empty q values, no wavelength, return empty arrays + (None, np.empty((0)), np.empty((0))), + # UC2: Empty q values, wavelength specified, return empty arrays + (4 * np.pi, np.empty((0)), np.empty(0)), + # UC3: user specified valid q values, no wavelength, return empty arrays + ( + None, + np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), + np.array([0, 1, 2, 3, 4, 5]), + ), + # UC4: user specified valid q values (with wavelength) + # expected tth values are 2*arcsin(q) in degrees + (4 * np.pi, np.array([0, 1 / np.sqrt(2), 1.0]), np.array([0, 90.0, 180.0])), + ], +) def test_q_to_tth(wavelength, q, expected_tth, wavelength_warning_msg): if wavelength is None: @@ -34,54 +35,51 @@ def test_q_to_tth(wavelength, q, expected_tth, wavelength_warning_msg): assert np.allclose(expected_tth, actual_tth) -test_q_to_tth_bad_params = [ - # UC1: user specified invalid q values that result in tth > 180 degrees - ( - 4 * np.pi, - np.array([0.2, 0.4, 0.6, 0.8, 1, 1.2]), - ValueError, - "The supplied input array and wavelength will result in an impossible two-theta. " - "Please check these values and re-instantiate the DiffractionObject with correct values.", - ), - # UC2: user specified a wrong wavelength that result in tth > 180 degrees - ( - 100, - np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), - ValueError, - "The supplied input array and wavelength will result in an impossible two-theta. " - "Please check these values and re-instantiate the DiffractionObject with correct values.", - ), -] - - -@pytest.mark.parametrize("q, wavelength, expected_error_type, expected_error_msg", test_q_to_tth_bad_params) -def test_q_to_tth_bad(q, wavelength, expected_error_type, expected_error_msg): +@pytest.mark.parametrize( + "wavelength, q, expected_error_type", + [ + # UC1: user specified invalid q values that result in tth > 180 degrees + ( + 4 * np.pi, + np.array([0.2, 0.4, 0.6, 0.8, 1, 1.2]), + ValueError, + ), + # UC2: user specified a wrong wavelength that result in tth > 180 degrees + ( + 100, + np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), + ValueError, + ), + ], +) +def test_q_to_tth_bad(wavelength, q, expected_error_type, invalid_q_or_d_or_wavelength_error_msg): + expected_error_msg = invalid_q_or_d_or_wavelength_error_msg with pytest.raises(expected_error_type, match=expected_error_msg): q_to_tth(wavelength, q) -test_tth_t_q_params = [ - # UC0: User specified empty tth values (without wavelength) - (None, np.array([]), np.array([])), - # UC1: User specified empty tth values (with wavelength) - (4 * np.pi, np.array([]), np.array([])), - # UC2: User specified valid tth values between 0-180 degrees (without wavelength) - ( - None, - np.array([0, 30, 60, 90, 120, 180]), - np.array([0, 1, 2, 3, 4, 5]), - ), - # UC3: User specified valid tth values between 0-180 degrees (with wavelength) - # expected q values are sin15, sin30, sin45, sin60, sin90 - ( - 4 * np.pi, - np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0]), - np.array([0, 0.258819, 0.5, 0.707107, 0.866025, 1]), - ), -] - - -@pytest.mark.parametrize("wavelength, tth, expected_q", test_tth_t_q_params) +@pytest.mark.parametrize( + "wavelength, tth, expected_q", + [ + # UC0: user specified empty tth values (without wavelength) + (None, np.array([]), np.array([])), + # UC1: user specified empty tth values (with wavelength) + (4 * np.pi, np.array([]), np.array([])), + # UC2: user specified valid tth values between 0-180 degrees (without wavelength) + ( + None, + np.array([0, 30, 60, 90, 120, 180]), + np.array([0, 1, 2, 3, 4, 5]), + ), + # UC3: user specified valid tth values between 0-180 degrees (with wavelength) + # expected q values are sin15, sin30, sin45, sin60, sin90 + ( + 4 * np.pi, + np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0]), + np.array([0, 0.258819, 0.5, 0.707107, 0.866025, 1]), + ), + ], +) def test_tth_to_q(wavelength, tth, expected_q, wavelength_warning_msg): if wavelength is None: with pytest.warns(UserWarning, match=re.escape(wavelength_warning_msg)): @@ -92,115 +90,116 @@ def test_tth_to_q(wavelength, tth, expected_q, wavelength_warning_msg): assert np.allclose(actual_q, expected_q) -test_tth_to_q_bad_params = [ - # UC0: user specified an invalid tth value of > 180 degrees (without wavelength) - ( - None, - np.array([0, 30, 60, 90, 120, 181]), - ValueError, - "Two theta exceeds 180 degrees. Please check the input values for errors.", - ), - # UC1: user specified an invalid tth value of > 180 degrees (with wavelength) - ( - 4 * np.pi, - np.array([0, 30, 60, 90, 120, 181]), - ValueError, - "Two theta exceeds 180 degrees. Please check the input values for errors.", - ), -] - - -@pytest.mark.parametrize("wavelength, tth, expected_error_type, expected_error_msg", test_tth_to_q_bad_params) +@pytest.mark.parametrize( + "wavelength, tth, expected_error_type, expected_error_msg", + [ + # UC0: user specified an invalid tth value of > 180 degrees (without wavelength) + ( + None, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", + ), + # UC1: user specified an invalid tth value of > 180 degrees (with wavelength) + ( + 4 * np.pi, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", + ), + ], +) def test_tth_to_q_bad(wavelength, tth, expected_error_type, expected_error_msg): with pytest.raises(expected_error_type, match=expected_error_msg): tth_to_q(tth, wavelength) -test_q_to_d_params = [ - # UC1: User specified empty q values - (np.array([]), np.array([])), - # UC2: User specified valid q values - ( - np.array([0, 1 * np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi, 5 * np.pi]), - np.array([np.inf, 2, 1, 0.66667, 0.5, 0.4]), - ), -] - - -@pytest.mark.parametrize("q, expected_d", test_q_to_d_params) +@pytest.mark.parametrize( + "q, expected_d", + [ + # UC1: User specified empty q values + (np.array([]), np.array([])), + # UC2: User specified valid q values + ( + np.array([0, 1 * np.pi, 2 * np.pi, 3 * np.pi, 4 * np.pi, 5 * np.pi]), + np.array([np.inf, 2, 1, 0.66667, 0.5, 0.4]), + ), + ], +) def test_q_to_d(q, expected_d): actual_d = q_to_d(q) assert np.allclose(actual_d, expected_d) -test_d_to_q_params = [ - # UC1: User specified empty d values - (np.array([]), np.array([])), - # UC2: User specified valid d values - ( - np.array([5 * np.pi, 4 * np.pi, 3 * np.pi, 2 * np.pi, np.pi, 0]), - np.array([0.4, 0.5, 0.66667, 1, 2, np.inf]), - ), -] - - -@pytest.mark.parametrize("d, expected_q", test_d_to_q_params) +@pytest.mark.parametrize( + "d, expected_q", + [ + # UC1: User specified empty d values + (np.array([]), np.array([])), + # UC2: User specified valid d values + ( + np.array([5 * np.pi, 4 * np.pi, 3 * np.pi, 2 * np.pi, np.pi, 0]), + np.array([0.4, 0.5, 0.66667, 1, 2, np.inf]), + ), + ], +) def test_d_to_q(d, expected_q): actual_q = d_to_q(d) assert np.allclose(actual_q, expected_q) -test_tth_to_d_params = [ - # UC0: User specified empty tth values (without wavelength) - (None, np.array([]), np.array([])), - # UC1: User specified empty tth values (with wavelength) - (4 * np.pi, np.array([]), np.array([])), - # UC2: User specified valid tth values between 0-180 degrees (without wavelength) - ( - None, - np.array([0, 30, 60, 90, 120, 180]), - np.array([0, 1, 2, 3, 4, 5]), - ), - # UC3: User specified valid tth values between 0-180 degrees (with wavelength) - ( - 4 * np.pi, - np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0]), - np.array([np.inf, 24.27636, 12.56637, 8.88577, 7.25520, 6.28319]), - ), -] - - -@pytest.mark.parametrize("wavelength, tth, expected_d", test_tth_to_d_params) +@pytest.mark.parametrize( + "wavelength, tth, expected_d", + [ + # UC0: User specified empty tth values (without wavelength) + (None, np.array([]), np.array([])), + # UC1: User specified empty tth values (with wavelength) + (4 * np.pi, np.array([]), np.array([])), + # UC2: User specified valid tth values between 0-180 degrees (without wavelength) + ( + None, + np.array([0, 30, 60, 90, 120, 180]), + np.array([0, 1, 2, 3, 4, 5]), + ), + # UC3: User specified valid tth values between 0-180 degrees (with wavelength) + ( + 4 * np.pi, + np.array([0, 30.0, 60.0, 90.0, 120.0, 180.0]), + np.array([np.inf, 24.27636, 12.56637, 8.88577, 7.25520, 6.28319]), + ), + ], +) def test_tth_to_d(wavelength, tth, expected_d): actual_d = tth_to_d(tth, wavelength) assert np.allclose(actual_d, expected_d) -test_tth_to_d_invalid_params = [ - # UC1: user specified an invalid tth value of > 180 degrees (without wavelength) - ( - None, - np.array([0, 30, 60, 90, 120, 181]), - ValueError, - "Two theta exceeds 180 degrees. Please check the input values for errors.", - ), - # UC2: user specified an invalid tth value of > 180 degrees (with wavelength) - ( - 4 * np.pi, - np.array([0, 30, 60, 90, 120, 181]), - ValueError, - "Two theta exceeds 180 degrees. Please check the input values for errors.", - ), -] - - -@pytest.mark.parametrize("wavelength, tth, expected_error_type, expected_error_msg", test_tth_to_d_invalid_params) +@pytest.mark.parametrize( + "wavelength, tth, expected_error_type, expected_error_msg", + [ + # UC1: user specified an invalid tth value of > 180 degrees (without wavelength) + ( + None, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", + ), + # UC2: user specified an invalid tth value of > 180 degrees (with wavelength) + ( + 4 * np.pi, + np.array([0, 30, 60, 90, 120, 181]), + ValueError, + "Two theta exceeds 180 degrees. Please check the input values for errors.", + ), + ], +) def test_tth_to_d_invalid(wavelength, tth, expected_error_type, expected_error_msg): with pytest.raises(expected_error_type, match=expected_error_msg): tth_to_d(tth, wavelength) -test_d_to_tth_params = [ + +@pytest.mark.parametrize("wavelength, d, expected_tth", [ # UC1: Empty d values, no wavelength, return empty arrays (None, np.empty((0)), np.empty((0))), # UC2: Empty d values, wavelength specified, return empty arrays @@ -217,36 +216,22 @@ def test_tth_to_d_invalid(wavelength, tth, expected_error_type, expected_error_m np.array([4 * np.pi, 4 / np.sqrt(2) * np.pi, 4 / np.sqrt(3) * np.pi]), np.array([60.0, 90.0, 120.0]), ), -] - - -@pytest.mark.parametrize("wavelength, d, expected_tth", test_d_to_tth_params) +]) def test_d_to_tth(wavelength, d, expected_tth): actual_tth = d_to_tth(d, wavelength) assert np.allclose(actual_tth, expected_tth) -test_d_to_tth_bad_params = [ - # UC1: user specified invalid d values that result in tth > 180 degrees - ( - 4 * np.pi, - np.array([1.2, 1, 0.8, 0.6, 0.4, 0.2]), - ValueError, - "The supplied input array and wavelength will result in an impossible two-theta. " - "Please check these values and re-instantiate the DiffractionObject with correct values.", - ), - # UC2: user specified a wrong wavelength that result in tth > 180 degrees - ( - 100, - np.array([1, 0.8, 0.6, 0.4, 0.2, 0]), - ValueError, - "The supplied input array and wavelength will result in an impossible two-theta. " - "Please check these values and re-instantiate the DiffractionObject with correct values.", - ), -] - - -@pytest.mark.parametrize("wavelength, d, expected_error_type, expected_error_msg", test_d_to_tth_bad_params) -def test_d_to_tth_bad(wavelength, d, expected_error_type, expected_error_msg): +@pytest.mark.parametrize( + "wavelength, d, expected_error_type", + [ + # UC1: user specified invalid d values that result in tth > 180 degrees + (4 * np.pi, np.array([1.2, 1, 0.8, 0.6, 0.4, 0.2]), ValueError), + # UC2: user specified a wrong wavelength that result in tth > 180 degrees + (100, np.array([1, 0.8, 0.6, 0.4, 0.2, 0]), ValueError), + ], +) +def test_d_to_tth_bad(wavelength, d, expected_error_type, invalid_q_or_d_or_wavelength_error_msg): + expected_error_msg = invalid_q_or_d_or_wavelength_error_msg with pytest.raises(expected_error_type, match=expected_error_msg): d_to_tth(d, wavelength) From cdf96dffe5c1745af5ddb952592f310428d23fa5 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 00:17:38 -0500 Subject: [PATCH 4/8] Apply pre-commit --- tests/test_transforms.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 4ebb8a73..487cf6ca 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -198,25 +198,27 @@ def test_tth_to_d_invalid(wavelength, tth, expected_error_type, expected_error_m tth_to_d(tth, wavelength) - -@pytest.mark.parametrize("wavelength, d, expected_tth", [ - # UC1: Empty d values, no wavelength, return empty arrays - (None, np.empty((0)), np.empty((0))), - # UC2: Empty d values, wavelength specified, return empty arrays - (4 * np.pi, np.empty((0)), np.empty(0)), - # UC3: User specified valid d values, no wavelength, return empty arrays - ( - None, - np.array([1, 0.8, 0.6, 0.4, 0.2, 0]), - np.array([0, 1, 2, 3, 4, 5]), - ), - # UC4: User specified valid d values (with wavelength) - ( - 4 * np.pi, - np.array([4 * np.pi, 4 / np.sqrt(2) * np.pi, 4 / np.sqrt(3) * np.pi]), - np.array([60.0, 90.0, 120.0]), - ), -]) +@pytest.mark.parametrize( + "wavelength, d, expected_tth", + [ + # UC1: Empty d values, no wavelength, return empty arrays + (None, np.empty((0)), np.empty((0))), + # UC2: Empty d values, wavelength specified, return empty arrays + (4 * np.pi, np.empty((0)), np.empty(0)), + # UC3: User specified valid d values, no wavelength, return empty arrays + ( + None, + np.array([1, 0.8, 0.6, 0.4, 0.2, 0]), + np.array([0, 1, 2, 3, 4, 5]), + ), + # UC4: User specified valid d values (with wavelength) + ( + 4 * np.pi, + np.array([4 * np.pi, 4 / np.sqrt(2) * np.pi, 4 / np.sqrt(3) * np.pi]), + np.array([60.0, 90.0, 120.0]), + ), + ], +) def test_d_to_tth(wavelength, d, expected_tth): actual_tth = d_to_tth(d, wavelength) assert np.allclose(actual_tth, expected_tth) From ef751973519f983055f28c273092b017afecf9e2 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 16:45:56 -0500 Subject: [PATCH 5/8] improve UC comment for test_q_to_tth func --- tests/test_transforms.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 487cf6ca..70660033 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -9,18 +9,23 @@ @pytest.mark.parametrize( "wavelength, q, expected_tth", [ - # UC1: Empty q values, no wavelength, return empty arrays + # UC1.1: User specified empty 'q' and no 'wavelength'. + # Expect empty 'tth' array and UserWarning about missing wavelength. (None, np.empty((0)), np.empty((0))), - # UC2: Empty q values, wavelength specified, return empty arrays + + # UC1.2: User specified empty 'q' and 'wavelength'. Expect empty 'tth' array. (4 * np.pi, np.empty((0)), np.empty(0)), - # UC3: user specified valid q values, no wavelength, return empty arrays + + # UC2.1: User specified non-empty 'q' values and no 'wavelength'. + # Expect non-empty 'tth' array and UserWarning about missing wavelength. ( None, np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), np.array([0, 1, 2, 3, 4, 5]), ), - # UC4: user specified valid q values (with wavelength) - # expected tth values are 2*arcsin(q) in degrees + + # UC2.2: User specified non-empty 'q' values and 'wavelength'. + # Expect tth values are 2*arcsin(q) in degrees. (4 * np.pi, np.array([0, 1 / np.sqrt(2), 1.0]), np.array([0, 90.0, 180.0])), ], ) From 8ebaede0549d4988162fe828be92ebff39f9971d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:46:06 +0000 Subject: [PATCH 6/8] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/test_transforms.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 70660033..d3e51e35 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -12,10 +12,8 @@ # UC1.1: User specified empty 'q' and no 'wavelength'. # Expect empty 'tth' array and UserWarning about missing wavelength. (None, np.empty((0)), np.empty((0))), - # UC1.2: User specified empty 'q' and 'wavelength'. Expect empty 'tth' array. (4 * np.pi, np.empty((0)), np.empty(0)), - # UC2.1: User specified non-empty 'q' values and no 'wavelength'. # Expect non-empty 'tth' array and UserWarning about missing wavelength. ( @@ -23,7 +21,6 @@ np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), np.array([0, 1, 2, 3, 4, 5]), ), - # UC2.2: User specified non-empty 'q' values and 'wavelength'. # Expect tth values are 2*arcsin(q) in degrees. (4 * np.pi, np.array([0, 1 / np.sqrt(2), 1.0]), np.array([0, 90.0, 180.0])), From 9343e86fccb8080e65818dc4456bde3325fae348 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Sun, 15 Dec 2024 21:38:10 -0500 Subject: [PATCH 7/8] Do not call UCs for test function --- tests/test_transforms.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index d3e51e35..5fb2326f 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -9,20 +9,22 @@ @pytest.mark.parametrize( "wavelength, q, expected_tth", [ - # UC1.1: User specified empty 'q' and no 'wavelength'. - # Expect empty 'tth' array and UserWarning about missing wavelength. + # Case 1: Allow empty arrays for q + # 1. Empty q values, no wavelength, return empty arrays (None, np.empty((0)), np.empty((0))), - # UC1.2: User specified empty 'q' and 'wavelength'. Expect empty 'tth' array. + # 2. Empty q values, wavelength specified, return empty arrays (4 * np.pi, np.empty((0)), np.empty(0)), - # UC2.1: User specified non-empty 'q' values and no 'wavelength'. - # Expect non-empty 'tth' array and UserWarning about missing wavelength. + + # Case 2: Allow wavelength to be missing. + # Valid q values, no wavelength, return index array ( None, np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), np.array([0, 1, 2, 3, 4, 5]), ), - # UC2.2: User specified non-empty 'q' values and 'wavelength'. - # Expect tth values are 2*arcsin(q) in degrees. + + # Case 3: Correctly specified q and wavelength + # Expected tth values are 2*arcsin(q) in degrees (4 * np.pi, np.array([0, 1 / np.sqrt(2), 1.0]), np.array([0, 90.0, 180.0])), ], ) From d962c1b37abcc3a873db22271627ca184f9fa9f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 02:38:44 +0000 Subject: [PATCH 8/8] [pre-commit.ci] auto fixes from pre-commit hooks --- tests/test_transforms.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index 5fb2326f..cf6a6ebb 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -14,7 +14,6 @@ (None, np.empty((0)), np.empty((0))), # 2. Empty q values, wavelength specified, return empty arrays (4 * np.pi, np.empty((0)), np.empty(0)), - # Case 2: Allow wavelength to be missing. # Valid q values, no wavelength, return index array ( @@ -22,7 +21,6 @@ np.array([0, 0.2, 0.4, 0.6, 0.8, 1]), np.array([0, 1, 2, 3, 4, 5]), ), - # Case 3: Correctly specified q and wavelength # Expected tth values are 2*arcsin(q) in degrees (4 * np.pi, np.array([0, 1 / np.sqrt(2), 1.0]), np.array([0, 90.0, 180.0])),