]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliFMDEventInspector.cxx
changed name of add task macro. git test.
[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();
c8b1a7db 644
645 TObjArray* pp = TPRegexp("LHC([0-9]+)([a-z]+)").MatchS(period);
0b7de667 646 fProdYear = static_cast<TObjString*>(pp->At(1))->String().Atoi();
647 fProdLetter = static_cast<TObjString*>(pp->At(2))->String()[0];
c8b1a7db 648 pp->Delete();
649
0b7de667 650 out->Add(AliForwardUtil::MakeParameter("year", fProdYear));
651 out->Add(AliForwardUtil::MakeParameter("letter", Int_t(fProdLetter)));
652 out->Add(AliForwardUtil::MakeParameter("alirootSVN", fProdSVN));
c8b1a7db 653 out->Add(AliForwardUtil::MakeParameter("rootSVN", rootSVN));
0b7de667 654 out->Add(AliForwardUtil::MakeParameter("pass", fProdPass));
655 out->Add(AliForwardUtil::MakeParameter("mc", fProdMC));
c8b1a7db 656}
657
658
659
660
8565b10b 661//____________________________________________________________________
662void
5934a3e3 663AliFMDEventInspector::CreateOutputObjects(TList* dir)
8565b10b 664{
7984e5f7 665 //
666 // Define the output histograms. These are put in a sub list of the
667 // passed list. The histograms are merged before the parent task calls
668 // AliAnalysisTaskSE::Terminate
669 //
670 // dir Directory to add to
671 //
6ab100ec 672 DGUARD(fDebug,1,"Define output from AliFMDEventInspector");
8565b10b 673 fList = new TList;
674 fList->SetName(GetName());
c929bc03 675 fList->SetOwner();
8565b10b 676 dir->Add(fList);
677}
678
679//____________________________________________________________________
680UInt_t
681AliFMDEventInspector::Process(const AliESDEvent* event,
682 UInt_t& triggers,
683 Bool_t& lowFlux,
0bd4b00f 684 UShort_t& ivz,
5ca83fee 685 TVector3& ip,
5bb5d1f6 686 Double_t& cent,
687 UShort_t& nClusters)
8565b10b 688{
7984e5f7 689 //
690 // Process the event
691 //
692 // Parameters:
693 // event Input event
694 // triggers On return, the triggers fired
695 // lowFlux On return, true if the event is considered a low-flux
696 // event (according to the setting of fLowFluxCut)
697 // ivz On return, the found vertex bin (1-based). A zero
698 // means outside of the defined vertex range
699 // vz On return, the z position of the interaction
5e4d905e 700 // cent On return, the centrality - if not available < 0
7984e5f7 701 //
702 // Return:
703 // 0 (or kOk) on success, otherwise a bit mask of error codes
704 //
4f9319f3 705 DGUARD(fDebug,1,"Process event in AliFMDEventInspector");
e1f47419 706 // --- Check that we have an event ---------------------------------
8565b10b 707 if (!event) {
708 AliWarning("No ESD event found for input event");
241cca4d 709 fHStatus->Fill(2);
8565b10b 710 return kNoEvent;
711 }
712
bfab35d9 713 // --- Process satellite event information is requested ------------
714 if (fUseDisplacedVertices) {
715 if (!fDisplacedVertex.Process(event))
716 AliWarning("Failed to process satellite event");
717 }
718
e1f47419 719 // --- Read trigger information from the ESD and store in AOD object
241cca4d 720 if (!ReadTriggers(*event, triggers, nClusters)) {
0bd4b00f 721 if (fDebug > 2) {
722 AliWarning("Failed to read triggers from ESD"); }
241cca4d 723 fHStatus->Fill(3);
8565b10b 724 return kNoTriggers;
725 }
726
e1f47419 727 // --- Check if this is a high-flux event --------------------------
8565b10b 728 const AliMultiplicity* testmult = event->GetMultiplicity();
729 if (!testmult) {
0bd4b00f 730 if (fDebug > 3) {
731 AliWarning("No central multiplicity object found"); }
8565b10b 732 }
e1f47419 733 else
734 lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
5e4d905e 735
0bd4b00f 736 fHType->Fill(lowFlux ? 0 : 1);
314f6077 737
738 // --- Get the interaction point -----------------------------------
739 Bool_t vzOk = ReadVertex(*event, ip);
740 fHEventsTr->Fill(ip.Z());
741 if (!vzOk) {
742 if (fDebug > 3) {
743 AliWarning("Failed to read vertex from ESD"); }
744 fHStatus->Fill(6);
745 return kNoVertex;
746 }
747
748 // --- Read centrality information
e308a636 749 cent = -10;
750 UShort_t qual = 0;
241cca4d 751 if (!ReadCentrality(*event, cent, qual)) {
e1f47419 752 if (fDebug > 3)
753 AliWarning("Failed to get centrality");
8565b10b 754 }
314f6077 755 // --- check centrality cut
4f9319f3 756
8449e3e0 757 if(fMinCent > -0.0001 && cent < fMinCent) return kNoEvent;
758 if(fMaxCent > -0.0001 && cent > fMaxCent) return kNoEvent;
77f97e3f 759 if (cent >= 0) fHCent->Fill(cent);
e308a636 760 if (qual == 0) fHCentVsQual->Fill(0., cent);
761 else {
77f97e3f 762 fHStatus->Fill(8);
e308a636 763 for (UShort_t i = 0; i < 4; i++)
764 if (qual & (1 << i)) fHCentVsQual->Fill(Double_t(i+1), cent);
765 }
314f6077 766
8565b10b 767
5ca83fee 768 fHEventsTrVtx->Fill(ip.Z());
96110c91 769
e1f47419 770 // --- Get the vertex bin ------------------------------------------
5ca83fee 771 ivz = fVtxAxis.FindBin(ip.Z());
5bb5d1f6 772 if (ivz <= 0 || ivz > fVtxAxis.GetNbins()) {
0bd4b00f 773 if (fDebug > 3) {
8565b10b 774 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
5ca83fee 775 ip.Z(), fVtxAxis.GetXmin(), fVtxAxis.GetXmax()));
5bb5d1f6 776 }
0bd4b00f 777 ivz = 0;
241cca4d 778 fHStatus->Fill(7);
8565b10b 779 return kBadVertex;
780 }
5ca83fee 781 fHEventsAccepted->Fill(ip.Z());
782 fHEventsAcceptedXY->Fill(ip.X(),ip.Y());
e58000b7 783
e1f47419 784 // --- Check the FMD ESD data --------------------------------------
785 if (!event->GetFMDData()) {
786 if (fDebug > 3) {
787 AliWarning("No FMD data found in ESD"); }
241cca4d 788 fHStatus->Fill(5);
e1f47419 789 return kNoFMD;
790 }
791
241cca4d 792 fHStatus->Fill(1);
8565b10b 793 return kOk;
794}
795
e1f47419 796//____________________________________________________________________
797Bool_t
241cca4d 798AliFMDEventInspector::ReadCentrality(const AliESDEvent& esd,
e308a636 799 Double_t& cent,
800 UShort_t& qual) const
e1f47419 801{
802 //
803 // Read centrality from event
804 //
805 // Parameters:
806 // esd Event
807 // cent On return, the centrality or negative if not found
808 //
809 // Return:
810 // False on error, true otherwise
811 //
6ab100ec 812 DGUARD(fDebug,2,"Read the centrality in AliFMDEventInspector");
241cca4d 813
241cca4d 814 cent = -1;
8449e3e0 815 qual = 1;
241cca4d 816 AliCentrality* centObj = const_cast<AliESDEvent&>(esd).GetCentrality();
8449e3e0 817 if (centObj) {
818 cent = centObj->GetCentralityPercentile(fCentMethod);
819 qual = centObj->GetQuality();
820 }
241cca4d 821
bc31b177 822 // We overwrite with satellite events, so we can be sure to get the
823 // centrality determination from the satellite vertex selection
824 if (fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
8449e3e0 825 cent = fDisplacedVertex.GetCentralityPercentile();
826 qual = 0;
827 }
e1f47419 828
829 return true;
830}
831
da70cd6a 832//____________________________________________________________________
833Bool_t
834AliFMDEventInspector::CheckpAExtraV0(const AliESDEvent& esd) const
835{
836 if (fCollisionSystem != AliForwardUtil::kPPb) return true;
837
838 AliVVZERO* esdV0 = esd.GetVZEROData();
839 if ((esdV0->GetV0ADecision()!=1) || (esdV0->GetV0CDecision()!=1))
840 return false;
841 return true;
842}
843
8565b10b 844//____________________________________________________________________
845Bool_t
241cca4d 846AliFMDEventInspector::ReadTriggers(const AliESDEvent& esd, UInt_t& triggers,
5bb5d1f6 847 UShort_t& nClusters)
8565b10b 848{
7984e5f7 849 //
850 // Read the trigger information from the ESD event
851 //
852 // Parameters:
853 // esd ESD event
854 // triggers On return, contains the trigger bits
855 //
856 // Return:
857 // @c true on success, @c false otherwise
858 //
6ab100ec 859 DGUARD(fDebug,2,"Read the triggers in AliFMDEventInspector");
8565b10b 860 triggers = 0;
861
862 // Get the analysis manager - should always be there
863 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
241cca4d 864 DMSG(fDebug,10,"Got analysis manager %p", am);
8565b10b 865 if (!am) {
866 AliWarning("No analysis manager defined!");
867 return kFALSE;
868 }
869
870 // Get the input handler - should always be there
871 AliInputEventHandler* ih =
872 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
241cca4d 873 DMSG(fDebug,10,"Got input handler %p", ih);
8565b10b 874 if (!ih) {
875 AliWarning("No input handler");
876 return kFALSE;
877 }
e85a76b7 878
e1f47419 879 // Check if this is a collision candidate (MB)
8449e3e0 880 ///
881 // Historic remark: Note, that we should use the value cached in the
882 // input handler rather than calling IsCollisionCandiate directly
883 // on the AliPhysicsSelection obejct. If we called the latter
884 // then the AliPhysicsSelection object would overcount by a factor
885 // of 2! :-(
886 UInt_t trgMask = ih->IsEventSelected();
887 Bool_t offline = trgMask;
888 Bool_t fastonly = (trgMask & AliVEvent::kFastOnly);
241cca4d 889 TString trigStr = esd.GetFiredTriggerClasses();
890
8449e3e0 891 if (trigStr.IsNull()) fHTrgStatus->Fill(kNoTrgWords);
241cca4d 892 if (fHWords) fHWords->Fill(trigStr.Data(), 1);
11d40ecb 893
241cca4d 894 if(fUseDisplacedVertices) {
895 DMSG(fDebug,3,"Using displaced vertex stuff");
8449e3e0 896 // if (TMath::Abs(fDisplacedVertex.GetVertexZ()) >= 999) offline = false;
897 if (fDisplacedVertex.IsSatellite())
898 triggers |= AliAODForwardMult::kSatellite;
899 }
900
901 if (CheckFastPartition(fastonly)) {
902 fHTrgStatus->Fill(kPP2760Fast);
903 offline = false;
241cca4d 904 }
65abd48b 905
8449e3e0 906 if (offline && CheckCosmics(trigStr)) {
907 fHTrgStatus->Fill(kMUON);
908 offline = false;
909 }
910 if (offline) fHTrgStatus->Fill(kTriggered);
911 Int_t f = 0;
912 if (trgMask & AliVEvent::kMB) f += fHTrgStatus->Fill(kMinBias);
913 if (trgMask & AliVEvent::kCINT5) f += fHTrgStatus->Fill(kMinBiasNoSPD);
914 if (trgMask & AliVEvent::kINT7) f += fHTrgStatus->Fill(kV0AndTrg);
915 if (trgMask & AliVEvent::kHighMult) f += fHTrgStatus->Fill(kHighMult);
916 if (trgMask & AliVEvent::kCentral) f += fHTrgStatus->Fill(kCentral);
917 if (trgMask & AliVEvent::kSemiCentral) f += fHTrgStatus->Fill(kSemiCentral);
918 if (trgMask & AliVEvent::kDG5) f += fHTrgStatus->Fill(kDiffractive);
919 if (trgMask & AliVEvent::kUserDefined) f += fHTrgStatus->Fill(kUser);
920 if (f <= 0) fHTrgStatus->Fill(kOther);
921
c929bc03 922 // if (!CheckpAExtraV0(esd)) offline = false;
241cca4d 923
924 DMSG(fDebug,2,"Event is %striggered by off-line", offline ? "" : "NOT ");
925
dd556bcd 926 if (offline) triggers |= AliAODForwardMult::kOffline;
927 // Only flag as in-elastic if a min-bias trigger is here
928 if (trgMask & AliVEvent::kMB) {
241cca4d 929 triggers |= AliAODForwardMult::kInel;
241cca4d 930 CheckINELGT0(esd, nClusters, triggers);
65abd48b 931 }
932
241cca4d 933 CheckNSD(esd,triggers);
cd51b0dd 934 CheckPileup(esd, triggers);
935 CheckEmpty(trigStr, triggers);
936 // if (CheckPileup(esd, triggers)) fHTriggers->Fill(kPileUp+.5);
937 // if (CheckEmpty(trigStr, triggers)) fHTriggers->Fill(kEmpty+.5);
241cca4d 938
8449e3e0 939 CheckWords(esd, triggers);
241cca4d 940
66cf95f2 941#define TEST_TRIG_BIN(RET,BIN,TRIGGERS) \
942 do { switch (BIN) { \
8449e3e0 943 case kInel: RET = triggers & AliAODForwardMult::kInel; break; \
944 case kInelGt0: RET = triggers & AliAODForwardMult::kInelGt0; break; \
945 case kNSD: RET = triggers & AliAODForwardMult::kNSD; break; \
946 case kV0AND: RET = triggers & AliAODForwardMult::kV0AND; break; \
947 case kEmpty: RET = triggers & AliAODForwardMult::kEmpty; break; \
948 case kA: RET = triggers & AliAODForwardMult::kA; break; \
949 case kB: RET = triggers & AliAODForwardMult::kB; break; \
950 case kC: RET = triggers & AliAODForwardMult::kC; break; \
951 case kE: RET = triggers & AliAODForwardMult::kE; break; \
952 case kPileUp: RET = triggers & AliAODForwardMult::kPileUp; break; \
953 case kMCNSD: RET = triggers & AliAODForwardMult::kMCNSD; break; \
954 case kSatellite:RET = triggers & AliAODForwardMult::kSatellite; break; \
955 case kOffline: RET = triggers & AliAODForwardMult::kOffline; break; \
956 default: RET = false; } } while(false)
66cf95f2 957
8449e3e0 958 if (!fHTriggers) {
959 AliWarning("Histogram of triggers not defined - has init been called");
960 return false;
961 }
241cca4d 962
66cf95f2 963 for (Int_t i = 0; i < kOffline+1; i++) {
964 Bool_t hasX = false;
965 TEST_TRIG_BIN(hasX, i, triggers);
966 if (!hasX) continue;
cd51b0dd 967 fHTriggers->Fill(i+.5);
968 for (Int_t j = 0; j < kOffline+1; j++) {
66cf95f2 969 Bool_t hasY = false;
970 TEST_TRIG_BIN(hasY, j, triggers);
971 if (!hasY) continue;
972
973 fHTriggerCorr->Fill(i+.5, j+.5);
974 }
975 }
241cca4d 976 return kTRUE;
977}
978
979//____________________________________________________________________
980Bool_t
981AliFMDEventInspector::CheckFastPartition(bool fastonly) const
982{
11d40ecb 983 // For the 2.76 TeV p+p run, the FMD ran in the slow partition
984 // so it received no triggers from the fast partition. Therefore
985 // the fast triggers are removed here but not for MC where all
986 // triggers are fast.
241cca4d 987 if (TMath::Abs(fEnergy - 2750.) > 20) return false;
988 if (fCollisionSystem != AliForwardUtil::kPP) return false;
e65b8b56 989 if (fMC) return false; // All MC events for pp @ 2.76TeV are `fast'
241cca4d 990 if (fastonly)
991 DMSG(fDebug,1,"Fast trigger in pp @ sqrt(s)=2.76TeV removed");
992
993 return fastonly;
994}
995
996//____________________________________________________________________
997Bool_t
998AliFMDEventInspector::CheckCosmics(const TString& trigStr) const
999{
1000 // MUON triggers are not strictly minimum bias (MB) so they are
1001 // removed (HHD)
1002 if(trigStr.Contains("CMUS1")) {
1003 DMSG(fDebug,1,"Cosmic trigger ins't min-bias, removed");
1004 return true;
1005 }
1006 return false;
1007}
1008
1009//____________________________________________________________________
1010Bool_t
1011AliFMDEventInspector::CheckINELGT0(const AliESDEvent& esd,
1012 UShort_t& nClusters,
1013 UInt_t& triggers) const
1014{
5bb5d1f6 1015 nClusters = 0;
8565b10b 1016
241cca4d 1017 // If this is inel, see if we have a tracklet
1018 const AliMultiplicity* spdmult = esd.GetMultiplicity();
1019 if (!spdmult) {
1020 AliWarning("No SPD multiplicity");
1021 return false;
1022 }
1023
1024 // Check if we have one or more tracklets
1025 // in the range -1 < eta < 1 to set the INEL>0
1026 // trigger flag.
1027 //
1028 // Also count tracklets as a single cluster
1029 Int_t n = spdmult->GetNumberOfTracklets();
1030 for (Int_t j = 0; j < n; j++) {
dd556bcd 1031 if(TMath::Abs(spdmult->GetEta(j)) < 1) nClusters++;
8565b10b 1032 }
dd556bcd 1033 // If we at this point had non-zero nClusters, it's INEL>0
1034 if (nClusters > 0) triggers |= AliAODForwardMult::kInelGt0;
1035
1036 // Loop over single clusters
241cca4d 1037 n = spdmult->GetNumberOfSingleClusters();
1038 for (Int_t j = 0; j < n; j++) {
1039 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
1040 if (TMath::Abs(eta) < 1) nClusters++;
1041 }
1042 if (nClusters > 0) triggers |= AliAODForwardMult::kNClusterGt0;
1043
1044 return triggers & AliAODForwardMult::kNClusterGt0;
1045}
1046
1047//____________________________________________________________________
1048Bool_t
1049AliFMDEventInspector::CheckNSD(const AliESDEvent& esd, UInt_t& triggers) const
1050{
8565b10b 1051 // Analyse some trigger stuff
1052 AliTriggerAnalysis ta;
241cca4d 1053 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kV0AND)) {
e6463868 1054 triggers |= AliAODForwardMult::kV0AND;
1055 if (fUseV0AND)
31554871 1056 triggers |= AliAODForwardMult::kNSD;
1057 }
241cca4d 1058 if (ta.IsOfflineTriggerFired(&esd, AliTriggerAnalysis::kNSD1))
e6463868 1059 triggers |= AliAODForwardMult::kNSD;
241cca4d 1060 return triggers & AliAODForwardMult::kNSD;
1061}
1062//____________________________________________________________________
1063Bool_t
1064AliFMDEventInspector::CheckPileup(const AliESDEvent& esd,
1065 UInt_t& triggers) const
1066{
5bb5d1f6 1067 // Check for multiple vertices (pile-up) with at least 3
1068 // contributors and at least 0.8cm from the primary vertex
dd556bcd 1069 // if(fCollisionSystem != AliForwardUtil::kPP) return false;
1070
1071 // Check for standard SPD pile-up
1072 Bool_t spdPileup = esd.IsPileupFromSPD(fMinPileupContrib,fMinPileupDistance);
241cca4d 1073
dd556bcd 1074 // Check for multi-vertex pileup
1075 Bool_t mvPileup = false; // CheckMultiVertex(esd);
1076
1077 // Check for out-of-bunch pileup
1078 Bool_t outPileup = (esd.GetHeader()->GetIRInt2ClosestInteractionMap() != 0 ||
1079 esd.GetHeader()->GetIRInt1ClosestInteractionMap() != 0);
1080
1081 // Our result
1082 Bool_t pileup = spdPileup || mvPileup || outPileup;
241cca4d 1083 if (pileup) triggers |= AliAODForwardMult::kPileUp;
1084 return pileup;
1085}
1086
dd556bcd 1087//____________________________________________________________________
1088Bool_t
c8b1a7db 1089AliFMDEventInspector::CheckMultiVertex(const AliESDEvent& esd,
1090 Bool_t checkOtherBC) const
dd556bcd 1091{
1092 // Adapted from AliAnalysisUtils
1093 //
1094 // Parameters
1095 const Double_t maxChi2nu = 5;
dd556bcd 1096
1097 // Number of vertices
1098 Int_t n = esd.GetNumberOfPileupVerticesTracks();
1099 if (n < 1)
1100 // No additional vertices from tracks -> no pileup
1101 return false;
1102
1103 // Primary vertex
1104 const AliESDVertex* primary = esd.GetPrimaryVertexTracks();
1105 if (primary->GetStatus() != 1)
1106 // No good primary vertex, but many candidates -> pileup
1107 return true;
1108
1109 // Bunch crossing number
1110 Int_t bcPrimary = primary->GetBC();
1111
1112 for (Int_t i = 0; i < n; i++) {
1113 const AliESDVertex* other = esd.GetPileupVertexTracks(i);
1114
1115 if (other->GetNContributors() < fMinPileupContrib)
1116 // Not enough contributors to this vertex
1117 continue;
1118
1119 if (other->GetChi2perNDF() > maxChi2nu)
1120 // Poorly determined vertex
1121 continue;
1122 if (checkOtherBC) {
1123 Int_t bcOther = other->GetBC();
1124 if (bcOther != AliVTrack::kTOFBCNA && TMath::Abs(bcOther-bcPrimary) > 2)
1125 // Pile-up from other BC
1126 return true;
1127 }
1128 // Calculate the distance
1129 Double_t d = -1;
1130 Double_t dx = primary->GetX() - other->GetX();
1131 Double_t dy = primary->GetY() - other->GetY();
1132 Double_t dz = primary->GetZ() - other->GetZ();
1133 Double_t covPrimary[6], covOther[6];
1134 primary->GetCovarianceMatrix(covPrimary);
1135 other->GetCovarianceMatrix(covOther);
1136 TMatrixDSym v(3);
1137 v(0,0) = covPrimary[0] + covOther[0]; // diagonal
1138 v(1,1) = covPrimary[2] + covOther[2]; // diagonal
1139 v(2,2) = covPrimary[5] + covOther[5]; // diagonal
1140 v(1,0) = v(0,1) = covPrimary[1]+covOther[1]; // Band
1141 v(0,2) = v(1,2) = v(2,0) = v(2,1) = 0; // Off-diagonal+band
1142 // Try to invert
1143 v.InvertFast();
1144 if (!v.IsValid())
1145 // Question if kStatus bit is every set after InvertFast?
1146 continue;
1147 d = (v(0,0) * dx * dx + v(1,1) * dy * dy + v(2,2) * dz * dz +
1148 2 * (v(0,1) * dx * dy + v(0,2) * dx * dz + v(1,2) * dy * dz));
1149
1150 if (d < 0 || TMath::Sqrt(d) < fMinPileupDistance)
1151 // Bad distance, or not fare enough from each other
1152 continue;
1153
1154 // Well separated vertices -> pileup
1155 return true;
1156 }
1157 return false;
1158}
1159
241cca4d 1160//____________________________________________________________________
1161Bool_t
1162AliFMDEventInspector::CheckEmpty(const TString& trigStr, UInt_t& triggers) const
1163{
8565b10b 1164 if (trigStr.Contains("CBEAMB-ABCE-NOPF-ALL")) {
1165 triggers |= AliAODForwardMult::kEmpty;
241cca4d 1166 return true;
8565b10b 1167 }
241cca4d 1168 return false;
1169}
1170//____________________________________________________________________
1171Bool_t
1172AliFMDEventInspector::CheckWords(const AliESDEvent& esd, UInt_t& triggers) const
1173{
1174 TObject* word = 0;
1175 TIter nextColl(&fCollWords);
1176 while ((word = nextColl())) {
1177 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1178 word->GetTitle(), word->GetName());
1179 if (!esd.IsTriggerClassFired(word->GetName())) continue;
8565b10b 1180
241cca4d 1181 TString beamSide = word->GetTitle();
1182 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
e85a76b7 1183
241cca4d 1184 if (!beamSide.EqualTo("B")) continue;
1185 triggers |= AliAODForwardMult::kB;
1186 break; // No more to do here
e85a76b7 1187 }
241cca4d 1188 TIter nextBg(&fBgWords);
1189 UInt_t all = (AliAODForwardMult::kA |
1190 AliAODForwardMult::kC |
1191 AliAODForwardMult::kE);
1192 while ((word = nextBg())) {
1193 DMSG(fDebug,10,"Checking if %s trigger %s is fired",
1194 word->GetTitle(), word->GetName());
1195 if (!esd.IsTriggerClassFired(word->GetName())) continue;
0be6c8cd 1196
241cca4d 1197 TString beamSide = word->GetTitle();
1198 DMSG(fDebug,10,"Found it - this is a %s trigger", beamSide.Data());
e6463868 1199
241cca4d 1200 if (beamSide.Contains("A")) triggers |= AliAODForwardMult::kA;
1201 if (beamSide.Contains("C")) triggers |= AliAODForwardMult::kC;
1202 if (beamSide.Contains("E")) triggers |= AliAODForwardMult::kE;
1203
1204 if ((triggers & all) == all) break; // No more to do
0be6c8cd 1205 }
241cca4d 1206 return true;
8565b10b 1207}
241cca4d 1208
1209
8565b10b 1210//____________________________________________________________________
1211Bool_t
5ca83fee 1212AliFMDEventInspector::ReadVertex(const AliESDEvent& esd, TVector3& ip)
8565b10b 1213{
7984e5f7 1214 //
1215 // Read the vertex information from the ESD event
1216 //
1217 // Parameters:
1218 // esd ESD event
1219 // vz On return, the vertex Z position
1220 //
1221 // Return:
1222 // @c true on success, @c false otherwise
1223 //
6ab100ec 1224 DGUARD(fDebug,2,"Read the vertex in AliFMDEventInspector");
5ca83fee 1225 ip.SetXYZ(1024, 1024, 0);
65abd48b 1226
8449e3e0 1227 EVtxStatus s = kNoVtx;
bfab35d9 1228 if (fUseDisplacedVertices && fDisplacedVertex.IsSatellite()) {
1229 s = kVtxOK;
1230 ip.SetZ(fDisplacedVertex.GetVertexZ());
1231 }
1232 else if (fUseFirstPhysicsVertex)
8449e3e0 1233 s = CheckPWGUDVertex(esd, ip);
1234 else if (fUsepA2012Vertex)
1235 s = CheckpA2012Vertex(esd,ip);
1236 else
1237 s = CheckVertex(esd, ip);
1238
8449e3e0 1239 fHVtxStatus->Fill(s);
1240
1241 return s == kVtxOK;
241cca4d 1242}
1243
1244//____________________________________________________________________
8449e3e0 1245AliFMDEventInspector::EVtxStatus
241cca4d 1246AliFMDEventInspector::CheckPWGUDVertex(const AliESDEvent& esd,
5ca83fee 1247 TVector3& ip) const
241cca4d 1248{
1249 // This is the code used by the 1st physics people
1250 const AliESDVertex* vertex = esd.GetPrimaryVertex();
1251 if (!vertex || !vertex->GetStatus()) {
1252 DMSG(fDebug,2,"No primary vertex (%p) or bad status %d",
1253 vertex, (vertex ? vertex->GetStatus() : -1));
8449e3e0 1254 return kNoVtx;
241cca4d 1255 }
1256 const AliESDVertex* vertexSPD = esd.GetPrimaryVertexSPD();
1257 if (!vertexSPD || !vertexSPD->GetStatus()) {
1258 DMSG(fDebug,2,"No primary SPD vertex (%p) or bad status %d",
1259 vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1));
8449e3e0 1260 return kNoSPDVtx;
241cca4d 1261 }
96110c91 1262
241cca4d 1263 // if vertex is from SPD vertexZ, require more stringent cuts
1264 if (vertex->IsFromVertexerZ()) {
1265 if (vertex->GetDispersion() > fMaxVzErr ||
1266 vertex->GetZRes() > 1.25 * fMaxVzErr) {
1267 DMSG(fDebug,2,"Dispersion %f > %f or resolution %f > %f",
1268 vertex->GetDispersion(), fMaxVzErr,
1269 vertex->GetZRes(), 1.25 * fMaxVzErr);
8449e3e0 1270 return kUncertain;
96110c91 1271 }
96110c91 1272 }
5ca83fee 1273 ip.SetZ(vertex->GetZ());
241cca4d 1274
1275 if(!vertex->IsFromVertexerZ()) {
5ca83fee 1276 ip.SetX(vertex->GetX());
1277 ip.SetY(vertex->GetY());
241cca4d 1278 }
8449e3e0 1279 return kVtxOK;
241cca4d 1280}
8449e3e0 1281//____________________________________________________________________
1282AliFMDEventInspector::EVtxStatus
1283AliFMDEventInspector::CheckpA2012Vertex(const AliESDEvent& esd,
1284 TVector3& ip) const
ffd35d33 1285{
8449e3e0 1286 const AliESDVertex *vertex = esd.GetPrimaryVertexSPD();
1287 if (!vertex) return kNoSPDVtx;
1288 if (vertex->GetNContributors() <= 0) return kFewContrib;
1289
1290 TString vtxTyp = vertex->GetTitle();
1291 if (vtxTyp.Contains("vertexer: Z")) return kNotVtxZ;
1292
1293 if (vertex->GetDispersion() >= 0.04 || vertex->GetZRes()>=0.25)
1294 return kUncertain;
1295
1296 ip.SetX(vertex->GetX());
1297 ip.SetY(vertex->GetY());
1298 ip.SetZ(vertex->GetZ());
1299
1300 return kVtxOK;
ffd35d33 1301}
1302
241cca4d 1303//____________________________________________________________________
8449e3e0 1304AliFMDEventInspector::EVtxStatus
241cca4d 1305AliFMDEventInspector::CheckVertex(const AliESDEvent& esd,
5ca83fee 1306 TVector3& ip) const
241cca4d 1307{
1308 // Use standard SPD vertex (perhaps preferable for Pb+Pb)
1309 // Get the vertex
1310 const AliESDVertex* vertex = esd.GetPrimaryVertexSPD();
1311 if (!vertex) {
1312 if (fDebug > 2) {
1313 AliWarning("No SPD vertex found in ESD"); }
8449e3e0 1314 return kNoSPDVtx;
241cca4d 1315 }
e83d0620 1316
8449e3e0 1317 // #if 0 // Check disabled - seem to kill a lot of PbPb events
241cca4d 1318 // Check that enough tracklets contributed
1319 if(vertex->GetNContributors() <= 0) {
1320 DMSG(fDebug,2,"Number of contributors to vertex is %d<=0",
1321 vertex->GetNContributors());
5ca83fee 1322 ip.SetZ(0);
8449e3e0 1323 return kFewContrib;
241cca4d 1324 }
8449e3e0 1325 // #endif
1326
241cca4d 1327 // Check that the uncertainty isn't too large
1328 if (vertex->GetZRes() > fMaxVzErr) {
1329 DMSG(fDebug,2,"Uncertaintity in Z of vertex is too large %f > %f",
1330 vertex->GetZRes(), fMaxVzErr);
8449e3e0 1331 return kUncertain;
241cca4d 1332 }
e83d0620 1333
241cca4d 1334 // Get the z coordiante
5ca83fee 1335 ip.SetZ(vertex->GetZ());
241cca4d 1336 const AliESDVertex* vertexXY = esd.GetPrimaryVertex();
96110c91 1337
5ca83fee 1338
241cca4d 1339 if(!vertexXY->IsFromVertexerZ()) {
5ca83fee 1340 ip.SetX(vertexXY->GetX());
1341 ip.SetY(vertexXY->GetY());
241cca4d 1342 }
8449e3e0 1343 return kVtxOK;
8565b10b 1344}
241cca4d 1345
0bd4b00f 1346//____________________________________________________________________
1347Bool_t
1348AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
1349{
7984e5f7 1350 //
1351 // Read the collision system, collision energy, and L3 field setting
1352 // from the ESD
1353 //
1354 // Parameters:
1355 // esd ESD to get information from
1356 //
1357 // Return:
1358 // true on success, false
1359 //
cc83fca2 1360 // AliInfo(Form("Parameters from 1st ESD event: cms=%s, sNN=%f, field=%f",
1361 // esd->GetBeamType(), 2*esd->GetBeamEnergy(),
1362 // esd->GetMagneticField()));
6ab100ec 1363 DGUARD(fDebug,2,"Read the run details in AliFMDEventInspector");
d4d486f8 1364 const char* sys = esd->GetBeamType();
1365 Float_t cms = 2 * esd->GetBeamEnergy();
1366 Float_t fld = esd->GetMagneticField();
1367 fCollisionSystem = AliForwardUtil::ParseCollisionSystem(sys);
1368 fEnergy = AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,
1369 cms);
1370 fField = AliForwardUtil::ParseMagneticField(fld);
8449e3e0 1371 fRunNumber = esd->GetRunNumber();
c8b1a7db 1372 StoreProduction();
8449e3e0 1373 StoreInformation();
d4d486f8 1374 if (fCollisionSystem == AliForwardUtil::kUnknown) {
1375 AliWarningF("Unknown collision system: %s - please check", sys);
1376 return false;
1377 }
1378 if (fEnergy <= 0) {
1379 AliWarningF("Unknown CMS energy: %f (%d) - please check", cms, fEnergy);
1380 return false;
1381 }
1382 if (TMath::Abs(fField) > 10) {
1383 AliWarningF("Unknown L3 field setting: %f (%d) - please check", fld,fField);
1384 return false;
1385 }
0bd4b00f 1386
d4d486f8 1387 return true;
0bd4b00f 1388}
1389
241cca4d 1390
1391//____________________________________________________________________
1392const Char_t*
1393AliFMDEventInspector::CodeString(UInt_t code)
1394{
1395 static TString s;
1396 s = "";
1397 if (code & kNoEvent) s.Append("NOEVENT ");
1398 if (code & kNoTriggers) s.Append("NOTRIGGERS ");
1399 if (code & kNoSPD) s.Append("NOSPD ");
1400 if (code & kNoFMD) s.Append("NOFMD ");
1401 if (code & kNoVertex) s.Append("NOVERTEX ");
1402 if (code & kBadVertex) s.Append("BADVERTEX ");
1403 return s.Data();
1404}
c8b1a7db 1405#define PF(N,V,...) \
1406 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
1407#define PFB(N,FLAG) \
1408 do { \
1409 AliForwardUtil::PrintName(N); \
1410 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
1411 } while(false)
1412#define PFV(N,VALUE) \
1413 do { \
1414 AliForwardUtil::PrintName(N); \
1415 std::cout << (VALUE) << std::endl; } while(false)
1416
0bd4b00f 1417//____________________________________________________________________
1418void
1419AliFMDEventInspector::Print(Option_t*) const
1420{
7984e5f7 1421 //
1422 // Print information
1423 //
1424 // option Not used
1425 //
c8b1a7db 1426 AliForwardUtil::PrintTask(*this);
0bd4b00f 1427 TString sNN(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
1428 sNN.Strip(TString::kBoth, '0');
1429 sNN.ReplaceAll("GeV", " GeV");
1430 TString field(AliForwardUtil::MagneticFieldString(fField));
1431 field.ReplaceAll("p", "+");
1432 field.ReplaceAll("m", "-");
1433 field.ReplaceAll("kG", " kG");
c8b1a7db 1434
1435 gROOT->IncreaseDirLevel();
0b7de667 1436 PFV("Production", "");
1437 gROOT->IncreaseDirLevel();
1438 PF("Period", "LHC%02d%c", fProdYear, fProdLetter);
1439 PFB("MC anchor", fProdMC);
1440 PFV("AliROOT Revision", fProdSVN);
1441 gROOT->DecreaseDirLevel();
c8b1a7db 1442 PFV("Vertex bins", fVtxAxis.GetNbins());
1443 PF("Vertex Range", "[%+6.1f,%+6.1f]", fVtxAxis.GetXmin(), fVtxAxis.GetXmax());
1444 PFV("Low flux cut", fLowFluxCut );
1445 PFV("Max(delta v_z)", fMaxVzErr );
1446 PFV("Min(nContrib_pileup)", fMinPileupContrib );
1447 PFV("Min(v-pileup)", fMinPileupDistance );
1448 PFV("System", AliForwardUtil::CollisionSystemString(fCollisionSystem));
1449 PFV("CMS energy per nucleon", sNN);
1450 PFV("Field", field);
1451 PFB("Satellite events", fUseDisplacedVertices);
1452 PFB("Use 2012 pA vertex", fUsepA2012Vertex );
1453 PFB("Use PWG-UD vertex", fUseFirstPhysicsVertex);
1454 PFB("Simulation input", fMC );
1455 PFV("Centrality method", fCentMethod);
1456 PFV("Centrality axis", (!fCentAxis ? "none" : ""));
1457 if (!fCentAxis) {return; }
d8244e9e 1458 Int_t nBin = fCentAxis->GetNbins();
d8244e9e 1459 for (Int_t i = 0; i < nBin; i++) {
0b7de667 1460 if (i != 0 && (i % 10) == 0) std::cout << '\n';
1461 if ((i % 10) == 0) std::cout << " ";
d8244e9e 1462 std::cout << std::setw(5) << fCentAxis->GetBinLowEdge(i+1) << '-';
1463 }
1464 std::cout << std::setw(5) << fCentAxis->GetBinUpEdge(nBin) << std::endl;
c8b1a7db 1465 gROOT->DecreaseDirLevel();
0bd4b00f 1466}
1467
1468
8565b10b 1469//
1470// EOF
1471//
1472