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

Last change on this file since 3885 was 3619, checked in by cmv, 16 years ago

add various #include<> for g++ 4.3 (jaunty 9.04), cmv 05/05/2009

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