diff --git a/CHANGES.rst b/CHANGES.rst index 178b9c2d49..67c54d0f85 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -201,6 +201,8 @@ mast - Added ``pass_id`` as an alias for the ``pass`` column in query functions for the Roman mission to avoid conflicts with the reserved Python keyword. [#3588] - Update the cutout format request parameter in ``Zcut.download_cutouts`` to reflect a recent service change. [#3608] +- Add a ``count_only`` parameter to ``MastMissions`` query methods to return only the number of matching results, + rather than the full result table. [#3645] jplspec diff --git a/astroquery/mast/missions.py b/astroquery/mast/missions.py index 94ae869a2e..af1652d2fd 100644 --- a/astroquery/mast/missions.py +++ b/astroquery/mast/missions.py @@ -138,6 +138,10 @@ def _parse_result(self, response, *, verbose=False): # Used by the async_to_syn if self.service == self._search: results = self._service_api_connection._parse_result(response, verbose, data_key='results') + # If returning a count_only response, return the count as an integer + if isinstance(results, int): + return results + # Add column descriptions to column metadata column_list = self.get_column_list() for col in results.columns: @@ -378,7 +382,7 @@ def _is_legacy_ra_dec_pair(items): @class_or_instance @deprecated_renamed_argument('objectname', 'object_names', since='0.4.12') def query_criteria_async(self, *, coordinates=None, object_names=None, radius=3*u.arcmin, - limit=5000, offset=0, select_cols=None, resolver=None, **criteria): + limit=5000, offset=0, select_cols=None, resolver=None, count_only=False, **criteria): """ Given a set of search criteria, returns a list of mission metadata. @@ -414,6 +418,8 @@ def query_criteria_async(self, *, coordinates=None, object_names=None, radius=3* "SIMBAD" and "NED". If not specified, the default resolver order will be used. Please see the `STScI Archive Name Translation Application (SANTA) `__ for more information. Default is None. + count_only : bool, optional + Default is False. If True, only the count of matching datasets will be returned. **criteria Criteria to apply. Valid criteria include coordinates, object_names, radius (as in `~astroquery.mast.missions.MastMissionsClass.query_region` and @@ -462,13 +468,16 @@ def query_criteria_async(self, *, coordinates=None, object_names=None, radius=3* params["radius"] = radius.arcsec params["radius_units"] = 'arcseconds' + if count_only: + params["count_only"] = True + self._build_params_from_criteria(params, **criteria) return self._service_api_connection.missions_request_async(self.service, params) @class_or_instance def query_region_async(self, coordinates, *, radius=3*u.arcmin, limit=5000, offset=0, - select_cols=None, **criteria): + select_cols=None, count_only=False, **criteria): """ Given a sky position (or positions) and radius, returns a list of matching dataset IDs. @@ -493,6 +502,8 @@ def query_region_async(self, coordinates, *, radius=3*u.arcmin, limit=5000, offs If None, a default set of columns will be returned. Can either be an iterable of column names, a comma-separated string of column names, or 'all'/'*' to return all available columns. + count_only : bool, optional + Default is False. If True, only the count of matching datasets will be returned. **criteria Other mission-specific criteria arguments. All valid filters can be found using `~astroquery.mast.missions.MastMissionsClass.get_column_list` @@ -516,12 +527,13 @@ def query_region_async(self, coordinates, *, radius=3*u.arcmin, limit=5000, offs limit=limit, offset=offset, select_cols=select_cols, + count_only=count_only, **criteria) @class_or_instance @deprecated_renamed_argument('objectname', 'object_names', since='0.4.12') def query_object_async(self, object_names, *, radius=3*u.arcmin, limit=5000, offset=0, - select_cols=None, resolver=None, **criteria): + select_cols=None, resolver=None, count_only=False, **criteria): """ Given an object name (or names), returns a list of matching rows. @@ -551,6 +563,8 @@ def query_object_async(self, object_names, *, radius=3*u.arcmin, limit=5000, off "SIMBAD" and "NED". If not specified, the default resolver order will be used. Please see the `STScI Archive Name Translation Application (SANTA) `__ for more information. Default is None. + count_only : bool, optional + Default is False. If True, only the count of matching datasets will be returned. **criteria Other mission-specific criteria arguments. All valid filters can be found using `~astroquery.mast.missions.MastMissionsClass.get_column_list` @@ -570,6 +584,7 @@ def query_object_async(self, object_names, *, radius=3*u.arcmin, limit=5000, off offset=offset, select_cols=select_cols, resolver=resolver, + count_only=count_only, **criteria) @class_or_instance diff --git a/astroquery/mast/services.py b/astroquery/mast/services.py index 697921ebf3..358040357d 100644 --- a/astroquery/mast/services.py +++ b/astroquery/mast/services.py @@ -262,8 +262,12 @@ def _parse_result(self, response, verbose=False, data_key='data'): ------- response : `~astropy.table.Table` """ - result = response.json() + + # Check for a count_only response and return the count if present + if "search_params" in result and result["search_params"]["count_only"]: + return result["totalResults"] + result_table = _json_to_table(result, data_key=data_key) # Check for no results diff --git a/astroquery/mast/tests/data/mission_count_only.json b/astroquery/mast/tests/data/mission_count_only.json new file mode 100644 index 0000000000..f30d191011 --- /dev/null +++ b/astroquery/mast/tests/data/mission_count_only.json @@ -0,0 +1,49 @@ +{ + "messages": [], + "search_params": { + "target": [], + "radius": 3.0, + "radius_units": "arcminutes", + "offset": 0, + "limit": 5000, + "sort_by": [ + "sci_targname", + "sci_data_set_name" + ], + "sort_desc": [ + false, + false + ], + "skip_count": false, + "count_only": true, + "select_cols": [ + "sci_data_set_name", + "sci_targname", + "sci_hapnum", + "sci_haspnum", + "sci_hslanum", + "sci_instrume", + "sci_aper_1234", + "sci_spec_1234", + "sci_actual_duration", + "sci_start_time", + "sci_pep_id", + "sci_pi_last_name", + "sci_ra", + "sci_dec", + "sci_refnum", + "sci_central_wavelength", + "sci_release_date", + "sci_stop_time", + "sci_preview_name", + "scp_scan_type", + "sci_hlsp" + ], + "search_key": [], + "user_fields": [], + "conditions": [] + }, + "totalResults": 1066009, + "info": [], + "results": [] +} \ No newline at end of file diff --git a/astroquery/mast/tests/data/mission_results.json b/astroquery/mast/tests/data/mission_results.json index a1f62fe682..8af13e3b93 100644 --- a/astroquery/mast/tests/data/mission_results.json +++ b/astroquery/mast/tests/data/mission_results.json @@ -1,83 +1,5 @@ { "messages": [], - "info": [ - { - "name": "sci_release_date", - "type": "DATETIME" - }, - { - "name": "sci_actual_duration", - "type": "FLOAT" - }, - { - "name": "sci_dec", - "type": "FLOAT" - }, - { - "name": "sci_pep_id", - "type": "INTEGER" - }, - { - "name": "sci_spec_1234", - "type": "VARCHAR" - }, - { - "name": "sci_aper_1234", - "type": "VARCHAR" - }, - { - "name": "sci_data_set_name", - "type": "VARCHAR" - }, - { - "name": "sci_preview_name", - "type": "VARCHAR" - }, - { - "name": "sci_targname", - "type": "VARCHAR" - }, - { - "name": "sci_instrume", - "type": "VARCHAR" - }, - { - "name": "search_key", - "type": "VARCHAR" - }, - { - "name": "sci_central_wavelength", - "type": "FLOAT" - }, - { - "name": "sci_status", - "type": "VARCHAR" - }, - { - "name": "sci_stop_time", - "type": "DATETIME" - }, - { - "name": "scp_scan_type", - "type": "VARCHAR" - }, - { - "name": "sci_hlsp", - "type": "INTEGER" - }, - { - "name": "sci_refnum", - "type": "INTEGER" - }, - { - "name": "sci_start_time", - "type": "DATETIME" - }, - { - "name": "sci_ra", - "type": "FLOAT" - } -], "search_params": { "target": [ "40.66963 -0.01328" @@ -85,7 +7,7 @@ "radius": 3, "radius_units": "arcminutes", "offset": 0, - "limit": 5000, + "limit": 10, "sort_by": [ "ang_sep", "sci_targname", @@ -97,32 +19,34 @@ false ], "skip_count": false, + "count_only": false, "select_cols": [ "sci_data_set_name", "sci_targname", - "sci_ra", - "sci_dec", - "sci_refnum", - "sci_start_time", - "sci_stop_time", - "sci_actual_duration", + "sci_hapnum", + "sci_haspnum", + "sci_hslanum", "sci_instrume", "sci_aper_1234", "sci_spec_1234", - "sci_central_wavelength", + "sci_actual_duration", + "sci_start_time", "sci_pep_id", + "sci_pi_last_name", + "sci_ra", + "sci_dec", + "sci_refnum", + "sci_central_wavelength", "sci_release_date", + "sci_stop_time", "sci_preview_name", "scp_scan_type", "sci_hlsp", - "sci_status" + "ang_sep" ], "search_key": [], "user_fields": [], "conditions": [ - { - "sci_obs_type": "" - }, { "sci_aec": "S" }, @@ -131,76 +55,374 @@ } ] }, - "totalResults": 3, + "totalResults": 193, + "info": [ + { + "name": "search_pos", + "type": "VARCHAR(255)", + "sortable": true + }, + { + "name": "sci_data_set_name", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_targname", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_hapnum", + "type": "INTEGER", + "sortable": true + }, + { + "name": "sci_haspnum", + "type": "INTEGER", + "sortable": true + }, + { + "name": "sci_hslanum", + "type": "INTEGER", + "sortable": true + }, + { + "name": "sci_instrume", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_aper_1234", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_spec_1234", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_actual_duration", + "type": "FLOAT", + "sortable": true + }, + { + "name": "sci_start_time", + "type": "DATETIME", + "sortable": true + }, + { + "name": "sci_pep_id", + "type": "INTEGER", + "sortable": true + }, + { + "name": "sci_pi_last_name", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_ra", + "type": "FLOAT", + "sortable": true + }, + { + "name": "sci_dec", + "type": "FLOAT", + "sortable": true + }, + { + "name": "sci_refnum", + "type": "INTEGER", + "sortable": true + }, + { + "name": "sci_central_wavelength", + "type": "FLOAT", + "sortable": true + }, + { + "name": "sci_release_date", + "type": "DATETIME", + "sortable": true + }, + { + "name": "sci_stop_time", + "type": "DATETIME", + "sortable": true + }, + { + "name": "sci_preview_name", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "scp_scan_type", + "type": "VARCHAR", + "sortable": true + }, + { + "name": "sci_hlsp", + "type": "INTEGER", + "sortable": true + }, + { + "name": "ang_sep", + "type": "NULL", + "sortable": true + } + ], "results": [ { - "sci_data_set_name": "W1DG8D06T", - "sci_targname": "HI-LAT", - "sci_ra": 40.68202694444444, - "sci_dec": -0.03533861111111111, - "sci_refnum": 18, - "sci_start_time": "1993-09-24T21:00:16.633000", - "sci_stop_time": "1993-09-24T21:35:16.633000", - "sci_actual_duration": 2100, - "sci_instrume": "WFPC ", - "sci_aper_1234": "ALL", - "sci_spec_1234": "F785LP", - "sci_central_wavelength": 8958, - "sci_pep_id": 4381, - "sci_release_date": "1994-09-24T23:03:09", - "sci_preview_name": "W1DG8D06T", + "sci_data_set_name": "X2JM010BT", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "256X1024-SLIT", + "sci_spec_1234": "CLEAR1;F130LP", + "sci_actual_duration": 627.625, + "sci_start_time": "1994-10-31T12:38:22.300000", + "sci_pep_id": 5763, + "sci_pi_last_name": "NOTA", + "sci_ra": 40.6696110934285, + "sci_dec": -0.0132734328786483, + "sci_refnum": 0, + "sci_central_wavelength": 3400, + "sci_release_date": "1994-11-16T23:02:06", + "sci_stop_time": "1994-10-31T12:48:49.923000", + "sci_preview_name": "X2JM010BT", + "scp_scan_type": "D ", + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.000020014632389090548 + }, + { + "sci_data_set_name": "Y0MW0803T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOS ", + "sci_aper_1234": "0.5", + "sci_spec_1234": "G270H", + "sci_actual_duration": 80, + "sci_start_time": "1991-06-25T19:14:31.147000", + "sci_pep_id": 1036, + "sci_pi_last_name": "FORD", + "sci_ra": 40.66962014399, + "sci_dec": -0.01331737850565, + "sci_refnum": 19, + "sci_central_wavelength": 2650, + "sci_release_date": "1992-06-25T00:02:53", + "sci_stop_time": "1991-06-25T19:25:42.777000", + "sci_preview_name": null, + "scp_scan_type": "D ", + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.00003865609411740929 + }, + { + "sci_data_set_name": "X2JM010CT", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "256X1024-SLIT", + "sci_spec_1234": "CLEAR1;F130LP", + "sci_actual_duration": 627.625, + "sci_start_time": "1994-10-31T12:53:24.300000", + "sci_pep_id": 5763, + "sci_pi_last_name": "NOTA", + "sci_ra": 40.6696805201903, + "sci_dec": -0.0132718657572788, + "sci_refnum": 0, + "sci_central_wavelength": 3400, + "sci_release_date": "1994-11-16T23:04:58", + "sci_stop_time": "1994-10-31T13:03:51.927000", + "sci_preview_name": "X2JM010CT", + "scp_scan_type": "D ", + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.00005117084517889686 + }, + { + "sci_data_set_name": "X24E0101R", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X1024", + "sci_spec_1234": "CLEAR1;F501N;CLEAR3;CLEAR4", + "sci_actual_duration": 296, + "sci_start_time": "1994-01-10T02:16:49.773000", + "sci_pep_id": 5578, + "sci_pi_last_name": "SPARKS", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 13, + "sci_central_wavelength": 5010, + "sci_release_date": "1995-01-10T02:41:48", + "sci_stop_time": "1994-01-10T02:21:45.773000", + "sci_preview_name": "X24E0101R", "scp_scan_type": null, "sci_hlsp": null, - "sci_status": "PUBLIC", - "search_key": "40.66963 -0.01328W1DG8D06T", "search_pos": "40.66963 -0.01328", - "ang_sep": 1.5182093051117103 - }, - { - "sci_data_set_name": "W1DG9S01T", - "sci_targname": "HI-LAT", - "sci_ra": 40.68202694444444, - "sci_dec": -0.03533861111111111, - "sci_refnum": 18, - "sci_start_time": "1993-09-24T22:57:16.633000", - "sci_stop_time": "1993-09-24T23:17:16.633000", - "sci_actual_duration": 1200, - "sci_instrume": "WFPC ", - "sci_aper_1234": "ALL", - "sci_spec_1234": "F785LP", - "sci_central_wavelength": 8958, - "sci_pep_id": 4381, - "sci_release_date": "1994-09-24T23:51:35", - "sci_preview_name": "W1DG9S01T", + "ang_sep": 0.000057342956865123236 + }, + { + "sci_data_set_name": "X24E0102T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X512", + "sci_spec_1234": "CLEAR1;F501N;CLEAR3;CLEAR4", + "sci_actual_duration": 1196, + "sci_start_time": "1994-01-10T03:53:43.773000", + "sci_pep_id": 5578, + "sci_pi_last_name": "SPARKS", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 13, + "sci_central_wavelength": 5010, + "sci_release_date": "1995-01-10T23:53:07", + "sci_stop_time": "1994-01-10T04:13:39.773000", + "sci_preview_name": "X24E0102T", "scp_scan_type": null, "sci_hlsp": null, - "sci_status": "PUBLIC", - "search_key": "40.66963 -0.01328W1DG9S01T", "search_pos": "40.66963 -0.01328", - "ang_sep": 1.5182093051117103 - }, - { - "sci_data_set_name": "J8DM01ELQ", - "sci_targname": "NGC1068-OFF", - "sci_ra": 40.71020833333, - "sci_dec": -0.02798888888889, - "sci_refnum": 8, - "sci_start_time": "2003-01-08T19:00:35.987000", - "sci_stop_time": "2003-01-08T19:00:37.833000", - "sci_actual_duration": 0.7955, - "sci_instrume": "ACS ", - "sci_aper_1234": "WFC2-FIX", - "sci_spec_1234": "F550M;CLEAR2L", - "sci_central_wavelength": 5581.3379, - "sci_pep_id": 9503, - "sci_release_date": "2003-07-11T06:24:30", - "sci_preview_name": "J8DM01ELQ", + "ang_sep": 0.000057342956865123236 + }, + { + "sci_data_set_name": "X24E0103T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X512", + "sci_spec_1234": "F4ND;F501N;CLEAR3;CLEAR4", + "sci_actual_duration": 1196, + "sci_start_time": "1994-01-10T05:22:37.773000", + "sci_pep_id": 5578, + "sci_pi_last_name": "SPARKS", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 13, + "sci_central_wavelength": 5010, + "sci_release_date": "1995-01-11T00:02:34", + "sci_stop_time": "1994-01-10T05:42:33.773000", + "sci_preview_name": "X24E0103T", + "scp_scan_type": null, + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.000057342956865123236 + }, + { + "sci_data_set_name": "X24E0104T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X512", + "sci_spec_1234": "CLEAR1;CLEAR2;CLEAR3;F372M", + "sci_actual_duration": 1196, + "sci_start_time": "1994-01-10T07:00:02.773000", + "sci_pep_id": 5578, + "sci_pi_last_name": "SPARKS", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 13, + "sci_central_wavelength": 3700, + "sci_release_date": "1995-01-11T00:13:19", + "sci_stop_time": "1994-01-10T07:19:58.773000", + "sci_preview_name": "X24E0104T", + "scp_scan_type": null, + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.000057342956865123236 + }, + { + "sci_data_set_name": "X24E0105T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X512", + "sci_spec_1234": "F4ND;CLEAR2;CLEAR3;F372M", + "sci_actual_duration": 1196, + "sci_start_time": "1994-01-10T08:35:41.773000", + "sci_pep_id": 5578, + "sci_pi_last_name": "SPARKS", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 13, + "sci_central_wavelength": 3700, + "sci_release_date": "1995-01-11T00:24:29", + "sci_stop_time": "1994-01-10T08:55:37.773000", + "sci_preview_name": "X24E0105T", + "scp_scan_type": null, + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.000057342956865123236 + }, + { + "sci_data_set_name": "X24E0106T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X512", + "sci_spec_1234": "CLEAR1;CLEAR2;CLEAR3;F253M", + "sci_actual_duration": 1196, + "sci_start_time": "1994-01-10T10:12:41.773000", + "sci_pep_id": 5578, + "sci_pi_last_name": "SPARKS", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 13, + "sci_central_wavelength": 2550, + "sci_release_date": "1995-01-11T00:36:41", + "sci_stop_time": "1994-01-10T10:32:37.773000", + "sci_preview_name": "X24E0106T", + "scp_scan_type": null, + "sci_hlsp": null, + "search_pos": "40.66963 -0.01328", + "ang_sep": 0.000057342956865123236 + }, + { + "sci_data_set_name": "X2740201T", + "sci_targname": "NGC1068", + "sci_hapnum": 0, + "sci_haspnum": 0, + "sci_hslanum": 0, + "sci_instrume": "FOC ", + "sci_aper_1234": "512X512", + "sci_spec_1234": "CLEAR1;F501N;CLEAR3;CLEAR4", + "sci_actual_duration": 1995.625, + "sci_start_time": "1995-02-27T21:39:06.303000", + "sci_pep_id": 5144, + "sci_pi_last_name": "MACCHETTO", + "sci_ra": 40.66957270132, + "sci_dec": -0.01327774696891, + "sci_refnum": 16, + "sci_central_wavelength": 5010, + "sci_release_date": "1996-02-28T01:47:21", + "sci_stop_time": "1995-02-27T22:12:21.927000", + "sci_preview_name": "X2740201T", "scp_scan_type": null, "sci_hlsp": null, - "sci_status": "PUBLIC", - "search_key": "40.66963 -0.01328J8DM01ELQ", "search_pos": "40.66963 -0.01328", - "ang_sep": 2.589715886363766 + "ang_sep": 0.000057342956865123236 } ] -} +} \ No newline at end of file diff --git a/astroquery/mast/tests/test_mast.py b/astroquery/mast/tests/test_mast.py index ad817949d3..6e277ddbeb 100644 --- a/astroquery/mast/tests/test_mast.py +++ b/astroquery/mast/tests/test_mast.py @@ -33,6 +33,7 @@ DATA_FILES = {'Mast.Caom.Cone': 'caom.json', 'Mast.Name.Lookup': 'resolver.json', 'mission_search_results': 'mission_results.json', + 'mission_count_only': 'mission_count_only.json', 'mission_columns': 'mission_columns.json', 'mission_products': 'mission_products.json', 'columnsconfig': 'columnsconfig.json', @@ -163,6 +164,8 @@ def service_mockreturn(self, method="POST", url=None, data=None, params=None, ti filename = data_path(DATA_FILES['mission_products']) elif use_json and data['radius'] == 300: filename = data_path(DATA_FILES["mission_incorrect_results"]) + elif use_json and 'count_only' in data and data['count_only']: + filename = data_path(DATA_FILES["mission_count_only"]) elif use_json: filename = data_path(DATA_FILES["mission_search_results"]) with open(filename, 'rb') as infile: @@ -314,6 +317,11 @@ def test_missions_query_criteria(): assert 'description' in result['sci_pep_id'].meta assert 'description' in result['sci_instrume'].meta + # Count only query + count_result = MastMissions.query_criteria(coordinates=regionCoords, count_only=True) + assert isinstance(count_result, int) + assert count_result == 1066009 + # Raise error if invalid criteria is supplied with pytest.raises(InvalidQueryError): MastMissions.query_criteria( diff --git a/astroquery/mast/tests/test_mast_remote.py b/astroquery/mast/tests/test_mast_remote.py index a3c1d0405c..35a666ff8c 100644 --- a/astroquery/mast/tests/test_mast_remote.py +++ b/astroquery/mast/tests/test_mast_remote.py @@ -186,6 +186,11 @@ def test_missions_query_criteria(self): radius=0.1) assert len(set(result['search_pos'])) == 4 # Should have four different search positions + # Count only query + count_result = MastMissions.query_criteria(coordinates=coord, radius=0.1, count_only=True) + assert isinstance(count_result, int) + assert count_result > 0 + # Raise error if invalid input is given with pytest.raises(InvalidQueryError): MastMissions.query_criteria(coordinates="245.89675 -26.52575", diff --git a/docs/mast/mast_missions.rst b/docs/mast/mast_missions.rst index f7e13f3d87..f43718b4d5 100644 --- a/docs/mast/mast_missions.rst +++ b/docs/mast/mast_missions.rst @@ -3,7 +3,7 @@ Mission-Specific Queries ************************ -The `~astroquery.mast.MastMissionsClass` class allows for search queries based on mission-specific +The `~astroquery.mast.MastMissionsClass` class allows for search queries based on mission-specific metadata for a given data collection. This metadata includes header keywords, proposal information, and observational parameters. The following missions/products are currently available for search: @@ -49,12 +49,12 @@ To search for JWST metadata, the ``mission`` attribute is reassigned to ``'JWST' Querying Missions ================== -The MastMissions interface provides three closely related query methods. All three methods return results as an `~astropy.table.Table` -and all three support column-based filtering, sorting, and result limiting. The primary difference between them is how positional +The MastMissions interface provides three closely related query methods. All three methods return results as an `~astropy.table.Table` +and all three support column-based filtering, sorting, and result limiting. The primary difference between them is how positional constraints are specified. At a high level: - - `~astroquery.mast.MastMissionsClass.query_criteria` is the most flexible method. It supports purely column-based queries, + - `~astroquery.mast.MastMissionsClass.query_criteria` is the most flexible method. It supports purely column-based queries, purely positional queries, or a combination of both. - `~astroquery.mast.MastMissionsClass.query_region` is a convenience wrapper for positional queries using coordinates. @@ -78,7 +78,7 @@ using the `~astroquery.mast.MastMissionsClass.get_column_list` method. Keyword arguments can also be used to refine results further. The following parameters are available: -- ``radius``: For positional searches only. Only return results within a certain distance from an object or set of coordinates. +- ``radius``: For positional searches only. Only return results within a certain distance from an object or set of coordinates. Default is 3 arcminutes. - ``limit``: The maximum number of results to return. Default is 5000. @@ -95,21 +95,24 @@ Keyword arguments can also be used to refine results further. The following para is returned. This parameter may be given as an iterable of column names, a comma-separated string, or the special values ``'all'`` or ``'*'`` to return all available columns. +- ``count_only``: If ``True``, return only the number of results that match the query criteria. Default is ``False``. This is + useful for quickly determining how many results would be returned without retrieving the full dataset. + Writing Queries ---------------- The `~astroquery.mast.MastMissionsClass.query_criteria` method supports both positional parameters and column-based filters. -Positional constraints are optional. +Positional constraints are optional. Supported positional parameters include: - ``coordinates`` : Sky coordinates around which to perform a cone search. - ``object_name`` : Name(s) of the object(s) around which to perform a cone search. - ``resolver`` : Resolver service to use for object name resolution. - - ``radius`` : Radius of the cone searches around the specified coordinates or object names. Can be defined as an `~astropy.units.Quantity`, + - ``radius`` : Radius of the cone searches around the specified coordinates or object names. Can be defined as an `~astropy.units.Quantity`, a string with units (e.g., ``"10 arcsec"``), or a numeric value interpreted as degrees. -Multiple coordinates or objects may be queried in a single request. The ``coordinates`` and ``object_names`` parameters +Multiple coordinates or objects may be queried in a single request. The ``coordinates`` and ``object_names`` parameters accept a single value, an iterable of values, or a comma-separated string. When multiple values are provided for either parameter, results matching *any* of the supplied positions are returned. @@ -117,7 +120,7 @@ results matching *any* of the supplied positions are returned. >>> from astropy.coordinates import SkyCoord >>> select_cols = ["sci_targname", "sci_pep_id", "sci_status"] - >>> results = missions.query_criteria(coordinates=[SkyCoord(245.89675, -26.52575, unit='deg'), "205.54842 28.37728"], + >>> results = missions.query_criteria(coordinates=[SkyCoord(245.89675, -26.52575, unit='deg'), "205.54842 28.37728"], ... object_names=["M2", "M9"], ... radius=0.1, ... select_cols=select_cols, @@ -168,13 +171,13 @@ Criteria syntax supports several operations: - For numeric or date columns, select an inclusive range with the syntax ``'#..#'``. -- Wildcards are special characters used in search patterns to represent one or more unknown characters, +- Wildcards are special characters used in search patterns to represent one or more unknown characters, allowing for flexible matching of strings. The wildcard character is ``*`` and it replaces any number of characters preceding, following, or in between existing characters, depending on its placement. .. note:: - For the Roman mission, query methods also support the ``pass_id`` parameter as an alias for the ``pass`` column, + For the Roman mission, query methods also support the ``pass_id`` parameter as an alias for the ``pass`` column, which refers to a single iteration of a pass plan. This is to avoid conflicts with the reserved Python keyword. .. doctest-remote-data:: @@ -196,7 +199,7 @@ Criteria syntax supports several operations: N4A702010 GAL-CLUS-0026+1653-ARCC F110W IMAGE N4A705010 GAL-CLUS-0026+1653-ARCC F110W IMAGE -The `~astroquery.mast.MastMissionsClass.query_region` and `~astroquery.mast.MastMissionsClass.query_object` methods are +The `~astroquery.mast.MastMissionsClass.query_region` and `~astroquery.mast.MastMissionsClass.query_object` methods are convenience wrappers around `~astroquery.mast.MastMissionsClass.query_criteria`: - `~astroquery.mast.MastMissionsClass.query_region` requires ``coordinates``. @@ -209,7 +212,7 @@ Both methods also accept column-based criteria, which are applied in the same wa >>> regionCoords = SkyCoord(210.80227, 54.34895, unit=('deg', 'deg')) >>> select_cols = ["sci_stop_time", "sci_targname", "sci_start_time", "sci_status"] - >>> results = missions.query_region(regionCoords, + >>> results = missions.query_region(regionCoords, ... radius=3, ... sci_pep_id=12556, ... select_cols=select_cols, @@ -226,8 +229,8 @@ Both methods also accept column-based criteria, which are applied in the same wa .. doctest-remote-data:: - >>> results = missions.query_object('M101', - ... radius=3, + >>> results = missions.query_object('M101', + ... radius=3, ... select_cols=select_cols, ... sort_by='sci_targname') >>> results[:5] # doctest: +IGNORE_OUTPUT @@ -248,11 +251,11 @@ Getting Product Lists ---------------------- Each observation returned from a MAST query can have one or more associated data products. Given -one or more datasets or dataset IDs, the `~astroquery.mast.MastMissionsClass.get_product_list` function +one or more datasets or dataset IDs, the `~astroquery.mast.MastMissionsClass.get_product_list` function will return a `~astropy.table.Table` containing the associated data products. -`~astroquery.mast.MastMissionsClass.get_product_list` also includes an optional ``batch_size`` parameter, -which controls how many datasets are sent to the MAST service per request. This can be useful for managing +`~astroquery.mast.MastMissionsClass.get_product_list` also includes an optional ``batch_size`` parameter, +which controls how many datasets are sent to the MAST service per request. This can be useful for managing memory usage or avoiding timeouts when requesting product lists for large numbers of datasets. If not provided, batch_size defaults to 1000. @@ -262,7 +265,7 @@ If not provided, batch_size defaults to 1000. ... sci_hlsp='>1') >>> products = missions.get_product_list(datasets[:2], batch_size=1000) >>> print(products[:5]) # doctest: +IGNORE_OUTPUT - product_key access dataset ... category size type + product_key access dataset ... category size type ---------------------------- ------ --------- ... ---------- --------- ------- JBTAA0010_jbtaa0010_asn.fits PUBLIC JBTAA0010 ... AUX 11520 science JBTAA0010_jbtaa0010_drz.fits PUBLIC JBTAA0010 ... CALIBRATED 214655040 science @@ -298,8 +301,8 @@ and any other of the product fields. The **AND** operation is applied between filters, and the **OR** operation is applied within each filter set, except in the case of negated values. A filter value can be negated by prefiing it with ``!``, meaning that rows matching that value will be excluded from the results. -When any negated value is present in a filter set, any positive values in that set are combined with **OR** logic, and the negated -values are combined with **AND** logic against the positives. +When any negated value is present in a filter set, any positive values in that set are combined with **OR** logic, and the negated +values are combined with **AND** logic against the positives. For example: - ``file_suffix=['A', 'B', '!C']`` → (file_suffix != C) AND (file_suffix == A OR file_suffix == B) @@ -318,10 +321,10 @@ The filter below returns FITS products that are "science" type **and** less than >>> filtered = missions.filter_products(products, ... extension='fits', ... type='science', - ... size='<=20000', + ... size='<=20000', ... file_suffix=['ASN', 'JIF']) >>> print(filtered) # doctest: +IGNORE_OUTPUT - product_key access dataset ... category size type + product_key access dataset ... category size type ---------------------------- ------ --------- ... -------------- ----- ------- JBTAA0010_jbtaa0010_asn.fits PUBLIC JBTAA0010 ... AUX 11520 science JBTAA0020_jbtaa0020_asn.fits PUBLIC JBTAA0020 ... AUX 11520 science @@ -333,13 +336,13 @@ Downloding Data Downloading Data Products ------------------------- -The `~astroquery.mast.MastMissionsClass.download_products` function accepts a table of products like the one above -and will download the products to your local machine. Products may also be provided as dataset IDs with product filters, +The `~astroquery.mast.MastMissionsClass.download_products` function accepts a table of products like the one above +and will download the products to your local machine. Products may also be provided as dataset IDs with product filters, or as JSON product metadata sent by the MAST subscription service (either as a local JSON file or as in-memory data). By default, products will be downloaded into the current working directory, in a subdirectory called ``mastDownload``. -The full local filepaths will have the form ``mastDownload///file.`` You can change the download -directory using the ``download_dir`` parameter. If ``flat=True`` is specified, all files will be downloaded directly into the +The full local filepaths will have the form ``mastDownload///file.`` You can change the download +directory using the ``download_dir`` parameter. If ``flat=True`` is specified, all files will be downloaded directly into the ``download_dir`` without any subdirectories. .. doctest-remote-data:: @@ -349,14 +352,14 @@ directory using the ``download_dir`` parameter. If ``flat=True`` is specified, a Downloading URL https://mast.stsci.edu/search/hst/api/v0.1/retrieve_product?product_name=JBTAA0020%2Fjbtaa0020_asn.fits to mastDownload/hst/JBTAA0020/jbtaa0020_asn.fits ... [Done] Downloading URL https://mast.stsci.edu/search/hst/api/v0.1/retrieve_product?product_name=JBTAA0020%2Fjbtaa0020_jif.fits to mastDownload/hst/JBTAA0020/jbtaa0020_jif.fits ... [Done] >>> print(manifest) # doctest: +IGNORE_OUTPUT - Local Path Status Message URL + Local Path Status Message URL --------------------------------------------- -------- ------- ---- mastDownload/hst/JBTAA0010/jbtaa0010_asn.fits COMPLETE None None mastDownload/hst/JBTAA0010/jbtaa0010_jif.fits COMPLETE None None mastDownload/hst/JBTAA0020/jbtaa0020_asn.fits COMPLETE None None mastDownload/hst/JBTAA0020/jbtaa0020_jif.fits COMPLETE None None -The function also accepts dataset IDs and product filters as input for a more streamlined workflow. +The function also accepts dataset IDs and product filters as input for a more streamlined workflow. .. doctest-remote-data:: >>> missions.download_products(['JBTAA0010', 'JBTAA0020'], @@ -374,7 +377,7 @@ Downloading a Single File To download a single data product file, use the `~astroquery.mast.MastMissionsClass.download_file` function with a MAST URI as input. Some missions (e.g., HST, JWST) accept direct filenames as input, but others require a fully-qualified ``mast:`` URI. -The default is to download the file to the current working directory, but you can specify the download directory or filepath with +The default is to download the file to the current working directory, but you can specify the download directory or filepath with the ``local_path`` keyword argument. .. doctest-remote-data::