Primary vertex reconstruction and standalone ITS tracking in the reconstruction chain
[u/mrichter/AliRoot.git] / STEER / AliReconstruction.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 // class for running the reconstruction                                      //
21 //                                                                           //
22 // Clusters and tracks are created for all detectors and all events by       //
23 // typing:                                                                   //
24 //                                                                           //
25 //   AliReconstruction rec;                                                  //
26 //   rec.Run();                                                              //
27 //                                                                           //
28 // The Run method returns kTRUE in case of successful execution.             //
29 // The name of the galice file can be changed from the default               //
30 // "galice.root" by passing it as argument to the AliReconstruction          //
31 // constructor or by                                                         //
32 //                                                                           //
33 //   rec.SetGAliceFile("...");                                               //
34 //                                                                           //
35 // The reconstruction can be switched on or off for individual detectors by  //
36 //                                                                           //
37 //   rec.SetRunReconstruction("...");                                        //
38 //                                                                           //
39 // The argument is a (case sensitive) string with the names of the           //
40 // detectors separated by a space. The special string "ALL" selects all      //
41 // available detectors. This is the default.                                 //
42 //                                                                           //
43 // The tracking in ITS, TPC and TRD and the creation of ESD tracks can be    //
44 // switched off by                                                           //
45 //                                                                           //
46 //   rec.SetRunTracking(kFALSE);                                             //
47 //                                                                           //
48 // The filling of additional ESD information can be steered by               //
49 //                                                                           //
50 //   rec.SetFillESD("...");                                                  //
51 //                                                                           //
52 // Again, the string specifies the list of detectors. The default is "ALL".  //
53 //                                                                           //
54 // The reconstruction requires digits as input. For the creation of digits   //
55 // have a look at the class AliSimulation.                                   //
56 //                                                                           //
57 // For debug purposes the method SetCheckPointLevel can be used. If the      //
58 // argument is greater than 0, files with ESD events will be written after   //
59 // selected steps of the reconstruction for each event:                      //
60 //   level 1: after tracking and after filling of ESD (final)                //
61 //   level 2: in addition after each tracking step                           //
62 //   level 3: in addition after the filling of ESD for each detector         //
63 // If a final check point file exists for an event, this event will be       //
64 // skipped in the reconstruction. The tracking and the filling of ESD for    //
65 // a detector will be skipped as well, if the corresponding check point      //
66 // file exists. The ESD event will then be loaded from the file instead.     //
67 //                                                                           //
68 ///////////////////////////////////////////////////////////////////////////////
69
70
71 #include "AliReconstruction.h"
72 #include "AliRunLoader.h"
73 #include "AliRun.h"
74 #include "AliModule.h"
75 #include "AliDetector.h"
76 #include "AliTracker.h"
77 #include "AliESD.h"
78 #include "AliESDVertex.h"
79 #include "AliVertexer.h"
80 #include "AliHeader.h"
81 #include "AliGenEventHeader.h"
82 #include "AliESDpid.h"
83 #include "AliMagF.h"
84 #include <TArrayF.h>
85 #include <TSystem.h>
86 #include <TROOT.h>
87
88
89 ClassImp(AliReconstruction)
90
91
92 //_____________________________________________________________________________
93 AliReconstruction::AliReconstruction(const char* gAliceFilename,
94                                      const char* name, const char* title) :
95   TNamed(name, title),
96
97   fRunReconstruction("ALL"),
98   fRunVertexFinder(kTRUE),
99   fRunTracking(kTRUE),
100   fFillESD("ALL"),
101   fGAliceFileName(gAliceFilename),
102   fStopOnError(kFALSE),
103   fCheckPointLevel(0),
104
105   fRunLoader(NULL),
106   fITSLoader(NULL),
107   fITSVertexer(NULL),
108   fITSTracker(NULL),
109   fTPCLoader(NULL),
110   fTPCTracker(NULL),
111   fTRDLoader(NULL),
112   fTRDTracker(NULL),
113   fTOFLoader(NULL),
114   fTOFTracker(NULL)
115 {
116 // create reconstruction object with default parameters
117
118 }
119
120 //_____________________________________________________________________________
121 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
122   TNamed(rec),
123
124   fRunReconstruction(rec.fRunReconstruction),
125   fRunVertexFinder(rec.fRunVertexFinder),
126   fRunTracking(rec.fRunTracking),
127   fFillESD(rec.fFillESD),
128   fGAliceFileName(rec.fGAliceFileName),
129   fStopOnError(rec.fStopOnError),
130   fCheckPointLevel(0),
131
132   fRunLoader(NULL),
133   fITSLoader(NULL),
134   fITSVertexer(NULL),
135   fITSTracker(NULL),
136   fTPCLoader(NULL),
137   fTPCTracker(NULL),
138   fTRDLoader(NULL),
139   fTRDTracker(NULL),
140   fTOFLoader(NULL),
141   fTOFTracker(NULL)
142 {
143 // copy constructor
144
145 }
146
147 //_____________________________________________________________________________
148 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
149 {
150 // assignment operator
151
152   this->~AliReconstruction();
153   new(this) AliReconstruction(rec);
154   return *this;
155 }
156
157 //_____________________________________________________________________________
158 AliReconstruction::~AliReconstruction()
159 {
160 // clean up
161
162   CleanUp();
163 }
164
165
166 //_____________________________________________________________________________
167 void AliReconstruction::SetGAliceFile(const char* fileName)
168 {
169 // set the name of the galice file
170
171   fGAliceFileName = fileName;
172 }
173
174
175 //_____________________________________________________________________________
176 Bool_t AliReconstruction::Run()
177 {
178 // run the reconstruction
179
180   // open the run loader
181   fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
182   if (!fRunLoader) {
183     Error("Run", "no run loader found in file %s", 
184           fGAliceFileName.Data());
185     CleanUp();
186     return kFALSE;
187   }
188   fRunLoader->LoadgAlice();
189   AliRun* aliRun = fRunLoader->GetAliRun();
190   if (!aliRun) {
191     Error("Run", "no gAlice object found in file %s", 
192           fGAliceFileName.Data());
193     CleanUp();
194     return kFALSE;
195   }
196   gAlice = aliRun;
197
198   // local reconstruction
199   if (!fRunReconstruction.IsNull()) {
200     if (!RunReconstruction(fRunReconstruction)) {
201       if (fStopOnError) {CleanUp(); return kFALSE;}
202     }
203   }
204   if (!fRunVertexFinder && !fRunTracking && fFillESD.IsNull()) return kTRUE;
205
206   // get vertexer
207   if (fRunVertexFinder && !CreateVertexer()) {
208     if (fStopOnError) {
209       CleanUp(); 
210       return kFALSE;
211     }
212   }
213
214   // get loaders and trackers
215   if (fRunTracking && !CreateTrackers()) {
216     if (fStopOnError) {
217       CleanUp(); 
218       return kFALSE;
219     }      
220   }
221
222   // create the ESD output file
223   TFile* file = TFile::Open("AliESDs.root", "RECREATE");
224   if (!file->IsOpen()) {
225     Error("Run", "opening AliESDs.root failed");
226     if (fStopOnError) {CleanUp(file); return kFALSE;}    
227   }
228
229   // loop over events
230   for (Int_t iEvent = 0; iEvent < fRunLoader->GetNumberOfEvents(); iEvent++) {
231     Info("Run", "processing event %d", iEvent);
232     fRunLoader->GetEvent(iEvent);
233
234     char fileName[256];
235     sprintf(fileName, "ESD_%d.%d_final.root", 
236             aliRun->GetRunNumber(), aliRun->GetEvNumber());
237     if (!gSystem->AccessPathName(fileName)) continue;
238
239     AliESD* esd = new AliESD;
240     esd->SetRunNumber(aliRun->GetRunNumber());
241     esd->SetEventNumber(aliRun->GetEvNumber());
242     esd->SetMagneticField(aliRun->Field()->SolenoidField());
243
244     // vertex finder
245     if (fRunVertexFinder) {
246       if (!ReadESD(esd, "vertex")) {
247         if (!RunVertexFinder(esd)) {
248           if (fStopOnError) {CleanUp(file); return kFALSE;}
249         }
250         if (fCheckPointLevel > 0) WriteESD(esd, "vertex");
251       }
252     }
253
254     // barrel tracking
255     if (fRunTracking) {
256       if (!ReadESD(esd, "tracking")) {
257         if (!RunTracking(esd)) {
258           if (fStopOnError) {CleanUp(file); return kFALSE;}
259         }
260         if (fCheckPointLevel > 0) WriteESD(esd, "tracking");
261       }
262     }
263
264     // fill ESD
265     if (!fFillESD.IsNull()) {
266       if (!FillESD(esd, fFillESD)) {
267         if (fStopOnError) {CleanUp(file); return kFALSE;}
268       }
269     }
270
271     // combined PID
272     AliESDpid::MakePID(esd);
273     if (fCheckPointLevel > 1) WriteESD(esd, "PID");
274
275     // write ESD
276     char name[100]; 
277     sprintf(name, "ESD%d", iEvent);
278     file->cd();
279     if (!esd->Write(name)) {
280       Error("Run", "writing ESD failed");
281       if (fStopOnError) {CleanUp(file); return kFALSE;}
282     }
283     file->Flush();
284
285     if (fCheckPointLevel > 0) WriteESD(esd, "final");
286     delete esd;
287   }
288
289   CleanUp(file);
290
291   return kTRUE;
292 }
293
294
295 //_____________________________________________________________________________
296 Bool_t AliReconstruction::RunReconstruction(const TString& detectors)
297 {
298 // run the reconstruction
299
300   TStopwatch stopwatch;
301   stopwatch.Start();
302
303   TString detStr = detectors;
304   TObjArray* detArray = fRunLoader->GetAliRun()->Detectors();
305   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
306     AliModule* det = (AliModule*) detArray->At(iDet);
307     if (!det || !det->IsActive()) continue;
308     if (IsSelected(det->GetName(), detStr)) {
309       Info("RunReconstruction", "running reconstruction for %s", 
310            det->GetName());
311       TStopwatch stopwatchDet;
312       stopwatchDet.Start();
313       det->Reconstruct();
314       Info("RunReconstruction", "execution time for %s:", det->GetName());
315       stopwatchDet.Print();
316     }
317   }
318
319   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
320     Error("RunReconstruction", "the following detectors were not found: %s", 
321           detStr.Data());
322     if (fStopOnError) return kFALSE;
323   }
324
325   Info("RunReconstruction", "execution time:");
326   stopwatch.Print();
327
328   return kTRUE;
329 }
330
331 //_____________________________________________________________________________
332 Bool_t AliReconstruction::RunVertexFinder(AliESD*& esd)
333 {
334 // run the barrel tracking
335
336   TStopwatch stopwatch;
337   stopwatch.Start();
338
339   AliESDVertex* vertex = NULL;
340   Double_t vtxPos[3] = {0, 0, 0};
341   Double_t vtxErr[3] = {0.07, 0.07, 0.1};
342   TArrayF mcVertex(3); 
343   fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
344   for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
345
346   if (fITSVertexer) {
347     Info("RunVertexFinder", "running the ITS vertex finder");
348     fITSVertexer->SetDebug(1);
349     vertex = fITSVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
350     if(!vertex){
351       Warning("RunVertexFinder","Vertex not found \n");
352       vtxErr[2]=10000.;
353       vertex = new AliESDVertex(vtxPos, vtxErr);
354     }
355     else {
356       vertex->SetTruePos(vtxPos);  // store also the vertex from MC
357     }
358
359   } else {
360     Info("RunVertexFinder", "getting the primary vertex from MC");
361     vertex = new AliESDVertex(vtxPos, vtxErr);
362   }
363
364   if (vertex) {
365     vertex->GetXYZ(vtxPos);
366     vertex->GetSigmaXYZ(vtxErr);
367   } else {
368     Warning("RunVertexFinder", "no vertex reconstructed");
369     vertex = new AliESDVertex(vtxPos, vtxErr);
370   }
371   esd->SetVertex(vertex);
372   if (fITSTracker) fITSTracker->SetVertex(vtxPos, vtxErr);
373   if (fTPCTracker) fTPCTracker->SetVertex(vtxPos, vtxErr);
374   if (fTRDTracker) fTRDTracker->SetVertex(vtxPos, vtxErr);
375   delete vertex;
376
377   Info("RunVertexFinder", "execution time:");
378   stopwatch.Print();
379
380   return kTRUE;
381 }
382
383 //_____________________________________________________________________________
384 Bool_t AliReconstruction::RunTracking(AliESD*& esd)
385 {
386 // run the barrel tracking
387
388   TStopwatch stopwatch;
389   stopwatch.Start();
390
391   if (!fTPCTracker) {
392     Error("RunTracking", "no TPC tracker");
393     return kFALSE;
394   }
395
396   // TPC tracking
397   Info("RunTracking", "TPC tracking");
398   fTPCLoader->LoadRecPoints("read");
399   TTree* tpcTree = fTPCLoader->TreeR();
400   if (!tpcTree) {
401     Error("RunTracking", "Can't get the TPC cluster tree");
402     return kFALSE;
403   }
404   fTPCTracker->LoadClusters(tpcTree);
405   if (fTPCTracker->Clusters2Tracks(esd) != 0) {
406     Error("RunTracking", "TPC Clusters2Tracks failed");
407     return kFALSE;
408   }
409   if (fCheckPointLevel > 1) WriteESD(esd, "TPC.tracking");
410
411   if (!fITSTracker) {
412     Warning("RunTracking", "no ITS tracker");
413   } else {
414
415     fRunLoader->GetAliRun()->GetDetector("TPC")->FillESD(esd); // preliminary
416     AliESDpid::MakePID(esd);                  // PID for the ITS tracker
417
418     // ITS tracking
419     Info("RunTracking", "ITS tracking");
420     fITSLoader->LoadRecPoints("read");
421     TTree* itsTree = fITSLoader->TreeR();
422     if (!itsTree) {
423       Error("RunTracking", "Can't get the ITS cluster tree");
424       return kFALSE;
425     }
426     fITSTracker->LoadClusters(itsTree);
427     if (fITSTracker->Clusters2Tracks(esd) != 0) {
428       Error("RunTracking", "ITS Clusters2Tracks failed");
429       return kFALSE;
430     }
431     if (fCheckPointLevel > 1) WriteESD(esd, "ITS.tracking");
432
433     if (!fTRDTracker) {
434       Warning("RunTracking", "no TRD tracker");
435     } else {
436       // ITS back propagation
437       Info("RunTracking", "ITS back propagation");
438       if (fITSTracker->PropagateBack(esd) != 0) {
439         Error("RunTracking", "ITS backward propagation failed");
440         return kFALSE;
441       }
442       if (fCheckPointLevel > 1) WriteESD(esd, "ITS.back");
443
444       // TPC back propagation
445       Info("RunTracking", "TPC back propagation");
446       if (fTPCTracker->PropagateBack(esd) != 0) {
447         Error("RunTracking", "TPC backward propagation failed");
448         return kFALSE;
449       }
450       if (fCheckPointLevel > 1) WriteESD(esd, "TPC.back");
451
452       // TRD back propagation
453       Info("RunTracking", "TRD back propagation");
454       fTRDLoader->LoadRecPoints("read");
455       TTree* trdTree = fTRDLoader->TreeR();
456       if (!trdTree) {
457         Error("RunTracking", "Can't get the TRD cluster tree");
458         return kFALSE;
459       }
460       fTRDTracker->LoadClusters(trdTree);
461       if (fTRDTracker->PropagateBack(esd) != 0) {
462         Error("RunTracking", "TRD backward propagation failed");
463         return kFALSE;
464       }
465       if (fCheckPointLevel > 1) WriteESD(esd, "TRD.back");
466
467       if (!fTOFTracker) {
468         Warning("RunTracking", "no TOF tracker");
469       } else {
470         // TOF back propagation
471         Info("RunTracking", "TOF back propagation");
472         fTOFLoader->LoadDigits("read");
473         TTree* tofTree = fTOFLoader->TreeD();
474         if (!tofTree) {
475           Error("RunTracking", "Can't get the TOF digits tree");
476           return kFALSE;
477         }
478         fTOFTracker->LoadClusters(tofTree);
479         if (fTOFTracker->PropagateBack(esd) != 0) {
480           Error("RunTracking", "TOF backward propagation failed");
481           return kFALSE;
482         }
483         if (fCheckPointLevel > 1) WriteESD(esd, "TOF.back");
484         fTOFTracker->UnloadClusters();
485         fTOFLoader->UnloadDigits();
486       }
487
488       // TRD inward refit
489       Info("RunTracking", "TRD inward refit");
490       if (fTRDTracker->RefitInward(esd) != 0) {
491         Error("RunTracking", "TRD inward refit failed");
492         return kFALSE;
493       }
494       if (fCheckPointLevel > 1) WriteESD(esd, "TRD.refit");
495       fTRDTracker->UnloadClusters();
496       fTRDLoader->UnloadRecPoints();
497     
498       // TPC inward refit
499       Info("RunTracking", "TPC inward refit");
500       if (fTPCTracker->RefitInward(esd) != 0) {
501         Error("RunTracking", "TPC inward refit failed");
502         return kFALSE;
503       }
504       if (fCheckPointLevel > 1) WriteESD(esd, "TPC.refit");
505     
506       // ITS inward refit
507       Info("RunTracking", "ITS inward refit");
508       if (fITSTracker->RefitInward(esd) != 0) {
509         Error("RunTracking", "ITS inward refit failed");
510         return kFALSE;
511       }
512       if (fCheckPointLevel > 1) WriteESD(esd, "ITS.refit");
513
514     }  // if TRD tracker
515     fITSTracker->UnloadClusters();
516     fITSLoader->UnloadRecPoints();
517
518   }  // if ITS tracker
519   fTPCTracker->UnloadClusters();
520   fTPCLoader->UnloadRecPoints();
521
522   Info("RunTracking", "execution time:");
523   stopwatch.Print();
524
525   return kTRUE;
526 }
527
528 //_____________________________________________________________________________
529 Bool_t AliReconstruction::FillESD(AliESD*& esd, const TString& detectors)
530 {
531 // fill the event summary data
532
533   TStopwatch stopwatch;
534   stopwatch.Start();
535
536   TString detStr = detectors;
537   TObjArray* detArray = fRunLoader->GetAliRun()->Detectors();
538   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
539     AliModule* det = (AliModule*) detArray->At(iDet);
540     if (!det || !det->IsActive()) continue;
541     if (IsSelected(det->GetName(), detStr)) {
542       if (!ReadESD(esd, det->GetName())) {
543         Info("FillESD", "filling ESD for %s", 
544              det->GetName());
545         det->FillESD(esd);
546         if (fCheckPointLevel > 2) WriteESD(esd, det->GetName());
547       }
548     }
549   }
550
551   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
552     Error("FillESD", "the following detectors were not found: %s", 
553           detStr.Data());
554     if (fStopOnError) return kFALSE;
555   }
556
557   Info("FillESD", "execution time:");
558   stopwatch.Print();
559
560   return kTRUE;
561 }
562
563
564 //_____________________________________________________________________________
565 Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
566 {
567 // check whether detName is contained in detectors
568 // if yes, it is removed from detectors
569
570   // check if all detectors are selected
571   if ((detectors.CompareTo("ALL") == 0) ||
572       detectors.BeginsWith("ALL ") ||
573       detectors.EndsWith(" ALL") ||
574       detectors.Contains(" ALL ")) {
575     detectors = "ALL";
576     return kTRUE;
577   }
578
579   // search for the given detector
580   Bool_t result = kFALSE;
581   if ((detectors.CompareTo(detName) == 0) ||
582       detectors.BeginsWith(detName+" ") ||
583       detectors.EndsWith(" "+detName) ||
584       detectors.Contains(" "+detName+" ")) {
585     detectors.ReplaceAll(detName, "");
586     result = kTRUE;
587   }
588
589   // clean up the detectors string
590   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
591   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
592   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
593
594   return result;
595 }
596
597 //_____________________________________________________________________________
598 Bool_t AliReconstruction::CreateVertexer()
599 {
600 // create the vertexer
601
602   fITSVertexer = NULL;
603   AliRun* aliRun = fRunLoader->GetAliRun();
604   if (aliRun->GetDetector("ITS")) {
605     fITSVertexer = aliRun->GetDetector("ITS")->CreateVertexer();
606   }
607   if (!fITSVertexer) {
608     Warning("CreateVertexer", "couldn't create a vertexer for ITS");
609     if (fStopOnError) return kFALSE;
610   }
611
612   return kTRUE;
613 }
614
615 //_____________________________________________________________________________
616 Bool_t AliReconstruction::CreateTrackers()
617 {
618 // get the loaders and create the trackers
619
620   AliRun* aliRun = fRunLoader->GetAliRun();
621
622   fITSTracker = NULL;
623   fITSLoader = fRunLoader->GetLoader("ITSLoader");
624   if (!fITSLoader) {
625     Warning("CreateTrackers", "no ITS loader found");
626     if (fStopOnError) return kFALSE;
627   } else {
628     if (aliRun->GetDetector("ITS")) {
629       fITSTracker = aliRun->GetDetector("ITS")->CreateTracker();
630     }
631     if (!fITSTracker) {
632       Warning("CreateTrackers", "couldn't create a tracker for ITS");
633       if (fStopOnError) return kFALSE;
634     }
635   }
636     
637   fTPCTracker = NULL;
638   fTPCLoader = fRunLoader->GetLoader("TPCLoader");
639   if (!fTPCLoader) {
640     Error("CreateTrackers", "no TPC loader found");
641     if (fStopOnError) return kFALSE;
642   } else {
643     if (aliRun->GetDetector("TPC")) {
644       fTPCTracker = aliRun->GetDetector("TPC")->CreateTracker();
645     }
646     if (!fTPCTracker) {
647       Error("CreateTrackers", "couldn't create a tracker for TPC");
648       if (fStopOnError) return kFALSE;
649     }
650   }
651     
652   fTRDTracker = NULL;
653   fTRDLoader = fRunLoader->GetLoader("TRDLoader");
654   if (!fTRDLoader) {
655     Warning("CreateTrackers", "no TRD loader found");
656     if (fStopOnError) return kFALSE;
657   } else {
658     if (aliRun->GetDetector("TRD")) {
659       fTRDTracker = aliRun->GetDetector("TRD")->CreateTracker();
660     }
661     if (!fTRDTracker) {
662       Warning("CreateTrackers", "couldn't create a tracker for TRD");
663       if (fStopOnError) return kFALSE;
664     }
665   }
666     
667   fTOFTracker = NULL;
668   fTOFLoader = fRunLoader->GetLoader("TOFLoader");
669   if (!fTOFLoader) {
670     Warning("CreateTrackers", "no TOF loader found");
671     if (fStopOnError) return kFALSE;
672   } else {
673     if (aliRun->GetDetector("TOF")) {
674       fTOFTracker = aliRun->GetDetector("TOF")->CreateTracker();
675     }
676     if (!fTOFTracker) {
677       Warning("CreateTrackers", "couldn't create a tracker for TOF");
678       if (fStopOnError) return kFALSE;
679     }
680   }
681
682   return kTRUE;
683 }
684
685 //_____________________________________________________________________________
686 void AliReconstruction::CleanUp(TFile* file)
687 {
688 // delete trackers and the run loader and close and delete the file
689
690   delete fITSVertexer;
691   fITSVertexer = NULL;
692   delete fITSTracker;
693   fITSTracker = NULL;
694   delete fTPCTracker;
695   fTPCTracker = NULL;
696   delete fTRDTracker;
697   fTRDTracker = NULL;
698   delete fTOFTracker;
699   fTOFTracker = NULL;
700
701   delete fRunLoader;
702   fRunLoader = NULL;
703
704   if (file) {
705     file->Close();
706     delete file;
707   }
708 }
709
710
711 //_____________________________________________________________________________
712 Bool_t AliReconstruction::ReadESD(AliESD*& esd, const char* recStep) const
713 {
714 // read the ESD event from a file
715
716   if (!esd) return kFALSE;
717   char fileName[256];
718   sprintf(fileName, "ESD_%d.%d_%s.root", 
719           esd->GetRunNumber(), esd->GetEventNumber(), recStep);
720   if (gSystem->AccessPathName(fileName)) return kFALSE;
721
722   Info("ReadESD", "reading ESD from file %s", fileName);
723   TFile* file = TFile::Open(fileName);
724   if (!file || !file->IsOpen()) {
725     Error("ReadESD", "opening %s failed", fileName);
726     delete file;
727     return kFALSE;
728   }
729
730   gROOT->cd();
731   delete esd;
732   esd = (AliESD*) file->Get("ESD");
733   file->Close();
734   delete file;
735   return kTRUE;
736 }
737
738 //_____________________________________________________________________________
739 void AliReconstruction::WriteESD(AliESD* esd, const char* recStep) const
740 {
741 // write the ESD event to a file
742
743   if (!esd) return;
744   char fileName[256];
745   sprintf(fileName, "ESD_%d.%d_%s.root", 
746           esd->GetRunNumber(), esd->GetEventNumber(), recStep);
747
748   Info("WriteESD", "writing ESD to file %s", fileName);
749   TFile* file = TFile::Open(fileName, "recreate");
750   if (!file || !file->IsOpen()) {
751     Error("WriteESD", "opening %s failed", fileName);
752   } else {
753     esd->Write("ESD");
754     file->Close();
755   }
756   delete file;
757 }