5a3160623241ae858d8ec422218efb57cd48b66a
[u/mrichter/AliRoot.git] / ANALYSIS / AliTriggerAnalysis.cxx
1 /* $Id: AliTriggerAnalysis.cxx 35782 2009-10-22 11:54:31Z jgrosseo $ */
2
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 //-------------------------------------------------------------------------
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
22 //   Origin: Jan Fiete Grosse-Oetringhaus, CERN
23 //-------------------------------------------------------------------------
24
25 #include <Riostream.h>
26 #include <TH1F.h>
27 #include <TH2F.h>
28 #include <TList.h>
29 #include <TIterator.h>
30 #include "TParameter.h"
31 #include <TMap.h>
32 #include <TRandom.h>
33
34 #include <AliTriggerAnalysis.h>
35
36 #include <AliLog.h>
37
38 #include <AliESDEvent.h>
39
40 #include <AliMultiplicity.h>
41 #include <AliESDVZERO.h>
42 #include <AliESDZDC.h>
43 #include <AliESDFMD.h>
44 #include <AliESDVertex.h>
45 #include <AliESDtrackCuts.h>
46
47 ClassImp(AliTriggerAnalysis)
48
49 AliTriggerAnalysis::AliTriggerAnalysis() :
50   fSPDGFOThreshold(2),
51   fSPDGFOEfficiency(0),
52   fV0TimeOffset(0),
53   fV0AdcThr(0),
54   fV0HwAdcThr(2.5),
55   fV0HwWinLow(61.5),
56   fV0HwWinHigh(86.5),
57   fZDCCutRefSum(-568.5),
58   fZDCCutRefDelta(-2.1),
59   fZDCCutSigmaSum(3.25),
60   fZDCCutSigmaDelta(2.25),
61   fZDCCutRefSumCorr(-65.5),
62   fZDCCutRefDeltaCorr(-2.1),
63   fZDCCutSigmaSumCorr(6.0),
64   fZDCCutSigmaDeltaCorr(1.2),
65   fASPDCvsTCut(65),
66   fBSPDCvsTCut(4),
67   fDoFMD(kTRUE),
68   fFMDLowCut(0.2),
69   fFMDHitCut(0.5),
70   fHistBitsSPD(0),
71   fHistFiredBitsSPD(0),
72   fHistSPDClsVsTrk(0),
73   fHistV0A(0),       
74   fHistV0C(0),
75   fHistZDC(0),    
76   fHistTDCZDC(0),    
77   fHistTimeZDC(0),    
78   fHistTimeCorrZDC(0),    
79   fHistFMDA(0),    
80   fHistFMDC(0),   
81   fHistFMDSingle(0),
82   fHistFMDSum(0),
83   fTriggerClasses(0),
84   fMC(kFALSE),
85   fEsdTrackCuts(0),
86   fTPCOnly(kFALSE)
87 {
88   // constructor
89 }
90
91 AliTriggerAnalysis::~AliTriggerAnalysis()
92 {
93   // destructor
94   
95   if (fHistBitsSPD)
96   {
97     delete fHistBitsSPD;
98     fHistBitsSPD = 0;
99   }
100
101   if (fHistFiredBitsSPD)
102   {
103     delete fHistFiredBitsSPD;
104     fHistFiredBitsSPD = 0;
105   }
106
107   if (fHistSPDClsVsTrk)
108   {
109     delete fHistSPDClsVsTrk;
110     fHistSPDClsVsTrk = 0;
111   }
112
113   if (fHistV0A)
114   {
115     delete fHistV0A;
116     fHistV0A = 0;
117   }
118
119   if (fHistV0C)
120   {
121     delete fHistV0C;
122     fHistV0C = 0;
123   }
124
125   if (fHistZDC)
126   {
127     delete fHistZDC;
128     fHistZDC = 0;
129   }
130   if (fHistTDCZDC)
131   {
132     delete fHistTDCZDC;
133     fHistTDCZDC = 0;
134   }
135   if (fHistTimeZDC)
136   {
137     delete fHistTimeZDC;
138     fHistTimeZDC = 0;
139   }
140   if (fHistTimeCorrZDC)
141   {
142     delete fHistTimeCorrZDC;
143     fHistTimeCorrZDC = 0;
144   }
145
146   if (fHistFMDA)
147   {
148     delete fHistFMDA;
149     fHistFMDA = 0;
150   }
151
152   if (fHistFMDC)
153   {
154     delete fHistFMDC;
155     fHistFMDC = 0;
156   }
157
158   if (fHistFMDSingle)
159   {
160     delete fHistFMDSingle;
161     fHistFMDSingle = 0;
162   }
163
164   if (fHistFMDSum)
165   {
166     delete fHistFMDSum;
167     fHistFMDSum = 0;
168   }
169
170   if (fTriggerClasses)
171   {
172     fTriggerClasses->DeleteAll();
173     delete fTriggerClasses;
174     fTriggerClasses = 0;
175   }
176
177   if (fEsdTrackCuts){
178     delete fEsdTrackCuts;
179     fEsdTrackCuts =0;
180   }
181 }
182
183 void AliTriggerAnalysis::EnableHistograms()
184 {
185   // creates the monitoring histograms
186   
187   // do not add this hists to the directory
188   Bool_t oldStatus = TH1::AddDirectoryStatus();
189   TH1::AddDirectory(kFALSE);
190   
191   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);
192   fHistFiredBitsSPD = new TH1F("fHistFiredBitsSPD", "SPD GFO Hardware;chip number;events", 1200, -0.5, 1199.5);
193   fHistSPDClsVsTrk = new TH2F("fHistSPDClsVsTrk", "SPD Clusters vs Tracklets", 300, -0.5, 2999.5, 1000, -0.5, 9999.5);
194   fHistV0A = new TH1F("fHistV0A", "V0A;leading time (ns);events", 400, -100, 100);
195   fHistV0C = new TH1F("fHistV0C", "V0C;leading time (ns);events", 400, -100, 100);
196   fHistZDC = new TH1F("fHistZDC", "ZDC;trigger bits;events", 8, -1.5, 6.5);
197   fHistTDCZDC = new TH1F("fHistTDCZDC", "ZDC;TDC bits;events", 32, -0.5, 32-0.5);
198   fHistTimeZDC = new TH2F("fHistTimeZDC", "ZDC;TDC timing A+C vs C-A; events", 120,-30,30,120,-600,-540);
199   fHistTimeCorrZDC = new TH2F("fHistTimeCorrZDC", "ZDC;Corrected TDC timing A+C vs C-A; events", 120,-30,30,120,-100,-40);
200   
201   // TODO check limits
202   fHistFMDA = new TH1F("fHistFMDA", "FMDA;combinations above threshold;events", 102, -1.5, 100.5);
203   fHistFMDC = new TH1F("fHistFMDC", "FMDC;combinations above threshold;events", 102, -1.5, 100.5);
204   fHistFMDSingle = new TH1F("fHistFMDSingle", "FMD single;multiplicity value;counts", 1000, 0, 10);
205   fHistFMDSum = new TH1F("fHistFMDSum", "FMD sum;multiplicity value;counts", 1000, 0, 10);
206   
207   fTriggerClasses = new TMap;
208   fTriggerClasses->SetOwner();
209   
210   TH1::AddDirectory(oldStatus);
211 }
212
213 //____________________________________________________________________
214 const char* AliTriggerAnalysis::GetTriggerName(Trigger trigger) 
215 {
216   // returns the name of the requested trigger
217   // the returned string will only be valid until the next call to this function [not thread-safe]
218   
219   static TString str;
220   
221   UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
222   
223   switch (triggerNoFlags)
224   {
225     case kAcceptAll : str = "ACCEPT ALL (bypass!)"; break;
226     case kMB1 : str = "MB1"; break;
227     case kMB2 : str = "MB2"; break;
228     case kMB3 : str = "MB3"; break;
229     case kSPDGFO : str = "SPD GFO"; break;
230     case kSPDGFOBits : str = "SPD GFO Bits"; break;
231     case kSPDGFOL0 : str = "SPD GFO L0 (first layer)"; break;
232     case kSPDGFOL1 : str = "SPD GFO L1 (second layer)"; break;
233     case kSPDClsVsTrkBG :  str = "Cluster vs Tracklets"; break;
234     case kV0A : str = "V0 A BB"; break;
235     case kV0C : str = "V0 C BB"; break;
236     case kV0OR : str = "V0 OR BB"; break;
237     case kV0AND : str = "V0 AND BB"; break;
238     case kV0ABG : str = "V0 A BG"; break;
239     case kV0CBG : str = "V0 C BG"; break;
240     case kZDC : str = "ZDC"; break;
241     case kZDCA : str = "ZDC A"; break;
242     case kZDCC : str = "ZDC C"; break;
243     case kFMDA : str = "FMD A"; break;
244     case kFMDC : str = "FMD C"; break;
245     case kFPANY : str = "SPD GFO | V0 | ZDC | FMD"; break;
246     case kNSD1 : str = "NSD1"; break;
247     case kMB1Prime: str = "MB1prime"; break;
248     case kZDCTDCA : str = "ZDC TDC A"; break;
249     case kZDCTDCC : str = "ZDC TDC C"; break;
250     case kZDCTime : str = "ZDC Time Cut"; break;
251     default: str = ""; break;
252   }
253    
254   if (trigger & kOfflineFlag)
255     str += " OFFLINE";  
256   
257   if (trigger & kOneParticle)
258     str += " OneParticle";  
259
260   if (trigger & kOneTrack)
261     str += " OneTrack";  
262
263   return str;
264 }
265
266 Bool_t AliTriggerAnalysis::IsTriggerFired(const AliESDEvent* aEsd, Trigger trigger)
267 {
268   // checks if an event has been triggered
269
270   if (trigger & kOfflineFlag)
271     return IsOfflineTriggerFired(aEsd, trigger);
272     
273   return IsTriggerBitFired(aEsd, trigger);
274 }
275
276 Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, Trigger trigger) const
277 {
278   // checks if an event is fired using the trigger bits
279
280   return IsTriggerBitFired(aEsd->GetTriggerMask(), trigger);
281 }
282
283 Bool_t AliTriggerAnalysis::IsTriggerBitFired(ULong64_t triggerMask, Trigger trigger) const
284 {
285   // checks if an event is fired using the trigger bits
286   //
287   // this function needs the branch TriggerMask in the ESD
288   
289   // definitions from p-p.cfg
290   ULong64_t spdFO = (1 << 14);
291   ULong64_t v0left = (1 << 10);
292   ULong64_t v0right = (1 << 11);
293
294   switch (trigger)
295   {
296     case kAcceptAll:
297     {
298       return kTRUE;
299       break;
300     }
301     case kMB1:
302     {
303       if (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)))
304         return kTRUE;
305       break;
306     }
307     case kMB2:
308     {
309       if (triggerMask & spdFO && ((triggerMask & v0left) || (triggerMask & v0right)))
310         return kTRUE;
311       break;
312     }
313     case kMB3:
314     {
315       if (triggerMask & spdFO && (triggerMask & v0left) && (triggerMask & v0right))
316         return kTRUE;
317       break;
318     }
319     case kSPDGFO:
320     {
321       if (triggerMask & spdFO)
322         return kTRUE;
323       break;
324     }
325     default:
326       Printf("IsEventTriggered: ERROR: Trigger type %d not implemented in this method", (Int_t) trigger);
327       break;
328   }
329
330   return kFALSE;
331 }
332
333 Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, ULong64_t tclass) const
334 {
335   // Checks if corresponding bit in mask is on
336   
337   ULong64_t trigmask = aEsd->GetTriggerMask();
338   return (trigmask & (1ull << (tclass-1)));
339 }
340   
341 Int_t AliTriggerAnalysis::EvaluateTrigger(const AliESDEvent* aEsd, Trigger trigger)
342 {
343   // evaluates a given trigger "offline"
344   // trigger combinations are not supported, for that see IsOfflineTriggerFired
345   
346   UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
347   Bool_t offline = kFALSE;
348   if (trigger & kOfflineFlag)
349     offline = kTRUE;
350   
351   Int_t decision = 0;
352   switch (triggerNoFlags)
353   {
354     case kSPDGFO:
355     {
356       decision = SPDFiredChips(aEsd, (offline) ? 0 : 1);
357       break;
358     }
359     case kSPDGFOL0:
360     {
361       decision = SPDFiredChips(aEsd, (offline) ? 0 : 1, kFALSE, 1);
362       break;
363     }
364     case kSPDGFOL1:
365     {
366       decision = SPDFiredChips(aEsd, (offline) ? 0 : 1, kFALSE, 2);
367       break;
368     } 
369     case kSPDClsVsTrkBG:
370     {
371       if(!offline) 
372         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
373       decision = IsSPDClusterVsTrackletBG(aEsd);
374       break;
375     }
376     case kV0A:
377     {
378       if (V0Trigger(aEsd, kASide, !offline) == kV0BB)
379         decision = 1;
380       break;
381     }
382     case kV0C:
383     {
384       if (V0Trigger(aEsd, kCSide, !offline) == kV0BB)
385         decision = 1;
386       break;
387     }
388     case kV0ABG:
389     {
390       if (V0Trigger(aEsd, kASide, !offline) == kV0BG)
391         decision = 1;
392       break;
393     }
394     case kV0CBG:
395     {
396       if (V0Trigger(aEsd, kCSide, !offline) == kV0BG)
397         decision = 1;
398       break;
399     }
400     case kZDCA:
401     {
402       if (!offline)
403         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
404       if (ZDCTrigger(aEsd, kASide))
405         decision = 1;
406       break;
407     }
408     case kZDCC:
409     {
410       if (!offline)
411         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
412       if (ZDCTrigger(aEsd, kCSide))
413         decision = 1;
414       break;
415     }
416     case kZDCTDCA:
417     {
418       if (!offline)
419         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
420       if (ZDCTDCTrigger(aEsd, kASide))
421         decision = 1;
422       break;
423     }
424     case kZDCTDCC:
425     {
426       if (!offline)
427         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
428       if (ZDCTDCTrigger(aEsd, kCSide))
429         decision = 1;
430       break;
431     }
432     case kZDCTime:
433     {
434       if (!offline)
435         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
436       if (ZDCTimeTrigger(aEsd))
437         decision = 1;
438       break;
439     }
440     case kFMDA:
441     {
442       if (!offline)
443         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
444       if (FMDTrigger(aEsd, kASide))
445         decision = 1;
446       break;
447     }
448     case kFMDC:
449     {
450       if (!offline)
451         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
452       if (FMDTrigger(aEsd, kCSide))
453         decision = 1;
454       break;
455     }
456     case kCTPV0A:
457     {
458       if (offline)
459         AliFatal(Form("Offline trigger not available for trigger %d", triggerNoFlags));
460       if (IsL0InputFired(aEsd, 2))
461         decision = 1;
462       break;
463     }
464     case kCTPV0C:
465     {
466       if (offline)
467         AliFatal(Form("Offline trigger not available for trigger %d", triggerNoFlags));
468       if (IsL0InputFired(aEsd, 3))
469         decision = 1;
470       break;
471     }
472     case kTPCLaserWarmUp:
473     {
474       if (!offline)
475         AliFatal(Form("Online trigger not available for trigger %d", triggerNoFlags));
476       return IsLaserWarmUpTPCEvent(aEsd);
477     }
478     default:
479     {
480       AliFatal(Form("Trigger type %d not implemented", triggerNoFlags));
481     }
482   }  
483   
484   return decision;
485 }
486
487 Bool_t AliTriggerAnalysis::IsLaserWarmUpTPCEvent(const AliESDEvent* esd)
488 {
489   //
490   // This function flags noisy TPC events which can happen during laser warm-up.
491   //
492   
493   Int_t trackCounter = 0;
494   for (Int_t i=0; i<esd->GetNumberOfTracks(); ++i) 
495   {
496     AliESDtrack *track = esd->GetTrack(i);
497     if (!track) 
498       continue;
499       
500     if (track->GetTPCNcls() < 30) continue;
501     if (TMath::Abs(track->Eta()) > 0.005) continue;
502     if (track->Pt() < 4) continue;
503     if (track->GetKinkIndex(0) > 0) continue;
504     
505     UInt_t status = track->GetStatus();
506     if ((status&AliESDtrack::kITSrefit)==AliESDtrack::kITSrefit) continue; // explicitly ask for tracks without ITS refit
507     if ((status&AliESDtrack::kTPCrefit)!=AliESDtrack::kTPCrefit) continue;
508     
509     if (track->GetTPCsignal() > 10) continue;          // explicitly ask for tracks without dE/dx
510     
511     trackCounter++;
512   }
513   if (trackCounter > 15) 
514     return kTRUE;
515   return kFALSE;
516 }
517
518 Bool_t AliTriggerAnalysis::IsOfflineTriggerFired(const AliESDEvent* aEsd, Trigger trigger)
519 {
520   // checks if an event has been triggered "offline"
521
522   UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
523   
524   Bool_t decision = kFALSE;
525   switch (triggerNoFlags)
526   {
527     case kAcceptAll:
528     {
529       decision = kTRUE;
530       break;
531     }
532     case kMB1:
533     {
534       if (SPDGFOTrigger(aEsd, 0) || V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
535         decision = kTRUE;
536       break;
537     }
538     case kMB2:
539     {
540       if (SPDGFOTrigger(aEsd, 0) && (V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB))
541         decision = kTRUE;
542       break;
543     }
544     case kMB3:
545     {
546       if (SPDGFOTrigger(aEsd, 0) && V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
547         decision = kTRUE;
548       break;
549     }
550     case kSPDGFO:
551     {
552       if (SPDGFOTrigger(aEsd, 0))
553         decision = kTRUE;
554       break;
555     }
556     case kSPDGFOBits:
557     {
558       if (SPDGFOTrigger(aEsd, 1))
559         decision = kTRUE;
560       break;
561     }
562     case kV0A:
563     {
564       if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB)
565         decision = kTRUE;
566       break;
567     }
568     case kV0C:
569     {
570       if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
571         decision = kTRUE;
572       break;
573     }
574     case kV0OR:
575     {
576       if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB || V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
577         decision = kTRUE;
578       break;
579     }
580     case kV0AND:
581     {
582       if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
583         decision = kTRUE;
584       break;
585     }
586     case kV0ABG:
587     {
588       if (V0Trigger(aEsd, kASide, kFALSE) == kV0BG)
589         decision = kTRUE;
590       break;
591     }
592     case kV0CBG:
593     {
594       if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BG)
595         decision = kTRUE;
596       break;
597     }
598     case kZDC:
599     {
600       if (ZDCTrigger(aEsd, kASide) || ZDCTrigger(aEsd, kCentralBarrel) || ZDCTrigger(aEsd, kCSide))
601         decision = kTRUE;
602       break;
603     }
604     case kZDCA:
605     {
606       if (ZDCTrigger(aEsd, kASide))
607         decision = kTRUE;
608       break;
609     }
610     case kZDCC:
611     {
612       if (ZDCTrigger(aEsd, kCSide))
613         decision = kTRUE;
614       break;
615     }
616     case kFMDA:
617     {
618       if (FMDTrigger(aEsd, kASide))
619         decision = kTRUE;
620       break;
621     }
622     case kFMDC:
623     {
624       if (FMDTrigger(aEsd, kCSide))
625         decision = kTRUE;
626       break;
627     }
628     case kFPANY:
629     {
630       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))
631         decision = kTRUE;
632       break;
633     }
634     case kNSD1:
635     {
636       if (SPDFiredChips(aEsd, 0) >= 5 || (V0Trigger(aEsd, kASide, kFALSE) == kV0BB && V0Trigger(aEsd, kCSide, kFALSE) == kV0BB))
637         decision = kTRUE;
638        break;
639     }
640     case kMB1Prime:
641     {
642       Int_t count = 0;
643       if (SPDGFOTrigger(aEsd, 0))
644         count++;
645       if (V0Trigger(aEsd, kASide, kFALSE) == kV0BB)
646         count++;
647       if (V0Trigger(aEsd, kCSide, kFALSE) == kV0BB)
648         count++;
649       
650       if (count >= 2)
651         decision = kTRUE;
652         
653       break;
654     }
655     default:
656     {
657       AliFatal(Form("Trigger type %d not implemented", triggerNoFlags));
658     }
659   }
660   
661   // hadron-level requirement
662   if (decision && (trigger & kOneParticle))
663   {
664     decision = kFALSE;
665     
666     const AliESDVertex* vertex = aEsd->GetPrimaryVertexSPD();
667     const AliMultiplicity* mult = aEsd->GetMultiplicity();
668
669     if (mult && vertex && vertex->GetNContributors() > 0 && (!vertex->IsFromVertexerZ() || vertex->GetDispersion() < 0.02) && TMath::Abs(vertex->GetZv()) < 5.5) 
670     {
671       for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
672       {
673         if (TMath::Abs(mult->GetEta(i)) < 1)
674         {
675           decision = kTRUE;
676           break;
677         }
678       }
679     }
680   }
681
682   // hadron level definition for TPC tracks
683
684   if (decision && (trigger & kOneTrack))
685   {
686     decision = kFALSE;
687     const AliESDVertex* vertex =0x0;
688     vertex = aEsd->GetPrimaryVertexTracks();
689     if (!vertex || vertex->GetNContributors() <= 0)
690     {
691       vertex = aEsd->GetPrimaryVertexSPD();
692     }
693     Float_t ptmin, ptmax;
694     fEsdTrackCuts->GetPtRange(ptmin,ptmax);
695     AliDebug(3, Form("ptmin = %f, ptmax = %f\n",ptmin, ptmax));
696
697     if (vertex && vertex->GetNContributors() > 0 && (!vertex->IsFromVertexerZ() || vertex->GetDispersion() < 0.02) && TMath::Abs(vertex->GetZv()) < 10.) {
698       AliDebug(3,Form("Check on the vertex passed\n"));
699       for (Int_t i=0; i<aEsd->GetNumberOfTracks(); ++i){
700         if (fTPCOnly == kFALSE){
701           if (fEsdTrackCuts->AcceptTrack(aEsd->GetTrack(i))){
702             AliDebug(2, Form("pt of track = %f --> check passed\n",aEsd->GetTrack(i)->Pt()));
703             decision = kTRUE;
704              break;
705           }
706         }
707         else {
708           // TPC only tracks
709           AliESDtrack *tpcTrack = fEsdTrackCuts->GetTPCOnlyTrack((AliESDEvent*)aEsd, i);
710           if (!tpcTrack){
711             AliDebug(3,Form("track %d is NOT a TPC track",i));
712             continue;
713           }
714           else{
715             AliDebug(3,Form("track %d IS a TPC track",i));
716             if (!(fEsdTrackCuts->AcceptTrack(tpcTrack))) {
717               AliDebug(2, Form("TPC track %d NOT ACCEPTED, pt = %f, eta = %f",i,tpcTrack->Pt(), tpcTrack->Eta()));
718               delete tpcTrack; tpcTrack = 0x0;
719               continue;
720             } // end if the TPC track is not accepted
721             else{
722               AliDebug(2, Form("TPC track %d ACCEPTED, pt = %f, eta = %f",i,tpcTrack->Pt(), tpcTrack->Eta()));
723               decision = kTRUE;
724               delete tpcTrack; tpcTrack = 0x0;
725               break;
726             } // end if the TPC track is accepted
727           } // end if it is a TPC track
728         } // end if you are looking at TPC only tracks                  
729       } // end loop on tracks
730     } // end check on vertex
731     else{
732       AliDebug(4,Form("Check on the vertex not passed\n"));
733       for (Int_t i=0; i<aEsd->GetNumberOfTracks(); ++i){
734         if (fEsdTrackCuts->AcceptTrack(aEsd->GetTrack(i))){
735           AliDebug(4,Form("pt of track = %f --> check would be passed if the vertex was ok\n",aEsd->GetTrack(i)->Pt()));
736           break;
737         }
738       }
739     }
740     if (!decision) AliDebug(3,("Check for kOneTrack NOT passed\n"));
741   }
742
743   return decision;
744 }
745
746 Bool_t AliTriggerAnalysis::IsTriggerClassFired(const AliESDEvent* aEsd, const Char_t* tclass) const 
747 {
748   // tclass is logical function of inputs, e.g. 01 && 02 || 03 && 11 && 21
749   // = L0 inp 1 && L0 inp 2 || L0 inp 3 && L1 inp 1 && L2 inp 1
750   // NO brackets in logical function !
751   // Spaces between operators and inputs.
752   // Not all logical functions are available in CTP= 
753   // =any function of first 4 inputs; 'AND' of other inputs, check not done
754   // This method will be replaced/complemened by similar one
755   // which works withh class and inputs names as in CTP cfg file
756   
757   TString TClass(tclass);
758   TObjArray* tcltokens = TClass.Tokenize(" ");
759   Char_t level=((TObjString*)tcltokens->At(0))->String()[0];
760   UInt_t input=atoi((((TObjString*)tcltokens->At(0))->String()).Remove(0));
761   Bool_t tcl = IsInputFired(aEsd,level,input);
762  
763   for (Int_t i=1;i<tcltokens->GetEntriesFast();i=i+2) {
764     level=((TObjString*)tcltokens->At(i+1))->String()[0];
765     input=atoi((((TObjString*)tcltokens->At(i+1))->String()).Remove(0));
766     Bool_t inpnext = IsInputFired(aEsd,level,input);
767     Char_t op =((TObjString*)tcltokens->At(i))->String()[0];
768     if (op == '&') tcl=tcl && inpnext;
769     else if (op == '|') tcl =tcl || inpnext;
770     else {
771        AliError(Form("Syntax error in %s", tclass));
772        delete tcltokens;
773        tcltokens = 0;
774        //      tcltokens->Delete();
775        return kFALSE;
776     }
777   }
778   delete tcltokens;
779   tcltokens = 0;
780        //  tcltokens->Delete();
781   return tcl;
782 }
783
784 Bool_t AliTriggerAnalysis::IsInputFired(const AliESDEvent* aEsd, Char_t level, UInt_t input) const
785 {
786   // Checks trigger input of any level
787   
788   switch (level)
789   {
790     case '0': return IsL0InputFired(aEsd,input);
791     case '1': return IsL1InputFired(aEsd,input);
792     case '2': return IsL2InputFired(aEsd,input);
793     default:
794       AliError(Form("Wrong level %i",level));
795       return kFALSE;
796   }
797 }
798
799 Bool_t AliTriggerAnalysis::IsL0InputFired(const AliESDEvent* aEsd, UInt_t input) const 
800 {
801   // Checks if corresponding bit in mask is on
802   
803   UInt_t inpmask = aEsd->GetHeader()->GetL0TriggerInputs();
804   return (inpmask & (1<<(input-1)));
805 }
806
807 Bool_t AliTriggerAnalysis::IsL1InputFired(const AliESDEvent* aEsd, UInt_t input) const
808 {
809   // Checks if corresponding bit in mask is on
810   
811   UInt_t inpmask = aEsd->GetHeader()->GetL1TriggerInputs();
812   return (inpmask & (1<<(input-1)));
813 }
814
815 Bool_t AliTriggerAnalysis::IsL2InputFired(const AliESDEvent* aEsd, UInt_t input) const 
816 {
817   // Checks if corresponding bit in mask is on
818   
819   UInt_t inpmask = aEsd->GetHeader()->GetL2TriggerInputs();
820   return (inpmask & (1<<(input-1)));
821 }
822
823 void AliTriggerAnalysis::FillHistograms(const AliESDEvent* aEsd) 
824 {
825   // fills the histograms with the info from the ESD
826   
827   fHistBitsSPD->Fill(SPDFiredChips(aEsd, 0), SPDFiredChips(aEsd, 1, kTRUE));
828   
829   V0Trigger(aEsd, kASide, kFALSE, kTRUE);
830   V0Trigger(aEsd, kCSide, kFALSE, kTRUE);
831   ZDCTDCTrigger(aEsd,kASide,kFALSE,kFALSE,kTRUE);
832   ZDCTimeTrigger(aEsd,kTRUE);
833   IsSPDClusterVsTrackletBG(aEsd, kTRUE);
834
835   AliESDZDC* zdcData = aEsd->GetESDZDC();
836   if (zdcData)
837   {
838     UInt_t quality = zdcData->GetESDQuality();
839     
840     // from Nora's presentation, general first physics meeting 16.10.09
841     static UInt_t zpc  = 0x20;
842     static UInt_t znc  = 0x10;
843     static UInt_t zem1 = 0x08;
844     static UInt_t zem2 = 0x04;
845     static UInt_t zpa  = 0x02;
846     static UInt_t zna  = 0x01;
847    
848     fHistZDC->Fill(1, quality & zna);
849     fHistZDC->Fill(2, quality & zpa);
850     fHistZDC->Fill(3, quality & zem2);
851     fHistZDC->Fill(4, quality & zem1);
852     fHistZDC->Fill(5, quality & znc);
853     fHistZDC->Fill(6, quality & zpc);
854   }
855   else
856   {
857     fHistZDC->Fill(-1);
858     AliError("AliESDZDC not available");
859   }
860   
861   if (fDoFMD) {
862     fHistFMDA->Fill(FMDHitCombinations(aEsd, kASide, kTRUE));
863     fHistFMDC->Fill(FMDHitCombinations(aEsd, kCSide, kTRUE));
864   }
865 }
866   
867 void AliTriggerAnalysis::FillTriggerClasses(const AliESDEvent* aEsd)
868 {
869   // fills trigger classes map
870   
871   TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(aEsd->GetFiredTriggerClasses().Data()));
872   if (!count)
873   {
874     count = new TParameter<Long64_t>(aEsd->GetFiredTriggerClasses(), 0);
875     fTriggerClasses->Add(new TObjString(aEsd->GetFiredTriggerClasses().Data()), count);
876   }
877   count->SetVal(count->GetVal() + 1);
878 }
879
880 Int_t AliTriggerAnalysis::SSDClusters(const AliESDEvent* aEsd)
881 {
882   // returns the number of clusters in the SSD
883   const AliMultiplicity* mult = aEsd->GetMultiplicity();
884   Int_t clusters = mult->GetNumberOfITSClusters(4)+mult->GetNumberOfITSClusters(5);
885   return clusters;
886 }
887
888
889 Int_t AliTriggerAnalysis::SPDFiredChips(const AliESDEvent* aEsd, Int_t origin, Bool_t fillHists, Int_t layer)
890 {
891   // returns the number of fired chips in the SPD
892   //
893   // origin = 0 --> aEsd->GetMultiplicity()->GetNumberOfFiredChips() (filled from clusters)
894   // origin = 1 --> aEsd->GetMultiplicity()->TestFastOrFiredChips() (from hardware bits)
895   // layer  = 0 --> both layers
896   // layer  = 1 --> inner
897   // layer  = 2 --> outer
898   
899   const AliMultiplicity* mult = aEsd->GetMultiplicity();
900   if (!mult)
901   {
902     AliError("AliMultiplicity not available");
903     return -1;
904   }
905   
906   if (origin == 0){
907     if (layer == 0) 
908       return mult->GetNumberOfFiredChips(0) + mult->GetNumberOfFiredChips(1);
909
910     return mult->GetNumberOfFiredChips(layer-1); 
911   }
912     
913   if (origin == 1)
914   {
915     Int_t nChips = 0;
916     Int_t firstChip = 0;
917     Int_t lastChip  = 1200;
918     if(layer == 1)
919       lastChip  = 400;
920     if(layer == 2)
921       firstChip = 400;
922
923     for (Int_t i=firstChip; i<lastChip; i++)
924     {
925       if (mult->TestFastOrFiredChips(i) == kTRUE)
926       {
927         // efficiency simulation (if enabled)
928         if (fSPDGFOEfficiency)
929         {
930           if (gRandom->Uniform() > fSPDGFOEfficiency->GetBinContent(i+1))
931             continue;
932         }
933         
934         nChips++;
935         if (fillHists)
936           fHistFiredBitsSPD->Fill(i);
937       }
938     }
939     return nChips;
940   }
941   
942   return -1;
943 }
944
945 Bool_t AliTriggerAnalysis::SPDGFOTrigger(const AliESDEvent* aEsd, Int_t origin)
946 {
947   // Returns if the SPD gave a global Fast OR trigger
948   
949   Int_t firedChips = SPDFiredChips(aEsd, origin);
950   
951   if (firedChips >= fSPDGFOThreshold)
952     return kTRUE;
953   return kFALSE;
954 }
955
956 Bool_t AliTriggerAnalysis::IsSPDClusterVsTrackletBG(const AliESDEvent* aEsd, Bool_t fillHists){
957   //rejects BG based on the cluster vs tracklet correlation
958   // returns true if the event is BG
959   const AliMultiplicity* mult = aEsd->GetMultiplicity();
960   if (!mult){
961     AliFatal("No multiplicity object"); // TODO: Should this be fatal?
962   }
963   Int_t ntracklet = mult->GetNumberOfTracklets();
964
965   Int_t spdClusters = 0;
966   for(Int_t ilayer = 0; ilayer < 2; ilayer++){
967     spdClusters += mult->GetNumberOfITSClusters(ilayer);
968   }
969
970   if(fillHists) {
971     fHistSPDClsVsTrk->Fill(ntracklet,spdClusters);
972   }
973
974   Bool_t isCvsTOk = kFALSE;
975   Float_t limit = Float_t(fASPDCvsTCut) + Float_t(ntracklet) * fBSPDCvsTCut;  
976   if (spdClusters > limit)        isCvsTOk = kTRUE;
977   else                            isCvsTOk = kFALSE ;
978
979   return isCvsTOk;
980
981 }
982   
983
984 AliTriggerAnalysis::V0Decision AliTriggerAnalysis::V0Trigger(const AliESDEvent* aEsd, AliceSide side, Bool_t online, Bool_t fillHists)
985 {
986   // Returns the V0 trigger decision in V0A | V0C
987   //
988   // Returns kV0Fake if the calculated average time is in a window where neither BB nor BG is expected. 
989   // The rate of such triggers can be used to estimate the background. Note that the rate has to be 
990   // rescaled with the size of the windows (numerical values see below in the code)
991   //
992   // argument 'online' is used as a switch between online and offline trigger algorithms
993   //
994   // Based on an algorithm by Cvetan Cheshkov
995
996   AliESDVZERO* esdV0 = aEsd->GetVZEROData();
997   if (!esdV0)
998   {
999     AliError("AliESDVZERO not available");
1000     return kV0Invalid;
1001   }
1002   AliDebug(2,Form("In V0Trigger: %f %f",esdV0->GetV0ATime(),esdV0->GetV0CTime()));
1003
1004   Int_t begin = -1;
1005   Int_t end = -1;
1006   
1007   if (side == kASide)
1008   {
1009     begin = 32;
1010     end = 64;
1011   } 
1012   else if (side == kCSide)
1013   {
1014     begin = 0;
1015     end = 32;
1016   }
1017   else
1018     return kV0Invalid;
1019     
1020    if (esdV0->TestBit(AliESDVZERO::kDecisionFilled)) {
1021     if (online) {
1022       if (esdV0->TestBit(AliESDVZERO::kOnlineBitsFilled)) {
1023         for (Int_t i = begin; i < end; ++i) {
1024           if (esdV0->GetBBFlag(i)) return kV0BB;
1025         }
1026         for (Int_t i = begin; i < end; ++i) {
1027           if (esdV0->GetBGFlag(i)) return kV0BG;
1028         }
1029         return kV0Empty;
1030       }
1031       else {
1032         AliWarning("V0 online trigger analysis is not yet available!");
1033         return kV0BB;
1034       }
1035     }
1036     else {
1037
1038       if (fillHists) {
1039         if (side == kASide && fHistV0A)
1040           fHistV0A->Fill(esdV0->GetV0ATime());
1041         if (side == kCSide && fHistV0C)
1042           fHistV0C->Fill(esdV0->GetV0CTime());
1043       }
1044
1045       if (side == kASide) return (V0Decision)esdV0->GetV0ADecision();
1046       else if (side == kCSide) return (V0Decision)esdV0->GetV0CDecision();
1047       else return kV0Invalid;
1048     }
1049   }
1050
1051   Float_t time = 0;
1052   Float_t weight = 0;
1053   if (fMC)
1054   {
1055     Int_t runRange;
1056     if (aEsd->GetRunNumber() <= 104803) runRange = 0;
1057     else if (aEsd->GetRunNumber() <= 104876) runRange = 1;
1058     else runRange = 2;
1059
1060     Float_t factors[3][64] = {
1061       // runs: 104792-104803
1062       {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},
1063       // runs: 104841-104876
1064       {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},
1065       // runs: 104890-92
1066       {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}
1067     };
1068     Float_t dA = 77.4 - 11.0;
1069     Float_t dC = 77.4 - 2.9;
1070     // Time misalignment
1071     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};
1072     Float_t dA2 = 2.8, dC2 = 3.3;
1073
1074     if (online) {
1075       for (Int_t i = begin; i < end; ++i) {
1076         Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
1077         Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
1078         if (esdV0->GetTime(i) >= 1e-6 &&
1079             tempTime > fV0HwWinLow && tempTime < fV0HwWinHigh &&
1080             tempAdc > fV0HwAdcThr)
1081           return kV0BB;
1082       }
1083       return kV0Empty;
1084     }
1085     else {
1086       for (Int_t i = begin; i < end; ++i) {
1087         Float_t tempAdc = esdV0->GetAdc(i)/factors[runRange][i];
1088         Float_t tempTime = (i >= 32) ? esdV0->GetTime(i)+dA : esdV0->GetTime(i)+dC;
1089         Float_t tempRawTime = (i >= 32) ? esdV0->GetTime(i)+dA+timeShift[i]+dA2 : esdV0->GetTime(i)+dC+timeShift[i]+dC2;
1090         if (esdV0->GetTime(i) >= 1e-6 &&
1091             tempRawTime < 125.0 &&
1092             tempAdc > fV0AdcThr) {
1093           weight += 1.0;
1094           time += tempTime;
1095         }
1096       }
1097     }
1098   }
1099   else {
1100     if (online) {
1101       for (Int_t i = begin; i < end; ++i) {
1102         if (esdV0->GetTime(i) >= 1e-6 &&
1103             esdV0->GetTime(i) > fV0HwWinLow && esdV0->GetTime(i) < fV0HwWinHigh &&
1104             esdV0->GetAdc(i) > fV0HwAdcThr)
1105           return kV0BB;
1106       }
1107       return kV0Empty;
1108     }
1109     else {
1110       for (Int_t i = begin; i < end; ++i) {
1111         if (esdV0->GetTime(i) > 1e-6 && esdV0->GetAdc(i) > fV0AdcThr) {
1112           Float_t correctedTime = V0CorrectLeadingTime(i, esdV0->GetTime(i), esdV0->GetAdc(i),aEsd->GetRunNumber());
1113           Float_t timeWeight = V0LeadingTimeWeight(esdV0->GetAdc(i));
1114           time += correctedTime*timeWeight;
1115             
1116           weight += timeWeight;
1117         }
1118       }
1119     }
1120   }
1121
1122   if (weight > 0) 
1123     time /= weight;
1124   time += fV0TimeOffset;
1125
1126   if (fillHists)
1127   {
1128     if (side == kASide && fHistV0A)
1129       fHistV0A->Fill(time);
1130     if (side == kCSide && fHistV0C)
1131       fHistV0C->Fill(time);
1132   }
1133   
1134   if (side == kASide)
1135   {
1136     if (time > 68 && time < 100)
1137       return kV0BB;
1138     if (time > 54 && time < 57.5) 
1139       return kV0BG;
1140     if (time > 57.5 && time < 68)
1141       return kV0Fake;
1142   }
1143   
1144   if (side == kCSide)
1145   {
1146     if (time > 75.5 && time < 100)
1147       return kV0BB;
1148     if (time > 69.5 && time < 73)
1149       return kV0BG; 
1150     if (time > 55 && time < 69.5)
1151       return kV0Fake;
1152   }
1153   
1154   return kV0Empty;
1155 }
1156
1157 Float_t AliTriggerAnalysis::V0CorrectLeadingTime(Int_t i, Float_t time, Float_t adc, Int_t runNumber) const
1158 {
1159   // Correct for slewing and align the channels
1160   //
1161   // Authors: Cvetan Cheshkov / Raphael Tieulent
1162
1163   if (time == 0) return 0;
1164
1165   // Time alignment
1166   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};
1167
1168   if(runNumber < 106031)
1169     time -= timeShift[i];
1170
1171   // Slewing correction
1172   if (adc == 0) return time;
1173
1174   Float_t p1 = 1.57345e1;
1175   Float_t p2 =-4.25603e-1;
1176
1177   if(runNumber >= 106031) adc *= (2.5/4.0);
1178   return (time - p1*TMath::Power(adc,p2));
1179 }
1180
1181 Float_t AliTriggerAnalysis::V0LeadingTimeWeight(Float_t adc) const
1182 {
1183   if (adc < 1e-6) return 0;
1184
1185   Float_t p1 = 40.211;
1186   Float_t p2 =-4.25603e-1;
1187   Float_t p3 = 0.5646;
1188
1189   return 1./(p1*p1*TMath::Power(adc,2.*(p2-1.))+p3*p3);
1190 }
1191
1192
1193 Bool_t AliTriggerAnalysis::ZDCTDCTrigger(const AliESDEvent* aEsd, AliceSide side, Bool_t useZN, Bool_t useZP, Bool_t fillHists) const
1194 {
1195   // Returns if ZDC triggered, based on TDC information 
1196   
1197   AliESDZDC *esdZDC = aEsd->GetESDZDC();
1198
1199   Bool_t zdcNA = kFALSE;
1200   Bool_t zdcNC = kFALSE;
1201   Bool_t zdcPA = kFALSE;
1202   Bool_t zdcPC = kFALSE;
1203
1204   if (fMC) {
1205         // If it's MC, we use the energy
1206     Double_t minEnergy = 0;
1207     Double_t  zNCEnergy = esdZDC->GetZDCN1Energy();
1208     Double_t  zPCEnergy = esdZDC->GetZDCP1Energy();
1209     Double_t  zNAEnergy = esdZDC->GetZDCN2Energy();
1210     Double_t  zPAEnergy = esdZDC->GetZDCP2Energy();
1211     zdcNA = (zNAEnergy>minEnergy);
1212     zdcNC = (zNCEnergy>minEnergy);
1213     zdcPA = (zPAEnergy>minEnergy);
1214     zdcPC = (zPCEnergy>minEnergy);
1215
1216   }
1217   else {
1218
1219     Bool_t tdc[32] = {kFALSE};
1220     for(Int_t itdc=0; itdc<32; itdc++){
1221       for(Int_t i=0; i<4; i++){
1222         if (esdZDC->GetZDCTDCData(itdc, i) != 0){
1223           tdc[itdc] = kTRUE;
1224         }
1225       }
1226       if(fillHists && tdc[itdc]) {
1227         fHistTDCZDC->Fill(itdc);
1228       }    
1229     }
1230     zdcNA = tdc[12];
1231     zdcNC = tdc[10];
1232     zdcPA = tdc[13];
1233     zdcPC = tdc[11];
1234   }
1235
1236   if (side == kASide) return ((useZP&&zdcPA) || (useZN&&zdcNA)); 
1237   if (side == kCSide) return ((useZP&&zdcPC) || (useZN&&zdcNC)); 
1238   return kFALSE;
1239 }
1240
1241 Bool_t AliTriggerAnalysis::ZDCTimeTrigger(const AliESDEvent *aEsd, Bool_t fillHists) const
1242 {
1243   // This method implements a selection
1244   // based on the timing in both sides of zdcN
1245   // It can be used in order to eliminate
1246   // parasitic collisions
1247   Bool_t zdcAccept = kFALSE;
1248   AliESDZDC *esdZDC = aEsd->GetESDZDC();
1249
1250   if(fMC) {
1251      UInt_t esdFlag =  esdZDC->GetESDQuality();
1252
1253      Bool_t znaFired=kFALSE, zpaFired=kFALSE;
1254      Bool_t zem1Fired=kFALSE, zem2Fired=kFALSE;
1255      Bool_t zncFired=kFALSE, zpcFired=kFALSE;
1256      //
1257      // **** Trigger patterns
1258      if((esdFlag & 0x00000001) == 0x00000001) znaFired=kTRUE;
1259      if((esdFlag & 0x00000002) == 0x00000002) zpaFired=kTRUE;
1260      if((esdFlag & 0x00000004) == 0x00000004) zem1Fired=kTRUE;
1261      if((esdFlag & 0x00000008) == 0x00000008) zem2Fired=kTRUE;
1262      if((esdFlag & 0x00000010) == 0x00000010) zncFired=kTRUE;
1263      if((esdFlag & 0x00000020) == 0x00000020) zpcFired=kTRUE;
1264      zdcAccept = (znaFired | zncFired);
1265   }
1266   else {
1267     for(Int_t i = 0; i < 4; ++i) {
1268       if (esdZDC->GetZDCTDCData(10,i) != 0) {
1269         Float_t tdcC = 0.025*(esdZDC->GetZDCTDCData(10,i)-esdZDC->GetZDCTDCData(14,i)); 
1270         Float_t tdcCcorr = esdZDC->GetZDCTDCCorrected(10,i); 
1271         for(Int_t j = 0; j < 4; ++j) {
1272           if (esdZDC->GetZDCTDCData(12,j) != 0) {
1273             Float_t tdcA = 0.025*(esdZDC->GetZDCTDCData(12,j)-esdZDC->GetZDCTDCData(14,j));
1274
1275             Float_t tdcAcorr = esdZDC->GetZDCTDCCorrected(12,j);
1276             if(fillHists) {
1277               fHistTimeZDC->Fill(tdcC-tdcA,tdcC+tdcA);
1278               fHistTimeCorrZDC->Fill(tdcCcorr-tdcAcorr,tdcCcorr+tdcAcorr);
1279             }
1280             if (esdZDC->TestBit(AliESDZDC::kCorrectedTDCFilled)) {
1281               if (((tdcCcorr-tdcAcorr-fZDCCutRefDeltaCorr)*(tdcCcorr-tdcAcorr-fZDCCutRefDeltaCorr)/(fZDCCutSigmaDeltaCorr*fZDCCutSigmaDeltaCorr) +
1282                    (tdcCcorr+tdcAcorr-fZDCCutRefSumCorr)*(tdcCcorr+tdcAcorr-fZDCCutRefSumCorr)/(fZDCCutSigmaSumCorr*fZDCCutSigmaSumCorr))< 1.0)
1283                 zdcAccept = kTRUE;
1284             }
1285             else {
1286               if (((tdcC-tdcA-fZDCCutRefDelta)*(tdcC-tdcA-fZDCCutRefDelta)/(fZDCCutSigmaDelta*fZDCCutSigmaDelta) +
1287                    (tdcC+tdcA-fZDCCutRefSum)*(tdcC+tdcA-fZDCCutRefSum)/(fZDCCutSigmaSum*fZDCCutSigmaSum))< 1.0)
1288                 zdcAccept = kTRUE;
1289             }
1290           }
1291         }
1292       }
1293     }
1294   }
1295   return zdcAccept;
1296 }
1297
1298 Bool_t AliTriggerAnalysis::ZDCTrigger(const AliESDEvent* aEsd, AliceSide side) const
1299 {
1300   // Returns if ZDC triggered
1301   
1302   AliESDZDC* zdcData = aEsd->GetESDZDC();
1303   if (!zdcData)
1304   {
1305     AliError("AliESDZDC not available");
1306     return kFALSE;
1307   }
1308   
1309   UInt_t quality = zdcData->GetESDQuality();
1310   
1311   // from Nora's presentation, general first physics meeting 16.10.09
1312   static UInt_t zpc  = 0x20;
1313   static UInt_t znc  = 0x10;
1314   static UInt_t zem1 = 0x08;
1315   static UInt_t zem2 = 0x04;
1316   static UInt_t zpa  = 0x02;
1317   static UInt_t zna  = 0x01;
1318   
1319   if (side == kASide && ((quality & zpa) || (quality & zna)))
1320     return kTRUE;
1321   if (side == kCentralBarrel && ((quality & zem1) || (quality & zem2)))
1322     return kTRUE;
1323   if (side == kCSide && ((quality & zpc) || (quality & znc)))
1324     return kTRUE;
1325   
1326   return kFALSE;
1327 }
1328
1329 Int_t AliTriggerAnalysis::FMDHitCombinations(const AliESDEvent* aEsd, AliceSide side, Bool_t fillHists)
1330 {
1331   // returns number of hit combinations agove threshold
1332   //
1333   // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
1334
1335   if (!fDoFMD)
1336     return -1;
1337
1338   // Workaround for AliESDEvent::GetFMDData is not const!
1339   const AliESDFMD* fmdData = (const_cast<AliESDEvent*>(aEsd))->GetFMDData();
1340   if (!fmdData)
1341   {
1342     AliError("AliESDFMD not available");
1343     return -1;
1344   }
1345
1346   Int_t detFrom = (side == kASide) ? 1 : 3;
1347   Int_t detTo   = (side == kASide) ? 2 : 3;
1348
1349   Int_t triggers = 0;
1350   Float_t totalMult = 0;
1351   for (UShort_t det=detFrom;det<=detTo;det++) {
1352     Int_t nRings = (det == 1 ? 1 : 2);
1353     for (UShort_t ir = 0; ir < nRings; ir++) {
1354       Char_t   ring = (ir == 0 ? 'I' : 'O');
1355       UShort_t nsec = (ir == 0 ? 20  : 40);
1356       UShort_t nstr = (ir == 0 ? 512 : 256);
1357       for (UShort_t sec =0; sec < nsec;  sec++) {
1358         for (UShort_t strip = 0; strip < nstr; strip++) {
1359           Float_t mult = fmdData->Multiplicity(det,ring,sec,strip);
1360           if (mult == AliESDFMD::kInvalidMult) continue;
1361           
1362           if (fillHists)
1363             fHistFMDSingle->Fill(mult);
1364           
1365           if (mult > fFMDLowCut)
1366             totalMult = totalMult + mult;
1367           else
1368           {
1369             if (totalMult > fFMDHitCut)
1370               triggers++;
1371               
1372             if (fillHists)
1373               fHistFMDSum->Fill(totalMult);
1374               
1375             totalMult = 0;
1376           }
1377         }
1378       }
1379     }
1380   }
1381   
1382   return triggers;
1383 }
1384
1385 Bool_t AliTriggerAnalysis::FMDTrigger(const AliESDEvent* aEsd, AliceSide side)
1386 {
1387   // Returns if the FMD triggered
1388   //
1389   // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
1390
1391   Int_t triggers = FMDHitCombinations(aEsd, side, kFALSE);
1392   
1393   if (triggers > 0)
1394     return kTRUE;
1395     
1396   return kFALSE;
1397 }
1398
1399 Long64_t AliTriggerAnalysis::Merge(TCollection* list)
1400 {
1401   // Merge a list of AliMultiplicityCorrection objects with this (needed for
1402   // PROOF).
1403   // Returns the number of merged objects (including this).
1404
1405   if (!list)
1406     return 0;
1407
1408   if (list->IsEmpty())
1409     return 1;
1410
1411   TIterator* iter = list->MakeIterator();
1412   TObject* obj;
1413
1414   // collections of all histograms
1415   const Int_t nHists = 13;
1416   TList collections[nHists];
1417
1418   Int_t count = 0;
1419   while ((obj = iter->Next())) {
1420
1421     AliTriggerAnalysis* entry = dynamic_cast<AliTriggerAnalysis*> (obj);
1422     if (entry == 0) 
1423       continue;
1424
1425     Int_t n = 0;
1426     collections[n++].Add(entry->fHistV0A);
1427     collections[n++].Add(entry->fHistV0C);
1428     collections[n++].Add(entry->fHistZDC);
1429     collections[n++].Add(entry->fHistTDCZDC);
1430     collections[n++].Add(entry->fHistTimeZDC);
1431     collections[n++].Add(entry->fHistTimeCorrZDC);
1432     collections[n++].Add(entry->fHistFMDA);
1433     collections[n++].Add(entry->fHistFMDC);
1434     collections[n++].Add(entry->fHistFMDSingle);
1435     collections[n++].Add(entry->fHistFMDSum);
1436     collections[n++].Add(entry->fHistBitsSPD);
1437     collections[n++].Add(entry->fHistFiredBitsSPD);
1438     collections[n++].Add(entry->fHistSPDClsVsTrk);
1439
1440     // merge fTriggerClasses
1441     TIterator* iter2 = entry->fTriggerClasses->MakeIterator();
1442     TObjString* obj2 = 0;
1443     while ((obj2 = dynamic_cast<TObjString*> (iter2->Next())))
1444     {
1445       TParameter<Long64_t>* param2 = static_cast<TParameter<Long64_t>*> (entry->fTriggerClasses->GetValue(obj2));
1446       
1447       TParameter<Long64_t>* param1 = dynamic_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj2));
1448       if (param1)
1449       {
1450         param1->SetVal(param1->GetVal() + param2->GetVal());
1451       }
1452       else
1453       {
1454         param1 = dynamic_cast<TParameter<Long64_t>*> (param2->Clone());
1455         fTriggerClasses->Add(new TObjString(obj2->String()), param1);
1456       }
1457     }
1458     
1459     delete iter2;
1460   
1461     count++;
1462   }
1463
1464   Int_t n = 0;
1465   fHistV0A->Merge(&collections[n++]);
1466   fHistV0C->Merge(&collections[n++]);
1467   fHistZDC->Merge(&collections[n++]);
1468   fHistTDCZDC->Merge(&collections[n++]);
1469   if (fHistTimeZDC)
1470     fHistTimeZDC->Merge(&collections[n++]);
1471   else
1472     n++;
1473   if (fHistTimeCorrZDC)
1474     fHistTimeCorrZDC->Merge(&collections[n++]);
1475   else
1476     n++;
1477   fHistFMDA->Merge(&collections[n++]);
1478   fHistFMDC->Merge(&collections[n++]);
1479   fHistFMDSingle->Merge(&collections[n++]);
1480   fHistFMDSum->Merge(&collections[n++]);
1481   fHistBitsSPD->Merge(&collections[n++]);
1482   fHistFiredBitsSPD->Merge(&collections[n++]);
1483   fHistSPDClsVsTrk->Merge(&collections[n++]);
1484   delete iter;
1485
1486   return count+1;
1487 }
1488
1489 void AliTriggerAnalysis::SaveHistograms() const
1490 {
1491   // write histograms to current directory
1492   
1493   if (!fHistBitsSPD)
1494     return;
1495     
1496   if (fHistBitsSPD) {
1497     fHistBitsSPD->Write();
1498     fHistBitsSPD->ProjectionX();
1499     fHistBitsSPD->ProjectionY();
1500   }
1501   else Printf("Cannot save fHistBitsSPD");
1502   if (fHistFiredBitsSPD) fHistFiredBitsSPD->Write();
1503   else Printf("Cannot save fHistFiredBitsSPD");
1504   if (fHistV0A) fHistV0A->Write();
1505   else Printf("Cannot save fHistV0A");
1506   if (fHistV0C) fHistV0C->Write();
1507   else Printf("Cannot save fHistV0C");
1508   if (fHistZDC) fHistZDC->Write();
1509   else Printf("Cannot save fHistZDC");
1510   if (fHistTDCZDC) fHistTDCZDC->Write();
1511   else Printf("Cannot save fHistTDCZDC");
1512   if (fHistTimeZDC) fHistTimeZDC->Write();
1513   else Printf("Cannot save fHistTimeZDC");
1514   if (fHistTimeCorrZDC) fHistTimeCorrZDC->Write();
1515   else Printf("Cannot save fHistTimeCorrZDC");
1516   if (fHistFMDA) fHistFMDA->Write();
1517   else Printf("Cannot save fHistFMDA");
1518   if (fHistFMDC) fHistFMDC->Write();
1519   else Printf("Cannot save fHistFMDC");
1520   if (fHistFMDSingle) fHistFMDSingle->Write();
1521   else Printf("Cannot save fHistFMDSingle");
1522   if (fHistFMDSum) fHistFMDSum->Write();
1523   else Printf("Cannot save fHistFMDSum");
1524   if (fSPDGFOEfficiency) fSPDGFOEfficiency->Write("fSPDGFOEfficiency");
1525   if (fHistSPDClsVsTrk) fHistSPDClsVsTrk->Write("fHistSPDClsVsTrk");
1526   //  else Printf("Cannot save fSPDGFOEfficiency");
1527   
1528   fTriggerClasses->Write("fTriggerClasses", TObject::kSingleKey);
1529 }
1530
1531 void AliTriggerAnalysis::PrintTriggerClasses() const
1532 {
1533   // print trigger classes
1534   
1535   Printf("Trigger Classes:");
1536   
1537   Printf("Event count for trigger combinations:");
1538   
1539   TMap singleTrigger;
1540   singleTrigger.SetOwner();
1541   
1542   TIterator* iter = fTriggerClasses->MakeIterator();
1543   TObjString* obj = 0;
1544   while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1545   {
1546     TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (fTriggerClasses->GetValue(obj));
1547     
1548     Printf(" %s: %ld triggers", obj->String().Data(), (Long_t)param->GetVal());
1549     
1550     TObjArray* tokens = obj->String().Tokenize(" ");
1551     for (Int_t i=0; i<tokens->GetEntries(); i++)
1552     {
1553       TParameter<Long64_t>* count = dynamic_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(((TObjString*) tokens->At(i))->String().Data()));
1554       if (!count)
1555       {
1556         count = new TParameter<Long64_t>(((TObjString*) tokens->At(i))->String().Data(), 0);
1557         singleTrigger.Add(new TObjString(((TObjString*) tokens->At(i))->String().Data()), count);
1558       }
1559       count->SetVal(count->GetVal() + param->GetVal());
1560     }
1561     
1562     delete tokens;
1563   }
1564   delete iter;
1565   
1566   Printf("Event count for single trigger:");
1567   
1568   iter = singleTrigger.MakeIterator();
1569   while ((obj = dynamic_cast<TObjString*> (iter->Next())))
1570   {
1571     TParameter<Long64_t>* param = static_cast<TParameter<Long64_t>*> (singleTrigger.GetValue(obj));
1572     
1573     Printf("  %s: %ld triggers", obj->String().Data(), (Long_t)param->GetVal());
1574   }
1575   delete iter;
1576   
1577   singleTrigger.DeleteAll();
1578 }
1579
1580