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
31 fListOfCentralities(0),
36 fNormalizationScheme(kFull),
45 //____________________________________________________________________
46 AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
47 : AliAnalysisTaskSE(name),
48 fSums(0), // Container of sums
49 fOutput(0), // Container of output
50 fVtxMin(-10), // Minimum v_z
51 fVtxMax(10), // Maximum v_z
52 fTriggerMask(AliAODForwardMult::kInel),
53 fRebin(5), // Rebinning factor
59 fListOfCentralities(0),
64 fNormalizationScheme(kFull),
71 fListOfCentralities = new TObjArray(1);
73 // Set the normalisation scheme
74 SetNormalizationScheme(kFull);
76 // Set the trigger mask
77 SetTriggerMask(AliAODForwardMult::kInel);
79 // Output slot #1 writes into a TH1 container
80 DefineOutput(1, TList::Class());
81 DefineOutput(2, TList::Class());
84 //____________________________________________________________________
85 AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
86 : AliAnalysisTaskSE(o),
87 fSums(o.fSums), // TList* - Container of sums
88 fOutput(o.fOutput), // Container of output
89 fVtxMin(o.fVtxMin), // Double_t - Minimum v_z
90 fVtxMax(o.fVtxMax), // Double_t - Maximum v_z
91 fTriggerMask(o.fTriggerMask),// Int_t - Trigger mask
92 fRebin(o.fRebin), // Int_t - Rebinning factor
93 fCutEdges(o.fCutEdges), // Bool_t - Whether to cut edges when rebinning
96 fTriggerEff(o.fTriggerEff),
97 fShapeCorr(o.fShapeCorr),
98 fListOfCentralities(o.fListOfCentralities),
99 fSNNString(o.fSNNString),
100 fSysString(o.fSysString),
102 fCentAxis(o.fCentAxis),
103 fNormalizationScheme(o.fNormalizationScheme),
104 fSchemeString(o.fSchemeString),
105 fTriggerString(o.fTriggerString)
108 //____________________________________________________________________
109 AliBasedNdetaTask::~AliBasedNdetaTask()
126 //________________________________________________________________________
128 AliBasedNdetaTask::SetCentralityAxis(UShort_t n, Short_t* bins)
131 fCentAxis = new TAxis();
132 fCentAxis->SetName("centAxis");
133 fCentAxis->SetTitle("Centrality [%]");
136 for (UShort_t i = 0; i <= n; i++)
137 dbins[i] = (bins[i] == 100 ? 100.1 : bins[i]);
138 fCentAxis->Set(n, dbins.GetArray());
141 //________________________________________________________________________
143 AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
146 // Add a centrality bin
152 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
153 AliInfo(Form("Adding centrality bin %p [%3d,%3d] @ %d", bin, low, high, at));
154 fListOfCentralities->AddAtAndExpand(bin, at);
157 //________________________________________________________________________
158 AliBasedNdetaTask::CentralityBin*
159 AliBasedNdetaTask::MakeCentralityBin(const char* name,
160 Short_t low, Short_t high) const
163 // Make a centrality bin
166 // name Name used for histograms
167 // low Low cut in percent
168 // high High cut in percent
171 // A newly created centrality bin
173 return new CentralityBin(name, low, high);
175 //________________________________________________________________________
177 AliBasedNdetaTask::SetNormalizationScheme(const char* what)
180 // Set normalisation scheme
186 TIter next(twhat.Tokenize(" ,|"));
187 while ((opt = static_cast<TObjString*>(next()))) {
188 TString s(opt->GetString());
189 if (s.IsNull()) continue;
192 case '-': add = false; // Fall through
193 case '+': s.Remove(0,1); // Remove character
196 if (s.CompareTo("EVENT") == 0) bit = kEventLevel;
197 else if (s.CompareTo("SHAPE") == 0) bit = kShape;
198 else if (s.CompareTo("BACKGROUND")== 0) bit = kBackground;
199 else if (s.CompareTo("TRIGGER") == 0) bit = kTriggerEfficiency;
200 else if (s.CompareTo("FULL") == 0) bit = kFull;
201 else if (s.CompareTo("NONE") == 0) bit = kNone;
203 Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
204 if (add) scheme |= bit;
207 SetNormalizationScheme(scheme);
209 //________________________________________________________________________
211 AliBasedNdetaTask::SetNormalizationScheme(UShort_t scheme)
213 fNormalizationScheme = scheme;
215 if (scheme == kFull) tit = "FULL";
217 if (scheme & kEventLevel) tit.Append("EVENT ");
218 if (scheme & kShape) tit.Append("SHAPE ");
219 if (scheme & kBackground) tit.Append("BACKGROUND ");
220 if (scheme & kTriggerEfficiency) tit.Append("TRIGGER");
222 tit = tit.Strip(TString::kBoth);
223 if (!fSchemeString) fSchemeString = new TNamed("scheme", "");
224 fSchemeString->SetTitle(tit);
225 fSchemeString->SetUniqueID(fNormalizationScheme);
227 //________________________________________________________________________
229 AliBasedNdetaTask::SetTriggerMask(const char* mask)
232 // Set the trigger maskl
237 SetTriggerMask(AliAODForwardMult::MakeTriggerMask(mask));
239 //________________________________________________________________________
241 AliBasedNdetaTask::SetTriggerMask(UShort_t mask)
244 TString tit(AliAODForwardMult::GetTriggerString(mask));
245 tit = tit.Strip(TString::kBoth);
246 if (!fTriggerString) fTriggerString = new TNamed("trigger", "");
247 fTriggerString->SetTitle(tit);
248 fTriggerString->SetUniqueID(fTriggerMask);
251 //________________________________________________________________________
253 AliBasedNdetaTask::SetShapeCorrection(const TH1* c)
256 // Set the shape correction (a.k.a., track correction) for selected
263 fShapeCorr = static_cast<TH1*>(c->Clone());
264 fShapeCorr->SetDirectory(0);
267 //________________________________________________________________________
269 AliBasedNdetaTask::UserCreateOutputObjects()
272 // Create output objects.
274 // This is called once per slave process
277 fSums->SetName(Form("%s_sums", GetName()));
280 // Automatically add 'all' centrality bin if nothing has been defined.
281 AddCentralityBin(0, 0, 0);
282 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
283 const TArrayD* bins = fCentAxis->GetXbins();
284 Int_t nbin = fCentAxis->GetNbins();
285 for (Int_t i = 0; i < nbin; i++)
286 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
288 fSums->Add(fCentAxis);
291 // Centrality histogram
292 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
293 fCent->SetDirectory(0);
297 // Loop over centrality bins
298 TIter next(fListOfCentralities);
299 CentralityBin* bin = 0;
300 while ((bin = static_cast<CentralityBin*>(next())))
301 bin->CreateOutputObjects(fSums);
303 // Check that we have an AOD input handler
304 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
305 AliAODInputHandler* ah =
306 dynamic_cast<AliAODInputHandler*>(am->GetInputEventHandler());
307 if (!ah) AliFatal("No AOD input handler set in analysis manager");
309 // Post data for ALL output slots >0 here, to get at least an empty histogram
312 //____________________________________________________________________
314 AliBasedNdetaTask::UserExec(Option_t *)
317 // Process a single event
323 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(InputEvent());
325 AliError("Cannot get the AOD event");
329 TObject* obj = aod->FindListObject("Forward");
331 AliWarning("No forward object found");
334 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
336 // Fill centrality histogram
337 Float_t cent = forward->GetCentrality();
340 // Get the histogram(s)
341 TH2D* data = GetHistogram(aod, false);
342 TH2D* dataMC = GetHistogram(aod, true);
344 // Loop over centrality bins
345 CentralityBin* allBin =
346 static_cast<CentralityBin*>(fListOfCentralities->At(0));
347 allBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax, data, dataMC);
349 // Find this centrality bin
350 if (fCentAxis && fCentAxis->GetNbins() > 0) {
351 Int_t icent = fCentAxis->FindBin(cent);
352 CentralityBin* thisBin = 0;
353 if (icent >= 1 && icent <= fCentAxis->GetNbins())
354 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
356 thisBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax,
360 // Here, we get the update
362 UShort_t sNN = forward->GetSNN();
363 fSNNString = new TNamed("sNN", "");
364 fSNNString->SetTitle(AliForwardUtil::CenterOfMassEnergyString(sNN));
365 fSNNString->SetUniqueID(sNN);
366 fSums->Add(fSNNString);
368 UShort_t sys = forward->GetSystem();
369 fSysString = new TNamed("sys", "");
370 fSysString->SetTitle(AliForwardUtil::CollisionSystemString(sys));
371 fSysString->SetUniqueID(sys);
372 fSums->Add(fSysString);
374 fSums->Add(fSchemeString);
375 fSums->Add(fTriggerString);
383 //________________________________________________________________________
385 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
386 const char* title, const char* ytitle)
389 // Set histogram graphical options, etc.
392 // h Histogram to modify
393 // colour Marker color
394 // marker Marker style
395 // title Title of histogram
396 // ytitle Title on y-axis.
399 h->SetMarkerColor(colour);
400 h->SetMarkerStyle(marker);
403 h->SetYTitle(ytitle);
404 h->GetXaxis()->SetTitleFont(132);
405 h->GetXaxis()->SetLabelFont(132);
406 h->GetXaxis()->SetNdivisions(10);
407 h->GetYaxis()->SetTitleFont(132);
408 h->GetYaxis()->SetLabelFont(132);
409 h->GetYaxis()->SetNdivisions(10);
410 h->GetYaxis()->SetDecimals();
414 //________________________________________________________________________
416 AliBasedNdetaTask::ProjectX(const TH2D* h,
424 // Project onto the X axis
429 // firstbin First bin to use
430 // lastbin Last bin to use
431 // error Whether to calculate errors
434 // Newly created histogram or null
438 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
441 TAxis* xaxis = h->GetXaxis();
442 TAxis* yaxis = h->GetYaxis();
443 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
444 xaxis->GetXmin(), xaxis->GetXmax());
445 static_cast<const TAttLine*>(h)->Copy(*ret);
446 static_cast<const TAttFill*>(h)->Copy(*ret);
447 static_cast<const TAttMarker*>(h)->Copy(*ret);
448 ret->GetXaxis()->ImportAttributes(xaxis);
450 Int_t first = firstbin;
451 Int_t last = lastbin;
452 if (first < 0) first = 0;
453 else if (first >= yaxis->GetNbins()+1) first = yaxis->GetNbins();
454 if (last < 0) last = yaxis->GetNbins();
455 else if (last > yaxis->GetNbins()+1) last = yaxis->GetNbins();
456 if (last-first < 0) {
457 AliWarningGeneral("AliBasedNdetaTask",
458 Form("Nothing to project [%d,%d]", first, last));
464 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
465 Int_t ybins = (last-first+1);
466 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
467 Double_t content = 0;
472 for (Int_t ybin = first; ybin <= last; ybin++) {
473 Double_t c1 = h->GetCellContent(xbin, ybin);
474 Double_t e1 = h->GetCellError(xbin, ybin);
477 if (c1 < 1e-12) continue;
487 if(content > 0 && nbins > 0) {
488 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
490 // Calculate weighted average
491 ret->SetBinContent(xbin, content * factor);
492 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
495 ret->SetBinContent(xbin, factor * content);
502 //________________________________________________________________________
504 AliBasedNdetaTask::Terminate(Option_t *)
507 // Called at end of event processing..
509 // This is called once in the master
514 // Draw result to screen, or perform fitting, normalizations Called
515 // once at the end of the query
517 fSums = dynamic_cast<TList*> (GetOutputData(1));
519 AliError("Could not retrieve TList fSums");
524 fOutput->SetName(Form("%s_result", GetName()));
527 fSNNString = static_cast<TNamed*>(fSums->FindObject("sNN"));
528 fSysString = static_cast<TNamed*>(fSums->FindObject("sys"));
529 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
530 fSchemeString = static_cast<TNamed*>(fSums->FindObject("scheme"));
531 fTriggerString = static_cast<TNamed*>(fSums->FindObject("trigger"));
533 if(fSysString && fSNNString &&
534 fSysString->GetUniqueID() == AliForwardUtil::kPP)
535 LoadNormalizationData(fSysString->GetUniqueID(),
536 fSNNString->GetUniqueID());
537 // Print before we loop
540 // Loop over centrality bins
541 TIter next(fListOfCentralities);
542 CentralityBin* bin = 0;
543 while ((bin = static_cast<CentralityBin*>(next())))
544 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr, fTriggerEff,
545 fSymmetrice, fRebin, fCorrEmpty, fCutEdges,
546 fTriggerMask, GetColor(), GetMarker());
548 // Output collision energy string
549 if (fSNNString) fOutput->Add(fSNNString->Clone());
551 // Output collision system string
552 if (fSysString) fOutput->Add(fSysString->Clone());
554 // Output centrality axis
555 if (fCentAxis) fOutput->Add(fCentAxis);
557 // Output trigger string
558 if (fTriggerString) fOutput->Add(fTriggerString->Clone());
560 // Normalization string
561 if (fSchemeString) fOutput->Add(fSchemeString->Clone());
563 // Output vertex axis
564 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
565 vtxAxis->SetName("vtxAxis");
566 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
567 fOutput->Add(vtxAxis);
569 // Output trigger efficiency and shape correction
570 fOutput->Add(new TParameter<Double_t>("triggerEff", fTriggerEff));
571 if (fShapeCorr) fOutput->Add(fShapeCorr);
573 PostData(2, fOutput);
575 //________________________________________________________________________
577 AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
579 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
582 if(energy == 7000) snn.Form("7000");
583 if(energy == 2750) snn.Form("2750");
585 if(fShapeCorr && (fTriggerEff != 1)) {
586 AliInfo("Objects already set for normalization - no action taken");
590 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWG2/FORWARD/corrections/"
591 "Normalization/normalizationHists_%s_%s.root",
592 type.Data(),snn.Data()));
594 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
599 TString shapeCorName(Form("h%sNormalization",
600 fTriggerMask == AliAODForwardMult::kInel ? "Inel" :
601 fTriggerMask == AliAODForwardMult::kNSD ? "NSD" :
602 fTriggerMask == AliAODForwardMult::kInelGt0 ?
604 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
605 if (shapeCor) SetShapeCorrection(shapeCor);
607 // Trigger efficiency
608 TString effName(Form("%sTriggerEff",
609 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
610 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
611 fTriggerMask == AliAODForwardMult::kInelGt0 ?
613 TParameter<float>* eff = static_cast<TParameter<float>*>(fin->Get(effName));
614 if (eff) SetTriggerEff(eff->GetVal());
617 // Rescale the shape correction by the trigger efficiency
618 AliWarning(Form("Rescaling shape correction by trigger efficiency: "
619 "1/E_X=1/%f", fTriggerEff));
620 fShapeCorr->Scale(1. / fTriggerEff);
623 if (shapeCor && eff) AliInfo("Loaded objects for normalization.");
627 //________________________________________________________________________
629 AliBasedNdetaTask::Print(Option_t*) const
634 std::cout << this->ClassName() << ": " << this->GetName() << "\n"
636 << " Trigger: " << (fTriggerString ?
637 fTriggerString->GetTitle() :
639 << " Vertex range: [" << fVtxMin << ":" << fVtxMax << "]\n"
640 << " Rebin factor: " << fRebin << "\n"
641 << " Cut edges: " << fCutEdges << "\n"
642 << " Symmertrice: " << fSymmetrice << "\n"
643 << " Correct for empty: " << fCorrEmpty << "\n"
644 << " Normalization scheme: " << (fSchemeString ?
645 fSchemeString->GetTitle() :
647 << " Trigger efficiency: " << fTriggerEff << "\n"
648 << " Shape correction: " << (fShapeCorr ?
649 fShapeCorr->GetName() :
651 << " sqrt(s_NN): " << (fSNNString ?
652 fSNNString->GetTitle() :
654 << " Collision system: " << (fSysString ?
655 fSysString->GetTitle() :
657 << " Centrality bins: " << (fCentAxis ? "" : "none");
659 Int_t nBins = fCentAxis->GetNbins();
660 const Double_t* bins = fCentAxis->GetXbins()->GetArray();
661 for (Int_t i = 0; i <= nBins; i++)
662 std::cout << (i==0 ? "" : "-") << bins[i];
664 std::cout << std::noboolalpha << std::endl;
668 //________________________________________________________________________
670 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
673 // Make a copy of the input histogram and rebin that histogram
676 // h Histogram to rebin
679 // New (rebinned) histogram
681 if (rebin <= 1) return 0;
683 Int_t nBins = h->GetNbinsX();
684 if(nBins % rebin != 0) {
685 AliWarningGeneral("AliBasedNdetaTask",
686 Form("Rebin factor %d is not a devisor of current number "
687 "of bins %d in the histogram %s",
688 rebin, nBins, h->GetName()));
693 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
694 h->GetName(), rebin)));
696 tmp->SetDirectory(0);
698 // The new number of bins
699 Int_t nBinsNew = nBins / rebin;
700 for(Int_t i = 1;i<= nBinsNew; i++) {
701 Double_t content = 0;
705 for(Int_t j = 1; j<=rebin;j++) {
706 Int_t bin = (i-1)*rebin + j;
707 Double_t c = h->GetBinContent(bin);
708 if (c <= 0) continue;
711 if (h->GetBinContent(bin+1)<=0 ||
712 h->GetBinContent(bin-1)<=0) {
714 AliWarningGeneral("AliBasedNdetaTask",
715 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
716 bin, c, h->GetName(),
717 bin+1, h->GetBinContent(bin+1),
718 bin-1, h->GetBinContent(bin-1)));
723 Double_t e = h->GetBinError(bin);
724 Double_t w = 1 / (e*e); // 1/c/c
731 if(content > 0 && nbins > 0) {
732 tmp->SetBinContent(i, wsum / sumw);
733 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
740 //__________________________________________________________________
742 AliBasedNdetaTask::Symmetrice(const TH1* h)
745 // Make an extension of @a h to make it symmetric about 0
748 // h Histogram to symmertrice
751 // Symmetric extension of @a h
753 Int_t nBins = h->GetNbinsX();
754 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
755 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
757 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
758 s->SetMarkerColor(h->GetMarkerColor());
759 s->SetMarkerSize(h->GetMarkerSize());
760 s->SetMarkerStyle(h->GetMarkerStyle()+4);
761 s->SetFillColor(h->GetFillColor());
762 s->SetFillStyle(h->GetFillStyle());
765 // Find the first and last bin with data
766 Int_t first = nBins+1;
768 for (Int_t i = 1; i <= nBins; i++) {
769 if (h->GetBinContent(i) <= 0) continue;
770 first = TMath::Min(first, i);
771 last = TMath::Max(last, i);
774 Double_t xfirst = h->GetBinCenter(first-1);
775 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
776 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
777 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
778 s->SetBinContent(j, h->GetBinContent(i));
779 s->SetBinError(j, h->GetBinError(i));
781 // Fill in overlap bin
782 s->SetBinContent(l2+1, h->GetBinContent(first));
783 s->SetBinError(l2+1, h->GetBinError(first));
787 //====================================================================
788 AliBasedNdetaTask::CentralityBin::CentralityBin()
802 //____________________________________________________________________
803 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
804 Short_t low, Short_t high)
818 // name Name used for histograms (e.g., Forward)
819 // low Lower centrality cut in percent
820 // high Upper centrality cut in percent
822 if (low <= 0 && high <= 0) {
825 SetTitle("All centralities");
830 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
833 //____________________________________________________________________
834 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
840 fTriggers(o.fTriggers),
848 // other Object to copy from
851 //____________________________________________________________________
852 AliBasedNdetaTask::CentralityBin::~CentralityBin()
857 if (fSums) fSums->Delete();
858 if (fOutput) fOutput->Delete();
861 //____________________________________________________________________
862 AliBasedNdetaTask::CentralityBin&
863 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
866 // Assignment operator
869 // other Object to assign from
874 SetName(o.GetName());
875 SetTitle(o.GetTitle());
880 fTriggers = o.fTriggers;
886 //____________________________________________________________________
888 AliBasedNdetaTask::CentralityBin::GetListName() const
896 if (IsAllBin()) return "all";
897 return Form("cent%03d_%03d", fLow, fHigh);
899 //____________________________________________________________________
901 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir)
904 // Create output objects
910 fSums->SetName(GetListName());
914 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers");
915 fTriggers->SetDirectory(0);
916 fSums->Add(fTriggers);
918 //____________________________________________________________________
920 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
923 // Create sum histogram
926 // data Data histogram to clone
927 // mc (optional) MC histogram to clone
929 fSum = static_cast<TH2D*>(data->Clone(GetName()));
930 fSum->SetDirectory(0);
934 // If no MC data is given, then do not create MC sum histogram
937 fSumMC = static_cast<TH2D*>(mc->Clone(Form("%sMC", GetName())));
938 fSumMC->SetDirectory(0);
943 //____________________________________________________________________
945 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
947 Double_t vzMin, Double_t vzMax)
950 // Check the trigger, vertex, and centrality
956 // true if the event is to be used
958 if (!forward) return false;
960 // We do not check for centrality here - it's already done
961 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
965 //____________________________________________________________________
967 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
969 Double_t vzMin, Double_t vzMax,
970 const TH2D* data, const TH2D* mc)
976 // forward Forward data (for trigger, vertex, & centrality)
977 // triggerMask Trigger mask
978 // vzMin Minimum IP z coordinate
979 // vzMax Maximum IP z coordinate
980 // data Data histogram
983 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
985 if (!fSum) CreateSums(data, mc);
988 if (mc) fSumMC->Add(mc);
991 //________________________________________________________________________
993 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
996 Double_t& ntotal) const
999 // Calculate normalization
1002 // t Trigger histogram
1003 // scheme Normaliztion scheme
1005 // ntotal On return, contains the number of events.
1008 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1009 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1010 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1011 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1012 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1013 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1014 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1015 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1016 Double_t nAccepted = t.GetBinContent(AliAODForwardMult::kAccepted);
1018 if (nTriggered <= 0.1) {
1019 AliError("Number of triggered events <= 0");
1022 if (nWithVertex <= 0.1) {
1023 AliError("Number of events with vertex <= 0");
1027 Double_t vtxEff = nWithVertex / nTriggered;
1028 Double_t scaler = 1;
1029 Double_t beta = nA + nC - 2*nE;
1031 if (scheme & kEventLevel) {
1032 ntotal = nAccepted / vtxEff;
1034 AliInfo(Form("Calculating event normalisation as\n"
1035 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1036 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1039 if (scheme & kBackground) {
1040 AliInfo(Form("Correcting for background\n"
1041 " beta = N_a + N_c + 2N_e = %d + %d - 2 * %d = %d",
1042 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta)));
1043 ntotal -= nAccepted * beta / nWithVertex;
1044 scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1045 // scaler -= (beta > 0 ? nWithVertex / beta : 0);
1046 AliInfo(Form("Calculating event normalisation as\n"
1047 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1048 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1049 Int_t(nWithVertex), ntotal, scaler));
1052 if (scheme & kTriggerEfficiency) {
1055 AliInfo(Form("Correcting for trigger efficiency:\n"
1056 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1057 trigEff, Int_t(ntotal), ntotal / trigEff, scaler));
1061 " Total of %9d events for %s\n"
1062 " of these %9d have an offline trigger\n"
1063 " of these N_T = %9d has the selected trigger\n"
1064 " of these N_V = %9d has a vertex\n"
1065 " of these N_A = %9d were in the selected range\n"
1066 " Triggers by hardware type:\n"
1068 " N_ac = %9d (%d+%d)\n"
1070 " Vertex efficiency: %f\n"
1071 " Trigger efficiency: %f\n"
1072 " Total number of events: N = %f\n"
1073 " Scaler (N_A/N): %f",
1074 Int_t(nAll), GetTitle(), Int_t(nOffline),
1075 Int_t(nTriggered), Int_t(nWithVertex), Int_t(nAccepted),
1076 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1077 vtxEff, trigEff, ntotal, scaler));
1081 //________________________________________________________________________
1083 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1086 const TH1* shapeCorr,
1097 // End of processing
1100 // sums List of sums
1101 // results Output list of results
1102 // shapeCorr Shape correction or nil
1103 // trigEff Trigger efficiency
1104 // symmetrice Whether to symmetrice the results
1105 // rebin Whether to rebin the results
1106 // corrEmpty Whether to correct for empty bins
1107 // cutEdges Whether to cut edges when rebinning
1108 // triggerMask Trigger mask
1111 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1113 AliError("Could not retrieve TList fSums");
1117 fOutput = new TList;
1118 fOutput->SetName(GetListName());
1119 fOutput->SetOwner();
1120 results->Add(fOutput);
1122 fSum = static_cast<TH2D*>(fSums->FindObject(GetName()));
1123 fSumMC = static_cast<TH2D*>(fSums->FindObject(Form("%sMC", GetName())));
1124 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1127 AliError("Couldn't find histogram 'triggers' in list");
1131 AliError(Form("Couldn't find histogram '%s' in list", GetName()));
1135 // --- Get acceptance normalisation from underflow bins ------------
1136 const char* name = GetName();
1137 TH1D* accNorm = ProjectX(fSum, Form("norm%s",name), 0, 0, corrEmpty, false);
1138 accNorm->SetDirectory(0);
1140 // ---- Scale by shape correction ----------------------------------
1141 if ((scheme & kShape) && shapeCorr) fSum->Divide(shapeCorr);
1142 else AliInfo("No shape correction specified, or disabled");
1144 // --- Project on X axis -------------------------------------------
1145 TH1D* dndeta = ProjectX(fSum, Form("dndeta%s",name), 1, fSum->GetNbinsY(),
1147 dndeta->SetDirectory(0);
1149 // Normalize to the acceptance -
1150 dndeta->Divide(accNorm);
1152 // --- Get normalization scaler ------------------------------------
1153 Double_t ntotal = 0;
1154 Double_t epsilonT = trigEff;
1156 if (triggerMask == AliAODForwardMult::kNSD) {
1157 // This is a local change
1159 AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
1161 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal);
1163 AliError("Failed to calculate normalization - bailing out");
1166 // Event-level normalization
1167 dndeta->Scale(scaler, "width");
1169 // --- Set some histogram attributes -------------------------------
1170 SetHistogramAttributes(dndeta, color, marker, Form("ALICE %s", name));
1171 SetHistogramAttributes(accNorm, color, marker, Form("ALICE %s normalisation",
1174 // --- Make symmetric extensions and rebinnings --------------------
1175 fOutput->Add(fTriggers->Clone());
1176 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1177 fOutput->Add(dndeta);
1178 fOutput->Add(accNorm);
1179 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1180 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1182 // --- Process result from TrackRefs -------------------------------
1184 // Project onto eta axis - _ignoring_underflow_bins_!
1185 TH1D* dndetaMC = ProjectX(fSumMC,Form("dndeta%sMC", name),1,
1186 fSum->GetNbinsY(), corrEmpty);
1187 // Get acceptance normalisation from underflow bins
1188 TH1D* accNormMC = ProjectX(fSumMC,Form("norm%sMC", name), 0, 0,
1190 // Scale by shape correction
1191 if ((scheme & kShape) && shapeCorr) fSum->Divide(shapeCorr);
1193 // Normalize to the acceptance
1194 dndetaMC->Divide(accNormMC);
1196 // Scale by the vertex efficiency
1197 dndetaMC->Scale(scaler, "width");
1199 // Set hisotgram attributes
1200 SetHistogramAttributes(dndetaMC, color+2, marker,
1201 Form("ALICE %s (MC)",name));
1202 SetHistogramAttributes(accNormMC, color+2, marker,
1203 Form("ALICE %s (MC) normalisation",name));
1205 // Make symmetric extensions, rebinnings, and add to output
1206 fOutput->Add(dndetaMC);
1207 if (symmetrice) fOutput->Add(Symmetrice(dndetaMC));
1209 fOutput->Add(accNormMC);
1210 fOutput->Add(Rebin(dndetaMC, rebin, cutEdges));
1213 fOutput->Add(Symmetrice(Rebin(dndetaMC, rebin, cutEdges)));
1217 if (!IsAllBin()) return;
1219 TFile* forward = TFile::Open("forward.root", "READ");
1221 AliWarning(Form("No forward.root file found"));
1225 TH1D* shapeCorrProj = 0;
1227 shapeCorrProj = static_cast<const TH2D*>(shapeCorr)->ProjectionX();
1228 shapeCorrProj->Scale(1. / shapeCorr->GetNbinsY());
1229 shapeCorrProj->SetDirectory(0);
1230 fOutput->Add(shapeCorrProj);
1233 TList* official = static_cast<TList*>(forward->Get("official"));
1235 TH1F* histEta = static_cast<TH1F*>(official->FindObject("fHistEta"));
1237 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1238 histEta->GetXaxis()->GetXmin(),
1239 histEta->GetXaxis()->GetXmax());
1240 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1241 oEta->SetBinContent(i, histEta->GetBinContent(i));
1242 oEta->SetBinError(i, histEta->GetBinError(i));
1244 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1245 oEta->Scale(1./ntotal, "width");
1246 oEta->SetDirectory(0);
1247 oEta->SetMarkerStyle(marker+4);
1248 oEta->SetMarkerColor(color+5);
1250 fOutput->Add(Rebin(oEta, rebin, false));
1253 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1254 official->GetName()));
1257 AliWarning(Form("Couldn't find list 'official' in %s",forward->GetName()));
1259 TList* tracks = static_cast<TList*>(forward->Get("tracks"));
1261 TH1F* histEta = static_cast<TH1F*>(tracks->FindObject("fHistEta"));
1263 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1264 histEta->GetXaxis()->GetXmin(),
1265 histEta->GetXaxis()->GetXmax());
1266 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1267 oEta->SetBinContent(i, histEta->GetBinContent(i));
1268 oEta->SetBinError(i, histEta->GetBinError(i));
1270 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1271 oEta->Scale(1./ntotal, "width");
1272 oEta->SetDirectory(0);
1273 oEta->SetMarkerStyle(marker);
1274 oEta->SetMarkerColor(color+5);
1276 fOutput->Add(Rebin(oEta, rebin, false));
1279 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1280 tracks->GetName()));
1283 AliWarning(Form("Couldn't find list 'tracks' in %s",forward->GetName()));