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