CCfits
2.7
|
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 00030 } // namespace CCfits 00031 namespace CCfits { 00032 class HDUCreator; // Needed for friend declaration 00033 } 00034 00035 #ifdef _MSC_VER 00036 #include "MSconfig.h" // for truncation warning 00037 #endif 00038 #include "KeywordT.h" 00039 00040 00041 namespace CCfits { 00042 00686 class HDU 00687 { 00688 00689 public: 00690 00691 00692 class InvalidImageDataType : public FitsException //## Inherits: <unnamed>%394FBA12005C 00693 { 00694 public: 00695 InvalidImageDataType (const string& diag, bool silent = true); 00696 00697 protected: 00698 private: 00699 private: //## implementation 00700 }; 00701 00702 00703 class InvalidExtensionType : public FitsException //## Inherits: <unnamed>%3964C1D00352 00704 { 00705 public: 00706 InvalidExtensionType (const string& diag, bool silent = true); 00707 00708 protected: 00709 private: 00710 private: //## implementation 00711 }; 00712 00713 00714 class NoSuchKeyword : public FitsException //## Inherits: <unnamed>%398865D10264 00715 { 00716 public: 00717 NoSuchKeyword (const string& diag, bool silent = true); 00718 00719 protected: 00720 private: 00721 private: //## implementation 00722 }; 00723 00724 00725 class NoNullValue : public FitsException //## Inherits: <unnamed>%3B0D58CE0306 00726 { 00727 public: 00728 NoNullValue (const string& diag, bool silent = true); 00729 00730 protected: 00731 private: 00732 private: //## implementation 00733 }; 00734 00735 00736 HDU(const HDU &right); 00737 bool operator==(const HDU &right) const; 00738 00739 bool operator!=(const HDU &right) const; 00740 00741 virtual HDU * clone (FITS* p) const = 0; 00742 fitsfile* fitsPointer () const; 00743 FITS* parent () const; 00744 // By all means necessary, set the fitsfile pointer so that 00745 // this HDU is the current HDU. 00746 // 00747 // This would appear to be a good candidate for the public 00748 // interface. 00749 virtual void makeThisCurrent () const; 00750 const String& getComments (); 00751 const string& comment () const; 00752 // Write a comment string. A default value for the string is given 00753 // "GenericComment" so users can put a placeholder call 00754 // to this function in their code before knowing quite what should go in it. 00755 void writeComment (const String& comment = "Generic Comment"); 00756 const String& getHistory (); 00757 const string& history () const; 00758 // Write a history string. A default value for the string is given 00759 // "Generic History String" so users can put a placeholder call 00760 // to this function in their code before knowing quite what should go in it. 00761 void writeHistory (const String& history = "Generic History String"); 00762 // Write a date card. 00763 void writeDate (); 00764 friend std::ostream& operator << (std::ostream& s, const CCfits::HDU& right); 00765 long axes () const; 00766 long axis (size_t index) const; 00767 void index (int value); 00768 int index () const; 00769 long bitpix () const; 00770 virtual double scale () const; 00771 virtual void scale (double value); 00772 virtual double zero () const; 00773 virtual void zero (double value); 00774 virtual void resetImageRead (); 00775 virtual void suppressScaling (bool toggle = true); 00776 void writeChecksum (); 00777 void updateChecksum (); 00778 std::pair<int,int> verifyChecksum () const; 00779 std::pair<unsigned long,unsigned long> getChecksum () const; 00780 void deleteKey (const String& doomed); 00781 void readAllKeys (const std::vector<int> & keyCategories = std::vector<int>()); 00782 void copyAllKeys (const HDU* inHdu, const std::vector<int> & keyCategories = std::vector<int>()); 00783 std::map<String, Keyword*>& keyWord (); 00784 Keyword& keyWord (const String& keyName); 00785 static std::vector<int> keywordCategories (); 00786 const std::map<string,Keyword*>& keyWord () const; 00787 const Keyword& keyWord (const string& keyname) const; 00788 Keyword& readNextKey(const std::vector<String>& incList, 00789 const std::vector<String>& excList, 00790 bool searchFromBeginning = false); 00791 00792 00793 public: 00794 // Additional Public Declarations 00795 00796 template <typename T> 00797 void readKey(const String& keyName, T& val); 00798 00799 template <typename T> 00800 void readKeys(std::vector<String>& keyNames, std::vector<T>& vals); 00801 00802 template <typename T> 00803 Keyword& addKey(const String& name, T val, const String& comment, bool isLongStr = false); 00804 00805 // This non-template function could be entered with Rose, but 00806 // it's instead placed with the other addKey function to 00807 // simplify the Doxygen generated doc file output. 00808 Keyword* addKey(const Keyword* inKeyword); 00809 00810 Keyword& addKey(const String& name, const char* charString, const String& comment, bool isLongStr = false); 00811 00812 Keyword& addKeyNull(const String& name, const String& comment, bool isLongStr = false); 00813 00814 #ifdef TEMPLATE_AMBIG_DEFECT 00815 inline void readKeyMS(const String& keyName, int & val); 00816 inline void readKeys(std::vector<String>& keyNames, std::vector<String>& vals); 00817 00818 #endif 00819 00820 00821 protected: 00822 00823 // Functions as the default constructor, which is required for 00824 // the map container class. 00825 HDU (FITS* p = 0); 00826 HDU (FITS* p, int bitpix, int naxis, const std::vector<long>& axes); 00827 virtual ~HDU(); 00828 00829 Keyword& readKeyword (const String &keyname); 00830 void readKeywords (std::list<String>& keynames); 00831 virtual std::ostream & put (std::ostream &s) const = 0; 00832 void bitpix (long value); 00833 bool checkImgDataTypeChange (double zero, double scale) const; 00834 long& naxis (); 00835 void naxis (const long& value); 00836 // Flags whether there were any null values found in the 00837 // last read operation. 00838 bool& anynul (); 00839 void anynul (const bool& value); 00840 FITS*& parent (); 00841 00842 std::vector< long >& naxes (); 00843 long& naxes (size_t index); 00844 void naxes (size_t index, const long& value); 00845 00846 // Additional Protected Declarations 00847 00848 00849 private: 00850 00851 // clear the FITS Keyword map. To be called by 00852 // the dtor and the copy/assignment operations. 00853 void clearKeys (); 00854 virtual void initRead () = 0; 00855 void readHduInfo (); 00856 Keyword* addKeyword (Keyword* newKey); 00857 virtual bool compare (const HDU &right) const; 00858 // clear the FITS Keyword map. To be called by 00859 // the dtor and the copy/assignment operations. 00860 void copyKeys (const HDU& right); 00861 String getNamedLines (const String& name); 00862 // save keyword found by read all keys into the array of keywords that have been read. 00863 // Similar to addKeyword except there's no write and no returned value. For use by readAllKeys() 00864 void saveReadKeyword (Keyword* newKey); 00865 void zeroInit (double value); 00866 void scaleInit (double value); 00867 00868 // Additional Private Declarations 00869 00870 00871 private: //## implementation 00872 // Data Members for Class Attributes 00873 long m_naxis; 00874 long m_bitpix; 00875 int m_index; 00876 bool m_anynul; 00877 string m_history; 00878 string m_comment; 00879 double m_zero; 00880 // Floating point scale factor for image data that takes 00881 // the value of the BSCALE parameter. 00882 double m_scale; 00883 00884 // Data Members for Associations 00885 std::map<string,Keyword*> m_keyWord; 00886 FITS* m_parent; 00887 std::vector< long > m_naxes; 00888 00889 // Additional Implementation Declarations 00890 static const size_t s_nCategories; 00891 static const int s_iKeywordCategories[]; 00892 00893 friend class HDUCreator; 00894 friend Keyword* KeywordCreator::getKeyword(const String& keyname, HDU* p); 00895 friend Keyword* KeywordCreator::getKeyword(const String& keyname, ValueType keyType, HDU* p); 00896 00897 }; 00898 00899 00900 template <typename T> 00901 Keyword& HDU::addKey(const String& name, T value, const String& comment, bool isLongStr) 00902 { 00903 makeThisCurrent(); 00904 NewKeyword<T> keyCreator(this,value); 00905 Keyword& newKey = *(addKeyword(keyCreator.createKeyword(name,comment,isLongStr))); 00906 return newKey; 00907 } 00908 00909 template <typename T> 00910 void HDU::readKey(const String& keyName, T& val) 00911 { 00912 makeThisCurrent(); 00913 Keyword& key = readKeyword(keyName); 00914 key.value(val); 00915 } 00916 00917 template <typename T> 00918 void HDU::readKeys(std::vector<String>& keyNames, std::vector<T>& vals) 00919 { 00920 size_t nRead = keyNames.size(); 00921 00922 std::list<String> valKeys; 00923 std::list<T> valList; 00924 for (size_t i = 0; i < nRead; i++) valKeys.push_back(keyNames[i]); 00925 // read all the keys requested, rejecting those that don't exist. 00926 00927 readKeywords(valKeys); 00928 00929 // get the values of all of the requested keys, rejecting those of the 00930 // wrong type. 00931 00932 T current; 00933 std::list<String>::iterator it = valKeys.begin(); 00934 while (it != valKeys.end()) 00935 { 00936 try 00937 { 00938 m_keyWord[*it]->value(current); 00939 valList.push_back(current); 00940 ++it; 00941 } 00942 catch ( Keyword::WrongKeywordValueType ) 00943 { 00944 it = valKeys.erase(it); 00945 } 00946 } 00947 00948 keyNames.erase(keyNames.begin(),keyNames.end()); 00949 00950 if (!valList.empty()) 00951 { 00952 if (valList.size() != vals.size()) vals.resize(valList.size()); 00953 00954 size_t i=0; 00955 for (typename std::list<T>::const_iterator it1 00956 = valList.begin(); it1 != valList.end(); ++it1,++i) 00957 { 00958 vals[i] = *it1; 00959 } 00960 for (std::list<String>::const_iterator it1= valKeys.begin(); it1 != valKeys.end(); ++it1) 00961 { 00962 keyNames.push_back(*it1); 00963 } 00964 } 00965 00966 } 00967 00968 // Class CCfits::HDU::InvalidImageDataType 00969 00970 // Class CCfits::HDU::InvalidExtensionType 00971 00972 // Class CCfits::HDU::NoSuchKeyword 00973 00974 // Class CCfits::HDU::NoNullValue 00975 00976 // Class CCfits::HDU 00977 00978 inline const string& HDU::comment () const 00979 { 00980 return m_comment; 00981 } 00982 00983 inline const string& HDU::history () const 00984 { 00985 return m_history; 00986 } 00987 00988 inline std::ostream& operator << (std::ostream& s, const CCfits::HDU& right) 00989 { 00990 return right.put(s); 00991 } 00992 00993 inline long HDU::axes () const 00994 { 00995 return m_naxis; 00996 } 00997 00998 inline long HDU::axis (size_t index) const 00999 { 01000 return m_naxes[index]; 01001 } 01002 01003 inline void HDU::index (int value) 01004 { 01005 m_index = value; 01006 } 01007 01008 inline int HDU::index () const 01009 { 01010 return m_index; 01011 } 01012 01013 inline long HDU::bitpix () const 01014 { 01015 return m_bitpix; 01016 } 01017 01018 inline void HDU::bitpix (long value) 01019 { 01020 m_bitpix = value; 01021 } 01022 01023 inline double HDU::scale () const 01024 { 01025 return m_scale; 01026 } 01027 01028 inline void HDU::scale (double value) 01029 { 01030 m_scale = value; 01031 } 01032 01033 inline double HDU::zero () const 01034 { 01035 return m_zero; 01036 } 01037 01038 inline void HDU::zero (double value) 01039 { 01040 m_zero = value; 01041 } 01042 01043 inline void HDU::resetImageRead () 01044 { 01045 } 01046 01047 inline void HDU::saveReadKeyword (Keyword* newKey) 01048 { 01049 m_keyWord.insert(std::map<String,Keyword*>::value_type(newKey->name(),newKey->clone())); 01050 } 01051 01052 inline std::map<String, Keyword*>& HDU::keyWord () 01053 { 01054 return m_keyWord; 01055 } 01056 01057 inline Keyword& HDU::keyWord (const String& keyName) 01058 { 01059 std::map<String,Keyword*>::iterator key = m_keyWord.find(keyName); 01060 if (key == m_keyWord.end()) throw HDU::NoSuchKeyword(keyName); 01061 return *((*key).second); 01062 } 01063 01064 inline long& HDU::naxis () 01065 { 01066 return m_naxis; 01067 } 01068 01069 inline void HDU::naxis (const long& value) 01070 { 01071 m_naxis = value; 01072 } 01073 01074 inline bool& HDU::anynul () 01075 { 01076 return m_anynul; 01077 } 01078 01079 inline void HDU::anynul (const bool& value) 01080 { 01081 m_anynul = value; 01082 } 01083 01084 inline const std::map<string,Keyword*>& HDU::keyWord () const 01085 { 01086 return m_keyWord; 01087 } 01088 01089 inline const Keyword& HDU::keyWord (const string& keyname) const 01090 { 01091 std::map<String,Keyword*>::const_iterator key = m_keyWord.find(keyname); 01092 if (key == m_keyWord.end()) throw HDU::NoSuchKeyword(keyname); 01093 return *((*key).second); 01094 } 01095 01096 inline FITS*& HDU::parent () 01097 { 01098 return m_parent; 01099 } 01100 01101 inline std::vector< long >& HDU::naxes () 01102 { 01103 return m_naxes; 01104 } 01105 01106 inline long& HDU::naxes (size_t index) 01107 { 01108 return m_naxes[index]; 01109 } 01110 01111 inline void HDU::naxes (size_t index, const long& value) 01112 { 01113 m_naxes[index] = value; 01114 } 01115 01116 } // namespace CCfits 01117 01118 #ifdef SPEC_TEMPLATE_IMP_DEFECT 01119 namespace CCfits { 01120 01121 inline void HDU::readKeyMS(const String& keyName, int & val) 01122 { 01123 makeThisCurrent(); 01124 Keyword& key = readKeyword(keyName); 01125 key.value(val); 01126 } 01127 01128 inline void HDU::readKeys(std::vector<String>& keyNames, std::vector<String>& vals) 01129 { 01130 size_t nRead = keyNames.size(); 01131 01132 std::list<String> valKeys; 01133 std::list<String> valList; 01134 for (size_t i = 0; i < nRead; i++) valKeys.push_back(keyNames[i]); 01135 // read all the keys requested, rejecting those that don't exist. 01136 01137 readKeywords(valKeys); 01138 01139 // get the values of all of the requested keys, rejecting those of the 01140 // wrong type. 01141 01142 String current; 01143 std::list<String>::iterator it = valKeys.begin(); 01144 while (it != valKeys.end()) 01145 { 01146 try 01147 { 01148 m_keyWord[*it]->value(current); 01149 valList.push_back(current); 01150 ++it; 01151 } 01152 catch ( Keyword::WrongKeywordValueType ) 01153 { 01154 it = valKeys.erase(it); 01155 } 01156 } 01157 01158 keyNames.erase(keyNames.begin(),keyNames.end()); 01159 01160 if (!valList.empty()) 01161 { 01162 if (valList.size() != vals.size()) vals.resize(valList.size()); 01163 01164 size_t i=0; 01165 std::list<String>::const_iterator it1 = valList.begin(); 01166 for ( ; it1 != valList.end(); ++it1,++i) 01167 { 01168 vals[i] = *it1; 01169 } 01170 for ( it1= valKeys.begin(); it1 != valKeys.end(); ++it1) 01171 { 01172 keyNames.push_back(*it1); 01173 } 01174 } 01175 01176 } 01177 } 01178 #endif 01179 01180 01181 #endif