AliPhysics  master (3d17d9d)
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 #include <fstream>
19 
20 #include <TArrayI.h>
21 #include <TF1.h>
22 #include <TObjArray.h>
23 #include <TRandom.h>
24 
25 #include "AliAODCaloTrigger.h"
26 #include "AliEMCALGeometry.h"
27 #include "AliEMCALTriggerConstants.h"
28 #include "AliEMCALTriggerDataGrid.h"
29 #include "AliEMCALTriggerPatchInfo.h"
30 #include "AliEMCALTriggerPatchFinder.h"
31 #include "AliEMCALTriggerAlgorithm.h"
32 #include "AliEMCALTriggerRawPatch.h"
35 #include "AliLog.h"
36 #include "AliVCaloCells.h"
37 #include "AliVCaloTrigger.h"
38 #include "AliVEvent.h"
39 #include "AliVVZERO.h"
40 
44 
46  TObject(),
47  fBadChannels(),
48  fOfflineBadChannels(),
49  fFastORPedestal(5000),
50  fTriggerBitConfig(nullptr),
51  fPatchFinder(nullptr),
52  fLevel0PatchFinder(nullptr),
53  fL0MinTime(7),
54  fL0MaxTime(10),
55  fMinCellAmp(0),
56  fMinL0FastORAmp(0),
57  fMinL1FastORAmp(0),
58  fBkgThreshold(-1),
59  fL0Threshold(0),
60  fIsMC(kFALSE),
61  fDebugLevel(0),
62  fMinCellAmplitude(0.),
63  fApplyOnlineBadChannelsToOffline(kFALSE),
64  fApplyOnlineBadChannelsToSmeared(kFALSE),
65  fConfigured(kFALSE),
66  fSmearModelMean(nullptr),
67  fSmearModelSigma(nullptr),
68  fSmearThreshold(0.1),
69  fScaleShift(0.),
70  fDoBackgroundSubtraction(false),
71  fGeometry(nullptr),
72  fPatchAmplitudes(nullptr),
73  fPatchADCSimple(nullptr),
74  fPatchADC(nullptr),
75  fPatchEnergySimpleSmeared(nullptr),
76  fLevel0TimeMap(nullptr),
77  fTriggerBitMap(nullptr),
78  fADCtoGeV(1.)
79 {
80  memset(fThresholdConstants, 0, sizeof(Int_t) * 12);
81  memset(fL1ThresholdsOffline, 0, sizeof(ULong64_t) * 4);
82  fCellTimeLimits[0] = -10000.;
83  fCellTimeLimits[1] = 10000.;
84  memset(fRhoValues, 0, sizeof(Double_t) * kNIndRho);
85 }
86 
88  delete fPatchAmplitudes;
89  delete fPatchADCSimple;
90  delete fPatchADC;
92  delete fLevel0TimeMap;
93  delete fTriggerBitMap;
94  delete fPatchFinder;
95  delete fLevel0PatchFinder;
97 }
98 
100  if (!fTriggerBitConfig) {
101  AliWarning("Trigger bit configuration was not provided! Assuming new bit configuration (>= 2013).");
102  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigNew();
103  SetTriggerBitConfig(triggerBitConfig);
104  }
105 
111 
112  // Allocate containers for the ADC values
113  int nrows = fGeometry->GetNTotalTRU() * 2;
114  std::cout << "Allocating channel grid with 48 columns in eta and " << nrows << " rows in phi" << std::endl;
115  fPatchAmplitudes->Allocate(48, nrows);
116  fPatchADC->Allocate(48, nrows);
117  fPatchADCSimple->Allocate(48, nrows);
118  fLevel0TimeMap->Allocate(48, nrows);
119  fTriggerBitMap->Allocate(48, nrows);
120 
122  // Allocate container for energy smearing (if enabled)
124  fPatchEnergySimpleSmeared->Allocate(48, nrows);
125  }
126 }
127 
128 void AliEmcalTriggerMakerKernel::AddL1TriggerAlgorithm(Int_t rowmin, Int_t rowmax, UInt_t bitmask, Int_t patchSize, Int_t subregionSize)
129 {
131  AliEMCALTriggerAlgorithm<double> *trigger = new AliEMCALTriggerAlgorithm<double>(rowmin, rowmax, bitmask);
132  trigger->SetPatchSize(patchSize);
133  trigger->SetSubregionSize(subregionSize);
134  fPatchFinder->AddTriggerAlgorithm(trigger);
135 }
136 
137 void AliEmcalTriggerMakerKernel::SetL0TriggerAlgorithm(Int_t rowmin, Int_t rowmax, UInt_t bitmask, Int_t patchSize, Int_t subregionSize)
138 {
140  fLevel0PatchFinder = new AliEMCALTriggerAlgorithm<double>(rowmin, rowmax, bitmask);
141  fLevel0PatchFinder->SetPatchSize(patchSize);
142  fLevel0PatchFinder->SetSubregionSize(subregionSize);
143 }
144 
146 {
147  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigNew();
148  SetTriggerBitConfig(triggerBitConfig);
149 
150  // Initialize patch finder
151  if (fPatchFinder) delete fPatchFinder;
153 
154  SetL0TriggerAlgorithm(0, 103, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
155  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
156  AddL1TriggerAlgorithm(64, 103, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
157  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit() | 1<<fTriggerBitConfig->GetBkgBit(), 8, 4);
158  AddL1TriggerAlgorithm(64, 103, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit() | 1<<fTriggerBitConfig->GetBkgBit(), 8, 4);
160  fConfigured = true;
161 }
162 
164 {
165  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigNew();
166  SetTriggerBitConfig(triggerBitConfig);
167 
168  // Initialize patch finder
169  if (fPatchFinder) delete fPatchFinder;
171 
172  SetL0TriggerAlgorithm(0, 103, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
173  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
174  AddL1TriggerAlgorithm(64, 103, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
175  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit(), 16, 4);
176  AddL1TriggerAlgorithm(64, 103, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit(), 8, 4);
177  fConfigured = true;
178 }
179 
181 {
182  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigNew();
183  SetTriggerBitConfig(triggerBitConfig);
184 
185  // Initialize patch finder
186  if (fPatchFinder) delete fPatchFinder;
188 
189  SetL0TriggerAlgorithm(0, 103, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
190  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
191  AddL1TriggerAlgorithm(64, 103, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
192  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit(), 8, 4);
193  AddL1TriggerAlgorithm(64, 103, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit(), 8, 4);
194  fConfigured = true;
195 }
196 
198 {
199  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigNew();
200  SetTriggerBitConfig(triggerBitConfig);
201 
202  // Initialize patch finder
203  if (fPatchFinder) delete fPatchFinder;
205 
206  SetL0TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
207  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetGammaHighBit() | 1<<fTriggerBitConfig->GetGammaLowBit(), 2, 1);
208  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetJetHighBit() | 1<<fTriggerBitConfig->GetJetLowBit(), 16, 4);
209  fConfigured = true;
210 }
211 
213 {
214  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigOld();
215  SetTriggerBitConfig(triggerBitConfig);
216 
217  // Initialize patch finder
218  if (fPatchFinder) delete fPatchFinder;
220 
221  SetL0TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
222  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetGammaHighBit(), 2, 1);
223  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetJetHighBit(), 16, 4);
224  fConfigured = true;
225 }
226 
228 {
229  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigOld();
230  SetTriggerBitConfig(triggerBitConfig);
231 
232  // Initialize patch finder
233  if (fPatchFinder) delete fPatchFinder;
235 
236  SetL0TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
237  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetGammaHighBit(), 2, 1);
238  AddL1TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetJetHighBit(), 16, 4);
239  fConfigured = true;
240 }
241 
243 {
244  AliEMCALTriggerBitConfig* triggerBitConfig = new AliEMCALTriggerBitConfigOld();
245  SetTriggerBitConfig(triggerBitConfig);
246 
247  // Initialize patch finder
248  if (fPatchFinder) delete fPatchFinder;
250 
251  SetL0TriggerAlgorithm(0, 63, 1<<fTriggerBitConfig->GetLevel0Bit(), 2, 1);
252  fConfigured = true;
253 }
254 
256 {
257  Short_t absId = 0;
258 
259  while (stream.good()) {
260  stream >> absId;
261  AddOfflineBadChannel(absId);
262  }
263 }
264 
266 {
267  std::ifstream file(fname);
269 }
270 
272 {
273  Short_t absId = -1;
274 
275  while (stream.good()) {
276  stream >> absId;
277  AddFastORBadChannel(absId);
278  }
279 }
280 
282 {
283  std::ifstream file(fname);
285 }
286 
288 {
289  if (absId < 0 || absId >= fFastORPedestal.GetSize()) {
290  AliWarning(Form("Abs. ID %d out of range (0,5000)", absId));
291  return;
292  }
293  fFastORPedestal[absId] = ped;
294 }
295 
297 {
298  Short_t absId = 0;
299  Float_t ped = 0;
300  while (stream.good()) {
301  stream >> ped;
302  SetFastORPedestal(absId, ped);
303  absId++;
304  }
305 }
306 
308 {
309  std::ifstream file(fname);
311 }
312 
314  fPatchAmplitudes->Reset();
315  fPatchADC->Reset();
316  fPatchADCSimple->Reset();
317  fLevel0TimeMap->Reset();
318  fTriggerBitMap->Reset();
320  memset(fL1ThresholdsOffline, 0, sizeof(ULong64_t) * 4);
321 }
322 
323 void AliEmcalTriggerMakerKernel::ReadTriggerData(AliVCaloTrigger *trigger){
324  trigger->Reset();
325  Int_t globCol=-1, globRow=-1;
326  Int_t adcAmp=-1, bitmap = 0;
327  while(trigger->Next()){
328  // get position in global 2x2 tower coordinates
329  // A0 left bottom (0,0)
330  trigger->GetPosition(globCol, globRow);
331  Int_t absId = -1;
332  fGeometry->GetAbsFastORIndexFromPositionInEMCAL(globCol, globRow, absId);
333 
334  // trigger bits can also occur on online masked fastors. Therefore trigger
335  // bits are handled before ADC values, and independently whether fastor is
336  // masked or not
337  trigger->GetTriggerBits(bitmap);
338  try {
339  (*fTriggerBitMap)(globCol, globRow) = bitmap;
340  }
342  std::string dirstring = e.GetDirection() == AliEMCALTriggerDataGrid<int>::OutOfBoundsException::kColDir ? "Col" : "Row";
343  AliErrorStream() << "Trigger maker task - filling trigger bit grid - index out-of-bounds in " << dirstring << ": " << e.GetIndex() << std::endl;
344  }
345 
346  // also Level0 times need to be handled without masking of the fastor ...
347  // @TODO cross check
348  Int_t nl0times(0);
349  trigger->GetNL0Times(nl0times);
350  if(nl0times){
351  TArrayI l0times(nl0times);
352  trigger->GetL0Times(l0times.GetArray());
353  for(int itime = 0; itime < nl0times; itime++){
354  try{
355  (*fLevel0TimeMap)(globCol,globRow) = static_cast<Char_t>(l0times[itime]);
356  break;
357  }
359  std::string dirstring = e.GetDirection() == AliEMCALTriggerDataGrid<char>::OutOfBoundsException::kColDir ? "Col" : "Row";
360  AliErrorStream() << "Trigger maker task - filling trigger bit grid - index out-of-bounds in " << dirstring << ": " << e.GetIndex() << std::endl;
361  }
362  }
363  }
364 
365  // exclude channel completely if it is masked as hot channel
366  if (fBadChannels.find(absId) != fBadChannels.end()){
367  AliDebugStream(1) << "Found ADC for masked fastor " << absId << ", rejecting" << std::endl;
368  continue;
369  }
370  // for some strange reason some ADC amps are initialized in reconstruction
371  // as -1, neglect those
372  trigger->GetL1TimeSum(adcAmp);
373  if (adcAmp < 0) adcAmp = 0;
374 
375  if (adcAmp >= fMinL1FastORAmp) {
376  try {
377  (*fPatchADC)(globCol,globRow) = adcAmp;
378  }
380  std::string dirstring = e.GetDirection() == AliEMCALTriggerDataGrid<double>::OutOfBoundsException::kColDir ? "Col" : "Row";
381  AliErrorStream() << "Trigger maker task - filling trigger bit grid - index out-of-bounds in " << dirstring << ": " << e.GetIndex() << std::endl;
382  }
383  }
384 
385  // Handling for L0 triggers
386  // For the ADC value we use fCaloTriggers->GetAmplitude()
387  // In data, all patches which have 4 TRUs with proper level0 times are
388  // valid trigger patches. Therefore we need to check all neighbors for
389  // the level0 times, not only the bottom left. In order to obtain this
390  // information, a lookup table with the L0 times for each TRU is created
391  Float_t amplitude(0);
392  trigger->GetAmplitude(amplitude);
393  amplitude *= 4; // values are shifted by 2 bits to fit in a 10 bit word (on the hardware side)
394  amplitude -= fFastORPedestal[absId];
395  if(amplitude < 0) amplitude = 0;
396  if (amplitude >= fMinL0FastORAmp) {
397  try{
398  (*fPatchAmplitudes)(globCol,globRow) = amplitude;
399  }
401  std::string dirstring = e.GetDirection() == AliEMCALTriggerDataGrid<int>::OutOfBoundsException::kColDir ? "Col" : "Row";
402  AliErrorStream() << "Trigger maker task - filling trigger bit grid - index out-of-bounds in " << dirstring << ": " << e.GetIndex() << std::endl;
403  }
404  }
405  }
406 
407  // Reading of the rho values (only PbPb)
409  AliInfoStream() << "Reading median values: EMCAL " << fRhoValues[kIndRhoEMCAL] << ", DCAL " << fRhoValues[kIndRhoDCAL] << std::endl;
410  fRhoValues[kIndRhoEMCAL] = trigger->GetMedian(0); // EMCAL STU at position 0
411  fRhoValues[kIndRhoDCAL] = trigger->GetMedian(1); // DCAL STU at position 1
412  }
413 }
414 
415 void AliEmcalTriggerMakerKernel::ReadCellData(AliVCaloCells *cells){
416  // fill the patch ADCs from cells
417  Int_t nCell = cells->GetNumberOfCells();
418  for(Int_t iCell = 0; iCell < nCell; ++iCell) {
419  // get the cell info, based in index in array
420  Short_t cellId = cells->GetCellNumber(iCell);
421 
422  // Check bad channel map
423  if (fOfflineBadChannels.find(cellId) != fOfflineBadChannels.end()) {
424  AliDebugStream(1) << "Cell " << cellId << " masked as bad channel, rejecting." << std::endl;
425  continue;
426  }
427 
428  Double_t amp = cells->GetAmplitude(iCell),
429  celltime = cells->GetTime(iCell);
430  if(celltime < fCellTimeLimits[0] || celltime > fCellTimeLimits[1]) continue;
431  if(amp < fMinCellAmplitude) continue;
432  if(fScaleShift) amp += fScaleShift;
433  amp = TMath::Max(amp, 0.); // never go negative in energy
434  // get position
435  Int_t absId=-1;
436  fGeometry->GetFastORIndexFromCellIndex(cellId, absId);
438  // Exclude FEE amplitudes from cells which are within a TRU which is masked at
439  // online level. Using this the online acceptance can be applied to offline
440  // patches as well.
441  if(fBadChannels.find(absId) != fBadChannels.end()){
442  AliDebugStream(1) << "Cell " << cellId << " corresponding to masked fastor " << absId << ", rejecting." << std::endl;
443  continue;
444  }
445  }
446  Int_t globCol=-1, globRow=-1;
447  fGeometry->GetPositionInEMCALFromAbsFastORIndex(absId, globCol, globRow);
448  // add
449  amp /= fADCtoGeV;
450  try {
451  if (amp >= fMinCellAmp) (*fPatchADCSimple)(globCol,globRow) += amp;
452  }
454  }
455  }
456 
457  // Apply energy smearing (if enabled)
459  AliDebugStream(1) << "Trigger Maker: Apply energy smearing" << std::endl;
460  for(int icol = 0; icol < fPatchADCSimple->GetNumberOfCols(); icol++){
461  for(int irow = 0; irow < fPatchADCSimple->GetNumberOfRows(); irow++){
462  bool doChannel = true;
464  int absFastor = -1;
465  fGeometry->GetAbsFastORIndexFromPositionInEMCAL(icol, irow, absFastor);
466  if(absFastor > -1) {
467  if(fBadChannels.find(absFastor) != fBadChannels.end()){
468  AliDebugStream(1) << "In smearing, FastOR " << absFastor << " masked, rejecting." << std::endl;
469  doChannel = false;
470  }
471  }
472  }
473  if(!doChannel) continue;
474  double energyorig = (*fPatchADCSimple)(icol, irow) * fADCtoGeV; // Apply smearing in GeV
475  double energysmear = energyorig;
476  if(energyorig > fSmearThreshold){
477  double mean = fSmearModelMean->Eval(energyorig), sigma = fSmearModelSigma->Eval(energyorig);
478  energysmear = gRandom->Gaus(mean, sigma);
479  if(energysmear < 0) energysmear = 0; // only accept positive or 0 energy values
480  AliDebugStream(1) << "Original energy " << energyorig << ", mean " << mean << ", sigma " << sigma << ", smeared " << energysmear << std::endl;
481  }
482  (*fPatchEnergySimpleSmeared)(icol, irow) = energysmear;
483  }
484  }
485  AliDebugStream(1) << "Smearing done" << std::endl;
486  }
487 }
488 
490  // get the V0 value and compute and set the offline thresholds
491  // get V0, compute thresholds and save them as global parameters
492  ULong64_t v0S = vzerodata->GetTriggerChargeA() + vzerodata->GetTriggerChargeC();
493  for (Int_t i = 0; i < 4; ++i) {
494  // A*V0^2/2^32+B*V0/2^16+C
495  fL1ThresholdsOffline[i]= ( ((ULong64_t)fThresholdConstants[i][0]) * v0S * v0S ) >> 32;
496  fL1ThresholdsOffline[i] += ( ((ULong64_t)fThresholdConstants[i][1]) * v0S ) >> 16;
497  fL1ThresholdsOffline[i] += ((ULong64_t)fThresholdConstants[i][2]);
498  }
499 }
500 
501 void AliEmcalTriggerMakerKernel::CreateTriggerPatches(const AliVEvent *inputevent, std::vector<AliEMCALTriggerPatchInfo> &outputcont, Bool_t useL0amp){
502  //std::cout << "Finding trigger patches" << std::endl;
503  //AliEMCALTriggerPatchInfo *trigger, *triggerMainJet, *triggerMainGamma, *triggerMainLevel0;
504  //AliEMCALTriggerPatchInfo *triggerMainJetSimple, *triggerMainGammaSimple;
505 
506  if (useL0amp) {
508  }
509  else {
510  fADCtoGeV = EMCALTrigger::kEMCL1ADCtoGeV;
511  }
512 
513  Double_t vertexpos[3];
514  inputevent->GetPrimaryVertex()->GetXYZ(vertexpos);
515  TVector3 vertexvec(vertexpos);
516 
517  Int_t isMC = fIsMC ? 1 : 0;
518  Int_t offset = (1 - isMC) * fTriggerBitConfig->GetTriggerTypesEnd();
519 
520  // Create trigger bit masks. They are needed later to remove
521  // trigger bits from the trigger bit mask for non-matching patch types
522  Int_t jetPatchMask = 1 << fTriggerBitConfig->GetJetHighBit()
523  | 1 << fTriggerBitConfig->GetJetLowBit()
524  | 1 << (fTriggerBitConfig->GetJetHighBit() + fTriggerBitConfig->GetTriggerTypesEnd())
525  | 1 << (fTriggerBitConfig->GetJetLowBit() + fTriggerBitConfig->GetTriggerTypesEnd()),
526  gammaPatchMask = 1 << fTriggerBitConfig->GetGammaHighBit()
527  | 1 << fTriggerBitConfig->GetGammaLowBit()
528  | 1 << (fTriggerBitConfig->GetGammaHighBit() + fTriggerBitConfig->GetTriggerTypesEnd())
529  | 1 << (fTriggerBitConfig->GetGammaLowBit() + fTriggerBitConfig->GetTriggerTypesEnd()),
530  bkgPatchMask = 1 << fTriggerBitConfig->GetBkgBit();
531  //l0PatchMask = 1 << fTriggerBitConfig->GetLevel0Bit();
532 
533  std::vector<AliEMCALTriggerRawPatch> patches;
534  if (fPatchFinder) {
535  if (useL0amp) {
536  patches = fPatchFinder->FindPatches(*fPatchAmplitudes, *fPatchADCSimple);
537  }
538  else {
539  patches = fPatchFinder->FindPatches(*fPatchADC, *fPatchADCSimple);
540  }
541  }
542  outputcont.clear();
543  for(std::vector<AliEMCALTriggerRawPatch>::iterator patchit = patches.begin(); patchit != patches.end(); ++patchit){
544  // Apply offline and recalc selection
545  // Remove unwanted bits from the online bits (gamma bits from jet patches and vice versa)
546  Int_t offlinebits = 0, onlinebits = (*fTriggerBitMap)(patchit->GetColStart(), patchit->GetRowStart());
547  if(HasPHOSOverlap(*patchit)) continue;
548  if(IsGammaPatch(*patchit)){
549  if(patchit->GetADC() > fL1ThresholdsOffline[1]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetGammaHighBit());
550  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[1]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetGammaHighBit());
551  if(patchit->GetADC() > fL1ThresholdsOffline[3]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetGammaLowBit());
552  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[3]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetGammaLowBit());
553  onlinebits &= gammaPatchMask;
554  }
555  if (IsJetPatch(*patchit)){
556  if(patchit->GetADC() > fL1ThresholdsOffline[0]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetJetHighBit());
557  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[0]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetJetHighBit());
558  if(patchit->GetADC() > fL1ThresholdsOffline[2]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetJetLowBit());
559  if(patchit->GetOfflineADC() > fL1ThresholdsOffline[2]) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetJetLowBit());
560  onlinebits &= jetPatchMask;
561  }
562  if (IsBkgPatch(*patchit)){
563  if(patchit->GetADC() > fBkgThreshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetBkgBit());
564  if(patchit->GetOfflineADC() > fBkgThreshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetBkgBit());
565  onlinebits &= bkgPatchMask;
566  }
568  double area = TMath::Power(static_cast<double>(patchit->GetPatchSize())/8., 2);
569  double rhoval = (patchit->GetRowStart() >= 64) ? fRhoValues[kIndRhoDCAL] : fRhoValues[kIndRhoEMCAL]; // Rho values are for a detector measured in the opposite arm
570  AliDebugStream(1) << "Subtracting background for area " << area << ": " << rhoval << " -> " << (area * rhoval) << std::endl;
571  patchit->SetADC(patchit->GetADC() - area * rhoval);
572  }
573  // convert
574  AliEMCALTriggerPatchInfo fullpatch;
575  fullpatch.Initialize(patchit->GetColStart(), patchit->GetRowStart(),
576  patchit->GetPatchSize(), patchit->GetADC(), patchit->GetOfflineADC(), patchit->GetOfflineADC() * fADCtoGeV,
577  onlinebits | offlinebits, vertexvec, fGeometry);
578  fullpatch.SetTriggerBitConfig(fTriggerBitConfig);
579  fullpatch.SetOffSet(offset);
581  // Add smeared energy
582  double energysmear = 0;
583  for(int icol = 0; icol < fullpatch.GetPatchSize(); icol++){
584  for(int irow = 0; irow < fullpatch.GetPatchSize(); irow++){
585  energysmear += (*fPatchEnergySimpleSmeared)(fullpatch.GetColStart() + icol, fullpatch.GetRowStart() + irow);
586  }
587  }
588  AliDebugStream(1) << "Patch size(" << fullpatch.GetPatchSize() <<") energy " << fullpatch.GetPatchE() << " smeared " << energysmear << std::endl;
589  fullpatch.SetSmearedEnergy(energysmear);
590  }
591  outputcont.push_back(fullpatch);
592  }
593 
594  // Find Level0 patches
595  std::vector<AliEMCALTriggerRawPatch> l0patches;
596  if (fLevel0PatchFinder) l0patches = fLevel0PatchFinder->FindPatches(*fPatchAmplitudes, *fPatchADCSimple);
597  for(std::vector<AliEMCALTriggerRawPatch>::iterator patchit = l0patches.begin(); patchit != l0patches.end(); ++patchit){
598  Int_t offlinebits = 0, onlinebits = 0;
599  if(HasPHOSOverlap(*patchit)) continue;
600  ELevel0TriggerStatus_t L0status = CheckForL0(patchit->GetColStart(), patchit->GetRowStart());
601  if (L0status == kNotLevel0) continue;
602  if (L0status == kLevel0Fired) SETBIT(onlinebits, fTriggerBitConfig->GetLevel0Bit());
603  if (patchit->GetADC() > fL0Threshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kRecalcOffset + fTriggerBitConfig->GetLevel0Bit());
604  if (patchit->GetOfflineADC() > fL0Threshold) SETBIT(offlinebits, AliEMCALTriggerPatchInfo::kOfflineOffset + fTriggerBitConfig->GetLevel0Bit());
605 
606  AliEMCALTriggerPatchInfo fullpatch;
607  fullpatch.Initialize(patchit->GetColStart(), patchit->GetRowStart(),
608  patchit->GetPatchSize(), patchit->GetADC(), patchit->GetOfflineADC(), patchit->GetOfflineADC() * fADCtoGeV,
609  onlinebits | offlinebits, vertexvec, fGeometry);
610  fullpatch.SetTriggerBitConfig(fTriggerBitConfig);
612  // Add smeared energy
613  double energysmear = 0;
614  for(int icol = 0; icol < fullpatch.GetPatchSize(); icol++){
615  for(int irow = 0; irow < fullpatch.GetPatchSize(); irow++){
616  energysmear += (*fPatchEnergySimpleSmeared)(fullpatch.GetColStart() + icol, fullpatch.GetRowStart() + irow);
617  }
618  }
619  fullpatch.SetSmearedEnergy(energysmear);
620  }
621  outputcont.push_back(fullpatch);
622  }
623  // std::cout << "Finished finding trigger patches" << std::endl;
624 }
625 
627  double amp = 0;
628  try {
629  amp = (*fPatchAmplitudes)(col, row);
631 
632  }
633  return amp;
634 }
635 
637  double adc = 0;
638  try {
639  adc = (*fPatchADC)(col, row);
641 
642  }
643  return adc;
644 }
645 
647  double adc = 0;
648  try {
649  adc = (*fPatchADC)(col, row) * EMCALTrigger::kEMCL1ADCtoGeV;
651 
652  }
653  return adc;
654 }
655 
657  double adc = 0;
658  try {
659  adc = (*fPatchADCSimple)(col, row);
661 
662  }
663  return adc;
664 }
665 
667  double adc = 0;
668  try {
669  adc = (*fPatchADCSimple)(col, row) * fADCtoGeV;
671 
672  }
673  return adc;
674 }
675 
677  double adc = 0;
679  try {
680  adc = (*fPatchEnergySimpleSmeared)(col, row);
682 
683  }
684  }
685  return adc;
686 }
687 
689  return fPatchADC->GetNumberOfRows();
690 }
691 
694 
695  if(col < 0 || row < 0){
696  AliError(Form("Patch outside range [col %d, row %d]", col, row));
697  return kNotLevel0;
698  }
699  Int_t truref(-1), trumod(-1), absFastor(-1), adc(-1);
700  fGeometry->GetAbsFastORIndexFromPositionInEMCAL(col, row, absFastor);
701  fGeometry->GetTRUFromAbsFastORIndex(absFastor, truref, adc);
702  int nvalid(0);
703  const int kNRowsPhi = fGeometry->GetNTotalTRU() * 2;
704  for(int ipos = 0; ipos < 2; ipos++){
705  if(row + ipos >= kNRowsPhi) continue; // boundary check
706  for(int jpos = 0; jpos < 2; jpos++){
707  if(col + jpos >= kColsEta) continue; // boundary check
708  // Check whether we are in the same TRU
709  trumod = -1;
710  fGeometry->GetAbsFastORIndexFromPositionInEMCAL(col+jpos, row+ipos, absFastor);
711  fGeometry->GetTRUFromAbsFastORIndex(absFastor, trumod, adc);
712  if(trumod != truref) {
713  result = kNotLevel0;
714  return result;
715  }
716  if(col + jpos >= kColsEta) AliError(Form("Boundary error in col [%d, %d + %d]", col + jpos, col, jpos));
717  if(row + ipos >= kNRowsPhi) AliError(Form("Boundary error in row [%d, %d + %d]", row + ipos, row, ipos));
718  Char_t l0times = (*fLevel0TimeMap)(col + jpos,row + ipos);
719  if(l0times > fL0MinTime && l0times < fL0MaxTime) nvalid++;
720  }
721  }
722  if (nvalid == 4) result = kLevel0Fired;
723  return result;
724 }
725 
727  fBadChannels.clear();
728 }
729 
731  fOfflineBadChannels.clear();
732 }
733 
734 Bool_t AliEmcalTriggerMakerKernel::IsGammaPatch(const AliEMCALTriggerRawPatch &patch) const {
735  ULong_t bitmask = patch.GetBitmask(), testmask = 1 << fTriggerBitConfig->GetGammaHighBit() | 1 << fTriggerBitConfig->GetGammaLowBit();
736  return bitmask & testmask;
737 }
738 
739 Bool_t AliEmcalTriggerMakerKernel::IsJetPatch(const AliEMCALTriggerRawPatch &patch) const {
740  ULong_t bitmask = patch.GetBitmask(), testmask = 1 << fTriggerBitConfig->GetJetHighBit() | 1 << fTriggerBitConfig->GetJetLowBit();
741  return bitmask & testmask;
742 }
743 
744 Bool_t AliEmcalTriggerMakerKernel::IsBkgPatch(const AliEMCALTriggerRawPatch &patch) const {
745  ULong_t bitmask = patch.GetBitmask(), testmask = 1 << fTriggerBitConfig->GetBkgBit();
746  return bitmask & testmask;
747 }
748 
749 void AliEmcalTriggerMakerKernel::SetTriggerBitConfig(const AliEMCALTriggerBitConfig *const config) {
750  if (config == fTriggerBitConfig) return;
752  fTriggerBitConfig = config;
753 }
754 
755 bool AliEmcalTriggerMakerKernel::HasPHOSOverlap(const AliEMCALTriggerRawPatch &patch) const {
756  const int kEtaMinPhos = 16, kEtaMaxPhos = 31, kPhiMinPhos = 64, kPhiMaxPhos = 99;
757  if(patch.GetRowStart() + patch.GetPatchSize() -1 < kPhiMinPhos) return false; // EMCAL Patch
758  if(patch.GetRowStart() > kPhiMaxPhos) return false; // DCAL 1/3 supermodule
759  if(patch.GetColStart() + patch.GetPatchSize() -1 < kEtaMinPhos) return false;
760  if(patch.GetColStart() > kEtaMaxPhos) return false;
761  return true;
762 }
void Reset()
Reset all data grids and VZERO-dependent L1 thresholds.
Int_t fBkgThreshold
threshold for the background patches (8x8)
ELevel0TriggerStatus_t CheckForL0(Int_t col, Int_t row) const
Accept trigger patch as Level0 patch.
double Double_t
Definition: External.C:58
Double_t fCellTimeLimits[2]
Maximum allowed abs cell time (default [0] = - 10000, [1] = 10000)
Double_t fMinCellAmplitude
Minimum amplitude in cell required to be considered for filling the data grid.
Bool_t IsGammaPatch(const AliEMCALTriggerRawPatch &patch) const
Check from the bitmask whether the patch is a gamma patch.
void ConfigureForPbPb2015()
Configure the class for 2015 PbPb.
void ConfigureForPP2015()
Configure the class for 2015 pp.
Bool_t IsBkgPatch(const AliEMCALTriggerRawPatch &patch) const
Check from the bitmask whether the patch is a background patch.
char Char_t
Definition: External.C:18
bool HasPHOSOverlap(const AliEMCALTriggerRawPatch &patch) const
AliEMCALTriggerDataGrid< int > * fTriggerBitMap
! Map of trigger bits
void ReadFastORBadChannelFromStream(std::istream &stream)
Read the FastOR bad channel map from a standard stream.
TArrayF fFastORPedestal
FastOR pedestal.
void AddFastORBadChannel(Short_t absId)
Add a FastOR bad channel to the list.
void SetTriggerBitConfig(const AliEMCALTriggerBitConfig *const config)
Set the trigger bit configuration applied for the given data set.
void ConfigureForPbPb2011()
Configure the class for 2011 PbPb.
Bool_t fConfigured
Switch specifying whether the trigger maker kernel has been configured for a given data set...
void Init()
Initialize the trigger maker Kernel.
Int_t fMinCellAmp
Minimum offline amplitude of the cells used to generate the patches.
void CreateTriggerPatches(const AliVEvent *inputevent, std::vector< AliEMCALTriggerPatchInfo > &outputcont, Bool_t useL0amp=kFALSE)
Run patch finders on input data.
void ClearFastORBadChannels()
Clear FastOR bad channel list.
TRandom * gRandom
void ConfigureForPP2011()
Configure the class for 2011 pp.
void ReadFastORBadChannelFromFile(const char *fname)
Read the FastOR bad channel map from a text file.
Bool_t fApplyOnlineBadChannelsToSmeared
Apply online bad channels to smeared energies values.
Bool_t fApplyOnlineBadChannelsToOffline
Apply online bad channels to offline ADC values.
void ReadTriggerData(AliVCaloTrigger *trigger)
Read the calo trigger data.
Int_t fMinL1FastORAmp
Minimum L1 amplitude of the FastORs used to generate the patches.
const AliEMCALTriggerBitConfig * fTriggerBitConfig
Trigger bit configuration, aliroot-dependent.
const AliEMCALGeometry * fGeometry
! Underlying EMCAL geometry
Double_t * sigma
ULong64_t fL1ThresholdsOffline[4]
container for V0-dependent offline thresholds
void ConfigureForPP20158x8()
Configure the class for 2015 pp.
int Int_t
Definition: External.C:63
void ReadOfflineBadChannelFromFile(const char *fname)
Read the offline bad channel map from a text file.
unsigned int UInt_t
Definition: External.C:33
void ConfigureForPP2012()
Configure the class for 2012 pp.
Int_t fThresholdConstants[4][3]
simple offline trigger thresholds constants
float Float_t
Definition: External.C:68
virtual ~AliEmcalTriggerMakerKernel()
Destructor.
double GetTriggerChannelADC(Int_t col, Int_t row) const
Get ADC value of a given trigger channel (in col-row space)
Double_t fSmearThreshold
Smear threshold: Only cell energies above threshold are smeared.
Double_t fADCtoGeV
! Conversion factor from ADC to GeV
void AddL1TriggerAlgorithm(Int_t rowmin, Int_t rowmax, UInt_t bitmask, Int_t patchSize, Int_t subregionSize)
void SetL0TriggerAlgorithm(Int_t rowmin, Int_t rowmax, UInt_t bitmask, Int_t patchSize, Int_t subregionSize)
Set the L0 algorithm.
void ReadOfflineBadChannelFromStream(std::istream &stream)
Read the offline bad channel map from a standard stream.
void SetFastORPedestal(Short_t absId, Float_t ped)
Set the pedestal value for a FastOR.
Bool_t fDoBackgroundSubtraction
Swtich for background subtraction (only online ADC)
unsigned long ULong_t
Definition: External.C:38
void AddOfflineBadChannel(Short_t absId)
Add an offline bad channel to the set.
double GetTriggerChannelEnergy(Int_t col, Int_t row) const
Get energy of the trigger channel estimated from cells (in col-row space)
std::set< Short_t > fBadChannels
Container of bad channels.
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.
short Short_t
Definition: External.C:23
void BuildL1ThresholdsOffline(const AliVVZERO *vzdata)
Build VZERO-dependent thresholds for the offline trigger.
AliEMCALTriggerDataGrid< double > * fPatchADC
! ADC values map
Bool_t isMC
Int_t fMinL0FastORAmp
Minimum L0 amplitude of the FastORs used to generate the patches.
Double_t fRhoValues[kNIndRho]
! Rho values for background subtraction (only online ADC)
std::set< Short_t > fOfflineBadChannels
Abd ID of offline bad channels.
AliEMCALTriggerPatchFinder< double > * fPatchFinder
The actual patch finder.
void ClearOfflineBadChannels()
Clear offline bad channel list.
TFile * file
TList with histograms for a given trigger.
double GetTriggerChannelADCSimple(Int_t col, Int_t row) const
Get ADC value of trigger channel estimated from cell energies.
double GetTriggerChannelEnergyRough(Int_t col, Int_t row) const
Get estimated energy of the trigger channel based on ADC measurement (in col-row space) ...
double GetTriggerChannelEnergySmeared(Int_t col, Int_t row) const
Get (simulated) smeared energy of a trigger channel estimated based on the measured energy from cells...
AliEMCALTriggerDataGrid< double > * fPatchADCSimple
! patch map for simple offline trigger
Kernel of the EMCAL trigger patch maker.
void ReadFastORPedestalFromFile(const char *fname)
Read the FastOR pedestals from a text file.
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
Check from the bitmask whether the patch is a jet patch.
bool Bool_t
Definition: External.C:53
TF1 * fSmearModelMean
Smearing parameterization for the mean.
double GetDataGridDimensionRows() const
Get the dimension of the underlying data grids in row direction.
void ReadFastORPedestalFromStream(std::istream &stream)
Read the FastOR pedestals from a standard stream.
void ReadCellData(AliVCaloCells *cells)
Read the EMCAL cell data.
void ConfigureForPPb2013()
Configure the class for 2013 pPb.
AliEMCALTriggerDataGrid< double > * fPatchEnergySimpleSmeared
! Data grid for smeared energy values from cell energies
Double_t fScaleShift
Scale shift simulation.
double GetL0TriggerChannelAmplitude(Int_t col, Int_t row) const
Get L0 amplitude of a given trigger channel (in col-row space)
TF1 * fSmearModelSigma
Smearing parameterization for the width.
const Double_t kEMCL0ADCtoGeV_AP