\documentclass[twoside,12pt]{article} \topmargin -0.5in \oddsidemargin-.15in \evensidemargin-.25in %\textheight 8.5in \textwidth 6.5in \newcommand{\exbegin}{\par\medskip} \newcommand{\exend}{\medskip\noindent} \newcommand{\exc}[2]{ \hbox to \hsize{\small\hskip .2in \parbox[t]{2.8in}{\raggedright\setlength{\parindent}{-.2in}\tt #1} \hspace{.2in} \parbox[t]{3.8in}{\raggedright\setlength{\parindent}{-.2in}\rm #2}\hss} \prevdepth=1.5pt\relax} % One line example \newcommand{\exone}[1]{\begin{center}\tt #1 \end{center}} \title{FITS Table I/O in IDL} \author{W. Landsman \\ Raytheon ITSS Co.} \date{20 May 2000} \begin{document} \maketitle \section{Introduction} This document describes how to use the procedures located in \\ http://idlastro.gsfc.nasa.gov/ftp/pro/fits\_table to read and write FITS ASCII tables and to read FITS binary tables. These procedures provide one of three methods in the IDL Astronomy Library to process FITS tables: the other two methods are to use (1) {\tt MRDFITS()/MWRFITS} which convert between FITS tables and IDL structures, and (2) the FX* procedures in \\ http://idlastro.gsfc.nasa.gov/ftp/pro/fits\_bintable/ which allow one to read and write any type of binary table. See http://idlastro.gsfc.nasa.gov/fitsio.html for further discussion of reading FITS files with IDL. This text concentrates on processing FITS ASCII tables after the data array and header has been read into IDL memory using the procedures {\tt READFITS()} or {\tt FITS\_READ}. For example, \exone{tab = READFITS('myfile.fits', h, EXT = 2) } The procedures for processing FITS tables begin with the letters `FT', and analagous procedures for reading FITS binary tables are available and begin with the letters `TB'. Note, however, that TB* procedures for {\em creating} a FITS binary table do not yet exist, so that to write FITS binary tables one must use either {\tt MWRFITS} or {\tt FXBWRITE}. Finally, for reading tables, most users will prefer to use the higher level FTAB* procedures, which operate directly on FITS files, and work transparently with either ASCII or binary tables. Each column in a FITS ASCII table is specified by a field name, TTYPEnnn, a column number, TBCOLnnn, and a FORTRAN format, TFORMnnn. Optional column descriptions include the data units, TUNITnnn, a scale factor, TBCALnnn, a zero offset, TZEROnnn, and a null string, TNULLnnn. A null string specifies the characters to be used (e.g.\ `***') to specify that data does not exist. (Note that a blank field is interpreted with a numeric format as a zero.) The most important routines can be summarized as follows. A header array and table array are read into IDL variables with {\tt READFITS} or {\tt FITS\_READ} and written to disk with {\tt WRITEFITS} or {\tt FITS\_WRITE}. {\tt FTHELP} ({\tt TBHELP}) will display table information in the header, and {\tt FTPRINT} ({\tt TBPRINT}) will print specified rows and columns. Values are read from a table into IDL variables with {\tt FTGET} ({\tt TBGET}), and inserted into a table with {\tt FTPUT}. A new header and table array is created with {\tt FTCREATE}, and a new column is added to a table with {\tt FTADDCOL}. A table can be sorted with {\tt FTSORT}. A FITS table header can be manipulated in the same manner as an FITS image header. In particular, note the procedures {\tt SXPAR}, to obtain the value of a FITS keyword, {\tt SXADDPAR}, to add a FITS keyword to a header, {\tt SXADDHIST}, to add a history record, and {\tt SXDELPAR}, to delete a FITS keyword. Fields can be specified either by their name or column number. Upper or lower case can be used when specifying field names. They are always converted to upper case before use. Row numbers start with 0, but in concordance with the FORTRAN based FITS convention, column numbers start with 1. \section{Reading, updating, and writing FITS tables} {\tt FTADDCOL,H,TAB,NAME,IDLTYPE,[TFORM,TUNIT,TSCAL,TZERO,TNULL]} \\ This routine will add a new field to a table specified by H and TAB. The name of the field should be placed in NAME. IDLTYPE specifies the IDL type of field (as in the SIZE function). For string data, IDLTYPE should be minus the string length. The remaining parameters are further optional specifications of the field. \\ {\tt FTCREATE,MAXCOLS,MAXROWS,H,TAB} \\ This routine creates an empty table H and TAB with the specified allocated size. MAXCOLS give the number of byte columns to allocate. MAXROWS give the number of allocated rows in the table. The values of MAXCOLS and MAXROWS are not critical, since subsequent procedures can always enlarge the table (at the loss of some efficiency). \\ {\tt FTDELCOL,H,TAB,FIELD} {\tt TBDELCOL,H,TAB,FIELD} \\ Procedures to delete column specified by FIELD from table with header, H, and data array, TAB. When changing the data format of a column, it is first necessary to delete the column with {\tt FTDELCOL}, and then add a new column with {\tt FTADDCOL.} \\ {\tt FTDELROW, H, TAB, ROWS} {\tt TBDELROW, H, TAB, ROWS} \\ Procedures to delete row(s) specified ROWS (scalar or vector) from a FITS table with header, H, and data array, TAB. \\ {\tt FTGET(H,TAB,FIELD,ROWS,[NULLS]) or FTGET(FT\_STR,TAB,FIELD,ROWS,[NULLS])} {\tt TBGET(H,TAB,FIELD,ROWS,[NULLS]) or TBGET(TB\_STR,TAB,FIELD,ROWS,[NULLS])} \\ Functions to extract the specified row(s) from field number (beginning with 1) or name FIELD from the table with header, H, and data, TAB. If ROWS is not supplied, or set = --1, then values for all rows are returned. If {\tt FTGET()} (or {\tt TBGET()}) are to be called multiple times, then the efficiency can be improved by first calling {\tt FTINFO (TBINFO)} to extract the header information into a structure, and then supplying this structure rather than the header to {\tt FTGET()}. \\ {\tt FTHELP,H, TEXTOUT = } {\tt TBHELP,H, TEXTOUT = } \\ These routines will print a short description of the table on the terminal. Information includes field names, units, print formats, and column numbers. Output can be directed to a disk file by setting the TEXTOUT keyword \\ {\tt FTPRINT, H, TAB,[ COLUMNS, ROWS, TEXTOUT = ]} {\tt TBPRINT, H, TAB,[ COLUMNS, ROWS, TEXTOUT = ]} \\ These routines print the specified columns in ASCII form for the table specified by H and TAB. Columns can be specified by a string array of column names, or an integer array of column numbers, or a scalar string with column names separated by commas (i.e. `colname1,colname2,...'). ROWS is an optional parameter containing a vector of row numbers to print. If not supplied, or set = --1 then all rows are printed. Output can be directed to a disk file by setting the TEXTOUT keyword. \\ {\tt FTPUT,H,TAB,FIELD,ROWS,VALUES,[NULLS]} \\ This routine updates an existing field or adds a new field to the table specified by H and TAB. FIELD is the name (or number) of the field to update or add. VALUES are the value(s) to be added to the column. If ROWS is not specified they are added sequentially beginning in row 0. If the column already exists, VALUES will automatically be converted to the correct data type for the column. If the column does not exist the column type will be determined from values. ROWS is an integer giving the starting row number to update or a vector giving arbitary row numbers to update. If ROWS is a vector, then VALUES must be a vector of the same length (one-to-one correspondence). If passed, NULLS should be the same length as VALUES and set to 1 at null value positions and 0 elsewhere. \\ {\tt FTSORT,H,TAB,FIELD or FTSORT,H,TAB,HNEW,TABNEW,FIELD} \\ Sort all columns in a table in increasing order of the value(s) specified in FIELD. If FIELD is a vector, then the first element is used for the primary sort, the second element is used for the secondary sort and so forth. (A secondary sort only takes effect when values in the primary sort field are equal.) A REVERSE keyword is available to specify that field should be sorted in descending rather than ascending order. If more than 3 parameters are supplied then a new header and table are created, otherwise the original header and table arrays are sorted. \\ \subsection{Program Level Procedures} The following procedures may be of some use but are generally not required for table manipulation. \\ {\tt FTHMOD,H,FIELD,PARAMETER,VALUE} \\ This routine modifies a parameter within a specified field of a table with a header H. FIELD can be specified either by its name or column number. PARAMETER is FITS table keyword (e.g. TTYPE, TUNIT, TNULL, TFORM, TSCAL, or TZERO) to be updated with a new value, VALUE. \\ {\tt FTINFO,H,FT\_STR} {\tt TBINFO,H,TB\_STR} \\ These routines will extract information about the table from the FITS header H and return it in a structure FT\_STR or TB\_STR. Information for the field available as output include the starting column position in bytes, TBCOL, the field with in bytes, WIDTH, the IDL type (as in the SIZE function), IDLTYPE, the field units, TUNIT, scale factor, TSCAL, zero offset, TZERO, null value, TNULL, print format, TFORM, and field name, TTYPE. (TTYPE might be needed if FIELD was specified as a scalar rather than a name.) \\ {\tt FTSIZE,H,TAB,NCOLS,ROWS,TFIELDS,NCOLS\_ALL,NROWS\_ALL} {\tt TBSIZE,H,TAB,NCOLS,ROWS,TFIELDS,NCOLS\_ALL,NROWS\_ALL} \\ These routines return the size of the table specified with H and TAB. NCOLS and NROWS are the actual table size. ALLCOLS and ALLROWS are the allocated size. TFIELDS is the number of fields per row. NCOLS\_ALL and NROWS\_ALL are the actual allocated size of TAB. \section{Examples} Read a FITS table (first extension), examine the contents, sort by flux, and print \exbegin \exc{tab = READFITS( `mytab.fits', tab, h, /EXTEN)}{;read FITS table mytab.fits into header array,h and data array, tab} \exc{PRINT,h}{;look at header} \exc{FTHELP,h}{;look at header, pretty format} \exc{PRINT,STRING(tab)}{;look at data} \exc{FTPRINT,h,tab}{;look at data, pretty format} \exc{FTPRINT,h,tab,`X,Y,FLUX',indgen(10)}{;type fields `X', `Y' and `FLUX', first 10 rows only} \exc{FTPRINT,h,tab,[1,3,4],[0,5,7]}{;Type rows 0, 5 and 7 of columns 1,3, and 4} \exc{FTSORT,h,tab,`FLUX'}{;Sort table in order of increasing flux} \exc{FTPRINT,h,tab, text=3}{;Write the entire table to an ASCII file, ftprint.prt} \exend Read a FITS ASCII table named MYTAB.FIT with columns FLUX, V, and B-V. Plot FLUX vs. V for stars with B-V $<$ 0.0. \exbegin \exc{tab = READFITS(`mytab.fit',h,tab,/EXTEN} {;Get header,h and data,tab} \exc{bv = FTGET(h,tab,`B-V')}{;get B-V column} \exc{rows = where( bv LT 0.)}{;selected rows} \exc{plot,FTGET(h,tab,`V',rows),FTGET(h,tab,`FLUX',rows)} \exend \exbegin A program has created RA and DEC vectors, and a string array of star names, NAME. Create a FITS ASCII table named ``star.fits''. \exbegin \exc{npts = n\_elements(ra)}{;Get \# of stars} \exc{FTCREATE,24,npts,h,tab}{;Create header,h and table, tab} \exc{FTADDCOL,h,tab,`RA',8,`F9.5',`DEGREES'}{;Create a new column for RA} \exc{FTADDCOL,h,tab,`DEC',8,`F9.5',`DEGREES'}{;Create a new column for DEC} \exc{FTPUT,h,tab,`NAME',0,name}{;Insert NAME vector into table starting at row 0.} \exc{FTPUT,h,tab,`RA',0,ra}{;Insert RA vector into table} \exc{FTPUT,h,tab,`DEC',0,dec}{;Insert DEC vector into table} \exc{MKHDR,h0,0,/exten}{;Make a default primary header showing extension} \exc{writefits,`star.fits',0,h0}{;Create FITS file with primary header} \exc{writefits,`star.fits',tab,h,/APPEND}{;Append ASCII table to FITS file} \exend In the last example, the table is created with a column size of 24, because that is the sum of the FORMAT field lengths (A6 + F9 + F9). (If too small a size was specified, then FTADDCOL would enlarge the table size.) It is possible to add a vector to a table with FTPUT, even if the column did not previously exist. However, the column is then created using default formats, and other parameter options (e.g. TUNIT) are not possible. Therefore, it is recommended to first use FTADDCOL to create a new column before adding numeric data. \end{document}