source: Sophya/trunk/SophyaLib/SkyMap/spherethetaphi.cc@ 947

Last change on this file since 947 was 908, checked in by ansari, 25 years ago

divers nettoyages : const. de copie, surcharge = etc.

File size: 15.3 KB
Line 
1#include "spherethetaphi.h"
2#include "smathconst.h"
3#include <complex>
4#include "piocmplx.h"
5#include "fiondblock.h"
6#include <iostream.h>
7
8
9//***************************************************************
10//++
11// Class SphereThetaPhi
12//
13//
14// include spherethetaphi.h
15//
16// sphere splitted with respect to theta, phi : each hemisphere is
17// splitted into (m-1) parallels (equator does not enter into account).
18// This operation defines m slices, each of which is splitted into
19// equidistant meridians. This splitting is realized in such a way that
20// all pixels have the same area and are as square as possible.
21
22// One begins with the hemisphere with positive z, starting from the pole
23// toward the equator. The first pixel is the polar cap ; it is circular
24// and centered on theta=0.
25//--
26//++
27//
28// Links Parents
29//
30// SphericalMap
31//--
32
33/* --Methode-- */
34//++
35// Titre Constructors
36//--
37//++
38
39template <class T>
40SphereThetaPhi<T>::SphereThetaPhi()
41
42//--
43{
44 InitNul();
45 pixels_.Reset();
46}
47
48
49/* --Methode-- */
50
51//++
52template <class T>
53SphereThetaPhi<T>::SphereThetaPhi(int_4 m)
54
55// m is the number of slices in theta on an hemisphere (the polar cap
56// forms the first slice).
57// pet is a dummy parameter at the moment.
58//--
59{
60 InitNul();
61 Pixelize(m);
62}
63
64template <class T>
65SphereThetaPhi<T>::SphereThetaPhi(const SphereThetaPhi<T>& s, bool share)
66 : NPhi_(s.NPhi_, share), TNphi_(s.TNphi_, share), Theta_(s.Theta_, share),
67 pixels_(s.pixels_ , share)
68{
69 if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
70
71 NTheta_= s.NTheta_;
72 NPix_ = s.NPix_;
73 Omega_ = s.Omega_;
74}
75
76template <class T>
77SphereThetaPhi<T>::SphereThetaPhi(const SphereThetaPhi<T>& s)
78 : NPhi_(s.NPhi_), TNphi_(s.TNphi_), Theta_(s.Theta_), pixels_(s.pixels_)
79{
80 if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
81
82 NTheta_= s.NTheta_;
83 NPix_ = s.NPix_;
84 Omega_ = s.Omega_;
85}
86
87//++
88// Titre Destructor
89//--
90//++
91template <class T>
92SphereThetaPhi<T>::~SphereThetaPhi()
93
94//--
95{}
96
97//++
98// Titre Public Méthods
99//--
100template <class T>
101void SphereThetaPhi<T>::InitNul()
102//
103{
104 NTheta_= 0;
105 NPix_ = 0;
106// pixels_.Reset(); Pas de reset par InitNul (en cas de share) - Reza 20/11/99 $CHECK$
107}
108
109
110//++
111template <class T>
112void SphereThetaPhi<T>::Resize(int_4 m)
113// re-pixelize the sphere
114//--
115{
116 InitNul();
117 Pixelize(m);
118}
119
120template<class T>
121void SphereThetaPhi<T>::CloneOrShare(const SphereThetaPhi<T>& a)
122{
123
124 NPhi_.CloneOrShare(a.NPhi_);
125 TNphi_.CloneOrShare(a.TNphi_);
126 Theta_.CloneOrShare(a.Theta_);
127 pixels_.CloneOrShare(a.pixels_);
128}
129
130template<class T>
131SphereThetaPhi<T>& SphereThetaPhi<T>::Set(const SphereThetaPhi<T>& a)
132 {
133 if (this != &a)
134 {
135
136
137 NTheta_= a.NTheta_;
138 NPix_ = a.NPix_;
139 Omega_ = a.Omega_;
140 CloneOrShare(a);
141 if (mInfo_) delete mInfo_;
142 mInfo_ = NULL;
143 if (a.mInfo_) mInfo_ = new DVList(*(a.mInfo_));
144 }
145 return(*this);
146 }
147
148
149
150/* --Methode-- */
151//++
152template <class T>
153int_4 SphereThetaPhi<T>::NbPixels() const
154
155// Return total number of pixels
156//--
157{
158 return(NPix_);
159}
160
161/* --Methode-- */
162//++
163template <class T>
164T& SphereThetaPhi<T>::PixVal(int_4 k)
165
166// Return value of pixel with index k
167//--
168{
169 if((k < 0) || (k >= NPix_))
170 {
171 throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
172 }
173 return pixels_(k);
174}
175
176//++
177template <class T>
178T const& SphereThetaPhi<T>::PixVal(int_4 k) const
179
180// Return value of pixel with index k
181//--
182{
183 if((k < 0) || (k >= NPix_))
184 {
185 throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
186 }
187 return *(pixels_.Data()+k);
188}
189
190/* --Methode-- */
191//++
192template <class T>
193bool SphereThetaPhi<T>::ContainsSph(double /*theta*/, double /*phi*/) const
194//--
195{
196 return(true);
197}
198
199/* --Methode-- */
200//++
201template <class T>
202int_4 SphereThetaPhi<T>::PixIndexSph(double theta, double phi) const
203
204// Return index of the pixel corresponding to
205// direction (theta, phi).
206//--
207{
208 double dphi;
209 int i,k;
210 bool fgzn = false;
211
212 if((theta > Pi) || (theta < 0.)) return(-1);
213 if((phi < 0.) || (phi > DeuxPi)) return(-1);
214 if(theta > Pi*0.5) {fgzn = true; theta = Pi-theta;}
215
216 // La bande d'indice kt est limitée par les valeurs de theta contenues dans
217 // Theta_[kt] et Theta_[kt+1]
218 for( i=1; i< NTheta_; i++ )
219 if( theta < Theta_(i) ) break;
220
221 dphi= DeuxPi/(double)NPhi_(i-1);
222
223 if (fgzn) k= NPix_-TNphi_(i)+(int_4)(phi/dphi);
224 else k= TNphi_(i-1)+(int_4)(phi/dphi);
225 return(k);
226}
227
228/* --Methode-- */
229//++
230template <class T>
231void SphereThetaPhi<T>::PixThetaPhi(int_4 k,double& theta,double& phi) const
232
233// Return (theta,phi) coordinates of middle of pixel with index k
234//--
235{
236 int i;
237 bool fgzn = false;
238
239 if((k < 0) || (k >= NPix_)) {theta = -99999.; phi = -99999.; return; }
240 if( k >= NPix_/2) {fgzn = true; k = NPix_-1-k;}
241
242 // recupère l'indice i de la tranche qui contient le pixel k
243 for( i=0; i< NTheta_; i++ )
244 if( k < TNphi_(i+1) ) break;
245
246 // angle theta
247 theta= 0.5*(Theta_(i)+Theta_(i+1));
248 if (fgzn) theta= Pi-theta;
249
250 // angle phi
251 k -= TNphi_(i);
252 phi= DeuxPi/(double)NPhi_(i)*(double)(k+.5);
253 if (fgzn) phi= DeuxPi-phi;
254}
255
256template <class T>
257T SphereThetaPhi<T>::SetPixels(T v)
258{
259pixels_.Reset(v);
260return(v);
261}
262
263//++
264template <class T>
265double SphereThetaPhi<T>::PixSolAngle(int_4 /*dummy*/) const
266
267// Pixel Solid angle (steradians)
268// All the pixels have the same solid angle. The dummy argument is
269// for compatibility with eventual pixelizations which would not
270// fulfil this requirement.
271//--
272{
273 return Omega_;
274}
275
276/* --Methode-- */
277//++
278template <class T>
279void SphereThetaPhi<T>::Limits(int_4 k,double& tetMin,double& tetMax,double& phiMin,double& phiMax)
280
281// Return values of theta,phi which limit the pixel with index k
282//--
283 {
284 int j;
285 double dphi;
286 bool fgzn= false;
287
288 if((k < 0) || (k >= NPix_)) {
289 tetMin= -99999.;
290 phiMin= -99999.;
291 tetMax= -99999.;
292 phiMax= -99999.;
293 return;
294 }
295
296 // si on se trouve dans l'hémisphère Sud
297 if(k >= NPix_/2) {
298 fgzn= true;
299 k= NPix_-1-k;
300 }
301
302 // on recupere l'indice i de la tranche qui contient le pixel k
303 int i;
304 for( i=0; i< NTheta_; i++ )
305 if(k < TNphi_(i+1)) break;
306
307 // valeurs limites de theta dans l'hemisphere Nord
308 tetMin= Theta_(i);
309 tetMax= Theta_(i+1);
310 // valeurs limites de theta dans l'hemisphere Sud
311 if (fgzn) {
312 tetMin= Pi - Theta_(i+1);
313 tetMax= Pi - Theta_(i);
314 }
315
316 // pixel correspondant dans l'hemisphere Nord
317 if (fgzn) k= TNphi_(i+1)-k+TNphi_(i)-1;
318
319 // indice j de discretisation ( phi= j*dphi )
320 j= k-TNphi_(i);
321 dphi= DeuxPi/(double)NPhi_(i);
322
323 // valeurs limites de phi
324 phiMin= dphi*(double)(j);
325 phiMax= dphi*(double)(j+1);
326 return;
327}
328
329/* --Methode-- */
330//++
331template <class T>
332uint_4 SphereThetaPhi<T>::NbThetaSlices() const
333
334// Return number of theta-slices on the sphere
335//--
336{
337 if (NTheta_<=0)
338 {
339 throw PException(" sphere not pixelized, NbSlice=0 ");
340 }
341 return( 2*NTheta_);
342}
343
344/* --Methode-- */
345//++
346template <class T>
347int_4 SphereThetaPhi<T>::NPhi(int_4 kt) const
348
349// Return number of pixels in phi-direction of the kt-th slice
350//--
351{
352 int nbpix;
353 // verification
354 if((kt < 0) || (kt >= 2*NTheta_)) return(-1);
355
356 // si on se trouve dans l'hemisphere Sud
357 if(kt >= NTheta_) {
358 kt= 2*NTheta_-1-kt;
359 }
360
361 // nombre de pixels
362 nbpix= NPhi_(kt);
363 return(nbpix);
364}
365
366
367/* --Methode-- */
368//++
369template <class T>
370void SphereThetaPhi<T>::Theta(int_4 kt,double& tetMin,double& tetMax)
371
372// Return theta values which limit the slice kt
373//--
374{
375 bool fgzn= false;
376 // verification
377 if( (kt< 0) || (kt>= 2*NTheta_) ) {
378 tetMin= -99999.;
379 tetMax= -99999.;
380 return;
381 }
382
383 // si on se trouve dans l'hemisphere Sud
384 if( kt >= NTheta_ ) {
385 fgzn= true;
386 kt= 2*NTheta_-1-kt;
387 }
388
389 // valeurs limites de theta dans l'hemisphere Nord
390 tetMin= Theta_(kt);
391 tetMax= Theta_(kt+1);
392 // valeurs limites de theta dans l'hemisphere Sud
393 if (fgzn) {
394 tetMin= Pi - Theta_(kt+1);
395 tetMax= Pi - Theta_(kt);
396 }
397}
398
399/* --Methode-- */
400//++
401template <class T>
402void SphereThetaPhi<T>::Phi(int_4 kt,int_4 jp,double& phiMin,double& phiMax)
403
404// Return values of phi which limit the jp-th pixel of the kt-th slice
405//--
406{
407 // verification
408 if((kt < 0) || (kt >= 2*NTheta_)) {
409 phiMin= -99999.;
410 phiMax= -99999.;
411 return;
412 }
413
414 // si on se trouve dans l'hemisphere Sud
415 if(kt >= NTheta_) kt= 2*NTheta_-1-kt;
416
417 // verifie si la tranche kt contient au moins jp pixels
418 if( (jp< 0) || (jp >= NPhi_(kt)) ) {
419 phiMin= -88888.;
420 phiMax= -88888.;
421 return;
422 }
423
424 double dphi= DeuxPi/(double)NPhi_(kt);
425 phiMin= dphi*(double)(jp);
426 phiMax= dphi*(double)(jp+1);
427 return;
428}
429
430/* --Methode-- */
431//++
432template <class T>
433int_4 SphereThetaPhi<T>::Index(int_4 kt,int_4 jp) const
434
435// Return pixel index with sequence index jp in the slice kt
436//--
437{
438 int k;
439 bool fgzn= false;
440
441 // si on se trouve dans l'hemisphere Sud
442 if(kt >= NTheta_) {
443 fgzn= true;
444 kt= 2*NTheta_-1-kt;
445 }
446
447 // si la tranche kt contient au moins i pixels
448 if( (jp>=0) && (jp<NPhi_(kt)) )
449 {
450 // dans l'hemisphere Sud
451 if (fgzn) k= NPix_-TNphi_(kt+1)+jp;
452 // dans l'hemisphere Nord
453 else k= TNphi_(kt)+jp;
454 }
455 else
456 {
457 k= 9999;
458 printf("\n la tranche %d ne contient pas un pixel de rang %d",kt,jp);
459 }
460 return(k);
461}
462
463/* --Methode-- */
464//++
465template <class T>
466void SphereThetaPhi<T>::ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp)
467
468// Return indices kt (theta) and jp (phi) of pixel with index k
469//--
470{
471 bool fgzn= false;
472 // si on se trouve dans l'hemisphere Sud
473 if(k >= NPix_/2)
474 {
475 fgzn= true;
476 k= NPix_-1-k;
477 }
478
479 // on recupere l'indice kt de la tranche qui contient le pixel k
480 int i;
481 for(i = 0; i < NTheta_; i++)
482 if(k < TNphi_(i+1)) break;
483
484 // indice kt de tranche
485 if (fgzn) kt= 2*NTheta_-1-i;
486 else kt= i;
487
488 // indice jp de pixel
489 if (fgzn) jp= TNphi_(i+1)-k-1;
490 else jp= k-TNphi_(i);
491}
492//++
493template <class T>
494void SphereThetaPhi<T>::Pixelize(int_4 m)
495
496// achieve the splitting into pixels (m has the same signification
497// as for the constructor)
498//
499// Each theta-slice of the north hemisphere will be spitted starting f
500// from phi=0 ...
501//
502// South hemisphere is scanned in the same direction according to phi
503// and from equator to the pole (the pixel following the last one of
504// the slice closest to the equator with z>0, is the pixel with lowest
505// phi of the slice closest of the equator with z<0).
506//--
507{
508 int ntotpix,j;
509
510 // Decodage et controle des arguments d'appel :
511 // au moins 2 et au plus 16384 bandes d'un hemisphere en theta
512 if (m < 2) m = 2;
513 if (m > 16384) m = 16384;
514
515 // On memorise les arguments d'appel
516 NTheta_ = m;
517
518 // On commence par decouper l'hemisphere z>0.
519 // Creation des vecteurs contenant :
520 // Les valeurs limites de theta (une valeur de plus que le nombre de bandes...)
521 // Theta_= new double[m+1];
522 Theta_.ReSize(m+1);
523
524 // Le nombre de pixels en phi de chacune des bandes en theta
525 // NPhi_ = new int_4[m];
526 NPhi_.ReSize(m);
527
528 // Le nombre/Deuxpi total des pixels contenus dans les bandes de z superieur a une
529 // bande donnee (mTPphi[m] contient le nombre de pixels total de l'hemisphere)
530 // TNphi_= new int_4[m+1];
531 TNphi_.ReSize(m+1);
532
533 // Calcul du nombre total de pixels dans chaque bande pour optimiser
534 // le rapport largeur/hauteur des pixels
535
536 //calotte polaire
537 TNphi_(0)= 0;
538 NPhi_(0) = 1;
539
540 //bandes jusqu'a l'equateur
541 for(j = 1; j < m; j++)
542 {
543 TNphi_(j)= TNphi_(j-1)+NPhi_(j-1);
544 NPhi_(j) = (int_4)(.5+4.*(double)(m-.5)*sin(Pi*(double)j/(double)(2.*m-1.))) ;
545 }
546
547 // Nombre total de pixels sur l'hemisphere
548 ntotpix = TNphi_(m-1)+NPhi_(m-1);
549 TNphi_(m)= ntotpix;
550 // et sur la sphere entiere
551 NPix_= 2*ntotpix;
552
553 // Creation et initialisation du vecteur des contenus des pixels
554 pixels_.ReSize(NPix_);
555 pixels_.Reset();
556
557 // Determination des limites des bandes en theta :
558 // omeg est l'angle solide couvert par chaque pixel,
559 // une bande donnee kt couvre un angle solide NPhi_[kt]*omeg
560 // egal a 2* Pi*(cos Theta_[kt]-cos Theta_[kt+1]). De meme, l'angle solide
561 //de la
562 // calotte allant du pole a la limite haute de la bande kt vaut
563 // 2* Pi*(1.-cos Theta_[kt+1])= TNphi_[kt]*omeg...
564
565 double omeg2pi= 1./(double)ntotpix;
566 Omega_ = omeg2pi*DeuxPi;
567
568 for(j=0; j <= m; j++)
569 {
570 Theta_(j)= acos(1.-(double)TNphi_(j)*omeg2pi);
571 }
572}
573
574//++
575template <class T>
576void SphereThetaPhi<T>::GetThetaSlice(int_4 index,r_8& theta, TVector<r_8>& phi, TVector<T>& value) const
577
578// For a theta-slice with index 'index', return :
579// the corresponding "theta"
580// a vector containing the phi's of the pixels of the slice
581// a vector containing the corresponding values of pixels
582//--
583
584{
585
586 if(index < 0 || index >= NbThetaSlices())
587 {
588 throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
589 }
590
591 int iring= Index(index,0);
592 int lring = NPhi(index);
593
594 phi.ReSize(lring);
595 value.ReSize(lring);
596 double Te= 0.;
597 double Fi= 0.;
598 for(int kk = 0; kk < lring; kk++)
599 {
600 PixThetaPhi(kk+iring,Te,Fi);
601 phi(kk)= Fi;
602 value(kk)= PixVal(kk+iring);
603 }
604 theta= Te;
605}
606
607//++
608template <class T>
609void SphereThetaPhi<T>::GetThetaSlice(int_4 index,r_8& theta, r_8& phi0,TVector<int_4>& pixelIndices, TVector<T>& value) const
610
611// For a theta-slice with index 'index', return :
612// the corresponding "theta"
613// the corresponding "phi" for first pixel of the slice
614// a vector containing the indices of the pixels of the slice
615// (equally distributed in phi)
616// a vector containing the corresponding values of pixels
617//--
618
619{
620
621 if(index < 0 || index >= NbThetaSlices())
622 {
623 throw RangeCheckError("SphereThetaPhi::PIxVal Pixel index out of range");
624
625 }
626
627 int iring= Index(index,0);
628 int lring = NPhi(index);
629
630 pixelIndices.ReSize(lring);
631 value.ReSize(lring);
632 double Te= 0.;
633 double Fi= 0.;
634 for(int kk = 0; kk < lring; kk++)
635 {
636 pixelIndices(kk)=kk+iring ;
637 value(kk)= PixVal(kk+iring);
638 }
639 PixThetaPhi(iring,theta,phi0);
640}
641
642
643
644
645template <class T>
646void SphereThetaPhi<T>::print(ostream& os) const
647{
648 if(mInfo_) os << " DVList Info= " << *mInfo_ << endl;
649 //
650 os << " NTheta_= " << NTheta_ << endl;
651 os << " NPix_ = " << NPix_ << endl;
652 os << " Omega_ = " << Omega_ << endl;
653
654 os << " contenu de NPhi_ : ";
655 int i;
656 for(i=0; i < NTheta_; i++)
657 {
658 if(i%5 == 0) os << endl;
659 os << NPhi_(i) <<", ";
660 }
661 os << endl;
662
663 os << " contenu de Theta_ : ";
664 for(i=0; i < NTheta_+1; i++)
665 {
666 if(i%5 == 0) os << endl;
667 os << Theta_(i) <<", ";
668 }
669 os << endl;
670
671 os << " contenu de TNphi_ : ";
672 for(i=0; i < NTheta_+1; i++)
673 {
674 if(i%5 == 0) os << endl;
675 os << TNphi_(i) <<", ";
676 }
677 os << endl;
678
679 os << " contenu de pixels : ";
680 for(i=0; i < NPix_; i++)
681 {
682 if(i%5 == 0) os << endl;
683 os << pixels_(i) <<", ";
684 }
685 os << endl;
686}
687
688
689#ifdef __CXX_PRAGMA_TEMPLATES__
690#pragma define_template SphereThetaPhi<r_8>
691#pragma define_template SphereThetaPhi<r_4>
692#pragma define_template SphereThetaPhi< complex<r_4> >
693#pragma define_template SphereThetaPhi< complex<r_8> >
694#endif
695#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
696template class SphereThetaPhi<r_8>;
697template class SphereThetaPhi<r_4>;
698template class SphereThetaPhi< complex<r_4> >;
699template class SphereThetaPhi< complex<r_8> >;
700#endif
Note: See TracBrowser for help on using the repository browser.