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

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

changement convention pour premier header

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