]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG0/dNdEta/AliMultiplicityMCSelector.cxx
AliPWG0depHelper: function to find mother among the primaries
[u/mrichter/AliRoot.git] / PWG0 / dNdEta / AliMultiplicityMCSelector.cxx
CommitLineData
43a9a462 1/* $Id$ */
2
3#include "AliMultiplicityMCSelector.h"
4
5#include <TStyle.h>
6#include <TSystem.h>
7#include <TCanvas.h>
8#include <TVector3.h>
9#include <TChain.h>
10#include <TFile.h>
43a9a462 11#include <TH2F.h>
0a173978 12#include <TH3F.h>
43a9a462 13#include <TParticle.h>
447c325d 14#include <TRandom.h>
15#include <TNtuple.h>
43a9a462 16
17#include <AliLog.h>
18#include <AliESD.h>
19#include <AliStack.h>
0a173978 20#include <AliHeader.h>
21#include <AliGenEventHeader.h>
22#include <AliMultiplicity.h>
43a9a462 23
24#include "esdTrackCuts/AliESDtrackCuts.h"
25#include "AliPWG0Helper.h"
447c325d 26#include "AliPWG0depHelper.h"
0a173978 27#include "dNdEta/AliMultiplicityCorrection.h"
447c325d 28#include "AliCorrection.h"
29#include "AliCorrectionMatrix3D.h"
43a9a462 30
cfc19dd5 31//#define TPCMEASUREMENT
32#define ITSMEASUREMENT
33
43a9a462 34ClassImp(AliMultiplicityMCSelector)
35
36AliMultiplicityMCSelector::AliMultiplicityMCSelector() :
37 AliSelectorRL(),
0a173978 38 fMultiplicity(0),
447c325d 39 fEsdTrackCuts(0),
40 fSystSkipParticles(kFALSE),
41 fSelectProcessType(0),
42 fParticleSpecies(0)
43a9a462 43{
44 //
45 // Constructor. Initialization of pointers
46 //
447c325d 47
48 for (Int_t i = 0; i<4; i++)
49 fParticleCorrection[i] = 0;
43a9a462 50}
51
52AliMultiplicityMCSelector::~AliMultiplicityMCSelector()
53{
54 //
55 // Destructor
56 //
57
58 // histograms are in the output list and deleted when the output
59 // list is deleted by the TSelector dtor
60}
61
62void AliMultiplicityMCSelector::Begin(TTree* tree)
63{
64 // Begin function
65
66 AliSelectorRL::Begin(tree);
67
68 ReadUserObjects(tree);
69}
70
71void AliMultiplicityMCSelector::ReadUserObjects(TTree* tree)
72{
73 // read the user objects, called from slavebegin and begin
74
75 if (!fEsdTrackCuts && fInput)
76 fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (fInput->FindObject("AliESDtrackCuts"));
77
78 if (!fEsdTrackCuts && tree)
79 fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (tree->GetUserInfo()->FindObject("AliESDtrackCuts"));
80
81 if (!fEsdTrackCuts)
82 AliDebug(AliLog::kError, "ERROR: Could not read EsdTrackCuts from input list.");
83}
84
85void AliMultiplicityMCSelector::SlaveBegin(TTree* tree)
86{
87 // The SlaveBegin() function is called after the Begin() function.
88 // When running with PROOF SlaveBegin() is called on each slave server.
89 // The tree argument is deprecated (on PROOF 0 is passed).
90
91 AliSelector::SlaveBegin(tree);
92
93 ReadUserObjects(tree);
94
0a173978 95 fMultiplicity = new AliMultiplicityCorrection("Multiplicity", "Multiplicity");
447c325d 96
97 TString option(GetOption());
98 if (option.Contains("skip-particles"))
99 {
100 fSystSkipParticles = kTRUE;
101 AliInfo("WARNING: Systematic study enabled. Particles will be skipped.");
102 }
103
104 if (option.Contains("particle-efficiency"))
105 for (Int_t i = 0; i<4; i++)
106 fParticleCorrection[i] = new AliCorrection(Form("correction_%d", i), Form("correction_%d", i));
107
108 if (option.Contains("only-process-type-nd"))
109 fSelectProcessType = 1;
110
111 if (option.Contains("only-process-type-sd"))
112 fSelectProcessType = 2;
113
114 if (option.Contains("only-process-type-dd"))
115 fSelectProcessType = 3;
116
117 if (fSelectProcessType != 0)
118 AliInfo(Form("WARNING: Systematic study enabled. Only considering process type %d", fSelectProcessType));
119
120 if (option.Contains("particle-species"))
121 fParticleSpecies = new TNtuple("fParticleSpecies", "fParticleSpecies", "Pi_True:K_True:p_True:o_True:Pi_Rec:K_Rec:p_Rec:o_Rec");
0a173978 122}
123
124void AliMultiplicityMCSelector::Init(TTree* tree)
125{
126 // read the user objects
127
128 AliSelectorRL::Init(tree);
129
b477f4f2 130 // enable only the needed branches
131 if (tree)
0a173978 132 {
133 tree->SetBranchStatus("*", 0);
134 tree->SetBranchStatus("fTriggerMask", 1);
135 tree->SetBranchStatus("fSPDVertex*", 1);
dd701109 136
137 #ifdef ITSMEASUREMENT
138 tree->SetBranchStatus("fSPDMult*", 1);
139 #endif
43a9a462 140
cfc19dd5 141 #ifdef TPCMEASUREMENT
142 AliESDtrackCuts::EnableNeededBranches(tree);
143 #endif
b477f4f2 144 }
43a9a462 145}
146
147Bool_t AliMultiplicityMCSelector::Process(Long64_t entry)
148{
149 // The Process() function is called for each entry in the tree (or possibly
150 // keyed object in the case of PROOF) to be processed. The entry argument
151 // specifies which entry in the currently loaded tree is to be processed.
152 // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
153 // to read either all or the required parts of the data. When processing
154 // keyed objects with PROOF, the object is already loaded and is available
155 // via the fObject pointer.
156 //
157 // This function should contain the "body" of the analysis. It can contain
158 // simple or elaborate selection criteria, run algorithms on the data
159 // of the event and typically fill histograms.
160
161 // WARNING when a selector is used with a TChain, you must use
162 // the pointer to the current TTree to call GetEntry(entry).
163 // The entry is always the local entry number in the current tree.
164 // Assuming that fTree is the pointer to the TChain being processed,
165 // use fTree->GetTree()->GetEntry(entry).
166
167 if (AliSelectorRL::Process(entry) == kFALSE)
168 return kFALSE;
169
170 // Check prerequisites
171 if (!fESD)
172 {
173 AliDebug(AliLog::kError, "ESD branch not available");
174 return kFALSE;
175 }
176
177 if (!fEsdTrackCuts)
178 {
179 AliDebug(AliLog::kError, "fESDTrackCuts not available");
180 return kFALSE;
181 }
182
0a173978 183 AliHeader* header = GetHeader();
184 if (!header)
185 {
186 AliDebug(AliLog::kError, "Header not available");
187 return kFALSE;
188 }
189
43a9a462 190 AliStack* stack = GetStack();
191 if (!stack)
192 {
193 AliDebug(AliLog::kError, "Stack not available");
194 return kFALSE;
195 }
196
447c325d 197 if (fSelectProcessType > 0)
198 {
199 // getting process information; NB: this only works for Pythia
200 Int_t processtype = AliPWG0depHelper::GetPythiaEventProcessType(header);
201
202 Bool_t processEvent = kFALSE;
203
204 // non diffractive
205 if (fSelectProcessType == 1 && processtype !=92 && processtype !=93 && processtype != 94)
206 processEvent = kTRUE;
207
208 // single diffractive
209 if (fSelectProcessType == 2 && (processtype == 92 || processtype == 93))
210 processEvent = kTRUE;
211
212 // double diffractive
213 if (fSelectProcessType == 3 && processtype == 94)
214 processEvent = kTRUE;
215
216 if (!processEvent)
217 {
218 AliDebug(AliLog::kDebug, Form("Skipping this event, because it is not of the requested process type (%d)", processtype));
219 return kTRUE;
220 }
221 }
222
cfc19dd5 223 Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD);
447c325d 224 eventTriggered = kTRUE; // no generated trigger for the simulated events
cfc19dd5 225 Bool_t eventVertex = AliPWG0Helper::IsVertexReconstructed(fESD);
43a9a462 226
0a173978 227 // get the ESD vertex
228 const AliESDVertex* vtxESD = fESD->GetVertex();
229 Double_t vtx[3];
230 vtxESD->GetXYZ(vtx);
231
232 // get the MC vertex
233 AliGenEventHeader* genHeader = header->GenEventHeader();
234 TArrayF vtxMC(3);
235 genHeader->PrimaryVertex(vtxMC);
236
237 // get tracklets
238 const AliMultiplicity* mult = fESD->GetMultiplicity();
239 if (!mult)
240 {
241 AliDebug(AliLog::kError, "AliMultiplicity not available");
242 return kFALSE;
243 }
43a9a462 244
0a173978 245 //const Float_t kPtCut = 0.3;
43a9a462 246
247 // get number of tracks from MC
248 // loop over mc particles
249 Int_t nPrim = stack->GetNprimary();
0a173978 250
251 // tracks in different eta ranges
252 Int_t nMCTracks05 = 0;
253 Int_t nMCTracks10 = 0;
254 Int_t nMCTracks15 = 0;
255 Int_t nMCTracks20 = 0;
256 Int_t nMCTracksAll = 0;
257
447c325d 258 // tracks per particle species, in |eta| < 2 (systematic study)
259 Int_t nMCTracksSpecies[4]; // (pi, K, p, other)
260 for (Int_t i = 0; i<4; ++i)
261 nMCTracksSpecies[i] = 0;
262
43a9a462 263 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
264 {
265 AliDebug(AliLog::kDebug+1, Form("MC Loop: Processing particle %d.", iMc));
266
267 TParticle* particle = stack->Particle(iMc);
268
269 if (!particle)
270 {
271 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (mc loop).", iMc));
272 continue;
273 }
274
447c325d 275 Bool_t debug = kFALSE;
276 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim, debug) == kFALSE)
277 {
278 //printf("%d) DROPPED ", iMC);
279 //particle->Print();
43a9a462 280 continue;
447c325d 281 }
282
283 //printf("%d) OK ", iMC);
284 //particle->Print();
43a9a462 285
0a173978 286 //if (particle->Pt() < kPtCut)
287 // continue;
43a9a462 288
0a173978 289 if (TMath::Abs(particle->Eta()) < 0.5)
290 nMCTracks05++;
43a9a462 291
0a173978 292 if (TMath::Abs(particle->Eta()) < 1.0)
293 nMCTracks10++;
294
295 if (TMath::Abs(particle->Eta()) < 1.5)
296 nMCTracks15++;
297
298 if (TMath::Abs(particle->Eta()) < 2.0)
299 nMCTracks20++;
300
301 nMCTracksAll++;
447c325d 302
303 Int_t id = -1;
304 switch (TMath::Abs(particle->GetPdgCode()))
305 {
306 case 211: id = 0; break;
307 case 321: id = 1; break;
308 case 2212: id = 2; break;
309 default: id = 3; break;
310 }
311 if (TMath::Abs(particle->Eta()) < 2.0)
312 nMCTracksSpecies[id]++;
313 if (fParticleCorrection[id])
314 fParticleCorrection[id]->GetTrackCorrection()->FillGene(vtxMC[2], particle->Eta(), particle->Pt());
43a9a462 315 }// end of mc particle
316
cfc19dd5 317 fMultiplicity->FillGenerated(vtxMC[2], eventTriggered, eventVertex, nMCTracks05, nMCTracks10, nMCTracks15, nMCTracks20, nMCTracksAll);
318
319 if (!eventTriggered || !eventVertex)
320 return kTRUE;
0a173978 321
322 Int_t nESDTracks05 = 0;
323 Int_t nESDTracks10 = 0;
324 Int_t nESDTracks15 = 0;
325 Int_t nESDTracks20 = 0;
326
447c325d 327 // tracks per particle species, in |eta| < 2 (systematic study)
328 Int_t nESDTracksSpecies[4]; // (pi, K, p, other)
329 for (Int_t i = 0; i<4; ++i)
330 nESDTracksSpecies[i] = 0;
331
cfc19dd5 332#ifdef ITSMEASUREMENT
0a173978 333 // get multiplicity from ITS tracklets
334 for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
335 {
336 //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
337
338 // this removes non-tracklets. Very bad solution. SPD guys are working on better solution...
339 if (mult->GetDeltaPhi(i) < -1000)
340 continue;
341
447c325d 342 // systematic study: 10% lower efficiency
343 if (fSystSkipParticles && gRandom->Uniform() < 0.1)
344 continue;
345
0a173978 346 Float_t theta = mult->GetTheta(i);
347 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
348
349 if (TMath::Abs(eta) < 0.5)
350 nESDTracks05++;
351
352 if (TMath::Abs(eta) < 1.0)
353 nESDTracks10++;
354
355 if (TMath::Abs(eta) < 1.5)
356 nESDTracks15++;
357
358 if (TMath::Abs(eta) < 2.0)
359 nESDTracks20++;
447c325d 360
361 // TODO define needed, because this only works with new AliRoot
362 Int_t label = mult->GetLabel(i);
363 if (label < 0)
364 continue;
365
366 TParticle* mother = AliPWG0depHelper::FindPrimaryMother(stack, label);
367
368 if (!mother)
369 continue;
370
371 Int_t id = -1;
372 switch (TMath::Abs(mother->GetPdgCode()))
373 {
374 case 211: id = 0; break;
375 case 321: id = 1; break;
376 case 2212: id = 2; break;
377 default: id = 3; break;
378 }
379 if (TMath::Abs(eta) < 2.0)
380 nESDTracksSpecies[id]++;
381 if (fParticleCorrection[id])
382 fParticleCorrection[id]->GetTrackCorrection()->FillMeas(vtxMC[2], mother->Eta(), mother->Pt());
0a173978 383 }
cfc19dd5 384#endif
0a173978 385
cfc19dd5 386#ifdef TPCMEASUREMENT
0a173978 387 // get multiplicity from ESD tracks
cfc19dd5 388 TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD);
0a173978 389 Int_t nGoodTracks = list->GetEntries();
390 // loop over esd tracks
391 for (Int_t i=0; i<nGoodTracks; i++)
392 {
393 AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
394 if (!esdTrack)
395 {
396 AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
397 continue;
398 }
399
400 Double_t p[3];
401 esdTrack->GetConstrainedPxPyPz(p); // ### TODO should be okay because we have a vertex, however GetInnerPxPyPy / GetOuterPxPyPy also exist
402 TVector3 vector(p);
403
404 Float_t theta = vector.Theta();
405 Float_t eta = -TMath::Log(TMath::Tan(theta/2.));
406 Float_t pt = vector.Pt();
407
cfc19dd5 408 //if (pt < kPtCut)
409 // continue;
0a173978 410
411 if (TMath::Abs(eta) < 0.5)
412 nESDTracks05++;
43a9a462 413
0a173978 414 if (TMath::Abs(eta) < 1.0)
415 nESDTracks10++;
416
417 if (TMath::Abs(eta) < 1.5)
418 nESDTracks15++;
419
420 if (TMath::Abs(eta) < 2.0)
421 nESDTracks20++;
447c325d 422
423 Int_t label = esdTrack->GetLabel();
424 if (label < 0)
425 continue;
426
427 TParticle* mother = AliPWG0depHelper::FindPrimaryMother(stack, label);
428
429 if (!mother)
430 continue;
431
432 Int_t id = -1;
433 switch (TMath::Abs(mother->GetPdgCode()))
434 {
435 case 211: id = 0; break;
436 case 321: id = 1; break;
437 case 2212: id = 2; break;
438 default: id = 3; break;
439 }
440 if (TMath::Abs(eta) < 2.0)
441 nESDTracksSpecies[id]++;
442 if (fParticleCorrection[id])
443 fParticleCorrection[id]->GetTrackCorrection()->FillMeas(vtxMC[2], mother->Eta(), mother->Pt());
cfc19dd5 444 }
445#endif
0a173978 446
447c325d 447 if (nMCTracks20 == 0 && nESDTracks20 > 3)
448 printf("WARNING: Event %lld has %d generated and %d reconstructed...\n", entry, nMCTracks05, nESDTracks05);
449
dd701109 450 fMultiplicity->FillMeasured(vtx[2], nESDTracks05, nESDTracks10, nESDTracks15, nESDTracks20);
0a173978 451
452 // TODO should this be vtx[2] or vtxMC[2] ?
453 fMultiplicity->FillCorrection(vtxMC[2], nMCTracks05, nMCTracks10, nMCTracks15, nMCTracks20, nMCTracksAll, nESDTracks05, nESDTracks10, nESDTracks15, nESDTracks20);
43a9a462 454
447c325d 455 if (fParticleSpecies)
456 fParticleSpecies->Fill(nMCTracksSpecies[0], nMCTracksSpecies[1], nMCTracksSpecies[2], nMCTracksSpecies[3], nESDTracksSpecies[0], nESDTracksSpecies[1], nESDTracksSpecies[2], nESDTracksSpecies[3]);
457
43a9a462 458 return kTRUE;
459}
460
461void AliMultiplicityMCSelector::SlaveTerminate()
462{
463 // The SlaveTerminate() function is called after all entries or objects
464 // have been processed. When running with PROOF SlaveTerminate() is called
465 // on each slave server.
466
467 AliSelector::SlaveTerminate();
468
469 // Add the histograms to the output on each slave server
470 if (!fOutput)
471 {
472 AliDebug(AliLog::kError, Form("ERROR: Output list not initialized."));
473 return;
474 }
475
0a173978 476 fOutput->Add(fMultiplicity);
447c325d 477 for (Int_t i = 0; i < 4; ++i)
478 fOutput->Add(fParticleCorrection[i]);
479
480 fOutput->Add(fParticleSpecies);
43a9a462 481}
482
483void AliMultiplicityMCSelector::Terminate()
484{
485 // The Terminate() function is the last function to be called during
486 // a query. It always runs on the client, it can be used to present
487 // the results graphically or save the results to file.
488
489 AliSelector::Terminate();
490
0a173978 491 fMultiplicity = dynamic_cast<AliMultiplicityCorrection*> (fOutput->FindObject("Multiplicity"));
447c325d 492 for (Int_t i = 0; i < 4; ++i)
493 fParticleCorrection[i] = dynamic_cast<AliCorrection*> (fOutput->FindObject(Form("correction_%d", i)));
494 fParticleSpecies = dynamic_cast<TNtuple*> (fOutput->FindObject("fParticleSpecies"));
43a9a462 495
0a173978 496 if (!fMultiplicity)
43a9a462 497 {
0a173978 498 AliDebug(AliLog::kError, Form("ERROR: Histograms not available %p", (void*) fMultiplicity));
43a9a462 499 return;
500 }
501
f31d5d49 502 TFile* file = TFile::Open("multiplicityMC.root", "RECREATE");
43a9a462 503
0a173978 504 fMultiplicity->SaveHistograms();
447c325d 505 for (Int_t i = 0; i < 4; ++i)
506 if (fParticleCorrection[i])
507 fParticleCorrection[i]->SaveHistograms();
508 fParticleSpecies->Write();
43a9a462 509
510 file->Close();
0a173978 511
512 fMultiplicity->DrawHistograms();
43a9a462 513}