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

Last change on this file since 4039 was 3836, checked in by ansari, 15 years ago

Declaration extern des classes templ des classes template avec instantiation explicite (avec flag NEED_EXT_DECL_TEMP) pour regler le pb de dynamic_cast sur Mac OS X 10.6, Reza 05/08/2010

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