]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG0/multiplicity/AliMultiplicityTask.cxx
adding offline triggers
[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>
69b09e3b 11#include <TH1D.h>
a9017e49 12#include <TH2F.h>
13#include <TH3F.h>
14#include <TParticle.h>
15#include <TRandom.h>
16#include <TNtuple.h>
17#include <TObjString.h>
18#include <TF1.h>
19
20#include <AliLog.h>
21#include <AliESDVertex.h>
22#include <AliESDEvent.h>
23#include <AliStack.h>
24#include <AliHeader.h>
25#include <AliGenEventHeader.h>
26#include <AliMultiplicity.h>
27#include <AliAnalysisManager.h>
28#include <AliMCEventHandler.h>
29#include <AliMCEvent.h>
30#include <AliESDInputHandler.h>
31
745d6088 32#include "AliESDtrackCuts.h"
a9017e49 33#include "AliPWG0Helper.h"
0a0f4adb 34#include "multiplicity/AliMultiplicityCorrection.h"
a9017e49 35#include "AliCorrection.h"
36#include "AliCorrectionMatrix3D.h"
37
a9017e49 38ClassImp(AliMultiplicityTask)
39
40AliMultiplicityTask::AliMultiplicityTask(const char* opt) :
41 AliAnalysisTask("AliMultiplicityTask", ""),
42 fESD(0),
43 fOption(opt),
745d6088 44 fAnalysisMode(AliPWG0Helper::kSPD),
a2cdb42c 45 fTrigger(AliPWG0Helper::kMB1),
69b09e3b 46 fDeltaPhiCut(-1),
2fa65f52 47 fReadMC(kFALSE),
f3eb27f6 48 fUseMCVertex(kFALSE),
a9017e49 49 fMultiplicity(0),
50 fEsdTrackCuts(0),
51 fSystSkipParticles(kFALSE),
52 fSelectProcessType(0),
53 fParticleSpecies(0),
69b09e3b 54 fdNdpT(0),
a9017e49 55 fPtSpectrum(0),
56 fOutput(0)
57{
58 //
59 // Constructor. Initialization of pointers
60 //
61
69b09e3b 62 for (Int_t i = 0; i<8; i++)
a9017e49 63 fParticleCorrection[i] = 0;
64
65 // Define input and output slots here
66 DefineInput(0, TChain::Class());
67 DefineOutput(0, TList::Class());
68}
69
70AliMultiplicityTask::~AliMultiplicityTask()
71{
72 //
73 // Destructor
74 //
75
76 // histograms are in the output list and deleted when the output
77 // list is deleted by the TSelector dtor
78
79 if (fOutput) {
80 delete fOutput;
81 fOutput = 0;
82 }
83}
84
85//________________________________________________________________________
86void AliMultiplicityTask::ConnectInputData(Option_t *)
87{
88 // Connect ESD
89 // Called once
90
2fa65f52 91 Printf("AliMultiplicityTask::ConnectInputData called");
92
a9017e49 93 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
94 if (!tree) {
95 Printf("ERROR: Could not read tree from input slot 0");
96 } else {
97 // Disable all branches and enable only the needed ones
69b09e3b 98 /*
f3eb27f6 99 tree->SetBranchStatus("*", 0);
2fa65f52 100
f3eb27f6 101 tree->SetBranchStatus("AliESDHeader*", 1);
102 tree->SetBranchStatus("*Vertex*", 1);
a9017e49 103
f3eb27f6 104 if (fAnalysisMode == AliPWG0Helper::kSPD) {
105 tree->SetBranchStatus("AliMultiplicity*", 1);
106 }
a9017e49 107
745d6088 108 if (fAnalysisMode == AliPWG0Helper::kTPC || fAnalysisMode == AliPWG0Helper::kTPCITS) {
f3eb27f6 109 //AliESDtrackCuts::EnableNeededBranches(tree);
110 tree->SetBranchStatus("Tracks*", 1);
2fa65f52 111 }
69b09e3b 112 */
a9017e49 113
a9017e49 114 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
115
116 if (!esdH) {
117 Printf("ERROR: Could not get ESDInputHandler");
118 } else
119 fESD = esdH->GetEvent();
120 }
f3eb27f6 121
122 // disable info messages of AliMCEvent (per event)
123 AliLog::SetClassDebugLevel("AliMCEvent", AliLog::kWarning - AliLog::kDebug + 1);
a9017e49 124}
125
126void AliMultiplicityTask::CreateOutputObjects()
127{
128 // create result objects and add to output list
129
130 fOutput = new TList;
131 fOutput->SetOwner();
132
133 fMultiplicity = new AliMultiplicityCorrection("Multiplicity", "Multiplicity");
134 fOutput->Add(fMultiplicity);
69b09e3b 135
136 fdNdpT = new TH1F("fdNdpT", "fdNdpT", 1000, 0, 10);
137 fdNdpT->Sumw2();
138 fOutput->Add(fdNdpT);
a9017e49 139
140 if (fOption.Contains("skip-particles"))
141 {
142 fSystSkipParticles = kTRUE;
143 AliInfo("WARNING: Systematic study enabled. Particles will be skipped.");
144 }
145
146 if (fOption.Contains("particle-efficiency"))
69b09e3b 147 for (Int_t i = 0; i<8; i++)
a9017e49 148 {
149 fParticleCorrection[i] = new AliCorrection(Form("correction_%d", i), Form("correction_%d", i));
150 fOutput->Add(fParticleCorrection[i]);
151 }
152
153 if (fOption.Contains("only-process-type-nd"))
154 fSelectProcessType = 1;
155
156 if (fOption.Contains("only-process-type-sd"))
157 fSelectProcessType = 2;
158
159 if (fOption.Contains("only-process-type-dd"))
160 fSelectProcessType = 3;
161
162 if (fSelectProcessType != 0)
163 AliInfo(Form("WARNING: Systematic study enabled. Only considering process type %d", fSelectProcessType));
164
165 if (fOption.Contains("pt-spectrum-hist"))
166 {
167 TFile* file = TFile::Open("ptspectrum_fit.root");
168 if (file)
169 {
170 TString subStr(fOption(fOption.Index("pt-spectrum")+17, 3));
171 TString histName(Form("ptspectrum_%s", subStr.Data()));
172 AliInfo(Form("Pt-Spectrum modification. Using %s.", histName.Data()));
69b09e3b 173 fPtSpectrum = (TH1D*) file->Get(histName);
174 if (!fPtSpectrum)
175 AliError("Histogram not found");
a9017e49 176 }
177 else
178 AliError("Could not open ptspectrum_fit.root. Pt Spectrum study could not be enabled.");
a9017e49 179 }
180
181 if (fOption.Contains("pt-spectrum-func"))
182 {
183 if (fPtSpectrum)
184 {
69b09e3b 185 Printf("Using function for systematic p_t study");
a9017e49 186 }
187 else
188 {
69b09e3b 189 Printf("ERROR: Could not find function for systematic p_t study");
190 fPtSpectrum = new TH1D("fPtSpectrum", "fPtSpectrum", 1, 0, 100);
a9017e49 191 fPtSpectrum->SetBinContent(1, 1);
192 }
a9017e49 193 }
194
69b09e3b 195 if (fPtSpectrum)
196 Printf("WARNING: Systematic study enabled. Pt spectrum will be modified");
197
a9017e49 198 if (fOption.Contains("particle-species")) {
199 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");
200 fOutput->Add(fParticleSpecies);
201 }
202
203 // TODO set seed for random generator
204}
205
206void AliMultiplicityTask::Exec(Option_t*)
207{
208 // process the event
209
210 // Check prerequisites
211 if (!fESD)
212 {
745d6088 213 AliDebug(AliLog::kError, "ESD not available");
a9017e49 214 return;
215 }
216
69b09e3b 217 Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD, fTrigger);
a9017e49 218
f3eb27f6 219 const AliESDVertex* vtxESD = AliPWG0Helper::GetVertex(fESD, fAnalysisMode);
220 Bool_t eventVertex = (vtxESD != 0);
a9017e49 221
a9017e49 222 Double_t vtx[3];
f3eb27f6 223 if (vtxESD)
224 vtxESD->GetXYZ(vtx);
a9017e49 225
2fa65f52 226 // post the data already here
227 PostData(0, fOutput);
69b09e3b 228
a9017e49 229 //const Float_t kPtCut = 0.3;
230
2fa65f52 231 // create list of (label, eta) tuples
232 Int_t inputCount = 0;
233 Int_t* labelArr = 0;
234 Float_t* etaArr = 0;
745d6088 235 if (fAnalysisMode == AliPWG0Helper::kSPD)
a9017e49 236 {
2fa65f52 237 // get tracklets
238 const AliMultiplicity* mult = fESD->GetMultiplicity();
239 if (!mult)
a9017e49 240 {
2fa65f52 241 AliDebug(AliLog::kError, "AliMultiplicity not available");
242 return;
a9017e49 243 }
244
2fa65f52 245 labelArr = new Int_t[mult->GetNumberOfTracklets()];
246 etaArr = new Float_t[mult->GetNumberOfTracklets()];
247
248 // get multiplicity from ITS tracklets
249 for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
a9017e49 250 {
2fa65f52 251 //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
a9017e49 252
69b09e3b 253 Float_t deltaPhi = mult->GetDeltaPhi(i);
254
255 if (fDeltaPhiCut > 0 && TMath::Abs(deltaPhi) > fDeltaPhiCut)
2fa65f52 256 continue;
a9017e49 257
2fa65f52 258 etaArr[inputCount] = mult->GetEta(i);
69b09e3b 259 if (mult->GetLabel(i, 0) == mult->GetLabel(i, 1))
260 {
261 labelArr[inputCount] = mult->GetLabel(i, 0);
262 }
263 else
264 labelArr[inputCount] = -1;
265
2fa65f52 266 ++inputCount;
267 }
268 }
745d6088 269 else if (fAnalysisMode == AliPWG0Helper::kTPC || fAnalysisMode == AliPWG0Helper::kTPCITS)
2fa65f52 270 {
271 if (!fEsdTrackCuts)
272 {
273 AliDebug(AliLog::kError, "fESDTrackCuts not available");
274 return;
275 }
a9017e49 276
69b09e3b 277 if (vtxESD)
a9017e49 278 {
69b09e3b 279 // get multiplicity from ESD tracks
280 TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD, (fAnalysisMode == AliPWG0Helper::kTPC));
281 Int_t nGoodTracks = list->GetEntries();
282
283 labelArr = new Int_t[nGoodTracks];
284 etaArr = new Float_t[nGoodTracks];
285
286 // loop over esd tracks
287 for (Int_t i=0; i<nGoodTracks; i++)
a9017e49 288 {
69b09e3b 289 AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
290 if (!esdTrack)
291 {
292 AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
293 continue;
294 }
295
296 etaArr[inputCount] = esdTrack->Eta();
297 labelArr[inputCount] = TMath::Abs(esdTrack->GetLabel());
298 ++inputCount;
a9017e49 299 }
69b09e3b 300
301 delete list;
a9017e49 302 }
2fa65f52 303 }
a9017e49 304
2fa65f52 305 // eta range for nMCTracksSpecies, nESDTracksSpecies
306 Float_t etaRange = -1;
307 switch (fAnalysisMode) {
773f84dc 308 case AliPWG0Helper::kInvalid: break;
745d6088 309 case AliPWG0Helper::kTPC:
310 case AliPWG0Helper::kTPCITS:
69b09e3b 311 etaRange = 1.0; break;
312 case AliPWG0Helper::kSPD: etaRange = 1.0; break;
2fa65f52 313 }
a9017e49 314
2fa65f52 315 if (!fReadMC) // Processing of ESD information
316 {
317 if (eventTriggered && eventVertex)
318 {
319 Int_t nESDTracks05 = 0;
69b09e3b 320 Int_t nESDTracks10 = 0;
2fa65f52 321 Int_t nESDTracks15 = 0;
322 Int_t nESDTracks20 = 0;
a9017e49 323
2fa65f52 324 for (Int_t i=0; i<inputCount; ++i)
325 {
326 Float_t eta = etaArr[i];
a9017e49 327
2fa65f52 328 if (TMath::Abs(eta) < 0.5)
329 nESDTracks05++;
a9017e49 330
69b09e3b 331 if (TMath::Abs(eta) < 1.0)
332 nESDTracks10++;
a9017e49 333
2fa65f52 334 if (TMath::Abs(eta) < 1.5)
335 nESDTracks15++;
336
337 if (TMath::Abs(eta) < 2.0)
338 nESDTracks20++;
a9017e49 339 }
2fa65f52 340
69b09e3b 341 fMultiplicity->FillMeasured(vtx[2], nESDTracks05, nESDTracks10, nESDTracks15, nESDTracks20);
2fa65f52 342 }
343 }
344 else if (fReadMC) // Processing of MC information
345 {
346 AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
347 if (!eventHandler) {
348 Printf("ERROR: Could not retrieve MC event handler");
349 return;
a9017e49 350 }
a9017e49 351
2fa65f52 352 AliMCEvent* mcEvent = eventHandler->MCEvent();
353 if (!mcEvent) {
354 Printf("ERROR: Could not retrieve MC event");
355 return;
356 }
a9017e49 357
2fa65f52 358 AliStack* stack = mcEvent->Stack();
359 if (!stack)
360 {
361 AliDebug(AliLog::kError, "Stack not available");
362 return;
363 }
69b09e3b 364
2fa65f52 365 AliHeader* header = mcEvent->Header();
366 if (!header)
367 {
368 AliDebug(AliLog::kError, "Header not available");
369 return;
370 }
a9017e49 371
f3eb27f6 372 if (fUseMCVertex)
373 {
374 Printf("WARNING: Replacing vertex by MC vertex. This is for systematical checks only.");
375 // get the MC vertex
376 AliGenEventHeader* genHeader = header->GenEventHeader();
377 TArrayF vtxMC(3);
378 genHeader->PrimaryVertex(vtxMC);
379
380 vtx[2] = vtxMC[2];
381 }
69b09e3b 382
383 // get process information
384 AliPWG0Helper::MCProcessType processType = AliPWG0Helper::GetEventProcessType(header);
f3eb27f6 385
2fa65f52 386 Bool_t processEvent = kTRUE;
387 if (fSelectProcessType > 0)
388 {
2fa65f52 389 processEvent = kFALSE;
a9017e49 390
2fa65f52 391 // non diffractive
69b09e3b 392 if (fSelectProcessType == 1 && processType == AliPWG0Helper::kND)
2fa65f52 393 processEvent = kTRUE;
a9017e49 394
2fa65f52 395 // single diffractive
69b09e3b 396 if (fSelectProcessType == 2 && processType == AliPWG0Helper::kSD)
2fa65f52 397 processEvent = kTRUE;
a9017e49 398
2fa65f52 399 // double diffractive
69b09e3b 400 if (fSelectProcessType == 3 && processType == AliPWG0Helper::kDD)
2fa65f52 401 processEvent = kTRUE;
a9017e49 402
2fa65f52 403 if (!processEvent)
69b09e3b 404 Printf("Skipping this event, because it is not of the requested process type (%d)", (Int_t) processType);
2fa65f52 405 }
a9017e49 406
2fa65f52 407 if (processEvent)
408 {
409 // get the MC vertex
410 AliGenEventHeader* genHeader = header->GenEventHeader();
411 TArrayF vtxMC(3);
412 genHeader->PrimaryVertex(vtxMC);
413
414 // get number of tracks from MC
415 // loop over mc particles
416 Int_t nPrim = stack->GetNprimary();
417 Int_t nMCPart = stack->GetNtrack();
418
419 // tracks in different eta ranges
420 Int_t nMCTracks05 = 0;
69b09e3b 421 Int_t nMCTracks10 = 0;
2fa65f52 422 Int_t nMCTracks15 = 0;
423 Int_t nMCTracks20 = 0;
424 Int_t nMCTracksAll = 0;
425
426 // tracks per particle species, in |eta| < 2 (systematic study)
427 Int_t nMCTracksSpecies[4]; // (pi, K, p, other)
428 for (Int_t i = 0; i<4; ++i)
429 nMCTracksSpecies[i] = 0;
430
431 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
432 {
433 AliDebug(AliLog::kDebug+1, Form("MC Loop: Processing particle %d.", iMc));
a9017e49 434
2fa65f52 435 TParticle* particle = stack->Particle(iMc);
a9017e49 436
2fa65f52 437 if (!particle)
438 {
439 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (mc loop).", iMc));
440 continue;
441 }
a9017e49 442
2fa65f52 443 Bool_t debug = kFALSE;
444 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim, debug) == kFALSE)
445 {
446 //printf("%d) DROPPED ", iMC);
447 //particle->Print();
448 continue;
449 }
a9017e49 450
2fa65f52 451 //printf("%d) OK ", iMC);
452 //particle->Print();
a9017e49 453
2fa65f52 454 //if (particle->Pt() < kPtCut)
455 // continue;
a9017e49 456
2fa65f52 457 Int_t particleWeight = 1;
a9017e49 458
2fa65f52 459 Float_t pt = particle->Pt();
a9017e49 460
2fa65f52 461 // in case of systematic study, weight according to the change of the pt spectrum
462 // it cannot be just multiplied because we cannot count "half of a particle"
463 // instead a random generator decides if the particle is counted twice (if value > 1)
464 // or not (if value < 0)
465 if (fPtSpectrum)
a9017e49 466 {
2fa65f52 467 Int_t bin = fPtSpectrum->FindBin(pt);
468 if (bin > 0 && bin <= fPtSpectrum->GetNbinsX())
a9017e49 469 {
2fa65f52 470 Float_t factor = fPtSpectrum->GetBinContent(bin);
471 if (factor > 0)
472 {
473 Float_t random = gRandom->Uniform();
474 if (factor > 1 && random < factor - 1)
475 {
476 particleWeight = 2;
477 }
478 else if (factor < 1 && random < 1 - factor)
479 particleWeight = 0;
480 }
a9017e49 481 }
a9017e49 482 }
a9017e49 483
2fa65f52 484 //Printf("MC weight is: %d", particleWeight);
a9017e49 485
2fa65f52 486 if (TMath::Abs(particle->Eta()) < 0.5)
487 nMCTracks05 += particleWeight;
a9017e49 488
69b09e3b 489 if (TMath::Abs(particle->Eta()) < 1.0)
490 nMCTracks10 += particleWeight;
a9017e49 491
2fa65f52 492 if (TMath::Abs(particle->Eta()) < 1.5)
493 nMCTracks15 += particleWeight;
a9017e49 494
2fa65f52 495 if (TMath::Abs(particle->Eta()) < 2.0)
496 nMCTracks20 += particleWeight;
a9017e49 497
2fa65f52 498 nMCTracksAll += particleWeight;
69b09e3b 499
500 if (particle->Pt() > 0 && TMath::Abs(particle->Eta()) < 1.0)
501 fdNdpT->Fill(particle->Pt(), 1.0 / particle->Pt());
a9017e49 502
2fa65f52 503 if (fParticleCorrection[0] || fParticleSpecies)
504 {
505 Int_t id = -1;
506 switch (TMath::Abs(particle->GetPdgCode()))
507 {
508 case 211: id = 0; break;
509 case 321: id = 1; break;
510 case 2212: id = 2; break;
511 default: id = 3; break;
512 }
a9017e49 513
2fa65f52 514 if (TMath::Abs(particle->Eta()) < etaRange)
515 nMCTracksSpecies[id]++;
516
517 if (fParticleCorrection[id])
518 fParticleCorrection[id]->GetTrackCorrection()->FillGene(vtxMC[2], particle->Eta(), particle->Pt());
519 }
520 } // end of mc particle
a9017e49 521
69b09e3b 522 fMultiplicity->FillGenerated(vtxMC[2], eventTriggered, eventVertex, processType, (Int_t) nMCTracks05, (Int_t) nMCTracks10, (Int_t) nMCTracks15, (Int_t) nMCTracks20, (Int_t) nMCTracksAll);
a9017e49 523
2fa65f52 524 if (eventTriggered && eventVertex)
a9017e49 525 {
2fa65f52 526 Int_t nESDTracks05 = 0;
69b09e3b 527 Int_t nESDTracks10 = 0;
2fa65f52 528 Int_t nESDTracks15 = 0;
529 Int_t nESDTracks20 = 0;
a9017e49 530
2fa65f52 531 // tracks per particle species, in |eta| < 2 (systematic study)
532 Int_t nESDTracksSpecies[7]; // (pi, K, p, other, nolabel, doublecount_prim, doublecount_all)
533 for (Int_t i = 0; i<7; ++i)
534 nESDTracksSpecies[i] = 0;
a9017e49 535
2fa65f52 536 Bool_t* foundPrimaries = new Bool_t[nPrim]; // to prevent double counting
537 for (Int_t i=0; i<nPrim; i++)
538 foundPrimaries[i] = kFALSE;
a9017e49 539
69b09e3b 540 Bool_t* foundPrimaries2 = new Bool_t[nPrim]; // to prevent double counting
541 for (Int_t i=0; i<nPrim; i++)
542 foundPrimaries2[i] = kFALSE;
543
2fa65f52 544 Bool_t* foundTracks = new Bool_t[nMCPart]; // to prevent double counting
545 for (Int_t i=0; i<nMCPart; i++)
546 foundTracks[i] = kFALSE;
a9017e49 547
2fa65f52 548 for (Int_t i=0; i<inputCount; ++i)
549 {
550 Float_t eta = etaArr[i];
551 Int_t label = labelArr[i];
a9017e49 552
2fa65f52 553 Int_t particleWeight = 1;
554
69b09e3b 555 // systematic study: 5% lower efficiency
556 if (fSystSkipParticles && (gRandom->Uniform() < 0.05))
557 continue;
558
2fa65f52 559 // in case of systematic study, weight according to the change of the pt spectrum
560 if (fPtSpectrum)
561 {
562 TParticle* mother = 0;
563
564 // preserve label for later
565 Int_t labelCopy = label;
566 if (labelCopy >= 0)
567 labelCopy = AliPWG0Helper::FindPrimaryMotherLabel(stack, labelCopy);
568 if (labelCopy >= 0)
569 mother = stack->Particle(labelCopy);
570
571 // in case of pt study we do not count particles w/o label, because they cannot be scaled
572 if (!mother)
573 continue;
574
575 // it cannot be just multiplied because we cannot count "half of a particle"
576 // instead a random generator decides if the particle is counted twice (if value > 1)
577 // or not (if value < 0)
578 Int_t bin = fPtSpectrum->FindBin(mother->Pt());
579 if (bin > 0 && bin <= fPtSpectrum->GetNbinsX())
580 {
581 Float_t factor = fPtSpectrum->GetBinContent(bin);
582 if (factor > 0)
583 {
584 Float_t random = gRandom->Uniform();
585 if (factor > 1 && random < factor - 1)
586 {
587 particleWeight = 2;
588 }
589 else if (factor < 1 && random < 1 - factor)
590 particleWeight = 0;
591 }
592 }
593 }
594
595 //Printf("ESD weight is: %d", particleWeight);
596
597 if (TMath::Abs(eta) < 0.5)
598 nESDTracks05 += particleWeight;
a9017e49 599
69b09e3b 600 if (TMath::Abs(eta) < 1.0)
601 nESDTracks10 += particleWeight;
a9017e49 602
2fa65f52 603 if (TMath::Abs(eta) < 1.5)
604 nESDTracks15 += particleWeight;
a9017e49 605
2fa65f52 606 if (TMath::Abs(eta) < 2.0)
607 nESDTracks20 += particleWeight;
a9017e49 608
a9017e49 609
69b09e3b 610 if (fParticleSpecies)
2fa65f52 611 {
612 Int_t motherLabel = -1;
613 TParticle* mother = 0;
614
615 // find mother
616 if (label >= 0)
617 motherLabel = AliPWG0Helper::FindPrimaryMotherLabel(stack, label);
618 if (motherLabel >= 0)
619 mother = stack->Particle(motherLabel);
620
621 if (!mother)
622 {
623 // count tracks that did not have a label
624 if (TMath::Abs(eta) < etaRange)
625 nESDTracksSpecies[4]++;
2fa65f52 626 }
69b09e3b 627 else
2fa65f52 628 {
69b09e3b 629 // get particle type (pion, proton, kaon, other) of mother
630 Int_t idMother = -1;
631 switch (TMath::Abs(mother->GetPdgCode()))
632 {
633 case 211: idMother = 0; break;
634 case 321: idMother = 1; break;
635 case 2212: idMother = 2; break;
636 default: idMother = 3; break;
637 }
638
639 // double counting is ok for particle ratio study
640 if (TMath::Abs(eta) < etaRange)
641 nESDTracksSpecies[idMother]++;
642
643 // double counting is not ok for efficiency study
644
645 // 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)
646 if (foundTracks[label])
647 {
648 if (TMath::Abs(eta) < etaRange)
649 nESDTracksSpecies[6]++;
650 }
651 else
652 {
653 foundTracks[label] = kTRUE;
654
655 // particle (primary) already counted?
656 if (foundPrimaries[motherLabel])
657 {
658 if (TMath::Abs(eta) < etaRange)
659 nESDTracksSpecies[5]++;
660 }
661 else
662 foundPrimaries[motherLabel] = kTRUE;
663 }
2fa65f52 664 }
69b09e3b 665 }
666
667 if (fParticleCorrection[0])
668 {
669 if (label >= 0 && stack->IsPhysicalPrimary(label))
670 {
671 TParticle* particle = stack->Particle(label);
2fa65f52 672
69b09e3b 673 // get particle type (pion, proton, kaon, other)
674 Int_t id = -1;
675 switch (TMath::Abs(particle->GetPdgCode()))
676 {
677 case 211: id = 0; break;
678 case 321: id = 1; break;
679 case 2212: id = 2; break;
680 default: id = 3; break;
681 }
2fa65f52 682
69b09e3b 683 // todo check if values are not completely off??
2fa65f52 684
69b09e3b 685 // particle (primary) already counted?
686 if (!foundPrimaries2[label])
687 {
688 foundPrimaries2[label] = kTRUE;
689 fParticleCorrection[id]->GetTrackCorrection()->FillMeas(vtxMC[2], particle->Eta(), particle->Pt());
690 }
691 }
692 }
693 }
694
695 if (fParticleCorrection[0])
696 {
697 // if the particle decays/stops before this radius we do not see it
698 // 8cm larger than SPD layer 2
699 // 123cm TPC radius where a track has about 50 clusters (cut limit)
700 const Float_t endRadius = (fAnalysisMode == AliPWG0Helper::kSPD) ? 8. : 123;
701
702 // loop over all primaries that have not been found
703 for (Int_t i=0; i<nPrim; i++)
704 {
705 // already found
706 if (foundPrimaries2[i])
707 continue;
708
709 TParticle* particle = 0;
710 TClonesArray* trackrefs = 0;
711 mcEvent->GetParticleAndTR(i, particle, trackrefs);
712
713 // true primary and charged
714 if (!AliPWG0Helper::IsPrimaryCharged(particle, nPrim))
715 continue;
716
717 //skip particles with larger |eta| than 3, to keep the log clean, is anyway not included in correction map
718 if (TMath::Abs(particle->Eta()) > 3)
719 continue;
720
721 // skipping checking of process type of daughter: Neither kPBrem, kPDeltaRay nor kPCerenkov should appear in the event generation
722
723 // get particle type (pion, proton, kaon, other)
724 Int_t id = -1;
725 switch (TMath::Abs(particle->GetPdgCode()))
2fa65f52 726 {
69b09e3b 727 case 211: id = 4; break;
728 case 321: id = 5; break;
729 case 2212: id = 6; break;
730 default: id = 7; break;
731 }
732
733 if (!fParticleCorrection[id])
734 continue;
735
736 // get last track reference
737 AliTrackReference* trackref = dynamic_cast<AliTrackReference*> (trackrefs->Last());
738
739 if (!trackref)
740 {
741 Printf("ERROR: Could not get trackref of %d (count %d)", i, trackrefs->GetEntries());
742 particle->Print();
2fa65f52 743 continue;
744 }
69b09e3b 745
746 // particle in tracking volume long enough...
747 if (trackref->R() > endRadius)
748 continue;
749
750 if (particle->GetLastDaughter() >= 0)
2fa65f52 751 {
69b09e3b 752 Int_t uID = stack->Particle(particle->GetLastDaughter())->GetUniqueID();
753 //if (uID != kPBrem && uID != kPDeltaRay && uID < kPCerenkov)
754 if (uID == kPDecay)
755 {
756 // decayed
757
758 Printf("Particle %d (%s) decayed at %f, daugher uniqueID: %d:", i, particle->GetName(), trackref->R(), uID);
759 particle->Print();
760 Printf("Daughers:");
761 for (Int_t d = particle->GetFirstDaughter(); d <= particle->GetLastDaughter(); d++)
762 stack->Particle(d)->Print();
763 Printf("");
764
765 fParticleCorrection[id]->GetTrackCorrection()->FillGene(vtxMC[2], particle->Eta(), particle->Pt());
766 continue;
767 }
768 }
769
770 if (trackref->DetectorId() == -1)
771 {
772 // stopped
773 Printf("Particle %d stopped at %f:", i, trackref->R());
774 particle->Print();
775 Printf("");
776
777 fParticleCorrection[id]->GetTrackCorrection()->FillMeas(vtxMC[2], particle->Eta(), particle->Pt());
2fa65f52 778 continue;
779 }
69b09e3b 780
781 Printf("Particle %d simply not tracked", i);
782 particle->Print();
783 Printf("");
2fa65f52 784 }
785 }
69b09e3b 786
2fa65f52 787 delete[] foundTracks;
788 delete[] foundPrimaries;
69b09e3b 789 delete[] foundPrimaries2;
a9017e49 790
69b09e3b 791 if ((Int_t) nMCTracks15 > 10 && nESDTracks15 <= 3)
f3eb27f6 792 {
793 TTree* tree = dynamic_cast<TTree*> (GetInputData(0));
69b09e3b 794 printf("WARNING: Event %lld %s (vtx-z = %f, recon: %f, contrib: %d, res: %f) has %d generated and %d reconstructed...\n", tree->GetReadEntry(), tree->GetCurrentFile()->GetName(), vtxMC[2], vtx[2], vtxESD->GetNContributors(), vtxESD->GetZRes(), nMCTracks15, nESDTracks15);
f3eb27f6 795 }
a9017e49 796
2fa65f52 797 // fill response matrix using vtxMC (best guess)
69b09e3b 798 fMultiplicity->FillCorrection(vtxMC[2], nMCTracks05, nMCTracks10, nMCTracks15, nMCTracks20, nMCTracksAll, nESDTracks05, nESDTracks10, nESDTracks15, nESDTracks20);
a9017e49 799
69b09e3b 800 fMultiplicity->FillMeasured(vtx[2], nESDTracks05, nESDTracks10, nESDTracks15, nESDTracks20);
2fa65f52 801
802 if (fParticleSpecies)
803 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]);
804 }
805 }
806 }
a9017e49 807
69b09e3b 808 if (etaArr)
809 delete[] etaArr;
810 if (labelArr)
811 delete[] labelArr;
a9017e49 812}
813
814void AliMultiplicityTask::Terminate(Option_t *)
815{
816 // The Terminate() function is the last function to be called during
817 // a query. It always runs on the client, it can be used to present
818 // the results graphically or save the results to file.
819
820 fOutput = dynamic_cast<TList*> (GetOutputData(0));
821 if (!fOutput) {
822 Printf("ERROR: fOutput not available");
823 return;
824 }
825
826 fMultiplicity = dynamic_cast<AliMultiplicityCorrection*> (fOutput->FindObject("Multiplicity"));
69b09e3b 827 for (Int_t i = 0; i < 8; ++i)
a9017e49 828 fParticleCorrection[i] = dynamic_cast<AliCorrection*> (fOutput->FindObject(Form("correction_%d", i)));
829 fParticleSpecies = dynamic_cast<TNtuple*> (fOutput->FindObject("fParticleSpecies"));
69b09e3b 830
831 fdNdpT = dynamic_cast<TH1*> (fOutput->FindObject("fdNdpT"));
a9017e49 832
833 if (!fMultiplicity)
834 {
835 AliDebug(AliLog::kError, Form("ERROR: Histograms not available %p", (void*) fMultiplicity));
836 return;
837 }
838
dca331bb 839 TFile* file = TFile::Open("multiplicity.root", "RECREATE");
a9017e49 840
841 fMultiplicity->SaveHistograms();
69b09e3b 842 for (Int_t i = 0; i < 8; ++i)
a9017e49 843 if (fParticleCorrection[i])
844 fParticleCorrection[i]->SaveHistograms();
845 if (fParticleSpecies)
846 fParticleSpecies->Write();
69b09e3b 847 if (fdNdpT)
848 fdNdpT->Write();
a9017e49 849
850 TObjString option(fOption);
851 option.Write();
852
853 file->Close();
854
dca331bb 855 Printf("Writting result to multiplicity.root");
a9017e49 856}