CCfits  2.5
HDU.h
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