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