Adding layer parameter to SPDFiredChips (0 == both, 1==inner, 2==outer).
[u/mrichter/AliRoot.git] / ANALYSIS / AliTriggerAnalysis.cxx
CommitLineData
70fdd197 1/* $Id: AliTriggerAnalysis.cxx 35782 2009-10-22 11:54:31Z jgrosseo $ */
ff8c4f30 2
7a11141c 3/**************************************************************************
4 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Author: The ALICE Off-line Project. *
7 * Contributors are mentioned in the code where appropriate. *
8 * *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18//-------------------------------------------------------------------------
70fdd197 19// Implementation of Class AliTriggerAnalysis
20// This class provides function to check if events have been triggered based on the data in the ESD
21// The trigger bits, trigger class inputs and only the data (offline trigger) can be used
7a11141c 22// Origin: Jan Fiete Grosse-Oetringhaus, CERN
23//-------------------------------------------------------------------------
24
70fdd197 25#include <Riostream.h>
907972ff 26#include <TH1F.h>
90dc86e9 27#include <TH2F.h>
907972ff 28#include <TList.h>
29#include <TIterator.h>
c01a136b 30#include "TParameter.h"
31#include <TMap.h>
733f0542 32#include <TRandom.h>
907972ff 33
70fdd197 34#include <AliTriggerAnalysis.h>
ff8c4f30 35
36#include <AliLog.h>
37
38#include <AliESDEvent.h>
39
40#include <AliMultiplicity.h>
41#include <AliESDVZERO.h>
c8d3e441 42#include <AliESDZDC.h>
7a11141c 43#include <AliESDFMD.h>
225667ea 44#include <AliESDVertex.h>
449618cd 45#include <AliESDtrackCuts.h>
ff8c4f30 46
70fdd197 47ClassImp(AliTriggerAnalysis)
ff8c4f30 48
70fdd197 49AliTriggerAnalysis::AliTriggerAnalysis() :
90dc86e9 50 fSPDGFOThreshold(2),
733f0542 51 fSPDGFOEfficiency(0),
61899827 52 fV0TimeOffset(0),
97fa3cbc 53 fV0AdcThr(0),
54 fV0HwAdcThr(2.5),
55 fV0HwWinLow(61.5),
56 fV0HwWinHigh(86.5),
90dc86e9 57 fFMDLowCut(0.2),
58 fFMDHitCut(0.5),
90dc86e9 59 fHistBitsSPD(0),
c2fff146 60 fHistFiredBitsSPD(0),
907972ff 61 fHistV0A(0),
61899827 62 fHistV0C(0),
907972ff 63 fHistZDC(0),
64 fHistFMDA(0),
65 fHistFMDC(0),
66 fHistFMDSingle(0),
c01a136b 67 fHistFMDSum(0),
a2ce3799 68 fTriggerClasses(0),
449618cd 69 fMC(kFALSE),
70 fEsdTrackCuts(0)
ff8c4f30 71{
61899827 72 // constructor
73}
74
75AliTriggerAnalysis::~AliTriggerAnalysis()
76{
77 // destructor
78
79 if (fHistBitsSPD)
80 {
81 delete fHistBitsSPD;
82 fHistBitsSPD = 0;
83 }
84
85 if (fHistFiredBitsSPD)
86 {
87 delete fHistFiredBitsSPD;
88 fHistFiredBitsSPD = 0;
89 }
90
91 if (fHistV0A)
92 {
93 delete fHistV0A;
94 fHistV0A = 0;
95 }
96
97 if (fHistV0C)
98 {
99 delete fHistV0C;
100 fHistV0C = 0;
101 }
102
103 if (fHistZDC)
104 {
105 delete fHistZDC;
106 fHistZDC = 0;
107 }
108
109 if (fHistFMDA)
110 {
111 delete fHistFMDA;
112 fHistFMDA = 0;
113 }
114
115 if (fHistFMDC)
116 {
117 delete fHistFMDC;
118 fHistFMDC = 0;
119 }
120
121 if (fHistFMDSingle)
122 {
123 delete fHistFMDSingle;
124 fHistFMDSingle = 0;
125 }
126
127 if (fHistFMDSum)
128 {
129 delete fHistFMDSum;
130 fHistFMDSum = 0;
131 }
132
133 if (fTriggerClasses)
134 {
35fb1e58 135 fTriggerClasses->DeleteAll();
61899827 136 delete fTriggerClasses;
137 fTriggerClasses = 0;
138 }
449618cd 139
140 if (fEsdTrackCuts){
141 delete fEsdTrackCuts;
142 fEsdTrackCuts =0;
143 }
ff8c4f30 144}
145
70fdd197 146void AliTriggerAnalysis::EnableHistograms()
907972ff 147{
148 // creates the monitoring histograms
149
296dd262 150 // do not add this hists to the directory
151 Bool_t oldStatus = TH1::AddDirectoryStatus();
152 TH1::AddDirectory(kFALSE);
153
90dc86e9 154 fHistBitsSPD = new TH2F("fHistBitsSPD", "SPD GFO;number of fired chips (offline);number of fired chips (hardware)", 1202, -1.5, 1200.5, 1202, -1.5, 1200.5);
c01a136b 155 fHistFiredBitsSPD = new TH1F("fHistFiredBitsSPD", "SPD GFO Hardware;chip number;events", 1200, -0.5, 1199.5);
988dd3a4 156 fHistV0A = new TH1F("fHistV0A", "V0A;leading time (ns);events", 400, -100, 100);
157 fHistV0C = new TH1F("fHistV0C", "V0C;leading time (ns);events", 400, -100, 100);
907972ff 158 fHistZDC = new TH1F("fHistZDC", "ZDC;trigger bits;events", 8, -1.5, 6.5);
159
160 // TODO check limits
161 fHistFMDA = new TH1F("fHistFMDA", "FMDA;combinations above threshold;events", 102, -1.5, 100.5);
162 fHistFMDC = new TH1F("fHistFMDC", "FMDC;combinations above threshold;events", 102, -1.5, 100.5);
163 fHistFMDSingle = new TH1F("fHistFMDSingle", "FMD single;multiplicity value;counts", 1000, 0, 10);
164 fHistFMDSum = new TH1F("fHistFMDSum", "FMD sum;multiplicity value;counts", 1000, 0, 10);
c01a136b 165
166 fTriggerClasses = new TMap;
61899827 167 fTriggerClasses->SetOwner();
296dd262 168
169 TH1::AddDirectory(oldStatus);
907972ff 170}
171
70fdd197 172//____________________________________________________________________
173const char* AliTriggerAnalysis::GetTriggerName(Trigger trigger)
174{
175 // returns the name of the requested trigger
176 // the returned string will only be valid until the next call to this function [not thread-safe]
177
178 static TString str;
179
180 UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
181
182 switch (triggerNoFlags)
183 {
184 case kAcceptAll : str = "ACCEPT ALL (bypass!)"; break;
185 case kMB1 : str = "MB1"; break;
186 case kMB2 : str = "MB2"; break;
187 case kMB3 : str = "MB3"; break;
188 case kSPDGFO : str = "SPD GFO"; break;
c2fff146 189 case kSPDGFOBits : str = "SPD GFO Bits"; break;
61899827 190 case kV0A : str = "V0 A BB"; break;
191 case kV0C : str = "V0 C BB"; break;
733f0542 192 case kV0OR : str = "V0 OR BB"; break;
193 case kV0AND : str = "V0 AND BB"; break;
61899827 194 case kV0ABG : str = "V0 A BG"; break;
195 case kV0CBG : str = "V0 C BG"; break;
70fdd197 196 case kZDC : str = "ZDC"; break;
197 case kZDCA : str = "ZDC A"; break;
198 case kZDCC : str = "ZDC C"; break;
199 case kFMDA : str = "FMD A"; break;
200 case kFMDC : str = "FMD C"; break;
201 case kFPANY : str = "SPD GFO | V0 | ZDC | FMD"; break;
733f0542 202 case kNSD1 : str = "NSD1"; break;
97fa3cbc 203 case kMB1Prime: str = "MB1prime"; break;
70fdd197 204 default: str = ""; break;
205 }
206
207 if (trigger & kOfflineFlag)
208 str += " OFFLINE";
209
225667ea 210 if (trigger & kOneParticle)
211 str += " OneParticle";
212
449618cd 213 if (trigger & kOneTrack)
214 str += " OneTrack";
215
70fdd197 216 return str;
217}
218
61899827 219Bool_t AliTriggerAnalysis::IsTriggerFired(const AliESDEvent* aEsd, Trigger trigger)
70fdd197 220{
221 // checks if an event has been triggered
222
223 if (trigger & kOfflineFlag)
224 return IsOfflineTriggerFired(aEsd, trigger);
225
226 return IsTriggerBitFired(aEsd, trigger);
227}
228
229Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, Trigger trigger) const
230{
231 // checks if an event is fired using the trigger bits
232
233 return IsTriggerBitFired(aEsd->GetTriggerMask(), trigger);
234}
235
236Bool_t AliTriggerAnalysis::IsTriggerBitFired(ULong64_t triggerMask, Trigger trigger) const
237{
238 // checks if an event is fired using the trigger bits
239 //
240 // this function needs the branch TriggerMask in the ESD
241
242 // definitions from p-p.cfg
243 ULong64_t spdFO = (1 << 14);
244 ULong64_t v0left = (1 << 10);
245 ULong64_t v0right = (1 << 11);
246
247 switch (trigger)
248 {
249 case kAcceptAll:
250 {
251 return kTRUE;
252 break;
253 }
254 case kMB1:
255 {
256 if (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)))
257 return kTRUE;
258 break;
259 }
260 case kMB2:
261 {
262 if (triggerMask & spdFO && ((triggerMask & v0left) || (triggerMask & v0right)))
263 return kTRUE;
264 break;
265 }
266 case kMB3:
267 {
268 if (triggerMask & spdFO && (triggerMask & v0left) && (triggerMask & v0right))
269 return kTRUE;
270 break;
271 }
272 case kSPDGFO:
273 {
274 if (triggerMask & spdFO)
275 return kTRUE;
276 break;
277 }
278 default:
279 Printf("IsEventTriggered: ERROR: Trigger type %d not implemented in this method", (Int_t) trigger);
280 break;
281 }
282
283 return kFALSE;
284}
285
286Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, ULong64_t tclass) const
287{
288 // Checks if corresponding bit in mask is on
289
290 ULong64_t trigmask = aEsd->GetTriggerMask();
291 return (trigmask & (1ull << (tclass-1)));
292}
293
61899827 294Bool_t AliTriggerAnalysis::IsOfflineTriggerFired(const AliESDEvent* aEsd, Trigger trigger)
ff8c4f30 295{
296 // checks if an event has been triggered "offline"
297
70fdd197 298 UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
ff8c4f30 299
225667ea 300 Bool_t decision = kFALSE;
ff8c4f30 301 switch (triggerNoFlags)
302 {
70fdd197 303 case kAcceptAll:
ff8c4f30 304 {
225667ea 305 decision = kTRUE;
ff8c4f30 306 break;
307 }
70fdd197 308 case kMB1:
ff8c4f30 309 {
97fa3cbc 310 if (SPDGFOTrigger(aEsd, 0) || V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
225667ea 311 decision = kTRUE;
ff8c4f30 312 break;
313 }
70fdd197 314 case kMB2:
ff8c4f30 315 {
97fa3cbc 316 if (SPDGFOTrigger(aEsd, 0) && (V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB))
225667ea 317 decision = kTRUE;
ff8c4f30 318 break;
319 }
70fdd197 320 case kMB3:
ff8c4f30 321 {
97fa3cbc 322 if (SPDGFOTrigger(aEsd, 0) && V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
225667ea 323 decision = kTRUE;
ff8c4f30 324 break;
325 }
70fdd197 326 case kSPDGFO:
ff8c4f30 327 {
c2fff146 328 if (SPDGFOTrigger(aEsd, 0))
225667ea 329 decision = kTRUE;
c2fff146 330 break;
331 }
332 case kSPDGFOBits:
333 {
334 if (SPDGFOTrigger(aEsd, 1))
225667ea 335 decision = kTRUE;
ff8c4f30 336 break;
337 }
70fdd197 338 case kV0A:
ff8c4f30 339 {
97fa3cbc 340 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB)
225667ea 341 decision = kTRUE;
ff8c4f30 342 break;
343 }
70fdd197 344 case kV0C:
ff8c4f30 345 {
97fa3cbc 346 if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
225667ea 347 decision = kTRUE;
ff8c4f30 348 break;
349 }
733f0542 350 case kV0OR:
351 {
97fa3cbc 352 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
225667ea 353 decision = kTRUE;
733f0542 354 break;
355 }
356 case kV0AND:
357 {
97fa3cbc 358 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
225667ea 359 decision = kTRUE;
733f0542 360 break;
361 }
61899827 362 case kV0ABG:
363 {
97fa3cbc 364 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BG)
225667ea 365 decision = kTRUE;
61899827 366 break;
367 }
368 case kV0CBG:
369 {
97fa3cbc 370 if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BG)
225667ea 371 decision = kTRUE;
61899827 372 break;
373 }
70fdd197 374 case kZDC:
c8d3e441 375 {
376 if (ZDCTrigger(aEsd, kASide) || ZDCTrigger(aEsd, kCentralBarrel) || ZDCTrigger(aEsd, kCSide))
225667ea 377 decision = kTRUE;
c8d3e441 378 break;
379 }
70fdd197 380 case kZDCA:
ff8c4f30 381 {
382 if (ZDCTrigger(aEsd, kASide))
225667ea 383 decision = kTRUE;
ff8c4f30 384 break;
385 }
70fdd197 386 case kZDCC:
ff8c4f30 387 {
388 if (ZDCTrigger(aEsd, kCSide))
225667ea 389 decision = kTRUE;
ff8c4f30 390 break;
391 }
70fdd197 392 case kFMDA:
7a11141c 393 {
394 if (FMDTrigger(aEsd, kASide))
225667ea 395 decision = kTRUE;
7a11141c 396 break;
397 }
70fdd197 398 case kFMDC:
7a11141c 399 {
400 if (FMDTrigger(aEsd, kCSide))
225667ea 401 decision = kTRUE;
7a11141c 402 break;
403 }
70fdd197 404 case kFPANY:
ff8c4f30 405 {
97fa3cbc 406 if (SPDGFOTrigger(aEsd, 0) || V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB || ZDCTrigger(aEsd, kASide) || ZDCTrigger(aEsd, kCentralBarrel) || ZDCTrigger(aEsd, kCSide) || FMDTrigger(aEsd, kASide) || FMDTrigger(aEsd, kCSide))
225667ea 407 decision = kTRUE;
ff8c4f30 408 break;
409 }
733f0542 410 case kNSD1:
411 {
97fa3cbc 412 if (SPDFiredChips(aEsd, 0) >= 5 || (V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB))
225667ea 413 decision = kTRUE;
733f0542 414 break;
415 }
97fa3cbc 416 case kMB1Prime:
417 {
418 Int_t count = 0;
419 if (SPDGFOTrigger(aEsd, 0))
420 count++;
421 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB)
422 count++;
423 if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
424 count++;
425
426 if (count >= 2)
225667ea 427 decision = kTRUE;
97fa3cbc 428
429 break;
430 }
ff8c4f30 431 default:
432 {
433 AliFatal(Form("Trigger type %d not implemented", triggerNoFlags));
434 }
435 }
436
225667ea 437 // hadron-level requirement
438 if (decision && (trigger & kOneParticle))
439 {
440 decision = kFALSE;
441
442 const AliESDVertex* vertex = aEsd->GetPrimaryVertexSPD();
443 const AliMultiplicity* mult = aEsd->GetMultiplicity();
ff8c4f30 444
225667ea 445 if (mult && vertex && vertex->GetNContributors() > 0 && (!vertex->IsFromVertexerZ() || vertex->GetDispersion() < 0.02) && TMath::Abs(vertex->GetZv()) < 5.5)
446 {
447 for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
448 {
449 if (TMath::Abs(mult->GetEta(i)) < 1)
450 {
451 decision = kTRUE;
452 break;
453 }
454 }
455 }
456 }
457
449618cd 458 // hadron level definition for TPC tracks
459
460 if (decision && (trigger & kOneTrack))
461 {
462 decision = kFALSE;
b256fde9 463 const AliESDVertex* vertex =0x0;
464 vertex = aEsd->GetPrimaryVertexTracks();
465 if (!vertex || vertex->GetNContributors() <= 0)
466 {
467 vertex = aEsd->GetPrimaryVertexSPD();
468 }
449618cd 469 Float_t ptmin, ptmax;
470 fEsdTrackCuts->GetPtRange(ptmin,ptmax);
471 AliDebug(3, Form("ptmin = %f, ptmax = %f\n",ptmin, ptmax));
472
473 if (vertex && vertex->GetNContributors() > 0 && (!vertex->IsFromVertexerZ() || vertex->GetDispersion() < 0.02) && TMath::Abs(vertex->GetZv()) < 10.) {
474 AliDebug(3,Form("Check on the vertex passed\n"));
475 for (Int_t i=0; i<aEsd->GetNumberOfTracks(); ++i){
476 if (fEsdTrackCuts->AcceptTrack(aEsd->GetTrack(i))){
477 AliDebug(2, Form("pt of track = %f --> check passed\n",aEsd->GetTrack(i)->Pt()));
478 decision = kTRUE;
479 break;
480 }
481 }
482 }
483 else{
484 AliDebug(4,Form("Check on the vertex not passed\n"));
485 for (Int_t i=0; i<aEsd->GetNumberOfTracks(); ++i){
486 if (fEsdTrackCuts->AcceptTrack(aEsd->GetTrack(i))){
487 AliDebug(4,Form("pt of track = %f --> check would be passed if the vertex was ok\n",aEsd->GetTrack(i)->Pt()));
488 break;
489 }
490 }
491 }
492 if (!decision) AliDebug(3,("Check for kOneTrack NOT passed\n"));
493 }
494
225667ea 495 return decision;
496}
70fdd197 497
498Bool_t AliTriggerAnalysis::IsTriggerClassFired(const AliESDEvent* aEsd, const Char_t* tclass) const
499{
500 // tclass is logical function of inputs, e.g. 01 && 02 || 03 && 11 && 21
501 // = L0 inp 1 && L0 inp 2 || L0 inp 3 && L1 inp 1 && L2 inp 1
502 // NO brackets in logical function !
503 // Spaces between operators and inputs.
504 // Not all logical functions are available in CTP=
505 // =any function of first 4 inputs; 'AND' of other inputs, check not done
506 // This method will be replaced/complemened by similar one
507 // which works withh class and inputs names as in CTP cfg file
508
509 TString TClass(tclass);
510 TObjArray* tcltokens = TClass.Tokenize(" ");
511 Char_t level=((TObjString*)tcltokens->At(0))->String()[0];
512 UInt_t input=atoi((((TObjString*)tcltokens->At(0))->String()).Remove(0));
513 Bool_t tcl = IsInputFired(aEsd,level,input);
514
515 for (Int_t i=1;i<tcltokens->GetEntriesFast();i=i+2) {
516 level=((TObjString*)tcltokens->At(i+1))->String()[0];
517 input=atoi((((TObjString*)tcltokens->At(i+1))->String()).Remove(0));
518 Bool_t inpnext = IsInputFired(aEsd,level,input);
519 Char_t op =((TObjString*)tcltokens->At(i))->String()[0];
520 if (op == '&') tcl=tcl && inpnext;
521 else if (op == '|') tcl =tcl || inpnext;
522 else {
523 AliError(Form("Syntax error in %s", tclass));
524 tcltokens->Delete();
525 return kFALSE;
526 }
527 }
528 tcltokens->Delete();
529 return tcl;
530}
531
532Bool_t AliTriggerAnalysis::IsInputFired(const AliESDEvent* aEsd, Char_t level, UInt_t input) const
533{
534 // Checks trigger input of any level
535
536 switch (level)
537 {
538 case '0': return IsL0InputFired(aEsd,input);
539 case '1': return IsL1InputFired(aEsd,input);
540 case '2': return IsL2InputFired(aEsd,input);
541 default:
542 AliError(Form("Wrong level %i",level));
543 return kFALSE;
544 }
545}
546
547Bool_t AliTriggerAnalysis::IsL0InputFired(const AliESDEvent* aEsd, UInt_t input) const
548{
549 // Checks if corresponding bit in mask is on
550
551 UInt_t inpmask = aEsd->GetHeader()->GetL0TriggerInputs();
552 return (inpmask & (1<<(input-1)));
553}
554
555Bool_t AliTriggerAnalysis::IsL1InputFired(const AliESDEvent* aEsd, UInt_t input) const
556{
557 // Checks if corresponding bit in mask is on
558
559 UInt_t inpmask = aEsd->GetHeader()->GetL1TriggerInputs();
560 return (inpmask & (1<<(input-1)));
561}
562
563Bool_t AliTriggerAnalysis::IsL2InputFired(const AliESDEvent* aEsd, UInt_t input) const
564{
565 // Checks if corresponding bit in mask is on
566
567 UInt_t inpmask = aEsd->GetHeader()->GetL2TriggerInputs();
568 return (inpmask & (1<<(input-1)));
569}
570
571void AliTriggerAnalysis::FillHistograms(const AliESDEvent* aEsd)
ff8c4f30 572{
907972ff 573 // fills the histograms with the info from the ESD
574
c2fff146 575 fHistBitsSPD->Fill(SPDFiredChips(aEsd, 0), SPDFiredChips(aEsd, 1, kTRUE));
907972ff 576
97fa3cbc 577 V0Trigger(aEsd, kASide, kFALSE, kTRUE);
578 V0Trigger(aEsd, kCSide, kFALSE, kTRUE);
907972ff 579
580 AliESDZDC* zdcData = aEsd->GetESDZDC();
581 if (zdcData)
582 {
583 UInt_t quality = zdcData->GetESDQuality();
584
585 // from Nora's presentation, general first physics meeting 16.10.09
586 static UInt_t zpc = 0x20;
587 static UInt_t znc = 0x10;
588 static UInt_t zem1 = 0x08;
589 static UInt_t zem2 = 0x04;
590 static UInt_t zpa = 0x02;
591 static UInt_t zna = 0x01;
592
593 fHistZDC->Fill(1, quality & zna);
594 fHistZDC->Fill(2, quality & zpa);
595 fHistZDC->Fill(3, quality & zem2);
596 fHistZDC->Fill(4, quality & zem1);
597 fHistZDC->Fill(5, quality & znc);
598 fHistZDC->Fill(6, quality & zpc);
599 }
600 else
601 {
602 fHistZDC->Fill(-1);
603 AliError("AliESDZDC not available");
604 }
605
606 fHistFMDA->Fill(FMDHitCombinations(aEsd, kASide, kTRUE));
607 fHistFMDC->Fill(FMDHitCombinations(aEsd, kCSide, kTRUE));
608}
c01a136b 609
610void AliTriggerAnalysis::FillTriggerClasses(const AliESDEvent* aEsd)
611{
612 // fills trigger classes map
613
614 TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(aEsd->GetFiredTriggerClasses().Data()));
615 if (!count)
616 {
617 count = new TParameter<Long64_t>(aEsd->GetFiredTriggerClasses(), 0);
618 fTriggerClasses->Add(new TObjString(aEsd->GetFiredTriggerClasses().Data()), count);
619 }
620 count->SetVal(count->GetVal() + 1);
621
622 // TODO add first and last orbit number here
623}
907972ff 624
85c71ba7 625Int_t AliTriggerAnalysis::SSDClusters(const AliESDEvent* aEsd)
626{
627 // returns the number of clusters in the SSD
628 const AliMultiplicity* mult = aEsd->GetMultiplicity();
629 Int_t clusters = mult->GetNumberOfITSClusters(4)+mult->GetNumberOfITSClusters(5);
630 return clusters;
631}
632
633
29533987 634Int_t AliTriggerAnalysis::SPDFiredChips(const AliESDEvent* aEsd, Int_t origin, Bool_t fillHists, Int_t layer)
907972ff 635{
636 // returns the number of fired chips in the SPD
90dc86e9 637 //
638 // origin = 0 --> aEsd->GetMultiplicity()->GetNumberOfFiredChips() (filled from clusters)
639 // origin = 1 --> aEsd->GetMultiplicity()->TestFastOrFiredChips() (from hardware bits)
29533987 640 // layer = 0 --> both layers
641 // layer = 1 --> inner
642 // layer = 2 --> outer
ff8c4f30 643
ff8c4f30 644 const AliMultiplicity* mult = aEsd->GetMultiplicity();
645 if (!mult)
646 {
647 AliError("AliMultiplicity not available");
907972ff 648 return -1;
ff8c4f30 649 }
90dc86e9 650
29533987 651 if (origin == 0){
652 if (layer == 0)
653 return mult->GetNumberOfFiredChips(0) + mult->GetNumberOfFiredChips(1);
654
655 return mult->GetNumberOfFiredChips(layer-1);
656 }
90dc86e9 657
658 if (origin == 1)
659 {
660 Int_t nChips = 0;
29533987 661 Int_t firstChip = 0;
662 Int_t lastChip = 1200;
663 if(layer == 1)
664 lastChip = 400;
665 if(layer == 2)
666 firstChip = 400;
667
90dc86e9 668 for (Int_t i=0; i<1200; i++)
733f0542 669 {
90dc86e9 670 if (mult->TestFastOrFiredChips(i) == kTRUE)
c2fff146 671 {
733f0542 672 // efficiency simulation (if enabled)
673 if (fSPDGFOEfficiency)
674 {
675 if (gRandom->Uniform() > fSPDGFOEfficiency->GetBinContent(i+1))
676 continue;
677 }
678
90dc86e9 679 nChips++;
61899827 680 if (fillHists)
c2fff146 681 fHistFiredBitsSPD->Fill(i);
682 }
733f0542 683 }
90dc86e9 684 return nChips;
685 }
686
687 return -1;
907972ff 688}
689
61899827 690Bool_t AliTriggerAnalysis::SPDGFOTrigger(const AliESDEvent* aEsd, Int_t origin)
907972ff 691{
692 // Returns if the SPD gave a global Fast OR trigger
693
c2fff146 694 Int_t firedChips = SPDFiredChips(aEsd, origin);
ff8c4f30 695
696 if (firedChips >= fSPDGFOThreshold)
697 return kTRUE;
698 return kFALSE;
699}
700
97fa3cbc 701AliTriggerAnalysis::V0Decision AliTriggerAnalysis::V0Trigger(const AliESDEvent* aEsd, AliceSide side, Bool_t online, Bool_t fillHists)
ff8c4f30 702{
c01a136b 703 // Returns the V0 trigger decision in V0A | V0C
704 //
733f0542 705 // Returns kV0Fake if the calculated average time is in a window where neither BB nor BG is expected.
706 // The rate of such triggers can be used to estimate the background. Note that the rate has to be
707 // rescaled with the size of the windows (numerical values see below in the code)
708 //
97fa3cbc 709 // argument 'online' is used as a switch between online and offline trigger algorithms
710 //
733f0542 711 // Based on an algorithm by Cvetan Cheshkov
b85bbd53 712
c01a136b 713 AliESDVZERO* esdV0 = aEsd->GetVZEROData();
714 if (!esdV0)
ff8c4f30 715 {
716 AliError("AliESDVZERO not available");
c01a136b 717 return kV0Invalid;
ff8c4f30 718 }
b85bbd53 719 AliDebug(2,Form("In V0Trigger: %f %f",esdV0->GetV0ATime(),esdV0->GetV0CTime()));
97fa3cbc 720
b85bbd53 721 Int_t begin = -1;
722 Int_t end = -1;
723
724 if (side == kASide)
725 {
726 begin = 32;
727 end = 64;
728 }
729 else if (side == kCSide)
730 {
731 begin = 0;
732 end = 32;
733 }
734 else
735 return kV0Invalid;
736
737 if (esdV0->TestBit(AliESDVZERO::kDecisionFilled)) {
988dd3a4 738 if (online) {
b85bbd53 739 if (esdV0->TestBit(AliESDVZERO::kOnlineBitsFilled)) {
740 for (Int_t i = begin; i < end; ++i) {
741 if (esdV0->GetBBFlag(i)) return kV0BB;
742 }
743 for (Int_t i = begin; i < end; ++i) {
744 if (esdV0->GetBGFlag(i)) return kV0BG;
745 }
746 return kV0Empty;
747 }
748 else {
749 AliWarning("V0 online trigger analysis is not yet available!");
750 return kV0BB;
751 }
988dd3a4 752 }
753 else {
754
755 if (fillHists) {
756 if (side == kASide && fHistV0A)
757 fHistV0A->Fill(esdV0->GetV0ATime());
758 if (side == kCSide && fHistV0C)
759 fHistV0C->Fill(esdV0->GetV0CTime());
760 }
761
762 if (side == kASide) return (V0Decision)esdV0->GetV0ADecision();
763 else if (side == kCSide) return (V0Decision)esdV0->GetV0CDecision();
764 else return kV0Invalid;
765 }
766 }
767
c01a136b 768 Float_t time = 0;
bcd135ec 769 Float_t weight = 0;
97fa3cbc 770 if (fMC)
771 {
772 Int_t runRange;
773 if (aEsd->GetRunNumber() <= 104803) runRange = 0;
774 else if (aEsd->GetRunNumber() <= 104876) runRange = 1;
775 else runRange = 2;
776
777 Float_t factors[3][64] = {
778 // runs: 104792-104803
779 {4.6,5.9,6.3,6.0,4.7,5.9,4.9,5.4,4.8,4.1,4.9,4.6,4.5,5.5,5.1,5.8,4.3,4.0,4.0,3.3,3.1,2.9,3.0,5.6,3.3,4.9,3.9,5.3,4.1,4.4,3.9,5.5,5.7,9.5,5.1,5.3,6.6,7.1,8.9,4.4,4.1,5.9,9.0,4.5,4.1,6.0,4.7,7.1,4.2,4.7,3.9,6.3,5.9,4.8,4.7,4.5,4.7,5.4,5.8,5.0,5.1,5.9,5.3,3.6},
780 // runs: 104841-104876
781 {4.6,4.8,4.9,4.8,4.3,4.9,4.4,4.5,4.6,5.0,4.7,4.6,4.7,4.6,4.6,5.5,4.7,4.5,4.7,5.0,6.5,7.6,5.3,4.9,5.5,4.8,4.6,4.9,4.5,4.5,4.6,4.9,5.7,9.8,4.9,5.2,7.1,7.1,8.1,4.4,4.0,6.0,8.3,4.6,4.2,5.6,4.6,6.4,4.4,4.7,4.5,6.5,6.0,4.7,4.5,4.4,4.8,5.5,5.9,5.3,5.0,5.7,5.1,3.6},
782 // runs: 104890-92
783 {4.7,5.2,4.8,5.0,4.4,5.0,4.4,4.6,4.6,4.5,4.4,4.6,4.5,4.6,4.8,5.5,4.8,4.5,4.4,4.3,5.4,7.7,5.6,5.0,5.4,4.3,4.5,4.8,4.5,4.5,4.6,5.3,5.7,9.6,4.9,5.4,6.1,7.2,8.6,4.4,4.0,5.4,8.8,4.4,4.2,5.8,4.7,6.7,4.3,4.7,4.0,6.1,6.0,4.9,4.8,4.6,4.7,5.2,5.7,5.0,5.0,5.8,5.3,3.6}
784 };
785 Float_t dA = 77.4 - 11.0;
786 Float_t dC = 77.4 - 2.9;
787 // Time misalignment
788 Float_t timeShift[64] = {0.477957 , 0.0889999 , 0.757669 , 0.205439 , 0.239666 , -0.183705 , 0.442873 , -0.281366 , 0.260976 , 0.788995 , 0.974758 , 0.548532 , 0.495023 , 0.868472 , 0.661167 , 0.358307 , 0.221243 , 0.530179 , 1.26696 , 1.33082 , 1.27086 , 1.77133 , 1.10253 , 0.634806 , 2.14838 , 1.50212 , 1.59253 , 1.66122 , 1.16957 , 1.52056 , 1.47791 , 1.81905 , -1.94123 , -1.29124 , -2.16045 , -1.78939 , -3.11111 , -1.87178 , -1.57671 , -1.70311 , -1.81208 , -1.94475 , -2.53058 , -1.7042 , -2.08109 , -1.84416 , -0.61073 , -1.77145 , 0.16999 , -0.0585339 , 0.00401133 , 0.397726 , 0.851111 , 0.264187 , 0.59573 , -0.158263 , 0.584362 , 1.20835 , 0.927573 , 1.13895 , 0.64648 , 2.18747 , 1.68909 , 0.451194};
789 Float_t dA2 = 2.8, dC2 = 3.3;
790
791 if (online) {
792 for (Int_t i = begin; i < end; ++i) {
793 Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
794 Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
795 if (esdV0->GetTime(i) >= 1e-6 &&
796 tempTime > fV0HwWinLow && tempTime < fV0HwWinHigh &&
797 tempAdc > fV0HwAdcThr)
798 return kV0BB;
799 }
800 return kV0Empty;
801 }
802 else {
803 for (Int_t i = begin; i < end; ++i) {
804 Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
805 Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA : esdV0->GetTime(i)+dC;
806 Float_t tempRawTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
807 if (esdV0->GetTime(i) >= 1e-6 &&
808 tempRawTime < 125.0 &&
809 tempAdc > fV0AdcThr) {
810 weight += 1.0;
811 time += tempTime;
812 }
813 }
814 }
815 }
816 else {
8b16e464 817 if (online) {
818 for (Int_t i = begin; i < end; ++i) {
819 if (esdV0->GetTime(i) >= 1e-6 &&
820 esdV0->GetTime(i) > fV0HwWinLow && esdV0->GetTime(i) < fV0HwWinHigh &&
821 esdV0->GetAdc(i) > fV0HwAdcThr)
822 return kV0BB;
823 }
824 return kV0Empty;
825 }
826 else {
827 for (Int_t i = begin; i < end; ++i) {
828 if (esdV0->GetTime(i) > 1e-6 && esdV0->GetAdc(i) > fV0AdcThr) {
2078f478 829 Float_t correctedTime = V0CorrectLeadingTime(i, esdV0->GetTime(i), esdV0->GetAdc(i),aEsd->GetRunNumber());
8b16e464 830 Float_t timeWeight = V0LeadingTimeWeight(esdV0->GetAdc(i));
831 time += correctedTime*timeWeight;
97fa3cbc 832
8b16e464 833 weight += timeWeight;
834 }
97fa3cbc 835 }
c01a136b 836 }
837 }
907972ff 838
bcd135ec 839 if (weight > 0)
840 time /= weight;
90a4610a 841 time += fV0TimeOffset;
c01a136b 842
843 if (fillHists)
844 {
845 if (side == kASide && fHistV0A)
846 fHistV0A->Fill(time);
847 if (side == kCSide && fHistV0C)
848 fHistV0C->Fill(time);
849 }
907972ff 850
c01a136b 851 if (side == kASide)
852 {
6dc2503d 853 if (time > 68 && time < 100)
c01a136b 854 return kV0BB;
bcd135ec 855 if (time > 54 && time < 57.5)
c01a136b 856 return kV0BG;
6dc2503d 857 if (time > 57.5 && time < 68)
733f0542 858 return kV0Fake;
c01a136b 859 }
907972ff 860
c01a136b 861 if (side == kCSide)
862 {
6dc2503d 863 if (time > 75.5 && time < 100)
c01a136b 864 return kV0BB;
bcd135ec 865 if (time > 69.5 && time < 73)
c01a136b 866 return kV0BG;
733f0542 867 if (time > 55 && time < 69.5)
868 return kV0Fake;
c01a136b 869 }
870
871 return kV0Empty;
872}
873
2078f478 874Float_t AliTriggerAnalysis::V0CorrectLeadingTime(Int_t i, Float_t time, Float_t adc, Int_t runNumber) const
c01a136b 875{
876 // Correct for slewing and align the channels
877 //
bcd135ec 878 // Authors: Cvetan Cheshkov / Raphael Tieulent
c01a136b 879
880 if (time == 0) return 0;
881
bcd135ec 882 // Time alignment
883 Float_t timeShift[64] = {0.477957 , 0.0889999 , 0.757669 , 0.205439 , 0.239666 , -0.183705 , 0.442873 , -0.281366 , 0.260976 , 0.788995 , 0.974758 , 0.548532 , 0.495023 , 0.868472 , 0.661167 , 0.358307 , 0.221243 , 0.530179 , 1.26696 , 1.33082 , 1.27086 , 1.77133 , 1.10253 , 0.634806 , 2.14838 , 1.50212 , 1.59253 , 1.66122 , 1.16957 , 1.52056 , 1.47791 , 1.81905 , -1.94123 , -1.29124 , -2.16045 , -1.78939 , -3.11111 , -1.87178 , -1.57671 , -1.70311 , -1.81208 , -1.94475 , -2.53058 , -1.7042 , -2.08109 , -1.84416 , -0.61073 , -1.77145 , 0.16999 , -0.0585339 , 0.00401133 , 0.397726 , 0.851111 , 0.264187 , 0.59573 , -0.158263 , 0.584362 , 1.20835 , 0.927573 , 1.13895 , 0.64648 , 2.18747 , 1.68909 , 0.451194};
884
2078f478 885 if(runNumber < 106031)
886 time -= timeShift[i];
c01a136b 887
888 // Slewing correction
889 if (adc == 0) return time;
890
bcd135ec 891 Float_t p1 = 1.57345e1;
892 Float_t p2 =-4.25603e-1;
893
2078f478 894 if(runNumber >= 106031) adc *= (2.5/4.0);
bcd135ec 895 return (time - p1*TMath::Power(adc,p2));
896}
897
898Float_t AliTriggerAnalysis::V0LeadingTimeWeight(Float_t adc) const
899{
900 if (adc < 1e-6) return 0;
901
902 Float_t p1 = 40.211;
903 Float_t p2 =-4.25603e-1;
904 Float_t p3 = 0.5646;
905
906 return 1./(p1*p1*TMath::Power(adc,2.*(p2-1.))+p3*p3);
ff8c4f30 907}
908
70fdd197 909Bool_t AliTriggerAnalysis::ZDCTrigger(const AliESDEvent* aEsd, AliceSide side) const
ff8c4f30 910{
911 // Returns if ZDC triggered
912
c8d3e441 913 AliESDZDC* zdcData = aEsd->GetESDZDC();
914 if (!zdcData)
915 {
916 AliError("AliESDZDC not available");
917 return kFALSE;
918 }
919
920 UInt_t quality = zdcData->GetESDQuality();
921
922 // from Nora's presentation, general first physics meeting 16.10.09
923 static UInt_t zpc = 0x20;
924 static UInt_t znc = 0x10;
925 static UInt_t zem1 = 0x08;
926 static UInt_t zem2 = 0x04;
927 static UInt_t zpa = 0x02;
928 static UInt_t zna = 0x01;
929
930 if (side == kASide && ((quality & zpa) || (quality & zna)))
931 return kTRUE;
932 if (side == kCentralBarrel && ((quality & zem1) || (quality & zem2)))
933 return kTRUE;
934 if (side == kCSide && ((quality & zpc) || (quality & znc)))
935 return kTRUE;
ff8c4f30 936
937 return kFALSE;
938}
939
61899827 940Int_t AliTriggerAnalysis::FMDHitCombinations(const AliESDEvent* aEsd, AliceSide side, Bool_t fillHists)
ff8c4f30 941{
907972ff 942 // returns number of hit combinations agove threshold
7a11141c 943 //
944 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
ff8c4f30 945
7a11141c 946 // Workaround for AliESDEvent::GetFMDData is not const!
947 const AliESDFMD* fmdData = (const_cast<AliESDEvent*>(aEsd))->GetFMDData();
948 if (!fmdData)
949 {
950 AliError("AliESDFMD not available");
907972ff 951 return -1;
7a11141c 952 }
953
954 Int_t detFrom = (side == kASide) ? 1 : 3;
955 Int_t detTo = (side == kASide) ? 2 : 3;
956
907972ff 957 Int_t triggers = 0;
7a11141c 958 Float_t totalMult = 0;
959 for (UShort_t det=detFrom;det<=detTo;det++) {
960 Int_t nRings = (det == 1 ? 1 : 2);
961 for (UShort_t ir = 0; ir < nRings; ir++) {
962 Char_t ring = (ir == 0 ? 'I' : 'O');
963 UShort_t nsec = (ir == 0 ? 20 : 40);
964 UShort_t nstr = (ir == 0 ? 512 : 256);
039db886 965 for (UShort_t sec =0; sec < nsec; sec++) {
966 for (UShort_t strip = 0; strip < nstr; strip++) {
967 Float_t mult = fmdData->Multiplicity(det,ring,sec,strip);
968 if (mult == AliESDFMD::kInvalidMult) continue;
969
61899827 970 if (fillHists)
907972ff 971 fHistFMDSingle->Fill(mult);
972
039db886 973 if (mult > fFMDLowCut)
974 totalMult = totalMult + mult;
975 else
907972ff 976 {
977 if (totalMult > fFMDHitCut)
978 triggers++;
979
61899827 980 if (fillHists)
907972ff 981 fHistFMDSum->Fill(totalMult);
982
983 totalMult = 0;
984 }
039db886 985 }
7a11141c 986 }
987 }
988 }
907972ff 989
990 return triggers;
991}
992
61899827 993Bool_t AliTriggerAnalysis::FMDTrigger(const AliESDEvent* aEsd, AliceSide side)
907972ff 994{
995 // Returns if the FMD triggered
996 //
997 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
998
999 Int_t triggers = FMDHitCombinations(aEsd, side, kFALSE);
1000
1001 if (triggers > 0)
1002 return kTRUE;
1003
ff8c4f30 1004 return kFALSE;
1005}
907972ff 1006
70fdd197 1007Long64_t AliTriggerAnalysis::Merge(TCollection* list)
907972ff 1008{
1009 // Merge a list of AliMultiplicityCorrection objects with this (needed for
1010 // PROOF).
1011 // Returns the number of merged objects (including this).
1012
1013 if (!list)
1014 return 0;
1015
1016 if (list->IsEmpty())
1017 return 1;
1018
1019 TIterator* iter = list->MakeIterator();
1020 TObject* obj;
1021
1022 // collections of all histograms
c01a136b 1023 const Int_t nHists = 9;
907972ff 1024 TList collections[nHists];
1025
1026 Int_t count = 0;
1027 while ((obj = iter->Next())) {
1028
70fdd197 1029 AliTriggerAnalysis* entry = dynamic_cast<AliTriggerAnalysis*> (obj);
907972ff 1030 if (entry == 0)
1031 continue;
1032
c01a136b 1033 Int_t n = 0;
1034 collections[n++].Add(entry->fHistV0A);
1035 collections[n++].Add(entry->fHistV0C);
1036 collections[n++].Add(entry->fHistZDC);
1037 collections[n++].Add(entry->fHistFMDA);
1038 collections[n++].Add(entry->fHistFMDC);
1039 collections[n++].Add(entry->fHistFMDSingle);
1040 collections[n++].Add(entry->fHistFMDSum);
1041 collections[n++].Add(entry->fHistBitsSPD);
1042 collections[n++].Add(entry->fHistFiredBitsSPD);
1043
1044 // merge fTriggerClasses
1045 TIterator* iter2 = entry->fTriggerClasses->MakeIterator();
73dc876a 1046 TObjString* obj2 = 0;
1047 while ((obj2 = dynamic_cast<TObjString*> (iter2->Next())))
c01a136b 1048 {
73dc876a 1049 TParameter<Long64_t>* param2 = dynamic_cast<TParameter<Long64_t>*> (entry->fTriggerClasses->GetValue(obj2));
c01a136b 1050
73dc876a 1051 TParameter<Long64_t>* param1 = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj2));
c01a136b 1052 if (param1)
1053 {
1054 param1->SetVal(param1->GetVal() + param2->GetVal());
1055 }
1056 else
1057 {
1058 param1 = dynamic_cast<TParameter<Long64_t>*> (param2->Clone());
73dc876a 1059 fTriggerClasses->Add(new TObjString(obj2->String()), param1);
c01a136b 1060 }
1061 }
1062
1063 delete iter2;
1064
907972ff 1065 count++;
1066 }
1067
c01a136b 1068 Int_t n = 0;
1069 fHistV0A->Merge(&collections[n++]);
1070 fHistV0C->Merge(&collections[n++]);
1071 fHistZDC->Merge(&collections[n++]);
1072 fHistFMDA->Merge(&collections[n++]);
1073 fHistFMDC->Merge(&collections[n++]);
1074 fHistFMDSingle->Merge(&collections[n++]);
1075 fHistFMDSum->Merge(&collections[n++]);
1076 fHistBitsSPD->Merge(&collections[n++]);
1077 fHistFiredBitsSPD->Merge(&collections[n++]);
1078
907972ff 1079 delete iter;
1080
1081 return count+1;
1082}
1083
61899827 1084void AliTriggerAnalysis::SaveHistograms() const
907972ff 1085{
1086 // write histograms to current directory
1087
c01a136b 1088 if (!fHistBitsSPD)
907972ff 1089 return;
1090
90dc86e9 1091 fHistBitsSPD->Write();
61899827 1092 fHistBitsSPD->ProjectionX();
1093 fHistBitsSPD->ProjectionY();
c2fff146 1094 fHistFiredBitsSPD->Write();
907972ff 1095 fHistV0A->Write();
1096 fHistV0C->Write();
1097 fHistZDC->Write();
1098 fHistFMDA->Write();
1099 fHistFMDC->Write();
1100 fHistFMDSingle->Write();
1101 fHistFMDSum->Write();
c01a136b 1102
733f0542 1103 if (fSPDGFOEfficiency)
1104 fSPDGFOEfficiency->Write("fSPDGFOEfficiency");
1105
c01a136b 1106 fTriggerClasses->Write("fTriggerClasses", TObject::kSingleKey);
1107}
1108
1109void AliTriggerAnalysis::PrintTriggerClasses() const
1110{
1111 // print trigger classes
1112
1113 Printf("Trigger Classes:");
1114
35fb1e58 1115 Printf("Event count for trigger combinations:");
1116
1117 TMap singleTrigger;
1118 singleTrigger.SetOwner();
1119
c01a136b 1120 TIterator* iter = fTriggerClasses->MakeIterator();
1121 TObjString* obj = 0;
1122 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1123 {
35fb1e58 1124 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj));
1125
e8b839ab 1126 Printf(" %s: %ld triggers", obj->String().Data(), (Long_t)param->GetVal());
c01a136b 1127
35fb1e58 1128 TObjArray* tokens = obj->String().Tokenize(" ");
1129 for (Int_t i=0; i<tokens->GetEntries(); i++)
1130 {
1131 TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(((TObjString*) tokens->At(i))->String().Data()));
1132 if (!count)
1133 {
1134 count = new TParameter<Long64_t>(((TObjString*) tokens->At(i))->String().Data(), 0);
1135 singleTrigger.Add(new TObjString(((TObjString*) tokens->At(i))->String().Data()), count);
1136 }
1137 count->SetVal(count->GetVal() + param->GetVal());
1138 }
1139
1140 delete tokens;
c01a136b 1141 }
35fb1e58 1142 delete iter;
1143
1144 Printf("Event count for single trigger:");
1145
1146 iter = singleTrigger.MakeIterator();
1147 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1148 {
1149 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(obj));
1150
e8b839ab 1151 Printf(" %s: %ld triggers", obj->String().Data(), (Long_t)param->GetVal());
35fb1e58 1152 }
1153 delete iter;
1154
1155 singleTrigger.DeleteAll();
907972ff 1156}