source: Sophya/trunk/SophyaLib/Samba/spheregorski.cc@ 473

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

modifs francois : passage en double etc. 18-OCT-99

File size: 38.5 KB
Line 
1#include "spheregorski.h"
2#include "strutil.h"
3#include <complex>
4#include "piocmplx.h"
5
6extern "C"
7{
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
11}
12
13extern "C"
14{
15void anafast_(int&,int&,int&,double&,float*,float*,float*,float*,float*,float*,float*);
16void synfast_(int&,int&,int&,int&,float&,float*,float*,float*,double*,double*,double*,double*,double*,float*);
17}
18
19//*******************************************************************
20// Class PIXELS_XY
21// Construction des tableaux necessaires a la traduction des indices RING en
22// indices NESTED (ou l'inverse)
23//*******************************************************************
24
25PIXELS_XY::PIXELS_XY()
26{
27 cout << " appel du constructeur PIXELS_XY " <<endl;
28 pix2x_.ReSize(1024);
29 pix2x_.Reset();
30 pix2y_.ReSize(1024);
31 pix2y_.Reset();
32 x2pix_.ReSize(128);
33 x2pix_.Reset();
34 y2pix_.ReSize(128);
35 y2pix_.Reset();
36 mk_pix2xy();
37 mk_xy2pix();
38}
39
40PIXELS_XY& PIXELS_XY::instance()
41{
42 static PIXELS_XY single;
43 return (single);
44}
45
46void PIXELS_XY::mk_pix2xy()
47{
48 /*
49 ==================================================
50 subroutine mk_pix2xy
51 ==================================================
52 c constructs the array giving x and y in the face from pixel number
53 c for the nested (quad-cube like) ordering of pixels
54 c
55 c the bits corresponding to x and y are interleaved in the pixel number
56 c one breaks up the pixel number by even and odd bits
57 ==================================================
58 */
59 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
60 // (16/12/98)
61
62 int kpix, jpix, IX, IY, IP, ID;
63
64 for(kpix = 0; kpix < 1024; kpix++)
65 {
66 jpix = kpix;
67 IX = 0;
68 IY = 0;
69 IP = 1 ;// ! bit position (in x and y)
70 while( jpix!=0 )
71 { // ! go through all the bits
72 ID=jpix%2;// ! bit value (in kpix), goes in ix
73 jpix = jpix/2;
74 IX = ID*IP+IX;
75
76 ID=jpix%2;// ! bit value (in kpix), goes in iy
77 jpix = jpix/2;
78 IY = ID*IP+IY;
79
80 IP = 2*IP;// ! next bit (in x and y)
81 }
82 pix2x_(kpix) = IX;// ! in 0,31
83 pix2y_(kpix) = IY;// ! in 0,31
84 }
85}
86
87void PIXELS_XY::mk_xy2pix()
88{
89 /*
90 =================================================
91 subroutine mk_xy2pix
92 =================================================
93 c sets the array giving the number of the pixel lying in (x,y)
94 c x and y are in {1,128}
95 c the pixel number is in {0,128**2-1}
96 c
97 c if i-1 = sum_p=0 b_p * 2^p
98 c then ix = sum_p=0 b_p * 4^p
99 c iy = 2*ix
100 c ix + iy in {0, 128**2 -1}
101 =================================================
102 */
103 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
104 // (16/12/98)
105
106 int K,IP,I,J,ID;
107 for(I = 1; I <= 128; I++)
108 {
109 J = I-1;// !pixel numbers
110 K = 0;//
111 IP = 1;//
112 truc : if( J==0 )
113 {
114 x2pix_(I-1) = K;
115 y2pix_(I-1) = 2*K;
116 }
117 else
118 {
119 ID = (int)fmod(J,2);
120 J = J/2;
121 K = IP*ID+K;
122 IP = IP*4;
123 goto truc;
124 }
125 }
126}
127
128//*******************************************************************
129//++
130// Class SphereGorski
131//
132// include spheregorski.h strutil.h
133//
134// Pixelisation Gorski
135//
136//
137//| -----------------------------------------------------------------------
138//| version 0.8.2 Aug97 TAC Eric Hivon, Kris Gorski
139//| -----------------------------------------------------------------------
140//
141// the sphere is split in 12 diamond-faces containing nside**2 pixels each
142//
143// the numbering of the pixels (in the nested scheme) is similar to
144// quad-cube
145// In each face the first pixel is in the lowest corner of the diamond
146//
147// the faces are (x,y) coordinate on each face
148//| . . . . <--- North Pole
149//| / \ / \ / \ / \ ^ ^
150//| . 0 . 1 . 2 . 3 . <--- z = 2/3 \ /
151//| \ / \ / \ / \ / y \ / x
152//| 4 . 5 . 6 . 7 . 4 <--- equator \ /
153//| / \ / \ / \ / \ \/
154//| . 8 . 9 .10 .11 . <--- z = -2/3 (0,0) : lowest corner
155//| \ / \ / \ / \ /
156//| . . . . <--- South Pole
157//|
158// phi:0 2Pi
159//
160// in the ring scheme pixels are numbered along the parallels
161// the first parallel is the one closest to the north pole and so on
162// on each parallel, pixels are numbered starting from the one closest
163// to phi = 0
164//
165// nside DOIT OBLIGATOIREMENT ETRE UNE PUISSANCE DE 2 (<= 8192)
166//--
167//++
168//
169// Links Parents
170//
171// SphericalMap
172//--
173//++
174//
175// Links Descendants
176//
177//
178//--
179
180/* --Methode-- */
181//++
182// Titre Constructeurs
183//--
184//++
185
186template<class T>
187SphereGorski<T>::SphereGorski()
188
189//--
190{
191 cout<<" appel du constructeur SphereGorski ()" <<endl;
192 InitNul();
193}
194
195//++
196template<class T>
197SphereGorski<T>::SphereGorski(int m)
198
199// Constructeur : m est la variable nside de l'algorithme de Gorski
200// le nombre total de pixels sera Npix = 12*nside**2
201// m DOIT OBLIGATOIREMENT ETRE UNE PUISSANCE DE 2 (<= 8192)
202//--
203{
204 cout<<" appel du constructeur SphereGorski (m)" <<endl;
205
206 if(m <= 0 || m > 8192)
207 {
208 cout << "SphereGorski : m hors bornes [0,8192], m= " << m << endl;
209 exit(1);
210 }
211 // verifier que m est une puissance de deux
212 int x= m;
213 while(x%2 == 0) x/=2;
214 if(x != 1)
215 {
216 cout<<"SphereGorski: m doit etre une puissance de deux, m= "<<m<<endl;
217 exit(1);
218 }
219 InitNul();
220 Pixelize(m);
221}
222
223template<class T>
224SphereGorski<T>::SphereGorski(const SphereGorski<T>& s)
225{
226 cout << " constructeur de recopie " << endl;
227 if(s.mInfo_) mInfo_= new DVList(*s.mInfo_);
228
229 nSide_= s.nSide_;
230 nPix_ = s.nPix_;
231 omeg_ = s.omeg_;
232
233 pixels_= s.pixels_;
234
235 nlmax_= s.nlmax_;
236 nmmax_= s.nmmax_;
237 iseed_= s.iseed_;
238 fwhm_ = s.fwhm_;
239 quadrupole_ = s.quadrupole_;
240 sym_cut_deg_= s.sym_cut_deg_;
241 strcpy(powFile_,s.powFile_);
242}
243
244//++
245// Titre Destructeur
246//--
247//++
248template<class T>
249SphereGorski<T>::~SphereGorski()
250
251//--
252{
253 InitNul();
254}
255
256//++
257// Titre Méthodes
258//--
259
260//++
261template<class T>
262void SphereGorski<T>::Resize(int m)
263
264// m est la variable nside de l'algorithme de Gorski
265// le nombre total de pixels sera Npix = 12*nside**2
266// m DOIT OBLIGATOIREMENT ETRE UNE PUISSANCE DE 2 (<= 8192)
267//--
268{
269 if (m<=0 || m> 8192) {
270 cout << "SphereGorski : m hors bornes [0,8192], m= " << m << endl;
271 exit(1);
272 }
273 // verifier que m est une puissance de deux
274 int x= m;
275 while (x%2==0) x/=2;
276 if(x != 1)
277 {
278 cout<<"SphereGorski: m doit etre une puissance de deux, m= "<<m<<endl;
279 exit(1);
280 }
281 InitNul();
282 Pixelize(m);
283}
284
285template<class T>
286void SphereGorski<T>::Pixelize( int m)
287
288// prépare la pixelisation Gorski (m a la même signification
289// que pour le constructeur)
290//
291//
292//--
293{
294 // On memorise les arguments d'appel
295 nSide_= m;
296
297 // Nombre total de pixels sur la sphere entiere
298 nPix_= 12*nSide_*nSide_;
299
300 // pour le moment les tableaux qui suivent seront ranges dans l'ordre
301 // de l'indexation GORSKY "RING"
302 // on pourra ulterieurement changer de strategie et tirer profit
303 // de la dualite d'indexation GORSKY (RING et NEST) : tout dependra
304 // de pourquoi c'est faire
305
306 // Creation et initialisation du vecteur des contenus des pixels
307 pixels_.ReSize(nPix_);
308 pixels_.Reset();
309
310 // solid angle per pixel
311 omeg_= 4.0*Pi/nPix_;
312}
313
314template<class T>
315void SphereGorski<T>::InitNul()
316//
317// initialise à zéro les variables de classe
318{
319 nSide_= 0;
320 nPix_ = 0;
321 omeg_ = 0.;
322 pixels_.Reset();
323
324 nlmax_= 0;
325 nmmax_= 0;
326 iseed_= 0;
327 fwhm_ = 0.;
328 quadrupole_ = 0.;
329 sym_cut_deg_= 0.;
330 for(int k = 0; k < 128; k++) powFile_[k]=' ';
331}
332
333/* --Methode-- */
334//++
335template<class T>
336int SphereGorski<T>::NbPixels() const
337
338// Retourne le nombre de pixels du découpage
339//--
340{
341 return(nPix_);
342}
343
344//++
345template<class T>
346int SphereGorski<T>::NbThetaSlices() const
347
348// Retourne le nombre de tranches en theta sur la sphere
349//--
350{
351 return int(4*nSide_-1);
352}
353
354//++
355template<class T>
356void SphereGorski<T>::GetThetaSlice(int index,double& theta,TVector<double>& phi,TVector<T>& value) const
357
358// Retourne, pour la tranche en theta d'indice 'index' le theta
359// correspondant, un vecteur (Peida) contenant les phi des pixels de
360// la tranche, un vecteur (Peida) contenant les valeurs de pixel
361// correspondantes
362//--
363{
364 cout << "entree GetThetaSlice, couche no " << index << endl;
365
366 if (index<0 || index > NbThetaSlices())
367 {
368 // THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
369 cout << " SphereGorski::GetThetaSlice : exceptions a mettre en place" <<endl;
370 THROW(rangeCheckErr);
371 }
372
373 int iring= 0;
374 int lring = 0;
375 if(index < nSide_-1)
376 {
377 iring= 2*index*(index+1);
378 lring= 4*(index+1);
379 }
380 else if(index < 3*nSide_)
381 {
382 iring= 2*nSide_*(2*index-nSide_+1);
383 lring= 4*nSide_;
384 }
385 else
386 {
387 int nc= 4*nSide_-1-index;
388 iring = nPix_-2*nc*(nc+1);
389 lring = 4*nc;
390 }
391
392 phi.ReSize(lring);
393 value.ReSize(lring);
394 double TH= 0.;
395 double FI= 0.;
396 for(int kk = 0; kk < lring;kk++)
397 {
398 PixThetaPhi(kk+iring,TH,FI);
399 phi(kk)= FI;
400 value(kk)= PixVal(kk+iring);
401 }
402 theta= TH;
403}
404
405/* --Methode-- */
406//++
407template<class T>
408T& SphereGorski<T>::PixVal(int k)
409
410// Retourne la valeur du contenu du pixel d'indice "RING" k
411//--
412{
413 if((k < 0) || (k >= nPix_))
414 {
415 // THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
416 cout << " SphereGorski::PIxVal : exceptions a mettre en place" <<endl;
417 THROW(rangeCheckErr);
418 }
419 return pixels_(k);
420}
421
422/* --Methode-- */
423//++
424template<class T>
425T const& SphereGorski<T>::PixVal(int k) const
426
427// Retourne la valeur du contenu du pixel d'indice "RING" k
428//--
429{
430 if((k < 0) || (k >= nPix_))
431 {
432 //THROW(out_of_range("SphereGorski::PIxVal Pixel index out of range"));
433 cout << " SphereGorski::PIxVal : exceptions a mettre en place" <<endl;
434 THROW(rangeCheckErr);
435 }
436 return *(pixels_.Data()+k);
437}
438
439//++
440template<class T>
441T& SphereGorski<T>::PixValNest(int k)
442
443// Retourne la valeur du contenu du pixel d'indice "NESTED" k
444//--
445{
446 if((k < 0) || (k >= nPix_))
447 {
448 //THROW(out_of_range("SphereGorski::PIxValNest Pixel index out of range"));
449 cout<<" SphereGorski::PIxValNest : exceptions a mettre en place" <<endl;
450 THROW(rangeCheckErr);
451 }
452 return pixels_(nest2ring(nSide_,k));
453}
454//++
455
456template<class T>
457T const& SphereGorski<T>::PixValNest(int k) const
458
459// Retourne la valeur du contenu du pixel d'indice "NESTED" k
460//--
461{
462 if((k < 0) || (k >= nPix_))
463 {
464 //THROW(out_of_range("SphereGorski::PIxValNest Pixel index out of range"));
465 cout<<" SphereGorski::PIxValNest : exceptions a mettre en place" <<endl;
466 THROW(rangeCheckErr);
467 }
468 int pix= nest2ring(nSide_,k);
469 return *(pixels_.Data()+pix);
470}
471
472/* --Methode-- */
473//++
474template<class T>
475int SphereGorski<T>::PixIndexSph(double theta,double phi) const
476
477// Retourne l'indice "RING" du pixel vers lequel pointe une direction
478// définie par ses coordonnées sphériques
479//--
480{
481 return ang2pix_ring(nSide_,theta,phi);
482}
483
484//++
485template<class T>
486int SphereGorski<T>::PixIndexSphNest(double theta,double phi) const
487
488// Retourne l'indice NESTED" du pixel vers lequel pointe une direction
489// définie par ses coordonnées sphériques
490//--
491{
492 return ang2pix_nest(nSide_,theta,phi);
493}
494
495
496/* --Methode-- */
497//++
498template<class T>
499void SphereGorski<T>::PixThetaPhi(int k,double& theta,double& phi) const
500
501// Retourne les coordonnées (theta,phi) du milieu du pixel d'indice "RING" k
502//--
503{
504 pix2ang_ring(nSide_,k,theta,phi);
505}
506
507//++
508template<class T>
509double SphereGorski<T>::PixSolAngle(int dummy) const
510// Pixel Solid angle (steradians)
511// All the pixels have the same solid angle. The dummy argument is
512// for compatibility with eventual pixelizations which would not
513// fulfil this requirement.
514//--
515{
516 return omeg_;
517}
518
519//++
520template<class T>
521void SphereGorski<T>::PixThetaPhiNest(int k,double& theta,double& phi) const
522
523// Retourne les coordonnées (theta,phi) du milieu du pixel d'indice
524// NESTED k
525//--
526{
527 pix2ang_nest(nSide_,k,theta,phi);
528}
529
530//++
531template<class T>
532int SphereGorski<T>::NestToRing(int k) const
533
534// conversion d'index NESTD en un index RING
535//
536//--
537{
538 return nest2ring(nSide_,k);
539}
540
541//++
542template<class T>
543int SphereGorski<T>::RingToNest(int k) const
544//
545// conversion d'index RING en un index NESTED
546//
547//--
548{
549 return ring2nest(nSide_,k);
550}
551
552/*
553//++
554template<class T>
555void SphereGorski<T>::anharm(int nlmax, float sym_c,float* powspec)
556//
557// analyse en harmoniques spheriques des valeurs des pixels de la
558// sphere : appel du module anafast (Gorski-Hivon)
559//
560// "nlmax" : multipole maximum, nlmax <= 2*nsmax (cf. Nyquist)
561//
562// "sym c" : coupure symetrique autour de l'equateur (degres)
563//
564// "powspec" : tableau resultat (a reserver avant l'appel) de C(l)
565// (spectre de puissance)
566//
567//--
568//
569// Pb a resoudre : dans cette classe les valeurs de pixel sont "double"
570// dans anafast le tableau correspondant est "float"
571// pour l'instant on duplique les tableaux, il faudra decider quelque chose
572//
573{
574 if (nlmax > 2*nSide_) {
575 cout << " anharm : nlmax= " << nlmax <<
576 " doit etre <= 2*nsmax (cf. Nyquist), soit :" << 2*nSide_ << endl;
577 exit(1);
578 }
579 else {
580 nlmax_=nlmax;
581 nmmax_=nlmax_;
582 }
583 sym_cut_deg_=sym_c;
584 float* map=new float[nPix_];
585 for (int k=0; k<nPix_; k++) map[k]=(float)pixels_(k);
586 int nsmax=nSide_;
587 int nmmax=nmmax_;
588 double sc=(double)sym_cut_deg_;
589 float* alm_T=new float[2*(nlmax+1)*(nmmax+1)];
590 if (powspec==NULL) {
591
592 cout <<
593 " anharm : un tableau de C_l doit etre alloue avant appel " << endl;
594 exit(1);
595 }
596 float* phas_n=new float[2*(nmmax+1)];
597 float* phas_s=new float[2*(nmmax+1)];
598 float* dataw =new float[16*nsmax];
599 float* work =new float[16*nsmax];
600
601 anafast_(nsmax,nlmax,nmmax,sc,map,alm_T, powspec,phas_n,phas_s,dataw,work);
602 quadrupole_=powspec[2];
603 delete [] map;
604 delete [] alm_T;
605 delete [] phas_n;
606 delete [] phas_s;
607 delete [] dataw;
608 delete [] work;
609}
610*/
611
612/*
613//++
614template<class T>
615void SphereGorski<T>::synharm(int nlmax, int iseed,float fwhm, float* powspec)
616//
617// synthese des valeurs des pixels de la sphere par l'intermediaire
618// des coefficients en harmoniques spheriques reconstitues apartir d'un
619// spectre en puissance : appel du module synfast (Gorski-Hivon)
620//
621// powspec est un tableau (a fournir) de C(l) (spectre de puissance)
622// Ce tableau doit contenir les valeur de C(l) par ordre
623// SEQUENTIEL de l (de l=0 a l=nlmax). IL SERA MODIFIE PAR L'ALGORITHME
624//
625// nlmax : multipole maximum (nlmax <= 2*nsmax (cf. Nyquist)
626// iseed : initialisation generation aleatoire (negatif, suggere : -1)
627// fwhm : largeur totale a mi-hauteur (minutes d'arc, >=0, ex: 5)
628//--
629// Pb a resoudre : dans cette classe les valeurs de pixel sont "double"
630// dans anafast le tableau correspondant est "float"
631// pour l'instant on duplique les tableaux, il faudra decider quelque chose
632
633{
634 if (nlmax > 2*nSide_) {
635 cout << " sphereGorski::synharm: nlmax= " << nlmax <<
636 " doit etre <= 2*nsmax (cf. Nyquist), soit : " << 2*nSide_ << endl;
637 exit(1);
638 }
639 else {
640 nlmax_=nlmax;
641 nmmax_=nlmax_;
642 quadrupole_=powspec[2];
643 }
644 if (powspec==NULL) {
645
646 cout <<
647 "sphereGorski::synharm : un tableau de C_l doit etre alloue avant appel"
648 << endl;
649 exit(1);
650 }
651 iseed_=iseed;
652 fwhm_ =fwhm;
653 float* map=new float[nPix_];
654 int nsmax=nSide_;
655 int nmmax=nmmax_;
656 float* alm_T=new float[2*(nlmax+1)*(nmmax+1)];
657
658 // tableaux de travail
659 double* b_north=new double[2*(2*nmmax+1)];
660 double* b_south=new double[2*(2*nmmax+1)];
661 double* bw=new double[2*4*nsmax];
662 double* data=new double[2*4*nsmax];
663 double* work=new double[2*4*nsmax];
664 float* lread=new float[nlmax+1];
665 synfast_(nsmax,nlmax,nmmax,iseed,fwhm, map,alm_T, powspec,
666 b_north,b_south,bw,data,work,lread);
667 for (int k=0; k<nPix_; k++) pixels_(k) = (T)map[k];
668 delete [] map;
669 delete [] alm_T;
670 delete [] b_north;
671 delete [] b_south;
672 delete [] bw;
673 delete [] data;
674 delete [] work;
675 delete [] lread;
676}
677*/
678
679template<class T>
680int SphereGorski<T>::nest2ring(int nside, int ipnest) const
681{
682 /*
683 ====================================================
684 subroutine nest2ring(nside, ipnest, ipring)
685 ====================================================
686 c conversion from NESTED to RING pixel number
687 ====================================================
688 */
689 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
690 // (16/12/98)
691
692 const PIXELS_XY& PXY= PIXELS_XY::instance();
693
694 int npix, npface, face_num, ncap, n_before;
695 int ipf, ip_low, ip_trunc, ip_med, ip_hi;
696 int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
697 int ns_max=8192;
698 int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};
699 int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};
700
701 if( nside<1 || nside>ns_max ) {
702 cout << "nside out of range" << endl;
703 exit(0);
704 }
705 npix = 12 * nside* nside;
706 if( ipnest<0 || ipnest>npix-1 ) {
707 cout << "ipnest out of range" << endl;
708 exit(0);
709 }
710
711 ncap = 2* nside*( nside-1);// ! number of points in the North Polar cap
712 nl4 = 4* nside;
713
714 //c finds the face, and the number in the face
715 npface = nside* nside;
716 //cccccc ip = ipnest - 1 ! in {0,npix-1}
717
718 face_num = ipnest/npface;// ! face number in {0,11}
719 ipf =ipnest%npface;// ! pixel number in the face {0,npface-1}
720 //c finds the x,y on the face (starting from the lowest corner)
721 //c from the pixel number
722 ip_low=ipf%1024; // ! content of the last 10 bits
723 ip_trunc = ipf/1024; // ! truncation of the last 10 bits
724 ip_med=ip_trunc%1024; // ! content of the next 10 bits
725 ip_hi = ip_trunc/1024;// ! content of the high weight 10 bits
726
727 ix = 1024*PXY.pix2x_(ip_hi)+32*PXY.pix2x_(ip_med)+PXY.pix2x_(ip_low);
728 iy = 1024*PXY.pix2y_(ip_hi)+32*PXY.pix2y_(ip_med)+PXY.pix2y_(ip_low);
729
730 //c transforms this in (horizontal, vertical) coordinates
731 jrt = ix + iy;// ! 'vertical' in {0,2*(nside-1)}
732 jpt = ix - iy;// ! 'horizontal' in {-nside+1,nside-1}
733
734 //c computes the z coordinate on the sphere
735 // jr = jrll[face_num+1]*nside - jrt - 1;// ! ring number in {1,4*nside-1}
736 jr = jrll[face_num]*nside - jrt - 1;
737 nr = nside;// ! equatorial region (the most frequent)
738 n_before = ncap + nl4 * (jr - nside);
739 kshift=(jr - nside)%2;
740 if( jr<nside ) {//then ! north pole region
741 nr = jr;
742 n_before = 2 * nr * (nr - 1);
743 kshift = 0;
744 }
745 else if( jr>3*nside ) {//then ! south pole region
746 nr = nl4 - jr;
747 n_before = npix - 2 * (nr + 1) * nr;
748 kshift = 0;
749 }
750
751 //c computes the phi coordinate on the sphere, in [0,2Pi]
752 jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;// ! 'phi' number in the ring in {1,4*nr}
753
754 if( jp>nl4 ) jp = jp - nl4;
755 if( jp<1 ) jp = jp + nl4;
756
757 int aux=n_before + jp - 1;
758 return (n_before + jp - 1);// ! in {0, npix-1}
759}
760
761template<class T>
762int SphereGorski<T>::ring2nest(int nside, int ipring) const
763{
764 /*
765 ==================================================
766 subroutine ring2nest(nside, ipring, ipnest)
767 ==================================================
768 c conversion from RING to NESTED pixel number
769 ==================================================
770 */
771 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
772 // (16/12/98)
773
774 const PIXELS_XY& PXY= PIXELS_XY::instance();
775
776 double fihip, hip;
777 int npix, nl2, nl4, ncap, ip, iphi, ipt, ipring1;
778 int kshift, face_num, nr;
779 int irn, ire, irm, irs, irt, ifm , ifp;
780 int ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf;
781 int ns_max(8192);
782
783 // coordinate of the lowest corner of each face
784 int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};// ! in unit of nside
785 int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};//! in unit of nside/2
786
787 if( nside<1 || nside>ns_max ) {
788 cout << "nside out of range" << endl;
789 exit(0);
790 }
791 npix = 12 * nside*nside;
792 if( ipring<0 || ipring>npix-1 ) {
793 cout << "ipring out of range" << endl;
794 exit(0);
795 }
796
797 nl2 = 2*nside;
798 nl4 = 4*nside;
799 npix = 12*nside*nside;// ! total number of points
800 ncap = 2*nside*(nside-1);// ! points in each polar cap, =0 for nside =1
801 ipring1 = ipring + 1;
802
803 //c finds the ring number, the position of the ring and the face number
804 if( ipring1<=ncap ) {//then
805
806 hip = ipring1/2.;
807 fihip = (int)floor ( hip );
808 irn = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;// ! counted from North pole
809 iphi = ipring1 - 2*irn*(irn - 1);
810
811 kshift = 0;
812 nr = irn ;// ! 1/4 of the number of points on the current ring
813 face_num = (iphi-1) / irn;// ! in {0,3}
814 }
815 else if( ipring1<=nl2*(5*nside+1) ) {//then
816
817 ip = ipring1 - ncap - 1;
818 irn = (int)floor( ip / nl4 ) + nside;// ! counted from North pole
819 iphi = (int)fmod(ip,nl4) + 1;
820
821 kshift = (int)fmod(irn+nside,2);// ! 1 if irn+nside is odd, 0 otherwise
822 nr = nside;
823 ire = irn - nside + 1;// ! in {1, 2*nside +1}
824 irm = nl2 + 2 - ire;
825 ifm = (iphi - ire/2 + nside -1) / nside;// ! face boundary
826 ifp = (iphi - irm/2 + nside -1) / nside;
827 if( ifp==ifm ) {//then ! faces 4 to 7
828 face_num = (int)fmod(ifp,4) + 4;
829 }
830 else if( ifp + 1==ifm ) {//then ! (half-)faces 0 to 3
831 face_num = ifp;
832 }
833 else if( ifp - 1==ifm ) {//then ! (half-)faces 8 to 11
834 face_num = ifp + 7;
835 }
836 }
837 else {
838
839 ip = npix - ipring1 + 1;
840 hip = ip/2.;
841 fihip = floor ( hip );
842 irs = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;// ! counted from South pole
843 iphi = 4*irs + 1 - (ip - 2*irs*(irs-1));
844
845 kshift = 0;
846 nr = irs;
847 irn = nl4 - irs;
848 face_num = (iphi-1) / irs + 8;// ! in {8,11}
849 }
850
851 //c finds the (x,y) on the face
852 irt = irn - jrll[face_num]*nside + 1;// ! in {-nside+1,0}
853 ipt = 2*iphi - jpll[face_num]*nr - kshift - 1;// ! in {-nside+1,nside-1}
854
855
856 if( ipt>=nl2 ) ipt = ipt - 8*nside;// ! for the face #4
857
858 ix = (ipt - irt ) / 2;
859 iy = -(ipt + irt ) / 2;
860
861 ix_low = (int)fmod(ix,128);
862 ix_hi = ix/128;
863 iy_low = (int)fmod(iy,128);
864 iy_hi = iy/128;
865 ipf=(PXY.x2pix_(ix_hi)+PXY.y2pix_(iy_hi))*(128*128)+(PXY.x2pix_(ix_low)+PXY.y2pix_(iy_low));
866
867 return (ipf + face_num* nside *nside);// ! in {0, 12*nside**2 - 1}
868}
869
870template<class T>
871int SphereGorski<T>::ang2pix_ring(int nside, double theta, double phi) const
872{
873 /*
874 ==================================================
875 c gives the pixel number ipix (RING)
876 c corresponding to angles theta and phi
877 c==================================================
878 */
879 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
880 // (16/12/98)
881
882 int nl2, nl4, ncap, npix, jp, jm, ipix1;
883 double z, za, tt, tp, tmp;
884 int ir, ip, kshift;
885
886 double piover2(Pi/2.);
887 double twopi(2.*Pi);
888 double z0(2./3.);
889 int ns_max(8192);
890
891 if( nside<1 || nside>ns_max ) {
892 cout << "nside out of range" << endl;
893 exit(0);
894 }
895
896 if( theta<0. || theta>Pi) {
897 cout << "theta out of range" << endl;
898 exit(0);
899 }
900
901 z = cos(theta);
902 za = fabs(z);
903 if( phi >= twopi) phi = phi - twopi;
904 if (phi < 0.) phi = phi + twopi;
905 tt = phi / piover2;// ! in [0,4)
906
907 nl2 = 2*nside;
908 nl4 = 4*nside;
909 ncap = nl2*(nside-1);// ! number of pixels in the north polar cap
910 npix = 12*nside*nside;
911
912 if( za <= z0 ) {
913
914 jp = (int)floor(nside*(0.5 + tt - z*0.75));// ! index of ascending edge line
915 jm = (int)floor(nside*(0.5 + tt + z*0.75));// ! index of descending edge line
916
917 ir = nside + 1 + jp - jm;// ! in {1,2n+1} (ring number counted from z=2/3)
918 kshift = 0;
919 if (fmod(ir,2)==0.) kshift = 1;// ! kshift=1 if ir even, 0 otherwise
920
921 ip = (int)floor( ( jp+jm - nside + kshift + 1 ) / 2 ) + 1;// ! in {1,4n}
922 if( ip>nl4 ) ip = ip - nl4;
923
924 ipix1 = ncap + nl4*(ir-1) + ip ;
925 }
926 else {
927
928 tp = tt - floor(tt);// !MOD(tt,1.d0)
929 tmp = sqrt( 3.*(1. - za) );
930
931 jp = (int)floor( nside * tp * tmp );// ! increasing edge line index
932 jm = (int)floor( nside * (1. - tp) * tmp );// ! decreasing edge line index
933
934 ir = jp + jm + 1;// ! ring number counted from the closest pole
935 ip = (int)floor( tt * ir ) + 1;// ! in {1,4*ir}
936 if( ip>4*ir ) ip = ip - 4*ir;
937
938 ipix1 = 2*ir*(ir-1) + ip;
939 if( z<=0. ) {
940 ipix1 = npix - 2*ir*(ir+1) + ip;
941 }
942 }
943 return (ipix1 - 1);// ! in {0, npix-1}
944}
945
946template<class T>
947int SphereGorski<T>::ang2pix_nest(int nside, double theta, double phi) const
948{
949 /*
950 ==================================================
951 subroutine ang2pix_nest(nside, theta, phi, ipix)
952 ==================================================
953 c gives the pixel number ipix (NESTED)
954 c corresponding to angles theta and phi
955 c
956 c the computation is made to the highest resolution available (nside=8192)
957 c and then degraded to that required (by integer division)
958 c this doesn't cost more, and it makes sure
959 c that the treatement of round-off will be consistent
960 c for every resolution
961 ==================================================
962 */
963 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
964 // (16/12/98)
965
966 const PIXELS_XY& PXY= PIXELS_XY::instance();
967
968 double z, za, z0, tt, tp, tmp;
969 int face_num,jp,jm;
970 int ifp, ifm;
971 int ix, iy, ix_low, ix_hi, iy_low, iy_hi, ipf, ntt;
972 double piover2(Pi/2.), twopi(2.*Pi);
973 int ns_max(8192);
974
975 if( nside<1 || nside>ns_max ) {
976 cout << "nside out of range" << endl;
977 exit(0);
978 }
979 if( theta<0 || theta>Pi ) {
980 cout << "theta out of range" << endl;
981 exit(0);
982 }
983 z = cos(theta);
984 za = fabs(z);
985 z0 = 2./3.;
986 if( phi>=twopi ) phi = phi - twopi;
987 if( phi<0. ) phi = phi + twopi;
988 tt = phi / piover2;// ! in [0,4[
989 if( za<=z0 ) { // then ! equatorial region
990
991 //(the index of edge lines increase when the longitude=phi goes up)
992 jp = (int)floor(ns_max*(0.5 + tt - z*0.75));// ! ascending edge line index
993 jm = (int)floor(ns_max*(0.5 + tt + z*0.75));// ! descending edge line index
994
995 //c finds the face
996 ifp = jp / ns_max;// ! in {0,4}
997 ifm = jm / ns_max;
998 if( ifp==ifm ) face_num = (int)fmod(ifp,4) + 4; //then ! faces 4 to 7
999 else if( ifp<ifm ) face_num = (int)fmod(ifp,4); // (half-)faces 0 to 3
1000 else face_num = (int)fmod(ifm,4) + 8;//! (half-)faces 8 to 11
1001
1002 ix = (int)fmod(jm, ns_max);
1003 iy = ns_max - (int)fmod(jp, ns_max) - 1;
1004 }
1005 else { //! polar region, za > 2/3
1006
1007 ntt = (int)floor(tt);
1008 if( ntt>=4 ) ntt = 3;
1009 tp = tt - ntt;
1010 tmp = sqrt( 3.*(1. - za) );// ! in ]0,1]
1011
1012 //(the index of edge lines increase when distance from the closest pole goes up)
1013 jp = (int)floor(ns_max*tp*tmp); // ! line going toward the pole as phi increases
1014 jm = (int)floor(ns_max*(1.-tp)*tmp); // ! that one goes away of the closest pole
1015 jp = (int)min(ns_max-1, jp);// ! for points too close to the boundary
1016 jm = (int)min(ns_max-1, jm);
1017
1018 // finds the face and pixel's (x,y)
1019 if( z>=0 ) {
1020 face_num = ntt;// ! in {0,3}
1021 ix = ns_max - jm - 1;
1022 iy = ns_max - jp - 1;
1023 }
1024 else {
1025 face_num = ntt + 8;// ! in {8,11}
1026 ix = jp;
1027 iy = jm;
1028 }
1029 }
1030
1031 ix_low = (int)fmod(ix,128);
1032 ix_hi = ix/128;
1033 iy_low = (int)fmod(iy,128);
1034 iy_hi = iy/128;
1035 ipf= (PXY.x2pix_(ix_hi)+PXY.y2pix_(iy_hi))*(128*128)+(PXY.x2pix_(ix_low)+PXY.y2pix_(iy_low));
1036 ipf = ipf / pow(ns_max/nside,2);// ! in {0, nside**2 - 1}
1037 return ( ipf + face_num*pow(nside,2));// ! in {0, 12*nside**2 - 1}
1038}
1039
1040template<class T>
1041void SphereGorski<T>::pix2ang_ring(int nside,int ipix,double& theta,double& phi) const {
1042 /*
1043 ===================================================
1044 c gives theta and phi corresponding to pixel ipix (RING)
1045 c for a parameter nside
1046 ===================================================
1047 */
1048 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
1049 // (16/12/98)
1050
1051 int nl2, nl4, npix, ncap, iring, iphi, ip, ipix1;
1052 double fact1, fact2, fodd, hip, fihip;
1053
1054 int ns_max(8192);
1055
1056 if( nside<1 || nside>ns_max ) {
1057 cout << "nside out of range" << endl;
1058 exit(0);
1059 }
1060 npix = 12*nside*nside; // ! total number of points
1061 if( ipix<0 || ipix>npix-1 ) {
1062 cout << "ipix out of range" << endl;
1063 exit(0);
1064 }
1065
1066 ipix1 = ipix + 1; // in {1, npix}
1067 nl2 = 2*nside;
1068 nl4 = 4*nside;
1069 ncap = 2*nside*(nside-1);// ! points in each polar cap, =0 for nside =1
1070 fact1 = 1.5*nside;
1071 fact2 = 3.0*nside*nside;
1072
1073 if( ipix1 <= ncap ) { //! North Polar cap -------------
1074
1075 hip = ipix1/2.;
1076 fihip = floor(hip);
1077 iring = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;// ! counted from North pole
1078 iphi = ipix1 - 2*iring*(iring - 1);
1079
1080 theta = acos( 1. - iring*iring / fact2 );
1081 phi = (1.*iphi - 0.5) * Pi/(2.*iring);
1082 // cout << theta << " " << phi << endl;
1083 }
1084 else if( ipix1 <= nl2*(5*nside+1) ) {//then ! Equatorial region ------
1085
1086 ip = ipix1 - ncap - 1;
1087 iring = (int)floor( ip / nl4 ) + nside;// ! counted from North pole
1088 iphi = (int)fmod(ip,nl4) + 1;
1089
1090 fodd = 0.5 * (1 + fmod((double)(iring+nside),2));// ! 1 if iring+nside is odd, 1/2 otherwise
1091 theta = acos( (nl2 - iring) / fact1 );
1092 phi = (1.*iphi - fodd) * Pi /(2.*nside);
1093 }
1094 else {//! South Polar cap -----------------------------------
1095
1096 ip = npix - ipix1 + 1;
1097 hip = ip/2.;
1098 fihip = 1.*hip;
1099 iring = (int)floor( sqrt( hip - sqrt(fihip) ) ) + 1;// ! counted from South pole
1100 iphi = (int)(4.*iring + 1 - (ip - 2.*iring*(iring-1)));
1101
1102 theta = acos( -1. + iring*iring / fact2 );
1103 phi = (1.*iphi - 0.5) * Pi/(2.*iring);
1104 // cout << theta << " " << phi << endl;
1105 }
1106}
1107
1108template<class T>
1109void SphereGorski<T>::pix2ang_nest(int nside,int ipix,double& theta,double& phi) const {
1110 /*
1111 ==================================================
1112 subroutine pix2ang_nest(nside, ipix, theta, phi)
1113 ==================================================
1114 c gives theta and phi corresponding to pixel ipix (NESTED)
1115 c for a parameter nside
1116 ==================================================
1117 */
1118 // tranlated from FORTRAN (Gorski) to C, by B. Revenu, revised Guy Le Meur
1119 // (16/12/98)
1120
1121 const PIXELS_XY& PXY= PIXELS_XY::instance();
1122
1123 int npix, npface, face_num;
1124 int ipf, ip_low, ip_trunc, ip_med, ip_hi;
1125 int ix, iy, jrt, jr, nr, jpt, jp, kshift, nl4;
1126 double z, fn, fact1, fact2;
1127 double piover2(Pi/2.);
1128 int ns_max(8192);
1129
1130 // ! coordinate of the lowest corner of each face
1131 int jrll[12]={2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4};//! in unit of nside
1132 int jpll[12]={1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7};// ! in unit of nside/2
1133
1134 if( nside<1 || nside>ns_max ) {
1135 cout << "nside out of range" << endl;
1136 exit(0);
1137 }
1138 npix = 12 * nside*nside;
1139 if( ipix<0 || ipix>npix-1 ) {
1140 cout << "ipix out of range" << endl;
1141 exit(0);
1142 }
1143
1144 fn = 1.*nside;
1145 fact1 = 1./(3.*fn*fn);
1146 fact2 = 2./(3.*fn);
1147 nl4 = 4*nside;
1148
1149 //c finds the face, and the number in the face
1150 npface = nside*nside;
1151
1152 face_num = ipix/npface;// ! face number in {0,11}
1153 ipf = (int)fmod(ipix,npface);// ! pixel number in the face {0,npface-1}
1154
1155 //c finds the x,y on the face (starting from the lowest corner)
1156 //c from the pixel number
1157 ip_low = (int)fmod(ipf,1024);// ! content of the last 10 bits
1158 ip_trunc = ipf/1024 ;// ! truncation of the last 10 bits
1159 ip_med = (int)fmod(ip_trunc,1024);// ! content of the next 10 bits
1160 ip_hi = ip_trunc/1024 ;//! content of the high weight 10 bits
1161
1162 ix = 1024*PXY.pix2x_(ip_hi)+32*PXY.pix2x_(ip_med)+PXY.pix2x_(ip_low);
1163 iy = 1024*PXY.pix2y_(ip_hi)+32*PXY.pix2y_(ip_med)+PXY.pix2y_(ip_low);
1164
1165 //c transforms this in (horizontal, vertical) coordinates
1166 jrt = ix + iy;// ! 'vertical' in {0,2*(nside-1)}
1167 jpt = ix - iy;// ! 'horizontal' in {-nside+1,nside-1}
1168
1169 //c computes the z coordinate on the sphere
1170 // jr = jrll[face_num+1]*nside - jrt - 1;// ! ring number in {1,4*nside-1}
1171 jr = jrll[face_num]*nside - jrt - 1;
1172 nr = nside;// ! equatorial region (the most frequent)
1173 z = (2*nside-jr)*fact2;
1174 kshift = (int)fmod(jr - nside, 2);
1175 if( jr<nside ) { //then ! north pole region
1176 nr = jr;
1177 z = 1. - nr*nr*fact1;
1178 kshift = 0;
1179 }
1180 else {
1181 if( jr>3*nside ) {// then ! south pole region
1182 nr = nl4 - jr;
1183 z = - 1. + nr*nr*fact1;
1184 kshift = 0;
1185 }
1186 }
1187 theta = acos(z);
1188
1189 //c computes the phi coordinate on the sphere, in [0,2Pi]
1190 // jp = (jpll[face_num+1]*nr + jpt + 1 + kshift)/2;// ! 'phi' number in the ring in {1,4*nr}
1191 jp = (jpll[face_num]*nr + jpt + 1 + kshift)/2;
1192 if( jp>nl4 ) jp = jp - nl4;
1193 if( jp<1 ) jp = jp + nl4;
1194 phi = (jp - (kshift+1)*0.5) * (piover2 / nr);
1195}
1196
1197// retourne le nom du fichier qui contient le spectre de puissance
1198template<class T>
1199void SphereGorski<T>::powfile(char filename[]) const
1200{
1201 bool status = false;
1202 for (int k=0; k< 128; k++)
1203 {
1204 if( powFile_[k] != ' ' )
1205 {
1206 status = true;
1207 break;
1208 }
1209 }
1210 if ( status )
1211 {
1212 strcpy(filename,powFile_);
1213 }
1214 else
1215 {
1216 strcpy(filename,"no file");
1217 }
1218}
1219
1220template<class T>
1221void SphereGorski<T>::getParafast(int& nlmax,int& nmmax,int& iseed,float& fwhm,float& quadr,float& cut) const
1222{
1223 nlmax= nlmax_;
1224 nmmax= nmmax_;
1225 iseed= iseed_;
1226 fwhm = fwhm_;
1227 quadr= quadrupole_;
1228 cut = sym_cut_deg_;
1229}
1230
1231template<class T>
1232void SphereGorski<T>::setParafast(int nlmax,int nmmax,int iseed,float fwhm,float quadr,float cut,char* filename)
1233{
1234 nlmax_= nlmax;
1235 nmmax_= nmmax;
1236 iseed_= iseed;
1237 fwhm_ = fwhm;
1238 quadrupole_ = quadr;
1239 sym_cut_deg_= cut;
1240 strcpy(powFile_,filename);
1241}
1242
1243template <class T>
1244void SphereGorski<T>::print(ostream& os) const
1245{
1246 if(mInfo_) os << " DVList Info= " << *mInfo_ << endl;
1247 //
1248 os << " nSide_ = " << nSide_ << endl;
1249 os << " nPix_ = " << nPix_ << endl;
1250 os << " omeg_ = " << omeg_ << endl;
1251
1252 os << " contenu de pixels : ";
1253 for(int i=0; i < nPix_; i++)
1254 {
1255 if(i%5 == 0) os << endl;
1256 os << pixels_(i) <<", ";
1257 }
1258 os << endl;
1259
1260 os << endl;
1261 const PIXELS_XY& PXY= PIXELS_XY::instance();
1262
1263 os << endl; os << " contenu des tableaux conversions "<<endl;
1264 for(int i=0; i < 5; i++)
1265 {
1266 os<<PXY.pix2x_(i)<<", "<<PXY.pix2y_(i)<<", "<<PXY.x2pix_(i)<<", "<<PXY.y2pix_(i)<<endl;
1267 }
1268 os << endl;
1269
1270 os << " les parametres des modules anafast et synfast " <<endl;
1271 os << " nlmax, nmmax & iseed= " <<nlmax_<<", "<<nmmax_<<", "<<iseed_<<endl;
1272 os << " fwhm, quadr & cut = "<<fwhm_<<", "<<quadrupole_<<", "<<sym_cut_deg_<<endl;
1273 os << " powfile= " << powFile_<<endl;
1274}
1275
1276//*******************************************************************
1277// Class FIO_SphereGorski<T>
1278// Les objets delegues pour la gestion de persistance
1279//*******************************************************************
1280
1281template <class T>
1282FIO_SphereGorski<T>::FIO_SphereGorski()
1283{
1284 dobj= new SphereGorski<T>;
1285 ownobj= true;
1286}
1287
1288template <class T>
1289FIO_SphereGorski<T>::FIO_SphereGorski(string const& filename)
1290{
1291 dobj= new SphereGorski<T>;
1292 ownobj= true;
1293 Read(filename);
1294}
1295
1296template <class T>
1297FIO_SphereGorski<T>::FIO_SphereGorski(const SphereGorski<T>& obj)
1298{
1299 dobj= new SphereGorski<T>(obj);
1300 ownobj= true;
1301}
1302
1303template <class T>
1304FIO_SphereGorski<T>::FIO_SphereGorski(SphereGorski<T>* obj)
1305{
1306 dobj= obj;
1307 ownobj= false;
1308}
1309
1310template <class T>
1311FIO_SphereGorski<T>::~FIO_SphereGorski()
1312{
1313 if (ownobj && dobj) delete dobj;
1314}
1315
1316template <class T>
1317AnyDataObj* FIO_SphereGorski<T>::DataObj()
1318{
1319 return(dobj);
1320}
1321
1322template <class T>
1323void FIO_SphereGorski<T>::ReadSelf(PInPersist& is)
1324{
1325 cout << " FIO_SphereGorski:: ReadSelf " << endl;
1326
1327 if(dobj == NULL)
1328 {
1329 dobj= new SphereGorski<T>;
1330 }
1331
1332 // Pour savoir s'il y avait un DVList Info associe
1333 char strg[256];
1334 is.GetLine(strg, 255);
1335 bool hadinfo= false;
1336 if(strncmp(strg+strlen(strg)-7, "HasInfo", 7) == 0) hadinfo= true;
1337 if(hadinfo)
1338 { // Lecture eventuelle du DVList Info
1339 is >> dobj->Info();
1340 }
1341
1342 int nSide;
1343 is.GetI4(nSide);
1344 dobj->setSizeIndex(nSide);
1345
1346 int nPix;
1347 is.GetI4(nPix);
1348 dobj->setNbPixels(nPix);
1349
1350 double Omega;
1351 is.GetR8(Omega);
1352 dobj->setPixSolAngle(Omega);
1353
1354 T* pixels= new T[nPix];
1355 PIOSReadArray(is, pixels, nPix);
1356 dobj->setDataBlock(pixels, nPix);
1357 delete [] pixels;
1358
1359 int nlmax,nmmax,iseed;
1360 is.GetI4(nlmax);
1361 is.GetI4(nmmax);
1362 is.GetI4(iseed);
1363
1364 float fwhm,quadr,cut;
1365 is.GetR4(fwhm);
1366 is.GetR4(quadr);
1367 is.GetR4(cut);
1368
1369 char powfl[128];
1370 is.GetLine(powfl, 127);
1371
1372 dobj->setParafast(nlmax,nmmax,iseed,fwhm,quadr,cut,powfl);
1373}
1374
1375template <class T>
1376void FIO_SphereGorski<T>::WriteSelf(POutPersist& os) const
1377{
1378 cout << " FIO_SphereGorski:: WriteSelf " << endl;
1379
1380 if(dobj == NULL)
1381 {
1382 cout << " WriteSelf:: dobj= null " << endl;
1383 return;
1384 }
1385
1386 char strg[256];
1387 int nSide= dobj->SizeIndex();
1388 int nPix = dobj->NbPixels();
1389
1390 if(dobj->ptrInfo())
1391 {
1392 sprintf(strg,"SphereGorski: NSide=%6d NPix=%9d HasInfo",nSide,nPix);
1393 os.PutLine(strg);
1394 os << dobj->Info();
1395 }
1396 else
1397 {
1398 sprintf(strg,"SphereGorski: NSide=%6d NPix=%9d ",nSide,nPix);
1399 os.PutLine(strg);
1400 }
1401
1402 os.PutI4(nSide);
1403 os.PutI4(nPix);
1404 os.PutR8(dobj->PixSolAngle(0));
1405
1406 PIOSWriteArray(os,(dobj->getDataBlock())->Data(), nPix);
1407
1408 int nlmax,nmmax,iseed;
1409 float fwhm,quadr,cut;
1410 dobj->getParafast(nlmax,nmmax,iseed,fwhm,quadr,cut);
1411 os.PutI4(nlmax);
1412 os.PutI4(nmmax);
1413 os.PutI4(iseed);
1414 os.PutR4(fwhm);
1415 os.PutR4(quadr);
1416 os.PutR4(cut);
1417
1418 char powfl[128];
1419 dobj->powfile(powfl);
1420 os.PutLine(powfl);
1421}
1422
1423#ifdef __CXX_PRAGMA_TEMPLATES__
1424#pragma define_template SphereGorski<double>
1425#pragma define_template SphereGorski<float>
1426#pragma define_template SphereGorski< complex<float> >
1427#pragma define_template SphereGorski< complex<double> >
1428#pragma define_template FIO_SphereGorski<double>
1429#pragma define_template FIO_SphereGorski<float>
1430#pragma define_template FIO_SphereGorski< complex<float> >
1431#pragma define_template FIO_SphereGorski< complex<double> >
1432#endif
1433#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1434template class SphereGorski<double>;
1435template class SphereGorski<float>;
1436template class SphereGorski< complex<float> >;
1437template class SphereGorski< complex<double> >;
1438template class FIO_SphereGorski<double>;
1439template class FIO_SphereGorski<float>;
1440template class FIO_SphereGorski< complex<float> >;
1441template class FIO_SphereGorski< complex<double> >;
1442#endif
1443
Note: See TracBrowser for help on using the repository browser.