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

Add default and set to zero masking option for specreduce operations. #216

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

cshanahan1
Copy link
Contributor

(incomplete draft, just look at tracing and background for now)

Copy link

codecov bot commented May 3, 2024

Codecov Report

Attention: Patch coverage is 37.20930% with 54 lines in your changes missing coverage. Please review.

Project coverage is 45.56%. Comparing base (6b8e995) to head (d4d528d).

Files with missing lines Patch % Lines
specreduce/core.py 18.91% 30 Missing ⚠️
specreduce/tracing.py 58.33% 15 Missing ⚠️
specreduce/background.py 22.22% 7 Missing ⚠️
specreduce/extract.py 50.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #216       +/-   ##
===========================================
- Coverage   83.37%   45.56%   -37.81%     
===========================================
  Files          13       13               
  Lines        1137     1196       +59     
===========================================
- Hits          948      545      -403     
- Misses        189      651      +462     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tepickering
Copy link
Contributor

finally got a chance to at least look through the code changes. i like it so far! let me know when it's ready for a fuller review and i'll try playing with it in more depth.

@camipacifici
Copy link

I am pretty sure it is! Please go ahead. Thank you!

@tepickering
Copy link
Contributor

there are a bunch of warnings in the RTD build. they look like malformed references, but need a deeper look to see what's the actual cause.

@tepickering
Copy link
Contributor

i'm confused why python 3.8 and 3.9 tests are being run. a rebase might be needed, though i thought this was forked after those tests were removed.

@@ -32,9 +32,9 @@ class Background(_ImageParser):
----------
image : `~astropy.nddata.NDData`-like or array-like
image with 2-D spectral image data
traces : trace, int, float (single or list)
traces : List, `tracing.Trace`, int, float
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 this is one of the RTD complaints. should be ~specreduce.tracing.Trace, i believe.

Individual or list of trace object(s) (or integers/floats to define
FlatTraces) to extract the background. If None, a FlatTrace at the
FlatTraces) to extract the background. If None, a `FlatTrace` at the
Copy link
Contributor

Choose a reason for hiding this comment

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

should be ``FlatTrace`` or a proper sphinx reference

crossdisp_axis : int
cross-dispersion axis
[default: 0]
mask_treatment : string, optional
The method for handling masked or non-finite data. Choice of `filter`,
Copy link
Contributor

Choose a reason for hiding this comment

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

here and elsewhere need to use double single-quotes for inline literal/code. pretty sure this is what RTD has been complaining about...

@cshanahan1 cshanahan1 marked this pull request as ready for review September 18, 2024 19:51
# handled as well. Note that input data may be modified if a fill value
# is chosen to handle masked data. The returned image will always have
# `image.mask` even if there are no nonfinte or masked values.
img, mask = self._mask_and_nonfinite_data_handling(image=img, mask=mask)
Copy link
Contributor

@hpparvi hpparvi Oct 25, 2024

Choose a reason for hiding this comment

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

_get_data_from_image is a static method, so self is not defined. This could be fixed by making _mask_and_nonfinite_data_handling a static method as well and calling it as _ImageParser._mask_and_nonfinite_data_handling(...), but this would require removing the self.image.mask reference in line 144.

Also, _ImageParser never assigns an image to self.image. This could be fixed by changing the line 55

img = self._get_data_from_image(image, disp_axis=disp_axis)
return img

into

self.image = self._get_data_from_image(image, disp_axis=disp_axis)
return self.image

Then again, _ImageParser seems to be meant to be a pure mixin class that provides the image parsing functionality but doesn't store information. The original version of _parse_image in #144 does assume that the object has an image attribute that is returned if no image is given

if image is None:
    # useful for Background's instance methods
    return self.image 

but I think this is quite dangerous since the code assumes that the class inheriting from _ImageParser sets the image attribute by default and that it does this before _ImageParser._parse_image(...) is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has become kind of a mess and i'm trying to figure out how to reorganize. A while back I had to move _get_data_from_image to a static method because some of the 'Background' methods that create Background objects call it before the object is instantiated. I am trying to work off the existing code and avoid refactoring in this PR, but I may have to. This option I'm exploring right now is changing _ImageParser from a mixin class to either just a regular class or set of functions that is called within each step, and the arguments are passed in each time.

Copy link
Contributor

@hpparvi hpparvi Oct 30, 2024

Choose a reason for hiding this comment

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

The only way to avoid refactoring _ImageParser that I can see would be to turn _mask_and_nonfinite_data_handling into a static method as well and to provide mask_treatment as a passed argument (and to handle checking whether the mask treatment method is valid in the calling code.) This way, the _get_data_from_image class method could be used the way it is now.

However, there wouldn't be much advantage to having the image parsing functionality as a class instead of a function, and I think refactoring _ImageParser into a function might make the most sense. Turning it into a regular class would also work, but I'm not sure what would be again the advantage of this over having the image parsing as a function if we want to be able to parse an image inside a class method (as with the Background methods).

Then again, we don't necessarily need to do the image parsing in the Background.two_sided and Background.one_sided class methods since it is done in Background.__post_init__ by default (unless I'm missing something). So, another option would be to leave the image parsing inside Background.__post_init__ and remove it from the two class methods, in which case the Background object would always be instantiated before parsing the image.

If you want to avoid major refactors in this PR, I could open a separate PR where I could refactor the _ImageParser into a function, and we can see how much sense this approach would make. What do you think?

return img

@staticmethod
def _get_data_from_image(image):
Copy link
Contributor

Choose a reason for hiding this comment

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

This method definition overrides the previous _get_data_from_image definition that handles masking.

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.

4 participants