source: Sophya/trunk/Cosmo/SimLSS/genefluct3d.cc@ 3129

Last change on this file since 3129 was 3129, checked in by cmv, 19 years ago

passage int en long aux endroits importants cmv 11/01/07

File size: 20.6 KB
RevLine 
[3115]1#include "sopnamsp.h"
2#include "machdefs.h"
3#include <iostream>
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7#include <math.h>
8#include <unistd.h>
9
10#include "timing.h"
11#include "tarray.h"
12#include "pexceptions.h"
13#include "perandom.h"
14#include "srandgen.h"
15
16#include "constcosmo.h"
17#include "integfunc.h"
18#include "geneutils.h"
19
20#include "genefluct3d.h"
21
22//#define FFTW_THREAD
23
24#define MODULE2(_x_) ((double)((_x_).real()*(_x_).real() + (_x_).imag()*(_x_).imag()))
25
26//-------------------------------------------------------
27GeneFluct3D::GeneFluct3D(TArray< complex<r_8 > >& T,PkSpectrumZ& pkz)
28 : T_(T) , pkz_(pkz)
29{
30 SetNThread();
31 SetSize(1,-1,1,1.,-1.,1.);
32}
33
34GeneFluct3D::~GeneFluct3D(void)
35{
36 fftw_destroy_plan(pf_);
37 fftw_destroy_plan(pb_);
38#ifdef FFTW_THREAD
39 if(nthread_>0) fftw_cleanup_threads();
40#endif
41}
42
43//-------------------------------------------------------
[3129]44void GeneFluct3D::SetSize(long nx,long ny,long nz,double dx,double dy,double dz)
[3115]45{
46 if(nx<=0 || dx<=0. ) {
47 cout<<"GeneFluct3D::SetSize_Error: bad value(s)"<<endl;
48 throw ParmError("GeneFluct3D::SetSize_Error: bad value(s)");
49 }
50
51 Tcontent_ = 0;
52
53 // Les taille des tableaux
54 Nx_ = nx;
55 Ny_ = ny; if(Ny_ <= 0) Ny_ = Nx_;
56 Nz_ = nz; if(Nz_ <= 0) Nz_ = Nx_;
57 NRtot_ = Nx_*Ny_*Nz_; // nombre de pixels dans le survey
58 NCz_ = Nz_/2 +1;
59 NTz_ = 2*NCz_;
60 SzK_[2] = Nx_; SzK_[1] = Ny_; SzK_[0] = NCz_; // a l'envers
61
62 // le pas dans l'espace (Mpc)
63 Dx_ = dx;
64 Dy_ = dy; if(Dy_ <= 0.) Dy_ = Dx_;
65 Dz_ = dz; if(Dz_ <= 0.) Dz_ = Dx_;
66 dVol_ = Dx_*Dy_*Dz_;
67 Vol_ = (Nx_*Dx_)*(Ny_*Dy_)*(Nz_*Dz_);
68
69 // Le pas dans l'espace de Fourier (Mpc^-1)
70 Dkx_ = 2.*M_PI/(Nx_*Dx_);
71 Dky_ = 2.*M_PI/(Ny_*Dy_);
72 Dkz_ = 2.*M_PI/(Nz_*Dz_);
73 Dk3_ = Dkx_*Dky_*Dkz_;
74
75 // La frequence de Nyquist en k (Mpc^-1)
76 Knyqx_ = M_PI/Dx_;
77 Knyqy_ = M_PI/Dy_;
78 Knyqz_ = M_PI/Dz_;
79
80}
81
82//-------------------------------------------------------
83void GeneFluct3D::Print(void)
84{
85 cout<<"GeneFluct3D(T_typ="<<Tcontent_<<"): z="<<pkz_.GetZ()<<endl;
86 cout<<"Space Size : nx="<<Nx_<<" ny="<<Ny_<<" nz="<<Nz_<<" ("<<NTz_<<") size="
87 <<NRtot_<<endl;
88 cout<<" Resol: dx="<<Dx_<<" dy="<<Dy_<<" dz="<<Dz_<<" Mpc"
89 <<", dVol="<<dVol_<<", Vol="<<Vol_<<" Mpc^3"<<endl;
90 cout<<"Fourier Size : nx="<<Nx_<<" ny="<<Ny_<<" nz="<<NCz_<<endl;
91 cout<<" Resol: dkx="<<Dkx_<<" dky="<<Dky_<<" dkz="<<Dkz_<<" Mpc^-1"
92 <<", Dk3="<<Dk3_<<" Mpc^-3"<<endl;
93 cout<<" (2Pi/k: "<<2.*M_PI/Dkx_<<" "<<2.*M_PI/Dky_<<" "<<2.*M_PI/Dkz_<<" Mpc)"<<endl;
94 cout<<" Nyquist: kx="<<Knyqx_<<" ky="<<Knyqy_<<" kz="<<Knyqz_<<" Mpc^-1"
95 <<", Kmax="<<GetKmax()<<" Mpc^-1"<<endl;
96 cout<<" (2Pi/k: "<<2.*M_PI/Knyqx_<<" "<<2.*M_PI/Knyqy_<<" "<<2.*M_PI/Knyqz_<<" Mpc)"<<endl;
97}
98
99//-------------------------------------------------------
100void GeneFluct3D::ComputeFourier0(void)
101// cf ComputeFourier() mais avec autre methode de realisation du spectre
102// (attention on fait une fft pour realiser le spectre)
103{
104 int lp=2;
105
106 T_.ReSize(3,SzK_);
107 T_.SetMemoryMapping(BaseArray::CMemoryMapping);
108
109 // --- Initialisation de fftw3 (attention data est sur-ecrit a l'init)
110 if(lp>1) PrtTim("--- ComputeFourier0: before fftw_plan ---");
111 fftw_complex *fdata = (fftw_complex *) (&T_(0,0,0));
112 double *data = (double *) (&T_(0,0,0));
113#ifdef FFTW_THREAD
114 if(nthread_>0) {
115 cout<<"Computing with "<<nthread_<<" threads"<<endl;
116 fftw_init_threads();
117 fftw_plan_with_nthreads(nthread_);
118 }
119#endif
120 pf_ = fftw_plan_dft_r2c_3d(Nx_,Ny_,Nz_,data,fdata,FFTW_ESTIMATE);
121 pb_ = fftw_plan_dft_c2r_3d(Nx_,Ny_,Nz_,fdata,data,FFTW_ESTIMATE);
122 if(lp>1) PrtTim("--- ComputeFourier0: after fftw_plan ---");
123
124 // --- realisation d'un tableau de tirage gaussiens
125 if(lp>1) PrtTim("--- ComputeFourier0: before gaussian filling ---");
126 // On tient compte du pb de normalisation de FFTW3
127 double sntot = sqrt((double)NRtot_);
[3129]128 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]129 size_t ip = l+NTz_*(j+Ny_*i);
130 data[ip] = NorRand()/sntot;
131 }
132 if(lp>1) PrtTim("--- ComputeFourier0: after gaussian filling ---");
133
134 // --- realisation d'un tableau de tirage gaussiens
135 if(lp>1) PrtTim("--- ComputeFourier0: before fft real ---");
136 fftw_execute(pf_);
137 if(lp>1) PrtTim("--- ComputeFourier0: after fft real ---");
138
139 // --- On remplit avec une realisation
140 if(lp>1) PrtTim("--- ComputeFourier0: before Fourier realization filling ---");
141 T_(0,0,0) = complex<r_8>(0.); // on coupe le continue et on l'initialise
[3129]142 long lmod = Nx_/10; if(lmod<1) lmod=1;
143 for(long i=0;i<Nx_;i++) {
144 long ii = (i>Nx_/2) ? Nx_-i : i;
[3115]145 double kx = ii*Dkx_; kx *= kx;
146 if(lp>1 && i%lmod==0) cout<<"i="<<i<<" ii="<<ii<<endl;
[3129]147 for(long j=0;j<Ny_;j++) {
148 long jj = (j>Ny_/2) ? Ny_-j : j;
[3115]149 double ky = jj*Dky_; ky *= ky;
[3129]150 for(long l=0;l<NCz_;l++) {
[3115]151 double kz = l*Dkz_; kz *= kz;
152 if(i==0 && j==0 && l==0) continue; // Suppression du continu
153 double k = sqrt(kx+ky+kz);
154 // cf normalisation: Peacock, Cosmology, formule 16.38 p504
155 double pk = pkz_(k)/Vol_;
156 // ici pas de "/2" a cause de la remarque ci-dessus
157 T_(l,j,i) *= sqrt(pk);
158 }
159 }
160 }
161 if(lp>1) PrtTim("--- ComputeFourier0: after Fourier realization filling ---");
162
163 double p = compute_power_carte();
164 cout<<"Puissance dans la realisation: "<<p<<endl;
165 if(lp>1) PrtTim("--- ComputeFourier0: after Computing power ---");
166
167 Tcontent_ = 1;
168
169}
170
171//-------------------------------------------------------
172void GeneFluct3D::ComputeFourier(void)
173// Calcule une realisation du spectre "pkz_"
174// Attention: dans TArray le premier indice varie le + vite
175// Explication normalisation: see Coles & Lucchin, Cosmology, p264-265
176// FFTW3: on note N=Nx*Ny*Nz
177// f --(FFT)--> F = TF(f) --(FFT^-1)--> fb = TF^-1(F) = TF^-1(TF(f))
178// sum(f(x_i)^2) = S
179// sum(F(nu_i)^2) = S*N
180// sum(fb(x_i)^2) = S*N^2
181{
182 int lp=2;
183
184 // --- Dimensionnement du tableau
185 // ATTENTION: TArray adresse en memoire a l'envers du C
186 // Tarray(n1,n2,n3) == Carray[n3][n2][n1]
187 T_.ReSize(3,SzK_);
188 T_.SetMemoryMapping(BaseArray::CMemoryMapping);
189
190 // --- Initialisation de fftw3 (attention data est sur-ecrit a l'init)
191 if(lp>1) PrtTim("--- ComputeFourier: before fftw_plan ---");
192 fftw_complex *fdata = (fftw_complex *) (&T_(0,0,0));
193 double *data = (double *) (&T_(0,0,0));
194#ifdef FFTW_THREAD
195 if(nthread_>0) {
196 cout<<"Computing with "<<nthread_<<" threads"<<endl;
197 fftw_init_threads();
198 fftw_plan_with_nthreads(nthread_);
199 }
200#endif
201 pf_ = fftw_plan_dft_r2c_3d(Nx_,Ny_,Nz_,data,fdata,FFTW_ESTIMATE);
202 pb_ = fftw_plan_dft_c2r_3d(Nx_,Ny_,Nz_,fdata,data,FFTW_ESTIMATE);
203 //fftw_print_plan(pb_); cout<<endl;
204 if(lp>1) PrtTim("--- ComputeFourier: after fftw_plan ---");
205
206 // --- RaZ du tableau
207 T_ = complex<r_8>(0.);
208
209 // --- On remplit avec une realisation
210 if(lp>1) PrtTim("--- ComputeFourier: before Fourier realization filling ---");
[3129]211 long lmod = Nx_/10; if(lmod<1) lmod=1;
212 for(long i=0;i<Nx_;i++) {
213 long ii = (i>Nx_/2) ? Nx_-i : i;
[3115]214 double kx = ii*Dkx_; kx *= kx;
215 if(lp>1 && i%lmod==0) cout<<"i="<<i<<" ii="<<ii<<endl;
[3129]216 for(long j=0;j<Ny_;j++) {
217 long jj = (j>Ny_/2) ? Ny_-j : j;
[3115]218 double ky = jj*Dky_; ky *= ky;
[3129]219 for(long l=0;l<NCz_;l++) {
[3115]220 double kz = l*Dkz_; kz *= kz;
221 if(i==0 && j==0 && l==0) continue; // Suppression du continu
222 double k = sqrt(kx+ky+kz);
223 // cf normalisation: Peacock, Cosmology, formule 16.38 p504
224 double pk = pkz_(k)/Vol_;
225 // Explication de la division par 2: voir perandom.cc
226 // ou egalement Coles & Lucchin, Cosmology formula 13.7.2 p279
227 T_(l,j,i) = ComplexGaussRan(sqrt(pk/2.));
228 }
229 }
230 }
231 if(lp>1) PrtTim("--- ComputeFourier: after Fourier realization filling ---");
232
233 manage_coefficients(); // gros effet pour les spectres que l'on utilise !
234 if(lp>1) PrtTim("--- ComputeFourier: after managing coefficients ---");
235
236 double p = compute_power_carte();
237 cout<<"Puissance dans la realisation: "<<p<<endl;
238 if(lp>1) PrtTim("--- ComputeFourier: after before Computing power ---");
239
240 Tcontent_ = 1;
241
242}
243
[3129]244long GeneFluct3D::manage_coefficients(void)
[3115]245// Take into account the real and complexe conjugate coefficients
246// because we want a realization of a real data in real space
247{
248 fftw_complex *fdata = (fftw_complex *) (&T_(0,0,0));
249
250 // 1./ Le Continu et Nyquist sont reels
[3129]251 long nreal = 0;
252 for(long kk=0;kk<2;kk++) {
253 long k=0; // continu
[3115]254 if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;} // Nyquist
[3129]255 for(long jj=0;jj<2;jj++) {
256 long j=0;
[3115]257 if(jj==1) {if( Ny_%2!=0) continue; else j = Ny_/2;}
[3129]258 for(long ii=0;ii<2;ii++) {
259 long i=0;
[3115]260 if(ii==1) {if( Nx_%2!=0) continue; else i = Nx_/2;}
261 size_t ip = k+NCz_*(j+Ny_*i);
262 //cout<<"i="<<i<<" j="<<j<<" k="<<k<<" = ("<<fdata[ip][0]<<","<<fdata[ip][1]<<")"<<endl;
263 fdata[ip][1] = 0.; fdata[ip][0] *= M_SQRT2;
264 nreal++;
265 }
266 }
267 }
268 cout<<"Number of forced real number ="<<nreal<<endl;
269
270 // 2./ Les elements complexe conjugues (tous dans le plan k=0,Nyquist)
271
272 // a./ les lignes et colonnes du continu et de nyquist
[3129]273 long nconj1 = 0;
274 for(long kk=0;kk<2;kk++) {
275 long k=0; // continu
[3115]276 if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;} // Nyquist
[3129]277 for(long jj=0;jj<2;jj++) { // selon j
278 long j=0;
[3115]279 if(jj==1) {if( Ny_%2!=0) continue; else j = Ny_/2;}
[3129]280 for(long i=1;i<(Nx_+1)/2;i++) {
[3115]281 size_t ip = k+NCz_*(j+Ny_*i);
282 size_t ip1 = k+NCz_*(j+Ny_*(Nx_-i));
283 fdata[ip1][0] = fdata[ip][0]; fdata[ip1][1] = -fdata[ip][1];
284 nconj1++;
285 }
286 }
[3129]287 for(long ii=0;ii<2;ii++) {
288 long i=0;
[3115]289 if(ii==1) {if( Nx_%2!=0) continue; else i = Nx_/2;}
[3129]290 for(long j=1;j<(Ny_+1)/2;j++) {
[3115]291 size_t ip = k+NCz_*(j+Ny_*i);
292 size_t ip1 = k+NCz_*((Ny_-j)+Ny_*i);
293 fdata[ip1][0] = fdata[ip][0]; fdata[ip1][1] = -fdata[ip][1];
294 nconj1++;
295 }
296 }
297 }
298 cout<<"Number of forced conjugate on cont+nyq ="<<nconj1<<endl;
299
300 // b./ les lignes et colonnes hors continu et de nyquist
[3129]301 long nconj2 = 0;
302 for(long kk=0;kk<2;kk++) {
303 long k=0; // continu
[3115]304 if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;} // Nyquist
[3129]305 for(long j=1;j<(Ny_+1)/2;j++) {
[3115]306 if(Ny_%2==0 && j==Ny_/2) continue; // on ne retraite pas nyquist en j
[3129]307 for(long i=1;i<Nx_;i++) {
[3115]308 if(Nx_%2==0 && i==Nx_/2) continue; // on ne retraite pas nyquist en i
309 size_t ip = k+NCz_*(j+Ny_*i);
310 size_t ip1 = k+NCz_*((Ny_-j)+Ny_*(Nx_-i));
311 fdata[ip1][0] = fdata[ip][0]; fdata[ip1][1] = -fdata[ip][1];
312 nconj2++;
313 }
314 }
315 }
316 cout<<"Number of forced conjugate hors cont+nyq ="<<nconj2<<endl;
317
318 cout<<"Check: ddl= "<<NRtot_<<" =?= "<<2*(Nx_*Ny_*NCz_-nconj1-nconj2)-8<<endl;
319
320 return nreal+nconj1+nconj2;
321}
322
323double GeneFluct3D::compute_power_carte(void)
324// Calcul la puissance de la realisation du spectre Pk
325{
326 double s2 = 0.;
[3129]327 for(long l=0;l<NCz_;l++)
328 for(long j=0;j<Ny_;j++)
329 for(long i=0;i<Nx_;i++) s2 += MODULE2(T_(l,j,i));
[3115]330
331 double s20 = 0.;
[3129]332 for(long j=0;j<Ny_;j++)
333 for(long i=0;i<Nx_;i++) s20 += MODULE2(T_(0,j,i));
[3115]334
335 double s2n = 0.;
336 if(Nz_%2==0)
[3129]337 for(long j=0;j<Ny_;j++)
338 for(long i=0;i<Nx_;i++) s2n += MODULE2(T_(NCz_-1,j,i));
[3115]339
340 return 2.*s2 -s20 -s2n;
341}
342
343//-------------------------------------------------------------------
344void GeneFluct3D::FilterByPixel(void)
345// Filtrage par la fonction fenetre du pixel (parallelepipede)
[3120]346// TF = 1/(dx*dy*dz)*Int[{-dx/2,dx/2},{-dy/2,dy/2},{-dz/2,dz/2}]
[3115]347// e^(ik_x*x) e^(ik_y*y) e^(ik_z*z) dxdydz
[3120]348// = 2/(k_x*dx) * sin(k_x*dx/2) * (idem y) * (idem z)
349// Gestion divergence en 0: sin(y)/y = 1 - y^2/6*(1-y^2/20)
350// avec y = k_x*dx/2
[3115]351{
352 int lp=2;
353 if(lp>1) PrtTim("--- FilterByPixel: before ---");
354
[3129]355 for(long i=0;i<Nx_;i++) {
356 long ii = (i>Nx_/2) ? Nx_-i : i;
[3120]357 double kx = ii*Dkx_ *Dx_/2;
358 double pkx = pixelfilter(kx);
[3129]359 for(long j=0;j<Ny_;j++) {
360 long jj = (j>Ny_/2) ? Ny_-j : j;
[3120]361 double ky = jj*Dky_ *Dy_/2;
362 double pky = pixelfilter(ky);
[3129]363 for(long l=0;l<NCz_;l++) {
[3120]364 double kz = l*Dkz_ *Dz_/2;
365 double pkz = pixelfilter(kz);
366 T_(l,j,i) *= pkx*pky*pkz;
[3115]367 }
368 }
369 }
370
371 if(lp>1) PrtTim("--- FilterByPixel: after ---");
372}
373
374//-------------------------------------------------------------------
375void GeneFluct3D::ComputeReal(void)
376// Calcule une realisation dans l'espace reel
377{
378 int lp=2;
379
380 if( Tcontent_==0 ) {
381 cout<<"GeneFluct3D::ComputeReal_Error: empty array"<<endl;
382 throw ParmError("GeneFluct3D::ComputeReal_Error: empty array");
383 }
384
385 // On fait la FFT
386 if(lp>1) PrtTim("--- ComputeReal: before fftw backward ---");
387 fftw_execute(pb_);
388 if(lp>1) PrtTim("--- ComputeReal: after fftw backward ---");
389
390 Tcontent_ = 2;
391}
392
393//-------------------------------------------------------------------
394void GeneFluct3D::ReComputeFourier(void)
395{
396 int lp=2;
397
398 // On fait la FFT
399 if(lp>1) PrtTim("--- ComputeReal: before fftw forward ---");
400 fftw_execute(pf_);
401 // On corrige du pb de la normalisation de FFTW3
402 double v = (double)NRtot_;
[3129]403 for(long i=0;i<Nx_;i++)
404 for(long j=0;j<Ny_;j++)
405 for(long l=0;l<NCz_;l++) T_(l,j,i) /= complex<r_8>(v);
[3115]406
407 Tcontent_ = 3;
408 if(lp>1) PrtTim("--- ComputeReal: after fftw forward ---");
409}
410
411//-------------------------------------------------------------------
412int GeneFluct3D::ComputeSpectrum(HProf& hp)
413// Compute spectrum from "T" and fill HProf "hp"
414// T : dans le format standard de GeneFuct3D: T(nz,ny,nx)
415// cad T(kz,ky,kx) avec 0<kz<kz_nyq -ky_nyq<ky<ky_nyq -kx_nyq<kx<kx_nyq
416{
417
418 if(hp.NBins()<0) return -1;
419 hp.Zero();
420 hp.SetErrOpt(false);
421
422 // Attention a l'ordre
[3129]423 for(long i=0;i<Nx_;i++) {
424 long ii = (i>Nx_/2) ? Nx_-i : i;
[3115]425 double kx = ii*Dkx_; kx *= kx;
[3129]426 for(long j=0;j<Ny_;j++) {
427 long jj = (j>Ny_/2) ? Ny_-j : j;
[3115]428 double ky = jj*Dky_; ky *= ky;
[3129]429 for(long l=0;l<NCz_;l++) {
[3115]430 double kz = l*Dkz_; kz *= kz;
431 double k = sqrt(kx+ky+kz);
432 double pk = MODULE2(T_(l,j,i));
433 hp.Add(k,pk);
434 }
435 }
436 }
437 hp.UpdateHisto();
438
439 // renormalize to directly compare to original spectrum
440 double norm = Vol_;
441 hp *= norm;
442
443 return 0;
444}
445
446//-------------------------------------------------------
447size_t GeneFluct3D::VarianceFrReal(double R,double& var)
448// Recompute MASS variance in spherical top-hat (rayon=R)
449{
450 int lp=2;
451 if(lp>1) PrtTim("--- VarianceFrReal: before computation ---");
452
453 double *data = (double *) (&T_(0,0,0));
[3129]454 long dnx = long(R/Dx_+0.5); if(dnx<=0) dnx = 1;
455 long dny = long(R/Dy_+0.5); if(dny<=0) dny = 1;
456 long dnz = long(R/Dz_+0.5); if(dnz<=0) dnz = 1;
[3115]457 cout<<"dnx="<<dnx<<" dny="<<dny<<" dnz="<<dnz<<endl;
458
459 double sum=0., sum2=0., r2 = R*R; size_t nsum=0;
460
[3129]461 for(long i=dnx;i<Nx_-dnx;i+=dnx) {
462 for(long j=dny;j<Ny_-dny;j+=dny) {
463 for(long l=dnz;l<Nz_-dnz;l+=dnz) {
[3115]464 double s=0.; size_t n=0;
[3129]465 for(long ii=i-dnx;ii<=i+dnx;ii++) {
[3115]466 double x = (ii-i)*Dx_; x *= x;
[3129]467 for(long jj=j-dny;jj<=j+dny;jj++) {
[3115]468 double y = (jj-j)*Dy_; y *= y;
[3129]469 for(long ll=l-dnz;ll<=l+dnz;ll++) {
[3115]470 double z = (ll-l)*Dz_; z *= z;
471 if(x+y+z>r2) continue;
472 size_t ip = ll+NTz_*(jj+Ny_*ii);
473 s += 1.+data[ip];
474 n++;
475 }
476 }
477 }
478 if(n>0) {sum += s; sum2 += s*s; nsum++;}
479 //cout<<i<<","<<j<<","<<l<<" n="<<n<<" s="<<s<<" sum="<<sum<<" sum2="<<sum2<<endl;
480 }
481 }
482 }
483
484 if(nsum<=1) {var=0.; return nsum;}
485
486 sum /= nsum;
487 sum2 = sum2/nsum - sum*sum;
488 if(lp) cout<<"VarianceFrReal: nsum="<<nsum<<" <M>="<<sum<<" <(M-<M>)^2>="<<sum2<<endl;
489
490 var = sum2/(sum*sum); // <dM>^2/<M>^2
491 if(lp) cout<<"sigmaR^2="<<var<<" -> "<<sqrt(var)<<endl;
492
493 if(lp>1) PrtTim("--- VarianceFrReal: after computation ---");
494 return nsum;
495}
496
497//-------------------------------------------------------
498size_t GeneFluct3D::NumberOfBad(double vmin,double vmax)
499// number of pixels outside of ]vmin,vmax[ extremites exclues
500// -> vmin and vmax are considered as bad
501{
502 double *data = (double *) (&T_(0,0,0));
503
504 size_t nbad = 0;
[3129]505 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]506 size_t ip = l+NTz_*(j+Ny_*i);
507 double v = data[ip];
508 if(v<=vmin || v>=vmax) nbad++;
509 }
510
511 return nbad;
512}
513
514size_t GeneFluct3D::MeanSigma2(double& rm,double& rs2,double vmin,double vmax)
515// mean,sigma^2 pour pixels avec valeurs ]vmin,vmax[ extremites exclues
516// -> mean and sigma^2 are NOT computed with pixels values vmin and vmax
517{
518 double *data = (double *) (&T_(0,0,0));
519
520 size_t n = 0;
521 rm = rs2 = 0.;
522
[3129]523 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]524 size_t ip = l+NTz_*(j+Ny_*i);
525 double v = data[ip];
526 if(v<=vmin || v>=vmax) continue;
527 rm += v;
528 rs2 += v*v;
529 n++;
530 }
531
532 if(n>1) {
533 rm /= (double)n;
534 rs2 = rs2/(double)n - rm*rm;
535 }
536
537 return n;
538}
539
540size_t GeneFluct3D::SetToVal(double vmin, double vmax,double val0)
541// set to "val0" if out of range ]vmin,vmax[ extremites exclues
542// -> vmin and vmax are set to val0
543{
544 double *data = (double *) (&T_(0,0,0));
545
546 size_t nbad = 0;
[3129]547 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]548 size_t ip = l+NTz_*(j+Ny_*i);
549 double v = data[ip];
550 if(v<=vmin || v>=vmax) {data[ip] = val0; nbad++;}
551 }
552
553 return nbad;
554}
555
556//-------------------------------------------------------
557void GeneFluct3D::TurnFluct2Mass(void)
558// d_rho/rho -> Mass (add one!)
559{
560 int lp=2;
561 if(lp>1) PrtTim("--- TurnFluct2Mass: before computation ---");
562 double *data = (double *) (&T_(0,0,0));
563
[3129]564 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]565 size_t ip = l+NTz_*(j+Ny_*i);
566 data[ip] += 1.;
567 }
568
569 Tcontent_ = 4;
570 if(lp>1) PrtTim("--- TurnFluct2Mass: after computation ---");
571}
572
573double GeneFluct3D::TurnMass2MeanNumber(double n_by_mpc3)
574// do NOT treate negative or nul values
575{
576 int lp=2;
577 if(lp>1) PrtTim("--- TurnMass2MeanNumber: before computation ---");
578
579 double *data = (double *) (&T_(0,0,0));
580
581 double m,s2;
582 size_t ngood = MeanSigma2(m,s2,0.,1e+200);
583 if(lp) cout<<"TurnMass2MeanNumber: ngood="<<ngood
584 <<" m="<<m<<" s2="<<s2<<" -> "<<sqrt(s2)<<endl;
585
586 // On doit mettre n*Vol galaxies dans notre survey
587 // On en met uniquement dans les pixels de masse >0.
588 // On NE met PAS a zero les pixels <0
589 // On renormalise sur les pixels>0 pour qu'on ait n*Vol galaxies
590 // comme on ne prend que les pixels >0, on doit normaliser
591 // a la moyenne de <1+d_rho/rho> sur ces pixels
592 // (rappel sur tout les pixels <1+d_rho/rho>=1)
593 double dn = n_by_mpc3*Vol_/m /(double)ngood; // nb de gal a mettre ds 1 px
594 if(lp) cout<<"galaxy density move from "
595 <<n_by_mpc3*Vol_/double(NRtot_)<<" to "<<dn<<" / pixel"<<endl;
596 double sum = 0.;
[3129]597 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]598 size_t ip = l+NTz_*(j+Ny_*i);
599 data[ip] *= dn; // par coherence on multiplie aussi les <=0
600 if(data[ip]>0.) sum += data[ip]; // mais on ne les compte pas
601 }
602 if(lp) cout<<sum<<" galaxies put into survey / "<<n_by_mpc3*Vol_<<endl;
603
604 Tcontent_ = 6;
605 if(lp>1) PrtTim("--- TurnMass2MeanNumber: after computation ---");
606 return sum;
607}
608
609double GeneFluct3D::ApplyPoisson(void)
610// do NOT treate negative or nul mass -> let it as it is
611{
612 int lp=2;
613 if(lp>1) PrtTim("--- ApplyPoisson: before computation ---");
614
615 double *data = (double *) (&T_(0,0,0));
616
617 double sum = 0.;
[3129]618 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]619 size_t ip = l+NTz_*(j+Ny_*i);
620 double v = data[ip];
621 if(v>0.) {
622 unsigned long dn = PoissRandLimit(v,10.);
623 data[ip] = (double)dn;
624 sum += (double)dn;
625 }
626 }
627 if(lp) cout<<sum<<" galaxies put into survey"<<endl;
628 Tcontent_ = 8;
629
630 if(lp>1) PrtTim("--- ApplyPoisson: before computation ---");
631 return sum;
632}
633
634double GeneFluct3D::TurnNGal2Mass(FunRan& massdist,bool axeslog)
635// do NOT treate negative or nul mass -> let it as it is
636// INPUT:
637// massdist : distribution de masse (m*dn/dm)
638// axeslog = false : retourne la masse
639// = true : retourne le log10(mass)
640// RETURN la masse totale
641{
642 int lp=2;
643 if(lp>1) PrtTim("--- TurnNGal2Mass: before computation ---");
644
645 double *data = (double *) (&T_(0,0,0));
646
647 double sum = 0.;
[3129]648 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]649 size_t ip = l+NTz_*(j+Ny_*i);
650 double v = data[ip];
651 if(v>0.) {
[3129]652 long ngal = long(v+0.1);
[3115]653 data[ip] = 0.;
[3129]654 for(long i=0;i<ngal;i++) {
[3115]655 double m = massdist.RandomInterp(); // massdist.Random();
656 if(axeslog) m = pow(10.,m);
657 data[ip] += m;
658 }
659 sum += data[ip];
660 }
661 }
662 if(lp) cout<<sum<<" MSol HI mass put into survey"<<endl;
663 Tcontent_ = 10;
664
665 if(lp>1) PrtTim("--- TurnNGal2Mass: after computation ---");
666 return sum;
667}
668
669void GeneFluct3D::AddNoise2Real(double snoise)
670// add noise to every pixels (meme les <=0 !)
671{
672 int lp=2;
673 if(lp>1) PrtTim("--- AddNoise2Real: before computation ---");
674
675 double *data = (double *) (&T_(0,0,0));
676
[3129]677 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) for(long l=0;l<Nz_;l++) {
[3115]678 size_t ip = l+NTz_*(j+Ny_*i);
679 data[ip] += snoise*NorRand();
680 }
681 Tcontent_ = 12;
682
683 if(lp>1) PrtTim("--- AddNoise2Real: after computation ---");
684}
Note: See TracBrowser for help on using the repository browser.