1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // impact parameter resolution and pull study
18 // for tracks which survivied the particle cuts
22 // Hongyan Yang <hongyan@physi.uni-heidelberg.de>
23 // Carlo Bombonati <carlo.bombonati@cern.ch>
31 #include <TObjArray.h>
32 #include <TParticle.h>
37 #include "AliAnalysisManager.h"
39 #include "AliCFManager.h"
41 #include "AliESDInputHandler.h"
42 #include "AliESDtrack.h"
43 #include "AliVertexerTracks.h"
44 #include "AliESDVertex.h"
46 #include "AliMCEventHandler.h"
47 #include "AliMCEvent.h"
48 #include "AliMCParticle.h"
50 #include "AliESDpid.h"
51 #include "AliHFEpid.h"
52 #include "AliHFEcuts.h"
53 #include "AliHFEdca.h"
55 #include "AliAnalysisTaskDCA.h"
58 //____________________________________________________________
59 AliAnalysisTaskDCA::AliAnalysisTaskDCA():
60 AliAnalysisTaskSE("Impact Parameter Resolution and Pull Analysis")
70 , fMinNprimVtxContrbutor(0x0)
78 , fDataVertexList(0x0)
83 , fHfeDataDcaList(0x0)
89 DefineInput(0, TChain::Class());
90 DefineOutput(1, TH1I::Class());
91 DefineOutput(2, TList::Class());
93 fDefaultPID = new AliESDpid;
94 fHFEpid = new AliHFEpid("PIDforDCAanalysis");
98 //____________________________________________________________
99 AliAnalysisTaskDCA::AliAnalysisTaskDCA(const char * name):
100 AliAnalysisTaskSE(name)
110 , fMinNprimVtxContrbutor(0x0)
118 , fDataVertexList(0x0)
123 , fHfeDataDcaList(0x0)
127 // Default constructor
129 DefineInput(0, TChain::Class());
130 DefineOutput(1, TH1I::Class());
131 DefineOutput(2, TList::Class());
133 fDefaultPID = new AliESDpid;
134 fHFEpid = new AliHFEpid("PIDforDCAanalysis");
138 //____________________________________________________________
139 AliAnalysisTaskDCA::AliAnalysisTaskDCA(const AliAnalysisTaskDCA &ref):
140 AliAnalysisTaskSE(ref)
141 , fPlugins(ref.fPlugins)
143 , fDefaultPID(ref.fDefaultPID)
144 , fHFEpid(ref.fHFEpid)
145 , fPIDdetectors(ref.fPIDdetectors)
146 , fPIDstrategy(ref.fPIDstrategy)
149 , fNclustersITS(ref.fNclustersITS)
150 , fMinNprimVtxContrbutor(ref.fMinNprimVtxContrbutor)
151 , fNEvents(ref.fNEvents)
152 , fResidualList(ref.fResidualList)
153 , fPullList(ref.fPullList)
154 , fDcaList(ref.fDcaList)
155 , fKfDcaList(ref.fKfDcaList)
156 , fMcVertexList(ref.fMcVertexList)
157 , fDataDcaList(ref.fDataDcaList)
158 , fDataVertexList(ref.fDataVertexList)
159 , fDataPullList(ref.fDataPullList)
160 , fMcPidList(ref.fMcPidList)
161 , fDataPidList(ref.fDataPidList)
162 , fHfeDcaList(ref.fHfeDcaList)
163 , fHfeDataDcaList(ref.fHfeDataDcaList)
164 , fOutput(ref.fOutput)
173 //____________________________________________________________
174 AliAnalysisTaskDCA &AliAnalysisTaskDCA::operator=(const AliAnalysisTaskDCA &ref){
176 // Assignment operator
178 if(this == &ref) return *this;
179 AliAnalysisTaskSE::operator=(ref);
180 fPlugins = ref.fPlugins;
182 fDefaultPID = ref.fDefaultPID;
183 fHFEpid = ref.fHFEpid;
184 fPIDdetectors = ref.fPIDdetectors;
185 fPIDstrategy = ref.fPIDstrategy;
188 fNclustersITS = ref.fNclustersITS;
189 fMinNprimVtxContrbutor = ref.fMinNprimVtxContrbutor;
190 fNEvents = ref.fNEvents;
191 fResidualList = ref.fResidualList;
192 fPullList = ref.fPullList;
193 fDcaList = ref.fDcaList;
194 fKfDcaList = ref.fKfDcaList;
195 fMcVertexList = ref.fMcVertexList;
196 fDataDcaList = ref.fDataDcaList;
197 fDataVertexList = ref.fDataVertexList;
198 fDataPullList = ref.fDataPullList;
199 fMcPidList = ref.fMcPidList;
200 fDataPidList = ref.fDataPidList;
201 fHfeDcaList = ref.fHfeDcaList;
202 fHfeDataDcaList = ref.fHfeDataDcaList;
203 fOutput = ref.fOutput;
208 //____________________________________________________________
209 AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){
214 if(fDefaultPID) delete fDefaultPID;
215 if(fHFEpid) delete fHFEpid;
216 if(fCFM) delete fCFM;
217 if(fDCA) delete fDCA;
218 if(fNEvents) delete fNEvents;
220 fResidualList->Clear();
221 delete fResidualList;
239 fMcVertexList->Clear();
240 delete fMcVertexList;
244 fDataDcaList->Clear();
249 fDataVertexList->Clear();
250 delete fDataVertexList;
253 fDataPullList->Clear();
254 delete fDataPullList;
258 fMcPidList -> Clear();
262 fDataPidList -> Clear();
267 fHfeDcaList->Clear();
271 if(fHfeDataDcaList) {
272 fHfeDataDcaList->Clear();
273 delete fHfeDataDcaList;
283 //____________________________________________________________
284 void AliAnalysisTaskDCA::UserCreateOutputObjects(){
285 // create output objects
289 // Automatic determination of the analysis mode
290 AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
292 AliError("NoEvent Handler available");
296 if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
300 if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
305 fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 5, -0.5, 4.5); // Number of Events neccessary for the analysis and not a QA histogram
306 if(!fOutput) fOutput = new TList;
307 // Initialize correction Framework and Cuts
308 fCFM = new AliCFManager;
309 MakeParticleContainer();
310 // Temporary fix: Initialize particle cuts with 0x0
311 for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
312 fCFM->SetParticleCutsList(istep, 0x0);
314 AliWarning("Cuts not available. Default cuts will be used");
315 fCuts = new AliHFEcuts;
316 fCuts->CreateStandardCuts();
319 fCuts->Initialize(fCFM);
321 if(!fHFEpid) printf("hallo, fHFEpid is not available\n");
323 if(fHFEpid && GetPlugin(kHFEpid)) {
324 fHFEpid->SetHasMCData(HasMCData());
325 fHFEpid->AddDetector("TPC", 0);
326 fHFEpid->InitializePID();
329 // dca study----------------------------------
332 if(!fDCA) fDCA = new AliHFEdca;
333 if(!fResidualList) fResidualList = new TList();
334 if(!fPullList) fPullList = new TList();
335 if(!fDcaList) fDcaList = new TList();
336 if(!fKfDcaList) fKfDcaList = new TList();
337 if(!fMcVertexList) fMcVertexList = new TList();
338 if(!fDataDcaList) fDataDcaList = new TList();
339 if(!fDataVertexList) fDataVertexList = new TList();
340 if(!fDataPullList) fDataPullList = new TList();
341 if(!fMcPidList) fMcPidList = new TList();
342 if(!fDataPidList) fDataPidList = new TList();
344 if(!fHfeDcaList) fHfeDcaList = new TList();
345 if(!fHfeDataDcaList) fHfeDataDcaList = new TList();
348 if(GetPlugin(kImpactPar) ) {
349 fDCA->CreateHistogramsResidual(fResidualList);
350 fDCA->CreateHistogramsPull(fPullList);
351 fDCA->CreateHistogramsDca(fDcaList);
352 fOutput->AddAt(fResidualList,0);
353 fOutput->AddAt(fPullList,1);
354 fOutput->AddAt(fDcaList,2);
356 if(GetPlugin(kKFdca)){
357 fDCA->CreateHistogramsKfDca(fKfDcaList);
358 fOutput->AddAt(fDcaList,3);
360 if(GetPlugin(kPrimVtx)){
361 fDCA->CreateHistogramsVertex(fMcVertexList);
362 fOutput->AddAt(fMcVertexList,4);
364 if(GetPlugin(kCombinedPid)){
365 fDCA->CreateHistogramsPid(fMcPidList);
366 fOutput->AddAt(fMcPidList, 5);
368 if(GetPlugin(kHFEpid)){
369 fDCA->CreateHistogramsHfeDca(fHfeDcaList);
370 fOutput->AddAt(fHfeDcaList, 6);
376 if(GetPlugin(kPrimVtx)){
377 fDCA->CreateHistogramsDataVertex(fDataVertexList);
378 fOutput->AddAt(fDataVertexList,0);
381 if(GetPlugin(kCombinedPid)){
382 fDCA->CreateHistogramsDataDca(fDataDcaList);
383 fDCA->CreateHistogramsDataPull(fDataPullList);
384 fDCA->CreateHistogramsDataPid(fDataPidList);
385 fOutput->AddAt(fDataDcaList,1);
386 fOutput->AddAt(fDataPullList,2);
387 fOutput->AddAt(fDataPidList, 3);
389 if(GetPlugin(kHFEpid)){
390 fDCA->CreateHistogramsHfeDataDca(fHfeDataDcaList);
391 fOutput->AddAt(fHfeDataDcaList, 4);
400 //____________________________________________________________
401 void AliAnalysisTaskDCA::UserExec(Option_t *){
406 AliDebug(3, "Processing ESD events");
409 AliError("Reconstructed Event not available");
413 AliDebug(4, Form("MC Event: %p", fMCEvent));
415 AliError("No MC Event, but MC Data required");
421 AliError("HFE cuts not available");
427 if(IsESDanalysis() && HasMCData()){
428 // Protect against missing MC trees
429 AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
431 AliError("No MC Event Handler available");
434 if(!mcH->InitOk()) return;
435 if(!mcH->TreeK()) return;
436 if(!mcH->TreeTR()) return;
439 if(!IsAODanalysis()) {
440 AliESDInputHandler *inH = dynamic_cast<AliESDInputHandler *>(fInputHandler);
442 AliError("No ESD Event Handler available");
445 AliESDpid *workingPID = inH->GetESDpid();
447 AliDebug(1, "Using ESD PID from the input handler");
448 fHFEpid->SetESDpid(workingPID);
450 AliDebug(1, "Using default ESD PID");
451 fHFEpid->SetESDpid(fDefaultPID);
453 ProcessDcaAnalysis();
457 PostData(1, fNEvents);
458 PostData(2, fOutput);
460 //____________________________________________________________
461 void AliAnalysisTaskDCA::ProcessDcaAnalysis(){
467 AliMCEvent *fMC = 0x0;
469 AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
471 AliError("ESD Event required for ESD Analysis");
476 fMC = dynamic_cast<AliMCEvent*>(fMCEvent);
478 AliError("MC Event required for Analysis");
484 fNEvents->Fill(1); // original event number before cut
485 fDCA->ApplyExtraCuts(fESD,fMinNprimVtxContrbutor); // cut on primVtx contributors
486 fNEvents->Fill(3); // events number after cut
488 AliESDtrack *track = 0x0;
489 AliMCParticle *mctrack = 0x0;
491 fCFM->SetRecEventInfo(fESD);
494 if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return;
496 for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
498 track = fESD->GetTrack(itrack);
499 if(HasMCData())mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(TMath::Abs(track->GetLabel())));
501 // RecPrim: primary cuts
502 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
503 // RecKine: ITSTPC cuts
504 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
505 // HFEcuts: ITS layers cuts
506 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
508 if(track->GetITSclusters(0)<=fNclustersITS) continue; // require number of ITS clusters
510 // track accepted, do PID
511 AliHFEpidObject hfetrack;
512 hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
513 hfetrack.SetRecTrack(track);
514 if(HasMCData()) hfetrack.SetMCTrack(mctrack);
517 if(GetPlugin(kPrimVtx))
518 fDCA->FillHistogramsVtx(fESD, fMC);
519 if(GetPlugin(kImpactPar))
520 fDCA->FillHistogramsDca(fESD, track, fMC);
521 if(GetPlugin(kKFdca))
522 fDCA->FillHistogramsKfDca(fESD, track, fMC);
523 if(GetPlugin(kCombinedPid))
524 fDCA->FillHistogramsPid(track, fMC);
525 if(GetPlugin(kHFEpid)) {
526 if(fHFEpid->IsSelected(&hfetrack))
527 fDCA->FillHistogramsHfeDca(fESD, track, fMC);
528 } // plugin for hfepid
532 if(GetPlugin(kPrimVtx))
533 fDCA->FillHistogramsDataVtx(fESD);
534 if(GetPlugin(kCombinedPid)) {
536 // method from Andrea D 28.05.2010
537 AliVertexerTracks *vertexer = new AliVertexerTracks(fESD->GetMagneticField());
538 vertexer->SetITSMode();
539 vertexer->SetMinClusters(fNclustersITS);
541 skipped[0] = (Int_t)track->GetID();
542 vertexer->SetSkipTracks(1,skipped);
543 AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESD);
544 delete vertexer; vertexer = NULL;
545 if(vtxESDSkip->GetNContributors()<fMinNprimVtxContrbutor) continue;
547 fDCA->FillHistogramsDataDca(fESD, track, vtxESDSkip);
548 fDCA->FillHistogramsDataPid(track);
550 if(GetPlugin(kHFEpid)) {
551 if(fHFEpid->IsSelected(&hfetrack)) {
552 // printf("Found an electron in p+p collision! from HFE pid \n");
553 fDCA->FillHistogramsHfeDataDca(fESD, track);
555 } // plugin for hfepid
563 //____________________________________________________________
564 void AliAnalysisTaskDCA::Terminate(Option_t *){
566 // Terminate not implemented at the moment
569 if(GetPlugin(kPostProcess)){
570 fOutput = dynamic_cast<TList *>(GetOutputData(1));
572 AliError("Results not available");
581 //____________________________________________________________
582 void AliAnalysisTaskDCA::Load(TString filename){
583 // no need for postprocessing for the moment
584 TFile *input = TFile::Open(filename.Data());
585 if(!input || input->IsZombie()){
586 AliError("Cannot read file");
596 //____________________________________________________________
597 void AliAnalysisTaskDCA::PostProcess(){
598 // do post processing
599 // should do fitting here for dca resolution
600 // moved to an external macro to do the job
603 TCanvas *c1 = new TCanvas("c1", "number of analyzed events", 300, 400);
605 c1->SaveAs("temp.png");
612 //____________________________________________________________
613 void AliAnalysisTaskDCA::PrintStatus() const {
616 // Print Analysis status
618 printf("\n\tAnalysis Settings\n\t========================================\n");
619 printf("\t Running on %s\n", !HasMCData()?"p+p collision data":"MC sample");
620 printf("\t Cuts: %s\n", (fCuts != NULL) ? "YES" : "NO");
621 printf("\t Impact parameter analysis is %s\n", GetPlugin(kImpactPar)?"ON":"OFF");
622 printf("\t Using AliKFParticle for analysis? %s\n", GetPlugin(kKFdca)?"ON":"OFF");
623 printf("\t Primary vertex analysis is %s\n", GetPlugin(kPrimVtx)?"ON":"OFF");
624 printf("\t Combined pid analysis is %s\n", GetPlugin(kCombinedPid)?"ON":"OFF");
625 printf("\t HFE pid analysis is %s\n", GetPlugin(kHFEpid)?"ON":"OFF");
626 printf("\t Post process analysis is %s\n", GetPlugin(kPostProcess)?"ON":"OFF");
631 //__________________________________________
632 void AliAnalysisTaskDCA::SwitchOnPlugin(Int_t plug){
636 // - analyze impact parameter
641 SETBIT(fPlugins, plug);
644 SETBIT(fPlugins, plug);
647 SETBIT(fPlugins, plug);
650 SETBIT(fPlugins, plug);
653 SETBIT(fPlugins, plug);
656 SETBIT(fPlugins, plug);
659 AliError("Unknown Plugin");
664 //____________________________________________________________
665 void AliAnalysisTaskDCA::MakeParticleContainer(){
667 // Create the particle container (borrowed from AliAnalysisTaskHFE)
669 const Int_t kNvar = 3 ; //number of variables on the grid:pt,eta, phi
670 const Double_t kPtmin = 0.1, kPtmax = 10.;
671 const Double_t kEtamin = -0.9, kEtamax = 0.9;
672 const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi();
674 //arrays for the number of bins in each dimension
676 iBin[0] = 40; //bins in pt
677 iBin[1] = 8; //bins in eta
678 iBin[2] = 18; // bins in phi
680 //arrays for lower bounds :
681 Double_t* binEdges[kNvar];
682 for(Int_t ivar = 0; ivar < kNvar; ivar++)
683 binEdges[ivar] = new Double_t[iBin[ivar] + 1];
685 //values for bin lower bounds
686 for(Int_t i=0; i<=iBin[0]; i++) binEdges[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/iBin[0]*(Double_t)i);
687 for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin + (kEtamax-kEtamin)/iBin[1]*(Double_t)i;
688 for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
690 //one "container" for MC
691 const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1;
692 const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack;
693 AliCFContainer* container = new AliCFContainer("container","container for tracks", (kNcutStepsTrack + 1 + 2*(kNcutStepsESDtrack + 1)), kNvar, iBin);
695 //setting the bin limits
696 for(Int_t ivar = 0; ivar < kNvar; ivar++)
697 container -> SetBinLimits(ivar, binEdges[ivar]);
698 fCFM->SetParticleContainer(container);
700 //create correlation matrix for unfolding
701 Int_t thnDim[2*kNvar];
702 for (int k=0; k<kNvar; k++) {
703 //first half : reconstructed
706 thnDim[k+kNvar] = iBin[k];
712 //____________________________________________________________
713 void AliAnalysisTaskDCA::AddPIDdetector(TString detector){
716 // Adding PID detector to the task
719 if(!fPIDdetectors.Length())
720 fPIDdetectors = detector;
722 fPIDdetectors += ":" + detector;