spacetelescope / jdaviz

JWST astronomical data analysis tools in the Jupyter platform
https://jdaviz.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
142 stars 74 forks source link

BUG: Mask cube is ignored in Cubeviz spectral extraction #2714

Open pllim opened 9 months ago

pllim commented 9 months ago

The current documentation (at the time of original posting this issue) at https://jdaviz.readthedocs.io/en/latest/cubeviz/plugins.html#spectral-extraction does not mention at all how uncertainty and mask arrays are used in the extraction process. The uncertainty is yet another issue (#2713); here I am only focusing on mask:

https://github.com/spacetelescope/jdaviz/blob/b563ed3e4090d7f8d752c54a01b8fcb222811ef2/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py#L214-L216

https://github.com/spacetelescope/jdaviz/blob/b563ed3e4090d7f8d752c54a01b8fcb222811ef2/jdaviz/configs/cubeviz/plugins/spectral_extraction/spectral_extraction.py#L231

This was originally implemented by @bmorris3 via https://github.com/spacetelescope/jdaviz/pull/2039 . In the code above, mask only takes account of the selected aperture (if any). However, our parser reads in a whole cube array that has the bitmask plane:

https://github.com/spacetelescope/jdaviz/blob/b563ed3e4090d7f8d752c54a01b8fcb222811ef2/jdaviz/configs/cubeviz/plugins/parsers.py#L21

While there is code to stuff the mask into Spectrum1D object, not all parser logic routes seem to trigger it (how Spectrum1D handle a bitplane is another story):

https://github.com/spacetelescope/jdaviz/blob/b563ed3e4090d7f8d752c54a01b8fcb222811ef2/jdaviz/configs/cubeviz/plugins/parsers.py#L184

As a result, aperture seems to solely define the mask, while the actual mask cube is ignored. How is a user supposed to mask out certain bad pixels from extraction (in addition to the aperture)?

ADDITIONAL REQUIREMENT: When MASK cube does not exist, the extraction should not crash and treat all pixels as "good".

🐱

bmorris3 commented 9 months ago

The subset choice of the selected aperture was implemented in https://github.com/spacetelescope/jdaviz/pull/2664. I think the simplest solution for now is to translate to NDDataArray with

nddata = spectral_cube.get_object(cls=NDDataArray)

without specifying the subset, to get the original mask cube for the full dataset. Then we can call to_mask on the aperture's glue subset, and take the logical-and with the full mask, something like:

nddata.mask &= ~aperture_subset.to_mask()  # the ~ may be needed b/c glue subset masks are "backwards"

How does that sound?

pllim commented 9 months ago

Maybe related?

https://github.com/spacetelescope/jdaviz/pull/2679#discussion_r1494876150