AliPhysics  master (3d17d9d)
AliAnalysisTaskEmcal.cxx
Go to the documentation of this file.
1 /************************************************************************************
2  * Copyright (C) 2017, Copyright Holders of the ALICE Collaboration *
3  * All rights reserved. *
4  * *
5  * Redistribution and use in source and binary forms, with or without *
6  * modification, are permitted provided that the following conditions are met: *
7  * * Redistributions of source code must retain the above copyright *
8  * notice, this list of conditions and the following disclaimer. *
9  * * Redistributions in binary form must reproduce the above copyright *
10  * notice, this list of conditions and the following disclaimer in the *
11  * documentation and/or other materials provided with the distribution. *
12  * * Neither the name of the <organization> nor the *
13  * names of its contributors may be used to endorse or promote products *
14  * derived from this software without specific prior written permission. *
15  * *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND *
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
19  * DISCLAIMED. IN NO EVENT SHALL ALICE COLLABORATION BE LIABLE FOR ANY *
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
26  ************************************************************************************/
27 #include <RVersion.h>
28 #include <iostream>
29 #include <memory>
30 
31 #include <TClonesArray.h>
32 #include <AliEmcalList.h>
33 #include <TObject.h>
34 #include <TObjString.h>
35 #include <TH1F.h>
36 #include <TProfile.h>
37 #include <TSystem.h>
38 #include <TFile.h>
39 #include <TChain.h>
40 #include <TKey.h>
41 
42 #include "AliAnalysisTaskEmcal.h"
43 #include "AliAnalysisUtils.h"
44 #include "AliAODEvent.h"
45 #include "AliAODMCHeader.h"
46 #include "AliAODTrack.h"
47 #include "AliAnalysisManager.h"
48 #include "AliCentrality.h"
50 #include "AliEMCALGeometry.h"
51 #include "AliEmcalPythiaInfo.h"
52 #include "AliEMCALTriggerPatchInfo.h"
53 #include "AliESDEvent.h"
54 #include "AliAODInputHandler.h"
55 #include "AliESDInputHandler.h"
56 #include "AliEventplane.h"
57 #include "AliGenPythiaEventHeader.h"
58 #include "AliGenHerwigEventHeader.h"
59 #include "AliInputEventHandler.h"
60 #include "AliLog.h"
61 #include "AliMCEvent.h"
62 #include "AliMCParticle.h"
63 #include "AliMultiInputEventHandler.h"
64 #include "AliMultSelection.h"
65 #include "AliStack.h"
66 #include "AliVCaloTrigger.h"
67 #include "AliVCluster.h"
68 #include "AliVEventHandler.h"
69 #include "AliVParticle.h"
70 #include "AliNanoAODHeader.h"
72 
74 
76 ClassImp(AliAnalysisTaskEmcal);
78 
80  AliAnalysisTaskSE("AliAnalysisTaskEmcal"),
81  fPythiaInfoName(""),
82  fForceBeamType(kNA),
83  fGeneralHistograms(kFALSE),
84  fLocalInitialized(kFALSE),
85  fFileChanged(kTRUE),
86  fCreateHisto(kTRUE),
87  fCaloCellsName(),
88  fCaloTriggersName(),
89  fCaloTriggerPatchInfoName(),
90  fMinCent(-999),
91  fMaxCent(-999),
92  fMinVz(-999),
93  fMaxVz(999),
94  fMinVertexContrib(1),
95  fTrackPtCut(0),
96  fMinNTrack(0),
97  fZvertexDiff(0.5),
98  fUseAliAnaUtils(kFALSE),
99  fRejectPileup(kFALSE),
100  fTklVsClusSPDCut(kFALSE),
101  fOffTrigger(AliVEvent::kAny),
102  fTrigClass(),
103  fMinBiasRefTrigger("CINT7-B-NOPF-ALLNOTRD"),
104  fTriggerTypeSel(kND),
105  fNbins(250),
106  fMinBinPt(0),
107  fMaxBinPt(250),
108  fMinPtTrackInEmcal(0),
109  fEventPlaneVsEmcal(-1),
110  fMinEventPlane(-1e6),
111  fMaxEventPlane(1e6),
112  fCentEst("V0M"),
113  fIsEmbedded(kFALSE),
114  fIsPythia(kFALSE),
115  fIsHerwig(kFALSE),
116  fGetPtHardBinFromName(kTRUE),
117  fSelectPtHardBin(-999),
118  fMinMCLabel(0),
119  fMCLabelShift(0),
120  fNcentBins(4),
121  fNeedEmcalGeom(kTRUE),
122  fParticleCollArray(),
123  fClusterCollArray(),
124  fTriggers(0),
125  fEMCalTriggerMode(kOverlapWithLowThreshold),
126  fUseNewCentralityEstimation(kFALSE),
127  fGeneratePythiaInfoObject(kFALSE),
128  fUsePtHardBinScaling(kFALSE),
129  fUseXsecFromHeader(kFALSE),
130  fMCRejectFilter(kFALSE),
131  fCountDownscaleCorrectedEvents(kFALSE),
132  fUseBuiltinEventSelection(kFALSE),
133  fPtHardAndJetPtFactor(0.),
134  fPtHardAndClusterPtFactor(0.),
135  fPtHardAndTrackPtFactor(0.),
136  fRunNumber(-1),
137  fAliEventCuts(kFALSE),
138  fAliAnalysisUtils(nullptr),
139  fIsEsd(kFALSE),
140  fGeom(nullptr),
141  fTracks(nullptr),
142  fCaloClusters(nullptr),
143  fCaloCells(nullptr),
144  fCaloTriggers(nullptr),
145  fTriggerPatchInfo(nullptr),
146  fCent(0),
147  fCentBin(-1),
148  fEPV0(-1.0),
149  fEPV0A(-1.0),
150  fEPV0C(-1.0),
151  fNVertCont(0),
152  fNVertSPDCont(0),
153  fBeamType(kNA),
154  fPythiaHeader(nullptr),
155  fHerwigHeader(nullptr),
156  fPtHard(0),
157  fPtHardBin(0),
158  fPtHardBinGlobal(-1),
159  fPtHardInitialized(false),
160  fNPtHardBins(11),
161  fPtHardBinning(),
162  fNTrials(0),
163  fXsection(0),
164  fPythiaInfo(nullptr),
165  fOutput(nullptr),
166  fHistEventCount(nullptr),
167  fHistTrialsAfterSel(nullptr),
168  fHistEventsAfterSel(nullptr),
169  fHistXsectionAfterSel(nullptr),
170  fHistTrials(nullptr),
171  fHistEvents(nullptr),
172  fHistXsection(nullptr),
173  fHistPtHard(nullptr),
174  fHistPtHardCorr(nullptr),
175  fHistPtHardCorrGlobal(nullptr),
176  fHistPtHardBinCorr(nullptr),
177  fHistCentrality(nullptr),
178  fHistZVertex(nullptr),
179  fHistEventPlane(nullptr),
180  fHistEventRejection(nullptr),
181  fHistTriggerClasses(nullptr),
182  fHistTriggerClassesCorr(nullptr)
183 {
184  fVertex[0] = 0;
185  fVertex[1] = 0;
186  fVertex[2] = 0;
187  fVertexSPD[0] = 0;
188  fVertexSPD[1] = 0;
189  fVertexSPD[2] = 0;
190 
191  fParticleCollArray.SetOwner(kTRUE);
192  fClusterCollArray.SetOwner(kTRUE);
193 }
194 
196  AliAnalysisTaskSE(name),
197  fPythiaInfoName(""),
199  fGeneralHistograms(kFALSE),
200  fLocalInitialized(kFALSE),
201  fFileChanged(kFALSE),
202  fCreateHisto(histo),
203  fCaloCellsName(),
206  fMinCent(-999),
207  fMaxCent(-999),
208  fMinVz(-999),
209  fMaxVz(999),
211  fTrackPtCut(0),
212  fMinNTrack(0),
213  fZvertexDiff(0.5),
214  fUseAliAnaUtils(kFALSE),
215  fRejectPileup(kFALSE),
216  fTklVsClusSPDCut(kFALSE),
217  fOffTrigger(AliVEvent::kAny),
218  fTrigClass(),
219  fMinBiasRefTrigger("CINT7-B-NOPF-ALLNOTRD"),
221  fNbins(250),
222  fMinBinPt(0),
223  fMaxBinPt(250),
225  fEventPlaneVsEmcal(-1),
226  fMinEventPlane(-1e6),
227  fMaxEventPlane(1e6),
228  fCentEst("V0M"),
229  fIsEmbedded(kFALSE),
230  fIsPythia(kFALSE),
231  fIsHerwig(kFALSE),
232  fGetPtHardBinFromName(kTRUE),
233  fSelectPtHardBin(-999),
234  fMinMCLabel(0),
235  fMCLabelShift(0),
236  fNcentBins(4),
237  fNeedEmcalGeom(kTRUE),
240  fTriggers(0),
244  fUsePtHardBinScaling(kFALSE),
245  fUseXsecFromHeader(kFALSE),
246  fMCRejectFilter(kFALSE),
252  fRunNumber(-1),
253  fAliEventCuts(kFALSE),
255  fIsEsd(kFALSE),
256  fGeom(nullptr),
257  fTracks(nullptr),
262  fCent(0),
263  fCentBin(-1),
264  fEPV0(-1.0),
265  fEPV0A(-1.0),
266  fEPV0C(-1.0),
267  fNVertCont(0),
268  fNVertSPDCont(0),
269  fBeamType(kNA),
272  fPtHard(0),
273  fPtHardBin(0),
274  fPtHardBinGlobal(-1),
275  fPtHardInitialized(false),
276  fNPtHardBins(11),
277  fPtHardBinning(),
278  fNTrials(0),
279  fXsection(0),
280  fPythiaInfo(0),
281  fOutput(nullptr),
299 {
300  fVertex[0] = 0;
301  fVertex[1] = 0;
302  fVertex[2] = 0;
303  fVertexSPD[0] = 0;
304  fVertexSPD[1] = 0;
305  fVertexSPD[2] = 0;
306  fParticleCollArray.SetOwner(kTRUE);
307  fClusterCollArray.SetOwner(kTRUE);
308  // Do not perform trigger selection in the AliEvent cuts but let the task do this before
309  fAliEventCuts.OverrideAutomaticTriggerSelection(AliVEvent::kAny, true);
310 
311  if (fCreateHisto) {
312  DefineOutput(1, AliEmcalList::Class());
313  }
314 }
315 
317 {
318  if(fOutput) delete fOutput;
320  if(fPythiaInfo) delete fPythiaInfo;
321 }
322 
324 {
326  if (cont) cont->SetClusPtCut(cut);
327  else AliError(Form("%s in SetClusPtCut(...): container %d not found",GetName(),c));
328 }
329 
331 {
333  if (cont) cont->SetClusTimeCut(min,max);
334  else AliError(Form("%s in SetClusTimeCut(...): container %d not found",GetName(),c));
335 }
336 
338 {
340  if (cont) cont->SetParticlePtCut(cut);
341  else AliError(Form("%s in SetTrackPtCut(...): container %d not found",GetName(),c));
342 
343  fTrackPtCut = cut;
344 }
345 
347 {
349  if (cont) cont->SetParticleEtaLimits(min,max);
350  else AliError(Form("%s in SetTrackPtCut(...): container %d not found",GetName(),c));
351 }
352 
354 {
356  if (cont) cont->SetParticlePhiLimits(min,max);
357  else AliError(Form("%s in SetTrackPhiLimits(...): container %d not found",GetName(),c));
358 }
359 
361 {
362  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
363  if (mgr) {
364  AliVEventHandler *evhand = mgr->GetInputEventHandler();
365  if (evhand) {
366  if (evhand->InheritsFrom("AliESDInputHandler")) {
367  fIsEsd = kTRUE;
368  }
369  else {
370  fIsEsd = kFALSE;
371  }
372  }
373  else {
374  AliError("Event handler not found!");
375  }
376  }
377  else {
378  AliError("Analysis manager not found!");
379  }
380 
381 
382  if (!fCreateHisto)
383  return;
384 
385  OpenFile(1);
386  fOutput = new AliEmcalList();
388  fOutput->SetOwner();
389 
390  if (fForceBeamType == kpp)
391  fNcentBins = 1;
392 
393  if (!fGeneralHistograms)
394  return;
395 
396  if (fIsPythia || fIsHerwig) {
397  fHistTrialsAfterSel = new TH1F("fHistTrialsAfterSel", "fHistTrialsAfterSel", fNPtHardBins, 0, fNPtHardBins);
398  fHistTrialsAfterSel->GetXaxis()->SetTitle("p_{T} hard bin");
399  fHistTrialsAfterSel->GetYaxis()->SetTitle("trials");
401 
402  fHistEventsAfterSel = new TH1F("fHistEventsAfterSel", "fHistEventsAfterSel", fNPtHardBins, 0, fNPtHardBins);
403  fHistEventsAfterSel->GetXaxis()->SetTitle("p_{T} hard bin");
404  fHistEventsAfterSel->GetYaxis()->SetTitle("total events");
406 
407  fHistXsectionAfterSel = new TProfile("fHistXsectionAfterSel", "fHistXsectionAfterSel", fNPtHardBins, 0, fNPtHardBins);
408  fHistXsectionAfterSel->GetXaxis()->SetTitle("p_{T} hard bin");
409  fHistXsectionAfterSel->GetYaxis()->SetTitle("xsection");
411 
412  fHistTrials = new TH1F("fHistTrials", "fHistTrials", fNPtHardBins, 0, fNPtHardBins);
413  fHistTrials->GetXaxis()->SetTitle("p_{T} hard bin");
414  fHistTrials->GetYaxis()->SetTitle("trials");
415  fOutput->Add(fHistTrials);
416 
417  fHistEvents = new TH1F("fHistEvents", "fHistEvents", fNPtHardBins, 0, fNPtHardBins);
418  fHistEvents->GetXaxis()->SetTitle("p_{T} hard bin");
419  fHistEvents->GetYaxis()->SetTitle("total events");
420  fOutput->Add(fHistEvents);
421 
422  fHistXsection = new TProfile("fHistXsection", "fHistXsection", fNPtHardBins, 0, fNPtHardBins);
423  fHistXsection->GetXaxis()->SetTitle("p_{T} hard bin");
424  fHistXsection->GetYaxis()->SetTitle("xsection");
425  fOutput->Add(fHistXsection);
426 
427  // Set the bin labels
428  Bool_t binningAvailable = false;
429  if(fPtHardBinning.GetSize() > 0) {
430  AliInfoStream() << "Using custom pt-hard binning" << std::endl;
431  if(fPtHardBinning.GetSize() == fNPtHardBins + 1) binningAvailable = true;
432  else AliErrorStream() << "Pt-hard binning (" << fPtHardBinning.GetSize() -1 << ") does not match the amount of bins (" << fNPtHardBins << ")" << std::endl;
433  } else {
434  // Check if we fall back to the default binning
435  if(fNPtHardBins == 11) {
436  AliInfoStream() << "11 pt-hard bins - fall back to default binning for bin labels" << std::endl;
437  const Int_t kDefaultPtHardBinning[12] = {0,5,11,21,36,57, 84,117,152,191,234,1000000};
438  fPtHardBinning.Set(12);
439  for(Int_t ib = 0; ib < 12; ib++) fPtHardBinning[ib] = kDefaultPtHardBinning[ib];
440  binningAvailable = true;
441  } else {
442  AliErrorStream() << "No default binning available for " << fNPtHardBins << " pt-hard bins - bin labels will not be set." << std::endl;
443  }
444  }
445 
446  if(binningAvailable){
447  for (Int_t i = 0; i < fNPtHardBins; i++) {
448  fHistTrialsAfterSel->GetXaxis()->SetBinLabel(i+1, Form("%d-%d",fPtHardBinning[i],fPtHardBinning[i+1]));
449  fHistEventsAfterSel->GetXaxis()->SetBinLabel(i+1, Form("%d-%d",fPtHardBinning[i],fPtHardBinning[i+1]));
450  fHistXsectionAfterSel->GetXaxis()->SetBinLabel(i+1, Form("%d-%d",fPtHardBinning[i],fPtHardBinning[i+1]));
451 
452  fHistTrials->GetXaxis()->SetBinLabel(i+1, Form("%d-%d",fPtHardBinning[i],fPtHardBinning[i+1]));
453  fHistXsection->GetXaxis()->SetBinLabel(i+1, Form("%d-%d",fPtHardBinning[i],fPtHardBinning[i+1]));
454  fHistEvents->GetXaxis()->SetBinLabel(i+1, Form("%d-%d",fPtHardBinning[i],fPtHardBinning[i+1]));
455  }
456  } else {
457  AliErrorStream() << "No suitable binning available - skipping bin labels" << std::endl;
458  }
459 
460 
461  fHistPtHard = new TH1F("fHistPtHard", "fHistPtHard", fNbins*2, fMinBinPt, fMaxBinPt*4);
462  fHistPtHard->GetXaxis()->SetTitle("p_{T,hard} (GeV/c)");
463  fHistPtHard->GetYaxis()->SetTitle("counts");
464  fOutput->Add(fHistPtHard);
465 
466  // Pt-hard correlation histograms (debugging)
467  fHistPtHardCorr = new TH2F("fHistPtHardCorr", "Correlation between pt-hard value and binning", fNPtHardBins, -0.5, fNPtHardBins - 0.5, 1000, 0., 500.);
468  fHistPtHardCorr->SetXTitle("p_{T,hard bin}");
469  fHistPtHardCorr->SetYTitle("p_{T,hard value}");
470  fOutput->Add(fHistPtHardCorr);
471 
472  fHistPtHardCorrGlobal = new TH2F("fHistPtHardCorrGlobal", "Correlation between global pt-hard value and binning", fNPtHardBins, -0.5, fNPtHardBins - 0.5, 1000, 0., 500.);
473  fHistPtHardCorrGlobal->SetXTitle("p_{T,hard} bin_{global}");
474  fHistPtHardCorrGlobal->SetYTitle("p_{T,hard} value");
476 
477  fHistPtHardBinCorr = new TH2F("fHistPtHardBinCorr", "Correlation between global and local pt-hard bin", fNPtHardBins, -0.5, fNPtHardBins - 0.5, fNPtHardBins, -0.5, fNPtHardBins);
478  fHistPtHardBinCorr->SetXTitle("p_{T,hard} bin_{local}");
479  fHistPtHardBinCorr->SetYTitle("p_{T,hard} bin_{global}");
481  }
482 
483  fHistZVertex = new TH1F("fHistZVertex","Z vertex position", 60, -30, 30);
484  fHistZVertex->GetXaxis()->SetTitle("z");
485  fHistZVertex->GetYaxis()->SetTitle("counts");
486  fOutput->Add(fHistZVertex);
487 
488  if (fForceBeamType != kpp) {
489  fHistCentrality = new TH1F("fHistCentrality","Event centrality distribution", 200, 0, 100);
490  fHistCentrality->GetXaxis()->SetTitle("Centrality (%)");
491  fHistCentrality->GetYaxis()->SetTitle("counts");
492  fOutput->Add(fHistCentrality);
493 
494  fHistEventPlane = new TH1F("fHistEventPlane","Event plane", 120, -TMath::Pi(), TMath::Pi());
495  fHistEventPlane->GetXaxis()->SetTitle("event plane");
496  fHistEventPlane->GetYaxis()->SetTitle("counts");
497  fOutput->Add(fHistEventPlane);
498  }
499 
501  fHistEventRejection = new TH1F("fHistEventRejection","Reasons to reject event",20,0,20);
502 #if ROOT_VERSION_CODE < ROOT_VERSION(6,4,2)
503  fHistEventRejection->SetBit(TH1::kCanRebin);
504 #else
505  fHistEventRejection->SetCanExtend(TH1::kAllAxes);
506 #endif
507  fHistEventRejection->GetXaxis()->SetBinLabel(1,"PhysSel");
508  fHistEventRejection->GetXaxis()->SetBinLabel(2,"trigger");
509  fHistEventRejection->GetXaxis()->SetBinLabel(3,"trigTypeSel");
510  fHistEventRejection->GetXaxis()->SetBinLabel(4,"Cent");
511  fHistEventRejection->GetXaxis()->SetBinLabel(5,"vertex contr.");
512  fHistEventRejection->GetXaxis()->SetBinLabel(6,"Vz");
513  fHistEventRejection->GetXaxis()->SetBinLabel(7,"VzSPD");
514  fHistEventRejection->GetXaxis()->SetBinLabel(8,"trackInEmcal");
515  fHistEventRejection->GetXaxis()->SetBinLabel(9,"minNTrack");
516  fHistEventRejection->GetXaxis()->SetBinLabel(10,"VtxSel2013pA");
517  fHistEventRejection->GetXaxis()->SetBinLabel(11,"PileUp");
518  fHistEventRejection->GetXaxis()->SetBinLabel(12,"EvtPlane");
519  fHistEventRejection->GetXaxis()->SetBinLabel(13,"SelPtHardBin");
520  fHistEventRejection->GetXaxis()->SetBinLabel(14,"Bkg evt");
521  fHistEventRejection->GetYaxis()->SetTitle("counts");
523  }
524  else {
525  fAliEventCuts.AddQAplotsToList(fOutput);
526  }
527 
528  fHistTriggerClasses = new TH1F("fHistTriggerClasses","fHistTriggerClasses",3,0,3);
529 #if ROOT_VERSION_CODE < ROOT_VERSION(6,4,2)
530  fHistTriggerClasses->SetBit(TH1::kCanRebin);
531 #else
532  fHistTriggerClasses->SetCanExtend(TH1::kAllAxes);
533 #endif
535 
537  fHistTriggerClassesCorr = new TH1F("fHistTriggerClassesCorr","fHistTriggerClassesCorr",3,0,3);
538 #if ROOT_VERSION_CODE < ROOT_VERSION(6,4,2)
539  fHistTriggerClassesCorr->SetBit(TH1::kCanRebin);
540 #else
541  fHistTriggerClassesCorr->SetCanExtend(TH1::kAllAxes);
542 #endif
544  }
545 
546  fHistEventCount = new TH1F("fHistEventCount","fHistEventCount",2,0,2);
547  fHistEventCount->GetXaxis()->SetBinLabel(1,"Accepted");
548  fHistEventCount->GetXaxis()->SetBinLabel(2,"Rejected");
549  fHistEventCount->GetYaxis()->SetTitle("counts");
550  fOutput->Add(fHistEventCount);
551 
552  PostData(1, fOutput);
553 }
554 
556 {
557  if (fIsPythia || fIsHerwig) {
558  // Protection: In case the pt-hard bin handling is not initialized we fall back to the
559  // global pt-hard bin (usually 0) in order to aviod mismatch between histograms before
560  // and after selection
564  fHistPtHard->Fill(fPtHard);
565  if(fPtHardInitialized){
566  fHistPtHardCorr->Fill(fPtHardBin, fPtHard);
568  fHistPtHardBinCorr->Fill(fPtHardBin, fPtHardBinGlobal);
569  }
570  }
571 
572 
573  fHistZVertex->Fill(fVertex[2]);
574 
575  if (fForceBeamType != kpp) {
576  fHistCentrality->Fill(fCent);
577  fHistEventPlane->Fill(fEPV0);
578  }
579 
580  std::unique_ptr<TObjArray> triggerClasses(InputEvent()->GetFiredTriggerClasses().Tokenize(" "));
581  TObjString* triggerClass(nullptr);
582  for(auto trg : *triggerClasses){
583  triggerClass = static_cast<TObjString*>(trg);
584  fHistTriggerClasses->Fill(triggerClass->GetString(), 1);
585  }
586 
588  // downscale-corrected number of events are calculated based on the min. bias reference
589  // Formula: N_corr = N_MB * d_Trg/d_{Min_Bias}
590  if(InputEvent()->GetFiredTriggerClasses().Contains(fMinBiasRefTrigger)){
592  Double_t downscaleref = downscalefactors->GetDownscaleFactorForTriggerClass(fMinBiasRefTrigger);
593  for(auto t : downscalefactors->GetTriggerClasses()){
594  Double_t downscaletrg = downscalefactors->GetDownscaleFactorForTriggerClass(t);
595  fHistTriggerClassesCorr->Fill(t, downscaletrg/downscaleref);
596  }
597  }
598  }
599 
600  return kTRUE;
601 }
602 
604 {
605  if (!fLocalInitialized){
606  ExecOnce();
607  UserExecOnce();
608  }
609 
610  if (!fLocalInitialized)
611  return;
612 
613  if(fFileChanged){
614  FileChanged();
615  fFileChanged = kFALSE;
616  }
617 
618  if (!RetrieveEventObjects())
619  return;
620 
621  if(InputEvent()->GetRunNumber() != fRunNumber){
622  fRunNumber = InputEvent()->GetRunNumber();
625  }
626 
627  // Apply fallback for pythia cross section if needed
629  AliDebugStream(1) << "Fallback to cross section from pythia header required" << std::endl;
630  /*
631  // Get the pthard bin
632  Float_t pthard = fPythiaHeader->GetPtHard();
633  int pthardbin = 0;
634  if(fPtHardBinning.GetSize()){
635  for(int ib = 0; ib < fNPtHardBins; ib++){
636  if(pthard >= static_cast<Float_t>(fPtHardBinning[ib]) && pthard < static_cast<Float_t>(fPtHardBinning[ib+1])) {
637  pthardbin = ib;
638  break;
639  }
640  }
641  }
642  */
643  fHistXsection->Fill(fPtHardBinGlobal, fPythiaHeader->GetXsection());
644  }
645 
646  if (IsEventSelected()) {
647  if (fGeneralHistograms) fHistEventCount->Fill("Accepted",1);
648  }
649  else {
650  if (fGeneralHistograms) fHistEventCount->Fill("Rejected",1);
651  return;
652  }
653 
655  if (!FillGeneralHistograms())
656  return;
657  }
658 
659  if (!Run())
660  return;
661 
662  if (fCreateHisto) {
663  if (!FillHistograms())
664  return;
665  }
666 
667  if (fCreateHisto && fOutput) {
668  // information for this iteration of the UserExec in the container
669  PostData(1, fOutput);
670  }
671 }
672 
674 {
675  AliWarning("AliAnalysisTaskEmcal::AcceptCluster method is deprecated. Please use GetCusterContainer(c)->AcceptCluster(clus).");
676 
677  if (!clus) return kFALSE;
678 
680  if (!cont) {
681  AliError(Form("%s:Container %d not found",GetName(),c));
682  return 0;
683  }
684  UInt_t rejectionReason = 0;
685  return cont->AcceptCluster(clus, rejectionReason);
686 }
687 
688 Bool_t AliAnalysisTaskEmcal::AcceptTrack(AliVParticle *track, Int_t c) const
689 {
690  AliWarning("AliAnalysisTaskEmcal::AcceptTrack method is deprecated. Please use GetParticleContainer(c)->AcceptParticle(clus).");
691 
692  if (!track) return kFALSE;
693 
695  if (!cont) {
696  AliError(Form("%s:Container %d not found",GetName(),c));
697  return 0;
698  }
699 
700  UInt_t rejectionReason = 0;
701  return cont->AcceptParticle(track, rejectionReason);
702 }
703 
704 Bool_t AliAnalysisTaskEmcal::PythiaInfoFromFile(const char* currFile, Float_t &fXsec, Float_t &fTrials, Int_t &pthard)
705 {
706  TString file(currFile);
707  fXsec = 0;
708  fTrials = 1;
709 
710  // Determine archive type
711  TString archivetype;
712  std::unique_ptr<TObjArray> walk(file.Tokenize("/"));
713  for(auto t : *walk){
714  TString &tok = static_cast<TObjString *>(t)->String();
715  if(tok.Contains(".zip")){
716  archivetype = tok;
717  Int_t pos = archivetype.Index(".zip");
718  archivetype.Replace(pos, archivetype.Length() - pos, "");
719  }
720  }
721  if(archivetype.Length()){
722  AliDebugStream(1) << "Auto-detected archive type " << archivetype << std::endl;
723  Ssiz_t pos1 = file.Index(archivetype,archivetype.Length(),0,TString::kExact);
724  Ssiz_t pos = file.Index("#",1,pos1,TString::kExact);
725  Ssiz_t pos2 = file.Index(".root",5,TString::kExact);
726  file.Replace(pos+1,pos2-pos1,"");
727  } else {
728  // not an archive take the basename....
729  file.ReplaceAll(gSystem->BaseName(file.Data()),"");
730  }
731  AliDebugStream(1) << "File name: " << file << std::endl;
732 
733  // Build virtual file name
734  // Support for train tests
735  TString virtualFileName;
736  if(file.Contains("__alice")){
737  TString tmp(file);
738  Int_t pos = tmp.Index("__alice");
739  tmp.Replace(0, pos, "");
740  tmp.ReplaceAll("__", "/");
741  // cut out tag for archive and root file
742  // this needs a determin
743  std::unique_ptr<TObjArray> toks(tmp.Tokenize("/"));
744  TString tag = "_" + archivetype;
745  for(auto t : *toks){
746  TString &path = static_cast<TObjString *>(t)->String();
747  if(path.Contains(tag)){
748  Int_t posTag = path.Index(tag);
749  path.Replace(posTag, path.Length() - posTag, "");
750  }
751  virtualFileName += "/" + path;
752  }
753  } else {
754  virtualFileName = file;
755  }
756 
757  AliDebugStream(1) << "Physical file name " << file << ", virtual file name " << virtualFileName << std::endl;
758 
759  // Get the pt hard bin
760  TString strPthard(virtualFileName);
761 
762  /*
763  // Dead code - to be removed after testing phase
764  // Procedure will fail for everything else than the expected path name
765  strPthard.Remove(strPthard.Last('/'));
766  strPthard.Remove(strPthard.Last('/'));
767  if (strPthard.Contains("AOD")) strPthard.Remove(strPthard.Last('/'));
768  strPthard.Remove(0,strPthard.Last('/')+1);
769  if (strPthard.IsDec()) pthard = strPthard.Atoi();
770  else
771  AliWarningStream() << "Could not extract file number from path " << strPthard << std::endl;
772  */
773 
774  // New implementation : pattern matching
775  // Reason: Implementation valid only for old productions (new productions swap run number and pt-hard bin)
776  // Idea: Don't use the position in the string but the match different informations
777  // + Year clearly 2000+
778  // + Run number can be match to the one in the event
779  // + If we know it is not year or run number, it must be the pt-hard bin if we start from the beginning
780  // The procedure is only valid for the current implementations and unable to detect non-pt-hard bins
781  // It will also fail in case of arbitrary file names
782 
783  bool binfound = false;
784  std::unique_ptr<TObjArray> tokens(strPthard.Tokenize("/"));
785  for(auto t : *tokens) {
786  TString &tok = static_cast<TObjString *>(t)->String();
787  if(tok.IsDec()){
788  Int_t number = tok.Atoi();
789  if(number > 2000 && number < 3000){
790  // Year
791  continue;
792  } else if(number == fInputHandler->GetEvent()->GetRunNumber()){
793  // Run number
794  continue;
795  } else {
796  if(!binfound){
797  // the first number that is not one of the two must be the pt-hard bin
798  binfound = true;
799  pthard = number;
800  break;
801  }
802  }
803  }
804  }
805  if(!binfound) {
806  AliErrorStream() << "Could not extract file number from path " << strPthard << std::endl;
807  } else {
808  AliInfoStream() << "Auto-detecting pt-hard bin " << pthard << std::endl;
809  }
810 
811  AliInfoStream() << "File: " << file << std::endl;
812 
813  // problem that we cannot really test the existance of a file in a archive so we have to live with open error message from root
814  std::unique_ptr<TFile> fxsec(TFile::Open(Form("%s%s",file.Data(),"pyxsec.root")));
815 
816  if (!fxsec) {
817  // next trial fetch the histgram file
818  fxsec = std::unique_ptr<TFile>(TFile::Open(Form("%s%s",file.Data(),"pyxsec_hists.root")));
819  if (!fxsec){
820  AliErrorStream() << "Failed reading cross section from file " << file << std::endl;
821  fUseXsecFromHeader = true;
822  return kFALSE; // not a severe condition but inciate that we have no information
823  }
824  else {
825  // find the tlist we want to be independtent of the name so use the Tkey
826  TKey* key = (TKey*)fxsec->GetListOfKeys()->At(0);
827  if (!key) return kFALSE;
828  TList *list = dynamic_cast<TList*>(key->ReadObj());
829  if (!list) return kFALSE;
830  TProfile *xSecHist = static_cast<TProfile*>(list->FindObject("h1Xsec"));
831  // check for failure
832  if(!xSecHist->GetEntries()) {
833  // No cross seciton information available - fall back to raw
834  AliErrorStream() << "No cross section information available in file " << fxsec->GetName() <<" - fall back to cross section in PYTHIA header" << std::endl;
835  fUseXsecFromHeader = true;
836  } else {
837  // Cross section histogram filled - take it from there
838  fXsec = xSecHist->GetBinContent(1);
839  if(!fXsec) AliErrorStream() << GetName() << ": Cross section 0 for file " << file << std::endl;
840  fUseXsecFromHeader = false;
841  }
842  fTrials = ((TH1F*)list->FindObject("h1Trials"))->GetBinContent(1);
843  }
844  } else { // no tree pyxsec.root
845  TTree *xtree = (TTree*)fxsec->Get("Xsection");
846  if (!xtree) return kFALSE;
847  UInt_t ntrials = 0;
848  Double_t xsection = 0;
849  xtree->SetBranchAddress("xsection",&xsection);
850  xtree->SetBranchAddress("ntrials",&ntrials);
851  xtree->GetEntry(0);
852  fTrials = ntrials;
853  fXsec = xsection;
854  }
855  return kTRUE;
856 }
857 
859  fPtHardInitialized = kFALSE;
860  fFileChanged = kTRUE;
861  return kTRUE;
862 }
863 
866  return kTRUE;
867 
868  // Debugging:
869  AliInfoStream() << "FileChanged called for run " << InputEvent()->GetRunNumber() << std::endl;
870 
871  TTree *tree = AliAnalysisManager::GetAnalysisManager()->GetTree();
872  if (!tree) {
873  AliErrorStream() << GetName() << " - FileChanged: No current tree!" << std::endl;
874  return kFALSE;
875  }
876 
877  Float_t xsection = 0;
878  Float_t trials = 0;
879  Int_t pthardbin = -1;
880 
881  TFile *curfile = tree->GetCurrentFile();
882  if (!curfile) {
883  AliErrorStream() << GetName() << " - FileChanged: No current file!" << std::endl;
884  return kFALSE;
885  }
886 
887  TChain *chain = dynamic_cast<TChain*>(tree);
888  if (chain) tree = chain->GetTree();
889 
890  Int_t nevents = tree->GetEntriesFast();
891 
892  fUseXsecFromHeader = false;
893  PythiaInfoFromFile(curfile->GetName(), xsection, trials, pthardbin);
895  // Use the bin obtained from the path name
896  fPtHardBinGlobal = pthardbin;
897  fPtHardInitialized = kTRUE;
898  } else {
899  // Put everything in the first bin
900  fPtHardBinGlobal = 0;
901  pthardbin = 0;
902  }
903 
904  if ((pthardbin < 0) || (pthardbin > fNPtHardBins-1)){
905  AliErrorStream() << GetName() << ": Invalid global pt-hard bin " << pthardbin << " detected" << std::endl;
906  pthardbin = 0;
907  }
908  fHistTrials->Fill(pthardbin, trials);
909  if(!fUseXsecFromHeader){
910  AliDebugStream(1) << "Using cross section from file pyxsec.root" << std::endl;
911  fHistXsection->Fill(pthardbin, xsection);
912  }
913  fHistEvents->Fill(pthardbin, nevents);
914 
915  return kTRUE;
916 }
917 
919 {
920  if (!fPythiaInfoName.IsNull() && !fPythiaInfo) {
921  fPythiaInfo = dynamic_cast<AliEmcalPythiaInfo*>(event->FindListObject(fPythiaInfoName));
922  if (!fPythiaInfo) {
923  AliError(Form("%s: Could not retrieve parton infos! %s!", GetName(), fPythiaInfoName.Data()));
924  return;
925  }
926  }
927 }
928 
930 {
931  if (!InputEvent()) {
932  AliError(Form("%s: Could not retrieve event! Returning!", GetName()));
933  return;
934  }
935 
936  LoadPythiaInfo(InputEvent());
937 
938  if (fNeedEmcalGeom) {
939  fGeom = AliEMCALGeometry::GetInstanceFromRunNumber(InputEvent()->GetRunNumber());
940  if (!fGeom) {
941  AliFatal(Form("%s: Can not get EMCal geometry instance. If you do not need the EMCal geometry, disable it by setting task->SetNeedEmcalGeometry(kFALSE).", GetName()));
942  return;
943  }
944  }
945 
946  if (fEventPlaneVsEmcal >= 0) {
947  if (fGeom) {
948  Double_t ep = (fGeom->GetArm1PhiMax() + fGeom->GetArm1PhiMin()) / 2 * TMath::DegToRad() + fEventPlaneVsEmcal - TMath::Pi();
949  fMinEventPlane = ep - TMath::Pi() / 4;
950  fMaxEventPlane = ep + TMath::Pi() / 4;
951  }
952  else {
953  AliWarning("Could not set event plane limits because EMCal geometry was not loaded!");
954  }
955  }
956 
957  //Load all requested track branches - each container knows name already
958  for (Int_t i =0; i<fParticleCollArray.GetEntriesFast(); i++) {
959  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
960  cont->SetArray(InputEvent());
961  }
962 
963  if (fParticleCollArray.GetEntriesFast()>0) {
965  if (!fTracks) {
966  AliError(Form("%s: Could not retrieve first track branch!", GetName()));
967  return;
968  }
969  }
970 
971  //Load all requested cluster branches - each container knows name already
972  for (Int_t i =0; i<fClusterCollArray.GetEntriesFast(); i++) {
973  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
974  cont->SetArray(InputEvent());
975  }
976 
977  if (fClusterCollArray.GetEntriesFast()>0) {
979  if (!fCaloClusters) {
980  AliError(Form("%s: Could not retrieve first cluster branch!", GetName()));
981  return;
982  }
983  }
984 
985  if (!fCaloCellsName.IsNull() && !fCaloCells) {
986  fCaloCells = dynamic_cast<AliVCaloCells*>(InputEvent()->FindListObject(fCaloCellsName));
987  if (!fCaloCells) {
988  AliError(Form("%s: Could not retrieve cells %s!", GetName(), fCaloCellsName.Data()));
989  return;
990  }
991  }
992 
993  if (!fCaloTriggersName.IsNull() && !fCaloTriggers) {
994  fCaloTriggers = dynamic_cast<AliVCaloTrigger*>(InputEvent()->FindListObject(fCaloTriggersName));
995  if (!fCaloTriggers) {
996  AliError(Form("%s: Could not retrieve calo triggers %s!", GetName(), fCaloTriggersName.Data()));
997  return;
998  }
999  }
1000 
1001  if (!fCaloTriggerPatchInfoName.IsNull() && !fTriggerPatchInfo) {
1002  fTriggerPatchInfo = GetArrayFromEvent(fCaloTriggerPatchInfoName.Data(),"AliEMCALTriggerPatchInfo");
1003  if (!fTriggerPatchInfo) {
1004  AliError(Form("%s: Could not retrieve calo trigger patch info %s!", GetName(), fCaloTriggerPatchInfoName.Data()));
1005  return;
1006  }
1007 
1008  }
1009 
1010  fLocalInitialized = kTRUE;
1011 }
1012 
1014 {
1015  if (fForceBeamType != kNA)
1016  return fForceBeamType;
1017 
1018  AliESDEvent *esd = dynamic_cast<AliESDEvent*>(InputEvent());
1019  if (esd) {
1020  const AliESDRun *run = esd->GetESDRun();
1021  TString beamType = run->GetBeamType();
1022  if (beamType == "p-p")
1023  return kpp;
1024  else if (beamType == "A-A")
1025  return kAA;
1026  else if (beamType == "p-A")
1027  return kpA;
1028  else
1029  return kNA;
1030  } else {
1031  Int_t runNumber = InputEvent()->GetRunNumber();
1032  // All run number ranges taken from the RCT
1033  if ((runNumber >= 136833 && runNumber <= 139517) || // LHC10h
1034  (runNumber >= 167693 && runNumber <= 170593) || // LHC11h
1035  (runNumber >= 244824 && runNumber <= 246994) || // LHC15o
1036  (runNumber >= 295581 && runNumber <= 297624)) { // LHC18p-q
1037  return kAA;
1038  } else if ((runNumber >= 188356 && runNumber <= 188366) || // LHC12g
1039  (runNumber >= 195164 && runNumber <= 197388) || // LHC13b-f
1040  (runNumber >= 265015 && runNumber <= 267166)) { // LHC16q-t
1041  return kpA;
1042  } else {
1043  return kpp;
1044  }
1045  }
1046 }
1047 
1049 {
1050  if (!fTriggerPatchInfo)
1051  return 0;
1052 
1053  //number of patches in event
1054  Int_t nPatch = fTriggerPatchInfo->GetEntries();
1055 
1056  //loop over patches to define trigger type of event
1057  Int_t nG1 = 0;
1058  Int_t nG2 = 0;
1059  Int_t nJ1 = 0;
1060  Int_t nJ2 = 0;
1061  Int_t nL0 = 0;
1062  AliEMCALTriggerPatchInfo *patch;
1063  for (Int_t iPatch = 0; iPatch < nPatch; iPatch++) {
1064  patch = (AliEMCALTriggerPatchInfo*)fTriggerPatchInfo->At( iPatch );
1065  if (patch->IsGammaHigh()) nG1++;
1066  if (patch->IsGammaLow()) nG2++;
1067  if (patch->IsJetHigh()) nJ1++;
1068  if (patch->IsJetLow()) nJ2++;
1069  if (patch->IsLevel0()) nL0++;
1070  }
1071 
1072  AliDebug(2, "Patch summary: ");
1073  AliDebug(2, Form("Number of patches: %d", nPatch));
1074  AliDebug(2, Form("Jet: low[%d], high[%d]" ,nJ2, nJ1));
1075  AliDebug(2, Form("Gamma: low[%d], high[%d]" ,nG2, nG1));
1076 
1077  ULong_t triggers(0);
1078  if (nL0>0) SETBIT(triggers, kL0);
1079  if (nG1>0) SETBIT(triggers, kG1);
1080  if (nG2>0) SETBIT(triggers, kG2);
1081  if (nJ1>0) SETBIT(triggers, kJ1);
1082  if (nJ2>0) SETBIT(triggers, kJ2);
1083  return triggers;
1084 }
1085 
1087 {
1088  //
1089  if(trigger==kND) {
1090  AliWarning(Form("%s: Requesting undefined trigger type!", GetName()));
1091  return kFALSE;
1092  }
1093  //MV: removing this logic which as far as I can see doesn't make any sense
1094  // if(trigger & kND){
1095  // return fTriggers == 0;
1096  // }
1097  return TESTBIT(fTriggers, trigger);
1098 }
1099 
1102  if(!IsTriggerSelected()) return false;
1103  if(!CheckMCOutliers()) return false;
1104  return fAliEventCuts.AcceptEvent(fInputEvent);
1105 }
1106 
1108 {
1109  AliDebugStream(3) << "Using default event selection" << std::endl;
1110  if (fOffTrigger != AliVEvent::kAny) {
1111  UInt_t res = 0;
1112  const AliESDEvent *eev = dynamic_cast<const AliESDEvent*>(InputEvent());
1113  if (eev) {
1114  res = ((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected();
1115  } else {
1116  const AliAODEvent *aev = dynamic_cast<const AliAODEvent*>(InputEvent());
1117  if (aev) {
1118  res = ((AliVAODHeader*)aev->GetHeader())->GetOfflineTrigger();
1119  }
1120  }
1121  if ((res & fOffTrigger) == 0) {
1122  if (fGeneralHistograms) fHistEventRejection->Fill("PhysSel",1);
1123  return kFALSE;
1124  }
1125  }
1126 
1127  if(!IsTriggerSelected()) {
1128  if (fGeneralHistograms) fHistEventRejection->Fill("trigger",1);
1129  return kFALSE;
1130  }
1131 
1132  if (fTriggerTypeSel != kND) {
1134  if (fGeneralHistograms) fHistEventRejection->Fill("trigTypeSel",1);
1135  return kFALSE;
1136  }
1137  }
1138 
1139  if ((fMinCent != -999) && (fMaxCent != -999)) {
1140  if (fCent<fMinCent || fCent>fMaxCent) {
1141  if (fGeneralHistograms) fHistEventRejection->Fill("Cent",1);
1142  return kFALSE;
1143  }
1144  }
1145 
1146  if (fUseAliAnaUtils) {
1147  if (!fAliAnalysisUtils)
1148  fAliAnalysisUtils = new AliAnalysisUtils();
1149  fAliAnalysisUtils->SetMinVtxContr(fMinVertexContrib);
1150  fAliAnalysisUtils->SetMaxVtxZ(999);
1151  if(fMinVz<-998.) fMinVz = -10.;
1152  if(fMaxVz>998.) fMaxVz = 10.;
1153 
1154  if (!fAliAnalysisUtils->IsVertexSelected2013pA(InputEvent())) {
1155  if (fGeneralHistograms) fHistEventRejection->Fill("VtxSel2013pA",1);
1156  return kFALSE;
1157  }
1158 
1159  if (fRejectPileup && fAliAnalysisUtils->IsPileUpEvent(InputEvent())) {
1160  if (fGeneralHistograms) fHistEventRejection->Fill("PileUp",1);
1161  return kFALSE;
1162  }
1163 
1164  if(fTklVsClusSPDCut && fAliAnalysisUtils->IsSPDClusterVsTrackletBG(InputEvent())) {
1165  if (fGeneralHistograms) fHistEventRejection->Fill("Bkg evt",1);
1166  return kFALSE;
1167  }
1168  }
1169 
1170  if ((fMinVz > -998.) && (fMaxVz < 998.)) {
1171  if (fNVertCont == 0 ) {
1172  if (fGeneralHistograms) fHistEventRejection->Fill("vertex contr.",1);
1173  return kFALSE;
1174  }
1175  Double_t vz = fVertex[2];
1176  if (vz < fMinVz || vz > fMaxVz) {
1177  if (fGeneralHistograms) fHistEventRejection->Fill("Vz",1);
1178  return kFALSE;
1179  }
1180 
1181  if (fNVertSPDCont > 0 && fZvertexDiff < 999) {
1182  Double_t vzSPD = fVertexSPD[2];
1183  Double_t dvertex = TMath::Abs(vz-vzSPD);
1184  //if difference larger than fZvertexDiff
1185  if (dvertex > fZvertexDiff) {
1186  if (fGeneralHistograms) fHistEventRejection->Fill("VzSPD",1);
1187  return kFALSE;
1188  }
1189  }
1190  }
1191 
1192  if (fMinPtTrackInEmcal > 0 && fGeom) {
1193  Bool_t trackInEmcalOk = kFALSE;
1194  Int_t ntracks = GetNParticles(0);
1195  for (Int_t i = 0; i < ntracks; i++) {
1196  AliVParticle *track = GetAcceptParticleFromArray(i,0);
1197  if (!track)
1198  continue;
1199 
1200  Double_t phiMin = fGeom->GetArm1PhiMin() * TMath::DegToRad();
1201  Double_t phiMax = fGeom->GetArm1PhiMax() * TMath::DegToRad();
1202  Int_t runNumber = InputEvent()->GetRunNumber();
1203  if (runNumber>=177295 && runNumber<=197470) { //small SM masked in 2012 and 2013
1204  phiMin = 1.4;
1205  phiMax = TMath::Pi();
1206  }
1207 
1208  if (track->Eta() < fGeom->GetArm1EtaMin() || track->Eta() > fGeom->GetArm1EtaMax() || track->Phi() < phiMin || track->Phi() > phiMax)
1209  continue;
1210  if (track->Pt() > fMinPtTrackInEmcal) {
1211  trackInEmcalOk = kTRUE;
1212  break;
1213  }
1214  }
1215  if (!trackInEmcalOk) {
1216  if (fGeneralHistograms) fHistEventRejection->Fill("trackInEmcal",1);
1217  return kFALSE;
1218  }
1219  }
1220 
1221  if (fMinNTrack > 0) {
1222  Int_t nTracksAcc = 0;
1223  Int_t ntracks = GetNParticles(0);
1224  for (Int_t i = 0; i < ntracks; i++) {
1225  AliVParticle *track = GetAcceptParticleFromArray(i,0);
1226  if (!track)
1227  continue;
1228  if (track->Pt() > fTrackPtCut) {
1229  nTracksAcc++;
1230  if (nTracksAcc>=fMinNTrack)
1231  break;
1232  }
1233  }
1234  if (nTracksAcc<fMinNTrack) {
1235  if (fGeneralHistograms) fHistEventRejection->Fill("minNTrack",1);
1236  return kFALSE;
1237  }
1238  }
1239 
1240  if (!(fEPV0 > fMinEventPlane && fEPV0 <= fMaxEventPlane) &&
1241  !(fEPV0 + TMath::Pi() > fMinEventPlane && fEPV0 + TMath::Pi() <= fMaxEventPlane) &&
1242  !(fEPV0 - TMath::Pi() > fMinEventPlane && fEPV0 - TMath::Pi() <= fMaxEventPlane))
1243  {
1244  if (fGeneralHistograms) fHistEventRejection->Fill("EvtPlane",1);
1245  return kFALSE;
1246  }
1247 
1248  if (fSelectPtHardBin != -999 && fSelectPtHardBin != fPtHardBin) {
1249  if (fGeneralHistograms) fHistEventRejection->Fill("SelPtHardBin",1);
1250  return kFALSE;
1251  }
1252 
1253  // Reject filter for MC data
1254  if (!CheckMCOutliers()) return kFALSE;
1255 
1256  return kTRUE;
1257 }
1258 
1260  // Default implementation of trigger selection
1261  // same as previously (code moved from IsEventSelected
1262  // to trigger selection). Users should re-implement
1263  // this function in case they have certain needs, in
1264  // particular for EMCAL triggers
1265  AliDebugStream(3) << "Using default trigger selection" << std::endl;
1266  if (!fTrigClass.IsNull()) {
1267  TString fired = InputEvent()->GetFiredTriggerClasses();
1268  if (!fired.Contains("-B-")) return kFALSE;
1269 
1270  std::unique_ptr<TObjArray> arr(fTrigClass.Tokenize("|"));
1271  if (!arr) return kFALSE;
1272  Bool_t match = false;
1273  for (Int_t i=0;i<arr->GetEntriesFast();++i) {
1274  TObject *obj = arr->At(i);
1275  if (!obj) continue;
1276 
1277  //Check if requested trigger was fired
1278  TString objStr = obj->GetName();
1280  (objStr.Contains("J1") || objStr.Contains("J2") || objStr.Contains("G1") || objStr.Contains("G2"))) {
1281  // This is relevant for EMCal triggers with 2 thresholds
1282  // If the kOverlapWithLowThreshold was requested than the overlap between the two triggers goes with the lower threshold trigger
1283  TString trigType1 = "J1";
1284  TString trigType2 = "J2";
1285  if(objStr.Contains("G")) {
1286  trigType1 = "G1";
1287  trigType2 = "G2";
1288  }
1289  if(objStr.Contains(trigType2) && fired.Contains(trigType2.Data())) { //requesting low threshold + overlap
1290  match = 1;
1291  break;
1292  } else if(objStr.Contains(trigType1) && fired.Contains(trigType1.Data()) && !fired.Contains(trigType2.Data())) { //high threshold only
1293  match = 1;
1294  break;
1295  }
1296  }
1297  else {
1298  // If this is not an EMCal trigger, or no particular treatment of EMCal triggers was requested,
1299  // simply check that the trigger was fired
1300  if (fired.Contains(obj->GetName())) {
1301  match = 1;
1302  break;
1303  }
1304  }
1305  }
1306  if (!match) return kFALSE;
1307  }
1308  return kTRUE;
1309 }
1310 
1312 {
1313  if (!fPythiaHeader || !fMCRejectFilter) return kTRUE;
1314  AliDebugStream(2) << "Using custom outlier rejection" << std::endl;
1315 
1316  // Condition 1: Pythia jet / pT-hard > factor
1317  if (fPtHardAndJetPtFactor > 0.) {
1318  AliTLorentzVector jet;
1319 
1320  Int_t nTriggerJets = fPythiaHeader->NTriggerJets();
1321 
1322  AliDebug(2,Form("Njets: %d, pT Hard %f",nTriggerJets, fPtHard));
1323 
1324  Float_t tmpjet[]={0,0,0,0};
1325  for (Int_t ijet = 0; ijet< nTriggerJets; ijet++) {
1326  fPythiaHeader->TriggerJet(ijet, tmpjet);
1327 
1328  jet.SetPxPyPzE(tmpjet[0],tmpjet[1],tmpjet[2],tmpjet[3]);
1329 
1330  AliDebug(2,Form("jet %d; pycell jet pT %f",ijet, jet.Pt()));
1331 
1332  //Compare jet pT and pt Hard
1333  if (jet.Pt() > fPtHardAndJetPtFactor * fPtHard) {
1334  AliInfo(Form("Reject jet event with : pT Hard %2.2f, pycell jet pT %2.2f, rejection factor %1.1f\n", fPtHard, jet.Pt(), fPtHardAndJetPtFactor));
1335  return kFALSE;
1336  }
1337  }
1338  }
1339  // end condition 1
1340 
1341  // Condition 2 : Reconstructed EMCal cluster pT / pT-hard > factor
1342  if (fPtHardAndClusterPtFactor > 0.) {
1343  AliClusterContainer* mccluscont = GetClusterContainer(0);
1344  if ((Bool_t)mccluscont) {
1345  for (auto cluster : mccluscont->all()) {// Not cuts applied ; use accept for cuts
1346  Float_t ecluster = cluster->E();
1347 
1348  if (ecluster > (fPtHardAndClusterPtFactor * fPtHard)) {
1349  AliInfo(Form("Reject : ecluster %2.2f, calo %d, factor %2.2f, ptHard %f",ecluster,cluster->GetType(),fPtHardAndClusterPtFactor,fPtHard));
1350  return kFALSE;
1351  }
1352  }
1353  }
1354  }
1355  // end condition 2
1356 
1357  // condition 3 : Reconstructed track pT / pT-hard >factor
1358  if (fPtHardAndTrackPtFactor > 0.) {
1359  AliMCParticleContainer* mcpartcont = dynamic_cast<AliMCParticleContainer*>(GetParticleContainer(0));
1360  if ((Bool_t)mcpartcont) {
1361  for (auto mctrack : mcpartcont->all()) {// Not cuts applied ; use accept for cuts
1362  Float_t trackpt = mctrack->Pt();
1363  if (trackpt > (fPtHardAndTrackPtFactor * fPtHard) ) {
1364  AliInfo(Form("Reject : track %2.2f, factor %2.2f, ptHard %f", trackpt, fPtHardAndTrackPtFactor, fPtHard));
1365  return kFALSE;
1366  }
1367  }
1368  }
1369  }
1370  // end condition 3
1371 
1372  return kTRUE;
1373 }
1374 
1375 TClonesArray *AliAnalysisTaskEmcal::GetArrayFromEvent(const char *name, const char *clname)
1376 {
1377  TClonesArray *arr = 0;
1378  TString sname(name);
1379  if (!sname.IsNull()) {
1380  arr = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(sname));
1381  if (!arr) {
1382  AliWarning(Form("%s: Could not retrieve array with name %s!", GetName(), name));
1383  return 0;
1384  }
1385  } else {
1386  return 0;
1387  }
1388 
1389  if (!clname)
1390  return arr;
1391 
1392  TString objname(arr->GetClass()->GetName());
1393  TClass cls(objname);
1394  if (!cls.InheritsFrom(clname)) {
1395  AliWarning(Form("%s: Objects of type %s in %s are not inherited from %s!",
1396  GetName(), cls.GetName(), name, clname));
1397  return 0;
1398  }
1399  return arr;
1400 }
1401 
1403 {
1404  fVertex[0] = 0;
1405  fVertex[1] = 0;
1406  fVertex[2] = 0;
1407  fNVertCont = 0;
1408 
1409  fVertexSPD[0] = 0;
1410  fVertexSPD[1] = 0;
1411  fVertexSPD[2] = 0;
1412  fNVertSPDCont = 0;
1413 
1414  if (fGeneratePythiaInfoObject && MCEvent()) {
1415  GeneratePythiaInfoObject(MCEvent());
1416  }
1417 
1418  const AliVVertex *vert = InputEvent()->GetPrimaryVertex();
1419  if (vert) {
1420  vert->GetXYZ(fVertex);
1421  fNVertCont = vert->GetNContributors();
1422  }
1423 
1424  const AliVVertex *vertSPD = InputEvent()->GetPrimaryVertexSPD();
1425  if (vertSPD) {
1426  vertSPD->GetXYZ(fVertexSPD);
1427  fNVertSPDCont = vertSPD->GetNContributors();
1428  }
1429 
1430  fBeamType = GetBeamType();
1431  TObject * header = InputEvent()->GetHeader();
1432  if (fBeamType == kAA || fBeamType == kpA ) {
1434  if (header->InheritsFrom("AliNanoAODStorage")){
1435  AliNanoAODHeader *nanoHead = (AliNanoAODHeader*)header;
1436  fCent=nanoHead->GetCentr(fCentEst.Data());
1437  }else{
1438  AliMultSelection *MultSelection = static_cast<AliMultSelection*>(InputEvent()->FindListObject("MultSelection"));
1439  if (MultSelection) {
1440  fCent = MultSelection->GetMultiplicityPercentile(fCentEst.Data());
1441  }
1442  else {
1443  AliWarning(Form("%s: Could not retrieve centrality information! Assuming 99", GetName()));
1444  }
1445  }
1446  }
1447  else { // old centrality estimation < 2015
1448  if (header->InheritsFrom("AliNanoAODStorage")){
1449  AliNanoAODHeader *nanoHead = (AliNanoAODHeader*)header;
1450  fCent=nanoHead->GetCentr(fCentEst.Data());
1451  }else{
1452  AliCentrality *aliCent = InputEvent()->GetCentrality();
1453  if (aliCent) {
1454  fCent = aliCent->GetCentralityPercentile(fCentEst.Data());
1455  }
1456  else {
1457  AliWarning(Form("%s: Could not retrieve centrality information! Assuming 99", GetName()));
1458  }
1459  }
1460  }
1461 
1462  if (fNcentBins==4) {
1463  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1464  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1465  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1466  else if (fCent >= 50 && fCent <= 100) fCentBin = 3;
1467  else {
1468  AliWarning(Form("%s: Negative centrality: %f. Assuming 99", GetName(), fCent));
1469  fCentBin = fNcentBins-1;
1470  }
1471  }
1472  else if (fNcentBins==5) { // for PbPb 2015
1473  if (fCent >= 0 && fCent < 10) fCentBin = 0;
1474  else if (fCent >= 10 && fCent < 30) fCentBin = 1;
1475  else if (fCent >= 30 && fCent < 50) fCentBin = 2;
1476  else if (fCent >= 50 && fCent <= 90) fCentBin = 3;
1477  else if (fCent > 90) {
1478  fCent = 99;
1479  fCentBin = 4;
1480  }
1481  else {
1482  AliWarning(Form("%s: Negative centrality: %f. Assuming 99", GetName(), fCent));
1483  fCentBin = fNcentBins-1;
1484  }
1485  }
1486  else {
1487  Double_t centWidth = (fMaxCent-fMinCent)/(Double_t)fNcentBins;
1488  if(centWidth>0.) {
1489  fCentBin = TMath::FloorNint(fCent/centWidth);
1490  }
1491  else {
1492  fCentBin = 0;
1493  }
1494  if (fCentBin>=fNcentBins) {
1495  AliWarning(Form("%s: fCentBin too large: cent = %f fCentBin = %d. Assuming 99", GetName(),fCent,fCentBin));
1496  fCentBin = fNcentBins-1;
1497  }
1498  }
1499  if (header->InheritsFrom("AliNanoAODStorage")){
1500  AliNanoAODHeader *nanoHead = (AliNanoAODHeader*)header;
1501  fEPV0=nanoHead->GetVar(nanoHead->GetVarIndex("cstEvPlaneV0"));
1502  fEPV0A=nanoHead->GetVar(nanoHead->GetVarIndex("cstEvPlaneV0A"));
1503  fEPV0C=nanoHead->GetVar(nanoHead->GetVarIndex("cstEvPlaneV0C"));
1504  }else{
1505  AliEventplane *aliEP = InputEvent()->GetEventplane();
1506  if (aliEP) {
1507  fEPV0 = aliEP->GetEventplane("V0" ,InputEvent());
1508  fEPV0A = aliEP->GetEventplane("V0A",InputEvent());
1509  fEPV0C = aliEP->GetEventplane("V0C",InputEvent());
1510  } else {
1511  AliWarning(Form("%s: Could not retrieve event plane information!", GetName()));
1512  }
1513  }
1514  }
1515  else {
1516  fCent = 99;
1517  fCentBin = 0;
1518  }
1519 
1520  if (fIsPythia) {
1521  if (MCEvent()) {
1522  fPythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(MCEvent()->GenEventHeader());
1523  if (!fPythiaHeader) {
1524  // Check if AOD
1525  AliAODMCHeader* aodMCH = dynamic_cast<AliAODMCHeader*>(InputEvent()->FindListObject(AliAODMCHeader::StdBranchName()));
1526 
1527  if (aodMCH) {
1528  for (UInt_t i = 0;i<aodMCH->GetNCocktailHeaders();i++) {
1529  fPythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(aodMCH->GetCocktailHeader(i));
1530  if (fPythiaHeader) break;
1531  }
1532  }
1533  }
1534  }
1535  }
1536 
1537  if (fPythiaHeader) {
1538  fPtHard = fPythiaHeader->GetPtHard();
1539 
1540  if(fPtHardBinning.GetSize()){
1541  // pt-hard binning defined for the corresponding dataset - automatically determine the bin
1542  for (fPtHardBin = 0; fPtHardBin < fNPtHardBins; fPtHardBin++) {
1543  if (fPtHard >= static_cast<float>(fPtHardBinning[fPtHardBin]) && fPtHard < static_cast<float>(fPtHardBinning[fPtHardBin+1]))
1544  break;
1545  }
1546  } else {
1547  // No pt-hard binning defined for the dataset - leaving the bin to 0
1548  fPtHardBin = 0;
1549  }
1550 
1551  if(fPtHardInitialized){
1552  // do check only in case the global pt-hard bin is initialized
1554  AliErrorStream() << GetName() << ": Mismatch in pt-hard bin determination. Local: " << fPtHardBin << ", Global: " << fPtHardBinGlobal << std::endl;
1555  }
1556  }
1557 
1558  fXsection = fPythiaHeader->GetXsection();
1559  fNTrials = fPythiaHeader->Trials();
1560  }
1561 
1562  if (fIsHerwig) {
1563  if (MCEvent()) {
1564  fHerwigHeader = dynamic_cast<AliGenHerwigEventHeader*>(MCEvent()->GenEventHeader());
1565 
1566  if (!fHerwigHeader) {
1567  // Check if AOD
1568  AliAODMCHeader* aodMCH = dynamic_cast<AliAODMCHeader*>(InputEvent()->FindListObject(AliAODMCHeader::StdBranchName()));
1569 
1570  if (aodMCH) {
1571  for (UInt_t i = 0;i<aodMCH->GetNCocktailHeaders();i++) {
1572  fHerwigHeader = dynamic_cast<AliGenHerwigEventHeader*>(aodMCH->GetCocktailHeader(i));
1573  if (fHerwigHeader) break;
1574  }
1575  }
1576  }
1577  }
1578  }
1579 
1580  if (fHerwigHeader) {
1581  fPtHard = fHerwigHeader->GetPtHard();
1582 
1583  if(fPtHardBinning.GetSize()){
1584  // pt-hard binning defined for the corresponding dataset - automatically determine the bin
1585  for (fPtHardBin = 0; fPtHardBin < fNPtHardBins; fPtHardBin++) {
1587  break;
1588  }
1589  } else {
1590  // No pt-hard binning defined for the dataset - leaving the bin to 0
1591  fPtHardBin = 0;
1592  }
1593  fXsection = fHerwigHeader->Weight();
1594  fNTrials = fHerwigHeader->Trials();
1595  }
1596 
1597 
1599 
1600  AliEmcalContainer* cont = 0;
1601 
1602  TIter nextPartColl(&fParticleCollArray);
1603  while ((cont = static_cast<AliEmcalContainer*>(nextPartColl()))){
1604  cont->NextEvent(InputEvent());
1605  }
1606 
1607  TIter nextClusColl(&fClusterCollArray);
1608  while ((cont = static_cast<AliParticleContainer*>(nextClusColl()))){
1609  cont->NextEvent(InputEvent());
1610  }
1611 
1612  return kTRUE;
1613 }
1614 
1616 {
1617  if (TString(n).IsNull()) return 0;
1618 
1620 
1621  fParticleCollArray.Add(cont);
1622 
1623  return cont;
1624 }
1625 
1627 {
1628  if (TString(n).IsNull()) return 0;
1629 
1630  AliTrackContainer* cont = new AliTrackContainer(n);
1631 
1632  fParticleCollArray.Add(cont);
1633 
1634  return cont;
1635 }
1636 
1638 {
1639  if (TString(n).IsNull()) return 0;
1640 
1642 
1643  fParticleCollArray.Add(cont);
1644 
1645  return cont;
1646 }
1647 
1649 {
1650  if (TString(n).IsNull()) return 0;
1651 
1653 
1654  fClusterCollArray.Add(cont);
1655 
1656  return cont;
1657 }
1658 
1660 {
1661  if (i<0 || i>fParticleCollArray.GetEntriesFast()) return 0;
1662  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.At(i));
1663  return cont;
1664 }
1665 
1667 {
1668  if (i<0 || i>fClusterCollArray.GetEntriesFast()) return 0;
1669  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.At(i));
1670  return cont;
1671 }
1672 
1674 {
1675  AliParticleContainer *cont = static_cast<AliParticleContainer*>(fParticleCollArray.FindObject(name));
1676  return cont;
1677 }
1678 
1680 {
1681  AliClusterContainer *cont = static_cast<AliClusterContainer*>(fClusterCollArray.FindObject(name));
1682  return cont;
1683 }
1684 
1686 {
1688  if (!cont) {
1689  AliError(Form("%s: Particle container %d not found",GetName(),i));
1690  return 0;
1691  }
1692  TString contName = cont->GetArrayName();
1693  return cont->GetArray();
1694 }
1695 
1697 {
1699  if (!cont) {
1700  AliError(Form("%s:Cluster container %d not found",GetName(),i));
1701  return 0;
1702  }
1703  return cont->GetArray();
1704 }
1705 
1707 {
1708 
1710  if (!cont) {
1711  AliError(Form("%s: Particle container %d not found",GetName(),c));
1712  return 0;
1713  }
1714  AliVParticle *vp = cont->GetAcceptParticle(p);
1715 
1716  return vp;
1717 }
1718 
1720 {
1722  if (!cont) {
1723  AliError(Form("%s: Cluster container %d not found",GetName(),c));
1724  return 0;
1725  }
1726  AliVCluster *vc = cont->GetAcceptCluster(cl);
1727 
1728  return vc;
1729 }
1730 
1732 {
1734  if (!cont) {
1735  AliError(Form("%s: Particle container %d not found",GetName(),i));
1736  return 0;
1737  }
1738  return cont->GetNEntries();
1739 }
1740 
1742 {
1744  if (!cont) {
1745  AliError(Form("%s: Cluster container %d not found",GetName(),i));
1746  return 0;
1747  }
1748  return cont->GetNEntries();
1749 }
1750 
1751 AliEMCALTriggerPatchInfo* AliAnalysisTaskEmcal::GetMainTriggerPatch(TriggerCategory trigger, Bool_t doSimpleOffline)
1752 {
1753 
1754  if (!fTriggerPatchInfo) {
1755  AliError(Form("%s: fTriggerPatchInfo not available",GetName()));
1756  return 0;
1757  }
1758 
1759  //number of patches in event
1760  Int_t nPatch = fTriggerPatchInfo->GetEntries();
1761 
1762  //extract main trigger patch(es)
1763  AliEMCALTriggerPatchInfo *patch(NULL), *selected(NULL);
1764  for (Int_t iPatch = 0; iPatch < nPatch; iPatch++) {
1765 
1766  patch = (AliEMCALTriggerPatchInfo*)fTriggerPatchInfo->At( iPatch );
1767  if (patch->IsMainTrigger()) {
1768  if(doSimpleOffline){
1769  if(patch->IsOfflineSimple()){
1770  switch(trigger){
1771  case kTriggerLevel0:
1772  // option not yet implemented in the trigger maker
1773  if(patch->IsLevel0()) selected = patch;
1774  break;
1775  case kTriggerLevel1Jet:
1776  if(patch->IsJetHighSimple() || patch->IsJetLowSimple()){
1777  if(!selected) selected = patch;
1778  else if(patch->GetADCOfflineAmp() > selected->GetADCOfflineAmp()) selected = patch;
1779  }
1780  break;
1781  case kTriggerLevel1Gamma:
1782  if(patch->IsGammaHighSimple() || patch->IsGammaLowSimple()){
1783  if(!selected) selected = patch;
1784  else if(patch->GetADCOfflineAmp() > selected->GetADCOfflineAmp()) selected = patch;
1785  }
1786  break;
1787  default: // Silence compiler warnings
1788  AliError("Untreated case: Main Patch is recalculated; should be in 'else' branch");
1789  };
1790  }
1791  } else { // Not OfflineSimple
1792  switch(trigger){
1793  case kTriggerLevel0:
1794  if(patch->IsLevel0()) selected = patch;
1795  break;
1796  case kTriggerLevel1Jet:
1797  if(patch->IsJetHigh() || patch->IsJetLow()){
1798  if(!selected) selected = patch;
1799  else if (patch->GetADCAmp() > selected->GetADCAmp())
1800  selected = patch;
1801  }
1802  break;
1803  case kTriggerLevel1Gamma:
1804  if(patch->IsGammaHigh() || patch->IsGammaLow()){
1805  if(!selected) selected = patch;
1806  else if (patch->GetADCAmp() > selected->GetADCAmp())
1807  selected = patch;
1808  }
1809  break;
1810  default:
1811  AliError("Untreated case: Main Patch is recalculated; should be in 'else' branch");
1812  };
1813  }
1814  }
1815  else if ((trigger == kTriggerRecalcJet && patch->IsRecalcJet()) ||
1816  (trigger == kTriggerRecalcGamma && patch->IsRecalcGamma())) { // recalculated patches
1817  if (doSimpleOffline && patch->IsOfflineSimple()) {
1818  if(!selected) selected = patch;
1819  else if (patch->GetADCOfflineAmp() > selected->GetADCOfflineAmp()) // this in fact should not be needed, but we have it in teh other branches as well, so keeping it for compleness
1820  selected = patch;
1821  }
1822  else if (!doSimpleOffline && !patch->IsOfflineSimple()) {
1823  if(!selected) selected = patch;
1824  else if (patch->GetADCAmp() > selected->GetADCAmp())
1825  selected = patch;
1826  }
1827  }
1828  }
1829  return selected;
1830 }
1831 
1833 {
1834  if (!(InputEvent()->FindListObject(obj->GetName()))) {
1835  InputEvent()->AddObject(obj);
1836  }
1837  else {
1838  if (!attempt) {
1839  AliFatal(Form("%s: Container with name %s already present. Aborting", GetName(), obj->GetName()));
1840  }
1841  }
1842 }
1843 
1845 {
1846 
1847  if (!fGeom) {
1848  AliWarning(Form("%s - AliAnalysisTaskEmcal::IsTrackInEmcalAcceptance - Geometry is not available!", GetName()));
1849  return kFALSE;
1850  }
1851 
1852  Double_t minPhi = fGeom->GetArm1PhiMin() - edges;
1853  Double_t maxPhi = fGeom->GetArm1PhiMax() + edges;
1854 
1855  if (part->Phi() > minPhi && part->Phi() < maxPhi) {
1856  return kTRUE;
1857  }
1858  else {
1859  return kFALSE;
1860  }
1861 }
1862 
1864 {
1865  axis->SetBinLabel(1, "NullObject");
1866  axis->SetBinLabel(2, "Pt");
1867  axis->SetBinLabel(3, "Acceptance");
1868  axis->SetBinLabel(4, "MCLabel");
1869  axis->SetBinLabel(5, "BitMap");
1870  axis->SetBinLabel(6, "HF cut");
1871  axis->SetBinLabel(7, "Bit6");
1872  axis->SetBinLabel(8, "NotHybridTrack");
1873  axis->SetBinLabel(9, "MCFlag");
1874  axis->SetBinLabel(10, "MCGenerator");
1875  axis->SetBinLabel(11, "ChargeCut");
1876  axis->SetBinLabel(12, "MinDistanceTPCSectorEdge");
1877  axis->SetBinLabel(13, "Bit12");
1878  axis->SetBinLabel(14, "IsEMCal");
1879  axis->SetBinLabel(15, "Time");
1880  axis->SetBinLabel(16, "Energy");
1881  axis->SetBinLabel(17, "ExoticCut");
1882  axis->SetBinLabel(18, "Bit17");
1883  axis->SetBinLabel(19, "Area");
1884  axis->SetBinLabel(20, "AreaEmc");
1885  axis->SetBinLabel(21, "ZLeadingCh");
1886  axis->SetBinLabel(22, "ZLeadingEmc");
1887  axis->SetBinLabel(23, "NEF");
1888  axis->SetBinLabel(24, "MinLeadPt");
1889  axis->SetBinLabel(25, "MaxTrackPt");
1890  axis->SetBinLabel(26, "MaxClusterPt");
1891  axis->SetBinLabel(27, "Flavour");
1892  axis->SetBinLabel(28, "TagStatus");
1893  axis->SetBinLabel(29, "MinNConstituents");
1894  axis->SetBinLabel(30, "Bit29");
1895  axis->SetBinLabel(31, "Bit30");
1896  axis->SetBinLabel(32, "Bit31");
1897 }
1898 
1899 Double_t AliAnalysisTaskEmcal::GetParallelFraction(AliVParticle* part1, AliVParticle* part2)
1900 {
1901  TVector3 vect1(part1->Px(), part1->Py(), part1->Pz());
1902  TVector3 vect2(part2->Px(), part2->Py(), part2->Pz());
1903  Double_t z = (vect1 * vect2) / (vect2 * vect2);
1904  return z;
1905 }
1906 
1907 Double_t AliAnalysisTaskEmcal::GetParallelFraction(const TVector3& vect1, AliVParticle* part2)
1908 {
1909  TVector3 vect2(part2->Px(), part2->Py(), part2->Pz());
1910  Double_t z = (vect1 * vect2) / (vect2 * vect2);
1911  return z;
1912 }
1913 
1914 void AliAnalysisTaskEmcal::GetEtaPhiDiff(const AliVTrack *t, const AliVCluster *v, Double_t &phidiff, Double_t &etadiff)
1915 {
1916  phidiff = 999;
1917  etadiff = 999;
1918 
1919  if (!t||!v) return;
1920 
1921  Double_t veta = t->GetTrackEtaOnEMCal();
1922  Double_t vphi = t->GetTrackPhiOnEMCal();
1923 
1924  Float_t pos[3] = {0};
1925  v->GetPosition(pos);
1926  TVector3 cpos(pos);
1927  Double_t ceta = cpos.Eta();
1928  Double_t cphi = cpos.Phi();
1929  etadiff=veta-ceta;
1930  phidiff=TVector2::Phi_mpi_pi(vphi-cphi);
1931 }
1932 
1933 Byte_t AliAnalysisTaskEmcal::GetTrackType(const AliVTrack *t)
1934 {
1935  Byte_t ret = 0;
1936  if (t->TestBit(BIT(22)) && !t->TestBit(BIT(23)))
1937  ret = 1;
1938  else if (!t->TestBit(BIT(22)) && t->TestBit(BIT(23)))
1939  ret = 2;
1940  else if (t->TestBit(BIT(22)) && t->TestBit(BIT(23)))
1941  ret = 3;
1942  return ret;
1943 }
1944 
1945 Byte_t AliAnalysisTaskEmcal::GetTrackType(const AliAODTrack *aodTrack, UInt_t filterBit1, UInt_t filterBit2)
1946 {
1947 
1948  Int_t res = 0;
1949 
1950  if (aodTrack->TestFilterBit(filterBit1)) {
1951  res = 0;
1952  }
1953  else if (aodTrack->TestFilterBit(filterBit2)) {
1954  if ((aodTrack->GetStatus()&AliVTrack::kITSrefit)!=0) {
1955  res = 1;
1956  }
1957  else {
1958  res = 2;
1959  }
1960  }
1961  else {
1962  res = 3;
1963  }
1964 
1965  return res;
1966 }
1967 
1969 {
1970  if (!fPythiaInfo) {
1972  }
1973 
1974  AliStack* stack = mcEvent->Stack();
1975 
1976  const Int_t nprim = stack->GetNprimary();
1977  // reject if partons are missing from stack for some reason
1978  if (nprim < 8) return;
1979 
1980  TParticle *part6 = stack->Particle(6);
1981  TParticle *part7 = stack->Particle(7);
1982 
1983  fPythiaInfo->SetPartonFlag6(TMath::Abs(part6->GetPdgCode()));
1984  fPythiaInfo->SetParton6(part6->Pt(), part6->Eta(), part6->Phi(), part6->GetMass());
1985 
1986  fPythiaInfo->SetPartonFlag7(TMath::Abs(part7->GetPdgCode()));
1987  fPythiaInfo->SetParton7(part7->Pt(), part7->Eta(), part7->Phi(), part7->GetMass());
1988 
1989  AliGenPythiaEventHeader *pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(mcEvent->GenEventHeader());
1990  if(pythiaGenHeader){
1991  Float_t ptWeight=pythiaGenHeader->EventWeight();
1992  fPythiaInfo->SetPythiaEventWeight(ptWeight);}
1993 }
1994 
1996 {
1997  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1998  if (!mgr) {
1999  ::Error("AddAODHandler", "No analysis manager to connect to.");
2000  return NULL;
2001  }
2002 
2003  AliAODInputHandler* aodHandler = new AliAODInputHandler();
2004 
2005  AliVEventHandler *inputHandler=mgr->GetInputEventHandler();
2006  if (inputHandler && (inputHandler->IsA() == AliMultiInputEventHandler::Class())) {
2007  AliMultiInputEventHandler *multiInputHandler=(AliMultiInputEventHandler*)inputHandler;
2008  multiInputHandler->AddInputEventHandler(aodHandler);
2009  }
2010  else {
2011  if (!inputHandler) {
2012  mgr->SetInputEventHandler(aodHandler);
2013  }
2014  else {
2015  ::Error("AddAODHandler", "inputHandler is NOT null. AOD handler was NOT added !!!");
2016  return NULL;
2017  }
2018  }
2019 
2020  return aodHandler;
2021 }
2022 
2024 {
2025  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
2026  if (!mgr) {
2027  ::Error("AddESDHandler", "No analysis manager to connect to.");
2028  return NULL;
2029  }
2030 
2031  AliESDInputHandler *esdHandler = new AliESDInputHandler();
2032 
2033  AliVEventHandler *inputHandler=mgr->GetInputEventHandler();
2034  if (inputHandler && (inputHandler->IsA() == AliMultiInputEventHandler::Class())) {
2035  AliMultiInputEventHandler *multiInputHandler=(AliMultiInputEventHandler*)inputHandler;
2036  multiInputHandler->AddInputEventHandler(esdHandler);
2037  }
2038  else {
2039  if (!inputHandler) {
2040  mgr->SetInputEventHandler(esdHandler);
2041  }
2042  else {
2043  ::Error("AddESDHandler", "inputHandler is NOT null. ESD handler was NOT added !!!");
2044  return NULL;
2045  }
2046  }
2047 
2048  return esdHandler;
2049 }
2050 
virtual Bool_t Run()
Run function. This is the core function of the analysis and contains the user code. Therefore users have to implement this function.
Bool_t fGeneratePythiaInfoObject
Generate Pythia info object.
TObjArray fClusterCollArray
cluster collection array
Int_t fNVertSPDCont
!event SPD vertex number of contributors
void SetParticlePtCut(Double_t cut)
Bool_t fIsPythia
trigger, if it is a PYTHIA production
double Double_t
Definition: External.C:58
void SetParton7(Float_t pt, Float_t eta, Float_t phi, Float_t mass=0)
TH2 * fHistPtHardBinCorr
!Correlation between global and local (per-event) -hard bin
TH1 * fHistTrials
!trials from pyxsec.root
Bool_t fPtHardInitialized
!flag whether the -hard bin was initialized, purely for internal processing
Definition: External.C:236
void SetArray(const AliVEvent *event)
EMCAL Level1 gamma trigger, low threshold.
AliEmcalPythiaInfo * fPythiaInfo
!event parton info
Bool_t AcceptTrack(AliVParticle *track, Int_t c=0) const
ULong_t GetTriggerList()
Get list of selected triggers of the given event.
Int_t fPtHardBinGlobal
!event -hard bin, detected from filename
EMCAL Level1 jet trigger, low threshold.
Bool_t HasTriggerType(TriggerType triggersel)
Check if event has a given trigger type.
Int_t fNTrials
!event trials
UInt_t fOffTrigger
offline trigger for event selection
Double_t fVertexSPD[3]
!event Svertex
Double_t fMinCent
min centrality for event selection
Double_t fTrackPtCut
cut on track pt in event selection
Recalculated jet trigger patch; does not need to be above trigger threshold.
Base task in the EMCAL framework.
Bool_t fLocalInitialized
whether or not the task has been already initialized
Bool_t fUsePtHardBinScaling
Use -hard bin scaling in merging.
TH2 * fHistPtHardCorrGlobal
!Correlation between -hard value and global bin
void SetPartonFlag7(Int_t flag7)
Container with name, TClonesArray and cuts for particles.
Bool_t fUseXsecFromHeader
! Use cross section from header instead of pyxsec.root (purely transient)
TSystem * gSystem
void SetTrackPtCut(Double_t cut, Int_t c=0)
Apply cut on the transverse momentum of all tracks in the track container with index c...
static void GetEtaPhiDiff(const AliVTrack *t, const AliVCluster *v, Double_t &phidiff, Double_t &etadiff)
Calculate and difference between a track (t) and a cluster (c).
Double_t fMinBinPt
min pt in histograms
Double_t fEPV0
!event plane V0
Double_t phiMin
static AliEmcalDownscaleFactorsOCDB * Instance()
Int_t fNPtHardBins
Number of -hard bins in the dataset.
Bool_t fGeneralHistograms
whether or not it should fill some general histograms
Declaration of class AliAnalysisTaskEmcalEmbeddingHelper.
Bool_t AcceptCluster(AliVCluster *clus, Int_t c=0) const
Cluster selection.
TCanvas * c
Definition: TestFitELoss.C:172
virtual void UserExecOnce()
Task initializations handled in user tasks.
Int_t fCentBin
!event centrality bin
virtual Bool_t IsTriggerSelected()
Selection of a hardware trigger.
TH1 * fHistEventsAfterSel
!total number of events per pt hard bin after selection
Double_t GetDownscaleFactorForTriggerClass(const TString &trigger) const
const AliMCParticleIterableContainer all() const
Int_t fMinVertexContrib
Min. number of vertex contributors.
Float_t fPtHardAndClusterPtFactor
Factor between ptHard and cluster pT to reject/accept event.
Double_t fMinPtTrackInEmcal
min pt track in emcal
AliStack * stack
TH1 * fHistEventPlane
!event plane distribution
Bool_t fUseBuiltinEventSelection
Use builtin event selection of the AliAnalysisTaskEmcal instead of AliEventCuts.
TH1 * fHistEvents
!total number of events per pt hard bin
void SetClusPtCut(Double_t cut, Int_t c=0)
Apply cut on for all clusters in container with index c.
AliClusterContainer * AddClusterContainer(const char *n)
Create new cluster container and attach it to the task.
virtual void NextEvent(const AliVEvent *event)
Preparation for the next event.
Double_t fEPV0C
!event plane V0C
void SetParton6(Float_t pt, Float_t eta, Float_t phi, Float_t mass=0)
TH1 * fHistCentrality
!event centrality distribution
Container for particles within the EMCAL framework.
Bool_t fIsEmbedded
trigger, embedded signal
TObjArray fParticleCollArray
particle/track collection array
BeamType
Switch for the beam type.
void SetTrackEtaLimits(Double_t min, Double_t max, Int_t c=0)
Apply cut on the pseudorapidity of the all tracks in the track container with index c...
AliParticleContainer * GetParticleContainer(Int_t i=0) const
Get particle container attached to this task.
TProfile * fHistXsectionAfterSel
!x section from pythia header
TriggerType
Switch for EMCAL trigger types.
virtual Bool_t CheckMCOutliers()
Filter the mc tails in pt-hard distributions.
EMCalTriggerMode_t fEMCalTriggerMode
EMCal trigger selection mode.
virtual Bool_t FillHistograms()
Function filling histograms.
Int_t GetNParticles(Int_t i=0) const
Get number of particles in container attached to this task with index i.
TClonesArray * fCaloClusters
!clusters
Bool_t fUseNewCentralityEstimation
Use new centrality estimation (for 2015 data)
Bool_t IsTrackInEmcalAcceptance(AliVParticle *part, Double_t edges=0.9) const
Determines if a track is inside the EMCal acceptance.
int Int_t
Definition: External.C:63
TH1 * fHistTriggerClasses
!number of events in each trigger class
Bool_t fCountDownscaleCorrectedEvents
Count event number corrected for downscaling.
unsigned int UInt_t
Definition: External.C:33
float Float_t
Definition: External.C:68
Double_t fMaxVz
max vertex for event selection
void GeneratePythiaInfoObject(AliMCEvent *mcEvent)
Copy some information about the Pythia event in a PythaInfo object.
AliEMCALGeometry * fGeom
!emcal geometry
The overlap between low and high threshold trigger is assigned to the lower threshold only...
kRecalculated gamma trigger patch; does not need to be above trigger threshold
TString fCaloTriggerPatchInfoName
trigger patch info array name
TString fCaloTriggersName
name of calo triggers collection
TH1 * fHistTriggerClassesCorr
!corrected number of events in each trigger class
Bool_t fIsHerwig
trigger, if it is a HERWIG production
AliGenPythiaEventHeader * fPythiaHeader
!event Pythia header
void SetTrackPhiLimits(Double_t min, Double_t max, Int_t c=0)
Apply cut on azimuthal angle of the all tracks in the track container with index c...
Double_t phiMax
AliParticleContainer * AddParticleContainer(const char *n)
Create new particle container and attach it to the task.
AliAnalysisUtils * fAliAnalysisUtils
!vertex selection (optional)
BeamType fForceBeamType
forced beam type
void SetUseScaling(Bool_t val)
Definition: AliEmcalList.h:31
Int_t fNcentBins
how many centrality bins
AliClusterContainer * GetClusterContainer(Int_t i=0) const
Get cluster container attached to this task.
Base class for container structures within the EMCAL framework.
TriggerType fTriggerTypeSel
trigger type to select based on trigger patches
virtual Bool_t AcceptCluster(Int_t i, UInt_t &rejectionReason) const
virtual Bool_t FillGeneralHistograms()
Filling general histograms.
TString fTrigClass
trigger class name for event selection
Float_t fPtHardAndJetPtFactor
Factor between ptHard and jet pT to reject/accept event.
AliVCluster * GetAcceptCluster(Int_t i) const
TClonesArray * GetParticleArray(Int_t i=0) const
Get TClonesArray with particles.
BeamType GetBeamType() const
Get beam type.
Double_t fMinVz
min vertex for event selection
virtual AliVParticle * GetAcceptParticle(Int_t i=-1) const
BeamType fBeamType
!event beam type
Float_t fPtHardAndTrackPtFactor
Factor between ptHard and track pT to reject/accept event.
Double_t fCent
!event centrality
TClonesArray * GetArray() const
Double_t fMinEventPlane
minimum event plane value
TString fCaloCellsName
name of calo cell collection
Int_t fMCLabelShift
if MC label > fMCLabelShift, MC label -= fMCLabelShift
Int_t GetNClusters(Int_t i=0) const
Get number of clusters in the cluster container attached to this task with index i.
Int_t fNVertCont
!event vertex number of contributors
Bool_t fMCRejectFilter
enable the filtering of events by tail rejection
Bool_t fGetPtHardBinFromName
Obtain pt-hard bin from file path.
unsigned long ULong_t
Definition: External.C:38
Double_t fZvertexDiff
upper limit for distance between primary and SPD vertex
virtual Bool_t AcceptParticle(const AliVParticle *vp, UInt_t &rejectionReason) const
AliEMCALTriggerPatchInfo * GetMainTriggerPatch(TriggerCategory triggersel=kTriggerLevel1Jet, Bool_t doSimpleOffline=kFALSE)
Get main trigger match.
EMCAL Level0 trigger.
EMCAL Level1 jet trigger, high threshold.
Int_t fSelectPtHardBin
select one pt hard bin for analysis
AliMCParticleContainer * AddMCParticleContainer(const char *n)
Create new container for MC particles and attach it to the task.
static Double_t GetParallelFraction(AliVParticle *part1, AliVParticle *part2)
Calculates the fraction of momentum z of part 1 w.r.t. part 2 in the direction of part 2...
virtual Bool_t RetrieveEventObjects()
Retrieve common objects from event.
Bool_t fRejectPileup
Reject pilup using function AliAnalysisUtils::IsPileUpEvent()
TProfile * fHistXsection
!x section from pyxsec.root
Bool_t PythiaInfoFromFile(const char *currFile, Float_t &fXsec, Float_t &fTrials, Int_t &pthard)
Loading PYTHIA information from external cross section file into the task.
void UserExec(Option_t *option)
Event loop, called for each event.
Int_t fMinMCLabel
minimum MC label value for the tracks/clusters being considered MC particles
void SetPartonFlag6(Int_t flag6)
AliVCaloCells * fCaloCells
!cells
const TString & GetArrayName() const
TClonesArray * GetArrayFromEvent(const char *name, const char *clname=0)
Read a TClonesArray from event.
Enhanced TList-derived class that implements correct merging for pt_hard binned production.
Definition: AliEmcalList.h:25
Double_t fEventPlaneVsEmcal
select events which have a certain event plane wrt the emcal
Bool_t IsEventSelectedInternal()
Perform event selection (old method)
virtual Bool_t IsEventSelected()
Performing event selection.
Float_t fPtHard
!event -hard
TH1 * fHistPtHard
! -hard distribution
void SetParticleEtaLimits(Double_t min, Double_t max)
AliEventCuts fAliEventCuts
Event cuts (run2 defaults)
AliEmcalList * fOutput
!output list
Handler for downscale factors for various triggers obtained from the OCDB.
Double_t fMaxBinPt
max pt in histograms
Int_t fPtHardBin
!event -hard bin
virtual void RunChanged(Int_t)
Process tasks relevant when a file with a different run number is processed.
TClonesArray * fTracks
!tracks
TH1 * fHistTrialsAfterSel
!total number of trials per pt hard bin after selection
AliGenHerwigEventHeader * fHerwigHeader
!event Herwig header
void LoadPythiaInfo(AliVEvent *event)
Load parton info.
Bool_t fIsEsd
!whether it&#39;s an ESD analysis
static AliAODInputHandler * AddAODHandler()
Add an AOD handler to the analysis manager.
Double_t fVertex[3]
!event vertex
AliTrackContainer * AddTrackContainer(const char *n)
Create new track container and attach it to the task.
Bool_t fCreateHisto
whether or not create histograms
Bool_t UserNotify()
Notifying the user that the input data file has changed and performing steps needed to be done...
Store some informaion about a Pythia eventThis class is used to store some information about a Pythia...
TFile * file
TList with histograms for a given trigger.
TH1 * fHistEventRejection
!book keep reasons for rejecting event
Int_t nevents[nsamples]
TClonesArray * fTriggerPatchInfo
!trigger patch info array
TClonesArray * GetClusterArray(Int_t i=0) const
Get TClonesArray with EMCAL clusters.
Bool_t FileChanged()
Steps to be executed when a few file is loaded into the input handler.
Double_t fEPV0A
!event plane V0A
virtual void ExecOnce()
Perform steps needed to initialize the analysis.
TString fCentEst
name of V0 centrality estimator
void SetArray(const AliVEvent *event)
TString fPythiaInfoName
name of pythia info object
Int_t GetRunNumber(TString)
Definition: PlotMuonQA.C:2235
Declaration of class AliEmcalPythiaInfo.
const char Option_t
Definition: External.C:48
void SetClusPtCut(Double_t cut)
Int_t fRunNumber
!run number (triggering RunChanged())
EMCAL Level1 gamma trigger, high threshold.
void AddObjectToEvent(TObject *obj, Bool_t attempt=kFALSE)
Add object to event.
AliVCaloTrigger * fCaloTriggers
!calo triggers
void SetRejectionReasonLabels(TAxis *axis)
void UserCreateOutputObjects()
Main initialization function on the worker.
Bool_t fFileChanged
! Signal triggered when the file has changed
TH1 * fHistZVertex
!z vertex position
Int_t fMinNTrack
minimum nr of tracks in event with pT>fTrackPtCut
Int_t GetNEntries() const
static Byte_t GetTrackType(const AliVTrack *t)
Get track type encoded from bits 20 and 21.
Bool_t fUseAliAnaUtils
used for LHC13* data: z-vtx, Ncontributors, z-vtx resolution cuts
void SetClusTimeCut(Double_t min, Double_t max, Int_t c=0)
Apply cut on cluster time for clusters in container with index c.
bool Bool_t
Definition: External.C:53
ULong_t fTriggers
list of fired triggers
static AliESDInputHandler * AddESDHandler()
Add a ESD handler to the analysis manager.
Double_t fMaxEventPlane
maximum event plane value
void SetPythiaEventWeight(Float_t ptWeight)
Float_t fXsection
!x-section from pythia header
TH1 * fHistEventCount
!incoming and selected events
TTree * tree
Double_t fMaxCent
max centrality for event selection
void SetClusTimeCut(Double_t min, Double_t max)
TriggerCategory
Online trigger categories.
void SetParticlePhiLimits(Double_t min, Double_t max)
AliVParticle * GetAcceptParticleFromArray(Int_t p, Int_t c=0) const
Get particle p if accepted from container with index c If particle not accepted return 0...
Container structure for EMCAL clusters.
TString fMinBiasRefTrigger
Name of the minmum bias reference trigger, used in the calculation of downscale-corrected event numbe...
Container for MC-true particles within the EMCAL framework.
Bool_t fNeedEmcalGeom
whether or not the task needs the emcal geometry
AliVCluster * GetAcceptClusterFromArray(Int_t cl, Int_t c=0) const
Get cluster cl if accepted from container c If particle not accepted return 0.
Int_t fNbins
no. of pt bins
Bool_t fTklVsClusSPDCut
Apply tracklet-vs-cluster SPD cut to reject background events in pp.
AliAnalysisTaskEmcal()
Default constructor.
TH2 * fHistPtHardCorr
!Correlation between -hard value and bin
TArrayI fPtHardBinning
-hard binning
TList * OpenFile(const char *fname)
Definition: DrawAnaELoss.C:65
virtual ~AliAnalysisTaskEmcal()
Destructor.
static Double_t fgkEMCalDCalPhiDivide
phi value used to distinguish between DCal and EMCal