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