]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliCosmicTracker.cxx
Add macro to create OCDB entry for ion tail
[u/mrichter/AliRoot.git] / TPC / AliCosmicTracker.cxx
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)
120   , fCosmicTrackfit(0x0)
121   , fTrackStack(0x0)
122   , fTrack0()
123   , fTrack1()
124   , fRawVtx(-999,-999,-999)
125   , fRawDCA(-999)
126   , fdPhi(-999)
127   , fCutdPhi(-999)
128   , fdTheta(-999)
129   , fCutdTheta(-999)
130   , fErrFlagESDtrackCut(-999)
131   , fErrFlagIsPair(-999)
132   , fErrFlagCosmicTrackfit(-999)
133 {
134   //
135   //constructor
136   //
137
138   if(fDebugLevel & 1)
139     fStreamer = new TTreeSRedirector(Form("CosmicTracker_%s.root", tag.Data()));
140
141   fCosmicTrackfit = new AliTPCCosmicTrackfit(0, "AliCosmicTracker");
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;
171   delete fCosmicTrackfit;
172   delete fTrackStack;
173 }
174
175 void AliCosmicTracker::SetESDEvent(AliESDEvent *esd)
176 {
177   //
178   //set esd event
179   //
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
200   fErrFlagESDtrackCut = 0;
201   fErrFlagIsPair = 0;
202   fErrFlagCosmicTrackfit = 0;
203
204   for(Int_t itrk=0; itrk<ntrk; itrk++){
205     if(!ESDtrackCut(fESDEvent->GetTrack(itrk), findabler0)){
206       continue;
207     }
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) ){
216         const Bool_t kfit = fCosmicTrackfit->CombineESDtracks(trk0, trk1);
217         fErrFlagCosmicTrackfit = fCosmicTrackfit->GetStatus();
218
219         if(kfit){
220           fRawVtx = fCosmicTrackfit->ImpactParameter3D();
221           fRawDCA = fCosmicTrackfit->ImpactParameter2D().Mag();
222
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();
228
229           const Double_t findableratio  = TMath::Min(findabler0, findabler1);
230
231           trkcounter[itrk]++;
232           trkcounter[jtrk]++;
233           const Bool_t isreuse          = (trkcounter[itrk]>1 || trkcounter[jtrk]>1);
234
235           const TVector3 icU = fCosmicTrackfit->GetInnerClusterUp();
236           const TVector3 icD = fCosmicTrackfit->GetInnerClusterLow();
237
238           Int_t idup = itrk;
239           Int_t idlow = jtrk;
240           if(fCosmicTrackfit->IsSwap()){
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) && 
252              ( (isreuse && ntrk<=4) || kprint )
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) &&
259              impactD > 160 && findableratio < 0.56
260              ){
261             AliESDtrack * trks[]={fESDEvent->GetTrack(idup), fESDEvent->GetTrack(idlow)};
262             AliTPCCosmicUtils::DrawTracks(trks, Form("largevtd_%.f_%.f_%03d_%03d_%03d_%s", impactD, findableratio, ntrk, itrk, jtrk, tag.Data()));
263           }
264
265           AliESDCosmicTrack costrk(idup, idlow, fCosmicTrackfit->GetTrackParamUp(), fCosmicTrackfit->GetTrackParamLow(), &fTrack0, &fTrack1, ncls, leverarm, chi2percluster, impactD, impactZ, isreuse, findableratio, icU, icD);
266           new((*fTrackStack)[npair]) AliESDCosmicTrack(costrk);
267           npair++;
268
269           if(fDebugLevel & 1)
270             WriteStreamer(ntrk, &costrk);
271
272         }
273         else{
274           if(fDebugLevel & 16){
275             if(ntrk==2){
276               AliESDtrack * trks[]={trk0, trk1};
277               AliTPCCosmicUtils::DrawTracks(trks, Form("failCosmicFit_%02d_%03d_%03d_%03d_%s", fCosmicTrackfit->GetStatus(), ntrk, itrk, jtrk, tag.Data()));
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
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++){
383     if(!AliTrackerBase::PropagateTrackToBxByBz(&(tmptrk[ii]), xTogo, AliTPCCosmicUtils::Mass(), maxStep, rotateTo, maxSnp, (Int_t)(eloss[ii]))){
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){
450     if(!fUserCut(trk)){
451       fErrFlagESDtrackCut = 1;
452       return kFALSE;
453     }
454   }
455
456   //reject kink
457   if(trk->GetKinkIndex(0)>0){
458     fErrFlagESDtrackCut = 2;
459     return kFALSE;
460   }
461
462   //require refit
463   if(!trk->IsOn(AliESDtrack::kTPCrefit)){
464     fErrFlagESDtrackCut = 3;
465     return kFALSE;
466   }
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;
471   if(!trk->GetTPCNclsF()){
472     fErrFlagESDtrackCut = 4;
473     return kFALSE;
474   }
475
476   findabler = (Double_t)trk->GetTPCNcls()/(Double_t) trk->GetTPCNclsF();
477
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;
486     return kFALSE;
487   }
488
489   //require ESDfriends
490   if(!AliTPCCosmicUtils::GetTPCseed(trk)){
491     fErrFlagESDtrackCut = 7;
492     return kFALSE;
493   }
494
495   return kTRUE;
496 }
497
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)
507 {
508   //
509   //output to streamer
510   //
511
512   (*fStreamer)<<"CosmicTracker_Streamer"<<
513     "ntrk="<<ntrk<<
514
515     "costrk="<<costrk<<
516
517     "rawvtx="<<&fRawVtx<<
518     "rawdca="<<fRawDCA<<
519
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 }
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