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

Last change on this file since 2897 was 2897, checked in by ansari, 20 years ago

Mise en place de l heritage FitsIOHandler (ancien) de FitsHandlerInterface pour une gestion commune - a partir de FitsManager - Reza 13/01/2006

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