Make it so we can use broadcasting even if input WCS is same dimension as data
This is very much a WIP and not ready for usage but just opening this to not lose my progress.
I think we need to write down the rules for block sizes, and broadcasted reprojection, and I think it's ok to not cover all arbitrary cases. I'm now using the terminology 'reprojected dimensions' and 'non-reprojected dimensions', where the latter are essentially dimensions where we assume the mapping is 1-to-1 between input and output.
Proposed rules:
- The dimensionality of the overall reprojection is determined by the shape of the input data (the array itself, not the input data). Call this
ndim. - If
wcs_inhas fewer pixel dimensions thanndim, then we assume that the input WCS applies to the lastwcs_in.pixel_n_dimdimensions of the input data, and that leading dimensions are the non-reprojected ones. The same applies towcs_out. -
shape_outshould either havendimelements, or match the number of reprojected dimensions. If the latter, then any missing elements for non-reprojected dimensions should be set to be the same as the input. -
block_size, if specified, should also either havendimelements, or match the number of reprojected dimensions. If the latter, then any missing elements for non-reprojected dimensions should be either set to1ifblock_sizeequalsshape_outfor reprojected dimensions, or-1otherwise -
block_sizeshould either matchshape_outfor reprojected or for non-reprojected dimensions (that is, we either chunk over non-reprojected dimensions only, or over reprojected dimensions only). If it matchesshape_outfor reprojected dimensions, then the remaining block_size should be 1 so that only a single slice is reprojected at a time (yes there may be cases where someone wants to process slices in e.g. time or spectral slices, but this is going to introduce more complexity when the input WCS has dimensionndimso we punt on this for now). - If specified,
non_reprojected_dimsshould for now be only leading dimensions starting from0, so e.g.(0,),(0, 1)and so on.(1,2)is not allowed for now. This could be relaxed in future potentially at the cost of more complexity. - In principle one could imagine examples where different dimensions need to be ignored in the input and output, for example if the WCS order is different. I don't really want to cross that bridge, but if we ever do want to do this, the
non_reprojected_dimsoption could take a list of tuples where each tuple gives the(input_dim, output_dim)correspondence. - If
non_reprojected_dimsis specified, then ifwcs_inorwcs_outhave fewer dimensions thanndim, the difference in the number of dimensions should match the length ofnon_reprojected_dims.
For cases where the third axis is completely decoupled from the spatial axes in cubes, non_reprojected_dims isn't strictly needed because the WCSes could be easily sliced down to 2D. However, we do need that option for cases where the input WCS is 3D in the sense that each spatial slice might be different (for example due to drift at different times) but where each time still corresponds cleanly to one 2D slice and there is no dependence of e.g. time position on spatial position.
Complex examples that should work:
- If a 3D dataset is reprojected from a 3D spectral WCS to a 3D time WCS, if the spectral and time axes are the third WCS axis (first numpy axis) then if
non_reprojected_dims=(0,), it should work and basically only care about the spatial to spatial conversion. This example doesn't make a huge amount of sense, but another more realistic example is that if one wants to align two spectral cubes spatially without touching the spectral axis,non_reprojected_dims=(0,)could do this.
Codecov Report
:x: Patch coverage is 80.35714% with 11 lines in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 87.57%. Comparing base (dc4b0e2) to head (0c503ea).
:warning: Report is 75 commits behind head on main.
| Files with missing lines | Patch % | Lines |
|---|---|---|
| reproject/common.py | 81.63% | 9 Missing :warning: |
| reproject/mosaicking/coadd.py | 66.66% | 2 Missing :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## main #539 +/- ##
==========================================
- Coverage 88.30% 87.57% -0.73%
==========================================
Files 28 28
Lines 1411 1441 +30
==========================================
+ Hits 1246 1262 +16
- Misses 165 179 +14
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
Ok so we need to add proper support for non_reprojected_dims to reproject_and_coadd rather than the current hack. And then of course a lot of documentation and tests!