26#ifndef ioutils_fits__fitsHeader_hpp
27#define ioutils_fits__fitsHeader_hpp
30#include <unordered_map>
52template <
class verboseT = verbose::d>
60 typedef std::list<fitsHeaderCard<verboseT>>
cardListT;
68 typedef std::unordered_multimap<std::string, headerIteratorT>
cardMapT;
122 size_t count(
const std::string &keyword );
161 template <
typename typeT>
172 template <
typename typeT>
201 template <
typename typeT>
203 const std::string &k,
213 template <
typename typeT>
215 const std::string &k,
232 template <
typename typeT>
234 const std::string &k,
244 template <
typename typeT>
246 const std::string &k,
265 operator[](
const std::string &keyword )
const;
269template <
class verboseT>
274template <
class verboseT>
280template <
class verboseT>
286template <
class verboseT>
294 while( it != m_cardList.end() )
303template <
class verboseT>
306 return m_cardList.begin();
309template <
class verboseT>
312 return m_cardList.end();
315template <
class verboseT>
318 return m_cardMap.find( keyword )->second;
321template <
class verboseT>
324 return m_cardList.empty();
327template <
class verboseT>
330 return m_cardList.size();
333template <
class verboseT>
342template <
class verboseT>
345 return m_cardMap.count( keyword );
348template <
class verboseT>
351 if( keyword ==
"COMMENT" )
353 return internal::mxlib_error_report<verboseT>(
error_t::invalidarg,
"can't erase COMMENT by keyword" );
356 if( keyword ==
"HISTORY" )
358 return internal::mxlib_error_report<verboseT>(
error_t::invalidarg,
"can't erase HISTORY by keyword" );
361 auto mit = m_cardMap.find( keyword );
362 if( mit == m_cardMap.end() )
364 return internal::mxlib_error_report<verboseT>(
error_t::notfound,
"keyword not found in map:" + keyword );
372 nrmv = m_cardMap.erase( keyword );
374 catch(
const std::exception &e )
377 "exception thrown erasing " + keyword +
": " + e.what() );
379 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
389 return internal::mxlib_error_report<verboseT>(
error_t::notfound,
"keyword not found:" + keyword );
392 if( it == m_cardList.end() )
394 return internal::mxlib_error_report<verboseT>(
error_t::notfound,
"keyword not found in list:" + keyword );
399 m_cardList.erase( it );
402 catch(
const std::exception &e )
405 "exception thrown erasing " + keyword +
": " + e.what() );
407 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
418template <
class verboseT>
421 if( it == m_cardList.end() )
423 return internal::mxlib_error_report<verboseT>(
error_t::invalidarg,
"invalid list iterator" );
426 std::string keyword = it->keyword();
430 if( mit == m_cardMap.end() )
432 return internal::mxlib_error_report<verboseT>(
error_t::notfound,
"keyword not found in map:" + keyword );
435 if( keyword ==
"COMMENT" || keyword ==
"HISTORY" )
437 while( mit->second->keyword() == keyword && it->comment() != mit->second->comment() )
442 if( mit == m_cardMap.end() )
445 keyword +
" with matching comment not found" );
449 m_cardMap.erase( mit );
453 m_cardList.erase( it );
456 catch(
const std::exception &e )
459 "exception thrown erasing " + keyword +
": " + e.what() );
461 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
472template <
class verboseT>
483 if( it->keyword() ==
"SIMPLE" || it->keyword() ==
"BITPIX" || it->keyword() ==
"NAXIS" ||
484 it->keyword() ==
"NAXIS1" || it->keyword() ==
"NAXIS2" || it->keyword() ==
"NAXIS3" ||
485 it->keyword() ==
"EXTEND" || it->keyword() ==
"BZERO" || it->keyword() ==
"BSCALE" ||
486 it->keyword() ==
"LONGSTRN" )
491 if( it->keyword() ==
"COMMENT" )
493 if( it->comment().find(
"FITS (Flexible Image" ) != std::string::npos )
497 else if( it->comment().find(
"and Astrophysics'" ) != std::string::npos )
514template <
class verboseT>
517 if( card.
keyword() ==
"CONTINUE" )
521 return backIt->appendContinue( card );
525 if( m_cardMap.count( card.
keyword() ) > 0 )
527 if( card.
type() != fitsType<fitsCommentType>() && card.
type() != fitsType<fitsHistoryType>() )
530 "attempt to duplicate keyword " + card.
keyword() );
539 m_cardList.push_back( card );
540 insertedIt = m_cardList.end();
543 catch(
const std::bad_alloc &e )
546 "inserting " + card.
keyword() +
" :" + e.what() );
548 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
555 catch(
const std::exception &e )
558 "inserting " + card.
keyword() +
" :" + e.what() );
560 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
573 if( insres == m_cardMap.end() )
578 catch(
const std::bad_alloc &e )
581 "inserting " + card.
keyword() +
" :" + e.what() );
583 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
590 catch(
const std::exception &e )
593 "inserting " + card.
keyword() +
" :" + e.what() );
595 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
606template <
class verboseT>
611 for( it = head.
begin(); it != head.
end(); ++it )
619template <
class verboseT>
625template <
class verboseT>
631template <
class verboseT>
632template <
typename typeT>
638template <
class verboseT>
639template <
typename typeT>
645template <
class verboseT>
649 if( m_cardMap.count( card.
keyword() ) > 0 )
651 if( card.
type() != fitsType<fitsCommentType>() && card.
type() != fitsType<fitsHistoryType>() )
654 "duplicate keyword: " + card.
keyword() );
663 insertedIt = m_cardList.insert( it, card );
665 catch(
const std::bad_alloc &e )
668 "inserting " + card.
keyword() +
" :" + e.what() );
670 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
677 catch(
const std::exception &e )
680 "inserting " + card.
keyword() +
" :" + e.what() );
682 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
695 catch(
const std::bad_alloc &e )
698 "inserting " + card.
keyword() +
" :" + e.what() );
700 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
707 catch(
const std::exception &e )
710 "inserting " + card.
keyword() +
" :" + e.what() );
712 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
723template <
class verboseT>
724template <
typename typeT>
730template <
class verboseT>
731template <
typename typeT>
737template <
class verboseT>
738template <
typename typeT>
744template <
class verboseT>
748 if( m_cardMap.count( card.
keyword() ) > 0 )
750 if( card.
type() != fitsType<fitsCommentType>() && card.
type() != fitsType<fitsHistoryType>() )
753 "duplicate keyword: " + card.
keyword() );
762 insertedIt = m_cardList.insert( ++it, card );
764 catch(
const std::bad_alloc &e )
767 "inserting " + card.
keyword() +
" :" + e.what() );
769 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
776 catch(
const std::exception &e )
779 "inserting " + card.
keyword() +
" :" + e.what() );
781 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
794 catch(
const std::bad_alloc &e )
797 "inserting " + card.
keyword() +
" :" + e.what() );
799 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
806 catch(
const std::exception &e )
809 "inserting " + card.
keyword() +
" :" + e.what() );
811 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
822template <
class verboseT>
823template <
typename typeT>
829template <
class verboseT>
834 auto mit = m_cardMap.find( keyword );
837 if( mit == m_cardMap.end() )
839 error_t errc = append( keyword );
842 internal::mxlib_error_report<verboseT>( errc,
"appending " + keyword );
843 m_emptyCard.keyword(
"" );
848 mit = m_cardMap.find( keyword );
849 if( mit == m_cardMap.end() )
851 internal::mxlib_error_report<verboseT>(
error_t::notfound,
"after appending " + keyword );
861template <
class verboseT>
864 auto mit = m_cardMap.find( keyword );
865 if( mit == m_cardMap.end() )
867 internal::mxlib_error_report<verboseT>(
error_t::notfound, keyword +
" not found" );
868 m_emptyCard.keyword(
"" );
892template <
typename dataT,
class fitsHeaderT>
894 std::vector<size_t> &bad,
896 std::vector<fitsHeaderT> &heads,
897 const std::string &keyw
901 v.resize( heads.size() );
904 for(
size_t i = 0; i < heads.size(); ++i )
907 v[i] = heads[i][keyw].template value<dataT>( &errc );
912 v[i] = std::numeric_limits<dataT>::max();
934template <
class fitsHeaderT>
937 std::string hist =
"Git status for " + repoName +
":";
938 head.append(
"", fitsHistoryType(), hist );
943 hist +=
", modified";
945 head.append(
"", fitsHistoryType(), hist );
950extern 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.
#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.
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.