Skip to content

Commit 91a2ec2

Browse files
authored
Merge pull request #44 from lsst-dm/tickets/DM-51564
DM-51564: Add TIMESYS and COOSYS to VOTable response
2 parents 3320214 + 43cceaa commit 91a2ec2

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

doc/changes/DM-51564.misc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added ``COOSYS`` and ``TIMESYS`` references to the VOTable fields.

python/lsst/dax/obscore/obscore_exporter.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@
2929
from functools import cache
3030
from typing import Any
3131

32-
import astropy.io.votable
33-
import astropy.table
32+
import astropy.io.votable.tree
3433
import felis.datamodel
3534
import pyarrow
3635
import sqlalchemy
@@ -319,15 +318,43 @@ def to_votable(self, limit: int | None = None) -> astropy.io.votable.tree.VOTabl
319318
if doc := getattr(column, "doc"): # noqa
320319
extra_descriptions[name] = doc
321320

322-
votable = astropy.io.votable.tree.VOTableFile()
323-
resource = astropy.io.votable.tree.Resource()
321+
# Astropy <= 7.1 has a bug whereby it internally does not know its
322+
# own version and so disallows some options. For now we have to use
323+
# an internal API to assign the internal config. Otherwise certain
324+
# elements can not be specified.
325+
# Being fixed in https://github.com/astropy/astropy/pull/18366
326+
votable = astropy.io.votable.tree.VOTableFile(version="1.5")
327+
votable_config = votable._get_version_checks()
328+
resource = astropy.io.votable.tree.Resource(config=votable_config)
329+
coosys_id = "coosys"
330+
resource.coordinate_systems.append(
331+
astropy.io.votable.tree.CooSys(
332+
system="ICRS", refposition="TOPOCENTER", ID=coosys_id, config=votable_config
333+
)
334+
)
335+
timesys_id = "timesys"
336+
resource.time_systems.append(
337+
astropy.io.votable.tree.TimeSys(
338+
timeorigin="MJD-origin",
339+
timescale="UTC",
340+
refposition="TOPOCENTER",
341+
ID=timesys_id,
342+
config=votable_config,
343+
)
344+
)
324345
votable.resources.append(resource)
325346

326347
fields = []
327348
for arrow_field in self.schema:
328349
if arrow_field.name in obscore_columns:
329350
ffield = obscore_columns[arrow_field.name]
330351
votable_datatype = felis.datamodel.FelisType.felis_type(ffield.datatype.value).votable_name
352+
refargs = {}
353+
if ivoa_ucd := ffield.ivoa_ucd:
354+
if ivoa_ucd.startswith("pos.eq") or ivoa_ucd.startswith("pos.outline"):
355+
refargs["ref"] = coosys_id
356+
elif ivoa_ucd.startswith("time.start") or ivoa_ucd.startswith("time.end"):
357+
refargs["ref"] = timesys_id
331358
field = astropy.io.votable.tree.Field(
332359
votable,
333360
name=ffield.name,
@@ -336,6 +363,7 @@ def to_votable(self, limit: int | None = None) -> astropy.io.votable.tree.VOTabl
336363
unit=ffield.ivoa_unit,
337364
ucd=ffield.ivoa_ucd,
338365
utype=ffield.votable_utype,
366+
**refargs,
339367
)
340368
if ffield.description:
341369
field.description = ffield.description
@@ -377,7 +405,9 @@ def to_votable(self, limit: int | None = None) -> astropy.io.votable.tree.VOTabl
377405
field.description = extra_descriptions[arrow_field.name]
378406
fields.append(field)
379407

380-
table0 = astropy.io.votable.tree.TableElement(votable)
408+
# Config parameter is needed until upstream inherits the config from
409+
# the VOTableFile. Without this BINARY2 will not be allowed if needed.
410+
table0 = astropy.io.votable.tree.TableElement(votable, config=votable_config)
381411
resource.tables.append(table0)
382412
table0.fields.extend(fields)
383413

0 commit comments

Comments
 (0)