Line data Source code
1 : /** \file fitsUtils.hpp
2 : * \brief Declares and defines utilities to work with FITS files
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_fitsUtils_hpp
28 : #define ioutils_fits_fitsUtils_hpp
29 :
30 : #include <iostream>
31 : #include <cstdlib>
32 : #include <cstring>
33 : #include <complex>
34 :
35 : #include <fitsio.h>
36 :
37 : #include "../stringUtils.hpp"
38 :
39 : namespace mx
40 : {
41 : namespace fits
42 : {
43 :
44 : /// The standard width of the value entry in a header card
45 : #define stdValWidth ( 20 )
46 :
47 : // #define fitsTUNKNOWN (-5000)
48 : struct fitsUnknownType
49 : {
50 : };
51 :
52 : // #define fitsTCOMMENT (-5001)
53 : struct fitsCommentType
54 : {
55 : fitsCommentType()
56 : {
57 : }
58 :
59 : explicit fitsCommentType( char *v )
60 : {
61 : static_cast<void>( v );
62 : }
63 :
64 : explicit fitsCommentType( const char *v )
65 : {
66 : static_cast<void>( v );
67 : }
68 : };
69 :
70 : // #define fitsTHISTORY (-5002)
71 :
72 : struct fitsHistoryType
73 : {
74 : fitsHistoryType()
75 : {
76 : }
77 :
78 : explicit fitsHistoryType( char *v )
79 : {
80 : static_cast<void>( v );
81 : }
82 :
83 : explicit fitsHistoryType( const char *v )
84 : {
85 : static_cast<void>( v );
86 : }
87 : };
88 :
89 : struct fitsContinueType
90 : {
91 : fitsContinueType()
92 : {
93 : }
94 :
95 : explicit fitsContinueType( char *v )
96 : {
97 : static_cast<void>( v );
98 : }
99 :
100 : explicit fitsContinueType( const char *v )
101 : {
102 : static_cast<void>( v );
103 : }
104 : };
105 :
106 : /** \ingroup fits_utils
107 : * @{
108 : */
109 :
110 : /// Return the cfitsio constant for a given data type.
111 : /**
112 : *
113 : * \tparam scalarT is the type
114 : *
115 : * \returns a constant defined in cfitsio corresponding to the native type
116 : * \returns -1 if not a define type in cfitsio
117 : *
118 : * \ingroup fits_utils
119 : */
120 : template <typename scalarT>
121 : constexpr int fitsType()
122 : {
123 : return -5000; // This is the same as unknownType
124 : }
125 :
126 : template <>
127 : constexpr int fitsType<char *>()
128 : {
129 : return TSTRING;
130 : }
131 :
132 : template <>
133 : constexpr int fitsType<std::string>()
134 : {
135 : return TSTRING;
136 : }
137 :
138 : template <>
139 : constexpr int fitsType<bool>() // mxlib extension, treated as uchar.
140 : {
141 : return -14002;
142 : }
143 :
144 : template <>
145 6 : constexpr int fitsType<char>()
146 : {
147 6 : return TSBYTE;
148 : }
149 :
150 : template <>
151 : constexpr int fitsType<unsigned char>()
152 : {
153 : return TBYTE;
154 : }
155 :
156 : template <>
157 : constexpr int fitsType<short>()
158 : {
159 : return TSHORT;
160 : }
161 :
162 : template <>
163 : constexpr int fitsType<unsigned short>()
164 : {
165 : return TUSHORT;
166 : }
167 :
168 : template <>
169 22 : constexpr int fitsType<int>()
170 : {
171 22 : return TINT;
172 : }
173 :
174 : template <>
175 : constexpr int fitsType<unsigned int>()
176 : {
177 : return TUINT;
178 : }
179 :
180 : template <>
181 : constexpr int fitsType<long>()
182 : {
183 : return TLONG;
184 : }
185 :
186 : template <>
187 : constexpr int fitsType<unsigned long>()
188 : {
189 : return TULONG;
190 : }
191 :
192 : template <>
193 : constexpr int fitsType<long long>()
194 : {
195 : return TLONGLONG;
196 : }
197 :
198 : template <>
199 : constexpr int fitsType<unsigned long long>()
200 : {
201 : return TULONGLONG;
202 : }
203 :
204 : template <>
205 24 : constexpr int fitsType<float>()
206 : {
207 24 : return TFLOAT;
208 : }
209 :
210 : template <>
211 : constexpr int fitsType<std::complex<float>>()
212 : {
213 : return TCOMPLEX;
214 : }
215 :
216 : template <>
217 : constexpr int fitsType<double>()
218 : {
219 : return TDOUBLE;
220 : }
221 :
222 : template <>
223 : constexpr int fitsType<std::complex<double>>()
224 : {
225 : return TDBLCOMPLEX;
226 : }
227 :
228 : template <>
229 37 : constexpr int fitsType<fitsUnknownType>()
230 : {
231 37 : return -5000;
232 : }
233 :
234 : template <>
235 : constexpr int fitsType<fitsCommentType>()
236 : {
237 : return -5001;
238 : }
239 :
240 : template <>
241 : constexpr int fitsType<fitsHistoryType>()
242 : {
243 : return -5002;
244 : }
245 :
246 : template <>
247 : constexpr int fitsType<fitsContinueType>()
248 : {
249 : return -5003;
250 : }
251 :
252 : /** Return the cfitsio BITPIX value for a given data type.
253 : *
254 : * \tparam scalarT is the type
255 : * \retval int > 0 if a constant is defined in cfitsio corresponding to the native type
256 : * \retval -1 if not a defined type in cfitsio
257 : */
258 : template <typename scalarT>
259 : constexpr int fitsBITPIX();
260 :
261 : template <>
262 : constexpr int fitsBITPIX<char>()
263 : {
264 : return SBYTE_IMG;
265 : }
266 :
267 : template <>
268 : constexpr int fitsBITPIX<signed char>()
269 : {
270 : return SBYTE_IMG;
271 : }
272 :
273 : template <>
274 : constexpr int fitsBITPIX<unsigned char>()
275 : {
276 : return BYTE_IMG;
277 : }
278 :
279 : template <>
280 : constexpr int fitsBITPIX<short>()
281 : {
282 : return SHORT_IMG;
283 : }
284 :
285 : template <>
286 : constexpr int fitsBITPIX<unsigned short>()
287 : {
288 : return USHORT_IMG;
289 : }
290 :
291 : template <>
292 : constexpr int fitsBITPIX<int>()
293 : {
294 : return LONG_IMG; // Yes, this is right. This returns 32
295 : }
296 :
297 : template <>
298 : constexpr int fitsBITPIX<unsigned int>()
299 : {
300 : return ULONG_IMG; // Yes, this is right, this returns 40
301 : }
302 :
303 : template <>
304 : constexpr int fitsBITPIX<long>()
305 : {
306 : return LONGLONG_IMG; // Yes, this is right, this returns 64
307 : }
308 :
309 : template <>
310 : constexpr int fitsBITPIX<unsigned long>()
311 : {
312 : return ULONGLONG_IMG; // Yes, this is right, this returns 64
313 : }
314 :
315 : template <>
316 : constexpr int fitsBITPIX<long long>()
317 : {
318 : return LONGLONG_IMG; // Yes, this is right, this returns 64
319 : }
320 :
321 : template <>
322 : constexpr int fitsBITPIX<unsigned long long>()
323 : {
324 : return ULONGLONG_IMG; // Yes, this is right, this returns 64
325 : }
326 :
327 : template <>
328 : constexpr int fitsBITPIX<float>()
329 : {
330 : return FLOAT_IMG;
331 : }
332 :
333 : template <>
334 : constexpr int fitsBITPIX<double>()
335 : {
336 : return DOUBLE_IMG;
337 : }
338 :
339 : /// Strip the apostrophes from a FITS value string
340 : /** The argument is modified if the first and/or last non-whitespace character is '
341 : *
342 : * \param s is the string from which to strip apostrophes
343 : *
344 : * \retval int containing the number of stripped apostrophes
345 : */
346 : int fitsStripApost( std::string &s );
347 :
348 : /// Populate a fits header card with the value string copied verbatim
349 : /**
350 : * \param headStr is a c-string which must be 81 characters in length, including the '\n'
351 : * \param keyword is the keyword name
352 : * \param value is the value string
353 : * \param comment is the comment string
354 : */
355 : void fitsPopulateCard( char headStr[81], char *keyword, char *value, char *comment );
356 :
357 : /// Write a header card to a file
358 : /** This is a templatized wrapper for the cfitsio routine fits_write_key.
359 : *
360 : * \tparam typeT is the type of the value
361 : *
362 : * \param fptr is a pointer to an open fits file
363 : * \param keyword is a c-string containing the keyword
364 : * \param value is a pointer to the memory location of the value
365 : * \param comment is a c-string, possibly NULL, containing a comment string
366 : *
367 : * \retval int containing the status returned by the cfitsio routine.
368 : *
369 : * \ingroup fits_utils
370 : */
371 : template <typename typeT>
372 : mx::error_t fits_write_key( fitsfile *fptr, char *keyword, void *value, char *comment )
373 : {
374 : int fstatus = 0;
375 :
376 : fits_write_key( fptr, fitsType<typeT>(), keyword, value, comment, &fstatus );
377 :
378 : return fits_status2error_t(fstatus);
379 : }
380 :
381 : template <>
382 : mx::error_t fits_write_key<char *>( fitsfile *fptr, char *keyword, void *value, char *comment );
383 :
384 : template <>
385 : mx::error_t fits_write_key<std::string>( fitsfile *fptr, char *keyword, void *value, char *comment );
386 :
387 : /// Specialization to handle the case bool
388 : /** This gets converted to unsigned char.
389 : */
390 : template <>
391 : mx::error_t fits_write_key<bool>( fitsfile *fptr, char *keyword, void *value, char *comment );
392 :
393 : template <>
394 : mx::error_t fits_write_key<fitsUnknownType>( fitsfile *fptr, char *keyword, void *value, char *comment );
395 :
396 : mx::error_t fits_write_comment( fitsfile *fptr, char *comment );
397 :
398 : mx::error_t fits_write_history( fitsfile *fptr, char *history );
399 :
400 : /// Generate a rich error meesage from a FITS status code.
401 : /*void fitsErrText( std::string &explan, ///< [out] the explanatory message
402 : const std::string &filename, ///< [in] the FITS file's name which generated the problem
403 : int fstatus ///< [in] the cfitstio status code
404 : );*/
405 : ///@}
406 :
407 : } // namespace fits
408 : } // namespace mx
409 :
410 : #endif // ioutils_fits_fitsUtils_hpp
|