casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
fitsio.h
Go to the documentation of this file.
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