| 1 | #include "machdefs.h"
 | 
|---|
| 2 | #include <iostream>
 | 
|---|
| 3 | #include <stdlib.h>
 | 
|---|
| 4 | #include <stdio.h>
 | 
|---|
| 5 | #include <string.h>
 | 
|---|
| 6 | #include <math.h>
 | 
|---|
| 7 | 
 | 
|---|
| 8 | #include "pexceptions.h"
 | 
|---|
| 9 | #include "histos.h"
 | 
|---|
| 10 | #include "perandom.h"
 | 
|---|
| 11 | #include "tvector.h"
 | 
|---|
| 12 | #include "fioarr.h"
 | 
|---|
| 13 | 
 | 
|---|
| 14 | #include "constcosmo.h"
 | 
|---|
| 15 | #include "geneutils.h"
 | 
|---|
| 16 | #include "schechter.h"
 | 
|---|
| 17 | 
 | 
|---|
| 18 | namespace SOPHYA {
 | 
|---|
| 19 | 
 | 
|---|
| 20 | ///////////////////////////////////////////////////////////
 | 
|---|
| 21 | //***************** Schechter Functions *****************//
 | 
|---|
| 22 | ///////////////////////////////////////////////////////////
 | 
|---|
| 23 | 
 | 
|---|
| 24 | // HI mass function:
 | 
|---|
| 25 | //    see M.Zwaan astroph-0502257 (MNRAS Letters, Volume 359, Issue 1, pp. L30-L34.)
 | 
|---|
| 26 | //    see M.Zwaan astroph-9707109 (ApJ, Volume 509, Issue 2, pp. 687-702.)
 | 
|---|
| 27 | 
 | 
|---|
| 28 | Schechter::Schechter(double nstar,double mstar,double alpha)
 | 
|---|
| 29 |   : nstar_(nstar) , mstar_(mstar) , alpha_(alpha) , outvalue_(0)
 | 
|---|
| 30 | {
 | 
|---|
| 31 | }
 | 
|---|
| 32 | 
 | 
|---|
| 33 | Schechter::Schechter(Schechter& f)
 | 
|---|
| 34 |   : nstar_(f.nstar_) , mstar_(f.mstar_) , alpha_(f.alpha_) , outvalue_(f.outvalue_)
 | 
|---|
| 35 | {
 | 
|---|
| 36 | }
 | 
|---|
| 37 | 
 | 
|---|
| 38 | Schechter::Schechter(void)
 | 
|---|
| 39 |   : nstar_(0.) , mstar_(0.) , alpha_(0.) , outvalue_(0)
 | 
|---|
| 40 | {
 | 
|---|
| 41 | }
 | 
|---|
| 42 | 
 | 
|---|
| 43 | Schechter::~Schechter(void)
 | 
|---|
| 44 | {
 | 
|---|
| 45 | }
 | 
|---|
| 46 | 
 | 
|---|
| 47 | void Schechter::SetOutValue(unsigned short outvalue)
 | 
|---|
| 48 | // outvalue = 0 : give dn/dm
 | 
|---|
| 49 | //          = 1 : give m*dn/dm
 | 
|---|
| 50 | {
 | 
|---|
| 51 |   if(outvalue>1) {
 | 
|---|
| 52 |     cout<<"Schechter::SetOutValue: Error bad outvalue: "<<outvalue<<endl;
 | 
|---|
| 53 |     throw ParmError("Schechter::SetOutValue: Error bad outvalue");
 | 
|---|
| 54 |   }
 | 
|---|
| 55 |   outvalue_ = outvalue;
 | 
|---|
| 56 | }
 | 
|---|
| 57 | 
 | 
|---|
| 58 | unsigned short Schechter::GetOutValue(void)
 | 
|---|
| 59 | {
 | 
|---|
| 60 |   return outvalue_;
 | 
|---|
| 61 | }
 | 
|---|
| 62 | 
 | 
|---|
| 63 | void Schechter::SetParam(double nstar,double mstar,double alpha)
 | 
|---|
| 64 | {
 | 
|---|
| 65 |   nstar_ = nstar; mstar_ = mstar; alpha_ = alpha;
 | 
|---|
| 66 | }
 | 
|---|
| 67 | 
 | 
|---|
| 68 | void Schechter::GetParam(double& nstar,double& mstar,double& alpha)
 | 
|---|
| 69 | {
 | 
|---|
| 70 |   nstar = nstar_; mstar = mstar_; alpha = alpha_;
 | 
|---|
| 71 | }
 | 
|---|
| 72 | 
 | 
|---|
| 73 | double Schechter::operator() (double m)
 | 
|---|
| 74 | // Return : "dn/dm = f(m)" or "m*dn/dm = f(m)"
 | 
|---|
| 75 | {
 | 
|---|
| 76 |   double x = m/mstar_;
 | 
|---|
| 77 |   double dndm = nstar_/mstar_ * pow(x,alpha_) * exp(-x);
 | 
|---|
| 78 |   if(outvalue_) dndm *= m;  // on veut m*dn/dm
 | 
|---|
| 79 |   return dndm;
 | 
|---|
| 80 | }
 | 
|---|
| 81 | 
 | 
|---|
| 82 | 
 | 
|---|
| 83 | double Schechter::Integrate(double massmin,double massmax,int npt)
 | 
|---|
| 84 | // Integrate from massmin to massmax with at least npt points log10 spaced
 | 
|---|
| 85 | {
 | 
|---|
| 86 |  if(massmin<=0. || massmax<=0. || massmax<=massmin) return 0.;
 | 
|---|
| 87 |  if(npt<1) npt = 100;
 | 
|---|
| 88 |  double lmassmin = log10(massmin), lmassmax = log10(massmax);
 | 
|---|
| 89 |  double perc=0.01, dlxinc=(lmassmax-lmassmin)/npt, dlxmax=10.*dlxinc; unsigned short glorder=4;
 | 
|---|
| 90 |  double sum = IntegrateFuncLog(*this,lmassmin,lmassmax,perc,dlxinc,dlxmax,glorder);
 | 
|---|
| 91 |  return sum;
 | 
|---|
| 92 | }
 | 
|---|
| 93 | 
 | 
|---|
| 94 | void Schechter::Print(void)
 | 
|---|
| 95 | {
 | 
|---|
| 96 |   cout<<"Schechter::Print: nstar="<<nstar_<<" Mpc^-3"
 | 
|---|
| 97 |       <<"  mstar="<<mstar_<<" MSol"
 | 
|---|
| 98 |       <<"  alpha="<<alpha_
 | 
|---|
| 99 |       <<"  (outvalue="<<outvalue_<<" -> return ";
 | 
|---|
| 100 |   if(outvalue_) cout<<"m*dn/dm)"; else cout<<"dn/dm)";
 | 
|---|
| 101 |   cout<<endl;
 | 
|---|
| 102 | }
 | 
|---|
| 103 | 
 | 
|---|
| 104 | ///////////////////////////////////////////////////////////
 | 
|---|
| 105 | //******* Les facilites pour tirer sur Schechter ********//
 | 
|---|
| 106 | ///////////////////////////////////////////////////////////
 | 
|---|
| 107 | 
 | 
|---|
| 108 | SchechterMassDist::SchechterMassDist(Schechter sch,double massmin,double massmax,int nbinmass)
 | 
|---|
| 109 | // On veut une fonction de tirage aleatoire de la masse de N galaxies sur une Schechter
 | 
|---|
| 110 | // Pour optimiser on cree (eventuellement) des histos de tirage
 | 
|---|
| 111 | // ATTENTION: on donne les limites en masses pour les histos mais leurs abscisses
 | 
|---|
| 112 | //   sont en log10(masse): histo [log10(massmin),log10(massmax)] avec nbinmass bins
 | 
|---|
| 113 | // Si nbinmass<0 alors c'est le nombre de points par decade
 | 
|---|
| 114 |   : sch_(sch) , sch_outvalue_(sch.GetOutValue())
 | 
|---|
| 115 |   , massmin_(massmin) , massmax_(massmax) , nbinmass_(nbinmass)
 | 
|---|
| 116 |   , ngalmin_(0) , ngalmax_(0) , nvalngal_(0)
 | 
|---|
| 117 |   , ntrial_dir(0) , ntrial_tab(0)
 | 
|---|
| 118 |   , hmdndm_(NULL) , tirhmdndm_(NULL)
 | 
|---|
| 119 | {
 | 
|---|
| 120 |   if(massmin_>massmax_  || massmin_<=0. || massmax_<=0.|| nbinmass_==0) {
 | 
|---|
| 121 |     cout<<"SchechterMassDist::SchechterMassDist: error in input values"<<endl;
 | 
|---|
| 122 |     throw ParmError("SchechterMassDist::SchechterMassDist: error in input values");
 | 
|---|
| 123 |   }
 | 
|---|
| 124 | 
 | 
|---|
| 125 |   // Creation du tirage aleatoire sur la Schechter
 | 
|---|
| 126 |   sch_outvalue_ = sch.GetOutValue();  // on sauve la configuration de la schechter
 | 
|---|
| 127 |   sch.SetOutValue(1);  // on veut m*dN/dm
 | 
|---|
| 128 |   double lnx1 = log10(massmin_), lnx2 = log10(massmax_); // Binning en log10 de la masse
 | 
|---|
| 129 |   if(nbinmass_<0) nbinmass_ = int((-nbinmass_)*(lnx2-lnx1+1.));
 | 
|---|
| 130 |   hmdndm_ = new Histo(lnx1,lnx2,nbinmass_); hmdndm_->ReCenterBin();
 | 
|---|
| 131 |   FuncToHisto(sch,*hmdndm_,true);  // true -> bin en log10(x)
 | 
|---|
| 132 |   tirhmdndm_ = new FunRan(*hmdndm_,true);  // true -> histo est pdf
 | 
|---|
| 133 |   sch.SetOutValue(sch_outvalue_);  // on remet a la valeur initiale
 | 
|---|
| 134 | }
 | 
|---|
| 135 | 
 | 
|---|
| 136 | SchechterMassDist::SchechterMassDist(void)
 | 
|---|
| 137 |   : sch_outvalue_(0)
 | 
|---|
| 138 |   , massmin_(0.) , massmax_(0.) , nbinmass_(0)
 | 
|---|
| 139 |   , ngalmin_(0) , ngalmax_(0) , nvalngal_(0)
 | 
|---|
| 140 |   , ntrial_dir(0) , ntrial_tab(0)
 | 
|---|
| 141 |   , hmdndm_(NULL) , tirhmdndm_(NULL)
 | 
|---|
| 142 | {
 | 
|---|
| 143 | }
 | 
|---|
| 144 | 
 | 
|---|
| 145 | SchechterMassDist::~SchechterMassDist(void)
 | 
|---|
| 146 | {
 | 
|---|
| 147 |  Delete();
 | 
|---|
| 148 | }
 | 
|---|
| 149 | 
 | 
|---|
| 150 | void SchechterMassDist::Delete(void)
 | 
|---|
| 151 | {
 | 
|---|
| 152 |  if(hmdndm_) delete hmdndm_;
 | 
|---|
| 153 |  if(tirhmdndm_) delete tirhmdndm_;
 | 
|---|
| 154 |  hmass_.resize(0);
 | 
|---|
| 155 |  tmass_.resize(0);
 | 
|---|
| 156 |  ntrial_dir = ntrial_tab = 0;
 | 
|---|
| 157 | }
 | 
|---|
| 158 | 
 | 
|---|
| 159 | int SchechterMassDist::GetMassLim(double& massmin,double& massmax)
 | 
|---|
| 160 | {
 | 
|---|
| 161 |  massmin = massmin_;
 | 
|---|
| 162 |  massmax = massmax_;
 | 
|---|
| 163 |  return nbinmass_;
 | 
|---|
| 164 | }
 | 
|---|
| 165 | 
 | 
|---|
| 166 | int SchechterMassDist::SetNgalLim(int ngalmax,int ngalmin,unsigned long nalea)
 | 
|---|
| 167 | // Creation des Histos de tirage pour ngalmin a ngalmax galaxies
 | 
|---|
| 168 | {
 | 
|---|
| 169 |  int lp=2;
 | 
|---|
| 170 |  ngalmin_=ngalmax_=nvalngal_=0;
 | 
|---|
| 171 |  if(ngalmin<=0) ngalmin=1;
 | 
|---|
| 172 |  if(ngalmax<ngalmin || ngalmax==1) return 0;
 | 
|---|
| 173 |  ngalmin_ = ngalmin;
 | 
|---|
| 174 |  ngalmax_ = ngalmax;
 | 
|---|
| 175 |  nvalngal_ = ngalmax-ngalmin+1;
 | 
|---|
| 176 |   
 | 
|---|
| 177 |  if(nalea<1) nalea = 100000;
 | 
|---|
| 178 | 
 | 
|---|
| 179 |  if(lp>0) cout<<"SchechterMassDist::SetNgalLim: ngal=["
 | 
|---|
| 180 |               <<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_
 | 
|---|
| 181 |               <<" filling with "<<nalea<<" trials"<<endl;
 | 
|---|
| 182 | 
 | 
|---|
| 183 |  //------- Construct histo
 | 
|---|
| 184 |  double lnx1 = log10(massmin_), lnx2 = log10(massmax_);
 | 
|---|
| 185 |  if(lp>0) cout<<"> Creating "<<nvalngal_<<" histos ["<<lnx1<<","<<lnx2<<"] n="<<nbinmass_<<endl;
 | 
|---|
| 186 |  for(int i=ngalmin_;i<=ngalmax_;i++) {
 | 
|---|
| 187 |    Histo h(*hmdndm_); h.Zero();
 | 
|---|
| 188 |    hmass_.push_back(h);
 | 
|---|
| 189 |  }
 | 
|---|
| 190 |  if(lp>1) cout<<"...number of histos is "<<hmass_.size()<<endl;
 | 
|---|
| 191 | 
 | 
|---|
| 192 |  //------- Remplissage random
 | 
|---|
| 193 |  sch_.SetOutValue(1);  // on veut m*dN/dm
 | 
|---|
| 194 |  int lpmod = nalea/20; if(lpmod<=0) lpmod=1;
 | 
|---|
| 195 |  double s1=0., sc1=0.; unsigned long ns1=0;
 | 
|---|
| 196 |  double sax=0., scax=0.; unsigned long nsax=0;
 | 
|---|
| 197 |  for(unsigned long ia=0;ia<nalea;ia++) {
 | 
|---|
| 198 |    if(lp>1 && ia%lpmod==0) cout<<"...tirage "<<ia<<endl;
 | 
|---|
| 199 |    double sum = 0.;
 | 
|---|
| 200 |    for(int i=1;i<=ngalmax_;i++) {
 | 
|---|
| 201 |      //double l10m = tirhmdndm_->Random();
 | 
|---|
| 202 |      double l10m = tirhmdndm_->RandomInterp();
 | 
|---|
| 203 |      double m = pow(10.,l10m);
 | 
|---|
| 204 |      sum += m;
 | 
|---|
| 205 |      s1 += m; sc1 += m*m; ns1++;
 | 
|---|
| 206 |      int ipo = i-ngalmin_;
 | 
|---|
| 207 |      if(ipo<0) continue;
 | 
|---|
| 208 |      // ATTENTION: l'histo de tirage stoque le log10(moyenne=somme_masses/ngal).
 | 
|---|
| 209 |      //            Ca permet d'avoir le meme binning quelque soit ngal
 | 
|---|
| 210 |      double v = log10(sum/(double)i);
 | 
|---|
| 211 |      hmass_[ipo].Add(v);
 | 
|---|
| 212 |      if(i==ngalmax) {sax += sum/(double)i; scax += sum/(double)i*sum/(double)i; nsax++;}
 | 
|---|
| 213 |    }
 | 
|---|
| 214 |  }
 | 
|---|
| 215 |  sch_.SetOutValue(sch_outvalue_);  // on remet a la valeur initiale
 | 
|---|
| 216 | 
 | 
|---|
| 217 |  if(ns1>1) {
 | 
|---|
| 218 |    s1 /= ns1; sc1 = sc1/ns1 - s1*s1;
 | 
|---|
| 219 |    cout<<"...Mean mass for ngal=1: "<<s1<<" ("<<log10(fabs(s1))<<")"
 | 
|---|
| 220 |        <<" s="<<sqrt(fabs(sc1))<<" (ntrials "<<ns1<<")"<<endl;
 | 
|---|
| 221 |  }
 | 
|---|
| 222 |  if(nsax>1) {
 | 
|---|
| 223 |    sax /= nsax; scax = scax/nsax - sax*sax;
 | 
|---|
| 224 |    cout<<"...Mean mass for ngal="<<ngalmax_<<": "<<sax<<" ("<<log10(fabs(sax))<<")"
 | 
|---|
| 225 |        <<" s="<<sqrt(fabs(scax))<<" (ntrials "<<nsax<<")"<<endl;
 | 
|---|
| 226 |  }
 | 
|---|
| 227 | 
 | 
|---|
| 228 |  //------- Generation des classes de tirage aleatoire et des histos de verif
 | 
|---|
| 229 |  if(lp>0) cout<<"> Creating "<<nvalngal_<<" FunRan"<<endl;
 | 
|---|
| 230 |  for(unsigned int i=0;i<hmass_.size();i++) {
 | 
|---|
| 231 |    FunRan t(hmass_[i],true);
 | 
|---|
| 232 |    tmass_.push_back(t);
 | 
|---|
| 233 |  }
 | 
|---|
| 234 |  if(lp>1) cout<<"...number of funran is "<<tmass_.size()<<endl;
 | 
|---|
| 235 | 
 | 
|---|
| 236 |  return nvalngal_;
 | 
|---|
| 237 | }
 | 
|---|
| 238 | 
 | 
|---|
| 239 | int SchechterMassDist::GetNgalLim(int& ngalmax,int& ngalmin)
 | 
|---|
| 240 | {
 | 
|---|
| 241 |  ngalmax = ngalmax_;
 | 
|---|
| 242 |  ngalmin = ngalmin_;
 | 
|---|
| 243 |  return nvalngal_;
 | 
|---|
| 244 | }
 | 
|---|
| 245 | 
 | 
|---|
| 246 | Histo SchechterMassDist::GetHmDnDm(void) const
 | 
|---|
| 247 | {
 | 
|---|
| 248 |   return *hmdndm_;
 | 
|---|
| 249 | }
 | 
|---|
| 250 | 
 | 
|---|
| 251 | FunRan SchechterMassDist::GetTmDnDm(void) const
 | 
|---|
| 252 | {
 | 
|---|
| 253 |   return *tirhmdndm_;
 | 
|---|
| 254 | }
 | 
|---|
| 255 | 
 | 
|---|
| 256 | Histo SchechterMassDist::GetHisto(int i) const
 | 
|---|
| 257 | {
 | 
|---|
| 258 |   if(i<0 || i>=nvalngal_) {
 | 
|---|
| 259 |     cout<<"SchechterMassDist::GetHisto: error in input values"<<endl;
 | 
|---|
| 260 |     throw ParmError("SchechterMassDist::GetHisto: error in input values");
 | 
|---|
| 261 |   }
 | 
|---|
| 262 |   return hmass_[i];
 | 
|---|
| 263 | }
 | 
|---|
| 264 | 
 | 
|---|
| 265 | FunRan SchechterMassDist::GetFunRan(int i) const
 | 
|---|
| 266 | {
 | 
|---|
| 267 |   if(i<0 || i>=nvalngal_) {
 | 
|---|
| 268 |     cout<<"SchechterMassDist::GetFunRan: error in input values"<<endl;
 | 
|---|
| 269 |     throw ParmError("SchechterMassDist::GetFunRan: error in input values");
 | 
|---|
| 270 |   }
 | 
|---|
| 271 |   return tmass_[i];
 | 
|---|
| 272 | }
 | 
|---|
| 273 | 
 | 
|---|
| 274 | double SchechterMassDist::TirMass(int ngal)
 | 
|---|
| 275 | {
 | 
|---|
| 276 |  if(ngal<1) return 0.;
 | 
|---|
| 277 | 
 | 
|---|
| 278 |  int ipo = IndexFrNGal(ngal);
 | 
|---|
| 279 |  double masse_des_ngal = 0.;
 | 
|---|
| 280 |  if(ipo<0) {  // Pas d'histos de tirage pour ce nombre de galaxies
 | 
|---|
| 281 |    for(long i=0;i<ngal;i++) {  // On tire donc ngal fois sur la Schechter
 | 
|---|
| 282 |      // double lm = tirhmdndm_->Random();
 | 
|---|
| 283 |      double lm = tirhmdndm_->RandomInterp();
 | 
|---|
| 284 |      masse_des_ngal += pow(10.,lm);  // ATTENTION abscisse en log10(masse)
 | 
|---|
| 285 |    }
 | 
|---|
| 286 |    ntrial_dir++;
 | 
|---|
| 287 |  } else {
 | 
|---|
| 288 |    // ATTENTION l'histo de tirage stoque le log10(moyenne=somme_masses/ngal)
 | 
|---|
| 289 |    //double lmngal = tmass_[ipo].Random();
 | 
|---|
| 290 |    double lmngal = tmass_[ipo].RandomInterp();
 | 
|---|
| 291 |    masse_des_ngal = pow(10.,lmngal) * ngal;
 | 
|---|
| 292 |    ntrial_tab++;
 | 
|---|
| 293 |  }
 | 
|---|
| 294 | 
 | 
|---|
| 295 |  return masse_des_ngal;
 | 
|---|
| 296 | }
 | 
|---|
| 297 | 
 | 
|---|
| 298 | void SchechterMassDist::Print(void)
 | 
|---|
| 299 | {
 | 
|---|
| 300 |  cout<<"SchechterMassDist::Print: mass=["<<massmin_<<","<<massmax_<<"] n="<<nbinmass_<<endl
 | 
|---|
| 301 |      <<"                 ngal=["<<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_<<endl;
 | 
|---|
| 302 |  sch_.Print();
 | 
|---|
| 303 | }
 | 
|---|
| 304 | 
 | 
|---|
| 305 | void SchechterMassDist::PrintStatus(void)
 | 
|---|
| 306 | {
 | 
|---|
| 307 |  cout<<"SchechterMassDist::PrintStatus: number of trials: direct="<<ntrial_dir
 | 
|---|
| 308 |      <<" tabulated="<<ntrial_tab<<endl;
 | 
|---|
| 309 | }
 | 
|---|
| 310 | 
 | 
|---|
| 311 | void SchechterMassDist::WritePPF(string ppfname)
 | 
|---|
| 312 | {
 | 
|---|
| 313 |  char str[64];
 | 
|---|
| 314 |  cout<<"SchechterMassDist::WritePPF into "<<ppfname<<endl;
 | 
|---|
| 315 |  POutPersist pos(ppfname.c_str());
 | 
|---|
| 316 | 
 | 
|---|
| 317 |  double nstar,mstar,alpha;
 | 
|---|
| 318 |  sch_.GetParam(nstar,mstar,alpha);
 | 
|---|
| 319 |  TVector<r_8> tdum(20); tdum = 0.;
 | 
|---|
| 320 |  tdum(0) = nstar;
 | 
|---|
| 321 |  tdum(1) = mstar;
 | 
|---|
| 322 |  tdum(2) = alpha;
 | 
|---|
| 323 |  tdum(3) = sch_outvalue_;
 | 
|---|
| 324 |  tdum(4) = massmin_;
 | 
|---|
| 325 |  tdum(5) = massmax_;
 | 
|---|
| 326 |  tdum(6) = nbinmass_;
 | 
|---|
| 327 |  tdum(7) = ngalmin_;
 | 
|---|
| 328 |  tdum(8) = ngalmax_;
 | 
|---|
| 329 |  tdum(9) = nvalngal_;
 | 
|---|
| 330 |  tdum(10) = hmass_.size();
 | 
|---|
| 331 |  tdum(11) = tmass_.size();
 | 
|---|
| 332 |  pos << PPFNameTag("SMDparam") << tdum;
 | 
|---|
| 333 | 
 | 
|---|
| 334 |  pos << PPFNameTag("SMDhmdndm") << *hmdndm_;
 | 
|---|
| 335 |  pos << PPFNameTag("SMDtirhmdndm") << *tirhmdndm_;
 | 
|---|
| 336 | 
 | 
|---|
| 337 |  if(hmass_.size()>0) {
 | 
|---|
| 338 |    for(unsigned int i=0;i<hmass_.size();i++) {
 | 
|---|
| 339 |      sprintf(str,"SMDh%d",NGalFrIndex(i));
 | 
|---|
| 340 |      pos << PPFNameTag(str) << hmass_[i];
 | 
|---|
| 341 |    }
 | 
|---|
| 342 |  }
 | 
|---|
| 343 | 
 | 
|---|
| 344 |  if(tmass_.size()>0) {
 | 
|---|
| 345 |    for(unsigned int i=0;i<tmass_.size();i++) {
 | 
|---|
| 346 |      sprintf(str,"SMDt%d",NGalFrIndex(i));
 | 
|---|
| 347 |      Histo hdum(tmass_[i]);
 | 
|---|
| 348 |      pos << PPFNameTag(str) << hdum;
 | 
|---|
| 349 |    }
 | 
|---|
| 350 |  }
 | 
|---|
| 351 | 
 | 
|---|
| 352 | }
 | 
|---|
| 353 | 
 | 
|---|
| 354 | void SchechterMassDist::ReadPPF(string ppfname)
 | 
|---|
| 355 | {
 | 
|---|
| 356 |  Delete(); // On des-alloue si deja remplit!
 | 
|---|
| 357 | 
 | 
|---|
| 358 |  char str[64];
 | 
|---|
| 359 |  cout<<"SchechterMassDist::ReadPPF from "<<ppfname<<endl;
 | 
|---|
| 360 |  PInPersist pis(ppfname.c_str());
 | 
|---|
| 361 | 
 | 
|---|
| 362 |  TVector<r_8> tdum;
 | 
|---|
| 363 |  pis >> PPFNameTag("SMDparam") >> tdum;
 | 
|---|
| 364 |  sch_.SetParam(tdum(0),tdum(1),tdum(2));
 | 
|---|
| 365 |  sch_.SetOutValue((unsigned short)(tdum(3)+0.1));
 | 
|---|
| 366 |  massmin_ = tdum(4);
 | 
|---|
| 367 |  massmax_ = tdum(5);
 | 
|---|
| 368 |  nbinmass_ = int(tdum(6)+0.1);
 | 
|---|
| 369 |  ngalmin_ = int(tdum(7)+0.1);
 | 
|---|
| 370 |  ngalmax_ = int(tdum(8)+0.1);
 | 
|---|
| 371 |  nvalngal_ = int(tdum(9)+0.1);
 | 
|---|
| 372 |  unsigned int nhmass = (unsigned int)(tdum(10)+0.1);
 | 
|---|
| 373 |  unsigned int ntmass = (unsigned int)(tdum(11)+0.1);
 | 
|---|
| 374 | 
 | 
|---|
| 375 |  {
 | 
|---|
| 376 |  Histo hdum;
 | 
|---|
| 377 |  pis >> PPFNameTag("SMDhmdndm") >> hdum;
 | 
|---|
| 378 |  hmdndm_ = new Histo(hdum);
 | 
|---|
| 379 |  pis >> PPFNameTag("SMDtirhmdndm") >> hdum;
 | 
|---|
| 380 |  tirhmdndm_ = new FunRan(hdum,false);
 | 
|---|
| 381 |  }
 | 
|---|
| 382 | 
 | 
|---|
| 383 |  if(nhmass>0) {
 | 
|---|
| 384 |    for(unsigned int i=0;i<nhmass;i++) {
 | 
|---|
| 385 |      sprintf(str,"SMDh%d",NGalFrIndex(i));
 | 
|---|
| 386 |      Histo hdum;
 | 
|---|
| 387 |      pis >> PPFNameTag(str) >> hdum;
 | 
|---|
| 388 |      hmass_.push_back(hdum);
 | 
|---|
| 389 |    }
 | 
|---|
| 390 |  }
 | 
|---|
| 391 | 
 | 
|---|
| 392 |  if(ntmass>0) {
 | 
|---|
| 393 |    for(unsigned int i=0;i<ntmass;i++) {
 | 
|---|
| 394 |      sprintf(str,"SMDt%d",NGalFrIndex(i));
 | 
|---|
| 395 |      Histo hdum;
 | 
|---|
| 396 |      pis >> PPFNameTag(str) >> hdum;
 | 
|---|
| 397 |      FunRan fdum(hdum,false);
 | 
|---|
| 398 |      tmass_.push_back(fdum);
 | 
|---|
| 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 |   // nstar et mstar ne sont jamais nuls
 | 
|---|
| 418 |   if(fabs(nstar1-nstar2)>fabs(nstar1+nstar2)/2.*eps) return false;
 | 
|---|
| 419 |   if(fabs(mstar1-mstar2)>fabs(mstar1+mstar2)/2.*eps) return false;
 | 
|---|
| 420 | 
 | 
|---|
| 421 |   // alpha peut etre eventuellement nul
 | 
|---|
| 422 |   if(fabs(alpha1)<1.e-100 && fabs(alpha2)<1.e-100 && fabs(alpha1-alpha2)>eps) return false;
 | 
|---|
| 423 |   if(fabs(alpha1-alpha2)>fabs(alpha1+alpha2)/2.*eps) return false;
 | 
|---|
| 424 |   return true;
 | 
|---|
| 425 | }
 | 
|---|
| 426 | 
 | 
|---|
| 427 | 
 | 
|---|
| 428 | ///////////////////////////////////////////////////////////
 | 
|---|
| 429 | //******************* Le Flux a 21cm ********************//
 | 
|---|
| 430 | ///////////////////////////////////////////////////////////
 | 
|---|
| 431 | double Msol2LumiHI(double m)
 | 
|---|
| 432 | // Input:
 | 
|---|
| 433 | //    m : masse de HI en "Msol"
 | 
|---|
| 434 | // Return:
 | 
|---|
| 435 | //    la luminosite en W
 | 
|---|
| 436 | // L(m) =  2.393e+18* m(en masse solaire) en W
 | 
|---|
| 437 | {
 | 
|---|
| 438 |   return 2.393e+18 * m;
 | 
|---|
| 439 | }
 | 
|---|
| 440 | 
 | 
|---|
| 441 | double Msol2FluxHI(double m,double d)
 | 
|---|
| 442 | // Input:
 | 
|---|
| 443 | //    m : masse de HI en "Msol"
 | 
|---|
| 444 | //    d : distance en "Mpc"  (si cosmo d=DLum(z))
 | 
|---|
| 445 | // Return:
 | 
|---|
| 446 | //    le flux total emis a 21 cm en W/m^2
 | 
|---|
| 447 | // Ref:
 | 
|---|
| 448 | // -- Binney & Merrifield, Galactic Astronomy p474 (ed:1998)
 | 
|---|
| 449 | // S(W/m^2) = 1e-26 * Nu_21cm(Hz) * m(en masse solaire) /(2.35e5 * C(km/s) * Dlum^2)
 | 
|---|
| 450 | //          = 2.0e-28 * m / Dlum^2
 | 
|---|
| 451 | // -- J.Peterson & K.Bandura, astroph-0606104  (eq 7)
 | 
|---|
| 452 | //    F.Abdalla & Rawlings, astroph-0411342 (eq 7 mais pb de d'unites?)
 | 
|---|
| 453 | //          (A_21cm = 2.86888e-15 s^-1)
 | 
|---|
| 454 | // S(W/m^2) = 3/4 * h(J.s) * Nu_21cm(Hz) * A_21cm(s^-1) * Msol(kg)/m_proton(kg)
 | 
|---|
| 455 | //                         / (4 Pi) / (Dlum(Mpc) * 3.0857e22(m/Mpc))^2
 | 
|---|
| 456 | //          = 2.0e-28 * m / Dlum^2
 | 
|---|
| 457 | //-------------
 | 
|---|
| 458 | {
 | 
|---|
| 459 |   return  2.0e-28 * m / (d*d);
 | 
|---|
| 460 | }
 | 
|---|
| 461 | 
 | 
|---|
| 462 | double FluxHI2Msol(double f,double d)
 | 
|---|
| 463 | // Input:
 | 
|---|
| 464 | //    f : flux total emis a 21 cm en W/m^2
 | 
|---|
| 465 | //    d : distance en "Mpc"  (si cosmo d=DLum(z))
 | 
|---|
| 466 | // Return:
 | 
|---|
| 467 | //    m : masse de HI en "Msol"
 | 
|---|
| 468 | {
 | 
|---|
| 469 |   return f *d*d / 2.0e-28;
 | 
|---|
| 470 | }
 | 
|---|
| 471 | 
 | 
|---|
| 472 | 
 | 
|---|
| 473 | }  // Fin namespace SOPHYA
 | 
|---|