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

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

correction longueurs de tableaux d'entiers das GetBinTabLine

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