AliPhysics  vAN-20150427 (e6e7aad)
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Macros
AliAnalysisTaskPtEMCalTrigger.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2014, 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 
16 /*
17  * Analysis task of the pt analysis on EMCal-triggered events
18  *
19  * Author: Markus Fasel
20  */
21 
22 #include <map>
23 #include <cstring>
24 #include <iostream>
25 #include <memory>
26 #include <vector>
27 #include <string>
28 #include <sstream>
29 
30 #include <TClonesArray.h>
31 #include <TDirectory.h>
32 #include <TH1.h>
33 #include <THashList.h>
34 #include <TList.h>
35 #include <TKey.h>
36 #include <TMath.h>
37 #include <TObjArray.h>
38 #include <TObjString.h>
39 #include <TString.h>
40 #include <TVector2.h>
41 
42 #include "AliAODEvent.h"
43 #include "AliESDEvent.h"
44 #include "AliInputEventHandler.h"
45 #include "AliMCEvent.h"
46 #include "AliParticleContainer.h"
47 #include "AliVCluster.h"
48 #include "AliVParticle.h"
49 #include "AliVTrack.h"
50 #include "AliVVertex.h"
51 
52 #include "AliClusterContainer.h"
53 #include "AliEmcalJet.h"
54 #include "AliEmcalTriggerPatchInfo.h"
55 #include "AliEmcalPhysicsSelection.h"
57 #include "AliEMCalHistoContainer.h"
61 #include "AliJetContainer.h"
62 #include "AliParticleContainer.h"
63 #include "AliPicoTrack.h"
64 
66 
67 namespace EMCalTriggerPtAnalysis {
68 
69  /*
70  * constants
71  */
72  const Int_t AliAnalysisTaskPtEMCalTrigger::kNJetRadii = 4;
73  const Double_t jetRadVals[AliAnalysisTaskPtEMCalTrigger::kNJetRadii] = {0.2, 0.3, 0.4, 0.5};
74  const Double_t *AliAnalysisTaskPtEMCalTrigger::kJetRadii = jetRadVals;
75 
76  //______________________________________________________________________________
77  AliAnalysisTaskPtEMCalTrigger::AliAnalysisTaskPtEMCalTrigger():
78  AliAnalysisTaskEmcalJet(),
79  fHistos(NULL),
80  fListTrackCuts(NULL),
81  fEtaRange(),
82  fPtRange(),
83  fEnergyRange(),
84  fVertexRange(),
85  fJetContainersMC(),
86  fJetContainersData(),
87  fSelectAllTracks(kFALSE),
88  fSwapEta(kFALSE),
89  fUseTriggersFromTriggerMaker(kFALSE)
90  {
91  /*
92  * Dummy constructor, initialising the values with default (NULL) values
93  */
94  }
95 
96  //______________________________________________________________________________
97  AliAnalysisTaskPtEMCalTrigger::AliAnalysisTaskPtEMCalTrigger(const char *name):
98  AliAnalysisTaskEmcalJet(name, kTRUE),
99  fHistos(NULL),
100  fListTrackCuts(NULL),
101  fEtaRange(),
102  fPtRange(),
103  fEnergyRange(),
104  fVertexRange(),
105  fJetContainersMC(),
106  fJetContainersData(),
107  fSelectAllTracks(kFALSE),
108  fSwapEta(kFALSE),
109  fUseTriggersFromTriggerMaker(kFALSE)
110  {
111  /*
112  * Main constructor, setting default values for eta and zvertex cut
113  */
114 
115  fListTrackCuts = new TList;
116  fListTrackCuts->SetOwner(false);
117 
118  // Set default cuts
119  fEtaRange.SetLimits(-0.8, 0.8);
120  fPtRange.SetLimits(0.15, 100.);
121  fEnergyRange.SetLimits(0., 1000.);
122  fVertexRange.SetLimits(-10., 10.);
123  SetMakeGeneralHistograms(kTRUE);
124  }
125 
126  //______________________________________________________________________________
127  AliAnalysisTaskPtEMCalTrigger::~AliAnalysisTaskPtEMCalTrigger(){
128  /*
129  * Destructor, deleting output
130  */
131  //if(fTrackSelection) delete fTrackSelection;
132  if(fHistos) delete fHistos;
133  if(fListTrackCuts) delete fListTrackCuts;
134  }
135 
136  //______________________________________________________________________________
137  void AliAnalysisTaskPtEMCalTrigger::UserCreateOutputObjects(){
138  /*
139  * Create the list of output objects and define the histograms.
140  * Also adding the track cuts to the list of histograms.
141  */
142  AliAnalysisTaskEmcal::UserCreateOutputObjects();
143  SetCaloTriggerPatchInfoName("EmcalTriggers");
144  fHistos = new AliEMCalHistoContainer("PtEMCalTriggerHistograms");
145  fHistos->ReleaseOwner();
146 
147  if(fJetContainersMC.GetEntries()){
148  AliDebug(1,"Jet containers for MC truth:");
149  TObjString *contname(NULL);
150  TIter contMCIter(&fJetContainersMC);
151  while((contname = dynamic_cast<TObjString *>(contMCIter.Next())))
152  AliDebug(1, Form("Next container: %s", contname->String().Data()));
153  }
154  if(fJetContainersData.GetEntries()){
155  AliDebug(1, "Jet containers for Data:");
156  TObjString *contname(NULL);
157  TIter contDataIter(&fJetContainersData);
158  while((contname = dynamic_cast<TObjString *>(contDataIter.Next())))
159  AliDebug(1, Form("Next container: %s", contname->String().Data()));
160  }
161  if(fJetCollArray.GetEntries()){
162  AliDebug(1, "Jet containers attached to this task:");
163  AliJetContainer *cont(NULL);
164  TIter contIter(&fJetCollArray);
165  while((cont = dynamic_cast<AliJetContainer *>(contIter.Next())))
166  AliDebug(1, Form("Container: %s", cont->GetName()));
167  }
168 
169  std::map<std::string, std::string> triggerCombinations;
170  const char *triggernames[12] = {"MinBias", "EMCJHigh", "EMCJLow", "EMCGHigh", "EMCGLow", "NoEMCal", "EMCHighBoth", "EMCHighGammaOnly", "EMCHighJetOnly", "EMCLowBoth", "EMCLowGammaOnly", "EMCLowJetOnly"},
171  *bitnames[4] = {"CINT7", "EMC7", "kEMCEGA", "kEMCEJE"};
172  // Define axes for the trigger correlation histogram
173  const TAxis *triggeraxis[5]; memset(triggeraxis, 0, sizeof(const TAxis *) * 5);
174  const TAxis *bitaxes[4]; memset(bitaxes, 0, sizeof(TAxis *) * 4);
175  const char *binlabels[2] = {"OFF", "ON"};
176  TAxis mytrgaxis[5], mybitaxis[4];
177  for(int itrg = 0; itrg < 5; ++itrg){
178  DefineAxis(mytrgaxis[itrg], triggernames[itrg], triggernames[itrg], 2, -0.5, 1.5, binlabels);
179  triggeraxis[itrg] = mytrgaxis+itrg;
180  if(itrg < 4){
181  DefineAxis(mybitaxis[itrg], bitnames[itrg], bitnames[itrg], 2, -0.5, 1.5, binlabels);
182  bitaxes[itrg] = mybitaxis+itrg;
183  }
184  }
185  // Define names and titles for different triggers in the histogram container
186  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[0], "min. bias events"));
187  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[1], "jet-triggered events (high threshold)"));
188  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[2], "jet-triggered events (low threshold)"));
189  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[3], "gamma-triggered events (high threshold)"));
190  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[4], "gamma-triggered events (low threshold)"));
191  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[5], "non-EMCal-triggered events"));
192  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[6], "jet and gamma triggered events (high threshold)"));
193  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[7], "exclusively gamma-triggered events (high threshold)"));
194  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[8], "exclusively jet-triggered events (high threshold)"));
195  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[9], "jet and gamma triggered events (low threshold)"));
196  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[10], "exclusively gamma-triggered events (low threshold)"));
197  triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[11], "exclusively-triggered events (low threshold)"));
198  // Define axes for the pt histogram
199  // Dimensions:
200  // 1. pt
201  // 2. eta
202  // 3. phi
203  // 4. vertex
204  // 5. pileup (0 = all events, 1 = after pileup rejection)
205  // 6. track cuts (0 = no cuts; 1 = after std cuts)
206  TArrayD ptbinning, zvertexBinning, etabinning, pileupaxis(3);
207  pileupaxis[0] = -0.5; pileupaxis[1] = 0.5; pileupaxis[2] = 1.5;
208  CreateDefaultPtBinning(ptbinning);
209  CreateDefaultZVertexBinning(zvertexBinning);
210  CreateDefaultEtaBinning(etabinning);
211  TAxis htrackaxes[7];
212  DefineAxis(htrackaxes[0], "pt", "p_{t} (GeV/c)", ptbinning);
213  DefineAxis(htrackaxes[1], "eta", "#eta", etabinning);
214  DefineAxis(htrackaxes[2], "phi", "#phi", 20, 0, 2 * TMath::Pi());
215  DefineAxis(htrackaxes[3], "zvertex", "z_{V} (cm)", zvertexBinning);
216  DefineAxis(htrackaxes[4], "pileup", "Pileup rejection", 2, -0.5, 1.5);
217  DefineAxis(htrackaxes[5], "trackcuts", "Track Cuts", (fListTrackCuts ? fListTrackCuts->GetEntries() : 0) + 1, -0.5, (fListTrackCuts ? fListTrackCuts->GetEntries() : 0) + 0.5);
218  DefineAxis(htrackaxes[6], "mbtrigger", "Has MB trigger", 2, -0.5, 1.5);
219  const TAxis *trackaxes[7];
220  for(int iaxis = 0; iaxis < 7; ++iaxis) trackaxes[iaxis] = htrackaxes + iaxis;
221  TAxis hclusteraxes[4];
222  DefineAxis(hclusteraxes[0], "energy", "E (GeV)", ptbinning);
223  DefineAxis(hclusteraxes[1], "zvertex", "z_{V} (cm)", zvertexBinning);
224  DefineAxis(hclusteraxes[2], "pileup", "Pileup rejection", 2,1 -0.5, 1.5);
225  DefineAxis(hclusteraxes[3], "mbtrigger", "Has MB trigger", 2, -0.5, 1.5);
226  const TAxis *clusteraxes[4];
227  for(int iaxis = 0; iaxis < 4; ++iaxis) clusteraxes[iaxis] = hclusteraxes + iaxis;
228  TAxis hpatchenergyaxes[5];
229  DefineAxis(hpatchenergyaxes[0], "energy", "Patch energy (GeV)", 100, 0., 100);
230  DefineAxis(hpatchenergyaxes[1], "eta", "#eta", etabinning);
231  DefineAxis(hpatchenergyaxes[2], "phi", "#phi", 20, 0, 2 * TMath::Pi());
232  DefineAxis(hpatchenergyaxes[3], "isMain", "Main trigger", 2, -0.5, 1.5);
233  DefineAxis(hpatchenergyaxes[4], "emcalgood", "EMCAL good event", 2, -0.5, 1.5);
234  const TAxis *patchenergyaxes[5];
235  for(int iaxis = 0; iaxis < 5; ++iaxis) patchenergyaxes[iaxis] = hpatchenergyaxes + iaxis;
236  TAxis hpatchampaxes[5];
237  DefineAxis(hpatchampaxes[0], "amplitude", "Patch energy (GeV)", 10000, 0., 10000.);
238  DefineAxis(hpatchampaxes[1], "eta", "#eta", etabinning);
239  DefineAxis(hpatchampaxes[2], "phi", "#phi", 20, 0, 2 * TMath::Pi());
240  DefineAxis(hpatchampaxes[3], "isMain", "Main trigger", 2, -0.5, 1.5);
241  DefineAxis(hpatchampaxes[4], "emcalgood", "EMCAL good event", 2, -0.5, 1.5);
242  const TAxis *patchampaxes[5];
243  for(int iaxis = 0; iaxis < 5; ++iaxis) patchampaxes[iaxis] = hpatchampaxes + iaxis;
244  try{
245  std::string patchnames[] = {"Level0", "JetHigh", "JetLow", "GammaHigh", "GammaLow"};
246  for(std::string * triggerpatch = patchnames; triggerpatch < patchnames + sizeof(patchnames)/sizeof(std::string); ++triggerpatch){
247  fHistos->CreateTHnSparse(Form("Energy%s", triggerpatch->c_str()), Form("Patch energy for %s trigger patches", triggerpatch->c_str()), 5, patchenergyaxes, "s");
248  fHistos->CreateTHnSparse(Form("EnergyRough%s", triggerpatch->c_str()), Form("Rough patch energy for %s trigger patches", triggerpatch->c_str()), 5, patchenergyaxes, "s");
249  fHistos->CreateTHnSparse(Form("Amplitude%s", triggerpatch->c_str()), Form("Patch amplitude for %s trigger patches", triggerpatch->c_str()), 5, patchampaxes, "s");
250  }
251 
252  // Create histogram for MC-truth
253  fHistos->CreateTHnSparse("hMCtrueParticles", "Particle-based histogram for MC-true particles", 5, trackaxes, "s");
254  if(fJetCollArray.GetEntries()){
255  for(int irad = 0; irad < kNJetRadii; irad++){
256  fHistos->CreateTHnSparse(Form("hMCtrueParticlesRad%02d", int(kJetRadii[irad]*10)),
257  Form("Particle-based histogram for MC-true particles in Jets with radius %.1f", kJetRadii[irad]*10), 5, trackaxes, "s");
258  }
259  // histogram for isolated particles
260  fHistos->CreateTHnSparse("hMCtrueParticlesIsolated", "Particle-based histogram for isolated MC-true particles", 5, trackaxes, "s");
261  }
262  for(std::map<std::string,std::string>::iterator it = triggerCombinations.begin(); it != triggerCombinations.end(); ++it){
263  const std::string name = it->first, &title = it->second;
264  // Create event-based histogram
265  fHistos->CreateTH2(Form("hEventHist%s", name.c_str()), Form("Event-based data for %s events; pileup rejection; z_{V} (cm)", title.c_str()), pileupaxis, zvertexBinning);
266  // Create track-based histogram
267  fHistos->CreateTHnSparse(Form("hTrackHist%s", name.c_str()), Form("Track-based data for %s events", title.c_str()), 7, trackaxes, "s");
268  fHistos->CreateTHnSparse(Form("hTrackInAcceptanceHist%s", name.c_str()), Form("Track-based data for %s events for tracks matched to EMCal clusters", title.c_str()), 7, trackaxes, "s");
269  fHistos->CreateTHnSparse(Form("hMCTrackHist%s", name.c_str()), Form("Track-based data for %s events with MC kinematics", title.c_str()), 7, trackaxes, "s");
270  fHistos->CreateTHnSparse(Form("hMCTrackInAcceptanceHist%s", name.c_str()), Form("Track-based data for %s events with MC kinematics for tracks matched to EMCal clusters", title.c_str()), 7, trackaxes, "s");
271  // Create cluster-based histogram (Uncalibrated and calibrated clusters)
272  fHistos->CreateTHnSparse(Form("hClusterCalibHist%s", name.c_str()), Form("Calib. cluster-based histogram for %s events", title.c_str()), 4, clusteraxes, "s");
273  fHistos->CreateTHnSparse(Form("hClusterUncalibHist%s", name.c_str()), Form("Uncalib. cluster-based histogram for %s events", title.c_str()), 4, clusteraxes, "s");
274  if(fJetCollArray.GetEntries()){
275  // Create histograms for particles in different jetfinder radii, only track-based
276  for(int irad = 0; irad < kNJetRadii; irad++){
277  fHistos->CreateTHnSparse(Form("hTrackHist%sRad%02d", name.c_str(), int(kJetRadii[irad]*10)),
278  Form("Track-based data for %s events for tracks in jets with Radius %.1f", title.c_str(), kJetRadii[irad]), 7, trackaxes, "s");
279  fHistos->CreateTHnSparse(Form("hTrackInAcceptanceHist%sRad%02d", name.c_str(), int(kJetRadii[irad]*10)),
280  Form("Track-based data for %s events for tracks matched to EMCal clusters in jets with Radius %.1f", title.c_str(), kJetRadii[irad]),
281  7, trackaxes, "s");
282  fHistos->CreateTHnSparse(Form("hMCTrackHist%sRad%02d", name.c_str(), int(kJetRadii[irad]*10)),
283  Form("Track-based data for %s events with MC kinematics for tracks in jets with Radius %.1f", title.c_str(), kJetRadii[irad]),
284  7, trackaxes, "s");
285  fHistos->CreateTHnSparse(Form("hMCTrackInAcceptanceHist%sRad%02d", name.c_str(), int(kJetRadii[irad]*10)),
286  Form("Track-based data for %s events with MC kinematics for tracks matched to EMCal clusters in jets with Radius %.1f", title.c_str(), kJetRadii[irad]),
287  7, trackaxes, "s");
288  fHistos->CreateTHnSparse(Form("hClusterCalibHist%sRad%02d", name.c_str(), int(kJetRadii[irad]*10)),
289  Form("Calib. cluster-based histogram for %s events for clusters in Jets with radius %.1f", title.c_str(), kJetRadii[irad]), 4, clusteraxes, "s");
290  }
291  }
292  // Create also histograms for isolated particles
293  fHistos->CreateTHnSparse(Form("hTrackHist%sIsolated", name.c_str()), Form("Track-based data for %s events for isolated tracks", title.c_str()), 7, trackaxes, "s");
294  fHistos->CreateTHnSparse(Form("hTrackInAcceptanceHist%sIsolated", name.c_str()), Form("Track-based data for %s events for isolated tracks matched to EMCal clusters", title.c_str()), 7, trackaxes, "s");
295  fHistos->CreateTHnSparse(Form("hMCTrackHist%sIsolated", name.c_str()), Form("Track-based data for %s events with MC kinematics for isolated tracks", title.c_str()), 7, trackaxes, "s");
296  fHistos->CreateTHnSparse(Form("hMCTrackInAcceptanceHist%sIsolated", name.c_str()), Form("Track-based data for %s events with MC kinematics for isolated tracks matched to EMCal clusters", title.c_str()), 7, trackaxes, "s");
297  }
298  fHistos->CreateTHnSparse("hEventTriggers", "Trigger type per event", 5, triggeraxis);
299  fHistos->CreateTHnSparse("hEventsTriggerbit", "Trigger bits for the different events", 4, bitaxes);
300  } catch (HistoContainerContentException &e){
301  std::stringstream errormessage;
302  errormessage << "Creation of histogram failed: " << e.what();
303  AliError(errormessage.str().c_str());
304  }
305  fOutput->Add(fHistos->GetListOfHistograms());
306  if(fListTrackCuts && fListTrackCuts->GetEntries()){
307  TIter cutIter(fListTrackCuts);
308  AliEMCalPtTaskVTrackSelection *cutObject(NULL);
309  while((cutObject = dynamic_cast<AliEMCalPtTaskVTrackSelection *>(cutIter()))){
310  AliESDtrackCuts *cuts = dynamic_cast<AliESDtrackCuts *>(cutObject->GetTrackCuts(0));
311  if(cuts){
312  cuts->DefineHistograms();
313  fOutput->Add(cuts);
314  }
315  }
316  }
317  PostData(1, fOutput);
318  }
319 
320  //______________________________________________________________________________
321  Bool_t AliAnalysisTaskPtEMCalTrigger::Run(){
322  /*
323  * Runs the event loop
324  *
325  * @param option: Additional options
326  */
327  // Common checks: Have SPD vertex and primary vertex from tracks, and both need to have at least one contributor
328  AliDebug(1,Form("Number of calibrated clusters: %d", fCaloClusters->GetEntries()));
329  AliDebug(1,Form("Number of matched tracks: %d", fTracks->GetEntries()));
330  if(fMCEvent){
331  // Build always trigger strig from the trigger maker in case of MC
332  fUseTriggersFromTriggerMaker = kTRUE;
333  }
334 
335  Bool_t emcalGood = fInputHandler->IsEventSelected() & AliEmcalPhysicsSelection::kEmcalOk;
336 
337  // Loop over trigger patches, fill patch energy
338  AliEmcalTriggerPatchInfo *triggerpatch(NULL);
339  TIter patchIter(this->fTriggerPatchInfo);
340  while((triggerpatch = dynamic_cast<AliEmcalTriggerPatchInfo *>(patchIter()))){
341  double triggerpatchinfo[5] = {triggerpatch->GetPatchE(), triggerpatch->GetEtaGeo(), triggerpatch->GetPhiGeo(), triggerpatch->IsMainTrigger() ? 1. : 0., emcalGood ? 1. : 0.};
342  double triggerpatchinfoamp[5] = {static_cast<double>(triggerpatch->GetADCAmp()), triggerpatch->GetEtaGeo(), triggerpatch->GetPhiGeo(), triggerpatch->IsMainTrigger() ? 1. : 0., emcalGood ? 1. : 0.};
343  double triggerpatchinfoer[5] = {triggerpatch->GetADCAmpGeVRough(), triggerpatch->GetEtaGeo(), triggerpatch->GetPhiGeo(), triggerpatch->IsMainTrigger() ? 1. : 0., emcalGood ? 1. : 0.};
344  if(triggerpatch->IsJetHigh()){
345  fHistos->FillTHnSparse("EnergyJetHigh", triggerpatchinfo);
346  fHistos->FillTHnSparse("AmplitudeJetHigh", triggerpatchinfoamp);
347  fHistos->FillTHnSparse("EnergyRoughJetHigh", triggerpatchinfoer);
348  }
349  if(triggerpatch->IsJetLow()){
350  fHistos->FillTHnSparse("EnergyJetLow", triggerpatchinfo);
351  fHistos->FillTHnSparse("AmplitudeJetLow", triggerpatchinfoamp);
352  fHistos->FillTHnSparse("EnergyRoughJetLow", triggerpatchinfoer);
353  }
354  if(triggerpatch->IsGammaHigh()){
355  fHistos->FillTHnSparse("EnergyGammaHigh", triggerpatchinfo);
356  fHistos->FillTHnSparse("AmplitudeGammaHigh", triggerpatchinfoamp);
357  fHistos->FillTHnSparse("EnergyRoughGammaHigh", triggerpatchinfoer);
358  }
359  if(triggerpatch->IsGammaLow()){
360  fHistos->FillTHnSparse("EnergyGammaLow", triggerpatchinfo);
361  fHistos->FillTHnSparse("AmplitudeGammaLow", triggerpatchinfoamp);
362  fHistos->FillTHnSparse("EnergyRoughGammaLow", triggerpatchinfoer);
363  }
364  if(triggerpatch->IsLevel0()){
365  fHistos->FillTHnSparse("EnergyLevel0", triggerpatchinfo);
366  fHistos->FillTHnSparse("AmplitudeLevel0", triggerpatchinfoamp);
367  fHistos->FillTHnSparse("EnergyRoughLevel0", triggerpatchinfoer);
368  }
369  }
370 
371  const AliVVertex *vtxTracks = fInputEvent->GetPrimaryVertex(),
372  *vtxSPD = GetSPDVertex();
373  if(!(vtxTracks && vtxSPD)) return false;
374  if(!fVertexRange.IsInRange(vtxTracks->GetZ())) return false;
375  if(vtxTracks->GetNContributors() < 1 || vtxSPD->GetNContributors() < 1) return false;
376 
377  double triggers[5]; memset(triggers, 0, sizeof(double) * 5);
378  double triggerbits[4]; memset(triggerbits, 0, sizeof(double) * 4);
379  if(fInputHandler->IsEventSelected() & AliVEvent::kINT7){
380  triggers[0] = 1.;
381  triggerbits[0] = 1.;
382  }
383 
384  // check triggerbits
385  if(fInputHandler->IsEventSelected() & AliVEvent::kEMC7){
386  triggerbits[1] = 1.;
387  }
388  if(fInputHandler->IsEventSelected() & AliVEvent::kEMCEGA){
389  triggerbits[2] = 1.;
390  }
391  if(fInputHandler->IsEventSelected() & AliVEvent::kEMCEJE){
392  triggerbits[3] = 1.;
393  }
394  try{
395  fHistos->FillTHnSparse("hEventsTriggerbit", triggerbits);
396  } catch(HistoContainerContentException &e) {
397  std::stringstream errormessage;
398  errormessage << "Filling of histogram failed: " << e.what();
399  AliError(errormessage.str().c_str());
400  }
401 
402  std::vector<std::string> triggerstrings;
403  // EMCal-triggered event, distinguish types
404  TString trgstr(fUseTriggersFromTriggerMaker ? BuildTriggerString() : fInputEvent->GetFiredTriggerClasses());
405  AliDebug(1, Form("Triggerstring: %s\n", trgstr.Data()));
406  if(trgstr.Contains("EJ1")){
407  triggerstrings.push_back("EMCJHigh");
408  triggers[1] = 1;
409  if(trgstr.Contains("EG1"))
410  triggerstrings.push_back("EMCHighBoth");
411  else
412  triggerstrings.push_back("EMCHighJetOnly");
413  }
414  if(trgstr.Contains("EJ2")){
415  triggerstrings.push_back("EMCJLow");
416  triggers[2] = 1;
417  if(trgstr.Contains("EG2"))
418  triggerstrings.push_back("EMCLowBoth");
419  else
420  triggerstrings.push_back("EMCLowJetOnly");
421  }
422  if(trgstr.Contains("EG1")){
423  triggerstrings.push_back("EMCGHigh");
424  triggers[3] = 1;
425  if(!trgstr.Contains("EJ1"))
426  triggerstrings.push_back("EMCHighGammaOnly");
427  }
428  if(trgstr.Contains("EG2")){
429  triggerstrings.push_back("EMCGLow");
430  triggers[4] = 1;
431  if(!trgstr.Contains("EJ2"))
432  triggerstrings.push_back("EMCLowGammaOnly");
433  }
434 
435  try{
436  fHistos->FillTHnSparse("hEventTriggers", triggers);
437  } catch (HistoContainerContentException &e){
438  std::stringstream errormessage;
439  errormessage << "Filling of histogram failed: " << e.what();
440  AliError(errormessage.str().c_str());
441  }
442 
443  // apply event selection: Combine the Pileup cut from SPD with the other pA Vertex selection cuts.
444  bool isPileupEvent = fInputEvent->IsPileupFromSPD(3, 0.8, 3., 2., 5.);
445  isPileupEvent = isPileupEvent || (TMath::Abs(vtxTracks->GetZ() - vtxSPD->GetZ()) > 0.5);
446  double covSPD[6]; vtxSPD->GetCovarianceMatrix(covSPD);
447  isPileupEvent = isPileupEvent || (TString(vtxSPD->GetTitle()).Contains("vertexer:Z") && TMath::Sqrt(covSPD[5]) > 0.25);
448 
449  // Fill event-based histogram
450  const double &zv = vtxTracks->GetZ();
451  if(triggers[0]) FillEventHist("MinBias", zv, isPileupEvent);
452  if(!triggerstrings.size()) // Non-EMCal-triggered
453  FillEventHist("NoEMCal", zv, isPileupEvent);
454  else{
455  // EMCal-triggered events
456  for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
457  FillEventHist(it->c_str(), zv, isPileupEvent);
458  }
459 
460  const AliEmcalJet *foundJet(NULL);
461  char histname[1024];
462  std::vector<double> coneradii;
463  AliJetContainer *jetContMC(NULL), *jetContData(NULL);
464 
465  // Fill MC truth
466  AliVParticle *part(NULL);
467  if(fMCEvent){
468  if(fJetCollArray.GetEntries() &&
469  (jetContMC = dynamic_cast<AliJetContainer *>(fJetCollArray.FindObject((static_cast<TObjString *>(fJetContainersMC.At(0)))->String().Data())))){
470  // In case we have a jet array we loop over all MC selected particles in the particle container of the jet array
471  TIter particles(jetContMC->GetParticleContainer()->GetArray());
472  while((part = dynamic_cast<AliVParticle *>(particles()))){
473  if(part->Charge() == 0) continue;
474  if(!fEtaRange.IsInRange(part->Eta())) continue;
475  if(!fPtRange.IsInRange(part->Pt())) continue;
476  FillMCParticleHist("hMCtrueParticles", part, zv, isPileupEvent);
477 
478  /*
479  * Jet part: Find track in jet container,
480  * check according to number of particles in jet, and
481  * check for different cone radii
482  */
483  foundJet = FoundTrackInJet(part, jetContMC);
484  if(foundJet && foundJet->GetNumberOfConstituents() > 1){
485  for(int irad = 0; irad < kNJetRadii; irad++){
486  if(IsInRadius(part, foundJet, kJetRadii[irad])){
487  sprintf(histname, "hMCtrueParticlesRad%02d", int(kJetRadii[irad]*10));
488  FillMCParticleHist(histname, part, zv, isPileupEvent);
489  }
490  }
491  } else {
492  // isolated track
493  FillMCParticleHist("hMCtrueParticlesIsolated", part, zv, isPileupEvent);
494  }
495  }
496  } else {
497  // Use MC Event
498  for(int ipart = 0; ipart < fMCEvent->GetNumberOfTracks(); ipart++){
499  // Select only physical primary particles
500  part = fMCEvent->GetTrack(ipart);
501  if(part->Charge() == 0) continue;
502  if(!fEtaRange.IsInRange(part->Eta())) continue;
503  if(!fPtRange.IsInRange(part->Pt())) continue;
504  if(!fMCEvent->IsPhysicalPrimary(ipart)) continue;
505  FillMCParticleHist("hMCtrueParticles", part, zv, isPileupEvent);
506  }
507  }
508  }
509 
510  AliVTrack *track(NULL);
511  AliPicoTrack *picoTrack(NULL);
512  TObject *containerObject(NULL);
513  // Loop over all tracks (No cuts applied)
514  if(fSelectAllTracks){
515  // loop over all tracks only if requested
516  TIter allTrackIter(fTracks);
517  while((containerObject = dynamic_cast<TObject *>(allTrackIter()))){
518  if((picoTrack = dynamic_cast<AliPicoTrack *>(containerObject))){
519  track = picoTrack->GetTrack();
520  } else
521  track = dynamic_cast<AliVTrack *>(containerObject);
522  if(!IsTrueTrack(track)) continue;
523  if(!fEtaRange.IsInRange(track->Eta())) continue;
524  if(!fPtRange.IsInRange(track->Pt())) continue;
525  if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, 0, triggers[0]);
526  if(!triggerstrings.size()) // Non-EMCal-triggered
527  FillTrackHist("NoEMCal", track, zv, isPileupEvent, 0, triggers[0]);
528  else {
529  // EMCal-triggered events
530  for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
531  FillTrackHist(it->c_str(), track, zv, isPileupEvent, 0, triggers[0]);
532  }
533  }
534  }
535 
536  // Now apply track selection cuts
537  // allow for several track selections to be tested at the same time
538  // each track selection gets a different cut ID starting from 1
539  // cut ID 0 is reserved for the case of no cuts
540  // In case we have a jet container attached we check whether the track is
541  // found in a jet, and check for different cone radii around a jet
542  if(fListTrackCuts && fListTrackCuts->GetEntries()){
543  for(int icut = 0; icut < fListTrackCuts->GetEntries(); icut++){
544  AliEMCalPtTaskVTrackSelection *trackSelection = static_cast<AliEMCalPtTaskVTrackSelection *>(fListTrackCuts->At(icut));
545  TIter trackIter(trackSelection->GetAcceptedTracks(fTracks));
546  while((track = dynamic_cast<AliVTrack *>(trackIter()))){
547  if(fMCEvent && !IsTrueTrack(track)) continue; // Reject fake tracks in case of MC
548  if(!fEtaRange.IsInRange(track->Eta())) continue;
549  if(!fPtRange.IsInRange(track->Pt())) continue;
550  coneradii.clear();
551  if(this->fJetCollArray.GetEntries() &&
552  (jetContData = dynamic_cast<AliJetContainer *>(this->fJetCollArray.FindObject((static_cast<TObjString *>(this->fJetContainersData.At(0)))->String().Data())))){
553  foundJet = FoundTrackInJet(track, jetContData);
554  if(foundJet){
555  for(int irad = 0; irad < kNJetRadii; irad++){
556  if(IsInRadius(track, foundJet, kJetRadii[irad])) coneradii.push_back(kJetRadii[irad]);
557  }
558  }
559  }
560  if(triggers[0]){
561  FillTrackHist("MinBias", track, zv, isPileupEvent, icut + 1, triggers[0]);
562  if(coneradii.size()){
563  for(std::vector<double>::iterator radIter = coneradii.begin(); radIter != coneradii.end(); radIter++)
564  FillTrackHist("MinBias", track, zv, isPileupEvent, icut + 1, triggers[0], *radIter);
565  }
566  }
567  if(!triggerstrings.size()){ // Non-EMCal-triggered
568  FillTrackHist("NoEMCal", track, zv, isPileupEvent, icut + 1, triggers[0]);
569  for(std::vector<double>::iterator radIter = coneradii.begin(); radIter != coneradii.end(); radIter++)
570  FillTrackHist("NoEMCal", track, zv, isPileupEvent, icut + 1, triggers[0], *radIter);
571  } else {
572  // EMCal-triggered events
573  for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
574  FillTrackHist(it->c_str(), track, zv, isPileupEvent, icut + 1, triggers[0]);
575  for(std::vector<double>::iterator radIter = coneradii.begin(); radIter != coneradii.end(); radIter++)
576  FillTrackHist(it->c_str(), track, zv, isPileupEvent, icut + 1, triggers[0], *radIter);
577  }
578  }
579  }
580  }
581  }
582 
583  // Next step we loop over the (uncalibrated) emcal clusters and fill histograms with the cluster energy
584  const AliVCluster *clust(NULL);
585  for(int icl = 0; icl < fInputEvent->GetNumberOfCaloClusters(); icl++){
586  clust = fInputEvent->GetCaloCluster(icl);
587  if(!clust->IsEMCAL()) continue;
588  if(!fEnergyRange.IsInRange(clust->E())) continue;
589  if(triggers[0]) FillClusterHist("hClusterUncalibHistMinBias", clust, zv, isPileupEvent, triggers[0]);
590  if(!triggerstrings.size()){ // Non-EMCal-triggered
591  FillClusterHist("hClusterUncalibHistNoEMCal", clust, zv, isPileupEvent, triggers[0]);
592  } else{
593  for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
594  sprintf(histname, "hClusterUncalibHist%s", it->c_str());
595  FillClusterHist(histname, clust, zv, isPileupEvent, triggers[0]);
596  }
597  }
598  }
599 
600  if(fCaloClusters){
601  TIter clustIter(fCaloClusters);
602  while((clust = dynamic_cast<const AliVCluster *>(clustIter()))){
603  if(!clust->IsEMCAL()) continue;
604  if(!fEnergyRange.IsInRange(clust->E())) continue;
605  if(triggers[0]) FillClusterHist("hClusterCalibHistMinBias", clust, zv, isPileupEvent, triggers[0]);
606  if(!triggerstrings.size()) // Non-EMCal-triggered
607  FillClusterHist("hClusterCalibHistNoEMCal", clust, zv, isPileupEvent, triggers[0]);
608  else{
609  for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
610  sprintf(histname, "hClusterCalibHist%s", it->c_str());
611  FillClusterHist(histname, clust, zv, isPileupEvent, triggers[0]);
612  }
613  }
614  }
615  }
616 
617  PostData(1, fOutput);
618  return true;
619  }
620 
621  //______________________________________________________________________________
622  void AliAnalysisTaskPtEMCalTrigger::CreateDefaultPtBinning(TArrayD &binning) const{
623  /*
624  * Creating the default pt binning.
625  *
626  * @param binning: Array where to store the results.
627  */
628  std::vector<double> mybinning;
629  std::map<double,double> definitions;
630  definitions.insert(std::pair<double,double>(2.5, 0.1));
631  definitions.insert(std::pair<double,double>(7., 0.25));
632  definitions.insert(std::pair<double,double>(15., 0.5));
633  definitions.insert(std::pair<double,double>(25., 1.));
634  definitions.insert(std::pair<double,double>(40., 2.5));
635  definitions.insert(std::pair<double,double>(50., 5.));
636  definitions.insert(std::pair<double,double>(100., 10.));
637  double currentval = 0;
638  for(std::map<double,double>::iterator id = definitions.begin(); id != definitions.end(); ++id){
639  double limit = id->first, binwidth = id->second;
640  while(currentval < limit){
641  currentval += binwidth;
642  mybinning.push_back(currentval);
643  }
644  }
645  binning.Set(mybinning.size());
646  int ib = 0;
647  for(std::vector<double>::iterator it = mybinning.begin(); it != mybinning.end(); ++it)
648  binning[ib++] = *it;
649  }
650 
651  //______________________________________________________________________________
652  void AliAnalysisTaskPtEMCalTrigger::CreateDefaultZVertexBinning(TArrayD &binning) const {
653  /*
654  * Creating default z-Vertex binning.
655  *
656  * @param binning: Array where to store the results.
657  */
658  std::vector<double> mybinning;
659  double currentval = -10;
660  mybinning.push_back(currentval);
661  while(currentval <= 10.){
662  currentval += 5.;
663  mybinning.push_back(currentval);
664  }
665  binning.Set(mybinning.size());
666  int ib = 0;
667  for(std::vector<double>::iterator it = mybinning.begin(); it != mybinning.end(); ++it)
668  binning[ib++] = *it;
669  }
670 
671  //______________________________________________________________________________
672  void AliAnalysisTaskPtEMCalTrigger::CreateDefaultEtaBinning(TArrayD& binning) const {
673  /*
674  * Creating default z-Vertex binning.
675  *
676  * @param binning: Array where to store the results.
677  */
678  std::vector<double> mybinning;
679  double currentval = -0.8;
680  mybinning.push_back(currentval);
681  while(currentval <= 0.8){
682  currentval += 0.1;
683  mybinning.push_back(currentval);
684  }
685  binning.Set(mybinning.size());
686  int ib = 0;
687  for(std::vector<double>::iterator it = mybinning.begin(); it != mybinning.end(); ++it)
688  binning[ib++] = *it;
689  }
690 
691  //______________________________________________________________________________
692  void AliAnalysisTaskPtEMCalTrigger::DefineAxis(TAxis& axis, const char* name,
693  const char* title, const TArrayD& binning, const char** labels) {
694  /*
695  * Define an axis with a given binning
696  *
697  * @param axis: Axis to be defined
698  * @param name: Name of the axis
699  * @param title: Title of the axis
700  * @param binning: axis binning
701  * @param labels (@optional): array of bin labels
702  */
703  axis.Set(binning.GetSize()-1, binning.GetArray());
704  axis.SetName(name);
705  axis.SetTitle(title);
706  if(labels){
707  for(int ib = 1; ib <= axis.GetNbins(); ++ib)
708  axis.SetBinLabel(ib, labels[ib-1]);
709  }
710  }
711 
712  //______________________________________________________________________________
713  void AliAnalysisTaskPtEMCalTrigger::DefineAxis(TAxis& axis, const char* name,
714  const char* title, int nbins, double min, double max,
715  const char** labels) {
716  /*
717  * Define an axis with number of bins from min to max
718  *
719  * @param axis: Axis to be defined
720  * @param name: Name of the axis
721  * @param title: Title of the axis
722  * @param nbins: Number of bins
723  * @param min: lower limit of the axis
724  * @param max: upper limit of the axis
725  * @param labels (@optional): array of bin labels
726  */
727  axis.Set(nbins, min, max);
728  axis.SetName(name);
729  axis.SetTitle(title);
730  if(labels){
731  for(int ib = 1; ib <= axis.GetNbins(); ++ib)
732  axis.SetBinLabel(ib, labels[ib-1]);
733  }
734  }
735 
736 
737  //______________________________________________________________________________
738  void AliAnalysisTaskPtEMCalTrigger::FillEventHist(const char* trigger,
739  double vz, bool isPileup) {
740  /*
741  * Fill event-based histogram
742  *
743  * @param trigger: name of the trigger configuration to be processed
744  * @param vz: z-position of the vertex
745  * @param isPileup: signalises if the event is flagged as pileup event
746  */
747  char histname[1024];
748  sprintf(histname, "hEventHist%s", trigger);
749  try{
750  fHistos->FillTH2(histname, 0., vz);
751  } catch (HistoContainerContentException &e){
752  std::stringstream errormessage;
753  errormessage << "Filling of histogram failed: " << e.what();
754  AliError(errormessage.str().c_str());
755  }
756  if(!isPileup){
757  try{
758  fHistos->FillTH2(histname, 1., vz);
759  } catch(HistoContainerContentException &e){
760  std::stringstream errormessage;
761  errormessage << "Filling of histogram failed: " << e.what();
762  AliError(errormessage.str().c_str());
763  }
764  }
765  }
766 
767  //______________________________________________________________________________
768  void AliAnalysisTaskPtEMCalTrigger::FillTrackHist(const char* trigger,
769  const AliVTrack* track, double vz, bool isPileup, int cut, bool isMinBias, double jetradius) {
770  /*
771  * Fill track-based histogram with corresponding information
772  *
773  * @param trigger: name of the trigger
774  * @param track: ESD track selected
775  * @param vz: z-position of the vertex
776  * @param isPileup: flag event as pileup event
777  * @param cut: id of the cut (0 = no cut)
778  */
779  double etasign = fSwapEta ? -1. : 1.;
780  double data[7] = {TMath::Abs(track->Pt()), etasign * track->Eta(), track->Phi(), vz, 0, static_cast<double>(cut), isMinBias ? 1. : 0.};
781  double dataMC[7] = {0., 0., 0., vz, 0, static_cast<double>(cut), isMinBias ? 1. : 0.};
782  AliVParticle *assocMC(NULL);
783  if(fMCEvent && (assocMC = fMCEvent->GetTrack(TMath::Abs(track->GetLabel())))){
784  // Select track onl
785  dataMC[0] = TMath::Abs(assocMC->Pt());
786  dataMC[1] = etasign * assocMC->Eta();
787  dataMC[2] = assocMC->Phi();
788  }
789  char histname[1024], histnameAcc[1024], histnameMC[1024], histnameMCAcc[1024];
790  sprintf(histname, "hTrackHist%s", trigger);
791  sprintf(histnameAcc, "hTrackInAcceptanceHist%s", trigger);
792  sprintf(histnameMC, "hMCTrackHist%s", trigger);
793  sprintf(histnameMCAcc, "hMCTrackInAcceptanceHist%s", trigger);
794  if(jetradius > 0.){
795  char *hnames[] = {histname, histnameAcc, histnameMC, histnameMCAcc};
796  for(unsigned int iname = 0; iname < sizeof(hnames)/sizeof(char *); iname++){
797  char *myhname = hnames[iname];
798  sprintf(myhname, "%sRad%02d", myhname, int(jetradius * 10.));
799  }
800  }
801  Bool_t isEMCAL = kFALSE;
802  if(track->IsEMCAL()){
803  // Check if the cluster is matched to only one track
804  AliVCluster *emcclust(NULL);
805  AliDebug(2, Form("cluster id: %d\n", track->GetEMCALcluster()));
806  if(fCaloClusters) {
807  AliDebug(2, "Using calibrated clusters");
808  emcclust = dynamic_cast<AliVCluster *>(fCaloClusters->At(track->GetEMCALcluster()));
809  } else {
810  AliDebug(2, "Using uncalibrated clusters");
811  emcclust = fInputEvent->GetCaloCluster(track->GetEMCALcluster());
812  }
813  if(!emcclust) AliError("Null pointer to EMCal cluster");
814  if(emcclust && emcclust->GetNTracksMatched() <= 1){
815  isEMCAL = kTRUE;
816  }
817  }
818  try{
819  fHistos->FillTHnSparse(histname, data);
820  if(fMCEvent) fHistos->FillTHnSparse(histnameMC, dataMC);
821  if(isEMCAL){
822  fHistos->FillTHnSparse(histnameAcc, data);
823  if(fMCEvent) fHistos->FillTHnSparse(histnameMCAcc, dataMC);
824  }
825  } catch (HistoContainerContentException &e){
826  std::stringstream errormessage;
827  errormessage << "Filling of histogram failed: " << e.what();
828  AliError(errormessage.str().c_str());
829  }
830  if(!isPileup){
831  data[4] = 1;
832  dataMC[4] = 1;
833  try{
834  fHistos->FillTHnSparse(histname, data);
835  if(fMCEvent) fHistos->FillTHnSparse(histnameMC, dataMC);
836  if(isEMCAL){
837  fHistos->FillTHnSparse(histnameAcc, data);
838  if(fMCEvent) fHistos->FillTHnSparse(histnameMCAcc, dataMC);
839  }
840  } catch (HistoContainerContentException &e){
841  std::stringstream errormessage;
842  errormessage << "Filling of histogram failed: " << e.what();
843  AliError(errormessage.str().c_str());
844  }
845  }
846  }
847 
848  //______________________________________________________________________________
849  void AliAnalysisTaskPtEMCalTrigger::FillClusterHist(const char* histname,
850  const AliVCluster* clust, double vz, bool isPileup, bool isMinBias) {
851  /*
852  * Fill cluster-based histogram with corresponding information
853  *
854  * @param trigger: name of the trigger
855  * @param cluster: the EMCal cluster information
856  * @param vz: z-position of the vertex
857  * @param isPileup: flag event as pileup event
858  */
859  double data[4] = {clust->E(), vz, 0, isMinBias ? 1. : 0.};
860  try{
861  fHistos->FillTHnSparse(histname, data);
862  } catch (HistoContainerContentException &e){
863  std::stringstream errormessage;
864  errormessage << "Filling of histogram failed: " << e.what();
865  AliError(errormessage.str().c_str());
866  }
867  if(!isPileup){
868  data[2] = 1.;
869  try{
870  fHistos->FillTHnSparse(histname, data);
871  } catch (HistoContainerContentException &e){
872  std::stringstream errormessage;
873  errormessage << "Filling of histogram failed: " << e.what();
874  AliError(errormessage.str().c_str());
875  }
876  }
877  }
878 
879  //______________________________________________________________________________
880  void AliAnalysisTaskPtEMCalTrigger::FillMCParticleHist(const char *histname, const AliVParticle * const track, double vz, bool isPileup){
881  /*
882  * Fill histogram for MC-true particles with the information pt, eta and phi
883  *
884  * @param track: the Monte-Carlo track
885  */
886  double data[5] = {TMath::Abs(track->Pt()), track->Eta(), track->Phi(), vz, 0.};
887  fHistos->FillTHnSparse(histname, data);
888  if(!isPileup){
889  data[4] = 1.;
890  fHistos->FillTHnSparse(histname, data);
891  }
892  }
893 
894  //______________________________________________________________________________
895  bool AliAnalysisTaskPtEMCalTrigger::IsTrueTrack(const AliVTrack *const track) const{
896  /*
897  * Check if the track has an associated MC particle, and that the particle is a physical primary
898  * In case of data we do not do the selection at that step (always return true)
899  *
900  * @param track: Track to check
901  * @result: true primary track (true or false)
902  */
903  if(!fMCEvent) return true;
904  AliVParticle *mcassociate = fMCEvent->GetTrack(TMath::Abs(track->GetLabel()));
905  if(!mcassociate) return false;
906  return fMCEvent->IsPhysicalPrimary(TMath::Abs(track->GetLabel()));
907  }
908 
909  //______________________________________________________________________________
910  void AliAnalysisTaskPtEMCalTrigger::AddESDTrackCuts(AliESDtrackCuts* trackCuts) {
911  /*
912  * Add new track cuts to the task
913  *
914  * @param trackCuts: Object of type AliESDtrackCuts
915  */
916  fListTrackCuts->AddLast(new AliEMCalPtTaskTrackSelectionESD(trackCuts));
917  }
918 
919  //______________________________________________________________________________
920  void AliAnalysisTaskPtEMCalTrigger::AddCutsForAOD(AliESDtrackCuts* trackCuts, UInt_t filterbits) {
921  /*
922  * Add new track cuts to the task
923  *
924  * @param trackCuts: Object of type AliESDtrackCuts
925  */
926  fListTrackCuts->AddLast(new AliEMCalPtTaskTrackSelectionAOD(trackCuts, filterbits));
927  }
928 
929 
930  //______________________________________________________________________________
931  TString AliAnalysisTaskPtEMCalTrigger::BuildTriggerString() {
932  /*
933  * Build trigger string from the trigger maker
934  *
935  * @return: blank-separated string of fired trigger classes
936  */
937  AliDebug(1, "trigger checking");
938  TString result = "";
939  if(HasTriggerType(kJ1)) result += "EJ1 ";
940  if(HasTriggerType(kJ2)) result += "EJ2 ";
941  if(HasTriggerType(kG1)) result += "EG1 ";
942  if(HasTriggerType(kG2)) result += "EG2 ";
943  return result;
944  }
945 
946  //______________________________________________________________________________
947  const AliVVertex* AliAnalysisTaskPtEMCalTrigger::GetSPDVertex() const {
948  /*
949  * Accessor for the SPD vertex, creating transparency for ESDs and AODs
950  *
951  * @return: the spd vertex
952  */
953  AliESDEvent *esd = dynamic_cast<AliESDEvent *>(fInputEvent);
954  if(esd){
955  return esd->GetPrimaryVertexSPD();
956  } else {
957  AliAODEvent *aod = dynamic_cast<AliAODEvent *>(fInputEvent);
958  if(aod){
959  return aod->GetPrimaryVertexSPD();
960  }
961  }
962  return NULL;
963  }
964 
965  //______________________________________________________________________________
966  const AliEmcalJet * AliAnalysisTaskPtEMCalTrigger::FoundTrackInJet(
967  const AliVParticle * const track, AliJetContainer *const jets) const
968  {
969  /*
970  * Correlate track to reconstructed jet
971  *
972  * @param track: particle to be checked
973  * @param jets: container of recontructed jets
974  * @return: The matched jet (NULL if not found)
975  */
976  const AliEmcalJet *result = NULL;
977  const AliEmcalJet *tmp = jets->GetNextAcceptJet(0);
978  while(tmp){
979  if(TrackInJet(track, tmp, jets->GetParticleContainer())){
980  result = tmp;
981  break;
982  }
983  tmp = jets->GetNextAcceptJet();
984  }
985  return result;
986  }
987 
988  //______________________________________________________________________________
989  bool AliAnalysisTaskPtEMCalTrigger::IsInRadius(const AliVParticle *const track, const AliEmcalJet *reconstructedJet, Double_t radius) const {
990  /*
991  * Check if track is in radius around a given jet
992  *
993  * @param track: Track to check
994  * @param reconstructed jet: jet to probe
995  * @param radius: cone radius
996  * @return: result of the test (true if track is inside the cone radius, false otherwise)
997  */
998  return reconstructedJet->DeltaR(track) < radius;
999  }
1000 
1001  //______________________________________________________________________________
1002  bool AliAnalysisTaskPtEMCalTrigger::IsInRadius(const AliVCluster *const clust, const AliEmcalJet *reconstructedJet, Double_t radius) const {
1003  /*
1004  * Check if track is in radius around a given jet
1005  *
1006  * @param track: Track to check
1007  * @param reconstructed jet: jet to probe
1008  * @param radius: cone radius
1009  * @return: result of the test (true if track is inside the cone radius, false otherwise)
1010  */
1011  double vertexPos[3];
1012  fInputEvent->GetPrimaryVertex()->GetXYZ(vertexPos);
1013  TLorentzVector clustVect;
1014  clust->GetMomentum(clustVect, vertexPos);
1015 
1016  Double_t dPhi = reconstructedJet->Phi() - clustVect.Phi();
1017  Double_t dEta = reconstructedJet->Eta() - clustVect.Eta();
1018  dPhi = TVector2::Phi_mpi_pi ( dPhi );
1019 
1020  double deltaR = TMath::Sqrt ( dPhi * dPhi + dEta * dEta );
1021  return deltaR < radius;
1022  }
1023 
1024  //______________________________________________________________________________
1025  bool AliAnalysisTaskPtEMCalTrigger::TrackInJet(const AliVParticle* const track,
1026  const AliEmcalJet* reconstructedJet, const AliParticleContainer * const particles) const {
1027  /*
1028  * Check whether track is among the jet constituents
1029  *
1030  * @param track: track to check
1031  * @param reconstructedJet: reconstructed jet to check
1032  * @param tracks: container with tracks used for jetfinding
1033  * @return: true if found, false otherwise
1034  */
1035  bool found = false;
1036  const AliPicoTrack *picotmp(NULL);
1037  const AliVParticle *tmp(NULL);
1038  for(int ipart = 0; ipart < reconstructedJet->GetNumberOfTracks(); ipart++){
1039  tmp = dynamic_cast<const AliVParticle *>(reconstructedJet->TrackAt(ipart, particles->GetArray()));
1040  if((picotmp = dynamic_cast<const AliPicoTrack *>(tmp))) // handle pico tracks
1041  tmp = picotmp->GetTrack();
1042  if(!tmp->Compare(track)){
1043  found = true;
1044  break;
1045  }
1046  }
1047  return found;
1048  }
1049 
1050  //______________________________________________________________________________
1051  const AliEmcalJet* AliAnalysisTaskPtEMCalTrigger::FoundClusterInJet(const AliVCluster* const clust, AliJetContainer* const jets) const {
1052  /*
1053  * Check whether a cluster is in a radius around a given jet
1054  *
1055  * @param clust: The cluster to check
1056  * @param reconstructedJet: reconstructed jet to check
1057  * @return: the jet containing the cluster (null otherwise)
1058  */
1059  const AliEmcalJet *result = NULL;
1060  const AliEmcalJet *tmp = jets->GetNextAcceptJet(0);
1061  while(tmp){
1062  if(ClusterInJet(clust, tmp, jets->GetClusterContainer())){
1063  result = tmp;
1064  break;
1065  }
1066  tmp =jets->GetNextAcceptJet();
1067  }
1068  return result;
1069  }
1070 
1071  //______________________________________________________________________________
1072  bool AliAnalysisTaskPtEMCalTrigger::ClusterInJet(const AliVCluster* const clust,
1073  const AliEmcalJet* reconstructedJet, const AliClusterContainer* const clusters) const {
1074  /*
1075  * Check whether cluster is among the jet constituents
1076  *
1077  * @param track: track to check
1078  * @param reconstructedJet: reconstructed jet to check
1079  * @param clusters: the cluster container
1080  * @return: true if found, false otherwise
1081  */
1082  bool found = false;
1083  const AliVCluster *tmp(NULL);
1084  for(int ipart = 0; ipart < reconstructedJet->GetNumberOfTracks(); ipart++){
1085  tmp = dynamic_cast<const AliVCluster *>(reconstructedJet->ClusterAt(ipart, clusters->GetArray()));
1086  if(!tmp->Compare(clust)){
1087  found = true;
1088  break;
1089  }
1090  }
1091  return found;
1092  }
1093 
1094  //______________________________________________________________________________
1095  void EMCalTriggerPtAnalysis::AliAnalysisTaskPtEMCalTrigger::AddJetContainerName(const Char_t* contname, Bool_t isMC) {
1096  /*
1097  * Add new Jet input container to the analysis task
1098  *
1099  * @param contname: Name of the container
1100  * @param isMC: Defines whether the container is for MC truth or not
1101  */
1102  TList &mycontainer = isMC ? fJetContainersMC : fJetContainersData;
1103  mycontainer.Add(new TObjString(contname));
1104  }
1105 }
Implement virtual track selection for AOD analysis.
void AddJetContainerName(const Char_t *contname, Bool_t isMC=kFALSE)
Declarartion of class AliEMCalHistoContainer.
Declaration of class AliEMCalPtTaskTrackSelectionESD.
Declartion of class AliEMCalPtTaskVTrackSelection.
ClassImp(EMCalTriggerPtAnalysis::AliAnalysisTaskPtEMCalTrigger) namespace EMCalTriggerPtAnalysis