]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ANALYSIS/AliTriggerAnalysis.cxx
Add online raw reader by Jochen as default version
[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>
ff8c4f30 44
70fdd197 45ClassImp(AliTriggerAnalysis)
ff8c4f30 46
70fdd197 47AliTriggerAnalysis::AliTriggerAnalysis() :
90dc86e9 48 fSPDGFOThreshold(2),
733f0542 49 fSPDGFOEfficiency(0),
61899827 50 fV0TimeOffset(0),
97fa3cbc 51 fV0AdcThr(0),
52 fV0HwAdcThr(2.5),
53 fV0HwWinLow(61.5),
54 fV0HwWinHigh(86.5),
90dc86e9 55 fFMDLowCut(0.2),
56 fFMDHitCut(0.5),
90dc86e9 57 fHistBitsSPD(0),
c2fff146 58 fHistFiredBitsSPD(0),
907972ff 59 fHistV0A(0),
61899827 60 fHistV0C(0),
907972ff 61 fHistZDC(0),
62 fHistFMDA(0),
63 fHistFMDC(0),
64 fHistFMDSingle(0),
c01a136b 65 fHistFMDSum(0),
a2ce3799 66 fTriggerClasses(0),
67 fMC(kFALSE)
ff8c4f30 68{
61899827 69 // constructor
70}
71
72AliTriggerAnalysis::~AliTriggerAnalysis()
73{
74 // destructor
75
76 if (fHistBitsSPD)
77 {
78 delete fHistBitsSPD;
79 fHistBitsSPD = 0;
80 }
81
82 if (fHistFiredBitsSPD)
83 {
84 delete fHistFiredBitsSPD;
85 fHistFiredBitsSPD = 0;
86 }
87
88 if (fHistV0A)
89 {
90 delete fHistV0A;
91 fHistV0A = 0;
92 }
93
94 if (fHistV0C)
95 {
96 delete fHistV0C;
97 fHistV0C = 0;
98 }
99
100 if (fHistZDC)
101 {
102 delete fHistZDC;
103 fHistZDC = 0;
104 }
105
106 if (fHistFMDA)
107 {
108 delete fHistFMDA;
109 fHistFMDA = 0;
110 }
111
112 if (fHistFMDC)
113 {
114 delete fHistFMDC;
115 fHistFMDC = 0;
116 }
117
118 if (fHistFMDSingle)
119 {
120 delete fHistFMDSingle;
121 fHistFMDSingle = 0;
122 }
123
124 if (fHistFMDSum)
125 {
126 delete fHistFMDSum;
127 fHistFMDSum = 0;
128 }
129
130 if (fTriggerClasses)
131 {
35fb1e58 132 fTriggerClasses->DeleteAll();
61899827 133 delete fTriggerClasses;
134 fTriggerClasses = 0;
135 }
ff8c4f30 136}
137
70fdd197 138void AliTriggerAnalysis::EnableHistograms()
907972ff 139{
140 // creates the monitoring histograms
141
296dd262 142 // do not add this hists to the directory
143 Bool_t oldStatus = TH1::AddDirectoryStatus();
144 TH1::AddDirectory(kFALSE);
145
90dc86e9 146 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 147 fHistFiredBitsSPD = new TH1F("fHistFiredBitsSPD", "SPD GFO Hardware;chip number;events", 1200, -0.5, 1199.5);
148 fHistV0A = new TH1F("fHistV0A", "V0A;leading time (ns);events", 200, 0, 100);
149 fHistV0C = new TH1F("fHistV0C", "V0C;leading time (ns);events", 200, 0, 100);
907972ff 150 fHistZDC = new TH1F("fHistZDC", "ZDC;trigger bits;events", 8, -1.5, 6.5);
151
152 // TODO check limits
153 fHistFMDA = new TH1F("fHistFMDA", "FMDA;combinations above threshold;events", 102, -1.5, 100.5);
154 fHistFMDC = new TH1F("fHistFMDC", "FMDC;combinations above threshold;events", 102, -1.5, 100.5);
155 fHistFMDSingle = new TH1F("fHistFMDSingle", "FMD single;multiplicity value;counts", 1000, 0, 10);
156 fHistFMDSum = new TH1F("fHistFMDSum", "FMD sum;multiplicity value;counts", 1000, 0, 10);
c01a136b 157
158 fTriggerClasses = new TMap;
61899827 159 fTriggerClasses->SetOwner();
296dd262 160
161 TH1::AddDirectory(oldStatus);
907972ff 162}
163
70fdd197 164//____________________________________________________________________
165const char* AliTriggerAnalysis::GetTriggerName(Trigger trigger)
166{
167 // returns the name of the requested trigger
168 // the returned string will only be valid until the next call to this function [not thread-safe]
169
170 static TString str;
171
172 UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
173
174 switch (triggerNoFlags)
175 {
176 case kAcceptAll : str = "ACCEPT ALL (bypass!)"; break;
177 case kMB1 : str = "MB1"; break;
178 case kMB2 : str = "MB2"; break;
179 case kMB3 : str = "MB3"; break;
180 case kSPDGFO : str = "SPD GFO"; break;
c2fff146 181 case kSPDGFOBits : str = "SPD GFO Bits"; break;
61899827 182 case kV0A : str = "V0 A BB"; break;
183 case kV0C : str = "V0 C BB"; break;
733f0542 184 case kV0OR : str = "V0 OR BB"; break;
185 case kV0AND : str = "V0 AND BB"; break;
61899827 186 case kV0ABG : str = "V0 A BG"; break;
187 case kV0CBG : str = "V0 C BG"; break;
70fdd197 188 case kZDC : str = "ZDC"; break;
189 case kZDCA : str = "ZDC A"; break;
190 case kZDCC : str = "ZDC C"; break;
191 case kFMDA : str = "FMD A"; break;
192 case kFMDC : str = "FMD C"; break;
193 case kFPANY : str = "SPD GFO | V0 | ZDC | FMD"; break;
733f0542 194 case kNSD1 : str = "NSD1"; break;
97fa3cbc 195 case kMB1Prime: str = "MB1prime"; break;
70fdd197 196 default: str = ""; break;
197 }
198
199 if (trigger & kOfflineFlag)
200 str += " OFFLINE";
201
202 return str;
203}
204
61899827 205Bool_t AliTriggerAnalysis::IsTriggerFired(const AliESDEvent* aEsd, Trigger trigger)
70fdd197 206{
207 // checks if an event has been triggered
208
209 if (trigger & kOfflineFlag)
210 return IsOfflineTriggerFired(aEsd, trigger);
211
212 return IsTriggerBitFired(aEsd, trigger);
213}
214
215Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, Trigger trigger) const
216{
217 // checks if an event is fired using the trigger bits
218
219 return IsTriggerBitFired(aEsd->GetTriggerMask(), trigger);
220}
221
222Bool_t AliTriggerAnalysis::IsTriggerBitFired(ULong64_t triggerMask, Trigger trigger) const
223{
224 // checks if an event is fired using the trigger bits
225 //
226 // this function needs the branch TriggerMask in the ESD
227
228 // definitions from p-p.cfg
229 ULong64_t spdFO = (1 << 14);
230 ULong64_t v0left = (1 << 10);
231 ULong64_t v0right = (1 << 11);
232
233 switch (trigger)
234 {
235 case kAcceptAll:
236 {
237 return kTRUE;
238 break;
239 }
240 case kMB1:
241 {
242 if (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)))
243 return kTRUE;
244 break;
245 }
246 case kMB2:
247 {
248 if (triggerMask & spdFO && ((triggerMask & v0left) || (triggerMask & v0right)))
249 return kTRUE;
250 break;
251 }
252 case kMB3:
253 {
254 if (triggerMask & spdFO && (triggerMask & v0left) && (triggerMask & v0right))
255 return kTRUE;
256 break;
257 }
258 case kSPDGFO:
259 {
260 if (triggerMask & spdFO)
261 return kTRUE;
262 break;
263 }
264 default:
265 Printf("IsEventTriggered: ERROR: Trigger type %d not implemented in this method", (Int_t) trigger);
266 break;
267 }
268
269 return kFALSE;
270}
271
272Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, ULong64_t tclass) const
273{
274 // Checks if corresponding bit in mask is on
275
276 ULong64_t trigmask = aEsd->GetTriggerMask();
277 return (trigmask & (1ull << (tclass-1)));
278}
279
61899827 280Bool_t AliTriggerAnalysis::IsOfflineTriggerFired(const AliESDEvent* aEsd, Trigger trigger)
ff8c4f30 281{
282 // checks if an event has been triggered "offline"
283
70fdd197 284 UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
ff8c4f30 285
286 switch (triggerNoFlags)
287 {
70fdd197 288 case kAcceptAll:
ff8c4f30 289 {
290 return kTRUE;
291 break;
292 }
70fdd197 293 case kMB1:
ff8c4f30 294 {
97fa3cbc 295 if (SPDGFOTrigger(aEsd, 0) || V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
ff8c4f30 296 return kTRUE;
297 break;
298 }
70fdd197 299 case kMB2:
ff8c4f30 300 {
97fa3cbc 301 if (SPDGFOTrigger(aEsd, 0) && (V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB))
ff8c4f30 302 return kTRUE;
303 break;
304 }
70fdd197 305 case kMB3:
ff8c4f30 306 {
97fa3cbc 307 if (SPDGFOTrigger(aEsd, 0) && V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
ff8c4f30 308 return kTRUE;
309 break;
310 }
70fdd197 311 case kSPDGFO:
ff8c4f30 312 {
c2fff146 313 if (SPDGFOTrigger(aEsd, 0))
314 return kTRUE;
315 break;
316 }
317 case kSPDGFOBits:
318 {
319 if (SPDGFOTrigger(aEsd, 1))
ff8c4f30 320 return kTRUE;
321 break;
322 }
70fdd197 323 case kV0A:
ff8c4f30 324 {
97fa3cbc 325 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB)
ff8c4f30 326 return kTRUE;
327 break;
328 }
70fdd197 329 case kV0C:
ff8c4f30 330 {
97fa3cbc 331 if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
ff8c4f30 332 return kTRUE;
333 break;
334 }
733f0542 335 case kV0OR:
336 {
97fa3cbc 337 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
733f0542 338 return kTRUE;
339 break;
340 }
341 case kV0AND:
342 {
97fa3cbc 343 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
733f0542 344 return kTRUE;
345 break;
346 }
61899827 347 case kV0ABG:
348 {
97fa3cbc 349 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BG)
61899827 350 return kTRUE;
351 break;
352 }
353 case kV0CBG:
354 {
97fa3cbc 355 if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BG)
61899827 356 return kTRUE;
357 break;
358 }
70fdd197 359 case kZDC:
c8d3e441 360 {
361 if (ZDCTrigger(aEsd, kASide) || ZDCTrigger(aEsd, kCentralBarrel) || ZDCTrigger(aEsd, kCSide))
362 return kTRUE;
363 break;
364 }
70fdd197 365 case kZDCA:
ff8c4f30 366 {
367 if (ZDCTrigger(aEsd, kASide))
368 return kTRUE;
369 break;
370 }
70fdd197 371 case kZDCC:
ff8c4f30 372 {
373 if (ZDCTrigger(aEsd, kCSide))
374 return kTRUE;
375 break;
376 }
70fdd197 377 case kFMDA:
7a11141c 378 {
379 if (FMDTrigger(aEsd, kASide))
380 return kTRUE;
381 break;
382 }
70fdd197 383 case kFMDC:
7a11141c 384 {
385 if (FMDTrigger(aEsd, kCSide))
386 return kTRUE;
387 break;
388 }
70fdd197 389 case kFPANY:
ff8c4f30 390 {
97fa3cbc 391 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))
ff8c4f30 392 return kTRUE;
393 break;
394 }
733f0542 395 case kNSD1:
396 {
97fa3cbc 397 if (SPDFiredChips(aEsd, 0) >= 5 || (V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB))
733f0542 398 return kTRUE;
399 break;
400 }
97fa3cbc 401 case kMB1Prime:
402 {
403 Int_t count = 0;
404 if (SPDGFOTrigger(aEsd, 0))
405 count++;
406 if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB)
407 count++;
408 if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
409 count++;
410
411 if (count >= 2)
412 return kTRUE;
413
414 break;
415 }
ff8c4f30 416 default:
417 {
418 AliFatal(Form("Trigger type %d not implemented", triggerNoFlags));
419 }
420 }
421
422 return kFALSE;
423}
424
70fdd197 425
426Bool_t AliTriggerAnalysis::IsTriggerClassFired(const AliESDEvent* aEsd, const Char_t* tclass) const
427{
428 // tclass is logical function of inputs, e.g. 01 && 02 || 03 && 11 && 21
429 // = L0 inp 1 && L0 inp 2 || L0 inp 3 && L1 inp 1 && L2 inp 1
430 // NO brackets in logical function !
431 // Spaces between operators and inputs.
432 // Not all logical functions are available in CTP=
433 // =any function of first 4 inputs; 'AND' of other inputs, check not done
434 // This method will be replaced/complemened by similar one
435 // which works withh class and inputs names as in CTP cfg file
436
437 TString TClass(tclass);
438 TObjArray* tcltokens = TClass.Tokenize(" ");
439 Char_t level=((TObjString*)tcltokens->At(0))->String()[0];
440 UInt_t input=atoi((((TObjString*)tcltokens->At(0))->String()).Remove(0));
441 Bool_t tcl = IsInputFired(aEsd,level,input);
442
443 for (Int_t i=1;i<tcltokens->GetEntriesFast();i=i+2) {
444 level=((TObjString*)tcltokens->At(i+1))->String()[0];
445 input=atoi((((TObjString*)tcltokens->At(i+1))->String()).Remove(0));
446 Bool_t inpnext = IsInputFired(aEsd,level,input);
447 Char_t op =((TObjString*)tcltokens->At(i))->String()[0];
448 if (op == '&') tcl=tcl && inpnext;
449 else if (op == '|') tcl =tcl || inpnext;
450 else {
451 AliError(Form("Syntax error in %s", tclass));
452 tcltokens->Delete();
453 return kFALSE;
454 }
455 }
456 tcltokens->Delete();
457 return tcl;
458}
459
460Bool_t AliTriggerAnalysis::IsInputFired(const AliESDEvent* aEsd, Char_t level, UInt_t input) const
461{
462 // Checks trigger input of any level
463
464 switch (level)
465 {
466 case '0': return IsL0InputFired(aEsd,input);
467 case '1': return IsL1InputFired(aEsd,input);
468 case '2': return IsL2InputFired(aEsd,input);
469 default:
470 AliError(Form("Wrong level %i",level));
471 return kFALSE;
472 }
473}
474
475Bool_t AliTriggerAnalysis::IsL0InputFired(const AliESDEvent* aEsd, UInt_t input) const
476{
477 // Checks if corresponding bit in mask is on
478
479 UInt_t inpmask = aEsd->GetHeader()->GetL0TriggerInputs();
480 return (inpmask & (1<<(input-1)));
481}
482
483Bool_t AliTriggerAnalysis::IsL1InputFired(const AliESDEvent* aEsd, UInt_t input) const
484{
485 // Checks if corresponding bit in mask is on
486
487 UInt_t inpmask = aEsd->GetHeader()->GetL1TriggerInputs();
488 return (inpmask & (1<<(input-1)));
489}
490
491Bool_t AliTriggerAnalysis::IsL2InputFired(const AliESDEvent* aEsd, UInt_t input) const
492{
493 // Checks if corresponding bit in mask is on
494
495 UInt_t inpmask = aEsd->GetHeader()->GetL2TriggerInputs();
496 return (inpmask & (1<<(input-1)));
497}
498
499void AliTriggerAnalysis::FillHistograms(const AliESDEvent* aEsd)
ff8c4f30 500{
907972ff 501 // fills the histograms with the info from the ESD
502
c2fff146 503 fHistBitsSPD->Fill(SPDFiredChips(aEsd, 0), SPDFiredChips(aEsd, 1, kTRUE));
907972ff 504
97fa3cbc 505 V0Trigger(aEsd, kASide, kFALSE, kTRUE);
506 V0Trigger(aEsd, kCSide, kFALSE, kTRUE);
907972ff 507
508 AliESDZDC* zdcData = aEsd->GetESDZDC();
509 if (zdcData)
510 {
511 UInt_t quality = zdcData->GetESDQuality();
512
513 // from Nora's presentation, general first physics meeting 16.10.09
514 static UInt_t zpc = 0x20;
515 static UInt_t znc = 0x10;
516 static UInt_t zem1 = 0x08;
517 static UInt_t zem2 = 0x04;
518 static UInt_t zpa = 0x02;
519 static UInt_t zna = 0x01;
520
521 fHistZDC->Fill(1, quality & zna);
522 fHistZDC->Fill(2, quality & zpa);
523 fHistZDC->Fill(3, quality & zem2);
524 fHistZDC->Fill(4, quality & zem1);
525 fHistZDC->Fill(5, quality & znc);
526 fHistZDC->Fill(6, quality & zpc);
527 }
528 else
529 {
530 fHistZDC->Fill(-1);
531 AliError("AliESDZDC not available");
532 }
533
534 fHistFMDA->Fill(FMDHitCombinations(aEsd, kASide, kTRUE));
535 fHistFMDC->Fill(FMDHitCombinations(aEsd, kCSide, kTRUE));
536}
c01a136b 537
538void AliTriggerAnalysis::FillTriggerClasses(const AliESDEvent* aEsd)
539{
540 // fills trigger classes map
541
542 TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(aEsd->GetFiredTriggerClasses().Data()));
543 if (!count)
544 {
545 count = new TParameter<Long64_t>(aEsd->GetFiredTriggerClasses(), 0);
546 fTriggerClasses->Add(new TObjString(aEsd->GetFiredTriggerClasses().Data()), count);
547 }
548 count->SetVal(count->GetVal() + 1);
549
550 // TODO add first and last orbit number here
551}
907972ff 552
61899827 553Int_t AliTriggerAnalysis::SPDFiredChips(const AliESDEvent* aEsd, Int_t origin, Bool_t fillHists)
907972ff 554{
555 // returns the number of fired chips in the SPD
90dc86e9 556 //
557 // origin = 0 --> aEsd->GetMultiplicity()->GetNumberOfFiredChips() (filled from clusters)
558 // origin = 1 --> aEsd->GetMultiplicity()->TestFastOrFiredChips() (from hardware bits)
ff8c4f30 559
ff8c4f30 560 const AliMultiplicity* mult = aEsd->GetMultiplicity();
561 if (!mult)
562 {
563 AliError("AliMultiplicity not available");
907972ff 564 return -1;
ff8c4f30 565 }
90dc86e9 566
567 if (origin == 0)
568 return mult->GetNumberOfFiredChips(0) + mult->GetNumberOfFiredChips(1);
569
570 if (origin == 1)
571 {
572 Int_t nChips = 0;
573 for (Int_t i=0; i<1200; i++)
733f0542 574 {
90dc86e9 575 if (mult->TestFastOrFiredChips(i) == kTRUE)
c2fff146 576 {
733f0542 577 // efficiency simulation (if enabled)
578 if (fSPDGFOEfficiency)
579 {
580 if (gRandom->Uniform() > fSPDGFOEfficiency->GetBinContent(i+1))
581 continue;
582 }
583
90dc86e9 584 nChips++;
61899827 585 if (fillHists)
c2fff146 586 fHistFiredBitsSPD->Fill(i);
587 }
733f0542 588 }
90dc86e9 589 return nChips;
590 }
591
592 return -1;
907972ff 593}
594
61899827 595Bool_t AliTriggerAnalysis::SPDGFOTrigger(const AliESDEvent* aEsd, Int_t origin)
907972ff 596{
597 // Returns if the SPD gave a global Fast OR trigger
598
c2fff146 599 Int_t firedChips = SPDFiredChips(aEsd, origin);
ff8c4f30 600
601 if (firedChips >= fSPDGFOThreshold)
602 return kTRUE;
603 return kFALSE;
604}
605
97fa3cbc 606AliTriggerAnalysis::V0Decision AliTriggerAnalysis::V0Trigger(const AliESDEvent* aEsd, AliceSide side, Bool_t online, Bool_t fillHists)
ff8c4f30 607{
c01a136b 608 // Returns the V0 trigger decision in V0A | V0C
609 //
733f0542 610 // Returns kV0Fake if the calculated average time is in a window where neither BB nor BG is expected.
611 // The rate of such triggers can be used to estimate the background. Note that the rate has to be
612 // rescaled with the size of the windows (numerical values see below in the code)
613 //
97fa3cbc 614 // argument 'online' is used as a switch between online and offline trigger algorithms
615 //
733f0542 616 // Based on an algorithm by Cvetan Cheshkov
ff8c4f30 617
c01a136b 618 AliESDVZERO* esdV0 = aEsd->GetVZEROData();
619 if (!esdV0)
ff8c4f30 620 {
621 AliError("AliESDVZERO not available");
c01a136b 622 return kV0Invalid;
ff8c4f30 623 }
97fa3cbc 624
c01a136b 625 Int_t begin = -1;
626 Int_t end = -1;
627
628 if (side == kASide)
ff8c4f30 629 {
c01a136b 630 begin = 32;
631 end = 64;
632 }
633 else if (side == kCSide)
634 {
635 begin = 0;
636 end = 32;
ff8c4f30 637 }
c01a136b 638 else
639 return kV0Invalid;
a2ce3799 640
c01a136b 641 Float_t time = 0;
bcd135ec 642 Float_t weight = 0;
97fa3cbc 643 if (fMC)
644 {
645 Int_t runRange;
646 if (aEsd->GetRunNumber() <= 104803) runRange = 0;
647 else if (aEsd->GetRunNumber() <= 104876) runRange = 1;
648 else runRange = 2;
649
650 Float_t factors[3][64] = {
651 // runs: 104792-104803
652 {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},
653 // runs: 104841-104876
654 {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},
655 // runs: 104890-92
656 {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}
657 };
658 Float_t dA = 77.4 - 11.0;
659 Float_t dC = 77.4 - 2.9;
660 // Time misalignment
661 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};
662 Float_t dA2 = 2.8, dC2 = 3.3;
663
664 if (online) {
665 for (Int_t i = begin; i < end; ++i) {
666 Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
667 Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
668 if (esdV0->GetTime(i) >= 1e-6 &&
669 tempTime > fV0HwWinLow && tempTime < fV0HwWinHigh &&
670 tempAdc > fV0HwAdcThr)
671 return kV0BB;
672 }
673 return kV0Empty;
674 }
675 else {
676 for (Int_t i = begin; i < end; ++i) {
677 Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
678 Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA : esdV0->GetTime(i)+dC;
679 Float_t tempRawTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
680 if (esdV0->GetTime(i) >= 1e-6 &&
681 tempRawTime < 125.0 &&
682 tempAdc > fV0AdcThr) {
683 weight += 1.0;
684 time += tempTime;
685 }
686 }
687 }
688 }
689 else {
8b16e464 690 if (online) {
691 for (Int_t i = begin; i < end; ++i) {
692 if (esdV0->GetTime(i) >= 1e-6 &&
693 esdV0->GetTime(i) > fV0HwWinLow && esdV0->GetTime(i) < fV0HwWinHigh &&
694 esdV0->GetAdc(i) > fV0HwAdcThr)
695 return kV0BB;
696 }
697 return kV0Empty;
698 }
699 else {
700 for (Int_t i = begin; i < end; ++i) {
701 if (esdV0->GetTime(i) > 1e-6 && esdV0->GetAdc(i) > fV0AdcThr) {
702 Float_t correctedTime = V0CorrectLeadingTime(i, esdV0->GetTime(i), esdV0->GetAdc(i));
703 Float_t timeWeight = V0LeadingTimeWeight(esdV0->GetAdc(i));
704 time += correctedTime*timeWeight;
97fa3cbc 705
8b16e464 706 weight += timeWeight;
707 }
97fa3cbc 708 }
c01a136b 709 }
710 }
907972ff 711
bcd135ec 712 if (weight > 0)
713 time /= weight;
90a4610a 714 time += fV0TimeOffset;
c01a136b 715
716 if (fillHists)
717 {
718 if (side == kASide && fHistV0A)
719 fHistV0A->Fill(time);
720 if (side == kCSide && fHistV0C)
721 fHistV0C->Fill(time);
722 }
907972ff 723
c01a136b 724 if (side == kASide)
725 {
6dc2503d 726 if (time > 68 && time < 100)
c01a136b 727 return kV0BB;
bcd135ec 728 if (time > 54 && time < 57.5)
c01a136b 729 return kV0BG;
6dc2503d 730 if (time > 57.5 && time < 68)
733f0542 731 return kV0Fake;
c01a136b 732 }
907972ff 733
c01a136b 734 if (side == kCSide)
735 {
6dc2503d 736 if (time > 75.5 && time < 100)
c01a136b 737 return kV0BB;
bcd135ec 738 if (time > 69.5 && time < 73)
c01a136b 739 return kV0BG;
733f0542 740 if (time > 55 && time < 69.5)
741 return kV0Fake;
c01a136b 742 }
743
744 return kV0Empty;
745}
746
747Float_t AliTriggerAnalysis::V0CorrectLeadingTime(Int_t i, Float_t time, Float_t adc) const
748{
749 // Correct for slewing and align the channels
750 //
bcd135ec 751 // Authors: Cvetan Cheshkov / Raphael Tieulent
c01a136b 752
753 if (time == 0) return 0;
754
bcd135ec 755 // Time alignment
756 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};
757
c01a136b 758 time -= timeShift[i];
759
760 // Slewing correction
761 if (adc == 0) return time;
762
bcd135ec 763 Float_t p1 = 1.57345e1;
764 Float_t p2 =-4.25603e-1;
765
766 return (time - p1*TMath::Power(adc,p2));
767}
768
769Float_t AliTriggerAnalysis::V0LeadingTimeWeight(Float_t adc) const
770{
771 if (adc < 1e-6) return 0;
772
773 Float_t p1 = 40.211;
774 Float_t p2 =-4.25603e-1;
775 Float_t p3 = 0.5646;
776
777 return 1./(p1*p1*TMath::Power(adc,2.*(p2-1.))+p3*p3);
ff8c4f30 778}
779
70fdd197 780Bool_t AliTriggerAnalysis::ZDCTrigger(const AliESDEvent* aEsd, AliceSide side) const
ff8c4f30 781{
782 // Returns if ZDC triggered
783
c8d3e441 784 AliESDZDC* zdcData = aEsd->GetESDZDC();
785 if (!zdcData)
786 {
787 AliError("AliESDZDC not available");
788 return kFALSE;
789 }
790
791 UInt_t quality = zdcData->GetESDQuality();
792
793 // from Nora's presentation, general first physics meeting 16.10.09
794 static UInt_t zpc = 0x20;
795 static UInt_t znc = 0x10;
796 static UInt_t zem1 = 0x08;
797 static UInt_t zem2 = 0x04;
798 static UInt_t zpa = 0x02;
799 static UInt_t zna = 0x01;
800
801 if (side == kASide && ((quality & zpa) || (quality & zna)))
802 return kTRUE;
803 if (side == kCentralBarrel && ((quality & zem1) || (quality & zem2)))
804 return kTRUE;
805 if (side == kCSide && ((quality & zpc) || (quality & znc)))
806 return kTRUE;
ff8c4f30 807
808 return kFALSE;
809}
810
61899827 811Int_t AliTriggerAnalysis::FMDHitCombinations(const AliESDEvent* aEsd, AliceSide side, Bool_t fillHists)
ff8c4f30 812{
907972ff 813 // returns number of hit combinations agove threshold
7a11141c 814 //
815 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
ff8c4f30 816
7a11141c 817 // Workaround for AliESDEvent::GetFMDData is not const!
818 const AliESDFMD* fmdData = (const_cast<AliESDEvent*>(aEsd))->GetFMDData();
819 if (!fmdData)
820 {
821 AliError("AliESDFMD not available");
907972ff 822 return -1;
7a11141c 823 }
824
825 Int_t detFrom = (side == kASide) ? 1 : 3;
826 Int_t detTo = (side == kASide) ? 2 : 3;
827
907972ff 828 Int_t triggers = 0;
7a11141c 829 Float_t totalMult = 0;
830 for (UShort_t det=detFrom;det<=detTo;det++) {
831 Int_t nRings = (det == 1 ? 1 : 2);
832 for (UShort_t ir = 0; ir < nRings; ir++) {
833 Char_t ring = (ir == 0 ? 'I' : 'O');
834 UShort_t nsec = (ir == 0 ? 20 : 40);
835 UShort_t nstr = (ir == 0 ? 512 : 256);
039db886 836 for (UShort_t sec =0; sec < nsec; sec++) {
837 for (UShort_t strip = 0; strip < nstr; strip++) {
838 Float_t mult = fmdData->Multiplicity(det,ring,sec,strip);
839 if (mult == AliESDFMD::kInvalidMult) continue;
840
61899827 841 if (fillHists)
907972ff 842 fHistFMDSingle->Fill(mult);
843
039db886 844 if (mult > fFMDLowCut)
845 totalMult = totalMult + mult;
846 else
907972ff 847 {
848 if (totalMult > fFMDHitCut)
849 triggers++;
850
61899827 851 if (fillHists)
907972ff 852 fHistFMDSum->Fill(totalMult);
853
854 totalMult = 0;
855 }
039db886 856 }
7a11141c 857 }
858 }
859 }
907972ff 860
861 return triggers;
862}
863
61899827 864Bool_t AliTriggerAnalysis::FMDTrigger(const AliESDEvent* aEsd, AliceSide side)
907972ff 865{
866 // Returns if the FMD triggered
867 //
868 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
869
870 Int_t triggers = FMDHitCombinations(aEsd, side, kFALSE);
871
872 if (triggers > 0)
873 return kTRUE;
874
ff8c4f30 875 return kFALSE;
876}
907972ff 877
70fdd197 878Long64_t AliTriggerAnalysis::Merge(TCollection* list)
907972ff 879{
880 // Merge a list of AliMultiplicityCorrection objects with this (needed for
881 // PROOF).
882 // Returns the number of merged objects (including this).
883
884 if (!list)
885 return 0;
886
887 if (list->IsEmpty())
888 return 1;
889
890 TIterator* iter = list->MakeIterator();
891 TObject* obj;
892
893 // collections of all histograms
c01a136b 894 const Int_t nHists = 9;
907972ff 895 TList collections[nHists];
896
897 Int_t count = 0;
898 while ((obj = iter->Next())) {
899
70fdd197 900 AliTriggerAnalysis* entry = dynamic_cast<AliTriggerAnalysis*> (obj);
907972ff 901 if (entry == 0)
902 continue;
903
c01a136b 904 Int_t n = 0;
905 collections[n++].Add(entry->fHistV0A);
906 collections[n++].Add(entry->fHistV0C);
907 collections[n++].Add(entry->fHistZDC);
908 collections[n++].Add(entry->fHistFMDA);
909 collections[n++].Add(entry->fHistFMDC);
910 collections[n++].Add(entry->fHistFMDSingle);
911 collections[n++].Add(entry->fHistFMDSum);
912 collections[n++].Add(entry->fHistBitsSPD);
913 collections[n++].Add(entry->fHistFiredBitsSPD);
914
915 // merge fTriggerClasses
916 TIterator* iter2 = entry->fTriggerClasses->MakeIterator();
35293555 917 TObjString* obje = 0;
918 while ((obje = dynamic_cast<TObjString*> (iter2->Next())))
c01a136b 919 {
35293555 920 TParameter<Long64_t>* param2 = dynamic_cast<TParameter<Long64_t>*> (entry->fTriggerClasses->GetValue(obje));
c01a136b 921
35293555 922 TParameter<Long64_t>* param1 = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obje));
c01a136b 923 if (param1)
924 {
925 param1->SetVal(param1->GetVal() + param2->GetVal());
926 }
927 else
928 {
929 param1 = dynamic_cast<TParameter<Long64_t>*> (param2->Clone());
35293555 930 fTriggerClasses->Add(new TObjString(obje->String()), param1);
c01a136b 931 }
932 }
933
934 delete iter2;
935
907972ff 936 count++;
937 }
938
c01a136b 939 Int_t n = 0;
940 fHistV0A->Merge(&collections[n++]);
941 fHistV0C->Merge(&collections[n++]);
942 fHistZDC->Merge(&collections[n++]);
943 fHistFMDA->Merge(&collections[n++]);
944 fHistFMDC->Merge(&collections[n++]);
945 fHistFMDSingle->Merge(&collections[n++]);
946 fHistFMDSum->Merge(&collections[n++]);
947 fHistBitsSPD->Merge(&collections[n++]);
948 fHistFiredBitsSPD->Merge(&collections[n++]);
949
907972ff 950 delete iter;
951
952 return count+1;
953}
954
61899827 955void AliTriggerAnalysis::SaveHistograms() const
907972ff 956{
957 // write histograms to current directory
958
c01a136b 959 if (!fHistBitsSPD)
907972ff 960 return;
961
90dc86e9 962 fHistBitsSPD->Write();
61899827 963 fHistBitsSPD->ProjectionX();
964 fHistBitsSPD->ProjectionY();
c2fff146 965 fHistFiredBitsSPD->Write();
907972ff 966 fHistV0A->Write();
967 fHistV0C->Write();
968 fHistZDC->Write();
969 fHistFMDA->Write();
970 fHistFMDC->Write();
971 fHistFMDSingle->Write();
972 fHistFMDSum->Write();
c01a136b 973
733f0542 974 if (fSPDGFOEfficiency)
975 fSPDGFOEfficiency->Write("fSPDGFOEfficiency");
976
c01a136b 977 fTriggerClasses->Write("fTriggerClasses", TObject::kSingleKey);
978}
979
980void AliTriggerAnalysis::PrintTriggerClasses() const
981{
982 // print trigger classes
983
984 Printf("Trigger Classes:");
985
35fb1e58 986 Printf("Event count for trigger combinations:");
987
988 TMap singleTrigger;
989 singleTrigger.SetOwner();
990
c01a136b 991 TIterator* iter = fTriggerClasses->MakeIterator();
992 TObjString* obj = 0;
993 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
994 {
35fb1e58 995 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj));
996
997 Printf(" %s: %ld triggers", obj->String().Data(), param->GetVal());
c01a136b 998
35fb1e58 999 TObjArray* tokens = obj->String().Tokenize(" ");
1000 for (Int_t i=0; i<tokens->GetEntries(); i++)
1001 {
1002 TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(((TObjString*) tokens->At(i))->String().Data()));
1003 if (!count)
1004 {
1005 count = new TParameter<Long64_t>(((TObjString*) tokens->At(i))->String().Data(), 0);
1006 singleTrigger.Add(new TObjString(((TObjString*) tokens->At(i))->String().Data()), count);
1007 }
1008 count->SetVal(count->GetVal() + param->GetVal());
1009 }
1010
1011 delete tokens;
c01a136b 1012 }
35fb1e58 1013 delete iter;
1014
1015 Printf("Event count for single trigger:");
1016
1017 iter = singleTrigger.MakeIterator();
1018 while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1019 {
1020 TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(obj));
1021
1022 Printf(" %s: %ld triggers", obj->String().Data(), param->GetVal());
1023 }
1024 delete iter;
1025
1026 singleTrigger.DeleteAll();
907972ff 1027}