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
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ svo_fps
^^^^^^^

- Add ``get_filter_metadata`` to allow retrieval of filter metadata. [#3528]
- Add ``get_zeropoint`` to allow retrieval of filter zeropoints and allow kwarg passing to ``get_filter_metadata``. [#3545]

heasarc
^^^^^^^
Expand Down
62 changes: 61 additions & 1 deletion astroquery/svo_fps/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def get_filter_index(self, wavelength_eff_min, wavelength_eff_max, **kwargs):
"succeed. Try increasing the timeout limit if a large range is needed."
)

def get_filter_metadata(self, filter_id, *, cache=True, timeout=None):
def get_filter_metadata(self, filter_id, *, cache=True, timeout=None, **kwargs):
"""Get metadata/parameters for the requested Filter ID from SVO

Parameters
Expand All @@ -122,13 +122,26 @@ def get_filter_metadata(self, filter_id, *, cache=True, timeout=None):
See :ref:`caching documentation <astroquery_cache>`.
timeout : int
Timeout in seconds. If not specified, defaults to ``conf.timeout``.
kwargs : dict
Appended to the ``query`` dictionary sent to SVO.

Returns
-------
params : dict
Dictionary of VOTable PARAM names and values.
"""
query = {'ID': filter_id, 'VERB': 0}
query.update(kwargs)

bad_params = [param for param in query if param not in QUERY_PARAMETERS]
if bad_params:
raise InvalidQueryError(
f"parameter{'s' if len(bad_params) > 1 else ''} "
f"{', '.join(bad_params)} {'are' if len(bad_params) > 1 else 'is'} "
f"invalid. For a description of valid query parameters see "
"https://svo2.cab.inta-csic.es/theory/fps/index.php?mode=voservice"
)

response = self._request("GET", self.SVO_MAIN_URL, params=query,
timeout=timeout or self.TIMEOUT,
cache=cache)
Expand All @@ -143,6 +156,53 @@ def get_filter_metadata(self, filter_id, *, cache=True, timeout=None):
params[param.name] = param.value
return params

def get_zeropoint(self, filter_id, mag_system='Vega', **kwargs):
"""
Get the zero point for a specififed filter in a specified system.

This is a highly-specific downselection of the metadata returned by
`get_filter_metadata`; the full metadata includes the zero point with
``Vega`` as the default system.

Parameters
----------
filter_id : str
Filter ID in the format SVO specifies it: 'facilty/instrument.filter'.
This is returned by `get_filter_list` and `get_filter_index` as the
``filterID`` column.
mag_system : str
The magnitude system for which to return the zero point.
kwargs : dict
Appended to the ``query`` dictionary sent to SVO.

Examples
--------
>>> from astroquery.svo_fps import SvoFps # doctest: +REMOTE_DATA
>>> SvoFps.get_zeropoint(filter_id='2MASS/2MASS.J', mag_system='AB') # doctest: +REMOTE_DATA
{'MagSys': 'AB',
'ZeroPoint': <Quantity 3631. Jy>,
'ZeroPointUnit': 'Jy',
'ZeroPointType': 'Pogson'}
>>> SvoFps.get_filter_metadata(filter_id='2MASS/2MASS.J', PhotCalID='2MASS/2MASS.J/AB') # doctest: +REMOTE_DATA
{'FilterProfileService': 'ivo://svo/fps',
'filterID': '2MASS/2MASS.J',
...
'PhotCalID': '2MASS/2MASS.J/AB',
'MagSys': 'AB',
'ZeroPoint': <Quantity 3631. Jy>,
'ZeroPointUnit': 'Jy',
'ZeroPointType': 'Pogson'}

"""
metadata = self.get_filter_metadata(filter_id=filter_id,
PhotCalID=f'{filter_id}/{mag_system}', **kwargs)

zeropoint_keys = ['MagSys', 'ZeroPoint', 'ZeroPointUnit', 'ZeroPointType']

zp = {key: metadata[key] for key in zeropoint_keys if key in metadata}

return zp

def get_transmission_data(self, filter_id, **kwargs):
"""Get transmission data for the requested Filter ID from SVO

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<VOTABLE version="1.1" xsi:schemaLocation="http://www.ivoa.net/xml/VOTable/v1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<INFO name="QUERY_STATUS" value="OK"/>
<RESOURCE type="results">
<TABLE utype="photdm:PhotometryFilter.transmissionCurve.spectrum">
<PARAM name="FilterProfileService" value="ivo://svo/fps" ucd="meta.ref.ivorn" utype="PhotometryFilter.fpsIdentifier" datatype="char" arraysize="*"/>
<PARAM name="filterID" value="2MASS/2MASS.H" ucd="meta.id" utype="photdm:PhotometryFilter.identifier" datatype="char" arraysize="*"/>
<PARAM name="WavelengthUnit" value="Angstrom" ucd="meta.unit" utype="PhotometryFilter.SpectralAxis.unit" datatype="char" arraysize="*"/>
<PARAM name="Description" value="2MASS H" ucd="meta.note" utype="photdm:PhotometryFilter.description" datatype="char" arraysize="*"/>
<PARAM name="WavelengthEff" value="16620" unit="Angstrom" ucd="em.wl.effective" datatype="float" >
<DESCRIPTION>Manually specified. See reference</DESCRIPTION>
</PARAM>
<PARAM name="ZeroPoint" value="1024" unit="Jy" ucd="phot.flux.density" utype="photdm:PhotCal.ZeroPoint.Flux.value" datatype="float" />
<PARAM name="PhotCalID" value="2MASS/2MASS.H/Vega" ucd="meta.id" utype="photdm:PhotCal.identifier" datatype="char" arraysize="*"/>
<PARAM name="MagSys" value="Vega" ucd="meta.code" utype="photdm:PhotCal.MagnitudeSystem.type" datatype="char" arraysize="*"/>
<PARAM name="ZeroPointUnit" value="Jy" ucd="meta.unit" utype="photdm:PhotCal.ZeroPoint.Flux.unit" datatype="char" arraysize="*"/>
<PARAM name="ZeroPointType" value="Pogson" ucd="meta.code" utype="photdm:PhotCal.ZeroPoint.type" datatype="char" arraysize="*"/>
<DATA>
<TABLEDATA>
</TABLEDATA>
</DATA>
</TABLE>
</RESOURCE>
</VOTABLE>
19 changes: 18 additions & 1 deletion astroquery/svo_fps/tests/test_svo_fps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@

DATA_FILES = {'filter_index': 'svo_fps_WavelengthEff_min=12000_WavelengthEff_max=12100.xml',
'transmission_data': 'svo_fps_ID=2MASS.2MASS.H.xml',
'filter_list': 'svo_fps_Facility=Keck_Instrument=NIRC2.xml'
'filter_list': 'svo_fps_Facility=Keck_Instrument=NIRC2.xml',
'zeropoint': 'svo_fps_PhotCalID=2MASS.2MASS.H.Vega.xml',
}
TEST_LAMBDA = 12000
TEST_FILTER_ID = '2MASS/2MASS.H'
TEST_FACILITY = 'Keck'
TEST_INSTRUMENT = 'NIRC2'
TEST_MAG_SYSTEM = 'Vega'


def data_path(filename):
Expand All @@ -35,6 +37,10 @@ def get_mockreturn(method, url, params=None, timeout=10, cache=None, **kwargs):
and (params['WavelengthEff_min'] == TEST_LAMBDA
and params['WavelengthEff_max'] == TEST_LAMBDA+100)):
filename = data_path(DATA_FILES['filter_index'])
elif ('PhotCalID' in params
and params.get('ID') == TEST_FILTER_ID
and params['PhotCalID'] == f'{TEST_FILTER_ID}/{TEST_MAG_SYSTEM}'):
filename = data_path(DATA_FILES['zeropoint'])
elif 'ID' in params and params['ID'] == TEST_FILTER_ID:
filename = data_path(DATA_FILES['filter_index'])
elif 'Facility' in params and (params['Facility'] == TEST_FACILITY
Expand Down Expand Up @@ -84,6 +90,17 @@ def test_get_filter_list(patch_get):
assert 'filterID' in table.colnames


def test_get_zeropoint(patch_get):
zp = SvoFps.get_zeropoint(TEST_FILTER_ID, mag_system=TEST_MAG_SYSTEM)
assert 'ZeroPoint' in zp
assert 'MagSys' in zp
assert zp['MagSys'] == TEST_MAG_SYSTEM
assert 'ZeroPointType' in zp
assert zp['ZeroPointType'] == 'Pogson'
assert 'ZeroPointUnit' in zp
assert zp['ZeroPoint'].unit == u.Jy


def test_invalid_query(patch_get):
msg = r"^parameter bad_param is invalid\. For a description of valid query "
with pytest.raises(InvalidQueryError, match=msg):
Expand Down
17 changes: 17 additions & 0 deletions astroquery/svo_fps/tests/test_svo_fps_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ def test_get_filter_list(self, test_facility, test_instrument):
# Check if column for Filter ID (named 'filterID') exists in table
assert 'filterID' in table.colnames

@pytest.mark.parametrize('test_filter_id, mag_system, expected_zp_jy', [
('2MASS/2MASS.J', 'Vega', 1594.0),
('2MASS/2MASS.J', 'AB', 3631.0),
])
def test_get_zeropoint(self, test_filter_id, mag_system, expected_zp_jy):
zp = SvoFps.get_zeropoint(test_filter_id, mag_system=mag_system)
# Check all expected keys are present
assert 'ZeroPoint' in zp
assert 'MagSys' in zp
assert 'ZeroPointType' in zp
assert 'ZeroPointUnit' in zp
# Check the magnitude system matches what was requested
assert zp['MagSys'] == mag_system
# Check zero point has the right unit and an approximately correct value
assert zp['ZeroPoint'].unit == u.Jy
assert abs(zp['ZeroPoint'].value - expected_zp_jy) < 10.0

def test_query_parameter_names(self):
# Checks if `QUERY_PARAMETERS` is up to date.
query = {"FORMAT": "metadata"}
Expand Down
Loading