sunpy / ndcube

A base package for multi-dimensional contiguous and non-contiguous coordinate-aware arrays. "Maintainers": @danryanirish & @Cadair
http://docs.sunpy.org/projects/ndcube/
BSD 2-Clause "Simplified" License
44 stars 47 forks source link

Construct FITS-WCS from WCS Wrappers #648

Open DanRyanIrish opened 10 months ago

DanRyanIrish commented 10 months ago

Describe the feature

ndcube only requires that its WCS is APE-14 compliant and is agnostic to the underlying WCS implementation. However, many users want to write their NDCube out to FITS. However, even if an NDCube starts with a FITS-WCS, certain operations will cause the WCS to be wrapped in an APE-14-compliant wrapper that cannot itself be read back to FITS. However, for many of these wrappers, it should be possible to reconstruct a FITS-WCS by combining the wrapper information with the original underlying FITS-WCS. This will enable users to write their modified NDCube out to FITS.

Currently, there are only two NDCube operations that will produce a WCS wrapper:

Aside

NDCube.reproject_to will also replace the WCS. However, the WCS is provided by the user and so the user can ensure that the new WCS is FITS-WCS.

Proposed solution

This issue proposes a set of functions to live in a new module in the ndcube.wcs sunpackage. These can be applied to the NDCube.wcs by the user to produce a new FITS-WCS. The user can then use this new FITS WCS to write their NDCube out to a FITS file.

The functions should be:

DanRyanIrish commented 10 months ago

ping @jmason86 @Cadair

I think these 3 functions would solve your problem @jmason86 and should not be an unreasonable amount of work. Your SunCET pipeline could then use NDCube natively and be significantly simplified. And you could write the end product our to FITS in only a couple of lines of code.

Cadair commented 10 months ago

While I think writing the convert-back-to-fits functionality is good and should be done, I think there's a better way of doing this holistically.

Ideally, when constructing a low level wrapper, the wrapper class should see if it can modify the input WCS rather than return an instance of itself. Ideally (I think), this would be dispatched out to the input WCS (i.e WCS._resample_wcs) which could return NotImplemented if the operation can not be done on that particular WCS.

I think this would be a good addition to the APE 14 API to extend it into analysis operations.