NASA - Jet Propulsion Laboratory
    + View the NASA Portal
Search JPL
Jet Propulsion Laboratory Home Earth Solar System Stars & Galaxies Technology
Introduction Background Software Links

fitshandle.h

Go to the documentation of this file.
00001 /*
00002  *  This file is part of Healpix_cxx.
00003  *
00004  *  Healpix_cxx is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  Healpix_cxx is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with Healpix_cxx; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  *  For more information about HEALPix, see http://healpix.jpl.nasa.gov
00019  */
00020 
00021 /*
00022  *  Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
00023  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00024  *  (DLR).
00025  */
00026 
00027 /*! \file fitshandle.h
00028  *  Declaration of the FITS I/O helper class used by LevelS
00029  *
00030  *  Copyright (C) 2002, 2003, 2004, 2005, 2006 Max-Planck-Society
00031  *  \author Martin Reinecke
00032  */
00033 
00034 #ifndef PLANCK_FITSHANDLE_H
00035 #define PLANCK_FITSHANDLE_H
00036 
00037 #include <string>
00038 #include <vector>
00039 #include "fitsio.h"
00040 #include "arr.h"
00041 #include "datatypes.h"
00042 
00043 /*! \defgroup fitsgroup FITS-related functionality */
00044 /*! \{ */
00045 
00046 template<typename T> struct FITSUTIL {};
00047 
00048 template<> struct FITSUTIL<signed char>
00049   { enum { DTYPE=TBYTE }; };
00050 template<> struct FITSUTIL<short>
00051   { enum { DTYPE=TSHORT }; };
00052 template<> struct FITSUTIL<int>
00053   { enum { DTYPE=TINT }; };
00054 template<> struct FITSUTIL<long>
00055   { enum { DTYPE=TLONG }; };
00056 template<> struct FITSUTIL<long long>
00057   { enum { DTYPE=TLONGLONG }; };
00058 template<> struct FITSUTIL<float>
00059   { enum { DTYPE=TFLOAT }; };
00060 template<> struct FITSUTIL<double>
00061   { enum { DTYPE=TDOUBLE }; };
00062 
00063 /*! Converts a FITS type code (i.e. the data type of a FITS column) to the
00064     corresponding Planck type code. */
00065 inline int ftc2type (int ftc)
00066   {
00067   switch (ftc)
00068     {
00069     case TLOGICAL : return PLANCK_BOOL;
00070     case TBYTE    : return PLANCK_INT8;
00071     case TSHORT   : return PLANCK_INT16;
00072     case TINT32BIT: return PLANCK_INT32;
00073     case TLONGLONG: return PLANCK_INT64;
00074     case TFLOAT   : return PLANCK_FLOAT32;
00075     case TDOUBLE  : return PLANCK_FLOAT64;
00076     case TSTRING  : return PLANCK_STRING;
00077     default: throw Message_error ("ftc2type: unsupported component type");
00078     }
00079   }
00080 
00081 /*! Converts a Planck type code to the corresponding FITS type code
00082     (i.e. the data type of a FITS column). */
00083 inline int type2ftc (int type)
00084   {
00085   switch (type)
00086     {
00087     case PLANCK_BOOL   : return TLOGICAL;
00088     case PLANCK_INT8   : return TBYTE;
00089     case PLANCK_INT16  : return TSHORT;
00090     case PLANCK_INT32  : return TINT32BIT;
00091     case PLANCK_INT64  : return TLONGLONG;
00092     case PLANCK_FLOAT32: return TFLOAT;
00093     case PLANCK_FLOAT64: return TDOUBLE;
00094     case PLANCK_STRING : return TSTRING;
00095     default: throw Message_error ("type2ftc: unsupported component type");
00096     }
00097   }
00098 
00099 /*! Class containing information about a single column in a FITS table. */
00100 class fitscolumn
00101   {
00102   private:
00103     std::string name_, unit_;
00104     int64 repcount_;
00105     int type_;
00106 
00107   public:
00108     fitscolumn()
00109       : repcount_(0), type_(-1) {}
00110     /*! Creates a \a fitscolumn with name \a nm, unit \a un, a repetition
00111         count of \a rc, and a FITS type code of \a tp. */
00112     fitscolumn (const std::string &nm, const std::string &un, int64 rc,
00113       int tp)
00114       : name_(nm), unit_(un), repcount_(rc), type_(tp) {}
00115 
00116     /*! Returns the column name. */
00117     const std::string &name() const {return name_;}
00118     /*! Returns the column unit string. */
00119     const std::string &unit() const {return unit_;}
00120     /*! Returns the repetition count of the column. */
00121     int64 repcount() const {return repcount_;}
00122     /*! Returns the FITS type code of the column. */
00123     int type() const {return type_;}
00124   };
00125 
00126 /*! Class for performing I/O from/to FITS files. */
00127 class fitshandle
00128   {
00129   private:
00130     enum { INVALID = -4711 };
00131 
00132     mutable int status;
00133     fitsfile *fptr;
00134     int hdutype_, bitpix_;
00135     std::vector<int64> axes_;
00136     std::vector<fitscolumn> columns_;
00137     int64 nrows_;
00138 
00139     void check_errors() const;
00140 
00141     void clean_data();
00142     void clean_all();
00143 
00144     void assert_connected (const std::string &func) const
00145       {
00146       planck_assert (hdutype_!=INVALID,
00147         func + ": not connected to a HDU");
00148       }
00149     void assert_table_hdu (const std::string &func, unsigned int col) const
00150       {
00151       planck_assert ((hdutype_==ASCII_TBL) || (hdutype_==BINARY_TBL),
00152         func + ": HDU is not a table");
00153       planck_assert (col>0 && col<=columns_.size(),
00154         func + ": column number out of range");
00155       }
00156     void assert_image_hdu (const std::string &func) const
00157       {
00158       planck_assert ((hdutype_==IMAGE_HDU), func + ": HDU is not an image");
00159       }
00160 
00161     void init_image();
00162     void init_asciitab();
00163     void init_bintab();
00164     void init_data();
00165 
00166     void check_key_present(const std::string &name)const ;
00167 
00168     void read_col (int colnum, void *data, int64 ndata, int dtype,
00169                    int64 offset) const;
00170     void write_col (int colnum, const void *data, int64 ndata, int dtype,
00171                    int64 offset);
00172 
00173   public:
00174     /*! the list of modes in which a \a fitshandle can be opened. */
00175     typedef enum { CREATE, /*!< the file must not yet exist */
00176                    OPEN    /*!< the file must already exist */
00177                  } openmethod;
00178 
00179     /*! \name File-level access and manipulation. */
00180     /*! \{ */
00181 
00182     /*! Creates an unconnected \a fitshandle. */
00183     fitshandle ()
00184       : status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0) {}
00185     /*! Creates a \a fitshandle connected to file \a fname.
00186         If \a rwmode == READONLY, no writing access is permitted; if it is
00187         READWRITE, reading and writing can be performed. */
00188     fitshandle (const std::string &fname, openmethod mode=OPEN,
00189       int rwmode=READONLY)
00190       : status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0)
00191       {
00192       if (mode==OPEN)
00193         open (fname, rwmode);
00194       else
00195         create (fname);
00196       }
00197     /*! Creates a \a fitshandle connected to file \a fname and jumps directly
00198         to the HDU with the number \a hdunum.
00199         If \a rwmode == READONLY, no writing access is permitted; if it is
00200         READWRITE, reading and writing can be performed. */
00201     fitshandle (const std::string &fname, int hdunum, int rwmode=READONLY)
00202       : status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0)
00203       {
00204       open (fname, rwmode);
00205       goto_hdu (hdunum);
00206       }
00207 
00208     /*! Performs all necessary cleanups. */
00209     ~fitshandle() { clean_all(); }
00210 
00211     /*! Connects to the file \a fname.
00212         If \a rwmode == READONLY, no writing access is permitted; if it is
00213         READWRITE, reading and writing can be performed. */
00214     void open (const std::string &fname, int rwmode=READONLY);
00215     /*! Creates the file \a fname and connects to it. */
00216     void create (const std::string &fname);
00217     /*! Closes the current file. */
00218     void close () { clean_all(); }
00219     /*! Deletes the file with name \a name. */
00220     static void delete_file (const std::string &name);
00221     /*! Jumps to the HDU with the absolute number \a hdu. */
00222     void goto_hdu (int hdu);
00223     /*! Returns the number of HDUs in the file. */
00224     int num_hdus () const;
00225     /*! Asserts that the PDMTYPE of the current HDU is \a pdmtype. */
00226     void assert_pdmtype (const std::string &pdmtype) const;
00227     /*! Inserts a binary table described by \a cols.
00228         The HDU has the name \a extname. */
00229     void insert_bintab (const std::vector<fitscolumn> &cols,
00230       const std::string &extname="xtension");
00231     /*! Inserts an ASCII table described by \a cols. The width of the
00232         columns is chosen automatically, in a way that avoids truncation.
00233         The HDU has the name \a extname. */
00234     void insert_asctab (const std::vector<fitscolumn> &cols,
00235       const std::string &extname="xtension");
00236     /*! Inserts a FITS image with the type given by \a btpx and dimensions
00237         given by \a Axes. */
00238     void insert_image (int btpx, const std::vector<int64> &Axes);
00239     /*! Inserts a 2D FITS image with the type given by \a btpx, whose
00240         contents are given in \a data. */
00241     template<typename T>
00242       void insert_image (int btpx, const arr2<T> &data);
00243 
00244     /*! Computes the checksum for the current HDU and writes it into the
00245         header. */
00246     void write_checksum();
00247 
00248     /*! \} */
00249 
00250     /*! \name Information about the current HDU */
00251     /*! \{ */
00252 
00253     /*! If the current HDU is an image, returns the BITPIX parameter of that
00254         image, else throws an exception. */
00255     int bitpix() const
00256       {
00257       assert_image_hdu ("fitshandle::bitpix()");
00258       return bitpix_;
00259       }
00260     /*! Returns the FITS type code for the current HDU. */
00261     int hdutype() const {return hdutype_;}
00262     /*! Returns the dimensions of the current image. */
00263     const std::vector<int64> &axes() const
00264       {
00265       assert_image_hdu ("fitshandle::axes()");
00266       return axes_;
00267       }
00268     /*! Returns the name of column \a #i. */
00269     const std::string &colname(int i) const
00270       {
00271       assert_table_hdu("fitshandle::colname()",i);
00272       return columns_[i-1].name();
00273       }
00274     /*! Returns the unit of column \a #i. */
00275     const std::string &colunit(int i) const
00276       {
00277       assert_table_hdu("fitshandle::colunit()",i);
00278       return columns_[i-1].unit();
00279       }
00280     /*! Returns repetition count of column \a #i. */
00281     int64 repcount(int i) const
00282       {
00283       assert_table_hdu("fitshandle::repcount()",i);
00284       return columns_[i-1].repcount();
00285       }
00286     /*! Returns the FITS type code for column \a #i. */
00287     int coltype(int i) const
00288       {
00289       assert_table_hdu("fitshandle::coltype()",i);
00290       return columns_[i-1].type();
00291       }
00292     /*! Returns the number of columns in the current table. */
00293     int ncols() const
00294       {
00295       assert_table_hdu("fitshandle::ncols()",1);
00296       return columns_.size();
00297       }
00298     /*! Returns the number of rows in the current table. */
00299     int64 nrows() const
00300       {
00301       assert_table_hdu("fitshandle::nrows()",1);
00302       return nrows_;
00303       }
00304     /*! Returns the total number of elements (nrows*repcount)
00305         in column \a #i. */
00306     int64 nelems(int i) const
00307       {
00308       assert_table_hdu("fitshandle::nelems()",i);
00309       if (columns_[i-1].type()==TSTRING) return nrows_;
00310       return nrows_*columns_[i-1].repcount();
00311       }
00312 
00313     /*! \} */
00314 
00315     /*! \name Keyword-handling methods */
00316     /*! \{ */
00317 
00318     /*! Copies all header keywords from the current HDU of \a orig to
00319         the current HDU of \a *this. */
00320     void copy_header (const fitshandle &orig);
00321     /*! Copies all header keywords from the current HDU of \a orig to
00322         the current HDU of \a *this, prepending a HISTORY keyword to
00323         every line. */
00324     void copy_historified_header (const fitshandle &orig);
00325 
00326     /*! Returns a list of all user-defined keys in the current HDU
00327         in \a keys. */
00328     void get_all_keys (std::vector<std::string> &keys) const;
00329 
00330     /*! Adds a new header line consisting of \a key, \a value and
00331         \a comment. */
00332     template<typename T> void add_key (const std::string &name, const T &value,
00333       const std::string &comment="");
00334     /*! Updates \a key with \a value and \a comment. */
00335     template<typename T> void update_key (const std::string &name,
00336       const T &value, const std::string &comment="");
00337     /*! Deletes \a key from the header. */
00338     void delete_key (const std::string &name);
00339     /*! Adds \a comment as a comment line. */
00340     void add_comment (const std::string &comment);
00341     /*! Reads the value belonging to \a key and returns it in \a value. */
00342     template<typename T> void get_key (const std::string &name, T &value) const;
00343     /*! Returms the value belonging to \a key. */
00344     template<typename T> T get_key (const std::string &name) const
00345       { T tmp; get_key(name, tmp); return tmp; }
00346     /*! Returns \a true if \a key is present, else \a false. */
00347     bool key_present (const std::string &name) const;
00348     /*! Returns the Planck type code for the key \a name. */
00349     int get_key_type(const std::string &name) const;
00350 
00351     /*! \} */
00352 
00353     /*! \name Methods for table data I/O */
00354     /*! \{ */
00355 
00356     void read_column_raw_void
00357       (int colnum, void *data, int type, int64 num, int64 offset=0) const;
00358     /*! Copies \a num elements from column \a colnum to the memory pointed
00359         to by \a data, starting at offset \a offset in the column. */
00360     template<typename T> void read_column_raw
00361       (int colnum, T *data, int64 num, int64 offset=0) const
00362       { read_column_raw_void (colnum, data, typehelper<T>::id, num, offset); }
00363     /*! Fills \a data with elements from column \a colnum,
00364         starting at offset \a offset in the column. */
00365     template<typename T> void read_column
00366       (int colnum, arr<T> &data, int64 offset=0) const
00367       { read_column_raw (colnum, &(data[0]), data.size(), offset); }
00368     /*! Reads the element \a #offset from column \a colnum into \a data. */
00369     template<typename T> void read_column
00370       (int colnum, T &data, int64 offset=0) const
00371       { read_column_raw (colnum, &data, 1, offset); }
00372     /* Reads the whole column \a colnum into \a data (which is resized
00373        accordingly). */
00374     template<typename T> void read_entire_column
00375       (int colnum, arr<T> &data) const
00376       { data.alloc(nelems(colnum)); read_column (colnum, data); }
00377 
00378 
00379     void write_column_raw_void
00380       (int colnum, const void *data, int type, int64 num, int64 offset=0);
00381     /*! Copies \a num elements from the memory pointed to by \a data to the
00382         column \a colnum, starting at offset \a offset in the column. */
00383     template<typename T> void write_column_raw
00384       (int colnum, const T *data, int64 num, int64 offset=0)
00385       { write_column_raw_void (colnum, data, typehelper<T>::id, num, offset); }
00386     /*! Copies all elements from \a data to the
00387         column \a colnum, starting at offset \a offset in the column. */
00388     template<typename T> void write_column
00389       (int colnum, const arr<T> &data, int64 offset=0)
00390       { write_column_raw (colnum, &(data[0]), data.size(), offset); }
00391     /*! Copies \a data to the column \a colnum, at the position \a offset. */
00392     template<typename T> void write_column
00393       (int colnum, const T &data, int64 offset=0)
00394       { write_column_raw (colnum, &data, 1, offset); }
00395 
00396     /*! \} */
00397 
00398     /*! \name Methods for image data I/O */
00399     /*! \{ */
00400 
00401     /*! Reads the current image into \a data, which is resized accordingly. */
00402     template<typename T> void read_image (arr2<T> &data) const;
00403     /*! Reads the current image into \a data, which is resized accordingly. */
00404     template<typename T> void read_image (arr3<T> &data) const;
00405     /*! Reads a partial image, whose dimensions are given by the dimensions
00406         of \a data, into data. The starting pixel indices are given by
00407         \a xl and \a yl. */
00408     template<typename T> void read_subimage
00409       (arr2<T> &data, int xl, int yl) const;
00410     /*! Fills \a data with values from the image, starting at the offset
00411         \a offset in the image. The image is treated as a one-dimensional
00412         array. */
00413     template<typename T> void read_subimage (arr<T> &data, int64 offset=0)
00414       const;
00415     /*! Writes \a data into the current image. \a data must have the same
00416         dimensions as specified in the HDU. */
00417     template<typename T> void write_image (const arr2<T> &data);
00418     /*! Copies \a data to the image, starting at the offset
00419         \a offset in the image. The image is treated as a one-dimensional
00420         array. */
00421     template<typename T> void write_subimage (const arr<T> &data,
00422       int64 offset=0);
00423 
00424     /*! \} */
00425 
00426     void add_healpix_keys (int datasize);
00427   };
00428 
00429 /*! \} */
00430 
00431 // announce the specialisations
00432 template<> void fitshandle::add_key(const std::string &name,
00433   const bool &value, const std::string &comment);
00434 template<> void fitshandle::add_key (const std::string &name,
00435   const std::string &value, const std::string &comment);
00436 template<> void fitshandle::update_key(const std::string &name,
00437   const bool &value, const std::string &comment);
00438 template<> void fitshandle::update_key (const std::string &name,
00439   const std::string &value, const std::string &comment);
00440 template<> void fitshandle::get_key(const std::string &name,bool &value) const;
00441 template<> void fitshandle::get_key (const std::string &name,
00442   std::string &value) const;
00443 
00444 #endif

Generated on Fri Jun 18 16:12:29 2010 for LevelS C++ support library
Privacy / Copyright
FIRST GOV Contact: NASA Home Page Site Manager:
Webmaster:

CL 03-2650