AliPhysics  a6017e1 (a6017e1)
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  auto triggerstring = fInputEvent->GetFiredTriggerClasses();
293  if(triggerstring.Contains("EMC") || triggerstring.Contains("DMC") ||
294  triggerstring.Contains("INT7E") || triggerstring.Contains("INT7D")){ // special conditions for 2015 PbPb
295  // Apply cut on the trigger string - this basically discriminates high- and low-threshold
296  // triggers
297  auto triggers = PWG::EMCAL::Triggerinfo::DecodeTriggerString(fInputEvent->GetFiredTriggerClasses().Data());
298  std::map<int, std::array<bool, 3>> matchedTriggers;
299  for(auto t : triggers) {
300  const auto &triggerclass = t.Triggerclass();
301  if((triggerclass.find("EMC") != std::string::npos) || (triggerclass.find("DMC") != std::string::npos) ||
302  (triggerclass.find("INT7E") != std::string::npos) || (triggerclass.find("INT7D") != std::string::npos))
303  AliDebugStream(1) << GetName() << ": Trigger string " << t.ExpandClassName() << std::endl;
304  else continue; // No EMC / DMC trigger - not to be checked
305  bool isT0trigger = (triggerclass.find("EMC8") != std::string::npos) || (triggerclass.find("DMC8") != std::string::npos) || (triggerclass.find("INT8") != std::string::npos),
306  isVZEROtrigger = (triggerclass.find("EMC7") != std::string::npos) || (triggerclass.find("DMC7") != std::string::npos) || (triggerclass.find("INT7") != std::string::npos);
307  for(auto iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
308  AliDebugStream(1) << "Next trigger: " << kEmcalSelectTriggerStrings[iclass] << std::endl;
309  bool emcalSelectionStatus = MatchTriggerFromPattern(kEmcalSelectTriggerStrings[iclass], triggerclass);
310  if(fUseTriggerSelectionContainer) emcalSelectionStatus = emcalSelectionStatus & MatchTriggerFromContainer(kEmcalSelectTriggerStrings[iclass], triggersel);
311  if(emcalSelectionStatus) {
312  auto entry = matchedTriggers.find(iclass);
313  if(entry == matchedTriggers.end()) {
314  std::array<bool, 3> interactions = {{isVZEROtrigger, isT0trigger, !(isVZEROtrigger || isT0trigger)}};
315  matchedTriggers.insert(std::pair<int, std::array<bool, 3>>(iclass, interactions));
316  } else {
317  auto &interactions = entry->second;
318  if(isVZEROtrigger) interactions[0] = true;
319  if(isT0trigger) interactions[1] = true;
320  if(!(isVZEROtrigger || isT0trigger)) interactions[2] = true;
321  }
322  }
323  }
324  }
325 
326  for(auto iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
327  auto entry = matchedTriggers.find(iclass);
328  if(entry != matchedTriggers.end()){
329  // trigger selected among at least one L0 class
330  const auto &interactions = entry->second;
331  emcalTriggers[iclass] &= interactions[0];
332  emc8Triggers[iclass] &= interactions[1];
333  emcNoIntTriggers[iclass] &= interactions[2];
334  } else {
335  // trigger not selected - mark all cases as false
336  emcalTriggers[iclass] = false;
337  emc8Triggers[iclass] = false;
338  emcNoIntTriggers[iclass] = false;
339  }
340 
341  if(emcalTriggers[iclass])
342  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT7 suite)" << std::endl;
343  if(emc8Triggers[iclass])
344  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT8 suite)" << std::endl;
345  if(emcNoIntTriggers[iclass])
346  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (No INT coincidence)" << std::endl;
347  }
348  }
349  } else {
350  // MC: Use INT7/INT08 for VZERO/TZERO triggers, for EMCAL trigger use trigger selection container
351  bool isT0trigger = selectionstatus & AliVEvent::kINT7, isVZEROtrigger = selectionstatus & AliVEvent::kINT8;
353  for(int iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
354  auto emcalSelectionStatus = MatchTriggerFromContainer(kEmcalSelectTriggerStrings[iclass], triggersel);
355  if(isT0trigger) {
356  emc8Triggers[iclass] &= emcalSelectionStatus;
357  }
358  if(isVZEROtrigger){
359  emcalTriggers[iclass] &= emcalSelectionStatus;
360  }
361  if(!(isT0trigger || isVZEROtrigger)){
362  // No coincidence with interaction trigger
363  emcNoIntTriggers[iclass] &= emcalSelectionStatus;
364  }
365  if(emcalTriggers[iclass])
366  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT7 suite)" << std::endl;
367  if(emc8Triggers[iclass])
368  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT8 suite)" << std::endl;
369  if(emcNoIntTriggers[iclass])
370  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (No INT coincidence)" << std::endl;
371  }
372  }
373  }
374 
375  // Apply offline trigger selection: In this case cuts are performed on the
376  // patch energy from EMCAL cells after calibration. This method is most relevant
377  // for simulations. It can have a special use case in data in case a stronger
378  // offline selection is applied in addition to the online selection.
380  for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++)
382  }
383  if(fEnableV0Triggers){
384  if(isMinBias) fSelectedTriggers.push_back("MB");
386  if(isCENT) fSelectedTriggers.push_back("CENT");
387  if(isSemiCENT) fSelectedTriggers.push_back("SEMICENT");
388  }
389  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]){
390  AliDebugStream(1) << "Event selected as EMC7" << std::endl;
391  fSelectedTriggers.push_back("EMC7");
392  if(!isMinBias) fSelectedTriggers.push_back("EMC7excl");
393  }
394  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2]){
395  AliDebugStream(1) << "Event selected as EJ2" << std::endl;
396  fSelectedTriggers.push_back("EJ2");
397  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EJ2excl");
398  }
399  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ1]){
400  AliDebugStream(1) << "Event selected as EJ1" << std::endl;
401  fSelectedTriggers.push_back("EJ1");
402  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("EJ1excl");
403  }
404  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2]){
405  AliDebugStream(1) << "Event selected as EG2" << std::endl;
406  fSelectedTriggers.push_back("EG2");
407  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EG2excl");
408  }
409  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG1]){
410  AliDebugStream(1) << "Event selected as EG1" << std::endl;
411  fSelectedTriggers.push_back("EG1");
412  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("EG1excl");
413  }
414 
416  // Handle DCAL triggers only in case DCAL triggers are enabled,
417  // otherwise ignore results of the online/offline trigger selection
418  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]){
419  AliDebugStream(1) << "Event selected as DMC7" << std::endl;
420  fSelectedTriggers.push_back("DMC7");
421  if(!isMinBias) fSelectedTriggers.push_back("DMC7excl");
422  }
423  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2]){
424  AliDebugStream(1) << "Event selected as DJ2" << std::endl;
425  fSelectedTriggers.push_back("DJ2");
426  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DJ2excl");
427  }
428  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ1]){
429  AliDebugStream(1) << "Event selected as DJ1" << std::endl;
430  fSelectedTriggers.push_back("DJ1");
431  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("DJ1excl");
432  }
433  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2]){
434  AliDebugStream(1) << "Event selected as DG2" << std::endl;
435  fSelectedTriggers.push_back("DG2");
436  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DG2excl");
437  }
438  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG1]){
439  AliDebugStream(1) << "Event selected as DG1" << std::endl;
440  fSelectedTriggers.push_back("DG1");
441  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("DG1excl");
442  }
443  }
444  }
445 
446  if(fEnableT0Triggers) {
447  if(isMinBiasT0) fSelectedTriggers.push_back("MBT0");
448  if(emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) {
449  // EMC8 trigger
450  AliDebugStream(1) << "Event selected as EMC8" << std::endl;
451  fSelectedTriggers.push_back("EMC8");
452  if(!isMinBiasT0) fSelectedTriggers.push_back("EMC8excl");
453  }
455  AliDebugStream(1) << "Event selected as EJ2 (EMC8)" << std::endl;
456  fSelectedTriggers.push_back("EMC8EJ2");
457  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EMC8EJ2excl");
458  }
460  AliDebugStream(1) << "Event selected as EJ1 (EMC8)" << std::endl;
461  fSelectedTriggers.push_back("EMC8EJ1");
462  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("EMC8EJ1excl");
463  }
465  AliDebugStream(1) << "Event selected as EG2 (EMC8)" << std::endl;
466  fSelectedTriggers.push_back("EMC8EG2");
467  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EMC8EG2excl");
468  }
470  AliDebugStream(1) << "Event selected as EG1 (EMC8)" << std::endl;
471  fSelectedTriggers.push_back("EMC8EG1");
472  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("EMC8EG1excl");
473  }
474 
476  // Handle DCAL triggers only in case DCAL triggers are enabled,
477  // otherwise ignore results of the online/offline trigger selection
479  AliDebugStream(1) << "Event selected as DMC8" << std::endl;
480  fSelectedTriggers.push_back("DMC8");
481  if(!isMinBiasT0) fSelectedTriggers.push_back("DMC8excl");
482  }
484  AliDebugStream(1) << "Event selected as DJ2 (DMC8)" << std::endl;
485  fSelectedTriggers.push_back("DMC8DJ2");
486  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DMC8DJ2excl");
487  }
489  AliDebugStream(1) << "Event selected as DJ1 (DMC8)" << std::endl;
490  fSelectedTriggers.push_back("DMC8DJ1");
491  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("DMC8DJ1excl");
492  }
494  AliDebugStream(1) << "Event selected as DG2 (DMC8)" << std::endl;
495  fSelectedTriggers.push_back("DMC8DG2");
496  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DMC8DG2excl");
497  }
499  AliDebugStream(1) << "Event selected as DG1 (DMC8)" << std::endl;
500  fSelectedTriggers.push_back("DMC8DG1");
501  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("DMC8DG1excl");
502  }
503  }
504  }
505 
507  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) {
508  // EMC8 trigger
509  AliDebugStream(1) << "Event selected as 0EMC" << std::endl;
510  fSelectedTriggers.push_back("0EMC");
511  }
512  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2]){
513  AliDebugStream(1) << "Event selected as EJ2 (E0MC)" << std::endl;
514  fSelectedTriggers.push_back("0EMCEJ2");
515  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) fSelectedTriggers.push_back("0EMCEJ2excl");
516  }
517  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ1]){
518  AliDebugStream(1) << "Event selected as EJ1 (0EMC)" << std::endl;
519  fSelectedTriggers.push_back("0EMCEJ1");
520  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("0EMCEJ1excl");
521  }
522  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2]){
523  AliDebugStream(1) << "Event selected as EG2 (0EMC)" << std::endl;
524  fSelectedTriggers.push_back("0EMCEG2");
525  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) fSelectedTriggers.push_back("0EMCEG2excl");
526  }
528  AliDebugStream(1) << "Event selected as EG1 (EMC8)" << std::endl;
529  fSelectedTriggers.push_back("0EMCEG1");
530  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("0EMCEG1excl");
531  }
532 
534  // Handle DCAL triggers only in case DCAL triggers are enabled,
535  // otherwise ignore results of the online/offline trigger selection
536  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]){
537  AliDebugStream(1) << "Event selected as 0DMC" << std::endl;
538  fSelectedTriggers.push_back("0DMC");
539  }
540  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2]){
541  AliDebugStream(1) << "Event selected as DJ2 (0DMC)" << std::endl;
542  fSelectedTriggers.push_back("0DMCDJ2");
543  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]) fSelectedTriggers.push_back("0DMCDJ2excl");
544  }
545  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ1]){
546  AliDebugStream(1) << "Event selected as DJ1 (0DMC)" << std::endl;
547  fSelectedTriggers.push_back("0DMCDJ1");
548  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("0DMCDJ1excl");
549  }
550  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2]){
551  AliDebugStream(1) << "Event selected as DG2 (0DMC)" << std::endl;
552  fSelectedTriggers.push_back("0DMCDG2");
553  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]) fSelectedTriggers.push_back("0DMCDG2excl");
554  }
555  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG1]){
556  AliDebugStream(1) << "Event selected as DG1 (0DMC)" << std::endl;
557  fSelectedTriggers.push_back("0DMCDG1");
558  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("0DMCDG1excl");
559  }
560  }
561  }
562 }
563 
566 
567  if(!fLocalInitialized){
568  return;
569  }
570 
571  // Handle OADB container with downscaling factors
572  if(fNameDownscaleOADB.Length()){
573  if(fNameDownscaleOADB.Contains("alien://") && ! gGrid) TGrid::Connect("alien://");
574  fDownscaleOADB = new AliOADBContainer("AliEmcalDownscaleFactors");
575  fDownscaleOADB->InitFromFile(fNameDownscaleOADB.Data(), "AliEmcalDownscaleFactors");
576  }
577 }
578 
580  if(fDownscaleOADB){
581  fDownscaleFactors = static_cast<TObjArray *>(fDownscaleOADB->GetObject(runnumber));
582  }
584 
585  // Log info for downscale factors
586  if(!fDownscaleFactors || !fDownscaleFactors->GetEntries()){
587  AliInfoStream() << GetName() << ": No downscale factors provided for run " << runnumber << std::endl;
588  } else {
589  AliInfoStream() << GetName() << ": Downscale factors used for run " << runnumber << std::endl;
590  for(auto e : *fDownscaleFactors){
591  TParameter<double> *dfactor = static_cast<TParameter<double> *>(e);
592  AliInfoStream() << GetName() << ": Trigger " << dfactor->GetName() << ", downscale factor " << dfactor->GetVal() << std::endl;
593  }
594  }
595 }
596 
597 std::vector<TString> AliAnalysisTaskEmcalTriggerBase::GetSupportedTriggers(Bool_t useExclusiveTriggers) const {
598  // Exclusive means classes without lower trigger classes (which are downscaled) -
599  // in order to make samples statistically independent: MBExcl means MinBias && !EMCAL trigger
600  std::vector<TString> triggers;
601  const std::array<TString, 5> emcaltriggers = {{"EMC7", "EJ1", "EJ2", "EG1", "EG2"}},
602  dcaltriggers = {{"DMC7", "DJ1", "DJ2", "DG1", "DG2"}},
603  emcalexclusive = {{"EMC7excl", "EG2excl", "EJ2excl", "EJ1excl", "EG1excl"}},
604  dcalexclusive = {{"DMC7excl", "DG2excl", "DJ2excl", "DJ1excl", "DG1excl"}},
605  t0triggers = {{"EMC8", "EMC8EJ1", "EMC8EJ2", "EMC8EG1", "EMC8EG2"}},
606  t0exclusive = {{"EMC8excl", "EMC8EG2excl", "EMC8EJ2excl", "EMC8EJ1excl", "EMC8EG1excl"}},
607  t0dcaltriggers = {{"DMC8", "DMC8DJ1", "DMC8DJ2", "DMC8DG1", "DMC8DG2"}},
608  t0dcalexclusive = {{"DMC8excl", "DMC8DG2excl", "DMC8DJ2excl", "DMC8DJ1excl", "DMC8DG1excl"}},
609  nointEMCAL = {{"0EMC", "0EMCEJ1", "0EMCEJ2", "0EMCEG1", "0EMCEG2"}},
610  nointDCAL = {{"0DMC", "0DMCDJ1", "0DMCDJ2", "0DMCDG1", "0DMCDG2"}};
611  const std::array<TString, 4> nointemcalexclusive = {{"0EMCEG2excl", "0EMCEJ2excl", "0EMCEJ1excl", "0EMCEG1excl"}},
612  nointdcalexclusive = {{"0DMCDG2excl", "0DMCDJ2excl", "0DMCDJ1excl", "0DMCDG1excl"}};
613  const std::array<TString, 2> centralitytriggers = {{"CENT", "SEMICENT"}};
614  if(fEnableV0Triggers){
615  triggers.push_back("MB"); // Min. Bias always enabled
616  if(!fExclusiveMinBias){
617  for(const auto &t : emcaltriggers) triggers.push_back(t);
618  if(useExclusiveTriggers)
619  for(const auto &t : emcalexclusive) triggers.push_back(t);
620  }
622  for(const auto &t : dcaltriggers) triggers.push_back(t);
623  if(useExclusiveTriggers)
624  for(const auto &t : dcalexclusive) triggers.push_back(t);
625  }
627  for(const auto &t : centralitytriggers) triggers.push_back(t);
628  }
629  }
630  if(fEnableT0Triggers){
631  triggers.push_back("MBT0");
632  if(!fExclusiveMinBias){
633  for(const auto &t: t0triggers) triggers.push_back(t);
634  if(useExclusiveTriggers)
635  for(const auto &t : t0exclusive) triggers.push_back(t);
636  }
638  for(const auto &t: t0dcaltriggers) triggers.push_back(t);
639  if(useExclusiveTriggers)
640  for(const auto &t : t0dcalexclusive) triggers.push_back(t);
641  }
642  }
643  if(fEnableNoINTTriggers) {
644  // No MB trigger since no interaction trigger
645  if(!fExclusiveMinBias){
646  for(const auto &t: nointEMCAL) triggers.push_back(t);
647  if(useExclusiveTriggers)
648  for(const auto &t : nointemcalexclusive) triggers.push_back(t);
649  }
651  for(const auto &t: nointDCAL) triggers.push_back(t);
652  if(useExclusiveTriggers)
653  for(const auto &t : nointdcalexclusive) triggers.push_back(t);
654  }
655  }
656  return triggers;
657 }
658 
659 bool AliAnalysisTaskEmcalTriggerBase::MatchTriggerFromPattern(const std::string &pattern, const std::string &trigger) const {
660  std::string patternstring = pattern;
661  bool isEqual = pattern[0] == '=';
662  if(pattern[0] == '=') patternstring = pattern.substr(1);
663  std::vector<std::string> classes;
664  if(patternstring.find("|") != std::string::npos){
665  std::stringstream decoder(patternstring);
666  std::string tmp;
667  while(std::getline(decoder, tmp, '|')) classes.emplace_back(tmp);
668  } else classes.emplace_back(patternstring);
669  bool found(false);
670  for(const auto &t : classes){
671  if(isEqual && (trigger == t)) {
672  found = true;
673  break;
674  }
675  if(!isEqual && (trigger.find(t) != std::string::npos)){
676  found = true;
677  break;
678  }
679  }
680  return found;
681 }
682 
684  if(!trgsel) return false;
685  std::string patternstring = pattern;
686  if(pattern[0] == '=') patternstring = pattern.substr(1);
687  std::vector<std::string> classes;
688  if(patternstring.find("|") != std::string::npos){
689  std::stringstream decoder(patternstring);
690  std::string tmp;
691  while(std::getline(decoder, tmp, '|')) classes.emplace_back(tmp);
692  } else classes.emplace_back(patternstring);
693  bool found(false);
694  for(const auto &t : classes) {
695  if(trgsel->IsEventSelected(t.data())) {
696  found = true;
697  break;
698  }
699  }
700  return found;
701 }
702 
704  if(fDownscaleFactors){
705  TParameter<double> *result(nullptr);
706  // Downscaling only done on MB, L0 and the low threshold triggers
707  if(triggerclass.Contains("MB")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("INT7"));
708  else if(triggerclass.Contains("EMC7")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EMC7"));
709  else if(triggerclass.Contains("DMC7")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DMC7"));
710  else if(triggerclass.Contains("EJ2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EJ2"));
711  else if(triggerclass.Contains("EJ1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EJ1"));
712  else if(triggerclass.Contains("EG2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EG2"));
713  else if(triggerclass.Contains("EG1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EG1"));
714  else if(triggerclass.Contains("DG2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DG2"));
715  else if(triggerclass.Contains("DG1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DG1"));
716  double triggerweight = 1.;
717  if(result) triggerweight = 1./result->GetVal();
718  AliDebugStream(1) << "Using trigger weight " << triggerweight << " for trigger " << triggerclass << std::endl;
719  return triggerweight;
720  } else {
721  AliDebugStream(1) << "No downscale factors loaded - using trigger weight 1" << std::endl;
722  }
723  return 1.;
724 }
725 
727  AliInfoStream() << "Reading downscale factors from OCDB for run " << fInputEvent->GetRunNumber() << std::endl;
728  if(!fDownscaleFactors){
730  fDownscaleFactors->SetOwner(true);
731  }
732  fDownscaleFactors->Clear();
734  if(downscaleOCDB->GetCurrentRun() != fInputEvent->GetRunNumber()) downscaleOCDB->SetRun(fInputEvent->GetRunNumber());
735  const std::array<TString, 11> khwtriggers = {"INT7", "EMC7", "DMC7", "EJ1", "EJ2", "DJ1", "DJ2", "EG1", "EG2", "DG1", "DG2"};
736  std::vector<TString> runtriggers = downscaleOCDB->GetTriggerClasses();
737  for(const auto &t : khwtriggers){
738  std::function<bool (TString)> triggerfinder = [t](const TString &test) -> bool {
739  if(!test.Contains(t + "-B-")) return false;
740  return true;
741  };
742  auto entry = std::find_if(runtriggers.begin(), runtriggers.end(), triggerfinder);
743  if(entry != runtriggers.end()){
744  TString triggername = *entry;
745  double downscalefactor = downscaleOCDB->GetDownscaleFactorForTriggerClass(triggername);
746  AliInfoStream() << "Applying downscale factor " << downscalefactor << " for trigger " << t << " (" << triggername << ") for run " << fInputEvent->GetRunNumber() << std::endl;
747  fDownscaleFactors->Add(new TParameter<double>(t, TMath::Abs(downscalefactor) < DBL_EPSILON ? 1 : downscalefactor));
748  } else {
749  AliErrorStream() << "No downscale factor found for trigger " << t << " for run " << fInputEvent->GetRunNumber() << std::endl;
750  }
751  }
752 }
753 
754 } /* 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.