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),
46 DGUARD(fDebug,3,"Default CTOR of AliBasedNdetaTask");
49 //____________________________________________________________________
50 AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
51 : AliAnalysisTaskSE(name),
52 fSums(0), // Container of sums
53 fOutput(0), // Container of output
54 fVtxMin(-10), // Minimum v_z
55 fVtxMax(10), // Maximum v_z
56 fTriggerMask(AliAODForwardMult::kInel),
57 fRebin(5), // Rebinning factor
65 fListOfCentralities(0),
70 fNormalizationScheme(kFull),
78 DGUARD(fDebug, 3,"Named CTOR of AliBasedNdetaTask: %s", name);
79 fListOfCentralities = new TObjArray(1);
81 // Set the normalisation scheme
82 SetNormalizationScheme(kFull);
84 // Set the trigger mask
85 SetTriggerMask(AliAODForwardMult::kInel);
87 // Output slot #1 writes into a TH1 container
88 DefineOutput(1, TList::Class());
89 DefineOutput(2, TList::Class());
92 //____________________________________________________________________
93 AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
94 : AliAnalysisTaskSE(o),
95 fSums(o.fSums), // TList* - Container of sums
96 fOutput(o.fOutput), // Container of output
97 fVtxMin(o.fVtxMin), // Double_t - Minimum v_z
98 fVtxMax(o.fVtxMax), // Double_t - Maximum v_z
99 fTriggerMask(o.fTriggerMask),// Int_t - Trigger mask
100 fRebin(o.fRebin), // Int_t - Rebinning factor
101 fCutEdges(o.fCutEdges), // Bool_t - Whether to cut edges when rebinning
102 fSymmetrice(o.fSymmetrice),
103 fCorrEmpty(o.fCorrEmpty),
104 fUseROOTProj(o.fUseROOTProj),
105 fTriggerEff(o.fTriggerEff),
106 fTriggerEff0(o.fTriggerEff0),
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)
118 DGUARD(fDebug, 3,"Copy CTOR of AliBasedNdetaTask");
121 //____________________________________________________________________
122 AliBasedNdetaTask::~AliBasedNdetaTask()
127 DGUARD(fDebug,3,"Destruction of AliBasedNdetaTask");
140 //________________________________________________________________________
142 AliBasedNdetaTask::SetDebugLevel(Int_t lvl)
144 AliAnalysisTaskSE::SetDebugLevel(lvl);
145 for (Int_t i = 0; i < fListOfCentralities->GetEntries(); i++) {
147 static_cast<CentralityBin*>(fListOfCentralities->At(i));
148 bin->SetDebugLevel(lvl);
152 //________________________________________________________________________
154 AliBasedNdetaTask::SetCentralityAxis(UShort_t n, Short_t* bins)
156 DGUARD(fDebug,3,"Set centrality axis, %d bins", n);
158 fCentAxis = new TAxis();
159 fCentAxis->SetName("centAxis");
160 fCentAxis->SetTitle("Centrality [%]");
163 for (UShort_t i = 0; i <= n; i++)
164 dbins[i] = (bins[i] == 100 ? 100.1 : bins[i]);
165 fCentAxis->Set(n, dbins.GetArray());
168 //________________________________________________________________________
170 AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
173 // Add a centrality bin
179 DGUARD(fDebug,3,"Add a centrality bin [%d,%d] @ %d", low, high, at);
180 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
182 Error("AddCentralityBin",
183 "Failed to create centrality bin for %s [%d,%d] @ %d",
184 GetName(), low, high, at);
187 bin->SetDebugLevel(fDebug);
188 fListOfCentralities->AddAtAndExpand(bin, at);
191 //________________________________________________________________________
192 AliBasedNdetaTask::CentralityBin*
193 AliBasedNdetaTask::MakeCentralityBin(const char* name,
194 Short_t low, Short_t high) const
197 // Make a centrality bin
200 // name Name used for histograms
201 // low Low cut in percent
202 // high High cut in percent
205 // A newly created centrality bin
207 DGUARD(fDebug,3,"Make a centrality bin %s [%d,%d]", name, low, high);
208 return new CentralityBin(name, low, high);
211 #define TESTAPPEND(SCHEME,BIT,STRING) \
212 do { if (!(SCHEME & BIT)) break; \
213 if (!s.IsNull()) s.Append(","); s.Append(STRING); } while(false)
215 //________________________________________________________________________
217 AliBasedNdetaTask::NormalizationSchemeString(UShort_t scheme)
219 // Create a string from normalization scheme bits
225 if (scheme == kFull) {
229 TESTAPPEND(scheme, kEventLevel, "EVENT");
230 TESTAPPEND(scheme, kShape, "SHAPE");
231 TESTAPPEND(scheme, kBackground, "BACKGROUND");
232 TESTAPPEND(scheme, kTriggerEfficiency, "TRIGGER");
233 TESTAPPEND(scheme, kZeroBin, "ZEROBIN");
237 //________________________________________________________________________
239 AliBasedNdetaTask::ParseNormalizationScheme(const char* what)
245 TObjArray* token = twhat.Tokenize(" ,|");
247 while ((opt = static_cast<TObjString*>(next()))) {
248 TString s(opt->GetString());
249 if (s.IsNull()) continue;
252 case '-': add = false; // Fall through
253 case '+': s.Remove(0,1); // Remove character
256 if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
257 else if (s.CompareTo("SHAPE") == 0) bit = kShape;
258 else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
259 else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
260 else if (s.CompareTo("FULL") == 0) bit = kFull;
261 else if (s.CompareTo("NONE") == 0) bit = kNone;
262 else if (s.CompareTo("ZEROBIN") == 0) bit = kZeroBin;
264 ::Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
265 if (add) scheme |= bit;
271 //________________________________________________________________________
273 AliBasedNdetaTask::SetNormalizationScheme(const char* what)
276 // Set normalisation scheme
278 DGUARD(fDebug,3,"Set the normalization scheme: %s", what);
279 SetNormalizationScheme(ParseNormalizationScheme(what));
281 //________________________________________________________________________
283 AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme)
285 DGUARD(fDebug,3,"Set the normalization scheme: 0x%x", scheme);
286 fNormalizationScheme = scheme;
287 if (fSchemeString) delete fSchemeString;
288 fSchemeString = AliForwardUtil::MakeParameter("scheme", scheme);
290 //________________________________________________________________________
292 AliBasedNdetaTask::SetTriggerMask(const char* mask)
295 // Set the trigger maskl
300 DGUARD(fDebug,3,"Set the trigger mask: %s", mask);
301 SetTriggerMask(AliAODForwardMult::MakeTriggerMask(mask));
303 //________________________________________________________________________
305 AliBasedNdetaTask::SetTriggerMask(UShort_t mask)
307 DGUARD(fDebug,3,"Set the trigger mask: 0x%0x", mask);
309 if (fTriggerString) delete fTriggerString;
310 fTriggerString = AliForwardUtil::MakeParameter("trigger", fTriggerMask);
313 //________________________________________________________________________
315 AliBasedNdetaTask::SetShapeCorrection(const TH2F* c)
318 // Set the shape correction (a.k.a., track correction) for selected
324 DGUARD(fDebug,3,"Set the shape correction: %p", c);
326 fShapeCorr = static_cast<TH2F*>(c->Clone());
327 fShapeCorr->SetDirectory(0);
330 //________________________________________________________________________
332 AliBasedNdetaTask::InitializeCentBins()
334 if (fListOfCentralities->GetEntries() > 0) return;
336 // Automatically add 'all' centrality bin if nothing has been defined.
337 AddCentralityBin(0, 0, 0);
338 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
339 const TArrayD* bins = fCentAxis->GetXbins();
340 Int_t nbin = fCentAxis->GetNbins();
341 for (Int_t i = 0; i < nbin; i++)
342 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
346 //________________________________________________________________________
348 AliBasedNdetaTask::UserCreateOutputObjects()
351 // Create output objects.
353 // This is called once per slave process
355 DGUARD(fDebug,1,"Create user ouput object");
357 fSums->SetName(Form("%s_sums", GetName()));
360 InitializeCentBins();
361 if (fCentAxis) fSums->Add(fCentAxis);
363 fSums->Add(AliForwardUtil::MakeParameter("alirootRev",
364 AliForwardUtil::AliROOTRevision()));
365 fSums->Add(AliForwardUtil::MakeParameter("alirootBranch",
366 AliForwardUtil::AliROOTBranch()));
368 // Centrality histogram
369 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
370 fCent->SetDirectory(0);
374 // Loop over centrality bins
375 TIter next(fListOfCentralities);
376 CentralityBin* bin = 0;
377 while ((bin = static_cast<CentralityBin*>(next())))
378 bin->CreateOutputObjects(fSums, fTriggerMask);
381 // Post data for ALL output slots >0 here, to get at least an empty
386 //____________________________________________________________________
388 AliBasedNdetaTask::UserExec(Option_t *)
391 // Process a single event
397 DGUARD(fDebug,1,"Analyse the AOD event");
398 AliAODEvent* aod = AliForwardUtil::GetAODEvent(this);
402 TObject* obj = aod->FindListObject("Forward");
404 AliWarning("No forward object found");
407 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
409 // Fill centrality histogram
410 Float_t cent = forward->GetCentrality();
413 // Get the histogram(s)
414 TH2D* data = GetHistogram(aod, false);
415 TH2D* dataMC = GetHistogram(aod, true);
417 Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
418 !forward->IsTriggerBits(AliAODForwardMult::kNClusterGt0));
421 // Loop over centrality bins
422 CentralityBin* allBin =
423 static_cast<CentralityBin*>(fListOfCentralities->At(0));
424 allBin->ProcessEvent(forward, fTriggerMask, isZero,
425 fVtxMin, fVtxMax, data, dataMC);
427 // Find this centrality bin
428 if (fCentAxis && fCentAxis->GetNbins() > 0) {
429 Int_t icent = fCentAxis->FindBin(cent);
430 CentralityBin* thisBin = 0;
431 if (icent >= 1 && icent <= fCentAxis->GetNbins())
432 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
434 thisBin->ProcessEvent(forward, fTriggerMask, isZero, fVtxMin, fVtxMax,
438 // Here, we get the update
440 fSNNString = AliForwardUtil::MakeParameter("sNN", forward->GetSNN());
441 fSysString = AliForwardUtil::MakeParameter("sys", forward->GetSystem());
443 fSums->Add(fSNNString);
444 fSums->Add(fSysString);
445 fSums->Add(fSchemeString);
446 fSums->Add(fTriggerString);
453 //________________________________________________________________________
455 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
456 const char* title, const char* ytitle)
459 // Set histogram graphical options, etc.
462 // h Histogram to modify
463 // colour Marker color
464 // marker Marker style
465 // title Title of histogram
466 // ytitle Title on y-axis.
469 h->SetMarkerColor(colour);
470 h->SetMarkerStyle(marker);
471 h->SetMarkerSize(marker == 29 || marker == 30 ? 1.2 : 1);
473 h->SetYTitle(ytitle);
474 h->GetXaxis()->SetTitleFont(132);
475 h->GetXaxis()->SetLabelFont(132);
476 h->GetXaxis()->SetNdivisions(10);
477 h->GetYaxis()->SetTitleFont(132);
478 h->GetYaxis()->SetLabelFont(132);
479 h->GetYaxis()->SetNdivisions(10);
480 h->GetYaxis()->SetDecimals();
484 //________________________________________________________________________
486 AliBasedNdetaTask::ScaleToCoverage(TH2D* copy, const TH1D* norm)
488 // Normalize to the acceptance -
489 // dndeta->Divide(accNorm);
490 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
491 Double_t a = norm->GetBinContent(i);
492 for (Int_t j = 1; j <= copy->GetNbinsY(); j++) {
494 copy->SetBinContent(i,j,0);
495 copy->SetBinError(i,j,0);
498 Double_t c = copy->GetBinContent(i, j);
499 Double_t e = copy->GetBinError(i, j);
500 copy->SetBinContent(i, j, c / a);
501 copy->SetBinError(i, j, e / a);
505 //________________________________________________________________________
507 AliBasedNdetaTask::ScaleToCoverage(TH1D* copy, const TH1D* norm)
509 // Normalize to the acceptance -
510 // dndeta->Divide(accNorm);
511 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
512 Double_t a = norm->GetBinContent(i);
514 copy->SetBinContent(i,0);
515 copy->SetBinError(i,0);
518 Double_t c = copy->GetBinContent(i);
519 Double_t e = copy->GetBinError(i);
520 copy->SetBinContent(i, c / a);
521 copy->SetBinError(i, e / a);
525 //________________________________________________________________________
527 AliBasedNdetaTask::ProjectX(const TH2D* h,
536 // Project onto the X axis
541 // firstbin First bin to use
542 // lastbin Last bin to use
543 // error Whether to calculate errors
546 // Newly created histogram or null
550 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
552 TAxis* xaxis = h->GetXaxis();
553 TAxis* yaxis = h->GetYaxis();
554 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
555 xaxis->GetXmin(), xaxis->GetXmax());
556 static_cast<const TAttLine*>(h)->Copy(*ret);
557 static_cast<const TAttFill*>(h)->Copy(*ret);
558 static_cast<const TAttMarker*>(h)->Copy(*ret);
559 ret->GetXaxis()->ImportAttributes(xaxis);
561 Int_t first = firstbin;
562 Int_t last = lastbin;
563 if (first < 0) first = 1;
564 else if (first >= yaxis->GetNbins()+2) first = yaxis->GetNbins()+1;
565 if (last < 0) last = yaxis->GetNbins();
566 else if (last >= yaxis->GetNbins()+2) last = yaxis->GetNbins()+1;
567 if (last-first < 0) {
568 AliWarningGeneral("AliBasedNdetaTask",
569 Form("Nothing to project [%d,%d]", first, last));
575 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
576 Int_t ybins = (last-first+1);
577 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
578 Double_t content = 0;
583 for (Int_t ybin = first; ybin <= last; ybin++) {
584 Double_t c1 = h->GetCellContent(xbin, ybin);
585 Double_t e1 = h->GetCellError(xbin, ybin);
588 if (c1 < 1e-12) continue;
598 if(content > 0 && nbins > 0) {
599 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
601 AliWarningGeneral(ret->GetName(),
602 Form("factor @ %d is %d/%d -> %f",
603 xbin, ybins, nbins, factor));
606 // Calculate weighted average
607 ret->SetBinContent(xbin, content * factor);
608 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
611 ret->SetBinContent(xbin, factor * content);
618 //________________________________________________________________________
620 AliBasedNdetaTask::Terminate(Option_t *)
623 // Called at end of event processing..
625 // This is called once in the master
630 // Draw result to screen, or perform fitting, normalizations Called
631 // once at the end of the query
632 DGUARD(fDebug,1,"Process final merged results");
634 fSums = dynamic_cast<TList*> (GetOutputData(1));
636 AliError("Could not retrieve TList fSums");
641 fOutput->SetName(Form("%s_result", GetName()));
644 fSNNString = fSums->FindObject("sNN");
645 fSysString = fSums->FindObject("sys");
646 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
647 fSchemeString = fSums->FindObject("scheme");
648 fTriggerString = fSums->FindObject("trigger");
650 if(fSysString && fSNNString &&
651 fSysString->GetUniqueID() == AliForwardUtil::kPP)
652 LoadNormalizationData(fSysString->GetUniqueID(),
653 fSNNString->GetUniqueID());
655 InitializeCentBins();
657 // Print before we loop
660 // Loop over centrality bins
661 TIter next(fListOfCentralities);
662 CentralityBin* bin = 0;
663 gStyle->SetPalette(1);
664 THStack* dndetaStack = new THStack("dndeta", "dN/d#eta");
665 THStack* dndetaStackRebin = new THStack(Form("dndeta_rebin%02d", fRebin),
667 THStack* dndetaMCStack = new THStack("dndetaMC", "dN_{ch}/d#eta");
668 THStack* dndetaMCStackRebin = new THStack(Form("dndetaMC_rebin%02d", fRebin),
672 TList* truthlist = 0;
674 if (fFinalMCCorrFile.Contains(".root")) {
675 TFile* ftest = TFile::Open(fFinalMCCorrFile.Data());
677 mclist = dynamic_cast<TList*>(ftest->Get(Form("%sResults",GetName())));
678 truthlist = dynamic_cast<TList*>(ftest->Get("MCTruthResults"));
681 AliWarning("MC analysis file invalid - no final MC correction possible");
683 Int_t style = GetMarker();
684 Int_t color = GetColor();
686 AliInfo(Form("Marker style=%d, color=%d", style, color));
687 while ((bin = static_cast<CentralityBin*>(next()))) {
689 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr,
690 fTriggerEff, fTriggerEff0,
691 fSymmetrice, fRebin, fUseROOTProj, fCorrEmpty, fCutEdges,
692 fTriggerMask, style, color, mclist, truthlist);
693 if (fCentAxis && bin->IsAllBin()) continue;
694 TH1* dndeta = bin->GetResult(0, false, "");
695 TH1* dndetaSym = bin->GetResult(0, true, "");
696 TH1* dndetaMC = bin->GetResult(0, false, "MC");
697 TH1* dndetaMCSym = bin->GetResult(0, true, "MC");
698 if (dndeta) dndetaStack->Add(dndeta);
699 if (dndetaSym) dndetaStack->Add(dndetaSym);
700 if (dndetaMC) dndetaMCStack->Add(dndetaMC);
701 if (dndetaMCSym) dndetaMCStack->Add(dndetaMCSym);
703 dndeta = bin->GetResult(fRebin, false, "");
704 dndetaSym = bin->GetResult(fRebin, true, "");
705 dndetaMC = bin->GetResult(fRebin, false, "MC");
706 dndetaMCSym = bin->GetResult(fRebin, true, "MC");
707 if (dndeta) dndetaStackRebin->Add(dndeta);
708 if (dndetaSym) dndetaStackRebin->Add(dndetaSym);
709 if (dndetaMC) dndetaMCStackRebin->Add(dndetaMC);
710 if (dndetaMCSym) dndetaMCStackRebin->Add(dndetaMCSym);
714 fOutput->Add(dndetaStack);
716 // If available output rebinned stack
717 if (!dndetaStackRebin->GetHists() ||
718 dndetaStackRebin->GetHists()->GetEntries() <= 0) {
719 AliWarning("No rebinned histograms found");
720 delete dndetaStackRebin;
721 dndetaStackRebin = 0;
723 if (dndetaStackRebin) fOutput->Add(dndetaStackRebin);
725 // If available, output track-ref stack
726 if (!dndetaMCStack->GetHists() ||
727 dndetaMCStack->GetHists()->GetEntries() <= 0) {
728 AliWarning("No MC histograms found");
729 delete dndetaMCStack;
732 if (dndetaMCStack) fOutput->Add(dndetaMCStack);
734 // If available, output rebinned track-ref stack
735 if (!dndetaMCStackRebin->GetHists() ||
736 dndetaMCStackRebin->GetHists()->GetEntries() <= 0) {
737 AliWarning("No rebinned MC histograms found");
738 delete dndetaMCStackRebin;
739 dndetaMCStackRebin = 0;
741 if (dndetaMCStackRebin) fOutput->Add(dndetaMCStackRebin);
743 // Output collision energy string
745 UShort_t sNN = fSNNString->GetUniqueID();
746 TNamed* sNNObj = new TNamed(fSNNString->GetName(),
747 AliForwardUtil::CenterOfMassEnergyString(sNN));
748 sNNObj->SetUniqueID(sNN);
749 fOutput->Add(sNNObj); // fSNNString->Clone());
752 // Output collision system string
754 UShort_t sys = fSysString->GetUniqueID();
755 TNamed* sysObj = new TNamed(fSysString->GetName(),
756 AliForwardUtil::CollisionSystemString(sys));
757 sysObj->SetUniqueID(sys);
758 fOutput->Add(sysObj); // fSysString->Clone());
761 // Output centrality axis
762 if (fCentAxis) fOutput->Add(fCentAxis);
764 // Output trigger string
765 if (fTriggerString) {
766 UShort_t mask = fTriggerString->GetUniqueID();
767 TNamed* maskObj = new TNamed(fTriggerString->GetName(),
768 AliAODForwardMult::GetTriggerString(mask));
769 maskObj->SetUniqueID(mask);
770 fOutput->Add(maskObj); // fTriggerString->Clone());
773 // Normalization string
775 UShort_t scheme = fSchemeString->GetUniqueID();
776 TNamed* schemeObj = new TNamed(fSchemeString->GetName(),
777 NormalizationSchemeString(scheme));
778 schemeObj->SetUniqueID(scheme);
779 fOutput->Add(schemeObj); // fSchemeString->Clone());
782 // Output vertex axis
783 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
784 vtxAxis->SetName("vtxAxis");
785 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
786 fOutput->Add(vtxAxis);
788 // Output trigger efficiency and shape correction
789 fOutput->Add(AliForwardUtil::MakeParameter("triggerEff", fTriggerEff));
790 fOutput->Add(AliForwardUtil::MakeParameter("triggerEff0", fTriggerEff0));
791 if (fShapeCorr) fOutput->Add(fShapeCorr);
793 TNamed* options = new TNamed("options","");
795 str.Append(Form("Edges %scut, ", fCutEdges ? "" : "not "));
796 str.Append(Form("Empty bins %scorrected for, ", fCorrEmpty ? "" : "not "));
797 str.Append(Form("TH2::ProjectionX %sused", fUseROOTProj ? "" : "not "));
798 options->SetTitle(str);
799 fOutput->Add(options);
801 PostData(2, fOutput);
803 //________________________________________________________________________
805 AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
807 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
808 DGUARD(fDebug,1,"Load the normalization data for sys=%d, energy=%d",
812 if(energy == 7000) snn.Form("7000");
813 if(energy == 2750) snn.Form("2750");
815 if(fShapeCorr && (fTriggerEff != 1)) {
816 AliInfo("Objects already set for normalization - no action taken");
820 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWGLF/FORWARD/corrections/"
821 "Normalization/normalizationHists_%s_%s.root",
822 type.Data(),snn.Data()));
824 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
829 if ((fNormalizationScheme & kShape) && !fShapeCorr) {
830 TString trigName("All");
831 if (fTriggerMask == AliAODForwardMult::kInel ||
832 fTriggerMask == AliAODForwardMult::kNClusterGt0)
834 else if (fTriggerMask == AliAODForwardMult::kNSD)
836 else if (fTriggerMask == AliAODForwardMult::kInelGt0)
837 trigName = "InelGt0";
839 AliWarning(Form("Normalization for trigger %s not known, using all",
840 AliAODForwardMult::GetTriggerString(fTriggerMask)));
843 TString shapeCorName(Form("h%sNormalization", trigName.Data()));
844 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
845 if (shapeCor) SetShapeCorrection(shapeCor);
847 AliWarning(Form("No shape correction found for %s", trigName.Data()));
851 // Trigger efficiency
852 TString effName(Form("%sTriggerEff",
853 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
854 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
855 fTriggerMask == AliAODForwardMult::kInelGt0 ?
858 Double_t trigEff = 1;
859 if (fNormalizationScheme & kTriggerEfficiency) {
860 TObject* eff = fin->Get(effName);
861 if (eff) AliForwardUtil::GetParameter(eff, trigEff);
863 if (fTriggerEff != 1) SetTriggerEff(trigEff);
864 if (fTriggerEff < 0) fTriggerEff = 1;
866 // Trigger efficiency
867 TString eff0Name(Form("%sTriggerEff0",
868 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
869 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
870 fTriggerMask == AliAODForwardMult::kInelGt0 ?
873 Double_t trigEff0 = 1;
874 if (fNormalizationScheme & kTriggerEfficiency) {
875 TObject* eff = fin->Get(eff0Name);
876 if (eff) AliForwardUtil::GetParameter(eff, trigEff0);
878 if (fTriggerEff0 != 1) SetTriggerEff0(trigEff0);
879 if (fTriggerEff0 < 0) fTriggerEff0 = 1;
882 // Rescale the shape correction by the trigger efficiency
884 AliWarning(Form("Rescaling shape correction by trigger efficiency: "
885 "1/E_X=1/%f", trigEff));
886 fShapeCorr->Scale(1. / trigEff);
890 if (fShapeCorr && fTriggerEff) AliInfo("Loaded objects for normalization.");
894 //________________________________________________________________________
896 AliBasedNdetaTask::Print(Option_t*) const
901 std::cout << this->ClassName() << ": " << this->GetName() << "\n"
903 << " Trigger: " << (fTriggerString ?
904 fTriggerString->GetTitle() :
906 << " Vertex range: [" << fVtxMin << ":"
908 << " Rebin factor: " << fRebin << "\n"
909 << " Cut edges: " << fCutEdges << "\n"
910 << " Symmertrice: " << fSymmetrice << "\n"
911 << " Use TH2::ProjectionX: " << fUseROOTProj << "\n"
912 << " Correct for empty: " << fCorrEmpty << "\n"
913 << " Normalization scheme: " << (fSchemeString ?
914 fSchemeString->GetTitle() :
916 << " Trigger efficiency: " << fTriggerEff << "\n"
917 << " Bin-0 Trigger efficiency: " << fTriggerEff0 << "\n"
918 << " Shape correction: " << (fShapeCorr ?
919 fShapeCorr->GetName() :
921 << " sqrt(s_NN): " << (fSNNString ?
922 fSNNString->GetTitle() :
924 << " Collision system: " << (fSysString ?
925 fSysString->GetTitle() :
927 << " Centrality bins: " << (fCentAxis ? "" : "none");
929 Int_t nBins = fCentAxis->GetNbins();
930 const Double_t* bins = fCentAxis->GetXbins()->GetArray();
931 for (Int_t i = 0; i <= nBins; i++)
932 std::cout << (i==0 ? "" : "-") << bins[i];
934 std::cout << std::noboolalpha << std::endl;
938 //________________________________________________________________________
940 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
943 // Make a copy of the input histogram and rebin that histogram
946 // h Histogram to rebin
949 // New (rebinned) histogram
951 if (rebin <= 1) return 0;
953 Int_t nBins = h->GetNbinsX();
954 if(nBins % rebin != 0) {
955 AliWarningGeneral("AliBasedNdetaTask",
956 Form("Rebin factor %d is not a devisor of current number "
957 "of bins %d in the histogram %s",
958 rebin, nBins, h->GetName()));
963 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
964 h->GetName(), rebin)));
966 tmp->SetDirectory(0);
968 // The new number of bins
969 Int_t nBinsNew = nBins / rebin;
970 for(Int_t i = 1;i<= nBinsNew; i++) {
971 Double_t content = 0;
975 for(Int_t j = 1; j<=rebin;j++) {
976 Int_t bin = (i-1)*rebin + j;
977 Double_t c = h->GetBinContent(bin);
978 if (c <= 0) continue;
981 if (h->GetBinContent(bin+1)<=0 ||
982 h->GetBinContent(bin-1)<=0) {
984 AliWarningGeneral("AliBasedNdetaTask",
985 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
986 bin, c, h->GetName(),
987 bin+1, h->GetBinContent(bin+1),
988 bin-1, h->GetBinContent(bin-1)));
993 Double_t e = h->GetBinError(bin);
994 Double_t w = 1 / (e*e); // 1/c/c
1001 if(content > 0 && nbins > 0) {
1002 tmp->SetBinContent(i, wsum / sumw);
1003 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
1010 //__________________________________________________________________
1012 AliBasedNdetaTask::Symmetrice(const TH1* h)
1015 // Make an extension of @a h to make it symmetric about 0
1018 // h Histogram to symmertrice
1021 // Symmetric extension of @a h
1023 Int_t nBins = h->GetNbinsX();
1024 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
1025 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
1027 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
1028 s->SetMarkerColor(h->GetMarkerColor());
1029 s->SetMarkerSize(h->GetMarkerSize());
1030 s->SetMarkerStyle(FlipHollowStyle(h->GetMarkerStyle()));
1031 s->SetFillColor(h->GetFillColor());
1032 s->SetFillStyle(h->GetFillStyle());
1035 // Find the first and last bin with data
1036 Int_t first = nBins+1;
1038 for (Int_t i = 1; i <= nBins; i++) {
1039 if (h->GetBinContent(i) <= 0) continue;
1040 first = TMath::Min(first, i);
1041 last = TMath::Max(last, i);
1044 Double_t xfirst = h->GetBinCenter(first-1);
1045 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
1046 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
1047 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
1048 s->SetBinContent(j, h->GetBinContent(i));
1049 s->SetBinError(j, h->GetBinError(i));
1051 // Fill in overlap bin
1052 s->SetBinContent(l2+1, h->GetBinContent(first));
1053 s->SetBinError(l2+1, h->GetBinError(first));
1057 //__________________________________________________________________
1059 AliBasedNdetaTask::GetMarkerStyle(UShort_t bits)
1061 Int_t base = bits & (0xFE);
1062 Bool_t hollow = bits & kHollow;
1064 case kCircle: return (hollow ? 24 : 20);
1065 case kSquare: return (hollow ? 25 : 21);
1066 case kUpTriangle: return (hollow ? 26 : 22);
1067 case kDownTriangle: return (hollow ? 32 : 23);
1068 case kDiamond: return (hollow ? 27 : 33);
1069 case kCross: return (hollow ? 28 : 34);
1070 case kStar: return (hollow ? 30 : 29);
1074 //__________________________________________________________________
1076 AliBasedNdetaTask::GetMarkerBits(Int_t style)
1080 case 24: case 25: case 26: case 27: case 28: case 30: case 32:
1081 bits |= kHollow; break;
1084 case 20: case 24: bits |= kCircle; break;
1085 case 21: case 25: bits |= kSquare; break;
1086 case 22: case 26: bits |= kUpTriangle; break;
1087 case 23: case 32: bits |= kDownTriangle; break;
1088 case 27: case 33: bits |= kDiamond; break;
1089 case 28: case 34: bits |= kCross; break;
1090 case 29: case 30: bits |= kStar; break;
1094 //__________________________________________________________________
1096 AliBasedNdetaTask::FlipHollowStyle(Int_t style)
1098 UShort_t bits = GetMarkerBits(style);
1099 Int_t ret = GetMarkerStyle(bits ^ kHollow);
1103 //====================================================================
1105 AliBasedNdetaTask::Sum::Init(TList* list, const TH2D* data, Int_t col)
1107 DGUARD(fDebug,1,"Initializing sums with %s", data->GetName());
1108 TString n(GetHistName(0));
1109 TString n0(GetHistName(1));
1110 const char* postfix = GetTitle();
1112 fSum = static_cast<TH2D*>(data->Clone(n));
1113 if (postfix) fSum->SetTitle(Form("%s (%s)", data->GetTitle(), postfix));
1114 fSum->SetDirectory(0);
1115 fSum->SetMarkerColor(col);
1116 fSum->SetMarkerStyle(GetMarkerStyle(kCircle|kSolid));
1120 fSum0 = static_cast<TH2D*>(data->Clone(n0));
1122 fSum0->SetTitle(Form("%s 0-bin (%s)", data->GetTitle(), postfix));
1124 fSum0->SetTitle(Form("%s 0-bin", data->GetTitle()));
1125 fSum0->SetDirectory(0);
1126 fSum0->SetMarkerColor(col);
1127 fSum0->SetMarkerStyle(GetMarkerStyle(kCross|kHollow));
1131 fEvents = new TH1I(GetHistName(2), "Event types", 2, -.5, 1.5);
1132 fEvents->SetDirectory(0);
1133 fEvents->GetXaxis()->SetBinLabel(1, "Non-zero");
1134 fEvents->GetXaxis()->SetBinLabel(2, "Zero");
1138 //____________________________________________________________________
1140 AliBasedNdetaTask::Sum::GetHistName(const char* name, Int_t what, const char* post)
1143 if (what == 1) n.Append("0");
1144 else if (what == 2) n.Append("Events");
1145 if (post && post[0] != '\0') n.Append(post);
1149 //____________________________________________________________________
1151 AliBasedNdetaTask::Sum::GetHistName(Int_t what) const
1153 return GetHistName(GetName(), what, GetTitle());
1156 //____________________________________________________________________
1158 AliBasedNdetaTask::Sum::Add(const TH2D* data, Bool_t isZero)
1160 DGUARD(fDebug,2,"Adding %s to sums", data->GetName());
1161 if (isZero) fSum0->Add(data);
1162 else fSum->Add(data);
1163 fEvents->Fill(isZero ? 1 : 0);
1166 //____________________________________________________________________
1168 AliBasedNdetaTask::Sum::CalcSum(TList* output,
1174 Bool_t corrEmpty) const
1176 DGUARD(fDebug,2,"Calculating final summed histogram %s", fSum->GetName());
1178 TH2D* ret = static_cast<TH2D*>(fSum->Clone(fSum->GetName()));
1179 ret->SetDirectory(0);
1181 Int_t n = Int_t(fEvents->GetBinContent(1));
1182 Int_t n0 = Int_t(fEvents->GetBinContent(2));
1184 AliInfoF("Adding histograms %s(%d) and %s(%d) with weights %f and %f resp.",
1185 fSum0->GetName(), n, fSum->GetName(), n0, 1./epsilon, 1./epsilon0);
1186 DMSG(fDebug,2, "Adding histograms %s and %s with weights %f and %f resp.",
1187 fSum0->GetName(), fSum->GetName(), 1./epsilon, 1./epsilon0);
1188 // Generate merged histogram
1189 ret->Add(fSum0, fSum, 1. / epsilon0, 1. / epsilon);
1190 ntotal = n / epsilon + n0 / epsilon0;
1192 TList* out = new TList;
1194 const char* postfix = GetTitle();
1195 if (!postfix) postfix = "";
1196 out->SetName(Form("partial%s", postfix));
1199 // Now make copies, normalize them, and store in output list
1200 TH2D* sumCopy = static_cast<TH2D*>(fSum->Clone("sum"));
1201 TH2D* sum0Copy = static_cast<TH2D*>(fSum0->Clone("sum0"));
1202 TH2D* retCopy = static_cast<TH2D*>(ret->Clone("sumAll"));
1203 sumCopy->SetMarkerStyle(FlipHollowStyle(marker));
1204 sumCopy->SetDirectory(0);
1205 sum0Copy->SetMarkerStyle(GetMarkerStyle(GetMarkerBits(marker)+4));
1206 sum0Copy->SetDirectory(0);
1207 retCopy->SetMarkerStyle(marker);
1208 retCopy->SetDirectory(0);
1210 Int_t nY = fSum->GetNbinsY();
1211 Int_t o = 0; // nY+1;
1212 TH1D* norm = ProjectX(fSum, "norm", o, o, rootProj, corrEmpty, false);
1213 TH1D* norm0 = ProjectX(fSum0, "norm0", o, o, rootProj, corrEmpty, false);
1214 TH1D* normAll = ProjectX(ret, "normAll", o, o, rootProj, corrEmpty, false);
1215 norm->SetDirectory(0);
1216 norm0->SetDirectory(0);
1217 normAll->SetDirectory(0);
1219 ScaleToCoverage(sumCopy, norm);
1220 ScaleToCoverage(sum0Copy, norm0);
1221 ScaleToCoverage(retCopy, normAll);
1223 TH1D* sumCopyPx = ProjectX(sumCopy, "average", 1, nY,rootProj,corrEmpty);
1224 TH1D* sum0CopyPx = ProjectX(sum0Copy, "average0", 1, nY,rootProj,corrEmpty);
1225 TH1D* retCopyPx = ProjectX(retCopy, "averageAll", 1, nY,rootProj,corrEmpty);
1226 sumCopyPx->SetDirectory(0);
1227 sum0CopyPx->SetDirectory(0);
1228 retCopyPx->SetDirectory(0);
1230 TH1D* phi = ProjectX(fSum, "phi", nY+1, nY+1,rootProj,corrEmpty);
1231 TH1D* phi0 = ProjectX(fSum0, "phi0", nY+1, nY+1,rootProj,corrEmpty);
1232 TH1D* phiAll = ProjectX(ret, "phiAll", nY+1, nY+1,rootProj,corrEmpty);
1233 phi->SetDirectory(0);
1234 phi0->SetDirectory(0);
1235 phiAll->SetDirectory(0);
1237 // Scale our 1D histograms
1238 sumCopyPx->Scale(1., "width");
1239 sum0CopyPx->Scale(1., "width");
1240 retCopyPx->Scale(1., "width");
1242 AliInfo(Form("Maximum %f,%f changed to %f", sumCopyPx->GetMaximum(),
1243 sum0CopyPx->GetMaximum(), retCopyPx->GetMaximum()));
1245 // Scale the normalization - they should be 1 at the maximum
1246 norm->Scale(n > 0 ? 1. / n : 1);
1247 norm0->Scale(n0 > 0 ? 1. / n0 : 1);
1248 normAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1253 out->Add(sumCopyPx);
1254 out->Add(sum0CopyPx);
1255 out->Add(retCopyPx);
1263 AliInfoF("Returning (1/%f * %s + 1/%f * %s), "
1264 "1/%f * %d + 1/%f * %d = %d",
1265 epsilon0, fSum0->GetName(), epsilon, fSum->GetName(),
1266 epsilon0, n0, epsilon, n, int(ntotal));
1268 for (Int_t i = 1; i <= ret->GetNbinsX(); i++) {
1269 Double_t nc = sum->GetBinContent(i, 0);
1270 Double_t nc0 = sum0->GetBinContent(i, 0);
1271 ret->SetBinContent(i, 0, nc + nc0); // Just count events
1278 //====================================================================
1279 AliBasedNdetaTask::CentralityBin::CentralityBin()
1288 fDoFinalMCCorrection(false),
1294 DGUARD(fDebug,3,"Default CTOR of AliBasedNdeta::CentralityBin");
1296 //____________________________________________________________________
1297 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
1298 Short_t low, Short_t high)
1307 fDoFinalMCCorrection(false),
1314 // name Name used for histograms (e.g., Forward)
1315 // low Lower centrality cut in percent
1316 // high Upper centrality cut in percent
1318 DGUARD(fDebug,3,"Named CTOR of AliBasedNdeta::CentralityBin: %s [%3d,%3d]",
1320 if (low <= 0 && high <= 0) {
1323 SetTitle("All centralities");
1328 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
1331 //____________________________________________________________________
1332 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
1338 fTriggers(o.fTriggers),
1341 fDoFinalMCCorrection(o.fDoFinalMCCorrection),
1348 // other Object to copy from
1350 DGUARD(fDebug,3,"Copy CTOR of AliBasedNdeta::CentralityBin");
1352 //____________________________________________________________________
1353 AliBasedNdetaTask::CentralityBin::~CentralityBin()
1358 DGUARD(fDebug,3,"DTOR of AliBasedNdeta::CentralityBin");
1360 // if (fSums) fSums->Delete();
1361 // if (fOutput) fOutput->Delete();
1364 //____________________________________________________________________
1365 AliBasedNdetaTask::CentralityBin&
1366 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
1369 // Assignment operator
1372 // other Object to assign from
1375 // Reference to this
1377 DGUARD(fDebug,3,"Centrality bin assignment");
1378 if (&o == this) return *this;
1379 SetName(o.GetName());
1380 SetTitle(o.GetTitle());
1382 fOutput = o.fOutput;
1385 fTriggers = o.fTriggers;
1388 fDoFinalMCCorrection = o.fDoFinalMCCorrection;
1392 //____________________________________________________________________
1394 AliBasedNdetaTask::CentralityBin::GetColor(Int_t fallback) const
1396 if (IsAllBin()) return fallback;
1397 Float_t fc = (fLow+double(fHigh-fLow)/2) / 100;
1398 Int_t nCol = gStyle->GetNumberOfColors();
1399 Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
1400 Int_t col = gStyle->GetColorPalette(icol);
1403 //____________________________________________________________________
1405 AliBasedNdetaTask::CentralityBin::GetListName() const
1408 // Get the list name
1413 if (IsAllBin()) return "all";
1414 return Form("cent%03d_%03d", fLow, fHigh);
1416 //____________________________________________________________________
1418 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir, Int_t mask)
1421 // Create output objects
1426 DGUARD(fDebug,1,"Create centrality bin output objects");
1428 fSums->SetName(GetListName());
1432 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers", mask);
1433 fTriggers->SetDirectory(0);
1434 fSums->Add(fTriggers);
1436 //____________________________________________________________________
1438 AliBasedNdetaTask::CentralityBin::SetDebugLevel(Int_t lvl)
1441 if (fSum) fSum->fDebug = lvl;
1442 if (fSumMC) fSumMC->fDebug = lvl;
1445 //____________________________________________________________________
1447 AliBasedNdetaTask::CentralityBin::ReadSum(TList* list, bool mc)
1449 const char* post = (mc ? "MC" : "");
1450 TString sn = Sum::GetHistName(GetName(),0,post);
1451 TString sn0 = Sum::GetHistName(GetName(),1,post);
1452 TString ev = Sum::GetHistName(GetName(),2,post);
1453 TH2D* sum = static_cast<TH2D*>(list->FindObject(sn));
1454 TH2D* sum0 = static_cast<TH2D*>(list->FindObject(sn0));
1455 TH1I* events = static_cast<TH1I*>(list->FindObject(ev));
1456 if (!sum || !sum0 || !events) {
1457 AliWarningF("Failed to find one or more histograms: "
1458 "%s (%p) %s (%p) %s (%p)",
1464 Sum* ret = new Sum(GetName(), post);
1467 ret->fEvents = events;
1468 ret->fDebug = fDebug;
1469 if (mc) fSumMC = ret;
1475 //____________________________________________________________________
1477 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
1480 // Create sum histogram
1483 // data Data histogram to clone
1484 // mc (optional) MC histogram to clone
1486 DGUARD(fDebug,1,"Create centrality bin sums from %s",
1487 data ? data->GetName() : "(null)");
1489 fSum = new Sum(GetName(),"");
1490 fSum->Init(fSums, data, GetColor());
1491 fSum->fDebug = fDebug;
1494 // If no MC data is given, then do not create MC sum histogram
1497 fSumMC = new Sum(GetName(), "MC");
1498 fSumMC->Init(fSums, mc, GetColor());
1499 fSumMC->fDebug = fDebug;
1502 //____________________________________________________________________
1504 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
1506 Double_t vzMin, Double_t vzMax)
1509 // Check the trigger, vertex, and centrality
1515 // true if the event is to be used
1517 if (!forward) return false;
1519 DGUARD(fDebug,2,"Check the event");
1520 // We do not check for centrality here - it's already done
1521 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
1525 //____________________________________________________________________
1527 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
1528 Int_t triggerMask, Bool_t isZero,
1529 Double_t vzMin, Double_t vzMax,
1530 const TH2D* data, const TH2D* mc)
1536 // forward Forward data (for trigger, vertex, & centrality)
1537 // triggerMask Trigger mask
1538 // vzMin Minimum IP z coordinate
1539 // vzMax Maximum IP z coordinate
1540 // data Data histogram
1543 DGUARD(fDebug,1,"Process one event for %s a given centrality bin",
1544 data ? data->GetName() : "(null)");
1545 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
1547 if (!fSum) CreateSums(data, mc);
1549 fSum->Add(data, isZero);
1550 if (mc) fSumMC->Add(mc, isZero);
1553 //________________________________________________________________________
1555 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
1559 TString* text) const
1562 // Calculate normalization
1565 // t Trigger histogram
1566 // scheme Normaliztion scheme
1568 // ntotal On return, contains the number of events.
1570 DGUARD(fDebug,1,"Normalize centrality bin %s with %s",
1571 GetName(), t.GetName());
1572 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1573 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1574 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1575 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1576 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1577 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1578 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1579 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1580 Double_t nAccepted = ntotal;
1583 if (nTriggered <= 0.1) {
1584 AliError("Number of triggered events <= 0");
1587 if (nWithVertex <= 0.1) {
1588 AliError("Number of events with vertex <= 0");
1592 Double_t vtxEff = nWithVertex / nTriggered;
1593 Double_t scaler = 1;
1594 Double_t beta = nA + nC - 2*nE;
1597 TString rhs("N = N_acc");
1598 if (!(scheme & kZeroBin)) {
1599 if (scheme & kEventLevel) {
1600 ntotal = nAccepted / vtxEff;
1602 AliInfoF("Calculating event normalisation as\n"
1603 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1604 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1606 if (scheme & kBackground) {
1608 // s = --------- = ------------- = ------------
1609 // 1 - beta 1 - beta E_V 1 - beta N_V
1610 // --- ---- -------- ---- ---
1611 // E_V N_V N_V N_V N_T
1619 ntotal -= nAccepted * beta / nWithVertex;
1620 // This one is direct and correct.
1621 // scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1622 // A simpler expresion
1623 scaler /= (1 - beta / nTriggered); // 0.831631 -> 0.780689
1624 AliInfo(Form("Calculating event normalisation as\n"
1625 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1626 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1627 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1628 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1629 Int_t(nWithVertex), ntotal, scaler));
1630 rhs.Append("(1/eps_V - beta/N_vtx)");
1633 rhs.Append("/eps_V");
1635 if (scheme & kTriggerEfficiency) {
1638 AliInfo(Form("Correcting for trigger efficiency:\n"
1639 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1640 trigEff, Int_t(ntotal), ntotal / trigEff, scaler));
1641 rhs.Append("/eps_T");
1642 } // Trigger efficiency
1647 // N = N_A + 1/E_X * N_A / N_V (N_T - N_V - beta)
1648 // = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1649 // = N_A (1 + 1/E_X (1/E_V - 1 - beta / N_V))
1651 // s = N_A/N = 1 / (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1652 // = N_V / (N_V + 1/E_X (N_T - N_V - beta))
1654 if (!(scheme & kBackground)) beta = 0;
1655 ntotal = nAccepted * (1 + 1/trigEff * (nTriggered / nWithVertex - 1
1656 - beta / nWithVertex));
1657 scaler = nWithVertex / (nWithVertex +
1658 1/trigEff * (nTriggered-nWithVertex-beta));
1659 AliInfo(Form("Calculating event normalisation as\n"
1660 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1661 " N = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V)) = "
1662 "%d (1 + 1 / %f (%d / %d - 1 - %d / %d)) = %f (%f)",
1663 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1664 Int_t(nAccepted), trigEff, Int_t(nTriggered),
1665 Int_t(nWithVertex), Int_t(beta), Int_t(nWithVertex),
1667 rhs.Append("(1+1/eps_T(1/eps_V-1-beta/N_vtx))");
1671 text->Append(Form("%-40s = %d\n", "N_all", UInt_t(nAll)));
1672 text->Append(Form("%-40s = %d\n", "N_acc", UInt_t(nAccepted)));
1673 text->Append(Form("%-40s = %d\n", "N_trg", UInt_t(nTriggered)));
1674 text->Append(Form("%-40s = %d\n", "N_vtx", UInt_t(nWithVertex)));
1675 text->Append(Form("%-40s = %d\n", "N_B", UInt_t(nB)));
1676 text->Append(Form("%-40s = %d\n", "N_A", UInt_t(nA)));
1677 text->Append(Form("%-40s = %d\n", "N_C", UInt_t(nC)));
1678 text->Append(Form("%-40s = %d\n", "N_E", UInt_t(nE)));
1679 text->Append(Form("%-40s = %d\n", "beta = N_A + N_C - 2N_E",UInt_t(beta)));
1680 text->Append(Form("%-40s = %f\n", "eps_V = N_vtx/N_trg",vtxEff));
1681 text->Append(Form("%-40s = %f\n", "eps_T", trigEff));
1682 text->Append(Form("%-40s = %f\n", rhs.Data(), ntotal));
1686 " Total of %9d events for %s\n"
1687 " of these %9d have an offline trigger\n"
1688 " of these N_T = %9d has the selected trigger\n"
1689 " of these N_V = %9d has a vertex\n"
1690 " of these N_A = %9d were in the selected range\n"
1691 " Triggers by hardware type:\n"
1693 " N_ac = %9d (%d+%d)\n"
1695 " Vertex efficiency: %f\n"
1696 " Trigger efficiency: %f\n"
1697 " Total number of events: N = %f\n"
1698 " Scaler (N_A/N): %f\n"
1700 Int_t(nAll), GetTitle(), Int_t(nOffline),
1701 Int_t(nTriggered), Int_t(nWithVertex), Int_t(nAccepted),
1702 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1703 vtxEff, trigEff, ntotal, scaler, rhs.Data(), ntotal));
1707 //________________________________________________________________________
1709 AliBasedNdetaTask::CentralityBin::GetResultName(Int_t rebin,
1711 const char* postfix) const
1714 n = Form("dndeta%s%s",GetName(), postfix);
1715 if (rebin > 1) n.Append(Form("_rebin%02d", rebin));
1716 if (sym) n.Append("_mirror");
1719 //________________________________________________________________________
1721 AliBasedNdetaTask::CentralityBin::GetResult(Int_t rebin,
1723 const char* postfix) const
1726 AliWarning(Form("No output list defined in %s [%3d,%3d]", GetName(),
1730 TString n = GetResultName(rebin, sym, postfix);
1731 TObject* o = fOutput->FindObject(n.Data());
1733 // AliWarning(Form("Object %s not found in output list", n.Data()));
1736 return static_cast<TH1*>(o);
1739 //________________________________________________________________________
1741 AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
1742 const char* postfix,
1745 const TH2F* shapeCorr,
1756 // Generate the dN/deta result from input
1759 // sum Sum of 2D hists
1760 // postfix Post fix on names
1761 // rootProj Whether to use ROOT TH2::ProjectionX
1762 // corrEmpty Correct for empty bins
1763 // shapeCorr Shape correction to use
1764 // scaler Event-level normalization scaler
1765 // symmetrice Whether to make symmetric extensions
1766 // rebin Whether to rebin
1767 // cutEdges Whether to cut edges when rebinning
1769 DGUARD(fDebug,1,"Make centrality bin result from %s", sum->GetName());
1770 TH2D* copy = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s%s",
1771 GetName(), postfix)));
1772 Int_t nY = sum->GetNbinsY();
1773 Int_t o = (corrEmpty ? 0 : nY+1);
1774 TH1D* accNorm = ProjectX(sum, Form("norm%s%s",GetName(), postfix), o, o,
1775 rootProj, corrEmpty, false);
1776 accNorm->SetDirectory(0);
1778 // ---- Scale by shape correction ----------------------------------
1779 if (shapeCorr) copy->Divide(shapeCorr);
1780 else AliInfo("No shape correction specified, or disabled");
1782 // --- Normalize to the coverage -----------------------------------
1784 ScaleToCoverage(copy, accNorm);
1785 // --- Event-level normalization ---------------------------------
1786 copy->Scale(scaler);
1789 // --- Project on X axis -------------------------------------------
1790 TH1D* dndeta = ProjectX(copy, Form("dndeta%s%s",GetName(), postfix),
1791 1, nY, rootProj, corrEmpty);
1792 dndeta->SetDirectory(0);
1793 // Event-level normalization
1795 ScaleToCoverage(dndeta, accNorm);
1796 dndeta->Scale(scaler);
1798 dndeta->Scale(1., "width");
1799 copy->Scale(1., "width");
1801 TH1D* dndetaMCCorrection = 0;
1802 TList* centlist = 0;
1803 TH1D* dndetaMCtruth = 0;
1804 TList* truthcentlist = 0;
1806 // Possible final correction to <MC analysis> / <MC truth>
1808 centlist = static_cast<TList*> (mclist->FindObject(GetListName()));
1810 dndetaMCCorrection =
1811 static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s",
1812 GetName(), postfix)));
1814 truthcentlist =static_cast<TList*>(truthlist->FindObject(GetListName()));
1816 dndetaMCtruth =static_cast<TH1D*>(truthcentlist->FindObject("dndetaTruth"));
1818 if(dndetaMCCorrection && dndetaMCtruth) {
1819 AliInfo("Correcting with final MC correction");
1820 dndetaMCCorrection->Divide(dndetaMCtruth);
1821 dndetaMCCorrection->SetTitle("Final MC correction");
1822 dndetaMCCorrection->SetName("finalMCCorr");
1823 dndeta->Divide(dndetaMCCorrection);
1826 AliInfo("No final MC correction applied");
1828 // --- Set some histogram attributes -------------------------------
1830 Int_t rColor = GetColor(color);
1831 if (postfix && postfix[0] != '\0') post = Form(" (%s)", postfix);
1832 SetHistogramAttributes(dndeta, rColor, marker,
1833 Form("ALICE %s%s", GetName(), post.Data()));
1834 SetHistogramAttributes(accNorm, rColor, marker,
1835 Form("ALICE %s normalisation%s",
1836 GetName(), post.Data()));
1838 // --- Make symmetric extensions and rebinnings --------------------
1839 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1840 fOutput->Add(dndeta);
1841 fOutput->Add(accNorm);
1843 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1844 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1845 if (dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
1848 //________________________________________________________________________
1850 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1853 const TH2F* shapeCorr,
1868 // End of processing
1871 // sums List of sums
1872 // results Output list of results
1873 // shapeCorr Shape correction or nil
1874 // trigEff Trigger efficiency
1875 // symmetrice Whether to symmetrice the results
1876 // rebin Whether to rebin the results
1877 // corrEmpty Whether to correct for empty bins
1878 // cutEdges Whether to cut edges when rebinning
1879 // triggerMask Trigger mask
1881 DGUARD(fDebug,1,"End centrality bin procesing");
1883 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1885 AliError("Could not retrieve TList fSums");
1889 fOutput = new TList;
1890 fOutput->SetName(GetListName());
1891 fOutput->SetOwner();
1892 results->Add(fOutput);
1895 if (!ReadSum(fSums, false)) {
1896 AliInfo("This task did not produce any output");
1900 if (!fSumMC) ReadSum(fSums, true);
1902 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1905 AliError("Couldn't find histogram 'triggers' in list");
1909 // --- Get normalization scaler ------------------------------------
1910 Double_t epsilonT = trigEff;
1911 Double_t epsilonT0 = trigEff0;
1912 AliInfoF("Using epsilonT=%f, epsilonT0=%f for %d",
1913 epsilonT, epsilonT0, triggerMask);
1916 if (triggerMask == AliAODForwardMult::kNSD) {
1917 // This is a local change
1919 AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
1921 else if (triggerMask == AliAODForwardMult::kInel) {
1922 // This is a local change
1924 AliWarning(Form("Using hard-coded Inel trigger efficiency of %f",epsilonT));
1926 if (scheme & kZeroBin) {
1927 if (triggerMask==AliAODForwardMult::kInel)
1928 epsilonT0 = 0.785021; // 0.100240;
1929 else if (triggerMask==AliAODForwardMult::kInelGt0)
1931 else if (triggerMask==AliAODForwardMult::kNSD)
1932 epsilonT0 = .706587;
1934 AliWarning(Form("Using hard-coded NCluster>0 trigger efficiency of %f",
1939 // Get our histograms
1941 TH2D* sum = fSum->CalcSum(fOutput, nSum, epsilonT0, epsilonT,
1942 marker, rootProj, corrEmpty);
1943 Double_t nSumMC = 0;
1945 if (fSumMC) sumMC = fSumMC->CalcSum(fOutput, nSumMC,
1946 epsilonT0, epsilonT, marker,
1947 rootProj, corrEmpty);
1949 AliError("Failed to get sum from summer - bailing out");
1954 Double_t ntotal = nSum;
1955 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal, &text);
1957 AliError("Failed to calculate normalization - bailing out");
1960 fOutput->Add(fTriggers->Clone());
1961 fOutput->Add(new TNamed("normCalc", text.Data()));
1963 // --- Make result and store ---------------------------------------
1964 MakeResult(sum, "", rootProj, corrEmpty, (scheme & kShape) ? shapeCorr : 0,
1965 scaler, symmetrice, rebin, cutEdges, marker, color,
1968 // --- Process result from TrackRefs -------------------------------
1970 MakeResult(sumMC, "MC", rootProj, corrEmpty,
1971 (scheme & kShape) ? shapeCorr : 0,
1972 scaler, symmetrice, rebin, cutEdges,
1973 GetMarkerStyle(GetMarkerBits(marker)+4), color,
1977 // if (!IsAllBin()) return;