40 #define FPTR (static_cast<fitsfile *> (fptr)) 41 #define OFPTR (static_cast<fitsfile *> (orig.fptr)) 47 template<
typename T>
inline int fitsType();
48 template<>
inline int fitsType<float> () {
return TFLOAT; }
49 template<>
inline int fitsType<double>() {
return TDOUBLE; }
51 int type2bitpix (
PDT type)
55 case PLANCK_FLOAT32:
return FLOAT_IMG;
56 case PLANCK_FLOAT64:
return DOUBLE_IMG;
57 default:
planck_fail (
"unsupported component type");
63 PDT ftc2type (
int ftc)
67 case TLOGICAL :
return PLANCK_BOOL;
68 case TBYTE :
return PLANCK_INT8;
69 case TSHORT :
return PLANCK_INT16;
71 case TINT32BIT:
return PLANCK_INT32;
72 case TLONGLONG:
return PLANCK_INT64;
73 case TFLOAT :
return PLANCK_FLOAT32;
74 case TDOUBLE :
return PLANCK_FLOAT64;
75 case TSTRING :
return PLANCK_STRING;
76 default:
planck_fail (
"unsupported component type");
82 int type2ftc (
PDT type)
86 case PLANCK_BOOL :
return TLOGICAL;
88 case PLANCK_UINT8 :
return TBYTE;
89 case PLANCK_INT16 :
return TSHORT;
90 case PLANCK_INT32 :
return TINT;
91 case PLANCK_INT64 :
return TLONGLONG;
92 case PLANCK_FLOAT32:
return TFLOAT;
93 case PLANCK_FLOAT64:
return TDOUBLE;
94 case PLANCK_STRING :
return TSTRING;
95 default:
planck_fail (
"unsupported component type");
99 const char *type2fitschar (
PDT type)
103 case PLANCK_BOOL :
return "L";
104 case PLANCK_FLOAT32:
return "E";
105 case PLANCK_FLOAT64:
return "D";
107 case PLANCK_UINT8 :
return "B";
108 case PLANCK_INT16 :
return "I";
109 case PLANCK_INT32 :
return "J";
110 case PLANCK_INT64 :
return "K";
111 case PLANCK_STRING :
return "A";
117 const char *type2asciiform (
PDT type)
121 case PLANCK_FLOAT32:
return "E14.7";
122 case PLANCK_FLOAT64:
return "D23.15";
123 case PLANCK_UINT8 :
return "I3";
124 case PLANCK_INT8 :
return "I4";
125 case PLANCK_INT16 :
return "I6";
126 case PLANCK_INT32 :
return "I11";
127 case PLANCK_INT64 :
return "I22";
133 string fixkey (
const string &key)
135 for (
tsize m=0; m<key.size(); ++m)
136 if (islower(key[m]))
return string(
"HIERARCH "+key);
142 fitscolumn::fitscolumn()
143 : repcount_(0), type_(PLANCK_INVALID) {}
145 fitscolumn::fitscolumn (
const string &nm,
const string &un, int64 rc,
PDT tp)
146 : name_(nm), unit_(un), repcount_(rc), type_(tp) {}
148 fitscolumn::~fitscolumn () {}
150 void fitshandle::check_errors()
const 155 while (fits_read_errmsg(msg))
156 cerr <<
"STALE FITS ERROR MESSAGE: " << msg << endl;
160 fits_get_errstatus (status, msg);
162 while (fits_read_errmsg(msg)) cerr << msg << endl;
168 void fitshandle::clean_data()
178 void fitshandle::clean_all()
182 fits_close_file (FPTR, &status);
187 bool fitshandle::table_hdu (
tsize col)
const 189 if ((hdutype_!=ASCII_TBL) && (hdutype_!=BINARY_TBL))
return false;
190 if ((col<=0) || (col>columns_.size()))
return false;
193 bool fitshandle::image_hdu ()
const 194 {
return hdutype_==IMAGE_HDU; }
196 void fitshandle::init_image()
199 fits_get_img_type (FPTR, &bitpix_, &status);
200 fits_get_img_dim (FPTR, &naxis, &status);
203 if (naxis>0) fits_get_img_sizell (FPTR, naxis, naxes.begin(), &status);
204 for (
long m=0; m<naxis; ++m) axes_.push_back(naxes[naxis-m-1]);
208 void fitshandle::init_asciitab()
210 char ttype[81], tunit[81], tform[81];
212 fits_get_num_cols (FPTR, &ncol, &status);
213 { LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
215 for (
int m=1; m<=ncol; ++m)
217 fits_get_acolparms (FPTR, m, ttype, 0, tunit, tform,
218 0, 0, 0, 0, &status);
219 fits_ascii_tform (tform, &typecode, 0,0, &status);
221 columns_.push_back (
fitscolumn (ttype,tunit,1,ftc2type(typecode)));
225 void fitshandle::init_bintab()
227 char ttype[81], tunit[81], tform[81];
230 fits_get_num_cols (FPTR, &ncol, &status);
231 { LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
233 for (
int m=1; m<=ncol; ++m)
235 fits_get_bcolparmsll (FPTR, m, ttype, tunit, tform, &repc,
236 0, 0, 0, 0, &status);
237 fits_binary_tform (tform, &typecode, 0,0, &status);
239 columns_.push_back (
fitscolumn (ttype,tunit,repc,ftc2type(typecode)));
243 void fitshandle::init_data()
246 fits_get_hdu_type (FPTR, &hdutype_, &status);
253 init_asciitab();
break;
255 init_bintab();
break;
257 planck_fail(
"init_data(): unsupported HDU type");
break;
261 void fitshandle::read_col (
int colnum,
void *data, int64 ndata,
PDT type,
264 planck_assert(table_hdu(colnum),
"incorrect FITS table access");
265 int64 repc = columns_[colnum-1].repcount();
266 planck_assert (ndata<=(repc*nrows_-offset),
"read_column(): array too large");
267 int64 frow = offset/repc+1;
268 int64 felem = offset%repc+1;
269 fits_read_col (FPTR, type2ftc(type), colnum, frow, felem, ndata, 0, data, 0,
273 void fitshandle::write_col (
int colnum,
const void *data, int64 ndata,
274 PDT type, int64 offset)
276 planck_assert(table_hdu(colnum),
"incorrect FITS table access");
277 int64 repc = columns_[colnum-1].repcount();
278 int64 frow = offset/repc+1;
279 int64 felem = offset%repc+1;
280 fits_write_col (FPTR, type2ftc(type), colnum, frow, felem, ndata,
281 const_cast<void *>(data), &status);
282 nrows_ = max(nrows_,offset+ndata);
286 void fitshandle::getKeyHelper(
const string &name)
const 288 if (status==KEY_NO_EXIST)
292 planck_fail(
"fitshandle::get_key(): key '"+name+
"' not found");
298 : status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0) {}
307 fits_open_file(&ptr, fname.c_str(), READONLY, &status);
317 fits_create_file(&ptr, fname.c_str(), &status);
319 fits_write_imghdr(FPTR, 8, 0, 0, &status);
320 fits_write_date(FPTR, &status);
330 fits_open_file(&ptr, name.c_str(), READWRITE, &stat);
331 fits_delete_file(ptr, &stat);
335 fits_get_errstatus (stat, msg);
337 while (fits_read_errmsg(msg)) cerr << msg << endl;
344 char *fname =
new char[2048];
345 fits_file_name(FPTR, fname, &status);
347 string result(fname);
355 fits_get_hdu_num(FPTR,&curhdu);
358 fits_movabs_hdu(FPTR, hdu, &hdutype_, &status);
367 fits_get_num_hdus (FPTR, &result, &status);
373 const string &extname)
376 int ncol=cols.size();
377 arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
379 for (
long m=0; m<ncol; ++m)
381 strcpy (ttype[m], cols[m].name().c_str());
382 strcpy (tunit[m], cols[m].unit().c_str());
384 x << cols[m].repcount() << type2fitschar(cols[m].type());
385 strcpy (tform[m], x.str().c_str());
387 fits_insert_btbl (FPTR, nrows_, ncol, ttype.p0(), tform.p0(), tunit.
p0(),
388 const_cast<char *
>(extname.c_str()), 0, &status);
394 const string &extname)
397 int ncol=cols.size();
398 arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
400 for (
long m=0; m<ncol; ++m)
402 strcpy (ttype[m], cols[m].name().c_str());
403 strcpy (tunit[m], cols[m].unit().c_str());
405 if (cols[m].type()!=PLANCK_STRING)
408 x << type2asciiform(cols[m].type());
414 strcpy (tform[m], x.str().c_str());
416 fits_insert_atbl (FPTR, 0, nrows_, ncol, ttype.p0(), 0, tform.p0(),
417 tunit.
p0(),
const_cast<char *
>(extname.c_str()), &status);
426 for (
long m=0; m<long(Axes.size()); m++) tmpax[m]=Axes[Axes.size()-1-m];
427 fits_insert_imgll (FPTR, type2bitpix(type), Axes.size(), &tmpax[0], &status);
437 tmpax[0] = data.
size2(); tmpax[1] = data.
size1();
438 fits_insert_imgll (FPTR, type2bitpix(type), 2, &tmpax[0], &status);
440 fits_write_img (FPTR, fitsType<T>(), 1, tmpax[0]*tmpax[1],
441 &tmparr[0][0], &status);
452 fits_write_chksum (FPTR, &status);
464 return columns_[i-1].name();
469 return columns_[i-1].unit();
474 return columns_[i-1].repcount();
479 return columns_[i-1].type();
484 return columns_.size();
494 if (columns_[i-1].type()==PLANCK_STRING)
return nrows_;
495 return nrows_*columns_[i-1].repcount();
501 fits_get_rowsize(FPTR, &res, &status);
504 return res*columns_[i-1].repcount();
511 const char *inclist[] = {
"*" };
513 fits_read_record (FPTR, 0, card, &status);
517 fits_find_nextkey (FPTR, const_cast<char **>(inclist), 1,
518 0, 0, card, &status);
519 if (status!=0)
break;
520 if (fits_get_keyclass(card)==TYP_USER_KEY)
524 fits_get_keyname(card, keyname, &dummy, &status);
526 keys.push_back(
trim(keyname));
530 if (status==KEY_NO_EXIST) { fits_clear_errmsg(); status=0; }
534 void fitshandle::set_key_void (
const string &key,
const void *value,
535 PDT type,
const string &comment)
538 string key2 = fixkey(key);
548 fits_update_key (FPTR, type2ftc(type), const_cast<char *>(key2.c_str()),
549 const_cast<void *>(value),
const_cast<char *
>(comment.c_str()),
554 int val = *(
static_cast<const bool *
>(value));
555 fits_update_key (FPTR, TLOGICAL, const_cast<char *>(key2.c_str()),
556 &val, const_cast<char *>(comment.c_str()), &status);
561 string val = *(
static_cast<const string *
>(value));
562 fits_update_key_longstr (FPTR, const_cast<char *>(key2.c_str()),
563 const_cast<char *>(val.c_str()), const_cast<char *>(comment.c_str()),
568 planck_fail (
"unsupported data type in set_key_void()");
573 void fitshandle::get_key_void (
const string &name,
void *value,
PDT type)
const 585 fits_read_key (FPTR, type2ftc(type), const_cast<char *>(name.c_str()),
592 fits_read_key (FPTR, TLOGICAL, const_cast<char *>(name.c_str()), &val, 0,
595 *(
static_cast<bool *
>(value))=val;
601 fits_read_key_longstr (FPTR, const_cast<char *>(name.c_str()), &tmp, 0,
604 *(
static_cast<string *
>(value))=tmp;
609 planck_fail (
"unsupported data type in get_key_void()");
617 fits_delete_key (FPTR, const_cast<char *>(name.c_str()), &status);
624 fits_write_comment(FPTR,const_cast<char *>(comment.c_str()),&status);
632 fits_read_card(FPTR, const_cast<char *>(name.c_str()), card, &status);
633 if (status==KEY_NO_EXIST)
634 { fits_clear_errmsg(); status=0;
return false; }
643 if (pdmtype==type)
return;
644 cerr <<
"PDMTYPE " << pdmtype <<
" expected, but found " << type << endl;
647 void fitshandle::read_column_raw_void
648 (
int colnum,
void *data,
PDT type, int64 num, int64 offset)
const 660 read_col (colnum, data, num, type, offset);
break;
663 string *data2 =
static_cast<string *
> (data);
664 planck_assert(table_hdu(colnum),
"incorrect FITS table access");
666 "read_column(): array too large");
668 safe_cast<tsize>(columns_[colnum-1].
repcount()+1));
670 fits_get_col_display_width(FPTR, colnum, &dispwidth, &status);
672 fits_read_col (FPTR, TSTRING, colnum, offset+1, 1, num,
673 0, tdata.p0(), 0, &status);
675 for (
long m=0;m<num;++m) data2[m]=tdata[m];
679 planck_fail (
"unsupported data type in read_column_raw_void()");
683 void fitshandle::write_column_raw_void
684 (
int colnum,
const void *data,
PDT type, int64 num, int64 offset)
696 write_col (colnum, data, num, type, offset);
break;
699 const string *data2 =
static_cast<const string *
> (data);
700 planck_assert(table_hdu(colnum),
"incorrect FITS table access");
702 arr2b<char> tdata(safe_cast<tsize>(num), stringlen);
703 for (
long m=0;m<num;++m)
705 strncpy(tdata[m],data2[m].c_str(),stringlen-1);
706 tdata[m][stringlen-1] =
'\0';
708 fits_write_col (FPTR, TSTRING, colnum, offset+1, 1, num,
709 tdata.p0(), &status);
710 nrows_ = max(nrows_,offset+num);
715 planck_fail (
"unsupported data type in write_column_raw_void()");
719 void fitshandle::write_image2D_void (
const void *data,
PDT type,
tsize s1,
723 planck_assert (axes_.size()==2,
"wrong number of dimensions");
724 planck_assert (axes_[0]==int64(s1),
"wrong size of dimension 1");
725 planck_assert (axes_[1]==int64(s2),
"wrong size of dimension 2");
727 fits_write_img (FPTR, type2ftc(type), 1, axes_[0]*axes_[1],
728 const_cast<void *>(data), &status);
732 void fitshandle::write_subimage_void (
const void *data,
PDT type,
tsize sz,
736 fits_write_img (FPTR, type2ftc(type), 1+offset, sz, const_cast<void *>(data),
744 planck_assert (axes_.size()==2,
"wrong number of dimensions");
745 data.
alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]));
746 fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1], 0, &data[0][0], 0,
757 planck_assert (axes_.size()==3,
"wrong number of dimensions");
758 data.
alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]),
759 safe_cast<tsize>(axes_[2]));
760 fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1]*axes_[2],
761 0, &data(0,0,0), 0, &status);
772 planck_assert (axes_.size()==2,
"wrong number of dimensions");
774 fits_read_img (FPTR, fitsType<T>(), (xl+m)*axes_[1]+yl+1,
775 data.
size2(), 0, &data[m][0], 0, &status);
784 void fitshandle::read_subimage_void (
void *data,
PDT type,
tsize ndata,
788 fits_read_img (FPTR, type2ftc(type), 1+offset, ndata, 0, data, 0, &status);
794 class cfitsio_checker
801 "error calling fits_get_version()");
809 int v_header = nearest<int>(10000*CFITSIO_MAJOR + 100*CFITSIO_MINOR + CFITSIO_MICRO),
810 v_library = nearest<int>(10000*fitsversion);
811 if (v_header!=v_library)
812 cerr << endl <<
"WARNING: version mismatch between CFITSIO header (v" 816 int v_header = nearest<int>(100*CFITSIO_VERSION),
817 v_library = nearest<int>(100*fitsversion);
818 if (v_header!=v_library)
819 cerr << endl <<
"WARNING: version mismatch between CFITSIO header (v" 820 <<
dataToString(v_header*0.01) <<
") and linked library (v" 821 <<
dataToString(v_library*0.01) <<
")." << endl << endl;
826 cfitsio_checker Cfitsio_Checker;
void create(const std::string &fname)
T1 safe_cast(const T2 &arg)
int64 nelems(int i) const
void get_key(const std::string &name, T &value) const
void assert_pdmtype(const std::string &pdmtype) const
int64 repcount(int i) const
void open(const std::string &fname)
int64 efficientChunkSize(int i) const
void alloc(tsize sz1, tsize sz2, tsize sz3)
void insert_asctab(const std::vector< fitscolumn > &cols, const std::string &extname="xtension")
void insert_bintab(const std::vector< fitscolumn > &cols, const std::string &extname="xtension")
const std::string & colname(int i) const
void get_all_keys(std::vector< std::string > &keys) const
void delete_key(const std::string &name)
std::string fileName() const
std::string trim(const std::string &orig)
void read_image(arr2< T > &data) const
void read_subimage(arr2< T > &data, int xl, int yl) const
string dataToString(const T &x)
#define planck_assert(testval, msg)
void add_comment(const std::string &comment)
void alloc(tsize sz1, tsize sz2)
bool key_present(const std::string &name) const
const std::vector< int64 > & axes() const
void insert_image(PDT type, const std::vector< int64 > &Axes)
static void delete_file(const std::string &name)
const char * type2string(PDT type)
const std::string & colunit(int i) const