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

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

petis changements cmv 21/03/2007

File size: 14.8 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 "constcosmo.h"
11#include "cosmocalc.h"
12#include "geneutils.h"
13#include "integfunc.h"
14#include "schechter.h"
15#include "planckspectra.h"
16
[3193]17/* --- Check Peterson at al. astro-ph/0606104 v1
18cmvdefsurv -z 0.0025 -x 1 -U 0.75,0.3,0.7,-1,1 -V 300 -O 400000,6000 -A 75 -M 6.156e9 -F 3 -2 1.5
19 --- */
20
[3115]21inline double rad2deg(double trad) {return trad/M_PI*180.;}
22inline double rad2min(double trad) {return trad/M_PI*180.*60.;}
23inline double rad2sec(double trad) {return trad/M_PI*180.*3600.;}
24inline double deg2rad(double tdeg) {return tdeg*M_PI/180.;}
25inline double min2rad(double tmin) {return tmin*M_PI/(180.*60.);}
26inline double sec2rad(double tsec) {return tsec*M_PI/(180.*3600.);}
27
28void usage(void);
29void usage(void) {
30 cout<<"cmvdefsurv [-r] -x adtx,atxlarg [-y adty,atylarg] -z dred,redlarg redshift"<<endl
31 <<" -x adtx,atxlarg : resolution en Theta_x (arcmin), largeur (degre)"<<endl
32 <<" -y adty,atylarg : idem selon y, si <=0 meme que x"<<endl
33 <<" -z dred,redlarg : resolution en redshift, largeur en redshift"<<endl
[3193]34 <<" -P : on donne -x -y -z en Mpc au lieu d\'angles et de redshift"<<endl
35 <<" -L lobewidth : taille du lobe d\'observation (FWHM) en arcmin (def= 1\')"<<endl
[3115]36 <<" -O surf,tobs : surface effective (m^2) et temps d\'observation (s)"<<endl
[3193]37 <<" -A Tsys : temperature du system (K)"<<endl
[3115]38 <<" -S Tsynch,indnu : temperature (K) synch a 408 Mhz, index d\'evolution"<<endl
39 <<" (indnu==0 no evolution with freq.)"<<endl
[3193]40 <<" -M : masse de HI de reference (MSol), si <=0 mean schechter in pixel"<<endl
[3115]41 <<" -F : HI flux factor to be applied for our redshift"<<endl
[3193]42 <<" -V Vrot : largeur en vitesse (km/s) pour l\'elargissement doppler (def=300km/s)"<<endl
43 <<" -U h100,om0,ol0,w0,or0,flat : cosmology"<<endl
44 <<" -2 : two polarisations measured"<<endl
[3115]45 <<" redshift : redshift moyen du survey"<<endl
46 <<endl;
47}
48
49int main(int narg,char *arg[])
50{
51 // --- Valeurs fixes
52 // WMAP
53 unsigned short flat = 0;
[3193]54 double h100=0.71, om0=0.267804, or0=7.9e-05*0., ol0=0.73,w0=-1.;
[3115]55 // Schechter
56 double h75 = h100 / 0.75;
57 double nstar = 0.006*pow(h75,3.); //
58 double mstar = pow(10.,9.8/(h75*h75)); // MSol
59 double alpha = -1.37;
60 cout<<"nstar= "<<nstar<<" mstar="<<mstar<<" alpha="<<alpha<<endl;
61
62
63 // --- Arguments
64 bool inmpc = false;
65 double adtx=1., atxlarg=90., adty=-1., atylarg=-1.;
66 double dx=1.,txlarg=1000., dy=-1.,tylarg=1000., dz=1.,tzlarg=100.;
67 int nx,ny,nz;
68 double redshift = 1., dred=0.01, redlarg=0.3;
[3193]69 double tobs = 6000., surfeff = 400000.;
70 double lobewidth = 1.; // taille du lobe d'observation en arcmin
71 double Tsys=75.;
[3115]72 // a 408 MHz (Haslam) + evol index a -2.6
73 double Tsynch408=60., nuhaslam=0.408, indnu = -2.6;
74 double mhiref = -1.; // reference Mass en HI (def integ schechter)
75 double hifactor = 1.;
[3193]76 double vrot = 300.; // largeur en vitesse (km/s) pour elargissement doppler
77 double facpolar = 0.5; // si on ne mesure les 2 polars -> 1.0
[3115]78
79 // --- Decodage arguments
80 char c;
[3193]81 while((c = getopt(narg,arg,"hP2x:y:z:A:S:O:M:F:V:U:L:")) != -1) {
[3115]82 switch (c) {
83 case 'P' :
84 inmpc = true;
85 break;
86 case 'x' :
87 sscanf(optarg,"%lf,%lf",&adtx,&atxlarg);
88 break;
89 case 'y' :
90 sscanf(optarg,"%lf,%lf",&adty,&atylarg);
91 break;
92 case 'z' :
93 sscanf(optarg,"%lf,%lf",&dred,&redlarg);
94 break;
95 case 'O' :
96 sscanf(optarg,"%lf,%lf",&surfeff,&tobs);
97 break;
[3193]98 case 'L' :
99 sscanf(optarg,"%lf",&lobewidth);
100 break;
[3115]101 case 'A' :
[3193]102 sscanf(optarg,"%lf",&Tsys);
[3115]103 break;
104 case 'S' :
105 sscanf(optarg,"%lf,%lf",&Tsynch408,&indnu);
106 break;
107 case 'M' :
108 sscanf(optarg,"%lf",&mhiref);
109 break;
110 case 'F' :
111 sscanf(optarg,"%lf",&hifactor);
112 break;
[3193]113 case 'V' :
114 sscanf(optarg,"%lf",&vrot);
[3115]115 break;
[3193]116 case 'U' :
117 sscanf(optarg,"%lf,%lf,%lf,%lf,%u",&h100,&om0,&ol0,&w0,&flat);
118 break;
119 case '2' :
120 facpolar = 1.0;
121 break;
[3115]122 case 'h' :
123 default :
124 usage(); return -1;
125 }
[3193]126 }
[3115]127 if(optind>=narg) {usage(); return-1;}
128 sscanf(arg[optind],"%lf",&redshift);
129 if(redshift<=0.) {cout<<"Redshift "<<redshift<<" should be >0"<<endl; return -2;}
130
131 // --- Initialisation de la Cosmologie
[3193]132 cout<<"\nh100="<<h100<<" Om0="<<om0<<" Or0="<<or0<<" Or0="
133 <<or0<<" Ol0="<<ol0<<" w0="<<w0<<" flat="<<flat<<endl;
[3115]134 cout<<"\n--- Cosmology for z = "<<redshift<<endl;
135 CosmoCalc univ(flat,true,2.*redshift);
136 double perc=0.01,dzinc=redshift/100.,dzmax=dzinc*10.; unsigned short glorder=4;
137 univ.SetInteg(perc,dzinc,dzmax,glorder);
138 univ.SetDynParam(h100,om0,or0,ol0,w0);
[3193]139 univ.Print(0.);
[3115]140 univ.Print(redshift);
141
142 double dang = univ.Dang(redshift);
143 double dtrcom = univ.Dtrcom(redshift);
144 double dlum = univ.Dlum(redshift);
145 double dloscom = univ.Dloscom(redshift);
146 double dlosdz = univ.Dhubble()/univ.E(redshift);
147 cout<<"dang="<<dang<<" dlum="<<dlum<<" dtrcom="<<dtrcom
148 <<" dloscom="<<dloscom<<" dlosdz="<<dlosdz<<" Mpc"<<endl;
149
150 cout<<"\n1\" -> "<<dang*sec2rad(1.)<<" Mpc = "<<dtrcom*sec2rad(1.)<<" Mpc com"<<endl;
151 cout<<"1\' -> "<<dang*min2rad(1.)<<" Mpc = "<<dtrcom*min2rad(1.)<<" Mpc com"<<endl;
152 cout<<"1d -> "<<dang*deg2rad(1.)<<" Mpc = "<<dtrcom*deg2rad(1.)<<" Mpc com"<<endl;
153
154 cout<<"dz=1 -> "<<dlosdz<<" Mpc com"<<endl;
155
156 cout<<"1 Mpc los com -> dz = "<<1./dlosdz<<endl;
157 cout<<"1 Mpc transv com -> "<<rad2sec(1./dtrcom)<<"\" = "
158 <<rad2min(1./dtrcom)<<" \' = "<<rad2deg(1./dtrcom)<<" d"<<endl;
159
160 // --- Mise en forme dans les unites appropriees
161 if(adty<=0.) adty=adtx;
162 if(atylarg<=0.) atylarg=atxlarg;
163 if(inmpc) {
164 dx = adtx; txlarg = atxlarg; nx = int(txlarg/dx+0.5);
165 dy = adty; txlarg = atxlarg; ny = int(tylarg/dy+0.5);
166 dz = dred; tzlarg = redlarg; nz = int(tzlarg/dz+0.5);
167 adtx = dx/dtrcom; atxlarg = adtx*nx;
168 adty = dy/dtrcom; atylarg = adty*ny;
169 dred = dz/dlosdz; redlarg = dred*nz;
170 } else {
171 adtx = min2rad(adtx); atxlarg = deg2rad(atxlarg); nx = int(atxlarg/adtx+0.5);
172 adty = min2rad(adty); atylarg = deg2rad(atylarg); ny = int(atylarg/adty+0.5);
173 nz = int(redlarg/dred+0.5);
174 dx = adtx*dtrcom; txlarg = dx*nx;
175 dy = adty*dtrcom; tylarg = dy*ny;
176 dz = dred*dlosdz; tzlarg = dz*nz;
177 }
178 double Npix = (double)nx*(double)ny*(double)nz;
179
180 double redlim[2] = {redshift-redlarg/2.,redshift+redlarg/2.};
181 if(redlim[0]<=0.)
182 {cout<<"Lower redshift limit "<<redlim[0]<<" should be >0"<<endl; return -3;}
183 double dtrlim[2] = {univ.Dtrcom(redlim[0]),univ.Dtrcom(redlim[1])};
184 double loslim[2] = {univ.Dloscom(redlim[0]), univ.Dloscom(redlim[1])};
185 double dlumlim[2] = {univ.Dlum(redlim[0]),univ.Dlum(redlim[1])};
186
187 cout<<"\n---- Type de donnees: inmpc = "<<inmpc<<endl;
188 cout<<"---- Line of Sight: Redshift = "<<redshift<<endl
189 <<"dred = "<<dred<<" redlarg = "<<redlarg<<endl
190 <<" dz = "<<dz<<" Mpc redlarg = "<<tzlarg<<" Mpc, nz = "<<nz<<" pix"<<endl;
191 cout<<"---- Transverse X:"<<endl
192 <<"adtx = "<<rad2min(adtx)<<"\', atxlarg = "<<rad2deg(atxlarg)<<" d"<<endl
193 <<" dx = "<<dx<<" Mpc, txlarg = "<<txlarg<<" Mpc, nx = "<<nx<<" pix"<<endl;
194 cout<<"---- Transverse Y:"<<endl
195 <<"adty = "<<rad2min(adty)<<"\', atylarg = "<<rad2deg(atylarg)<<" d"<<endl
196 <<" dy = "<<dy<<" Mpc, tylarg = "<<tylarg<<" Mpc, ny = "<<ny<<" pix"<<endl;
197 cout<<"---- Npix total = "<<Npix<<" -> "<<Npix*sizeof(double)/1.e6<<" Mo"<<endl;
198
199 // --- Cosmolographie Transverse
200 cout<<"\n--- Transverse"<<endl;
201 cout<<"dang comoving = "<<dtrcom<<" Mpc (com) var_in_z ["
202 <<dtrlim[0]<<","<<dtrlim[1]<<"]"<<endl;
203
204 cout<<"... dx = "<<dx<<" Mpc (com), with angle "<<adtx*dtrcom<<endl
205 <<" with angle var_in_z ["<<adtx*dtrlim[0]<<","<<adtx*dtrlim[1]<<"]"<<endl;
206 cout<<"... largx = "<<txlarg<<" Mpc (com), with angle "<<atxlarg*dtrcom<<endl
207 <<" with angle var_in_z ["<<atxlarg*dtrlim[0]<<","<<atxlarg*dtrlim[1]<<"]"<<endl;
208
209 cout<<"... dy = "<<dy<<" Mpc (com), with angle "<<adty*dtrcom<<endl
210 <<" with angle var_in_z ["<<adty*dtrlim[0]<<","<<adty*dtrlim[1]<<"]"<<endl;
211 cout<<"... largy = "<<tylarg<<" Mpc (com), with angle "<<atylarg*dtrcom<<endl
212 <<" with angle var_in_z ["<<atylarg*dtrlim[0]<<","<<atylarg*dtrlim[1]<<"]"<<endl;
213
214 // --- Cosmolographie Line of sight
215 cout<<"\n--- Line of Sight"<<endl;
216 cout<<"los comoving distance = "<<dloscom<<" Mpc (com) in ["
217 <<loslim[0]<<","<<loslim[1]<<"]"<<endl
218 <<" diff = "
219 <<loslim[1]-loslim[0]<<" Mpc"<<endl;
220
221 cout<<"...dz = "<<dz<<" Mpc (com), with redshift approx "<<dred*dlosdz<<endl;
222 cout<<"...tzlarg = "<<tzlarg<<" Mpc (com), with redshift approx "<<redlarg*dlosdz<<endl;
223
224 // --- Solid Angle & Volume
225 cout<<"\n--- Solid angle"<<endl;
226 double angsol = AngSol(adtx/2.,adty/2.,M_PI/2.);
227 cout<<"Elementary solid angle = "<<angsol<<" sr = "<<angsol/(4.*M_PI)<<" *4Pi sr"<<endl;
228 double angsoltot = AngSol(atxlarg/2.,atylarg/2.,M_PI/2.);
229 cout<<"Total solid angle = "<<angsoltot<<" sr = "<<angsoltot/(4.*M_PI)<<" *4Pi sr"<<endl;
230
231 cout<<"\n--- Volume"<<endl;
232 double dvol = dx*dy*dz;
233 cout<<"Pixel volume comoving = "<<dvol<<" Mpc^3"<<endl;
234 double vol = univ.Vol4Pi(redlim[0],redlim[1])/(4.*M_PI)*angsoltot;
235 cout<<"Volume comoving = "<<vol<<" Mpc^3 = "<<vol/1.e9<<" Gpc^3"<<endl
236 <<"Pixel volume comoving = vol/Npix = "<<vol/Npix<<" Mpc^3"<<endl;
237
238 // --- Fourier space: k = omega = 2*Pi*Nu
239 cout<<"\n--- Fourier space"<<endl;
240 cout<<"Array size: nx = "<<nx<<", ny = "<<ny<<", nz = "<<nz<<endl;
241 double dk_x = 2.*M_PI/(nx*dx), knyq_x = M_PI/dx;
242 double dk_y = 2.*M_PI/(nx*dy), knyq_y = M_PI/dy;
243 double dk_z = 2.*M_PI/(nz*dz), knyq_z = M_PI/dz;
244 cout<<"Resolution: dk_x = "<<dk_x<<" Mpc^-1 (2Pi/dk_x="<<2.*M_PI/dk_x<<" Mpc)"<<endl
245 <<" dk_y = "<<dk_y<<" Mpc^-1 (2Pi/dk_y="<<2.*M_PI/dk_y<<" Mpc)"<<endl;
246 cout<<"Nyquist: kx = "<<knyq_x<<" Mpc^-1 (2Pi/knyq_x="<<2.*M_PI/knyq_x<<" Mpc)"<<endl
247 <<" ky = "<<knyq_y<<" Mpc^-1 (2Pi/knyq_y="<<2.*M_PI/knyq_y<<" Mpc)"<<endl;
248 cout<<"Resolution: dk_z = "<<dk_z<<" Mpc^-1 (2Pi/dk_z="<<2.*M_PI/dk_z<<" Mpc)"<<endl;
249 cout<<"Nyquist: kz = "<<knyq_z<<" Mpc^-1 (2Pi/knyq_z="<<2.*M_PI/knyq_z<<" Mpc)"<<endl;
250
251 // --- Masse de HI
252 cout<<"\n--- Mass HI"<<endl;
253 Schechter sch(nstar,mstar,alpha);
254 sch.SetOutValue(1);
255 cout<<"nstar= "<<nstar<<" mstar="<<mstar<<" alpha="<<alpha<<endl;
256 cout<<"mstar*sch(mstar) = "<<sch(mstar)<<" Msol/Mpc^3/Msol"<<endl;
257 int npt = 10000;
258 double lnx1=log10(1e-6), lnx2=log10(1e+14), dlnx=(lnx2-lnx1)/npt;
259 double masshimpc3 = IntegrateFuncLog(sch,lnx1,lnx2,0.001,dlnx,10.*dlnx,6);
260 cout<<"Mass density: "<<masshimpc3<<" Msol/Mpc^3"<<endl;
261
262 double masshipix = masshimpc3*dvol;
263 double masshitot = masshimpc3*vol;
264 cout<<"Pixel mass = "<<masshipix<<" Msol"<<endl
265 <<"Total mass in survey = "<<masshitot<<" Msol"<<endl;
266 if(mhiref<=0.) mhiref = masshipix;
267
268 // --- Survey values
269 double unplusz = 1.+redshift;
270 double nuhiz = Fr_HyperFin_Par / unplusz; // GHz
271 // dnu = NuHi/(1.+z0-dz/2) - NuHi/(1.+z0+dz/2)
272 // = NuHi*dz/(1.+z0)^2 * 1/[1-(dz/(2*(1+z0)))^2]
273 double dnuhiz = Fr_HyperFin_Par *dred/(unplusz*unplusz)
274 / (1.- (dred/.2/unplusz)*(dred/.2/unplusz));
275 cout<<"\n--- Observation:"<<endl
276 <<" surf_eff="<<surfeff<<" m^2, tobs="<<tobs<<" s"<<endl
277 <<" nu="<<nuhiz<<" GHz, dnu="<<dnuhiz*1.e3<<" Mhz"<<endl;
278 cout<<"dang lumi = "<<dlum<<" in ["<<dlumlim[0]<<","<<dlumlim[1]<<"] Mpc"<<endl;
279
[3193]280 double slobe = lobewidth/2.35482; // sigma du lobe en arcmin
281 double lobecyl = sqrt(8.)*slobe; // diametre du lobe cylindrique equiv en arcmin
282 double lobearea = M_PI*lobecyl*lobecyl/4.; // en arcmin^2 (hypothese lobe gaussien)
283 cout<<"\nBeam FWHM = "<<lobewidth<<"\' -> sigma = "<<slobe<<"\' -> "
284 <<" Dcyl = "<<lobecyl<<"\' -> area = "<<lobearea<<" arcmin^2"<<endl;
285 double nlobes = rad2min(adtx)*rad2min(adty)/lobearea;
286 cout<<"Number of beams in one transversal pixel = "<<nlobes<<endl;
287
[3115]288 // --- Power emitted by HI
289 cout<<"\n--- Power from HI for M = "<<mhiref<<" Msol at "<<nuhiz<<" GHz"<<endl;
290 cout<<"flux factor = "<<hifactor<<" at redshift = "<<redshift<<endl;
291
292 double fhi = hifactor*FluxHI(mhiref,dlum);
293 cout<<"FluxHI("<<dlum<<" Mpc) all polar:"<<endl
294 <<" Flux= "<<fhi<<" W/m^2 = "<<fhi/Jansky2Watt_cst<<" Jy.Hz"<<endl
295 <<" in ["<<hifactor*FluxHI(mhiref,dlumlim[0])
296 <<","<<hifactor*FluxHI(mhiref,dlumlim[1])<<"] W/m^2"<<endl;
[3193]297 double sfhi = fhi / (dnuhiz*1e9) / Jansky2Watt_cst;
[3115]298 cout<<"If spread over "<<dnuhiz<<" GHz, flux density = "<<sfhi<<" Jy"<<endl;
299
300 // --- Signal analysis
301 cout<<"\n--- Signal analysis"<<endl;
[3193]302 cout<<"Facteur polar = "<<facpolar<<endl;
303
[3115]304 PlanckSpectra planck(T_CMB_Par);
305 planck.SetApprox(1); // Rayleigh spectra
306 planck.SetVar(0); // frequency
307 planck.SetUnitOut(0); // output en W/....
308 planck.SetTypSpectra(0); // radiance W/m^2/Sr/Hz
309
[3193]310 // Signal
[3115]311 double psig = facpolar * fhi * surfeff;
[3193]312 double tsig = psig / k_Boltzman_Cst / (dnuhiz*1e9);
313 double ssig = psig / surfeff / (dnuhiz*1e9) / Jansky2Watt_cst;
314 cout<<"Signal("<<mhiref<<" Msol): P="<<psig<<" W"<<endl;
315 cout<<" flux density = "<<ssig<<" Jy (for Dnu="<<dnuhiz<<" GHz)"<<endl;
[3115]316 cout<<" Antenna temperature: tsig="<<tsig<<" K"<<endl;
317
[3193]318 // Elargissement doppler de la raie a 21cm: dNu = vrot/C * Nu(21cm) / (1+z)
319 double doplarge = vrot / SpeedOfLight_Cst * nuhiz;
320 cout<<" Doppler width="<<doplarge*1.e3<<" MHz for rotation width of "<<vrot<<" km/s"<<endl;
321 if(doplarge>dnuhiz) {
322 cout<<"Warning: doppler width "<<doplarge<<" GHz > "<<dnuhiz<<" GHz redshift bin width"<<endl;
323 }
[3115]324
[3193]325 // Synchrotron
[3115]326 double tsynch = Tsynch408;
327 if(fabs(indnu)>1.e-50) tsynch *= pow(nuhiz/nuhaslam,indnu);
328 planck.SetTemperature(tsynch);
[3193]329 double psynch = facpolar * planck(nuhiz*1.e+9) * surfeff * angsol * (dnuhiz*1e9);
330 double ssynch = psynch / surfeff / (dnuhiz*1e9) / Jansky2Watt_cst;
[3115]331 cout<<"Synchrotron: T="<<Tsynch408<<" K ("<<nuhaslam<<" GHz), "
332 <<tsynch<<" K ("<<nuhiz<<" GHz)"<<endl
[3193]333 <<" P="<<psynch<<" W"<<endl;
334 cout<<" flux density = "<<ssynch<<" Jy"<<endl;
[3115]335
[3193]336 // CMB
[3115]337 double tcmb = T_CMB_Par;
338 planck.SetTemperature(tcmb);
[3193]339 double pcmb = facpolar * planck(nuhiz*1.e+9) * surfeff * angsol * (dnuhiz*1e9);
[3115]340 double scmb = pcmb / surfeff / (dnuhiz*1.e+9) / Jansky2Watt_cst;
[3193]341 cout<<"CMB: T="<<tcmb<<" K -> P="<<pcmb<<" W"<<endl;
342 cout<<" flux density = "<<scmb<<" Jy"<<endl;
[3115]343
344 // --- Noise analysis
345 cout<<"\n--- Noise analysis"<<endl;
[3193]346 double psys = k_Boltzman_Cst * Tsys * (dnuhiz*1.e+9);
347 cout<<"Noise: T="<<Tsys<<" K, P="<<psys<<" W (for Dnu="<<dnuhiz<<" GHz)"<<endl;
[3115]348
[3193]349 double slim = 2. * k_Boltzman_Cst * Tsys / surfeff
350 / sqrt(2.*(dnuhiz*1.e+9)*tobs) /Jansky2Watt_cst;
351 cout<<"Observation flux density limit: "<<slim<<" Jy (in 1 lobe)"<<endl;
[3115]352
[3193]353 slim = slim * sqrt(nlobes);
354 cout<<"Observation flux density limit: "<<slim<<" Jy (in "<<nlobes<<" lobes)"<<endl;
[3115]355
356 double SsN = ssig/slim;
357 cout<<"\nSignal to noise ratio = "<<SsN<<endl;
358
359 double smass = mhiref/ssig*slim;
360 cout<<"\nSigma noise equivalent = "<<smass<<" Msol"<<endl;
361
362 return 0;
363}
Note: See TracBrowser for help on using the repository browser.