]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG0/dNdEta/AlidNdEtaCorrectionTask.cxx
some fixes/improvements while moving to new ESD format
[u/mrichter/AliRoot.git] / PWG0 / dNdEta / AlidNdEtaCorrectionTask.cxx
CommitLineData
0f67a57c 1/* $Id$ */
2
3#include "AlidNdEtaCorrectionTask.h"
4
5#include <TCanvas.h>
6#include <TChain.h>
7#include <TFile.h>
8#include <TH1F.h>
9#include <TParticle.h>
10
11#include <AliLog.h>
12#include <AliESDVertex.h>
13#include <AliESDEvent.h>
14#include <AliStack.h>
15#include <AliHeader.h>
16#include <AliGenEventHeader.h>
17#include <AliMultiplicity.h>
18#include <AliAnalysisManager.h>
19#include <AliMCEventHandler.h>
20#include <AliMCEvent.h>
21#include <AliESDInputHandler.h>
22
23#include "esdTrackCuts/AliESDtrackCuts.h"
24#include "AliPWG0Helper.h"
25//#include "AliCorrection.h"
26//#include "AliCorrectionMatrix3D.h"
27#include "dNdEta/dNdEtaAnalysis.h"
28#include "dNdEta/AlidNdEtaCorrection.h"
29
30ClassImp(AlidNdEtaCorrectionTask)
31
32AlidNdEtaCorrectionTask::AlidNdEtaCorrectionTask(const char* opt) :
33 AliAnalysisTask("AlidNdEtaCorrectionTask", ""),
34 fESD(0),
35 fOutput(0),
36 fOption(opt),
37 fAnalysisMode(kTPC),
38 fSignMode(0),
39 fEsdTrackCuts(0),
40 fdNdEtaCorrection(0),
41 fdNdEtaAnalysisMC(0),
42 fdNdEtaAnalysisESD(0),
43 fPIDParticles(0),
44 fPIDTracks(0)
45{
46 //
47 // Constructor. Initialization of pointers
48 //
49
50 // Define input and output slots here
51 DefineInput(0, TChain::Class());
52 DefineOutput(0, TList::Class());
53}
54
55AlidNdEtaCorrectionTask::~AlidNdEtaCorrectionTask()
56{
57 //
58 // Destructor
59 //
60
61 // histograms are in the output list and deleted when the output
62 // list is deleted by the TSelector dtor
63
64 if (fOutput) {
65 delete fOutput;
66 fOutput = 0;
67 }
68}
69
70//________________________________________________________________________
71void AlidNdEtaCorrectionTask::ConnectInputData(Option_t *)
72{
73 // Connect ESD
74 // Called once
75
76 Printf("AlidNdEtaCorrectionTask::ConnectInputData called");
77
78 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
79 if (!tree) {
80 Printf("ERROR: Could not read tree from input slot 0");
81 } else {
82 // Disable all branches and enable only the needed ones
83 tree->SetBranchStatus("*", 0);
84
85 tree->SetBranchStatus("fTriggerMask", 1);
86 tree->SetBranchStatus("fSPDVertex*", 1);
87
88 if (fAnalysisMode == kSPD)
89 tree->SetBranchStatus("fSPDMult*", 1);
90
91 if (fAnalysisMode == kTPC) {
92 AliESDtrackCuts::EnableNeededBranches(tree);
93 tree->SetBranchStatus("fTracks.fLabel", 1);
94 }
95
0f67a57c 96 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
97
98 if (!esdH) {
99 Printf("ERROR: Could not get ESDInputHandler");
100 } else
101 fESD = esdH->GetEvent();
102 }
103}
104
105void AlidNdEtaCorrectionTask::CreateOutputObjects()
106{
107 // create result objects and add to output list
108
109 if (fOption.Contains("only-positive"))
110 {
111 Printf("INFO: Processing only positive particles.");
112 fSignMode = 1;
113 }
114 else if (fOption.Contains("only-negative"))
115 {
116 Printf("INFO: Processing only negative particles.");
117 fSignMode = -1;
118 }
119
120 TString detector;
121 if (fAnalysisMode == kTPC)
122 {
123 detector = "TPC";
124 }
125 else if (fAnalysisMode == kSPD)
126 detector = "SPD";
127
128 fOutput = new TList;
129 fOutput->SetOwner();
130
131 fdNdEtaCorrection = new AlidNdEtaCorrection("dndeta_correction", "dndeta_correction", detector);
132 fOutput->Add(fdNdEtaCorrection);
133
134 fPIDParticles = new TH1F("pid_particles", "PID of generated primary particles", 10001, -5000.5, 5000.5);
135 fOutput->Add(fPIDParticles);
136
137 fPIDTracks = new TH1F("pid_tracks", "MC PID of reconstructed tracks", 10001, -5000.5, 5000.5);
138 fOutput->Add(fPIDTracks);
139
140 fdNdEtaAnalysisMC = new dNdEtaAnalysis("dndetaMC", "dndetaMC", detector);
141 fOutput->Add(fdNdEtaAnalysisMC);
142
143 fdNdEtaAnalysisESD = new dNdEtaAnalysis("dndetaESD", "dndetaESD", detector);
144 fOutput->Add(fdNdEtaAnalysisESD);
145}
146
147void AlidNdEtaCorrectionTask::Exec(Option_t*)
148{
149 // process the event
150
151 // Check prerequisites
152 if (!fESD)
153 {
154 AliDebug(AliLog::kError, "ESD branch not available");
155 return;
156 }
157
158 // trigger definition
159 Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD->GetTriggerMask(), AliPWG0Helper::kMB2);
160
161 Bool_t eventVertex = AliPWG0Helper::IsVertexReconstructed(fESD->GetVertex());
162
163 // post the data already here
164 PostData(0, fOutput);
165
166 // create list of (label, eta, pt) tuples
167 Int_t inputCount = 0;
168 Int_t* labelArr = 0;
169 Float_t* etaArr = 0;
170 Float_t* ptArr = 0;
171 if (fAnalysisMode == kSPD)
172 {
173 // get tracklets
174 const AliMultiplicity* mult = fESD->GetMultiplicity();
175 if (!mult)
176 {
177 AliDebug(AliLog::kError, "AliMultiplicity not available");
178 return;
179 }
180
181 labelArr = new Int_t[mult->GetNumberOfTracklets()];
182 etaArr = new Float_t[mult->GetNumberOfTracklets()];
183 ptArr = new Float_t[mult->GetNumberOfTracklets()];
184
185 // get multiplicity from ITS tracklets
186 for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
187 {
188 //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
189
190 // This removes non-tracklets in PDC06 data. Very bad solution. New solution is implemented for newer data. Keeping this for compatibility.
191 if (mult->GetDeltaPhi(i) < -1000)
192 continue;
193
194 etaArr[inputCount] = mult->GetEta(i);
195 labelArr[inputCount] = mult->GetLabel(i);
196 ptArr[inputCount] = 0; // no pt for tracklets
197 ++inputCount;
198 }
199 }
200 else if (fAnalysisMode == kTPC)
201 {
202 if (!fEsdTrackCuts)
203 {
204 AliDebug(AliLog::kError, "fESDTrackCuts not available");
205 return;
206 }
207
208 // get multiplicity from ESD tracks
209 TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD);
210 Int_t nGoodTracks = list->GetEntries();
211
212 labelArr = new Int_t[nGoodTracks];
213 etaArr = new Float_t[nGoodTracks];
214 ptArr = new Float_t[nGoodTracks];
215
216 // loop over esd tracks
217 for (Int_t i=0; i<nGoodTracks; i++)
218 {
219 AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
220 if (!esdTrack)
221 {
222 AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
223 continue;
224 }
225
226 etaArr[inputCount] = esdTrack->Eta();
227 labelArr[inputCount] = TMath::Abs(esdTrack->GetLabel());
228 ptArr[inputCount] = esdTrack->Pt();
229 ++inputCount;
230 }
231 }
232 else
233 return;
234
235 AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
236 if (!eventHandler) {
237 Printf("ERROR: Could not retrieve MC event handler");
238 return;
239 }
240
241 AliMCEvent* mcEvent = eventHandler->MCEvent();
242 if (!mcEvent) {
243 Printf("ERROR: Could not retrieve MC event");
244 return;
245 }
246
247 AliStack* stack = mcEvent->Stack();
248 if (!stack)
249 {
250 AliDebug(AliLog::kError, "Stack not available");
251 return;
252 }
253
254 AliHeader* header = mcEvent->Header();
255 if (!header)
256 {
257 AliDebug(AliLog::kError, "Header not available");
258 return;
259 }
260
261 // get process type
262 Int_t processType = AliPWG0Helper::GetPythiaEventProcessType(header);
263 AliDebug(AliLog::kDebug+1, Form("Found pythia procces type %d", processType));
264
265 if (processType<0)
266 AliDebug(AliLog::kError, Form("Unknown Pythia process type %d.", processType));
267
268 // get the MC vertex
269 AliGenEventHeader* genHeader = header->GenEventHeader();
270 TArrayF vtxMC(3);
271 genHeader->PrimaryVertex(vtxMC);
272
273 // loop over mc particles
274 Int_t nPrim = stack->GetNprimary();
275
276 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
277 {
278 //Printf("Getting particle %d", iMc);
279 TParticle* particle = stack->Particle(iMc);
280
281 if (!particle)
282 continue;
283
284 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
285 continue;
286
287 if (SignOK(particle->GetPDG()) == kFALSE)
288 continue;
289
290 Float_t eta = particle->Eta();
291 Float_t pt = particle->Pt();
292
293 fdNdEtaCorrection->FillMCParticle(vtxMC[2], eta, pt, eventTriggered, eventVertex, processType);
294
295 if (eventTriggered)
296 if (eventVertex)
297 fdNdEtaAnalysisMC->FillTrack(vtxMC[2], eta, pt);
298 }
299
300 for (Int_t i=0; i<inputCount; ++i)
301 {
302 Int_t label = labelArr[i];
303
304 if (label < 0)
305 {
306 AliDebug(AliLog::kWarning, Form("WARNING: cannot find corresponding mc part for track %d.", label));
307 continue;
308 }
309
310 TParticle* particle = stack->Particle(label);
311 if (!particle)
312 {
313 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (track loop).", label));
314 continue;
315 }
316
317 if (SignOK(particle->GetPDG()) == kFALSE)
318 continue;
319
320 if (eventTriggered && eventVertex)
321 {
322 fdNdEtaCorrection->FillTrackedParticle(vtxMC[2], particle->Eta(), particle->Pt());
323 fdNdEtaAnalysisESD->FillTrack(vtxMC[2], particle->Eta(), particle->Pt());
324 if (particle->Pt() > 0.1 && particle->Pt() < 0.2)
325 {
326 fPIDTracks->Fill(particle->GetPdgCode());
327 }
328 }
329 }
330
331 if (eventTriggered && eventVertex)
332 fdNdEtaAnalysisMC->FillEvent(vtxMC[2], inputCount);
333
334 // stuff regarding the vertex reco correction and trigger bias correction
335 fdNdEtaCorrection->FillEvent(vtxMC[2], inputCount, eventTriggered, eventVertex, processType);
336 if (eventTriggered) {
337 if (eventVertex)
338 {
339 fdNdEtaAnalysisESD->FillEvent(vtxMC[2], inputCount);
340 }
341 }
342
343 delete[] etaArr;
344 delete[] labelArr;
345 delete[] ptArr;
346}
347
348void AlidNdEtaCorrectionTask::Terminate(Option_t *)
349{
350 // The Terminate() function is the last function to be called during
351 // a query. It always runs on the client, it can be used to present
352 // the results graphically or save the results to file.
353
354 fOutput = dynamic_cast<TList*> (GetOutputData(0));
355 if (!fOutput) {
356 Printf("ERROR: fOutput not available");
357 return;
358 }
359
360 fdNdEtaCorrection = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction"));
361 fdNdEtaAnalysisMC = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaMC"));
362 fdNdEtaAnalysisESD = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaESD"));
363 if (!fdNdEtaCorrection || !fdNdEtaAnalysisMC || !fdNdEtaAnalysisESD)
364 {
365 AliDebug(AliLog::kError, "Could not read object from output list");
366 return;
367 }
368
369 fdNdEtaCorrection->Finish();
370
371 TString fileName;
372 fileName.Form("correction_map%s.root", fOption.Data());
373 TFile* fout = new TFile(fileName, "RECREATE");
374
375 if (fEsdTrackCuts)
376 fEsdTrackCuts->SaveHistograms("esd_track_cuts");
377 fdNdEtaCorrection->SaveHistograms();
378 fdNdEtaAnalysisMC->SaveHistograms();
379 fdNdEtaAnalysisESD->SaveHistograms();
380
381 fout->Write();
382 fout->Close();
383
384 fdNdEtaCorrection->DrawHistograms();
385
386 if (fPIDParticles && fPIDTracks)
387 {
388 new TCanvas("pidcanvas", "pidcanvas", 500, 500);
389
390 fPIDParticles->Draw();
391 fPIDTracks->SetLineColor(2);
392 fPIDTracks->Draw("SAME");
393
394 TDatabasePDG* pdgDB = new TDatabasePDG;
395
396 for (Int_t i=0; i <= fPIDParticles->GetNbinsX()+1; ++i)
397 if (fPIDParticles->GetBinContent(i) > 0)
398 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));
399
400 delete pdgDB;
401 pdgDB = 0;
402 }
403
404 Printf("Writting result to %s", fileName.Data());
405}
406
407Bool_t AlidNdEtaCorrectionTask::SignOK(TParticlePDG* particle)
408{
409 // returns if a particle with this sign should be counted
410 // this is determined by the value of fSignMode, which should have the same sign
411 // as the charge
412 // if fSignMode is 0 all particles are counted
413
414 if (fSignMode == 0)
415 return kTRUE;
416
417 if (!particle)
418 {
419 printf("WARNING: not counting a particle that does not have a pdg particle\n");
420 return kFALSE;
421 }
422
423 Double_t charge = particle->Charge();
424
425 if (fSignMode > 0)
426 if (charge < 0)
427 return kFALSE;
428
429 if (fSignMode < 0)
430 if (charge > 0)
431 return kFALSE;
432
433 return kTRUE;
434}