CCfits  2.4
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 : public std::binary_function<string,string,bool>
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 : public std::binary_function<T,std::string,bool>  //## Inherits: <unnamed>%39491BC9025D
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 : public std::binary_function<T,std::string,bool>  //## Inherits: <unnamed>%39491BC50121
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 : public std::binary_function<T,int,bool>  //## Inherits: <unnamed>%39491BCE01C0
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 : public std::binary_function<T,int,bool>  //## Inherits: <unnamed>%39491BD3034B
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 : public std::binary_function<T,T,bool>  //## Inherits: <unnamed>%3B24DB930299
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     MatchType<T> errType;
00762     string diag ("Image: ");
00763     diag += FITSType2String(errType());
00764     throw UnrecognizedType(diag);        
00765     }
00766 
00767     // Parameterized Class CCfits::FITSUtil::MatchPtrNum 
00768 
00769     // Parameterized Class CCfits::FITSUtil::auto_array_ptr 
00770 
00771     template <typename X>
00772     auto_array_ptr<X>::auto_array_ptr (X* p) throw ()
00773           : m_p(p)
00774     {
00775     }
00776 
00777     template <typename X>
00778     auto_array_ptr<X>::auto_array_ptr (auto_array_ptr<X>& right) throw ()
00779           : m_p(right.release())
00780     {
00781     }
00782 
00783 
00784     template <typename X>
00785     auto_array_ptr<X>::~auto_array_ptr()
00786     {
00787       delete [] m_p;
00788     }
00789 
00790 
00791     template <typename X>
00792     void auto_array_ptr<X>::operator = (auto_array_ptr<X>& right)
00793     {
00794       if (this != &right)
00795       {
00796                 remove(m_p);
00797                 m_p = right.release();       
00798       }
00799     }
00800 
00801     template <typename X>
00802     X& auto_array_ptr<X>::operator * () throw ()
00803     {
00804       return *m_p;
00805     }
00806 
00807     template <typename X>
00808     X& auto_array_ptr<X>::operator [] (size_t i) throw ()
00809     {
00810       return m_p[i];
00811     }
00812 
00813     template <typename X>
00814     X auto_array_ptr<X>::operator [] (size_t i) const throw ()
00815     {
00816       return m_p[i];
00817     }
00818 
00819     template <typename X>
00820     X* auto_array_ptr<X>::get () const
00821     {
00822       return m_p;
00823     }
00824 
00825     template <typename X>
00826     X* auto_array_ptr<X>::release () throw ()
00827     {
00828       return reset(0);
00829     }
00830 
00831     template <typename X>
00832     X* auto_array_ptr<X>::reset (X* p) throw ()
00833     {
00834       // set the auto_ptr to manage p and return the old pointer it was managing.
00835       X* __tmp = m_p; 
00836       m_p = p;
00837       return __tmp;
00838     }
00839 
00840     template <typename X>
00841     void auto_array_ptr<X>::remove (X*& x)
00842     {
00843       X* __tmp(x);
00844       x = 0;
00845       delete [] __tmp;
00846     }
00847 
00848     // Parameterized Class CCfits::FITSUtil::ComparePtrIndex 
00849 
00850     template <typename T>
00851     bool ComparePtrIndex<T>::operator () (const T* left, const T* right)
00852     {
00853       return (left->index() < right->index());
00854     }
00855 
00856     // Parameterized Class CCfits::FITSUtil::CAarray 
00857 
00858     template <typename T>
00859     T* CAarray<T>::operator () (const std::valarray<T>& inArray)
00860     {
00861       size_t n(inArray.size());
00862       auto_array_ptr<T> pC(new T[n]);
00863       T* c= pC.get();
00864       for (size_t j = 0; j < n; ++j) c[j] = inArray[j];
00865       return pC.release();      
00866     }
00867 
00868     // Parameterized Class CCfits::FITSUtil::CVAarray 
00869 
00870     template <typename T>
00871     T* CVAarray<T>::operator () (const std::vector< std::valarray<T> >& inArray)
00872     {
00873       size_t  sz(0);
00874       size_t  n(inArray.size());
00875 
00876       std::vector<size_t> nr(n);
00877 
00878       size_t i = 0; // for MS VC++ bug
00879       for ( i = 0; i < n; ++i)
00880       {
00881          nr[i] = inArray[i].size();
00882          sz += nr[i];
00883 
00884       }
00885       auto_array_ptr<T> pC(new T[sz]);
00886       T* c = pC.get();
00887 
00888       size_t k(0);
00889       for ( i = 0; i < n; ++i)
00890       {
00891          size_t& m = nr[i];
00892          const std::valarray<T>& current = inArray[i];
00893          for (size_t j=0; j < m ; ++j) c[k++] = current[j];
00894       }
00895 
00896       return pC.release();      
00897     }
00898 
00899   } // namespace FITSUtil
00900 } // namespace CCfits
00901 
00902 namespace CCfits
00903 {
00904 
00905    namespace FITSUtil
00906    {                
00907 
00908       template <typename T>
00909       void swap(T& left, T& right)
00910       {
00911               T temp(left);
00912               left = right;
00913               right = temp;                
00914       }
00915 
00916       template <typename T>
00917       void swap(std::vector<T>& left, std::vector<T>& right)
00918       {
00919               left.swap(right);        
00920       }
00921 
00922       template <>
00923       inline string FitsNullValue<string>::operator () ()
00924       {
00925          return string("");
00926       }
00927       
00928       template <>
00929       inline float FitsNullValue<float>::operator () ()
00930       {
00931          return FLOATNULLVALUE;
00932       }
00933 
00934       template <>
00935       inline double FitsNullValue<double>::operator () ()
00936       {
00937          return DOUBLENULLVALUE;
00938       }
00939       
00940       template <>
00941       inline std::complex<float> FitsNullValue<std::complex<float> >::operator () ()
00942       {
00943          return std::complex<float>(FLOATNULLVALUE);
00944       }
00945 
00946       template <>
00947       inline std::complex<double> FitsNullValue<std::complex<double> >::operator () ()
00948       {
00949          return std::complex<double>(DOUBLENULLVALUE);
00950       }
00951       
00952    } // end namespace FITSUtil
00953 } // end namespace CCfits
00954 
00955 
00956 
00957 #endif