1 /* $Id: AliTriggerAnalysis.cxx 35782 2009-10-22 11:54:31Z jgrosseo $ */
3 /**************************************************************************
4 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
6 * Author: The ALICE Off-line Project. *
7 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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 //-------------------------------------------------------------------------
25 #include <Riostream.h>
29 #include <TIterator.h>
31 #include <AliTriggerAnalysis.h>
35 #include <AliESDEvent.h>
37 #include <AliMultiplicity.h>
38 #include <AliESDVZERO.h>
39 #include <AliESDZDC.h>
40 #include <AliESDFMD.h>
42 ClassImp(AliTriggerAnalysis)
44 AliTriggerAnalysis::AliTriggerAnalysis() :
63 void AliTriggerAnalysis::EnableHistograms()
65 // creates the monitoring histograms
67 fHistSPD = new TH1F("fHistSPD", "SPD GFO;number of fired chips;events", 1202, -1.5, 1200.5);
68 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);
69 fHistFiredBitsSPD = new TH1F("fHistFiredBitsSPD", "SPD GFO HARDWARE;chip number;events", 1200, -0.5, 1199.5);
70 fHistV0A = new TH1F("fHistV0A", "V0A;number of BB triggers;events", 34, -1.5, 32.5);
71 fHistV0C = new TH1F("fHistV0C", "V0C;number of BB triggers;events", 34, -1.5, 32.5);
72 fHistZDC = new TH1F("fHistZDC", "ZDC;trigger bits;events", 8, -1.5, 6.5);
75 fHistFMDA = new TH1F("fHistFMDA", "FMDA;combinations above threshold;events", 102, -1.5, 100.5);
76 fHistFMDC = new TH1F("fHistFMDC", "FMDC;combinations above threshold;events", 102, -1.5, 100.5);
77 fHistFMDSingle = new TH1F("fHistFMDSingle", "FMD single;multiplicity value;counts", 1000, 0, 10);
78 fHistFMDSum = new TH1F("fHistFMDSum", "FMD sum;multiplicity value;counts", 1000, 0, 10);
81 //____________________________________________________________________
82 const char* AliTriggerAnalysis::GetTriggerName(Trigger trigger)
84 // returns the name of the requested trigger
85 // the returned string will only be valid until the next call to this function [not thread-safe]
89 UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
91 switch (triggerNoFlags)
93 case kAcceptAll : str = "ACCEPT ALL (bypass!)"; break;
94 case kMB1 : str = "MB1"; break;
95 case kMB2 : str = "MB2"; break;
96 case kMB3 : str = "MB3"; break;
97 case kSPDGFO : str = "SPD GFO"; break;
98 case kSPDGFOBits : str = "SPD GFO Bits"; break;
99 case kV0A : str = "V0 A"; break;
100 case kV0C : str = "V0 C"; break;
101 case kZDC : str = "ZDC"; break;
102 case kZDCA : str = "ZDC A"; break;
103 case kZDCC : str = "ZDC C"; break;
104 case kFMDA : str = "FMD A"; break;
105 case kFMDC : str = "FMD C"; break;
106 case kFPANY : str = "SPD GFO | V0 | ZDC | FMD"; break;
107 default: str = ""; break;
110 if (trigger & kOfflineFlag)
116 Bool_t AliTriggerAnalysis::IsTriggerFired(const AliESDEvent* aEsd, Trigger trigger) const
118 // checks if an event has been triggered
120 if (trigger & kOfflineFlag)
121 return IsOfflineTriggerFired(aEsd, trigger);
123 return IsTriggerBitFired(aEsd, trigger);
126 Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, Trigger trigger) const
128 // checks if an event is fired using the trigger bits
130 return IsTriggerBitFired(aEsd->GetTriggerMask(), trigger);
133 Bool_t AliTriggerAnalysis::IsTriggerBitFired(ULong64_t triggerMask, Trigger trigger) const
135 // checks if an event is fired using the trigger bits
137 // this function needs the branch TriggerMask in the ESD
139 // definitions from p-p.cfg
140 ULong64_t spdFO = (1 << 14);
141 ULong64_t v0left = (1 << 10);
142 ULong64_t v0right = (1 << 11);
153 if (triggerMask & spdFO || ((triggerMask & v0left) || (triggerMask & v0right)))
159 if (triggerMask & spdFO && ((triggerMask & v0left) || (triggerMask & v0right)))
165 if (triggerMask & spdFO && (triggerMask & v0left) && (triggerMask & v0right))
171 if (triggerMask & spdFO)
176 Printf("IsEventTriggered: ERROR: Trigger type %d not implemented in this method", (Int_t) trigger);
183 Bool_t AliTriggerAnalysis::IsTriggerBitFired(const AliESDEvent* aEsd, ULong64_t tclass) const
185 // Checks if corresponding bit in mask is on
187 ULong64_t trigmask = aEsd->GetTriggerMask();
188 return (trigmask & (1ull << (tclass-1)));
191 Bool_t AliTriggerAnalysis::IsOfflineTriggerFired(const AliESDEvent* aEsd, Trigger trigger) const
193 // checks if an event has been triggered "offline"
195 UInt_t triggerNoFlags = (UInt_t) trigger % (UInt_t) kStartOfFlags;
197 switch (triggerNoFlags)
206 if (SPDGFOTrigger(aEsd, 0) || V0Trigger(aEsd, kASide) || V0Trigger(aEsd, kCSide))
212 if (SPDGFOTrigger(aEsd, 0) && (V0Trigger(aEsd, kASide) || V0Trigger(aEsd, kCSide)))
218 if (SPDGFOTrigger(aEsd, 0) && V0Trigger(aEsd, kASide) && V0Trigger(aEsd, kCSide))
224 if (SPDGFOTrigger(aEsd, 0))
230 if (SPDGFOTrigger(aEsd, 1))
236 if (V0Trigger(aEsd, kASide))
242 if (V0Trigger(aEsd, kCSide))
248 if (ZDCTrigger(aEsd, kASide) || ZDCTrigger(aEsd, kCentralBarrel) || ZDCTrigger(aEsd, kCSide))
254 if (ZDCTrigger(aEsd, kASide))
260 if (ZDCTrigger(aEsd, kCSide))
266 if (FMDTrigger(aEsd, kASide))
272 if (FMDTrigger(aEsd, kCSide))
278 if (SPDGFOTrigger(aEsd, 0) || V0Trigger(aEsd, kASide) || V0Trigger(aEsd, kCSide) || ZDCTrigger(aEsd, kASide) || ZDCTrigger(aEsd, kCentralBarrel) || ZDCTrigger(aEsd, kCSide) || FMDTrigger(aEsd, kASide) || FMDTrigger(aEsd, kCSide))
284 AliFatal(Form("Trigger type %d not implemented", triggerNoFlags));
292 Bool_t AliTriggerAnalysis::IsTriggerClassFired(const AliESDEvent* aEsd, const Char_t* tclass) const
294 // tclass is logical function of inputs, e.g. 01 && 02 || 03 && 11 && 21
295 // = L0 inp 1 && L0 inp 2 || L0 inp 3 && L1 inp 1 && L2 inp 1
296 // NO brackets in logical function !
297 // Spaces between operators and inputs.
298 // Not all logical functions are available in CTP=
299 // =any function of first 4 inputs; 'AND' of other inputs, check not done
300 // This method will be replaced/complemened by similar one
301 // which works withh class and inputs names as in CTP cfg file
303 TString TClass(tclass);
304 TObjArray* tcltokens = TClass.Tokenize(" ");
305 Char_t level=((TObjString*)tcltokens->At(0))->String()[0];
306 UInt_t input=atoi((((TObjString*)tcltokens->At(0))->String()).Remove(0));
307 Bool_t tcl = IsInputFired(aEsd,level,input);
309 for (Int_t i=1;i<tcltokens->GetEntriesFast();i=i+2) {
310 level=((TObjString*)tcltokens->At(i+1))->String()[0];
311 input=atoi((((TObjString*)tcltokens->At(i+1))->String()).Remove(0));
312 Bool_t inpnext = IsInputFired(aEsd,level,input);
313 Char_t op =((TObjString*)tcltokens->At(i))->String()[0];
314 if (op == '&') tcl=tcl && inpnext;
315 else if (op == '|') tcl =tcl || inpnext;
317 AliError(Form("Syntax error in %s", tclass));
326 Bool_t AliTriggerAnalysis::IsInputFired(const AliESDEvent* aEsd, Char_t level, UInt_t input) const
328 // Checks trigger input of any level
332 case '0': return IsL0InputFired(aEsd,input);
333 case '1': return IsL1InputFired(aEsd,input);
334 case '2': return IsL2InputFired(aEsd,input);
336 AliError(Form("Wrong level %i",level));
341 Bool_t AliTriggerAnalysis::IsL0InputFired(const AliESDEvent* aEsd, UInt_t input) const
343 // Checks if corresponding bit in mask is on
345 UInt_t inpmask = aEsd->GetHeader()->GetL0TriggerInputs();
346 return (inpmask & (1<<(input-1)));
349 Bool_t AliTriggerAnalysis::IsL1InputFired(const AliESDEvent* aEsd, UInt_t input) const
351 // Checks if corresponding bit in mask is on
353 UInt_t inpmask = aEsd->GetHeader()->GetL1TriggerInputs();
354 return (inpmask & (1<<(input-1)));
357 Bool_t AliTriggerAnalysis::IsL2InputFired(const AliESDEvent* aEsd, UInt_t input) const
359 // Checks if corresponding bit in mask is on
361 UInt_t inpmask = aEsd->GetHeader()->GetL2TriggerInputs();
362 return (inpmask & (1<<(input-1)));
365 void AliTriggerAnalysis::FillHistograms(const AliESDEvent* aEsd)
367 // fills the histograms with the info from the ESD
369 fHistSPD->Fill(SPDFiredChips(aEsd, 0));
370 fHistBitsSPD->Fill(SPDFiredChips(aEsd, 0), SPDFiredChips(aEsd, 1, kTRUE));
372 fHistV0A->Fill(V0BBTriggers(aEsd, kASide));
373 fHistV0C->Fill(V0BBTriggers(aEsd, kCSide));
375 AliESDZDC* zdcData = aEsd->GetESDZDC();
378 UInt_t quality = zdcData->GetESDQuality();
380 // from Nora's presentation, general first physics meeting 16.10.09
381 static UInt_t zpc = 0x20;
382 static UInt_t znc = 0x10;
383 static UInt_t zem1 = 0x08;
384 static UInt_t zem2 = 0x04;
385 static UInt_t zpa = 0x02;
386 static UInt_t zna = 0x01;
388 fHistZDC->Fill(1, quality & zna);
389 fHistZDC->Fill(2, quality & zpa);
390 fHistZDC->Fill(3, quality & zem2);
391 fHistZDC->Fill(4, quality & zem1);
392 fHistZDC->Fill(5, quality & znc);
393 fHistZDC->Fill(6, quality & zpc);
398 AliError("AliESDZDC not available");
401 fHistFMDA->Fill(FMDHitCombinations(aEsd, kASide, kTRUE));
402 fHistFMDC->Fill(FMDHitCombinations(aEsd, kCSide, kTRUE));
405 Int_t AliTriggerAnalysis::SPDFiredChips(const AliESDEvent* aEsd, Int_t origin, Bool_t fillHist) const
407 // returns the number of fired chips in the SPD
409 // origin = 0 --> aEsd->GetMultiplicity()->GetNumberOfFiredChips() (filled from clusters)
410 // origin = 1 --> aEsd->GetMultiplicity()->TestFastOrFiredChips() (from hardware bits)
412 const AliMultiplicity* mult = aEsd->GetMultiplicity();
415 AliError("AliMultiplicity not available");
420 return mult->GetNumberOfFiredChips(0) + mult->GetNumberOfFiredChips(1);
425 for (Int_t i=0; i<1200; i++)
426 if (mult->TestFastOrFiredChips(i) == kTRUE)
430 fHistFiredBitsSPD->Fill(i);
438 Bool_t AliTriggerAnalysis::SPDGFOTrigger(const AliESDEvent* aEsd, Int_t origin) const
440 // Returns if the SPD gave a global Fast OR trigger
442 Int_t firedChips = SPDFiredChips(aEsd, origin);
444 if (firedChips >= fSPDGFOThreshold)
449 Int_t AliTriggerAnalysis::V0BBTriggers(const AliESDEvent* aEsd, AliceSide side) const
451 // returns the number of BB triggers in V0A | V0C
453 AliESDVZERO* v0Data = aEsd->GetVZEROData();
456 AliError("AliESDVZERO not available");
461 for (Int_t i=0; i<32; i++)
463 if (side == kASide && v0Data->BBTriggerV0A(i))
465 if (side == kCSide && v0Data->BBTriggerV0C(i))
472 Bool_t AliTriggerAnalysis::V0Trigger(const AliESDEvent* aEsd, AliceSide side) const
474 // Returns if the V0 triggered
476 Int_t count = V0BBTriggers(aEsd, side);
478 if (side == kASide && count >= fV0AThreshold)
480 if (side == kCSide && count >= fV0CThreshold)
485 Bool_t AliTriggerAnalysis::ZDCTrigger(const AliESDEvent* aEsd, AliceSide side) const
487 // Returns if ZDC triggered
489 AliESDZDC* zdcData = aEsd->GetESDZDC();
492 AliError("AliESDZDC not available");
496 UInt_t quality = zdcData->GetESDQuality();
498 // from Nora's presentation, general first physics meeting 16.10.09
499 static UInt_t zpc = 0x20;
500 static UInt_t znc = 0x10;
501 static UInt_t zem1 = 0x08;
502 static UInt_t zem2 = 0x04;
503 static UInt_t zpa = 0x02;
504 static UInt_t zna = 0x01;
506 if (side == kASide && ((quality & zpa) || (quality & zna)))
508 if (side == kCentralBarrel && ((quality & zem1) || (quality & zem2)))
510 if (side == kCSide && ((quality & zpc) || (quality & znc)))
516 Int_t AliTriggerAnalysis::FMDHitCombinations(const AliESDEvent* aEsd, AliceSide side, Bool_t fillHistograms) const
518 // returns number of hit combinations agove threshold
520 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
522 // Workaround for AliESDEvent::GetFMDData is not const!
523 const AliESDFMD* fmdData = (const_cast<AliESDEvent*>(aEsd))->GetFMDData();
526 AliError("AliESDFMD not available");
530 Int_t detFrom = (side == kASide) ? 1 : 3;
531 Int_t detTo = (side == kASide) ? 2 : 3;
534 Float_t totalMult = 0;
535 for (UShort_t det=detFrom;det<=detTo;det++) {
536 Int_t nRings = (det == 1 ? 1 : 2);
537 for (UShort_t ir = 0; ir < nRings; ir++) {
538 Char_t ring = (ir == 0 ? 'I' : 'O');
539 UShort_t nsec = (ir == 0 ? 20 : 40);
540 UShort_t nstr = (ir == 0 ? 512 : 256);
541 for (UShort_t sec =0; sec < nsec; sec++) {
542 for (UShort_t strip = 0; strip < nstr; strip++) {
543 Float_t mult = fmdData->Multiplicity(det,ring,sec,strip);
544 if (mult == AliESDFMD::kInvalidMult) continue;
547 fHistFMDSingle->Fill(mult);
549 if (mult > fFMDLowCut)
550 totalMult = totalMult + mult;
553 if (totalMult > fFMDHitCut)
557 fHistFMDSum->Fill(totalMult);
569 Bool_t AliTriggerAnalysis::FMDTrigger(const AliESDEvent* aEsd, AliceSide side) const
571 // Returns if the FMD triggered
573 // Authors: FMD team, Hans Dalsgaard (code merged from FMD/AliFMDOfflineTrigger)
575 Int_t triggers = FMDHitCombinations(aEsd, side, kFALSE);
583 Long64_t AliTriggerAnalysis::Merge(TCollection* list)
585 // Merge a list of AliMultiplicityCorrection objects with this (needed for
587 // Returns the number of merged objects (including this).
595 TIterator* iter = list->MakeIterator();
598 // collections of all histograms
599 const Int_t nHists = 10;
600 TList collections[nHists];
603 while ((obj = iter->Next())) {
605 AliTriggerAnalysis* entry = dynamic_cast<AliTriggerAnalysis*> (obj);
609 collections[0].Add(entry->fHistSPD);
610 collections[1].Add(entry->fHistV0A);
611 collections[2].Add(entry->fHistV0C);
612 collections[3].Add(entry->fHistZDC);
613 collections[4].Add(entry->fHistFMDA);
614 collections[5].Add(entry->fHistFMDC);
615 collections[6].Add(entry->fHistFMDSingle);
616 collections[7].Add(entry->fHistFMDSum);
617 collections[8].Add(entry->fHistBitsSPD);
618 collections[9].Add(entry->fHistFiredBitsSPD);
623 fHistSPD->Merge(&collections[0]);
624 fHistV0A->Merge(&collections[1]);
625 fHistV0C->Merge(&collections[2]);
626 fHistZDC->Merge(&collections[3]);
627 fHistFMDA->Merge(&collections[4]);
628 fHistFMDC->Merge(&collections[5]);
629 fHistFMDSingle->Merge(&collections[6]);
630 fHistFMDSum->Merge(&collections[7]);
631 fHistBitsSPD->Merge(&collections[8]);
632 fHistFiredBitsSPD->Merge(&collections[9]);
639 void AliTriggerAnalysis::WriteHistograms() const
641 // write histograms to current directory
647 fHistBitsSPD->Write();
648 fHistFiredBitsSPD->Write();
654 fHistFMDSingle->Write();
655 fHistFMDSum->Write();