CCfits  2.7
FITSUtil.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 FITSUTIL_H
00010 #define FITSUTIL_H 1
00011 #include "CCfits.h"
00012 
00013 // functional
00014 #include <functional>
00015 // complex
00016 #include <complex>
00017 // valarray
00018 #include <valarray>
00019 // vector
00020 #include <vector>
00021 // string
00022 #include <string>
00023 // FitsError
00024 #include "FitsError.h"
00025 #include <typeinfo>
00026 
00027 
00028 namespace CCfits {
00029 
00030   namespace FITSUtil {
00031 
00280 #ifdef _MSC_VER
00281 #include "MSconfig.h" // for truncation double to float warning
00282 #endif
00283 
00284      template <typename T>
00285     void swap(T& left,T& right);
00286 
00287     template <typename T>
00288     void swap(std::vector<T>& left, std::vector<T>& right);
00289 
00290     string lowerCase(const string& inputString);
00291 
00292     string upperCase(const string& inputString);
00293 
00294   // Check if a file name includes an image compression specifier,
00295   // and return its location if it exists.
00296     string::size_type checkForCompressString(const string& fileName);
00297 
00298   struct InvalidConversion : public FitsException
00299   {
00300         InvalidConversion(const string& diag, bool silent=false);
00301 
00302   };
00303 
00304   struct MatchStem
00305   {
00306           bool operator()(const string& left, const string& right) const;
00307   };
00308 
00309   static const  double d1(0);
00310   static const  float  f1(0);
00311   static const  std::complex<float> c1(0.);
00312   static const  std::complex<double> d2(0.);
00313   static const  string s1("");
00314   static const  int    i1(0);
00315   static const  unsigned int  u1(0);        
00316   static const  long l1(0);
00317   static const  unsigned long ul1(0);
00318   static const  LONGLONG ll1(0);
00319   static const  short s2(0);
00320   static const  unsigned short us1(0); 
00321   static const  bool b1(false);
00322   static const  unsigned char b2(0);  
00323 
00324   char** CharArray(const std::vector<string>& inArray);
00325 
00326   string FITSType2String( int typeInt );
00327 
00328 
00329   template <typename S, typename T> 
00330   void fill(std::vector<S>& outArray, const std::vector<T>& inArray,size_t first, size_t last);
00331 
00332   template <typename S, typename T> 
00333   void fill(std::valarray<S>& outArray, const std::valarray<T>& inArray);
00334 
00335   template <typename S, typename T> 
00336   void fill(std::valarray<S>& outArray, const std::vector<T>& inArray,size_t first, size_t last);
00337 
00338 
00339   template <typename S, typename T> 
00340   void fill(std::vector<S>& outArray, const std::valarray<T>& inArray);
00341 
00342   // VF<-AF
00343    void fill(std::vector<std::complex<float> >& outArray, 
00344                   const std::valarray<std::complex<float> >& inArray);
00345 
00346   // VF<-AD
00347   void fill(std::vector<std::complex<float> >& outArray, 
00348                   const std::valarray<std::complex<double> >& inArray);
00349 
00350   // VD<-AD
00351   void fill(std::vector<std::complex<double> >& outArray, 
00352                   const std::valarray<std::complex<double> >& inArray);
00353 
00354 
00355   // VD<-AF
00356   void fill(std::vector<std::complex<double> >& outArray, 
00357                   const std::valarray<std::complex<float> >& inArray);
00358 
00359   template <typename T>
00360   void fill(std::vector<string>& outArray, const std::vector<T>& inArray, size_t first, size_t last);
00361 
00362   template <typename T>
00363   void fill(std::vector<T>& outArray, const std::vector<string>& inArray, size_t first, size_t last);
00364 
00365   template <typename S> 
00366   void fill(std::valarray<S>& outArray, const std::vector<string>& inArray,size_t first, size_t last);
00367 
00368 //  template <typename S, typename T>
00369 //  void fill(std::valarray<std::complex<S> >& outArray, const std::valarray<std::complex<T> >& inArray);            
00370   // seems no other way of doing this.
00371 
00372   // VF<-VF
00373 #ifdef TEMPLATE_AMBIG_DEFECT
00374   void fillMSvfvf(std::vector<std::complex<float> >& outArray, 
00375                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00376 #endif
00377 
00378   void fill(std::vector<std::complex<float> >& outArray, 
00379                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00380 
00381   // VF<-VD
00382 #ifdef TEMPLATE_AMBIG_DEFECT
00383     void fillMSvfvd(std::vector<std::complex<float> >& outArray, 
00384                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00385 #endif
00386 
00387    void fill(std::vector<std::complex<float> >& outArray, 
00388                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00389 
00390    // VD<-VD
00391 #ifdef TEMPLATE_AMBIG_DEFECT
00392  void fillMSvdvd(std::vector<std::complex<double> >& outArray, 
00393                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00394 #endif
00395 
00396    void fill(std::vector<std::complex<double> >& outArray, 
00397                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00398 
00399 #ifdef TEMPLATE_AMBIG_DEFECT
00400   void fillMSvdvf(std::vector<std::complex<double> >& outArray, 
00401                 const std::vector<std::complex<float> >& inArray, 
00402                         size_t first, size_t last);
00403 #else
00404   void fill(std::vector<std::complex<double> >& outArray, 
00405                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00406 #endif
00407 
00408   // AF<-VD
00409   void fill(std::valarray<std::complex<float> >& outArray, 
00410                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00411 
00412   // AF<-VF
00413 #ifdef TEMPLATE_AMBIG_DEFECT
00414  void fillMSafvf(std::valarray<std::complex<float> >& outArray, 
00415                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00416 #else
00417  void fill(std::valarray<std::complex<float> >& outArray, 
00418                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00419 #endif
00420 
00421  // AD<-VF
00422 #ifdef TEMPLATE_AMBIG_DEFECT
00423   void fillMSadvf(std::valarray<std::complex<double> >& outArray, 
00424                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00425 #else
00426   void fill(std::valarray<std::complex<double> >& outArray, 
00427                   const std::vector<std::complex<float> >& inArray, size_t first, size_t last);
00428 #endif
00429 
00430   // AD<-VD
00431 #ifdef TEMPLATE_AMBIG_DEFECT
00432   void fillMSadvd(std::valarray<std::complex<double> >& outArray, 
00433                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00434 #else
00435   void fill(std::valarray<std::complex<double> >& outArray, 
00436                   const std::vector<std::complex<double> >& inArray, size_t first, size_t last);
00437 #endif
00438 
00439   // AF<-AF
00440   void fill(std::valarray<std::complex<float> >& outArray,  
00441                   const std::valarray<std::complex<float> >& inArray);
00442   // AD<-AD
00443   void fill(std::valarray<std::complex<double> >& outArray,  
00444                   const std::valarray<std::complex<double> >& inArray);
00445   // AF<-AD
00446   void fill(std::valarray<std::complex<float> >& outArray, 
00447                   const std::valarray<std::complex<double> >& inArray);
00448   // AD<-AF
00449   void fill(std::valarray<std::complex<double> >& outArray,  
00450                   const std::valarray<std::complex<float> >& inArray);
00451 
00452 #if TEMPLATE_AMBIG_DEFECT || TEMPLATE_AMBIG7_DEFECT
00453   void fillMSvsvs(std::vector<string>& outArray, const std::vector<string>& inArray, size_t first, size_t last);
00454 #endif
00455 
00456 
00457   void fill(std::vector<string>& outArray, const std::vector<string>& inArray, size_t first, size_t last);
00458 
00459   template <typename S, typename T>
00460   string errorMessage(const S& out, const T& in);
00461 
00462 
00463 
00464     template <class T>
00465     struct MatchPtrName  
00466     {
00467           //    Parameterized Class MatchPtrName
00468           bool operator () (const T& left, const string& right) const;
00469 
00470       public:
00471       protected:
00472       private:
00473       private: //## implementation
00474     };
00475 
00476 
00477 
00478     template <class T>
00479     struct MatchName     
00480     {
00481           bool operator () (const T& left, const string& right) const;
00482 
00483       public:
00484       protected:
00485       private:
00486       private: //## implementation
00487     };
00488 
00489 
00490 
00491     template <class T>
00492     struct MatchNum 
00493     {
00494           bool operator () (const T& left, const int& right) const;
00495 
00496       public:
00497       protected:
00498       private:
00499       private: //## implementation
00500     };
00501 
00502 
00503 
00504     template <typename T>
00505     struct MatchType 
00506     {
00507           ValueType operator () ();
00508 
00509       public:
00510       protected:
00511       private:
00512       private: //## implementation
00513     };
00514 
00515 
00516 
00517     template <typename T>
00518     struct CVarray 
00519     {
00520           T* operator () (const std::vector<T>& inArray);
00521 
00522       public:
00523       protected:
00524       private:
00525       private: //## implementation
00526     };
00527 
00528 
00529 
00530     template <typename T>
00531     struct FitsNullValue 
00532     {
00533           T operator () ();
00534 
00535       public:
00536       protected:
00537       private:
00538       private: //## implementation
00539     };
00540 
00541 
00542 
00543     template <typename T>
00544     struct MatchImageType 
00545     {
00546           ImageType operator () ();
00547 
00548       public:
00549       protected:
00550       private:
00551       private: //## implementation
00552     };
00553 
00554 
00555 
00556     template <class T>
00557     struct MatchPtrNum  
00558     {
00559           bool operator () (const T& left, const int& right) const;
00560 
00561       public:
00562       protected:
00563       private:
00564       private: //## implementation
00565     };
00566     //  auto_ptr analogue for arrays.
00567 
00568 
00569 
00570     template <typename X>
00571     class auto_array_ptr 
00572     {
00573       public:
00574           explicit auto_array_ptr (X* p = 0) throw ();
00575           explicit auto_array_ptr (auto_array_ptr<X>& right) throw ();
00576           ~auto_array_ptr();
00577 
00578           void operator = (auto_array_ptr<X>& right);
00579           X& operator * () throw ();
00580           X& operator [] (size_t i) throw ();
00581           X operator [] (size_t i) const throw ();
00582           X* get () const;
00583           X* release () throw ();
00584           X* reset (X* p) throw ();
00585           static void remove (X*& x);
00586 
00587       protected:
00588       private:
00589       private: //## implementation
00590         // Data Members for Class Attributes
00591           X* m_p;
00592 
00593     };
00594 
00595 
00596 
00597     template <typename T>
00598     struct ComparePtrIndex 
00599     {
00600           bool operator () (const T* left, const T* right);
00601 
00602       public:
00603       protected:
00604       private:
00605       private: //## implementation
00606     };
00607 
00608 
00609 
00610     template <typename T>
00611     struct CAarray 
00612     {
00613           T* operator () (const std::valarray<T>& inArray);
00614 
00615       public:
00616       protected:
00617       private:
00618       private: //## implementation
00619     };
00620 
00621 
00622 
00623     template <typename T>
00624     struct CVAarray 
00625     {
00626           T* operator () (const std::vector< std::valarray<T> >& inArray);
00627 
00628       public:
00629       protected:
00630       private:
00631       private: //## implementation
00632     };
00633 
00634 
00635 
00636     class UnrecognizedType : public FitsException  //## Inherits: <unnamed>%3CE143AB00C6
00637     {
00638       public:
00639           UnrecognizedType (string diag, bool silent = true);
00640 
00641       protected:
00642       private:
00643       private: //## implementation
00644     };
00645 
00646     // Parameterized Class CCfits::FITSUtil::MatchPtrName 
00647 
00648     template <class T>
00649     inline bool MatchPtrName<T>::operator () (const T& left, const string& right) const
00650     {
00651        return left->name() == right;
00652     }
00653 
00654     // Parameterized Class CCfits::FITSUtil::MatchName 
00655 
00656     template <class T>
00657     inline bool MatchName<T>::operator () (const T& left, const string& right) const
00658     {
00659        return left.name() == right;
00660     }
00661 
00662     // Parameterized Class CCfits::FITSUtil::MatchNum 
00663 
00664     template <class T>
00665     inline bool MatchNum<T>::operator () (const T& left, const int& right) const
00666     {
00667     return left.index() == right;
00668     }
00669 
00670     // Parameterized Class CCfits::FITSUtil::MatchType 
00671 
00672     // Parameterized Class CCfits::FITSUtil::CVarray 
00673 
00674     template <typename T>
00675     inline T* CVarray<T>::operator () (const std::vector<T>& inArray)
00676     {
00677 
00678       // convert std containers used commonly in FITS to C arrays in an exception
00679       // safe manner that is also clear about resource ownership.      
00680       auto_array_ptr<T> pC(new T[inArray.size()]);
00681       T* c = pC.get();
00682       std::copy(inArray.begin(),inArray.end(),&c[0]);
00683       return pC.release();
00684     }
00685 
00686     // Parameterized Class CCfits::FITSUtil::FitsNullValue 
00687 
00688     template <typename T>
00689     inline T FitsNullValue<T>::operator () ()
00690     {
00691        // This works for int types.  Float, complex, and string types 
00692        //   are handled below with specialized templates.
00693        return 0;
00694     }
00695 
00696     // Parameterized Class CCfits::FITSUtil::MatchImageType 
00697 
00698     // Parameterized Class CCfits::FITSUtil::MatchPtrNum 
00699 
00700     template <class T>
00701     inline bool MatchPtrNum<T>::operator () (const T& left, const int& right) const
00702     {
00703     return left->index() == right;
00704     }
00705 
00706     // Parameterized Class CCfits::FITSUtil::auto_array_ptr 
00707 
00708     // Parameterized Class CCfits::FITSUtil::ComparePtrIndex 
00709 
00710     // Parameterized Class CCfits::FITSUtil::CAarray 
00711 
00712     // Parameterized Class CCfits::FITSUtil::CVAarray 
00713 
00714     // Class CCfits::FITSUtil::UnrecognizedType 
00715 
00716     // Parameterized Class CCfits::FITSUtil::MatchPtrName 
00717 
00718     // Parameterized Class CCfits::FITSUtil::MatchName 
00719 
00720     // Parameterized Class CCfits::FITSUtil::MatchNum 
00721 
00722     // Parameterized Class CCfits::FITSUtil::MatchType 
00723 
00724     template <typename T>
00725     ValueType MatchType<T>::operator () ()
00726     {
00727 
00728     if ( typeid(T) == typeid(d1) ) return Tdouble;
00729     if ( typeid(T) == typeid(f1) ) return Tfloat;
00730     if ( typeid(T) == typeid(c1) ) return Tcomplex;
00731     if ( typeid(T) == typeid(d2) ) return Tdblcomplex;
00732     if ( typeid(T) == typeid(s1) ) return Tstring;
00733     if ( typeid(T) == typeid(i1) ) return Tint;
00734     if ( typeid(T) == typeid(u1) ) return Tuint;
00735     if ( typeid(T) == typeid(s2) ) return Tshort;
00736     if ( typeid(T) == typeid(us1) ) return Tushort;
00737     if ( typeid(T) == typeid(b1) ) return Tlogical;
00738     if ( typeid(T) == typeid(b2) ) return Tbyte;
00739     if ( typeid(T) == typeid(l1) ) return Tlong;
00740     if ( typeid(T) == typeid(ul1) ) return Tulong;
00741     // Carefull, on some compilers LONGLONG == long,
00742     // so this should go after test for long.
00743     if ( typeid(T) == typeid(ll1) ) return Tlonglong;
00744     throw UnrecognizedType("Invalid data type for FITS Data I/O\n");    
00745     }
00746 
00747     // Parameterized Class CCfits::FITSUtil::CVarray 
00748 
00749     // Parameterized Class CCfits::FITSUtil::MatchImageType 
00750 
00751     template <typename T>
00752     ImageType MatchImageType<T>::operator () ()
00753     {
00754     if ( typeid(T) == typeid(b2) ) return Ibyte;    
00755     if ( typeid(T) == typeid(s2) ) return Ishort;
00756     if ( typeid(T) == typeid(l1) ) return Ilong;
00757     if ( typeid(T) == typeid(f1) ) return Ifloat;
00758     if ( typeid(T) == typeid(d1) ) return Idouble;
00759     if ( typeid(T) == typeid(us1) ) return Iushort;
00760     if ( typeid(T) == typeid(ul1) ) return Iulong;
00761     if ( typeid(T) == typeid(ll1) ) return Ilonglong;
00762     MatchType<T> errType;
00763     string diag ("Image: ");
00764     diag += FITSType2String(errType());
00765     throw UnrecognizedType(diag);        
00766     }
00767 
00768     // Parameterized Class CCfits::FITSUtil::MatchPtrNum 
00769 
00770     // Parameterized Class CCfits::FITSUtil::auto_array_ptr 
00771 
00772     template <typename X>
00773     auto_array_ptr<X>::auto_array_ptr (X* p) throw ()
00774           : m_p(p)
00775     {
00776     }
00777 
00778     template <typename X>
00779     auto_array_ptr<X>::auto_array_ptr (auto_array_ptr<X>& right) throw ()
00780           : m_p(right.release())
00781     {
00782     }
00783 
00784 
00785     template <typename X>
00786     auto_array_ptr<X>::~auto_array_ptr()
00787     {
00788       delete [] m_p;
00789     }
00790 
00791 
00792     template <typename X>
00793     void auto_array_ptr<X>::operator = (auto_array_ptr<X>& right)
00794     {
00795       if (this != &right)
00796       {
00797                 remove(m_p);
00798                 m_p = right.release();       
00799       }
00800     }
00801 
00802     template <typename X>
00803     X& auto_array_ptr<X>::operator * () throw ()
00804     {
00805       return *m_p;
00806     }
00807 
00808     template <typename X>
00809     X& auto_array_ptr<X>::operator [] (size_t i) throw ()
00810     {
00811       return m_p[i];
00812     }
00813 
00814     template <typename X>
00815     X auto_array_ptr<X>::operator [] (size_t i) const throw ()
00816     {
00817       return m_p[i];
00818     }
00819 
00820     template <typename X>
00821     X* auto_array_ptr<X>::get () const
00822     {
00823       return m_p;
00824     }
00825 
00826     template <typename X>
00827     X* auto_array_ptr<X>::release () throw ()
00828     {
00829       return reset(0);
00830     }
00831 
00832     template <typename X>
00833     X* auto_array_ptr<X>::reset (X* p) throw ()
00834     {
00835       // set the auto_ptr to manage p and return the old pointer it was managing.
00836       X* __tmp = m_p; 
00837       m_p = p;
00838       return __tmp;
00839     }
00840 
00841     template <typename X>
00842     void auto_array_ptr<X>::remove (X*& x)
00843     {
00844       X* __tmp(x);
00845       x = 0;
00846       delete [] __tmp;
00847     }
00848 
00849     // Parameterized Class CCfits::FITSUtil::ComparePtrIndex 
00850 
00851     template <typename T>
00852     bool ComparePtrIndex<T>::operator () (const T* left, const T* right)
00853     {
00854       return (left->index() < right->index());
00855     }
00856 
00857     // Parameterized Class CCfits::FITSUtil::CAarray 
00858 
00859     template <typename T>
00860     T* CAarray<T>::operator () (const std::valarray<T>& inArray)
00861     {
00862       size_t n(inArray.size());
00863       auto_array_ptr<T> pC(new T[n]);
00864       T* c= pC.get();
00865       for (size_t j = 0; j < n; ++j) c[j] = inArray[j];
00866       return pC.release();      
00867     }
00868 
00869     // Parameterized Class CCfits::FITSUtil::CVAarray 
00870 
00871     template <typename T>
00872     T* CVAarray<T>::operator () (const std::vector< std::valarray<T> >& inArray)
00873     {
00874       size_t  sz(0);
00875       size_t  n(inArray.size());
00876 
00877       std::vector<size_t> nr(n);
00878 
00879       size_t i = 0; // for MS VC++ bug
00880       for ( i = 0; i < n; ++i)
00881       {
00882          nr[i] = inArray[i].size();
00883      sz += nr[i];
00884 
00885       }
00886       auto_array_ptr<T> pC(new T[sz]);
00887       T* c = pC.get();
00888 
00889       size_t k(0);
00890       for ( i = 0; i < n; ++i)
00891       {
00892          size_t& m = nr[i];
00893          const std::valarray<T>& current = inArray[i];
00894      for (size_t j=0; j < m ; ++j) c[k++] = current[j];
00895       }
00896 
00897       return pC.release();      
00898     }
00899 
00900   } // namespace FITSUtil
00901 } // namespace CCfits
00902 
00903 namespace CCfits
00904 {
00905 
00906    namespace FITSUtil
00907    {                
00908 
00909       template <typename T>
00910       void swap(T& left, T& right)
00911       {
00912               T temp(left);
00913               left = right;
00914               right = temp;                
00915       }
00916 
00917       template <typename T>
00918       void swap(std::vector<T>& left, std::vector<T>& right)
00919       {
00920               left.swap(right);        
00921       }
00922 
00923       template <>
00924       inline string FitsNullValue<string>::operator () ()
00925       {
00926      return string("");
00927       }
00928       
00929       template <>
00930       inline float FitsNullValue<float>::operator () ()
00931       {
00932          return FLOATNULLVALUE;
00933       }
00934 
00935       template <>
00936       inline double FitsNullValue<double>::operator () ()
00937       {
00938          return DOUBLENULLVALUE;
00939       }
00940       
00941       template <>
00942       inline std::complex<float> FitsNullValue<std::complex<float> >::operator () ()
00943       {
00944          return std::complex<float>(FLOATNULLVALUE);
00945       }
00946 
00947       template <>
00948       inline std::complex<double> FitsNullValue<std::complex<double> >::operator () ()
00949       {
00950          return std::complex<double>(DOUBLENULLVALUE);
00951       }
00952       
00953    } // end namespace FITSUtil
00954 } // end namespace CCfits
00955 
00956 
00957 
00958 #endif