3 #include "AlidNdEtaCorrectionTask.h"
12 #include <TParticle.h>
13 #include <TParticlePDG.h>
14 #include <TDatabasePDG.h>
18 #include <AliESDVertex.h>
19 #include <AliESDEvent.h>
20 #include <AliESDRun.h>
22 #include <AliHeader.h>
23 #include <AliGenEventHeader.h>
24 #include <AliMultiplicity.h>
25 #include <AliAnalysisManager.h>
26 #include <AliMCEventHandler.h>
27 #include <AliMCEvent.h>
28 #include <AliESDInputHandler.h>
30 #include "AliESDtrackCuts.h"
31 #include "AliPWG0Helper.h"
32 #include "dNdEta/dNdEtaAnalysis.h"
33 #include "dNdEta/AlidNdEtaCorrection.h"
34 #include "AliTriggerAnalysis.h"
35 #include "AliPhysicsSelection.h"
37 ClassImp(AlidNdEtaCorrectionTask)
39 AlidNdEtaCorrectionTask::AlidNdEtaCorrectionTask() :
44 fAnalysisMode((AliPWG0Helper::AnalysisMode) (AliPWG0Helper::kTPC | AliPWG0Helper::kFieldOn)),
45 fTrigger(AliTriggerAnalysis::kMB1),
49 fMultAxisEta1(kFALSE),
50 fDiffTreatment(AliPWG0Helper::kMCFlags),
52 fOnlyPrimaries(kFALSE),
54 fSystSkipParticles(kFALSE),
58 fdNdEtaAnalysisESD(0),
61 fVertexCorrelation(0),
62 fVertexCorrelationShift(0),
67 fEtaCorrelationShift(0),
70 fDeltaPhiCorrelation(0),
82 // Constructor. Initialization of pointers
85 for (Int_t i=0; i<4; i++)
86 fdNdEtaCorrectionSpecial[i] = 0;
88 for (Int_t i=0; i<8; i++)
91 AliLog::SetClassDebugLevel("AlidNdEtaCorrectionTask", AliLog::kWarning);
94 AlidNdEtaCorrectionTask::AlidNdEtaCorrectionTask(const char* opt) :
95 AliAnalysisTask("AlidNdEtaCorrectionTask", ""),
99 fAnalysisMode((AliPWG0Helper::AnalysisMode) (AliPWG0Helper::kTPC | AliPWG0Helper::kFieldOn)),
100 fTrigger(AliTriggerAnalysis::kMB1),
104 fMultAxisEta1(kFALSE),
105 fDiffTreatment(AliPWG0Helper::kMCFlags),
107 fOnlyPrimaries(kFALSE),
109 fSystSkipParticles(kFALSE),
111 fdNdEtaCorrection(0),
112 fdNdEtaAnalysisMC(0),
113 fdNdEtaAnalysisESD(0),
116 fVertexCorrelation(0),
117 fVertexCorrelationShift(0),
122 fEtaCorrelationShift(0),
125 fDeltaPhiCorrelation(0),
127 fEsdTrackCutsPrim(0),
137 // Constructor. Initialization of pointers
140 // Define input and output slots here
141 DefineInput(0, TChain::Class());
142 DefineOutput(0, TList::Class());
144 for (Int_t i=0; i<4; i++)
145 fdNdEtaCorrectionSpecial[i] = 0;
147 for (Int_t i=0; i<8; i++)
150 AliLog::SetClassDebugLevel("AlidNdEtaCorrectionTask", AliLog::kWarning);
153 AlidNdEtaCorrectionTask::~AlidNdEtaCorrectionTask()
159 // histograms are in the output list and deleted when the output
160 // list is deleted by the TSelector dtor
168 //________________________________________________________________________
169 void AlidNdEtaCorrectionTask::ConnectInputData(Option_t *)
174 Printf("AlidNdEtaCorrectionTask::ConnectInputData called");
176 AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
179 Printf("ERROR: Could not get ESDInputHandler");
181 fESD = esdH->GetEvent();
183 // Enable only the needed branches
184 esdH->SetActiveBranches("AliESDHeader Vertex");
186 if (fAnalysisMode & AliPWG0Helper::kSPD)
187 esdH->SetActiveBranches("AliESDHeader Vertex AliMultiplicity");
189 if (fAnalysisMode & AliPWG0Helper::kTPC || fAnalysisMode & AliPWG0Helper::kTPCITS) {
190 esdH->SetActiveBranches("AliESDHeader Vertex Tracks");
194 // disable info messages of AliMCEvent (per event)
195 AliLog::SetClassDebugLevel("AliMCEvent", AliLog::kWarning - AliLog::kDebug + 1);
198 void AlidNdEtaCorrectionTask::CreateOutputObjects()
200 // create result objects and add to output list
202 if (fOption.Contains("only-positive"))
204 Printf("INFO: Processing only positive particles.");
207 else if (fOption.Contains("only-negative"))
209 Printf("INFO: Processing only negative particles.");
213 if (fOption.Contains("stat-error-1"))
215 Printf("INFO: Evaluation statistical errors. Mode: 1.");
218 else if (fOption.Contains("stat-error-2"))
220 Printf("INFO: Evaluation statistical errors. Mode: 2.");
227 fdNdEtaCorrection = new AlidNdEtaCorrection("dndeta_correction", "dndeta_correction", fAnalysisMode);
228 fOutput->Add(fdNdEtaCorrection);
230 fPIDParticles = new TH1F("fPIDParticles", "PID of generated primary particles", 10001, -5000.5, 5000.5);
231 fOutput->Add(fPIDParticles);
233 fPIDTracks = new TH1F("fPIDTracks", "MC PID of reconstructed tracks", 10001, -5000.5, 5000.5);
234 fOutput->Add(fPIDTracks);
236 fdNdEtaAnalysisMC = new dNdEtaAnalysis("dndetaMC", "dndetaMC", fAnalysisMode);
237 fOutput->Add(fdNdEtaAnalysisMC);
239 fdNdEtaAnalysisESD = new dNdEtaAnalysis("dndetaESD", "dndetaESD", fAnalysisMode);
240 fOutput->Add(fdNdEtaAnalysisESD);
244 fEsdTrackCutsPrim = dynamic_cast<AliESDtrackCuts*> (fEsdTrackCuts->Clone("fEsdTrackCutsPrim"));
245 fEsdTrackCutsSec = dynamic_cast<AliESDtrackCuts*> (fEsdTrackCuts->Clone("fEsdTrackCutsSec"));
246 fOutput->Add(fEsdTrackCutsPrim);
247 fOutput->Add(fEsdTrackCutsSec);
250 if (fOption.Contains("process-types")) {
251 fdNdEtaCorrectionSpecial[0] = new AlidNdEtaCorrection("dndeta_correction_ND", "dndeta_correction_ND", fAnalysisMode);
252 fdNdEtaCorrectionSpecial[1] = new AlidNdEtaCorrection("dndeta_correction_SD", "dndeta_correction_SD", fAnalysisMode);
253 fdNdEtaCorrectionSpecial[2] = new AlidNdEtaCorrection("dndeta_correction_DD", "dndeta_correction_DD", fAnalysisMode);
255 fOutput->Add(fdNdEtaCorrectionSpecial[0]);
256 fOutput->Add(fdNdEtaCorrectionSpecial[1]);
257 fOutput->Add(fdNdEtaCorrectionSpecial[2]);
260 if (fOption.Contains("particle-species")) {
261 fdNdEtaCorrectionSpecial[0] = new AlidNdEtaCorrection("dndeta_correction_pi", "dndeta_correction_pi", fAnalysisMode);
262 fdNdEtaCorrectionSpecial[1] = new AlidNdEtaCorrection("dndeta_correction_K", "dndeta_correction_K", fAnalysisMode);
263 fdNdEtaCorrectionSpecial[2] = new AlidNdEtaCorrection("dndeta_correction_p", "dndeta_correction_p", fAnalysisMode);
264 fdNdEtaCorrectionSpecial[3] = new AlidNdEtaCorrection("dndeta_correction_other", "dndeta_correction_other", fAnalysisMode);
266 for (Int_t i=0; i<4; i++)
267 fOutput->Add(fdNdEtaCorrectionSpecial[i]);
271 //fTemp1 = new TH2F("fTemp1", "fTemp1", 4, 0.5, 4.5, 101, -1.5, 99.5); // nsd study
272 fTemp1 = new TH2F("fTemp1", "fTemp1", 300, -15, 15, 80, -2.0, 2.0);
273 fOutput->Add(fTemp1);
275 fTemp2 = new TH2F("fTemp2", "fTemp2", 300, -15, 15, 80, -2.0, 2.0);
276 fOutput->Add(fTemp2);
278 fVertexCorrelation = new TH2F("fVertexCorrelation", "fVertexCorrelation;MC z-vtx;ESD z-vtx", 120, -30, 30, 120, -30, 30);
279 fOutput->Add(fVertexCorrelation);
280 fVertexCorrelationShift = new TH3F("fVertexCorrelationShift", "fVertexCorrelationShift;MC z-vtx;MC z-vtx - ESD z-vtx;rec. tracks", 120, -30, 30, 100, -1, 1, 100, -0.5, 99.5);
281 fOutput->Add(fVertexCorrelationShift);
282 fVertexProfile = new TProfile("fVertexProfile", "fVertexProfile;MC z-vtx;MC z-vtx - ESD z-vtx", 40, -20, 20);
283 fOutput->Add(fVertexProfile);
284 fVertexShift = new TH1F("fVertexShift", "fVertexShift;(MC z-vtx - ESD z-vtx);Entries", 201, -2, 2);
285 fOutput->Add(fVertexShift);
286 fVertexShiftNorm = new TH2F("fVertexShiftNorm", "fVertexShiftNorm;(MC z-vtx - ESD z-vtx);rec. tracks;Entries", 200, -100, 100, 100, -0.5, 99.5);
287 fOutput->Add(fVertexShiftNorm);
289 fEtaCorrelation = new TH2F("fEtaCorrelation", "fEtaCorrelation;MC #eta;ESD #eta", 120, -3, 3, 120, -3, 3);
290 fOutput->Add(fEtaCorrelation);
291 fEtaCorrelationShift = new TH2F("fEtaCorrelationShift", "fEtaCorrelationShift;MC #eta;MC #eta - ESD #eta", 120, -3, 3, 100, -0.1, 0.1);
292 fOutput->Add(fEtaCorrelationShift);
293 fEtaProfile = new TProfile("fEtaProfile", "fEtaProfile;MC #eta;MC #eta - ESD #eta", 120, -3, 3);
294 fOutput->Add(fEtaProfile);
295 fEtaResolution = new TH1F("fEtaResolution", "fEtaResolution;MC #eta - ESD #eta", 201, -0.2, 0.2);
296 fOutput->Add(fEtaResolution);
298 fpTResolution = new TH2F("fpTResolution", ";MC p_{T} (GeV/c);(MC p_{T} - ESD p_{T}) / MC p_{T}", 160, 0, 20, 201, -0.2, 0.2);
299 fOutput->Add(fpTResolution);
301 fMultAll = new TH1F("fMultAll", "fMultAll", 500, -0.5, 499.5);
302 fOutput->Add(fMultAll);
303 fMultVtx = new TH1F("fMultVtx", "fMultVtx", 500, -0.5, 499.5);
304 fOutput->Add(fMultVtx);
305 fMultTr = new TH1F("fMultTr", "fMultTr", 500, -0.5, 499.5);
306 fOutput->Add(fMultTr);
308 for (Int_t i=0; i<8; i++)
310 fDeltaPhi[i] = new TH2F(Form("fDeltaPhi_%d", i), ";#Delta phi;#phi;Entries", 2000, -0.1, 0.1, 18 * 5, 0, TMath::TwoPi());
311 fOutput->Add(fDeltaPhi[i]);
314 fEventStats = new TH2F("fEventStats", "fEventStats;event type;status;count", 109, -6.5, 102.5, 4, -0.5, 3.5);
315 fOutput->Add(fEventStats);
316 fEventStats->GetXaxis()->SetBinLabel(1, "INEL"); // x = -5
317 fEventStats->GetXaxis()->SetBinLabel(2, "NSD"); // x = -4
318 fEventStats->GetXaxis()->SetBinLabel(3, "ND"); // x = -3
319 fEventStats->GetXaxis()->SetBinLabel(4, "SD"); // x = -2
320 fEventStats->GetXaxis()->SetBinLabel(5, "DD"); // x = -1
322 fEventStats->GetXaxis()->SetBinLabel(108, "INEL=0"); // x = -101
323 fEventStats->GetXaxis()->SetBinLabel(109, "INEL>0"); // x = -102
325 for (Int_t i=-1; i<100; i++)
326 fEventStats->GetXaxis()->SetBinLabel(7+i, Form("%d", i));
328 fEventStats->GetYaxis()->SetBinLabel(1, "nothing");
329 fEventStats->GetYaxis()->SetBinLabel(2, "trg");
330 fEventStats->GetYaxis()->SetBinLabel(3, "vtx");
331 fEventStats->GetYaxis()->SetBinLabel(4, "trgvtx");
335 fEsdTrackCuts->SetName("fEsdTrackCuts");
336 // TODO like this we send an empty object back...
337 fOutput->Add(fEsdTrackCuts->Clone());
341 void AlidNdEtaCorrectionTask::Exec(Option_t*)
345 // Check prerequisites
348 AliDebug(AliLog::kError, "ESD branch not available");
353 Printf("WARNING: Processing only primaries. For systematical studies only!");
356 Printf("WARNING: Statistical error evaluation active!");
358 AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
361 Printf("ERROR: Could not receive input handler");
365 Bool_t eventTriggered = inputHandler->IsEventSelected();
367 static AliTriggerAnalysis* triggerAnalysis = 0;
368 if (!triggerAnalysis)
370 AliPhysicsSelection* physicsSelection = dynamic_cast<AliPhysicsSelection*> (inputHandler->GetEventSelection());
371 if (physicsSelection)
372 triggerAnalysis = physicsSelection->GetTriggerAnalysis();
376 eventTriggered = triggerAnalysis->IsTriggerFired(fESD, fTrigger);
379 Printf("No trigger");
381 // post the data already here
382 PostData(0, fOutput);
385 AliMCEventHandler* eventHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
387 Printf("ERROR: Could not retrieve MC event handler");
391 AliMCEvent* mcEvent = eventHandler->MCEvent();
393 Printf("ERROR: Could not retrieve MC event");
397 AliStack* stack = mcEvent->Stack();
400 AliDebug(AliLog::kError, "Stack not available");
404 AliHeader* header = mcEvent->Header();
407 AliDebug(AliLog::kError, "Header not available");
412 Int_t processType = AliPWG0Helper::GetEventProcessType(fESD, header, stack, fDiffTreatment);
414 AliDebug(AliLog::kDebug+1, Form("Found process type %d", processType));
416 if (processType == AliPWG0Helper::kInvalidProcess)
418 AliDebug(AliLog::kWarning, "Unknown process type. Setting to ND");
419 processType = AliPWG0Helper::kND;
423 AliGenEventHeader* genHeader = header->GenEventHeader();
425 genHeader->PrimaryVertex(vtxMC);
427 // get the ESD vertex
428 Bool_t eventVertex = kFALSE;
430 const AliESDVertex* vtxESD = AliPWG0Helper::GetVertex(fESD, fAnalysisMode);
431 if (vtxESD && AliPWG0Helper::TestVertex(vtxESD, fAnalysisMode))
436 // remove vertices outside +- 15 cm
437 if (TMath::Abs(vtx[2]) > 15)
439 eventVertex = kFALSE;
446 // create list of (label, eta, pt) tuples
447 Int_t inputCount = 0;
449 Int_t* labelArr2 = 0; // only for case of SPD
451 Float_t* thirdDimArr = 0;
452 Float_t* deltaPhiArr = 0;
453 if (fAnalysisMode & AliPWG0Helper::kSPD)
458 const AliMultiplicity* mult = fESD->GetMultiplicity();
461 AliDebug(AliLog::kError, "AliMultiplicity not available");
465 labelArr = new Int_t[mult->GetNumberOfTracklets()];
466 labelArr2 = new Int_t[mult->GetNumberOfTracklets()];
467 etaArr = new Float_t[mult->GetNumberOfTracklets()];
468 thirdDimArr = new Float_t[mult->GetNumberOfTracklets()];
469 deltaPhiArr = new Float_t[mult->GetNumberOfTracklets()];
471 Bool_t foundInEta10 = kFALSE;
473 // get multiplicity from SPD tracklets
474 for (Int_t i=0; i<mult->GetNumberOfTracklets(); ++i)
476 //printf("%d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), mult->GetDeltaPhi(i));
478 Float_t phi = mult->GetPhi(i);
480 phi += TMath::Pi() * 2;
481 Float_t deltaPhi = mult->GetDeltaPhi(i);
483 if (TMath::Abs(deltaPhi) > 1)
484 printf("WARNING: Very high Delta Phi: %d %f %f %f\n", i, mult->GetTheta(i), mult->GetPhi(i), deltaPhi);
487 if (mult->GetLabel(i, 0) < 0 || mult->GetLabel(i, 0) != mult->GetLabel(i, 1) || !stack->IsPhysicalPrimary(mult->GetLabel(i, 0)))
490 if (fDeltaPhiCut > 0 && (TMath::Abs(deltaPhi) > fDeltaPhiCut || TMath::Abs(mult->GetDeltaTheta(i)) > fDeltaPhiCut / 0.08 * 0.025))
493 if (fSystSkipParticles && gRandom->Uniform() < 0.0153)
495 Printf("Skipped tracklet!");
499 // TEST exclude potentially inefficient phi region
500 //if (phi > 5.70 || phi < 0.06)
503 // we have to repeat the trigger here, because the tracklet might have been kicked out fSystSkipParticles
504 if (TMath::Abs(mult->GetEta(i)) < 1)
505 foundInEta10 = kTRUE;
507 etaArr[inputCount] = mult->GetEta(i);
509 etaArr[inputCount] = TMath::Abs(etaArr[inputCount]);
510 labelArr[inputCount] = mult->GetLabel(i, 0);
511 labelArr2[inputCount] = mult->GetLabel(i, 1);
512 thirdDimArr[inputCount] = phi;
513 deltaPhiArr[inputCount] = deltaPhi;
518 for (Int_t i=0; i<mult->GetNumberOfSingleClusters(); ++i)
520 if (TMath::Abs(TMath::Log(TMath::Tan(mult->GetThetaSingle(i)/2.))) < 1);
522 foundInEta10 = kTRUE;
528 if (fSystSkipParticles && (fTrigger & AliTriggerAnalysis::kOneParticle) && !foundInEta10)
529 eventTriggered = kFALSE;
532 else if (fAnalysisMode & AliPWG0Helper::kTPC || fAnalysisMode & AliPWG0Helper::kTPCITS)
536 AliDebug(AliLog::kError, "fESDTrackCuts not available");
540 Bool_t foundInEta10 = kFALSE;
544 // get multiplicity from ESD tracks
545 TObjArray* list = fEsdTrackCuts->GetAcceptedTracks(fESD, (fAnalysisMode & AliPWG0Helper::kTPC));
546 Int_t nGoodTracks = list->GetEntries();
548 Printf("Accepted %d tracks", nGoodTracks);
550 labelArr = new Int_t[nGoodTracks];
551 labelArr2 = new Int_t[nGoodTracks];
552 etaArr = new Float_t[nGoodTracks];
553 thirdDimArr = new Float_t[nGoodTracks];
554 deltaPhiArr = new Float_t[nGoodTracks];
556 // loop over esd tracks
557 for (Int_t i=0; i<nGoodTracks; i++)
559 AliESDtrack* esdTrack = dynamic_cast<AliESDtrack*> (list->At(i));
562 AliDebug(AliLog::kError, Form("ERROR: Could not retrieve track %d.", i));
566 if (esdTrack->Pt() < 0.15)
571 Int_t label = TMath::Abs(esdTrack->GetLabel());
575 if (stack->IsPhysicalPrimary(label) == kFALSE)
580 if (TMath::Abs(esdTrack->Eta()) < 1 && esdTrack->Pt() > 0.15)
581 foundInEta10 = kTRUE;
583 etaArr[inputCount] = esdTrack->Eta();
585 etaArr[inputCount] = TMath::Abs(etaArr[inputCount]);
586 labelArr[inputCount] = TMath::Abs(esdTrack->GetLabel());
587 labelArr2[inputCount] = labelArr[inputCount]; // no second label for tracks
588 thirdDimArr[inputCount] = esdTrack->Pt();
589 deltaPhiArr[inputCount] = 0; // no delta phi for tracks
595 // TODO this code crashes for TPCITS because particles are requested from the stack for some labels that are out of bound
596 if (0 && eventTriggered)
598 // collect values for primaries and secondaries
599 for (Int_t iTrack = 0; iTrack < fESD->GetNumberOfTracks(); iTrack++)
601 AliESDtrack* track = 0;
603 if (fAnalysisMode & AliPWG0Helper::kTPC)
604 track = AliESDtrackCuts::GetTPCOnlyTrack(fESD, iTrack);
605 else if (fAnalysisMode & AliPWG0Helper::kTPCITS)
606 track = fESD->GetTrack(iTrack);
611 Int_t label = TMath::Abs(track->GetLabel());
612 if (!stack->Particle(label) || !stack->Particle(label)->GetPDG())
614 Printf("WARNING: No particle for %d", label);
615 if (stack->Particle(label))
616 stack->Particle(label)->Print();
620 if (stack->Particle(label)->GetPDG()->Charge() == 0)
623 if (TMath::Abs(track->Eta()) < 0.8 && track->Pt() > 0.15)
625 if (stack->IsPhysicalPrimary(label))
628 if (fEsdTrackCutsPrim->AcceptTrack(track))
630 // if (AliESDtrackCuts::GetSigmaToVertex(track) > 900)
632 // Printf("Track %d has nsigma of %f. Printing track and vertex...", iTrack, AliESDtrackCuts::GetSigmaToVertex(track));
635 // track->GetImpactParameters(b, r);
636 // Printf("Impact parameter %f %f and resolution: %f %f %f", b[0], b[1], r[0], r[1], r[2]);
646 fEsdTrackCutsSec->AcceptTrack(track);
650 // TODO mem leak in the continue statements above
651 if (fAnalysisMode & AliPWG0Helper::kTPC)
658 eventTriggered = kFALSE;
664 Int_t biny = (Int_t) eventTriggered + 2 * (Int_t) eventVertex;
666 fEventStats->Fill(-6, biny);
668 if (processType != AliPWG0Helper::kSD)
669 fEventStats->Fill(-5, biny);
671 if (processType == AliPWG0Helper::kND)
672 fEventStats->Fill(-4, biny);
673 if (processType == AliPWG0Helper::kSD)
674 fEventStats->Fill(-3, biny);
675 if (processType == AliPWG0Helper::kDD)
676 fEventStats->Fill(-2, biny);
678 // loop over mc particles
679 Int_t nPrim = stack->GetNprimary();
682 Bool_t oneParticleEvent = kFALSE;
683 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
685 //Printf("Getting particle %d", iMc);
686 TParticle* particle = stack->Particle(iMc);
691 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
694 if (TMath::Abs(particle->Eta()) < 1.0)
696 oneParticleEvent = kTRUE;
701 if (TMath::Abs(vtxMC[2]) < 5.5)
703 if (oneParticleEvent)
704 fEventStats->Fill(102, biny);
706 fEventStats->Fill(101, biny);
709 for (Int_t iMc = 0; iMc < nPrim; ++iMc)
711 //Printf("Getting particle %d", iMc);
712 TParticle* particle = stack->Particle(iMc);
717 if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
719 //if (TMath::Abs(particle->GetPdgCode()) > 3000 && TMath::Abs(particle->Eta()) < 1.0)
720 // fPIDParticles->Fill(particle->GetPdgCode());
724 if (SignOK(particle->GetPDG()) == kFALSE)
727 if (fPIDParticles && TMath::Abs(particle->Eta()) < 1.0)
728 fPIDParticles->Fill(particle->GetPdgCode());
730 Float_t eta = particle->Eta();
732 eta = TMath::Abs(eta);
734 Float_t thirdDim = -1;
735 if (fAnalysisMode & AliPWG0Helper::kSPD)
739 thirdDim = particle->Phi();
742 thirdDim = inputCount;
745 thirdDim = particle->Pt();
748 //Float_t y = 0.5 * TMath::Log((particle->Energy() + particle->Pz()) / (particle->Energy() - particle->Pz()));
752 Int_t processType2 = processType;
753 if (oneParticleEvent)
754 processType2 |= AliPWG0Helper::kOnePart;
755 fdNdEtaCorrection->FillMCParticle(vtxMC[2], eta, thirdDim, eventTriggered, eventVertex, processType2);
757 if (fOption.Contains("process-types"))
760 if (processType==AliPWG0Helper::kND)
761 fdNdEtaCorrectionSpecial[0]->FillMCParticle(vtxMC[2], eta, thirdDim, eventTriggered, eventVertex, processType2);
763 // single diffractive
764 if (processType==AliPWG0Helper::kSD)
765 fdNdEtaCorrectionSpecial[1]->FillMCParticle(vtxMC[2], eta, thirdDim, eventTriggered, eventVertex, processType2);
767 // double diffractive
768 if (processType==AliPWG0Helper::kDD)
769 fdNdEtaCorrectionSpecial[2]->FillMCParticle(vtxMC[2], eta, thirdDim, eventTriggered, eventVertex, processType2);
772 if (fOption.Contains("particle-species"))
775 switch (TMath::Abs(particle->GetPdgCode()))
777 case 211: id = 0; break;
778 case 321: id = 1; break;
779 case 2212: id = 2; break;
780 default: id = 3; break;
782 fdNdEtaCorrectionSpecial[id]->FillMCParticle(vtxMC[2], eta, thirdDim, eventTriggered, eventVertex, processType2);
787 fdNdEtaAnalysisMC->FillTrack(vtxMC[2], eta, thirdDim);
789 // TODO this value might be needed lower for the SPD study (only used for control histograms anyway)
790 if (TMath::Abs(eta) < 1.5) // && pt > 0.2)
794 if (AliPWG0Helper::GetLastProcessType() >= -1)
795 fEventStats->Fill(AliPWG0Helper::GetLastProcessType(), biny);
797 fMultAll->Fill(nAccepted);
798 if (eventTriggered) {
799 fMultTr->Fill(nAccepted);
801 fMultVtx->Fill(nAccepted);
806 Bool_t* primCount = 0;
809 primCount = new Bool_t[nPrim];
810 for (Int_t i=0; i<nPrim; ++i)
811 primCount[i] = kFALSE;
816 for (Int_t i=0; i<inputCount; ++i)
818 if (TMath::Abs(etaArr[i]) < 0.5)
820 if (TMath::Abs(etaArr[i]) < 1.0)
824 for (Int_t i=0; i<inputCount; ++i)
826 Int_t label = labelArr[i];
827 Int_t label2 = labelArr2[i];
831 Printf("WARNING: cannot find corresponding mc particle for track(let) %d with label %d.", i, label);
835 TParticle* particle = stack->Particle(label);
838 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (track loop).", label));
842 if (TMath::Abs(particle->Eta()) < 1.0)
843 fPIDTracks->Fill(particle->GetPdgCode());
845 // find particle that is filled in the correction map
846 // this should be the particle that has been reconstructed
847 // for TPC this is clear and always identified by the track's label
848 // for SPD the labels might not be identical. In this case the particle closest to the beam line that is a primary is taken:
849 // L1 L2 (P = primary, S = secondary)
855 if (label != label2 && label2 >= 0)
857 if (stack->IsPhysicalPrimary(label) == kFALSE && stack->IsPhysicalPrimary(label2))
859 particle = stack->Particle(label2);
862 AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (track loop).", label2));
868 if (eventTriggered && eventVertex)
870 if (SignOK(particle->GetPDG()) == kFALSE)
877 fEtaResolution->Fill(TMath::Abs(particle->Eta()) - etaArr[i]);
879 fEtaResolution->Fill(particle->Eta() - etaArr[i]);
881 if (fAnalysisMode & AliPWG0Helper::kTPC || fAnalysisMode & AliPWG0Helper::kTPCITS)
882 if (TMath::Abs(particle->Eta() < 0.9) && particle->Pt() > 0)
883 fpTResolution->Fill(particle->Pt(), (particle->Pt() - thirdDimArr[i]) / particle->Pt());
886 Float_t thirdDim = -1;
888 Bool_t firstIsPrim = stack->IsPhysicalPrimary(label);
889 // in case of same label the MC values are filled, otherwise (background) the reconstructed values
892 eta = particle->Eta();
894 eta = TMath::Abs(eta);
896 if (fAnalysisMode & AliPWG0Helper::kSPD)
900 thirdDim = particle->Phi();
903 thirdDim = inputCount;
906 thirdDim = particle->Pt();
910 if (fAnalysisMode & AliPWG0Helper::kSPD && !fFillPhi)
912 thirdDim = (fMultAxisEta1) ? nEta10 : inputCount;
915 thirdDim = thirdDimArr[i];
920 Bool_t fillTrack = kTRUE;
922 // statistical error evaluation active?
925 Bool_t statErrorDecision = kFALSE;
927 // primary and not yet counted
928 if (label == label2 && firstIsPrim && !primCount[label])
930 statErrorDecision = kTRUE;
931 primCount[label] = kTRUE;
934 // in case of 1 we count only unique primaries, in case of 2 all the rest
937 fillTrack = statErrorDecision;
939 else if (fStatError == 2)
940 fillTrack = !statErrorDecision;
945 fdNdEtaCorrection->FillTrackedParticle(vtxMC[2], eta, thirdDim);
946 fTemp2->Fill(vtxMC[2], eta);
949 // eta comparison for tracklets with the same label (others are background)
952 Float_t eta2 = particle->Eta();
954 eta2 = TMath::Abs(eta2);
956 fEtaProfile->Fill(eta2, eta2 - etaArr[i]);
957 fEtaCorrelation->Fill(etaArr[i], eta2);
958 fEtaCorrelationShift->Fill(eta2, eta2 - etaArr[i]);
962 fdNdEtaAnalysisESD->FillTrack(vtxMC[2], TMath::Abs(particle->Eta()), thirdDim);
964 fdNdEtaAnalysisESD->FillTrack(vtxMC[2], particle->Eta(), thirdDim);
966 if (fOption.Contains("process-types"))
969 if (processType == AliPWG0Helper::kND)
970 fdNdEtaCorrectionSpecial[0]->FillTrackedParticle(vtxMC[2], eta, thirdDim);
972 // single diffractive
973 if (processType == AliPWG0Helper::kSD)
974 fdNdEtaCorrectionSpecial[1]->FillTrackedParticle(vtxMC[2], eta, thirdDim);
976 // double diffractive
977 if (processType == AliPWG0Helper::kDD)
978 fdNdEtaCorrectionSpecial[2]->FillTrackedParticle(vtxMC[2], eta, thirdDim);
981 if (fOption.Contains("particle-species"))
984 TParticle* mother = AliPWG0Helper::FindPrimaryMother(stack, label);
987 switch (TMath::Abs(mother->GetPdgCode()))
989 case 211: id = 0; break;
990 case 321: id = 1; break;
991 case 2212: id = 2; break;
992 default: id = 3; break;
994 fdNdEtaCorrectionSpecial[id]->FillTrackedParticle(vtxMC[2], eta, thirdDim);
997 // control histograms
1008 else if (label2 >= 0)
1010 Bool_t secondIsPrim = stack->IsPhysicalPrimary(label2);
1011 if (firstIsPrim && secondIsPrim)
1015 else if (firstIsPrim && !secondIsPrim)
1019 // check if secondary is caused by the primary or it is a fake combination
1020 //Printf("PS case --> Label 1 is %d, label 2 is %d", label, label2);
1021 Int_t mother = label2;
1022 while (stack->Particle(mother) && stack->Particle(mother)->GetMother(0) >= 0)
1024 //Printf(" %d created by %d, %d", mother, stack->Particle(mother)->GetMother(0), stack->Particle(mother)->GetMother(1));
1025 if (stack->Particle(mother)->GetMother(0) == label)
1027 /*Printf("The untraceable decay was:");
1030 Printf(" to (status code %d):", stack->Particle(mother)->GetStatusCode());
1031 stack->Particle(mother)->Print();*/
1034 mother = stack->Particle(mother)->GetMother(0);
1037 else if (!firstIsPrim && secondIsPrim)
1041 else if (!firstIsPrim && !secondIsPrim)
1050 fDeltaPhi[hist]->Fill(deltaPhiArr[i], thirdDimArr[i]);
1060 if (processed < inputCount)
1061 Printf("Only %d out of %d track(let)s were used", processed, inputCount);
1063 if (eventTriggered && eventVertex)
1065 Double_t diff = vtxMC[2] - vtx[2];
1066 fVertexShift->Fill(diff);
1068 fVertexCorrelation->Fill(vtxMC[2], vtx[2]);
1069 fVertexCorrelationShift->Fill(vtxMC[2], vtxMC[2] - vtx[2], inputCount);
1070 fVertexProfile->Fill(vtxMC[2], vtxMC[2] - vtx[2]);
1072 if (vtxESD->IsFromVertexerZ() && inputCount > 0)
1073 fVertexShiftNorm->Fill(diff, vtxESD->GetNContributors());
1076 Int_t multAxis = inputCount;
1080 if (eventTriggered && eventVertex)
1082 fdNdEtaAnalysisMC->FillEvent(vtxMC[2], multAxis);
1083 fdNdEtaAnalysisESD->FillEvent(vtxMC[2], multAxis);
1086 Int_t processType2 = processType;
1087 if (oneParticleEvent)
1088 processType2 |= AliPWG0Helper::kOnePart;
1090 // stuff regarding the vertex reco correction and trigger bias correction
1091 fdNdEtaCorrection->FillEvent(vtxMC[2], multAxis, eventTriggered, eventVertex, processType2);
1093 if (fOption.Contains("process-types"))
1096 if (processType == AliPWG0Helper::kND)
1097 fdNdEtaCorrectionSpecial[0]->FillEvent(vtxMC[2], multAxis, eventTriggered, eventVertex, processType2);
1099 // single diffractive
1100 if (processType == AliPWG0Helper::kSD)
1101 fdNdEtaCorrectionSpecial[1]->FillEvent(vtxMC[2], multAxis, eventTriggered, eventVertex, processType2);
1103 // double diffractive
1104 if (processType == AliPWG0Helper::kDD)
1105 fdNdEtaCorrectionSpecial[2]->FillEvent(vtxMC[2], multAxis, eventTriggered, eventVertex, processType2);
1108 if (fOption.Contains("particle-species"))
1109 for (Int_t id=0; id<4; id++)
1110 fdNdEtaCorrectionSpecial[id]->FillEvent(vtxMC[2], multAxis, eventTriggered, eventVertex, processType2);
1119 delete[] thirdDimArr;
1121 delete[] deltaPhiArr;
1124 void AlidNdEtaCorrectionTask::Terminate(Option_t *)
1126 // The Terminate() function is the last function to be called during
1127 // a query. It always runs on the client, it can be used to present
1128 // the results graphically or save the results to file.
1130 fOutput = dynamic_cast<TList*> (GetOutputData(0));
1132 Printf("ERROR: fOutput not available");
1136 fdNdEtaCorrection = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction"));
1137 fdNdEtaAnalysisMC = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaMC"));
1138 fdNdEtaAnalysisESD = dynamic_cast<dNdEtaAnalysis*> (fOutput->FindObject("dndetaESD"));
1139 if (!fdNdEtaCorrection || !fdNdEtaAnalysisMC || !fdNdEtaAnalysisESD)
1141 AliDebug(AliLog::kError, "Could not read object from output list");
1145 fdNdEtaCorrection->Finish();
1148 fileName.Form("correction_map%s.root", fOption.Data());
1149 TFile* fout = new TFile(fileName, "RECREATE");
1151 fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (fOutput->FindObject("fEsdTrackCuts"));
1153 fEsdTrackCuts->SaveHistograms("esd_track_cuts");
1155 fEsdTrackCutsPrim = dynamic_cast<AliESDtrackCuts*> (fOutput->FindObject("fEsdTrackCutsPrim"));
1156 if (fEsdTrackCutsPrim)
1157 fEsdTrackCutsPrim->SaveHistograms("esd_track_cuts_primaries");
1159 fEsdTrackCutsSec = dynamic_cast<AliESDtrackCuts*> (fOutput->FindObject("fEsdTrackCutsSec"));
1160 if (fEsdTrackCutsSec)
1161 fEsdTrackCutsSec->SaveHistograms("esd_track_cuts_secondaries");
1163 fdNdEtaCorrection->SaveHistograms();
1164 fdNdEtaAnalysisMC->SaveHistograms();
1165 fdNdEtaAnalysisESD->SaveHistograms();
1167 if (fOutput->FindObject("dndeta_correction_ND"))
1169 fdNdEtaCorrectionSpecial[0] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_ND"));
1170 fdNdEtaCorrectionSpecial[1] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_SD"));
1171 fdNdEtaCorrectionSpecial[2] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_DD"));
1175 fdNdEtaCorrectionSpecial[0] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_pi"));
1176 fdNdEtaCorrectionSpecial[1] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_K"));
1177 fdNdEtaCorrectionSpecial[2] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_p"));
1178 fdNdEtaCorrectionSpecial[3] = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction_other"));
1180 for (Int_t i=0; i<4; ++i)
1181 if (fdNdEtaCorrectionSpecial[i])
1182 fdNdEtaCorrectionSpecial[i]->SaveHistograms();
1184 fTemp1 = dynamic_cast<TH1*> (fOutput->FindObject("fTemp1"));
1187 fTemp2 = dynamic_cast<TH1*> (fOutput->FindObject("fTemp2"));
1191 fVertexCorrelation = dynamic_cast<TH2F*> (fOutput->FindObject("fVertexCorrelation"));
1192 if (fVertexCorrelation)
1193 fVertexCorrelation->Write();
1194 fVertexCorrelationShift = dynamic_cast<TH3F*> (fOutput->FindObject("fVertexCorrelationShift"));
1195 if (fVertexCorrelationShift)
1197 ((TH2*) fVertexCorrelationShift->Project3D("yx"))->FitSlicesY();
1198 fVertexCorrelationShift->Write();
1200 fVertexProfile = dynamic_cast<TProfile*> (fOutput->FindObject("fVertexProfile"));
1202 fVertexProfile->Write();
1203 fVertexShift = dynamic_cast<TH1F*> (fOutput->FindObject("fVertexShift"));
1205 fVertexShift->Write();
1206 fVertexShiftNorm = dynamic_cast<TH2F*> (fOutput->FindObject("fVertexShiftNorm"));
1207 if (fVertexShiftNorm)
1209 fVertexShiftNorm->ProjectionX();
1210 fVertexShiftNorm->Write();
1213 fEtaCorrelation = dynamic_cast<TH2F*> (fOutput->FindObject("fEtaCorrelation"));
1214 if (fEtaCorrelation)
1215 fEtaCorrelation->Write();
1216 fEtaCorrelationShift = dynamic_cast<TH2F*> (fOutput->FindObject("fEtaCorrelationShift"));
1217 if (fEtaCorrelationShift)
1219 fEtaCorrelationShift->FitSlicesY();
1220 fEtaCorrelationShift->Write();
1222 fEtaProfile = dynamic_cast<TProfile*> (fOutput->FindObject("fEtaProfile"));
1224 fEtaProfile->Write();
1225 fEtaResolution = dynamic_cast<TH1F*> (fOutput->FindObject("fEtaResolution"));
1227 fEtaResolution->Write();
1228 fpTResolution = dynamic_cast<TH2F*> (fOutput->FindObject("fpTResolution"));
1231 fpTResolution->FitSlicesY();
1232 fpTResolution->Write();
1235 fMultAll = dynamic_cast<TH1F*> (fOutput->FindObject("fMultAll"));
1239 fMultTr = dynamic_cast<TH1F*> (fOutput->FindObject("fMultTr"));
1243 fMultVtx = dynamic_cast<TH1F*> (fOutput->FindObject("fMultVtx"));
1247 for (Int_t i=0; i<8; ++i)
1249 fDeltaPhi[i] = dynamic_cast<TH2*> (fOutput->FindObject(Form("fDeltaPhi_%d", i)));
1251 fDeltaPhi[i]->Write();
1254 fEventStats = dynamic_cast<TH2F*> (fOutput->FindObject("fEventStats"));
1256 fEventStats->Write();
1258 fPIDParticles = dynamic_cast<TH1F*> (fOutput->FindObject("fPIDParticles"));
1260 fPIDParticles->Write();
1262 fPIDTracks = dynamic_cast<TH1F*> (fOutput->FindObject("fPIDTracks"));
1264 fPIDTracks->Write();
1266 //fdNdEtaCorrection->DrawHistograms();
1268 Printf("Writting result to %s", fileName.Data());
1270 if (fPIDParticles && fPIDTracks)
1272 TDatabasePDG* pdgDB = new TDatabasePDG;
1274 for (Int_t i=0; i <= fPIDParticles->GetNbinsX()+1; ++i)
1275 if (fPIDParticles->GetBinContent(i) > 0)
1277 TObject* pdgParticle = pdgDB->GetParticle((Int_t) fPIDParticles->GetBinCenter(i));
1278 printf("PDG = %d (%s): generated: %d, reconstructed: %d, ratio: %f\n", (Int_t) fPIDParticles->GetBinCenter(i), (pdgParticle) ? pdgParticle->GetName() : "not found", (Int_t) fPIDParticles->GetBinContent(i), (Int_t) fPIDTracks->GetBinContent(i), ((fPIDTracks->GetBinContent(i) > 0) ? fPIDParticles->GetBinContent(i) / fPIDTracks->GetBinContent(i) : -1));
1289 Bool_t AlidNdEtaCorrectionTask::SignOK(TParticlePDG* particle)
1291 // returns if a particle with this sign should be counted
1292 // this is determined by the value of fSignMode, which should have the same sign
1294 // if fSignMode is 0 all particles are counted
1301 printf("WARNING: not counting a particle that does not have a pdg particle\n");
1305 Double_t charge = particle->Charge();