001    /* @(#)FitsTable.java     $Revision: 1.6 $    $Date: 2002/05/06 12:42:22 $
002     *
003     * Copyright (C) 2002 European Southern Observatory 
004     * License:  GNU General Public License version 2 or later
005     */
006    package org.eso.fits;
007    
008    import java.lang.*;
009    import java.io.*;
010    import java.util.*;
011    
012    /** FitsTable class represents a FITS table extension in either ASCII
013     *  or BINARY table format.  It is a collection of FitsColumn object
014     *  giving acess to the table data.
015     *
016     *  @version $Revision: 1.6 $ $Date: 2002/05/06 12:42:22 $
017     *  @author  P.Grosbol, DMD/ESO, <pgrosbol@eso.org>
018     */
019    public class FitsTable extends FitsData {
020    
021        private Vector columns;
022        private int noRows;
023    
024        /** Constructor for FitsTable class given a FITS table extension
025         *  header with associated data unit as a file.
026         *
027         *  @param header  FitsHeader object with the table extension header
028         *  @param file    RandomAccess file positioned at the start of the
029         *                 associated data unit
030         *  @param sflag   Flag for storing data matrix internally
031         *  @exception FitsException */
032        public FitsTable(FitsHeader header, DataInput file, boolean sflag) throws FitsException {
033            super(header, file, sflag);
034    
035            if ((bitpix != 8) || (noParm < 0) || (noGroup != 1)) {
036                throw new FitsException("Incompatible TABLE header", FitsException.HEADER);
037            }
038    
039            FitsKeyword kw = header.getKeyword("TFIELDS");
040            if (kw == null) {
041                throw new FitsException("Missing TFIELDS keyword", FitsException.HEADER);
042            }
043            int ncol = (int) kw.getInt();
044            columns = new Vector(ncol);
045            int recordSize = naxis[0];
046            noRows = naxis[1];
047    
048            kw = header.getKeyword("THEAP");
049            long heapOffset = (kw == null) ? 0 : kw.getInt();
050    
051            int npos = 0;
052            long   tnull;
053            double tzero, tscale;
054            String tform, ttype, tunit, tdisp, tdim;
055            FitsColumn column;
056    
057            for (int n=1; n<=ncol; n++) {
058                kw = header.getKeyword("TFORM"+n);
059                if (kw == null) { 
060                    throw new FitsException("Missing TFORMn keyword", FitsException.HEADER);
061                }
062                tform = kw.getString();
063                if (type == Fits.ATABLE) {
064                    kw = header.getKeyword("TBCOL"+n);
065                    if (kw == null) { 
066                        throw new FitsException("Missing TBCOLn keyword", FitsException.HEADER);
067                    }
068                    npos = (int) kw.getInt();
069                }
070                kw = header.getKeyword("TTYPE"+n);
071                ttype = (kw == null) ? "Label"+n : kw.getString();
072    
073                // create the Column
074    
075                column = new FitsColumn(type, tform, ttype, noRows);
076                if (isRAFile) {
077                    column.setData(dataFile, dataOffset, npos, recordSize);
078                } else if (dataArray != null) {
079                    column.setData(dataArray, npos, recordSize);
080                }
081    
082                if (type == Fits.BTABLE) {
083                    npos += column.getWidth();
084                }
085    
086                kw = header.getKeyword("TZERO"+n);
087                if (kw != null) {
088                    column.setZero(kw.getReal());
089                }
090    
091                kw = header.getKeyword("TSCALE"+n);
092                if (kw != null) {
093                    column.setScale(kw.getReal());
094                }
095    
096                kw = header.getKeyword("TNULL"+n);
097                if (kw != null) {
098                    if (type == Fits.BTABLE) {
099                        column.setNull(kw.getInt());
100                    } else {
101                        column.setNull(kw.getString());
102                    }
103                }
104    
105                kw = header.getKeyword("TUNIT"+n);
106                if (kw != null) {
107                    column.setUnit(kw.getString());
108                }
109    
110                kw = header.getKeyword("TDISP"+n);
111                if (kw != null) {
112                    column.setDisplay(kw.getString());
113                }
114    
115                kw = header.getKeyword("TDIM"+n);
116                if (kw != null) {
117                    column.setDim(kw.getString());
118                }
119    
120                columns.addElement(column);
121            }
122        }
123    
124        /** Create and return a minimum FITS header for data Matrix.
125         */
126        public FitsHeader getHeader() {
127            FitsHeader hdr = new FitsHeader();
128    
129            hdr.addKeyword(new FitsKeyword("XTENSION", "BINTABLE", "Binary table extension"));
130            hdr.addKeyword(new FitsKeyword("BITPIX", 8, "No. of bits per pixel"));
131            hdr.addKeyword(new FitsKeyword("NAXIS", 2, "No. of axes in image"));
132            int nb = 0;
133            for (int n=0; n<columns.size(); n++);
134    
135    
136            hdr.addKeyword(new FitsKeyword("NAXIS1", nb, "No. of bytes in row"));
137            hdr.addKeyword(new FitsKeyword("NAXIS2", getNoRows(), "No. of rows in table"));
138            hdr.addKeyword(new FitsKeyword("PCOUNT", noParm, "Size of heap area"));
139            hdr.addKeyword(new FitsKeyword("GCOUNT", noGroup, "Group count"));
140            hdr.addKeyword(new FitsKeyword("TFIELDS", getNoColumns(), "No. of columns in table"));
141    
142            return hdr;
143        }
144    
145        /** Add column to table.
146         *
147         *  @param  column  FitsColumn to be appended to the table */
148        public void addColumn(FitsColumn column) {
149            columns.addElement(column);
150        }
151    
152        /** Insert column in table at specified position.
153         *
154         *  @param  column  FitsColumn to be inserted into the table
155         *  @param  index   position where to insert column */
156        public void insertColumnAt(FitsColumn column, int index) {
157            columns.insertElementAt(column, index);
158        }
159    
160        /** Remove column from table.
161         *
162         *  @param  index  position of column to be removed */
163        public void removeColumnAt(int index) {
164            columns.removeElementAt(index);
165        }
166    
167        /** Get column with a given index in the table.
168         *
169         *  @param index  position of column in table */
170        public FitsColumn getColumn(int index){
171            if ((index < 0) || (columns.size() <= index)) {
172                return null;
173            }
174            Enumeration enumeration = columns.elements();
175            while (0<index--) enumeration.nextElement();
176            return (FitsColumn) enumeration.nextElement();
177        }
178    
179        /** Get column with a given label.  The first column found with 
180         *  the label is returned.  If none is found a NULL is returned.
181         *
182         *  @param label  string with column label */
183        public FitsColumn getColumn(String label){
184            FitsColumn col;
185            Enumeration enumeration = columns.elements();
186            while (enumeration.hasMoreElements()) {
187                col = (FitsColumn) enumeration.nextElement();
188                if (label.equalsIgnoreCase(col.getLabel())) {
189                    return col;
190                }
191            }
192            return null;
193        }
194    
195        /** Retrieve number of columns in current table. */
196        public int getNoColumns(){
197            return columns.size();
198        }
199    
200        /** Get total number of rows defined for the table (see NAXIS2). */
201        public int getNoRows() {
202            return noRows;
203        }
204    }
205    
206