#ifndef SPHEREHEALPIX_SEEN #define SPHEREHEALPIX_SEEN #include "sphericalmap.h" #include "tvector.h" #include "ndatablock.h" #include "anydataobj.h" #include "ppersist.h" #include "HEALPixUtils.h" namespace SOPHYA { // ***************** CLASSE SphereHEALPix ***************************** /*! Class SphereHEALPix */ template class FIO_SphereHEALPix; template class FITS_SphereHEALPix; template class SphereHEALPix : public SphericalMap { public : // Static Methods to ease the use of HEALPix index <> angle conversion methods static inline int_4 nest2ring(int_4 nside,int_4 ipnest) { return HEALPix::nest2ring(nside, ipnest); } static inline int_4 ring2nest(int_4 nside,int_4 ipring) { return HEALPix::ring2nest(nside, ipring); } static inline int_4 ang2pix_ring(int_4 nside,double theta,double phi) { return HEALPix::ang2pix_ring(nside, theta, phi); } static inline int_4 ang2pix_nest(int_4 nside,double theta,double phi) { return HEALPix::ang2pix_nest(nside, theta, phi); } static inline void pix2ang_ring(int_4 nside,int_4 ipix,double& theta,double& phi) { HEALPix::pix2ang_ring(nside, ipix, theta, phi); } static inline void pix2ang_nest(int_4 nside,int_4 ipix,double& theta,double& phi) { HEALPix::pix2ang_nest(nside, ipix, theta, phi); } SphereHEALPix(); SphereHEALPix(int_4 m); SphereHEALPix(const SphereHEALPix& s, bool share); SphereHEALPix(const SphereHEALPix& s); virtual ~SphereHEALPix(); inline virtual bool IsTemp(void) const { if (sliceBeginIndex_.IsTemp() != pixels_.IsTemp() || sliceLenght_.IsTemp() != pixels_.IsTemp() ) throw PException(" l'etat 'temporaire' de la spherehealpix est incoherent"); return pixels_.IsTemp(); } inline virtual void SetTemp(bool temp=false) const { pixels_.SetTemp(temp); sliceBeginIndex_.SetTemp(temp); sliceLenght_.SetTemp(temp); }; // ------------------ Definition of PixelMap abstract methods virtual int_4 NbPixels() const; virtual T& PixVal(int_4 k); virtual T const& PixVal(int_4 k) const; uint_4 NbThetaSlices() const; virtual void GetThetaSlice(int_4 index,r_8& theta,TVector& phi,TVector& value) const; virtual void GetThetaSlice(int_4 sliceIndex,r_8& theta, r_8& phi0, TVector& pixelIndices,TVector& value) const ; virtual bool ContainsSph(double theta, double phi) const; virtual int_4 PixIndexSph(double theta,double phi) const; virtual void PixThetaPhi(int_4 k,double& theta,double& phi) const; virtual T SetPixels(T v); /*! Pixel Solid angle (steradians) All the pixels have the same solid angle. The dummy argument is for compatibility with eventual pixelizations which would not fulfil this requirement. */ inline virtual double PixSolAngle(int_4 dummy=0) const {return omeg_;} /* Acces to the DataBlock */ inline NDataBlock& DataBlock() {return pixels_;} inline const NDataBlock& DataBlock() const {return pixels_;} // --------------- Specific methods virtual void Resize(int_4 m); /*! \return type of storage of the map : RING or NESTED at the moment, always RING */ inline virtual char* TypeOfMap() const {return "RING";}; virtual T& PixValNest(int_4 k); virtual T const& PixValNest(int_4 k) const; virtual int_4 PixIndexSphNest(double theta,double phi) const; virtual void PixThetaPhiNest(int_4 k,double& theta,double& phi) const; void Pixelize(int_4); int_4 NestToRing(int_4) const; int_4 RingToNest(int_4) const; /*! \return value of healpix nside */ inline virtual int_4 SizeIndex() const {return(nSide_);} void print(ostream& os) const; // Operations diverses = , +=, ... SphereHEALPix& Set(const SphereHEALPix& a); inline SphereHEALPix& operator = (const SphereHEALPix& a) {return Set(a);} // A += -= *= /= x (ajoute, soustrait, ... x a tous les elements) //! Fill SphereHEALPix with all elements equal to \b x virtual SphereHEALPix& SetT(T a); inline SphereHEALPix& operator = (T a) {return SetT(a);} //! Add \b x to all elements virtual SphereHEALPix& Add(T a); inline SphereHEALPix& operator += (T x) { return Add(x); } //! Substract \b x to all elements virtual SphereHEALPix& Sub(T a,bool fginv=false); inline SphereHEALPix& operator -= (T x) { return Sub(x); } //! Multiply all elements by \b x virtual SphereHEALPix& Mul(T a); inline SphereHEALPix& operator *= (T x) { return Mul(x); } //! Divide all elements by \b x virtual SphereHEALPix& Div(T a); inline SphereHEALPix& operator /= (T x) { return Div(x); } // A += -= (ajoute, soustrait element par element les deux spheres ) //! Operator SphereHEALPix += SphereHEALPix virtual SphereHEALPix& AddElt(const SphereHEALPix& a); inline SphereHEALPix& operator += (const SphereHEALPix& a) { return AddElt(a); } virtual SphereHEALPix& SubElt(const SphereHEALPix& a); //! Operator SphereHEALPix -= SphereHEALPix inline SphereHEALPix& operator -= (const SphereHEALPix& a) { return SubElt(a); } // Multiplication, division element par element les deux SphereHEALPix virtual SphereHEALPix& MulElt(const SphereHEALPix& a); inline SphereHEALPix& operator *= (const SphereHEALPix& a) { return MulElt(a); } virtual SphereHEALPix& DivElt(const SphereHEALPix& a); inline SphereHEALPix& operator /= (const SphereHEALPix& a) { return DivElt(a); } void CloneOrShare(const SphereHEALPix& a); void Share(const SphereHEALPix& a); SphereHEALPix& CopyElt(const SphereHEALPix& a); // friend declaration for classes which handle persistence and FITS IO friend class FIO_SphereHEALPix; friend class FITS_SphereHEALPix; protected : // ------------- méthodes internes ---------------------- void InitNul(); void SetThetaSlices(); inline void setParameters(int_4 nside, int_4 nbpixels, double solangle) { nSide_= nside; nPix_= nbpixels; omeg_= solangle; } // ------------- variables internes ----------------------- int_4 nSide_; int_4 nPix_; double omeg_; NDataBlock pixels_; NDataBlock sliceBeginIndex_; // Rationalisation Mac. D.Y. NDataBlock sliceLenght_; }; //////////////////////////////////////////////////////////////// // Surcharge d'operateurs A (+,-,*,/) (T) x /*! \ingroup SkyMap \fn operator+(const SphereHEALPix&,T) \brief Operator SphereHEALPix = SphereHEALPix + constant */ template inline SphereHEALPix operator + (const SphereHEALPix& a, T b) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Add(b); return result;} /*! \ingroup SkyMap \fn operator+(T,const SphereHEALPix&) \brief Operator SphereHEALPix = constant + SphereHEALPix */ template inline SphereHEALPix operator + (T b,const SphereHEALPix& a) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Add(b); return result;} /*! \ingroup SphereHEALPix\fn operator-(const SphereHEALPix&,T) \brief Operator SphereHEALPix = SphereHEALPix - constant */ template inline SphereHEALPix operator - (const SphereHEALPix& a, T b) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Sub(b); return result;} /*! \ingroup \fn operator-(T,const SphereHEALPix&) \brief Operator SphereHEALPix = constant - SphereHEALPix */ template inline SphereHEALPix operator - (T b,const SphereHEALPix& a) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Sub(b,true); return result;} /*! \ingroup SkyMap \fn operator*(const SphereHEALPix&,T) \brief Operator SphereHEALPix = SphereHEALPix * constant */ template inline SphereHEALPix operator * (const SphereHEALPix& a, T b) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Mul(b); return result;} /*! \ingroup SkyMap \fn operator*(T,const SphereHEALPix&) \brief Operator SphereHEALPix = constant * SphereHEALPix */ template inline SphereHEALPix operator * (T b,const SphereHEALPix& a) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Mul(b); return result;} /*! \ingroup SkyMap \fn operator/(const SphereHEALPix&,T) \brief Operator SphereHEALPix = SphereHEALPix / constant */ template inline SphereHEALPix operator / (const SphereHEALPix& a, T b) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Div(b); return result;} /*! \ingroup SkyMap \fn operator/(T,const SphereHEALPix&) \brief Operator SphereHEALPix = constant / SphereHEALPix */ template inline SphereHEALPix operator / (T b, const SphereHEALPix& a) {SphereHEALPix result; result.CloneOrShare(a); result.SetTemp(true); result.Div(b, true); return result;} //////////////////////////////////////////////////////////////// // Surcharge d'operateurs C = A (+,-) B /*! \ingroup SkyMap \fn operator+(const SphereHEALPix&,const SphereHEALPix&) \brief Operator SphereHEALPix = SphereHEALPix + SphereHEALPix */ template inline SphereHEALPix operator + (const SphereHEALPix& a,const SphereHEALPix& b) { SphereHEALPix result; result.SetTemp(true); if (b.IsTemp()) { result.Share(b); result.AddElt(a); } else { result.CloneOrShare(a); result.AddElt(b); } return result; } /*! \ingroup SkyMap \fn operator-(const SphereHEALPix&,const SphereHEALPix&) \brief Operator SphereHEALPix = SphereHEALPix - SphereHEALPix */ template inline SphereHEALPix operator - (const SphereHEALPix& a,const SphereHEALPix& b) { SphereHEALPix result; result.SetTemp(true); if (b.IsTemp()) { result.Share(b); result.SubElt(a); } else { result.CloneOrShare(a); result.SubElt(b); } return result; } //////////////////////////////////////////////////////////////// // Surcharge d'operateurs C = A (*,/) B /*! \ingroup SkyMap \fn operator*(const SphereHEALPix&,const SphereHEALPix&) \brief Operator SphereHEALPix = SphereHEALPix * SphereHEALPix (pixel by pixel multiply) */ template inline SphereHEALPix operator * (const SphereHEALPix& a,const SphereHEALPix& b) { SphereHEALPix result; result.SetTemp(true); if (b.IsTemp()) { result.Share(b); result.MulElt(a); } else { result.CloneOrShare(a); result.MulElt(b); } return result; } /*! \ingroup SkyMap \fn operator/(const SphereHEALPix&,const SphereHEALPix&) \brief Operator SphereHEALPix = SphereHEALPix / SphereHEALPix (pixel by pixel divide) */ template inline SphereHEALPix operator / (const SphereHEALPix& a,const SphereHEALPix& b) { SphereHEALPix result; result.SetTemp(true); if (b.IsTemp()) { result.Share(b); result.DivElt(a); } else { result.CloneOrShare(a); result.DivElt(b); } return result; } } // Fin du namespace #endif