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

Allow users to provide custom pixel grid for BaseTableCoordinate #740

Open DanRyanIrish opened 3 months ago

DanRyanIrish commented 3 months ago

Describe the feature

Background

TableCoordinate is used to build tabular extra coordinates, and can be used as a helper for generating tabular gWCS objects. Currently, it takes a 1-D table of coordinates (or several tables of the same length) and assumes that they represent the world coordinates at the centre of the pixels along the associate axis.

Motivation

However, there are many cases, e.g. solar X-ray spectroscopy, where pixels represent irregularly sized intervals along a specific axis (e.g. bins along a spectral axis). In this case, the only unambiguous way to capture the coordinate information is to provide the world coordinates at the bin/pixel edges.

Proposed solution

To address the above use case, and to enhance overall flexibility, BaseTableCoordinate should require that the user provides the pixel coordinates to which the world table values corresponds, and then store that grid natively. This will enable users to sample the coordinate however they wish.

The proposed new __init__ signature for BaseTableCoordinate is therefore:

class BaseTableCoordinate(abc.ABC):
    def __init__(self, *tables, mesh=False, names=None, physical_types=None, pixel_table="centers"):

where pixel_table is the new addition. pixel_table must be a Quantity with pixel units of the same shape as the table/tables provided. To make things simple for most users, two convenience values are allowed: "centers" and "corners", with the default being "centers" for backwards compatibility. If either of these strings are provided, a pixel Quantity is generated, (np.arange(len(tables[0])) * u.pix for "centers", and np.arange(-0.5, len(tables[0])) * u.pix for "corners").

In places throughout the table_coord.py module where the pixel grid is required, it will then be drawn from the values stored in BaseTableCoordinate, rather than assumed to be the pixel centers, as is currently done. This will likely require changes to subclasses of BaseTableCoordinate, QuantityTableCoordinate, etc., as well as other relevant functions including _generate_tabular, _generate_compound_model, _model_from_quantity, etc.