Changeset 3199 in Sophya for trunk/Cosmo/SimLSS/genefluct3d.cc
- Timestamp:
- Apr 5, 2007, 7:19:06 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cosmo/SimLSS/genefluct3d.cc
r3196 r3199 21 21 #include "constcosmo.h" 22 22 #include "geneutils.h" 23 #include "schechter.h" 23 24 24 25 #include "genefluct3d.h" … … 33 34 , redshref_(-999.) , kredshref_(0.) , cosmo_(NULL) , growth_(NULL) 34 35 , loscom_ref_(-999.), loscom_min_(-999.), loscom_max_(-999.) 35 36 36 , loscom2zred_min_(0.) , loscom2zred_max_(0.) 37 37 { 38 38 xobs_[0] = xobs_[1] = xobs_[2] = 0.; 39 39 zred_.resize(0); 40 40 loscom_.resize(0); 41 loscom2zred_.resize(0); 41 42 SetNThread(); 42 43 } … … 76 77 redshref_ = redshref; 77 78 kredshref_ = kredshref; 79 if(lp_>0) 80 cout<<"--- GeneFluct3D::SetObservator zref="<<redshref_<<" kref="<<kredshref_<<endl; 78 81 } 79 82 … … 94 97 <<" D="<<dx<<","<<dy<<","<<dz<<endl; 95 98 if(nx<=0 || dx<=0.) { 96 c out<<"GeneFluct3D::setsize_Error: bad value(s)"<<endl;97 throw ParmError("GeneFluct3D::setsize_Error: bad value(s)");99 char *bla = "GeneFluct3D::setsize_Error: bad value(s"; 100 cout<<bla<<endl; throw ParmError(bla); 98 101 } 99 102 … … 161 164 char bla[90]; 162 165 sprintf(bla,"GeneFluct3D::check_array_alloc_Error: array is not allocated"); 163 cout<<bla<<endl; 164 throw ParmError(bla); 166 cout<<bla<<endl; throw ParmError(bla); 165 167 } 166 168 … … 183 185 184 186 //------------------------------------------------------- 185 long GeneFluct3D::LosComRedshift(double zinc )187 long GeneFluct3D::LosComRedshift(double zinc,long npoints) 186 188 // Given a position of the cube relative to the observer 187 189 // and a cosmology … … 190 192 // the vector "zred_" of scanned redshift (by zinc increments) 191 193 // the vector "loscom_" of corresponding los comoving distance 194 // -- Input: 195 // zinc : redshift increment for computation 196 // npoints : number of points required for inverting loscom -> zred 192 197 // 193 198 { 194 if(zinc<=0.) zinc = 0.01; 195 if(lp_>0) cout<<"--- LosComRedshift: zinc="<<zinc<<endl; 199 if(lp_>0) cout<<"--- LosComRedshift: zinc="<<zinc<<" , npoints="<<npoints<<endl; 196 200 197 201 if(cosmo_ == NULL || redshref_<0.) { 198 cout<<"GeneFluct3D::LosComRedshift_Error: set Observator and Cosmology first"<<endl; 199 throw ParmError(""); 200 } 201 202 // On calcule les coordonnees de l'observateur 203 // Il est sur un axe centre sur le milieu de la face Oxy 202 char *bla = "GeneFluct3D::LosComRedshift_Error: set Observator and Cosmology first"; 203 cout<<bla<<endl; throw ParmError(bla); 204 } 205 206 // On calcule les coordonnees de l'observateur dans le repere du cube 207 // cad dans le repere ou l'origine est au centre du pixel i=j=l=0. 208 // L'observateur est sur un axe centre sur le milieu de la face Oxy 204 209 double loscom_ref_ = cosmo_->Dloscom(redshref_); 205 210 xobs_[0] = Nx_/2.*Dx_; … … 239 244 } 240 245 241 // Fill the corresponding vectors 246 // Fill the corresponding vectors for loscom and zred 247 if(zinc<=0.) zinc = 0.01; 242 248 for(double z=0.; ; z+=zinc) { 243 249 double dlc = cosmo_->Dloscom(z); … … 246 252 loscom_.push_back(dlc); 247 253 z += zinc; 248 if(dlc>loscom_max_) break; // on break apres avoir stoque un dlc>dlcmax 249 } 250 251 long n = zred_.size(); 254 if(dlc>loscom_max_) break; // on sort apres avoir stoque un dlc>dlcmax 255 } 256 252 257 if(lp_>0) { 253 cout<<"...n="<<n; 258 long n = zred_.size(); 259 cout<<"...zred/loscom tables[zinc="<<zinc<<"]: n="<<n; 254 260 if(n>0) cout<<" z="<<zred_[0]<<" -> d="<<loscom_[0]; 255 261 if(n>1) cout<<" , z="<<zred_[n-1]<<" -> d="<<loscom_[n-1]; … … 257 263 } 258 264 259 return n; 265 // Compute the parameters and tables needed for inversion loscom->zred 266 if(npoints<3) npoints = zred_.size(); 267 InverseFunc invfun(zred_,loscom_); 268 invfun.ComputeParab(npoints,loscom2zred_); 269 loscom2zred_min_ = invfun.YMin(); 270 loscom2zred_max_ = invfun.YMax(); 271 272 if(lp_>0) { 273 long n = loscom2zred_.size(); 274 cout<<"...loscom -> zred[npoints="<<npoints<<"]: n="<<n 275 <<" los_min="<<loscom2zred_min_ 276 <<" los_max="<<loscom2zred_max_ 277 <<" -> zred=["; 278 if(n>0) cout<<loscom2zred_[0]; 279 cout<<","; 280 if(n>1) cout<<loscom2zred_[n-1]; 281 cout<<"]"<<endl; 282 if(lp_>1 && n>0) 283 for(int i=0;i<n;i++) 284 if(i==0 || abs(i-n/2)<2 || i==n-1) 285 cout<<" "<<i<<" "<<loscom2zred_[i]<<endl; 286 } 287 288 return zred_.size(); 260 289 } 261 290 … … 624 653 625 654 //------------------------------------------------------------------- 626 void GeneFluct3D::ApplyGrowthFactor( long npoints)655 void GeneFluct3D::ApplyGrowthFactor(void) 627 656 // Apply Growth to real space 628 657 // Using the correspondance between redshift and los comoving distance 629 658 // describe in vector "zred_" "loscom_" 630 659 { 631 if(npoints<3) npoints = zred_.size(); 632 if(lp_>0) cout<<"--- ApplyGrowthFactor --- npoints="<<npoints<<endl; 660 if(lp_>0) cout<<"--- ApplyGrowthFactor ---"<<endl; 633 661 check_array_alloc(); 634 662 635 663 if(growth_ == NULL) { 636 cout<<"GeneFluct3D::ApplyGrowthFactor_Error: set GrowthFactor first"<<endl; 637 throw ParmError("GeneFluct3D::ApplyGrowthFactor_Error: set GrowthFactor first"); 638 } 639 640 long n = zred_.size(); 641 InverseFunc invfun(zred_,loscom_); 642 vector<double> invlos; 643 invfun.ComputeParab(npoints,invlos); 644 645 InterpFunc interpinv(invfun.YMin(),invfun.YMax(),invlos); 664 char *bla = "GeneFluct3D::ApplyGrowthFactor_Error: set GrowthFactor first"; 665 cout<<bla<<endl; throw ParmError(bla); 666 } 667 668 InterpFunc interpinv(loscom2zred_min_,loscom2zred_max_,loscom2zred_); 646 669 unsigned short ok; 647 670 … … 969 992 } 970 993 971 void GeneFluct3D::AddAGN(double l msol,double lsigma)994 void GeneFluct3D::AddAGN(double lfjy,double lsigma,double powlaw) 972 995 // Add AGN flux into simulation: 973 996 // --- Procedure: 974 997 // 1. lancer "cmvdefsurv" avec les parametres du survey 998 // (au redshift de reference du survey) 975 999 // et recuperer l'angle solide "angsol sr" du pixel elementaire 976 1000 // au centre du cube. … … 978 1002 // 3. regarder l'histo "hlfang" et en deduire un equivalent gaussienne 979 1003 // cad une moyenne <log10(S)> et un sigma "sig" 980 // Attention: la distribution n'etant pas gaussienne 981 // 4. re-lancer "cmvdefsurv" en ajoutant l'info sur les AGN 982 // "cmvdefsurv ... -G <log10(S)> ..." 983 // et recuperer le log10(masse solaire equivalente) 1004 // Attention: la distribution n'est pas gaussienne les "mean,sigma" 1005 // de l'histo ne sont pas vraiment ce que l'on veut 984 1006 // --- Limitations actuelle du code: 985 // a. l'angle solide du pixel est pris au centre du cube 986 // et ne varie pas avec la distance a l'interieur du cube 987 // b. la taille en dNu des pixels (selon z) est supposee constante 988 // et egale a celle calculee pour le centre du cube 989 // c. les AGN sont supposes plats en flux 990 // d. le flux des AGN est mis dans une colonne Oz (indice k) 991 // et pas sur la ligne de visee 992 // e. la distribution est approximee a une gaussienne 993 // .. C'est une approximation pour un observateur loin du centre du cube 994 // et pour un cube peu epais / distance observateur 1007 // . les AGN sont supposes en loi de puissance IDENTIQUE pour tout theta,phi 1008 // . le flux des AGN est mis dans une colonne Oz (indice k) et pas sur la ligne de visee 1009 // . la distribution est approximee a une gaussienne 1010 // ... C'est une approximation pour un observateur loin du centre du cube 1011 // et pour un cube peu epais / distance observateur 995 1012 // --- Parametres de la routine: 996 // lmsol : c'est le <log10(Msol)> qui est la conversion en masse solaire 997 // du flux depose dans un pixel par les AGN 1013 // llfy : c'est le <log10(S)> du flux depose dans un pixel par les AGN 998 1014 // lsigma : c'est le sigma de la distribution 1015 // powlaw : c'est la pente de ls distribution cad que le flux "lmsol" 1016 // et considere comme le flux a 1.4GHz et qu'on suppose une loi 1017 // F(nu) = (1.4GHz/nu)^powlaw * F(1.4GHz) 999 1018 // - Comme on est en echelle log10(): 1000 1019 // on tire log10(Msol) + X … … 1003 1022 // - Pas de probleme de pixel negatif car on a une multiplication! 1004 1023 { 1005 if(lp_>0) cout<<"--- AddAGN: lmsol = "<<lmsol<<" , sigma = "<<lsigma<<endl;1024 if(lp_>0) cout<<"--- AddAGN: <log10(S Jy)> = "<<lfjy<<" , sigma = "<<lsigma<<endl; 1006 1025 check_array_alloc(); 1007 1026 1008 double m = pow(10.,lmsol); 1009 1010 double sum=0., sum2=0., nsum=0.; 1011 for(long l=0;l<Nz_;l++) { 1012 double a = lsigma*NorRand(); 1013 a = m*pow(10.,a); 1014 // On met le meme tirage le long de Oz (indice k) 1015 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) { 1016 int_8 ip = IndexR(i,j,l); 1017 data_[ip] += a; 1018 } 1019 sum += a; sum2 += a*a; nsum += 1.; 1020 } 1021 1022 if(nsum>1.) { 1027 if(cosmo_ == NULL || redshref_<0.| loscom2zred_.size()<1) { 1028 char *bla = "GeneFluct3D::AddAGN_Error: set Observator and Cosmology first"; 1029 cout<<bla<<endl; throw ParmError(bla); 1030 } 1031 1032 // La distance angulaire/luminosite/Dnu au centre 1033 double dangref = cosmo_->Dang(redshref_); 1034 double dlumref = cosmo_->Dlum(redshref_); 1035 double dredref = Dz_/(cosmo_->Dhubble()/cosmo_->E(redshref_)); 1036 double dnuref = Fr_HyperFin_Par *dredref/pow(1.+redshref_,2.); // GHz 1037 double fagnref = pow(10.,lfjy)*(dnuref*1.e9); // Jy.Hz 1038 double magnref = FluxHI2Msol(fagnref*Jansky2Watt_cst,dlumref); // Msol 1039 if(lp_>0) { 1040 cout<<"Au centre: z="<<redshref_<<", dredref="<<dredref<<", dnuref="<<dnuref<<" GHz"<<endl 1041 <<" dang="<<dangref<<" Mpc, dlum="<<dlumref<<" Mpc," 1042 <<" fagnref="<<fagnref<<" Jy.Hz (a 1.4GHz), magnref="<<magnref<<" Msol"<<endl; 1043 } 1044 1045 if(powlaw!=0.) { 1046 // F(nu) = (nu GHz/1.4 Ghz)^p * F(1.4GHz) et nu = 1.4 GHz / (1+z) 1047 magnref *= pow(1/(1.+redshref_),powlaw); 1048 if(lp_>0) cout<<" powlaw="<<powlaw<<" -> change magnref to "<<magnref<<" Msol"<<endl; 1049 } 1050 1051 // Les infos en fonction de l'indice "l" selon Oz 1052 vector<double> correction; 1053 InterpFunc interpinv(loscom2zred_min_,loscom2zred_max_,loscom2zred_); 1054 for(long l=0;l<Nz_;l++) { 1055 double z = fabs(xobs_[2] - l*Dz_); 1056 double zred = interpinv(z); 1057 double dang = cosmo_->Dang(zred); // pour variation angle solide 1058 double dlum = cosmo_->Dlum(zred); // pour variation conversion mass HI 1059 double dred = Dz_/(cosmo_->Dhubble()/cosmo_->E(zred)); 1060 double dnu = Fr_HyperFin_Par *dred/pow(1.+zred,2.); // pour variation dNu 1061 double corr = dnu/dnuref*pow(dangref/dang*dlum/dlumref,2.); 1062 if(powlaw!=0.) corr *= pow((1.+redshref_)/(1.+zred),powlaw); 1063 correction.push_back(corr); 1064 if(lp_>0 && (l==0 || abs(l-Nz_/2)<2 || l==Nz_-1)) { 1065 cout<<"l="<<l<<" z="<<z<<" red="<<zred 1066 <<" da="<<dang<<" dlu="<<dlum<<" dred="<<dred 1067 <<" dnu="<<dnu<<" -> corr="<<corr<<endl; 1068 } 1069 } 1070 1071 double sum=0., sum2=0., nsum=0.; 1072 for(long i=0;i<Nx_;i++) for(long j=0;j<Ny_;j++) { 1073 double a = lsigma*NorRand(); 1074 a = magnref*pow(10.,a); 1075 // On met le meme tirage le long de Oz (indice k) 1076 for(long l=0;l<Nz_;l++) { 1077 int_8 ip = IndexR(i,j,l); 1078 data_[ip] += a*correction[l]; 1079 } 1080 sum += a; sum2 += a*a; nsum += 1.; 1081 } 1082 1083 if(lp_>0 && nsum>1.) { 1023 1084 sum /= nsum; 1024 1085 sum2 = sum2/nsum - sum*sum; … … 1039 1100 } 1040 1101 } 1102 1103 1104 1105 //------------------------------------------------------------------- 1106 //------------------------------------------------------------------- 1107 //--------------------- BRICOLO A NE PAS GARDER --------------------- 1108 //------------------------------------------------------------------- 1109 //------------------------------------------------------------------- 1110 int GeneFluct3D::ComputeSpectrum_bricolo(HistoErr& herr) 1111 // Compute spectrum from "T" and fill HistoErr "herr" 1112 // T : dans le format standard de GeneFuct3D: T(nz,ny,nx) 1113 // cad T(kz,ky,kx) avec 0<kz<kz_nyq -ky_nyq<ky<ky_nyq -kx_nyq<kx<kx_nyq 1114 { 1115 if(lp_>0) cout<<"--- ComputeSpectrum_bricolo ---"<<endl; 1116 check_array_alloc(); 1117 1118 if(herr.NBins()<0) return -1; 1119 herr.Zero(); 1120 1121 // Attention a l'ordre 1122 for(long i=0;i<Nx_;i++) { 1123 long ii = (i>Nx_/2) ? Nx_-i : i; 1124 double kx = ii*Dkx_; kx *= kx; 1125 for(long j=0;j<Ny_;j++) { 1126 if(i==0 && j==0) continue; 1127 long jj = (j>Ny_/2) ? Ny_-j : j; 1128 double ky = jj*Dky_; ky *= ky; 1129 for(long l=1;l<NCz_;l++) { 1130 double kz = l*Dkz_; kz *= kz; 1131 double k = sqrt(kx+ky+kz); 1132 double pk = MODULE2(T_(l,j,i)); 1133 herr.Add(k,pk); 1134 } 1135 } 1136 } 1137 herr.ToVariance(); 1138 1139 // renormalize to directly compare to original spectrum 1140 double norm = Vol_; 1141 herr *= norm; 1142 1143 return 0; 1144 } 1145 1146 int GeneFluct3D::ComputeSpectrum2D_bricolo(Histo2DErr& herr) 1147 { 1148 if(lp_>0) cout<<"--- ComputeSpectrum2D_bricolo ---"<<endl; 1149 check_array_alloc(); 1150 1151 if(herr.NBinX()<0 || herr.NBinY()<0) return -1; 1152 herr.Zero(); 1153 1154 // Attention a l'ordre 1155 for(long i=0;i<Nx_;i++) { 1156 long ii = (i>Nx_/2) ? Nx_-i : i; 1157 double kx = ii*Dkx_; kx *= kx; 1158 for(long j=0;j<Ny_;j++) { 1159 if(i==0 && j==0) continue; 1160 long jj = (j>Ny_/2) ? Ny_-j : j; 1161 double ky = jj*Dky_; ky *= ky; 1162 double kt = sqrt(kx+ky); 1163 for(long l=1;l<NCz_;l++) { 1164 double kz = l*Dkz_; 1165 double pk = MODULE2(T_(l,j,i)); 1166 herr.Add(kt,kz,pk); 1167 } 1168 } 1169 } 1170 herr.ToVariance(); 1171 1172 // renormalize to directly compare to original spectrum 1173 double norm = Vol_; 1174 herr *= norm; 1175 1176 return 0; 1177 }
Note:
See TracChangeset
for help on using the changeset viewer.