mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
fitsFile.hpp
Go to the documentation of this file.
1 /** \file fitsFile.hpp
2  * \brief Declares and defines a class to work with a FITS file
3  * \ingroup fits_processing_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2015-2022 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef ioutils_fits_fitsFile_hpp
28 #define ioutils_fits_fitsFile_hpp
29 
30 
31 #include "../../mxError.hpp"
32 
33 #include "../../improc/eigenImage.hpp"
34 
35 #include "fitsUtils.hpp"
36 #include "fitsHeader.hpp"
37 
38 namespace mx
39 {
40 namespace fits
41 {
42 
43 
44 
45 /// Class to manage interactions with a FITS file
46 /** This class wraps the functionality of cfitsio.
47  *
48  * \tparam dataT is the datatype to use for in-memory storage of the image. This does not have to match the data type stored on disk for reading, but will be the type used for writing.
49  *
50  * \ingroup fits_processing
51  */
52 template<typename dataT>
53 class fitsFile
54 {
55 
56  friend class fitsFile_test;
57 
58 protected:
59 
60  ///The path to the file
61  std::string m_fileName;
62 
63  ///The cfitsio data structure
64  fitsfile * m_fptr {nullptr};
65 
66  ///The dimensions of the image (1D, 2D, 3D etc)
67  int m_naxis;
68 
69  ///The size of each dimension
70  long * m_naxes {nullptr};
71 
72  ///Flag indicating whether the file is open or not
73  bool m_isOpen {false};
74 
75  ///The value to replace null values with
76  dataT m_nulval {0};
77 
78  ///Records whether any null values were replaced
79  int m_anynul {0};
80 
81  ///Flag to control whether the comment string is read.
82  int m_noComment {0};
83 
84 
85  ///The starting x-pixel to read from
86  long m_x0 {-1};
87 
88  ///The starting y-pixel to read from
89  long m_y0 {-1};
90 
91  ///The number of x-pixels to read
92  long m_xpix {-1};
93 
94  ///The number of y-pixels to read
95  long m_ypix {-1};
96 
97  ///The starting frame to read from a cube
98  long m_z0 {-1};
99 
100  ///The number of frames to read from a cube
101  long m_zframes {-1};
102 
103  ///One time initialization common to all constructors
104  void construct();
105 
106 public:
107 
108  ///Default constructor
109  fitsFile();
110 
111  ///Constructor with m_fileName, and option to open.
112  fitsFile( const std::string & fname, ///<File name to set on construction
113  bool doopen = true ///< If true, then the file is opened (the default).
114  );
115 
116  ///Destructor
117  ~fitsFile();
118 
119  ///Get the current value of m_fileName
120  /**
121  * \returns the current value of m_fileName.
122  */
123  std::string fileName();
124 
125  ///Set the file path, and optionally open the file.
126  /**
127  * \returns 0 on success
128  * \returns -1 on success
129  */
130  int fileName( const std::string & fname, ///< The new file name.
131  bool doopen = true ///< If true, then the file is opened (the default).
132  );
133 
134  ///Get the current value of m_naxis
135  /**
136  * \returns the current value of m_naxis
137  *
138  * \test Scenario: fitsFile calculating subimage sizes \ref tests_ioutils_fits_fitsFile_subimage_sizes "[test doc]"
139  */
140  int naxis();
141 
142  ///Get the current value of m_naxes for the specified dimension
143  /**
144  * \returns the current value of m_naxes for the specified dimension. -1 if no such dimension
145  *
146  * \test Scenario: fitsFile calculating subimage sizes \ref tests_ioutils_fits_fitsFile_subimage_sizes "[test doc]"
147  */
148  long naxes( int dim /**< [in] the dimension */);
149 
150  /// Open the file and gets its dimensions.
151  /** File name needs to already have been set.
152  * If the file has already been opened, this returns immediately with no re-open.
153  *
154  * \returns 0 on success
155  * \returns -1 on error
156  */
157  int open();
158 
159  ///Open the file, first setting the file path.
160  /**
161  * \returns 0 on success
162  * \returns -1 on error
163  */
164  int open( const std::string & fname /**< The name of the file to open. */);
165 
166  ///Close the file.
167  /**
168  * \returns 0 on success
169  * \returns -1 on error
170  */
171  int close();
172 
173  ///Get the number of dimensions (i.e. m_naxis)
174  int getDimensions();
175 
176  ///Get the total size
177  long getSize();
178 
179  ///Get the size of a specific dimension
180  long getSize(size_t axis);
181 
182 
183  /** \name Reading Basic Arrays
184  * These methods read FITS data into basic or raw arrays specified by a pointer.
185  * @{
186  */
187 
188 protected:
189 
190  /// Fill in the read-size arrays for reading a subset (always used)
191  /** \note this allocates with new. You are responsible for calling delete.
192  *
193  * \test Scenario: fitsFile calculating subimage sizes \ref tests_ioutils_fits_fitsFile_subimage_sizes "[test doc]"
194  */
195  void pixarrs( long ** fpix, ///< Populated with the lower left pixel to read. Is allocated.
196  long ** lpix, ///< Populated with the upper right pixel to read. Is allocated.
197  long ** inc ///< The increment. Is allocated.
198  );
199 
200 public:
201 
202  ///Read the contents of the FITS file into an array.
203  /** The array pointed to by data must have been allocated.
204  *
205  * \returns 0 on success
206  * \returns -1 on error
207  */
208  int read( dataT * data /**< [out] an allocated arrray large enough to hold the entire image */ );
209 
210  ///Read the contents of the FITS file into an array.
211  /** The array pointed to by data must have been allocated.
212  *
213  * \returns 0 on success
214  * \returns -1 on error
215  */
216  int read( dataT * data, ///< [out] an allocated arrray large enough to hold the entire image
217  fitsHeader &head ///< [out] a fitsHeader object which is passed to \ref readHeader
218  );
219 
220  ///Read the contents of the FITS file into an array.
221  /** The array pointed to by data must have been allocated.
222  *
223  * \returns 0 on success
224  * \returns -1 on error
225  */
226  int read( dataT * data, ///< [out] is an allocated arrray large enough to hold the entire image
227  const std::string &fname ///< [in] is the file path, which is passed to \ref fileName
228  );
229 
230  ///Read the contents of the FITS file into an array and read the header.
231  /** The array pointed to by data must have been allocated.
232  *
233  * \returns 0 on success
234  * \returns -1 on error
235  */
236  int read( dataT * data, ///< [out] an allocated arrray large enough to hold the entire image
237  fitsHeader &head, ///< [out] a fitsHeader object which is passed to \ref readHeader
238  const std::string &fname ///< [in] the file path, which is passed to \ref fileName
239  );
240 
241  ///Read data from a vector list of files into an image cube
242  int read( dataT * im, ///< [out] An allocated array large enough to hold all the images
243  const std::vector<std::string> & flist ///< [in] The list of files to read.
244  );
245 
246  ///Read data from a vector of files into an image cube with individual headers
247  int read( dataT * im, ///< [out] An allocated array large enough to hold all the images
248  std::vector<fitsHeader> &heads, ///< [in.out] The vector of fits headers, allocated to contain one per image.
249  const std::vector<std::string> & flist ///< [in] The list of files to read.
250  );
251 
252 
253  ///@}
254 
255  /** \name Reading Eigen Arrays
256  * These methods read FITS data into array types with an Eigen-like interface.
257  * @{
258  */
259 
260  ///Read the contents of the FITS file into an Eigen array type (not a simple pointer).
261  /** The type arrT can be any type with the following members defined:
262  * - resize(int, int) (allocates memory)
263  * - data() (returns a pointer to the underlying array)
264  * - typedef arrT::Scalar (is the data type, does not have to be dataT)
265  *
266  * \tparam arrT is the type of array, see requirements above.
267  *
268  * \returns 0 on success
269  * \returns -1 on error
270  */
271  template<typename arrT>
272  int read( arrT & data /**< [out] is the array, which will be resized as necessary using its resize(int, int) member */);
273 
274  ///Read the contents of the FITS file into an Eigen array type (not a simple pointer).
275  /** The type arrT can be any type with the following members defined:
276  * - resize(int, int) (allocates memory)
277  * - data() (returns a pointer to the underlying array)
278  * - typedef arrT::Scalar (is the data type, does not have to be dataT)
279  *
280  * \tparam arrT is the type of array, see requirements above.
281  *
282  * \returns 0 on success
283  * \returns -1 on error
284  */
285  template<typename arrT>
286  int read( arrT & data, ///< [out] is the array, which will be resized as necessary using its resize(int, int) member
287  fitsHeader &head ///< [out] is a fitsHeader object which is passed to \ref readHeader
288  );
289 
290  ///Read the contents of the FITS file into an Eigen array type (not a simple pointer).
291  /** The type arrT can be any type with the following members defined:
292  * - resize(int, int) (allocates memory)
293  * - data() (returns a pointer to the underlying array)
294  * - typedef arrT::Scalar (is the data type, does not have to be dataT)
295  *
296  * \tparam arrT is the type of array, see requirements above.
297  *
298  * \returns 0 on success
299  * \returns -1 on error
300  */
301  template<typename arrT>
302  int read( arrT & data, ///< [out] is the array, which will be resized as necessary using its resize(int, int) member
303  const std::string &fname ///< [in] is the file path, which is passed to \ref fileName
304  );
305 
306  ///Read the contents of the FITS file into an Eigen array type (not a simple pointer).
307  /** The type arrT can be any type with the following members defined:
308  * - resize(int, int) (allocates memory)
309  * - data() (returns a pointer to the underlying array)
310  * - typedef arrT::Scalar (is the data type, does not have to be dataT)
311  *
312  * \tparam arrT is the type of array, see requirements above.
313  *
314  * \returns 0 on success
315  * \returns -1 on error
316  */
317  template<typename arrT>
318  int read( arrT & data, ///< [out] the array, which will be resized as necessary using its resize(int, int) member
319  fitsHeader &head, ///< [out] a fitsHeader object which is passed to \ref readHeader
320  const std::string &fname ///< [in] the file path, which is passed to \ref fileName
321  );
322 
323  ///Read data from a vector list of files into an image cube
324  /** The type cubeT can be any type with the following members defined:
325  * - resize(int, int, int) (allocates memory)
326  * - data() (returns a pointer to the underlying array)
327  * - typedef cubeT::Scalar (is the data type, does not have to be dataT)
328  *
329  * \note The images must all be the same size, or all be as large or larger than the subset specified.
330  *
331  * \tparam cubeT is the type of array, see requirements above.
332  *
333  * \returns 0 on success
334  * \returns -1 on error
335  */
336  template<typename cubeT>
337  int read( cubeT & cube, ///< [out] A cube which will be resized using its resize(int, int, int) member.
338  const std::vector<std::string> & flist, ///< [in] The list of files to read.
339  std::vector<fitsHeader> * heads = 0 ///< [out] [optional] A vector of fits headers, allocated to contain one per image.
340  );
341 
342  ///Read data from a vector of files into an image cube with individual headers
343  /** The type cubeT can be any type with the following members defined:
344  * - resize(int, int, int) (allocates memory)
345  * - data() (returns a pointer to the underlying array)
346  * - typedef cubeT::Scalar (is the data type, does not have to be dataT)
347  *
348  * \tparam cubeT is the type of array, see requirements above.
349  *
350  * \returns 0 on success
351  * \returns -1 on error
352  */
353  template<typename cubeT>
354  int read( cubeT & cube, ///< [out] A cube which will be resized using its resize(int, int, int) member.
355  std::vector<fitsHeader> &heads, ///< [out] The vector of fits headers, allocated to contain one per image.
356  const std::vector<std::string> & flist ///< [in] The list of files to read.
357  );
358 
359 
360  ///@}
361 
362 
363  /** \name Reading Headers
364  * @{
365  */
366 
367  ///Read the header from the fits file.
368  /** If head is not empty, then only the keywords already in head are updated. Otherwise
369  * the complete header is read.
370  *
371  * \returns 0 on success
372  * \returns -1 on error
373  */
374  int readHeader(fitsHeader &head /**< [out] a fitsHeader object */);
375 
376  ///Read the header from the fits file.
377  /** If head is not empty, then only the keywords already in head are updated. Otherwise
378  * the complete header is read.
379  *
380  * \returns 0 on success
381  * \returns -1 on error
382  */
383  int readHeader( fitsHeader &head, ///< [out] a fitsHeader object
384  const std::string &fname ///< [in] the file path, which is passed to \ref fileName
385  );
386 
387  /// Read the headers from a list of FITS files.
388  /** In each case, if the header is not empty then only the keywords already in head are updated. Otherwise
389  * the complete header is read.
390  *
391  * \returns 0 on success
392  * \returns -1 on error
393  */
394  int readHeader( std::vector<fitsHeader> & heads, /// A vector of fitsHeader objects to read into.
395  const std::vector<std::string> & flist ///< [in] A list of files, each of which is passed to \ref fileName
396  );
397 
398  ///@}
399 
400  /** \name Writing Basic Arrays
401  * These methods write basic arrays specified by a pointer to FITS.
402  * @{
403  */
404 
405  ///Write the contents of a raw array to the FITS file.
406  /**
407  * \returns 0 on success
408  * \returns -1 on error
409  */
410  int write( const dataT * im, ///< [in] is the array
411  int d1, ///< [in] is the first dimension
412  int d2, ///< [in] is the second dimension
413  int d3, ///< [in] is the third dimenesion (minimum value is 1)
414  fitsHeader * head ///< [in] a pointer to the header. Set to 0 if not used.
415  );
416 
417  ///Write the contents of a raw array to the FITS file.
418  /**
419  * \returns 0 on success
420  * \returns -1 on error
421  */
422  int write( const dataT * im, ///< [in] is the array
423  int d1, ///< [in] is the first dimension
424  int d2, ///< [in] is the second dimension
425  int d3 ///< [in] is the third dimenesion (minimum value is 1)
426  );
427 
428  ///Write the contents of a raw array to the FITS file.
429  /**
430  * Note: the type of the array must match dataT
431  *
432  * \returns 0 on success
433  * \returns -1 on error
434  */
435  int write( const dataT * im, ///< [in] is the array
436  int d1, ///< [in] is the first dimension
437  int d2, ///< [in] is the second dimension
438  int d3, ///< [in] is the third dimenesion (minimum value is 1)
439  fitsHeader & head ///< [in] is the header
440  );
441 
442  ///Write the contents of a raw array to the FITS file.
443  /**
444  * \returns 0 on success
445  * \returns -1 on error
446  */
447  int write( const std::string & fname, ///< [in] is the name of the file.
448  const dataT * im, ///< [in] is the array
449  int d1, ///< [in] is the first dimension
450  int d2, ///< [in] is the second dimension
451  int d3 ///< [in] is the third dimenesion (minimum value is 1)
452  );
453 
454  ///Write the contents of a raw array to the FITS file.
455  /**
456  * \returns 0 on success
457  * \returns -1 on error
458  */
459  int write( const std::string & fname, ///< [in] is the name of the file.
460  const dataT * im, ///< [in] is the array
461  int d1, ///< [in] is the first dimension
462  int d2, ///< [in] is the second dimension
463  int d3, ///< [in] is the third dimenesion (minimum value is 1)
464  fitsHeader & head ///< [in] is the header
465  );
466 
467  ///@}
468 
469  /** \name Writing Eigen Arrays
470  * These methods write array types with an Eigen-like interface.
471  * @{
472  */
473 
474  ///Write the contents of an Eigen-type array to a FITS file.
475  /** The type arrT can be any type with the following members defined:
476  * - data() (returns a pointer to the underlying array)
477  * - rows() (returrns the number of rows)
478  * - cols() (returns the number of columns)
479  * - may have planes() defined
480  *
481  * Note: as with all write methods, the Scalar type of the array must match dataT
482  *
483  * \tparam arrT is the type of array, see requirements above.
484  *
485  * \returns 0 on success
486  * \returns -1 on error
487  */
488  template<typename arrT>
489  int write( const std::string & fname, ///< [in] is the name of the file.
490  const arrT & im ///< [in] is the array
491  );
492 
493  ///Write the contents of an Eigen-type array to a FITS file.
494  /** The type arrT can be any type with the following members defined:
495  * - data() (returns a pointer to the underlying array)
496  * - rows() (returrns the number of rows)
497  * - cols() (returns the number of columns)
498  * - may have planes() defined.
499  *
500  * Note: as with all write methods, the Scalar type of the array must match dataT
501  *
502  * \tparam arrT is the type of array, see requirements above.
503  *
504  * \returns 0 on success
505  * \returns -1 on error
506  */
507  template<typename arrT>
508  int write( const std::string & fname, ///< [in] is the file path, which is passed to \ref fileName
509  const arrT & im, ///< [in] is the array
510  fitsHeader & head ///< [in] is a fitsHeader object which is passed to \ref readHeader
511  );
512 
513  //int writeHeader( fitsHeader &head );
514 
515  ///@}
516 
517  /** \name Reading Subsets
518  * It is often desirable to read only a subset of an image or images into memory. These methods
519  * allow you to specify this.
520  * @{
521  */
522 
523  ///Set to read all the pixels in the file
524  void setReadSize();
525 
526  ///Set to read only a subset of the pixels in the file
527  /**
528  *
529  * \test Scenario: fitsFile calculating subimage sizes \ref tests_ioutils_fits_fitsFile_subimage_sizes "[test doc]"
530  */
531  void setReadSize( long x0, ///< is the starting x-pixel to read
532  long y0, ///< is the starting y-pixel to read
533  long xpix, ///< is the number of x-pixels to read
534  long ypix ///< is the number of y-pixels to read
535  );
536 
537  ///Set to read all frames from a cube.
538  /**
539  */
540  void setCubeReadSize();
541 
542  ///Set the number of frames to read from a cube.
543  /**
544  *
545  * \test Scenario: fitsFile calculating subimage sizes \ref tests_ioutils_fits_fitsFile_subimage_sizes "[test doc]"
546  */
547  void setCubeReadSize( long z0, ///< is the starting frame to read
548  long zframes ///< is the number of frames to read
549  );
550 
551  ///@}
552 
553 }; // fitsFile
554 
555 
556 template<typename dataT>
558 {
559 }
560 
561 template<typename dataT>
563 {
564  construct();
565 }
566 
567 template<typename dataT>
568 fitsFile<dataT>::fitsFile(const std::string &fname, bool doopen)
569 {
570  construct();
571  fileName(fname, doopen);
572 }
573 
574 template<typename dataT>
576 {
577  if(m_isOpen) close();
578 
579  if(m_naxes) delete[] m_naxes;
580 }
581 
582 template<typename dataT>
584 {
585  return m_fileName;
586 }
587 
588 template<typename dataT>
589 int fitsFile<dataT>::fileName(const std::string &fname, bool doopen)
590 {
591  if(m_isOpen)
592  {
593  close();
594  }
595 
596  m_fileName = fname;
597 
598  if(doopen)
599  {
600  return open();
601  }
602 
603  return 0;
604 
605 }
606 
607 template<typename dataT>
609 {
610  return m_naxis;
611 }
612 
613 template<typename dataT>
615 {
616  if(m_naxes == nullptr) return -1;
617 
618  if(dim >= m_naxis) return -1;
619 
620  return m_naxes[dim];
621 }
622 
623 template<typename dataT>
625 {
626  if(m_isOpen) //no-op
627  {
628  return 0;
629  }
630 
631  int fstatus = 0;
632 
633  fits_open_file(&m_fptr, m_fileName.c_str(), READONLY, &fstatus);
634 
635  if (fstatus)
636  {
637  std::string explan = "Error opening file";
638  fitsErrText(explan, m_fileName, fstatus);
639  mxError("fitsFile", MXE_FILEOERR, explan);
640 
641  return -1;
642 
643  }
644 
645  fits_get_img_dim(m_fptr, &m_naxis, &fstatus);
646  if (fstatus)
647  {
648  std::string explan = "Error getting number of axes in file";
649  fitsErrText(explan, m_fileName, fstatus);
650  mxError("fitsFile", MXE_FILERERR, explan);
651 
652  return -1;
653 
654  }
655 
656  if(m_naxes) delete[] m_naxes;
657  m_naxes = new long[m_naxis];
658 
659  fits_get_img_size(m_fptr, m_naxis, m_naxes, &fstatus);
660  if (fstatus)
661  {
662  std::string explan = "Error getting dimensions in file";
663  fitsErrText(explan, m_fileName, fstatus);
664  mxError("fitsFile", MXE_FILERERR, explan);
665 
666  return -1;
667  }
668 
669  m_isOpen = true; //Only set this after opening is complete.
670 
671  return 0;
672 }
673 
674 template<typename dataT>
675 int fitsFile<dataT>::open(const std::string & fname)
676 {
677  return fileName(fname, true);
678 }
679 
680 template<typename dataT>
682 {
683  if(!m_isOpen)
684  {
685  return 0; //No error.
686  }
687 
688  int fstatus = 0;
689  fits_close_file(m_fptr, &fstatus);
690 
691  if (fstatus)
692  {
693  std::string explan = "Error closing file";
694  fitsErrText( explan, m_fileName, fstatus);
695  mxError("fitsFile", MXE_FILECERR, explan);
696 
697  return -1;
698  }
699 
700  m_isOpen = 0;
701  fstatus = 0;
702 
703  if(m_naxes) delete[] m_naxes;
704 
705  m_naxes = nullptr;
706 
707  return 0;
708 }
709 
710 template<typename dataT>
712 {
713  if(!m_isOpen or !m_naxes) return -1;
714 
715  return m_naxis;
716 }
717 
718 template<typename dataT>
720 {
721  if(!m_isOpen or !m_naxes) return -1;
722 
723  long sz = 1;
724 
725  if(m_x0 > -1 && m_y0 > -1 && m_xpix > -1 && m_ypix > -1 && m_naxis ==2)
726  {
727  return m_xpix*m_ypix;
728  }
729  else
730  {
731  for(int i=0;i<m_naxis;++i) sz*= m_naxes[i];
732  }
733 
734  return sz;
735 }
736 
737 template<typename dataT>
738 long fitsFile<dataT>::getSize(size_t axis)
739 {
740  if(!m_isOpen or !m_naxes) return -1;
741 
742  if(m_x0 > -1 && m_y0 > -1 && m_xpix > -1 && m_ypix > -1 && m_naxis ==2)
743  {
744  if(axis == 0) return m_xpix;
745  return m_ypix;
746  }
747  else
748  {
749  return m_naxes[axis];
750  }
751 }
752 
753 template<typename dataT>
754 void fitsFile<dataT>::pixarrs( long ** fpix,
755  long ** lpix,
756  long ** inc
757  )
758 {
759  *fpix = new long[m_naxis];
760  *lpix = new long[m_naxis];
761  *inc = new long[m_naxis];
762 
763  if(m_x0 > -1 && m_y0 > -1 && m_xpix > -1 && m_ypix > -1 && m_naxis == 2)
764  {
765  (*fpix)[0] = m_x0+1;
766  (*lpix)[0] = (*fpix)[0] + m_xpix-1;
767  (*fpix)[1] = m_y0+1;
768  (*lpix)[1] = (*fpix)[1] + m_ypix-1;
769 
770  (*inc)[0] = 1;
771  (*inc)[1] = 1;
772  }
773  else
774  {
775  if(m_x0 < 0 && m_y0 < 0 && m_xpix < 0 && m_ypix < 0 && m_z0 < 0 && m_zframes < 0)
776  {
777  for(int i=0;i<m_naxis; i++)
778  {
779  (*fpix)[i] = 1;
780  (*lpix)[i] = m_naxes[i];
781  (*inc)[i] = 1;
782  }
783  }
784  else
785  {
786  if(m_x0 > -1 && m_y0 > -1 && m_xpix > -1 && m_ypix > -1)
787  {
788  (*fpix)[0] = m_x0+1;
789  (*lpix)[0] = (*fpix)[0] + m_xpix-1;
790  (*fpix)[1] = m_y0+1;
791  (*lpix)[1] = (*fpix)[1] + m_ypix-1;
792 
793  (*inc)[0] = 1;
794  (*inc)[1] = 1;
795  }
796  else
797  {
798  (*fpix)[0] = 1;
799  (*lpix)[0] = m_naxes[0];
800  (*fpix)[1] = 1;
801  (*lpix)[1] = m_naxes[1];
802 
803  (*inc)[0] = 1;
804  (*inc)[1] = 1;
805  }
806 
807  if(m_z0 > -1 && m_zframes > -1)
808  {
809  (*fpix)[2] = m_z0 + 1;
810  (*lpix)[2] = (*fpix)[2] + m_zframes-1;
811  (*inc)[2] = 1;
812  }
813  else
814  {
815  (*fpix)[2] = 1;
816  (*lpix)[2] = m_naxes[2];
817  (*inc)[2] = 1;
818  }
819  }
820  }
821 }
822 
823 /************************************************************/
824 /*** Basic Arrays ***/
825 /************************************************************/
826 
827 template<typename dataT>
828 int fitsFile<dataT>::read(dataT * data)
829 {
830  int fstatus = 0;
831 
832  if(!m_isOpen)
833  {
834  if( open() < 0) return -1;
835  }
836 
837  long *fpix, *lpix, *inc;
838  pixarrs(&fpix, &lpix, &inc);
839 
840  ///\todo test if there is a speed difference for full reads for fits_read_pix/subset
841 
842  //fits_read_pix(m_fptr, fitsType<dataT>(), fpix, nelements, (void *) &m_nulval,
843  //(void *) data, &m_anynul, &fstatus);
844  fits_read_subset(m_fptr, fitsType<dataT>(), fpix, lpix, inc, (void *) &m_nulval,
845  (void *) data, &m_anynul, &fstatus);
846 
847  delete[] fpix;
848  delete[] lpix;
849  delete[] inc;
850 
851  if (fstatus && fstatus != 107)
852  {
853  std::string explan = "Error reading data from file";
854  fitsErrText(explan, m_fileName, fstatus);
855  mxError("fitsFile", MXE_FILERERR, explan);
856  return -1;
857  }
858 
859  return 0;
860 }
861 
862 template<typename dataT>
863 int fitsFile<dataT>::read( dataT * data,
864  fitsHeader &head
865  )
866 {
867  if( read(data) < 0 ) return -1;
868  if( readHeader(head) < 0) return -1;
869 
870  return 0;
871 }
872 
873 template<typename dataT>
874 int fitsFile<dataT>::read( dataT * data,
875  const std::string &fname
876  )
877 {
878  if( fileName(fname) < 0 ) return -1;
879  if( read(data) < 0 ) return -1;
880  return 0;
881 }
882 
883 template<typename dataT>
884 int fitsFile<dataT>::read( dataT * data,
885  fitsHeader &head,
886  const std::string &fname
887  )
888 {
889  if( fileName(fname) < 0 ) return -1;
890  if( read(data) < 0 ) return -1;
891  if( readHeader(head) < 0 ) return -1;
892  return 0;
893 }
894 
895 template<typename dataT>
896 int fitsFile<dataT>::read( dataT * im,
897  const std::vector<std::string> & flist
898  )
899 {
900  if(flist.size() == 0)
901  {
902  mxError("fitsFile", MXE_PARAMNOTSET, "Empty file list");
903  return - 1;
904  }
905 
906  long sz0 =0, sz1=0;
907 
908  for(int i=0;i<flist.size(); ++i)
909  {
910  if( fileName(flist[i], 1) < 0 ) return -1;
911 
912  if( read(im + i*sz0*sz1) < 0 ) return -1;
913 
914  sz0 = getSize(0);
915  sz1 = getSize(1);
916  }
917 
918  return 0;
919 }
920 
921 template<typename dataT>
922 int fitsFile<dataT>::read( dataT * im,
923  std::vector<fitsHeader> &heads,
924  const std::vector<std::string> & flist
925  )
926 {
927  if(flist.size() == 0)
928  {
929  mxError("fitsFile", MXE_PARAMNOTSET, "Empty file list");
930  return -1;
931  }
932 
933  long sz0 =0, sz1=0;
934 
935  for(size_t i=0;i<flist.size(); ++i)
936  {
937  if( fileName(flist[i], 1) < 0 ) return -1;
938 
939  if( read(im + i*sz0*sz1) < 0 ) return -1;
940 
941  if( readHeader(heads[i]) < 0 ) return -1;
942 
943  sz0 = getSize(0);
944  sz1 = getSize(1);
945 
946  }
947 
948  return 0;
949 }
950 
951 
952 /************************************************************/
953 /*** Eigen Arrays ***/
954 /************************************************************/
955 
956 template<typename arrT, bool isCube=improc::is_eigenCube<arrT>::value>
957 struct eigenArrResize
958 {
959  //If it's a cube, always pass zsz
960  void resize(arrT & arr, int xsz, int ysz, int zsz)
961  {
962  arr.resize(xsz, ysz, zsz);
963  }
964 };
965 
966 template<typename arrT>
967 struct eigenArrResize<arrT, false>
968 {
969  //If it's not a cube, never pass zsz
970  void resize(arrT & arr, int xsz, int ysz, int zsz)
971  {
972  static_cast<void>(zsz);
973 
974  arr.resize(xsz, ysz);
975  }
976 };
977 
978 template<typename dataT>
979 template<typename arrT>
980 int fitsFile<dataT>::read(arrT & im)
981 {
982  ///\todo this can probably be made part of one read function (or call read(data *)) with a call to resize with SFINAE
983  int fstatus = 0;
984 
985  if(!m_isOpen)
986  {
987  if( open() < 0 ) return -1;
988  }
989 
990  long *fpix, *lpix, *inc;
991  pixarrs(&fpix, &lpix, &inc);
992 
993  eigenArrResize<arrT> arrresz;
994  if(m_naxis > 2)
995  {
996  arrresz.resize(im, lpix[0]-fpix[0]+1, lpix[1]-fpix[1]+1, lpix[2]-fpix[2]+1);
997  }
998  else if(m_naxis > 1)
999  {
1000  arrresz.resize(im, lpix[0]-fpix[0]+1, lpix[1]-fpix[1]+1,1);
1001  }
1002  else
1003  {
1004  arrresz.resize(im, lpix[0]-fpix[0]+1, 1,1);
1005  }
1006 
1007  if( fits_read_subset(m_fptr, fitsType<typename arrT::Scalar>(), fpix, lpix, inc, (void *) &m_nulval,
1008  (void *) im.data(), &m_anynul, &fstatus) < 0 ) return -1;
1009 
1010  delete[] fpix;
1011  delete[] lpix;
1012  delete[] inc;
1013 
1014  if (fstatus && fstatus != 107)
1015  {
1016  std::string explan = "Error reading data from file";
1017  fitsErrText(explan, m_fileName, fstatus);
1018  mxError("fitsFile", MXE_FILERERR, explan);
1019  return -1;
1020  }
1021 
1022  return 0;
1023 
1024 }
1025 
1026 template<typename dataT>
1027 template<typename arrT>
1028 int fitsFile<dataT>::read(arrT & data, fitsHeader &head)
1029 {
1030  if( read(data) < 0 ) return -1;
1031  if( readHeader(head) < 0 ) return -1;
1032  return 0;
1033 }
1034 
1035 template<typename dataT>
1036 template<typename arrT>
1037 int fitsFile<dataT>::read( arrT & data,
1038  const std::string &fname
1039  )
1040 {
1041  if( fileName(fname) < 0 ) return -1;
1042  if( read(data) < 0 ) return -1;
1043  return 0;
1044 }
1045 
1046 template<typename dataT>
1047 template<typename arrT>
1048 int fitsFile<dataT>::read( arrT & data,
1049  fitsHeader &head,
1050  const std::string &fname
1051  )
1052 {
1053  if( fileName(fname) < 0 ) return -1;
1054  if( read(data) < 0 ) return -1;
1055  if( readHeader(head) < 0 ) return -1;
1056 
1057  return 0;
1058 }
1059 
1060 
1061 template<typename dataT>
1062 template<typename cubeT>
1063 int fitsFile<dataT>::read( cubeT & cube,
1064  const std::vector<std::string> & flist,
1065  std::vector<fitsHeader> * heads
1066  )
1067 {
1068  int fstatus = 0;
1069 
1070  if( flist.size() == 0 )
1071  {
1072  mxError("fitsFile", MXE_PARAMNOTSET, "Empty file list");
1073  return -1;
1074  }
1075 
1076 
1077  //Open the first file to get the dimensions.
1078  if( fileName(flist[0], 1) < 0) return -1;
1079 
1080  long *fpix, *lpix, *inc;
1081  pixarrs(&fpix, &lpix, &inc);
1082 
1083  cube.resize(lpix[0]-fpix[0]+1, lpix[1]-fpix[1]+1, lpix[2]-fpix[2]+1);
1084 
1085  //Now read first image.
1086  fits_read_subset(m_fptr, fitsType<typename cubeT::Scalar>(), fpix, lpix, inc, (void *) &m_nulval,
1087  (void *) cube.image(0).data(), &m_anynul, &fstatus);
1088 
1089 
1090  if (fstatus && fstatus != 107)
1091  {
1092 
1093  std::string explan = "Error reading data from file";
1094  fitsErrText(explan, m_fileName, fstatus);
1095 
1096  mxError("cfitsio", MXE_FILERERR, explan);
1097 
1098  delete[] fpix;
1099  delete[] lpix;
1100  delete[] inc;
1101 
1102  return -1;
1103  }
1104 
1105  if(heads)
1106  {
1107  if( readHeader( (*heads)[0]) < 0) return -1;
1108  }
1109 
1110 
1111  //Now read in the rest.
1112  for(int i=1; i< flist.size(); ++i)
1113  {
1114  fileName(flist[i], 1);
1115 
1116  //Now read image.
1117  fits_read_subset(m_fptr, fitsType<typename cubeT::Scalar>(), fpix, lpix, inc, (void *) &m_nulval,
1118  (void *) cube.image(i).data(), &m_anynul, &fstatus);
1119 
1120  if (fstatus && fstatus != 107)
1121  {
1122  std::string explan = "Error reading data from file";
1123  fitsErrText(explan, m_fileName, fstatus);
1124  mxError("cfitsio", MXE_FILERERR, explan);
1125 
1126  delete[] fpix;
1127  delete[] lpix;
1128  delete[] inc;
1129 
1130  return -1;
1131  }
1132 
1133  if(heads)
1134  {
1135  if( readHeader( (*heads)[i]) < 0) return -1;
1136  }
1137  }
1138 
1139 
1140  delete[] fpix;
1141  delete[] lpix;
1142  delete[] inc;
1143 
1144  return 0;
1145 }
1146 
1147 
1148 template<typename dataT>
1149 template<typename cubeT>
1150 int fitsFile<dataT>::read( cubeT & cube,
1151  std::vector<fitsHeader> & heads,
1152  const std::vector<std::string> & flist
1153  )
1154 {
1155  return read(cube, flist, &heads);
1156 }
1157 
1158 template<typename dataT>
1160 {
1161  int fstatus = 0;
1162 
1163  char keyword[FLEN_KEYWORD];
1164  char value[FLEN_VALUE];
1165  char * comment;
1166 
1167  //The keys to look for if head is already populated
1168  std::list<fitsHeader::headerIterator> head_keys;
1169  std::list<fitsHeader::headerIterator>::iterator head_keys_it;
1170 // int num_head_keys;
1171 
1172  bool head_keys_only = false;
1173  if(head.size() > 0)
1174  {
1175  head_keys_only = true;
1176  fitsHeader::headerIterator headIt = head.begin();
1177  while(headIt != head.end())
1178  {
1179  head_keys.push_back(headIt);
1180  ++headIt;
1181  }
1182 // num_head_keys = head.size();
1183  }
1184 
1185  //If m_noComment is set, then we don't read in the comment
1186  if(m_noComment)
1187  {
1188  comment = 0;
1189  }
1190  else
1191  {
1192  comment = new char[FLEN_COMMENT];
1193  }
1194 
1195  int keysexist;
1196  int morekeys;
1197 
1198  if(!m_isOpen)
1199  {
1200  open();
1201  }
1202 
1203  //This gets the number of header keys to read
1204  fits_get_hdrspace(m_fptr, &keysexist, &morekeys, &fstatus);
1205 
1206  if (fstatus)
1207  {
1208  std::string explan = "Error reading header from file";
1209  fitsErrText( explan, m_fileName, fstatus);
1210  mxError( "fitsFile", MXE_FILERERR, explan);
1211 
1212  if(comment) delete[] comment;
1213 
1214  return -1;
1215  }
1216 
1217  for(int i=0; i<keysexist; i++)
1218  {
1219  fits_read_keyn(m_fptr, i+1, keyword, value, comment, &fstatus);
1220 
1221  if (fstatus)
1222  {
1223  std::string explan = "Error reading header from file";
1224  fitsErrText( explan, m_fileName, fstatus);
1225  mxError( "fitsFile", MXE_FILERERR, explan);
1226 
1227  if(comment) delete[] comment;
1228 
1229  return -1;
1230  }
1231 
1232  if(!head_keys_only)
1233  {
1234  if(strcmp(keyword, "COMMENT") == 0)
1235  {
1236  head.append<fitsCommentType>(keyword, fitsCommentType(value), comment);
1237  }
1238  else if(strcmp(keyword, "HISTORY") == 0)
1239  {
1240  head.append<fitsHistoryType>(keyword, fitsHistoryType(value), comment);
1241  }
1242  else
1243  {
1244  //Otherwise we append it as an unknown type
1245  head.append(keyword, value, comment);
1246  }
1247  }
1248  else
1249  {
1250  head_keys_it = head_keys.begin();
1251  while(head_keys_it != head_keys.end())
1252  {
1253  if( (*(*head_keys_it)).keyword() == keyword)
1254  {
1255  head[keyword].value(value);
1256  if(comment) head[keyword].comment(comment);
1257 
1258  head_keys.erase(head_keys_it);
1259 
1260  break;
1261  }
1262  ++head_keys_it;
1263  }
1264 
1265  //Quit if we're done.
1266  if(head_keys.empty()) break;
1267  }
1268  }
1269 
1270  if(comment) delete[] comment;
1271 
1272  return 0;
1273 }
1274 
1275 template<typename dataT>
1277  const std::string &fname
1278  )
1279 {
1280  if( fileName(fname) < 0 ) return -1;
1281  if( readHeader(head) < 0 ) return -1;
1282 }
1283 
1284 template<typename dataT>
1285 int fitsFile<dataT>::readHeader( std::vector<fitsHeader> & heads,
1286  const std::vector<std::string> & flist
1287  )
1288 {
1289  for(int i=0; i< flist.size(); ++i)
1290  {
1291  fileName(flist[i], 1);
1292 
1293  if( readHeader( heads[i]) < 0) return -1;
1294  }
1295 
1296  return 0;
1297 }
1298 
1299 
1300 template<typename dataT>
1301 int fitsFile<dataT>::write( const dataT * im,
1302  int d1,
1303  int d2,
1304  int d3,
1305  fitsHeader * head
1306  )
1307 {
1308  int fstatus = 0;
1309 
1310  if(m_isOpen) close();
1311  if(m_naxes) delete[] m_naxes;
1312 
1313  fstatus = 0;
1314  m_naxis = 1;
1315  if(d2 > 0)
1316  {
1317  if(d3 > 1) m_naxis = 3;
1318  else m_naxis = 2;
1319  }
1320 
1321  m_naxes = new long[m_naxis];
1322 
1323  m_naxes[0] = d1;
1324  if(m_naxis > 1) m_naxes[1] = d2;
1325  if(m_naxis > 2) m_naxes[2] = d3;
1326 
1327  std::string forceFileName = "!"+m_fileName;
1328 
1329  fits_create_file(&m_fptr, forceFileName.c_str(), &fstatus);
1330  if (fstatus)
1331  {
1332  std::string explan = "Error creating file";
1333  fitsErrText(explan, m_fileName, fstatus);
1334  mxError("fitsFile", MXE_FILEOERR, explan);
1335 
1336  return -1;
1337  }
1338  m_isOpen = true;
1339 
1340  fits_create_img( m_fptr, fitsBITPIX<dataT>(), m_naxis, m_naxes, &fstatus);
1341  if (fstatus)
1342  {
1343  std::string explan = "Error creating image";
1344  fitsErrText(explan, m_fileName, fstatus);
1345  mxError("fitsFile", MXE_FILEWERR, explan);
1346 
1347  return -1;
1348  }
1349 
1350  long fpixel[3];
1351  fpixel[0] = 1;
1352  fpixel[1] = 1;
1353  fpixel[2] = 1;
1354 
1355  LONGLONG nelements = 1;
1356 
1357  for(int i=0;i<m_naxis;++i) nelements *= m_naxes[i];
1358 
1359  fits_write_pix( m_fptr, fitsType<dataT>(), fpixel, nelements, (void *) im, &fstatus);
1360  if (fstatus)
1361  {
1362  std::string explan = "Error writing data";
1363  fitsErrText(explan, m_fileName, fstatus);
1364  mxError("fitsFile", MXE_FILEWERR, explan);
1365 
1366  return -1;
1367 
1368  }
1369 
1370  if(head != 0)
1371  {
1373 
1374  for(it = head->begin(); it != head->end(); ++it)
1375  {
1376  int wrv = it->write(m_fptr);
1377  if(wrv != 0)
1378  {
1379  std::string explan = "Error writing keyword";
1380  fitsErrText(explan, m_fileName, wrv);
1381  mxError("fitsFile", MXE_FILEWERR, explan);
1382  }
1383 
1384  }
1385  }
1386 
1387  if( close() < 0) return -1;
1388 
1389  return 0;
1390 }
1391 
1392 template<typename dataT>
1393 int fitsFile<dataT>::write( const dataT * im,
1394  int d1,
1395  int d2,
1396  int d3
1397  )
1398 {
1399  return write(im, d1, d2, d3, (fitsHeader *) 0);
1400 }
1401 
1402 template<typename dataT>
1403 int fitsFile<dataT>::write( const dataT * im,
1404  int d1,
1405  int d2,
1406  int d3,
1407  fitsHeader & head)
1408 {
1409  return write(im, d1, d2, d3, &head);
1410 }
1411 
1412 
1413 template<typename dataT>
1414 int fitsFile<dataT>::write( const std::string & fname,
1415  const dataT * im,
1416  int d1,
1417  int d2,
1418  int d3
1419  )
1420 {
1421  if( fileName(fname, false) < 0) return -1;
1422  return write(im, d1, d2, d3, (fitsHeader *) 0);
1423 }
1424 
1425 template<typename dataT>
1426 int fitsFile<dataT>::write( const std::string & fname,
1427  const dataT * im,
1428  int d1,
1429  int d2,
1430  int d3,
1431  fitsHeader & head)
1432 {
1433  if( fileName(fname, false) < 0) return -1;
1434  return write(im, d1, d2, d3, &head);
1435 }
1436 
1437 
1438 
1439 template<typename dataT>
1440 template<typename arrT>
1441 int fitsFile<dataT>::write( const std::string & fname,
1442  const arrT & im
1443  )
1444 {
1446 
1447  return write(fname, im.data(), im.rows(), im.cols(), planes(im));
1448 
1449 }
1450 
1451 template<typename dataT>
1452 template<typename arrT>
1453 int fitsFile<dataT>::write( const std::string & fname,
1454  const arrT & im,
1455  fitsHeader & head)
1456 {
1458 
1459  return write(fname, im.data(), im.rows(), im.cols(), planes(im), head);
1460 
1461 }
1462 
1463 template<typename dataT>
1465 {
1466  m_x0 = -1;
1467  m_y0 = -1;
1468  m_xpix = -1;
1469  m_ypix = -1;
1470 }
1471 
1472 template<typename dataT>
1474  long y0,
1475  long xpix,
1476  long ypix
1477  )
1478 {
1479  m_x0 = x0;
1480  m_y0 = y0;
1481  m_xpix = xpix;
1482  m_ypix = ypix;
1483 }
1484 
1485 template<typename dataT>
1487 {
1488  m_z0 = -1;
1489  m_zframes = -1;
1490 }
1491 
1492 template<typename dataT>
1494  long zframes
1495  )
1496 {
1497  m_z0 = z0;
1498  m_zframes = zframes;
1499 }
1500 
1501 /** \ingroup fits_processing_typedefs
1502  * @{
1503  */
1504 
1505 /// A \ref fitsFile to work in signed characters
1507 
1508 /// A \ref fitsFile to work in unsigned characters
1510 
1511 /// A \ref fitsFile to work in signed short integers
1513 
1514 /// A \ref fitsFile to work in unsigned short integers
1516 
1517 /// A \ref fitsFile to work in signed integers
1519 
1520 /// A \ref fitsFile to work in unsigned integers
1522 
1523 /// A \ref fitsFile to work in signed long integers
1525 
1526 /// A \ref fitsFile to work in single precision floats
1528 
1529 /// A \ref fitsFile to work in double precision
1531 
1532 ///@}
1533 
1534 } //namespace fits
1535 } //namespace mx
1536 
1537 #endif //ioutils_fits_fitsFile_hpp
Class to manage interactions with a FITS file.
Definition: fitsFile.hpp:54
long * m_naxes
The size of each dimension.
Definition: fitsFile.hpp:70
int write(const dataT *im, int d1, int d2, int d3, fitsHeader *head)
Write the contents of a raw array to the FITS file.
Definition: fitsFile.hpp:1301
long naxes(int dim)
Get the current value of m_naxes for the specified dimension.
Definition: fitsFile.hpp:614
dataT m_nulval
The value to replace null values with.
Definition: fitsFile.hpp:76
long m_zframes
The number of frames to read from a cube.
Definition: fitsFile.hpp:101
int open()
Open the file and gets its dimensions.
Definition: fitsFile.hpp:624
long getSize()
Get the total size.
Definition: fitsFile.hpp:719
int readHeader(fitsHeader &head)
Read the header from the fits file.
Definition: fitsFile.hpp:1159
void pixarrs(long **fpix, long **lpix, long **inc)
Fill in the read-size arrays for reading a subset (always used)
Definition: fitsFile.hpp:754
void setReadSize()
Set to read all the pixels in the file.
Definition: fitsFile.hpp:1464
long m_ypix
The number of y-pixels to read.
Definition: fitsFile.hpp:95
fitsFile()
Default constructor.
Definition: fitsFile.hpp:562
long m_z0
The starting frame to read from a cube.
Definition: fitsFile.hpp:98
long m_y0
The starting y-pixel to read from.
Definition: fitsFile.hpp:89
void setCubeReadSize()
Set to read all frames from a cube.
Definition: fitsFile.hpp:1486
int getDimensions()
Get the number of dimensions (i.e. m_naxis)
Definition: fitsFile.hpp:711
int m_naxis
The dimensions of the image (1D, 2D, 3D etc)
Definition: fitsFile.hpp:67
int m_noComment
Flag to control whether the comment string is read.
Definition: fitsFile.hpp:82
int m_anynul
Records whether any null values were replaced.
Definition: fitsFile.hpp:79
void construct()
One time initialization common to all constructors.
Definition: fitsFile.hpp:557
int naxis()
Get the current value of m_naxis.
Definition: fitsFile.hpp:608
fitsfile * m_fptr
The cfitsio data structure.
Definition: fitsFile.hpp:64
~fitsFile()
Destructor.
Definition: fitsFile.hpp:575
std::string m_fileName
The path to the file.
Definition: fitsFile.hpp:61
long m_x0
The starting x-pixel to read from.
Definition: fitsFile.hpp:86
long m_xpix
The number of x-pixels to read.
Definition: fitsFile.hpp:92
std::string fileName()
Get the current value of m_fileName.
Definition: fitsFile.hpp:583
bool m_isOpen
Flag indicating whether the file is open or not.
Definition: fitsFile.hpp:73
int close()
Close the file.
Definition: fitsFile.hpp:681
int read(dataT *data)
Read the contents of the FITS file into an array.
Definition: fitsFile.hpp:828
Class to manage a complete fits header.
Definition: fitsHeader.hpp:52
std::list< fitsHeaderCard >::iterator headerIterator
The iterator type for the cards list.
Definition: fitsHeader.hpp:57
headerIterator begin()
Get iterator to the beginning of the cards list.
Definition: fitsHeader.cpp:66
void erase(const std::string &keyword)
Erase card by keyword.
Definition: fitsHeader.cpp:102
size_t size()
Get number of cards currently stored in the header.
Definition: fitsHeader.cpp:86
void append(fitsHeaderCard card)
Append a fitsHeaderCard to the end of the header.
Definition: fitsHeader.cpp:156
headerIterator end()
Get iterator to the end of the cards list.
Definition: fitsHeader.cpp:71
Declares and defines a class to work with a FITS header.
Declares and defines utilities to work with FITS files.
fitsFile< long > fitsFilel
A fitsFile to work in signed long integers.
Definition: fitsFile.hpp:1524
fitsFile< unsigned short > fitsFileus
A fitsFile to work in unsigned short integers.
Definition: fitsFile.hpp:1515
fitsFile< short > fitsFiles
A fitsFile to work in signed short integers.
Definition: fitsFile.hpp:1512
fitsFile< char > fitsFilec
A fitsFile to work in signed characters.
Definition: fitsFile.hpp:1506
fitsFile< int > fitsFilei
A fitsFile to work in signed integers.
Definition: fitsFile.hpp:1518
fitsFile< unsigned char > fitsFileuc
A fitsFile to work in unsigned characters.
Definition: fitsFile.hpp:1509
fitsFile< unsigned int > fitsFileui
A fitsFile to work in unsigned integers.
Definition: fitsFile.hpp:1521
fitsFile< double > fitsFiled
A fitsFile to work in double precision.
Definition: fitsFile.hpp:1530
fitsFile< float > fitsFilef
A fitsFile to work in single precision floats.
Definition: fitsFile.hpp:1527
void fitsErrText(std::string &explan, const std::string &filename, int fstatus)
Generate a rich error meesage from a FITS status code.
Definition: fitsUtils.cpp:175
The mxlib c++ namespace.
Definition: mxError.hpp:107
Function object to return the number of planes for any Eigen like object, whether 2D or a 3D cube.
Definition: eigenImage.hpp:91