AliPhysics  3b4a69f (3b4a69f)
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  fSelectCentralityTriggers2018(false)
78 {
79  SetNeedEmcalGeom(true);
81 }
82 
84  AliAnalysisTaskEmcal(name, true),
86  fUseTriggerBits(kTRUE),
87  fRequireBunchCrossing(kTRUE),
92  fRequireAnalysisUtils(kTRUE),
93  fUseSPDVertex(false),
94  fApplyVertexCuts(true),
95  fVertexCut(-10., 10.),
99  fNameTriggerSelectionContainer("EmcalTriggerDecision"),
100  fEnableDCALTriggers(true),
101  fEnableV0Triggers(true),
102  fEnableT0Triggers(false),
103  fEnableNoINTTriggers(false),
105  fExclusiveMinBias(false),
108 {
109  SetNeedEmcalGeom(true);
111 }
112 
115  if(fHistos) delete fHistos;
117 }
118 
121  if(fRequireAnalysisUtils && !fAliAnalysisUtils) fAliAnalysisUtils = new AliAnalysisUtils;
122 
123  if((!fNameClusterContainer.Length()) || fNameClusterContainer == "usedefault") fNameClusterContainer = AliEmcalAnalysisFactory::ClusterContainerNameFactory(fInputHandler->IsA() == AliAODInputHandler::Class());
126  }
127 
128  fHistos = new THistManager(Form("Histos_%s", GetName()));
129 
130  // Create trigger correlation histogram
131  std::vector<std::string> binlabels = {"MB"};
133  binlabels.emplace_back("CENT");
134  binlabels.emplace_back("SEMICENT");
135  }
136  if(fEnableV0Triggers){
137  const std::array<const std::string, 5> vzlabels = {{"EMC7", "EG1", "EG2", "EJ1", "EJ2"}};
138  for(const auto & vlab : vzlabels) binlabels.emplace_back(vlab);
140  const std::array<const std::string, 5> dclabels = {{"DMC7", "DG1", "DG2", "DJ1", "DJ2"}};
141  for(const auto & dlab : dclabels) binlabels.emplace_back(dlab);
142  }
143  }
144  if(fEnableT0Triggers) {
145  binlabels.emplace_back("MBT0");
146  const std::array<const std::string, 5> t0labels = {{"EMC8", "EMC8EG1", "EMC8EG2", "EMC8EJ1", "EMC8EJ2"}};
147  for(const auto & tlab : t0labels) binlabels.emplace_back(tlab);
149  const std::array<const std::string, 5> dtclabels = {{"DMC8", "DMC8DG1", "DMC8DG2", "DMC8DJ1", "DMC8DJ2"}};
150  for(const auto & dtlab : dtclabels) binlabels.emplace_back(dtlab);
151  }
152  }
153  fHistos->CreateTH2("hTriggerCorrelation", "Correlation selected trigger classes", binlabels.size(), -0.5, binlabels.size() - 0.5, binlabels.size(), -0.5, binlabels.size() - 0.5);
154  TH1 *correlationHist = static_cast<TH1 *>(fHistos->FindObject("hTriggerCorrelation"));
155  for(decltype(binlabels.size()) ib = 0; ib < binlabels.size(); ib++){
156  correlationHist->GetXaxis()->SetBinLabel(ib+1, binlabels[ib].data());
157  correlationHist->GetYaxis()->SetBinLabel(ib+1, binlabels[ib].data());
158  }
159 
162 
163  for(auto h : *(fHistos->GetListOfHistograms())) fOutput->Add(h);
164  fHistos->GetListOfHistograms()->SetOwner(false);
165 
166  PostData(1, fOutput);
167 }
168 
170  // Apply trigger selection
172  if(!fSelectedTriggers.size()) {
173  AliDebugStream(1) << "Failed trigger selection" << std::endl;
174  return false;
175  }
176 
178 
179  if(fApplyVertexCuts){
180  const AliVVertex *vtx = fUseSPDVertex ? fInputEvent->GetPrimaryVertexSPD() : fInputEvent->GetPrimaryVertex();
181  //if(!fInputEvent->IsPileupFromSPD(3, 0.8, 3., 2., 5.)) return; // reject pileup event
182  if(vtx->GetNContributors() < 1) {
183  AliDebugStream(1) << "Failed Vertex Selection" << std::endl;
184  return false;
185  }
187  AliDebugStream(1) << "Failed vertex-z cut" << std::endl;
188  return false;
189  }
190  }
191 
193  AliDebugStream(1) << "Checking cuts in AliAnalysisUtils" << std::endl;
194  if(fInputEvent->IsA() == AliESDEvent::Class() && fAliAnalysisUtils->IsFirstEventInChunk(fInputEvent)) return false;
195  if(fAliAnalysisUtils->IsPileUpEvent(fInputEvent)) return false; // Apply new vertex cut
196  if(!fAliAnalysisUtils->IsVertexSelected2013pA(fInputEvent))return false; // Apply new vertex cut
197  }
198 
199  if(!IsUserEventSelected()) {
200  AliDebugStream(1) << "Failed user extra cuts" << std::endl;
201  return false;
202  }
203 
204  // Do MC outlier cut
205  if(fIsPythia){
206  if(!CheckMCOutliers()){
207  AliDebugStream(1) << GetName() << ": Reject MC outliers" << std::endl;
208  return false;
209  }
210  }
211 
212  // Fill histogram with trigger correlation
213  // self-correlations included
214  auto *corrhist = static_cast<TH2 *>(fHistos->GetListOfHistograms()->FindObject("hTriggerCorrelation"));
215  for(int itrg = 0; itrg < corrhist->GetXaxis()->GetNbins(); itrg++){
216  const char *xlabel = corrhist->GetXaxis()->GetBinLabel(itrg+1);
217  bool hasTriggerA = (std::find(fSelectedTriggers.begin(), fSelectedTriggers.end(), xlabel) != fSelectedTriggers.end());
218  if(hasTriggerA) {
219  for(int jtrg = 0; jtrg < corrhist->GetYaxis()->GetNbins(); jtrg++){
220  const char *ylabel = corrhist->GetYaxis()->GetBinLabel(jtrg+1);
221  bool hasTriggerB = (std::find(fSelectedTriggers.begin(), fSelectedTriggers.end(), ylabel) != fSelectedTriggers.end());
222  if(hasTriggerB) fHistos->FillTH2("hTriggerCorrelation", xlabel, ylabel);
223  }
224  }
225  }
226 
228  AliDebugStream(1) << "Event is selected" << std::endl;
229  return true;
230 }
231 
232 
234  AliDebugStream(1) << "Entering trigger selection\n";
235  fSelectedTriggers.clear();
236  Bool_t isMC = MCEvent() != nullptr;
237 
238  UInt_t selectionstatus = fInputHandler->IsEventSelected();
239  Bool_t isMinBias = selectionstatus & AliVEvent::kINT7,
240  isMinBiasT0 = selectionstatus & AliVEvent::kINT8,
241  isCENT = selectionstatus & AliVEvent::kCentral,
242  isSemiCENT = selectionstatus & AliVEvent::kSemiCentral,
245  emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgn];
246 
247  // check the centrality triggers
248  // temp hack to overcome missing support for 2018 by the physics selection
251  auto triggers = PWG::EMCAL::Triggerinfo::DecodeTriggerString(fInputEvent->GetFiredTriggerClasses().Data());
252  for(auto t : triggers) {
253  if(t.Triggercluster() != "CENT") continue;
254  if(t.Triggerclass() == "CV0H7") isCENT = true;
255  else if(t.Triggerclass() == "CMID7") isSemiCENT = true;
256  }
257  }
258  }
259 
260  if(fExclusiveMinBias){
261  AliDebugStream(1) << "Min bias mode\n";
262  // do not perform EMCAL trigger selection in case only
263  // min. bias trigger is requested:w
264  if(isMinBias) fSelectedTriggers.push_back("MB");
265  if(isMinBiasT0 && fEnableT0Triggers) fSelectedTriggers.push_back("MBT0");
267  if(isCENT) fSelectedTriggers.push_back("CENT");
268  if(isSemiCENT) fSelectedTriggers.push_back("SEMICENT");
269  }
270  return;
271  }
272 
275  triggersel = dynamic_cast<PWG::EMCAL::AliEmcalTriggerDecisionContainer *>(fInputEvent->GetList()->FindObject(fNameTriggerSelectionContainer.Data()));
276  if(!triggersel) {
277  AliErrorStream() << "Trigger selection container requested but not found - not possible to select EMCAL triggers" << std::endl;
278  return;
279  }
280  }
281 
282  AliDebugStream(1) << "Found triggers " << fInputEvent->GetFiredTriggerClasses() << std::endl;
283 
284  for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++) emcalTriggers[itrg] = true;
285  if(fEnableT0Triggers) for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++) emc8Triggers[itrg] = true;
286  if(fEnableNoINTTriggers) for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++) emcNoIntTriggers[itrg] = true;
287  const std::array<std::string, AliEmcalTriggerOfflineSelection::kTrgn> kEmcalSelectTriggerStrings = {
288  "=CEMC7|CEMC8|C0EMC", "EG1|EGA", "EG2", "EJ1|EJE", "EJ2", "=CDMC7|CDMC8|C0DMC", "DG1", "DG2", "DJ1", "DJ2"
289  };
290  if(!isMC){
291  // In case of data select events as bunch-bunch (-B-) events.
292  // Cut not applied in simulations
293  if(fRequireBunchCrossing && ! (fInputEvent->GetFiredTriggerClasses().Contains("-B-") || fInputEvent->GetFiredTriggerClasses().Contains("-S-"))) return;
294 
295  // In case of data use information from the physics selection and event record
296  // Further cleanup of trigger events can be performed depending on the presence
297  // of recalc patches (after masking hot fastors in the trigger maker) above
298  // threshold
299  if(fUseTriggerBits){
300  AliDebugStream(1) << "Require trigger bits" << std::endl;
301  const std::array<ULong_t, AliEmcalTriggerOfflineSelection::kTrgn> kSelectTriggerBits = {
302  AliVEvent::kEMC7|AliVEvent::kEMC8, AliVEvent::kEMCEGA, AliVEvent::kEMCEGA, AliVEvent::kEMCEJE, AliVEvent::kEMCEJE,
303  AliVEvent::kEMC7|AliVEvent::kEMC8, AliVEvent::kEMCEGA, AliVEvent::kEMCEGA, AliVEvent::kEMCEJE, AliVEvent::kEMCEJE
304  };
305  for(int iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
306  if(!(selectionstatus & kSelectTriggerBits[iclass])) {
307  emcNoIntTriggers[iclass] = emc8Triggers[iclass] = emcalTriggers[iclass] = false;
308  }
309  }
310  }
311  auto triggerstring = fInputEvent->GetFiredTriggerClasses();
312  if(triggerstring.Contains("EMC") || triggerstring.Contains("DMC") ||
313  triggerstring.Contains("INT7E") || triggerstring.Contains("INT7D")){ // special conditions for 2015 PbPb
314  // Apply cut on the trigger string - this basically discriminates high- and low-threshold
315  // triggers
316  auto triggers = PWG::EMCAL::Triggerinfo::DecodeTriggerString(fInputEvent->GetFiredTriggerClasses().Data());
317  std::map<int, std::array<bool, 3>> matchedTriggers;
318  for(auto t : triggers) {
319  const auto &triggerclass = t.Triggerclass();
320  if((triggerclass.find("EMC") != std::string::npos) || (triggerclass.find("DMC") != std::string::npos) ||
321  (triggerclass.find("INT7E") != std::string::npos) || (triggerclass.find("INT7D") != std::string::npos))
322  AliDebugStream(1) << GetName() << ": Trigger string " << t.ExpandClassName() << std::endl;
323  else continue; // No EMC / DMC trigger - not to be checked
324  bool isT0trigger = (triggerclass.find("EMC8") != std::string::npos) || (triggerclass.find("DMC8") != std::string::npos) || (triggerclass.find("INT8") != std::string::npos),
325  isVZEROtrigger = (triggerclass.find("EMC7") != std::string::npos) || (triggerclass.find("DMC7") != std::string::npos) || (triggerclass.find("INT7") != std::string::npos);
326  for(auto iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
327  AliDebugStream(1) << "Next trigger: " << kEmcalSelectTriggerStrings[iclass] << std::endl;
328  bool emcalSelectionStatus = MatchTriggerFromPattern(kEmcalSelectTriggerStrings[iclass], triggerclass);
329  if(fUseTriggerSelectionContainer) emcalSelectionStatus = emcalSelectionStatus & MatchTriggerFromContainer(kEmcalSelectTriggerStrings[iclass], triggersel);
330  if(emcalSelectionStatus) {
331  auto entry = matchedTriggers.find(iclass);
332  if(entry == matchedTriggers.end()) {
333  std::array<bool, 3> interactions = {{isVZEROtrigger, isT0trigger, !(isVZEROtrigger || isT0trigger)}};
334  matchedTriggers.insert(std::pair<int, std::array<bool, 3>>(iclass, interactions));
335  } else {
336  auto &interactions = entry->second;
337  if(isVZEROtrigger) interactions[0] = true;
338  if(isT0trigger) interactions[1] = true;
339  if(!(isVZEROtrigger || isT0trigger)) interactions[2] = true;
340  }
341  }
342  }
343  }
344 
345  for(auto iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
346  auto entry = matchedTriggers.find(iclass);
347  if(entry != matchedTriggers.end()){
348  // trigger selected among at least one L0 class
349  const auto &interactions = entry->second;
350  emcalTriggers[iclass] &= interactions[0];
351  emc8Triggers[iclass] &= interactions[1];
352  emcNoIntTriggers[iclass] &= interactions[2];
353  } else {
354  // trigger not selected - mark all cases as false
355  emcalTriggers[iclass] = false;
356  emc8Triggers[iclass] = false;
357  emcNoIntTriggers[iclass] = false;
358  }
359 
360  if(emcalTriggers[iclass])
361  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT7 suite)" << std::endl;
362  if(emc8Triggers[iclass])
363  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT8 suite)" << std::endl;
364  if(emcNoIntTriggers[iclass])
365  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (No INT coincidence)" << std::endl;
366  }
367  }
368  } else {
369  // MC: Use INT7/INT08 for VZERO/TZERO triggers, for EMCAL trigger use trigger selection container
370  bool isT0trigger = selectionstatus & AliVEvent::kINT7, isVZEROtrigger = selectionstatus & AliVEvent::kINT8;
372  for(int iclass = 0; iclass < AliEmcalTriggerOfflineSelection::kTrgn; iclass++){
373  auto emcalSelectionStatus = MatchTriggerFromContainer(kEmcalSelectTriggerStrings[iclass], triggersel);
374  if(isT0trigger) {
375  emc8Triggers[iclass] &= emcalSelectionStatus;
376  }
377  if(isVZEROtrigger){
378  emcalTriggers[iclass] &= emcalSelectionStatus;
379  }
380  if(!(isT0trigger || isVZEROtrigger)){
381  // No coincidence with interaction trigger
382  emcNoIntTriggers[iclass] &= emcalSelectionStatus;
383  }
384  if(emcalTriggers[iclass])
385  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT7 suite)" << std::endl;
386  if(emc8Triggers[iclass])
387  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (INT8 suite)" << std::endl;
388  if(emcNoIntTriggers[iclass])
389  AliDebugStream(1) << GetName() << ": Event selected as trigger " << kEmcalSelectTriggerStrings[iclass] << " (No INT coincidence)" << std::endl;
390  }
391  }
392  }
393 
394  // Apply offline trigger selection: In this case cuts are performed on the
395  // patch energy from EMCAL cells after calibration. This method is most relevant
396  // for simulations. It can have a special use case in data in case a stronger
397  // offline selection is applied in addition to the online selection.
399  for(int itrg = 0; itrg < AliEmcalTriggerOfflineSelection::kTrgn; itrg++)
401  }
402  if(fEnableV0Triggers){
403  if(isMinBias) fSelectedTriggers.push_back("MB");
405  if(isCENT) fSelectedTriggers.push_back("CENT");
406  if(isSemiCENT) fSelectedTriggers.push_back("SEMICENT");
407  }
408  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]){
409  AliDebugStream(1) << "Event selected as EMC7" << std::endl;
410  fSelectedTriggers.push_back("EMC7");
411  if(!isMinBias) fSelectedTriggers.push_back("EMC7excl");
412  }
413  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2]){
414  AliDebugStream(1) << "Event selected as EJ2" << std::endl;
415  fSelectedTriggers.push_back("EJ2");
416  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EJ2excl");
417  }
418  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ1]){
419  AliDebugStream(1) << "Event selected as EJ1" << std::endl;
420  fSelectedTriggers.push_back("EJ1");
421  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("EJ1excl");
422  }
423  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2]){
424  AliDebugStream(1) << "Event selected as EG2" << std::endl;
425  fSelectedTriggers.push_back("EG2");
426  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EG2excl");
427  }
428  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG1]){
429  AliDebugStream(1) << "Event selected as EG1" << std::endl;
430  fSelectedTriggers.push_back("EG1");
431  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("EG1excl");
432  }
433 
435  // Handle DCAL triggers only in case DCAL triggers are enabled,
436  // otherwise ignore results of the online/offline trigger selection
437  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]){
438  AliDebugStream(1) << "Event selected as DMC7" << std::endl;
439  fSelectedTriggers.push_back("DMC7");
440  if(!isMinBias) fSelectedTriggers.push_back("DMC7excl");
441  }
442  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2]){
443  AliDebugStream(1) << "Event selected as DJ2" << std::endl;
444  fSelectedTriggers.push_back("DJ2");
445  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DJ2excl");
446  }
447  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ1]){
448  AliDebugStream(1) << "Event selected as DJ1" << std::endl;
449  fSelectedTriggers.push_back("DJ1");
450  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("DJ1excl");
451  }
452  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2]){
453  AliDebugStream(1) << "Event selected as DG2" << std::endl;
454  fSelectedTriggers.push_back("DG2");
455  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DG2excl");
456  }
457  if(emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG1]){
458  AliDebugStream(1) << "Event selected as DG1" << std::endl;
459  fSelectedTriggers.push_back("DG1");
460  if(!(isMinBias || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcalTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("DG1excl");
461  }
462  }
463  }
464 
465  if(fEnableT0Triggers) {
466  if(isMinBiasT0) fSelectedTriggers.push_back("MBT0");
467  if(emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) {
468  // EMC8 trigger
469  AliDebugStream(1) << "Event selected as EMC8" << std::endl;
470  fSelectedTriggers.push_back("EMC8");
471  if(!isMinBiasT0) fSelectedTriggers.push_back("EMC8excl");
472  }
474  AliDebugStream(1) << "Event selected as EJ2 (EMC8)" << std::endl;
475  fSelectedTriggers.push_back("EMC8EJ2");
476  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EMC8EJ2excl");
477  }
479  AliDebugStream(1) << "Event selected as EJ1 (EMC8)" << std::endl;
480  fSelectedTriggers.push_back("EMC8EJ1");
481  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("EMC8EJ1excl");
482  }
484  AliDebugStream(1) << "Event selected as EG2 (EMC8)" << std::endl;
485  fSelectedTriggers.push_back("EMC8EG2");
486  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0])) fSelectedTriggers.push_back("EMC8EG2excl");
487  }
489  AliDebugStream(1) << "Event selected as EG1 (EMC8)" << std::endl;
490  fSelectedTriggers.push_back("EMC8EG1");
491  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("EMC8EG1excl");
492  }
493 
495  // Handle DCAL triggers only in case DCAL triggers are enabled,
496  // otherwise ignore results of the online/offline trigger selection
498  AliDebugStream(1) << "Event selected as DMC8" << std::endl;
499  fSelectedTriggers.push_back("DMC8");
500  if(!isMinBiasT0) fSelectedTriggers.push_back("DMC8excl");
501  }
503  AliDebugStream(1) << "Event selected as DJ2 (DMC8)" << std::endl;
504  fSelectedTriggers.push_back("DMC8DJ2");
505  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DMC8DJ2excl");
506  }
508  AliDebugStream(1) << "Event selected as DJ1 (DMC8)" << std::endl;
509  fSelectedTriggers.push_back("DMC8DJ1");
510  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("DMC8DJ1excl");
511  }
513  AliDebugStream(1) << "Event selected as DG2 (DMC8)" << std::endl;
514  fSelectedTriggers.push_back("DMC8DG2");
515  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0])) fSelectedTriggers.push_back("DMC8DG2excl");
516  }
518  AliDebugStream(1) << "Event selected as DG1 (DMC8)" << std::endl;
519  fSelectedTriggers.push_back("DMC8DG1");
520  if(!(isMinBiasT0 || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emc8Triggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("DMC8DG1excl");
521  }
522  }
523  }
524 
526  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) {
527  // EMC8 trigger
528  AliDebugStream(1) << "Event selected as 0EMC" << std::endl;
529  fSelectedTriggers.push_back("0EMC");
530  }
531  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2]){
532  AliDebugStream(1) << "Event selected as EJ2 (E0MC)" << std::endl;
533  fSelectedTriggers.push_back("0EMCEJ2");
534  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) fSelectedTriggers.push_back("0EMCEJ2excl");
535  }
536  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ1]){
537  AliDebugStream(1) << "Event selected as EJ1 (0EMC)" << std::endl;
538  fSelectedTriggers.push_back("0EMCEJ1");
539  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEJ2])) fSelectedTriggers.push_back("0EMCEJ1excl");
540  }
541  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2]){
542  AliDebugStream(1) << "Event selected as EG2 (0EMC)" << std::endl;
543  fSelectedTriggers.push_back("0EMCEG2");
544  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0]) fSelectedTriggers.push_back("0EMCEG2excl");
545  }
547  AliDebugStream(1) << "Event selected as EG1 (EMC8)" << std::endl;
548  fSelectedTriggers.push_back("0EMCEG1");
549  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgEG2])) fSelectedTriggers.push_back("0EMCEG1excl");
550  }
551 
553  // Handle DCAL triggers only in case DCAL triggers are enabled,
554  // otherwise ignore results of the online/offline trigger selection
555  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]){
556  AliDebugStream(1) << "Event selected as 0DMC" << std::endl;
557  fSelectedTriggers.push_back("0DMC");
558  }
559  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2]){
560  AliDebugStream(1) << "Event selected as DJ2 (0DMC)" << std::endl;
561  fSelectedTriggers.push_back("0DMCDJ2");
562  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]) fSelectedTriggers.push_back("0DMCDJ2excl");
563  }
564  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ1]){
565  AliDebugStream(1) << "Event selected as DJ1 (0DMC)" << std::endl;
566  fSelectedTriggers.push_back("0DMCDJ1");
567  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDJ2])) fSelectedTriggers.push_back("0DMCDJ1excl");
568  }
569  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2]){
570  AliDebugStream(1) << "Event selected as DG2 (0DMC)" << std::endl;
571  fSelectedTriggers.push_back("0DMCDG2");
572  if(!emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0]) fSelectedTriggers.push_back("0DMCDG2excl");
573  }
574  if(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG1]){
575  AliDebugStream(1) << "Event selected as DG1 (0DMC)" << std::endl;
576  fSelectedTriggers.push_back("0DMCDG1");
577  if(!(emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDL0] || emcNoIntTriggers[AliEmcalTriggerOfflineSelection::kTrgDG2])) fSelectedTriggers.push_back("0DMCDG1excl");
578  }
579  }
580  }
581 }
582 
585 
586  if(!fLocalInitialized){
587  return;
588  }
589 
590  // Handle OADB container with downscaling factors
591  if(fNameDownscaleOADB.Length()){
592  if(fNameDownscaleOADB.Contains("alien://") && ! gGrid) TGrid::Connect("alien://");
593  fDownscaleOADB = new AliOADBContainer("AliEmcalDownscaleFactors");
594  fDownscaleOADB->InitFromFile(fNameDownscaleOADB.Data(), "AliEmcalDownscaleFactors");
595  }
596 }
597 
599  if(fDownscaleOADB){
600  fDownscaleFactors = static_cast<TObjArray *>(fDownscaleOADB->GetObject(runnumber));
601  }
603 
604  // Log info for downscale factors
605  if(!fDownscaleFactors || !fDownscaleFactors->GetEntries()){
606  AliInfoStream() << GetName() << ": No downscale factors provided for run " << runnumber << std::endl;
607  } else {
608  AliInfoStream() << GetName() << ": Downscale factors used for run " << runnumber << std::endl;
609  for(auto e : *fDownscaleFactors){
610  TParameter<double> *dfactor = static_cast<TParameter<double> *>(e);
611  AliInfoStream() << GetName() << ": Trigger " << dfactor->GetName() << ", downscale factor " << dfactor->GetVal() << std::endl;
612  }
613  }
614 }
615 
616 std::vector<TString> AliAnalysisTaskEmcalTriggerBase::GetSupportedTriggers(Bool_t useExclusiveTriggers) const {
617  // Exclusive means classes without lower trigger classes (which are downscaled) -
618  // in order to make samples statistically independent: MBExcl means MinBias && !EMCAL trigger
619  std::vector<TString> triggers;
620  const std::array<TString, 5> emcaltriggers = {{"EMC7", "EJ1", "EJ2", "EG1", "EG2"}},
621  dcaltriggers = {{"DMC7", "DJ1", "DJ2", "DG1", "DG2"}},
622  emcalexclusive = {{"EMC7excl", "EG2excl", "EJ2excl", "EJ1excl", "EG1excl"}},
623  dcalexclusive = {{"DMC7excl", "DG2excl", "DJ2excl", "DJ1excl", "DG1excl"}},
624  t0triggers = {{"EMC8", "EMC8EJ1", "EMC8EJ2", "EMC8EG1", "EMC8EG2"}},
625  t0exclusive = {{"EMC8excl", "EMC8EG2excl", "EMC8EJ2excl", "EMC8EJ1excl", "EMC8EG1excl"}},
626  t0dcaltriggers = {{"DMC8", "DMC8DJ1", "DMC8DJ2", "DMC8DG1", "DMC8DG2"}},
627  t0dcalexclusive = {{"DMC8excl", "DMC8DG2excl", "DMC8DJ2excl", "DMC8DJ1excl", "DMC8DG1excl"}},
628  nointEMCAL = {{"0EMC", "0EMCEJ1", "0EMCEJ2", "0EMCEG1", "0EMCEG2"}},
629  nointDCAL = {{"0DMC", "0DMCDJ1", "0DMCDJ2", "0DMCDG1", "0DMCDG2"}};
630  const std::array<TString, 4> nointemcalexclusive = {{"0EMCEG2excl", "0EMCEJ2excl", "0EMCEJ1excl", "0EMCEG1excl"}},
631  nointdcalexclusive = {{"0DMCDG2excl", "0DMCDJ2excl", "0DMCDJ1excl", "0DMCDG1excl"}};
632  const std::array<TString, 2> centralitytriggers = {{"CENT", "SEMICENT"}};
633  if(fEnableV0Triggers){
634  triggers.push_back("MB"); // Min. Bias always enabled
635  if(!fExclusiveMinBias){
636  for(const auto &t : emcaltriggers) triggers.push_back(t);
637  if(useExclusiveTriggers)
638  for(const auto &t : emcalexclusive) triggers.push_back(t);
639  }
641  for(const auto &t : dcaltriggers) triggers.push_back(t);
642  if(useExclusiveTriggers)
643  for(const auto &t : dcalexclusive) triggers.push_back(t);
644  }
646  for(const auto &t : centralitytriggers) triggers.push_back(t);
647  }
648  }
649  if(fEnableT0Triggers){
650  triggers.push_back("MBT0");
651  if(!fExclusiveMinBias){
652  for(const auto &t: t0triggers) triggers.push_back(t);
653  if(useExclusiveTriggers)
654  for(const auto &t : t0exclusive) triggers.push_back(t);
655  }
657  for(const auto &t: t0dcaltriggers) triggers.push_back(t);
658  if(useExclusiveTriggers)
659  for(const auto &t : t0dcalexclusive) triggers.push_back(t);
660  }
661  }
662  if(fEnableNoINTTriggers) {
663  // No MB trigger since no interaction trigger
664  if(!fExclusiveMinBias){
665  for(const auto &t: nointEMCAL) triggers.push_back(t);
666  if(useExclusiveTriggers)
667  for(const auto &t : nointemcalexclusive) triggers.push_back(t);
668  }
670  for(const auto &t: nointDCAL) triggers.push_back(t);
671  if(useExclusiveTriggers)
672  for(const auto &t : nointdcalexclusive) triggers.push_back(t);
673  }
674  }
675  return triggers;
676 }
677 
678 bool AliAnalysisTaskEmcalTriggerBase::MatchTriggerFromPattern(const std::string &pattern, const std::string &trigger) const {
679  std::string patternstring = pattern;
680  bool isEqual = pattern[0] == '=';
681  if(pattern[0] == '=') patternstring = pattern.substr(1);
682  std::vector<std::string> classes;
683  if(patternstring.find("|") != std::string::npos){
684  std::stringstream decoder(patternstring);
685  std::string tmp;
686  while(std::getline(decoder, tmp, '|')) classes.emplace_back(tmp);
687  } else classes.emplace_back(patternstring);
688  bool found(false);
689  for(const auto &t : classes){
690  if(isEqual && (trigger == t)) {
691  found = true;
692  break;
693  }
694  if(!isEqual && (trigger.find(t) != std::string::npos)){
695  found = true;
696  break;
697  }
698  }
699  return found;
700 }
701 
703  if(!trgsel) return false;
704  std::string patternstring = pattern;
705  if(pattern[0] == '=') patternstring = pattern.substr(1);
706  std::vector<std::string> classes;
707  if(patternstring.find("|") != std::string::npos){
708  std::stringstream decoder(patternstring);
709  std::string tmp;
710  while(std::getline(decoder, tmp, '|')) classes.emplace_back(tmp);
711  } else classes.emplace_back(patternstring);
712  bool found(false);
713  for(const auto &t : classes) {
714  if(trgsel->IsEventSelected(t.data())) {
715  found = true;
716  break;
717  }
718  }
719  return found;
720 }
721 
723  if(fDownscaleFactors){
724  TParameter<double> *result(nullptr);
725  // Downscaling only done on MB, L0 and the low threshold triggers
726  if(triggerclass.Contains("MB")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("INT7"));
727  else if(triggerclass.Contains("EMC7")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EMC7"));
728  else if(triggerclass.Contains("DMC7")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DMC7"));
729  else if(triggerclass.Contains("EJ2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EJ2"));
730  else if(triggerclass.Contains("EJ1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EJ1"));
731  else if(triggerclass.Contains("EG2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EG2"));
732  else if(triggerclass.Contains("EG1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("EG1"));
733  else if(triggerclass.Contains("DG2")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DG2"));
734  else if(triggerclass.Contains("DG1")) result = static_cast<TParameter<double> *>(fDownscaleFactors->FindObject("DG1"));
735  double triggerweight = 1.;
736  if(result) triggerweight = 1./result->GetVal();
737  AliDebugStream(1) << "Using trigger weight " << triggerweight << " for trigger " << triggerclass << std::endl;
738  return triggerweight;
739  } else {
740  AliDebugStream(1) << "No downscale factors loaded - using trigger weight 1" << std::endl;
741  }
742  return 1.;
743 }
744 
746  AliInfoStream() << "Reading downscale factors from OCDB for run " << fInputEvent->GetRunNumber() << std::endl;
747  if(!fDownscaleFactors){
749  fDownscaleFactors->SetOwner(true);
750  }
751  fDownscaleFactors->Clear();
753  if(downscaleOCDB->GetCurrentRun() != fInputEvent->GetRunNumber()) downscaleOCDB->SetRun(fInputEvent->GetRunNumber());
754  const std::array<TString, 11> khwtriggers = {"INT7", "EMC7", "DMC7", "EJ1", "EJ2", "DJ1", "DJ2", "EG1", "EG2", "DG1", "DG2"};
755  std::vector<TString> runtriggers = downscaleOCDB->GetTriggerClasses();
756  for(const auto &t : khwtriggers){
757  std::function<bool (TString)> triggerfinder = [t](const TString &test) -> bool {
758  if(!test.Contains(t + "-B-")) return false;
759  return true;
760  };
761  auto entry = std::find_if(runtriggers.begin(), runtriggers.end(), triggerfinder);
762  if(entry != runtriggers.end()){
763  TString triggername = *entry;
764  double downscalefactor = downscaleOCDB->GetDownscaleFactorForTriggerClass(triggername);
765  AliInfoStream() << "Applying downscale factor " << downscalefactor << " for trigger " << t << " (" << triggername << ") for run " << fInputEvent->GetRunNumber() << std::endl;
766  fDownscaleFactors->Add(new TParameter<double>(t, TMath::Abs(downscalefactor) < DBL_EPSILON ? 1 : downscalefactor));
767  } else {
768  AliErrorStream() << "No downscale factor found for trigger " << t << " for run " << fInputEvent->GetRunNumber() << std::endl;
769  }
770  }
771 }
772 
773 } /* 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)
Bool_t fSelectCentralityTriggers2018
Select centrality triggers 2018 based on trigger string (missing support by physics selection yet) ...
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.