source: Sophya/trunk/Cosmo/SimLSS/cmvdefsurv.cc@ 3367

Last change on this file since 3367 was 3367, checked in by cmv, 18 years ago

gestion correct du lobe / taille pixel, evolution bruit Msol en fct de z, cmv 30/10/2007

File size: 37.7 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
[3350]10#include <vector>
11
[3115]12#include "constcosmo.h"
13#include "cosmocalc.h"
14#include "geneutils.h"
15#include "schechter.h"
[3350]16#include "pkspectrum.h"
[3115]17#include "planckspectra.h"
18
[3336]19/* --- Check Peterson at al. astro-ph/0606104 v1 (pb facteur sqrt(2) sur S/N !)
[3288]20cmvdefsurv -U 0.75,0.3,0.7,-1,1 -V 300 -z 0.0025,0.2,Z -x 1,90,A -O 400000,6000 -N 75 -M 6.156e9 -F 3 -2 1.5
[3193]21 --- */
22
[3365]23//-----------------------------------------------------------------------------------------------------------
[3115]24inline double rad2deg(double trad) {return trad/M_PI*180.;}
25inline double rad2min(double trad) {return trad/M_PI*180.*60.;}
26inline double rad2sec(double trad) {return trad/M_PI*180.*3600.;}
27inline double deg2rad(double tdeg) {return tdeg*M_PI/180.;}
28inline double min2rad(double tmin) {return tmin*M_PI/(180.*60.);}
29inline double sec2rad(double tsec) {return tsec*M_PI/(180.*3600.);}
30
[3367]31inline double sr2deg2(double asr) {return asr*pow(rad2deg(1.),2.);}
32inline double sr2min2(double asr) {return asr*pow(rad2min(1.),2.);}
33inline double deg22sr(double adeg) {return adeg*pow(deg2rad(1.),2.);}
34inline double min22sr(double amin) {return amin*pow(min2rad(1.),2.);}
35
[3365]36double LargeurDoppler(double v /* km/s */, double nu);
37double DzFrV(double v /* km/s */, double zred);
38double DNuFrDz(double dzred,double nu_at_0,double zred);
39double DzFrDNu(double dnu_at_0,double nu_at_0,double zred);
40double DzFrDNuApprox(double dnu_at_0,double nu_at_0,double zred);
41double ZFrLos(double loscom /* Mpc com */,CosmoCalc& univ);
42double AngsolEqTelescope(double nu /* GHz */,double telsurf /* m^2 */);
[3115]43void usage(void);
[3365]44
[3115]45void usage(void) {
[3365]46 cout<<"cmvdefsurv [options] -x dx,txlarg[,unit_x] -y dy,tylarg[,unit_y] -z dz,tzlarg[,unit_z] redshift"<<endl
[3287]47 <<"----------------"<<endl
[3365]48 <<" -x dx,txlarg[,unit_x] : resolution et largeur dans le plan transverse selon X"<<endl
49 <<" -y dy,tylarg[,unit_y] : idem selon Y, si <=0 meme que X"<<endl
50 <<" -z dz,tzlarg[,unit_z] : resolution et largeur sur la ligne de visee"<<endl
[3287]51 <<"-- Unites pour X-Y:"<<endl
[3365]52 <<" \'A\' : en angles (pour X-Y) : resolution=ArcMin, largeur=Degre (defaut)"<<endl
53 <<" \'Z\' : en redshift (pour Z) : resolution et largeur en redshift (defaut)"<<endl
54 <<" \'F\' : en frequence (pour Z) : resolution et largeur MHz"<<endl
55 <<" \'M\' : en longeur comobile (pour X-Y-Z) : resolution et largeur Mpc"<<endl
[3287]56 <<"----------------"<<endl
[3351]57 <<" -K k,dk,pk : k(Mpc^-1) dk(Mpc^-1) pk(a z=0 en Mpc^-3) pour estimer la variance cosmique"<<endl
[3350]58 <<"----------------"<<endl
[3352]59 <<" -O surf,tobs,eta : surface effective (m^2), temps d\'observation (s), efficacite d\'ouverture"<<endl
[3196]60 <<" -N Tsys : temperature du system (K)"<<endl
[3367]61 <<" -L lobearea,freqlob : angle solide du lobe d\'observation en arcmin^2 (def= celle du pixel)"<<endl
62 <<" pour la frequence freqlob en MHz"<<endl
63 <<" Si freqlob<=0 : la frequence de reference est celle du redshift etudie (def)"<<endl
[3287]64 <<" -2 : two polarisations measured"<<endl
[3193]65 <<" -M : masse de HI de reference (MSol), si <=0 mean schechter in pixel"<<endl
[3115]66 <<" -F : HI flux factor to be applied for our redshift"<<endl
[3193]67 <<" -V Vrot : largeur en vitesse (km/s) pour l\'elargissement doppler (def=300km/s)"<<endl
[3287]68 <<"----------------"<<endl
69 <<" -S Tsynch,indnu : temperature (K) synch a 408 Mhz, index d\'evolution"<<endl
70 <<" (indnu==0 no evolution with freq.)"<<endl
71 <<"----------------"<<endl
[3193]72 <<" -U h100,om0,ol0,w0,or0,flat : cosmology"<<endl
[3287]73 <<"----------------"<<endl
[3196]74 <<" -A <log10(S_agn)> : moyenne du flux AGN en Jy dans le pixel"<<endl
[3115]75 <<" redshift : redshift moyen du survey"<<endl
76 <<endl;
77}
78
[3365]79//-------------------------------------------------------------------------------------------
[3115]80int main(int narg,char *arg[])
81{
[3365]82 // ---
83 // --- Valeurs fixes ou par defaut
84 // ---
85
86 //-- WMAP
[3115]87 unsigned short flat = 0;
[3193]88 double h100=0.71, om0=0.267804, or0=7.9e-05*0., ol0=0.73,w0=-1.;
[3365]89
90 //-- Schechter HIMASS
[3115]91 double h75 = h100 / 0.75;
92 double nstar = 0.006*pow(h75,3.); //
[3343]93 double mstar = pow(10.,9.8); // MSol
[3115]94 double alpha = -1.37;
95 cout<<"nstar= "<<nstar<<" mstar="<<mstar<<" alpha="<<alpha<<endl;
96
[3365]97 double hifactor = 1.;
98 double vrot = 300.; // largeur en vitesse (km/s) pour elargissement doppler
99
100 //-- CMB , Synchrotron et AGN
101 double tcmb = T_CMB_Par;
[3115]102 // a 408 MHz (Haslam) + evol index a -2.6
103 double Tsynch408=60., nuhaslam=0.408, indnu = -2.6;
[3365]104 double lflux_agn = -3.;
105
106 //-- Appareillage
[3339]107 bool ya2polar = false;
[3336]108 double facpolar = 0.5; // si on mesure les 2 polars -> 1.0
[3365]109 double Tsys=75.;
110 double tobs = 6000., surftot = 400000., eta_eff = 1.;
111 // taille du lobe d'observation en arcmin pour la frequence
[3367]112 double lobearea0 = -1., lobefreq0 = -1.;
[3115]113
[3365]114 //-- Variance cosmique (default = standard SDSSII)
115 double kcosm = 0.05, dkcosm = -1., pkcosm = 40000.;
116
117 // --- Pour taille du survey
118 double dx=0., dy=-1., dz=0., txlarg=0., tylarg=-1., tzlarg=0.;
119 int nx=0, ny=0, nz=0;
120 char unit_x = 'A', unit_y = 'A', unit_z = 'Z';
121 double redshift0 = 0.;
122 double mhiref = -1.; // reference Mass en HI (def integ schechter)
123
124 // ---
[3115]125 // --- Decodage arguments
[3365]126 // ---
[3115]127 char c;
[3350]128 while((c = getopt(narg,arg,"h2x:y:z:N:S:O:M:F:V:U:L:A:K:")) != -1) {
[3115]129 switch (c) {
130 case 'x' :
[3365]131 sscanf(optarg,"%lf,%lf,%c",&dx,&txlarg,&unit_x);
[3115]132 break;
133 case 'y' :
[3365]134 sscanf(optarg,"%lf,%lf,%c",&dy,&tylarg,&unit_y);
[3115]135 break;
136 case 'z' :
[3365]137 sscanf(optarg,"%lf,%lf,%c",&dz,&tzlarg,&unit_z);
[3115]138 break;
139 case 'O' :
[3352]140 sscanf(optarg,"%lf,%lf,%lf",&surftot,&tobs,&eta_eff);
[3115]141 break;
[3193]142 case 'L' :
[3367]143 sscanf(optarg,"%lf,%lf",&lobearea0,&lobefreq0);
[3193]144 break;
[3196]145 case 'N' :
[3193]146 sscanf(optarg,"%lf",&Tsys);
[3115]147 break;
148 case 'S' :
149 sscanf(optarg,"%lf,%lf",&Tsynch408,&indnu);
150 break;
151 case 'M' :
152 sscanf(optarg,"%lf",&mhiref);
153 break;
154 case 'F' :
155 sscanf(optarg,"%lf",&hifactor);
156 break;
[3193]157 case 'V' :
158 sscanf(optarg,"%lf",&vrot);
[3115]159 break;
[3193]160 case 'U' :
[3248]161 sscanf(optarg,"%lf,%lf,%lf,%lf,%hu",&h100,&om0,&ol0,&w0,&flat);
[3193]162 break;
163 case '2' :
[3339]164 ya2polar = true;
[3193]165 facpolar = 1.0;
166 break;
[3196]167 case 'A' :
168 sscanf(optarg,"%lf",&lflux_agn);
169 break;
[3350]170 case 'K' :
[3351]171 sscanf(optarg,"%lf,%lf,%lf",&kcosm,&dkcosm,&pkcosm);
[3350]172 break;
[3115]173 case 'h' :
174 default :
175 usage(); return -1;
176 }
[3193]177 }
[3365]178 if(optind>=narg) {usage(); return -1;}
179 sscanf(arg[optind],"%lf",&redshift0);
180 if(redshift0<=0.) {cout<<"Redshift "<<redshift0<<" should be >0"<<endl; return -2;}
[3115]181
[3365]182 // ---
[3115]183 // --- Initialisation de la Cosmologie
[3365]184 // ---
185 CosmoCalc univ(flat,true,2.*redshift0);
186 double perc=0.01,dzinc=redshift0/100.,dzmax=dzinc*10.; unsigned short glorder=4;
[3115]187 univ.SetInteg(perc,dzinc,dzmax,glorder);
188 univ.SetDynParam(h100,om0,or0,ol0,w0);
[3365]189
[3350]190 GrowthFactor growth(om0,ol0);
[3115]191
[3365]192 // ---
[3115]193 // --- Mise en forme dans les unites appropriees
[3365]194 // ---
195 // ATTENTION: le cube de simulation est en Mpc avec des pixels de taille comobile fixe
[3287]196 cout<<"\n>>>>\n>>>> Geometrie\n>>>>"<<endl;
[3365]197 if(dy<=0. || tylarg<=0.) {dy=dx; tylarg=txlarg; unit_y=unit_x;}
198 cout<<"X values: resolution="<<dx<<" largeur="<<txlarg<<" unite="<<unit_x<<endl;
[3287]199 if(unit_x == 'A') {
[3365]200 nx = int(txlarg*60./dx+0.5);
201 dx = min2rad(dx)*univ.Dtrcom(redshift0);
202 txlarg = dx*nx;
[3287]203 } else if(unit_x == 'M') {
[3365]204 nx = int(txlarg/dx+0.5);
205 txlarg = dx*nx;
[3287]206 } else {
[3365]207 cout<<"Unknown unit_x = "<<unit_x<<endl; return -2;
[3287]208 }
[3365]209 cout<<"Y values: resolution="<<dy<<" largeur="<<tylarg<<" unite="<<unit_y<<endl;
[3287]210 if(unit_y == 'A') {
[3365]211 ny = int(tylarg*60./dy+0.5);
212 dy = min2rad(dy)*univ.Dtrcom(redshift0);
213 tylarg = dy*ny;
[3287]214 } else if(unit_y == 'M') {
[3365]215 ny = int(tylarg/dy+0.5);
216 tylarg = dy*ny;
[3115]217 } else {
[3365]218 cout<<"Unknown unit_y = "<<unit_y<<endl; return -2;
[3287]219 }
[3365]220 cout<<"Z values: resolution="<<dz<<" largeur="<<tzlarg<<" unite="<<unit_z<<endl;
[3287]221 if(unit_z == 'Z') {
[3365]222 nz = int(tzlarg/dz+0.5);
223 dz = dz*univ.Dhubble()/univ.E(redshift0);
224 tzlarg = dz*nz;
[3287]225 } else if(unit_z == 'M') {
[3365]226 nz = int(tzlarg/dz+0.5);
227 tzlarg = dz*nz;
228 } else if(unit_z == 'F') { // unite en MHz
229 nz = int(tzlarg/dz+0.5);
230 dz = DzFrDNu(dz,Fr_HyperFin_Par*1.e3,redshift0); //dzred
231 dz = dz*univ.Dhubble()/univ.E(redshift0);
232 tzlarg = dz*nz;
[3287]233 } else {
[3365]234 cout<<"Unknown unit_z = "<<unit_z<<endl; return -2;
[3115]235 }
[3287]236
[3365]237 // ---
238 // --- Calcul des valeurs au centre du cube et aux faces limites av/ar
239 // ---
240 cout<<"\n>>>>\n>>>> Cosmologie generale\n>>>>"<<endl;
241 double adtx[3], adty[3], atxlarg[3], atylarg[3];
242 double loscom[3], redshift[3], unplusz[3], dred[3], growthfac[3], rhocz[3];
243 double dang[3], dtrcom[3], dlum[3], dloscom[3], dlosdz[3];
244 double nuhiz[3], lambdahiz[3], dnuhiz[3];
245 double angsol_pix[3], angsol_tot[3];
[3115]246
[3365]247 redshift[0] = redshift0;
248 loscom[0] = univ.Dloscom(redshift0);
249 loscom[1] = loscom[0]-tzlarg/2.;
250 loscom[2] = loscom[0]+tzlarg/2.;
251 //if(loscom[1]<=0.) {cout<<"Lower distance limit "<<loscom[1]<<" should be >0"<<endl; return -3;}
252 for(int i=0;i<3;i++) {
253 double l = loscom[i]; if(l<=0.) l = dz/2.;
254 redshift[i] = ZFrLos(l,univ);
255 unplusz[i] = 1. + redshift[i];
256 growthfac[i] = growth(redshift[i]);
257 rhocz[i] = univ.Rhoc(redshift[i])*GCm3toMsolMpc3_Cst;;
258 dang[i] = univ.Dang(redshift[i]);
259 dtrcom[i] = univ.Dtrcom(redshift[i]);
260 dlum[i] = univ.Dlum(redshift[i]);
261 dloscom[i] = univ.Dloscom(redshift[i]);
262 dlosdz[i] = univ.Dhubble()/univ.E(redshift[i]);
263 dred[i] = dz/dlosdz[i];
264 adtx[i] = dx/dtrcom[i];
265 atxlarg[i] = adtx[i]*nx;
266 adty[i] = dy/dtrcom[i];
267 atylarg[i] = adty[i]*ny;
268 nuhiz[i] = Fr_HyperFin_Par / unplusz[i]; // GHz
269 lambdahiz[i] = SpeedOfLight_Cst*1000./(nuhiz[i]*1.e9); // m
270 dnuhiz[i] = DNuFrDz(dred[i],Fr_HyperFin_Par,redshift[i]); // GHz
271 angsol_pix[i] = AngSol(adtx[i]/2.,adty[i]/2.,M_PI/2.);
272 angsol_tot[i] = AngSol(atxlarg[i]/2.,atylarg[i]/2.,M_PI/2.);
273 }
274
[3115]275
[3365]276 cout<<"--- Cosmology for z = "<<0.<<endl;
277 univ.Print(0.);
278 double rhoc0 = univ.Rhoc(0.)*GCm3toMsolMpc3_Cst;
279
280 for(int i=0;i<3;i++) {
281 cout<<"\n--- Cosmology for z = "<<redshift[i]<<endl;
282 univ.Print(redshift[i]);
283 }
284
285 cout<<endl;
286 cout<<"Facteur de croissance lineaire = "<<growthfac[0]
287 <<" in ["<<growthfac[1]<<","<<growthfac[2]<<"]"<<endl;
288 cout<<" 1/(1+z) = "<<1./(1.+redshift[0])
289 <<" in ["<<1./(1.+redshift[1])<<","<<1./(1.+redshift[2])<<"]"<<endl;
290 cout<<"Facteur de croissance lineaire^2 = "<<growthfac[0]*growthfac[0]
291 <<" in ["<<growthfac[1]*growthfac[1]<<","<<growthfac[2]*growthfac[2]<<"]"<<endl;
292
293 cout<<"Rho_c (z=0) = "<<rhoc0<<", a z="<<0<<": "<<rhoc0<<" Msol/Mpc^3"<<endl;
294 cout<<"Rho_c a z = "<<rhocz[0]
295 <<" Msol/Mpc^3 in ["<<rhocz[1]<<","<<rhocz[2]<<"]"<<endl;
296
297 cout<<endl;
298 cout<<"dang= "<<dang[0]<<" Mpc in ["<<dang[1]<<","<<dang[2]<<"]"<<endl;
299 cout<<"dtrcom= "<<dtrcom[0]<<" Mpc com in ["<<dtrcom[1]<<","<<dtrcom[2]<<"]"<<endl;
300 cout<<"dlum= "<<dlum[0]<<" Mpc in ["<<dlum[1]<<","<<dlum[2]<<"]"<<endl;
301 cout<<"dloscom= "<<dloscom[0]<<" Mpc com in ["<<dloscom[1]<<","<<dloscom[2]<<"]"<<endl;
302 cout<<"dz=1 -> dlosdz= "<<dlosdz[0]<<" Mpc com in ["<<dlosdz[1]<<","<<dlosdz[2]<<"]"<<endl;
303 cout<<"1 Mpc los com -> dz = "<<1./dlosdz[0]<<" in ["<<1./dlosdz[1]<<","<<1./dlosdz[2]<<"]"<<endl;
304
305 cout<<endl;
306 for(int i=0;i<3;i++) {
307 cout<<"...Redshift="<<redshift[i]<<endl;
308 cout<<"1\" -> "<<dang[i]*sec2rad(1.)<<" Mpc = "<<dtrcom[i]*sec2rad(1.)<<" Mpc com"<<endl;
309 cout<<"1\' -> "<<dang[i]*min2rad(1.)<<" Mpc = "<<dtrcom[i]*min2rad(1.)<<" Mpc com"<<endl;
310 cout<<"1d -> "<<dang[i]*deg2rad(1.)<<" Mpc = "<<dtrcom[i]*deg2rad(1.)<<" Mpc com"<<endl;
311 cout<<"1 Mpc transv com -> "<<rad2sec(1./dtrcom[i])<<"\" = "
312 <<rad2min(1./dtrcom[i])<<" \' = "<<rad2deg(1./dtrcom[i])<<" d"<<endl;
313 cout<<"dz=1 -> dlosdz= "<<dlosdz[i]<<" Mpc com"<<endl;
314 cout<<"1 Mpc los com -> dz = "<<1./dlosdz[0]<<endl;
315 }
316
317 // ---
[3115]318 // --- Cosmolographie Transverse
[3365]319 // ---
[3287]320 cout<<"\n>>>>\n>>>> Cosmologie & Geometrie transverse\n>>>>"<<endl;
[3115]321
[3365]322 cout<<"dx = "<<dx<<", txlarg = "<<txlarg<<" Mpc (com), nx="<<nx<<endl;
323 cout<<"adtx = "<<adtx[0]<<" rd in ["<<adtx[1]<<","<<adtx[2]<<"]"<<endl;
324 cout<<" = "<<rad2min(adtx[0])<<"\' in ["<<rad2min(adtx[1])<<","<<rad2min(adtx[2])<<"]"<<endl;
325 cout<<"atxlarg = "<<atxlarg[0]<<" rd in ["<<atxlarg[1]<<","<<atxlarg[2]<<"]"<<endl;
326 cout<<" "<<rad2deg(atxlarg[0])<<" d in ["<<rad2deg(atxlarg[1])<<","<<rad2deg(atxlarg[2])<<"]"<<endl;
[3115]327
[3365]328 if(fabs(dx-dy)>1.e-20 && fabs(txlarg-tylarg)>1.e-20) {
329 cout<<"\ndy = "<<dy<<", tylarg = "<<tylarg<<" Mpc (com), ny="<<ny<<endl;
330 cout<<"adty = "<<adty[0]<<" rd in ["<<adty[1]<<","<<adty[2]<<"]"<<endl;
331 cout<<" = "<<rad2min(adty[0])<<"\' in ["<<rad2min(adty[1])<<","<<rad2min(adty[2])<<"]"<<endl;
332 cout<<"atylarg = "<<atylarg[0]<<" rd in ["<<atylarg[1]<<","<<atylarg[2]<<"]"<<endl;
333 cout<<" "<<rad2deg(atylarg[0])<<" d in ["<<rad2deg(atylarg[1])<<","<<rad2deg(atylarg[2])<<"]"<<endl;
334 }
[3115]335
[3365]336 // ---
[3115]337 // --- Cosmolographie Line of sight
[3365]338 // ---
[3287]339 cout<<"\n>>>>\n>>>> Cosmologie & Geometrie ligne de visee\n>>>>"<<endl;
[3365]340 cout<<"dz = "<<dz<<", tzlarg = "<<tzlarg<<" Mpc (com), nz="<<nz<<endl;
341 cout<<"Redshift = "<<redshift[0]<<" in ["<<redshift[1]<<","<<redshift[2]<<"]"<<endl;
342 cout<<"dred = "<<dred[0]<<" in ["<<dred[1]<<","<<dred[2]<<"]"<<endl;
343 cout<<"nu HI = "<<nuhiz[0]<<" GHz in ["<<nuhiz[1]<<","<<nuhiz[2]<<"]"<<endl;
344 cout<<"lambda HI = "<<lambdahiz[0]<<" m in ["<<lambdahiz[1]<<","<<lambdahiz[2]<<"]"<<endl;
345 cout<<"dnu HI= "<<dnuhiz[0]*1e3<<" MHz in ["<<dnuhiz[1]*1e3<<","<<dnuhiz[2]*1e3<<"]"<<endl;
[3115]346
[3365]347 // ---
348 // --- Volume
349 // ---
350 cout<<"\n>>>>\n>>>> Volumes\n>>>>"<<endl;
351 double Npix = (double)nx*(double)ny*(double)nz;
352 double vol_pixel = dx*dy*dz;
353 double vol_survey = vol_pixel*Npix;
354 cout<<"Npix total = "<<Npix<<" -> "<<Npix*sizeof(double)/1.e6<<" Mo"<<endl;
355 cout<<"Volume pixel = "<<vol_pixel<<" Mpc^3 com"<<endl;
356 cout<<"Volume total = "<<vol_survey<<" Mpc^3 com = "<<vol_survey/1.e9<<" Gpc^3"<<endl;
[3115]357
[3365]358 double vol = univ.Vol4Pi(redshift[1],redshift[2])/(4.*M_PI)*angsol_tot[0];
359 cout<<"Calcul avec angsol et redshift: vol = "<<vol<<" Mpc^3 = "<<vol/1.e9<<" Gpc^3"<<endl
360 <<" -> pixel volume comoving = vol/Npix = "<<vol/Npix<<" Mpc^3"<<endl;
[3115]361
[3365]362 // ---
363 // --- Angles solides
364 // ---
365 cout<<"\n>>>>\n>>>> Angles solides\n>>>>"<<endl;
366 cout<<"Pixel solid angle = "<<angsol_pix[0]<<" sr ("<<angsol_pix[0]/(4.*M_PI)<<" *4Pi)"
367 <<" in ["<<angsol_pix[1]<<","<<angsol_pix[2]<<"]"<<endl;
[3367]368 cout<<" = "<<sr2min2(angsol_pix[0])<<"\'^2"
369 <<" in ["<<sr2min2(angsol_pix[1])<<","<<sr2min2(angsol_pix[2])<<"]"<<endl;
[3365]370 cout<<"Total solid angle = "<<angsol_tot[0]<<" sr ("<<angsol_tot[0]/(4.*M_PI)<<" *4Pi)"
371 <<" in ["<<angsol_tot[1]<<","<<angsol_tot[2]<<"]"<<endl;
[3115]372
[3365]373 // ---
374 // --- Fourier space: k = omega = 2*Pi*Nu = 2*Pi*C/Lambda
375 // ---
[3287]376 cout<<"\n>>>>\n>>>> Geometrie dans l'espace de Fourier\n>>>>"<<endl;
[3115]377 cout<<"Array size: nx = "<<nx<<", ny = "<<ny<<", nz = "<<nz<<endl;
378 double dk_x = 2.*M_PI/(nx*dx), knyq_x = M_PI/dx;
379 double dk_y = 2.*M_PI/(nx*dy), knyq_y = M_PI/dy;
380 double dk_z = 2.*M_PI/(nz*dz), knyq_z = M_PI/dz;
[3365]381 cout<<"Transverse:"<<endl
382 <<" Resolution: dk_x = "<<dk_x<<" Mpc^-1 (2Pi/dk_x="<<2.*M_PI/dk_x<<" Mpc)"<<endl
383 <<" dk_y = "<<dk_y<<" Mpc^-1 (2Pi/dk_y="<<2.*M_PI/dk_y<<" Mpc)"<<endl
384 <<" Nyquist: kx = "<<knyq_x<<" Mpc^-1 (2Pi/knyq_x="<<2.*M_PI/knyq_x<<" Mpc)"<<endl
385 <<" ky = "<<knyq_y<<" Mpc^-1 (2Pi/knyq_y="<<2.*M_PI/knyq_y<<" Mpc)"<<endl;
386 cout<<"Line of sight:"<<endl
387 <<" Resolution: dk_z = "<<dk_z<<" Mpc^-1 (2Pi/dk_z="<<2.*M_PI/dk_z<<" Mpc)"<<endl
388 <<" Nyquist: kz = "<<knyq_z<<" Mpc^-1 (2Pi/knyq_z="<<2.*M_PI/knyq_z<<" Mpc)"<<endl;
[3115]389
[3365]390 // ---
[3350]391 // --- Variance cosmique
[3365]392 // ---
[3350]393 // cosmique poisson
[3351]394 // (sigma/P)^2 = 2*(2Pi)^3 / (4Pi k^2 dk Vsurvey) * [(1+n*P)/(n*P)]^2
[3350]395 // nombre de mode = 1/2 * Vsurvey/(2Pi)^3 * 4Pi*k^2*dk
396 if(kcosm>0. && pkcosm>0.) {
[3365]397 double pk = pkcosm*pow(growthfac[0],2.);
[3350]398 cout<<"\n>>>>\n>>>> variance cosmique pour k="<<kcosm<<" Mpc^-1, pk(z=0)="
[3365]399 <<pkcosm<<", pk(z="<<redshift[0]<<")="<<pk<<"\n>>>>"<<endl;
[3350]400 for(int i=0;i<3;i++) { // la correction de variance du au bruit de poisson
401 double v = 1.1; if(i==1) v=1.5; if(i==2) v=2.0;
402 double ngal = 1./(v-1.)/pk;
403 cout<<" pour "<<ngal<<" gal/Mpc^3 on multiplie par "<<v<<" sigma/P"<<endl;
404 }
[3365]405
406 cout<<endl;
[3350]407 vector<double> dk; if(dkcosm>0.) dk.push_back(dkcosm);
408 dk.push_back(dk_x); dk.push_back(dk_y); dk.push_back(dk_z);
409 for(int i=0;i<(int)dk.size();i++) { // la variance cosmique pure
[3365]410 double vcosm = sqrt( 2.*pow(2.*M_PI,3.)/(4.*M_PI*pow(kcosm,2.)*dk[i]*vol_survey) );
411 double nmode = 0.5*vol_survey/pow(2.*M_PI,3.) * 4.*M_PI*pow(kcosm,2.)*dk[i];
[3350]412 cout<<" pour dk = "<<dk[i]<<" Mpc^-1: sigma/P = "<<vcosm
413 <<" , Nmode = "<<nmode<<endl;
414 }
415 }
416
[3365]417 // ---
[3115]418 // --- Masse de HI
[3365]419 // ---
[3287]420 cout<<"\n>>>>\n>>>> Mass HI\n>>>>"<<endl;
[3115]421 Schechter sch(nstar,mstar,alpha);
422 sch.SetOutValue(1);
423 cout<<"nstar= "<<nstar<<" mstar="<<mstar<<" alpha="<<alpha<<endl;
424 cout<<"mstar*sch(mstar) = "<<sch(mstar)<<" Msol/Mpc^3/Msol"<<endl;
425 int npt = 10000;
[3344]426 double lnx1=log10(1.e+6), lnx2=log10(1.e+13), dlnx=(lnx2-lnx1)/npt;
[3115]427 double masshimpc3 = IntegrateFuncLog(sch,lnx1,lnx2,0.001,dlnx,10.*dlnx,6);
428 cout<<"Mass density: "<<masshimpc3<<" Msol/Mpc^3"<<endl;
429
[3365]430 double masshipix = masshimpc3*vol_pixel;
431 double masshitot = masshimpc3*vol_survey;
[3115]432 cout<<"Pixel mass = "<<masshipix<<" Msol"<<endl
433 <<"Total mass in survey = "<<masshitot<<" Msol"<<endl;
[3365]434 cout<<"OmegaHI a z=0: "<<masshimpc3/rhoc0<<endl;
435 for(int i=0;i<3;i++)
436 cout<<" a z="<<redshift[i]<<": "<<masshimpc3/rhocz[i]<<endl;
[3115]437 if(mhiref<=0.) mhiref = masshipix;
438
[3343]439 sch.SetOutValue(0);
440 cout<<"\nsch(mstar) = "<<sch(mstar)<<" /Mpc^3/Msol"<<endl;
441 cout<<"Galaxy number density:"<<endl;
[3344]442 for(double x=lnx1; x<lnx2-0.5; x+=1.) {
[3343]443 double n = IntegrateFuncLog(sch,x,lnx2,0.001,dlnx,10.*dlnx,6);
[3365]444 cout<<" m>"<<x<<" Msol: "<<n<<" /Mpc^3, "<<n*vol_pixel<<" /pixel, "
445 <<n*vol_survey<<" in survey"<<endl;
[3343]446 }
447 sch.SetOutValue(1);
448
[3365]449 // ---
[3115]450 // --- Survey values
[3365]451 // ---
[3287]452 cout<<"\n>>>>\n>>>> Observations\n>>>>"<<endl;
[3352]453 double surfeff = surftot * eta_eff;
[3365]454 cout<<"surf_tot="<<surftot<<" m^2, eta="<<eta_eff<<" surf_eff="<<surfeff<<" m^2, tobs="<<tobs<<" s"<<endl;
[3115]455
[3365]456 // Angles solides pour un telescope plein
457 double angSEq[4], angEq[4];
458 for(int i=0;i<4;i++) {
[3367]459 double nu = Fr_HyperFin_Par;
[3365]460 if(i<3) nu = nuhiz[i];
461 angSEq[i] = AngsolEqTelescope(nu,surftot);
462 angEq[i] = 2.*FrAngSol(angSEq[i]);
463 }
464 cout<<"\nFor a "<<surftot<<" m^2 telescope:"<<endl
465 <<" equivalent Omega = "<<angSEq[0]<<" sr in ["<<angSEq[1]<<","<<angSEq[2]<<"]"<<endl
466 <<" angular diameter = "<<angEq[0]<<" rd = "<<rad2min(angEq[0])
467 <<"\' in ["<<angEq[2]<<","<<angEq[2]<<"]"<<endl;
468 cout<<"At z=0: equivalent Omega = "<<angSEq[3]<<" sr"<<endl
469 <<" angular diameter = "<<angEq[3]<<" rd = "<<rad2min(angEq[3])<<"\'"<<endl;
470
[3367]471 // Pour une observation ou le lobe est + petit ou grand que le pixel de simulation
[3365]472 // La taille angulaire du lobe change avec la frequence donc avec le redshift
[3367]473 // La taille du lobe "lobearea0" est donnee pour une frequence de reference "lobefreq0" en MHz
[3365]474 double nlobes[3] = {1.,1.,1.};
[3367]475 // Si "lobefreq0" negatif c'est la frequence du centre du cube
476 if(lobefreq0<=0.) lobefreq0 = nuhiz[0]*1.e3;
477 // Si "lobearea0" negatif c'est la taille du pixel ramenee a lobefreq0
478 if(lobearea0<=0.) lobearea0 = sr2min2(angsol_pix[0])*pow(nuhiz[0]*1.e3/lobefreq0,2.);
479 cout<<"\n--- Lobe: angsol="<<lobearea0<<"\'^2 pour "<<lobefreq0<<" MHz"<<endl;
480 double lobearea[3];
481 for(int i=0;i<3;i++) {
482 lobearea[i] = lobearea0*pow(lobefreq0/(nuhiz[0]*1.e3),2.);
483 nlobes[i] = sr2min2(angsol_pix[i])/lobearea[i];
[3336]484 }
[3367]485 cout<<"Lobe cylindrique area "<<lobearea[0]<<"\'^2 in ["<<lobearea[1]<<","<<lobearea[2]<<"]"<<endl;
486 cout<<"Number of beams in one transversal pixel "<<nlobes[0]<<" in ["<<nlobes[1]<<","<<nlobes[2]<<"]"<<endl;
[3193]487
[3365]488 // ---
489 // --- Signal analysis
490 // ---
491 // --- Temperature d'antenne Ta et temperature de brillance Tb
492 // La puissance d'une source de brillance I non polarisee est:
493 // P = I * S * Omega * dNu
494 // La puissance recue pour une seule polarisation est:
495 // P = 1/2 * I * S * Omega * dNu
496 // La puissance recue pour un telescope (plein) est
497 // en remplacant Omega = lambda^2/S
498 // P = 1/2 * I * lambda^2 * dNu
499 // En appliquant la loi de Rayleigh: I = 2*k*Tb/lambda^2
500 // on obtient
501 // P = 1/2 * 2*k*Tb * dNu = k * Tb * dNu
502 // La temperature d'antenne est definie comme
503 // P = k * Ta * dNu
504 // Donc pour un ciel de temperature de brillance Tb
505 // et pour une antenne qui mesure une seule polarisation
506 // on a: Ta = Tb
[3115]507
[3365]508 cout<<"\n>>>>\n>>>> Signal Analysis\n>>>>"<<endl;
[3193]509 cout<<"Facteur polar = "<<facpolar<<endl;
510
[3115]511 PlanckSpectra planck(T_CMB_Par);
[3347]512 planck.SetSpectraApprox(PlanckSpectra::RAYLEIGH); // Rayleigh spectra
513 planck.SetSpectraVar(PlanckSpectra::NU); // frequency
514 planck.SetSpectraPower(PlanckSpectra::POWER); // output en W/....
515 planck.SetSpectraUnit(PlanckSpectra::ANGSFLUX); // radiance W/m^2/Sr/Hz
[3115]516
[3365]517 // ---
518 // --- Signal HI
519 // ---
520 // Power emitted by HI
521 cout<<"--- Power from HI for M = "<<mhiref<<" Msol"<<endl;
522 cout<<"Flux factor = "<<hifactor<<" at redshift = "<<redshift[0]<<endl;
523 cout<<"Luminosite = "<<hifactor*Msol2LumiHI(mhiref)<<" W"<<endl;
[3115]524
[3365]525 double fhi_ref[3], sfhi_ref[3];
526 for(int i=0;i<3;i++) {
527 fhi_ref[i] = hifactor*Msol2FluxHI(mhiref,dlum[i]);
528 sfhi_ref[i] = fhi_ref[i] / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
529 }
530 cout<<"FluxHI("<<dlum[0]<<" Mpc) all polar: "<<fhi_ref[0]<<" W/m^2 = "
531 <<fhi_ref[0]/Jansky2Watt_cst<<" Jy.Hz"
532 <<" in ["<<fhi_ref[1]/Jansky2Watt_cst<<","<<fhi_ref[2]/Jansky2Watt_cst<<"]"<<endl;
533 cout<<"If spread over pixel depth ("<<dnuhiz[0]<<" GHz):"<<endl
534 <<" flux density = "<<sfhi_ref[0]*1.e6<<" mu_Jy"
535 <<" in ["<<sfhi_ref[1]<<","<<sfhi_ref[2]<<"]"<<endl;
536
537 // Signal HI
538 double psig_2polar[3], tasig_2polar[3], ssig_2polar[3], isig_2polar[3], tsig_2polar[3];
539 double psig[3], tasig[3], ssig[3], isig[3], tsig[3];
540 double doplarge[3], dzvrot[3];
541
542 for(int i=0;i<3;i++) {
543 psig_2polar[i] = fhi_ref[i] * surfeff;
544 tasig_2polar[i] = psig_2polar[i] / k_Boltzman_Cst / (dnuhiz[i]*1e9);
545 ssig_2polar[i] = psig_2polar[i] / surfeff / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
546 isig_2polar[i] = ssig_2polar[i] / angsol_pix[i];
547 tsig_2polar[i] = isig_2polar[i]*Jansky2Watt_cst
548 / (2.*pow(nuhiz[i]*1e9/(SpeedOfLight_Cst*1000.),2.)*k_Boltzman_Cst);
549 psig[i] = facpolar * psig_2polar[i];
550 tasig[i] = facpolar * tasig_2polar[i];
551 ssig[i] = facpolar * ssig_2polar[i];
552 isig[i] = facpolar * isig_2polar[i];
553 tsig[i] = facpolar * tsig_2polar[i];
554 doplarge[i] = LargeurDoppler(vrot,nuhiz[i]);
555 dzvrot[i] = DzFrV(vrot,redshift[i]);
556 }
557 cout<<"\n--- Signal HI("<<mhiref<<" Msol) for Dnu="<<dnuhiz[0]<<" GHz :"<<endl
558 <<" Observation:"<<endl
559 <<" Power="<<psig[0]<<" W in ["<<psig[1]<<","<<psig[2]<<"]"<<endl
560 <<" Flux density = "<<ssig[0]*1.e6<<" mu_Jy in ["<<ssig[1]*1.e6<<","<<ssig[2]*1.e6<<"]"<<endl
561 <<" Intensity = "<<isig[0]<<" Jy/sr in ["<<isig[1]<<","<<isig[2]<<"]"<<endl
562 <<" Antenna temperature = "<<tasig[0]<<" K in ["<<tasig[1]<<","<<tasig[2]<<"]"<<endl
563 <<" Brightness temperature = "<<tsig[0]<<" K in ["<<tsig[1]<<","<<tsig[2]<<"]"<<endl
564 <<" 2 polars:"<<endl
565 <<" Power="<<psig_2polar[0]<<" W in ["<<psig_2polar[1]<<","<<psig_2polar[2]<<"]"<<endl
566 <<" Flux density = "<<ssig_2polar[0]*1.e6<<" mu_Jy in ["<<ssig_2polar[1]*1.e6<<","<<ssig_2polar[2]*1.e6<<"]"<<endl
567 <<" Intensity = "<<isig_2polar[0]<<" Jy/sr in ["<<isig_2polar[1]<<","<<isig_2polar[2]<<"]"<<endl
568 <<" Antenna temperature = "<<tasig_2polar[0]<<" K in ["<<tasig_2polar[1]<<","<<tasig_2polar[2]<<"]"<<endl
569 <<" Brightness temperature = "<<tsig_2polar[0]<<" K in ["<<tsig_2polar[1]<<","<<tsig_2polar[2]<<"]"<<endl;
570
[3193]571 // Elargissement doppler de la raie a 21cm: dNu = vrot/C * Nu(21cm) / (1+z)
[3365]572 cout<<" Doppler for rotation width of "<<vrot<<" km/s"<<endl
573 <<" width="<<doplarge[0]*1.e3<<" MHz in ["<<doplarge[1]*1.e3<<","<<doplarge[2]*1.e3<<"]"<<endl
574 <<" dzvrot= "<<dzvrot[0]<<" in ["<<dzvrot[1]<<","<<dzvrot[2]<<"]"<<endl;
575 if(doplarge[0]>dnuhiz[0])
576 cout<<"Warning: doppler width "<<doplarge[0]<<" GHz > "<<dnuhiz[0]<<" GHz redshift bin width"<<endl;
[3115]577
[3365]578 // ---
579 // --- Synchrotron (T en -2.7 -> Flux en -0.7 dans l'approximation Rayleigh)
580 // ---
581 double tsynch[3];
582 double psynch_2polar[3], tasynch_2polar[3], ssynch_2polar[3], isynch_2polar[3];
583 double psynch[3], tasynch[3], ssynch[3], isynch[3];
[3115]584
[3365]585 for(int i=0;i<3;i++) {
586 tsynch[i] = Tsynch408;
587 if(fabs(indnu)>1.e-50) tsynch[i] *= pow(nuhiz[i]/nuhaslam,indnu);
588 planck.SetTemperature(tsynch[i]);
589 psynch_2polar[i] = planck(nuhiz[i]*1.e+9) * surfeff * angsol_pix[i] * (dnuhiz[i]*1e9);
590 tasynch_2polar[i] = psynch_2polar[i] / k_Boltzman_Cst / (dnuhiz[i]*1e9);
591 ssynch_2polar[i] = psynch_2polar[i] / surfeff / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
592 isynch_2polar[i] = ssynch_2polar[i] / angsol_pix[i];
593 psynch[i] = facpolar * psynch_2polar[i];
594 tasynch[i] = facpolar * tasynch_2polar[i];
595 ssynch[i] = facpolar * ssynch_2polar[i];
596 isynch[i] = ssynch[i] / angsol_pix[i];
597 }
598 cout<<"\n--- Synchrotron: T="<<Tsynch408<<" K ("<<nuhaslam<<" GHz), "<<endl
599 <<" tsynch="<<tsynch[0]<<" K ("<<nuhiz[0]<<" GHz) in ["<<tsynch[1]<<","<<tsynch[2]<<"]"<<endl
600 <<" Observation:"<<endl
601 <<" Power="<<psynch[0]<<" W for pixel in ["<<psynch[1]<<","<<psynch[2]<<"]"<<endl
602 <<" Flux density = "<<ssynch[0]<<" Jy for pixel solid angle in ["<<ssynch[1]<<","<<ssynch[2]<<"]"<<endl
603 <<" Intensity = "<<isynch[0]<<" Jy/sr in ["<<isynch[1]<<","<<isynch[2]<<"]"<<endl
604 <<" Antenna temperature = "<<tasynch[0]<<" K in ["<<tasynch[1]<<","<<tasynch[2]<<"]"<<endl
605 <<" 2 polars:"<<endl
606 <<" Power="<<psynch_2polar[0]<<" W for pixel in ["<<psynch_2polar[1]<<","<<psynch_2polar[2]<<"]"<<endl
607 <<" Flux density = "<<ssynch_2polar[0]<<" Jy for pixel solid angle in ["<<ssynch_2polar[1]<<","<<ssynch_2polar[2]<<"]"<<endl
608 <<" Intensity = "<<isynch_2polar[0]<<" Jy/sr in ["<<isynch_2polar[1]<<","<<isynch_2polar[2]<<"]"<<endl
609 <<" Antenna temperature = "<<tasynch_2polar[0]<<" K in ["<<tasynch_2polar[1]<<","<<tasynch_2polar[2]<<"]"<<endl;
610
611 // ---
612 // --- CMB
613 // ---
[3115]614 planck.SetTemperature(tcmb);
[3365]615 double pcmb_2polar[3], tacmb_2polar[3], scmb_2polar[3], icmb_2polar[3];
616 double pcmb[3], tacmb[3], scmb[3], icmb[3];
[3115]617
[3365]618 for(int i=0;i<3;i++) {
619 pcmb_2polar[i] = planck(nuhiz[i]*1.e+9) * surfeff * angsol_pix[i] * (dnuhiz[i]*1e9);
620 tacmb_2polar[i] = pcmb_2polar[i] / k_Boltzman_Cst / (dnuhiz[i]*1e9);
621 scmb_2polar[i] = pcmb_2polar[i] / surfeff / (dnuhiz[i]*1e9) / Jansky2Watt_cst;
622 icmb_2polar[i] = scmb_2polar[i] / angsol_pix[i];
623 pcmb[i] = facpolar * pcmb_2polar[i];
624 tacmb[i] = facpolar * tacmb_2polar[i];
625 scmb[i] = facpolar * scmb_2polar[i];
626 icmb[i] = scmb[i] / angsol_pix[i];
627 }
628 cout<<"\n--- CMB: T="<<tcmb<<" K"<<endl
629 <<" Observation:"<<endl
630 <<" Power="<<pcmb[0]<<" W for pixel in ["<<pcmb[1]<<","<<pcmb[2]<<"]"<<endl
631 <<" Flux density = "<<scmb[0]<<" Jy for pixel solid angle in ["<<scmb[1]<<","<<scmb[2]<<"]"<<endl
632 <<" Intensity = "<<icmb[0]<<" Jy/sr in ["<<icmb[1]<<","<<icmb[2]<<"]"<<endl
633 <<" Antenna temperature = "<<tacmb[0]<<" K in ["<<tacmb[1]<<","<<tacmb[2]<<"]"<<endl
634 <<" 2 polars:"<<endl
635 <<" Power="<<pcmb_2polar[0]<<" W for pixel in ["<<pcmb_2polar[1]<<","<<pcmb_2polar[2]<<"]"<<endl
636 <<" Flux density = "<<scmb_2polar[0]<<" Jy for pixel solid angle in ["<<scmb_2polar[1]<<","<<scmb_2polar[2]<<"]"<<endl
637 <<" Intensity = "<<icmb_2polar[0]<<" Jy/sr in ["<<icmb_2polar[1]<<","<<icmb_2polar[2]<<"]"<<endl
638 <<" Antenna temperature = "<<tacmb_2polar[0]<<" K in ["<<tacmb_2polar[1]<<","<<tacmb_2polar[2]<<"]"<<endl;
639
640 // ---
641 // --- AGN
642 // ---
[3196]643 double flux_agn = pow(10.,lflux_agn);
[3365]644 double mass_agn[3], flux_agn_pix[3], mass_agn_pix[3], lmass_agn_pix[3];
645 for(int i=0;i<3;i++) {
646 mass_agn[i] = FluxHI2Msol(flux_agn*Jansky2Watt_cst,dlum[i]);
647 flux_agn_pix[i] = flux_agn*(dnuhiz[i]*1e9);
648 mass_agn_pix[i] = FluxHI2Msol(flux_agn_pix[i]*Jansky2Watt_cst,dlum[i]);
649 lmass_agn_pix[i] = log10(mass_agn_pix[i]);
650 }
651 cout<<"\n--- AGN: log10(S_agn)="<<lflux_agn<<" S_agn="<<flux_agn<<" Jy :"<<endl
652 <<" mass_agn = "<<mass_agn[0]<<" equiv. Msol/Hz in ["<<mass_agn[1]<<","<<mass_agn[2]<<"]"<<endl
653 <<" flux_agn_pix = "<<flux_agn_pix[0]<<" 10^-26 W/m^2 in ["<<flux_agn_pix[1]<<","<<flux_agn_pix[2]<<"]"<<endl
654 <<" mass_agn_pix = "<<mass_agn_pix[0]<<" Msol in ["<<mass_agn_pix[1]<<","<<mass_agn_pix[2]<<"]"<<endl
655 <<" log10(mass_agn_pix) = "<<lmass_agn_pix[0]<<" in ["<<lmass_agn_pix[1]<<","<<lmass_agn_pix[2]<<"]"<<endl;
[3196]656
[3339]657 // =====================================================================
[3336]658 // ---
[3115]659 // --- Noise analysis
[3336]660 // ---
[3339]661 // --- Puissance du bruit pour un telescope de surface Ae et de BW dNu
662 // Par definition la puissance du bruit est:
663 // Pb = k * Tsys * dNu (W)
664 // Pour une source (non-polarisee) de densite de flux (totale 2 polars)
[3352]665 // St (exprimee en Jy = 10^-26 W/m^2/Hz)
[3339]666 // Pt = St * Ae * dNu (puissance totale emise en W pour 2 polars)
667 // P1 = 1/2 * St * Ae * dNu (puissance emise en W pour une polar)
668 // la SEFD (system equivalent flux density en Jy) est definie comme
669 // la densite de flux total (2 polars) "St" d'une source (non-polarisee)
670 // dont la puissance P1 mesuree pour une seule polarisation
671 // serait egale a la puissance du bruit. De P1 = Pb on deduit:
672 // SEFD = 2 * k * Tsys / Ae (en Jy)
673 // la puissance du bruit est: Pb = 1/2 * SEFD * Ae * dNu (en W)
674 // la sensibilite Slim tient compte du temps d'integration et de la BW:
675 // le nombre de mesures independantes est "2*dNu*Tobs" donc
676 // Slim = SEFD / sqrt(2*dNu*Tobs) = 2*k*Tsys/[Ae*sqrt(2*dNu*Tobs) (en Jy)
677 // --- Puissance du bruit pour un interferometre
[3336]678 // Ae = surface d'un telescope elementaire
679 // N = nombre de telescopes dans l'interferometre (Atot = N*Ae)
[3339]680 // La sensibilite Slim en Jy est:
[3336]681 // Slim = 2 * k * Tsys / [ Ae * Sqrt(2*N(N-1)/2 *dnu*Tobs) ]
682 // = 2 * k * Tsys / [ Atot/N * Sqrt(2*N(N-1)/2*dnu*Tobs) ]
683 // = 2 * k * Tsys / [ Atot * Sqrt((N-1)/N *dnu*Tobs) ]
[3339]684 // - Interferometre a deux antennes:
[3336]685 // Slim = 2 * k * Tsys / [ Atot * Sqrt(1/2 *dnu*Tobs) ]
[3339]686 // - Interferometre a N antennes (N grand):
[3336]687 // Slim -> 2 * k * Tsys / [ Atot * Sqrt(dnu*Tobs) ]
[3341]688 // C'est aussi la formule pour un telescope unique de surface Atot
[3339]689 // --- On ne mesure qu'une seule polarisation
690 // Ces formules sont valables si on mesure 1 polarisation:
691 // Slim est la densite de flux total "St" (2 polars) d'une source (non-polarisee)
692 // qui donne la meme puissance que le bruit dans un detecteur qui ne
693 // mesure qu'une seule polarisation:
694 // Le rapport S/N pour une source de densite de flux St (totale 2 polars):
695 // S/N = St / Slim
696 // La puissance de bruit est, par definition:
697 // Pb = 1/2 *Slim*Atot*dNu
698 // = k*Tsys*sqrt(2*dNu/Tobs) pour N=2
699 // = k*Tsys*sqrt(dNu/Tobs) pour N>>grand
700 // La densite de flux d'une source a S/N=1 est:
701 // St = Slim
702 // La puissance d'une source a S/N=1 mesuree par un detecteur
703 // qui ne mesure qu'une polar est:
704 // P1_lim = 1/2 *Slim*Atot*dNu
705 // --- On mesure les 2 polarisations avec deux voies d'electronique distinctes
706 // la puissance du signal mesure est multipliee par 2
707 // la puissance du bruit est multipliee par sqrt(2)
708 // on a donc un gain d'un facteur sqrt(2) sur le rapport S/N
709 // (cela revient d'ailleur a doubler le temps de pose: Tobs -> 2*Tobs)
710 // En notant arbitrairement: Slim' = Slim / sqrt(2)
711 // ou Slim est defini par les formules ci-dessus
712 // Le rapport S/N pour une source de densite de flux St (totale 2 polars):
713 // (S/N)_2 = (S/N)_1 * sqrt(2) = (St / Slim) * sqrt(2) = St / Slim'
714 // La densite de flux d'une source a S/N=1 est:
715 // St = Slim' = Slim / sqrt(2)
716 // La puissance d'une source a S/N=1 cumulee par les 2 detecteurs est:
717 // P_lim = St*Atot*dNu = Slim'*Atot*dNu = 1/sqrt(2) *Slim*Atot*dNu
718 // = P1_lim * sqrt(2)
719 // La puissance de bruit cumulee par les 2 detecteurs est, par definition:
720 // Pb = P_lim = Slim'*Atot*dNu = P1_lim * sqrt(2)
721 // = 2*k*Tsys*sqrt(dNu/Tobs) pour N=2
722 // = k*Tsys*sqrt(2*dNu/Tobs) pour N>>grand
723 // =====================================================================
724
[3365]725 cout<<"\n>>>>\n>>>> Noise analysis\n>>>>"<<endl;
726 double psys[3];
727 for(int i=0;i<3;i++) psys[i] = k_Boltzman_Cst * Tsys * (dnuhiz[i]*1.e+9);
728 cout<<"Noise: T="<<Tsys<<" K"<<endl
729 <<" P="<<psys[0]<<" W in ["<<psys[1]<<","<<psys[2]<<"]"<<endl;
[3115]730
[3336]731 cout<<"...Computation assume that noise dominate the signal."<<endl;
[3339]732 if(ya2polar)
[3336]733 cout<<"...Assuming 2 polarisations measurements with 2 different electronics."<<endl;
[3115]734
735
[3336]736 //---
[3339]737 for(unsigned short it=0;it<2;it++) {
[3115]738
[3339]739 double fac = 1.;
740 if(it==0) { // Interferometre a 2 telescopes
741 fac = 0.5;
742 cout<<"\n...Observation limits for a 2 telescope interferometer (with complex correlator)"<<endl
743 <<" (sensitivity is given for real or complex correlator output)"<<endl;
744 } else if (it==1) { // Interferometre a N>> telescopes
745 fac = 1.;
746 cout<<"\n...Observation limits for a N (large) telescope interferometer (with complex correlator)"<<endl
[3341]747 <<" (weak source limit sensitivity in a synthetised image)"<<endl
748 <<" Also valid for a single dish telescope."<<endl;
[3339]749 } else continue;
750
[3365]751 double slim[3], SsN[3], smass[3], pkbruit[3];
752 for(int i=0;i<3;i++) {
753 slim[i] = 2. * k_Boltzman_Cst * Tsys / surfeff
754 / sqrt(fac*(dnuhiz[i]*1.e+9)*tobs) /Jansky2Watt_cst;
755 if(ya2polar) slim[i] /= sqrt(2.);
756 SsN[i] = ssig_2polar[i] / slim[i]; // independant de angsol_pix*surfeff
757 smass[i] = mhiref / ssig_2polar[i] * slim[i];
758 pkbruit[i] = pow(smass[i]/mhiref,2.)*vol_pixel;
759 }
[3339]760 cout<<"for 1 lobe:"<<endl
[3365]761 <<" Slim = "<<slim[0]*1.e6<<" mu_Jy in ["<<slim[1]*1.e6<<","<<slim[2]*1.e6<<"]"<<endl
762 <<" S/N = "<<SsN[0]<<" in ["<<SsN[1]<<","<<SsN[2]<<"]"<<endl
763 <<" Mass HI = "<<smass[0]<<" Msol in ["<<smass[1]<<","<<smass[2]<<"]"<<endl
764 <<" Pk = "<<pkbruit[0]<<" Mpc^3 in ["<<pkbruit[1]<<","<<pkbruit[2]<<"]"<<endl;
[3341]765
[3367]766 double slim_nl[3], SsN_nl[3], smass_nl[3], pkbruit_nl[3];
767 for(int i=0;i<3;i++) {
768 slim_nl[i] = slim[i] * sqrt(nlobes[i]);
769 SsN_nl[i] = ssig_2polar[i] / slim_nl[i];
770 smass_nl[i] = mhiref / ssig_2polar[i] * slim_nl[i];
771 pkbruit_nl[i] = pow(smass_nl[i]/mhiref,2.)*vol_pixel;
772 }
773 cout<<"for "<<nlobes[0]<<" lobes[i] in ["<<nlobes[1]<<","<<nlobes[2]<<"] :"<<endl
[3365]774 <<" Slim = "<<slim_nl[0]*1.e6<<" mu_Jy in ["<<slim_nl[1]*1.e6<<","<<slim_nl[2]*1.e6<<"]"<<endl
775 <<" S/N = "<<SsN_nl[0]<<" in ["<<SsN_nl[1]<<","<<SsN_nl[2]<<"]"<<endl
776 <<" Mass HI = "<<smass_nl[0]<<" Msol in ["<<smass_nl[1]<<","<<smass_nl[2]<<"]"<<endl
777 <<" Pk = "<<pkbruit_nl[0]<<" Mpc^3 in ["<<pkbruit_nl[1]<<","<<pkbruit_nl[2]<<"]"<<endl;
[3339]778
779 }
780
[3115]781 return 0;
[3365]782 }
783
784
785//-------------------------------------------------------------------------------------------
786double LargeurDoppler(double v, double nu)
787// largeur doppler pour une vitesse v en km/s et une frequence nu
788{
789 return v / SpeedOfLight_Cst * nu;
[3115]790}
[3365]791
792double DzFrV(double v, double zred)
793// largeur en redshift pour une vitesse v en km/s au redshift zred
794{
795 return v / SpeedOfLight_Cst * (1. + zred);
796}
797
798double DNuFrDz(double dzred,double nu_at_0,double zred)
799// Largeur DNu pour une largeur en redshift "dzred" au redshift "zred"
800// pour la frequence "nu_at_0" a z=0
801// nu = NuHi(z=0)/(1.+z0)
802// dnu = NuHi(z=0)/(1.+z0-dz/2) - NuHi/(1.+z0+dz/2)
803// = NuHi(z=0)*dz/[ (1+z0)^2 - (dz/2)^2 ]
804// = NuHi(z=0)*dz/(1.+z0)^2 / [ 1 - [dz/(1+z0)/2)]^2 ]
805// = NuHi(z=0)*dz/(1.+z0)^2 / [1 - dz/(1+z0)/2] / [1 + dz/(1+z0)/2]
806// ~= NuHi(z=0)*dz/(1.+z0)^2 (approx. pour dz<<z0 a l'ordre (dz/z0)^2)
807{
808 double zp1 = 1.+zred;
809 return nu_at_0*dzred/(zp1*zp1)/(1.-dzred/zp1/2.)/(1.+dzred/zp1/2.);
810}
811
812double DzFrDNu(double dnu_at_0,double nu_at_0,double zred)
813// Largeur en redshift au redshift "zred" pour une largeur
814// en frequence "dnu_at_0" a la frequence "nu_at_0" a z=0
815{
816 if(dnu_at_0<=0.) return 0.;
817 double zp1 = 1.+zred;
818 double dnusnu0 = dnu_at_0/nu_at_0;
819 return 2./dnusnu0 * (sqrt(1.+(dnusnu0*zp1)*(dnusnu0*zp1)) - 1.);
820}
821double DzFrDNuApprox(double dnu_at_0,double nu_at_0,double zred)
822// idem DzFrDNu mais on utilise l'approximation: dnu=NuHi(z=0)*dz/(1.+z0)^2
823{
824 double zp1 = 1.+zred;
825 return dnu_at_0/nu_at_0 *(zp1*zp1);
826}
827
828double ZFrLos(double loscom,CosmoCalc& univ)
829// Recherche du redshift correspondant a une distance comobile
830// le long de la ligne de visee egale a "loscom" Mpc
831// et pour un univers "univ"
832{
833 double dz = univ.ZMax()/10.; if(dz<=0.) dz = 0.1;
834 double zmin=0., zmax=0.;
835 while(univ.Dloscom(zmax)<loscom) zmax += dz;
836 if(zmax==0.) return 0.;
837 for(int i=0; i<6; i++) {
838 zmin=zmax-dz; if(zmin<0.) zmin=0.;
839 dz /= 10.;
840 for(double z=zmin; z<zmax+dz; z+=dz) {
841 double d = univ.Dloscom(z);
842 if(d<loscom) continue;
843 zmax = z;
844 //cout<<"ZFrLos: z="<<zmax<<" d="<<d<<" / "<<loscom<<endl;
845 break;
846 }
847 }
848 return zmax;
849}
850
851double AngsolEqTelescope(double nu /* GHz */,double telsurf /* m^2 */)
852/*
853Calcul de l'angle solide (sr) equivalent pour un telescope
854de surface totale "telsurf" (m^2) a la frequence "nu" (GHz)
855- Soit D(t) la figure de diffraction du telescope telle que D(t=0)=1
856 (t = angle depuis l'axe optique)
857 telescope circulaire de diametre D:
858 D(t) = [2J1(Pi*D*t/l)/(Pi*D*t/l)]
859 telescope rectangulaire axb:
860 D(t) = [sin(Pi*a*t/l)/(Pi*a*t/l)]*[sin(Pi*b*t/l)/(Pi*b*t/l)]
861- On cherche l'angle solide equivalent (par ex d'un cylindre de hauteur 1)
862 Int[ D(t)^2 dOmega ] = Int[ D(t)^2 2Pi t dt ] = Lambda^2/S
863- En conclusion, pour un ciel d'intensite uniforme I, on a:
864 P = I * S * Omega * dNu = I * S * (Lambda^2/S) * dNu
865*/
866{
867 double lambda = SpeedOfLight_Cst*1000./(nu*1.e9);
868 return lambda*lambda / telsurf;
869}
Note: See TracBrowser for help on using the repository browser.