CCfits
2.4
|
00001 // Astrophysics Science Division, 00002 // NASA/ Goddard Space Flight Center 00003 // HEASARC 00004 // http://heasarc.gsfc.nasa.gov 00005 // e-mail: ccfits@legacy.gsfc.nasa.gov 00006 // 00007 // Original author: Ben Dorman 00008 00009 #ifndef HDU_H 00010 #define HDU_H 1 00011 #include <map> 00012 00013 // vector 00014 #include <vector> 00015 #include <list> 00016 // CCfitsHeader 00017 #include "CCfits.h" 00018 // Keyword 00019 #include "Keyword.h" 00020 // NewKeyword 00021 #include "NewKeyword.h" 00022 // FitsError 00023 #include "FitsError.h" 00024 // FITSUtil 00025 #include "FITSUtil.h" 00026 00027 namespace CCfits { 00028 class FITS; 00029 class FITSBase; 00030 00031 } // namespace CCfits 00032 namespace CCfits { 00033 class HDUCreator; // Needed for friend declaration 00034 } 00035 00036 #ifdef _MSC_VER 00037 #include "MSconfig.h" // for truncation warning 00038 #endif 00039 #include "KeywordT.h" 00040 00041 00042 namespace CCfits { 00543 class HDU 00544 { 00545 00546 public: 00547 00548 00549 00550 class InvalidImageDataType : public FitsException //## Inherits: <unnamed>%394FBA12005C 00551 { 00552 public: 00553 InvalidImageDataType (const string& diag, bool silent = true); 00554 00555 protected: 00556 private: 00557 private: //## implementation 00558 }; 00559 00560 00561 00562 class InvalidExtensionType : public FitsException //## Inherits: <unnamed>%3964C1D00352 00563 { 00564 public: 00565 InvalidExtensionType (const string& diag, bool silent = true); 00566 00567 protected: 00568 private: 00569 private: //## implementation 00570 }; 00571 00572 00573 00574 class NoSuchKeyword : public FitsException //## Inherits: <unnamed>%398865D10264 00575 { 00576 public: 00577 NoSuchKeyword (const string& diag, bool silent = true); 00578 00579 protected: 00580 private: 00581 private: //## implementation 00582 }; 00583 00584 00585 00586 class NoNullValue : public FitsException //## Inherits: <unnamed>%3B0D58CE0306 00587 { 00588 public: 00589 NoNullValue (const string& diag, bool silent = true); 00590 00591 protected: 00592 private: 00593 private: //## implementation 00594 }; 00595 HDU(const HDU &right); 00596 bool operator==(const HDU &right) const; 00597 00598 bool operator!=(const HDU &right) const; 00599 00600 virtual HDU * clone (FITSBase* p) const = 0; 00601 fitsfile* fitsPointer () const; 00602 FITSBase* parent () const; 00603 // By all means necessary, set the fitsfile pointer so that 00604 // this HDU is the current HDU. 00605 // 00606 // This would appear to be a good candidate for the public 00607 // interface. 00608 virtual void makeThisCurrent () const; 00609 const String& getComments (); 00610 const string& comment () const; 00611 // Write a history string. A default value for the string is given 00612 // "GenericComment" so users can put a placeholder call 00613 // to this function in their code before knowing quite what should go in it. 00614 void writeComment (const String& comment = "Generic Comment"); 00615 const String& getHistory (); 00616 const string& history () const; 00617 // Write a history string. A default value for the string is given 00618 // "Generic History String" so users can put a placeholder call 00619 // to this function in their code before knowing quite what should go in it. 00620 void writeHistory (const String& history = "Generic History String"); 00621 // Write a date card. 00622 void writeDate (); 00623 friend std::ostream& operator << (std::ostream& s, const CCfits::HDU& right); 00624 long axes () const; 00625 long axis (size_t index) const; 00626 void index (int value); 00627 int index () const; 00628 long bitpix () const; 00629 virtual double scale () const; 00630 virtual void scale (double value); 00631 virtual double zero () const; 00632 virtual void zero (double value); 00633 void suppressScaling (bool toggle = true); 00634 void writeChecksum (); 00635 void updateChecksum (); 00636 std::pair<int,int> verifyChecksum () const; 00637 std::pair<unsigned long,unsigned long> getChecksum () const; 00638 void deleteKey (const String& doomed); 00639 void readAllKeys (); 00640 void copyAllKeys (const HDU* inHdu); 00641 std::map<String, Keyword*>& keyWord (); 00642 Keyword& keyWord (const String& keyName); 00643 static std::vector<int> keywordCategories (); 00644 const std::map<string,Keyword*>& keyWord () const; 00645 const Keyword& keyWord (const string& keyname) const; 00646 00647 public: 00648 // Additional Public Declarations 00649 template <typename T> 00650 void readKey(const String& keyName, T& val); 00651 00652 template <typename T> 00653 void readKeys(std::vector<String>& keyNames, std::vector<T>& vals); 00654 00655 template <typename T> 00656 Keyword& addKey(const String& name, T val, const String& comment); 00657 00658 // This non-template function could be entered with Rose, but 00659 // it's instead placed with the other addKey function to 00660 // simplify the Doxygen generated doc file output. 00661 Keyword* addKey(const Keyword* inKeyword); 00662 00663 Keyword& addKey(const String& name, const char* charString, const String& comment); 00664 00665 #ifdef TEMPLATE_AMBIG_DEFECT 00666 inline void readKeyMS(const String& keyName, int & val); 00667 inline void readKeys(std::vector<String>& keyNames, std::vector<String>& vals); 00668 00669 #endif 00670 protected: 00671 // Functions as the default constructor, which is required for 00672 // the map container class. 00673 HDU (FITSBase* p = 0); 00674 HDU (FITSBase* p, int bitpix, int naxis, const std::vector<long>& axes); 00675 virtual ~HDU(); 00676 00677 Keyword& readKeyword (const String &keyname); 00678 void readKeywords (std::list<String>& keynames); 00679 virtual std::ostream & put (std::ostream &s) const = 0; 00680 void bitpix (long value); 00681 bool checkImgDataTypeChange (double zero, double scale) const; 00682 long& naxis (); 00683 void naxis (const long& value); 00684 // Flags whether there were any null values found in the 00685 // last read operation. 00686 bool& anynul (); 00687 void anynul (const bool& value); 00688 FITSBase*& parent (); 00689 std::vector< long >& naxes (); 00690 long& naxes (size_t index); 00691 void naxes (size_t index, const long& value); 00692 00693 // Additional Protected Declarations 00694 00695 private: 00696 // clear the FITS Keyword map. To be called by 00697 // the dtor and the copy/assignment operations. 00698 void clearKeys (); 00699 virtual void initRead () = 0; 00700 void readHduInfo (); 00701 Keyword* addKeyword (Keyword* newKey); 00702 virtual bool compare (const HDU &right) const; 00703 // clear the FITS Keyword map. To be called by 00704 // the dtor and the copy/assignment operations. 00705 void copyKeys (const HDU& right); 00706 String getNamedLines (const String& name); 00707 // save keyword found by read all keys into the array of keywords that have been read. 00708 // Similar to addKeyword except there's no write and no returned value. For use by readAllKeys() 00709 void saveReadKeyword (Keyword* newKey); 00710 void zeroInit (double value); 00711 void scaleInit (double value); 00712 00713 // Additional Private Declarations 00714 00715 private: //## implementation 00716 // Data Members for Class Attributes 00717 long m_naxis; 00718 long m_bitpix; 00719 int m_index; 00720 bool m_anynul; 00721 string m_history; 00722 string m_comment; 00723 double m_zero; 00724 // Floating point scale factor for image data that takes 00725 // the value of the BSCALE parameter. 00726 double m_scale; 00727 00728 // Data Members for Associations 00729 std::map<string,Keyword*> m_keyWord; 00730 FITSBase* m_parent; 00731 std::vector< long > m_naxes; 00732 00733 // Additional Implementation Declarations 00734 static const size_t s_nCategories; 00735 static const int s_iKeywordCategories[]; 00736 00737 friend class HDUCreator; 00738 friend Keyword* KeywordCreator::getKeyword(const String& keyname, HDU* p); 00739 friend Keyword* KeywordCreator::getKeyword(const String& keyname, ValueType keyType, HDU* p); 00740 }; 00741 template <typename T> 00742 Keyword& HDU::addKey(const String& name, T value, const String& comment) 00743 { 00744 makeThisCurrent(); 00745 NewKeyword<T> keyCreator(this,value); 00746 Keyword& newKey = *(addKeyword(keyCreator.createKeyword(name,comment))); 00747 return newKey; 00748 } 00749 00750 template <typename T> 00751 void HDU::readKey(const String& keyName, T& val) 00752 { 00753 makeThisCurrent(); 00754 Keyword& key = readKeyword(keyName); 00755 key.value(val); 00756 } 00757 00758 00759 template <typename T> 00760 void HDU::readKeys(std::vector<String>& keyNames, std::vector<T>& vals) 00761 { 00762 size_t nRead = keyNames.size(); 00763 00764 std::list<String> valKeys; 00765 std::list<T> valList; 00766 for (size_t i = 0; i < nRead; i++) valKeys.push_back(keyNames[i]); 00767 // read all the keys requested, rejecting those that don't exist. 00768 00769 readKeywords(valKeys); 00770 00771 // get the values of all of the requested keys, rejecting those of the 00772 // wrong type. 00773 00774 T current; 00775 std::list<String>::iterator it = valKeys.begin(); 00776 while (it != valKeys.end()) 00777 { 00778 try 00779 { 00780 m_keyWord[*it]->value(current); 00781 valList.push_back(current); 00782 ++it; 00783 } 00784 catch ( Keyword::WrongKeywordValueType ) 00785 { 00786 it = valKeys.erase(it); 00787 } 00788 } 00789 00790 keyNames.erase(keyNames.begin(),keyNames.end()); 00791 00792 if (!valList.empty()) 00793 { 00794 if (valList.size() != vals.size()) vals.resize(valList.size()); 00795 00796 size_t i=0; 00797 for (typename std::list<T>::const_iterator it1 00798 = valList.begin(); it1 != valList.end(); ++it1,++i) 00799 { 00800 vals[i] = *it1; 00801 } 00802 for (std::list<String>::const_iterator it1= valKeys.begin(); it1 != valKeys.end(); ++it1) 00803 { 00804 keyNames.push_back(*it1); 00805 } 00806 } 00807 00808 } 00809 00810 // Class CCfits::HDU::InvalidImageDataType 00811 00812 // Class CCfits::HDU::InvalidExtensionType 00813 00814 // Class CCfits::HDU::NoSuchKeyword 00815 00816 // Class CCfits::HDU::NoNullValue 00817 00818 // Class CCfits::HDU 00819 00820 inline const string& HDU::comment () const 00821 { 00822 return m_comment; 00823 } 00824 00825 inline const string& HDU::history () const 00826 { 00827 return m_history; 00828 } 00829 00830 inline std::ostream& operator << (std::ostream& s, const CCfits::HDU& right) 00831 { 00832 return right.put(s); 00833 } 00834 00835 inline long HDU::axes () const 00836 { 00837 00838 return m_naxis; 00839 } 00840 00841 inline long HDU::axis (size_t index) const 00842 { 00843 00844 return m_naxes[index]; 00845 } 00846 00847 inline void HDU::index (int value) 00848 { 00849 00850 m_index = value; 00851 } 00852 00853 inline int HDU::index () const 00854 { 00855 return m_index; 00856 } 00857 00858 inline long HDU::bitpix () const 00859 { 00860 return m_bitpix; 00861 } 00862 00863 inline void HDU::bitpix (long value) 00864 { 00865 m_bitpix = value; 00866 } 00867 00868 inline double HDU::scale () const 00869 { 00870 return m_scale; 00871 } 00872 00873 inline void HDU::scale (double value) 00874 { 00875 m_scale = value; 00876 } 00877 00878 inline double HDU::zero () const 00879 { 00880 return m_zero; 00881 } 00882 00883 inline void HDU::zero (double value) 00884 { 00885 m_zero = value; 00886 } 00887 00888 inline void HDU::saveReadKeyword (Keyword* newKey) 00889 { 00890 m_keyWord.insert(std::map<String,Keyword*>::value_type(newKey->name(),newKey->clone())); 00891 } 00892 00893 inline std::map<String, Keyword*>& HDU::keyWord () 00894 { 00895 00896 return m_keyWord; 00897 } 00898 00899 inline Keyword& HDU::keyWord (const String& keyName) 00900 { 00901 std::map<String,Keyword*>::iterator key = m_keyWord.find(keyName); 00902 if (key == m_keyWord.end()) throw HDU::NoSuchKeyword(keyName); 00903 return *((*key).second); 00904 } 00905 00906 inline long& HDU::naxis () 00907 { 00908 return m_naxis; 00909 } 00910 00911 inline void HDU::naxis (const long& value) 00912 { 00913 m_naxis = value; 00914 } 00915 00916 inline bool& HDU::anynul () 00917 { 00918 return m_anynul; 00919 } 00920 00921 inline void HDU::anynul (const bool& value) 00922 { 00923 m_anynul = value; 00924 } 00925 00926 inline const std::map<string,Keyword*>& HDU::keyWord () const 00927 { 00928 return m_keyWord; 00929 } 00930 00931 inline const Keyword& HDU::keyWord (const string& keyname) const 00932 { 00933 std::map<String,Keyword*>::const_iterator key = m_keyWord.find(keyname); 00934 if (key == m_keyWord.end()) throw HDU::NoSuchKeyword(keyname); 00935 return *((*key).second); 00936 } 00937 00938 inline FITSBase*& HDU::parent () 00939 { 00940 return m_parent; 00941 } 00942 00943 inline std::vector< long >& HDU::naxes () 00944 { 00945 return m_naxes; 00946 } 00947 00948 inline long& HDU::naxes (size_t index) 00949 { 00950 return m_naxes[index]; 00951 } 00952 00953 inline void HDU::naxes (size_t index, const long& value) 00954 { 00955 m_naxes[index] = value; 00956 } 00957 00958 } // namespace CCfits 00959 #ifdef SPEC_TEMPLATE_IMP_DEFECT 00960 namespace CCfits { 00961 00962 inline void HDU::readKeyMS(const String& keyName, int & val) 00963 { 00964 makeThisCurrent(); 00965 Keyword& key = readKeyword(keyName); 00966 key.value(val); 00967 } 00968 00969 inline void HDU::readKeys(std::vector<String>& keyNames, std::vector<String>& vals) 00970 { 00971 size_t nRead = keyNames.size(); 00972 00973 std::list<String> valKeys; 00974 std::list<String> valList; 00975 for (size_t i = 0; i < nRead; i++) valKeys.push_back(keyNames[i]); 00976 // read all the keys requested, rejecting those that don't exist. 00977 00978 readKeywords(valKeys); 00979 00980 // get the values of all of the requested keys, rejecting those of the 00981 // wrong type. 00982 00983 String current; 00984 std::list<String>::iterator it = valKeys.begin(); 00985 while (it != valKeys.end()) 00986 { 00987 try 00988 { 00989 m_keyWord[*it]->value(current); 00990 valList.push_back(current); 00991 ++it; 00992 } 00993 catch ( Keyword::WrongKeywordValueType ) 00994 { 00995 it = valKeys.erase(it); 00996 } 00997 } 00998 00999 keyNames.erase(keyNames.begin(),keyNames.end()); 01000 01001 if (!valList.empty()) 01002 { 01003 if (valList.size() != vals.size()) vals.resize(valList.size()); 01004 01005 size_t i=0; 01006 std::list<String>::const_iterator it1 = valList.begin(); 01007 for ( ; it1 != valList.end(); ++it1,++i) 01008 { 01009 vals[i] = *it1; 01010 } 01011 for ( it1= valKeys.begin(); it1 != valKeys.end(); ++it1) 01012 { 01013 keyNames.push_back(*it1); 01014 } 01015 } 01016 01017 } 01018 } 01019 #endif 01020 01021 01022 #endif