casa
$Rev:20696$
|
00001 //# fitsio.h: 00002 //# Copyright (C) 1993,1994,1995,1996,1999,2001,2003 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 //# $Id: fitsio.h 21069 2011-05-06 13:59:44Z gervandiepen $ 00027 00028 #ifndef FITS_FITSIO_H 00029 #define FITS_FITSIO_H 00030 00031 # include <fits/FITS/fits.h> 00032 # include <fits/FITS/blockio.h> 00033 # include <fits/FITS/hdu.h> 00034 //# include <casa/stdvector.h> 00035 # include <casa/Arrays/Vector.h> 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 //<summary> sequential FITS I/O </summary> 00040 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos=""> 00041 // </reviewed> 00042 //<synopsis> 00043 // FitsIO is a base class that handles all the sequential blocked 00044 // FITS I/O. Special derived classes do the input and output. 00045 // No interpretation of the data is attempted here, there are 00046 // special FITS classes that handle syntax and interpretation. 00047 //</synopsis> 00048 //<example> 00049 //<srcblock> 00050 // FitsInput fin("myfile.fits",FITS::Disk); // open disk file for FITS input 00051 // if (fin.err() == FitsIO::IOERR) { // check if open succeeded 00052 // cout << "Could not open FITS input\n"; 00053 // exit(0); 00054 // } 00055 // if (fin.rectype() == FITS::HDURecord && // test for primary array 00056 // fin.hdutype() == FITS::PrimaryArrayHDU) { 00057 // } 00058 //</srcblock> 00059 //</example> 00060 00061 class FitsIO { 00062 public: 00063 virtual ~FitsIO(); 00064 00065 // error return code. Should be one of an 00066 // enumerated type: 00067 // 00068 //# until cxx2html can handle enum() we duplicate it here 00069 // 00070 //<srcblock> 00071 // enum FitsErrs { OK, IOERR, MISSKEY, BADBEGIN, EMPTYFILE, 00072 // NOPRIMARY, BADOPER, BADEOF, MEMERR, BADBITPIX, NOAXISN, 00073 // NOPCOUNT, NOGCOUNT, BADPCOUNT, BADGCOUNT, NOGROUPS, 00074 // BADNAXIS, BADPRIMARY, BADSIZE, HDUERR }; 00075 //</srcblock> 00076 //<group> 00077 enum FitsErrs { OK, IOERR, MISSKEY, BADBEGIN, EMPTYFILE, 00078 NOPRIMARY, BADOPER, BADEOF, MEMERR, BADBITPIX, NOAXISN, 00079 NOPCOUNT, NOGCOUNT, BADPCOUNT, BADGCOUNT, NOGROUPS, 00080 BADNAXIS, BADPRIMARY, BADSIZE, HDUERR }; 00081 int err() const { return m_err_status; } 00082 //</group> 00083 // 00084 // record size, in bytes, of a FITS block. 00085 // Normally set at 2880, unless some form of blocking was used. 00086 int fitsrecsize() const { return m_recsize; } 00087 // is it a valid fits file (SIMPLE==T). If not, the only 00088 // safest operation is to skip the data portion of the 00089 // current HeaderDataUnit 00090 Bool isafits() const { return m_valid_fits; } 00091 // see if there may be FITS extensions present (EXTENT==T) 00092 Bool isextend() const { return m_extend; } 00093 // test if end of file has been reached 00094 Bool eof() const { return Bool(m_rec_type == FITS::EndOfFile); } 00095 // the FITS record type 00096 FITS::FitsRecType rectype() const { return m_rec_type; } 00097 // Header Data Unit type (e.g. 00098 FITS::HDUType hdutype() const { return m_hdu_type; } 00099 FITS::ValueType datatype() const { return m_data_type; } 00100 // return the datasize of the current HDU. This excludes 00101 // the trailing end of the blocked data portion. 00102 OFF_T datasize() const { return m_data_size; } 00103 // data characteristics 00104 Int itemsize() const { return m_item_size; } 00105 // for input, size of remaining data 00106 // for output, size of data written 00107 OFF_T currsize() const { return m_curr_size; } 00108 // get FitsKeyCardTranslator 00109 FitsKeyCardTranslator& getkc(){ return m_kc; } 00110 // get the fitsfile pointer 00111 fitsfile *getfptr() const { return m_fptr; } 00112 00113 // get the size of the last skipped HDU 00114 OFF_T getskipsize() const {return m_skipHDU_size;} 00115 00116 00117 protected: 00118 FitsIO(FITSErrorHandler); 00119 00120 fitsfile *m_fptr; 00121 const int m_recsize; 00122 Bool m_valid_fits; // True if SIMPLE == T 00123 Bool m_extend; // True if EXTEND == T 00124 Bool m_isaprimary; // True if there is a primary HDU 00125 Bool m_header_done; // True if header has been processed 00126 FITS::FitsRecType m_rec_type; // always set 00127 FITS::HDUType m_hdu_type; // always set 00128 00129 FITSErrorHandler m_errfn; // error handler function 00130 FitsErrs m_err_status; 00131 FitsKeyCardTranslator m_kc; 00132 FitsKeywordList m_kw; 00133 00134 char *m_curr; // pointer to current record 00135 int m_bytepos; // current byte position within record 00136 Int m_item_size; // data characteristics 00137 FITS::ValueType m_data_type; 00138 //uInt m_data_size; 00139 OFF_T m_data_size; 00140 // for input, size of remaining data 00141 // for output, size of data written 00142 //uInt m_curr_size; 00143 OFF_T m_curr_size; 00144 00145 // for size of the last HDU skipped 00146 OFF_T m_skipHDU_size; 00147 00148 // set error message that belongs to one of the enumerated types 00149 virtual void errmsg(FitsErrs, const char *) = 0; 00150 00151 }; 00152 00153 //<summary> fixed-length sequential blocked FITS input </summary> 00154 00155 class FitsInput : public FitsIO { 00156 friend int HeaderDataUnit::get_hdr(FITS::HDUType, FitsKeywordList &); 00157 friend OFF_T HeaderDataUnit::read_all_data(char *); 00158 friend int HeaderDataUnit::read_data(char *, Int); 00159 friend int HeaderDataUnit::skip(uInt); 00160 friend int HeaderDataUnit::skip(); 00161 00162 public: 00163 //<group> 00164 FitsInput(const char *, const FITS::FitsDevice &, int = 10, 00165 FITSErrorHandler errhandler = FITSError::defaultHandler); 00166 FitsInput(FITSErrorHandler errhandler = FITSError::defaultHandler); 00167 ~FitsInput(); 00168 //</group> 00169 00170 int skip_hdu(); 00171 00172 // skip all remaining data 00173 void skip_all(FITS::HDUType); 00174 00175 //int skip_hdu2(); 00176 // read special or unrecognizable records 00177 char *read_sp(); 00178 00179 // get hdu header image cards as strings. By default the strings will be of 00180 // variable length. You can optionally ask for them to be length 80 (padded 00181 // with spaces). 00182 Vector<String> kwlist_str(Bool length80=False); 00183 00184 // number of physical blocks read/written 00185 int blockno() const {return m_fin.blockno();} 00186 00187 // number of logical records read/written 00188 int recno() const {return m_fin.recno();} 00189 BlockInput & getfin(){ return m_fin; } // for test use only 00190 00191 // the number of hdu in this fits file 00192 int getnumhdu() const {return m_thdunum;} 00193 00194 private: 00195 BlockInput &m_fin; 00196 BlockInput &make_input(const char *, const FITS::FitsDevice &, int, 00197 FITSErrorHandler errhandler = FITSError::defaultHandler); 00198 00199 // flag used for read control in errors 00200 Bool m_got_rec; 00201 // total number of hdu in this fits file 00202 int m_thdunum; 00203 00204 virtual void errmsg(FitsErrs, const char *); 00205 void init(); 00206 void read_header_rec(); 00207 bool current_hdu_type( FITS::HDUType &); 00208 bool get_data_type( FITS::ValueType &); 00209 00210 //# check if this comes out ok in cxx2html 00211 // Special interface to class HeaderDataUnit 00212 //<group> 00213 // special way to process header 00214 int process_header(FITS::HDUType, FitsKeywordList &); 00215 // read all data into a given address - all responsibility is given 00216 // to the user 00217 OFF_T read_all(FITS::HDUType, char *); 00218 // read N bytes into address 00219 int read(FITS::HDUType, char *, int ); 00220 // skip N bytes 00221 int skip(FITS::HDUType, OFF_T); 00222 //</group> 00223 }; 00224 00225 //<summary> fixed-length sequential blocked FITS output </summary> 00226 00227 class FitsOutput : public FitsIO { 00228 friend int HeaderDataUnit::write_hdr(FitsOutput &); 00229 friend int HeaderDataUnit::write_all_data(FitsOutput &, char *); 00230 friend int HeaderDataUnit::write_data(FitsOutput &, char *, Int); 00231 00232 public: 00233 //<group> 00234 FitsOutput(const char *, const FITS::FitsDevice &, int = 10, 00235 FITSErrorHandler errhandler = FITSError::defaultHandler); 00236 FitsOutput(FITSErrorHandler errhandler = FITSError::defaultHandler); 00237 ~FitsOutput(); 00238 //</group> 00239 // used by PrimaryArray, BinaryTabelExtention etc to work with the constructor without keyword list. 00240 void set_data_info( FitsKeywordList &kwl, FITS::HDUType t, FITS::ValueType dt, OFF_T ds, Int is); 00241 // write a special record. For this the record type must also 00242 // be to set to FITS::SpecialRecord 00243 int write_sp(char *rec); 00244 // check if the current hdu is done. It was private. 00245 int hdu_complete() { 00246 return (m_rec_type == FITS::HDURecord && m_data_size == 0); 00247 } 00248 BlockOutput & getfout(){ return m_fout; } 00249 void setfptr( fitsfile* ffp ); 00250 Bool required_keys_only(){ return m_required_keys_only; } 00251 00252 private: 00253 BlockOutput &m_fout; 00254 Bool m_required_keys_only; 00255 BlockOutput &make_output(const char *, const FITS::FitsDevice &, int, 00256 FITSErrorHandler errhandler = FITSError::defaultHandler); 00257 00258 virtual void errmsg(FitsErrs, const char *); 00259 00260 int hdu_inprogress() { 00261 return (m_rec_type == FITS::HDURecord && m_data_size > 0 && m_curr_size < m_data_size); 00262 } 00263 00264 // Special interface to class HeaderDataUnit 00265 //<group> 00266 int write_hdr(FitsKeywordList &, FITS::HDUType, FITS::ValueType, OFF_T, Int); 00267 // write all data from address 00268 int write_all(FITS::HDUType, char *, char); 00269 // write N bytes from address 00270 int write(FITS::HDUType, char *, Int, char); 00271 //</group> 00272 }; 00273 00274 //<summary> FITS input from disk </summary> 00275 00276 class FitsDiskInput : public BlockInput { 00277 public: 00278 FitsDiskInput(const char *, int, int = 1, 00279 FITSErrorHandler errhandler = FITSError::defaultHandler); 00280 ~FitsDiskInput(); 00281 // implements skip in terms of lseek 00282 char *skip(int); 00283 }; 00284 00285 //<summary> FITS output to disk </summary> 00286 00287 class FitsDiskOutput : public BlockOutput { 00288 public: 00289 FitsDiskOutput(const char *, int, int = 1, 00290 FITSErrorHandler errhandler = FITSError::defaultHandler); 00291 ~FitsDiskOutput(); 00292 }; 00293 00294 //<summary> FITS input from standard input </summary> 00295 00296 class FitsStdInput : public BlockInput { 00297 public: 00298 FitsStdInput(int, 00299 FITSErrorHandler errhandler = FITSError::defaultHandler); 00300 ~FitsStdInput(); 00301 }; 00302 00303 //<summary> FITS output to standard output </summary> 00304 00305 class FitsStdOutput : public BlockOutput { 00306 public: 00307 FitsStdOutput(int, 00308 FITSErrorHandler errhandler = FITSError::defaultHandler); 00309 ~FitsStdOutput(); 00310 }; 00311 00312 //<summary> FITS input from 9-track tape </summary> 00313 00314 class FitsTape9Input : public BlockInput { 00315 public: 00316 FitsTape9Input(const char *, int, int = 10, 00317 FITSErrorHandler errhandler = FITSError::defaultHandler); 00318 ~FitsTape9Input(); 00319 }; 00320 00321 //<summary> FITS output to 9-track tape </summary> 00322 00323 class FitsTape9Output : public BlockOutput { 00324 public: 00325 FitsTape9Output(const char *, int, int = 10, 00326 FITSErrorHandler errhandler = FITSError::defaultHandler); 00327 ~FitsTape9Output(); 00328 }; 00329 00330 00331 } //# NAMESPACE CASA - END 00332 00333 # endif