diff --git a/astroquery/esa/euclid/core.py b/astroquery/esa/euclid/core.py index d1ed43fb85..768d2288f6 100644 --- a/astroquery/esa/euclid/core.py +++ b/astroquery/esa/euclid/core.py @@ -11,13 +11,12 @@ import pprint import tarfile import zipfile -from collections.abc import Iterable -from datetime import datetime - from astropy import units from astropy import units as u from astropy.coordinates import Angle from astropy.units import Quantity +from collections.abc import Iterable +from datetime import datetime from requests.exceptions import HTTPError from astroquery import log @@ -408,7 +407,8 @@ def query_object(self, coordinate, *, radius=None, width=None, height=None, height_quantity = self.__get_quantity_input(height, "height") width_deg = width_quantity.to(units.deg) height_deg = height_quantity.to(units.deg) - query = ("SELECT DISTANCE(POINT('ICRS'," + self.main_table_ra + "," + self.main_table_dec + "), \ + query = ("SELECT " + (("TOP " + str(self.ROW_LIMIT)) if self.ROW_LIMIT > 0 else "") + + " DISTANCE(POINT('ICRS'," + self.main_table_ra + "," + self.main_table_dec + "), \ POINT('ICRS'," + str(ra) + "," + str(dec) + ")) AS dist, * \ FROM " + self.main_table + " WHERE CONTAINS(\ POINT('ICRS'," + self.main_table_ra + "," + self.main_table_dec + "),\ @@ -560,12 +560,10 @@ def cone_search(self, coordinate, radius, *, ra_column_name = self.main_table_ra dec_column_name = self.main_table_dec - """ if columns: columns = ','.join(map(str, columns)) else: columns = "*" - """ query = """ SELECT diff --git a/astroquery/esa/euclid/tests/test_euclid_remote.py b/astroquery/esa/euclid/tests/test_euclid_remote.py new file mode 100644 index 0000000000..6d5f3e61f9 --- /dev/null +++ b/astroquery/esa/euclid/tests/test_euclid_remote.py @@ -0,0 +1,78 @@ +import astropy.units as u +import pytest +from astropy.coordinates import SkyCoord + +from astroquery.esa.euclid import EuclidClass +from astroquery.utils.tap.model.filter import Filter + + +@pytest.mark.remote_data +def test_query_object_columns_with_radius(): + euclid = EuclidClass() + sc = SkyCoord(ra=0 * u.deg, dec=0 * u.deg) + table = euclid.query_object(sc, radius=10 * u.arcsec, columns=['right_ascension'], async_job=True) + assert table.colnames == ['right_ascension', 'dist'] + + +@pytest.mark.remote_data +@pytest.mark.filterwarnings("ignore::astropy.units.UnitsWarning") +def test_query_object_row_limit(): + euclid = EuclidClass() + coord = SkyCoord(ra=265.8, dec=64.1, unit=(u.degree, u.degree), frame='icrs') + width = u.Quantity(0.1, u.deg) + height = u.Quantity(0.1, u.deg) + r = euclid.query_object(coordinate=coord, width=width, height=height, async_job=True, verbose=True) + + assert len(r) == 50 + + euclid.ROW_LIMIT = 10 + r = euclid.query_object(coordinate=coord, width=width, height=height, async_job=True) + + assert len(r) == 10 == euclid.ROW_LIMIT + + euclid.ROW_LIMIT = -1 + r = euclid.query_object(coordinate=coord, width=width, height=height, async_job=True, verbose=True) + + assert len(r) == 1948 + + +@pytest.mark.remote_data +def test_cone_search_row_limit(): + euclid = EuclidClass() + coord = SkyCoord(ra=265.8, dec=64.1, unit=(u.degree, u.degree), frame='icrs') + radius = u.Quantity(0.1, u.deg) + j = euclid.cone_search(coord, radius=radius, async_job=True) + r = j.get_results() + + assert len(r) == euclid.ROW_LIMIT + + euclid.ROW_LIMIT = 10 + j = euclid.cone_search(coord, radius=radius, async_job=True) + r = j.get_results() + + assert len(r) == 10 == euclid.ROW_LIMIT + + euclid.ROW_LIMIT = -1 + j = euclid.cone_search(coord, radius=radius, async_job=True) + r = j.get_results() + + assert len(r) == 14606 + + +@pytest.mark.remote_data +def test_search_async_jobs(): + euclid = EuclidClass() + jobfilter = Filter() + jobfilter.limit = 10 + jobs = euclid.search_async_jobs(jobfilter=jobfilter, verbose=True) + assert len(jobs) == 10 + + +@pytest.mark.remote_data +def test_get_tables(): + euclid = EuclidClass() + r = euclid.load_tables() + assert len(r) > 1 + + table = euclid.load_table("catalogue.mer_catalogue") + assert len(table.columns) == 471 diff --git a/docs/esa/euclid/euclid.rst b/docs/esa/euclid/euclid.rst index 2f97c55cb3..43d6b7c3b5 100644 --- a/docs/esa/euclid/euclid.rst +++ b/docs/esa/euclid/euclid.rst @@ -4,6 +4,7 @@ ESA EUCLID Archive (`astroquery.esa.euclid`) ******************************************** + Euclid is an ESA mission to map the geometry of the dark Universe. The mission investigates the distance-redshift relationship and the evolution of cosmic structures. The space telescope creates a great map of the large-scale structure of the Universe across space and time by observing billions of galaxies out to 10 billion light-years, across @@ -80,7 +81,9 @@ Examples It is highly recommended checking the status of Euclid TAP before executing this module. To do this: -.. doctest-remote-data:: +.. almost all code examples require remote-data access, thus only using this + one at the first example +.. doctest-remote-data-all:: >>> from astroquery.esa.euclid import Euclid >>> Euclid.get_status_messages() @@ -122,14 +125,10 @@ The description of these data products can be found on the Data Product Definiti By default, the object *Euclid* -.. doctest-remote-data:: - >>> from astroquery.esa.euclid import Euclid makes use of the *PDR* environment. In order to make use of a different one, it is necessary to instantiate the class EuclidClass -.. doctest-remote-data:: - >>> from astroquery.esa.euclid import EuclidClass >>> euclid = EuclidClass(environment='IDR') @@ -146,8 +145,6 @@ Table and column metadata are specified by IVOA TAP_ recommendation (to access t To load only table names metadata (TAP+ capability): -.. doctest-remote-data:: - >>> from astroquery.esa.euclid import Euclid >>> tables = Euclid.load_tables(only_names=True, include_shared_tables=True) INFO: Retrieving tables... [astroquery.utils.tap.core] @@ -177,8 +174,6 @@ To load only table names metadata (TAP+ capability): To load all table metadata (TAP compatible): -.. doctest-remote-data:: - >>> from astroquery.esa.euclid import Euclid >>> tables = Euclid.load_tables() INFO: Retrieving tables... [astroquery.utils.tap.core] @@ -193,8 +188,6 @@ To load all table metadata (TAP compatible): To load only a table (TAP+ capability) and inspect its columns: -.. doctest-remote-data:: - >>> from astroquery.esa.euclid import Euclid >>> raw_detector_table = Euclid.load_table('sedm.raw_detector') >>> print(raw_detector_table) # doctest: +SKIP @@ -282,9 +275,6 @@ In the following example, for the Clusters of Galaxies category, and the group G This query performs a cone search centered at the specified ra/dec coordinates with the provided radius argument. -.. Skipping authentication requiring examples -.. doctest-skip:: - >>> #example cone search for source NGC6505 >>> from astroquery.esa.euclid import Euclid >>> from astropy.coordinates import SkyCoord @@ -296,33 +286,32 @@ This query performs a cone search centered at the specified ra/dec coordinates w >>> cone_results = job.get_results() >>> print("Found", len(cone_results), "results") Found 27 results - >>> cone_results['tile_index', 'creation_date', 'ra', 'dec', 'file_name', 'file_path', 'datalabs_path', 'filter_name', 'dist'][:5] + >>> cone_results['tile_index', 'creation_date', 'ra', 'dec', 'file_name', 'file_path', 'datalabs_path', 'filter_name', 'dist'][:5] # doctest: +IGNORE_OUTPUT - tile_index creation_date ra dec file_name file_path datalabs_path filter_name dist - int64 str23 float64 float64 str88 str55 str43 str11 float64 - ---------- ----------------------- ----------- ------- ------------------------------------------------------------------------------------- ------------------------------------------------------- ------------------------------------------- ----------- ------------------- - 102158889 2024-10-26T14:01:21.038 267.3807789 65.4983 EUC_MER_BGSUB-MOSAIC-CFIS-R_TILE102158889-4366B7_20241024T203624.450577Z_00.00.fits /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/MEGACAM /data/euclid_q1/Q1_R1/MER/102158889/MEGACAM MEGACAM_r 0.16895922479034217 - 102158889 2024-10-26T13:50:13.676 267.3807789 65.4983 EUC_MER_BGSUB-MOSAIC-WISHES-G_TILE102158889-3DC3C3_20241024T205647.635112Z_00.00.fits /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/HSC /data/euclid_q1/Q1_R1/MER/102158889/HSC HSC_g 0.16895922479034217 - 102158889 2024-10-26T13:37:09.628 267.3807789 65.4983 EUC_MER_BGSUB-MOSAIC-NIR-Y_TILE102158889-AC6585_20241024T225321.344048Z_00.00.fits /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/NISP /data/euclid_q1/Q1_R1/MER/102158889/NISP NIR_Y 0.16895922479034217 - 102158889 2024-10-26T14:05:09.98 267.3807789 65.4983 EUC_MER_BGSUB-MOSAIC-CFIS-U_TILE102158889-9E97F_20241024T204431.839748Z_00.00.fits /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/MEGACAM /data/euclid_q1/Q1_R1/MER/102158889/MEGACAM MEGACAM_u 0.16895922479034217 - 102158889 2024-10-26T13:10:32.453 267.3807789 65.4983 EUC_MER_BGSUB-MOSAIC-NIR-H_TILE102158889-ED035A_20241024T212936.705156Z_00.00.fits /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/NISP /data/euclid_q1/Q1_R1/MER/102158889/NISP NIR_H 0.16895922479034217 + tile_index creation_date ra dec ... file_path datalabs_path filter_name dist + int64 str23 float64 float64 ... str55 str43 str11 float64 + ---------- ----------------------- ----------- ------- ... ------------------------------------------------------- ------------------------------------------- ----------- ------------------- + 102158889 2024-10-26T14:01:21.038 267.3807789 65.4983 ... /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/MEGACAM /data/euclid_q1/Q1_R1/MER/102158889/MEGACAM MEGACAM_r 0.16895922479034217 + 102158889 2024-10-26T13:50:13.676 267.3807789 65.4983 ... /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/HSC /data/euclid_q1/Q1_R1/MER/102158889/HSC HSC_g 0.16895922479034217 + 102158889 2024-10-26T13:37:09.628 267.3807789 65.4983 ... /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/NISP /data/euclid_q1/Q1_R1/MER/102158889/NISP NIR_Y 0.16895922479034217 + 102158889 2024-10-26T14:05:09.98 267.3807789 65.4983 ... /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/MEGACAM /data/euclid_q1/Q1_R1/MER/102158889/MEGACAM MEGACAM_u 0.16895922479034217 + 102158889 2024-10-26T13:10:32.453 267.3807789 65.4983 ... /euclid/repository_idr/iqr1/Q1_R1/MER/102158889/NISP /data/euclid_q1/Q1_R1/MER/102158889/NISP NIR_H 0.16895922479034217 Queries return a limited number of rows controlled by ``Euclid.ROW_LIMIT``. To change the default behaviour set this appropriately. -.. Skipping authentication requiring examples -.. doctest-skip:: - >>> Euclid.ROW_LIMIT = 2 >>> job = Euclid.cone_search(coordinate=coord, radius=radius, table_name="sedm.mosaic_product", ra_column_name="ra", dec_column_name="dec", columns="*", async_job=True) + INFO: Query finished. [astroquery.utils.tap.core] >>> cone_results = job.get_results() - >>> print("Found", len(cone_results), "results") + >>> print(f"Found {len(cone_results)} results") Found 2 results - To return an unlimited number of rows set ``Euclid.ROW_LIMIT`` to -1. + >>> Euclid.ROW_LIMIT = -1 + 1.3. Query object ^^^^^^^^^^^^^^^^^ @@ -336,19 +325,15 @@ The following example searches for all the sources contained in an squared regio The method returns the job results as astropy.table - -.. Skipping authentication requiring examples -.. doctest-skip:: - >>> # Search for objects around a given position with the default catalog catalogue.mer_catalogue >>> from astroquery.esa.euclid import Euclid >>> from astropy.coordinates import SkyCoord >>> import astropy.units as u >>> coord = SkyCoord(ra=60.3372780005097, dec=-49.93184727724773, unit=(u.degree, u.degree), frame='icrs') - >>> table = Euclid.query_object(coordinate=coord, width=u.Quantity(0.1, u.deg), height= u.Quantity(0.1, u.deg)) + >>> table = Euclid.query_object(coordinate=coord, width=u.Quantity(0.1, u.deg), height= u.Quantity(0.1, u.deg)) # doctest: +IGNORE_WARNINGS >>> print("Found a total of", len(table), "query results") Found a total of 2000 query results - >>> print(table) + >>> print(table) # doctest: +IGNORE_OUTPUT dist avg_trans_wave_g_ext_decam avg_trans_wave_g_ext_hsc avg_trans_wave_g_ext_jpcam avg_trans_wave_g_ext_lsst avg_trans_wave_h avg_trans_wave_i_ext_decam ... sersic_fract_z_ext_panstarrs_disk_sersic sersic_fract_z_ext_panstarrs_disk_sersic_err she_flag spurious_flag spurious_prob variable_flag vis_det --------------------- -------------------------- ------------------------ -------------------------- ------------------------- ---------------- -------------------------- ... ---------------------------------------- -------------------------------------------- -------- ------------- ---------------------- ------------- ------- 3.566798805594703e-06 4826.7998046875 -- -- -- -- 7826.669921875 ... -- -- -- 0 0.15743961930274963 -- 1 @@ -371,20 +356,17 @@ Synchronous queries like this one return a limited number of rows -> 2000 The previous query can be executed as an asynchronous version: -.. Skipping authentication requiring examples -.. doctest-skip:: - >>> from astroquery.esa.euclid import Euclid >>> from astropy.coordinates import SkyCoord >>> import astropy.units as u >>> coord = SkyCoord(ra=60.3372780005097, dec=-49.93184727724773, unit=(u.degree, u.degree), frame='icrs') >>> width=u.Quantity(0.1, u.deg) >>> height= u.Quantity(0.1, u.deg) - >>> table_async = Euclid.query_object(coordinate=coord, width=width, height=height, async_job=True) + >>> table_async = Euclid.query_object(coordinate=coord, width=width, height=height, async_job=True) # doctest: +IGNORE_WARNINGS INFO: Query finished. [astroquery.utils.tap.core] - >>> print("Found a total of", len(table_async), "query results") + >>> print(f"Found a total of {len(table_async)} query results") Found a total of 2895 query results - >>> print(table_async) + >>> print(table_async) # doctest: +IGNORE_OUTPUT dist avg_trans_wave_g_ext_decam avg_trans_wave_g_ext_hsc avg_trans_wave_g_ext_jpcam avg_trans_wave_g_ext_lsst avg_trans_wave_h avg_trans_wave_i_ext_decam ... sersic_fract_z_ext_panstarrs_disk_sersic sersic_fract_z_ext_panstarrs_disk_sersic_err she_flag spurious_flag spurious_prob variable_flag vis_det --------------------- -------------------------- ------------------------ -------------------------- ------------------------- ---------------- -------------------------- ... ---------------------------------------- -------------------------------------------- -------- ------------- ---------------------- ------------- ------- 3.566798805594703e-06 4826.7998046875 -- -- -- -- 7826.669921875 ... -- -- -- 0 0.15743961930274963 -- 1 @@ -835,13 +817,24 @@ In the Euclid archive user tables can be shared among user groups. To obtain a list of the tables shared to a user type the following: -.. Skipping authentication requiring examples -.. doctest-skip:: - >>> from astroquery.esa.euclid import Euclid >>> tables = Euclid.load_tables(only_names=True, include_shared_tables=True) + INFO: Retrieving tables... [astroquery.utils.tap.core] + INFO: Parsing tables... [astroquery.utils.tap.core] + INFO: Done. [astroquery.utils.tap.core] >>> for table in tables: ... print(table.get_qualified_name()) + catalogue.mer_catalogue + catalogue.mer_cutouts + catalogue.mer_morphology + catalogue.phz_classification + catalogue.phz_galaxy_sed + ... + tap_schema.columns + tap_schema.key_columns + tap_schema.keys + tap_schema.schemas + tap_schema.tables .. _uploading_table_to_user_space: @@ -977,7 +970,7 @@ table named: user_.'t': >>> from astroquery.esa.euclid import Euclid >>> Euclid.login() - >>> job_1 = Euclid.launch_job_async("select top 10 * from Eucliddr3.Euclid_source") + >>> job_1 = Euclid.launch_job_async("select top 10 * from catalogue.mer_catalogue") >>> Euclid.upload_table_from_job(job=job_1) Created table 't1539932994481O' from job: '1539932994481O'.