1 //====================================================================
2 #include "AliBasedNdetaTask.h"
8 #include <TParameter.h>
9 #include <AliAnalysisManager.h>
10 #include <AliAODEvent.h>
11 #include <AliAODHandler.h>
12 #include <AliAODInputHandler.h>
13 #include "AliForwardUtil.h"
14 #include "AliAODForwardMult.h"
18 //____________________________________________________________________
19 AliBasedNdetaTask::AliBasedNdetaTask()
20 : AliAnalysisTaskSE(),
21 fSums(0), // Container of sums
22 fOutput(0), // Container of output
23 fVtxMin(0), // Minimum v_z
24 fVtxMax(0), // Maximum v_z
25 fTriggerMask(0), // Trigger mask
26 fRebin(0), // Rebinning factor
33 fListOfCentralities(0),
38 fNormalizationScheme(kFull),
47 DGUARD(0,0,"Default construction of AliBasedNdetaTask");
50 //____________________________________________________________________
51 AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
52 : AliAnalysisTaskSE(name),
53 fSums(0), // Container of sums
54 fOutput(0), // Container of output
55 fVtxMin(-10), // Minimum v_z
56 fVtxMax(10), // Maximum v_z
57 fTriggerMask(AliAODForwardMult::kInel),
58 fRebin(5), // Rebinning factor
65 fListOfCentralities(0),
70 fNormalizationScheme(kFull),
79 DGUARD(0,0,"Named construction of AliBasedNdetaTask: %s", name);
80 fListOfCentralities = new TObjArray(1);
82 // Set the normalisation scheme
83 SetNormalizationScheme(kFull);
85 // Set the trigger mask
86 SetTriggerMask(AliAODForwardMult::kInel);
88 // Output slot #1 writes into a TH1 container
89 DefineOutput(1, TList::Class());
90 DefineOutput(2, TList::Class());
93 //____________________________________________________________________
94 AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
95 : AliAnalysisTaskSE(o),
96 fSums(o.fSums), // TList* - Container of sums
97 fOutput(o.fOutput), // Container of output
98 fVtxMin(o.fVtxMin), // Double_t - Minimum v_z
99 fVtxMax(o.fVtxMax), // Double_t - Maximum v_z
100 fTriggerMask(o.fTriggerMask),// Int_t - Trigger mask
101 fRebin(o.fRebin), // Int_t - Rebinning factor
102 fCutEdges(o.fCutEdges), // Bool_t - Whether to cut edges when rebinning
103 fSymmetrice(o.fSymmetrice),
104 fCorrEmpty(o.fCorrEmpty),
105 fUseROOTProj(o.fUseROOTProj),
106 fTriggerEff(o.fTriggerEff),
107 fShapeCorr(o.fShapeCorr),
108 fListOfCentralities(o.fListOfCentralities),
109 fSNNString(o.fSNNString),
110 fSysString(o.fSysString),
112 fCentAxis(o.fCentAxis),
113 fNormalizationScheme(o.fNormalizationScheme),
114 fSchemeString(o.fSchemeString),
115 fTriggerString(o.fTriggerString),
116 fFinalMCCorrFile(o.fFinalMCCorrFile),
119 DGUARD(0,0,"Copy construction of AliBasedNdetaTask");
122 //____________________________________________________________________
123 AliBasedNdetaTask::~AliBasedNdetaTask()
128 DGUARD(fDebug,3,"Destruction of AliBasedNdetaTask");
141 //________________________________________________________________________
143 AliBasedNdetaTask::SetDebugLevel(Int_t lvl)
145 AliAnalysisTaskSE::SetDebugLevel(lvl);
146 for (Int_t i = 0; i < fListOfCentralities->GetEntries(); i++) {
148 static_cast<CentralityBin*>(fListOfCentralities->At(i));
149 bin->SetDebugLevel(lvl);
153 //________________________________________________________________________
155 AliBasedNdetaTask::SetCentralityAxis(UShort_t n, Short_t* bins)
157 DGUARD(fDebug,3,"Set centrality axis, %d bins", n);
159 fCentAxis = new TAxis();
160 fCentAxis->SetName("centAxis");
161 fCentAxis->SetTitle("Centrality [%]");
164 for (UShort_t i = 0; i <= n; i++)
165 dbins[i] = (bins[i] == 100 ? 100.1 : bins[i]);
166 fCentAxis->Set(n, dbins.GetArray());
169 //________________________________________________________________________
171 AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
174 // Add a centrality bin
180 DGUARD(fDebug,3,"Add a centrality bin [%f,%f] @ %d", low, high, at);
181 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
182 bin->SetDebugLevel(fDebug);
183 fListOfCentralities->AddAtAndExpand(bin, at);
186 //________________________________________________________________________
187 AliBasedNdetaTask::CentralityBin*
188 AliBasedNdetaTask::MakeCentralityBin(const char* name,
189 Short_t low, Short_t high) const
192 // Make a centrality bin
195 // name Name used for histograms
196 // low Low cut in percent
197 // high High cut in percent
200 // A newly created centrality bin
202 DGUARD(fDebug,3,"Make a centrality bin [%f,%f]: %s", low, high, name);
203 return new CentralityBin(name, low, high);
205 //________________________________________________________________________
207 AliBasedNdetaTask::SetNormalizationScheme(const char* what)
210 // Set normalisation scheme
212 DGUARD(fDebug,3,"Set the normalization scheme: %s", what);
217 TIter next(twhat.Tokenize(" ,|"));
218 while ((opt = static_cast<TObjString*>(next()))) {
219 TString s(opt->GetString());
220 if (s.IsNull()) continue;
223 case '-': add = false; // Fall through
224 case '+': s.Remove(0,1); // Remove character
227 if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
228 else if (s.CompareTo("SHAPE") == 0) bit = kShape;
229 else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
230 else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
231 else if (s.CompareTo("FULL") == 0) bit = kFull;
232 else if (s.CompareTo("NONE") == 0) bit = kNone;
233 else if (s.CompareTo("ZEROBIN") == 0) bit = kZeroBin;
235 Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
236 if (add) scheme |= bit;
239 SetNormalizationScheme(scheme);
241 //________________________________________________________________________
243 AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme)
245 DGUARD(fDebug,3,"Set the normalization scheme: 0x%x", scheme);
246 fNormalizationScheme = scheme;
248 if (scheme == kFull) tit = "FULL";
250 if (scheme & kEventLevel) tit.Append("EVENT ");
251 if (scheme & kShape) tit.Append("SHAPE ");
252 if (scheme & kBackground) tit.Append("BACKGROUND ");
253 if (scheme & kTriggerEfficiency) tit.Append("TRIGGER ");
254 if (scheme & kZeroBin) tit.Append("ZEROBIN ");
256 tit = tit.Strip(TString::kBoth);
257 if (!fSchemeString) fSchemeString = new TNamed("scheme", "");
258 fSchemeString->SetTitle(tit);
259 fSchemeString->SetUniqueID(fNormalizationScheme);
261 //________________________________________________________________________
263 AliBasedNdetaTask::SetTriggerMask(const char* mask)
266 // Set the trigger maskl
271 DGUARD(fDebug,3,"Set the trigger mask: %s", mask);
272 SetTriggerMask(AliAODForwardMult::MakeTriggerMask(mask));
274 //________________________________________________________________________
276 AliBasedNdetaTask::SetTriggerMask(UShort_t mask)
278 DGUARD(fDebug,3,"Set the trigger mask: 0x%0x", mask);
280 TString tit(AliAODForwardMult::GetTriggerString(mask));
281 tit = tit.Strip(TString::kBoth);
282 if (!fTriggerString) fTriggerString = new TNamed("trigger", "");
283 fTriggerString->SetTitle(tit);
284 fTriggerString->SetUniqueID(fTriggerMask);
287 //________________________________________________________________________
289 AliBasedNdetaTask::SetShapeCorrection(const TH1* c)
292 // Set the shape correction (a.k.a., track correction) for selected
298 DGUARD(fDebug,3,"Set the shape correction: %p", c);
300 fShapeCorr = static_cast<TH1*>(c->Clone());
301 fShapeCorr->SetDirectory(0);
304 //________________________________________________________________________
306 AliBasedNdetaTask::UserCreateOutputObjects()
309 // Create output objects.
311 // This is called once per slave process
313 DGUARD(fDebug,1,"Create user ouput object");
315 fSums->SetName(Form("%s_sums", GetName()));
318 // Automatically add 'all' centrality bin if nothing has been defined.
319 AddCentralityBin(0, 0, 0);
320 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
321 const TArrayD* bins = fCentAxis->GetXbins();
322 Int_t nbin = fCentAxis->GetNbins();
323 for (Int_t i = 0; i < nbin; i++)
324 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
326 if (fCentAxis) fSums->Add(fCentAxis);
329 // Centrality histogram
330 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
331 fCent->SetDirectory(0);
335 // Loop over centrality bins
336 TIter next(fListOfCentralities);
337 CentralityBin* bin = 0;
338 while ((bin = static_cast<CentralityBin*>(next())))
339 bin->CreateOutputObjects(fSums);
341 // Check that we have an AOD input handler
342 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
343 AliAODInputHandler* ah =
344 dynamic_cast<AliAODInputHandler*>(am->GetInputEventHandler());
347 const char* depName = GetTitle();
348 AliAnalysisTask* dep = am->GetTask(depName); // "Central"
350 AliErrorF("The multiplicity task %s wasn't added to the train", depName);
354 if (!fIsESD && !ah) AliFatal("No AOD input handler set in analysis manager");
356 // Post data for ALL output slots >0 here, to get at least an empty histogram
359 //____________________________________________________________________
361 AliBasedNdetaTask::GetAODEvent(bool isESD)
366 // isESD Whether we have ESD input or not
369 // Pointer to AOD event or null
370 DGUARD(fDebug,1,"Get the AOD event (%s analysis)", isESD ? "ESD" : "AOD");
371 AliAODEvent* aod = 0;
373 if (!isESD) aod = dynamic_cast<AliAODEvent*>(InputEvent());
374 else aod = AODEvent();
375 if (!aod) AliError("Cannot get the AOD event");
380 //____________________________________________________________________
382 AliBasedNdetaTask::UserExec(Option_t *)
385 // Process a single event
391 DGUARD(fDebug,1,"Analyse the AOD event");
392 AliAODEvent* aod = GetAODEvent(fIsESD);
396 TObject* obj = aod->FindListObject("Forward");
398 AliWarning("No forward object found");
401 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
403 // Fill centrality histogram
404 Float_t cent = forward->GetCentrality();
407 // Get the histogram(s)
408 TH2D* data = GetHistogram(aod, false);
409 TH2D* dataMC = GetHistogram(aod, true);
411 Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
412 !forward->IsTriggerBits(AliAODForwardMult::kNClusterGt0));
415 // Loop over centrality bins
416 CentralityBin* allBin =
417 static_cast<CentralityBin*>(fListOfCentralities->At(0));
418 allBin->ProcessEvent(forward, fTriggerMask, isZero,
419 fVtxMin, fVtxMax, data, dataMC);
421 // Find this centrality bin
422 if (fCentAxis && fCentAxis->GetNbins() > 0) {
423 Int_t icent = fCentAxis->FindBin(cent);
424 CentralityBin* thisBin = 0;
425 if (icent >= 1 && icent <= fCentAxis->GetNbins())
426 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
428 thisBin->ProcessEvent(forward, fTriggerMask, isZero, fVtxMin, fVtxMax,
432 // Here, we get the update
434 UShort_t sNN = forward->GetSNN();
435 fSNNString = new TNamed("sNN", "");
436 fSNNString->SetTitle(AliForwardUtil::CenterOfMassEnergyString(sNN));
437 fSNNString->SetUniqueID(sNN);
438 fSums->Add(fSNNString);
440 UShort_t sys = forward->GetSystem();
441 fSysString = new TNamed("sys", "");
442 fSysString->SetTitle(AliForwardUtil::CollisionSystemString(sys));
443 fSysString->SetUniqueID(sys);
444 fSums->Add(fSysString);
446 fSums->Add(fSchemeString);
447 fSums->Add(fTriggerString);
455 //________________________________________________________________________
457 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
458 const char* title, const char* ytitle)
461 // Set histogram graphical options, etc.
464 // h Histogram to modify
465 // colour Marker color
466 // marker Marker style
467 // title Title of histogram
468 // ytitle Title on y-axis.
471 h->SetMarkerColor(colour);
472 h->SetMarkerStyle(marker);
473 h->SetMarkerSize(marker == 29 || marker == 30 ? 1.2 : 1);
475 h->SetYTitle(ytitle);
476 h->GetXaxis()->SetTitleFont(132);
477 h->GetXaxis()->SetLabelFont(132);
478 h->GetXaxis()->SetNdivisions(10);
479 h->GetYaxis()->SetTitleFont(132);
480 h->GetYaxis()->SetLabelFont(132);
481 h->GetYaxis()->SetNdivisions(10);
482 h->GetYaxis()->SetDecimals();
486 //________________________________________________________________________
488 AliBasedNdetaTask::ScaleToCoverage(TH2D* copy, const TH1D* norm)
490 // Normalize to the acceptance -
491 // dndeta->Divide(accNorm);
492 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
493 Double_t a = norm->GetBinContent(i);
494 for (Int_t j = 1; j <= copy->GetNbinsY(); j++) {
496 copy->SetBinContent(i,j,0);
497 copy->SetBinError(i,j,0);
500 Double_t c = copy->GetBinContent(i, j);
501 Double_t e = copy->GetBinError(i, j);
502 copy->SetBinContent(i, j, c / a);
503 copy->SetBinError(i, j, e / a);
508 //________________________________________________________________________
510 AliBasedNdetaTask::ProjectX(const TH2D* h,
519 // Project onto the X axis
524 // firstbin First bin to use
525 // lastbin Last bin to use
526 // error Whether to calculate errors
529 // Newly created histogram or null
533 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
535 TAxis* xaxis = h->GetXaxis();
536 TAxis* yaxis = h->GetYaxis();
537 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
538 xaxis->GetXmin(), xaxis->GetXmax());
539 static_cast<const TAttLine*>(h)->Copy(*ret);
540 static_cast<const TAttFill*>(h)->Copy(*ret);
541 static_cast<const TAttMarker*>(h)->Copy(*ret);
542 ret->GetXaxis()->ImportAttributes(xaxis);
544 Int_t first = firstbin;
545 Int_t last = lastbin;
546 if (first < 0) first = 0;
547 else if (first >= yaxis->GetNbins()+1) first = yaxis->GetNbins();
548 if (last < 0) last = yaxis->GetNbins();
549 else if (last > yaxis->GetNbins()+1) last = yaxis->GetNbins();
550 if (last-first < 0) {
551 AliWarningGeneral("AliBasedNdetaTask",
552 Form("Nothing to project [%d,%d]", first, last));
558 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
559 Int_t ybins = (last-first+1);
560 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
561 Double_t content = 0;
566 for (Int_t ybin = first; ybin <= last; ybin++) {
567 Double_t c1 = h->GetCellContent(xbin, ybin);
568 Double_t e1 = h->GetCellError(xbin, ybin);
571 if (c1 < 1e-12) continue;
581 if(content > 0 && nbins > 0) {
582 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
584 AliWarningGeneral(ret->GetName(),
585 Form("factor @ %d is %d/%d -> %f",
586 xbin, ybins, nbins, factor));
589 // Calculate weighted average
590 ret->SetBinContent(xbin, content * factor);
591 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
594 ret->SetBinContent(xbin, factor * content);
601 //________________________________________________________________________
603 AliBasedNdetaTask::Terminate(Option_t *)
606 // Called at end of event processing..
608 // This is called once in the master
613 // Draw result to screen, or perform fitting, normalizations Called
614 // once at the end of the query
615 DGUARD(fDebug,1,"Process final merged results");
617 fSums = dynamic_cast<TList*> (GetOutputData(1));
619 AliError("Could not retrieve TList fSums");
624 fOutput->SetName(Form("%s_result", GetName()));
627 fSNNString = static_cast<TNamed*>(fSums->FindObject("sNN"));
628 fSysString = static_cast<TNamed*>(fSums->FindObject("sys"));
629 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
630 fSchemeString = static_cast<TNamed*>(fSums->FindObject("scheme"));
631 fTriggerString = static_cast<TNamed*>(fSums->FindObject("trigger"));
633 if(fSysString && fSNNString &&
634 fSysString->GetUniqueID() == AliForwardUtil::kPP)
635 LoadNormalizationData(fSysString->GetUniqueID(),
636 fSNNString->GetUniqueID());
637 // Print before we loop
640 // Loop over centrality bins
641 TIter next(fListOfCentralities);
642 CentralityBin* bin = 0;
643 gStyle->SetPalette(1);
644 THStack* dndetaStack = new THStack("dndeta", "dN/d#eta");
645 THStack* dndetaStackRebin = new THStack(Form("dndeta_rebin%02d", fRebin),
647 THStack* dndetaMCStack = new THStack("dndetaMC", "dN_{ch}/d#eta");
648 THStack* dndetaMCStackRebin = new THStack(Form("dndetaMC_rebin%02d", fRebin),
652 TList* truthlist = 0;
654 if (fFinalMCCorrFile.Contains(".root")) {
655 TFile* ftest = TFile::Open(fFinalMCCorrFile.Data());
657 mclist = dynamic_cast<TList*>(ftest->Get(Form("%sResults",GetName())));
658 truthlist = dynamic_cast<TList*>(ftest->Get("MCTruthResults"));
661 AliWarning("MC analysis file invalid - no final MC correction possible");
663 Int_t style = GetMarker();
664 Int_t color = GetColor();
666 AliInfo(Form("Marker style=%d, color=%d", style, color));
667 while ((bin = static_cast<CentralityBin*>(next()))) {
669 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr, fTriggerEff,
670 fSymmetrice, fRebin, fUseROOTProj, fCorrEmpty, fCutEdges,
671 fTriggerMask, style, color, mclist, truthlist);
672 if (fCentAxis && bin->IsAllBin()) continue;
673 TH1* dndeta = bin->GetResult(0, false, "");
674 TH1* dndetaSym = bin->GetResult(0, true, "");
675 TH1* dndetaMC = bin->GetResult(0, false, "MC");
676 TH1* dndetaMCSym = bin->GetResult(0, true, "MC");
677 if (dndeta) dndetaStack->Add(dndeta);
678 if (dndetaSym) dndetaStack->Add(dndetaSym);
679 if (dndetaMC) dndetaMCStack->Add(dndetaMC);
680 if (dndetaMCSym) dndetaMCStack->Add(dndetaMCSym);
682 dndeta = bin->GetResult(fRebin, false, "");
683 dndetaSym = bin->GetResult(fRebin, true, "");
684 dndetaMC = bin->GetResult(fRebin, false, "MC");
685 dndetaMCSym = bin->GetResult(fRebin, true, "MC");
686 if (dndeta) dndetaStackRebin->Add(dndeta);
687 if (dndetaSym) dndetaStackRebin->Add(dndetaSym);
688 if (dndetaMC) dndetaMCStackRebin->Add(dndetaMC);
689 if (dndetaMCSym) dndetaMCStackRebin->Add(dndetaMCSym);
693 fOutput->Add(dndetaStack);
695 // If available output rebinned stack
696 if (!dndetaStackRebin->GetHists() ||
697 dndetaStackRebin->GetHists()->GetEntries() <= 0) {
698 AliWarning("No rebinned histograms found");
699 delete dndetaStackRebin;
700 dndetaStackRebin = 0;
702 if (dndetaStackRebin) fOutput->Add(dndetaStackRebin);
704 // If available, output track-ref stack
705 if (!dndetaMCStack->GetHists() ||
706 dndetaMCStack->GetHists()->GetEntries() <= 0) {
707 AliWarning("No MC histograms found");
708 delete dndetaMCStack;
711 if (dndetaMCStack) fOutput->Add(dndetaMCStack);
713 // If available, output rebinned track-ref stack
714 if (!dndetaMCStackRebin->GetHists() ||
715 dndetaMCStackRebin->GetHists()->GetEntries() <= 0) {
716 AliWarning("No rebinned MC histograms found");
717 delete dndetaMCStackRebin;
718 dndetaMCStackRebin = 0;
720 if (dndetaMCStackRebin) fOutput->Add(dndetaMCStackRebin);
722 // Output collision energy string
723 if (fSNNString) fOutput->Add(fSNNString->Clone());
725 // Output collision system string
726 if (fSysString) fOutput->Add(fSysString->Clone());
728 // Output centrality axis
729 if (fCentAxis) fOutput->Add(fCentAxis);
731 // Output trigger string
732 if (fTriggerString) fOutput->Add(fTriggerString->Clone());
734 // Normalization string
735 if (fSchemeString) fOutput->Add(fSchemeString->Clone());
737 // Output vertex axis
738 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
739 vtxAxis->SetName("vtxAxis");
740 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
741 fOutput->Add(vtxAxis);
743 // Output trigger efficiency and shape correction
744 fOutput->Add(new TParameter<Double_t>("triggerEff", fTriggerEff));
745 if (fShapeCorr) fOutput->Add(fShapeCorr);
747 TNamed* options = new TNamed("options","");
749 str.Append(Form("Edges %scut, ", fCutEdges ? "" : "not "));
750 str.Append(Form("Empty bins %scorrected for, ", fCorrEmpty ? "" : "not "));
751 str.Append(Form("TH2::ProjectionX %sused", fUseROOTProj ? "" : "not "));
752 options->SetTitle(str);
753 fOutput->Add(options);
755 PostData(2, fOutput);
757 //________________________________________________________________________
759 AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
761 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
762 DGUARD(fDebug,1,"Load the normalization data for sys=%d, energy=%d",
766 if(energy == 7000) snn.Form("7000");
767 if(energy == 2750) snn.Form("2750");
769 if(fShapeCorr && (fTriggerEff != 1)) {
770 AliInfo("Objects already set for normalization - no action taken");
774 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWGLF/FORWARD/corrections/"
775 "Normalization/normalizationHists_%s_%s.root",
776 type.Data(),snn.Data()));
778 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
783 if ((fNormalizationScheme & kShape) && !fShapeCorr) {
784 TString trigName("All");
785 if (fTriggerMask == AliAODForwardMult::kInel ||
786 fTriggerMask == AliAODForwardMult::kNClusterGt0)
788 else if (fTriggerMask == AliAODForwardMult::kNSD)
790 else if (fTriggerMask == AliAODForwardMult::kInelGt0)
791 trigName = "InelGt0";
793 AliWarning(Form("Normalization for trigger %s not known, using all",
794 AliAODForwardMult::GetTriggerString(fTriggerMask)));
797 TString shapeCorName(Form("h%sNormalization", trigName.Data()));
798 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
799 if (shapeCor) SetShapeCorrection(shapeCor);
801 AliWarning(Form("No shape correction found for %s", trigName.Data()));
805 // Trigger efficiency
806 TString effName(Form("%sTriggerEff",
807 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
808 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
809 fTriggerMask == AliAODForwardMult::kInelGt0 ?
811 TParameter<float>* eff = 0;
812 if (fNormalizationScheme & kTriggerEfficiency)
813 eff = static_cast<TParameter<float>*>(fin->Get(effName));
814 Double_t trigEff = eff ? eff->GetVal() : 1;
815 if (fTriggerEff != 1) SetTriggerEff(trigEff);
816 if (fTriggerEff < 0) fTriggerEff = 1;
819 // Rescale the shape correction by the trigger efficiency
821 AliWarning(Form("Rescaling shape correction by trigger efficiency: "
822 "1/E_X=1/%f", trigEff));
823 fShapeCorr->Scale(1. / trigEff);
827 if (fShapeCorr && fTriggerEff) AliInfo("Loaded objects for normalization.");
831 //________________________________________________________________________
833 AliBasedNdetaTask::Print(Option_t*) const
838 std::cout << this->ClassName() << ": " << this->GetName() << "\n"
840 << " Trigger: " << (fTriggerString ?
841 fTriggerString->GetTitle() :
843 << " Vertex range: [" << fVtxMin << ":" << fVtxMax << "]\n"
844 << " Rebin factor: " << fRebin << "\n"
845 << " Cut edges: " << fCutEdges << "\n"
846 << " Symmertrice: " << fSymmetrice << "\n"
847 << " Use TH2::ProjectionX: " << fUseROOTProj << "\n"
848 << " Correct for empty: " << fCorrEmpty << "\n"
849 << " Normalization scheme: " << (fSchemeString ?
850 fSchemeString->GetTitle() :
852 << " Trigger efficiency: " << fTriggerEff << "\n"
853 << " Shape correction: " << (fShapeCorr ?
854 fShapeCorr->GetName() :
856 << " sqrt(s_NN): " << (fSNNString ?
857 fSNNString->GetTitle() :
859 << " Collision system: " << (fSysString ?
860 fSysString->GetTitle() :
862 << " Centrality bins: " << (fCentAxis ? "" : "none");
864 Int_t nBins = fCentAxis->GetNbins();
865 const Double_t* bins = fCentAxis->GetXbins()->GetArray();
866 for (Int_t i = 0; i <= nBins; i++)
867 std::cout << (i==0 ? "" : "-") << bins[i];
869 std::cout << std::noboolalpha << std::endl;
873 //________________________________________________________________________
875 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
878 // Make a copy of the input histogram and rebin that histogram
881 // h Histogram to rebin
884 // New (rebinned) histogram
886 if (rebin <= 1) return 0;
888 Int_t nBins = h->GetNbinsX();
889 if(nBins % rebin != 0) {
890 AliWarningGeneral("AliBasedNdetaTask",
891 Form("Rebin factor %d is not a devisor of current number "
892 "of bins %d in the histogram %s",
893 rebin, nBins, h->GetName()));
898 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
899 h->GetName(), rebin)));
901 tmp->SetDirectory(0);
903 // The new number of bins
904 Int_t nBinsNew = nBins / rebin;
905 for(Int_t i = 1;i<= nBinsNew; i++) {
906 Double_t content = 0;
910 for(Int_t j = 1; j<=rebin;j++) {
911 Int_t bin = (i-1)*rebin + j;
912 Double_t c = h->GetBinContent(bin);
913 if (c <= 0) continue;
916 if (h->GetBinContent(bin+1)<=0 ||
917 h->GetBinContent(bin-1)<=0) {
919 AliWarningGeneral("AliBasedNdetaTask",
920 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
921 bin, c, h->GetName(),
922 bin+1, h->GetBinContent(bin+1),
923 bin-1, h->GetBinContent(bin-1)));
928 Double_t e = h->GetBinError(bin);
929 Double_t w = 1 / (e*e); // 1/c/c
936 if(content > 0 && nbins > 0) {
937 tmp->SetBinContent(i, wsum / sumw);
938 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
945 //__________________________________________________________________
947 AliBasedNdetaTask::Symmetrice(const TH1* h)
950 // Make an extension of @a h to make it symmetric about 0
953 // h Histogram to symmertrice
956 // Symmetric extension of @a h
958 Int_t nBins = h->GetNbinsX();
959 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
960 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
962 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
963 s->SetMarkerColor(h->GetMarkerColor());
964 s->SetMarkerSize(h->GetMarkerSize());
965 s->SetMarkerStyle(FlipHollowStyle(h->GetMarkerStyle()));
966 s->SetFillColor(h->GetFillColor());
967 s->SetFillStyle(h->GetFillStyle());
970 // Find the first and last bin with data
971 Int_t first = nBins+1;
973 for (Int_t i = 1; i <= nBins; i++) {
974 if (h->GetBinContent(i) <= 0) continue;
975 first = TMath::Min(first, i);
976 last = TMath::Max(last, i);
979 Double_t xfirst = h->GetBinCenter(first-1);
980 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
981 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
982 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
983 s->SetBinContent(j, h->GetBinContent(i));
984 s->SetBinError(j, h->GetBinError(i));
986 // Fill in overlap bin
987 s->SetBinContent(l2+1, h->GetBinContent(first));
988 s->SetBinError(l2+1, h->GetBinError(first));
992 //__________________________________________________________________
994 AliBasedNdetaTask::GetMarkerStyle(UShort_t bits)
996 Int_t base = bits & (0xFE);
997 Bool_t hollow = bits & kHollow;
999 case kCircle: return (hollow ? 24 : 20);
1000 case kSquare: return (hollow ? 25 : 21);
1001 case kUpTriangle: return (hollow ? 26 : 22);
1002 case kDownTriangle: return (hollow ? 32 : 23);
1003 case kDiamond: return (hollow ? 27 : 33);
1004 case kCross: return (hollow ? 28 : 34);
1005 case kStar: return (hollow ? 30 : 29);
1009 //__________________________________________________________________
1011 AliBasedNdetaTask::GetMarkerBits(Int_t style)
1015 case 24: case 25: case 26: case 27: case 28: case 30: case 32:
1016 bits |= kHollow; break;
1019 case 20: case 24: bits |= kCircle; break;
1020 case 21: case 25: bits |= kSquare; break;
1021 case 22: case 26: bits |= kUpTriangle; break;
1022 case 23: case 32: bits |= kDownTriangle; break;
1023 case 27: case 33: bits |= kDiamond; break;
1024 case 28: case 34: bits |= kCross; break;
1025 case 29: case 30: bits |= kStar; break;
1029 //__________________________________________________________________
1031 AliBasedNdetaTask::FlipHollowStyle(Int_t style)
1033 UShort_t bits = GetMarkerBits(style);
1034 Int_t ret = GetMarkerStyle(bits ^ kHollow);
1038 //====================================================================
1040 AliBasedNdetaTask::Sum::Init(TList* list, const TH2D* data, Int_t col)
1042 DGUARD(fDebug,1,"Initializing sums with %s", data->GetName());
1043 TString n(GetHistName(0));
1044 TString n0(GetHistName(1));
1045 const char* postfix = GetTitle();
1047 fSum = static_cast<TH2D*>(data->Clone(n));
1048 if (postfix) fSum->SetTitle(Form("%s (%s)", data->GetTitle(), postfix));
1049 fSum->SetDirectory(0);
1050 fSum->SetMarkerColor(col);
1051 fSum->SetMarkerStyle(GetMarkerStyle(kCircle|kSolid));
1055 fSum0 = static_cast<TH2D*>(data->Clone(n0));
1057 fSum0->SetTitle(Form("%s 0-bin (%s)", data->GetTitle(), postfix));
1059 fSum0->SetTitle(Form("%s 0-bin", data->GetTitle()));
1060 fSum0->SetDirectory(0);
1061 fSum0->SetMarkerColor(col);
1062 fSum0->SetMarkerStyle(GetMarkerStyle(kCross|kHollow));
1066 fEvents = new TH1I(GetHistName(2), "Event types", 2, -.5, 1.5);
1067 fEvents->SetDirectory(0);
1068 fEvents->GetXaxis()->SetBinLabel(1, "Non-zero");
1069 fEvents->GetXaxis()->SetBinLabel(2, "Zero");
1073 //____________________________________________________________________
1075 AliBasedNdetaTask::Sum::GetHistName(Int_t what) const
1077 TString n(GetName());
1078 if (what == 1) n.Append("0");
1079 else if (what == 2) n.Append("Events");
1080 const char* postfix = GetTitle();
1081 if (postfix && postfix[0] != '\0') n.Append(postfix);
1085 //____________________________________________________________________
1087 AliBasedNdetaTask::Sum::Add(const TH2D* data, Bool_t isZero)
1089 DGUARD(fDebug,2,"Adding %s to sums", data->GetName());
1090 if (isZero) fSum0->Add(data);
1091 else fSum->Add(data);
1092 fEvents->Fill(isZero ? 1 : 0);
1095 //____________________________________________________________________
1097 AliBasedNdetaTask::Sum::GetSum(const TList* input,
1104 Bool_t corrEmpty) const
1106 DGUARD(fDebug,2,"Get sums from input list %s", input->GetName());
1107 TH2D* sum = static_cast<TH2D*>(input->FindObject(GetHistName(0)));
1108 TH2D* sum0 = static_cast<TH2D*>(input->FindObject(GetHistName(1)));
1109 TH1I* events = static_cast<TH1I*>(input->FindObject(GetHistName(2)));
1110 if (!sum || !sum0 || !events) {
1111 AliWarning(Form("Failed to find one or more histograms: "
1112 "%s (%p) %s (%p) %s (%p)",
1113 GetHistName(0).Data(), sum,
1114 GetHistName(1).Data(), sum0,
1115 GetHistName(2).Data(), events));
1119 TH2D* ret = static_cast<TH2D*>(sum->Clone(sum->GetName()));
1120 ret->SetDirectory(0);
1122 Int_t n = Int_t(events->GetBinContent(1));
1123 Int_t n0 = Int_t(events->GetBinContent(2));
1125 AliInfo(Form("Adding histograms %s and %s with weights %f and %f resp.",
1126 sum0->GetName(), sum->GetName(), 1./epsilon, 1./epsilon0));
1127 // Generate merged histogram
1128 ret->Add(sum0, sum, 1. / epsilon0, 1. / epsilon);
1129 ntotal = n / epsilon + n0 / epsilon0;
1131 TList* out = new TList;
1133 const char* postfix = GetTitle();
1134 if (!postfix) postfix = "";
1135 out->SetName(Form("partial%s", postfix));
1138 // Now make copies, normalize them, and store in output list
1139 TH2D* sumCopy = static_cast<TH2D*>(sum->Clone("sum"));
1140 TH2D* sum0Copy = static_cast<TH2D*>(sum0->Clone("sum0"));
1141 TH2D* retCopy = static_cast<TH2D*>(ret->Clone("sumAll"));
1142 sumCopy->SetMarkerStyle(FlipHollowStyle(marker));
1143 sumCopy->SetDirectory(0);
1144 sum0Copy->SetMarkerStyle(GetMarkerStyle(GetMarkerBits(marker)+4));
1145 sum0Copy->SetDirectory(0);
1146 retCopy->SetMarkerStyle(marker);
1147 retCopy->SetDirectory(0);
1149 TH1D* norm = ProjectX(sum, "norm", 0, 0, rootProj, corrEmpty, false);
1150 TH1D* norm0 = ProjectX(sum0, "norm0", 0, 0, rootProj, corrEmpty, false);
1151 TH1D* normAll = ProjectX(ret, "normAll", 0, 0, rootProj, corrEmpty, false);
1152 norm->SetDirectory(0);
1153 norm0->SetDirectory(0);
1154 normAll->SetDirectory(0);
1156 ScaleToCoverage(sumCopy, norm);
1157 ScaleToCoverage(sum0Copy, norm0);
1158 ScaleToCoverage(retCopy, normAll);
1160 Int_t nY = sum->GetNbinsY();
1161 TH1D* sumCopyPx = ProjectX(sumCopy, "average", 1, nY,rootProj,corrEmpty);
1162 TH1D* sum0CopyPx = ProjectX(sum0Copy, "average0", 1, nY,rootProj,corrEmpty);
1163 TH1D* retCopyPx = ProjectX(retCopy, "averageAll", 1, nY,rootProj,corrEmpty);
1164 sumCopyPx->SetDirectory(0);
1165 sum0CopyPx->SetDirectory(0);
1166 retCopyPx->SetDirectory(0);
1168 // Scale our 1D histograms
1169 sumCopyPx->Scale(1., "width");
1170 sum0CopyPx->Scale(1., "width");
1171 retCopyPx->Scale(1., "width");
1173 AliInfo(Form("Maximum %f,%f changed to %f", sumCopyPx->GetMaximum(),
1174 sum0CopyPx->GetMaximum(), retCopyPx->GetMaximum()));
1176 // Scale the normalization - they should be 1 at the maximum
1177 norm->Scale(n > 0 ? 1. / n : 1);
1178 norm0->Scale(n0 > 0 ? 1. / n0 : 1);
1179 normAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1184 out->Add(sumCopyPx);
1185 out->Add(sum0CopyPx);
1186 out->Add(retCopyPx);
1191 AliInfo(Form("Returning (1/%f * %s + 1/%f * %s), "
1192 "1/%f * %d + 1/%f * %d = %d",
1193 epsilon0, sum0->GetName(), epsilon, sum->GetName(),
1194 epsilon0, n0, epsilon, n, int(ntotal)));
1196 for (Int_t i = 1; i <= ret->GetNbinsX(); i++) {
1197 Double_t nc = sum->GetBinContent(i, 0);
1198 Double_t nc0 = sum0->GetBinContent(i, 0);
1199 ret->SetBinContent(i, 0, nc + nc0); // Just count events
1206 //====================================================================
1207 AliBasedNdetaTask::CentralityBin::CentralityBin()
1216 fDoFinalMCCorrection(false),
1222 DGUARD(0,0,"Centrality bin default construction");
1224 //____________________________________________________________________
1225 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
1226 Short_t low, Short_t high)
1235 fDoFinalMCCorrection(false),
1242 // name Name used for histograms (e.g., Forward)
1243 // low Lower centrality cut in percent
1244 // high Upper centrality cut in percent
1246 DGUARD(0,0,"Named Centrality bin construction: %s [%d,%d]", name);
1247 if (low <= 0 && high <= 0) {
1250 SetTitle("All centralities");
1255 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
1258 //____________________________________________________________________
1259 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
1265 fTriggers(o.fTriggers),
1268 fDoFinalMCCorrection(o.fDoFinalMCCorrection),
1275 // other Object to copy from
1277 DGUARD(0,0,"Copy Centrality bin construction");
1279 //____________________________________________________________________
1280 AliBasedNdetaTask::CentralityBin::~CentralityBin()
1285 DGUARD(fDebug,3,"Centrality bin desctruction");
1286 if (fSums) fSums->Delete();
1287 if (fOutput) fOutput->Delete();
1290 //____________________________________________________________________
1291 AliBasedNdetaTask::CentralityBin&
1292 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
1295 // Assignment operator
1298 // other Object to assign from
1301 // Reference to this
1303 DGUARD(fDebug,3,"Centrality bin assignment");
1304 if (&o == this) return *this;
1305 SetName(o.GetName());
1306 SetTitle(o.GetTitle());
1308 fOutput = o.fOutput;
1311 fTriggers = o.fTriggers;
1314 fDoFinalMCCorrection = o.fDoFinalMCCorrection;
1318 //____________________________________________________________________
1320 AliBasedNdetaTask::CentralityBin::GetColor(Int_t fallback) const
1322 if (IsAllBin()) return fallback;
1323 Float_t fc = (fLow+double(fHigh-fLow)/2) / 100;
1324 Int_t nCol = gStyle->GetNumberOfColors();
1325 Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
1326 Int_t col = gStyle->GetColorPalette(icol);
1329 //____________________________________________________________________
1331 AliBasedNdetaTask::CentralityBin::GetListName() const
1334 // Get the list name
1339 if (IsAllBin()) return "all";
1340 return Form("cent%03d_%03d", fLow, fHigh);
1342 //____________________________________________________________________
1344 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir)
1347 // Create output objects
1352 DGUARD(fDebug,1,"Create centrality bin output objects");
1354 fSums->SetName(GetListName());
1358 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers");
1359 fTriggers->SetDirectory(0);
1360 fSums->Add(fTriggers);
1362 //____________________________________________________________________
1364 AliBasedNdetaTask::CentralityBin::SetDebugLevel(Int_t lvl)
1367 if (fSum) fSum->fDebug = lvl;
1368 if (fSumMC) fSumMC->fDebug = lvl;
1371 //____________________________________________________________________
1373 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
1376 // Create sum histogram
1379 // data Data histogram to clone
1380 // mc (optional) MC histogram to clone
1382 DGUARD(fDebug,1,"Create centrality bin sums from %s", data->GetName());
1384 fSum = new Sum(GetName(),"");
1385 fSum->Init(fSums, data, GetColor());
1386 fSum->fDebug = fDebug;
1389 // If no MC data is given, then do not create MC sum histogram
1392 fSumMC = new Sum(GetName(), "MC");
1393 fSumMC->Init(fSums, mc, GetColor());
1394 fSumMC->fDebug = fDebug;
1397 //____________________________________________________________________
1399 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
1401 Double_t vzMin, Double_t vzMax)
1404 // Check the trigger, vertex, and centrality
1410 // true if the event is to be used
1412 if (!forward) return false;
1414 DGUARD(fDebug,2,"Check the event");
1415 // We do not check for centrality here - it's already done
1416 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
1420 //____________________________________________________________________
1422 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
1423 Int_t triggerMask, Bool_t isZero,
1424 Double_t vzMin, Double_t vzMax,
1425 const TH2D* data, const TH2D* mc)
1431 // forward Forward data (for trigger, vertex, & centrality)
1432 // triggerMask Trigger mask
1433 // vzMin Minimum IP z coordinate
1434 // vzMax Maximum IP z coordinate
1435 // data Data histogram
1438 DGUARD(fDebug,1,"Process one event for %s a given centrality bin",
1440 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
1442 if (!fSum) CreateSums(data, mc);
1444 fSum->Add(data, isZero);
1445 if (mc) fSumMC->Add(mc, isZero);
1448 //________________________________________________________________________
1450 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
1453 Double_t& ntotal) const
1456 // Calculate normalization
1459 // t Trigger histogram
1460 // scheme Normaliztion scheme
1462 // ntotal On return, contains the number of events.
1464 DGUARD(fDebug,1,"Normalize centrality bin with %s", t.GetName());
1465 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1466 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1467 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1468 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1469 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1470 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1471 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1472 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1473 Double_t nAccepted = ntotal; // t.GetBinContent(AliAODForwardMult::kAccepted);
1476 if (nTriggered <= 0.1) {
1477 AliError("Number of triggered events <= 0");
1480 if (nWithVertex <= 0.1) {
1481 AliError("Number of events with vertex <= 0");
1485 Double_t vtxEff = nWithVertex / nTriggered;
1486 Double_t scaler = 1;
1487 Double_t beta = nA + nC - 2*nE;
1489 if (scheme & kEventLevel && !(scheme & kZeroBin)) {
1490 ntotal = nAccepted / vtxEff;
1492 AliInfo(Form("Calculating event normalisation as\n"
1493 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1494 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1497 if (scheme & kBackground) {
1499 // s = --------- = ------------- = ------------
1500 // 1 - beta 1 - beta E_V 1 - beta N_V
1501 // --- ---- -------- ---- ---
1502 // E_V N_V N_V N_V N_T
1510 ntotal -= nAccepted * beta / nWithVertex;
1511 // This one is direct and correct.
1512 // scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1513 // A simpler expresion
1514 scaler /= (1 - beta / nTriggered); // 0.831631 -> 0.780689
1515 AliInfo(Form("Calculating event normalisation as\n"
1516 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1517 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1518 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1519 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1520 Int_t(nWithVertex), ntotal, scaler));
1523 if (scheme & kZeroBin) {
1526 // N = N_A + 1/E_X * N_A / N_V (N_T - N_V - beta)
1527 // = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1529 // s = N_A/N = 1 / (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1530 // = N_V / (N_V + 1/E_X (N_T - N_V - beta))
1532 if (!(scheme & kBackground)) beta = 0;
1533 ntotal = nAccepted * (1 + 1/trigEff * (nTriggered / nWithVertex - 1
1534 - beta / nWithVertex));
1535 scaler = nWithVertex / (nWithVertex +
1536 1/trigEff * (nTriggered-nWithVertex-beta));
1537 AliInfo(Form("Calculating event normalisation as\n"
1538 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1539 " N = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V)) = "
1540 "%d (1 + 1 / %f (%d / %d - 1 - %d / %d)) = %f (%f)",
1541 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1542 Int_t(nAccepted), trigEff, Int_t(nTriggered),
1543 Int_t(nWithVertex), Int_t(beta), Int_t(nWithVertex),
1546 if (scheme & kTriggerEfficiency && !(scheme & kZeroBin)) {
1549 AliInfo(Form("Correcting for trigger efficiency:\n"
1550 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1551 trigEff, Int_t(ntotal), ntotal / trigEff, scaler));
1555 " Total of %9d events for %s\n"
1556 " of these %9d have an offline trigger\n"
1557 " of these N_T = %9d has the selected trigger\n"
1558 " of these N_V = %9d has a vertex\n"
1559 " of these N_A = %9d were in the selected range\n"
1560 " Triggers by hardware type:\n"
1562 " N_ac = %9d (%d+%d)\n"
1564 " Vertex efficiency: %f\n"
1565 " Trigger efficiency: %f\n"
1566 " Total number of events: N = %f\n"
1567 " Scaler (N_A/N): %f",
1568 Int_t(nAll), GetTitle(), Int_t(nOffline),
1569 Int_t(nTriggered), Int_t(nWithVertex), Int_t(nAccepted),
1570 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1571 vtxEff, trigEff, ntotal, scaler));
1575 //________________________________________________________________________
1577 AliBasedNdetaTask::CentralityBin::GetResultName(Int_t rebin,
1579 const char* postfix) const
1582 n = Form("dndeta%s%s",GetName(), postfix);
1583 if (rebin > 1) n.Append(Form("_rebin%02d", rebin));
1584 if (sym) n.Append("_mirror");
1587 //________________________________________________________________________
1589 AliBasedNdetaTask::CentralityBin::GetResult(Int_t rebin,
1591 const char* postfix) const
1594 AliWarning(Form("No output list defined in %s [%3d,%3d]", GetName(),
1598 TString n = GetResultName(rebin, sym, postfix);
1599 TObject* o = fOutput->FindObject(n.Data());
1601 // AliWarning(Form("Object %s not found in output list", n.Data()));
1604 return static_cast<TH1*>(o);
1607 //________________________________________________________________________
1609 AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
1610 const char* postfix,
1613 const TH1* shapeCorr,
1624 // Generate the dN/deta result from input
1627 // sum Sum of 2D hists
1628 // postfix Post fix on names
1629 // rootProj Whether to use ROOT TH2::ProjectionX
1630 // corrEmpty Correct for empty bins
1631 // shapeCorr Shape correction to use
1632 // scaler Event-level normalization scaler
1633 // symmetrice Whether to make symmetric extensions
1634 // rebin Whether to rebin
1635 // cutEdges Whether to cut edges when rebinning
1637 DGUARD(fDebug,1,"Make centrality bin result from %s", sum->GetName());
1638 TH2D* copy = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s%s",
1639 GetName(), postfix)));
1640 TH1D* accNorm = ProjectX(sum, Form("norm%s%s",GetName(), postfix), 0, 0,
1641 rootProj, corrEmpty, false);
1642 accNorm->SetDirectory(0);
1644 // ---- Scale by shape correction ----------------------------------
1645 if (shapeCorr) copy->Divide(shapeCorr);
1646 else AliInfo("No shape correction specified, or disabled");
1648 // --- Normalize to the coverage -----------------------------------
1649 ScaleToCoverage(copy, accNorm);
1651 // --- Event-level normalization -----------------------------------
1652 copy->Scale(scaler);
1654 // --- Project on X axis -------------------------------------------
1655 TH1D* dndeta = ProjectX(copy, Form("dndeta%s%s",GetName(), postfix),
1656 1, sum->GetNbinsY(), rootProj, corrEmpty);
1657 dndeta->SetDirectory(0);
1658 // Event-level normalization
1659 dndeta->Scale(1., "width");
1660 copy->Scale(1., "width");
1662 TH1D* dndetaMCCorrection = 0;
1663 TList* centlist = 0;
1664 TH1D* dndetaMCtruth = 0;
1665 TList* truthcentlist = 0;
1667 // Possible final correction to <MC analysis> / <MC truth>
1669 centlist = static_cast<TList*> (mclist->FindObject(GetListName()));
1671 dndetaMCCorrection = static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s",GetName(), postfix)));
1673 truthcentlist = static_cast<TList*> (truthlist->FindObject(GetListName()));
1675 dndetaMCtruth = static_cast<TH1D*> (truthcentlist->FindObject("dndetaTruth"));
1676 //std::cout<<dndetaMCCorrection<<" "<<dndetaMCtruth<<std::endl;
1677 if(dndetaMCCorrection && dndetaMCtruth) {
1678 AliInfo("Correcting with final MC correction");
1679 dndetaMCCorrection->Divide(dndetaMCtruth);
1680 dndeta->Divide(dndetaMCCorrection);
1682 //std::cout<<"histo "<<Form("dndeta%s%s",GetName(), postfix)<<" "<<GetListName()<<" "<<dndetaMCCorrection<<std::endl;
1683 //std::cout<<"truth "<<GetListName()<<" "<<dndetaMCtruth<<std::endl;
1686 else AliInfo("No final MC correction applied");
1688 // --- Set some histogram attributes -------------------------------
1690 Int_t rColor = GetColor(color);
1691 if (postfix && postfix[0] != '\0') post = Form(" (%s)", postfix);
1692 SetHistogramAttributes(dndeta, rColor, marker,
1693 Form("ALICE %s%s", GetName(), post.Data()));
1694 SetHistogramAttributes(accNorm, rColor, marker,
1695 Form("ALICE %s normalisation%s",
1696 GetName(), post.Data()));
1698 // --- Make symmetric extensions and rebinnings --------------------
1699 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1700 fOutput->Add(dndeta);
1701 fOutput->Add(accNorm);
1703 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1704 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1707 //________________________________________________________________________
1709 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1712 const TH1* shapeCorr,
1726 // End of processing
1729 // sums List of sums
1730 // results Output list of results
1731 // shapeCorr Shape correction or nil
1732 // trigEff Trigger efficiency
1733 // symmetrice Whether to symmetrice the results
1734 // rebin Whether to rebin the results
1735 // corrEmpty Whether to correct for empty bins
1736 // cutEdges Whether to cut edges when rebinning
1737 // triggerMask Trigger mask
1739 DGUARD(fDebug,1,"End centrality bin procesing");
1741 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1743 AliError("Could not retrieve TList fSums");
1747 fOutput = new TList;
1748 fOutput->SetName(GetListName());
1749 fOutput->SetOwner();
1750 results->Add(fOutput);
1753 AliInfo("This task did not produce any output");
1757 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1760 AliError("Couldn't find histogram 'triggers' in list");
1764 AliError(Form("No sum object for %s", GetName()));
1768 // --- Get normalization scaler ------------------------------------
1769 Double_t epsilonT = trigEff;
1770 Double_t epsilonT0 = trigEff;
1772 if (triggerMask == AliAODForwardMult::kNSD) {
1773 // This is a local change
1775 AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
1777 else if (triggerMask == AliAODForwardMult::kInel) {
1778 // This is a local change
1780 AliWarning(Form("Using hard-coded Inel trigger efficiency of %f",epsilonT));
1782 if (scheme & kZeroBin) {
1783 if (triggerMask==AliAODForwardMult::kInel)
1784 epsilonT0 = 0.785021; // 0.100240;
1785 else if (triggerMask==AliAODForwardMult::kInelGt0)
1787 else if (triggerMask==AliAODForwardMult::kNSD)
1788 epsilonT0 = .706587;
1790 AliWarning(Form("Using hard-coded NCluster>0 trigger efficiency of %f",
1794 // Get our histograms
1796 TH2D* sum = fSum->GetSum(fSums, fOutput, nSum, epsilonT0, 1,
1797 marker, rootProj, corrEmpty);
1798 Double_t nSumMC = 0;
1800 if (fSumMC) sumMC = fSumMC->GetSum(fSums, fOutput, nSumMC,
1801 epsilonT0, 1, marker,
1802 rootProj, corrEmpty);
1804 AliError("Failed to get sum from summer - bailing out");
1808 Double_t ntotal = nSum;
1809 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal);
1811 AliError("Failed to calculate normalization - bailing out");
1814 fOutput->Add(fTriggers->Clone());
1816 // --- Make result and store ---------------------------------------
1817 MakeResult(sum, "", rootProj, corrEmpty, (scheme & kShape) ? shapeCorr : 0,
1818 scaler, symmetrice, rebin, cutEdges, marker, color,
1821 // --- Process result from TrackRefs -------------------------------
1823 MakeResult(sumMC, "MC", rootProj, corrEmpty,
1824 (scheme & kShape) ? shapeCorr : 0,
1825 scaler, symmetrice, rebin, cutEdges,
1826 GetMarkerStyle(GetMarkerBits(marker)+4), color,
1830 // if (!IsAllBin()) return;