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

Last change on this file since 3115 was 3115, checked in by ansari, 19 years ago

Creation initiale du groupe Cosmo avec le repertoire SimLSS de
simulation de distribution de masse 3D des galaxies par CMV+Rz
18/12/2006

File size: 20.5 KB
Line 
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//-------------------------------------------------------
44void GeneFluct3D::SetSize(int nx,int ny,int nz,double dx,double dy,double dz)
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_);
128 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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
142 int lmod = Nx_/10; if(lmod<1) lmod=1;
143 for(int i=0;i<Nx_;i++) {
144 int ii = (i>Nx_/2) ? Nx_-i : i;
145 double kx = ii*Dkx_; kx *= kx;
146 if(lp>1 && i%lmod==0) cout<<"i="<<i<<" ii="<<ii<<endl;
147 for(int j=0;j<Ny_;j++) {
148 int jj = (j>Ny_/2) ? Ny_-j : j;
149 double ky = jj*Dky_; ky *= ky;
150 for(int l=0;l<NCz_;l++) {
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 ---");
211 int lmod = Nx_/10; if(lmod<1) lmod=1;
212 for(int i=0;i<Nx_;i++) {
213 int ii = (i>Nx_/2) ? Nx_-i : i;
214 double kx = ii*Dkx_; kx *= kx;
215 if(lp>1 && i%lmod==0) cout<<"i="<<i<<" ii="<<ii<<endl;
216 for(int j=0;j<Ny_;j++) {
217 int jj = (j>Ny_/2) ? Ny_-j : j;
218 double ky = jj*Dky_; ky *= ky;
219 for(int l=0;l<NCz_;l++) {
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
244int GeneFluct3D::manage_coefficients(void)
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
251 int nreal = 0;
252 for(int kk=0;kk<2;kk++) {
253 int k=0; // continu
254 if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;} // Nyquist
255 for(int jj=0;jj<2;jj++) {
256 int j=0;
257 if(jj==1) {if( Ny_%2!=0) continue; else j = Ny_/2;}
258 for(int ii=0;ii<2;ii++) {
259 int i=0;
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
273 int nconj1 = 0;
274 for(int kk=0;kk<2;kk++) {
275 int k=0; // continu
276 if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;} // Nyquist
277 for(int jj=0;jj<2;jj++) { // selon j
278 int j=0;
279 if(jj==1) {if( Ny_%2!=0) continue; else j = Ny_/2;}
280 for(int i=1;i<(Nx_+1)/2;i++) {
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 }
287 for(int ii=0;ii<2;ii++) {
288 int i=0;
289 if(ii==1) {if( Nx_%2!=0) continue; else i = Nx_/2;}
290 for(int j=1;j<(Ny_+1)/2;j++) {
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
301 int nconj2 = 0;
302 for(int kk=0;kk<2;kk++) {
303 int k=0; // continu
304 if(kk==1) {if(Nz_%2!=0) continue; else k = Nz_/2;} // Nyquist
305 for(int j=1;j<(Ny_+1)/2;j++) {
306 if(Ny_%2==0 && j==Ny_/2) continue; // on ne retraite pas nyquist en j
307 for(int i=1;i<Nx_;i++) {
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.;
327 for(int l=0;l<NCz_;l++)
328 for(int j=0;j<Ny_;j++)
329 for(int i=0;i<Nx_;i++) s2 += MODULE2(T_(l,j,i));
330
331 double s20 = 0.;
332 for(int j=0;j<Ny_;j++)
333 for(int i=0;i<Nx_;i++) s20 += MODULE2(T_(0,j,i));
334
335 double s2n = 0.;
336 if(Nz_%2==0)
337 for(int j=0;j<Ny_;j++)
338 for(int i=0;i<Nx_;i++) s2n += MODULE2(T_(NCz_-1,j,i));
339
340 return 2.*s2 -s20 -s2n;
341}
342
343//-------------------------------------------------------------------
344void GeneFluct3D::FilterByPixel(void)
345// Filtrage par la fonction fenetre du pixel (parallelepipede)
346// TF = 1/(dx*dy*dz)*Int[{0,dx},{0,dy},{0,dz}]
347// e^(ik_x*x) e^(ik_y*y) e^(ik_z*z) dxdydz
348// |TF|^2 = 2*(1-cos(k_x*dx)/dx^2/k_x^2 * (idem dy) * (idem dz)
349// et on traite la divergence en K_x = 0:
350// 2*(1-cos(k*d)/d^2/k^2 ~= 1 - (k*d)^2/12 *[1 - (k*d)^2/30]
351{
352 int lp=2;
353 if(lp>1) PrtTim("--- FilterByPixel: before ---");
354
355 for(int i=0;i<Nx_;i++) {
356 int ii = (i>Nx_/2) ? Nx_-i : i;
357 double kx = ii*Dkx_ *Dx_;
358 double pkx2 = pixelfilter(kx);
359 for(int j=0;j<Ny_;j++) {
360 int jj = (j>Ny_/2) ? Ny_-j : j;
361 double ky = jj*Dky_ *Dy_;
362 double pky2 = pixelfilter(ky);
363 for(int l=0;l<NCz_;l++) {
364 double kz = l*Dkz_ *Dz_;
365 double pkz2 = pixelfilter(kz);
366 T_(l,j,i) *= pkx2*pky2*pkz2;
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_;
403 for(int i=0;i<Nx_;i++)
404 for(int j=0;j<Ny_;j++)
405 for(int l=0;l<NCz_;l++) T_(l,j,i) /= complex<r_8>(v);
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
423 for(int i=0;i<Nx_;i++) {
424 int ii = (i>Nx_/2) ? Nx_-i : i;
425 double kx = ii*Dkx_; kx *= kx;
426 for(int j=0;j<Ny_;j++) {
427 int jj = (j>Ny_/2) ? Ny_-j : j;
428 double ky = jj*Dky_; ky *= ky;
429 for(int l=0;l<NCz_;l++) {
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));
454 int dnx = int(R/Dx_+0.5); if(dnx<=0) dnx = 1;
455 int dny = int(R/Dy_+0.5); if(dny<=0) dny = 1;
456 int dnz = int(R/Dz_+0.5); if(dnz<=0) dnz = 1;
457 cout<<"dnx="<<dnx<<" dny="<<dny<<" dnz="<<dnz<<endl;
458
459 double sum=0., sum2=0., r2 = R*R; size_t nsum=0;
460
461 for(int i=dnx;i<Nx_-dnx;i+=dnx) {
462 for(int j=dny;j<Ny_-dny;j+=dny) {
463 for(int l=dnz;l<Nz_-dnz;l+=dnz) {
464 double s=0.; size_t n=0;
465 for(int ii=i-dnx;ii<=i+dnx;ii++) {
466 double x = (ii-i)*Dx_; x *= x;
467 for(int jj=j-dny;jj<=j+dny;jj++) {
468 double y = (jj-j)*Dy_; y *= y;
469 for(int ll=l-dnz;ll<=l+dnz;ll++) {
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;
505 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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
523 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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;
547 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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
564 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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.;
597 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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.;
618 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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.;
648 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
649 size_t ip = l+NTz_*(j+Ny_*i);
650 double v = data[ip];
651 if(v>0.) {
652 int ngal = int(v+0.1);
653 data[ip] = 0.;
654 for(int i=0;i<ngal;i++) {
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
677 for(int i=0;i<Nx_;i++) for(int j=0;j<Ny_;j++) for(int l=0;l<Nz_;l++) {
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.