Skip to content

Commit 122e26a

Browse files
authored
Fix bugs in ASDF cutouts (#154)
* Fix bugs in ASDF cutouts * update package versions * Rollback gwcs package version * rdm version
1 parent 8894b35 commit 122e26a

File tree

3 files changed

+40
-60
lines changed

3 files changed

+40
-60
lines changed

astrocut/asdf_cutout.py

Lines changed: 28 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import copy
1+
import warnings
2+
from copy import deepcopy
23
from pathlib import Path
34
from time import monotonic
45
from typing import List, Tuple, Union, Optional
5-
import warnings
66

77
import asdf
88
import gwcs
@@ -67,8 +67,6 @@ class ASDFCutout(ImageCutout):
6767
Write the cutouts to disk or memory in FITS format.
6868
write_as_asdf(output_dir)
6969
Write the cutouts to disk or memory in ASDF format.
70-
get_center_pixel(gwcsobj, ra, dec)
71-
Get the closest pixel location on an input image for a given set of coordinates.
7270
"""
7371

7472
def __init__(self, input_files: List[Union[str, Path, S3Path]], coordinates: Union[SkyCoord, str],
@@ -175,8 +173,8 @@ def _load_file_data(self, input_file: Union[str, Path, S3Path]) -> Tuple[np.ndar
175173

176174
# Get data and GWCS object from ASDF input file
177175
with asdf.open(input_file) as af:
178-
data = af[self._mission_kwd]['data']
179-
gwcs = af[self._mission_kwd]['meta'].get('wcs', None)
176+
data = deepcopy(af[self._mission_kwd]['data'])
177+
gwcs = deepcopy(af[self._mission_kwd]['meta'].get('wcs', None))
180178

181179
return (data, gwcs)
182180

@@ -244,7 +242,7 @@ def _slice_gwcs(self, cutout: Cutout2D, gwcs: gwcs.wcs.WCS) -> gwcs.wcs.WCS:
244242
The sliced GWCS object.
245243
"""
246244
# Create copy of original gwcs object
247-
tmp = copy.deepcopy(gwcs)
245+
tmp = deepcopy(gwcs)
248246

249247
# Get the cutout array bounds and create a new shift transform to the cutout
250248
# Add the new transform to the gwcs
@@ -280,7 +278,7 @@ def _cutout_file(self, file: Union[str, Path, S3Path]):
280278
return
281279

282280
# Get closest pixel coordinates and approximated WCS
283-
pixel_coords, wcs = self.get_center_pixel(gwcs, self._coordinates.ra.value, self._coordinates.dec.value)
281+
pixel_coords, wcs = get_center_pixel(gwcs, self._coordinates.ra.value, self._coordinates.dec.value)
284282

285283
# Create the cutout
286284
try:
@@ -415,53 +413,8 @@ def write_as_asdf(self, output_dir: Union[str, Path] = '.') -> List[str]:
415413
"""
416414
return self._write_as_format(output_format='.asdf', output_dir=output_dir)
417415

418-
@staticmethod
419-
def get_center_pixel(gwcsobj: gwcs.wcs.WCS, ra: float, dec: float) -> Tuple[Tuple[int, int], WCS]:
420-
"""
421-
Get the closest pixel location on an input image for a given set of coordinates.
422-
423-
Parameters
424-
----------
425-
gwcsobj : gwcs.wcs.WCS
426-
The GWCS object.
427-
ra : float
428-
The right ascension of the input coordinates.
429-
dec : float
430-
The declination of the input coordinates.
431-
432-
Returns
433-
-------
434-
pixel_position
435-
The pixel position of the input coordinates.
436-
wcs_updated : `~astropy.wcs.WCS`
437-
The approximated FITS WCS object.
438-
"""
439-
440-
# Convert the gwcs object to an astropy FITS WCS header
441-
header = gwcsobj.to_fits_sip()
442-
443-
# Update WCS header with some keywords that it's missing.
444-
# Otherwise, it won't work with astropy.wcs tools (TODO: Figure out why. What are these keywords for?)
445-
for k in ['cpdis1', 'cpdis2', 'det2im1', 'det2im2', 'sip']:
446-
if k not in header:
447-
header[k] = 'na'
448-
449-
# New WCS object with updated header
450-
with warnings.catch_warnings():
451-
warnings.simplefilter('ignore')
452-
wcs_updated = WCS(header)
453-
454-
# Turn input RA, Dec into a SkyCoord object
455-
coordinates = SkyCoord(ra, dec, unit='deg')
456-
457-
# Map the coordinates to a pixel's location on the Roman 2d array (row, col)
458-
gwcsobj.bounding_box = None
459-
row, col = gwcsobj.invert(coordinates)
460-
461-
return (row, col), wcs_updated
462-
463416

464-
def get_center_pixel(gwcsobj: gwcs.wcs.WCS, ra: float, dec: float) -> tuple:
417+
def get_center_pixel(gwcsobj: gwcs.wcs.WCS, ra: float, dec: float) -> Tuple[Tuple[int, int], WCS]:
465418
"""
466419
Get the closest pixel location on an input image for a given set of coordinates.
467420
@@ -481,7 +434,27 @@ def get_center_pixel(gwcsobj: gwcs.wcs.WCS, ra: float, dec: float) -> tuple:
481434
wcs_updated : `~astropy.wcs.WCS`
482435
The approximated FITS WCS object.
483436
"""
484-
return ASDFCutout.get_center_pixel(gwcsobj, ra, dec)
437+
# Convert the gwcs object to an astropy FITS WCS header
438+
header = gwcsobj.to_fits_sip()
439+
440+
# Update WCS header with some keywords that it's missing.
441+
# Otherwise, it won't work with astropy.wcs tools (TODO: Figure out why. What are these keywords for?)
442+
for k in ['cpdis1', 'cpdis2', 'det2im1', 'det2im2', 'sip']:
443+
if k not in header:
444+
header[k] = 'na'
445+
446+
# New WCS object with updated header
447+
with warnings.catch_warnings():
448+
warnings.simplefilter('ignore')
449+
wcs_updated = WCS(header)
450+
451+
# Turn input RA, Dec into a SkyCoord object
452+
coordinates = SkyCoord(ra, dec, unit='deg')
453+
454+
# Map the coordinates to a pixel's location on the Roman 2d array (row, col)
455+
row, col = gwcsobj.invert(coordinates, with_bounding_box=False)
456+
457+
return (row, col), wcs_updated
485458

486459

487460
@deprecated_renamed_argument('output_file', None, '1.0.0', warning_type=DeprecationWarning,

astrocut/tests/test_asdf_cutout.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from gwcs import wcs, coordinate_frames
1313
from PIL import Image
1414

15-
from astrocut.asdf_cutout import ASDFCutout, asdf_cut
15+
from astrocut.asdf_cutout import ASDFCutout, asdf_cut, get_center_pixel
1616
from astrocut.exceptions import DataWarning, InvalidInputError, InvalidQueryError
1717

1818

@@ -296,13 +296,20 @@ def test_asdf_cutout_img_output(test_images, center_coord, cutout_size, tmpdir):
296296

297297
def test_get_center_pixel(fakedata):
298298
""" Test get_center_pixel function """
299-
# get the fake data
299+
# Get the fake data
300300
__, gwcs = fakedata
301301

302-
pixel_coordinates, wcs = ASDFCutout.get_center_pixel(gwcs, 30, 45)
302+
# Using center coordinates
303+
pixel_coordinates, wcs = get_center_pixel(gwcs, 30, 45)
303304
assert np.allclose(pixel_coordinates, (np.array(500), np.array(500)))
304305
assert np.allclose(wcs.celestial.wcs.crval, np.array([30, 45]))
305306

307+
# Using upper left corner
308+
# Running this without parametrization to make sure that gwcs is not corrupted
309+
ra, dec = wcs.all_pix2world(0, 0, 0)
310+
pixel_coordinates, wcs = get_center_pixel(gwcs, ra, dec)
311+
assert np.allclose(pixel_coordinates, (np.array(0), np.array(0)))
312+
306313

307314
def test_asdf_cut(test_images, center_coord, cutout_size, tmpdir):
308315
""" Test convenience function to create ASDF cutouts """

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ packages = find:
1616
python_requires = >=3.9
1717
setup_requires = setuptools_scm
1818
install_requires =
19-
asdf>=2.15.0 # for ASDF file format
19+
asdf>=4.1.0 # for ASDF file format
2020
astropy>=5.2 # astropy with s3fs support
2121
cachetools>=5.3.2 # for caching data
2222
fsspec[http]>=2022.8.2 # for remote cutouts
2323
s3fs>=2022.8.2 # for remote cutouts
2424
s3path>=0.5.7 # for remote file paths
25-
roman_datamodels>=0.17.0 # for roman file support
25+
roman_datamodels>=0.19.0 # for roman file support
2626
requests>=2.32.3 # for making HTTP requests
2727
spherical_geometry>=1.3.0
2828
gwcs>=0.21.0

0 commit comments

Comments
 (0)