source: Sophya/trunk/SophyaLib/SkyMap/spherehealpix.cc@ 2978

Last change on this file since 2978 was 2978, checked in by ansari, 19 years ago

1/ Mise en place de la prise en charge du schema de pixelisation NESTED dans
SphereHEALPix<T>
2/ petites corrections sur PixelMap<T> et cartes speheriques

Reza 21/06/2006

File size: 19.7 KB
RevLine 
[2615]1#include "sopnamsp.h"
[843]2#include "machdefs.h"
3#include <math.h>
4#include <complex>
5
6#include "pexceptions.h"
7#include "fiondblock.h"
8#include "spherehealpix.h"
9#include "strutil.h"
[1196]10
[843]11extern "C"
12{
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16}
17
[1195]18using namespace SOPHYA;
[843]19
[1217]20/*!
21 \class SOPHYA::SphereHEALPix
[2303]22 \ingroup SkyMap
[2808]23 \brief Spherical maps in HEALPix pixelisation scheme.
24
[2303]25 Class implementing spherical maps, in the HEALPix pixelisation scheme,
26 with template data types (double, float, complex, ...)
[843]27
[1217]28
29\verbatim
[2960]30 Adapted from :
[1217]31 -----------------------------------------------------------------------
32 version 0.8.2 Aug97 TAC Eric Hivon, Kris Gorski
33 -----------------------------------------------------------------------
34
35 the sphere is split in 12 diamond-faces containing nside**2 pixels each
36 the numbering of the pixels (in the nested scheme) is similar to
37 quad-cube
38 In each face the first pixel is in the lowest corner of the diamond
39 the faces are (x,y) coordinate on each face
40
41 . . . . <--- North Pole
42 / \ / \ / \ / \ ^ ^
43 . 0 . 1 . 2 . 3 . <--- z = 2/3 \ /
44 \ / \ / \ / \ / y \ / x
45 4 . 5 . 6 . 7 . 4 <--- equator \ /
46 / \ / \ / \ / \ \/
47 . 8 . 9 .10 .11 . <--- z = -2/3 (0,0) : lowest corner
48 \ / \ / \ / \ /
49 . . . . <--- South Pole
50\endverbatim
51 phi:0 2Pi
52
53 in the ring scheme pixels are numbered along the parallels
54 the first parallel is the one closest to the north pole and so on
55 on each parallel, pixels are numbered starting from the one closest
56 to phi = 0
57
58 nside MUST be a power of 2 (<= 8192)
59
60*/
61
[843]62/* --Methode-- */
63
[2978]64//! Default constructor - optional pixelisation scheme parameter
[843]65template<class T>
[2978]66SphereHEALPix<T>::SphereHEALPix(bool fgring) : fgring_(fgring), pixels_(),
67 sliceBeginIndex_(), sliceLenght_()
[843]68
69{
70 InitNul();
71}
72
[2978]73/*! \brief Constructor with specification of nside and optional pixelisation scheme
74
[1217]75 \param <m> : "nside" of the Healpix algorithm
[2978]76 \param <fgring> : if true -> RING pixelisation (default), if not NESTED
[1217]77
78 The total number of pixels will be Npix = 12*nside**2
79
80 nside MUST be a power of 2 (<= 8192)
81*/
82
[843]83template<class T>
[2978]84SphereHEALPix<T>::SphereHEALPix(int_4 m, bool fgring)
[843]85
86{
[2978]87 fgring_ = fgring;
[843]88 InitNul();
89 Pixelize(m);
90 SetThetaSlices();
91}
[2960]92//! Copy constructor
[843]93template<class T>
[853]94SphereHEALPix<T>::SphereHEALPix(const SphereHEALPix<T>& s, bool share)
[843]95 : pixels_(s.pixels_, share), sliceBeginIndex_(s.sliceBeginIndex_, share),
96 sliceLenght_(s.sliceLenght_, share)
97//--
98{
99 nSide_= s.nSide_;
100 nPix_ = s.nPix_;
101 omeg_ = s.omeg_;
[2978]102 fgring_ = s.fgring_;
[2885]103 if(s.mInfo_) this->mInfo_= new DVList(*s.mInfo_);
[843]104}
[906]105//++
106template<class T>
107SphereHEALPix<T>::SphereHEALPix(const SphereHEALPix<T>& s)
108 : pixels_(s.pixels_), sliceBeginIndex_(s.sliceBeginIndex_),
109 sliceLenght_(s.sliceLenght_)
110// copy constructor
111//--
112{
113 nSide_= s.nSide_;
114 nPix_ = s.nPix_;
115 omeg_ = s.omeg_;
[2978]116 fgring_ = s.fgring_;
[2885]117 if(s.mInfo_) this->mInfo_= new DVList(*s.mInfo_);
[979]118 // CloneOrShare(s);
[906]119}
120
[1419]121//! Clone if \b a is not temporary, share if temporary
122/*! \sa NDataBlock::CloneOrShare(const NDataBlock<T>&) */
[892]123template<class T>
124void SphereHEALPix<T>::CloneOrShare(const SphereHEALPix<T>& a)
125{
[979]126 nSide_= a.nSide_;
127 nPix_ = a.nPix_;
128 omeg_ = a.omeg_;
[2978]129 fgring_ = a.fgring_;
[892]130 pixels_.CloneOrShare(a.pixels_);
131 sliceBeginIndex_.CloneOrShare(a.sliceBeginIndex_);
132 sliceLenght_.CloneOrShare(a.sliceLenght_);
[2885]133 if (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
134 if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
[1419]135}
[979]136
[1419]137//! Share data with a
138template<class T>
139void SphereHEALPix<T>::Share(const SphereHEALPix<T>& a)
140{
141 nSide_= a.nSide_;
142 nPix_ = a.nPix_;
143 omeg_ = a.omeg_;
[2978]144 fgring_ = a.fgring_;
[1419]145 pixels_.Share(a.pixels_);
146 sliceBeginIndex_.Share(a.sliceBeginIndex_);
147 sliceLenght_.Share(a.sliceLenght_);
[2885]148 if (this->mInfo_) {delete this->mInfo_; this->mInfo_ = NULL;}
149 if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
[892]150}
151
[979]152////////////////////////// methodes de copie/share
[892]153template<class T>
154SphereHEALPix<T>& SphereHEALPix<T>::Set(const SphereHEALPix<T>& a)
[980]155{
[2978]156 if (this != &a) {
[980]157 if (a.NbPixels() < 1)
[1419]158 throw RangeCheckError("SphereHEALPix<T>::Set(a ) - SphereHEALPix a not allocated ! ");
[980]159 if (NbPixels() < 1) CloneOrShare(a);
160 else CopyElt(a);
161
[2885]162 if (this->mInfo_) delete this->mInfo_;
163 this->mInfo_ = NULL;
164 if (a.mInfo_) this->mInfo_ = new DVList(*(a.mInfo_));
[2978]165 }
[892]166 return(*this);
[980]167}
[892]168
[979]169template<class T>
170SphereHEALPix<T>& SphereHEALPix<T>::CopyElt(const SphereHEALPix<T>& a)
171{
172 if (NbPixels() < 1)
[2978]173 throw RangeCheckError("SphereHEALPix<T>::CopyElt(a) - Not Allocated SphereHEALPix ! ");
[979]174 if (NbPixels() != a.NbPixels())
[2978]175 throw(SzMismatchError("SphereHEALPix<T>::CopyElt(a) SizeMismatch")) ;
[979]176 nSide_= a.nSide_;
177 nPix_ = a.nPix_;
178 omeg_ = a.omeg_;
179 int k;
[2978]180 if (fgring_ != a.fgring_)
181 for (k=0; k< nPix_; k++) pixels_(k) = a.pixels_(k);
182 else {
183 if (fgring_) for (k=0; k< nPix_; k++)
184 pixels_(k) = a.pixels_(ring2nest(nSide_, k));
185 else for (k=0; k< nPix_; k++)
186 pixels_(k) = a.pixels_(nest2ring(nSide_, k));
187 }
[979]188 for (k=0; k< a.sliceBeginIndex_.Size(); k++) sliceBeginIndex_(k) = a.sliceBeginIndex_(k);
189 for (k=0; k< a.sliceLenght_.Size(); k++) sliceLenght_(k) = a.sliceLenght_(k);
190 return(*this);
191}
[1419]192
[843]193template<class T>
[853]194SphereHEALPix<T>::~SphereHEALPix()
[843]195{
196}
197
[1217]198/*! \fn void SOPHYA::SphereHEALPix::Resize(int_4 m)
[2960]199 \param <m> "nside" of the HEALPix algorithm
[1217]200
201 The total number of pixels will be Npix = 12*nside**2
202
203 nside MUST be a power of 2 (<= 8192)
204*/
[843]205template<class T>
[853]206void SphereHEALPix<T>::Resize(int_4 m)
[843]207{
[2960]208 if ((m <= 0 && nSide_ > 0)) {
209 cout << "SphereHEALPix<T>::Resize(m) with m<=0, NOT resized" << endl;
210 return;
[843]211 }
212 InitNul();
213 Pixelize(m);
214 SetThetaSlices();
215}
216
[2978]217
218//! return type of the map pixelisation : RING or NESTED
[843]219template<class T>
[2978]220string SphereHEALPix<T>::TypeOfMap() const
221{
222 if (fgring_) return string("RING");
223 else return string("NESTED");
224}
225
226template<class T>
[853]227void SphereHEALPix<T>::Pixelize( int_4 m)
[843]228// prépare la pixelisation Gorski (m a la même signification
229// que pour le constructeur)
230{
[2960]231 if (m<=0 || m> 8192) {
232 cout << "SphereHEALPix<T>::Pixelize() m=" << m <<" out of range [0,8192]" << endl;
233 throw ParmError("SphereHEALPix<T>::Pixelize() m out of range");
234 }
235 // verifier que m est une puissance de deux
236 int x= m;
237 while (x%2==0) x/=2;
238 if(x != 1) {
239 cout << "SphereHEALPix<T>::Pixelize() m=" << m << " != 2^n " << endl;
240 throw ParmError("SphereHEALPix<T>::Pixelize() m!=2^n");
241 }
242
[843]243 // On memorise les arguments d'appel
244 nSide_= m;
245
246 // Nombre total de pixels sur la sphere entiere
247 nPix_= 12*nSide_*nSide_;
248
249 // pour le moment les tableaux qui suivent seront ranges dans l'ordre
250 // de l'indexation GORSKY "RING"
251 // on pourra ulterieurement changer de strategie et tirer profit
252 // de la dualite d'indexation GORSKY (RING et NEST) : tout dependra
253 // de pourquoi c'est faire
254
255 // Creation et initialisation du vecteur des contenus des pixels
256 pixels_.ReSize(nPix_);
257 pixels_.Reset();
258
259 // solid angle per pixel
260 omeg_= 4.0*Pi/nPix_;
261}
262
263template<class T>
[853]264void SphereHEALPix<T>::InitNul()
[843]265//
266// initialise à zéro les variables de classe
267{
268 nSide_= 0;
269 nPix_ = 0;
270 omeg_ = 0.;
271// pixels_.Reset(); - Il ne faut pas mettre les pixels a zero si share !
272}
273
274/* --Methode-- */
[1217]275/* Nombre de pixels du decoupage */
276/*! \fn int_4 SOPHYA::SphereHEALPix::NbPixels() const
277
278 Return number of pixels of the splitting
279*/
[843]280template<class T>
[853]281int_4 SphereHEALPix<T>::NbPixels() const
[843]282{
283 return(nPix_);
284}
285
[1217]286
287/*! \fn uint_4 SOPHYA::SphereHEALPix::NbThetaSlices() const
288
289 \return number of slices in theta direction on the sphere
290*/
[843]291template<class T>
[853]292uint_4 SphereHEALPix<T>::NbThetaSlices() const
[843]293{
294 uint_4 nbslices = uint_4(4*nSide_-1);
[2978]295 if (nSide_<=0) {
296 nbslices = 0;
297 throw PException(" sphere not pixelized, NbSlice=0 ");
298 }
[843]299 return nbslices;
300}
301
[2968]302//! Return the theta angle for slice defined by \b index
303template<class T>
304r_8 SphereHEALPix<T>::ThetaOfSlice(int_4 index) const
305{
306 uint_4 nbslices = uint_4(4*nSide_-1);
307 if (index<0 || index >= nbslices)
308 throw RangeCheckError(" SphereHEALPix::ThetaOfSlice() index out of range");
309 r_8 theta, phi0;
310 PixThetaPhi(sliceBeginIndex_(index), theta, phi0);
311 return theta;
312}
313
[2973]314//! Return true : All theta slices have a symmetric slice at Pi-Theta in SphereHEALPix
315template <class T>
316bool SphereHEALPix<T>::HasSymThetaSlice() const
317{
318 return true;
319}
320//! Return the slice index for the symmetric slice at theta=Pi-ThetaOfSlice(idx)
321template <class T>
322int_4 SphereHEALPix<T>::GetSymThetaSliceIndex(int_4 idx) const
323{
324 if(idx < 0 || idx >= NbThetaSlices())
325 throw RangeCheckError("SphereHEALPix::GetSymThetaSliceIndex index out of range");
326 return (NbThetaSlices()-1-idx);
327}
328
[1217]329/*! \fn void SOPHYA::SphereHEALPix::GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const
330
331 For a theta-slice with index 'index', return :
332
333 the corresponding "theta"
334
335 a vector containing the phi's of the pixels of the slice
336
337 a vector containing the corresponding values of pixels
338*/
[843]339template<class T>
[853]340void SphereHEALPix<T>::GetThetaSlice(int_4 index,r_8& theta,TVector<r_8>& phi,TVector<T>& value) const
[843]341{
[2978]342 if (index<0 || index >= NbThetaSlices()) {
[853]343 cout << " SphereHEALPix::GetThetaSlice : Pixel index out of range" <<endl;
[2968]344 throw RangeCheckError(" SphereHEALPix::GetThetaSlice() index out of range");
[2978]345 }
[843]346
347 int_4 iring= sliceBeginIndex_(index);
348 int_4 lring = sliceLenght_(index);
349
[2978]350 phi.ReSize(lring);
351 value.ReSize(lring);
[843]352
353 double TH= 0.;
354 double FI= 0.;
[2978]355 if (fgring_) { // RING pixelisation scheme
356 for(int_4 kk = 0; kk < lring;kk++) {
[843]357 PixThetaPhi(kk+iring,TH,FI);
358 phi(kk)= FI;
[2978]359 value(kk)= pixels_(kk+iring);
[843]360 }
[2978]361 }
362 else { // NESTED pixelisation scheme
363 for(int_4 kk = 0; kk < lring;kk++) {
364 int kkn = ring2nest(nSide_, kk+iring);
365 PixThetaPhi(kkn,TH,FI);
366 phi(kk)= FI;
367 value(kk)= pixels_(kkn);
368 }
369 }
[843]370 theta= TH;
371}
[1217]372/*! \fn void SOPHYA::SphereHEALPix::GetThetaSlice(int_4 sliceIndex,r_8& theta, r_8& phi0, TVector<int_4>& pixelIndices,TVector<T>& value) const
[843]373
[1217]374 For a theta-slice with index 'index', return :
375
376 the corresponding "theta"
377
378 the corresponding "phi" for first pixel of the slice
379
380 a vector containing indices of the pixels of the slice
381
382 (equally distributed in phi)
383
384 a vector containing the corresponding values of pixels
385*/
386
[843]387template<class T>
[853]388void SphereHEALPix<T>::GetThetaSlice(int_4 sliceIndex,r_8& theta, r_8& phi0, TVector<int_4>& pixelIndices,TVector<T>& value) const
[843]389
390{
391
392 if (sliceIndex<0 || sliceIndex >= NbThetaSlices())
393 {
[853]394 cout << " SphereHEALPix::GetThetaSlice : Pixel index out of range" <<endl;
395 throw RangeCheckError(" SphereHEALPix::GetThetaSlice : Pixel index out of range");
[843]396 }
397 int_4 iring= sliceBeginIndex_(sliceIndex);
398 int_4 lring = sliceLenght_(sliceIndex);
399 pixelIndices.ReSize(lring);
400 value.ReSize(lring);
401
[2978]402 if (fgring_) { // RING pixelisation scheme
403 for(int_4 kk = 0; kk < lring;kk++) {
[843]404 pixelIndices(kk)= kk+iring;
[2978]405 value(kk)= pixels_(kk+iring);
[843]406 }
[2978]407 PixThetaPhi(iring, theta, phi0);
408 }
409 else { // NESTED pixelisation scheme
410 for(int_4 kk = 0; kk < lring;kk++) {
411 int_4 kkn = ring2nest(nSide_, kk+iring);
412 pixelIndices(kk)= kkn;
413 value(kk)= pixels_(kkn);
414 }
415 PixThetaPhi(ring2nest(nSide_,iring), theta, phi0);
416 }
[843]417}
[1217]418
[843]419template<class T>
[853]420void SphereHEALPix<T>::SetThetaSlices()
[843]421{
422 sliceBeginIndex_.ReSize(4*nSide_-1);
423 sliceLenght_.ReSize(4*nSide_-1);
[965]424 int sliceIndex;
425 for (sliceIndex=0; sliceIndex< nSide_-1; sliceIndex++)
[843]426 {
427 sliceBeginIndex_(sliceIndex) = 2*sliceIndex*(sliceIndex+1);
428 sliceLenght_(sliceIndex) = 4*(sliceIndex+1);
429 }
[965]430 for (sliceIndex= nSide_-1; sliceIndex< 3*nSide_; sliceIndex++)
[843]431 {
432 sliceBeginIndex_(sliceIndex) = 2*nSide_*(2*sliceIndex-nSide_+1);
433 sliceLenght_(sliceIndex) = 4*nSide_;
434 }
[965]435 for (sliceIndex= 3*nSide_; sliceIndex< 4*nSide_-1; sliceIndex++)
[843]436 {
437 int_4 nc= 4*nSide_-1-sliceIndex;
438 sliceBeginIndex_(sliceIndex) = nPix_-2*nc*(nc+1);
439 sliceLenght_(sliceIndex) = 4*nc;
440 }
441}
442
[1217]443
444
[2978]445//! \return value of the \b k th pixel
[843]446template<class T>
[853]447T& SphereHEALPix<T>::PixVal(int_4 k)
[843]448
449{
450 if((k < 0) || (k >= nPix_))
[2978]451 throw RangeCheckError("SphereHEALPix::PixVal() Pixel index out of range");
[843]452 return pixels_(k);
453}
454
[2978]455//! \return value of the \b k th pixel
[843]456template<class T>
[853]457T const& SphereHEALPix<T>::PixVal(int_4 k) const
[843]458
459{
460 if((k < 0) || (k >= nPix_))
[2978]461 throw RangeCheckError("SphereHEALPix::PIxVal Pixel index out of range");
[843]462 return *(pixels_.Data()+k);
463}
464
[1217]465/*! \fn T& SOPHYA::SphereHEALPix::PixValNest(int_4 k)
466
467 \return value of pixel with "NESTED" index k
[2978]468
[843]469template<class T>
[853]470T& SphereHEALPix<T>::PixValNest(int_4 k)
[843]471
472//--
473{
474 if((k < 0) || (k >= nPix_))
475 {
[853]476 throw RangeCheckError("SphereHEALPix::PIxValNest Pixel index out of range");
[843]477 }
478 return pixels_(nest2ring(nSide_,k));
479}
[2978]480*/
[1217]481/*! \fn T const& SOPHYA::SphereHEALPix::PixValNest(int_4 k) const
482
483 \return value of pixel with "NESTED" index k
484
[843]485template<class T>
[853]486T const& SphereHEALPix<T>::PixValNest(int_4 k) const
[843]487
488{
489 if((k < 0) || (k >= nPix_))
490 {
[853]491 throw RangeCheckError("SphereHEALPix::PIxValNest Pixel index out of range");
[843]492 }
493 int_4 pix= nest2ring(nSide_,k);
494 return *(pixels_.Data()+pix);
495}
[2978]496*/
[843]497
[1217]498/*! \fn bool SOPHYA::SphereHEALPix::ContainsSph(double theta, double phi) const
499
500\return true if teta,phi in map
501*/
[843]502template<class T>
[1217]503bool SphereHEALPix<T>::ContainsSph(double theta, double phi) const
[843]504{
505return(true);
506}
507
[1217]508/*! \fn int_4 SOPHYA::SphereHEALPix::PixIndexSph(double theta,double phi) const
509
510 \return "RING" index of the pixel corresponding to direction (theta, phi).
511 */
[843]512template<class T>
[853]513int_4 SphereHEALPix<T>::PixIndexSph(double theta,double phi) const
[843]514
515{
[2978]516 if (fgring_) return ang2pix_ring(nSide_,theta,phi);
517 else return ang2pix_nest(nSide_,theta,phi);
[843]518}
519
[1217]520/*! \fn int_4 SOPHYA::SphereHEALPix::PixIndexSphNest(double theta,double phi) const
521
522 \return "NESTED" index of the pixel corresponding to direction (theta, phi).
[2978]523
[843]524template<class T>
[853]525int_4 SphereHEALPix<T>::PixIndexSphNest(double theta,double phi) const
[843]526
527{
528 return ang2pix_nest(nSide_,theta,phi);
529}
[2978]530*/
[843]531
[2978]532//! \return (theta,phi) coordinates of middle of pixel with "RING" index k
[843]533template<class T>
[853]534void SphereHEALPix<T>::PixThetaPhi(int_4 k,double& theta,double& phi) const
[843]535{
[2978]536 if (fgring_) pix2ang_ring(nSide_,k,theta,phi);
537 else pix2ang_nest(nSide_,k,theta,phi);
[843]538}
539
[2978]540//! Set all pixels to value v
[843]541template <class T>
[853]542T SphereHEALPix<T>::SetPixels(T v)
[843]543{
544pixels_.Reset(v);
545return(v);
546}
547
548
[1217]549
550/*! \fn void SOPHYA::SphereHEALPix::PixThetaPhiNest(int_4 k,double& theta,double& phi) const
551
552 \return (theta,phi) coordinates of middle of pixel with "NESTED" index k
[843]553template<class T>
[853]554void SphereHEALPix<T>::PixThetaPhiNest(int_4 k,double& theta,double& phi) const
[843]555
556{
557 pix2ang_nest(nSide_,k,theta,phi);
558}
[2978]559*/
[843]560
[2978]561//! Conversion from NESTED index into RING index
[843]562template<class T>
[853]563int_4 SphereHEALPix<T>::NestToRing(int_4 k) const
[843]564{
565 return nest2ring(nSide_,k);
566}
567
[2978]568//! Conversion from RING index into NESTED index
[843]569template<class T>
[853]570int_4 SphereHEALPix<T>::RingToNest(int_4 k) const
[843]571{
572 return ring2nest(nSide_,k);
573}
574
[1419]575// ...... Operations de calcul ......
[843]576
[1419]577//! Fill a SphereHEALPix with a constant value \b a
[843]578template <class T>
[1419]579SphereHEALPix<T>& SphereHEALPix<T>::SetT(T a)
580{
581 if (NbPixels() < 1)
582 throw RangeCheckError("SphereHEALPix<T>::SetT(T ) - SphereHEALPix not dimensionned ! ");
583 pixels_ = a;
584 return (*this);
585}
586
[2978]587//! Add a constant value \b x to a SphereHEALPix
[1419]588template <class T>
589SphereHEALPix<T>& SphereHEALPix<T>::Add(T a)
590 {
[2290]591 cout << " c'est mon Add " << endl;
[1419]592 if (NbPixels() < 1)
593 throw RangeCheckError("SphereHEALPix<T>::Add(T ) - SphereHEALPix not dimensionned ! ");
[2290]594 // pixels_ += a;
595 pixels_.Add(a);
[1419]596 return (*this);
597}
598
599/*! Substract a constant value \b a to a SphereHEALPix */
600template <class T>
[1624]601SphereHEALPix<T>& SphereHEALPix<T>::Sub(T a,bool fginv)
[1419]602{
603 if (NbPixels() < 1)
604 throw RangeCheckError("SphereHEALPix<T>::Sub(T ) - SphereHEALPix not dimensionned ! ");
[1624]605 pixels_.Sub(a,fginv);
[1419]606 return (*this);
607}
608
609/*! multiply a SphereHEALPix by a constant value \b a */
610template <class T>
611SphereHEALPix<T>& SphereHEALPix<T>::Mul(T a)
612{
613 if (NbPixels() < 1)
614 throw RangeCheckError("SphereHEALPix<T>::Mul(T ) - SphereHEALPix not dimensionned ! ");
615 pixels_ *= a;
616 return (*this);
617}
618
619/*! divide a SphereHEALPix by a constant value \b a */
620template <class T>
621SphereHEALPix<T>& SphereHEALPix<T>::Div(T a)
622{
623 if (NbPixels() < 1)
624 throw RangeCheckError("SphereHEALPix<T>::Div(T ) - SphereHEALPix not dimensionned ! ");
625 pixels_ /= a;
626 return (*this);
627}
628
629// >>>> Operations avec 2nd membre de type SphereHEALPix
630//! Add two SphereHEALPix
631
632template <class T>
633SphereHEALPix<T>& SphereHEALPix<T>::AddElt(const SphereHEALPix<T>& a)
634{
635 if (NbPixels() != a.NbPixels() )
[2978]636 throw(SzMismatchError("SphereHEALPix<T>::AddElt(a) SizeMismatch")) ;
637 if (fgring_ != a.fgring_)
638 throw(ParmError("SphereHEALPix<T>::AddElt(a) different pixelisation RING<>NESTED")) ;
639
[1419]640 pixels_ += a.pixels_;
641 return (*this);
642}
643
644//! Substract two SphereHEALPix
645template <class T>
646SphereHEALPix<T>& SphereHEALPix<T>::SubElt(const SphereHEALPix<T>& a)
647{
648 if (NbPixels() != a.NbPixels() )
[2978]649 throw(SzMismatchError("SphereHEALPix<T>::SubElt(a) SizeMismatch")) ;
650 if (fgring_ != a.fgring_)
651 throw(ParmError("SphereHEALPix<T>::SubElt(a) different pixelisation RING<>NESTED")) ;
652
[1419]653 pixels_ -= a.pixels_;
654 return (*this);
655}
656
657//! Multiply two SphereHEALPix (elements by elements)
658template <class T>
659SphereHEALPix<T>& SphereHEALPix<T>::MulElt(const SphereHEALPix<T>& a)
660{
661 if (NbPixels() != a.NbPixels() )
[2978]662 throw(SzMismatchError("SphereHEALPix<T>::MulElt(a) SizeMismatch")) ;
663 if (fgring_ != a.fgring_)
664 throw(ParmError("SphereHEALPix<T>::MulElt(a) different pixelisation RING<>NESTED")) ;
665
[1419]666 pixels_ *= a.pixels_;
667 return (*this);
668}
669
[1551]670//! Divide two SphereHEALPix (elements by elements) - No protection for divide by 0
671template <class T>
672SphereHEALPix<T>& SphereHEALPix<T>::DivElt(const SphereHEALPix<T>& a)
673{
674 if (NbPixels() != a.NbPixels() )
[2978]675 throw(SzMismatchError("SphereHEALPix<T>::DivElt(a) SizeMismatch")) ;
676 if (fgring_ != a.fgring_)
677 throw(ParmError("SphereHEALPix<T>::DivElt(a) different pixelisation RING<>NESTED")) ;
[1551]678 pixels_ /= a.pixels_;
679 return (*this);
680}
[1419]681
682
683
[1551]684
[1419]685template <class T>
[853]686void SphereHEALPix<T>::print(ostream& os) const
[843]687{
[2973]688 Show(os);
[2978]689 os << "SphereHEALPix<T>(" << TypeOfMap() << ") NSide= "
690 << nSide_ << " nPix_ = " << nPix_ << " omeg_ = " << omeg_ << endl;
691
[2885]692 if(this->mInfo_) os << " DVList Info= " << *(this->mInfo_) << endl;
[2978]693 os << "... Pixel values : ";
[843]694 for(int i=0; i < nPix_; i++)
695 {
696 if(i%5 == 0) os << endl;
697 os << pixels_(i) <<", ";
698 }
699 os << endl;
700
701
702}
703
704
705
706//*******************************************************************
707
708#ifdef __CXX_PRAGMA_TEMPLATES__
[853]709#pragma define_template SphereHEALPix<uint_2>
[1304]710#pragma define_template SphereHEALPix<int_4>
[853]711#pragma define_template SphereHEALPix<r_8>
712#pragma define_template SphereHEALPix<r_4>
713#pragma define_template SphereHEALPix< complex<r_4> >
714#pragma define_template SphereHEALPix< complex<r_8> >
[843]715#endif
716#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[2869]717namespace SOPHYA {
[853]718template class SphereHEALPix<uint_2>;
[1304]719template class SphereHEALPix<int_4>;
[853]720template class SphereHEALPix<r_8>;
721template class SphereHEALPix<r_4>;
722template class SphereHEALPix< complex<r_4> >;
723template class SphereHEALPix< complex<r_8> >;
[2869]724}
[843]725#endif
726
Note: See TracBrowser for help on using the repository browser.