source: Sophya/trunk/SophyaExt/FitsIOServer/fitsfile.cc@ 1333

Last change on this file since 1333 was 1333, checked in by ansari, 25 years ago

warning dans getheader

File size: 49.3 KB
RevLine 
[949]1#include "machdefs.h"
2#include <stdlib.h>
[839]3#include "fitsfile.h"
4#include "pexceptions.h"
5#include "strutil.h"
[903]6#include "anydataobj.h"
7#include "fitsspherehealpix.h"
[1136]8
9
[1218]10void BnTblLine::setFormat(int dc, int fc, int ic, int cc, vector<string> names)
11 {
12 int nbcols = dc + fc + ic + cc;
13 int maxName = names.size();
14 if (nbcols != maxName)
15 {
16 cout << " WARNING: BnTblLine:: length of vector of column names not equal to total number of columns" << endl;
17 maxName = nbcols < maxName ? nbcols : maxName;
18 }
19 ColName_ = vector<string>(nbcols);
20 for (int k=0; k < maxName; k++) ColName_[k] = names[k];
21 if (dc >0) ddata_ = vector<double>(dc);
22 if (fc >0) fdata_ = vector<float>(fc);
23 if (ic >0) idata_ = vector<int>(fc);
24 if (cc >0) cdata_ = vector<string>(fc);
25 }
26
27bool BnTblLine::sameFormat(const BnTblLine& btl) const
28 {
29 if (btl.ddata_.size() == ddata_.size() && btl.fdata_.size() == fdata_.size() && btl.idata_.size() == idata_.size() && btl.cdata_.size() == cdata_.size()) return true;
30 else return false;
31 }
32
33void BnTblLine::Print()
34 {
35 int k;
36 cout << " ********* ligne ************* " << endl;
37 cout << " *** noms de variables " << endl;
38 for (k=0; k < ColName_.size(); k++) cout << ColName_[k] << " ";
39 cout << endl;
40 cout << " *** variables doubles " << endl;
41 for (k=0; k < ddata_.size(); k++) cout << ddata_[k] << " ";
42 cout << endl;
43 cout << " *** variables float " << endl;
44 for (k=0; k < fdata_.size(); k++) cout << fdata_[k] << " ";
45 cout << endl;
46 cout << " *** variables int " << endl;
47 for (k=0; k < idata_.size(); k++) cout << idata_[k] << " ";
48 cout << endl;
49 cout << " *** variables string " << endl;
50 for (k=0; k < cdata_.size(); k++) cout << cdata_[k] << " ";
51 cout << endl;
52 cout << " ***************************** " << endl;
53 }
54
55
56
57/*!
58 \class SOPHYA::FitsIOHandler
59The class structure is analogous to Sophya-PPersist system :
60Each SOPHYA object XXX is associated with a object of class FITS_XXX
61 (inheriting from FitsFileHandler), to which input/output operations with FITS
62 files are delegated (through a class Hierarchy : FitsFile (virtual),
63 FitsInFile, FitsOutFile) . A typical example of use is the following :
64
65\verbatim
66 int m=... ;
67 SphereHEALPix<r_8> sphere1(m); // definition of the SOPHYA object
68 .... fill the sphere ....
69
70 FITS_SphereHEALPix<r_8> fits_sph1(sphere1);
71 // delegated object
72 fits_sph.Write("myfile.fits"); // writing on FITS file
73
74 FITS_SphereHEALPix<r_8> fits_sph2("myfile.fits");
75 // load a delegated object
76 // from FITS file
77 SphereHEALPix<r_8> sphere2=(SphereHEALPix<r_8>)fits_sph2;
78 // casting the delegated object
79 // into a SOPHYA object
80\endverbatim
81
82
83*/
84
85/*! \fn void SOPHYA::FitsIOHandler::Read(char flnm[],int hdunum)
86
87this method is called from inherited objects :
88
89opens a file 'flnm'
90
91gets parameters in extension-header (hdunum)
92
93calls the method 'ReadFromFits' from the inherited object
94*/
[1136]95void FitsIOHandler::Read(char flnm[],int hdunum)
[839]96{
[1136]97 FitsInFile ifts(flnm);
98 Read(ifts, hdunum);
[839]99}
[1218]100
101 /*! \fn void SOPHYA::FitsIOHandler::Read(FitsInFile& is, int hdunum)
102Read the data on extension hdunum (or primary header, if hdunum=1) from FitsInFIle. If hdunum is not addressed, , one reads the next extension, with respect to the current position.
103 */
[1136]104void FitsIOHandler::Read(FitsInFile& is, int hdunum)
105{
[1300]106 is.ReadHeader(hdunum);
[1136]107 ReadFromFits(is);
108}
109
110
[1218]111/*! \fn void SOPHYA::FitsIOHandler::Write(char flnm[])
112this method is called from inherited objects.
113
114for writing a new object in a new fits-extension :
115
[1234]116\warning By convention, primary header may contain fits-image data.
117For switching off this convention (i.e. to make sure that all data will be on fits-extensions) use the method :
[1218]118
119firstImageOnPrimaryHeader() (see below)
120
121calls the method 'WriteToFits' from the inherited object
122
123*/
[1193]124void FitsIOHandler::Write(char flnm[])
[1136]125
126{
[1231]127 FitsOutFile of(flnm, FitsFile::unknown);
[1136]128 Write(of);
129}
130
131void FitsIOHandler::Write(FitsOutFile& os)
132{
133 WriteToFits(os);
134}
135
136
[1218]137/*!
138 \class SOPHYA::FitsIOHandler
139Class (virtual) for managing FITS format files
140*/
[1136]141
[1218]142
[839]143
144FitsFile::~FitsFile()
145{
146 int status = 0;
[1175]147 if( fptr_ != NULL)
[903]148 {
149 fits_close_file(fptr_,&status);
[1175]150 // je ne fais pas delete fptr_, c'est la lib. fitsio qui a fait
151 // new...
[903]152 }
[1175]153 if( status ) printerror( status );
[839]154}
[903]155
[1136]156
157void FitsFile::printerror(int &status)
158 //*****************************************************/
159 //* Print out cfitsio error messages and exit program */
160 //*****************************************************/
[1045]161{
[1136]162 if( status )
163 {
164 fits_report_error(stderr,status);
165 throw IOExc("FitsFile:: error FITSIO status");
166 }
167 return;
168}
[903]169
[1136]170void FitsFile::printerror(int& status, char* texte)
171 //*****************************************************/
172 //* Print out cfitsio error messages and exit program */
173 //*****************************************************/
174{
175 // print out cfitsio error messages and exit program
176 // print error report
[1235]177 fits_report_error(stderr, status);
[1136]178 cout << " erreur:: " << texte << endl;
179 throw IOExc("FitsFile:: error FITSIO status");
180}
181
182void FitsFile::ResetStatus(int& status)
183{
184 fits_status_ = status;
185 status = 0;
[1235]186 fits_clear_errmsg();
[1136]187}
188
[1209]189string FitsFile::GetErrStatus(int status)
[1136]190{
191 char text[31];
192 fits_get_errstatus(status, text);
193 return string(text);
194}
195
[1218]196/*!
197 \class SOPHYA::FitsInFile
198
[1246]199class for reading SOPHYA objects from FITS Format Files (uses cfitsio lib)
[1218]200*/
201
[1136]202FitsInFile::FitsInFile()
203{
204 InitNull();
205}
[1218]206
[1231]207FitsInFile::FitsInFile(string const & flnm)
[1136]208{
[1175]209 InitNull();
210 int status = 0;
[1231]211 fits_open_file(&fptr_,flnm.c_str(),READONLY,&status);
212 if( status ) printerror( status );
213}
214
215FitsInFile::FitsInFile(const char * flnm)
216{
217 InitNull();
218 int status = 0;
[1175]219 fits_open_file(&fptr_,flnm,READONLY,&status);
220 if( status ) printerror( status );
[1136]221}
222
223
224void FitsInFile::InitNull()
225{
[1300]226 imageDataType_ = FitsDataType_NULL;
[1045]227 naxis_ = 0;
228 nbData_ = 0;
229 nrows_ = 0;
230 nbcols_ = 0;
231 naxisn_.clear();
232 repeat_.clear();
233 noms_.clear();
234 taille_des_chaines_.clear();
235 dvl_.Clear();
[1175]236
[1045]237}
238
[1218]239//////////////////////////////////////////////////////////
240// methods with general purpose
241/////////////////////////////////////////////////////////
[1045]242
[1136]243int FitsInFile::NbBlocks(char flnm[])
[903]244{
245 int status = 0;
246 int nbhdu = 0;
247 fitsfile* fileptr;
248 fits_open_file(&fileptr,flnm,READONLY,&status);
249 if( status ) printerror( status, "NbBlocks: erreur ouverture fichier" );
250 fits_get_num_hdus(fileptr, &nbhdu, &status);
251 fits_close_file(fileptr,&status);
252 return nbhdu;
253}
254
[1231]255void FitsInFile::GetBlockType(char flnm[], int hdunum, FitsExtensionType& typeOfExtension, int& naxis, vector<int>& naxisn, FitsDataType& dataType, DVList& dvl )
[903]256{
257 int status = 0;
258 fitsfile* fileptr;
259 fits_open_file(&fileptr,flnm,READONLY,&status);
[1209]260 if( status ) printerror( status, "GetBlockType: erreur ouverture fichier" );
[903]261 // move to the specified HDU number
262 int hdutype = 0;
263 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
[1209]264 if( status ) printerror( status,"GetBlockType: erreur movabs");
[903]265 if(hdutype == IMAGE_HDU)
266 {
[1231]267 typeOfExtension = FitsExtensionType_IMAGE;
[1300]268 GetImageParameters (fileptr, dataType, naxis, naxisn);
[903]269 }
270 else
271 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
272 {
273 int nrows = 0;
274 vector<string> noms;
[1300]275 vector<FitsDataType> types;
[903]276 vector<int> taille_des_chaines;
[971]277 GetBinTabParameters(fileptr, naxis, nrows, naxisn, noms, types, taille_des_chaines);
278 int k;
279 for (k=0; k< naxisn.size(); k++) naxisn[k] *= nrows;
[903]280 if(hdutype == ASCII_TBL)
281 {
[1231]282 typeOfExtension = FitsExtensionType_ASCII_TBL;
283 dataType = FitsDataType_ASCII;
[903]284 }
285 else
286 {
[1231]287 typeOfExtension = FitsExtensionType_BINARY_TBL;
[1300]288 dataType = types[0];
[903]289 }
290 }
291 else
292 {
293 cout << " hdutype= " << hdutype << endl;
[1209]294 throw IOExc("FitsFile::GetBlockType: this HDU type is unknown");
[903]295 }
296
[971]297 KeywordsIntoDVList(fileptr, dvl, hdunum);
[903]298 fits_close_file(fileptr,&status);
299}
300
[1136]301
[1300]302void FitsInFile::ReadHeader(int hdunum)
[1045]303{
[1300]304 // InitNull();
[1045]305 int status = 0;
[1136]306
[1234]307 if (hdunum != 0 ) hdunum_ = hdunum;
308
309 // si le numero de header non precise
310 else
[1045]311 {
[1234]312 // si c'est le premier objet a lire
313 if (hdunum_ == 0)
[1045]314 {
[1234]315 // on calcule le numero de header a lire
[1246]316 if (imageOnPrimary_ == true ) hdunum_ = 1;
[1234]317 else hdunum_ = 2;
[1045]318 }
[1234]319 // sinon objet suivant
320 else hdunum_++;
[1045]321 }
[1234]322 getHeader();
323
[1045]324}
325
[1218]326
[1300]327void FitsInFile::GetImageParameters (fitsfile* fileptr,FitsDataType& dataType,int& naxis,vector<int>& naxisn)
[1218]328{
329 int hdunum=0;
330 cout << " Reading a FITS image in HDU : " << fits_get_hdu_num(fileptr,&hdunum) << endl;
331 int status= 0;
332
333 // bits per pixels
[1300]334 int bitpix=0;
[1218]335 fits_read_key(fileptr,TINT,"BITPIX",&bitpix,NULL,&status);
336 if( status ) printerror( status );
[1300]337 if(bitpix == DOUBLE_IMG) dataType = FitsDataType_double;
338 else if(bitpix == FLOAT_IMG) dataType = FitsDataType_float;
339 else if(bitpix == LONG_IMG || bitpix == SHORT_IMG ) dataType = FitsDataType_int;
340 else if (bitpix == BYTE_IMG) dataType = FitsDataType_char;
341 else
342 {
343 cout << " bitpix= " << bitpix << endl;
344 throw PException(" FitsFile::GetImageParameters : unsupported FITS data type");
345 }
[1218]346
347 // number of dimensions in the FITS array
348 naxis= 0;
349 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
350 if( status ) printerror( status );
351 // read the NAXISn keywords to get image size
352 long* naxes = new long[naxis] ;
353 int nfound;
354 fits_read_keys_lng(fileptr,"NAXIS",1,naxis,naxes,&nfound,&status);
355 if( status ) printerror( status );
356 if (nfound != naxis )
357 cout << " WARNING : " << nfound << " axes found, expected naxis= " << naxis << endl;
358 int k;
359 for (k=0; k<naxis; k++)
360 {
361 naxisn.push_back( (int)naxes[k] );
362 }
363 delete [] naxes;
364}
365
366
367
368
369 /*! \fn DVList SOPHYA::FitsInFile::DVListFromPrimaryHeader() const
370
371 \return the keywords of primary header in a DVList
372
373*/
[1143]374DVList FitsInFile::DVListFromPrimaryHeader() const
375 {
376 int status;
377 DVList dvl;
378 KeywordsIntoDVList(fptr_, dvl, 1);
379 int hdutype = 0;
380 if (hdunum_ > 0) fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
381 return dvl;
382 }
[1136]383
[1234]384void FitsInFile::getHeader()
[971]385{
[1300]386 // si hdunum_ > 1 lit le header correspondant
387 // si hdunum_ = 1 se positionne au (et lit le) premier header qui
388 // contient reellement un objet
[1234]389 int status=0;
390 if (hdunum_ < 1) throw PException(" attempt to read hdunum < 1");
[1300]391 InitNull();
[1234]392 if (hdunum_ == 1)
[839]393 {
[1234]394 // presence of image ?
395 int naxis= 0;
396 fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
397 if( status ) printerror( status );
398 if (naxis > 0 ) // there is an image
399 {
400 hdutype_ = IMAGE_HDU;
[1300]401 GetImageParameters (fptr_, imageDataType_, naxis_, naxisn_);
[1234]402 nbData_ = 1;
403 int k;
404 for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
405 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
406 }
407 else
408 {
[1333]409 cout << " WARNING (FitsInFile::getHeader): attempt to read data on the primary hader, which does not contain any... It may be a consequence of confusion in the HDU numbering of the application." << endl;
410 cout << " The object to be read is supposed to be a bin or ascii table.. on the first extension" << endl;
411 cout << " Anyway, some trouble can result... " << endl;
[1246]412 hdunum_++;
413 getHeader();
414
415 // throw PException(" first header : no image, probably error in hdunum");
[1234]416 }
[839]417 }
[1234]418 else
[839]419 {
[1234]420 int hdutype;
421 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
422 if( status ) printerror( status,":FitsInFile::getHeader : erreur movabs");
423 hdutype_= hdutype;
424 if(hdutype_ == IMAGE_HDU)
425 {
[1300]426 GetImageParameters (fptr_, imageDataType_, naxis_, naxisn_);
[1234]427 nbData_ = 1;
428 int k;
429 for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
430 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
431 }
432 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
433 {
434 GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_);
435 KeywordsIntoDVList(fptr_, dvl_, hdunum_);
436 }
[839]437 }
[971]438}
[839]439
[1136]440
[1234]441void FitsInFile::moveToFollowingHeader()
442{
443 int status = 0;
444 hdunum_++;
445 getHeader();
446}
[1218]447
448
449
[1234]450
451
[1218]452/*! \fn int SOPHYA::FitsInFile::NbColsFromFits() const
453\return number of columns (return 1 if IMAGE)
454*/
[1136]455int FitsInFile::NbColsFromFits() const
[839]456{
[1136]457 if(hdutype_ == BINARY_TBL) return nbcols_;
[971]458 else
[1136]459 if(hdutype_ == ASCII_TBL || hdutype_ == IMAGE_HDU) return 1;
[839]460 else
461 {
[1136]462 cout << " hdutype= " << hdutype_ << endl;
463 throw PException("FitsFile::NbColsFromFits, this HDU is unknown");
[839]464 }
465}
466
[1218]467/*! \fn int SOPHYA::FitsInFile::NentriesFromFits(int nocol) const
468\return number of data in the current IMAGE extension on FITS file, or number
469 of data of column number 'nocol' of the current BINTABLE extension
470*/
[1136]471int FitsInFile::NentriesFromFits(int nocol) const
[839]472{
[1136]473 if(hdutype_ == BINARY_TBL ) return nrows_*repeat_[nocol];
474 else
475 if(hdutype_ == ASCII_TBL) return nrows_;
476 else
477 if(hdutype_ == IMAGE_HDU) return nbData_;
478 else
[839]479 {
[1136]480 cout << "hdutype= " << hdutype_ << endl;
481 throw PException("FitsFile::NentriesFromFits, this HDU is unknown");
[839]482 }
483}
484
[1218]485/*! \fn char SOPHYA::FitsInFile::ColTypeFromFits(int nocol) const
486
487return a character denoting data type of column number 'nocol' in a BINTABLE :
488
489D : double
490
491E : float
492
493I : integer
494
495S : character string
496
497 */
498
[1300]499FitsFile::FitsDataType FitsInFile::ColTypeFromFits(int nocol) const
[839]500{
[1136]501 if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL)
[839]502 {
[1136]503 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
[839]504 }
[1136]505 return types_[nocol];
[839]506}
[1218]507
508
509/*! \fn string SOPHYA::FitsInFile::ColNameFromFits(int nocol) const
510
511\return name of the column number 'nocol' of the current BINTABLE extension
512 */
513
[1136]514string FitsInFile::ColNameFromFits(int nocol) const
[839]515{
[1136]516 if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL)
[1045]517 {
[1136]518 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
[1045]519 }
[1136]520 return noms_[nocol];
[839]521}
522
[1218]523/*! \fn int DSOPHYA::FitsInFile::ColStringLengthFromFits(int nocol) const
524
525 \return number of characters of each data for the column number 'nocol' (if char* typed) of the current BINTABLE extension
526*/
527
[1136]528int FitsInFile::ColStringLengthFromFits(int nocol) const
[839]529{
[1136]530 if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL)
531 {
532 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
533 }
534 int index=-1;
535 int k;
536 for (k=0; k<=nocol; k++)
537 {
[1300]538 if (types_[k] == FitsDataType_char) index++;
[1136]539 }
540 return taille_des_chaines_[index];
[839]541}
[1218]542
543
544
545/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
546
547Get the NoLine-th 'line' from the current BINTABLE extension on FITS file,
548 */
549
[1193]550void FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
[839]551{
552 int status= 0;
[1136]553 int anull;
554 double dnull= 0.;
555 float fnull= 0.;
556 int inull= 0;
557 char* cnull= "";
558 int dcount = 0.;
559 int fcount = 0.;
560 int icount = 0;
561 int ccount =0;
562 int ncol;
563 long nels=1;
564 for (ncol=0; ncol<nbcols_; ncol++)
[861]565 {
[1136]566 switch (types_[ncol])
567 {
[1300]568 case FitsDataType_double :
[1136]569 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ddata[dcount++],&anull,&status);
570 break;
[1300]571 case FitsDataType_float :
[1136]572 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[fcount++],&anull,&status);
573 break;
[1300]574 case FitsDataType_int :
[1136]575 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&idata[icount++],
576 &anull,&status);
577 break;
[1300]578 case FitsDataType_char :
[1136]579 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&cdata[ccount++],&anull,&status);
580 break;
581 }
582 if (status)
583 {
584 ResetStatus(status);
585 break;
586 }
[861]587 }
[903]588}
[839]589
[1218]590/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(long NoLine, BnTblLine& ligne)
591Get the NoLine-th 'line' from the current BINTABLE extension on FITS file,
592*/
[1193]593void FitsInFile::GetBinTabLine(long NoLine, BnTblLine& ligne)
594{
595 int status= 0;
596 int anull;
597 double dnull= 0.;
598 float fnull= 0.;
599 int inull= 0;
600 char* cnull= "";
601 int dcount = 0.;
602 int fcount = 0.;
603 int icount = 0;
604 int ccount =0;
605 int ncol;
606 long nels=1;
607 for (ncol=0; ncol<nbcols_; ncol++)
608 {
609 switch (types_[ncol])
610 {
[1300]611 case FitsDataType_double :
[1193]612 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ligne.ddata_[dcount++],&anull,&status);
[1300]613 break;
614 case FitsDataType_float :
[1193]615 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&ligne.fdata_[fcount++],&anull,&status);
616 break;
[1300]617 case FitsDataType_int :
[1193]618 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ligne.idata_[icount++],
619 &anull,&status);
620 break;
[1300]621 case FitsDataType_char :
[1193]622 char* chaine = new char[taille_des_chaines_[ccount]];
623 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anull,&status);
624 ligne.cdata_[ccount++] = string(chaine);
625 break;
626 }
627 if (status)
628 {
629 ResetStatus(status);
630 break;
631 }
632 }
633}
634
[1218]635/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, float* fdata)
636
637Get the NoLine-th float 'line' from the current BINTABLE extension on FITS file,
638*/
[1136]639void FitsInFile::GetBinTabLine(int NoLine, float* fdata)
[903]640{
[1136]641 int status= 0;
642 int anull;
643 float fnull= 0.;
644 long nels=1;
645 int ncol;
646 for (ncol=0; ncol<nbcols_; ncol++)
[861]647 {
[1136]648 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[ncol],&anull,&status);
649 if (status)
[903]650 {
[1136]651 ResetStatus(status);
652 break;
[903]653 }
[1136]654 }
655}
[839]656
[903]657
[1218]658/*! \fn void SPOPHYA::FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
659
660fill the array 'valeurs' with double data from the current BINTABLE extension on FITS file, from column number 'NoCol'
661
662\param <nentries> number of data to be read
663*/
[1136]664void FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
[839]665 {
666 int status= 0;
667 int DTYPE;
668 long repeat,width;
669 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
670 if( DTYPE != TDOUBLE)
671 {
[1045]672 if (DTYPE == TFLOAT) cout << " WARNING: reading double from float : conversion will be made by fitsio library" << endl;
673 else
674 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non double");
[839]675 }
676 long nels=nentries;
[971]677 int anull;
[839]678 // no checking for undefined pixels
[971]679 double dnull= 0.;
680 // fits_read_key(fptr_,TDOUBLE,"BAD_DATA",&dnull,NULL,&status);
681 // if (status != 0)
682 // {
683 // dnull = -1.6375e30; // default value
684 // status = 0;
685 // }
686 if (nentries != nrows_*repeat)
687 {
688 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat << endl;
689 throw PException(" FitsFile:::GetBinTabFCol ");
690 }
[839]691 fits_read_col(fptr_,TDOUBLE,NoCol+1,1,1,nels,&dnull,valeurs,
692 &anull,&status);
693 if( status ) printerror( status,"erreur lecture de colonne" );
[971]694
[839]695 }
696
[1218]697/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
698
699 same as previous method with float data
700*/
[1136]701void FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
[839]702 {
703 int status= 0;
704 int DTYPE;
705 long repeat,width;
706 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
707 if( DTYPE != TFLOAT)
708 {
[1045]709 if (DTYPE == TDOUBLE) cout << " WARNING: reading float from double : conversion will be made by fitsio library" << endl;
710 else
711 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non float");
[839]712 }
713 long nels=nentries;
[971]714 int anull;
[839]715 // no checking for undefined pixels
716 float fnull= 0.;
[971]717 // fits_read_key(fptr_,TFLOAT,"BAD_DATA",&fnull,NULL,&status);
718 // if (status != 0)
719 // {
720 // fnull = -1.6375e30; // default value
721 // status = 0;
722 // }
723 if (nentries != nrows_*repeat)
724 {
725 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat << endl;
726 throw PException(" FitsFile:::GetBinTabFCol ");
727 }
[839]728 fits_read_col(fptr_,TFLOAT,NoCol+1,1,1,nels,&fnull,valeurs,
729 &anull,&status);
730 if( status ) printerror( status,"erreur lecture de colonne" );
731 }
[1136]732
[1218]733/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
734
735 same as previous method with int data
736*/
737
[1136]738void FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
[839]739 {
740 int status= 0;
741 int DTYPE;
742 long repeat,width;
743 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
744 if( DTYPE != TLONG && DTYPE != TINT && DTYPE != TSHORT )
745 {
746 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non entier");
747 }
748 long nels=nentries;
749 // no checking for undefined pixels
750 int anull;
751 int inull= 0;
[971]752 // fits_read_key(fptr_,TINT,"BAD_DATA",&inull,NULL,&status);
753 // if (status != 0)
754 // {
755 // inull = -999999; // default value
756 // status = 0;
757 // }
758 if (nentries != nrows_*repeat)
759 {
760 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat << endl;
761 throw PException(" FitsFile:::GetBinTabFCol ");
762 }
[839]763 fits_read_col(fptr_,TINT,NoCol+1,1,1,nels,&inull,valeurs,
764 &anull,&status);
765 if( status ) printerror( status,"erreur lecture de colonne" );
766 }
[1136]767
[1218]768/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
769
770 same as previous method with char* data
771*/
772
[1136]773void FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
[839]774 {
775 int status= 0;
776 int DTYPE;
777 long repeat,width;
778 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
[1300]779 if( DTYPE != TSTRING && DTYPE != TBYTE)
[839]780 {
[1300]781 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non string");
[839]782 }
783 long nels=nentries;
784 // no checking for undefined pixels
785 int anull;
[971]786 char* cnull= "";
787 if (nentries != nrows_*repeat/width)
788 {
789 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat/width << endl;
790 throw PException(" FitsFile:::GetBinTabFCol ");
791 }
[839]792 long frow=1;
793 long felem=1;
794 fits_read_col(fptr_,TSTRING,NoCol+1,frow,felem,nels,cnull,valeurs,
795 &anull,&status);
796 if( status ) printerror( status,"erreur lecture de colonne" );
797 }
[1045]798
[1218]799/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(double* map, int nentries) const
800fill the array 'map' with double data from the current extension on FITS file.
801If the extension is BINTABLE, the first column is provided.
802
803\param <nentries> number of data to be read
804*/
[1136]805void FitsInFile::GetSingleColumn(double* map, int nentries) const
806{
807 int status = 0;
808 if(hdutype_ == IMAGE_HDU)
[1045]809 {
[1136]810
[1300]811 if(imageDataType_ != FitsDataType_double)
[1047]812 {
[1136]813 cout << " The data type on fits file is not double...";
814 cout << " Conversion to double achieved by cfitsio lib" << endl;
[1047]815 }
[1136]816
817 // no checking for undefined pixels
818 int anull;
819 double dnull= 0.;
820
821 long nels= nentries;
822 fits_read_img(fptr_,TDOUBLE,1,nels,&dnull,map,&anull,&status);
823 if( status ) printerror( status );
[1045]824 }
[1136]825 else
826 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
827 {
828 GetBinTabFCol(map,nentries, 0);
829 }
830 else
831 {
832 cout << " hdutype= " << hdutype_ << endl;
833 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
834 }
[1045]835}
836
[1218]837/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(float* map, int nentries) const
838same as above with float data
839*/
[1136]840void FitsInFile::GetSingleColumn(float* map, int nentries) const
[1045]841{
[1136]842 int status = 0;
843 if(hdutype_ == IMAGE_HDU)
[1045]844 {
[1300]845 if(imageDataType_ != FitsDataType_float)
[1047]846 {
[1136]847 cout << " The data type on fits file is not float ";
848 cout << " Conversion to float achieved by cfitsio lib" << endl;
[1047]849 }
[1136]850 // no checking for undefined pixels
851 int anull;
852 float fnull= 0.;
853
854 long nels= nentries;
855 fits_read_img(fptr_,TFLOAT,1,nels,&fnull, map,&anull,&status);
856 if( status ) printerror( status );
[1045]857 }
[839]858 else
[1136]859 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
860 {
861 GetBinTabFCol(map,nentries, 0);
862 }
[839]863 else
864 {
[1136]865 cout << " hdutype= " << hdutype_ << endl;
866 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
[839]867 }
868}
869
[1218]870/*! \fn void SOPHYA::FitsInFile::GetSingleColumn( int* map, int nentries) const
871 same as above with int data
872*/
[1136]873void FitsInFile::GetSingleColumn( int* map, int nentries) const
[839]874{
[1136]875 int status = 0;
876 if(hdutype_ == IMAGE_HDU)
[839]877 {
[1300]878 if(imageDataType_ != FitsDataType_int)
[1136]879 {
880 cout << " The data type on fits file is not int ";
881 cout << " Conversion to float achieved by cfitsio lib" << endl;
882 }
883 // no checking for undefined pixels
884 int anull;
885 float fnull= 0.;
886
887 long nels= nentries;
888 fits_read_img(fptr_,TINT,1,nels,&fnull,map,&anull,&status);
889 if( status ) printerror( status );
[839]890 }
891 else
[1136]892 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
893 {
894 GetBinTabFCol(map,nentries, 0);
895 }
[839]896 else
[1136]897 {
898 cout << " hdutype= " << hdutype_ << endl;
899 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
900 }
[839]901}
902
[1136]903void FitsInFile::GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows,
[903]904 vector<int>& repeat,
905 vector<string>& noms,
[1300]906 vector<FitsDataType>& types,
[903]907 vector<int>& taille_des_chaines)
[839]908{
909 int status= 0;
[903]910 int hdunum=0;
911 int hdutype=0;
912 fits_get_hdu_num(fileptr,&hdunum);
913 fits_get_hdu_type(fileptr, &hdutype, &status);
914
915 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
[839]916 {
[903]917 throw IOExc("FitsFile::GetBinTabParameters this HDU is not an ASCII table nor a binary table");
[839]918 }
[903]919 if(hdutype == ASCII_TBL)
920 cout << " Reading a FITS ascii table in HDU : " << hdunum << endl;
921 if(hdutype == BINARY_TBL)
922 cout << " Reading a FITS binary table in HDU : " << hdunum << endl;
[839]923
924 // get the number of columns
[903]925 fits_get_num_cols(fileptr, &nbcols,&status);
[839]926 if( status ) printerror( status );
927
928 // get the number of rows
929 long naxis2= 0;
[903]930 fits_get_num_rows(fileptr,&naxis2,&status);
[839]931 if( status ) printerror( status );
[903]932 nrows = (int)naxis2;
[839]933
934 // get the datatype, names and the repeat count
[903]935 noms.clear();
936 noms.reserve(nbcols);
937 types.clear();
938 types.reserve(nbcols);
939 repeat.clear();
940 repeat.reserve(nbcols);
941 taille_des_chaines.clear();
[839]942 char **ttype = new char*[nbcols];
[923]943 int ii;
[1175]944 //
945 //
[923]946 for (ii=0; ii < nbcols; ii++) ttype[ii]=new char[FLEN_VALUE];
[839]947 int nfound;
[903]948 fits_read_keys_str(fileptr, "TTYPE",1,nbcols,ttype,&nfound, &status);
[839]949 if( status ) printerror( status,"erreur lecture des noms de colonne");
950 int rept=0;
[1300]951 if(hdutype == ASCII_TBL)
[839]952 {
[1300]953 for(ii = 0; ii < nbcols; ii++)
[839]954 {
[1300]955 int DTYPE;
956 long width;
957 long repete = 0;
958 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
959 if( status ) printerror( status,"erreur lecture type de colonne");
960 rept = repete;
961 noms.push_back(string(ttype[ii]));
962 switch (DTYPE)
963 {
964 case TDOUBLE :
965 types.push_back(FitsDataType_double);
966 break;
967 case TFLOAT :
968 types.push_back(FitsDataType_float);
969 break;
970 case TLONG :
971 types.push_back(FitsDataType_int);
972 break;
973 case TSHORT :
974 types.push_back(FitsDataType_int);
975 break;
976 case TSTRING :
977 types.push_back(FitsDataType_char);
978 taille_des_chaines.push_back(width);
979 rept/=width;
980 break;
981 default :
982 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
983 throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for ASCII table");
984 }
985 repeat.push_back(rept);
[839]986 }
[1136]987 }
[1300]988 else
989 {
990 for(ii = 0; ii < nbcols; ii++)
991 {
992 int DTYPE;
993 long width;
994 long repete = 0;
995 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
996 if( status ) printerror( status,"erreur lecture type de colonne");
997 rept = repete;
998 noms.push_back(string(ttype[ii]));
999 switch (DTYPE)
1000 {
1001 case TDOUBLE :
1002 types.push_back(FitsDataType_double);
1003 break;
1004 case TFLOAT :
1005 types.push_back(FitsDataType_float);
1006 break;
1007 case TLONG :
1008 types.push_back(FitsDataType_int);
1009 break;
1010 case TINT :
1011 types.push_back(FitsDataType_int);
1012 break;
1013 case TSHORT :
1014 types.push_back(FitsDataType_int);
1015 break;
1016 case TSTRING :
1017 types.push_back(FitsDataType_char);
1018 taille_des_chaines.push_back(width);
1019 rept/=width;
1020 break;
1021 case TBYTE :
1022 types.push_back(FitsDataType_char);
1023 taille_des_chaines.push_back(width);
1024 rept/=width;
1025 break;
1026 default :
1027 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
1028 throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for BINTABLE");
1029 }
1030 repeat.push_back(rept);
1031 }
1032 }
[1136]1033 for (ii=0; ii < nbcols; ii++) delete [] ttype[ii];
1034 delete [] ttype;
1035}
1036
1037void FitsInFile::KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum)
1038{
1039 int status = 0;
1040 int hdutype;
1041 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
1042 if( status ) printerror( status,":KeywordsIntoDVList : erreur movabs");
1043 // get number of keywords
1044 int nkeys,keypos;
1045 fits_get_hdrpos(fileptr,&nkeys,&keypos,&status);
1046 if( status ) printerror( status );
1047
1048 // put keywords in a DVList object
1049 char keyname[LEN_KEYWORD]= "";
1050 char strval[FLEN_VALUE]= "";
1051 char dtype;
1052 char card[FLEN_CARD];
1053 char *comkey = "COMMENT";
[1143]1054 char comment[FLEN_COMMENT];
[1136]1055
1056 // shift with the number of mandatory keywords
[1143]1057 // int num= 8;
1058 int num= 0;
1059 // primary header
1060 if (hdunum == 1)
1061 {
1062 // read NAXIS
1063 int naxis=0;
1064 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1065 // number of mandatory keywords
1066 num = naxis+3;
1067 }
1068 // extensions
1069 else
1070 {
1071 if (hdutype == IMAGE_HDU)
1072 {
1073 // read NAXIS
1074 int naxis=0;
1075 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1076 // number of mandatory keywords
1077 num = naxis+5;
1078 }
1079 else
1080 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
1081 {
1082 // number of mandatory keywords
1083 num = 8;
1084 }
1085 }
[1136]1086 int j;
1087 for(j = num+1; j <= nkeys; j++)
1088 {
1089 fits_read_keyn(fileptr,j,card,strval,NULL,&status);
1090 if(status) printerror(status);
1091
1092 strncpy(keyname,card,LEN_KEYWORD-1);
1093 if(strncmp(keyname,comkey,LEN_KEYWORD-1) != 0 && strlen(keyname) != 0
1094 && strlen(strval) != 0)
1095 {
1096 fits_get_keytype(strval,&dtype,&status);
1097 if(status) printerror(status);
1098
1099 strip(keyname, 'B',' ');
1100 strip(strval, 'B',' ');
1101 strip(strval, 'B','\'');
1102
1103 switch( dtype )
1104 {
1105 case 'C':
[1143]1106 fits_read_key(fileptr,TSTRING,keyname,strval,comment,&status);
1107 dvl[keyname]= strval;
1108 dvl.SetComment(keyname, comment);
[1136]1109 break;
1110 case 'I':
1111 int ival;
[1143]1112 fits_read_key(fileptr,TINT,keyname,&ival,comment,&status);
[1136]1113 dvl[keyname]= (int_4) ival; // Portage mac DY
[1143]1114 dvl.SetComment(keyname, comment);
[1136]1115 break;
1116 case 'L':
1117 int ilog;
[1143]1118 fits_read_key(fileptr,TLOGICAL,keyname,&ilog,comment,&status);
[1136]1119 dvl[keyname]= (int_4) ilog;
[1143]1120 dvl.SetComment(keyname, comment);
[1136]1121 break;
1122 case 'F':
1123 double dval;
[1143]1124 fits_read_key(fileptr,TDOUBLE,keyname,&dval,comment,&status);
[1136]1125 dvl[keyname]= dval;
[1143]1126 dvl.SetComment(keyname, comment);
[1136]1127 break;
1128 }
1129
1130 }
[839]1131 }
[1136]1132 // dvl_.Print();
1133}
1134
[1218]1135
1136/*!
1137 \class SOPHYA::FitsOutFile
1138 Class for loading SOPHYA objects from FITS Format Files (uses cfitsio lib)
1139*/
1140
[1136]1141FitsOutFile::FitsOutFile()
1142{
[1193]1143 InitNull();
[903]1144}
[839]1145
[1218]1146 /*! \fn SOPHYA::FitsOutFile::FitsOutFile(char flnm[], WriteMode wrm)
1147
1148\param <WriteMode> 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)
1149
1150 */
[1231]1151
1152FitsOutFile::FitsOutFile(string const & flnm, WriteMode wrm)
[1136]1153{
[1231]1154 InitNull();
1155 openoutputfitsfile(flnm.c_str(), wrm);
1156}
[839]1157
[1231]1158FitsOutFile::FitsOutFile(const char * flnm, WriteMode wrm)
1159{
[1136]1160 InitNull();
[1231]1161 openoutputfitsfile(flnm, wrm);
1162}
1163
1164void FitsOutFile::openoutputfitsfile(const char * flnm, WriteMode wrm)
1165{
[1136]1166 int status = 0;
[839]1167
[1136]1168 // create new FITS file
[1183]1169 fits_create_file(&fptr_,flnm,&status);
1170 if( status )
[1136]1171 {
[1193]1172
1173 switch (wrm)
1174 {
[1183]1175 // si on veut ecrire a la fin de ce fichier
[1193]1176 case append :
[1183]1177 status = 0;
[1235]1178 fits_clear_errmsg();
[1183]1179 fits_open_file(&fptr_,flnm,READWRITE,&status);
1180 if( status )
1181 {
1182 cout << " error opening file: " << flnm << endl;
1183 printerror(status, "failure opening a file supposed to exist");
1184 }
1185 else cout << " file " << flnm << " opened, new objects will be appended " << endl;
1186 fits_get_num_hdus(fptr_, &hdunum_, &status);
1187 int hdutype;
1188 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1189 if( status ) printerror( status,":FitsFile::WriteF : erreur movabs");
[1193]1190 break;
1191
1192 case clear :
[1183]1193 {
1194 status = 0;
[1235]1195 fits_clear_errmsg();
[1183]1196 char* newname = new char[strlen(flnm)+1];
1197 //
1198 newname[0] = '!';
1199 newname[1] = '\0';
1200 strcat(newname, flnm);
1201 fits_create_file(&fptr_,newname,&status);
[1193]1202 delete [] newname;
[1183]1203 if (status)
1204 {
1205 cout << " error opening file: " << flnm << endl;
1206 printerror(status, "unable to open file, supposed to exist");
1207 }
[1193]1208 else cout << " WARNING : file " << flnm << " is overwritten " << endl;
1209 break;
[1183]1210 }
[1193]1211 case unknown :
1212 printerror(status, " file seems already to exist");
1213 break;
[1183]1214
[1193]1215 }
[1136]1216 }
1217}
1218
1219
1220
[1218]1221/*! \fn void SOPHYA::FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList &dvl)
1222
1223create an IMAGE header on FITS file.
1224\param <type> type of data (see method ColTypeFromFits)
1225\param <nbdim> number of dimensions : 1D, 2D, 3D etc. = NAXIS
1226\param <naxisn> array containind sizes of the different dimensions
1227*/
[1221]1228void FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList* ptr_dvl)
[1136]1229{
1230 int status = 0;
1231 long naxis = nbdim;
1232 long* naxes = new long[nbdim];
[1246]1233 bool hdunfirst= (hdunum_ == 0);
1234 if (hdunfirst)
[1136]1235 {
[1143]1236 if (imageOnPrimary_ == false)
1237 {
[1234]1238 hdunum_ = 1;
[1143]1239 fits_create_img(fptr_,FLOAT_IMG,0,naxes,&status);
[1246]1240 }
[1136]1241 }
1242 int k;
1243 for (k=0; k< nbdim; k++) naxes[k] = (long)naxisn[k];
1244 if (type == 'D')
1245 fits_create_img(fptr_,DOUBLE_IMG,naxis,naxes,&status);
1246 else
1247 if (type == 'E')
1248 fits_create_img(fptr_,FLOAT_IMG,naxis,naxes,&status);
1249 else
1250 if (type == 'I')
1251 fits_create_img(fptr_,LONG_IMG,naxis,naxes,&status);
1252 else
1253 {
1254 cout << " type of data: " << type << endl;
1255 throw PException("FitsFile:::makeHeaderImageOnFits:unprogrammed type of data ");
1256 }
[1246]1257 // on ajoute eventuellement un dvlist prepare et la doc SOPHYA
[1136]1258 hdunum_++;
[1246]1259 if (hdunfirst)
1260 {
1261 addDVListOnPrimary();
1262 writeSignatureOnFits(1);
1263 }
[1143]1264
1265 // write supplementary keywords
1266 // dvl.Print();
[1221]1267 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
[1143]1268
[1136]1269 delete [] naxes;
1270 if( status ) printerror( status, "erreur creation HDU IMAGE" );
1271
1272}
[1218]1273
1274
1275/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, double* map) const
1276
1277write double data from array 'map'on an IMAGE extension
1278\param <nbData> number of data to be written
1279*/
[1209]1280void FitsOutFile::PutImageToFits(int nbData, double* map) const
[1136]1281{
1282 int status = 0;
1283 long npix= nbData;
1284 fits_write_img(fptr_,TDOUBLE,1,npix,map,&status);
[1209]1285 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
[1136]1286}
1287
[1218]1288/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, float* map) const
1289
1290same as previous method with float data
1291*/
[1209]1292void FitsOutFile::PutImageToFits(int nbData, float* map) const
[1136]1293{
1294 int status = 0;
1295 long npix= nbData;
1296 fits_write_img(fptr_,TFLOAT,1,npix, map,&status);
[1209]1297 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
[1136]1298
1299}
[1218]1300
1301 /*! \fn void SOPHYA::FitsOutFile::PutImageToFits( int nbData, int* map) const
1302
1303 same as previous method with int data */
[1209]1304void FitsOutFile::PutImageToFits( int nbData, int* map) const
[1136]1305{
1306 int status = 0;
1307
1308 long npix= nbData;
1309 fits_write_img(fptr_,TINT,1,npix,map,&status);
[1209]1310 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
[1136]1311}
1312
1313
1314
[1218]1315/*! \fn void SOPHYA::FitsOutFile::makeHeaderBntblOnFits( string fieldType, vector<string> Noms, int nentries, int tfields, DVList &dvl, string extname, vector<int> taille_des_chaines)
1316
1317create an BINTABLE header on FITS file.
1318\param <fieldType> array conta
1319ining characters denoting types of the different column (see method ColTypeFromFits)
1320\param <Noms> array of the names of columns
1321\param <nentries> number of data of each column
1322\param <tfields> number of columns
1323\param <dvl> a SOPHYA DVList containing keywords to be appended
1324\param <extname> keyword EXTNAME for FITS file
1325\param <taille_des_chaines> vector containing the number of characters of data for each char* typed column, with order of appearance in 'fieldType'
1326*/
[1300]1327void FitsOutFile::makeHeaderBntblOnFits(string fieldType, vector<string> Noms, int nentries, int tfields, DVList* ptr_dvl, string extname, vector<int> taille_des_chaines)
[839]1328{
[1209]1329 int k;
[839]1330 int status = 0;
1331 long nrows;
[1300]1332 // verifications de coherences
[1209]1333
[1193]1334 if (fieldType.length() != tfields)
[839]1335 {
[1193]1336 cout << " nombre de champs :" << tfields << "nombre de types: " << fieldType.length() << endl;
[1136]1337 throw ParmError("FitsFile:: fields and types don't match");
[839]1338
1339 }
[1209]1340 if (tfields > Noms.size())
1341 {
1342 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of column names not equal to total number of columns" << endl;
1343 for (k=0; k<(tfields-Noms.size()); k++) Noms.push_back( string(" "));
1344 }
1345
1346 // nombre de variables "chaines de caracteres"
1347 int nbString = 0;
1348 for (k=0; k<tfields;k++) if (fieldType[k] == 'A') nbString++;
1349 // coherence de la longueur du vecteur des tailles
1350 if (nbString > taille_des_chaines.size())
1351 {
1352 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of string lengths not equal to total number of columns" << endl;
1353 int strSz=0;
1354 for (k=0; k<taille_des_chaines.size(); k++) if ( taille_des_chaines[k] > strSz) strSz = taille_des_chaines[k];
1355 for (k=0; k<(nbString-taille_des_chaines.size()); k++) taille_des_chaines.push_back(strSz);
1356 }
[839]1357 char ** ttype= new char*[tfields];
1358 char ** tform= new char*[tfields];
1359 char largeur[FLEN_VALUE];
1360 int noColString=0;
[971]1361 for (k=0; k<tfields;k++)
[839]1362 {
1363 char format[FLEN_VALUE];
1364
1365 if(nentries < 1024)
1366 {
1367 nrows= nentries;
1368 if (fieldType[k] == 'A')
1369 {
1370 sprintf(largeur,"%d",taille_des_chaines[noColString++]);
1371 strcpy(format,largeur);
1372 }
1373 else strcpy(format,"1");
1374 }
1375 else
1376 {
1377 nrows = nentries/1024;
1378 if(nentries%1024 != 0) nrows++;
1379 if (fieldType[k] == 'A')
1380 {
[1136]1381 char largaux[FLEN_VALUE];
1382 sprintf(largeur,"%d",taille_des_chaines[noColString]);
1383 sprintf(largaux,"%d",1024*taille_des_chaines[noColString]);
1384 noColString++;
1385 strcpy(format, largaux);
[839]1386 }
1387 else strcpy(format,"1024");
1388 }
1389 strncat(format,&fieldType[k],1);
1390 if (fieldType[k] == 'A')
1391 {
1392 strcat(format,largeur);
1393 }
[1193]1394 ttype[k] = const_cast<char*>(Noms[k].c_str());
[839]1395 tform[k]= new char[FLEN_VALUE];
1396 strcpy(tform[k],format);
1397 }
[1193]1398 char* extn = const_cast<char*>(extname.c_str());
[839]1399
1400 // create a new empty binary table onto the FITS file
1401 // physical units if they exist, are defined in the DVList object
1402 // so the NULL pointer is given for the tunit parameters.
1403 nrows=0;
1404 fits_create_tbl(fptr_,BINARY_TBL,nrows,tfields,ttype,tform,
1405 NULL,extn,&status);
1406 if( status ) printerror( status );
[1246]1407 // on ajoute eventuellement un dvlist prepare
1408 if ( hdunum_ == 0 )
1409 {
1410 hdunum_ = 2;
1411 addDVListOnPrimary();
1412 writeSignatureOnFits(1);
1413 }
[1026]1414 else hdunum_++;
[971]1415 int ii;
1416 for(ii = 0; ii < tfields; ii++)
[839]1417 {
1418 delete [] tform[ii];
1419 }
1420 delete [] ttype;
1421 delete [] tform;
1422 //
1423 // write supplementary keywords
[1221]1424 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
[839]1425}
1426
[1218]1427/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
1428
1429write double data from array 'donnees ' on column number 'nocol' of a BINTABLE extension.
1430\param <nentries> number of data to be written
1431*/
[1209]1432void FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
[839]1433{
1434 int status = 0;
[971]1435 int hdutype;
[839]1436 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
[1209]1437 if( status ) printerror(status,"PutColToFits: le movabs a foire");
[839]1438 fits_get_hdu_type(fptr_, &hdutype, &status);
[867]1439 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1440 {
1441 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
[1209]1442 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
[867]1443 }
[839]1444 int code;
1445 long repeat, width;
1446 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1447 if( code != TDOUBLE)
1448 {
[1209]1449 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " to be written= DOUBLE " << endl;
[839]1450 }
1451 fits_write_col(fptr_,TDOUBLE,nocol+1,1,1,nentries, donnees ,&status);
1452 if( status ) printerror( status,"erreur ecriture du fichier fits" );
1453}
[1218]1454
1455
1456
1457 /*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
1458
1459same as previous method with float data
1460*/
[1209]1461void FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
[839]1462{
1463 int status = 0;
1464 int hdutype;
1465 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
[1209]1466 if( status ) printerror(status,"PutColToFits: le movabs a foire");
[839]1467 fits_get_hdu_type(fptr_, &hdutype, &status);
1468 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1469 {
1470 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
[1209]1471 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
[839]1472 }
1473 if(hdutype == ASCII_TBL && nocol>0)
1474 {
[1209]1475 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
[839]1476 }
1477 int code;
1478 long repeat, width;
1479 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1480 if( code != TFLOAT)
1481 {
[1209]1482 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= FLOAT " << endl;
[839]1483 }
1484 fits_write_col(fptr_,TFLOAT,nocol+1,1,1,nentries, donnees ,&status);
1485 if( status ) printerror( status,"erreur ecriture du fichier fits" );
1486}
[1218]1487
1488
1489/*! \fn void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
1490
1491same as previous method with int data
1492*/
[1209]1493void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
[839]1494{
1495 int status = 0;
1496 int hdutype;
1497 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
[1209]1498 if( status ) printerror(status,"PutColToFits: le movabs a foire");
[839]1499 fits_get_hdu_type(fptr_, &hdutype, &status);
1500 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1501 {
1502 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
[1209]1503 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
[839]1504 }
1505 if(hdutype == ASCII_TBL && nocol>0)
1506 {
[1209]1507 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
[839]1508 }
1509 int code;
1510 long repeat, width;
1511 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1512 if( code != TLONG && code != TINT && code != TSHORT )
1513 {
[1209]1514 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= INT " << endl;
[839]1515 }
1516 fits_write_col(fptr_,TINT,nocol+1,1,1,nentries, donnees ,&status);
[971]1517 if( status ) printerror( status," ecriture du fichier fits" );
[839]1518}
[1218]1519
1520
1521/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1522same as previous method with char* data
1523*/
[1209]1524void FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
[839]1525{
1526 int status = 0;
1527 int hdutype;
1528 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
[1209]1529 if( status ) printerror(status,"PutColToFits: le movabs a foire");
[839]1530 fits_get_hdu_type(fptr_, &hdutype, &status);
1531 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1532 {
1533 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
[1209]1534 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
[839]1535 }
1536 if(hdutype == ASCII_TBL && nocol>0)
1537 {
[1209]1538 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
[839]1539 }
1540 int code;
1541 long repeat, width;
1542 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1543 if( code != TSTRING)
1544 {
[1209]1545 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= char** " << endl;
[839]1546 }
1547 fits_write_col(fptr_,TSTRING,nocol+1,1,1,nentries, donnees ,&status);
1548 if( status ) printerror( status,"erreur ecriture du fichier fits" );
1549}
1550
[1209]1551void FitsOutFile::PutBinTabLine(long NoLine, BnTblLine& ligne) const
[1193]1552{
[1209]1553 // on ne fait pas de verification de type, ni de dimension ici, pour
1554 // des raisons de performances
1555 int k;
[1193]1556 int status= 0;
1557 int anull;
[1209]1558 int ncol=0;
[1193]1559 long nels=1;
[1209]1560 // int nbcols;
1561 // fits_get_num_cols(fptr_, &nbcols,&status);
1562 for (k=0; k<ligne.ddata_.size(); k++, ncol++)
[1193]1563 {
[1209]1564 fits_write_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1, &ligne.ddata_[k] ,&status);
1565 if( status ) printerror( status, "PutBinTabLine : erreur ecriture double" );
[1193]1566 }
[1209]1567 for (k=0; k<ligne.fdata_.size(); k++, ncol++)
1568 {
1569 fits_write_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1, &ligne.fdata_[k] ,&status);
1570 if( status ) printerror( status, "PutBinTabLine : erreur ecriture float" );
1571 }
1572 for (k=0; k<ligne.idata_.size(); k++, ncol++)
1573 {
1574 fits_write_col(fptr_,TINT,ncol+1,NoLine+1,1,1, &ligne.idata_[k] ,&status);
1575 if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier" );
1576 }
1577
1578 for (k=0; k<ligne.cdata_.size(); k++, ncol++)
1579 {
[1220]1580 fits_write_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1, (void*)ligne.cdata_[k].c_str() ,&status);
[1209]1581 if( status ) printerror( status, "PutBinTabLine : erreur ecriture caracteres" );
1582 }
[1193]1583}
1584
1585
[1218]1586/* \fn void SOPHYA::FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl) const
1587
1588Put keywords from a DVList into the primary header of the fits-file
1589*/
[1246]1590void FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl)
[1143]1591{
1592 int status = 0;
1593 int hdutype;
[1246]1594 if (hdunum_ == 0)
1595 {
1596 if (dvlToPrimary_ == NULL) dvlToPrimary_ = new DVList(dvl);
1597 else dvlToPrimary_->Merge(dvl);
1598 }
1599 else
1600 {
1601 fits_movabs_hdu(fptr_,1,&hdutype,&status);
1602 addKeywordsOfDVList(dvl);
1603 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1604 }
[1143]1605}
[839]1606
[1143]1607
[1246]1608void FitsOutFile::writeSignatureOnFits(int hdunum) const
[839]1609{
1610 int status = 0;
[1246]1611 int hdutype;
[839]1612 char keyname[LEN_KEYWORD];
1613 char strval[FLEN_VALUE];
1614 char comment[FLEN_COMMENT];
[1246]1615 if (hdunum_ == 0)
1616 {
1617 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
1618 return;
1619 }
1620 fits_movabs_hdu(fptr_,1,&hdutype,&status);
1621 //
[971]1622 strncpy(keyname, "CREATOR", LEN_KEYWORD);
1623 keyname[LEN_KEYWORD-1] = '\0';
1624 strcpy(strval, "SOPHYA");
1625 strcpy(comment," SOPHYA Package - FITSIOServer ");
1626 fits_write_key(fptr_, TSTRING, keyname, &strval, comment, &status);
1627 if( status ) printerror( status );
[1143]1628 fits_write_date(fptr_, &status);
[971]1629 fits_write_comment(fptr_,"..............................................", &status);
1630 fits_write_comment(fptr_, " SOPHYA package - FITSIOSever ", &status);
1631 fits_write_comment(fptr_, " (C) LAL/IN2P3-CNRS Orsay, FRANCE 2000", &status);
1632 fits_write_comment(fptr_, " (C) DAPNIA/CEA Saclay, FRANCE 2000", &status);
1633 fits_write_comment(fptr_,"..............................................", &status);
[1045]1634 if( status ) printerror( status, "erreur writeSignatureOnFits" );
[1246]1635 //
1636 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
[839]1637}
1638
[903]1639
[1246]1640void FitsOutFile::addKeywordsOfDVList( DVList& dvl) const
[1143]1641{
1642 int status = 0;
1643 fits_write_comment(fptr_,"---------- keywords from SOPHYA ---------", &status);
1644 DVList::ValList::const_iterator it;
1645 for(it = dvl.Begin(); it != dvl.End(); it++)
1646 {
[1311]1647 MuTyV::MTVType keytype= (*it).second.elval.Type();
[1143]1648 char keyname[10];
1649 strncpy(keyname,(*it).first.substr(0,64).c_str(),10);
[1183]1650 string key(keyname);
[1143]1651 char comment[FLEN_COMMENT];
1652 char strval[FLEN_VALUE]= "";
1653 char *comkey = "COMMENT";
1654 fits_read_keyword(fptr_, keyname, strval, NULL, &status);
1655 if (status != 0 || strncmp(keyname,comkey,LEN_KEYWORD-1) == 0 )
1656 {
[1183]1657 string coco = dvl.GetComment(key);
1658 coco.copy( comment, FLEN_COMMENT-1);
1659 int bout = (coco.length() < FLEN_COMMENT) ? coco.length() : FLEN_COMMENT-1;
1660 comment[bout]= '\0';
[1143]1661 status = 0;
1662 switch (keytype)
1663 {
[1311]1664 case MuTyV::MTVInteger :
[1143]1665 {
[1183]1666 int ival = (int)dvl.GetI(key);
1667 fits_write_key(fptr_,TINT,keyname,&ival, comment,&status);
[1143]1668 break;
1669 }
[1311]1670 case MuTyV::MTVFloat :
[1143]1671 {
[1183]1672 double dval= (double)dvl.GetD(key);
[1143]1673 fits_write_key(fptr_,TDOUBLE,keyname,&dval,comment,&status);
1674 break;
1675 }
[1311]1676 case MuTyV::MTVString :
[1143]1677 {
[1183]1678 char strvaleur[FLEN_VALUE]= "";
1679 string valChaine = dvl.GetS(key);
1680 valChaine.copy(strvaleur, FLEN_VALUE-1);
1681 int fin = (valChaine.length() < FLEN_VALUE) ? valChaine.length() : FLEN_VALUE-1;
1682 strvaleur[fin]= '\0';
1683
1684 fits_write_key(fptr_,TSTRING,keyname,&strvaleur,comment,&status);
[1143]1685 break;
1686 }
1687 }
1688 }
1689 if( status ) printerror( status,"fitsfile: probleme ecriture mot-cle du dvlist" );
1690 }
1691 fits_write_comment(fptr_,"--------------------------------------", &status);
1692}
[903]1693
1694
[1246]1695void FitsOutFile::addDVListOnPrimary()
1696 {
1697 int status = 0;
1698 int hdutype;
1699 if (hdunum_ == 0)
1700 {
1701 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
1702 return;
1703 }
1704 if (dvlToPrimary_ != NULL)
1705 {
1706 fits_movabs_hdu(fptr_,1,&hdutype,&status);
1707 addKeywordsOfDVList(*dvlToPrimary_);
1708 delete dvlToPrimary_;
1709 dvlToPrimary_ = NULL;
1710 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1711 }
1712 }
[839]1713
Note: See TracBrowser for help on using the repository browser.