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

Last change on this file since 2885 was 2885, checked in by ansari, 20 years ago

Modifs (ajout this->) pour compilation avec g++ 4 (V >= 3.4) - Reza 4 Jan 2006

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