3 #include "AlidNdEtaCorrectionSelector.h"
9 #include <TParticlePDG.h>
13 #include <TSelector.h>
17 #include <AliTracker.h>
18 #include <AliESDVertex.h>
20 #include <AliESDtrack.h>
21 #include <AliRunLoader.h>
24 #include <AliHeader.h>
25 #include <AliGenEventHeader.h>
26 #include <../PYTHIA6/AliGenPythiaEventHeader.h>
27 #include <../EVGEN/AliGenCocktailEventHeader.h>
29 #include "esdTrackCuts/AliESDtrackCuts.h"
30 #include "dNdEta/AlidNdEtaCorrection.h"
31 #include "AliPWG0Helper.h"
32 #include "AliPWG0depHelper.h"
34 #include "dNdEta/dNdEtaAnalysis.h"
36 ClassImp(AlidNdEtaCorrectionSelector)
38 AlidNdEtaCorrectionSelector::AlidNdEtaCorrectionSelector() :
43 fdNdEtaAnalysisESD(0),
53 // Constructor. Initialization of pointers
57 AlidNdEtaCorrectionSelector::~AlidNdEtaCorrectionSelector()
63 // histograms are in the output list and deleted when the output
64 // list is deleted by the TSelector dtor
67 Bool_t AlidNdEtaCorrectionSelector::SignOK(TParticlePDG* particle)
69 // returns if a particle with this sign should be counted
70 // this is determined by the value of fSignMode, which should have the same sign
72 // if fSignMode is 0 all particles are counted
79 printf("WARNING: not counting a particle that does not have a pdg particle\n");
83 Double_t charge = particle->Charge();
96 void AlidNdEtaCorrectionSelector::ReadUserObjects(TTree* tree)
98 // read the user objects, called from slavebegin and begin
100 if (!fEsdTrackCuts && fInput)
101 fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (fInput->FindObject("AliESDtrackCuts"));
103 if (!fEsdTrackCuts && tree)
104 fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (tree->GetUserInfo()->FindObject("AliESDtrackCuts"));
107 AliDebug(AliLog::kError, "ERROR: Could not read EsdTrackCuts from input list.");
110 void AlidNdEtaCorrectionSelector::Begin(TTree * tree)
112 // The Begin() function is called at the start of the query.
113 // When running with PROOF Begin() is only called on the client.
114 // The tree argument is deprecated (on PROOF 0 is passed).
116 AliSelectorRL::Begin(tree);
118 ReadUserObjects(tree);
120 TString option = GetOption();
121 AliInfo(Form("Called with option %s.", option.Data()));
123 if (option.Contains("only-positive"))
125 AliInfo("Processing only positive particles.");
128 else if (option.Contains("only-negative"))
130 AliInfo("Processing only negative particles.");
135 void AlidNdEtaCorrectionSelector::SlaveBegin(TTree * tree)
137 // The SlaveBegin() function is called after the Begin() function.
138 // When running with PROOF SlaveBegin() is called on each slave server.
139 // The tree argument is deprecated (on PROOF 0 is passed).
141 AliSelectorRL::SlaveBegin(tree);
143 ReadUserObjects(tree);
145 fdNdEtaCorrection = new AlidNdEtaCorrection("dndeta_correction", "dndeta_correction");
147 fPIDParticles = new TH1F("pid_particles", "PID of generated primary particles", 10001, -5000.5, 5000.5);
148 fPIDTracks = new TH1F("pid_tracks", "MC PID of reconstructed tracks", 10001, -5000.5, 5000.5);
150 fClustersITSPos = new TH1F("clusters_its_pos", "clusters_its_pos", 7, -0.5, 6.5);
151 fClustersTPCPos = new TH1F("clusters_tpc_pos", "clusters_tpc_pos", 160, -0.5, 159.5);
153 fClustersITSNeg = new TH1F("clusters_its_neg", "clusters_its_neg", 7, -0.5, 6.5);
154 fClustersTPCNeg = new TH1F("clusters_tpc_neg", "clusters_tpc_neg", 160, -0.5, 159.5);
156 fdNdEtaAnalysisMC = new dNdEtaAnalysis("dndetaMC", "dndetaMC");
157 fdNdEtaAnalysisESD = new dNdEtaAnalysis("dndetaESD", "dndetaESD");
160 void AlidNdEtaCorrectionSelector::Init(TTree* tree)
162 // read the user objects
164 AliSelectorRL::Init(tree);
166 // Enable only the needed branches
169 tree->SetBranchStatus("*", 0);
170 tree->SetBranchStatus("fTriggerMask", 1);
171 tree->SetBranchStatus("fSPDVertex*", 1);
172 tree->SetBranchStatus("fTracks.fLabel", 1);
173 tree->SetBranchStatus("fTracks.fITSncls", 1);
174 tree->SetBranchStatus("fTracks.fTPCncls", 1);
176 AliESDtrackCuts::EnableNeededBranches(tree);
180 Bool_t AlidNdEtaCorrectionSelector::Process(Long64_t entry)
182 // The Process() function is called for each entry in the tree (or possibly
183 // keyed object in the case of PROOF) to be processed. The entry argument
184 // specifies which entry in the currently loaded tree is to be processed.
185 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
186 // to read either all or the required parts of the data. When processing
187 // keyed objects with PROOF, the object is already loaded and is available
188 // via the fObject pointer.
190 // This function should contain the "body" of the analysis. It can contain
191 // simple or elaborate selection criteria, run algorithms on the data
192 // of the event and typically fill histograms.
194 // WARNING when a selector is used with a TChain, you must use
195 // the pointer to the current TTree to call GetEntry(entry).
196 // The entry is always the local entry number in the current tree.
197 // Assuming that fTree is the pointer to the TChain being processed,
198 // use fTree->GetTree()->GetEntry(entry).
200 AliDebug(AliLog::kDebug+1,"Processing event ...\n");
203 if (AliSelectorRL::Process(entry) == kFALSE)
206 // check prerequesites
209 AliDebug(AliLog::kError, "ESD branch not available");
213 AliHeader* header = GetHeader();
216 AliDebug(AliLog::kError, "Header not available");
220 AliStack* stack = GetStack();
223 AliDebug(AliLog::kError, "Stack not available");
229 AliDebug(AliLog::kError, "fESDTrackCuts not available");
233 Bool_t vertexReconstructed = AliPWG0Helper::IsVertexReconstructed(fESD);
235 Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD);
238 AliGenEventHeader* genHeader = header->GenEventHeader();
240 // primary vertex (from MC)
242 genHeader->PrimaryVertex(vtxMC);
245 Int_t processType = AliPWG0depHelper::GetPythiaEventProcessType(header);
246 AliDebug(AliLog::kDebug+1, Form("Found pythia procces type %d", processType));
249 AliDebug(AliLog::kError, Form("Unknown Pythia process type %d.", processType));
251 // loop over mc particles
252 Int_t nPrim = stack->GetNprimary();
254 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
256 AliDebug(AliLog::kDebug+1, Form("MC Loop: Processing particle %d.", iMc));
258 TParticle* particle = stack->Particle(iMc);
262 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (mc loop).", iMc));
266 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
269 if (SignOK(particle->GetPDG()) == kFALSE)
272 Float_t eta = particle->Eta();
273 Float_t pt = particle->Pt();
275 fdNdEtaCorrection->FillMCParticle(vtxMC[2], eta, pt, eventTriggered, vertexReconstructed, processType);
279 if (vertexReconstructed)
281 fdNdEtaAnalysisMC->FillTrack(vtxMC[2], eta, pt);
284 } // end of mc particle
286 // ########################################################
287 // loop over esd tracks
288 Int_t nTracks = fESD->GetNumberOfTracks();
290 // count the number of "good" tracks as parameter for vertex reconstruction efficiency
291 Int_t nGoodTracks = 0;
292 for (Int_t t=0; t<nTracks; t++)
294 AliDebug(AliLog::kDebug+1, Form("ESD Loop: Processing track %d.", t));
296 AliESDtrack* esdTrack = fESD->GetTrack(t);
298 // cut the esd track?
299 if (!fEsdTrackCuts->AcceptTrack(esdTrack))
304 // using the properties of the mc particle
305 Int_t label = TMath::Abs(esdTrack->GetLabel());
308 AliDebug(AliLog::kWarning, Form("WARNING: cannot find corresponding mc part for track %d.", t));
312 TParticle* particle = stack->Particle(label);
315 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (track loop).", label));
319 if (SignOK(particle->GetPDG()) == kFALSE)
322 if (eventTriggered && vertexReconstructed)
324 fdNdEtaCorrection->FillTrackedParticle(vtxMC[2], particle->Eta(), particle->Pt());
325 fdNdEtaAnalysisESD->FillTrack(vtxMC[2], particle->Eta(), particle->Pt());
326 if (particle->Pt() > 0.1 && particle->Pt() < 0.2)
328 fPIDTracks->Fill(particle->GetPdgCode());
329 if (particle->GetPDG()->Charge() > 0)
331 fClustersITSPos->Fill(esdTrack->GetITSclusters(0));
332 fClustersTPCPos->Fill(esdTrack->GetTPCclusters(0));
336 fClustersITSNeg->Fill(esdTrack->GetITSclusters(0));
337 fClustersTPCNeg->Fill(esdTrack->GetTPCclusters(0));
341 } // end of track loop
343 if (eventTriggered && vertexReconstructed)
344 fdNdEtaAnalysisMC->FillEvent(vtxMC[2], nGoodTracks);
346 // stuff regarding the vertex reco correction and trigger bias correction
347 fdNdEtaCorrection->FillEvent(vtxMC[2], nGoodTracks, eventTriggered, vertexReconstructed, processType);
348 if (eventTriggered) {
349 if (vertexReconstructed)
351 fdNdEtaAnalysisESD->FillEvent(vtxMC[2], nGoodTracks);
358 void AlidNdEtaCorrectionSelector::SlaveTerminate()
360 // The SlaveTerminate() function is called after all entries or objects
361 // have been processed. When running with PROOF SlaveTerminate() is called
362 // on each slave server.
364 AliSelectorRL::SlaveTerminate();
366 // Add the histograms to the output on each slave server
369 AliDebug(AliLog::kError, "ERROR: Output list not initialized");
373 fOutput->Add(fdNdEtaCorrection);
374 fOutput->Add(fdNdEtaAnalysisMC);
375 fOutput->Add(fdNdEtaAnalysisESD);
378 void AlidNdEtaCorrectionSelector::Terminate()
380 // The Terminate() function is the last function to be called during
381 // a query. It always runs on the client, it can be used to present
382 // the results graphically or save the results to file.
384 AliSelectorRL::Terminate();
386 fdNdEtaCorrection = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction"));
387 fdNdEtaAnalysisMC = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaMC"));
388 fdNdEtaAnalysisESD = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaESD"));
389 if (!fdNdEtaCorrection || !fdNdEtaAnalysisMC || !fdNdEtaAnalysisESD)
391 AliDebug(AliLog::kError, "Could not read object from output list");
395 fdNdEtaCorrection->Finish();
397 TFile* fout = new TFile(Form("correction_map%s.root", GetOption()), "RECREATE");
400 fEsdTrackCuts->SaveHistograms("esd_track_cuts");
401 fdNdEtaCorrection->SaveHistograms();
402 fdNdEtaAnalysisMC->SaveHistograms();
403 fdNdEtaAnalysisESD->SaveHistograms();
408 fdNdEtaCorrection->DrawHistograms();
410 if (fPIDParticles && fPIDTracks)
412 new TCanvas("pidcanvas", "pidcanvas", 500, 500);
414 fPIDParticles->Draw();
415 fPIDTracks->SetLineColor(2);
416 fPIDTracks->Draw("SAME");
418 TDatabasePDG* pdgDB = new TDatabasePDG;
420 for (Int_t i=0; i <= fPIDParticles->GetNbinsX()+1; ++i)
421 if (fPIDParticles->GetBinContent(i) > 0)
422 printf("PDG = %d (%s): generated: %d, reconstructed: %d, ratio: %f\n", (Int_t) fPIDParticles->GetBinCenter(i), pdgDB->GetParticle((Int_t) fPIDParticles->GetBinCenter(i))->GetName(), (Int_t) fPIDParticles->GetBinContent(i), (Int_t) fPIDTracks->GetBinContent(i), ((fPIDTracks->GetBinContent(i) > 0) ? fPIDParticles->GetBinContent(i) / fPIDTracks->GetBinContent(i) : -1));
428 if (fClustersITSPos && fClustersITSNeg && fClustersTPCPos && fClustersTPCNeg)
430 TCanvas* canvas = new TCanvas("clusters", "clusters", 1000, 500);
431 canvas->Divide(2, 1);
434 fClustersITSPos->Draw();
435 fClustersITSNeg->SetLineColor(kRed);
436 fClustersITSNeg->Draw("SAME");
439 fClustersTPCPos->Draw();
440 fClustersTPCNeg->SetLineColor(kRed);
441 fClustersTPCNeg->Draw("SAME");