00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <sstream>
00034 #include <cstring>
00035 #include <vector>
00036 #include "fitsio.h"
00037 #include "fitshandle.h"
00038 #include "string_utils.h"
00039
00040 #define FPTR (static_cast<fitsfile *> (fptr))
00041 #define OFPTR (static_cast<fitsfile *> (orig.fptr))
00042
00043 using namespace std;
00044
00045 namespace {
00046
00047 template<typename T> inline int fitsType();
00048 template<> inline int fitsType<float> () { return TFLOAT; }
00049 template<> inline int fitsType<double>() { return TDOUBLE; }
00050
00051 int type2bitpix (PDT type)
00052 {
00053 switch (type)
00054 {
00055 case PLANCK_FLOAT32: return FLOAT_IMG;
00056 case PLANCK_FLOAT64: return DOUBLE_IMG;
00057 default: planck_fail ("unsupported component type");
00058 }
00059 }
00060
00061
00062
00063 PDT ftc2type (int ftc)
00064 {
00065 switch (ftc)
00066 {
00067 case TLOGICAL : return PLANCK_BOOL;
00068 case TBYTE : return PLANCK_INT8;
00069 case TSHORT : return PLANCK_INT16;
00070 case TINT :
00071 case TINT32BIT: return PLANCK_INT32;
00072 case TLONGLONG: return PLANCK_INT64;
00073 case TFLOAT : return PLANCK_FLOAT32;
00074 case TDOUBLE : return PLANCK_FLOAT64;
00075 case TSTRING : return PLANCK_STRING;
00076 default: planck_fail ("unsupported component type");
00077 }
00078 }
00079
00080
00081
00082 int type2ftc (PDT type)
00083 {
00084 switch (type)
00085 {
00086 case PLANCK_BOOL : return TLOGICAL;
00087 case PLANCK_INT8 :
00088 case PLANCK_UINT8 : return TBYTE;
00089 case PLANCK_INT16 : return TSHORT;
00090 case PLANCK_INT32 : return TINT;
00091 case PLANCK_INT64 : return TLONGLONG;
00092 case PLANCK_FLOAT32: return TFLOAT;
00093 case PLANCK_FLOAT64: return TDOUBLE;
00094 case PLANCK_STRING : return TSTRING;
00095 default: planck_fail ("unsupported component type");
00096 }
00097 }
00098
00099 const char *type2fitschar (PDT type)
00100 {
00101 switch (type)
00102 {
00103 case PLANCK_BOOL : return "L";
00104 case PLANCK_FLOAT32: return "E";
00105 case PLANCK_FLOAT64: return "D";
00106 case PLANCK_INT8 :
00107 case PLANCK_UINT8 : return "B";
00108 case PLANCK_INT16 : return "I";
00109 case PLANCK_INT32 : return "J";
00110 case PLANCK_INT64 : return "K";
00111 case PLANCK_STRING : return "A";
00112 default:
00113 planck_fail(string("unknown data type ")+type2string(type));
00114 }
00115 }
00116
00117 const char *type2asciiform (PDT type)
00118 {
00119 switch (type)
00120 {
00121 case PLANCK_FLOAT32: return "E14.7";
00122 case PLANCK_FLOAT64: return "D23.15";
00123 case PLANCK_UINT8 : return "I3";
00124 case PLANCK_INT8 : return "I4";
00125 case PLANCK_INT16 : return "I6";
00126 case PLANCK_INT32 : return "I11";
00127 case PLANCK_INT64 : return "I22";
00128 default:
00129 planck_fail(string("unknown data type ")+type2string(type));
00130 }
00131 }
00132
00133 string fixkey (const string &key)
00134 {
00135 for (tsize m=0; m<key.size(); ++m)
00136 if (islower(key[m])) return string("HIERARCH "+key);
00137
00138 return key;
00139 }
00140 }
00141
00142 fitscolumn::fitscolumn()
00143 : repcount_(0), type_(PLANCK_INVALID) {}
00144
00145 fitscolumn::fitscolumn (const string &nm, const string &un, int64 rc, PDT tp)
00146 : name_(nm), unit_(un), repcount_(rc), type_(tp) {}
00147
00148 fitscolumn::~fitscolumn () {}
00149
00150 void fitshandle::check_errors() const
00151 {
00152 char msg[81];
00153 if (status==0)
00154 {
00155 while (fits_read_errmsg(msg))
00156 cerr << "STALE FITS ERROR MESSAGE: " << msg << endl;
00157 fits_clear_errmsg();
00158 return;
00159 }
00160 fits_get_errstatus (status, msg);
00161 cerr << msg << endl;
00162 while (fits_read_errmsg(msg)) cerr << msg << endl;
00163 fits_clear_errmsg();
00164 status=0;
00165 planck_fail("FITS error");
00166 }
00167
00168 void fitshandle::clean_data()
00169 {
00170 if (!fptr) return;
00171 axes_.clear();
00172 columns_.clear();
00173 hdutype_=INVALID;
00174 bitpix_=INVALID;
00175 nrows_=0;
00176 }
00177
00178 void fitshandle::clean_all()
00179 {
00180 if (!fptr) return;
00181 clean_data();
00182 fits_close_file (FPTR, &status);
00183 check_errors();
00184 fptr=0;
00185 }
00186
00187 bool fitshandle::table_hdu (tsize col) const
00188 {
00189 if ((hdutype_!=ASCII_TBL) && (hdutype_!=BINARY_TBL)) return false;
00190 if ((col<=0) || (col>columns_.size())) return false;
00191 return true;
00192 }
00193 bool fitshandle::image_hdu () const
00194 { return hdutype_==IMAGE_HDU; }
00195
00196 void fitshandle::init_image()
00197 {
00198 int naxis;
00199 fits_get_img_type (FPTR, &bitpix_, &status);
00200 fits_get_img_dim (FPTR, &naxis, &status);
00201 check_errors();
00202 arr<LONGLONG> naxes(naxis);
00203 fits_get_img_sizell (FPTR, naxis, &naxes[0], &status);
00204 for (long m=0; m<naxis; ++m) axes_.push_back(naxes[naxis-m-1]);
00205 check_errors();
00206 }
00207
00208 void fitshandle::init_asciitab()
00209 {
00210 char ttype[81], tunit[81], tform[81];
00211 int ncol, typecode;
00212 fits_get_num_cols (FPTR, &ncol, &status);
00213 { LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
00214 check_errors();
00215 for (int m=1; m<=ncol; ++m)
00216 {
00217 fits_get_acolparms (FPTR, m, ttype, 0, tunit, tform,
00218 0, 0, 0, 0, &status);
00219 fits_ascii_tform (tform, &typecode, 0,0, &status);
00220 check_errors();
00221 columns_.push_back (fitscolumn (ttype,tunit,1,ftc2type(typecode)));
00222 }
00223 }
00224
00225 void fitshandle::init_bintab()
00226 {
00227 char ttype[81], tunit[81], tform[81];
00228 LONGLONG repc;
00229 int ncol, typecode;
00230 fits_get_num_cols (FPTR, &ncol, &status);
00231 { LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
00232 check_errors();
00233 for (int m=1; m<=ncol; ++m)
00234 {
00235 fits_get_bcolparmsll (FPTR, m, ttype, tunit, tform, &repc,
00236 0, 0, 0, 0, &status);
00237 fits_binary_tform (tform, &typecode, 0,0, &status);
00238 check_errors();
00239 columns_.push_back (fitscolumn (ttype,tunit,repc,ftc2type(typecode)));
00240 }
00241 }
00242
00243 void fitshandle::init_data()
00244 {
00245 clean_data();
00246 fits_get_hdu_type (FPTR, &hdutype_, &status);
00247 check_errors();
00248 switch(hdutype_)
00249 {
00250 case IMAGE_HDU:
00251 init_image(); break;
00252 case ASCII_TBL:
00253 init_asciitab(); break;
00254 case BINARY_TBL:
00255 init_bintab(); break;
00256 default:
00257 planck_fail("init_data(): unsupported HDU type"); break;
00258 }
00259 }
00260
00261 void fitshandle::read_col (int colnum, void *data, int64 ndata, PDT type,
00262 int64 offset) const
00263 {
00264 planck_assert(table_hdu(colnum),"incorrect FITS table access");
00265 int64 repc = columns_[colnum-1].repcount();
00266 planck_assert (ndata<=(repc*nrows_-offset),"read_column(): array too large");
00267 int64 frow = offset/repc+1;
00268 int64 felem = offset%repc+1;
00269 fits_read_col (FPTR, type2ftc(type), colnum, frow, felem, ndata, 0, data, 0,
00270 &status);
00271 check_errors();
00272 }
00273 void fitshandle::write_col (int colnum, const void *data, int64 ndata,
00274 PDT type, int64 offset)
00275 {
00276 planck_assert(table_hdu(colnum),"incorrect FITS table access");
00277 int64 repc = columns_[colnum-1].repcount();
00278 int64 frow = offset/repc+1;
00279 int64 felem = offset%repc+1;
00280 fits_write_col (FPTR, type2ftc(type), colnum, frow, felem, ndata,
00281 const_cast<void *>(data), &status);
00282 nrows_ = max(nrows_,offset+ndata);
00283 check_errors();
00284 }
00285
00286 void fitshandle::getKeyHelper(const string &name) const
00287 {
00288 if (status==KEY_NO_EXIST)
00289 {
00290 fits_clear_errmsg();
00291 status=0;
00292 planck_fail("fitshandle::get_key(): key '"+name+"' not found");
00293 }
00294 check_errors();
00295 }
00296
00297 fitshandle::fitshandle ()
00298 : status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0) {}
00299
00300 fitshandle::~fitshandle()
00301 { clean_all(); }
00302
00303 void fitshandle::open (const string &fname)
00304 {
00305 clean_all();
00306 fitsfile *ptr;
00307 fits_open_file(&ptr, fname.c_str(), READONLY, &status);
00308 fptr=ptr;
00309 check_errors();
00310 init_data();
00311 }
00312
00313 void fitshandle::create (const string &fname)
00314 {
00315 clean_all();
00316 fitsfile *ptr;
00317 fits_create_file(&ptr, fname.c_str(), &status);
00318 fptr=ptr;
00319 fits_write_imghdr(FPTR, 8, 0, 0, &status);
00320 fits_write_date(FPTR, &status);
00321 check_errors();
00322 init_data();
00323 }
00324
00325
00326 void fitshandle::delete_file (const string &name)
00327 {
00328 fitsfile *ptr;
00329 int stat = 0;
00330 fits_open_file(&ptr, name.c_str(), READWRITE, &stat);
00331 fits_delete_file(ptr, &stat);
00332 if (stat==0) return;
00333
00334 char msg[81];
00335 fits_get_errstatus (stat, msg);
00336 cerr << msg << endl;
00337 while (fits_read_errmsg(msg)) cerr << msg << endl;
00338 planck_fail("FITS error");
00339 }
00340
00341 string fitshandle::fileName() const
00342 {
00343 planck_assert(connected(),"handle not connected to a file");
00344 char *fname = new char[2048];
00345 fits_file_name(FPTR, fname, &status);
00346 check_errors();
00347 string result(fname);
00348 delete[] fname;
00349 return result;
00350 }
00351
00352 void fitshandle::goto_hdu (int hdu)
00353 {
00354 int curhdu;
00355 fits_get_hdu_num(FPTR,&curhdu);
00356 if (curhdu!=hdu)
00357 {
00358 fits_movabs_hdu(FPTR, hdu, &hdutype_, &status);
00359 check_errors();
00360 init_data();
00361 }
00362 }
00363
00364 int fitshandle::num_hdus () const
00365 {
00366 int result;
00367 fits_get_num_hdus (FPTR, &result, &status);
00368 check_errors();
00369 return result;
00370 }
00371
00372 void fitshandle::insert_bintab (const vector<fitscolumn> &cols,
00373 const string &extname)
00374 {
00375 clean_data();
00376 int ncol=cols.size();
00377 arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
00378
00379 for (long m=0; m<ncol; ++m)
00380 {
00381 strcpy (ttype[m], cols[m].name().c_str());
00382 strcpy (tunit[m], cols[m].unit().c_str());
00383 ostringstream x;
00384 x << cols[m].repcount() << type2fitschar(cols[m].type());
00385 strcpy (tform[m], x.str().c_str());
00386 }
00387 fits_insert_btbl (FPTR, nrows_, ncol, ttype.p0(), tform.p0(), tunit.p0(),
00388 const_cast<char *>(extname.c_str()), 0, &status);
00389 check_errors();
00390 init_data();
00391 }
00392
00393 void fitshandle::insert_asctab (const vector<fitscolumn> &cols,
00394 const string &extname)
00395 {
00396 clean_data();
00397 int ncol=cols.size();
00398 arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
00399
00400 for (long m=0; m<ncol; ++m)
00401 {
00402 strcpy (ttype[m], cols[m].name().c_str());
00403 strcpy (tunit[m], cols[m].unit().c_str());
00404 ostringstream x;
00405 if (cols[m].type()!=PLANCK_STRING)
00406 {
00407 planck_assert (cols[m].repcount()==1,"bad repcount for ASCII table");
00408 x << type2asciiform(cols[m].type());
00409 }
00410 else
00411 {
00412 x << "A" << dataToString(cols[m].repcount());
00413 }
00414 strcpy (tform[m], x.str().c_str());
00415 }
00416 fits_insert_atbl (FPTR, 0, nrows_, ncol, ttype.p0(), 0, tform.p0(),
00417 tunit.p0(), const_cast<char *>(extname.c_str()), &status);
00418 check_errors();
00419 init_data();
00420 }
00421
00422 void fitshandle::insert_image (PDT type, const vector<int64> &Axes)
00423 {
00424 clean_data();
00425 arr<LONGLONG> tmpax(Axes.size());
00426 for (long m=0; m<long(Axes.size()); m++) tmpax[m]=Axes[Axes.size()-1-m];
00427 fits_insert_imgll (FPTR, type2bitpix(type), Axes.size(), &tmpax[0], &status);
00428 check_errors();
00429 init_data();
00430 }
00431
00432 template<typename T>
00433 void fitshandle::insert_image (PDT type, const arr2<T> &data)
00434 {
00435 clean_data();
00436 arr<LONGLONG> tmpax(2);
00437 tmpax[0] = data.size2(); tmpax[1] = data.size1();
00438 fits_insert_imgll (FPTR, type2bitpix(type), 2, &tmpax[0], &status);
00439 arr2<T> &tmparr = const_cast<arr2<T> &> (data);
00440 fits_write_img (FPTR, fitsType<T>(), 1, tmpax[0]*tmpax[1],
00441 &tmparr[0][0], &status);
00442 check_errors();
00443 init_data();
00444 }
00445
00446 template void fitshandle::insert_image (PDT type, const arr2<double> &data);
00447 template void fitshandle::insert_image (PDT type, const arr2<float> &data);
00448
00449 void fitshandle::write_checksum()
00450 {
00451 planck_assert(connected(),"handle not connected to a file");
00452 fits_write_chksum (FPTR, &status);
00453 check_errors();
00454 }
00455
00456 const vector<int64> &fitshandle::axes() const
00457 {
00458 planck_assert(image_hdu(),"not connected to an image");
00459 return axes_;
00460 }
00461 const string &fitshandle::colname(int i) const
00462 {
00463 planck_assert(table_hdu(i),"incorrect FITS table access");
00464 return columns_[i-1].name();
00465 }
00466 const string &fitshandle::colunit(int i) const
00467 {
00468 planck_assert(table_hdu(i),"incorrect FITS table access");
00469 return columns_[i-1].unit();
00470 }
00471 int64 fitshandle::repcount(int i) const
00472 {
00473 planck_assert(table_hdu(i),"incorrect FITS table access");
00474 return columns_[i-1].repcount();
00475 }
00476 PDT fitshandle::coltype(int i) const
00477 {
00478 planck_assert(table_hdu(i),"incorrect FITS table access");
00479 return columns_[i-1].type();
00480 }
00481 int fitshandle::ncols() const
00482 {
00483 planck_assert(table_hdu(1),"incorrect FITS table access");
00484 return columns_.size();
00485 }
00486 int64 fitshandle::nrows() const
00487 {
00488 planck_assert(table_hdu(1),"incorrect FITS table access");
00489 return nrows_;
00490 }
00491 int64 fitshandle::nelems(int i) const
00492 {
00493 planck_assert(table_hdu(i),"incorrect FITS table access");
00494 if (columns_[i-1].type()==PLANCK_STRING) return nrows_;
00495 return nrows_*columns_[i-1].repcount();
00496 }
00497 int64 fitshandle::efficientChunkSize(int i) const
00498 {
00499 planck_assert(table_hdu(1),"incorrect FITS table access");
00500 long int res;
00501 fits_get_rowsize(FPTR, &res, &status);
00502 planck_assert(res>=1,"bad recommended FITS chunk size");
00503 check_errors();
00504 return res*columns_[i-1].repcount();
00505 }
00506
00507 void fitshandle::get_all_keys(vector<string> &keys) const
00508 {
00509 keys.clear();
00510 char card[81];
00511 const char *inclist[] = { "*" };
00512 planck_assert(connected(),"handle not connected to a file");
00513 fits_read_record (FPTR, 0, card, &status);
00514 check_errors();
00515 while (true)
00516 {
00517 fits_find_nextkey (FPTR, const_cast<char **>(inclist), 1,
00518 0, 0, card, &status);
00519 if (status!=0) break;
00520 if (fits_get_keyclass(card)==TYP_USER_KEY)
00521 {
00522 char keyname[80];
00523 int dummy;
00524 fits_get_keyname(card, keyname, &dummy, &status);
00525 check_errors();
00526 keys.push_back(trim(keyname));
00527 }
00528 check_errors();
00529 }
00530 if (status==KEY_NO_EXIST) { fits_clear_errmsg(); status=0; }
00531 check_errors();
00532 }
00533
00534 void fitshandle::set_key_void (const string &key, const void *value,
00535 PDT type, const string &comment)
00536 {
00537 planck_assert(connected(),"handle not connected to a file");
00538 string key2 = fixkey(key);
00539 switch (type)
00540 {
00541 case PLANCK_INT8:
00542 case PLANCK_UINT8:
00543 case PLANCK_INT16:
00544 case PLANCK_INT32:
00545 case PLANCK_INT64:
00546 case PLANCK_FLOAT32:
00547 case PLANCK_FLOAT64:
00548 fits_update_key (FPTR, type2ftc(type), const_cast<char *>(key2.c_str()),
00549 const_cast<void *>(value), const_cast<char *>(comment.c_str()),
00550 &status);
00551 break;
00552 case PLANCK_BOOL:
00553 {
00554 int val = *(static_cast<const bool *>(value));
00555 fits_update_key (FPTR, TLOGICAL, const_cast<char *>(key2.c_str()),
00556 &val, const_cast<char *>(comment.c_str()), &status);
00557 break;
00558 }
00559 case PLANCK_STRING:
00560 {
00561 string val = *(static_cast<const string *>(value));
00562 fits_update_key_longstr (FPTR, const_cast<char *>(key2.c_str()),
00563 const_cast<char *>(val.c_str()), const_cast<char *>(comment.c_str()),
00564 &status);
00565 break;
00566 }
00567 default:
00568 planck_fail ("unsupported data type in set_key_void()");
00569 }
00570 check_errors();
00571 }
00572
00573 void fitshandle::get_key_void (const string &name, void *value, PDT type) const
00574 {
00575 planck_assert(connected(),"handle not connected to a file");
00576 switch (type)
00577 {
00578 case PLANCK_INT8:
00579 case PLANCK_UINT8:
00580 case PLANCK_INT16:
00581 case PLANCK_INT32:
00582 case PLANCK_INT64:
00583 case PLANCK_FLOAT32:
00584 case PLANCK_FLOAT64:
00585 fits_read_key (FPTR, type2ftc(type), const_cast<char *>(name.c_str()),
00586 value, 0, &status);
00587 getKeyHelper(name);
00588 break;
00589 case PLANCK_BOOL:
00590 {
00591 int val;
00592 fits_read_key (FPTR, TLOGICAL, const_cast<char *>(name.c_str()), &val, 0,
00593 &status);
00594 getKeyHelper(name);
00595 *(static_cast<bool *>(value))=val;
00596 break;
00597 }
00598 case PLANCK_STRING:
00599 {
00600 char *tmp=0;
00601 fits_read_key_longstr (FPTR, const_cast<char *>(name.c_str()), &tmp, 0,
00602 &status);
00603 getKeyHelper(name);
00604 *(static_cast<string *>(value))=tmp;
00605 if (tmp) free(tmp);
00606 break;
00607 }
00608 default:
00609 planck_fail ("unsupported data type in get_key_void()");
00610 }
00611 check_errors();
00612 }
00613
00614 void fitshandle::delete_key (const string &name)
00615 {
00616 planck_assert(connected(),"handle not connected to a file");
00617 fits_delete_key (FPTR, const_cast<char *>(name.c_str()), &status);
00618 check_errors();
00619 }
00620
00621 void fitshandle::add_comment(const string &comment)
00622 {
00623 planck_assert(connected(),"handle not connected to a file");
00624 fits_write_comment(FPTR,const_cast<char *>(comment.c_str()),&status);
00625 check_errors();
00626 }
00627
00628 bool fitshandle::key_present(const string &name) const
00629 {
00630 char card[81];
00631 planck_assert(connected(),"handle not connected to a file");
00632 fits_read_card(FPTR, const_cast<char *>(name.c_str()), card, &status);
00633 if (status==KEY_NO_EXIST)
00634 { fits_clear_errmsg(); status=0; return false; }
00635 check_errors();
00636 return true;
00637 }
00638
00639 void fitshandle::assert_pdmtype (const string &pdmtype) const
00640 {
00641 string type;
00642 get_key("PDMTYPE",type);
00643 if (pdmtype==type) return;
00644 cerr << "PDMTYPE " << pdmtype << " expected, but found " << type << endl;
00645 }
00646
00647 void fitshandle::read_column_raw_void
00648 (int colnum, void *data, PDT type, int64 num, int64 offset) const
00649 {
00650 switch (type)
00651 {
00652 case PLANCK_INT8:
00653 case PLANCK_UINT8:
00654 case PLANCK_INT16:
00655 case PLANCK_INT32:
00656 case PLANCK_INT64:
00657 case PLANCK_FLOAT32:
00658 case PLANCK_FLOAT64:
00659 case PLANCK_BOOL:
00660 read_col (colnum, data, num, type, offset); break;
00661 case PLANCK_STRING:
00662 {
00663 string *data2 = static_cast<string *> (data);
00664 planck_assert(table_hdu(colnum),"incorrect FITS table access");
00665 planck_assert (num<=(nrows_-offset),
00666 "read_column(): array too large");
00667 arr2b<char> tdata(safe_cast<tsize>(num),
00668 safe_cast<tsize>(columns_[colnum-1].repcount()+1));
00669 int dispwidth;
00670 fits_get_col_display_width(FPTR, colnum, &dispwidth, &status);
00671 planck_assert(dispwidth<=columns_[colnum-1].repcount(),"column too wide");
00672 fits_read_col (FPTR, TSTRING, colnum, offset+1, 1, num,
00673 0, tdata.p0(), 0, &status);
00674 check_errors();
00675 for (long m=0;m<num;++m) data2[m]=tdata[m];
00676 break;
00677 }
00678 default:
00679 planck_fail ("unsupported data type in read_column_raw_void()");
00680 }
00681 }
00682
00683 void fitshandle::write_column_raw_void
00684 (int colnum, const void *data, PDT type, int64 num, int64 offset)
00685 {
00686 switch (type)
00687 {
00688 case PLANCK_INT8:
00689 case PLANCK_UINT8:
00690 case PLANCK_INT16:
00691 case PLANCK_INT32:
00692 case PLANCK_INT64:
00693 case PLANCK_FLOAT32:
00694 case PLANCK_FLOAT64:
00695 case PLANCK_BOOL:
00696 write_col (colnum, data, num, type, offset); break;
00697 case PLANCK_STRING:
00698 {
00699 const string *data2 = static_cast<const string *> (data);
00700 planck_assert(table_hdu(colnum),"incorrect FITS table access");
00701 tsize stringlen = safe_cast<tsize>(columns_[colnum-1].repcount()+1);
00702 arr2b<char> tdata(safe_cast<tsize>(num), stringlen);
00703 for (long m=0;m<num;++m)
00704 {
00705 strncpy(tdata[m],data2[m].c_str(),stringlen-1);
00706 tdata[m][stringlen-1] = '\0';
00707 }
00708 fits_write_col (FPTR, TSTRING, colnum, offset+1, 1, num,
00709 tdata.p0(), &status);
00710 nrows_ = max(nrows_,offset+num);
00711 check_errors();
00712 break;
00713 }
00714 default:
00715 planck_fail ("unsupported data type in write_column_raw_void()");
00716 }
00717 }
00718
00719 void fitshandle::write_image2D_void (const void *data, PDT type, tsize s1,
00720 tsize s2)
00721 {
00722 planck_assert(image_hdu(),"not connected to an image");
00723 planck_assert (axes_.size()==2, "wrong number of dimensions");
00724 planck_assert (axes_[0]==int64(s1), "wrong size of dimension 1");
00725 planck_assert (axes_[1]==int64(s2), "wrong size of dimension 2");
00726
00727 fits_write_img (FPTR, type2ftc(type), 1, axes_[0]*axes_[1],
00728 const_cast<void *>(data), &status);
00729 check_errors();
00730 }
00731
00732 void fitshandle::write_subimage_void (const void *data, PDT type, tsize sz,
00733 int64 offset)
00734 {
00735 planck_assert(image_hdu(),"not connected to an image");
00736 fits_write_img (FPTR, type2ftc(type), 1+offset, sz, const_cast<void *>(data),
00737 &status);
00738 check_errors();
00739 }
00740
00741 template<typename T> void fitshandle::read_image (arr2<T> &data) const
00742 {
00743 planck_assert(image_hdu(),"not connected to an image");
00744 planck_assert (axes_.size()==2, "wrong number of dimensions");
00745 data.alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]));
00746 fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1], 0, &data[0][0], 0,
00747 &status);
00748 check_errors();
00749 }
00750
00751 template void fitshandle::read_image (arr2<float> &data) const;
00752 template void fitshandle::read_image (arr2<double> &data) const;
00753
00754 template<typename T> void fitshandle::read_image (arr3<T> &data) const
00755 {
00756 planck_assert(image_hdu(),"not connected to an image");
00757 planck_assert (axes_.size()==3, "wrong number of dimensions");
00758 data.alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]),
00759 safe_cast<tsize>(axes_[2]));
00760 fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1]*axes_[2],
00761 0, &data(0,0,0), 0, &status);
00762 check_errors();
00763 }
00764
00765 template void fitshandle::read_image (arr3<float> &data) const;
00766 template void fitshandle::read_image (arr3<double> &data) const;
00767
00768 template<typename T> void fitshandle::read_subimage
00769 (arr2<T> &data, int xl, int yl) const
00770 {
00771 planck_assert(image_hdu(),"not connected to an image");
00772 planck_assert (axes_.size()==2, "wrong number of dimensions");
00773 for (tsize m=0; m<data.size1(); ++m)
00774 fits_read_img (FPTR, fitsType<T>(), (xl+m)*axes_[1]+yl+1,
00775 data.size2(), 0, &data[m][0], 0, &status);
00776 check_errors();
00777 }
00778
00779 template void fitshandle::read_subimage
00780 (arr2<float> &data, int xl, int yl) const;
00781 template void fitshandle::read_subimage
00782 (arr2<double> &data, int xl, int yl) const;
00783
00784 void fitshandle::read_subimage_void (void *data, PDT type, tsize ndata,
00785 int64 offset) const
00786 {
00787 planck_assert(image_hdu(),"not connected to an image");
00788 fits_read_img (FPTR, type2ftc(type), 1+offset, ndata, 0, data, 0, &status);
00789 check_errors();
00790 }
00791
00792 namespace {
00793
00794 class cfitsio_checker
00795 {
00796 public:
00797 cfitsio_checker()
00798 {
00799 float fitsversion;
00800 planck_assert(fits_get_version(&fitsversion),
00801 "error calling fits_get_version()");
00802 int v_header = nearest<int>(1000.*CFITSIO_VERSION),
00803 v_library = nearest<int>(1000.*fitsversion);
00804 if (v_header!=v_library)
00805 cerr << endl << "WARNING: version mismatch between CFITSIO header (v"
00806 << dataToString(v_header*0.001) << ") and linked library (v"
00807 << dataToString(v_library*0.001) << ")." << endl << endl;
00808 }
00809 };
00810
00811 cfitsio_checker Cfitsio_Checker;
00812
00813 }