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