taldcroft/asciitable

CDS writer (from atpy)

Closed this issue · 6 comments

I've been reading through the asciitable source trying to figure out how to make myself a writer... but I'm stuck at an early point; how do you access the column information that asciitable reads? The reader seems to return only a numpy record array, but more data is grabbed into a header... what happens to that header? Is it accessible at all if asciitable.read(filename) is used to access the table?

Look in ui.write() to see how this works. The upshot is that in order to do any write process the code always reads the user-supplied table using the Memory reader to establish all the information (like columns) that are needed for writing. That info is available in the "table" that gets passed to the writer, e.g. table.cols which is a list of Column objects.

See also the Latex writer, which is somewhat complex but should illustrate the mechanics of writing a full featured writer.

I'm still having a little trouble. I'd like to be able to play with the structures interactively, so I'm doing the following:
ipactab = asciitable.read('/Users/adam/work/catalogs/bgps_ipac.txt',guess='ipac')

However, ipactab does not have a 'cols' attribute:
hasattr(ipactab,"cols")

I can access some of the relevant information via:
ipactab.dtype.descr

but there is apparently no way to access the header attribute of the BaseReader class, since that class is never returned by asciitable.read. For that matter, the .write attribute is inaccessible, since I'm only given a numpy recordarray. Am I missing something?

To deal with writing you need to get into the concept of asciitable Reader objects instead of using the high-level read() method. The Reader object has a read() method that actually does the reading into a "table" attribute (which is what would get returned by ui.read()).

import asciitable 
ipac_reader = asciitable.get_reader(Reader=asciitable.Ipac)
ipac_data = ipac_reader.read('t/ipac.dat')
print ipac_reader.cols
print [col.name for col in ipac_reader.cols]
print ipac_reader.table  # This is what got read from "t/ipac.dat"

When you write with the Ipac.write() method it will be passed a Reader object like ipac_reader, and that's how it gets all the metadata like columns. See line 846 of core.py (the write() method) which is what your Ipac class will be overiding. Sorry for the confusing use of "table": as a attribute of a Reader object it is a numpy structured array (without metadata), but as an arg to a write() method it is a full Reader object with metadata. Also the term "Reader" object is historic from when asciitable only read tables. Now a Reader object is really more like a Table object since it can read or write tables.

Got it, thanks... I'll be able to continue working from here. I'm not closing the issue since the original topic is the CDS writer.

It's off topic, but a suggestion: it might make sense to overload the "table" recordarray and add the header and write attributes so they are directly accessible from the object returned by asciitable.read.

I've thought about this overloading of the record array to add asciitable metadata. It would definitely be a good thing, I just got worried about how to do this in a way that is transparent to any downstream application.

New development will be done in astropy.io.ascii.