1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
27 #include <TGraphErrors.h>
32 #include <TDatabasePDG.h>
34 #include "AliCentralityGlauberFit.h"
37 ClassImp(AliCentralityGlauberFit)
39 //______________________________________________________________________________
40 AliCentralityGlauberFit::AliCentralityGlauberFit(const char *filename) :
79 fAncfilename("ancestor_hists.root"),
82 // Standard constructor.
84 if (filename) { // glauber file
85 f = TFile::Open(filename);
86 fGlauntuple = (TNtuple*) f->Get("nt_p_Pb");
87 fGlauntuple->SetBranchAddress("Npart",&fNpart);
88 fGlauntuple->SetBranchAddress("Ncoll",&fNcoll);
89 fGlauntuple->SetBranchAddress("B",&fB);
90 fGlauntuple->SetBranchAddress("tAA",&fTaa);
92 for(int i=0; i<4; i++) fParamnSlow[i] = 0.;
96 //--------------------------------------------------------------------------------------------------
97 void AliCentralityGlauberFit::SetRangeToFit(Double_t fmultmin, Double_t fmultmax)
105 //--------------------------------------------------------------------------------------------------
106 void AliCentralityGlauberFit::SetRangeToScale(Double_t fscalemin)
108 // Set range where to scale simulated histo to data
113 //--------------------------------------------------------------------------------------------------
114 void AliCentralityGlauberFit::SetGlauberParam(
134 // Set Glauber parameters.
140 fAlphahigh=alphahigh;
143 fSigmahigh=sigmahigh;
149 fgammahigh=gammahigh;
151 fsigmaplow=sigmaplow;
152 fsigmaphigh=sigmaphigh;
155 //--------------------------------------------------------------------------------------------------
156 void AliCentralityGlauberFit::SetNParam(Double_t a, Double_t b, Double_t c, Double_t d)
158 // Setting parameters that are adjusted
163 for(int i=0; i<4; i++) printf(" INITIAL PARAMETER VALUES : paramnSlow[%d] = %f\n", i, fParamnSlow[i]);
166 //--------------------------------------------------------------------------------------------------
167 void AliCentralityGlauberFit::MakeFits()
176 // open inrootfile, outrootfile
177 std::cout << "input file " << fInrootfilename << std::endl;
178 std::cout << "output file " << fOutrootfilename << std::endl << std::endl;
179 inrootfile = new TFile(fInrootfilename,"OPEN");
180 outrootfile = new TFile(fOutrootfilename,"RECREATE");
182 // loop over all distribution names
183 std::vector<TString>::const_iterator hni;
184 for(hni=fHistnames.begin(); hni!=fHistnames.end(); hni++) {
185 hDATA = (TH1F*) (inrootfile->Get(*hni));
186 std::cout << " -> Getting histogram " << *hni << std::endl << std::endl;
188 printf(" @@@@@@ No DATA histo in input -> EXITING!!!!!\n\n");
190 //TList *list = (TList*) (inrootfile->Get("CentralityStat"));
191 //hDATA = (TH1F*) (list->FindObject(*hni));
193 //hDATA->Rebin(fRebinFactor);
194 //TH1F *hGLAU = new TH1F("hGLAU","hGLAU",hDATA->GetNbinsX(),0,hDATA->GetNbinsX()*hDATA->GetBinWidth(1));
196 Double_t gamma_min=-1;
197 Double_t sigmap_min=-1;
199 Double_t sigma_min=-1;
200 Double_t alpha_min=-1;
201 Double_t k_min=-1, chi2=0.;
202 Double_t alpha=0., k=0., sigma=0., bog=0., gamma=0., sigmap=0.;
204 for(Int_t nsigmap=0; nsigmap<fNsigmap; nsigmap++) {
205 sigmap = fsigmaplow + ((Double_t) nsigmap ) * (fsigmaphigh - fsigmaplow ) / fNsigmap;
207 for(Int_t ngamma=0; ngamma<fNgamma; ngamma++) {
208 gamma = fgammalow + ((Double_t) ngamma ) * (fgammahigh - fgammalow ) / fNgamma;
210 for(Int_t nbog=0; nbog<fNbog; nbog++) {
211 bog = fBoglow + ((Double_t) nbog ) * (fBoghigh - fBoglow ) / fNbog;
213 for(Int_t nsigma=0; nsigma<fNsigma; nsigma++) {
214 sigma = fSigmalow + ((Double_t) nsigma ) * (fSigmahigh - fSigmalow ) / fNsigma;
216 for(Int_t nalpha=0; nalpha<fNalpha; nalpha++) {
217 alpha = fAlphalow + ((Double_t) nalpha ) * (fAlphahigh - fAlphalow ) / fNalpha;
219 for(Int_t nk=0; nk<fNk; nk++) {
220 k = fKlow + ((Double_t) nk ) * (fKhigh - fKlow ) / fNk;
223 for(int i=0; i<fNTrials; i++){
224 printf(" **** calling GlauberHisto with acc = %1.3f R = %1.4f k = %1.4f bog = %1.3f gamma = %1.3f sigmap = %1.3f\n",
225 alpha, sigma, k, bog, gamma, sigmap);
227 // Updating parameters for slow n
228 fParamnSlow[0] = fParamnSlow[0]; // + 0.5*i;
229 fParamnSlow[1] = fParamnSlow[1]; // + 10.*i;
230 fParamnSlow[2] = fParamnSlow[2] + 0.05*i;
231 fParamnSlow[3] = fParamnSlow[3];// + 0.01*i;
233 printf(" \t\t trial #%d n slow param.: %1.2f %1.2f %1.2f %1.2f\n",
234 i,fParamnSlow[0], fParamnSlow[1], fParamnSlow[2], fParamnSlow[3]);
237 //thistGlau = GlauberHisto(k,alpha,sigma,bog,gamma,sigmap,hDATA,kFALSE);
238 thistGlau = GlauberHisto(k,alpha,sigma,bog,gamma,sigmap,hDATA,kTRUE);
240 chi2 = CalculateChi2(hDATA, thistGlau);
241 printf(" -> Chi2 %f \n", chi2);
258 if(fNsigmap>1 || fNgamma>1 || fNbog>1 || fNsigma>1 || fNalpha>1 || fNk>1 || fNTrials>1){
260 printf(" **** calling GlauberHisto with acc = %1.3f R = %1.4f bog = %1.3f gamma = %1.3f sigmap = %1.3f\n",
261 alpha, sigma, bog, gamma, sigmap);
262 thistGlau = GlauberHisto(k_min,alpha_min,sigma_min,bog_min,gamma_min, sigmap_min, hDATA,kTRUE);
266 hGLAU = (TH1F *) thistGlau->Clone("hGLAU");
268 hGLAU->SetName( ((TString)hDATA->GetName()).Append(Form("_GLAU")));
269 if(fIsZN) hGLAU->SetTitle(((TString)hDATA->GetName()).Append(Form("_GLAU_%.3f_%.3f_%.3f_%.2f-%.2f-%.3f-%.2f",
270 bog,sigmap,gamma,fParamnSlow[0], fParamnSlow[1], fParamnSlow[2], fParamnSlow[3])));
271 else hGLAU->SetTitle(((TString)hDATA->GetName()).Append(Form("_GLAU_%.3f_%.3f_%.3f",
275 if(fIsZN) firstBin = 8;//ZN
277 if(fIsZN) lastBin = 800;//ZN
278 else lastBin = hDATA->GetNbinsX(); // ZP
280 Double_t mcintegral = hGLAU->Integral(firstBin, lastBin,"width");
281 Double_t dataintegral = hDATA->Integral(firstBin, lastBin,"width");
283 if(mcintegral>0.) (scale = dataintegral/mcintegral);
284 printf("\n scale %f \n", scale);
286 std::cout << "hGLAU -> Integral in bin range:" << firstBin << "-" << lastBin << " = " <<
287 mcintegral << std::endl;
288 std::cout << "hDATA -> Integral in bin range:" << firstBin << "-" << lastBin << " = " <<
289 dataintegral << std::endl;
293 std::cout << "hGLAU -> Integral (whole range): " << hGLAU->Integral(1, hGLAU->GetNbinsX(),"width") << std::endl;
294 std::cout << "hDATA -> Integral (whole range): " << hDATA->Integral(1, hDATA->GetNbinsX(),"width") << std::endl;
296 TCanvas *c2 = new TCanvas("c2","checkGLAU",100,0,700,700);
298 hGLAU->SetLineColor(kPink);
302 SaveHisto(hDATA, hGLAU, outrootfile);
304 printf("\n \t k = %1.4f alpha = %1.3f sigma = %1.2f bog = %1.4f gamma = %1.4f sigmap = %.3f \n", k,alpha, sigma, bog, gamma, sigmap);
305 if(fIsZN) printf(" \t a = %1.2f b = %1.3f c = %1.2f d = %1.2f\n\n", fParamnSlow[0], fParamnSlow[1], fParamnSlow[2], fParamnSlow[3]);
306 std::cout << "chi2 min is " << fChi2Min << std::endl << std::endl;
307 std::cout << "fitted " << hGLAU->Integral(hGLAU->FindBin(fMultmin),
308 hGLAU->FindBin(fMultmax))/hGLAU->Integral()
309 << " of the total cross section" << std::endl << std::endl;
311 fGlauberHist = hGLAU;
314 // close inrootfile, outrootfile
316 outrootfile->Close();
320 //--------------------------------------------------------------------------------------------------
321 TH1F *AliCentralityGlauberFit::GlauberHisto(Double_t k, Double_t alpha, Double_t sigma, Double_t bog,
322 Double_t gamma, Double_t sigmap, TH1F *hDATA, Bool_t save)
324 // Get Glauber histogram.
325 static TH1F *h1 = (TH1F*) hDATA->Clone("h1");
327 h1->SetName(Form("fit_%.3f_%.3f",k,alpha));
329 TFile *outFile = NULL;
330 TNtuple *ntuple = NULL;
332 Double_t ntot=0, nblack=0, ngray=0, Etot=0, lcp=0, nslowp=0, nslown=0;
335 outFile = new TFile(fOutntuplename,"RECREATE");
336 ntuple = new TNtuple("gnt", "Glauber ntuple", "fNpart:fNcoll:fB:fTaa:ntot:nblack:ngray:Etot:lcp:nslowp:nslown");
339 Int_t nents=0, evtot=0, evn=0, evzeron=0, evzerop=0, evenzero=0;
340 if(fGlauntuple) nents = fGlauntuple->GetEntries();
342 for (Int_t i=0;i<fNevents;++i) {
343 if(fGlauntuple) fGlauntuple->GetEntry(i % nents);
345 printf(" NOT GETTING ENTRY FROM TNTUPLE for ev. %d -> setting Ncoll=1 \n\n",i);
349 //printf(" Getting entry %d from ntuple Ncoll = %f\n",i%nents, fNcoll);
351 // Slow Nucleon Model from Chiara
352 Double_t n=0., nbn=0., ngn=0., nbp=0., ngp=0.;
354 //MakeSlowNucleons(fNcoll,nbn,ngn,nbp,ngp); // pure Sikler
355 //MakeSlowNucleons2(fNcoll,bog,gamma, nbn,ngn,nbp,ngp,lcp); // smear in Ncoll
356 MakeSlowNucleons2s(fNcoll,bog,gamma,sigmap, nbn,ngn,nbp,ngp,lcp); // smear in Nslow
367 n = alpha*(ngp+nbp); // ZPA
374 if((alpha*(ngn+nbn)<0.5)) evzeron++;
375 if((alpha*(ngp+nbp)<0.5)) evzerop++;
377 //------ experimental resolution -> Gaussian smearing ------------------------------------
378 Double_t resexp = 0.;
379 //if (n>0) resexp = sigma*gRandom->Gaus(0.0,1.0)/TMath::Sqrt(n);
381 //ntot = n*(1+resexp);
384 resexp = sigma*TMath::Sqrt(n);
385 ntot = (gRandom->Gaus(n, resexp));
389 // non-lineary effect -------------------------------
390 //ntot = ntot + k*ntot*ntot;
392 Double_t nFact = 4.*82./208.;
395 // USE ONLY IF ZDC TDC IS REQUESTED TO CONDITION THE SPECTRUM!!!!!!!!!
398 resexpe = 1./TMath::Sqrt(n)*sigma*gRandom->Gaus(0.0, 1.0);
399 //resexpe = 1./TMath::Sqrt(n)*sigma;
401 Etot = Etot*(1+resexpe);
403 // non-lineary effect -------------------------------
404 //Etot = Etot + k*Etot*Etot;
406 if(Etot<0.5) evenzero++;
409 if(save) ntuple->Fill(fNpart, fNcoll, fB, fTaa, ntot, nblack, ngray, Etot, lcp, nslowp, nslown);
413 //printf("\n ******** Fraction of events with Ncoll=1 in the ntuple %f\n",(float) (1.*evn/evtot));
415 printf(" ******** Fraction of events with no neutrons %f\n",(float) (1.*evzeron/evtot));
416 printf(" ******** Fraction of events with no neutron energy %f\n",(float) (1.*evenzero/evtot));
417 printf(" DATA: fraction of events with no ZN signal = %f\n\n", 1-alpha);
419 else printf("\n ******** Fraction of events with no protons %f \n",(float) (1.*evzerop/evtot));
428 //--------------------------------------------------------------------------------------------------
429 Double_t AliCentralityGlauberFit::CalculateChi2(TH1F *hDATA, TH1F *thistGlau)
431 // Note that for different values of neff the mc distribution is identical, just re-scaled below
432 // normalize the two histogram, scale MC up but leave data alone - that preserves error bars !!!!
435 Int_t highchibin = 0;
436 if(fIsZN) highchibin = 800;
437 else highchibin = 25;
439 Double_t mcintegral = thistGlau->Integral(1, thistGlau->GetNbinsX());
440 Double_t scale = (hDATA->Integral(1, hDATA->GetNbinsX())/mcintegral);
441 thistGlau->Scale(scale);
443 // calculate the chi2 between MC and real data over some range ????
446 for (Int_t i=lowchibin; i<=highchibin; i++) {
447 if (hDATA->GetBinContent(i) < 1.0) continue;
448 Double_t diff = TMath::Power((thistGlau->GetBinContent(i) - hDATA->GetBinContent(i)),2);
449 diff = diff / (TMath::Power(hDATA->GetBinError(i),2) + TMath::Power(thistGlau->GetBinError(i),2));
452 chi2 = chi2 / (highchibin - lowchibin + 1);
455 // "-2 log likelihood ratio(mu;n) = 2[(mu - n) + n ln(n/mu)]"
457 std::cout << "LL" << std::endl;
460 for (Int_t i=lowchibin; i<=highchibin; i++) {
461 Double_t data = hDATA ->GetBinContent(i);
462 Double_t mc = thistGlau->GetBinContent(i);
463 Int_t idata = TMath::Nint(data);
464 if (mc < 1.e-9) mc = 1.e-9;
465 Double_t fsub = - mc + idata * TMath::Log(mc);
468 for(Int_t istep = 0; istep < idata; istep++){
470 fobs += TMath::Log(istep);
480 //--------------------------------------------------------------------------------------------------
481 void AliCentralityGlauberFit::SaveHisto(TH1F *hist1, TH1F *hist2, TFile *outrootfile)
490 //--------------------------------------------------------------------------------------------------
491 void AliCentralityGlauberFit::MakeSlowNucleons(Int_t ncoll, Double_t &nbn, Double_t &ngn,Double_t &nbp, Double_t &ngp)
493 // from AliGenSlowNucleonModelExp (Chiara Oppedisano)
494 // Return the number of black and gray nucleons
496 // Number of collisions
500 Float_t nu = (Float_t) ncoll;
502 // Mean number of gray nucleons
503 Float_t nGray = 2. * nu;
504 Float_t nGrayNeutrons = nGray * fN / (fN + fP);
505 Float_t nGrayProtons = nGray - nGrayNeutrons;
507 // Mean number of black nucleons
509 if(nGray>=15.) nBlack = 28.;
510 Float_t nBlackNeutrons = nBlack * 0.84;
511 Float_t nBlackProtons = nBlack - nBlackNeutrons;
513 // Actual number (including fluctuations) from binomial distribution
515 ngn = (double) gRandom->Binomial((Int_t) fN, nGrayNeutrons/fN);
518 ngp = (double) gRandom->Binomial((Int_t) fP, nGrayProtons/fP);
521 nbn = (double) gRandom->Binomial((Int_t) fN, nBlackNeutrons/fN);
524 nbp = (double) gRandom->Binomial((Int_t) fP, nBlackProtons/fP);
526 // printf(" Ncoll %d ngp %f nbp %f ngn %f nbn %f \n",ncoll,ngp, nbp, ngn, nbn);
531 //--------------------------------------------------------------------------------------------------
532 void AliCentralityGlauberFit::MakeSlowNucleons2(Int_t ncoll, Double_t bog, Double_t gamma,
533 Double_t &nbn, Double_t &ngn, Double_t &nbp, Double_t &ngp, Double_t &lcp)
535 // from AliGenSlowNucleonModelExp (Chiara Oppedisano)
537 // Return the number of black and gray nucleons
540 // PROTONS ----------------------------------------------------------------
545 Float_t nu = (Float_t) ncoll;
547 nu = gRandom->Gaus(nu,0.5);
550 // PROTONS ----------------------------------------------------------------
552 Float_t poverpd = 0.843;
553 Float_t zAu2zPb = 82./79.;
554 Float_t nGrayp = (-0.27 + 0.63 * nu - 0.0008 *nu *nu)*poverpd*zAu2zPb;
555 if(nGrayp<0.) nGrayp=0;
559 ngp = (double) gRandom->Binomial(fP, p);
562 //Float_t blackovergray = 3./7.;// from spallation
563 //Float_t blackovergray = 0.65; // from COSY
564 Float_t blackovergray = bog;
565 Float_t nBlackp = blackovergray*nGrayp;
566 if(nBlackp<0.) nBlackp=0;
568 p = nBlackp/(fP-ngp);
569 nbp = (double) gRandom->Binomial((Int_t) (fP-ngp), p);
570 // SATURATION in no. of black protons
571 //if(ngp>=9.) nbp = 15;
573 // NEUTRONS ----------------------------------------------------------------
576 nGrayp = -0.836 + 0.9112 *nu - 0.05381 *nu *nu;
577 nBlackp = blackovergray*nGrayp;
581 Float_t nGrayNeutrons = 0.;
582 Float_t nBlackNeutrons = 0.;
583 lcp = (nGrayp+nBlackp)/gamma;
587 nSlow = fParamnSlow[0]-fParamnSlow[1]/(fParamnSlow[2]+lcp)+fParamnSlow[3]*lcp;
590 // float xconj = fParamnSlow[1]/fParamnSlow[0]-fParamnSlow[2];
592 float yconj = fParamnSlow[0]-fParamnSlow[1]/(fParamnSlow[2]+xconj)+fParamnSlow[3]*xconj;
593 if(lcp<xconj) nSlow = 0.+(yconj-0.)*(lcp-0.)/(xconj-0.);
595 // Factor to scale COSY to obtain ALICE n mltiplicities
596 // nSlow = 1.68*nSlow; // now integrated in fParamnSlow[0], fParamnSlow[1]
598 nBlackNeutrons = nSlow * 0.9;
599 //nBlackNeutrons = nSlow * 0.5;
600 nGrayNeutrons = nSlow - nBlackNeutrons;
603 // slightly adjusted Sikler corrected for neutron yield...
604 nBlackNeutrons = 126./208. * 4. * nu;
605 //nGrayNeutrons = 126./208. * 2. * nu; // a la Sikler (<Ngn>~0.50*<Nbn>)
606 //nGrayNeutrons = 0.47 * 2. * nu; // a la DPMJET (<Ngn>~0.39*<Nbn>)
607 nGrayNeutrons = nBlackNeutrons/9.; // a la spallation (<Ngn>~0.11*<Nbn>)
610 if(nGrayNeutrons<0.) nGrayNeutrons=0.;
611 if(nBlackNeutrons<0.) nBlackNeutrons=0.;
613 p = nGrayNeutrons/fN;
614 ngn = gRandom->Binomial(fN, p);
616 if(nGrayNeutrons>=10) ngn = gRandom->Gaus(nGrayNeutrons+0.5, TMath::Sqrt(fN*p*(1-p)));
617 //else ngn = gRandom->PoissonD(nGrayNeutrons);
618 //else ngn = gRandom->Binomial((Int_t) fN, p);
622 p = nBlackNeutrons/(fN-ngn);
623 nbn = gRandom->Binomial((Int_t) (fN-ngn), p);
625 if(nBlackNeutrons>=10) nbn = gRandom->Gaus(nBlackNeutrons+0.5, TMath::Sqrt(fN*p*(1-p)));
626 else nbn = gRandom->PoissonD(nBlackNeutrons);
627 //else nbn = gRandom->Binomial((Int_t) fN, p);
632 //--------------------------------------------------------------------------------------------------
633 void AliCentralityGlauberFit::MakeSlowNucleons2s(Float_t ncoll, Double_t bog, Double_t gamma, Double_t sigmap,
634 Double_t &nbn, Double_t &ngn, Double_t &nbp, Double_t &ngp, Double_t &lcp)
636 // from AliGenSlowNucleonModelExp (Chiara Oppedisano)
638 // Return the number of black and gray nucleons
645 //Float_t nu = ncoll*(gRandom->Rndm()+0.5);
647 // PROTONS ----------------------------------------------------------------
649 Float_t poverpd = 0.843;
650 Float_t zAu2zPb = 82./79.;
651 Float_t grayp = (-0.27 + 0.63 * nu - 0.0008 *nu *nu)*poverpd*zAu2zPb;
652 //if(nu<3.) grayp = -0.836 + 0.9112 *nu - 0.05381 *nu *nu;
655 //Float_t nGrayp = grayp;
656 Float_t nGrayp = gRandom->Gaus(grayp, sigmap);
658 // Float_t nGrayp = gRandom->Gaus(grayp, (0.8*sigmap-sigmap)*grayp/90+sigmap);
659 if(nGrayp<0.) nGrayp=0;
663 ngp = (double) gRandom->Binomial((int) fP, p);
666 //Float_t blackovergray = 3./7.;// =0.43 from spallation
667 //Float_t blackovergray = 0.65; // from COSY
668 Float_t blackovergray = bog;
670 Float_t nBlackp = blackovergray*nGrayp;
671 //if(nBlackp<0.) nBlackp=0;
673 p = nBlackp/(fP-ngp);
674 nbp = (double) gRandom->Binomial((int) (fP-ngp), p);
675 // SATURATION in no. of black protons
676 //if(ngp>=9.) nbp = 15;
678 // NEUTRONS ----------------------------------------------------------------
679 // Relevant ONLY for n
680 // NB-> DOESN'T WORK FOR SMEARING IN Nslow!!!!!!!!!!
682 grayp = -0.836 + 0.9112 *nu - 0.05381 *nu *nu;
684 //nGrayp = gRandom->Gaus(grayp, sigmap);
686 nBlackp = blackovergray*nGrayp;
690 lcp = (nGrayp+nBlackp)/gamma;
692 Float_t nGrayNeutrons = 0.;
693 Float_t nBlackNeutrons = 0.;
696 nSlow = fParamnSlow[0]-fParamnSlow[1]/(fParamnSlow[2]+lcp)+fParamnSlow[3]*lcp;
699 // float xconj = fParamnSlow[1]/fParamnSlow[0]-fParamnSlow[2];
701 float yconj = fParamnSlow[0]-fParamnSlow[1]/(fParamnSlow[2]+xconj)+fParamnSlow[3]*xconj;
702 if(lcp<xconj) nSlow = 0.+(yconj-0.)*(lcp-0.)/(xconj-0.);*/
704 // Factor to scale COSY to obtain ALICE n mltiplicities
705 // nSlow = 1.68*nSlow; // now integrated in fParamnSlow[0], fParamnSlow[1]
707 nBlackNeutrons = nSlow * 0.9;
708 //nBlackNeutrons = nSlow * 0.5;
709 nGrayNeutrons = nSlow - nBlackNeutrons;
712 // taking into account the prob4bility p to have 0 neutrons when we have 0 protons
713 // p = 1.-(0.82*0.96) ~ 0.22 (assuming that 100% of ev. without n are also without p)
714 //Float_t r = gRandom->Rndm();
716 // Sikler corrected for neutron yield...
717 nBlackNeutrons = 126./208. * 4. * nu;
718 //nGrayNeutrons = 126./208. * 2. * nu; // a la Sikler (<Ngn>~0.50*<Nbn>)
719 //nGrayNeutrons = 0.47 * 2. * nu; // a la DPMJET (<Ngn>~0.39*<Nbn>)
720 //nGrayNeutrons = nBlackNeutrons/9.; // a la spallation (<Ngn>~0.11*<Nbn>)
723 nBlackNeutrons = gRandom->Gaus(nBlackNeutrons, sigmap);
724 //nGrayNeutrons = nBlackNeutrons/2.; // a la Sikler (<Ngn>~0.50*<Nbn>)
725 nGrayNeutrons = nBlackNeutrons/9.; // a la spallation (<Ngn>~0.11*<Nbn>)
726 //printf(" Sikler -> Ncoll %f <Ngrayn> %f <Nblackn> %f \n",nu,nGrayNeutrons, nBlackNeutrons);
730 if(nGrayNeutrons<0.) nGrayNeutrons=0.;
731 if(nBlackNeutrons<0.) nBlackNeutrons=0.;
734 p = nBlackNeutrons/fN;
735 nbn = gRandom->Binomial((Int_t) fN, p);
737 //nbn = (double) r.Binomial((int) fN, p);
739 // if(nBlackNeutrons>=10) nbn = r.Gaus(nBlackNeutrons+0.5, TMath::Sqrt(fN*p*(1-p)));
743 p = nGrayNeutrons/(fN-nbn);
744 ngn = gRandom->Binomial((Int_t) (fN-nbn), p);
745 //ngn = (double) (r.Binomial((Int_t) (fN-nbn), p));
747 /*if(nGrayNeutrons>=10) ngn = gRandom->Gaus(nGrayNeutrons+0.5, TMath::Sqrt(fN*p*(1-p)));
748 else ngn = gRandom->Binomial((Int_t) fN, p);*/
751 //printf(" Ncoll %1.2f Ngp %1.2f Nbp %1.2f Nbn %1.2f Ngn %1.2f\n",nu, ngp,nbp,nbn,ngn);
756 Double_t AliCentralityGlauberFit::ConvertToEnergy(Double_t T)
758 TDatabasePDG * pdg = TDatabasePDG::Instance();
759 const Double_t kMassNeutron = pdg->GetParticle(kNeutron)->Mass();
762 Double_t m, p, pmax, f;
764 pmax = TMath::Sqrt(2*T*(T+TMath::Sqrt(T*T+m*m)));
768 p = gRandom->Rndm() * fPmax;
769 f = Maxwell(m, p, T) / Maxwell(m , pmax, T);
771 while(f < gRandom->Rndm());
773 return 13.5*TMath::Sqrt(p*p+m*m);
776 Double_t AliCentralityGlauberFit::Maxwell(Double_t m, Double_t p, Double_t T)
778 /* Relativistic Maxwell-distribution */
780 ekin = TMath::Sqrt(p*p+m*m)-m;
781 return (p*p * exp(-ekin/T));