]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliFMDEventInspector.cxx
Coverity fixes
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliFMDEventInspector.cxx
CommitLineData
7984e5f7 1//
2// This class inspects the event
3//
4// Input:
5// - AliESDFMD object possibly corrected for sharing
6//
7// Output:
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
11//
12// Note, that these are added to the master output list
13//
14// Corrections used:
15// - None
16//
8565b10b 17#include "AliFMDEventInspector.h"
c8b1a7db 18#include "AliProdInfo.h"
8565b10b 19#include "AliLog.h"
20#include "AliESDEvent.h"
21#include "AliMultiplicity.h"
22#include "AliAnalysisManager.h"
11d40ecb 23#include "AliMCEventHandler.h"
8565b10b 24#include "AliInputEventHandler.h"
25#include "AliTriggerAnalysis.h"
26#include "AliPhysicsSelection.h"
e85a76b7 27#include "AliOADBPhysicsSelection.h"
8565b10b 28#include "AliAODForwardMult.h"
0bd4b00f 29#include "AliForwardUtil.h"
5e4d905e 30#include "AliCentrality.h"
8565b10b 31#include <TH1.h>
32#include <TList.h>
33#include <TDirectory.h>
0bd4b00f 34#include <TROOT.h>
e6463868 35#include <TParameter.h>
dd556bcd 36#include <TMatrixDSym.h>
c8b1a7db 37#include <TPRegexp.h>
0bd4b00f 38#include <iostream>
39#include <iomanip>
65abd48b 40#include "AliMCEvent.h"
41#include "AliHeader.h"
42#include "AliGenEventHeader.h"
43#include "AliCollisionGeometry.h"
da70cd6a 44#include "AliVVZERO.h"
e1f47419 45
77f97e3f
CHC
46//====================================================================
47namespace {
48 AliPhysicsSelection* GetPhysicsSelection()
49 {
50 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
51
52 // Get the input handler - should always be there
53 AliInputEventHandler* ih =
54 dynamic_cast<AliInputEventHandler*>(am->GetInputEventHandler());
55 if (!ih) {
56 Warning("GetPhysicsSelection", "No input handler");
57 return 0;
58 }
59 // Get the physics selection - should always be there
60 AliPhysicsSelection* ps =
61 dynamic_cast<AliPhysicsSelection*>(ih->GetEventSelection());
62 if (!ps) {
63 Warning("GetPhysicsSelection", "No physics selection");
64 return 0;
65 }
66 return ps;
67 }
68}
69
8565b10b 70//====================================================================
5ca83fee 71const char* AliFMDEventInspector::fgkFolderName = "fmdEventInspector";
72
73//____________________________________________________________________
8565b10b 74AliFMDEventInspector::AliFMDEventInspector()
75 : TNamed(),
76 fHEventsTr(0),
77 fHEventsTrVtx(0),
5bb5d1f6 78 fHEventsAccepted(0),
96110c91 79 fHEventsAcceptedXY(0),
8565b10b 80 fHTriggers(0),
66cf95f2 81 fHTriggerCorr(0),
0bd4b00f 82 fHType(0),
5ca83fee 83 fHWords(0),
84 fHCent(0),
85 fHCentVsQual(0),
86 fHStatus(0),
8449e3e0 87 fHVtxStatus(0),
e65b8b56 88 fHTrgStatus(0),
5ca83fee 89 fLowFluxCut(1000),
90 fMaxVzErr(0.2),
91 fList(0),
92 fEnergy(0),
0bd4b00f 93 fField(999),
5ca83fee 94 fCollisionSystem(kUnknown),
e308a636 95 fDebug(0),
5bb5d1f6 96 fCentAxis(0),
e83d0620 97 fVtxAxis(10,-10,10),
5ca83fee 98 fUseFirstPhysicsVertex(false),
99 fUseV0AND(false),
0b7de667 100 fMinPileupContrib(3),
101 fMinPileupDistance(0.8),
e65b8b56 102 fUseDisplacedVertices(false),
0b7de667 103 fDisplacedVertex(),
104 fCollWords(),
105 fBgWords(),
106 fCentMethod("V0M"),
107 fMinCent(-1.0),
108 fMaxCent(-1.0),
109 fUsepA2012Vertex(false),
110 fRunNumber(0),
111 fMC(false),
112 fProdYear(-1),
113 fProdLetter('?'),
114 fProdPass(-1),
115 fProdSVN(-1),
116 fProdMC(false)
8565b10b 117{
7984e5f7 118 //
119 // Constructor
120 //
241cca4d 121 DGUARD(fDebug,1,"Default CTOR of AliFMDEventInspector");
8565b10b 122}
123
124//____________________________________________________________________
125AliFMDEventInspector::AliFMDEventInspector(const char* name)
5ca83fee 126 : TNamed(fgkFolderName, name),
8565b10b 127 fHEventsTr(0),
128 fHEventsTrVtx(0),
5bb5d1f6 129 fHEventsAccepted(0),
96110c91 130 fHEventsAcceptedXY(0),
8565b10b 131 fHTriggers(0),
66cf95f2 132 fHTriggerCorr(0),
0bd4b00f 133 fHType(0),
fe52e455 134 fHWords(0),
5e4d905e 135 fHCent(0),
e308a636 136 fHCentVsQual(0),
241cca4d 137 fHStatus(0),
8449e3e0 138 fHVtxStatus(0),
139 fHTrgStatus(0),
8565b10b 140 fLowFluxCut(1000),
9d05ffeb 141 fMaxVzErr(0.2),
8565b10b 142 fList(0),
0bd4b00f 143 fEnergy(0),
144 fField(999),
145 fCollisionSystem(kUnknown),
e308a636 146 fDebug(0),
5bb5d1f6 147 fCentAxis(0),
e83d0620 148 fVtxAxis(10,-10,10),
5ca83fee 149 fUseFirstPhysicsVertex(false),
e6463868 150 fUseV0AND(false),
151 fMinPileupContrib(3),
65abd48b 152 fMinPileupDistance(0.8),
153 fUseDisplacedVertices(false),
241cca4d 154 fDisplacedVertex(),
155 fCollWords(),
5934a3e3 156 fBgWords(),
4f9319f3 157 fCentMethod("V0M"),
8449e3e0 158 fMinCent(-1.0),
159 fMaxCent(-1.0),
160 fUsepA2012Vertex(false),
e65b8b56 161 fRunNumber(0),
0b7de667 162 fMC(false),
163 fProdYear(-1),
164 fProdLetter('?'),
165 fProdPass(-1),
166 fProdSVN(-1),
167 fProdMC(false)
8565b10b 168{
7984e5f7 169 //
170 // Constructor
171 //
172 // Parameters:
173 // name Name of object
174 //
241cca4d 175 DGUARD(fDebug,1,"Named CTOR of AliFMDEventInspector: %s", name);
77f97e3f
CHC
176 if (!GetPhysicsSelection()) {
177 AliFatal("No physics selection defined in manager\n"
178 "=======================================================\n"
179 " The use of AliFMDEventInspector _requires_ a valid\n"
180 " AliPhysicsSelection registered with the input handler.\n\n"
181 " Please check our train setup\n"
182 "=======================================================\n");
183}
8565b10b 184}
185
8565b10b 186//____________________________________________________________________
187AliFMDEventInspector::~AliFMDEventInspector()
188{
7984e5f7 189 //
190 // Destructor
191 //
c929bc03 192 DGUARD(fDebug,1,"DTOR of AliFMDEventInspector");
193 // if (fList) delete fList;
8565b10b 194}
8565b10b 195
5934a3e3 196//____________________________________________________________________
197void
198AliFMDEventInspector::SetCentralityMethod(ECentMethod m)
199{
200 switch (m) {
201 case kV0Multiplicity: fCentMethod = "VOM"; break; // VZERO multiplicity
202 case kV0Amplitude: fCentMethod = "V0A"; break; // VZERO amplitude
203 case kV0Charge: fCentMethod = "V0C"; break; // VZERO charge
204 case kFMDRough: fCentMethod = "FMD"; break; // FMD scaled energy l
205 case kNTracks: fCentMethod = "TRK"; break; // Number of tracks
206 case kLTracks: fCentMethod = "TKL"; break; // Number of tracks
207 case kCL0: fCentMethod = "CL0"; break; //
208 case kCL1: fCentMethod = "CL1"; break; //
209 case kCND: fCentMethod = "CND"; break; //
210 case kNParticles: fCentMethod = "NPA"; break; // Neutral particles
211 case kNeutrons: fCentMethod = "ZNA"; break; // ZDC neutron amplitu
212 case kV0vsFMD: fCentMethod = "V0MvsFMD"; break; // VZERO versus FMD
213 case kV0vsNTracks: fCentMethod = "TKLvsVOM"; break; // Tracks versus VZERO
214 case kZEMvsZDC: fCentMethod = "ZEMvsZDC"; break; // ZDC
215 default: fCentMethod = "V0M"; break;
216 }
217}
218
8449e3e0 219//____________________________________________________________________
220void
221AliFMDEventInspector::SetMinCentrality(Double_t minCent)
222{
223 AliWarning("\n"
224 "*******************************************************\n"
225 "* Setting centrality cuts in this stage is deprecated *\n"
226 "*******************************************************");
227 fMinCent = minCent;
228}
229//____________________________________________________________________
230void
231AliFMDEventInspector::SetMaxCentrality(Double_t maxCent)
232{
233 AliWarning("\n"
234 "*******************************************************\n"
235 "* Setting centrality cuts in this stage is deprecated *\n"
236 "*******************************************************");
237 fMaxCent = maxCent;
238}
239
8565b10b 240//____________________________________________________________________
241Bool_t
fb3430ac 242AliFMDEventInspector::FetchHistograms(const TList* d,
8565b10b 243 TH1I*& hEventsTr,
244 TH1I*& hEventsTrVtx,
5ca83fee 245 TH1I*& hEventsAcc,
8565b10b 246 TH1I*& hTriggers) const
247{
7984e5f7 248 //
249 // Fetch our histograms from the passed list
250 //
251 // Parameters:
252 // d Input
253 // hEventsTr On return, pointer to histogram, or null
254 // hEventsTrVtx On return, pointer to histogram, or null
255 // hTriggers On return, pointer to histogram, or null
256 //
257 // Return:
258 // true on success, false otherwise
259 //
6ab100ec 260 DGUARD(fDebug,3,"Fetch histograms in AliFMDEventInspector");
8565b10b 261 hEventsTr = 0;
262 hEventsTrVtx = 0;
5ca83fee 263 hEventsAcc = 0;
264 hTriggers = 0;
8565b10b 265 TList* dd = dynamic_cast<TList*>(d->FindObject(GetName()));
266 if (!dd) return kFALSE;
267
268 hEventsTr = dynamic_cast<TH1I*>(dd->FindObject("nEventsTr"));
269 hEventsTrVtx = dynamic_cast<TH1I*>(dd->FindObject("nEventsTrVtx"));
5ca83fee 270 hEventsAcc = dynamic_cast<TH1I*>(dd->FindObject("nEventsAccepted"));
8565b10b 271 hTriggers = dynamic_cast<TH1I*>(dd->FindObject("triggers"));
272
5ca83fee 273 if (!hEventsTr ||
274 !hEventsTrVtx ||
275 !hEventsAcc ||
276 !hTriggers) return kFALSE;
8565b10b 277 return kTRUE;
278}
241cca4d 279//____________________________________________________________________
280void
281AliFMDEventInspector::CacheConfiguredTriggerClasses(TList& cache,
282 const TList* classes,
283 AliOADBPhysicsSelection* o)
284{
285 TIter nextClass(classes);
286 TObjString* trigClass = 0;
287 // Loop over all trigger classes. Trigger classes have the format
288 //
289 // class := positive_words SPACE(s) negative_words
290 // positive_words :=
291 // | '+' words
292 // negative_words :=
293 // | '-' words
294 // words := word
295 // | word ',' words
296 //
297 while ((trigClass = static_cast<TObjString*>(nextClass()))) {
298 // Tokenize on space to get positive and negative parts
299 TString side = o->GetBeamSide(trigClass->String());
300 TObjArray* parts = trigClass->String().Tokenize(" ");
301 TObjString* part = 0;
302 TIter nextPart(parts);
303 while ((part = static_cast<TObjString*>(nextPart()))) {
304 // We only care about the positive ones
305 if (part->GetName()[0] != '+') continue;
306 part->String().Remove(0,1);
307
308 // Tokenize on a comma to get the words
309 TObjArray* words = part->String().Tokenize(",");
310 TObjString* word = 0;
311 TIter nextWord(words);
312 while ((word = static_cast<TObjString*>(nextWord()))) {
313 TNamed* store = new TNamed(word->String(), side);
314 cache.Add(store);
315 DMSG(fDebug,3,"Caching %s trigger word %s",
316 store->GetTitle(), store->GetName());
317 } // while (word)
318 delete words;
319 }
320 delete parts;
321 }
322}
323
8565b10b 324//____________________________________________________________________
325void
5934a3e3 326AliFMDEventInspector::SetupForData(const TAxis& vtxAxis)
8565b10b 327{
7984e5f7 328 //
241cca4d 329 // Initialize the object - this is called on the first seen event.
7984e5f7 330 //
331 // Parameters:
332 // vtxAxis Vertex axis in use
333 //
6ab100ec 334 DGUARD(fDebug,1,"Initialize in AliFMDEventInspector");
241cca4d 335
241cca4d 336 // Get the physics selection - should always be there
77f97e3f 337 AliPhysicsSelection* ps = GetPhysicsSelection();
241cca4d 338 if (!ps) {
339 AliWarning("No physics selection");
340 return;
341 }
342 // Get the configured triggers
343 AliOADBPhysicsSelection* oadb =
344 const_cast<AliOADBPhysicsSelection*>(ps->GetOADBPhysicsSelection());
345 if (!oadb) {
346 AliWarning("No OADB physics selection object");
347 return;
348 }
349 // Get the configured trigger words from the physics selection
350 const TList* collTriggClasses = ps->GetCollisionTriggerClasses();
351 const TList* bgTriggClasses = ps->GetBGTriggerClasses();
352 if (!collTriggClasses) {
353 AliWarning("No configured collision trigger classes");
354 return;
355 }
356 if (!bgTriggClasses) {
357 AliWarning("No configured background trigger classes");
358 return;
359 }
360 CacheConfiguredTriggerClasses(fCollWords, collTriggClasses, oadb);
361 CacheConfiguredTriggerClasses(fBgWords, bgTriggClasses, oadb);
362 // fCollWords.ls();
363 // fBgWords.ls();
364
e308a636 365
8449e3e0 366 TArrayD limits;
367 if ((fMinCent < 0 && fMaxCent < 0) || fMaxCent <= fMinCent) {
77f97e3f 368 // Was:
8449e3e0 369 // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
370 // ----- 92 number --------- ---- 1 ---
77f97e3f
CHC
371 // Now:
372 // -0.5 0.5 1.5 ... 89.5 ... 100.5
373 // ----- 91 number ---- ---- 1 ---
374 limits.Set(92);
375 for (Int_t i = 0; i < 91; i++) limits[i] = -.5 + i;
376 limits[91] = 100.5;
8449e3e0 377 }
378 else {
77f97e3f 379 Int_t n = Int_t(fMaxCent-fMinCent+2);
8449e3e0 380 limits.Set(n);
381 for (Int_t i = 0; i < n; i++) {
382 limits[i] = fMinCent + i - .5;
383 }
384 }
385
5bb5d1f6 386 fVtxAxis.Set(vtxAxis.GetNbins(), vtxAxis.GetXmin(), vtxAxis.GetXmax());
e308a636 387
388 fCentAxis = new TAxis(limits.GetSize()-1, limits.GetArray());
8565b10b 389 fHEventsTr = new TH1I("nEventsTr", "Number of events w/trigger",
5bb5d1f6 390 4*vtxAxis.GetNbins(),
391 2*vtxAxis.GetXmin(),
392 2*vtxAxis.GetXmax());
8565b10b 393 fHEventsTr->SetXTitle("v_{z} [cm]");
394 fHEventsTr->SetYTitle("# of events");
395 fHEventsTr->SetFillColor(kRed+1);
396 fHEventsTr->SetFillStyle(3001);
397 fHEventsTr->SetDirectory(0);
398 // fHEventsTr->Sumw2();
399 fList->Add(fHEventsTr);
400
5bb5d1f6 401 fHEventsTrVtx = static_cast<TH1I*>(fHEventsTr->Clone("nEventsTrVtx"));
402 fHEventsTrVtx->SetTitle("Number of events w/trigger and vertex");
8565b10b 403 fHEventsTrVtx->SetFillColor(kBlue+1);
8565b10b 404 fHEventsTrVtx->SetDirectory(0);
405 // fHEventsTrVtx->Sumw2();
406 fList->Add(fHEventsTrVtx);
407
5bb5d1f6 408 fHEventsAccepted = new TH1I("nEventsAccepted",
409 "Number of events w/trigger and vertex in range",
410 2*vtxAxis.GetNbins(),
411 2*vtxAxis.GetXmin(),
412 2*vtxAxis.GetXmax());
413 fHEventsAccepted->SetXTitle("v_{z} [cm]");
414 fHEventsAccepted->SetYTitle("# of events");
415 fHEventsAccepted->SetFillColor(kGreen+1);
416 fHEventsAccepted->SetFillStyle(3001);
417 fHEventsAccepted->SetDirectory(0);
418 // fHEventsAccepted->Sumw2();
419 fList->Add(fHEventsAccepted);
420
96110c91 421 fHEventsAcceptedXY = new TH2D("nEventsAcceptedXY",
422 "XY vertex w/trigger and Z vertex in range",
423 1000,-1,1,1000,-1,1);
424
425 fHEventsAcceptedXY->SetXTitle("v_{x} [cm]");
426 fHEventsAcceptedXY->SetYTitle("v_{y} [cm]");
427 fHEventsAcceptedXY->SetDirectory(0);
428 // fHEventsAccepted->Sumw2();
429 fList->Add(fHEventsAcceptedXY);
430
431
0be6c8cd 432 fHTriggers = new TH1I("triggers", "Triggers", kOffline+1, 0, kOffline+1);
8565b10b 433 fHTriggers->SetFillColor(kRed+1);
434 fHTriggers->SetFillStyle(3001);
435 fHTriggers->SetStats(0);
436 fHTriggers->SetDirectory(0);
66cf95f2 437
438 fHTriggerCorr = new TH2I("triggerCorr", "Trigger correlation",
439 kOffline+1, 0, kOffline+1,
440 kOffline+1, 0, kOffline+1);
441 fHTriggerCorr->SetStats(0);
442 fHTriggerCorr->SetDirectory(0);
cd51b0dd 443 fHTriggerCorr->SetXTitle("Requirement");
444 fHTriggerCorr->SetYTitle("Companion");
445
66cf95f2 446 Int_t binNum[] = { kInel +1,
447 kInelGt0+1,
448 kNSD +1,
449 kV0AND +1,
450 kEmpty +1,
451 kA +1,
452 kB +1,
453 kC +1,
454 kE +1,
455 kPileUp +1,
456 kMCNSD +1,
8449e3e0 457 kSatellite+1,
66cf95f2 458 kOffline+1 };
459 const char* binLbl[] = { "INEL",
460 "INEL>0",
461 "NSD",
462 "VOAND",
463 "Empty",
464 "A",
465 "B",
466 "C",
467 "E",
468 "Pileup",
469 "NSD_{MC}",
8449e3e0 470 "Satellite",
66cf95f2 471 "Offline" };
cd51b0dd 472 for (Int_t i = 0; i < kOffline+1; i++) {
66cf95f2 473 fHTriggers->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
474 fHTriggerCorr->GetXaxis()->SetBinLabel(binNum[i], binLbl[i]);
475 fHTriggerCorr->GetYaxis()->SetBinLabel(binNum[i], binLbl[i]);
476 }
8565b10b 477 fList->Add(fHTriggers);
66cf95f2 478 fList->Add(fHTriggerCorr);
479
0bd4b00f 480
481 fHType = new TH1I("type", Form("Event type (cut: SPD mult>%d)",
482 fLowFluxCut), 2, -.5, 1.5);
483 fHType->SetFillColor(kRed+1);
484 fHType->SetFillStyle(3001);
485 fHType->SetStats(0);
486 fHType->SetDirectory(0);
487 fHType->GetXaxis()->SetBinLabel(1,"Low-flux");
488 fHType->GetXaxis()->SetBinLabel(2,"High-flux");
489 fList->Add(fHType);
fe52e455 490
c56f8519 491#if 0
492 // This histogram disabled as it causes problems in the merge
fe52e455 493 fHWords = new TH1I("words", "Trigger words seen", 1, 0, 0);
494 fHWords->SetFillColor(kBlue+1);
495 fHWords->SetFillStyle(3001);
496 fHWords->SetStats(0);
497 fHWords->SetDirectory(0);
498 fHWords->SetBit(TH1::kCanRebin);
499 fList->Add(fHWords);
c56f8519 500#endif
5e4d905e 501
e308a636 502 fHCent = new TH1F("cent", "Centrality", limits.GetSize()-1,limits.GetArray());
5e4d905e 503 fHCent->SetFillColor(kBlue+1);
504 fHCent->SetFillStyle(3001);
505 fHCent->SetStats(0);
506 fHCent->SetDirectory(0);
507 fHCent->SetXTitle("Centrality [%]");
508 fHCent->SetYTitle("Events");
509 fList->Add(fHCent);
e308a636 510
511 fHCentVsQual = new TH2F("centVsQuality", "Quality vs Centrality",
512 5, 0, 5, limits.GetSize()-1, limits.GetArray());
513 fHCentVsQual->SetXTitle("Quality");
514 fHCentVsQual->SetYTitle("Centrality [%]");
515 fHCentVsQual->SetZTitle("Events");
516 fHCentVsQual->GetXaxis()->SetBinLabel(1, "OK");
517 fHCentVsQual->GetXaxis()->SetBinLabel(2, "Outside v_{z} cut");
518 fHCentVsQual->GetXaxis()->SetBinLabel(3, "V0 vs SPD outlier");
519 fHCentVsQual->GetXaxis()->SetBinLabel(4, "V0 vs TPC outlier");
520 fHCentVsQual->GetXaxis()->SetBinLabel(5, "V0 vs ZDC outlier");
b7ab8a2c 521 fHCentVsQual->SetDirectory(0);
e308a636 522 fList->Add(fHCentVsQual);
241cca4d 523
77f97e3f 524 fHStatus = new TH1I("status", "Status", 8, 1, 9);
8449e3e0 525 fHStatus->SetFillColor(kBlue+1);
241cca4d 526 fHStatus->SetFillStyle(3001);
527 fHStatus->SetStats(0);
528 fHStatus->SetDirectory(0);
8449e3e0 529 TAxis* xAxis = fHStatus->GetXaxis();
530 xAxis->SetBinLabel(1, "OK");
531 xAxis->SetBinLabel(2, "No event");
532 xAxis->SetBinLabel(3, "No triggers");
533 xAxis->SetBinLabel(4, "No SPD");
534 xAxis->SetBinLabel(5, "No FMD");
535 xAxis->SetBinLabel(6, "No vertex");
536 xAxis->SetBinLabel(7, "Bad vertex");
77f97e3f 537 xAxis->SetBinLabel(8, "No centrality");
241cca4d 538 fList->Add(fHStatus);
8449e3e0 539
540 fHVtxStatus = new TH1I("vtxStatus","Vertex Status",
541 kNotVtxZ,kVtxOK,kNotVtxZ+1);
542 fHVtxStatus->SetFillColor(kGreen+1);
543 fHVtxStatus->SetFillStyle(3001);
544 fHVtxStatus->SetStats(0);
545 fHVtxStatus->SetDirectory(0);
546 xAxis = fHVtxStatus->GetXaxis();
547 xAxis->SetBinLabel(kVtxOK, "OK");
548 xAxis->SetBinLabel(kNoVtx, "None/bad status");
549 xAxis->SetBinLabel(kNoSPDVtx, "No SPD/bad status");
550 xAxis->SetBinLabel(kFewContrib, "N_{contrib} <= 0");
551 xAxis->SetBinLabel(kUncertain, Form("#delta z > %4.2f", fMaxVzErr));
552 xAxis->SetBinLabel(kNotVtxZ, "Not Z vertexer");
553 fList->Add(fHVtxStatus);
554
555 fHTrgStatus = new TH1I("trgStatus", "Trigger Status",
556 kOther, kNoTrgWords, kOther+1);
557 fHTrgStatus->SetFillColor(kMagenta+1);
558 fHTrgStatus->SetFillStyle(3001);
559 fHTrgStatus->SetStats(0);
560 fHTrgStatus->SetDirectory(0);
561 xAxis = fHTrgStatus->GetXaxis();
562 xAxis->SetBinLabel(kNoTrgWords, "No words");
563 xAxis->SetBinLabel(kPP2760Fast, "FAST in pp@#sqrt{s}=2.76TeV");
564 xAxis->SetBinLabel(kMUON, "Muon trigger");
565 xAxis->SetBinLabel(kTriggered, "Triggered");
566 xAxis->SetBinLabel(kMinBias, "CINT1 (V0A||V0C||FASTOR)");
567 xAxis->SetBinLabel(kMinBiasNoSPD, "CINT5 (V0A||V0C)");
568 xAxis->SetBinLabel(kV0AndTrg, "CINT7 (V0A&&V0C)");
569 xAxis->SetBinLabel(kHighMult, "N>>0");
570 xAxis->SetBinLabel(kCentral, "Central");
571 xAxis->SetBinLabel(kSemiCentral, "Semi-central");
572 xAxis->SetBinLabel(kDiffractive, "Diffractive");
573 xAxis->SetBinLabel(kUser, "User");
574 xAxis->SetBinLabel(kOther, "Other");
575 fList->Add(fHTrgStatus);
576
bfab35d9 577 if (fUseDisplacedVertices) fDisplacedVertex.SetupForData(fList, "", false);
8565b10b 578}
579
f7cfc454 580//____________________________________________________________________
581void
8449e3e0 582AliFMDEventInspector::StoreInformation()
f7cfc454 583{
584 // Write TNamed objects to output list containing information about
585 // the running conditions
6ab100ec 586 DGUARD(fDebug,2,"Store information from AliFMDEventInspector");
f7cfc454 587 if (!fList) return;
588
241cca4d 589
590 fList->Add(AliForwardUtil::MakeParameter("sys", fCollisionSystem));
591 fList->Add(AliForwardUtil::MakeParameter("sNN", fEnergy));
592 fList->Add(AliForwardUtil::MakeParameter("field", fField));
8449e3e0 593 fList->Add(AliForwardUtil::MakeParameter("runNo", fRunNumber));
241cca4d 594 fList->Add(AliForwardUtil::MakeParameter("lowFlux", fLowFluxCut));
595 fList->Add(AliForwardUtil::MakeParameter("fpVtx",fUseFirstPhysicsVertex));
596 fList->Add(AliForwardUtil::MakeParameter("v0and",fUseV0AND));
597 fList->Add(AliForwardUtil::MakeParameter("nPileUp", fMinPileupContrib));
598 fList->Add(AliForwardUtil::MakeParameter("dPileup", fMinPileupDistance));
8449e3e0 599 fList->Add(AliForwardUtil::MakeParameter("satellite", fUseDisplacedVertices));
1ff25622 600 fList->Add(AliForwardUtil::MakeParameter("alirootRev",
601 AliForwardUtil::AliROOTRevision()));
602 fList->Add(AliForwardUtil::MakeParameter("alirootBranch",
603 AliForwardUtil::AliROOTBranch()));
e65b8b56 604 fList->Add(AliForwardUtil::MakeParameter("mc", fMC));
1ff25622 605
f7cfc454 606}
607
c8b1a7db 608//____________________________________________________________________
609void
610AliFMDEventInspector::StoreProduction()
611{
612 if (!fList) return;
613
614 AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
615 AliVEventHandler *inputHandler=mgr->GetInputEventHandler();
616 if (!inputHandler) {
617 AliWarning("Got no input handler");
618 return;
619 }
620 TList *uiList = inputHandler->GetUserInfo();
621 if (!uiList) {
622 AliWarning("Got no user list from input tree");
623 return;
624 }
625
626 AliProdInfo p(uiList);
627 p.List();
628 if (p.GetAlirootSvnVersion() <= 0) return;
629
630 // Make our output list
631 TList* out = new TList;
632 out->SetOwner(true);
633 out->SetName("production");
634 // out->SetTitle("ESD production details");
635 fList->Add(out);
636
637 TString period = p.GetLHCPeriod();
638 // TString aliROOTVersion = p.GetAlirootVersion();
0b7de667 639 fProdSVN = p.GetAlirootSvnVersion();
c8b1a7db 640 // TString rootVersion = p.GetRootVersion();
641 Int_t rootSVN = p.GetRootSvnVersion();
0b7de667 642 fProdPass = p.GetRecoPass();
643 fProdMC = p.IsMC();
0e8bd15f
AH
644
645 if (period.Length() > 0) {
646 TObjArray* pp = TPRegexp("LHC([0-9]+)([a-z]+)").MatchS(period);
647 fProdYear = static_cast<TObjString*>(pp->At(1))->String().Atoi();
648 fProdLetter = static_cast<TObjString*>(pp->At(2))->String()[0];
649 pp->Delete();
650 }
c8b1a7db 651
0b7de667 652 out->Add(AliForwardUtil::MakeParameter("year", fProdYear));
653 out->Add(AliForwardUtil::MakeParameter("letter", Int_t(fProdLetter)));
654 out->Add(AliForwardUtil::MakeParameter("alirootSVN", fProdSVN));
c8b1a7db 655 out->Add(AliForwardUtil::MakeParameter("rootSVN", rootSVN));
0b7de667 656 out->Add(AliForwardUtil::MakeParameter("pass", fProdPass));
657 out->Add(AliForwardUtil::MakeParameter("mc", fProdMC));
c8b1a7db 658}
659
660
661
662
8565b10b 663//____________________________________________________________________
664void
5934a3e3 665AliFMDEventInspector::CreateOutputObjects(TList* dir)
8565b10b 666{
7984e5f7 667 //
668 // Define the output histograms. These are put in a sub list of the
669 // passed list. The histograms are merged before the parent task calls
670 // AliAnalysisTaskSE::Terminate
671 //
672 // dir Directory to add to
673 //
6ab100ec 674 DGUARD(fDebug,1,"Define output from AliFMDEventInspector");
8565b10b 675 fList = new TList;
676 fList->SetName(GetName());
c929bc03 677 fList->SetOwner();
8565b10b 678 dir->Add(fList);
679}
680
681//____________________________________________________________________
682UInt_t
683AliFMDEventInspector::Process(const AliESDEvent* event,
684 UInt_t& triggers,
685 Bool_t& lowFlux,
0bd4b00f 686 UShort_t& ivz,
5ca83fee 687 TVector3& ip,
5bb5d1f6 688 Double_t& cent,
689 UShort_t& nClusters)
8565b10b 690{
7984e5f7 691 //
692 // Process the event
693 //
694 // Parameters:
695 // event Input event
696 // triggers On return, the triggers fired
697 // lowFlux On return, true if the event is considered a low-flux
698 // event (according to the setting of fLowFluxCut)
699 // ivz On return, the found vertex bin (1-based). A zero
700 // means outside of the defined vertex range
701 // vz On return, the z position of the interaction
5e4d905e 702 // cent On return, the centrality - if not available < 0
7984e5f7 703 //
704 // Return:
705 // 0 (or kOk) on success, otherwise a bit mask of error codes
706 //
4f9319f3 707 DGUARD(fDebug,1,"Process event in AliFMDEventInspector");
e1f47419 708 // --- Check that we have an event ---------------------------------
8565b10b 709 if (!event) {
710 AliWarning("No ESD event found for input event");
241cca4d 711 fHStatus->Fill(2);
8565b10b 712 return kNoEvent;
713 }
714
bfab35d9 715 // --- Process satellite event information is requested ------------
716 if (fUseDisplacedVertices) {
717 if (!fDisplacedVertex.Process(event))
718 AliWarning("Failed to process satellite event");
719 }
720
e1f47419 721 // --- Read trigger information from the ESD and store in AOD object
241cca4d 722 if (!ReadTriggers(*event, triggers, nClusters)) {
0bd4b00f 723 if (fDebug > 2) {
724 AliWarning("Failed to read triggers from ESD"); }
241cca4d 725 fHStatus->Fill(3);
8565b10b 726 return kNoTriggers;
727 }
728
e1f47419 729 // --- Check if this is a high-flux event --------------------------
8565b10b 730 const AliMultiplicity* testmult = event->GetMultiplicity();
731 if (!testmult) {
0bd4b00f 732 if (fDebug > 3) {
733 AliWarning("No central multiplicity object found"); }
8565b10b 734 }
e1f47419 735 else
736 lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
5e4d905e 737
0bd4b00f 738 fHType->Fill(lowFlux ? 0 : 1);
314f6077 739
740 // --- Get the interaction point -----------------------------------
741 Bool_t vzOk = ReadVertex(*event, ip);
742 fHEventsTr->Fill(ip.Z());
743 if (!vzOk) {
744 if (fDebug > 3) {
745 AliWarning("Failed to read vertex from ESD"); }
746 fHStatus->Fill(6);
747 return kNoVertex;
748 }
749
750 // --- Read centrality information
e308a636 751 cent = -10;
752 UShort_t qual = 0;
241cca4d 753 if (!ReadCentrality(*event, cent, qual)) {
e1f47419 754 if (fDebug > 3)
755 AliWarning("Failed to get centrality");
8565b10b 756 }
314f6077 757 // --- check centrality cut
4f9319f3 758
8449e3e0 759 if(fMinCent > -0.0001 && cent < fMinCent) return kNoEvent;
760 if(fMaxCent > -0.0001 && cent > fMaxCent) return kNoEvent;
77f97e3f 761 if (cent >= 0) fHCent->Fill(cent);
e308a636 762 if (qual == 0) fHCentVsQual->Fill(0., cent);
763 else {
77f97e3f 764 fHStatus->Fill(8);
e308a636 765 for (UShort_t i = 0; i < 4; i++)
766 if (qual & (1 << i)) fHCentVsQual->Fill(Double_t(i+1), cent);
767 }
314f6077 768
8565b10b 769
5ca83fee 770 fHEventsTrVtx->Fill(ip.Z());
96110c91 771
e1f47419 772 // --- Get the vertex bin ------------------------------------------
5ca83fee 773 ivz = fVtxAxis.FindBin(ip.Z());
5bb5d1f6 774 if (ivz <= 0 || ivz > fVtxAxis.GetNbins()) {
0bd4b00f 775 if (fDebug > 3) {
8565b10b 776 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
5ca83fee 777 ip.Z(), fVtxAxis.GetXmin(), fVtxAxis.GetXmax()));
5bb5d1f6 778 }
0bd4b00f 779 ivz = 0;
241cca4d 780 fHStatus->Fill(7);
8565b10b 781 return kBadVertex;
782 }
5ca83fee 783 fHEventsAccepted->Fill(ip.Z());
784 fHEventsAcceptedXY->Fill(ip.X(),ip.Y());
e58000b7 785
e1f47419 786 // --- Check the FMD ESD data --------------------------------------
787 if (!event->GetFMDData()) {
788 if (fDebug > 3) {
789 AliWarning("No FMD data found in ESD"); }
241cca4d 790 fHStatus->Fill(5);
e1f47419 791 return kNoFMD;
792 }
793
241cca4d 794 fHStatus->Fill(1);
8565b10b 795 return kOk;
796}
797
e1f47419 798//____________________________________________________________________
799Bool_t
241cca4d 800AliFMDEventInspector::ReadCentrality(const AliESDEvent& esd,
e308a636 801 Double_t& cent,
802 UShort_t& qual) const
e1f47419 803{
804 //
805 // Read centrality from event
806 //
807 // Parameters:
808 // esd Event
809 // cent On return, the centrality or negative if not found
810 //
811 // Return:
812 // False on error, true otherwise
813 //
6ab100ec 814 DGUARD(fDebug,2,"Read the centrality in AliFMDEventInspector");
241cca4d 815
241cca4d 816 cent = -1;
8449e3e0 817 qual = 1;
241cca4d 818 AliCentrality* centObj = const_cast<AliESDEvent&>(esd).GetCentrality();
8449e3e0 819 if (centObj) {
820 cent = centObj->GetCentralityPercentile(fCentMethod);
821 qual = centObj->GetQuality();
822 }
241cca4d 823
bc31b177 824 // We overwrite with satellite events, so we can be sure to get the
825 // centrality determination from the satellite vertex selection
826 if (fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
8449e3e0 827 cent = fDisplacedVertex.GetCentralityPercentile();
828 qual = 0;
829 }
e1f47419 830
831 return true;
832}
833
da70cd6a 834//____________________________________________________________________
835Bool_t
836AliFMDEventInspector::CheckpAExtraV0(const AliESDEvent& esd) const
837{
838 if (fCollisionSystem != AliForwardUtil::kPPb) return true;
839
840 AliVVZERO* esdV0 = esd.GetVZEROData();
841 if ((esdV0->GetV0ADecision()!=1) || (esdV0->GetV0CDecision()!=1))
842 return false;
843 return true;
844}
845
8565b10b 846//____________________________________________________________________
847Bool_t
241cca4d 848AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
5bb5d1f6 849 UShort_t& nClusters)
8565b10b 850{
7984e5f7 851 //
852 // Read the trigger information from the ESD event
853 //
854 // Parameters:
855 // esd ESD event
856 // triggers On return, contains the trigger bits
857 //
858 // Return:
859 // @c true on success, @c false otherwise
860 //
6ab100ec 861 DGUARD(fDebug,2,"Read the triggers in AliFMDEventInspector");
8565b10b 862 triggers = 0;
863
864 // Get the analysis manager - should always be there
865 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
241cca4d 866 DMSG(fDebug,10,"Got analysis manager %p", am);
8565b10b 867 if (!am) {
868 AliWarning("No analysis manager defined!");
869 return kFALSE;
870 }
871
872 // Get the input handler - should always be there
873 AliInputEventHandler* ih =
874 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
241cca4d 875 DMSG(fDebug,10,"Got input handler %p", ih);
8565b10b 876 if (!ih) {
877 AliWarning("No input handler");
878 return kFALSE;
879 }
e85a76b7 880
e1f47419 881 // Check if this is a collision candidate (MB)
8449e3e0 882 ///
883 // Historic remark: Note, that we should use the value cached in the
884 // input handler rather than calling IsCollisionCandiate directly
885 // on the AliPhysicsSelection obejct. If we called the latter
886 // then the AliPhysicsSelection object would overcount by a factor
887 // of 2! :-(
888 UInt_t trgMask = ih->IsEventSelected();
889 Bool_t offline = trgMask;
890 Bool_t fastonly = (trgMask & AliVEvent::kFastOnly);
241cca4d 891 TString trigStr = esd.GetFiredTriggerClasses();
892
8449e3e0 893 if (trigStr.IsNull()) fHTrgStatus->Fill(kNoTrgWords);
241cca4d 894 if (fHWords) fHWords->Fill(trigStr.Data(), 1);
11d40ecb 895
241cca4d 896 if(fUseDisplacedVertices) {
897 DMSG(fDebug,3,"Using displaced vertex stuff");
8449e3e0 898 // if (TMath::Abs(fDisplacedVertex.GetVertexZ()) >= 999) offline = false;
899 if (fDisplacedVertex.IsSatellite())
900 triggers |= AliAODForwardMult::kSatellite;
901 }
902
903 if (CheckFastPartition(fastonly)) {
904 fHTrgStatus->Fill(kPP2760Fast);
905 offline = false;
241cca4d 906 }
65abd48b 907
8449e3e0 908 if (offline && CheckCosmics(trigStr)) {
909 fHTrgStatus->Fill(kMUON);
910 offline = false;
911 }
912 if (offline) fHTrgStatus->Fill(kTriggered);
913 Int_t f = 0;
914 if (trgMask & AliVEvent::kMB) f += fHTrgStatus->Fill(kMinBias);
915 if (trgMask & AliVEvent::kCINT5) f += fHTrgStatus->Fill(kMinBiasNoSPD);
916 if (trgMask & AliVEvent::kINT7) f += fHTrgStatus->Fill(kV0AndTrg);
917 if (trgMask & AliVEvent::kHighMult) f += fHTrgStatus->Fill(kHighMult);
918 if (trgMask & AliVEvent::kCentral) f += fHTrgStatus->Fill(kCentral);
919 if (trgMask & AliVEvent::kSemiCentral) f += fHTrgStatus->Fill(kSemiCentral);
920 if (trgMask & AliVEvent::kDG5) f += fHTrgStatus->Fill(kDiffractive);
921 if (trgMask & AliVEvent::kUserDefined) f += fHTrgStatus->Fill(kUser);
922 if (f <= 0) fHTrgStatus->Fill(kOther);
923
c929bc03 924 // if (!CheckpAExtraV0(esd)) offline = false;
241cca4d 925
926 DMSG(fDebug,2,"Event is %striggered by off-line", offline ? "" : "NOT ");
927
dd556bcd 928 if (offline) triggers |= AliAODForwardMult::kOffline;
929 // Only flag as in-elastic if a min-bias trigger is here
930 if (trgMask & AliVEvent::kMB) {
241cca4d 931 triggers |= AliAODForwardMult::kInel;
241cca4d 932 CheckINELGT0(esd, nClusters, triggers);
65abd48b 933 }
934
241cca4d 935 CheckNSD(esd,triggers);
cd51b0dd 936 CheckPileup(esd, triggers);
937 CheckEmpty(trigStr, triggers);
938 // if (CheckPileup(esd, triggers)) fHTriggers->Fill(kPileUp+.5);
939 // if (CheckEmpty(trigStr, triggers)) fHTriggers->Fill(kEmpty+.5);
241cca4d 940
8449e3e0 941 CheckWords(esd, triggers);
241cca4d 942
66cf95f2 943#define TEST_TRIG_BIN(RET,BIN,TRIGGERS) \
944 do { switch (BIN) { \
8449e3e0 945 case kInel: RET = triggers & AliAODForwardMult::kInel; break; \
946 case kInelGt0: RET = triggers & AliAODForwardMult::kInelGt0; break; \
947 case kNSD: RET = triggers & AliAODForwardMult::kNSD; break; \
948 case kV0AND: RET = triggers & AliAODForwardMult::kV0AND; break; \
949 case kEmpty: RET = triggers & AliAODForwardMult::kEmpty; break; \
950 case kA: RET = triggers & AliAODForwardMult::kA; break; \
951 case kB: RET = triggers & AliAODForwardMult::kB; break; \
952 case kC: RET = triggers & AliAODForwardMult::kC; break; \
953 case kE: RET = triggers & AliAODForwardMult::kE; break; \
954 case kPileUp: RET = triggers & AliAODForwardMult::kPileUp; break; \
955 case kMCNSD: RET = triggers & AliAODForwardMult::kMCNSD; break; \
956 case kSatellite:RET = triggers & AliAODForwardMult::kSatellite; break; \
957 case kOffline: RET = triggers & AliAODForwardMult::kOffline; break; \
958 default: RET = false; } } while(false)
66cf95f2 959
8449e3e0 960 if (!fHTriggers) {
961 AliWarning("Histogram of triggers not defined - has init been called");
962 return false;
963 }
241cca4d 964
66cf95f2 965 for (Int_t i = 0; i < kOffline+1; i++) {
966 Bool_t hasX = false;
967 TEST_TRIG_BIN(hasX, i, triggers);
968 if (!hasX) continue;
cd51b0dd 969 fHTriggers->Fill(i+.5);
970 for (Int_t j = 0; j < kOffline+1; j++) {
66cf95f2 971 Bool_t hasY = false;
972 TEST_TRIG_BIN(hasY, j, triggers);
973 if (!hasY) continue;
974
975 fHTriggerCorr->Fill(i+.5, j+.5);
976 }
977 }
241cca4d 978 return kTRUE;
979}
980
981//____________________________________________________________________
982Bool_t
983AliFMDEventInspector::CheckFastPartition(bool fastonly) const
984{
11d40ecb 985 // For the 2.76 TeV p+p run, the FMD ran in the slow partition
986 // so it received no triggers from the fast partition. Therefore
987 // the fast triggers are removed here but not for MC where all
988 // triggers are fast.
241cca4d 989 if (TMath::Abs(fEnergy - 2750.) > 20) return false;
990 if (fCollisionSystem != AliForwardUtil::kPP) return false;
e65b8b56 991 if (fMC) return false; // All MC events for pp @ 2.76TeV are `fast'
241cca4d 992 if (fastonly)
993 DMSG(fDebug,1,"Fast trigger in pp @ sqrt(s)=2.76TeV removed");
994
995 return fastonly;
996}
997
998//____________________________________________________________________
999Bool_t
1000AliFMDEventInspector::CheckCosmics(const TString& trigStr) const
1001{
1002 // MUON triggers are not strictly minimum bias (MB) so they are
1003 // removed (HHD)
1004 if(trigStr.Contains("CMUS1")) {
1005 DMSG(fDebug,1,"Cosmic trigger ins't min-bias, removed");
1006 return true;
1007 }
1008 return false;
1009}
1010
1011//____________________________________________________________________
1012Bool_t
1013AliFMDEventInspector::CheckINELGT0(const AliESDEvent& esd,
1014 UShort_t& nClusters,
1015 UInt_t& triggers) const
1016{
5bb5d1f6 1017 nClusters = 0;
8565b10b 1018
241cca4d 1019 // If this is inel, see if we have a tracklet
1020 const AliMultiplicity* spdmult = esd.GetMultiplicity();
1021 if (!spdmult) {
1022 AliWarning("No SPD multiplicity");
1023 return false;
1024 }
1025
1026 // Check if we have one or more tracklets
1027 // in the range -1 < eta < 1 to set the INEL>0
1028 // trigger flag.
1029 //
1030 // Also count tracklets as a single cluster
1031 Int_t n = spdmult->GetNumberOfTracklets();
1032 for (Int_t j = 0; j < n; j++) {
dd556bcd 1033 if(TMath::Abs(spdmult->GetEta(j)) < 1) nClusters++;
8565b10b 1034 }
dd556bcd 1035 // If we at this point had non-zero nClusters, it's INEL>0
1036 if (nClusters > 0) triggers |= AliAODForwardMult::kInelGt0;
1037
1038 // Loop over single clusters
241cca4d 1039 n = spdmult->GetNumberOfSingleClusters();
1040 for (Int_t j = 0; j < n; j++) {
1041 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
1042 if (TMath::Abs(eta) < 1) nClusters++;
1043 }
1044 if (nClusters > 0) triggers |= AliAODForwardMult::kNClusterGt0;
1045
1046 return triggers & AliAODForwardMult::kNClusterGt0;
1047}
1048
1049//____________________________________________________________________
1050Bool_t
1051AliFMDEventInspector::CheckNSD(const AliESDEvent& esd, UInt_t& triggers) const
1052{
8565b10b 1053 // Analyse some trigger stuff
1054 AliTriggerAnalysis ta;
241cca4d 1055 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kV0AND)) {
e6463868 1056 triggers |= AliAODForwardMult::kV0AND;
1057 if (fUseV0AND)
31554871 1058 triggers |= AliAODForwardMult::kNSD;
1059 }
241cca4d 1060 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kNSD1))
e6463868 1061 triggers |= AliAODForwardMult::kNSD;
241cca4d 1062 return triggers & AliAODForwardMult::kNSD;
1063}
1064//____________________________________________________________________
1065Bool_t
1066AliFMDEventInspector::CheckPileup(const AliESDEvent& esd,
1067 UInt_t& triggers) const
1068{
5bb5d1f6 1069 // Check for multiple vertices (pile-up) with at least 3
1070 // contributors and at least 0.8cm from the primary vertex
dd556bcd 1071 // if(fCollisionSystem != AliForwardUtil::kPP) return false;
1072
1073 // Check for standard SPD pile-up
1074 Bool_t spdPileup = esd.IsPileupFromSPD(fMinPileupContrib,fMinPileupDistance);
241cca4d 1075
dd556bcd 1076 // Check for multi-vertex pileup
1077 Bool_t mvPileup = false; // CheckMultiVertex(esd);
1078
1079 // Check for out-of-bunch pileup
1080 Bool_t outPileup = (esd.GetHeader()->GetIRInt2ClosestInteractionMap() != 0 ||
1081 esd.GetHeader()->GetIRInt1ClosestInteractionMap() != 0);
1082
1083 // Our result
1084 Bool_t pileup = spdPileup || mvPileup || outPileup;
241cca4d 1085 if (pileup) triggers |= AliAODForwardMult::kPileUp;
1086 return pileup;
1087}
1088
dd556bcd 1089//____________________________________________________________________
1090Bool_t
c8b1a7db 1091AliFMDEventInspector::CheckMultiVertex(const AliESDEvent& esd,
1092 Bool_t checkOtherBC) const
dd556bcd 1093{
1094 // Adapted from AliAnalysisUtils
1095 //
1096 // Parameters
1097 const Double_t maxChi2nu = 5;
dd556bcd 1098
1099 // Number of vertices
1100 Int_t n = esd.GetNumberOfPileupVerticesTracks();
1101 if (n < 1)
1102 // No additional vertices from tracks -> no pileup
1103 return false;
1104
1105 // Primary vertex
1106 const AliESDVertex* primary = esd.GetPrimaryVertexTracks();
1107 if (primary->GetStatus() != 1)
1108 // No good primary vertex, but many candidates -> pileup
1109 return true;
1110
1111 // Bunch crossing number
1112 Int_t bcPrimary = primary->GetBC();
1113
1114 for (Int_t i = 0; i < n; i++) {
1115 const AliESDVertex* other = esd.GetPileupVertexTracks(i);
1116
1117 if (other->GetNContributors() < fMinPileupContrib)
1118 // Not enough contributors to this vertex
1119 continue;
1120
1121 if (other->GetChi2perNDF() > maxChi2nu)
1122 // Poorly determined vertex
1123 continue;
1124 if (checkOtherBC) {
1125 Int_t bcOther = other->GetBC();
1126 if (bcOther != AliVTrack::kTOFBCNA && TMath::Abs(bcOther-bcPrimary) > 2)
1127 // Pile-up from other BC
1128 return true;
1129 }
1130 // Calculate the distance
1131 Double_t d = -1;
1132 Double_t dx = primary->GetX() - other->GetX();
1133 Double_t dy = primary->GetY() - other->GetY();
1134 Double_t dz = primary->GetZ() - other->GetZ();
1135 Double_t covPrimary[6], covOther[6];
1136 primary->GetCovarianceMatrix(covPrimary);
1137 other->GetCovarianceMatrix(covOther);
1138 TMatrixDSym v(3);
1139 v(0,0) = covPrimary[0] + covOther[0]; // diagonal
1140 v(1,1) = covPrimary[2] + covOther[2]; // diagonal
1141 v(2,2) = covPrimary[5] + covOther[5]; // diagonal
1142 v(1,0) = v(0,1) = covPrimary[1]+covOther[1]; // Band
1143 v(0,2) = v(1,2) = v(2,0) = v(2,1) = 0; // Off-diagonal+band
1144 // Try to invert
1145 v.InvertFast();
1146 if (!v.IsValid())
1147 // Question if kStatus bit is every set after InvertFast?
1148 continue;
1149 d = (v(0,0) * dx * dx + v(1,1) * dy * dy + v(2,2) * dz * dz +
1150 2 * (v(0,1) * dx * dy + v(0,2) * dx * dz + v(1,2) * dy * dz));
1151
1152 if (d < 0 || TMath::Sqrt(d) < fMinPileupDistance)
1153 // Bad distance, or not fare enough from each other
1154 continue;
1155
1156 // Well separated vertices -> pileup
1157 return true;
1158 }
1159 return false;
1160}
1161
241cca4d 1162//____________________________________________________________________
1163Bool_t
1164AliFMDEventInspector::CheckEmpty(const TString& trigStr, UInt_t& triggers) const
1165{
8565b10b 1166 if (trigStr.Contains("CBEAMB-ABCE-NOPF-ALL")) {
1167 triggers |= AliAODForwardMult::kEmpty;
241cca4d 1168 return true;
8565b10b 1169 }
241cca4d 1170 return false;
1171}
1172//____________________________________________________________________
1173Bool_t
1174AliFMDEventInspector::CheckWords(const AliESDEvent& esd, UInt_t& triggers) const
1175{
1176 TObject* word = 0;
1177 TIter nextColl(&fCollWords);
1178 while ((word = nextColl())) {
1179 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1180 word->GetTitle(), word->GetName());
1181 if (!esd.IsTriggerClassFired(word->GetName())) continue;
8565b10b 1182
241cca4d 1183 TString beamSide = word->GetTitle();
1184 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
e85a76b7 1185
241cca4d 1186 if (!beamSide.EqualTo("B")) continue;
1187 triggers |= AliAODForwardMult::kB;
1188 break; // No more to do here
e85a76b7 1189 }
241cca4d 1190 TIter nextBg(&fBgWords);
1191 UInt_t all = (AliAODForwardMult::kA |
1192 AliAODForwardMult::kC |
1193 AliAODForwardMult::kE);
1194 while ((word = nextBg())) {
1195 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1196 word->GetTitle(), word->GetName());
1197 if (!esd.IsTriggerClassFired(word->GetName())) continue;
0be6c8cd 1198
241cca4d 1199 TString beamSide = word->GetTitle();
1200 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
e6463868 1201
241cca4d 1202 if (beamSide.Contains("A")) triggers |= AliAODForwardMult::kA;
1203 if (beamSide.Contains("C")) triggers |= AliAODForwardMult::kC;
1204 if (beamSide.Contains("E")) triggers |= AliAODForwardMult::kE;
1205
1206 if ((triggers & all) == all) break; // No more to do
0be6c8cd 1207 }
241cca4d 1208 return true;
8565b10b 1209}
241cca4d 1210
1211
8565b10b 1212//____________________________________________________________________
1213Bool_t
5ca83fee 1214AliFMDEventInspector::ReadVertex(const AliESDEvent& esd, TVector3& ip)
8565b10b 1215{
7984e5f7 1216 //
1217 // Read the vertex information from the ESD event
1218 //
1219 // Parameters:
1220 // esd ESD event
1221 // vz On return, the vertex Z position
1222 //
1223 // Return:
1224 // @c true on success, @c false otherwise
1225 //
6ab100ec 1226 DGUARD(fDebug,2,"Read the vertex in AliFMDEventInspector");
5ca83fee 1227 ip.SetXYZ(1024, 1024, 0);
65abd48b 1228
8449e3e0 1229 EVtxStatus s = kNoVtx;
bfab35d9 1230 if (fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
1231 s = kVtxOK;
1232 ip.SetZ(fDisplacedVertex.GetVertexZ());
1233 }
1234 else if (fUseFirstPhysicsVertex)
8449e3e0 1235 s = CheckPWGUDVertex(esd, ip);
1236 else if (fUsepA2012Vertex)
1237 s = CheckpA2012Vertex(esd,ip);
1238 else
1239 s = CheckVertex(esd, ip);
1240
8449e3e0 1241 fHVtxStatus->Fill(s);
1242
1243 return s == kVtxOK;
241cca4d 1244}
1245
1246//____________________________________________________________________
8449e3e0 1247AliFMDEventInspector::EVtxStatus
241cca4d 1248AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
5ca83fee 1249 TVector3& ip) const
241cca4d 1250{
1251 // This is the code used by the 1st physics people
1252 const AliESDVertex* vertex = esd.GetPrimaryVertex();
1253 if (!vertex || !vertex->GetStatus()) {
1254 DMSG(fDebug,2,"No primary vertex (%p) or bad status %d",
1255 vertex, (vertex ? vertex->GetStatus() : -1));
8449e3e0 1256 return kNoVtx;
241cca4d 1257 }
1258 const AliESDVertex* vertexSPD = esd.GetPrimaryVertexSPD();
1259 if (!vertexSPD || !vertexSPD->GetStatus()) {
1260 DMSG(fDebug,2,"No primary SPD vertex (%p) or bad status %d",
1261 vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1));
8449e3e0 1262 return kNoSPDVtx;
241cca4d 1263 }
96110c91 1264
241cca4d 1265 // if vertex is from SPD vertexZ, require more stringent cuts
1266 if (vertex->IsFromVertexerZ()) {
1267 if (vertex->GetDispersion() > fMaxVzErr ||
1268 vertex->GetZRes() > 1.25 * fMaxVzErr) {
1269 DMSG(fDebug,2,"Dispersion %f > %f or resolution %f > %f",
1270 vertex->GetDispersion(), fMaxVzErr,
1271 vertex->GetZRes(), 1.25 * fMaxVzErr);
8449e3e0 1272 return kUncertain;
96110c91 1273 }
96110c91 1274 }
5ca83fee 1275 ip.SetZ(vertex->GetZ());
241cca4d 1276
1277 if(!vertex->IsFromVertexerZ()) {
5ca83fee 1278 ip.SetX(vertex->GetX());
1279 ip.SetY(vertex->GetY());
241cca4d 1280 }
8449e3e0 1281 return kVtxOK;
241cca4d 1282}
8449e3e0 1283//____________________________________________________________________
1284AliFMDEventInspector::EVtxStatus
1285AliFMDEventInspector::CheckpA2012Vertex(const AliESDEvent& esd,
1286 TVector3& ip) const
ffd35d33 1287{
8449e3e0 1288 const AliESDVertex *vertex = esd.GetPrimaryVertexSPD();
1289 if (!vertex) return kNoSPDVtx;
1290 if (vertex->GetNContributors() <= 0) return kFewContrib;
1291
1292 TString vtxTyp = vertex->GetTitle();
1293 if (vtxTyp.Contains("vertexer: Z")) return kNotVtxZ;
1294
1295 if (vertex->GetDispersion() >= 0.04 || vertex->GetZRes()>=0.25)
1296 return kUncertain;
1297
1298 ip.SetX(vertex->GetX());
1299 ip.SetY(vertex->GetY());
1300 ip.SetZ(vertex->GetZ());
1301
1302 return kVtxOK;
ffd35d33 1303}
1304
241cca4d 1305//____________________________________________________________________
8449e3e0 1306AliFMDEventInspector::EVtxStatus
241cca4d 1307AliFMDEventInspector::CheckVertex(const AliESDEvent& esd,
5ca83fee 1308 TVector3& ip) const
241cca4d 1309{
1310 // Use standard SPD vertex (perhaps preferable for Pb+Pb)
1311 // Get the vertex
1312 const AliESDVertex* vertex = esd.GetPrimaryVertexSPD();
1313 if (!vertex) {
1314 if (fDebug > 2) {
1315 AliWarning("No SPD vertex found in ESD"); }
8449e3e0 1316 return kNoSPDVtx;
241cca4d 1317 }
e83d0620 1318
8449e3e0 1319 // #if 0 // Check disabled - seem to kill a lot of PbPb events
241cca4d 1320 // Check that enough tracklets contributed
1321 if(vertex->GetNContributors() <= 0) {
1322 DMSG(fDebug,2,"Number of contributors to vertex is %d<=0",
1323 vertex->GetNContributors());
5ca83fee 1324 ip.SetZ(0);
8449e3e0 1325 return kFewContrib;
241cca4d 1326 }
8449e3e0 1327 // #endif
1328
241cca4d 1329 // Check that the uncertainty isn't too large
1330 if (vertex->GetZRes() > fMaxVzErr) {
1331 DMSG(fDebug,2,"Uncertaintity in Z of vertex is too large %f > %f",
1332 vertex->GetZRes(), fMaxVzErr);
8449e3e0 1333 return kUncertain;
241cca4d 1334 }
e83d0620 1335
241cca4d 1336 // Get the z coordiante
5ca83fee 1337 ip.SetZ(vertex->GetZ());
241cca4d 1338 const AliESDVertex* vertexXY = esd.GetPrimaryVertex();
96110c91 1339
5ca83fee 1340
241cca4d 1341 if(!vertexXY->IsFromVertexerZ()) {
5ca83fee 1342 ip.SetX(vertexXY->GetX());
1343 ip.SetY(vertexXY->GetY());
241cca4d 1344 }
8449e3e0 1345 return kVtxOK;
8565b10b 1346}
241cca4d 1347
0bd4b00f 1348//____________________________________________________________________
1349Bool_t
1350AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
1351{
7984e5f7 1352 //
1353 // Read the collision system, collision energy, and L3 field setting
1354 // from the ESD
1355 //
1356 // Parameters:
1357 // esd ESD to get information from
1358 //
1359 // Return:
1360 // true on success, false
1361 //
cc83fca2 1362 // AliInfo(Form("Parameters from 1st ESD event: cms=%s, sNN=%f, field=%f",
1363 // esd->GetBeamType(), 2*esd->GetBeamEnergy(),
1364 // esd->GetMagneticField()));
6ab100ec 1365 DGUARD(fDebug,2,"Read the run details in AliFMDEventInspector");
d4d486f8 1366 const char* sys = esd->GetBeamType();
1367 Float_t cms = 2 * esd->GetBeamEnergy();
1368 Float_t fld = esd->GetMagneticField();
1369 fCollisionSystem = AliForwardUtil::ParseCollisionSystem(sys);
1370 fEnergy = AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,
1371 cms);
1372 fField = AliForwardUtil::ParseMagneticField(fld);
8449e3e0 1373 fRunNumber = esd->GetRunNumber();
c8b1a7db 1374 StoreProduction();
8449e3e0 1375 StoreInformation();
d4d486f8 1376 if (fCollisionSystem == AliForwardUtil::kUnknown) {
1377 AliWarningF("Unknown collision system: %s - please check", sys);
1378 return false;
1379 }
1380 if (fEnergy <= 0) {
1381 AliWarningF("Unknown CMS energy: %f (%d) - please check", cms, fEnergy);
1382 return false;
1383 }
1384 if (TMath::Abs(fField) > 10) {
1385 AliWarningF("Unknown L3 field setting: %f (%d) - please check", fld,fField);
1386 return false;
1387 }
0bd4b00f 1388
d4d486f8 1389 return true;
0bd4b00f 1390}
1391
241cca4d 1392
1393//____________________________________________________________________
1394const Char_t*
1395AliFMDEventInspector::CodeString(UInt_t code)
1396{
1397 static TString s;
1398 s = "";
1399 if (code & kNoEvent) s.Append("NOEVENT ");
1400 if (code & kNoTriggers) s.Append("NOTRIGGERS ");
1401 if (code & kNoSPD) s.Append("NOSPD ");
1402 if (code & kNoFMD) s.Append("NOFMD ");
1403 if (code & kNoVertex) s.Append("NOVERTEX ");
1404 if (code & kBadVertex) s.Append("BADVERTEX ");
1405 return s.Data();
1406}
c8b1a7db 1407#define PF(N,V,...) \
1408 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
1409#define PFB(N,FLAG) \
1410 do { \
1411 AliForwardUtil::PrintName(N); \
1412 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
1413 } while(false)
1414#define PFV(N,VALUE) \
1415 do { \
1416 AliForwardUtil::PrintName(N); \
1417 std::cout << (VALUE) << std::endl; } while(false)
1418
0bd4b00f 1419//____________________________________________________________________
1420void
1421AliFMDEventInspector::Print(Option_t*) const
1422{
7984e5f7 1423 //
1424 // Print information
1425 //
1426 // option Not used
1427 //
c8b1a7db 1428 AliForwardUtil::PrintTask(*this);
0bd4b00f 1429 TString sNN(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
1430 sNN.Strip(TString::kBoth, '0');
1431 sNN.ReplaceAll("GeV", " GeV");
1432 TString field(AliForwardUtil::MagneticFieldString(fField));
1433 field.ReplaceAll("p", "+");
1434 field.ReplaceAll("m", "-");
1435 field.ReplaceAll("kG", " kG");
c8b1a7db 1436
1437 gROOT->IncreaseDirLevel();
0b7de667 1438 PFV("Production", "");
1439 gROOT->IncreaseDirLevel();
1440 PF("Period", "LHC%02d%c", fProdYear, fProdLetter);
1441 PFB("MC anchor", fProdMC);
1442 PFV("AliROOT Revision", fProdSVN);
1443 gROOT->DecreaseDirLevel();
c8b1a7db 1444 PFV("Vertex bins", fVtxAxis.GetNbins());
1445 PF("Vertex Range", "[%+6.1f,%+6.1f]", fVtxAxis.GetXmin(), fVtxAxis.GetXmax());
1446 PFV("Low flux cut", fLowFluxCut );
1447 PFV("Max(delta v_z)", fMaxVzErr );
1448 PFV("Min(nContrib_pileup)", fMinPileupContrib );
1449 PFV("Min(v-pileup)", fMinPileupDistance );
1450 PFV("System", AliForwardUtil::CollisionSystemString(fCollisionSystem));
1451 PFV("CMS energy per nucleon", sNN);
1452 PFV("Field", field);
1453 PFB("Satellite events", fUseDisplacedVertices);
1454 PFB("Use 2012 pA vertex", fUsepA2012Vertex );
1455 PFB("Use PWG-UD vertex", fUseFirstPhysicsVertex);
1456 PFB("Simulation input", fMC );
1457 PFV("Centrality method", fCentMethod);
1458 PFV("Centrality axis", (!fCentAxis ? "none" : ""));
1459 if (!fCentAxis) {return; }
d8244e9e 1460 Int_t nBin = fCentAxis->GetNbins();
d8244e9e 1461 for (Int_t i = 0; i < nBin; i++) {
0b7de667 1462 if (i != 0 && (i % 10) == 0) std::cout << '\n';
1463 if ((i % 10) == 0) std::cout << " ";
d8244e9e 1464 std::cout << std::setw(5) << fCentAxis->GetBinLowEdge(i+1) << '-';
1465 }
1466 std::cout << std::setw(5) << fCentAxis->GetBinUpEdge(nBin) << std::endl;
c8b1a7db 1467 gROOT->DecreaseDirLevel();
0bd4b00f 1468}
1469
1470
8565b10b 1471//
1472// EOF
1473//
1474