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 UShort_t trgMask = 0;
241 TIter next(trgs.Tokenize(" ,|"));
242 while ((trg = static_cast<TObjString*>(next()))) {
243 TString s(trg->GetString());
244 if (s.IsNull()) continue;
245 if (s.CompareTo("INEL") == 0) trgMask = AliAODForwardMult::kInel;
246 else if (s.CompareTo("INEL>0")== 0) trgMask = AliAODForwardMult::kInelGt0;
247 else if (s.CompareTo("NSD") == 0) trgMask = AliAODForwardMult::kNSD;
249 Warning("SetTriggerMask", "Unknown trigger %s", s.Data());
251 if (trgMask == 0) trgMask = 1;
252 SetTriggerMask(trgMask);
254 //________________________________________________________________________
256 AliBasedNdetaTask::SetTriggerMask(UShort_t mask)
259 TString tit(AliAODForwardMult::GetTriggerString(mask));
260 tit = tit.Strip(TString::kBoth);
261 if (!fTriggerString) fTriggerString = new TNamed("trigger", "");
262 fTriggerString->SetTitle(tit);
263 fTriggerString->SetUniqueID(fTriggerMask);
266 //________________________________________________________________________
268 AliBasedNdetaTask::SetShapeCorrection(const TH1* c)
271 // Set the shape correction (a.k.a., track correction) for selected
278 fShapeCorr = static_cast<TH1*>(c->Clone());
279 fShapeCorr->SetDirectory(0);
282 //________________________________________________________________________
284 AliBasedNdetaTask::UserCreateOutputObjects()
287 // Create output objects.
289 // This is called once per slave process
292 fSums->SetName(Form("%s_sums", GetName()));
295 // Automatically add 'all' centrality bin if nothing has been defined.
296 AddCentralityBin(0, 0, 0);
297 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
298 const TArrayD* bins = fCentAxis->GetXbins();
299 Int_t nbin = fCentAxis->GetNbins();
300 for (Int_t i = 0; i < nbin; i++)
301 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
303 fSums->Add(fCentAxis);
306 // Centrality histogram
307 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
308 fCent->SetDirectory(0);
312 // Loop over centrality bins
313 TIter next(fListOfCentralities);
314 CentralityBin* bin = 0;
315 while ((bin = static_cast<CentralityBin*>(next())))
316 bin->CreateOutputObjects(fSums);
318 // Check that we have an AOD input handler
319 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
320 AliAODInputHandler* ah =
321 dynamic_cast<AliAODInputHandler*>(am->GetInputEventHandler());
322 if (!ah) AliFatal("No AOD input handler set in analysis manager");
324 // Post data for ALL output slots >0 here, to get at least an empty histogram
327 //____________________________________________________________________
329 AliBasedNdetaTask::UserExec(Option_t *)
332 // Process a single event
338 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(InputEvent());
340 AliError("Cannot get the AOD event");
344 TObject* obj = aod->FindListObject("Forward");
346 AliWarning("No forward object found");
349 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
351 // Fill centrality histogram
352 Float_t cent = forward->GetCentrality();
355 // Get the histogram(s)
356 TH2D* data = GetHistogram(aod, false);
357 TH2D* dataMC = GetHistogram(aod, true);
359 // Loop over centrality bins
360 CentralityBin* allBin =
361 static_cast<CentralityBin*>(fListOfCentralities->At(0));
362 allBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax, data, dataMC);
364 // Find this centrality bin
365 if (fCentAxis && fCentAxis->GetNbins() > 0) {
366 Int_t icent = fCentAxis->FindBin(cent);
367 CentralityBin* thisBin = 0;
368 if (icent >= 1 && icent <= fCentAxis->GetNbins())
369 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
371 thisBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax,
375 // Here, we get the update
377 UShort_t sNN = forward->GetSNN();
378 fSNNString = new TNamed("sNN", "");
379 fSNNString->SetTitle(AliForwardUtil::CenterOfMassEnergyString(sNN));
380 fSNNString->SetUniqueID(sNN);
381 fSums->Add(fSNNString);
383 UShort_t sys = forward->GetSystem();
384 fSysString = new TNamed("sys", "");
385 fSysString->SetTitle(AliForwardUtil::CollisionSystemString(sys));
386 fSysString->SetUniqueID(sys);
387 fSums->Add(fSysString);
389 fSums->Add(fSchemeString);
390 fSums->Add(fTriggerString);
398 //________________________________________________________________________
400 AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
401 const char* title, const char* ytitle)
404 // Set histogram graphical options, etc.
407 // h Histogram to modify
408 // colour Marker color
409 // marker Marker style
410 // title Title of histogram
411 // ytitle Title on y-axis.
414 h->SetMarkerColor(colour);
415 h->SetMarkerStyle(marker);
418 h->SetYTitle(ytitle);
419 h->GetXaxis()->SetTitleFont(132);
420 h->GetXaxis()->SetLabelFont(132);
421 h->GetXaxis()->SetNdivisions(10);
422 h->GetYaxis()->SetTitleFont(132);
423 h->GetYaxis()->SetLabelFont(132);
424 h->GetYaxis()->SetNdivisions(10);
425 h->GetYaxis()->SetDecimals();
429 //________________________________________________________________________
431 AliBasedNdetaTask::ProjectX(const TH2D* h,
439 // Project onto the X axis
444 // firstbin First bin to use
445 // lastbin Last bin to use
446 // error Whether to calculate errors
449 // Newly created histogram or null
453 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
456 TAxis* xaxis = h->GetXaxis();
457 TAxis* yaxis = h->GetYaxis();
458 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
459 xaxis->GetXmin(), xaxis->GetXmax());
460 static_cast<const TAttLine*>(h)->Copy(*ret);
461 static_cast<const TAttFill*>(h)->Copy(*ret);
462 static_cast<const TAttMarker*>(h)->Copy(*ret);
463 ret->GetXaxis()->ImportAttributes(xaxis);
465 Int_t first = firstbin;
466 Int_t last = lastbin;
467 if (first < 0) first = 0;
468 else if (first >= yaxis->GetNbins()+1) first = yaxis->GetNbins();
469 if (last < 0) last = yaxis->GetNbins();
470 else if (last > yaxis->GetNbins()+1) last = yaxis->GetNbins();
471 if (last-first < 0) {
472 AliWarningGeneral("AliBasedNdetaTask",
473 Form("Nothing to project [%d,%d]", first, last));
479 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
480 Int_t ybins = (last-first+1);
481 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
482 Double_t content = 0;
487 for (Int_t ybin = first; ybin <= last; ybin++) {
488 Double_t c1 = h->GetCellContent(xbin, ybin);
489 Double_t e1 = h->GetCellError(xbin, ybin);
492 if (c1 < 1e-12) continue;
502 if(content > 0 && nbins > 0) {
503 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
505 // Calculate weighted average
506 ret->SetBinContent(xbin, content * factor);
507 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
510 ret->SetBinContent(xbin, factor * content);
517 //________________________________________________________________________
519 AliBasedNdetaTask::Terminate(Option_t *)
522 // Called at end of event processing..
524 // This is called once in the master
529 // Draw result to screen, or perform fitting, normalizations Called
530 // once at the end of the query
532 fSums = dynamic_cast<TList*> (GetOutputData(1));
534 AliError("Could not retrieve TList fSums");
539 fOutput->SetName(Form("%s_result", GetName()));
542 fSNNString = static_cast<TNamed*>(fSums->FindObject("sNN"));
543 fSysString = static_cast<TNamed*>(fSums->FindObject("sys"));
544 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
545 fSchemeString = static_cast<TNamed*>(fSums->FindObject("scheme"));
546 fTriggerString = static_cast<TNamed*>(fSums->FindObject("trigger"));
548 if(fSysString && fSNNString &&
549 fSysString->GetUniqueID() == AliForwardUtil::kPP)
550 LoadNormalizationData(fSysString->GetUniqueID(),
551 fSNNString->GetUniqueID());
552 // Print before we loop
555 // Loop over centrality bins
556 TIter next(fListOfCentralities);
557 CentralityBin* bin = 0;
558 while ((bin = static_cast<CentralityBin*>(next())))
559 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr, fTriggerEff,
560 fSymmetrice, fRebin, fCorrEmpty, fCutEdges,
561 fTriggerMask, GetColor(), GetMarker());
563 // Output collision energy string
564 if (fSNNString) fOutput->Add(fSNNString->Clone());
566 // Output collision system string
567 if (fSysString) fOutput->Add(fSysString->Clone());
569 // Output centrality axis
570 if (fCentAxis) fOutput->Add(fCentAxis);
572 // Output trigger string
573 if (fTriggerString) fOutput->Add(fTriggerString->Clone());
575 // Normalization string
576 if (fSchemeString) fOutput->Add(fSchemeString->Clone());
578 // Output vertex axis
579 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
580 vtxAxis->SetName("vtxAxis");
581 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
582 fOutput->Add(vtxAxis);
584 // Output trigger efficiency and shape correction
585 fOutput->Add(new TParameter<Double_t>("triggerEff", fTriggerEff));
586 if (fShapeCorr) fOutput->Add(fShapeCorr);
588 PostData(2, fOutput);
590 //________________________________________________________________________
592 AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
594 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
597 if(energy == 7000) snn.Form("7000");
598 if(energy == 2750) snn.Form("2750");
600 if(fShapeCorr && (fTriggerEff != 1)) {
601 AliInfo("Objects already set for normalization - no action taken");
605 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWG2/FORWARD/corrections/"
606 "Normalization/normalizationHists_%s_%s.root",
607 type.Data(),snn.Data()));
609 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
614 TString shapeCorName(Form("h%sNormalization",
615 fTriggerMask == AliAODForwardMult::kInel ? "Inel" :
616 fTriggerMask == AliAODForwardMult::kNSD ? "NSD" :
617 fTriggerMask == AliAODForwardMult::kInelGt0 ?
619 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
620 if (shapeCor) SetShapeCorrection(shapeCor);
622 // Trigger efficiency
623 TString effName(Form("%sTriggerEff",
624 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
625 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
626 fTriggerMask == AliAODForwardMult::kInelGt0 ?
628 TParameter<float>* eff = static_cast<TParameter<float>*>(fin->Get(effName));
629 if (eff) SetTriggerEff(eff->GetVal());
632 // Rescale the shape correction by the trigger efficiency
633 AliWarning(Form("Rescaling shape correction by trigger efficiency: "
634 "1/E_X=1/%f", fTriggerEff));
635 fShapeCorr->Scale(1. / fTriggerEff);
638 if (shapeCor && eff) AliInfo("Loaded objects for normalization.");
642 //________________________________________________________________________
644 AliBasedNdetaTask::Print(Option_t*) const
649 std::cout << this->ClassName() << ": " << this->GetName() << "\n"
651 << " Trigger: " << (fTriggerString ?
652 fTriggerString->GetTitle() :
654 << " Vertex range: [" << fVtxMin << ":" << fVtxMax << "]\n"
655 << " Rebin factor: " << fRebin << "\n"
656 << " Cut edges: " << fCutEdges << "\n"
657 << " Symmertrice: " << fSymmetrice << "\n"
658 << " Correct for empty: " << fCorrEmpty << "\n"
659 << " Normalization scheme: " << (fSchemeString ?
660 fSchemeString->GetTitle() :
662 << " Trigger efficiency: " << fTriggerEff << "\n"
663 << " Shape correction: " << (fShapeCorr ?
664 fShapeCorr->GetName() :
666 << " sqrt(s_NN): " << (fSNNString ?
667 fSNNString->GetTitle() :
669 << " Collision system: " << (fSysString ?
670 fSysString->GetTitle() :
672 << " Centrality bins: " << (fCentAxis ? "" : "none");
674 Int_t nBins = fCentAxis->GetNbins();
675 const Double_t* bins = fCentAxis->GetXbins()->GetArray();
676 for (Int_t i = 0; i <= nBins; i++)
677 std::cout << (i==0 ? "" : "-") << bins[i];
679 std::cout << std::noboolalpha << std::endl;
683 //________________________________________________________________________
685 AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
688 // Make a copy of the input histogram and rebin that histogram
691 // h Histogram to rebin
694 // New (rebinned) histogram
696 if (rebin <= 1) return 0;
698 Int_t nBins = h->GetNbinsX();
699 if(nBins % rebin != 0) {
700 AliWarningGeneral("AliBasedNdetaTask",
701 Form("Rebin factor %d is not a devisor of current number "
702 "of bins %d in the histogram %s",
703 rebin, nBins, h->GetName()));
708 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
709 h->GetName(), rebin)));
711 tmp->SetDirectory(0);
713 // The new number of bins
714 Int_t nBinsNew = nBins / rebin;
715 for(Int_t i = 1;i<= nBinsNew; i++) {
716 Double_t content = 0;
720 for(Int_t j = 1; j<=rebin;j++) {
721 Int_t bin = (i-1)*rebin + j;
722 Double_t c = h->GetBinContent(bin);
723 if (c <= 0) continue;
726 if (h->GetBinContent(bin+1)<=0 ||
727 h->GetBinContent(bin-1)<=0) {
729 AliWarningGeneral("AliBasedNdetaTask",
730 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
731 bin, c, h->GetName(),
732 bin+1, h->GetBinContent(bin+1),
733 bin-1, h->GetBinContent(bin-1)));
738 Double_t e = h->GetBinError(bin);
739 Double_t w = 1 / (e*e); // 1/c/c
746 if(content > 0 && nbins > 0) {
747 tmp->SetBinContent(i, wsum / sumw);
748 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
755 //__________________________________________________________________
757 AliBasedNdetaTask::Symmetrice(const TH1* h)
760 // Make an extension of @a h to make it symmetric about 0
763 // h Histogram to symmertrice
766 // Symmetric extension of @a h
768 Int_t nBins = h->GetNbinsX();
769 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
770 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
772 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
773 s->SetMarkerColor(h->GetMarkerColor());
774 s->SetMarkerSize(h->GetMarkerSize());
775 s->SetMarkerStyle(h->GetMarkerStyle()+4);
776 s->SetFillColor(h->GetFillColor());
777 s->SetFillStyle(h->GetFillStyle());
780 // Find the first and last bin with data
781 Int_t first = nBins+1;
783 for (Int_t i = 1; i <= nBins; i++) {
784 if (h->GetBinContent(i) <= 0) continue;
785 first = TMath::Min(first, i);
786 last = TMath::Max(last, i);
789 Double_t xfirst = h->GetBinCenter(first-1);
790 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
791 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
792 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
793 s->SetBinContent(j, h->GetBinContent(i));
794 s->SetBinError(j, h->GetBinError(i));
796 // Fill in overlap bin
797 s->SetBinContent(l2+1, h->GetBinContent(first));
798 s->SetBinError(l2+1, h->GetBinError(first));
802 //====================================================================
803 AliBasedNdetaTask::CentralityBin::CentralityBin()
817 //____________________________________________________________________
818 AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
819 Short_t low, Short_t high)
833 // name Name used for histograms (e.g., Forward)
834 // low Lower centrality cut in percent
835 // high Upper centrality cut in percent
837 if (low <= 0 && high <= 0) {
840 SetTitle("All centralities");
845 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
848 //____________________________________________________________________
849 AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
855 fTriggers(o.fTriggers),
863 // other Object to copy from
866 //____________________________________________________________________
867 AliBasedNdetaTask::CentralityBin::~CentralityBin()
872 if (fSums) fSums->Delete();
873 if (fOutput) fOutput->Delete();
876 //____________________________________________________________________
877 AliBasedNdetaTask::CentralityBin&
878 AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
881 // Assignment operator
884 // other Object to assign from
889 SetName(o.GetName());
890 SetTitle(o.GetTitle());
895 fTriggers = o.fTriggers;
901 //____________________________________________________________________
903 AliBasedNdetaTask::CentralityBin::GetListName() const
911 if (IsAllBin()) return "all";
912 return Form("cent%03d_%03d", fLow, fHigh);
914 //____________________________________________________________________
916 AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir)
919 // Create output objects
925 fSums->SetName(GetListName());
929 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers");
930 fTriggers->SetDirectory(0);
931 fSums->Add(fTriggers);
933 //____________________________________________________________________
935 AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
938 // Create sum histogram
941 // data Data histogram to clone
942 // mc (optional) MC histogram to clone
944 fSum = static_cast<TH2D*>(data->Clone(GetName()));
945 fSum->SetDirectory(0);
949 // If no MC data is given, then do not create MC sum histogram
952 fSumMC = static_cast<TH2D*>(mc->Clone(Form("%sMC", GetName())));
953 fSumMC->SetDirectory(0);
958 //____________________________________________________________________
960 AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
962 Double_t vzMin, Double_t vzMax)
965 // Check the trigger, vertex, and centrality
971 // true if the event is to be used
973 if (!forward) return false;
975 // We do not check for centrality here - it's already done
976 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
980 //____________________________________________________________________
982 AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
984 Double_t vzMin, Double_t vzMax,
985 const TH2D* data, const TH2D* mc)
991 // forward Forward data (for trigger, vertex, & centrality)
992 // triggerMask Trigger mask
993 // vzMin Minimum IP z coordinate
994 // vzMax Maximum IP z coordinate
995 // data Data histogram
998 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
1000 if (!fSum) CreateSums(data, mc);
1003 if (mc) fSumMC->Add(mc);
1006 //________________________________________________________________________
1008 AliBasedNdetaTask::CentralityBin::Normalization(const TH1I& t,
1011 Double_t& ntotal) const
1014 // Calculate normalization
1017 // t Trigger histogram
1018 // scheme Normaliztion scheme
1020 // ntotal On return, contains the number of events.
1023 Double_t nAll = t.GetBinContent(AliAODForwardMult::kBinAll);
1024 Double_t nB = t.GetBinContent(AliAODForwardMult::kBinB);
1025 Double_t nA = t.GetBinContent(AliAODForwardMult::kBinA);
1026 Double_t nC = t.GetBinContent(AliAODForwardMult::kBinC);
1027 Double_t nE = t.GetBinContent(AliAODForwardMult::kBinE);
1028 Double_t nOffline = t.GetBinContent(AliAODForwardMult::kBinOffline);
1029 Double_t nTriggered = t.GetBinContent(AliAODForwardMult::kWithTrigger);
1030 Double_t nWithVertex = t.GetBinContent(AliAODForwardMult::kWithVertex);
1031 Double_t nAccepted = t.GetBinContent(AliAODForwardMult::kAccepted);
1033 if (nTriggered <= 0.1) {
1034 AliError("Number of triggered events <= 0");
1037 if (nWithVertex <= 0.1) {
1038 AliError("Number of events with vertex <= 0");
1042 Double_t vtxEff = nWithVertex / nTriggered;
1043 Double_t scaler = 1;
1044 Double_t beta = nA + nC - 2*nE;
1046 if (scheme & kEventLevel) {
1047 ntotal = nAccepted / vtxEff;
1049 AliInfo(Form("Calculating event normalisation as\n"
1050 " N = N_A * N_T / N_V = %d * %d / %d = %f (%f)",
1051 Int_t(nAccepted), Int_t(nTriggered), Int_t(nWithVertex),
1054 if (scheme & kBackground) {
1055 AliInfo(Form("Correcting for background\n"
1056 " beta = N_a + N_c + 2N_e = %d + %d - 2 * %d = %d",
1057 Int_t(nA), Int_t(nC), Int_t(nE), Int_t(beta)));
1058 ntotal -= nAccepted * beta / nWithVertex;
1059 scaler = 1. / (1. / vtxEff - beta / nWithVertex);
1060 // scaler -= (beta > 0 ? nWithVertex / beta : 0);
1061 AliInfo(Form("Calculating event normalisation as\n"
1062 " N = N - N_A * beta / N_V = %f - %d * %d / %d = %f (%f)",
1063 nAccepted / vtxEff, Int_t(nAccepted), Int_t(beta),
1064 Int_t(nWithVertex), ntotal, scaler));
1067 if (scheme & kTriggerEfficiency) {
1070 AliInfo(Form("Correcting for trigger efficiency:\n"
1071 " N = 1 / E_X * N = 1 / %f * %d = %f (%f)",
1072 trigEff, Int_t(ntotal), ntotal / trigEff, scaler));
1076 " Total of %9d events for %s\n"
1077 " of these %9d have an offline trigger\n"
1078 " of these N_T = %9d has the selected trigger\n"
1079 " of these N_V = %9d has a vertex\n"
1080 " of these N_A = %9d were in the selected range\n"
1081 " Triggers by hardware type:\n"
1083 " N_ac = %9d (%d+%d)\n"
1085 " Vertex efficiency: %f\n"
1086 " Trigger efficiency: %f\n"
1087 " Total number of events: N = %f\n"
1088 " Scaler (N_A/N): %f",
1089 Int_t(nAll), GetTitle(), Int_t(nOffline),
1090 Int_t(nTriggered), Int_t(nWithVertex), Int_t(nAccepted),
1091 Int_t(nB), Int_t(nA+nC), Int_t(nA), Int_t(nC), Int_t(nE),
1092 vtxEff, trigEff, ntotal, scaler));
1096 //________________________________________________________________________
1098 AliBasedNdetaTask::CentralityBin::End(TList* sums,
1101 const TH1* shapeCorr,
1112 // End of processing
1115 // sums List of sums
1116 // results Output list of results
1117 // shapeCorr Shape correction or nil
1118 // trigEff Trigger efficiency
1119 // symmetrice Whether to symmetrice the results
1120 // rebin Whether to rebin the results
1121 // corrEmpty Whether to correct for empty bins
1122 // cutEdges Whether to cut edges when rebinning
1123 // triggerMask Trigger mask
1126 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
1128 AliError("Could not retrieve TList fSums");
1132 fOutput = new TList;
1133 fOutput->SetName(GetListName());
1134 fOutput->SetOwner();
1135 results->Add(fOutput);
1137 fSum = static_cast<TH2D*>(fSums->FindObject(GetName()));
1138 fSumMC = static_cast<TH2D*>(fSums->FindObject(Form("%sMC", GetName())));
1139 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
1142 AliError("Couldn't find histogram 'triggers' in list");
1146 AliError(Form("Couldn't find histogram '%s' in list", GetName()));
1150 // --- Get acceptance normalisation from underflow bins ------------
1151 const char* name = GetName();
1152 TH1D* accNorm = ProjectX(fSum, Form("norm%s",name), 0, 0, corrEmpty, false);
1153 accNorm->SetDirectory(0);
1155 // ---- Scale by shape correction ----------------------------------
1156 if ((scheme & kShape) && shapeCorr) fSum->Divide(shapeCorr);
1157 else AliInfo("No shape correction specified, or disabled");
1159 // --- Project on X axis -------------------------------------------
1160 TH1D* dndeta = ProjectX(fSum, Form("dndeta%s",name), 1, fSum->GetNbinsY(),
1162 dndeta->SetDirectory(0);
1164 // Normalize to the acceptance -
1165 dndeta->Divide(accNorm);
1167 // --- Get normalization scaler ------------------------------------
1168 Double_t ntotal = 0;
1169 Double_t epsilonT = trigEff;
1171 if (triggerMask == AliAODForwardMult::kNSD) {
1172 // This is a local change
1174 AliWarning(Form("Using hard-coded NSD trigger efficiency of %f",epsilonT));
1176 Double_t scaler = Normalization(*fTriggers, scheme, epsilonT, ntotal);
1178 AliError("Failed to calculate normalization - bailing out");
1181 // Event-level normalization
1182 dndeta->Scale(scaler, "width");
1184 // --- Set some histogram attributes -------------------------------
1185 SetHistogramAttributes(dndeta, color, marker, Form("ALICE %s", name));
1186 SetHistogramAttributes(accNorm, color, marker, Form("ALICE %s normalisation",
1189 // --- Make symmetric extensions and rebinnings --------------------
1190 fOutput->Add(fTriggers->Clone());
1191 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1192 fOutput->Add(dndeta);
1193 fOutput->Add(accNorm);
1194 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1195 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1197 // --- Process result from TrackRefs -------------------------------
1199 // Project onto eta axis - _ignoring_underflow_bins_!
1200 TH1D* dndetaMC = ProjectX(fSumMC,Form("dndeta%sMC", name),1,
1201 fSum->GetNbinsY(), corrEmpty);
1202 // Get acceptance normalisation from underflow bins
1203 TH1D* accNormMC = ProjectX(fSumMC,Form("norm%sMC", name), 0, 0,
1205 // Scale by shape correction
1206 if ((scheme & kShape) && shapeCorr) fSum->Divide(shapeCorr);
1208 // Normalize to the acceptance
1209 dndetaMC->Divide(accNormMC);
1211 // Scale by the vertex efficiency
1212 dndetaMC->Scale(scaler, "width");
1214 // Set hisotgram attributes
1215 SetHistogramAttributes(dndetaMC, color+2, marker,
1216 Form("ALICE %s (MC)",name));
1217 SetHistogramAttributes(accNormMC, color+2, marker,
1218 Form("ALICE %s (MC) normalisation",name));
1220 // Make symmetric extensions, rebinnings, and add to output
1221 fOutput->Add(dndetaMC);
1222 if (symmetrice) fOutput->Add(Symmetrice(dndetaMC));
1224 fOutput->Add(accNormMC);
1225 fOutput->Add(Rebin(dndetaMC, rebin, cutEdges));
1228 fOutput->Add(Symmetrice(Rebin(dndetaMC, rebin, cutEdges)));
1232 if (!IsAllBin()) return;
1234 TFile* forward = TFile::Open("forward.root", "READ");
1236 AliWarning(Form("No forward.root file found"));
1240 TH1D* shapeCorrProj = 0;
1242 shapeCorrProj = static_cast<const TH2D*>(shapeCorr)->ProjectionX();
1243 shapeCorrProj->Scale(1. / shapeCorr->GetNbinsY());
1244 shapeCorrProj->SetDirectory(0);
1245 fOutput->Add(shapeCorrProj);
1248 TList* official = static_cast<TList*>(forward->Get("official"));
1250 TH1F* histEta = static_cast<TH1F*>(official->FindObject("fHistEta"));
1252 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1253 histEta->GetXaxis()->GetXmin(),
1254 histEta->GetXaxis()->GetXmax());
1255 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1256 oEta->SetBinContent(i, histEta->GetBinContent(i));
1257 oEta->SetBinError(i, histEta->GetBinError(i));
1259 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1260 oEta->Scale(1./ntotal, "width");
1261 oEta->SetDirectory(0);
1262 oEta->SetMarkerStyle(marker+4);
1263 oEta->SetMarkerColor(color+5);
1265 fOutput->Add(Rebin(oEta, rebin, false));
1268 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1269 official->GetName()));
1272 AliWarning(Form("Couldn't find list 'official' in %s",forward->GetName()));
1274 TList* tracks = static_cast<TList*>(forward->Get("tracks"));
1276 TH1F* histEta = static_cast<TH1F*>(tracks->FindObject("fHistEta"));
1278 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1279 histEta->GetXaxis()->GetXmin(),
1280 histEta->GetXaxis()->GetXmax());
1281 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1282 oEta->SetBinContent(i, histEta->GetBinContent(i));
1283 oEta->SetBinError(i, histEta->GetBinError(i));
1285 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1286 oEta->Scale(1./ntotal, "width");
1287 oEta->SetDirectory(0);
1288 oEta->SetMarkerStyle(marker);
1289 oEta->SetMarkerColor(color+5);
1291 fOutput->Add(Rebin(oEta, rebin, false));
1294 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1295 tracks->GetName()));
1298 AliWarning(Form("Couldn't find list 'tracks' in %s",forward->GetName()));