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>
25 #include <Riostream.h>
32 #include <TObjArray.h>
33 #include <TParticle.h>
38 #include "AliAnalysisManager.h"
40 #include "AliCFManager.h"
42 #include "AliAODEvent.h"
43 #include "AliESDInputHandler.h"
44 #include "AliESDtrack.h"
45 #include "AliVertexerTracks.h"
46 #include "AliESDVertex.h"
48 #include "AliMCEventHandler.h"
49 #include "AliMCEvent.h"
50 #include "AliMCParticle.h"
51 #include "AliPIDResponse.h"
53 #include "AliHFEpid.h"
54 #include "AliHFEcuts.h"
55 #include "AliHFEdca.h"
56 #include "AliHFEtools.h"
58 #include "AliAnalysisTaskDCA.h"
61 //____________________________________________________________
62 AliAnalysisTaskDCA::AliAnalysisTaskDCA():
63 AliAnalysisTaskSE("Impact Parameter Resolution and Pull Analysis")
72 , fMinNprimVtxContrbutor(0x0)
80 , fDataVertexList(0x0)
85 , fHfeDataDcaList(0x0)
93 //____________________________________________________________
94 AliAnalysisTaskDCA::AliAnalysisTaskDCA(const char * name):
95 AliAnalysisTaskSE(name)
104 , fMinNprimVtxContrbutor(0x0)
112 , fDataVertexList(0x0)
117 , fHfeDataDcaList(0x0)
121 // Default constructor
123 DefineInput(0, TChain::Class());
124 DefineOutput(1, TH1I::Class());
125 DefineOutput(2, TList::Class());
129 Int_t nMinTPCcluster = 100;
130 Float_t maxDcaXY = 0.5;
131 Float_t maxDcaZ = 1.0;
133 AliHFEcuts *hfecuts = new AliHFEcuts;
134 hfecuts->CreateStandardCuts();
135 hfecuts->SetMinNClustersTPC(nMinTPCcluster);
136 hfecuts->SetCutITSpixel(AliHFEextraCuts::kFirst);
137 hfecuts->SetCheckITSLayerStatus(kFALSE);
138 hfecuts->SetMaxImpactParam(maxDcaXY, maxDcaZ);
141 fHFEpid = new AliHFEpid("PIDforDCAanalysis");
145 //____________________________________________________________
146 AliAnalysisTaskDCA::AliAnalysisTaskDCA(const AliAnalysisTaskDCA &ref):
147 AliAnalysisTaskSE(ref)
148 , fPlugins(ref.fPlugins)
150 , fHFEpid(ref.fHFEpid)
151 , fPIDdetectors(ref.fPIDdetectors)
152 , fPIDstrategy(ref.fPIDstrategy)
155 , fNclustersITS(ref.fNclustersITS)
156 , fMinNprimVtxContrbutor(ref.fMinNprimVtxContrbutor)
157 , fNEvents(ref.fNEvents)
158 , fResidualList(ref.fResidualList)
159 , fPullList(ref.fPullList)
160 , fDcaList(ref.fDcaList)
161 , fKfDcaList(ref.fKfDcaList)
162 , fMcVertexList(ref.fMcVertexList)
163 , fDataDcaList(ref.fDataDcaList)
164 , fDataVertexList(ref.fDataVertexList)
165 , fDataPullList(ref.fDataPullList)
166 , fMcPidList(ref.fMcPidList)
167 , fDataPidList(ref.fDataPidList)
168 , fHfeDcaList(ref.fHfeDcaList)
169 , fHfeDataDcaList(ref.fHfeDataDcaList)
170 , fOutput(ref.fOutput)
175 AliInfo("Copy Constructor");
179 //____________________________________________________________
180 AliAnalysisTaskDCA &AliAnalysisTaskDCA::operator=(const AliAnalysisTaskDCA &ref){
182 // Assignment operator
184 if(this == &ref) return *this;
185 AliAnalysisTaskSE::operator=(ref);
186 fPlugins = ref.fPlugins;
188 fHFEpid = ref.fHFEpid;
189 fPIDdetectors = ref.fPIDdetectors;
190 fPIDstrategy = ref.fPIDstrategy;
193 fNclustersITS = ref.fNclustersITS;
194 fMinNprimVtxContrbutor = ref.fMinNprimVtxContrbutor;
195 fNEvents = ref.fNEvents;
196 fResidualList = ref.fResidualList;
197 fPullList = ref.fPullList;
198 fDcaList = ref.fDcaList;
199 fKfDcaList = ref.fKfDcaList;
200 fMcVertexList = ref.fMcVertexList;
201 fDataDcaList = ref.fDataDcaList;
202 fDataVertexList = ref.fDataVertexList;
203 fDataPullList = ref.fDataPullList;
204 fMcPidList = ref.fMcPidList;
205 fDataPidList = ref.fDataPidList;
206 fHfeDcaList = ref.fHfeDcaList;
207 fHfeDataDcaList = ref.fHfeDataDcaList;
208 fOutput = ref.fOutput;
213 //____________________________________________________________
214 AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){
219 if(fHFEpid) delete fHFEpid;
220 if(fCFM) delete fCFM;
221 if(fDCA) delete fDCA;
222 if(fNEvents) delete fNEvents;
224 fResidualList->Clear();
225 delete fResidualList;
243 fMcVertexList->Clear();
244 delete fMcVertexList;
248 fDataDcaList->Clear();
253 fDataVertexList->Clear();
254 delete fDataVertexList;
257 fDataPullList->Clear();
258 delete fDataPullList;
262 fMcPidList -> Clear();
266 fDataPidList -> Clear();
271 fHfeDcaList->Clear();
275 if(fHfeDataDcaList) {
276 fHfeDataDcaList->Clear();
277 delete fHfeDataDcaList;
287 //____________________________________________________________
288 void AliAnalysisTaskDCA::UserCreateOutputObjects(){
289 // create output objects
292 //printf("\n=====UserCreateOutputObjects=====\n");
294 // Automatic determination of the analysis mode
295 AliVEventHandler *inputHandler = dynamic_cast<AliVEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
297 AliError("NoEvent Handler available");
301 if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
305 if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
310 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
311 if(!fOutput) fOutput = new TList;
312 // Initialize correction Framework and Cuts
313 fCFM = new AliCFManager;
314 MakeParticleContainer();
315 // Temporary fix: Initialize particle cuts with 0x0
316 for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
317 fCFM->SetParticleCutsList(istep, 0x0);
319 AliWarning("Cuts not available. Default cuts will be used");
320 fCuts = new AliHFEcuts;
321 fCuts->CreateStandardCuts();
324 fCuts->Initialize(fCFM);
326 if(!fHFEpid) AliWarning("Hello, fHFEpid is not available");
327 cout<<" Hello this is a cout "<<endl<<endl;
329 if(GetPlugin(kHFEpid)) {
330 fHFEpid->SetHasMCData(HasMCData());
331 fHFEpid->AddDetector("TOF", 0);
332 fHFEpid->AddDetector("TPC", 1);
333 cout<<endl<<" ---> TPC and TOF added to the PID"<<endl;
334 fHFEpid->ConfigureTOF();
335 fHFEpid->ConfigureTPCdefaultCut();
336 fHFEpid->InitializePID();
339 // dca study----------------------------------
342 if(!fDCA) fDCA = new AliHFEdca;
343 if(!fResidualList) fResidualList = new TList();
344 if(!fPullList) fPullList = new TList();
345 if(!fDcaList) fDcaList = new TList();
346 if(!fKfDcaList) fKfDcaList = new TList();
347 if(!fMcVertexList) fMcVertexList = new TList();
348 if(!fDataDcaList) fDataDcaList = new TList();
349 if(!fDataVertexList) fDataVertexList = new TList();
350 if(!fDataPullList) fDataPullList = new TList();
351 if(!fMcPidList) fMcPidList = new TList();
352 if(!fDataPidList) fDataPidList = new TList();
354 if(!fHfeDcaList) fHfeDcaList = new TList();
355 if(!fHfeDataDcaList) fHfeDataDcaList = new TList();
358 if(GetPlugin(kImpactPar) ) {
359 fDCA->CreateHistogramsResidual(fResidualList);
360 fDCA->CreateHistogramsPull(fPullList);
361 fDCA->CreateHistogramsDca(fDcaList);
362 fOutput->AddAt(fResidualList,0);
363 fOutput->AddAt(fPullList,1);
364 fOutput->AddAt(fDcaList,2);
366 if(GetPlugin(kKFdca)){
367 fDCA->CreateHistogramsKfDca(fKfDcaList);
368 fOutput->AddAt(fDcaList,3);
370 if(GetPlugin(kPrimVtx)){//<---
371 fDCA->CreateHistogramsVertex(fMcVertexList);
372 fOutput->AddAt(fMcVertexList,4);
374 if(GetPlugin(kCombinedPid)){//<---
375 fDCA->CreateHistogramsPid(fMcPidList);
376 fOutput->AddAt(fMcPidList, 5);
378 if(GetPlugin(kHFEpid)){//<---
379 fDCA->CreateHistogramsHfeDca(fHfeDcaList);
380 fOutput->AddAt(fHfeDcaList, 6);
386 if(GetPlugin(kPrimVtx)){
387 fDCA->CreateHistogramsDataVertex(fDataVertexList);
388 fOutput->AddAt(fDataVertexList,0);
391 if(GetPlugin(kCombinedPid)){
392 fDCA->CreateHistogramsDataDca(fDataDcaList);
393 fDCA->CreateHistogramsDataPull(fDataPullList);
394 fDCA->CreateHistogramsDataPid(fDataPidList);
395 fOutput->AddAt(fDataDcaList,1);
396 fOutput->AddAt(fDataPullList,2);
397 fOutput->AddAt(fDataPidList, 3);
399 if(GetPlugin(kHFEpid)){
400 fDCA->CreateHistogramsHfeDataDca(fHfeDataDcaList);
401 fOutput->AddAt(fHfeDataDcaList, 4);
410 //____________________________________________________________
411 void AliAnalysisTaskDCA::UserExec(Option_t *){
415 //printf("\n=====UserExec=====\n");
416 if(HasMCData()) printf("WITH MC!\n");
418 AliDebug(3, "Processing ESD events");
421 AliError("Reconstructed Event not available");
425 AliDebug(4, Form("MC Event: %p", fMCEvent));
427 AliError("No MC Event, but MC Data required");
433 AliError("HFE cuts not available");
439 if(IsESDanalysis() && HasMCData()){
440 // Protect against missing MC trees
441 AliMCEventHandler *mcH = dynamic_cast<AliMCEventHandler *>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
443 AliError("No MC Event Handler available");
446 if(!mcH->InitOk()) return;
447 if(!mcH->TreeK()) return;
448 if(!mcH->TreeTR()) return;
452 AliPIDResponse *pidResponse = fInputHandler->GetPIDResponse();
454 AliDebug(1, "Using default PID Response");
455 pidResponse = AliHFEtools::GetDefaultPID(HasMCData(), fInputEvent->IsA() == AliAODEvent::Class());
457 fHFEpid->SetPIDResponse(pidResponse);
458 ProcessDcaAnalysis();
460 PostData(1, fNEvents);
461 PostData(2, fOutput);
463 //____________________________________________________________
464 void AliAnalysisTaskDCA::ProcessDcaAnalysis(){
466 //printf("\n=====ProcessDcaAnalysis=====\n");
471 AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
473 AliError("ESD Event required for ESD Analysis");
477 AliMCEvent *fMC = 0x0;
479 fMC = dynamic_cast<AliMCEvent*>(fMCEvent);
481 AliError("MC Event required for Analysis");
486 fNEvents->Fill(1); // original event number before cut
487 fDCA->ApplyExtraCuts(fESD,fMinNprimVtxContrbutor); // cut on primVtx contributors
488 fNEvents->Fill(3); // events number after cut
489 fCFM->SetRecEventInfo(fESD);
492 if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return;
494 AliESDtrack *track = 0x0;
495 AliMCParticle *mctrack = 0x0;
496 AliESDVertex *vtxESDSkip = 0x0;
497 AliHFEpidObject hfetrack;
499 for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
501 track = fESD->GetTrack(itrack);
502 if(HasMCData()) mctrack = dynamic_cast<AliMCParticle *>(fMC->GetTrack(TMath::Abs(track->GetLabel())));
504 // RecPrim: primary cuts
505 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
506 // RecKine: ITSTPC cuts
507 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
508 // HFEcuts: ITS layers cuts
509 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsMCTrack, track)) continue;
511 if(track->GetITSclusters(0)<=fNclustersITS) continue; // require number of ITS clusters
513 // track accepted, do PID
514 hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
515 hfetrack.SetRecTrack(track);
516 if(HasMCData()) hfetrack.SetMCTrack(mctrack);
518 //printf("Track %d passed all the cuts!\n",itrack);
521 if(GetPlugin(kPrimVtx))
522 fDCA->FillHistogramsVtx(fESD, fMC);
523 if(GetPlugin(kImpactPar))
524 fDCA->FillHistogramsDca(fESD, track, fMC);
525 if(GetPlugin(kKFdca))
526 fDCA->FillHistogramsKfDca(fESD, track, fMC);
527 if(GetPlugin(kCombinedPid))
528 fDCA->FillHistogramsPid(track, fMC);
529 if(GetPlugin(kHFEpid)) { // data-like
530 if(fHFEpid->IsSelected(&hfetrack)){
532 // printf("Found an electron in p+p collision! from HFE pid \n");
534 // method from Andrea D 28.05.2010
535 AliVertexerTracks *vertexer = new AliVertexerTracks(fESD->GetMagneticField());
536 vertexer->SetITSMode();
537 vertexer->SetMinClusters(fNclustersITS);
539 skipped[0] = (Int_t)track->GetID();
540 vertexer->SetSkipTracks(1,skipped);
541 vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESD);
542 delete vertexer; vertexer = NULL;
543 if(vtxESDSkip->GetNContributors()<fMinNprimVtxContrbutor) continue;
545 //printf("\n[ABOUT TO FILL HFE DCA: MC!]\n");
546 fDCA->FillHistogramsHfeDataDca(fESD, track, vtxESDSkip);
548 } // plugin for hfepid
552 if(GetPlugin(kPrimVtx))
553 fDCA->FillHistogramsDataVtx(fESD);
554 if(GetPlugin(kCombinedPid)) {
556 // method from Andrea D 28.05.2010
557 AliVertexerTracks *vertexer = new AliVertexerTracks(fESD->GetMagneticField());
558 vertexer->SetITSMode();
559 vertexer->SetMinClusters(fNclustersITS);
561 skipped[0] = (Int_t)track->GetID();
562 vertexer->SetSkipTracks(1,skipped);
563 vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESD);
564 delete vertexer; vertexer = NULL;
565 if(vtxESDSkip->GetNContributors()<fMinNprimVtxContrbutor) continue;
567 fDCA->FillHistogramsDataDca(fESD, track, vtxESDSkip);
568 fDCA->FillHistogramsDataPid(track);
570 if(GetPlugin(kHFEpid)) {
571 if(fHFEpid->IsSelected(&hfetrack)) {
572 // printf("Found an electron in p+p collision! from HFE pid \n");
574 // method from Andrea D 28.05.2010
575 AliVertexerTracks *vertexer = new AliVertexerTracks(fESD->GetMagneticField());
576 vertexer->SetITSMode();
577 vertexer->SetMinClusters(fNclustersITS);
579 skipped[0] = (Int_t)track->GetID();
580 vertexer->SetSkipTracks(1,skipped);
581 vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESD);
582 delete vertexer; vertexer = NULL;
583 if(vtxESDSkip->GetNContributors()<fMinNprimVtxContrbutor) continue;
585 printf("\n[ABOUT TO FILL HFE DCA: DATA!]\n");
586 fDCA->FillHistogramsHfeDataDca(fESD, track,vtxESDSkip);
588 } // plugin for hfepid
596 //____________________________________________________________
597 void AliAnalysisTaskDCA::Terminate(Option_t *){
599 // Terminate not implemented at the moment
601 //printf("\n=====Terminate=====\n");
603 if(GetPlugin(kPostProcess)){
604 fOutput = dynamic_cast<TList *>(GetOutputData(1));
606 AliError("Results not available");
615 //____________________________________________________________
616 void AliAnalysisTaskDCA::Load(TString filename){
618 //printf("\n=====Load=====\n");
620 // no need for postprocessing for the moment
621 TFile *input = TFile::Open(filename.Data());
622 if(!input || input->IsZombie()){
623 AliError("Cannot read file");
633 //____________________________________________________________
634 void AliAnalysisTaskDCA::PostProcess(){
635 // do post processing
636 // should do fitting here for dca resolution
637 // moved to an external macro to do the job
639 //printf("\n=====PostProcess=====\n");
641 TCanvas *c1 = new TCanvas("c1", "number of analyzed events", 300, 400);
643 c1->SaveAs("temp.png");
650 //____________________________________________________________
651 void AliAnalysisTaskDCA::PrintStatus() const {
654 // Print Analysis status
656 printf("\n\tAnalysis Settings\n\t========================================\n");
657 printf("\t Running on %s\n", !HasMCData()?"p+p collision data":"MC sample");
658 printf("\t Cuts: %s\n", (fCuts != NULL) ? "YES" : "NO");
659 printf("\t Impact parameter analysis is %s\n", GetPlugin(kImpactPar)?"ON":"OFF");
660 printf("\t Using AliKFParticle for analysis? %s\n", GetPlugin(kKFdca)?"ON":"OFF");
661 printf("\t Primary vertex analysis is %s\n", GetPlugin(kPrimVtx)?"ON":"OFF");
662 printf("\t Combined pid analysis is %s\n", GetPlugin(kCombinedPid)?"ON":"OFF");
663 printf("\t HFE pid analysis is %s\n", GetPlugin(kHFEpid)?"ON":"OFF");
664 printf("\t Post process analysis is %s\n", GetPlugin(kPostProcess)?"ON":"OFF");
669 //__________________________________________
670 void AliAnalysisTaskDCA::SwitchOnPlugin(Int_t plug){
674 // - analyze impact parameter
677 AliDebug(2,Form("SwitchOnPlugin %d",plug));
681 SETBIT(fPlugins, plug);
684 SETBIT(fPlugins, plug);
687 SETBIT(fPlugins, plug);
690 SETBIT(fPlugins, plug);
693 SETBIT(fPlugins, plug);
696 SETBIT(fPlugins, plug);
699 AliError("Unknown Plugin");
704 //____________________________________________________________
705 void AliAnalysisTaskDCA::MakeParticleContainer(){
707 //printf("\n=====MakeParticleContainer=====\n");
709 // Create the particle container (borrowed from AliAnalysisTaskHFE)
711 const Int_t kNvar = 3 ; //number of variables on the grid:pt,eta, phi
712 const Double_t kPtmin = 0.1, kPtmax = 10.;
713 const Double_t kEtamin = -0.9, kEtamax = 0.9;
714 const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi();
716 //arrays for the number of bins in each dimension
718 iBin[0] = 40; //bins in pt
719 iBin[1] = 8; //bins in eta
720 iBin[2] = 18; // bins in phi
722 //arrays for lower bounds :
723 Double_t* binEdges[kNvar];
724 for(Int_t ivar = 0; ivar < kNvar; ivar++)
725 binEdges[ivar] = new Double_t[iBin[ivar] + 1];
727 //values for bin lower bounds
728 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);
729 for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin + (kEtamax-kEtamin)/iBin[1]*(Double_t)i;
730 for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin + (kPhimax-kPhimin)/iBin[2]*(Double_t)i;
732 //one "container" for MC
733 const Int_t kNcutStepsESDtrack = AliHFEcuts::kNcutStepsRecTrack + 1;
734 const Int_t kNcutStepsTrack = AliHFEcuts::kNcutStepsMCTrack + kNcutStepsESDtrack;
735 AliCFContainer* container = new AliCFContainer("container","container for tracks", (kNcutStepsTrack + 1 + 2*(kNcutStepsESDtrack + 1)), kNvar, iBin);
737 //setting the bin limits
738 for(Int_t ivar = 0; ivar < kNvar; ivar++)
739 container -> SetBinLimits(ivar, binEdges[ivar]);
740 fCFM->SetParticleContainer(container);
742 //create correlation matrix for unfolding
743 Int_t thnDim[2*kNvar];
744 for (int k=0; k<kNvar; k++) {
745 //first half : reconstructed
748 thnDim[k+kNvar] = iBin[k];
754 //____________________________________________________________
755 void AliAnalysisTaskDCA::AddPIDdetector(TString detector){
758 // Adding PID detector to the task
760 //printf("\n=====AddPIDdetector=====\n");
762 if(!fPIDdetectors.Length())
763 fPIDdetectors = detector;
765 fPIDdetectors += ":" + detector;