Skip to content

Commit 3f65fe4

Browse files
committed
Merge remote-tracking branch 'upstream/main' into develop
2 parents f03b75f + c26a457 commit 3f65fe4

File tree

5 files changed

+66
-38
lines changed

5 files changed

+66
-38
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ gaia
3434
^^^^
3535

3636
- New datalink DR4 retrieval type RESIDUAL_IMAGE. [#3489]
37+
- The method ``load_data`` parses ecsv files [#3500].
3738

3839
esa.hubble
3940
^^^^^^^^^^

astroquery/gaia/core.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from astropy.coordinates import Angle
2121
from astropy.io import fits
2222
from astropy.io import votable
23+
from astropy.io.fits import TableHDU, BinTableHDU
2324
from astropy.table import Table
2425
from astropy.units import Quantity
2526
from astropy.utils.decorators import deprecated_renamed_argument
@@ -194,9 +195,9 @@ def load_data(self, ids, *, data_release=None, data_structure='INDIVIDUAL', retr
194195
'EPOCH_PHOTOMETRY_CROWDED_FIELD', 'EPOCH_IMAGE', 'EPOCH_PHOTOMETRY_CCD', 'EPOCH_SPECTRUM_XP_SSO',
195196
'EPOCH_SPECTRUM_XP_CROWDING', 'MEAN_SPECTRUM_XP', 'EPOCH_SPECTRUM_XP', 'CROWDED_FIELD_IMAGE',
196197
'EPOCH_ASTROMETRY_BRIGHT', 'MEAN_SPECTRUM_XP_GRAVLENS', 'EPOCH_FLAGS_NSS', 'EPOCH_PARAMETERS_RVS_SINGLE',
197-
'EPOCH_PARAMETERS_RVS_DOUBLE', 'EPOCH_FLAGS_VARI']. Note that for 'CROWDED_FIELD_IMAGE', only the format
198-
'fits' can be used, and its image, in the principal header, will not be available in the returned
199-
dictionary. Set 'output_file' to retrieve all data: image + tables. Note that for 'RESIDUAL_IMAGE',
198+
'EPOCH_PARAMETERS_RVS_DOUBLE', 'EPOCH_FLAGS_VARI', 'RESIDUAL_IMAGE']. Note that for 'CROWDED_FIELD_IMAGE',
199+
only the format 'fits' can be used, and its image, in the principal header, will not be available in the
200+
returned dictionary. Set 'output_file' to retrieve all data: image + tables. Note that for 'RESIDUAL_IMAGE',
200201
only the format 'fits' can be used. Since the fits files only contain images, the returned table will be
201202
empty. Therefore, set 'output_file' to save the files to get access to their content.
202203
linking_parameter : str, optional, default SOURCE_ID, valid values: SOURCE_ID, TRANSIT_ID, IMAGE_ID
@@ -308,7 +309,9 @@ def load_data(self, ids, *, data_release=None, data_structure='INDIVIDUAL', retr
308309
shutil.rmtree(path)
309310
else:
310311
for file in files.keys():
311-
os.remove(os.path.join(os.getcwd(), path, file))
312+
final_file = os.path.join(os.getcwd(), path, file)
313+
if os.path.isfile(final_file):
314+
os.remove(final_file)
312315

313316
if verbose:
314317
if output_file_specified:
@@ -340,13 +343,13 @@ def __get_data_files(output_file, path):
340343

341344
if key.endswith('.fits'):
342345
tables = []
343-
with fits.open(value) as hduList:
344-
num_hdus = len(hduList)
345-
for i in range(1, num_hdus):
346-
table = Table.read(hduList[i], format='fits')
347-
Gaia.correct_table_units(table)
348-
tables.append(table)
349-
files[key] = tables
346+
with fits.open(value, memmap=False) as hduList:
347+
for hdu in hduList:
348+
if isinstance(hdu, (TableHDU, BinTableHDU)):
349+
table = Table.read(hdu, format='fits')
350+
Gaia.correct_table_units(table)
351+
tables.append(table)
352+
files[key] = tables
350353

351354
elif key.endswith('.xml'):
352355
tables = []
@@ -360,6 +363,12 @@ def __get_data_files(output_file, path):
360363
tables.append(table)
361364
files[key] = tables
362365

366+
elif key.endswith('.ecsv'):
367+
tables = []
368+
table = Table.read(value, format='ascii.ecsv', fast_reader=False)
369+
tables.append(table)
370+
files[key] = tables
371+
363372
elif key.endswith('.json'):
364373
tables = []
365374
with open(value) as f:

astroquery/gaia/tests/test_gaiatap.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -942,11 +942,14 @@ def test_datalink_querier_load_data_ecsv(mock_datalink_querier_ecsv):
942942

943943
assert len(result_dict) == 3
944944

945-
files = list(result_dict.keys())
946-
files.sort()
947-
assert files[0] == 'MCMC_MSC-Gaia DR3 5937083312263887616.ecsv'
948-
assert files[1] == 'XP_CONTINUOUS-Gaia DR3 5937083312263887616.ecsv'
949-
assert files[2] == 'XP_SAMPLED-Gaia DR3 5937083312263887616.ecsv'
945+
files = list(sorted(result_dict.items()))
946+
assert files[0][0] == 'MCMC_MSC-Gaia DR3 5937083312263887616.ecsv'
947+
assert files[1][0] == 'XP_CONTINUOUS-Gaia DR3 5937083312263887616.ecsv'
948+
assert files[2][0] == 'XP_SAMPLED-Gaia DR3 5937083312263887616.ecsv'
949+
950+
assert isinstance(files[0][1][0], Table)
951+
assert isinstance(files[1][1][0], Table)
952+
assert isinstance(files[2][1][0], Table)
950953

951954
os.remove(os.path.join(os.getcwd(), datalink_output))
952955

@@ -980,18 +983,21 @@ def test_datalink_querier_load_data_csv(mock_datalink_querier_csv):
980983

981984
assert len(result_dict) == 3
982985

983-
files = list(result_dict.keys())
984-
files.sort()
985-
assert files[0] == 'MCMC_MSC-Gaia DR3 5937083312263887616.csv'
986-
assert files[1] == 'XP_CONTINUOUS-Gaia DR3 5937083312263887616.csv'
987-
assert files[2] == 'XP_SAMPLED-Gaia DR3 5937083312263887616.csv'
986+
files = list(sorted(result_dict.items()))
987+
assert files[0][0] == 'MCMC_MSC-Gaia DR3 5937083312263887616.csv'
988+
assert files[1][0] == 'XP_CONTINUOUS-Gaia DR3 5937083312263887616.csv'
989+
assert files[2][0] == 'XP_SAMPLED-Gaia DR3 5937083312263887616.csv'
990+
991+
assert isinstance(files[0][1][0], Table)
992+
assert isinstance(files[1][1][0], Table)
993+
assert isinstance(files[2][1][0], Table)
988994

989995
os.remove(os.path.join(os.getcwd(), datalink_output))
990996

991997
assert not os.path.exists(datalink_output)
992998

993999

994-
@pytest.mark.skip(reason="Thes fits files generate an error relatate to the unit 'log(cm.s**-2)")
1000+
@pytest.mark.filterwarnings("ignore:")
9951001
def test_datalink_querier_load_data_fits(mock_datalink_querier_fits):
9961002
result_dict = mock_datalink_querier_fits.load_data(ids=[5937083312263887616], data_release='Gaia DR3',
9971003
data_structure='INDIVIDUAL',
@@ -1019,11 +1025,14 @@ def test_datalink_querier_load_data_fits(mock_datalink_querier_fits):
10191025

10201026
assert len(result_dict) == 3
10211027

1022-
files = list(result_dict.keys())
1023-
files.sort()
1024-
assert files[0] == 'MCMC_MSC-Gaia DR3 5937083312263887616.fits'
1025-
assert files[1] == 'XP_CONTINUOUS-Gaia DR3 5937083312263887616.fits'
1026-
assert files[2] == 'XP_SAMPLED-Gaia DR3 5937083312263887616.fits'
1028+
files = list(sorted(result_dict.items()))
1029+
assert files[0][0] == 'MCMC_MSC-Gaia DR3 5937083312263887616.fits'
1030+
assert files[1][0] == 'XP_CONTINUOUS-Gaia DR3 5937083312263887616.fits'
1031+
assert files[2][0] == 'XP_SAMPLED-Gaia DR3 5937083312263887616.fits'
1032+
1033+
assert isinstance(files[0][1][0], Table)
1034+
assert isinstance(files[1][1][0], Table)
1035+
assert isinstance(files[2][1][0], Table)
10271036

10281037
os.remove(os.path.join(os.getcwd(), datalink_output))
10291038

@@ -1072,10 +1081,12 @@ def load_data_monkeypatched(self, params_dict, output_file, verbose):
10721081
path.unlink()
10731082

10741083

1075-
@pytest.mark.skip(reason="Thes fits files generate an error relatate to the unit 'log(cm.s**-2)")
1076-
def test_load_data_fits(monkeypatch, tmp_path, tmp_path_factory):
1084+
@pytest.mark.filterwarnings("ignore:")
1085+
def test_load_data_fits(monkeypatch, tmp_path, tmp_path_factory, patch_datetime_now):
1086+
assert datetime.datetime.now(datetime.timezone.utc) == FAKE_TIME
1087+
10771088
now = datetime.datetime.now(datetime.timezone.utc)
1078-
output_file = 'datalink_output_' + now.strftime("%Y%m%dT%H%M%S") + '.zip'
1089+
output_file = 'datalink_output_' + now.strftime("%Y%m%dT%H%M%S.%f") + '.zip'
10791090

10801091
path = Path(os.getcwd(), output_file)
10811092

@@ -1092,7 +1103,7 @@ def load_data_monkeypatched(self, params_dict, output_file, verbose):
10921103
"RETRIEVAL_TYPE": "epoch_photometry",
10931104
"DATA_STRUCTURE": "INDIVIDUAL",
10941105
"USE_ZIP_ALWAYS": "true"}
1095-
assert output_file == Path(os.getcwd(), 'datalink_output.zip')
1106+
assert str(path) == output_file
10961107
assert verbose is True
10971108

10981109
monkeypatch.setattr(TapPlus, "load_data", load_data_monkeypatched)

astroquery/simbad/tests/test_utils.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import pytest
32

43
from astroquery.simbad.utils import (CriteriaTranslator, _parse_coordinate_and_convert_to_icrs,
@@ -82,9 +81,6 @@ def test_tokenizer():
8281

8382

8483
@pytest.mark.parametrize("test, result", [
85-
("region(GAL,180 0,2d) & otype = 'G' & (nbref >= 10|bibyear >= 2000)",
86-
("CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 86.40498828654475, 28.93617776179148, 2.0)) = 1"
87-
" AND otypes.otype = 'G' AND (nbref >= 10 OR bibyear >= 2000)")),
8884
("author ∼ 'egret*'", "regexp(author, '^egret.*$') = 1"),
8985
("cat in ('hd','hip','ppm')", "cat IN ('hd','hip','ppm')"),
9086
("author !~ 'test'", "regexp(author, '^test$') = 0"),
@@ -103,6 +99,17 @@ def test_transpiler(test, result):
10399
assert translated == result
104100

105101

102+
def test_transpiler_with_floats():
103+
# This test is not part of the previous one as the floats in the string have
104+
# some version dependent variations. Expected translation:
105+
# ("CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 86.40498828654475, 28.93617776179148, 2.0)) = 1"
106+
# " AND otypes.otype = 'G' AND (nbref >= 10 OR bibyear >= 2000)")
107+
translation = CriteriaTranslator.parse("region(GAL,180 0,2d) & otype = 'G' & (nbref >= 10|bibyear >= 2000)")
108+
109+
assert "CONTAINS(POINT('ICRS', ra, dec), CIRCLE('ICRS', 86.404988286" == translation[:60]
110+
assert ", 2.0)) = 1 AND otypes.otype = 'G' AND (nbref >= 10 OR bibyear >= 2000)" == translation[-71:]
111+
112+
106113
def test_transpiler_errors(capsys):
107114
with pytest.raises(ValueError, match="Syntax error for sim-script criteria"):
108115
CriteriaTranslator.parse("otype % 'G'")

docs/eso/eso.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ ESO Queries (`astroquery.eso`)
1717

1818
In TAP, ``column_filters`` accepts ADQL expressions. For example:
1919

20-
.. doctest-skip::
20+
.. code-block:: python
2121
2222
column_filters = {
2323
'some_int_column': "< 5",
@@ -234,7 +234,6 @@ as certain columns with datatype ``char`` actually define timestamps or regions
234234

235235
Number of records present in the table ist.midi:
236236
421764
237-
[astroquery.eso.core]
238237

239238
**Note:** for a deeper description of each column, the following query can be issued
240239
on the ESO **Programmatic Access** website (https://archive.eso.org/programmatic/#TAP):
@@ -249,6 +248,7 @@ target ``NGC 4151`` between ``2008-01-01`` and ``2009-05-12`` are searched, and
249248
return two columns: the date of observation and the name of the object.
250249

251250
.. doctest-remote-data::
251+
252252
>>> table = eso.query_instrument(
253253
... 'midi',
254254
... column_filters={
@@ -477,7 +477,7 @@ Two concrete and relevant examples of fields present in WDB but not present in T
477477
are ``stime`` and ``etime``. The following snippet shows how to adapt the filters to
478478
the TAP / ADQL syntax:
479479

480-
.. doctest-skip::
480+
.. code-block:: python
481481
482482
# The following filters won't work:
483483
column_filters = {

0 commit comments

Comments
 (0)