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

Last change on this file since 843 was 840, checked in by ansari, 25 years ago

FIO en fichiers separes

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