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 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////////
18 // Glauber MC implementation
20 // origin: PHOBOS experiment
21 // alification: Mikolaj Krzewicki, Nikhef, mikolaj.krzewicki@cern.ch
23 ////////////////////////////////////////////////////////////////////////////////
25 #include <Riostream.h>
30 #include <TObjArray.h>
34 #include "AliGlauberNucleon.h"
35 #include "AliGlauberNucleus.h"
36 #include "AliGlauberMC.h"
38 ClassImp(AliGlauberMC)
40 //______________________________________________________________________________
41 AliGlauberMC::AliGlauberMC(Option_t* NA, Option_t* NB, Double_t xsect) :
42 fANucleus(NA),fBNucleus(NB),
43 fXSect(0),fNucleonsA(0),fNucleonsB(0),fnt(0),
44 fMeanX2(0),fMeanY2(0),fMeanXY(0),fMeanXParts(0),
45 fMeanYParts(0),fMeanXSystem(0),fMeanYSystem(0),
46 fMeanX_A(0),fMeanY_A(0),fMeanX_B(0),fMeanY_B(0),fB_MC(0),
47 fEvents(0),fTotalEvents(0),fBMin(0),fBMax(0),fMaxNpartFound(0),
48 fNpart(0),fNcoll(0),fSx2(0),fSy2(0),fSxy(0), fX(0.13), fNpp(8.)
54 TString name(Form("Glauber_%s_%s",fANucleus.GetName(),fBNucleus.GetName()));
55 TString title(Form("Glauber %s+%s Version",fANucleus.GetName(),fBNucleus.GetName()));
60 //______________________________________________________________________________
61 Bool_t AliGlauberMC::CalcEvent(Double_t bgen)
64 fANucleus.ThrowNucleons(-bgen/2.);
65 fNucleonsA = fANucleus.GetNucleons();
66 fAN = fANucleus.GetN();
67 for (Int_t i = 0; i<fAN; i++) {
68 AliGlauberNucleon *nucleonA=(AliGlauberNucleon*)(fNucleonsA->At(i));
69 nucleonA->SetInNucleusA();
71 fBNucleus.ThrowNucleons(bgen/2.);
72 fNucleonsB = fBNucleus.GetNucleons();
73 fBN = fBNucleus.GetN();
74 for (Int_t i = 0; i<fBN; i++) {
75 AliGlauberNucleon *nucleonB=(AliGlauberNucleon*)(fNucleonsB->At(i));
76 nucleonB->SetInNucleusB();
79 // "ball" diameter = distance at which two balls interact
80 Double_t d2 = (Double_t)fXSect/(TMath::Pi()*10); // in fm^2
82 // for each of the A nucleons in nucleus B
83 for (Int_t i = 0; i<fBN; i++) {
84 AliGlauberNucleon *nucleonB=(AliGlauberNucleon*)(fNucleonsB->At(i));
85 for (Int_t j = 0 ; j < fAN ;j++) {
86 AliGlauberNucleon *nucleonA=(AliGlauberNucleon*)(fNucleonsA->At(j));
87 Double_t dx = nucleonB->GetX()-nucleonA->GetX();
88 Double_t dy = nucleonB->GetY()-nucleonA->GetY();
89 Double_t dij = dx*dx+dy*dy;
97 return CalcResults(bgen);
100 //______________________________________________________________________________
101 Bool_t AliGlauberMC::CalcResults(Double_t bgen)
103 // calc results for the given event
118 for (Int_t i = 0; i<fAN; i++) {
119 AliGlauberNucleon *nucleonA=(AliGlauberNucleon*)(fNucleonsA->At(i));
120 Double_t xA=nucleonA->GetX();
121 Double_t yA=nucleonA->GetY();
127 if(nucleonA->IsWounded()) {
137 for (Int_t i = 0; i<fBN; i++) {
138 AliGlauberNucleon *nucleonB=(AliGlauberNucleon*)(fNucleonsB->At(i));
139 Double_t xB=nucleonB->GetX();
140 Double_t yB=nucleonB->GetY();
146 if(nucleonB->IsWounded()) {
153 fNcoll += nucleonB->GetNColl();
158 fMeanXParts /= fNpart;
159 fMeanYParts /= fNpart;
172 fMeanXSystem /= (fAN + fBN);
173 fMeanYSystem /= (fAN + fBN);
194 fSx2=fMeanX2-(fMeanXParts*fMeanXParts);
195 fSy2=fMeanY2-(fMeanYParts*fMeanYParts);
196 fSxy=fMeanXY-fMeanXParts*fMeanYParts;
201 if (fNpart>0) fEvents++;
203 if (fNpart==0) return kFALSE;
204 if (fNpart > fMaxNpartFound) fMaxNpartFound = fNpart;
209 //______________________________________________________________________________
210 void AliGlauberMC::Draw(Option_t* /*option*/)
212 fANucleus.Draw(fXSect, 2);
213 fBNucleus.Draw(fXSect, 4);
220 e.DrawEllipse(GetB()/2,0,fBNucleus.GetR(),fBNucleus.GetR(),0,360,0);
221 e.DrawEllipse(-GetB()/2,0,fANucleus.GetR(),fANucleus.GetR(),0,360,0);
224 //______________________________________________________________________________
225 Double_t AliGlauberMC::GetTotXSect() const
227 return (1.*fEvents/fTotalEvents)*TMath::Pi()*fBMax*fBMax/100;
230 //______________________________________________________________________________
231 Double_t AliGlauberMC::GetTotXSectErr() const
233 return GetTotXSect()/TMath::Sqrt((Double_t)fEvents) *
234 TMath::Sqrt(Double_t(1.-fEvents/fTotalEvents));
237 //______________________________________________________________________________
238 TObjArray *AliGlauberMC::GetNucleons()
240 if(!fNucleonsA || !fNucleonsB) return 0;
241 fNucleonsA->SetOwner(0);
242 fNucleonsB->SetOwner(0);
243 TObjArray *allnucleons=new TObjArray(fAN+fBN);
244 allnucleons->SetOwner();
245 for (Int_t i = 0; i<fAN; i++) {
246 allnucleons->Add(fNucleonsA->At(i));
248 for (Int_t i = 0; i<fBN; i++) {
249 allnucleons->Add(fNucleonsB->At(i));
254 //______________________________________________________________________________
255 Double_t AliGlauberMC::GetdNdEta( const Double_t npp, const Double_t x) const
257 //Get particle density per unit of rapidity
258 //using the two component model
259 return (npp*((1.-x)*fNpart/2.+x*fNcoll));
262 //______________________________________________________________________________
263 Double_t AliGlauberMC::GetdNdEtaGBW( const Double_t delta,
264 const Double_t lambda,
265 const Double_t snn ) const
267 //Get particle density per unit of rapidity
268 //using the GBW model
269 return (fNpart*0.47*TMath::Sqrt(TMath::Power(snn,lambda))
270 * TMath::Power(fNpart,(1.-delta)/3./delta));
273 //______________________________________________________________________________
274 Double_t AliGlauberMC::GetEccentricityPart() const
276 //get participant eccentricity
277 return (TMath::Sqrt((fSy2-fSx2)*(fSy2-fSx2)+4*fSxy*fSxy)/(fSy2+fSx2));
280 //______________________________________________________________________________
281 Double_t AliGlauberMC::GetEccentricity() const
283 //get standard eccentricity
284 return ((fSy2-fSx2)/(fSy2+fSx2));
286 //______________________________________________________________________________
287 Bool_t AliGlauberMC::NextEvent(Double_t bgen)
291 bgen = TMath::Sqrt((fBMax*fBMax-fBMin*fBMin)*gRandom->Rndm()+fBMin*fBMin);
293 return CalcEvent(bgen);
296 //______________________________________________________________________________
297 void AliGlauberMC::Run(Int_t nevents)
299 TString name(Form("nt_%s_%s",fANucleus.GetName(),fBNucleus.GetName()));
300 TString title(Form("%s + %s (x-sect = %d mb)",fANucleus.GetName(),fBNucleus.GetName(),(Int_t) fXSect));
302 fnt = new TNtuple(name,title,
303 "Npart:Ncoll:B:MeanX:MeanY:MeanX2:MeanY2:MeanXY:VarX:VarY:VarXY:MeanXSystem:MeanYSystem:MeanXA:MeanYA:MeanXB:MeanYB:VarE:VarEpart:Mult:MultGBW");
304 fnt->SetDirectory(0);
307 for (int i = 0;i<nevents;i++) {
309 while(!NextEvent()) {}
323 v[11] = fMeanXSystem;
324 v[12] = fMeanYSystem;
329 v[17] = GetEccentricity();
330 v[18] = GetEccentricityPart();
332 v[20] = GetdNdEtaGBW();
336 if (!(i%50)) std::cout << "Event # " << i << " x-sect = " << GetTotXSect() << " +- " << GetTotXSectErr() << " b \r" << flush;
338 std::cout << std::endl << "Done!" << std::endl;
341 //---------------------------------------------------------------------------------
342 void AliGlauberMC::runAndSaveNtuple( Int_t n,
349 AliGlauberMC *mcg=new AliGlauberMC(sysA,sysB,signn);
350 mcg->SetMinDistance(mind);
352 TNtuple *nt=mcg->GetNtuple();
353 TFile out(fname,"recreate",fname,9);
358 //---------------------------------------------------------------------------------
359 void AliGlauberMC::runAndSaveNucleons( Int_t n,
367 AliGlauberMC *mcg=new AliGlauberMC(sysA,sysB,signn);
368 mcg->SetMinDistance(mind);
371 out=new TFile(fname,"recreate",fname,9);
373 for(Int_t ievent=0;ievent<n;ievent++){
375 //get an event with at least one collision
376 while(!mcg->NextEvent()) {}
378 //access, save and (if wanted) print out nucleons
379 TObjArray* nucleons=mcg->GetNucleons();
380 if(!nucleons) continue;
382 nucleons->Write(Form("nucleonarray%d",ievent),TObject::kSingleKey);
385 cout<<endl<<endl<<"EVENT NO: "<<ievent<<endl;
386 cout<<"B = "<<mcg->GetB()<<" Npart = "<<mcg->GetNpart()<<endl<<endl;
387 printf("Nucleus\t X\t Y\t Z\tNcoll\n");
388 Int_t nNucls=nucleons->GetEntries();
389 for(Int_t iNucl=0;iNucl<nNucls;iNucl++) {
390 AliGlauberNucleon *nucl=(AliGlauberNucleon *)nucleons->At(iNucl);
392 if(nucl->IsInNucleusB()) nucleus='B';
393 Double_t x=nucl->GetX();
394 Double_t y=nucl->GetY();
395 Double_t z=nucl->GetZ();
396 Int_t ncoll=nucl->GetNColl();
397 printf(" %c\t%2.2f\t%2.2f\t%2.2f\t%3d\n",nucleus,x,y,z,ncoll);