26#ifndef ioutils_fits__fitsHeader_hpp
27#define ioutils_fits__fitsHeader_hpp
30#include <unordered_map>
42namespace fitsHeaderDetail
58using mutationHookT =
error_t ( * )( mutation );
61mutationHookT &mutationHook();
64void resetMutationHook();
79template <
class verboseT = verbose::d>
87 typedef std::list<fitsHeaderCard<verboseT>>
cardListT;
95 typedef std::unordered_multimap<std::string, headerIteratorT>
cardMapT;
149 size_t count(
const std::string &keyword );
188 template <
typename typeT>
199 template <
typename typeT>
228 template <
typename typeT>
230 const std::string &k,
240 template <
typename typeT>
242 const std::string &k,
259 template <
typename typeT>
261 const std::string &k,
271 template <
typename typeT>
273 const std::string &k,
296template <
class verboseT>
301template <
class verboseT>
307template <
class verboseT>
313template <
class verboseT>
330template <
class verboseT>
336template <
class verboseT>
342template <
class verboseT>
354template <
class verboseT>
360template <
class verboseT>
366template <
class verboseT>
375template <
class verboseT>
381template <
class verboseT>
384 if( keyword ==
"COMMENT" )
389 if( keyword ==
"HISTORY" )
408template <
class verboseT>
416 std::string keyword = it->keyword();
418 auto range =
m_cardMap.equal_range( keyword );
420 for( mit = range.first; mit != range.second; ++mit )
422 if( mit->second == it )
434template <
class verboseT>
445 if( it->keyword() ==
"SIMPLE" || it->keyword() ==
"BITPIX" || it->keyword() ==
"NAXIS" ||
446 it->keyword() ==
"NAXIS1" || it->keyword() ==
"NAXIS2" || it->keyword() ==
"NAXIS3" ||
447 it->keyword() ==
"EXTEND" || it->keyword() ==
"BZERO" || it->keyword() ==
"BSCALE" ||
448 it->keyword() ==
"LONGSTRN" )
453 if( it->keyword() ==
"COMMENT" )
455 if( it->comment().find(
"FITS (Flexible Image" ) != std::string::npos )
459 else if( it->comment().find(
"and Astrophysics'" ) != std::string::npos )
476template <
class verboseT>
479 if( card.
keyword() ==
"CONTINUE" )
484 "CONTINUE card requires a preceding card" );
489 return backIt->appendContinue( card );
498 "attempt to duplicate keyword " + card.
keyword() );
507 error_t errc = fitsHeaderDetail::mutationHook()( fitsHeaderDetail::mutation::appendList );
517 catch(
const std::bad_alloc &e )
520 "inserting " + card.
keyword() +
" :" + e.what() );
522 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
529 catch(
const std::exception &e )
532 "inserting " + card.
keyword() +
" :" + e.what() );
534 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
545 error_t errc = fitsHeaderDetail::mutationHook()( fitsHeaderDetail::mutation::appendMap );
554 catch(
const std::bad_alloc &e )
558 "inserting " + card.
keyword() +
" :" + e.what() );
560 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
567 catch(
const std::exception &e )
571 "inserting " + card.
keyword() +
" :" + e.what() );
573 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
584template <
class verboseT>
595 for( it = head.
begin(); it != head.
end(); ++it )
603template <
class verboseT>
609template <
class verboseT>
615template <
class verboseT>
616template <
typename typeT>
622template <
class verboseT>
623template <
typename typeT>
629template <
class verboseT>
638 "duplicate keyword: " + card.
keyword() );
647 error_t errc = fitsHeaderDetail::mutationHook()( fitsHeaderDetail::mutation::insertBeforeList );
655 catch(
const std::bad_alloc &e )
658 "inserting " + card.
keyword() +
" :" + e.what() );
660 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
667 catch(
const std::exception &e )
670 "inserting " + card.
keyword() +
" :" + e.what() );
672 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
683 error_t errc = fitsHeaderDetail::mutationHook()( fitsHeaderDetail::mutation::insertBeforeMap );
692 catch(
const std::bad_alloc &e )
696 "inserting " + card.
keyword() +
" :" + e.what() );
698 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
705 catch(
const std::exception &e )
709 "inserting " + card.
keyword() +
" :" + e.what() );
711 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
722template <
class verboseT>
723template <
typename typeT>
729template <
class verboseT>
730template <
typename typeT>
736template <
class verboseT>
737template <
typename typeT>
743template <
class verboseT>
757 "duplicate keyword: " + card.
keyword() );
766 error_t errc = fitsHeaderDetail::mutationHook()( fitsHeaderDetail::mutation::insertAfterList );
774 catch(
const std::bad_alloc &e )
777 "inserting " + card.
keyword() +
" :" + e.what() );
779 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
786 catch(
const std::exception &e )
789 "inserting " + card.
keyword() +
" :" + e.what() );
791 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
802 error_t errc = fitsHeaderDetail::mutationHook()( fitsHeaderDetail::mutation::insertAfterMap );
811 catch(
const std::bad_alloc &e )
815 "inserting " + card.
keyword() +
" :" + e.what() );
817 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
824 catch(
const std::exception &e )
828 "inserting " + card.
keyword() +
" :" + e.what() );
830 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
841template <
class verboseT>
842template <
typename typeT>
848template <
class verboseT>
875template <
class verboseT>
906template <
typename dataT,
class fitsHeaderT>
908 std::vector<size_t> &bad,
910 std::vector<fitsHeaderT> &heads,
911 const std::string &keyw
915 v.resize( heads.size() );
918 for(
size_t i = 0; i < heads.size(); ++i )
921 v[i] = heads[i][keyw].template value<dataT>( &errc );
926 v[i] = std::numeric_limits<dataT>::max();
948template <
class fitsHeaderT>
951 std::string hist =
"Git status for " + repoName +
":";
952 head.append(
"", fitsHistoryType(), hist );
957 hist +=
", modified";
959 head.append(
"", fitsHistoryType(), hist );
964extern template class fitsHeader<verbose::d>;
error_t
The mxlib error codes.
@ noerror
No error has occurred.
@ std_exception
An exception was thrown.
@ std_bad_alloc
A bad allocation exception was thrown.
@ invalidarg
An argument was invalid.
@ notfound
An item was not found.
@ error
A general error has occurred.
error_t mxlib_error_report(const error_t &code, const std::string &expl, const std::source_location &loc=std::source_location::current())
Print a report to stderr given an mxlib error_t code and explanation and return the code.
#define mxlib_error_check(fxn)
Perform an error check, if an error occurs report it and return the error. Does not return on no erro...
#define mxlib_error_return(fxn)
Perform an error check, if an error occurs report it, and return the error code even if no error.
constexpr int fitsType()
Return the cfitsio constant for a given data type.
void fitsHeaderGitStatus(fitsHeaderT &head, const std::string &repoName, const char *sha1, int modified)
Write the status of a Git repository to HISTORY in a FITS header.
error_t headersToValues(std::vector< dataT > &v, std::vector< size_t > &bad, std::vector< fitsHeaderT > &heads, const std::string &keyw)
Convert the values in a std::vector of fits headers into a std::vector of values.