]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TOF/AliTOFT0v1.cxx
Savannah bug 71585 fixed (F.Bellini)
[u/mrichter/AliRoot.git] / TOF / AliTOFT0v1.cxx
CommitLineData
536031f2 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
6a4e212e 16/* $Id: AliTOFT0v1.cxx,v 1.8 2010/01/19 16:32:20 noferini Exp $ */
536031f2 17
18//_________________________________________________________________________
19// This is a TTask that made the calculation of the Time zero using TOF.
20// Description: The algorithm used to calculate the time zero of interaction
21// using TOF detector is the following.
6a4e212e 22// We select in the ESD some "primary" particles - or tracks in the following -
536031f2 23// that strike the TOF detector (the larger part are pions, kaons or protons).
24// We choose a set of 10 selected tracks, for each track You have the length
6a4e212e 25// of the track when the TOF is reached,
26// the momentum and the time of flight
536031f2 27// given by the TOF detector.
536031f2 28// Let consider now only one set of 10 tracks (the algorithm is the same for all sets).
29// Assuming the (mass) hypothesis that each track can be AUT a pion, AUT a kaon, AUT a proton,
30// we consider all the 3 at 10 possible cases.
31// For each track in each (mass) configuration
32// (a configuration can be e.g. pion/pion/kaon/proton/pion/proton/kaon/kaon/pion/pion)
33// we calculate the time zero (we know in fact the velocity of the track after
34// the assumption about its mass, the time of flight given by the TOF, and the
35// corresponding path travelled till the TOF detector). Then for each mass configuration we have
36// 10 time zero and we can calculate the ChiSquare for the current configuration using the
37// weighted mean over all 10 time zero.
38// We call the best assignment the mass configuration that gives the minimum value of the ChiSquare.
39// We plot the weighted mean over all 10 time zero for the best assignment,
40// the ChiSquare for the best assignment and the corresponding confidence level.
41// The strong assumption is the MC selection of primary particles. It will be introduced
42// in the future also some more realistic simulation about this point.
43// Use case:
44// root [0] AliTOFT0v1 * tzero = new AliTOFT0v1("galice.root")
45// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
46// root [1] tzero->ExecuteTask()
47// root [2] tzero->ExecuteTask("tim")
48// // available parameters:
49// tim - print benchmarking information
50// all - print usefull informations about the number of misidentified tracks
51// and a comparison about the true configuration (known from MC) and the best
52// assignment
53// Different Selections for pp and Pb-Pb: Momentum Range, Max Time, # pions
54//-- Author: F. Pierella
6a4e212e 55//-- Mod By Silvia Arcelli, Francesco Noferini, Barbara Guerzoni
536031f2 56//////////////////////////////////////////////////////////////////////////////
57
536031f2 58#include "AliESDtrack.h"
8f589502 59#include "AliESDEvent.h"
03bd764d 60#include "AliTOFT0v1.h"
2a258f40 61#include "TBenchmark.h"
62#include "AliPID.h"
63#include "AliESDpid.h"
536031f2 64
65ClassImp(AliTOFT0v1)
66
67//____________________________________________________________________________
2a258f40 68AliTOFT0v1::AliTOFT0v1(AliESDpid *extPID):
5b4ed716 69 TObject(),
03bd764d 70 fLowerMomBound(0.5),
5b4ed716 71 fUpperMomBound(3),
8f589502 72 fTimeCorr(0.),
2a258f40 73 fEvent(0x0),
74 fPIDesd(extPID)
536031f2 75{
8f589502 76 //
77 // default constructor
78 //
2a258f40 79 if(AliPID::ParticleMass(0) == 0) new AliPID();
80
81 if(!fPIDesd){
82 fPIDesd = new AliESDpid();
83 }
536031f2 84
5b4ed716 85 Init(NULL);
86
8f589502 87}
88
8f589502 89//____________________________________________________________________________
2a258f40 90AliTOFT0v1::AliTOFT0v1(AliESDEvent* event,AliESDpid *extPID):
5b4ed716 91 TObject(),
03bd764d 92 fLowerMomBound(0.5),
5b4ed716 93 fUpperMomBound(3.0),
8f589502 94 fTimeCorr(0.),
2a258f40 95 fEvent(event),
96 fPIDesd(extPID)
8f589502 97{
98 //
99 // real constructor
100 //
2a258f40 101 if(AliPID::ParticleMass(0) == 0) new AliPID();
536031f2 102
2a258f40 103 if(!fPIDesd){
104 fPIDesd = new AliESDpid();
105 }
5b4ed716 106
2a258f40 107 Init(event);
8f589502 108
536031f2 109}
8f589502 110//____________________________________________________________________________
111AliTOFT0v1& AliTOFT0v1::operator=(const AliTOFT0v1 &tzero)
112{
113 //
114 // assign. operator
115 //
116
117 if (this == &tzero)
118 return *this;
119
120 fLowerMomBound=tzero.fLowerMomBound;
121 fUpperMomBound=tzero.fUpperMomBound;
8f589502 122 fTimeCorr=tzero.fTimeCorr;
123 fEvent=tzero.fEvent;
8f589502 124 fT0SigmaT0def[0]=tzero.fT0SigmaT0def[0];
125 fT0SigmaT0def[1]=tzero.fT0SigmaT0def[1];
126 fT0SigmaT0def[2]=tzero.fT0SigmaT0def[2];
127 fT0SigmaT0def[3]=tzero.fT0SigmaT0def[3];
128
129 return *this;
130}
5b4ed716 131
536031f2 132//____________________________________________________________________________
133AliTOFT0v1::~AliTOFT0v1()
134{
135 // dtor
8f589502 136 fEvent=NULL;
137
536031f2 138}
5b4ed716 139//____________________________________________________________________________
140
141void
142AliTOFT0v1::Init(AliESDEvent *event)
143{
144
145 /*
146 * init
147 */
148
149 fEvent = event;
150 fT0SigmaT0def[0]=0.;
151 fT0SigmaT0def[1]=0.6;
152 fT0SigmaT0def[2]=0.;
153 fT0SigmaT0def[3]=0.;
154
155}
156
536031f2 157//____________________________________________________________________________
158Double_t * AliTOFT0v1::DefineT0(Option_t *option)
159{
8f589502 160 // Caluclate the Event Time using the ESD TOF time
161
2a258f40 162 TBenchmark *bench=new TBenchmark();
163 bench->Start("t0computation");
164
5b4ed716 165 fT0SigmaT0def[0]=0.;
166 fT0SigmaT0def[1]=0.600;
167 fT0SigmaT0def[2]=0.;
168 fT0SigmaT0def[3]=0.;
536031f2 169
2a258f40 170 const Int_t nmaxtracksinsetMax=10;
171 Int_t nmaxtracksinset=10;
6a4e212e 172// if(strstr(option,"all")){
173// cout << "Selecting primary tracks with momentum between " << fLowerMomBound << " GeV/c and " << fUpperMomBound << " GeV/c" << endl;
174// cout << "Memorandum: 0 means PION | 1 means KAON | 2 means PROTON" << endl;
175// }
536031f2 176
536031f2 177 Int_t nsets=0;
8f589502 178 Int_t nUsedTracks=0;
536031f2 179 Int_t ngoodsetsSel= 0;
180 Float_t t0bestSel[300];
8f589502 181 Float_t eT0bestSel[300];
182 Float_t chiSquarebestSel[300];
183 Float_t confLevelbestSel[300];
536031f2 184 Float_t t0bestallSel=0.;
8f589502 185 Float_t eT0bestallSel=0.;
536031f2 186 Float_t sumWt0bestallSel=0.;
8f589502 187 Float_t eMeanTzeroPi=0.;
536031f2 188 Float_t meantzeropi=0.;
189 Float_t sumAllweightspi=0.;
190 Double_t t0def=-999;
191 Double_t deltat0def=999;
192 Int_t ngoodtrktrulyused=0;
193 Int_t ntracksinsetmyCut = 0;
194
195 Int_t ntrk=fEvent->GetNumberOfTracks();
196
197 AliESDtrack **tracks=new AliESDtrack*[ntrk];
198 Int_t ngoodtrk=0;
199 Int_t ngoodtrkt0 =0;
200 Float_t mintime =1E6;
201
202 // First Track loop, Selection of good tracks
203
204 for (Int_t itrk=0; itrk<ntrk; itrk++) {
205 AliESDtrack *t=fEvent->GetTrack(itrk);
206 Double_t momOld=t->GetP();
207 Double_t mom=momOld-0.0036*momOld;
208 if ((t->GetStatus()&AliESDtrack::kTIME)==0) continue;
03bd764d 209 if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
536031f2 210 Double_t time=t->GetTOFsignal();
211
212 time*=1.E-3; // tof given in nanoseconds
213 if (!(mom<=fUpperMomBound && mom>=fLowerMomBound))continue;
2a258f40 214
14b2cbea 215 if (!AcceptTrack(t)) continue;
536031f2 216
2a258f40 217 if(t->GetP() < fLowerMomBound || t->GetIntegratedLength() < 350 || t->GetTOFsignalToT() < 0.000000001)continue; //skip decays
536031f2 218 if(time <= mintime) mintime=time;
219 tracks[ngoodtrk]=t;
220 ngoodtrk++;
221 }
222
2a258f40 223 if(ngoodtrk>22) nmaxtracksinset = 6;
224
03bd764d 225// cout << " N. of ESD tracks : " << ntrk << endl;
226// cout << " N. of preselected tracks : " << ngoodtrk << endl;
227// cout << " Minimum tof time in set (in ns) : " << mintime << endl;
536031f2 228
229 AliESDtrack **gtracks=new AliESDtrack*[ngoodtrk];
230
231 for (Int_t jtrk=0; jtrk< ngoodtrk; jtrk++) {
232 AliESDtrack *t=tracks[jtrk];
233 Double_t time=t->GetTOFsignal();
234
235 if((time-mintime*1.E3)<50.E3){ // For pp and per
236 gtracks[ngoodtrkt0]=t;
237 ngoodtrkt0++;
238 }
239 }
240
241
242 Int_t nseteq = (ngoodtrkt0-1)/nmaxtracksinset + 1;
243 Int_t nmaxtracksinsetCurrent=ngoodtrkt0/nseteq;
244 if(nmaxtracksinsetCurrent*nseteq < ngoodtrkt0) nmaxtracksinsetCurrent++;
245
246 if(ngoodtrkt0<2){
6a4e212e 247// cout << "less than 2 tracks, skip event " << endl;
536031f2 248 t0def=-999;
249 deltat0def=0.600;
250 fT0SigmaT0def[0]=t0def;
251 fT0SigmaT0def[1]=deltat0def;
252 fT0SigmaT0def[2]=ngoodtrkt0;
253 fT0SigmaT0def[3]=ngoodtrkt0;
254 //goto finish;
255 }
256 if(ngoodtrkt0>=2){
257 // Decide how many tracks in set
03bd764d 258 Int_t ntracksinset = std::min(ngoodtrkt0,nmaxtracksinsetCurrent);
536031f2 259 Int_t nset=1;
260
261 if(ngoodtrkt0>nmaxtracksinsetCurrent) {nset= (Int_t)(ngoodtrkt0/ntracksinset)+1;}
6a4e212e 262
536031f2 263 // Loop over selected sets
264
265 if(nset>=1){
266 for (Int_t i=0; i< nset; i++) {
267
268 Float_t t0best=999.;
8f589502 269 Float_t eT0best=999.;
536031f2 270 Float_t chisquarebest=99999.;
271 Int_t npionbest=0;
272
273 Int_t ntracksinsetmy=0;
274 AliESDtrack **tracksT0=new AliESDtrack*[ntracksinset];
275 for (Int_t itrk=0; itrk<ntracksinset; itrk++) {
276 Int_t index = itrk+i*ntracksinset;
277 if(index < ngoodtrkt0){
278 AliESDtrack *t=gtracks[index];
279 tracksT0[itrk]=t;
280 ntracksinsetmy++;
281 }
282 }
283
284 // Analyse it
285
2a258f40 286 Int_t assparticle[nmaxtracksinsetMax];
287 Float_t exptof[nmaxtracksinsetMax][3];
288 Float_t timeofflight[nmaxtracksinsetMax];
289 Float_t momentum[nmaxtracksinsetMax];
290 Float_t timezero[nmaxtracksinsetMax];
291 Float_t weightedtimezero[nmaxtracksinsetMax];
292 Float_t beta[nmaxtracksinsetMax];
293 Float_t texp[nmaxtracksinsetMax];
294 Float_t dtexp[nmaxtracksinsetMax];
295 Float_t sqMomError[nmaxtracksinsetMax];
296 Float_t sqTrackError[nmaxtracksinsetMax];
536031f2 297 Float_t massarray[3]={0.13957,0.493677,0.9382723};
2a258f40 298 Float_t tracktoflen[nmaxtracksinsetMax];
299 Float_t besttimezero[nmaxtracksinsetMax];
300 Float_t besttexp[nmaxtracksinsetMax];
301 Float_t besttimeofflight[nmaxtracksinsetMax];
302 Float_t bestmomentum[nmaxtracksinsetMax];
303 Float_t bestchisquare[nmaxtracksinsetMax];
304 Float_t bestweightedtimezero[nmaxtracksinsetMax];
305 Float_t bestsqTrackError[nmaxtracksinsetMax];
306 Int_t imass[nmaxtracksinsetMax];
536031f2 307
308 for (Int_t j=0; j<ntracksinset; j++) {
309 assparticle[j] = 3;
310 timeofflight[j] = 0;
311 momentum[j] = 0;
312 timezero[j] = 0;
313 weightedtimezero[j] = 0;
314 beta[j] = 0;
315 texp[j] = 0;
316 dtexp[j] = 0;
317 sqMomError[j] = 0;
318 sqTrackError[j] = 0;
319 tracktoflen[j] = 0;
320 besttimezero[j] = 0;
321 besttexp[j] = 0;
322 besttimeofflight[j] = 0;
323 bestmomentum[j] = 0;
324 bestchisquare[j] = 0;
325 bestweightedtimezero[j] = 0;
326 bestsqTrackError[j] = 0;
327 imass[j] = 1;
328 }
329
330 for (Int_t j=0; j<ntracksinsetmy; j++) {
331 AliESDtrack *t=tracksT0[j];
332 Double_t momOld=t->GetP();
333 Double_t mom=momOld-0.0036*momOld;
334 Double_t time=t->GetTOFsignal();
335
336 time*=1.E-3; // tof given in nanoseconds
337 Double_t exptime[10]; t->GetIntegratedTimes(exptime);
338 Double_t toflen=t->GetIntegratedLength();
339 toflen=toflen/100.; // toflen given in m
340
8f589502 341 timeofflight[j]=time;
342 tracktoflen[j]=toflen;
536031f2 343 exptof[j][0]=exptime[2]*1.E-3+fTimeCorr;// in ns
344 exptof[j][1]=exptime[3]*1.E-3+fTimeCorr;
345 exptof[j][2]=exptime[4]*1.E-3+fTimeCorr;
346 momentum[j]=mom;
347 assparticle[j]=3;
348
349 } //end for (Int_t j=0; j<ntracksinsetmy; j++) {
350
536031f2 351 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
352 beta[itz]=momentum[itz]/sqrt(massarray[0]*massarray[0]
353 +momentum[itz]*momentum[itz]);
354 sqMomError[itz]= ((1.-beta[itz]*beta[itz])*0.01)*((1.-beta[itz]*beta[itz])*0.01)*(tracktoflen[itz]/(0.299792*beta[itz]))*(tracktoflen[itz]/(0.299792*beta[itz]));
2a258f40 355 sqTrackError[itz]=sqMomError[itz]; //in ns
536031f2 356 timezero[itz]=exptof[itz][0]-timeofflight[itz];// in ns
357 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
358 sumAllweightspi+=1./sqTrackError[itz];
359 meantzeropi+=weightedtimezero[itz];
360 } // end loop for (Int_t itz=0; itz< ntracksinset;itz++)
361
362
363 // Then, Combinatorial Algorithm
364
365 if(ntracksinsetmy<2 )break;
366
367 for (Int_t j=0; j<ntracksinsetmy; j++) {
368 imass[j] = 3;
369 }
370
371 Int_t ncombinatorial = Int_t(TMath::Power(3,ntracksinsetmy));
372
373 // Loop on mass hypotheses
374 for (Int_t k=0; k < ncombinatorial;k++) {
375 for (Int_t j=0; j<ntracksinsetmy; j++) {
376 imass[j] = (k % Int_t(TMath::Power(3,ntracksinsetmy-j)))/Int_t(TMath::Power(3,ntracksinsetmy-j-1));
377 texp[j]=exptof[j][imass[j]];
378 dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
379 }
380 Float_t sumAllweights=0.;
381 Float_t meantzero=0.;
8f589502 382 Float_t eMeanTzero=0.;
536031f2 383
384 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
2a258f40 385 sqTrackError[itz]=dtexp[itz]*dtexp[itz]*1E-6; //in ns2
536031f2 386
387 timezero[itz]=texp[itz]-timeofflight[itz];// in ns
388
389 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
390 sumAllweights+=1./sqTrackError[itz];
391 meantzero+=weightedtimezero[itz];
392
393 } // end loop for (Int_t itz=0; itz<15;itz++)
394
395 meantzero=meantzero/sumAllweights; // it is given in [ns]
8f589502 396 eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
536031f2 397
398 // calculate chisquare
399
400 Float_t chisquare=0.;
401 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
402 chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
403
404 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
405
406 if(chisquare<=chisquarebest){
407 for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
408
409 bestsqTrackError[iqsq]=sqTrackError[iqsq];
410 besttimezero[iqsq]=timezero[iqsq];
411 bestmomentum[iqsq]=momentum[iqsq];
412 besttimeofflight[iqsq]=timeofflight[iqsq];
413 besttexp[iqsq]=texp[iqsq];
414 bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
415 bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
416 }
417
418 Int_t npion=0;
419 for (Int_t j=0; j<ntracksinsetmy; j++) {
420 assparticle[j]=imass[j];
421 if(imass[j] == 0) npion++;
422 }
423 npionbest=npion;
424 chisquarebest=chisquare;
425 t0best=meantzero;
8f589502 426 eT0best=eMeanTzero;
536031f2 427 } // close if(dummychisquare<=chisquare)
428
429 }
430
2a258f40 431 Double_t chi2cut[nmaxtracksinsetMax];
536031f2 432 chi2cut[0] = 0;
433 chi2cut[1] = 6.6; // corresponding to a C.L. of 0.01
434 for (Int_t j=2; j<ntracksinset; j++) {
435 chi2cut[j] = chi2cut[1] * TMath::Sqrt(j*1.);
436 }
437
438 Double_t chi2singlecut = chi2cut[ntracksinsetmy-1]/ntracksinsetmy + TMath::Abs(chisquarebest-chi2cut[ntracksinsetmy-1])/ntracksinsetmy;
439
03bd764d 440// printf("tracks removed with a chi2 > %f (chi2total = %f w.r.t. the limit of %f)\n",chi2singlecut,chisquarebest,chi2cut[ntracksinsetmy-1]);
536031f2 441
442 Bool_t kRedoT0 = kFALSE;
443 ntracksinsetmyCut = ntracksinsetmy;
2a258f40 444 Bool_t usetrack[nmaxtracksinsetMax];
536031f2 445 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
446 usetrack[icsq] = kTRUE;
447 if((bestchisquare[icsq] > chisquarebest*0.5 && ntracksinsetmy > 2) || (bestchisquare[icsq] > chi2singlecut)){
448 kRedoT0 = kTRUE;
449 ntracksinsetmyCut--;
450 usetrack[icsq] = kFALSE;
451 }
452 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
453
6a4e212e 454 // printf("ntrackinsetmy = %i - %i\n",ntracksinsetmy,ntracksinsetmyCut);
536031f2 455
456 // Loop on mass hypotheses Redo
457 if(kRedoT0 && ntracksinsetmyCut > 1){
6a4e212e 458 // printf("Redo T0\n");
536031f2 459 for (Int_t k=0; k < ncombinatorial;k++) {
460 for (Int_t j=0; j<ntracksinsetmy; j++) {
461 imass[j] = (k % Int_t(TMath::Power(3,ntracksinsetmy-j))) / Int_t(TMath::Power(3,ntracksinsetmy-j-1));
462 texp[j]=exptof[j][imass[j]];
463 dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
464 }
465
466 Float_t sumAllweights=0.;
467 Float_t meantzero=0.;
8f589502 468 Float_t eMeanTzero=0.;
536031f2 469
470 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
471 if(! usetrack[itz]) continue;
2a258f40 472 sqTrackError[itz]=dtexp[itz]*dtexp[itz]*1E-6; //in ns2
536031f2 473
474 timezero[itz]=texp[itz]-timeofflight[itz];// in ns
475
476 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
477 sumAllweights+=1./sqTrackError[itz];
478 meantzero+=weightedtimezero[itz];
479
480 } // end loop for (Int_t itz=0; itz<15;itz++)
481
482 meantzero=meantzero/sumAllweights; // it is given in [ns]
8f589502 483 eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
536031f2 484
485 // calculate chisquare
486
487 Float_t chisquare=0.;
488 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
489 if(! usetrack[icsq]) continue;
490 chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
491
492 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
493
494 Int_t npion=0;
495 for (Int_t j=0; j<ntracksinsetmy; j++) {
496 assparticle[j]=imass[j];
497 if(imass[j] == 0) npion++;
498 }
499
500 if(chisquare<=chisquarebest){
501 for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
502 if(! usetrack[iqsq]) continue;
503 bestsqTrackError[iqsq]=sqTrackError[iqsq];
504 besttimezero[iqsq]=timezero[iqsq];
505 bestmomentum[iqsq]=momentum[iqsq];
506 besttimeofflight[iqsq]=timeofflight[iqsq];
507 besttexp[iqsq]=texp[iqsq];
508 bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
509 bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
510 }
511
512 npionbest=npion;
513 chisquarebest=chisquare;
514 t0best=meantzero;
8f589502 515 eT0best=eMeanTzero;
536031f2 516 } // close if(dummychisquare<=chisquare)
517
518 }
519 }
6a4e212e 520
536031f2 521 // filling histos
522 Float_t confLevel=999;
523
524 // Sets with decent chisquares
525
526 if(chisquarebest<999.){
527 Double_t dblechisquare=(Double_t)chisquarebest;
528 confLevel=(Float_t)TMath::Prob(dblechisquare,ntracksinsetmyCut-1);
03bd764d 529// cout << " Set Number " << nsets << endl;
530// cout << "Best Assignment, selection " << assparticle[0] <<
531// assparticle[1] << assparticle[2] <<
532// assparticle[3] << assparticle[4] <<
533// assparticle[5] << endl;
534// cout << " Chisquare of the set "<< chisquarebest <<endl;
535// cout << " C.L. of the set "<< confLevel <<endl;
536// cout << " T0 for this set (in ns) " << t0best << endl;
536031f2 537
538 for(Int_t icsq=0; icsq<ntracksinsetmy;icsq++){
539
540 if(! usetrack[icsq]) continue;
541
03bd764d 542// cout << "Track # " << icsq << " T0 offsets = "
543// << besttimezero[icsq]-t0best <<
544// " track error = " << bestsqTrackError[icsq]
545// << " Chisquare = " << bestchisquare[icsq]
546// << " Momentum = " << bestmomentum[icsq]
547// << " TOF = " << besttimeofflight[icsq]
548// << " TOF tracking = " << besttexp[icsq]
549// << " is used = " << usetrack[icsq] << endl;
536031f2 550 }
551
552 // Pick up only those with C.L. >1%
553 // if(confLevel>0.01 && ngoodsetsSel<200){
554 if(confLevel>0.01 && ngoodsetsSel<200){
8f589502 555 chiSquarebestSel[ngoodsetsSel]=chisquarebest;
556 confLevelbestSel[ngoodsetsSel]=confLevel;
557 t0bestSel[ngoodsetsSel]=t0best/eT0best/eT0best;
558 eT0bestSel[ngoodsetsSel]=1./eT0best/eT0best;
559 t0bestallSel += t0best/eT0best/eT0best;
560 sumWt0bestallSel += 1./eT0best/eT0best;
536031f2 561 ngoodsetsSel++;
562 ngoodtrktrulyused+=ntracksinsetmyCut;
2a258f40 563
564 // printf("t0 of a set = %f +/- %f\n",t0best,eT0best);
536031f2 565 }
566 else{
6a4e212e 567 // printf("conflevel = %f -- ngoodsetsSel = %i -- ntrackset = %i\n",confLevel,ngoodsetsSel,ntracksinsetmy);
536031f2 568 }
569 }
570 delete[] tracksT0;
571 nsets++;
572
573 } // end for the current set
574
8f589502 575 nUsedTracks = ngoodtrkt0;
536031f2 576 if(strstr(option,"all")){
577 if(sumAllweightspi>0.){
578 meantzeropi=meantzeropi/sumAllweightspi; // it is given in [ns]
8f589502 579 eMeanTzeroPi=sqrt(1./sumAllweightspi); // it is given in [ns]
536031f2 580 }
581
582 if(sumWt0bestallSel>0){
583 t0bestallSel = t0bestallSel/sumWt0bestallSel;
8f589502 584 eT0bestallSel = sqrt(1./sumWt0bestallSel);
536031f2 585
586 }// end of if(sumWt0bestallSel>0){
587
6a4e212e 588// cout << "T0 all " << t0bestallSel << " +/- " << eT0bestallSel << "Number of tracks used: "<<ngoodtrktrulyused<<endl;
536031f2 589 }
590
591 t0def=t0bestallSel;
8f589502 592 deltat0def=eT0bestallSel;
536031f2 593
594 fT0SigmaT0def[0]=t0def;
2a258f40 595 fT0SigmaT0def[1]=TMath::Sqrt(deltat0def*deltat0def);//*ngoodtrktrulyused/(ngoodtrktrulyused-1));
6a4e212e 596 fT0SigmaT0def[2]=ngoodtrkt0;
536031f2 597 fT0SigmaT0def[3]=ngoodtrktrulyused;
598 }
599 }
600
6a4e212e 601 // if(strstr(option,"tim") || strstr(option,"all")){
602 // cout << "AliTOFT0v1:" << endl ;
603 //}
536031f2 604
2a258f40 605 if(fT0SigmaT0def[1] < 0.00001) fT0SigmaT0def[1] = 0.6;
606
607 bench->Stop("t0computation");
608
609 fT0SigmaT0def[4]=bench->GetRealTime("t0computation");
610 fT0SigmaT0def[5]=bench->GetCpuTime("t0computation");
611
612// bench->Print("t0computation");
613// printf("%f %f\n",fT0SigmaT0def[4],fT0SigmaT0def[5]);
614
615 bench->Reset();
5b4ed716 616
617 return fT0SigmaT0def;
618 }
619//__________________________________________________________________
620Double_t * AliTOFT0v1::DefineT0(Option_t *option,Float_t pMinCut,Float_t pMaxCut)
621{
2a258f40 622 TBenchmark *bench=new TBenchmark();
623 bench->Start("t0computation");
624
5b4ed716 625 // Caluclate the Event Time using the ESD TOF time
626
627 fT0SigmaT0def[0]=0.;
628 fT0SigmaT0def[1]=0.600;
629 fT0SigmaT0def[2]=0.;
630 fT0SigmaT0def[3]=0.;
5b4ed716 631
2a258f40 632 const Int_t nmaxtracksinsetMax=10;
633 Int_t nmaxtracksinset=10;
5b4ed716 634// if(strstr(option,"all")){
635// cout << "Selecting primary tracks with momentum between " << fLowerMomBound << " GeV/c and " << fUpperMomBound << " GeV/c" << endl;
636// cout << "Memorandum: 0 means PION | 1 means KAON | 2 means PROTON" << endl;
637// }
638
639
640 Int_t nsets=0;
641 Int_t nUsedTracks=0;
642 Int_t ngoodsetsSel= 0;
643 Float_t t0bestSel[300];
644 Float_t eT0bestSel[300];
645 Float_t chiSquarebestSel[300];
646 Float_t confLevelbestSel[300];
647 Float_t t0bestallSel=0.;
648 Float_t eT0bestallSel=0.;
649 Float_t sumWt0bestallSel=0.;
650 Float_t eMeanTzeroPi=0.;
651 Float_t meantzeropi=0.;
652 Float_t sumAllweightspi=0.;
653 Double_t t0def=-999;
654 Double_t deltat0def=999;
655 Int_t ngoodtrktrulyused=0;
656 Int_t ntracksinsetmyCut = 0;
657
658 Int_t ntrk=fEvent->GetNumberOfTracks();
659
660 AliESDtrack **tracks=new AliESDtrack*[ntrk];
661 Int_t ngoodtrk=0;
662 Int_t ngoodtrkt0 =0;
663 Float_t mintime =1E6;
664
665 // First Track loop, Selection of good tracks
666
667 for (Int_t itrk=0; itrk<ntrk; itrk++) {
668 AliESDtrack *t=fEvent->GetTrack(itrk);
669 Double_t momOld=t->GetP();
670 Double_t mom=momOld-0.0036*momOld;
671 if ((t->GetStatus()&AliESDtrack::kTIME)==0) continue;
672 if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
673 Double_t time=t->GetTOFsignal();
674
675 time*=1.E-3; // tof given in nanoseconds
676 if (!(mom<=fUpperMomBound && mom>=fLowerMomBound))continue;
2a258f40 677
5b4ed716 678 if (!AcceptTrack(t)) continue;
679
9c89b8bd 680 if(t->GetIntegratedLength() < 350)continue; //skip decays
5b4ed716 681 if(t->GetP() > pMinCut && t->GetP() < pMaxCut) continue;
682 if(time <= mintime) mintime=time;
683 tracks[ngoodtrk]=t;
684 ngoodtrk++;
685 }
686
2a258f40 687 if(ngoodtrk>22) nmaxtracksinset = 6;
688
5b4ed716 689
2a258f40 690// cout << " N. of ESD tracks : " << ntrk << endl;
691// cout << " N. of preselected tracks : " << ngoodtrk << endl;
692// cout << " Minimum tof time in set (in ns) : " << mintime << endl;
5b4ed716 693
694 AliESDtrack **gtracks=new AliESDtrack*[ngoodtrk];
695
696 for (Int_t jtrk=0; jtrk< ngoodtrk; jtrk++) {
697 AliESDtrack *t=tracks[jtrk];
698 Double_t time=t->GetTOFsignal();
699
700 if((time-mintime*1.E3)<50.E3){ // For pp and per
701 gtracks[ngoodtrkt0]=t;
702 ngoodtrkt0++;
703 }
704 }
705
2a258f40 706// cout << " N. of preselected tracks t0 : " << ngoodtrkt0 << endl;
5b4ed716 707
708 Int_t nseteq = (ngoodtrkt0-1)/nmaxtracksinset + 1;
709 Int_t nmaxtracksinsetCurrent=ngoodtrkt0/nseteq;
710 if(nmaxtracksinsetCurrent*nseteq < ngoodtrkt0) nmaxtracksinsetCurrent++;
711
2a258f40 712// cout << " N. of sets : " << nseteq << endl;
713
5b4ed716 714 if(ngoodtrkt0<2){
715// cout << "less than 2 tracks, skip event " << endl;
716 t0def=-999;
717 deltat0def=0.600;
718 fT0SigmaT0def[0]=t0def;
719 fT0SigmaT0def[1]=deltat0def;
720 fT0SigmaT0def[2]=ngoodtrkt0;
721 fT0SigmaT0def[3]=ngoodtrkt0;
722 //goto finish;
723 }
724 if(ngoodtrkt0>=2){
725 // Decide how many tracks in set
726 Int_t ntracksinset = std::min(ngoodtrkt0,nmaxtracksinsetCurrent);
727 Int_t nset=1;
728
729 if(ngoodtrkt0>nmaxtracksinsetCurrent) {nset= (Int_t)(ngoodtrkt0/ntracksinset)+1;}
730
731 // Loop over selected sets
732
733 if(nset>=1){
734 for (Int_t i=0; i< nset; i++) {
2a258f40 735 // printf("Set %i of %i\n",i+1,nset);
5b4ed716 736 Float_t t0best=999.;
737 Float_t eT0best=999.;
738 Float_t chisquarebest=99999.;
739 Int_t npionbest=0;
740
741 Int_t ntracksinsetmy=0;
742 AliESDtrack **tracksT0=new AliESDtrack*[ntracksinset];
743 for (Int_t itrk=0; itrk<ntracksinset; itrk++) {
744 Int_t index = itrk+i*ntracksinset;
745 if(index < ngoodtrkt0){
746 AliESDtrack *t=gtracks[index];
747 tracksT0[itrk]=t;
748 ntracksinsetmy++;
749 }
750 }
751
752 // Analyse it
753
2a258f40 754 Int_t assparticle[nmaxtracksinsetMax];
755 Float_t exptof[nmaxtracksinsetMax][3];
756 Float_t timeofflight[nmaxtracksinsetMax];
757 Float_t momentum[nmaxtracksinsetMax];
758 Float_t timezero[nmaxtracksinsetMax];
759 Float_t weightedtimezero[nmaxtracksinsetMax];
760 Float_t beta[nmaxtracksinsetMax];
761 Float_t texp[nmaxtracksinsetMax];
762 Float_t dtexp[nmaxtracksinsetMax];
763 Float_t sqMomError[nmaxtracksinsetMax];
764 Float_t sqTrackError[nmaxtracksinsetMax];
5b4ed716 765 Float_t massarray[3]={0.13957,0.493677,0.9382723};
2a258f40 766 Float_t tracktoflen[nmaxtracksinsetMax];
767 Float_t besttimezero[nmaxtracksinsetMax];
768 Float_t besttexp[nmaxtracksinsetMax];
769 Float_t besttimeofflight[nmaxtracksinsetMax];
770 Float_t bestmomentum[nmaxtracksinsetMax];
771 Float_t bestchisquare[nmaxtracksinsetMax];
772 Float_t bestweightedtimezero[nmaxtracksinsetMax];
773 Float_t bestsqTrackError[nmaxtracksinsetMax];
774 Int_t imass[nmaxtracksinsetMax];
5b4ed716 775
776 for (Int_t j=0; j<ntracksinset; j++) {
777 assparticle[j] = 3;
778 timeofflight[j] = 0;
779 momentum[j] = 0;
780 timezero[j] = 0;
781 weightedtimezero[j] = 0;
782 beta[j] = 0;
783 texp[j] = 0;
784 dtexp[j] = 0;
785 sqMomError[j] = 0;
786 sqTrackError[j] = 0;
787 tracktoflen[j] = 0;
788 besttimezero[j] = 0;
789 besttexp[j] = 0;
790 besttimeofflight[j] = 0;
791 bestmomentum[j] = 0;
792 bestchisquare[j] = 0;
793 bestweightedtimezero[j] = 0;
794 bestsqTrackError[j] = 0;
795 imass[j] = 1;
796 }
797
798 for (Int_t j=0; j<ntracksinsetmy; j++) {
799 AliESDtrack *t=tracksT0[j];
800 Double_t momOld=t->GetP();
801 Double_t mom=momOld-0.0036*momOld;
802 Double_t time=t->GetTOFsignal();
803
804 time*=1.E-3; // tof given in nanoseconds
805 Double_t exptime[10]; t->GetIntegratedTimes(exptime);
806 Double_t toflen=t->GetIntegratedLength();
807 toflen=toflen/100.; // toflen given in m
808
809 timeofflight[j]=time;
810 tracktoflen[j]=toflen;
811 exptof[j][0]=exptime[2]*1.E-3+fTimeCorr;// in ns
812 exptof[j][1]=exptime[3]*1.E-3+fTimeCorr;
813 exptof[j][2]=exptime[4]*1.E-3+fTimeCorr;
814 momentum[j]=mom;
815 assparticle[j]=3;
816
817 } //end for (Int_t j=0; j<ntracksinsetmy; j++) {
818
819 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
820 beta[itz]=momentum[itz]/sqrt(massarray[0]*massarray[0]
821 +momentum[itz]*momentum[itz]);
822 sqMomError[itz]= ((1.-beta[itz]*beta[itz])*0.01)*((1.-beta[itz]*beta[itz])*0.01)*(tracktoflen[itz]/(0.299792*beta[itz]))*(tracktoflen[itz]/(0.299792*beta[itz]));
2a258f40 823 sqTrackError[itz]=sqMomError[itz]; //in ns
5b4ed716 824 timezero[itz]=exptof[itz][0]-timeofflight[itz];// in ns
825 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
826 sumAllweightspi+=1./sqTrackError[itz];
827 meantzeropi+=weightedtimezero[itz];
828 } // end loop for (Int_t itz=0; itz< ntracksinset;itz++)
829
830
831 // Then, Combinatorial Algorithm
832
833 if(ntracksinsetmy<2 )break;
834
835 for (Int_t j=0; j<ntracksinsetmy; j++) {
836 imass[j] = 3;
837 }
838
839 Int_t ncombinatorial = Int_t(TMath::Power(3,ntracksinsetmy));
840
841 // Loop on mass hypotheses
842 for (Int_t k=0; k < ncombinatorial;k++) {
843 for (Int_t j=0; j<ntracksinsetmy; j++) {
844 imass[j] = (k % Int_t(TMath::Power(3,ntracksinsetmy-j)))/Int_t(TMath::Power(3,ntracksinsetmy-j-1));
845 texp[j]=exptof[j][imass[j]];
846 dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
847 }
848 Float_t sumAllweights=0.;
849 Float_t meantzero=0.;
850 Float_t eMeanTzero=0.;
851
852 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
2a258f40 853 sqTrackError[itz]=dtexp[itz]*dtexp[itz]*1E-6; //in ns2
5b4ed716 854
855 timezero[itz]=texp[itz]-timeofflight[itz];// in ns
856
857 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
858 sumAllweights+=1./sqTrackError[itz];
859 meantzero+=weightedtimezero[itz];
860
861 } // end loop for (Int_t itz=0; itz<15;itz++)
862
863 meantzero=meantzero/sumAllweights; // it is given in [ns]
864 eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
865
866 // calculate chisquare
867
868 Float_t chisquare=0.;
869 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
870 chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
5b4ed716 871 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
872
873 if(chisquare<=chisquarebest){
874 for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
875
876 bestsqTrackError[iqsq]=sqTrackError[iqsq];
877 besttimezero[iqsq]=timezero[iqsq];
878 bestmomentum[iqsq]=momentum[iqsq];
879 besttimeofflight[iqsq]=timeofflight[iqsq];
880 besttexp[iqsq]=texp[iqsq];
881 bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
882 bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
883 }
884
885 Int_t npion=0;
886 for (Int_t j=0; j<ntracksinsetmy; j++) {
887 assparticle[j]=imass[j];
888 if(imass[j] == 0) npion++;
889 }
890 npionbest=npion;
891 chisquarebest=chisquare;
892 t0best=meantzero;
893 eT0best=eMeanTzero;
894 } // close if(dummychisquare<=chisquare)
5b4ed716 895 }
896
2a258f40 897 Double_t chi2cut[nmaxtracksinsetMax];
5b4ed716 898 chi2cut[0] = 0;
899 chi2cut[1] = 6.6; // corresponding to a C.L. of 0.01
900 for (Int_t j=2; j<ntracksinset; j++) {
901 chi2cut[j] = chi2cut[1] * TMath::Sqrt(j*1.);
902 }
903
904 Double_t chi2singlecut = chi2cut[ntracksinsetmy-1]/ntracksinsetmy + TMath::Abs(chisquarebest-chi2cut[ntracksinsetmy-1])/ntracksinsetmy;
905
2a258f40 906 // printf("tracks removed with a chi2 > %f (chi2total = %f w.r.t. the limit of %f)\n",chi2singlecut,chisquarebest,chi2cut[ntracksinsetmy-1]);
5b4ed716 907
908 Bool_t kRedoT0 = kFALSE;
909 ntracksinsetmyCut = ntracksinsetmy;
2a258f40 910 Bool_t usetrack[nmaxtracksinsetMax];
5b4ed716 911 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
912 usetrack[icsq] = kTRUE;
913 if((bestchisquare[icsq] > chisquarebest*0.5 && ntracksinsetmy > 2) || (bestchisquare[icsq] > chi2singlecut)){
914 kRedoT0 = kTRUE;
915 ntracksinsetmyCut--;
916 usetrack[icsq] = kFALSE;
917 }
918 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
919
920 // printf("ntrackinsetmy = %i - %i\n",ntracksinsetmy,ntracksinsetmyCut);
2a258f40 921
5b4ed716 922 // Loop on mass hypotheses Redo
923 if(kRedoT0 && ntracksinsetmyCut > 1){
924 // printf("Redo T0\n");
925 for (Int_t k=0; k < ncombinatorial;k++) {
926 for (Int_t j=0; j<ntracksinsetmy; j++) {
927 imass[j] = (k % Int_t(TMath::Power(3,ntracksinsetmy-j))) / Int_t(TMath::Power(3,ntracksinsetmy-j-1));
928 texp[j]=exptof[j][imass[j]];
929 dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
930 }
931
932 Float_t sumAllweights=0.;
933 Float_t meantzero=0.;
934 Float_t eMeanTzero=0.;
935
936 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
937 if(! usetrack[itz]) continue;
2a258f40 938 sqTrackError[itz]=dtexp[itz]*dtexp[itz]*1E-6; //in ns2
5b4ed716 939
940 timezero[itz]=texp[itz]-timeofflight[itz];// in ns
941
942 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
943 sumAllweights+=1./sqTrackError[itz];
944 meantzero+=weightedtimezero[itz];
945
946 } // end loop for (Int_t itz=0; itz<15;itz++)
947
948 meantzero=meantzero/sumAllweights; // it is given in [ns]
949 eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
950
951 // calculate chisquare
952
953 Float_t chisquare=0.;
954 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
955 if(! usetrack[icsq]) continue;
956 chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
957
958 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
959
960 Int_t npion=0;
961 for (Int_t j=0; j<ntracksinsetmy; j++) {
962 assparticle[j]=imass[j];
963 if(imass[j] == 0) npion++;
964 }
965
966 if(chisquare<=chisquarebest){
967 for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
968 if(! usetrack[iqsq]) continue;
969 bestsqTrackError[iqsq]=sqTrackError[iqsq];
970 besttimezero[iqsq]=timezero[iqsq];
971 bestmomentum[iqsq]=momentum[iqsq];
972 besttimeofflight[iqsq]=timeofflight[iqsq];
973 besttexp[iqsq]=texp[iqsq];
974 bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
975 bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
976 }
977
978 npionbest=npion;
979 chisquarebest=chisquare;
980 t0best=meantzero;
981 eT0best=eMeanTzero;
982 } // close if(dummychisquare<=chisquare)
983
984 }
985 }
986
987 // filling histos
988 Float_t confLevel=999;
989
990 // Sets with decent chisquares
2a258f40 991 // printf("Chi2best of the set = %f \n",chisquarebest);
5b4ed716 992
993 if(chisquarebest<999.){
994 Double_t dblechisquare=(Double_t)chisquarebest;
995 confLevel=(Float_t)TMath::Prob(dblechisquare,ntracksinsetmyCut-1);
996// cout << " Set Number " << nsets << endl;
997// cout << "Best Assignment, selection " << assparticle[0] <<
998// assparticle[1] << assparticle[2] <<
999// assparticle[3] << assparticle[4] <<
1000// assparticle[5] << endl;
1001// cout << " Chisquare of the set "<< chisquarebest <<endl;
1002// cout << " C.L. of the set "<< confLevel <<endl;
1003// cout << " T0 for this set (in ns) " << t0best << endl;
1004
1005 for(Int_t icsq=0; icsq<ntracksinsetmy;icsq++){
1006
1007 if(! usetrack[icsq]) continue;
1008
1009// cout << "Track # " << icsq << " T0 offsets = "
1010// << besttimezero[icsq]-t0best <<
1011// " track error = " << bestsqTrackError[icsq]
1012// << " Chisquare = " << bestchisquare[icsq]
1013// << " Momentum = " << bestmomentum[icsq]
1014// << " TOF = " << besttimeofflight[icsq]
1015// << " TOF tracking = " << besttexp[icsq]
1016// << " is used = " << usetrack[icsq] << endl;
1017 }
1018
2a258f40 1019 // printf("%i) CL(Chi2) = %f < 0.01\n",ngoodsetsSel,confLevel);
1020
5b4ed716 1021 // Pick up only those with C.L. >1%
1022 // if(confLevel>0.01 && ngoodsetsSel<200){
1023 if(confLevel>0.01 && ngoodsetsSel<200){
1024 chiSquarebestSel[ngoodsetsSel]=chisquarebest;
1025 confLevelbestSel[ngoodsetsSel]=confLevel;
1026 t0bestSel[ngoodsetsSel]=t0best/eT0best/eT0best;
1027 eT0bestSel[ngoodsetsSel]=1./eT0best/eT0best;
1028 t0bestallSel += t0best/eT0best/eT0best;
1029 sumWt0bestallSel += 1./eT0best/eT0best;
1030 ngoodsetsSel++;
2a258f40 1031 ngoodtrktrulyused+=ntracksinsetmyCut;
1032 // printf("T0 set = %f +/- %f\n",t0best,eT0best);
5b4ed716 1033 }
1034 else{
1035 // printf("conflevel = %f -- ngoodsetsSel = %i -- ntrackset = %i\n",confLevel,ngoodsetsSel,ntracksinsetmy);
1036 }
1037 }
1038 delete[] tracksT0;
1039 nsets++;
1040
1041 } // end for the current set
1042
1043 nUsedTracks = ngoodtrkt0;
1044 if(strstr(option,"all")){
1045 if(sumAllweightspi>0.){
1046 meantzeropi=meantzeropi/sumAllweightspi; // it is given in [ns]
1047 eMeanTzeroPi=sqrt(1./sumAllweightspi); // it is given in [ns]
1048 }
1049
2a258f40 1050 // printf("t0bestallSel = %f -- eT0bestallSel = %f\n",t0bestallSel,sumWt0bestallSel);
1051
5b4ed716 1052 if(sumWt0bestallSel>0){
1053 t0bestallSel = t0bestallSel/sumWt0bestallSel;
1054 eT0bestallSel = sqrt(1./sumWt0bestallSel);
2a258f40 1055 // printf("Final) t0bestallSel = %f -- eT0bestallSel = %f\n",t0bestallSel,eT0bestallSel);
5b4ed716 1056 }// end of if(sumWt0bestallSel>0){
1057
1058// cout << "T0 all " << t0bestallSel << " +/- " << eT0bestallSel << "Number of tracks used: "<<ngoodtrktrulyused<<endl;
1059 }
1060
1061 t0def=t0bestallSel;
1062 deltat0def=eT0bestallSel;
5b4ed716 1063
1064 fT0SigmaT0def[0]=t0def;
2a258f40 1065 fT0SigmaT0def[1]=TMath::Sqrt(deltat0def*deltat0def);//*ngoodtrktrulyused/(ngoodtrktrulyused-1));
5b4ed716 1066 fT0SigmaT0def[2]=ngoodtrkt0;
1067 fT0SigmaT0def[3]=ngoodtrktrulyused;
1068 }
1069 }
1070
1071 // if(strstr(option,"tim") || strstr(option,"all")){
1072 // cout << "AliTOFT0v1:" << endl ;
1073 //}
1074
2a258f40 1075 if(fT0SigmaT0def[1] < 0.00001) fT0SigmaT0def[1] = 0.6;
1076
1077 bench->Stop("t0computation");
1078
1079 fT0SigmaT0def[4]=bench->GetRealTime("t0computation");
1080 fT0SigmaT0def[5]=bench->GetCpuTime("t0computation");
1081
1082// bench->Print("t0computation");
1083// printf("(%4.1f < p < %4.1f GeV/c) T0-TOF =%9.1f +/- %5.1f ps (n_track = %i)\n\n",pMinCut,pMaxCut,-fT0SigmaT0def[0]*1000,fT0SigmaT0def[1]*1000,Int_t(fT0SigmaT0def[3]));
1084
1085 bench->Reset();
5b4ed716 1086
536031f2 1087 return fT0SigmaT0def;
1088 }
1089//__________________________________________________________________
8f589502 1090Float_t AliTOFT0v1::GetMomError(Int_t index, Float_t mom, Float_t texp) const
536031f2 1091{
8f589502 1092 // Take the error extimate for the TOF time in the track reconstruction
536031f2 1093
536031f2 1094 static const Double_t kMasses[]={
1095 0.000511, 0.105658, 0.139570, 0.493677, 0.938272, 1.875613
1096 };
1097
1098 Double_t mass=kMasses[index+2];
536031f2 1099
2a258f40 1100 Float_t sigma = fPIDesd->GetTOFResponse().GetExpectedSigma(mom,texp,mass);
536031f2 1101
1102 return sigma;
1103}
14b2cbea 1104
1105//__________________________________________________________________
1106Bool_t AliTOFT0v1::AcceptTrack(AliESDtrack *track)
1107{
1108
1109 /* TPC refit */
1110 if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
1111 /* do not accept kink daughters */
1112 if (track->GetKinkIndex(0)>0) return kFALSE;
1113 /* N clusters TPC */
1114 if (track->GetTPCclusters(0) < 50) return kFALSE;
1115 /* chi2 TPC */
1116 if (track->GetTPCchi2()/Float_t(track->GetTPCclusters(0)) > 3.5) return kFALSE;
1117 /* sigma to vertex */
1118 if (GetSigmaToVertex(track) > 4.) return kFALSE;
1119
1120 /* accept track */
1121 return kTRUE;
1122
1123}
1124
1125//____________________________________________________________________
8f589502 1126Float_t AliTOFT0v1::GetSigmaToVertex(AliESDtrack* esdTrack) const
14b2cbea 1127{
1128 // Calculates the number of sigma to the vertex.
1129
1130 Float_t b[2];
1131 Float_t bRes[2];
1132 Float_t bCov[3];
1133 esdTrack->GetImpactParameters(b,bCov);
1134
1135 if (bCov[0]<=0 || bCov[2]<=0) {
1136 bCov[0]=0; bCov[2]=0;
1137 }
1138 bRes[0] = TMath::Sqrt(bCov[0]);
1139 bRes[1] = TMath::Sqrt(bCov[2]);
1140
1141 // -----------------------------------
1142 // How to get to a n-sigma cut?
1143 //
1144 // The accumulated statistics from 0 to d is
1145 //
1146 // -> Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
1147 // -> 1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
1148 //
1149 // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-d**2)/2)
1150 // Can this be expressed in a different way?
1151
1152 if (bRes[0] == 0 || bRes[1] ==0)
1153 return -1;
1154
1155 Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
1156
1157 // work around precision problem
1158 // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
1159 // 1e-15 corresponds to nsigma ~ 7.7
1160 if (TMath::Exp(-d * d / 2) < 1e-15)
1161 return 1000;
1162
1163 Float_t nSigma = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);
1164 return nSigma;
1165}