2 // This class inspects the event
5 // - AliESDFMD object possibly corrected for sharing
8 // - A histogram of v_z of events with triggers.
9 // - A histogram of v_z of events with vertex and triggers
10 // - A histogram of trigger counters
12 // Note, that these are added to the master output list
17 #include "AliFMDEventInspector.h"
19 #include "AliESDEvent.h"
20 #include "AliMultiplicity.h"
21 #include "AliAnalysisManager.h"
22 #include "AliMCEventHandler.h"
23 #include "AliInputEventHandler.h"
24 #include "AliTriggerAnalysis.h"
25 #include "AliPhysicsSelection.h"
26 #include "AliOADBPhysicsSelection.h"
27 #include "AliAODForwardMult.h"
28 #include "AliForwardUtil.h"
29 #include "AliCentrality.h"
32 #include <TDirectory.h>
34 #include <TParameter.h>
37 #include "AliMCEvent.h"
38 #include "AliHeader.h"
39 #include "AliGenEventHeader.h"
40 #include "AliCollisionGeometry.h"
41 #include "AliVVZERO.h"
43 //====================================================================
44 const char* AliFMDEventInspector::fgkFolderName = "fmdEventInspector";
46 //____________________________________________________________________
47 AliFMDEventInspector::AliFMDEventInspector()
52 fHEventsAcceptedXY(0),
67 fCollisionSystem(kUnknown),
71 fUseFirstPhysicsVertex(false),
74 fMinPileupDistance(0.8),
75 fUseDisplacedVertices(false),
82 fUsepA2012Vertex(false),
88 DGUARD(fDebug,1,"Default CTOR of AliFMDEventInspector");
91 //____________________________________________________________________
92 AliFMDEventInspector::AliFMDEventInspector(const char* name)
93 : TNamed(fgkFolderName, name),
97 fHEventsAcceptedXY(0),
112 fCollisionSystem(kUnknown),
116 fUseFirstPhysicsVertex(false),
118 fMinPileupContrib(3),
119 fMinPileupDistance(0.8),
120 fUseDisplacedVertices(false),
127 fUsepA2012Vertex(false),
134 // name Name of object
136 DGUARD(fDebug,1,"Named CTOR of AliFMDEventInspector: %s", name);
139 //____________________________________________________________________
140 AliFMDEventInspector::AliFMDEventInspector(const AliFMDEventInspector& o)
142 fHEventsTr(o.fHEventsTr),
143 fHEventsTrVtx(o.fHEventsTrVtx),
144 fHEventsAccepted(o.fHEventsAccepted),
145 fHEventsAcceptedXY(o.fHEventsAcceptedXY),
146 fHTriggers(o.fHTriggers),
147 fHTriggerCorr(o.fHTriggerCorr),
151 fHCentVsQual(o.fHCentVsQual),
152 fHStatus(o.fHStatus),
153 fHVtxStatus(o.fHVtxStatus),
154 fHTrgStatus(o.fHTrgStatus),
155 fLowFluxCut(o.fLowFluxCut),
156 fMaxVzErr(o.fMaxVzErr),
160 fCollisionSystem(o.fCollisionSystem),
163 fVtxAxis(o.fVtxAxis),
164 fUseFirstPhysicsVertex(o.fUseFirstPhysicsVertex),
165 fUseV0AND(o.fUseV0AND),
166 fMinPileupContrib(o.fMinPileupContrib),
167 fMinPileupDistance(o.fMinPileupDistance),
168 fUseDisplacedVertices(o.fUseDisplacedVertices),
169 fDisplacedVertex(o.fDisplacedVertex),
172 fCentMethod(o.fCentMethod),
173 fMinCent(o.fMinCent),
174 fMaxCent(o.fMaxCent),
175 fUsepA2012Vertex(o.fUsepA2012Vertex),
176 fRunNumber(o.fRunNumber)
183 // o Object to copy from
185 DGUARD(fDebug,1,"Copy CTOR of AliFMDEventInspector");
188 //____________________________________________________________________
189 AliFMDEventInspector::~AliFMDEventInspector()
194 DGUARD(fDebug,1,"DTOR of AliFMDEventInspector");
195 // if (fList) delete fList;
197 //____________________________________________________________________
198 AliFMDEventInspector&
199 AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
202 // Assignement operator
205 // o Object to assign from
208 // Reference to this object
210 DGUARD(fDebug,3,"Assignment of AliFMDEventInspector");
211 if (&o == this) return *this;
212 TNamed::operator=(o);
213 fHEventsTr = o.fHEventsTr;
214 fHEventsTrVtx = o.fHEventsTrVtx;
215 fHEventsAccepted = o.fHEventsAccepted;
216 fHEventsAcceptedXY = o.fHEventsAcceptedXY;
217 fHTriggers = o.fHTriggers;
218 fHTriggerCorr = o.fHTriggerCorr;
222 fHCentVsQual = o.fHCentVsQual;
223 fHStatus = o.fHStatus;
224 fHVtxStatus = o.fHVtxStatus;
225 fHTrgStatus = o.fHTrgStatus;
226 fLowFluxCut = o.fLowFluxCut;
227 fMaxVzErr = o.fMaxVzErr;
229 fList = (o.fList ? new TList : 0);
232 fCollisionSystem = o.fCollisionSystem;
233 fVtxAxis.Set(o.fVtxAxis.GetNbins(), o.fVtxAxis.GetXmin(),
234 o.fVtxAxis.GetXmax());
236 fUseFirstPhysicsVertex = o.fUseFirstPhysicsVertex;
237 fUseV0AND = o.fUseV0AND;
238 fMinPileupContrib = o.fMinPileupContrib;
239 fMinPileupDistance = o.fMinPileupDistance;
240 fUseDisplacedVertices = o.fUseDisplacedVertices;
241 fDisplacedVertex = o.fDisplacedVertex;
242 fCentMethod = o.fCentMethod;
243 fMinCent = o.fMinCent;
244 fMaxCent = o.fMaxCent;
245 fUsepA2012Vertex = o.fUsepA2012Vertex;
246 fRunNumber = o.fRunNumber;
249 fList->SetName(GetName());
250 if (fHEventsTr) fList->Add(fHEventsTr);
251 if (fHEventsTrVtx) fList->Add(fHEventsTrVtx);
252 if (fHTriggers) fList->Add(fHTriggers);
253 if (fHTriggerCorr) fList->Add(fHTriggerCorr);
254 if (fHType) fList->Add(fHType);
255 if (fHWords) fList->Add(fHWords);
256 if (fHCent) fList->Add(fHCent);
257 if (fHCentVsQual) fList->Add(fHCentVsQual);
258 if (fHStatus) fList->Add(fHStatus);
259 if (fHVtxStatus) fList->Add(fHVtxStatus);
260 if (fHTrgStatus) fList->Add(fHTrgStatus);
265 //____________________________________________________________________
267 AliFMDEventInspector::SetCentralityMethod(ECentMethod m)
270 case kV0Multiplicity: fCentMethod = "VOM"; break; // VZERO multiplicity
271 case kV0Amplitude: fCentMethod = "V0A"; break; // VZERO amplitude
272 case kV0Charge: fCentMethod = "V0C"; break; // VZERO charge
273 case kFMDRough: fCentMethod = "FMD"; break; // FMD scaled energy l
274 case kNTracks: fCentMethod = "TRK"; break; // Number of tracks
275 case kLTracks: fCentMethod = "TKL"; break; // Number of tracks
276 case kCL0: fCentMethod = "CL0"; break; //
277 case kCL1: fCentMethod = "CL1"; break; //
278 case kCND: fCentMethod = "CND"; break; //
279 case kNParticles: fCentMethod = "NPA"; break; // Neutral particles
280 case kNeutrons: fCentMethod = "ZNA"; break; // ZDC neutron amplitu
281 case kV0vsFMD: fCentMethod = "V0MvsFMD"; break; // VZERO versus FMD
282 case kV0vsNTracks: fCentMethod = "TKLvsVOM"; break; // Tracks versus VZERO
283 case kZEMvsZDC: fCentMethod = "ZEMvsZDC"; break; // ZDC
284 default: fCentMethod = "V0M"; break;
288 //____________________________________________________________________
290 AliFMDEventInspector::SetMinCentrality(Double_t minCent)
293 "*******************************************************\n"
294 "* Setting centrality cuts in this stage is deprecated *\n"
295 "*******************************************************");
298 //____________________________________________________________________
300 AliFMDEventInspector::SetMaxCentrality(Double_t maxCent)
303 "*******************************************************\n"
304 "* Setting centrality cuts in this stage is deprecated *\n"
305 "*******************************************************");
309 //____________________________________________________________________
311 AliFMDEventInspector::FetchHistograms(const TList* d,
315 TH1I*& hTriggers) const
318 // Fetch our histograms from the passed list
322 // hEventsTr On return, pointer to histogram, or null
323 // hEventsTrVtx On return, pointer to histogram, or null
324 // hTriggers On return, pointer to histogram, or null
327 // true on success, false otherwise
329 DGUARD(fDebug,3,"Fetch histograms in AliFMDEventInspector");
334 TList* dd = dynamic_cast<TList*>(d->FindObject(GetName()));
335 if (!dd) return kFALSE;
337 hEventsTr = dynamic_cast<TH1I*>(dd->FindObject("nEventsTr"));
338 hEventsTrVtx = dynamic_cast<TH1I*>(dd->FindObject("nEventsTrVtx"));
339 hEventsAcc = dynamic_cast<TH1I*>(dd->FindObject("nEventsAccepted"));
340 hTriggers = dynamic_cast<TH1I*>(dd->FindObject("triggers"));
345 !hTriggers) return kFALSE;
348 //____________________________________________________________________
350 AliFMDEventInspector::CacheConfiguredTriggerClasses(TList& cache,
351 const TList* classes,
352 AliOADBPhysicsSelection* o)
354 TIter nextClass(classes);
355 TObjString* trigClass = 0;
356 // Loop over all trigger classes. Trigger classes have the format
358 // class := positive_words SPACE(s) negative_words
366 while ((trigClass = static_cast<TObjString*>(nextClass()))) {
367 // Tokenize on space to get positive and negative parts
368 TString side = o->GetBeamSide(trigClass->String());
369 TObjArray* parts = trigClass->String().Tokenize(" ");
370 TObjString* part = 0;
371 TIter nextPart(parts);
372 while ((part = static_cast<TObjString*>(nextPart()))) {
373 // We only care about the positive ones
374 if (part->GetName()[0] != '+') continue;
375 part->String().Remove(0,1);
377 // Tokenize on a comma to get the words
378 TObjArray* words = part->String().Tokenize(",");
379 TObjString* word = 0;
380 TIter nextWord(words);
381 while ((word = static_cast<TObjString*>(nextWord()))) {
382 TNamed* store = new TNamed(word->String(), side);
384 DMSG(fDebug,3,"Caching %s trigger word %s",
385 store->GetTitle(), store->GetName());
393 //____________________________________________________________________
395 AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
398 // Initialize the object - this is called on the first seen event.
401 // vtxAxis Vertex axis in use
403 DGUARD(fDebug,1,"Initialize in AliFMDEventInspector");
405 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
407 // Get the input handler - should always be there
408 AliInputEventHandler* ih =
409 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
411 AliWarning("No input handler");
414 // Get the physics selection - should always be there
415 AliPhysicsSelection* ps =
416 static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
418 AliWarning("No physics selection");
421 // Get the configured triggers
422 AliOADBPhysicsSelection* oadb =
423 const_cast<AliOADBPhysicsSelection*>(ps->GetOADBPhysicsSelection());
425 AliWarning("No OADB physics selection object");
428 // Get the configured trigger words from the physics selection
429 const TList* collTriggClasses = ps->GetCollisionTriggerClasses();
430 const TList* bgTriggClasses = ps->GetBGTriggerClasses();
431 if (!collTriggClasses) {
432 AliWarning("No configured collision trigger classes");
435 if (!bgTriggClasses) {
436 AliWarning("No configured background trigger classes");
439 CacheConfiguredTriggerClasses(fCollWords, collTriggClasses, oadb);
440 CacheConfiguredTriggerClasses(fBgWords, bgTriggClasses, oadb);
446 if ((fMinCent < 0 && fMaxCent < 0) || fMaxCent <= fMinCent) {
447 // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
448 // ----- 92 number --------- ---- 1 ---
450 for (Int_t i = 0; i < 92; i++) limits[i] = -1.5 + i;
454 Int_t n = fMaxCent-fMinCent+2;
456 for (Int_t i = 0; i < n; i++) {
457 limits[i] = fMinCent + i - .5;
461 fVtxAxis.Set(vtxAxis.GetNbins(), vtxAxis.GetXmin(), vtxAxis.GetXmax());
463 fCentAxis = new TAxis(limits.GetSize()-1, limits.GetArray());
464 fHEventsTr = new TH1I("nEventsTr", "Number of events w/trigger",
465 4*vtxAxis.GetNbins(),
467 2*vtxAxis.GetXmax());
468 fHEventsTr->SetXTitle("v_{z} [cm]");
469 fHEventsTr->SetYTitle("# of events");
470 fHEventsTr->SetFillColor(kRed+1);
471 fHEventsTr->SetFillStyle(3001);
472 fHEventsTr->SetDirectory(0);
473 // fHEventsTr->Sumw2();
474 fList->Add(fHEventsTr);
476 fHEventsTrVtx = static_cast<TH1I*>(fHEventsTr->Clone("nEventsTrVtx"));
477 fHEventsTrVtx->SetTitle("Number of events w/trigger and vertex");
478 fHEventsTrVtx->SetFillColor(kBlue+1);
479 fHEventsTrVtx->SetDirectory(0);
480 // fHEventsTrVtx->Sumw2();
481 fList->Add(fHEventsTrVtx);
483 fHEventsAccepted = new TH1I("nEventsAccepted",
484 "Number of events w/trigger and vertex in range",
485 2*vtxAxis.GetNbins(),
487 2*vtxAxis.GetXmax());
488 fHEventsAccepted->SetXTitle("v_{z} [cm]");
489 fHEventsAccepted->SetYTitle("# of events");
490 fHEventsAccepted->SetFillColor(kGreen+1);
491 fHEventsAccepted->SetFillStyle(3001);
492 fHEventsAccepted->SetDirectory(0);
493 // fHEventsAccepted->Sumw2();
494 fList->Add(fHEventsAccepted);
496 fHEventsAcceptedXY = new TH2D("nEventsAcceptedXY",
497 "XY vertex w/trigger and Z vertex in range",
498 1000,-1,1,1000,-1,1);
500 fHEventsAcceptedXY->SetXTitle("v_{x} [cm]");
501 fHEventsAcceptedXY->SetYTitle("v_{y} [cm]");
502 fHEventsAcceptedXY->SetDirectory(0);
503 // fHEventsAccepted->Sumw2();
504 fList->Add(fHEventsAcceptedXY);
507 fHTriggers = new TH1I("triggers", "Triggers", kOffline+1, 0, kOffline+1);
508 fHTriggers->SetFillColor(kRed+1);
509 fHTriggers->SetFillStyle(3001);
510 fHTriggers->SetStats(0);
511 fHTriggers->SetDirectory(0);
513 fHTriggerCorr = new TH2I("triggerCorr", "Trigger correlation",
514 kOffline+1, 0, kOffline+1,
515 kOffline+1, 0, kOffline+1);
516 fHTriggerCorr->SetStats(0);
517 fHTriggerCorr->SetDirectory(0);
518 fHTriggerCorr->SetXTitle("Requirement");
519 fHTriggerCorr->SetYTitle("Companion");
521 Int_t binNum[] = { kInel +1,
534 const char* binLbl[] = { "INEL",
547 for (Int_t i = 0; i < kOffline+1; i++) {
548 fHTriggers->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
549 fHTriggerCorr->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
550 fHTriggerCorr->GetYaxis()->SetBinLabel(binNum[i], binLbl[i]);
552 fList->Add(fHTriggers);
553 fList->Add(fHTriggerCorr);
556 fHType = new TH1I("type", Form("Event type (cut: SPD mult>%d)",
557 fLowFluxCut), 2, -.5, 1.5);
558 fHType->SetFillColor(kRed+1);
559 fHType->SetFillStyle(3001);
561 fHType->SetDirectory(0);
562 fHType->GetXaxis()->SetBinLabel(1,"Low-flux");
563 fHType->GetXaxis()->SetBinLabel(2,"High-flux");
567 // This histogram disabled as it causes problems in the merge
568 fHWords = new TH1I("words", "Trigger words seen", 1, 0, 0);
569 fHWords->SetFillColor(kBlue+1);
570 fHWords->SetFillStyle(3001);
571 fHWords->SetStats(0);
572 fHWords->SetDirectory(0);
573 fHWords->SetBit(TH1::kCanRebin);
577 fHCent = new TH1F("cent", "Centrality", limits.GetSize()-1,limits.GetArray());
578 fHCent->SetFillColor(kBlue+1);
579 fHCent->SetFillStyle(3001);
581 fHCent->SetDirectory(0);
582 fHCent->SetXTitle("Centrality [%]");
583 fHCent->SetYTitle("Events");
586 fHCentVsQual = new TH2F("centVsQuality", "Quality vs Centrality",
587 5, 0, 5, limits.GetSize()-1, limits.GetArray());
588 fHCentVsQual->SetXTitle("Quality");
589 fHCentVsQual->SetYTitle("Centrality [%]");
590 fHCentVsQual->SetZTitle("Events");
591 fHCentVsQual->GetXaxis()->SetBinLabel(1, "OK");
592 fHCentVsQual->GetXaxis()->SetBinLabel(2, "Outside v_{z} cut");
593 fHCentVsQual->GetXaxis()->SetBinLabel(3, "V0 vs SPD outlier");
594 fHCentVsQual->GetXaxis()->SetBinLabel(4, "V0 vs TPC outlier");
595 fHCentVsQual->GetXaxis()->SetBinLabel(5, "V0 vs ZDC outlier");
596 fHCentVsQual->SetDirectory(0);
597 fList->Add(fHCentVsQual);
599 fHStatus = new TH1I("status", "Status", 7, 1, 8);
600 fHStatus->SetFillColor(kBlue+1);
601 fHStatus->SetFillStyle(3001);
602 fHStatus->SetStats(0);
603 fHStatus->SetDirectory(0);
604 TAxis* xAxis = fHStatus->GetXaxis();
605 xAxis->SetBinLabel(1, "OK");
606 xAxis->SetBinLabel(2, "No event");
607 xAxis->SetBinLabel(3, "No triggers");
608 xAxis->SetBinLabel(4, "No SPD");
609 xAxis->SetBinLabel(5, "No FMD");
610 xAxis->SetBinLabel(6, "No vertex");
611 xAxis->SetBinLabel(7, "Bad vertex");
612 fList->Add(fHStatus);
614 fHVtxStatus = new TH1I("vtxStatus","Vertex Status",
615 kNotVtxZ,kVtxOK,kNotVtxZ+1);
616 fHVtxStatus->SetFillColor(kGreen+1);
617 fHVtxStatus->SetFillStyle(3001);
618 fHVtxStatus->SetStats(0);
619 fHVtxStatus->SetDirectory(0);
620 xAxis = fHVtxStatus->GetXaxis();
621 xAxis->SetBinLabel(kVtxOK, "OK");
622 xAxis->SetBinLabel(kNoVtx, "None/bad status");
623 xAxis->SetBinLabel(kNoSPDVtx, "No SPD/bad status");
624 xAxis->SetBinLabel(kFewContrib, "N_{contrib} <= 0");
625 xAxis->SetBinLabel(kUncertain, Form("#delta z > %4.2f", fMaxVzErr));
626 xAxis->SetBinLabel(kNotVtxZ, "Not Z vertexer");
627 fList->Add(fHVtxStatus);
629 fHTrgStatus = new TH1I("trgStatus", "Trigger Status",
630 kOther, kNoTrgWords, kOther+1);
631 fHTrgStatus->SetFillColor(kMagenta+1);
632 fHTrgStatus->SetFillStyle(3001);
633 fHTrgStatus->SetStats(0);
634 fHTrgStatus->SetDirectory(0);
635 xAxis = fHTrgStatus->GetXaxis();
636 xAxis->SetBinLabel(kNoTrgWords, "No words");
637 xAxis->SetBinLabel(kPP2760Fast, "FAST in pp@#sqrt{s}=2.76TeV");
638 xAxis->SetBinLabel(kMUON, "Muon trigger");
639 xAxis->SetBinLabel(kTriggered, "Triggered");
640 xAxis->SetBinLabel(kMinBias, "CINT1 (V0A||V0C||FASTOR)");
641 xAxis->SetBinLabel(kMinBiasNoSPD, "CINT5 (V0A||V0C)");
642 xAxis->SetBinLabel(kV0AndTrg, "CINT7 (V0A&&V0C)");
643 xAxis->SetBinLabel(kHighMult, "N>>0");
644 xAxis->SetBinLabel(kCentral, "Central");
645 xAxis->SetBinLabel(kSemiCentral, "Semi-central");
646 xAxis->SetBinLabel(kDiffractive, "Diffractive");
647 xAxis->SetBinLabel(kUser, "User");
648 xAxis->SetBinLabel(kOther, "Other");
649 fList->Add(fHTrgStatus);
651 if (fUseDisplacedVertices) fDisplacedVertex.SetupForData(fList, "", false);
654 //____________________________________________________________________
656 AliFMDEventInspector::StoreInformation()
658 // Write TNamed objects to output list containing information about
659 // the running conditions
660 DGUARD(fDebug,2,"Store information from AliFMDEventInspector");
664 fList->Add(AliForwardUtil::MakeParameter("sys", fCollisionSystem));
665 fList->Add(AliForwardUtil::MakeParameter("sNN", fEnergy));
666 fList->Add(AliForwardUtil::MakeParameter("field", fField));
667 fList->Add(AliForwardUtil::MakeParameter("runNo", fRunNumber));
668 fList->Add(AliForwardUtil::MakeParameter("lowFlux", fLowFluxCut));
669 fList->Add(AliForwardUtil::MakeParameter("fpVtx",fUseFirstPhysicsVertex));
670 fList->Add(AliForwardUtil::MakeParameter("v0and",fUseV0AND));
671 fList->Add(AliForwardUtil::MakeParameter("nPileUp", fMinPileupContrib));
672 fList->Add(AliForwardUtil::MakeParameter("dPileup", fMinPileupDistance));
673 fList->Add(AliForwardUtil::MakeParameter("satellite", fUseDisplacedVertices));
674 fList->Add(AliForwardUtil::MakeParameter("alirootRev",
675 AliForwardUtil::AliROOTRevision()));
676 fList->Add(AliForwardUtil::MakeParameter("alirootBranch",
677 AliForwardUtil::AliROOTBranch()));
681 //____________________________________________________________________
683 AliFMDEventInspector::CreateOutputObjects(TList* dir)
686 // Define the output histograms. These are put in a sub list of the
687 // passed list. The histograms are merged before the parent task calls
688 // AliAnalysisTaskSE::Terminate
690 // dir Directory to add to
692 DGUARD(fDebug,1,"Define output from AliFMDEventInspector");
694 fList->SetName(GetName());
699 //____________________________________________________________________
701 AliFMDEventInspector::Process(const AliESDEvent* event,
714 // triggers On return, the triggers fired
715 // lowFlux On return, true if the event is considered a low-flux
716 // event (according to the setting of fLowFluxCut)
717 // ivz On return, the found vertex bin (1-based). A zero
718 // means outside of the defined vertex range
719 // vz On return, the z position of the interaction
720 // cent On return, the centrality - if not available < 0
723 // 0 (or kOk) on success, otherwise a bit mask of error codes
725 DGUARD(fDebug,1,"Process event in AliFMDEventInspector");
726 // --- Check that we have an event ---------------------------------
728 AliWarning("No ESD event found for input event");
733 // --- Process satellite event information is requested ------------
734 if (fUseDisplacedVertices) {
735 if (!fDisplacedVertex.Process(event))
736 AliWarning("Failed to process satellite event");
739 // --- Read trigger information from the ESD and store in AOD object
740 if (!ReadTriggers(*event, triggers, nClusters)) {
742 AliWarning("Failed to read triggers from ESD"); }
747 // --- Check if this is a high-flux event --------------------------
748 const AliMultiplicity* testmult = event->GetMultiplicity();
751 AliWarning("No central multiplicity object found"); }
754 lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
756 fHType->Fill(lowFlux ? 0 : 1);
758 // --- Get the interaction point -----------------------------------
759 Bool_t vzOk = ReadVertex(*event, ip);
760 fHEventsTr->Fill(ip.Z());
763 AliWarning("Failed to read vertex from ESD"); }
768 // --- Read centrality information
771 if (!ReadCentrality(*event, cent, qual)) {
773 AliWarning("Failed to get centrality");
775 // --- check centrality cut
777 if(fMinCent > -0.0001 && cent < fMinCent) return kNoEvent;
778 if(fMaxCent > -0.0001 && cent > fMaxCent) return kNoEvent;
780 if (qual == 0) fHCentVsQual->Fill(0., cent);
782 for (UShort_t i = 0; i < 4; i++)
783 if (qual & (1 << i)) fHCentVsQual->Fill(Double_t(i+1), cent);
787 fHEventsTrVtx->Fill(ip.Z());
789 // --- Get the vertex bin ------------------------------------------
790 ivz = fVtxAxis.FindBin(ip.Z());
791 if (ivz <= 0 || ivz > fVtxAxis.GetNbins()) {
793 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
794 ip.Z(), fVtxAxis.GetXmin(), fVtxAxis.GetXmax()));
800 fHEventsAccepted->Fill(ip.Z());
801 fHEventsAcceptedXY->Fill(ip.X(),ip.Y());
803 // --- Check the FMD ESD data --------------------------------------
804 if (!event->GetFMDData()) {
806 AliWarning("No FMD data found in ESD"); }
815 //____________________________________________________________________
817 AliFMDEventInspector::ReadCentrality(const AliESDEvent& esd,
819 UShort_t& qual) const
822 // Read centrality from event
826 // cent On return, the centrality or negative if not found
829 // False on error, true otherwise
831 DGUARD(fDebug,2,"Read the centrality in AliFMDEventInspector");
835 AliCentrality* centObj = const_cast<AliESDEvent&>(esd).GetCentrality();
837 cent = centObj->GetCentralityPercentile(fCentMethod);
838 qual = centObj->GetQuality();
841 if (qual > 0 && fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
842 cent = fDisplacedVertex.GetCentralityPercentile();
849 //____________________________________________________________________
851 AliFMDEventInspector::CheckpAExtraV0(const AliESDEvent& esd) const
853 if (fCollisionSystem != AliForwardUtil::kPPb) return true;
855 AliVVZERO* esdV0 = esd.GetVZEROData();
856 if ((esdV0->GetV0ADecision()!=1) || (esdV0->GetV0CDecision()!=1))
861 //____________________________________________________________________
863 AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
867 // Read the trigger information from the ESD event
871 // triggers On return, contains the trigger bits
874 // @c true on success, @c false otherwise
876 DGUARD(fDebug,2,"Read the triggers in AliFMDEventInspector");
879 // Get the analysis manager - should always be there
880 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
881 DMSG(fDebug,10,"Got analysis manager %p", am);
883 AliWarning("No analysis manager defined!");
887 // Get the input handler - should always be there
888 AliInputEventHandler* ih =
889 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
890 DMSG(fDebug,10,"Got input handler %p", ih);
892 AliWarning("No input handler");
896 // Check if this is a collision candidate (MB)
898 // Historic remark: Note, that we should use the value cached in the
899 // input handler rather than calling IsCollisionCandiate directly
900 // on the AliPhysicsSelection obejct. If we called the latter
901 // then the AliPhysicsSelection object would overcount by a factor
903 UInt_t trgMask = ih->IsEventSelected();
904 Bool_t offline = trgMask;
905 Bool_t fastonly = (trgMask & AliVEvent::kFastOnly);
906 TString trigStr = esd.GetFiredTriggerClasses();
908 if (trigStr.IsNull()) fHTrgStatus->Fill(kNoTrgWords);
909 if (fHWords) fHWords->Fill(trigStr.Data(), 1);
911 if(fUseDisplacedVertices) {
912 DMSG(fDebug,3,"Using displaced vertex stuff");
913 // if (TMath::Abs(fDisplacedVertex.GetVertexZ()) >= 999) offline = false;
914 if (fDisplacedVertex.IsSatellite())
915 triggers |= AliAODForwardMult::kSatellite;
918 if (CheckFastPartition(fastonly)) {
919 fHTrgStatus->Fill(kPP2760Fast);
923 if (offline && CheckCosmics(trigStr)) {
924 fHTrgStatus->Fill(kMUON);
927 if (offline) fHTrgStatus->Fill(kTriggered);
929 if (trgMask & AliVEvent::kMB) f += fHTrgStatus->Fill(kMinBias);
930 if (trgMask & AliVEvent::kCINT5) f += fHTrgStatus->Fill(kMinBiasNoSPD);
931 if (trgMask & AliVEvent::kINT7) f += fHTrgStatus->Fill(kV0AndTrg);
932 if (trgMask & AliVEvent::kHighMult) f += fHTrgStatus->Fill(kHighMult);
933 if (trgMask & AliVEvent::kCentral) f += fHTrgStatus->Fill(kCentral);
934 if (trgMask & AliVEvent::kSemiCentral) f += fHTrgStatus->Fill(kSemiCentral);
935 if (trgMask & AliVEvent::kDG5) f += fHTrgStatus->Fill(kDiffractive);
936 if (trgMask & AliVEvent::kUserDefined) f += fHTrgStatus->Fill(kUser);
937 if (f <= 0) fHTrgStatus->Fill(kOther);
939 // if (!CheckpAExtraV0(esd)) offline = false;
941 DMSG(fDebug,2,"Event is %striggered by off-line", offline ? "" : "NOT ");
944 triggers |= AliAODForwardMult::kOffline;
945 triggers |= AliAODForwardMult::kInel;
946 CheckINELGT0(esd, nClusters, triggers);
949 CheckNSD(esd,triggers);
950 CheckPileup(esd, triggers);
951 CheckEmpty(trigStr, triggers);
952 // if (CheckPileup(esd, triggers)) fHTriggers->Fill(kPileUp+.5);
953 // if (CheckEmpty(trigStr, triggers)) fHTriggers->Fill(kEmpty+.5);
955 CheckWords(esd, triggers);
957 #define TEST_TRIG_BIN(RET,BIN,TRIGGERS) \
958 do { switch (BIN) { \
959 case kInel: RET = triggers & AliAODForwardMult::kInel; break; \
960 case kInelGt0: RET = triggers & AliAODForwardMult::kInelGt0; break; \
961 case kNSD: RET = triggers & AliAODForwardMult::kNSD; break; \
962 case kV0AND: RET = triggers & AliAODForwardMult::kV0AND; break; \
963 case kEmpty: RET = triggers & AliAODForwardMult::kEmpty; break; \
964 case kA: RET = triggers & AliAODForwardMult::kA; break; \
965 case kB: RET = triggers & AliAODForwardMult::kB; break; \
966 case kC: RET = triggers & AliAODForwardMult::kC; break; \
967 case kE: RET = triggers & AliAODForwardMult::kE; break; \
968 case kPileUp: RET = triggers & AliAODForwardMult::kPileUp; break; \
969 case kMCNSD: RET = triggers & AliAODForwardMult::kMCNSD; break; \
970 case kSatellite:RET = triggers & AliAODForwardMult::kSatellite; break; \
971 case kOffline: RET = triggers & AliAODForwardMult::kOffline; break; \
972 default: RET = false; } } while(false)
975 AliWarning("Histogram of triggers not defined - has init been called");
979 for (Int_t i = 0; i < kOffline+1; i++) {
981 TEST_TRIG_BIN(hasX, i, triggers);
983 fHTriggers->Fill(i+.5);
984 for (Int_t j = 0; j < kOffline+1; j++) {
986 TEST_TRIG_BIN(hasY, j, triggers);
989 fHTriggerCorr->Fill(i+.5, j+.5);
995 //____________________________________________________________________
997 AliFMDEventInspector::CheckFastPartition(bool fastonly) const
999 // For the 2.76 TeV p+p run, the FMD ran in the slow partition
1000 // so it received no triggers from the fast partition. Therefore
1001 // the fast triggers are removed here but not for MC where all
1002 // triggers are fast.
1003 if (TMath::Abs(fEnergy - 2750.) > 20) return false;
1004 if (fCollisionSystem != AliForwardUtil::kPP) return false;
1006 DMSG(fDebug,1,"Fast trigger in pp @ sqrt(s)=2.76TeV removed");
1011 //____________________________________________________________________
1013 AliFMDEventInspector::CheckCosmics(const TString& trigStr) const
1015 // MUON triggers are not strictly minimum bias (MB) so they are
1017 if(trigStr.Contains("CMUS1")) {
1018 DMSG(fDebug,1,"Cosmic trigger ins't min-bias, removed");
1024 //____________________________________________________________________
1026 AliFMDEventInspector::CheckINELGT0(const AliESDEvent& esd,
1027 UShort_t& nClusters,
1028 UInt_t& triggers) const
1032 // If this is inel, see if we have a tracklet
1033 const AliMultiplicity* spdmult = esd.GetMultiplicity();
1035 AliWarning("No SPD multiplicity");
1039 // Check if we have one or more tracklets
1040 // in the range -1 < eta < 1 to set the INEL>0
1043 // Also count tracklets as a single cluster
1044 Int_t n = spdmult->GetNumberOfTracklets();
1045 for (Int_t j = 0; j < n; j++) {
1046 if(TMath::Abs(spdmult->GetEta(j)) < 1) {
1047 triggers |= AliAODForwardMult::kInelGt0;
1051 n = spdmult->GetNumberOfSingleClusters();
1052 for (Int_t j = 0; j < n; j++) {
1053 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
1054 if (TMath::Abs(eta) < 1) nClusters++;
1056 if (nClusters > 0) triggers |= AliAODForwardMult::kNClusterGt0;
1058 return triggers & AliAODForwardMult::kNClusterGt0;
1061 //____________________________________________________________________
1063 AliFMDEventInspector::CheckNSD(const AliESDEvent& esd, UInt_t& triggers) const
1065 // Analyse some trigger stuff
1066 AliTriggerAnalysis ta;
1067 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kV0AND)) {
1068 triggers |= AliAODForwardMult::kV0AND;
1070 triggers |= AliAODForwardMult::kNSD;
1072 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kNSD1))
1073 triggers |= AliAODForwardMult::kNSD;
1074 return triggers & AliAODForwardMult::kNSD;
1076 //____________________________________________________________________
1078 AliFMDEventInspector::CheckPileup(const AliESDEvent& esd,
1079 UInt_t& triggers) const
1081 // Check for multiple vertices (pile-up) with at least 3
1082 // contributors and at least 0.8cm from the primary vertex
1083 if(fCollisionSystem != AliForwardUtil::kPP) return false;
1085 Bool_t pileup = esd.IsPileupFromSPD(fMinPileupContrib,fMinPileupDistance);
1086 if (pileup) triggers |= AliAODForwardMult::kPileUp;
1090 //____________________________________________________________________
1092 AliFMDEventInspector::CheckEmpty(const TString& trigStr, UInt_t& triggers) const
1094 if (trigStr.Contains("CBEAMB-ABCE-NOPF-ALL")) {
1095 triggers |= AliAODForwardMult::kEmpty;
1100 //____________________________________________________________________
1102 AliFMDEventInspector::CheckWords(const AliESDEvent& esd, UInt_t& triggers) const
1105 TIter nextColl(&fCollWords);
1106 while ((word = nextColl())) {
1107 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1108 word->GetTitle(), word->GetName());
1109 if (!esd.IsTriggerClassFired(word->GetName())) continue;
1111 TString beamSide = word->GetTitle();
1112 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
1114 if (!beamSide.EqualTo("B")) continue;
1115 triggers |= AliAODForwardMult::kB;
1116 break; // No more to do here
1118 TIter nextBg(&fBgWords);
1119 UInt_t all = (AliAODForwardMult::kA |
1120 AliAODForwardMult::kC |
1121 AliAODForwardMult::kE);
1122 while ((word = nextBg())) {
1123 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1124 word->GetTitle(), word->GetName());
1125 if (!esd.IsTriggerClassFired(word->GetName())) continue;
1127 TString beamSide = word->GetTitle();
1128 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
1130 if (beamSide.Contains("A")) triggers |= AliAODForwardMult::kA;
1131 if (beamSide.Contains("C")) triggers |= AliAODForwardMult::kC;
1132 if (beamSide.Contains("E")) triggers |= AliAODForwardMult::kE;
1134 if ((triggers & all) == all) break; // No more to do
1140 //____________________________________________________________________
1142 AliFMDEventInspector::ReadVertex(const AliESDEvent& esd, TVector3& ip)
1145 // Read the vertex information from the ESD event
1149 // vz On return, the vertex Z position
1152 // @c true on success, @c false otherwise
1154 DGUARD(fDebug,2,"Read the vertex in AliFMDEventInspector");
1155 ip.SetXYZ(1024, 1024, 0);
1157 EVtxStatus s = kNoVtx;
1158 if (fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
1160 ip.SetZ(fDisplacedVertex.GetVertexZ());
1162 else if (fUseFirstPhysicsVertex)
1163 s = CheckPWGUDVertex(esd, ip);
1164 else if (fUsepA2012Vertex)
1165 s = CheckpA2012Vertex(esd,ip);
1167 s = CheckVertex(esd, ip);
1169 fHVtxStatus->Fill(s);
1174 //____________________________________________________________________
1175 AliFMDEventInspector::EVtxStatus
1176 AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
1179 // This is the code used by the 1st physics people
1180 const AliESDVertex* vertex = esd.GetPrimaryVertex();
1181 if (!vertex || !vertex->GetStatus()) {
1182 DMSG(fDebug,2,"No primary vertex (%p) or bad status %d",
1183 vertex, (vertex ? vertex->GetStatus() : -1));
1186 const AliESDVertex* vertexSPD = esd.GetPrimaryVertexSPD();
1187 if (!vertexSPD || !vertexSPD->GetStatus()) {
1188 DMSG(fDebug,2,"No primary SPD vertex (%p) or bad status %d",
1189 vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1));
1193 // if vertex is from SPD vertexZ, require more stringent cuts
1194 if (vertex->IsFromVertexerZ()) {
1195 if (vertex->GetDispersion() > fMaxVzErr ||
1196 vertex->GetZRes() > 1.25 * fMaxVzErr) {
1197 DMSG(fDebug,2,"Dispersion %f > %f or resolution %f > %f",
1198 vertex->GetDispersion(), fMaxVzErr,
1199 vertex->GetZRes(), 1.25 * fMaxVzErr);
1203 ip.SetZ(vertex->GetZ());
1205 if(!vertex->IsFromVertexerZ()) {
1206 ip.SetX(vertex->GetX());
1207 ip.SetY(vertex->GetY());
1211 //____________________________________________________________________
1212 AliFMDEventInspector::EVtxStatus
1213 AliFMDEventInspector::CheckpA2012Vertex(const AliESDEvent& esd,
1216 const AliESDVertex *vertex = esd.GetPrimaryVertexSPD();
1217 if (!vertex) return kNoSPDVtx;
1218 if (vertex->GetNContributors() <= 0) return kFewContrib;
1220 TString vtxTyp = vertex->GetTitle();
1221 if (vtxTyp.Contains("vertexer: Z")) return kNotVtxZ;
1223 if (vertex->GetDispersion() >= 0.04 || vertex->GetZRes()>=0.25)
1226 ip.SetX(vertex->GetX());
1227 ip.SetY(vertex->GetY());
1228 ip.SetZ(vertex->GetZ());
1233 //____________________________________________________________________
1234 AliFMDEventInspector::EVtxStatus
1235 AliFMDEventInspector::CheckVertex(const AliESDEvent& esd,
1238 // Use standard SPD vertex (perhaps preferable for Pb+Pb)
1240 const AliESDVertex* vertex = esd.GetPrimaryVertexSPD();
1243 AliWarning("No SPD vertex found in ESD"); }
1247 // #if 0 // Check disabled - seem to kill a lot of PbPb events
1248 // Check that enough tracklets contributed
1249 if(vertex->GetNContributors() <= 0) {
1250 DMSG(fDebug,2,"Number of contributors to vertex is %d<=0",
1251 vertex->GetNContributors());
1257 // Check that the uncertainty isn't too large
1258 if (vertex->GetZRes() > fMaxVzErr) {
1259 DMSG(fDebug,2,"Uncertaintity in Z of vertex is too large %f > %f",
1260 vertex->GetZRes(), fMaxVzErr);
1264 // Get the z coordiante
1265 ip.SetZ(vertex->GetZ());
1266 const AliESDVertex* vertexXY = esd.GetPrimaryVertex();
1269 if(!vertexXY->IsFromVertexerZ()) {
1270 ip.SetX(vertexXY->GetX());
1271 ip.SetY(vertexXY->GetY());
1276 //____________________________________________________________________
1278 AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
1281 // Read the collision system, collision energy, and L3 field setting
1285 // esd ESD to get information from
1288 // true on success, false
1290 // AliInfo(Form("Parameters from 1st ESD event: cms=%s, sNN=%f, field=%f",
1291 // esd->GetBeamType(), 2*esd->GetBeamEnergy(),
1292 // esd->GetMagneticField()));
1293 DGUARD(fDebug,2,"Read the run details in AliFMDEventInspector");
1294 const char* sys = esd->GetBeamType();
1295 Float_t cms = 2 * esd->GetBeamEnergy();
1296 Float_t fld = esd->GetMagneticField();
1297 fCollisionSystem = AliForwardUtil::ParseCollisionSystem(sys);
1298 fEnergy = AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,
1300 fField = AliForwardUtil::ParseMagneticField(fld);
1301 fRunNumber = esd->GetRunNumber();
1303 if (fCollisionSystem == AliForwardUtil::kUnknown) {
1304 AliWarningF("Unknown collision system: %s - please check", sys);
1308 AliWarningF("Unknown CMS energy: %f (%d) - please check", cms, fEnergy);
1311 if (TMath::Abs(fField) > 10) {
1312 AliWarningF("Unknown L3 field setting: %f (%d) - please check", fld,fField);
1320 //____________________________________________________________________
1322 AliFMDEventInspector::CodeString(UInt_t code)
1326 if (code & kNoEvent) s.Append("NOEVENT ");
1327 if (code & kNoTriggers) s.Append("NOTRIGGERS ");
1328 if (code & kNoSPD) s.Append("NOSPD ");
1329 if (code & kNoFMD) s.Append("NOFMD ");
1330 if (code & kNoVertex) s.Append("NOVERTEX ");
1331 if (code & kBadVertex) s.Append("BADVERTEX ");
1334 //____________________________________________________________________
1336 AliFMDEventInspector::Print(Option_t*) const
1339 // Print information
1343 char ind[gROOT->GetDirLevel()+1];
1344 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
1345 ind[gROOT->GetDirLevel()] = '\0';
1346 TString sNN(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
1347 sNN.Strip(TString::kBoth, '0');
1348 sNN.ReplaceAll("GeV", " GeV");
1349 TString field(AliForwardUtil::MagneticFieldString(fField));
1350 field.ReplaceAll("p", "+");
1351 field.ReplaceAll("m", "-");
1352 field.ReplaceAll("kG", " kG");
1354 std::cout << std::boolalpha
1355 << ind << ClassName() << ": " << GetName() << '\n'
1356 << ind << " Vertex bins: " << fVtxAxis.GetNbins() << '\n'
1357 << ind << " Vertex range: [" << fVtxAxis.GetXmin()
1358 << "," << fVtxAxis.GetXmax() << "]\n"
1359 << ind << " Low flux cut: " << fLowFluxCut << '\n'
1360 << ind << " Max(delta v_z): " << fMaxVzErr << " cm\n"
1361 << ind << " Min(nContrib_pileup): " << fMinPileupContrib << '\n'
1362 << ind << " Min(v-pileup): " << fMinPileupDistance << '\n'
1363 << ind << " System: "
1364 << AliForwardUtil::CollisionSystemString(fCollisionSystem) << '\n'
1365 << ind << " CMS energy per nucleon: " << sNN << '\n'
1366 << ind << " Field: " << field << '\n'
1367 << ind << " Satellite events: " << fUseDisplacedVertices<<'\n'
1368 << ind << " Centrality method: " << fCentMethod << '\n'
1369 << std::noboolalpha;
1370 if (!fCentAxis) { std::cout << std::flush; return; }
1371 Int_t nBin = fCentAxis->GetNbins();
1372 std::cout << ind << " Centrality axis: " << nBin << " bins"
1374 for (Int_t i = 0; i < nBin; i++) {
1375 if ((i % 10) == 0) std::cout << '\n' << ind << " ";
1376 std::cout << std::setw(5) << fCentAxis->GetBinLowEdge(i+1) << '-';
1378 std::cout << std::setw(5) << fCentAxis->GetBinUpEdge(nBin) << std::endl;