Skip to content

Commit 506fc64

Browse files
authored
Merge pull request #210 from Jammy2211/feature/wcs_coordinates
Feature/wcs coordinates
2 parents 2788bcb + 822ebec commit 506fc64

File tree

4 files changed

+365
-4
lines changed

4 files changed

+365
-4
lines changed

autoarray/config/visualize/plots.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fit: # Settings for plots of all fits (e.g
2121
fit_imaging: {} # Settings for plots of fits to imaging datasets (e.g. FitImagingPlotter).
2222
inversion: # Settings for plots of inversions (e.g. InversionPlotter).
2323
subplot_inversion: true # Plot subplot of all quantities in each inversion (e.g. reconstrucuted image, reconstruction)?
24-
subplot_mappings: true # Plot subplot of the image-to-source pixels mappings of each pixelization?
24+
subplot_mappings: false # Plot subplot of the image-to-source pixels mappings of each pixelization?
2525
data_subtracted: false # Plot individual plots of the data with the other inversion linear objects subtracted?
2626
reconstruction_noise_map: false # Plot image of the noise of every mesh-pixel reconstructed value?
2727
sub_pixels_per_image_pixels: false # Plot the number of sub pixels per masked data pixels?

autoarray/geometry/geometry_2d.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ def central_scaled_coordinates(self) -> Tuple[float, float]:
132132

133133
def pixel_coordinates_2d_from(
134134
self, scaled_coordinates_2d: Tuple[float, float]
135-
) -> Tuple[float, float]:
135+
) -> Tuple[int, int]:
136136
"""
137-
Convert a 2D (y,x) scaled coordinate to a 2D (y,x) pixel coordinate, which are returned as floats such that they
138-
include the decimal offset from each pixel's top-left corner relative to the input scaled coordinate.
137+
Convert a 2D (y,x) scaled coordinate to a 2D (y,x) pixel coordinate, which are returned as integers such that
138+
they do not include the decimal offset from each pixel's top-left corner relative to the input scaled coordinate.
139139
140140
The conversion is performed according to the 2D geometry on a uniform grid, where the pixel coordinate origin
141141
is at the top left corner, such that the pixel [0,0] corresponds to the highest (most positive) y scaled
@@ -190,6 +190,41 @@ def scaled_coordinates_2d_from(
190190
origins=self.origin,
191191
)
192192

193+
def pixel_coordinates_wcs_2d_from(
194+
self, scaled_coordinates_2d: Tuple[float, float]
195+
) -> Tuple[float, float]:
196+
"""
197+
Convert a 2D (y,x) scaled coordinate to a 2D (y,x) WCS/FITS-style pixel coordinate.
198+
199+
The returned pixel coordinates follow the standard WCS convention:
200+
201+
- Coordinates are 1-based rather than 0-based, so that the centre of the top-left pixel is at (y, x) = (1.0, 1.0).
202+
- Coordinates refer to pixel centres, not pixel corners.
203+
- Values are continuous floats, so the fractional part encodes the sub-pixel offset from the pixel centre.
204+
205+
This differs from integer pixel-index conversions (e.g. ``pixel_coordinates_2d_from``), which return 0-based
206+
indices associated with pixel corners/top-left positions.
207+
208+
The mapping from scaled coordinates to WCS pixel coordinates is defined by this geometry's ``origin``: scaled
209+
coordinates are first shifted by the specified origin(s) before being converted using the pixel scale and
210+
array shape. Changing ``origin`` therefore translates the returned WCS pixel coordinates by a constant offset.
211+
212+
Parameters
213+
----------
214+
scaled_coordinates_2d
215+
The 2D (y,x) coordinates in scaled units to be converted to WCS-style pixel coordinates.
216+
217+
Returns
218+
-------
219+
A 2D (y,x) WCS pixel coordinate, expressed as 1-based, pixel-centre, floating-point values.
220+
"""
221+
return geometry_util.pixel_coordinates_wcs_2d_from(
222+
scaled_coordinates_2d=scaled_coordinates_2d,
223+
shape_native=self.shape_native,
224+
pixel_scales=self.pixel_scales,
225+
origins=self.origin,
226+
)
227+
193228
def scaled_coordinate_2d_to_scaled_at_pixel_centre_from(
194229
self, scaled_coordinate_2d: Tuple[float, float]
195230
) -> Tuple[float, float]:

autoarray/geometry/geometry_util.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,57 @@ def scaled_coordinates_2d_from(
357357
return (y_pixel, x_pixel)
358358

359359

360+
def pixel_coordinates_wcs_2d_from(
361+
scaled_coordinates_2d: Tuple[float, float],
362+
shape_native: Tuple[int, int],
363+
pixel_scales: ty.PixelScales,
364+
origins: Tuple[float, float] = (0.0, 0.0),
365+
) -> Tuple[float, float]:
366+
"""
367+
Return FITS / WCS pixel coordinates (1-based, pixel-centre convention) as floats.
368+
369+
This function returns continuous pixel coordinates suitable for Astropy WCS
370+
transforms (e.g. ``wcs_pix2world`` with ``origin=1``). Pixel centres lie at
371+
integer values; for an image of shape ``(ny, nx)`` the geometric centre is::
372+
373+
((ny + 1) / 2, (nx + 1) / 2)
374+
375+
e.g. ``(100, 100) -> (50.5, 50.5)``.
376+
377+
Parameters
378+
----------
379+
scaled_coordinates_2d
380+
The 2D (y, x) coordinates in scaled units which are converted to WCS
381+
pixel coordinates.
382+
shape_native
383+
The (y, x) shape of the 2D array on which the scaled coordinates are
384+
defined, used to determine the geometric centre in WCS pixel units.
385+
pixel_scales
386+
The (y, x) conversion factors from scaled units to pixel units.
387+
origins
388+
The (y, x) origin in scaled units about which the coordinates are
389+
defined. The scaled coordinates are shifted by this origin before being
390+
converted to WCS pixel coordinates.
391+
392+
Returns
393+
-------
394+
pixel_coordinates_wcs_2d
395+
A 2D (y, x) WCS pixel coordinate in the 1-based, pixel-centre
396+
convention, returned as floats.
397+
"""
398+
ny, nx = shape_native
399+
400+
# Geometric centre in WCS pixel coordinates (1-based, pixel centres at integers)
401+
ycen_wcs = (ny + 1) / 2.0
402+
xcen_wcs = (nx + 1) / 2.0
403+
404+
# Continuous WCS pixel coordinates (NO int-cast, NO +0.5 binning)
405+
y_wcs = (-scaled_coordinates_2d[0] + origins[0]) / pixel_scales[0] + ycen_wcs
406+
x_wcs = (scaled_coordinates_2d[1] - origins[1]) / pixel_scales[1] + xcen_wcs
407+
408+
return (y_wcs, x_wcs)
409+
410+
360411
def transform_grid_2d_to_reference_frame(
361412
grid_2d: np.ndarray, centre: Tuple[float, float], angle: float, xp=np
362413
) -> np.ndarray:

0 commit comments

Comments
 (0)