Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ esa.euclid
``datalabs_path``, ``file_name`` and ``hdu_index``. [#3438]
- The default value of the parameter ``output_format`` in the the methods ``launch_job``, ``launch_job_async`` and
``cone_search`` is changed to "votable_gzip". [#3497]


- Methods ``cone_search`` and ``cross_match_basic`` now define the parameters ``table_name`` and ``ra_column_name`` and
``dec_column_name`` independently [#3496]
- The method ``get_spectrum`` accepts the new parameter ``linking_parameter`` to retrieve the spectra by source_id and
sourcepatch_id [#3543]

vizier
^^^^^^
Expand Down
2 changes: 2 additions & 0 deletions astroquery/esa/euclid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ class Conf(_config.ConfigNamespace):

VALID_DATALINK_RETRIEVAL_TYPES = ['SPECTRA_BGS', 'SPECTRA_RGS']

VALID_LINKING_PARAMETERS = {'SOURCE_ID', 'SOURCEPATCH_ID'}


conf = Conf()

Expand Down
52 changes: 39 additions & 13 deletions astroquery/esa/euclid/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from astropy import units as u
from astropy.coordinates import Angle
from astropy.units import Quantity
from astropy.utils import deprecated_renamed_argument
from requests.exceptions import HTTPError

from astroquery import log
Expand All @@ -34,6 +35,7 @@ class EuclidClass(TapPlus):
__ERROR_MSG_REQUESTED_PRODUCT_TYPE = "Missing required argument: 'product_type'"
__ERROR_MSG_REQUESTED_GENERIC = "Missing required argument"
__ERROR_MSG_REQUESTED_RADIUS = "Radius cannot be greater than 30 arcminutes"

EUCLID_MESSAGES = "notification?action=GetNotifications"

"""
Expand All @@ -42,6 +44,7 @@ class EuclidClass(TapPlus):
ROW_LIMIT = conf.ROW_LIMIT

__VALID_DATALINK_RETRIEVAL_TYPES = conf.VALID_DATALINK_RETRIEVAL_TYPES
__VALID_LINKING_PARAMETERS = conf.VALID_LINKING_PARAMETERS

def __init__(self, *, environment='PDR', tap_plus_conn_handler=None, datalink_handler=None, cutout_handler=None,
verbose=False, show_server_messages=True):
Expand Down Expand Up @@ -1450,7 +1453,9 @@ def get_cutout(self, *, file_path=None, instrument=None, id=None, coordinate, ra

return files

def get_spectrum(self, *, source_id, schema='sedm', retrieval_type="ALL", output_file=None, verbose=False):
@deprecated_renamed_argument('source_id', 'ids', since='0.4.12')
def get_spectrum(self, *, ids, schema='sedm', retrieval_type="ALL", linking_parameter='SOURCE_ID',
output_file=None, verbose=False):
"""
Downloads a spectrum with datalink.

Expand All @@ -1462,13 +1467,17 @@ def get_spectrum(self, *, source_id, schema='sedm', retrieval_type="ALL", output

Parameters
----------
source_id : str, mandatory, default None
source id for the spectrum
ids : str or int, mandatory
identifier for the spectrum
schema : str, mandatory, default 'sedm'
the data release
retrieval_type : str, optional, default 'ALL' to retrieve all data from the list of sources
retrieval type identifier. Possible values are: 'SPECTRA_BGS' for the blue spectrum and 'SPECTRA_RGS' for
the red one.
linking_parameter : str, optional, default SOURCE_ID, valid values: SOURCE_ID or SOURCEPATCH_ID
By default, all the identifiers are considered as source_id
SOURCE_ID: the identifiers are considered as source_id
SOURCEPATCH_ID: the identifiers are considered as sourcepatch_id
output_file : str, optional
output file name. If no value is provided, a temporary one is created with the name
"<working directory>/temp_<%Y%m%d_%H%M%S>/<source_id>.fits"
Expand All @@ -1483,7 +1492,7 @@ def get_spectrum(self, *, source_id, schema='sedm', retrieval_type="ALL", output

"""

if source_id is None or schema is None:
if ids is None or schema is None:
raise ValueError(self.__ERROR_MSG_REQUESTED_GENERIC)

rt = str(retrieval_type).upper()
Expand All @@ -1493,14 +1502,22 @@ def get_spectrum(self, *, source_id, schema='sedm', retrieval_type="ALL", output

params_dict = {}

id_value = """{schema} {source_id}""".format(**{'schema': schema, 'source_id': source_id})
id_value = """{schema} {source_id}""".format(**{'schema': schema, 'source_id': ids})
params_dict['ID'] = id_value
params_dict['SCHEMA'] = schema
params_dict['RETRIEVAL_TYPE'] = str(retrieval_type)
params_dict['USE_ZIP_ALWAYS'] = 'true'
params_dict['TAPCLIENT'] = 'ASTROQUERY'

fits_file = source_id + '.fits.zip'
if linking_parameter not in self.__VALID_LINKING_PARAMETERS:
raise ValueError(
f"Invalid linking_parameter value '{linking_parameter}' (Valid values: "
f"{', '.join(self.__VALID_LINKING_PARAMETERS)})")
else:
if linking_parameter != 'SOURCE_ID':
params_dict['LINKING_PARAMETER'] = linking_parameter

fits_file = ids + '.fits.zip'

if output_file is not None:
if not output_file.endswith('.zip'):
Expand All @@ -1522,10 +1539,10 @@ def get_spectrum(self, *, source_id, schema='sedm', retrieval_type="ALL", output
try:
self.__eucliddata.load_data(params_dict=params_dict, output_file=output_file_full_path, verbose=verbose)
except HTTPError as err:
log.error(f'Cannot retrieve spectrum for source_id {source_id}, schema {schema}. HTTP error: {err}')
log.error(f'Cannot retrieve spectrum for source_id {ids}, schema {schema}. HTTP error: {err}')
return None
except Exception as exx:
log.error(f'Cannot retrieve spectrum for source_id {source_id}, schema {schema}: {str(exx)}')
log.error(f'Cannot retrieve spectrum for source_id {ids}, schema {schema}: {str(exx)}')
return None

self.__extract_file(output_file_full_path=output_file_full_path, output_dir=output_dir, files=files)
Expand All @@ -1548,8 +1565,10 @@ def get_datalinks(self, ids, *, linking_parameter='SOURCE_ID', extra_options=Non
----------
ids : str, int, list of str or list of int, mandatory
list of identifiers
linking_parameter : str, optional, default SOURCE_ID, valid values: SOURCE_ID
linking_parameter : str, optional, default SOURCE_ID, valid values: SOURCE_ID or SOURCEPATCH_ID
By default, all the identifiers are considered as source_id
SOURCE_ID: the identifiers are considered as source_id
SOURCEPATCH_ID: the identifiers are considered as sourcepatch_id
extra_options : str, optional, default None, valid values: METADATA
To let customize the server behaviour, if present.
If provided with value METADATA, the extra fields datalabs_path, file_name & hdu_index will be retrieved.
Expand All @@ -1562,10 +1581,17 @@ def get_datalinks(self, ids, *, linking_parameter='SOURCE_ID', extra_options=Non

"""

return self.__eucliddata.get_datalinks(ids=ids,
linking_parameter=linking_parameter,
extra_options=extra_options,
verbose=verbose)
if linking_parameter not in self.__VALID_LINKING_PARAMETERS:
raise ValueError(
f"Invalid linking_parameter value '{linking_parameter}' (Valid values: "
f"{', '.join(self.__VALID_LINKING_PARAMETERS)})")

final_linking_parameter = None
if linking_parameter != 'SOURCE_ID':
final_linking_parameter = linking_parameter

return self.__eucliddata.get_datalinks(ids=ids, linking_parameter=final_linking_parameter,
extra_options=extra_options, verbose=verbose)

def get_scientific_product_list(self, *, observation_id=None, tile_index=None, category=None, group=None,
product_type=None, dataset_release='REGREPROC1_R2', dsr_part1=None, dsr_part2=None,
Expand Down
6 changes: 2 additions & 4 deletions astroquery/esa/euclid/tests/DummyTapHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,11 +291,9 @@ def get_cutout(self, coordinate, file_path=None,
self.__parameters['output_file'] = output_file
return output_file

def get_spectrum(self, source_id=None,
schema='sedm_pvpr01',
output_file=None):
def get_spectrum(self, id=None, schema='sedm_pvpr01', output_file=None):
self.__invokedMethod = 'get_spectrum'
self.__parameters['source_id'] = source_id
self.__parameters['id'] = id
self.__parameters['schema'] = schema
self.__parameters['output_file'] = output_file
return output_file
39 changes: 32 additions & 7 deletions astroquery/esa/euclid/tests/test_euclidtap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ def test_get_spectrum(tmp_path_factory):

tap = EuclidClass(tap_plus_conn_handler=conn_handler, datalink_handler=tap_plus, show_server_messages=False)

result = tap.get_spectrum(source_id='2417660845403252054', schema='sedm_sc8', output_file=None)
result = tap.get_spectrum(ids='2417660845403252054', schema='sedm_sc8', output_file=None)

assert result is not None

Expand All @@ -1149,10 +1149,30 @@ def test_get_spectrum(tmp_path_factory):

fits_file = os.path.join(tmp_path_factory.mktemp("euclid_tmp"), 'my_fits_file.fits')

result = tap.get_spectrum(source_id='2417660845403252054', schema='sedm_sc8', output_file=fits_file)
result = tap.get_spectrum(ids='2417660845403252054', schema='sedm_sc8', output_file=fits_file)

assert result is not None

remove_temp_dir()

fits_file = os.path.join(tmp_path_factory.mktemp("euclid_tmp"), 'my_fits_file.fits')

result = tap.get_spectrum(ids='2417660845403252054', schema='sedm_sc8', linking_parameter="SOURCE_ID",
output_file=fits_file)

assert result is not None

remove_temp_dir()

fits_file = os.path.join(tmp_path_factory.mktemp("euclid_tmp"), 'my_fits_file.fits')

result = tap.get_spectrum(ids='1499442653027920313123456789', schema='sedm_sc8', linking_parameter="SOURCEPATCH_ID",
output_file=fits_file)

assert result is not None

remove_temp_dir()


@patch.object(TapPlus, 'load_data')
def test_get_spectrum_exceptions_2(mock_load_data, caplog):
Expand All @@ -1169,15 +1189,15 @@ def test_get_spectrum_exceptions_2(mock_load_data, caplog):

mock_load_data.side_effect = HTTPError("launch_job_async HTTPError")

tap.get_spectrum(source_id='2417660845403252054', schema='sedm_sc8', output_file=None)
tap.get_spectrum(ids='2417660845403252054', schema='sedm_sc8', output_file=None)

mssg = ("Cannot retrieve spectrum for source_id 2417660845403252054, schema sedm_sc8. HTTP error: launch_job_async "
"HTTPError")
assert caplog.records[0].msg == mssg

mock_load_data.side_effect = Exception("launch_job_async Exception")

tap.get_spectrum(source_id='2417660845403252054', schema='sedm_sc8', output_file=None)
tap.get_spectrum(ids='2417660845403252054', schema='sedm_sc8', output_file=None)

mssg = "Cannot retrieve spectrum for source_id 2417660845403252054, schema sedm_sc8: launch_job_async Exception"
assert caplog.records[1].msg == mssg
Expand All @@ -1198,15 +1218,20 @@ def test_get_spectrum_exceptions():
# if source_id is None or schema is None:

with pytest.raises(ValueError, match="Missing required argument"):
tap.get_spectrum(source_id=None, schema='sedm_sc8', output_file=None)
tap.get_spectrum(ids=None, schema='sedm_sc8', output_file=None)

with pytest.raises(ValueError, match="Missing required argument"):
tap.get_spectrum(source_id='2417660845403252054', schema=None, output_file=None)
tap.get_spectrum(ids='2417660845403252054', schema=None, output_file=None)

with pytest.raises(ValueError, match=(
"Invalid argument value for 'retrieval_type'. Found hola, expected: 'ALL' or any of \\['SPECTRA_BGS', "
"'SPECTRA_RGS'\\]")):
tap.get_spectrum(retrieval_type='hola', source_id='2417660845403252054', schema='schema', output_file=None)
tap.get_spectrum(retrieval_type='hola', ids='2417660845403252054', schema='schema', output_file=None)

linking_parameter = 'NOT_VALID'
with pytest.raises(ValueError, match=f"^Invalid linking_parameter value '{linking_parameter}' .*"):
tap.get_spectrum(ids='2417660845403252054', schema='sedm_sc8', linking_parameter=linking_parameter,
output_file='fits_file')


def test_get_scientific_data_product_list():
Expand Down
2 changes: 1 addition & 1 deletion docs/esa/euclid/euclid.rst
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ Alternatively, the get_datalinks_ method can be used to find out if a given sour
Download the spectra:

>>> inp_source = str(res['source_id'][0]) # Note: the input of get_spectrum must be a string.
>>> dl_out = Euclid.get_spectrum(source_id=inp_source, retrieval_type = "SPECTRA_RGS", verbose = True)
>>> dl_out = Euclid.get_spectrum(ids=inp_source, retrieval_type = "SPECTRA_RGS", verbose = True)
>>> print(f'Spectra downloaded and saved in: {dl_out}')

Read the spectra and convert it to Astropy table:
Expand Down
Loading