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