AliPhysics  608b256 (608b256)
AliAnalysisTaskEmcalRecalcPatchesRef.cxx
Go to the documentation of this file.
1 /************************************************************************************
2  * Copyright (C) 2017, Copyright Holders of the ALICE Collaboration *
3  * All rights reserved. *
4  * *
5  * Redistribution and use in source and binary forms, with or without *
6  * modification, are permitted provided that the following conditions are met: *
7  * * Redistributions of source code must retain the above copyright *
8  * notice, this list of conditions and the following disclaimer. *
9  * * Redistributions in binary form must reproduce the above copyright *
10  * notice, this list of conditions and the following disclaimer in the *
11  * documentation and/or other materials provided with the distribution. *
12  * * Neither the name of the <organization> nor the *
13  * names of its contributors may be used to endorse or promote products *
14  * derived from this software without specific prior written permission. *
15  * *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND *
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
19  * DISCLAIMED. IN NO EVENT SHALL ALICE COLLABORATION BE LIABLE FOR ANY *
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
26  ************************************************************************************/
27 #include <algorithm>
28 #include <array>
29 #include <iostream>
30 #include <unordered_map>
31 #include <sstream>
32 #include <string>
33 #include <TClonesArray.h>
34 #include <THistManager.h>
35 #include <TLinearBinning.h>
36 #include <TList.h>
37 #include <TObjString.h>
38 #include <TString.h>
39 #include "AliAnalysisManager.h"
40 #include "AliEMCALTriggerPatchInfo.h"
42 #include "AliMultSelection.h"
43 #include "AliMultEstimator.h"
45 
47 
48 using namespace EMCalTriggerPtAnalysis;
49 
52  fEnableSumw2(false),
53  fOnlineThresholds(),
54  fSwapPatches(false),
55  fRequiredOverlaps(),
56  fExcludedOverlaps(),
57  fCentralityRange(-999., 999.),
58  fUseRecalcPatches(false),
59  fRequestCentrality(false),
60  fEventCentrality(0)
61 {
62  SetCaloTriggerPatchInfoName("EmcalTriggers");
63 }
64 
67  fEnableSumw2(false),
69  fSwapPatches(false),
72  fCentralityRange(-999., 999.),
73  fUseRecalcPatches(false),
74  fRequestCentrality(false),
76 {
77  SetCaloTriggerPatchInfoName("EmcalTriggers");
78  fOnlineThresholds.Set(8);
79 }
80 
82  const std::array<std::string, 9> kNamesTriggerClasses = {{"MB", "EG1", "EG2", "DG1", "DG2", "EJ1", "EJ2", "DJ1", "DJ2"}};
83  const std::array<std::string, 6> kNamesTriggerClusters = {{"ANY", "CENT", "CENTNOTRD", "BOTH", "ONLYCENT", "ONLYCENTNOTRD"}};
84  const std::array<std::string, 4> kNamesPatchTypes = {{"EGA", "DGA", "EJE", "DJE"}};
85 
86  TLinearBinning ADCBinning(2000, 0., 2000.), colbinning(48, -0.5, 47.5), rowbinning(104, -0.5, 103.5), npatchbinning(51, -0.5, 50.5), noverlapbinning(21, -0.5, 20.5);
87  const TBinning *firedpatchbinning[5] = {&ADCBinning, &colbinning, &rowbinning, &npatchbinning, &noverlapbinning},
88  *allpatchbinning[3] = {&ADCBinning, &npatchbinning, &noverlapbinning};
89  // Create event counters
90  for(const auto &kt : kNamesTriggerClasses){
91  // Min. Bias: Only CENT cluster - no distinction between trigger clusters
92  // EMCAL triggers: Distinction between CENT and CENTNOTRD necessary
93  if(kt.find("MB") != std::string::npos)
94  fHistos->CreateTH1(Form("hEventCounter%s", kt.data()), Form("Event counter for %s", kt.data()), 1, 0.5, 1.5);
95  else {
96  for(const auto &kc : kNamesTriggerClusters) {
97  fHistos->CreateTH1(Form("hEventCounter%s%s", kt.data(), kc.data()), Form("Event counter for %s in cluster %s", kt.data(), kc.data()), 1, 0.5, 1.5);
98  }
99  }
100  }
101 
102  // Min. Bias: Create patch energy spectra (all patches) for EMCAL and DCAL
103  // Min. Bias trigger only in CENT cluster
104  for(const auto &kp : kNamesPatchTypes) fHistos->CreateTH1(Form("hPatchADC%sMB", kp.data()), Form("Patch ADC spectra for %s patches in MB events", kp.data()), 2000, 0., 2000., fEnableSumw2 ? "s" : "");
105 
106  // Triggers: Create trigger spectra and THnSparse of firing patches
107  for(const auto &kt : kNamesTriggerClasses) {
108  if(kt == "MB") continue;
109  const char detector = kt[0];
110  const char *patchtype = ((kt[1] == 'G') ? "GA" : "JE");
111  // distinction between trigger clusters
112  for(const auto &kc : kNamesTriggerClusters){
113  fHistos->CreateTH1(Form("hPatchADC%c%s%s%s", detector, patchtype, kt.data(), kc.data()), Form("Patch ADC spectra for %c%s patches in %s events (cluster %s)", detector, patchtype, kt.data(), kc.data()), 2000, 0., 2000., fEnableSumw2 ? "s" : "");
114  fHistos->CreateTHnSparse(Form("hFiredPatches%c%s%s%s", detector, patchtype, kt.data(), kc.data()), Form("Fired %c%s patches for trigger %s (cluster %s)", detector, patchtype, kt.data(), kc.data()), 5, firedpatchbinning, fEnableSumw2 ? "s" : "");
115  fHistos->CreateTHnSparse(Form("hAllPatches%c%s%s%s", detector, patchtype, kt.data(), kc.data()), Form("Fired %c%s patches for trigger %s (cluster %s)", detector, patchtype, kt.data(), kc.data()), 3, allpatchbinning, fEnableSumw2 ? "s" : "");
116  }
117  }
118 }
119 
121 
122  fEventCentrality = -1;
123  if(fRequestCentrality){
124  AliMultSelection *mult = dynamic_cast<AliMultSelection *>(InputEvent()->FindListObject("MultSelection"));
125  if(!mult){
126  AliErrorStream() << GetName() << ": Centrality selection enabled but no centrality estimator found" << std::endl;
127  return false;
128  }
129  if(mult->IsEventSelected()) return false;
130  fEventCentrality = mult->GetEstimator("V0M")->GetPercentile();
131  AliDebugStream(1) << GetName() << ": Centrality " << fEventCentrality << std::endl;
133  AliDebugStream(1) << GetName() << ": reject centrality: " << fEventCentrality << std::endl;
134  return false;
135  } else {
136  AliDebugStream(1) << GetName() << ": select centrality " << fEventCentrality << std::endl;
137  }
138  } else {
139  AliDebugStream(1) << GetName() << ": No centrality selection applied" << std::endl;
140  }
141 
142  // handle overlaps
143  if(fRequiredOverlaps.GetEntries() || fExcludedOverlaps.GetEntries()){
144  if(fRequiredOverlaps.GetEntries()){
145  Bool_t allFound(true);
146  for(auto t : fRequiredOverlaps){
147  auto trgstr = static_cast<TObjString *>(t)->String();
148  if(std::find_if(fSelectedTriggers.begin(), fSelectedTriggers.end(), [&trgstr](const TString &seltrigger) -> bool { return seltrigger.Contains(trgstr); }) == fSelectedTriggers.end()) {
149  allFound = false;
150  break;
151  }
152  }
153  if(!allFound) return false;
154  }
155 
156  if(fExcludedOverlaps.GetEntries()){
157  Bool_t oneFound(false);
158  for(auto t : fExcludedOverlaps){
159  auto trgstr = static_cast<TObjString *>(t)->String();
160  if(std::find_if(fSelectedTriggers.begin(), fSelectedTriggers.end(), [&trgstr](const TString &seltrigger) -> bool { return seltrigger.Contains(trgstr); }) != fSelectedTriggers.end()) {
161  oneFound = true;
162  break;
163  }
164  }
165  if(oneFound) return false;
166  }
167  }
168  return true;
169 }
170 
172  const std::array<std::string, 9> kNamesTriggerClasses = {{"MB", "EG1", "EG2", "DG1", "DG2", "EJ1", "EJ2", "DJ1", "DJ2"}};
173  const auto selclusters = GetAcceptedTriggerClusters(fInputEvent->GetFiredTriggerClasses().Data());
174 
175  auto findTriggerType = [](const std::vector<TString> &triggers, TString type) -> bool {
176  bool found = false;
177  for(const auto t : triggers) {
178  if(t.Contains(type)) {
179  found = true;
180  break;
181  }
182  }
183  return found;
184  };
185 
186  std::vector<TString> handledtriggers;
187  for(auto t : kNamesTriggerClasses) {
188  if(findTriggerType(fSelectedTriggers, t.data())){
189  handledtriggers.emplace_back(t);
190  }
191  }
192 
193  for(const auto &kt : handledtriggers) {
194  if(kt == "MB") fHistos->FillTH1(Form("hEventCounter%s", kt.Data()), 1.);
195  else {
196  for(const auto &kc : selclusters) fHistos->FillTH1(Form("hEventCounter%s%s", kt.Data(), kc.data()), 1.);
197  }
198  }
199 }
200 
202  const std::array<std::string, 9> kNamesTriggerClasses = {{"MB", "EG1", "EG2", "DG1", "DG2", "EJ1", "EJ2", "DJ1", "DJ2"}};
203  const std::unordered_map<std::string, ETriggerThreshold_t> kPatchIndex = {{"EG1", kThresholdEG1},{"EG2", kThresholdEG2},{"DG1", kThresholdDG1},{"DG2", kThresholdDG2},
204  {"EJ1", kThresholdEJ1},{"EJ2", kThresholdEJ2},{"DJ1", kThresholdDJ1},{"DJ2", kThresholdDJ2}};
205  if(!fSelectedTriggers.size()) return false; // no trigger selected
206  AliDebugStream(1) << "Found triggers" << std::endl;
207  for(auto t : fSelectedTriggers) AliDebugStream(1) << t << std::endl;
208  AliDebugStream(1) << "Trigger patch container has " << fTriggerPatchInfo->GetEntries() << " patches" << std::endl;
209 
210  // Decode trigger clusters
211  const auto selclusters = GetAcceptedTriggerClusters(fInputEvent->GetFiredTriggerClasses().Data());
212 
213  auto findTriggerType = [](const std::vector<TString> &triggers, TString type) -> bool {
214  bool found = false;
215  for(const auto t : triggers) {
216  if(t.Contains(type)) {
217  found = true;
218  break;
219  }
220  }
221  return found;
222  };
223  bool isMB = std::find(fSelectedTriggers.begin(), fSelectedTriggers.end(), "MB") != fSelectedTriggers.end(),
224  isEG = findTriggerType(fSelectedTriggers, "EG"),
225  isDG = findTriggerType(fSelectedTriggers, "DG"),
226  isEJ = findTriggerType(fSelectedTriggers, "EJ"),
227  isDJ = findTriggerType(fSelectedTriggers, "DJ");
228 
229  std::vector<TString> handledtriggers;
230  for(auto t : kNamesTriggerClasses) {
231  if(findTriggerType(fSelectedTriggers, t.data())){
232  handledtriggers.emplace_back(t);
233  }
234  }
235 
236  AliDebugStream(1) << "Processing triggers" << std::endl;
237  for(auto t : handledtriggers) AliDebugStream(1) << t << std::endl;
238  if(!handledtriggers.size()){
239  AliDebugStream(1) << "No supported trigger class found " << std::endl;
240  return false;
241  }
242 
243  std::vector<const AliEMCALTriggerPatchInfo *> EGApatches, DGApatches, EJEpatches, DJEpatches;
244  if(isMB || isEG) EGApatches = SelectAllPatchesByType(*fTriggerPatchInfo, fSwapPatches ? kEJEpatches : kEGApatches);
245  if(isMB || isDG) DGApatches = SelectAllPatchesByType(*fTriggerPatchInfo, fSwapPatches ? kDJEpatches : kDGApatches);
246  if(isMB || isEJ) EJEpatches = SelectAllPatchesByType(*fTriggerPatchInfo, fSwapPatches ? kEGApatches : kEJEpatches);
247  if(isMB || isDJ) DJEpatches = SelectAllPatchesByType(*fTriggerPatchInfo, fSwapPatches ? kDGApatches : kDJEpatches);
248 
249  for(const auto &t : handledtriggers) {
250  if(t == "MB") {
251  // Min bias: Only fill patch ADC spectra all patches
252  for(auto patch : EGApatches) fHistos->FillTH1("hPatchADCEGAMB", patch->GetADCAmp());
253  for(auto patch : DGApatches) fHistos->FillTH1("hPatchADCDGAMB", patch->GetADCAmp());
254  for(auto patch : EJEpatches) fHistos->FillTH1("hPatchADCEJEMB", patch->GetADCAmp());
255  for(auto patch : DJEpatches) fHistos->FillTH1("hPatchADCDJEMB", patch->GetADCAmp());
256  } else {
257  const char detector = t[0];
258  const char *patchtype = ((t[1] == 'G') ? "GA" : "JE");
259  std::vector<const AliEMCALTriggerPatchInfo *> &patchhandler = (detector == 'E' ? (t[1] == 'G' ? EGApatches : EJEpatches) : (t[1] == 'G' ? DGApatches : DJEpatches));
260  auto firedpatches = SelectFiredPatchesByTrigger(*fTriggerPatchInfo, kPatchIndex.find(t.Data())->second);
261  auto patchareas = GetNumberNonOverlappingPatchAreas(firedpatches);
262  AliDebugStream(3) << "Trigger " << t << ", patches " << patchhandler.size() << ", firing " << firedpatches.size() << std::endl;
263  for(auto p : patchhandler){
264  double point[3] = {static_cast<double>(p->GetADCAmp()), static_cast<double>(firedpatches.size()), static_cast<double>(patchareas)};
265  for(const auto &kc : selclusters) {
266  fHistos->FillTH1(Form("hPatchADC%c%s%s%s", detector, patchtype, t.Data(), kc.data()), p->GetADCAmp());
267  fHistos->FillTHnSparse(Form("hAllPatches%c%s%s%s", detector, patchtype, t.Data(), kc.data()), point);
268  }
269  }
270  for(auto p : firedpatches) {
271  double point[5] = {static_cast<double>(p->GetADCAmp()), static_cast<double>(p->GetColStart()), static_cast<double>(p->GetRowStart()), static_cast<double>(firedpatches.size()), static_cast<double>(patchareas)};
272  for(const auto &kc : selclusters)
273  fHistos->FillTHnSparse(Form("hFiredPatches%c%s%s%s", detector, patchtype, t.Data(), kc.data()), point);
274  }
275  }
276  }
277  return true;
278 }
279 
280 std::vector<const AliEMCALTriggerPatchInfo *> AliAnalysisTaskEmcalRecalcPatchesRef::SelectAllPatchesByType(const TClonesArray &list, EPatchType_t patchtype) const {
281  AliDebugStream(2) << "Selecting all patches for trigger " << static_cast<int>(patchtype) << std::endl;
282  std::vector<const AliEMCALTriggerPatchInfo *> result;
283  for(auto p : list){
284  AliEMCALTriggerPatchInfo *patch = static_cast<AliEMCALTriggerPatchInfo *>(p);
285  if(!patch->IsRecalc()) continue;
286  bool selected(true);
287  switch(patchtype){
288  case kEGApatches: if(patch->IsDCalPHOS() || !patch->IsGammaHighRecalc()) selected = false; break;
289  case kDGApatches: if(patch->IsEMCal() || !patch->IsGammaHighRecalc()) selected = false; break;
290  case kEJEpatches: if(patch->IsDCalPHOS() || !patch->IsJetHighRecalc()) selected = false; break;
291  case kDJEpatches: if(patch->IsEMCal() || !patch->IsJetHighRecalc()) selected = false; break;
292  };
293  if(selected) result.emplace_back(patch);
294  }
295  AliDebugStream(2) << "In: " << list.GetEntries() << ", out: " << result.size() << std::endl;
296  return result;
297 }
298 
299 std::vector<const AliEMCALTriggerPatchInfo *> AliAnalysisTaskEmcalRecalcPatchesRef::SelectFiredPatchesByTrigger(const TClonesArray &list, ETriggerThreshold_t trigger) const {
300  std::vector<const AliEMCALTriggerPatchInfo *> result;
301  EPatchType_t patchtype;
302  switch(trigger) {
303  case kThresholdEG1: patchtype = kEGApatches; break;
304  case kThresholdEG2: patchtype = kEGApatches; break;
305  case kThresholdDG1: patchtype = kDGApatches; break;
306  case kThresholdDG2: patchtype = kDGApatches; break;
307  case kThresholdEJ1: patchtype = kEJEpatches; break;
308  case kThresholdEJ2: patchtype = kEJEpatches; break;
309  case kThresholdDJ1: patchtype = kDJEpatches; break;
310  case kThresholdDJ2: patchtype = kDJEpatches; break;
311  default: return result; // unsupported patch type - return empty list
312  };
313  for(auto patch : SelectAllPatchesByType(list, patchtype)) {
314  if(patch->GetADCAmp() > fOnlineThresholds[trigger]) result.emplace_back(patch);
315  }
316  return result;
317 }
318 
319 std::vector<std::string> AliAnalysisTaskEmcalRecalcPatchesRef::GetAcceptedTriggerClusters(const char *triggerstring) const {
320  auto clusters = PWG::EMCAL::Triggerinfo::DecodeTriggerString(triggerstring);
321  std::vector<std::string> selclusters;
322  selclusters.push_back("ANY");
323  bool isCENT(false), isCENTNOTRD(false);
324  for(const auto &c : clusters){
325  if((c.Triggercluster() == "CENT") && !isCENT) { // don't count clusters multiple times
326  selclusters.push_back("CENT");
327  isCENT = true;
328  } else if((c.Triggercluster() == "CENTNOTRD") && !isCENTNOTRD) { // don't count clusters multiple times
329  selclusters.push_back("CENTNOTRD");
330  isCENTNOTRD = true;
331  }
332  }
333  if(isCENT && isCENTNOTRD) selclusters.push_back("BOTH");
334  else {
335  if(isCENT) selclusters.push_back("ONLYCENT");
336  if(isCENTNOTRD) selclusters.push_back("ONLYCENTNOTRD");
337  }
338  return selclusters;
339 }
340 
341 int AliAnalysisTaskEmcalRecalcPatchesRef::GetNumberNonOverlappingPatchAreas(const std::vector<const AliEMCALTriggerPatchInfo *> &firedpatches) const {
342  std::vector<const AliEMCALTriggerPatchInfo *> patchareas;
343  for(const auto patch : firedpatches) {
344  if(!patchareas.size()) patchareas.push_back(patch); // first patch always considered as new area
345  else {
346  bool overlapFound = false;
347  for(const auto refpatch : patchareas) {
348  if(!refpatch) {
349  AliErrorStream() << "Ref patch null" << std::endl;
350  AliErrorStream() << "Patchareas has size " << patchareas.size() << std::endl;
351  AliErrorStream() << "Firedpatches has size " << firedpatches.size() << std::endl;
352  }
353  if(!patch){
354  AliErrorStream() << "Test patch null" << std::endl;
355  AliErrorStream() << "Patchareas has size " << patchareas.size() << std::endl;
356  AliErrorStream() << "Firedpatches has size " << firedpatches.size() << std::endl;
357  }
358  if(HasOverlap(*refpatch, *patch)) {
359  // patch has overlap with allready accepted patch - discard
360  overlapFound = true;
361  break;
362  }
363  }
364  if(!overlapFound) patchareas.emplace_back(patch); // New non-overlapping patch found
365  }
366  }
367  return patchareas.size();
368 }
369 
370 bool AliAnalysisTaskEmcalRecalcPatchesRef::HasOverlap(const AliEMCALTriggerPatchInfo &ref, const AliEMCALTriggerPatchInfo &test) const {
371  int testcolmin = test.GetColStart(), testcolmax = test.GetColStart()+test.GetPatchSize()-1,
372  testrowmin = test.GetRowStart(), testrowmax = test.GetRowStart()+test.GetPatchSize()-1,
373  refcolmin = ref.GetColStart(), refcolmax = ref.GetColStart()+ref.GetPatchSize()-1,
374  refrowmin = ref.GetRowStart(), refrowmax = ref.GetRowStart()+ref.GetPatchSize()-1;
375  if((InRange(testcolmin, refcolmin, refcolmax) && InRange(testrowmin, refrowmin, refrowmax)) ||
376  (InRange(testcolmax, refcolmin, refcolmax) && InRange(testrowmax, refrowmin, refrowmax))) return true;
377  return false;
378 }
379 
381  if(fRequiredOverlaps.FindObject(trigger)) return;
382  fRequiredOverlaps.Add(new TObjString(trigger));
383 }
384 
386  if(fExcludedOverlaps.FindObject(trigger)) return;
387  fExcludedOverlaps.Add(new TObjString(trigger));
388 }
389 
391  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
392  if(!mgr){
393  std::cerr << "No analysis manager defined" << std::endl;
394  return nullptr;
395  }
396 
397  std::stringstream taskname;
398  taskname << "EmcalRecalcPatches_" << suffix;
400  mgr->AddTask(task);
401  task->SetEnableSumw2(true);
402 
411 
412  std::stringstream outfilename, outlistname;
413  outfilename << mgr->GetCommonFileName() << ":" << taskname.str();
414  outlistname << "Histos_" << taskname.str();
415  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
416  mgr->ConnectOutput(task, 1, mgr->CreateContainer(outlistname.str().data(), TList::Class(), AliAnalysisManager::kOutputContainer, outfilename.str().data()));
417 
418  return task;
419 }
std::vector< TString > fSelectedTriggers
! Triggers selected for given event
bool HasOverlap(const AliEMCALTriggerPatchInfo &ref, const AliEMCALTriggerPatchInfo &test) const
Class creating a linear binning, used in the histogram manager.
TCanvas * c
Definition: TestFitELoss.C:172
Interface for binnings used by the histogram handler.
Definition: TBinning.h:23
static std::vector< PWG::EMCAL::Triggerinfo > DecodeTriggerString(const std::string &triggerstring)
Decoding trigger string.
void SetCaloTriggerPatchInfoName(const char *n)
AliCutValueRange< double > fCentralityRange
Range of accepted event centralities.
TObjArray fRequiredOverlaps
Add option to require overlap with certain triggers.
void FillTHnSparse(const char *name, const double *x, double weight=1., Option_t *opt="")
Bool_t fUseRecalcPatches
Switch between offline (FEE) and recalc (L1) patches.
static AliAnalysisTaskEmcalRecalcPatchesRef * AddTaskEmcalRecalcPatches(const char *suffix)
std::vector< const AliEMCALTriggerPatchInfo * > SelectFiredPatchesByTrigger(const TClonesArray &patches, ETriggerThreshold_t trigger) const
TH1 * CreateTH1(const char *name, const char *title, int nbins, double xmin, double xmax, Option_t *opt="")
Create a new TH1 within the container.
int GetNumberNonOverlappingPatchAreas(const std::vector< const AliEMCALTriggerPatchInfo * > &diredpatches) const
void FillTH1(const char *hname, double x, double weight=1., Option_t *opt="")
Fill a 1D histogram within the container.
virtual bool Run()
Run function. This is the core function of the analysis and contains the user code. Therefore users have to implement this function.
TObjArray fExcludedOverlaps
Add option to exclude overlap with certain triggers.
std::vector< std::string > GetAcceptedTriggerClusters(const char *triggerstring) const
Analysis of high- tracks in triggered events.
TClonesArray * fTriggerPatchInfo
!trigger patch info array
void test(int runnumber=195345)
bool Bool_t
Definition: External.C:53
THnSparse * CreateTHnSparse(const char *name, const char *title, int ndim, const int *nbins, const double *min, const double *max, Option_t *opt="")
Create a new THnSparse within the container.
std::vector< const AliEMCALTriggerPatchInfo * > SelectAllPatchesByType(const TClonesArray &patches, EPatchType_t patchtype) const