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

Last change on this file since 1281 was 1281, checked in by ansari, 25 years ago

Decodage type byte ds lecture entete FITS - Reza 2/11/2000

File size: 47.6 KB
Line 
1#include "machdefs.h"
2#include <stdlib.h>
3#include "fitsfile.h"
4#include "pexceptions.h"
5#include "strutil.h"
6#include "anydataobj.h"
7#include "fitsspherehealpix.h"
8
9
10void BnTblLine::setFormat(int dc, int fc, int ic, int cc, vector<string> names)
11 {
12 int nbcols = dc + fc + ic + cc;
13 int maxName = names.size();
14 if (nbcols != maxName)
15 {
16 cout << " WARNING: BnTblLine:: length of vector of column names not equal to total number of columns" << endl;
17 maxName = nbcols < maxName ? nbcols : maxName;
18 }
19 ColName_ = vector<string>(nbcols);
20 for (int k=0; k < maxName; k++) ColName_[k] = names[k];
21 if (dc >0) ddata_ = vector<double>(dc);
22 if (fc >0) fdata_ = vector<float>(fc);
23 if (ic >0) idata_ = vector<int>(fc);
24 if (cc >0) cdata_ = vector<string>(fc);
25 }
26
27bool BnTblLine::sameFormat(const BnTblLine& btl) const
28 {
29 if (btl.ddata_.size() == ddata_.size() && btl.fdata_.size() == fdata_.size() && btl.idata_.size() == idata_.size() && btl.cdata_.size() == cdata_.size()) return true;
30 else return false;
31 }
32
33void BnTblLine::Print()
34 {
35 int k;
36 cout << " ********* ligne ************* " << endl;
37 cout << " *** noms de variables " << endl;
38 for (k=0; k < ColName_.size(); k++) cout << ColName_[k] << " ";
39 cout << endl;
40 cout << " *** variables doubles " << endl;
41 for (k=0; k < ddata_.size(); k++) cout << ddata_[k] << " ";
42 cout << endl;
43 cout << " *** variables float " << endl;
44 for (k=0; k < fdata_.size(); k++) cout << fdata_[k] << " ";
45 cout << endl;
46 cout << " *** variables int " << endl;
47 for (k=0; k < idata_.size(); k++) cout << idata_[k] << " ";
48 cout << endl;
49 cout << " *** variables string " << endl;
50 for (k=0; k < cdata_.size(); k++) cout << cdata_[k] << " ";
51 cout << endl;
52 cout << " ***************************** " << endl;
53 }
54
55
56
57/*!
58 \class SOPHYA::FitsIOHandler
59The class structure is analogous to Sophya-PPersist system :
60Each SOPHYA object XXX is associated with a object of class FITS_XXX
61 (inheriting from FitsFileHandler), to which input/output operations with FITS
62 files are delegated (through a class Hierarchy : FitsFile (virtual),
63 FitsInFile, FitsOutFile) . A typical example of use is the following :
64
65\verbatim
66 int m=... ;
67 SphereHEALPix<r_8> sphere1(m); // definition of the SOPHYA object
68 .... fill the sphere ....
69
70 FITS_SphereHEALPix<r_8> fits_sph1(sphere1);
71 // delegated object
72 fits_sph.Write("myfile.fits"); // writing on FITS file
73
74 FITS_SphereHEALPix<r_8> fits_sph2("myfile.fits");
75 // load a delegated object
76 // from FITS file
77 SphereHEALPix<r_8> sphere2=(SphereHEALPix<r_8>)fits_sph2;
78 // casting the delegated object
79 // into a SOPHYA object
80\endverbatim
81
82
83*/
84
85/*! \fn void SOPHYA::FitsIOHandler::Read(char flnm[],int hdunum)
86
87this method is called from inherited objects :
88
89opens a file 'flnm'
90
91gets parameters in extension-header (hdunum)
92
93calls the method 'ReadFromFits' from the inherited object
94*/
95void FitsIOHandler::Read(char flnm[],int hdunum)
96{
97 FitsInFile ifts(flnm);
98 Read(ifts, hdunum);
99}
100
101 /*! \fn void SOPHYA::FitsIOHandler::Read(FitsInFile& is, int hdunum)
102Read 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.
103 */
104void FitsIOHandler::Read(FitsInFile& is, int hdunum)
105{
106 is.ReadFInit(hdunum);
107 ReadFromFits(is);
108}
109
110
111/*! \fn void SOPHYA::FitsIOHandler::Write(char flnm[])
112this method is called from inherited objects.
113
114for writing a new object in a new fits-extension :
115
116\warning By convention, primary header may contain fits-image data.
117For switching off this convention (i.e. to make sure that all data will be on fits-extensions) use the method :
118
119firstImageOnPrimaryHeader() (see below)
120
121calls the method 'WriteToFits' from the inherited object
122
123*/
124void FitsIOHandler::Write(char flnm[])
125
126{
127 FitsOutFile of(flnm, FitsFile::unknown);
128 Write(of);
129}
130
131void FitsIOHandler::Write(FitsOutFile& os)
132{
133 WriteToFits(os);
134}
135
136
137/*!
138 \class SOPHYA::FitsIOHandler
139Class (virtual) for managing FITS format files
140*/
141
142
143
144FitsFile::~FitsFile()
145{
146 int status = 0;
147 if( fptr_ != NULL)
148 {
149 fits_close_file(fptr_,&status);
150 // je ne fais pas delete fptr_, c'est la lib. fitsio qui a fait
151 // new...
152 }
153 if( status ) printerror( status );
154}
155
156
157void FitsFile::printerror(int &status)
158 //*****************************************************/
159 //* Print out cfitsio error messages and exit program */
160 //*****************************************************/
161{
162 if( status )
163 {
164 fits_report_error(stderr,status);
165 throw IOExc("FitsFile:: error FITSIO status");
166 }
167 return;
168}
169
170void FitsFile::printerror(int& status, char* texte)
171 //*****************************************************/
172 //* Print out cfitsio error messages and exit program */
173 //*****************************************************/
174{
175 // print out cfitsio error messages and exit program
176 // print error report
177 fits_report_error(stderr, status);
178 cout << " erreur:: " << texte << endl;
179 throw IOExc("FitsFile:: error FITSIO status");
180}
181
182void FitsFile::ResetStatus(int& status)
183{
184 fits_status_ = status;
185 status = 0;
186 fits_clear_errmsg();
187}
188
189string FitsFile::GetErrStatus(int status)
190{
191 char text[31];
192 fits_get_errstatus(status, text);
193 return string(text);
194}
195
196/*!
197 \class SOPHYA::FitsInFile
198
199class for reading SOPHYA objects from FITS Format Files (uses cfitsio lib)
200*/
201
202FitsInFile::FitsInFile()
203{
204 InitNull();
205}
206
207FitsInFile::FitsInFile(string const & flnm)
208{
209 InitNull();
210 int status = 0;
211 fits_open_file(&fptr_,flnm.c_str(),READONLY,&status);
212 if( status ) printerror( status );
213}
214
215FitsInFile::FitsInFile(const char * flnm)
216{
217 InitNull();
218 int status = 0;
219 fits_open_file(&fptr_,flnm,READONLY,&status);
220 if( status ) printerror( status );
221}
222
223
224void FitsInFile::InitNull()
225{
226
227 bitpix_ = 0;
228 naxis_ = 0;
229 nbData_ = 0;
230 nrows_ = 0;
231 nbcols_ = 0;
232 naxisn_.clear();
233 repeat_.clear();
234 noms_.clear();
235 taille_des_chaines_.clear();
236 dvl_.Clear();
237
238
239}
240
241//////////////////////////////////////////////////////////
242// methods with general purpose
243/////////////////////////////////////////////////////////
244
245int FitsInFile::NbBlocks(char flnm[])
246{
247 int status = 0;
248 int nbhdu = 0;
249 fitsfile* fileptr;
250 fits_open_file(&fileptr,flnm,READONLY,&status);
251 if( status ) printerror( status, "NbBlocks: erreur ouverture fichier" );
252 fits_get_num_hdus(fileptr, &nbhdu, &status);
253 fits_close_file(fileptr,&status);
254 return nbhdu;
255}
256
257void FitsInFile::GetBlockType(char flnm[], int hdunum, FitsExtensionType& typeOfExtension, int& naxis, vector<int>& naxisn, FitsDataType& dataType, DVList& dvl )
258{
259 int status = 0;
260 fitsfile* fileptr;
261 fits_open_file(&fileptr,flnm,READONLY,&status);
262 if( status ) printerror( status, "GetBlockType: erreur ouverture fichier" );
263 // move to the specified HDU number
264 int hdutype = 0;
265 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
266 if( status ) printerror( status,"GetBlockType: erreur movabs");
267 if(hdutype == IMAGE_HDU)
268 {
269 typeOfExtension = FitsExtensionType_IMAGE;
270 int bitpix;
271 GetImageParameters (fileptr, bitpix, naxis, naxisn);
272 if(bitpix == DOUBLE_IMG) dataType = FitsDataType_double;
273 else
274 if(bitpix == FLOAT_IMG) dataType = FitsDataType_float;
275 else
276 if(bitpix == LONG_IMG || bitpix == SHORT_IMG ) dataType = FitsDataType_int;
277 else
278 if (bitpix == BYTE_IMG) dataType = FitsDataType_char;
279 else
280 {
281 cout << " bitpix= " << bitpix << endl;
282 throw PException(" FitsFile::GetBlockType : unsupprted FITS data type");
283 }
284
285 }
286 else
287 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
288 {
289 int nrows = 0;
290 vector<string> noms;
291 vector<char> types;
292 vector<int> taille_des_chaines;
293 GetBinTabParameters(fileptr, naxis, nrows, naxisn, noms, types, taille_des_chaines);
294 int k;
295 for (k=0; k< naxisn.size(); k++) naxisn[k] *= nrows;
296 if(hdutype == ASCII_TBL)
297 {
298 typeOfExtension = FitsExtensionType_ASCII_TBL;
299 dataType = FitsDataType_ASCII;
300 }
301 else
302 {
303 typeOfExtension = FitsExtensionType_BINARY_TBL;
304 if(types[0] == 'D') dataType = FitsDataType_double;
305 else
306 if(types[0] == 'E') dataType = FitsDataType_float;
307 else
308 if(types[0] == 'I' ) dataType = FitsDataType_int;
309 else
310 if(types[0] == 'S' ) dataType = FitsDataType_char;
311 else
312 {
313 cout << " types[0]= " << types[0] << endl;
314 throw PException(" FitsFile::GetBlockType : unsupprted FITS data type");
315 }
316 }
317 }
318 else
319 {
320 cout << " hdutype= " << hdutype << endl;
321 throw IOExc("FitsFile::GetBlockType: this HDU type is unknown");
322 }
323
324 KeywordsIntoDVList(fileptr, dvl, hdunum);
325 fits_close_file(fileptr,&status);
326}
327
328
329void FitsInFile::ReadFInit(int hdunum)
330{
331 InitNull();
332 int status = 0;
333
334 if (hdunum != 0 ) hdunum_ = hdunum;
335
336 // si le numero de header non precise
337 else
338 {
339 // si c'est le premier objet a lire
340 if (hdunum_ == 0)
341 {
342 // on calcule le numero de header a lire
343 if (imageOnPrimary_ == true ) hdunum_ = 1;
344 else hdunum_ = 2;
345 }
346 // sinon objet suivant
347 else hdunum_++;
348 }
349 getHeader();
350
351}
352
353
354void FitsInFile::GetImageParameters (fitsfile* fileptr,int& bitpix,int& naxis,vector<int>& naxisn)
355{
356 int hdunum=0;
357 cout << " Reading a FITS image in HDU : " << fits_get_hdu_num(fileptr,&hdunum) << endl;
358 int status= 0;
359
360 // bits per pixels
361 fits_read_key(fileptr,TINT,"BITPIX",&bitpix,NULL,&status);
362 if( status ) printerror( status );
363
364 // number of dimensions in the FITS array
365 naxis= 0;
366 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
367 if( status ) printerror( status );
368 // read the NAXISn keywords to get image size
369 long* naxes = new long[naxis] ;
370 int nfound;
371 fits_read_keys_lng(fileptr,"NAXIS",1,naxis,naxes,&nfound,&status);
372 if( status ) printerror( status );
373 if (nfound != naxis )
374 cout << " WARNING : " << nfound << " axes found, expected naxis= " << naxis << endl;
375 int k;
376 for (k=0; k<naxis; k++)
377 {
378 naxisn.push_back( (int)naxes[k] );
379 }
380 delete [] naxes;
381}
382
383
384
385
386 /*! \fn DVList SOPHYA::FitsInFile::DVListFromPrimaryHeader() const
387
388 \return the keywords of primary header in a DVList
389
390*/
391DVList FitsInFile::DVListFromPrimaryHeader() const
392 {
393 int status;
394 DVList dvl;
395 KeywordsIntoDVList(fptr_, dvl, 1);
396 int hdutype = 0;
397 if (hdunum_ > 0) fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
398 return dvl;
399 }
400
401void FitsInFile::getHeader()
402{
403 int status=0;
404 if (hdunum_ < 1) throw PException(" attempt to read hdunum < 1");
405 if (hdunum_ == 1)
406 {
407 // presence of image ?
408 int naxis= 0;
409 fits_read_key(fptr_,TINT,"NAXIS",&naxis,NULL,&status);
410 if( status ) printerror( status );
411 if (naxis > 0 ) // there is an image
412 {
413 hdutype_ = IMAGE_HDU;
414 GetImageParameters (fptr_, bitpix_, naxis_, naxisn_);
415 nbData_ = 1;
416 int k;
417 for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
418 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
419 }
420 else
421 {
422 // the object to be read is probably a bin or ascii table
423 // (on an extension)
424 hdunum_++;
425 getHeader();
426
427 // throw PException(" first header : no image, probably error in hdunum");
428 }
429 }
430 else
431 {
432 int hdutype;
433 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
434 if( status ) printerror( status,":FitsInFile::getHeader : erreur movabs");
435 hdutype_= hdutype;
436 if(hdutype_ == IMAGE_HDU)
437 {
438 GetImageParameters (fptr_, bitpix_, naxis_, naxisn_);
439 nbData_ = 1;
440 int k;
441 for (k=0; k<naxis_; k++) if (naxisn_[k] > 0) nbData_ *= naxisn_[k];
442 KeywordsIntoDVList(fptr_, dvl_,hdunum_);
443 }
444 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
445 {
446 GetBinTabParameters(fptr_,nbcols_, nrows_,repeat_, noms_, types_, taille_des_chaines_);
447 KeywordsIntoDVList(fptr_, dvl_, hdunum_);
448 }
449 }
450}
451
452
453void FitsInFile::moveToFollowingHeader()
454{
455 int status = 0;
456 hdunum_++;
457 getHeader();
458}
459
460
461
462
463
464/*! \fn int SOPHYA::FitsInFile::NbColsFromFits() const
465\return number of columns (return 1 if IMAGE)
466*/
467int FitsInFile::NbColsFromFits() const
468{
469 if(hdutype_ == BINARY_TBL) return nbcols_;
470 else
471 if(hdutype_ == ASCII_TBL || hdutype_ == IMAGE_HDU) return 1;
472 else
473 {
474 cout << " hdutype= " << hdutype_ << endl;
475 throw PException("FitsFile::NbColsFromFits, this HDU is unknown");
476 }
477}
478
479/*! \fn int SOPHYA::FitsInFile::NentriesFromFits(int nocol) const
480\return number of data in the current IMAGE extension on FITS file, or number
481 of data of column number 'nocol' of the current BINTABLE extension
482*/
483int FitsInFile::NentriesFromFits(int nocol) const
484{
485 if(hdutype_ == BINARY_TBL ) return nrows_*repeat_[nocol];
486 else
487 if(hdutype_ == ASCII_TBL) return nrows_;
488 else
489 if(hdutype_ == IMAGE_HDU) return nbData_;
490 else
491 {
492 cout << "hdutype= " << hdutype_ << endl;
493 throw PException("FitsFile::NentriesFromFits, this HDU is unknown");
494 }
495}
496
497/*! \fn char SOPHYA::FitsInFile::ColTypeFromFits(int nocol) const
498
499return a character denoting data type of column number 'nocol' in a BINTABLE :
500
501D : double
502
503E : float
504
505I : integer
506
507S : character string
508
509 */
510
511char FitsInFile::ColTypeFromFits(int nocol) const
512{
513 if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL)
514 {
515 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
516 }
517 return types_[nocol];
518}
519
520
521/*! \fn string SOPHYA::FitsInFile::ColNameFromFits(int nocol) const
522
523\return name of the column number 'nocol' of the current BINTABLE extension
524 */
525
526string FitsInFile::ColNameFromFits(int nocol) const
527{
528 if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL)
529 {
530 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
531 }
532 return noms_[nocol];
533}
534
535/*! \fn int DSOPHYA::FitsInFile::ColStringLengthFromFits(int nocol) const
536
537 \return number of characters of each data for the column number 'nocol' (if char* typed) of the current BINTABLE extension
538*/
539
540int FitsInFile::ColStringLengthFromFits(int nocol) const
541{
542 if(hdutype_ != ASCII_TBL && hdutype_ != BINARY_TBL)
543 {
544 throw IOExc("FitsFile::TypeFromFits, this HDU is not an ASCII table nor a binary table");
545 }
546 int index=-1;
547 int k;
548 for (k=0; k<=nocol; k++)
549 {
550 if (types_[k] == 'S') index++;
551 }
552 return taille_des_chaines_[index];
553}
554
555
556
557/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
558
559Get the NoLine-th 'line' from the current BINTABLE extension on FITS file,
560 */
561
562void FitsInFile::GetBinTabLine(int NoLine, double* ddata, float* fdata, int* idata, char ** cdata)
563{
564 int status= 0;
565 int anull;
566 double dnull= 0.;
567 float fnull= 0.;
568 int inull= 0;
569 char* cnull= "";
570 int dcount = 0.;
571 int fcount = 0.;
572 int icount = 0;
573 int ccount =0;
574 int ncol;
575 long nels=1;
576 for (ncol=0; ncol<nbcols_; ncol++)
577 {
578 switch (types_[ncol])
579 {
580 case 'D' :
581 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ddata[dcount++],&anull,&status);
582 break;
583 case 'E' :
584 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[fcount++],&anull,&status);
585 break;
586 case 'I' :
587 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&idata[icount++],
588 &anull,&status);
589 break;
590 case 'S' :
591 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&cdata[ccount++],&anull,&status);
592 break;
593 }
594 if (status)
595 {
596 ResetStatus(status);
597 break;
598 }
599 }
600}
601
602/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(long NoLine, BnTblLine& ligne)
603Get the NoLine-th 'line' from the current BINTABLE extension on FITS file,
604*/
605void FitsInFile::GetBinTabLine(long NoLine, BnTblLine& ligne)
606{
607 int status= 0;
608 int anull;
609 double dnull= 0.;
610 float fnull= 0.;
611 int inull= 0;
612 char* cnull= "";
613 int dcount = 0.;
614 int fcount = 0.;
615 int icount = 0;
616 int ccount =0;
617 int ncol;
618 long nels=1;
619 for (ncol=0; ncol<nbcols_; ncol++)
620 {
621 switch (types_[ncol])
622 {
623 case 'D' :
624 fits_read_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1,&dnull,&ligne.ddata_[dcount++],&anull,&status);
625 break;
626 case 'E' :
627 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&ligne.fdata_[fcount++],&anull,&status);
628 break;
629 case 'I' :
630 fits_read_col(fptr_,TINT,ncol+1,NoLine+1,1,1,&inull,&ligne.idata_[icount++],
631 &anull,&status);
632 break;
633 case 'S' :
634 char* chaine = new char[taille_des_chaines_[ccount]];
635 fits_read_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1,cnull,&chaine,&anull,&status);
636 ligne.cdata_[ccount++] = string(chaine);
637 break;
638 }
639 if (status)
640 {
641 ResetStatus(status);
642 break;
643 }
644 }
645}
646
647/*! \fn void SOPHYA::FitsInFile::GetBinTabLine(int NoLine, float* fdata)
648
649Get the NoLine-th float 'line' from the current BINTABLE extension on FITS file,
650*/
651void FitsInFile::GetBinTabLine(int NoLine, float* fdata)
652{
653 int status= 0;
654 int anull;
655 float fnull= 0.;
656 long nels=1;
657 int ncol;
658 for (ncol=0; ncol<nbcols_; ncol++)
659 {
660 fits_read_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1,&fnull,&fdata[ncol],&anull,&status);
661 if (status)
662 {
663 ResetStatus(status);
664 break;
665 }
666 }
667}
668
669
670/*! \fn void SPOPHYA::FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
671
672fill the array 'valeurs' with double data from the current BINTABLE extension on FITS file, from column number 'NoCol'
673
674\param <nentries> number of data to be read
675*/
676void FitsInFile::GetBinTabFCol(double* valeurs,int nentries, int NoCol) const
677 {
678 int status= 0;
679 int DTYPE;
680 long repeat,width;
681 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
682 if( DTYPE != TDOUBLE)
683 {
684 if (DTYPE == TFLOAT) cout << " WARNING: reading double from float : conversion will be made by fitsio library" << endl;
685 else
686 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non double");
687 }
688 long nels=nentries;
689 int anull;
690 // no checking for undefined pixels
691 double dnull= 0.;
692 // fits_read_key(fptr_,TDOUBLE,"BAD_DATA",&dnull,NULL,&status);
693 // if (status != 0)
694 // {
695 // dnull = -1.6375e30; // default value
696 // status = 0;
697 // }
698 if (nentries != nrows_*repeat)
699 {
700 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat << endl;
701 throw PException(" FitsFile:::GetBinTabFCol ");
702 }
703 fits_read_col(fptr_,TDOUBLE,NoCol+1,1,1,nels,&dnull,valeurs,
704 &anull,&status);
705 if( status ) printerror( status,"erreur lecture de colonne" );
706
707 }
708
709/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
710
711 same as previous method with float data
712*/
713void FitsInFile::GetBinTabFCol(float* valeurs,int nentries, int NoCol) const
714 {
715 int status= 0;
716 int DTYPE;
717 long repeat,width;
718 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
719 if( DTYPE != TFLOAT)
720 {
721 if (DTYPE == TDOUBLE) cout << " WARNING: reading float from double : conversion will be made by fitsio library" << endl;
722 else
723 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non float");
724 }
725 long nels=nentries;
726 int anull;
727 // no checking for undefined pixels
728 float fnull= 0.;
729 // fits_read_key(fptr_,TFLOAT,"BAD_DATA",&fnull,NULL,&status);
730 // if (status != 0)
731 // {
732 // fnull = -1.6375e30; // default value
733 // status = 0;
734 // }
735 if (nentries != nrows_*repeat)
736 {
737 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat << endl;
738 throw PException(" FitsFile:::GetBinTabFCol ");
739 }
740 fits_read_col(fptr_,TFLOAT,NoCol+1,1,1,nels,&fnull,valeurs,
741 &anull,&status);
742 if( status ) printerror( status,"erreur lecture de colonne" );
743 }
744
745/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
746
747 same as previous method with int data
748*/
749
750void FitsInFile::GetBinTabFCol(int* valeurs,int nentries, int NoCol) const
751 {
752 int status= 0;
753 int DTYPE;
754 long repeat,width;
755 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
756 if( DTYPE != TLONG && DTYPE != TINT && DTYPE != TSHORT )
757 {
758 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non entier");
759 }
760 long nels=nentries;
761 // no checking for undefined pixels
762 int anull;
763 int inull= 0;
764 // fits_read_key(fptr_,TINT,"BAD_DATA",&inull,NULL,&status);
765 // if (status != 0)
766 // {
767 // inull = -999999; // default value
768 // status = 0;
769 // }
770 if (nentries != nrows_*repeat)
771 {
772 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat << endl;
773 throw PException(" FitsFile:::GetBinTabFCol ");
774 }
775 fits_read_col(fptr_,TINT,NoCol+1,1,1,nels,&inull,valeurs,
776 &anull,&status);
777 if( status ) printerror( status,"erreur lecture de colonne" );
778 }
779
780/*! \fn void SOPHYA::FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
781
782 same as previous method with char* data
783*/
784
785void FitsInFile::GetBinTabFCol(char** valeurs, int nentries, int NoCol) const
786 {
787 int status= 0;
788 int DTYPE;
789 long repeat,width;
790 fits_get_coltype(fptr_, NoCol+1,&DTYPE,&repeat,&width,&status);
791 if( DTYPE != TSTRING )
792 {
793 throw IOExc("FitsFile::GetBinTabFCol, tentative de lecture non float");
794 }
795 long nels=nentries;
796 // no checking for undefined pixels
797 int anull;
798 char* cnull= "";
799 if (nentries != nrows_*repeat/width)
800 {
801 cout << " found " << nentries << " pixels, expected: " << nrows_*repeat/width << endl;
802 throw PException(" FitsFile:::GetBinTabFCol ");
803 }
804 long frow=1;
805 long felem=1;
806 fits_read_col(fptr_,TSTRING,NoCol+1,frow,felem,nels,cnull,valeurs,
807 &anull,&status);
808 if( status ) printerror( status,"erreur lecture de colonne" );
809 }
810
811/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(double* map, int nentries) const
812fill the array 'map' with double data from the current extension on FITS file.
813If the extension is BINTABLE, the first column is provided.
814
815\param <nentries> number of data to be read
816*/
817void FitsInFile::GetSingleColumn(double* map, int nentries) const
818{
819 int status = 0;
820 if(hdutype_ == IMAGE_HDU)
821 {
822
823 if(bitpix_ != DOUBLE_IMG)
824 {
825 cout << " The data type on fits file is not double...";
826 cout << " Conversion to double achieved by cfitsio lib" << endl;
827 }
828
829 // no checking for undefined pixels
830 int anull;
831 double dnull= 0.;
832
833 long nels= nentries;
834 fits_read_img(fptr_,TDOUBLE,1,nels,&dnull,map,&anull,&status);
835 if( status ) printerror( status );
836 }
837 else
838 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
839 {
840 GetBinTabFCol(map,nentries, 0);
841 }
842 else
843 {
844 cout << " hdutype= " << hdutype_ << endl;
845 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
846 }
847}
848
849/*! \fn void SOPHYA::FitsInFile::GetSingleColumn(float* map, int nentries) const
850same as above with float data
851*/
852void FitsInFile::GetSingleColumn(float* map, int nentries) const
853{
854 int status = 0;
855 if(hdutype_ == IMAGE_HDU)
856 {
857 if(bitpix_ != FLOAT_IMG)
858 {
859 cout << " The data type on fits file is not float ";
860 cout << " Conversion to float achieved by cfitsio lib" << endl;
861 }
862 // no checking for undefined pixels
863 int anull;
864 float fnull= 0.;
865
866 long nels= nentries;
867 fits_read_img(fptr_,TFLOAT,1,nels,&fnull, map,&anull,&status);
868 if( status ) printerror( status );
869 }
870 else
871 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
872 {
873 GetBinTabFCol(map,nentries, 0);
874 }
875 else
876 {
877 cout << " hdutype= " << hdutype_ << endl;
878 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
879 }
880}
881
882/*! \fn void SOPHYA::FitsInFile::GetSingleColumn( int* map, int nentries) const
883 same as above with int data
884*/
885void FitsInFile::GetSingleColumn( int* map, int nentries) const
886{
887 int status = 0;
888 if(hdutype_ == IMAGE_HDU)
889 {
890 if(bitpix_ != LONG_IMG)
891 {
892 cout << " The data type on fits file is not int ";
893 cout << " Conversion to float achieved by cfitsio lib" << endl;
894 }
895 // no checking for undefined pixels
896 int anull;
897 float fnull= 0.;
898
899 long nels= nentries;
900 fits_read_img(fptr_,TINT,1,nels,&fnull,map,&anull,&status);
901 if( status ) printerror( status );
902 }
903 else
904 if(hdutype_ == ASCII_TBL || hdutype_ == BINARY_TBL)
905 {
906 GetBinTabFCol(map,nentries, 0);
907 }
908 else
909 {
910 cout << " hdutype= " << hdutype_ << endl;
911 throw IOExc("FitsFile::GetSingleColumn this HDU is unknown");
912 }
913}
914
915void FitsInFile::GetBinTabParameters(fitsfile* fileptr, int& nbcols, int& nrows,
916 vector<int>& repeat,
917 vector<string>& noms,
918 vector<char>& types,
919 vector<int>& taille_des_chaines)
920{
921 int status= 0;
922 int hdunum=0;
923 int hdutype=0;
924 fits_get_hdu_num(fileptr,&hdunum);
925 fits_get_hdu_type(fileptr, &hdutype, &status);
926
927 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
928 {
929 throw IOExc("FitsFile::GetBinTabParameters this HDU is not an ASCII table nor a binary table");
930 }
931 if(hdutype == ASCII_TBL)
932 cout << " Reading a FITS ascii table in HDU : " << hdunum << endl;
933 if(hdutype == BINARY_TBL)
934 cout << " Reading a FITS binary table in HDU : " << hdunum << endl;
935
936 // get the number of columns
937 fits_get_num_cols(fileptr, &nbcols,&status);
938 if( status ) printerror( status );
939
940 // get the number of rows
941 long naxis2= 0;
942 fits_get_num_rows(fileptr,&naxis2,&status);
943 if( status ) printerror( status );
944 nrows = (int)naxis2;
945
946 // get the datatype, names and the repeat count
947 noms.clear();
948 noms.reserve(nbcols);
949 types.clear();
950 types.reserve(nbcols);
951 repeat.clear();
952 repeat.reserve(nbcols);
953 taille_des_chaines.clear();
954 char **ttype = new char*[nbcols];
955 int ii;
956 //
957 //
958 for (ii=0; ii < nbcols; ii++) ttype[ii]=new char[FLEN_VALUE];
959 int nfound;
960 fits_read_keys_str(fileptr, "TTYPE",1,nbcols,ttype,&nfound, &status);
961 if( status ) printerror( status,"erreur lecture des noms de colonne");
962 int rept=0;
963 for(ii = 0; ii < nbcols; ii++)
964 {
965 int DTYPE;
966 long width;
967 long repete = 0;
968 fits_get_coltype(fileptr,ii+1,&DTYPE,&repete,&width,&status);
969 if( status ) printerror( status,"erreur lecture type de colonne");
970 rept = repete;
971 noms.push_back(string(ttype[ii]));
972 switch (DTYPE)
973 {
974 case TDOUBLE :
975 types.push_back('D');
976 break;
977 case TFLOAT :
978 types.push_back('E');
979 break;
980 case TLONG :
981 types.push_back('I');
982 break;
983 case TINT :
984 types.push_back('I');
985 break;
986 case TSHORT :
987 types.push_back('I');
988 break;
989 case TSTRING :
990 types.push_back('S');
991 taille_des_chaines.push_back(width);
992 rept/=width;
993 break;
994 default :
995 cout << " field " << ii+1 << " DTYPE= " << DTYPE << endl;
996 throw IOExc("FitsFile:: unknown type of field");
997 }
998 repeat.push_back(rept);
999 }
1000 for (ii=0; ii < nbcols; ii++) delete [] ttype[ii];
1001 delete [] ttype;
1002}
1003
1004void FitsInFile::KeywordsIntoDVList(fitsfile* fileptr, DVList& dvl, int hdunum)
1005{
1006 int status = 0;
1007 int hdutype;
1008 fits_movabs_hdu(fileptr,hdunum,&hdutype,&status);
1009 if( status ) printerror( status,":KeywordsIntoDVList : erreur movabs");
1010 // get number of keywords
1011 int nkeys,keypos;
1012 fits_get_hdrpos(fileptr,&nkeys,&keypos,&status);
1013 if( status ) printerror( status );
1014
1015 // put keywords in a DVList object
1016 char keyname[LEN_KEYWORD]= "";
1017 char strval[FLEN_VALUE]= "";
1018 char dtype;
1019 char card[FLEN_CARD];
1020 char *comkey = "COMMENT";
1021 char comment[FLEN_COMMENT];
1022
1023 // shift with the number of mandatory keywords
1024 // int num= 8;
1025 int num= 0;
1026 // primary header
1027 if (hdunum == 1)
1028 {
1029 // read NAXIS
1030 int naxis=0;
1031 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1032 // number of mandatory keywords
1033 num = naxis+3;
1034 }
1035 // extensions
1036 else
1037 {
1038 if (hdutype == IMAGE_HDU)
1039 {
1040 // read NAXIS
1041 int naxis=0;
1042 fits_read_key(fileptr,TINT,"NAXIS",&naxis,NULL,&status);
1043 // number of mandatory keywords
1044 num = naxis+5;
1045 }
1046 else
1047 if(hdutype == ASCII_TBL || hdutype == BINARY_TBL)
1048 {
1049 // number of mandatory keywords
1050 num = 8;
1051 }
1052 }
1053 int j;
1054 for(j = num+1; j <= nkeys; j++)
1055 {
1056 fits_read_keyn(fileptr,j,card,strval,NULL,&status);
1057 if(status) printerror(status);
1058
1059 strncpy(keyname,card,LEN_KEYWORD-1);
1060 if(strncmp(keyname,comkey,LEN_KEYWORD-1) != 0 && strlen(keyname) != 0
1061 && strlen(strval) != 0)
1062 {
1063 fits_get_keytype(strval,&dtype,&status);
1064 if(status) printerror(status);
1065
1066 strip(keyname, 'B',' ');
1067 strip(strval, 'B',' ');
1068 strip(strval, 'B','\'');
1069
1070 switch( dtype )
1071 {
1072 case 'C':
1073 fits_read_key(fileptr,TSTRING,keyname,strval,comment,&status);
1074 dvl[keyname]= strval;
1075 dvl.SetComment(keyname, comment);
1076 break;
1077 case 'I':
1078 int ival;
1079 fits_read_key(fileptr,TINT,keyname,&ival,comment,&status);
1080 dvl[keyname]= (int_4) ival; // Portage mac DY
1081 dvl.SetComment(keyname, comment);
1082 break;
1083 case 'L':
1084 int ilog;
1085 fits_read_key(fileptr,TLOGICAL,keyname,&ilog,comment,&status);
1086 dvl[keyname]= (int_4) ilog;
1087 dvl.SetComment(keyname, comment);
1088 break;
1089 case 'F':
1090 double dval;
1091 fits_read_key(fileptr,TDOUBLE,keyname,&dval,comment,&status);
1092 dvl[keyname]= dval;
1093 dvl.SetComment(keyname, comment);
1094 break;
1095 }
1096
1097 }
1098 }
1099 // dvl_.Print();
1100}
1101
1102
1103/*!
1104 \class SOPHYA::FitsOutFile
1105 Class for loading SOPHYA objects from FITS Format Files (uses cfitsio lib)
1106*/
1107
1108FitsOutFile::FitsOutFile()
1109{
1110 InitNull();
1111}
1112
1113 /*! \fn SOPHYA::FitsOutFile::FitsOutFile(char flnm[], WriteMode wrm)
1114
1115\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)
1116
1117 */
1118
1119FitsOutFile::FitsOutFile(string const & flnm, WriteMode wrm)
1120{
1121 InitNull();
1122 openoutputfitsfile(flnm.c_str(), wrm);
1123}
1124
1125FitsOutFile::FitsOutFile(const char * flnm, WriteMode wrm)
1126{
1127 InitNull();
1128 openoutputfitsfile(flnm, wrm);
1129}
1130
1131void FitsOutFile::openoutputfitsfile(const char * flnm, WriteMode wrm)
1132{
1133 int status = 0;
1134
1135 // create new FITS file
1136 fits_create_file(&fptr_,flnm,&status);
1137 if( status )
1138 {
1139
1140 switch (wrm)
1141 {
1142 // si on veut ecrire a la fin de ce fichier
1143 case append :
1144 status = 0;
1145 fits_clear_errmsg();
1146 fits_open_file(&fptr_,flnm,READWRITE,&status);
1147 if( status )
1148 {
1149 cout << " error opening file: " << flnm << endl;
1150 printerror(status, "failure opening a file supposed to exist");
1151 }
1152 else cout << " file " << flnm << " opened, new objects will be appended " << endl;
1153 fits_get_num_hdus(fptr_, &hdunum_, &status);
1154 int hdutype;
1155 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1156 if( status ) printerror( status,":FitsFile::WriteF : erreur movabs");
1157 break;
1158
1159 case clear :
1160 {
1161 status = 0;
1162 fits_clear_errmsg();
1163 char* newname = new char[strlen(flnm)+1];
1164 //
1165 newname[0] = '!';
1166 newname[1] = '\0';
1167 strcat(newname, flnm);
1168 fits_create_file(&fptr_,newname,&status);
1169 delete [] newname;
1170 if (status)
1171 {
1172 cout << " error opening file: " << flnm << endl;
1173 printerror(status, "unable to open file, supposed to exist");
1174 }
1175 else cout << " WARNING : file " << flnm << " is overwritten " << endl;
1176 break;
1177 }
1178 case unknown :
1179 printerror(status, " file seems already to exist");
1180 break;
1181
1182 }
1183 }
1184}
1185
1186
1187
1188/*! \fn void SOPHYA::FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList &dvl)
1189
1190create an IMAGE header on FITS file.
1191\param <type> type of data (see method ColTypeFromFits)
1192\param <nbdim> number of dimensions : 1D, 2D, 3D etc. = NAXIS
1193\param <naxisn> array containind sizes of the different dimensions
1194*/
1195void FitsOutFile::makeHeaderImageOnFits(char type, int nbdim, int* naxisn, DVList* ptr_dvl)
1196{
1197 int status = 0;
1198 long naxis = nbdim;
1199 long* naxes = new long[nbdim];
1200 bool hdunfirst= (hdunum_ == 0);
1201 if (hdunfirst)
1202 {
1203 if (imageOnPrimary_ == false)
1204 {
1205 hdunum_ = 1;
1206 fits_create_img(fptr_,FLOAT_IMG,0,naxes,&status);
1207 }
1208 }
1209 int k;
1210 for (k=0; k< nbdim; k++) naxes[k] = (long)naxisn[k];
1211 if (type == 'D')
1212 fits_create_img(fptr_,DOUBLE_IMG,naxis,naxes,&status);
1213 else
1214 if (type == 'E')
1215 fits_create_img(fptr_,FLOAT_IMG,naxis,naxes,&status);
1216 else
1217 if (type == 'I')
1218 fits_create_img(fptr_,LONG_IMG,naxis,naxes,&status);
1219 else
1220 {
1221 cout << " type of data: " << type << endl;
1222 throw PException("FitsFile:::makeHeaderImageOnFits:unprogrammed type of data ");
1223 }
1224 // on ajoute eventuellement un dvlist prepare et la doc SOPHYA
1225 hdunum_++;
1226 if (hdunfirst)
1227 {
1228 addDVListOnPrimary();
1229 writeSignatureOnFits(1);
1230 }
1231
1232 // write supplementary keywords
1233 // dvl.Print();
1234 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
1235
1236 delete [] naxes;
1237 if( status ) printerror( status, "erreur creation HDU IMAGE" );
1238
1239}
1240
1241
1242/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, double* map) const
1243
1244write double data from array 'map'on an IMAGE extension
1245\param <nbData> number of data to be written
1246*/
1247void FitsOutFile::PutImageToFits(int nbData, double* map) const
1248{
1249 int status = 0;
1250 long npix= nbData;
1251 fits_write_img(fptr_,TDOUBLE,1,npix,map,&status);
1252 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1253}
1254
1255/*! \fn void SOPHYA::FitsOutFile::PutImageToFits(int nbData, float* map) const
1256
1257same as previous method with float data
1258*/
1259void FitsOutFile::PutImageToFits(int nbData, float* map) const
1260{
1261 int status = 0;
1262 long npix= nbData;
1263 fits_write_img(fptr_,TFLOAT,1,npix, map,&status);
1264 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1265
1266}
1267
1268 /*! \fn void SOPHYA::FitsOutFile::PutImageToFits( int nbData, int* map) const
1269
1270 same as previous method with int data */
1271void FitsOutFile::PutImageToFits( int nbData, int* map) const
1272{
1273 int status = 0;
1274
1275 long npix= nbData;
1276 fits_write_img(fptr_,TINT,1,npix,map,&status);
1277 if( status ) printerror( status, "erreur ecriture PutImageToFits" );
1278}
1279
1280
1281
1282/*! \fn void SOPHYA::FitsOutFile::makeHeaderBntblOnFits( string fieldType, vector<string> Noms, int nentries, int tfields, DVList &dvl, string extname, vector<int> taille_des_chaines)
1283
1284create an BINTABLE header on FITS file.
1285\param <fieldType> array conta
1286ining characters denoting types of the different column (see method ColTypeFromFits)
1287\param <Noms> array of the names of columns
1288\param <nentries> number of data of each column
1289\param <tfields> number of columns
1290\param <dvl> a SOPHYA DVList containing keywords to be appended
1291\param <extname> keyword EXTNAME for FITS file
1292\param <taille_des_chaines> vector containing the number of characters of data for each char* typed column, with order of appearance in 'fieldType'
1293*/
1294void FitsOutFile::makeHeaderBntblOnFits( string fieldType, vector<string> Noms, int nentries, int tfields, DVList* ptr_dvl, string extname, vector<int> taille_des_chaines)
1295{
1296 int k;
1297 int status = 0;
1298 long nrows;
1299 // verifications de coherence
1300
1301 if (fieldType.length() != tfields)
1302 {
1303 cout << " nombre de champs :" << tfields << "nombre de types: " << fieldType.length() << endl;
1304 throw ParmError("FitsFile:: fields and types don't match");
1305
1306 }
1307 if (tfields > Noms.size())
1308 {
1309 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of column names not equal to total number of columns" << endl;
1310 for (k=0; k<(tfields-Noms.size()); k++) Noms.push_back( string(" "));
1311 }
1312
1313 // nombre de variables "chaines de caracteres"
1314 int nbString = 0;
1315 for (k=0; k<tfields;k++) if (fieldType[k] == 'A') nbString++;
1316 // coherence de la longueur du vecteur des tailles
1317 if (nbString > taille_des_chaines.size())
1318 {
1319 cout << " WARNING: FitsOutFile::makeHeaderBntblOnFits, length of vector of string lengths not equal to total number of columns" << endl;
1320 int strSz=0;
1321 for (k=0; k<taille_des_chaines.size(); k++) if ( taille_des_chaines[k] > strSz) strSz = taille_des_chaines[k];
1322 for (k=0; k<(nbString-taille_des_chaines.size()); k++) taille_des_chaines.push_back(strSz);
1323 }
1324 char ** ttype= new char*[tfields];
1325 char ** tform= new char*[tfields];
1326 char largeur[FLEN_VALUE];
1327 int noColString=0;
1328 for (k=0; k<tfields;k++)
1329 {
1330 char format[FLEN_VALUE];
1331
1332 if(nentries < 1024)
1333 {
1334 nrows= nentries;
1335 if (fieldType[k] == 'A')
1336 {
1337 sprintf(largeur,"%d",taille_des_chaines[noColString++]);
1338 strcpy(format,largeur);
1339 }
1340 else strcpy(format,"1");
1341 }
1342 else
1343 {
1344 nrows = nentries/1024;
1345 if(nentries%1024 != 0) nrows++;
1346 if (fieldType[k] == 'A')
1347 {
1348 char largaux[FLEN_VALUE];
1349 sprintf(largeur,"%d",taille_des_chaines[noColString]);
1350 sprintf(largaux,"%d",1024*taille_des_chaines[noColString]);
1351 noColString++;
1352 strcpy(format, largaux);
1353 }
1354 else strcpy(format,"1024");
1355 }
1356 strncat(format,&fieldType[k],1);
1357 if (fieldType[k] == 'A')
1358 {
1359 strcat(format,largeur);
1360 }
1361 ttype[k] = const_cast<char*>(Noms[k].c_str());
1362 tform[k]= new char[FLEN_VALUE];
1363 strcpy(tform[k],format);
1364 }
1365 char* extn = const_cast<char*>(extname.c_str());
1366
1367 // create a new empty binary table onto the FITS file
1368 // physical units if they exist, are defined in the DVList object
1369 // so the NULL pointer is given for the tunit parameters.
1370 nrows=0;
1371 fits_create_tbl(fptr_,BINARY_TBL,nrows,tfields,ttype,tform,
1372 NULL,extn,&status);
1373 if( status ) printerror( status );
1374 // on ajoute eventuellement un dvlist prepare
1375 if ( hdunum_ == 0 )
1376 {
1377 hdunum_ = 2;
1378 addDVListOnPrimary();
1379 writeSignatureOnFits(1);
1380 }
1381 else hdunum_++;
1382 int ii;
1383 for(ii = 0; ii < tfields; ii++)
1384 {
1385 delete [] tform[ii];
1386 }
1387 delete [] ttype;
1388 delete [] tform;
1389 //
1390 // write supplementary keywords
1391 if (ptr_dvl != NULL) addKeywordsOfDVList(*ptr_dvl);
1392}
1393
1394/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
1395
1396write double data from array 'donnees ' on column number 'nocol' of a BINTABLE extension.
1397\param <nentries> number of data to be written
1398*/
1399void FitsOutFile::PutColToFits(int nocol, int nentries, double* donnees) const
1400{
1401 int status = 0;
1402 int hdutype;
1403 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1404 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1405 fits_get_hdu_type(fptr_, &hdutype, &status);
1406 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1407 {
1408 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1409 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1410 }
1411 int code;
1412 long repeat, width;
1413 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1414 if( code != TDOUBLE)
1415 {
1416 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " to be written= DOUBLE " << endl;
1417 }
1418 fits_write_col(fptr_,TDOUBLE,nocol+1,1,1,nentries, donnees ,&status);
1419 if( status ) printerror( status,"erreur ecriture du fichier fits" );
1420}
1421
1422
1423
1424 /*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
1425
1426same as previous method with float data
1427*/
1428void FitsOutFile::PutColToFits(int nocol, int nentries, float* donnees) const
1429{
1430 int status = 0;
1431 int hdutype;
1432 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1433 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1434 fits_get_hdu_type(fptr_, &hdutype, &status);
1435 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1436 {
1437 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1438 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1439 }
1440 if(hdutype == ASCII_TBL && nocol>0)
1441 {
1442 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1443 }
1444 int code;
1445 long repeat, width;
1446 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1447 if( code != TFLOAT)
1448 {
1449 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= FLOAT " << endl;
1450 }
1451 fits_write_col(fptr_,TFLOAT,nocol+1,1,1,nentries, donnees ,&status);
1452 if( status ) printerror( status,"erreur ecriture du fichier fits" );
1453}
1454
1455
1456/*! \fn void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
1457
1458same as previous method with int data
1459*/
1460void FitsOutFile::PutColToFits(int nocol, int nentries, int* donnees) const
1461{
1462 int status = 0;
1463 int hdutype;
1464 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1465 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1466 fits_get_hdu_type(fptr_, &hdutype, &status);
1467 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1468 {
1469 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1470 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1471 }
1472 if(hdutype == ASCII_TBL && nocol>0)
1473 {
1474 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1475 }
1476 int code;
1477 long repeat, width;
1478 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1479 if( code != TLONG && code != TINT && code != TSHORT )
1480 {
1481 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= INT " << endl;
1482 }
1483 fits_write_col(fptr_,TINT,nocol+1,1,1,nentries, donnees ,&status);
1484 if( status ) printerror( status," ecriture du fichier fits" );
1485}
1486
1487
1488/*! \fn void SOPHYA::FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1489same as previous method with char* data
1490*/
1491void FitsOutFile::PutColToFits(int nocol, int nentries, char** donnees) const
1492{
1493 int status = 0;
1494 int hdutype;
1495 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1496 if( status ) printerror(status,"PutColToFits: le movabs a foire");
1497 fits_get_hdu_type(fptr_, &hdutype, &status);
1498 if(hdutype != ASCII_TBL && hdutype != BINARY_TBL)
1499 {
1500 cout << " hdunum= " << hdunum_ << " hdutype= " << hdutype << endl;
1501 throw IOExc("FitsFile::PutColToFits, this HDU is not an ASCII table nor a binary table");
1502 }
1503 if(hdutype == ASCII_TBL && nocol>0)
1504 {
1505 throw IOExc("FitsFile::PutColToFits, this HDU is an ASCII table, nocol>0 forbidden");
1506 }
1507 int code;
1508 long repeat, width;
1509 fits_get_coltype(fptr_, nocol+1, &code, &repeat,&width, &status);
1510 if( code != TSTRING)
1511 {
1512 cout << " WARNING : types don't match (PutColToFits) : on fits file= " << code << " (FITS code), to be written= char** " << endl;
1513 }
1514 fits_write_col(fptr_,TSTRING,nocol+1,1,1,nentries, donnees ,&status);
1515 if( status ) printerror( status,"erreur ecriture du fichier fits" );
1516}
1517
1518void FitsOutFile::PutBinTabLine(long NoLine, BnTblLine& ligne) const
1519{
1520 // on ne fait pas de verification de type, ni de dimension ici, pour
1521 // des raisons de performances
1522 int k;
1523 int status= 0;
1524 int anull;
1525 int ncol=0;
1526 long nels=1;
1527 // int nbcols;
1528 // fits_get_num_cols(fptr_, &nbcols,&status);
1529 for (k=0; k<ligne.ddata_.size(); k++, ncol++)
1530 {
1531 fits_write_col(fptr_,TDOUBLE,ncol+1,NoLine+1,1,1, &ligne.ddata_[k] ,&status);
1532 if( status ) printerror( status, "PutBinTabLine : erreur ecriture double" );
1533 }
1534 for (k=0; k<ligne.fdata_.size(); k++, ncol++)
1535 {
1536 fits_write_col(fptr_,TFLOAT,ncol+1,NoLine+1,1,1, &ligne.fdata_[k] ,&status);
1537 if( status ) printerror( status, "PutBinTabLine : erreur ecriture float" );
1538 }
1539 for (k=0; k<ligne.idata_.size(); k++, ncol++)
1540 {
1541 fits_write_col(fptr_,TINT,ncol+1,NoLine+1,1,1, &ligne.idata_[k] ,&status);
1542 if( status ) printerror( status, "PutBinTabLine : erreur ecriture entier" );
1543 }
1544
1545 for (k=0; k<ligne.cdata_.size(); k++, ncol++)
1546 {
1547 fits_write_col(fptr_,TSTRING,ncol+1,NoLine+1,1,1, (void*)ligne.cdata_[k].c_str() ,&status);
1548 if( status ) printerror( status, "PutBinTabLine : erreur ecriture caracteres" );
1549 }
1550}
1551
1552
1553/* \fn void SOPHYA::FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl) const
1554
1555Put keywords from a DVList into the primary header of the fits-file
1556*/
1557void FitsOutFile::DVListIntoPrimaryHeader(DVList& dvl)
1558{
1559 int status = 0;
1560 int hdutype;
1561 if (hdunum_ == 0)
1562 {
1563 if (dvlToPrimary_ == NULL) dvlToPrimary_ = new DVList(dvl);
1564 else dvlToPrimary_->Merge(dvl);
1565 }
1566 else
1567 {
1568 fits_movabs_hdu(fptr_,1,&hdutype,&status);
1569 addKeywordsOfDVList(dvl);
1570 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1571 }
1572}
1573
1574
1575void FitsOutFile::writeSignatureOnFits(int hdunum) const
1576{
1577 int status = 0;
1578 int hdutype;
1579 char keyname[LEN_KEYWORD];
1580 char strval[FLEN_VALUE];
1581 char comment[FLEN_COMMENT];
1582 if (hdunum_ == 0)
1583 {
1584 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
1585 return;
1586 }
1587 fits_movabs_hdu(fptr_,1,&hdutype,&status);
1588 //
1589 strncpy(keyname, "CREATOR", LEN_KEYWORD);
1590 keyname[LEN_KEYWORD-1] = '\0';
1591 strcpy(strval, "SOPHYA");
1592 strcpy(comment," SOPHYA Package - FITSIOServer ");
1593 fits_write_key(fptr_, TSTRING, keyname, &strval, comment, &status);
1594 if( status ) printerror( status );
1595 fits_write_date(fptr_, &status);
1596 fits_write_comment(fptr_,"..............................................", &status);
1597 fits_write_comment(fptr_, " SOPHYA package - FITSIOSever ", &status);
1598 fits_write_comment(fptr_, " (C) LAL/IN2P3-CNRS Orsay, FRANCE 2000", &status);
1599 fits_write_comment(fptr_, " (C) DAPNIA/CEA Saclay, FRANCE 2000", &status);
1600 fits_write_comment(fptr_,"..............................................", &status);
1601 if( status ) printerror( status, "erreur writeSignatureOnFits" );
1602 //
1603 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1604}
1605
1606
1607void FitsOutFile::addKeywordsOfDVList( DVList& dvl) const
1608{
1609 int status = 0;
1610 fits_write_comment(fptr_,"---------- keywords from SOPHYA ---------", &status);
1611 DVList::ValList::const_iterator it;
1612 for(it = dvl.Begin(); it != dvl.End(); it++)
1613 {
1614 char keytype= (*it).second.elval.typ;
1615 char keyname[10];
1616 strncpy(keyname,(*it).first.substr(0,64).c_str(),10);
1617 string key(keyname);
1618 char comment[FLEN_COMMENT];
1619 char strval[FLEN_VALUE]= "";
1620 char *comkey = "COMMENT";
1621 fits_read_keyword(fptr_, keyname, strval, NULL, &status);
1622 if (status != 0 || strncmp(keyname,comkey,LEN_KEYWORD-1) == 0 )
1623 {
1624 string coco = dvl.GetComment(key);
1625 coco.copy( comment, FLEN_COMMENT-1);
1626 int bout = (coco.length() < FLEN_COMMENT) ? coco.length() : FLEN_COMMENT-1;
1627 comment[bout]= '\0';
1628 status = 0;
1629 switch (keytype)
1630 {
1631 case 'I' :
1632 {
1633 int ival = (int)dvl.GetI(key);
1634 fits_write_key(fptr_,TINT,keyname,&ival, comment,&status);
1635 break;
1636 }
1637 case 'D' :
1638 {
1639 double dval= (double)dvl.GetD(key);
1640 fits_write_key(fptr_,TDOUBLE,keyname,&dval,comment,&status);
1641 break;
1642 }
1643 case 'S' :
1644 {
1645 char strvaleur[FLEN_VALUE]= "";
1646 string valChaine = dvl.GetS(key);
1647 valChaine.copy(strvaleur, FLEN_VALUE-1);
1648 int fin = (valChaine.length() < FLEN_VALUE) ? valChaine.length() : FLEN_VALUE-1;
1649 strvaleur[fin]= '\0';
1650
1651 fits_write_key(fptr_,TSTRING,keyname,&strvaleur,comment,&status);
1652 break;
1653 }
1654 }
1655 }
1656 if( status ) printerror( status,"fitsfile: probleme ecriture mot-cle du dvlist" );
1657 }
1658 fits_write_comment(fptr_,"--------------------------------------", &status);
1659}
1660
1661
1662void FitsOutFile::addDVListOnPrimary()
1663 {
1664 int status = 0;
1665 int hdutype;
1666 if (hdunum_ == 0)
1667 {
1668 cerr << " WARNING : can't write keywords on non existing primary header" << endl;
1669 return;
1670 }
1671 if (dvlToPrimary_ != NULL)
1672 {
1673 fits_movabs_hdu(fptr_,1,&hdutype,&status);
1674 addKeywordsOfDVList(*dvlToPrimary_);
1675 delete dvlToPrimary_;
1676 dvlToPrimary_ = NULL;
1677 fits_movabs_hdu(fptr_,hdunum_,&hdutype,&status);
1678 }
1679 }
1680
Note: See TracBrowser for help on using the repository browser.