Changeset 3320 in Sophya for trunk/Cosmo/SimLSS/schechter.cc
- Timestamp:
- Sep 5, 2007, 9:58:05 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cosmo/SimLSS/schechter.cc
r3196 r3320 8 8 9 9 #include "pexceptions.h" 10 #include "histos.h" 11 #include "perandom.h" 12 #include "tvector.h" 13 #include "fioarr.h" 10 14 11 15 #include "constcosmo.h" 16 #include "geneutils.h" 12 17 #include "schechter.h" 13 18 … … 27 32 Schechter::Schechter(Schechter& f) 28 33 : nstar_(f.nstar_) , mstar_(f.mstar_) , alpha_(f.alpha_) , outvalue_(f.outvalue_) 34 { 35 } 36 37 Schechter::Schechter(void) 38 : nstar_(0.) , mstar_(0.) , alpha_(0.) , outvalue_(0) 29 39 { 30 40 } … … 45 55 } 46 56 57 unsigned short Schechter::GetOutValue(void) 58 { 59 return outvalue_; 60 } 61 62 void Schechter::SetParam(double nstar,double mstar,double alpha) 63 { 64 nstar_ = nstar; mstar_ = mstar; alpha_ = alpha; 65 } 66 67 void Schechter::GetParam(double& nstar,double& mstar,double& alpha) 68 { 69 nstar = nstar_; mstar = mstar_; alpha = alpha_; 70 } 71 47 72 double Schechter::operator() (double m) 48 73 // Return : "dn/dm = f(m)" or "m*dn/dm = f(m)" … … 52 77 if(outvalue_) dndm *= m; // on veut m*dn/dm 53 78 return dndm; 79 } 80 81 82 double Schechter::Integrate(double massmin,double massmax,int npt) 83 // Integrate from massmin to massmax with at least npt points log10 spaced 84 { 85 if(massmin<=0. || massmax<=0. || massmax<=massmin) return 0.; 86 if(npt<1) npt = 100; 87 double lmassmin = log10(massmin), lmassmax = log10(massmax); 88 double perc=0.01, dlxinc=(lmassmax-lmassmin)/npt, dlxmax=10.*dlxinc; unsigned short glorder=4; 89 double sum = IntegrateFuncLog(*this,lmassmin,lmassmax,perc,dlxinc,dlxmax,glorder); 90 return sum; 54 91 } 55 92 … … 63 100 cout<<endl; 64 101 } 102 103 /////////////////////////////////////////////////////////// 104 //******* Les facilites pour tirer sur Schechter ********// 105 /////////////////////////////////////////////////////////// 106 107 SchechterMassDist::SchechterMassDist(Schechter sch,double massmin,double massmax,int nbinmass) 108 // On veut une fonction de tirage aleatoire de la masse de N galaxies sur une Schechter 109 // Pour optimiser on cree (eventuellement) des histos de tirage 110 // ATTENTION: on donne les limites en masses pour les histos mais leurs abscisses 111 // sont en log10(masse): histo [log10(massmin),log10(massmax)] avec nbinmass bins 112 // Si nbinmass<0 alors c'est le nombre de points par decade 113 : sch_(sch) , sch_outvalue_(sch.GetOutValue()) 114 , massmin_(massmin) , massmax_(massmax) , nbinmass_(nbinmass) 115 , ngalmin_(0) , ngalmax_(0) , nvalngal_(0) 116 , ntrial_dir(0) , ntrial_tab(0) 117 , hmdndm_(NULL) , tirhmdndm_(NULL) 118 { 119 if(massmin_>massmax_ || massmin_<=0. || massmax_<=0.|| nbinmass_==0) { 120 cout<<"SchechterMassDist::SchechterMassDist: error in input values"<<endl; 121 throw ParmError("SchechterMassDist::SchechterMassDist: error in input values"); 122 } 123 124 // Creation du tirage aleatoire sur la Schechter 125 sch_outvalue_ = sch.GetOutValue(); // on sauve la configuration de la schechter 126 sch.SetOutValue(1); // on veut m*dN/dm 127 double lnx1 = log10(massmin_), lnx2 = log10(massmax_); // Binning en log10 de la masse 128 if(nbinmass_<0) nbinmass_ = int((-nbinmass_)*(lnx2-lnx1+1.)); 129 hmdndm_ = new Histo(lnx1,lnx2,nbinmass_); hmdndm_->ReCenterBin(); 130 FuncToHisto(sch,*hmdndm_,true); // true -> bin en log10(x) 131 tirhmdndm_ = new FunRan(*hmdndm_,true); // true -> histo est pdf 132 sch.SetOutValue(sch_outvalue_); // on remet a la valeur initiale 133 } 134 135 SchechterMassDist::SchechterMassDist(void) 136 : sch_outvalue_(0) 137 , massmin_(0.) , massmax_(0.) , nbinmass_(0) 138 , ngalmin_(0) , ngalmax_(0) , nvalngal_(0) 139 , ntrial_dir(0) , ntrial_tab(0) 140 , hmdndm_(NULL) , tirhmdndm_(NULL) 141 { 142 } 143 144 SchechterMassDist::~SchechterMassDist(void) 145 { 146 Delete(); 147 } 148 149 void SchechterMassDist::Delete(void) 150 { 151 if(hmdndm_) delete hmdndm_; 152 if(tirhmdndm_) delete tirhmdndm_; 153 hmass_.resize(0); 154 tmass_.resize(0); 155 ntrial_dir = ntrial_tab = 0; 156 } 157 158 int SchechterMassDist::GetMassLim(double& massmin,double& massmax) 159 { 160 massmin = massmin_; 161 massmax = massmax_; 162 return nbinmass_; 163 } 164 165 int SchechterMassDist::SetNgalLim(int ngalmax,int ngalmin,unsigned long nalea) 166 // Creation des Histos de tirage pour ngalmin a ngalmax galaxies 167 { 168 int lp=2; 169 ngalmin_=ngalmax_=nvalngal_=0; 170 if(ngalmin<=0) ngalmin=1; 171 if(ngalmax<ngalmin || ngalmax==1) return 0; 172 ngalmin_ = ngalmin; 173 ngalmax_ = ngalmax; 174 nvalngal_ = ngalmax-ngalmin+1; 175 176 if(nalea<1) nalea = 100000; 177 178 if(lp>0) cout<<"SchechterMassDist::SetNgalLim: ngal=[" 179 <<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_ 180 <<" filling with "<<nalea<<" trials"<<endl; 181 182 //------- Construct histo 183 double lnx1 = log10(massmin_), lnx2 = log10(massmax_); 184 if(lp>0) cout<<"> Creating "<<nvalngal_<<" histos ["<<lnx1<<","<<lnx2<<"] n="<<nbinmass_<<endl; 185 for(int i=ngalmin_;i<=ngalmax_;i++) { 186 Histo h(*hmdndm_); h.Zero(); 187 hmass_.push_back(h); 188 } 189 if(lp>1) cout<<"...number of histos is "<<hmass_.size()<<endl; 190 191 //------- Remplissage random 192 sch_.SetOutValue(1); // on veut m*dN/dm 193 int lpmod = nalea/20; if(lpmod<=0) lpmod=1; 194 double s1=0., sc1=0.; unsigned long ns1=0; 195 double sax=0., scax=0.; unsigned long nsax=0; 196 for(unsigned long ia=0;ia<nalea;ia++) { 197 if(lp>1 && ia%lpmod==0) cout<<"...tirage "<<ia<<endl; 198 double sum = 0.; 199 for(int i=1;i<=ngalmax_;i++) { 200 //double l10m = tirhmdndm_->Random(); 201 double l10m = tirhmdndm_->RandomInterp(); 202 double m = pow(10.,l10m); 203 sum += m; 204 s1 += m; sc1 += m*m; ns1++; 205 int ipo = i-ngalmin_; 206 if(ipo<0) continue; 207 // ATTENTION: l'histo de tirage stoque le log10(moyenne=somme_masses/ngal). 208 // Ca permet d'avoir le meme binning quelque soit ngal 209 double v = log10(sum/(double)i); 210 hmass_[ipo].Add(v); 211 if(i==ngalmax) {sax += sum/(double)i; scax += sum/(double)i*sum/(double)i; nsax++;} 212 } 213 } 214 sch_.SetOutValue(sch_outvalue_); // on remet a la valeur initiale 215 216 if(ns1>1) { 217 s1 /= ns1; sc1 = sc1/ns1 - s1*s1; 218 cout<<"...Mean mass for ngal=1: "<<s1<<" ("<<log10(fabs(s1))<<")" 219 <<" s="<<sqrt(fabs(sc1))<<" (ntrials "<<ns1<<")"<<endl; 220 } 221 if(nsax>1) { 222 sax /= nsax; scax = scax/nsax - sax*sax; 223 cout<<"...Mean mass for ngal="<<ngalmax_<<": "<<sax<<" ("<<log10(fabs(sax))<<")" 224 <<" s="<<sqrt(fabs(scax))<<" (ntrials "<<nsax<<")"<<endl; 225 } 226 227 //------- Generation des classes de tirage aleatoire et des histos de verif 228 if(lp>0) cout<<"> Creating "<<nvalngal_<<" FunRan"<<endl; 229 for(unsigned int i=0;i<hmass_.size();i++) { 230 FunRan t(hmass_[i],true); 231 tmass_.push_back(t); 232 } 233 if(lp>1) cout<<"...number of funran is "<<tmass_.size()<<endl; 234 235 return nvalngal_; 236 } 237 238 int SchechterMassDist::GetNgalLim(int& ngalmax,int& ngalmin) 239 { 240 ngalmax = ngalmax_; 241 ngalmin = ngalmin_; 242 return nvalngal_; 243 } 244 245 Histo SchechterMassDist::GetHmDnDm(void) const 246 { 247 return *hmdndm_; 248 } 249 250 FunRan SchechterMassDist::GetTmDnDm(void) const 251 { 252 return *tirhmdndm_; 253 } 254 255 Histo SchechterMassDist::GetHisto(int i) const 256 { 257 if(i<0 || i>=nvalngal_) { 258 cout<<"SchechterMassDist::GetHisto: error in input values"<<endl; 259 throw ParmError("SchechterMassDist::GetHisto: error in input values"); 260 } 261 return hmass_[i]; 262 } 263 264 FunRan SchechterMassDist::GetFunRan(int i) const 265 { 266 if(i<0 || i>=nvalngal_) { 267 cout<<"SchechterMassDist::GetFunRan: error in input values"<<endl; 268 throw ParmError("SchechterMassDist::GetFunRan: error in input values"); 269 } 270 return tmass_[i]; 271 } 272 273 double SchechterMassDist::TirMass(int ngal) 274 { 275 if(ngal<1) return 0.; 276 277 int ipo = IndexFrNGal(ngal); 278 double masse_des_ngal = 0.; 279 if(ipo<0) { // Pas d'histos de tirage pour ce nombre de galaxies 280 for(long i=0;i<ngal;i++) { // On tire donc ngal fois sur la Schechter 281 // double lm = tirhmdndm_->Random(); 282 double lm = tirhmdndm_->RandomInterp(); 283 masse_des_ngal += pow(10.,lm); // ATTENTION abscisse en log10(masse) 284 } 285 ntrial_dir++; 286 } else { 287 // ATTENTION l'histo de tirage stoque le log10(moyenne=somme_masses/ngal) 288 //double lmngal = tmass_[ipo].Random(); 289 double lmngal = tmass_[ipo].RandomInterp(); 290 masse_des_ngal = pow(10.,lmngal) * ngal; 291 ntrial_tab++; 292 } 293 294 return masse_des_ngal; 295 } 296 297 void SchechterMassDist::Print(void) 298 { 299 cout<<"SchechterMassDist::Print: mass=["<<massmin_<<","<<massmax_<<"] n="<<nbinmass_<<endl 300 <<" ngal=["<<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_<<endl; 301 sch_.Print(); 302 } 303 304 void SchechterMassDist::PrintStatus(void) 305 { 306 cout<<"SchechterMassDist::PrintStatus: number of trials: direct="<<ntrial_dir 307 <<" tabulated="<<ntrial_tab<<endl; 308 } 309 310 void SchechterMassDist::WritePPF(string ppfname) 311 { 312 char str[64]; 313 cout<<"SchechterMassDist::WritePPF into "<<ppfname<<endl; 314 POutPersist pos(ppfname.c_str()); 315 316 double nstar,mstar,alpha; 317 sch_.GetParam(nstar,mstar,alpha); 318 TVector<r_8> tdum(20); tdum = 0.; 319 tdum(0) = nstar; 320 tdum(1) = mstar; 321 tdum(2) = alpha; 322 tdum(3) = sch_outvalue_; 323 tdum(4) = massmin_; 324 tdum(5) = massmax_; 325 tdum(6) = nbinmass_; 326 tdum(7) = ngalmin_; 327 tdum(8) = ngalmax_; 328 tdum(9) = nvalngal_; 329 tdum(10) = hmass_.size(); 330 tdum(11) = tmass_.size(); 331 pos << PPFNameTag("SMDparam") << tdum; 332 333 pos << PPFNameTag("SMDhmdndm") << *hmdndm_; 334 pos << PPFNameTag("SMDtirhmdndm") << *tirhmdndm_; 335 336 if(hmass_.size()>0) { 337 for(unsigned int i=0;i<hmass_.size();i++) { 338 sprintf(str,"SMDh%d",NGalFrIndex(i)); 339 pos << PPFNameTag(str) << hmass_[i]; 340 } 341 } 342 343 if(tmass_.size()>0) { 344 for(unsigned int i=0;i<tmass_.size();i++) { 345 sprintf(str,"SMDt%d",NGalFrIndex(i)); 346 Histo hdum(tmass_[i]); 347 pos << PPFNameTag(str) << hdum; 348 } 349 } 350 351 } 352 353 void SchechterMassDist::ReadPPF(string ppfname) 354 { 355 Delete(); // On des-alloue si deja remplit! 356 357 char str[64]; 358 cout<<"SchechterMassDist::ReadPPF from "<<ppfname<<endl; 359 PInPersist pis(ppfname.c_str()); 360 361 TVector<r_8> tdum; 362 pis >> PPFNameTag("SMDparam") >> tdum; 363 sch_.SetParam(tdum(0),tdum(1),tdum(2)); 364 sch_.SetOutValue((unsigned short)(tdum(3)+0.1)); 365 massmin_ = tdum(4); 366 massmax_ = tdum(5); 367 nbinmass_ = int(tdum(6)+0.1); 368 ngalmin_ = int(tdum(7)+0.1); 369 ngalmax_ = int(tdum(8)+0.1); 370 nvalngal_ = int(tdum(9)+0.1); 371 unsigned int nhmass = (unsigned int)(tdum(10)+0.1); 372 unsigned int ntmass = (unsigned int)(tdum(11)+0.1); 373 374 { 375 Histo hdum; 376 pis >> PPFNameTag("SMDhmdndm") >> hdum; 377 hmdndm_ = new Histo(hdum); 378 pis >> PPFNameTag("SMDtirhmdndm") >> hdum; 379 tirhmdndm_ = new FunRan(hdum,false); 380 } 381 382 if(nhmass>0) { 383 for(unsigned int i=0;i<nhmass;i++) { 384 sprintf(str,"SMDh%d",NGalFrIndex(i)); 385 Histo hdum; 386 pis >> PPFNameTag(str) >> hdum; 387 hmass_.push_back(hdum); 388 } 389 } 390 391 if(ntmass>0) { 392 for(unsigned int i=0;i<ntmass;i++) { 393 sprintf(str,"SMDt%d",NGalFrIndex(i)); 394 Histo hdum; 395 pis >> PPFNameTag(str) >> hdum; 396 FunRan fdum(hdum,false); 397 tmass_.push_back(fdum); 398 } 399 } 400 401 } 402 403 404 /////////////////////////////////////////////////////////// 405 //***************** Fonctions de Check ******************// 406 /////////////////////////////////////////////////////////// 407 408 bool IsCompatible(Schechter& sch1,Schechter& sch2,double eps) 409 // on compare les differences a eps pres 410 { 411 if(eps<=0.) eps=1.e-4; 412 double nstar1,mstar1,alpha1; 413 sch1.GetParam(nstar1,mstar1,alpha1); 414 double nstar2,mstar2,alpha2; 415 sch2.GetParam(nstar2,mstar2,alpha2); 416 417 if(fabs(nstar1-nstar2)>fabs(nstar1+nstar2)/2.*eps) return false; 418 if(fabs(mstar1-mstar2)>fabs(mstar1+mstar2)/2.*eps) return false; 419 if(fabs(alpha1-alpha2)>fabs(alpha1+alpha2)/2.*eps) return false; 420 return true; 421 } 422 65 423 66 424 /////////////////////////////////////////////////////////// … … 98 456 return f *d*d / 2.0e-28; 99 457 } 458
Note:
See TracChangeset
for help on using the changeset viewer.