/* Writer de table Fits (binaire ou ASCII) */ #include "machdefs.h" #include #include #include "pexceptions.h" #include "fabtwriter.h" /*! \class SOPHYA::FitsABTWriter \ingroup FitsIOServer Class for writing a FITS ASCII or BINARY table \verbatim //----------------------------------------------------------- -- Exemple 1: Writing element by element FitsABTWriter fbtw(fitswrit,BINARY_TBL); fbtw.SetExtName("MY_OWN_EXTENSION"); fbtw.AddCol("vars",NULL,"km",TSHORT); // col=0 fbtw.AddCol("vars2",NULL,"km",TSHORT); // col=1 fbtw.AddCol("varl",NULL,"Degre",TLONG); // col=2 fbtw.AddCol("varf",NULL,"",TFLOAT); // col=3 fbtw.AddCol("vard","","arcmin",TDOUBLE); // col=4 fbtw.SetDebug(3); for(long i=0;i<1000;i++) { double x = i; fbtw.Write(0,i,1000.*x); // if overflow, managed by cfitsio // Write(int,long,double) is called fbtw.Write(1,i,(short)(1000.*x)); // if overflow, managed by language // Write(int,long,short) is called fbtw.Write(2,i,x); fbtw.Write(3,i,x); fbtw.Write(4,i,x); } cout<<"Number of Overflows when writing: " < datad(100); TVector dataf(100); TVector datal(100); for(long i=0;i<9990;i+=100) { long i2=i+100-1; if(i2>=9990) i2=9990-1; for(long j=0;j<100;j++) datad(i) = ...; for(long j=0;j<100;j++) dataf(i) = ...; for(long j=0;j<100;j++) datal(i) = ...; fbtw.Write(1,i,datal); fbtw.Write(2,i,dataf); fbtw.Write(3,i,datad); } \endverbatim */ ////////////////////////////////////////////////////////////// /*! Constructor. \param fname : FITS file name to be written \param hdutype : type of extension to be created (BINARY_TBL or ASCII_TBL) \param lp : debug level */ FitsABTWriter::FitsABTWriter(string fname,int hdutype,int lp) { createfits(fname.c_str(),hdutype,lp); } /*! See FitsABTWriter() */ FitsABTWriter::FitsABTWriter(const char* cfname,int hdutype,int lp) { createfits(cfname,hdutype,lp); } /*! See FitsABTWriter() */ void FitsABTWriter::createfits(const char *cfname,int hdutype,int lp) { FirstTime = true; FitsPtr = NULL; HduType = hdutype; SetDebug(lp); FitsFN = cfname; NOverFlow = 0; if(DbgLevel) cout<<"FitsABTWriter::createfits FitsFN="<0) for(unsigned int i=0;i(DoubleKey[i].keyname.c_str()); char* com = const_cast(DoubleKey[i].comment.c_str()); double val = DoubleKey[i].val; if(fits_update_key(FitsPtr,TDOUBLE,key,&val,com,&sta)) printerror(sta); } if(LongKey.size()>0) for(unsigned int i=0;i(LongKey[i].keyname.c_str()); char* com = const_cast(LongKey[i].comment.c_str()); long val = LongKey[i].val; if(fits_update_key(FitsPtr,TLONG,key,&val,com,&sta)) printerror(sta); } DoubleKey.resize(0); LongKey.resize(0); } ////////////////////////////////////////////////////////////// /*! Add a new column to the FITS table \param label : column label \param tform : fits tform definition ("1I","1J","1E","1J",...) (can be automatically set as "datatype" if BINARY_TBL and tform="" or tform=NULL) \param tunit : fits tunit definition (optional) \param datatype : TBYTE TSHORT TLONG (TINT32BIT) TFLOAT TDOUBLE TUSHORT TULONG. That parameter is only use in case of a BINARY_TBL table when tform is not defined). \return The number of the new added column in the table. \warning col = [0,ncol-1] */ int FitsABTWriter::addcol(const char* label,const char* tform ,const char* tunit,int datatype) { if(!FirstTime) throw AllocationError("FitsABTWriter::addcol: table already created\n"); // Gestion auto du tform pour les tables binaires avec le datatype (si non-definie) bool tformauto = false; if(HduType==BINARY_TBL) { if(tform==NULL) tformauto = true; else if(strlen(tform)<=0) tformauto = true; } if(tformauto) { char str[8]; if(datatype==TBYTE) strcpy(str,"1B"); else if(datatype==TSHORT) strcpy(str,"1I"); //CMV$CHECK Commentaire temporaire (il faut au moins cfitsio 2204) //else if(datatype==TINT32BIT) strcpy(str,"1J"); else if(datatype==TLONG) strcpy(str,"1J"); else if(datatype==TFLOAT) strcpy(str,"1E"); else if(datatype==TDOUBLE) strcpy(str,"1D"); else if(datatype==TUSHORT) strcpy(str,"1U"); else if(datatype==TULONG) strcpy(str,"1V"); else throw ParmError("FitsABTWriter::addcol: datatype not allowed\n"); TForm.push_back(str); } else { if(tform) TForm.push_back(tform); else TForm.push_back(""); datatype = 0; } Label.push_back(label); if(tunit) TUnit.push_back(tunit); else TUnit.push_back(""); int n = (int) Label.size() -1; if(DbgLevel) cout<<"FitsABTWriter::addcol["<0) { extname = (char *) malloc((strlen(ExtName.c_str())+1)*sizeof(char)); strcpy(extname,ExtName.c_str()); } int i; for(i=0;i& val) { if(FirstTime) createtbl(); long nel = val.Size(); int sta=0; // Bug ou inconsistence cfitsio sur machine ou long=8Bytes ? int T = (sizeof(long)==4) ? TLONG: TINT; if(fits_write_col(FitsPtr,T,col+1,row+1,1,nel,val.Data(),&sta)) printerrorwrite("long",col,row,sta); return row+nel; } /*! Write a vector of float data to FITS file (see below) */ long FitsABTWriter::Write(int col,long row,TVector& val) { if(FirstTime) createtbl(); long nel = val.Size(); int sta=0; if(fits_write_col(FitsPtr,TFLOAT,col+1,row+1,1,nel,val.Data(),&sta)) printerrorwrite("float",col,row,sta); return row+nel; } /*! Write a vector of double data to FITS file (see below) */ long FitsABTWriter::Write(int col,long row,TVector& val) { if(FirstTime) createtbl(); long nel = val.Size(); int sta=0; if(fits_write_col(FitsPtr,TDOUBLE,col+1,row+1,1,nel,val.Data(),&sta)) printerrorwrite("double",col,row,sta); return row+nel; } ////////////////////////////////////////////////////////////// void FitsABTWriter::printerrorwrite(const char* type,int col,long row,int sta) { if(sta==NUM_OVERFLOW) {NOverFlow++; return;} printerror(sta); char str[256]; sprintf(str,"FitsABTWriter::Write_%s: Error Writing Fits c=%d r=%ld sta=%d" ,type,col,row,sta); throw NotAvailableOperation(str); } ///////////////////////////////////////////////// void FitsABTWriter::printerror(int sta) const { int stat = sta; fits_report_error(stdout,stat); fflush(stdout); return; } ///////////////////////////////////////////////// void FitsABTWriter::Print(ostream& os,int lp) const { os<<"FitsABTWriter::Print: FitsFN "<0 && lp>=1) for(int i=0;i<(int)Label.size();i++) os<