/* --- SOPHYA software - FitsIOServer module --- R. Ansari , 2005-2008 (C) UPS+LAL IN2P3/CNRS (C) DAPNIA-SPP/CEA */ #ifndef FITSARRHAND_H #define FITSARRHAND_H #include "machdefs.h" #include #include "tarray.h" #include "tvector.h" #include "fitshandler.h" #include "fitsblkrw.h" namespace SOPHYA { /*! \ingroup FitsIOServer \brief FITS I/O handler for array objects */ template class FitsArrayHandler : public FitsHandlerInterface { public : FitsArrayHandler() { dobj=NULL; ownobj=true; } FitsArrayHandler(TArray< T > & obj) { dobj = &obj; ownobj=false; } virtual ~FitsArrayHandler() { if (ownobj && dobj) delete dobj; } virtual AnyDataObj* DataObj() { return(dobj); } virtual int CheckHandling(AnyDataObj & o) { if ( (typeid(o) == typeid(TArray)) || (typeid(o) == typeid(TMatrix)) || (typeid(o) == typeid(TVector)) ) return 2; TArray * po = dynamic_cast< TArray * >(& o); if (po == NULL) return 0; else return 1; } virtual void SetDataObj(AnyDataObj & o) { TArray * po = dynamic_cast< TArray * >(& o); if (po == NULL) { string msg = "FitsHandler::SetDataObj() Wrong object type: " ; msg += typeid(o).name(); throw TypeMismatchExc(msg); } if (ownobj && dobj) delete dobj; dobj = po; ownobj = false; } virtual int CheckReadability(FitsInOutFile& is) { if (is.CurrentHDUType() != IMAGE_HDU) return 0; T x = 0; LONGLONG naxes[BASEARRAY_MAXNDIMS]; int naxis=BASEARRAY_MAXNDIMS; int imgtyp = is.GetImageHDUInfo(naxis, naxes); if (naxis < 1) return 0; if (FitsTypes::ImageType(x) == imgtyp) return 2; else return 1; } virtual FitsHandlerInterface* Clone() { return new FitsArrayHandler< T >(); } inline operator T&() { return(*dobj); } //----- Ecriture //! Writes the complete array as an IMAGE HDU virtual void Write(FitsInOutFile& os) { if (( dobj == NULL) || (dobj->Size() < 1)) throw NullPtrError("FitsArrayHandler::Write() dobj=NULL or dobj->Size()=0"); LONGLONG naxes[BASEARRAY_MAXNDIMS] = {0,0,0,0,0}; for(int_4 id=0; idNbDimensions(); id++) naxes[id] = dobj->Size(id); int naxis=dobj->NbDimensions(); T x = 0; TVector * pvec = dynamic_cast< TVector * >(dobj); if (pvec!=NULL) { naxis=1; naxes[0]=pvec->NElts(); } os.CreateImageHDU(FitsTypes::ImageType(x), naxis, naxes); os.WriteHeaderRecords(dobj->Info()); MuTyV mtv; mtv = "SOPHYA::TArray"; os.WriteKey("SOPCLSNM",mtv," Object class name "); FitsBlockRW::WriteImageData(os, dobj->Data(), dobj->Size()); } //----- Lecture //! Resize the array and reads the complete IMAGE HDU to the array virtual void Read(FitsInOutFile& is) { LONGLONG naxes[BASEARRAY_MAXNDIMS]; int naxis=BASEARRAY_MAXNDIMS; is.GetImageHDUInfo(naxis, naxes); if ( dobj == NULL) { if (naxis == 1) dobj = new TVector; else if (naxis == 2) { if ( (naxes[0] == 1) || (naxes[1] == 1) ) dobj = new TVector; else dobj = new TMatrix; } else dobj = new TArray; ownobj = true; } sa_size_t sz[BASEARRAY_MAXNDIMS]; if (naxis > BASEARRAY_MAXNDIMS) { cerr << "FitsArrayHandler::Read()/Warning FITS NAXIS=" << naxis << " > BASEARRAY_MAXNDIMS=" << BASEARRAY_MAXNDIMS << endl; naxis = BASEARRAY_MAXNDIMS; } for(int_4 id=0; id * pmx = dynamic_cast< TMatrix * >(dobj); if ((naxis==1)&&(pmx!=NULL)) { TVector * pvec = dynamic_cast< TVector * >(dobj); if (pvec!=NULL) pvec->SetSize(naxes[0]); else pmx->SetSize(1,naxes[0]); } else dobj->SetSize(naxis, sz, 1, false); FitsBlockRW::ReadImageData(is, dobj->Data(), dobj->Size()); is.GetHeaderRecords(dobj->Info()); } //----- Lecture avec specification d'offset et taille donnee par le tableau /*! \brief Reads from the fits file into the array, at the specified offset The array should be allocated and its size is used to define the number of pixels to be read. \warning The offset should be specified with SOPHYA/C array index convention (starting at zero) - and NOT the cfitsio/fortran convention. The offset should contain as many elements as the fits NAXIS keyword. */ virtual void ReadAtOffset(FitsInOutFile& is, sa_size_t* offset) { if (( dobj == NULL) || (dobj->Size() < 1)) throw NullPtrError("FitsArrayHandler::ReadAtOffset() dobj=NULL or dobj->Size()=0"); LONGLONG naxes[BASEARRAY_MAXNDIMS]; int naxis=BASEARRAY_MAXNDIMS; is.GetImageHDUInfo(naxis, naxes); LONGLONG fpix[15]; int namx = (naxis < 15) ? naxis : 15; for(int i=0; i::ReadImageData(is, dobj->Data(), dobj->Size(), fpix); is.GetHeaderRecords(dobj->Info()); } //----- Ecriture avec specification d'offset et taille donnee par le tableau /*! \brief Writes the array to the fits file, at the specified offset The array should be allocated and its size is used to define the number of pixels to be written. \warning The offset should be specified with SOPHYA/C array index convention (starting at zero) - and NOT the cfitsio/fortran convention. The offset should contain as many elements as the fits NAXIS keyword. \warning The IMAGE HDU should be already created using FitsInOutFile::CreateImageHDU(). */ virtual void WriteAtOffset(FitsInOutFile& os, sa_size_t* offset) { if (( dobj == NULL) || (dobj->Size() < 1)) throw NullPtrError("FitsArrayHandler::ReadAtOffset() dobj=NULL or dobj->Size()=0"); LONGLONG naxes[BASEARRAY_MAXNDIMS]; int naxis=BASEARRAY_MAXNDIMS; os.GetImageHDUInfo(naxis, naxes); LONGLONG fpix[15]; int namx = (naxis < 15) ? naxis : 15; for(int i=0; i::WriteImageData(os, dobj->Data(), dobj->Size(), fpix); } protected : TArray * dobj; bool ownobj; // True si dobj obtenu par new }; //! operator << overload to write a TArray to a fits IMAGE HDU template inline FitsInOutFile& operator << (FitsInOutFile& os, TArray const & obj) { FitsArrayHandler fio(const_cast< TArray &>(obj)); fio.Write(os); return os; } //! operator >> overload to read a TArray from a fits IMAGE HDU template inline FitsInOutFile& operator >> (FitsInOutFile& is, TArray & obj) { FitsArrayHandler fio(obj); fio.Read(is); is.MoveToNextHDU(); return(is); } } // Fin du namespace #endif