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

Last change on this file since 3885 was 3572, checked in by cmv, 17 years ago

char* -> const char* pour regler les problemes de deprecated string const... + comparaison unsigned signed + suppression EVOL_PLANCK rz+cmv 07/02/2009

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