]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG0/multiplicity/AliMultiplicityTask.cxx
silvermy@ornl.gov - adding Calib areas for Preprocessor
[u/mrichter/AliRoot.git] / PWG0 / multiplicity / AliMultiplicityTask.cxx
CommitLineData
a9017e49 1/* $Id$ */
2
3#include "AliMultiplicityTask.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>
11#include <TH2F.h>
12#include <TH3F.h>
13#include <TParticle.h>
14#include <TRandom.h>
15#include <TNtuple.h>
16#include <TObjString.h>
17#include <TF1.h>
18
19#include <AliLog.h>
20#include <AliESDVertex.h>
21#include <AliESDEvent.h>
22#include <AliStack.h>
23#include <AliHeader.h>
24#include <AliGenEventHeader.h>
25#include <AliMultiplicity.h>
26#include <AliAnalysisManager.h>
27#include <AliMCEventHandler.h>
28#include <AliMCEvent.h>
29#include <AliESDInputHandler.h>
30
745d6088 31#include "AliESDtrackCuts.h"
a9017e49 32#include "AliPWG0Helper.h"
33#include "dNdEta/AliMultiplicityCorrection.h"
34#include "AliCorrection.h"
35#include "AliCorrectionMatrix3D.h"
36
a9017e49 37ClassImp(AliMultiplicityTask)
38
39AliMultiplicityTask::AliMultiplicityTask(const char* opt) :
40 AliAnalysisTask("AliMultiplicityTask", ""),
41 fESD(0),
42 fOption(opt),
745d6088 43 fAnalysisMode(AliPWG0Helper::kSPD),
2fa65f52 44 fReadMC(kFALSE),
a9017e49 45 fMultiplicity(0),
46 fEsdTrackCuts(0),
47 fSystSkipParticles(kFALSE),
48 fSelectProcessType(0),
49 fParticleSpecies(0),
50 fPtSpectrum(0),
51 fOutput(0)
52{
53 //
54 // Constructor. Initialization of pointers
55 //
56
57 for (Int_t i = 0; i<4; i++)
58 fParticleCorrection[i] = 0;
59
60 // Define input and output slots here
61 DefineInput(0, TChain::Class());
62 DefineOutput(0, TList::Class());
63}
64
65AliMultiplicityTask::~AliMultiplicityTask()
66{
67 //
68 // Destructor
69 //
70
71 // histograms are in the output list and deleted when the output
72 // list is deleted by the TSelector dtor
73
74 if (fOutput) {
75 delete fOutput;
76 fOutput = 0;
77 }
78}
79
80//________________________________________________________________________
81void AliMultiplicityTask::ConnectInputData(Option_t *)
82{
83 // Connect ESD
84 // Called once
85
2fa65f52 86 Printf("AliMultiplicityTask::ConnectInputData called");
87
a9017e49 88 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
89 if (!tree) {
90 Printf("ERROR: Could not read tree from input slot 0");
91 } else {
92 // Disable all branches and enable only the needed ones
2fa65f52 93 //tree->SetBranchStatus("*", 0);
94
a9017e49 95 tree->SetBranchStatus("fTriggerMask", 1);
96 tree->SetBranchStatus("fSPDVertex*", 1);
97
745d6088 98 if (fAnalysisMode == AliPWG0Helper::kSPD)
a9017e49 99 tree->SetBranchStatus("fSPDMult*", 1);
a9017e49 100
745d6088 101 if (fAnalysisMode == AliPWG0Helper::kTPC || fAnalysisMode == AliPWG0Helper::kTPCITS) {
a9017e49 102 AliESDtrackCuts::EnableNeededBranches(tree);
103 tree->SetBranchStatus("fTracks.fLabel", 1);
2fa65f52 104 }
a9017e49 105
a9017e49 106 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
107
108 if (!esdH) {
109 Printf("ERROR: Could not get ESDInputHandler");
110 } else
111 fESD = esdH->GetEvent();
112 }
113}
114
115void AliMultiplicityTask::CreateOutputObjects()
116{
117 // create result objects and add to output list
118
119 fOutput = new TList;
120 fOutput->SetOwner();
121
122 fMultiplicity = new AliMultiplicityCorrection("Multiplicity", "Multiplicity");
123 fOutput->Add(fMultiplicity);
124
125 if (fOption.Contains("skip-particles"))
126 {
127 fSystSkipParticles = kTRUE;
128 AliInfo("WARNING: Systematic study enabled. Particles will be skipped.");
129 }
130
131 if (fOption.Contains("particle-efficiency"))
132 for (Int_t i = 0; i<4; i++)
133 {
134 fParticleCorrection[i] = new AliCorrection(Form("correction_%d", i), Form("correction_%d", i));
135 fOutput->Add(fParticleCorrection[i]);
136 }
137
138 if (fOption.Contains("only-process-type-nd"))
139 fSelectProcessType = 1;
140
141 if (fOption.Contains("only-process-type-sd"))
142 fSelectProcessType = 2;
143
144 if (fOption.Contains("only-process-type-dd"))
145 fSelectProcessType = 3;
146
147 if (fSelectProcessType != 0)
148 AliInfo(Form("WARNING: Systematic study enabled. Only considering process type %d", fSelectProcessType));
149
150 if (fOption.Contains("pt-spectrum-hist"))
151 {
152 TFile* file = TFile::Open("ptspectrum_fit.root");
153 if (file)
154 {
155 TString subStr(fOption(fOption.Index("pt-spectrum")+17, 3));
156 TString histName(Form("ptspectrum_%s", subStr.Data()));
157 AliInfo(Form("Pt-Spectrum modification. Using %s.", histName.Data()));
158 fPtSpectrum = (TH1*) file->Get(histName);
159 if (!fPtSpectrum)
160 AliError("Histogram not found");
161 }
162 else
163 AliError("Could not open ptspectrum_fit.root. Pt Spectrum study could not be enabled.");
164
165 if (fPtSpectrum)
166 AliInfo("WARNING: Systematic study enabled. Pt spectrum will be modified");
167 }
168
169 if (fOption.Contains("pt-spectrum-func"))
170 {
171 if (fPtSpectrum)
172 {
173 Printf("Using function from input list for systematic p_t study");
174 }
175 else
176 {
177 fPtSpectrum = new TH1F("fPtSpectrum", "fPtSpectrum", 1, 0, 100);
178 fPtSpectrum->SetBinContent(1, 1);
179 }
180
181 if (fPtSpectrum)
182 AliInfo("WARNING: Systematic study enabled. Pt spectrum will be modified");
183 }
184
185 if (fOption.Contains("particle-species")) {
186 fParticleSpecies = new TNtuple("fParticleSpecies", "fParticleSpecies", "vtx:Pi_True:K_True:p_True:o_True:Pi_Rec:K_Rec:p_Rec:o_Rec:nolabel:doublePrim:doubleCount");
187 fOutput->Add(fParticleSpecies);
188 }
189
190 // TODO set seed for random generator
191}
192
193void AliMultiplicityTask::Exec(Option_t*)
194{
195 // process the event
196
197 // Check prerequisites
198 if (!fESD)
199 {
745d6088 200 AliDebug(AliLog::kError, "ESD not available");
a9017e49 201 return;
202 }
203
745d6088 204 //MB1 definition
205 Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD->GetTriggerMask(), AliPWG0Helper::kMB1);
2fa65f52 206 // only FASTOR
745d6088 207 //Bool_t eventTriggered = fESD->GetTriggerMask() & 32;
a9017e49 208
209 Bool_t eventVertex = AliPWG0Helper::IsVertexReconstructed(fESD->GetVertex());
210
211 // get the ESD vertex
212 const AliESDVertex* vtxESD = fESD->GetVertex();
213 Double_t vtx[3];
214 vtxESD->GetXYZ(vtx);
215
2fa65f52 216 // post the data already here
217 PostData(0, fOutput);
a9017e49 218
219 //const Float_t kPtCut = 0.3;
220
2fa65f52 221 // create list of (label, eta) tuples
222 Int_t inputCount = 0;
223 Int_t* labelArr = 0;
224 Float_t* etaArr = 0;
745d6088 225 if (fAnalysisMode == AliPWG0Helper::kSPD)
a9017e49 226 {
2fa65f52 227 // get tracklets
228 const AliMultiplicity* mult = fESD->GetMultiplicity();
229 if (!mult)
a9017e49 230 {
2fa65f52 231 AliDebug(AliLog::kError, "AliMultiplicity not available");
232 return;
a9017e49 233 }
234
2fa65f52 235 labelArr = new Int_t[mult->GetNumberOfTracklets()];
236 etaArr = new Float_t[mult->GetNumberOfTracklets()];
237
238 // get multiplicity from ITS tracklets
239 for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
a9017e49 240 {
2fa65f52 241 //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
a9017e49 242
2fa65f52 243 // This removes non-tracklets in PDC06 data. Very bad solution. New solution is implemented for newer data. Keeping this for compatibility.
244 if (mult->GetDeltaPhi(i) < -1000)
245 continue;
a9017e49 246
2fa65f52 247 etaArr[inputCount] = mult->GetEta(i);
3886f106 248 // TODO add second label array
249 labelArr[inputCount] = mult->GetLabel(i, 0);
2fa65f52 250 ++inputCount;
251 }
252 }
745d6088 253 else if (fAnalysisMode == AliPWG0Helper::kTPC || fAnalysisMode == AliPWG0Helper::kTPCITS)
2fa65f52 254 {
255 if (!fEsdTrackCuts)
256 {
257 AliDebug(AliLog::kError, "fESDTrackCuts not available");
258 return;
259 }
a9017e49 260
2fa65f52 261 // get multiplicity from ESD tracks
262 TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD);
263 Int_t nGoodTracks = list->GetEntries();
a9017e49 264
2fa65f52 265 labelArr = new Int_t[nGoodTracks];
266 etaArr = new Float_t[nGoodTracks];
a9017e49 267
2fa65f52 268 // loop over esd tracks
269 for (Int_t i=0; i<nGoodTracks; i++)
a9017e49 270 {
2fa65f52 271 AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
272 if (!esdTrack)
a9017e49 273 {
2fa65f52 274 AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
275 continue;
a9017e49 276 }
2fa65f52 277
278 etaArr[inputCount] = esdTrack->Eta();
279 labelArr[inputCount] = TMath::Abs(esdTrack->GetLabel());
280 ++inputCount;
a9017e49 281 }
282
2fa65f52 283 delete list;
284 }
a9017e49 285
2fa65f52 286 // eta range for nMCTracksSpecies, nESDTracksSpecies
287 Float_t etaRange = -1;
288 switch (fAnalysisMode) {
773f84dc 289 case AliPWG0Helper::kInvalid: break;
745d6088 290 case AliPWG0Helper::kTPC:
291 case AliPWG0Helper::kTPCITS:
292 etaRange = 0.9; break;
293 case AliPWG0Helper::kSPD: etaRange = 2.0; break;
2fa65f52 294 }
a9017e49 295
2fa65f52 296 if (!fReadMC) // Processing of ESD information
297 {
298 if (eventTriggered && eventVertex)
299 {
300 Int_t nESDTracks05 = 0;
301 Int_t nESDTracks09 = 0;
302 Int_t nESDTracks15 = 0;
303 Int_t nESDTracks20 = 0;
a9017e49 304
2fa65f52 305 for (Int_t i=0; i<inputCount; ++i)
306 {
307 Float_t eta = etaArr[i];
a9017e49 308
2fa65f52 309 if (TMath::Abs(eta) < 0.5)
310 nESDTracks05++;
a9017e49 311
2fa65f52 312 if (TMath::Abs(eta) < 0.9)
313 nESDTracks09++;
a9017e49 314
2fa65f52 315 if (TMath::Abs(eta) < 1.5)
316 nESDTracks15++;
317
318 if (TMath::Abs(eta) < 2.0)
319 nESDTracks20++;
a9017e49 320 }
2fa65f52 321
322 fMultiplicity->FillMeasured(vtx[2], nESDTracks05, nESDTracks09, nESDTracks15, nESDTracks20);
323 }
324 }
325 else if (fReadMC) // Processing of MC information
326 {
327 AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
328 if (!eventHandler) {
329 Printf("ERROR: Could not retrieve MC event handler");
330 return;
a9017e49 331 }
a9017e49 332
2fa65f52 333 AliMCEvent* mcEvent = eventHandler->MCEvent();
334 if (!mcEvent) {
335 Printf("ERROR: Could not retrieve MC event");
336 return;
337 }
a9017e49 338
2fa65f52 339 AliStack* stack = mcEvent->Stack();
340 if (!stack)
341 {
342 AliDebug(AliLog::kError, "Stack not available");
343 return;
344 }
345
346 AliHeader* header = mcEvent->Header();
347 if (!header)
348 {
349 AliDebug(AliLog::kError, "Header not available");
350 return;
351 }
a9017e49 352
2fa65f52 353 Bool_t processEvent = kTRUE;
354 if (fSelectProcessType > 0)
355 {
356 // getting process information; NB: this only works for Pythia
6b62a9c7 357 Int_t processtype = AliPWG0Helper::GetEventProcessType(header);
a9017e49 358
2fa65f52 359 processEvent = kFALSE;
a9017e49 360
2fa65f52 361 // non diffractive
6b62a9c7 362 if (fSelectProcessType == 1 && processtype == AliPWG0Helper::kND )
2fa65f52 363 processEvent = kTRUE;
a9017e49 364
2fa65f52 365 // single diffractive
6b62a9c7 366 if (fSelectProcessType == 2 && processtype == AliPWG0Helper::kSD )
2fa65f52 367 processEvent = kTRUE;
a9017e49 368
2fa65f52 369 // double diffractive
6b62a9c7 370 if (fSelectProcessType == 3 && processtype == AliPWG0Helper::kDD )
2fa65f52 371 processEvent = kTRUE;
a9017e49 372
2fa65f52 373 if (!processEvent)
374 AliDebug(AliLog::kDebug, Form("Skipping this event, because it is not of the requested process type (%d)", processtype));
375 }
a9017e49 376
377 // systematic study: 10% lower efficiency
378 if (fSystSkipParticles && (gRandom->Uniform() < 0.1))
2fa65f52 379 processEvent = kFALSE;
a9017e49 380
2fa65f52 381 if (processEvent)
382 {
383 // get the MC vertex
384 AliGenEventHeader* genHeader = header->GenEventHeader();
385 TArrayF vtxMC(3);
386 genHeader->PrimaryVertex(vtxMC);
387
388 // get number of tracks from MC
389 // loop over mc particles
390 Int_t nPrim = stack->GetNprimary();
391 Int_t nMCPart = stack->GetNtrack();
392
393 // tracks in different eta ranges
394 Int_t nMCTracks05 = 0;
395 Int_t nMCTracks09 = 0;
396 Int_t nMCTracks15 = 0;
397 Int_t nMCTracks20 = 0;
398 Int_t nMCTracksAll = 0;
399
400 // tracks per particle species, in |eta| < 2 (systematic study)
401 Int_t nMCTracksSpecies[4]; // (pi, K, p, other)
402 for (Int_t i = 0; i<4; ++i)
403 nMCTracksSpecies[i] = 0;
404
405 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
406 {
407 AliDebug(AliLog::kDebug+1, Form("MC Loop: Processing particle %d.", iMc));
a9017e49 408
2fa65f52 409 TParticle* particle = stack->Particle(iMc);
a9017e49 410
2fa65f52 411 if (!particle)
412 {
413 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (mc loop).", iMc));
414 continue;
415 }
a9017e49 416
2fa65f52 417 Bool_t debug = kFALSE;
418 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim, debug) == kFALSE)
419 {
420 //printf("%d) DROPPED ", iMC);
421 //particle->Print();
422 continue;
423 }
a9017e49 424
2fa65f52 425 //printf("%d) OK ", iMC);
426 //particle->Print();
a9017e49 427
2fa65f52 428 //if (particle->Pt() < kPtCut)
429 // continue;
a9017e49 430
2fa65f52 431 Int_t particleWeight = 1;
a9017e49 432
2fa65f52 433 Float_t pt = particle->Pt();
a9017e49 434
2fa65f52 435 // in case of systematic study, weight according to the change of the pt spectrum
436 // it cannot be just multiplied because we cannot count "half of a particle"
437 // instead a random generator decides if the particle is counted twice (if value > 1)
438 // or not (if value < 0)
439 if (fPtSpectrum)
a9017e49 440 {
2fa65f52 441 Int_t bin = fPtSpectrum->FindBin(pt);
442 if (bin > 0 && bin <= fPtSpectrum->GetNbinsX())
a9017e49 443 {
2fa65f52 444 Float_t factor = fPtSpectrum->GetBinContent(bin);
445 if (factor > 0)
446 {
447 Float_t random = gRandom->Uniform();
448 if (factor > 1 && random < factor - 1)
449 {
450 particleWeight = 2;
451 }
452 else if (factor < 1 && random < 1 - factor)
453 particleWeight = 0;
454 }
a9017e49 455 }
a9017e49 456 }
a9017e49 457
2fa65f52 458 //Printf("MC weight is: %d", particleWeight);
a9017e49 459
2fa65f52 460 if (TMath::Abs(particle->Eta()) < 0.5)
461 nMCTracks05 += particleWeight;
a9017e49 462
2fa65f52 463 if (TMath::Abs(particle->Eta()) < 0.9)
464 nMCTracks09 += particleWeight;
a9017e49 465
2fa65f52 466 if (TMath::Abs(particle->Eta()) < 1.5)
467 nMCTracks15 += particleWeight;
a9017e49 468
2fa65f52 469 if (TMath::Abs(particle->Eta()) < 2.0)
470 nMCTracks20 += particleWeight;
a9017e49 471
2fa65f52 472 nMCTracksAll += particleWeight;
a9017e49 473
2fa65f52 474 if (fParticleCorrection[0] || fParticleSpecies)
475 {
476 Int_t id = -1;
477 switch (TMath::Abs(particle->GetPdgCode()))
478 {
479 case 211: id = 0; break;
480 case 321: id = 1; break;
481 case 2212: id = 2; break;
482 default: id = 3; break;
483 }
a9017e49 484
2fa65f52 485 if (TMath::Abs(particle->Eta()) < etaRange)
486 nMCTracksSpecies[id]++;
487
488 if (fParticleCorrection[id])
489 fParticleCorrection[id]->GetTrackCorrection()->FillGene(vtxMC[2], particle->Eta(), particle->Pt());
490 }
491 } // end of mc particle
a9017e49 492
2fa65f52 493 fMultiplicity->FillGenerated(vtxMC[2], eventTriggered, eventVertex, (Int_t) nMCTracks05, (Int_t) nMCTracks09, (Int_t) nMCTracks15, (Int_t) nMCTracks20, (Int_t) nMCTracksAll);
a9017e49 494
2fa65f52 495 if (eventTriggered && eventVertex)
a9017e49 496 {
2fa65f52 497 Int_t nESDTracks05 = 0;
498 Int_t nESDTracks09 = 0;
499 Int_t nESDTracks15 = 0;
500 Int_t nESDTracks20 = 0;
a9017e49 501
2fa65f52 502 // tracks per particle species, in |eta| < 2 (systematic study)
503 Int_t nESDTracksSpecies[7]; // (pi, K, p, other, nolabel, doublecount_prim, doublecount_all)
504 for (Int_t i = 0; i<7; ++i)
505 nESDTracksSpecies[i] = 0;
a9017e49 506
2fa65f52 507 Bool_t* foundPrimaries = new Bool_t[nPrim]; // to prevent double counting
508 for (Int_t i=0; i<nPrim; i++)
509 foundPrimaries[i] = kFALSE;
a9017e49 510
2fa65f52 511 Bool_t* foundTracks = new Bool_t[nMCPart]; // to prevent double counting
512 for (Int_t i=0; i<nMCPart; i++)
513 foundTracks[i] = kFALSE;
a9017e49 514
2fa65f52 515 for (Int_t i=0; i<inputCount; ++i)
516 {
517 Float_t eta = etaArr[i];
518 Int_t label = labelArr[i];
a9017e49 519
2fa65f52 520 Int_t particleWeight = 1;
521
522 // in case of systematic study, weight according to the change of the pt spectrum
523 if (fPtSpectrum)
524 {
525 TParticle* mother = 0;
526
527 // preserve label for later
528 Int_t labelCopy = label;
529 if (labelCopy >= 0)
530 labelCopy = AliPWG0Helper::FindPrimaryMotherLabel(stack, labelCopy);
531 if (labelCopy >= 0)
532 mother = stack->Particle(labelCopy);
533
534 // in case of pt study we do not count particles w/o label, because they cannot be scaled
535 if (!mother)
536 continue;
537
538 // it cannot be just multiplied because we cannot count "half of a particle"
539 // instead a random generator decides if the particle is counted twice (if value > 1)
540 // or not (if value < 0)
541 Int_t bin = fPtSpectrum->FindBin(mother->Pt());
542 if (bin > 0 && bin <= fPtSpectrum->GetNbinsX())
543 {
544 Float_t factor = fPtSpectrum->GetBinContent(bin);
545 if (factor > 0)
546 {
547 Float_t random = gRandom->Uniform();
548 if (factor > 1 && random < factor - 1)
549 {
550 particleWeight = 2;
551 }
552 else if (factor < 1 && random < 1 - factor)
553 particleWeight = 0;
554 }
555 }
556 }
557
558 //Printf("ESD weight is: %d", particleWeight);
559
560 if (TMath::Abs(eta) < 0.5)
561 nESDTracks05 += particleWeight;
a9017e49 562
2fa65f52 563 if (TMath::Abs(eta) < 0.9)
564 nESDTracks09 += particleWeight;
a9017e49 565
2fa65f52 566 if (TMath::Abs(eta) < 1.5)
567 nESDTracks15 += particleWeight;
a9017e49 568
2fa65f52 569 if (TMath::Abs(eta) < 2.0)
570 nESDTracks20 += particleWeight;
a9017e49 571
a9017e49 572
2fa65f52 573 if (fParticleCorrection[0] || fParticleSpecies)
574 {
575 Int_t motherLabel = -1;
576 TParticle* mother = 0;
577
578 // find mother
579 if (label >= 0)
580 motherLabel = AliPWG0Helper::FindPrimaryMotherLabel(stack, label);
581 if (motherLabel >= 0)
582 mother = stack->Particle(motherLabel);
583
584 if (!mother)
585 {
586 // count tracks that did not have a label
587 if (TMath::Abs(eta) < etaRange)
588 nESDTracksSpecies[4]++;
589 continue;
590 }
591
592 // get particle type (pion, proton, kaon, other)
593 Int_t id = -1;
594 switch (TMath::Abs(mother->GetPdgCode()))
595 {
596 case 211: id = 0; break;
597 case 321: id = 1; break;
598 case 2212: id = 2; break;
599 default: id = 3; break;
600 }
601
602 // double counting is ok for particle ratio study
603 if (TMath::Abs(eta) < etaRange)
604 nESDTracksSpecies[id]++;
605
606 // double counting is not ok for efficiency study
607
608 // check if we already counted this particle, this way distinguishes double counted particles (bug/artefact in tracking) or double counted primaries due to secondaries (physics)
609 if (foundTracks[label])
610 {
611 if (TMath::Abs(eta) < etaRange)
612 nESDTracksSpecies[6]++;
613 continue;
614 }
615 foundTracks[label] = kTRUE;
616
617 // particle (primary) already counted?
618 if (foundPrimaries[motherLabel])
619 {
620 if (TMath::Abs(eta) < etaRange)
621 nESDTracksSpecies[5]++;
622 continue;
623 }
624 foundPrimaries[motherLabel] = kTRUE;
625
626 if (fParticleCorrection[id])
627 fParticleCorrection[id]->GetTrackCorrection()->FillMeas(vtxMC[2], mother->Eta(), mother->Pt());
628 }
629 }
630
631 delete[] foundTracks;
632 delete[] foundPrimaries;
a9017e49 633
2fa65f52 634 if ((Int_t) nMCTracks20 == 0 && nESDTracks20 > 3)
635 printf("WARNING: Event has %d generated and %d reconstructed...\n", nMCTracks20, nESDTracks20);
a9017e49 636
2fa65f52 637 // fill response matrix using vtxMC (best guess)
638 fMultiplicity->FillCorrection(vtxMC[2], nMCTracks05, nMCTracks09, nMCTracks15, nMCTracks20, nMCTracksAll, nESDTracks05, nESDTracks09, nESDTracks15, nESDTracks20);
a9017e49 639
2fa65f52 640 fMultiplicity->FillMeasured(vtx[2], nESDTracks05, nESDTracks09, nESDTracks15, nESDTracks20);
641
642 if (fParticleSpecies)
643 fParticleSpecies->Fill(vtxMC[2], nMCTracksSpecies[0], nMCTracksSpecies[1], nMCTracksSpecies[2], nMCTracksSpecies[3], nESDTracksSpecies[0], nESDTracksSpecies[1], nESDTracksSpecies[2], nESDTracksSpecies[3], nESDTracksSpecies[4], nESDTracksSpecies[5], nESDTracksSpecies[6]);
644 }
645 }
646 }
a9017e49 647
2fa65f52 648 delete etaArr;
649 delete labelArr;
a9017e49 650}
651
652void AliMultiplicityTask::Terminate(Option_t *)
653{
654 // The Terminate() function is the last function to be called during
655 // a query. It always runs on the client, it can be used to present
656 // the results graphically or save the results to file.
657
658 fOutput = dynamic_cast<TList*> (GetOutputData(0));
659 if (!fOutput) {
660 Printf("ERROR: fOutput not available");
661 return;
662 }
663
664 fMultiplicity = dynamic_cast<AliMultiplicityCorrection*> (fOutput->FindObject("Multiplicity"));
665 for (Int_t i = 0; i < 4; ++i)
666 fParticleCorrection[i] = dynamic_cast<AliCorrection*> (fOutput->FindObject(Form("correction_%d", i)));
667 fParticleSpecies = dynamic_cast<TNtuple*> (fOutput->FindObject("fParticleSpecies"));
668
669 if (!fMultiplicity)
670 {
671 AliDebug(AliLog::kError, Form("ERROR: Histograms not available %p", (void*) fMultiplicity));
672 return;
673 }
674
675 TFile* file = TFile::Open("multiplicityMC.root", "RECREATE");
676
677 fMultiplicity->SaveHistograms();
678 for (Int_t i = 0; i < 4; ++i)
679 if (fParticleCorrection[i])
680 fParticleCorrection[i]->SaveHistograms();
681 if (fParticleSpecies)
682 fParticleSpecies->Write();
683
684 TObjString option(fOption);
685 option.Write();
686
687 file->Close();
688
689 Printf("Writting result to multiplicityMC.root");
690}