1 //====================================================================
2 #include "AliBasedNdetaTask.h"
8 #include <AliAnalysisManager.h>
9 #include <AliAODEvent.h>
10 #include <AliAODHandler.h>
11 #include <AliAODInputHandler.h>
12 #include "AliForwardUtil.h"
13 #include "AliAODForwardMult.h"
17 //____________________________________________________________________
18 AliBasedNdetaTask::AliBasedNdetaTask()
19 : AliAnalysisTaskSE(),
20 fSums(0), // Container of sums
21 fOutput(0), // Container of output
22 fVtxMin(0), // Minimum v_z
23 fVtxMax(0), // Maximum v_z
24 fTriggerMask(0), // Trigger mask
25 fRebin(0), // Rebinning factor
33 fListOfCentralities(0),
38 fNormalizationScheme(kFull),
42 fglobalempiricalcorrection(0),
48 DGUARD(fDebug,3,"Default CTOR of AliBasedNdetaTask");
51 //____________________________________________________________________
52 AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
53 : AliAnalysisTaskSE(name),
54 fSums(0), // Container of sums
55 fOutput(0), // Container of output
56 fVtxMin(-10), // Minimum v_z
57 fVtxMax(10), // Maximum v_z
58 fTriggerMask(AliAODForwardMult::kInel),
59 fRebin(5), // Rebinning factor
67 fListOfCentralities(0),
72 fNormalizationScheme(kFull),
76 fglobalempiricalcorrection(0),
82 DGUARD(fDebug, 3,"Named CTOR of AliBasedNdetaTask: %s", name);
83 fListOfCentralities = new TObjArray(1);
85 // Set the normalisation scheme
86 SetNormalizationScheme(kFull);
88 // Set the trigger mask
89 SetTriggerMask(AliAODForwardMult::kInel);
91 // Output slot #1 writes into a TH1 container
92 DefineOutput(1, TList::Class());
93 DefineOutput(2, TList::Class());
96 //____________________________________________________________________
97 AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
98 : AliAnalysisTaskSE(o),
99 fSums(o.fSums), // TList* - Container of sums
100 fOutput(o.fOutput), // Container of output
101 fVtxMin(o.fVtxMin), // Double_t - Minimum v_z
102 fVtxMax(o.fVtxMax), // Double_t - Maximum v_z
103 fTriggerMask(o.fTriggerMask),// Int_t - Trigger mask
104 fRebin(o.fRebin), // Int_t - Rebinning factor
105 fCutEdges(o.fCutEdges), // Bool_t - Whether to cut edges when rebinning
106 fSymmetrice(o.fSymmetrice),
107 fCorrEmpty(o.fCorrEmpty),
108 fUseROOTProj(o.fUseROOTProj),
109 fTriggerEff(o.fTriggerEff),
110 fTriggerEff0(o.fTriggerEff0),
111 fShapeCorr(o.fShapeCorr),
112 fListOfCentralities(o.fListOfCentralities),
113 fSNNString(o.fSNNString),
114 fSysString(o.fSysString),
116 fCentAxis(o.fCentAxis),
117 fNormalizationScheme(o.fNormalizationScheme),
118 fSchemeString(o.fSchemeString),
119 fTriggerString(o.fTriggerString),
120 fFinalMCCorrFile(o.fFinalMCCorrFile),
121 fglobalempiricalcorrection(o.fglobalempiricalcorrection),
122 fmeabsignalvscentr(o.fmeabsignalvscentr)
124 DGUARD(fDebug, 3,"Copy CTOR of AliBasedNdetaTask");
127 //____________________________________________________________________
128 AliBasedNdetaTask::~AliBasedNdetaTask()
133 DGUARD(fDebug,3,"Destruction of AliBasedNdetaTask");
146 //________________________________________________________________________
148 AliBasedNdetaTask::SetDebugLevel(Int_t lvl)
150 AliAnalysisTaskSE::SetDebugLevel(lvl);
151 for (Int_t i = 0; i < fListOfCentralities->GetEntries(); i++) {
153 static_cast<CentralityBin*>(fListOfCentralities->At(i));
154 bin->SetDebugLevel(lvl);
158 //________________________________________________________________________
160 AliBasedNdetaTask::SetCentralityAxis(UShort_t n, Short_t* bins)
162 DGUARD(fDebug,3,"Set centrality axis, %d bins", n);
164 fCentAxis = new TAxis();
165 fCentAxis->SetName("centAxis");
166 fCentAxis->SetTitle("Centrality [%]");
169 for (UShort_t i = 0; i <= n; i++)
170 dbins[i] = (bins[i] == 100 ? 100.1 : bins[i]);
171 fCentAxis->Set(n, dbins.GetArray());
174 //________________________________________________________________________
176 AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
179 // Add a centrality bin
185 DGUARD(fDebug,3,"Add a centrality bin [%d,%d] @ %d", low, high, at);
186 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
188 Error("AddCentralityBin",
189 "Failed to create centrality bin for %s [%d,%d] @ %d",
190 GetName(), low, high, at);
193 bin->SetDebugLevel(fDebug);
194 fListOfCentralities->AddAtAndExpand(bin, at);
197 //________________________________________________________________________
198 AliBasedNdetaTask::CentralityBin*
199 AliBasedNdetaTask::MakeCentralityBin(const char* name,
200 Short_t low, Short_t high) const
203 // Make a centrality bin
206 // name Name used for histograms
207 // low Low cut in percent
208 // high High cut in percent
211 // A newly created centrality bin
213 DGUARD(fDebug,3,"Make a centrality bin %s [%d,%d]", name, low, high);
214 return new CentralityBin(name, low, high);
217 #define TESTAPPEND(SCHEME,BIT,STRING) \
218 do { if (!(SCHEME & BIT)) break; \
219 if (!s.IsNull()) s.Append(","); s.Append(STRING); } while(false)
221 //________________________________________________________________________
223 AliBasedNdetaTask::NormalizationSchemeString(UShort_t scheme)
225 // Create a string from normalization scheme bits
231 if (scheme == kFull) {
235 TESTAPPEND(scheme, kEventLevel, "EVENT");
236 TESTAPPEND(scheme, kShape, "SHAPE");
237 TESTAPPEND(scheme, kBackground, "BACKGROUND");
238 TESTAPPEND(scheme, kTriggerEfficiency, "TRIGGER");
239 TESTAPPEND(scheme, kZeroBin, "ZEROBIN");
243 //________________________________________________________________________
245 AliBasedNdetaTask::ParseNormalizationScheme(const char* what)
251 TObjArray* token = twhat.Tokenize(" ,|");
253 while ((opt = static_cast<TObjString*>(next()))) {
254 TString s(opt->GetString());
255 if (s.IsNull()) continue;
258 case '-': add = false; // Fall through
259 case '+': s.Remove(0,1); // Remove character
262 if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
263 else if (s.CompareTo("SHAPE") == 0) bit = kShape;
264 else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
265 else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
266 else if (s.CompareTo("FULL") == 0) bit = kFull;
267 else if (s.CompareTo("NONE") == 0) bit = kNone;
268 else if (s.CompareTo("ZEROBIN") == 0) bit = kZeroBin;
270 ::Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
271 if (add) scheme |= bit;
277 //________________________________________________________________________
279 AliBasedNdetaTask::SetNormalizationScheme(const char* what)
282 // Set normalisation scheme
284 DGUARD(fDebug,3,"Set the normalization scheme: %s", what);
285 SetNormalizationScheme(ParseNormalizationScheme(what));
287 //________________________________________________________________________
289 AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme)
291 DGUARD(fDebug,3,"Set the normalization scheme: 0x%x", scheme);
292 fNormalizationScheme = scheme;
293 if (fSchemeString) delete fSchemeString;
294 fSchemeString = AliForwardUtil::MakeParameter("scheme", scheme);
296 //________________________________________________________________________
298 AliBasedNdetaTask::SetTriggerMask(const char* mask)
301 // Set the trigger maskl
306 DGUARD(fDebug,3,"Set the trigger mask: %s", mask);
307 SetTriggerMask(AliAODForwardMult::MakeTriggerMask(mask));
309 //________________________________________________________________________
311 AliBasedNdetaTask::SetTriggerMask(UShort_t mask)
313 DGUARD(fDebug,3,"Set the trigger mask: 0x%0x", mask);
315 if (fTriggerString) delete fTriggerString;
316 fTriggerString = AliForwardUtil::MakeParameter("trigger", fTriggerMask);
319 //________________________________________________________________________
321 AliBasedNdetaTask::SetShapeCorrection(const TH2F* c)
324 // Set the shape correction (a.k.a., track correction) for selected
330 DGUARD(fDebug,3,"Set the shape correction: %p", c);
332 fShapeCorr = static_cast<TH2F*>(c->Clone());
333 fShapeCorr->SetDirectory(0);
336 //________________________________________________________________________
338 AliBasedNdetaTask::InitializeCentBins()
340 if (fListOfCentralities->GetEntries() > 0) return;
342 // Automatically add 'all' centrality bin if nothing has been defined.
343 AddCentralityBin(0, 0, 0);
344 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
345 const TArrayD* bins = fCentAxis->GetXbins();
346 Int_t nbin = fCentAxis->GetNbins();
347 for (Int_t i = 0; i < nbin; i++)
348 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
352 //________________________________________________________________________
354 AliBasedNdetaTask::UserCreateOutputObjects()
357 // Create output objects.
359 // This is called once per slave process
361 DGUARD(fDebug,1,"Create user ouput object");
363 fSums->SetName(Form("%s_sums", GetName()));
366 InitializeCentBins();
367 if (fCentAxis) fSums->Add(fCentAxis);
369 fSums->Add(AliForwardUtil::MakeParameter("alirootRev",
370 AliForwardUtil::AliROOTRevision()));
371 fSums->Add(AliForwardUtil::MakeParameter("alirootBranch",
372 AliForwardUtil::AliROOTBranch()));
374 // Centrality histogram
375 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
376 fCent->SetDirectory(0);
380 // Loop over centrality bins
381 TIter next(fListOfCentralities);
382 CentralityBin* bin = 0;
383 while ((bin = static_cast<CentralityBin*>(next())))
384 bin->CreateOutputObjects(fSums, fTriggerMask);
386 fmeabsignalvscentr=new TH2D("meabsignalvscentr","meabsignalvscentr",400,0,20,100,0,100);
387 fSums->Add(fmeabsignalvscentr);
388 // Post data for ALL output slots >0 here, to get at least an empty
393 //____________________________________________________________________
395 AliBasedNdetaTask::UserExec(Option_t *)
398 // Process a single event
404 DGUARD(fDebug,1,"Analyse the AOD event");
405 AliAODEvent* aod = AliForwardUtil::GetAODEvent(this);
409 TObject* obj = aod->FindListObject("Forward");
411 AliWarning("No forward object found");
414 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
416 // Fill centrality histogram
417 Float_t cent = forward->GetCentrality();
420 // Get the histogram(s)
421 TH2D* data = GetHistogram(aod, false);
422 TH2D* dataMC = GetHistogram(aod, true);
423 if(!ApplyEmpiricalCorrection(forward,data))
426 Int_t notemptybins=0;
428 for (Int_t ix=1;ix<=data->GetXaxis()->GetNbins();ix++)
431 for(Int_t iy=1;iy<=data->GetYaxis()->GetNbins();iy++)
433 if(data->GetBinContent(ix,iy)>0.0)
435 sumy+=data->GetBinContent(ix,iy);
445 sum=sum/((Double_t)notemptybins);
449 fmeabsignalvscentr->Fill(sum,cent);
452 Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
453 !forward->IsTriggerBits(AliAODForwardMult::kNClusterGt0));
456 // Loop over centrality bins
457 CentralityBin* allBin =
458 static_cast<CentralityBin*>(fListOfCentralities->At(0));
459 allBin->ProcessEvent(forward, fTriggerMask, isZero,
460 fVtxMin, fVtxMax, data, dataMC);
462 // Find this centrality bin
463 if (fCentAxis && fCentAxis->GetNbins() > 0) {
464 Int_t icent = fCentAxis->FindBin(cent);
465 CentralityBin* thisBin = 0;
466 if (icent >= 1 && icent <= fCentAxis->GetNbins())
467 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
469 thisBin->ProcessEvent(forward, fTriggerMask, isZero, fVtxMin, fVtxMax,
473 // Here, we get the update
475 fSNNString = AliForwardUtil::MakeParameter("sNN", forward->GetSNN());
476 fSysString = AliForwardUtil::MakeParameter("sys", forward->GetSystem());
478 fSums->Add(fSNNString);
479 fSums->Add(fSysString);
480 fSums->Add(fSchemeString);
481 fSums->Add(fTriggerString);
488 //________________________________________________________________________
490 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
491 const char* title, const char* ytitle)
494 // Set histogram graphical options, etc.
497 // h Histogram to modify
498 // colour Marker color
499 // marker Marker style
500 // title Title of histogram
501 // ytitle Title on y-axis.
504 h->SetMarkerColor(colour);
505 h->SetMarkerStyle(marker);
506 h->SetMarkerSize(marker == 29 || marker == 30 ? 1.2 : 1);
508 h->SetYTitle(ytitle);
509 h->GetXaxis()->SetTitleFont(132);
510 h->GetXaxis()->SetLabelFont(132);
511 h->GetXaxis()->SetNdivisions(10);
512 h->GetYaxis()->SetTitleFont(132);
513 h->GetYaxis()->SetLabelFont(132);
514 h->GetYaxis()->SetNdivisions(10);
515 h->GetYaxis()->SetDecimals();
519 //________________________________________________________________________
521 AliBasedNdetaTask::ScaleToCoverage(TH2D* copy, const TH1D* norm)
523 // Normalize to the acceptance -
524 // dndeta->Divide(accNorm);
525 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
526 Double_t a = norm->GetBinContent(i);
527 for (Int_t j = 1; j <= copy->GetNbinsY(); j++) {
529 copy->SetBinContent(i,j,0);
530 copy->SetBinError(i,j,0);
533 Double_t c = copy->GetBinContent(i, j);
534 Double_t e = copy->GetBinError(i, j);
535 copy->SetBinContent(i, j, c / a);
536 copy->SetBinError(i, j, e / a);
540 //________________________________________________________________________
542 AliBasedNdetaTask::ScaleToCoverage(TH1D* copy, const TH1D* norm)
544 // Normalize to the acceptance -
545 // dndeta->Divide(accNorm);
546 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
547 Double_t a = norm->GetBinContent(i);
549 copy->SetBinContent(i,0);
550 copy->SetBinError(i,0);
553 Double_t c = copy->GetBinContent(i);
554 Double_t e = copy->GetBinError(i);
555 copy->SetBinContent(i, c / a);
556 copy->SetBinError(i, e / a);
560 //________________________________________________________________________
562 AliBasedNdetaTask::ProjectX(const TH2D* h,
571 // Project onto the X axis
576 // firstbin First bin to use
577 // lastbin Last bin to use
578 // error Whether to calculate errors
581 // Newly created histogram or null
585 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
587 TAxis* xaxis = h->GetXaxis();
588 TAxis* yaxis = h->GetYaxis();
589 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
590 xaxis->GetXmin(), xaxis->GetXmax());
591 static_cast<const TAttLine*>(h)->Copy(*ret);
592 static_cast<const TAttFill*>(h)->Copy(*ret);
593 static_cast<const TAttMarker*>(h)->Copy(*ret);
594 ret->GetXaxis()->ImportAttributes(xaxis);
596 Int_t first = firstbin;
597 Int_t last = lastbin;
598 if (first < 0) first = 1;
599 else if (first >= yaxis->GetNbins()+2) first = yaxis->GetNbins()+1;
600 if (last < 0) last = yaxis->GetNbins();
601 else if (last >= yaxis->GetNbins()+2) last = yaxis->GetNbins()+1;
602 if (last-first < 0) {
603 AliWarningGeneral("AliBasedNdetaTask",
604 Form("Nothing to project [%d,%d]", first, last));
610 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
611 Int_t ybins = (last-first+1);
612 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
613 Double_t content = 0;
618 for (Int_t ybin = first; ybin <= last; ybin++) {
619 Double_t c1 = h->GetCellContent(xbin, ybin);
620 Double_t e1 = h->GetCellError(xbin, ybin);
623 if (c1 < 1e-12) continue;
633 if(content > 0 && nbins > 0) {
634 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
636 AliWarningGeneral(ret->GetName(),
637 Form("factor @ %d is %d/%d -> %f",
638 xbin, ybins, nbins, factor));
641 // Calculate weighted average
642 ret->SetBinContent(xbin, content * factor);
643 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
646 ret->SetBinContent(xbin, factor * content);
653 //________________________________________________________________________
655 AliBasedNdetaTask::Terminate(Option_t *)
658 // Called at end of event processing..
660 // This is called once in the master
665 // Draw result to screen, or perform fitting, normalizations Called
666 // once at the end of the query
667 DGUARD(fDebug,1,"Process final merged results");
669 fSums = dynamic_cast<TList*> (GetOutputData(1));
671 AliError("Could not retrieve TList fSums");
676 fOutput->SetName(Form("%s_result", GetName()));
679 fSNNString = fSums->FindObject("sNN");
680 fSysString = fSums->FindObject("sys");
681 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
682 fSchemeString = fSums->FindObject("scheme");
683 fTriggerString = fSums->FindObject("trigger");
685 if(fSysString && fSNNString &&
686 fSysString->GetUniqueID() == AliForwardUtil::kPP)
687 LoadNormalizationData(fSysString->GetUniqueID(),
688 fSNNString->GetUniqueID());
690 InitializeCentBins();
692 // Print before we loop
695 // Loop over centrality bins
696 TIter next(fListOfCentralities);
697 CentralityBin* bin = 0;
698 gStyle->SetPalette(1);
699 THStack* dndetaStack = new THStack("dndeta", "dN/d#eta");
700 THStack* dndetaStackRebin = new THStack(Form("dndeta_rebin%02d", fRebin),
702 THStack* dndetaMCStack = new THStack("dndetaMC", "dN_{ch}/d#eta");
703 THStack* dndetaMCStackRebin = new THStack(Form("dndetaMC_rebin%02d", fRebin),
707 TList* truthlist = 0;
709 if (fFinalMCCorrFile.Contains(".root")) {
710 TFile* ftest = TFile::Open(fFinalMCCorrFile.Data());
712 mclist = dynamic_cast<TList*>(ftest->Get(Form("%sResults",GetName())));
713 truthlist = dynamic_cast<TList*>(ftest->Get("MCTruthResults"));
716 AliWarning("MC analysis file invalid - no final MC correction possible");
718 Int_t style = GetMarker();
719 Int_t color = GetColor();
721 AliInfo(Form("Marker style=%d, color=%d", style, color));
722 while ((bin = static_cast<CentralityBin*>(next()))) {
724 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr,
725 fTriggerEff, fTriggerEff0,
726 fSymmetrice, fRebin, fUseROOTProj, fCorrEmpty, fCutEdges,
727 fTriggerMask, style, color, mclist, truthlist);
728 if (fCentAxis && bin->IsAllBin()) continue;
729 TH1* dndeta = bin->GetResult(0, false, "");
730 TH1* dndetaSym = bin->GetResult(0, true, "");
731 TH1* dndetaMC = bin->GetResult(0, false, "MC");
732 TH1* dndetaMCSym = bin->GetResult(0, true, "MC");
733 if (dndeta) dndetaStack->Add(dndeta);
734 if (dndetaSym) dndetaStack->Add(dndetaSym);
735 if (dndetaMC) dndetaMCStack->Add(dndetaMC);
736 if (dndetaMCSym) dndetaMCStack->Add(dndetaMCSym);
738 dndeta = bin->GetResult(fRebin, false, "");
739 dndetaSym = bin->GetResult(fRebin, true, "");
740 dndetaMC = bin->GetResult(fRebin, false, "MC");
741 dndetaMCSym = bin->GetResult(fRebin, true, "MC");
742 if (dndeta) dndetaStackRebin->Add(dndeta);
743 if (dndetaSym) dndetaStackRebin->Add(dndetaSym);
744 if (dndetaMC) dndetaMCStackRebin->Add(dndetaMC);
745 if (dndetaMCSym) dndetaMCStackRebin->Add(dndetaMCSym);
749 fOutput->Add(dndetaStack);
751 // If available output rebinned stack
752 if (!dndetaStackRebin->GetHists() ||
753 dndetaStackRebin->GetHists()->GetEntries() <= 0) {
754 AliWarning("No rebinned histograms found");
755 delete dndetaStackRebin;
756 dndetaStackRebin = 0;
758 if (dndetaStackRebin) fOutput->Add(dndetaStackRebin);
760 // If available, output track-ref stack
761 if (!dndetaMCStack->GetHists() ||
762 dndetaMCStack->GetHists()->GetEntries() <= 0) {
763 AliWarning("No MC histograms found");
764 delete dndetaMCStack;
767 if (dndetaMCStack) fOutput->Add(dndetaMCStack);
769 // If available, output rebinned track-ref stack
770 if (!dndetaMCStackRebin->GetHists() ||
771 dndetaMCStackRebin->GetHists()->GetEntries() <= 0) {
772 AliWarning("No rebinned MC histograms found");
773 delete dndetaMCStackRebin;
774 dndetaMCStackRebin = 0;
776 if (dndetaMCStackRebin) fOutput->Add(dndetaMCStackRebin);
778 // Output collision energy string
780 UShort_t sNN = fSNNString->GetUniqueID();
781 TNamed* sNNObj = new TNamed(fSNNString->GetName(),
782 AliForwardUtil::CenterOfMassEnergyString(sNN));
783 sNNObj->SetUniqueID(sNN);
784 fOutput->Add(sNNObj); // fSNNString->Clone());
787 // Output collision system string
789 UShort_t sys = fSysString->GetUniqueID();
790 TNamed* sysObj = new TNamed(fSysString->GetName(),
791 AliForwardUtil::CollisionSystemString(sys));
792 sysObj->SetUniqueID(sys);
793 fOutput->Add(sysObj); // fSysString->Clone());
796 // Output centrality axis
797 if (fCentAxis) fOutput->Add(fCentAxis);
799 // Output trigger string
800 if (fTriggerString) {
801 UShort_t mask = fTriggerString->GetUniqueID();
802 TNamed* maskObj = new TNamed(fTriggerString->GetName(),
803 AliAODForwardMult::GetTriggerString(mask));
804 maskObj->SetUniqueID(mask);
805 fOutput->Add(maskObj); // fTriggerString->Clone());
808 // Normalization string
810 UShort_t scheme = fSchemeString->GetUniqueID();
811 TNamed* schemeObj = new TNamed(fSchemeString->GetName(),
812 NormalizationSchemeString(scheme));
813 schemeObj->SetUniqueID(scheme);
814 fOutput->Add(schemeObj); // fSchemeString->Clone());
817 // Output vertex axis
818 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
819 vtxAxis->SetName("vtxAxis");
820 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
821 fOutput->Add(vtxAxis);
823 // Output trigger efficiency and shape correction
824 fOutput->Add(AliForwardUtil::MakeParameter("triggerEff", fTriggerEff));
825 fOutput->Add(AliForwardUtil::MakeParameter("triggerEff0", fTriggerEff0));
826 if (fShapeCorr) fOutput->Add(fShapeCorr);
828 TNamed* options = new TNamed("options","");
830 str.Append(Form("Edges %scut, ", fCutEdges ? "" : "not "));
831 str.Append(Form("Empty bins %scorrected for, ", fCorrEmpty ? "" : "not "));
832 str.Append(Form("TH2::ProjectionX %sused", fUseROOTProj ? "" : "not "));
833 options->SetTitle(str);
834 fOutput->Add(options);
836 PostData(2, fOutput);
838 //________________________________________________________________________
840 AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
842 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
843 DGUARD(fDebug,1,"Load the normalization data for sys=%d, energy=%d",
847 if(energy == 7000) snn.Form("7000");
848 if(energy == 2750) snn.Form("2750");
850 if(fShapeCorr && (fTriggerEff != 1)) {
851 AliInfo("Objects already set for normalization - no action taken");
855 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWGLF/FORWARD/corrections/"
856 "Normalization/normalizationHists_%s_%s.root",
857 type.Data(),snn.Data()));
859 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
864 if ((fNormalizationScheme & kShape) && !fShapeCorr) {
865 TString trigName("All");
866 if (fTriggerMask == AliAODForwardMult::kInel ||
867 fTriggerMask == AliAODForwardMult::kNClusterGt0)
869 else if (fTriggerMask == AliAODForwardMult::kNSD)
871 else if (fTriggerMask == AliAODForwardMult::kInelGt0)
872 trigName = "InelGt0";
874 AliWarning(Form("Normalization for trigger %s not known, using all",
875 AliAODForwardMult::GetTriggerString(fTriggerMask)));
878 TString shapeCorName(Form("h%sNormalization", trigName.Data()));
879 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
880 if (shapeCor) SetShapeCorrection(shapeCor);
882 AliWarning(Form("No shape correction found for %s", trigName.Data()));
886 // Trigger efficiency
887 TString effName(Form("%sTriggerEff",
888 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
889 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
890 fTriggerMask == AliAODForwardMult::kInelGt0 ?
893 Double_t trigEff = 1;
894 if (fNormalizationScheme & kTriggerEfficiency) {
895 TObject* eff = fin->Get(effName);
896 if (eff) AliForwardUtil::GetParameter(eff, trigEff);
898 if (fTriggerEff != 1) SetTriggerEff(trigEff);
899 if (fTriggerEff < 0) fTriggerEff = 1;
901 // Trigger efficiency
902 TString eff0Name(Form("%sTriggerEff0",
903 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
904 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
905 fTriggerMask == AliAODForwardMult::kInelGt0 ?
908 Double_t trigEff0 = 1;
909 if (fNormalizationScheme & kTriggerEfficiency) {
910 TObject* eff = fin->Get(eff0Name);
911 if (eff) AliForwardUtil::GetParameter(eff, trigEff0);
913 if (fTriggerEff0 != 1) SetTriggerEff0(trigEff0);
914 if (fTriggerEff0 < 0) fTriggerEff0 = 1;
917 // Rescale the shape correction by the trigger efficiency
919 AliWarning(Form("Rescaling shape correction by trigger efficiency: "
920 "1/E_X=1/%f", trigEff));
921 fShapeCorr->Scale(1. / trigEff);
925 if (fShapeCorr && fTriggerEff) AliInfo("Loaded objects for normalization.");
929 //________________________________________________________________________
931 AliBasedNdetaTask::Print(Option_t*) const
936 std::cout << this->ClassName() << ": " << this->GetName() << "\n"
938 << " Trigger: " << (fTriggerString ?
939 fTriggerString->GetTitle() :
941 << " Vertex range: [" << fVtxMin << ":"
943 << " Rebin factor: " << fRebin << "\n"
944 << " Cut edges: " << fCutEdges << "\n"
945 << " Symmertrice: " << fSymmetrice << "\n"
946 << " Use TH2::ProjectionX: " << fUseROOTProj << "\n"
947 << " Correct for empty: " << fCorrEmpty << "\n"
948 << " Normalization scheme: " << (fSchemeString ?
949 fSchemeString->GetTitle() :
951 << " Trigger efficiency: " << fTriggerEff << "\n"
952 << " Bin-0 Trigger efficiency: " << fTriggerEff0 << "\n"
953 << " Shape correction: " << (fShapeCorr ?
954 fShapeCorr->GetName() :
956 << " sqrt(s_NN): " << (fSNNString ?
957 fSNNString->GetTitle() :
959 << " Collision system: " << (fSysString ?
960 fSysString->GetTitle() :
962 << " Centrality bins: " << (fCentAxis ? "" : "none");
964 Int_t nBins = fCentAxis->GetNbins();
965 const Double_t* bins = fCentAxis->GetXbins()->GetArray();
966 for (Int_t i = 0; i <= nBins; i++)
967 std::cout << (i==0 ? "" : "-") << bins[i];
969 std::cout << std::noboolalpha << std::endl;
973 //________________________________________________________________________
975 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
978 // Make a copy of the input histogram and rebin that histogram
981 // h Histogram to rebin
984 // New (rebinned) histogram
986 if (rebin <= 1) return 0;
988 Int_t nBins = h->GetNbinsX();
989 if(nBins % rebin != 0) {
990 AliWarningGeneral("AliBasedNdetaTask",
991 Form("Rebin factor %d is not a devisor of current number "
992 "of bins %d in the histogram %s",
993 rebin, nBins, h->GetName()));
998 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
999 h->GetName(), rebin)));
1002 tmp->SetDirectory(0);
1004 // The new number of bins
1005 Int_t nBinsNew = nBins / rebin;
1006 for(Int_t i = 1;i<= nBinsNew; i++) {
1007 Double_t content = 0;
1011 for(Int_t j = 1; j<=rebin;j++) {
1012 Int_t bin = (i-1)*rebin + j;
1013 Double_t c = h->GetBinContent(bin);
1020 if (h->GetBinContent(bin+1)<=0 ||
1021 h->GetBinContent(bin-1)<=0) {
1023 AliWarningGeneral("AliBasedNdetaTask",
1024 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
1025 bin, c, h->GetName(),
1026 bin+1, h->GetBinContent(bin+1),
1027 bin-1, h->GetBinContent(bin-1)));
1032 Double_t e = h->GetBinError(bin);
1033 Double_t w = 1 / (e*e); // 1/c/c
1040 if(content > 0 && nbins > 0) {
1041 tmp->SetBinContent(i, wsum / sumw);
1042 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
1049 //__________________________________________________________________
1051 AliBasedNdetaTask::Symmetrice(const TH1* h)
1054 // Make an extension of @a h to make it symmetric about 0
1057 // h Histogram to symmertrice
1060 // Symmetric extension of @a h
1062 Int_t nBins = h->GetNbinsX();
1063 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
1064 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
1066 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
1067 s->SetMarkerColor(h->GetMarkerColor());
1068 s->SetMarkerSize(h->GetMarkerSize());
1069 s->SetMarkerStyle(FlipHollowStyle(h->GetMarkerStyle()));
1070 s->SetFillColor(h->GetFillColor());
1071 s->SetFillStyle(h->GetFillStyle());
1074 // Find the first and last bin with data
1075 Int_t first = nBins+1;
1077 for (Int_t i = 1; i <= nBins; i++) {
1078 if (h->GetBinContent(i) <= 0) continue;
1079 first = TMath::Min(first, i);
1080 last = TMath::Max(last, i);
1083 Double_t xfirst = h->GetBinCenter(first-1);
1084 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
1085 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
1086 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
1087 s->SetBinContent(j, h->GetBinContent(i));
1088 s->SetBinError(j, h->GetBinError(i));
1090 // Fill in overlap bin
1091 s->SetBinContent(l2+1, h->GetBinContent(first));
1092 s->SetBinError(l2+1, h->GetBinError(first));
1096 //__________________________________________________________________
1098 AliBasedNdetaTask::GetMarkerStyle(UShort_t bits)
1100 Int_t base = bits & (0xFE);
1101 Bool_t hollow = bits & kHollow;
1103 case kCircle: return (hollow ? 24 : 20);
1104 case kSquare: return (hollow ? 25 : 21);
1105 case kUpTriangle: return (hollow ? 26 : 22);
1106 case kDownTriangle: return (hollow ? 32 : 23);
1107 case kDiamond: return (hollow ? 27 : 33);
1108 case kCross: return (hollow ? 28 : 34);
1109 case kStar: return (hollow ? 30 : 29);
1113 //__________________________________________________________________
1115 AliBasedNdetaTask::GetMarkerBits(Int_t style)
1119 case 24: case 25: case 26: case 27: case 28: case 30: case 32:
1120 bits |= kHollow; break;
1123 case 20: case 24: bits |= kCircle; break;
1124 case 21: case 25: bits |= kSquare; break;
1125 case 22: case 26: bits |= kUpTriangle; break;
1126 case 23: case 32: bits |= kDownTriangle; break;
1127 case 27: case 33: bits |= kDiamond; break;
1128 case 28: case 34: bits |= kCross; break;
1129 case 29: case 30: bits |= kStar; break;
1133 //__________________________________________________________________
1135 AliBasedNdetaTask::FlipHollowStyle(Int_t style)
1137 UShort_t bits = GetMarkerBits(style);
1138 Int_t ret = GetMarkerStyle(bits ^ kHollow);
1142 //====================================================================
1144 AliBasedNdetaTask::Sum::Init(TList* list, const TH2D* data, Int_t col)
1146 DGUARD(fDebug,1,"Initializing sums with %s", data->GetName());
1147 TString n(GetHistName(0));
1148 TString n0(GetHistName(1));
1149 const char* postfix = GetTitle();
1151 fSum = static_cast<TH2D*>(data->Clone(n));
1152 if (postfix) fSum->SetTitle(Form("%s (%s)", data->GetTitle(), postfix));
1153 fSum->SetDirectory(0);
1154 fSum->SetMarkerColor(col);
1155 fSum->SetMarkerStyle(GetMarkerStyle(kCircle|kSolid));
1159 fSum0 = static_cast<TH2D*>(data->Clone(n0));
1161 fSum0->SetTitle(Form("%s 0-bin (%s)", data->GetTitle(), postfix));
1163 fSum0->SetTitle(Form("%s 0-bin", data->GetTitle()));
1164 fSum0->SetDirectory(0);
1165 fSum0->SetMarkerColor(col);
1166 fSum0->SetMarkerStyle(GetMarkerStyle(kCross|kHollow));
1170 fEvents = new TH1I(GetHistName(2), "Event types", 2, -.5, 1.5);
1171 fEvents->SetDirectory(0);
1172 fEvents->GetXaxis()->SetBinLabel(1, "Non-zero");
1173 fEvents->GetXaxis()->SetBinLabel(2, "Zero");
1177 //____________________________________________________________________
1179 AliBasedNdetaTask::Sum::GetHistName(const char* name, Int_t what, const char* post)
1182 if (what == 1) n.Append("0");
1183 else if (what == 2) n.Append("Events");
1184 if (post && post[0] != '\0') n.Append(post);
1188 //____________________________________________________________________
1190 AliBasedNdetaTask::Sum::GetHistName(Int_t what) const
1192 return GetHistName(GetName(), what, GetTitle());
1195 //____________________________________________________________________
1197 AliBasedNdetaTask::Sum::Add(const TH2D* data, Bool_t isZero)
1199 DGUARD(fDebug,2,"Adding %s to sums", data->GetName());
1200 if (isZero) fSum0->Add(data);
1201 else fSum->Add(data);
1202 fEvents->Fill(isZero ? 1 : 0);
1205 //____________________________________________________________________
1207 AliBasedNdetaTask::Sum::CalcSum(TList* output,
1213 Bool_t corrEmpty) const
1215 DGUARD(fDebug,2,"Calculating final summed histogram %s", fSum->GetName());
1217 TH2D* ret = static_cast<TH2D*>(fSum->Clone(fSum->GetName()));
1218 ret->SetDirectory(0);
1220 Int_t n = Int_t(fEvents->GetBinContent(1));
1221 Int_t n0 = Int_t(fEvents->GetBinContent(2));
1223 AliInfoF("Adding histograms %s(%d) and %s(%d) with weights %f and %f resp.",
1224 fSum0->GetName(), n, fSum->GetName(), n0, 1./epsilon, 1./epsilon0);
1225 DMSG(fDebug,2, "Adding histograms %s and %s with weights %f and %f resp.",
1226 fSum0->GetName(), fSum->GetName(), 1./epsilon, 1./epsilon0);
1227 // Generate merged histogram
1228 ret->Add(fSum0, fSum, 1. / epsilon0, 1. / epsilon);
1229 ntotal = n / epsilon + n0 / epsilon0;
1231 TList* out = new TList;
1233 const char* postfix = GetTitle();
1234 if (!postfix) postfix = "";
1235 out->SetName(Form("partial%s", postfix));
1238 // Now make copies, normalize them, and store in output list
1239 TH2D* sumCopy = static_cast<TH2D*>(fSum->Clone("sum"));
1240 TH2D* sum0Copy = static_cast<TH2D*>(fSum0->Clone("sum0"));
1241 TH2D* retCopy = static_cast<TH2D*>(ret->Clone("sumAll"));
1242 sumCopy->SetMarkerStyle(FlipHollowStyle(marker));
1243 sumCopy->SetDirectory(0);
1244 sum0Copy->SetMarkerStyle(GetMarkerStyle(GetMarkerBits(marker)+4));
1245 sum0Copy->SetDirectory(0);
1246 retCopy->SetMarkerStyle(marker);
1247 retCopy->SetDirectory(0);
1249 Int_t nY = fSum->GetNbinsY();
1250 Int_t o = 0; // nY+1;
1251 TH1D* norm = ProjectX(fSum, "norm", o, o, rootProj, corrEmpty, false);
1252 TH1D* norm0 = ProjectX(fSum0, "norm0", o, o, rootProj, corrEmpty, false);
1253 TH1D* normAll = ProjectX(ret, "normAll", o, o, rootProj, corrEmpty, false);
1254 norm->SetDirectory(0);
1255 norm0->SetDirectory(0);
1256 normAll->SetDirectory(0);
1258 ScaleToCoverage(sumCopy, norm);
1259 ScaleToCoverage(sum0Copy, norm0);
1260 ScaleToCoverage(retCopy, normAll);
1262 TH1D* sumCopyPx = ProjectX(sumCopy, "average", 1, nY,rootProj,corrEmpty);
1263 TH1D* sum0CopyPx = ProjectX(sum0Copy, "average0", 1, nY,rootProj,corrEmpty);
1264 TH1D* retCopyPx = ProjectX(retCopy, "averageAll", 1, nY,rootProj,corrEmpty);
1265 sumCopyPx->SetDirectory(0);
1266 sum0CopyPx->SetDirectory(0);
1267 retCopyPx->SetDirectory(0);
1269 TH1D* phi = ProjectX(fSum, "phi", nY+1, nY+1,rootProj,corrEmpty);
1270 TH1D* phi0 = ProjectX(fSum0, "phi0", nY+1, nY+1,rootProj,corrEmpty);
1271 TH1D* phiAll = ProjectX(ret, "phiAll", nY+1, nY+1,rootProj,corrEmpty);
1272 phi->SetDirectory(0);
1273 phi0->SetDirectory(0);
1274 phiAll->SetDirectory(0);
1276 // Scale our 1D histograms
1277 sumCopyPx->Scale(1., "width");
1278 sum0CopyPx->Scale(1., "width");
1279 retCopyPx->Scale(1., "width");
1281 AliInfo(Form("Maximum %f,%f changed to %f", sumCopyPx->GetMaximum(),
1282 sum0CopyPx->GetMaximum(), retCopyPx->GetMaximum()));
1284 // Scale the normalization - they should be 1 at the maximum
1285 norm->Scale(n > 0 ? 1. / n : 1);
1286 norm0->Scale(n0 > 0 ? 1. / n0 : 1);
1287 normAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1292 out->Add(sumCopyPx);
1293 out->Add(sum0CopyPx);
1294 out->Add(retCopyPx);
1302 AliInfoF("Returning (1/%f * %s + 1/%f * %s), "
1303 "1/%f * %d + 1/%f * %d = %d",
1304 epsilon0, fSum0->GetName(), epsilon, fSum->GetName(),
1305 epsilon0, n0, epsilon, n, int(ntotal));
1307 for (Int_t i = 1; i <= ret->GetNbinsX(); i++) {
1308 Double_t nc = sum->GetBinContent(i, 0);
1309 Double_t nc0 = sum0->GetBinContent(i, 0);
1310 ret->SetBinContent(i, 0, nc + nc0); // Just count events
1317 //====================================================================
1318 AliBasedNdetaTask::CentralityBin::CentralityBin()
1327 fDoFinalMCCorrection(false),
1333 DGUARD(fDebug,3,"Default CTOR of AliBasedNdeta::CentralityBin");
1335 //____________________________________________________________________
1336 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
1337 Short_t low, Short_t high)
1346 fDoFinalMCCorrection(false),
1353 // name Name used for histograms (e.g., Forward)
1354 // low Lower centrality cut in percent
1355 // high Upper centrality cut in percent
1357 DGUARD(fDebug,3,"Named CTOR of AliBasedNdeta::CentralityBin: %s [%3d,%3d]",
1359 if (low <= 0 && high <= 0) {
1362 SetTitle("All centralities");
1367 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
1370 //____________________________________________________________________
1371 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
1377 fTriggers(o.fTriggers),
1380 fDoFinalMCCorrection(o.fDoFinalMCCorrection),
1387 // other Object to copy from
1389 DGUARD(fDebug,3,"Copy CTOR of AliBasedNdeta::CentralityBin");
1391 //____________________________________________________________________
1392 AliBasedNdetaTask::CentralityBin::~CentralityBin()
1397 DGUARD(fDebug,3,"DTOR of AliBasedNdeta::CentralityBin");
1399 // if (fSums) fSums->Delete();
1400 // if (fOutput) fOutput->Delete();
1403 //____________________________________________________________________
1404 AliBasedNdetaTask::CentralityBin&
1405 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
1408 // Assignment operator
1411 // other Object to assign from
1414 // Reference to this
1416 DGUARD(fDebug,3,"Centrality bin assignment");
1417 if (&o == this) return *this;
1418 SetName(o.GetName());
1419 SetTitle(o.GetTitle());
1421 fOutput = o.fOutput;
1424 fTriggers = o.fTriggers;
1427 fDoFinalMCCorrection = o.fDoFinalMCCorrection;
1431 //____________________________________________________________________
1433 AliBasedNdetaTask::CentralityBin::GetColor(Int_t fallback) const
1435 if (IsAllBin()) return fallback;
1436 Float_t fc = (fLow+double(fHigh-fLow)/2) / 100;
1437 Int_t nCol = gStyle->GetNumberOfColors();
1438 Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
1439 Int_t col = gStyle->GetColorPalette(icol);
1442 //____________________________________________________________________
1444 AliBasedNdetaTask::CentralityBin::GetListName() const
1447 // Get the list name
1452 if (IsAllBin()) return "all";
1453 return Form("cent%03d_%03d", fLow, fHigh);
1455 //____________________________________________________________________
1457 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir, Int_t mask)
1460 // Create output objects
1465 DGUARD(fDebug,1,"Create centrality bin output objects");
1467 fSums->SetName(GetListName());
1471 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers", mask);
1472 fTriggers->SetDirectory(0);
1473 fSums->Add(fTriggers);
1475 //____________________________________________________________________
1477 AliBasedNdetaTask::CentralityBin::SetDebugLevel(Int_t lvl)
1480 if (fSum) fSum->fDebug = lvl;
1481 if (fSumMC) fSumMC->fDebug = lvl;
1484 //____________________________________________________________________
1486 AliBasedNdetaTask::CentralityBin::ReadSum(TList* list, bool mc)
1488 const char* post = (mc ? "MC" : "");
1489 TString sn = Sum::GetHistName(GetName(),0,post);
1490 TString sn0 = Sum::GetHistName(GetName(),1,post);
1491 TString ev = Sum::GetHistName(GetName(),2,post);
1492 TH2D* sum = static_cast<TH2D*>(list->FindObject(sn));
1493 TH2D* sum0 = static_cast<TH2D*>(list->FindObject(sn0));
1494 TH1I* events = static_cast<TH1I*>(list->FindObject(ev));
1495 if (!sum || !sum0 || !events) {
1496 AliWarningF("Failed to find one or more histograms: "
1497 "%s (%p) %s (%p) %s (%p)",
1503 Sum* ret = new Sum(GetName(), post);
1506 ret->fEvents = events;
1507 ret->fDebug = fDebug;
1508 if (mc) fSumMC = ret;
1514 //____________________________________________________________________
1516 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
1519 // Create sum histogram
1522 // data Data histogram to clone
1523 // mc (optional) MC histogram to clone
1525 DGUARD(fDebug,1,"Create centrality bin sums from %s",
1526 data ? data->GetName() : "(null)");
1528 fSum = new Sum(GetName(),"");
1529 fSum->Init(fSums, data, GetColor());
1530 fSum->fDebug = fDebug;
1533 // If no MC data is given, then do not create MC sum histogram
1536 fSumMC = new Sum(GetName(), "MC");
1537 fSumMC->Init(fSums, mc, GetColor());
1538 fSumMC->fDebug = fDebug;
1541 //____________________________________________________________________
1543 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
1545 Double_t vzMin, Double_t vzMax)
1548 // Check the trigger, vertex, and centrality
1554 // true if the event is to be used
1556 if (!forward) return false;
1558 DGUARD(fDebug,2,"Check the event");
1559 // We do not check for centrality here - it's already done
1560 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
1564 //____________________________________________________________________
1566 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
1567 Int_t triggerMask, Bool_t isZero,
1568 Double_t vzMin, Double_t vzMax,
1569 const TH2D* data, const TH2D* mc)
1575 // forward Forward data (for trigger, vertex, & centrality)
1576 // triggerMask Trigger mask
1577 // vzMin Minimum IP z coordinate
1578 // vzMax Maximum IP z coordinate
1579 // data Data histogram
1582 DGUARD(fDebug,1,"Process one event for %s a given centrality bin",
1583 data ? data->GetName() : "(null)");
1584 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
1586 if (!fSum) CreateSums(data, mc);
1588 fSum->Add(data, isZero);
1589 if (mc) fSumMC->Add(mc, isZero);
1592 //________________________________________________________________________
1594 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
1598 TString* text) const
1601 // Calculate normalization
1604 // t Trigger histogram
1605 // scheme Normaliztion scheme
1607 // ntotal On return, contains the number of events.
1609 DGUARD(fDebug,1,"Normalize centrality bin %s with %s",
1610 GetName(), t.GetName());
1611 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1612 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1613 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1614 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1615 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1616 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1617 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1618 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1619 Double_t nAccepted = ntotal;
1622 if (nTriggered <= 0.1) {
1623 AliError("Number of triggered events <= 0");
1626 if (nWithVertex <= 0.1) {
1627 AliError("Number of events with vertex <= 0");
1631 Double_t vtxEff = nWithVertex / nTriggered;
1632 Double_t scaler = 1;
1633 Double_t beta = nA + nC - 2*nE;
1636 TString rhs("N = N_acc");
1637 if (!(scheme & kZeroBin)) {
1638 if (scheme & kEventLevel) {
1639 ntotal = nAccepted / vtxEff;
1641 AliInfoF("Calculating event normalisation as\n"
1642 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1643 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1645 if (scheme & kBackground) {
1647 // s = --------- = ------------- = ------------
1648 // 1 - beta 1 - beta E_V 1 - beta N_V
1649 // --- ---- -------- ---- ---
1650 // E_V N_V N_V N_V N_T
1658 ntotal -= nAccepted * beta / nWithVertex;
1659 // This one is direct and correct.
1660 // scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1661 // A simpler expresion
1662 scaler /= (1 - beta / nTriggered); // 0.831631 -> 0.780689
1663 AliInfo(Form("Calculating event normalisation as\n"
1664 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1665 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1666 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1667 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1668 Int_t(nWithVertex), ntotal, scaler));
1669 rhs.Append("(1/eps_V - beta/N_vtx)");
1672 rhs.Append("/eps_V");
1674 if (scheme & kTriggerEfficiency) {
1677 AliInfo(Form("Correcting for trigger efficiency:\n"
1678 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1679 trigEff, Int_t(ntotal), ntotal / trigEff, scaler));
1680 rhs.Append("/eps_T");
1681 } // Trigger efficiency
1686 // N = N_A + 1/E_X * N_A / N_V (N_T - N_V - beta)
1687 // = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1688 // = N_A (1 + 1/E_X (1/E_V - 1 - beta / N_V))
1690 // s = N_A/N = 1 / (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1691 // = N_V / (N_V + 1/E_X (N_T - N_V - beta))
1693 if (!(scheme & kBackground)) beta = 0;
1694 ntotal = nAccepted * (1 + 1/trigEff * (nTriggered / nWithVertex - 1
1695 - beta / nWithVertex));
1696 scaler = nWithVertex / (nWithVertex +
1697 1/trigEff * (nTriggered-nWithVertex-beta));
1698 AliInfo(Form("Calculating event normalisation as\n"
1699 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1700 " N = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V)) = "
1701 "%d (1 + 1 / %f (%d / %d - 1 - %d / %d)) = %f (%f)",
1702 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1703 Int_t(nAccepted), trigEff, Int_t(nTriggered),
1704 Int_t(nWithVertex), Int_t(beta), Int_t(nWithVertex),
1706 rhs.Append("(1+1/eps_T(1/eps_V-1-beta/N_vtx))");
1710 text->Append(Form("%-40s = %d\n", "N_all", UInt_t(nAll)));
1711 text->Append(Form("%-40s = %d\n", "N_acc", UInt_t(nAccepted)));
1712 text->Append(Form("%-40s = %d\n", "N_trg", UInt_t(nTriggered)));
1713 text->Append(Form("%-40s = %d\n", "N_vtx", UInt_t(nWithVertex)));
1714 text->Append(Form("%-40s = %d\n", "N_B", UInt_t(nB)));
1715 text->Append(Form("%-40s = %d\n", "N_A", UInt_t(nA)));
1716 text->Append(Form("%-40s = %d\n", "N_C", UInt_t(nC)));
1717 text->Append(Form("%-40s = %d\n", "N_E", UInt_t(nE)));
1718 text->Append(Form("%-40s = %d\n", "beta = N_A + N_C - 2N_E",UInt_t(beta)));
1719 text->Append(Form("%-40s = %f\n", "eps_V = N_vtx/N_trg",vtxEff));
1720 text->Append(Form("%-40s = %f\n", "eps_T", trigEff));
1721 text->Append(Form("%-40s = %f\n", rhs.Data(), ntotal));
1725 " Total of %9d events for %s\n"
1726 " of these %9d have an offline trigger\n"
1727 " of these N_T = %9d has the selected trigger\n"
1728 " of these N_V = %9d has a vertex\n"
1729 " of these N_A = %9d were in the selected range\n"
1730 " Triggers by hardware type:\n"
1732 " N_ac = %9d (%d+%d)\n"
1734 " Vertex efficiency: %f\n"
1735 " Trigger efficiency: %f\n"
1736 " Total number of events: N = %f\n"
1737 " Scaler (N_A/N): %f\n"
1739 Int_t(nAll), GetTitle(), Int_t(nOffline),
1740 Int_t(nTriggered), Int_t(nWithVertex), Int_t(nAccepted),
1741 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1742 vtxEff, trigEff, ntotal, scaler, rhs.Data(), ntotal));
1746 //________________________________________________________________________
1748 AliBasedNdetaTask::CentralityBin::GetResultName(Int_t rebin,
1750 const char* postfix) const
1753 n = Form("dndeta%s%s",GetName(), postfix);
1754 if (rebin > 1) n.Append(Form("_rebin%02d", rebin));
1755 if (sym) n.Append("_mirror");
1758 //________________________________________________________________________
1760 AliBasedNdetaTask::CentralityBin::GetResult(Int_t rebin,
1762 const char* postfix) const
1765 AliWarning(Form("No output list defined in %s [%3d,%3d]", GetName(),
1769 TString n = GetResultName(rebin, sym, postfix);
1770 TObject* o = fOutput->FindObject(n.Data());
1772 // AliWarning(Form("Object %s not found in output list", n.Data()));
1775 return static_cast<TH1*>(o);
1778 //________________________________________________________________________
1780 AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
1781 const char* postfix,
1784 const TH2F* shapeCorr,
1795 // Generate the dN/deta result from input
1798 // sum Sum of 2D hists
1799 // postfix Post fix on names
1800 // rootProj Whether to use ROOT TH2::ProjectionX
1801 // corrEmpty Correct for empty bins
1802 // shapeCorr Shape correction to use
1803 // scaler Event-level normalization scaler
1804 // symmetrice Whether to make symmetric extensions
1805 // rebin Whether to rebin
1806 // cutEdges Whether to cut edges when rebinning
1808 DGUARD(fDebug,1,"Make centrality bin result from %s", sum->GetName());
1809 TH2D* copy = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s%s",
1810 GetName(), postfix)));
1811 Int_t nY = sum->GetNbinsY();
1812 Int_t o = (corrEmpty ? 0 : nY+1);
1813 TH1D* accNorm = ProjectX(sum, Form("norm%s%s",GetName(), postfix), o, o,
1814 rootProj, corrEmpty, false);
1815 accNorm->SetDirectory(0);
1817 // ---- Scale by shape correction ----------------------------------
1818 if (shapeCorr) copy->Divide(shapeCorr);
1819 else AliInfo("No shape correction specified, or disabled");
1821 // --- Normalize to the coverage -----------------------------------
1823 ScaleToCoverage(copy, accNorm);
1824 // --- Event-level normalization ---------------------------------
1825 copy->Scale(scaler);
1828 // --- Project on X axis -------------------------------------------
1829 TH1D* dndeta = ProjectX(copy, Form("dndeta%s%s",GetName(), postfix),
1830 1, nY, rootProj, corrEmpty);
1831 dndeta->SetDirectory(0);
1832 // Event-level normalization
1834 ScaleToCoverage(dndeta, accNorm);
1835 dndeta->Scale(scaler);
1837 dndeta->Scale(1., "width");
1838 copy->Scale(1., "width");
1840 TH1D* dndetaMCCorrection = 0;
1841 TList* centlist = 0;
1842 TH1D* dndetaMCtruth = 0;
1843 TList* truthcentlist = 0;
1845 // Possible final correction to <MC analysis> / <MC truth>
1847 centlist = static_cast<TList*> (mclist->FindObject(GetListName()));
1849 dndetaMCCorrection =
1850 static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s",
1851 GetName(), postfix)));
1853 truthcentlist =static_cast<TList*>(truthlist->FindObject(GetListName()));
1855 dndetaMCtruth =static_cast<TH1D*>(truthcentlist->FindObject("dndetaTruth"));
1857 if(dndetaMCCorrection && dndetaMCtruth) {
1858 AliInfo("Correcting with final MC correction");
1859 dndetaMCCorrection->Divide(dndetaMCtruth);
1860 dndetaMCCorrection->SetTitle("Final MC correction");
1861 dndetaMCCorrection->SetName("finalMCCorr");
1862 dndeta->Divide(dndetaMCCorrection);
1865 AliInfo("No final MC correction applied");
1867 // --- Set some histogram attributes -------------------------------
1869 Int_t rColor = GetColor(color);
1870 if (postfix && postfix[0] != '\0') post = Form(" (%s)", postfix);
1871 SetHistogramAttributes(dndeta, rColor, marker,
1872 Form("ALICE %s%s", GetName(), post.Data()));
1873 SetHistogramAttributes(accNorm, rColor, marker,
1874 Form("ALICE %s normalisation%s",
1875 GetName(), post.Data()));
1877 // --- Make symmetric extensions and rebinnings --------------------
1878 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1879 fOutput->Add(dndeta);
1880 fOutput->Add(accNorm);
1882 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1883 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1884 if (dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
1887 //________________________________________________________________________
1889 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1892 const TH2F* shapeCorr,
1907 // End of processing
1910 // sums List of sums
1911 // results Output list of results
1912 // shapeCorr Shape correction or nil
1913 // trigEff Trigger efficiency
1914 // symmetrice Whether to symmetrice the results
1915 // rebin Whether to rebin the results
1916 // corrEmpty Whether to correct for empty bins
1917 // cutEdges Whether to cut edges when rebinning
1918 // triggerMask Trigger mask
1920 DGUARD(fDebug,1,"End centrality bin procesing");
1922 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1924 AliError("Could not retrieve TList fSums");
1928 fOutput = new TList;
1929 fOutput->SetName(GetListName());
1930 fOutput->SetOwner();
1931 results->Add(fOutput);
1934 if (!ReadSum(fSums, false)) {
1935 AliInfo("This task did not produce any output");
1939 if (!fSumMC) ReadSum(fSums, true);
1941 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1944 AliError("Couldn't find histogram 'triggers' in list");
1948 // --- Get normalization scaler ------------------------------------
1949 Double_t epsilonT = trigEff;
1950 Double_t epsilonT0 = trigEff0;
1951 AliInfoF("Using epsilonT=%f, epsilonT0=%f for %d",
1952 epsilonT, epsilonT0, triggerMask);
1955 if (triggerMask == AliAODForwardMult::kNSD) {
1956 // This is a local change
1958 AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
1960 else if (triggerMask == AliAODForwardMult::kInel) {
1961 // This is a local change
1963 AliWarning(Form("Using hard-coded Inel trigger efficiency of %f",epsilonT));
1965 if (scheme & kZeroBin) {
1966 if (triggerMask==AliAODForwardMult::kInel)
1967 epsilonT0 = 0.785021; // 0.100240;
1968 else if (triggerMask==AliAODForwardMult::kInelGt0)
1970 else if (triggerMask==AliAODForwardMult::kNSD)
1971 epsilonT0 = .706587;
1973 AliWarning(Form("Using hard-coded NCluster>0 trigger efficiency of %f",
1978 // Get our histograms
1980 TH2D* sum = fSum->CalcSum(fOutput, nSum, epsilonT0, epsilonT,
1981 marker, rootProj, corrEmpty);
1982 Double_t nSumMC = 0;
1984 if (fSumMC) sumMC = fSumMC->CalcSum(fOutput, nSumMC,
1985 epsilonT0, epsilonT, marker,
1986 rootProj, corrEmpty);
1988 AliError("Failed to get sum from summer - bailing out");
1993 Double_t ntotal = nSum;
1994 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal, &text);
1996 AliError("Failed to calculate normalization - bailing out");
1999 fOutput->Add(fTriggers->Clone());
2000 fOutput->Add(new TNamed("normCalc", text.Data()));
2002 // --- Make result and store ---------------------------------------
2003 MakeResult(sum, "", rootProj, corrEmpty, (scheme & kShape) ? shapeCorr : 0,
2004 scaler, symmetrice, rebin, cutEdges, marker, color,
2007 // --- Process result from TrackRefs -------------------------------
2009 MakeResult(sumMC, "MC", rootProj, corrEmpty,
2010 (scheme & kShape) ? shapeCorr : 0,
2011 scaler, symmetrice, rebin, cutEdges,
2012 GetMarkerStyle(GetMarkerBits(marker)+4), color,
2016 // if (!IsAllBin()) return;
2019 //_________________________________________________________________________________________________
2020 Bool_t AliBasedNdetaTask::ApplyEmpiricalCorrection(const AliAODForwardMult* aod,TH2D* data)
2022 if (!fglobalempiricalcorrection)
2024 Float_t zvertex=aod->GetIpZ();
2025 Int_t binzvertex=fglobalempiricalcorrection->GetXaxis()->FindBin(zvertex);
2026 if(binzvertex<1||binzvertex>fglobalempiricalcorrection->GetNbinsX())
2028 for (int i=1;i<=data->GetNbinsX();i++)
2030 Int_t bincorrection=fglobalempiricalcorrection->GetYaxis()->FindBin(data->GetXaxis()->GetBinCenter(i));
2031 if(bincorrection<1||bincorrection>fglobalempiricalcorrection->GetNbinsY())
2033 Float_t correction=fglobalempiricalcorrection->GetBinContent(binzvertex,bincorrection);
2034 if(correction<0.001)
2036 data->SetBinContent(i,0,0);
2037 data->SetBinContent(i,data->GetNbinsY()+1,0);
2040 for(int j=1;j<=data->GetNbinsY();j++)
2042 if (data->GetBinContent(i,j)>0.0)
2044 data->SetBinContent(i,j,data->GetBinContent(i,j)*correction);
2045 data->SetBinError(i,j,data->GetBinError(i,j)*correction);