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