CCfits  2.7
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 
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