Skip to content

Commit b40b22b

Browse files
committed
Support reading and writing multidimensional columns in ECSV format
1 parent 32019d7 commit b40b22b

13 files changed

Lines changed: 656 additions & 370 deletions

File tree

‎astropy/io/ascii/core.py‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@
3939
FAST_CLASSES = {}
4040

4141

42+
def _check_multidim_table(table, max_ndim=1):
43+
"""Check that ``table`` has only columns with ndim <= ``max_ndim``
44+
45+
Currently ECSV is the only built-in format that supports output of arbitrary
46+
N-d columns, but HTML supports 2-d.
47+
"""
48+
# Check for N-d columns
49+
nd_names = [col.info.name for col in table.itercols() if len(col.shape) > max_ndim]
50+
if nd_names:
51+
raise ValueError(f'column(s) {",".join(nd_names)} with dimension > {max_ndim} '
52+
"cannot be be written with this format, try using 'ecsv' "
53+
"(Enhanced CSV) format")
54+
55+
4256
class CsvWriter:
4357
"""
4458
Internal class to replace the csv writer ``writerow`` and ``writerows``
@@ -1221,6 +1235,20 @@ def __init__(self):
12211235
self.meta = OrderedDict(table=OrderedDict(),
12221236
cols=OrderedDict())
12231237

1238+
def _check_multidim_table(self, table, max_ndim=1):
1239+
"""Check that ``table`` has only 1-d columns.
1240+
1241+
If a reader class supports N-d columns then override this method.
1242+
1243+
Parameters
1244+
----------
1245+
table : `~astropy.table.Table`
1246+
Input table.
1247+
max_ndim : int
1248+
Max allowed number of dimensions (default=1)
1249+
"""
1250+
_check_multidim_table(table, max_ndim)
1251+
12241252
def read(self, table):
12251253
"""Read the ``table`` and return the results in a format determined by
12261254
the ``outputter`` attribute.
@@ -1409,6 +1437,10 @@ def write(self, table):
14091437
# only used by ECSV and is otherwise just a pass-through.
14101438
table = self.update_table_data(table)
14111439

1440+
# Check that table has only 1-d columns. Classes that support output of
1441+
# N-d columns can override this method.
1442+
self._check_multidim_table(table)
1443+
14121444
# Now use altered columns
14131445
new_cols = list(table.columns.values())
14141446
# link information about the columns to the writer object (i.e. self)

‎astropy/io/ascii/ecsv.py‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,6 @@ def write(self, lines):
5454
if self.splitter.delimiter not in DELIMITERS:
5555
raise ValueError('only space and comma are allowed for delimiter in ECSV format')
5656

57-
for col in self.cols:
58-
if len(getattr(col, 'shape', ())) > 1:
59-
raise ValueError(
60-
f"ECSV format does not support multidimensional column '{col.info.name}'\n"
61-
'One can filter out such columns using:\n'
62-
'names = [name for name in tbl.colnames if len(tbl[name].shape) <= 1]\n'
63-
'tbl[names].write(...)')
64-
6557
# Now assemble the header dict that will be serialized by the YAML dumper
6658
header = {'cols': self.cols, 'schema': 'astropy-2.0'}
6759

‎astropy/io/ascii/fastbasic.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ def write(self, table, output):
169169
def _write(self, table, output, default_kwargs,
170170
header_output=True, output_types=False):
171171

172+
core._check_multidim_table(table)
173+
172174
write_kwargs = {'delimiter': self.delimiter,
173175
'quotechar': self.quotechar,
174176
'strip_whitespace': self.strip_whitespace_fields,

‎astropy/io/ascii/html.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ def write(self, table):
344344
"""
345345
Return data in ``table`` converted to HTML as a list of strings.
346346
"""
347+
# Check that table has only 1-d or 2-d columns. Above that fails.
348+
self._check_multidim_table(table, max_ndim=2)
349+
347350
cols = list(table.columns.values())
348351

349352
self.data.header.cols = cols

‎astropy/io/ascii/ipac.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,9 @@ def write(self, table):
473473

474474
core._apply_include_exclude_names(table, self.names, self.include_names, self.exclude_names)
475475

476+
# Check that table has only 1-d columns.
477+
self._check_multidim_table(table)
478+
476479
# Now use altered columns
477480
new_cols = list(table.columns.values())
478481
# link information about the columns to the writer object (i.e. self)

0 commit comments

Comments
 (0)