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