casa
$Rev:20696$
|
00001 //# FITSTable.h: Simplified interface to FITS tables with AIPS++ Look and Feel. 00002 //# Copyright (C) 1995,1996,1997,1999,2000,2001 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# 00027 //# $Id: FITSTable.h 20299 2008-04-03 05:56:44Z gervandiepen $ 00028 00029 #ifndef FITS_FITSTABLE_H 00030 #define FITS_FITSTABLE_H 00031 00032 00033 #include <casa/aips.h> 00034 #include <casa/Containers/Record.h> 00035 #include <tables/Tables/TableRecord.h> 00036 #include <casa/Containers/Block.h> 00037 #include <fits/FITS/hdu.h> 00038 #include <fits/FITS/fitsio.h> 00039 #include <casa/iosfwd.h> 00040 00041 namespace casa { //# NAMESPACE CASA - BEGIN 00042 00043 class String; 00044 class FITSFieldCopier; 00045 class TableDesc; 00046 template<class T> class Vector; 00047 00048 // <summary> 00049 // Simplified interface to FITS tables with AIPS++ Look and Feel. 00050 // </summary> 00051 // 00052 // <use visibility=export> 00053 // 00054 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00055 // </reviewed> 00056 // 00057 // <prerequisite> 00058 // <li> General knowledge of FITS binary and ASCII tables. 00059 // </prerequisite> 00060 // 00061 // <etymology> 00062 // </etymology> 00063 // 00064 // <synopsis> 00065 // FITSTablular is an obstract base class which is used for read-only access to 00066 // tabular FITS-like data structures. 00067 // </synopsis> 00068 // 00069 // <example> 00070 // </example> 00071 // 00072 // <motivation> 00073 // </motivation> 00074 // 00075 // <todo asof="1995/06/01"> 00076 // <li> Eventually we'd like to be able to write the tables as well as read 00077 // them. 00078 // </todo> 00079 00080 class FITSTabular 00081 { 00082 public: 00083 virtual ~FITSTabular(); 00084 // isValid() returns False if this object isn't a valid Tabular data 00085 // structure. 00086 virtual Bool isValid() const = 0; 00087 // Returns keywords which are associated with the underlying FITS files. 00088 virtual const TableRecord &keywords() const = 0; 00089 // Returns the description of the underlying FITS table. 00090 virtual const RecordDesc &description() const = 0; 00091 // Returns any TUNITnnn associated with a column (the field names 00092 // are the column names, each field value is the TUNITnnn value for 00093 // that field). Note that only those columns with a non-empty 00094 // TUNITnnn have an entry in the units() Record. 00095 virtual const Record &units() const = 0; 00096 // Returns any TDISPnnn associated with a column (the field names 00097 // are the column names, each field value is the TDISPnnn value for 00098 // that field). Note that only those columns with a non-empty 00099 // TDISPnnn have an entry in the displayFormats() Record. 00100 virtual const Record &displayFormats() const = 0; 00101 // Returns any TNULLnnn associated with a column (the field names 00102 // are the column names, each field value is the TNULLnnn value for 00103 // that field). Note that only those columns with a specific entry for 00104 // TNULLnnn and which have not been promoted to doubles due TSCAL 00105 // and TZERO values will have an entry in the nulls() Record. 00106 // The meaning of TNULL is only defined for integer and byte columns. 00107 // When a column is promoted to a double because of scaling, 00108 // any TNULL values will be assigned a value of NaN. 00109 virtual const Record &nulls() const = 0; 00110 00111 // Returns True if we have advanced past the end of data. 00112 virtual Bool pastEnd() const = 0; 00113 00114 // Advance the row if possible (guaranteed harmless if pastEnd() is True. 00115 virtual void next() = 0; 00116 00117 // Reopen the table, default behavior is to do nothing, return False 00118 virtual Bool reopen(const String&) { return False; } 00119 00120 // return the name 00121 virtual const String &name() const = 0; 00122 00123 // Has the description changed since construction, default is False 00124 virtual Bool hasChanged() const { return False;} 00125 // reset the changed flag, default do nothing 00126 virtual void resetChangedFlag() {;} 00127 00128 // Return the currentRow. This is guaranteed to be valid so long as only 00129 // member functions of this base class are called (so you can safely attach 00130 // RecordFieldPtr objects to it. The result is undefined if pastEnd() is True. 00131 virtual const Record ¤tRow() const = 0; 00132 00133 // Helper function for retrieving keywords from a native-FITS hdu. 00134 // If allKeywords is not True, some keywords will be excluded 00135 // from the list. Currently the list of excluded keywords 00136 // includes TTYPEnnn, TFORMnnn, and TUNITnnn 00137 static TableRecord keywordsFromHDU(HeaderDataUnit &hdu, 00138 Bool allKeywords = False); 00139 00140 // Helper function for retrieving a description from a native-FITS hdu. 00141 static RecordDesc descriptionFromHDU(BinaryTableExtension &hdu); 00142 00143 // Help function for retrieving any shape information from String columns 00144 // using the SubString convention. 00145 // Information is returned in a Record having named fields = all String 00146 // columns following those convention. Each of these fields is, in turn, 00147 // a sub-record having these three fields: NCHAR, NELEM, DELIM. 00148 // If NELEM == -1 then there must have been a DELIM specified and 00149 // this field is a variable shaped string array where each element has 00150 // at most NCHAR and they are separated by DELIM (which is a String field here). 00151 // Otherwise, DELIM is not used and there are NCHAR per element for each 00152 // of NELEM in each cell for this column. 00153 static Record subStringShapeFromHDU(BinaryTableExtension &hdu); 00154 00155 // Helper function for retrieving the TUNITnnn from a native-FITS hdu. 00156 static Record unitsFromHDU(BinaryTableExtension &hdu); 00157 00158 // Helper function for retrieving the TDISPnnn from a native-FITS hdu. 00159 static Record displayFormatsFromHDU(BinaryTableExtension &hdu); 00160 00161 // Helper function for retrieving the TNULLnnn from a native-FITS hdu. 00162 static Record nullsFromHDU(BinaryTableExtension &hdu); 00163 00164 // Get a TableDesc appropriate to hold a FITSTabular 00165 // the keywords, description, units, displayFormats, and nulls are all used 00166 static TableDesc tableDesc(const FITSTabular &fitstabular); 00167 }; 00168 00169 // <summary> 00170 // Attach a FITSTabular to a binary or ASCII table 00171 // </summary> 00172 // 00173 // <use visibility=export> 00174 // 00175 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00176 // </reviewed> 00177 // 00178 // <prerequisite> 00179 // <li> General knowledge of FITS binary and ASCII tables. 00180 // </prerequisite> 00181 // 00182 // <etymology> 00183 // </etymology> 00184 // 00185 // <synopsis> 00186 // FITSTable is a FITSTabular which is attached to a FITS table (on disk only 00187 // presently), either Binary or ASCII. 00188 // </synopsis> 00189 // 00190 // <example> 00191 // </example> 00192 // 00193 // <motivation> 00194 // </motivation> 00195 // 00196 // <todo asof="1995/06/01"> 00197 // <li> 00198 // </todo> 00199 00200 class FITSTable : public FITSTabular 00201 { 00202 public: 00203 // this creates an invalid (isValid() return False) FITSTable 00204 // Its primary purpose is so that FITSTables can be created before 00205 // the file name is known. reopen() is then used to open the file. 00206 FITSTable(uInt whichHDU=1, Bool allKeywords=False); 00207 00208 // 0-relative HDU. It can never be zero by the FITS rules. 00209 // allKeywords is passed to FITSTabular::keywordsFromHDU 00210 // See the documentation for that function for a list of 00211 // excluded keywords when allKeywords is False. 00212 FITSTable(const String &fileName, uInt whichHDU=1, 00213 Bool allKeywords = False); 00214 ~FITSTable() { clear_self();} 00215 00216 // Has the end of file been reached yet 00217 virtual Bool eof() const {return io_p->eof();} 00218 00219 // Attach this FITSTable to a new file name, same HDU# as at open time 00220 virtual Bool reopen(const String &fileName); 00221 virtual const String& name() const { return name_p;} 00222 00223 virtual Bool isValid() const {return isValid_p;} 00224 00225 virtual const TableRecord &keywords() const {return keywords_p;} 00226 virtual const RecordDesc &description() const {return description_p;} 00227 virtual const Record &units() const {return units_p;} 00228 virtual const Record &displayFormats() const {return disps_p;} 00229 virtual const Record &nulls() const {return nulls_p;} 00230 00231 virtual Bool pastEnd() const; 00232 virtual void next(); 00233 virtual const Record ¤tRow() const; 00234 00235 // single FITS tables know how many rows there are 00236 // unlike general FITSTabulars, which may not know 00237 // (e.g. if it is a FITSMultiTable) 00238 virtual uInt nrow() const {return raw_table_p->nrows();} 00239 00240 // these tables should also know where they are 00241 virtual Int rownr() const {return row_nr_p;} 00242 00243 // and it should be possible to move to a desired row 00244 // the rownr() member can be used to verify that a move 00245 // was successful - this will happen if the requested row 00246 // was < rownr() or >= nrow() - i.e. movements backwards or 00247 // beyond the end of the file are not possible. 00248 virtual void move(Int torow); 00249 00250 // the keywords from the Primary HDU 00251 virtual const TableRecord &primaryKeywords() const {return primaryKeys_p;} 00252 protected: 00253 // SDFITSTable needs to make some keywords appear as 00254 // columns, this requires access to description_p, keywords_p, and 00255 // row_p. However, its not something that typical FITSTable 00256 // users will want. Therefore, I've provided this protected 00257 // function for SDFITSTable to use so as to not have to provide 00258 // direct access to those data members at the public level. 00259 // The named keywords and values are appended to the end of 00260 // row_p and removed from keywords_p, description_p is modified 00261 // appropriately. The returned value is False if any named 00262 // keyword did not appear in keywords_p (however, all named 00263 // keywords that DO appear in keywords_p will have been correctly 00264 // moved). 00265 Bool virtualColumns(const Vector<String>& keyNames); 00266 private: 00267 // Undefined and inaccessible. An alternative would be to use reference 00268 // semantics like Table. 00269 FITSTable(const FITSTable &); 00270 FITSTable &operator=(const FITSTable &); 00271 00272 void fill_row(); 00273 void clear_self(); 00274 00275 Bool isValid_p; 00276 00277 String name_p; 00278 00279 uInt hdu_nr_p; 00280 00281 Int row_nr_p; 00282 BinaryTableExtension *raw_table_p; 00283 FitsInput *io_p; 00284 TableRecord keywords_p; 00285 TableRecord primaryKeys_p; 00286 RecordDesc description_p; 00287 Record row_p; 00288 Record units_p; 00289 Record disps_p; 00290 Record nulls_p; 00291 Record subStrShapes_p; 00292 Bool allKeys_p; 00293 // One per field in row_p, of the right type. i.e. casting required. 00294 uInt nfields_p; 00295 Block<void *> row_fields_p; 00296 Block<Int> field_types_p; 00297 Block<Bool> promoted_p; 00298 Block<Int> tdims_p; 00299 // these are used by VADESC columns 00300 Block<Int> vatypes_p; 00301 Block<void *> vaptr_p; 00302 // I had trouble making a Block<VADescFitsField> 00303 VADescFitsField *va_p; 00304 char *theheap_p; 00305 00306 // It is necessary to read the PDA to get the primary keywords. 00307 // If there is any data there, the FITS classes do not provide any way to 00308 // just skip over them to get to the next HDU. The only way to do that is 00309 // to actually read all of the data. If there is no data, this step is 00310 // unnecessary and so this subroutine need only be called after the primary 00311 // keywords have been read AND the PDA has some data in it. Closing the 00312 // FitsInput and reopening it is faster in most cases than reading in each 00313 // data value. 00314 void reopenAtFirstHDU(const String &name); 00315 }; 00316 00317 // <summary> 00318 // Simplified interface to create and write to a FITS Binary Table 00319 // </summary> 00320 // 00321 // <use visibility=export> 00322 // 00323 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00324 // </reviewed> 00325 // 00326 // <prerequisite> 00327 // <li> General knowledge of FITS binary and ASCII tables. 00328 // </prerequisite> 00329 // 00330 // <etymology> 00331 // </etymology> 00332 // 00333 // <synopsis> 00334 // </synopsis> 00335 // 00336 // <example> 00337 // </example> 00338 // 00339 // <motivation> 00340 // </motivation> 00341 // 00342 // <todo asof="1995/06/01"> 00343 // <li> probably much 00344 // </todo> 00345 00346 class FITSTableWriter 00347 { 00348 public: 00349 enum {DefaultMaxStringSize = 16}; 00350 00351 // You MUST have already written a first HDU to FitsOutput. 00352 // description contains the names and types of the table columns to be written. 00353 // The row is not rearranged (i.e. they are used in order) for alignment purposes. 00354 // Array columns must have fixed shape unless tdimColumns is used. Use the 00355 // maxLengths record to indicate any string columns which should have a length other 00356 // than the default value by providing an int field of the same name as the string 00357 // field in this record. 00358 // The size of the table (nrows) must be given at creation. Use extraKeywords to 00359 // indicate any keywords not automatically created. The units record is used to 00360 // indicate the units for any column. Provide a string field with the same name as 00361 // the column field in description. If freeOutput is True, file must come from new 00362 // since it will be deleted upon destruction. You might not want this to happen if 00363 // you are going to write many tables to the same fits file. Use variableShapes to 00364 // signal which array columns have variable shape and use maxLengths to indicate 00365 // the maximum size of those variable shaped columns. The variableShapes record 00366 // should contain a String corresponding to the longest TDIM value appropriate for 00367 // each variable shaped column. The maxLengths record should contain an int field 00368 // for each variable shaped column which indicates the maximum number of elements 00369 // to be found in that column. Unused values in any cell in the variable shaped 00370 // columns will be filled with zero. These columns will use the SDFITS TDIM convention 00371 // where for column nnn there is a corresponding TDIMnnn column where 00372 // the values in each row are the true shape of the data in column nnn. 00373 // variableShapes appears as the last argument for backwards compatibility with 00374 // existing code. 00375 FITSTableWriter(FitsOutput *file, 00376 const RecordDesc &description, 00377 const Record &maxLengths, 00378 uInt nrows, 00379 const Record &extraKeywords, 00380 const Record &units, 00381 Bool freeOutput = True, 00382 const Record &variableShapes = Record()); 00383 00384 ~FITSTableWriter(); 00385 00386 // use this to set the value of the current row to be written 00387 RecordInterface &row() {return row_p;} 00388 00389 // Write the current row() 00390 void write(); 00391 00392 // Don't delete this out from under us! 00393 FitsOutput *writer() {return writer_p;} 00394 00395 // Returns a writer, with the first HDU filled in (set to null). The caller 00396 // is responsible for deleting the pointer returned from makeWriter. 00397 static FitsOutput *makeWriter(const String &fileName); 00398 private: 00399 // Undefined and inaccessible 00400 FITSTableWriter(); 00401 FITSTableWriter(const FITSTableWriter&); 00402 FITSTableWriter& operator=(const FITSTableWriter&); 00403 00404 Bool delete_writer_p; 00405 FitsOutput *writer_p; 00406 uInt nrows_written_p; 00407 BinaryTableExtension *bintable_p; 00408 Record row_p; 00409 PtrBlock<FITSFieldCopier *> copiers_p; 00410 }; 00411 00412 // <summary> 00413 // Simplified interface to create and write to FITS random groups 00414 // </summary> 00415 // 00416 // <use visibility=export> 00417 // 00418 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00419 // </reviewed> 00420 // 00421 // <prerequisite> 00422 // <li> General knowledge of FITS binary and ASCII tables. 00423 // </prerequisite> 00424 // 00425 // <etymology> 00426 // </etymology> 00427 // 00428 // <synopsis> 00429 // Like FITSTableWriter except that this must be the first HDU and 00430 // all "columns" in the description must have the same type, i.e. float. 00431 // </synopsis> 00432 // 00433 // <example> 00434 // </example> 00435 // 00436 // <motivation> 00437 // </motivation> 00438 // 00439 // <todo asof="1995/06/01"> 00440 // <li> probably much 00441 // </todo> 00442 00443 class FITSGroupWriter 00444 { 00445 public: 00446 // Since this must always be the first HDU, there is no point in constructing it 00447 // with a FitsOutput. description indicates the names of the random groups parameters. 00448 // nrows is a synonym for ngroups. Use extraKeywords to 00449 // indicate any keywords not automatically created (SIMPLE, BITPIX, NAXIS*, EXTEND, 00450 // BLOCKED, GROUPS, PCOUNT, GOUNT, ORIGIN, END). If freeOutput is True, file will be 00451 // deleted by the destructor. You might not want this to happen if 00452 // you are going to write any extensions to the same fits file. You can get the 00453 // FitsOutput used here from write() 00454 FITSGroupWriter(const String &fileName, 00455 const RecordDesc &description, 00456 uInt nrows, 00457 const Record &extraKeywords, 00458 Bool freeOutput = True); 00459 00460 ~FITSGroupWriter(); 00461 00462 // Set the values for the current group 00463 RecordInterface &row() {return row_p;} 00464 00465 // Write the current group (row()). 00466 void write(); 00467 00468 // Don't delete this out from under us! 00469 FitsOutput *writer() {return writer_p;} 00470 private: 00471 // Undefined and inaccessible 00472 FITSGroupWriter(); 00473 FITSGroupWriter(const FITSGroupWriter&); 00474 FITSGroupWriter& operator=(const FITSGroupWriter&); 00475 00476 Bool delete_writer_p; 00477 FitsOutput *writer_p; 00478 uInt nrows_written_p, nrows_total_p; 00479 PrimaryGroup<Float> *group_p; 00480 Record row_p; 00481 Int error_count_p; 00482 00483 // Checks error status of writer_p and group_p. Cleans up and throws an exception if bad. 00484 void check_error(const char *extra_info = 0); 00485 }; 00486 00487 } //# NAMESPACE CASA - END 00488 00489 #endif