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

Have cubeviz auto-recognize and load into viewers interpretable cube datasets #86

Closed eteq closed 2 years ago

eteq commented 4 years ago

Right now when one either via click or by command line loads data into cubeviz, the user has to manually assign the particular data cubes to the various windows in cubeviz. That's not good because when a user loads "a data cube" they expect the cube viewers in the layout to be a particular set of cube planes - flux, uncertainty, and mask.

So this issue is about working out a way to have this happen automatically (or semi-automatically) when a cube is loaded. I can think of several cases to consider here:

  1. A cube that can be laoded by spectral-cube, vector/cubespecutils.Spectrum1D or specutils.SpectralCollection using their built-in readers, which then correctly populates the various attributes like uncertainty or mask. JWST cubes should end up in this category.
  2. A fits file where the cube planes are in separate HDUs which follows some naming convention we can guess things based on (e.g. the SDSS MANGA cubes) but does not have a native reader.
  3. Some home-grown cube format that comes out of a specific instrument's pipeline or unique capabilities (e.g. the outputs of CWI data reduction pipeline, MUSE, etc.)

This issue is meant to only address 1 and 2. 3 We might consider in the future, but for now would just need to be dealt with manually by the user (and that's OK).

Case 1: in this case when the data is loaded, things should just happen automatically. .flux of a spectrum should be recognized as belonging in the first window, .uncertainty in the second, .mask in the third. This should happen whether the file is loaded as a file or as a live object in the notebook interface via app.load_data (it should all be the same machinery, which I think it is already).

Case 2: This could be "turned into" case 1 by having a function that generates the relevant case 1 data object using naming heuristics. E.g., if "flux" is in the name of the HDU, call that the flux, "unc" or "err" the uncertainty, "mask" the mask, etc. Then the user can try out the heuristic by calling the function if they want to, but in the app they can just load the file and have it transparently work if they don't care about the details. The one catch I see in this case is that it's not clear what to do about "extra" HDUs that the user might want to have an option to look at. Maybe they end up in .meta from the heuristic function? (and then still appear in glue as currently).

cc @nmearl @astrofrog

eteq commented 4 years ago

Added consideration which could be discussed in a separate issue of that's better: it might also be desirable to treat the loaded data set as "the data", which is then used for other things like the default dataset for plugins or the like.

eteq commented 4 years ago

Fleshing the expectation for a few "known-good" cases:

MANGA cubes

for example: manga-7495-12704-LOGCUBE.fits (from https://data.sdss.org/sas/dr14/manga/spectro/redux/v2_1_2/7495/stack/manga-7495-12704-LOGCUBE.fits.gz)

Note: the above is not really special to MANGA, because anyone could create a cube with the three keywords as primary and point them to the right extensions. This is good, as we can use that as a template for a "generic" cube format!

Caveat: the MANGA cubes as-delivered have the wrong BUNIT in 'WAVE'. I would suggest we have a check that parses the BUNIT and if it turns out not to be a spectral-compatible unit, look for evidence that it's a MANGA cube (easiest way would appear to be if the primary HDU has a keyword INSTRUME= 'MaNGA '), and if that's true, just fix the cube to have the correct units.

JWST cubes

JWST level-3 data cubes should load via the jwst.datamodel mechanism, such that data (which is the 'SCI' extension) is treated as the "flux" cube (i.e., goes in the upper-left and profile viewer), err (same as the 'ERR'extension) is treated as aStdDevUncertainty(upper-middle),dq('DQ') is themask(upper-right), and the units are taken frombunit_dataandbunit_err. Thewcsshould come straight fromwcs(and thespectral_axis/coordinates should then be generated from thewcs` instead of the other way around).

Anything that can be loaded into/viewed as a Spectrum1D or SpectrumCollection

Simply assign flux, err, mask, and wcs/spectral_axis exactly as I said above for JWST cubes. In fact, the most natural way to load the JWST cubes might be to first map them onto a Spectrum1D and then use "generic" loading in that form!

eteq commented 4 years ago

Some out-of-band conversation with @nmearl revealed a concern here: 1) currently the specutils loaders for JWST data may not pull in the full WCS. 2) The Spectrum1D translators in glue-astronomy currently do not carry over the full WCS, only the spectral part.

1 should just be fixed in specutils, but we can do a temporary custom loader here until that happens. 2 should also be fixed, but as a temporary work-around we can translate the specutils objects into spectral-cube objects which glue-astronomy does understand. But we should make an issue to be sure we undo that as soon as the upstream changes are working.

pllim commented 2 years ago

I think this is possible already (more or less). If there is a specific use case not possible still, please open one issue per unique use case. Thanks!