1 Double_t tofReso = 85.;
3 /**************************************************************/
4 /*** HISTOS AND BINNING ***************************************/
5 /**************************************************************/
7 /**************************************************************/
13 const Char_t *chargeName[kNCharges] = {
17 /**************************************************************/
27 /**************************************************************/
28 const Int_t NcentralityBins = 10;
29 Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
30 /**************************************************************/
31 const Int_t NpBins = 46;
32 Double_t pBin[NpBins + 1] = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
33 /**************************************************************/
34 const Int_t NclsBins = 200;
35 Double_t clsBin[NclsBins + 1];
36 Double_t clsMin = 0., clsMax = 200., clsStep = (clsMax - clsMin) / NclsBins;
37 /**************************************************************/
38 const Int_t NtpcdeltaBins = 200;
39 Double_t tpcdeltaBin[NtpcdeltaBins + 1];
40 Double_t tpcdeltaMin = -100., tpcdeltaMax = 100., tpcdeltaStep = (tpcdeltaMax - tpcdeltaMin) / NtpcdeltaBins;
41 /**************************************************************/
42 const Int_t NtpcgainBins = 200;
43 Double_t tpcgainBin[NtpcgainBins + 1];
44 Double_t tpcgainMin = 0., tpcgainMax = 2., tpcgainStep = (tpcgainMax - tpcgainMin) / NtpcgainBins;
45 /**************************************************************/
46 const Int_t NsigmaBins = 20;
47 Double_t sigmaBin[NsigmaBins + 1];
48 Double_t sigmaMin = -5., sigmaMax = 5., sigmaStep = (sigmaMax - sigmaMin) / NsigmaBins;
49 /**************************************************************/
50 Int_t NparamsBins[kNHistoParams] = {NcentralityBins, NpBins, NclsBins, NtpcdeltaBins, NtpcgainBins, NsigmaBins};
51 Double_t *paramBin[kNHistoParams] = {centralityBin, pBin, clsBin, tpcdeltaBin, tpcgainBin, sigmaBin};
52 /**************************************************************/
54 /**************************************************************/
57 TPCcalib(const Char_t *filename, Int_t evMax = kMaxInt, Int_t startEv = 0)
60 /* include path for ACLic */
61 gSystem->AddIncludePath("-I$ALICE_ROOT/include");
62 gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
64 gSystem->Load("libANALYSIS");
65 gSystem->Load("libANALYSISalice");
66 /* build analysis task class */
67 gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
68 gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
69 gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
71 /* open file, get tree and connect */
72 TFile *filein = TFile::Open(filename);
73 TTree *treein = (TTree *)filein->Get("aodTree");
74 printf("got \"aodTree\": %d entries\n", treein->GetEntries());
75 AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
76 TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
77 AliAnalysisTrack *analysisTrack = NULL;
78 treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
79 treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
81 /**************************************************************/
82 /*** HISTOS ***************************************************/
83 /**************************************************************/
85 /* run-time binning */
86 for (Int_t ibin = 0; ibin < NclsBins + 1; ibin++)
87 clsBin[ibin] = clsMin + ibin * clsStep;
88 for (Int_t ibin = 0; ibin < NtpcdeltaBins + 1; ibin++)
89 tpcdeltaBin[ibin] = tpcdeltaMin + ibin * tpcdeltaStep;
90 for (Int_t ibin = 0; ibin < NtpcgainBins + 1; ibin++)
91 tpcgainBin[ibin] = tpcgainMin + ibin * tpcgainStep;
92 for (Int_t ibin = 0; ibin < NsigmaBins + 1; ibin++)
93 sigmaBin[ibin] = sigmaMin + ibin * sigmaStep;
96 THnSparse *hTPCcalib[AliPID::kSPECIES][kNCharges];
97 for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
98 for (Int_t icharge = 0; icharge< kNCharges; icharge++) {
99 hTPCcalib[ipart][icharge] = new THnSparseF(Form("hTPCcalib_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", kNHistoParams, NparamsBins);
100 for (Int_t iparam = 0; iparam < kNHistoParams; iparam++) {
101 hTPCcalib[ipart][icharge]->SetBinEdges(iparam, paramBin[iparam]);
106 /**************************************************************/
107 /**************************************************************/
108 /**************************************************************/
110 /* TOF PID response */
111 AliTOFPIDResponse tofResponse;
112 tofResponse.SetTimeResolution(tofReso);
113 /* TPC PID response */
114 AliTPCPIDResponse *tpcResponse = AliAnalysisTrack::GetTPCResponse();
116 /* start stopwatch */
120 /* loop over events */
124 Double_t ptpc, dedx, bethe, deltadedx, dedx_sigma, tpcsignal;
125 Double_t p, time, time_sigma, timezero, timezero_sigma, tof, tof_sigma, texp, texp_sigma, deltat, deltat_sigma, tofsignal;
126 Double_t tpctofsignal;
127 Double_t param[kNHistoParams];
128 for (Int_t iev = startEv; iev < treein->GetEntries() && iev < evMax; iev++) {
130 treein->GetEvent(iev);
131 if (iev % 100 == 0) printf("iev = %d\n", iev);
133 if (!analysisEvent->AcceptVertex()) continue;
134 /* check collision candidate */
135 if (!analysisEvent->IsCollisionCandidate()) continue;
136 /* check centrality quality */
137 if (analysisEvent->GetCentralityQuality() != 0.) continue;
139 /*** ACCEPTED EVENT ***/
141 /* apply time-zero TOF correction */
142 analysisEvent->ApplyTimeZeroTOFCorrection();
145 param[kCentrality] = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
147 /* loop over tracks */
148 for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
150 analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
151 if (!analysisTrack) continue;
152 /* check accepted track */
153 if (!analysisTrack->AcceptTrack()) continue;
155 charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
157 /*** ACCEPTED TRACK ***/
160 if (!analysisTrack->HasTOFPID() || !analysisTrack->HasTPCPID()) continue;
162 /*** ACCEPTED TRACK WITH TPC+TOF PID ***/
164 /* apply expected time correction */
165 analysisTrack->ApplyTOFExpectedTimeCorrection();
168 p = analysisTrack->GetP();
171 dedx = analysisTrack->GetTPCdEdx();
172 dedxN = analysisTrack->GetTPCdEdxN();
173 ptpc = analysisTrack->GetTPCmomentum();
175 param[kTPCNcls] = dedxN;
178 time = analysisTrack->GetTOFTime();
179 time_sigma = tofReso;
180 timezero = analysisEvent->GetTimeZeroTOF(p);
181 timezero_sigma = analysisEvent->GetTimeZeroTOFSigma(p);
182 tof = time - timezero;
183 tof_sigma = TMath::Sqrt(time_sigma * time_sigma + timezero_sigma * timezero_sigma);
185 /* loop over particle IDs */
186 for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
189 if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(ipart))) > 0.5) continue;
191 /*** ACCEPTED TRACK WITHIN CORRECT RAPIDITY ***/
193 /* TOF expected time */
194 texp = analysisTrack->GetTOFExpTime(ipart);
195 texp_sigma = analysisTrack->GetTOFExpTimeSigma(ipart);
199 deltat_sigma = TMath::Sqrt(tof_sigma * tof_sigma + texp_sigma * texp_sigma);
200 tofsignal = deltat / deltat_sigma;
201 param[kTOFsignal] = tofsignal;
203 /* check TOF PID with 3-sigma cut */
204 if (TMath::Abs(tofsignal) > 3.) continue;
206 /*** ACCEPTED TRACK WITH COMPATIBLE TOF PID ***/
209 bethe = tpcResponse->GetExpectedSignal(ptpc, ipart);
210 deltadedx = dedx - bethe;
211 param[kTPCdelta] = deltadedx;
212 param[kTPCgain] = dedx / bethe;
215 hTPCcalib[ipart][charge]->Fill(param);
217 } /* end of loop over particle IDs */
218 } /* end of loop over tracks */
219 } /* end of loop over events */
221 /* start stopwatch */
226 TFile *fileout = TFile::Open(Form("TPCcalib.%s", filename), "RECREATE");
227 for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
228 for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
229 hTPCcalib[ipart][icharge]->Write();
236 /**************************************************************/
238 TPCcalib_delta(const Char_t *filename, Int_t ipart, Int_t icharge, Float_t tofsigmaMin = -3., Float_t tofsigmaMax = 3.)
241 Double_t ptMin[AliPID::kSPECIES] = {0., 0., 0.5, 0.5, 0.5};
242 Double_t ptMax[AliPID::kSPECIES] = {0.5, 0., 1.5, 1.5, 2.0};
244 /* load HistoUtils */
245 gROOT->LoadMacro("HistoUtils.C");
248 TFile *filein = TFile::Open(filename);
249 THnSparseF *hTPCcalib = (THnSparseF *)filein->Get(Form("hTPCcalib_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
251 /* set momentum range */
252 hTPCcalib->GetAxis(kPtpc)->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
254 /* set TOF pid range */
255 // hTPCcalib->GetAxis(kTOFsignal)->SetRangeUser(tofsigmaMin + 0.001, tofsigmaMax - 0.001);
257 /* minimum-bias projection */
258 hTPCcalib->GetAxis(kCentrality)->SetRange(1, NcentralityBins);
259 TH2 *hDeltaPtpc = hTPCcalib->Projection(kTPCdelta, kPtpc);
260 TObjArray *oaTPCdelta_mb = HistoUtils_FitPeak(NULL, hDeltaPtpc, 5, 3., 3., 100, Form("hTPCdelta_mb_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
263 /* convert to bethe-blok */
264 TH1D *hTPCdelta_mb = (TH1D *)oaTPCdelta_mb->At(1);
265 TH1D *hTPCbethe_mb = TPCcalib_delta2bethe(hTPCdelta_mb, ipart, Form("hTPCbethe_mb_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
267 /* centrality projections */
268 TObjArray *oaTPCdelta_cent[NcentralityBins];
269 for (Int_t icent = 0; icent < NcentralityBins; icent++) {
271 hTPCcalib->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
272 hDeltaPtpc = hTPCcalib->Projection(kTPCdelta, kPtpc);
273 oaTPCdelta_cent[icent] = HistoUtils_FitPeak(NULL, hDeltaPtpc, 5, 3., 3., 100, Form("hTPCdelta_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
279 /**************************************************************/
282 TPCcalib_BetheBlochAleph(Double_t min, Double_t max)
285 TF1 *f = new TF1("fBetheBlochAleph", "[0] * AliExternalTrackParam::BetheBlochAleph(x, [1], [2], [3], [4], [5])", min, max);
286 f->SetParameter(0, 50.);
287 f->SetParameter(1, 0.0283086);
288 f->SetParameter(2, 2.63394e+01);
289 f->SetParameter(3, 5.04114e-11);
290 f->SetParameter(4, 2.12543);
291 f->SetParameter(5, 4.88663);
296 /**************************************************************/
299 TPCcalib_fitBetheBloch(TGraphErrors *g, TF1 *f, Int_t param = -1)
303 for (Int_t ipar = 0; ipar < 6; ipar++)
305 f->FixParameter(ipar, f->GetParameter(ipar));
307 f->ReleaseParameter(ipar);
310 for (Int_t ipar = 0; ipar < 6; ipar++)
311 f->ReleaseParameter(ipar);
317 /**************************************************************/
319 TPCcalib_bethe(const Char_t *filename, Int_t icent = -1, Float_t tofsigmaMin = -3., Float_t tofsigmaMax = 3.)
322 Double_t ptMin[AliPID::kSPECIES] = {0., 0., 0.5, 0.5, 0.5};
323 Double_t ptMax[AliPID::kSPECIES] = {0., 0., 1.5, 1.5, 2.0};
325 /* set centrality name */
326 Char_t centName[1024];
327 if (icent < 0 || icent >= NcentralityBins)
328 sprintf(centName, "cent0090");
330 sprintf(centName, "cent%02d%02d", , centralityBin[icent], centralityBin[icent + 1]);
332 /* load HistoUtils */
333 gROOT->LoadMacro("HistoUtils.C");
336 TFile *filein = TFile::Open(filename);
339 TFile *fileout = TFile::Open(Form("TPCcalib_bethe_%s.%s", centName, filename), "RECREATE");
341 /* loop over particles and charges */
342 TH1D *hTPCbethe[AliPID::kSPECIES][kNCharges];
343 TGraphErrors *gTPCbethe = new TGraphErrors();
344 gTPCbethe->SetName("gTPCbethe");
346 for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
347 for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
349 /* check momentum range */
350 if (ptMax[ipart] == 0. || ptMax[ipart] < ptMin[ipart]) continue;
353 THnSparseF *hTPCcalib = (THnSparseF *)filein->Get(Form("hTPCcalib_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
355 /* set centrality range */
356 if (icent < 0 || icent >= NcentralityBins)
357 hTPCcalib->GetAxis(kCentrality)->SetRange(1, NcentralityBins);
359 hTPCcalib->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
361 /* set TOF pid range */
362 // hTPCcalib->GetAxis(kTOFsignal)->SetRangeUser(tofsigmaMin + 0.001, tofsigmaMax - 0.001);
364 /* set momentum range */
365 hTPCcalib->GetAxis(kPtpc)->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
367 /* minimum-bias projection */
368 TH2 *hDeltaPtpc = hTPCcalib->Projection(kTPCdelta, kPtpc);
369 TObjArray *oaTPCdelta = HistoUtils_FitPeak(NULL, hDeltaPtpc, 5, 3., 3., 100, Form("hTPCdelta_%s_%s_%s", centName, AliPID::ParticleName(ipart), chargeName[icharge]));
372 /* convert to bethe-blok */
373 TH1D *hTPCdelta = (TH1D *)oaTPCdelta->At(1);
374 hTPCbethe[ipart][icharge] = TPCcalib_delta2bethe(hTPCdelta, ipart, Form("hTPCbethe_%s_%s_%s", centName, AliPID::ParticleName(ipart), chargeName[icharge]));
379 /* add points to graph */
380 for (Int_t ibin = 0; ibin < hTPCbethe[ipart][icharge]->GetNbinsX(); ibin++) {
381 gTPCbethe->SetPoint(nPoints, hTPCbethe[ipart][icharge]->GetBinCenter(ibin + 1), hTPCbethe[ipart][icharge]->GetBinContent(ibin + 1));
382 gTPCbethe->SetPointError(nPoints, 0.5 * hTPCbethe[ipart][icharge]->GetBinWidth(ibin + 1), hTPCbethe[ipart][icharge]->GetBinError(ibin + 1));
388 hTPCbethe[ipart][icharge]->Write();
392 TF1 *fBethe = TPCcalib_BetheBlochAleph(0.1, 1.e3);
393 for (Int_t i = 0; i < 50; i++)
394 for (Int_t ii = 0; ii < 6; ii++)
395 TPCcalib_fitBetheBloch(gTPCbethe, fBethe, ii);
396 TPCcalib_fitBetheBloch(gTPCbethe, fBethe, -1);
400 gTPCbethe->Write("gTPCbethe");
401 fBethe->Write("fBetheBlochAleph");
410 /**************************************************************/
412 TPCcalib_gain(const Char_t *filename, Int_t ipart, Int_t icharge, Float_t tofsigmaMin = -3., Float_t tofsigmaMax = 3.)
415 /* load HistoUtils */
416 gROOT->LoadMacro("HistoUtils.C");
419 TFile *filein = TFile::Open(filename);
420 THnSparseF *hTPCcalib = (THnSparseF *)filein->Get(Form("hTPCcalib_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
422 /* set TOF pid range */
423 // hTPCcalib->GetAxis(kTOFsignal)->SetRangeUser(tofsigmaMin + 0.001, tofsigmaMax - 0.001);
425 /* minimum-bias projection */
426 hTPCcalib->GetAxis(kCentrality)->SetRange(1, NcentralityBins);
427 TH2 *hGainPtpc = hTPCcalib->Projection(kTPCgain, kPtpc);
428 TObjArray *oaTPCgain_mb = HistoUtils_FitPeak(NULL, hGainPtpc, 5, 3., 3., 100, Form("hTPCgain_mb_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
430 TH1D *hmb = (TH1D *)oaTPCgain_mb->At(1);
432 /* centrality projections */
433 TObjArray *oaTPCgain_cent[NcentralityBins];
434 for (Int_t icent = 0; icent < NcentralityBins; icent++) {
436 hTPCcalib->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
437 hGainPtpc = hTPCcalib->Projection(kTPCgain, kPtpc);
438 oaTPCgain_cent[icent] = HistoUtils_FitPeak(NULL, hGainPtpc, 5, 3., 3., 100, Form("hTPCgain_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
439 TH1D *hcent = (TH1D *)oaTPCgain_cent[icent]->At(1);
446 /**************************************************************/
449 TPCcalib_delta2bethe(TH1D *hDelta, Int_t ipart, const Char_t *name = "hTPCbethe")
452 Int_t nbins = hDelta->GetNbinsX();
453 Float_t *xbins = new Float_t[nbins + 1];
454 for(Int_t ibin = 0; ibin <= nbins; ibin++)
455 xbins[ibin] = hDelta->GetBinLowEdge(ibin + 1) / AliPID::ParticleMass(ipart);
457 TH1D *hBethe = new TH1D(name, "", nbins, xbins);
458 AliTPCPIDResponse tpcResponse;
459 Double_t ptpc, delta, bethe, deltae;
460 for (Int_t ibin = 0; ibin < nbins; ibin++) {
461 ptpc = hDelta->GetBinCenter(ibin + 1);
462 delta = hDelta->GetBinContent(ibin + 1);
463 deltae = hDelta->GetBinError(ibin + 1);
464 bethe = tpcResponse.GetExpectedSignal(ptpc, ipart);
465 hBethe->SetBinContent(ibin + 1, bethe + delta);
466 hBethe->SetBinError(ibin + 1, deltae);