source: Sophya/trunk/SophyaLib/Samba/spherethetaphi.cc@ 372

Last change on this file since 372 was 276, checked in by ansari, 26 years ago

Adaptation nouveau schema PPersist pour DVList Reza 28/04/99

File size: 14.2 KB
RevLine 
[228]1//
2//
3#include "spherethetaphi.h"
4#include "nbmath.h"
5#include <iostream.h>
6//***************************************************************
7//++
8// Class SphereThetaPhi
9//
10//
11// include spherethetaphi.h nbmath.h
12//
13// Découpage de la sphère selon theta et phi, chaque
14// hémisphère étant découpé en (m-1) parallèles (l'équateur compte pour du
15// beurre), chacune des m bandes de theta ainsi définies étant découpée par
16// des méridiens équirepartis, ce découpage étant fait de sorte que tous
17// les pixels aient la même surface et soient le plus carré possible.
18// On commence par découper l'hémisphère de z positif en partant du pôle et
19// en allant vers l'équateur. Le premier pixel est la calotte polaire,
20// il est circulaire et centré sur theta=0.
21//--
22//++
23//
24// Links Parents
25//
26// SphericalMap
27//--
28//++
29//
30// Links Descendants
31//
32//
33//--
34
35/* --Methode-- */
36//++
37// Titre Constructeurs
38//--
39//++
40
41
42SphereThetaPhi::SphereThetaPhi()
43
44//--
45{
46 InitNul();
47}
48
49/* --Methode-- */
50//++
51SphereThetaPhi::SphereThetaPhi(char* flnm)
52
53// Constructeur : charge une image à partir d'un fichier
54//--
55{
56 InitNul();
57 PInPersist s(flnm);
58 Read(s);
59}
60
61/* --Methode-- */
62
63//++
64SphereThetaPhi::SphereThetaPhi(int_4 m, int_4 pet)
65
66// Constructeur : m est le nombre de bandes en theta sur un hémisphère
67// (la calotte constituant la premiere bande).
68// pet est le nombre de pixels (pétales) de la bande en contact avec la
69// calotte polaire. Pour l'instant pet est inopérant!
70//--
71{
72 InitNul();
73 Pixelize(m,pet);
74}
75
76
77//++
78// Titre Destructeur
79//--
80//++
81SphereThetaPhi::~SphereThetaPhi()
82
83//--
84{
85 Clear();
86}
87
88//++
89// Titre Méthodes
90//--
91void SphereThetaPhi::InitNul()
92//
93// initialise à zéro les variables de classe pointeurs
94{
95 mTheta = NULL;
96 mNphi = NULL;
97 mTNphi = NULL;
98 // mPix = NULL;
99 _pixel=NULL;
100 mNTheta = mNPet = 0;
101 mNPix = 0;
102}
103
104/* --Methode-- */
105void SphereThetaPhi::Clear()
106
107{
108 if (mTheta) delete[] mTheta;
109 if (mNphi) delete[] mNphi;
110 if (mTNphi) delete[] mTNphi;
111 //if (mPix) delete[] mPix;
112 if (_pixel) _pixel->Detach();
113 mTheta = NULL;
114 mNphi = NULL;
115 mTNphi = NULL;
116 //mPix = NULL;
117 _pixel=NULL;
118 mNTheta = mNPet = 0;
119 mNPix = 0;
120}
121
122/* --Methode-- */
123//++
124void SphereThetaPhi::WriteSelf(POutPersist& s) const
125
126// créer un fichier image
127//--
128{
129 char strg[256];
130 if (mInfo_) {sprintf(strg, "SphereThetaPhi: NSlices=%6d NPix=%9d HasInfo", (int_4)mNTheta, (int_4)mNPix);
131 }
132 else { sprintf(strg, "SphereThetaPhi: NSlices=%6d NPix=%9d ",
133 (int_4)mNTheta, (int_4)mNPix);
134 }
135 s.PutLine(strg);
[276]136 if (mInfo_) s << (*mInfo_);
137 s.PutI4(mNTheta);
[228]138 s.PutI4(mNPet);
139 s.PutI4(mNPix);
140 s.PutR8(mOmeg);
141 s.PutR4s(mTheta, mNTheta+1);
142 s.PutI4s(mNphi, mNTheta);
143 s.PutI4s(mTNphi, mNTheta+1);
144 s.PutR8s(_pixel->Data(), mNPix);
145 //s.PutR8s(mPix, mNPix);
146 return;
147}
148
149/* --Methode-- */
150//++
151void SphereThetaPhi::ReadSelf(PInPersist& s)
152
153// relit un fichier d'image
154//--
155{
156 Clear();
157 char strg[256];
158 s.GetLine(strg, 255);
159// Pour savoir s'il y avait un DVList Info associe
160 bool hadinfo = false;
161 if (strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0) hadinfo = true;
162 if (hadinfo) { // Lecture eventuelle du DVList Info
163 if (mInfo_ == NULL) mInfo_ = new DVList;
[276]164 s >> (*mInfo_);
[228]165 }
166 s.GetI4(mNTheta);
167 s.GetI4(mNPet);
168 s.GetI4(mNPix);
169 s.GetR8(mOmeg);
170 mTheta = new r_4[mNTheta+1];
171 mNphi = new int_4[mNTheta];
172 mTNphi = new int_4[mNTheta+1];
173 //mPix = new r_8[mNPix+1];
174 _pixel=new PDataArray<r_8>(mNPix,true);
175 s.GetR4s(mTheta, mNTheta+1);
176 s.GetI4s(mNphi, mNTheta);
177 s.GetI4s(mTNphi, mNTheta+1);
178 s.GetR8s(_pixel->Data(), mNPix);
179 //s.GetR8s(mPix, mNPix);
180 return;
181}
182
183
184/* --Methode-- */
185//++
186int_4 SphereThetaPhi::NbPixels() const
187
188// Retourne le nombre de pixels du découpage
189//--
190{
191 return(mNPix);
192}
193
194
195static r_8 dummy_pixel = 0;
196
197/* --Methode-- */
198//++
199r_8& SphereThetaPhi::PixVal(int_4 k)
200
201// Retourne la valeur du contenu du pixel d'indice k
202//--
203{
204 if ( (k<0) || (k >= mNPix) ) {
205 // THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
206 cout << " SphereThetaPhi::PIxVal : exceptions a mettre en place" <<endl;
207 THROW(rangeCheckErr);
208
209 //throw "SphereThetaPhi::PIxVal Pixel index out of range";
210 }
211 return (*(_pixel->Data()+k));
212 //return(mPix[k]);
213}
214//++
215r_8 const& SphereThetaPhi::PixVal(int_4 k) const
216
217// Retourne la valeur du contenu du pixel d'indice k
218//--
219{
220 if ( (k<0) || (k >= mNPix) ) {
221 cout << " SphereThetaPhi::PIxVal : exceptions a mettre en place" <<endl;
222 // THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
223
224 throw "SphereThetaPhi::PIxVal Pixel index out of range";
225 }
226 return *(_pixel->Data()+k);
227 //return(mPix[k]);
228}
229
230
231/* --Methode-- */
232//++
233int_4 SphereThetaPhi::PixIndexSph(r_4 theta, r_4 phi) const
234
235// Retourne l'indice du pixel vers lequel pointe une direction définie par
236// ses coordonnées sphériques
237//--
238{
239 r_4 dphi;
240 int_4 i,j,k;
241 bool fgzn = false;
242
243 if( (theta > (r_4)Pi) || (theta < 0. ) ) return(-1);
244 if( (phi < 0.) || (phi > DeuxPi) ) return(-1);
245 if( theta > (r_4)Pi*0.5) { fgzn = true; theta = Pi-theta; }
246
247 // La bande d'indice kt est limitée par les valeurs de theta contenues dans
248 // mTheta[kt] et mTheta[kt+1]
249 for( i=1; i< mNTheta; i++ )
250 if( theta < mTheta[i] ) break;
251
252 dphi= (r_4)DeuxPi/(r_4)mNphi[i-1];
253
254 if (fgzn) k= mNPix-mTNphi[i]+(int_4)(phi/dphi);
255 else k= mTNphi[i-1]+(int_4)(phi/dphi);
256
257 return(k);
258}
259
260
261/* --Methode-- */
262//++
263void SphereThetaPhi::PixThetaPhi(int_4 k, r_4& theta, r_4& phi) const
264
265// Retourne les coordonnées (theta,phi) du milieu du pixel d'indice k
266//--
267{
268 int_4 i;
269 bool fgzn = false;
270
271 if( (k < 0) || (k >= mNPix) ) {theta = -99999.; phi = -99999.; return; }
272 if( k >= mNPix/2) {fgzn = true; k = mNPix-1-k; }
273
274 // recupère l'indice i de la tranche qui contient le pixel k
275 for( i=0; i< mNTheta; i++ )
276 if( k < mTNphi[i+1] ) break;
277
278 // angle theta
279 theta= 0.5*(mTheta[i]+mTheta[i+1]);
280 if (fgzn) theta= Pi-theta;
281
282 // angle phi
283 k -= mTNphi[i];
284 phi= (r_4)DeuxPi/(r_4)mNphi[i]*(r_4)(k+.5);
285 if (fgzn) phi= DeuxPi-phi;
286
287 return;
288}
289
290
291//++
292r_8 SphereThetaPhi::PixSolAngle(int_4 dummy) const
293// Pixel Solid angle (steradians)
294// All the pixels have the same solid angle. The dummy argument is
295// for compatibility with eventual pixelizations which would not
296// fulfil this requirement.
297//--
298{
299 return mOmeg;
300}
301
302
303/* --Methode-- */
304//++
305void SphereThetaPhi::Limits(int_4 k, r_4& tetMin, r_4& tetMax,
306 r_4& phiMin, r_4& phiMax)
307
308// Retourne les valeurs de theta et phi limitant le pixel d'indice k
309//--
310 {
311 int_4 j;
312 r_4 dphi;
313 bool fgzn= false;
314
315 if( (k< 0) || (k >= mNPix) ) {
316 tetMin= -99999.;
317 phiMin= -99999.;
318 tetMax= -99999.;
319 phiMax= -99999.;
320 return;
321 }
322
323 // si on se trouve dans l'hémisphère Sud
324 if( k >= mNPix/2 ) {
325 fgzn= true;
326 k= mNPix-1-k;
327 }
328
329 // on recupere l'indice i de la tranche qui contient le pixel k
330 int i;
331 for( i=0; i< mNTheta; i++ )
332 if( k< mTNphi[i+1] ) break;
333
334 // valeurs limites de theta dans l'hemisphere Nord
335 tetMin= mTheta[i];
336 tetMax= mTheta[i+1];
337 // valeurs limites de theta dans l'hemisphere Sud
338 if (fgzn) {
339 tetMin= Pi-mTheta[i+1];
340 tetMax= Pi-mTheta[i];
341 }
342
343 // pixel correspondant dans l'hemisphere Nord
344 if (fgzn) k= mTNphi[i+1]-k+mTNphi[i]-1;
345
346 // indice j de discretisation ( phi= j*dphi )
347 j= k-mTNphi[i];
348 dphi= (r_4)DeuxPi/(r_4)mNphi[i];
349
350 // valeurs limites de phi
351 phiMin= dphi*(r_4)(j);
352 phiMax= dphi*(r_4)(j+1);
353 return;
354}
355
356/* --Methode-- */
357//++
358int_4 SphereThetaPhi::NbThetaSlices() const
359
360// Retourne le nombre de tranches en theta sur la sphere
361//--
362{
363 int_4 nbslices;
364 nbslices= 2*mNTheta;
365 return(nbslices);
366}
367
368/* --Methode-- */
369//++
370int_4 SphereThetaPhi::NPhi(int_4 kt) const
371
372// Retourne le nombre de pixels en phi de la tranche kt
373//--
374{
375
376 int_4 nbpix;
377
378 // verification
379 if( (kt< 0) || (kt>= 2*mNTheta) ) return(-1);
380
381 // si on se trouve dans l'hemisphere Sud
382 if( kt >= mNTheta ) {
383 kt= 2*mNTheta-1-kt;
384 }
385
386 // nombre de pixels
387 nbpix= mNphi[kt];
388 return(nbpix);
389}
390
391
392/* --Methode-- */
393//++
394void SphereThetaPhi::Theta(int_4 kt,r_4& tetMin,r_4& tetMax)
395
396// Retourne les valeurs de theta limitant la tranche kt
397//--
398{
399
400 bool fgzn= false;
401
402 // verification
403 if( (kt< 0) || (kt>= 2*mNTheta) ) {
404 tetMin= -99999.;
405 tetMax= -99999.;
406 return;
407 }
408
409 // si on se trouve dans l'hemisphere Sud
410 if( kt >= mNTheta ) {
411 fgzn= true;
412 kt= 2*mNTheta-1-kt;
413 }
414
415 // valeurs limites de theta dans l'hemisphere Nord
416 tetMin= mTheta[kt];
417 tetMax= mTheta[kt+1];
418 // valeurs limites de theta dans l'hemisphere Sud
419 if (fgzn) {
420 tetMin= Pi-mTheta[kt+1];
421 tetMax= Pi-mTheta[kt];
422 }
423}
424
425/* --Methode-- */
426//++
427void SphereThetaPhi::Phi(int_4 kt,int_4 jp,r_4& phiMin,r_4& phiMax)
428
429// Retourne les valeurs de phi limitant le pixel jp de la tranche kt
430//--
431{
432
433 r_4 dphi;
434
435 // verification
436 if( (kt< 0) || (kt>= 2*mNTheta) ) {
437 phiMin= -99999.;
438 phiMax= -99999.;
439 return;
440 }
441
442 // si on se trouve dans l'hemisphere Sud
443 if( kt >= mNTheta ) kt= 2*mNTheta-1-kt;
444
445 // verifie si la tranche kt contient au moins jp pixels
446 if( (jp< 0) || (jp >= mNphi[kt]) ) {
447 phiMin= -88888.;
448 phiMax= -88888.;
449 return;
450 }
451
452 dphi= (r_4)DeuxPi/(r_4)mNphi[kt];
453 phiMin= dphi*(r_4)(jp);
454 phiMax= dphi*(r_4)(jp+1);
455 return;
456}
457
458/* --Methode-- */
459//++
460int_4 SphereThetaPhi::Index(int_4 kt,int_4 jp) const
461
462// Retourne l'indice du pixel d'indice jp dans la tranche kt
463//--
464{
465
466 int_4 k;
467 bool fgzn= false;
468
469 // si on se trouve dans l'hemisphere Sud
470 if( kt >= mNTheta ) {
471 fgzn= true;
472 kt= 2*mNTheta-1-kt;
473 }
474
475 // si la tranche kt contient au moins i pixels
476 if( (jp>=0) && (jp<mNphi[kt]) ) {
477 // dans l'hemisphere Sud
478 if (fgzn) k= mNPix-mTNphi[kt+1]+jp;
479 // dans l'hemisphere Nord
480 else k= mTNphi[kt]+jp;
481 }
482 else{
483 k= 9999;
484 printf("\n la tranche %d ne contient pas un pixel de rang %d",kt,jp);
485 }
486 return(k);
487}
488
489/* --Methode-- */
490//++
491void SphereThetaPhi::ThetaPhiIndex(int_4 k,int_4& kt,int_4& jp)
492
493// Retourne les indices kt et jp du pixel d'indice k
494//--
495{
496
497 bool fgzn= false;
498
499 // si on se trouve dans l'hemisphere Sud
500 if( k >= mNPix/2 ) {
501 fgzn= true;
502 k= mNPix-1-k;
503 }
504
505 // on recupere l'indice kt de la tranche qui contient le pixel k
506 int i;
507 for( i=0; i< mNTheta; i++ )
508 if( k< mTNphi[i+1] ) break;
509
510 // indice kt de tranche
511 if (fgzn) kt= 2*mNTheta-1-i;
512 else kt= i;
513
514 // indice jp de pixel
515 if (fgzn) jp= mTNphi[i+1]-k-1;
516 else jp= k-mTNphi[i];
517
518}
519//++
520void SphereThetaPhi::Pixelize( int_4 m, int_4 pet)
521
522// effectue le découpage en pixels (m et pet ont la même signification
523// que pour le constructeur)
524//
525// Chaque bande de theta sera découpée en partant de phi=0 ...
526// L'autre hémisphère est parcourue dans le même sens en phi et de
527// l'équateur vers le pôle (le pixel qui suit le dernier de la bande la plus
528// proche de l'équateur a z>0 est celui de plus petit phi de la bande la
529// plus proche de l'equateur a z<0).
530//--
531{
532 int_4 ntotpix,i,j;
533 //r_8 x, omeg, omeg2pi, teti, tetm, tet, nphi, costeti;
534 r_8 omeg2pi;
535 // Decodage et controle des arguments d'appel :
536 // au moins 2 et au plus 16384 bandes d'un hemisphere en theta
537 if (m < 2) m = 2;
538 if (m > 16384) m = 16384;
539
540 // Au moins 4 et au plus 256 pixels dans la premiere bande decoupee en phi
541 if (pet < 4) pet = 4;
542 if (pet > 256) pet = 256;
543
544 // On memorise les arguments d'appel
545 mNTheta = m; mNPet = pet;
546
547 // On commence par decouper l'hemisphere z>0.
548 // Creation des vecteurs contenant :
549 // Les valeurs limites de theta (une valeur de plus que le nombre de bandes...)
550 mTheta = new r_4[m+1];
551
552 // Le nombre de pixels en phi de chacune des bandes en theta
553 mNphi = new int_4[m];
554
555 // Le nombre/Deuxpi total des pixels contenus dans les bandes de z superieur a une
556 // bande donnee (mTPphi[m] contient le nombre de pixels total de l'hemisphere)
557 mTNphi = new int_4[m+1];
558
559 // Calcul du nombre total de pixels dans chaque bande pour optimiser
560 // le rapport largeur/hauteur des pixels
561
562 //calotte polaire
563 mTNphi[0]=0;
564 mNphi[0] = 1;
565
566 //bandes jusqu'a l'equateur
567 for(j=1; j < m; j++) {
568 mTNphi[j] = mTNphi[j-1]+mNphi[j-1];
569 mNphi[j] = (int_4)(.5+4.*(double)(m-.5)*sin(Pi*(double)j/(double)(2.*m-1.))) ;
570 }
571
572 // Nombre total de pixels sur l'hemisphere
573 ntotpix = mTNphi[m-1]+mNphi[m-1];
574 mTNphi[m] = ntotpix;
575 // et sur la sphere entiere
576 mNPix=2*ntotpix;
577
578 // Creation et initialisation du vecteur des contenus des pixels
579 //mPix = new r_8[mNPix];
580 //for(i=0; i<mNPix; i++) mPix[i] = 0.;
581 _pixel=new PDataArray<r_8>(mNPix,true);
582 for(i=0; i<mNPix; i++) *(_pixel->Data()+i)=0.;
583 // Determination des limites des bandes en theta :
584 // omeg est l'angle solide couvert par chaque pixel,
585 // une bande donnee kt couvre un angle solide mNphi[kt]*omeg
586 // egal a 2* Pi*(cos mTheta[kt]-cos mTheta[kt+1]). De meme, l'angle solide
587 //de la
588 // calotte allant du pole a la limite haute de la bande kt vaut
589 // 2* Pi*(1.-cos mTheta[kt+1])= mTNphi[kt]*omeg...
590
591 omeg2pi = 1./(r_8)ntotpix;
592 mOmeg = omeg2pi*DeuxPi;
593
594 for(j=0; j <= m; j++) {
595 mTheta[j] = acos(1.-(double)mTNphi[j]*omeg2pi);
596 }
597}
598
599
600//++
601void SphereThetaPhi::GetThetaSlice(int_4 index, r_4& theta, Vector& phi, Vector& value) const
602
603// Retourne, pour la tranche en theta d'indice 'index' le theta
604// correspondant, un vecteur (Peida) contenant les phi des pixels de
605// la tranche, un vecteur (Peida) contenant les valeurs de pixel
606// correspondantes
607//--
608
609{
610 cout << "entree GetThetaSlice, couche no " << index << endl;
611 if (index<0 || index > NbThetaSlices()) {
612 // THROW(out_of_range("SphereThetaPhi::PIxVal Pixel index out of range"));
613 cout << " SphereThetaPhi::GetThetaSlice : exceptions a mettre en place" <<endl;
614 THROW(rangeCheckErr);
615 }
616 int_4 iring=Index(index,0);
617 int_4 bid=this->NPhi(index);
618 int lring=bid;
619 cout << " iring= " << iring << " lring= " << lring << endl;
620 phi.Realloc(lring);
621 value.Realloc(lring);
622 float T=0.;
623 float F=0.;
624 for (int kk=0; kk<lring;kk++) {
625 PixThetaPhi(kk+iring,T,F);
626 phi(kk)=F;
627 value(kk)=PixVal(kk+iring);
628 }
629 theta=T;
630
631}
632
633
634/* --Methode-- */
635
Note: See TracBrowser for help on using the repository browser.