Skip to content

Commit 6115fbb

Browse files
authored
Remove TICA option from TESS footprint cutouts, deprecate product parameter (#161)
* Remove from footprint cutouts, deprecate product parameter * fix test bug * Deprecation in other classes, update docs * Docs note * Update changelog
1 parent 1135558 commit 6115fbb

File tree

10 files changed

+94
-114
lines changed

10 files changed

+94
-114
lines changed

CHANGES.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- By default, ASDF cutouts now preserve all metadata from the input file. [#158]
99
- Add ``lite`` parameter to ``ASDFCutout`` to create minimal cutouts with only the science data and updated world coordinate system. [#158]
1010
- Add history entry to ASDF cutouts specifying the cutout shape and center coordinates. [#158]
11+
- Remove TICA (TESS Image Calibration) as an option for the ``product`` parameter in ``TessFootprintCutout``. [#161]
12+
- Deprecate the ``TicaCubeFactory`` class. [#161]
13+
- Deprecate the ``product`` parameter in the ``TessCubeCutout`` class, the ``TessFootprintCutout`` class, the ``cube_cut`` function,
14+
the ``CutoutFactory.cube_cut`` function, and the ``cube_cutout_from_footprint`` function. [#161]
1115

1216

1317
1.0.1 (2025-05-12)

astrocut/cube_factory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class CubeFactory():
4444
Updates an existing cube file with new FITS images.
4545
"""
4646

47-
ERROR_MSG = ('One or more incorrect file types were input. Please input TICA FFI files when using '
48-
'``TicaCubeFactory``, and SPOC FFI files when using ``CubeFactory``.')
47+
ERROR_MSG = ('One or more incorrect file types were input. Please input only SPOC FFI files when '
48+
'using ``CubeFactory``.')
4949

5050
def __init__(self, max_memory: int = 50):
5151
""" Setting up the class members """

astrocut/cutout_factory.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import astropy.units as u
99
import numpy as np
1010
from astropy.coordinates import SkyCoord
11+
from astropy.utils.decorators import deprecated_renamed_argument
1112
from s3path import S3Path
1213

1314
from .tess_cube_cutout import TessCubeCutout
@@ -18,14 +19,16 @@ class CutoutFactory():
1819
Class for creating image cutouts from TESS image cube files.
1920
2021
This class encompasses all of the cutout functionality.
21-
In the current version this means creating cutout target pixel files from both
22-
SPOC (Science Processing Operations Center) and TICA (Tess Image CAlibration)
23-
full frame image cubes.
22+
In the current version, this means creating cutout target pixel files from
23+
TESS full frame images cubes.
2424
2525
This class is maintained for backwards compatibility. For maximum flexibility, we recommend using the
2626
`~astrocut.TessCubeCutout` class.
2727
"""
2828

29+
@deprecated_renamed_argument('product', None, since='1.1.0', message='The `product` argument is deprecated and '
30+
'will be removed in a future version. Astrocut will only support cutouts from '
31+
'SPOC products.')
2932
def cube_cut(self, cube_file: Union[str, Path, S3Path], coordinates: Union[SkyCoord, str],
3033
cutout_size: Union[int, np.ndarray, u.Quantity, List[int], Tuple[int]],
3134
product: str = 'SPOC', target_pixel_file: Optional[str] = None,
@@ -57,8 +60,9 @@ def cube_cut(self, cube_file: Union[str, Path, S3Path], coordinates: Union[SkyCo
5760
units of pixels. `~astropy.units.Quantity` objects must be in pixel or
5861
angular units.
5962
product : str
60-
The product type to make the cutouts from.
61-
Can either be 'SPOC' or 'TICA' (default is 'SPOC').
63+
.. deprecated:: 1.1.0
64+
This parameter is deprecated and will be removed in a future release.
65+
Only "SPOC" products will be supported.
6266
target_pixel_file : str
6367
Optional. The name for the output target pixel file.
6468
If no name is supplied, the file will be named:
@@ -104,7 +108,8 @@ def cube_cut(self, cube_file: Union[str, Path, S3Path], coordinates: Union[SkyCo
104108
output_file=target_pixel_file)[0]
105109

106110

107-
111+
@deprecated_renamed_argument('product', None, since='1.1.0', message='The `product` argument is deprecated and will be '
112+
'removed in a future version. Astrocut will only support cutouts from SPOC products.')
108113
def cube_cut(cube_file: Union[str, Path, S3Path], coordinates: Union[SkyCoord, str],
109114
cutout_size: Union[int, np.ndarray, u.Quantity, List[int], Tuple[int]],
110115
product: str = 'SPOC', target_pixel_file: Optional[str] = None,
@@ -136,8 +141,9 @@ def cube_cut(cube_file: Union[str, Path, S3Path], coordinates: Union[SkyCoord, s
136141
units of pixels. `~astropy.units.Quantity` objects must be in pixel or
137142
angular units.
138143
product : str
139-
The product type to make the cutouts from.
140-
Can either be 'SPOC' or 'TICA' (default is 'SPOC').
144+
.. deprecated:: 1.1.0
145+
This parameter is deprecated and will be removed in a future release.
146+
Only "SPOC" products will be supported.
141147
target_pixel_file : str
142148
Optional. The name for the output target pixel file.
143149
If no name is supplied, the file will be named:

astrocut/tess_cube_cutout.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from astropy.coordinates import SkyCoord
99
from astropy.io import fits
1010
from astropy.time import Time
11+
from astropy.utils.decorators import deprecated_renamed_argument
1112
from astropy.wcs import WCS
1213
from s3path import S3Path
1314

@@ -36,8 +37,9 @@ class TessCubeCutout(CubeCutout):
3637
The number of threads to use for making the cutouts. If 'auto', the number of threads will be set to the number
3738
of available CPUs.
3839
product : str
39-
The product type to make the cutouts from.
40-
Can either be 'SPOC' or 'TICA' (default is 'SPOC').
40+
.. deprecated:: 1.1.0
41+
This parameter is deprecated and will be removed in a future release.
42+
Only "SPOC" products will be supported.
4143
verbose : bool
4244
If True, log messages are printed to the console.
4345
@@ -60,6 +62,9 @@ class TessCubeCutout(CubeCutout):
6062
Write the cutouts to target pixel files.
6163
"""
6264

65+
@deprecated_renamed_argument('product', None, since='1.1.0', message='The `product` argument is deprecated and '
66+
'will be removed in a future version. Astrocut will only support cutouts from '
67+
'SPOC products.')
6368
def __init__(self, input_files: List[Union[str, Path, S3Path]], coordinates: Union[SkyCoord, str],
6469
cutout_size: Union[int, np.ndarray, u.Quantity, List[int], Tuple[int]] = 25,
6570
fill_value: Union[int, float] = np.nan, limit_rounding_method: str = 'round',

astrocut/tess_footprint_cutout.py

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
from astropy.coordinates import SkyCoord
88
from astropy.io.fits import HDUList
9+
from astropy.utils.decorators import deprecated_renamed_argument
910
from astropy.table import Table
1011

1112
from . import log
@@ -35,7 +36,9 @@ class TessFootprintCutout(FootprintCutout):
3536
cutouts will be generated from all sequences that contain the cutout.
3637
For the TESS mission, this parameter corresponds to sectors.
3738
product : str, optional
38-
Default 'SPOC'. The product type to make the cutouts from.
39+
.. deprecated:: 1.1.0
40+
This parameter is deprecated and will be removed in a future release.
41+
Only "SPOC" products are now supported.
3942
verbose : bool
4043
If True, log messages are printed to the console.
4144
@@ -62,25 +65,24 @@ class TessFootprintCutout(FootprintCutout):
6265
Write the cutouts as Target Pixel Files (TPFs) to the specified directory.
6366
"""
6467

68+
@deprecated_renamed_argument('product', None, since='1.1.0', message='Astrocut no longer supports cutouts from '
69+
'TESS Image Calibrator (TICA) products. '
70+
'The `product` argument is deprecated and will be removed in a future version.')
6571
def __init__(self, coordinates: Union[SkyCoord, str],
6672
cutout_size: Union[int, np.ndarray, u.Quantity, List[int], Tuple[int]] = 25,
6773
fill_value: Union[int, float] = np.nan, limit_rounding_method: str = 'round',
6874
sequence: Union[int, List[int], None] = None, product: str = 'SPOC', verbose: bool = False):
6975
super().__init__(coordinates, cutout_size, fill_value, limit_rounding_method, sequence, verbose)
7076

7177
# Validate and set the product
72-
if product.upper() not in ['SPOC', 'TICA']:
73-
raise InvalidInputError('Product for TESS cube cutouts must be either "SPOC" or "TICA".')
74-
self._product = product.upper()
78+
if product.upper() != 'SPOC':
79+
raise InvalidInputError('Product for TESS cube cutouts must be "SPOC".')
80+
self._product = 'SPOC'
7581
self._arcsec_per_px = 21 # Number of arcseconds per pixel in a TESS image
7682

77-
# Set S3 URIs to footprint cache file and base file path based on product
78-
if self._product == 'SPOC':
79-
self._s3_footprint_cache = 's3://stpubdata/tess/public/footprints/tess_ffi_footprint_cache.json'
80-
self._s3_base_file_path = 's3://stpubdata/tess/public/mast/'
81-
else:
82-
self._s3_footprint_cache = 's3://stpubdata/tess/public/footprints/tica_ffi_footprint_cache.json'
83-
self._s3_base_file_path = 's3://stpubdata/tess/public/mast/tica/'
83+
# Set S3 URIs to footprint cache file and base file path
84+
self._s3_footprint_cache = 's3://stpubdata/tess/public/footprints/tess_ffi_footprint_cache.json'
85+
self._s3_base_file_path = 's3://stpubdata/tess/public/mast/'
8486

8587
# Make the cutouts upon initialization
8688
self.cutout()
@@ -99,14 +101,8 @@ def _extract_sequence_information(self, sector_name: str) -> dict:
99101
dict
100102
A dictionary containing the sector name, sector number, camera number, and CCD number.
101103
"""
102-
# Define the pattern based on the product
103-
if self._product == 'SPOC':
104-
pattern = re.compile(r"(tess-s)(?P<sector>\d{4})-(?P<camera>\d{1,4})-(?P<ccd>\d{1,4})")
105-
elif self._product == 'TICA':
106-
pattern = re.compile(r"(hlsp_tica_s)(?P<sector>\d{4})-(cam)(?P<camera>\d{1,4})-(ccd)(?P<ccd>\d{1,4})")
107-
else:
108-
# Return an empty dictionary if the product is not recognized
109-
return {}
104+
# Example sector name format: "tess-s0001-4-4"
105+
pattern = re.compile(r"(tess-s)(?P<sector>\d{4})-(?P<camera>\d{1,4})-(?P<ccd>\d{1,4})")
110106
sector_match = re.match(pattern, sector_name)
111107

112108
if not sector_match:
@@ -118,10 +114,6 @@ def _extract_sequence_information(self, sector_name: str) -> dict:
118114
camera = sector_match.group("camera")
119115
ccd = sector_match.group("ccd")
120116

121-
# Rename the TICA sector because of the naming convention in Astrocut
122-
if self._product == 'TICA':
123-
sector_name = f"tica-s{sector}-{camera}-{ccd}"
124-
125117
return {"sectorName": sector_name, "sector": sector, "camera": camera, "ccd": ccd}
126118

127119
def _create_sequence_list(self, observations: Table) -> List[dict]:
@@ -139,8 +131,7 @@ def _create_sequence_list(self, observations: Table) -> List[dict]:
139131
A list of dictionaries, each containing the sector name, sector number, camera number, and CCD number.
140132
"""
141133
# Filter observations by target name to get only the FFI observations
142-
target_name = "TESS FFI" if self._product == 'SPOC' else "TICA FFI"
143-
obs_filtered = [obs for obs in observations if obs["target_name"].upper() == target_name]
134+
obs_filtered = [obs for obs in observations if obs["target_name"].upper() == "TESS FFI"]
144135

145136
sequence_results = []
146137
for row in obs_filtered:
@@ -220,7 +211,7 @@ def cutout(self):
220211
input_files = [f"{self._s3_base_file_path}{file['cube']}" for file in files_mapping]
221212
tess_cube_cutout = TessCubeCutout(input_files, self._coordinates, self._cutout_size,
222213
self._fill_value, self._limit_rounding_method, threads=8,
223-
product=self._product, verbose=self._verbose)
214+
verbose=self._verbose)
224215

225216
# Assign attributes from the TessCubeCutout object
226217
self.tess_cube_cutout = tess_cube_cutout
@@ -244,8 +235,11 @@ def write_as_tpf(self, output_dir: Union[str, Path] = '.') -> List[str]:
244235
List of file paths to cutout target pixel files.
245236
"""
246237
return self.tess_cube_cutout.write_as_tpf(output_dir)
247-
248238

239+
240+
@deprecated_renamed_argument('product', None, since='1.1.0', message='Astrocut no longer supports cutouts from '
241+
'TESS Image Calibrator (TICA) products. '
242+
'The `product` argument is deprecated and will be removed in a future version.')
249243
def cube_cut_from_footprint(coordinates: Union[str, SkyCoord], cutout_size,
250244
sequence: Union[int, List[int], None] = None, product: str = 'SPOC',
251245
memory_only=False, output_dir: str = '.',
@@ -273,7 +267,9 @@ def cube_cut_from_footprint(coordinates: Union[str, SkyCoord], cutout_size,
273267
cutouts will be generated from all sequences that contain the cutout.
274268
For the TESS mission, this parameter corresponds to sectors.
275269
product : str, optional
276-
Default 'SPOC'. The product type to make the cutouts from.
270+
.. deprecated:: 1.1.0
271+
This parameter is deprecated and will be removed in a future release.
272+
Only "SPOC" products are now supported.
277273
memory_only : bool, optional
278274
Default False. If True, the cutouts are stored in memory and not written to disk.
279275
output_dir : str, optional
@@ -295,7 +291,6 @@ def cube_cut_from_footprint(coordinates: Union[str, SkyCoord], cutout_size,
295291
... coordinates='83.40630967798376 -62.48977125108528',
296292
... cutout_size=64,
297293
... sequence=[1, 2], # TESS sectors
298-
... product='SPOC',
299294
... output_dir='./cutouts')
300295
['./cutouts/tess-s0001-4-4/tess-s0001-4-4_83.406310_-62.489771_64x64_astrocut.fits',
301296
'./cutouts/tess-s0002-4-1/tess-s0002-4-1_83.406310_-62.489771_64x64_astrocut.fits']

astrocut/tests/test_cube_factory.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,7 @@ def test_invalid_inputs(tmpdir, ffi_type, img_size, num_images):
182182
"""
183183
# Assigning some variables
184184
product = 'TICA' if ffi_type == 'TICA' else 'SPOC'
185-
value_error = ('One or more incorrect file types were input. Please input TICA FFI files when using '
186-
'``TicaCubeFactory``, and SPOC FFI files when using ``CubeFactory``.')
185+
value_error = ('One or more incorrect file types were input.')
187186

188187
# Create test FFI files
189188
ffi_files = create_test_ffis(img_size=img_size,

astrocut/tests/test_tess_footprint_cutout.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ def coordinates():
2626
return SkyCoord('350 -80', unit='deg')
2727

2828

29-
def check_output_tpf(tpf, ffi_type, sequences=[], cutout_size=5):
29+
def check_output_tpf(tpf, sequences=[], cutout_size=5):
3030
"""Helper function to check the validity of output cutout files"""
3131
tpf_table = tpf[1].data
3232

3333
# SPOC cutouts have 1 extra columns in EXT 1
34-
ncols = 12 if ffi_type == 'SPOC' else 11
35-
assert len(tpf_table.columns) == ncols
34+
assert len(tpf_table.columns) == 12
3635
assert tpf_table[0]['FLUX'].shape == (cutout_size, cutout_size)
3736

3837
# Check that sector matches a provided sequence
@@ -78,10 +77,9 @@ def test_ffi_intersect(lon, lat, center, expected):
7877
assert intersection.value[0] == expected
7978

8079

81-
@pytest.mark.parametrize('ffi_type', ['SPOC', 'TICA'])
82-
def test_tess_footprint_cutout(cutout_size, caplog, ffi_type):
80+
def test_tess_footprint_cutout(cutout_size, caplog):
8381
"""Test that a single data cube is created for a given sequence"""
84-
cutout = TessFootprintCutout('130 30', cutout_size, product=ffi_type, sequence=44, verbose=True)
82+
cutout = TessFootprintCutout('130 30', cutout_size, sequence=44, verbose=True)
8583

8684
# Check cutouts attribute
8785
cutouts = cutout.cutouts
@@ -101,15 +99,15 @@ def test_tess_footprint_cutout(cutout_size, caplog, ffi_type):
10199
assert len(tpf_cutouts) == 1
102100
assert isinstance(tpf_cutouts, list)
103101
assert isinstance(tpf_cutouts[0], fits.HDUList)
104-
check_output_tpf(tpf_cutouts[0], ffi_type, [44])
102+
check_output_tpf(tpf_cutouts[0], [44])
105103

106104
# Check tpf_cutouts_by_file
107105
tpf_cutouts_by_file = cutout.tpf_cutouts_by_file
108106
tpf_cutout = list(tpf_cutouts_by_file.values())[0]
109107
assert len(tpf_cutouts_by_file) == 1
110108
assert isinstance(tpf_cutouts_by_file, dict)
111109
assert isinstance(tpf_cutout, fits.HDUList)
112-
check_output_tpf(tpf_cutout, ffi_type, [44])
110+
check_output_tpf(tpf_cutout, [44])
113111

114112
# Check tess_cube attribute
115113
tess_cube = cutout.tess_cube_cutout
@@ -125,8 +123,8 @@ def test_tess_footprint_cutout(cutout_size, caplog, ffi_type):
125123
assert 'Generating cutouts...' in captured
126124

127125
# Check that _extract_sequence_information works correctly
128-
# Should return empty dict if sector name does not match product
129-
sector_name = 'hlsp_tica_s' if ffi_type == 'SPOC' else 'tess_s'
126+
# Should return empty dict if sector name does not match format
127+
sector_name = 'invalid_s'
130128
sector_name += '0044-4-1'
131129
info = cutout._extract_sequence_information(sector_name)
132130
assert info == {}
@@ -135,18 +133,18 @@ def test_tess_footprint_cutout(cutout_size, caplog, ffi_type):
135133
def test_tess_footprint_cutout_multi_sequence(coordinates, cutout_size):
136134
"""Test that a cube is created for each sequence when multiple are provided"""
137135
sequences = [1, 13]
138-
cutout = TessFootprintCutout(coordinates, cutout_size, product='SPOC', sequence=sequences)
136+
cutout = TessFootprintCutout(coordinates, cutout_size, sequence=sequences)
139137
cutout_tpfs = cutout.tpf_cutouts
140138
assert len(cutout_tpfs) == 2
141139

142140
for tpf in cutout_tpfs:
143-
check_output_tpf(tpf, 'SPOC', sequences)
141+
check_output_tpf(tpf, sequences)
144142

145143

146144
def test_tess_footprint_cutout_all_sequences(coordinates, cutout_size):
147145
"""Test that cubes are created for all sequences that intersect the cutout"""
148146
# Create cutouts for all possible sequences
149-
cutout = TessFootprintCutout(coordinates, cutout_size, product='SPOC')
147+
cutout = TessFootprintCutout(coordinates, cutout_size)
150148
cutout_tpfs = cutout.tpf_cutouts
151149
assert len(cutout_tpfs) >= 5
152150

@@ -159,7 +157,7 @@ def test_tess_footprint_cutout_all_sequences(coordinates, cutout_size):
159157
# Assert non-empty results
160158
assert len(seq_list) == len(cutout_tpfs)
161159
for tpf in cutout_tpfs:
162-
check_output_tpf(tpf, 'SPOC', sequences)
160+
check_output_tpf(tpf, sequences)
163161

164162

165163
def test_tess_footprint_cutout_write_as_tpf(coordinates, cutout_size, tmpdir):
@@ -193,9 +191,12 @@ def test_tess_footprint_cutout_outside_coords(coordinates, cutout_size):
193191

194192
def test_tess_footprint_cutout_invalid_product(coordinates, cutout_size):
195193
"""Test that InvalidQueryError is raised if an invalid product is given"""
196-
err = 'Product for TESS cube cutouts must be either "SPOC" or "TICA".'
194+
err = 'Product for TESS cube cutouts must be "SPOC".'
197195
with pytest.raises(InvalidInputError, match=err):
198196
TessFootprintCutout(coordinates, cutout_size, product='invalid')
197+
198+
with pytest.raises(InvalidInputError, match=err):
199+
TessFootprintCutout(coordinates, cutout_size, product='TICA')
199200

200201

201202
def test_cube_cut_from_footprint(coordinates, cutout_size, tmpdir):

astrocut/tica_cube_factory.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
import numpy as np
66
from astropy.io import fits
7+
from astropy.utils.decorators import deprecated
78

89
from .cube_factory import CubeFactory
910

1011

12+
@deprecated(since='1.1.0', message='The `TicaCubeFactory` class is deprecated and will be removed in a future version. '
13+
'Use the `CubeFactory` class for creating image cubes from SPOC product files.')
1114
class TicaCubeFactory(CubeFactory):
1215
"""
1316
Class for creating TICA image cubes.
@@ -25,7 +28,6 @@ class TicaCubeFactory(CubeFactory):
2528
Note, this is the maximum amount of space to be used for the cube array only,
2629
so should not be set to the full amount of memory on the system.
2730
"""
28-
2931
def __init__(self, max_memory: int = 50):
3032
""" Setting up the class members."""
3133
super().__init__(max_memory=max_memory)

0 commit comments

Comments
 (0)