1 //====================================================================
3 // Base class for classes that calculate the multiplicity in the
4 // central region event-by-event
10 // - AliAODCentralMult
15 #include "AliCentralMultiplicityTask.h"
16 #include "AliCentralCorrectionManager.h"
17 #include "AliCentralCorrAcceptance.h"
18 #include "AliCentralCorrSecondaryMap.h"
19 #include "AliAODForwardMult.h"
20 #include "AliForwardUtil.h"
22 #include "AliAODHandler.h"
23 #include "AliAnalysisManager.h"
24 #include "AliESDEvent.h"
25 #include "AliMultiplicity.h"
31 #include <TObjArray.h>
35 //====================================================================
36 AliCentralMultiplicityTask::AliCentralMultiplicityTask(const char* name)
37 : AliBaseESDTask(name, "AliCentralMultiplicityTask",
38 &(AliCentralCorrectionManager::Instance())),
45 fClusterPerTracklet(0),
55 DGUARD(fDebug, 3,"Named CTOR of AliCentralMultiplicityTask: %s", name);
57 "ESD:AliESDRun.,AliESDHeader.,AliMultiplicity.,"
58 "SPDVertex.,PrimaryVertex.";
60 //____________________________________________________________________
61 AliCentralMultiplicityTask::AliCentralMultiplicityTask()
69 fClusterPerTracklet(0),
79 DGUARD(fDebug, 3,"Default CTOR of AliCentralMultiplicityTask");
82 //____________________________________________________________________
84 AliCentralMultiplicityTask::CreateBranches(AliAODHandler* ah)
87 // Create output objects
90 DGUARD(fDebug,1,"Create user output in AliCentralMultiplicityTask");
93 //AliFatal("No AOD output handler set in analysis manager");
96 TObject* obj = &fAODCentral;
97 ah->AddBranch("AliAODCentralMult", &obj);
99 //____________________________________________________________________
101 AliCentralMultiplicityTask::Book()
103 fNeededCorrections = (AliCentralCorrectionManager::kSecondaryMap|
104 AliCentralCorrectionManager::kAcceptance);
108 //____________________________________________________________________
110 AliCentralMultiplicityTask::PreData(const TAxis& vertex, const TAxis& eta)
113 // unsigned short s = 1;
114 TH2D* hCoverage = new TH2D("coverage", "#eta coverage per v_{z}",
115 eta.GetNbins(), eta.GetXmin(), eta.GetXmax(),
116 vertex.GetNbins(),vertex.GetXmin(),
118 hCoverage->SetDirectory(0);
119 hCoverage->SetXTitle("#eta");
120 hCoverage->SetYTitle("v_{z} [cm]");
121 hCoverage->SetZTitle("n_{bins}");
123 fAODCentral.Init(eta);
125 UShort_t nVz = vertex.GetNbins();
126 fVtxList = new TObjArray(nVz, 1);
127 fVtxList->SetName("centMultVtxBins");
128 fVtxList->SetOwner();
130 // Bool_t store = false;
131 for (Int_t v = 1; v <= nVz; v++) {
132 VtxBin* bin = new VtxBin(v, vertex.GetBinLowEdge(v),
133 vertex.GetBinUpEdge(v));
134 bin->SetupForData(fList, hCoverage, fStore);
135 fVtxList->AddAt(bin, v);
137 fList->Add(hCoverage);
141 // N-bins, loweset order, higest order, return array
142 AliForwardUtil::MakeLogScale(300, 0, 5, bins);
143 fNClusterTracklet = new TH2D("nClusterVsnTracklet",
144 "Total number of cluster vs number of tracklets",
145 bins.GetSize()-1, bins.GetArray(),
146 bins.GetSize()-1, bins.GetArray());
147 fNClusterTracklet->SetDirectory(0);
148 fNClusterTracklet->SetXTitle("N_{free cluster}");
149 fNClusterTracklet->SetYTitle("N_{tracklet}");
150 fNClusterTracklet->SetStats(0);
151 fList->Add(fNClusterTracklet);
155 fClusterPerTracklet = new TH2D("clusterPerTracklet",
156 "N_{free cluster}/N_{tracklet} vs. #eta",
157 nEta,-lEta,lEta, 101, -.05, 10.05);
158 fClusterPerTracklet->SetDirectory(0);
159 fClusterPerTracklet->SetXTitle("#eta");
160 fClusterPerTracklet->SetYTitle("N_{free cluster}/N_{tracklet}");
161 fClusterPerTracklet->SetStats(0);
162 fList->Add(fClusterPerTracklet);
165 fNCluster = new TH1D("cacheCluster", "", nEta,-lEta,lEta);
166 fNCluster->SetDirectory(0);
169 fNTracklet = new TH1D("cacheTracklet", "", nEta,-lEta,lEta);
170 fNTracklet->SetDirectory(0);
173 fList->Add(AliForwardUtil::MakeParameter("secondary", fUseSecondary));
174 fList->Add(AliForwardUtil::MakeParameter("acceptance", fUseAcceptance));
176 fHData = static_cast<TH2D*>(fAODCentral.GetHistogram().Clone("d2Ndetadphi"));
178 fHData->SetDirectory(0);
181 // Initialize the inspecto
182 // fInspector.SetupForData(vertex);
184 fAODCentral.SetBit(AliAODCentralMult::kSecondary, fUseSecondary);
185 fAODCentral.SetBit(AliAODCentralMult::kAcceptance, fUseAcceptance);
189 //____________________________________________________________________
191 AliCentralMultiplicityTask::PreEvent()
193 fAODCentral.Clear("");
196 //____________________________________________________________________
198 AliCentralMultiplicityTask::Event(AliESDEvent& esd)
201 // Process each event
206 DGUARD(fDebug,1,"Process event in AliCentralMultiplicityTask");
208 Bool_t lowFlux = kFALSE;
213 UShort_t nClusters = 0;
214 UInt_t found = fInspector.Process(&esd, triggers, lowFlux,
215 ivz, ip, cent, nClusters);
217 // No event or no trigger
218 if (found & AliFMDEventInspector::kNoEvent) return false;
219 if (found & AliFMDEventInspector::kNoTriggers) return false;
221 // Make sure AOD is filled
224 if (found & AliFMDEventInspector::kNoSPD) return false;
225 if (found & AliFMDEventInspector::kNoVertex) return false;
226 if (triggers & AliAODForwardMult::kPileUp) return false;
227 if (found & AliFMDEventInspector::kBadVertex) return false;
230 const AliMultiplicity* spdmult = esd.GetMultiplicity();
232 TH2D& aodHist = fAODCentral.GetHistogram();
234 VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(ivz));
235 if (!bin) return false;
237 ProcessESD(aodHist, spdmult);
238 bin->Correct(aodHist, fUseSecondary, fUseAcceptance);
240 if (triggers & AliAODForwardMult::kInel)
241 fHData->Add(&(fAODCentral.GetHistogram()));
245 //____________________________________________________________________
247 AliCentralMultiplicityTask::ProcessESD(TH2D& aodHist,
248 const AliMultiplicity* spdmult) const
250 DGUARD(fDebug,1,"Process the ESD in AliCentralMultiplicityTask");
254 //Filling clusters in layer 1 used for tracklets...
255 for(Int_t j = 0; j< spdmult->GetNumberOfTracklets();j++) {
256 Double_t eta = spdmult->GetEta(j);
257 fNTracklet->Fill(eta);
258 aodHist.Fill(eta,spdmult->GetPhi(j));
261 //...and then the unused ones in layer 1
262 for(Int_t j = 0; j< spdmult->GetNumberOfSingleClusters();j++) {
263 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
264 fNCluster->Fill(eta);
265 aodHist.Fill(eta, spdmult->GetPhiSingle(j));
267 fNClusterTracklet->Fill(fNCluster->GetEntries(),
268 fNTracklet->GetEntries());
270 fNCluster->Divide(fNTracklet);
271 for (Int_t j = 1; j <= fNCluster->GetNbinsX(); j++)
272 fClusterPerTracklet->Fill(fNCluster->GetXaxis()->GetBinCenter(j),
273 fNCluster->GetBinContent(j));
277 //____________________________________________________________________
279 AliCentralMultiplicityTask::Finalize()
287 DGUARD(fDebug,1,"Process merged output in AliCentralMultiplicityTask");
289 Double_t nTr = 0, nTrVtx = 0, nAcc = 0;
290 MakeSimpledNdeta(fList, fResults, nTr, nTrVtx, nAcc);
292 "\t# events w/trigger: %f\n"
293 "\t# events w/trigger+vertex: %f\n"
294 "\t# events accepted y cuts: %f",
299 //____________________________________________________________________
301 AliCentralMultiplicityTask::MakeSimpledNdeta(const TList* input,
307 // Get our histograms from the container
309 TH1I* hEventsTrVtx = 0;
310 TH1I* hEventsAcc = 0;
312 if (!GetEventInspector().FetchHistograms(input,
317 AliError(Form("Didn't get histograms from event selector "
318 "(hEventsTr=%p,hEventsTrVtx=%p,hEventsAcc=%p,hTriggers=%p)",
319 hEventsTr, hEventsTrVtx, hEventsAcc, hTriggers));
323 nTr = hEventsTr->Integral();
324 nTrVtx = hEventsTrVtx->Integral();
325 nAcc = hEventsAcc->Integral();
326 Double_t vtxEff = nTrVtx / nTr;
327 TH2D* hData = static_cast<TH2D*>(input->FindObject("d2Ndetadphi"));
329 AliError(Form("Couldn't get our summed histogram from output "
330 "list %s (d2Ndetadphi=%p)", input->GetName(), hData));
335 Int_t nY = hData->GetNbinsY();
336 TH1D* dNdeta = hData->ProjectionX("dNdeta", 1, nY, "e");
337 TH1D* dNdeta_ = hData->ProjectionX("dNdeta_", 1, nY, "e");
338 TH1D* norm = hData->ProjectionX("norm", 0, 0, "");
339 TH1D* phi = hData->ProjectionX("phi", nY+1, nY+1, "");
340 dNdeta->SetTitle("dN_{ch}/d#eta in the forward regions");
341 dNdeta->SetYTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
342 dNdeta->SetMarkerColor(kRed+1);
343 dNdeta->SetMarkerStyle(20);
344 dNdeta->SetDirectory(0);
346 dNdeta_->SetTitle("dN_{ch}/d#eta in the forward regions");
347 dNdeta_->SetYTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
348 dNdeta_->SetMarkerColor(kMagenta+1);
349 dNdeta_->SetMarkerStyle(21);
350 dNdeta_->SetDirectory(0);
352 norm->SetTitle("Normalization to #eta coverage");
353 norm->SetYTitle("#eta coverage");
354 norm->SetLineColor(kBlue+1);
355 norm->SetMarkerColor(kBlue+1);
356 norm->SetMarkerStyle(21);
357 norm->SetFillColor(kBlue+1);
358 norm->SetFillStyle(3005);
359 norm->SetDirectory(0);
361 phi->SetTitle("Normalization to #phi acceptance");
362 phi->SetYTitle("#phi acceptance");
363 phi->SetLineColor(kGreen+1);
364 phi->SetMarkerColor(kGreen+1);
365 phi->SetMarkerStyle(20);
366 phi->SetFillColor(kGreen+1);
367 phi->SetFillStyle(3004);
368 // phi->Scale(1. / nAcc);
369 phi->SetDirectory(0);
371 // dNdeta->Divide(norm);
374 dNdeta->Scale(vtxEff, "width");
376 dNdeta_->Divide(norm);
377 dNdeta_->SetStats(0);
378 dNdeta_->Scale(vtxEff, "width");
381 output->Add(dNdeta_);
388 #define PF(N,V,...) \
389 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
390 #define PFB(N,FLAG) \
392 AliForwardUtil::PrintName(N); \
393 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
395 #define PFV(N,VALUE) \
397 AliForwardUtil::PrintName(N); \
398 std::cout << (VALUE) << std::endl; } while(false)
400 //____________________________________________________________________
402 AliCentralMultiplicityTask::Print(Option_t* option) const
410 AliBaseESDTask::Print(option);
411 PFB("Use secondary correction", fUseSecondary);
412 PFB("Use acceptance correction", fUseAcceptance);
414 AliCentralCorrectionManager& ccm =
415 AliCentralCorrectionManager::Instance();
417 const AliCentralCorrSecondaryMap* secMap = ccm.GetSecondaryMap();
419 const TAxis& vaxis = secMap->GetVertexAxis();
421 std::cout << " Eta ranges:\n"
422 << " Vertex | Eta bins\n"
424 << " ----------------+-----------" << std::endl;
425 for (Int_t v = 1; v <= vaxis.GetNbins(); v++) {
426 VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(v));
433 gROOT->IncreaseDirLevel();
435 // fInspector.Print(option);
436 gROOT->DecreaseDirLevel();
440 //====================================================================
441 AliCentralMultiplicityTask::VtxBin::VtxBin(Int_t iVz,
454 //____________________________________________________________________
455 AliCentralMultiplicityTask::VtxBin::VtxBin(const VtxBin& o)
467 //____________________________________________________________________
468 AliCentralMultiplicityTask::VtxBin&
469 AliCentralMultiplicityTask::VtxBin::operator=(const VtxBin& o)
471 if (&o == this) return *this;
484 //____________________________________________________________________
486 AliCentralMultiplicityTask::VtxBin::GetName() const
488 return Form("%c%03d_%c%03d",
489 (fMinIpZ >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fMinIpZ)),
490 (fMaxIpZ >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fMaxIpZ)));
493 //____________________________________________________________________
495 AliCentralMultiplicityTask::VtxBin::SetupForData(TList* l,
502 out->SetName(GetName());
507 AliCentralCorrectionManager& ccm =
508 AliCentralCorrectionManager::Instance();
519 // Get secondary correction and make a projection onto eta
520 TH2* sec = ccm.GetSecondaryMap()->GetCorrection(UShort_t(fId));
521 TH1* acc = ccm.GetAcceptance()->GetCorrection(UShort_t(fId));
522 fSec = static_cast<TH2*>(sec->Clone());
523 fAcc = static_cast<TH1*>(acc->Clone());
524 fSec->SetDirectory(0);
525 fAcc->SetDirectory(0);
527 TH1D* proj = fSec->ProjectionX("secondary");
528 proj->SetDirectory(0);
529 proj->Scale(1. / fSec->GetNbinsY());
531 // Find lower bound on eta
532 fEtaMin = proj->GetNbinsX();
533 for (Int_t e = 1; e <= proj->GetNbinsX(); e++) {
534 Double_t c = proj->GetBinContent(e);
535 if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
540 // Find upper bound on eta
542 for (Int_t e = proj->GetNbinsX(); e >= 1; e--) {
543 Double_t c = proj->GetBinContent(e);
544 if (c > .5 /*&& TMath::Abs(c - prev) < .1*c*/) {
549 // Fill our coverage histogram
550 for (Int_t nn = fEtaMin; nn<=fEtaMax; nn++) {
551 coverage->SetBinContent(nn,fId,1);
555 // If we're not asked to store anything, clean-up, and get out
560 // Modify the title of the projection
561 proj->SetTitle(Form("Projection of secondary correction "
562 "for %+5.1f<v_{z}<%+5.1f",fMinIpZ, fMaxIpZ));
563 proj->SetYTitle("#LT 2^{nd} correction#GT");
564 proj->SetMarkerStyle(20);
565 proj->SetMarkerColor(kBlue+1);
568 // Make some histograms to store diagnostics
569 TH2D* obg = static_cast<TH2D*>(fSec->Clone("secondaryMapFiducial"));
570 obg->SetTitle(Form("%s - fiducial volume", obg->GetTitle()));
571 obg->GetYaxis()->SetTitle("#varphi");
572 obg->SetDirectory(0);
575 TH1D* after = static_cast<TH1D*>(proj->Clone("secondaryFiducial"));
576 after->SetDirectory(0);
577 after->GetYaxis()->SetTitle("#LT 2^{nd} correction#GT");
578 after->SetTitle(Form("%s - fiducial volume", after->GetTitle()));
579 after->SetMarkerColor(kRed+1);
586 fHits = static_cast<TH2D*>(fSec->Clone("hitMap"));
587 fHits->SetDirectory(0);
588 fHits->SetTitle(Form("d^{2}N/d#eta d#phi for %+5.1f<v_{z}<%+5.1f",
590 fHits->GetYaxis()->SetTitle("#varphi");
591 fHits->GetZaxis()->SetTitle("d^{2}N/d#eta d#varphi");
592 fHits->SetMarkerColor(kBlack);
593 fHits->SetMarkerStyle(1);
596 // Get the acceptance, and store that
597 TH1D* accClone = static_cast<TH1D*>(fAcc->Clone("acceptance"));
598 accClone->SetTitle(Form("Acceptance for %+5.1f<v_{z}<%+5.1f",
600 accClone->SetDirectory(0);
603 // Now zero content outside our eta range
604 for (Int_t e = 1; e < fEtaMin; e++) {
605 after->SetBinContent(e, 0);
606 after->SetBinError(e, 0);
607 for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
608 obg->SetBinContent(e,nn,0);
611 for (Int_t e = fEtaMax+1; e <= proj->GetNbinsX(); e++) {
612 after->SetBinContent(e, 0);
613 after->SetBinError(e, 0);
614 for(Int_t nn =1; nn <=obg->GetNbinsY();nn++)
615 obg->SetBinContent(e,nn,0);
618 //____________________________________________________________________
620 AliCentralMultiplicityTask::VtxBin::Correct(TH2D& aodHist,
622 Bool_t useAcceptance,
625 if (useSecondary && fSec) aodHist.Divide(fSec);
627 Int_t nY = aodHist.GetNbinsY();
628 for(Int_t ix = 1; ix <= aodHist.GetNbinsX(); ix++) {
629 Bool_t fiducial = true;
630 if (ix < fEtaMin || ix > fEtaMax) fiducial = false;
631 // Bool_t etabinSeen = kFALSE;
633 Double_t eta = aodHist.GetXaxis()->GetBinCenter(ix);
634 Int_t iax = fAcc->GetXaxis()->FindBin(eta);
635 Float_t accCor = fAcc->GetBinContent(iax);
637 // Float_t accErr = fAcc->GetBinError(ix);
640 for(Int_t iy = 1; iy <= nY; iy++) {
641 // If outside our fiducial volume, zero content
643 aodHist.SetBinContent(ix, iy, 0);
644 aodHist.SetBinError(ix, iy, 0);
647 // Get currrent value
648 Float_t aodValue = aodHist.GetBinContent(ix,iy);
649 Float_t aodErr = aodHist.GetBinError(ix,iy);
651 // Ignore very small values
652 if (aodValue < 0.000001) {
653 aodHist.SetBinContent(ix,iy, 0);
654 aodHist.SetBinError(ix,iy, 0);
657 if (!useAcceptance) continue;
659 // Acceptance correction
660 Float_t accTmp = accCor;
661 if (accTmp < 0.000001) accTmp = 1;
662 Float_t aodNew = aodValue / accTmp ;
663 aodHist.SetBinContent(ix,iy, aodNew);
664 aodHist.SetBinError(ix,iy,aodErr);
666 // Float_t error = aodNew*TMath::Sqrt(TMath::Power(aodErr/aodValue,2) +
667 // TMath::Power(accErr/accCor,2) );
668 // test - aodHist.SetBinError(ix,iy,error);
670 //Filling underflow bin if we eta bin is in range
672 aodHist.SetBinContent(ix,0, 1.);
673 aodHist.SetBinContent(ix,nY+1, accCor);
676 if (sum && fHits) fHits->Add(&aodHist);
679 //____________________________________________________________________
681 AliCentralMultiplicityTask::VtxBin::Print(Option_t* /*option*/) const
684 << std::setw(2) << fId << " "
685 << std::setw(5) << fMinIpZ << "-"
686 << std::setw(5) << fMaxIpZ << " | "
687 << std::setw(3) << fEtaMin << "-"
688 << std::setw(3) << fEtaMax << std::endl;