]>
Commit | Line | Data |
---|---|---|
15d37333 | 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 | // | |
16 | // | |
17 | // | |
18 | // | |
19 | //------------------------------------------------------- | |
20 | // Implementation of the Cosmic tracker | |
21 | // | |
22 | // Origin: Xianguo Lu lu@physi.uni-heidelberg.de Xianguo.Lu@cern.ch | |
23 | // | |
24 | //========================================================================================= | |
25 | // Motivation: | |
26 | // | |
27 | // In the default reconstruction in the ALICE the cosmic tracks are found as two independent particles. | |
28 | // | |
29 | // In general any of subtracks can be used for the physics studies. In order to avoid the double counting, | |
30 | // the track from the upper hemisphere can be used. | |
31 | // | |
32 | // The momentum resolution is determined by the lever arm (1/L^2) and by the number of clusters | |
33 | // used for the track fitting (1/sqrt(Ncl)). | |
34 | // Combining/refitting the two segments together significantly better momentum resolution can be obtained. | |
35 | // sigma_{1/pt} ~ 8x10^-3 - defaul tracking (e.g only upper track) | |
36 | // sigma_{1/pt} ~ 8x10^-4 - combined tracking | |
37 | //=========================================================================================== | |
38 | // | |
39 | // Interface/Implementation: | |
40 | // The class AliCosmicTracker provides functionality to find and refit the cosmic tracks. As a starting point, the events reconstruccted using standard tracking are used. | |
41 | // Input: AliESDEvent | |
42 | // Output: TClonesArray of the AliESDCosmicTrack | |
43 | // The array is stored as a data member of the tracker. | |
44 | // | |
45 | // The cosmic tracker can be called in the user analysis code (standard analisys train, using the AliAnalysisTask, | |
46 | // see e.g. AliAnalysisTaskCosmicTracker.h). In oreder to make an analysis simpler and faster it is planned to use the tracker already in the standard reconstruction (To be done). | |
47 | // | |
48 | //=========================================================================================== | |
49 | // Algorithm: | |
50 | // 1. Reads an ESD event - SetESDEvent() function | |
51 | // 2. Loop over single tracks - Process() function | |
52 | // cuts are applied for individual ESD tracks (see function ESDtrckCut()). Only ESD tracks with TPCrefit, | |
53 | // no kink and with ESDfriends will be selected. | |
54 | // User defined cuts (as a pointer to the static function) can be used. (Expert usage) | |
55 | ||
56 | // 3. Double loop over tracks - Process() function | |
57 | // a.) if not pair ( see function IsPair() ) continue; | |
58 | // To accept the pair the tracks should be close together in the parameter space (AliExternalTrackParam - fP[0]-[4], also cut on ESD-phi and -theta) | |
59 | // Absolute, and relative (pull) cut are used | |
60 | // The cuts can be modified beyond default values via SetCut***(). | |
61 | // | |
62 | // b.) Each pair is fit via AliTPCCosmicTrackfit::CombineESDtracks | |
63 | // c.) For each pair one AliESDCosmicTrack object is stored in the fTrackStack, which can be passed out via TClonesArray *arr = fCosmicTracker->GetTrackStack(); | |
64 | // | |
65 | // | |
66 | //=========================================================================================== | |
67 | // Algorithm numerical debugging: | |
68 | // The AliCosmicTracker can be used in the different debug/verbose level (see fDebugLevel) | |
69 | // Several intermediate variables can be stored in the trees, printout, or draw. | |
70 | // Given functionality (dumping of variables to the tree) was also used for the tuning of the pair | |
71 | // selection criterias, and for validation of the fit functionality. | |
72 | // | |
73 | //=========================================================================================== | |
74 | // Usage: | |
75 | // AliCosmicTracker *fCosmicTracker = new AliCosmicTracker(debuglevel, tag); | |
76 | // fCosmicTracker->SetESDEvent(fESDEvent); //fTrackStack will be automatically cleared/emptied | |
77 | // Int_t npair = fCosmicTracker->Process(processtag, kprint); //processtag only relavant if (debuglevel & 4) to draw the tracks in png; number of cosmic candidates are returned; if kprint the event is draw to png | |
78 | // | |
79 | // | |
80 | // Advanced usage: | |
81 | // fUserCut can be assigned externally so that additional ESDtrack cut can be applied in the very beginning together with those in ESDtrackCut() | |
82 | // | |
83 | // Example: | |
84 | /* | |
85 | //define static (important!!) cut function in analysis task, e.g. AliAnalysisTaskCosmicTracker | |
86 | //1) in AliAnalysisTaskCosmicTracker.h | |
87 | static Bool_t TrackCut(AliESDtrack *trk); | |
88 | ||
89 | //2) in AliAnalysisTaskCosmicTracker.cxx | |
90 | Bool_t AliAnalysisTaskCosmicTracker::TrackCut(AliESDtrack *trk) | |
91 | { | |
92 | // | |
93 | //external track cut in addition to the one in AliCosmicTracker (example) | |
94 | // | |
95 | if(!trk->GetTRDncls()) | |
96 | return kFALSE; | |
97 | ||
98 | return kTRUE; | |
99 | } | |
100 | //set user cut function | |
101 | fCosmicTracker = new AliCosmicTracker; | |
102 | fCosmicTracker->SetUserESDtrackCut(AliAnalysisTaskCosmicTracker::TrackCut); | |
103 | */ | |
104 | ||
105 | #include <TTreeStream.h> | |
106 | ||
107 | #include "AliESDEvent.h" | |
108 | #include "AliTPCseed.h" | |
109 | #include "AliTrackerBase.h" | |
110 | ||
111 | #include "AliESDCosmicTrack.h" | |
112 | #include "AliCosmicTracker.h" | |
113 | #include "AliTPCCosmicUtils.h" | |
114 | #include "AliTPCCosmicTrackfit.h" | |
115 | ||
116 | AliCosmicTracker::AliCosmicTracker(const Int_t dlev, const TString tag): | |
117 | fUserCut(0x0) | |
118 | , fStreamer(0x0), fDebugLevel(dlev) | |
119 | , fESDEvent(0x0) | |
3aa6a136 | 120 | , fCosmicTrackfit(0x0) |
15d37333 | 121 | , fTrackStack(0x0) |
3aa6a136 | 122 | , fTrack0() |
123 | , fTrack1() | |
124 | , fRawVtx(-999,-999,-999) | |
125 | , fRawDCA(-999) | |
15d37333 | 126 | , fdPhi(-999) |
3aa6a136 | 127 | , fCutdPhi(-999) |
15d37333 | 128 | , fdTheta(-999) |
3aa6a136 | 129 | , fCutdTheta(-999) |
130 | , fErrFlagESDtrackCut(-999) | |
131 | , fErrFlagIsPair(-999) | |
132 | , fErrFlagCosmicTrackfit(-999) | |
15d37333 | 133 | { |
134 | // | |
135 | //constructor | |
136 | // | |
137 | ||
138 | if(fDebugLevel & 1) | |
139 | fStreamer = new TTreeSRedirector(Form("CosmicTracker_%s.root", tag.Data())); | |
140 | ||
3aa6a136 | 141 | fCosmicTrackfit = new AliTPCCosmicTrackfit(0, "AliCosmicTracker"); |
15d37333 | 142 | fTrackStack = new TClonesArray("AliESDCosmicTrack",100); |
143 | ||
144 | for(Int_t ii=0; ii<5; ii++){ | |
145 | fDelta[ii] = -999; | |
146 | fPull[ii] = -999; | |
147 | } | |
148 | ||
149 | fCutdPhi = 19e-3*5; | |
150 | fCutdTheta = 10e-3*5; | |
151 | ||
152 | fCutPull[0] = 1.9 *10; | |
153 | fCutPull[1] = 1.5 *1e10; | |
154 | fCutPull[2] = 1.9 *10;//bug-fixed! | |
155 | fCutPull[3] = 0.4 *1e10; | |
156 | fCutPull[4] = 3.6 *10; | |
157 | ||
158 | fCutDelta[0] = 0.8 * 10; | |
159 | fCutDelta[1] = 2.7 * 10; | |
160 | fCutDelta[2] = 0.012 * 10;//bug-fixed! | |
161 | fCutDelta[3] = 0.007 * 10; | |
162 | fCutDelta[4] = 0.05 * 10; | |
163 | } | |
164 | ||
165 | AliCosmicTracker::~AliCosmicTracker() | |
166 | { | |
167 | // | |
168 | //destructor | |
169 | // | |
170 | delete fStreamer; | |
3aa6a136 | 171 | delete fCosmicTrackfit; |
15d37333 | 172 | delete fTrackStack; |
173 | } | |
174 | ||
175 | void AliCosmicTracker::SetESDEvent(AliESDEvent *esd) | |
176 | { | |
177 | // | |
178 | //set esd event | |
179 | // | |
15d37333 | 180 | fESDEvent = esd; |
181 | fTrackStack->Clear(); | |
182 | } | |
183 | ||
184 | Int_t AliCosmicTracker::Process(const TString tag, const Bool_t kprint) | |
185 | { | |
186 | // | |
187 | //double loop over combinations of esd tracks, cosmic event candidates sotred in fTrackStack | |
188 | // | |
189 | ||
190 | Int_t npair=0; | |
191 | const Int_t ntrk = fESDEvent->GetNumberOfTracks(); | |
192 | Int_t trkcounter[ntrk]; | |
193 | for(Int_t ii=0; ii<ntrk; ii++){ | |
194 | trkcounter[ii]=0; | |
195 | } | |
196 | ||
197 | Double_t findabler0 = -999; | |
198 | Double_t findabler1 = -999; | |
199 | ||
3aa6a136 | 200 | fErrFlagESDtrackCut = 0; |
201 | fErrFlagIsPair = 0; | |
202 | fErrFlagCosmicTrackfit = 0; | |
203 | ||
15d37333 | 204 | for(Int_t itrk=0; itrk<ntrk; itrk++){ |
3aa6a136 | 205 | if(!ESDtrackCut(fESDEvent->GetTrack(itrk), findabler0)){ |
15d37333 | 206 | continue; |
3aa6a136 | 207 | } |
15d37333 | 208 | |
209 | for(Int_t jtrk=itrk+1; jtrk<ntrk; jtrk++){ | |
210 | if(!ESDtrackCut(fESDEvent->GetTrack(jtrk), findabler1)) | |
211 | continue; | |
212 | ||
213 | AliESDtrack * trk0 = fESDEvent->GetTrack(itrk); | |
214 | AliESDtrack * trk1 = fESDEvent->GetTrack(jtrk); | |
215 | if( IsPair(trk0, trk1) ){ | |
3aa6a136 | 216 | const Bool_t kfit = fCosmicTrackfit->CombineESDtracks(trk0, trk1); |
217 | fErrFlagCosmicTrackfit = fCosmicTrackfit->GetStatus(); | |
15d37333 | 218 | |
3aa6a136 | 219 | if(kfit){ |
220 | fRawVtx = fCosmicTrackfit->ImpactParameter3D(); | |
221 | fRawDCA = fCosmicTrackfit->ImpactParameter2D().Mag(); | |
15d37333 | 222 | |
3aa6a136 | 223 | const Int_t ncls = fCosmicTrackfit->GetFitNcls(); |
224 | const Double_t leverarm = fCosmicTrackfit->GetFitLeverArm(); | |
225 | const Double_t chi2percluster = fCosmicTrackfit->GetChi2PerCluster(); | |
226 | const Double_t impactD = fCosmicTrackfit->GetImpactD(); | |
227 | const Double_t impactZ = fCosmicTrackfit->GetImpactZ(); | |
15d37333 | 228 | |
3aa6a136 | 229 | const Double_t findableratio = TMath::Min(findabler0, findabler1); |
15d37333 | 230 | |
231 | trkcounter[itrk]++; | |
232 | trkcounter[jtrk]++; | |
3aa6a136 | 233 | const Bool_t isreuse = (trkcounter[itrk]>1 || trkcounter[jtrk]>1); |
15d37333 | 234 | |
3aa6a136 | 235 | const TVector3 icU = fCosmicTrackfit->GetInnerClusterUp(); |
236 | const TVector3 icD = fCosmicTrackfit->GetInnerClusterLow(); | |
15d37333 | 237 | |
238 | Int_t idup = itrk; | |
239 | Int_t idlow = jtrk; | |
3aa6a136 | 240 | if(fCosmicTrackfit->IsSwap()){ |
15d37333 | 241 | const Int_t idtmp = idup; |
242 | idup = idlow; | |
243 | idlow = idtmp; | |
244 | ||
245 | AliExternalTrackParam tptmp = fTrack0; | |
246 | fTrack0 = fTrack1; | |
247 | fTrack1 = tptmp; | |
248 | } | |
249 | ||
250 | if( | |
251 | (fDebugLevel & 4) && | |
3aa6a136 | 252 | ( (isreuse && ntrk<=4) || kprint ) |
15d37333 | 253 | ){ |
254 | AliESDtrack * trks[]={fESDEvent->GetTrack(idup), fESDEvent->GetTrack(idlow)}; | |
255 | AliTPCCosmicUtils::DrawTracks(trks, Form("reuse_%03d_%03d_%03d_%s", ntrk, itrk, jtrk, tag.Data())); | |
256 | } | |
257 | if( | |
258 | (fDebugLevel & 8) && | |
3aa6a136 | 259 | impactD > 160 && findableratio < 0.56 |
15d37333 | 260 | ){ |
261 | AliESDtrack * trks[]={fESDEvent->GetTrack(idup), fESDEvent->GetTrack(idlow)}; | |
3aa6a136 | 262 | AliTPCCosmicUtils::DrawTracks(trks, Form("largevtd_%.f_%.f_%03d_%03d_%03d_%s", impactD, findableratio, ntrk, itrk, jtrk, tag.Data())); |
15d37333 | 263 | } |
264 | ||
3aa6a136 | 265 | AliESDCosmicTrack costrk(idup, idlow, fCosmicTrackfit->GetTrackParamUp(), fCosmicTrackfit->GetTrackParamLow(), &fTrack0, &fTrack1, ncls, leverarm, chi2percluster, impactD, impactZ, isreuse, findableratio, icU, icD); |
15d37333 | 266 | new((*fTrackStack)[npair]) AliESDCosmicTrack(costrk); |
267 | npair++; | |
3aa6a136 | 268 | |
269 | if(fDebugLevel & 1) | |
270 | WriteStreamer(ntrk, &costrk); | |
271 | ||
15d37333 | 272 | } |
273 | else{ | |
274 | if(fDebugLevel & 16){ | |
275 | if(ntrk==2){ | |
276 | AliESDtrack * trks[]={trk0, trk1}; | |
3aa6a136 | 277 | AliTPCCosmicUtils::DrawTracks(trks, Form("failCosmicFit_%02d_%03d_%03d_%03d_%s", fCosmicTrackfit->GetStatus(), ntrk, itrk, jtrk, tag.Data())); |
15d37333 | 278 | } |
279 | } | |
280 | } | |
281 | } | |
282 | else{ | |
283 | if(fDebugLevel & 32){ | |
284 | if(ntrk==2){ | |
285 | AliESDtrack * trks[]={trk0, trk1}; | |
286 | AliTPCCosmicUtils::DrawTracks(trks, Form("failIsPair_%02d_%03d_%03d_%03d_%s", fErrFlagIsPair, ntrk, itrk, jtrk, tag.Data())); | |
287 | } | |
288 | } | |
289 | } | |
290 | } | |
291 | } | |
292 | ||
293 | return npair; | |
294 | } | |
295 | ||
296 | Bool_t AliCosmicTracker::IsPair(AliESDtrack * trk0, AliESDtrack * trk1) | |
297 | { | |
298 | // | |
299 | //check whether the two tracks come from one cosmic ray | |
300 | // | |
301 | ||
15d37333 | 302 | //dphi + pi should = 0 |
303 | fdPhi = AliTPCCosmicUtils::AngleInRange(trk0->Phi() - trk1->Phi() + TMath::Pi()); | |
304 | if( TMath::Abs(fdPhi) > fCutdPhi ){ | |
305 | fErrFlagIsPair = 1; | |
306 | return kFALSE; | |
307 | } | |
308 | ||
309 | fdTheta = AliTPCCosmicUtils::AngleInRange(trk0->Theta() + trk1->Theta() + TMath::Pi()); | |
310 | if( TMath::Abs(fdTheta) > fCutdTheta ){ | |
311 | fErrFlagIsPair = 2; | |
312 | return kFALSE; | |
313 | } | |
314 | ||
315 | //use fIp, the comments on the web is wrong (M. Ivanov) | |
316 | if(!trk0->GetInnerParam()){ | |
317 | fErrFlagIsPair = 3; | |
318 | return kFALSE; | |
319 | } | |
320 | if(!trk1->GetInnerParam()){ | |
321 | fErrFlagIsPair = 4; | |
322 | return kFALSE; | |
323 | } | |
324 | ||
325 | AliExternalTrackParam tmptrk[]={*(trk0->GetInnerParam()), *(trk1->GetInnerParam())}; | |
326 | ||
327 | if(fDebugLevel & 2){ | |
328 | printf("\n************************ raw ESD:\n"); | |
329 | AliTPCCosmicUtils::PrintTrackParam(100, &(tmptrk[0])); | |
330 | AliTPCCosmicUtils::PrintTrackParam(101, &(tmptrk[1])); | |
331 | tmptrk[0].Print(); | |
332 | tmptrk[1].Print(); | |
333 | } | |
334 | ||
335 | Double_t xyz0[3], xyz1[3]; | |
336 | tmptrk[0].GetXYZ(xyz0); | |
337 | tmptrk[1].GetXYZ(xyz1); | |
338 | const TVector3 gpos0(xyz0), gpos1(xyz1); | |
339 | ||
340 | //============================== rotate to common angle (M. Ivanov), since it is not possible to rotate from alpha1 to alpha0 via AliExternalTrackParam::Rotate | |
341 | const Double_t meanalpha = (gpos0-gpos1).Phi(); | |
342 | const Double_t alpha0 = tmptrk[0].GetAlpha(); | |
343 | ||
344 | //track0 closer to mean alpha | |
345 | if( TMath::Abs(AliTPCCosmicUtils::AngleInRange(meanalpha-alpha0)) <TMath::PiOver2() ){ | |
346 | if( !AliTPCCosmicUtils::RotateSafe(&(tmptrk[0]), meanalpha) || | |
347 | !AliTPCCosmicUtils::RotateSafe(&(tmptrk[1]), meanalpha+TMath::Pi()) ){ | |
348 | fErrFlagIsPair = 5; | |
349 | return kFALSE; | |
350 | } | |
351 | } | |
352 | //track1 closer to mean alpha | |
353 | else{ | |
354 | if( !AliTPCCosmicUtils::RotateSafe(&(tmptrk[1]), meanalpha) || | |
355 | !AliTPCCosmicUtils::RotateSafe(&(tmptrk[0]), meanalpha+TMath::Pi()) ){ | |
356 | fErrFlagIsPair = 6; | |
357 | return kFALSE; | |
358 | } | |
359 | } | |
360 | ||
361 | if(fDebugLevel & 2){ | |
362 | printf("\n************************ after rotation!!\n"); | |
363 | AliTPCCosmicUtils::PrintTrackParam(300, &(tmptrk[0])); | |
364 | AliTPCCosmicUtils::PrintTrackParam(301, &(tmptrk[1])); | |
365 | tmptrk[0].Print(); | |
366 | tmptrk[1].Print(); | |
367 | } | |
368 | ||
369 | //============================== propagate from TPC inner wall to x=0 with correct dedx | |
370 | const Double_t xTogo = 0.0; | |
371 | const Double_t maxStep = 1; | |
372 | const Bool_t rotateTo = kFALSE; | |
373 | const Double_t maxSnp = 0.8; | |
374 | Double_t eloss[2]={-1, 1}; | |
375 | //default [0]=upper [1]=lower | |
376 | //tmptrk[0].phi<0 ==> [0]=lower | |
377 | if(AliTPCCosmicUtils::AngleInRange(tmptrk[0].Phi())<0){ | |
378 | eloss[0]= 1; | |
379 | eloss[1]=-1; | |
380 | } | |
381 | ||
382 | for(Int_t ii=0; ii<2; ii++){ | |
3aa6a136 | 383 | if(!AliTrackerBase::PropagateTrackToBxByBz(&(tmptrk[ii]), xTogo, AliTPCCosmicUtils::Mass(), maxStep, rotateTo, maxSnp, (Int_t)(eloss[ii]))){ |
15d37333 | 384 | fErrFlagIsPair = 7; |
385 | return kFALSE; | |
386 | } | |
387 | } | |
388 | ||
389 | if(fDebugLevel & 2){ | |
390 | printf("\n************************ after dedx corr:\n"); | |
391 | AliTPCCosmicUtils::PrintTrackParam(200, &(tmptrk[0])); | |
392 | AliTPCCosmicUtils::PrintTrackParam(201, &(tmptrk[1])); | |
393 | tmptrk[0].Print(); | |
394 | tmptrk[1].Print(); | |
395 | } | |
396 | ||
397 | //____________________________________________________________________________________ | |
398 | //____________________________________________________________________________________ | |
399 | ||
400 | //ESD tracks after reconstruction all have x=0 and | |
401 | //TMath::Abs(alpha0 - alpha1)~ pi ==> back-to-back with angular resolution | |
402 | //[0]: local Y-coordinate of a track (cm); 9.945702e+01 -9.961257e+01 ==> opposite | |
403 | //[1]: local Z-coordinate of a track (cm); 2.677805e+01 2.711143e+01 ==> same | |
404 | //[2]: local sine of the track momentum azimuthal angle; should be the same!! bug-fixed | |
405 | //[3]: tangent of the track momentum dip angle; 1.563563e-01 -1.542005e-01 ==> opposite | |
406 | //[4]: 1/pt (1/(GeV/c)); -1.774935e-01 1.705480e-01 ==> opposite | |
407 | ||
408 | fDelta[0] = tmptrk[0].GetParameter()[0] + tmptrk[1].GetParameter()[0]; | |
409 | fDelta[1] = tmptrk[0].GetParameter()[1] - tmptrk[1].GetParameter()[1]; | |
410 | fDelta[2] = tmptrk[0].GetParameter()[2] - tmptrk[1].GetParameter()[2];//bug-fixed!! should use "-" | |
411 | fDelta[3] = tmptrk[0].GetParameter()[3] + tmptrk[1].GetParameter()[3]; | |
412 | fDelta[4] = tmptrk[0].GetParameter()[4] + tmptrk[1].GetParameter()[4]; | |
413 | ||
414 | fPull[0] = fDelta[0]/TMath::Sqrt(tmptrk[0].GetCovariance()[0] +tmptrk[1].GetCovariance()[0]); | |
415 | fPull[1] = fDelta[1]/TMath::Sqrt(tmptrk[0].GetCovariance()[2] +tmptrk[1].GetCovariance()[2]); | |
416 | fPull[2] = fDelta[2]/TMath::Sqrt(tmptrk[0].GetCovariance()[5] +tmptrk[1].GetCovariance()[5]); | |
417 | fPull[3] = fDelta[3]/TMath::Sqrt(tmptrk[0].GetCovariance()[9] +tmptrk[1].GetCovariance()[9]); | |
418 | fPull[4] = fDelta[4]/TMath::Sqrt(tmptrk[0].GetCovariance()[14]+tmptrk[1].GetCovariance()[14]); | |
419 | ||
420 | if(fDebugLevel & 2){ | |
421 | for(Int_t ii=0; ii<5; ii++){ | |
422 | printf("test %d %e %e -- %e\n", ii, tmptrk[0].GetParameter()[ii], tmptrk[1].GetParameter()[ii], fPull[ii]); | |
423 | } | |
424 | } | |
425 | ||
426 | for(Int_t ii=0; ii<5; ii++){ | |
427 | if( TMath::Abs(fPull[ii]) > fCutPull[ii] ){ | |
428 | fErrFlagIsPair = 10+ii; | |
429 | return kFALSE; | |
430 | } | |
431 | if( TMath::Abs(fDelta[ii]) > fCutDelta[ii] ){ | |
432 | fErrFlagIsPair = 20+ii; | |
433 | return kFALSE; | |
434 | } | |
435 | } | |
436 | ||
437 | fTrack0 = tmptrk[0]; | |
438 | fTrack1 = tmptrk[1]; | |
439 | ||
440 | return kTRUE; | |
441 | } | |
442 | ||
443 | Bool_t AliCosmicTracker::ESDtrackCut(AliESDtrack * trk, Double_t &findabler) | |
444 | { | |
445 | // | |
446 | //cut on track quality (kink, TPCrefit, findable ratio) and require TPC seed | |
447 | // | |
448 | ||
449 | if(fUserCut){ | |
3aa6a136 | 450 | if(!fUserCut(trk)){ |
451 | fErrFlagESDtrackCut = 1; | |
15d37333 | 452 | return kFALSE; |
3aa6a136 | 453 | } |
15d37333 | 454 | } |
455 | ||
456 | //reject kink | |
3aa6a136 | 457 | if(trk->GetKinkIndex(0)>0){ |
458 | fErrFlagESDtrackCut = 2; | |
15d37333 | 459 | return kFALSE; |
3aa6a136 | 460 | } |
15d37333 | 461 | |
462 | //require refit | |
3aa6a136 | 463 | if(!trk->IsOn(AliESDtrack::kTPCrefit)){ |
464 | fErrFlagESDtrackCut = 3; | |
15d37333 | 465 | return kFALSE; |
3aa6a136 | 466 | } |
15d37333 | 467 | |
468 | // due to drift velocity calibration, a track crossing Z=0 may be reconstructed as 2 ESD tracks, so two pairs are formed, each with one part of this track. Solution: cut on findable ratio (require > 0.5) to remove split tracks due to drift velocity calibration systematics on different sides | |
469 | //there is some remaining with isreuse = true, user should cut on findable ratio according to the fraction of isreuse | |
470 | findabler = -999; | |
3aa6a136 | 471 | if(!trk->GetTPCNclsF()){ |
472 | fErrFlagESDtrackCut = 4; | |
15d37333 | 473 | return kFALSE; |
3aa6a136 | 474 | } |
15d37333 | 475 | |
476 | findabler = (Double_t)trk->GetTPCNcls()/(Double_t) trk->GetTPCNclsF(); | |
477 | ||
3aa6a136 | 478 | if(findabler < CutFindable() ){ |
479 | fErrFlagESDtrackCut = 5; | |
480 | return kFALSE; | |
481 | } | |
482 | ||
483 | //cut on # TPC ncls on each ESDtrack | |
484 | if(trk->GetTPCncls()<AliTPCCosmicUtils::NclsMin()){ | |
485 | fErrFlagESDtrackCut = 6; | |
15d37333 | 486 | return kFALSE; |
487 | } | |
488 | ||
489 | //require ESDfriends | |
3aa6a136 | 490 | if(!AliTPCCosmicUtils::GetTPCseed(trk)){ |
491 | fErrFlagESDtrackCut = 7; | |
15d37333 | 492 | return kFALSE; |
3aa6a136 | 493 | } |
15d37333 | 494 | |
495 | return kTRUE; | |
496 | } | |
497 | ||
3aa6a136 | 498 | Int_t AliCosmicTracker::GetErrFlag() const |
499 | { | |
500 | // | |
501 | //return the error status in process | |
502 | // | |
503 | return fErrFlagESDtrackCut + fErrFlagIsPair*100 + fErrFlagCosmicTrackfit*10000; | |
504 | } | |
505 | ||
506 | void AliCosmicTracker::WriteStreamer(Int_t ntrk, AliESDCosmicTrack *costrk) | |
15d37333 | 507 | { |
508 | // | |
509 | //output to streamer | |
510 | // | |
511 | ||
512 | (*fStreamer)<<"CosmicTracker_Streamer"<< | |
513 | "ntrk="<<ntrk<< | |
3aa6a136 | 514 | |
515 | "costrk="<<costrk<< | |
516 | ||
517 | "rawvtx="<<&fRawVtx<< | |
518 | "rawdca="<<fRawDCA<< | |
519 | ||
15d37333 | 520 | "dphi="<<fdPhi<< |
521 | "dtheta="<<fdTheta<< | |
522 | "pull0="<<fPull[0]<< | |
523 | "pull1="<<fPull[1]<< | |
524 | "pull2="<<fPull[2]<< | |
525 | "pull3="<<fPull[3]<< | |
526 | "pull4="<<fPull[4]<< | |
527 | "delta0="<<fDelta[0]<< | |
528 | "delta1="<<fDelta[1]<< | |
529 | "delta2="<<fDelta[2]<< | |
530 | "delta3="<<fDelta[3]<< | |
531 | "delta4="<<fDelta[4]<< | |
532 | "\n"; | |
533 | } | |
3aa6a136 | 534 | |
535 | TClonesArray *AliCosmicTracker::FindCosmic(AliESDEvent *event, const Bool_t kadd) | |
536 | { | |
537 | // | |
538 | //do cosmic combined trackfit | |
539 | // | |
540 | ||
541 | AliCosmicTracker cosmicTracker; | |
542 | cosmicTracker.SetESDEvent(event); | |
543 | const Int_t npair = cosmicTracker.Process(); | |
544 | const TClonesArray *arr = cosmicTracker.GetTrackStack(); | |
545 | ||
546 | TClonesArray *stackCosmic = 0x0; | |
547 | if(kadd){ | |
548 | for(Int_t ip=0; ip<npair; ip++){ | |
549 | const AliESDCosmicTrack * esdcos = (AliESDCosmicTrack*) arr->At(ip); | |
550 | event->AddCosmicTrack(esdcos); | |
551 | } | |
552 | printf("AliCosmicTracker::FindCosmic: event %d: Number of cosmic pairs by AliCosmicTracker %d out of %d tracks, err %d\n", event->GetEventNumberInFile(), npair, event->GetNumberOfTracks(), cosmicTracker.GetErrFlag()); | |
553 | } | |
554 | else{ | |
555 | stackCosmic = new TClonesArray(*arr); | |
556 | } | |
557 | ||
558 | return stackCosmic; | |
559 | } | |
560 |