Skip to content

Commit

Permalink
Merge pull request #594 from duytnguyendtn/radquantity
Browse files Browse the repository at this point in the history
Support Astropy Quantity as radius arg for Registry SkyCoord Spatial constraint
  • Loading branch information
bsipocz committed Oct 14, 2024
1 parent 3aaa8a1 commit d795cb7
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
4 changes: 1 addition & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ Bug Fixes
- path separators are no longer taken over from image titles to file
system paths. [#557]


1.5.3 (unreleased)
==================
- Registry Spatial constraint now supports Astropy Quantities for the radius argument [#594]

- Added `'sia1'` as servicetype for registry searches. [#583]

Expand Down
31 changes: 24 additions & 7 deletions docs/registry/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,30 @@ And to look for tap resources *in* a specific cone, you would do

>>> from astropy.coordinates import SkyCoord
>>> registry.search(registry.Freetext("Wolf-Rayet"),
... registry.Spatial((SkyCoord("23d +3d"), 3), intersect="enclosed")) # doctest: +IGNORE_OUTPUT
<DALResultsTable length=1>
ivoid ...
...
object ...
---------------------------- ...
ivo://cds.vizier/j/aj/166/68 ...
... registry.Spatial((SkyCoord("23d +3d"), 3), intersect="enclosed"))
<DALResultsTable length=2>
ivoid ...
...
object ...
------------------------------- ...
ivo://cds.vizier/j/a+a/688/a104 ...
ivo://cds.vizier/j/aj/166/68 ...

Astropy Quantities are also supported for the radius angle of a SkyCoord-defined circular region:

.. doctest-remote-data::

>>> from astropy.coordinates import SkyCoord
>>> from astropy import units as u
>>> registry.search(registry.Freetext("Wolf-Rayet"),
... registry.Spatial((SkyCoord("23d +3d"), 180*u.Unit('arcmin')), intersect="enclosed"))
<DALResultsTable length=2>
ivoid ...
...
object ...
------------------------------- ...
ivo://cds.vizier/j/a+a/688/a104 ...
ivo://cds.vizier/j/aj/166/68 ...

Where ``intersect`` can take the following values:
* 'covers' is the default and returns resources that cover the geometry provided,
Expand Down
15 changes: 13 additions & 2 deletions pyvo/registry/rtcons.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,10 @@ class Spatial(Constraint):
are interpreted in degrees)::
>>> resources = registry.Spatial((SkyCoord("23d +3d"), 3))
Or you can provide the radius angle as an Astropy Quantity:
>>> resources = registry.Spatial((SkyCoord("23d +3d"), 1*u.rad))
"""
_keyword = "spatial"
_extra_tables = ["rr.stc_spatial"]
Expand All @@ -631,7 +635,7 @@ def __init__(self, geom_spec, order=6, intersect="covers"):
as a DALI point, a 3-sequence as a DALI circle, a 2n sequence
as a DALI polygon. Additionally, strings are interpreted
as ASCII MOCs, SkyCoords as points, and a pair of a
SkyCoord and a float as a circle. Other types (proper
SkyCoord and a float or Quantity as a circle. Other types (proper
geometries or MOCPy objects) might be supported in the
future.
order : int, optional
Expand Down Expand Up @@ -661,9 +665,16 @@ def tomoc(s):

elif len(geom_spec) == 2:
if isinstance(geom_spec[0], SkyCoord):
# If radius given is astropy quantity, then convert to degrees
if isinstance(geom_spec[1], u.Quantity):
if geom_spec[1].unit.physical_type != 'angle':
raise ValueError("Radius quantity is not of type angle.")
radius = geom_spec[1].to(u.deg).value
else:
radius = geom_spec[1]
geom = tomoc(format_function_call("CIRCLE",
[geom_spec[0].ra.value, geom_spec[0].dec.value,
geom_spec[1]]))
radius]))
else:
geom = tomoc(format_function_call("POINT", geom_spec))

Expand Down
9 changes: 9 additions & 0 deletions pyvo/registry/tests/test_rtcons.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ def test_SkyCoord_Circle(self):
assert cons.get_search_condition(FAKE_GAVO) == "1 = CONTAINS(MOC(6, CIRCLE(3.0, -30.0, 3)), coverage)"
assert cons._extra_tables == ["rr.stc_spatial"]

def test_SkyCoord_Circle_RadiusQuantity(self):
for radius in [3*u.deg, 180*u.Unit('arcmin'), 10800*u.Unit('arcsec')]:
cons = registry.Spatial((SkyCoord(3 * u.deg, -30 * u.deg), radius))
assert cons.get_search_condition(FAKE_GAVO) == (
"1 = CONTAINS(MOC(6, CIRCLE(3.0, -30.0, 3.0)), coverage)")

with pytest.raises(ValueError, match="is not of type angle."):
cons = registry.Spatial((SkyCoord(3 * u.deg, -30 * u.deg), (1 * u.m)))

def test_enclosed(self):
cons = registry.Spatial("0/1-3", intersect="enclosed")
assert cons.get_search_condition(FAKE_GAVO) == "1 = CONTAINS(coverage, MOC('0/1-3'))"
Expand Down

0 comments on commit d795cb7

Please sign in to comment.