LCOV - code coverage report
Current view: top level - FASTSIM - AliFastGlauber.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 945 0.1 %
Date: 2016-06-14 17:26:59 Functions: 1 87 1.1 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       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             :  **************************************************************************/
      15             : 
      16             : /* $Id$ */
      17             : //
      18             : // Utility class to make simple Glauber type calculations 
      19             : //           for SYMMETRIC collision geometries (AA):
      20             : // Impact parameter, production points, reaction plane dependence
      21             : //
      22             : // The SimulateTrigger method can be used for simple MB and hard-process
      23             : // (binary scaling) trigger studies.
      24             : // 
      25             : // Some basic quantities can be visualized directly.
      26             : //
      27             : // The default set-up for PbPb or AUAu collisions can be read from a file 
      28             : // calling Init(1) or Init(2) if you want to read Almonds too.
      29             : //
      30             : // ***** If you change settings dont forget to call init afterwards, *****
      31             : // ***** in order to update the formulas with the new parameters.    *****
      32             : // 
      33             : // Author: andreas.morsch@cern.ch
      34             : //=================== Added by A. Dainese 11/02/04 ===========================
      35             : // Calculate path length for a parton with production point (x0,y0)
      36             : // and propagation direction (ux=cos(phi0),uy=sin(phi0)) 
      37             : // in a collision with impact parameter b and functions that make use
      38             : // of it.
      39             : //=================== Added by A. Dainese 05/03/04 ===========================
      40             : // Calculation of line integrals I0 and I1
      41             : //  integral0 =    \int_0^ellCut dl*(T_A*T_B)(x0+l*ux,y0+l*uy)
      42             : //  integral1 =    \int_0^ellCut dl*l*(T_A*T_B)(x0+l*ux,y0+l*uy)
      43             : // mostly for use in the Quenching class
      44             : //=================== Added by C. Loizdes 27/03/04 ===========================
      45             : // Handling of AuAu collisions
      46             : // More get/set functions
      47             : // Comments, units and clearing of code
      48             : //
      49             : 
      50             : // from AliRoot
      51             : #include "AliFastGlauber.h"
      52             : // from root
      53             : #include <TCanvas.h>
      54             : #include <TF1.h>
      55             : #include <TF2.h>
      56             : #include <TFile.h>
      57             : #include <TH1F.h>
      58             : #include <TH2F.h>
      59             : #include <TLegend.h>
      60             : #include <TMath.h>
      61             : #include <TRandom.h>
      62             : #include <TStyle.h>
      63             : 
      64          12 : ClassImp(AliFastGlauber)
      65             : 
      66             : Float_t AliFastGlauber::fgBMax           = 0.;
      67             : TF1*    AliFastGlauber::fgWSb            = NULL;     
      68             : TF1*    AliFastGlauber::fgRWSb           = NULL;     
      69             : TF2*    AliFastGlauber::fgWSbz           = NULL;    
      70             : TF1*    AliFastGlauber::fgWSz            = NULL;     
      71             : TF1*    AliFastGlauber::fgWSta           = NULL;    
      72             : TF2*    AliFastGlauber::fgWStarfi        = NULL; 
      73             : TF2*    AliFastGlauber::fgWAlmond        = NULL; 
      74             : TF1*    AliFastGlauber::fgWStaa          = NULL;   
      75             : TF1*    AliFastGlauber::fgWSgeo          = NULL;   
      76             : TF1*    AliFastGlauber::fgWSbinary       = NULL;   
      77             : TF1*    AliFastGlauber::fgWSN            = NULL;   
      78             : TF1*    AliFastGlauber::fgWPathLength0   = NULL;   
      79             : TF1*    AliFastGlauber::fgWPathLength    = NULL;
      80             : TF1*    AliFastGlauber::fgWEnergyDensity = NULL;   
      81             : TF1*    AliFastGlauber::fgWIntRadius     = NULL;   
      82             : TF2*    AliFastGlauber::fgWKParticipants = NULL; 
      83             : TF1*    AliFastGlauber::fgWParticipants  = NULL; 
      84             : TF2*    AliFastGlauber::fgWAlmondCurrent = NULL;    
      85             : TF2*    AliFastGlauber::fgWAlmondFixedB[40]; 
      86             : const Int_t AliFastGlauber::fgkMCInts = 100000;
      87             : AliFastGlauber* AliFastGlauber::fgGlauber = NULL;
      88             : 
      89             : 
      90           0 : AliFastGlauber::AliFastGlauber(): 
      91           0 :     fWSr0(0.),
      92           0 :     fWSd(0.), 
      93           0 :     fWSw(0.), 
      94           0 :     fWSn(0.), 
      95           0 :     fSigmaHard(0.),
      96           0 :     fSigmaNN(0.),  
      97           0 :     fA(0),         
      98           0 :     fBmin(0.),     
      99           0 :     fBmax(0.),     
     100           0 :     fEllDef(0),    
     101           0 :     fName()     
     102           0 : {
     103             :   //  Default Constructor 
     104             :   //  Defaults for Pb
     105           0 :   SetMaxImpact();
     106           0 :   SetLengthDefinition();
     107           0 :   SetPbPbLHC();
     108           0 :   fXY[0] = fXY[1] = 0;
     109           0 :   fI0I1[0] = fI0I1[1] = 0;
     110           0 : }
     111             : 
     112             : AliFastGlauber::AliFastGlauber(const AliFastGlauber & gl)
     113           0 :     :TObject(gl),
     114           0 :      fWSr0(0.),
     115           0 :      fWSd(0.), 
     116           0 :      fWSw(0.), 
     117           0 :      fWSn(0.), 
     118           0 :      fSigmaHard(0.),
     119           0 :      fSigmaNN(0.),  
     120           0 :      fA(0),         
     121           0 :      fBmin(0.),     
     122           0 :      fBmax(0.),     
     123           0 :      fEllDef(0),    
     124           0 :      fName()     
     125           0 : {
     126             : // Copy constructor
     127           0 :     gl.Copy(*this);
     128           0 :     fXY[0] = fXY[1] = 0;
     129           0 :     fI0I1[0] = fI0I1[1] = 0;
     130           0 : }
     131             : 
     132             : AliFastGlauber* AliFastGlauber::Instance()
     133             : { 
     134             : // Set random number generator 
     135           0 :     if (fgGlauber) {
     136           0 :         return fgGlauber;
     137             :     } else {
     138           0 :         fgGlauber = new AliFastGlauber();
     139           0 :         return fgGlauber;
     140             :     }
     141           0 : }
     142             : 
     143             : AliFastGlauber::~AliFastGlauber()
     144           0 : {
     145             : // Destructor
     146           0 :   for(Int_t k=0; k<40; k++) delete fgWAlmondFixedB[k];
     147           0 : }
     148             : 
     149             : void AliFastGlauber::SetAuAuRhic()
     150             : {
     151             :   //Set all parameters for RHIC
     152           0 :   SetWoodSaxonParametersAu();
     153           0 :   SetHardCrossSection();
     154           0 :   SetNNCrossSection(42);
     155           0 :   SetNucleus(197);
     156           0 :   SetFileName("$(ALICE_ROOT)/FASTSIM/data/glauberAuAu.root");
     157           0 : }
     158             : 
     159             : void AliFastGlauber::SetPbPbLHC()
     160             : {
     161             :   //Set all parameters for LHC
     162           0 :   SetWoodSaxonParametersPb();
     163           0 :   SetHardCrossSection();
     164           0 :   SetNNCrossSection();
     165           0 :   SetNucleus();
     166           0 :   SetFileName();
     167           0 : }
     168             : 
     169             : void AliFastGlauber::Init(Int_t mode)
     170             : {
     171             :   // Initialisation
     172             :   //    mode = 0; all functions are calculated 
     173             :   //    mode = 1; overlap function is read from file (for Pb-Pb only)
     174             :   //    mode = 2; interaction almond functions are read from file 
     175             :   //              USE THIS FOR PATH LENGTH CALC.!
     176             :   //
     177             : 
     178             :   // 
     179           0 :   Reset(); 
     180             :   //
     181             : 
     182             :   //
     183             :   //  Wood-Saxon
     184             :   //
     185           0 :   fgWSb = new TF1("WSb", WSb, 0, fgBMax, 4);
     186           0 :   fgWSb->SetParameter(0, fWSr0);
     187           0 :   fgWSb->SetParameter(1, fWSd);
     188           0 :   fgWSb->SetParameter(2, fWSw);
     189           0 :   fgWSb->SetParameter(3, fWSn);
     190             : 
     191           0 :   fgRWSb = new TF1("RWSb", RWSb, 0, fgBMax, 4);
     192           0 :   fgRWSb->SetParameter(0, fWSr0);
     193           0 :   fgRWSb->SetParameter(1, fWSd);
     194           0 :   fgRWSb->SetParameter(2, fWSw);
     195           0 :   fgRWSb->SetParameter(3, fWSn);
     196             : 
     197           0 :   fgWSbz = new TF2("WSbz", WSbz, 0, fgBMax, 0, fgBMax, 4);
     198           0 :   fgWSbz->SetParameter(0, fWSr0);
     199           0 :   fgWSbz->SetParameter(1, fWSd);
     200           0 :   fgWSbz->SetParameter(2, fWSw);
     201           0 :   fgWSbz->SetParameter(3, fWSn);
     202             : 
     203           0 :   fgWSz = new TF1("WSz", WSz, 0, fgBMax, 5);
     204           0 :   fgWSz->SetParameter(0, fWSr0);
     205           0 :   fgWSz->SetParameter(1, fWSd);
     206           0 :   fgWSz->SetParameter(2, fWSw);
     207           0 :   fgWSz->SetParameter(3, fWSn);
     208             : 
     209             :   //
     210             :   //  Thickness
     211             :   //
     212           0 :   fgWSta = new TF1("WSta", WSta, 0., fgBMax, 0);
     213             :     
     214             :   //
     215             :   //  Overlap Kernel
     216             :   //
     217           0 :   fgWStarfi = new TF2("WStarfi", WStarfi, 0., fgBMax, 0., TMath::Pi(), 1);
     218           0 :   fgWStarfi->SetParameter(0, 0.);     
     219           0 :   fgWStarfi->SetNpx(200);     
     220           0 :   fgWStarfi->SetNpy(20);    
     221             : 
     222             :   //
     223             :   //  Participants Kernel
     224             :   //
     225           0 :   fgWKParticipants = new TF2("WKParticipants", WKParticipants, 0., fgBMax, 0., TMath::Pi(), 3);
     226           0 :   fgWKParticipants->SetParameter(0, 0.);     
     227           0 :   fgWKParticipants->SetParameter(1, fSigmaNN);     
     228           0 :   fgWKParticipants->SetParameter(2, fA);     
     229           0 :   fgWKParticipants->SetNpx(200);     
     230           0 :   fgWKParticipants->SetNpy(20);      
     231             : 
     232             :   //
     233             :   //  Overlap and Participants
     234             :   //
     235           0 :   if (!mode) {
     236           0 :     fgWStaa = new TF1("WStaa", WStaa, 0., fgBMax, 1);
     237           0 :     fgWStaa->SetNpx(100);
     238           0 :     fgWStaa->SetParameter(0,fA);
     239           0 :     fgWStaa->SetNpx(100);
     240           0 :     fgWParticipants = new TF1("WParticipants", WParticipants, 0., fgBMax, 2);
     241           0 :     fgWParticipants->SetParameter(0, fSigmaNN);     
     242           0 :     fgWParticipants->SetParameter(1, fA);     
     243           0 :     fgWParticipants->SetNpx(100);
     244           0 :   } else {
     245           0 :     Info("Init","Reading overlap function from file %s",fName.Data()); 
     246           0 :     TFile* f = new TFile(fName.Data());
     247           0 :     if(!f->IsOpen()){
     248           0 :       Fatal("Init", "Could not open file %s",fName.Data());
     249           0 :     }
     250           0 :     fgWStaa = (TF1*) f->Get("WStaa");
     251           0 :     fgWParticipants = (TF1*) f->Get("WParticipants");
     252           0 :     delete f;
     253             :   }
     254             : 
     255             :   //
     256             :   //  Energy Density
     257             :   //
     258           0 :   fgWEnergyDensity = new TF1("WEnergyDensity", WEnergyDensity, 0., 2. * fWSr0, 1);
     259           0 :   fgWEnergyDensity->SetParameter(0, fWSr0 + 1.);
     260             :     
     261             :   //
     262             :   //  Geometrical Cross-Section
     263             :   //
     264           0 :   fgWSgeo = new TF1("WSgeo", WSgeo, 0., fgBMax, 1);
     265           0 :   fgWSgeo->SetParameter(0,fSigmaNN); //mbarn
     266           0 :   fgWSgeo->SetNpx(100);
     267             : 
     268             :   //
     269             :   //  Hard cross section (binary collisions)
     270             :   //
     271           0 :   fgWSbinary = new TF1("WSbinary", WSbinary, 0., fgBMax, 1);
     272           0 :   fgWSbinary->SetParameter(0, fSigmaHard); //mbarn
     273           0 :   fgWSbinary->SetNpx(100);
     274             : 
     275             :   //
     276             :   // Hard collisions per event
     277             :   //
     278           0 :   fgWSN = new TF1("WSN", WSN, 0.01, fgBMax, 1);
     279           0 :   fgWSN->SetNpx(100);
     280             : 
     281             :   //
     282             :   //  Almond shaped interaction region
     283             :   //
     284           0 :   fgWAlmond = new TF2("WAlmond", WAlmond, -fgBMax, fgBMax, -fgBMax, fgBMax, 1);
     285           0 :   fgWAlmond->SetParameter(0, 0.);     
     286           0 :   fgWAlmond->SetNpx(200);     
     287           0 :   fgWAlmond->SetNpy(200);  
     288             :   
     289           0 :   if(mode==2) {
     290           0 :     Info("Init","Reading interaction almonds from file: %s",fName.Data());
     291           0 :     Char_t almondName[100];
     292           0 :     TFile* ff = new TFile(fName.Data());
     293           0 :     for(Int_t k=0; k<40; k++) {
     294           0 :       snprintf(almondName,100, "WAlmondFixedB%d",k);
     295           0 :       fgWAlmondCurrent = (TF2*)ff->Get(almondName);
     296           0 :       fgWAlmondFixedB[k] = fgWAlmondCurrent;
     297             :     }
     298           0 :     delete ff;
     299           0 :   }
     300             : 
     301           0 :   fgWIntRadius = new TF1("WIntRadius", WIntRadius, 0., fgBMax, 1);
     302           0 :   fgWIntRadius->SetParameter(0, 0.);    
     303             : 
     304             :   //
     305             :   //  Path Length as a function of Phi
     306             :   //    
     307           0 :   fgWPathLength0 = new TF1("WPathLength0", WPathLength0, -TMath::Pi(), TMath::Pi(), 2);
     308           0 :   fgWPathLength0->SetParameter(0, 0.);
     309           0 :   fgWPathLength0->SetParameter(1, 0.); //Pathlength definition     
     310             : 
     311           0 :   fgWPathLength = new TF1("WPathLength", WPathLength, -TMath::Pi(), TMath::Pi(), 3);
     312           0 :   fgWPathLength->SetParameter(0, 0.);    //Impact Parameter
     313           0 :   fgWPathLength->SetParameter(1, 1000.); //Number of interactions used for average
     314           0 :   fgWPathLength->SetParameter(2, 0);     //Pathlength definition
     315           0 : }
     316             : 
     317             : void AliFastGlauber::Reset() const
     318             : {
     319             :   //
     320             :   // Reset dynamic allocated formulas
     321             :   // in case init is called twice
     322             : 
     323           0 :   if(fgWSb)            delete fgWSb;     
     324           0 :   if(fgRWSb)           delete fgRWSb;     
     325           0 :   if(fgWSbz)           delete fgWSbz;
     326           0 :   if(fgWSz)            delete fgWSz;
     327           0 :   if(fgWSta)           delete fgWSta;
     328           0 :   if(fgWStarfi)        delete fgWStarfi;
     329           0 :   if(fgWAlmond)        delete fgWAlmond;
     330           0 :   if(fgWStaa)          delete fgWStaa;
     331           0 :   if(fgWSgeo)          delete fgWSgeo;
     332           0 :   if(fgWSbinary)       delete fgWSbinary;
     333           0 :   if(fgWSN)            delete fgWSN;
     334           0 :   if(fgWPathLength0)   delete fgWPathLength0;
     335           0 :   if(fgWPathLength)    delete fgWPathLength;
     336           0 :   if(fgWEnergyDensity) delete fgWEnergyDensity;
     337           0 :   if(fgWIntRadius)     delete fgWIntRadius; 
     338           0 :   if(fgWKParticipants) delete fgWKParticipants; 
     339           0 :   if(fgWParticipants)  delete fgWParticipants;
     340           0 : }
     341             : 
     342             : void AliFastGlauber::DrawWSb() const
     343             : {
     344             :   //
     345             :   //  Draw Wood-Saxon Nuclear Density Function
     346             :   //
     347           0 :   TCanvas *c1 = new TCanvas("c1","Wood Saxon",400,10,600,700);
     348           0 :   c1->cd();
     349           0 :   Double_t max=fgWSb->GetMaximum(0.,fgBMax)*1.01;
     350           0 :   TH2F *h2f=new TH2F("h2fwsb","Wood Saxon: #rho(r) = n (1-#omega(r/r_{0})^2)/(1+exp((r-r_{0})/d)) [fm^{-3}]",2,0,fgBMax,2,0,max);
     351           0 :   h2f->SetStats(0);
     352           0 :   h2f->GetXaxis()->SetTitle("r [fm]");
     353           0 :   h2f->GetYaxis()->SetNoExponent(kTRUE);
     354           0 :   h2f->GetYaxis()->SetTitle("#rho [fm^{-3}]");
     355           0 :   h2f->Draw(); 
     356           0 :   fgWSb->Draw("same");
     357           0 :   TLegend *l1a = new TLegend(0.45,0.6,.90,0.8);
     358           0 :   l1a->SetFillStyle(0);
     359           0 :   l1a->SetBorderSize(0);
     360           0 :   Char_t label[100];
     361           0 :   snprintf(label,100, "r_{0} = %.2f fm",fWSr0);
     362           0 :   l1a->AddEntry(fgWSb,label,"");
     363           0 :   snprintf(label,100, "d = %.2f fm",fWSd);
     364           0 :   l1a->AddEntry(fgWSb,label,"");
     365           0 :   snprintf(label,100, "n = %.2e fm^{-3}",fWSn);
     366           0 :   l1a->AddEntry(fgWSb,label,"");
     367           0 :   snprintf(label,100, "#omega = %.2f",fWSw);
     368           0 :   l1a->AddEntry(fgWSb,label,"");
     369           0 :   l1a->Draw();
     370           0 :   c1->Update();
     371           0 : }
     372             : 
     373             : void AliFastGlauber::DrawOverlap() const
     374             : {
     375             :   //
     376             :   //  Draw Overlap Function
     377             :   //
     378           0 :   TCanvas *c2 = new TCanvas("c2","Overlap",400,10,600,700);
     379           0 :   c2->cd();
     380           0 :   Double_t max=fgWStaa->GetMaximum(0,fgBMax)*1.01;
     381           0 :   TH2F *h2f=new TH2F("h2ftaa","Overlap function: T_{AB} [mbarn^{-1}]",2,0,fgBMax,2,0, max);
     382           0 :   h2f->SetStats(0);
     383           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     384           0 :   h2f->GetYaxis()->SetTitle("T_{AB} [mbarn^{-1}]");
     385           0 :   h2f->Draw(); 
     386           0 :   fgWStaa->Draw("same");
     387           0 : }
     388             : 
     389             : void AliFastGlauber::DrawParticipants() const
     390             : {
     391             :   //
     392             :   //  Draw Number of Participants Npart
     393             :   //
     394           0 :   TCanvas *c3 = new TCanvas("c3","Participants",400,10,600,700);
     395           0 :   c3->cd();
     396           0 :   Double_t max=fgWParticipants->GetMaximum(0,fgBMax)*1.01;
     397           0 :   TH2F *h2f=new TH2F("h2fpart","Number of Participants",2,0,fgBMax,2,0,max);
     398           0 :   h2f->SetStats(0);
     399           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     400           0 :   h2f->GetYaxis()->SetTitle("N_{part}");
     401           0 :   h2f->Draw(); 
     402           0 :   fgWParticipants->Draw("same");
     403           0 :   TLegend *l1a = new TLegend(0.50,0.75,.90,0.9);
     404           0 :   l1a->SetFillStyle(0);
     405           0 :   l1a->SetBorderSize(0);
     406           0 :   Char_t label[100];
     407           0 :   snprintf(label,100, "#sigma^{inel.}_{NN} = %.1f mbarn",fSigmaNN);
     408           0 :   l1a->AddEntry(fgWParticipants,label,"");
     409           0 :   l1a->Draw();
     410           0 :   c3->Update();
     411           0 : }
     412             : 
     413             : void AliFastGlauber::DrawThickness() const
     414             : {
     415             :   //
     416             :   //  Draw Thickness Function
     417             :   //
     418           0 :   TCanvas *c4 = new TCanvas("c4","Thickness",400,10,600,700);
     419           0 :   c4->cd();
     420           0 :   Double_t max=fgWSta->GetMaximum(0,fgBMax)*1.01;
     421           0 :   TH2F *h2f=new TH2F("h2fta","Thickness function: T_{A} [fm^{-2}]",2,0,fgBMax,2,0,max);
     422           0 :   h2f->SetStats(0);
     423           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     424           0 :   h2f->GetYaxis()->SetTitle("T_{A} [fm^{-2}]");
     425           0 :   h2f->Draw(); 
     426           0 :   fgWSta->Draw("same");
     427           0 : }
     428             : 
     429             : void AliFastGlauber::DrawGeo() const
     430             : {
     431             :   //
     432             :   //  Draw Geometrical Cross-Section
     433             :   //
     434           0 :   TCanvas *c5 = new TCanvas("c5","Geometrical Cross-Section",400,10,600,700);
     435           0 :   c5->cd();
     436           0 :   Double_t max=fgWSgeo->GetMaximum(0,fgBMax)*1.01;
     437           0 :   TH2F *h2f=new TH2F("h2fgeo","Differential Geometrical Cross-Section: d#sigma^{geo}_{AB}/db [fm]",2,0,fgBMax,2,0,max);
     438           0 :   h2f->SetStats(0);
     439           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     440           0 :   h2f->GetYaxis()->SetTitle("d#sigma^{geo}_{AB}/db [fm]");
     441           0 :   h2f->Draw(); 
     442           0 :   fgWSgeo->Draw("same");
     443           0 :   TLegend *l1a = new TLegend(0.10,0.8,.40,0.9);
     444           0 :   l1a->SetFillStyle(0);
     445           0 :   l1a->SetBorderSize(0);
     446           0 :   Char_t label[100];
     447           0 :   snprintf(label,100, "#sigma_{NN}^{inel.} = %.1f mbarn",fSigmaNN);
     448           0 :   l1a->AddEntry(fgWSgeo,label,"");
     449           0 :   l1a->Draw();
     450           0 :   c5->Update();
     451           0 : }
     452             : 
     453             : void AliFastGlauber::DrawBinary() const
     454             : {
     455             :   //
     456             :   //  Draw Binary Cross-Section
     457             :   //
     458           0 :   TCanvas *c6 = new TCanvas("c6","Binary Cross-Section",400,10,600,700);
     459           0 :   c6->cd();
     460           0 :   Double_t max=fgWSbinary->GetMaximum(0,fgBMax)*1.01;
     461           0 :   TH2F *h2f=new TH2F("h2fbinary","Differential Binary Cross-Section: #sigma^{hard}_{NN} dT_{AB}/db [fm]",2,0,fgBMax,2,0,max);
     462           0 :   h2f->SetStats(0);
     463           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     464           0 :   h2f->GetYaxis()->SetTitle("d#sigma^{hard}_{AB}/db [fm]");
     465           0 :   h2f->Draw(); 
     466           0 :   fgWSbinary->Draw("same");
     467           0 :   TLegend *l1a = new TLegend(0.50,0.8,.90,0.9);
     468           0 :   l1a->SetFillStyle(0);
     469           0 :   l1a->SetBorderSize(0);
     470           0 :   Char_t label[100];
     471           0 :   snprintf(label,100, "#sigma_{NN}^{hard} = %.1f mbarn",fSigmaHard);
     472           0 :   l1a->AddEntry(fgWSb,label,"");
     473           0 :   l1a->Draw();
     474           0 :   c6->Update();
     475           0 : }
     476             : 
     477             : void AliFastGlauber::DrawN() const
     478             : {
     479             :   //
     480             :   //  Draw Binaries per event (Ncoll)
     481             :   //
     482           0 :   TCanvas *c7 = new TCanvas("c7","Binaries per event",400,10,600,700);
     483           0 :   c7->cd();
     484           0 :   Double_t max=fgWSN->GetMaximum(0.01,fgBMax)*1.01;
     485           0 :   TH2F *h2f=new TH2F("h2fhardcols","Number of hard collisions: T_{AB} #sigma^{hard}_{NN}/#sigma_{AB}^{geo}",2,0,fgBMax,2,0,max);
     486           0 :   h2f->SetStats(0);
     487           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     488           0 :   h2f->GetYaxis()->SetTitle("N_{coll}");
     489           0 :   h2f->Draw(); 
     490           0 :   fgWSN->Draw("same");
     491           0 :   TLegend *l1a = new TLegend(0.50,0.75,.90,0.9);
     492           0 :   l1a->SetFillStyle(0);
     493           0 :   l1a->SetBorderSize(0);
     494           0 :   Char_t label[100];
     495           0 :   snprintf(label,100, "#sigma^{hard}_{NN} = %.1f mbarn",fSigmaHard);
     496           0 :   l1a->AddEntry(fgWSN,label,"");
     497           0 :   snprintf(label,100, "#sigma^{inel.}_{NN} = %.1f mbarn",fSigmaNN);
     498           0 :   l1a->AddEntry(fgWSN,label,"");
     499           0 :   l1a->Draw();
     500           0 :   c7->Update();
     501           0 : }
     502             : 
     503             : void AliFastGlauber::DrawKernel(Double_t b) const
     504             : {
     505             :   //
     506             :   //  Draw Kernel
     507             :   //
     508           0 :   TCanvas *c8 = new TCanvas("c8","Kernel",400,10,600,700);
     509           0 :   c8->cd();
     510           0 :   fgWStarfi->SetParameter(0, b);
     511           0 :   TH2F *h2f=new TH2F("h2fkernel","Kernel of Overlap function: d^{2}T_{AB}/dr/d#phi [fm^{-3}]",2,0,fgBMax,2,0,TMath::Pi());
     512           0 :   h2f->SetStats(0);
     513           0 :   h2f->GetXaxis()->SetTitle("r [fm]");
     514           0 :   h2f->GetYaxis()->SetTitle("#phi [rad]");
     515           0 :   h2f->Draw(); 
     516           0 :   fgWStarfi->Draw("same");
     517           0 :   TLegend *l1a = new TLegend(0.65,0.8,.90,0.9);
     518           0 :   l1a->SetFillStyle(0);
     519           0 :   l1a->SetBorderSize(0);
     520           0 :   Char_t label[100];
     521           0 :   snprintf(label, 100, "b = %.1f fm",b);
     522           0 :   l1a->AddEntry(fgWStarfi,label,"");
     523           0 :   l1a->Draw();
     524           0 :   c8->Update();
     525           0 : }
     526             : 
     527             : void AliFastGlauber::DrawAlmond(Double_t b) const
     528             : {
     529             :   //
     530             :   //  Draw Interaction Almond
     531             :   //
     532           0 :   TCanvas *c9 = new TCanvas("c9","Almond",400,10,600,700);
     533           0 :   c9->cd();
     534           0 :   fgWAlmond->SetParameter(0, b);
     535           0 :   TH2F *h2f=new TH2F("h2falmond","Interaction Almond [fm^{-4}]",2,-fgBMax, fgBMax, 2, -fgBMax, fgBMax);
     536           0 :   h2f->SetStats(0);
     537           0 :   h2f->GetXaxis()->SetTitle("x [fm]");
     538           0 :   h2f->GetYaxis()->SetTitle("y [fm]");
     539           0 :   h2f->Draw("");
     540           0 :   gStyle->SetPalette(1);
     541           0 :   fgWAlmond->Draw("colzsame");
     542           0 :   TLegend *l1a = new TLegend(0.65,0.8,.90,0.9);
     543           0 :   l1a->SetFillStyle(0);
     544           0 :   l1a->SetBorderSize(0);
     545           0 :   Char_t label[100];
     546           0 :   snprintf(label, 100, "b = %.1f fm",b);
     547           0 :   l1a->AddEntry(fgWAlmond,label,"");
     548           0 :   l1a->Draw();
     549           0 :   c9->Update();
     550           0 : }
     551             : 
     552             : void AliFastGlauber::DrawEnergyDensity() const
     553             : {
     554             :   //
     555             :   //  Draw energy density
     556             :   //
     557           0 :   TCanvas *c10 = new TCanvas("c10","Energy Density",400, 10, 600, 700);
     558           0 :   c10->cd();
     559           0 :   fgWEnergyDensity->SetMinimum(0.);
     560           0 :   Double_t max=fgWEnergyDensity->GetMaximum(0,fgWEnergyDensity->GetParameter(0))*1.01;
     561           0 :   TH2F *h2f=new TH2F("h2fenergydens","Energy density",2,0,fgBMax,2,0,max);
     562           0 :   h2f->SetStats(0);
     563           0 :   h2f->GetXaxis()->SetTitle("b [fm]");
     564           0 :   h2f->GetYaxis()->SetTitle("fm^{-4}");
     565           0 :   h2f->Draw(); 
     566           0 :   fgWEnergyDensity->Draw("same");
     567           0 :   c10->Update();
     568           0 : }
     569             : 
     570             : void AliFastGlauber::DrawPathLength0(Double_t b, Int_t iopt) const
     571             : {
     572             :   //
     573             :   //  Draw Path Length
     574             :   //
     575           0 :   TCanvas *c11 = new TCanvas("c11","Path Length",400,10,600,700);
     576           0 :   c11->cd();
     577           0 :   fgWPathLength0->SetParameter(0, b);
     578           0 :   fgWPathLength0->SetParameter(1, Double_t(iopt));
     579           0 :   fgWPathLength0->SetMinimum(0.); 
     580           0 :   fgWPathLength0->SetMaximum(10.); 
     581           0 :   TH2F *h2f=new TH2F("h2fpathlength0","Path length",2,-TMath::Pi(), TMath::Pi(),2,0,10.);
     582           0 :   h2f->SetStats(0);
     583           0 :   h2f->GetXaxis()->SetTitle("#phi [rad]");
     584           0 :   h2f->GetYaxis()->SetTitle("l [fm]");
     585           0 :   h2f->Draw(); 
     586           0 :   fgWPathLength0->Draw("same");
     587           0 : }
     588             : 
     589             : void AliFastGlauber::DrawPathLength(Double_t b , Int_t ni, Int_t iopt) const
     590             : {
     591             :   //
     592             :   //  Draw Path Length
     593             :   //
     594           0 :   TCanvas *c12 = new TCanvas("c12","Path Length",400,10,600,700);
     595           0 :   c12->cd();
     596           0 :   fgWAlmond->SetParameter(0, b);
     597           0 :   fgWPathLength->SetParameter(0, b);
     598           0 :   fgWPathLength->SetParameter(1, Double_t (ni));
     599           0 :   fgWPathLength->SetParameter(2, Double_t (iopt));
     600           0 :   fgWPathLength->SetMinimum(0.); 
     601           0 :   fgWPathLength->SetMaximum(10.); 
     602           0 :   TH2F *h2f=new TH2F("h2fpathlength","Path length",2,-TMath::Pi(), TMath::Pi(),2,0,10.);
     603           0 :   h2f->SetStats(0);
     604           0 :   h2f->GetXaxis()->SetTitle("#phi [rad]");
     605           0 :   h2f->GetYaxis()->SetTitle("l [fm]");
     606           0 :   h2f->Draw(); 
     607           0 :   fgWPathLength->Draw("same");
     608           0 : }
     609             : 
     610             : void AliFastGlauber::DrawIntRadius(Double_t b) const
     611             : {
     612             :   //
     613             :   //  Draw Interaction Radius
     614             :   //
     615           0 :   TCanvas *c13 = new TCanvas("c13","Interaction Radius",400,10,600,700);
     616           0 :   c13->cd();
     617           0 :   fgWIntRadius->SetParameter(0, b);
     618           0 :   fgWIntRadius->SetMinimum(0);
     619           0 :   Double_t max=fgWIntRadius->GetMaximum(0,fgBMax)*1.01;
     620           0 :   TH2F *h2f=new TH2F("h2fintradius","Interaction Density",2,0.,fgBMax,2,0,max);
     621           0 :   h2f->SetStats(0);
     622           0 :   h2f->GetXaxis()->SetTitle("r [fm]");
     623           0 :   h2f->GetYaxis()->SetTitle("[fm^{-3}]");
     624           0 :   h2f->Draw(); 
     625           0 :   fgWIntRadius->Draw("same");
     626           0 : }
     627             : 
     628             : Double_t AliFastGlauber::WSb(const Double_t* x, const Double_t* par)
     629             : {
     630             :   //
     631             :   //  Woods-Saxon Parameterisation
     632             :   //  as a function of radius (xx)
     633             :   //
     634           0 :   const Double_t kxx  = x[0];   //fm
     635           0 :   const Double_t kr0  = par[0]; //fm
     636           0 :   const Double_t kd   = par[1]; //fm   
     637           0 :   const Double_t kw   = par[2]; //no units
     638           0 :   const Double_t kn   = par[3]; //fm^-3 (used to normalize integral to one)
     639           0 :   Double_t y   = kn * (1.+kw*(kxx/kr0)*(kxx/kr0))/(1.+TMath::Exp((kxx-kr0)/kd));
     640           0 :   return y; //fm^-3
     641             : }
     642             : 
     643             : Double_t AliFastGlauber::RWSb(const Double_t* x, const Double_t* par)
     644             : {
     645             :   //
     646             :   //  Woods-Saxon Parameterisation
     647             :   //  as a function of radius (xx)
     648             :   //  times r**2
     649           0 :   const Double_t kxx  = x[0];   //fm
     650           0 :   const Double_t kr0  = par[0]; //fm
     651           0 :   const Double_t kd   = par[1]; //fm   
     652           0 :   const Double_t kw   = par[2]; //no units
     653           0 :   const Double_t kn   = par[3]; //fm^-3 (used to normalize integral to one)
     654           0 :   Double_t y   = kxx * kxx * kn * (1.+kw*(kxx/kr0)*(kxx/kr0))/(1.+TMath::Exp((kxx-kr0)/kd));
     655             : 
     656           0 :   return y; //fm^-1
     657             : }
     658             : 
     659             : Double_t AliFastGlauber::WSbz(const Double_t* x, const Double_t* par)
     660             : {
     661             :   //
     662             :   //  Wood Saxon Parameterisation
     663             :   //  as a function of z and  b
     664             :   //
     665           0 :   const Double_t kbb  = x[0];   //fm
     666           0 :   const Double_t kzz  = x[1];   //fm
     667           0 :   const Double_t kr0  = par[0]; //fm
     668           0 :   const Double_t kd   = par[1]; //fm
     669           0 :   const Double_t kw   = par[2]; //no units
     670           0 :   const Double_t kn   = par[3]; //fm^-3 (used to normalize integral to one)
     671           0 :   const Double_t kxx  = TMath::Sqrt(kbb*kbb+kzz*kzz);
     672           0 :   Double_t y  = kn * (1.+kw*(kxx/kr0)*(kxx/kr0))/(1.+TMath::Exp((kxx-kr0)/kd));
     673           0 :   return y; //fm^-3
     674             : }
     675             : 
     676             : Double_t AliFastGlauber::WSz(const Double_t* x, const Double_t* par)
     677             : {
     678             :   //
     679             :   //  Wood Saxon Parameterisation
     680             :   //  as a function of z for fixed b
     681             :   //
     682           0 :   const Double_t kzz  = x[0];   //fm
     683           0 :   const Double_t kr0  = par[0]; //fm
     684           0 :   const Double_t kd   = par[1]; //fm
     685           0 :   const Double_t kw   = par[2]; //no units
     686           0 :   const Double_t kn   = par[3]; //fm^-3 (used to normalize integral to one)
     687           0 :   const Double_t kbb  = par[4]; //fm
     688           0 :   const Double_t kxx  = TMath::Sqrt(kbb*kbb+kzz*kzz);
     689           0 :   Double_t y  = kn * (1.+kw*(kxx/kr0)*(kxx/kr0))/(1.+TMath::Exp((kxx-kr0)/kd));
     690           0 :   return y; //fm^-3
     691             : }
     692             : 
     693             : Double_t AliFastGlauber::WSta(const Double_t* x, const Double_t* /*par*/)
     694             : {
     695             :   //
     696             :   //  Thickness function T_A
     697             :   //  as a function of b
     698             :   //
     699           0 :   const Double_t kb  = x[0];
     700           0 :   fgWSz->SetParameter(4, kb);
     701           0 :   Double_t y  = 2. * fgWSz->Integral(0., fgBMax);
     702           0 :   return y; //fm^-2
     703             : }
     704             : 
     705             : Double_t AliFastGlauber::WStarfi(const Double_t* x, const Double_t* par)
     706             : {
     707             :   //
     708             :   //  Kernel for overlap function: T_A(s)*T_A(s-b)
     709             :   //  as a function of r and phi
     710           0 :   const Double_t kr1  = x[0];
     711           0 :   const Double_t kphi = x[1];
     712           0 :   const Double_t kb   = par[0];
     713           0 :   const Double_t kr2  = TMath::Sqrt(kr1*kr1 + kb*kb - 2.*kr1*kb*TMath::Cos(kphi)); 
     714           0 :   Double_t y = kr1 * fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
     715           0 :   return y; //fm^-3
     716             : }
     717             : 
     718             : Double_t AliFastGlauber::WStaa(const Double_t* x, const Double_t* par)
     719             : {
     720             :   //
     721             :   //  Overlap function 
     722             :   //  T_{AB}=Int d2s T_A(s)*T_B(s-b)
     723             :   //  as a function of b
     724             :   // (normalized to fA*fB)
     725             :   //
     726           0 :   const Double_t kb  = x[0];
     727           0 :   const Double_t ka = par[0];
     728           0 :   fgWStarfi->SetParameter(0, kb);
     729             : 
     730             :   // root integration seems to fail
     731             :   /* 
     732             :      Double_t al[2];
     733             :      Double_t bl[2];
     734             :      al[0] = 1e-6;
     735             :      al[1] = fgBMax;
     736             :      bl[0] = 0.;
     737             :      bl[1] = TMath::Pi();
     738             :      Double_t err;
     739             :      
     740             :      Double_t y =  2. *  208. * 208. * fgWStarfi->IntegralMultiple(2, al, bl, 0.001, err);
     741             :      printf("WStaa: %.5e %.5e %.5e\n", b, y, err);
     742             :   */
     743             : 
     744             :   //
     745             :   //  MC Integration
     746             :   //
     747             :   Double_t y = 0;
     748             :   
     749             : 
     750           0 :   for (Int_t i = 0; i < fgkMCInts; i++)
     751             :     {
     752             :         
     753           0 :       const Double_t kphi = TMath::Pi() * gRandom->Rndm();
     754           0 :       const Double_t kb1  = fgBMax      * gRandom->Rndm();   
     755           0 :       y += fgWStarfi->Eval(kb1, kphi);
     756             :     }
     757           0 :   y *= 2. * TMath::Pi() * fgBMax / fgkMCInts; //fm^-2
     758           0 :   y *= ka * ka * 0.1; //mbarn^-1
     759           0 :   return y;
     760             : }
     761             : 
     762             : Double_t AliFastGlauber::WKParticipants(const Double_t* x, const Double_t* par)
     763             : {
     764             :   //
     765             :   //  Kernel for number of participants
     766             :   //  as a function of r and phi
     767             :   //
     768           0 :   const Double_t kr1   = x[0];
     769           0 :   const Double_t kphi  = x[1];
     770           0 :   const Double_t kb    = par[0]; //fm
     771           0 :   const Double_t ksig  = par[1]; //mbarn
     772           0 :   const Double_t ka    = par[2]; //mass number
     773           0 :   const Double_t kr2   = TMath::Sqrt(kr1*kr1 +kb*kb - 2.*kr1*kb*TMath::Cos(kphi)); 
     774           0 :   const Double_t kxsi  = fgWSta->Eval(kr2) * ksig * 0.1; //no units
     775             :   /*
     776             :     Double_t y=(1-TMath::Power((1-xsi),aa))
     777             :    */
     778             :   Double_t a   = ka;
     779           0 :   Double_t sum = ka * kxsi;
     780             :   Double_t y   = sum;
     781           0 :   for (Int_t i = 1; i <= ka; i++)
     782             :     {
     783           0 :       a--;
     784           0 :       sum *= (-kxsi) * a / Float_t(i+1);
     785           0 :       y  += sum;
     786             :     }
     787           0 :   y *= kr1 * fgWSta->Eval(kr1);
     788           0 :   return y; //fm^-1
     789             : }
     790             : 
     791             : Double_t AliFastGlauber::WParticipants(const Double_t* x, const Double_t* par)
     792             : {
     793             :   //
     794             :   //  Number of Participants as 
     795             :   //  a function of b
     796             :   //
     797           0 :   const Double_t kb = x[0];
     798           0 :   const Double_t ksig  = par[0]; //mbarn
     799           0 :   const Double_t ka   = par[1];  //mass number
     800           0 :   fgWKParticipants->SetParameter(0, kb);
     801           0 :   fgWKParticipants->SetParameter(1, ksig);
     802           0 :   fgWKParticipants->SetParameter(2, ka);
     803             : 
     804             :   //
     805             :   //  MC Integration
     806             :   //
     807             :   Double_t y = 0;
     808           0 :   for (Int_t i = 0; i < fgkMCInts; i++)
     809             :     {
     810           0 :       const Double_t kphi = TMath::Pi() * gRandom->Rndm();
     811           0 :       const Double_t kb1  = fgBMax      * gRandom->Rndm();   
     812           0 :       y += fgWKParticipants->Eval(kb1, kphi);
     813             :     }
     814           0 :   y *= 2. *  ka * 2. * TMath::Pi() * fgBMax / fgkMCInts;
     815           0 :   return y; //no units
     816             : }
     817             : 
     818             : Double_t AliFastGlauber::WSgeo(const Double_t* x, const Double_t* par)
     819             : {
     820             :   //
     821             :   //  Geometrical Cross-Section
     822             :   //  as a function of b
     823             :   //
     824           0 :   const Double_t kb     = x[0];              //fm
     825           0 :   const Double_t ksigNN = par[0];            //mbarn
     826           0 :   const Double_t ktaa   = fgWStaa->Eval(kb); //mbarn^-1
     827           0 :   Double_t y     = 2. * TMath::Pi() * kb * (1. - TMath::Exp(- ksigNN * ktaa)); 
     828           0 :   return y; //fm
     829             : }
     830             : 
     831             : Double_t AliFastGlauber::WSbinary(const Double_t* x, const Double_t* par)
     832             : {
     833             :   //
     834             :   //  Number of binary hard collisions
     835             :   //  as a function of b
     836             :   //
     837           0 :   const Double_t kb     = x[0];              //fm
     838           0 :   const Double_t ksig   = par[0];            //mbarn
     839           0 :   const Double_t ktaa   = fgWStaa->Eval(kb); //mbarn^-1
     840           0 :   Double_t y = 2. * TMath::Pi() * kb * ksig * ktaa; 
     841           0 :   return y; //fm
     842             : }
     843             : 
     844             : Double_t AliFastGlauber::WSN(const Double_t* x, const Double_t* /*par*/)
     845             : {
     846             :   //
     847             :   //  Number of hard processes per event
     848             :   //  as a function of b
     849           0 :   const Double_t kb = x[0];
     850           0 :   Double_t y = fgWSbinary->Eval(kb)/fgWSgeo->Eval(kb);
     851           0 :   return y; //no units
     852             : }
     853             : 
     854             : Double_t AliFastGlauber::WEnergyDensity(const Double_t* x, const Double_t* par)
     855             : {
     856             :   //
     857             :   //  Initial energy density 
     858             :   //  as a function of the impact parameter
     859             :   //
     860           0 :   const Double_t kb     = x[0];
     861           0 :   const Double_t krA    = par[0];
     862             :   //
     863             :   //  Attention: area of transverse reaction zone in hard-sphere approximation !     
     864           0 :   const Double_t krA2=krA*krA;
     865           0 :   const Double_t kb2=kb*kb;  
     866           0 :   const Double_t ksaa = (TMath::Pi() - 2. * TMath::ASin(kb/ 2./ krA)) * krA2 
     867           0 :                       - kb * TMath::Sqrt(krA2 - kb2/ 4.); //fm^2
     868           0 :   const Double_t ktaa = fgWStaa->Eval(kb); //mbarn^-1
     869           0 :   Double_t y=ktaa/ksaa*10;
     870           0 :   return y; //fm^-4
     871             : }
     872             : 
     873             : Double_t AliFastGlauber::WAlmond(const Double_t* x, const Double_t* par)
     874             : {
     875             :   //
     876             :   //  Almond shaped interaction region
     877             :   //  as a function of cartesian x,y.
     878             :   //
     879           0 :   const Double_t kb    = par[0];
     880           0 :   const Double_t kxx   = x[0] + kb/2.;
     881           0 :   const Double_t kyy   = x[1];
     882           0 :   const Double_t kr1   = TMath::Sqrt(kxx*kxx + kyy*kyy);
     883           0 :   const Double_t kphi  = TMath::ATan2(kyy,kxx);
     884           0 :   const Double_t kr2   = TMath::Sqrt(kr1*kr1 + kb*kb - 2.*kr1*kb*TMath::Cos(kphi)); 
     885             :   //
     886             :   //  Interaction probability calculated as product of thicknesses
     887             :   //
     888           0 :   Double_t y    = fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
     889           0 :   return y; //fm^-4
     890             : }
     891             : 
     892             : Double_t AliFastGlauber::WIntRadius(const Double_t* x, const Double_t* par)
     893             : {
     894             :   //
     895             :   //  Average interaction density over radius 
     896             :   //  at which interaction takes place
     897             :   //  as a function of radius
     898             :   //
     899           0 :   const Double_t kr    = x[0];
     900           0 :   const Double_t kb    = par[0];
     901           0 :   fgWAlmond->SetParameter(0, kb);
     902             :   //  Average over phi in small steps   
     903           0 :   const Double_t kdphi = 2. * TMath::Pi() / 100.;
     904             :   Double_t phi  = 0.;
     905             :   Double_t y    = 0.;
     906           0 :   for (Int_t i = 0; i < 100; i++) {
     907           0 :     const Double_t kxx = kr * TMath::Cos(phi);
     908           0 :     const Double_t kyy = kr * TMath::Sin(phi);
     909           0 :     y   += fgWAlmond->Eval(kxx,kyy);
     910           0 :     phi += kdphi;
     911             :   } // phi loop
     912             :   // Result multiplied by Jacobian (2 pi r)     
     913           0 :   y *= 2. * TMath::Pi() * kr / 100.;
     914           0 :   return y; //fm^-3
     915             : }
     916             : 
     917             : Double_t AliFastGlauber::WPathLength0(const Double_t* x, const Double_t* par)
     918             : {
     919             :   //
     920             :   //  Path Length as a function of phi 
     921             :   //  for interaction point fixed at (0,0)
     922             :   //  as a function of phi-direction
     923             :   //
     924             :   //  Phi direction in Almond
     925           0 :   const Double_t kphi0   = x[0];
     926           0 :   const Double_t kb      = par[0];
     927             :   //  Path Length definition
     928           0 :   const Int_t    kiopt   = Int_t(par[1]);
     929             : 
     930             :   //  Step along radial direction phi   
     931             :   const Int_t    kNp  = 100; // Steps in r 
     932           0 :   const Double_t kDr  = fgBMax/kNp;
     933             :   Double_t r  = 0.;
     934             :   Double_t rw = 0.;
     935             :   Double_t w  = 0.;
     936           0 :   for (Int_t i = 0; i < kNp; i++) {
     937             :     //
     938             :     //  Transform into target frame
     939             :     //
     940           0 :     const Double_t kxx   = r * TMath::Cos(kphi0) + kb / 2.;
     941           0 :     const Double_t kyy   = r * TMath::Sin(kphi0);
     942           0 :     const Double_t kphi  = TMath::ATan2(kyy, kxx);
     943           0 :     const Double_t kr1   = TMath::Sqrt(kxx*kxx + kyy*kyy);
     944             :     // Radius in projectile frame
     945           0 :     const Double_t kr2   = TMath::Sqrt(kr1*kr1 + kb*kb - 2.*kr1*kb*TMath::Cos(kphi)); 
     946           0 :     const Double_t ky    = fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
     947             : 
     948           0 :     rw += ky * r;
     949           0 :     w  += ky;
     950           0 :     r  += kDr;
     951             :   } // radial steps
     952             : 
     953             :   Double_t y=0.;
     954           0 :   if (!kiopt) { // My length definition (is exact for hard disk)
     955           0 :       if(w) y= 2. * rw / w; 
     956             :   } else {
     957           0 :       const Double_t knorm=fgWSta->Eval(1e-4);
     958           0 :       if(knorm) y =  TMath::Sqrt(2. * rw * kDr / knorm / knorm);
     959             :   }
     960           0 :   return y; //fm
     961             : }
     962             : 
     963             : Double_t AliFastGlauber::WPathLength(const Double_t* x, const Double_t* par)
     964             : {
     965             :   //
     966             :   //  Path Length as a function of phi 
     967             :   //  Interaction point from random distribution
     968             :   //  as a function of the phi-direction
     969           0 :   const Double_t kphi0   = x[0];
     970           0 :   const Double_t kb      = par[0];
     971           0 :   fgWAlmond->SetParameter(0, kb); 
     972           0 :   const Int_t    kNpi    = Int_t (par[1]); //Number of interactions
     973           0 :   const Int_t    kiopt   = Int_t(par[2]);  //Path Length definition 
     974             : 
     975             :   //
     976             :   //  r-steps
     977             :   // 
     978             :   const Int_t    kNp   = 100;
     979           0 :   const Double_t kDr  = fgBMax/Double_t(kNp);
     980             :   Double_t l = 0.;  //  Path length 
     981           0 :   for (Int_t in = 0; in < kNpi; in ++) {
     982             :     Double_t rw = 0.;
     983             :     Double_t w  = 0.;
     984             :     // Interaction point
     985           0 :     Double_t x0, y0;
     986           0 :     fgWAlmond->GetRandom2(x0, y0);
     987             :     // Initial radius
     988           0 :     const Double_t kr0  = TMath::Sqrt(x0*x0 + y0*y0);
     989           0 :     const Int_t    knps = Int_t ((fgBMax - kr0)/kDr) - 1;
     990             :         
     991             :     // Radial steps
     992             :     Double_t r  = 0.;
     993           0 :     for (Int_t i = 0; (i < knps ); i++) {
     994             :       // Transform into target frame
     995           0 :       const Double_t kxx   = x0 + r * TMath::Cos(kphi0) + kb / 2.;
     996           0 :       const Double_t kyy   = y0 + r * TMath::Sin(kphi0);
     997           0 :       const Double_t kphi  = TMath::ATan2(kyy, kxx);
     998           0 :       const Double_t kr1   = TMath::Sqrt(kxx*kxx + kyy*kyy);
     999             :       // Radius in projectile frame
    1000           0 :       const Double_t kr2   = TMath::Sqrt(kr1*kr1 + kb*kb - 2.*kr1*kb*TMath::Cos(kphi)); 
    1001           0 :       const Double_t ky    = fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
    1002             :             
    1003           0 :       rw += ky * r;
    1004           0 :       w  += ky;
    1005           0 :       r  += kDr;
    1006             :     } // steps
    1007             :     // Average over interactions
    1008           0 :     if (!kiopt) {
    1009           0 :       if(w) l += (2. * rw / w);
    1010             :     } else {
    1011           0 :       const Double_t knorm=fgWSta->Eval(1e-4);
    1012           0 :       if(knorm) l+= 2. * rw * kDr / knorm / knorm;
    1013             :     }
    1014           0 :   } // interactions
    1015             :   Double_t ret=0;
    1016           0 :   if (!kiopt) 
    1017           0 :     ret= l / kNpi;
    1018             :   else 
    1019           0 :     ret=TMath::Sqrt( l / kNpi);
    1020           0 :   return ret; //fm
    1021             : }
    1022             : 
    1023             : Double_t AliFastGlauber::CrossSection(Double_t b1, Double_t b2) const
    1024             : {
    1025             :   //
    1026             :   // Return the geometrical cross-section integrated from b1 to b2 
    1027             :   //
    1028           0 :   return fgWSgeo->Integral(b1, b2)*10.; //mbarn
    1029             : }
    1030             : 
    1031             : Double_t AliFastGlauber::HardCrossSection(Double_t b1, Double_t b2) const
    1032             : {
    1033             :   //
    1034             :   // Return the hard cross-section integrated from b1 to b2 
    1035             :   //
    1036           0 :   return fgWSbinary->Integral(b1, b2)*10.; //mbarn
    1037             : }
    1038             : 
    1039             : Double_t AliFastGlauber::FractionOfHardCrossSection(Double_t b1, Double_t b2) const
    1040             : {
    1041             :   //
    1042             :   // Return fraction of hard cross-section integrated from b1 to b2 
    1043             :   //
    1044           0 :   return fgWSbinary->Integral(b1, b2)/fgWSbinary->Integral(0., 100.);
    1045             : }
    1046             : 
    1047             : Double_t AliFastGlauber::NHard(const Double_t b1, const Double_t b2) const
    1048             : {
    1049             :   //
    1050             :   //  Number of binary hard collisions 
    1051             :   //  as a function of b (nucl/ex/0302016 eq. 19)
    1052             :   //
    1053           0 :   const Double_t kshard=HardCrossSection(b1,b2);
    1054           0 :   const Double_t ksgeo=CrossSection(b1,b2); 
    1055           0 :   if(ksgeo>0)
    1056           0 :     return kshard/ksgeo;
    1057           0 :   else return -1; 
    1058           0 : }
    1059             : 
    1060             : Double_t AliFastGlauber::Binaries(Double_t b) const
    1061             : {
    1062             :   //
    1063             :   // Return number of binary hard collisions normalized to 1 at b=0
    1064             :   //
    1065           0 :   if(b < 1.e-4) b = 1e-4;
    1066           0 :   return fgWSN->Eval(b)/fgWSN->Eval(1e-4);
    1067             : }
    1068             : 
    1069             : Double_t AliFastGlauber::MeanOverlap(Double_t b1, Double_t b2)
    1070             : {
    1071             : //
    1072             : // Calculate the mean overlap for impact parameter range b1 .. b2
    1073             : //
    1074             :     Double_t sum  = 0.;
    1075             :     Double_t sumc = 0.;
    1076             :     Double_t b    = b1;
    1077             :     
    1078           0 :     while (b < b2-0.005) {
    1079           0 :         Double_t  nc = GetNumberOfCollisions(b);
    1080           0 :         sum  += 10. * fgWStaa->Eval(b) * fgWSgeo->Eval(b) * 0.01 / (1. - TMath::Exp(-nc));
    1081           0 :         sumc += 10. * fgWSgeo->Eval(b) * 0.01;
    1082           0 :         b += 0.01;
    1083             :     }
    1084           0 :     return (sum / CrossSection(b1, b2));
    1085             : }
    1086             : 
    1087             : 
    1088             : Double_t AliFastGlauber::MeanNumberOfCollisionsPerEvent(Double_t b1, Double_t b2)
    1089             : {
    1090             : //
    1091             : // Calculate the mean number of collisions per event for impact parameter range b1 .. b2
    1092             : //
    1093             :     Double_t sum  = 0.;
    1094             :     Double_t sumc = 0.;
    1095             :     Double_t b    = b1;
    1096             :     
    1097           0 :     while (b < b2-0.005) {
    1098           0 :         Double_t  nc = GetNumberOfCollisions(b);
    1099           0 :         sum  += nc / (1. - TMath::Exp(-nc)) * 10. * fgWSgeo->Eval(b) * 0.01;
    1100           0 :         sumc += 10. * fgWSgeo->Eval(b) * 0.01;
    1101           0 :         b += 0.01;
    1102             :     }
    1103           0 :     return (sum / CrossSection(b1, b2));
    1104             : }
    1105             : 
    1106             : 
    1107             : Double_t AliFastGlauber::GetNumberOfBinaries(Double_t b) const
    1108             : {
    1109             :   //
    1110             :   // Return number of binary hard collisions at b
    1111             :   //
    1112           0 :   if(b<1.e-4) b=1e-4;
    1113           0 :   return fgWSN->Eval(b);
    1114             : }
    1115             : 
    1116             : Double_t AliFastGlauber::Participants(Double_t  b) const
    1117             : {
    1118             :   //
    1119             :   // Return the number of participants normalized to 1 at b=0
    1120             :   //
    1121           0 :   if(b<1.e-4) b=1e-4;
    1122           0 :   return (fgWParticipants->Eval(b)/fgWParticipants->Eval(1e-4));
    1123             : }
    1124             : 
    1125             : Double_t AliFastGlauber::GetNumberOfParticipants(Double_t  b) const
    1126             : {
    1127             :   //
    1128             :   // Return the number of participants for impact parameter b
    1129             :   //
    1130           0 :   if(b<1.e-4) b=1e-4;
    1131           0 :   return (fgWParticipants->Eval(b));
    1132             : }
    1133             : 
    1134             : Double_t AliFastGlauber::GetNumberOfCollisions(Double_t  b) const
    1135             : {
    1136             :   //
    1137             :   // Return the number of collisions for impact parameter b
    1138             :   //
    1139           0 :   if(b<1.e-4) b=1e-4;
    1140           0 :   return (fgWStaa->Eval(b)*fSigmaNN);
    1141             : }
    1142             : 
    1143             : Double_t AliFastGlauber::GetNumberOfCollisionsPerEvent(Double_t  b) const
    1144             : {
    1145             :   //
    1146             :   // Return the number of collisions per event (at least one collision)
    1147             :   // for impact parameter b
    1148             :   //
    1149           0 :     Double_t n = GetNumberOfCollisions(b);
    1150           0 :     if (n > 0.) {
    1151           0 :         return (n / (1. - TMath::Exp(- n)));
    1152             :     } else {
    1153           0 :         return (0.);
    1154             :     }
    1155           0 : }
    1156             : 
    1157             : void AliFastGlauber::SimulateTrigger(Int_t n)
    1158             : {
    1159             :   //
    1160             :   //  Simulates Trigger
    1161             :   //
    1162           0 :   TH1F* mbtH = new TH1F("mbtH", "MB Trigger b-Distribution",   100, 0., 20.);
    1163           0 :   TH1F* hdtH = new TH1F("hdtH", "Hard Trigger b-Distribution", 100, 0., 20.);   
    1164           0 :   TH1F* mbmH = new TH1F("mbmH", "MB Trigger Multiplicity Distribution",   100, 0., 8000.);
    1165           0 :   TH1F* hdmH = new TH1F("hdmH", "Hard Trigger Multiplicity Distribution", 100, 0., 8000.);   
    1166             : 
    1167           0 :   mbtH->SetXTitle("b [fm]");
    1168           0 :   hdtH->SetXTitle("b [fm]");    
    1169           0 :   mbmH->SetXTitle("Multiplicity");
    1170           0 :   hdmH->SetXTitle("Multiplicity");    
    1171             : 
    1172           0 :   TCanvas *c0 = new TCanvas("c0","Trigger Simulation",400,10,600,700);    
    1173           0 :   c0->Divide(2,1);
    1174           0 :   TCanvas *c1 = new TCanvas("c1","Trigger Simulation",400,10,600,700);    
    1175           0 :   c1->Divide(1,2);
    1176             : 
    1177             :   //
    1178             :   //
    1179           0 :   Init(1);
    1180           0 :   for (Int_t iev = 0; iev < n; iev++)
    1181             :     {
    1182           0 :       Float_t b, p, mult;
    1183           0 :       GetRandom(b, p, mult);
    1184           0 :       mbtH->Fill(b,1.);
    1185           0 :       hdtH->Fill(b, p);
    1186           0 :       mbmH->Fill(mult, 1.);
    1187           0 :       hdmH->Fill(mult, p);
    1188             : 
    1189           0 :       c0->cd(1);
    1190           0 :       mbtH->Draw();
    1191           0 :       c0->cd(2);
    1192           0 :       hdtH->Draw();  
    1193           0 :       c0->Update();
    1194             : 
    1195           0 :       c1->cd(1);
    1196           0 :       mbmH->Draw();
    1197           0 :       c1->cd(2);
    1198           0 :       hdmH->Draw();  
    1199           0 :       c1->Update();
    1200           0 :     }
    1201           0 : }
    1202             : 
    1203             : void AliFastGlauber::GetRandom(Float_t& b, Float_t& p, Float_t& mult)
    1204             : {
    1205             :   //
    1206             :   // Gives back a random impact parameter, hard trigger probability and multiplicity
    1207             :   //
    1208           0 :   b = fgWSgeo->GetRandom();
    1209           0 :   const Float_t kmu = fgWSN->Eval(b);
    1210           0 :   p = 1.-TMath::Exp(-kmu);
    1211           0 :   mult = 6000./fgWSN->Eval(1.) * kmu;
    1212           0 : }
    1213             : 
    1214             : void AliFastGlauber::GetRandom(Int_t& bin, Bool_t& hard)
    1215             : {
    1216             :   //
    1217             :   // Gives back a random impact parameter bin, and hard trigger decission
    1218             :   //
    1219           0 :   const Float_t kb  = fgWSgeo->GetRandom();
    1220           0 :   const Float_t kmu = fgWSN->Eval(kb) * fSigmaHard;
    1221           0 :   const Float_t kp  = 1.-TMath::Exp(-kmu);
    1222           0 :   if (kb < 5.) {
    1223           0 :     bin = 1;
    1224           0 :   } else if (kb <  8.6) {
    1225           0 :     bin = 2;
    1226           0 :   } else if (kb < 11.2) {
    1227           0 :     bin = 3;
    1228           0 :   } else if (kb < 13.2) {
    1229           0 :     bin = 4;
    1230           0 :   } else if (kb < 15.0) {
    1231           0 :     bin = 5;
    1232           0 :   } else {
    1233           0 :     bin = 6;
    1234             :   }
    1235           0 :   hard = kFALSE;
    1236           0 :   const Float_t kr = gRandom->Rndm();
    1237           0 :   if (kr < kp) hard = kTRUE;
    1238           0 : }
    1239             : 
    1240             : Double_t  AliFastGlauber::GetRandomImpactParameter(Double_t bmin, Double_t bmax)
    1241             : {
    1242             :   //
    1243             :   // Gives back a random impact parameter in the range bmin .. bmax
    1244             :   //
    1245             :   Float_t b = -1.;
    1246           0 :   while(b < bmin || b > bmax)
    1247           0 :     b = fgWSgeo->GetRandom();
    1248           0 :   return b;
    1249             : }
    1250             : 
    1251             : void AliFastGlauber::StoreFunctions() const
    1252             : {
    1253             :   //
    1254             :   // Store in file functions
    1255             :   //
    1256           0 :   TFile* ff = new TFile(fName.Data(),"recreate");
    1257           0 :   fgWStaa->Write("WStaa");
    1258           0 :   fgWParticipants->Write("WParticipants");
    1259           0 :   ff->Close();
    1260             :   return;
    1261           0 : }
    1262             : 
    1263             : //=================== Added by A. Dainese 11/02/04 ===========================
    1264             : 
    1265             : void AliFastGlauber::StoreAlmonds() const
    1266             : {
    1267             :   //
    1268             :   // Store in file 
    1269             :   // 40 almonds for b = (0.25+k*0.5) fm (k=0->39)
    1270             :   //
    1271           0 :   Char_t almondName[100];
    1272           0 :   TFile* ff = new TFile(fName.Data(),"update");
    1273           0 :   for(Int_t k=0; k<40; k++) {
    1274           0 :     snprintf(almondName, 100, "WAlmondFixedB%d",k);
    1275           0 :     Double_t b = 0.25+k*0.5;
    1276           0 :     Info("StoreAlmonds"," b = %f\n",b); 
    1277           0 :     fgWAlmond->SetParameter(0,b);
    1278           0 :     fgWAlmond->Write(almondName);
    1279             :   }
    1280           0 :   ff->Close();
    1281             :   return;
    1282           0 : }
    1283             : 
    1284             : void AliFastGlauber::SetCentralityClass(Double_t xsecFrLow,Double_t xsecFrUp)
    1285             : {
    1286             :   //
    1287             :   // Set limits of centrality class as fractions 
    1288             :   // of the geomtrical cross section  
    1289             :   //
    1290           0 :   if(xsecFrLow>1. || xsecFrUp>1. || xsecFrLow>xsecFrUp) {
    1291           0 :     Error("SetCentralityClass", "Please set 0 <= xsecFrLow <= xsecFrUp <= 1\n");
    1292           0 :     return;
    1293             :   }
    1294             : 
    1295             :   Double_t bLow=0.,bUp=0.;
    1296             :   Double_t xsecFr=0.;
    1297           0 :   const Double_t knorm=fgWSgeo->Integral(0.,100.);
    1298           0 :   while(xsecFr<xsecFrLow) {
    1299           0 :     xsecFr = fgWSgeo->Integral(0.,bLow)/knorm;
    1300           0 :     bLow += 0.1;
    1301             :   }
    1302             :   bUp = bLow;
    1303           0 :   while(xsecFr<xsecFrUp) {
    1304           0 :     xsecFr = fgWSgeo->Integral(0.,bUp)/knorm;
    1305           0 :     bUp += 0.1;
    1306             :   }
    1307             : 
    1308           0 :   Info("SetCentralityClass", "Centrality class: %4.2f-%4.2f; %4.1f < b < %4.1f fm",
    1309             :          xsecFrLow,xsecFrUp,bLow,bUp);
    1310           0 :   fgWSbinary->SetRange(bLow,bUp);
    1311           0 :   fBmin=bLow;
    1312           0 :   fBmax=bUp;
    1313             :   return;
    1314           0 : }
    1315             : 
    1316             : void AliFastGlauber::GetRandomBHard(Double_t& b)
    1317             : {
    1318             :   //
    1319             :   // Get random impact parameter according to distribution of 
    1320             :   // hard (binary) cross-section, in the range defined by the centrality class
    1321             :   //
    1322           0 :   b = fgWSbinary->GetRandom();
    1323           0 :   Int_t bin = 2*(Int_t)b;
    1324           0 :   if( (b-(Int_t)b) > 0.5) bin++;
    1325           0 :   fgWAlmondCurrent = fgWAlmondFixedB[bin]; 
    1326             :   return;
    1327           0 : }
    1328             : 
    1329             : void AliFastGlauber::GetRandomXY(Double_t& x,Double_t& y)
    1330             : {
    1331             :   //
    1332             :   // Get random position of parton production point according to 
    1333             :   // product of thickness functions
    1334             :   //
    1335           0 :   fgWAlmondCurrent->GetRandom2(x,y);
    1336           0 :   return;
    1337             : }
    1338             : 
    1339             : void AliFastGlauber::GetRandomPhi(Double_t& phi) 
    1340             : {
    1341             :   //
    1342             :   // Get random parton azimuthal propagation direction
    1343             :   //
    1344           0 :   phi = 2.*TMath::Pi()*gRandom->Rndm();
    1345           0 :   return;
    1346             : }
    1347             : 
    1348             : Double_t AliFastGlauber::CalculateLength(Double_t b,Double_t x0,Double_t y0,Double_t phi0)
    1349             : {
    1350             :   // 
    1351             :   // Calculate path length for a parton with production point (x0,y0)
    1352             :   // and propagation direction (ux=cos(phi0),uy=sin(phi0)) 
    1353             :   // in a collision with impact parameter b
    1354             :   //
    1355             : 
    1356             :   // number of steps in l
    1357             :   const Int_t    kNp  = 100;
    1358           0 :   const Double_t kDl  = fgBMax/Double_t(kNp);
    1359             : 
    1360           0 :   if(fEllDef==1) {
    1361             :     //
    1362             :     // Definition 1:
    1363             :     // 
    1364             :     // ell = 2 * \int_0^\infty dl*l*(T_A*T_B)(x0+l*ux,y0+l*uy) /
    1365             :     //           \int_0^\infty dl*(T_A*T_B)(x0+l*ux,y0+l*uy)
    1366             :     //
    1367             : 
    1368             :     // Initial radius
    1369           0 :     const Double_t kr0 = TMath::Sqrt(x0*x0 + y0*y0);
    1370           0 :     const Int_t knps = Int_t ((fgBMax - kr0)/kDl) - 1;
    1371             :     Double_t l  = 0.;
    1372             :     Double_t integral1 = 0.;
    1373             :     Double_t integral2 = 0.;
    1374             :     // Radial steps
    1375           0 :     for (Int_t i = 0; i < knps; i++) {
    1376             :       
    1377             :       // Transform into target frame
    1378           0 :       const Double_t kxx   = x0 + l * TMath::Cos(phi0) + b / 2.;
    1379           0 :       const Double_t kyy   = y0 + l * TMath::Sin(phi0);
    1380           0 :       const Double_t kphi  = TMath::ATan2(kyy, kxx);
    1381           0 :       const Double_t kr1   = TMath::Sqrt(kxx*kxx + kyy*kyy);
    1382             :       // Radius in projectile frame
    1383           0 :       const Double_t kr2   = TMath::Sqrt(kr1*kr1 + b*b - 2.*kr1*b*TMath::Cos(kphi)); 
    1384           0 :       const Double_t kprodTATB = fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
    1385             :       
    1386           0 :       integral1 += kprodTATB * l * kDl;
    1387           0 :       integral2 += kprodTATB * kDl;
    1388           0 :       l  += kDl;
    1389             :     } // steps
    1390             :     
    1391             :     Double_t ell=0.;
    1392           0 :     if(integral2)
    1393           0 :       ell = (2. * integral1 / integral2);
    1394             :     return ell;
    1395           0 :   } else if(fEllDef==2) {
    1396             :     //
    1397             :     // Definition 2:
    1398             :     // 
    1399             :     // ell = \int_0^\infty dl*
    1400             :     //       \Theta((T_A*T_B)(x0+l*ux,y0+l*uy)-0.5*(T_A*T_B)(0,0))
    1401             :     //
    1402             : 
    1403             :     // Initial radius
    1404           0 :     const Double_t kr0  = TMath::Sqrt(x0*x0 + y0*y0);
    1405           0 :     const Int_t knps = Int_t ((fgBMax - kr0)/kDl) - 1;
    1406           0 :     const Double_t kprodTATBHalfMax = 0.5*fgWAlmondCurrent->Eval(0.,0.);
    1407             :     // Radial steps
    1408             :     Double_t l  = 0.;
    1409             :     Double_t integral = 0.;
    1410           0 :     for (Int_t i = 0; i < knps; i++) {
    1411             :       // Transform into target frame
    1412           0 :       const Double_t kxx   = x0 + l * TMath::Cos(phi0) + b / 2.;
    1413           0 :       const Double_t kyy   = y0 + l * TMath::Sin(phi0);
    1414           0 :       const Double_t kphi  = TMath::ATan2(kyy, kxx);
    1415           0 :       const Double_t kr1   = TMath::Sqrt(kxx*kxx + kyy*kyy);
    1416             :       // Radius in projectile frame
    1417           0 :       const Double_t kr2   = TMath::Sqrt(kr1*kr1 + b*b - 2.*kr1*b*TMath::Cos(kphi)); 
    1418           0 :       const Double_t kprodTATB = fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
    1419           0 :       if(kprodTATB>kprodTATBHalfMax) integral += kDl;
    1420           0 :       l  += kDl;
    1421             :     } // steps
    1422             :     Double_t ell = integral;
    1423             :     return ell;
    1424             :   } else {
    1425           0 :     Error("CalculateLength","Wrong length definition setting: %d !\n",fEllDef);
    1426           0 :     return -1.;
    1427             :   }
    1428           0 : }
    1429             : 
    1430             : void AliFastGlauber::GetLengthAndPhi(Double_t& ell,Double_t& phi,Double_t b)
    1431             : {
    1432             :   //
    1433             :   // Return length from random b, x0, y0, phi0 
    1434             :   // Return also phi0
    1435             :   //
    1436           0 :   Double_t x0,y0,phi0;
    1437           0 :   if(b<0.) GetRandomBHard(b);
    1438           0 :   GetRandomXY(x0,y0);
    1439           0 :   GetRandomPhi(phi0);
    1440           0 :   phi = phi0;
    1441           0 :   ell = CalculateLength(b,x0,y0,phi0);
    1442             :   return;
    1443           0 : }
    1444             : 
    1445             : void AliFastGlauber::GetLength(Double_t& ell,Double_t b)
    1446             : {
    1447             :   //
    1448             :   // Return length from random b, x0, y0, phi0 
    1449             :   //
    1450           0 :   Double_t phi;
    1451           0 :   GetLengthAndPhi(ell,phi,b);
    1452             :   return;
    1453           0 : }
    1454             : 
    1455             : void AliFastGlauber::GetLengthsBackToBackAndPhi(Double_t& ell1,Double_t& ell2,Double_t &phi,Double_t b)
    1456             : {
    1457             :   //
    1458             :   // Return 2 lengths back to back from random b, x0, y0, phi0 
    1459             :   // Return also phi0 
    1460             :  // 
    1461           0 :   Double_t x0,y0,phi0;
    1462           0 :   if(b<0.) GetRandomBHard(b);
    1463           0 :   GetRandomXY(x0,y0);
    1464           0 :   GetRandomPhi(phi0);
    1465           0 :   const Double_t kphi0plusPi = phi0+TMath::Pi();
    1466           0 :   phi = phi0;
    1467           0 :   ell1 = CalculateLength(b,x0,y0,phi0);
    1468           0 :   ell2 = CalculateLength(b,x0,y0,kphi0plusPi);
    1469             :   return;
    1470           0 : }
    1471             : 
    1472             : void AliFastGlauber::GetLengthsBackToBack(Double_t& ell1,Double_t& ell2,
    1473             :                                           Double_t b)
    1474             : {
    1475             :   //
    1476             :   // Return 2 lengths back to back from random b, x0, y0, phi0 
    1477             :   // 
    1478           0 :   Double_t phi;
    1479           0 :   GetLengthsBackToBackAndPhi(ell1,ell2,phi,b);
    1480             :   return;
    1481           0 : }
    1482             : 
    1483             : void AliFastGlauber::GetLengthsForPythia(Int_t n,Double_t* const phi,Double_t* ell, Double_t b)
    1484             : {
    1485             :   //
    1486             :   // Returns lenghts for n partons with azimuthal angles phi[n] 
    1487             :   // from random b, x0, y0
    1488             :   //
    1489           0 :   Double_t x0, y0;
    1490           0 :   if(b < 0.) GetRandomBHard(b);
    1491           0 :   GetRandomXY(x0,y0);
    1492           0 :   for(Int_t i = 0; i< n; i++) ell[i] = CalculateLength(b,x0,y0,phi[i]);
    1493             :   return;
    1494           0 : }
    1495             : 
    1496             : void AliFastGlauber::PlotBDistr(Int_t n)
    1497             : {  
    1498             :   // 
    1499             :   // Plot distribution of n impact parameters
    1500             :   //
    1501           0 :   Double_t b;
    1502           0 :   TH1F *hB = new TH1F("hB","dN/db",100,0,fgBMax); 
    1503           0 :   hB->SetXTitle("b [fm]");
    1504           0 :   hB->SetYTitle("dN/db [a.u.]");
    1505           0 :   hB->SetFillColor(3);
    1506           0 :   for(Int_t i=0; i<n; i++) {
    1507           0 :     GetRandomBHard(b);
    1508           0 :     hB->Fill(b);
    1509             :   }
    1510           0 :   TCanvas *cB = new TCanvas("cB","Impact parameter distribution",0,0,500,500);
    1511           0 :   cB->cd();
    1512           0 :   hB->Draw();
    1513             :   return;
    1514           0 : }
    1515             : 
    1516             : void AliFastGlauber::PlotLengthDistr(Int_t n,Bool_t save,const char *fname)
    1517             : {
    1518             :   //
    1519             :   // Plot length distribution
    1520             :   //
    1521           0 :   Double_t ell;
    1522           0 :   TH1F *hEll = new TH1F("hEll","Length distribution",64,-0.5,15); 
    1523           0 :   hEll->SetXTitle("Transverse path length, L [fm]");
    1524           0 :   hEll->SetYTitle("Probability");
    1525           0 :   hEll->SetFillColor(2);
    1526           0 :   for(Int_t i=0; i<n; i++) {
    1527           0 :     GetLength(ell);
    1528           0 :     hEll->Fill(ell);
    1529             :   }
    1530           0 :   hEll->Scale(1/(Double_t)n);
    1531           0 :   TCanvas *cL = new TCanvas("cL","Length distribution",0,0,500,500);
    1532           0 :   cL->cd();
    1533           0 :   hEll->Draw();
    1534             : 
    1535           0 :   if(save) {
    1536           0 :     TFile *f = new TFile(fname,"recreate");
    1537           0 :     hEll->Write();
    1538           0 :     f->Close();
    1539           0 :   }
    1540             :   return;
    1541           0 : }
    1542             : 
    1543             : void AliFastGlauber::PlotLengthB2BDistr(Int_t n,Bool_t save,const char *fname)
    1544             : {
    1545             :   //
    1546             :   // Plot lengths back-to-back distributions
    1547             :   //
    1548           0 :   Double_t ell1,ell2;
    1549           0 :   TH2F *hElls = new TH2F("hElls","Lengths back-to-back",100,0,15,100,0,15); 
    1550           0 :   hElls->SetXTitle("Transverse path length, L [fm]");
    1551           0 :   hElls->SetYTitle("Transverse path length, L [fm]");
    1552           0 :   for(Int_t i=0; i<n; i++) {
    1553           0 :     GetLengthsBackToBack(ell1,ell2);
    1554           0 :     hElls->Fill(ell1,ell2);
    1555             :   }
    1556           0 :   hElls->Scale(1/(Double_t)n);
    1557           0 :   TCanvas *cLs = new TCanvas("cLs","Length back-to-back distribution",0,0,500,500);
    1558           0 :   gStyle->SetPalette(1,0);
    1559           0 :   cLs->cd();
    1560           0 :   hElls->Draw("col,Z");
    1561           0 :   if(save) {
    1562           0 :     TFile *f = new TFile(fname,"recreate");
    1563           0 :     hElls->Write();
    1564           0 :     f->Close();
    1565           0 :   }
    1566             :   return;
    1567           0 : }
    1568             : 
    1569             : void AliFastGlauber::PlotAlmonds() const
    1570             : {
    1571             :   //
    1572             :   // Plot almonds for some impact parameters
    1573             :   //
    1574           0 :   TCanvas *c = new TCanvas("c","Almonds",0,0,500,500);
    1575           0 :   gStyle->SetPalette(1,0);
    1576           0 :   c->Divide(2,2);
    1577           0 :   c->cd(1);
    1578           0 :   fgWAlmondFixedB[0]->Draw("cont1");
    1579           0 :   c->cd(2);
    1580           0 :   fgWAlmondFixedB[10]->Draw("cont1");
    1581           0 :   c->cd(3);
    1582           0 :   fgWAlmondFixedB[20]->Draw("cont1");
    1583           0 :   c->cd(4);
    1584           0 :   fgWAlmondFixedB[30]->Draw("cont1");
    1585             :   return;
    1586           0 : }
    1587             : 
    1588             : //=================== Added by A. Dainese 05/03/04 ===========================
    1589             : 
    1590             : void AliFastGlauber::CalculateI0I1(Double_t& integral0,Double_t& integral1,
    1591             :                                    Double_t b,Double_t x0,Double_t y0,
    1592             :                                    Double_t phi0,Double_t ellCut) const
    1593             : {
    1594             :   // 
    1595             :   // Calculate integrals: 
    1596             :   //  integral0 = \int_0^ellCut dl*(T_A*T_B)(x0+l*ux,y0+l*uy)
    1597             :   //  integral1 = \int_0^ellCut dl*l*(T_A*T_B)(x0+l*ux,y0+l*uy)
    1598             :   //
    1599             :   // for a parton with production point (x0,y0)
    1600             :   // and propagation direction (ux=cos(phi0),uy=sin(phi0)) 
    1601             :   // in a collision with impact parameter b
    1602             :   // 
    1603             : 
    1604             :   // number of steps in l
    1605             :   const Int_t    kNp  = 100;
    1606           0 :   const Double_t kDl  = fgBMax/Double_t(kNp);
    1607             :     
    1608             :   // Initial radius
    1609           0 :   const Double_t kr0  = TMath::Sqrt(x0 * x0 + y0 * y0);
    1610           0 :   const Int_t knps = Int_t ((fgBMax - kr0)/kDl) - 1;
    1611             :     
    1612             :   // Radial steps
    1613             :   Double_t l  = 0.;
    1614           0 :   integral0 = 0.;
    1615           0 :   integral1 = 0.;
    1616             :   Int_t i = 0;
    1617           0 :   while((i < knps) && (l < ellCut)) {
    1618             :     // Transform into target frame
    1619           0 :     const Double_t kxx   = x0 + l * TMath::Cos(phi0) + b / 2.;
    1620           0 :     const Double_t kyy   = y0 + l * TMath::Sin(phi0);
    1621           0 :     const Double_t kphi  = TMath::ATan2(kyy, kxx);
    1622           0 :     const Double_t kr1   = TMath::Sqrt(kxx*kxx + kyy*kyy);
    1623             :     // Radius in projectile frame
    1624           0 :     const Double_t kr2   = TMath::Sqrt(kr1*kr1 + b*b - 2.*kr1*b*TMath::Cos(kphi)); 
    1625           0 :     const Double_t kprodTATB = fgWSta->Eval(kr1) * fgWSta->Eval(kr2);
    1626           0 :     integral0 += kprodTATB * kDl;
    1627           0 :     integral1 += kprodTATB * l * kDl;
    1628           0 :     l  += kDl;
    1629           0 :     i++;
    1630             :   } // steps
    1631             :   return;  
    1632           0 : }
    1633             : 
    1634             : void AliFastGlauber::GetI0I1AndPhi(Double_t& integral0,Double_t& integral1,
    1635             :                                    Double_t& phi,
    1636             :                                    Double_t ellCut,Double_t b)
    1637             : {
    1638             :   //
    1639             :   // Return I0 and I1 from random b, x0, y0, phi0 
    1640             :   // Return also phi
    1641             :   //
    1642           0 :   Double_t x0,y0,phi0;
    1643           0 :   if(b<0.) GetRandomBHard(b);
    1644           0 :   GetRandomXY(x0,y0);
    1645           0 :   GetRandomPhi(phi0);
    1646           0 :   phi = phi0;
    1647           0 :   CalculateI0I1(integral0,integral1,b,x0,y0,phi0,ellCut);
    1648             :   return;
    1649           0 : }
    1650             : 
    1651             : void AliFastGlauber::GetI0I1(Double_t& integral0,Double_t& integral1,
    1652             :                              Double_t ellCut,Double_t b)
    1653             : {
    1654             :   //
    1655             :   // Return I0 and I1 from random b, x0, y0, phi0 
    1656             :   //
    1657           0 :   Double_t phi;
    1658           0 :   GetI0I1AndPhi(integral0,integral1,phi,ellCut,b);
    1659             :   return;
    1660           0 : }
    1661             : 
    1662             : void AliFastGlauber::GetI0I1BackToBackAndPhi(Double_t& integral01,Double_t& integral11,
    1663             :                                              Double_t& integral02,Double_t& integral12,
    1664             :                                              Double_t& phi,
    1665             :                                              Double_t ellCut,Double_t b)
    1666             : {
    1667             :   //
    1668             :   // Return 2 pairs of I0 and I1 back to back from random b, x0, y0, phi0 
    1669             :   // Return also phi0
    1670             :   //
    1671           0 :   Double_t x0,y0,phi0;
    1672           0 :   if(b<0.) GetRandomBHard(b);
    1673           0 :   GetRandomXY(x0,y0);
    1674           0 :   GetRandomPhi(phi0);
    1675           0 :   phi = phi0;
    1676           0 :   const Double_t kphi0plusPi = phi0+TMath::Pi();
    1677           0 :   CalculateI0I1(integral01,integral11,b,x0,y0,phi0,ellCut);
    1678           0 :   CalculateI0I1(integral02,integral12,b,x0,y0,kphi0plusPi,ellCut);
    1679             :   return;
    1680           0 : }
    1681             : 
    1682             : void AliFastGlauber::GetI0I1BackToBackAndPhiAndXY(Double_t& integral01,Double_t& integral11,
    1683             :                                                   Double_t& integral02,Double_t& integral12,
    1684             :                                                   Double_t& phi,Double_t &x,Double_t &y,
    1685             :                                                   Double_t ellCut,Double_t b)
    1686             : {
    1687             :   //
    1688             :   // Return 2 pairs of I0 and I1 back to back from random b, x0, y0, phi0 
    1689             :   // Return also phi0
    1690             :   //
    1691           0 :   Double_t x0,y0,phi0;
    1692           0 :   if(b<0.) GetRandomBHard(b);
    1693           0 :   GetRandomXY(x0,y0);
    1694           0 :   GetRandomPhi(phi0);
    1695           0 :   phi = phi0; x=x0; y=y0;
    1696           0 :   const Double_t kphi0plusPi = phi0+TMath::Pi();
    1697           0 :   CalculateI0I1(integral01,integral11,b,x0,y0,phi0,ellCut);
    1698           0 :   CalculateI0I1(integral02,integral12,b,x0,y0,kphi0plusPi,ellCut);
    1699             :   return;
    1700           0 : }
    1701             : 
    1702             : void AliFastGlauber::GetI0I1BackToBack(Double_t& integral01,Double_t& integral11,
    1703             :                                        Double_t& integral02,Double_t& integral12,
    1704             :                                        Double_t ellCut,Double_t b)
    1705             : {
    1706             :   //
    1707             :   // Return 2 pairs of I0 and I1 back to back from random b, x0, y0, phi0 
    1708             :   //
    1709           0 :   Double_t phi;
    1710           0 :   GetI0I1BackToBackAndPhi(integral01,integral11,integral02,integral12,
    1711             :                           phi,ellCut,b);
    1712             :   return;
    1713           0 : }
    1714             : 
    1715             : void AliFastGlauber::GetI0I1ForPythia(Int_t n,Double_t* phi,
    1716             :                                       Double_t* integral0,Double_t* integral1,
    1717             :                                       Double_t ellCut,Double_t b)
    1718             : {
    1719             :   //
    1720             :   // Returns I0 and I1 pairs for n partons with azimuthal angles phi[n] 
    1721             :   // from random b, x0, y0
    1722             :   //
    1723           0 :   Double_t x0,y0;
    1724           0 :   if(b<0.) GetRandomBHard(b);
    1725           0 :   GetRandomXY(x0,y0);
    1726           0 :   for(Int_t i=0; i<n; i++) 
    1727           0 :     CalculateI0I1(integral0[i],integral1[i],b,x0,y0,phi[i],ellCut);
    1728             :   return;
    1729           0 : }
    1730             : 
    1731             : void AliFastGlauber::GetI0I1ForPythiaAndXY(Int_t n,Double_t* phi,
    1732             :                                       Double_t* integral0,Double_t* integral1,
    1733             :                                       Double_t &x,Double_t& y,
    1734             :                                       Double_t ellCut,Double_t b)
    1735             : {
    1736             :   //
    1737             :   // Returns I0 and I1 pairs for n partons with azimuthal angles phi[n] 
    1738             :   // from random b, x0, y0 and return x0,y0
    1739             :   //
    1740           0 :   Double_t x0,y0;
    1741           0 :   if(b<0.) GetRandomBHard(b);
    1742           0 :   GetRandomXY(x0,y0);
    1743           0 :   for(Int_t i=0; i<n; i++) 
    1744           0 :     CalculateI0I1(integral0[i],integral1[i],b,x0,y0,phi[i],ellCut);
    1745           0 :   x=x0;
    1746           0 :   y=y0;
    1747             :   return;
    1748           0 : }
    1749             : 
    1750             : void AliFastGlauber::PlotI0I1Distr(Int_t n,Double_t ellCut,
    1751             :                                    Bool_t save,const char *fname)
    1752             : {
    1753             :   //
    1754             :   // Plot I0-I1 distribution
    1755             :   //
    1756           0 :   Double_t i0,i1;
    1757           0 :   TH2F *hI0I1s = new TH2F("hI0I1s","I_{0} versus I_{1}",1000,0,0.001,1000,0,0.01); 
    1758           0 :   hI0I1s->SetXTitle("I_{0} [fm^{-3}]");
    1759           0 :   hI0I1s->SetYTitle("I_{1} [fm^{-2}]");
    1760             : 
    1761           0 :   TH1F *hI0 = new TH1F("hI0","I_{0} = #hat{q}L / k",
    1762             :                        1000,0,0.001); 
    1763           0 :   hI0->SetXTitle("I_{0} [fm^{-3}]");
    1764           0 :   hI0->SetYTitle("Probability");
    1765           0 :   hI0->SetFillColor(3);
    1766           0 :   TH1F *hI1 = new TH1F("hI1","I_{1} = #omega_{c} / k",
    1767             :                        1000,0,0.01); 
    1768           0 :   hI1->SetXTitle("I_{1} [fm^{-2}]");
    1769           0 :   hI1->SetYTitle("Probability");
    1770           0 :   hI1->SetFillColor(4);
    1771           0 :   TH1F *h2 = new TH1F("h2","2 I_{1}^{2}/I_{0} = R / k",
    1772             :                       100,0,0.02); 
    1773           0 :   h2->SetXTitle("2 I_{1}^{2}/I_{0} [fm^{-1}]");
    1774           0 :   h2->SetYTitle("Probability");
    1775           0 :   h2->SetFillColor(2);
    1776           0 :   TH1F *h3 = new TH1F("h3","2 I_{1}/I_{0} = L",
    1777             :                       100,0,15); 
    1778           0 :   h3->SetXTitle("2 I_{1}/I_{0} [fm]");
    1779           0 :   h3->SetYTitle("Probability");
    1780           0 :   h3->SetFillColor(5);
    1781           0 :   TH1F *h4 = new TH1F("h4","I_{0}^{2}/(2 I_{1}) = #hat{q} / k",
    1782             :                       100,0,0.00015); 
    1783           0 :   h4->SetXTitle("I_{0}^{2}/(2 I_{1}) [fm^{-4}]");
    1784           0 :   h4->SetYTitle("Probability");
    1785           0 :   h4->SetFillColor(7);
    1786             : 
    1787           0 :   for(Int_t i=0; i<n; i++) {
    1788           0 :     GetI0I1(i0,i1,ellCut);
    1789           0 :     hI0I1s->Fill(i0,i1);
    1790           0 :     hI0->Fill(i0);
    1791           0 :     hI1->Fill(i1);
    1792           0 :     h2->Fill(2.*i1*i1/i0);
    1793           0 :     h3->Fill(2.*i1/i0);
    1794           0 :     h4->Fill(i0*i0/2./i1);
    1795             :   }
    1796           0 :   hI0->Scale(1/(Double_t)n);
    1797           0 :   hI1->Scale(1/(Double_t)n);
    1798           0 :   h2->Scale(1/(Double_t)n);
    1799           0 :   h3->Scale(1/(Double_t)n);
    1800           0 :   h4->Scale(1/(Double_t)n);
    1801           0 :   hI0I1s->Scale(1/(Double_t)n);
    1802             : 
    1803           0 :   TCanvas *cI0I1 = new TCanvas("cI0I1","I0 and I1",0,0,900,700);
    1804           0 :   cI0I1->Divide(3,2);
    1805           0 :   cI0I1->cd(1);
    1806           0 :   hI0->Draw();
    1807           0 :   cI0I1->cd(2);
    1808           0 :   hI1->Draw();
    1809           0 :   cI0I1->cd(3);
    1810           0 :   h2->Draw();
    1811           0 :   cI0I1->cd(4);
    1812           0 :   h3->Draw();
    1813           0 :   cI0I1->cd(5);
    1814           0 :   h4->Draw();
    1815           0 :   cI0I1->cd(6);
    1816           0 :   gStyle->SetPalette(1,0);
    1817           0 :   hI0I1s->Draw("col,Z");
    1818             : 
    1819           0 :   if(save) {
    1820           0 :     TFile *f = new TFile(fname,"recreate");
    1821           0 :     hI0I1s->Write();
    1822           0 :     hI0->Write();
    1823           0 :     hI1->Write();
    1824           0 :     h2->Write();
    1825           0 :     h3->Write();
    1826           0 :     h4->Write();
    1827           0 :     f->Close();
    1828           0 :   }
    1829             :   return;
    1830           0 : }
    1831             : 
    1832             : void AliFastGlauber::PlotI0I1B2BDistr(Int_t n,Double_t ellCut,
    1833             :                                       Bool_t save,const char *fname)
    1834             : {
    1835             :   //
    1836             :   // Plot I0-I1 back-to-back distributions
    1837             :   //
    1838           0 :   Double_t i01,i11,i02,i12;
    1839           0 :   TH2F *hI0s = new TH2F("hI0s","I_{0}'s back-to-back",100,0,100,100,0,100); 
    1840           0 :   hI0s->SetXTitle("I_{0} [fm^{-3}]");
    1841           0 :   hI0s->SetYTitle("I_{0} [fm^{-3}]");
    1842           0 :   TH2F *hI1s = new TH2F("hI1s","I_{1}'s back-to-back",100,0,100,100,0,100); 
    1843           0 :   hI1s->SetXTitle("I_{1} [fm^{-2}]");
    1844           0 :   hI1s->SetYTitle("I_{1} [fm^{-2}]");
    1845             : 
    1846           0 :   for(Int_t i=0; i<n; i++) {
    1847           0 :     GetI0I1BackToBack(i01,i11,i02,i12,ellCut);
    1848           0 :     hI0s->Fill(i01,i02);
    1849           0 :     hI1s->Fill(i11,i12);
    1850             :   }
    1851           0 :   hI0s->Scale(1/(Double_t)n);
    1852           0 :   hI1s->Scale(1/(Double_t)n);
    1853             : 
    1854           0 :   TCanvas *cI0I1s = new TCanvas("cI0I1s","I0 and I1 back-to-back distributions",0,0,800,400);
    1855           0 :   gStyle->SetPalette(1,0);
    1856           0 :   cI0I1s->Divide(2,1);
    1857           0 :   cI0I1s->cd(1);
    1858           0 :   hI0s->Draw("col,Z");
    1859           0 :   cI0I1s->cd(2);
    1860           0 :   hI1s->Draw("col,Z");
    1861             : 
    1862           0 :   if(save) {
    1863           0 :     TFile *f = new TFile(fname,"recreate");
    1864           0 :     hI0s->Write();
    1865           0 :     hI1s->Write();
    1866           0 :     f->Close();
    1867           0 :   }
    1868             :   return;
    1869           0 : }
    1870             : 
    1871             : AliFastGlauber& AliFastGlauber::operator=(const  AliFastGlauber& rhs)
    1872             : {
    1873             : // Assignment operator
    1874           0 :     rhs.Copy(*this);
    1875           0 :     return *this;
    1876             : }
    1877             : 
    1878             : void AliFastGlauber::Copy(TObject&) const
    1879             : {
    1880             :     //
    1881             :     // Copy 
    1882             :     //
    1883           0 :     Fatal("Copy","Not implemented!\n");
    1884           0 : }
    1885             : 

Generated by: LCOV version 1.11