2 /**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
17 //------------------------------------------------------------------------------
18 // Implementation of AliPerformancePtCalib class. It fills histograms with ESD or
19 // TPC track information to study charge/pt spectra.
20 // To analyse the output of AliPerformancePtCalib use AliPerfAnalyzeInvPt class:
21 // Projection of charge/pt vs theta and vs phi resp. histoprams will be fitted
22 // with either polynomial or gaussian fit function to extract minimum position of
24 // Fit options and theta, phi bins can be set by user.
25 // Attention: use the Set functions of AliPerformancePtCalib when running
26 // AliPerformancePtCalib::Analyse()
27 // The result of the analysis (histograms/graphs) are stored in the folder which is
28 // a data member of AliPerformancePtCalib.
30 // Author: S.Schuchmann 11/13/2009
31 // sschuchm@ikf.uni-frankfurt.de
32 //------------------------------------------------------------------------------
36 // after running the performance task, read the file, and get component
38 TFile f("Output.root");
39 AliPerformancePtCalib * compObj = (AliPerformancePtCalib*)coutput->FindObject("AliPerformancePtCalib");
41 // set phi and theta bins for fitting and analyse comparison data
42 compObj->SetProjBinsTheta(thetaBins,nThetaBins,minPhi, maxPhi);
43 compObj->SetProjBinsPhi(phiBins,nPhiBins,minTheta,maxTheta);
44 compObj->SetMakeFitOption(kFALSE,exclRange,fitRange);
45 compObj->SetDoRebin(rebin);
47 //details see functions of this class
49 // the output histograms/graphs will be stored in the folder "folderRes"
50 compObj->GetAnalysisFolder()->ls("*");
52 // user can save whole comparison object (or only folder with anlysed histograms)
53 // in the seperate output file (e.g.)
54 TFile fout("Analysed_InvPt.root","recreate");
55 compObj->Write(); // compObj->GetAnalysisFolder()->Write();
61 #include "THnSparse.h"
66 #include "AliESDEvent.h"
67 #include "AliESDtrack.h"
68 #include "AliESDfriendTrack.h"
69 #include "AliESDfriend.h"
70 #include "AliESDtrackCuts.h"
71 #include "AliESDpid.h"
73 #include "AliPerfAnalyzeInvPt.h"
74 #include "AliPerformancePtCalib.h"
78 ClassImp(AliPerformancePtCalib)
80 //________________________________________________________________________
81 AliPerformancePtCalib::AliPerformancePtCalib(const Char_t* name, const Char_t* title):
82 AliPerformanceObject(name,title),
84 // option parameter for AliPerformancePtCalib::Analyse()
96 // option parameter for user defined charge/pt shift
108 fHistInvPtPtThetaPhi(0),
110 fHistPrimaryVertexPosX(0),
111 fHistPrimaryVertexPosY(0),
112 fHistPrimaryVertexPosZ(0),
113 fHistTrackMultiplicity(0),
114 fHistTrackMultiplicityCuts(0),
116 fHistTPCMomentaPosP(0),
117 fHistTPCMomentaNegP(0),
118 fHistTPCMomentaPosPt(0),
119 fHistTPCMomentaNegPt(0),
135 fOptTPC = kTRUE; // read TPC tracks yes/no
141 //esd track cut options
142 fEtaAcceptance = 0.8;
144 // options for function AliPerformancePtCalibMC::Analyse()
145 fFitGaus = kFALSE;// use gaussian function for fitting charge/pt yes/no
146 fNThetaBins = 0; //number of theta bins
147 fNPhiBins = 0; //number of phi bins
148 fMaxPhi = 6.5;// max phi for 2D projection on theta and charge/pt axis
149 fMinPhi = 0.0;// min phi for 2D projection on theta and charge/pt axis
150 fMaxTheta = 3.0;// max theta for 2D projection on phi and charge/pt axis
151 fMinTheta = 0.0;// min theta for 2D projection on phi and charge/pt axis
152 fRange = 0; //fit range around 0
153 fExclRange =0; //range of rejection of points around 0
157 for(Int_t i=0; i<100; i++) {
165 //________________________________________________________________________
166 AliPerformancePtCalib::~AliPerformancePtCalib() {
171 if(fList) delete fList;
173 if( fHistInvPtPtThetaPhi) delete fHistInvPtPtThetaPhi;fHistInvPtPtThetaPhi=0;
174 if(fHistPtShift0) delete fHistPtShift0;fHistPtShift0=0;
175 if(fHistPrimaryVertexPosX) delete fHistPrimaryVertexPosX;fHistPrimaryVertexPosX=0;
176 if(fHistPrimaryVertexPosY) delete fHistPrimaryVertexPosY;fHistPrimaryVertexPosY=0;
177 if(fHistPrimaryVertexPosZ) delete fHistPrimaryVertexPosZ;fHistPrimaryVertexPosZ=0;
178 if(fHistTrackMultiplicity) delete fHistTrackMultiplicity;fHistTrackMultiplicity=0;
179 if(fHistTrackMultiplicityCuts) delete fHistTrackMultiplicityCuts;fHistTrackMultiplicityCuts=0;
181 if(fHistTPCMomentaPosP) delete fHistTPCMomentaPosP;fHistTPCMomentaPosP=0;
182 if(fHistTPCMomentaNegP) delete fHistTPCMomentaNegP;fHistTPCMomentaNegP=0;
183 if(fHistTPCMomentaPosPt) delete fHistTPCMomentaPosPt;fHistTPCMomentaPosPt=0;
184 if(fHistTPCMomentaNegPt) delete fHistTPCMomentaNegPt ;fHistTPCMomentaNegPt=0;
185 if(fHistUserPtShift) delete fHistUserPtShift;fHistUserPtShift=0;
186 if(fHistdedxPions) delete fHistdedxPions;fHistdedxPions=0;
188 if(fESDTrackCuts) delete fESDTrackCuts;fESDTrackCuts=0;
190 if(fESDpid) delete fESDpid;fESDpid=0;
192 if(fAnalysisFolder) delete fAnalysisFolder; fAnalysisFolder=0;
195 //________________________________________________________________________
196 void AliPerformancePtCalib::Init()
203 fAnalysisFolder = CreateFolder("folderPt_TPC","Analysis Pt Resolution Folder");
206 fHistPrimaryVertexPosX = new TH1F("fHistPrimaryVertexPosX", "Primary Vertex Position X;Primary Vertex Position X (cm);Events",100,-0.5,0.5);
207 fList->Add(fHistPrimaryVertexPosX);
208 fHistPrimaryVertexPosY = new TH1F("fHistPrimaryVertexPosY", "Primary Vertex Position Y;Primary Vertex Position Y (cm);Events",100,-0.5,0.5);
209 fList->Add(fHistPrimaryVertexPosY);
210 fHistPrimaryVertexPosZ = new TH1F("fHistPrimaryVertexPosZ", "Primary Vertex Position Z;Primary Vertex Position Z (cm);Events",200,-2.0,2.0);
211 fList->Add(fHistPrimaryVertexPosZ);
213 fHistTrackMultiplicity = new TH1F("fHistTrackMultiplicity", "Multiplicity distribution;Number of tracks;Events", 250, 0, 250);
214 fList->Add(fHistTrackMultiplicity);
215 fHistTrackMultiplicityCuts = new TH1F("fHistTrackMultiplicityCuts", "Multiplicity distribution;Number of tracks after cuts;Events", 250, 0, 250);
216 fList->Add(fHistTrackMultiplicityCuts);
219 //pt shift 0 only needed if shift in 1/pt is applied
220 fHistPtShift0 = new TH1F("fHistPtShift0","1/pt dN/pt vs. pt of ESD track ",800,-40.0,40.0);
221 fList->Add(fHistPtShift0);
223 // THnSparse for 1/pt and pt spectra vs angles
224 const Int_t invPtDims = 4;
230 Double_t xminInvPt[invPtDims] = {-4.5,-40.0,fMinTheta,fMinPhi};
231 Double_t xmaxInvPt[invPtDims] = {4.5,40.0,fMaxTheta,fMaxPhi};
232 Int_t binsInvPt[invPtDims] = {450,400,150,163};
235 fHistInvPtPtThetaPhi = new THnSparseF("fHistInvPtPtThetaPhi","1/pt vs pt vs #theta vs #phi ",invPtDims,binsInvPt,xminInvPt,xmaxInvPt);
236 fList->Add(fHistInvPtPtThetaPhi);
238 // momentum test histos
239 fHistTPCMomentaPosP = new TH2F("fHistTPCMomentaPosP","TPC p vs global esd track p pos",300,0.0,15.0,300,0.0,15.0);
240 fList->Add(fHistTPCMomentaPosP);
241 fHistTPCMomentaNegP = new TH2F("fHistTPCMomentaNegP","TPC p vs global esd track p neg",300,0.0,15.0,300,0.0,15.0);
242 fList->Add(fHistTPCMomentaNegP);
243 fHistTPCMomentaPosPt = new TH2F("fHistTPCMomentaPosPt","TPC pt vs global esd track pt pos",300,0.0,15.0,300,0.0,15.0);
244 fList->Add(fHistTPCMomentaPosPt);
245 fHistTPCMomentaNegPt = new TH2F("fHistTPCMomentaNegPt","TPC pt vs global esd track pt neg",300,0.0,15.0,300,0.0,15.0);
246 fList->Add(fHistTPCMomentaNegPt);
248 //user pt shift check
249 fHistUserPtShift = new TH1F("fHistUserPtShift","user defined shift in 1/pt",100,-0.5,1.5);
250 fList->Add(fHistUserPtShift);
252 fHistdedxPions = new TH2F ("fHistdedxPions","dEdx of pions ident. via kPID vs signed Pt",300,-15.05,15.05,200,0.0,400.0);
253 fList->Add(fHistdedxPions);
255 fESDpid = new AliESDpid();
261 //________________________________________________________________________
262 void AliPerformancePtCalib::SetPtShift(const Double_t shiftVal ) {
263 //set user defined shift in charge/pt
265 if(shiftVal) { fShift=kTRUE; fDeltaInvP = shiftVal; }
268 //________________________________________________________________________
269 void AliPerformancePtCalib::Exec(AliMCEvent* const /*mcEvent*/, AliESDEvent *const esdEvent, AliESDfriend * const /*esdFriend*/, const Bool_t /*bUseMC*/, const Bool_t /*bUseESDfriend*/)
271 //exec: read esd or tpc
274 Printf("no esd track cut");
279 Printf("ERROR: Event not available");
283 if (!(esdEvent->GetNumberOfTracks())) return;
286 //vertex info for cut
287 const AliESDVertex *vtx = esdEvent->GetPrimaryVertex();
288 if (!vtx->GetStatus()) return ;
290 //histo fo user defined shift in charge/pt
291 if(fShift) fHistUserPtShift->Fill(fDeltaInvP);
294 fHistTrackMultiplicity->Fill(esdEvent->GetNumberOfTracks());
297 // read primary vertex info
298 Double_t tPrimaryVtxPosition[3];
299 const AliESDVertex *primaryVtx = esdEvent->GetPrimaryVertexTPC();
301 tPrimaryVtxPosition[0] = primaryVtx->GetXv();
302 tPrimaryVtxPosition[1] = primaryVtx->GetYv();
303 tPrimaryVtxPosition[2] = primaryVtx->GetZv();
305 fHistPrimaryVertexPosX->Fill(tPrimaryVtxPosition[0]);
306 fHistPrimaryVertexPosY->Fill(tPrimaryVtxPosition[1]);
307 fHistPrimaryVertexPosZ->Fill(tPrimaryVtxPosition[2]);
310 //_fill histos for pt spectra and shift of transverse momentum
313 for(Int_t j = 0;j<esdEvent->GetNumberOfTracks();j++){// track loop
314 AliESDtrack *esdTrack = esdEvent->GetTrack(j);
315 if(!esdTrack) continue;
319 if(!fESDTrackCuts->AcceptTrack(esdTrack))continue;
324 if(fOptTPC){ //TPC tracks
325 const AliExternalTrackParam *tpcTrack = esdTrack->GetTPCInnerParam();
326 if(!tpcTrack) continue;
327 if(fabs(tpcTrack->Eta())>= fEtaAcceptance) continue;
329 Double_t signedPt = tpcTrack->GetSignedPt();
334 fESDpid->GetTPCResponse().SetBetheBlochParameters(0.0283086,2.63394e+01,5.04114e-11, 2.12543e+00,4.88663e+00);
336 if( TMath::Abs(fESDpid->NumberOfSigmasTPC(esdTrack,AliPID::kPion)) >1) continue;
337 fHistdedxPions->Fill(signedPt,esdTrack->GetTPCsignal());
340 Double_t invPt = 0.0;
342 invPt = 1.0/signedPt;
344 fHistPtShift0->Fill(signedPt);
346 if(fShift){Printf("user shift of momentum SET to non zero value!");
347 invPt += fDeltaInvP; //shift momentum for tests
348 if(invPt) signedPt = 1.0/invPt;
351 Double_t theta = tpcTrack->Theta();
352 Double_t phi = tpcTrack->Phi();
354 Double_t momAng[4] = {invPt,signedPt,theta,phi};
355 fHistInvPtPtThetaPhi->Fill(momAng);
357 Double_t pTPC = tpcTrack->GetP();
358 Double_t pESD = esdTrack->GetP();
359 Double_t ptESD = esdTrack->GetSignedPt();
361 if(esdTrack->GetSign()>0){
362 //compare momenta ESD track and TPC track
363 fHistTPCMomentaPosP->Fill(fabs(pESD),fabs(pTPC));
364 fHistTPCMomentaPosPt->Fill(fabs(ptESD),fabs(signedPt));
367 fHistTPCMomentaNegP->Fill(fabs(pESD),fabs(pTPC));
368 fHistTPCMomentaNegPt->Fill(fabs(ptESD),fabs(signedPt));
376 if(fabs(esdTrack->Eta())> fEtaAcceptance) continue;
377 Double_t invPt = 0.0;
378 Double_t signedPt = esdTrack->GetSignedPt();
380 invPt = 1.0/signedPt;
382 fHistPtShift0->Fill(signedPt);
384 if(fShift){Printf("user shift of momentum SET to non zero value!");
385 invPt += fDeltaInvP;//shift momentum for tests
386 if(invPt) signedPt = 1.0/invPt;
389 Double_t theta = esdTrack->Theta();
390 Double_t phi = esdTrack->Phi();
391 Double_t momAng[4] = {invPt,signedPt,theta,phi};
392 fHistInvPtPtThetaPhi->Fill(momAng);
398 fHistTrackMultiplicityCuts->Fill(count);
400 //______________________________________________________________________________________________________________________
402 void AliPerformancePtCalib::Analyse()
404 // analyse charge/pt spectra in bins of theta and phi. Bins can be set by user
406 THnSparseF *copyTHnSparseTheta = (THnSparseF*)fHistInvPtPtThetaPhi->Clone("copyTHnSparseTheta");
407 if(!copyTHnSparseTheta) return;
408 copyTHnSparseTheta->GetAxis(3)->SetRangeUser(fMinPhi,fMaxPhi);
409 TH2F *histInvPtTheta = (TH2F*)copyTHnSparseTheta->Projection(2,0);
411 THnSparseF *copyTHnSparsePhi = (THnSparseF*)fHistInvPtPtThetaPhi->Clone("copyTHnSparsePhi");
412 if(!copyTHnSparsePhi) return;
413 copyTHnSparsePhi->GetAxis(2)->SetRangeUser(fMinTheta,fMaxTheta);
414 TH2F *histInvPtPhi = (TH2F*)copyTHnSparsePhi->Projection(3,0);
416 AliPerfAnalyzeInvPt *ana = new AliPerfAnalyzeInvPt("AliPerfAnalyzeInvPt","AliPerfAnalyzeInvPt");
420 TH1::AddDirectory(kFALSE);
422 ana->SetProjBinsTheta(fThetaBins,fNThetaBins);
423 ana->SetProjBinsPhi(fPhiBins,fNPhiBins);
424 ana->SetMakeFitOption(fFitGaus,fExclRange,fRange);
425 if(fDoRebin) ana->SetDoRebin(fRebin);
426 TObjArray *aFolderObj = new TObjArray;
427 if(!aFolderObj) return;
429 ana->StartAnalysis(histInvPtTheta,histInvPtPhi,aFolderObj);
431 // export objects to analysis folder
432 fAnalysisFolder = ExportToFolder(aFolderObj);
434 // delete only TObjArray
435 if(aFolderObj) delete aFolderObj;
440 //______________________________________________________________________________________________________________________
441 TFolder* AliPerformancePtCalib::ExportToFolder(TObjArray * array)
443 // recreate folder every time and export objects to new one
445 AliPerformancePtCalib * comp=this;
446 TFolder *folder = comp->GetAnalysisFolder();
449 TFolder *newFolder = 0;
451 Int_t size = array->GetSize();
454 // get name and title from old folder
455 name = folder->GetName();
456 title = folder->GetTitle();
462 newFolder = CreateFolder(name.Data(),title.Data());
463 newFolder->SetOwner();
465 // add objects to folder
467 newFolder->Add(array->At(i));
475 //______________________________________________________________________________________________________________________
476 Long64_t AliPerformancePtCalib::Merge(TCollection* const list)
478 // Merge list of objects (needed by PROOF)
486 TIterator* iter = list->MakeIterator();
489 // collection of generated histograms
491 while((obj = iter->Next()) != 0)
493 AliPerformancePtCalib* entry = dynamic_cast<AliPerformancePtCalib*>(obj);
494 if (entry == 0) continue;
495 fHistInvPtPtThetaPhi->Add(entry->fHistInvPtPtThetaPhi);
497 fHistPtShift0->Add(entry->fHistPtShift0);
498 fHistPrimaryVertexPosX->Add(entry->fHistPrimaryVertexPosX);
499 fHistPrimaryVertexPosY->Add(entry->fHistPrimaryVertexPosY);
500 fHistPrimaryVertexPosZ->Add(entry->fHistPrimaryVertexPosZ);
501 fHistTrackMultiplicity->Add(entry->fHistTrackMultiplicity);
502 fHistTrackMultiplicityCuts->Add(entry->fHistTrackMultiplicityCuts);
504 fHistTPCMomentaPosP->Add(entry->fHistTPCMomentaPosP);
505 fHistTPCMomentaNegP->Add(entry->fHistTPCMomentaNegP);
506 fHistTPCMomentaPosPt->Add(entry->fHistTPCMomentaPosPt);
507 fHistTPCMomentaNegPt->Add(entry->fHistTPCMomentaNegPt);
508 fHistdedxPions->Add(entry->fHistdedxPions);
515 //______________________________________________________________________________________________________________________
516 TFolder* AliPerformancePtCalib::CreateFolder(TString name,TString title) {
517 // create folder for analysed histograms
520 folder = new TFolder(name.Data(),title.Data());
524 //______________________________________________________________________________________________________________________
525 void AliPerformancePtCalib::SetProjBinsPhi(const Double_t *phiBinArray,const Int_t nphBins, const Double_t minTheta, const Double_t maxTheta){
526 // set phi bins for Analyse()
527 //set phi bins as array and set number of this array which is equal to number of bins analysed
528 //the last analysed bin will always be the projection from first to last bin in the array
532 for(Int_t k = 0;k<fNPhiBins;k++){
533 fPhiBins[k] = phiBinArray[k];
535 Printf("AliPerformancePtCalib::SetProjBinsPhi: number of bins in phi set to %i",fNPhiBins);
537 else Printf("Warning AliPerformancePtCalib::SetProjBinsPhi: number of bins in phi NOT set!!! Default values are taken.");
539 if(fabs(minTheta-maxTheta)<0.001){
540 Printf("AliPerformancePtCalib::SetProjBinsPhi: theta range for projection on phi and charge/pt is too small. whole range of theta selected.");
543 Printf("AliPerformancePtCalib::SetProjBinsPhi: theta range for projection on phi and charge/pt is selected by user: %1.3f - %1.3f rad",minTheta,maxTheta);
544 fMinTheta = minTheta;
545 fMaxTheta = maxTheta;
549 //____________________________________________________________________________________________________________________________________________
550 void AliPerformancePtCalib::SetProjBinsTheta(const Double_t *thetaBinArray, const Int_t nthBins, const Double_t minPhi, const Double_t maxPhi){
551 // set theta bins for Analyse()
552 //set theta bins as array and set number of this array which is equal to number of bins analysed
553 //the last analysed bin will always be the projection from first to last bin in the array
555 fNThetaBins = nthBins;
556 for(Int_t k = 0;k<fNThetaBins;k++){
557 fThetaBins[k] = thetaBinArray[k];
559 Printf("AliPerformancePtCalib::SetProjBinsTheta: number of bins in theta set to %i",fNThetaBins);
561 else Printf("Warning AliPerformancePtCalib::SetProjBinsTheta: number of bins in theta NOT set!!! Default values are taken.");
563 if(fabs(minPhi-maxPhi)<0.001){
564 Printf("AliPerformancePtCalib::SetProjBinsTheta: phi range for projection on theta and charge/pt is too small. whole range of phi selected.");
567 Printf("AliPerformancePtCalib::SetProjBinsTheta: phi range for projection on theta and charge/pt is selected by user: %1.3f - %1.3f rad",minPhi,maxPhi);
572 //____________________________________________________________________________________________________________________________________________
573 void AliPerformancePtCalib::SetMakeFitOption(const Bool_t setGausFit, const Double_t exclusionR,const Double_t fitR ){
574 //set the fit options:
575 //for usage of gaussian function instead of polynomial (default) set setGausFit=kTRUE
576 //set the range of rejection of points around 0 via exclusionR
577 //set the fit range around 0 with fitR
580 fFitGaus = setGausFit;
581 fExclRange = exclusionR;
583 if(fFitGaus) Printf("AliPerformancePtCalib::SetMakeFitOption: set MakeGausFit with fit range %2.3f and exclusion range in fabs(1/pt): %2.3f",fRange,fExclRange);
584 else Printf("AliPerformancePtCalib::SetMakeFitOption: set standard polynomial fit with fit range %2.3f and exclusion range in fabs(1/pt): %2.3f",fRange,fExclRange);