Skip to content
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

Refactor __add__ operation in DiffractionObject and add tests #285

Merged
merged 11 commits into from
Dec 29, 2024

Conversation

bobleesj
Copy link
Contributor

@bobleesj bobleesj commented Dec 27, 2024

Starting with __add__ first, and will make separate PRs for subtraction, multiplication, division, etc. after review


def __radd__(self, other):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

radd i think we don't need?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may. Are you sure? Anyway, we can test and see.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are correct - added __radd__ back using __radd__ = __add__

please see a new test below for do + scalar as well as scalar + do

Copy link

codecov bot commented Dec 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (3f2d0a4) to head (da70bd6).
Report is 12 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #285   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            8         8           
  Lines          408       446   +38     
=========================================
+ Hits           408       446   +38     
Files with missing lines Coverage Δ
tests/conftest.py 100.00% <100.00%> (ø)
tests/test_diffraction_objects.py 100.00% <100.00%> (ø)

multiplied.on_q[1] = self.on_q[1] * other.on_q[1]
return multiplied

def __rmul__(self, other):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed since identical as __mul__

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test and make sure it is ok to remove this. On balance, I probably want to leave the 'r' functionalities



@pytest.mark.parametrize(
"LHS_all_arrays, RHS_all_arrays, expected_all_arrays_sum",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. test adding do1 + do2



@pytest.mark.parametrize(
"starting_all_arrays, scalar_value, expected_all_arrays",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. test adding do + number

# Add a string to a DO object, expect TypeError, only scalar (int, float) allowed for addition
do_LHS = do_minimal_tth
with pytest.raises(TypeError, match=re.escape(invalid_add_type_error_msg)):
do_LHS + "string_value"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string not allowed

do_LHS = do_minimal
do_RHS = do_minimal_tth
with pytest.raises(ValueError, match=re.escape(x_grid_size_mismatch_error_msg)):
do_LHS + do_RHS
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

different lengths of xarray, not allowed

Copy link
Contributor Author

@bobleesj bobleesj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbillinge ready for review

@bobleesj bobleesj changed the title Fix __add__ operation in DiffractionObject and add tests Refactor __add__ operation in DiffractionObject and add tests Dec 27, 2024
@bobleesj bobleesj mentioned this pull request Dec 27, 2024
9 tasks
Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see inline.


def __radd__(self, other):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may. Are you sure? Anyway, we can test and see.

multiplied.on_q[1] = self.on_q[1] * other.on_q[1]
return multiplied

def __rmul__(self, other):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test and make sure it is ok to remove this. On balance, I probably want to leave the 'r' functionalities

tests/test_diffraction_objects.py Show resolved Hide resolved
do = do_minimal_tth
assert np.allclose(do.all_arrays, starting_all_arrays)
do_sum_RHS = do + scalar_to_add
do_sum_LHS = scalar_to_add + do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test for __radd__

Copy link
Contributor Author

@bobleesj bobleesj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbillinge

ready for review

right, radd is back. rmul is also back.

If this looks okay, then I will further implement the rest of the remaining operations

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please see inline comments.

src/diffpy/utils/diffraction_objects.py Show resolved Hide resolved
invalid_add_type_emsg = (
"You may only add a DiffractionObject with another DiffractionObject or a scalar value. "
"Please rerun by adding another DiffractionObject instance or a scalar value. "
"e.g., my_do_1 + my_do_2 or my_do + 10"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for completeness, lets also add a radd as an example here. We could say "to add 10 to all intensities use..."


Examples
--------
Add a scalar value to the xarrays of the DiffractionObject instance:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add the radd example here too.

tests/test_diffraction_objects.py Outdated Show resolved Hide resolved
@pytest.mark.parametrize(
"starting_all_arrays, scalar_to_add, expected_all_arrays",
[
# Test scalar addition to xarray values (q, tth, d) and expect no change to yarray values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the add operation is supposed to operate on the yarray leaving xarrays unaffected.

@bobleesj
Copy link
Contributor Author

@sbillinge

the add operation is supposed to operate on the yarray leaving xarrays unaffected.

I see, I just refactored the earlier code which had xarrays adding up

        if isinstance(other, int) or isinstance(other, float) or isinstance(other, np.ndarray):
            summed.on_tth[1] = self.on_tth[1] + other
            summed.on_q[1] = self.on_q[1] + other

I will fix these.

@sbillinge
Copy link
Contributor

@sbillinge

the add operation is supposed to operate on the yarray leaving xarrays unaffected.

I see, I just refactored the earlier code which had xarrays adding up

        if isinstance(other, int) or isinstance(other, float) or isinstance(other, np.ndarray):
            summed.on_tth[1] = self.on_tth[1] + other
            summed.on_q[1] = self.on_q[1] + other

I will fix these.

Those were the y-arrays 😂. On_q[0] is the q and on_q[1] the intensities so it is more logical for users when plotting.

>>> new_do = my_do_1 + my_do_2
"""

self._check_operation_compatibility(other)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a private func that checks the validity of other

def _check_operation_compatibility(self, other):
        if not isinstance(other, (DiffractionObject, int, float)):
            raise TypeError(invalid_add_type_emsg)
        if isinstance(other, DiffractionObject):
            self_yarray = self.all_arrays[:, 0]
            other_yarray = other.all_arrays[:, 0]
            if len(self_yarray) != len(other_yarray):
                raise ValueError(y_grid_length_mismatch_emsg)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! it may be more readable if we use

if shape(self.all_arrays) != shape(other.all_arrays)

to accomplish the same thing?

@bobleesj
Copy link
Contributor Author

bobleesj commented Dec 29, 2024

@sbillinge ready for review! - addressed all of the comments

Copy link
Contributor

@sbillinge sbillinge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will merge this, but please see my comment on the private function. No need to make a special PR for that, but if you want, fix i tin any other PR....... or not.....

>>> new_do = my_do_1 + my_do_2
"""

self._check_operation_compatibility(other)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! it may be more readable if we use

if shape(self.all_arrays) != shape(other.all_arrays)

to accomplish the same thing?

@sbillinge sbillinge merged commit 1ea8e9a into diffpy:main Dec 29, 2024
5 checks passed
@bobleesj
Copy link
Contributor Author

I will merge this, but please see my comment on the private function. No need to make a special PR for that, but if you want, fix i tin any other PR....... or not.....

Yup will do 👍

@bobleesj bobleesj deleted the do-ops branch December 29, 2024 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants