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