psrfitsio.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2006 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 // psrchive/Util/fitsutil/psrfitsio.h
10 
11 #ifndef __psrfitsio_h
12 #define __psrfitsio_h
13 
14 #include "FITSError.h"
15 #include "fitsutil.h"
16 
17 #include <fitsio.h>
18 
19 #include <string>
20 #include <vector>
21 
22 extern bool psrfits_verbose;
23 
25 template<typename T> struct FITS_traits { };
26 
28 template<> struct FITS_traits<double>
29 {
30  static inline int datatype() { return TDOUBLE; }
31  static inline double null () { return 0; }
32 };
33 
35 template<> struct FITS_traits<float>
36 {
37  static inline int datatype() { return TFLOAT; }
38  static inline float null () { return fits_nullfloat; }
39 };
40 
42 template<> struct FITS_traits<short>
43 {
44  static inline int datatype() { return TSHORT; }
45  static inline short null () { return -1; }
46 };
47 
49 template<> struct FITS_traits<int>
50 {
51  static inline int datatype() { return TINT; }
52  static inline int null () { return -1; }
53 };
54 
56 template<> struct FITS_traits<long> {
57  static inline int datatype() { return TLONG; }
58  static inline long null () { return -1; }
59 };
60 
62 template<> struct FITS_traits<long long> {
63  static inline int datatype() { return TLONGLONG; }
64  static inline long null () { return -1; }
65 };
66 
68 template<> struct FITS_traits<unsigned> {
69  static inline int datatype() { return TUINT; }
70  static inline long null () { return 0; }
71 };
72 
74 template<> struct FITS_traits<std::string>
75 {
76  static inline int datatype() { return TSTRING; }
77  static inline std::string null () { return ""; }
78 };
79 
80 template<typename T>
81 void* FITS_void_ptr (const T& ptr)
82 {
83  return const_cast<T*> (&ptr);
84 }
85 
86 void* FITS_void_ptr (const std::string&);
87 
89 template<typename T>
90 void psrfits_update_key (fitsfile* fptr, const char* name, T data,
91  const char* comment = 0)
92 {
93  // status
94  int status = 0;
95 
96  fits_update_key (fptr, FITS_traits<T>::datatype(),
97  const_cast<char*>(name), &data,
98  const_cast<char*>(comment), &status);
99 
100  if (status)
101  throw FITSError (status, "psrfits_update_key", name);
102 }
103 
105 void psrfits_update_key (fitsfile* fptr, const char* name,
106  const char* data,
107  const char* comment = 0);
108 
110 void psrfits_update_key (fitsfile* fptr, const char* name,
111  const std::string& data,
112  const char* comment = 0);
113 
115 void psrfits_update_key (fitsfile* fptr,
116  const char* name,
117  int column,
118  const std::string& value,
119  const char* comment = 0);
120 
122 void psrfits_read_key (fitsfile* fptr,
123  const char* name,
124  int column,
125  std::string& value,
126  std::string& comment);
127 
129 template<typename T>
130 void psrfits_read_key_work (fitsfile* fptr, const char* name, T* data,
131  int* status)
132 {
133  // no comment
134  char* comment = 0;
135 
136  fits_read_key (fptr, FITS_traits<T>::datatype(),
137  const_cast<char*>(name), data,
138  comment, status);
139 }
140 
142 void psrfits_read_key_work (fitsfile* fptr, const char* name, std::string*,
143  int* status);
144 
146 template<typename T>
147 void psrfits_read_key (fitsfile* fptr, const char* name, T* data)
148 {
149  // status
150  int status = 0;
151  psrfits_read_key_work (fptr, name, data, &status);
152  if (status)
153  throw FITSError (status, "psrfits_read_key", name);
154 }
155 
157 template<typename T>
158 void psrfits_read_key (fitsfile* fptr, const char* name, T* data,
159  T dfault, bool verbose = false)
160 {
161  // status
162  int status = 0;
163  psrfits_read_key_work (fptr, name, data, &status);
164  if (status)
165  {
166  if (verbose)
167  {
168  FITSError error (status, "psrfits_read_key", name);
169  std::cerr << error.get_message() << std::endl;
170  std::cerr << "psrfits_read_key: using default=" << dfault << std::endl;
171  }
172  *data = dfault;
173  }
174  else if (verbose)
175  std::cerr << "psrfits_read_key: " << name << "=" << *data << std::endl;
176 }
177 
179 void psrfits_update_tdim (fitsfile* ffptr, int column, unsigned dim);
180 
182 void psrfits_update_tdim (fitsfile* ffptr, int column,
183  unsigned dim1, unsigned dim2);
184 
186 void psrfits_update_tdim (fitsfile* ffptr, int column,
187  unsigned dim1, unsigned dim2, unsigned dim3);
188 
190 void psrfits_update_tdim (fitsfile* ffptr, int column,
191  unsigned dim1, unsigned dim2,
192  unsigned dim3, unsigned dim4);
193 
195 void psrfits_update_tdim (fitsfile* ffptr, int column,
196  const std::vector<unsigned>& dims);
197 
198 template<typename T>
199 void psrfits_write_col (fitsfile* fptr, const char* name, int row,
200  const std::vector<T>& data,
201  const std::vector<unsigned>& dims)
202 {
203  //
204  // Get the number of the named column
205 
206  int colnum = 0;
207  int status = 0;
208 
209  if (psrfits_verbose)
210  std::cerr << "psrfits_write_col calling fits_get_colnum"
211  " name='" << name << "'" << std::endl;
212 
213  fits_get_colnum (fptr, CASEINSEN, const_cast<char*>(name), &colnum, &status);
214 
215  if (status)
216  throw FITSError (status, "psrfits_write_col(vector<T>)",
217  "fits_get_colnum (name=%s)", name);
218 
219  psrfits_write_col (fptr, colnum, row, data, dims);
220 }
221 
222 /* when it is not feasible to write a single block of data in one go */
223 template<typename Stream>
224 void psrfits_write_col (fitsfile* fptr, const char* name, int row,
225  const Stream* stream)
226 {
227  //
228  // Get the number of the named column
229 
230  int colnum = 0;
231  int status = 0;
232 
233  if (psrfits_verbose)
234  std::cerr << "psrfits_write_col calling fits_get_colnum"
235  " name='" << name << "'" << std::endl;
236 
237  fits_get_colnum (fptr, CASEINSEN, const_cast<char*>(name), &colnum, &status);
238 
239  if (status)
240  throw FITSError (status, "psrfits_write_col(vector<T>)",
241  "fits_get_colnum (name=%s)", name);
242 
243  try
244  {
245  psrfits_write_col (fptr, colnum, row, stream);
246  }
247  catch (Error& error)
248  {
249  throw error += "psrfits_write_col(vector<T>," + std::string(name) + ")";
250  }
251 }
252 
253 template<typename T>
254 void psrfits_write_col (fitsfile* fptr, int colnum, int row,
255  const std::vector<T>& data,
256  const std::vector<unsigned>& dims)
257 {
258  int status = 0;
259 
260  if (psrfits_verbose)
261  std::cerr << "psrfits_write_col calling fits_modify_vector_len"
262  " colnum=" << colnum << " size=" << data.size() << std::endl;
263 
264  fits_modify_vector_len (fptr, colnum, data.size(), &status);
265 
266  if (status)
267  throw FITSError (status, "psrfits_write_col(vector<T>)",
268  "fits_modify_vector_len (col=%d size=%u)",
269  colnum, data.size());
270 
271  if (dims.size() > 1)
272  {
273  if (psrfits_verbose)
274  std::cerr << "psrfits_write_col calling psrfits_update_tdim" << std::endl;
275 
276  psrfits_update_tdim (fptr, colnum, dims);
277  }
278 
279  if (psrfits_verbose)
280  std::cerr << "psrfits_write_col calling fits_write_col" << std::endl;
281 
282  fits_write_col (fptr, FITS_traits<T>::datatype(),
283  colnum, row,
284  1, data.size(),
285  const_cast<T*>(&(data[0])), &status);
286 
287  if (status)
288  throw FITSError (status, "psrfits_write_col(vector<T>)",
289  "fits_write_col (type=%s col=%d row=%d size=%u)",
290  fits_datatype_str(FITS_traits<T>::datatype()),
291  colnum, row, data.size());
292 }
293 
294 template<typename Stream>
295 void psrfits_write_col (fitsfile* fptr, int colnum, int row,
296  const Stream* stream)
297 {
298  int status = 0;
299 
300  unsigned ndat = stream->get_ndat();
301 
302  if (psrfits_verbose)
303  std::cerr << "psrfits_write_col (Stream) calling fits_modify_vector_len"
304  " colnum=" << colnum << " size=" << ndat << std::endl;
305 
306  fits_modify_vector_len (fptr, colnum, ndat, &status);
307 
308  if (status)
309  throw FITSError (status, "psrfits_write_col(vector<T>)",
310  "fits_modify_vector_len (col=%d size=%u)",
311  colnum, ndat);
312 
313  unsigned nwritten = 0;
314 
315  unsigned buffer_size = 1024 * 1024;
316 
317  std::vector< typename Stream::Type > tmp ( buffer_size );
318  while (nwritten < ndat)
319  {
320  if (nwritten + buffer_size > ndat)
321  buffer_size = ndat - nwritten;
322 
323  stream->get_data (nwritten, buffer_size, &tmp[0] );
324 
325  fits_write_col (fptr, FITS_traits< typename Stream::Type >::datatype(),
326  colnum, row,
327  nwritten + 1, buffer_size,
328  &(tmp[0]), &status);
329 
330  if (status)
331  throw FITSError (status, "psrfits_write_col(Stream)",
332  "fits_write_col (type=%s col=%d row=%d size=%u)",
334  colnum, row, buffer_size);
335 
336  nwritten += buffer_size;
337  }
338 }
339 
340 template<typename T>
341 void psrfits_write_col( fitsfile *fptr, const char *name, int row,
342  const T& data )
343 {
344  int colnum = 0;
345  int status = 0;
346 
347  fits_get_colnum (fptr, CASEINSEN, const_cast<char*>(name), &colnum, &status);
348 
349  if (status)
350  throw FITSError (status, "psrfits_write_col(T)",
351  "fits_get_colnum (name=%s)", name);
352 
353  try {
354  psrfits_write_col (fptr, colnum, row, data);
355  }
356  catch (Error& error)
357  {
358  throw error += "psrfits_write_col(T," + std::string(name) + ")";
359  }
360 }
361 
362 template<typename T>
363 void psrfits_write_col( fitsfile *fptr, int colnum, int row, const T& data )
364 {
365  int status = 0;
366 
367  fits_write_col (fptr, FITS_traits<T>::datatype(),
368  colnum, row,
369  1, 1,
370  FITS_void_ptr(data), &status);
371 
372  if (status)
373  throw FITSError (status, "psrfits_write_col(T)",
374  "col=%d row=%d", colnum, row);
375 }
376 
377 template<typename T>
378 void psrfits_read_col (fitsfile* fptr, const char* name,
379  std::vector< std::vector<T> >& data,
380  int row = 1, T null = FITS_traits<T>::null())
381 {
382  //
383  // Get the number of the named column
384 
385  int colnum = 0;
386  int status = 0;
387 
388  fits_get_colnum (fptr, CASEINSEN, const_cast<char*>(name), &colnum, &status);
389 
390  int anynul = 0;
391  int counter = 1;
392 
393  for (unsigned i = 0; i < data.size(); i++)
394  {
395  fits_read_col (fptr, FITS_traits<T>::datatype(),
396  colnum, row,
397  counter, data[i].size(),
398  &null, &(data[i][0]),
399  &anynul, &status);
400 
401  if (status != 0)
402  throw FITSError( status, "psrfits_read_col",
403  "%s colnum=%d firstrow=%d firstelem=%d nelements=%d",
404  name, colnum, row, counter, data[i].size() );
405 
406  counter += data[i].size();
407  }
408 
409 }
410 
411 template<typename T>
412 void psrfits_read_col (fitsfile* fptr, const char* name, std::vector<T>& data,
413  int row = 1, T null = FITS_traits<T>::null())
414 {
415  //
416  // Get the number of the named column
417 
418  int colnum = 0;
419  int status = 0;
420 
421  fits_get_colnum (fptr, CASEINSEN, const_cast<char*>(name), &colnum, &status);
422 
423  //
424  // If the vector length is unspecified, read it from the file
425 
426  if (data.size() == 0)
427  {
428  int typecode = 0;
429  long repeat = 0;
430  long width = 0;
431 
432  fits_get_coltype (fptr, colnum, &typecode, &repeat, &width, &status);
433  if (status)
434  throw FITSError (status, "psrfits_read_col",
435  "fits_get_coltype (%s)", name);
436 
437  data.resize( repeat );
438  }
439 
440  int anynul = 0;
441  fits_read_col (fptr, FITS_traits<T>::datatype(),
442  colnum, row,
443  1, data.size(),
444  &null, &(data[0]),
445  &anynul, &status);
446 
447  if (status)
448  throw FITSError (status, "psrfits_read_col", name);
449 }
450 
452 template< typename T >
453 void psrfits_read_col_work( fitsfile *fptr, const char *name, T *data,
454  int row, T null, int* status)
455 {
456  int colnum = 0;
457  fits_get_colnum (fptr, CASEINSEN, const_cast<char*>(name), &colnum, status);
458 
459  int anynul = 0;
460  fits_read_col( fptr, FITS_traits<T>::datatype(),
461  colnum, row,
462  1, 1, &null, data,
463  &anynul, status );
464 }
465 
467 void psrfits_read_col_work( fitsfile *fptr, const char *name,
468  std::string *data,
469  int row, std::string& null, int* status);
470 
471 
472 template< typename T >
473 void psrfits_read_col( fitsfile *fptr, const char *name, T *data,
474  int row = 1, T null = FITS_traits<T>::null() )
475 {
476  int status = 0;
477  psrfits_read_col_work (fptr, name, data, row, null, &status);
478  if (status)
479  throw FITSError (status, "psrfits_read_call", name);
480 }
481 
483 template< typename T >
484 void psrfits_read_col( fitsfile *fptr, const char *name, T *data,
485  int row, T null, T dfault, bool verbose)
486 {
487  // status
488  int status = 0;
489  psrfits_read_col_work (fptr, name, data, row, null, &status);
490  if (status)
491  {
492  if (verbose)
493  {
494  FITSError error (status, "psrfits_read_col", name);
495  std::cerr << error.get_message() << std::endl;
496  std::cerr << "psrfits_read_col: using default=" << dfault << std::endl;
497  }
498  *data = dfault;
499  }
500  else if (verbose)
501  std::cerr << "psrfits_read_col: " << name << "=" << *data << std::endl;
502 
503 }
504 
506 void psrfits_init_hdu (fitsfile *fptr, const char *name, unsigned nrows=1);
507 
509 bool psrfits_move_hdu (fitsfile *fptr, const char *name,
510  bool optional = false,
511  int table_type = BINARY_TBL, int version = 0);
512 
514 void psrfits_clean_rows (fitsfile*);
515 
517 void psrfits_set_rows (fitsfile*, unsigned nrow);
518 
520 void psrfits_insert_row (fitsfile* fptr);
521 
523 void psrfits_delete_col (fitsfile* fptr, const char* name);
524 
525 #endif
A convenient exception handling class.
Definition: Error.h:54
Empty template class requires specialization.
Definition: psrfitsio.h:25

Generated using doxygen 1.8.17