-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Support *, /, - operations between two DiffractionObjects or scalar #293
Merged
Merged
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
630f00e
feat: implement __sub__ feature for DiffractionObject
bobleesj ddeeb26
feat: implement __mul__ for DiffracitonObject wih test funcs
bobleesj eb2941b
feat: add __div__ function to DiffractionObject
bobleesj 48e4c58
chore: add news
bobleesj e8653ef
test: improve comments for tests
bobleesj 116280c
[pre-commit.ci] auto fixes from pre-commit hooks
pre-commit-ci[bot] 6656dab
test: add higher-level test comments
bobleesj 21711fb
fix: shorten all_arrays shape check
sbillinge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
**Added:** | ||
|
||
* addition, multiplication, subtraction, and division operators between two DiffractionObject instances or a scalar value with another DiffractionObject for modifying yarray (intensity) values. | ||
|
||
**Changed:** | ||
|
||
* <news item> | ||
|
||
**Deprecated:** | ||
|
||
* <news item> | ||
|
||
**Removed:** | ||
|
||
* <news item> | ||
|
||
**Fixed:** | ||
|
||
* <news item> | ||
|
||
**Security:** | ||
|
||
* <news item> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -713,75 +713,174 @@ def test_copy_object(do_minimal): | |
|
||
|
||
@pytest.mark.parametrize( | ||
"starting_all_arrays, scalar_to_add, expected_all_arrays", | ||
"operation, starting_yarray, scalar_value, expected_yarray", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. operation b/w scalar and do |
||
[ | ||
# Test scalar addition to yarray values (intensity) and expect no change to xarrays (q, tth, d) | ||
( # C1: Add integer of 5, expect yarray to increase by by 5 | ||
np.array([[1.0, 0.51763809, 30.0, 12.13818192], [2.0, 1.0, 60.0, 6.28318531]]), | ||
# C1: Test scalar addition to y-values (intensity), expect no change to x-values (q, tth, d) | ||
( # 1. Add 5 | ||
"add", | ||
np.array([1.0, 2.0]), | ||
5, | ||
np.array([[6.0, 0.51763809, 30.0, 12.13818192], [7.0, 1.0, 60.0, 6.28318531]]), | ||
np.array([6.0, 7.0]), | ||
), | ||
( # C2: Add float of 5.1, expect yarray to be added by 5.1 | ||
np.array([[1.0, 0.51763809, 30.0, 12.13818192], [2.0, 1.0, 60.0, 6.28318531]]), | ||
( # 2. Add 5.1 | ||
"add", | ||
np.array([1.0, 2.0]), | ||
5.1, | ||
np.array([[6.1, 0.51763809, 30.0, 12.13818192], [7.1, 1.0, 60.0, 6.28318531]]), | ||
np.array([6.1, 7.1]), | ||
), | ||
# C2: Test scalar subtraction to y-values (intensity), expect no change to x-values (q, tth, d) | ||
( # 1. Subtract 1 | ||
"sub", | ||
np.array([1.0, 2.0]), | ||
1, | ||
np.array([0.0, 1.0]), | ||
), | ||
( # 2. Subtract 0.5 | ||
"sub", | ||
np.array([1.0, 2.0]), | ||
0.5, | ||
np.array([0.5, 1.5]), | ||
), | ||
# C3: Test scalar multiplication to y-values (intensity), expect no change to x-values (q, tth, d) | ||
( # 1. Multiply by 2 | ||
"mul", | ||
np.array([1.0, 2.0]), | ||
2, | ||
np.array([2.0, 4.0]), | ||
), | ||
( # 2. Multiply by 2.5 | ||
"mul", | ||
np.array([1.0, 2.0]), | ||
2.5, | ||
np.array([2.5, 5.0]), | ||
), | ||
# C4: Test scalar division to y-values (intensity), expect no change to x-values (q, tth, d) | ||
( # 1. Divide by 2 | ||
"div", | ||
np.array([1.0, 2.0]), | ||
2, | ||
np.array([0.5, 1.0]), | ||
), | ||
( # 2. Divide by 2.5 | ||
"div", | ||
np.array([1.0, 2.0]), | ||
2.5, | ||
np.array([0.4, 0.8]), | ||
), | ||
], | ||
) | ||
def test_addition_operator_by_scalar(starting_all_arrays, scalar_to_add, expected_all_arrays, do_minimal_tth): | ||
def test_scalar_operations(operation, starting_yarray, scalar_value, expected_yarray, do_minimal_tth): | ||
do = do_minimal_tth | ||
assert np.allclose(do.all_arrays, starting_all_arrays) | ||
do_scalar_right_sum = do + scalar_to_add | ||
assert np.allclose(do_scalar_right_sum.all_arrays, expected_all_arrays) | ||
do_scalar_left_sum = scalar_to_add + do | ||
assert np.allclose(do_scalar_left_sum.all_arrays, expected_all_arrays) | ||
expected_xarray_constant = np.array([[0.51763809, 30.0, 12.13818192], [1.0, 60.0, 6.28318531]]) | ||
assert np.allclose(do.all_arrays[:, [1, 2, 3]], expected_xarray_constant) | ||
assert np.allclose(do.all_arrays[:, 0], starting_yarray) | ||
if operation == "add": | ||
do_right_op = do + scalar_value | ||
do_left_op = scalar_value + do | ||
elif operation == "sub": | ||
do_right_op = do - scalar_value | ||
do_left_op = scalar_value - do | ||
elif operation == "mul": | ||
do_right_op = do * scalar_value | ||
do_left_op = scalar_value * do | ||
elif operation == "div": | ||
do_right_op = do / scalar_value | ||
do_left_op = scalar_value / do | ||
assert np.allclose(do_right_op.all_arrays[:, 0], expected_yarray) | ||
assert np.allclose(do_left_op.all_arrays[:, 0], expected_yarray) | ||
# Ensure x-values are unchanged | ||
assert np.allclose(do_right_op.all_arrays[:, [1, 2, 3]], expected_xarray_constant) | ||
assert np.allclose(do_left_op.all_arrays[:, [1, 2, 3]], expected_xarray_constant) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"do_1_all_arrays, " | ||
"do_2_all_arrays, " | ||
"expected_do_1_all_arrays_with_y_summed, " | ||
"expected_do_2_all_arrays_with_y_summed", | ||
"operation, " "expected_do_1_all_arrays_with_y_modified, " "expected_do_2_all_arrays_with_y_modified", | ||
[ | ||
# Test addition of two DO objects, expect combined yarray values and no change to xarrays ((q, tth, d) | ||
( # C1: Add two DO objects, expect sum of yarray values | ||
(np.array([[1.0, 0.51763809, 30.0, 12.13818192], [2.0, 1.0, 60.0, 6.28318531]]),), | ||
(np.array([[1.0, 6.28318531, 100.70777771, 1], [2.0, 3.14159265, 45.28748053, 2.0]]),), | ||
(np.array([[2.0, 0.51763809, 30.0, 12.13818192], [4.0, 1.0, 60.0, 6.28318531]]),), | ||
(np.array([[2.0, 6.28318531, 100.70777771, 1], [4.0, 3.14159265, 45.28748053, 2.0]]),), | ||
( # Test addition of two DO objects, expect combined yarray values | ||
"add", | ||
np.array([[2.0, 0.51763809, 30.0, 12.13818192], [4.0, 1.0, 60.0, 6.28318531]]), | ||
np.array([[2.0, 6.28318531, 100.70777771, 1], [4.0, 3.14159265, 45.28748053, 2.0]]), | ||
), | ||
( # Test subtraction of two DO objects, expect differences in yarray values | ||
"sub", | ||
np.array([[0.0, 0.51763809, 30.0, 12.13818192], [0.0, 1.0, 60.0, 6.28318531]]), | ||
np.array([[0.0, 6.28318531, 100.70777771, 1], [0.0, 3.14159265, 45.28748053, 2.0]]), | ||
), | ||
( # Test multiplication of two DO objects, expect multiplication in yarray values | ||
"mul", | ||
np.array([[1.0, 0.51763809, 30.0, 12.13818192], [4.0, 1.0, 60.0, 6.28318531]]), | ||
np.array([[1.0, 6.28318531, 100.70777771, 1], [4.0, 3.14159265, 45.28748053, 2.0]]), | ||
), | ||
( # Test division of two DO objects, expect division in yarray values | ||
"div", | ||
np.array([[1.0, 0.51763809, 30.0, 12.13818192], [1.0, 1.0, 60.0, 6.28318531]]), | ||
np.array([[1.0, 6.28318531, 100.70777771, 1], [1.0, 3.14159265, 45.28748053, 2.0]]), | ||
), | ||
], | ||
) | ||
def test_addition_operator_by_another_do( | ||
do_1_all_arrays, | ||
do_2_all_arrays, | ||
expected_do_1_all_arrays_with_y_summed, | ||
expected_do_2_all_arrays_with_y_summed, | ||
def test_binary_operator_on_do( | ||
operation, | ||
expected_do_1_all_arrays_with_y_modified, | ||
expected_do_2_all_arrays_with_y_modified, | ||
do_minimal_tth, | ||
do_minimal_d, | ||
): | ||
do_1 = do_minimal_tth | ||
assert np.allclose(do_1.all_arrays, do_1_all_arrays) | ||
do_2 = do_minimal_d | ||
assert np.allclose(do_2.all_arrays, do_2_all_arrays) | ||
assert np.allclose((do_1 + do_2).all_arrays, expected_do_1_all_arrays_with_y_summed) | ||
assert np.allclose((do_2 + do_1).all_arrays, expected_do_2_all_arrays_with_y_summed) | ||
assert np.allclose( | ||
do_1.all_arrays, np.array([[1.0, 0.51763809, 30.0, 12.13818192], [2.0, 1.0, 60.0, 6.28318531]]) | ||
) | ||
assert np.allclose( | ||
do_2.all_arrays, np.array([[1.0, 6.28318531, 100.70777771, 1], [2.0, 3.14159265, 45.28748053, 2.0]]) | ||
) | ||
|
||
if operation == "add": | ||
do_1_y_modified = do_1 + do_2 | ||
do_2_y_modified = do_2 + do_1 | ||
elif operation == "sub": | ||
do_1_y_modified = do_1 - do_2 | ||
do_2_y_modified = do_2 - do_1 | ||
elif operation == "mul": | ||
do_1_y_modified = do_1 * do_2 | ||
do_2_y_modified = do_2 * do_1 | ||
elif operation == "div": | ||
do_1_y_modified = do_1 / do_2 | ||
do_2_y_modified = do_2 / do_1 | ||
|
||
def test_addition_operator_invalid_type(do_minimal_tth, invalid_add_type_error_msg): | ||
# Add a string to a DO object, expect TypeError, only scalar (int, float) allowed for addition | ||
do = do_minimal_tth | ||
with pytest.raises(TypeError, match=re.escape(invalid_add_type_error_msg)): | ||
do + "string_value" | ||
with pytest.raises(TypeError, match=re.escape(invalid_add_type_error_msg)): | ||
"string_value" + do | ||
assert np.allclose(do_1_y_modified.all_arrays, expected_do_1_all_arrays_with_y_modified) | ||
assert np.allclose(do_2_y_modified.all_arrays, expected_do_2_all_arrays_with_y_modified) | ||
|
||
|
||
def test_addition_operator_invalid_yarray_length(do_minimal, do_minimal_tth, y_grid_size_mismatch_error_msg): | ||
# Combine two DO objects, one with empty xarrays (do_minimal) and the other with non-empty xarrays | ||
def test_operator_invalid_type(do_minimal_tth, invalid_add_type_error_msg): | ||
do = do_minimal_tth | ||
invalid_value = "string_value" | ||
operations = [ | ||
(lambda x, y: x + y), # Test addition | ||
(lambda x, y: x - y), # Test subtraction | ||
(lambda x, y: x * y), # Test multiplication | ||
(lambda x, y: x / y), # Test division | ||
] | ||
# Add a string to a DiffractionObject, expect TypeError | ||
for operation in operations: | ||
with pytest.raises(TypeError, match=re.escape(invalid_add_type_error_msg)): | ||
operation(do, invalid_value) | ||
with pytest.raises(TypeError, match=re.escape(invalid_add_type_error_msg)): | ||
operation(invalid_value, do) | ||
|
||
|
||
@pytest.mark.parametrize("operation", ["add", "sub", "mul", "div"]) | ||
def test_operator_invalid_yarray_length(operation, do_minimal, do_minimal_tth, y_grid_size_mismatch_error_msg): | ||
do_1 = do_minimal | ||
do_2 = do_minimal_tth | ||
assert len(do_1.all_arrays[:, 0]) == 0 | ||
assert len(do_2.all_arrays[:, 0]) == 2 | ||
# Add two DO objets with different yarray lengths, expect ValueError | ||
with pytest.raises(ValueError, match=re.escape(y_grid_size_mismatch_error_msg)): | ||
do_1 + do_2 | ||
if operation == "add": | ||
do_1 + do_2 | ||
elif operation == "sub": | ||
do_1 - do_2 | ||
elif operation == "mul": | ||
do_1 * do_2 | ||
elif operation == "div": | ||
do_1 / do_2 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sbillinge as suggested - using
shape
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the idea for using shape was to shorten code and make it more readable, so
is replaced by