1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 * Analysis task of the pt analysis on EMCal-triggered events
19 * Author: Markus Fasel
30 #include <TClonesArray.h>
31 #include <TDirectory.h>
33 #include <THashList.h>
37 #include <TObjArray.h>
40 #include "AliESDCaloCluster.h"
41 #include "AliESDEvent.h"
42 #include "AliESDInputHandler.h"
43 #include "AliESDtrack.h"
44 #include "AliESDVertex.h"
46 #include "AliEMCalHistoContainer.h"
47 #include "AliAnalysisTaskPtEMCalTrigger.h"
49 ClassImp(EMCalTriggerPtAnalysis::AliAnalysisTaskPtEMCalTrigger)
51 namespace EMCalTriggerPtAnalysis {
53 //______________________________________________________________________________
54 AliAnalysisTaskPtEMCalTrigger::AliAnalysisTaskPtEMCalTrigger():
63 * Dummy constructor, initialising the values with default (NULL) values
67 //______________________________________________________________________________
68 AliAnalysisTaskPtEMCalTrigger::AliAnalysisTaskPtEMCalTrigger(const char *name):
69 AliAnalysisTaskSE(name),
77 * Main constructor, setting default values for eta and zvertex cut
79 DefineOutput(1, TList::Class());
81 fListTrackCuts = new TList;
82 fListTrackCuts->SetOwner(false);
85 fEtaRange.SetLimits(-0.8, 0.8);
86 fPtRange.SetLimits(0.15, 100.);
90 //______________________________________________________________________________
91 AliAnalysisTaskPtEMCalTrigger::~AliAnalysisTaskPtEMCalTrigger(){
93 * Destructor, deleting output
95 //if(fTrackSelection) delete fTrackSelection;
96 if(fHistos) delete fHistos;
97 if(fListTrackCuts) delete fListTrackCuts;
100 //______________________________________________________________________________
101 void AliAnalysisTaskPtEMCalTrigger::UserCreateOutputObjects(){
103 * Create the list of output objects and define the histograms.
104 * Also adding the track cuts to the list of histograms.
106 fResults = new TList;
107 fResults->SetOwner();
109 fHistos = new AliEMCalHistoContainer("PtEMCalTriggerHistograms");
110 fHistos->ReleaseOwner();
112 std::map<std::string, std::string> triggerCombinations;
113 const char *triggernames[12] = {"MinBias", "EMCJHigh", "EMCJLow", "EMCGHigh", "EMCGLow", "NoEMCal", "EMCHighBoth", "EMCHighGammaOnly", "EMCHighJetOnly", "EMCLowBoth", "EMCLowGammaOnly", "EMCLowJetOnly"},
114 *bitnames[4] = {"CINT7", "EMC7", "kEMCEGA", "kEMCEJE"};
115 // Define axes for the trigger correlation histogram
116 const TAxis *triggeraxis[5]; memset(triggeraxis, 0, sizeof(const TAxis *) * 5);
117 const TAxis *bitaxes[4]; memset(bitaxes, 0, sizeof(TAxis *) * 4);
118 const char *binlabels[2] = {"OFF", "ON"};
119 TAxis mytrgaxis[5], mybitaxis[4];
120 for(int itrg = 0; itrg < 5; ++itrg){
121 DefineAxis(mytrgaxis[itrg], triggernames[itrg], triggernames[itrg], 2, -0.5, 1.5, binlabels);
122 triggeraxis[itrg] = mytrgaxis+itrg;
124 DefineAxis(mybitaxis[itrg], bitnames[itrg], bitnames[itrg], 2, -0.5, 1.5, binlabels);
125 bitaxes[itrg] = mybitaxis+itrg;
128 // Define names and titles for different triggers in the histogram container
129 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[0], "min. bias events"));
130 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[1], "jet-triggered events (high threshold)"));
131 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[2], "jet-triggered events (low threshold)"));
132 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[3], "gamma-triggered events (high threshold)"));
133 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[4], "gamma-triggered events (low threshold)"));
134 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[5], "non-EMCal-triggered events"));
135 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[6], "jet and gamma triggered events (high threshold)"));
136 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[7], "exclusively gamma-triggered events (high threshold)"));
137 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[8], "exclusively jet-triggered events (high threshold)"));
138 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[9], "jet and gamma triggered events (low threshold)"));
139 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[10], "exclusively gamma-triggered events (low threshold)"));
140 triggerCombinations.insert(std::pair<std::string,std::string>(triggernames[11], "exclusively-triggered events (low threshold)"));
141 // Define axes for the pt histogram
147 // 5. pileup (0 = all events, 1 = after pileup rejection)
148 // 6. track cuts (0 = no cuts; 1 = after std cuts)
149 TArrayD ptbinning, zvertexBinning, etabinning, pileupaxis(3);
150 pileupaxis[0] = -0.5; pileupaxis[1] = 0.5; pileupaxis[2] = 1.5;
151 CreateDefaultPtBinning(ptbinning);
152 CreateDefaultZVertexBinning(zvertexBinning);
153 CreateDefaultEtaBinning(etabinning);
155 DefineAxis(htrackaxes[0], "pt", "p_{t} (GeV/c)", ptbinning);
156 DefineAxis(htrackaxes[1], "eta", "#eta", etabinning);
157 DefineAxis(htrackaxes[2], "phi", "#phi", 20, 0, 2 * TMath::Pi());
158 DefineAxis(htrackaxes[3], "zvertex", "z_{V} (cm)", zvertexBinning);
159 DefineAxis(htrackaxes[4], "pileup", "Pileup rejection", 2, -0.5, 1.5);
160 DefineAxis(htrackaxes[5], "trackcuts", "Track Cuts", (fListTrackCuts ? fListTrackCuts->GetEntries() : 0) + 1, -0.5, (fListTrackCuts ? fListTrackCuts->GetEntries() : 0) + 0.5);
161 const TAxis *trackaxes[6];
162 for(int iaxis = 0; iaxis < 6; ++iaxis) trackaxes[iaxis] = htrackaxes + iaxis;
163 TAxis hclusteraxes[3];
164 DefineAxis(hclusteraxes[0], "energy", "E (GeV)", ptbinning);
165 DefineAxis(hclusteraxes[1], "zvertex", "z_{V} (cm)", zvertexBinning);
166 DefineAxis(hclusteraxes[2], "pileup", "Pileup rejection", 2, -0.5, 1.5);
167 const TAxis *clusteraxes[3];
168 for(int iaxis = 0; iaxis < 3; ++iaxis) clusteraxes[iaxis] = hclusteraxes + iaxis;
170 for(std::map<std::string,std::string>::iterator it = triggerCombinations.begin(); it != triggerCombinations.end(); ++it){
171 const std::string name = it->first, &title = it->second;
172 // Create event-based histogram
173 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);
174 // Create track-based histogram
175 fHistos->CreateTHnSparse(Form("hTrackHist%s", name.c_str()), Form("Track-based data for %s events", title.c_str()), 6, trackaxes);
176 // Create cluster-based histogram (Uncalibrated and calibrated clusters)
177 fHistos->CreateTHnSparse(Form("hClusterCalibHist%s", name.c_str()), Form("Calib. cluster-based histogram for %s events", title.c_str()), 3, clusteraxes);
178 fHistos->CreateTHnSparse(Form("hClusterUncalibHist%s", name.c_str()), Form("Uncalib. cluster-based histogram for %s events", title.c_str()), 3, clusteraxes);
180 fHistos->CreateTHnSparse("hEventTriggers", "Trigger type per event", 5, triggeraxis);
181 fHistos->CreateTHnSparse("hEventsTriggerbit", "Trigger bits for the different events", 4, bitaxes);
182 } catch (HistoContainerContentException &e){
183 std::stringstream errormessage;
184 errormessage << "Creation of histogram failed: " << e.what();
185 AliError(errormessage.str().c_str());
187 fResults->Add(fHistos->GetListOfHistograms());
188 if(fListTrackCuts && fListTrackCuts->GetEntries()){
189 TIter cutIter(fListTrackCuts);
190 AliESDtrackCuts *cutObject(NULL);
191 while((cutObject = dynamic_cast<AliESDtrackCuts *>(cutIter()))){
192 cutObject->DefineHistograms();
193 fResults->Add(cutObject);
196 PostData(1, fResults);
199 //______________________________________________________________________________
200 void AliAnalysisTaskPtEMCalTrigger::UserExec(Option_t* /*option*/){
202 * Runs the event loop
204 * @param option: Additional options
206 // Common checks: Have SPD vertex and primary vertex from tracks, and both need to have at least one contributor
207 AliESDEvent *esd = static_cast<AliESDEvent *>(fInputEvent);
208 const AliESDVertex *vtxTracks = esd->GetPrimaryVertex(),
209 *vtxSPD = esd->GetPrimaryVertexSPD();
210 if(!(vtxTracks && vtxSPD)) return;
211 if(vtxTracks->GetNContributors() < 1 || vtxSPD->GetNContributors() < 1) return;
213 double triggers[5]; memset(triggers, 0, sizeof(double) * 5);
214 double triggerbits[4]; memset(triggerbits, 0, sizeof(double) * 4);
215 if(fInputHandler->IsEventSelected() & AliVEvent::kINT7){
221 if(fInputHandler->IsEventSelected() & AliVEvent::kEMC7){
224 if(fInputHandler->IsEventSelected() & AliVEvent::kEMCEGA){
227 if(fInputHandler->IsEventSelected() & AliVEvent::kEMCEJE){
231 fHistos->FillTHnSparse("hEventsTriggerbit", triggerbits);
232 } catch(HistoContainerContentException &e) {
233 std::stringstream errormessage;
234 errormessage << "Filling of histogram failed: " << e.what();
235 AliError(errormessage.str().c_str());
238 std::vector<std::string> triggerstrings;
239 // EMCal-triggered event, distinguish types
240 TString trgstr(fInputEvent->GetFiredTriggerClasses());
241 if(trgstr.Contains("EJ1")){
242 triggerstrings.push_back("EMCJHigh");
244 if(trgstr.Contains("EG1"))
245 triggerstrings.push_back("EMCHighBoth");
247 triggerstrings.push_back("EMCHighJetOnly");
249 if(trgstr.Contains("EJ2")){
250 triggerstrings.push_back("EMCJLow");
252 if(trgstr.Contains("EG2"))
253 triggerstrings.push_back("EMCLowBoth");
255 triggerstrings.push_back("EMCLowJetOnly");
257 if(trgstr.Contains("EG1")){
258 triggerstrings.push_back("EMCGHigh");
260 if(!trgstr.Contains("EJ1"))
261 triggerstrings.push_back("EMCHighGammaOnly");
263 if(trgstr.Contains("EG2")){
264 triggerstrings.push_back("EMCGLow");
266 if(!trgstr.Contains("EJ2"))
267 triggerstrings.push_back("EMCLowGammaOnly");
271 fHistos->FillTHnSparse("hEventTriggers", triggers);
272 } catch (HistoContainerContentException &e){
273 std::stringstream errormessage;
274 errormessage << "Filling of histogram failed: " << e.what();
275 AliError(errormessage.str().c_str());
278 // apply event selection: Combine the Pileup cut from SPD with the other pA Vertex selection cuts.
279 bool isPileupEvent = esd->IsPileupFromSPD();
280 isPileupEvent = isPileupEvent || (TMath::Abs(vtxTracks->GetZ() - vtxSPD->GetZ()) > 0.5);
281 double covSPD[6]; vtxSPD->GetCovarianceMatrix(covSPD);
282 isPileupEvent = isPileupEvent || (TString(vtxSPD->GetTitle()).Contains("vertexer:Z") && TMath::Sqrt(covSPD[5]) > 0.25);
284 // Fill event-based histogram
285 const double &zv = vtxTracks->GetZ();
286 if(triggers[0]) FillEventHist("MinBias", zv, isPileupEvent);
287 if(!triggerstrings.size()) // Non-EMCal-triggered
288 FillEventHist("NoEMCal", zv, isPileupEvent);
290 // EMCal-triggered events
291 for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
292 FillEventHist(it->c_str(), zv, isPileupEvent);
295 AliESDtrack *track(NULL);
296 // Loop over all tracks (No cuts applied)
297 for(int itrk = 0; itrk < fInputEvent->GetNumberOfTracks(); ++itrk){
298 track = dynamic_cast<AliESDtrack *>(fInputEvent->GetTrack(itrk));
299 if(!fEtaRange.IsInRange(track->Eta())) continue;
300 if(!fPtRange.IsInRange(track->Pt())) continue;
301 if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, 0);
302 if(!triggerstrings.size()) // Non-EMCal-triggered
303 FillTrackHist("NoEMCal", track, zv, isPileupEvent, 0);
305 // EMCal-triggered events
306 for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
307 FillTrackHist(it->c_str(), track, zv, isPileupEvent, 0);
311 // Now apply track selection cuts
312 // allow for several track selections to be tested at the same time
313 // each track selection gets a different cut ID starting from 1
314 // cut ID 0 is reserved for the case of no cuts
315 if(fListTrackCuts && fListTrackCuts->GetEntries()){
316 for(int icut = 0; icut < fListTrackCuts->GetEntries(); icut++){
317 AliESDtrackCuts *trackSelection = static_cast<AliESDtrackCuts *>(fListTrackCuts->At(icut));
318 std::auto_ptr<TObjArray> acceptedTracks(trackSelection->GetAcceptedTracks(esd));
319 TIter trackIter(acceptedTracks.get());
320 while((track = dynamic_cast<AliESDtrack *>(trackIter()))){
321 if(!fEtaRange.IsInRange(track->Eta())) continue;
322 if(!fPtRange.IsInRange(track->Pt())) continue;
323 if(triggers[0]) FillTrackHist("MinBias", track, zv, isPileupEvent, icut + 1);
324 if(!triggerstrings.size()) // Non-EMCal-triggered
325 FillTrackHist("NoEMCal", track, zv, isPileupEvent, icut + 1);
327 // EMCal-triggered events
328 for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it)
329 FillTrackHist(it->c_str(), track, zv, isPileupEvent, icut + 1);
335 // Next step we loop over the (uncalibrated) emcal clusters and fill histograms with the cluster energy
336 for(int icl = 0; icl < fInputEvent->GetNumberOfCaloClusters(); icl++){
337 const AliVCluster *clust = fInputEvent->GetCaloCluster(icl);
338 if(!clust->IsEMCAL()) continue;
339 if(triggers[0]) FillClusterHist("MinBias", clust, false, zv, isPileupEvent);
340 if(!triggerstrings.size()) // Non-EMCal-triggered
341 FillClusterHist("NoEMCal", clust, false, zv, isPileupEvent);
343 for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
344 FillClusterHist(it->c_str(), clust, false, zv, isPileupEvent);
349 TClonesArray *calibratedClusters = dynamic_cast<TClonesArray *>(fInputEvent->FindListObject("EmcCaloClusters"));
350 if(calibratedClusters){
351 for(int icl = 0; icl < calibratedClusters->GetEntries(); icl++){
352 const AliVCluster *clust = dynamic_cast<const AliVCluster *>((*calibratedClusters)[icl]);
353 if(!clust->IsEMCAL()) continue;
354 if(triggers[0]) FillClusterHist("MinBias", clust, true, zv, isPileupEvent);
355 if(!triggerstrings.size()) // Non-EMCal-triggered
356 FillClusterHist("NoEMCal", clust, true, zv, isPileupEvent);
358 for(std::vector<std::string>::iterator it = triggerstrings.begin(); it != triggerstrings.end(); ++it){
359 FillClusterHist(it->c_str(), clust, true, zv, isPileupEvent);
365 PostData(1, fResults);
368 //______________________________________________________________________________
369 void AliAnalysisTaskPtEMCalTrigger::CreateDefaultPtBinning(TArrayD &binning) const{
371 * Creating the default pt binning.
373 * @param binning: Array where to store the results.
375 std::vector<double> mybinning;
376 std::map<double,double> definitions;
377 definitions.insert(std::pair<double,double>(2.5, 0.1));
378 definitions.insert(std::pair<double,double>(7., 0.25));
379 definitions.insert(std::pair<double,double>(15., 0.5));
380 definitions.insert(std::pair<double,double>(25., 1.));
381 definitions.insert(std::pair<double,double>(40., 2.5));
382 definitions.insert(std::pair<double,double>(60., 5.));
383 definitions.insert(std::pair<double,double>(100., 5.));
384 double currentval = 0;
385 for(std::map<double,double>::iterator id = definitions.begin(); id != definitions.end(); ++id){
386 double limit = id->first, binwidth = id->second;
387 while(currentval <= limit){
388 currentval += binwidth;
389 mybinning.push_back(currentval);
392 binning.Set(mybinning.size());
394 for(std::vector<double>::iterator it = mybinning.begin(); it != mybinning.end(); ++it)
398 //______________________________________________________________________________
399 void AliAnalysisTaskPtEMCalTrigger::CreateDefaultZVertexBinning(TArrayD &binning) const {
401 * Creating default z-Vertex binning.
403 * @param binning: Array where to store the results.
405 std::vector<double> mybinning;
406 double currentval = -40;
407 mybinning.push_back(currentval);
408 while(currentval <= 40.){
410 mybinning.push_back(currentval);
412 binning.Set(mybinning.size());
414 for(std::vector<double>::iterator it = mybinning.begin(); it != mybinning.end(); ++it)
418 //______________________________________________________________________________
419 void AliAnalysisTaskPtEMCalTrigger::CreateDefaultEtaBinning(TArrayD& binning) const {
421 * Creating default z-Vertex binning.
423 * @param binning: Array where to store the results.
425 std::vector<double> mybinning;
426 double currentval = -0.8;
427 mybinning.push_back(currentval);
428 while(currentval <= 0.8){
430 mybinning.push_back(currentval);
432 binning.Set(mybinning.size());
434 for(std::vector<double>::iterator it = mybinning.begin(); it != mybinning.end(); ++it)
438 //______________________________________________________________________________
439 void AliAnalysisTaskPtEMCalTrigger::DefineAxis(TAxis& axis, const char* name,
440 const char* title, const TArrayD& binning, const char** labels) {
442 * Define an axis with a given binning
444 * @param axis: Axis to be defined
445 * @param name: Name of the axis
446 * @param title: Title of the axis
447 * @param binning: axis binning
448 * @param labels (@optional): array of bin labels
450 axis.Set(binning.GetSize()-1, binning.GetArray());
452 axis.SetTitle(title);
454 for(int ib = 1; ib <= axis.GetNbins(); ++ib)
455 axis.SetBinLabel(ib, labels[ib-1]);
459 //______________________________________________________________________________
460 void AliAnalysisTaskPtEMCalTrigger::DefineAxis(TAxis& axis, const char* name,
461 const char* title, int nbins, double min, double max,
462 const char** labels) {
464 * Define an axis with number of bins from min to max
466 * @param axis: Axis to be defined
467 * @param name: Name of the axis
468 * @param title: Title of the axis
469 * @param nbins: Number of bins
470 * @param min: lower limit of the axis
471 * @param max: upper limit of the axis
472 * @param labels (@optional): array of bin labels
474 axis.Set(nbins, min, max);
476 axis.SetTitle(title);
478 for(int ib = 1; ib <= axis.GetNbins(); ++ib)
479 axis.SetBinLabel(ib, labels[ib-1]);
483 //______________________________________________________________________________
484 void AliAnalysisTaskPtEMCalTrigger::FillEventHist(const char* trigger,
485 double vz, bool isPileup) {
487 * Fill event-based histogram
489 * @param trigger: name of the trigger configuration to be processed
490 * @param vz: z-position of the vertex
491 * @param isPileup: signalises if the event is flagged as pileup event
494 sprintf(histname, "hEventHist%s", trigger);
496 fHistos->FillTH2(histname, 0., vz);
497 } catch (HistoContainerContentException &e){
498 std::stringstream errormessage;
499 errormessage << "Filling of histogram failed: " << e.what();
500 AliError(errormessage.str().c_str());
504 fHistos->FillTH2(histname, 1., vz);
505 } catch(HistoContainerContentException &e){
506 std::stringstream errormessage;
507 errormessage << "Filling of histogram failed: " << e.what();
508 AliError(errormessage.str().c_str());
513 //______________________________________________________________________________
514 void AliAnalysisTaskPtEMCalTrigger::FillTrackHist(const char* trigger,
515 const AliESDtrack* track, double vz, bool isPileup, int cut) {
517 * Fill track-based histogram with corresponding information
519 * @param trigger: name of the trigger
520 * @param track: ESD track selected
521 * @param vz: z-position of the vertex
522 * @param isPileup: flag event as pileup event
523 * @param cut: id of the cut (0 = no cut)
525 double data[6] = {track->Pt(), track->Eta(), track->Phi(), vz, 0, static_cast<double>(cut)};
527 sprintf(histname, "hTrackHist%s", trigger);
529 fHistos->FillTHnSparse(histname, data);
530 } catch (HistoContainerContentException &e){
531 std::stringstream errormessage;
532 errormessage << "Filling of histogram failed: " << e.what();
533 AliError(errormessage.str().c_str());
538 fHistos->FillTHnSparse(histname, data);
539 } catch (HistoContainerContentException &e){
540 std::stringstream errormessage;
541 errormessage << "Filling of histogram failed: " << e.what();
542 AliError(errormessage.str().c_str());
547 //______________________________________________________________________________
548 void AliAnalysisTaskPtEMCalTrigger::FillClusterHist(const char* trigger,
549 const AliVCluster* clust, bool isCalibrated, double vz, bool isPileup) {
551 * Fill cluster-based histogram with corresponding information
553 * @param trigger: name of the trigger
554 * @param cluster: the EMCal cluster information
555 * @param vz: z-position of the vertex
556 * @param isPileup: flag event as pileup event
558 double data[3] = {clust->E(), vz, 0};
560 sprintf(histname, "hCluster%sHist%s", isCalibrated ? "Calib" : "Uncalib", trigger);
562 fHistos->FillTHnSparse(histname, data);
563 } catch (HistoContainerContentException &e){
564 std::stringstream errormessage;
565 errormessage << "Filling of histogram failed: " << e.what();
566 AliError(errormessage.str().c_str());
571 fHistos->FillTHnSparse(histname, data);
572 } catch (HistoContainerContentException &e){
573 std::stringstream errormessage;
574 errormessage << "Filling of histogram failed: " << e.what();
575 AliError(errormessage.str().c_str());