Skip to content

Commit 29ee109

Browse files
authored
Update docs 0.11 (#118)
* Documentation for asdf_cut * Remove anon from s3fs
1 parent 8ba4902 commit 29ee109

File tree

5 files changed

+128
-49
lines changed

5 files changed

+128
-49
lines changed

astrocut/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ class UnsupportedPythonError(Exception):
2727
from .cutouts import fits_cut, img_cut, normalize_img # noqa
2828
from .cutout_processing import (path_to_footprints, center_on_path, # noqa
2929
CutoutsCombiner, build_default_combine_function) # noqa
30+
from .asdf_cutouts import asdf_cut, get_center_pixel # noqa

astrocut/asdf_cutouts.py

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,42 @@
1616

1717

1818
def _get_cloud_http(s3_uri: str) -> str:
19-
""" Get the HTTP URI of a cloud resource from an S3 URI
19+
"""
20+
Get the HTTP URI of a cloud resource from an S3 URI.
2021
2122
Parameters
2223
----------
2324
s3_uri : string
2425
the S3 URI of the cloud resource
2526
"""
2627
# create file system
27-
fs = s3fs.S3FileSystem(anon=True)
28+
fs = s3fs.S3FileSystem()
2829

2930
# open resource and get URL
3031
with fs.open(s3_uri, 'rb') as f:
3132
return f.url()
3233

3334

3435
def get_center_pixel(gwcsobj: gwcs.wcs.WCS, ra: float, dec: float) -> tuple:
35-
""" Get the center pixel from a roman 2d science image
36+
"""
37+
Get the center pixel from a Roman 2D science image.
3638
3739
For an input RA, Dec sky coordinate, get the closest pixel location
3840
on the input Roman image.
3941
4042
Parameters
4143
----------
4244
gwcsobj : gwcs.wcs.WCS
43-
the Roman GWCS object
45+
The Roman GWCS object.
4446
ra : float
45-
the input Right Ascension
47+
The input right ascension.
4648
dec : float
47-
the input Declination
49+
The input declination.
4850
4951
Returns
5052
-------
5153
tuple
52-
the pixel position, FITS wcs object
54+
The pixel position, FITS wcs object
5355
"""
5456

5557
# Convert the gwcs object to an astropy FITS WCS header
@@ -73,11 +75,12 @@ def get_center_pixel(gwcsobj: gwcs.wcs.WCS, ra: float, dec: float) -> tuple:
7375
return (row, col), wcs_updated
7476

7577

76-
def get_cutout(data: asdf.tags.core.ndarray.NDArrayType, coords: Union[tuple, SkyCoord],
77-
wcs: astropy.wcs.wcs.WCS = None, size: int = 20, outfile: str = "example_roman_cutout.fits",
78-
write_file: bool = True, fill_value: Union[int, float] = np.nan,
79-
gwcsobj: gwcs.wcs.WCS = None) -> astropy.nddata.Cutout2D:
80-
""" Get a Roman image cutout
78+
def _get_cutout(data: asdf.tags.core.ndarray.NDArrayType, coords: Union[tuple, SkyCoord],
79+
wcs: astropy.wcs.wcs.WCS = None, size: int = 20, outfile: str = "example_roman_cutout.fits",
80+
write_file: bool = True, fill_value: Union[int, float] = np.nan,
81+
gwcsobj: gwcs.wcs.WCS = None) -> astropy.nddata.Cutout2D:
82+
"""
83+
Get a Roman image cutout.
8184
8285
Cut out a square section from the input image data array. The ``coords`` can either be a tuple of x, y
8386
pixel coordinates or an astropy SkyCoord object, in which case, a wcs is required. Writes out a
@@ -154,7 +157,8 @@ def get_cutout(data: asdf.tags.core.ndarray.NDArrayType, coords: Union[tuple, Sk
154157

155158

156159
def _write_fits(cutout: astropy.nddata.Cutout2D, outfile: str = "example_roman_cutout.fits"):
157-
""" Write cutout as FITS file
160+
"""
161+
Write cutout as FITS file.
158162
159163
Parameters
160164
----------
@@ -173,7 +177,8 @@ def _write_fits(cutout: astropy.nddata.Cutout2D, outfile: str = "example_roman_c
173177

174178

175179
def _slice_gwcs(gwcsobj: gwcs.wcs.WCS, slices: Tuple[slice, slice]) -> gwcs.wcs.WCS:
176-
""" Slice the original gwcs object
180+
"""
181+
Slice the original gwcs object.
177182
178183
"Slices" the original gwcs object down to the cutout shape. This is a hack
179184
until proper gwcs slicing is in place a la fits WCS slicing. The ``slices``
@@ -211,7 +216,8 @@ def _slice_gwcs(gwcsobj: gwcs.wcs.WCS, slices: Tuple[slice, slice]) -> gwcs.wcs.
211216

212217

213218
def _write_asdf(cutout: astropy.nddata.Cutout2D, gwcsobj: gwcs.wcs.WCS, outfile: str = "example_roman_cutout.asdf"):
214-
""" Write cutout as ASDF file
219+
"""
220+
Write cutout as ASDF file.
215221
216222
Parameters
217223
----------
@@ -236,32 +242,33 @@ def _write_asdf(cutout: astropy.nddata.Cutout2D, gwcsobj: gwcs.wcs.WCS, outfile:
236242
def asdf_cut(input_file: str, ra: float, dec: float, cutout_size: int = 20,
237243
output_file: str = "example_roman_cutout.fits",
238244
write_file: bool = True, fill_value: Union[int, float] = np.nan) -> astropy.nddata.Cutout2D:
239-
""" Preliminary proof-of-concept functionality.
245+
"""
246+
Takes a single ASDF input file (`input_file`) and generates a cutout of designated size `cutout_size`
247+
around the given coordinates (`coordinates`).
240248
241-
Takes a single ASDF input file (``input_file``) and generates a cutout of designated size ``cutout_size``
242-
around the given coordinates (``coordinates``).
249+
Preliminary proof-of-concept functionality.
243250
244251
Parameters
245252
----------
246253
input_file : str
247-
the input ASDF file
254+
The input ASDF file.
248255
ra : float
249-
the Right Ascension of the central cutout
256+
The right ascension of the central cutout.
250257
dec : float
251-
the Declination of the central cutout
252-
cutout_size : int, optional
253-
the image cutout pixel size, by default 20
254-
output_file : str, optional
255-
the name of the output cutout file, by default "example_roman_cutout.fits"
256-
write_file : bool, by default True
257-
Flag to write the cutout to a file or not
258-
fill_value: int | float, by default np.nan
259-
The fill value for pixels outside the original image.
258+
The declination of the central cutout.
259+
cutout_size : int
260+
Optional, default 20. The image cutout pixel size.
261+
output_file : str
262+
Optional, default "example_roman_cutout.fits". The name of the output cutout file.
263+
write_file : bool
264+
Optional, default True. Flag to write the cutout to a file or not.
265+
fill_value: int | float
266+
Optional, default `np.nan`. The fill value for pixels outside the original image.
260267
261268
Returns
262269
-------
263270
astropy.nddata.Cutout2D:
264-
an image cutout object
271+
An image cutout object.
265272
"""
266273

267274
# if file comes from AWS cloud bucket, get HTTP URL to open with asdf
@@ -278,5 +285,5 @@ def asdf_cut(input_file: str, ra: float, dec: float, cutout_size: int = 20,
278285
pixel_coordinates, wcs = get_center_pixel(gwcsobj, ra, dec)
279286

280287
# create the 2d image cutout
281-
return get_cutout(data, pixel_coordinates, wcs, size=cutout_size, outfile=output_file,
282-
write_file=write_file, fill_value=fill_value, gwcsobj=gwcsobj)
288+
return _get_cutout(data, pixel_coordinates, wcs, size=cutout_size, outfile=output_file,
289+
write_file=write_file, fill_value=fill_value, gwcsobj=gwcsobj)

astrocut/tests/test_asdf_cut.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from astropy.wcs.utils import pixel_to_skycoord
1414
from gwcs import wcs
1515
from gwcs import coordinate_frames as cf
16-
from astrocut.asdf_cutouts import get_center_pixel, get_cutout, asdf_cut, _slice_gwcs, _get_cloud_http
16+
from astrocut.asdf_cutouts import get_center_pixel, asdf_cut, _get_cutout, _slice_gwcs, _get_cloud_http
1717

1818

1919
def make_wcs(xsize, ysize, ra=30., dec=45.):
@@ -137,7 +137,7 @@ def test_get_cutout(output, fakedata, quantity):
137137
data = data.value
138138

139139
# create cutout
140-
cutout = get_cutout(data, skycoord, wcs, size=10, outfile=output_file)
140+
cutout = _get_cutout(data, skycoord, wcs, size=10, outfile=output_file)
141141

142142
assert_same_coord(5, 10, cutout, wcs)
143143

@@ -185,7 +185,7 @@ def test_fail_write_asdf(fakedata, output):
185185
data, gwcs = fakedata
186186
skycoord = gwcs(25, 25, with_units=True)
187187
wcs = WCS(gwcs.to_fits_sip())
188-
get_cutout(data, skycoord, wcs, size=10, outfile=output_file)
188+
_get_cutout(data, skycoord, wcs, size=10, outfile=output_file)
189189

190190

191191
def test_cutout_nofile(make_file, output):
@@ -217,7 +217,7 @@ def test_cutout_poles(makefake):
217217
wcs = WCS(gwcs.to_fits_sip())
218218

219219
# get cutout
220-
cutout = get_cutout(data, cc, wcs, size=50, write_file=False)
220+
cutout = _get_cutout(data, cc, wcs, size=50, write_file=False)
221221
assert_same_coord(5, 10, cutout, wcs)
222222

223223
# check cutout contains all data
@@ -232,7 +232,7 @@ def test_fail_cutout_outside(fakedata):
232232

233233
with pytest.raises(RuntimeError, match='Could not create 2d cutout. The requested '
234234
'cutout does not overlap with the original image'):
235-
get_cutout(data, cc, wcs, size=50, write_file=False)
235+
_get_cutout(data, cc, wcs, size=50, write_file=False)
236236

237237

238238
def assert_same_coord(x, y, cutout, wcs):
@@ -251,7 +251,7 @@ def test_partial_cutout(makefake, asint, fill):
251251

252252
wcs = WCS(gwcs.to_fits_sip())
253253
cc = coord.SkyCoord(29.999, 44.998, unit=u.degree)
254-
cutout = get_cutout(data, cc, wcs, size=50, write_file=False, fill_value=fill)
254+
cutout = _get_cutout(data, cc, wcs, size=50, write_file=False, fill_value=fill)
255255
assert cutout.shape == (50, 50)
256256
if asint:
257257
assert -9999 in cutout.data
@@ -266,7 +266,7 @@ def test_bad_fill(makefake):
266266
wcs = WCS(gwcs.to_fits_sip())
267267
cc = coord.SkyCoord(29.999, 44.998, unit=u.degree)
268268
with pytest.raises(ValueError, match='fill_value is inconsistent with the data type of the input array'):
269-
get_cutout(data, cc, wcs, size=50, write_file=False)
269+
_get_cutout(data, cc, wcs, size=50, write_file=False)
270270

271271

272272
def test_cutout_raedge(makefake):
@@ -284,7 +284,7 @@ def test_cutout_raedge(makefake):
284284
wcs = WCS(gg.to_fits_sip())
285285

286286
# get cutout
287-
cutout = get_cutout(data, cc, wcs, size=100, write_file=False)
287+
cutout = _get_cutout(data, cc, wcs, size=100, write_file=False)
288288
assert_same_coord(5, 10, cutout, wcs)
289289

290290
# assert the RA cutout bounds are > 359 and < 0
@@ -299,7 +299,7 @@ def test_slice_gwcs(fakedata):
299299
skycoord = gwcsobj(250, 250)
300300
wcs = WCS(gwcsobj.to_fits_sip())
301301

302-
cutout = get_cutout(data, skycoord, wcs, size=50, write_file=False)
302+
cutout = _get_cutout(data, skycoord, wcs, size=50, write_file=False)
303303

304304
sliced = _slice_gwcs(gwcsobj, cutout.slices_original)
305305

@@ -329,6 +329,6 @@ def test_get_cloud_http(mock_s3fs):
329329
http_uri = _get_cloud_http(s3_uri)
330330

331331
assert http_uri == HTTP_URI
332-
mock_s3fs.assert_called_once_with(anon=True)
332+
mock_s3fs.assert_called_once_with()
333333
mock_fs.open.assert_called_once_with(s3_uri, 'rb')
334334
mock_file.url.assert_called_once()

docs/astrocut/file_formats.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ it contains the name of the file the cutout comes from.
3939

4040

4141

42+
ASDF Cutout Files
43+
==================
44+
45+
ASDF files output by `asdf_cut` are a minimal tree structure that mirrors the format of the original Roman image file.
46+
47+
.. code-block:: python
48+
49+
asdf_cutout = {
50+
"roman": {
51+
"meta": {
52+
"wcs" - the gwcs of the cutout
53+
},
54+
"data" - the cutout data
55+
}
56+
}
57+
58+
`wcs` is the original `gwcs` object from the input ASDF file that has been sliced into the shape of the cutout.
59+
60+
61+
4262
Cube Files
4363
==========
4464

docs/astrocut/index.rst

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ Three main areas of functionality are included:
1717

1818

1919

20-
FITS file image cutouts
20+
FITS File Image Cutouts
2121
=======================
2222

2323
These functions provide general purpose astronomical cutout functionality for FITS files.
2424
There are two main cutout functions, `~astrocut.fits_cut` for creating cutout FITS files,
2525
and `~astrocut.img_cut` for creating cutout JPG or PNG files. An image normalization
2626
(`~astrocut.normalize_img`) function is also available.
2727

28-
Creating FITS cutouts
28+
Creating FITS Cutouts
2929
---------------------
3030

3131
The function `~astrocut.fits_cut` takes one or more FITS files and performs the same cutout
@@ -107,7 +107,7 @@ The cutout(s) can also be returned in memory as `~astropy.io.fits.HDUList` objec
107107
1 CUTOUT 1 ImageHDU 97 (100, 100) float32
108108
109109
110-
Creating image cutouts
110+
Creating Image Cutouts
111111
----------------------
112112

113113
The function `~astrocut.img_cut` takes one or more FITS files and performs the same cutout
@@ -179,7 +179,7 @@ the same Sector, camera, and CCD.
179179
If you are creating a small number of cutouts, the TESSCut web service
180180
may suit your needs: `mast.stsci.edu/tesscut <https://mast.stsci.edu/tesscut/>`_
181181

182-
Making image cubes
182+
Making Image Cubes
183183
------------------
184184

185185
.. important::
@@ -250,7 +250,7 @@ The output image cube file format is described `here <file_formats.html#cube-fil
250250
2 1 BinTableHDU 302 144R x 147C [24A, J, J, J, J, J, J, D, 24A, J, 24A, 24A, J, J, D, 24A, 24A, 24A, J, D, 24A, D, D, D, D, 24A, 24A, D, D, D, D, D, 24A, D, D, D, D, J, D, D, D, D, D, D, D, D, D, D, D, D, J, J, D, J, J, J, J, J, J, J, J, J, J, D, J, J, J, J, J, J, D, J, J, J, J, J, J, D, J, J, J, J, J, J, D, J, J, J, J, J, J, J, J, 24A, D, J, 24A, 24A, D, D, D, D, D, D, D, D, J, J, D, D, D, D, D, D, J, J, D, D, D, D, D, D, D, D, D, D, D, D, 24A, J, 24A, 24A, J, J, D, 24A, 24A, J, J, D, D, D, D, J, 24A, 24A, 24A]
251251
252252
253-
Making cutout target pixel files
253+
Making Cutout Target Pixel Files
254254
--------------------------------
255255

256256
To make a cutout, you must already have an image cube from which to create the cutout.
@@ -356,10 +356,61 @@ Note that multithreading is disabled by default.
356356
Total time: 7.8 sec
357357
358358
359+
360+
ASDF File Cutouts
361+
===================
362+
363+
The Nancy Grace Roman Space Telescope will store its data using the Advanced Scientific Data Format (ASDF). With the `asdf_cut` function, users can create cutouts of Roman mission products.
364+
365+
Creating ASDF Cutouts
366+
----------------------
367+
368+
The function `asdf_cut` performs a cutout of an ASDF file and returns the result as either a FITS file or an ASDF file.
369+
The format of the cutout is determined by the filename extension of the `output_file` parameter. In the below example, a cutout is written as a FITS file.
370+
The cutout FITS file format is described `here <file_formats.html#fits-cutout-files>`__.
371+
372+
.. code-block:: python
373+
374+
>>> from astrocut import asdf_cut
375+
>>> from astropy.coordinates import SkyCoord
376+
>>> from astropy.io import fits
377+
378+
>>> input_file = "" # Path to local ASDF file or URI
379+
380+
>>> center_coord = SkyCoord("80.15189743 29.74561219", unit='deg')
381+
382+
>>> cutout_file = asdf_cut(input_file, center_coord.ra, center_coord.dec, cutout_size=200,
383+
... output_file="roman-demo.fits") #doctest: +SKIP
384+
385+
>>> cutout_hdulist = fits.open(cutout_file) #doctest: +SKIP
386+
>>> cutout_hdulist.info() #doctest: +SKIP
387+
Filename: roman-demo.fits
388+
No. Name Ver Type Cards Dimensions Format
389+
0 PRIMARY 1 PrimaryHDU 25 (200, 200) float32
390+
391+
`asdf_cut` accepts S3 URIs to perform cutouts on ASDF files from the cloud.
392+
In this example, a cutout is performed on a cloud file and written as an ASDF file. The cutout ASDF file format is described `here <file_formats.html#asdf-cutout-files>`__.
393+
394+
.. code-block:: python
395+
396+
>>> from astrocut import asdf_cut
397+
>>> from astropy.coordinates import SkyCoord
398+
399+
>>> s3_uri = "s3://..." # Complete URI
400+
401+
>>> center_coord = SkyCoord("80.15189743 29.74561219", unit='deg')
402+
403+
>>> cutout_file = asdf_cut(s3_uri, center_coord.ra, center_coord.dec, cutout_size=200,
404+
... output_file="roman-demo.asdf") #doctest: +SKIP
405+
406+
When requesting a cutout that is partially outside of image bounds, the `fill_value` parameter is used to preserve the cutout shape and fill outside pixels.
407+
408+
409+
359410
Additional Cutout Processing
360411
============================
361412

362-
Path-based cutouts
413+
Path-based Cutouts
363414
------------------
364415

365416
The `~astrocut.center_on_path` function allows the user to take one or more Astrocut cutout
@@ -436,7 +487,7 @@ cutout location/size(s) necesary to cover the entire path.
436487
2 APERTURE 1 ImageHDU 97 (2136, 2078) int32
437488
438489
439-
Combining cutouts
490+
Combining Cutouts
440491
-----------------
441492

442493
The `~astrocut.CutoutsCombiner` class allows the user to take one or more Astrocut cutout

0 commit comments

Comments
 (0)