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

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

suppression strdup

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