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

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

classe FITS_AutoReader

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