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