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

Last change on this file since 2197 was 2197, checked in by lemeur, 23 years ago

toilette d'ete : rationalisation de types...

File size: 68.2 KB
Line 
1#include "machdefs.h"
2#include <stdlib.h>
3#include "fitsfile.h"
4#include "pexceptions.h"
5#include "strutil.h"
6#include "anydataobj.h"
7#include "fitsspherehealpix.h"
8
9/*!
10 \defgroup FitsIOServer FitsIOServer module
11 This module contains classes which handle FITS format I/O for
12 SOPHYA objects. This module uses cfitsio library.
13*/
14
15void BnTblLine::setFormat(int dc, int fc, int ic, int lc, int bc,int cc, vector<string> names)
16 {
17 int nbcols = dc + fc + ic + cc + lc + bc;
18 int maxName = names.size();
19 if (nbcols != maxName)
20 {
21 cout << " WARNING: BnTblLine:: length of vector of column names not equal to total number of columns" << endl;
22 maxName = nbcols < maxName ? nbcols : maxName;
23 }
24 ColName_ = vector<string>(nbcols);
25 for (int k=0; k < maxName; k++) ColName_[k] = names[k];
26 if (dc >0) ddata_ = vector<double>(dc);
27 if (fc >0) fdata_ = vector<float>(fc);
28 if (ic >0) idata_ = vector<int>(ic);
29 if (lc >0) ldata_ = vector<long>(lc);
30 if (bc >0) bdata_ = vector<unsigned char>(bc);
31 if (cc >0) cdata_ = vector<string>(cc);
32 }
33
34bool BnTblLine::sameFormat(const BnTblLine& btl) const
35 {
36 if (btl.ddata_.size() == ddata_.size() && btl.fdata_.size() == fdata_.size() && btl.idata_.size() == idata_.size() && btl.cdata_.size() == cdata_.size() && btl.ldata_.size() == ldata_.size() && btl.bdata_.size() == bdata_.size()) return true;
37 else return false;
38 }
39
40void BnTblLine::Print()
41 {
42 int k;
43 cout << " ********* ligne ************* " << endl;
44 cout << " *** noms de variables " << endl;
45 for (k=0; k < ColName_.size(); k++) cout << ColName_[k] << " ";
46 cout << endl;
47 cout << " *** variables doubles " << endl;
48 for (k=0; k < ddata_.size(); k++) cout << ddata_[k] << " ";
49 cout << endl;
50 cout << " *** variables float " << endl;
51 for (k=0; k < fdata_.size(); k++) cout << fdata_[k] << " ";
52 cout << endl;
53 cout << " *** variables int " << endl;
54 for (k=0; k < idata_.size(); k++) cout << idata_[k] << " ";
55 cout << endl;
56 cout << " *** variables string " << endl;
57 for (k=0; k < cdata_.size(); k++) cout << cdata_[k] << " ";
58 cout << endl;
59 cout << " *** variables long " << endl;
60 for (k=0; k < ldata_.size(); k++) cout << ldata_[k] << " ";
61 cout << endl;
62 cout << " *** variables byte " << endl;
63 for (k=0; k < bdata_.size(); k++) cout << (int)bdata_[k] << " ";
64 cout << endl;
65 cout << " ***************************** " << endl;
66 }
67
68FitsFile::BufferLine::BufferLine(const vector<FitsFile::FitsDataType>& types)
69{
70
71
72 int dc=0;
73 int fc=0;
74 int shc=0;
75 int ic=0;
76 int lc=0;
77 int cc=0;
78 int bc=0;
79 id_ = vector< pair<FitsFile::FitsDataType, int> >(types.size());
80 for (int k= 0; k < types.size(); k++)
81 {
82 switch( types[k] )
83 {
84 case FitsFile::FitsDataType_double :
85 {
86 id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_double, dc);
87 dc++;
88 break;
89 }
90 case FitsFile::FitsDataType_float :
91 {
92 id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_float, fc);
93 fc++;
94 break;
95 }
96 case FitsFile::FitsDataType_short :
97 {
98 id_[k] = pair<FitsFile::FitsDataType, int>(FitsDataType_short, shc);
99 shc++;
100 break;
101 }
102 case FitsFile::FitsDataType_int :
103 {
104 id_[k] = pair<FitsFile::FitsDataType, int>(FitsDataType_int, ic);
105 ic++;
106 break;
107 }
108 case FitsFile::FitsDataType_long :
109 {
110 id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_long, lc);
111 lc++;
112 break;
113 }
114 case FitsFile::FitsDataType_byte :
115 {
116 id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_byte, bc);
117 bc++;
118 break;
119 }
120 case FitsDataType_char :
121 {
122 id_[k] = pair<FitsFile::FitsDataType, int>(FitsFile::FitsDataType_char, cc);
123 cc++;
124 break;
125 }
126 default:
127 {
128 throw PException(" FitsFile::getHeaderWithSophyaObject() : unsupported FITS data type");
129 }
130 }
131 }
132
133 if (dc >0) ddata_ = vector<r_8>(dc);
134 if (fc >0) fdata_ = vector<r_4>(fc);
135 if (shc >0) shdata_ = vector<int_2>(shc);
136 if (ic >0) idata_ = vector<int_4>(ic);
137 if (lc >0) ldata_ = vector<int_8>(lc);
138 if (cc >0) cdata_ = vector<string>(cc);
139 if (bc >0) bdata_ = vector<unsigned char>(bc);
140}
141
142
143void FitsFile::BufferLine::Print() const
144{
145 cout << " impression de la ligne: " << endl;
146
147 cout << " doubles : " << endl;
148 for (int k=0; k< ddata_.size(); k++)
149 {
150 cout << ddata_[k] << " " ;
151 }
152 cout << endl;
153
154 cout << " floats : " << endl;
155 for (int k=0; k< fdata_.size(); k++)
156 {
157 cout << fdata_[k] << " " ;
158 }
159 cout << endl;
160
161 cout << " entiers courts: " << endl;
162 for (int k=0; k< shdata_.size(); k++)
163 {
164 cout << shdata_[k] << " " ;
165 }
166 cout << endl;
167 cout << " entiers : " << endl;
168 for (int k=0; k< idata_.size(); k++)
169 {
170 cout << idata_[k] << " " ;
171 }
172 cout << endl;
173
174 cout << " entiers longs : " << endl;
175 for (int k=0; k< ldata_.size(); k++)
176 {
177 cout << ldata_[k] << " " ;
178 }
179 cout << endl;
180
181 cout << " chaines carac. : " << endl;
182 for (int k=0; k< cdata_.size(); k++)
183 {
184 cout << cdata_[k] << " " ;
185 }
186 cout << endl;
187
188 cout << " bytes : " << endl;
189 for (int k=0; k< bdata_.size(); k++)
190 {
191 cout << (char)bdata_[k] << " " ;
192 }
193 cout << endl;
194
195
196}
197
198/*!
199 \class SOPHYA::FitsIOHandler
200 \ingroup FitsIOServer
201The class structure is analogous to Sophya-PPersist system :
202Each SOPHYA object XXX is associated with a object of class FITS_XXX
203 (inheriting from FitsFileHandler), to which input/output operations with FITS
204 files are delegated (through a class Hierarchy : FitsFile (virtual),
205 FitsInFile, FitsOutFile) . A typical example of use is the following :
206
207\verbatim
208 int m=... ;
209 SphereHEALPix<r_8> sphere1(m); // definition of the SOPHYA object
210 .... fill the sphere ....
211
212 FITS_SphereHEALPix<r_8> fits_sph1(sphere1);
213 // delegated object
214 fits_sph.Write("myfile.fits"); // writing on FITS file
215
216 FITS_SphereHEALPix<r_8> fits_sph2("myfile.fits");
217 // load a delegated object
218 // from FITS file
219 SphereHEALPix<r_8> sphere2=(SphereHEALPix<r_8>)fits_sph2;
220 // casting the delegated object
221 // into a SOPHYA object
222\endverbatim
223
224
225*/
226
227/*! \fn void SOPHYA::FitsIOHandler::Read(char flnm[],int hdunum)
228
229this method is called from inherited objects :
230
231opens a file 'flnm'
232
233gets parameters in extension-header (hdunum)
234
235calls the method 'ReadFromFits' from the inherited object
236*/
237void FitsIOHandler::Read(char flnm[],int hdunum)
238{
239 FitsInFile ifts(flnm);
240 Read(ifts, hdunum);
241}
242
243 /*! \fn void SOPHYA::FitsIOHandler::Read(FitsInFile& is, int hdunum)
244Read 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.
245 */
246void FitsIOHandler::Read(FitsInFile& is, int hdunum)
247{
248 is.ReadHeader(hdunum);
249 ReadFromFits(is);
250}
251
252
253/*! \fn void SOPHYA::FitsIOHandler::Write(char flnm[])
254this method is called from inherited objects.
255
256for writing a new object in a new fits-extension :
257
258\warning By convention, primary header may contain fits-image data.
259For switching off this convention (i.e. to make sure that all data will be on fits-extensions) use the method :
260
261firstImageOnPrimaryHeader() (see below)
262
263calls the method 'WriteToFits' from the inherited object
264
265*/
266void FitsIOHandler::Write(char flnm[])
267
268{
269 FitsOutFile of(flnm, FitsFile::unknown);
270 Write(of);
271}
272
273void FitsIOHandler::Write(FitsOutFile& os)
274{
275 WriteToFits(os);
276}
277
278
279
280
281FitsFile::~FitsFile()
282{
283 int status = 0;
284 if( fptr_ != NULL)
285 {
286 fits_close_file(fptr_,&status);
287 // je ne fais pas delete fptr_, c'est la lib. fitsio qui a fait
288 // new...
289 }
290 if( status ) printerror( status );
291}
292
293
294void FitsFile::printerror(int &status)
295 //*****************************************************/
296 //* Print out cfitsio error messages and exit program */
297 //*****************************************************/
298{
299 if( status )
300 {
301 fits_report_error(stderr,status);
302 throw IOExc("FitsFile:: error FITSIO status");
303 }
304 return;
305}
306
307void FitsFile::printerror(int& status, char* texte)
308 //*****************************************************/
309 //* Print out cfitsio error messages and exit program */
310 //*****************************************************/
311{
312 // print out cfitsio error messages and exit program
313 // print error report
314 fits_report_error(stderr, status);
315 cout << " erreur:: " << texte << endl;
316 throw IOExc("FitsFile:: error FITSIO status");
317}
318void FitsFile::printerrorAndContinue(int& status, char* texte)
319 //*****************************************************/
320 //* Print out cfitsio error messages and exit program */
321 //*****************************************************/
322{
323 // print out cfitsio error messages and exit program
324 // print error report
325 fits_report_error(stderr, status);
326 cout << " erreur:: " << texte << endl;
327 // throw IOExc("FitsFile:: error FITSIO status");
328}
329
330void FitsFile::ResetStatus(int& status)
331{
332 fits_status_ = status;
333 status = 0;
334 fits_clear_errmsg();
335}
336
337string FitsFile::GetErrStatus(int status)
338{
339 char text[31];
340 fits_get_errstatus(status, text);
341 return string(text);
342}
343
344/*!
345 \class SOPHYA::FitsInFile
346 \ingroup FitsIOServer
347class for reading SOPHYA objects from FITS Format Files (uses cfitsio lib)
348*/
349
350FitsInFile::FitsInFile()
351{
352 InitNull();
353}
354
355FitsInFile::FitsInFile(string const & flnm)
356{
357 InitNull();
358 int status = 0;
359 fits_open_file(&fptr_,flnm.c_str(),READONLY,&status);
360 if( status ) printerror( status );
361}
362
363FitsInFile::FitsInFile(const char * flnm)
364{
365 InitNull();
366 int status = 0;
367 fits_open_file(&fptr_,flnm,READONLY,&status);
368 if( status ) printerror( status );
369}
370
371
372void FitsInFile::InitNull()
373{
374 imageDataType_ = FitsDataType_NULL;
375 naxis_ = 0;
376 nbData_ = 0;
377 nrows_ = 0;
378 nbcols_ = 0;
379 naxisn_.clear();
380 repeat_.clear();
381 noms_.clear();
382 taille_des_chaines_.clear();
383 dvl_.Clear();
384
385 dnull_ = 1.e-300;
386 fnull_ = 1.e-33;
387 inull_= 99999;
388 cnull_= string("xxx");
389
390
391}
392
393//////////////////////////////////////////////////////////
394// methods with general purpose
395/////////////////////////////////////////////////////////
396
397int FitsInFile::NbBlocks(char flnm[])
398{
399 int status = 0;
400 int nbhdu = 0;
401 fitsfile* fileptr;
402 fits_open_file(&fileptr,flnm,READONLY,&status);
403 if( status ) printerror( status, "NbBlocks: erreur ouverture fichier" );
404 fits_get_num_hdus(fileptr, &nbhdu, &status);
405 fits_close_file(fileptr,&status);
406 return nbhdu;
407}
408int FitsInFile::NbBlocks()
409{
410 int status = 0;
411 int nbhdu = 0;
412 fits_get_num_hdus(fptr_, &nbhdu, &status);
413 return nbhdu;
414}
415
416void FitsInFile::GetBlockType(char flnm[], int hdunum, FitsExtensionType& typeOfExtension, int& naxis, vector<int>& naxisn, FitsDataType& dataType, DVList& dvl )
417{
418 int status = 0;
419 fitsfile* fileptr;
420 fits_open_file(&fileptr,flnm,READONLY,&status);
421 if( status ) printerror( status, "GetBlockType: erreur ouverture fichier" );
422 // move to the specified HDU number
423 int hdutype = 0;
424 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
425 if( status ) printerror( status,"GetBlockType: erreur movabs");
426 if(hdutype == IMAGE_HDU)
427 {
428 typeOfExtension = FitsExtensionType_IMAGE;
429 GetImageParameters (fileptr, dataType, naxis, naxisn);
430 }
431 else
432 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
433 {
434 int nrows = 0;
435 vector<string> noms;
436 vector<FitsDataType> types;
437 vector<int> taille_des_chaines;
438 GetBinTabParameters(fileptr, naxis, nrows, naxisn, noms, types, taille_des_chaines);
439 int k;
440 for (k=0; k< naxisn.size(); k++) naxisn[k] *= nrows;
441 if(hdutype == ASCII_TBL)
442 {
443 typeOfExtension = FitsExtensionType_ASCII_TBL;
444 dataType = FitsDataType_ASCII;
445 }
446 else
447 {
448 typeOfExtension = FitsExtensionType_BINARY_TBL;
449 dataType = types[0];
450 }
451 }
452 else
453 {
454 cout << " hdutype= " << hdutype << endl;
455 throw IOExc("FitsFile::GetBlockType: this HDU type is unknown");
456 }
457
458 KeywordsIntoDVList(fileptr, dvl, hdunum);
459 fits_close_file(fileptr,&status);
460}
461
462
463void FitsInFile::ReadHeader(int hdunum)
464{
465 // InitNull();
466 int status = 0;
467 if (hdunum<0)
468 {
469 throw PException(" FitsInFile::ReadHeader : hdu number must be not negative");
470 }
471 if (hdunum != 0 ) hdunum_ = hdunum;
472
473 // si le numero de header non precise
474 else
475 {
476 // si c'est le premier objet a lire
477 if (hdunum_ == 0)
478 {
479 // on calcule le numero de header a lire
480 if (imageOnPrimary_ == true ) hdunum_ = 1;
481 else hdunum_ = 2;
482 }
483 // sinon objet suivant
484 else hdunum_++;
485 }
486 getHeaderWithSophyaObject();
487 if ( hdutype_ == FitsExtensionType_NULL )
488 {
489 if (hdunum == 0 && hdunum_ == 1)
490 {
491 hdunum_++;
492 getHeaderWithSophyaObject();
493 }
494 else
495 {
496 cout << " WARNING (FitsInFile::ReadHeader) : no SOPHYA object on HDU number : " << hdunum_ << endl;
497 }
498 }
499 if ( hdutype_ == FitsExtensionType_EOF )
500 {
501 throw PException("FitsFile::ReadHeader, attempt to read through EOF");
502 }
503}
504
505string FitsInFile::getStringKeyword(int hdunum, string keyw, int& retStatus)
506{
507 string s;
508 retStatus = 0;
509 int status = 0;
510 if (hdunum != hdunum_ )
511 {
512 int hdutype;
513 fits_movabs_hdu(fptr_,hdunum,&hdutype,&status);
514 }
515
516 char value[FLEN_VALUE];
517 char* keyname= const_cast<char*>(keyw.c_str());
518 fits_read_key_str(fptr_,keyname,value,NULL,&status);
519 if (status == 0)
520 s = string(value);
521 else retStatus = status;
522 if (hdunum != hdunum_ )
523 {
524 int hdutype;
525 if (hdunum_ != 0)
526 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
527 else fits_movabs_hdu(fptr_,1,&hdutype,&status);
528
529 }
530 return s;
531}
532bool FitsInFile::hasKeyword(int hdunum, string keyw)
533 {
534 bool has=false;
535 int status = 0;
536 if (hdunum != hdunum_ )
537 {
538 int hdutype;
539 fits_movabs_hdu(fptr_,hdunum,&hdutype,&status);
540 }
541
542 char value[FLEN_VALUE];
543 char* keyname= const_cast<char*>(keyw.c_str());
544 fits_read_keyword(fptr_,keyname,value,NULL,&status);
545 if (status == 0)
546 has = true;
547 else
548 if (status == KEY_NO_EXIST ) status =0;
549 else fits_report_error(stderr,status);
550 if (hdunum != hdunum_ )
551 {
552 int hdutype;
553 if (hdunum_ != 0)
554 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
555 else fits_movabs_hdu(fptr_,1,&hdutype,&status);
556
557 }
558 return has;
559 }
560
561void FitsInFile::GetKeywordsFromHeader (int hdunum, list<FitsKeyword>& mots_cles) const
562{
563 int status = 0;
564 int hdutype;
565 fits_movabs_hdu(fptr_,hdunum,&hdutype,&status);
566 if( status ) fits_report_error(stderr,status);
567
568 // get number of keywords
569 int nkeys,keypos;
570 fits_get_hdrpos(fptr_, &nkeys, &keypos,&status);
571 if( status ) fits_report_error(stderr,status);
572 // shift with the number of mandatory keywords
573 int num= 0;
574 // if primary header
575 if (hdunum == 1)
576 {
577 // read NAXIS
578 int naxis=0;
579 fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
580 // number of mandatory keywords
581 num = naxis+3;
582 }
583 // extensions
584 else
585 {
586 if (hdutype == IMAGE_HDU)
587 {
588 // read NAXIS
589 int naxis=0;
590 fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
591 // number of mandatory keywords
592 num = naxis+5;
593 }
594 else
595 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
596 {
597 // number of mandatory keywords
598 num = 8;
599 }
600 }
601 int j;
602 char keyname[LEN_KEYWORD];
603 char value[FLEN_VALUE];
604 char comment[FLEN_COMMENT];
605 for(j = num+1; j <= nkeys; j++)
606 {
607 char dtype;
608 fits_read_keyn(fptr_,j,keyname,value,comment,&status);
609 if(status)
610 {
611 fits_report_error(stderr,status);
612 status=0;
613 }
614 string kn(keyname);
615 string cm(comment);
616 string val(value);
617 FitsKeyword kw(kn, val, cm);
618 mots_cles.push_back(kw);
619 }
620 if (hdunum_ > 0) fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
621
622}
623void FitsInFile::GetImageParameters (fitsfile* fileptr,FitsDataType& dataType,int& naxis,vector<int>& naxisn)
624{
625 int hdunum=0;
626 // cout << " Reading a FITS image in HDU : " << fits_get_hdu_num(fileptr,&hdunum) << endl;
627 int status= 0;
628
629 // bits per pixels
630 int bitpix=0;
631 fits_read_key(fileptr,TINT,"BITPIX",&bitpix,NULL,&status);
632 if( status ) printerror( status );
633 if(bitpix == DOUBLE_IMG) dataType = FitsDataType_double;
634 else if(bitpix == FLOAT_IMG) dataType = FitsDataType_float;
635 else if(bitpix == LONG_IMG || bitpix == SHORT_IMG ) dataType = FitsDataType_int;
636 else if (bitpix == BYTE_IMG) dataType = FitsDataType_char;
637 else
638 {
639 cout << " bitpix= " << bitpix << endl;
640 throw PException(" FitsFile::GetImageParameters : unsupported FITS data type");
641 }
642
643 // number of dimensions in the FITS array
644 naxis= 0;
645 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
646 if( status ) printerror( status );
647 // read the NAXISn keywords to get image size
648 long* naxes = new long[naxis] ;
649 int nfound;
650 fits_read_keys_lng(fileptr,"NAXIS",1,naxis,naxes,&nfound,&status);
651 if( status ) printerror( status );
652 if (nfound != naxis )
653 cout << " WARNING : " << nfound << " axes found, expected naxis= " << naxis << endl;
654 int k;
655 for (k=0; k<naxis; k++)
656 {
657 naxisn.push_back( (int)naxes[k] );
658 }
659 delete [] naxes;
660}
661
662
663
664
665 /*! \fn DVList SOPHYA::FitsInFile::DVListFromPrimaryHeader() const
666
667 \return the keywords of primary header in a DVList
668
669*/
670DVList FitsInFile::DVListFromPrimaryHeader() const
671 {
672 int status;
673 DVList dvl;
674 KeywordsIntoDVList(fptr_, dvl, 1);
675 int hdutype = 0;
676 if (hdunum_ > 0) fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
677 return dvl;
678 }
679
680void FitsInFile::getHeaderWithSophyaObject()
681{
682 // si hdunum_ > 1 lit le header correspondant
683 // si hdunum_ = 1 se positionne au (et lit le) premier header qui
684 // contient reellement un objet
685 int status=0;
686 if (hdunum_ < 1) throw PException(" attempt to read hdunum < 1");
687 InitNull();
688 if (hdunum_ == 1)
689 {
690 // presence of image ?
691 int naxis= 0;
692 fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
693 if( status ) printerror( status );
694 if (naxis > 0 ) // there is an image
695 {
696 hdutype_ = FitsExtensionType_IMAGE;
697 GetImageParameters (fptr_, imageDataType_, naxis_, naxisn_);
698 nbData_ = 1;
699 int k;
700 for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
701 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
702 }
703 else
704 {
705 hdutype_ = FitsExtensionType_NULL;
706 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
707 }
708 }
709 else
710 {
711 int hdutype;
712 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
713
714 if( status )
715 {
716 if (status == END_OF_FILE)
717 {
718 hdutype_= FitsExtensionType_EOF;
719 status =0;
720 return;
721 }
722 else
723 {
724 cout << "WARNING (FitsInFile::getHeaderWithSophyaObject) : error during movabs" << endl;
725 hdutype_= FitsExtensionType_ERROR;
726 status =0;
727 return;
728 }
729 // printerror( status,":FitsInFile::getHeader : erreur movabs");
730 }
731
732
733 if(hdutype == IMAGE_HDU)
734 {
735 hdutype_= FitsExtensionType_IMAGE;
736 GetImageParameters (fptr_, imageDataType_, naxis_, naxisn_);
737 nbData_ = 1;
738 int k;
739 for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
740 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
741 }
742 else if(hdutype == ASCII_TBL)
743 {
744 hdutype_= FitsExtensionType_ASCII_TBL;
745 GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_);
746 KeywordsIntoDVList(fptr_, dvl_, hdunum_);
747 }
748 else if(hdutype == BINARY_TBL)
749 {
750 hdutype_= FitsExtensionType_BINARY_TBL;
751 GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_);
752 KeywordsIntoDVList(fptr_, dvl_, hdunum_);
753 }
754 else
755 {
756 hdutype_= FitsExtensionType_NULL;
757 KeywordsIntoDVList(fptr_, dvl_, hdunum_);
758 }
759
760 }
761 if (hdutype_ == FitsExtensionType_BINARY_TBL || hdutype_ == FitsExtensionType_ASCII_TBL)
762 {
763 bfl_ = BufferLine(types_);
764 }
765}
766
767
768void FitsInFile::moveToFollowingHeader()
769{
770 int status = 0;
771 hdunum_++;
772 getHeaderWithSophyaObject();
773 if ( hdutype_ == FitsExtensionType_NULL )
774 {
775 cout << " WARNING (FitsInFile::ReadHeader) : no SOPHYA object on HDU number : " << hdunum_ << endl;
776
777 }
778}
779
780
781
782
783
784/*! \fn int SOPHYA::FitsInFile::NbColsFromFits() const
785\return number of columns (return 1 if IMAGE)
786*/
787int FitsInFile::NbColsFromFits() const
788{
789 if(hdutype_ == FitsExtensionType_BINARY_TBL) return nbcols_;
790 else
791 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_IMAGE) return 1;
792 else
793 {
794 cout << " hdutype= " << (int) hdutype_ << endl;
795 throw PException("FitsFile::NbColsFromFits, HDU not supported");
796 }
797}
798
799/*! \fn int SOPHYA::FitsInFile::NentriesFromFits(int nocol) const
800\return number of data in the current IMAGE extension on FITS file, or number
801 of data of column number 'nocol' of the current BINTABLE extension
802*/
803int FitsInFile::NentriesFromFits(int nocol) const
804{
805 if(hdutype_ == FitsExtensionType_BINARY_TBL) return nrows_*repeat_[nocol];
806 else
807 if(hdutype_ == FitsExtensionType_ASCII_TBL) return nrows_;
808 else
809 if(hdutype_ == FitsExtensionType_IMAGE) return nbData_;
810 else
811 {
812 cout << "hdutype= " << (int) hdutype_ << endl;
813 throw PException("FitsFile::NentriesFromFits, this HDU is not supported");
814 }
815}
816
817/*! \fn char SOPHYA::FitsInFile::ColTypeFromFits(int nocol) const
818
819return a character denoting data type of column number 'nocol' in a BINTABLE :
820
821D : double
822
823E : float
824
825I : integer
826
827S : character string
828
829 */
830
831FitsFile::FitsDataType FitsInFile::ColTypeFromFits(int nocol) const
832{
833 if(hdutype_ != FitsExtensionType_ASCII_TBL && hdutype_ != FitsExtensionType_BINARY_TBL)
834 {
835 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
836 }
837 return types_[nocol];
838}
839
840
841/*! \fn string SOPHYA::FitsInFile::ColNameFromFits(int nocol) const
842
843\return name of the column number 'nocol' of the current BINTABLE extension
844 */
845
846string FitsInFile::ColNameFromFits(int nocol) const
847{
848 if(hdutype_ != FitsExtensionType_ASCII_TBL && hdutype_ != FitsExtensionType_BINARY_TBL)
849 {
850 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
851 }
852 return noms_[nocol];
853}
854
855/*! \fn int DSOPHYA::FitsInFile::ColStringLengthFromFits(int nocol) const
856
857 \return number of characters of each data for the column number 'nocol' (if char* typed) of the current BINTABLE extension
858*/
859
860int FitsInFile::ColStringLengthFromFits(int nocol) const
861{
862 if(hdutype_ != FitsExtensionType_ASCII_TBL && hdutype_ != FitsExtensionType_BINARY_TBL)
863 {
864 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
865 }
866 int index=-1;
867 int k;
868 for (k=0; k<=nocol; k++)
869 {
870 if (types_[k] == FitsDataType_char) index++;
871 }
872 return taille_des_chaines_[index];
873}
874
875const FitsFile::BufferLine& FitsInFile::GetBufferLine(long NoLine)
876{
877 int status= 0;
878 int anynul;
879 double dnull= dnull_;
880 float fnull= fnull_;
881 int inull= inull_;
882 char* cnull= const_cast<char*>(cnull_.c_str());
883 int ncol;
884 long nels=1;
885 double dval;
886 float fval;
887 int ival;
888
889 // pas d'entier de longueur superieure a 32 bits, pour cfitsio
890 int lval;
891
892 unsigned char usval;
893 int rang = 0;
894 int ccount = 0;
895 for (ncol=0; ncol<nbcols_; ncol++)
896 {
897 rang = bfl_.identificateur()[ncol].second;
898 // cout << " fitsfile : relecture col " << ncol << " type " << bfl_.identificateur()[ncol].first << " rang " << rang << endl;
899 switch (bfl_.identificateur()[ncol].first)
900 {
901 case FitsDataType_double :
902 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull, &dval,&anynul,&status);
903 bfl_.r_8Array(rang) = (r_8)dval;
904 break;
905 case FitsDataType_float :
906 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fval,&anynul,&status);
907 bfl_.r_4Array(rang) = (r_4)fval;
908 break;
909 case FitsDataType_short :
910 fits_read_col(fptr_,TSHORT,ncol+1,NoLine+1,1,1,&inull,&ival, &anynul,&status);
911 bfl_.int_2Array(rang) = (int_2)ival;
912 break;
913 case FitsDataType_int :
914 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ival, &anynul,&status);
915 bfl_.int_4Array(rang) = (int_4)ival;
916 break;
917 case FitsDataType_long :
918 fits_read_col(fptr_,TLONG,ncol+1,NoLine+1,1,1,&inull,&lval, &anynul,&status);
919 bfl_.int_8Array(rang) = (int_8)lval;
920 break;
921 case FitsDataType_byte :
922 fits_read_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1,&inull, &usval, &anynul,&status);
923 bfl_.u_charArray(rang) = usval;
924 break;
925 case FitsDataType_char :
926 char* chaine = new char[taille_des_chaines_[ccount++]];
927 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anynul,&status);
928 bfl_.stringArray(rang) = string(chaine);
929 break;
930 }
931 if (status)
932 {
933 ResetStatus(status);
934 break;
935 }
936 }
937 // cout << " fitsfile : ligne relue " << endl;
938 // bfl_.Print();
939 return bfl_;
940}
941
942
943
944/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
945
946Get the NoLine-th 'line' from the current BINTABLE extension on FITS file,
947 */
948
949void FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
950{
951 int status= 0;
952 int anynul;
953 double dnull= dnull_;
954 float fnull= fnull_;
955 int inull= inull_;
956 char* cnull= const_cast<char*>(cnull_.c_str());
957 int dcount = 0.;
958 int fcount = 0.;
959 int icount = 0;
960 int ccount =0;
961 int ncol;
962 long nels=1;
963 int ligneAsolue = NoLine+1;
964 for (ncol=0; ncol<nbcols_; ncol++)
965 {
966 int repetition =repeat_[ncol];
967 int ligneALire = ligneAsolue/repetition;
968 int premierElement = ligneAsolue-ligneALire*repetition;
969 if (premierElement != 0 )
970 {
971 ligneALire++;
972 }
973 else premierElement = repetition;
974
975 switch (types_[ncol])
976 {
977 case FitsDataType_double :
978 {
979 fits_read_col(fptr_,TDOUBLE,ncol+1,ligneALire,premierElement,1,&dnull,&ddata[dcount++],&anynul,&status);
980 break;
981 }
982 case FitsDataType_float :
983 {
984 fits_read_col(fptr_,TFLOAT,ncol+1,ligneALire,premierElement,1,&fnull,&fdata[fcount++],&anynul,&status);
985 break;
986 }
987 case FitsDataType_int :
988 {
989 fits_read_col(fptr_,TINT,ncol+1,ligneALire,premierElement,1,&inull,&idata[icount++],
990 &anynul,&status);
991 break;
992 }
993 case FitsDataType_long :
994 {
995 fits_read_col(fptr_,TLONG,ncol+1,ligneALire,premierElement,1,&inull,&idata[icount++], &anynul,&status);
996 break;
997 }
998 case FitsDataType_byte :
999 {
1000 unsigned char uschar = 0;
1001 fits_read_col(fptr_,TBYTE,ncol+1,ligneALire,premierElement,1,&inull,&uschar, &anynul,&status);
1002 idata[icount++] = (int)uschar;
1003 break;
1004 }
1005 case FitsDataType_char :
1006 {
1007 fits_read_col(fptr_,TSTRING,ncol+1,ligneALire,premierElement,1,cnull,&cdata[ccount++],&anynul,&status);
1008 break;
1009 }
1010 default:
1011 {
1012 throw PException(" FitsInFile::GetBinTabLine : unsupported FITS data type");
1013 }
1014 }
1015 if (status)
1016 {
1017 ResetStatus(status);
1018 break;
1019 }
1020 }
1021}
1022
1023/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(long NoLine, BnTblLine& ligne)
1024Get the NoLine-th 'line' from the current BINTABLE extension on FITS file,
1025*/
1026void FitsInFile::GetBinTabLine(long NoLine, BnTblLine& ligne)
1027{
1028 int status= 0;
1029 int anynul;
1030 double dnull= dnull_;
1031 float fnull= fnull_;
1032 int inull= inull_;
1033 char* cnull= const_cast<char*>(cnull_.c_str());
1034 int dcount = 0.;
1035 int fcount = 0.;
1036 int icount = 0;
1037 int ccount =0;
1038 int ncol;
1039 long nels=1;
1040 for (ncol=0; ncol<nbcols_; ncol++)
1041 {
1042 switch (types_[ncol])
1043 {
1044 case FitsDataType_double :
1045 {
1046 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ligne.ddata_[dcount++],&anynul,&status);
1047 break;
1048 }
1049 case FitsDataType_float :
1050 {
1051 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&ligne.fdata_[fcount++],&anynul,&status);
1052 break;
1053 }
1054 case FitsDataType_int :
1055 {
1056 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ligne.idata_[icount++], &anynul,&status);
1057 break;
1058 }
1059 case FitsDataType_long :
1060 {
1061 fits_read_col(fptr_,TLONG,ncol+1,NoLine+1,1,1,&inull,&ligne.ldata_[icount++], &anynul,&status);
1062 break;
1063 }
1064 case FitsDataType_byte :
1065 {
1066 fits_read_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1,&inull,&ligne.bdata_[icount++], &anynul,&status);
1067 break;
1068 }
1069 case FitsDataType_char :
1070 {
1071 char* chaine = new char[taille_des_chaines_[ccount]];
1072 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anynul,&status);
1073 ligne.cdata_[ccount++] = string(chaine);
1074 break;
1075 }
1076 default:
1077 {
1078 throw PException(" FitsInFile::GetBinTabLine : unsupported FITS data type");
1079 }
1080 }
1081 if (status)
1082 {
1083 ResetStatus(status);
1084 break;
1085 }
1086 }
1087}
1088
1089
1090
1091/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, float* fdata)
1092
1093Get the NoLine-th float 'line' from the current BINTABLE extension on FITS file,
1094*/
1095void FitsInFile::GetBinTabLine(int NoLine, float* fdata)
1096{
1097 int status= 0;
1098 int anynul;
1099 float fnull= fnull_;
1100 long nels=1;
1101 int ncol;
1102 for (ncol=0; ncol<nbcols_; ncol++)
1103 {
1104 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[ncol],&anynul,&status);
1105 if (status)
1106 {
1107 ResetStatus(status);
1108 break;
1109 }
1110 }
1111}
1112
1113
1114/*! \fn void SPOPHYA::FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
1115
1116fill the array 'valeurs' with double data from the current BINTABLE extension on FITS file, from column number 'NoCol'
1117
1118\param <nentries> number of data to be read
1119*/
1120void FitsInFile::GetBinTabFCol(r_8* valeurs,int nentries, int NoCol) const
1121 {
1122 int status= 0;
1123 int DTYPE;
1124 long repeat,width;
1125 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1126 if( DTYPE != TDOUBLE)
1127 {
1128 if (DTYPE == TFLOAT) cout << " WARNING: reading double from float : conversion will be made by fitsio library" << endl;
1129 else
1130 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non double");
1131 }
1132 long nels=nentries;
1133 int anynul;
1134 double dnull= dnull_;
1135
1136 fits_read_col(fptr_,TDOUBLE,NoCol+1,1,1,nels,&dnull,valeurs,
1137 &anynul,&status);
1138 if( status )
1139 {
1140 printerrorAndContinue( status,"erreur lecture de colonne" );
1141 }
1142 }
1143
1144/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
1145
1146 same as previous method with float data
1147*/
1148void FitsInFile::GetBinTabFCol(r_4* valeurs,int nentries, int NoCol) const
1149 {
1150 int status= 0;
1151 int DTYPE;
1152 long repeat,width;
1153 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1154 if( DTYPE != TFLOAT)
1155 {
1156 if (DTYPE == TDOUBLE) cout << " WARNING: reading float from double : conversion will be made by fitsio library" << endl;
1157 else
1158 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non float");
1159 }
1160 long nels=nentries;
1161 int anynul;
1162 float fnull= fnull_;
1163 fits_read_col(fptr_,TFLOAT,NoCol+1,1,1,nels,&fnull,valeurs,
1164 &anynul,&status);
1165 if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
1166 }
1167
1168/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
1169
1170 same as previous method with int data
1171*/
1172
1173void FitsInFile::GetBinTabFCol(int_4* valeurs,int nentries, int NoCol) const
1174 {
1175 int status= 0;
1176 int DTYPE;
1177 long repeat,width;
1178 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1179 if( DTYPE != TLONG && DTYPE != TINT)
1180 {
1181 throw IOExc("FitsFile::GetBinTabFCol, probleme de lecture d'entiers");
1182 }
1183 long nels=nentries;
1184 int anynul;
1185 int inull= inull_;
1186
1187
1188
1189 // voir commentaire dans putColToFits()
1190 fits_read_col(fptr_,TINT,NoCol+1,1,1,nels,&inull,valeurs,
1191 &anynul,&status);
1192 if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
1193 }
1194
1195/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
1196
1197 same as previous method with char* data
1198*/
1199
1200void FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
1201 {
1202 int status= 0;
1203 int DTYPE;
1204 long repeat,width;
1205 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1206 if( DTYPE != TSTRING && DTYPE != TBYTE)
1207 {
1208 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non string");
1209 }
1210 long nels=nentries;
1211 int anynul;
1212 char* cnull= const_cast<char*>(cnull_.c_str());
1213 long frow=1;
1214 long felem=1;
1215 fits_read_col(fptr_,TSTRING,NoCol+1,frow,felem,nels,cnull,valeurs,
1216 &anynul,&status);
1217 if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
1218 }
1219
1220/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(double* map, int nentries) const
1221fill the array 'map' with double data from the current extension on FITS file.
1222If the extension is BINTABLE, the first column is provided.
1223
1224\param <nentries> number of data to be read
1225*/
1226void FitsInFile::GetSingleColumn(r_8* map, int nentries) const
1227{
1228 int status = 0;
1229 if(hdutype_ == FitsExtensionType_IMAGE)
1230 {
1231
1232 if(imageDataType_ != FitsDataType_double)
1233 {
1234 cout << " The data type on fits file is not double...";
1235 cout << " Conversion to double achieved by cfitsio lib" << endl;
1236 }
1237
1238 int anynul;
1239 double dnull= dnull_;
1240
1241 long nels= nentries;
1242 fits_read_img(fptr_,TDOUBLE,1,nels,&dnull,map,&anynul,&status);
1243 if( status ) printerror( status );
1244 }
1245 else
1246 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
1247 {
1248 GetBinTabFCol(map,nentries, 0);
1249 }
1250 else
1251 {
1252 cout << " hdutype= " << (int) hdutype_ << endl;
1253 throw IOExc("FitsFile::GetSingleColumn, this HDU is unknown");
1254 }
1255}
1256
1257/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(float* map, int nentries) const
1258same as above with float data
1259*/
1260void FitsInFile::GetSingleColumn(r_4* map, int nentries) const
1261{
1262 int status = 0;
1263 if(hdutype_ == FitsExtensionType_IMAGE)
1264 {
1265 if(imageDataType_ != FitsDataType_float)
1266 {
1267 cout << " The data type on fits file is not float ";
1268 cout << " Conversion to float achieved by cfitsio lib" << endl;
1269 }
1270 int anynul;
1271 float fnull= fnull_;
1272
1273 long nels= nentries;
1274 fits_read_img(fptr_,TFLOAT,1,nels,&fnull, map,&anynul,&status);
1275 if( status ) printerror( status );
1276 }
1277 else
1278 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
1279 {
1280 GetBinTabFCol(map,nentries, 0);
1281 }
1282 else
1283 {
1284 cout << " hdutype= " << (int) hdutype_ << endl;
1285 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
1286 }
1287}
1288
1289/*! \fn void SOPHYA::FitsInFile::GetSingleColumn( int* map, int nentries) const
1290 same as above with int data
1291*/
1292void FitsInFile::GetSingleColumn( int_4* map, int nentries) const
1293{
1294 int status = 0;
1295 if(hdutype_ == FitsExtensionType_IMAGE)
1296 {
1297 if(imageDataType_ != FitsDataType_int)
1298 {
1299 cout << " The data type on fits file is not int ";
1300 cout << " Conversion to float achieved by cfitsio lib" << endl;
1301 }
1302 int anynul;
1303 float fnull= fnull_;
1304
1305 long nels= nentries;
1306 fits_read_img(fptr_,TINT,1,nels,&fnull,map,&anynul,&status);
1307 if( status ) printerror( status );
1308 }
1309 else
1310 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
1311 {
1312 GetBinTabFCol(map,nentries, 0);
1313 }
1314 else
1315 {
1316 cout << " hdutype= " << (int) hdutype_ << endl;
1317 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
1318 }
1319}
1320
1321void FitsInFile::GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows,
1322 vector<int>& repeat,
1323 vector<string>& noms,
1324 vector<FitsDataType>& types,
1325 vector<int>& taille_des_chaines)
1326{
1327 int status= 0;
1328 int hdunum=0;
1329 int hdutype=0;
1330 fits_get_hdu_num(fileptr,&hdunum);
1331 fits_get_hdu_type(fileptr, &hdutype, &status);
1332
1333 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1334 {
1335 throw IOExc("FitsFile::GetBinTabParameters this HDU is not an ASCII table nor a binary table");
1336 }
1337 // if(hdutype == ASCII_TBL)
1338 // cout << " Reading a FITS ascii table in HDU : " << hdunum << endl;
1339 // if(hdutype == BINARY_TBL)
1340 // cout << " Reading a FITS binary table in HDU : " << hdunum << endl;
1341
1342 // get the number of columns
1343 fits_get_num_cols(fileptr, &nbcols,&status);
1344 if( status ) printerror( status );
1345
1346 // get the number of rows
1347 long naxis2= 0;
1348 fits_get_num_rows(fileptr,&naxis2,&status);
1349 if( status ) printerror( status );
1350 nrows = (int)naxis2;
1351
1352 // get the datatype, names and the repeat count
1353 noms.clear();
1354 noms.reserve(nbcols);
1355 types.clear();
1356 types.reserve(nbcols);
1357 repeat.clear();
1358 repeat.reserve(nbcols);
1359 taille_des_chaines.clear();
1360 char **ttype = new char*[nbcols];
1361 int ii;
1362 //
1363 //
1364 for (ii=0; ii < nbcols; ii++) ttype[ii]=new char[FLEN_VALUE];
1365 int nfound;
1366 fits_read_keys_str(fileptr, "TTYPE",1,nbcols,ttype,&nfound, &status);
1367 if( status ) printerror( status,"erreur lecture des noms de colonne");
1368 int rept=0;
1369 if(hdutype == ASCII_TBL)
1370 {
1371 for(ii = 0; ii < nbcols; ii++)
1372 {
1373 int DTYPE;
1374 long width;
1375 long repete = 0;
1376 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
1377 if( status ) printerror( status,"erreur lecture type de colonne");
1378 rept = repete;
1379 noms.push_back(string(ttype[ii]));
1380 switch (DTYPE)
1381 {
1382 case TDOUBLE :
1383 types.push_back(FitsDataType_double);
1384 break;
1385 case TFLOAT :
1386 types.push_back(FitsDataType_float);
1387 break;
1388 case TLONG :
1389 types.push_back(FitsDataType_long);
1390 break;
1391 case TINT :
1392 types.push_back(FitsDataType_int);
1393 break;
1394 case TSHORT :
1395 types.push_back(FitsDataType_short);
1396 break;
1397 case TSTRING :
1398 types.push_back(FitsDataType_char);
1399 taille_des_chaines.push_back(width);
1400 rept/=width;
1401 break;
1402 default :
1403 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
1404 throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for ASCII table");
1405 }
1406 repeat.push_back(rept);
1407 }
1408 }
1409 else
1410 {
1411 for(ii = 0; ii < nbcols; ii++)
1412 {
1413 int DTYPE;
1414 long width;
1415 long repete = 0;
1416 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
1417 if( status ) printerror( status,"erreur lecture type de colonne");
1418 rept = repete;
1419 noms.push_back(string(ttype[ii]));
1420 switch (DTYPE)
1421 {
1422 case TDOUBLE :
1423 types.push_back(FitsDataType_double);
1424 break;
1425 case TFLOAT :
1426 types.push_back(FitsDataType_float);
1427 break;
1428 case TLONG :
1429 types.push_back(FitsDataType_long);
1430 break;
1431 case TINT :
1432 types.push_back(FitsDataType_int);
1433 break;
1434 case TSHORT :
1435 types.push_back(FitsDataType_short);
1436 break;
1437 case TSTRING :
1438 types.push_back(FitsDataType_char);
1439 taille_des_chaines.push_back(width);
1440 rept/=width;
1441 break;
1442 case TBYTE :
1443 types.push_back(FitsDataType_byte);
1444 break;
1445 default :
1446 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
1447 throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for BINTABLE");
1448 }
1449 repeat.push_back(rept);
1450 }
1451 }
1452 for (ii=0; ii < nbcols; ii++) delete [] ttype[ii];
1453 delete [] ttype;
1454}
1455
1456void FitsInFile::KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum)
1457{
1458 int status = 0;
1459 int hdutype;
1460 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
1461 if( status ) printerror( status,":KeywordsIntoDVList : erreur movabs");
1462 // get number of keywords
1463 int nkeys,keypos;
1464 fits_get_hdrpos(fileptr,&nkeys,&keypos,&status);
1465 if( status ) printerror( status );
1466
1467 // put keywords in a DVList object
1468 char keyname[LEN_KEYWORD]= "";
1469 char strval[FLEN_VALUE]= "";
1470 char dtype;
1471 char card[FLEN_CARD];
1472 char *comkey = "COMMENT";
1473 char comment[FLEN_COMMENT];
1474
1475 // shift with the number of mandatory keywords
1476 // int num= 8;
1477 int num= 0;
1478 // primary header
1479 if (hdunum == 1)
1480 {
1481 // read NAXIS
1482 int naxis=0;
1483 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1484 // number of mandatory keywords
1485 num = naxis+3;
1486 }
1487 // extensions
1488 else
1489 {
1490 if (hdutype == IMAGE_HDU)
1491 {
1492 // read NAXIS
1493 int naxis=0;
1494 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1495 // number of mandatory keywords
1496 num = naxis+5;
1497 }
1498 else
1499 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
1500 {
1501 // number of mandatory keywords
1502 num = 8;
1503 }
1504 }
1505 int j;
1506 for(j = num+1; j <= nkeys; j++)
1507 {
1508 fits_read_keyn(fileptr,j,card,strval,NULL,&status);
1509 if(status) printerror(status);
1510
1511 strncpy(keyname,card,LEN_KEYWORD-1);
1512 if(strncmp(keyname,comkey,LEN_KEYWORD-1) != 0 && strlen(keyname) != 0
1513 && strlen(strval) != 0)
1514 {
1515 fits_get_keytype(strval,&dtype,&status);
1516 if(status) printerror(status);
1517
1518 strip(keyname, 'B',' ');
1519 strip(strval, 'B',' ');
1520 strip(strval, 'B','\'');
1521
1522 switch( dtype )
1523 {
1524 case 'C':
1525 fits_read_key(fileptr,TSTRING,keyname,strval,comment,&status);
1526 if ( strncmp(keyname,"TTYPE",5) == 0 ||
1527 strncmp(keyname,"TFORM",5) == 0 ||
1528 strncmp(keyname,"TBCOL",5) == 0 ) break;
1529 dvl[keyname]= strval;
1530 dvl.SetComment(keyname, comment);
1531 break;
1532 case 'I':
1533 int ival;
1534 fits_read_key(fileptr,TINT,keyname,&ival,comment,&status);
1535 dvl[keyname]= (int_4) ival; // Portage mac DY
1536 dvl.SetComment(keyname, comment);
1537 break;
1538 case 'L':
1539 int ilog;
1540 fits_read_key(fileptr,TLOGICAL,keyname,&ilog,comment,&status);
1541 dvl[keyname]= (int_4) ilog;
1542 dvl.SetComment(keyname, comment);
1543 break;
1544 case 'F':
1545 double dval;
1546 fits_read_key(fileptr,TDOUBLE,keyname,&dval,comment,&status);
1547 dvl[keyname]= dval;
1548 dvl.SetComment(keyname, comment);
1549 break;
1550 }
1551
1552 }
1553 }
1554 // dvl.Print();
1555}
1556
1557
1558/*!
1559 \class SOPHYA::FitsOutFile
1560 \ingroup FitsIOServer
1561 Class for loading SOPHYA objects from FITS Format Files (uses cfitsio lib)
1562*/
1563
1564FitsOutFile::FitsOutFile()
1565{
1566 InitNull();
1567}
1568
1569 /*! \fn SOPHYA::FitsOutFile::FitsOutFile(char flnm[], WriteMode wrm)
1570
1571\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)
1572
1573 */
1574
1575FitsOutFile::FitsOutFile(string const & flnm, WriteMode wrm)
1576{
1577 InitNull();
1578 openoutputfitsfile(flnm.c_str(), wrm);
1579}
1580
1581FitsOutFile::FitsOutFile(const char * flnm, WriteMode wrm)
1582{
1583 InitNull();
1584 openoutputfitsfile(flnm, wrm);
1585}
1586
1587void FitsOutFile::openoutputfitsfile(const char * flnm, WriteMode wrm)
1588{
1589 int status = 0;
1590
1591 // create new FITS file
1592 fits_create_file(&fptr_,flnm,&status);
1593 if( status )
1594 {
1595
1596 switch (wrm)
1597 {
1598 // si on veut ecrire a la fin de ce fichier
1599 case append :
1600 status = 0;
1601 fits_clear_errmsg();
1602 fits_open_file(&fptr_,flnm,READWRITE,&status);
1603 if( status )
1604 {
1605 cout << " error opening file: " << flnm << endl;
1606 printerror(status, "failure opening a file supposed to exist");
1607 }
1608 else cout << " file " << flnm << " opened, new objects will be appended " << endl;
1609 fits_get_num_hdus(fptr_, &hdunum_, &status);
1610 int hdutype;
1611 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1612 if( status ) printerror( status,":FitsFile::WriteF : erreur movabs");
1613 break;
1614
1615 case clear :
1616 {
1617 status = 0;
1618 fits_clear_errmsg();
1619 char* newname = new char[strlen(flnm)+1];
1620 //
1621 newname[0] = '!';
1622 newname[1] = '\0';
1623 strcat(newname, flnm);
1624 fits_create_file(&fptr_,newname,&status);
1625 delete [] newname;
1626 if (status)
1627 {
1628 cout << " error opening file: " << flnm << endl;
1629 printerror(status, "unable to open file, supposed to exist");
1630 }
1631 else cout << " WARNING : file " << flnm << " is overwritten " << endl;
1632 break;
1633 }
1634 case unknown :
1635 printerror(status, " file seems already to exist");
1636 break;
1637
1638 }
1639 }
1640}
1641
1642
1643
1644/*! \fn void SOPHYA::FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList &dvl)
1645
1646create an IMAGE header on FITS file.
1647\param <type> type of data (see method ColTypeFromFits)
1648\param <nbdim> number of dimensions : 1D, 2D, 3D etc. = NAXIS
1649\param <naxisn> array containind sizes of the different dimensions
1650*/
1651void FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList* ptr_dvl)
1652{
1653 int status = 0;
1654 long naxis = nbdim;
1655 long* naxes = new long[nbdim];
1656 bool hdunfirst= (hdunum_ == 0);
1657 if (hdunfirst)
1658 {
1659 if (imageOnPrimary_ == false)
1660 {
1661 hdunum_ = 1;
1662 fits_create_img(fptr_,FLOAT_IMG,0,naxes,&status);
1663 }
1664 }
1665 int k;
1666 for (k=0; k< nbdim; k++) naxes[k] = (long)naxisn[k];
1667 if (type == 'D')
1668 fits_create_img(fptr_,DOUBLE_IMG,naxis,naxes,&status);
1669 else
1670 if (type == 'E')
1671 fits_create_img(fptr_,FLOAT_IMG,naxis,naxes,&status);
1672 else
1673 if (type == 'I')
1674 fits_create_img(fptr_,LONG_IMG,naxis,naxes,&status);
1675 else
1676 {
1677 cout << " type of data: " << type << endl;
1678 throw PException("FitsFile:::makeHeaderImageOnFits:unprogrammed type of data ");
1679 }
1680
1681 // on ajoute eventuellement un dvlist prepare et la doc SOPHYA
1682 hdunum_++;
1683 if (hdunfirst)
1684 {
1685 addDVListOnPrimary();
1686 writeSignatureOnFits(1);
1687 }
1688
1689 // header format FITS
1690
1691 writeAppendedHeaderOnFits();
1692
1693 // write supplementary keywords (from SOPHYA)
1694 // dvl.Print();
1695 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
1696
1697 delete [] naxes;
1698 if( status ) printerror( status, "erreur creation HDU IMAGE" );
1699
1700}
1701
1702
1703/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, double* map) const
1704
1705write double data from array 'map'on an IMAGE extension
1706\param <nbData> number of data to be written
1707*/
1708void FitsOutFile::PutImageToFits(int nbData, r_8* map) const
1709{
1710 int status = 0;
1711 long npix= nbData;
1712 fits_write_img(fptr_,TDOUBLE,1,npix,map,&status);
1713 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1714}
1715
1716/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, float* map) const
1717
1718same as previous method with float data
1719*/
1720void FitsOutFile::PutImageToFits(int nbData, r_4* map) const
1721{
1722 int status = 0;
1723 long npix= nbData;
1724 fits_write_img(fptr_,TFLOAT,1,npix, map,&status);
1725 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1726
1727}
1728
1729 /*! \fn void SOPHYA::FitsOutFile::PutImageToFits( int nbData, int* map) const
1730
1731 same as previous method with int data */
1732void FitsOutFile::PutImageToFits( int nbData, int_4* map) const
1733{
1734 int status = 0;
1735
1736 long npix= nbData;
1737 fits_write_img(fptr_,TINT,1,npix,map,&status);
1738 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1739}
1740
1741
1742
1743/*! \fn void SOPHYA::FitsOutFile::makeHeaderBntblOnFits( string fieldType, vector<string> Noms, int nentries, int tfields, DVList &dvl, string extname, vector<int> taille_des_chaines)
1744
1745create an BINTABLE header on FITS file.
1746\param <fieldType> array conta
1747ining characters denoting types of the different column (see method ColTypeFromFits)
1748\param <Noms> array of the names of columns
1749\param <nentries> number of data of each column
1750\param <tfields> number of columns
1751\param <dvl> a SOPHYA DVList containing keywords to be appended
1752\param <extname> keyword EXTNAME for FITS file
1753\param <taille_des_chaines> vector containing the number of characters of data for each char* typed column, with order of appearance in 'fieldType'
1754*/
1755void FitsOutFile::makeHeaderBntblOnFits(string fieldType, vector<string> Noms, int nentries, int tfields, DVList* ptr_dvl, string extname, vector<int> taille_des_chaines)
1756{
1757 int k;
1758 int status = 0;
1759 long nrows;
1760 // verifications de coherences
1761
1762 if (fieldType.length() != tfields)
1763 {
1764 cout << " nombre de champs :" << tfields << "nombre de types: " << fieldType.length() << endl;
1765 throw ParmError("FitsFile:: fields and types don't match");
1766
1767 }
1768 if (tfields > Noms.size())
1769 {
1770 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of column names not equal to total number of columns" << endl;
1771 for (k=0; k<(tfields-Noms.size()); k++) Noms.push_back( string(" "));
1772 }
1773
1774 // nombre de variables "chaines de caracteres"
1775 int nbString = 0;
1776 for (k=0; k<tfields;k++) if (fieldType[k] == 'A') nbString++;
1777 // coherence de la longueur du vecteur des tailles
1778 if (nbString > taille_des_chaines.size())
1779 {
1780 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of string lengths not equal to total number of columns" << endl;
1781 int strSz=0;
1782 for (k=0; k<taille_des_chaines.size(); k++) if ( taille_des_chaines[k] > strSz) strSz = taille_des_chaines[k];
1783 for (k=0; k<(nbString-taille_des_chaines.size()); k++) taille_des_chaines.push_back(strSz);
1784 }
1785 char ** ttype= new char*[tfields];
1786 char ** tform= new char*[tfields];
1787 char largeur[FLEN_VALUE];
1788 int noColString=0;
1789 for (k=0; k<tfields;k++)
1790 {
1791 char format[FLEN_VALUE];
1792
1793 if(nentries < 1024)
1794 {
1795 nrows= nentries;
1796 if (fieldType[k] == 'A')
1797 {
1798 sprintf(largeur,"%d",taille_des_chaines[noColString++]);
1799 strcpy(format,largeur);
1800 }
1801 else strcpy(format,"1");
1802 }
1803 else
1804 {
1805 nrows = nentries/1024;
1806 if(nentries%1024 != 0) nrows++;
1807 if (fieldType[k] == 'A')
1808 {
1809 char largaux[FLEN_VALUE];
1810 sprintf(largeur,"%d",taille_des_chaines[noColString]);
1811 sprintf(largaux,"%d",1024*taille_des_chaines[noColString]);
1812 noColString++;
1813 strcpy(format, largaux);
1814 }
1815 else strcpy(format,"1024");
1816 }
1817 strncat(format,&fieldType[k],1);
1818 if (fieldType[k] == 'A')
1819 {
1820 strcat(format,largeur);
1821 }
1822 ttype[k] = const_cast<char*>(Noms[k].c_str());
1823 tform[k]= new char[FLEN_VALUE];
1824 strcpy(tform[k],format);
1825 }
1826 char* extn = const_cast<char*>(extname.c_str());
1827
1828 // create a new empty binary table onto the FITS file
1829 // physical units if they exist, are defined in the DVList object
1830 // so the NULL pointer is given for the tunit parameters.
1831 nrows=0;
1832 fits_create_tbl(fptr_,BINARY_TBL,nrows,tfields,ttype,tform,
1833 NULL,extn,&status);
1834 if( status ) printerror( status );
1835
1836 int ii;
1837 for(ii = 0; ii < tfields; ii++)
1838 {
1839 delete [] tform[ii];
1840 }
1841 delete [] ttype;
1842 delete [] tform;
1843
1844 // on ajoute eventuellement des mots-cles
1845
1846 if ( hdunum_ == 0 )
1847 {
1848 hdunum_ = 2;
1849 addDVListOnPrimary();
1850 writeSignatureOnFits(1);
1851 }
1852 else hdunum_++;
1853
1854 // header format FITS
1855
1856 writeAppendedHeaderOnFits();
1857
1858 // write SOPHYA keywords
1859 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
1860}
1861
1862
1863
1864/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
1865
1866write double data from array 'donnees ' on column number 'nocol' of a BINTABLE extension.
1867\param <nentries> number of data to be written
1868*/
1869
1870void FitsOutFile::PutColToFits(int nocol, int nentries, r_8* donnees) const
1871{
1872 int status = 0;
1873 int hdutype;
1874 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1875 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1876 fits_get_hdu_type(fptr_, &hdutype, &status);
1877 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1878 {
1879 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1880 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1881 }
1882 int code;
1883 long repeat, width;
1884 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1885 if( code != TDOUBLE)
1886 {
1887 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " to be written= DOUBLE " << endl;
1888 }
1889 // cout << " 10 elements de colonne " << endl;
1890 // for (int toto=0; toto < 10; toto++) cout << donnees[toto] << endl;
1891 fits_write_col(fptr_,TDOUBLE,nocol+1,1,1,nentries, donnees ,&status);
1892 if( status ) printerror( status,"erreur ecriture col. double, dans fichier fits" );
1893}
1894
1895
1896
1897 /*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
1898
1899same as previous method with float data
1900*/
1901void FitsOutFile::PutColToFits(int nocol, int nentries, r_4* donnees) const
1902{
1903 int status = 0;
1904 int hdutype;
1905 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1906 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1907 fits_get_hdu_type(fptr_, &hdutype, &status);
1908 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1909 {
1910 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1911 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1912 }
1913 if(hdutype == ASCII_TBL && nocol>0)
1914 {
1915 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1916 }
1917 int code;
1918 long repeat, width;
1919 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1920 if( code != TFLOAT)
1921 {
1922 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= FLOAT " << endl;
1923 }
1924 fits_write_col(fptr_,TFLOAT,nocol+1,1,1,nentries, donnees ,&status);
1925 if( status ) printerror( status,"erreur ecriture col. floats, dans fichier fits" );
1926}
1927
1928
1929/*! \fn void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
1930
1931same as previous method with int data
1932*/
1933void FitsOutFile::PutColToFits(int nocol, int nentries, int_4* donnees) const
1934{
1935 int status = 0;
1936 int hdutype;
1937 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1938 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1939 fits_get_hdu_type(fptr_, &hdutype, &status);
1940 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1941 {
1942 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1943 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1944 }
1945 if(hdutype == ASCII_TBL && nocol>0)
1946 {
1947 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1948 }
1949 int code;
1950 long repeat, width;
1951 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1952
1953
1954
1955 if (code == TINT || code == TLONG)
1956 {
1957 // cfitsio n'a que des entiers de longueur inferieure a 32 bits.
1958 // ici, a l'ecriture TLONG impliquerait que le tableau de donnees
1959 // soit un tableau int_8. Donc c'est toujours TINT qu;il faut mettre
1960 // De plus, j'ai l'impression que TINT va devenir obsolete dans cfitsio
1961 // (GLM)
1962 fits_write_col(fptr_,TINT,nocol+1,1,1,nentries, donnees ,&status);
1963 }
1964 else
1965 {
1966 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= integers " << endl;
1967 }
1968 if( status ) printerror( status,"erreur ecriture col. entiers, dans fichier fits" );
1969}
1970
1971
1972/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1973same as previous method with char* data
1974*/
1975void FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1976{
1977 int status = 0;
1978 int hdutype;
1979 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1980 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1981 fits_get_hdu_type(fptr_, &hdutype, &status);
1982 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1983 {
1984 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1985 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1986 }
1987 if(hdutype == ASCII_TBL && nocol>0)
1988 {
1989 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1990 }
1991 int code;
1992 long repeat, width;
1993 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1994 if( code != TSTRING)
1995 {
1996 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= char** " << endl;
1997 }
1998 fits_write_col(fptr_,TSTRING,nocol+1,1,1,nentries, donnees ,&status);
1999 if( status ) printerror( status,"erreur ecriture col. chars, dans fichier fits" );
2000}
2001
2002void FitsOutFile::PutBinTabLine(long NoLine, BnTblLine& ligne) const
2003{
2004 // on ne fait pas de verification de type, ni de dimension ici, pour
2005 // des raisons de performances
2006 int k;
2007 int status= 0;
2008 int anynul;
2009 int ncol=0;
2010 long nels=1;
2011 // int nbcols;
2012 // fits_get_num_cols(fptr_, &nbcols,&status);
2013 for (k=0; k<ligne.ddata_.size(); k++, ncol++)
2014 {
2015 fits_write_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1, &ligne.ddata_[k] ,&status);
2016 if( status ) printerror( status, "PutBinTabLine : erreur ecriture double" );
2017 }
2018 for (k=0; k<ligne.fdata_.size(); k++, ncol++)
2019 {
2020 fits_write_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1, &ligne.fdata_[k] ,&status);
2021 if( status ) printerror( status, "PutBinTabLine : erreur ecriture float" );
2022 }
2023 for (k=0; k<ligne.idata_.size(); k++, ncol++)
2024 {
2025 fits_write_col(fptr_,TINT,ncol+1,NoLine+1,1,1, &ligne.idata_[k] ,&status);
2026 if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier" );
2027 }
2028 for (k=0; k<ligne.ldata_.size(); k++, ncol++)
2029 {
2030 fits_write_col(fptr_,TLONG,ncol+1,NoLine+1,1,1, &ligne.ldata_[k] ,&status);
2031 if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier long" );
2032 }
2033 for (k=0; k<ligne.bdata_.size(); k++, ncol++)
2034 {
2035 fits_write_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1, &ligne.bdata_[k] ,&status);
2036 if( status ) printerror( status, "PutBinTabLine : erreur ecriture byte" );
2037 }
2038
2039 for (k=0; k<ligne.cdata_.size(); k++, ncol++)
2040 {
2041 fits_write_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1, (void*)ligne.cdata_[k].c_str() ,&status);
2042 if( status ) printerror( status, "PutBinTabLine : erreur ecriture caracteres" );
2043 }
2044}
2045
2046
2047/* \fn void SOPHYA::FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl) const
2048
2049Put keywords from a DVList into the primary header of the fits-file
2050*/
2051void FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl)
2052{
2053 int status = 0;
2054 int hdutype;
2055 if (hdunum_ == 0)
2056 {
2057 if (dvlToPrimary_ == NULL) dvlToPrimary_ = new DVList(dvl);
2058 else dvlToPrimary_->Merge(dvl);
2059 }
2060 else
2061 {
2062 fits_movabs_hdu(fptr_,1,&hdutype,&status);
2063 addKeywordsOfDVList(dvl);
2064 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
2065 }
2066}
2067
2068
2069void FitsOutFile::writeSignatureOnFits(int hdunum) const
2070{
2071 int status = 0;
2072 int hdutype;
2073 char keyname[LEN_KEYWORD];
2074 char strval[FLEN_VALUE];
2075 char comment[FLEN_COMMENT];
2076 if (hdunum_ == 0)
2077 {
2078 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
2079 return;
2080 }
2081 fits_movabs_hdu(fptr_,1,&hdutype,&status);
2082 //
2083 strncpy(keyname, "CREATOR", LEN_KEYWORD);
2084 keyname[7] = '\0';
2085 strcpy(strval, "SOPHYA");
2086 strcpy(comment," SOPHYA Package - FITSIOServer ");
2087 fits_write_key(fptr_, TSTRING, keyname, &strval, comment, &status);
2088 if( status ) printerror( status );
2089 fits_write_date(fptr_, &status);
2090 fits_write_comment(fptr_,"..............................................", &status);
2091 fits_write_comment(fptr_, " SOPHYA package - FITSIOSever ", &status);
2092 fits_write_comment(fptr_, " (C) LAL/IN2P3-CNRS Orsay, FRANCE 2000", &status);
2093 fits_write_comment(fptr_, " (C) DAPNIA/CEA Saclay, FRANCE 2000", &status);
2094 fits_write_comment(fptr_,"..............................................", &status);
2095 if( status ) printerror( status, "erreur writeSignatureOnFits" );
2096 //
2097 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
2098}
2099
2100
2101void FitsOutFile::addKeywordsOfDVList( DVList& dvl) const
2102{
2103 int status = 0;
2104 fits_write_comment(fptr_,"---------- keywords from SOPHYA ---------", &status);
2105 DVList::ValList::const_iterator it;
2106 for(it = dvl.Begin(); it != dvl.End(); it++)
2107 {
2108 MuTyV::MTVType keytype= (*it).second.elval.Type();
2109 char keyname[LEN_KEYWORD];
2110 strncpy(keyname,(*it).first.substr(0,64).c_str(),LEN_KEYWORD);
2111 int bout = ((*it).first.substr(0,64).length() < LEN_KEYWORD) ? (*it).first.substr(0,64).length() : LEN_KEYWORD-1;
2112 keyname[bout] = '\0';
2113 string key((*it).first.substr(0,64));
2114 // string key(keyname);
2115 char comment[FLEN_COMMENT];
2116 char strval[FLEN_VALUE]= "";
2117 char *comkey = "COMMENT";
2118 // fits_read_keyword(fptr_, keyname, strval, NULL, &status);
2119 // if (status != 0 || strncmp(keyname,comkey,LEN_KEYWORD-1) == 0 )
2120 {
2121 string coco = dvl.GetComment(key);
2122 coco.copy( comment, FLEN_COMMENT-1);
2123 int bout = (coco.length() < FLEN_COMMENT) ? coco.length() : FLEN_COMMENT-1;
2124 comment[bout]= '\0';
2125 status = 0;
2126 switch (keytype)
2127 {
2128 case MuTyV::MTVInteger :
2129 {
2130 int ival = (int)dvl.GetI(key);
2131 fits_write_key(fptr_,TINT,keyname,&ival, comment,&status);
2132 break;
2133 }
2134 case MuTyV::MTVFloat :
2135 {
2136 double dval= (double)dvl.GetD(key);
2137 fits_write_key(fptr_,TDOUBLE,keyname,&dval,comment,&status);
2138 break;
2139 }
2140 case MuTyV::MTVString :
2141 {
2142 char strvaleur[FLEN_VALUE]= "";
2143 string valChaine = dvl.GetS(key);
2144 valChaine.copy(strvaleur, FLEN_VALUE-1);
2145 int fin = (valChaine.length() < FLEN_VALUE) ? valChaine.length() : FLEN_VALUE-1;
2146 strvaleur[fin]= '\0';
2147
2148 fits_write_key(fptr_,TSTRING,keyname,&strvaleur,comment,&status);
2149 break;
2150 }
2151 }
2152 }
2153 if( status ) printerror( status,"fitsfile: probleme ecriture mot-cle du dvlist" );
2154 }
2155 fits_write_comment(fptr_,"--------------------------------------", &status);
2156}
2157
2158
2159void FitsOutFile::addDVListOnPrimary()
2160 {
2161 int status = 0;
2162 int hdutype;
2163 if (hdunum_ == 0)
2164 {
2165 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
2166 return;
2167 }
2168 if (dvlToPrimary_ != NULL)
2169 {
2170 fits_movabs_hdu(fptr_,1,&hdutype,&status);
2171 addKeywordsOfDVList(*dvlToPrimary_);
2172 delete dvlToPrimary_;
2173 dvlToPrimary_ = NULL;
2174 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
2175 }
2176 }
2177
2178
2179/*! \fn void FitsOutFile::appendInHeader(FitsInFile& infits, int hdunum)
2180
2181get a header from FitsInFile and append to the header beeing built
2182(shifting mandatory keywords)
2183*/
2184
2185void FitsOutFile::appendInputHeader(FitsInFile& infits, int hdunum)
2186{
2187
2188 infits.GetKeywordsFromHeader(hdunum, mots_cles_);
2189 /*
2190 int status = 0;
2191 int hdutype;
2192 fitsfile* fptr=infits.fitsfilePtr();
2193 fits_movabs_hdu(fptr,hdunum,&hdutype,&status);
2194 if( status ) fits_report_error(stderr,status);
2195
2196 // get number of keywords
2197 int nkeys,keypos;
2198 fits_get_hdrpos(fptr,&nkeys,&keypos,&status);
2199 if( status ) fits_report_error(stderr,status);
2200 // shift with the number of mandatory keywords
2201 int num= 0;
2202 // if primary header
2203 if (hdunum == 1)
2204 {
2205 // read NAXIS
2206 int naxis=0;
2207 fits_read_key(fptr,TINT,"NAXIS",&naxis,NULL,&status);
2208 // number of mandatory keywords
2209 num = naxis+3;
2210 }
2211 // extensions
2212 else
2213 {
2214 if (hdutype == IMAGE_HDU)
2215 {
2216 // read NAXIS
2217 int naxis=0;
2218 fits_read_key(fptr,TINT,"NAXIS",&naxis,NULL,&status);
2219 // number of mandatory keywords
2220 num = naxis+5;
2221 }
2222 else
2223 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
2224 {
2225 // number of mandatory keywords
2226 num = 8;
2227 }
2228 }
2229 int j;
2230 char keyname[LEN_KEYWORD];
2231 char value[FLEN_VALUE];
2232 char comment[FLEN_COMMENT];
2233 for(j = num+1; j <= nkeys; j++)
2234 {
2235 char dtype;
2236 fits_read_keyn(fptr,j,keyname,value,comment,&status);
2237 if(status)
2238 {
2239 fits_report_error(stderr,status);
2240 status=0;
2241 }
2242 string kn(keyname);
2243 string cm(comment);
2244 string val(value);
2245 FitsKeyword kw(kn, val, cm);
2246 mots_cles_.push_back(kw);
2247 }
2248 */
2249}
2250void FitsOutFile::writeAppendedHeaderOnFits()
2251{
2252 for (list<FitsKeyword>::iterator it=mots_cles_.begin(); it !=mots_cles_.end(); it++)
2253 {
2254 (*it).writeOnFits(fptr_);
2255 }
2256 mots_cles_.clear();
2257}
2258
2259void FitsOutFile::insertKeywordOnHeader(string keyname, double value, string comment)
2260{
2261 char cvalue[16];
2262 sprintf(cvalue,"%e",value);
2263 FitsKeyword kw(keyname, string(cvalue), comment, 'F');
2264 mots_cles_.push_back(kw);
2265}
2266void FitsOutFile::insertKeywordOnHeader(string keyname, int value, string comment)
2267{
2268 char cvalue[16];
2269 sprintf(cvalue,"%d",value);
2270 FitsKeyword kw(keyname, string(cvalue), comment, 'I');
2271 mots_cles_.push_back(kw);
2272}
2273void FitsOutFile::insertKeywordOnHeader(string keyname, string value, string comment)
2274{
2275 FitsKeyword kw(keyname, value , comment, 'C');
2276 mots_cles_.push_back(kw);
2277}
2278
2279void FitsOutFile::insertCommentLineOnHeader(string comment)
2280{
2281 FitsKeyword kw(comment);
2282 mots_cles_.push_back(kw);
2283}
2284
2285void FitsOutFile::PrintHeaderToBeAppended()
2286{
2287 cout << " contenu du header en cours de fabrication " << endl;
2288 for (list<FitsKeyword>::iterator it=mots_cles_.begin(); it !=mots_cles_.end(); it++)
2289 {
2290 (*it).Print();
2291 }
2292}
2293
2294
2295FitsKeyword::FitsKeyword()
2296 {
2297 datatype_=' ';
2298 keyname_ = string("");
2299 dvalue_=0.;
2300 ivalue_=1;
2301 svalue_=string("");
2302 comment_=string("");
2303 }
2304
2305FitsKeyword::FitsKeyword(string comment)
2306 {
2307 datatype_=' ';
2308 keyname_=string("COMMENT");
2309 comment_=comment;
2310 }
2311
2312FitsKeyword::FitsKeyword(string keyname, string value, string comment) : keyname_(keyname), comment_(comment)
2313 {
2314 int status=0;
2315 char dtype;
2316 const char* val= value.c_str();
2317 char* valk = const_cast<char*>(val);
2318 fits_get_keytype(valk,&dtype,&status);
2319 if(status)
2320 {
2321 status=0;
2322 if (status == VALUE_UNDEFINED) cout << "WARNING (FitsKeyword) : undefined keyword value " << endl;
2323 datatype_=' ';
2324 }
2325 else datatype_=dtype;
2326
2327 switch( datatype_ )
2328 {
2329 case 'C':
2330 {
2331 strip(valk, 'B','\'');
2332 svalue_ = string(valk);
2333 break;
2334 }
2335 case 'I':
2336 {
2337 ivalue_ = atoi(val);
2338 break;
2339 }
2340 case 'L':
2341 {
2342 bool bb = value.c_str();
2343 ivalue_ = (int)bb;
2344 break;
2345 }
2346 case 'F':
2347 {
2348 dvalue_ = atof(val);
2349 break;
2350 }
2351 case 'X':
2352 {
2353 throw IOExc("FitsKeyword , complex keyword value not supported");
2354 }
2355 }
2356 }
2357
2358// constructeur pour les mots-cles maison (ne prvenant pas de la lecture d'un fichier fits)
2359FitsKeyword::FitsKeyword(string keyname, string value, string comment, char type) : keyname_(keyname), comment_(comment), datatype_(type)
2360 {
2361 char dtype;
2362 const char* val= value.c_str();
2363 char* valk = const_cast<char*>(val);
2364 switch( datatype_ )
2365 {
2366 case 'C':
2367 {
2368 strip(valk, 'B','\'');
2369 svalue_ = string(valk);
2370 break;
2371 }
2372 case 'I':
2373 {
2374 ivalue_ = atoi(val);
2375 break;
2376 }
2377 case 'L':
2378 {
2379 bool bb = value.c_str();
2380 ivalue_ = (int)bb;
2381 break;
2382 }
2383 case 'F':
2384 {
2385 dvalue_ = atof(val);
2386 break;
2387 }
2388 case 'X':
2389 {
2390 throw IOExc("FitsKeyword , complex keyword value not supported");
2391 }
2392 }
2393 }
2394
2395void FitsKeyword::writeOnFits(fitsfile* ptr)
2396 {
2397 int status=0;
2398 char keyname[LEN_KEYWORD];
2399 char comment[FLEN_COMMENT];
2400 keyname_.copy(keyname, LEN_KEYWORD);
2401 int bout = (keyname_.length() < LEN_KEYWORD) ? keyname_.length() : LEN_KEYWORD-1;
2402 keyname[bout] = '\0';
2403 comment_.copy( comment, FLEN_COMMENT);
2404 bout = (comment_.length() < FLEN_COMMENT) ? comment_.length() : FLEN_COMMENT-1;
2405 comment[bout]= '\0';
2406
2407 int nkeys,keypos;
2408 fits_get_hdrpos(ptr,&nkeys,&keypos,&status);
2409 switch( datatype_ )
2410 {
2411 case 'C':
2412 {
2413 char value[FLEN_VALUE]="";
2414 svalue_.copy(value, FLEN_VALUE-1);
2415 int fin = (svalue_.length() < FLEN_VALUE) ? svalue_.length() : FLEN_VALUE-1;
2416 value[fin]= '\0';
2417 fits_write_key(ptr,TSTRING,keyname,&value, comment,&status);
2418 fits_report_error(stderr,status);
2419 break;
2420 }
2421 case 'I':
2422 {
2423 fits_write_key(ptr,TINT,keyname,&ivalue_, comment,&status);
2424 fits_report_error(stderr,status);
2425 break;
2426 }
2427 case 'L':
2428 {
2429 fits_write_key(ptr,TLOGICAL,keyname,&ivalue_, comment,&status);
2430 fits_report_error(stderr,status);
2431 break;
2432 }
2433 case 'F':
2434 {
2435 fits_write_key(ptr,TDOUBLE,keyname,&dvalue_, comment,&status);
2436 fits_report_error(stderr,status);
2437 break;
2438 }
2439 case 'X':
2440 {
2441 cout << "FitsKeyword : complex keyword value not supported" << endl;;
2442 break;
2443 }
2444 default :
2445 {
2446 char *comkey = "COMMENT";
2447 if(strncmp(keyname,comkey,LEN_KEYWORD-1) == 0)
2448 {
2449 fits_write_comment(ptr,comment,&status);
2450 fits_report_error(stderr,status);
2451 }
2452 else
2453 {
2454 cout << " WARNING (FitsKeyword::writeOnFits) : unrecognized keyword : " << keyname_ << endl;
2455 }
2456 }
2457 }
2458 }
2459
2460void FitsKeyword::Print()
2461 {
2462 switch( datatype_ )
2463 {
2464 case 'C':
2465 {
2466 cout << " mot cle : " << keyname_ << " valeur : " << svalue_ << " commentaire : " << comment_ <<endl;
2467 break;
2468 }
2469 case 'I':
2470 {
2471 cout << " mot cle : " << keyname_ << " valeur : " << ivalue_ << " commentaire : " << comment_ <<endl;
2472 break;
2473 }
2474 case 'L':
2475 {
2476 cout << " mot cle : " << keyname_ << " valeur : " << ivalue_ << " commentaire : " << comment_ <<endl;
2477 break;
2478 }
2479 case 'F':
2480 {
2481 cout << " mot cle : " << keyname_ << " valeur : " << dvalue_ << " commentaire : " << comment_ <<endl;
2482 break;
2483 }
2484 case 'X':
2485 {
2486 cout << "FitsKeyword : complex keyword value not supported" << endl;;
2487 }
2488 default :
2489 {
2490 cout << " mot cle : " << keyname_ << " commentaire : " << comment_ <<endl;
2491 }
2492 }
2493 }
Note: See TracBrowser for help on using the repository browser.