1 //====================================================================
2 #include "AliBasedNdetaTask.h"
8 #include <TParameter.h>
9 #include <AliAnalysisManager.h>
10 #include <AliAODEvent.h>
11 #include <AliAODHandler.h>
12 #include <AliAODInputHandler.h>
13 #include "AliForwardUtil.h"
14 #include "AliAODForwardMult.h"
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
32 fListOfCentralities(0),
37 fNormalizationScheme(kFull),
46 //____________________________________________________________________
47 AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
48 : AliAnalysisTaskSE(name),
49 fSums(0), // Container of sums
50 fOutput(0), // Container of output
51 fVtxMin(-10), // Minimum v_z
52 fVtxMax(10), // Maximum v_z
53 fTriggerMask(AliAODForwardMult::kInel),
54 fRebin(5), // Rebinning factor
61 fListOfCentralities(0),
66 fNormalizationScheme(kFull),
73 fListOfCentralities = new TObjArray(1);
75 // Set the normalisation scheme
76 SetNormalizationScheme(kFull);
78 // Set the trigger mask
79 SetTriggerMask(AliAODForwardMult::kInel);
81 // Output slot #1 writes into a TH1 container
82 DefineOutput(1, TList::Class());
83 DefineOutput(2, TList::Class());
86 //____________________________________________________________________
87 AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
88 : AliAnalysisTaskSE(o),
89 fSums(o.fSums), // TList* - Container of sums
90 fOutput(o.fOutput), // Container of output
91 fVtxMin(o.fVtxMin), // Double_t - Minimum v_z
92 fVtxMax(o.fVtxMax), // Double_t - Maximum v_z
93 fTriggerMask(o.fTriggerMask),// Int_t - Trigger mask
94 fRebin(o.fRebin), // Int_t - Rebinning factor
95 fCutEdges(o.fCutEdges), // Bool_t - Whether to cut edges when rebinning
96 fSymmetrice(o.fSymmetrice),
97 fCorrEmpty(o.fCorrEmpty),
98 fUseROOTProj(o.fUseROOTProj),
99 fTriggerEff(o.fTriggerEff),
100 fShapeCorr(o.fShapeCorr),
101 fListOfCentralities(o.fListOfCentralities),
102 fSNNString(o.fSNNString),
103 fSysString(o.fSysString),
105 fCentAxis(o.fCentAxis),
106 fNormalizationScheme(o.fNormalizationScheme),
107 fSchemeString(o.fSchemeString),
108 fTriggerString(o.fTriggerString)
111 //____________________________________________________________________
112 AliBasedNdetaTask::~AliBasedNdetaTask()
129 //________________________________________________________________________
131 AliBasedNdetaTask::SetCentralityAxis(UShort_t n, Short_t* bins)
134 fCentAxis = new TAxis();
135 fCentAxis->SetName("centAxis");
136 fCentAxis->SetTitle("Centrality [%]");
139 for (UShort_t i = 0; i <= n; i++)
140 dbins[i] = (bins[i] == 100 ? 100.1 : bins[i]);
141 fCentAxis->Set(n, dbins.GetArray());
144 //________________________________________________________________________
146 AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
149 // Add a centrality bin
155 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
156 AliInfo(Form("Adding centrality bin %p [%3d,%3d] @ %d", bin, low, high, at));
157 fListOfCentralities->AddAtAndExpand(bin, at);
160 //________________________________________________________________________
161 AliBasedNdetaTask::CentralityBin*
162 AliBasedNdetaTask::MakeCentralityBin(const char* name,
163 Short_t low, Short_t high) const
166 // Make a centrality bin
169 // name Name used for histograms
170 // low Low cut in percent
171 // high High cut in percent
174 // A newly created centrality bin
176 return new CentralityBin(name, low, high);
178 //________________________________________________________________________
180 AliBasedNdetaTask::SetNormalizationScheme(const char* what)
183 // Set normalisation scheme
189 TIter next(twhat.Tokenize(" ,|"));
190 while ((opt = static_cast<TObjString*>(next()))) {
191 TString s(opt->GetString());
192 if (s.IsNull()) continue;
195 case '-': add = false; // Fall through
196 case '+': s.Remove(0,1); // Remove character
199 if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
200 else if (s.CompareTo("SHAPE") == 0) bit = kShape;
201 else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
202 else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
203 else if (s.CompareTo("FULL") == 0) bit = kFull;
204 else if (s.CompareTo("NONE") == 0) bit = kNone;
206 Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
207 if (add) scheme |= bit;
210 SetNormalizationScheme(scheme);
212 //________________________________________________________________________
214 AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme)
216 fNormalizationScheme = scheme;
218 if (scheme == kFull) tit = "FULL";
220 if (scheme & kEventLevel) tit.Append("EVENT ");
221 if (scheme & kShape) tit.Append("SHAPE ");
222 if (scheme & kBackground) tit.Append("BACKGROUND ");
223 if (scheme & kTriggerEfficiency) tit.Append("TRIGGER");
225 tit = tit.Strip(TString::kBoth);
226 if (!fSchemeString) fSchemeString = new TNamed("scheme", "");
227 fSchemeString->SetTitle(tit);
228 fSchemeString->SetUniqueID(fNormalizationScheme);
230 //________________________________________________________________________
232 AliBasedNdetaTask::SetTriggerMask(const char* mask)
235 // Set the trigger maskl
240 SetTriggerMask(AliAODForwardMult::MakeTriggerMask(mask));
242 //________________________________________________________________________
244 AliBasedNdetaTask::SetTriggerMask(UShort_t mask)
247 TString tit(AliAODForwardMult::GetTriggerString(mask));
248 tit = tit.Strip(TString::kBoth);
249 if (!fTriggerString) fTriggerString = new TNamed("trigger", "");
250 fTriggerString->SetTitle(tit);
251 fTriggerString->SetUniqueID(fTriggerMask);
254 //________________________________________________________________________
256 AliBasedNdetaTask::SetShapeCorrection(const TH1* c)
259 // Set the shape correction (a.k.a., track correction) for selected
266 fShapeCorr = static_cast<TH1*>(c->Clone());
267 fShapeCorr->SetDirectory(0);
270 //________________________________________________________________________
272 AliBasedNdetaTask::UserCreateOutputObjects()
275 // Create output objects.
277 // This is called once per slave process
280 fSums->SetName(Form("%s_sums", GetName()));
283 // Automatically add 'all' centrality bin if nothing has been defined.
284 AddCentralityBin(0, 0, 0);
285 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
286 const TArrayD* bins = fCentAxis->GetXbins();
287 Int_t nbin = fCentAxis->GetNbins();
288 for (Int_t i = 0; i < nbin; i++)
289 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
291 fSums->Add(fCentAxis);
294 // Centrality histogram
295 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
296 fCent->SetDirectory(0);
300 // Loop over centrality bins
301 TIter next(fListOfCentralities);
302 CentralityBin* bin = 0;
303 while ((bin = static_cast<CentralityBin*>(next())))
304 bin->CreateOutputObjects(fSums);
306 // Check that we have an AOD input handler
307 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
308 AliAODInputHandler* ah =
309 dynamic_cast<AliAODInputHandler*>(am->GetInputEventHandler());
310 if (!ah) AliFatal("No AOD input handler set in analysis manager");
312 // Post data for ALL output slots >0 here, to get at least an empty histogram
315 //____________________________________________________________________
317 AliBasedNdetaTask::UserExec(Option_t *)
320 // Process a single event
326 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(InputEvent());
328 AliError("Cannot get the AOD event");
332 TObject* obj = aod->FindListObject("Forward");
334 AliWarning("No forward object found");
337 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
339 // Fill centrality histogram
340 Float_t cent = forward->GetCentrality();
343 // Get the histogram(s)
344 TH2D* data = GetHistogram(aod, false);
345 TH2D* dataMC = GetHistogram(aod, true);
347 // Loop over centrality bins
348 CentralityBin* allBin =
349 static_cast<CentralityBin*>(fListOfCentralities->At(0));
350 allBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax, data, dataMC);
352 // Find this centrality bin
353 if (fCentAxis && fCentAxis->GetNbins() > 0) {
354 Int_t icent = fCentAxis->FindBin(cent);
355 CentralityBin* thisBin = 0;
356 if (icent >= 1 && icent <= fCentAxis->GetNbins())
357 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
359 thisBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax,
363 // Here, we get the update
365 UShort_t sNN = forward->GetSNN();
366 fSNNString = new TNamed("sNN", "");
367 fSNNString->SetTitle(AliForwardUtil::CenterOfMassEnergyString(sNN));
368 fSNNString->SetUniqueID(sNN);
369 fSums->Add(fSNNString);
371 UShort_t sys = forward->GetSystem();
372 fSysString = new TNamed("sys", "");
373 fSysString->SetTitle(AliForwardUtil::CollisionSystemString(sys));
374 fSysString->SetUniqueID(sys);
375 fSums->Add(fSysString);
377 fSums->Add(fSchemeString);
378 fSums->Add(fTriggerString);
386 //________________________________________________________________________
388 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
389 const char* title, const char* ytitle)
392 // Set histogram graphical options, etc.
395 // h Histogram to modify
396 // colour Marker color
397 // marker Marker style
398 // title Title of histogram
399 // ytitle Title on y-axis.
402 h->SetMarkerColor(colour);
403 h->SetMarkerStyle(marker);
406 h->SetYTitle(ytitle);
407 h->GetXaxis()->SetTitleFont(132);
408 h->GetXaxis()->SetLabelFont(132);
409 h->GetXaxis()->SetNdivisions(10);
410 h->GetYaxis()->SetTitleFont(132);
411 h->GetYaxis()->SetLabelFont(132);
412 h->GetYaxis()->SetNdivisions(10);
413 h->GetYaxis()->SetDecimals();
417 //________________________________________________________________________
419 AliBasedNdetaTask::ProjectX(const TH2D* h,
428 // Project onto the X axis
433 // firstbin First bin to use
434 // lastbin Last bin to use
435 // error Whether to calculate errors
438 // Newly created histogram or null
442 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
444 TAxis* xaxis = h->GetXaxis();
445 TAxis* yaxis = h->GetYaxis();
446 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
447 xaxis->GetXmin(), xaxis->GetXmax());
448 static_cast<const TAttLine*>(h)->Copy(*ret);
449 static_cast<const TAttFill*>(h)->Copy(*ret);
450 static_cast<const TAttMarker*>(h)->Copy(*ret);
451 ret->GetXaxis()->ImportAttributes(xaxis);
453 Int_t first = firstbin;
454 Int_t last = lastbin;
455 if (first < 0) first = 0;
456 else if (first >= yaxis->GetNbins()+1) first = yaxis->GetNbins();
457 if (last < 0) last = yaxis->GetNbins();
458 else if (last > yaxis->GetNbins()+1) last = yaxis->GetNbins();
459 if (last-first < 0) {
460 AliWarningGeneral("AliBasedNdetaTask",
461 Form("Nothing to project [%d,%d]", first, last));
467 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
468 Int_t ybins = (last-first+1);
469 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
470 Double_t content = 0;
475 for (Int_t ybin = first; ybin <= last; ybin++) {
476 Double_t c1 = h->GetCellContent(xbin, ybin);
477 Double_t e1 = h->GetCellError(xbin, ybin);
480 if (c1 < 1e-12) continue;
490 if(content > 0 && nbins > 0) {
491 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
493 AliWarningGeneral(ret->GetName(),
494 Form("factor @ %d is %d/%d -> %f",
495 xbin, ybins, nbins, factor));
498 // Calculate weighted average
499 ret->SetBinContent(xbin, content * factor);
500 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
503 ret->SetBinContent(xbin, factor * content);
510 //________________________________________________________________________
512 AliBasedNdetaTask::Terminate(Option_t *)
515 // Called at end of event processing..
517 // This is called once in the master
522 // Draw result to screen, or perform fitting, normalizations Called
523 // once at the end of the query
525 fSums = dynamic_cast<TList*> (GetOutputData(1));
527 AliError("Could not retrieve TList fSums");
532 fOutput->SetName(Form("%s_result", GetName()));
535 fSNNString = static_cast<TNamed*>(fSums->FindObject("sNN"));
536 fSysString = static_cast<TNamed*>(fSums->FindObject("sys"));
537 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
538 fSchemeString = static_cast<TNamed*>(fSums->FindObject("scheme"));
539 fTriggerString = static_cast<TNamed*>(fSums->FindObject("trigger"));
541 if(fSysString && fSNNString &&
542 fSysString->GetUniqueID() == AliForwardUtil::kPP)
543 LoadNormalizationData(fSysString->GetUniqueID(),
544 fSNNString->GetUniqueID());
545 // Print before we loop
548 // Loop over centrality bins
549 TIter next(fListOfCentralities);
550 CentralityBin* bin = 0;
551 while ((bin = static_cast<CentralityBin*>(next())))
552 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr, fTriggerEff,
553 fSymmetrice, fRebin, fUseROOTProj, fCorrEmpty, fCutEdges,
554 fTriggerMask, GetColor(), GetMarker());
556 // Output collision energy string
557 if (fSNNString) fOutput->Add(fSNNString->Clone());
559 // Output collision system string
560 if (fSysString) fOutput->Add(fSysString->Clone());
562 // Output centrality axis
563 if (fCentAxis) fOutput->Add(fCentAxis);
565 // Output trigger string
566 if (fTriggerString) fOutput->Add(fTriggerString->Clone());
568 // Normalization string
569 if (fSchemeString) fOutput->Add(fSchemeString->Clone());
571 // Output vertex axis
572 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
573 vtxAxis->SetName("vtxAxis");
574 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
575 fOutput->Add(vtxAxis);
577 // Output trigger efficiency and shape correction
578 fOutput->Add(new TParameter<Double_t>("triggerEff", fTriggerEff));
579 if (fShapeCorr) fOutput->Add(fShapeCorr);
581 TNamed* options = new TNamed("options","");
583 str.Append(Form("Edges %scut, ", fCutEdges ? "" : "not "));
584 str.Append(Form("Empty bins %scorrected for, ", fCorrEmpty ? "" : "not "));
585 str.Append(Form("TH2::ProjectionX %sused", fUseROOTProj ? "" : "not "));
586 options->SetTitle(str);
587 fOutput->Add(options);
589 PostData(2, fOutput);
591 //________________________________________________________________________
593 AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
595 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
598 if(energy == 7000) snn.Form("7000");
599 if(energy == 2750) snn.Form("2750");
601 if(fShapeCorr && (fTriggerEff != 1)) {
602 AliInfo("Objects already set for normalization - no action taken");
606 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWG2/FORWARD/corrections/"
607 "Normalization/normalizationHists_%s_%s.root",
608 type.Data(),snn.Data()));
610 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
615 TString shapeCorName(Form("h%sNormalization",
616 fTriggerMask == AliAODForwardMult::kInel ? "Inel" :
617 fTriggerMask == AliAODForwardMult::kNSD ? "NSD" :
618 fTriggerMask == AliAODForwardMult::kInelGt0 ?
620 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
621 if (shapeCor) SetShapeCorrection(shapeCor);
623 // Trigger efficiency
624 TString effName(Form("%sTriggerEff",
625 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
626 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
627 fTriggerMask == AliAODForwardMult::kInelGt0 ?
629 TParameter<float>* eff = static_cast<TParameter<float>*>(fin->Get(effName));
630 if (eff) SetTriggerEff(eff->GetVal());
633 // Rescale the shape correction by the trigger efficiency
634 AliWarning(Form("Rescaling shape correction by trigger efficiency: "
635 "1/E_X=1/%f", fTriggerEff));
636 fShapeCorr->Scale(1. / fTriggerEff);
639 if (shapeCor && eff) AliInfo("Loaded objects for normalization.");
643 //________________________________________________________________________
645 AliBasedNdetaTask::Print(Option_t*) const
650 std::cout << this->ClassName() << ": " << this->GetName() << "\n"
652 << " Trigger: " << (fTriggerString ?
653 fTriggerString->GetTitle() :
655 << " Vertex range: [" << fVtxMin << ":" << fVtxMax << "]\n"
656 << " Rebin factor: " << fRebin << "\n"
657 << " Cut edges: " << fCutEdges << "\n"
658 << " Symmertrice: " << fSymmetrice << "\n"
659 << " Use TH2::ProjectionX: " << fUseROOTProj << "\n"
660 << " Correct for empty: " << fCorrEmpty << "\n"
661 << " Normalization scheme: " << (fSchemeString ?
662 fSchemeString->GetTitle() :
664 << " Trigger efficiency: " << fTriggerEff << "\n"
665 << " Shape correction: " << (fShapeCorr ?
666 fShapeCorr->GetName() :
668 << " sqrt(s_NN): " << (fSNNString ?
669 fSNNString->GetTitle() :
671 << " Collision system: " << (fSysString ?
672 fSysString->GetTitle() :
674 << " Centrality bins: " << (fCentAxis ? "" : "none");
676 Int_t nBins = fCentAxis->GetNbins();
677 const Double_t* bins = fCentAxis->GetXbins()->GetArray();
678 for (Int_t i = 0; i <= nBins; i++)
679 std::cout << (i==0 ? "" : "-") << bins[i];
681 std::cout << std::noboolalpha << std::endl;
685 //________________________________________________________________________
687 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
690 // Make a copy of the input histogram and rebin that histogram
693 // h Histogram to rebin
696 // New (rebinned) histogram
698 if (rebin <= 1) return 0;
700 Int_t nBins = h->GetNbinsX();
701 if(nBins % rebin != 0) {
702 AliWarningGeneral("AliBasedNdetaTask",
703 Form("Rebin factor %d is not a devisor of current number "
704 "of bins %d in the histogram %s",
705 rebin, nBins, h->GetName()));
710 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
711 h->GetName(), rebin)));
713 tmp->SetDirectory(0);
715 // The new number of bins
716 Int_t nBinsNew = nBins / rebin;
717 for(Int_t i = 1;i<= nBinsNew; i++) {
718 Double_t content = 0;
722 for(Int_t j = 1; j<=rebin;j++) {
723 Int_t bin = (i-1)*rebin + j;
724 Double_t c = h->GetBinContent(bin);
725 if (c <= 0) continue;
728 if (h->GetBinContent(bin+1)<=0 ||
729 h->GetBinContent(bin-1)<=0) {
731 AliWarningGeneral("AliBasedNdetaTask",
732 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
733 bin, c, h->GetName(),
734 bin+1, h->GetBinContent(bin+1),
735 bin-1, h->GetBinContent(bin-1)));
740 Double_t e = h->GetBinError(bin);
741 Double_t w = 1 / (e*e); // 1/c/c
748 if(content > 0 && nbins > 0) {
749 tmp->SetBinContent(i, wsum / sumw);
750 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
757 //__________________________________________________________________
759 AliBasedNdetaTask::Symmetrice(const TH1* h)
762 // Make an extension of @a h to make it symmetric about 0
765 // h Histogram to symmertrice
768 // Symmetric extension of @a h
770 Int_t nBins = h->GetNbinsX();
771 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
772 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
774 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
775 s->SetMarkerColor(h->GetMarkerColor());
776 s->SetMarkerSize(h->GetMarkerSize());
777 s->SetMarkerStyle(h->GetMarkerStyle()+4);
778 s->SetFillColor(h->GetFillColor());
779 s->SetFillStyle(h->GetFillStyle());
782 // Find the first and last bin with data
783 Int_t first = nBins+1;
785 for (Int_t i = 1; i <= nBins; i++) {
786 if (h->GetBinContent(i) <= 0) continue;
787 first = TMath::Min(first, i);
788 last = TMath::Max(last, i);
791 Double_t xfirst = h->GetBinCenter(first-1);
792 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
793 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
794 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
795 s->SetBinContent(j, h->GetBinContent(i));
796 s->SetBinError(j, h->GetBinError(i));
798 // Fill in overlap bin
799 s->SetBinContent(l2+1, h->GetBinContent(first));
800 s->SetBinError(l2+1, h->GetBinError(first));
804 //====================================================================
805 AliBasedNdetaTask::CentralityBin::CentralityBin()
819 //____________________________________________________________________
820 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
821 Short_t low, Short_t high)
835 // name Name used for histograms (e.g., Forward)
836 // low Lower centrality cut in percent
837 // high Upper centrality cut in percent
839 if (low <= 0 && high <= 0) {
842 SetTitle("All centralities");
847 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
850 //____________________________________________________________________
851 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
857 fTriggers(o.fTriggers),
865 // other Object to copy from
868 //____________________________________________________________________
869 AliBasedNdetaTask::CentralityBin::~CentralityBin()
874 if (fSums) fSums->Delete();
875 if (fOutput) fOutput->Delete();
878 //____________________________________________________________________
879 AliBasedNdetaTask::CentralityBin&
880 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
883 // Assignment operator
886 // other Object to assign from
891 SetName(o.GetName());
892 SetTitle(o.GetTitle());
897 fTriggers = o.fTriggers;
903 //____________________________________________________________________
905 AliBasedNdetaTask::CentralityBin::GetListName() const
913 if (IsAllBin()) return "all";
914 return Form("cent%03d_%03d", fLow, fHigh);
916 //____________________________________________________________________
918 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir)
921 // Create output objects
927 fSums->SetName(GetListName());
931 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers");
932 fTriggers->SetDirectory(0);
933 fSums->Add(fTriggers);
935 //____________________________________________________________________
937 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
940 // Create sum histogram
943 // data Data histogram to clone
944 // mc (optional) MC histogram to clone
946 fSum = static_cast<TH2D*>(data->Clone(GetName()));
947 fSum->SetDirectory(0);
951 // If no MC data is given, then do not create MC sum histogram
954 fSumMC = static_cast<TH2D*>(mc->Clone(Form("%sMC", GetName())));
955 fSumMC->SetDirectory(0);
960 //____________________________________________________________________
962 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
964 Double_t vzMin, Double_t vzMax)
967 // Check the trigger, vertex, and centrality
973 // true if the event is to be used
975 if (!forward) return false;
977 // We do not check for centrality here - it's already done
978 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
982 //____________________________________________________________________
984 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
986 Double_t vzMin, Double_t vzMax,
987 const TH2D* data, const TH2D* mc)
993 // forward Forward data (for trigger, vertex, & centrality)
994 // triggerMask Trigger mask
995 // vzMin Minimum IP z coordinate
996 // vzMax Maximum IP z coordinate
997 // data Data histogram
1000 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
1002 if (!fSum) CreateSums(data, mc);
1005 if (mc) fSumMC->Add(mc);
1008 //________________________________________________________________________
1010 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
1013 Double_t& ntotal) const
1016 // Calculate normalization
1019 // t Trigger histogram
1020 // scheme Normaliztion scheme
1022 // ntotal On return, contains the number of events.
1025 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1026 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1027 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1028 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1029 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1030 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1031 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1032 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1033 Double_t nAccepted = t.GetBinContent(AliAODForwardMult::kAccepted);
1035 if (nTriggered <= 0.1) {
1036 AliError("Number of triggered events <= 0");
1039 if (nWithVertex <= 0.1) {
1040 AliError("Number of events with vertex <= 0");
1044 Double_t vtxEff = nWithVertex / nTriggered;
1045 Double_t scaler = 1;
1046 Double_t beta = nA + nC - 2*nE;
1048 if (scheme & kEventLevel) {
1049 ntotal = nAccepted / vtxEff;
1051 AliInfo(Form("Calculating event normalisation as\n"
1052 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1053 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1056 if (scheme & kBackground) {
1058 // s = --------- = ------------- = ------------
1059 // 1 - beta 1 - beta E_V 1 - beta N_V
1060 // --- ---- -------- ---- ---
1061 // E_V N_V N_V N_V N_T
1069 ntotal -= nAccepted * beta / nWithVertex;
1070 // This one is direct and correct.
1071 // scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1072 // A simpler expresion
1073 scaler /= (1 - beta / nTriggered); // 0.831631 -> 0.780689
1074 AliInfo(Form("Calculating event normalisation as\n"
1075 " beta = N_a + N_c + 2 N_e = %d + %d - 2 * %d = %d\n"
1076 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1077 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta),
1078 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1079 Int_t(nWithVertex), ntotal, scaler));
1082 if (scheme & kTriggerEfficiency) {
1085 AliInfo(Form("Correcting for trigger efficiency:\n"
1086 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1087 trigEff, Int_t(ntotal), ntotal / trigEff, scaler));
1091 " Total of %9d events for %s\n"
1092 " of these %9d have an offline trigger\n"
1093 " of these N_T = %9d has the selected trigger\n"
1094 " of these N_V = %9d has a vertex\n"
1095 " of these N_A = %9d were in the selected range\n"
1096 " Triggers by hardware type:\n"
1098 " N_ac = %9d (%d+%d)\n"
1100 " Vertex efficiency: %f\n"
1101 " Trigger efficiency: %f\n"
1102 " Total number of events: N = %f\n"
1103 " Scaler (N_A/N): %f",
1104 Int_t(nAll), GetTitle(), Int_t(nOffline),
1105 Int_t(nTriggered), Int_t(nWithVertex), Int_t(nAccepted),
1106 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1107 vtxEff, trigEff, ntotal, scaler));
1111 //________________________________________________________________________
1113 AliBasedNdetaTask::CentralityBin::MakeResult(const TH2D* sum,
1114 const char* postfix,
1117 const TH1* shapeCorr,
1126 // Generate the dN/deta result from input
1129 // sum Sum of 2D hists
1130 // postfix Post fix on names
1131 // rootProj Whether to use ROOT TH2::ProjectionX
1132 // corrEmpty Correct for empty bins
1133 // shapeCorr Shape correction to use
1134 // scaler Event-level normalization scaler
1135 // symmetrice Whether to make symmetric extensions
1136 // rebin Whether to rebin
1137 // cutEdges Whether to cut edges when rebinning
1139 TH2D* copy = static_cast<TH2D*>(sum->Clone(Form("d2Ndetadphi%s%s",
1140 GetName(), postfix)));
1141 TH1D* accNorm = ProjectX(sum, Form("norm%s%s",GetName(), postfix), 0, 0,
1142 rootProj, corrEmpty, false);
1143 accNorm->SetDirectory(0);
1145 // ---- Scale by shape correction ----------------------------------
1146 if (shapeCorr) copy->Divide(shapeCorr);
1147 else AliInfo("No shape correction specified, or disabled");
1149 // Normalize to the acceptance -
1150 // dndeta->Divide(accNorm);
1151 for (Int_t i = 1; i <= copy->GetNbinsX(); i++) {
1152 for (Int_t j = 1; j <= copy->GetNbinsY(); j++) {
1153 Double_t c = copy->GetBinContent(i, j);
1154 Double_t e = copy->GetBinError(i, j);
1155 Double_t a = accNorm->GetBinContent(i);
1156 copy->SetBinContent(i, j, a <= 0 ? 0 : c / a);
1157 copy->SetBinError(i, j, a <= 0 ? 0 : e / a);
1160 // --- Event-level normalization -----------------------------------
1161 copy->Scale(scaler);
1163 // --- Project on X axis -------------------------------------------
1164 TH1D* dndeta = ProjectX(copy, Form("dndeta%s%s",GetName(), postfix),
1165 1, sum->GetNbinsY(), rootProj, corrEmpty);
1166 dndeta->SetDirectory(0);
1167 // Event-level normalization
1168 dndeta->Scale(1., "width");
1169 copy->Scale(1., "width");
1171 // --- Set some histogram attributes -------------------------------
1172 SetHistogramAttributes(dndeta, color, marker, Form("ALICE %s", GetName()));
1173 SetHistogramAttributes(accNorm, color, marker, Form("ALICE %s normalisation",
1176 // --- Make symmetric extensions and rebinnings --------------------
1177 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1178 fOutput->Add(dndeta);
1179 fOutput->Add(accNorm);
1181 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1182 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1185 //________________________________________________________________________
1187 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1190 const TH1* shapeCorr,
1202 // End of processing
1205 // sums List of sums
1206 // results Output list of results
1207 // shapeCorr Shape correction or nil
1208 // trigEff Trigger efficiency
1209 // symmetrice Whether to symmetrice the results
1210 // rebin Whether to rebin the results
1211 // corrEmpty Whether to correct for empty bins
1212 // cutEdges Whether to cut edges when rebinning
1213 // triggerMask Trigger mask
1216 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1218 AliError("Could not retrieve TList fSums");
1222 fOutput = new TList;
1223 fOutput->SetName(GetListName());
1224 fOutput->SetOwner();
1225 results->Add(fOutput);
1227 fSum = static_cast<TH2D*>(fSums->FindObject(GetName()));
1228 fSumMC = static_cast<TH2D*>(fSums->FindObject(Form("%sMC", GetName())));
1229 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1232 AliError("Couldn't find histogram 'triggers' in list");
1236 AliError(Form("Couldn't find histogram '%s' in list", GetName()));
1240 // --- Get normalization scaler ------------------------------------
1241 Double_t ntotal = 0;
1242 Double_t epsilonT = trigEff;
1244 if (triggerMask == AliAODForwardMult::kNSD) {
1245 // This is a local change
1247 AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
1249 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal);
1251 AliError("Failed to calculate normalization - bailing out");
1254 fOutput->Add(fTriggers->Clone());
1256 // --- Make result and store ---------------------------------------
1257 MakeResult(fSum, "", rootProj, corrEmpty, (scheme & kShape) ? shapeCorr : 0,
1258 scaler, symmetrice, rebin, cutEdges, color, marker);
1260 // --- Process result from TrackRefs -------------------------------
1262 MakeResult(fSumMC, "MC", rootProj, corrEmpty,
1263 (scheme & kShape) ? shapeCorr : 0,
1264 scaler, symmetrice, rebin, cutEdges, color+2, marker);
1268 if (!IsAllBin()) return;
1270 TFile* forward = TFile::Open("forward.root", "READ");
1272 AliWarning(Form("No forward.root file found"));
1276 TH1D* shapeCorrProj = 0;
1278 shapeCorrProj = static_cast<const TH2D*>(shapeCorr)->ProjectionX();
1279 shapeCorrProj->Scale(1. / shapeCorr->GetNbinsY());
1280 shapeCorrProj->SetDirectory(0);
1281 fOutput->Add(shapeCorrProj);
1284 TList* official = static_cast<TList*>(forward->Get("official"));
1286 TH1F* histEta = static_cast<TH1F*>(official->FindObject("fHistEta"));
1288 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1289 histEta->GetXaxis()->GetXmin(),
1290 histEta->GetXaxis()->GetXmax());
1291 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1292 oEta->SetBinContent(i, histEta->GetBinContent(i));
1293 oEta->SetBinError(i, histEta->GetBinError(i));
1295 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1296 oEta->Scale(1./ntotal, "width");
1297 oEta->SetDirectory(0);
1298 oEta->SetMarkerStyle(marker+4);
1299 oEta->SetMarkerColor(color+5);
1301 fOutput->Add(Rebin(oEta, rebin, false));
1304 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1305 official->GetName()));
1308 AliWarning(Form("Couldn't find list 'official' in %s",forward->GetName()));
1310 TList* tracks = static_cast<TList*>(forward->Get("tracks"));
1312 TH1F* histEta = static_cast<TH1F*>(tracks->FindObject("fHistEta"));
1314 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1315 histEta->GetXaxis()->GetXmin(),
1316 histEta->GetXaxis()->GetXmax());
1317 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1318 oEta->SetBinContent(i, histEta->GetBinContent(i));
1319 oEta->SetBinError(i, histEta->GetBinError(i));
1321 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1322 oEta->Scale(1./ntotal, "width");
1323 oEta->SetDirectory(0);
1324 oEta->SetMarkerStyle(marker);
1325 oEta->SetMarkerColor(color+5);
1327 fOutput->Add(Rebin(oEta, rebin, false));
1330 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1331 tracks->GetName()));
1334 AliWarning(Form("Couldn't find list 'tracks' in %s",forward->GetName()));