]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliTriggerAnalysis.cxx
Bugfix: moved the initialization of 4-vectors for daughters before cut checking,...
[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;
463 const AliESDVertex* vertex = aEsd->GetPrimaryVertexSPD();
464 Float_t ptmin, ptmax;
465 fEsdTrackCuts->GetPtRange(ptmin,ptmax);
466 AliDebug(3, Form("ptmin = %f, ptmax = %f\n",ptmin, ptmax));
467
468 if (vertex && vertex->GetNContributors() > 0 && (!vertex->IsFromVertexerZ() || vertex->GetDispersion() < 0.02) && TMath::Abs(vertex->GetZv()) < 10.) {
469 AliDebug(3,Form("Check on the vertex passed\n"));
470 for (Int_t i=0; i<aEsd->GetNumberOfTracks(); ++i){
471 if (fEsdTrackCuts->AcceptTrack(aEsd->GetTrack(i))){
472 AliDebug(2, Form("pt of track = %f --> check passed\n",aEsd->GetTrack(i)->Pt()));
473 decision = kTRUE;
474 break;
475 }
476 }
477 }
478 else{
479 AliDebug(4,Form("Check on the vertex not passed\n"));
480 for (Int_t i=0; i<aEsd->GetNumberOfTracks(); ++i){
481 if (fEsdTrackCuts->AcceptTrack(aEsd->GetTrack(i))){
482 AliDebug(4,Form("pt of track = %f --> check would be passed if the vertex was ok\n",aEsd->GetTrack(i)->Pt()));
483 break;
484 }
485 }
486 }
487 if (!decision) AliDebug(3,("Check for kOneTrack NOT passed\n"));
488 }
489
225667ea 490 return decision;
491}
70fdd197 492
493Bool_t AliTriggerAnalysis::IsTriggerClassFired(const AliESDEvent* aEsd, const Char_t* tclass) const
494{
495 // tclass is logical function of inputs, e.g. 01 && 02 || 03 && 11 && 21
496 // = L0 inp 1 && L0 inp 2 || L0 inp 3 && L1 inp 1 && L2 inp 1
497 // NO brackets in logical function !
498 // Spaces between operators and inputs.
499 // Not all logical functions are available in CTP=
500 // =any function of first 4 inputs; 'AND' of other inputs, check not done
501 // This method will be replaced/complemened by similar one
502 // which works withh class and inputs names as in CTP cfg file
503
504 TString TClass(tclass);
505 TObjArray* tcltokens = TClass.Tokenize(" ");
506 Char_t level=((TObjString*)tcltokens->At(0))->String()[0];
507 UInt_t input=atoi((((TObjString*)tcltokens->At(0))->String()).Remove(0));
508 Bool_t tcl = IsInputFired(aEsd,level,input);
509
510 for (Int_t i=1;i<tcltokens->GetEntriesFast();i=i+2) {
511 level=((TObjString*)tcltokens->At(i+1))->String()[0];
512 input=atoi((((TObjString*)tcltokens->At(i+1))->String()).Remove(0));
513 Bool_t inpnext = IsInputFired(aEsd,level,input);
514 Char_t op =((TObjString*)tcltokens->At(i))->String()[0];
515 if (op == '&') tcl=tcl && inpnext;
516 else if (op == '|') tcl =tcl || inpnext;
517 else {
518 AliError(Form("Syntax error in %s", tclass));
519 tcltokens->Delete();
520 return kFALSE;
521 }
522 }
523 tcltokens->Delete();
524 return tcl;
525}
526
527Bool_t AliTriggerAnalysis::IsInputFired(const AliESDEvent* aEsd, Char_t level, UInt_t input) const
528{
529 // Checks trigger input of any level
530
531 switch (level)
532 {
533 case '0': return IsL0InputFired(aEsd,input);
534 case '1': return IsL1InputFired(aEsd,input);
535 case '2': return IsL2InputFired(aEsd,input);
536 default:
537 AliError(Form("Wrong level %i",level));
538 return kFALSE;
539 }
540}
541
542Bool_t AliTriggerAnalysis::IsL0InputFired(const AliESDEvent* aEsd, UInt_t input) const
543{
544 // Checks if corresponding bit in mask is on
545
546 UInt_t inpmask = aEsd->GetHeader()->GetL0TriggerInputs();
547 return (inpmask & (1<<(input-1)));
548}
549
550Bool_t AliTriggerAnalysis::IsL1InputFired(const AliESDEvent* aEsd, UInt_t input) const
551{
552 // Checks if corresponding bit in mask is on
553
554 UInt_t inpmask = aEsd->GetHeader()->GetL1TriggerInputs();
555 return (inpmask & (1<<(input-1)));
556}
557
558Bool_t AliTriggerAnalysis::IsL2InputFired(const AliESDEvent* aEsd, UInt_t input) const
559{
560 // Checks if corresponding bit in mask is on
561
562 UInt_t inpmask = aEsd->GetHeader()->GetL2TriggerInputs();
563 return (inpmask & (1<<(input-1)));
564}
565
566void AliTriggerAnalysis::FillHistograms(const AliESDEvent* aEsd)
ff8c4f30 567{
907972ff 568 // fills the histograms with the info from the ESD
569
c2fff146 570 fHistBitsSPD->Fill(SPDFiredChips(aEsd, 0), SPDFiredChips(aEsd, 1, kTRUE));
907972ff 571
97fa3cbc 572 V0Trigger(aEsd, kASide, kFALSE, kTRUE);
573 V0Trigger(aEsd, kCSide, kFALSE, kTRUE);
907972ff 574
575 AliESDZDC* zdcData = aEsd->GetESDZDC();
576 if (zdcData)
577 {
578 UInt_t quality = zdcData->GetESDQuality();
579
580 // from Nora's presentation, general first physics meeting 16.10.09
581 static UInt_t zpc = 0x20;
582 static UInt_t znc = 0x10;
583 static UInt_t zem1 = 0x08;
584 static UInt_t zem2 = 0x04;
585 static UInt_t zpa = 0x02;
586 static UInt_t zna = 0x01;
587
588 fHistZDC->Fill(1, quality & zna);
589 fHistZDC->Fill(2, quality & zpa);
590 fHistZDC->Fill(3, quality & zem2);
591 fHistZDC->Fill(4, quality & zem1);
592 fHistZDC->Fill(5, quality & znc);
593 fHistZDC->Fill(6, quality & zpc);
594 }
595 else
596 {
597 fHistZDC->Fill(-1);
598 AliError("AliESDZDC not available");
599 }
600
601 fHistFMDA->Fill(FMDHitCombinations(aEsd, kASide, kTRUE));
602 fHistFMDC->Fill(FMDHitCombinations(aEsd, kCSide, kTRUE));
603}
c01a136b 604
605void AliTriggerAnalysis::FillTriggerClasses(const AliESDEvent* aEsd)
606{
607 // fills trigger classes map
608
609 TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(aEsd->GetFiredTriggerClasses().Data()));
610 if (!count)
611 {
612 count = new TParameter<Long64_t>(aEsd->GetFiredTriggerClasses(), 0);
613 fTriggerClasses->Add(new TObjString(aEsd->GetFiredTriggerClasses().Data()), count);
614 }
615 count->SetVal(count->GetVal() + 1);
616
617 // TODO add first and last orbit number here
618}
907972ff 619
85c71ba7 620Int_t AliTriggerAnalysis::SSDClusters(const AliESDEvent* aEsd)
621{
622 // returns the number of clusters in the SSD
623 const AliMultiplicity* mult = aEsd->GetMultiplicity();
624 Int_t clusters = mult->GetNumberOfITSClusters(4)+mult->GetNumberOfITSClusters(5);
625 return clusters;
626}
627
628
61899827 629Int_t AliTriggerAnalysis::SPDFiredChips(const AliESDEvent* aEsd, Int_t origin, Bool_t fillHists)
907972ff 630{
631 // returns the number of fired chips in the SPD
90dc86e9 632 //
633 // origin = 0 --> aEsd->GetMultiplicity()->GetNumberOfFiredChips() (filled from clusters)
634 // origin = 1 --> aEsd->GetMultiplicity()->TestFastOrFiredChips() (from hardware bits)
ff8c4f30 635
ff8c4f30 636 const AliMultiplicity* mult = aEsd->GetMultiplicity();
637 if (!mult)
638 {
639 AliError("AliMultiplicity not available");
907972ff 640 return -1;
ff8c4f30 641 }
90dc86e9 642
643 if (origin == 0)
644 return mult->GetNumberOfFiredChips(0) + mult->GetNumberOfFiredChips(1);
645
646 if (origin == 1)
647 {
648 Int_t nChips = 0;
649 for (Int_t i=0; i<1200; i++)
733f0542 650 {
90dc86e9 651 if (mult->TestFastOrFiredChips(i) == kTRUE)
c2fff146 652 {
733f0542 653 // efficiency simulation (if enabled)
654 if (fSPDGFOEfficiency)
655 {
656 if (gRandom->Uniform() > fSPDGFOEfficiency->GetBinContent(i+1))
657 continue;
658 }
659
90dc86e9 660 nChips++;
61899827 661 if (fillHists)
c2fff146 662 fHistFiredBitsSPD->Fill(i);
663 }
733f0542 664 }
90dc86e9 665 return nChips;
666 }
667
668 return -1;
907972ff 669}
670
61899827 671Bool_t AliTriggerAnalysis::SPDGFOTrigger(const AliESDEvent* aEsd, Int_t origin)
907972ff 672{
673 // Returns if the SPD gave a global Fast OR trigger
674
c2fff146 675 Int_t firedChips = SPDFiredChips(aEsd, origin);
ff8c4f30 676
677 if (firedChips >= fSPDGFOThreshold)
678 return kTRUE;
679 return kFALSE;
680}
681
97fa3cbc 682AliTriggerAnalysis::V0Decision AliTriggerAnalysis::V0Trigger(const AliESDEvent* aEsd, AliceSide side, Bool_t online, Bool_t fillHists)
ff8c4f30 683{
c01a136b 684 // Returns the V0 trigger decision in V0A | V0C
685 //
733f0542 686 // Returns kV0Fake if the calculated average time is in a window where neither BB nor BG is expected.
687 // The rate of such triggers can be used to estimate the background. Note that the rate has to be
688 // rescaled with the size of the windows (numerical values see below in the code)
689 //
97fa3cbc 690 // argument 'online' is used as a switch between online and offline trigger algorithms
691 //
733f0542 692 // Based on an algorithm by Cvetan Cheshkov
b85bbd53 693
c01a136b 694 AliESDVZERO* esdV0 = aEsd->GetVZEROData();
695 if (!esdV0)
ff8c4f30 696 {
697 AliError("AliESDVZERO not available");
c01a136b 698 return kV0Invalid;
ff8c4f30 699 }
b85bbd53 700 AliDebug(2,Form("In V0Trigger: %f %f",esdV0->GetV0ATime(),esdV0->GetV0CTime()));
97fa3cbc 701
b85bbd53 702 Int_t begin = -1;
703 Int_t end = -1;
704
705 if (side == kASide)
706 {
707 begin = 32;
708 end = 64;
709 }
710 else if (side == kCSide)
711 {
712 begin = 0;
713 end = 32;
714 }
715 else
716 return kV0Invalid;
717
718 if (esdV0->TestBit(AliESDVZERO::kDecisionFilled)) {
988dd3a4 719 if (online) {
b85bbd53 720 if (esdV0->TestBit(AliESDVZERO::kOnlineBitsFilled)) {
721 for (Int_t i = begin; i < end; ++i) {
722 if (esdV0->GetBBFlag(i)) return kV0BB;
723 }
724 for (Int_t i = begin; i < end; ++i) {
725 if (esdV0->GetBGFlag(i)) return kV0BG;
726 }
727 return kV0Empty;
728 }
729 else {
730 AliWarning("V0 online trigger analysis is not yet available!");
731 return kV0BB;
732 }
988dd3a4 733 }
734 else {
735
736 if (fillHists) {
737 if (side == kASide && fHistV0A)
738 fHistV0A->Fill(esdV0->GetV0ATime());
739 if (side == kCSide && fHistV0C)
740 fHistV0C->Fill(esdV0->GetV0CTime());
741 }
742
743 if (side == kASide) return (V0Decision)esdV0->GetV0ADecision();
744 else if (side == kCSide) return (V0Decision)esdV0->GetV0CDecision();
745 else return kV0Invalid;
746 }
747 }
748
c01a136b 749 Float_t time = 0;
bcd135ec 750 Float_t weight = 0;
97fa3cbc 751 if (fMC)
752 {
753 Int_t runRange;
754 if (aEsd->GetRunNumber() <= 104803) runRange = 0;
755 else if (aEsd->GetRunNumber() <= 104876) runRange = 1;
756 else runRange = 2;
757
758 Float_t factors[3][64] = {
759 // runs: 104792-104803
760 {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},
761 // runs: 104841-104876
762 {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},
763 // runs: 104890-92
764 {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}
765 };
766 Float_t dA = 77.4 - 11.0;
767 Float_t dC = 77.4 - 2.9;
768 // Time misalignment
769 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};
770 Float_t dA2 = 2.8, dC2 = 3.3;
771
772 if (online) {
773 for (Int_t i = begin; i < end; ++i) {
774 Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
775 Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
776 if (esdV0->GetTime(i) >= 1e-6 &&
777 tempTime > fV0HwWinLow && tempTime < fV0HwWinHigh &&
778 tempAdc > fV0HwAdcThr)
779 return kV0BB;
780 }
781 return kV0Empty;
782 }
783 else {
784 for (Int_t i = begin; i < end; ++i) {
785 Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
786 Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA : esdV0->GetTime(i)+dC;
787 Float_t tempRawTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
788 if (esdV0->GetTime(i) >= 1e-6 &&
789 tempRawTime < 125.0 &&
790 tempAdc > fV0AdcThr) {
791 weight += 1.0;
792 time += tempTime;
793 }
794 }
795 }
796 }
797 else {
8b16e464 798 if (online) {
799 for (Int_t i = begin; i < end; ++i) {
800 if (esdV0->GetTime(i) >= 1e-6 &&
801 esdV0->GetTime(i) > fV0HwWinLow && esdV0->GetTime(i) < fV0HwWinHigh &&
802 esdV0->GetAdc(i) > fV0HwAdcThr)
803 return kV0BB;
804 }
805 return kV0Empty;
806 }
807 else {
808 for (Int_t i = begin; i < end; ++i) {
809 if (esdV0->GetTime(i) > 1e-6 && esdV0->GetAdc(i) > fV0AdcThr) {
2078f478 810 Float_t correctedTime = V0CorrectLeadingTime(i, esdV0->GetTime(i), esdV0->GetAdc(i),aEsd->GetRunNumber());
8b16e464 811 Float_t timeWeight = V0LeadingTimeWeight(esdV0->GetAdc(i));
812 time += correctedTime*timeWeight;
97fa3cbc 813
8b16e464 814 weight += timeWeight;
815 }
97fa3cbc 816 }
c01a136b 817 }
818 }
907972ff 819
bcd135ec 820 if (weight > 0)
821 time /= weight;
90a4610a 822 time += fV0TimeOffset;
c01a136b 823
824 if (fillHists)
825 {
826 if (side == kASide && fHistV0A)
827 fHistV0A->Fill(time);
828 if (side == kCSide && fHistV0C)
829 fHistV0C->Fill(time);
830 }
907972ff 831
c01a136b 832 if (side == kASide)
833 {
6dc2503d 834 if (time > 68 && time < 100)
c01a136b 835 return kV0BB;
bcd135ec 836 if (time > 54 && time < 57.5)
c01a136b 837 return kV0BG;
6dc2503d 838 if (time > 57.5 && time < 68)
733f0542 839 return kV0Fake;
c01a136b 840 }
907972ff 841
c01a136b 842 if (side == kCSide)
843 {
6dc2503d 844 if (time > 75.5 && time < 100)
c01a136b 845 return kV0BB;
bcd135ec 846 if (time > 69.5 && time < 73)
c01a136b 847 return kV0BG;
733f0542 848 if (time > 55 && time < 69.5)
849 return kV0Fake;
c01a136b 850 }
851
852 return kV0Empty;
853}
854
2078f478 855Float_t AliTriggerAnalysis::V0CorrectLeadingTime(Int_t i, Float_t time, Float_t adc, Int_t runNumber) const
c01a136b 856{
857 // Correct for slewing and align the channels
858 //
bcd135ec 859 // Authors: Cvetan Cheshkov / Raphael Tieulent
c01a136b 860
861 if (time == 0) return 0;
862
bcd135ec 863 // Time alignment
864 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};
865
2078f478 866 if(runNumber < 106031)
867 time -= timeShift[i];
c01a136b 868
869 // Slewing correction
870 if (adc == 0) return time;
871
bcd135ec 872 Float_t p1 = 1.57345e1;
873 Float_t p2 =-4.25603e-1;
874
2078f478 875 if(runNumber >= 106031) adc *= (2.5/4.0);
bcd135ec 876 return (time - p1*TMath::Power(adc,p2));
877}
878
879Float_t AliTriggerAnalysis::V0LeadingTimeWeight(Float_t adc) const
880{
881 if (adc < 1e-6) return 0;
882
883 Float_t p1 = 40.211;
884 Float_t p2 =-4.25603e-1;
885 Float_t p3 = 0.5646;
886
887 return 1./(p1*p1*TMath::Power(adc,2.*(p2-1.))+p3*p3);
ff8c4f30 888}
889
70fdd197 890Bool_t AliTriggerAnalysis::ZDCTrigger(const AliESDEvent* aEsd, AliceSide side) const
ff8c4f30 891{
892 // Returns if ZDC triggered
893
c8d3e441 894 AliESDZDC* zdcData = aEsd->GetESDZDC();
895 if (!zdcData)
896 {
897 AliError("AliESDZDC not available");
898 return kFALSE;
899 }
900
901 UInt_t quality = zdcData->GetESDQuality();
902
903 // from Nora's presentation, general first physics meeting 16.10.09
904 static UInt_t zpc = 0x20;
905 static UInt_t znc = 0x10;
906 static UInt_t zem1 = 0x08;
907 static UInt_t zem2 = 0x04;
908 static UInt_t zpa = 0x02;
909 static UInt_t zna = 0x01;
910
911 if (side == kASide && ((quality & zpa) || (quality & zna)))
912 return kTRUE;
913 if (side == kCentralBarrel && ((quality & zem1) || (quality & zem2)))
914 return kTRUE;
915 if (side == kCSide && ((quality & zpc) || (quality & znc)))
916 return kTRUE;
ff8c4f30 917
918 return kFALSE;
919}
920
61899827 921Int_t AliTriggerAnalysis::FMDHitCombinations(const AliESDEvent* aEsd, AliceSide side, Bool_t fillHists)
ff8c4f30 922{
907972ff 923 // returns number of hit combinations agove threshold
7a11141c 924 //
925 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
ff8c4f30 926
7a11141c 927 // Workaround for AliESDEvent::GetFMDData is not const!
928 const AliESDFMD* fmdData = (const_cast<AliESDEvent*>(aEsd))->GetFMDData();
929 if (!fmdData)
930 {
931 AliError("AliESDFMD not available");
907972ff 932 return -1;
7a11141c 933 }
934
935 Int_t detFrom = (side == kASide) ? 1 : 3;
936 Int_t detTo = (side == kASide) ? 2 : 3;
937
907972ff 938 Int_t triggers = 0;
7a11141c 939 Float_t totalMult = 0;
940 for (UShort_t det=detFrom;det<=detTo;det++) {
941 Int_t nRings = (det == 1 ? 1 : 2);
942 for (UShort_t ir = 0; ir < nRings; ir++) {
943 Char_t ring = (ir == 0 ? 'I' : 'O');
944 UShort_t nsec = (ir == 0 ? 20 : 40);
945 UShort_t nstr = (ir == 0 ? 512 : 256);
039db886 946 for (UShort_t sec =0; sec < nsec; sec++) {
947 for (UShort_t strip = 0; strip < nstr; strip++) {
948 Float_t mult = fmdData->Multiplicity(det,ring,sec,strip);
949 if (mult == AliESDFMD::kInvalidMult) continue;
950
61899827 951 if (fillHists)
907972ff 952 fHistFMDSingle->Fill(mult);
953
039db886 954 if (mult > fFMDLowCut)
955 totalMult = totalMult + mult;
956 else
907972ff 957 {
958 if (totalMult > fFMDHitCut)
959 triggers++;
960
61899827 961 if (fillHists)
907972ff 962 fHistFMDSum->Fill(totalMult);
963
964 totalMult = 0;
965 }
039db886 966 }
7a11141c 967 }
968 }
969 }
907972ff 970
971 return triggers;
972}
973
61899827 974Bool_t AliTriggerAnalysis::FMDTrigger(const AliESDEvent* aEsd, AliceSide side)
907972ff 975{
976 // Returns if the FMD triggered
977 //
978 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
979
980 Int_t triggers = FMDHitCombinations(aEsd, side, kFALSE);
981
982 if (triggers > 0)
983 return kTRUE;
984
ff8c4f30 985 return kFALSE;
986}
907972ff 987
70fdd197 988Long64_t AliTriggerAnalysis::Merge(TCollection* list)
907972ff 989{
990 // Merge a list of AliMultiplicityCorrection objects with this (needed for
991 // PROOF).
992 // Returns the number of merged objects (including this).
993
994 if (!list)
995 return 0;
996
997 if (list->IsEmpty())
998 return 1;
999
1000 TIterator* iter = list->MakeIterator();
1001 TObject* obj;
1002
1003 // collections of all histograms
c01a136b 1004 const Int_t nHists = 9;
907972ff 1005 TList collections[nHists];
1006
1007 Int_t count = 0;
1008 while ((obj = iter->Next())) {
1009
70fdd197 1010 AliTriggerAnalysis* entry = dynamic_cast<AliTriggerAnalysis*> (obj);
907972ff 1011 if (entry == 0)
1012 continue;
1013
c01a136b 1014 Int_t n = 0;
1015 collections[n++].Add(entry->fHistV0A);
1016 collections[n++].Add(entry->fHistV0C);
1017 collections[n++].Add(entry->fHistZDC);
1018 collections[n++].Add(entry->fHistFMDA);
1019 collections[n++].Add(entry->fHistFMDC);
1020 collections[n++].Add(entry->fHistFMDSingle);
1021 collections[n++].Add(entry->fHistFMDSum);
1022 collections[n++].Add(entry->fHistBitsSPD);
1023 collections[n++].Add(entry->fHistFiredBitsSPD);
1024
1025 // merge fTriggerClasses
1026 TIterator* iter2 = entry->fTriggerClasses->MakeIterator();
73dc876a 1027 TObjString* obj2 = 0;
1028 while ((obj2 = dynamic_cast<TObjString*> (iter2->Next())))
c01a136b 1029 {
73dc876a 1030 TParameter<Long64_t>* param2 = dynamic_cast<TParameter<Long64_t>*> (entry->fTriggerClasses->GetValue(obj2));
c01a136b 1031
73dc876a 1032 TParameter<Long64_t>* param1 = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj2));
c01a136b 1033 if (param1)
1034 {
1035 param1->SetVal(param1->GetVal() + param2->GetVal());
1036 }
1037 else
1038 {
1039 param1 = dynamic_cast<TParameter<Long64_t>*> (param2->Clone());
73dc876a 1040 fTriggerClasses->Add(new TObjString(obj2->String()), param1);
c01a136b 1041 }
1042 }
1043
1044 delete iter2;
1045
907972ff 1046 count++;
1047 }
1048
c01a136b 1049 Int_t n = 0;
1050 fHistV0A->Merge(&collections[n++]);
1051 fHistV0C->Merge(&collections[n++]);
1052 fHistZDC->Merge(&collections[n++]);
1053 fHistFMDA->Merge(&collections[n++]);
1054 fHistFMDC->Merge(&collections[n++]);
1055 fHistFMDSingle->Merge(&collections[n++]);
1056 fHistFMDSum->Merge(&collections[n++]);
1057 fHistBitsSPD->Merge(&collections[n++]);
1058 fHistFiredBitsSPD->Merge(&collections[n++]);
1059
907972ff 1060 delete iter;
1061
1062 return count+1;
1063}
1064
61899827 1065void AliTriggerAnalysis::SaveHistograms() const
907972ff 1066{
1067 // write histograms to current directory
1068
c01a136b 1069 if (!fHistBitsSPD)
907972ff 1070 return;
1071
90dc86e9 1072 fHistBitsSPD->Write();
61899827 1073 fHistBitsSPD->ProjectionX();
1074 fHistBitsSPD->ProjectionY();
c2fff146 1075 fHistFiredBitsSPD->Write();
907972ff 1076 fHistV0A->Write();
1077 fHistV0C->Write();
1078 fHistZDC->Write();
1079 fHistFMDA->Write();
1080 fHistFMDC->Write();
1081 fHistFMDSingle->Write();
1082 fHistFMDSum->Write();
c01a136b 1083
733f0542 1084 if (fSPDGFOEfficiency)
1085 fSPDGFOEfficiency->Write("fSPDGFOEfficiency");
1086
c01a136b 1087 fTriggerClasses->Write("fTriggerClasses", TObject::kSingleKey);
1088}
1089
1090void AliTriggerAnalysis::PrintTriggerClasses() const
1091{
1092 // print trigger classes
1093
1094 Printf("Trigger Classes:");
1095
35fb1e58 1096 Printf("Event count for trigger combinations:");
1097
1098 TMap singleTrigger;
1099 singleTrigger.SetOwner();
1100
c01a136b 1101 TIterator* iter = fTriggerClasses->MakeIterator();
1102 TObjString* obj = 0;
1103 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1104 {
35fb1e58 1105 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj));
1106
e8b839ab 1107 Printf(" %s: %ld triggers", obj->String().Data(), (Long_t)param->GetVal());
c01a136b 1108
35fb1e58 1109 TObjArray* tokens = obj->String().Tokenize(" ");
1110 for (Int_t i=0; i<tokens->GetEntries(); i++)
1111 {
1112 TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(((TObjString*) tokens->At(i))->String().Data()));
1113 if (!count)
1114 {
1115 count = new TParameter<Long64_t>(((TObjString*) tokens->At(i))->String().Data(), 0);
1116 singleTrigger.Add(new TObjString(((TObjString*) tokens->At(i))->String().Data()), count);
1117 }
1118 count->SetVal(count->GetVal() + param->GetVal());
1119 }
1120
1121 delete tokens;
c01a136b 1122 }
35fb1e58 1123 delete iter;
1124
1125 Printf("Event count for single trigger:");
1126
1127 iter = singleTrigger.MakeIterator();
1128 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1129 {
1130 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(obj));
1131
e8b839ab 1132 Printf(" %s: %ld triggers", obj->String().Data(), (Long_t)param->GetVal());
35fb1e58 1133 }
1134 delete iter;
1135
1136 singleTrigger.DeleteAll();
907972ff 1137}