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

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

mise aux normes de for(int k= ...)

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 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 ccount =0;
1041 int ncol;
1042 long nels=1;
1043 for (ncol=0; ncol<nbcols_; ncol++)
1044 {
1045 switch (types_[ncol])
1046 {
1047 case FitsDataType_double :
1048 {
1049 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ligne.ddata_[dcount++],&anynul,&status);
1050 break;
1051 }
1052 case FitsDataType_float :
1053 {
1054 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&ligne.fdata_[fcount++],&anynul,&status);
1055 break;
1056 }
1057 case FitsDataType_int :
1058 {
1059 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ligne.idata_[icount++], &anynul,&status);
1060 break;
1061 }
1062 case FitsDataType_long :
1063 {
1064 fits_read_col(fptr_,TLONG,ncol+1,NoLine+1,1,1,&inull,&ligne.ldata_[icount++], &anynul,&status);
1065 break;
1066 }
1067 case FitsDataType_byte :
1068 {
1069 fits_read_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1,&inull,&ligne.bdata_[icount++], &anynul,&status);
1070 break;
1071 }
1072 case FitsDataType_char :
1073 {
1074 char* chaine = new char[taille_des_chaines_[ccount]];
1075 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anynul,&status);
1076 ligne.cdata_[ccount++] = string(chaine);
1077 break;
1078 }
1079 default:
1080 {
1081 throw PException(" FitsInFile::GetBinTabLine : unsupported FITS data type");
1082 }
1083 }
1084 if (status)
1085 {
1086 ResetStatus(status);
1087 break;
1088 }
1089 }
1090}
1091
1092
1093
1094/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, float* fdata)
1095
1096Get the NoLine-th float 'line' from the current BINTABLE extension on FITS file,
1097*/
1098void FitsInFile::GetBinTabLine(int NoLine, float* fdata)
1099{
1100 int status= 0;
1101 int anynul;
1102 float fnull= fnull_;
1103 long nels=1;
1104 int ncol;
1105 for (ncol=0; ncol<nbcols_; ncol++)
1106 {
1107 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[ncol],&anynul,&status);
1108 if (status)
1109 {
1110 ResetStatus(status);
1111 break;
1112 }
1113 }
1114}
1115
1116
1117/*! \fn void SPOPHYA::FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
1118
1119fill the array 'valeurs' with double data from the current BINTABLE extension on FITS file, from column number 'NoCol'
1120
1121\param <nentries> number of data to be read
1122*/
1123void FitsInFile::GetBinTabFCol(r_8* valeurs,int nentries, int NoCol) const
1124 {
1125 int status= 0;
1126 int DTYPE;
1127 long repeat,width;
1128 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1129 if( DTYPE != TDOUBLE)
1130 {
1131 if (DTYPE == TFLOAT) cout << " WARNING: reading double from float : conversion will be made by fitsio library" << endl;
1132 else
1133 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non double");
1134 }
1135 long nels=nentries;
1136 int anynul;
1137 double dnull= dnull_;
1138
1139 fits_read_col(fptr_,TDOUBLE,NoCol+1,1,1,nels,&dnull,valeurs,
1140 &anynul,&status);
1141 if( status )
1142 {
1143 printerrorAndContinue( status,"erreur lecture de colonne" );
1144 }
1145 }
1146
1147/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
1148
1149 same as previous method with float data
1150*/
1151void FitsInFile::GetBinTabFCol(r_4* valeurs,int nentries, int NoCol) const
1152 {
1153 int status= 0;
1154 int DTYPE;
1155 long repeat,width;
1156 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1157 if( DTYPE != TFLOAT)
1158 {
1159 if (DTYPE == TDOUBLE) cout << " WARNING: reading float from double : conversion will be made by fitsio library" << endl;
1160 else
1161 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non float");
1162 }
1163 long nels=nentries;
1164 int anynul;
1165 float fnull= fnull_;
1166 fits_read_col(fptr_,TFLOAT,NoCol+1,1,1,nels,&fnull,valeurs,
1167 &anynul,&status);
1168 if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
1169 }
1170
1171/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
1172
1173 same as previous method with int data
1174*/
1175
1176void FitsInFile::GetBinTabFCol(int_4* valeurs,int nentries, int NoCol) const
1177 {
1178 int status= 0;
1179 int DTYPE;
1180 long repeat,width;
1181 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1182 if( DTYPE != TLONG && DTYPE != TINT)
1183 {
1184 throw IOExc("FitsFile::GetBinTabFCol, probleme de lecture d'entiers");
1185 }
1186 long nels=nentries;
1187 int anynul;
1188 int inull= inull_;
1189
1190
1191
1192 // voir commentaire dans putColToFits()
1193 fits_read_col(fptr_,TINT,NoCol+1,1,1,nels,&inull,valeurs,
1194 &anynul,&status);
1195 if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
1196 }
1197
1198/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
1199
1200 same as previous method with char* data
1201*/
1202
1203void FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
1204 {
1205 int status= 0;
1206 int DTYPE;
1207 long repeat,width;
1208 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
1209 if( DTYPE != TSTRING && DTYPE != TBYTE)
1210 {
1211 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non string");
1212 }
1213 long nels=nentries;
1214 int anynul;
1215 char* cnull= const_cast<char*>(cnull_.c_str());
1216 long frow=1;
1217 long felem=1;
1218 fits_read_col(fptr_,TSTRING,NoCol+1,frow,felem,nels,cnull,valeurs,
1219 &anynul,&status);
1220 if( status ) printerrorAndContinue( status,"erreur lecture de colonne" );
1221 }
1222
1223/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(double* map, int nentries) const
1224fill the array 'map' with double data from the current extension on FITS file.
1225If the extension is BINTABLE, the first column is provided.
1226
1227\param <nentries> number of data to be read
1228*/
1229void FitsInFile::GetSingleColumn(r_8* map, int nentries) const
1230{
1231 int status = 0;
1232 if(hdutype_ == FitsExtensionType_IMAGE)
1233 {
1234
1235 if(imageDataType_ != FitsDataType_double)
1236 {
1237 cout << " The data type on fits file is not double...";
1238 cout << " Conversion to double achieved by cfitsio lib" << endl;
1239 }
1240
1241 int anynul;
1242 double dnull= dnull_;
1243
1244 long nels= nentries;
1245 fits_read_img(fptr_,TDOUBLE,1,nels,&dnull,map,&anynul,&status);
1246 if( status ) printerror( status );
1247 }
1248 else
1249 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
1250 {
1251 GetBinTabFCol(map,nentries, 0);
1252 }
1253 else
1254 {
1255 cout << " hdutype= " << (int) hdutype_ << endl;
1256 throw IOExc("FitsFile::GetSingleColumn, this HDU is unknown");
1257 }
1258}
1259
1260/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(float* map, int nentries) const
1261same as above with float data
1262*/
1263void FitsInFile::GetSingleColumn(r_4* map, int nentries) const
1264{
1265 int status = 0;
1266 if(hdutype_ == FitsExtensionType_IMAGE)
1267 {
1268 if(imageDataType_ != FitsDataType_float)
1269 {
1270 cout << " The data type on fits file is not float ";
1271 cout << " Conversion to float achieved by cfitsio lib" << endl;
1272 }
1273 int anynul;
1274 float fnull= fnull_;
1275
1276 long nels= nentries;
1277 fits_read_img(fptr_,TFLOAT,1,nels,&fnull, map,&anynul,&status);
1278 if( status ) printerror( status );
1279 }
1280 else
1281 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
1282 {
1283 GetBinTabFCol(map,nentries, 0);
1284 }
1285 else
1286 {
1287 cout << " hdutype= " << (int) hdutype_ << endl;
1288 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
1289 }
1290}
1291
1292/*! \fn void SOPHYA::FitsInFile::GetSingleColumn( int* map, int nentries) const
1293 same as above with int data
1294*/
1295void FitsInFile::GetSingleColumn( int_4* map, int nentries) const
1296{
1297 int status = 0;
1298 if(hdutype_ == FitsExtensionType_IMAGE)
1299 {
1300 if(imageDataType_ != FitsDataType_int)
1301 {
1302 cout << " The data type on fits file is not int ";
1303 cout << " Conversion to float achieved by cfitsio lib" << endl;
1304 }
1305 int anynul;
1306 float fnull= fnull_;
1307
1308 long nels= nentries;
1309 fits_read_img(fptr_,TINT,1,nels,&fnull,map,&anynul,&status);
1310 if( status ) printerror( status );
1311 }
1312 else
1313 if(hdutype_ == FitsExtensionType_ASCII_TBL || hdutype_ == FitsExtensionType_BINARY_TBL)
1314 {
1315 GetBinTabFCol(map,nentries, 0);
1316 }
1317 else
1318 {
1319 cout << " hdutype= " << (int) hdutype_ << endl;
1320 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
1321 }
1322}
1323
1324void FitsInFile::GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows,
1325 vector<int>& repeat,
1326 vector<string>& noms,
1327 vector<FitsDataType>& types,
1328 vector<int>& taille_des_chaines)
1329{
1330 int status= 0;
1331 int hdunum=0;
1332 int hdutype=0;
1333 fits_get_hdu_num(fileptr,&hdunum);
1334 fits_get_hdu_type(fileptr, &hdutype, &status);
1335
1336 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1337 {
1338 throw IOExc("FitsFile::GetBinTabParameters this HDU is not an ASCII table nor a binary table");
1339 }
1340 // if(hdutype == ASCII_TBL)
1341 // cout << " Reading a FITS ascii table in HDU : " << hdunum << endl;
1342 // if(hdutype == BINARY_TBL)
1343 // cout << " Reading a FITS binary table in HDU : " << hdunum << endl;
1344
1345 // get the number of columns
1346 fits_get_num_cols(fileptr, &nbcols,&status);
1347 if( status ) printerror( status );
1348
1349 // get the number of rows
1350 long naxis2= 0;
1351 fits_get_num_rows(fileptr,&naxis2,&status);
1352 if( status ) printerror( status );
1353 nrows = (int)naxis2;
1354
1355 // get the datatype, names and the repeat count
1356 noms.clear();
1357 noms.reserve(nbcols);
1358 types.clear();
1359 types.reserve(nbcols);
1360 repeat.clear();
1361 repeat.reserve(nbcols);
1362 taille_des_chaines.clear();
1363 char **ttype = new char*[nbcols];
1364 int ii;
1365 //
1366 //
1367 for (ii=0; ii < nbcols; ii++) ttype[ii]=new char[FLEN_VALUE];
1368 int nfound;
1369 fits_read_keys_str(fileptr, "TTYPE",1,nbcols,ttype,&nfound, &status);
1370 if( status ) printerror( status,"erreur lecture des noms de colonne");
1371 int rept=0;
1372 if(hdutype == ASCII_TBL)
1373 {
1374 for(ii = 0; ii < nbcols; ii++)
1375 {
1376 int DTYPE;
1377 long width;
1378 long repete = 0;
1379 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
1380 if( status ) printerror( status,"erreur lecture type de colonne");
1381 rept = repete;
1382 noms.push_back(string(ttype[ii]));
1383 switch (DTYPE)
1384 {
1385 case TDOUBLE :
1386 types.push_back(FitsDataType_double);
1387 break;
1388 case TFLOAT :
1389 types.push_back(FitsDataType_float);
1390 break;
1391 case TLONG :
1392 types.push_back(FitsDataType_long);
1393 break;
1394 case TINT :
1395 types.push_back(FitsDataType_int);
1396 break;
1397 case TSHORT :
1398 types.push_back(FitsDataType_short);
1399 break;
1400 case TSTRING :
1401 types.push_back(FitsDataType_char);
1402 taille_des_chaines.push_back(width);
1403 rept/=width;
1404 break;
1405 default :
1406 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
1407 throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for ASCII table");
1408 }
1409 repeat.push_back(rept);
1410 }
1411 }
1412 else
1413 {
1414 for(ii = 0; ii < nbcols; ii++)
1415 {
1416 int DTYPE;
1417 long width;
1418 long repete = 0;
1419 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
1420 if( status ) printerror( status,"erreur lecture type de colonne");
1421 rept = repete;
1422 noms.push_back(string(ttype[ii]));
1423 switch (DTYPE)
1424 {
1425 case TDOUBLE :
1426 types.push_back(FitsDataType_double);
1427 break;
1428 case TFLOAT :
1429 types.push_back(FitsDataType_float);
1430 break;
1431 case TLONG :
1432 types.push_back(FitsDataType_long);
1433 break;
1434 case TINT :
1435 types.push_back(FitsDataType_int);
1436 break;
1437 case TSHORT :
1438 types.push_back(FitsDataType_short);
1439 break;
1440 case TSTRING :
1441 types.push_back(FitsDataType_char);
1442 taille_des_chaines.push_back(width);
1443 rept/=width;
1444 break;
1445 case TBYTE :
1446 types.push_back(FitsDataType_byte);
1447 break;
1448 default :
1449 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
1450 throw IOExc("FitsFile::GetBinTabParameters, unsupported data type of field, for BINTABLE");
1451 }
1452 repeat.push_back(rept);
1453 }
1454 }
1455 for (ii=0; ii < nbcols; ii++) delete [] ttype[ii];
1456 delete [] ttype;
1457}
1458
1459void FitsInFile::KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum)
1460{
1461 int status = 0;
1462 int hdutype;
1463 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
1464 if( status ) printerror( status,":KeywordsIntoDVList : erreur movabs");
1465 // get number of keywords
1466 int nkeys,keypos;
1467 fits_get_hdrpos(fileptr,&nkeys,&keypos,&status);
1468 if( status ) printerror( status );
1469
1470 // put keywords in a DVList object
1471 char keyname[LEN_KEYWORD]= "";
1472 char strval[FLEN_VALUE]= "";
1473 char dtype;
1474 char card[FLEN_CARD];
1475 char *comkey = "COMMENT";
1476 char comment[FLEN_COMMENT];
1477
1478 // shift with the number of mandatory keywords
1479 // int num= 8;
1480 int num= 0;
1481 // primary header
1482 if (hdunum == 1)
1483 {
1484 // read NAXIS
1485 int naxis=0;
1486 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1487 // number of mandatory keywords
1488 num = naxis+3;
1489 }
1490 // extensions
1491 else
1492 {
1493 if (hdutype == IMAGE_HDU)
1494 {
1495 // read NAXIS
1496 int naxis=0;
1497 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1498 // number of mandatory keywords
1499 num = naxis+5;
1500 }
1501 else
1502 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
1503 {
1504 // number of mandatory keywords
1505 num = 8;
1506 }
1507 }
1508 int j;
1509 for(j = num+1; j <= nkeys; j++)
1510 {
1511 fits_read_keyn(fileptr,j,card,strval,NULL,&status);
1512 if(status) printerror(status);
1513
1514 strncpy(keyname,card,LEN_KEYWORD-1);
1515 if(strncmp(keyname,comkey,LEN_KEYWORD-1) != 0 && strlen(keyname) != 0
1516 && strlen(strval) != 0)
1517 {
1518 fits_get_keytype(strval,&dtype,&status);
1519 if(status) printerror(status);
1520
1521 strip(keyname, 'B',' ');
1522 strip(strval, 'B',' ');
1523 strip(strval, 'B','\'');
1524
1525 switch( dtype )
1526 {
1527 case 'C':
1528 fits_read_key(fileptr,TSTRING,keyname,strval,comment,&status);
1529 if ( strncmp(keyname,"TTYPE",5) == 0 ||
1530 strncmp(keyname,"TFORM",5) == 0 ||
1531 strncmp(keyname,"TBCOL",5) == 0 ) break;
1532 dvl[keyname]= strval;
1533 dvl.SetComment(keyname, comment);
1534 break;
1535 case 'I':
1536 int ival;
1537 fits_read_key(fileptr,TINT,keyname,&ival,comment,&status);
1538 dvl[keyname]= (int_4) ival; // Portage mac DY
1539 dvl.SetComment(keyname, comment);
1540 break;
1541 case 'L':
1542 int ilog;
1543 fits_read_key(fileptr,TLOGICAL,keyname,&ilog,comment,&status);
1544 dvl[keyname]= (int_4) ilog;
1545 dvl.SetComment(keyname, comment);
1546 break;
1547 case 'F':
1548 double dval;
1549 fits_read_key(fileptr,TDOUBLE,keyname,&dval,comment,&status);
1550 dvl[keyname]= dval;
1551 dvl.SetComment(keyname, comment);
1552 break;
1553 }
1554
1555 }
1556 }
1557 // dvl.Print();
1558}
1559
1560
1561/*!
1562 \class SOPHYA::FitsOutFile
1563 \ingroup FitsIOServer
1564 Class for loading SOPHYA objects from FITS Format Files (uses cfitsio lib)
1565*/
1566
1567FitsOutFile::FitsOutFile()
1568{
1569 InitNull();
1570}
1571
1572 /*! \fn SOPHYA::FitsOutFile::FitsOutFile(char flnm[], WriteMode wrm)
1573
1574\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)
1575
1576 */
1577
1578FitsOutFile::FitsOutFile(string const & flnm, WriteMode wrm)
1579{
1580 InitNull();
1581 openoutputfitsfile(flnm.c_str(), wrm);
1582}
1583
1584FitsOutFile::FitsOutFile(const char * flnm, WriteMode wrm)
1585{
1586 InitNull();
1587 openoutputfitsfile(flnm, wrm);
1588}
1589
1590void FitsOutFile::openoutputfitsfile(const char * flnm, WriteMode wrm)
1591{
1592 int status = 0;
1593
1594 // create new FITS file
1595 fits_create_file(&fptr_,flnm,&status);
1596 if( status )
1597 {
1598
1599 switch (wrm)
1600 {
1601 // si on veut ecrire a la fin de ce fichier
1602 case append :
1603 status = 0;
1604 fits_clear_errmsg();
1605 fits_open_file(&fptr_,flnm,READWRITE,&status);
1606 if( status )
1607 {
1608 cout << " error opening file: " << flnm << endl;
1609 printerror(status, "failure opening a file supposed to exist");
1610 }
1611 else cout << " file " << flnm << " opened, new objects will be appended " << endl;
1612 fits_get_num_hdus(fptr_, &hdunum_, &status);
1613 int hdutype;
1614 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1615 if( status ) printerror( status,":FitsFile::WriteF : erreur movabs");
1616 break;
1617
1618 case clear :
1619 {
1620 status = 0;
1621 fits_clear_errmsg();
1622 char* newname = new char[strlen(flnm)+2];
1623 //
1624 newname[0] = '!';
1625 newname[1] = '\0';
1626 strcat(newname, flnm);
1627 fits_create_file(&fptr_,newname,&status);
1628 delete [] newname;
1629 if (status)
1630 {
1631 cout << " error opening file: " << flnm << endl;
1632 printerror(status, "unable to open file, supposed to exist");
1633 }
1634 else cout << " WARNING : file " << flnm << " is overwritten " << endl;
1635 break;
1636 }
1637 case unknown :
1638 printerror(status, " file seems already to exist");
1639 break;
1640
1641 }
1642 }
1643}
1644
1645
1646
1647/*! \fn void SOPHYA::FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList &dvl)
1648
1649create an IMAGE header on FITS file.
1650\param <type> type of data (see method ColTypeFromFits)
1651\param <nbdim> number of dimensions : 1D, 2D, 3D etc. = NAXIS
1652\param <naxisn> array containind sizes of the different dimensions
1653*/
1654void FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList* ptr_dvl)
1655{
1656 int status = 0;
1657 long naxis = nbdim;
1658 long* naxes = new long[nbdim];
1659 bool hdunfirst= (hdunum_ == 0);
1660 if (hdunfirst)
1661 {
1662 if (imageOnPrimary_ == false)
1663 {
1664 hdunum_ = 1;
1665 fits_create_img(fptr_,FLOAT_IMG,0,naxes,&status);
1666 }
1667 }
1668 int k;
1669 for (k=0; k< nbdim; k++) naxes[k] = (long)naxisn[k];
1670 if (type == 'D')
1671 fits_create_img(fptr_,DOUBLE_IMG,naxis,naxes,&status);
1672 else
1673 if (type == 'E')
1674 fits_create_img(fptr_,FLOAT_IMG,naxis,naxes,&status);
1675 else
1676 if (type == 'I')
1677 fits_create_img(fptr_,LONG_IMG,naxis,naxes,&status);
1678 else
1679 {
1680 cout << " type of data: " << type << endl;
1681 throw PException("FitsFile:::makeHeaderImageOnFits:unprogrammed type of data ");
1682 }
1683
1684 // on ajoute eventuellement un dvlist prepare et la doc SOPHYA
1685 hdunum_++;
1686 if (hdunfirst)
1687 {
1688 addDVListOnPrimary();
1689 writeSignatureOnFits(1);
1690 }
1691
1692 // header format FITS
1693
1694 writeAppendedHeaderOnFits();
1695
1696 // write supplementary keywords (from SOPHYA)
1697 // dvl.Print();
1698 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
1699
1700 delete [] naxes;
1701 if( status ) printerror( status, "erreur creation HDU IMAGE" );
1702
1703}
1704
1705
1706/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, double* map) const
1707
1708write double data from array 'map'on an IMAGE extension
1709\param <nbData> number of data to be written
1710*/
1711void FitsOutFile::PutImageToFits(int nbData, r_8* map) const
1712{
1713 int status = 0;
1714 long npix= nbData;
1715 fits_write_img(fptr_,TDOUBLE,1,npix,map,&status);
1716 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1717}
1718
1719/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, float* map) const
1720
1721same as previous method with float data
1722*/
1723void FitsOutFile::PutImageToFits(int nbData, r_4* map) const
1724{
1725 int status = 0;
1726 long npix= nbData;
1727 fits_write_img(fptr_,TFLOAT,1,npix, map,&status);
1728 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1729
1730}
1731
1732 /*! \fn void SOPHYA::FitsOutFile::PutImageToFits( int nbData, int* map) const
1733
1734 same as previous method with int data */
1735void FitsOutFile::PutImageToFits( int nbData, int_4* map) const
1736{
1737 int status = 0;
1738
1739 long npix= nbData;
1740 fits_write_img(fptr_,TINT,1,npix,map,&status);
1741 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1742}
1743
1744
1745
1746/*! \fn void SOPHYA::FitsOutFile::makeHeaderBntblOnFits( string fieldType, vector<string> Noms, int nentries, int tfields, DVList &dvl, string extname, vector<int> taille_des_chaines)
1747
1748create an BINTABLE header on FITS file.
1749\param <fieldType> array conta
1750ining characters denoting types of the different column (see method ColTypeFromFits)
1751\param <Noms> array of the names of columns
1752\param <nentries> number of data of each column
1753\param <tfields> number of columns
1754\param <dvl> a SOPHYA DVList containing keywords to be appended
1755\param <extname> keyword EXTNAME for FITS file
1756\param <taille_des_chaines> vector containing the number of characters of data for each char* typed column, with order of appearance in 'fieldType'
1757*/
1758void FitsOutFile::makeHeaderBntblOnFits(string fieldType, vector<string> Noms, int nentries, int tfields, DVList* ptr_dvl, string extname, vector<int> taille_des_chaines)
1759{
1760 int k;
1761 int status = 0;
1762 long nrows;
1763 // verifications de coherences
1764
1765 if (fieldType.length() != tfields)
1766 {
1767 cout << " nombre de champs :" << tfields << "nombre de types: " << fieldType.length() << endl;
1768 throw ParmError("FitsFile:: fields and types don't match");
1769
1770 }
1771 if (tfields > Noms.size())
1772 {
1773 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of column names not equal to total number of columns" << endl;
1774 for (k=0; k<(tfields-Noms.size()); k++) Noms.push_back( string(" "));
1775 }
1776
1777 // nombre de variables "chaines de caracteres"
1778 int nbString = 0;
1779 for (k=0; k<tfields;k++) if (fieldType[k] == 'A') nbString++;
1780 // coherence de la longueur du vecteur des tailles
1781 if (nbString > taille_des_chaines.size())
1782 {
1783 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of string lengths not equal to total number of columns" << endl;
1784 int strSz=0;
1785 for (k=0; k<taille_des_chaines.size(); k++) if ( taille_des_chaines[k] > strSz) strSz = taille_des_chaines[k];
1786 for (k=0; k<(nbString-taille_des_chaines.size()); k++) taille_des_chaines.push_back(strSz);
1787 }
1788 char ** ttype= new char*[tfields];
1789 char ** tform= new char*[tfields];
1790 char largeur[FLEN_VALUE];
1791 int noColString=0;
1792 for (k=0; k<tfields;k++)
1793 {
1794 char format[FLEN_VALUE];
1795
1796 if(nentries < 1024)
1797 {
1798 nrows= nentries;
1799 if (fieldType[k] == 'A')
1800 {
1801 sprintf(largeur,"%d",taille_des_chaines[noColString++]);
1802 strcpy(format,largeur);
1803 }
1804 else strcpy(format,"1");
1805 }
1806 else
1807 {
1808 nrows = nentries/1024;
1809 if(nentries%1024 != 0) nrows++;
1810 if (fieldType[k] == 'A')
1811 {
1812 char largaux[FLEN_VALUE];
1813 sprintf(largeur,"%d",taille_des_chaines[noColString]);
1814 sprintf(largaux,"%d",1024*taille_des_chaines[noColString]);
1815 noColString++;
1816 strcpy(format, largaux);
1817 }
1818 else strcpy(format,"1024");
1819 }
1820 strncat(format,&fieldType[k],1);
1821 if (fieldType[k] == 'A')
1822 {
1823 strcat(format,largeur);
1824 }
1825 ttype[k] = const_cast<char*>(Noms[k].c_str());
1826 tform[k]= new char[FLEN_VALUE];
1827 strcpy(tform[k],format);
1828 }
1829 char* extn = const_cast<char*>(extname.c_str());
1830
1831 // create a new empty binary table onto the FITS file
1832 // physical units if they exist, are defined in the DVList object
1833 // so the NULL pointer is given for the tunit parameters.
1834 nrows=0;
1835 fits_create_tbl(fptr_,BINARY_TBL,nrows,tfields,ttype,tform,
1836 NULL,extn,&status);
1837 if( status ) printerror( status );
1838
1839 int ii;
1840 for(ii = 0; ii < tfields; ii++)
1841 {
1842 delete [] tform[ii];
1843 }
1844 delete [] ttype;
1845 delete [] tform;
1846
1847 // on ajoute eventuellement des mots-cles
1848
1849 if ( hdunum_ == 0 )
1850 {
1851 hdunum_ = 2;
1852 addDVListOnPrimary();
1853 writeSignatureOnFits(1);
1854 }
1855 else hdunum_++;
1856
1857 // header format FITS
1858
1859 writeAppendedHeaderOnFits();
1860
1861 // write SOPHYA keywords
1862 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
1863}
1864
1865
1866
1867/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
1868
1869write double data from array 'donnees ' on column number 'nocol' of a BINTABLE extension.
1870\param <nentries> number of data to be written
1871*/
1872
1873void FitsOutFile::PutColToFits(int nocol, int nentries, r_8* donnees) const
1874{
1875 int status = 0;
1876 int hdutype;
1877 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1878 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1879 fits_get_hdu_type(fptr_, &hdutype, &status);
1880 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1881 {
1882 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1883 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1884 }
1885 int code;
1886 long repeat, width;
1887 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1888 if( code != TDOUBLE)
1889 {
1890 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " to be written= DOUBLE " << endl;
1891 }
1892 // cout << " 10 elements de colonne " << endl;
1893 // for (int toto=0; toto < 10; toto++) cout << donnees[toto] << endl;
1894 fits_write_col(fptr_,TDOUBLE,nocol+1,1,1,nentries, donnees ,&status);
1895 if( status ) printerror( status,"erreur ecriture col. double, dans fichier fits" );
1896}
1897
1898
1899
1900 /*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
1901
1902same as previous method with float data
1903*/
1904void FitsOutFile::PutColToFits(int nocol, int nentries, r_4* donnees) const
1905{
1906 int status = 0;
1907 int hdutype;
1908 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1909 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1910 fits_get_hdu_type(fptr_, &hdutype, &status);
1911 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1912 {
1913 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1914 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1915 }
1916 if(hdutype == ASCII_TBL && nocol>0)
1917 {
1918 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1919 }
1920 int code;
1921 long repeat, width;
1922 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1923 if( code != TFLOAT)
1924 {
1925 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= FLOAT " << endl;
1926 }
1927 fits_write_col(fptr_,TFLOAT,nocol+1,1,1,nentries, donnees ,&status);
1928 if( status ) printerror( status,"erreur ecriture col. floats, dans fichier fits" );
1929}
1930
1931
1932/*! \fn void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
1933
1934same as previous method with int data
1935*/
1936void FitsOutFile::PutColToFits(int nocol, int nentries, int_4* donnees) const
1937{
1938 int status = 0;
1939 int hdutype;
1940 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1941 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1942 fits_get_hdu_type(fptr_, &hdutype, &status);
1943 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1944 {
1945 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1946 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1947 }
1948 if(hdutype == ASCII_TBL && nocol>0)
1949 {
1950 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1951 }
1952 int code;
1953 long repeat, width;
1954 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1955
1956
1957
1958 if (code == TINT || code == TLONG)
1959 {
1960 // cfitsio n'a que des entiers de longueur inferieure a 32 bits.
1961 // ici, a l'ecriture TLONG impliquerait que le tableau de donnees
1962 // soit un tableau int_8. Donc c'est toujours TINT qu;il faut mettre
1963 // De plus, j'ai l'impression que TINT va devenir obsolete dans cfitsio
1964 // (GLM)
1965 fits_write_col(fptr_,TINT,nocol+1,1,1,nentries, donnees ,&status);
1966 }
1967 else
1968 {
1969 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= integers " << endl;
1970 }
1971 if( status ) printerror( status,"erreur ecriture col. entiers, dans fichier fits" );
1972}
1973
1974
1975/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1976same as previous method with char* data
1977*/
1978void FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1979{
1980 int status = 0;
1981 int hdutype;
1982 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1983 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1984 fits_get_hdu_type(fptr_, &hdutype, &status);
1985 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1986 {
1987 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1988 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1989 }
1990 if(hdutype == ASCII_TBL && nocol>0)
1991 {
1992 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1993 }
1994 int code;
1995 long repeat, width;
1996 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1997 if( code != TSTRING)
1998 {
1999 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= char** " << endl;
2000 }
2001 fits_write_col(fptr_,TSTRING,nocol+1,1,1,nentries, donnees ,&status);
2002 if( status ) printerror( status,"erreur ecriture col. chars, dans fichier fits" );
2003}
2004
2005void FitsOutFile::PutBinTabLine(long NoLine, BnTblLine& ligne) const
2006{
2007 // on ne fait pas de verification de type, ni de dimension ici, pour
2008 // des raisons de performances
2009 int k;
2010 int status= 0;
2011 int anynul;
2012 int ncol=0;
2013 long nels=1;
2014 // int nbcols;
2015 // fits_get_num_cols(fptr_, &nbcols,&status);
2016 for (k=0; k<ligne.ddata_.size(); k++, ncol++)
2017 {
2018 fits_write_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1, &ligne.ddata_[k] ,&status);
2019 if( status ) printerror( status, "PutBinTabLine : erreur ecriture double" );
2020 }
2021 for (k=0; k<ligne.fdata_.size(); k++, ncol++)
2022 {
2023 fits_write_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1, &ligne.fdata_[k] ,&status);
2024 if( status ) printerror( status, "PutBinTabLine : erreur ecriture float" );
2025 }
2026 for (k=0; k<ligne.idata_.size(); k++, ncol++)
2027 {
2028 fits_write_col(fptr_,TINT,ncol+1,NoLine+1,1,1, &ligne.idata_[k] ,&status);
2029 if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier" );
2030 }
2031 for (k=0; k<ligne.ldata_.size(); k++, ncol++)
2032 {
2033 fits_write_col(fptr_,TLONG,ncol+1,NoLine+1,1,1, &ligne.ldata_[k] ,&status);
2034 if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier long" );
2035 }
2036 for (k=0; k<ligne.bdata_.size(); k++, ncol++)
2037 {
2038 fits_write_col(fptr_,TBYTE,ncol+1,NoLine+1,1,1, &ligne.bdata_[k] ,&status);
2039 if( status ) printerror( status, "PutBinTabLine : erreur ecriture byte" );
2040 }
2041
2042 for (k=0; k<ligne.cdata_.size(); k++, ncol++)
2043 {
2044 fits_write_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1, (void*)ligne.cdata_[k].c_str() ,&status);
2045 if( status ) printerror( status, "PutBinTabLine : erreur ecriture caracteres" );
2046 }
2047}
2048
2049
2050/* \fn void SOPHYA::FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl) const
2051
2052Put keywords from a DVList into the primary header of the fits-file
2053*/
2054void FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl)
2055{
2056 int status = 0;
2057 int hdutype;
2058 if (hdunum_ == 0)
2059 {
2060 if (dvlToPrimary_ == NULL) dvlToPrimary_ = new DVList(dvl);
2061 else dvlToPrimary_->Merge(dvl);
2062 }
2063 else
2064 {
2065 fits_movabs_hdu(fptr_,1,&hdutype,&status);
2066 addKeywordsOfDVList(dvl);
2067 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
2068 }
2069}
2070
2071
2072void FitsOutFile::writeSignatureOnFits(int hdunum) const
2073{
2074 int status = 0;
2075 int hdutype;
2076 char keyname[LEN_KEYWORD];
2077 char strval[FLEN_VALUE];
2078 char comment[FLEN_COMMENT];
2079 if (hdunum_ == 0)
2080 {
2081 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
2082 return;
2083 }
2084 fits_movabs_hdu(fptr_,1,&hdutype,&status);
2085 //
2086 strncpy(keyname, "CREATOR", LEN_KEYWORD);
2087 keyname[7] = '\0';
2088 strcpy(strval, "SOPHYA");
2089 strcpy(comment," SOPHYA Package - FITSIOServer ");
2090 fits_write_key(fptr_, TSTRING, keyname, &strval, comment, &status);
2091 if( status ) printerror( status );
2092 fits_write_date(fptr_, &status);
2093 fits_write_comment(fptr_,"..............................................", &status);
2094 fits_write_comment(fptr_, " SOPHYA package - FITSIOSever ", &status);
2095 fits_write_comment(fptr_, " (C) LAL/IN2P3-CNRS Orsay, FRANCE 2000", &status);
2096 fits_write_comment(fptr_, " (C) DAPNIA/CEA Saclay, FRANCE 2000", &status);
2097 fits_write_comment(fptr_,"..............................................", &status);
2098 if( status ) printerror( status, "erreur writeSignatureOnFits" );
2099 //
2100 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
2101}
2102
2103
2104void FitsOutFile::addKeywordsOfDVList( DVList& dvl) const
2105{
2106 int status = 0;
2107 fits_write_comment(fptr_,"---------- keywords from SOPHYA ---------", &status);
2108 DVList::ValList::const_iterator it;
2109 for(it = dvl.Begin(); it != dvl.End(); it++)
2110 {
2111 MuTyV::MTVType keytype= (*it).second.elval.Type();
2112 char keyname[LEN_KEYWORD];
2113 strncpy(keyname,(*it).first.substr(0,64).c_str(),LEN_KEYWORD);
2114 int bout = ((*it).first.substr(0,64).length() < LEN_KEYWORD) ? (*it).first.substr(0,64).length() : LEN_KEYWORD-1;
2115 keyname[bout] = '\0';
2116 string key((*it).first.substr(0,64));
2117 // string key(keyname);
2118 char comment[FLEN_COMMENT];
2119 char strval[FLEN_VALUE]= "";
2120 char *comkey = "COMMENT";
2121 // fits_read_keyword(fptr_, keyname, strval, NULL, &status);
2122 // if (status != 0 || strncmp(keyname,comkey,LEN_KEYWORD-1) == 0 )
2123 {
2124 string coco = dvl.GetComment(key);
2125 coco.copy( comment, FLEN_COMMENT-1);
2126 int bout = (coco.length() < FLEN_COMMENT) ? coco.length() : FLEN_COMMENT-1;
2127 comment[bout]= '\0';
2128 status = 0;
2129 switch (keytype)
2130 {
2131 case MuTyV::MTVInteger :
2132 {
2133 int ival = (int)dvl.GetI(key);
2134 fits_write_key(fptr_,TINT,keyname,&ival, comment,&status);
2135 break;
2136 }
2137 case MuTyV::MTVFloat :
2138 {
2139 double dval= (double)dvl.GetD(key);
2140 fits_write_key(fptr_,TDOUBLE,keyname,&dval,comment,&status);
2141 break;
2142 }
2143 case MuTyV::MTVString :
2144 {
2145 char strvaleur[FLEN_VALUE]= "";
2146 string valChaine = dvl.GetS(key);
2147 valChaine.copy(strvaleur, FLEN_VALUE-1);
2148 int fin = (valChaine.length() < FLEN_VALUE) ? valChaine.length() : FLEN_VALUE-1;
2149 strvaleur[fin]= '\0';
2150
2151 fits_write_key(fptr_,TSTRING,keyname,&strvaleur,comment,&status);
2152 break;
2153 }
2154 }
2155 }
2156 if( status ) printerror( status,"fitsfile: probleme ecriture mot-cle du dvlist" );
2157 }
2158 fits_write_comment(fptr_,"--------------------------------------", &status);
2159}
2160
2161
2162void FitsOutFile::addDVListOnPrimary()
2163 {
2164 int status = 0;
2165 int hdutype;
2166 if (hdunum_ == 0)
2167 {
2168 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
2169 return;
2170 }
2171 if (dvlToPrimary_ != NULL)
2172 {
2173 fits_movabs_hdu(fptr_,1,&hdutype,&status);
2174 addKeywordsOfDVList(*dvlToPrimary_);
2175 delete dvlToPrimary_;
2176 dvlToPrimary_ = NULL;
2177 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
2178 }
2179 }
2180
2181
2182/*! \fn void FitsOutFile::appendInHeader(FitsInFile& infits, int hdunum)
2183
2184get a header from FitsInFile and append to the header beeing built
2185(shifting mandatory keywords)
2186*/
2187
2188void FitsOutFile::appendInputHeader(FitsInFile& infits, int hdunum)
2189{
2190
2191 infits.GetKeywordsFromHeader(hdunum, mots_cles_);
2192 /*
2193 int status = 0;
2194 int hdutype;
2195 fitsfile* fptr=infits.fitsfilePtr();
2196 fits_movabs_hdu(fptr,hdunum,&hdutype,&status);
2197 if( status ) fits_report_error(stderr,status);
2198
2199 // get number of keywords
2200 int nkeys,keypos;
2201 fits_get_hdrpos(fptr,&nkeys,&keypos,&status);
2202 if( status ) fits_report_error(stderr,status);
2203 // shift with the number of mandatory keywords
2204 int num= 0;
2205 // if primary header
2206 if (hdunum == 1)
2207 {
2208 // read NAXIS
2209 int naxis=0;
2210 fits_read_key(fptr,TINT,"NAXIS",&naxis,NULL,&status);
2211 // number of mandatory keywords
2212 num = naxis+3;
2213 }
2214 // extensions
2215 else
2216 {
2217 if (hdutype == IMAGE_HDU)
2218 {
2219 // read NAXIS
2220 int naxis=0;
2221 fits_read_key(fptr,TINT,"NAXIS",&naxis,NULL,&status);
2222 // number of mandatory keywords
2223 num = naxis+5;
2224 }
2225 else
2226 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
2227 {
2228 // number of mandatory keywords
2229 num = 8;
2230 }
2231 }
2232 int j;
2233 char keyname[LEN_KEYWORD];
2234 char value[FLEN_VALUE];
2235 char comment[FLEN_COMMENT];
2236 for(j = num+1; j <= nkeys; j++)
2237 {
2238 char dtype;
2239 fits_read_keyn(fptr,j,keyname,value,comment,&status);
2240 if(status)
2241 {
2242 fits_report_error(stderr,status);
2243 status=0;
2244 }
2245 string kn(keyname);
2246 string cm(comment);
2247 string val(value);
2248 FitsKeyword kw(kn, val, cm);
2249 mots_cles_.push_back(kw);
2250 }
2251 */
2252}
2253void FitsOutFile::writeAppendedHeaderOnFits()
2254{
2255 for (list<FitsKeyword>::iterator it=mots_cles_.begin(); it !=mots_cles_.end(); it++)
2256 {
2257 (*it).writeOnFits(fptr_);
2258 }
2259 mots_cles_.clear();
2260}
2261
2262void FitsOutFile::insertKeywordOnHeader(string keyname, double value, string comment)
2263{
2264 char cvalue[16];
2265 sprintf(cvalue,"%e",value);
2266 FitsKeyword kw(keyname, string(cvalue), comment, 'F');
2267 mots_cles_.push_back(kw);
2268}
2269void FitsOutFile::insertKeywordOnHeader(string keyname, int value, string comment)
2270{
2271 char cvalue[16];
2272 sprintf(cvalue,"%d",value);
2273 FitsKeyword kw(keyname, string(cvalue), comment, 'I');
2274 mots_cles_.push_back(kw);
2275}
2276void FitsOutFile::insertKeywordOnHeader(string keyname, string value, string comment)
2277{
2278 FitsKeyword kw(keyname, value , comment, 'C');
2279 mots_cles_.push_back(kw);
2280}
2281
2282void FitsOutFile::insertCommentLineOnHeader(string comment)
2283{
2284 FitsKeyword kw(comment);
2285 mots_cles_.push_back(kw);
2286}
2287
2288void FitsOutFile::PrintHeaderToBeAppended()
2289{
2290 cout << " contenu du header en cours de fabrication " << endl;
2291 for (list<FitsKeyword>::iterator it=mots_cles_.begin(); it !=mots_cles_.end(); it++)
2292 {
2293 (*it).Print();
2294 }
2295}
2296
2297
2298FitsKeyword::FitsKeyword()
2299 {
2300 datatype_=' ';
2301 keyname_ = string("");
2302 dvalue_=0.;
2303 ivalue_=1;
2304 svalue_=string("");
2305 comment_=string("");
2306 }
2307
2308FitsKeyword::FitsKeyword(string comment)
2309 {
2310 datatype_=' ';
2311 keyname_=string("COMMENT");
2312 comment_=comment;
2313 }
2314
2315FitsKeyword::FitsKeyword(string keyname, string value, string comment) : keyname_(keyname), comment_(comment)
2316 {
2317 int status=0;
2318 char dtype;
2319 const char* val= value.c_str();
2320 char* valk = const_cast<char*>(val);
2321 fits_get_keytype(valk,&dtype,&status);
2322 if(status)
2323 {
2324 status=0;
2325 if (status == VALUE_UNDEFINED) cout << "WARNING (FitsKeyword) : undefined keyword value " << endl;
2326 datatype_=' ';
2327 }
2328 else datatype_=dtype;
2329
2330 switch( datatype_ )
2331 {
2332 case 'C':
2333 {
2334 strip(valk, 'B','\'');
2335 svalue_ = string(valk);
2336 break;
2337 }
2338 case 'I':
2339 {
2340 ivalue_ = atoi(val);
2341 break;
2342 }
2343 case 'L':
2344 {
2345 bool bb = value.c_str();
2346 ivalue_ = (int)bb;
2347 break;
2348 }
2349 case 'F':
2350 {
2351 dvalue_ = atof(val);
2352 break;
2353 }
2354 case 'X':
2355 {
2356 throw IOExc("FitsKeyword , complex keyword value not supported");
2357 }
2358 }
2359 }
2360
2361// constructeur pour les mots-cles maison (ne prvenant pas de la lecture d'un fichier fits)
2362FitsKeyword::FitsKeyword(string keyname, string value, string comment, char type) : keyname_(keyname), comment_(comment), datatype_(type)
2363 {
2364 char dtype;
2365 const char* val= value.c_str();
2366 char* valk = const_cast<char*>(val);
2367 switch( datatype_ )
2368 {
2369 case 'C':
2370 {
2371 strip(valk, 'B','\'');
2372 svalue_ = string(valk);
2373 break;
2374 }
2375 case 'I':
2376 {
2377 ivalue_ = atoi(val);
2378 break;
2379 }
2380 case 'L':
2381 {
2382 bool bb = value.c_str();
2383 ivalue_ = (int)bb;
2384 break;
2385 }
2386 case 'F':
2387 {
2388 dvalue_ = atof(val);
2389 break;
2390 }
2391 case 'X':
2392 {
2393 throw IOExc("FitsKeyword , complex keyword value not supported");
2394 }
2395 }
2396 }
2397
2398void FitsKeyword::writeOnFits(fitsfile* ptr)
2399 {
2400 int status=0;
2401 char keyname[LEN_KEYWORD];
2402 char comment[FLEN_COMMENT];
2403 keyname_.copy(keyname, LEN_KEYWORD);
2404 int bout = (keyname_.length() < LEN_KEYWORD) ? keyname_.length() : LEN_KEYWORD-1;
2405 keyname[bout] = '\0';
2406 comment_.copy( comment, FLEN_COMMENT);
2407 bout = (comment_.length() < FLEN_COMMENT) ? comment_.length() : FLEN_COMMENT-1;
2408 comment[bout]= '\0';
2409
2410 int nkeys,keypos;
2411 fits_get_hdrpos(ptr,&nkeys,&keypos,&status);
2412 switch( datatype_ )
2413 {
2414 case 'C':
2415 {
2416 char value[FLEN_VALUE]="";
2417 svalue_.copy(value, FLEN_VALUE-1);
2418 int fin = (svalue_.length() < FLEN_VALUE) ? svalue_.length() : FLEN_VALUE-1;
2419 value[fin]= '\0';
2420 fits_write_key(ptr,TSTRING,keyname,&value, comment,&status);
2421 fits_report_error(stderr,status);
2422 break;
2423 }
2424 case 'I':
2425 {
2426 fits_write_key(ptr,TINT,keyname,&ivalue_, comment,&status);
2427 fits_report_error(stderr,status);
2428 break;
2429 }
2430 case 'L':
2431 {
2432 fits_write_key(ptr,TLOGICAL,keyname,&ivalue_, comment,&status);
2433 fits_report_error(stderr,status);
2434 break;
2435 }
2436 case 'F':
2437 {
2438 fits_write_key(ptr,TDOUBLE,keyname,&dvalue_, comment,&status);
2439 fits_report_error(stderr,status);
2440 break;
2441 }
2442 case 'X':
2443 {
2444 cout << "FitsKeyword : complex keyword value not supported" << endl;;
2445 break;
2446 }
2447 default :
2448 {
2449 char *comkey = "COMMENT";
2450 if(strncmp(keyname,comkey,LEN_KEYWORD-1) == 0)
2451 {
2452 fits_write_comment(ptr,comment,&status);
2453 fits_report_error(stderr,status);
2454 }
2455 else
2456 {
2457 cout << " WARNING (FitsKeyword::writeOnFits) : unrecognized keyword : " << keyname_ << endl;
2458 }
2459 }
2460 }
2461 }
2462
2463void FitsKeyword::Print()
2464 {
2465 switch( datatype_ )
2466 {
2467 case 'C':
2468 {
2469 cout << " mot cle : " << keyname_ << " valeur : " << svalue_ << " commentaire : " << comment_ <<endl;
2470 break;
2471 }
2472 case 'I':
2473 {
2474 cout << " mot cle : " << keyname_ << " valeur : " << ivalue_ << " commentaire : " << comment_ <<endl;
2475 break;
2476 }
2477 case 'L':
2478 {
2479 cout << " mot cle : " << keyname_ << " valeur : " << ivalue_ << " commentaire : " << comment_ <<endl;
2480 break;
2481 }
2482 case 'F':
2483 {
2484 cout << " mot cle : " << keyname_ << " valeur : " << dvalue_ << " commentaire : " << comment_ <<endl;
2485 break;
2486 }
2487 case 'X':
2488 {
2489 cout << "FitsKeyword : complex keyword value not supported" << endl;;
2490 }
2491 default :
2492 {
2493 cout << " mot cle : " << keyname_ << " commentaire : " << comment_ <<endl;
2494 }
2495 }
2496 }
Note: See TracBrowser for help on using the repository browser.