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"
18 //____________________________________________________________________
19 AliBasedNdetaTask::AliBasedNdetaTask()
25 fListOfCentralities(0),
26 fNormalizationScheme(kFull),
28 fSatelliteVertices(0),
29 fEmpiricalCorrection(0),
34 fCheckSPDOutlier(false)
39 DGUARD(fDebug,3,"Default CTOR of AliBasedNdetaTask");
42 //____________________________________________________________________
43 AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
44 : AliBaseAODTask(Form("%sdNdeta", name),"AliBasedNdetaTask"),
49 fListOfCentralities(0),
50 fNormalizationScheme(kFull),
52 fSatelliteVertices(0),
53 fEmpiricalCorrection(0),
58 fCheckSPDOutlier(false)
63 DGUARD(fDebug, 3,"Named CTOR of AliBasedNdetaTask: %s", name);
65 fTriggerMask = AliAODForwardMult::kInel;
68 fListOfCentralities = new TObjArray(1);
70 // Set the normalisation scheme
71 SetNormalizationScheme(kFull);
75 //____________________________________________________________________
76 AliBasedNdetaTask::~AliBasedNdetaTask()
81 DGUARD(fDebug,3,"Destruction of AliBasedNdetaTask");
84 //________________________________________________________________________
86 AliBasedNdetaTask::SetDebugLevel(Int_t lvl)
88 AliAnalysisTaskSE::SetDebugLevel(lvl);
89 for (Int_t i = 0; i < fListOfCentralities->GetEntries(); i++) {
91 static_cast<CentralityBin*>(fListOfCentralities->At(i));
92 bin->SetDebugLevel(lvl);
96 //________________________________________________________________________
98 AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
101 // Add a centrality bin
107 DGUARD(fDebug,3,"Add a centrality bin [%d,%d] @ %d", low, high, at);
108 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
110 Error("AddCentralityBin",
111 "Failed to create centrality bin for %s [%d,%d] @ %d",
112 GetName(), low, high, at);
115 bin->SetSatelliteVertices(fSatelliteVertices);
116 bin->SetDebugLevel(fDebug);
117 fListOfCentralities->AddAtAndExpand(bin, at);
120 //________________________________________________________________________
121 AliBasedNdetaTask::CentralityBin*
122 AliBasedNdetaTask::MakeCentralityBin(const char* name,
123 Short_t low, Short_t high) const
126 // Make a centrality bin
129 // name Name used for histograms
130 // low Low cut in percent
131 // high High cut in percent
134 // A newly created centrality bin
136 DGUARD(fDebug,3,"Make a centrality bin %s [%d,%d]", name, low, high);
137 return new CentralityBin(name, low, high);
140 #define TESTAPPEND(SCHEME,BIT,STRING) \
141 do { if (!(SCHEME & BIT)) break; \
142 if (!s.IsNull()) s.Append(","); s.Append(STRING); } while(false)
144 //________________________________________________________________________
146 AliBasedNdetaTask::NormalizationSchemeString(UShort_t scheme)
148 // Create a string from normalization scheme bits
154 if (scheme == kFull) {
158 TESTAPPEND(scheme, kEventLevel, "EVENT");
159 TESTAPPEND(scheme, kBackground, "BACKGROUND");
160 TESTAPPEND(scheme, kTriggerEfficiency, "TRIGGER");
161 TESTAPPEND(scheme, kZeroBin, "ZEROBIN");
165 //________________________________________________________________________
167 AliBasedNdetaTask::ParseNormalizationScheme(const char* what)
173 TObjArray* token = twhat.Tokenize(" ,|");
175 while ((opt = static_cast<TObjString*>(next()))) {
176 TString s(opt->GetString());
177 if (s.IsNull()) continue;
180 case '-': add = false; // Fall through
181 case '+': s.Remove(0,1); // Remove character
184 if (s.EqualTo("SHAPE")) {
185 AliWarningGeneral("AliBasedNdetaTask",
186 Form("SHAPE correction no longer supported (%s)",
190 if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
191 else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
192 else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
193 else if (s.CompareTo("FULL") == 0) bit = kFull;
194 else if (s.CompareTo("NONE") == 0) bit = kNone;
195 else if (s.CompareTo("ZEROBIN") == 0) bit = kZeroBin;
197 ::Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
198 if (add) scheme |= bit;
204 //________________________________________________________________________
206 AliBasedNdetaTask::SetNormalizationScheme(const char* what)
209 // Set normalisation scheme
211 DGUARD(fDebug,3,"Set the normalization scheme: %s", what);
212 SetNormalizationScheme(ParseNormalizationScheme(what));
214 //________________________________________________________________________
216 AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme)
218 DGUARD(fDebug,3,"Set the normalization scheme: 0x%x", scheme);
219 fNormalizationScheme = scheme;
221 //____________________________________________________________________
223 AliBasedNdetaTask::SetCentralityMethod(const TString& method)
225 Int_t id = GetCentMethodID(method);
227 AliErrorF("Unknown centrality estimator: %s", method.Data());
230 if (id < 0) // Do not use any estimator
233 TString meth = GetCentMethod(id);
234 if (fName.Contains("Forward", TString::kIgnoreCase) && meth.Contains("FMD"))
235 AliWarningF("Centrality estimator %s used by %s - beware of auto-corr",
236 meth.Data(), fName.Data());
237 else if (fName.Contains("Central", TString::kIgnoreCase) &&
238 (meth.Contains("CL0") || meth.Contains("TKL")))
239 AliWarningF("Centrality estimator %s used by %s - beware of auto-corr",
240 meth.Data(), fName.Data());
246 //________________________________________________________________________
248 AliBasedNdetaTask::GetCentMethodID(const TString& meth)
253 if (m.EqualTo("NONE") || m.EqualTo("NO") || m.EqualTo("FALSE")) ret = -1;
254 else if (m.IsNull()) ret = kCentDefault;
255 else if (m.BeginsWith("ZEMVSZDC")) ret = kCentZEMvsZDC;
256 else if (m.BeginsWith("TKLVSV0M")) ret = kCentTklvsV0M;
257 else if (m.BeginsWith("V0MVSFMD")) ret = kCentV0MvsFMD;
258 else if (m.BeginsWith("NPA")) ret = kCentNPA;
259 else if (m.BeginsWith("ZPC")) ret = kCentZPC;
260 else if (m.BeginsWith("ZPA")) ret = kCentZPA;
261 else if (m.BeginsWith("ZNC")) ret = kCentZNC;
262 else if (m.BeginsWith("ZNA")) ret = kCentZNA;
263 else if (m.BeginsWith("CND")) ret = kCentCND;
264 else if (m.BeginsWith("CL1")) ret = kCentCL1;
265 else if (m.BeginsWith("CL0")) ret = kCentCL0;
266 else if (m.BeginsWith("TKL")) ret = kCentTkl;
267 else if (m.BeginsWith("TRK")) ret = kCentTrk;
268 else if (m.BeginsWith("FMD")) ret = kCentFMD;
269 else if (m.BeginsWith("V0C")) ret = kCentV0C;
270 else if (m.BeginsWith("V0A123")) ret = kCentV0A123;
271 else if (m.BeginsWith("V0A")) ret = kCentV0A;
272 else if (m.BeginsWith("V0M")) ret = kCentV0M;
273 if (m.Contains("TRUE")) ret |= kCentTrue;
274 if (m.Contains("EG")) ret |= kCentEq;
278 //________________________________________________________________________
280 AliBasedNdetaTask::GetCentMethod(UShort_t id)
282 static TString ret("");
283 UShort_t base = (id & 0xFF);
285 case kCentNone: ret = "none"; break;
286 case kCentDefault: ret = ""; break;
287 case kCentV0M: ret = "V0M"; break;
288 case kCentV0A: ret = "V0A"; break;
289 case kCentV0A123: ret = "V0A123"; break;
290 case kCentV0C: ret = "V0C"; break;
291 case kCentFMD: ret = "FMD"; break;
292 case kCentTrk: ret = "TRK"; break;
293 case kCentTkl: ret = "TKL"; break;
294 case kCentCL0: ret = "CL0"; break;
295 case kCentCL1: ret = "CL1"; break;
296 case kCentCND: ret = "CND"; break;
297 case kCentZNA: ret = "ZNA"; break;
298 case kCentZNC: ret = "ZNC"; break;
299 case kCentZPA: ret = "ZPA"; break;
300 case kCentZPC: ret = "ZPC"; break;
301 case kCentNPA: ret = "NPA"; break;
302 case kCentV0MvsFMD: ret = "V0MvsFMD"; break;
303 case kCentTklvsV0M: ret = "TKLvsV0M"; break;
304 case kCentZEMvsZDC: ret = "ZEMvsZDC"; break;
305 default: ret = ""; break;
307 Bool_t tru = id & kCentTrue;
308 Bool_t eq = id & kCentEq;
310 if (!tru) ret.Append("eq");
311 else ret.Append("Eq");
313 if (tru) ret.Append("true");
319 //________________________________________________________________________
321 AliBasedNdetaTask::InitializeCentBins()
323 if (fListOfCentralities->GetEntries() > 0) return;
325 // Automatically add 'all' centrality bin if nothing has been defined.
326 AddCentralityBin(0, 0, 0);
327 if (HasCentrality()) {
328 const TArrayD* bins = fCentAxis.GetXbins();
329 Int_t nbin = fCentAxis.GetNbins();
330 for (Int_t i = 0; i < nbin; i++)
331 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
335 //________________________________________________________________________
337 AliBasedNdetaTask::Book()
340 // Create output objects.
342 // This is called once per slave process
344 DGUARD(fDebug,1,"Create user ouput object");
346 fSums->Add(AliForwardUtil::MakeParameter("empirical",
347 fEmpiricalCorrection != 0));
348 fSums->Add(AliForwardUtil::MakeParameter("scheme", fNormalizationScheme));
349 fSums->Add(AliForwardUtil::MakeParameter("centEstimator",
350 GetCentMethodID(fCentMethod)));
351 fSums->Add(AliForwardUtil::MakeParameter("spdOutlier", fCheckSPDOutlier));
352 // fSums->Add(new TNamed("centEstimator", fCentMethod.Data()));
354 // Make our centrality bins
355 InitializeCentBins();
357 // Loop over centrality bins
358 TIter next(fListOfCentralities);
359 CentralityBin* bin = 0;
360 while ((bin = static_cast<CentralityBin*>(next())))
361 bin->CreateOutputObjects(fSums, fTriggerMask);
363 fMeanVsC=new TH2D("meanAbsSignalVsCentr",
364 "Mean absolute signal versus centrality",
365 400, 0, 20, 100, 0, 100);
366 fSums->Add(fMeanVsC);
371 //____________________________________________________________________
373 AliBasedNdetaTask::CheckEvent(const AliAODForwardMult& fwd)
375 AliBaseAODTask::CheckEvent(fwd);
376 // Check full AOD mask
377 if (fPileupMask & kPileupFull &&
378 fwd.IsTriggerBits(AliAODForwardMult::kPileUp))
381 // Check for SPD pile-up
382 if (fPileupMask & kPileupSPD &&
383 fwd.IsTriggerBits(AliAODForwardMult::kPileupSPD))
386 // Check for track pile-up
387 if (fPileupMask & kPileupTrk &&
388 fwd.IsTriggerBits(AliAODForwardMult::kPileupTrack))
391 // Check for out of bunc pile-up
392 if (fPileupMask & kPileupBC &&
393 fwd.IsTriggerBits(AliAODForwardMult::kPileupBC))
396 // Check for SPD outlier (N_cluster > 65 + 4 * N_tracklet)
397 if (fCheckSPDOutlier && fwd.IsTriggerBits(AliAODForwardMult::kSPDOutlier))
400 // Here, we always return true, as the centrality bins will do
401 // their own checks on the events - this is needed for event
402 // normalization etc.
406 //____________________________________________________________________
408 AliBasedNdetaTask::Event(AliAODEvent& aod)
411 // Process a single event
417 DGUARD(fDebug,1,"Analyse the AOD event");
418 if (fPileupMask & kPileupUtil && fAnaUtil.IsPileUpEvent(&aod)) return false;
420 AliAODForwardMult* forward = GetForward(aod);
421 if (!forward) return false;
423 // Fill centrality histogram
425 Double_t vtx = forward->GetIpZ();
426 TH2D* data = GetHistogram(aod, false);
427 TH2D* dataMC = GetHistogram(aod, true);
428 if (!data) return false;
430 CheckEventData(vtx, data, dataMC);
432 if (!ApplyEmpiricalCorrection(forward,data))
436 Bool_t isZero = ((fNormalizationScheme & kZeroBin) &&
437 !forward->IsTriggerBits(AliAODForwardMult::kNClusterGt0));
438 Bool_t taken = false;
439 Bool_t checkPileup = fPileupMask == kPileupNormal;
440 // Loop over centrality bins
441 CentralityBin* allBin =
442 static_cast<CentralityBin*>(fListOfCentralities->At(0));
443 if (allBin->ProcessEvent(forward, fTriggerMask, isZero, fMinIpZ, fMaxIpZ,
444 data, dataMC, checkPileup)) taken = true;
446 // Find this centrality bin
447 if (HasCentrality()) {
448 Double_t cent = forward->GetCentrality();
449 if (!fCentMethod.IsNull()) {
450 AliAODHeader* hdr = aod.GetHeader();
452 AliCentrality* cP = hdr->GetCentralityP();
454 cent = cP->GetCentralityPercentile(fCentMethod);
458 Int_t icent = fCentAxis.FindBin(cent);
459 CentralityBin* thisBin = 0;
460 if (icent >= 1 && icent <= fCentAxis.GetNbins())
461 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
463 if (thisBin->ProcessEvent(forward, fTriggerMask, isZero, fMinIpZ,
464 fMaxIpZ, data, dataMC, checkPileup))
471 //________________________________________________________________________
472 void AliBasedNdetaTask::CheckEventData(Double_t,
478 //________________________________________________________________________
480 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
481 const char* title, const char* ytitle)
484 // Set histogram graphical options, etc.
487 // h Histogram to modify
488 // colour Marker color
489 // marker Marker style
490 // title Title of histogram
491 // ytitle Title on y-axis.
494 h->SetMarkerColor(colour);
495 h->SetMarkerStyle(marker);
496 h->SetMarkerSize(marker == 29 || marker == 30 ? 1.2 : 1);
499 if (ytitle && ytitle[0] != '\0') ytit = ytitle;
500 ytit = "#frac{1}{#it{N}}#frac{d#it{N}_{ch}}{d#it{#eta}}";
502 h->GetXaxis()->SetTitleFont(132);
503 h->GetXaxis()->SetLabelFont(132);
504 h->GetXaxis()->SetNdivisions(10);
505 h->GetYaxis()->SetTitleFont(132);
506 h->GetYaxis()->SetLabelFont(132);
507 h->GetYaxis()->SetNdivisions(10);
508 h->GetYaxis()->SetDecimals();
512 //________________________________________________________________________
514 AliBasedNdetaTask::ScaleToCoverage(TH2D* copy, const TH1D* norm)
516 // Normalize to the acceptance -
517 // dndeta->Divide(accNorm);
518 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
519 Double_t a = norm->GetBinContent(i);
520 for (Int_t j = 1; j <= copy->GetNbinsY(); j++) {
522 copy->SetBinContent(i,j,0);
523 copy->SetBinError(i,j,0);
526 Double_t c = copy->GetBinContent(i, j);
527 Double_t e = copy->GetBinError(i, j);
528 copy->SetBinContent(i, j, c / a);
529 copy->SetBinError(i, j, e / a);
533 //________________________________________________________________________
535 AliBasedNdetaTask::ScaleToCoverage(TH1D* copy, const TH1D* norm)
537 // Normalize to the acceptance -
538 // dndeta->Divide(accNorm);
539 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
540 Double_t a = norm->GetBinContent(i);
542 copy->SetBinContent(i,0);
543 copy->SetBinError(i,0);
546 Double_t c = copy->GetBinContent(i);
547 Double_t e = copy->GetBinError(i);
548 copy->SetBinContent(i, c / a);
549 copy->SetBinError(i, e / a);
553 //________________________________________________________________________
555 AliBasedNdetaTask::ProjectX(const TH2D* h,
564 // Project onto the X axis
569 // firstbin First bin to use
570 // lastbin Last bin to use
571 // error Whether to calculate errors
574 // Newly created histogram or null
578 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
580 const TAxis* xaxis = h->GetXaxis();
581 const TAxis* yaxis = h->GetYaxis();
582 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
583 xaxis->GetXmin(), xaxis->GetXmax());
584 static_cast<const TAttLine*>(h)->Copy(*ret);
585 static_cast<const TAttFill*>(h)->Copy(*ret);
586 static_cast<const TAttMarker*>(h)->Copy(*ret);
587 ret->GetXaxis()->ImportAttributes(xaxis);
589 Int_t first = firstbin;
590 Int_t last = lastbin;
591 if (first < 0) first = 1;
592 else if (first >= yaxis->GetNbins()+2) first = yaxis->GetNbins()+1;
593 if (last < 0) last = yaxis->GetNbins();
594 else if (last >= yaxis->GetNbins()+2) last = yaxis->GetNbins()+1;
595 if (last-first < 0) {
596 AliWarningGeneral("AliBasedNdetaTask",
597 Form("Nothing to project [%d,%d]", first, last));
603 //DMSG(fDebug,3,"Projecting bins [%d,%d] of %s", first, last, h->GetName()));
604 Int_t ybins = (last-first+1);
605 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
606 Double_t content = 0;
611 for (Int_t ybin = first; ybin <= last; ybin++) {
612 Double_t c1 = h->GetBinContent(h->GetBin(xbin, ybin));
613 Double_t e1 = h->GetBinError(h->GetBin(xbin, ybin));
616 if (c1 < 1e-12) continue;
626 if(content > 0 && nbins > 0) {
627 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
629 AliWarningGeneral(ret->GetName(),
630 Form("factor @ %d is %d/%d -> %f",
631 xbin, ybins, nbins, factor));
634 // Calculate weighted average
635 ret->SetBinContent(xbin, content * factor);
636 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
639 ret->SetBinContent(xbin, factor * content);
646 //________________________________________________________________________
648 AliBasedNdetaTask::Finalize()
651 // Called at end of event processing..
653 // This is called once in the master
658 // Draw result to screen, or perform fitting, normalizations Called
659 // once at the end of the query
660 DGUARD(fDebug,1,"Process final merged results");
667 AliForwardUtil::GetParameter(fSums->FindObject("sNN"), sNN);
668 AliForwardUtil::GetParameter(fSums->FindObject("sys"), sys);
669 AliForwardUtil::GetParameter(fSums->FindObject("trigger"), trig);
670 AliForwardUtil::GetParameter(fSums->FindObject("scheme"), scheme);
671 //AliForwardUtil::GetParameter(fSums->FindObject("centEstimator"), centID);
673 TH1* cH = static_cast<TH1*>(fSums->FindObject("centAxis"));
674 Info("", "centAxis: %p (%s)", cH, (cH ? cH->ClassName() : "null"));
675 // TAxis* cA = static_cast<TAxis*>(fSums->FindObject("centAxis"));
676 TAxis* cA = (cH ? cH->GetXaxis() : 0);
677 if (cA) cA->Copy(fCentAxis);
678 fCentAxis.SetName("centAxis");
679 fCentAxis.SetTitle("Centrality [%]");
681 // (Re)Create our centrality bins
682 InitializeCentBins();
684 // Print before we loop
687 // Loop over centrality bins
688 TIter next(fListOfCentralities);
689 CentralityBin* bin = 0;
690 gStyle->SetPalette(1);
691 THStack* dndetaStack = new THStack("dndeta", "dN/d#eta");
692 THStack* dndetaMCStack = new THStack("dndetaMC", "dN_{ch}/d#eta");
695 TList* truthlist = 0;
697 if (fFinalMCCorrFile.Contains(".root")) {
698 TFile* ftest = TFile::Open(fFinalMCCorrFile.Data());
700 mclist = dynamic_cast<TList*>(ftest->Get(Form("%sResults",GetName())));
701 truthlist = dynamic_cast<TList*>(ftest->Get("MCTruthResults"));
704 AliWarning("MC analysis file invalid - no final MC correction possible");
706 Int_t style = GetMarker();
707 Int_t color = GetColor();
709 DMSG(fDebug,3,"Marker style=%d, color=%d", style, color);
710 while ((bin = static_cast<CentralityBin*>(next()))) {
711 bin->End(fSums, fResults, fNormalizationScheme, fTriggerEff, fTriggerEff0,
712 fUseROOTProj, fCorrEmpty, fTriggerMask,
713 style, color, mclist, truthlist);
714 if (HasCentrality() && bin->IsAllBin())
715 // If we have centrality bins, do not add the min-bias
716 // distribution to the output stack.
718 TH1* dndeta = bin->GetResult("");
719 TH1* dndetaMC = bin->GetResult("MC", false);
720 DMSG(fDebug,2,"Results: bare=%p mcbare=%p", dndeta, dndetaMC);
721 if (dndeta) dndetaStack->Add(dndeta);
722 if (dndetaMC) dndetaMCStack->Add(dndetaMC);
725 fResults->Add(dndetaStack);
727 // If available, output track-ref stack
728 if (!dndetaMCStack->GetHists() ||
729 dndetaMCStack->GetHists()->GetEntries() <= 0) {
730 // AliWarning("No MC histograms found");
731 delete dndetaMCStack;
734 if (dndetaMCStack) fResults->Add(dndetaMCStack);
736 // Output collision energy string
738 TNamed* sNNObj = new TNamed("sNN",
739 AliForwardUtil::CenterOfMassEnergyString(sNN));
740 sNNObj->SetUniqueID(sNN);
741 fResults->Add(sNNObj); // fSNNString->Clone());
744 // Output collision system string
746 TNamed* sysObj = new TNamed("sys",
747 AliForwardUtil::CollisionSystemString(sys));
748 sysObj->SetUniqueID(sys);
749 fResults->Add(sysObj); // fSysString->Clone());
752 // Output centrality axis
753 fResults->Add(&fCentAxis);
754 fResults->Add(new TNamed("centEstimator", fCentMethod.Data()));
756 // Output trigger string
758 TNamed* maskObj = new TNamed("trigger",
759 AliAODForwardMult::GetTriggerString(trig));
760 maskObj->SetUniqueID(trig);
761 fResults->Add(maskObj); // fTriggerString->Clone());
764 // Normalization string
766 TNamed* schemeObj = new TNamed("scheme",
767 NormalizationSchemeString(scheme));
768 schemeObj->SetUniqueID(scheme);
769 fResults->Add(schemeObj); // fSchemeString->Clone());
772 // Output vertex axis
773 TAxis* vtxAxis = new TAxis(1,fMinIpZ,fMaxIpZ);
774 vtxAxis->SetName("vtxAxis");
775 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fMinIpZ,fMaxIpZ));
776 fResults->Add(vtxAxis);
778 // Output trigger efficiency
779 fResults->Add(AliForwardUtil::MakeParameter("triggerEff", fTriggerEff));
780 fResults->Add(AliForwardUtil::MakeParameter("triggerEff0", fTriggerEff0));
782 TNamed* options = new TNamed("options","");
784 str.Append(Form("Empty bins %scorrected for, ", fCorrEmpty ? "" : "not "));
785 str.Append(Form("TH2::ProjectionX %sused", fUseROOTProj ? "" : "not "));
786 options->SetTitle(str);
787 fResults->Add(options);
792 #define PF(N,V,...) \
793 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
794 #define PFB(N,FLAG) \
796 AliForwardUtil::PrintName(N); \
797 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
799 #define PFV(N,VALUE) \
801 AliForwardUtil::PrintName(N); \
802 std::cout << (VALUE) << std::endl; } while(false)
804 //________________________________________________________________________
806 AliBasedNdetaTask::Print(Option_t* option) const
811 AliBaseAODTask::Print(option);
812 TString schemeString(NormalizationSchemeString(fNormalizationScheme));
814 gROOT->IncreaseDirLevel();
815 PFB("Use TH2::ProjectionX", fUseROOTProj);
816 PFB("Correct for empty", fCorrEmpty);
817 PFV("Normalization scheme", schemeString );
818 PFV("Trigger efficiency", fTriggerEff);
819 PFV("Bin-0 Trigger efficiency", fTriggerEff0);
820 PFV("Centrality estimator", fCentMethod);
821 PF("Pile-up mask", "0x%x", fPileupMask);
822 PFB("Check SPD outlier", fCheckSPDOutlier);
823 gROOT->DecreaseDirLevel();
826 //__________________________________________________________________
828 AliBasedNdetaTask::GetMarkerStyle(UShort_t bits)
830 Int_t base = bits & (0xFE);
831 Bool_t hollow = bits & kHollow;
833 case kCircle: return (hollow ? 24 : 20);
834 case kSquare: return (hollow ? 25 : 21);
835 case kUpTriangle: return (hollow ? 26 : 22);
836 case kDownTriangle: return (hollow ? 32 : 23);
837 case kDiamond: return (hollow ? 27 : 33);
838 case kCross: return (hollow ? 28 : 34);
839 case kStar: return (hollow ? 30 : 29);
843 //__________________________________________________________________
845 AliBasedNdetaTask::GetMarkerBits(Int_t style)
849 case 24: case 25: case 26: case 27: case 28: case 30: case 32:
850 bits |= kHollow; break;
853 case 20: case 24: bits |= kCircle; break;
854 case 21: case 25: bits |= kSquare; break;
855 case 22: case 26: bits |= kUpTriangle; break;
856 case 23: case 32: bits |= kDownTriangle; break;
857 case 27: case 33: bits |= kDiamond; break;
858 case 28: case 34: bits |= kCross; break;
859 case 29: case 30: bits |= kStar; break;
863 //__________________________________________________________________
865 AliBasedNdetaTask::FlipHollowStyle(Int_t style)
867 UShort_t bits = GetMarkerBits(style);
868 Int_t ret = GetMarkerStyle(bits ^ kHollow);
872 //====================================================================
874 AliBasedNdetaTask::Sum::Init(TList* list, const TH2D* data, Int_t col)
876 DGUARD(fDebug,1,"Initializing sums with %s", data->GetName());
877 TString n(GetHistName(0));
878 TString n0(GetHistName(1));
879 const char* postfix = GetTitle();
881 fSum = static_cast<TH2D*>(data->Clone(n));
882 if (postfix) fSum->SetTitle(Form("%s (%s)", data->GetTitle(), postfix));
883 fSum->SetDirectory(0);
884 fSum->SetMarkerColor(col);
885 fSum->SetMarkerStyle(GetMarkerStyle(kCircle|kSolid));
889 fSum0 = static_cast<TH2D*>(data->Clone(n0));
891 fSum0->SetTitle(Form("%s 0-bin (%s)", data->GetTitle(), postfix));
893 fSum0->SetTitle(Form("%s 0-bin", data->GetTitle()));
894 fSum0->SetDirectory(0);
895 fSum0->SetMarkerColor(col);
896 fSum0->SetMarkerStyle(GetMarkerStyle(kCross|kHollow));
900 fEvents = new TH1I(GetHistName(2), "Event types", 2, -.5, 1.5);
901 fEvents->SetDirectory(0);
902 fEvents->GetXaxis()->SetBinLabel(1, "Non-zero");
903 fEvents->GetXaxis()->SetBinLabel(2, "Zero");
907 //____________________________________________________________________
909 AliBasedNdetaTask::Sum::GetHistName(const char* /*name*/,
910 Int_t what, const char* post)
914 case 0: n = "sum"; break;
915 case 1: n = "sum0"; break;
916 case 2: n = "events"; break;
918 if (post && post[0] != '\0') n.Append(post);
922 //____________________________________________________________________
924 AliBasedNdetaTask::Sum::GetHistName(Int_t what) const
926 return GetHistName(GetName(), what, GetTitle());
929 //____________________________________________________________________
931 AliBasedNdetaTask::Sum::Add(const TH2D* data, Bool_t isZero)
933 DGUARD(fDebug,2,"Adding %s to sums", data->GetName());
934 if (isZero) fSum0->Add(data);
935 else fSum->Add(data);
936 fEvents->Fill(isZero ? 1 : 0);
939 //____________________________________________________________________
941 AliBasedNdetaTask::Sum::CalcSum(TList* output,
947 Bool_t corrEmpty) const
949 DGUARD(fDebug,2,"Calculating final summed histogram %s", fSum->GetName());
951 // The return value `ret' is not scaled in anyway
952 TH2D* ret = static_cast<TH2D*>(fSum->Clone(fSum->GetName()));
953 ret->SetDirectory(0);
954 Int_t n = Int_t(fEvents->GetBinContent(1));
955 Int_t n0 = Int_t(fEvents->GetBinContent(2));
960 "Adding histograms %s(%d) and %s(%d) w/weights %f and %f resp.",
961 fSum0->GetName(), n, fSum->GetName(), n0, 1./epsilon,1./epsilon0);
962 ret->Add(fSum0, fSum, 1. / epsilon0, 1. / epsilon);
963 ntotal = n / epsilon + n0 / epsilon0;
966 TList* out = new TList;
968 const char* postfix = GetTitle();
969 if (!postfix) postfix = "";
970 out->SetName(Form("partial%s", postfix));
973 // Now make copies, normalize them, and store in output list
974 // Note, these are the only ones normalized here
975 // These are mainly for diagnostics
976 TH2D* sumCopy = static_cast<TH2D*>(fSum->Clone("sum"));
977 TH2D* sum0Copy = static_cast<TH2D*>(fSum0->Clone("sum0"));
978 TH2D* retCopy = static_cast<TH2D*>(ret->Clone("sumAll"));
979 sumCopy->SetMarkerStyle(FlipHollowStyle(marker));
980 sumCopy->SetDirectory(0);
981 sum0Copy->SetMarkerStyle(GetMarkerStyle(GetMarkerBits(marker)+4));
982 sum0Copy->SetDirectory(0);
983 retCopy->SetMarkerStyle(marker);
984 retCopy->SetDirectory(0);
986 Int_t nY = fSum->GetNbinsY();
987 Int_t o = 0; // nY+1;
988 TH1D* norm = ProjectX(fSum, "norm", o, o, rootProj, corrEmpty, false);
989 TH1D* norm0 = ProjectX(fSum0, "norm0", o, o, rootProj, corrEmpty, false);
990 TH1D* normAll = ProjectX(ret, "normAll", o, o, rootProj, corrEmpty, false);
991 norm->SetTitle("#eta coverage - >0-bin");
992 norm0->SetTitle("#eta coverage - 0-bin");
993 normAll->SetTitle("#eta coverage");
994 norm->SetDirectory(0);
995 norm0->SetDirectory(0);
996 normAll->SetDirectory(0);
998 TH1D* sumCopyPx = ProjectX(sumCopy, "average", 1,nY,rootProj,corrEmpty);
999 TH1D* sum0CopyPx = ProjectX(sum0Copy, "average0", 1,nY,rootProj,corrEmpty);
1000 TH1D* retCopyPx = ProjectX(retCopy, "averageAll", 1,nY,rootProj,corrEmpty);
1001 sumCopyPx-> SetTitle(Form("#sum_{i}^{N_{#phi}}%s", sumCopy->GetTitle()));
1002 sum0CopyPx->SetTitle(Form("#sum_{i}^{N_{#phi}}%s", sum0Copy->GetTitle()));
1003 retCopyPx-> SetTitle(Form("#sum_{i}^{N_{#phi}}%s", retCopy->GetTitle()));
1004 sumCopyPx-> SetDirectory(0);
1005 sum0CopyPx->SetDirectory(0);
1006 retCopyPx-> SetDirectory(0);
1008 TH1D* phi = ProjectX(fSum, "phi", nY+1,nY+1,rootProj,corrEmpty,false);
1009 TH1D* phi0 = ProjectX(fSum0, "phi0", nY+1,nY+1,rootProj,corrEmpty,false);
1010 TH1D* phiAll = ProjectX(ret, "phiAll", nY+1,nY+1,rootProj,corrEmpty,false);
1011 phi ->SetTitle("#phi acceptance from dead strips - >0-bin");
1012 phi0 ->SetTitle("#phi acceptance from dead strips - 0-bin");
1013 phiAll->SetTitle("#phi acceptance from dead strips");
1014 phi ->SetDirectory(0);
1015 phi0 ->SetDirectory(0);
1016 phiAll->SetDirectory(0);
1018 const TH1D* cov = (corrEmpty ? norm : phi);
1019 const TH1D* cov0 = (corrEmpty ? norm0 : phi0);
1020 const TH1D* covAll = (corrEmpty ? normAll : phiAll);
1022 // Here, we scale to the coverage (or phi acceptance)
1023 ScaleToCoverage(sumCopy, cov);
1024 ScaleToCoverage(sum0Copy, cov0);
1025 ScaleToCoverage(retCopy, covAll);
1027 // Scale our 1D histograms
1028 sumCopyPx ->Scale(1., "width");
1029 sum0CopyPx->Scale(1., "width");
1030 retCopyPx ->Scale(1., "width");
1032 DMSG(fDebug,2,"Maximum %f,%f changed to %f", sumCopyPx->GetMaximum(),
1033 sum0CopyPx->GetMaximum(), retCopyPx->GetMaximum());
1035 // Scale the normalization - they should be 1 at the maximum
1036 norm ->Scale(n > 0 ? 1. / n : 1);
1037 norm0 ->Scale(n0 > 0 ? 1. / n0 : 1);
1038 normAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1040 // Scale the normalization - they should be 1 at the maximum
1041 phi ->Scale(n > 0 ? 1. / n : 1);
1042 phi0 ->Scale(n0 > 0 ? 1. / n0 : 1);
1043 phiAll->Scale(ntotal > 0 ? 1. / ntotal : 1);
1048 out->Add(sumCopyPx);
1049 out->Add(sum0CopyPx);
1050 out->Add(retCopyPx);
1060 DMSG(fDebug,1,"Returning (1/%f * %s + 1/%f * %s), "
1061 "1/%f * %d + 1/%f * %d = %d",
1062 epsilon0, fSum0->GetName(), epsilon, fSum->GetName(),
1063 epsilon0, n0, epsilon, n, int(ntotal));
1065 DMSG(fDebug,1, "Returning %s, %d", fSum->GetName(), int(ntotal));
1069 for (Int_t i = 1; i <= ret->GetNbinsX(); i++) {
1070 Double_t nc = sum->GetBinContent(i, 0);
1071 Double_t nc0 = sum0->GetBinContent(i, 0);
1072 ret->SetBinContent(i, 0, nc + nc0); // Just count events
1079 //====================================================================
1080 AliBasedNdetaTask::CentralityBin::CentralityBin()
1090 fDoFinalMCCorrection(false),
1091 fSatelliteVertices(false),
1097 DGUARD(fDebug,3,"Default CTOR of AliBasedNdeta::CentralityBin");
1099 //____________________________________________________________________
1100 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
1101 Short_t low, Short_t high)
1111 fDoFinalMCCorrection(false),
1112 fSatelliteVertices(false),
1119 // name Name used for histograms (e.g., Forward)
1120 // low Lower centrality cut in percent
1121 // high Upper centrality cut in percent
1123 DGUARD(fDebug,3,"Named CTOR of AliBasedNdeta::CentralityBin: %s [%3d,%3d]",
1125 if (low <= 0 && high <= 0) {
1128 SetTitle("All centralities");
1133 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
1136 //____________________________________________________________________
1137 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
1143 fTriggers(o.fTriggers),
1147 fDoFinalMCCorrection(o.fDoFinalMCCorrection),
1148 fSatelliteVertices(o.fSatelliteVertices),
1155 // other Object to copy from
1157 DGUARD(fDebug,3,"Copy CTOR of AliBasedNdeta::CentralityBin");
1159 //____________________________________________________________________
1160 AliBasedNdetaTask::CentralityBin::~CentralityBin()
1165 DGUARD(fDebug,3,"DTOR of AliBasedNdeta::CentralityBin");
1167 // if (fSums) fSums->Delete();
1168 // if (fOutput) fOutput->Delete();
1171 //____________________________________________________________________
1172 AliBasedNdetaTask::CentralityBin&
1173 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
1176 // Assignment operator
1179 // other Object to assign from
1182 // Reference to this
1184 DGUARD(fDebug,3,"Centrality bin assignment");
1185 if (&o == this) return *this;
1186 SetName(o.GetName());
1187 SetTitle(o.GetTitle());
1189 fOutput = o.fOutput;
1192 fTriggers = o.fTriggers;
1193 fStatus = o.fStatus;
1196 fDoFinalMCCorrection = o.fDoFinalMCCorrection;
1197 fSatelliteVertices = o.fSatelliteVertices;
1201 //____________________________________________________________________
1203 AliBasedNdetaTask::CentralityBin::GetColor(Int_t fallback) const
1205 if (IsAllBin()) return fallback;
1206 Float_t fc = (fLow+double(fHigh-fLow)/2) / 100;
1207 Int_t nCol = gStyle->GetNumberOfColors();
1208 Int_t icol = TMath::Min(nCol-1,int(fc * nCol + .5));
1209 Int_t col = gStyle->GetColorPalette(icol);
1212 //____________________________________________________________________
1214 AliBasedNdetaTask::CentralityBin::GetListName() const
1217 // Get the list name
1222 if (IsAllBin()) return "all";
1223 return Form("cent%03d_%03d", fLow, fHigh);
1225 //____________________________________________________________________
1227 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir, Int_t mask)
1230 // Create output objects
1235 DGUARD(fDebug,1,"Create centrality bin output objects");
1237 fSums->SetName(GetListName());
1241 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers", mask);
1242 fTriggers->SetDirectory(0);
1244 fStatus = AliAODForwardMult::MakeStatusHistogram("status");
1245 fStatus->SetDirectory(0);
1247 fSums->Add(fTriggers);
1248 fSums->Add(fStatus);
1250 //____________________________________________________________________
1252 AliBasedNdetaTask::CentralityBin::SetDebugLevel(Int_t lvl)
1255 if (fSum) fSum->fDebug = lvl;
1256 if (fSumMC) fSumMC->fDebug = lvl;
1259 //____________________________________________________________________
1261 AliBasedNdetaTask::CentralityBin::ReadSum(TList* list, bool mc)
1263 const char* post = (mc ? "MC" : "");
1264 TString sn = Sum::GetHistName(GetName(),0,post);
1265 TString sn0 = Sum::GetHistName(GetName(),1,post);
1266 TString ev = Sum::GetHistName(GetName(),2,post);
1267 TH2D* sum = static_cast<TH2D*>(list->FindObject(sn));
1268 TH2D* sum0 = static_cast<TH2D*>(list->FindObject(sn0));
1269 TH1I* events = static_cast<TH1I*>(list->FindObject(ev));
1270 if (!sum || !sum0 || !events) {
1272 AliWarningF("Failed to find one or more histograms: "
1273 "%s (%p) %s (%p) %s (%p)",
1279 Sum* ret = new Sum(GetName(), post);
1282 ret->fEvents = events;
1283 ret->fDebug = fDebug;
1284 if (mc) fSumMC = ret;
1290 //____________________________________________________________________
1292 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
1295 // Create sum histogram
1298 // data Data histogram to clone
1299 // mc (optional) MC histogram to clone
1301 DGUARD(fDebug,1,"Create centrality bin sums from %s",
1302 data ? data->GetName() : "(null)");
1304 fSum = new Sum(GetName(),"");
1305 fSum->Init(fSums, data, GetColor());
1306 fSum->fDebug = fDebug;
1309 // If no MC data is given, then do not create MC sum histogram
1312 fSumMC = new Sum(GetName(), "MC");
1313 fSumMC->Init(fSums, mc, GetColor());
1314 fSumMC->fDebug = fDebug;
1317 //____________________________________________________________________
1319 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
1326 // Check the trigger, vertex, and centrality
1332 // true if the event is to be used
1334 if (!forward) return false;
1336 DGUARD(fDebug,2,"Check the event");
1337 // We do not check for centrality here - it's already done
1338 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0,
1339 fTriggers, fStatus, checkPileup);
1343 //____________________________________________________________________
1345 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
1346 Int_t triggerMask, Bool_t isZero,
1347 Double_t vzMin, Double_t vzMax,
1348 const TH2D* data, const TH2D* mc,
1355 // forward Forward data (for trigger, vertex, & centrality)
1356 // triggerMask Trigger mask
1357 // vzMin Minimum IP z coordinate
1358 // vzMax Maximum IP z coordinate
1359 // data Data histogram
1362 DGUARD(fDebug,1,"Process one event for %s a given centrality bin",
1363 data ? data->GetName() : "(null)");
1364 if (!CheckEvent(forward, triggerMask, vzMin, vzMax, checkPileup))
1366 if (!data) return false;
1367 if (!fSum) CreateSums(data, mc);
1369 fSum->Add(data, isZero);
1370 if (mc) fSumMC->Add(mc, isZero);
1375 //________________________________________________________________________
1377 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
1381 TString* text) const
1384 // Calculate normalization
1387 // t Trigger histogram
1388 // scheme Normaliztion scheme
1390 // ntotal On return, contains the number of events.
1392 DGUARD(fDebug,1,"Normalize centrality bin %s [%3d-%3d%%] with %s",
1393 GetName(), fLow, fHigh, t.GetName());
1394 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1395 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1396 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1397 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1398 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1399 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1400 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1401 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1402 Double_t nAccepted = ntotal;
1405 if (nTriggered <= 0.1) {
1406 AliError("Number of triggered events <= 0");
1409 if (nWithVertex <= 0.1) {
1410 AliError("Number of events with vertex <= 0");
1414 Double_t vtxEff = nWithVertex / nTriggered;
1415 Double_t scaler = 1;
1416 Double_t beta = nA + nC - 2*nE;
1419 TString rhs("N = N_acc");
1420 if (!(scheme & kZeroBin)) {
1421 if (scheme & kEventLevel) {
1422 ntotal = nAccepted / vtxEff;
1424 DMSG(fDebug,0,"Calculating event normalisation as\n"
1425 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1426 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1428 if (scheme & kBackground) {
1430 // s = --------- = ------------- = ------------
1431 // 1 - beta 1 - beta E_V 1 - beta N_V
1432 // --- ---- -------- ---- ---
1433 // E_V N_V N_V N_V N_T
1441 ntotal -= nAccepted * beta / nWithVertex;
1442 // This one is direct and correct.
1443 // scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1444 // A simpler expresion
1445 scaler /= (1 - beta / nTriggered); // 0.831631 -> 0.780689
1446 DMSG(fDebug,0,"Calculating event normalisation as\n"
1447 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1448 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1449 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1450 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1451 Int_t(nWithVertex), ntotal, scaler);
1452 rhs.Append("(1/eps_V - beta/N_vtx)");
1455 rhs.Append("/eps_V");
1457 if (scheme & kTriggerEfficiency) {
1458 Int_t old = Int_t(ntotal);
1461 DMSG(fDebug,0,"Correcting for trigger efficiency:\n"
1462 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1463 trigEff, old, ntotal, scaler);
1464 rhs.Append("/eps_T");
1465 } // Trigger efficiency
1470 // N = N_A + 1/E_X * N_A / N_V (N_T - N_V - beta)
1471 // = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1472 // = N_A (1 + 1/E_X (1/E_V - 1 - beta / N_V))
1474 // s = N_A/N = 1 / (1 + 1/E_X (N_T/N_V - 1 - beta / N_V))
1475 // = N_V / (N_V + 1/E_X (N_T - N_V - beta))
1477 if (!(scheme & kBackground)) beta = 0;
1478 ntotal = nAccepted * (1 + 1/trigEff * (nTriggered / nWithVertex - 1
1479 - beta / nWithVertex));
1480 scaler = nWithVertex / (nWithVertex +
1481 1/trigEff * (nTriggered-nWithVertex-beta));
1482 DMSG(fDebug,0,"Calculating event normalisation as\n"
1483 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1484 " N = N_A (1 + 1/E_X (N_T/N_V - 1 - beta / N_V)) = "
1485 "%d (1 + 1 / %f (%d / %d - 1 - %d / %d)) = %f (%f)",
1486 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1487 Int_t(nAccepted), trigEff, Int_t(nTriggered),
1488 Int_t(nWithVertex), Int_t(beta), Int_t(nWithVertex),
1490 rhs.Append("(1+1/eps_T(1/eps_V-1-beta/N_vtx))");
1494 text->Append(Form("%-40s = %d\n", "N_all", UInt_t(nAll)));
1495 text->Append(Form("%-40s = %d\n", "N_acc", UInt_t(nAccepted)));
1496 text->Append(Form("%-40s = %d\n", "N_trg", UInt_t(nTriggered)));
1497 text->Append(Form("%-40s = %d\n", "N_vtx", UInt_t(nWithVertex)));
1498 text->Append(Form("%-40s = %d\n", "N_B", UInt_t(nB)));
1499 text->Append(Form("%-40s = %d\n", "N_A", UInt_t(nA)));
1500 text->Append(Form("%-40s = %d\n", "N_C", UInt_t(nC)));
1501 text->Append(Form("%-40s = %d\n", "N_E", UInt_t(nE)));
1502 text->Append(Form("%-40s = %d\n", "beta = N_A + N_C - 2N_E",UInt_t(beta)));
1503 text->Append(Form("%-40s = %f\n", "eps_V = N_vtx/N_trg",vtxEff));
1504 text->Append(Form("%-40s = %f\n", "eps_T", trigEff));
1505 text->Append(Form("%-40s = %f\n", rhs.Data(), ntotal));
1507 TString tN = t.GetXaxis()->GetBinLabel(AliAODForwardMult::kWithTrigger);
1508 tN.ReplaceAll("w/Selected trigger (","");
1509 tN.ReplaceAll(")", "");
1511 " Total of %9d events for %s\n"
1512 " of these %9d have an offline trigger\n"
1513 " of these N_T = %9d has the selected trigger (%s)\n"
1514 " of these N_V = %9d has a vertex\n"
1515 " of these N_A = %9d were in the selected range\n"
1516 " Triggers by hardware type:\n"
1518 " N_ac = %9d (%d+%d)\n"
1520 " Vertex efficiency: %f\n"
1521 " Trigger efficiency: %f\n"
1522 " Total number of events: N = %f\n"
1523 " Scaler (N_A/N): %f\n"
1525 Int_t(nAll), GetTitle(), Int_t(nOffline),
1526 Int_t(nTriggered), tN.Data(),
1527 Int_t(nWithVertex), Int_t(nAccepted),
1528 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1529 vtxEff, trigEff, ntotal, scaler, rhs.Data(), ntotal);
1533 //________________________________________________________________________
1535 AliBasedNdetaTask::CentralityBin::GetResultName(const char* postfix) const
1539 n.ReplaceAll("dNdeta", "");
1540 n.Prepend("dndeta");
1544 //________________________________________________________________________
1546 AliBasedNdetaTask::CentralityBin::GetResult(const char* postfix,
1547 Bool_t verbose) const
1550 AliWarningF("No output list defined in %s [%3d,%3d]", GetName(),
1554 TString n = GetResultName(postfix);
1555 TObject* o = fOutput->FindObject(n.Data());
1558 AliWarningF("Object %s not found in output list of %s",
1559 n.Data(), GetName());
1562 return static_cast<TH1*>(o);
1565 //________________________________________________________________________
1567 AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
1568 const char* postfix,
1578 // Generate the dN/deta result from input
1581 // sum Sum of 2D hists
1582 // postfix Post fix on names
1583 // rootProj Whether to use ROOT TH2::ProjectionX
1584 // corrEmpty Correct for empty bins
1585 // scaler Event-level normalization scaler
1587 DGUARD(fDebug,1,"Make centrality bin result from %s", sum->GetName());
1588 TString base(GetName());
1589 base.ReplaceAll("dNdeta", "");
1590 base.Append(postfix);
1591 TH2D* copy = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s",
1595 Int_t nY = sum->GetNbinsY();
1596 // Hack HHD Hans test code to manually remove FMD2 dead channel (but
1599 // cholm comment: The original hack has been moved to
1600 // AliForwarddNdetaTask::CheckEventData - this simplifies things a
1601 // great deal, and we could in principle use the new phi acceptance.
1603 // However, since we may have filtered out the dead sectors in the
1604 // AOD production already, we can't be sure we can recalculate the
1605 // phi acceptance correctly, so for now, we rely on fCorrEmpty being set.
1606 Int_t o = (corrEmpty ? 0 : nY+1);
1607 accNorm = ProjectX(sum, Form("norm%s",base.Data()), o, o,
1608 rootProj, corrEmpty, false);
1609 accNorm->SetDirectory(0);
1611 // --- Normalize to the coverage -----------------------------------
1613 ScaleToCoverage(copy, accNorm);
1614 // --- Event-level normalization ---------------------------------
1615 copy->Scale(scaler);
1618 // --- Project on X axis -------------------------------------------
1619 TH1D* dndeta = ProjectX(copy, Form("dndeta%s",base.Data()),
1620 1, nY, rootProj, corrEmpty);
1621 dndeta->SetDirectory(0);
1622 // Event-level normalization
1624 ScaleToCoverage(dndeta, accNorm);
1625 dndeta->Scale(scaler);
1627 dndeta->Scale(1., "width");
1628 copy->Scale(1., "width");
1630 TH1D* dndetaMCCorrection = 0;
1631 TH1D* dndetaMCtruth = 0;
1632 TList* centlist = 0;
1633 TList* truthcentlist = 0;
1635 // --- Possible final correction to <MC analysis> / <MC truth> -----
1636 // we get the rebinned distribution for satellite to make the correction
1637 TString rebinSuf(fSatelliteVertices ? "_rebin05" : "");
1639 centlist = static_cast<TList*> (mclist->FindObject(GetListName()));
1641 dndetaMCCorrection =
1642 static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s%s",
1647 truthcentlist = static_cast<TList*>(truthlist->FindObject(GetListName()));
1649 // TODO here new is "dndetaTruth"
1651 static_cast<TH1D*>(truthcentlist->FindObject(Form("dndetaMCTruth%s",
1655 if (dndetaMCCorrection && dndetaMCtruth) {
1656 AliInfo("Correcting with final MC correction");
1657 TString testString(dndetaMCCorrection->GetName());
1659 // We take the measured MC dN/deta and divide with truth
1660 dndetaMCCorrection->Divide(dndetaMCtruth);
1661 dndetaMCCorrection->SetTitle("Final MC correction");
1662 dndetaMCCorrection->SetName("finalMCCorr");
1663 for(Int_t m = 1; m <= dndetaMCCorrection->GetNbinsX(); m++) {
1664 if(dndetaMCCorrection->GetBinContent(m) < 0.5 ||
1665 dndetaMCCorrection->GetBinContent(m) > 1.75) {
1666 dndetaMCCorrection->SetBinContent(m,1.);
1667 dndetaMCCorrection->SetBinError(m,0.1);
1670 // Applying the correction
1671 if (!fSatelliteVertices)
1672 // For non-satellites we took the same binning, so we do a straight
1674 dndeta->Divide(dndetaMCCorrection);
1676 // For satelitte events, we took coarser binned histograms, so
1677 // we need to do a bit more
1678 for(Int_t m = 1; m <= dndeta->GetNbinsX(); m++) {
1679 if(dndeta->GetBinContent(m) <= 0.01 ) continue;
1681 Double_t eta = dndeta->GetXaxis()->GetBinCenter(m);
1682 Int_t bin = dndetaMCCorrection->GetXaxis()->FindBin(eta);
1683 Double_t mccorr = dndetaMCCorrection->GetBinContent(bin);
1684 Double_t mcerror = dndetaMCCorrection->GetBinError(bin);
1685 if (mccorr < 1e-6) {
1686 dndeta->SetBinContent(m, 0);
1687 dndeta->SetBinError(m, 0);
1689 Double_t value = dndeta->GetBinContent(m);
1690 Double_t error = dndeta->GetBinError(m);
1691 Double_t sumw2 = (error * error * mccorr * mccorr +
1692 mcerror * mcerror * value * value);
1693 dndeta->SetBinContent(m,value/mccorr) ;
1694 dndeta->SetBinError(m,TMath::Sqrt(sumw2)/mccorr/mccorr);
1699 DMSG(fDebug,1,"No final MC correction applied");
1701 // --- Set some histogram attributes -------------------------------
1703 Int_t rColor = GetColor(color);
1704 if (postfix && postfix[0] != '\0') post = Form(" (%s)", postfix);
1705 SetHistogramAttributes(dndeta, rColor, marker,
1706 Form("ALICE %s%s", GetName(), post.Data()));
1707 SetHistogramAttributes(accNorm, rColor, marker,
1708 Form("ALICE %s normalisation%s",
1709 GetName(), post.Data()));
1711 // --- Add the histograms to output list ---------------------------
1712 fOutput->Add(dndeta);
1713 fOutput->Add(accNorm);
1715 if (dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
1717 // HHD Test of dN/deta in phi bins add flag later?
1719 // cholm comment: We disable this for now
1721 for (Int_t nn=1; nn <= sum->GetNbinsY(); nn++) {
1722 TH1D* dndeta_phi = ProjectX(copy, Form("dndeta%s_phibin%d",
1724 nn, nn, rootProj, corrEmpty);
1725 dndeta_phi->SetDirectory(0);
1726 // Event-level normalization
1727 dndeta_phi->Scale(TMath::Pi()/10., "width");
1730 dndetaMCCorrection =
1731 static_cast<TH1D*>(centlist->FindObject(Form("dndeta%s_phibin%d",
1735 = static_cast<TH1D*>(truthcentlist->FindObject("dndetaMCTruth"));
1737 if (dndetaMCCorrection && dndetaMCtruth) {
1738 AliInfo("Correcting with final MC correction");
1739 TString testString(dndetaMCCorrection->GetName());
1740 dndetaMCCorrection->Divide(dndetaMCtruth);
1741 dndetaMCCorrection->SetTitle(Form("Final_MC_correction_phibin%d",nn));
1742 dndetaMCCorrection->SetName(Form("Final_MC_correction_phibin%d",nn));
1743 for(Int_t m = 1; m <= dndetaMCCorrection->GetNbinsX(); m++) {
1744 if(dndetaMCCorrection->GetBinContent(m) < 0.25 ||
1745 dndetaMCCorrection->GetBinContent(m) > 1.75) {
1746 dndetaMCCorrection->SetBinContent(m,1.);
1747 dndetaMCCorrection->SetBinError(m,0.1);
1750 //Applying the correction
1751 dndeta_phi->Divide(dndetaMCCorrection);
1753 fOutput->Add(dndeta_phi);
1754 if(dndetaMCCorrection) fOutput->Add(dndetaMCCorrection);
1759 //________________________________________________________________________
1761 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1775 // End of processing
1778 // sums List of sums
1779 // results Output list of results
1780 // trigEff Trigger efficiency
1781 // corrEmpty Whether to correct for empty bins
1782 // triggerMask Trigger mask
1784 DGUARD(fDebug,1,"End centrality bin procesing");
1786 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1788 AliError("Could not retrieve TList fSums");
1792 fOutput = new TList;
1793 fOutput->SetName(GetListName());
1794 fOutput->SetOwner();
1795 results->Add(fOutput);
1798 if (!ReadSum(fSums, false)) {
1799 AliInfo("This task did not produce any output");
1803 if (!fSumMC) ReadSum(fSums, true);
1805 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1808 AliError("Couldn't find histogram 'triggers' in list");
1812 // --- Get normalization scaler ------------------------------------
1813 Double_t epsilonT = trigEff;
1814 Double_t epsilonT0 = trigEff0;
1815 DMSG(fDebug,2,"Using epsilonT=%f, epsilonT0=%f for 0x%x",
1816 epsilonT, epsilonT0, triggerMask);
1818 // Get our histograms
1820 TH2D* sum = fSum->CalcSum(fOutput, nSum, epsilonT0, epsilonT,
1821 marker, rootProj, corrEmpty);
1822 Double_t nSumMC = 0;
1824 if (fSumMC) sumMC = fSumMC->CalcSum(fOutput, nSumMC,
1825 epsilonT0, epsilonT, marker,
1826 rootProj, corrEmpty);
1828 AliError("Failed to get sum from summer - bailing out");
1833 Double_t ntotal = nSum;
1834 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal, &text);
1836 AliError("Failed to calculate normalization - bailing out");
1839 fOutput->Add(fTriggers->Clone());
1840 fOutput->Add(new TNamed("normCalc", text.Data()));
1842 // --- Make result and store ---------------------------------------
1843 MakeResult(sum, "", rootProj, corrEmpty, scaler, marker, color,
1846 // --- Process result from TrackRefs -------------------------------
1848 MakeResult(sumMC, "MC", rootProj, corrEmpty, scaler,
1849 GetMarkerStyle(GetMarkerBits(marker)+4), color,
1853 // if (!IsAllBin()) return;
1856 //____________________________________________________________________
1858 AliBasedNdetaTask::ApplyEmpiricalCorrection(const AliAODForwardMult* aod,
1861 if (!fEmpiricalCorrection || !data)
1863 Float_t zvertex=aod->GetIpZ();
1864 Int_t binzvertex=fEmpiricalCorrection->GetXaxis()->FindBin(zvertex);
1865 if(binzvertex<1||binzvertex>fEmpiricalCorrection->GetNbinsX())
1867 for (int i=1;i<=data->GetNbinsX();i++) {
1868 Int_t bincorrection=fEmpiricalCorrection->GetYaxis()
1869 ->FindBin(data->GetXaxis()->GetBinCenter(i));
1870 if(bincorrection<1||bincorrection>fEmpiricalCorrection->GetNbinsY())
1872 Float_t correction=fEmpiricalCorrection
1873 ->GetBinContent(binzvertex,bincorrection);
1874 if(correction<0.001) {
1875 data->SetBinContent(i,0,0);
1876 data->SetBinContent(i,data->GetNbinsY()+1,0);
1878 for(int j=1;j<=data->GetNbinsY();j++) {
1879 if (data->GetBinContent(i,j)>0.0) {
1880 data->SetBinContent(i,j,data->GetBinContent(i,j)*correction);
1881 data->SetBinError(i,j,data->GetBinError(i,j)*correction);