#include "machdefs.h" #include #include "fitsfile.h" #include "pexceptions.h" #include "strutil.h" #include "anydataobj.h" #include "fitsspherehealpix.h" void FitsIOHandler::Read(char flnm[],int hdunum) { // FitsInFile ifts(flnm, hdunum); FitsInFile ifts(flnm); Read(ifts, hdunum); } void FitsIOHandler::Read(FitsInFile& is, int hdunum) { if (hdunum == 0) is.moveToFollowingHeader(); else is.ReadFInit(hdunum); ReadFromFits(is); } void FitsIOHandler::Write(char flnm[], bool OldFile) { FitsOutFile of(flnm, OldFile); Write(of); } void FitsIOHandler::Write(FitsOutFile& os) { WriteToFits(os); } FitsFile::~FitsFile() { cout << " destructeur FitsFile " << endl; int status = 0; if( fptr_ != NULL) { fits_close_file(fptr_,&status); delete fptr_; } if( status ) printerror( status ); } void FitsFile::printerror(int &status) //*****************************************************/ //* Print out cfitsio error messages and exit program */ //*****************************************************/ { if( status ) { fits_report_error(stderr,status); throw IOExc("FitsFile:: error FITSIO status"); } return; } void FitsFile::printerror(int& status, char* texte) //*****************************************************/ //* Print out cfitsio error messages and exit program */ //*****************************************************/ { // print out cfitsio error messages and exit program // print error report fits_report_error(stderr, status); cout << " erreur:: " << texte << endl; throw IOExc("FitsFile:: error FITSIO status"); } void FitsFile::ResetStatus(int& status) { fits_status_ = status; status = 0; } string FitsFile::getErrStatus(int status) { char text[31]; fits_get_errstatus(status, text); return string(text); } FitsInFile::FitsInFile() { InitNull(); } //FitsInFile::FitsInFile(char flnm[], int hdunum) FitsInFile::FitsInFile(char flnm[]) { InitNull(); int status = 0; fits_open_file(&fptr_,flnm,READONLY,&status); if( status ) printerror( status ); // ReadFInit(flnm, hdunum); } void FitsInFile::InitNull() { cout << " init FitsInFile " << endl; bitpix_ = 0; naxis_ = 0; nbData_ = 0; nrows_ = 0; nbcols_ = 0; naxisn_.clear(); repeat_.clear(); noms_.clear(); taille_des_chaines_.clear(); dvl_.Clear(); } int FitsInFile::NbBlocks(char flnm[]) { int status = 0; int nbhdu = 0; fitsfile* fileptr; fits_open_file(&fileptr,flnm,READONLY,&status); if( status ) printerror( status, "NbBlocks: erreur ouverture fichier" ); fits_get_num_hdus(fileptr, &nbhdu, &status); fits_close_file(fileptr,&status); return nbhdu; } void FitsInFile::getBlockType(char flnm[], int hdunum, string& typeOfExtension, int& naxis, vector& naxisn, string& dataType, DVList& dvl ) { int status = 0; fitsfile* fileptr; fits_open_file(&fileptr,flnm,READONLY,&status); if( status ) printerror( status, "getBlockType: erreur ouverture fichier" ); // move to the specified HDU number int hdutype = 0; fits_movabs_hdu(fileptr,hdunum,&hdutype,&status); if( status ) printerror( status,"getBlockType: erreur movabs"); if(hdutype == IMAGE_HDU) { typeOfExtension = "IMAGE"; int bitpix; GetImageParameters (fileptr, bitpix, naxis, naxisn); if(bitpix == DOUBLE_IMG) dataType = "double"; else if(bitpix == FLOAT_IMG) dataType = "float"; else if(bitpix == LONG_IMG || bitpix == SHORT_IMG ) dataType = "int"; else { cout << " bitpix= " << bitpix << endl; throw PException(" FitsFile::getBlockType : unsupprted FITS data type"); } } else if(hdutype == ASCII_TBL || hdutype == BINARY_TBL) { int nrows = 0; vector noms; vector types; vector taille_des_chaines; GetBinTabParameters(fileptr, naxis, nrows, naxisn, noms, types, taille_des_chaines); int k; for (k=0; k< naxisn.size(); k++) naxisn[k] *= nrows; if(hdutype == ASCII_TBL) { typeOfExtension = "ASCII_TBL"; dataType = "ASCII"; } else { typeOfExtension = "BINARY_TBL"; if(types[0] == 'D') dataType = "double"; else if(types[0] == 'E') dataType = "float"; else if(types[0] == 'I' ) dataType = "int"; else if(types[0] == 'S' ) dataType = "char*"; else { cout << " types[0]= " << types[0] << endl; throw PException(" FitsFile::getBlockType : unsupprted FITS data type"); } } } else { cout << " hdutype= " << hdutype << endl; throw IOExc("FitsFile::getBlockType: this HDU type is unknown"); } KeywordsIntoDVList(fileptr, dvl, hdunum); fits_close_file(fileptr,&status); } void FitsInFile::GetImageParameters (fitsfile* fileptr,int& bitpix,int& naxis,vector& naxisn) { int hdunum=0; cout << " Reading a FITS image in HDU : " << fits_get_hdu_num(fileptr,&hdunum) << endl; int status= 0; // bits per pixels fits_read_key(fileptr,TINT,"BITPIX",&bitpix,NULL,&status); if( status ) printerror( status ); // number of dimensions in the FITS array naxis= 0; fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status); if( status ) printerror( status ); // cout << " dimension lue " << naxis << endl; // read the NAXISn keywords to get image size long* naxes = new long[naxis] ; int nfound; fits_read_keys_lng(fileptr,"NAXIS",1,naxis,naxes,&nfound,&status); if( status ) printerror( status ); if (nfound != naxis ) cout << " WARNING : " << nfound << " axes found, expected naxis= " << naxis << endl; int k; for (k=0; k 0 ) // there is an image { hdutype_ = IMAGE_HDU; GetImageParameters (fptr_, bitpix_, naxis_, naxisn_); nbData_ = 1; int k; for (k=0; k 0) nbData_ *= naxisn_[k]; KeywordsIntoDVList(fptr_, dvl_,hdunum_); } else { throw PException(" first header : no image, probably error in hdunum"); } // } else { hdunum_ = hdunum-1; int hdutype; fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status); if( status ) printerror( status,":FitsFile::ReadF : erreur movabs"); moveToFollowingHeader(); } } void FitsInFile::moveToFollowingHeader() { int status = 0; int hdutype; fits_movrel_hdu(fptr_, 1,&hdutype,&status); if( status ) printerror( status," lecture du header suivant" ); hdunum_++; hdutype_= hdutype; if(hdutype_ == IMAGE_HDU) { GetImageParameters (fptr_, bitpix_, naxis_, naxisn_); nbData_ = 1; int k; for (k=0; k 0) nbData_ *= naxisn_[k]; KeywordsIntoDVList(fptr_, dvl_,hdunum_); } if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL) { GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_); KeywordsIntoDVList(fptr_, dvl_, hdunum_); } } int FitsInFile::NbColsFromFits() const { if(hdutype_ == BINARY_TBL) return nbcols_; else if(hdutype_ == ASCII_TBL || hdutype_ == IMAGE_HDU) return 1; else { cout << " hdutype= " << hdutype_ << endl; throw PException("FitsFile::NbColsFromFits, this HDU is unknown"); } } int FitsInFile::NentriesFromFits(int nocol) const { if(hdutype_ == BINARY_TBL ) return nrows_*repeat_[nocol]; else if(hdutype_ == ASCII_TBL) return nrows_; else if(hdutype_ == IMAGE_HDU) return nbData_; else { cout << "hdutype= " << hdutype_ << endl; throw PException("FitsFile::NentriesFromFits, this HDU is unknown"); } } char FitsInFile::ColTypeFromFits(int nocol) const { if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL) { throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table"); } return types_[nocol]; } string FitsInFile::ColNameFromFits(int nocol) const { if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL) { throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table"); } return noms_[nocol]; } int FitsInFile::ColStringLengthFromFits(int nocol) const { if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL) { throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table"); } int index=-1; int k; for (k=0; k<=nocol; k++) { if (types_[k] == 'S') index++; } return taille_des_chaines_[index]; } void FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata) { int status= 0; int anull; double dnull= 0.; float fnull= 0.; int inull= 0; char* cnull= ""; int dcount = 0.; int fcount = 0.; int icount = 0; int ccount =0; int ncol; long nels=1; for (ncol=0; ncol& repeat, vector& noms, vector& types, vector& taille_des_chaines) { int status= 0; int hdunum=0; int hdutype=0; fits_get_hdu_num(fileptr,&hdunum); fits_get_hdu_type(fileptr, &hdutype, &status); if(hdutype != ASCII_TBL && hdutype != BINARY_TBL) { throw IOExc("FitsFile::GetBinTabParameters this HDU is not an ASCII table nor a binary table"); } if(hdutype == ASCII_TBL) cout << " Reading a FITS ascii table in HDU : " << hdunum << endl; if(hdutype == BINARY_TBL) cout << " Reading a FITS binary table in HDU : " << hdunum << endl; // get the number of columns fits_get_num_cols(fileptr, &nbcols,&status); if( status ) printerror( status ); // get the number of rows long naxis2= 0; fits_get_num_rows(fileptr,&naxis2,&status); if( status ) printerror( status ); nrows = (int)naxis2; // get the datatype, names and the repeat count noms.clear(); noms.reserve(nbcols); types.clear(); types.reserve(nbcols); repeat.clear(); repeat.reserve(nbcols); taille_des_chaines.clear(); char **ttype = new char*[nbcols]; int ii; for (ii=0; ii < nbcols; ii++) ttype[ii]=new char[FLEN_VALUE]; int nfound; fits_read_keys_str(fileptr, "TTYPE",1,nbcols,ttype,&nfound, &status); if( status ) printerror( status,"erreur lecture des noms de colonne"); int rept=0; for(ii = 0; ii < nbcols; ii++) { int DTYPE; long width; long repete = 0; fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status); if( status ) printerror( status,"erreur lecture type de colonne"); rept = repete; noms.push_back(string(ttype[ii])); switch (DTYPE) { case TDOUBLE : types.push_back('D'); break; case TFLOAT : types.push_back('E'); break; case TLONG : types.push_back('I'); break; case TINT : types.push_back('I'); break; case TSHORT : types.push_back('I'); break; case TSTRING : types.push_back('S'); taille_des_chaines.push_back(width); rept/=width; break; default : cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl; throw IOExc("FitsFile:: unknown type of field"); } repeat.push_back(rept); } for (ii=0; ii < nbcols; ii++) delete [] ttype[ii]; delete [] ttype; } void FitsInFile::KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum) { int status = 0; int hdutype; fits_movabs_hdu(fileptr,hdunum,&hdutype,&status); if( status ) printerror( status,":KeywordsIntoDVList : erreur movabs"); // get number of keywords int nkeys,keypos; fits_get_hdrpos(fileptr,&nkeys,&keypos,&status); if( status ) printerror( status ); // put keywords in a DVList object char keyname[LEN_KEYWORD]= ""; char strval[FLEN_VALUE]= ""; char dtype; char card[FLEN_CARD]; char *comkey = "COMMENT"; // shift with the number of mandatory keywords int num= 8; int j; for(j = num+1; j <= nkeys; j++) { fits_read_keyn(fileptr,j,card,strval,NULL,&status); if(status) printerror(status); strncpy(keyname,card,LEN_KEYWORD-1); if(strncmp(keyname,comkey,LEN_KEYWORD-1) != 0 && strlen(keyname) != 0 && strlen(strval) != 0) { fits_get_keytype(strval,&dtype,&status); if(status) printerror(status); strip(keyname, 'B',' '); strip(strval, 'B',' '); strip(strval, 'B','\''); switch( dtype ) { case 'C': dvl[keyname]= strval; break; case 'I': int ival; fits_read_key(fileptr,TINT,keyname,&ival,NULL,&status); dvl[keyname]= (int_4) ival; // Portage mac DY break; case 'L': int ilog; if(strncmp(strval,"T",1) == 0) ilog= 1; else ilog= 0; dvl[keyname]= (int_4) ilog; break; case 'F': double dval; fits_read_key(fileptr,TDOUBLE,keyname,&dval,NULL,&status); dvl[keyname]= dval; break; } } } // dvl_.Print(); } FitsOutFile::FitsOutFile() { InitNull(); } FitsOutFile::FitsOutFile(char flnm[], bool OldFile) { InitNull(); int status = 0; // create new FITS file if (!OldFile) { fits_create_file(&fptr_,flnm,&status); if( status ) printerror(status,"file already exists"); } else { fits_open_file(&fptr_,flnm,READWRITE,&status); if( status ) printerror(status,"file does not exist"); fits_get_num_hdus(fptr_, &hdunum_, &status); int hdutype; fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status); if( status ) printerror( status,":FitsFile::WriteF : erreur movabs"); } } void FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn) { int status = 0; long naxis = nbdim; long* naxes = new long[nbdim]; if (hdunum_ == 1) { if (imageOnPrimary_ == false) fits_create_img(fptr_,FLOAT_IMG,0,naxes,&status); else hdunum_--; } int k; for (k=0; k< nbdim; k++) naxes[k] = (long)naxisn[k]; if (type == 'D') fits_create_img(fptr_,DOUBLE_IMG,naxis,naxes,&status); else if (type == 'E') fits_create_img(fptr_,FLOAT_IMG,naxis,naxes,&status); else if (type == 'I') fits_create_img(fptr_,LONG_IMG,naxis,naxes,&status); else { cout << " type of data: " << type << endl; throw PException("FitsFile:::makeHeaderImageOnFits:unprogrammed type of data "); } hdunum_++; delete [] naxes; if( status ) printerror( status, "erreur creation HDU IMAGE" ); } void FitsOutFile::putImageToFits(int nbData, double* map) const { int status = 0; long npix= nbData; fits_write_img(fptr_,TDOUBLE,1,npix,map,&status); if( status ) printerror( status, "erreur ecriture putImageToFits" ); writeSignatureOnFits(); } void FitsOutFile::putImageToFits(int nbData, float* map) const { int status = 0; long npix= nbData; fits_write_img(fptr_,TFLOAT,1,npix, map,&status); if( status ) printerror( status, "erreur ecriture putImageToFits" ); writeSignatureOnFits(); } void FitsOutFile::putImageToFits( int nbData, int* map) const { int status = 0; long npix= nbData; fits_write_img(fptr_,TINT,1,npix,map,&status); if( status ) printerror( status, "erreur ecriture putImageToFits" ); writeSignatureOnFits(); } void FitsOutFile::makeHeaderBntblOnFits( char* fieldType, char** Noms, int nentries, int tfields, DVList &dvl, char* extname, vector taille_des_chaines) { int status = 0; long nrows; if (strlen(fieldType) != tfields) { cout << " nombre de champs :" << tfields << "nombre de types: " << strlen(fieldType) << endl; throw ParmError("FitsFile:: fields and types don't match"); } char ** ttype= new char*[tfields]; char ** tform= new char*[tfields]; char largeur[FLEN_VALUE]; int noColString=0; int k; for (k=0; kc_str(),127); strncpy(comment,(*it).second.elcomm.c_str(),FLEN_COMMENT ); fits_write_key(fptr_,TSTRING,keyname,&strval,comment,&status); break; } } if( status ) printerror( status,"fitsfile: probleme ecriture mot-cle du dvlist" ); } fits_write_comment(fptr_,"--------------------------------------", &status); } void FitsOutFile::putColToFits(int nocol, int nentries, double* donnees) const { int status = 0; int hdutype; fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status); if( status ) printerror(status,"putColToFits: le movabs a foire"); fits_get_hdu_type(fptr_, &hdutype, &status); if(hdutype != ASCII_TBL && hdutype != BINARY_TBL) { cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl; throw IOExc("FitsFile::putColToFits, this HDU is not an ASCII table nor a binary table"); } int code; long repeat, width; fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status); if( code != TDOUBLE) { cout << " WARNING : types don't match (putColToFits) : on fits file= " << code << " to be written= DOUBLE " << endl; } fits_write_col(fptr_,TDOUBLE,nocol+1,1,1,nentries, donnees ,&status); if( status ) printerror( status,"erreur ecriture du fichier fits" ); } void FitsOutFile::putColToFits(int nocol, int nentries, float* donnees) const { int status = 0; int hdutype; fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status); if( status ) printerror(status,"putColToFits: le movabs a foire"); fits_get_hdu_type(fptr_, &hdutype, &status); if(hdutype != ASCII_TBL && hdutype != BINARY_TBL) { cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl; throw IOExc("FitsFile::putColToFits, this HDU is not an ASCII table nor a binary table"); } if(hdutype == ASCII_TBL && nocol>0) { throw IOExc("FitsFile::putColToFits, this HDU is an ASCII table, nocol>0 forbidden"); } int code; long repeat, width; fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status); if( code != TFLOAT) { cout << " WARNING : types don't match (putColToFits) : on fits file= " << code << " (FITS code), to be written= FLOAT " << endl; } fits_write_col(fptr_,TFLOAT,nocol+1,1,1,nentries, donnees ,&status); if( status ) printerror( status,"erreur ecriture du fichier fits" ); } void FitsOutFile::putColToFits(int nocol, int nentries, int* donnees) const { int status = 0; int hdutype; fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status); if( status ) printerror(status,"putColToFits: le movabs a foire"); fits_get_hdu_type(fptr_, &hdutype, &status); if(hdutype != ASCII_TBL && hdutype != BINARY_TBL) { cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl; throw IOExc("FitsFile::putColToFits, this HDU is not an ASCII table nor a binary table"); } if(hdutype == ASCII_TBL && nocol>0) { throw IOExc("FitsFile::putColToFits, this HDU is an ASCII table, nocol>0 forbidden"); } int code; long repeat, width; fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status); if( code != TLONG && code != TINT && code != TSHORT ) { cout << " WARNING : types don't match (putColToFits) : on fits file= " << code << " (FITS code), to be written= INT " << endl; } fits_write_col(fptr_,TINT,nocol+1,1,1,nentries, donnees ,&status); if( status ) printerror( status," ecriture du fichier fits" ); } void FitsOutFile::putColToFits(int nocol, int nentries, char** donnees) const { int status = 0; int hdutype; fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status); if( status ) printerror(status,"putColToFits: le movabs a foire"); fits_get_hdu_type(fptr_, &hdutype, &status); if(hdutype != ASCII_TBL && hdutype != BINARY_TBL) { cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl; throw IOExc("FitsFile::putColToFits, this HDU is not an ASCII table nor a binary table"); } if(hdutype == ASCII_TBL && nocol>0) { throw IOExc("FitsFile::putColToFits, this HDU is an ASCII table, nocol>0 forbidden"); } int code; long repeat, width; fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status); if( code != TSTRING) { cout << " WARNING : types don't match (putColToFits) : on fits file= " << code << " (FITS code), to be written= char** " << endl; } fits_write_col(fptr_,TSTRING,nocol+1,1,1,nentries, donnees ,&status); if( status ) printerror( status,"erreur ecriture du fichier fits" ); } void FitsOutFile::writeSignatureOnFits() const { int status = 0; char keyname[LEN_KEYWORD]; char strval[FLEN_VALUE]; char comment[FLEN_COMMENT]; strncpy(keyname, "CREATOR", LEN_KEYWORD); keyname[LEN_KEYWORD-1] = '\0'; strcpy(strval, "SOPHYA"); strcpy(comment," SOPHYA Package - FITSIOServer "); fits_write_key(fptr_, TSTRING, keyname, &strval, comment, &status); if( status ) printerror( status ); fits_write_comment(fptr_,"..............................................", &status); fits_write_comment(fptr_, " SOPHYA package - FITSIOSever ", &status); fits_write_comment(fptr_, " (C) LAL/IN2P3-CNRS Orsay, FRANCE 2000", &status); fits_write_comment(fptr_, " (C) DAPNIA/CEA Saclay, FRANCE 2000", &status); fits_write_comment(fptr_,"..............................................", &status); if( status ) printerror( status, "erreur writeSignatureOnFits" ); }