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