source: Sophya/trunk/SophyaExt/FitsIOServer/fitsinoutfile.cc@ 2907

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

1/ Ajout methode CheckReadability() , retour int pour CheckHandling() ds l'interface FitsHandler et propagation vers handler TArray et DataTable
2/ Correction dans FitsManager et ajout initialiseur de module FitsIOServer (fiosinit.h .cc)
3/ FitsSwapper complete - corrige - full template (suppression de fitsswapper.cc)
4/ MAJ Makefile et objlist.list suite ajout fiosinit.cc et swfitsdtable

Reza , 2 Jan 2006

  • Property svn:executable set to *
File size: 17.1 KB
Line 
1#include "sopnamsp.h"
2#include "machdefs.h"
3#include "segdatablock.h"
4#include "fitsinoutfile.h"
5#include <stdio.h>
6#include <string.h>
7#include <iostream>
8
9string FitsTypes::ImageTypeToTypeString(int ityp)
10{
11 switch (ityp) {
12 case BYTE_IMG :
13 return "uint_1";
14 break;
15 case SHORT_IMG :
16 return "int_2";
17 break;
18 case LONG_IMG :
19 return "int_4";
20 break;
21 case FLOAT_IMG :
22 return "r_4";
23 break;
24 case DOUBLE_IMG :
25 return "r_8";
26 break;
27 default:
28 return "???" ;
29 break;
30 }
31 return "";
32}
33string FitsTypes::DataTypeToTypeString(int ityp)
34{
35 switch (ityp) {
36 case TBYTE :
37 return "uint_1";
38 break;
39 case TSHORT :
40 return "int_2";
41 break;
42 case TUSHORT :
43 return "uint_2";
44 break;
45 case TINT :
46 if (sizeof(int) == 4) return "int_4";
47 else if (sizeof(int) == 8) return "int_8";
48 else if (sizeof(int) == 2) return "int_2";
49 break;
50 case TUINT :
51 if (sizeof(int) == 4) return "uint_4";
52 else if (sizeof(int) == 8) return "uint_8";
53 else if (sizeof(int) == 2) return "uint_2";
54 break;
55 case TLONG :
56 if (sizeof(long) == 4) return "int_4";
57 else if (sizeof(long) == 8) return "int_8";
58 else if (sizeof(long) == 2) return "int_2";
59 break;
60 case TULONG :
61 if (sizeof(long) == 4) return "uint_4";
62 else if (sizeof(long) == 8) return "uint_8";
63 else if (sizeof(long) == 2) return "uint_2";
64 break;
65#ifdef TLONGLONG
66 case TLONGLONG :
67 return "int_8";
68 break;
69#endif
70 case TFLOAT :
71 return "r_4";
72 break;
73 case TDOUBLE :
74 return "r_8";
75 break;
76 case TCOMPLEX :
77 return "complex< r_4 >";
78 break;
79 case TDBLCOMPLEX :
80 return "complex< r_8 >";
81 break;
82 case TSTRING :
83 return "string";
84 break;
85 default:
86 return "???" ;
87 break;
88 }
89 return "";
90}
91
92/*!
93 \class SOPHYA::FitsInOutFile
94 \ingroup FitsIOServer
95 \brief Wrapper class for cfitsio library functions
96*/
97
98/*-- Methode --*/
99//! Default constructor - The file should be opened subsequently using Open
100FitsInOutFile::FitsInOutFile()
101{
102 fptr_ = NULL;
103 mode_ = Fits_RO;
104 SetDef_BinTable();
105 SetDef_StrColWidth();
106}
107
108/*-- Methode --*/
109//! Constructor with specification of file name and access mode
110FitsInOutFile::FitsInOutFile(string const & name, FitsIOMode mode)
111{
112 // cout << " DBG - FitsInOutFile(string name= " << name << ")" << endl;
113 fptr_ = NULL;
114 ownfptr = true;
115 SetDef_BinTable();
116 SetDef_StrColWidth();
117 Open(name.c_str(), mode);
118}
119
120/*-- Methode --*/
121//! Constructor with specification of file name and access mode
122FitsInOutFile::FitsInOutFile(const char * name, FitsIOMode mode)
123{
124 // cout << " DBG - FitsInOutFile(char* name= " << name << ")" << endl;
125 fptr_ = NULL;
126 ownfptr = true;
127 SetDef_BinTable();
128 SetDef_StrColWidth();
129 Open(name, mode);
130}
131
132/*! \brief Copy constructor
133 \warning The fits file pointer is owned by the original FitsInOutFile object and
134 should not be closed as long as the new object is being used.
135*/
136FitsInOutFile::FitsInOutFile(FitsInOutFile const& fios)
137{
138 fptr_ = fios.fptr_;
139 fname_ = fios.fname_;
140 mode_ = fios.mode_;
141 ownfptr = false;
142 SetDef_BinTable();
143 SetDef_StrColWidth();
144}
145
146/* -- Fonction utilitaire pour verifier fichier ouvert (pointeur non null) -- */
147static inline void CheckFitsPtr(fitsfile* fptr) {
148 if (fptr == NULL) throw FitsIOException("FitsInOutFile/Error - NULL fitsfile pointer ");
149 return;
150}
151/* -- Fonction utilitaire pour verifier le code d'erreur fitsio -- */
152static inline bool FitsCheckStatus(int st, char * emsg = NULL) {
153 if (st) {
154 fits_report_error(stderr, st);
155 if (emsg) {
156 char buff[FLEN_ERRMSG];
157 fits_get_errstatus(st, buff);
158 string msg = emsg;
159 msg += buff;
160 throw FitsIOException(msg);
161 }
162 else return true;
163 }
164 else return false;
165}
166
167/*-- Methode --*/
168//! Destructor - Closes the fits file (if opened)
169FitsInOutFile::~FitsInOutFile()
170{
171 Close();
172}
173
174/*-- Methode --*/
175//! Opens the named fits file (see cfitsio routines fits_open_file and fits_create_file)
176void FitsInOutFile::Open(const char* name, FitsIOMode mode)
177{
178 if (fptr_ != NULL)
179 throw FitsIOException("FitsInOutFile::Open() /Error - file already opened ");
180 int status = 0;
181 fptr_ = NULL;
182 switch ( mode ) {
183 case Fits_RO :
184 fits_open_file(&fptr_, name, READONLY, &status);
185 break;
186 case Fits_RW :
187 fits_open_file(&fptr_, name, READWRITE, &status);
188 break;
189 case Fits_Create :
190 fits_create_file(&fptr_, name, &status);
191 break;
192 }
193 FitsCheckStatus(status, "FitsInOutFile::Open() Error: ");
194 fname_ = name;
195 mode_ = mode;
196 ownfptr = true;
197 return;
198}
199
200/*-- Methode --*/
201//! Opens the named fits file (see cfitsio routines fits_open_file and fits_create_file)
202void FitsInOutFile::Close()
203{
204 if (ownfptr == false) return;
205 if (fptr_ == NULL) return;
206 int status = 0;
207 if (mode_ == Fits_Create) {
208 status = 0;
209 int hdutyp;
210 fits_movabs_hdu(FitsPtr() , 1, &hdutyp, &status);
211 status = 0;
212 float sfv = Version();
213 fits_write_key(FitsPtr(), TFLOAT, "SOPHYAFV", &sfv,
214 "SOPHYA FitsIOServer module version", &status);
215 fits_write_date(FitsPtr(), &status);
216 status = 0;
217 fits_write_comment(FitsPtr(), "------------- SOPHYA (http://www.sophya.org) -------------", &status);
218 fits_write_comment(FitsPtr(), " (C) LAL/IN2P3-CNRS Orsay , (C) DAPNIA/CEA Saclay (FRANCE)", &status);
219 fits_write_comment(FitsPtr(), "-----------------------------------------------------------", &status);
220 }
221 MoveAbsToHDU(1);
222 status = 0;
223 if (fptr_) fits_close_file(fptr_, &status);
224 if (status) {
225 cerr << " FitsInOutFile::Close - Error closing fits file !" << endl;
226 fits_report_error(stderr, status);
227 }
228}
229
230/*! \brief Closes the current fits file and uses \b fios file for subsequent operations.
231 \warning The fits file pointer is owned by the original FitsInOutFile object and
232 should not be closed as long as the current object (this) is being used.
233*/
234
235void FitsInOutFile::ShareFitsPtr(FitsInOutFile const& fios)
236{
237 Close();
238 fptr_ = fios.fptr_;
239 fname_ = fios.fname_;
240 mode_ = fios.mode_;
241 ownfptr = false;
242}
243
244/*-- Methode --*/
245float FitsInOutFile::cfitsioVersion()
246{
247 float ver;
248 fits_get_version(&ver);
249 return ver;
250}
251
252/*-- Methode --*/
253int FitsInOutFile::NbHDUs() const
254{
255 int status = 0;
256 int nbhdu = 0;
257 fits_get_num_hdus(FitsPtr() , &nbhdu, &status);
258 FitsCheckStatus(status, "FitsInOutFile::NbHDUs() Error: ");
259 return nbhdu;
260}
261
262/*-- Methode --*/
263int FitsInOutFile::CurrentHDU() const
264{
265 int status = 0;
266 int curhdu = 0;
267 fits_get_hdu_num(FitsPtr() , &curhdu);
268 return curhdu;
269}
270
271/*-- Methode --*/
272int FitsInOutFile::CurrentHDUType() const
273{
274 int status = 0;
275 int hdutyp = 0;
276 fits_get_hdu_type(FitsPtr() , &hdutyp, &status);
277 FitsCheckStatus(status, "FitsInOutFile::CurrentHDUType() Error: ");
278 return hdutyp;
279}
280
281/*-- Methode --*/
282string FitsInOutFile::CurrentHDUTypeStr() const
283{
284 int status = 0;
285 int hdutyp = 0;
286 fits_get_hdu_type(FitsPtr() , &hdutyp, &status);
287 if ( FitsCheckStatus(status, "FitsInOutFile::CurrentHDUTypeStr() Error: ") )
288 return "Unknown";
289 else {
290 if (hdutyp == IMAGE_HDU) return "IMAGE_HDU";
291 else if (hdutyp == BINARY_TBL) return "BINARY_TBL";
292 else if (hdutyp == ASCII_TBL) return "ASCII_TBL";
293 else return "Unknown";
294 }
295}
296
297/*-- Methode --*/
298int FitsInOutFile::MoveAbsToHDU(int hdunum)
299{
300 int status = 0;
301 int hdutyp = 0;
302 fits_movabs_hdu(FitsPtr() , hdunum, &hdutyp, &status);
303 FitsCheckStatus(status, "FitsInOutFile::MoveAbsToHDU Error: ");
304 return hdutyp;
305}
306
307/*-- Methode --*/
308int FitsInOutFile::MoveRelToHDU(int hdunum)
309{
310 int status = 0;
311 int hdutyp = 0;
312 fits_movrel_hdu(FitsPtr() , hdunum, &hdutyp, &status);
313 FitsCheckStatus(status, "FitsInOutFile::MoveRelToHDU Error: ");
314 return hdutyp;
315}
316
317/*-- Methode --*/
318int FitsInOutFile::MoveToNextHDU()
319{
320 if (CurrentHDU() < NbHDUs())
321 return MoveRelToHDU(1);
322 else return -1;
323}
324
325/*-- Methode --*/
326void FitsInOutFile::CreateImageHDU(int bitpix, int naxis, long* naxes)
327{
328 int status = 0;
329 fits_create_img(fptr_, bitpix, naxis, naxes, &status);
330 FitsCheckStatus(status,"FitsInOutFile::CreateImageHDU() Error: ");
331 return;
332}
333
334/*-- Methode --*/
335 /*!
336 See cfitsio function fits_get_img_param() for more information
337 naxis : input=max naxes dimension / out=image dimension
338 Rc : return the image type (bitpix)
339 */
340int FitsInOutFile::GetImageHDUInfo(int& naxis, long* naxes) const
341{
342 int status = 0;
343 int maxdim = naxis;
344 int bitpix = 0;
345 fits_get_img_param(fptr_, maxdim, &bitpix, &naxis, naxes, &status);
346 FitsCheckStatus(status, "FitsInOutFile::GetImageHDUInfo() Error: ");
347 return bitpix;
348}
349
350/*-- Methode --*/
351long FitsInOutFile::GetNbRows() const
352{
353 int status = 0;
354 long nbrow = 0;
355 fits_get_num_rows(FitsPtr() , &nbrow, &status);
356 FitsCheckStatus(status, "FitsInOutFile::GetNbRows() Error: " );
357 return nbrow;
358}
359
360/*-- Methode --*/
361int FitsInOutFile::GetNbCols() const
362{
363 int status = 0;
364 int nbcol = 0;
365 fits_get_num_cols(FitsPtr() , &nbcol, &status);
366 FitsCheckStatus(status, "FitsInOutFile::GetNbCols() Error: ");
367 return nbcol;
368}
369
370/*-- Methode --*/
371/*!
372 Create a binary or ascii table - See cfitsio routine fits_create_tbl for more information.
373 \param extname : extension name. NextExtensionName() will be used if extname == NULL or extname == "".
374 \param ncols : Number of columns
375 \param ttype : Column names
376 \param tform : Column data types J / V / K / E / D ...
377 \param tunit : Column units
378*/
379void FitsInOutFile::CreateTable(int tbltyp, const char * extname, int ncols,
380 char * ttype[], char * tform[],
381 char * tunit[], long ininr)
382{
383 int status = 0;
384
385 char * extn;
386 if ( (extname != NULL) && (extname[0] != '\0') ) extn = const_cast<char *>(extname);
387 else extn = const_cast<char *>(next_extname_.c_str());
388
389 fits_create_tbl(FitsPtr(), tbltyp, ininr, ncols, ttype,
390 tform, tunit, extn, &status);
391 next_extname_ = "";
392 FitsCheckStatus(status, "FitsInOutFile::CreateTable() Error: ");
393 return;
394}
395
396/*-- Methode --*/
397/*!
398 Create a binary or ascii table - See cfitsio routine fits_create_tbl for more information.
399 number of columns specified by colnames.size()
400 \param extname : extension name
401 \param colnames : Column names
402 \param tform : Column data types J / V / K / E / D ...
403 \param tunit : Column units
404*/
405void FitsInOutFile::CreateTable(int tbltyp, const string & extname,
406 const vector<string> & colnames,
407 const vector<string> & tform,
408 const vector<string> & tunit,
409 long ininr)
410{
411 if ( (colnames.size() != tform.size() ) ||
412 (colnames.size() != tunit.size() ) )
413 throw SzMismatchError("FitsInOutFile::CreateTable(): different sizes for colnames,tform,tunit");
414
415 // On utilise les SegDataBlock<T> pour eviter d'avoir a gerer les new/delete
416 // en plus avec les exceptions ...
417 size_t kk;
418 int ncols = colnames.size();
419
420 SegDataBlock<const char *> colnm(colnames.size(), 1);
421 for(kk=0; kk<colnames.size(); kk++) colnm[kk] = colnames[kk].c_str();
422 SegDataBlock<const char *> tfm(tform.size(), 1);
423 for(kk=0; kk<tform.size(); kk++) tfm[kk] = tform[kk].c_str();
424 SegDataBlock<const char *> tun(tunit.size(), 1);
425 for(kk=0; kk<tunit.size(); kk++) tun[kk] = tunit[kk].c_str();
426
427 CreateTable(tbltyp, const_cast<char *>(extname.c_str()), ncols,
428 const_cast<char **>(colnm.GetSegment(0)),
429 const_cast<char **>(tfm.GetSegment(0)),
430 const_cast<char **>(tun.GetSegment(0)),
431 ininr);
432}
433
434/*-- Methode --*/
435/*!
436 Return number of columns in table (See fits_get_colname and fits_get_coltype for more information)
437 \param colnames : Column names
438 \param coltypes : Column data types ( TSTRING / TSHORT / TFLOAT / ... )
439 \param repcnt : Repeat count (for columns with vector data)
440 \param width : The width (in bytes) of a single element in a column
441
442*/
443long FitsInOutFile::GetColInfo(vector<string> & colnames,
444 vector<int> & coltypes,
445 vector<long> & repcnt,
446 vector<long> & width)
447{
448
449 int status = 0;
450
451 colnames.clear();
452 coltypes.clear();
453 width.clear();
454 repcnt.clear();
455
456 int colnum, typecode;
457 long repeat, colw;
458 int ncols = 0;
459 char colname[128]; // longueur max d'un nom de colonne
460
461 while (status != COL_NOT_FOUND) {
462 fits_get_colname(FitsPtr(), CASEINSEN, "*", colname, &colnum, &status);
463 if (status == COL_NOT_FOUND) break;
464 if ( (status != COL_NOT_UNIQUE) && (status != 0) ) {
465 char buff[32];
466 fits_get_errstatus(status, buff);
467 string msg = "FitsInOutFile::GetColInfo() Error(1): " ;
468 msg += buff;
469 throw FitsIOException(msg);
470 }
471 int sta2 = 0;
472 fits_get_coltype(FitsPtr(), colnum, &typecode, &repeat, &colw, &sta2);
473 FitsCheckStatus(sta2, "FitsInOutFile::GetColInfo() Error(2): ");
474
475 colnames.push_back(colname);
476 coltypes.push_back(typecode);
477 repcnt.push_back(repeat);
478 width.push_back(colw);
479 if (status == 0) break;
480 }
481 return colnames.size();
482}
483
484/*-- Methode --*/
485void FitsInOutFile::InsertColumn(int numcol, const char* colname, const char* fmt)
486{
487 int status = 0;
488 fits_insert_col(FitsPtr(), numcol, const_cast<char *>(colname),
489 const_cast<char *>(fmt), &status);
490 FitsCheckStatus(status, "FitsInOutFile::AddColumn() Error: ");
491
492 return;
493}
494
495/*-- Methode --*/
496/*!
497 Return the value associated to the keyword \b key in the header as a string.
498 If the keyword is not found in the fits header, an empty string is returned
499 and the \b nosk flag is set to true.
500*/
501string FitsInOutFile::KeyValue(string const & key, bool& nosk)
502{
503 nosk = false;
504 int status = 0;
505 char value[FLEN_VALUE], comm[FLEN_COMMENT];
506 fits_read_key(FitsPtr(), TSTRING, const_cast<char *>(key.c_str()), value, comm, &status);
507 if (status == KEY_NO_EXIST) {
508 nosk = true;
509 return "";
510 }
511 FitsCheckStatus(status, "FitsInOutFile::KeyValue() Error: ");
512 return value;
513}
514
515/*-- Methode --*/
516int FitsInOutFile::GetHeaderRecords(DVList& dvl)
517{
518 int status = 0;
519 int nkeys = 0;
520 fits_get_hdrspace(FitsPtr(), &nkeys, NULL, &status);
521 FitsCheckStatus(status, "FitsInOutFile::GetHeaderRecords() Error(1): ");
522
523 char record[FLEN_CARD], value[FLEN_VALUE], comm[FLEN_COMMENT];
524 string comment;
525 int nok = 0;
526 for(int kk=1; kk<=nkeys; kk++) {
527 status = 0;
528 fits_read_record(FitsPtr(), kk, record, &status);
529 FitsCheckStatus(status, "FitsInOutFile::GetHeaderRecords() Error(2): ");
530 int kclas = fits_get_keyclass(record);
531 if ( (kclas == TYP_STRUC_KEY) || (kclas == TYP_NULL_KEY) ) continue;
532 int len = 0;
533 status = 0;
534 fits_get_keyname(record, value, &len, &status);
535 if (status) continue;
536 string keyname = value;
537 status = 0;
538 fits_parse_value(record, value, comm, &status);
539 if (status) continue;
540 if (kclas == TYP_COMM_KEY) {
541 if (comment.length() > 0) comment += '\n';
542 comment += value;
543 continue;
544 }
545 char ktyp;
546 status = 0;
547 fits_get_keytype(value, &ktyp, &status);
548 if (status) continue;
549 switch (ktyp) {
550 case 'C' :
551 case 'L' : // Il faudra traiter le cas des nb complexes
552 case 'X' : // idem pour les valeurs logiques
553 dvl.SetS(keyname, value);
554 break;
555 case 'I' :
556 dvl.SetI(keyname, atoi(value));
557 break;
558 case 'F' :
559 dvl.SetD(keyname, atof(value));
560 break;
561 }
562 if (strlen(comm) > 0) {
563 string scom = comm;
564 dvl.SetComment(keyname, scom);
565 }
566 nok++;
567 }
568 if (comment.length() > 0) dvl.Comment() = comment;
569 return nok;
570}
571
572/*-- Methode --*/
573void FitsInOutFile::WriteKey(const char * kname, MuTyV const & mtv,
574 const char *comment)
575{
576 CheckFitsPtr(FitsPtr());
577 char keyname[FLEN_KEYWORD], comm[FLEN_COMMENT], sval[FLEN_VALUE];
578 long lval;
579 double dval;
580 string s;
581
582 keyname[0] = '\0';
583 strncpy(keyname, kname, FLEN_KEYWORD); keyname[FLEN_KEYWORD-1] = '\0';
584 comm[0] = '\0';
585 if (comm != NULL)
586 strncpy(comm, comment, FLEN_COMMENT); comm[FLEN_COMMENT-1] = '\0';
587 int status = 0;
588 switch (mtv.Type()) {
589 case MuTyV::MTVInteger :
590 lval = mtv.GetIntPart();
591 fits_write_key(FitsPtr(), TLONG, keyname, &lval, comm, &status);
592 break;
593 case MuTyV::MTVFloat :
594 dval = mtv.GetRealPart();
595 fits_write_key(FitsPtr(), TDOUBLE, keyname, &dval, comm, &status);
596 break;
597 case MuTyV::MTVString :
598 strncpy(sval, mtv.GetStringPointer()->c_str(), FLEN_VALUE);
599 keyname[FLEN_VALUE-1] = '\0';
600 fits_write_key(FitsPtr(), TSTRING, keyname, sval, comm, &status);
601 break;
602 default :
603 s = (string)mtv;
604 strncpy(sval, s.c_str(), FLEN_VALUE);
605 keyname[FLEN_VALUE-1] = '\0';
606 fits_write_key(FitsPtr(), TSTRING, keyname, sval, comm, &status);
607 break;
608 }
609 FitsCheckStatus(status, "FitsInOutFile::WriteKey() Error: ");
610 return;
611}
612
613/*-- Methode --*/
614int FitsInOutFile::WriteHeaderRecords(DVList & dvl)
615{
616
617 CheckFitsPtr(FitsPtr());
618 int status = 0;
619 DVList::ValList::const_iterator it;
620 for(it = dvl.Begin(); it != dvl.End(); it++)
621 WriteKey( (*it).first, (*it).second.elval, (*it).second.elcomm);
622 // Ecriture commentaires
623 return 0;
624
625}
626
627/*-- Methode --*/
628void FitsInOutFile::Print(ostream& os, int lev) const
629{
630 string mode;
631 if (mode_ == Fits_Create) mode = "Create";
632 else if (mode_ == Fits_RO) mode = "ReadOnly";
633 else mode = "ReadWrite";
634 os << " FitsInOutFile(FileName= " << fname_ << " Mode="
635 << mode << ") fitsioVers= " << cfitsioVersion() << endl;
636 os << " TotalNumberHDU= " << NbHDUs() << " CurrentHDU: Num= "
637 << CurrentHDU() << " Type= " << CurrentHDUTypeStr() << endl;
638
639 return;
640}
641
642
Note: See TracBrowser for help on using the repository browser.