#ifndef FITSFILE_H #define FITSFILE_H #include "ndatablock.h" #include "dvlist.h" #include "FitsIO/fitsio.h" #define OPENFILE 0 #define CREATEFILE 1 #define LEN_KEYWORD 9 namespace SOPHYA { struct BnTblLine { BnTblLine() {} void setFormat(int dc, int fc, int ic, int cc, vector names) { int nbcols = dc + fc + ic + cc; ColName_ = vector(nbcols); for (int k=0; k < nbcols; k++) ColName_ = names; if (dc >0) ddata_ = vector(dc); if (fc >0) fdata_ = vector(fc); if (ic >0) idata_ = vector(fc); if (cc >0) cdata_ = vector(fc); } void Print() { int k; int compt = 0; cout << " ********* ligne ************* " << endl; cout << " *** noms de variables " << endl; for (k=0; k < compt + ColName_.size(); k++) cout << ColName_[k] << " "; cout << endl; cout << " *** variables doubles " << endl; for (k=0; k < ddata_.size(); k++) cout << ddata_[k] << " "; cout << endl; cout << " *** variables float " << endl; for (k=0; k < fdata_.size(); k++) cout << fdata_[k] << " "; cout << endl; cout << " *** variables int " << endl; for (k=0; k < idata_.size(); k++) cout << idata_[k] << " "; cout << endl; cout << " *** variables string " << endl; for (k=0; k < cdata_.size(); k++) cout << cdata_[k] << " "; cout << endl; cout << " ***************************** " << endl; } vector ddata_; vector fdata_; vector idata_; vector cdata_; vector ColName_; }; class FitsFile; class FitsInFile; class FitsOutFile; enum WriteMode {append, clear, unknown}; // //! Class for managing Interface for SOPHYA objects to FITS Format Files (uses cfitsio lib) /*! The class structure is analogous to Sophya-PPersist system : Each SOPHYA object XXX is associated with a object of class FITS_XXX (inheriting from FitsFileHandler), to which input/output operations with FITS files are delegated (through a class Hierarchy : FitsFile (virtual), FitsInFile, FitsOutFile) . A typical example of use is the following : \verbatim int m=... ; SphereHEALPix sphere1(m); // definition of the SOPHYA object .... fill the sphere .... FITS_SphereHEALPix fits_sph1(sphere1); // delegated object fits_sph.Write("myfile.fits"); // writing on FITS file FITS_SphereHEALPix fits_sph2("myfile.fits"); // load a delegated object // from FITS file SphereHEALPix sphere2=(SphereHEALPix)fits_sph2; // casting the delegated object // into a SOPHYA object \endverbatim */ class FitsIOHandler { public: virtual ~FitsIOHandler() {} /*! this method is called from inherited objects : opens a file 'flnm' gets parameters in extension-header (hdunum) calls the method 'ReadFromFits' from the inherited object */ void Read(char flnm[],int hdunum= 0); /*! this method is called from inherited objects : for writing a new object in a new fits-extension : ??? at the end of the existing file (flnm), if OldFile=true. If OldFile=false, an exception occurs By convention, primary header does not contain fits-image data : i.e. all data are fits-extensions. The first relevant header will have hdunum=2. For switching off this convention use the method : firstImageOnPrimaryHeader() (see below) In that case do not forget to precise hdunum=1 when reading data on primary header. calls the method 'WriteToFits' from the inherited object */ void Write(char flnm[]) ; /*! Read the data on extension hdunum (or primary header, if hdunum=1) from FitsInFIle. With default value for hdunum, one reads the next extension, with respect to the current position. */ void Read(FitsInFile& ifts, int hdunum=0); void Write(FitsOutFile& ofts) ; protected: virtual void ReadFromFits(FitsInFile& is)=0; virtual void WriteToFits(FitsOutFile& os) =0; friend class FitsInFile; friend class FitsOutFile; private : }; class FitsFile { public: FitsFile() { InitNull(); }; virtual ~FitsFile(); static string getErrStatus(int status); inline int statusF() const { return fits_status_;} protected: void ResetStatus(int& status) ; static void printerror(int&) ; static void printerror(int&,char* texte) ; inline void InitNull() {fptr_ = NULL; hdutype_= 0; hdunum_ = 1; fits_status_ = 0;} //! pointer to the FITS file, defined in fitsio.h fitsfile *fptr_; //! image or bintable ? int hdutype_; //! index of header to be read/written int hdunum_; //! last status returned by fitsio library. updated only by several methods int fits_status_; }; class FitsInFile : public FitsFile { public: FitsInFile(); // FitsInFile(char flnm[], int hdunum=0); FitsInFile(char flnm[]); ~FitsInFile() { ; }; ////////////////////////////////////////////////////////// // methods with general purpose /////////////////////////////////////// static int NbBlocks(char flnm[]); static void getBlockType(char flnm[], int hdunum, string& typeOfExtension, int& naxis, vector& naxisn, string& dataType, DVList& dvl ); // void ReadFInit(char flnm[],int hdunum=0); void ReadFInit(int hdunum); /*! return a reference on a DVList containing the keywords from FITS file */ inline const DVList& DVListFromFits() const { return dvl_;} /* get the keywords of primary header in a DVList */ DVList DVListFromPrimaryHeader() const; void moveToFollowingHeader(); ////////////////////////////////////////////////////////// /////// methods for managing extensions //////////////// ////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// // methods for managing FITS IMAGE extension /////////////////////////////////////////////////// /*! return true if the current header corresponds to a FITS image extension */ inline bool IsFitsImage() const { return (hdutype_ == IMAGE_HDU);} /*! number of dimensions of an image extension : NAXIS parameter (in FITS notations) */ inline int nbDimOfImage() const {return naxis_;} /*! a reference on a vector containing sizes of the NAXIS dimensions : NAXIS1, NAXIS2, NAXIS3 wtc. */ inline const vector& dimOfImageAxes() const { return naxisn_;} /*! total number of data in the current IMAGE extension */ inline int nbOfImageData() const { return nbData_; } ////////////////////////////////////////////////////////////////////////// // methods for managing FITS BINARY TABLE or ASCII TABLE extension //////////////////////////////////////////////////////////////////////// /*! return true if the current header corresponds to a FITS ASCII or BINTABLE extension */ inline bool IsFitsTable() const {return (hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL);} static void GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows, vector& repeat, vector& noms, vector& types, vector& taille_des_chaines); /*! return a character denoting data type of column number 'nocol' in a BINTABLE : D : double E : float I : integer S : character string */ char ColTypeFromFits(int nocol) const; /*! name of the column number 'nocol' of the current BINTABLE extension */ string ColNameFromFits(int nocol) const; /*! number of characters of each data for the column number 'nocol' (if char* typed) of the current BINTABLE extension */ int ColStringLengthFromFits(int nocol) const; /*! get the NoLine-th 'line' from the current BINTABLE extension on FITS file, */ void GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata) ; /*! get the NoLine-th 'line' from the current BINTABLE extension on FITS file, */ void GetBinTabLine(long NoLine, BnTblLine& ligne) ; /*! get the NoLine-th 'line' from the current BINTABLE extension on FITS file, */ void GetBinTabLine(int NoLine, float* fdata) ; /*! fill the array 'valeurs' with double data from the current BINTABLE extension on FITS file, from column number 'NoCol' \param number of data to be read */ void GetBinTabFCol(double* valeurs, int nentries, int NoCol) const; /*! same as previous method with float data */ void GetBinTabFCol(float* valeurs, int nentries, int NoCol) const; /*! same as previous method with int data */ void GetBinTabFCol(int* valeurs, int nentries, int NoCol) const; /*! same as previous method with char* data */ void GetBinTabFCol(char** valeurs,int nentries, int NoCol) const; // Write elements into the FITS data array ///////////////////////////////////////////////////////////// // methods for managing any type of FITS extension //////////////////////////////////////////////////////// /*! return number of columns (return 1 if IMAGE) */ int NbColsFromFits() const; /*! number of data in the current IMAGE extension on FITS file, or number of data of column number 'nocol' of the current BINTABLE extension */ int NentriesFromFits(int nocol) const; /*! fill the array 'map' with double data from the current extension on FITS file. If the extension is BINTABLE, the first column is provided. \param number of data to be read */ void GetSingleColumn(double* map, int nentries) const; /*! same as above with float data */ void GetSingleColumn(float* map, int nentries) const; /*! same as above with int data */ void GetSingleColumn(int* map, int nentries) const; private : void InitNull(); static void KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum); static void GetImageParameters (fitsfile* fileptr,int& bitpix,int& naxis,vector& naxisn); //! fits-Image parameter int bitpix_; //! fits-Image parameter int naxis_; //! fits-Image parameters : sizes of dimensions vector naxisn_; //! fits-Image parameter: number of data int nbData_; //! Bintable parameter int nrows_; //! Bintable parameter vector repeat_; //! Bintable parameter int nbcols_; //! Bintable parameter: column names vector noms_; //! Bintable parameters: types of columns (D: double, E: float, I: integers, A: char*) vector types_; //! Bintable parameters: length of the char* variables vector taille_des_chaines_; //! DVList for transferring keywords DVList dvl_; }; class FitsOutFile : public FitsFile { public: FitsOutFile(); /*! \param enum , WriteMode = clear -> if alreadyy exists, the file will be overwritten (else created) ; WriteMode = append -> further objects will be appended to the file if it exists (else : file created). WriteMode = unknown -> file created if does not exist, else : exception. (the last situation is the default) */ FitsOutFile(char flnm[], WriteMode wrm = unknown ); ~FitsOutFile() { ;}; inline void InitNull() {imageOnPrimary_=false;} ////////////////////////////////////////////////////////// /////// methods for managing extensions //////////////// ////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// // methods for managing FITS IMAGE extension /////////////////////////////////////////////////// inline void firstImageOnPrimaryHeader() {imageOnPrimary_=true;} /*! create an IMAGE header on FITS file. \param type of data (see method ColTypeFromFits) \param number of dimensions : 1D, 2D, 3D etc. = NAXIS \param array containind sizes of the different dimensions */ void makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList &dvl) ; /*! write double data from array 'map'on an IMAGE extension \param number of data to be written */ void putImageToFits( int nbData, double* map) const; /*! same as previous method with float data */ void putImageToFits(int nbData, float* map ) const; /*! same as previous method with int data */ void putImageToFits(int nbData, int* map) const; ////////////////////////////////////////////////////////////////////////// // methods for managing FITS BINARY TABLE or ASCII TABLE extension //////////////////////////////////////////////////////////////////////// /*! create an BINTABLE header on FITS file. \param array conta ining characters denoting types of the different column (see method ColTypeFromFits) \param array of the names of columns \param number of data of each column \param number of columns \param a SOPHYA DVList containing keywords to be appended \param keyword EXTNAME for FITS file \param vector containing the number of characters of data for each char* typed column, with order of appearance in 'fieldType' */ void makeHeaderBntblOnFits ( string fieldType, vector Noms, int nentries, int tfields, DVList &dvl, string extname, vector taille_des_chaines) ; /*! write double data from array 'donnees ' on column number 'nocol' of a BINTABLE extension. \param number of data to be written */ void putColToFits(int nocol, int nentries, double* donnees) const; /*! same as previous method with float data */ void putColToFits(int nocol, int nentries, float* donnees) const; /*! same as previous method with int data */ void putColToFits(int nocol, int nentries, int* donnees) const; /*! same as previous method with char* data */ void putColToFits(int nocol, int nentries, char** donnees) const; void putBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata) const; ///////////////////////////////////////////////////////////// // methods for managing any type of FITS extension //////////////////////////////////////////////////////// /* put keywords from a DVList into the primary header of the fits-file */ void DVListIntoPrimaryHeader(DVList& dvl) const; private : void writeSignatureOnFits() const; void addKeywordsOfDVList(DVList& dvl) const; bool imageOnPrimary_; }; } // Fin du namespace #endif