]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliReconstruction.cxx
use dummy reconstructor only if detector exists
[u/mrichter/AliRoot.git] / STEER / AliReconstruction.cxx
index fff28de8b68d3dd8e02bb4ebcaded049b74b282b..0ef7b2d6626a528cbaf76d15ab1b3aee9a58c4c0 100644 (file)
 //                                                                           //
 //   rec.SetGAliceFile("...");                                               //
 //                                                                           //
-// The reconstruction can be switched on or off for individual detectors by  //
+// The local reconstruction can be switched on or off for individual         //
+// detectors by                                                              //
 //                                                                           //
-//   rec.SetRunReconstruction("...");                                        //
+//   rec.SetRunLocalReconstruction("...");                                   //
 //                                                                           //
 // The argument is a (case sensitive) string with the names of the           //
 // detectors separated by a space. The special string "ALL" selects all      //
 // The reconstruction requires digits as input. For the creation of digits   //
 // have a look at the class AliSimulation.                                   //
 //                                                                           //
+// For debug purposes the method SetCheckPointLevel can be used. If the      //
+// argument is greater than 0, files with ESD events will be written after   //
+// selected steps of the reconstruction for each event:                      //
+//   level 1: after tracking and after filling of ESD (final)                //
+//   level 2: in addition after each tracking step                           //
+//   level 3: in addition after the filling of ESD for each detector         //
+// If a final check point file exists for an event, this event will be       //
+// skipped in the reconstruction. The tracking and the filling of ESD for    //
+// a detector will be skipped as well, if the corresponding check point      //
+// file exists. The ESD event will then be loaded from the file instead.     //
+//                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
+#include <TArrayF.h>
+#include <TFile.h>
+#include <TSystem.h>
+#include <TROOT.h>
+#include <TPluginManager.h>
+#include <TStopwatch.h>
 
 #include "AliReconstruction.h"
 #include "AliRunLoader.h"
 #include "AliRun.h"
-#include "AliModule.h"
-#include "AliDetector.h"
 #include "AliTracker.h"
 #include "AliESD.h"
+#include "AliESDVertex.h"
+#include "AliVertexer.h"
 #include "AliHeader.h"
 #include "AliGenEventHeader.h"
 #include "AliESDpid.h"
 #include "AliMagF.h"
-#include <TArrayF.h>
-
 
 ClassImp(AliReconstruction)
 
 
+//_____________________________________________________________________________
+const char* AliReconstruction::fgkDetectorName[AliReconstruction::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "RICH", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "START", "VZERO", "CRT", "HLT"};
+
 //_____________________________________________________________________________
 AliReconstruction::AliReconstruction(const char* gAliceFilename,
                                     const char* name, const char* title) :
   TNamed(name, title),
 
-  fRunReconstruction("ALL"),
+  fRunLocalReconstruction("ALL"),
+  fRunVertexFinder(kTRUE),
   fRunTracking(kTRUE),
   fFillESD("ALL"),
   fGAliceFileName(gAliceFilename),
   fStopOnError(kFALSE),
+  fCheckPointLevel(0),
 
   fRunLoader(NULL),
   fITSLoader(NULL),
+  fITSVertexer(NULL),
   fITSTracker(NULL),
   fTPCLoader(NULL),
   fTPCTracker(NULL),
@@ -103,14 +125,17 @@ AliReconstruction::AliReconstruction(const char* gAliceFilename,
 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
   TNamed(rec),
 
-  fRunReconstruction(rec.fRunReconstruction),
+  fRunLocalReconstruction(rec.fRunLocalReconstruction),
+  fRunVertexFinder(rec.fRunVertexFinder),
   fRunTracking(rec.fRunTracking),
   fFillESD(rec.fFillESD),
   fGAliceFileName(rec.fGAliceFileName),
   fStopOnError(rec.fStopOnError),
+  fCheckPointLevel(0),
 
   fRunLoader(NULL),
   fITSLoader(NULL),
+  fITSVertexer(NULL),
   fITSTracker(NULL),
   fTPCLoader(NULL),
   fTPCTracker(NULL),
@@ -174,69 +199,66 @@ Bool_t AliReconstruction::Run()
   }
   gAlice = aliRun;
 
-  // local reconstruction
-  if (!fRunReconstruction.IsNull()) {
-    if (!RunReconstruction(fRunReconstruction)) {
-      if (fStopOnError) {CleanUp(); return kFALSE;}
+  // load the reconstructor objects
+  TPluginManager* pluginManager = gROOT->GetPluginManager();
+  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+    TString detName = fgkDetectorName[iDet];
+    TString recName = "Ali" + detName + "Reconstructor";
+    if (!gAlice->GetDetector(detName) && detName != "HLT") continue;
+
+    if(detName == "HLT") {
+      if (!gROOT->GetClass("AliLevel3")) {
+       gSystem->Load("libAliL3Src.so");
+       gSystem->Load("libAliL3Misc.so");
+       gSystem->Load("libAliL3Hough.so");
+       gSystem->Load("libAliL3Comp.so");
+      }
     }
-  }
-  if (!fRunTracking && fFillESD.IsNull()) return kTRUE;
 
-  // get loaders and trackers
-  fITSLoader = fRunLoader->GetLoader("ITSLoader");
-  if (!fITSLoader) {
-    Error("Run", "no ITS loader found");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
-  }
-  fITSTracker = NULL;
-  if (aliRun->GetDetector("ITS")) {
-    fITSTracker = aliRun->GetDetector("ITS")->CreateTracker();
-  }
-  if (!fITSTracker) {
-    Error("Run", "couldn't create a tracker for ITS");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
+    AliReconstructor* reconstructor = NULL;
+    // first check if a plugin is defined for the reconstructor
+    TPluginHandler* pluginHandler = 
+      pluginManager->FindHandler("AliReconstructor", detName);
+    // if not, but the reconstructor class is implemented, add a plugin for it
+    if (!pluginHandler && gROOT->GetClass(recName.Data())) {
+      Info("Run", "defining plugin for %s", recName.Data());
+      pluginManager->AddHandler("AliReconstructor", detName, 
+                               recName, detName, recName + "()");
+      pluginHandler = pluginManager->FindHandler("AliReconstructor", detName);
+    }
+    if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
+      reconstructor = (AliReconstructor*) pluginHandler->ExecPlugin(0);
+    }
+    // if there is no reconstructor class for the detector use the dummy one
+    if (!reconstructor && gAlice->GetDetector(detName)) {
+      Info("Run", "using dummy reconstructor for %s", detName.Data());
+      reconstructor = new AliDummyReconstructor(gAlice->GetDetector(detName));
+    }
+    if (reconstructor) fReconstructors.Add(reconstructor);
   }
 
-  fTPCLoader = fRunLoader->GetLoader("TPCLoader");
-  if (!fTPCLoader) {
-    Error("Run", "no TPC loader found");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
-  }
-  fTPCTracker = NULL;
-  if (aliRun->GetDetector("TPC")) {
-    fTPCTracker = aliRun->GetDetector("TPC")->CreateTracker();
-  }
-  if (!fTPCTracker) {
-    Error("Run", "couldn't create a tracker for TPC");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
+  // local reconstruction
+  if (!fRunLocalReconstruction.IsNull()) {
+    if (!RunLocalReconstruction(fRunLocalReconstruction)) {
+      if (fStopOnError) {CleanUp(); return kFALSE;}
+    }
   }
+  if (!fRunVertexFinder && !fRunTracking && fFillESD.IsNull()) return kTRUE;
 
-  fTRDLoader = fRunLoader->GetLoader("TRDLoader");
-  if (!fTRDLoader) {
-    Error("Run", "no TRD loader found");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
-  }
-  fTRDTracker = NULL;
-  if (aliRun->GetDetector("TRD")) {
-    fTRDTracker = aliRun->GetDetector("TRD")->CreateTracker();
-  }
-  if (!fTRDTracker) {
-    Error("Run", "couldn't create a tracker for TRD");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
+  // get vertexer
+  if (fRunVertexFinder && !CreateVertexer()) {
+    if (fStopOnError) {
+      CleanUp(); 
+      return kFALSE;
+    }
   }
 
-  fTOFLoader = fRunLoader->GetLoader("TOFLoader");
-  if (!fTOFLoader) {
-    Error("Run", "no TOF loader found");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
-  }
-  fTOFTracker = NULL;
-  if (aliRun->GetDetector("TOF")) {
-    fTOFTracker = aliRun->GetDetector("TOF")->CreateTracker();
-  }
-  if (!fTOFTracker) {
-    Error("Run", "couldn't create a tracker for TOF");
-    if (fStopOnError) {CleanUp(); return kFALSE;}
+  // get loaders and trackers
+  if (fRunTracking && !CreateTrackers()) {
+    if (fStopOnError) {
+      CleanUp(); 
+      return kFALSE;
+    }      
   }
 
   // create the ESD output file
@@ -249,16 +271,35 @@ Bool_t AliReconstruction::Run()
   // loop over events
   for (Int_t iEvent = 0; iEvent < fRunLoader->GetNumberOfEvents(); iEvent++) {
     Info("Run", "processing event %d", iEvent);
-    AliESD* esd = new AliESD;
     fRunLoader->GetEvent(iEvent);
+
+    char fileName[256];
+    sprintf(fileName, "ESD_%d.%d_final.root", 
+           aliRun->GetRunNumber(), aliRun->GetEvNumber());
+    if (!gSystem->AccessPathName(fileName)) continue;
+
+    AliESD* esd = new AliESD;
     esd->SetRunNumber(aliRun->GetRunNumber());
     esd->SetEventNumber(aliRun->GetEvNumber());
     esd->SetMagneticField(aliRun->Field()->SolenoidField());
 
+    // vertex finder
+    if (fRunVertexFinder) {
+      if (!ReadESD(esd, "vertex")) {
+       if (!RunVertexFinder(esd)) {
+         if (fStopOnError) {CleanUp(file); return kFALSE;}
+       }
+       if (fCheckPointLevel > 0) WriteESD(esd, "vertex");
+      }
+    }
+
     // barrel tracking
     if (fRunTracking) {
-      if (!RunTracking(esd)) {
-       if (fStopOnError) {CleanUp(file); return kFALSE;}
+      if (!ReadESD(esd, "tracking")) {
+       if (!RunTracking(esd)) {
+         if (fStopOnError) {CleanUp(file); return kFALSE;}
+       }
+       if (fCheckPointLevel > 0) WriteESD(esd, "tracking");
       }
     }
 
@@ -271,6 +312,7 @@ Bool_t AliReconstruction::Run()
 
     // combined PID
     AliESDpid::MakePID(esd);
+    if (fCheckPointLevel > 1) WriteESD(esd, "PID");
 
     // write ESD
     char name[100]; 
@@ -280,6 +322,10 @@ Bool_t AliReconstruction::Run()
       Error("Run", "writing ESD failed");
       if (fStopOnError) {CleanUp(file); return kFALSE;}
     }
+    file->Flush();
+
+    if (fCheckPointLevel > 0) WriteESD(esd, "final");
+    delete esd;
   }
 
   CleanUp(file);
@@ -289,25 +335,25 @@ Bool_t AliReconstruction::Run()
 
 
 //_____________________________________________________________________________
-Bool_t AliReconstruction::RunReconstruction(const TString& detectors)
+Bool_t AliReconstruction::RunLocalReconstruction(const TString& detectors)
 {
-// run the reconstruction
+// run the local reconstruction
 
   TStopwatch stopwatch;
   stopwatch.Start();
 
   TString detStr = detectors;
-  TObjArray* detArray = fRunLoader->GetAliRun()->Detectors();
-  for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
-    AliModule* det = (AliModule*) detArray->At(iDet);
-    if (!det || !det->IsActive()) continue;
-    if (IsSelected(det->GetName(), detStr)) {
+  for (Int_t iDet = 0; iDet < fReconstructors.GetEntriesFast(); iDet++) {
+    AliReconstructor* reconstructor = 
+      (AliReconstructor*) fReconstructors[iDet];
+    TString detName = reconstructor->GetDetectorName();
+    if (IsSelected(detName, detStr)) {
       Info("RunReconstruction", "running reconstruction for %s", 
-          det->GetName());
+          detName.Data());
       TStopwatch stopwatchDet;
       stopwatchDet.Start();
-      det->Reconstruct();
-      Info("RunReconstruction", "execution time for %s:", det->GetName());
+      reconstructor->Reconstruct(fRunLoader);
+      Info("RunReconstruction", "execution time for %s:", detName.Data());
       stopwatchDet.Print();
     }
   }
@@ -325,27 +371,70 @@ Bool_t AliReconstruction::RunReconstruction(const TString& detectors)
 }
 
 //_____________________________________________________________________________
-Bool_t AliReconstruction::RunTracking(AliESD* esd)
+Bool_t AliReconstruction::RunVertexFinder(AliESD*& esd)
+{
+// run the barrel tracking
+
+  TStopwatch stopwatch;
+  stopwatch.Start();
+
+  AliESDVertex* vertex = NULL;
+  Double_t vtxPos[3] = {0, 0, 0};
+  Double_t vtxErr[3] = {0.07, 0.07, 0.1};
+  TArrayF mcVertex(3); 
+  if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
+    fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
+    for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
+  }
+
+  if (fITSVertexer) {
+    Info("RunVertexFinder", "running the ITS vertex finder");
+    fITSVertexer->SetDebug(1);
+    vertex = fITSVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
+    if(!vertex){
+      Warning("RunVertexFinder","Vertex not found \n");
+      vertex = new AliESDVertex();
+    }
+    else {
+      vertex->SetTruePos(vtxPos);  // store also the vertex from MC
+    }
+
+  } else {
+    Info("RunVertexFinder", "getting the primary vertex from MC");
+    vertex = new AliESDVertex(vtxPos, vtxErr);
+  }
+
+  if (vertex) {
+    vertex->GetXYZ(vtxPos);
+    vertex->GetSigmaXYZ(vtxErr);
+  } else {
+    Warning("RunVertexFinder", "no vertex reconstructed");
+    vertex = new AliESDVertex(vtxPos, vtxErr);
+  }
+  esd->SetVertex(vertex);
+  if (fITSTracker) fITSTracker->SetVertex(vtxPos, vtxErr);
+  if (fTPCTracker) fTPCTracker->SetVertex(vtxPos, vtxErr);
+  if (fTRDTracker) fTRDTracker->SetVertex(vtxPos, vtxErr);
+  delete vertex;
+
+  Info("RunVertexFinder", "execution time:");
+  stopwatch.Print();
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::RunTracking(AliESD*& esd)
 {
 // run the barrel tracking
 
   TStopwatch stopwatch;
   stopwatch.Start();
 
-  // get the primary vertex (from MC for the moment)
-  TArrayF vertex(3);     
-  fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(vertex);
-  Double_t vtxPos[3] = {vertex[0], vertex[1], vertex[2]};
-  Double_t vtxCov[6] = {
-    0.005,
-    0.000, 0.005,
-    0.000, 0.000, 0.010
-  };
-  Double_t vtxErr[3] = {vtxCov[0], vtxCov[2], vtxCov[5]}; // diag. elements
-  esd->SetVertex(vtxPos, vtxCov);
-  fITSTracker->SetVertex(vtxPos, vtxErr);
-  fTPCTracker->SetVertex(vtxPos, vtxErr);
-  fTRDTracker->SetVertex(vtxPos, vtxErr);
+  if (!fTPCTracker) {
+    Error("RunTracking", "no TPC tracker");
+    return kFALSE;
+  }
 
   // TPC tracking
   Info("RunTracking", "TPC tracking");
@@ -354,100 +443,124 @@ Bool_t AliReconstruction::RunTracking(AliESD* esd)
   if (!tpcTree) {
     Error("RunTracking", "Can't get the TPC cluster tree");
     return kFALSE;
-  }     
+  }
   fTPCTracker->LoadClusters(tpcTree);
   if (fTPCTracker->Clusters2Tracks(esd) != 0) {
     Error("RunTracking", "TPC Clusters2Tracks failed");
     return kFALSE;
   }
+  if (fCheckPointLevel > 1) WriteESD(esd, "TPC.tracking");
 
-  fRunLoader->GetAliRun()->GetDetector("TPC")->FillESD(esd); // preliminary PID
-  AliESDpid::MakePID(esd);                  // for the ITS tracker
-
-  // ITS tracking
-  Info("RunTracking", "ITS tracking");
-  fITSLoader->LoadRecPoints("read");
-  TTree* itsTree = fITSLoader->TreeR();
-  if (!itsTree) {
-    Error("RunTracking", "Can't get the ITS cluster tree");
-    return kFALSE;
-  }     
-  fITSTracker->LoadClusters(itsTree);
-  if (fITSTracker->Clusters2Tracks(esd) != 0) {
-    Error("RunTracking", "ITS Clusters2Tracks failed");
-    return kFALSE;
-  }
-
-  // ITS back propagation
-  Info("RunTracking", "ITS back propagation");
-  if (fITSTracker->PropagateBack(esd) != 0) {
-    Error("RunTracking", "ITS backward propagation failed");
-    return kFALSE;
-  }
+  if (!fITSTracker) {
+    Warning("RunTracking", "no ITS tracker");
+  } else {
+
+    fRunLoader->GetAliRun()->GetDetector("TPC")->FillESD(esd); // preliminary
+    AliESDpid::MakePID(esd);                  // PID for the ITS tracker
+
+    // ITS tracking
+    Info("RunTracking", "ITS tracking");
+    fITSLoader->LoadRecPoints("read");
+    TTree* itsTree = fITSLoader->TreeR();
+    if (!itsTree) {
+      Error("RunTracking", "Can't get the ITS cluster tree");
+      return kFALSE;
+    }
+    fITSTracker->LoadClusters(itsTree);
+    if (fITSTracker->Clusters2Tracks(esd) != 0) {
+      Error("RunTracking", "ITS Clusters2Tracks failed");
+      return kFALSE;
+    }
+    if (fCheckPointLevel > 1) WriteESD(esd, "ITS.tracking");
+
+    if (!fTRDTracker) {
+      Warning("RunTracking", "no TRD tracker");
+    } else {
+      // ITS back propagation
+      Info("RunTracking", "ITS back propagation");
+      if (fITSTracker->PropagateBack(esd) != 0) {
+       Error("RunTracking", "ITS backward propagation failed");
+       return kFALSE;
+      }
+      if (fCheckPointLevel > 1) WriteESD(esd, "ITS.back");
 
-  // TPC back propagation
-  Info("RunTracking", "TPC back propagation");
-  if (fTPCTracker->PropagateBack(esd) != 0) {
-    Error("RunTracking", "TPC backward propagation failed");
-    return kFALSE;
-  }
+      // TPC back propagation
+      Info("RunTracking", "TPC back propagation");
+      if (fTPCTracker->PropagateBack(esd) != 0) {
+       Error("RunTracking", "TPC backward propagation failed");
+       return kFALSE;
+      }
+      if (fCheckPointLevel > 1) WriteESD(esd, "TPC.back");
+
+      // TRD back propagation
+      Info("RunTracking", "TRD back propagation");
+      fTRDLoader->LoadRecPoints("read");
+      TTree* trdTree = fTRDLoader->TreeR();
+      if (!trdTree) {
+       Error("RunTracking", "Can't get the TRD cluster tree");
+       return kFALSE;
+      }
+      fTRDTracker->LoadClusters(trdTree);
+      if (fTRDTracker->PropagateBack(esd) != 0) {
+       Error("RunTracking", "TRD backward propagation failed");
+       return kFALSE;
+      }
+      if (fCheckPointLevel > 1) WriteESD(esd, "TRD.back");
+
+      if (!fTOFTracker) {
+       Warning("RunTracking", "no TOF tracker");
+      } else {
+       // TOF back propagation
+       Info("RunTracking", "TOF back propagation");
+       fTOFLoader->LoadDigits("read");
+       TTree* tofTree = fTOFLoader->TreeD();
+       if (!tofTree) {
+         Error("RunTracking", "Can't get the TOF digits tree");
+         return kFALSE;
+       }
+       fTOFTracker->LoadClusters(tofTree);
+       if (fTOFTracker->PropagateBack(esd) != 0) {
+         Error("RunTracking", "TOF backward propagation failed");
+         return kFALSE;
+       }
+       if (fCheckPointLevel > 1) WriteESD(esd, "TOF.back");
+       fTOFTracker->UnloadClusters();
+       fTOFLoader->UnloadDigits();
+      }
 
-  // TRD back propagation
-  Info("RunTracking", "TRD back propagation");
-  fTRDLoader->LoadRecPoints("read");
-  TTree* trdTree = fTRDLoader->TreeR();
-  if (!trdTree) {
-    Error("RunTracking", "Can't get the TRD cluster tree");
-    return kFALSE;
-  }     
-  fTRDTracker->LoadClusters(trdTree);
-  if (fTRDTracker->PropagateBack(esd) != 0) {
-    Error("RunTracking", "TRD backward propagation failed");
-    return kFALSE;
-  }
+      // TRD inward refit
+      Info("RunTracking", "TRD inward refit");
+      if (fTRDTracker->RefitInward(esd) != 0) {
+       Error("RunTracking", "TRD inward refit failed");
+       return kFALSE;
+      }
+      if (fCheckPointLevel > 1) WriteESD(esd, "TRD.refit");
+      fTRDTracker->UnloadClusters();
+      fTRDLoader->UnloadRecPoints();
+    
+      // TPC inward refit
+      Info("RunTracking", "TPC inward refit");
+      if (fTPCTracker->RefitInward(esd) != 0) {
+       Error("RunTracking", "TPC inward refit failed");
+       return kFALSE;
+      }
+      if (fCheckPointLevel > 1) WriteESD(esd, "TPC.refit");
+    
+      // ITS inward refit
+      Info("RunTracking", "ITS inward refit");
+      if (fITSTracker->RefitInward(esd) != 0) {
+       Error("RunTracking", "ITS inward refit failed");
+       return kFALSE;
+      }
+      if (fCheckPointLevel > 1) WriteESD(esd, "ITS.refit");
 
-  // TOF back propagation
-  Info("RunTracking", "TOF back propagation");
-  fTOFLoader->LoadDigits("read");
-  TTree* tofTree = fTOFLoader->TreeD();
-  if (!tofTree) {
-    Error("RunTracking", "Can't get the TOF digits tree");
-    return kFALSE;
-  }     
-  fTOFTracker->LoadClusters(tofTree);
-  if (fTOFTracker->PropagateBack(esd) != 0) {
-    Error("RunTracking", "TOF backward propagation failed");
-    return kFALSE;
-  }
-  fTOFTracker->UnloadClusters();
-  fTOFLoader->UnloadDigits();
+    }  // if TRD tracker
+    fITSTracker->UnloadClusters();
+    fITSLoader->UnloadRecPoints();
 
-  // TRD inward refit
-  Info("RunTracking", "TRD inward refit");
-  if (fTRDTracker->RefitInward(esd) != 0) {
-    Error("RunTracking", "TRD inward refit failed");
-    return kFALSE;
-  }
-  fTRDTracker->UnloadClusters();
-  fTRDLoader->UnloadRecPoints();
-    
-  // TPC inward refit
-  Info("RunTracking", "TPC inward refit");
-  if (fTPCTracker->RefitInward(esd) != 0) {
-    Error("RunTracking", "TPC inward refit failed");
-    return kFALSE;
-  }
+  }  // if ITS tracker
   fTPCTracker->UnloadClusters();
   fTPCLoader->UnloadRecPoints();
-    
-  // ITS inward refit
-  Info("RunTracking", "ITS inward refit");
-  if (fITSTracker->RefitInward(esd) != 0) {
-    Error("RunTracking", "ITS inward refit failed");
-    return kFALSE;
-  }
-  fITSTracker->UnloadClusters();
-  fITSLoader->UnloadRecPoints();
 
   Info("RunTracking", "execution time:");
   stopwatch.Print();
@@ -456,7 +569,7 @@ Bool_t AliReconstruction::RunTracking(AliESD* esd)
 }
 
 //_____________________________________________________________________________
-Bool_t AliReconstruction::FillESD(AliESD* esd, const TString& detectors)
+Bool_t AliReconstruction::FillESD(AliESD*& esd, const TString& detectors)
 {
 // fill the event summary data
 
@@ -464,14 +577,16 @@ Bool_t AliReconstruction::FillESD(AliESD* esd, const TString& detectors)
   stopwatch.Start();
 
   TString detStr = detectors;
-  TObjArray* detArray = fRunLoader->GetAliRun()->Detectors();
-  for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
-    AliModule* det = (AliModule*) detArray->At(iDet);
-    if (!det || !det->IsActive()) continue;
-    if (IsSelected(det->GetName(), detStr)) {
-      Info("FillESD", "filling ESD for %s", 
-          det->GetName());
-      det->FillESD(esd);
+  for (Int_t iDet = 0; iDet < fReconstructors.GetEntriesFast(); iDet++) {
+    AliReconstructor* reconstructor = 
+      (AliReconstructor*) fReconstructors[iDet];
+    TString detName = reconstructor->GetDetectorName();
+    if (IsSelected(detName, detStr)) {
+      if (!ReadESD(esd, detName.Data())) {
+       Info("FillESD", "filling ESD for %s", detName.Data());
+       reconstructor->FillESD(fRunLoader, esd);
+       if (fCheckPointLevel > 2) WriteESD(esd, detName.Data());
+      }
     }
   }
 
@@ -521,11 +636,120 @@ Bool_t AliReconstruction::IsSelected(TString detName, TString& detectors) const
   return result;
 }
 
+//_____________________________________________________________________________
+AliReconstructor* AliReconstruction::GetReconstructor(const char* detName) const
+{
+// get the reconstructor object for a detector
+
+  for (Int_t iDet = 0; iDet < fReconstructors.GetEntriesFast(); iDet++) {
+    AliReconstructor* reconstructor = 
+      (AliReconstructor*) fReconstructors[iDet];
+    if (strcmp(reconstructor->GetDetectorName(), detName) == 0) {
+      return reconstructor;
+    }
+  }
+  return NULL;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::CreateVertexer()
+{
+// create the vertexer
+
+  fITSVertexer = NULL;
+  AliReconstructor* itsReconstructor = GetReconstructor("ITS");
+  if (itsReconstructor) {
+    fITSVertexer = itsReconstructor->CreateVertexer(fRunLoader);
+  }
+  if (!fITSVertexer) {
+    Warning("CreateVertexer", "couldn't create a vertexer for ITS");
+    if (fStopOnError) return kFALSE;
+  }
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::CreateTrackers()
+{
+// get the loaders and create the trackers
+
+  fITSTracker = NULL;
+  fITSLoader = fRunLoader->GetLoader("ITSLoader");
+  if (!fITSLoader) {
+    Warning("CreateTrackers", "no ITS loader found");
+    if (fStopOnError) return kFALSE;
+  } else {
+    AliReconstructor* itsReconstructor = GetReconstructor("ITS");
+    if (itsReconstructor) {
+      fITSTracker = itsReconstructor->CreateTracker(fRunLoader);
+    }
+    if (!fITSTracker) {
+      Warning("CreateTrackers", "couldn't create a tracker for ITS");
+      if (fStopOnError) return kFALSE;
+    }
+  }
+    
+  fTPCTracker = NULL;
+  fTPCLoader = fRunLoader->GetLoader("TPCLoader");
+  if (!fTPCLoader) {
+    Error("CreateTrackers", "no TPC loader found");
+    if (fStopOnError) return kFALSE;
+  } else {
+    AliReconstructor* tpcReconstructor = GetReconstructor("TPC");
+    if (tpcReconstructor) {
+      fTPCTracker = tpcReconstructor->CreateTracker(fRunLoader);
+    }
+    if (!fTPCTracker) {
+      Error("CreateTrackers", "couldn't create a tracker for TPC");
+      if (fStopOnError) return kFALSE;
+    }
+  }
+    
+  fTRDTracker = NULL;
+  fTRDLoader = fRunLoader->GetLoader("TRDLoader");
+  if (!fTRDLoader) {
+    Warning("CreateTrackers", "no TRD loader found");
+    if (fStopOnError) return kFALSE;
+  } else {
+    AliReconstructor* trdReconstructor = GetReconstructor("TRD");
+    if (trdReconstructor) {
+      fTRDTracker = trdReconstructor->CreateTracker(fRunLoader);
+    }
+    if (!fTRDTracker) {
+      Warning("CreateTrackers", "couldn't create a tracker for TRD");
+      if (fStopOnError) return kFALSE;
+    }
+  }
+    
+  fTOFTracker = NULL;
+  fTOFLoader = fRunLoader->GetLoader("TOFLoader");
+  if (!fTOFLoader) {
+    Warning("CreateTrackers", "no TOF loader found");
+    if (fStopOnError) return kFALSE;
+  } else {
+    AliReconstructor* tofReconstructor = GetReconstructor("TOF");
+    if (tofReconstructor) {
+      fTOFTracker = tofReconstructor->CreateTracker(fRunLoader);
+    }
+    if (!fTOFTracker) {
+      Warning("CreateTrackers", "couldn't create a tracker for TOF");
+      if (fStopOnError) return kFALSE;
+    }
+  }
+
+  return kTRUE;
+}
+
 //_____________________________________________________________________________
 void AliReconstruction::CleanUp(TFile* file)
 {
 // delete trackers and the run loader and close and delete the file
 
+  fReconstructors.Delete();
+
+  delete fITSVertexer;
+  fITSVertexer = NULL;
   delete fITSTracker;
   fITSTracker = NULL;
   delete fTPCTracker;
@@ -543,3 +767,52 @@ void AliReconstruction::CleanUp(TFile* file)
     delete file;
   }
 }
+
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::ReadESD(AliESD*& esd, const char* recStep) const
+{
+// read the ESD event from a file
+
+  if (!esd) return kFALSE;
+  char fileName[256];
+  sprintf(fileName, "ESD_%d.%d_%s.root", 
+         esd->GetRunNumber(), esd->GetEventNumber(), recStep);
+  if (gSystem->AccessPathName(fileName)) return kFALSE;
+
+  Info("ReadESD", "reading ESD from file %s", fileName);
+  TFile* file = TFile::Open(fileName);
+  if (!file || !file->IsOpen()) {
+    Error("ReadESD", "opening %s failed", fileName);
+    delete file;
+    return kFALSE;
+  }
+
+  gROOT->cd();
+  delete esd;
+  esd = (AliESD*) file->Get("ESD");
+  file->Close();
+  delete file;
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::WriteESD(AliESD* esd, const char* recStep) const
+{
+// write the ESD event to a file
+
+  if (!esd) return;
+  char fileName[256];
+  sprintf(fileName, "ESD_%d.%d_%s.root", 
+         esd->GetRunNumber(), esd->GetEventNumber(), recStep);
+
+  Info("WriteESD", "writing ESD to file %s", fileName);
+  TFile* file = TFile::Open(fileName, "recreate");
+  if (!file || !file->IsOpen()) {
+    Error("WriteESD", "opening %s failed", fileName);
+  } else {
+    esd->Write("ESD");
+    file->Close();
+  }
+  delete file;
+}