AliPhysics  2b88e80 (2b88e80)
AliAnalysisTaskEmcalTriggerBase.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2016, 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 <algorithm>
16 #include <array>
17 #include <cfloat>
18 #include <functional>
19 #include <iostream>
20 #include <memory>
21 #include <sstream>
22 
23 #include <TClonesArray.h>
24 #include <TGrid.h>
25 #include <THistManager.h>
26 #include <TObjArray.h>
27 #include <TObjString.h>
28 #include <TParameter.h>
29 
31 #include "AliAnalysisUtils.h"
32 #include "AliAODEvent.h"
33 #include "AliAODInputHandler.h"
36 #include "AliEMCALGeometry.h"
37 #include "AliEMCALTriggerPatchInfo.h"
38 #include "AliEMCALTriggerMapping.h"
41 #include "AliESDEvent.h"
42 #include "AliInputEventHandler.h"
43 #include "AliLog.h"
44 #include "AliOADBContainer.h"
45 #include "AliVVertex.h"
46 
50 
51 namespace EMCalTriggerPtAnalysis {
52 
53 AliAnalysisTaskEmcalTriggerBase::AliAnalysisTaskEmcalTriggerBase():
55  fHistos(nullptr),
56  fUseTriggerBits(kTRUE),
57  fRequireBunchCrossing(kTRUE),
58  fUseDownscaleCorrectionFormOCDB(kFALSE),
59  fTriggerSelection(nullptr),
60  fSelectedTriggers(),
61  fNameClusterContainer(""),
62  fRequireAnalysisUtils(kTRUE),
63  fUseSPDVertex(false),
64  fApplyVertexCuts(true),
65  fVertexCut(-10., 10.),
66  fNameDownscaleOADB(""),
67  fDownscaleOADB(nullptr),
68  fDownscaleFactors(nullptr),
69  fNameTriggerSelectionContainer("EmcalTriggerDecision"),
70  fEnableDCALTriggers(true),
71  fEnableV0Triggers(true),
72  fEnableT0Triggers(false),
73  fEnableNoINTTriggers(false),
74  fEnableCentralityTriggers(false),
75  fExclusiveMinBias(false),
76  fUseTriggerSelectionContainer(false)
77 {
78  SetNeedEmcalGeom(true);
80 }
81 
83  AliAnalysisTaskEmcal(name, true),
85  fUseTriggerBits(kTRUE),
86  fRequireBunchCrossing(kTRUE),
91  fRequireAnalysisUtils(kTRUE),
92  fUseSPDVertex(false),
93  fApplyVertexCuts(true),
94  fVertexCut(-10., 10.),
98  fNameTriggerSelectionContainer("EmcalTriggerDecision"),
99  fEnableDCALTriggers(true),
100  fEnableV0Triggers(true),
101  fEnableT0Triggers(false),
102  fEnableNoINTTriggers(false),
104  fExclusiveMinBias(false),
106 {
107  SetNeedEmcalGeom(true);
109 }
110 
113  if(fHistos) delete fHistos;
115 }
116 
119  if(fRequireAnalysisUtils && !fAliAnalysisUtils) fAliAnalysisUtils = new AliAnalysisUtils;
120 
121  if((!fNameClusterContainer.Length()) || fNameClusterContainer == "usedefault") fNameClusterContainer = AliEmcalAnalysisFactory::ClusterContainerNameFactory(fInputHandler->IsA() == AliAODInputHandler::Class());
124  }
125 
126  fHistos = new THistManager(Form("Histos_%s", GetName()));
127 
128  // Create trigger correlation histogram
129  std::vector<std::string> binlabels = {"MB"};
130  if(fEnableV0Triggers){
131  const std::array<const std::string, 5> vzlabels = {{"EMC7", "EG1", "EG2", "EJ1", "EJ2"}};
132  for(const auto & vlab : vzlabels) binlabels.emplace_back(vlab);
134  const std::array<const std::string, 5> dclabels = {{"DMC7", "DG1", "DG2", "DJ1", "DJ2"}};
135  for(const auto & dlab : dclabels) binlabels.emplace_back(dlab);
136  }
137  }
138  if(fEnableT0Triggers) {
139  binlabels.emplace_back("MBT0");
140  const std::array<const std::string, 5> t0labels = {{"EMC8", "EMC8EG1", "EMC8EG2", "EMC8EJ1", "EMC8EJ2"}};
141  for(const auto & tlab : t0labels) binlabels.emplace_back(tlab);
143  const std::array<const std::string, 5> dtclabels = {{"DMC8", "DMC8DG1", "DMC8DG2", "DMC8DJ1", "DMC8DJ2"}};
144  for(const auto & dtlab : dtclabels) binlabels.emplace_back(dtlab);
145  }
146  }
147  fHistos->CreateTH2("hTriggerCorrelation", "Correlation selected trigger classes", binlabels.size(), -0.5, binlabels.size() - 0.5, binlabels.size(), -0.5, binlabels.size() - 0.5);
148  TH1 *correlationHist = static_cast<TH1 *>(fHistos->FindObject("hTriggerCorrelation"));
149  for(decltype(binlabels.size()) ib = 0; ib < binlabels.size(); ib++){
150  correlationHist->GetXaxis()->SetBinLabel(ib+1, binlabels[ib].data());
151  correlationHist->GetYaxis()->SetBinLabel(ib+1, binlabels[ib].data());
152  }
153 
156 
157  for(auto h : *(fHistos->GetListOfHistograms())) fOutput->Add(h);
158  fHistos->GetListOfHistograms()->SetOwner(false);
159 
160  PostData(1, fOutput);
161 }
162 
164  // Apply trigger selection
166  if(!fSelectedTriggers.size()) {
167  AliDebugStream(1) << "Failed trigger selection" << std::endl;
168  return false;
169  }
170 
172 
173  if(fApplyVertexCuts){
174  const AliVVertex *vtx = fUseSPDVertex ? fInputEvent->GetPrimaryVertexSPD() : fInputEvent->GetPrimaryVertex();
175  //if(!fInputEvent->IsPileupFromSPD(3, 0.8, 3., 2., 5.)) return; // reject pileup event
176  if(vtx->GetNContributors() < 1) {
177  AliDebugStream(1) << "Failed Vertex Selection" << std::endl;
178  return false;
179  }
181  AliDebugStream(1) << "Failed vertex-z cut" << std::endl;
182  return false;
183  }
184  }
185 
187  AliDebugStream(1) << "Checking cuts in AliAnalysisUtils" << std::endl;
188  if(fInputEvent->IsA() == AliESDEvent::Class() && fAliAnalysisUtils->IsFirstEventInChunk(fInputEvent)) return false;
189  if(fAliAnalysisUtils->IsPileUpEvent(fInputEvent)) return false; // Apply new vertex cut
190  if(!fAliAnalysisUtils->IsVertexSelected2013pA(fInputEvent))return false; // Apply new vertex cut
191  }
192 
193  if(!IsUserEventSelected()) {
194  AliDebugStream(1) << "Failed user extra cuts" << std::endl;
195  return false;
196  }
197 
198  // Do MC outlier cut
199  if(fIsPythia){
200  if(!CheckMCOutliers()){
201  AliDebugStream(1) << GetName() << ": Reject MC outliers" << std::endl;
202  return false;
203  }
204  }
205 
206  // Fill histogram with trigger correlation
207  // self-correlations included
208  auto *corrhist = static_cast<TH2 *>(fHistos->GetListOfHistograms()->FindObject("hTriggerCorrelation"));
209  for(int itrg = 0; itrg < corrhist->GetXaxis()->GetNbins(); itrg++){
210  const char *xlabel = corrhist->GetXaxis()->GetBinLabel(itrg+1);
211  bool hasTriggerA = (std::find(fSelectedTriggers.begin(), fSelectedTriggers.end(), xlabel) != fSelectedTriggers.end());
212  if(hasTriggerA) {
213  for(int jtrg = 0; jtrg < corrhist->GetYaxis()->GetNbins(); jtrg++){
214  const char *ylabel = corrhist->GetYaxis()->GetBinLabel(jtrg+1);
215  bool hasTriggerB = (std::find(fSelectedTriggers.begin(), fSelectedTriggers.end(), ylabel) != fSelectedTriggers.end());
216  if(hasTriggerB) fHistos->FillTH2("hTriggerCorrelation", xlabel, ylabel);
217  }
218  }
219  }
220 
222  AliDebugStream(1) << "Event is selected" << std::endl;
223  return true;
224 }
225 
226 
228  AliDebugStream(1) << "Entering trigger selection\n";
229  fSelectedTriggers.clear();
230  Bool_t isMC = MCEvent() != nullptr;
231 
232  UInt_t selectionstatus = fInputHandler->IsEventSelected();
233  Bool_t isMinBias = selectionstatus & AliVEvent::kINT7,
234  isMinBiasT0 = selectionstatus & AliVEvent::kINT8,
235  isCENT = selectionstatus & AliVEvent::kCentral,
236  isSemiCENT = selectionstatus & AliVEvent::kSemiCentral,
239  emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgn];
240 
241  if(fExclusiveMinBias){
242  AliDebugStream(1) << "Min bias mode\n";
243  // do not perform EMCAL trigger selection in case only
244  // min. bias trigger is requested:w
245  if(isMinBias) fSelectedTriggers.push_back("MB");
246  if(isMinBiasT0 && fEnableT0Triggers) fSelectedTriggers.push_back("MBT0");
248  if(isCENT) fSelectedTriggers.push_back("CENT");
249  if(isSemiCENT) fSelectedTriggers.push_back("SEMICENT");
250  }
251  return;
252  }
253 
256  triggersel = dynamic_cast<PWG::EMCAL::AliEmcalTriggerDecisionContainer *>(fInputEvent->GetList()->FindObject(fNameTriggerSelectionContainer.Data()));
257  if(!triggersel) {
258  AliErrorStream() << "Trigger selection container requested but not found - not possible to select EMCAL triggers" << std::endl;
259  return;
260  }
261  }
262 
263  AliDebugStream(1) << "Found triggers " << fInputEvent->GetFiredTriggerClasses() << std::endl;
264 
265  for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++) emcalTriggers[itrg] = true;
266  if(fEnableT0Triggers) for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++) emc8Triggers[itrg] = true;
267  if(fEnableNoINTTriggers) for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++) emcNoIntTriggers[itrg] = true;
268  const std::array<std::string, AliEmcalTriggerOfflineSelection::kTrgn> kEmcalSelectTriggerStrings = {
269  "=CEMC7|CEMC8|C0EMC", "EG1|EGA", "EG2", "EJ1|EJE", "EJ2", "=CDMC7|CDMC8|C0DMC", "DG1", "DG2", "DJ1", "DJ2"
270  };
271  if(!isMC){
272  // In case of data select events as bunch-bunch (-B-) events.
273  // Cut not applied in simulations
274  if(fRequireBunchCrossing && ! (fInputEvent->GetFiredTriggerClasses().Contains("-B-") || fInputEvent->GetFiredTriggerClasses().Contains("-S-"))) return;
275 
276  // In case of data use information from the physics selection and event record
277  // Further cleanup of trigger events can be performed depending on the presence
278  // of recalc patches (after masking hot fastors in the trigger maker) above
279  // threshold
280  if(fUseTriggerBits){
281  AliDebugStream(1) << "Require trigger bits" << std::endl;
282  const std::array<ULong_t, AliEmcalTriggerOfflineSelection::kTrgn> kSelectTriggerBits = {
283  AliVEvent::kEMC7|AliVEvent::kEMC8, AliVEvent::kEMCEGA, AliVEvent::kEMCEGA, AliVEvent::kEMCEJE, AliVEvent::kEMCEJE,
284  AliVEvent::kEMC7|AliVEvent::kEMC8, AliVEvent::kEMCEGA, AliVEvent::kEMCEGA, AliVEvent::kEMCEJE, AliVEvent::kEMCEJE
285  };
286  for(int iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
287  if(!(selectionstatus & kSelectTriggerBits[iclass])) {
288  emcNoIntTriggers[iclass] = emc8Triggers[iclass] = emcalTriggers[iclass] = false;
289  }
290  }
291  }
292 
293  if(fInputEvent->GetFiredTriggerClasses().Contains("EMC") || fInputEvent->GetFiredTriggerClasses().Contains("DMC")){
294  // Apply cut on the trigger string - this basically discriminates high- and low-threshold
295  // triggers
296  auto triggers = PWG::EMCAL::Triggerinfo::DecodeTriggerString(fInputEvent->GetFiredTriggerClasses().Data());
297  std::map<int, std::array<bool, 3>> matchedTriggers;
298  for(auto t : triggers) {
299  const auto &triggerclass = t.Triggerclass();
300  if((triggerclass.find("EMC") != std::string::npos) || (triggerclass.find("DMC") != std::string::npos))
301  AliDebugStream(1) << GetName() << ": Trigger string " << t.ExpandClassName() << std::endl;
302  else continue; // No EMC / DMC trigger - not to be checked
303  bool isT0trigger = (triggerclass.find("EMC8") != std::string::npos) || (triggerclass.find("DMC8") != std::string::npos),
304  isVZEROtrigger = (triggerclass.find("EMC7") != std::string::npos) || (triggerclass.find("DMC7") != std::string::npos);
305  for(auto iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
306  AliDebugStream(1) << "Next trigger: " << kEmcalSelectTriggerStrings[iclass] << std::endl;
307  bool emcalSelectionStatus = MatchTriggerFromPattern(kEmcalSelectTriggerStrings[iclass], triggerclass);
308  if(fUseTriggerSelectionContainer) emcalSelectionStatus = emcalSelectionStatus & MatchTriggerFromContainer(kEmcalSelectTriggerStrings[iclass], triggersel);
309  if(emcalSelectionStatus) {
310  auto entry = matchedTriggers.find(iclass);
311  if(entry == matchedTriggers.end()) {
312  std::array<bool, 3> interactions = {{isVZEROtrigger, isT0trigger, !(isVZEROtrigger || isT0trigger)}};
313  matchedTriggers.insert(std::pair<int, std::array<bool, 3>>(iclass, interactions));
314  } else {
315  auto &interactions = entry->second;
316  if(isVZEROtrigger) interactions[0] = true;
317  if(isT0trigger) interactions[1] = true;
318  if(!(isVZEROtrigger || isT0trigger)) interactions[2] = true;
319  }
320  }
321  }
322  }
323 
324  for(auto iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
325  auto entry = matchedTriggers.find(iclass);
326  if(entry != matchedTriggers.end()){
327  // trigger selected among at least one L0 class
328  const auto &interactions = entry->second;
329  emcalTriggers[iclass] &= interactions[0];
330  emc8Triggers[iclass] &= interactions[1];
331  emcNoIntTriggers[iclass] &= interactions[2];
332  } else {
333  // trigger not selected - mark all cases as false
334  emcalTriggers[iclass] = false;
335  emc8Triggers[iclass] = false;
336  emcNoIntTriggers[iclass] = false;
337  }
338 
339  if(emcalTriggers[iclass])
340  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT7 suite)" << std::endl;
341  if(emc8Triggers[iclass])
342  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT8 suite)" << std::endl;
343  if(emcNoIntTriggers[iclass])
344  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (No INT coincidence)" << std::endl;
345  }
346  }
347  } else {
348  // MC: Use INT7/INT08 for VZERO/TZERO triggers, for EMCAL trigger use trigger selection container
349  bool isT0trigger = selectionstatus & AliVEvent::kINT7, isVZEROtrigger = selectionstatus & AliVEvent::kINT8;
351  for(int iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
352  auto emcalSelectionStatus = MatchTriggerFromContainer(kEmcalSelectTriggerStrings[iclass], triggersel);
353  if(isT0trigger) {
354  emc8Triggers[iclass] &= emcalSelectionStatus;
355  }
356  if(isVZEROtrigger){
357  emcalTriggers[iclass] &= emcalSelectionStatus;
358  }
359  if(!(isT0trigger || isVZEROtrigger)){
360  // No coincidence with interaction trigger
361  emcNoIntTriggers[iclass] &= emcalSelectionStatus;
362  }
363  if(emcalTriggers[iclass])
364  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT7 suite)" << std::endl;
365  if(emc8Triggers[iclass])
366  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT8 suite)" << std::endl;
367  if(emcNoIntTriggers[iclass])
368  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (No INT coincidence)" << std::endl;
369  }
370  }
371  }
372 
373  // Apply offline trigger selection: In this case cuts are performed on the
374  // patch energy from EMCAL cells after calibration. This method is most relevant
375  // for simulations. It can have a special use case in data in case a stronger
376  // offline selection is applied in addition to the online selection.
378  for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++)
380  }
381  if(fEnableV0Triggers){
382  if(isMinBias) fSelectedTriggers.push_back("MB");
384  if(isCENT) fSelectedTriggers.push_back("CENT");
385  if(isSemiCENT) fSelectedTriggers.push_back("SEMICENT");
386  }
387  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]){
388  AliDebugStream(1) << "Event selected as EMC7" << std::endl;
389  fSelectedTriggers.push_back("EMC7");
390  if(!isMinBias) fSelectedTriggers.push_back("EMC7excl");
391  }
392  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2]){
393  AliDebugStream(1) << "Event selected as EJ2" << std::endl;
394  fSelectedTriggers.push_back("EJ2");
395  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EJ2excl");
396  }
397  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ1]){
398  AliDebugStream(1) << "Event selected as EJ1" << std::endl;
399  fSelectedTriggers.push_back("EJ1");
400  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("EJ1excl");
401  }
402  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2]){
403  AliDebugStream(1) << "Event selected as EG2" << std::endl;
404  fSelectedTriggers.push_back("EG2");
405  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EG2excl");
406  }
407  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG1]){
408  AliDebugStream(1) << "Event selected as EG1" << std::endl;
409  fSelectedTriggers.push_back("EG1");
410  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("EG1excl");
411  }
412 
414  // Handle DCAL triggers only in case DCAL triggers are enabled,
415  // otherwise ignore results of the online/offline trigger selection
416  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]){
417  AliDebugStream(1) << "Event selected as DMC7" << std::endl;
418  fSelectedTriggers.push_back("DMC7");
419  if(!isMinBias) fSelectedTriggers.push_back("DMC7excl");
420  }
421  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2]){
422  AliDebugStream(1) << "Event selected as DJ2" << std::endl;
423  fSelectedTriggers.push_back("DJ2");
424  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DJ2excl");
425  }
426  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ1]){
427  AliDebugStream(1) << "Event selected as DJ1" << std::endl;
428  fSelectedTriggers.push_back("DJ1");
429  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("DJ1excl");
430  }
431  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2]){
432  AliDebugStream(1) << "Event selected as DG2" << std::endl;
433  fSelectedTriggers.push_back("DG2");
434  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DG2excl");
435  }
436  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG1]){
437  AliDebugStream(1) << "Event selected as DG1" << std::endl;
438  fSelectedTriggers.push_back("DG1");
439  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("DG1excl");
440  }
441  }
442  }
443 
444  if(fEnableT0Triggers) {
445  if(isMinBiasT0) fSelectedTriggers.push_back("MBT0");
446  if(emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) {
447  // EMC8 trigger
448  AliDebugStream(1) << "Event selected as EMC8" << std::endl;
449  fSelectedTriggers.push_back("EMC8");
450  if(!isMinBiasT0) fSelectedTriggers.push_back("EMC8excl");
451  }
453  AliDebugStream(1) << "Event selected as EJ2 (EMC8)" << std::endl;
454  fSelectedTriggers.push_back("EMC8EJ2");
455  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EMC8EJ2excl");
456  }
458  AliDebugStream(1) << "Event selected as EJ1 (EMC8)" << std::endl;
459  fSelectedTriggers.push_back("EMC8EJ1");
460  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("EMC8EJ1excl");
461  }
463  AliDebugStream(1) << "Event selected as EG2 (EMC8)" << std::endl;
464  fSelectedTriggers.push_back("EMC8EG2");
465  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EMC8EG2excl");
466  }
468  AliDebugStream(1) << "Event selected as EG1 (EMC8)" << std::endl;
469  fSelectedTriggers.push_back("EMC8EG1");
470  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("EMC8EG1excl");
471  }
472 
474  // Handle DCAL triggers only in case DCAL triggers are enabled,
475  // otherwise ignore results of the online/offline trigger selection
477  AliDebugStream(1) << "Event selected as DMC8" << std::endl;
478  fSelectedTriggers.push_back("DMC8");
479  if(!isMinBiasT0) fSelectedTriggers.push_back("DMC8excl");
480  }
482  AliDebugStream(1) << "Event selected as DJ2 (DMC8)" << std::endl;
483  fSelectedTriggers.push_back("DMC8DJ2");
484  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DMC8DJ2excl");
485  }
487  AliDebugStream(1) << "Event selected as DJ1 (DMC8)" << std::endl;
488  fSelectedTriggers.push_back("DMC8DJ1");
489  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("DMC8DJ1excl");
490  }
492  AliDebugStream(1) << "Event selected as DG2 (DMC8)" << std::endl;
493  fSelectedTriggers.push_back("DMC8DG2");
494  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DMC8DG2excl");
495  }
497  AliDebugStream(1) << "Event selected as DG1 (DMC8)" << std::endl;
498  fSelectedTriggers.push_back("DMC8DG1");
499  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("DMC8DG1excl");
500  }
501  }
502  }
503 
505  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) {
506  // EMC8 trigger
507  AliDebugStream(1) << "Event selected as 0EMC" << std::endl;
508  fSelectedTriggers.push_back("0EMC");
509  }
510  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2]){
511  AliDebugStream(1) << "Event selected as EJ2 (E0MC)" << std::endl;
512  fSelectedTriggers.push_back("0EMCEJ2");
513  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) fSelectedTriggers.push_back("0EMCEJ2excl");
514  }
515  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ1]){
516  AliDebugStream(1) << "Event selected as EJ1 (0EMC)" << std::endl;
517  fSelectedTriggers.push_back("0EMCEJ1");
518  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("0EMCEJ1excl");
519  }
520  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2]){
521  AliDebugStream(1) << "Event selected as EG2 (0EMC)" << std::endl;
522  fSelectedTriggers.push_back("0EMCEG2");
523  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) fSelectedTriggers.push_back("0EMCEG2excl");
524  }
526  AliDebugStream(1) << "Event selected as EG1 (EMC8)" << std::endl;
527  fSelectedTriggers.push_back("0EMCEG1");
528  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("0EMCEG1excl");
529  }
530 
532  // Handle DCAL triggers only in case DCAL triggers are enabled,
533  // otherwise ignore results of the online/offline trigger selection
534  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]){
535  AliDebugStream(1) << "Event selected as 0DMC" << std::endl;
536  fSelectedTriggers.push_back("0DMC");
537  }
538  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2]){
539  AliDebugStream(1) << "Event selected as DJ2 (0DMC)" << std::endl;
540  fSelectedTriggers.push_back("0DMCDJ2");
541  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]) fSelectedTriggers.push_back("0DMCDJ2excl");
542  }
543  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ1]){
544  AliDebugStream(1) << "Event selected as DJ1 (0DMC)" << std::endl;
545  fSelectedTriggers.push_back("0DMCDJ1");
546  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("0DMCDJ1excl");
547  }
548  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2]){
549  AliDebugStream(1) << "Event selected as DG2 (0DMC)" << std::endl;
550  fSelectedTriggers.push_back("0DMCDG2");
551  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]) fSelectedTriggers.push_back("0DMCDG2excl");
552  }
553  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG1]){
554  AliDebugStream(1) << "Event selected as DG1 (0DMC)" << std::endl;
555  fSelectedTriggers.push_back("0DMCDG1");
556  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("0DMCDG1excl");
557  }
558  }
559  }
560 }
561 
564 
565  if(!fLocalInitialized){
566  return;
567  }
568 
569  // Handle OADB container with downscaling factors
570  if(fNameDownscaleOADB.Length()){
571  if(fNameDownscaleOADB.Contains("alien://") && ! gGrid) TGrid::Connect("alien://");
572  fDownscaleOADB = new AliOADBContainer("AliEmcalDownscaleFactors");
573  fDownscaleOADB->InitFromFile(fNameDownscaleOADB.Data(), "AliEmcalDownscaleFactors");
574  }
575 }
576 
578  if(fDownscaleOADB){
579  fDownscaleFactors = static_cast<TObjArray *>(fDownscaleOADB->GetObject(runnumber));
580  }
582 
583  // Log info for downscale factors
584  if(!fDownscaleFactors || !fDownscaleFactors->GetEntries()){
585  AliInfoStream() << GetName() << ": No downscale factors provided for run " << runnumber << std::endl;
586  } else {
587  AliInfoStream() << GetName() << ": Downscale factors used for run " << runnumber << std::endl;
588  for(auto e : *fDownscaleFactors){
589  TParameter<double> *dfactor = static_cast<TParameter<double> *>(e);
590  AliInfoStream() << GetName() << ": Trigger " << dfactor->GetName() << ", downscale factor " << dfactor->GetVal() << std::endl;
591  }
592  }
593 }
594 
595 std::vector<TString> AliAnalysisTaskEmcalTriggerBase::GetSupportedTriggers(Bool_t useExclusiveTriggers) const {
596  // Exclusive means classes without lower trigger classes (which are downscaled) -
597  // in order to make samples statistically independent: MBExcl means MinBias && !EMCAL trigger
598  std::vector<TString> triggers;
599  const std::array<TString, 5> emcaltriggers = {{"EMC7", "EJ1", "EJ2", "EG1", "EG2"}},
600  dcaltriggers = {{"DMC7", "DJ1", "DJ2", "DG1", "DG2"}},
601  emcalexclusive = {{"EMC7excl", "EG2excl", "EJ2excl", "EJ1excl", "EG1excl"}},
602  dcalexclusive = {{"DMC7excl", "DG2excl", "DJ2excl", "DJ1excl", "DG1excl"}},
603  t0triggers = {{"EMC8", "EMC8EJ1", "EMC8EJ2", "EMC8EG1", "EMC8EG2"}},
604  t0exclusive = {{"EMC8excl", "EMC8EG2excl", "EMC8EJ2excl", "EMC8EJ1excl", "EMC8EG1excl"}},
605  t0dcaltriggers = {{"DMC8", "DMC8DJ1", "DMC8DJ2", "DMC8DG1", "DMC8DG2"}},
606  t0dcalexclusive = {{"DMC8excl", "DMC8DG2excl", "DMC8DJ2excl", "DMC8DJ1excl", "DMC8DG1excl"}},
607  nointEMCAL = {{"0EMC", "0EMCEJ1", "0EMCEJ2", "0EMCEG1", "0EMCEG2"}},
608  nointDCAL = {{"0DMC", "0DMCDJ1", "0DMCDJ2", "0DMCDG1", "0DMCDG2"}};
609  const std::array<TString, 4> nointemcalexclusive = {{"0EMCEG2excl", "0EMCEJ2excl", "0EMCEJ1excl", "0EMCEG1excl"}},
610  nointdcalexclusive = {{"0DMCDG2excl", "0DMCDJ2excl", "0DMCDJ1excl", "0DMCDG1excl"}};
611  const std::array<TString, 2> centralitytriggers = {{"CENT", "SEMICENT"}};
612  if(fEnableV0Triggers){
613  triggers.push_back("MB"); // Min. Bias always enabled
614  if(!fExclusiveMinBias){
615  for(const auto &t : emcaltriggers) triggers.push_back(t);
616  if(useExclusiveTriggers)
617  for(const auto &t : emcalexclusive) triggers.push_back(t);
618  }
620  for(const auto &t : dcaltriggers) triggers.push_back(t);
621  if(useExclusiveTriggers)
622  for(const auto &t : dcalexclusive) triggers.push_back(t);
623  }
625  for(const auto &t : centralitytriggers) triggers.push_back(t);
626  }
627  }
628  if(fEnableT0Triggers){
629  triggers.push_back("MBT0");
630  if(!fExclusiveMinBias){
631  for(const auto &t: t0triggers) triggers.push_back(t);
632  if(useExclusiveTriggers)
633  for(const auto &t : t0exclusive) triggers.push_back(t);
634  }
636  for(const auto &t: t0dcaltriggers) triggers.push_back(t);
637  if(useExclusiveTriggers)
638  for(const auto &t : t0dcalexclusive) triggers.push_back(t);
639  }
640  }
641  if(fEnableNoINTTriggers) {
642  // No MB trigger since no interaction trigger
643  if(!fExclusiveMinBias){
644  for(const auto &t: nointEMCAL) triggers.push_back(t);
645  if(useExclusiveTriggers)
646  for(const auto &t : nointemcalexclusive) triggers.push_back(t);
647  }
649  for(const auto &t: nointDCAL) triggers.push_back(t);
650  if(useExclusiveTriggers)
651  for(const auto &t : nointdcalexclusive) triggers.push_back(t);
652  }
653  }
654  return triggers;
655 }
656 
657 bool AliAnalysisTaskEmcalTriggerBase::MatchTriggerFromPattern(const std::string &pattern, const std::string &trigger) const {
658  std::string patternstring = pattern;
659  bool isEqual = pattern[0] == '=';
660  if(pattern[0] == '=') patternstring = pattern.substr(1);
661  std::vector<std::string> classes;
662  if(patternstring.find("|") != std::string::npos){
663  std::stringstream decoder(patternstring);
664  std::string tmp;
665  while(std::getline(decoder, tmp, '|')) classes.emplace_back(tmp);
666  } else classes.emplace_back(patternstring);
667  bool found(false);
668  for(const auto &t : classes){
669  if(isEqual && (trigger == t)) {
670  found = true;
671  break;
672  }
673  if(!isEqual && (trigger.find(t) != std::string::npos)){
674  found = true;
675  break;
676  }
677  }
678  return found;
679 }
680 
682  if(!trgsel) return false;
683  std::string patternstring = pattern;
684  if(pattern[0] == '=') patternstring = pattern.substr(1);
685  std::vector<std::string> classes;
686  if(patternstring.find("|") != std::string::npos){
687  std::stringstream decoder(patternstring);
688  std::string tmp;
689  while(std::getline(decoder, tmp, '|')) classes.emplace_back(tmp);
690  } else classes.emplace_back(patternstring);
691  bool found(false);
692  for(const auto &t : classes) {
693  if(trgsel->IsEventSelected(t.data())) {
694  found = true;
695  break;
696  }
697  }
698  return found;
699 }
700 
702  if(fDownscaleFactors){
703  TParameter<double> *result(nullptr);
704  // Downscaling only done on MB, L0 and the low threshold triggers
705  if(triggerclass.Contains("MB")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("INT7"));
706  else if(triggerclass.Contains("EMC7")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EMC7"));
707  else if(triggerclass.Contains("DMC7")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DMC7"));
708  else if(triggerclass.Contains("EJ2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EJ2"));
709  else if(triggerclass.Contains("EJ1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EJ1"));
710  else if(triggerclass.Contains("EG2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EG2"));
711  else if(triggerclass.Contains("EG1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EG1"));
712  else if(triggerclass.Contains("DG2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DG2"));
713  else if(triggerclass.Contains("DG1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DG1"));
714  double triggerweight = 1.;
715  if(result) triggerweight = 1./result->GetVal();
716  AliDebugStream(1) << "Using trigger weight " << triggerweight << " for trigger " << triggerclass << std::endl;
717  return triggerweight;
718  } else {
719  AliDebugStream(1) << "No downscale factors loaded - using trigger weight 1" << std::endl;
720  }
721  return 1.;
722 }
723 
725  AliInfoStream() << "Reading downscale factors from OCDB for run " << fInputEvent->GetRunNumber() << std::endl;
726  if(!fDownscaleFactors){
728  fDownscaleFactors->SetOwner(true);
729  }
730  fDownscaleFactors->Clear();
732  if(downscaleOCDB->GetCurrentRun() != fInputEvent->GetRunNumber()) downscaleOCDB->SetRun(fInputEvent->GetRunNumber());
733  const std::array<TString, 11> khwtriggers = {"INT7", "EMC7", "DMC7", "EJ1", "EJ2", "DJ1", "DJ2", "EG1", "EG2", "DG1", "DG2"};
734  std::vector<TString> runtriggers = downscaleOCDB->GetTriggerClasses();
735  for(const auto &t : khwtriggers){
736  std::function<bool (TString)> triggerfinder = [t](const TString &test) -> bool {
737  if(!test.Contains(t + "-B-")) return false;
738  return true;
739  };
740  auto entry = std::find_if(runtriggers.begin(), runtriggers.end(), triggerfinder);
741  if(entry != runtriggers.end()){
742  TString triggername = *entry;
743  double downscalefactor = downscaleOCDB->GetDownscaleFactorForTriggerClass(triggername);
744  AliInfoStream() << "Applying downscale factor " << downscalefactor << " for trigger " << t << " (" << triggername << ") for run " << fInputEvent->GetRunNumber() << std::endl;
745  fDownscaleFactors->Add(new TParameter<double>(t, TMath::Abs(downscalefactor) < DBL_EPSILON ? 1 : downscalefactor));
746  } else {
747  AliErrorStream() << "No downscale factor found for trigger " << t << " for run " << fInputEvent->GetRunNumber() << std::endl;
748  }
749  }
750 }
751 
752 } /* namespace EMCalTriggerPtAnalysis */
std::vector< TString > fSelectedTriggers
! Triggers selected for given event
bool IsEventSelected(const char *name) const
Checks whether the events is selected for a given trigger type.
Bool_t IsOfflineSelected(EmcalTriggerClass trgcls, const AliVEvent *const data) const
Select event as triggered event.
Bool_t fIsPythia
trigger, if it is a PYTHIA production
double Double_t
Definition: External.C:58
Double_t fVertexSPD[3]
!event Svertex
Base task in the EMCAL framework.
Bool_t fLocalInitialized
whether or not the task has been already initialized
void FillTH2(const char *hname, double x, double y, double weight=1., Option_t *opt="")
Fill a 2D histogram within the container.
Bool_t fEnableV0Triggers
Enable VZERO-based triggers (default)
static AliEmcalDownscaleFactorsOCDB * Instance()
Bool_t fEnableNoINTTriggers
Process EMCAL triggers without coincidence with INT triggers - exotic case - default off...
AliEmcalTriggerOfflineSelection * fTriggerSelection
Offline trigger selection.
void PrepareDownscaleFactorsFormOCDB()
Read the downscale factors from the OCDB.
Bool_t fEnableDCALTriggers
Enable / Disable event selection for DCAL trigger classes.
static std::vector< PWG::EMCAL::Triggerinfo > DecodeTriggerString(const std::string &triggerstring)
Decoding trigger string.
Bool_t fRequireAnalysisUtils
Switch whether to require event selection in AliAnalysisUtils.
Bool_t CheckMCOutliers()
Filter the mc tails in pt-hard distributions.
Bool_t fRequireBunchCrossing
Require bunch-bunch events (tag -B- in trigger string)
TH2 * CreateTH2(const char *name, const char *title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double ymax, Option_t *opt="")
Create a new TH2 within the container.
TObject * FindObject(const char *name) const
Find an object inside the container.
int Int_t
Definition: External.C:63
TString fNameClusterContainer
Name of the cluster container in the event.
TString fNameTriggerSelectionContainer
Name of the trigger selection container.
unsigned int UInt_t
Definition: External.C:33
THashList * GetListOfHistograms() const
Get the list of histograms.
Definition: THistManager.h:671
EmcalTriggerClass
Definition of the various supported trigger types.
AliAnalysisUtils * fAliAnalysisUtils
!vertex selection (optional)
TString fNameDownscaleOADB
Name of the downscale OADB container.
Bool_t fEnableT0Triggers
Enable triggers depending on T0 (INT8, EMC8, EMC8EGA, EMC8EJE) - default off.
const TString & GetNameClusterContainer() const
Get the name of the cluster container.
Bool_t fEnableCentralityTriggers
Enable central / semi-central trigger.
Bool_t fUseTriggerBits
Switch whether using trigger bits (relies on physics selection)
Bool_t isMC
AliEmcalList * fOutput
!output list
Definition: External.C:220
AliOADBContainer * fDownscaleOADB
! Container with downscale factors for different triggers
Analysis of high- tracks in triggered events.
Bool_t fUseSPDVertex
Use SPD vertex (for productions without TPC)
Double_t fVertex[3]
!event vertex
void SetMakeGeneralHistograms(Bool_t g)
TClonesArray * fTriggerPatchInfo
!trigger patch info array
void SetNeedEmcalGeom(Bool_t n)
Container class for histograms.
Definition: THistManager.h:99
virtual void ExecOnce()
Perform steps needed to initialize the analysis.
void test(int runnumber=195345)
void UserCreateOutputObjects()
Main initialization function on the worker.
AliCutValueRange< double > fVertexCut
Cut on the z-position of the primary vertex.
bool Bool_t
Definition: External.C:53
bool MatchTriggerFromPattern(const std::string &pattern, const std::string &triggerclass) const
Match trigger pattern.
Bool_t fUseTriggerSelectionContainer
Use trigger decision in trigger selection container.
std::vector< TString > GetSupportedTriggers(Bool_t useExclusiveTriggers=true) const
Definition: External.C:196
bool MatchTriggerFromContainer(const std::string &pattern, const PWG::EMCAL::AliEmcalTriggerDecisionContainer *trgcont) const
Matching triggers in pattern with entry in trigger decision container.
static TString ClusterContainerNameFactory(Bool_t isAOD)
Get name of the default cluster container.