AliPhysics  de71be2 (de71be2)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
AliEmcalTriggerMakerKernel.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2015, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 #include <iostream>
16 #include <vector>
17 #include <cstring>
18 
19 #include <TArrayI.h>
20 #include <TObjArray.h>
21 
22 #include "AliAODCaloTrigger.h"
23 #include "AliEMCALGeometry.h"
24 #include "AliEMCALTriggerConstants.h"
25 #include "AliEMCALTriggerDataGrid.h"
26 #include "AliEMCALTriggerPatchInfo.h"
27 #include "AliEMCALTriggerPatchFinder.h"
28 #include "AliEMCALTriggerAlgorithm.h"
29 #include "AliEMCALTriggerRawPatch.h"
32 #include "AliLog.h"
33 #include "AliVCaloCells.h"
34 #include "AliVCaloTrigger.h"
35 #include "AliVEvent.h"
36 #include "AliVVZERO.h"
37 
41 
43  TObject(),
44  fBadChannels(),
45  fTriggerBitConfig(NULL),
46  fGeometry(NULL),
47  fPatchAmplitudes(NULL),
48  fPatchADCSimple(NULL),
49  fPatchADC(NULL),
50  fLevel0TimeMap(NULL),
51  fTriggerBitMap(NULL),
52  fPatchFinder(NULL),
53  fLevel0PatchFinder(NULL),
54  fADCtoGeV(1.),
55  fJetPatchsize(16),
56  fBkgThreshold(-1),
57  fL0Threshold(0),
58  fIsMC(kFALSE),
59  fDebugLevel(0)
60 {
61  memset(fThresholdConstants, 0, sizeof(Int_t) * 12);
62  memset(fL1ThresholdsOffline, 0, sizeof(ULong64_t) * 4);
63 }
64 
66  delete fPatchAmplitudes;
67  delete fPatchADCSimple;
68  delete fPatchADC;
69  delete fLevel0TimeMap;
70  delete fTriggerBitMap;
71  delete fPatchFinder;
72  delete fLevel0PatchFinder;
74 }
75 
82 
83  // Allocate containers for the ADC values
84  int nrows = fGeometry->GetNTotalTRU() * 2;
85  std::cout << "Allocating channel grid with 48 columns in eta and " << nrows << " rows in phi" << std::endl;
86  std::cout << "Using jet patch size " << fJetPatchsize << std::endl;
87  fPatchAmplitudes->Allocate(48, nrows);
88  fPatchADC->Allocate(48, nrows);
89  fPatchADCSimple->Allocate(48, nrows);
90  fLevel0TimeMap->Allocate(48, nrows);
91  fTriggerBitMap->Allocate(48, nrows);
92 
93  // Initialize patch finder
95  fPatchFinder->AddTriggerAlgorithm(CreateGammaTriggerAlgorithm(0, 63));
97  fPatchFinder->AddTriggerAlgorithm(jettrigger);
98  if(fJetPatchsize == 8){
99  //jettrigger->SetBitMask(jettrigger->GetBitMask() | 1 << fTriggerBitConfig->GetBkgBit());
100  jettrigger->SetBitMask(1 << fTriggerBitConfig->GetJetHighBit() | 1 << fTriggerBitConfig->GetJetLowBit() | 1 << fTriggerBitConfig->GetBkgBit());
101  } else {
102  fPatchFinder->AddTriggerAlgorithm(CreateBkgTriggerAlgorithm(0, 63));
103  }
104  if(nrows > 64){
105  // Add trigger algorithms for DCAL
106  fPatchFinder->AddTriggerAlgorithm(CreateGammaTriggerAlgorithm(64, nrows));
107  jettrigger = CreateJetTriggerAlgorithm(64, nrows);
108  fPatchFinder->AddTriggerAlgorithm(jettrigger);
109  if(fJetPatchsize == 8) {
110  //jettrigger->SetBitMask(jettrigger->GetBitMask() | 1 << fTriggerBitConfig->GetBkgBit());
111  jettrigger->SetBitMask(1 << fTriggerBitConfig->GetJetHighBit() | 1 << fTriggerBitConfig->GetJetLowBit() | 1 << fTriggerBitConfig->GetBkgBit());
112  } else {
113  fPatchFinder->AddTriggerAlgorithm(CreateBkgTriggerAlgorithm(64, nrows));
114  }
115  }
116 
118  fLevel0PatchFinder->SetPatchSize(2);
119  fLevel0PatchFinder->SetSubregionSize(1);
120 }
121 
123  fPatchAmplitudes->Reset();
124  fPatchADC->Reset();
125  fPatchADCSimple->Reset();
126  fLevel0TimeMap->Reset();
127  fTriggerBitMap->Reset();
128  memset(fL1ThresholdsOffline, 0, sizeof(ULong64_t) * 4);
129 }
130 
131 void AliEmcalTriggerMakerKernel::ReadTriggerData(AliVCaloTrigger *trigger){
132  trigger->Reset();
133  Int_t globCol=-1, globRow=-1;
134  Int_t adcAmp=-1, bitmap = 0;
135  while(trigger->Next()){
136  // get position in global 2x2 tower coordinates
137  // A0 left bottom (0,0)
138  trigger->GetPosition(globCol, globRow);
139  // exclude channel completely if it is masked as hot channel
140  if(fBadChannels.HasChannel(globCol, globRow)) continue;
141  // for some strange reason some ADC amps are initialized in reconstruction
142  // as -1, neglect those
143  trigger->GetL1TimeSum(adcAmp);
144  if (adcAmp>-1) (*fPatchADC)(globCol,globRow) = adcAmp;
145  trigger->GetTriggerBits(bitmap);
146  (*fTriggerBitMap)(globCol, globRow) = bitmap;
147 
148  // Handling for L0 triggers
149  // For the ADC value we use fCaloTriggers->GetAmplitude()
150  // In data, all patches which have 4 TRUs with proper level0 times are
151  // valid trigger patches. Therefore we need to check all neighbors for
152  // the level0 times, not only the bottom left. In order to obtain this
153  // information, a lookup table with the L0 times for each TRU is created
154  Float_t amplitude(0);
155  trigger->GetAmplitude(amplitude);
156  if(amplitude < 0) amplitude = 0;
157  (*fPatchAmplitudes)(globCol,globRow) = amplitude*4; // values are shifted by 2 bits to fit in a 10 bit word (on the hardware side)
158  Int_t nl0times(0);
159  trigger->GetNL0Times(nl0times);
160  if(nl0times){
161  TArrayI l0times(nl0times);
162  trigger->GetL0Times(l0times.GetArray());
163  for(int itime = 0; itime < nl0times; itime++){
164  if(l0times[itime] >7 && l0times[itime] < 10){
165  (*fLevel0TimeMap)(globCol,globRow) = static_cast<Char_t>(l0times[itime]);
166  break;
167  }
168  }
169  }
170  }
171 }
172 
173 void AliEmcalTriggerMakerKernel::ReadCellData(AliVCaloCells *cells){
174  // fill the patch ADCs from cells
175  Int_t nCell = cells->GetNumberOfCells();
176  for(Int_t iCell = 0; iCell < nCell; ++iCell) {
177  // get the cell info, based in index in array
178  Short_t cellId = cells->GetCellNumber(iCell);
179  Double_t amp = cells->GetAmplitude(iCell);
180  // get position
181  Int_t absId=-1;
182  fGeometry->GetFastORIndexFromCellIndex(cellId, absId);
183  Int_t globCol=-1, globRow=-1;
184  fGeometry->GetPositionInEMCALFromAbsFastORIndex(absId, globCol, globRow);
185  // add
186  (*fPatchADCSimple)(globCol,globRow) += amp/fADCtoGeV;
187  }
188 }
189 
191  // get the V0 value and compute and set the offline thresholds
192  // get V0, compute thresholds and save them as global parameters
193  ULong64_t v0S = vzerodata->GetTriggerChargeA() + vzerodata->GetTriggerChargeC();
194  for (Int_t i = 0; i < 4; ++i) {
195  // A*V0^2/2^32+B*V0/2^16+C
196  fL1ThresholdsOffline[i]= ( ((ULong64_t)fThresholdConstants[i][0]) * v0S * v0S ) >> 32;
197  fL1ThresholdsOffline[i] += ( ((ULong64_t)fThresholdConstants[i][1]) * v0S ) >> 16;
198  fL1ThresholdsOffline[i] += ((ULong64_t)fThresholdConstants[i][2]);
199  }
200 }
201 
202 TObjArray *AliEmcalTriggerMakerKernel::CreateTriggerPatches(const AliVEvent *inputevent, Bool_t useL0amp){
203  //std::cout << "Finding trigger patches" << std::endl;
204  //AliEMCALTriggerPatchInfo *trigger, *triggerMainJet, *triggerMainGamma, *triggerMainLevel0;
205  //AliEMCALTriggerPatchInfo *triggerMainJetSimple, *triggerMainGammaSimple;
206 
207  if (useL0amp) {
209  }
210  else {
211  fADCtoGeV = EMCALTrigger::kEMCL1ADCtoGeV;
212  }
213 
214  Double_t vertexpos[3];
215  inputevent->GetPrimaryVertex()->GetXYZ(vertexpos);
216  TVector3 vertexvec(vertexpos);
217 
218  Int_t isMC = fIsMC ? 1 : 0;
219  Int_t offset = (1 - isMC) * fTriggerBitConfig->GetTriggerTypesEnd();
220 
221  // Create trigger bit masks. They are needed later to remove
222  // trigger bits from the trigger bit mask for non-matching patch types
223  Int_t jetPatchMask = 1 << fTriggerBitConfig->GetJetHighBit()
224  | 1 << fTriggerBitConfig->GetJetLowBit()
225  | 1 << (fTriggerBitConfig->GetJetHighBit() + fTriggerBitConfig->GetTriggerTypesEnd())
226  | 1 << (fTriggerBitConfig->GetJetLowBit() + fTriggerBitConfig->GetTriggerTypesEnd()),
227  gammaPatchMask = 1 << fTriggerBitConfig->GetGammaHighBit()
228  | 1 << fTriggerBitConfig->GetGammaLowBit()
229  | 1 << (fTriggerBitConfig->GetGammaHighBit() + fTriggerBitConfig->GetTriggerTypesEnd())
230  | 1 << (fTriggerBitConfig->GetGammaLowBit() + fTriggerBitConfig->GetTriggerTypesEnd()),
231  bkgPatchMask = 1 << fTriggerBitConfig->GetBkgBit(),
232  l0PatchMask = 1 << fTriggerBitConfig->GetLevel0Bit();
233 
234  std::vector<AliEMCALTriggerRawPatch> patches;
235  if (useL0amp) {
236  patches = fPatchFinder->FindPatches(*fPatchAmplitudes, *fPatchADCSimple);
237  }
238  else {
239  patches = fPatchFinder->FindPatches(*fPatchADC, *fPatchADCSimple);
240  }
241  TObjArray *result = new TObjArray(1000);
242  result->SetOwner(kTRUE);
243  for(std::vector<AliEMCALTriggerRawPatch>::iterator patchit = patches.begin(); patchit != patches.end(); ++patchit){
244  // Apply offline and recalc selection
245  // Remove unwanted bits from the online bits (gamma bits from jet patches and vice versa)
246  Int_t offlinebits = 0, onlinebits = (*fTriggerBitMap)(patchit->GetColStart(), patchit->GetRowStart());
247  if(IsGammaPatch(*patchit)){
248  if(patchit->GetADC() > fL1ThresholdsOffline[1]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetGammaHighBit());
249  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[1]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetGammaHighBit());
250  if(patchit->GetADC() > fL1ThresholdsOffline[3]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetGammaLowBit());
251  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[3]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetGammaLowBit());
252  onlinebits &= gammaPatchMask;
253  }
254  if (IsJetPatch(*patchit)){
255  if(patchit->GetADC() > fL1ThresholdsOffline[0]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetJetHighBit());
256  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[0]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetJetHighBit());
257  if(patchit->GetADC() > fL1ThresholdsOffline[2]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetJetLowBit());
258  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[2]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetJetLowBit());
259  onlinebits &= jetPatchMask;
260  }
261  if (IsBkgPatch(*patchit)){
262  if(patchit->GetADC() > fBkgThreshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetBkgBit());
263  if(patchit->GetOfflineADC() > fBkgThreshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetBkgBit());
264  onlinebits &= bkgPatchMask;
265  }
266  // convert
267  AliEMCALTriggerPatchInfo *fullpatch = AliEMCALTriggerPatchInfo::CreateAndInitialize(patchit->GetColStart(), patchit->GetRowStart(),
268  patchit->GetPatchSize(), patchit->GetADC(), patchit->GetOfflineADC(), patchit->GetOfflineADC() * fADCtoGeV,
269  onlinebits | offlinebits, vertexvec, fGeometry);
270  fullpatch->SetTriggerBitConfig(fTriggerBitConfig);
271  fullpatch->SetOffSet(offset);
272  result->Add(fullpatch);
273  }
274 
275  // Find Level0 patches
276  std::vector<AliEMCALTriggerRawPatch> l0patches = fLevel0PatchFinder->FindPatches(*fPatchAmplitudes, *fPatchADCSimple);
277  for(std::vector<AliEMCALTriggerRawPatch>::iterator patchit = patches.begin(); patchit != patches.end(); ++patchit){
278  if(!CheckForL0(patchit->GetColStart(), patchit->GetRowStart())) continue;
279  Int_t offlinebits = 0;
280  if(patchit->GetADC() > fL0Threshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetLevel0Bit());
281  if(patchit->GetOfflineADC() > fL0Threshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetLevel0Bit());
282 
283  Int_t onlinebits = (*fTriggerBitMap)(patchit->GetColStart(), patchit->GetRowStart());
284  onlinebits &= l0PatchMask;
285 
286  AliEMCALTriggerPatchInfo *fullpatch = AliEMCALTriggerPatchInfo::CreateAndInitialize(patchit->GetColStart(), patchit->GetRowStart(),
287  patchit->GetPatchSize(), patchit->GetADC(), patchit->GetOfflineADC(), patchit->GetOfflineADC() * fADCtoGeV,
288  patchit->GetBitmask() | onlinebits | offlinebits, vertexvec, fGeometry);
289  fullpatch->SetTriggerBitConfig(fTriggerBitConfig);
290  result->Add(fullpatch);
291  }
292  // std::cout << "Finished finding trigger patches" << std::endl;
293  return result;
294 }
295 
296 Bool_t AliEmcalTriggerMakerKernel::CheckForL0(Int_t col, Int_t row) const {
297  if(col < 0 || row < 0){
298  AliError(Form("Patch outside range [col %d, row %d]", col, row));
299  return kFALSE;
300  }
301  Int_t truref(-1), trumod(-1), absFastor(-1), adc(-1);
302  fGeometry->GetAbsFastORIndexFromPositionInEMCAL(col, row, absFastor);
303  fGeometry->GetTRUFromAbsFastORIndex(absFastor, truref, adc);
304  int nvalid(0);
305  const int kNRowsPhi = fGeometry->GetNTotalTRU() * 2;
306  for(int ipos = 0; ipos < 2; ipos++){
307  if(row + ipos >= kNRowsPhi) continue; // boundary check
308  for(int jpos = 0; jpos < 2; jpos++){
309  if(col + jpos >= kColsEta) continue; // boundary check
310  // Check whether we are in the same TRU
311  trumod = -1;
312  fGeometry->GetAbsFastORIndexFromPositionInEMCAL(col+jpos, row+ipos, absFastor);
313  fGeometry->GetTRUFromAbsFastORIndex(absFastor, trumod, adc);
314  if(trumod != truref) continue;
315  if(col + jpos >= kColsEta) AliError(Form("Boundary error in col [%d, %d + %d]", col + jpos, col, jpos));
316  if(row + ipos >= kNRowsPhi) AliError(Form("Boundary error in row [%d, %d + %d]", row + ipos, row, ipos));
317  Char_t l0times = (*fLevel0TimeMap)(col + jpos,row + ipos);
318  if(l0times > 7 && l0times < 10) nvalid++;
319  }
320  }
321  if (nvalid != 4) return false;
322  return true;
323 }
324 
327  result->SetPatchSize(2);
328  result->SetSubregionSize(1);
329  result->SetBitMask(1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit());
330  return result;
331 }
332 
335  result->SetPatchSize(fJetPatchsize);
336  result->SetSubregionSize(4);
337  result->SetBitMask(1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit());
338  return result;
339 }
340 
343  result->SetPatchSize(8);
344  result->SetSubregionSize(4);
345  result->SetBitMask(1<<fTriggerBitConfig->GetBkgBit());
346  return result;
347 }
348 
349 Bool_t AliEmcalTriggerMakerKernel::IsGammaPatch(const AliEMCALTriggerRawPatch &patch) const {
350  ULong_t bitmask = patch.GetBitmask(), testmask = 1 << fTriggerBitConfig->GetGammaHighBit() | 1 << fTriggerBitConfig->GetGammaLowBit();
351  return bitmask & testmask;
352 }
353 
354 Bool_t AliEmcalTriggerMakerKernel::IsJetPatch(const AliEMCALTriggerRawPatch &patch) const {
355  ULong_t bitmask = patch.GetBitmask(), testmask = 1 << fTriggerBitConfig->GetJetHighBit() | 1 << fTriggerBitConfig->GetJetLowBit();
356  return bitmask & testmask;
357 }
358 
359 Bool_t AliEmcalTriggerMakerKernel::IsBkgPatch(const AliEMCALTriggerRawPatch &patch) const {
360  ULong_t bitmask = patch.GetBitmask(), testmask = 1 << fTriggerBitConfig->GetBkgBit();
361  return bitmask & testmask;
362 }
Int_t fBkgThreshold
threshold for the background patches (8x8)
ClassImp(AliAnalysisTaskTriggerRates) AliAnalysisTaskTriggerRates
AliEMCALTriggerChannelContainer fBadChannels
Container of bad channels.
Bool_t IsGammaPatch(const AliEMCALTriggerRawPatch &patch) const
Bool_t IsBkgPatch(const AliEMCALTriggerRawPatch &patch) const
TObjArray * CreateTriggerPatches(const AliVEvent *inputevent, Bool_t useL0amp=kFALSE)
AliEMCALTriggerDataGrid< int > * fTriggerBitMap
! Map of trigger bits
void ReadTriggerData(AliVCaloTrigger *trigger)
const AliEMCALTriggerBitConfig * fTriggerBitConfig
Trigger bit configuration, aliroot-dependent.
const AliEMCALGeometry * fGeometry
! Underlying EMCAL geometry
ULong64_t fL1ThresholdsOffline[4]
container for V0-dependent offline thresholds
Int_t fThresholdConstants[4][3]
simple offline trigger thresholds constants
AliEMCALTriggerAlgorithm< double > * CreateGammaTriggerAlgorithm(Int_t rowmin, Int_t rowmax) const
Double_t fADCtoGeV
! Conversion factor from ADC to GeV
Int_t fDebugLevel
Int_t fL0Threshold
threshold for the L0 patches (2x2)
AliEMCALTriggerDataGrid< double > * fPatchAmplitudes
! TRU Amplitudes (for L0)
Manager for constants used in the trigger maker.
void BuildL1ThresholdsOffline(const AliVVZERO *vzdata)
AliEMCALTriggerDataGrid< double > * fPatchADC
! ADC values map
Bool_t isMC
AliEMCALTriggerAlgorithm< double > * CreateBkgTriggerAlgorithm(Int_t rowmin, Int_t rowmax) const
AliEMCALTriggerPatchFinder< double > * fPatchFinder
! The actual patch finder
AliEMCALTriggerDataGrid< double > * fPatchADCSimple
! patch map for simple offline trigger
Kernel of the EMCAL trigger patch makerThe trigger maker kernel contains the core functionality of th...
AliEMCALTriggerDataGrid< char > * fLevel0TimeMap
! Map needed to store the level0 times
AliEMCALTriggerAlgorithm< double > * fLevel0PatchFinder
! Patch finder for Level0 patches
Bool_t IsJetPatch(const AliEMCALTriggerRawPatch &patch) const
Int_t fJetPatchsize
Size of a jet patch.
Bool_t CheckForL0(Int_t col, Int_t row) const
void ReadCellData(AliVCaloCells *cells)
AliEMCALTriggerAlgorithm< double > * CreateJetTriggerAlgorithm(Int_t rowmin, Int_t rowmax) const
const Double_t kEMCL0ADCtoGeV_AP
Conversion from EMCAL Level0 ADC to energy.