1 /**************************************************************************
2 * Author: Panos Christakoglou. *
3 * Contributors are mentioned in the code where appropriate. *
5 * Permission to use, copy, modify and distribute this software and its *
6 * documentation strictly for non-commercial purposes is hereby granted *
7 * without fee, provided that the above copyright notice appears in all *
8 * copies and that both the copyright notice and this permission notice *
9 * appear in the supporting documentation. The authors make no claims *
10 * about the suitability of this software for any purpose. It is *
11 * provided "as is" without express or implied warranty. *
12 **************************************************************************/
14 //-----------------------------------------------------------------
15 // Balance Function class
16 // This is the class to deal with the Balance Function analysis
17 // Origin: Panos Christakoglou, UOA-CERN, Panos.Christakoglou@cern.ch
18 // Modified: Michael Weber, m.weber@cern.ch
19 //-----------------------------------------------------------------
23 #include <Riostream.h>
27 #include <TLorentzVector.h>
28 #include <TObjArray.h>
29 #include <TGraphErrors.h>
32 #include "AliVParticle.h"
33 #include "AliMCParticle.h"
34 #include "AliESDtrack.h"
35 #include "AliAODTrack.h"
37 #include "AliBalance.h"
38 #include "AliBalanceEventMixing.h"
44 ClassImp(AliBalanceEventMixing)
46 //____________________________________________________________________//
47 AliBalanceEventMixing::AliBalanceEventMixing() :
51 fConversionCut(kFALSE),
52 fAnalysisLevel("ESD"),
58 // Default constructor
60 for(Int_t i = 0; i < ANALYSIS_TYPES; i++){
62 fNumberOfBins[i] = 180;
70 fNumberOfBins[i] = 20;
76 fP2Step[i] = TMath::Abs(fP2Start - fP2Stop) / (Double_t)fNumberOfBins[i];
83 for(Int_t j = 0; j < MAXIMUM_NUMBER_OF_STEPS; j++) {
103 //____________________________________________________________________//
104 AliBalanceEventMixing::AliBalanceEventMixing(const AliBalanceEventMixing& balance):
105 TObject(balance), fShuffle(balance.fShuffle),
106 fHBTcut(balance.fHBTcut),
107 fConversionCut(balance.fConversionCut),
108 fAnalysisLevel(balance.fAnalysisLevel),
109 fAnalyzedEvents(balance.fAnalyzedEvents),
110 fCentralityId(balance.fCentralityId),
111 fCentStart(balance.fCentStart),
112 fCentStop(balance.fCentStop) {
114 for(Int_t i = 0; i < ANALYSIS_TYPES; i++){
115 fNn[i] = balance.fNn[i];
116 fNp[i] = balance.fNp[i];
118 fP1Start[i] = balance.fP1Start[i];
119 fP1Stop[i] = balance.fP1Stop[i];
120 fNumberOfBins[i] = balance.fNumberOfBins[i];
121 fP2Start[i] = balance.fP2Start[i];
122 fP2Stop[i] = balance.fP2Stop[i];
123 fP2Step[i] = balance.fP2Step[i];
124 fCentStart = balance.fCentStart;
125 fCentStop = balance.fCentStop;
127 fHistP[i] = balance.fHistP[i];
128 fHistN[i] = balance.fHistN[i];
129 fHistPN[i] = balance.fHistPN[i];
130 fHistNP[i] = balance.fHistNP[i];
131 fHistPP[i] = balance.fHistPP[i];
132 fHistNN[i] = balance.fHistNN[i];
134 for(Int_t j = 0; j < MAXIMUM_NUMBER_OF_STEPS; j++) {
146 //____________________________________________________________________//
147 AliBalanceEventMixing::~AliBalanceEventMixing() {
150 for(Int_t i = 0; i < ANALYSIS_TYPES; i++){
162 //____________________________________________________________________//
163 void AliBalanceEventMixing::SetInterval(Int_t iAnalysisType,
164 Double_t p1Start, Double_t p1Stop,
165 Int_t ibins, Double_t p2Start, Double_t p2Stop) {
166 // Sets the analyzed interval.
167 // Set the same Information for all analyses
169 if(iAnalysisType == -1){
170 for(Int_t i = 0; i < ANALYSIS_TYPES; i++){
171 fP1Start[i] = p1Start;
173 fNumberOfBins[i] = ibins;
174 fP2Start[i] = p2Start;
176 fP2Step[i] = TMath::Abs(p2Start - p2Stop) / (Double_t)fNumberOfBins[i];
179 // Set the Information for one analysis
180 else if((iAnalysisType > -1) && (iAnalysisType < ANALYSIS_TYPES)) {
181 fP1Start[iAnalysisType] = p1Start;
182 fP1Stop[iAnalysisType] = p1Stop;
183 fNumberOfBins[iAnalysisType] = ibins;
184 fP2Start[iAnalysisType] = p2Start;
185 fP2Stop[iAnalysisType] = p2Stop;
186 fP2Step[iAnalysisType] = TMath::Abs(p2Start - p2Stop) / (Double_t)fNumberOfBins[iAnalysisType];
189 AliError("Wrong ANALYSIS number!");
193 //____________________________________________________________________//
194 void AliBalanceEventMixing::InitHistograms() {
195 //Initialize the histograms
197 // global switch disabling the reference
198 // (to avoid "Replacing existing TH1" if several wagons are created in train)
199 Bool_t oldStatus = TH1::AddDirectoryStatus();
200 TH1::AddDirectory(kFALSE);
203 for(Int_t iAnalysisType = 0; iAnalysisType < ANALYSIS_TYPES; iAnalysisType++) {
204 histName = "fHistP"; histName += kBFAnalysisType[iAnalysisType];
205 if(fShuffle) histName.Append("_shuffle");
206 if(fCentralityId) histName += fCentralityId.Data();
207 fHistP[iAnalysisType] = new TH2D(histName.Data(),"",fCentStop-fCentStart,fCentStart,fCentStop,100,fP1Start[iAnalysisType],fP1Stop[iAnalysisType]);
209 histName = "fHistN"; histName += kBFAnalysisType[iAnalysisType];
210 if(fShuffle) histName.Append("_shuffle");
211 if(fCentralityId) histName += fCentralityId.Data();
212 fHistN[iAnalysisType] = new TH2D(histName.Data(),"",fCentStop-fCentStart,fCentStart,fCentStop,100,fP1Start[iAnalysisType],fP1Stop[iAnalysisType]);
214 histName = "fHistPN"; histName += kBFAnalysisType[iAnalysisType];
215 if(fShuffle) histName.Append("_shuffle");
216 if(fCentralityId) histName += fCentralityId.Data();
217 fHistPN[iAnalysisType] = new TH2D(histName.Data(),"",fCentStop-fCentStart,fCentStart,fCentStop,fNumberOfBins[iAnalysisType],fP2Start[iAnalysisType],fP2Stop[iAnalysisType]);
219 histName = "fHistNP"; histName += kBFAnalysisType[iAnalysisType];
220 if(fShuffle) histName.Append("_shuffle");
221 if(fCentralityId) histName += fCentralityId.Data();
222 fHistNP[iAnalysisType] = new TH2D(histName.Data(),"",fCentStop-fCentStart,fCentStart,fCentStop,fNumberOfBins[iAnalysisType],fP2Start[iAnalysisType],fP2Stop[iAnalysisType]);
224 histName = "fHistPP"; histName += kBFAnalysisType[iAnalysisType];
225 if(fShuffle) histName.Append("_shuffle");
226 if(fCentralityId) histName += fCentralityId.Data();
227 fHistPP[iAnalysisType] = new TH2D(histName.Data(),"",fCentStop-fCentStart,fCentStart,fCentStop,fNumberOfBins[iAnalysisType],fP2Start[iAnalysisType],fP2Stop[iAnalysisType]);
229 histName = "fHistNN"; histName += kBFAnalysisType[iAnalysisType];
230 if(fShuffle) histName.Append("_shuffle");
231 if(fCentralityId) histName += fCentralityId.Data();
232 fHistNN[iAnalysisType] = new TH2D(histName.Data(),"",fCentStop-fCentStart,fCentStart,fCentStop,fNumberOfBins[iAnalysisType],fP2Start[iAnalysisType],fP2Stop[iAnalysisType]);
235 TH1::AddDirectory(oldStatus);
239 //____________________________________________________________________//
240 void AliBalanceEventMixing::PrintAnalysisSettings() {
241 //prints the analysis settings
243 Printf("======================================");
244 Printf("Analysis level: %s",fAnalysisLevel.Data());
245 Printf("======================================");
246 for(Int_t ibin = 0; ibin < ANALYSIS_TYPES; ibin++){
247 Printf("Interval info for variable %d",ibin);
248 Printf("Analyzed interval (min.): %lf",fP2Start[ibin]);
249 Printf("Analyzed interval (max.): %lf",fP2Stop[ibin]);
250 Printf("Number of bins: %d",fNumberOfBins[ibin]);
251 Printf("Step: %lf",fP2Step[ibin]);
254 Printf("======================================");
257 //____________________________________________________________________//
258 void AliBalanceEventMixing::CalculateBalance(Float_t fCentrality,vector<Double_t> **chargeVector,Int_t iMainTrack,Float_t bSign) {
259 // Calculates the balance function
260 // For the event mixing only for all combinations of the first track (main event) with all other tracks (mix event)
265 // Initialize histograms if not done yet
267 AliWarning("Histograms not yet initialized! --> Will be done now");
268 AliWarning("This works only in local mode --> Add 'gBalance->InitHistograms()' in your configBalanceFunction");
272 Int_t gNtrack = chargeVector[0]->size();
273 //Printf("(AliBalanceEventMixing) Number of tracks: %d",gNtrack);
275 for(i = 0; i < gNtrack;i++){
277 // for event mixing: only store the track from the main event
282 Short_t charge = chargeVector[0]->at(i);
283 Double_t rapidity = chargeVector[1]->at(i);
284 Double_t pseudorapidity = chargeVector[2]->at(i);
285 Double_t phi = chargeVector[3]->at(i);
287 //0:y - 1:eta - 2:Qlong - 3:Qout - 4:Qside - 5:Qinv - 6:phi
288 for(Int_t iAnalysisType = 0; iAnalysisType < ANALYSIS_TYPES; iAnalysisType++) {
289 if(iAnalysisType == kEta) {
290 if((pseudorapidity >= fP1Start[iAnalysisType]) && (pseudorapidity <= fP1Stop[iAnalysisType])) {
292 fNp[iAnalysisType] += 1.;
293 fHistP[iAnalysisType]->Fill(fCentrality,pseudorapidity);
296 fNn[iAnalysisType] += 1.;
297 fHistN[iAnalysisType]->Fill(fCentrality,pseudorapidity);
300 }//analysis type: eta
301 else if(iAnalysisType == kPhi) {
302 if((phi >= fP1Start[iAnalysisType]) && (phi <= fP1Stop[iAnalysisType])) {
304 fNp[iAnalysisType] += 1.;
305 fHistP[iAnalysisType]->Fill(fCentrality,phi);
308 fNn[iAnalysisType] += 1.;
309 fHistN[iAnalysisType]->Fill(fCentrality,phi);
312 }//analysis type: phi
314 if((rapidity >= fP1Start[iAnalysisType]) && (rapidity <= fP1Stop[iAnalysisType])) {
316 fNp[iAnalysisType] += 1.;
317 fHistP[iAnalysisType]->Fill(fCentrality,rapidity);
320 fNn[iAnalysisType] += 1.;
321 fHistN[iAnalysisType]->Fill(fCentrality,rapidity);
324 }//analysis type: y, qside, qout, qlong, qinv
325 }//analysis type loop
328 //Printf("Np: %lf - Nn: %lf",fNp[0],fNn[0]);
330 Double_t dy = 0., deta = 0.;
331 Double_t qLong = 0., qOut = 0., qSide = 0., qInv = 0.;
335 Double_t eta1 = 0., rap1 = 0.;
336 Double_t px1 = 0., py1 = 0., pz1 = 0.;
338 Double_t energy1 = 0.;
342 Double_t eta2 = 0., rap2 = 0.;
343 Double_t px2 = 0., py2 = 0., pz2 = 0.;
345 Double_t energy2 = 0.;
347 //0:y - 1:eta - 2:Qlong - 3:Qout - 4:Qside - 5:Qinv - 6:phi
348 for(i = 1; i < gNtrack; i++) {
350 charge1 = chargeVector[0]->at(i);
351 rap1 = chargeVector[1]->at(i);
352 eta1 = chargeVector[2]->at(i);
353 phi1 = chargeVector[3]->at(i);
354 px1 = chargeVector[4]->at(i);
355 py1 = chargeVector[5]->at(i);
356 pz1 = chargeVector[6]->at(i);
357 pt1 = chargeVector[7]->at(i);
358 energy1 = chargeVector[8]->at(i);
360 for(j = 0; j < i; j++) {
362 // for event mixing: only store the track from the main event
367 charge2 = chargeVector[0]->at(j);
368 rap2 = chargeVector[1]->at(j);
369 eta2 = chargeVector[2]->at(j);
370 phi2 = chargeVector[3]->at(j);
371 px2 = chargeVector[4]->at(j);
372 py2 = chargeVector[5]->at(j);
373 pz2 = chargeVector[6]->at(j);
374 pt2 = chargeVector[7]->at(j);
375 energy2 = chargeVector[8]->at(j);
377 // filling the arrays
380 dy = TMath::Abs(rap1 - rap2);
383 deta = TMath::Abs(eta1 - eta2);
386 Double_t eTot = energy1 + energy2;
387 Double_t pxTot = px1 + px2;
388 Double_t pyTot = py1 + py2;
389 Double_t pzTot = pz1 + pz2;
390 Double_t q0Tot = energy1 - energy2;
391 Double_t qxTot = px1 - px2;
392 Double_t qyTot = py1 - py2;
393 Double_t qzTot = pz1 - pz2;
395 Double_t eTot2 = eTot*eTot;
396 Double_t pTot2 = pxTot*pxTot + pyTot*pyTot + pzTot*pzTot;
397 Double_t pzTot2 = pzTot*pzTot;
399 Double_t q0Tot2 = q0Tot*q0Tot;
400 Double_t qTot2 = qxTot*qxTot + qyTot*qyTot + qzTot*qzTot;
402 Double_t snn = eTot2 - pTot2;
403 Double_t ptTot2 = pTot2 - pzTot2 ;
404 Double_t ptTot = TMath::Sqrt( ptTot2 );
406 qLong = TMath::Abs(eTot*qzTot - pzTot*q0Tot)/TMath::Sqrt(snn + ptTot2);
409 qOut = TMath::Sqrt(snn/(snn + ptTot2)) * TMath::Abs(pxTot*qxTot + pyTot*qyTot)/ptTot;
412 qSide = TMath::Abs(pxTot*qyTot - pyTot*qxTot)/ptTot;
415 qInv = TMath::Sqrt(TMath::Abs(-q0Tot2 + qTot2 ));
418 dphi = TMath::Abs(phi1 - phi2);
419 if(dphi>180) dphi = 360 - dphi; //dphi should be between 0 and 180!
422 if(fHBTcut && charge1 * charge2 > 0){
423 //if( dphi < 3 || deta < 0.01 ){ // VERSION 1
426 // VERSION 2 (Taken from DPhiCorrelations)
427 // the variables & cuthave been developed by the HBT group
428 // see e.g. https://indico.cern.ch/materialDisplay.py?contribId=36&sessionId=6&materialId=slides&confId=142700
431 if (TMath::Abs(deta) < 0.02 * 2.5 * 3) //twoTrackEfficiencyCutValue = 0.02 [default for dphicorrelations]
435 Float_t phi1rad = phi1*TMath::DegToRad();
436 Float_t phi2rad = phi2*TMath::DegToRad();
438 // check first boundaries to see if is worth to loop and find the minimum
439 Float_t dphistar1 = GetDPhiStar(phi1rad, pt1, charge1, phi2rad, pt2, charge2, 0.8, bSign);
440 Float_t dphistar2 = GetDPhiStar(phi1rad, pt1, charge1, phi2rad, pt2, charge2, 2.5, bSign);
442 const Float_t kLimit = 0.02 * 3;
444 Float_t dphistarminabs = 1e5;
446 if (TMath::Abs(dphistar1) < kLimit || TMath::Abs(dphistar2) < kLimit || dphistar1 * dphistar2 < 0 )
448 for (Double_t rad=0.8; rad<2.51; rad+=0.01)
450 Float_t dphistar = GetDPhiStar(phi1rad, pt1, charge1, phi2rad, pt2, charge2, rad, bSign);
451 Float_t dphistarabs = TMath::Abs(dphistar);
453 if (dphistarabs < dphistarminabs)
455 dphistarminabs = dphistarabs;
459 if (dphistarminabs < 0.02 && TMath::Abs(deta) < 0.02)
461 //AliInfo(Form("HBT: Removed track pair %d %d with [[%f %f]] %f %f %f | %f %f %d %f %f %d %f", i, j, deta, dphi, dphistarminabs, dphistar1, dphistar2, phi1rad, pt1, charge1, phi2rad, pt2, charge2, bSign));
470 if (charge1 * charge2 < 0)
473 Float_t m0 = 0.510e-3;
474 Float_t tantheta1 = 1e10;
477 Float_t phi1rad = phi1*TMath::DegToRad();
478 Float_t phi2rad = phi2*TMath::DegToRad();
480 if (eta1 < -1e-10 || eta1 > 1e-10)
481 tantheta1 = 2 * TMath::Exp(-eta1) / ( 1 - TMath::Exp(-2*eta1));
483 Float_t tantheta2 = 1e10;
484 if (eta2 < -1e-10 || eta2 > 1e-10)
485 tantheta2 = 2 * TMath::Exp(-eta2) / ( 1 - TMath::Exp(-2*eta2));
487 Float_t e1squ = m0 * m0 + pt1 * pt1 * (1.0 + 1.0 / tantheta1 / tantheta1);
488 Float_t e2squ = m0 * m0 + pt2 * pt2 * (1.0 + 1.0 / tantheta2 / tantheta2);
490 Float_t masssqu = 2 * m0 * m0 + 2 * ( TMath::Sqrt(e1squ * e2squ) - ( pt1 * pt2 * ( TMath::Cos(phi1rad - phi2rad) + 1.0 / tantheta1 / tantheta2 ) ) );
492 if (masssqu < 0.04*0.04){
493 //AliInfo(Form("Conversion: Removed track pair %d %d with [[%f %f] %f %f] %d %d <- %f %f %f %f %f %f ", i, j, deta, dphi, masssqu, charge1, charge2,eta1,eta2,phi1,phi2,pt1,pt2));
499 //0:y - 1:eta - 2:Qlong - 3:Qout - 4:Qside - 5:Qinv - 6:phi
500 if((rap1 >= fP1Start[kRapidity]) && (rap1 <= fP1Stop[kRapidity]) && (rap2 >= fP1Start[kRapidity]) && (rap2 <= fP1Stop[kRapidity])) {
503 if( dy > fP2Start[kRapidity] && dy < fP2Stop[kRapidity]){
504 iBin = Int_t((dy-fP2Start[kRapidity])/fP2Step[kRapidity]);
505 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
507 if((charge1 > 0)&&(charge2 > 0)) {
508 fNpp[kRapidity][iBin] += 1.;
509 fHistPP[kRapidity]->Fill(fCentrality,dy);
511 else if((charge1 < 0)&&(charge2 < 0)) {
512 fNnn[kRapidity][iBin] += 1.;
513 fHistNN[kRapidity]->Fill(fCentrality,dy);
515 else if((charge1 > 0)&&(charge2 < 0)) {
516 fNpn[kRapidity][iBin] += 1.;
517 fHistPN[kRapidity]->Fill(fCentrality,dy);
519 else if((charge1 < 0)&&(charge2 > 0)) {
520 fNpn[kRapidity][iBin] += 1.;
521 fHistPN[kRapidity]->Fill(fCentrality,dy);
528 if((eta1 >= fP1Start[kEta]) && (eta1 <= fP1Stop[kEta]) && (eta2 >= fP1Start[kEta]) && (eta2 <= fP1Stop[kEta])) {
529 if( deta > fP2Start[kEta] && deta < fP2Stop[kEta]){
530 iBin = Int_t((deta-fP2Start[kEta])/fP2Step[kEta]);
531 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
532 if((charge1 > 0)&&(charge2 > 0)) {
533 fNpp[kEta][iBin] += 1.;
534 fHistPP[kEta]->Fill(fCentrality,deta);
536 if((charge1 < 0)&&(charge2 < 0)) {
537 fNnn[kEta][iBin] += 1.;
538 fHistNN[kEta]->Fill(fCentrality,deta);
540 if((charge1 > 0)&&(charge2 < 0)) {
541 fNpn[kEta][iBin] += 1.;
542 fHistPN[kEta]->Fill(fCentrality,deta);
544 if((charge1 < 0)&&(charge2 > 0)) {
545 fNpn[kEta][iBin] += 1.;
546 fHistPN[kEta]->Fill(fCentrality,deta);
552 // Qlong, out, side, inv
553 // Check the p1 intervall for rapidity here (like for single tracks above)
554 if((rap1 >= fP1Start[kRapidity]) && (rap1 <= fP1Stop[kRapidity]) && (rap2 >= fP1Start[kRapidity]) && (rap2 <= fP1Stop[kRapidity])) {
555 if( qLong > fP2Start[kQlong] && qLong < fP2Stop[kQlong]){
556 iBin = Int_t((qLong-fP2Start[kQlong])/fP2Step[kQlong]);
557 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
558 if((charge1 > 0)&&(charge2 > 0)) {
559 fNpp[kQlong][iBin] += 1.;
560 fHistPP[kQlong]->Fill(fCentrality,qLong);
562 if((charge1 < 0)&&(charge2 < 0)) {
563 fNnn[kQlong][iBin] += 1.;
564 fHistNN[kQlong]->Fill(fCentrality,qLong);
566 if((charge1 > 0)&&(charge2 < 0)) {
567 fNpn[kQlong][iBin] += 1.;
568 fHistPN[kQlong]->Fill(fCentrality,qLong);
570 if((charge1 < 0)&&(charge2 > 0)) {
571 fNpn[kQlong][iBin] += 1.;
572 fHistPN[kQlong]->Fill(fCentrality,qLong);
578 if((rap1 >= fP1Start[kRapidity]) && (rap1 <= fP1Stop[kRapidity]) && (rap2 >= fP1Start[kRapidity]) && (rap2 <= fP1Stop[kRapidity])) {
579 if( qOut > fP2Start[kQout] && qOut < fP2Stop[kQout]){
580 iBin = Int_t((qOut-fP2Start[kQout])/fP2Step[kQout]);
581 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
582 if((charge1 > 0)&&(charge2 > 0)) {
583 fNpp[kQout][iBin] += 1.;
584 fHistPP[kQout]->Fill(fCentrality,qOut);
586 if((charge1 < 0)&&(charge2 < 0)) {
587 fNnn[kQout][iBin] += 1.;
588 fHistNN[kQout]->Fill(fCentrality,qOut);
590 if((charge1 > 0)&&(charge2 < 0)) {
591 fNpn[kQout][iBin] += 1.;
592 fHistPN[kQout]->Fill(fCentrality,qOut);
594 if((charge1 < 0)&&(charge2 > 0)) {
595 fNpn[kQout][iBin] += 1.;
596 fHistPN[kQout]->Fill(fCentrality,qOut);
602 if((rap1 >= fP1Start[kRapidity]) && (rap1 <= fP1Stop[kRapidity]) && (rap2 >= fP1Start[kRapidity]) && (rap2 <= fP1Stop[kRapidity])) {
603 if( qSide > fP2Start[kQside] && qSide < fP2Stop[kQside]){
604 iBin = Int_t((qSide-fP2Start[kQside])/fP2Step[kQside]);
605 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
606 if((charge1 > 0)&&(charge2 > 0)) {
607 fNpp[kQside][iBin] += 1.;
608 fHistPP[kQside]->Fill(fCentrality,qSide);
610 if((charge1 < 0)&&(charge2 < 0)) {
611 fNnn[kQside][iBin] += 1.;
612 fHistNN[kQside]->Fill(fCentrality,qSide);
614 if((charge1 > 0)&&(charge2 < 0)) {
615 fNpn[kQside][iBin] += 1.;
616 fHistPN[kQside]->Fill(fCentrality,qSide);
618 if((charge1 < 0)&&(charge2 > 0)) {
619 fNpn[kQside][iBin] += 1.;
620 fHistPN[kQside]->Fill(fCentrality,qSide);
626 if((rap1 >= fP1Start[kRapidity]) && (rap1 <= fP1Stop[kRapidity]) && (rap2 >= fP1Start[kRapidity]) && (rap2 <= fP1Stop[kRapidity])) {
627 if( qInv > fP2Start[kQinv] && qInv < fP2Stop[kQinv]){
628 iBin = Int_t((qInv-fP2Start[kQinv])/fP2Step[kQinv]);
629 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
630 if((charge1 > 0)&&(charge2 > 0)) {
631 fNpp[kQinv][iBin] += 1.;
632 fHistPP[kQinv]->Fill(fCentrality,qInv);
634 if((charge1 < 0)&&(charge2 < 0)) {
635 fNnn[kQinv][iBin] += 1.;
636 fHistNN[kQinv]->Fill(fCentrality,qInv);
638 if((charge1 > 0)&&(charge2 < 0)) {
639 fNpn[kQinv][iBin] += 1.;
640 fHistPN[kQinv]->Fill(fCentrality,qInv);
642 if((charge1 < 0)&&(charge2 > 0)) {
643 fNpn[kQinv][iBin] += 1.;
644 fHistPN[kQinv]->Fill(fCentrality,qInv);
651 if((phi1 >= fP1Start[kPhi]) && (phi1 <= fP1Stop[kPhi]) && (phi2 >= fP1Start[kPhi]) && (phi2 <= fP1Stop[kPhi])) {
652 if( dphi > fP2Start[kPhi] && dphi < fP2Stop[kPhi]){
653 iBin = Int_t((dphi-fP2Start[kPhi])/fP2Step[kPhi]);
654 if(iBin >=0 && iBin < MAXIMUM_NUMBER_OF_STEPS){
655 if((charge1 > 0)&&(charge2 > 0)) {
656 fNpp[kPhi][iBin] += 1.;
657 fHistPP[kPhi]->Fill(fCentrality,dphi);
659 if((charge1 < 0)&&(charge2 < 0)) {
660 fNnn[kPhi][iBin] += 1.;
661 fHistNN[kPhi]->Fill(fCentrality,dphi);
663 if((charge1 > 0)&&(charge2 < 0)) {
664 fNpn[kPhi][iBin] += 1.;
665 fHistPN[kPhi]->Fill(fCentrality,dphi);
667 if((charge1 < 0)&&(charge2 > 0)) {
668 fNpn[kPhi][iBin] += 1.;
669 fHistPN[kPhi]->Fill(fCentrality,dphi);
674 }//end of 2nd particle loop
677 }//end of 1st particle loop
678 //Printf("Number of analyzed events: %i",fAnalyzedEvents);
679 //Printf("DeltaEta NN[0] = %.0f, PP[0] = %.0f, NP[0] = %.0f, PN[0] = %.0f",fNnn[kEta][0],fNpp[kEta][0],fNnp[kEta][0],fNpn[kEta][0]);
683 //____________________________________________________________________//
684 Double_t AliBalanceEventMixing::GetBalance(Int_t iAnalysisType, Int_t p2) {
685 // Returns the value of the balance function in bin p2
686 fB[iAnalysisType][p2] = 0.5*(((fNpn[iAnalysisType][p2] - 2.*fNnn[iAnalysisType][p2])/fNn[iAnalysisType]) + ((fNpn[iAnalysisType][p2] - 2.*fNpp[iAnalysisType][p2])/fNp[iAnalysisType]))/fP2Step[iAnalysisType];
688 return fB[iAnalysisType][p2];
691 //____________________________________________________________________//
692 Double_t AliBalanceEventMixing::GetError(Int_t iAnalysisType, Int_t p2) {
693 // Returns the error on the BF value for bin p2
694 // The errors for fNn and fNp are neglected here (0.1 % of total error)
695 /*ferror[iAnalysisType][p2] = TMath::Sqrt(Double_t(fNpp[iAnalysisType][p2])/(Double_t(fNp[iAnalysisType])*Double_t(fNp[iAnalysisType]))
696 + Double_t(fNnn[iAnalysisType][p2])/(Double_t(fNn[iAnalysisType])*Double_t(fNn[iAnalysisType]))
697 + Double_t(fNpn[iAnalysisType][p2])/(Double_t(fNp[iAnalysisType])*Double_t(fNp[iAnalysisType]))
698 + Double_t(fNnp[iAnalysisType][p2])/(Double_t(fNp[iAnalysisType])*Double_t(fNp[iAnalysisType]))
699 //+ TMath::Power(fNpn[iAnalysisType][p2]-fNpp[iAnalysisType][p2],2)/TMath::Power(Double_t(fNp[iAnalysisType]),3)
700 //+ TMath::Power(fNnp[iAnalysisType][p2]-fNnn[iAnalysisType][p2],2)/TMath::Power(Double_t(fNn[iAnalysisType]),3)
701 ) /fP2Step[iAnalysisType];*/
703 ferror[iAnalysisType][p2] = TMath::Sqrt( Double_t(fNpp[iAnalysisType][p2])/(Double_t(fNp[iAnalysisType])*Double_t(fNp[iAnalysisType])) +
704 Double_t(fNnn[iAnalysisType][p2])/(Double_t(fNn[iAnalysisType])*Double_t(fNn[iAnalysisType])) +
705 Double_t(fNpn[iAnalysisType][p2])*TMath::Power((0.5/Double_t(fNp[iAnalysisType]) + 0.5/Double_t(fNn[iAnalysisType])),2))/fP2Step[iAnalysisType];
707 return ferror[iAnalysisType][p2];
709 //____________________________________________________________________//
710 TGraphErrors *AliBalanceEventMixing::DrawBalance(Int_t iAnalysisType) {
713 Double_t x[MAXIMUM_NUMBER_OF_STEPS];
714 Double_t xer[MAXIMUM_NUMBER_OF_STEPS];
715 Double_t b[MAXIMUM_NUMBER_OF_STEPS];
716 Double_t ber[MAXIMUM_NUMBER_OF_STEPS];
718 if((fNp[iAnalysisType] == 0)||(fNn[iAnalysisType] == 0)) {
719 cerr<<"Couldn't find any particles in the analyzed interval!!!"<<endl;
723 for(Int_t i = 0; i < fNumberOfBins[iAnalysisType]; i++) {
724 b[i] = GetBalance(iAnalysisType,i);
725 ber[i] = GetError(iAnalysisType,i);
726 x[i] = fP2Start[iAnalysisType] + fP2Step[iAnalysisType]*i + fP2Step[iAnalysisType]/2;
730 TGraphErrors *gr = new TGraphErrors(fNumberOfBins[iAnalysisType],x,b,xer,ber);
731 gr->GetXaxis()->SetTitleColor(1);
732 if(iAnalysisType==0) {
733 gr->SetTitle("Balance function B(#Delta y)");
734 gr->GetXaxis()->SetTitle("#Delta y");
735 gr->GetYaxis()->SetTitle("B(#Delta y)");
737 if(iAnalysisType==1) {
738 gr->SetTitle("Balance function B(#Delta #eta)");
739 gr->GetXaxis()->SetTitle("#Delta #eta");
740 gr->GetYaxis()->SetTitle("B(#Delta #eta)");
742 if(iAnalysisType==2) {
743 gr->SetTitle("Balance function B(q_{long})");
744 gr->GetXaxis()->SetTitle("q_{long} (GeV/c)");
745 gr->GetYaxis()->SetTitle("B(q_{long}) ((GeV/c)^{-1})");
747 if(iAnalysisType==3) {
748 gr->SetTitle("Balance function B(q_{out})");
749 gr->GetXaxis()->SetTitle("q_{out} (GeV/c)");
750 gr->GetYaxis()->SetTitle("B(q_{out}) ((GeV/c)^{-1})");
752 if(iAnalysisType==4) {
753 gr->SetTitle("Balance function B(q_{side})");
754 gr->GetXaxis()->SetTitle("q_{side} (GeV/c)");
755 gr->GetYaxis()->SetTitle("B(q_{side}) ((GeV/c)^{-1})");
757 if(iAnalysisType==5) {
758 gr->SetTitle("Balance function B(q_{inv})");
759 gr->GetXaxis()->SetTitle("q_{inv} (GeV/c)");
760 gr->GetYaxis()->SetTitle("B(q_{inv}) ((GeV/c)^{-1})");
762 if(iAnalysisType==6) {
763 gr->SetTitle("Balance function B(#Delta #phi)");
764 gr->GetXaxis()->SetTitle("#Delta #phi");
765 gr->GetYaxis()->SetTitle("B(#Delta #phi)");
771 //____________________________________________________________________//
772 void AliBalanceEventMixing::PrintResults(Int_t iAnalysisType, TH1D *gHistBalance) {
773 //Prints the calculated width of the BF and its error
774 Double_t gSumXi = 0.0, gSumBi = 0.0, gSumBiXi = 0.0;
775 Double_t gSumBiXi2 = 0.0, gSumBi2Xi2 = 0.0;
776 Double_t gSumDeltaBi2 = 0.0, gSumXi2DeltaBi2 = 0.0;
777 Double_t deltaBalP2 = 0.0, integral = 0.0;
778 Double_t deltaErrorNew = 0.0;
780 cout<<"=================================================="<<endl;
781 for(Int_t i = 1; i <= fNumberOfBins[iAnalysisType]; i++) {
782 //cout<<"B: "<<gHistBalance->GetBinContent(i)<<"\t Error: "<<gHistBalance->GetBinError(i)<<"\t bin: "<<gHistBalance->GetBinCenter(i)<<endl;
784 //cout<<"=================================================="<<endl;
785 for(Int_t i = 2; i <= fNumberOfBins[iAnalysisType]; i++) {
786 gSumXi += gHistBalance->GetBinCenter(i);
787 gSumBi += gHistBalance->GetBinContent(i);
788 gSumBiXi += gHistBalance->GetBinContent(i)*gHistBalance->GetBinCenter(i);
789 gSumBiXi2 += gHistBalance->GetBinContent(i)*TMath::Power(gHistBalance->GetBinCenter(i),2);
790 gSumBi2Xi2 += TMath::Power(gHistBalance->GetBinContent(i),2)*TMath::Power(gHistBalance->GetBinCenter(i),2);
791 gSumDeltaBi2 += TMath::Power(gHistBalance->GetBinError(i),2);
792 gSumXi2DeltaBi2 += TMath::Power(gHistBalance->GetBinCenter(i),2) * TMath::Power(gHistBalance->GetBinError(i),2);
794 deltaBalP2 += fP2Step[iAnalysisType]*TMath::Power(gHistBalance->GetBinError(i),2);
795 integral += fP2Step[iAnalysisType]*gHistBalance->GetBinContent(i);
797 for(Int_t i = 1; i < fNumberOfBins[iAnalysisType]; i++)
798 deltaErrorNew += gHistBalance->GetBinError(i)*(gHistBalance->GetBinCenter(i)*gSumBi - gSumBiXi)/TMath::Power(gSumBi,2);
800 Double_t integralError = TMath::Sqrt(deltaBalP2);
802 Double_t delta = gSumBiXi / gSumBi;
803 Double_t deltaError = (gSumBiXi / gSumBi) * TMath::Sqrt(TMath::Power((TMath::Sqrt(gSumXi2DeltaBi2)/gSumBiXi),2) + TMath::Power((gSumDeltaBi2/gSumBi),2) );
804 cout<<"Analysis type: "<<kBFAnalysisType[iAnalysisType].Data()<<endl;
805 cout<<"Width: "<<delta<<"\t Error: "<<deltaError<<endl;
806 cout<<"New error: "<<deltaErrorNew<<endl;
807 cout<<"Integral: "<<integral<<"\t Error: "<<integralError<<endl;
808 cout<<"=================================================="<<endl;
811 //____________________________________________________________________//
812 TH1D *AliBalanceEventMixing::GetBalanceFunctionHistogram(Int_t iAnalysisType,Double_t centrMin, Double_t centrMax, Double_t etaWindow) {
813 //Returns the BF histogram, extracted from the 6 TH2D objects
814 //(private members) of the AliBalanceEventMixing class.
816 // Acceptance correction:
817 // - only for analysis type = kEta
818 // - only if etaWindow > 0 (default = -1.)
819 // - calculated as proposed by STAR
821 TString gAnalysisType[ANALYSIS_TYPES] = {"y","eta","qlong","qout","qside","qinv","phi"};
822 TString histName = "gHistBalanceFunctionHistogram";
823 histName += gAnalysisType[iAnalysisType];
825 SetInterval(iAnalysisType, fHistP[iAnalysisType]->GetYaxis()->GetXmin(),
826 fHistP[iAnalysisType]->GetYaxis()->GetXmin(),
827 fHistPP[iAnalysisType]->GetNbinsY(),
828 fHistPP[iAnalysisType]->GetYaxis()->GetXmin(),
829 fHistPP[iAnalysisType]->GetYaxis()->GetXmax());
831 // determine the projection thresholds
832 Int_t binMinX, binMinY, binMinZ;
833 Int_t binMaxX, binMaxY, binMaxZ;
835 fHistPP[iAnalysisType]->GetBinXYZ(fHistPP[iAnalysisType]->FindBin(centrMin),binMinX,binMinY,binMinZ);
836 fHistPP[iAnalysisType]->GetBinXYZ(fHistPP[iAnalysisType]->FindBin(centrMax),binMaxX,binMaxY,binMaxZ);
838 TH1D *gHistBalanceFunctionHistogram = new TH1D(histName.Data(),"",fHistPP[iAnalysisType]->GetNbinsY(),fHistPP[iAnalysisType]->GetYaxis()->GetXmin(),fHistPP[iAnalysisType]->GetYaxis()->GetXmax());
839 switch(iAnalysisType) {
841 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("#Delta y");
842 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(#Delta y)");
845 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("#Delta #eta");
846 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(#Delta #eta)");
849 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("q_{long} (GeV/c)");
850 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(q_{long})");
853 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("q_{out} (GeV/c)");
854 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(q_{out})");
857 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("q_{side} (GeV/c)");
858 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(q_{side})");
861 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("q_{inv} (GeV/c)");
862 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(q_{inv})");
865 gHistBalanceFunctionHistogram->GetXaxis()->SetTitle("#Delta #phi (deg.)");
866 gHistBalanceFunctionHistogram->GetYaxis()->SetTitle("B(#Delta #phi)");
872 TH1D *hTemp1 = dynamic_cast<TH1D *>(fHistPN[iAnalysisType]->ProjectionY(Form("%s_Cent_%.0f_%.0f",fHistPN[iAnalysisType]->GetName(),centrMin,centrMax),binMinX,binMaxX));
873 TH1D *hTemp2 = dynamic_cast<TH1D *>(fHistPN[iAnalysisType]->ProjectionY(Form("%s_Cent_%.0f_%.0f_copy",fHistPN[iAnalysisType]->GetName(),centrMin,centrMax),binMinX,binMaxX));
874 TH1D *hTemp3 = dynamic_cast<TH1D *>(fHistNN[iAnalysisType]->ProjectionY(Form("%s_Cent_%.0f_%.0f",fHistNN[iAnalysisType]->GetName(),centrMin,centrMax),binMinX,binMaxX));
875 TH1D *hTemp4 = dynamic_cast<TH1D *>(fHistPP[iAnalysisType]->ProjectionY(Form("%s_Cent_%.0f_%.0f",fHistPP[iAnalysisType]->GetName(),centrMin,centrMax),binMinX,binMaxX));
876 TH1D *hTemp5 = dynamic_cast<TH1D *>(fHistN[iAnalysisType]->ProjectionY(Form("%s_Cent_%.0f_%.0f",fHistN[iAnalysisType]->GetName(),centrMin,centrMax),binMinX,binMaxX));
877 TH1D *hTemp6 = dynamic_cast<TH1D *>(fHistP[iAnalysisType]->ProjectionY(Form("%s_Cent_%.0f_%.0f",fHistP[iAnalysisType]->GetName(),centrMin,centrMax),binMinX,binMaxX));
879 if((hTemp1)&&(hTemp2)&&(hTemp3)&&(hTemp4)) {
884 hTemp1->Add(hTemp3,-2.);
885 hTemp1->Scale(1./hTemp5->GetEntries());
886 hTemp2->Add(hTemp4,-2.);
887 hTemp2->Scale(1./hTemp6->GetEntries());
888 gHistBalanceFunctionHistogram->Add(hTemp1,hTemp2,1.,1.);
889 gHistBalanceFunctionHistogram->Scale(0.5/fP2Step[iAnalysisType]);
892 // do the acceptance correction (only for Eta and etaWindow > 0)
893 if(iAnalysisType == kEta && etaWindow > 0){
894 for(Int_t iBin = 0; iBin < gHistBalanceFunctionHistogram->GetNbinsX(); iBin++){
896 Double_t notCorrected = gHistBalanceFunctionHistogram->GetBinContent(iBin+1);
897 Double_t corrected = notCorrected / (1 - (gHistBalanceFunctionHistogram->GetBinCenter(iBin+1))/ etaWindow );
898 gHistBalanceFunctionHistogram->SetBinContent(iBin+1, corrected);
903 PrintResults(iAnalysisType,gHistBalanceFunctionHistogram);
905 return gHistBalanceFunctionHistogram;