1 #include "AliForwardMultDists.h"
2 #include <AliForwardUtil.h>
3 #include <AliAODForwardMult.h>
4 #include <AliAODCentralMult.h>
5 #include <AliAODEvent.h>
11 #include <TParameter.h>
16 //====================================================================
27 kDownTriangle = 0x008,
33 * Get a ROOT marker style from bit options
35 * @param bits Bit mask of options
37 * @return ROOT marker style
39 Int_t GetMarkerStyle(UShort_t bits)
41 Int_t base = bits & (0xFE);
42 Bool_t hollow = bits & kHollow;
44 case kCircle: return (hollow ? 24 : 20);
45 case kSquare: return (hollow ? 25 : 21);
46 case kUpTriangle: return (hollow ? 26 : 22);
47 case kDownTriangle: return (hollow ? 32 : 23);
48 case kDiamond: return (hollow ? 27 : 33);
49 case kCross: return (hollow ? 28 : 34);
50 case kStar: return (hollow ? 30 : 29);
55 * Get the marker option bits from a ROOT style
57 * @param style ROOT style
59 * @return Pattern of marker options
61 UShort_t GetMarkerBits(Int_t style)
65 case 24: case 25: case 26: case 27: case 28: case 30: case 32:
66 bits |= kHollow; break;
69 case 20: case 24: bits |= kCircle; break;
70 case 21: case 25: bits |= kSquare; break;
71 case 22: case 26: bits |= kUpTriangle; break;
72 case 23: case 32: bits |= kDownTriangle; break;
73 case 27: case 33: bits |= kDiamond; break;
74 case 28: case 34: bits |= kCross; break;
75 case 29: case 30: bits |= kStar; break;
79 static Int_t GetIndexMarker(Int_t idx)
81 const UShort_t nMarkers = 7;
82 UShort_t markers[] = {
92 return markers[idx % nMarkers];
95 * Flip the 'hollow-ness' of a marker
97 * @param style ROOT Style
101 Int_t FlipHollowStyle(Int_t style)
103 UShort_t bits = GetMarkerBits(style);
104 Int_t ret = GetMarkerStyle(bits ^ kHollow);
109 //====================================================================
110 AliForwardMultDists::BinSpec::BinSpec(Double_t etaMin,
113 : fEtaMin(etaMin), fEtaMax(etaMax), fLow(nchLow), fN(0), fD(0), fAxis(1,0,1)
116 //____________________________________________________________________
118 AliForwardMultDists::BinSpec::Push(UShort_t n, Double_t d)
120 Int_t l = fN.GetSize();
121 fN.Set(l+1); // Not terribly efficient, but that's ok because we do
122 fD.Set(l+1); // this infrequently
126 //____________________________________________________________________
128 AliForwardMultDists::BinSpec::Axis() const
130 if (fAxis.GetNbins() > 1) return fAxis;
131 if (fN.GetSize() <= 0) return fAxis;
132 if (fN.GetSize() == 1) {
134 fAxis.Set(fN[0], fLow, fN[0]*fD[0]+fLow);
137 Int_t n = Int_t(fN.GetSum());
138 Int_t l = fN.GetSize();
142 for (Int_t j = 0; j < l; j++) {
143 for (Int_t k = 0; k < fN[j]; k++) {
144 b[i+1] = b[i] + fD[j];
149 ::Warning("Axis", "Assigned bins, and number of bins not equal");
150 n = TMath::Min(i, n);
152 fAxis.Set(n, b.GetArray());
157 //====================================================================
158 AliForwardMultDists::AliForwardMultDists()
173 //____________________________________________________________________
174 AliForwardMultDists::AliForwardMultDists(const char* name)
175 : AliBaseAODTask(name,"AliForwardMultDists"),
191 * @param name Name of the task
196 //____________________________________________________________________
198 AliForwardMultDists::Book()
201 * Create output objects - called at start of job in slave
206 //____________________________________________________________________
208 AliForwardMultDists::PreData()
211 * Set-up internal structures on first seen event
214 AliAODEvent* aod = AliForwardUtil::GetAODEvent(this);
215 AliAODForwardMult* forward = GetForward(*aod);
216 const TH2D& hist = forward->GetHistogram();
217 Bool_t useMC = GetPrimary(*aod) != 0;
219 fSums->Add(AliForwardUtil::MakeParameter("minIpZ", fMinIpZ));
220 fSums->Add(AliForwardUtil::MakeParameter("maxIpZ", fMaxIpZ));
222 TAxis* xaxis = hist.GetXaxis();
223 if (!xaxis->GetXbins() || xaxis->GetXbins()->GetSize() <= 0) {
224 fForwardCache = new TH1D("forwardCache", "Projection of Forward data",
225 xaxis->GetNbins(), xaxis->GetXmin(),
227 fCentralCache = new TH1D("centralCache", "Projection of Central data",
228 xaxis->GetNbins(), xaxis->GetXmin(),
231 fMCCache = new TH1D("mcCache", "Projection of Mc data",
232 xaxis->GetNbins(), xaxis->GetXmin(),
236 fForwardCache = new TH1D("forwardCache", "Projection of Forward data",
237 xaxis->GetNbins(),xaxis->GetXbins()->GetArray());
238 fCentralCache = new TH1D("centralCache", "Projection of Central data",
239 xaxis->GetNbins(),xaxis->GetXbins()->GetArray());
241 fMCCache = new TH1D("mcCache", "Projection of Mc data",
242 xaxis->GetNbins(),xaxis->GetXbins()->GetArray());
244 fForwardCache->SetDirectory(0);
245 fForwardCache->GetXaxis()->SetTitle("#eta");
246 fForwardCache->GetYaxis()->SetTitle("#sum#frac{d^{2}N}{d#etadphi}");
247 fForwardCache->Sumw2();
248 fCentralCache->SetDirectory(0);
249 fCentralCache->GetXaxis()->SetTitle("#eta");
250 fCentralCache->GetYaxis()->SetTitle("#sum#frac{d^{2}N}{d#etadphi}");
251 fCentralCache->Sumw2();
254 fMCCache->SetDirectory(0);
255 fMCCache->GetXaxis()->SetTitle("#eta");
256 fMCCache->GetYaxis()->SetTitle("#sum#frac{d^{2}N}{d#etadphi}");
259 fMCVertex = static_cast<TH1*>(fVertex->Clone("mcVertex"));
260 fMCVertex->SetTitle("Vertex distribution from MC");
261 fMCVertex->SetDirectory(0);
262 fMCVertex->SetFillColor(kBlue+2);
263 fSums->Add(fMCVertex);
266 UShort_t xBase = kTrigger-1;
267 UShort_t yBase = kAnalysis-1;
268 fDiag = new TH2I("diagnostics", "Event selection",
269 kTriggerVertex-xBase, kTrigger-.5, kTriggerVertex+.5,
270 kTriggerVertex-yBase, kAnalysis-.5, kTriggerVertex+.5);
271 fDiag->SetDirectory(0);
272 fDiag->GetXaxis()->SetTitle("Selection");
273 fDiag->GetXaxis()->SetBinLabel(kTrigger -xBase, "Trigger");
274 fDiag->GetXaxis()->SetBinLabel(kVertex -xBase, "Vertex");
275 fDiag->GetXaxis()->SetBinLabel(kTriggerVertex-xBase, "Trigger+Vertex");
276 fDiag->GetYaxis()->SetTitle("Type/MC selection");
277 fDiag->GetYaxis()->SetBinLabel(kAnalysis -yBase, "Analysis");
278 fDiag->GetYaxis()->SetBinLabel(kMC -yBase, "MC");
279 fDiag->GetYaxis()->SetBinLabel(kTrigger -yBase, "MC Trigger");
280 fDiag->GetYaxis()->SetBinLabel(kVertex -yBase, "MC Vertex");
281 fDiag->GetYaxis()->SetBinLabel(kTriggerVertex-yBase, "MC Trigger+Vertex");
282 fDiag->SetMarkerSize(3);
283 fDiag->SetMarkerColor(kWhite);
288 while ((bin = static_cast<EtaBin*>(next()))) {
289 bin->SetupForData(fSums, hist, useMC);
293 //____________________________________________________________________
295 AliForwardMultDists::Event(AliAODEvent& aod)
298 * Analyse a single event
300 * @param aod Input event
302 AliAODForwardMult* forward = GetForward(aod, false, true);
303 if (!forward) return false;
305 AliAODCentralMult* central = GetCentral(aod, false, true);
306 if (!central) return false;
308 TH2* primary = GetPrimary(aod);
310 const TH2& forwardData = forward->GetHistogram();
311 const TH2& centralData = central->GetHistogram();
313 Double_t vz = forward->GetIpZ();
314 Bool_t trg = forward->IsTriggerBits(fTriggerMask);
315 Bool_t vtx = (vz <= fMaxIpZ && vz >= fMinIpZ);
316 Bool_t ok = true; // Should bins process this event?
317 Bool_t mcTrg = false;
318 Bool_t mcVtx = false;
319 // If we have MC inpunt
321 // For MC, we need to check if we should process the event for
322 // MC information or not.
323 if ((fTriggerMask & (AliAODForwardMult::kV0AND|AliAODForwardMult::kNSD))
324 && !forward->IsTriggerBits(AliAODForwardMult::kMCNSD))
325 // Bail out if this event is not MC NSD event
329 Double_t mcVz = primary->GetBinContent(0,0);
330 fMCVertex->Fill(mcVz);
331 if (mcVz > fMaxIpZ || mcVz < fMinIpZ)
332 // Bail out if this event was not in the valid range
339 fDiag->Fill(kTrigger, kAnalysis);
340 if (mcTrg) fDiag->Fill(kTrigger, kTrigger);
341 if (mcVtx) fDiag->Fill(kTrigger, kVertex);
342 if (mcTrg && mcVtx) fDiag->Fill(kTrigger, kTriggerVertex);
345 fDiag->Fill(kVertex, kAnalysis);
346 if (mcTrg) fDiag->Fill(kVertex, kTrigger);
347 if (mcVtx) fDiag->Fill(kVertex, kVertex);
348 if (mcTrg && mcVtx) fDiag->Fill(kVertex, kTriggerVertex);
351 fDiag->Fill(kTriggerVertex, kAnalysis);
352 if (mcTrg) fDiag->Fill(kTriggerVertex, kTrigger);
353 if (mcVtx) fDiag->Fill(kTriggerVertex, kVertex);
354 if (mcTrg && mcVtx) fDiag->Fill(kTriggerVertex, kTriggerVertex);
357 if (mcTrg) fDiag->Fill(kTrigger, kMC);
358 if (mcVtx) fDiag->Fill(kVertex, kMC);
359 if (mcTrg && mcVtx) fDiag->Fill(kTriggerVertex, kMC);
361 if (!fIsSelected && !ok) {
362 // Printf("Event is neither accepted by analysis nor by MC");
367 // Info("", "Event vz=%f", forward->GetIpZ());
369 ProjectX(forwardData, *fForwardCache, fUsePhiAcc);
370 ProjectX(centralData, *fCentralCache, fUsePhiAcc);
371 ProjectX(primary, fMCCache);
375 while ((bin = static_cast<EtaBin*>(next()))) {
376 bin->Process(*fForwardCache, *fCentralCache,
377 forwardData, centralData,
378 fIsSelected, fMCCache);
384 //_____________________________________________________________________
386 AliForwardMultDists::CheckEvent(const AliAODForwardMult& fwd)
388 fIsSelected = AliBaseAODTask::CheckEvent(fwd);
389 // We always return true, so that we can process MC truth;
393 //____________________________________________________________________
395 AliForwardMultDists::Finalize()
398 * Called at the end of the final processing of the job on the
399 * full data set (merged data)
401 fResults->Add(fSums->FindObject("triggers")->Clone());
402 fResults->Add(fSums->FindObject("status")->Clone());
403 fResults->Add(fSums->FindObject("diagnostics")->Clone());
405 THStack* sym = new THStack("all", "All distributions");
406 THStack* pos = new THStack("all", "All distributions");
407 THStack* neg = new THStack("all", "All distributions");
408 THStack* oth = new THStack("all", "All distributions");
412 while ((bin = static_cast<EtaBin*>(next()))) {
413 bin->Terminate(fSums, fResults);
416 if (bin->IsSymmetric()) sta = sym;
417 else if (bin->IsNegative()) sta = neg;
418 else if (bin->IsPositive()) sta = pos;
420 TH1* hh[] = { bin->fSum, bin->fTruth, bin->fTruthAccepted, 0 };
423 Int_t idx = sta->GetHists() ? sta->GetHists()->GetEntries() : 0;
424 if (bin->fTruth) idx /= 2;
426 Int_t mkrBits = GetIndexMarker(idx);
428 Int_t factor = Int_t(TMath::Power(10, idx));
429 TH1* h = static_cast<TH1*>((*ph)->Clone());
432 h->SetTitle(Form("%s (#times%d)", h->GetTitle(), Int_t(factor)));
433 h->SetMarkerStyle(GetMarkerStyle(mkrBits));
440 TList* lsym = static_cast<TList*>(fResults->FindObject("symmetric"));
441 TList* lneg = static_cast<TList*>(fResults->FindObject("negative"));
442 TList* lpos = static_cast<TList*>(fResults->FindObject("positive"));
443 TList* loth = static_cast<TList*>(fResults->FindObject("other"));
445 if (lsym) lsym->Add(sym);
446 if (lneg) lneg->Add(neg);
447 if (lpos) lpos->Add(pos);
448 if (loth) loth->Add(oth);
453 //____________________________________________________________________
455 AliForwardMultDists::ProjectX(const TH2& input, TH1& cache, Bool_t usePhiAcc)
458 * Project a 2D histogram into a 1D histogram taking care to use
459 * either the @f$\phi@f$ acceptance stored in the overflow bins, or
460 * the @f$\eta@f$ coverage stored in the underflow bins.
462 * @param input 2D histogram to project
463 * @param cache 1D histogram to project into
464 * @param usePhiAcc If true, use the @f$\phi@f$ acceptance stored in
465 * the overflow bins, or if false the @f$\eta@f$ coverage stored in
466 * the underflow bins.
470 Int_t nPhi = input.GetNbinsY();
471 Int_t nEta = input.GetNbinsX();
473 for (Int_t iEta = 1; iEta <= nEta; iEta++) {
474 Double_t phiAcc = input.GetBinContent(iEta, nPhi+1);
475 Double_t etaCov = input.GetBinContent(iEta, 0);
476 Double_t factor = usePhiAcc ? phiAcc : etaCov;
478 if (factor < 1e-3) continue;
481 for (Int_t iPhi = 1; iPhi <= nPhi; iPhi++) {
482 Double_t c = input.GetBinContent(iEta, iPhi);
483 Double_t e = input.GetBinError(iEta, iPhi);
488 cache.SetBinContent(iEta, factor * sum);
489 cache.SetBinError(iEta, factor * TMath::Sqrt(e2sum));
492 //____________________________________________________________________
494 AliForwardMultDists::ProjectX(const TH2* input, TH1* cache)
497 * Project on @f$\eta@f$ axis. If any of the pointers passed is
503 if (!input || !cache) return;
506 Int_t nPhi = input->GetNbinsY();
507 Int_t nEta = input->GetNbinsX();
509 for (Int_t iEta = 1; iEta <= nEta; iEta++) {
512 for (Int_t iPhi = 1; iPhi <= nPhi; iPhi++) {
513 Double_t c = input->GetBinContent(iEta, iPhi);
514 Double_t e = input->GetBinError(iEta, iPhi);
519 cache->SetBinContent(iEta, sum);
520 cache->SetBinError(iEta, TMath::Sqrt(e2sum));
523 //____________________________________________________________________
525 AliForwardMultDists::AddBin(const BinSpec& spec)
527 AddBin(spec.fEtaMin, spec.fEtaMax, spec.Axis());
530 //____________________________________________________________________
532 AliForwardMultDists::AddBin(Double_t etaLow, Double_t etaMax,
536 * Add an @f$\eta@f$ bin
538 * @param etaLow Low cut on @f$\eta@f$
539 * @param etaMax High cut on @f$\eta@f$
542 if (etaMax >= kInvalidEta) {
543 etaLow = -TMath::Abs(etaLow);
544 etaMax = +TMath::Abs(etaLow);
546 EtaBin* bin = new EtaBin(etaLow, etaMax, mAxis);
547 // AliInfoF("Adding bin %f, %f: %s", etaLow, etaMax, bin->GetName());
550 //____________________________________________________________________
552 AliForwardMultDists::AddBin(Double_t etaLow, Double_t etaMax,
553 UShort_t nMax, UShort_t nDiv)
556 * Add an @f$\eta@f$ bin
558 * @param etaLow Low cut on @f$\eta@f$
559 * @param etaMax High cut on @f$\eta@f$
562 if (etaMax >= kInvalidEta) {
563 etaLow = -TMath::Abs(etaLow);
564 etaMax = +TMath::Abs(etaLow);
566 TAxis mAxis((nMax+1)/nDiv, -.5, nMax+.5);
567 EtaBin* bin = new EtaBin(etaLow, etaMax, mAxis);
568 // AliInfoF("Adding bin %f, %f: %s", etaLow, etaMax, bin->GetName());
571 #define PFV(N,VALUE) \
573 AliForwardUtil::PrintName(N); \
574 std::cout << (VALUE) << std::endl; } while(false)
575 #define PFB(N,FLAG) \
577 AliForwardUtil::PrintName(N); \
578 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
581 //____________________________________________________________________
583 AliForwardMultDists::Print(Option_t* option) const
588 * @param option Not used
590 AliBaseAODTask::Print(option);
591 gROOT->IncreaseDirLevel();
592 PFB("Use phi acceptance", fUsePhiAcc);
593 // AliForwardUtil::PrintName("Bins");
598 while ((bin = static_cast<EtaBin*>(next()))) {
599 PFV(first ? "Bins" : "", bin->GetName());
602 gROOT->DecreaseDirLevel();
605 //====================================================================
606 AliForwardMultDists::EtaBin::EtaBin()
626 //____________________________________________________________________
627 AliForwardMultDists::EtaBin::EtaBin(Double_t minEta, Double_t maxEta,
646 * @param minEta Least @f$\eta@f$ to consider
647 * @param maxEta Largest @f$\eta@f$ to consider
649 fName = TString::Format("%+05.2f_%+05.2f", fMinEta, fMaxEta);
650 fName.ReplaceAll("-", "m");
651 fName.ReplaceAll("+", "p");
652 fName.ReplaceAll(".", "d");
654 // Copy to other our object
657 if (mAxis.GetXbins() && mAxis.GetXbins()->GetArray()) {
658 const TArrayD& mA = *(mAxis.GetXbins());
659 TArrayD tA(mA.GetSize());
661 Double_t min = mA[0];
663 for (Int_t i = 1; i < mA.GetSize(); i++) {
664 Double_t d = mA[i] - min;
666 // Not full integer bin
668 tA[j+1] = tA[j] + Int_t(d);
672 fTAxis.Set(j, tA.GetArray());
675 // Rounded down maximum and minimum
676 Int_t max = Int_t(mAxis.GetXmax());
677 Int_t min = Int_t(mAxis.GetXmin());
678 fTAxis.Set((max-min)+1, min-.5, max+.5);
681 //____________________________________________________________________
682 AliForwardMultDists::EtaBin::EtaBin(const EtaBin& o)
693 fResponse(o.fResponse),
695 fTruthAccepted(o.fTruthAccepted),
696 fCoverage(o.fCoverage)
698 //____________________________________________________________________
699 AliForwardMultDists::EtaBin&
700 AliForwardMultDists::EtaBin::operator=(const EtaBin& o)
702 if (&o == this) return *this;
713 fResponse = o.fResponse;
715 fTruthAccepted = o.fTruthAccepted;
716 fCoverage = o.fCoverage;
720 //____________________________________________________________________
722 AliForwardMultDists::EtaBin::IsSymmetric() const
724 return TMath::Abs(fMaxEta + fMinEta) < 1e-6;
726 //____________________________________________________________________
728 AliForwardMultDists::EtaBin::IsNegative() const
730 return TMath::Abs(fMaxEta) < 1e-6 && fMinEta < 0;
732 //____________________________________________________________________
734 AliForwardMultDists::EtaBin::IsPositive() const
736 return TMath::Abs(fMinEta) < 1e-6 && fMaxEta > 0;
738 //____________________________________________________________________
740 AliForwardMultDists::EtaBin::ParentName() const
742 if (IsSymmetric()) return "symmetric";
743 else if (IsNegative()) return "negative";
744 else if (IsPositive()) return "positive";
747 //____________________________________________________________________
749 AliForwardMultDists::EtaBin::FindParent(TList* l, Bool_t create) const
751 const char* parent = ParentName();
752 TObject* op = l->FindObject(parent);
754 if (op) return static_cast<TList*>(op);
755 if (!create) return 0;
757 // Info("FindParent", "Parent %s not found in %s, creating and adding",
758 // parent, l->GetName());
759 TList* p = new TList;
764 TList* lowEdges = new TList;
765 lowEdges->SetName("lowEdges");
766 lowEdges->SetOwner();
769 TList* highEdges = new TList;
770 highEdges->SetName("highEdges");
771 highEdges->SetOwner();
777 //____________________________________________________________________
779 AliForwardMultDists::EtaBin::CreateH1(const char* name,
785 if (xAxis.GetXbins() && xAxis.GetXbins()->GetArray())
786 ret = new TH1D(name,title,xAxis.GetNbins(), xAxis.GetXbins()->GetArray());
788 ret = new TH1D(name,title,xAxis.GetNbins(),xAxis.GetXmin(),xAxis.GetXmax());
791 //____________________________________________________________________
793 AliForwardMultDists::EtaBin::CreateH2(const char* name,
800 if (xAxis.GetXbins() && xAxis.GetXbins()->GetArray()) {
801 if (yAxis.GetXbins() && yAxis.GetXbins()->GetArray())
803 ret = new TH2D(name,title,
804 xAxis.GetNbins(), xAxis.GetXbins()->GetArray(),
805 yAxis.GetNbins(), yAxis.GetXbins()->GetArray());
808 ret = new TH2D(name,title,
809 xAxis.GetNbins(), xAxis.GetXbins()->GetArray(),
810 yAxis.GetNbins(),yAxis.GetXmin(),yAxis.GetXmax());
813 if (yAxis.GetXbins() && yAxis.GetXbins()->GetArray())
815 ret = new TH2D(name,title,
816 xAxis.GetNbins(), xAxis.GetXmin(), xAxis.GetXmax(),
817 yAxis.GetNbins(), yAxis.GetXbins()->GetArray());
820 ret = new TH2D(name,title,
821 xAxis.GetNbins(), xAxis.GetXmin(), xAxis.GetXmax(),
822 yAxis.GetNbins(), yAxis.GetXmin(), yAxis.GetXmax());
827 //____________________________________________________________________
829 AliForwardMultDists::EtaBin::SetupForData(TList* list, const TH2& hist,
833 * Set-up internal structures on first event.
835 * @param list List to add information to
836 * @param hist Template histogram
837 * @param max Maximum number of particles
838 * @param useMC Whether to set-up for MC input
840 TList* p = FindParent(list, true);
841 TList* l = new TList;
842 l->SetName(GetName());
845 TList* le = static_cast<TList*>(p->FindObject("lowEdges"));
846 TList* he = static_cast<TList*>(p->FindObject("highEdges"));
848 AliError("Failed to get bin edge lists from parent");
852 Int_t n = le->GetEntries();
853 TParameter<double>* lp =
854 new TParameter<double>(Form("minEta%02d", n), fMinEta);
855 TParameter<double>* hp =
856 new TParameter<double>(Form("maxEta%02d", n), fMaxEta);
857 lp->SetMergeMode('f');
858 hp->SetMergeMode('f');
863 fMinBin = hist.GetXaxis()->FindBin(fMinEta);
864 fMaxBin = hist.GetXaxis()->FindBin(fMaxEta-.00001);
866 TString t(Form("%+5.2f<#eta<%+5.2f", fMinEta, fMaxEta));
867 fSum = CreateH1("rawDist",Form("Raw P(#it{N}_{ch}) in %s",t.Data()),fMAxis);
868 fSum->SetDirectory(0);
869 fSum->GetXaxis()->SetTitle("#it{N}_{ch}");
870 fSum->GetYaxis()->SetTitle("Raw P(#it{N}_{ch})");
871 fSum->SetFillColor(kRed+1);
872 fSum->SetFillStyle(0);
873 // fSum->SetOption("hist e");
874 fSum->SetMarkerStyle(20);
875 fSum->SetMarkerColor(kRed+1);
876 fSum->SetLineColor(kBlack);
880 fCorr = CreateH2("corr",Form("C_{SPD,FMD} in %s", t.Data()),fTAxis,fTAxis);
881 fCorr->SetDirectory(0);
882 fCorr->GetXaxis()->SetTitle("Forward");
883 fCorr->GetYaxis()->SetTitle("Central");
884 fCorr->SetOption("colz");
887 fCoverage = new TH1D("coverage", "Fraction of bins with coverage",
889 fCoverage->SetDirectory(0);
890 fCoverage->SetXTitle("Fraction of bins [%]");
891 fCoverage->SetFillStyle(3001);
892 fCoverage->SetFillColor(kGreen+1);
896 fResponse = CreateH2("response", Form("Reponse matrix in %s", t.Data()),
898 fResponse->SetDirectory(0);
899 fResponse->SetYTitle("MC");
900 fResponse->SetXTitle("Signal");
901 fResponse->SetOption("colz");
904 fTruth = CreateH1("truth",Form("True P(#it{N}_{ch}) in %s",t.Data()),fTAxis);
905 fTruth->SetXTitle(fSum->GetXaxis()->GetTitle());
906 fTruth->SetYTitle(fSum->GetYaxis()->GetTitle());
907 fTruth->SetLineColor(kBlack);
908 fTruth->SetFillColor(kBlue+1);
909 fTruth->SetFillStyle(0);
910 fTruth->SetDirectory(0);
911 /// fTruth->SetOption("");
912 fTruth->SetMarkerColor(kBlue+1);
913 fTruth->SetMarkerStyle(24);
917 fTruthAccepted = static_cast<TH1D*>(fTruth->Clone("truthAccepted"));
918 fTruthAccepted->SetTitle(Form("True (accepted) P(#it{N}_{ch}) in %s",
920 fTruthAccepted->SetLineColor(kGray+2);
921 fTruthAccepted->SetFillColor(kOrange+2);
922 fTruthAccepted->SetDirectory(0);
923 /// fTruth->SetOption("");
924 fTruthAccepted->SetMarkerColor(kOrange+2);
925 l->Add(fTruthAccepted);
927 //____________________________________________________________________
929 AliForwardMultDists::EtaBin::Process(const TH1& sumForward,
930 const TH1& sumCentral,
937 * Process a single event
939 * @param sumForward Projection of forward data
940 * @param sumCentral Projection of the central data
941 * @param forward The original forward data
942 * @param central The original central data
944 if (!mc && !accepted)
945 // If we're not looking at MC data, and the event wasn't selected,
946 // we bail out - this check is already done, but we do it again
956 Double_t mce2sum = 0;
957 for (Int_t iEta = fMinBin; iEta <= fMaxBin; iEta++) {
959 Double_t cM = mc->GetBinContent(iEta);
960 Double_t eM = mc->GetBinError(iEta);
965 // Event wasn't selected, but we still need to get the rest of
969 Double_t cF = sumForward.GetBinContent(iEta);
970 Double_t eF = sumForward.GetBinError(iEta);
971 Bool_t bF = forward.GetBinContent(iEta, 0) > 0;
972 Double_t cC = sumCentral.GetBinContent(iEta);
973 Double_t eC = sumCentral.GetBinError(iEta);
974 Bool_t bC = central.GetBinContent(iEta, 0) > 0;
978 // If we have an overlap - as given by the eta-coverage,
979 // calculate the mean
982 e = TMath::Sqrt(eF*eF + eC*eC);
985 // Else, if we have coverage from forward, use that
991 // Else, if we have covrage from central, use that
997 // Else, we have incomplete coverage
1000 if (fsum < 0) fsum = 0;
1004 if (csum < 0) csum = 0;
1013 // Only update the histograms if the event was triggered.
1015 Double_t w = 1; // e2sum > 0 ? 1/TMath::Sqrt(e2sum) : 1
1017 fCorr->Fill((fsum<0?0:fsum), (csum<0?0:csum));
1019 Int_t nTotal = fMaxBin - fMinBin + 1;
1020 fCoverage->Fill(100*float(covered) / nTotal);
1024 Double_t w = 1; // mce2sum > 0 ? 1/TMath::Sqrt(mce2sum) : 1
1026 fTruth->Fill(mcsum, w);
1030 // Only fill response matrix for accepted events
1031 fResponse->Fill(sum, mcsum);
1033 fTruthAccepted->Fill(mcsum, w);
1037 //____________________________________________________________________
1039 AliForwardMultDists::EtaBin::Terminate(TList* in, TList* out)
1042 * Called at the end of the final processing of the job on the
1043 * full data set (merged data)
1045 * @param in Input list
1046 * @param out Output list
1047 * @param maxN Maximum number of @f$N_{ch}@f$ to consider
1049 TList* ip = FindParent(in, false);
1051 AliErrorF("Parent folder %s not found in input", ParentName());
1055 TList* i = dynamic_cast<TList*>(ip->FindObject(GetName()));
1057 AliErrorF("List %s not found in input", GetName());
1061 TList* op = FindParent(out, true);
1062 TList* o = static_cast<TList*>(i->Clone());
1066 fSum = static_cast<TH1*>(o->FindObject("rawDist"));
1067 fTruth = static_cast<TH1*>(o->FindObject("truth"));
1068 fTruthAccepted = static_cast<TH1*>(o->FindObject("truthAccepted"));
1070 TH1* hists[] = { fSum, fTruth, fTruthAccepted, 0 };
1071 TH1** phist = hists;
1075 Int_t maxN = h->GetNbinsX();
1076 Double_t intg = h->Integral(1, maxN);
1077 h->Scale(1. / intg, "width");
1082 if (fTruth && fTruthAccepted) {
1083 TH1* trgVtx = static_cast<TH1*>(fTruthAccepted->Clone("triggerVertex"));
1084 TString tit(fTruth->GetTitle());
1085 tit.ReplaceAll("True P(#it{N}_{ch})", "C_{trigger,vertex}");
1086 trgVtx->SetTitle(tit);
1087 trgVtx->SetYTitle("P_{MC}(#it{N}_{ch})/P_{MC,accepted}(#it{N}_{ch})");
1088 trgVtx->Divide(fTruth);
1089 trgVtx->SetDirectory(0);
1094 //====================================================================