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