Skip to content

Commit d927bdf

Browse files
authored
Merge pull request #3427 from snbianco/filter-case
2 parents aa9c920 + b4ccef0 commit d927bdf

File tree

6 files changed

+50
-21
lines changed

6 files changed

+50
-21
lines changed

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ mast
2525

2626
- Raise an error if non-string values are passed to ``utils.resolve_object``. [#3435]
2727

28+
- Filtering by file extension or by a string column is now case-insensitive in ``MastMissions.filter_products``
29+
and ``Observations.filter_products``. [#3427]
2830

2931

3032
Infrastructure, Utility and Other Changes and Additions

astroquery/mast/missions.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -517,12 +517,7 @@ def filter_products(self, products, *, extension=None, **filters):
517517

518518
# Filter by file extension, if provided
519519
if extension:
520-
extensions = [extension] if isinstance(extension, str) else extension
521-
ext_mask = np.array(
522-
[not isinstance(x, np.ma.core.MaskedConstant) and any(x.endswith(ext) for ext in extensions)
523-
for x in products["filename"]],
524-
dtype=bool
525-
)
520+
ext_mask = utils.apply_extension_filter(products, extension, 'filename')
526521
filter_mask &= ext_mask
527522

528523
# Apply column-based filters

astroquery/mast/observations.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -594,12 +594,7 @@ def filter_products(self, products, *, mrp_only=False, extension=None, **filters
594594

595595
# Filter by file extension, if provided
596596
if extension:
597-
extensions = [extension] if isinstance(extension, str) else extension
598-
ext_mask = np.array(
599-
[not isinstance(x, np.ma.core.MaskedConstant) and any(x.endswith(ext) for ext in extensions)
600-
for x in products["productFilename"]],
601-
dtype=bool
602-
)
597+
ext_mask = utils.apply_extension_filter(products, extension, 'productFilename')
603598
filter_mask &= ext_mask
604599

605600
# Apply column-based filters

astroquery/mast/tests/test_mast.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ def test_missions_filter_products(patch_post):
428428
assert all(~((filtered['size'] >= 14400) & (filtered['size'] <= 17280)))
429429

430430
# Negate a string match
431-
filtered = mast.MastMissions.filter_products(products, category='!CALIBRATED')
431+
filtered = mast.MastMissions.filter_products(products, category='!calibrated')
432432
assert all(filtered['category'] != 'CALIBRATED')
433433

434434
# Negate one string in a list
@@ -802,7 +802,7 @@ def test_observations_get_product_list(patch_post):
802802
def test_observations_filter_products(patch_post):
803803
products = mast.Observations.get_product_list('2003738726')
804804
filtered = mast.Observations.filter_products(products,
805-
productType=["SCIENCE"],
805+
productType=["sCiEnCE"],
806806
mrp_only=False)
807807
assert isinstance(filtered, Table)
808808
assert len(filtered) == 7
@@ -812,8 +812,10 @@ def test_observations_filter_products(patch_post):
812812
assert all(filtered['productGroupDescription'] == 'Minimum Recommended Products')
813813

814814
# Filter by extension
815-
filtered = mast.Observations.filter_products(products, extension='fits')
815+
filtered = mast.Observations.filter_products(products, extension='FITS')
816816
assert len(filtered) > 0
817+
filtered = mast.Observations.filter_products(products, extension=['png'])
818+
assert len(filtered) == 0
817819

818820
# Numeric filtering
819821
filtered = mast.Observations.filter_products(products, size='<50000')

astroquery/mast/utils.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,38 @@ def remove_duplicate_products(data_products, uri_key):
456456
return unique_products
457457

458458

459+
def apply_extension_filter(products, extension, filename_key):
460+
"""
461+
Applies an extension filter to a product table.
462+
463+
Parameters
464+
----------
465+
products : `~astropy.table.Table`
466+
The product table to filter.
467+
extension : str
468+
The extension to filter by (e.g., 'fits', 'csv').
469+
filename_key : str
470+
The column name representing the filename of a product.
471+
472+
Returns
473+
-------
474+
ext_mask : `numpy.ndarray`
475+
A boolean mask indicating which rows of the product table have the specified extension.
476+
"""
477+
# Normalize extensions to lowercase
478+
extensions = [extension] if isinstance(extension, str) else extension
479+
extensions = tuple(ext.lower() for ext in extensions)
480+
481+
# Build mask
482+
ext_mask = np.array(
483+
[not isinstance(x, np.ma.core.MaskedConstant)
484+
and str(x).lower().endswith(extensions)
485+
for x in products[filename_key]],
486+
dtype=bool
487+
)
488+
return ext_mask
489+
490+
459491
def _combine_positive_negative_masks(mask_funcs):
460492
"""
461493
Combines a list of mask functions into a single mask according to:
@@ -582,7 +614,9 @@ def apply_column_filters(products, filters):
582614
v = val[1:] if is_negated else val
583615

584616
def func(col, v=v):
585-
return np.isin(col, [v])
617+
# Normalize both column values and filter to lowercase strings for case-insensitive comparison
618+
col_lower = np.char.lower(col.astype(str))
619+
return np.isin(col_lower, [v.lower()])
586620
mask_funcs.append((func, is_negated))
587621

588622
this_mask = _combine_positive_negative_masks(mask_funcs)(col_data)

docs/mast/mast_cut.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Processing Operation's Center (`SPOC <https://archive.stsci.edu/missions-and-dat
1212
The cutouts are returned in the form of target pixel files that follow the same format as TESS pipeline target
1313
pixel files. This tool can be accessed in Astroquery by using the Tesscut class.
1414

15-
As of August 2025, the option to create cutouts using TESS Image CAlibration
16-
(`TICA <https://ui.adsabs.harvard.edu/abs/2020RNAAS...4..251F/abstract>`__) full frame images
17-
was discontinued. Individual TICA full frame images remain available from the
15+
As of August 2025, the option to create cutouts using TESS Image CAlibration
16+
(`TICA <https://ui.adsabs.harvard.edu/abs/2020RNAAS...4..251F/abstract>`__) full frame images
17+
was discontinued. Individual TICA full frame images remain available from the
1818
`MAST TICA homepage <https://archive.stsci.edu/hlsp/tica>`__. Cutouts using SPOC data remain available through TESSCut.
1919

2020
**Note:** TESScut limits each user to no more than 10 simultaneous calls to the service.
@@ -97,7 +97,7 @@ simply with either the objectname or coordinates.
9797
2 APERTURE 1 ImageHDU 97 (2136, 2078) int32
9898

9999

100-
The `~astroquery.mast.TesscutClass.download_cutouts` function takes a coordinate, cutout size
100+
The `~astroquery.mast.TesscutClass.download_cutouts` function takes a coordinate, cutout size
101101
(in pixels or an angular quantity), or object name (e.g. "M104" or "TIC 32449963") and moving target
102102
(True or False). It uses these parameters to download the cutout target pixel file(s).
103103

@@ -170,6 +170,7 @@ The following example requests SPOC cutouts for a moving target.
170170
tess-s0043-3-3 43 3 3
171171
tess-s0044-2-4 44 2 4
172172
tess-s0092-4-3 92 4 3
173+
tess-s0097-1-4 97 1 4
173174

174175

175176
Zcut
@@ -237,7 +238,7 @@ If a given coordinate appears in more than one Zcut survey, a cutout will be pro
237238
Downloading URL https://mast.stsci.edu/zcut/api/v0.1/astrocut?ra=189.49206&dec=62.20615&y=200&x=300&units=px&format=jpg to ./zcut_20201202132453.zip ... [Done]
238239
...
239240
>>> print(manifest)
240-
Local Path
241+
Local Path
241242
-------------------------------------------------------------------------------------------------------
242243
./hlsp_3dhst_spitzer_irac_goods-n_irac1_v4.0_sc_189.492060_62.206150_10.0pix-x-5.0pix_astrocut_0.jpg
243244
./hlsp_3dhst_spitzer_irac_goods-n-s2_irac3_v4.0_sc_189.492060_62.206150_10.0pix-x-5.0pix_astrocut_0.jpg

0 commit comments

Comments
 (0)