CCfits  2.4
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 {
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