Before astropy v7.0.0, I was able to write a table to 'votable' format which has units Jy/beam.
e.g. in astropy v6.1.4:
In [12]: a['col_flux_peak'].unit
Out[12]: Unit("mJy / beam")
In [13]: a.write('~/test.xml',format='votable')
Why has this behaviour changed? And can it be updated such that Jy/beam units are allowed again?
In [11]: a['col_flux_peak'].unit
Out[11]: Unit("mJy / beam")
In [12]: a.write('~/test.xml',format='votable')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[12], line 1
----> 1 a.write('~/test.xml',format='votable')
File /usr/local/lib/python3.12/site-packages/astropy/table/connect.py:130, in TableWrite.__call__(self, serialize_method, *args, **kwargs)
128 instance = self._instance
129 with serialize_method_as(instance, serialize_method):
--> 130 self.registry.write(instance, *args, **kwargs)
File /usr/local/lib/python3.12/site-packages/astropy/io/registry/core.py:386, in UnifiedOutputRegistry.write(self, data, format, *args, **kwargs)
381 format = self._get_valid_format(
382 "write", data.__class__, path, fileobj, args, kwargs
383 )
385 writer = self.get_writer(format, data.__class__)
--> 386 return writer(data, *args, **kwargs)
File /usr/local/lib/python3.12/site-packages/astropy/io/votable/connect.py:176, in write_table_votable(input, output, table_id, overwrite, tabledata_format)
173 table_file = from_table(input, table_id=table_id)
175 # Write out file
--> 176 table_file.to_xml(output, tabledata_format=tabledata_format)
File /usr/local/lib/python3.12/site-packages/astropy/io/votable/tree.py:4384, in VOTableFile.to_xml(self, fd, compressed, tabledata_format, _debug_python_based_parser, _astropy_version)
4382 for element_set in element_sets:
4383 for element in element_set:
-> 4384 element.to_xml(w, **kwargs)
File /usr/local/lib/python3.12/site-packages/astropy/io/votable/tree.py:3991, in Resource.to_xml(self, w, **kwargs)
3988 elm.to_xml(w, **kwargs)
3990 for elm in self.tables:
-> 3991 elm.to_xml(w, **kwargs)
3993 for elm in self.resources:
3994 if elm.type != "meta":
File /usr/local/lib/python3.12/site-packages/astropy/io/votable/tree.py:3282, in TableElement.to_xml(self, w, **kwargs)
3280 for element_set in (self.fields, self.params, self.groups, self.links):
3281 for element in element_set:
-> 3282 element.to_xml(w, **kwargs)
3283 elif kwargs["version_1_2_or_later"]:
3284 index = list(self._votable.iter_tables()).index(self)
File /usr/local/lib/python3.12/site-packages/astropy/io/votable/tree.py:1678, in Field.to_xml(self, w, **kwargs)
1676 attrib = w.object_attrs(self, self._attr_list)
1677 if "unit" in attrib:
-> 1678 attrib["unit"] = self.unit.to_string("cds")
1679 with w.tag(self._element_name, attrib=attrib):
1680 if self.description is not None:
File /usr/local/lib/python3.12/site-packages/astropy/units/core.py:762, in UnitBase.to_string(self, format, **kwargs)
720 r"""Output the unit in the given format as a string.
721
722 Parameters
(...)
759 s
760 """
761 f = unit_format.get_format(format)
--> 762 return f.to_string(self, **kwargs)
File /usr/local/lib/python3.12/site-packages/astropy/units/format/cds.py:303, in CDS.to_string(cls, unit, fraction)
298 @classmethod
299 def to_string(
300 cls, unit: UnitBase, fraction: bool | Literal["inline"] = False
301 ) -> str:
302 # Remove units that aren't known to the format
--> 303 unit = cls._decompose_to_known_units(unit)
305 if not unit.bases:
306 if unit.scale == 1:
File /usr/local/lib/python3.12/site-packages/astropy/units/format/generic.py:640, in Generic._decompose_to_known_units(cls, unit)
633 """
634 Partially decomposes a unit so it is only composed of units that
635 are "known" to a given format.
636 """
637 if isinstance(unit, core.CompositeUnit):
638 return core.CompositeUnit(
639 unit.scale,
--> 640 [cls._decompose_to_known_units(base) for base in unit.bases],
641 unit.powers,
642 _error_check=False,
643 )
644 if isinstance(unit, core.NamedUnit):
645 try:
File /usr/local/lib/python3.12/site-packages/astropy/units/format/generic.py:646, in Generic._decompose_to_known_units(cls, unit)
644 if isinstance(unit, core.NamedUnit):
645 try:
--> 646 cls._get_unit_name(unit)
647 except ValueError:
648 if isinstance(unit, core.Unit):
File /usr/local/lib/python3.12/site-packages/astropy/units/format/generic.py:585, in Generic._get_unit_name(cls, unit)
582 @classmethod
583 def _get_unit_name(cls, unit: NamedUnit) -> str:
584 name = unit._get_format_name(cls.name)
--> 585 cls._validate_unit(name)
586 return name
File /usr/local/lib/python3.12/site-packages/astropy/units/format/generic.py:592, in Generic._validate_unit(cls, unit, detailed_exception)
590 if unit not in cls._units:
591 if detailed_exception:
--> 592 raise ValueError(
593 f"Unit '{unit}' not supported by the {cls.__name__} standard. "
594 + cls._did_you_mean_units(unit)
595 )
596 raise ValueError()
597 if unit in cls._deprecated_units:
ValueError: Unit 'beam' not supported by the CDS standard.
Expect writing table to 'votable' format with units Jy/beam to work.
Take any table with units Jy/beam in any of the columns and try to write it to votable format.
from astropy.table import Table
import astropy.units as u
b = Table()
b['flux'] = [5]
b['flux'].unit = u.Jy/u.beam
b.write('~/test.xml',format='votable')
### Versions
```python
import astropy
try:
astropy.system_info()
except AttributeError:
import platform; print(platform.platform())
import sys; print("Python", sys.version)
import astropy; print("astropy", astropy.__version__)
import numpy; print("Numpy", numpy.__version__)
import erfa; print("pyerfa", erfa.__version__)
try:
import scipy
print("Scipy", scipy.__version__)
except ImportError:
print("Scipy not installed")
try:
import matplotlib
print("Matplotlib", matplotlib.__version__)
except ImportError:
print("Matplotlib not installed")
platform
--------
platform.platform() = 'Linux-4.18.0-553.27.1.el8_10.x86_64-x86_64-with-glibc2.36'
platform.version() = '#1 SMP Tue Nov 5 04:50:16 EST 2024'
platform.python_version() = '3.12.2'
packages
--------
astropy 7.0.0
numpy 1.26.4
scipy 1.14.1
matplotlib 3.9.3
pandas 2.2.3
pyerfa 2.0.1.5
Description
Before astropy v7.0.0, I was able to write a table to 'votable' format which has units Jy/beam.
e.g. in astropy v6.1.4:
However, as of astropy v7.0.0, this raises an error (full trace at bottom)
ValueError: Unit 'beam' not supported by the CDS standard.Why has this behaviour changed? And can it be updated such that Jy/beam units are allowed again?
Thanks in advance,
Erik
Expected behavior
Expect writing table to 'votable' format with units Jy/beam to work.
How to Reproduce
Take any table with units Jy/beam in any of the columns and try to write it to votable format.