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),
65 fCollisionSystem(kUnknown),
69 fUseFirstPhysicsVertex(false),
72 fMinPileupDistance(0.8),
73 fUseDisplacedVertices(false),
80 fUsepA2012Vertex(false)
85 DGUARD(fDebug,1,"Default CTOR of AliFMDEventInspector");
88 //____________________________________________________________________
89 AliFMDEventInspector::AliFMDEventInspector(const char* name)
90 : TNamed(fgkFolderName, name),
94 fHEventsAcceptedXY(0),
107 fCollisionSystem(kUnknown),
111 fUseFirstPhysicsVertex(false),
113 fMinPileupContrib(3),
114 fMinPileupDistance(0.8),
115 fUseDisplacedVertices(false),
122 fUsepA2012Vertex(false)
128 // name Name of object
130 DGUARD(fDebug,1,"Named CTOR of AliFMDEventInspector: %s", name);
133 //____________________________________________________________________
134 AliFMDEventInspector::AliFMDEventInspector(const AliFMDEventInspector& o)
136 fHEventsTr(o.fHEventsTr),
137 fHEventsTrVtx(o.fHEventsTrVtx),
138 fHEventsAccepted(o.fHEventsAccepted),
139 fHEventsAcceptedXY(o.fHEventsAcceptedXY),
140 fHTriggers(o.fHTriggers),
141 fHTriggerCorr(o.fHTriggerCorr),
145 fHCentVsQual(o.fHCentVsQual),
146 fHStatus(o.fHStatus),
147 fLowFluxCut(o.fLowFluxCut),
148 fMaxVzErr(o.fMaxVzErr),
152 fCollisionSystem(o.fCollisionSystem),
155 fVtxAxis(o.fVtxAxis),
156 fUseFirstPhysicsVertex(o.fUseFirstPhysicsVertex),
157 fUseV0AND(o.fUseV0AND),
158 fMinPileupContrib(o.fMinPileupContrib),
159 fMinPileupDistance(o.fMinPileupDistance),
160 fUseDisplacedVertices(o.fUseDisplacedVertices),
161 fDisplacedVertex(o.fDisplacedVertex),
164 fCentMethod(o.fCentMethod),
165 fminCent(o.fminCent),
166 fmaxCent(o.fmaxCent),
167 fUsepA2012Vertex(o.fUsepA2012Vertex)
173 // o Object to copy from
175 DGUARD(fDebug,1,"Copy CTOR of AliFMDEventInspector");
178 //____________________________________________________________________
179 AliFMDEventInspector::~AliFMDEventInspector()
184 DGUARD(fDebug,1,"DTOR of AliFMDEventInspector");
185 // if (fList) delete fList;
187 //____________________________________________________________________
188 AliFMDEventInspector&
189 AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
192 // Assignement operator
195 // o Object to assign from
198 // Reference to this object
200 DGUARD(fDebug,3,"Assignment of AliFMDEventInspector");
201 if (&o == this) return *this;
202 TNamed::operator=(o);
203 fHEventsTr = o.fHEventsTr;
204 fHEventsTrVtx = o.fHEventsTrVtx;
205 fHEventsAccepted = o.fHEventsAccepted;
206 fHEventsAcceptedXY = o.fHEventsAcceptedXY;
207 fHTriggers = o.fHTriggers;
208 fHTriggerCorr = o.fHTriggerCorr;
212 fHCentVsQual = o.fHCentVsQual;
213 fHStatus = o.fHStatus;
214 fLowFluxCut = o.fLowFluxCut;
215 fMaxVzErr = o.fMaxVzErr;
217 fList = (o.fList ? new TList : 0);
220 fCollisionSystem = o.fCollisionSystem;
221 fVtxAxis.Set(o.fVtxAxis.GetNbins(), o.fVtxAxis.GetXmin(),
222 o.fVtxAxis.GetXmax());
224 fUseFirstPhysicsVertex = o.fUseFirstPhysicsVertex;
225 fUseV0AND = o.fUseV0AND;
226 fMinPileupContrib = o.fMinPileupContrib;
227 fMinPileupDistance = o.fMinPileupDistance;
228 fUseDisplacedVertices = o.fUseDisplacedVertices;
229 fDisplacedVertex = o.fDisplacedVertex;
230 fCentMethod = o.fCentMethod;
231 fminCent = o.fminCent;
232 fmaxCent = o.fmaxCent;
233 fUsepA2012Vertex =o.fUsepA2012Vertex;
236 fList->SetName(GetName());
237 if (fHEventsTr) fList->Add(fHEventsTr);
238 if (fHEventsTrVtx) fList->Add(fHEventsTrVtx);
239 if (fHTriggers) fList->Add(fHTriggers);
240 if (fHTriggerCorr) fList->Add(fHTriggerCorr);
241 if (fHType) fList->Add(fHType);
242 if (fHWords) fList->Add(fHWords);
243 if (fHCent) fList->Add(fHCent);
244 if (fHCentVsQual) fList->Add(fHCentVsQual);
245 if (fHStatus) fList->Add(fHStatus);
250 //____________________________________________________________________
252 AliFMDEventInspector::SetCentralityMethod(ECentMethod m)
255 case kV0Multiplicity: fCentMethod = "VOM"; break; // VZERO multiplicity
256 case kV0Amplitude: fCentMethod = "V0A"; break; // VZERO amplitude
257 case kV0Charge: fCentMethod = "V0C"; break; // VZERO charge
258 case kFMDRough: fCentMethod = "FMD"; break; // FMD scaled energy l
259 case kNTracks: fCentMethod = "TRK"; break; // Number of tracks
260 case kLTracks: fCentMethod = "TKL"; break; // Number of tracks
261 case kCL0: fCentMethod = "CL0"; break; //
262 case kCL1: fCentMethod = "CL1"; break; //
263 case kCND: fCentMethod = "CND"; break; //
264 case kNParticles: fCentMethod = "NPA"; break; // Neutral particles
265 case kNeutrons: fCentMethod = "ZNA"; break; // ZDC neutron amplitu
266 case kV0vsFMD: fCentMethod = "V0MvsFMD"; break; // VZERO versus FMD
267 case kV0vsNTracks: fCentMethod = "TKLvsVOM"; break; // Tracks versus VZERO
268 case kZEMvsZDC: fCentMethod = "ZEMvsZDC"; break; // ZDC
269 default: fCentMethod = "V0M"; break;
273 //____________________________________________________________________
275 AliFMDEventInspector::FetchHistograms(const TList* d,
279 TH1I*& hTriggers) const
282 // Fetch our histograms from the passed list
286 // hEventsTr On return, pointer to histogram, or null
287 // hEventsTrVtx On return, pointer to histogram, or null
288 // hTriggers On return, pointer to histogram, or null
291 // true on success, false otherwise
293 DGUARD(fDebug,3,"Fetch histograms in AliFMDEventInspector");
298 TList* dd = dynamic_cast<TList*>(d->FindObject(GetName()));
299 if (!dd) return kFALSE;
301 hEventsTr = dynamic_cast<TH1I*>(dd->FindObject("nEventsTr"));
302 hEventsTrVtx = dynamic_cast<TH1I*>(dd->FindObject("nEventsTrVtx"));
303 hEventsAcc = dynamic_cast<TH1I*>(dd->FindObject("nEventsAccepted"));
304 hTriggers = dynamic_cast<TH1I*>(dd->FindObject("triggers"));
309 !hTriggers) return kFALSE;
312 //____________________________________________________________________
314 AliFMDEventInspector::CacheConfiguredTriggerClasses(TList& cache,
315 const TList* classes,
316 AliOADBPhysicsSelection* o)
318 TIter nextClass(classes);
319 TObjString* trigClass = 0;
320 // Loop over all trigger classes. Trigger classes have the format
322 // class := positive_words SPACE(s) negative_words
330 while ((trigClass = static_cast<TObjString*>(nextClass()))) {
331 // Tokenize on space to get positive and negative parts
332 TString side = o->GetBeamSide(trigClass->String());
333 TObjArray* parts = trigClass->String().Tokenize(" ");
334 TObjString* part = 0;
335 TIter nextPart(parts);
336 while ((part = static_cast<TObjString*>(nextPart()))) {
337 // We only care about the positive ones
338 if (part->GetName()[0] != '+') continue;
339 part->String().Remove(0,1);
341 // Tokenize on a comma to get the words
342 TObjArray* words = part->String().Tokenize(",");
343 TObjString* word = 0;
344 TIter nextWord(words);
345 while ((word = static_cast<TObjString*>(nextWord()))) {
346 TNamed* store = new TNamed(word->String(), side);
348 DMSG(fDebug,3,"Caching %s trigger word %s",
349 store->GetTitle(), store->GetName());
357 //____________________________________________________________________
359 AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
362 // Initialize the object - this is called on the first seen event.
365 // vtxAxis Vertex axis in use
367 DGUARD(fDebug,1,"Initialize in AliFMDEventInspector");
369 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
371 // Get the input handler - should always be there
372 AliInputEventHandler* ih =
373 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
375 AliWarning("No input handler");
378 // Get the physics selection - should always be there
379 AliPhysicsSelection* ps =
380 static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
382 AliWarning("No physics selection");
385 // Get the configured triggers
386 AliOADBPhysicsSelection* oadb =
387 const_cast<AliOADBPhysicsSelection*>(ps->GetOADBPhysicsSelection());
389 AliWarning("No OADB physics selection object");
392 // Get the configured trigger words from the physics selection
393 const TList* collTriggClasses = ps->GetCollisionTriggerClasses();
394 const TList* bgTriggClasses = ps->GetBGTriggerClasses();
395 if (!collTriggClasses) {
396 AliWarning("No configured collision trigger classes");
399 if (!bgTriggClasses) {
400 AliWarning("No configured background trigger classes");
403 CacheConfiguredTriggerClasses(fCollWords, collTriggClasses, oadb);
404 CacheConfiguredTriggerClasses(fBgWords, bgTriggClasses, oadb);
409 // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
410 // ----- 92 number --------- ---- 1 ---
412 for (Int_t i = 0; i < 92; i++) limits[i] = -1.5 + i;
415 fVtxAxis.Set(vtxAxis.GetNbins(), vtxAxis.GetXmin(), vtxAxis.GetXmax());
417 fCentAxis = new TAxis(limits.GetSize()-1, limits.GetArray());
418 fHEventsTr = new TH1I("nEventsTr", "Number of events w/trigger",
419 4*vtxAxis.GetNbins(),
421 2*vtxAxis.GetXmax());
422 fHEventsTr->SetXTitle("v_{z} [cm]");
423 fHEventsTr->SetYTitle("# of events");
424 fHEventsTr->SetFillColor(kRed+1);
425 fHEventsTr->SetFillStyle(3001);
426 fHEventsTr->SetDirectory(0);
427 // fHEventsTr->Sumw2();
428 fList->Add(fHEventsTr);
430 fHEventsTrVtx = static_cast<TH1I*>(fHEventsTr->Clone("nEventsTrVtx"));
431 fHEventsTrVtx->SetTitle("Number of events w/trigger and vertex");
432 fHEventsTrVtx->SetFillColor(kBlue+1);
433 fHEventsTrVtx->SetDirectory(0);
434 // fHEventsTrVtx->Sumw2();
435 fList->Add(fHEventsTrVtx);
437 fHEventsAccepted = new TH1I("nEventsAccepted",
438 "Number of events w/trigger and vertex in range",
439 2*vtxAxis.GetNbins(),
441 2*vtxAxis.GetXmax());
442 fHEventsAccepted->SetXTitle("v_{z} [cm]");
443 fHEventsAccepted->SetYTitle("# of events");
444 fHEventsAccepted->SetFillColor(kGreen+1);
445 fHEventsAccepted->SetFillStyle(3001);
446 fHEventsAccepted->SetDirectory(0);
447 // fHEventsAccepted->Sumw2();
448 fList->Add(fHEventsAccepted);
450 fHEventsAcceptedXY = new TH2D("nEventsAcceptedXY",
451 "XY vertex w/trigger and Z vertex in range",
452 1000,-1,1,1000,-1,1);
454 fHEventsAcceptedXY->SetXTitle("v_{x} [cm]");
455 fHEventsAcceptedXY->SetYTitle("v_{y} [cm]");
456 fHEventsAcceptedXY->SetDirectory(0);
457 // fHEventsAccepted->Sumw2();
458 fList->Add(fHEventsAcceptedXY);
461 fHTriggers = new TH1I("triggers", "Triggers", kOffline+1, 0, kOffline+1);
462 fHTriggers->SetFillColor(kRed+1);
463 fHTriggers->SetFillStyle(3001);
464 fHTriggers->SetStats(0);
465 fHTriggers->SetDirectory(0);
467 fHTriggerCorr = new TH2I("triggerCorr", "Trigger correlation",
468 kOffline+1, 0, kOffline+1,
469 kOffline+1, 0, kOffline+1);
470 fHTriggerCorr->SetStats(0);
471 fHTriggerCorr->SetDirectory(0);
472 fHTriggerCorr->SetXTitle("Requirement");
473 fHTriggerCorr->SetYTitle("Companion");
475 Int_t binNum[] = { kInel +1,
487 const char* binLbl[] = { "INEL",
499 for (Int_t i = 0; i < kOffline+1; i++) {
500 fHTriggers->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
501 fHTriggerCorr->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
502 fHTriggerCorr->GetYaxis()->SetBinLabel(binNum[i], binLbl[i]);
504 fList->Add(fHTriggers);
505 fList->Add(fHTriggerCorr);
508 fHType = new TH1I("type", Form("Event type (cut: SPD mult>%d)",
509 fLowFluxCut), 2, -.5, 1.5);
510 fHType->SetFillColor(kRed+1);
511 fHType->SetFillStyle(3001);
513 fHType->SetDirectory(0);
514 fHType->GetXaxis()->SetBinLabel(1,"Low-flux");
515 fHType->GetXaxis()->SetBinLabel(2,"High-flux");
519 // This histogram disabled as it causes problems in the merge
520 fHWords = new TH1I("words", "Trigger words seen", 1, 0, 0);
521 fHWords->SetFillColor(kBlue+1);
522 fHWords->SetFillStyle(3001);
523 fHWords->SetStats(0);
524 fHWords->SetDirectory(0);
525 fHWords->SetBit(TH1::kCanRebin);
529 fHCent = new TH1F("cent", "Centrality", limits.GetSize()-1,limits.GetArray());
530 fHCent->SetFillColor(kBlue+1);
531 fHCent->SetFillStyle(3001);
533 fHCent->SetDirectory(0);
534 fHCent->SetXTitle("Centrality [%]");
535 fHCent->SetYTitle("Events");
538 fHCentVsQual = new TH2F("centVsQuality", "Quality vs Centrality",
539 5, 0, 5, limits.GetSize()-1, limits.GetArray());
540 fHCentVsQual->SetXTitle("Quality");
541 fHCentVsQual->SetYTitle("Centrality [%]");
542 fHCentVsQual->SetZTitle("Events");
543 fHCentVsQual->GetXaxis()->SetBinLabel(1, "OK");
544 fHCentVsQual->GetXaxis()->SetBinLabel(2, "Outside v_{z} cut");
545 fHCentVsQual->GetXaxis()->SetBinLabel(3, "V0 vs SPD outlier");
546 fHCentVsQual->GetXaxis()->SetBinLabel(4, "V0 vs TPC outlier");
547 fHCentVsQual->GetXaxis()->SetBinLabel(5, "V0 vs ZDC outlier");
548 fHCentVsQual->SetDirectory(0);
549 fList->Add(fHCentVsQual);
551 fHStatus = new TH1I("status", "Status", 7, 1, 8);
552 fHStatus->SetFillColor(kRed+1);
553 fHStatus->SetFillStyle(3001);
554 fHStatus->SetStats(0);
555 fHStatus->SetDirectory(0);
556 fHStatus->GetXaxis()->SetBinLabel(1, "OK");
557 fHStatus->GetXaxis()->SetBinLabel(2, "No event");
558 fHStatus->GetXaxis()->SetBinLabel(3, "No triggers");
559 fHStatus->GetXaxis()->SetBinLabel(4, "No SPD");
560 fHStatus->GetXaxis()->SetBinLabel(5, "No FMD");
561 fHStatus->GetXaxis()->SetBinLabel(6, "No vertex");
562 fHStatus->GetXaxis()->SetBinLabel(7, "Bad vertex");
563 fList->Add(fHStatus);
566 //____________________________________________________________________
568 AliFMDEventInspector::StoreInformation(Int_t runNo)
570 // Write TNamed objects to output list containing information about
571 // the running conditions
572 DGUARD(fDebug,2,"Store information from AliFMDEventInspector");
576 fList->Add(AliForwardUtil::MakeParameter("sys", fCollisionSystem));
577 fList->Add(AliForwardUtil::MakeParameter("sNN", fEnergy));
578 fList->Add(AliForwardUtil::MakeParameter("field", fField));
579 fList->Add(AliForwardUtil::MakeParameter("runNo", runNo));
580 fList->Add(AliForwardUtil::MakeParameter("lowFlux", fLowFluxCut));
581 fList->Add(AliForwardUtil::MakeParameter("fpVtx",fUseFirstPhysicsVertex));
582 fList->Add(AliForwardUtil::MakeParameter("v0and",fUseV0AND));
583 fList->Add(AliForwardUtil::MakeParameter("nPileUp", fMinPileupContrib));
584 fList->Add(AliForwardUtil::MakeParameter("dPileup", fMinPileupDistance));
585 fList->Add(AliForwardUtil::MakeParameter("alirootRev",
586 AliForwardUtil::AliROOTRevision()));
587 fList->Add(AliForwardUtil::MakeParameter("alirootBranch",
588 AliForwardUtil::AliROOTBranch()));
592 //____________________________________________________________________
594 AliFMDEventInspector::CreateOutputObjects(TList* dir)
597 // Define the output histograms. These are put in a sub list of the
598 // passed list. The histograms are merged before the parent task calls
599 // AliAnalysisTaskSE::Terminate
601 // dir Directory to add to
603 DGUARD(fDebug,1,"Define output from AliFMDEventInspector");
605 fList->SetName(GetName());
610 //____________________________________________________________________
612 AliFMDEventInspector::Process(const AliESDEvent* event,
625 // triggers On return, the triggers fired
626 // lowFlux On return, true if the event is considered a low-flux
627 // event (according to the setting of fLowFluxCut)
628 // ivz On return, the found vertex bin (1-based). A zero
629 // means outside of the defined vertex range
630 // vz On return, the z position of the interaction
631 // cent On return, the centrality - if not available < 0
634 // 0 (or kOk) on success, otherwise a bit mask of error codes
636 DGUARD(fDebug,1,"Process event in AliFMDEventInspector");
637 // --- Check that we have an event ---------------------------------
639 AliWarning("No ESD event found for input event");
644 // --- Read trigger information from the ESD and store in AOD object
645 if (!ReadTriggers(*event, triggers, nClusters)) {
647 AliWarning("Failed to read triggers from ESD"); }
652 // --- Check if this is a high-flux event --------------------------
653 const AliMultiplicity* testmult = event->GetMultiplicity();
656 AliWarning("No central multiplicity object found"); }
659 lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
661 fHType->Fill(lowFlux ? 0 : 1);
663 // --- Process satellite event information is requested ------------
664 if (fUseDisplacedVertices) {
665 if (!fDisplacedVertex.Process(event))
666 AliWarning("Failed to process satellite event");
670 // --- Get the interaction point -----------------------------------
671 Bool_t vzOk = ReadVertex(*event, ip);
672 fHEventsTr->Fill(ip.Z());
675 AliWarning("Failed to read vertex from ESD"); }
680 // --- Read centrality information
683 if (!ReadCentrality(*event, cent, qual)) {
685 AliWarning("Failed to get centrality");
687 // --- check centrality cut
689 if(fminCent>-0.0001&¢<fminCent)
691 if(fmaxCent>-0.0001&¢>fmaxCent)
694 if (qual == 0) fHCentVsQual->Fill(0., cent);
696 for (UShort_t i = 0; i < 4; i++)
697 if (qual & (1 << i)) fHCentVsQual->Fill(Double_t(i+1), cent);
701 fHEventsTrVtx->Fill(ip.Z());
703 // --- Get the vertex bin ------------------------------------------
704 ivz = fVtxAxis.FindBin(ip.Z());
705 if (ivz <= 0 || ivz > fVtxAxis.GetNbins()) {
707 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
708 ip.Z(), fVtxAxis.GetXmin(), fVtxAxis.GetXmax()));
714 fHEventsAccepted->Fill(ip.Z());
715 fHEventsAcceptedXY->Fill(ip.X(),ip.Y());
717 // --- Check the FMD ESD data --------------------------------------
718 if (!event->GetFMDData()) {
720 AliWarning("No FMD data found in ESD"); }
729 //____________________________________________________________________
731 AliFMDEventInspector::ReadCentrality(const AliESDEvent& esd,
733 UShort_t& qual) const
736 // Read centrality from event
740 // cent On return, the centrality or negative if not found
743 // False on error, true otherwise
745 DGUARD(fDebug,2,"Read the centrality in AliFMDEventInspector");
747 if(fUseDisplacedVertices) {
748 Double_t zvtx = fDisplacedVertex.GetVertexZ();
750 if(TMath::Abs(zvtx) < 999) {
751 cent = fDisplacedVertex.GetCentralityPercentile();
759 AliCentrality* centObj = const_cast<AliESDEvent&>(esd).GetCentrality();
760 if (!centObj) return true;
762 cent = centObj->GetCentralityPercentile(fCentMethod);
763 qual = centObj->GetQuality();
768 //____________________________________________________________________
770 AliFMDEventInspector::CheckpAExtraV0(const AliESDEvent& esd) const
772 if (fCollisionSystem != AliForwardUtil::kPPb) return true;
774 AliVVZERO* esdV0 = esd.GetVZEROData();
775 if ((esdV0->GetV0ADecision()!=1) || (esdV0->GetV0CDecision()!=1))
780 //____________________________________________________________________
782 AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
786 // Read the trigger information from the ESD event
790 // triggers On return, contains the trigger bits
793 // @c true on success, @c false otherwise
795 DGUARD(fDebug,2,"Read the triggers in AliFMDEventInspector");
798 // Get the analysis manager - should always be there
799 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
800 DMSG(fDebug,10,"Got analysis manager %p", am);
802 AliWarning("No analysis manager defined!");
806 // Get the input handler - should always be there
807 AliInputEventHandler* ih =
808 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
809 DMSG(fDebug,10,"Got input handler %p", ih);
811 AliWarning("No input handler");
815 // Check if this is a collision candidate (MB)
816 // Note, that we should use the value cached in the input
817 // handler rather than calling IsCollisionCandiate directly
818 // on the AliPhysicsSelection obejct. If we called the latter
819 // then the AliPhysicsSelection object would overcount by a
821 Bool_t offline = ih->IsEventSelected();
822 Bool_t fastonly = (ih->IsEventSelected() & AliVEvent::kFastOnly);
823 TString trigStr = esd.GetFiredTriggerClasses();
825 if (fHWords) fHWords->Fill(trigStr.Data(), 1);
827 if(fUseDisplacedVertices) {
828 DMSG(fDebug,3,"Using displaced vertex stuff");
829 if (TMath::Abs(fDisplacedVertex.GetVertexZ()) >= 999) offline = false;
832 if (CheckFastPartition(fastonly)) offline = false;
833 if (offline && CheckCosmics(trigStr)) offline = false;
834 // if (!CheckpAExtraV0(esd)) offline = false;
836 DMSG(fDebug,2,"Event is %striggered by off-line", offline ? "" : "NOT ");
839 triggers |= AliAODForwardMult::kOffline;
840 triggers |= AliAODForwardMult::kInel;
842 AliWarning("Histogram of triggers not defined - has init been called");
845 // fHTriggers->Fill(kOffline+0.5);
847 CheckINELGT0(esd, nClusters, triggers);
850 CheckNSD(esd,triggers);
851 CheckPileup(esd, triggers);
852 CheckEmpty(trigStr, triggers);
853 // if (CheckPileup(esd, triggers)) fHTriggers->Fill(kPileUp+.5);
854 // if (CheckEmpty(trigStr, triggers)) fHTriggers->Fill(kEmpty+.5);
856 CheckWords(esd, triggers);
859 // Now check - if we have a collision - for offline triggers and
861 if (triggers & AliAODForwardMult::kB) {
862 fHTriggers->Fill(kB+.5);
863 if (triggers & AliAODForwardMult::kInel)
864 fHTriggers->Fill(kInel+.5);
866 if (triggers & AliAODForwardMult::kInelGt0)
867 fHTriggers->Fill(kInelGt0+.5);
869 if (triggers & AliAODForwardMult::kNSD)
870 fHTriggers->Fill(kNSD+.5);
872 if (triggers & AliAODForwardMult::kV0AND)
873 fHTriggers->Fill(kV0AND+.5);
875 if (triggers & AliAODForwardMult::kA) fHTriggers->Fill(kA+.5);
876 if (triggers & AliAODForwardMult::kC) fHTriggers->Fill(kC+.5);
877 if (triggers & AliAODForwardMult::kE) fHTriggers->Fill(kE+.5);
879 #define TEST_TRIG_BIN(RET,BIN,TRIGGERS) \
880 do { switch (BIN) { \
881 case kInel: RET = triggers & AliAODForwardMult::kInel; break; \
882 case kInelGt0: RET = triggers & AliAODForwardMult::kInelGt0; break; \
883 case kNSD: RET = triggers & AliAODForwardMult::kNSD; break; \
884 case kV0AND: RET = triggers & AliAODForwardMult::kV0AND; break; \
885 case kEmpty: RET = triggers & AliAODForwardMult::kEmpty; break; \
886 case kA: RET = triggers & AliAODForwardMult::kA; break; \
887 case kB: RET = triggers & AliAODForwardMult::kB; break; \
888 case kC: RET = triggers & AliAODForwardMult::kC; break; \
889 case kE: RET = triggers & AliAODForwardMult::kE; break; \
890 case kPileUp: RET = triggers & AliAODForwardMult::kPileUp; break; \
891 case kMCNSD: RET = triggers & AliAODForwardMult::kMCNSD; break; \
892 case kOffline: RET = triggers & AliAODForwardMult::kOffline; break; \
893 default: RET = false; } } while(false)
896 for (Int_t i = 0; i < kOffline+1; i++) {
898 TEST_TRIG_BIN(hasX, i, triggers);
900 fHTriggers->Fill(i+.5);
901 for (Int_t j = 0; j < kOffline+1; j++) {
903 TEST_TRIG_BIN(hasY, j, triggers);
906 fHTriggerCorr->Fill(i+.5, j+.5);
912 //____________________________________________________________________
914 AliFMDEventInspector::CheckFastPartition(bool fastonly) const
916 // For the 2.76 TeV p+p run, the FMD ran in the slow partition
917 // so it received no triggers from the fast partition. Therefore
918 // the fast triggers are removed here but not for MC where all
919 // triggers are fast.
920 if (TMath::Abs(fEnergy - 2750.) > 20) return false;
921 if (fCollisionSystem != AliForwardUtil::kPP) return false;
923 DMSG(fDebug,1,"Fast trigger in pp @ sqrt(s)=2.76TeV removed");
928 //____________________________________________________________________
930 AliFMDEventInspector::CheckCosmics(const TString& trigStr) const
932 // MUON triggers are not strictly minimum bias (MB) so they are
934 if(trigStr.Contains("CMUS1")) {
935 DMSG(fDebug,1,"Cosmic trigger ins't min-bias, removed");
941 //____________________________________________________________________
943 AliFMDEventInspector::CheckINELGT0(const AliESDEvent& esd,
945 UInt_t& triggers) const
949 // If this is inel, see if we have a tracklet
950 const AliMultiplicity* spdmult = esd.GetMultiplicity();
952 AliWarning("No SPD multiplicity");
956 // Check if we have one or more tracklets
957 // in the range -1 < eta < 1 to set the INEL>0
960 // Also count tracklets as a single cluster
961 Int_t n = spdmult->GetNumberOfTracklets();
962 for (Int_t j = 0; j < n; j++) {
963 if(TMath::Abs(spdmult->GetEta(j)) < 1) {
964 triggers |= AliAODForwardMult::kInelGt0;
968 n = spdmult->GetNumberOfSingleClusters();
969 for (Int_t j = 0; j < n; j++) {
970 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
971 if (TMath::Abs(eta) < 1) nClusters++;
973 if (nClusters > 0) triggers |= AliAODForwardMult::kNClusterGt0;
975 return triggers & AliAODForwardMult::kNClusterGt0;
978 //____________________________________________________________________
980 AliFMDEventInspector::CheckNSD(const AliESDEvent& esd, UInt_t& triggers) const
982 // Analyse some trigger stuff
983 AliTriggerAnalysis ta;
984 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kV0AND)) {
985 triggers |= AliAODForwardMult::kV0AND;
987 triggers |= AliAODForwardMult::kNSD;
989 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kNSD1))
990 triggers |= AliAODForwardMult::kNSD;
991 return triggers & AliAODForwardMult::kNSD;
993 //____________________________________________________________________
995 AliFMDEventInspector::CheckPileup(const AliESDEvent& esd,
996 UInt_t& triggers) const
998 // Check for multiple vertices (pile-up) with at least 3
999 // contributors and at least 0.8cm from the primary vertex
1000 if(fCollisionSystem != AliForwardUtil::kPP) return false;
1002 Bool_t pileup = esd.IsPileupFromSPD(fMinPileupContrib,fMinPileupDistance);
1003 if (pileup) triggers |= AliAODForwardMult::kPileUp;
1007 //____________________________________________________________________
1009 AliFMDEventInspector::CheckEmpty(const TString& trigStr, UInt_t& triggers) const
1011 if (trigStr.Contains("CBEAMB-ABCE-NOPF-ALL")) {
1012 triggers |= AliAODForwardMult::kEmpty;
1017 //____________________________________________________________________
1019 AliFMDEventInspector::CheckWords(const AliESDEvent& esd, UInt_t& triggers) const
1022 TIter nextColl(&fCollWords);
1023 while ((word = nextColl())) {
1024 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1025 word->GetTitle(), word->GetName());
1026 if (!esd.IsTriggerClassFired(word->GetName())) continue;
1028 TString beamSide = word->GetTitle();
1029 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
1031 if (!beamSide.EqualTo("B")) continue;
1032 triggers |= AliAODForwardMult::kB;
1033 break; // No more to do here
1035 TIter nextBg(&fBgWords);
1036 UInt_t all = (AliAODForwardMult::kA |
1037 AliAODForwardMult::kC |
1038 AliAODForwardMult::kE);
1039 while ((word = nextBg())) {
1040 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1041 word->GetTitle(), word->GetName());
1042 if (!esd.IsTriggerClassFired(word->GetName())) continue;
1044 TString beamSide = word->GetTitle();
1045 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
1047 if (beamSide.Contains("A")) triggers |= AliAODForwardMult::kA;
1048 if (beamSide.Contains("C")) triggers |= AliAODForwardMult::kC;
1049 if (beamSide.Contains("E")) triggers |= AliAODForwardMult::kE;
1051 if ((triggers & all) == all) break; // No more to do
1057 //____________________________________________________________________
1059 AliFMDEventInspector::ReadVertex(const AliESDEvent& esd, TVector3& ip)
1062 // Read the vertex information from the ESD event
1066 // vz On return, the vertex Z position
1069 // @c true on success, @c false otherwise
1071 DGUARD(fDebug,2,"Read the vertex in AliFMDEventInspector");
1072 ip.SetXYZ(1024, 1024, 0);
1074 if(fUseDisplacedVertices) {
1075 Double_t zvtx = fDisplacedVertex.GetVertexZ();
1077 if(TMath::Abs(zvtx) < 999) {
1084 if(fUseFirstPhysicsVertex) return CheckPWGUDVertex(esd, ip);
1086 if(fUsepA2012Vertex) return CheckpA2012Vertex(esd,ip);
1088 return CheckVertex(esd, ip);
1091 //____________________________________________________________________
1093 AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
1096 // This is the code used by the 1st physics people
1097 const AliESDVertex* vertex = esd.GetPrimaryVertex();
1098 if (!vertex || !vertex->GetStatus()) {
1099 DMSG(fDebug,2,"No primary vertex (%p) or bad status %d",
1100 vertex, (vertex ? vertex->GetStatus() : -1));
1103 const AliESDVertex* vertexSPD = esd.GetPrimaryVertexSPD();
1104 if (!vertexSPD || !vertexSPD->GetStatus()) {
1105 DMSG(fDebug,2,"No primary SPD vertex (%p) or bad status %d",
1106 vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1));
1110 // if vertex is from SPD vertexZ, require more stringent cuts
1111 if (vertex->IsFromVertexerZ()) {
1112 if (vertex->GetDispersion() > fMaxVzErr ||
1113 vertex->GetZRes() > 1.25 * fMaxVzErr) {
1114 DMSG(fDebug,2,"Dispersion %f > %f or resolution %f > %f",
1115 vertex->GetDispersion(), fMaxVzErr,
1116 vertex->GetZRes(), 1.25 * fMaxVzErr);
1120 ip.SetZ(vertex->GetZ());
1122 if(!vertex->IsFromVertexerZ()) {
1123 ip.SetX(vertex->GetX());
1124 ip.SetY(vertex->GetY());
1129 Bool_t AliFMDEventInspector::CheckpA2012Vertex(const AliESDEvent& esd,
1132 const AliESDVertex *vertex = esd.GetPrimaryVertexSPD();
1133 Bool_t fVtxOK = kFALSE;
1134 if (vertex->GetNContributors()>0)
1136 TString vtxTyp = vertex->GetTitle();
1137 if ( !vtxTyp.Contains("vertexer: Z") || (vertex->GetDispersion()<0.04 && vertex->GetZRes()<0.25))
1140 ip.SetX(vertex->GetX());
1141 ip.SetY(vertex->GetY());
1142 ip.SetZ(vertex->GetZ());
1149 //____________________________________________________________________
1151 AliFMDEventInspector::CheckVertex(const AliESDEvent& esd,
1154 // Use standard SPD vertex (perhaps preferable for Pb+Pb)
1156 const AliESDVertex* vertex = esd.GetPrimaryVertexSPD();
1159 AliWarning("No SPD vertex found in ESD"); }
1163 // Check that enough tracklets contributed
1164 if(vertex->GetNContributors() <= 0) {
1165 DMSG(fDebug,2,"Number of contributors to vertex is %d<=0",
1166 vertex->GetNContributors());
1170 // Check that the uncertainty isn't too large
1171 if (vertex->GetZRes() > fMaxVzErr) {
1172 DMSG(fDebug,2,"Uncertaintity in Z of vertex is too large %f > %f",
1173 vertex->GetZRes(), fMaxVzErr);
1177 // Get the z coordiante
1178 ip.SetZ(vertex->GetZ());
1179 const AliESDVertex* vertexXY = esd.GetPrimaryVertex();
1182 if(!vertexXY->IsFromVertexerZ()) {
1183 ip.SetX(vertexXY->GetX());
1184 ip.SetY(vertexXY->GetY());
1189 //____________________________________________________________________
1191 AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
1194 // Read the collision system, collision energy, and L3 field setting
1198 // esd ESD to get information from
1201 // true on success, false
1203 // AliInfo(Form("Parameters from 1st ESD event: cms=%s, sNN=%f, field=%f",
1204 // esd->GetBeamType(), 2*esd->GetBeamEnergy(),
1205 // esd->GetMagneticField()));
1206 DGUARD(fDebug,2,"Read the run details in AliFMDEventInspector");
1207 const char* sys = esd->GetBeamType();
1208 Float_t cms = 2 * esd->GetBeamEnergy();
1209 Float_t fld = esd->GetMagneticField();
1210 fCollisionSystem = AliForwardUtil::ParseCollisionSystem(sys);
1211 fEnergy = AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,
1213 fField = AliForwardUtil::ParseMagneticField(fld);
1215 StoreInformation(esd->GetRunNumber());
1216 if (fCollisionSystem == AliForwardUtil::kUnknown) {
1217 AliWarningF("Unknown collision system: %s - please check", sys);
1221 AliWarningF("Unknown CMS energy: %f (%d) - please check", cms, fEnergy);
1224 if (TMath::Abs(fField) > 10) {
1225 AliWarningF("Unknown L3 field setting: %f (%d) - please check", fld,fField);
1233 //____________________________________________________________________
1235 AliFMDEventInspector::CodeString(UInt_t code)
1239 if (code & kNoEvent) s.Append("NOEVENT ");
1240 if (code & kNoTriggers) s.Append("NOTRIGGERS ");
1241 if (code & kNoSPD) s.Append("NOSPD ");
1242 if (code & kNoFMD) s.Append("NOFMD ");
1243 if (code & kNoVertex) s.Append("NOVERTEX ");
1244 if (code & kBadVertex) s.Append("BADVERTEX ");
1247 //____________________________________________________________________
1249 AliFMDEventInspector::Print(Option_t*) const
1252 // Print information
1256 char ind[gROOT->GetDirLevel()+1];
1257 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
1258 ind[gROOT->GetDirLevel()] = '\0';
1259 TString sNN(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
1260 sNN.Strip(TString::kBoth, '0');
1261 sNN.ReplaceAll("GeV", " GeV");
1262 TString field(AliForwardUtil::MagneticFieldString(fField));
1263 field.ReplaceAll("p", "+");
1264 field.ReplaceAll("m", "-");
1265 field.ReplaceAll("kG", " kG");
1267 std::cout << std::boolalpha
1268 << ind << ClassName() << ": " << GetName() << '\n'
1269 << ind << " Vertex bins: " << fVtxAxis.GetNbins() << '\n'
1270 << ind << " Vertex range: [" << fVtxAxis.GetXmin()
1271 << "," << fVtxAxis.GetXmax() << "]\n"
1272 << ind << " Low flux cut: " << fLowFluxCut << '\n'
1273 << ind << " Max(delta v_z): " << fMaxVzErr << " cm\n"
1274 << ind << " Min(nContrib_pileup): " << fMinPileupContrib << '\n'
1275 << ind << " Min(v-pileup): " << fMinPileupDistance << '\n'
1276 << ind << " System: "
1277 << AliForwardUtil::CollisionSystemString(fCollisionSystem) << '\n'
1278 << ind << " CMS energy per nucleon: " << sNN << '\n'
1279 << ind << " Field: " << field << '\n'
1280 << ind << " Satellite events: " << fUseDisplacedVertices<<'\n'
1281 << ind << " Centrality method: " << fCentMethod << '\n'
1282 << std::noboolalpha;
1283 if (!fCentAxis) { std::cout << std::flush; return; }
1284 Int_t nBin = fCentAxis->GetNbins();
1285 std::cout << ind << " Centrality axis: " << nBin << " bins"
1287 for (Int_t i = 0; i < nBin; i++) {
1288 if ((i % 10) == 0) std::cout << '\n' << ind << " ";
1289 std::cout << std::setw(5) << fCentAxis->GetBinLowEdge(i+1) << '-';
1291 std::cout << std::setw(5) << fCentAxis->GetBinUpEdge(nBin) << std::endl;