First half of changes for displaced vertices - second half to follow
[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"
18#include "AliLog.h"
19#include "AliESDEvent.h"
20#include "AliMultiplicity.h"
21#include "AliAnalysisManager.h"
11d40ecb 22#include "AliMCEventHandler.h"
8565b10b 23#include "AliInputEventHandler.h"
24#include "AliTriggerAnalysis.h"
25#include "AliPhysicsSelection.h"
e85a76b7 26#include "AliOADBPhysicsSelection.h"
8565b10b 27#include "AliAODForwardMult.h"
0bd4b00f 28#include "AliForwardUtil.h"
5e4d905e 29#include "AliCentrality.h"
8565b10b 30#include <TH1.h>
31#include <TList.h>
32#include <TDirectory.h>
0bd4b00f 33#include <TROOT.h>
e6463868 34#include <TParameter.h>
0bd4b00f 35#include <iostream>
36#include <iomanip>
e1f47419 37
8565b10b 38//====================================================================
39AliFMDEventInspector::AliFMDEventInspector()
40 : TNamed(),
41 fHEventsTr(0),
42 fHEventsTrVtx(0),
5bb5d1f6 43 fHEventsAccepted(0),
96110c91 44 fHEventsAcceptedXY(0),
8565b10b 45 fHTriggers(0),
0bd4b00f 46 fHType(0),
fe52e455 47 fHWords(0),
5e4d905e 48 fHCent(0),
e308a636 49 fHCentVsQual(0),
8565b10b 50 fLowFluxCut(1000),
9d05ffeb 51 fMaxVzErr(0.2),
8565b10b 52 fList(0),
0bd4b00f 53 fEnergy(0),
54 fField(999),
55 fCollisionSystem(kUnknown),
e308a636 56 fDebug(0),
5bb5d1f6 57 fCentAxis(0),
e83d0620 58 fVtxAxis(10,-10,10),
31554871 59 fUseFirstPhysicsVertex(true),
e6463868 60 fUseV0AND(false),
61 fMinPileupContrib(3),
62 fMinPileupDistance(0.8)
8565b10b 63{
7984e5f7 64 //
65 // Constructor
66 //
8565b10b 67}
68
69//____________________________________________________________________
70AliFMDEventInspector::AliFMDEventInspector(const char* name)
71 : TNamed("fmdEventInspector", name),
72 fHEventsTr(0),
73 fHEventsTrVtx(0),
5bb5d1f6 74 fHEventsAccepted(0),
96110c91 75 fHEventsAcceptedXY(0),
8565b10b 76 fHTriggers(0),
0bd4b00f 77 fHType(0),
fe52e455 78 fHWords(0),
5e4d905e 79 fHCent(0),
e308a636 80 fHCentVsQual(0),
8565b10b 81 fLowFluxCut(1000),
9d05ffeb 82 fMaxVzErr(0.2),
8565b10b 83 fList(0),
0bd4b00f 84 fEnergy(0),
85 fField(999),
86 fCollisionSystem(kUnknown),
e308a636 87 fDebug(0),
5bb5d1f6 88 fCentAxis(0),
e83d0620 89 fVtxAxis(10,-10,10),
31554871 90 fUseFirstPhysicsVertex(true),
e6463868 91 fUseV0AND(false),
92 fMinPileupContrib(3),
93 fMinPileupDistance(0.8)
8565b10b 94{
7984e5f7 95 //
96 // Constructor
97 //
98 // Parameters:
99 // name Name of object
100 //
8565b10b 101}
102
103//____________________________________________________________________
104AliFMDEventInspector::AliFMDEventInspector(const AliFMDEventInspector& o)
105 : TNamed(o),
106 fHEventsTr(o.fHEventsTr),
107 fHEventsTrVtx(o.fHEventsTrVtx),
5bb5d1f6 108 fHEventsAccepted(o.fHEventsAccepted),
96110c91 109 fHEventsAcceptedXY(o.fHEventsAcceptedXY),
8565b10b 110 fHTriggers(o.fHTriggers),
0bd4b00f 111 fHType(o.fHType),
fe52e455 112 fHWords(o.fHWords),
5e4d905e 113 fHCent(o.fHCent),
e308a636 114 fHCentVsQual(o.fHCentVsQual),
6feacd76 115 fLowFluxCut(o.fLowFluxCut),
8565b10b 116 fMaxVzErr(o.fMaxVzErr),
117 fList(o.fList),
0bd4b00f 118 fEnergy(o.fEnergy),
119 fField(o.fField),
120 fCollisionSystem(o.fCollisionSystem),
e308a636 121 fDebug(0),
5bb5d1f6 122 fCentAxis(0),
e83d0620 123 fVtxAxis(o.fVtxAxis),
31554871 124 fUseFirstPhysicsVertex(o.fUseFirstPhysicsVertex),
e6463868 125 fUseV0AND(o.fUseV0AND),
126 fMinPileupContrib(o.fMinPileupContrib),
127 fMinPileupDistance(o.fMinPileupDistance)
8565b10b 128{
7984e5f7 129 //
130 // Copy constructor
131 //
132 // Parameters:
133 // o Object to copy from
134 //
8565b10b 135}
136
137//____________________________________________________________________
138AliFMDEventInspector::~AliFMDEventInspector()
139{
7984e5f7 140 //
141 // Destructor
142 //
8565b10b 143 if (fList) delete fList;
144}
145//____________________________________________________________________
146AliFMDEventInspector&
147AliFMDEventInspector::operator=(const AliFMDEventInspector& o)
148{
7984e5f7 149 //
150 // Assignement operator
151 //
152 // Parameters:
153 // o Object to assign from
154 //
155 // Return:
156 // Reference to this object
157 //
d015ecfe 158 if (&o == this) return *this;
8565b10b 159 TNamed::operator=(o);
160 fHEventsTr = o.fHEventsTr;
161 fHEventsTrVtx = o.fHEventsTrVtx;
5bb5d1f6 162 fHEventsAccepted = o.fHEventsAccepted;
96110c91 163 fHEventsAcceptedXY = o.fHEventsAcceptedXY;
8565b10b 164 fHTriggers = o.fHTriggers;
0bd4b00f 165 fHType = o.fHType;
fe52e455 166 fHWords = o.fHWords;
5e4d905e 167 fHCent = o.fHCent;
e308a636 168 fHCentVsQual = o.fHCentVsQual;
8565b10b 169 fLowFluxCut = o.fLowFluxCut;
170 fMaxVzErr = o.fMaxVzErr;
171 fDebug = o.fDebug;
172 fList = (o.fList ? new TList : 0);
0bd4b00f 173 fEnergy = o.fEnergy;
174 fField = o.fField;
175 fCollisionSystem = o.fCollisionSystem;
5bb5d1f6 176 fVtxAxis.Set(o.fVtxAxis.GetNbins(), o.fVtxAxis.GetXmin(),
177 o.fVtxAxis.GetXmax());
e83d0620 178
179 fUseFirstPhysicsVertex = o.fUseFirstPhysicsVertex;
31554871 180 fUseV0AND = o.fUseV0AND;
e6463868 181 fMinPileupContrib = o.fMinPileupContrib;
182 fMinPileupDistance = o.fMinPileupDistance;
e83d0620 183
8565b10b 184 if (fList) {
185 fList->SetName(GetName());
186 if (fHEventsTr) fList->Add(fHEventsTr);
187 if (fHEventsTrVtx) fList->Add(fHEventsTrVtx);
188 if (fHTriggers) fList->Add(fHTriggers);
0bd4b00f 189 if (fHType) fList->Add(fHType);
fe52e455 190 if (fHWords) fList->Add(fHWords);
5e4d905e 191 if (fHCent) fList->Add(fHCent);
e308a636 192 if (fHCentVsQual) fList->Add(fHCentVsQual);
8565b10b 193 }
194 return *this;
195}
196
197//____________________________________________________________________
198Bool_t
fb3430ac 199AliFMDEventInspector::FetchHistograms(const TList* d,
8565b10b 200 TH1I*& hEventsTr,
201 TH1I*& hEventsTrVtx,
202 TH1I*& hTriggers) const
203{
7984e5f7 204 //
205 // Fetch our histograms from the passed list
206 //
207 // Parameters:
208 // d Input
209 // hEventsTr On return, pointer to histogram, or null
210 // hEventsTrVtx On return, pointer to histogram, or null
211 // hTriggers On return, pointer to histogram, or null
212 //
213 // Return:
214 // true on success, false otherwise
215 //
8565b10b 216 hEventsTr = 0;
217 hEventsTrVtx = 0;
218 hTriggers = 0;
219 TList* dd = dynamic_cast<TList*>(d->FindObject(GetName()));
220 if (!dd) return kFALSE;
221
222 hEventsTr = dynamic_cast<TH1I*>(dd->FindObject("nEventsTr"));
223 hEventsTrVtx = dynamic_cast<TH1I*>(dd->FindObject("nEventsTrVtx"));
224 hTriggers = dynamic_cast<TH1I*>(dd->FindObject("triggers"));
225
226 if (!hEventsTr || !hEventsTrVtx || !hTriggers) return kFALSE;
227 return kTRUE;
228}
229//____________________________________________________________________
230void
231AliFMDEventInspector::Init(const TAxis& vtxAxis)
232{
7984e5f7 233 //
234 // Initialize the object
235 //
236 // Parameters:
237 // vtxAxis Vertex axis in use
238 //
e308a636 239
240 // -1.5 -0.5 0.5 1.5 ... 89.5 ... 100.5
241 // ----- 92 number --------- ---- 1 ---
242 TArrayD limits(93);
243 for (Int_t i = 0; i < 92; i++) limits[i] = -1.5 + i;
d8244e9e 244 limits[92] = 100.5;
5bb5d1f6 245
246 fVtxAxis.Set(vtxAxis.GetNbins(), vtxAxis.GetXmin(), vtxAxis.GetXmax());
e308a636 247
248 fCentAxis = new TAxis(limits.GetSize()-1, limits.GetArray());
8565b10b 249 fHEventsTr = new TH1I("nEventsTr", "Number of events w/trigger",
5bb5d1f6 250 4*vtxAxis.GetNbins(),
251 2*vtxAxis.GetXmin(),
252 2*vtxAxis.GetXmax());
8565b10b 253 fHEventsTr->SetXTitle("v_{z} [cm]");
254 fHEventsTr->SetYTitle("# of events");
255 fHEventsTr->SetFillColor(kRed+1);
256 fHEventsTr->SetFillStyle(3001);
257 fHEventsTr->SetDirectory(0);
258 // fHEventsTr->Sumw2();
259 fList->Add(fHEventsTr);
260
5bb5d1f6 261 fHEventsTrVtx = static_cast<TH1I*>(fHEventsTr->Clone("nEventsTrVtx"));
262 fHEventsTrVtx->SetTitle("Number of events w/trigger and vertex");
8565b10b 263 fHEventsTrVtx->SetFillColor(kBlue+1);
8565b10b 264 fHEventsTrVtx->SetDirectory(0);
265 // fHEventsTrVtx->Sumw2();
266 fList->Add(fHEventsTrVtx);
267
5bb5d1f6 268 fHEventsAccepted = new TH1I("nEventsAccepted",
269 "Number of events w/trigger and vertex in range",
270 2*vtxAxis.GetNbins(),
271 2*vtxAxis.GetXmin(),
272 2*vtxAxis.GetXmax());
273 fHEventsAccepted->SetXTitle("v_{z} [cm]");
274 fHEventsAccepted->SetYTitle("# of events");
275 fHEventsAccepted->SetFillColor(kGreen+1);
276 fHEventsAccepted->SetFillStyle(3001);
277 fHEventsAccepted->SetDirectory(0);
278 // fHEventsAccepted->Sumw2();
279 fList->Add(fHEventsAccepted);
280
96110c91 281 fHEventsAcceptedXY = new TH2D("nEventsAcceptedXY",
282 "XY vertex w/trigger and Z vertex in range",
283 1000,-1,1,1000,-1,1);
284
285 fHEventsAcceptedXY->SetXTitle("v_{x} [cm]");
286 fHEventsAcceptedXY->SetYTitle("v_{y} [cm]");
287 fHEventsAcceptedXY->SetDirectory(0);
288 // fHEventsAccepted->Sumw2();
289 fList->Add(fHEventsAcceptedXY);
290
291
0be6c8cd 292 fHTriggers = new TH1I("triggers", "Triggers", kOffline+1, 0, kOffline+1);
8565b10b 293 fHTriggers->SetFillColor(kRed+1);
294 fHTriggers->SetFillStyle(3001);
295 fHTriggers->SetStats(0);
296 fHTriggers->SetDirectory(0);
297 fHTriggers->GetXaxis()->SetBinLabel(kInel +1,"INEL");
298 fHTriggers->GetXaxis()->SetBinLabel(kInelGt0+1,"INEL>0");
299 fHTriggers->GetXaxis()->SetBinLabel(kNSD +1,"NSD");
e6463868 300 fHTriggers->GetXaxis()->SetBinLabel(kV0AND +1,"VOAND");
8565b10b 301 fHTriggers->GetXaxis()->SetBinLabel(kEmpty +1,"Empty");
302 fHTriggers->GetXaxis()->SetBinLabel(kA +1,"A");
303 fHTriggers->GetXaxis()->SetBinLabel(kB +1,"B");
304 fHTriggers->GetXaxis()->SetBinLabel(kC +1,"C");
305 fHTriggers->GetXaxis()->SetBinLabel(kE +1,"E");
e58000b7 306 fHTriggers->GetXaxis()->SetBinLabel(kPileUp +1,"Pileup");
0be6c8cd 307 fHTriggers->GetXaxis()->SetBinLabel(kMCNSD +1,"NSD_{MC}");
308 fHTriggers->GetXaxis()->SetBinLabel(kOffline+1,"Offline");
8565b10b 309 fList->Add(fHTriggers);
0bd4b00f 310
311 fHType = new TH1I("type", Form("Event type (cut: SPD mult>%d)",
312 fLowFluxCut), 2, -.5, 1.5);
313 fHType->SetFillColor(kRed+1);
314 fHType->SetFillStyle(3001);
315 fHType->SetStats(0);
316 fHType->SetDirectory(0);
317 fHType->GetXaxis()->SetBinLabel(1,"Low-flux");
318 fHType->GetXaxis()->SetBinLabel(2,"High-flux");
319 fList->Add(fHType);
fe52e455 320
c56f8519 321#if 0
322 // This histogram disabled as it causes problems in the merge
fe52e455 323 fHWords = new TH1I("words", "Trigger words seen", 1, 0, 0);
324 fHWords->SetFillColor(kBlue+1);
325 fHWords->SetFillStyle(3001);
326 fHWords->SetStats(0);
327 fHWords->SetDirectory(0);
328 fHWords->SetBit(TH1::kCanRebin);
329 fList->Add(fHWords);
c56f8519 330#endif
5e4d905e 331
e308a636 332 fHCent = new TH1F("cent", "Centrality", limits.GetSize()-1,limits.GetArray());
5e4d905e 333 fHCent->SetFillColor(kBlue+1);
334 fHCent->SetFillStyle(3001);
335 fHCent->SetStats(0);
336 fHCent->SetDirectory(0);
337 fHCent->SetXTitle("Centrality [%]");
338 fHCent->SetYTitle("Events");
339 fList->Add(fHCent);
e308a636 340
341 fHCentVsQual = new TH2F("centVsQuality", "Quality vs Centrality",
342 5, 0, 5, limits.GetSize()-1, limits.GetArray());
343 fHCentVsQual->SetXTitle("Quality");
344 fHCentVsQual->SetYTitle("Centrality [%]");
345 fHCentVsQual->SetZTitle("Events");
346 fHCentVsQual->GetXaxis()->SetBinLabel(1, "OK");
347 fHCentVsQual->GetXaxis()->SetBinLabel(2, "Outside v_{z} cut");
348 fHCentVsQual->GetXaxis()->SetBinLabel(3, "V0 vs SPD outlier");
349 fHCentVsQual->GetXaxis()->SetBinLabel(4, "V0 vs TPC outlier");
350 fHCentVsQual->GetXaxis()->SetBinLabel(5, "V0 vs ZDC outlier");
351 fList->Add(fHCentVsQual);
8565b10b 352}
353
f7cfc454 354//____________________________________________________________________
355void
9b2f2e39 356AliFMDEventInspector::StoreInformation(Int_t runNo)
f7cfc454 357{
358 // Write TNamed objects to output list containing information about
359 // the running conditions
360 if (!fList) return;
361
362 TNamed* sys = new TNamed("sys", "");
363 TNamed* sNN = new TNamed("sNN", "");
364 TNamed* fld = new TNamed("field", "");
9b2f2e39 365 TNamed* run = new TNamed("runNo", Form("%d", runNo));
e6463868 366 TNamed* low = new TNamed("lowFlux", Form("%d", fLowFluxCut));
367 TNamed* fpv = new TNamed("fpVtx", Form("%s", fUseFirstPhysicsVertex ? "true" : "false"));
368 TNamed* v0a = new TNamed("v0and", Form("%s", fUseV0AND ? "true" : "false"));
369 TNamed* nCp = new TNamed("nPileup", Form("%d", fMinPileupContrib));
f7cfc454 370 sys->SetTitle(AliForwardUtil::CollisionSystemString(fCollisionSystem));
371 sNN->SetTitle(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
372 fld->SetTitle(AliForwardUtil::MagneticFieldString(fField));
373 sys->SetUniqueID(fCollisionSystem);
374 sNN->SetUniqueID(fEnergy);
375 fld->SetUniqueID(fField);
9b2f2e39 376 run->SetUniqueID(runNo);
e6463868 377 low->SetUniqueID(fLowFluxCut);
378 fpv->SetUniqueID(fUseFirstPhysicsVertex ? 1 : 0);
379 v0a->SetUniqueID(fUseV0AND ? 1 : 0);
380 nCp->SetUniqueID(fMinPileupContrib);
f7cfc454 381
e6463868 382 TParameter<Double_t>* dP = new TParameter<Double_t>("dPileup", fMinPileupDistance);
f7cfc454 383 fList->Add(sys);
384 fList->Add(sNN);
385 fList->Add(fld);
e6463868 386 fList->Add(run);
387 fList->Add(low);
388 fList->Add(fpv);
389 fList->Add(v0a);
390 fList->Add(nCp);
391 fList->Add(dP);
392
393
f7cfc454 394}
395
8565b10b 396//____________________________________________________________________
397void
398AliFMDEventInspector::DefineOutput(TList* dir)
399{
7984e5f7 400 //
401 // Define the output histograms. These are put in a sub list of the
402 // passed list. The histograms are merged before the parent task calls
403 // AliAnalysisTaskSE::Terminate
404 //
405 // dir Directory to add to
406 //
8565b10b 407 fList = new TList;
408 fList->SetName(GetName());
409 dir->Add(fList);
410}
411
412//____________________________________________________________________
413UInt_t
414AliFMDEventInspector::Process(const AliESDEvent* event,
415 UInt_t& triggers,
416 Bool_t& lowFlux,
0bd4b00f 417 UShort_t& ivz,
5e4d905e 418 Double_t& vz,
5bb5d1f6 419 Double_t& cent,
420 UShort_t& nClusters)
8565b10b 421{
7984e5f7 422 //
423 // Process the event
424 //
425 // Parameters:
426 // event Input event
427 // triggers On return, the triggers fired
428 // lowFlux On return, true if the event is considered a low-flux
429 // event (according to the setting of fLowFluxCut)
430 // ivz On return, the found vertex bin (1-based). A zero
431 // means outside of the defined vertex range
432 // vz On return, the z position of the interaction
5e4d905e 433 // cent On return, the centrality - if not available < 0
7984e5f7 434 //
435 // Return:
436 // 0 (or kOk) on success, otherwise a bit mask of error codes
437 //
438
e1f47419 439 // --- Check that we have an event ---------------------------------
8565b10b 440 if (!event) {
441 AliWarning("No ESD event found for input event");
442 return kNoEvent;
443 }
444
e1f47419 445 // --- Read trigger information from the ESD and store in AOD object
5bb5d1f6 446 if (!ReadTriggers(event, triggers, nClusters)) {
0bd4b00f 447 if (fDebug > 2) {
448 AliWarning("Failed to read triggers from ESD"); }
8565b10b 449 return kNoTriggers;
450 }
451
e1f47419 452 // --- Check if this is a high-flux event --------------------------
8565b10b 453 const AliMultiplicity* testmult = event->GetMultiplicity();
454 if (!testmult) {
0bd4b00f 455 if (fDebug > 3) {
456 AliWarning("No central multiplicity object found"); }
8565b10b 457 }
e1f47419 458 else
459 lowFlux = testmult->GetNumberOfTracklets() < fLowFluxCut;
5e4d905e 460
0bd4b00f 461 fHType->Fill(lowFlux ? 0 : 1);
5e4d905e 462
e1f47419 463 // --- Read centrality information
e308a636 464 cent = -10;
465 UShort_t qual = 0;
466 if (!ReadCentrality(event, cent, qual)) {
e1f47419 467 if (fDebug > 3)
468 AliWarning("Failed to get centrality");
8565b10b 469 }
e308a636 470 fHCent->Fill(cent);
471 if (qual == 0) fHCentVsQual->Fill(0., cent);
472 else {
473 for (UShort_t i = 0; i < 4; i++)
474 if (qual & (1 << i)) fHCentVsQual->Fill(Double_t(i+1), cent);
475 }
8565b10b 476
e1f47419 477 // --- Get the vertex information ----------------------------------
96110c91 478
479 Double_t vx = 0;
480 Double_t vy = 0;
8565b10b 481 vz = 0;
96110c91 482
483 Bool_t vzOk = ReadVertex(event, vz,vx,vy);
8565b10b 484
485 fHEventsTr->Fill(vz);
486 if (!vzOk) {
0bd4b00f 487 if (fDebug > 3) {
488 AliWarning("Failed to read vertex from ESD"); }
8565b10b 489 return kNoVertex;
490 }
491 fHEventsTrVtx->Fill(vz);
96110c91 492
e1f47419 493 // --- Get the vertex bin ------------------------------------------
5bb5d1f6 494 ivz = fVtxAxis.FindBin(vz);
495 if (ivz <= 0 || ivz > fVtxAxis.GetNbins()) {
0bd4b00f 496 if (fDebug > 3) {
8565b10b 497 AliWarning(Form("Vertex @ %f outside of range [%f,%f]",
5bb5d1f6 498 vz, fVtxAxis.GetXmin(), fVtxAxis.GetXmax()));
499 }
0bd4b00f 500 ivz = 0;
8565b10b 501 return kBadVertex;
502 }
5bb5d1f6 503 fHEventsAccepted->Fill(vz);
96110c91 504 fHEventsAcceptedXY->Fill(vx,vy);
e58000b7 505
e1f47419 506 // --- Check the FMD ESD data --------------------------------------
507 if (!event->GetFMDData()) {
508 if (fDebug > 3) {
509 AliWarning("No FMD data found in ESD"); }
510 return kNoFMD;
511 }
512
e58000b7 513
8565b10b 514 return kOk;
515}
516
e1f47419 517//____________________________________________________________________
518Bool_t
e308a636 519AliFMDEventInspector::ReadCentrality(const AliESDEvent* esd,
520 Double_t& cent,
521 UShort_t& qual) const
e1f47419 522{
523 //
524 // Read centrality from event
525 //
526 // Parameters:
527 // esd Event
528 // cent On return, the centrality or negative if not found
529 //
530 // Return:
531 // False on error, true otherwise
532 //
e308a636 533 cent = -1;
534 qual = 0;
e1f47419 535 AliCentrality* centObj = const_cast<AliESDEvent*>(esd)->GetCentrality();
e308a636 536 if (!centObj) return true;
537
538 // AliInfo(Form("Got centrality object %p with quality %d",
539 // centObj, centObj->GetQuality()));
540 // centObj->Print();
541 cent = centObj->GetCentralityPercentile("V0M");
fd36b8a6 542 //cent = centObj->GetCentralityPercentile("ZEMvsZDC");
e308a636 543 qual = centObj->GetQuality();
e1f47419 544
545 return true;
546}
547
8565b10b 548//____________________________________________________________________
549Bool_t
5bb5d1f6 550AliFMDEventInspector::ReadTriggers(const AliESDEvent* esd, UInt_t& triggers,
551 UShort_t& nClusters)
8565b10b 552{
7984e5f7 553 //
554 // Read the trigger information from the ESD event
555 //
556 // Parameters:
557 // esd ESD event
558 // triggers On return, contains the trigger bits
559 //
560 // Return:
561 // @c true on success, @c false otherwise
562 //
8565b10b 563 triggers = 0;
564
565 // Get the analysis manager - should always be there
566 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
567 if (!am) {
568 AliWarning("No analysis manager defined!");
569 return kFALSE;
570 }
571
572 // Get the input handler - should always be there
573 AliInputEventHandler* ih =
574 static_cast<AliInputEventHandler*>(am->GetInputEventHandler());
575 if (!ih) {
576 AliWarning("No input handler");
577 return kFALSE;
578 }
e85a76b7 579 AliPhysicsSelection* ps =
580 static_cast<AliPhysicsSelection*>(ih->GetEventSelection());
581 if (!ps) {
582 AliWarning("No physics selection");
583 return kFALSE;
584 }
585 AliOADBPhysicsSelection* oadb =
586 const_cast<AliOADBPhysicsSelection*>(ps->GetOADBPhysicsSelection());
587 if (!oadb) {
588 AliWarning("No OADB physics selection object");
589 return kFALSE;
590 }
591
e1f47419 592 // Check if this is a collision candidate (MB)
e333578d 593 // Note, that we should use the value cached in the input
594 // handler rather than calling IsCollisionCandiate directly
595 // on the AliPhysicsSelection obejct. If we called the latter
596 // then the AliPhysicsSelection object would overcount by a
597 // factor of 2! :-(
11d40ecb 598 Bool_t offline = ih->IsEventSelected() ;
599 Bool_t fastonly = (ih->IsEventSelected() & AliVEvent::kFastOnly);
59acef00 600 TString trigStr = esd->GetFiredTriggerClasses();
11d40ecb 601
460a5c02 602 //If we have the MC input handler, this must be MC
603 Bool_t isMC = am->GetMCtruthEventHandler() != 0;
604
11d40ecb 605 // For the 2.76 TeV p+p run, the FMD ran in the slow partition
606 // so it received no triggers from the fast partition. Therefore
607 // the fast triggers are removed here but not for MC where all
608 // triggers are fast.
11d40ecb 609 if(TMath::Abs(fEnergy - 2750.) < 20 &&
610 fCollisionSystem == AliForwardUtil::kPP &&
611 !isMC)
612 if (fastonly) offline = false;
5bb5d1f6 613 nClusters = 0;
59acef00 614
615 // MUON triggers are not strictly minimum bias (MB) so they are removed (HHD)
616
617 if(offline && trigStr.Contains("CMUS1")) offline = false;
618
e6463868 619 if (offline) {
0be6c8cd 620 triggers |= AliAODForwardMult::kOffline;
8565b10b 621 triggers |= AliAODForwardMult::kInel;
0be6c8cd 622 fHTriggers->Fill(kOffline+0.5);
8565b10b 623
0be6c8cd 624 // If this is inel, see if we have a tracklet
8565b10b 625 const AliMultiplicity* spdmult = esd->GetMultiplicity();
626 if (!spdmult) {
627 AliWarning("No SPD multiplicity");
628 }
629 else {
e333578d 630 // Check if we have one or more tracklets
631 // in the range -1 < eta < 1 to set the INEL>0
632 // trigger flag.
5bb5d1f6 633 //
634 // Also count tracklets as a single cluster
8565b10b 635 Int_t n = spdmult->GetNumberOfTracklets();
636 for (Int_t j = 0; j < n; j++) {
637 if(TMath::Abs(spdmult->GetEta(j)) < 1) {
638 triggers |= AliAODForwardMult::kInelGt0;
5bb5d1f6 639 nClusters++;
8565b10b 640 }
641 }
5bb5d1f6 642 n = spdmult->GetNumberOfSingleClusters();
643 for (Int_t j = 0; j < n; j++) {
644 Double_t eta = -TMath::Log(TMath::Tan(spdmult->GetThetaSingle(j)/2.));
645 if (TMath::Abs(eta) < 1) nClusters++;
646 }
8565b10b 647 }
5bb5d1f6 648 if (nClusters > 0) triggers |= AliAODForwardMult::kNClusterGt0;
8565b10b 649 }
11d40ecb 650
8565b10b 651 // Analyse some trigger stuff
652 AliTriggerAnalysis ta;
e6463868 653 if (ta.IsOfflineTriggerFired(esd, AliTriggerAnalysis::kV0AND)) {
654 triggers |= AliAODForwardMult::kV0AND;
655 if (fUseV0AND)
31554871 656 triggers |= AliAODForwardMult::kNSD;
657 }
e6463868 658 if (ta.IsOfflineTriggerFired(esd, AliTriggerAnalysis::kNSD1))
659 triggers |= AliAODForwardMult::kNSD;
31554871 660
5bb5d1f6 661 // Check for multiple vertices (pile-up) with at least 3
662 // contributors and at least 0.8cm from the primary vertex
10f6a070 663 Bool_t pileup = kFALSE;
664 if(fCollisionSystem == AliForwardUtil::kPP)
e6463868 665 pileup = esd->IsPileupFromSPD(fMinPileupContrib,fMinPileupDistance);
e58000b7 666 if (pileup) {
667 triggers |= AliAODForwardMult::kPileUp;
668 fHTriggers->Fill(kPileUp+.5);
669 }
59acef00 670
8565b10b 671 // Get trigger stuff
59acef00 672
673 //TString trigStr = esd->GetFiredTriggerClasses();
fe52e455 674 // AliWarning(Form("Fired trigger classes: %s", trigStr.Data()));
c56f8519 675 if (fHWords) fHWords->Fill(trigStr.Data(), 1);
fe52e455 676#if 0
677 if (trigStr.Contains("MB1") || trigStr.Contains("MBBG3"))
0be6c8cd 678 triggers |= AliAOODForwardMult::kB;
fe52e455 679 if (trigStr.Contains("COTA"))
680 triggers |= AliAODForwardMult::kA;
681 if (trigStr.Contains("COTC"))
682 triggers |= AliAODForwardMult::kC;
683#endif
8565b10b 684 if (trigStr.Contains("CBEAMB-ABCE-NOPF-ALL")) {
685 triggers |= AliAODForwardMult::kEmpty;
686 fHTriggers->Fill(kEmpty+.5);
687 }
e85a76b7 688#if 0
d969d4af 689 // Check for B triggers
690 if (trigStr.Contains("CINT1B-ABCE-NOPF-ALL") || // Early pp
691 trigStr.Contains("CINT1-B-NOPF-ALLNOTRD") || // Late pp
59acef00 692 trigStr.Contains("CINT1-B-NOPF-FASTNOTRD") || // Late pp
693 //trigStr.Contains("CMUS1-B-NOPF-MUON") || // Late pp -- HHD 160811
d969d4af 694 trigStr.Contains("CSMBB-ABCE-NOPF-ALL") || // pp
695 trigStr.Contains("CMBACS2-B-NOPF-ALL") || // PbPb
696 // trigStr.Contains("C0SMH-B-NOPF-ALL") || // PbPb - high mult
697 trigStr.Contains("CMBS2A-B-NOPF-ALL") || // PbPb
698 trigStr.Contains("CMBS2C-B-NOPF-ALL") || // PbPb
699 trigStr.Contains("CMBAC-B-NOPF-ALL") || // PbPb
700 // trigStr.Contains("C0SMH-B-NOPF-ALL") || // PbPb - high mult
701 trigStr.Contains("CMBACS2-B-NOPF-ALLNOTRD") // PbPb
702 // trigStr.Contains("C0SMH-B-NOPF-ALLNOTRD") // PbPb - high mult
703 ) {
59acef00 704 Bool_t bTrigger = kTRUE;
705 if ( trigStr.Contains("CINT1-B-NOPF-FASTNOTRD") &&
706 !trigStr.Contains("CINT1-B-NOPF-ALLNOTRD") &&
707 TMath::Abs(fEnergy - 2750.) < 20 &&
708 fCollisionSystem == AliForwardUtil::kPP)
709 bTrigger = kFALSE;
710 if(bTrigger) {
711 triggers |= AliAODForwardMult::kB;
712 fHTriggers->Fill(kB+.5);
713 }
8565b10b 714 }
d969d4af 715
716 // Check for A triggers
8d847dd3 717 if (trigStr.Contains("CINT1A-ABCE-NOPF-ALL") || // Early pp
718 trigStr.Contains("CINT1-AC-NOPF-ALLNOTRD") || // Late pp
719 trigStr.Contains("CINT1-AC-NOPF-FASTNOTRD") || // Late pp
d969d4af 720 (trigStr.Contains("CSMBA-ABCE-NOPF-ALL") &&
8d847dd3 721 !(triggers & AliAODForwardMult::kB)) || // pp
722 trigStr.Contains("CMBACS2-A-NOPF-ALL") || // PbPb
723 // trigStr.Contains("C0SMH-A-NOPF-ALL") || // PbPb - high mult
724 trigStr.Contains("CMBS2A-A-NOPF-ALL") || // PbPb
725 trigStr.Contains("CMBS2C-A-NOPF-ALL") || // PbPb
726 trigStr.Contains("CMBAC-A-NOPF-ALL") || // PbPb
727 // trigStr.Contains("C0SMH-A-NOPF-ALL") || // PbPb - high mult
d969d4af 728 trigStr.Contains("CMBACS2-A-NOPF-ALLNOTRD") // PbPb
729 // trigStr.Contains("C0SMH-A-NOPF-ALLNOTRD") // PbPb - high mult
730 ) {
731 triggers |= AliAODForwardMult::kA;
732 fHTriggers->Fill(kA+.5);
733 }
8565b10b 734
d969d4af 735 // Check for C triggers
736 if (trigStr.Contains("CINT1C-ABCE-NOPF-ALL") || // Early pp
737 (trigStr.Contains("CSMBC-ABCE-NOPF-ALL") &&
738 !(triggers & AliAODForwardMult::kB)) || // pp
739 trigStr.Contains("CMBACS2-C-NOPF-ALL") || // PbPb
740 // trigStr.Contains("C0SMH-B-NOPF-ALL") || // PbPb - high mult
741 trigStr.Contains("CMBS2A-C-NOPF-ALL") || // PbPb
742 trigStr.Contains("CMBS2C-C-NOPF-ALL") || // PbPb
743 trigStr.Contains("CMBAC-C-NOPF-ALL") || // PbPb
744 // trigStr.Contains("C0SMH-B-NOPF-ALL") || // PbPb - high mult
745 trigStr.Contains("CMBACS2-C-NOPF-ALLNOTRD") // PbPb
746 // trigStr.Contains("C0SMH-B-NOPF-ALLNOTRD") // PbPb - high mult
747 ) {
8565b10b 748 triggers |= AliAODForwardMult::kC;
749 fHTriggers->Fill(kC+.5);
750 }
751
d969d4af 752 // Check for E triggers
753 if (trigStr.Contains("CINT1-E-NOPF-ALL") || // Early pp
754 trigStr.Contains("CINT1-E-NOPF-ALLNOTRD") || // Late pp
308e9175 755 trigStr.Contains("CINT1-E-NOPF-FASTNOTRD") || // Late pp
d969d4af 756 trigStr.Contains("CMBACS2-E-NOPF-ALL") || // PbPb
757 // trigStr.Contains("C0SMH-B-NOPF-ALL") || // PbPb - high mult
758 trigStr.Contains("CMBS2A-E-NOPF-ALL") || // PbPb
759 trigStr.Contains("CMBS2C-E-NOPF-ALL") || // PbPb
760 trigStr.Contains("CMBAC-E-NOPF-ALL") || // PbPb
761 // trigStr.Contains("C0SMH-B-NOPF-ALL") || // PbPb - high mult
762 trigStr.Contains("CMBACS2-E-NOPF-ALLNOTRD") // PbPb
763 // trigStr.Contains("C0SMH-B-NOPF-ALLNOTRD") // PbPb - high mult
764 ) {
8565b10b 765 triggers |= AliAODForwardMult::kE;
766 fHTriggers->Fill(kE+.5);
767 }
e85a76b7 768#endif
769
770 const TList* collTriggClasses = ps->GetCollisionTriggerClasses();
771 const TList* bgTriggClasses = ps->GetBGTriggerClasses();
772
773 TIter nextColl(collTriggClasses);
774 TObjString* oadbString = 0;
775 TObjArray* tokens = 0;
776 while ((oadbString = static_cast<TObjString*>(nextColl()))) {
777 tokens = oadbString->String().Tokenize(" ");
778 for (Int_t i = 0; i < tokens->GetEntries(); i++) {
779 TString string = (((TObjString*)tokens->At(i))->String());
780 if (string[0] != '+') continue;
781 string.Remove(0,1);
782 if (trigStr.Contains(string.Data())) {
783 TString beamSide = oadb->GetBeamSide(oadbString->String().Data());
784 if (beamSide.EqualTo("B")) {
785 triggers |= AliAODForwardMult::kB;
786 fHTriggers->Fill(kB+.5);
787 }
788 }
789 }
790 }
791 TIter nextBG(bgTriggClasses);
792 while ((oadbString = static_cast<TObjString*>(nextBG()))) {
793 tokens = oadbString->String().Tokenize(" ");
794 for (Int_t i = 0; i < tokens->GetEntries(); i++) {
795 TString string = (((TObjString*)tokens->At(i))->String());
796 if (string[0] != '+') continue;
797 string.Remove(0,1);
798 if (trigStr.Contains(string.Data())) {
799 TString beamSide = oadb->GetBeamSide(oadbString->String().Data());
800 if (beamSide.Contains("A")) {
801 triggers |= AliAODForwardMult::kA;
802 fHTriggers->Fill(kA+.5);
803 }
804 if (beamSide.Contains("C")) {
805 triggers |= AliAODForwardMult::kC;
806 fHTriggers->Fill(kC+.5);
807 }
808 if (beamSide.Contains("E")) {
809 triggers |= AliAODForwardMult::kE;
810 fHTriggers->Fill(kE+.5);
811 }
812 }
813 }
814 }
8565b10b 815
d969d4af 816 // Now check - if we have a collision - for offline triggers and
817 // fill histogram.
0be6c8cd 818 if (triggers & AliAODForwardMult::kB) {
819 if (triggers & AliAODForwardMult::kInel)
820 fHTriggers->Fill(kInel);
821
822 if (triggers & AliAODForwardMult::kInelGt0)
823 fHTriggers->Fill(kInelGt0+.5);
824
825 if (triggers & AliAODForwardMult::kNSD)
826 fHTriggers->Fill(kNSD+.5);
e6463868 827
828 if (triggers & AliAODForwardMult::kV0AND)
829 fHTriggers->Fill(kV0AND+.5);
0be6c8cd 830 }
831
8565b10b 832 return kTRUE;
833}
834//____________________________________________________________________
835Bool_t
96110c91 836AliFMDEventInspector::ReadVertex(const AliESDEvent* esd,
837 Double_t& vz,
838 Double_t& vx,
839 Double_t& vy)
8565b10b 840{
7984e5f7 841 //
842 // Read the vertex information from the ESD event
843 //
844 // Parameters:
845 // esd ESD event
846 // vz On return, the vertex Z position
847 //
848 // Return:
849 // @c true on success, @c false otherwise
850 //
8565b10b 851 vz = 0;
96110c91 852 vx = 1024;
853 vy = 1024;
e83d0620 854 if(fUseFirstPhysicsVertex) {
855 // This is the code used by the 1st physics people
856 const AliESDVertex* vertex = esd->GetPrimaryVertex();
857 if (!vertex || !vertex->GetStatus()) {
858 if (fDebug > 2) {
859 AliWarning(Form("No primary vertex (%p) or bad status %d",
860 vertex, (vertex ? vertex->GetStatus() : -1)));
861 }
862 return false;
5bb5d1f6 863 }
e83d0620 864 const AliESDVertex* vertexSPD = esd->GetPrimaryVertexSPD();
865 if (!vertexSPD || !vertexSPD->GetStatus()) {
5bb5d1f6 866 if (fDebug > 2) {
e83d0620 867 AliWarning(Form("No primary SPD vertex (%p) or bad status %d",
868 vertexSPD, (vertexSPD ? vertexSPD->GetStatus() : -1)));
5bb5d1f6 869 }
870 return false;
871 }
e83d0620 872
873 // if vertex is from SPD vertexZ, require more stringent cuts
874 if (vertex->IsFromVertexerZ()) {
875 if (vertex->GetDispersion() > fMaxVzErr ||
876 vertex->GetZRes() > 1.25 * fMaxVzErr) {
877 if (fDebug > 2) {
878 AliWarning(Form("Dispersion %f > %f or resolution %f > %f",
879 vertex->GetDispersion(), fMaxVzErr,
880 vertex->GetZRes(), 1.25 * fMaxVzErr));
881 }
882 return false;
883 }
884 }
885 vz = vertex->GetZ();
96110c91 886
887 if(!vertex->IsFromVertexerZ()) {
888 vx = vertex->GetX();
889 vy = vertex->GetY();
890 }
e83d0620 891 return true;
96110c91 892 }
e83d0620 893 else { //Use standard SPD vertex (perhaps preferable for Pb+Pb)
894
895 // Get the vertex
896 const AliESDVertex* vertex = esd->GetPrimaryVertexSPD();
897 if (!vertex) {
898 if (fDebug > 2) {
899 AliWarning("No SPD vertex found in ESD"); }
900 return kFALSE;
901 }
902
903 // Check that enough tracklets contributed
904 if(vertex->GetNContributors() <= 0) {
905 if (fDebug > 2) {
906 AliWarning(Form("Number of contributors to vertex is %d<=0",
907 vertex->GetNContributors())); }
908 vz = 0;
909 return kFALSE;
910 }
911 // Check that the uncertainty isn't too large
912 if (vertex->GetZRes() > fMaxVzErr) {
913 if (fDebug > 2) {
914 AliWarning(Form("Uncertaintity in Z of vertex is too large %f > %f",
0bd4b00f 915 vertex->GetZRes(), fMaxVzErr)); }
e83d0620 916 return kFALSE;
917 }
918
919 // Get the z coordiante
920 vz = vertex->GetZ();
96110c91 921 const AliESDVertex* vertexXY = esd->GetPrimaryVertex();
922
923 if(!vertexXY->IsFromVertexerZ()) {
924 vx = vertexXY->GetX();
925 vy = vertexXY->GetY();
926 }
e83d0620 927 return kTRUE;
928 }
8565b10b 929}
0be6c8cd 930
0bd4b00f 931//____________________________________________________________________
932Bool_t
933AliFMDEventInspector::ReadRunDetails(const AliESDEvent* esd)
934{
7984e5f7 935 //
936 // Read the collision system, collision energy, and L3 field setting
937 // from the ESD
938 //
939 // Parameters:
940 // esd ESD to get information from
941 //
942 // Return:
943 // true on success, false
944 //
cc83fca2 945 // AliInfo(Form("Parameters from 1st ESD event: cms=%s, sNN=%f, field=%f",
946 // esd->GetBeamType(), 2*esd->GetBeamEnergy(),
947 // esd->GetMagneticField()));
0bd4b00f 948 fCollisionSystem =
949 AliForwardUtil::ParseCollisionSystem(esd->GetBeamType());
950 fEnergy =
951 AliForwardUtil::ParseCenterOfMassEnergy(fCollisionSystem,
0be6c8cd 952 2 * esd->GetBeamEnergy());
0bd4b00f 953 fField =
954 AliForwardUtil::ParseMagneticField(esd->GetMagneticField());
f7cfc454 955
9b2f2e39 956 StoreInformation(esd->GetRunNumber());
0bd4b00f 957 if (fCollisionSystem == AliForwardUtil::kUnknown ||
958 fEnergy <= 0 ||
959 TMath::Abs(fField) > 10)
960 return kFALSE;
961
962 return kTRUE;
963}
964
965//____________________________________________________________________
966void
967AliFMDEventInspector::Print(Option_t*) const
968{
7984e5f7 969 //
970 // Print information
971 //
972 // option Not used
973 //
0bd4b00f 974 char ind[gROOT->GetDirLevel()+1];
975 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
976 ind[gROOT->GetDirLevel()] = '\0';
977 TString sNN(AliForwardUtil::CenterOfMassEnergyString(fEnergy));
978 sNN.Strip(TString::kBoth, '0');
979 sNN.ReplaceAll("GeV", " GeV");
980 TString field(AliForwardUtil::MagneticFieldString(fField));
981 field.ReplaceAll("p", "+");
982 field.ReplaceAll("m", "-");
983 field.ReplaceAll("kG", " kG");
984
e1f47419 985 std::cout << ind << ClassName() << ": " << GetName() << '\n'
2a9e4c0b 986 << ind << " Vertex bins: " << fVtxAxis.GetNbins() << '\n'
987 << ind << " Vertex range: [" << fVtxAxis.GetXmin()
988 << "," << fVtxAxis.GetXmax() << "]\n"
0bd4b00f 989 << ind << " Low flux cut: " << fLowFluxCut << '\n'
990 << ind << " Max(delta v_z): " << fMaxVzErr << " cm\n"
e6463868 991 << ind << " Min(nContrib_pileup): " << fMinPileupContrib << '\n'
992 << ind << " Min(v-pileup): " << fMinPileupDistance << '\n'
0bd4b00f 993 << ind << " System: "
994 << AliForwardUtil::CollisionSystemString(fCollisionSystem) << '\n'
995 << ind << " CMS energy per nucleon: " << sNN << '\n'
d8244e9e 996 << ind << " Field: " << field << '\n';
997 if (!fCentAxis) { std::cout << std::flush; return; }
998 Int_t nBin = fCentAxis->GetNbins();
999 std::cout << ind << " Centrality axis: " << nBin << " bins"
1000 << std::flush;
1001 for (Int_t i = 0; i < nBin; i++) {
1002 if ((i % 10) == 0) std::cout << '\n' << ind << " ";
1003 std::cout << std::setw(5) << fCentAxis->GetBinLowEdge(i+1) << '-';
1004 }
1005 std::cout << std::setw(5) << fCentAxis->GetBinUpEdge(nBin) << std::endl;
0bd4b00f 1006}
1007
1008
8565b10b 1009//
1010// EOF
1011//
1012