diff --git a/astroquery/simbad/core.py b/astroquery/simbad/core.py index 2afbbf9547..0578578f03 100644 --- a/astroquery/simbad/core.py +++ b/astroquery/simbad/core.py @@ -89,14 +89,14 @@ class SimbadClass(BaseVOQuery): SIMBAD_URL = 'https://' + conf.server + '/simbad/sim-script' ROW_LIMIT = conf.row_limit - @dataclass + @dataclass(frozen=True) class Column: """A class to define a column in a SIMBAD query.""" table: str name: str alias: str = field(default=None) - @dataclass + @dataclass(frozen=True) class Join: """A class to define a join between two tables.""" table: str @@ -199,11 +199,12 @@ def list_output_options(self): velocity ... """ # get the tables with a simple link to basic - query_tables = """SELECT table_name AS name, tables.description + query_tables = """SELECT DISTINCT table_name AS name, tables.description FROM TAP_SCHEMA.keys JOIN TAP_SCHEMA.key_columns USING (key_id) JOIN TAP_SCHEMA.tables ON TAP_SCHEMA.keys.from_table = TAP_SCHEMA.tables.table_name + OR TAP_SCHEMA.keys.target_table = TAP_SCHEMA.tables.table_name WHERE TAP_SCHEMA.tables.schema_name = 'public' - AND target_table = 'basic' + AND (from_table = 'basic' OR target_table = 'basic') AND from_table != 'h_link' """ tables = self.query_tap(query_tables) diff --git a/astroquery/simbad/setup_package.py b/astroquery/simbad/setup_package.py index ba92842b61..1f63c9662f 100644 --- a/astroquery/simbad/setup_package.py +++ b/astroquery/simbad/setup_package.py @@ -4,7 +4,9 @@ def get_package_data(): - paths_test = [str(Path('data') / 'simbad_output_options.xml')] + paths_test = [str(Path('data') / 'simbad_output_options.xml'), + str(Path("data") / "simbad_basic_columns.xml"), + str(Path("data") / "simbad_linked_to_basic.xml")] paths_core = [str(Path('data') / 'query_criteria_fields.json')] diff --git a/astroquery/simbad/tests/data/simbad_basic_columns.xml b/astroquery/simbad/tests/data/simbad_basic_columns.xml new file mode 100644 index 0000000000..2a20853c80 --- /dev/null +++ b/astroquery/simbad/tests/data/simbad_basic_columns.xml @@ -0,0 +1,579 @@ + + + + + + + + table name from TAP_SCHEMA.tables + + + + + column name + + + + + ADQL datatype as in section 2.5 + + + + + brief description of column + + + + + unit in VO standard format + + + + + UCD of column if any + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
basicdecDOUBLEDeclinationdegpos.eq.dec;meta.main
basicmain_idVARCHARMain identifier for an object + meta.id;meta.main
basicotype_txtVARCHARObject type + src.class
basicraDOUBLERight ascensiondegpos.eq.ra;meta.main
basiccoo_bibcodeCHARCoordinate reference + meta.bib.bibcode;pos.eq
basiccoo_err_angleSMALLINTCoordinate error angledegpos.posAng;pos.errorEllipse;pos.eq
basiccoo_err_majREALCoordinate error major axismasphys.angSize.smajAxis;pos.errorEllipse;pos.eq
basiccoo_err_maj_precSMALLINTCoordinate error major axis precision + +
basiccoo_err_minREALCoordinate error minor axismasphys.angSize.sminAxis;pos.errorEllipse;pos.eq
basiccoo_err_min_precSMALLINTCoordinate error minor axis precision + +
basiccoo_qualCHARCoordinate quality + meta.code.qual;pos.eq
basiccoo_wavelengthCHARWavelength class for the origin of the coordinates (R,I,V,U,X,G) + instr.bandpass;pos.eq
basicdec_precSMALLINTDeclination precision + +
basicgaldim_angleSMALLINTGalaxy ellipse angledegpos.posAng
basicgaldim_bibcodeCHARGalaxy dimension reference + meta.bib.bibcode;phys.angSize
basicgaldim_majaxisREALAngular size major axisarcminphys.angSize.smajAxis
basicgaldim_majaxis_precSMALLINTAngular size major axis precision + +
basicgaldim_minaxisREALAngular size minor axisarcminphys.angSize.sminAxis
basicgaldim_minaxis_precSMALLINTAngular size minor axis precision + +
basicgaldim_qualCHARGalaxy dimension quality + meta.code.qual;phys.angSize
basicgaldim_wavelengthCHARWavelength class for the origin of the Galaxy dimension + instr.bandpass;phys.angSize
basichpxBIGINTHealpix number at ORDER=10 + meta.id
basicmorph_bibcodeCHARmorphological type reference + meta.bib.bibcode;src.morph.type
basicmorph_qualCHARMorphological type quality + meta.code.qual;src.morph.type
basicmorph_typeVARCHARMorphological type + src.morph.type
basicnbrefINTEGERnumber of references + meta.bib;meta.number
basicoidBIGINTObject internal identifier + meta.record;meta.id
basicotypeVARCHARObject type + src.class
basicplx_bibcodeCHARParallax reference + meta.bib.bibcode;pos.parallax.trig
basicplx_errREALParallax errormasstat.error;pos.parallax.trig
basicplx_err_precSMALLINTParallax error precision + +
basicplx_precSMALLINTParallax precision + +
basicplx_qualCHARParallax quality + meta.code.qual;pos.parallax.trig
basicplx_valueDOUBLEParallaxmaspos.parallax.trig
basicpm_bibcodeCHARProper motion reference + meta.bib.bibcode;pos.pm
basicpm_err_angleSMALLINTProper motion error angledegpos.posAng;pos.errorEllipse;pos.pm
basicpm_err_majREALProper motion error major axismas.yr-1phys.angSize.smajAxis;pos.errorEllipse;pos.pm
basicpm_err_maj_precSMALLINTProper motion error major axis precision + +
basicpm_err_minREALProper motion error minor axismas.yr-1phys.angSize.sminAxis;pos.errorEllipse;pos.pm
basicpm_err_min_precSMALLINTProper motion error minor axis precision + +
basicpm_qualCHARProper motion quality + meta.code.qual;pos.pm
basicpmdecDOUBLEProper motion in DECmas.yr-1pos.pm;pos.eq.dec
basicpmdec_precSMALLINTProper motion in DEC precision + +
basicpmraDOUBLEProper motion in RAmas.yr-1pos.pm;pos.eq.ra
basicpmra_precSMALLINTProper motion in RA precision + +
basicra_precSMALLINTRight ascension precision + +
basicrvz_bibcodeCHARRadial velocity / redshift reference + meta.bib.bibcode;spect.dopplerVeloc
basicrvz_errREALRadial velocity / redshift errorkm.s-1stat.error;spect.dopplerVeloc
basicrvz_err_precSMALLINTRadial velocity / redshift error precision + +
basicrvz_natureCHARvelocity / redshift nature + meta.code;spect.dopplerVeloc
basicrvz_qualCHARRadial velocity / redshift quality + meta.code.qual;spect.dopplerVeloc
basicrvz_radvelDOUBLERadial Velocitykm.s-1spect.dopplerVeloc.opt
basicrvz_radvel_precSMALLINTRadial velocity precision + +
basicrvz_redshiftDOUBLEredshift + src.redshift
basicrvz_redshift_precSMALLINTredshift precision + +
basicrvz_typeCHARRadial velocity / redshift type + +
basicrvz_wavelengthCHARWavelength class for the origin of the radial velocity/reshift + instr.bandpass;spect.dopplerVeloc.opt
basicsp_bibcodeCHARspectral type reference + meta.bib.bibcode;src.spType
basicsp_qualCHARSpectral type quality + meta.code.qual;src.spType
basicsp_typeVARCHARMK spectral type + src.spType
basicupdate_datedateDate of last modification + time.processing
basicvlsrDOUBLEvelocity in Local Standard of Rest reference framekm.s-1phys.veloc;pos.lsr;stat.mean
basicvlsr_bibcodeCHARReference for the origin of the LSR velocity + meta.bib.bibcode;phys.veloc;pos.lsr
basicvlsr_errDOUBLEError incertainty of the VLSR velocitykm.s-1stat.error;phys.veloc;pos.lsr
basicvlsr_maxREALMaximum for the mean value of the LSR velocitykm.s-1phys.veloc;pos.lsr;stat.max
basicvlsr_minREALMinimum for the mean value of the LSR velocitykm.s-1phys.veloc;pos.lsr;stat.min
basicvlsr_wavelengthCHARWavelength class for the origin of the LSR velocity + instr.bandpass;phys.veloc;pos.lsr
+
+
diff --git a/astroquery/simbad/tests/data/simbad_linked_to_basic.xml b/astroquery/simbad/tests/data/simbad_linked_to_basic.xml new file mode 100644 index 0000000000..9372985aa1 --- /dev/null +++ b/astroquery/simbad/tests/data/simbad_linked_to_basic.xml @@ -0,0 +1,177 @@ + + + + + + + + fully qualified table name + + + + + key column name in the from_table + + + + + fully qualified table name + + + + + key column name in the target_table + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
idsoidrefbasicoid
otypedefotypebasicotype
identoidrefbasicoid
fluxoidrefbasicoid
allfluxesoidrefbasicoid
has_refoidrefbasicoid
mesDistanceoidrefbasicoid
mesDiameteroidrefbasicoid
mesFe_hoidrefbasicoid
mesISOoidrefbasicoid
mesIUEoidrefbasicoid
mesPLXoidrefbasicoid
mesPMoidrefbasicoid
mesRotoidrefbasicoid
mesVaroidrefbasicoid
mesVelocitiesoidrefbasicoid
mesXmmoidrefbasicoid
h_linkparentbasicoid
h_linkchildbasicoid
mesHerscheloidrefbasicoid
bibliooidrefbasicoid
alltypesoidrefbasicoid
otypesoidrefbasicoid
mesSpToidrefbasicoid
+
+
diff --git a/astroquery/simbad/tests/data/simbad_output_options.xml b/astroquery/simbad/tests/data/simbad_output_options.xml index 459e88015c..45ac029e43 100644 --- a/astroquery/simbad/tests/data/simbad_output_options.xml +++ b/astroquery/simbad/tests/data/simbad_output_options.xml @@ -3,7 +3,7 @@ http://www.astropy.org/ --> - +
column name @@ -18,23 +18,23 @@ - - + + - - + + - - + + - - + + @@ -43,63 +43,68 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + @@ -108,23 +113,23 @@ - - + + - - + + - - + + - - + + @@ -469,7 +474,7 @@ - + diff --git a/astroquery/simbad/tests/test_simbad.py b/astroquery/simbad/tests/test_simbad.py index 72f6f34ebc..811a19982f 100644 --- a/astroquery/simbad/tests/test_simbad.py +++ b/astroquery/simbad/tests/test_simbad.py @@ -1,17 +1,18 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst -import os from pathlib import Path import re from astropy.coordinates import SkyCoord from astropy.io.votable import parse_single_table +from astropy.table import Table import astropy.units as u +from pyvo.dal.tap import TAPService import pytest from ... import simbad from .test_simbad_remote import multicoords -from astroquery.utils.mocks import MockResponse +from astroquery.exceptions import LargeQueryWarning GALACTIC_COORDS = SkyCoord(l=-67.02084 * u.deg, b=-29.75447 * u.deg, frame="galactic") @@ -19,69 +20,62 @@ FK4_COORDS = SkyCoord(ra=84.90759 * u.deg, dec=-80.89403 * u.deg, frame="fk4") FK5_COORDS = SkyCoord(ra=83.82207 * u.deg, dec=-80.86667 * u.deg, frame="fk5") -DATA_FILES = { - 'sample': 'query_sample.data', - 'region': 'query_sample_region.data', -} +@pytest.fixture() +def _mock_simbad_class(monkeypatch): + """Avoid a TAP request for properties in the tests.""" -class MockResponseSimbad(MockResponse): - query_regex = re.compile(r'query\s+([a-z]+)\s+') - - def __init__(self, script, cache=False, **kwargs): - # preserve, e.g., headers - super().__init__(**kwargs) - self.content = self.get_content(script) - - def get_content(self, script): - match = self.query_regex.search(script) - if match: - filename = DATA_FILES[match.group(1)] - with open(data_path(filename), "rb") as infile: - content = infile.read() - return content - - -def data_path(filename): - data_dir = os.path.join(os.path.dirname(__file__), 'data') - return os.path.join(data_dir, filename) - - -@pytest.fixture -def patch_post(request): - mp = request.getfixturevalue("monkeypatch") - - mp.setattr(simbad.SimbadClass, '_request', post_mockreturn) - - return mp + with open(Path(__file__).parent / "data" / "simbad_output_options.xml", "rb") as f: + table = parse_single_table(f).to_table() + # This should not change too often, to regenerate this file, do: + # >>> from astroquery.simbad import Simbad + # >>> options = Simbad.list_output_options() + # >>> options.write("simbad_output_options.xml", format="votable") + monkeypatch.setattr(simbad.SimbadClass, "hardlimit", 2000000) + monkeypatch.setattr(simbad.SimbadClass, "list_output_options", lambda self: table) -def post_mockreturn(self, method, url, data, timeout, **kwargs): - response = MockResponseSimbad(data['script'], **kwargs) +@pytest.fixture() +def _mock_basic_columns(monkeypatch): + """Avoid a request to get the columns of basic.""" + with open(Path(__file__).parent / "data" / "simbad_basic_columns.xml", "rb") as f: + table = parse_single_table(f).to_table() + # This should not change too often, to regenerate this file, do: + # >>> from astroquery.simbad import Simbad + # >>> columns = Simbad.list_columns("basic") + # >>> columns.write("simbad_basic_columns.xml", format="votable") - class last_query: - pass + def _mock_list_columns(self, table_name=None): + """Patch a call with basic as an argument only.""" + if table_name == "basic": + return table + # to test in add_to_output + if table_name == "mesdistance": + return Table( + [["bibcode"]], names=["column_name"] + ) + return simbad.SimbadClass().list_columns(table_name) - self._last_query = last_query() - self._last_query.data = data - return response + monkeypatch.setattr(simbad.SimbadClass, "list_columns", _mock_list_columns) @pytest.fixture() -def _mock_simbad_class(monkeypatch): - """Avoid a TAP request for properties in the tests.""" - - with open(Path(__file__).parent / "data" / "simbad_output_options.xml", "rb") as f: +def _mock_linked_to_basic(monkeypatch): + """Avoid a request to get the columns of basic.""" + with open(Path(__file__).parent / "data" / "simbad_linked_to_basic.xml", "rb") as f: table = parse_single_table(f).to_table() # This should not change too often, to regenerate this file, do: # >>> from astroquery.simbad import Simbad - # >>> options = Simbad.list_output_options() - # >>> options.write("simbad_output_options.xml", format="votable") + # >>> linked = Simbad.list_linked_tables("basic") + # >>> linked.write("simbad_linked_to_basic.xml", format="votable") - def mock_output_options(self): - return table - monkeypatch.setattr(simbad.SimbadClass, "hardlimit", 2000000) - monkeypatch.setattr(simbad.SimbadClass, "list_output_options", mock_output_options) + def _mock_linked_to_basic(self, table_name=None): + """Patch a call with basic as an argument only.""" + if table_name == "basic": + return table + return simbad.SimbadClass().list_linked_tables(table_name) + + monkeypatch.setattr(simbad.SimbadClass, "list_linked_tables", _mock_linked_to_basic) def test_adql_parameter(): @@ -116,6 +110,12 @@ def test_simbad_create_tap_service(): assert 'simbad/sim-tap' in simbadtap.baseurl +def test_simbad_hardlimit(monkeypatch): + simbad_instance = simbad.Simbad() + monkeypatch.setattr(TAPService, "hardlimit", 2) + assert simbad_instance.hardlimit == 2 + + def test_init_columns_in_output(): simbad_instance = simbad.Simbad() default_columns = simbad_instance.columns_in_output @@ -139,7 +139,53 @@ def test_mocked_simbad(): # ---------------------------- +@pytest.mark.usefixtures("_mock_basic_columns") +def test_list_output_options(monkeypatch): + monkeypatch.setattr(simbad.SimbadClass, "query_tap", + lambda self, _: Table([["biblio"], ["biblio description"]], + names=["name", "description"], + dtype=["object", "object"])) + options = simbad.SimbadClass().list_output_options() + assert set(options.group_by("type").groups.keys["type"]) == {"table", + "column of basic", + "bundle of basic columns"} + + +@pytest.mark.usefixtures("_mock_basic_columns") +@pytest.mark.parametrize(("bundle_name", "column"), + [("coordinates", simbad.SimbadClass.Column("basic", "ra")), + ("coordinates", simbad.SimbadClass.Column("basic", "coo_bibcode")), + ("dim", simbad.SimbadClass.Column("basic", "galdim_wavelength"))]) +def test_get_bundle_columns(bundle_name, column): + assert column in simbad.SimbadClass()._get_bundle_columns(bundle_name) + + +@pytest.mark.usefixtures("_mock_linked_to_basic") +def test_add_table_to_output(monkeypatch): + # if table = basic, no need to add a join + simbad_instance = simbad.Simbad() + simbad_instance._add_table_to_output("basic") + assert simbad.SimbadClass.Column("basic", "*") in simbad_instance.columns_in_output + # cannot add h_link (two ways to join it, it's not a simple link) + with pytest.raises(ValueError, match="'h_link' has no explicit link to 'basic'.*"): + simbad_instance._add_table_to_output("h_link") + # add a table with a link and an alias needed + monkeypatch.setattr(simbad.SimbadClass, "list_columns", lambda self, _: Table([["oidref", "bibcode"]], + names=["column_name"])) + simbad_instance._add_table_to_output("mesDiameter") + assert simbad.SimbadClass.Join("mesdiameter", + simbad.SimbadClass.Column("basic", "oid"), + simbad.SimbadClass.Column("mesdiameter", "oidref") + ) in simbad_instance.joins + assert simbad.SimbadClass.Column("mesdiameter", "bibcode", '"mesdiameter.bibcode"' + ) in simbad_instance.columns_in_output + assert simbad.SimbadClass.Column("mesdiameter", "oidref", '"mesdiameter.oidref"' + ) not in simbad_instance.columns_in_output + + @pytest.mark.usefixtures("_mock_simbad_class") +@pytest.mark.usefixtures("_mock_basic_columns") +@pytest.mark.usefixtures("_mock_linked_to_basic") def test_add_to_output(): simbad_instance = simbad.Simbad() # add columns from basic (one value) @@ -150,6 +196,13 @@ def test_add_to_output(): expected = [simbad.SimbadClass.Column("basic", "pmdec"), simbad.SimbadClass.Column("basic", "pm_bibcode")] assert all(column in simbad_instance.columns_in_output for column in expected) + # add a table + simbad_instance.columns_in_output = [] + simbad_instance.add_to_output("basic") + assert [simbad.SimbadClass.Column("basic", "*")] == simbad_instance.columns_in_output + # add a bundle + simbad_instance.add_to_output("dimensions") + assert simbad.SimbadClass.Column("basic", "galdim_majaxis") in simbad_instance.columns_in_output # a column which name has changed should raise a warning but still # be added under its new name simbad_instance.columns_in_output = [] @@ -157,6 +210,9 @@ def test_add_to_output(): "appearing with its new name in the output table"): simbad_instance.add_to_output("id(1)") assert simbad.SimbadClass.Column("basic", "main_id") in simbad_instance.columns_in_output + # a table which name has changed should raise a warning too + with pytest.warns(DeprecationWarning, match="'distance' has been renamed 'mesdistance'*"): + simbad_instance.add_to_output("distance") # errors are raised for the deprecated fields with options with pytest.raises(ValueError, match="Criteria on filters are deprecated when defining Simbad's output.*"): simbad_instance.add_to_output("fluxdata(V)") @@ -192,6 +248,13 @@ def test_query_bibcode_class(): assert adql == ('SELECT TOP 5 "bibcode", "doi", "journal", "nbobject", "page", "last_page",' ' "title", "volume", "year", "abstract" FROM ref WHERE bibcode =' ' \'1968ZA.....68..366D\' ORDER BY bibcode') + # with a criteria + adql = simbad_instance.query_bibcode("200*", wildcard=True, + criteria="abstract LIKE '%exoplanet%'", get_adql=True) + assert adql == ('SELECT TOP 5 "bibcode", "doi", "journal", "nbobject", "page", "last_page", ' + '"title", "volume", "year" FROM ref ' + 'WHERE regexp(lowercase(bibcode), \'^200.*$\') = 1 ' + 'AND abstract LIKE \'%exoplanet%\' ORDER BY bibcode') @pytest.mark.usefixtures("_mock_simbad_class") @@ -224,30 +287,61 @@ def test_query_catalog(): assert adql.endswith(where_clause) -@pytest.mark.parametrize(('coordinates', 'radius'), - [(ICRS_COORDS, 2*u.arcmin), - (GALACTIC_COORDS, 5 * u.deg), - (FK4_COORDS, '5d0m0s'), - (FK5_COORDS, 2*u.arcmin), - (multicoords, 0.5*u.arcsec), - (multicoords, "0.5s"), +@pytest.mark.parametrize(('coordinates', 'radius', 'where'), + [(ICRS_COORDS, 2*u.arcmin, + "WHERE CONTAINS(POINT('ICRS', basic.ra, basic.dec), " + "CIRCLE('ICRS', 83.82208333333332, -80.86666666666667, " + "0.03333333333333333)) = 1"), + (GALACTIC_COORDS, 5 * u.deg, + "WHERE CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 83.82143390876422, -80.86670635998868, 5.0)) = 1"), + (FK4_COORDS, '5d0m0s', + "WHERE CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 83.82167690397775, -80.86665433684944, 5.0)) = 1"), + (FK5_COORDS, 2*u.arcmin, + "WHERE CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 83.82208297061133, -80.86666477635467, " + "0.03333333333333333)) = 1"), + (multicoords, 0.5*u.arcsec, + "WHERE (CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 266.835, -28.38528, 0.0001388888888888889)) " + "= 1 OR CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 266.835, -28.38528, 0.0001388888888888889)) = 1 )"), + (multicoords, ["0.5s", "0.2s"], + "WHERE (CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 266.835, -28.38528, 0.0001388888888888889)) " + "= 1 OR CONTAINS(POINT(\'ICRS\', basic.ra, basic.dec), " + "CIRCLE(\'ICRS\', 266.835, -28.38528, 5.555555555555556e-05)) = 1 )"), ]) @pytest.mark.usefixtures("_mock_simbad_class") -def test_query_region(coordinates, radius): - # looks like this also tests class as Simbad or Simbad() +def test_query_region(coordinates, radius, where): adql = simbad.core.Simbad.query_region(coordinates, radius=radius, get_adql=True) adql_2 = simbad.core.Simbad().query_region(coordinates, radius=radius, get_adql=True) assert adql == adql_2 + assert adql.endswith(where) + + +@pytest.mark.usefixtures("_mock_simbad_class") +def test_query_region_with_criteria(): + adql = simbad.core.Simbad.query_region(ICRS_COORDS, radius="0.1s", + criteria="galdim_majaxis>0.2", get_adql=True) + assert adql.endswith("AND (galdim_majaxis>0.2)") +# transform large query warning into error to save execution time +@pytest.mark.filterwarnings("error:For very large queries") @pytest.mark.usefixtures("_mock_simbad_class") def test_query_region_errors(): with pytest.raises(u.UnitsError): simbad.core.Simbad().query_region(ICRS_COORDS, radius=0) - + with pytest.raises(TypeError, match="The cone radius must be specified as an angle-equivalent quantity"): + simbad.SimbadClass().query_region(ICRS_COORDS, radius=None) with pytest.raises(ValueError, match="Mismatch between radii of length 3 " "and center coordinates of length 2."): simbad.SimbadClass().query_region(multicoords, radius=[1, 2, 3] * u.deg) + centers = SkyCoord([0] * 10001, [0] * 10001, unit="deg", frame="icrs") + with pytest.raises(LargeQueryWarning, match="For very large queries, you may receive a timeout error.*"): + simbad.core.Simbad.query_region(centers, radius="2m", get_adql=True) @pytest.mark.usefixtures("_mock_simbad_class") @@ -277,6 +371,10 @@ def test_query_object(): adql = simbad.core.Simbad.query_object("m [0-9]", wildcard=True, get_adql=True) end = "WHERE regexp(id, '^m +[0-9]$') = 1" assert adql.endswith(end) + # with criteria + adql = simbad.core.Simbad.query_object("NGC*", wildcard=True, criteria="otype = 'G..'", get_adql=True) + end = "AND (otype = 'G..')" + assert adql.endswith(end) # ------------------------- # Test query_tap exceptions @@ -293,6 +391,13 @@ def test_query_tap_errors(): simbad.Simbad.query_tap("'''") +@pytest.mark.usefixtures("_mock_simbad_class") +def test_query_tap_cache_call(monkeypatch): + msg = "called_cached_query_tap" + monkeypatch.setattr(simbad.core, "_cached_query_tap", lambda tap, query, maxrec: msg) + assert simbad.Simbad.query_tap("select top 1 * from basic") == msg + + # --------------------------------------------------- # Test the adql string for query_tap helper functions # --------------------------------------------------- diff --git a/astroquery/simbad/tests/test_simbad_remote.py b/astroquery/simbad/tests/test_simbad_remote.py index 08de105362..a534cd4288 100644 --- a/astroquery/simbad/tests/test_simbad_remote.py +++ b/astroquery/simbad/tests/test_simbad_remote.py @@ -67,7 +67,7 @@ def test_query_regions(self): SkyCoord.from_name('m10')]), radius=1 * u.arcmin, criteria="main_id LIKE 'M %'") # filtering on main_id to retrieve the two cone centers - assert ["M 81", "M 10"] == list(result["main_id"].data.data) + assert {"M 81", "M 10"} == set(result["main_id"].data.data) def test_query_object_ids(self): self.simbad.ROW_LIMIT = -1 diff --git a/astroquery/simbad/tests/test_utils.py b/astroquery/simbad/tests/test_utils.py index 0b3e4ad7d5..3b7cd5707e 100644 --- a/astroquery/simbad/tests/test_utils.py +++ b/astroquery/simbad/tests/test_utils.py @@ -12,7 +12,7 @@ def test_setup_package(): data = get_package_data() - assert data["astroquery.simbad.tests"] == ["data/simbad_output_options.xml"] + assert "data/simbad_output_options.xml" in data["astroquery.simbad.tests"] assert data["astroquery.simbad"] == ["data/query_criteria_fields.json"] diff --git a/docs/simbad/simbad.rst b/docs/simbad/simbad.rst index 24672e3f60..40c5d6902c 100644 --- a/docs/simbad/simbad.rst +++ b/docs/simbad/simbad.rst @@ -456,31 +456,31 @@ The list of possible options is printed with: >>> from astroquery.simbad import Simbad >>> Simbad.list_output_options()[["name", "description"]] -
idsall names concatenated with pipemesDiameterCollection of stellar diameters. table
otypedefall names and definitions for the object typesmesPMCollection of proper motions. table
identIdentifiers of an astronomical objectmesISOInfrared Space Observatory (ISO) observing log. table
fluxMagnitude/Flux information about an astronomical objectmesSpTCollection of spectral types. table
table
has_refAssociations between astronomical objects and their bibliographic referencesidentIdentifiers of an astronomical object table
mesDistanceCollection of distances (pc, kpc or Mpc) by several means.fluxMagnitude/Flux information about an astronomical object table
mesDiameterCollection of stellar diameters.mesPLXCollection of trigonometric parallaxes. table
mesFe_hCollection of metallicity, as well as Teff, logg for stars.otypedefall names and definitions for the object types table
mesISOInfrared Space Observatory (ISO) observing log.mesDistanceCollection of distances (pc, kpc or Mpc) by several means. table
mesIUEInternational Ultraviolet Explorer observing log.otypesList of all object types associated with an object table
mesPLXCollection of trigonometric parallaxes.mesVarCollection of stellar variability types and periods. table
mesPMCollection of proper motions.mesXmmXMM observing log. table
mesRotStellar Rotational Velocities.mesVelocitiesCollection of HRV, Vlsr, cz and redshifts. table
mesVarCollection of stellar variability types and periods.has_refAssociations between astronomical objects and their bibliographic references table
mesVelocitiesCollection of HRV, Vlsr, cz and redshifts.mesRotStellar Rotational Velocities. table
mesXmmXMM observing log.biblioBibliographytable
idsall names concatenated with pipe table
table
biblioBibliographymesIUEInternational Ultraviolet Explorer observing log. table
alltypesall object types concatenated with pipemesFe_hCollection of metallicity, as well as Teff, logg for stars. table
otypesList of all object types associated with an objectalltypesall object types concatenated with pipe table
mesSpTCollection of spectral types.basicGeneral data about an astronomical object table
dimmain fields related to object dimensions: major and minor axis, angle and inclinationmajor and minor axis, angle and inclination bundle of basic columns
- name ... - object ... - --------------- ... - ids ... - otypedef ... - ident ... - flux ... - allfluxes ... - has_ref ... - mesDistance ... - mesDiameter ... - mesFe_h ... - mesISO ... - ... ... - vlsr_min ... - vlsr_wavelength ... - coordinates ... - dim ... - dimensions ... - morphtype ... - parallax ... - propermotions ... - sp ... - velocity ... +
+ name description + object object + --------------- ---------------------------------------------------------- + mesDiameter Collection of stellar diameters. + mesPM Collection of proper motions. + mesISO Infrared Space Observatory (ISO) observing log. + mesSpT Collection of spectral types. + allfluxes all flux/magnitudes U,B,V,I,J,H,K,u_,g_,r_,i_,z_ + ident Identifiers of an astronomical object + flux Magnitude/Flux information about an astronomical object + mesPLX Collection of trigonometric parallaxes. + otypedef all names and definitions for the object types + mesDistance Collection of distances (pc, kpc or Mpc) by several means. + ... ... + vlsr_min Minimum for the mean value of the LSR velocity + vlsr_wavelength Wavelength class for the origin of the LSR velocity + coordinates all fields related with coordinates + dim major and minor axis, angle and inclination + dimensions all fields related to object dimensions + morphtype all fields related to the morphological type + parallax all fields related to parallaxes + propermotions all fields related with the proper motions + sp all fields related with the spectral type + velocity all fields related with radial velocity and redshift Additional criteria ------------------- diff --git a/docs/simbad/simbad_evolution.rst b/docs/simbad/simbad_evolution.rst index e057f93d7c..6af2796fb0 100644 --- a/docs/simbad/simbad_evolution.rst +++ b/docs/simbad/simbad_evolution.rst @@ -70,22 +70,23 @@ See for example: >>> # we add the main type and all the types that have historically been attributed to the object >>> simbad.add_to_output("otype", "alltypes") >>> result = simbad.query_catalog("M", criteria=CriteriaTranslator.parse(old_criteria)) + >>> result.sort("catalog_id") >>> result[["main_id", "catalog_id", "otype", "otypes"]]
- main_id catalog_id otype otypes + main_id catalog_id otype otypes object object object object --------- ---------- ------ ---------------------------------------- - M 27 M 27 PN *|G|HS?|IR|PN|UV|WD*|WD?|X|blu + M 1 M 1 SNR HII|IR|Psr|Rad|SNR|X|gam M 24 M 24 As* As*|Cl*|GNe + M 27 M 27 PN *|G|HS?|IR|PN|UV|WD*|WD?|X|blu M 40 M 40 ? ? - M 78 M 78 RNe C?*|Cl*|ISM|RNe - NGC 6994 M 73 err Cl*|err - M 43 M 43 HII HII|IR|Rad M 42 M 42 HII C?*|Cl*|HII|OpC|Rad|X - M 1 M 1 SNR HII|IR|Rad|SNR|X|gam + M 43 M 43 HII HII|IR|Rad + M 57 M 57 PN *|HS?|IR|PN|Rad|WD*|WD?|blu + NGC 6994 M 73 err Cl*|err M 76 M 76 PN *|IR|PN|Rad|WD* + M 78 M 78 RNe C?*|Cl*|ISM|RNe M 97 M 97 PN *|HS?|IR|NIR|Opt|PN|Rad|UV|WD*|WD?|X|blu - M 57 M 57 PN *|HS?|IR|PN|Rad|WD*|WD?|blu And we indeed get objects from the Messier catalog (as `~astroquery.simbad.SimbadClass.query_catalog` is meant to return), but with the additional criteria that these objects should be neither galaxies