1 //====================================================================
3 // Base class for classes that calculate the multiplicity in the
4 // forward regions event-by-event
10 // - AliAODForwardMult
15 #include "AliForwardMultiplicityBase.h"
16 #include "AliForwardCorrectionManager.h"
17 #include "AliForwardUtil.h"
18 #include "AliFMDCorrELossFit.h"
20 #include "AliAODHandler.h"
21 #include "AliInputEventHandler.h"
22 #include "AliAnalysisManager.h"
23 #include "AliFMDEventInspector.h"
24 #include "AliFMDESDFixer.h"
25 #include "AliFMDSharingFilter.h"
26 #include "AliFMDDensityCalculator.h"
27 #include "AliFMDCorrector.h"
28 #include "AliFMDHistCollector.h"
29 #include "AliFMDEventPlaneFinder.h"
30 #include "AliESDEvent.h"
40 # define DEFINE(N) DefineOutput(N,AliAODForwardMult::Class())
41 # define POST(N) PostData(N,fAODFMD)
43 # define DEFINE(N) do { } while(false)
44 # define POST(N) do { } while(false)
47 //====================================================================
48 AliForwardMultiplicityBase::AliForwardMultiplicityBase(const char* name)
49 : AliBaseESDTask(name, "AliForwardMultiplicityBase",
50 &(AliForwardCorrectionManager::Instance())),
51 fEnableLowFlux(false),
61 fAddMask(AliAODForwardMult::kInel)
63 DGUARD(fDebug, 3,"Named CTOR of AliForwardMultiplicityBase %s",name);
69 //____________________________________________________________________
71 AliForwardMultiplicityBase::SetDebug(Int_t dbg)
79 AliBaseESDTask:: SetDebug(dbg);
80 GetSharingFilter() .SetDebug(dbg);
81 GetDensityCalculator().SetDebug(dbg);
82 GetCorrections() .SetDebug(dbg);
83 GetHistCollector() .SetDebug(dbg);
84 GetEventPlaneFinder() .SetDebug(dbg);
87 //____________________________________________________________________
89 AliForwardMultiplicityBase::Book()
92 // Create output objects
95 DGUARD(fDebug,1,"Create user ouput");
96 UInt_t what = AliForwardCorrectionManager::kAll;
98 what ^= AliForwardCorrectionManager::kDoubleHit;
99 if (!GetESDFixer().IsUseNoiseCorrection())
100 what ^= AliForwardCorrectionManager::kNoiseGain;
101 if (!GetCorrections().IsUseVertexBias())
102 what ^= AliForwardCorrectionManager::kVertexBias;
103 if (!GetCorrections().IsUseAcceptance())
104 what ^= AliForwardCorrectionManager::kAcceptance;
105 if (!GetCorrections().IsUseMergingEfficiency())
106 what ^= AliForwardCorrectionManager::kMergingEfficiency;
107 fNeededCorrections = what;
109 GetESDFixer() .CreateOutputObjects(fList);
110 GetSharingFilter() .CreateOutputObjects(fList);
111 GetDensityCalculator().CreateOutputObjects(fList);
112 GetCorrections() .CreateOutputObjects(fList);
113 GetHistCollector() .CreateOutputObjects(fList);
114 GetEventPlaneFinder() .CreateOutputObjects(fList);
119 if (fDebug > 1) fDoTiming = true;
121 fHTiming = new TProfile("timing", "Timing of task",
122 kTimingTotal, 0.5, kTimingTotal+.5);
123 fHTiming->SetDirectory(0);
124 fHTiming->SetFillColor(kRed+1);
125 fHTiming->SetFillStyle(3001);
126 fHTiming->SetMarkerStyle(20);
127 fHTiming->SetMarkerColor(kBlack);
128 fHTiming->SetLineColor(kBlack);
129 fHTiming->SetXTitle("Part");
130 fHTiming->SetYTitle("#LTt_{part}#GT [CPU]");
131 fHTiming->SetStats(0);
132 TAxis* xaxis = fHTiming->GetXaxis();
133 xaxis->SetBinLabel(kTimingEventInspector,
134 GetEventInspector() .GetName());
135 xaxis->SetBinLabel(kTimingSharingFilter,
136 GetSharingFilter() .GetName());
137 xaxis->SetBinLabel(kTimingDensityCalculator,
138 GetDensityCalculator().GetName());
139 xaxis->SetBinLabel(kTimingCorrections,
140 GetCorrections() .GetName());
141 xaxis->SetBinLabel(kTimingHistCollector,
142 GetHistCollector() .GetName());
143 xaxis->SetBinLabel(kTimingEventPlaneFinder,
144 GetEventPlaneFinder() .GetName());
145 xaxis->SetBinLabel(kTimingTotal, "Total");
146 fList->Add(fHTiming);
148 fHStatus = new TH1I("status", "Status of task",15, .5, 15.5);
149 fHStatus->SetDirectory(0);
150 fHStatus->SetFillColor(kCyan+2);
151 fHStatus->SetFillStyle(3001);
152 fHStatus->SetLineColor(kBlack);
153 fHStatus->SetMarkerStyle(20);
154 fHStatus->SetMarkerColor(kBlack);
155 fHStatus->SetYTitle("Events");
156 TAxis* a = fHStatus->GetXaxis();
157 a->SetBinLabel(1,"No event");
158 a->SetBinLabel(2,"No triggers");
159 a->SetBinLabel(3,"No SPD (not used)");
160 a->SetBinLabel(4,"No FMD");
161 a->SetBinLabel(5,"No Vertex");
162 a->SetBinLabel(6,"Pile-up");
163 a->SetBinLabel(7,"IP_{z} out of range");
164 a->SetBinLabel(8,"Merger failed");
165 a->SetBinLabel(9,"N_{ch} estimator failed");
166 a->SetBinLabel(10,"#Phi_{R} estimator failed");
167 a->SetBinLabel(11,"Too many outliers");
168 a->SetBinLabel(12,"Corrector failed");
169 a->SetBinLabel(13,"Histogram collector failed");
170 a->SetBinLabel(14,"Not added");
171 a->SetBinLabel(15,"All through");
172 fList->Add(fHStatus);
177 //____________________________________________________________________
179 AliForwardMultiplicityBase::CreateBranches(AliAODHandler* ah)
181 TObject* obj = &fAODFMD; ah->AddBranch("AliAODForwardMult", &obj);
182 TObject* epobj = &fAODEP; ah->AddBranch("AliAODForwardEP", &epobj);
184 if (!fStorePerRing) return;
186 AliWarning("Per-ring histograms in AOD\n"
187 "*********************************************************\n"
188 "* For each event 5 additional 2D histogram are stored *\n"
189 "* in separate branches of the AODs. This will increase *\n"
190 "* the size of the AODs - proceed with caution *\n"
191 "*********************************************************");
192 TObject* hists[] = { fHistos.fFMD1i,
193 fHistos.fFMD2i, fHistos.fFMD2o,
194 fHistos.fFMD3i, fHistos.fFMD3o };
195 for (Int_t i = 0; i < 5; i++) {
196 ah->AddBranch("TH2D", &(hists[i]));
200 //____________________________________________________________________
202 AliForwardMultiplicityBase::PreData(const TAxis& vertex, const TAxis& eta)
205 // Initialise the sub objects and stuff. Called on first event
208 DGUARD(fDebug,1,"Initialize sub-algorithms");
210 // Force this here so we select the proper quality
211 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
213 UInt_t what = fNeededCorrections;
214 // Check that we have the energy loss fits, needed by
215 // AliFMDSharingFilter
216 // AliFMDDensityCalculator
217 if (what & AliForwardCorrectionManager::kELossFits && !fcm.GetELossFit())
218 AliFatal(Form("No energy loss fits"));
220 // Check that we have the double hit correction - (optionally) used by
221 // AliFMDDensityCalculator
222 if (what & AliForwardCorrectionManager::kDoubleHit && !fcm.GetDoubleHit())
223 AliFatal("No double hit corrections");
225 // Check that we have the secondary maps, needed by
227 // AliFMDHistCollector
228 if (what & AliForwardCorrectionManager::kSecondaryMap &&
229 !fcm.GetSecondaryMap())
230 AliFatal("No secondary corrections");
232 // Check that we have the vertex bias correction, needed by
234 if (what & AliForwardCorrectionManager::kVertexBias && !fcm.GetVertexBias())
235 AliFatal("No event vertex bias corrections");
237 // Check that we have the merging efficiencies, optionally used by
239 if (what & AliForwardCorrectionManager::kMergingEfficiency &&
240 !fcm.GetMergingEfficiency())
241 AliFatal("No merging efficiencies");
243 // Check that we have the acceptance correction, needed by
245 if (what & AliForwardCorrectionManager::kAcceptance && !fcm.GetAcceptance())
246 AliFatal("No acceptance corrections");
248 // const AliFMDCorrELossFit* fits = fcm.GetELossFit();
249 // fits->CacheBins(GetDensityCalculator().GetMinQuality());
251 InitMembers(eta,vertex);
253 GetDensityCalculator().SetupForData(eta);
254 GetSharingFilter() .SetupForData(eta);
255 GetCorrections() .SetupForData(eta);
256 GetHistCollector() .SetupForData(vertex,eta);
258 GetEventPlaneFinder() .SetRunNumber(GetEventInspector().GetRunNumber());
259 GetEventPlaneFinder() .SetupForData(eta);
261 fAODFMD.SetBit(AliAODForwardMult::kSecondary,
262 GetCorrections().IsUseSecondaryMap());
263 fAODFMD.SetBit(AliAODForwardMult::kVertexBias,
264 GetCorrections().IsUseVertexBias());
265 fAODFMD.SetBit(AliAODForwardMult::kAcceptance,
266 GetCorrections().IsUseAcceptance());
267 fAODFMD.SetBit(AliAODForwardMult::kMergingEfficiency,
268 GetCorrections().IsUseMergingEfficiency());
269 fAODFMD.SetBit(AliAODForwardMult::kSum,
270 GetHistCollector().GetMergeMethod() ==
271 AliFMDHistCollector::kSum);
275 //____________________________________________________________________
277 AliForwardMultiplicityBase::InitMembers(const TAxis& eta, const TAxis& /*pv*/)
284 fHData = static_cast<TH2D*>(fAODFMD.GetHistogram().Clone("d2Ndetadphi"));
286 fHData->SetDirectory(0);
289 TList* rings = new TList;
290 rings->SetName("ringSums");
294 rings->Add(fRingSums.Get(1, 'I'));
295 rings->Add(fRingSums.Get(2, 'I'));
296 rings->Add(fRingSums.Get(2, 'O'));
297 rings->Add(fRingSums.Get(3, 'I'));
298 rings->Add(fRingSums.Get(3, 'O'));
299 fRingSums.Get(1, 'I')->SetMarkerColor(AliForwardUtil::RingColor(1, 'I'));
300 fRingSums.Get(2, 'I')->SetMarkerColor(AliForwardUtil::RingColor(2, 'I'));
301 fRingSums.Get(2, 'O')->SetMarkerColor(AliForwardUtil::RingColor(2, 'O'));
302 fRingSums.Get(3, 'I')->SetMarkerColor(AliForwardUtil::RingColor(3, 'I'));
303 fRingSums.Get(3, 'O')->SetMarkerColor(AliForwardUtil::RingColor(3, 'O'));
305 //____________________________________________________________________
307 AliForwardMultiplicityBase::PostEvent()
312 //____________________________________________________________________
314 AliForwardMultiplicityBase::Finalize()
322 DGUARD(fDebug,1,"Processing the merged results");
325 TList* output = fResults;
326 Double_t nTr = 0, nTrVtx = 0, nAcc = 0;
327 MakeSimpledNdeta(list, output, nTr, nTrVtx, nAcc);
329 "\t# events w/trigger: %f\n"
330 "\t# events w/trigger+vertex: %f\n"
331 "\t# events accepted by cuts: %f",
334 EstimatedNdeta(list, output);
336 GetSharingFilter() .Terminate(list,output,Int_t(nTr));
337 GetDensityCalculator().Terminate(list,output,Int_t(nTrVtx));
338 GetCorrections() .Terminate(list,output,Int_t(nTrVtx));
340 TProfile* timing = static_cast<TProfile*>(list->FindObject("timing"));
341 Int_t nTiming = (timing ? timing->GetBinContent(timing->GetNbinsX()) : 0);
342 if (timing && nTiming > 0) {
343 TProfile* p = static_cast<TProfile*>(timing->Clone());
345 p->Scale(100. / nTiming);
346 p->SetYTitle("#LTt_{part}#GT/#LTt_{total}#GT [%]");
347 p->SetTitle("Relative timing of task");
353 //____________________________________________________________________
355 AliForwardMultiplicityBase::EstimatedNdeta(const TList* input,
358 MakeRingdNdeta(input, "ringSums", output, "ringResults");
361 //____________________________________________________________________
363 AliForwardMultiplicityBase::MakeSimpledNdeta(const TList* input,
369 // Get our histograms from the container
371 TH1I* hEventsTrVtx = 0;
372 TH1I* hEventsAcc = 0;
374 TH1* hStatus = dynamic_cast<TH1*>(input->FindObject("status"));
375 if (!GetEventInspector().FetchHistograms(input,
380 AliError(Form("Didn't get histograms from event selector "
381 "(hEventsTr=%p,hEventsTrVtx=%p,hEventsAcc=%p,hTriggers=%p)",
382 hEventsTr, hEventsTrVtx, hEventsAcc, hTriggers));
386 nTr = hEventsTr->Integral();
387 nTrVtx = hEventsTrVtx->Integral();
388 nAcc = hEventsAcc->Integral();
389 Double_t vtxEff = nTrVtx / nTr;
390 Double_t vtxEff2 = 0;
392 Double_t nTrg = hStatus->Integral(3,15);
393 Double_t nTrgVtx = hStatus->Integral(6,15);
394 vtxEff2 = (nTrg > 0 ? nTrgVtx / nTrg : 0);
397 TH2D* hData = static_cast<TH2D*>(input->FindObject("d2Ndetadphi"));
399 AliError(Form("Couldn't get our summed histogram from output "
400 "list %s (d2Ndetadphi=%p)", input->GetName(), hData));
405 Int_t nY = hData->GetNbinsY();
406 TH1D* dNdeta = hData->ProjectionX("dNdeta", 1, nY, "e");
407 TH1D* dNdeta_ = hData->ProjectionX("dNdeta_", 1, nY, "e");
408 TH1D* norm = hData->ProjectionX("norm", 0, 0, "");
409 TH1D* phi = hData->ProjectionX("phi", nY+1, nY+1, "");
410 dNdeta->SetTitle("dN_{ch}/d#eta in the forward regions");
411 dNdeta->SetYTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
412 dNdeta->SetMarkerColor(kRed+1);
413 dNdeta->SetMarkerStyle(20);
414 dNdeta->SetDirectory(0);
416 dNdeta_->SetTitle("dN_{ch}/d#eta in the forward regions");
417 dNdeta_->SetYTitle("#frac{1}{N}#frac{dN_{ch}}{d#eta}");
418 dNdeta_->SetMarkerColor(kMagenta+1);
419 dNdeta_->SetMarkerStyle(21);
420 dNdeta_->SetDirectory(0);
422 norm->SetTitle("Normalization to #eta coverage");
423 norm->SetYTitle("#eta coverage");
424 norm->SetLineColor(kBlue+1);
425 norm->SetMarkerColor(kBlue+1);
426 norm->SetMarkerStyle(21);
427 norm->SetFillColor(kBlue+1);
428 norm->SetFillStyle(3005);
429 norm->SetDirectory(0);
431 phi->SetTitle("Normalization to #phi acceptance");
432 phi->SetYTitle("#phi acceptance");
433 phi->SetLineColor(kGreen+1);
434 phi->SetMarkerColor(kGreen+1);
435 phi->SetMarkerStyle(20);
436 phi->SetFillColor(kGreen+1);
437 phi->SetFillStyle(3004);
438 // phi->Scale(1. / nAcc);
439 phi->SetDirectory(0);
441 // dNdeta->Divide(norm);
444 dNdeta->Scale(vtxEff, "width");
446 dNdeta_->Divide(norm);
447 dNdeta_->SetStats(0);
448 dNdeta_->Scale(vtxEff, "width");
451 "\tNormalization eta: %d\n"
452 "\tNormalization phi: %d\n"
453 "\tVertex efficiency: %f (%f)",
454 Int_t(norm->GetMaximum()), Int_t(phi->GetMaximum()),
457 output->Add(dNdeta_);
465 //____________________________________________________________________
467 AliForwardMultiplicityBase::MakeRingdNdeta(const TList* input,
473 // Make dN/deta for each ring found in the input list.
475 // A stack of all the dN/deta is also made for easy drawing.
477 // Note, that the distributions are normalised to the number of
478 // observed events only - they should be corrected for
479 DGUARD(fDebug,3,"Make first-shot ring dN/deta");
482 TList* list = static_cast<TList*>(input->FindObject(inName));
484 AliWarning(Form("No list %s found in %s", inName, input->GetName()));
488 TList* out = new TList;
489 out->SetName(outName);
493 THStack* dndetaRings = new THStack("all", "dN/d#eta per ring");
494 const char* names[] = { "FMD1I", "FMD2I", "FMD2O", "FMD3I", "FMD3O", 0 };
495 const char** ptr = names;
498 TList* thisList = new TList;
499 thisList->SetOwner();
500 thisList->SetName(*ptr);
503 TH2D* h = static_cast<TH2D*>(list->FindObject(Form("%s_cache", *ptr)));
505 AliWarning(Form("Didn't find %s_cache in %s", *ptr, list->GetName()));
509 TH2D* sumPhi = static_cast<TH2D*>(h->Clone("sum_phi"));
510 sumPhi->SetDirectory(0);
511 thisList->Add(sumPhi);
513 TH2D* sumEta = static_cast<TH2D*>(h->Clone("sum_eta"));
514 sumEta->SetDirectory(0);
515 thisList->Add(sumEta);
517 Int_t nY = sumEta->GetNbinsY();
518 TH1D* etaCov =static_cast<TH1D*>(h->ProjectionX("etaCov", 0, 0, ""));
519 TH1D* phiAcc =static_cast<TH1D*>(h->ProjectionX("phiAcc", nY+1, nY+1, ""));
521 etaCov->SetTitle("Normalization to #eta coverage");
522 etaCov->SetYTitle("#eta coverage");
523 etaCov->SetMarkerColor(kBlue+1);
524 etaCov->SetFillColor(kBlue+1);
525 etaCov->SetFillStyle(3005);
526 etaCov->SetDirectory(0);
528 phiAcc->SetTitle("Normalization to #phi acceptance");
529 phiAcc->SetYTitle("#phi acceptance");
530 phiAcc->SetMarkerColor(kGreen+1);
531 phiAcc->SetFillColor(kGreen+1);
532 phiAcc->SetFillStyle(3004);
533 // phiAcc->Scale(1. / nAcc);
534 phiAcc->SetDirectory(0);
536 // Double_t s = (etaCov->GetMaximum() > 0 ? 1. / etaCov->GetMaximum() : 1);
537 for (Int_t i = 1; i <= sumEta->GetNbinsX(); i++) {
538 for (Int_t j = 1; j <= nY; j++) {
539 Double_t c = sumEta->GetBinContent(i, j);
540 Double_t e = sumEta->GetBinError(i, j);
541 Double_t a = etaCov->GetBinContent(i);
542 Double_t p = phiAcc->GetBinContent(i);
543 // Double_t t = p; // * a
544 sumEta->SetBinContent(i, j, a <= 0 ? 0 : c / a);
545 sumEta->SetBinError( i, j, a <= 0 ? 0 : e / a);
546 sumPhi->SetBinContent(i, j, p <= 0 ? 0 : c / p);
547 sumPhi->SetBinError( i, j, p <= 0 ? 0 : e / p);
553 TH1D* resPhi =static_cast<TH1D*>(sumPhi->ProjectionX("dndeta_phi",
555 resPhi->SetMarkerStyle(style);
556 resPhi->SetDirectory(0);
557 resPhi->Scale(1, "width");
559 TH1D* resEta =static_cast<TH1D*>(sumEta->ProjectionX("dndeta_eta",
561 resEta->SetMarkerStyle(style);
562 resEta->SetDirectory(0);
563 resEta->Scale(1, "width");
565 thisList->Add(resEta);
566 thisList->Add(etaCov);
567 thisList->Add(resPhi);
568 thisList->Add(phiAcc);
569 dndetaRings->Add(resPhi);
572 "\tNormalization eta: %d\n"
573 "\tNormalization phi: %d\n",
575 Int_t(etaCov->GetMaximum()), Int_t(phiAcc->GetMaximum()));
579 out->Add(dndetaRings);
581 #define PFB(N,FLAG) \
583 AliForwardUtil::PrintName(N); \
584 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
586 #define PFV(N,VALUE) \
588 AliForwardUtil::PrintName(N); \
589 std::cout << (VALUE) << std::endl; } while(false)
590 //____________________________________________________________________
592 AliForwardMultiplicityBase::Print(Option_t* option) const
600 AliBaseESDTask::Print(option);
601 gROOT->IncreaseDirLevel();
602 PFB("Enable low flux code", fEnableLowFlux);
603 PFB("Store per-ring hists", fStorePerRing);
604 PFB("Make timing histogram", fDoTiming);
605 PFV("Trigger mask for adding", AliAODForwardMult::GetTriggerString(fAddMask));
606 // gROOT->IncreaseDirLevel();
607 GetESDFixer() .Print(option);
608 GetSharingFilter() .Print(option);
609 GetDensityCalculator().Print(option);
610 GetCorrections() .Print(option);
611 GetHistCollector() .Print(option);
612 GetEventPlaneFinder() .Print(option);
613 // gROOT->DecreaseDirLevel();
614 gROOT->DecreaseDirLevel();