]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TOF/AliTOFT0v1.cxx
restore threshold getters after parameter dynamics update (fw v. >= A012)
[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),
62f44f07 74 fPIDesd(extPID),
75 fTracks(new TObjArray(10)),
76 fGTracks(new TObjArray(10)),
77 fTracksT0(new TObjArray(10))
536031f2 78{
8f589502 79 //
80 // default constructor
81 //
2a258f40 82 if(AliPID::ParticleMass(0) == 0) new AliPID();
83
84 if(!fPIDesd){
85 fPIDesd = new AliESDpid();
86 }
536031f2 87
5b4ed716 88 Init(NULL);
89
8f589502 90}
91
8f589502 92//____________________________________________________________________________
2a258f40 93AliTOFT0v1::AliTOFT0v1(AliESDEvent* event,AliESDpid *extPID):
5b4ed716 94 TObject(),
03bd764d 95 fLowerMomBound(0.5),
5b4ed716 96 fUpperMomBound(3.0),
8f589502 97 fTimeCorr(0.),
2a258f40 98 fEvent(event),
62f44f07 99 fPIDesd(extPID),
100 fTracks(new TObjArray(10)),
101 fGTracks(new TObjArray(10)),
102 fTracksT0(new TObjArray(10))
8f589502 103{
104 //
105 // real constructor
106 //
2a258f40 107 if(AliPID::ParticleMass(0) == 0) new AliPID();
536031f2 108
2a258f40 109 if(!fPIDesd){
110 fPIDesd = new AliESDpid();
111 }
5b4ed716 112
2a258f40 113 Init(event);
8f589502 114
536031f2 115}
8f589502 116//____________________________________________________________________________
117AliTOFT0v1& AliTOFT0v1::operator=(const AliTOFT0v1 &tzero)
118{
119 //
120 // assign. operator
121 //
122
123 if (this == &tzero)
124 return *this;
125
126 fLowerMomBound=tzero.fLowerMomBound;
127 fUpperMomBound=tzero.fUpperMomBound;
8f589502 128 fTimeCorr=tzero.fTimeCorr;
129 fEvent=tzero.fEvent;
8f589502 130 fT0SigmaT0def[0]=tzero.fT0SigmaT0def[0];
131 fT0SigmaT0def[1]=tzero.fT0SigmaT0def[1];
132 fT0SigmaT0def[2]=tzero.fT0SigmaT0def[2];
133 fT0SigmaT0def[3]=tzero.fT0SigmaT0def[3];
134
62f44f07 135 fTracks=tzero.fTracks;
136 fGTracks=tzero.fGTracks;
137 fTracksT0=tzero.fTracksT0;
138
139 for (Int_t ii=0; ii<tzero.fTracks->GetEntries(); ii++)
140 fTracks->AddLast(tzero.fTracks->At(ii));
141
142 for (Int_t ii=0; ii<tzero.fGTracks->GetEntries(); ii++)
143 fGTracks->AddLast(tzero.fGTracks->At(ii));
144
145 for (Int_t ii=0; ii<tzero.fTracksT0->GetEntries(); ii++)
146 fTracksT0->AddLast(tzero.fTracksT0->At(ii));
147
8f589502 148 return *this;
149}
5b4ed716 150
536031f2 151//____________________________________________________________________________
152AliTOFT0v1::~AliTOFT0v1()
153{
154 // dtor
8f589502 155 fEvent=NULL;
e26296dc 156
157 if (fTracks) {
158 fTracks->Clear();
159 delete fTracks;
160 fTracks=0x0;
161 }
8f589502 162
e26296dc 163 if (fGTracks) {
164 fGTracks->Clear();
165 delete fGTracks;
166 fGTracks=0x0;
167 }
62f44f07 168
e26296dc 169 if (fTracksT0) {
170 fTracksT0->Clear();
171 delete fTracksT0;
172 fTracksT0=0x0;
173 }
62f44f07 174
536031f2 175}
5b4ed716 176//____________________________________________________________________________
177
178void
179AliTOFT0v1::Init(AliESDEvent *event)
180{
181
182 /*
183 * init
184 */
185
186 fEvent = event;
187 fT0SigmaT0def[0]=0.;
188 fT0SigmaT0def[1]=0.6;
189 fT0SigmaT0def[2]=0.;
190 fT0SigmaT0def[3]=0.;
191
192}
721ed687 193//____________________________________________________________________________
5b4ed716 194Double_t * AliTOFT0v1::DefineT0(Option_t *option,Float_t pMinCut,Float_t pMaxCut)
195{
2a258f40 196 TBenchmark *bench=new TBenchmark();
197 bench->Start("t0computation");
198
5b4ed716 199 // Caluclate the Event Time using the ESD TOF time
200
201 fT0SigmaT0def[0]=0.;
202 fT0SigmaT0def[1]=0.600;
203 fT0SigmaT0def[2]=0.;
204 fT0SigmaT0def[3]=0.;
5b4ed716 205
2a258f40 206 const Int_t nmaxtracksinsetMax=10;
207 Int_t nmaxtracksinset=10;
5b4ed716 208// if(strstr(option,"all")){
209// cout << "Selecting primary tracks with momentum between " << fLowerMomBound << " GeV/c and " << fUpperMomBound << " GeV/c" << endl;
210// cout << "Memorandum: 0 means PION | 1 means KAON | 2 means PROTON" << endl;
211// }
212
213
214 Int_t nsets=0;
215 Int_t nUsedTracks=0;
216 Int_t ngoodsetsSel= 0;
217 Float_t t0bestSel[300];
218 Float_t eT0bestSel[300];
219 Float_t chiSquarebestSel[300];
220 Float_t confLevelbestSel[300];
221 Float_t t0bestallSel=0.;
222 Float_t eT0bestallSel=0.;
223 Float_t sumWt0bestallSel=0.;
224 Float_t eMeanTzeroPi=0.;
225 Float_t meantzeropi=0.;
226 Float_t sumAllweightspi=0.;
227 Double_t t0def=-999;
228 Double_t deltat0def=999;
229 Int_t ngoodtrktrulyused=0;
230 Int_t ntracksinsetmyCut = 0;
231
232 Int_t ntrk=fEvent->GetNumberOfTracks();
233
5b4ed716 234 Int_t ngoodtrk=0;
235 Int_t ngoodtrkt0 =0;
721ed687 236 Float_t meantime =0;
5b4ed716 237
238 // First Track loop, Selection of good tracks
239
995c3398 240 fTracks->Clear();
5b4ed716 241 for (Int_t itrk=0; itrk<ntrk; itrk++) {
242 AliESDtrack *t=fEvent->GetTrack(itrk);
243 Double_t momOld=t->GetP();
244 Double_t mom=momOld-0.0036*momOld;
245 if ((t->GetStatus()&AliESDtrack::kTIME)==0) continue;
246 if ((t->GetStatus()&AliESDtrack::kTOFout)==0) continue;
247 Double_t time=t->GetTOFsignal();
248
249 time*=1.E-3; // tof given in nanoseconds
250 if (!(mom<=fUpperMomBound && mom>=fLowerMomBound))continue;
2a258f40 251
5b4ed716 252 if (!AcceptTrack(t)) continue;
253
9c89b8bd 254 if(t->GetIntegratedLength() < 350)continue; //skip decays
5b4ed716 255 if(t->GetP() > pMinCut && t->GetP() < pMaxCut) continue;
721ed687 256
257 meantime+=time;
62f44f07 258 fTracks->AddLast(t);
5b4ed716 259 ngoodtrk++;
260 }
2a258f40 261
721ed687 262 if(ngoodtrk > 1) meantime /= ngoodtrk;
263
264 if(ngoodtrk>22) nmaxtracksinset = 6;
995c3398 265
266 fGTracks->Clear();
62f44f07 267 for (Int_t jtrk=0; jtrk< fTracks->GetEntries(); jtrk++) {
62f44f07 268 AliESDtrack *t=(AliESDtrack*)fTracks->At(jtrk);
721ed687 269 // Double_t time=t->GetTOFsignal();
270 // if((time-meantime*1.E3)<50.E3){ // For pp and per
271 fGTracks->AddLast(t);
272 ngoodtrkt0++;
273 // }
5b4ed716 274 }
62f44f07 275
62f44f07 276 fTracks->Clear();
277
5b4ed716 278 Int_t nseteq = (ngoodtrkt0-1)/nmaxtracksinset + 1;
279 Int_t nmaxtracksinsetCurrent=ngoodtrkt0/nseteq;
280 if(nmaxtracksinsetCurrent*nseteq < ngoodtrkt0) nmaxtracksinsetCurrent++;
281
2a258f40 282
5b4ed716 283 if(ngoodtrkt0<2){
5b4ed716 284 t0def=-999;
285 deltat0def=0.600;
286 fT0SigmaT0def[0]=t0def;
287 fT0SigmaT0def[1]=deltat0def;
288 fT0SigmaT0def[2]=ngoodtrkt0;
289 fT0SigmaT0def[3]=ngoodtrkt0;
290 //goto finish;
291 }
292 if(ngoodtrkt0>=2){
293 // Decide how many tracks in set
294 Int_t ntracksinset = std::min(ngoodtrkt0,nmaxtracksinsetCurrent);
295 Int_t nset=1;
296
297 if(ngoodtrkt0>nmaxtracksinsetCurrent) {nset= (Int_t)(ngoodtrkt0/ntracksinset)+1;}
298
299 // Loop over selected sets
300
301 if(nset>=1){
302 for (Int_t i=0; i< nset; i++) {
2a258f40 303 // printf("Set %i of %i\n",i+1,nset);
5b4ed716 304 Float_t t0best=999.;
305 Float_t eT0best=999.;
306 Float_t chisquarebest=99999.;
307 Int_t npionbest=0;
308
995c3398 309 fTracksT0->Clear();
5b4ed716 310 Int_t ntracksinsetmy=0;
5b4ed716 311 for (Int_t itrk=0; itrk<ntracksinset; itrk++) {
312 Int_t index = itrk+i*ntracksinset;
62f44f07 313 if(index < fGTracks->GetEntries()){
62f44f07 314 AliESDtrack *t=(AliESDtrack*)fGTracks->At(index);
62f44f07 315 fTracksT0->AddLast(t);
5b4ed716 316 ntracksinsetmy++;
317 }
318 }
62f44f07 319
5b4ed716 320 // Analyse it
321
2a258f40 322 Int_t assparticle[nmaxtracksinsetMax];
323 Float_t exptof[nmaxtracksinsetMax][3];
324 Float_t timeofflight[nmaxtracksinsetMax];
325 Float_t momentum[nmaxtracksinsetMax];
326 Float_t timezero[nmaxtracksinsetMax];
327 Float_t weightedtimezero[nmaxtracksinsetMax];
328 Float_t beta[nmaxtracksinsetMax];
329 Float_t texp[nmaxtracksinsetMax];
330 Float_t dtexp[nmaxtracksinsetMax];
331 Float_t sqMomError[nmaxtracksinsetMax];
332 Float_t sqTrackError[nmaxtracksinsetMax];
5b4ed716 333 Float_t massarray[3]={0.13957,0.493677,0.9382723};
2a258f40 334 Float_t tracktoflen[nmaxtracksinsetMax];
335 Float_t besttimezero[nmaxtracksinsetMax];
336 Float_t besttexp[nmaxtracksinsetMax];
337 Float_t besttimeofflight[nmaxtracksinsetMax];
338 Float_t bestmomentum[nmaxtracksinsetMax];
339 Float_t bestchisquare[nmaxtracksinsetMax];
340 Float_t bestweightedtimezero[nmaxtracksinsetMax];
341 Float_t bestsqTrackError[nmaxtracksinsetMax];
342 Int_t imass[nmaxtracksinsetMax];
5b4ed716 343
344 for (Int_t j=0; j<ntracksinset; j++) {
345 assparticle[j] = 3;
346 timeofflight[j] = 0;
347 momentum[j] = 0;
348 timezero[j] = 0;
349 weightedtimezero[j] = 0;
350 beta[j] = 0;
351 texp[j] = 0;
352 dtexp[j] = 0;
353 sqMomError[j] = 0;
354 sqTrackError[j] = 0;
355 tracktoflen[j] = 0;
356 besttimezero[j] = 0;
357 besttexp[j] = 0;
358 besttimeofflight[j] = 0;
359 bestmomentum[j] = 0;
360 bestchisquare[j] = 0;
361 bestweightedtimezero[j] = 0;
362 bestsqTrackError[j] = 0;
363 imass[j] = 1;
364 }
365
62f44f07 366 for (Int_t j=0; j<fTracksT0->GetEntries(); j++) {
62f44f07 367 AliESDtrack *t=(AliESDtrack*)fTracksT0->At(j);
5b4ed716 368 Double_t momOld=t->GetP();
369 Double_t mom=momOld-0.0036*momOld;
370 Double_t time=t->GetTOFsignal();
371
372 time*=1.E-3; // tof given in nanoseconds
373 Double_t exptime[10]; t->GetIntegratedTimes(exptime);
374 Double_t toflen=t->GetIntegratedLength();
375 toflen=toflen/100.; // toflen given in m
376
377 timeofflight[j]=time;
378 tracktoflen[j]=toflen;
379 exptof[j][0]=exptime[2]*1.E-3+fTimeCorr;// in ns
380 exptof[j][1]=exptime[3]*1.E-3+fTimeCorr;
381 exptof[j][2]=exptime[4]*1.E-3+fTimeCorr;
382 momentum[j]=mom;
383 assparticle[j]=3;
384
385 } //end for (Int_t j=0; j<ntracksinsetmy; j++) {
386
387 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
388 beta[itz]=momentum[itz]/sqrt(massarray[0]*massarray[0]
389 +momentum[itz]*momentum[itz]);
390 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 391 sqTrackError[itz]=sqMomError[itz]; //in ns
5b4ed716 392 timezero[itz]=exptof[itz][0]-timeofflight[itz];// in ns
393 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
394 sumAllweightspi+=1./sqTrackError[itz];
395 meantzeropi+=weightedtimezero[itz];
396 } // end loop for (Int_t itz=0; itz< ntracksinset;itz++)
397
398
399 // Then, Combinatorial Algorithm
400
401 if(ntracksinsetmy<2 )break;
402
403 for (Int_t j=0; j<ntracksinsetmy; j++) {
404 imass[j] = 3;
405 }
406
62f44f07 407 Int_t ncombinatorial = ToCalculatePower(3,ntracksinsetmy);
5b4ed716 408
409 // Loop on mass hypotheses
410 for (Int_t k=0; k < ncombinatorial;k++) {
411 for (Int_t j=0; j<ntracksinsetmy; j++) {
62f44f07 412 imass[j] = (k % ToCalculatePower(3,ntracksinsetmy-j))/ToCalculatePower(3,ntracksinsetmy-j-1);
5b4ed716 413 texp[j]=exptof[j][imass[j]];
414 dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
415 }
90beec49 416
5b4ed716 417 Float_t sumAllweights=0.;
418 Float_t meantzero=0.;
419 Float_t eMeanTzero=0.;
420
421 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
2a258f40 422 sqTrackError[itz]=dtexp[itz]*dtexp[itz]*1E-6; //in ns2
5b4ed716 423
424 timezero[itz]=texp[itz]-timeofflight[itz];// in ns
425
426 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
427 sumAllweights+=1./sqTrackError[itz];
428 meantzero+=weightedtimezero[itz];
429
430 } // end loop for (Int_t itz=0; itz<15;itz++)
431
432 meantzero=meantzero/sumAllweights; // it is given in [ns]
433 eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
434
435 // calculate chisquare
5b4ed716 436 Float_t chisquare=0.;
437 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
1fde62a1 438 chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
5b4ed716 439 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
440
441 if(chisquare<=chisquarebest){
442 for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
443
444 bestsqTrackError[iqsq]=sqTrackError[iqsq];
445 besttimezero[iqsq]=timezero[iqsq];
446 bestmomentum[iqsq]=momentum[iqsq];
447 besttimeofflight[iqsq]=timeofflight[iqsq];
448 besttexp[iqsq]=texp[iqsq];
449 bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
1fde62a1 450 bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
5b4ed716 451 }
452
453 Int_t npion=0;
454 for (Int_t j=0; j<ntracksinsetmy; j++) {
455 assparticle[j]=imass[j];
456 if(imass[j] == 0) npion++;
457 }
458 npionbest=npion;
459 chisquarebest=chisquare;
460 t0best=meantzero;
461 eT0best=eMeanTzero;
462 } // close if(dummychisquare<=chisquare)
5b4ed716 463 }
464
2a258f40 465 Double_t chi2cut[nmaxtracksinsetMax];
5b4ed716 466 chi2cut[0] = 0;
467 chi2cut[1] = 6.6; // corresponding to a C.L. of 0.01
468 for (Int_t j=2; j<ntracksinset; j++) {
469 chi2cut[j] = chi2cut[1] * TMath::Sqrt(j*1.);
470 }
471
472 Double_t chi2singlecut = chi2cut[ntracksinsetmy-1]/ntracksinsetmy + TMath::Abs(chisquarebest-chi2cut[ntracksinsetmy-1])/ntracksinsetmy;
473
721ed687 474 // printf("tracks removed with a chi2 > %f (chi2total = %f w.r.t. the limit of %f)\n",chi2singlecut,chisquarebest,chi2cut[ntracksinsetmy-1]);
5b4ed716 475
476 Bool_t kRedoT0 = kFALSE;
477 ntracksinsetmyCut = ntracksinsetmy;
2a258f40 478 Bool_t usetrack[nmaxtracksinsetMax];
5b4ed716 479 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
480 usetrack[icsq] = kTRUE;
481 if((bestchisquare[icsq] > chisquarebest*0.5 && ntracksinsetmy > 2) || (bestchisquare[icsq] > chi2singlecut)){
90beec49 482 kRedoT0 = kTRUE;
483 ntracksinsetmyCut--;
484 usetrack[icsq] = kFALSE;
721ed687 485 // printf("tracks chi2 = %f\n",bestchisquare[icsq]);
5b4ed716 486 }
487 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
488
5b4ed716 489 // Loop on mass hypotheses Redo
490 if(kRedoT0 && ntracksinsetmyCut > 1){
491 // printf("Redo T0\n");
492 for (Int_t k=0; k < ncombinatorial;k++) {
493 for (Int_t j=0; j<ntracksinsetmy; j++) {
62f44f07 494 imass[j] = (k % ToCalculatePower(3,ntracksinsetmy-j)) / ToCalculatePower(3,ntracksinsetmy-j-1);
5b4ed716 495 texp[j]=exptof[j][imass[j]];
496 dtexp[j]=GetMomError(imass[j], momentum[j], texp[j]);
497 }
498
499 Float_t sumAllweights=0.;
500 Float_t meantzero=0.;
501 Float_t eMeanTzero=0.;
502
503 for (Int_t itz=0; itz<ntracksinsetmy;itz++) {
504 if(! usetrack[itz]) continue;
2a258f40 505 sqTrackError[itz]=dtexp[itz]*dtexp[itz]*1E-6; //in ns2
5b4ed716 506
507 timezero[itz]=texp[itz]-timeofflight[itz];// in ns
508
509 weightedtimezero[itz]=timezero[itz]/sqTrackError[itz];
510 sumAllweights+=1./sqTrackError[itz];
511 meantzero+=weightedtimezero[itz];
512
513 } // end loop for (Int_t itz=0; itz<15;itz++)
514
515 meantzero=meantzero/sumAllweights; // it is given in [ns]
516 eMeanTzero=sqrt(1./sumAllweights); // it is given in [ns]
517
518 // calculate chisquare
519
520 Float_t chisquare=0.;
521 for (Int_t icsq=0; icsq<ntracksinsetmy;icsq++) {
522 if(! usetrack[icsq]) continue;
1fde62a1 523 chisquare+=(timezero[icsq]-meantzero)*(timezero[icsq]-meantzero)/sqTrackError[icsq];
5b4ed716 524 } // end loop for (Int_t icsq=0; icsq<15;icsq++)
525
526 Int_t npion=0;
527 for (Int_t j=0; j<ntracksinsetmy; j++) {
528 assparticle[j]=imass[j];
529 if(imass[j] == 0) npion++;
530 }
531
90beec49 532 if(chisquare<=chisquarebest && npion>0){
5b4ed716 533 for(Int_t iqsq = 0; iqsq<ntracksinsetmy; iqsq++) {
534 if(! usetrack[iqsq]) continue;
535 bestsqTrackError[iqsq]=sqTrackError[iqsq];
536 besttimezero[iqsq]=timezero[iqsq];
537 bestmomentum[iqsq]=momentum[iqsq];
538 besttimeofflight[iqsq]=timeofflight[iqsq];
539 besttexp[iqsq]=texp[iqsq];
540 bestweightedtimezero[iqsq]=weightedtimezero[iqsq];
1fde62a1 541 bestchisquare[iqsq]=(timezero[iqsq]-meantzero)*(timezero[iqsq]-meantzero)/sqTrackError[iqsq];
5b4ed716 542 }
543
544 npionbest=npion;
545 chisquarebest=chisquare;
546 t0best=meantzero;
547 eT0best=eMeanTzero;
548 } // close if(dummychisquare<=chisquare)
549
550 }
551 }
552
553 // filling histos
554 Float_t confLevel=999;
555
556 // Sets with decent chisquares
2a258f40 557 // printf("Chi2best of the set = %f \n",chisquarebest);
5b4ed716 558
559 if(chisquarebest<999.){
560 Double_t dblechisquare=(Double_t)chisquarebest;
561 confLevel=(Float_t)TMath::Prob(dblechisquare,ntracksinsetmyCut-1);
5b4ed716 562
90beec49 563 Int_t ntrackincurrentsel=0;
5b4ed716 564 for(Int_t icsq=0; icsq<ntracksinsetmy;icsq++){
565
566 if(! usetrack[icsq]) continue;
567
90beec49 568 ntrackincurrentsel++;
5b4ed716 569 }
570
2a258f40 571 // printf("%i) CL(Chi2) = %f < 0.01\n",ngoodsetsSel,confLevel);
572
5b4ed716 573 // Pick up only those with C.L. >1%
5b4ed716 574 if(confLevel>0.01 && ngoodsetsSel<200){
575 chiSquarebestSel[ngoodsetsSel]=chisquarebest;
576 confLevelbestSel[ngoodsetsSel]=confLevel;
577 t0bestSel[ngoodsetsSel]=t0best/eT0best/eT0best;
578 eT0bestSel[ngoodsetsSel]=1./eT0best/eT0best;
579 t0bestallSel += t0best/eT0best/eT0best;
580 sumWt0bestallSel += 1./eT0best/eT0best;
581 ngoodsetsSel++;
2a258f40 582 ngoodtrktrulyused+=ntracksinsetmyCut;
721ed687 583 // printf("T0best = %f +/- %f (%i-%i) -- conflevel = %f\n",t0best,eT0best,ntrackincurrentsel,npionbest,confLevel);
5b4ed716 584 }
585 else{
586 // printf("conflevel = %f -- ngoodsetsSel = %i -- ntrackset = %i\n",confLevel,ngoodsetsSel,ntracksinsetmy);
587 }
588 }
62f44f07 589 fTracksT0->Clear();
5b4ed716 590 nsets++;
591
592 } // end for the current set
593
90beec49 594 //Redo the computation of the best in order to esclude very bad samples
595 if(ngoodsetsSel > 1){
596 Double_t t0BestStep1 = t0bestallSel/sumWt0bestallSel;
597 Int_t nsamples=ngoodsetsSel;
598 ngoodsetsSel=0;
599 t0bestallSel=0;
600 sumWt0bestallSel=0;
601 for (Int_t itz=0; itz<nsamples;itz++) {
602 if(TMath::Abs(t0bestSel[itz]/eT0bestSel[itz]-t0BestStep1)<1.0){
603 t0bestallSel += t0bestSel[itz];
604 sumWt0bestallSel += eT0bestSel[itz];
605 ngoodsetsSel++;
721ed687 606 // printf("not rejected %f +/- %f\n",t0bestSel[itz]/eT0bestSel[itz],1./TMath::Sqrt(eT0bestSel[itz]));
90beec49 607 }
608 else{
721ed687 609 // printf("rejected %f +/- %f\n",t0bestSel[itz]/eT0bestSel[itz],1./TMath::Sqrt(eT0bestSel[itz]));
90beec49 610 }
611 }
612 }
613 if(ngoodsetsSel < 1){
614 sumWt0bestallSel = 0.0;
615 }
616 //--------------------------------End recomputation
617
5b4ed716 618 nUsedTracks = ngoodtrkt0;
619 if(strstr(option,"all")){
620 if(sumAllweightspi>0.){
621 meantzeropi=meantzeropi/sumAllweightspi; // it is given in [ns]
622 eMeanTzeroPi=sqrt(1./sumAllweightspi); // it is given in [ns]
623 }
624
2a258f40 625 // printf("t0bestallSel = %f -- eT0bestallSel = %f\n",t0bestallSel,sumWt0bestallSel);
626
5b4ed716 627 if(sumWt0bestallSel>0){
628 t0bestallSel = t0bestallSel/sumWt0bestallSel;
629 eT0bestallSel = sqrt(1./sumWt0bestallSel);
2a258f40 630 // printf("Final) t0bestallSel = %f -- eT0bestallSel = %f\n",t0bestallSel,eT0bestallSel);
5b4ed716 631 }// end of if(sumWt0bestallSel>0){
632
5b4ed716 633 }
634
635 t0def=t0bestallSel;
636 deltat0def=eT0bestallSel;
5b4ed716 637
638 fT0SigmaT0def[0]=t0def;
2a258f40 639 fT0SigmaT0def[1]=TMath::Sqrt(deltat0def*deltat0def);//*ngoodtrktrulyused/(ngoodtrktrulyused-1));
5b4ed716 640 fT0SigmaT0def[2]=ngoodtrkt0;
641 fT0SigmaT0def[3]=ngoodtrktrulyused;
642 }
643 }
62f44f07 644
62f44f07 645 fGTracks->Clear();
646
2a258f40 647 if(fT0SigmaT0def[1] < 0.00001) fT0SigmaT0def[1] = 0.6;
648
649 bench->Stop("t0computation");
650
651 fT0SigmaT0def[4]=bench->GetRealTime("t0computation");
652 fT0SigmaT0def[5]=bench->GetCpuTime("t0computation");
653
654// bench->Print("t0computation");
655// 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]));
656
90beec49 657 delete bench;
658 bench=NULL;
5b4ed716 659
536031f2 660 return fT0SigmaT0def;
661 }
662//__________________________________________________________________
8f589502 663Float_t AliTOFT0v1::GetMomError(Int_t index, Float_t mom, Float_t texp) const
536031f2 664{
8f589502 665 // Take the error extimate for the TOF time in the track reconstruction
536031f2 666
536031f2 667 static const Double_t kMasses[]={
668 0.000511, 0.105658, 0.139570, 0.493677, 0.938272, 1.875613
669 };
670
671 Double_t mass=kMasses[index+2];
536031f2 672
2a258f40 673 Float_t sigma = fPIDesd->GetTOFResponse().GetExpectedSigma(mom,texp,mass);
536031f2 674
675 return sigma;
676}
14b2cbea 677
678//__________________________________________________________________
679Bool_t AliTOFT0v1::AcceptTrack(AliESDtrack *track)
680{
681
682 /* TPC refit */
683 if (!(track->GetStatus() & AliESDtrack::kTPCrefit)) return kFALSE;
684 /* do not accept kink daughters */
685 if (track->GetKinkIndex(0)>0) return kFALSE;
686 /* N clusters TPC */
687 if (track->GetTPCclusters(0) < 50) return kFALSE;
688 /* chi2 TPC */
689 if (track->GetTPCchi2()/Float_t(track->GetTPCclusters(0)) > 3.5) return kFALSE;
690 /* sigma to vertex */
691 if (GetSigmaToVertex(track) > 4.) return kFALSE;
692
693 /* accept track */
694 return kTRUE;
695
696}
697
698//____________________________________________________________________
8f589502 699Float_t AliTOFT0v1::GetSigmaToVertex(AliESDtrack* esdTrack) const
14b2cbea 700{
701 // Calculates the number of sigma to the vertex.
702
703 Float_t b[2];
704 Float_t bRes[2];
705 Float_t bCov[3];
706 esdTrack->GetImpactParameters(b,bCov);
707
708 if (bCov[0]<=0 || bCov[2]<=0) {
709 bCov[0]=0; bCov[2]=0;
710 }
711 bRes[0] = TMath::Sqrt(bCov[0]);
712 bRes[1] = TMath::Sqrt(bCov[2]);
713
714 // -----------------------------------
715 // How to get to a n-sigma cut?
716 //
717 // The accumulated statistics from 0 to d is
718 //
719 // -> Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
720 // -> 1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
721 //
722 // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-d**2)/2)
723 // Can this be expressed in a different way?
724
725 if (bRes[0] == 0 || bRes[1] ==0)
726 return -1;
727
62f44f07 728 //Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
729 Float_t d = TMath::Sqrt(ToCalculatePower(b[0]/bRes[0],2) + ToCalculatePower(b[1]/bRes[1],2));
14b2cbea 730
731 // work around precision problem
732 // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
733 // 1e-15 corresponds to nsigma ~ 7.7
734 if (TMath::Exp(-d * d / 2) < 1e-15)
735 return 1000;
736
737 Float_t nSigma = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);
738 return nSigma;
739}
90beec49 740//____________________________________________________________________
741
742Bool_t AliTOFT0v1::CheckTPCMatching(AliESDtrack *track,Int_t imass) const{
743 Bool_t status = kFALSE;
744
745 Double_t exptimes[5];
746 track->GetIntegratedTimes(exptimes);
747
748 Float_t dedx = track->GetTPCsignal();
749
750 Double_t ptpc[3];
751 track->GetInnerPxPyPz(ptpc);
752 Float_t momtpc=TMath::Sqrt(ptpc[0]*ptpc[0] + ptpc[1]*ptpc[1] + ptpc[2]*ptpc[2]);
753
754 if(imass > 2 || imass < 0) return status;
755 Int_t i = imass+2;
756
757 AliPID::EParticleType type=AliPID::EParticleType(i);
758
759 Float_t dedxExp = fPIDesd->GetTPCResponse().GetExpectedSignal(momtpc,type);
760 Float_t resolutionTPC = fPIDesd->GetTPCResponse().GetExpectedSigma(momtpc,track->GetTPCsignalN(),type);
761
762 if(TMath::Abs(dedx - dedxExp) < 5 * resolutionTPC){
763 status = kTRUE;
764 }
765
766 return status;
767}
62f44f07 768
769//____________________________________________________________________
770Float_t AliTOFT0v1::ToCalculatePower(Float_t base, Int_t exponent) const
771{
772 //
773 // Returns base^exponent
774 //
775
776 Float_t power=1.;
777
778 for (Int_t ii=exponent; ii>0; ii--)
779 power=power*base;
780
781 return power;
782
783}
784//____________________________________________________________________
785Int_t AliTOFT0v1::ToCalculatePower(Int_t base, Int_t exponent) const
786{
787 //
788 // Returns base^exponent
789 //
790
791 Int_t power=1;
792
793 for (Int_t ii=exponent; ii>0; ii--)
794 power=power*base;
795
796 return power;
797
798}