#include "sopnamsp.h" #include "machdefs.h" #include #include #include #include #include #include "pexceptions.h" #include "histos.h" #include "perandom.h" #include "tvector.h" #include "fioarr.h" #include "constcosmo.h" #include "geneutils.h" #include "schechter.h" /////////////////////////////////////////////////////////// //***************** Schechter Functions *****************// /////////////////////////////////////////////////////////// // HI mass function: // see M.Zwaan astroph-0502257 (MNRAS Letters, Volume 359, Issue 1, pp. L30-L34.) // see M.Zwaan astroph-9707109 (ApJ, Volume 509, Issue 2, pp. 687-702.) Schechter::Schechter(double nstar,double mstar,double alpha) : nstar_(nstar) , mstar_(mstar) , alpha_(alpha) , outvalue_(0) { } Schechter::Schechter(Schechter& f) : nstar_(f.nstar_) , mstar_(f.mstar_) , alpha_(f.alpha_) , outvalue_(f.outvalue_) { } Schechter::Schechter(void) : nstar_(0.) , mstar_(0.) , alpha_(0.) , outvalue_(0) { } Schechter::~Schechter(void) { } void Schechter::SetOutValue(unsigned short outvalue) // outvalue = 0 : give dn/dm // = 1 : give m*dn/dm { if(outvalue>1) { cout<<"Schechter::SetOutValue: Error bad outvalue: "< return "; if(outvalue_) cout<<"m*dn/dm)"; else cout<<"dn/dm)"; cout<massmax_ || massmin_<=0. || massmax_<=0.|| nbinmass_==0) { cout<<"SchechterMassDist::SchechterMassDist: error in input values"<ReCenterBin(); FuncToHisto(sch,*hmdndm_,true); // true -> bin en log10(x) tirhmdndm_ = new FunRan(*hmdndm_,true); // true -> histo est pdf sch.SetOutValue(sch_outvalue_); // on remet a la valeur initiale } SchechterMassDist::SchechterMassDist(void) : sch_outvalue_(0) , massmin_(0.) , massmax_(0.) , nbinmass_(0) , ngalmin_(0) , ngalmax_(0) , nvalngal_(0) , ntrial_dir(0) , ntrial_tab(0) , hmdndm_(NULL) , tirhmdndm_(NULL) { } SchechterMassDist::~SchechterMassDist(void) { Delete(); } void SchechterMassDist::Delete(void) { if(hmdndm_) delete hmdndm_; if(tirhmdndm_) delete tirhmdndm_; hmass_.resize(0); tmass_.resize(0); ntrial_dir = ntrial_tab = 0; } int SchechterMassDist::GetMassLim(double& massmin,double& massmax) { massmin = massmin_; massmax = massmax_; return nbinmass_; } int SchechterMassDist::SetNgalLim(int ngalmax,int ngalmin,unsigned long nalea) // Creation des Histos de tirage pour ngalmin a ngalmax galaxies { int lp=2; ngalmin_=ngalmax_=nvalngal_=0; if(ngalmin<=0) ngalmin=1; if(ngalmax0) cout<<"SchechterMassDist::SetNgalLim: ngal=[" <0) cout<<"> Creating "<1 && ia%lpmod==0) cout<<"...tirage "<Random(); double l10m = tirhmdndm_->RandomInterp(); double m = pow(10.,l10m); sum += m; s1 += m; sc1 += m*m; ns1++; int ipo = i-ngalmin_; if(ipo<0) continue; // ATTENTION: l'histo de tirage stoque le log10(moyenne=somme_masses/ngal). // Ca permet d'avoir le meme binning quelque soit ngal double v = log10(sum/(double)i); hmass_[ipo].Add(v); if(i==ngalmax) {sax += sum/(double)i; scax += sum/(double)i*sum/(double)i; nsax++;} } } sch_.SetOutValue(sch_outvalue_); // on remet a la valeur initiale if(ns1>1) { s1 /= ns1; sc1 = sc1/ns1 - s1*s1; cout<<"...Mean mass for ngal=1: "<1) { sax /= nsax; scax = scax/nsax - sax*sax; cout<<"...Mean mass for ngal="<0) cout<<"> Creating "<1) cout<<"...number of funran is "<=nvalngal_) { cout<<"SchechterMassDist::GetHisto: error in input values"<=nvalngal_) { cout<<"SchechterMassDist::GetFunRan: error in input values"<Random(); double lm = tirhmdndm_->RandomInterp(); masse_des_ngal += pow(10.,lm); // ATTENTION abscisse en log10(masse) } ntrial_dir++; } else { // ATTENTION l'histo de tirage stoque le log10(moyenne=somme_masses/ngal) //double lmngal = tmass_[ipo].Random(); double lmngal = tmass_[ipo].RandomInterp(); masse_des_ngal = pow(10.,lmngal) * ngal; ntrial_tab++; } return masse_des_ngal; } void SchechterMassDist::Print(void) { cout<<"SchechterMassDist::Print: mass=["< tdum(20); tdum = 0.; tdum(0) = nstar; tdum(1) = mstar; tdum(2) = alpha; tdum(3) = sch_outvalue_; tdum(4) = massmin_; tdum(5) = massmax_; tdum(6) = nbinmass_; tdum(7) = ngalmin_; tdum(8) = ngalmax_; tdum(9) = nvalngal_; tdum(10) = hmass_.size(); tdum(11) = tmass_.size(); pos << PPFNameTag("SMDparam") << tdum; pos << PPFNameTag("SMDhmdndm") << *hmdndm_; pos << PPFNameTag("SMDtirhmdndm") << *tirhmdndm_; if(hmass_.size()>0) { for(unsigned int i=0;i0) { for(unsigned int i=0;i tdum; pis >> PPFNameTag("SMDparam") >> tdum; sch_.SetParam(tdum(0),tdum(1),tdum(2)); sch_.SetOutValue((unsigned short)(tdum(3)+0.1)); massmin_ = tdum(4); massmax_ = tdum(5); nbinmass_ = int(tdum(6)+0.1); ngalmin_ = int(tdum(7)+0.1); ngalmax_ = int(tdum(8)+0.1); nvalngal_ = int(tdum(9)+0.1); unsigned int nhmass = (unsigned int)(tdum(10)+0.1); unsigned int ntmass = (unsigned int)(tdum(11)+0.1); { Histo hdum; pis >> PPFNameTag("SMDhmdndm") >> hdum; hmdndm_ = new Histo(hdum); pis >> PPFNameTag("SMDtirhmdndm") >> hdum; tirhmdndm_ = new FunRan(hdum,false); } if(nhmass>0) { for(unsigned int i=0;i> PPFNameTag(str) >> hdum; hmass_.push_back(hdum); } } if(ntmass>0) { for(unsigned int i=0;i> PPFNameTag(str) >> hdum; FunRan fdum(hdum,false); tmass_.push_back(fdum); } } } /////////////////////////////////////////////////////////// //***************** Fonctions de Check ******************// /////////////////////////////////////////////////////////// bool IsCompatible(Schechter& sch1,Schechter& sch2,double eps) // on compare les differences a eps pres { if(eps<=0.) eps=1.e-4; double nstar1,mstar1,alpha1; sch1.GetParam(nstar1,mstar1,alpha1); double nstar2,mstar2,alpha2; sch2.GetParam(nstar2,mstar2,alpha2); if(fabs(nstar1-nstar2)>fabs(nstar1+nstar2)/2.*eps) return false; if(fabs(mstar1-mstar2)>fabs(mstar1+mstar2)/2.*eps) return false; if(fabs(alpha1-alpha2)>fabs(alpha1+alpha2)/2.*eps) return false; return true; } /////////////////////////////////////////////////////////// //******************* Le Flux a 21cm ********************// /////////////////////////////////////////////////////////// double Msol2FluxHI(double m,double d) // Input: // m : masse de HI en "Msol" // d : distance en "Mpc" (si cosmo d=DLum(z)) // Return: // le flux total emis a 21 cm en W/m^2 // Ref: // -- Binney & Merrifield, Galactic Astronomy p474 (ed:1998) // S(W/m^2) = 1e-26 * Nu_21cm(Hz) * m(en masse solaire) /(2.35e5 * C(km/s) * Dlum^2) // = 2.0e-28 * m / Dlum^2 // -- J.Peterson & K.Bandura, astroph-0606104 (eq 7) // F.Abdalla & Rawlings, astroph-0411342 (eq 7 mais pb de d'unites?) // (A_21cm = 2.86888e-15 s^-1) // S(W/m^2) = 3/4 * h(J.s) * Nu_21cm(Hz) * A_21cm(s^-1) * Msol(kg)/m_proton(kg) // / (4 Pi) / (Dlum(Mpc) * 3.0857e22(m/Mpc))^2 // = 2.0e-28 * m / Dlum^2 //------------- { return 2.0e-28 * m / (d*d); } double FluxHI2Msol(double f,double d) // Input: // f : flux total emis a 21 cm en W/m^2 // d : distance en "Mpc" (si cosmo d=DLum(z)) // Return: // m : masse de HI en "Msol" { return f *d*d / 2.0e-28; }