]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliReconstruction.cxx
Changes for report #74151: Important update in AliTOFPIDResponse class: use also...
[u/mrichter/AliRoot.git] / STEER / AliReconstruction.cxx
index 1329fe0c22d9f0001499f39a877728c9635811a9..031286da59dabaed3b5aa2120495f06c5ae1ddbb 100644 (file)
 // The reconstruction requires digits or raw data as input. For the creation //
 // of digits and raw data 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.     //
+// The input data of a detector can be replaced by the corresponding HLT     //
+// data by calling (usual detector string)                                   //
+// SetUseHLTData("...");                                                     //
+//                                                                           //
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
+#include <TArrayD.h>
 #include <TArrayF.h>
+#include <TArrayS.h>
+#include <TChain.h>
 #include <TFile.h>
-#include <TList.h>
-#include <TSystem.h>
-#include <TROOT.h>
-#include <TPluginManager.h>
+#include <TGeoGlobalMagField.h>
 #include <TGeoManager.h>
+#include <TList.h>
 #include <TLorentzVector.h>
-#include <TArrayS.h>
-#include <TArrayD.h>
+#include <TMap.h>
+#include <TObjArray.h>
+#include <TPRegexp.h>
+#include <TParameter.h>
+#include <TPluginManager.h>
+#include <TProof.h>
+#include <TProofOutputFile.h>
+#include <TROOT.h>
+#include <TSystem.h>
+#include <THashTable.h>
+#include <TGrid.h>
+#include <TMessage.h>
+#include <TUrl.h>
+#include <TRandom.h>
 
-#include "AliReconstruction.h"
+#include "AliAlignObj.h"
+#include "AliCDBEntry.h"
+#include "AliCDBManager.h"
+#include "AliCDBStorage.h"
+#include "AliCTPRawStream.h"
+#include "AliCascadeVertexer.h"
+#include "AliCentralTrigger.h"
 #include "AliCodeTimer.h"
-#include "AliReconstructor.h"
-#include "AliLog.h"
-#include "AliRunLoader.h"
-#include "AliRun.h"
-#include "AliRawReaderFile.h"
-#include "AliRawReaderDate.h"
-#include "AliRawReaderRoot.h"
-#include "AliRawEventHeaderBase.h"
+#include "AliDAQ.h"
+#include "AliDetectorRecoParam.h"
+#include "AliESDCaloCells.h"
+#include "AliESDCaloCluster.h"
 #include "AliESDEvent.h"
 #include "AliESDMuonTrack.h"
-#include "AliESDfriend.h"
+#include "AliESDPmdTrack.h"
+#include "AliESDTagCreator.h"
 #include "AliESDVertex.h"
 #include "AliESDcascade.h"
+#include "AliESDfriend.h"
 #include "AliESDkink.h"
-#include "AliESDtrack.h"
-#include "AliESDCaloCluster.h"
-#include "AliESDCaloCells.h"
-#include "AliMultiplicity.h"
-#include "AliTracker.h"
-#include "AliVertexer.h"
-#include "AliVertexerTracks.h"
-#include "AliV0vertexer.h"
-#include "AliCascadeVertexer.h"
-#include "AliHeader.h"
-#include "AliGenEventHeader.h"
-#include "AliPID.h"
 #include "AliESDpid.h"
 #include "AliESDtrack.h"
-#include "AliESDPmdTrack.h"
-
-#include "AliESDTagCreator.h"
-#include "AliAODTagCreator.h"
-
+#include "AliESDtrack.h"
+#include "AliEventInfo.h"
+#include "AliGRPObject.h"
+#include "AliGRPRecoParam.h"
+#include "AliGenEventHeader.h"
 #include "AliGeomManager.h"
-#include "AliTrackPointArray.h"
-#include "AliCDBManager.h"
-#include "AliCDBStorage.h"
-#include "AliCDBEntry.h"
-#include "AliAlignObj.h"
-
-#include "AliCentralTrigger.h"
-#include "AliCTPRawStream.h"
-
-#include "AliAODEvent.h"
-#include "AliAODHeader.h"
-#include "AliAODTrack.h"
-#include "AliAODVertex.h"
-#include "AliAODv0.h"
-#include "AliAODJet.h"
-#include "AliAODCaloCells.h"
-#include "AliAODCaloCluster.h"
-#include "AliAODPmdCluster.h"
-#include "AliAODFmdCluster.h"
-#include "AliAODTracklets.h"
-
-#include "AliQADataMakerRec.h" 
 #include "AliGlobalQADataMaker.h" 
-#include "AliQA.h"
-#include "AliQADataMakerSteer.h"
-
+#include "AliHeader.h"
+#include "AliLog.h"
+#include "AliMagF.h"
+#include "AliMultiplicity.h"
+#include "AliPID.h"
+#include "AliPlaneEff.h"
+#include "AliQAv1.h"
+#include "AliQADataMakerRec.h" 
+#include "AliQAManager.h"
+#include "AliRawVEvent.h"
+#include "AliRawEventHeaderBase.h"
+#include "AliRawHLTManager.h"
+#include "AliRawReaderDate.h"
+#include "AliRawReaderFile.h"
+#include "AliRawReaderRoot.h"
+#include "AliReconstruction.h"
+#include "AliReconstructor.h"
+#include "AliRun.h"
+#include "AliRunInfo.h"
+#include "AliRunLoader.h"
 #include "AliSysInfo.h" // memory snapshots
-
-
+#include "AliTrackPointArray.h"
+#include "AliTracker.h"
+#include "AliTriggerClass.h"
+#include "AliTriggerCluster.h"
+#include "AliTriggerIR.h"
+#include "AliTriggerConfiguration.h"
+#include "AliV0vertexer.h"
+#include "AliVertexer.h"
+#include "AliTrackleter.h"
+#include "AliVertexerTracks.h"
+#include "AliTriggerRunScalers.h"
+#include "AliCTPTimeParams.h" 
+#include "AliESDHLTDecision.h"
+#include "AliTriggerInput.h"
+#include "AliLHCData.h"
 ClassImp(AliReconstruction)
 
-
 //_____________________________________________________________________________
-const char* AliReconstruction::fgkDetectorName[AliReconstruction::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
+const char* AliReconstruction::fgkDetectorName[AliReconstruction::kNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
 
 //_____________________________________________________________________________
-AliReconstruction::AliReconstruction(const char* gAliceFilename,
-                                    const char* name, const char* title) :
-  TNamed(name, title),
-
-  fUniformField(kTRUE),
+AliReconstruction::AliReconstruction(const char* gAliceFilename) :
+  TSelector(),
   fRunVertexFinder(kTRUE),
+  fRunVertexFinderTracks(kTRUE),
   fRunHLTTracking(kFALSE),
   fRunMuonTracking(kFALSE),
   fRunV0Finder(kTRUE),
   fRunCascadeFinder(kTRUE),
-  fStopOnError(kFALSE),
+  fRunMultFinder(kTRUE),
+  fStopOnError(kTRUE),
   fWriteAlignmentData(kFALSE),
   fWriteESDfriend(kFALSE),
-  fWriteAOD(kFALSE),
   fFillTriggerESD(kTRUE),
 
   fCleanESD(kTRUE),
@@ -222,64 +226,108 @@ AliReconstruction::AliReconstruction(const char* gAliceFilename,
   fRunLocalReconstruction("ALL"),
   fRunTracking("ALL"),
   fFillESD("ALL"),
+  fLoadCDB(""),
   fUseTrackingErrorsForAlignment(""),
   fGAliceFileName(gAliceFilename),
-  fInput(""),
+  fRawInput(""),
+  fESDOutput(""),
+  fProofOutputFileName(""),
+  fProofOutputLocation(""),
+  fProofOutputDataset(kFALSE),
+  fProofOutputArchive(""),
   fEquipIdMap(""),
   fFirstEvent(0),
   fLastEvent(-1),
-  fNumberOfEventsPerFile(1),
-  fCheckPointLevel(0),
+  fNumberOfEventsPerFile((UInt_t)-1),
+  fFractionFriends(0.04),
   fOptions(),
   fLoadAlignFromCDB(kTRUE),
   fLoadAlignData("ALL"),
-  fESDPar(""),
+  fUseHLTData(),
+  fRunInfo(NULL),
+  fEventInfo(),
+  fRunScalers(NULL),
+  fCTPTimeParams(NULL),  
+  fCTPTimeAlign(NULL),  
 
   fRunLoader(NULL),
   fRawReader(NULL),
+  fParentRawReader(NULL),
 
-  fVertexer(NULL),
-  fDiamondProfile(NULL),
-  fMeanVertexConstraint(kTRUE),
+  fRecoParam(),
 
-  fGRPList(NULL),
+  fSPDTrackleter(NULL),
+
+  fDiamondProfileSPD(NULL),
+  fDiamondProfile(NULL),
+  fDiamondProfileTPC(NULL),
+  fListOfCosmicTriggers(NULL),
+  
+  fGRPData(NULL),
 
   fAlignObjArray(NULL),
   fCDBUri(),
+  fQARefUri(),
   fSpecCDBUri(), 
   fInitCDBCalled(kFALSE),
   fSetRunNumberFromDataCalled(kFALSE),
+  fQADetectors("ALL"), 
+  fQATasks("ALL"), 
   fRunQA(kTRUE),  
-  fRunGlobalQA(kFALSE),
-  fInLoopQA(kFALSE)
+  fRunGlobalQA(kTRUE),
+  fSameQACycle(kFALSE),
+  fInitQACalled(kFALSE), 
+  fWriteQAExpertData(kTRUE), 
+  fRunPlaneEff(kFALSE),
+
+  fesd(NULL),
+  fhltesd(NULL),
+  fesdf(NULL),
+  ffile(NULL),
+  ffileF(NULL),
+  ftree(NULL),
+  ftreeF(NULL),
+  fhlttree(NULL),
+  ftVertexer(NULL),
+  fIsNewRunLoader(kFALSE),
+  fRunAliEVE(kFALSE),
+  fChain(NULL),
+  fNall(0),
+  fNspecie(0),
+  fSspecie(0),
+  fNhighPt(0),
+  fShighPt(0)
 {
 // create reconstruction object with default parameters
+  gGeoManager = NULL;
   
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     fReconstructor[iDet] = NULL;
     fLoader[iDet] = NULL;
     fTracker[iDet] = NULL;
-    fQADataMaker[iDet] = NULL;
-       fQACycles[iDet] = 999999;       
   }
-  fQADataMaker[fgkNDetectors]=NULL;  //Global QA
+  for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
+    fQACycles[iDet] = 999999 ;
+    fQAWriteExpert[iDet] = kFALSE ; 
+  }
+  fBeamInt[0][0]=fBeamInt[0][1]=fBeamInt[1][0]=fBeamInt[1][1] = -1;
+
   AliPID pid;
 }
 
 //_____________________________________________________________________________
 AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
-  TNamed(rec),
-
-  fUniformField(rec.fUniformField),
+  TSelector(),
   fRunVertexFinder(rec.fRunVertexFinder),
+  fRunVertexFinderTracks(rec.fRunVertexFinderTracks),
   fRunHLTTracking(rec.fRunHLTTracking),
   fRunMuonTracking(rec.fRunMuonTracking),
   fRunV0Finder(rec.fRunV0Finder),
   fRunCascadeFinder(rec.fRunCascadeFinder),
+  fRunMultFinder(rec.fRunMultFinder),
   fStopOnError(rec.fStopOnError),
   fWriteAlignmentData(rec.fWriteAlignmentData),
   fWriteESDfriend(rec.fWriteESDfriend),
-  fWriteAOD(rec.fWriteAOD),
   fFillTriggerESD(rec.fFillTriggerESD),
 
   fCleanESD(rec.fCleanESD),
@@ -291,62 +339,238 @@ AliReconstruction::AliReconstruction(const AliReconstruction& rec) :
   fRunLocalReconstruction(rec.fRunLocalReconstruction),
   fRunTracking(rec.fRunTracking),
   fFillESD(rec.fFillESD),
+  fLoadCDB(rec.fLoadCDB),
   fUseTrackingErrorsForAlignment(rec.fUseTrackingErrorsForAlignment),
   fGAliceFileName(rec.fGAliceFileName),
-  fInput(rec.fInput),
+  fRawInput(rec.fRawInput),
+  fESDOutput(rec.fESDOutput),
+  fProofOutputFileName(rec.fProofOutputFileName),
+  fProofOutputLocation(rec.fProofOutputLocation),
+  fProofOutputDataset(rec.fProofOutputDataset),
+  fProofOutputArchive(rec.fProofOutputArchive),
   fEquipIdMap(rec.fEquipIdMap),
   fFirstEvent(rec.fFirstEvent),
   fLastEvent(rec.fLastEvent),
   fNumberOfEventsPerFile(rec.fNumberOfEventsPerFile),
-  fCheckPointLevel(0),
+  fFractionFriends(rec.fFractionFriends),
   fOptions(),
   fLoadAlignFromCDB(rec.fLoadAlignFromCDB),
   fLoadAlignData(rec.fLoadAlignData),
-  fESDPar(rec.fESDPar),
+  fUseHLTData(rec.fUseHLTData),
+  fRunInfo(NULL),
+  fEventInfo(),
+  fRunScalers(NULL),
+  fCTPTimeParams(NULL),
+  fCTPTimeAlign(NULL),
 
   fRunLoader(NULL),
   fRawReader(NULL),
+  fParentRawReader(NULL),
 
-  fVertexer(NULL),
-  fDiamondProfile(NULL),
-  fMeanVertexConstraint(rec.fMeanVertexConstraint),
+  fRecoParam(rec.fRecoParam),
+
+  fSPDTrackleter(NULL),
 
-  fGRPList(NULL),
+  fDiamondProfileSPD(rec.fDiamondProfileSPD),
+  fDiamondProfile(rec.fDiamondProfile),
+  fDiamondProfileTPC(rec.fDiamondProfileTPC),
+  fListOfCosmicTriggers(NULL),
+  
+  fGRPData(NULL),
 
   fAlignObjArray(rec.fAlignObjArray),
   fCDBUri(rec.fCDBUri),
+  fQARefUri(rec.fQARefUri),
   fSpecCDBUri(), 
   fInitCDBCalled(rec.fInitCDBCalled),
   fSetRunNumberFromDataCalled(rec.fSetRunNumberFromDataCalled),
+  fQADetectors(rec.fQADetectors), 
+  fQATasks(rec.fQATasks), 
   fRunQA(rec.fRunQA),  
   fRunGlobalQA(rec.fRunGlobalQA),
-  fInLoopQA(rec.fInLoopQA)
+  fSameQACycle(rec.fSameQACycle),
+  fInitQACalled(rec.fInitQACalled),
+  fWriteQAExpertData(rec.fWriteQAExpertData), 
+  fRunPlaneEff(rec.fRunPlaneEff),
+
+  fesd(NULL),
+  fhltesd(NULL),
+  fesdf(NULL),
+  ffile(NULL),
+  ffileF(NULL),
+  ftree(NULL),
+  ftreeF(NULL),
+  fhlttree(NULL),
+  ftVertexer(NULL),
+  fIsNewRunLoader(rec.fIsNewRunLoader),
+  fRunAliEVE(kFALSE),
+  fChain(NULL),
+  fNall(0),
+  fNspecie(0),
+  fSspecie(0),
+  fNhighPt(0),
+  fShighPt(0)
 {
 // copy constructor
 
   for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
     if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
   }
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     fReconstructor[iDet] = NULL;
     fLoader[iDet] = NULL;
     fTracker[iDet] = NULL;
-    fQADataMaker[iDet] = NULL;
-       fQACycles[iDet] = rec.fQACycles[iDet];  
+  }  
+  
+  for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
+    fQACycles[iDet] = rec.fQACycles[iDet];
+    fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ; 
   }
-  fQADataMaker[fgkNDetectors]=NULL;  //Global QA
+
   for (Int_t i = 0; i < rec.fSpecCDBUri.GetEntriesFast(); i++) {
     if (rec.fSpecCDBUri[i]) fSpecCDBUri.Add(rec.fSpecCDBUri[i]->Clone());
   }
+
+  for (int i=2;i--;) for (int j=2;j--;) fBeamInt[i][j] = rec.fBeamInt[i][j];
+
 }
 
 //_____________________________________________________________________________
 AliReconstruction& AliReconstruction::operator = (const AliReconstruction& rec)
 {
 // assignment operator
+// Used in PROOF mode
+// Be very careful while modifing it!
+// Simple rules to follow:
+// for persistent data members - use their assignment operators
+// for non-persistent ones - do nothing or take the default values from constructor
+// TSelector members should not be touched
+  if(&rec == this) return *this;
+
+  fRunVertexFinder       = rec.fRunVertexFinder;
+  fRunVertexFinderTracks = rec.fRunVertexFinderTracks;
+  fRunHLTTracking        = rec.fRunHLTTracking;
+  fRunMuonTracking       = rec.fRunMuonTracking;
+  fRunV0Finder           = rec.fRunV0Finder;
+  fRunCascadeFinder      = rec.fRunCascadeFinder;
+  fRunMultFinder         = rec.fRunMultFinder;
+  fStopOnError           = rec.fStopOnError;
+  fWriteAlignmentData    = rec.fWriteAlignmentData;
+  fWriteESDfriend        = rec.fWriteESDfriend;
+  fFillTriggerESD        = rec.fFillTriggerESD;
+
+  fCleanESD  = rec.fCleanESD;
+  fV0DCAmax  = rec.fV0DCAmax;
+  fV0CsPmin  = rec.fV0CsPmin;
+  fDmax      = rec.fDmax;
+  fZmax      = rec.fZmax;
+
+  fRunLocalReconstruction        = rec.fRunLocalReconstruction;
+  fRunTracking                   = rec.fRunTracking;
+  fFillESD                       = rec.fFillESD;
+  fLoadCDB                       = rec.fLoadCDB;
+  fUseTrackingErrorsForAlignment = rec.fUseTrackingErrorsForAlignment;
+  fGAliceFileName                = rec.fGAliceFileName;
+  fRawInput                      = rec.fRawInput;
+  fESDOutput                     = rec.fESDOutput;
+  fProofOutputFileName           = rec.fProofOutputFileName;
+  fProofOutputLocation           = rec.fProofOutputLocation;
+  fProofOutputDataset            = rec.fProofOutputDataset;
+  fProofOutputArchive            = rec.fProofOutputArchive;
+  fEquipIdMap                    = rec.fEquipIdMap;
+  fFirstEvent                    = rec.fFirstEvent;
+  fLastEvent                     = rec.fLastEvent;
+  fNumberOfEventsPerFile         = rec.fNumberOfEventsPerFile;
+  fFractionFriends               = rec.fFractionFriends;
+
+  for (Int_t i = 0; i < rec.fOptions.GetEntriesFast(); i++) {
+    if (rec.fOptions[i]) fOptions.Add(rec.fOptions[i]->Clone());
+  }
+
+  fLoadAlignFromCDB              = rec.fLoadAlignFromCDB;
+  fLoadAlignData                 = rec.fLoadAlignData;
+  fUseHLTData                    = rec.fUseHLTData;
+
+  delete fRunInfo; fRunInfo = NULL;
+  if (rec.fRunInfo) fRunInfo = new AliRunInfo(*rec.fRunInfo);
+
+  fEventInfo                     = rec.fEventInfo;
+
+  delete fRunScalers; fRunScalers = NULL;
+  if (rec.fRunScalers) fRunScalers = new AliTriggerRunScalers(*rec.fRunScalers); 
+
+  delete fCTPTimeParams; fCTPTimeParams = NULL;
+  if (rec.fCTPTimeParams) fCTPTimeParams = new AliCTPTimeParams(*rec.fCTPTimeParams);
+  delete fCTPTimeAlign; fCTPTimeAlign = NULL;
+  if (rec.fCTPTimeAlign) fCTPTimeAlign = new AliCTPTimeParams(*rec.fCTPTimeAlign);
+
+  fRunLoader       = NULL;
+  fRawReader       = NULL;
+  fParentRawReader = NULL;
+
+  fRecoParam = rec.fRecoParam;
+
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+    delete fReconstructor[iDet]; fReconstructor[iDet] = NULL;
+    delete fLoader[iDet]; fLoader[iDet] = NULL;
+    delete fTracker[iDet]; fTracker[iDet] = NULL;
+  }
+  
+  for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
+    fQACycles[iDet] = rec.fQACycles[iDet];
+    fQAWriteExpert[iDet] = rec.fQAWriteExpert[iDet] ;
+  } 
+
+  delete fSPDTrackleter; fSPDTrackleter = NULL;
+    
+  delete fDiamondProfileSPD; fDiamondProfileSPD = NULL;
+  if (rec.fDiamondProfileSPD) fDiamondProfileSPD = new AliESDVertex(*rec.fDiamondProfileSPD);
+  delete fDiamondProfile; fDiamondProfile = NULL;
+  if (rec.fDiamondProfile) fDiamondProfile = new AliESDVertex(*rec.fDiamondProfile);
+  delete fDiamondProfileTPC; fDiamondProfileTPC = NULL;
+  if (rec.fDiamondProfileTPC) fDiamondProfileTPC = new AliESDVertex(*rec.fDiamondProfileTPC);
+
+  delete fListOfCosmicTriggers; fListOfCosmicTriggers = NULL;
+  if (rec.fListOfCosmicTriggers) fListOfCosmicTriggers = (THashTable*)((rec.fListOfCosmicTriggers)->Clone());
+
+  delete fGRPData; fGRPData = NULL;
+  //  if (rec.fGRPData) fGRPData = (TMap*)((rec.fGRPData)->Clone());
+  if (rec.fGRPData) fGRPData = (AliGRPObject*)((rec.fGRPData)->Clone());
+
+  delete fAlignObjArray; fAlignObjArray = NULL;
+
+  fCDBUri        = "";
+  fQARefUri      = rec.fQARefUri;
+  fSpecCDBUri.Delete();
+  fInitCDBCalled               = rec.fInitCDBCalled;
+  fSetRunNumberFromDataCalled  = rec.fSetRunNumberFromDataCalled;
+  fQADetectors                 = rec.fQADetectors;
+  fQATasks                     = rec.fQATasks; 
+  fRunQA                       = rec.fRunQA;  
+  fRunGlobalQA                 = rec.fRunGlobalQA;
+  fSameQACycle                 = rec.fSameQACycle;
+  fInitQACalled                = rec.fInitQACalled;
+  fWriteQAExpertData           = rec.fWriteQAExpertData;
+  fRunPlaneEff                 = rec.fRunPlaneEff;
+  for (int i=2;i--;) for (int j=2;j--;) fBeamInt[i][j] = rec.fBeamInt[i][j];
+  fesd     = NULL;
+  fhltesd  = NULL;
+  fesdf    = NULL;
+  ffile    = NULL;
+  ffileF   = NULL;
+  ftree    = NULL;
+  ftreeF   = NULL;
+  fhlttree = NULL;
+  ftVertexer = NULL;
+  fIsNewRunLoader = rec.fIsNewRunLoader;
+  fRunAliEVE = kFALSE;
+  fChain = NULL;
+  fNall = 0;
+  fNspecie = 0;
+  fSspecie = 0;
+  fNhighPt = 0;
+  fShighPt = 0;
 
-  this->~AliReconstruction();
-  new(this) AliReconstruction(rec);
   return *this;
 }
 
@@ -356,18 +580,104 @@ AliReconstruction::~AliReconstruction()
 // clean up
 
   CleanUp();
+  if (fListOfCosmicTriggers) {
+    fListOfCosmicTriggers->Delete();
+    delete fListOfCosmicTriggers;
+  }
+  delete fGRPData;
+  delete fRunScalers;
+  delete fCTPTimeParams;
+  delete fCTPTimeAlign;
   fOptions.Delete();
+  if (fAlignObjArray) {
+    fAlignObjArray->Delete();
+    delete fAlignObjArray;
+  }
   fSpecCDBUri.Delete();
 
   AliCodeTimer::Instance()->Print();
 }
 
+//_____________________________________________________________________________
+void AliReconstruction::InitQA()
+{
+  //Initialize the QA and start of cycle 
+  AliCodeTimerAuto("",0);
+  
+  if (fInitQACalled) return;
+  fInitQACalled = kTRUE;
+  
+  AliQAManager * qam = AliQAManager::QAManager(AliQAv1::kRECMODE) ; 
+  if (fWriteQAExpertData)
+    qam->SetWriteExpert() ; 
+  if (qam->IsDefaultStorageSet()) {
+    AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+    AliWarning("Default QA reference storage has been already set !");
+    AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fQARefUri.Data()));
+    AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+    fQARefUri = qam->GetDefaultStorage()->GetURI();
+  } else {
+    if (fQARefUri.Length() > 0) {
+       AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+       AliDebug(2, Form("Default QA reference storage is set to: %s", fQARefUri.Data()));
+       AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+      } else {
+        fQARefUri="local://$ALICE_ROOT/QAref";
+        AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+        AliWarning("Default QA refeference storage not yet set !!!!");
+        AliWarning(Form("Setting it now to: %s", fQARefUri.Data()));
+        AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+               
+      }
+    qam->SetDefaultStorage(fQARefUri);
+  }
+  
+  if (fRunQA) {
+  qam->SetActiveDetectors(fQADetectors) ; 
+  for (Int_t det = 0 ; det < AliQAv1::kNDET ; det++) {
+    qam->SetCycleLength(AliQAv1::DETECTORINDEX_t(det), fQACycles[det]) ;  
+    qam->SetWriteExpert(AliQAv1::DETECTORINDEX_t(det)) ;
+  }
+  if (!fRawReader && !fInput && IsInTasks(AliQAv1::kRAWS))
+    fQATasks.ReplaceAll(Form("%d",AliQAv1::kRAWS), "") ;
+  qam->SetTasks(fQATasks) ; 
+  qam->InitQADataMaker(AliCDBManager::Instance()->GetRun()) ; 
+  }
+  if (fRunGlobalQA) {
+    Bool_t sameCycle = kFALSE ;
+    AliQADataMaker *qadm = qam->GetQADataMaker(AliQAv1::kGLOBAL);
+    AliInfo(Form("Initializing the global QA data maker"));
+    if (IsInTasks(AliQAv1::kRECPOINTS)) {
+      qadm->StartOfCycle(AliQAv1::kRECPOINTS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
+      TObjArray **arr=qadm->Init(AliQAv1::kRECPOINTS);
+      AliTracker::SetResidualsArray(arr);
+      sameCycle = kTRUE ; 
+    }
+    if (IsInTasks(AliQAv1::kESDS)) {
+      qadm->StartOfCycle(AliQAv1::kESDS, AliCDBManager::Instance()->GetRun(), sameCycle) ; 
+      qadm->Init(AliQAv1::kESDS);
+    }
+  }
+    AliSysInfo::AddStamp("InitQA") ; 
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::MergeQA(const char *fileName)
+{
+  //Initialize the QA and start of cycle 
+  AliCodeTimerAuto("",0) ;
+  AliQAManager::QAManager()->Merge(AliCDBManager::Instance()->GetRun(),fileName) ; 
+  AliSysInfo::AddStamp("MergeQA") ; 
+}
+  
 //_____________________________________________________________________________
 void AliReconstruction::InitCDB()
 {
 // activate a default CDB storage
 // First check if we have any CDB storage set, because it is used 
 // to retrieve the calibration and alignment constants
+  AliCodeTimerAuto("",0);
 
   if (fInitCDBCalled) return;
   fInitCDBCalled = kTRUE;
@@ -387,15 +697,21 @@ void AliReconstruction::InitCDB()
        AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
        AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-    } else {
-       fCDBUri="local://$ALICE_ROOT";
+       man->SetDefaultStorage(fCDBUri);
+    } 
+    else if (!man->GetRaw()){
+       fCDBUri="local://$ALICE_ROOT/OCDB";
        AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        AliWarning("Default CDB storage not yet set !!!!");
        AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
        AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
-               
+       man->SetDefaultStorage(fCDBUri);
+    }
+    else {    
+       AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+       AliWarning("Default storage will be set after setting the Run Number!!!");
+       AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");                    
     }
-    man->SetDefaultStorage(fCDBUri);
   }
 
   // Now activate the detector specific CDB storage locations
@@ -407,7 +723,7 @@ void AliReconstruction::InitCDB()
     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
   }
-  
+  AliSysInfo::AddStamp("InitCDB");
 }
 
 //_____________________________________________________________________________
@@ -419,6 +735,15 @@ void AliReconstruction::SetDefaultStorage(const char* uri) {
 
 }
 
+//_____________________________________________________________________________
+void AliReconstruction::SetQARefDefaultStorage(const char* uri) {
+  // Store the desired default CDB storage location
+  // Activate it later within the Run() method
+  
+  fQARefUri = uri;
+  AliQAv1::SetQARefStorage(fQARefUri.Data()) ;
+  
+}
 //_____________________________________________________________________________
 void AliReconstruction::SetSpecificStorage(const char* calibType, const char* uri) {
 // Store a detector-specific CDB storage location
@@ -427,7 +752,7 @@ void AliReconstruction::SetSpecificStorage(const char* calibType, const char* ur
   AliCDBPath aPath(calibType);
   if(!aPath.IsValid()){
        // if calibType is not wildcard but it is a valid detector, add "/*" to make it a valid path
-       for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+       for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
                if(!strcmp(calibType, fgkDetectorName[iDet])) {
                        aPath.SetPath(Form("%s/*", calibType));
                        AliInfo(Form("Path for specific storage set to %s", aPath.GetPath().Data()));
@@ -442,7 +767,7 @@ void AliReconstruction::SetSpecificStorage(const char* calibType, const char* ur
 
 //  // check that calibType refers to a "valid" detector name
 //  Bool_t isDetector = kFALSE;
-//  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+//  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
 //    TString detName = fgkDetectorName[iDet];
 //    if(aPath.GetLevel0() == detName) {
 //     isDetector = kTRUE;
@@ -473,33 +798,45 @@ Bool_t AliReconstruction::SetRunNumberFromData()
   fSetRunNumberFromDataCalled = kTRUE;
   
   AliCDBManager* man = AliCDBManager::Instance();
-  
-  if(man->GetRun() > 0) {
-       AliWarning("Run number is taken from event header! Ignoring settings in AliCDBManager!");
-  } 
-  
-  if (!fRunLoader) {
-      AliError("No run loader is found !"); 
+  if(fRawReader) {
+    if(fRawReader->NextEvent()) {
+      if(man->GetRun() > 0) {
+       AliWarning("Run number is taken from raw-event header! Ignoring settings in AliCDBManager!");
+      } 
+      man->SetRun(fRawReader->GetRunNumber());
+      fRawReader->RewindEvents();
+    }
+    else {
+      if(man->GetRun() > 0) {
+       AliWarning("No raw-data events are found ! Using settings in AliCDBManager !");
+      }
+      else {
+       AliWarning("Neither raw events nor settings in AliCDBManager are found !");
+       return kFALSE;
+      }
+    }
+  }
+  else {
+    AliRunLoader *rl = AliRunLoader::Open(fGAliceFileName.Data());
+    if (!rl) {
+      AliError(Form("No run loader found in file %s", fGAliceFileName.Data()));
       return kFALSE;
     }
-    // read run number from gAlice
-    if(fRunLoader->GetAliRun())
-      AliCDBManager::Instance()->SetRun(fRunLoader->GetHeader()->GetRun());
     else {
-      if(fRawReader) {
-       if(fRawReader->NextEvent()) {
-         AliCDBManager::Instance()->SetRun(fRawReader->GetRunNumber());
-         fRawReader->RewindEvents();
-       }
-       else {
-         AliError("No raw-data events found !");
-         return kFALSE;
-       }
+      rl->LoadHeader();
+      // read run number from gAlice
+      if(rl->GetHeader()) {
+       man->SetRun(rl->GetHeader()->GetRun());
+       rl->UnloadHeader();
+       delete rl;
       }
       else {
-       AliError("Neither gAlice nor RawReader objects are found !");
+       AliError("Neither run-loader header nor RawReader objects are found !");
+       delete rl;
        return kFALSE;
       }
+    }
   }
 
   man->Print();  
@@ -532,13 +869,21 @@ Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
     TString detStr = detectors;
     TString loadAlObjsListOfDets = "";
     
-    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-      if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
-      loadAlObjsListOfDets += fgkDetectorName[iDet];
-      loadAlObjsListOfDets += " ";
+    for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+      if(!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+      if(!strcmp(fgkDetectorName[iDet],"HLT")) continue;
+      
+      if(AliGeomManager::GetNalignable(fgkDetectorName[iDet]) != 0)
+      {
+       loadAlObjsListOfDets += fgkDetectorName[iDet];
+       loadAlObjsListOfDets += " ";
+      }
     } // end loop over detectors
-    loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
+    
+    if(AliGeomManager::GetNalignable("GRP") != 0)
+      loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
+    AliCDBManager::Instance()->UnloadFromCache("*/Align/*");
   }else{
     // Check if the array with alignment objects was
     // provided by the user. If yes, apply the objects
@@ -558,7 +903,10 @@ Bool_t AliReconstruction::MisalignGeometry(const TString& detectors)
     }
   }
   
-  delete fAlignObjArray; fAlignObjArray=0;
+  if (fAlignObjArray) {
+    fAlignObjArray->Delete();
+    delete fAlignObjArray; fAlignObjArray=NULL;
+  }
 
   return kTRUE;
 }
@@ -571,6 +919,27 @@ void AliReconstruction::SetGAliceFile(const char* fileName)
   fGAliceFileName = fileName;
 }
 
+//_____________________________________________________________________________
+void AliReconstruction::SetInput(const char* input) 
+{
+  // In case the input string starts with 'mem://', we run in an online mode
+  // and AliRawReaderDateOnline object is created. In all other cases a raw-data
+  // file is assumed. One can give as an input:
+  // mem://: - events taken from DAQ monitoring libs online
+  //  or
+  // mem://<filename> - emulation of the above mode (via DATE monitoring libs)
+  if (input) fRawInput = input;
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::SetOutput(const char* output) 
+{
+  // Set the output ESD filename
+  // 'output' is a normalt ROOT url
+  // The method is used in case of raw-data reco with PROOF
+  if (output) fESDOutput = output;
+}
+
 //_____________________________________________________________________________
 void AliReconstruction::SetOption(const char* detector, const char* option)
 {
@@ -581,425 +950,1206 @@ void AliReconstruction::SetOption(const char* detector, const char* option)
   fOptions.Add(new TNamed(detector, option));
 }
 
-
 //_____________________________________________________________________________
-Bool_t AliReconstruction::Run(const char* input, Bool_t IsOnline)
+void AliReconstruction::SetRecoParam(const char* detector, AliDetectorRecoParam *par)
 {
-// run the reconstruction
+  // Set custom reconstruction parameters for a given detector
+  // Single set of parameters for all the events
 
-  AliCodeTimerAuto("")
-  
-  // set the input
-  if (!IsOnline) {
-    if (!input) input = fInput.Data();
-    TString fileName(input);
-    if (fileName.EndsWith("/")) {
-      fRawReader = new AliRawReaderFile(fileName);
-    } else if (fileName.EndsWith(".root")) {
-      fRawReader = new AliRawReaderRoot(fileName);
-    } else if (!fileName.IsNull()) {
-      fRawReader = new AliRawReaderDate(fileName);
-    }
+  // First check if the reco-params are global
+  if(!strcmp(detector, "GRP")) {
+    par->SetAsDefault();
+    fRecoParam.AddDetRecoParam(kNDetectors,par);
+    return;
   }
-  else {
-    if (!input) {
-      AliError("Null pointer to the event structure!");
-      return kFALSE;
+
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+    if(!strcmp(detector, fgkDetectorName[iDet])) {
+      par->SetAsDefault();
+      fRecoParam.AddDetRecoParam(iDet,par);
+      break;
     }
-    fRawReader = new AliRawReaderDate((void *)input);
   }
 
-  if (!fEquipIdMap.IsNull() && fRawReader)
-    fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
-
-   AliSysInfo::AddStamp("Start");
-  // get the run loader
-  if (!InitRunLoader()) return kFALSE;
-   AliSysInfo::AddStamp("LoadLoader");
+}
 
-  // Initialize the CDB storage
-  InitCDB();
-  
-  AliSysInfo::AddStamp("LoadCDB");
+//_____________________________________________________________________________
+Bool_t AliReconstruction::InitGRP() {
+  //------------------------------------
+  // Initialization of the GRP entry 
+  //------------------------------------
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/Data");
 
-  // Set run number in CDBManager (if it is not already set by the user)
-  if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
-  
-  // Set CDB lock: from now on it is forbidden to reset the run number
-  // or the default storage or to activate any further storage!
-  SetCDBLock();
-  
-  // Import ideal TGeo geometry and apply misalignment
-  if (!gGeoManager) {
-    TString geom(gSystem->DirName(fGAliceFileName));
-    geom += "/geometry.root";
-    AliGeomManager::LoadGeometry(geom.Data());
-    if (!gGeoManager) if (fStopOnError) return kFALSE;
-  }
+  if (entry) {
 
-  if (!MisalignGeometry(fLoadAlignData)) if (fStopOnError) return kFALSE;
-   AliSysInfo::AddStamp("LoadGeom");
+    TMap* m = dynamic_cast<TMap*>(entry->GetObject());  // old GRP entry
 
-  //QA 
-  AliQADataMakerSteer qas ; 
-  if (fRunQA && fRawReader) qas.Run(fRunLocalReconstruction, fRawReader) ; 
-  // checking the QA of previous steps
-  //CheckQA() ; 
-  /*
-  // local reconstruction
-  if (!fRunLocalReconstruction.IsNull()) {
-    if (!RunLocalReconstruction(fRunLocalReconstruction)) {
-      if (fStopOnError) {CleanUp(); return kFALSE;}
+    if (m) {
+       AliInfo("Found a TMap in GRP/GRP/Data, converting it into an AliGRPObject");
+       m->Print();
+       fGRPData = new AliGRPObject();
+       fGRPData->ReadValuesFromMap(m);
     }
-  }
-  */
 
-  // get vertexer
-  if (fRunVertexFinder && !CreateVertexer()) {
-    if (fStopOnError) {
-      CleanUp(); 
-      return kFALSE;
+    else {
+       AliInfo("Found an AliGRPObject in GRP/GRP/Data, reading it");
+       fGRPData = dynamic_cast<AliGRPObject*>(entry->GetObject());  // new GRP entry
+       entry->SetOwner(0);
     }
-  }
-   AliSysInfo::AddStamp("Vertexer");
 
-  // get trackers
-  if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
-    if (fStopOnError) {
-      CleanUp(); 
-      return kFALSE;
-    }      
+    //    FIX ME: The unloading of GRP entry is temporarily disabled
+    //    because ZDC and VZERO are using it in order to initialize
+    //    their reconstructor objects. In the future one has to think
+    //    of propagating AliRunInfo to the reconstructors.
+    //    AliCDBManager::Instance()->UnloadFromCache("GRP/GRP/Data");
   }
-   AliSysInfo::AddStamp("LoadTrackers");
 
-  // get the possibly already existing ESD file and tree
-  AliESDEvent* esd = new AliESDEvent(); AliESDEvent* hltesd = new AliESDEvent();
-  TFile* fileOld = NULL;
-  TTree* treeOld = NULL; TTree *hlttreeOld = NULL;
-  if (!gSystem->AccessPathName("AliESDs.root")){
-    gSystem->CopyFile("AliESDs.root", "AliESDs.old.root", kTRUE);
-    fileOld = TFile::Open("AliESDs.old.root");
-    if (fileOld && fileOld->IsOpen()) {
-      treeOld = (TTree*) fileOld->Get("esdTree");
-      if (treeOld)esd->ReadFromTree(treeOld);
-      hlttreeOld = (TTree*) fileOld->Get("HLTesdTree");
-      if (hlttreeOld)  hltesd->ReadFromTree(hlttreeOld);
-    }
+  if (!fGRPData) {
+     AliError("No GRP entry found in OCDB!");
+     return kFALSE;
   }
 
-  // create the ESD output file and tree
-  TFile* file = TFile::Open("AliESDs.root", "RECREATE");
-  file->SetCompressionLevel(2);
-  if (!file->IsOpen()) {
-    AliError("opening AliESDs.root failed");
-    if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}    
-  }
-
-  TTree* tree = new TTree("esdTree", "Tree with ESD objects");
-  esd = new AliESDEvent();
-  esd->CreateStdContent();
-  esd->WriteToTree(tree);
-
-  TTree* hlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
-  hltesd = new AliESDEvent();
-  hltesd->CreateStdContent();
-  hltesd->WriteToTree(hlttree);
-
-  /* CKB Why?
-  delete esd; delete hltesd;
-  esd = NULL; hltesd = NULL;
-  */
-  // create the branch with ESD additions
-
-
+  TString lhcState = fGRPData->GetLHCState();
+  if (lhcState==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the LHC state ! Using UNKNOWN");
+    lhcState = "UNKNOWN";
+  }
 
-  AliESDfriend *esdf = 0; 
-  if (fWriteESDfriend) {
-    esdf = new AliESDfriend();
-    TBranch *br=tree->Branch("ESDfriend.","AliESDfriend", &esdf);
-    br->SetFile("AliESDfriends.root");
-    esd->AddObject(esdf);
+  TString beamType = fGRPData->GetBeamType();
+  if (beamType==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the beam type ! Using UNKNOWN");
+    beamType = "UNKNOWN";
   }
 
-  
-  // Get the GRP CDB entry
-  AliCDBEntry* entryGRP = AliCDBManager::Instance()->Get("GRP/GRP/Data");
-       
-  if(entryGRP) {
-       fGRPList = dynamic_cast<TList*> (entryGRP->GetObject());  
-  } else {
-       AliError("No GRP entry found in OCDB!");
+  Float_t beamEnergy = fGRPData->GetBeamEnergy();
+  if (beamEnergy==AliGRPObject::GetInvalidFloat()) {
+    AliError("GRP/GRP/Data entry:  missing value for the beam energy ! Using 0");
+    beamEnergy = 0;
   }
 
-  // Get the diamond profile from OCDB
-  AliCDBEntry* entry = AliCDBManager::Instance()
-       ->Get("GRP/Calib/MeanVertex");
-       
-  if(entry) {
-       fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
-  } else {
-       AliError("No diamond profile found in OCDB!");
+  TString runType = fGRPData->GetRunType();
+  if (runType==AliGRPObject::GetInvalidString()) {
+    AliError("GRP/GRP/Data entry:  missing value for the run type ! Using UNKNOWN");
+    runType = "UNKNOWN";
   }
 
-  AliVertexerTracks tVertexer(AliTracker::GetBz());
-  if(fDiamondProfile && fMeanVertexConstraint) tVertexer.SetVtxStart(fDiamondProfile);
+  Int_t activeDetectors = fGRPData->GetDetectorMask();
+  if (activeDetectors==AliGRPObject::GetInvalidUInt()) {
+    AliError("GRP/GRP/Data entry:  missing value for the detector mask ! Using 1074790399");
+    activeDetectors = 1074790399;
+  }
 
-  if (fRawReader) fRawReader->RewindEvents();
+  fRunInfo = new AliRunInfo(lhcState, beamType, beamEnergy, runType, activeDetectors);
+  fRunInfo->Dump();
 
-  ProcInfo_t ProcInfo;
-  gSystem->GetProcInfo(&ProcInfo);
-  AliInfo(Form("Current memory usage %d %d", ProcInfo.fMemResident, ProcInfo.fMemVirtual));
-  
 
-  //Initialize the QA and start of cycle for out-of-cycle QA
-  if (fRunQA) {
-     TString detStr(fFillESD); 
-     for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-        if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
-        AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
-        if (!qadm) continue;
-        AliInfo(Form("Initializing the QA data maker for %s", 
-               fgkDetectorName[iDet]));
-        qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
-        qadm->Init(AliQA::kESDS, AliCDBManager::Instance()->GetRun());
-        if (!fInLoopQA) {
-           qadm->StartOfCycle(AliQA::kRECPOINTS);
-           qadm->StartOfCycle(AliQA::kESDS,"same");
-        }
-     }
-     if (fRunGlobalQA) {
-        AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
-       AliInfo(Form("Initializing the global QA data maker"));
-        TObjArray *arr=
-          qadm->Init(AliQA::kRECPOINTS, AliCDBManager::Instance()->GetRun());
-       AliTracker::SetResidualsArray(arr);
-        if (!fInLoopQA) {
-           qadm->StartOfCycle(AliQA::kRECPOINTS);
-        }
-     }
+  // Process the list of active detectors
+  if (activeDetectors) {
+    UInt_t detMask = activeDetectors;
+    fRunLocalReconstruction = MatchDetectorList(fRunLocalReconstruction,detMask);
+    fRunTracking = MatchDetectorList(fRunTracking,detMask);
+    fFillESD = MatchDetectorList(fFillESD,detMask);
+    fQADetectors = MatchDetectorList(fQADetectors,detMask);
+    fLoadCDB.Form("%s %s %s %s",
+                 fRunLocalReconstruction.Data(),
+                 fRunTracking.Data(),
+                 fFillESD.Data(),
+                 fQADetectors.Data());
+    fLoadCDB = MatchDetectorList(fLoadCDB,detMask);
+    if (!((detMask >> AliDAQ::DetectorID("ITSSPD")) & 0x1) &&
+       !((detMask >> AliDAQ::DetectorID("ITSSDD")) & 0x1) &&
+       !((detMask >> AliDAQ::DetectorID("ITSSSD")) & 0x1) ) {
+      // switch off the vertexer
+      AliInfo("SPD,SDD,SSD is not in the list of active detectors. Vertexer and Trackleter are switched off.");
+      fRunVertexFinder = kFALSE;
+      fRunMultFinder = kFALSE;
+    }
+    if (!((detMask >> AliDAQ::DetectorID("TRG")) & 0x1)) {
+      // switch off the reading of CTP raw-data payload
+      if (fFillTriggerESD) {
+       AliInfo("CTP is not in the list of active detectors. CTP data reading switched off.");
+       fFillTriggerESD = kFALSE;
+      }
+    }
   }
 
+  AliInfo("===================================================================================");
+  AliInfo(Form("Running local reconstruction for detectors: %s",fRunLocalReconstruction.Data()));
+  AliInfo(Form("Running tracking for detectors: %s",fRunTracking.Data()));
+  AliInfo(Form("Filling ESD for detectors: %s",fFillESD.Data()));
+  AliInfo(Form("Quality assurance is active for detectors: %s",fQADetectors.Data()));
+  AliInfo(Form("CDB and reconstruction parameters are loaded for detectors: %s",fLoadCDB.Data()));
+  AliInfo("===================================================================================");
 
-  //******* The loop over events
-  for (Int_t iEvent = 0; iEvent < fRunLoader->GetNumberOfEvents(); iEvent++) {
-    if (fRawReader) fRawReader->NextEvent();
-    if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
-      // copy old ESD to the new one
-      if (treeOld) {
-       esd->ReadFromTree(treeOld);
-       treeOld->GetEntry(iEvent);
-      }
-      tree->Fill();
-      if (hlttreeOld) {
-       esd->ReadFromTree(hlttreeOld);
-       hlttreeOld->GetEntry(iEvent);
-      }
-      hlttree->Fill();
-      continue;
+  //*** Dealing with the magnetic field map
+  if ( TGeoGlobalMagField::Instance()->IsLocked() ) {
+    if (TGeoGlobalMagField::Instance()->GetField()->TestBit(AliMagF::kOverrideGRP)) {
+      AliInfo("ExpertMode!!! GRP information will be ignored !");
+      AliInfo("ExpertMode!!! Running with the externally locked B field !");
+    }
+    else {
+      AliInfo("Destroying existing B field instance!");
+      delete TGeoGlobalMagField::Instance();
+    }    
+  }
+  if ( !TGeoGlobalMagField::Instance()->IsLocked() ) {
+    // Construct the field map out of the information retrieved from GRP.
+    Bool_t ok = kTRUE;
+    // L3
+    Float_t l3Current = fGRPData->GetL3Current((AliGRPObject::Stats)0);
+    if (l3Current == AliGRPObject::GetInvalidFloat()) {
+      AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
+      ok = kFALSE;
     }
     
-    AliInfo(Form("processing event %d", iEvent));
-
-    //Start of cycle for the in-loop QA
-    if (fRunQA && fInLoopQA) {
-       TString detStr(fFillESD); 
-       for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-          if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
-          AliQADataMakerRec *qadm = GetQADataMaker(iDet);  
-          if (!qadm) continue;
-          qadm->StartOfCycle(AliQA::kRECPOINTS);
-          qadm->StartOfCycle(AliQA::kESDS, "same") ;   
-       }
-       if (fRunGlobalQA) {
-          AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
-          qadm->StartOfCycle(AliQA::kRECPOINTS);
-       }
+    Char_t l3Polarity = fGRPData->GetL3Polarity();
+    if (l3Polarity == AliGRPObject::GetInvalidChar()) {
+      AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
+      ok = kFALSE;
+    }
+
+    // Dipole
+    Float_t diCurrent = fGRPData->GetDipoleCurrent((AliGRPObject::Stats)0);
+    if (diCurrent == AliGRPObject::GetInvalidFloat()) {
+      AliError("GRP/GRP/Data entry:  missing value for the dipole current !");
+      ok = kFALSE;
+    }
+
+    Char_t diPolarity = fGRPData->GetDipolePolarity();
+    if (diPolarity == AliGRPObject::GetInvalidChar()) {
+      AliError("GRP/GRP/Data entry:  missing value for the dipole polarity !");
+      ok = kFALSE;
+    }
+
+    // read special bits for the polarity convention and map type
+    Int_t  polConvention = fGRPData->IsPolarityConventionLHC() ? AliMagF::kConvLHC : AliMagF::kConvDCS2008;
+    Bool_t uniformB = fGRPData->IsUniformBMap();
+
+    if (ok) { 
+      AliMagF* fld = AliMagF::CreateFieldMap(TMath::Abs(l3Current) * (l3Polarity ? -1:1), 
+                                            TMath::Abs(diCurrent) * (diPolarity ? -1:1), 
+                                            polConvention,uniformB,beamEnergy, beamType.Data());
+      if (fld) {
+       TGeoGlobalMagField::Instance()->SetField( fld );
+       TGeoGlobalMagField::Instance()->Lock();
+       AliInfo("Running with the B field constructed out of GRP !");
+      }
+      else AliFatal("Failed to create a B field map !");
     }
+    else AliFatal("B field is neither set nor constructed from GRP ! Exitig...");
+  }
+  
+  //*** Get the diamond profiles from OCDB
+  entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
+  if (entry) {
+    fDiamondProfileSPD = dynamic_cast<AliESDVertex*> (entry->GetObject());  
+  } else {
+     AliError("No SPD diamond profile found in OCDB!");
+  }
+
+  entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
+  if (entry) {
+    fDiamondProfile = dynamic_cast<AliESDVertex*> (entry->GetObject());  
+  } else {
+     AliError("No diamond profile found in OCDB!");
+  }
+
+  entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexTPC");
+  if (entry) {
+    fDiamondProfileTPC = dynamic_cast<AliESDVertex*> (entry->GetObject());  
+  } else {
+     AliError("No TPC diamond profile found in OCDB!");
+  }
+
+  entry = AliCDBManager::Instance()->Get("GRP/Calib/CosmicTriggers");
+  if (entry) {
+    fListOfCosmicTriggers = dynamic_cast<THashTable*>(entry->GetObject());
+    entry->SetOwner(0);
+    AliCDBManager::Instance()->UnloadFromCache("GRP/Calib/CosmicTriggers");
+  }
+
+  if (!fListOfCosmicTriggers) {
+    AliWarning("Can not get list of cosmic triggers from OCDB! Cosmic event specie will be effectively disabled!");
+  }
+
+  return kTRUE;
+} 
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::LoadCDB()
+{
+  // Load CDB entries for all active detectors.
+  // By default we load all the entries in <det>/Calib
+  // folder.
+
+  AliCodeTimerAuto("",0);
+
+  AliCDBManager::Instance()->Get("GRP/CTP/Config");
+
+  AliCDBManager::Instance()->Get("GRP/Calib/LHCClockPhase");
+
+  TString detStr = fLoadCDB;
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+    AliCDBManager::Instance()->GetAll(Form("%s/Calib/*",fgkDetectorName[iDet]));
+  }
+
+  // Temporary fix - one has to define the correct policy in order
+  // to load the trigger OCDB entries only for the detectors that
+  // in the trigger or that are needed in order to put correct
+  // information in ESD
+  AliCDBManager::Instance()->GetAll("TRIGGER/*/*");
+
+  return kTRUE;
+}
+//_____________________________________________________________________________
+Bool_t AliReconstruction::LoadTriggerScalersCDB()
+{
+  // Load CTP scalers from OCDB.
+  // The scalers are checked for consistency.
+
+  AliCodeTimerAuto("",0);
+
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/Scalers");
+
+  if (entry) { 
+   
+       AliInfo("Found an AliTriggerRunScalers in GRP/CTP/Scalers, reading it");
+       fRunScalers = dynamic_cast<AliTriggerRunScalers*> (entry->GetObject());
+       entry->SetOwner(0);
+       if (fRunScalers->CorrectScalersOverflow() == 0) AliInfo("32bit Trigger counters corrected for overflow");
+
+  }
+  return kTRUE;
+}
+//_____________________________________________________________________________
+Bool_t AliReconstruction::LoadCTPTimeParamsCDB()
+{
+  // Load CTP timing information (alignment)
+  // from OCDB.
+
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/CTP/CTPtiming");
+  if (!entry) return kFALSE;
+
+  AliInfo("Found an AliCTPTimeParams in GRP/CTP/CTPtiming, reading it");
+  fCTPTimeParams = dynamic_cast<AliCTPTimeParams*> (entry->GetObject());
+  entry->SetOwner(0);
+
+  AliCDBEntry* entry2 = AliCDBManager::Instance()->Get("GRP/CTP/TimeAlign");
+  if (!entry2) return kFALSE;
+
+  AliInfo("Found an AliCTPTimeParams in GRP/CTP/TimeAlign, reading it");
+  fCTPTimeAlign = dynamic_cast<AliCTPTimeParams*> (entry2->GetObject());
+  entry2->SetOwner(0);
+
+  return kTRUE;
+}
 
-    fRunLoader->GetEvent(iEvent);
+//_____________________________________________________________________________
+Bool_t AliReconstruction::ReadIntensityInfoCDB()
+{
+  // Load LHC DIP data
+  AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/GRP/LHCData");
+
+  if (entry) { 
+    AliInfo("Found an AliLHCData in GRP/GRP/LHCData, reading it");
+    AliLHCData* dipData = dynamic_cast<AliLHCData*> (entry->GetObject());
+    for (int ib=2;ib--;) {
+      double intI,intNI;
+      if (dipData->GetMeanIntensity(ib,intI,intNI)>=0) {
+       fBeamInt[ib][0] = intI;
+       fBeamInt[ib][1] = intNI;        
+      }
+    }
+    return kTRUE;
+  }
+  return kFALSE;
+}
 
-    char aFileName[256];
-    sprintf(aFileName, "ESD_%d.%d_final.root", 
-           fRunLoader->GetHeader()->GetRun(), 
-           fRunLoader->GetHeader()->GetEventNrInRun());
-    if (!gSystem->AccessPathName(aFileName)) continue;
 
-    // local signle event reconstruction
+//_____________________________________________________________________________
+Bool_t AliReconstruction::Run(const char* input)
+{
+  // Run Run Run
+  AliCodeTimerAuto("",0);
+
+  InitRun(input);
+  if (GetAbort() != TSelector::kContinue) return kFALSE;
+
+  TChain *chain = NULL;
+  if (fRawReader && (chain = fRawReader->GetChain())) {
+    Long64_t nEntries = (fLastEvent < 0) ? (TChain::kBigNumber) : (fLastEvent - fFirstEvent + 1);
+    // Proof mode
+    if (gProof) {
+      // Temporary fix for long raw-data runs (until socket timeout handling in PROOF is revised)
+      gProof->Exec("gEnv->SetValue(\"Proof.SocketActivityTimeout\",-1)", kTRUE);
+
+      if (gGrid)
+       gProof->Exec("TGrid::Connect(\"alien://\")",kTRUE);
+
+      TMessage::EnableSchemaEvolutionForAll(kTRUE);
+      gProof->Exec("TMessage::EnableSchemaEvolutionForAll(kTRUE)",kTRUE);
+
+      gProof->AddInput(this);
+
+      if (!ParseOutput()) return kFALSE;
+
+      gProof->SetParameter("PROOF_MaxSlavesPerNode", 9999);
+      chain->SetProof();
+      chain->Process("AliReconstruction","",nEntries,fFirstEvent);
+    }
+    else {
+      chain->Process(this,"",nEntries,fFirstEvent);
+    }
+  }
+  else {
+    Begin(NULL);
+    if (GetAbort() != TSelector::kContinue) return kFALSE;
+    SlaveBegin(NULL);
+    if (GetAbort() != TSelector::kContinue) return kFALSE;
+    //******* The loop over events
+    AliInfo("Starting looping over events");
+    Int_t iEvent = 0;
+    while ((iEvent < fRunLoader->GetNumberOfEvents()) ||
+          (fRawReader && fRawReader->NextEvent())) {
+      if (!ProcessEvent(iEvent)) {
+        Abort("ProcessEvent",TSelector::kAbortFile);
+        return kFALSE;
+      }
+      iEvent++;
+    }
+    SlaveTerminate();
+    if (GetAbort() != TSelector::kContinue) return kFALSE;
+    Terminate();
+    if (GetAbort() != TSelector::kContinue) return kFALSE;
+  }
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::InitRawReader(const char* input)
+{
+  // Init raw-reader and
+  // set the input in case of raw data
+
+  AliCodeTimerAuto("",0);
+
+  if (input) fRawInput = input;
+  fRawReader = AliRawReader::Create(fRawInput.Data());
+  if (!fRawReader) {
+    if (fRawInput.IsNull()) {
+      AliInfo("Reconstruction will run over digits");
+    }
+    else {
+      AliFatal("Can not create raw-data reader ! Exiting..."); 
+    }
+  }
+
+  if (!fEquipIdMap.IsNull() && fRawReader)
+    fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
+
+  if (!fUseHLTData.IsNull()) {
+    // create the RawReaderHLT which performs redirection of HLT input data for
+    // the specified detectors
+    AliRawReader* pRawReader=AliRawHLTManager::CreateRawReaderHLT(fRawReader, fUseHLTData.Data());
+    if (pRawReader) {
+      fParentRawReader=fRawReader;
+      fRawReader=pRawReader;
+    } else {
+      AliError(Form("can not create Raw Reader for HLT input %s", fUseHLTData.Data()));
+    }
+  }
+  AliSysInfo::AddStamp("CreateRawReader");
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::InitRun(const char* input)
+{
+  // Initialization of raw-reader,
+  // run number, CDB etc.
+  AliCodeTimerAuto("",0);
+  AliSysInfo::AddStamp("Start");
+
+  // Initialize raw-reader if any
+  InitRawReader(input);
+
+  // Initialize the CDB storage
+  InitCDB();
+
+  // Set run number in CDBManager (if it is not already set by the user)
+  if (!SetRunNumberFromData()) {
+    Abort("SetRunNumberFromData", TSelector::kAbortProcess);
+    return;
+  }
+
+  // Set CDB lock: from now on it is forbidden to reset the run number
+  // or the default storage or to activate any further storage!
+  SetCDBLock();
+  
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::Begin(TTree *)
+{
+  // Initialize AlReconstruction before
+  // going into the event loop
+  // Should follow the TSelector convention
+  // i.e. initialize only the object on the client side
+  AliCodeTimerAuto("",0);
+
+  AliReconstruction *reco = NULL;
+  if (fInput) {
+    if ((reco = (AliReconstruction*)fInput->FindObject("AliReconstruction"))) {
+      *this = *reco;
+    }
+    AliSysInfo::AddStamp("ReadInputInBegin");
+  }
+
+  // Import ideal TGeo geometry and apply misalignment
+  if (!gGeoManager) {
+    TString geom(gSystem->DirName(fGAliceFileName));
+    geom += "/geometry.root";
+    AliGeomManager::LoadGeometry(geom.Data());
+    if (!gGeoManager) {
+      Abort("LoadGeometry", TSelector::kAbortProcess);
+      return;
+    }
+    AliSysInfo::AddStamp("LoadGeom");
+    TString detsToCheck=fRunLocalReconstruction;
+    if(!AliGeomManager::CheckSymNamesLUT(detsToCheck.Data())) {
+      Abort("CheckSymNamesLUT", TSelector::kAbortProcess);
+      return;
+    }
+    AliSysInfo::AddStamp("CheckGeom");
+  }
+
+  if (!MisalignGeometry(fLoadAlignData)) {
+    Abort("MisalignGeometry", TSelector::kAbortProcess);
+    return;
+  }
+  AliCDBManager::Instance()->UnloadFromCache("GRP/Geometry/Data");
+  AliSysInfo::AddStamp("MisalignGeom");
+
+  if (!InitGRP()) {
+    Abort("InitGRP", TSelector::kAbortProcess);
+    return;
+  }
+  AliSysInfo::AddStamp("InitGRP");
+
+  if (!LoadCDB()) {
+    Abort("LoadCDB", TSelector::kAbortProcess);
+    return;
+  }
+  AliSysInfo::AddStamp("LoadCDB");
+
+  if (!LoadTriggerScalersCDB()) {
+    Abort("LoadTriggerScalersCDB", TSelector::kAbortProcess);
+    return;
+  }
+  AliSysInfo::AddStamp("LoadTriggerScalersCDB");
+
+  if (!LoadCTPTimeParamsCDB()) {
+    Abort("LoadCTPTimeParamsCDB", TSelector::kAbortProcess);
+    return;
+  }
+  AliSysInfo::AddStamp("LoadCTPTimeParamsCDB");
+
+  if (!ReadIntensityInfoCDB()) {
+    Abort("ReadIntensityInfoCDB", TSelector::kAbortProcess);
+    return;
+  }
+  AliSysInfo::AddStamp("ReadIntensityInfoCDB");
+
+  // Read the reconstruction parameters from OCDB
+  if (!InitRecoParams()) {
+    AliWarning("Not all detectors have correct RecoParam objects initialized");
+  }
+  AliSysInfo::AddStamp("InitRecoParams");
+
+  if (fInput && gProof) {
+    if (reco) *reco = *this;
+
+    gGeoManager->SetName("Geometry");
+    gProof->AddInputData(gGeoManager,kTRUE);
+    gGeoManager = NULL;
+    gProof->AddInputData(const_cast<TMap*>(AliCDBManager::Instance()->GetEntryCache()),kTRUE);
+    fInput->Add(new TParameter<Int_t>("RunNumber",AliCDBManager::Instance()->GetRun()));
+    AliMagF *magFieldMap = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+    magFieldMap->SetName("MagneticFieldMap");
+    gProof->AddInputData(magFieldMap,kTRUE);
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::SlaveBegin(TTree*)
+{
+  // Initialization related to run-loader,
+  // vertexer, trackers, recontructors
+  // In proof mode it is executed on the slave
+  AliCodeTimerAuto("",0);
+
+  TProofOutputFile *outProofFile = NULL;
+  if (fInput) {
+    if (AliDebugLevel() > 0) fInput->Print();
+    if (AliDebugLevel() > 10) fInput->Dump();
+    if (AliReconstruction *reco = (AliReconstruction*)fInput->FindObject("AliReconstruction")) {
+      *this = *reco;
+    }
+    if (TGeoManager *tgeo = (TGeoManager*)fInput->FindObject("Geometry")) {
+      gGeoManager = tgeo;
+      AliGeomManager::SetGeometry(tgeo);
+    }
+    if (TMap *entryCache = (TMap*)fInput->FindObject("CDBEntryCache")) {
+      Int_t runNumber = -1;
+      if (TProof::GetParameter(fInput,"RunNumber",runNumber) == 0) {
+       AliCDBManager *man = AliCDBManager::Instance(entryCache,runNumber);
+       man->SetCacheFlag(kTRUE);
+       man->SetLock(kTRUE);
+       man->Print();
+      }
+    }
+    if (AliMagF *map = (AliMagF*)fInput->FindObject("MagneticFieldMap")) {
+      AliMagF *newMap = new AliMagF(*map);
+      if (!newMap->LoadParameterization()) {
+       Abort("AliMagF::LoadParameterization", TSelector::kAbortProcess);
+       return;
+      }
+      TGeoGlobalMagField::Instance()->SetField(newMap);
+      TGeoGlobalMagField::Instance()->Lock();
+    }
+    if (TNamed *outputFileName = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE"))
+      fProofOutputFileName = outputFileName->GetTitle();
+    if (TNamed *outputLocation = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_LOCATION"))
+      fProofOutputLocation = outputLocation->GetTitle();
+    if (fInput->FindObject("PROOF_OUTPUTFILE_DATASET"))
+      fProofOutputDataset = kTRUE;
+    if (TNamed *archiveList = (TNamed*)fInput->FindObject("PROOF_OUTPUTFILE_ARCHIVE"))
+      fProofOutputArchive = archiveList->GetTitle();
+    if (!fProofOutputFileName.IsNull() &&
+       !fProofOutputLocation.IsNull() &&
+       fProofOutputArchive.IsNull()) {
+      if (!fProofOutputDataset) {
+       outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"M");
+       outProofFile->SetOutputFileName(Form("%s%s",fProofOutputLocation.Data(),fProofOutputFileName.Data()));
+      }
+      else {
+       outProofFile = new TProofOutputFile(fProofOutputFileName.Data(),"DROV",fProofOutputLocation.Data());
+      }
+      if (AliDebugLevel() > 0) outProofFile->Dump();
+      fOutput->Add(outProofFile);
+    }
+    AliSysInfo::AddStamp("ReadInputInSlaveBegin");
+  }
+
+  // get the run loader
+  if (!InitRunLoader()) {
+    Abort("InitRunLoader", TSelector::kAbortProcess);
+    return;
+  }
+  AliSysInfo::AddStamp("LoadLoader");
+  ftVertexer = new AliVertexerTracks(AliTracker::GetBz());
+
+  // get trackers
+  if (!fRunTracking.IsNull() && !CreateTrackers(fRunTracking)) {
+    Abort("CreateTrackers", TSelector::kAbortProcess);
+    return;
+  }      
+  AliSysInfo::AddStamp("CreateTrackers");
+
+  // create the ESD output file and tree
+  if (!outProofFile) {
+    ffile = TFile::Open("AliESDs.root", "RECREATE");
+    ffile->SetCompressionLevel(2);
+    if (!ffile->IsOpen()) {
+      Abort("OpenESDFile", TSelector::kAbortProcess);
+      return;
+    }
+  }
+  else {
+    AliInfo(Form("Opening output PROOF file: %s/%s",
+                outProofFile->GetDir(), outProofFile->GetFileName()));
+    if (!(ffile = outProofFile->OpenFile("RECREATE"))) {
+      Abort(Form("Problems opening output PROOF file: %s/%s",
+                outProofFile->GetDir(), outProofFile->GetFileName()),
+           TSelector::kAbortProcess);
+      return;
+    }
+  }
+
+  ftree = new TTree("esdTree", "Tree with ESD objects");
+  fesd = new AliESDEvent();
+  fesd->CreateStdContent();
+  // add a so far non-std object to the ESD, this will
+  // become part of the std content
+  fesd->AddObject(new AliESDHLTDecision);
+
+  fesd->WriteToTree(ftree);
+  if (fWriteESDfriend) {
+    ffileF = TFile::Open("AliESDfriends.root", "RECREATE");
+    ftreeF = new TTree("esdFriendTree", "Tree with ESD Friend objects");
+    fesdf  = new AliESDfriend();
+    ftreeF->Branch("ESDfriend.","AliESDfriend", &fesdf);
+    fesd->AddObject(fesdf);
+    ffile->cd();
+  }
+  ftree->GetUserInfo()->Add(fesd);
+
+  fhlttree = new TTree("HLTesdTree", "Tree with HLT ESD objects");
+  fhltesd = new AliESDEvent();
+  fhltesd->CreateStdContent();
+  // read the ESD template from CDB
+  // HLT is allowed to put non-std content to its ESD, the non-std
+  // objects need to be created before invocation of WriteToTree in
+  // order to create all branches. Initialization is done from an
+  // ESD layout template in CDB
+  AliCDBManager* man = AliCDBManager::Instance();
+  AliCDBPath hltESDConfigPath("HLT/ConfigHLT/esdLayout");
+  AliCDBEntry* hltESDConfig=NULL;
+  if (man->GetId(hltESDConfigPath)!=NULL &&
+      (hltESDConfig=man->Get(hltESDConfigPath))!=NULL) {
+    AliESDEvent* pESDLayout=dynamic_cast<AliESDEvent*>(hltESDConfig->GetObject());
+    if (pESDLayout) {
+      // init all internal variables from the list of objects
+      pESDLayout->GetStdContent();
+
+      // copy content and create non-std objects
+      *fhltesd=*pESDLayout;
+      fhltesd->Reset();
+    } else {
+      AliError(Form("error setting hltEsd layout from %s: invalid object type",
+                   hltESDConfigPath.GetPath().Data()));
+    }
+  }
+
+  fhltesd->WriteToTree(fhlttree);
+  fhlttree->GetUserInfo()->Add(fhltesd);
+
+  ProcInfo_t procInfo;
+  gSystem->GetProcInfo(&procInfo);
+  AliInfo(Form("Current memory usage %ld %ld", procInfo.fMemResident, procInfo.fMemVirtual));
+  
+  //QA
+  //Initialize the QA and start of cycle 
+  if (fRunQA || fRunGlobalQA) 
+    InitQA() ; 
+
+  //Initialize the Plane Efficiency framework
+  if (fRunPlaneEff && !InitPlaneEff()) {
+    Abort("InitPlaneEff", TSelector::kAbortProcess);
+    return;
+  }
+
+  if (strcmp(gProgName,"alieve") == 0)
+    fRunAliEVE = InitAliEVE();
+
+  return;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::Process(Long64_t entry)
+{
+  // run the reconstruction over a single entry
+  // from the chain with raw data
+  AliCodeTimerAuto("",0);
+
+  TTree *currTree = fChain->GetTree();
+  AliRawVEvent *event = NULL;
+  currTree->SetBranchAddress("rawevent",&event);
+  currTree->GetEntry(entry);
+  fRawReader = new AliRawReaderRoot(event);
+  fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
+  delete fRawReader;
+  fRawReader = NULL;
+  delete event;
+
+  return fStatus;
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::Init(TTree *tree)
+{
+  // Implementation of TSelector::Init()
+  // method
+  if (tree == 0) {
+    AliError("The input tree is not found!");
+    return;
+  }
+  fChain = tree;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::ProcessEvent(Int_t iEvent)
+{
+  // run the reconstruction over a single event
+  // The event loop is steered in Run method
+
+
+  static Long_t oldMres=0;
+  static Long_t oldMvir=0;
+  static Float_t oldCPU=0;
+  static Long_t aveDMres=0;
+  static Long_t aveDMvir=0;
+  static Float_t aveDCPU=0;
+
+  AliCodeTimerAuto("",0);
+
+  AliESDpid pid;
+
+  if (iEvent >= fRunLoader->GetNumberOfEvents()) {
+    fRunLoader->SetEventNumber(iEvent);
+    fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
+                                  iEvent, iEvent);
+    fRunLoader->TreeE()->Fill();
+    if (fRawReader && fRawReader->UseAutoSaveESD())
+      fRunLoader->TreeE()->AutoSave("SaveSelf");
+  }
+
+  if ((iEvent < fFirstEvent) || ((fLastEvent >= 0) && (iEvent > fLastEvent))) {
+    return kTRUE;
+  }
+
+
+  fRunLoader->GetEvent(iEvent);
+
+  // Fill Event-info object
+  GetEventInfo();
+  fRecoParam.SetEventSpecie(fRunInfo,fEventInfo,fListOfCosmicTriggers);
+  
+  ProcInfo_t procInfo;
+  if(iEvent==fFirstEvent) {
+    gSystem->GetProcInfo(&procInfo);
+    oldMres=procInfo.fMemResident;
+    oldMvir=procInfo.fMemVirtual;
+    oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
+  }
+  AliInfo(Form("================================= Processing event %d of type %-10s ==================================", iEvent,fRecoParam.PrintEventSpecie()));
+
+  // Set the reco-params
+  {
+    TString detStr = fLoadCDB;
+    for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+      if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+      AliReconstructor *reconstructor = GetReconstructor(iDet);
+      if (reconstructor && fRecoParam.GetDetRecoParamArray(iDet)) {
+        const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
+        reconstructor->SetRecoParam(par);
+       reconstructor->GetPidSettings(&pid);
+       reconstructor->SetEventInfo(&fEventInfo);
+        if (fRunQA) {
+          AliQAManager::QAManager()->SetRecoParam(iDet, par) ; 
+          if (par) AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(par->GetEventSpecie())) ;
+        }
+      }
+    }
+    if (fRunQA) {
+      const AliDetectorRecoParam *grppar = fRecoParam.GetDetRecoParam(kNDetectors);
+      AliQAManager::QAManager()->SetRecoParam(AliQAv1::kGLOBAL, grppar) ; 
+      AliQAManager::QAManager()->SetEventSpecie(AliRecoParam::Convert(grppar->GetEventSpecie())) ;
+    }
+  }
+
+    // QA on single raw 
+  if (fRunQA && IsInTasks(AliQAv1::kRAWS)) {
+    AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
+    AliQAManager::QAManager()->RunOneEvent(fRawReader) ;  
+  }
+    // local single event reconstruction
     if (!fRunLocalReconstruction.IsNull()) {
-      if (!RunLocalEventReconstruction(fRunLocalReconstruction)) {
-       if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
+      TString detectors=fRunLocalReconstruction;
+      // run HLT event reconstruction first
+      // ;-( IsSelected changes the string
+      if (IsSelected("HLT", detectors) &&
+         !RunLocalEventReconstruction("HLT")) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
+      }
+      detectors=fRunLocalReconstruction;
+      detectors.ReplaceAll("HLT", "");
+      if (!RunLocalEventReconstruction(detectors)) {
+        if (fStopOnError) {
+          CleanUp(); 
+          return kFALSE;
+        }
       }
     }
 
-    esd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
-    hltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
-    esd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
-    hltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
+  
+    // fill Event header information from the RawEventHeader
+    if (fRawReader){FillRawEventHeaderESD(fesd);}
+    if (fRawReader){FillRawEventHeaderESD(fhltesd);}
+
+    fesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
+    fhltesd->SetRunNumber(fRunLoader->GetHeader()->GetRun());
     
-    // Set magnetic field from the tracker
-    esd->SetMagneticField(AliTracker::GetBz());
-    hltesd->SetMagneticField(AliTracker::GetBz());
+    ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
+    ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInDAQ(fRunInfo->GetDetectorMask());
+    ((AliESDRun*)fesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
+    ((AliESDRun*)fhltesd->GetESDRun())->SetDetectorsInReco(AliDAQ::DetectorPatternOffline(fFillESD.Data()));
 
+    fesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
+    fhltesd->SetEventNumberInFile(fRunLoader->GetHeader()->GetEventNrInRun());
+
+    fesd->SetEventSpecie(fRecoParam.GetEventSpecie());
+    fhltesd->SetEventSpecie(fRecoParam.GetEventSpecie());
     
+    // Set magnetic field from the tracker
+    fesd->SetMagneticField(AliTracker::GetBz());
+    fhltesd->SetMagneticField(AliTracker::GetBz());
+    //
+    AliESDRun *esdRun,*esdRunH;
+    esdRun  = (AliESDRun*)fesd->GetESDRun();
+    esdRunH = (AliESDRun*)fhltesd->GetESDRun();
+    esdRun->SetBeamEnergyIsSqrtSHalfGeV();
+    esdRunH->SetBeamEnergyIsSqrtSHalfGeV();
+    //
+    for (int ib=2;ib--;) for (int it=2;it--;) {
+       esdRun->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
+       esdRunH->SetMeanIntensity(ib,it, fBeamInt[ib][it]); 
+      }
+    //
+    AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+    if (fld) { // set info needed for field initialization
+      fesd->SetCurrentL3(fld->GetCurrentSol());
+      fesd->SetCurrentDip(fld->GetCurrentDip());
+      fesd->SetBeamEnergy(fld->GetBeamEnergy());
+      fesd->SetBeamType(fld->GetBeamTypeText());
+      fesd->SetUniformBMap(fld->IsUniform());
+      fesd->SetBInfoStored();
+      //
+      fhltesd->SetCurrentL3(fld->GetCurrentSol());
+      fhltesd->SetCurrentDip(fld->GetCurrentDip());
+      fhltesd->SetBeamEnergy(fld->GetBeamEnergy());
+      fhltesd->SetBeamType(fld->GetBeamTypeText());
+      fhltesd->SetUniformBMap(fld->IsUniform());
+      fhltesd->SetBInfoStored();
+    }
+    //
+    // Set most probable pt, for B=0 tracking
+    // Get the global reco-params. They are atposition 16 inside the array of detectors in fRecoParam
+    const AliGRPRecoParam *grpRecoParam = dynamic_cast<const AliGRPRecoParam*>(fRecoParam.GetDetRecoParam(kNDetectors));
+    if (grpRecoParam) AliExternalTrackParam::SetMostProbablePt(grpRecoParam->GetMostProbablePt());
     
     // Fill raw-data error log into the ESD
-    if (fRawReader) FillRawDataErrorLog(iEvent,esd);
+    if (fRawReader) FillRawDataErrorLog(iEvent,fesd);
 
     // vertex finder
     if (fRunVertexFinder) {
-      if (!ReadESD(esd, "vertex")) {
-       if (!RunVertexFinder(esd)) {
-         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
-       }
-       if (fCheckPointLevel > 0) WriteESD(esd, "vertex");
+      if (!RunVertexFinder(fesd)) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
       }
     }
 
-    // HLT tracking
-    if (!fRunTracking.IsNull()) {
-      if (fRunHLTTracking) {
-       hltesd->SetVertex(esd->GetVertex());
-       if (!RunHLTTracking(hltesd)) {
-         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
-       }
+    // For Plane Efficiency: run the SPD trackleter
+    if (fRunPlaneEff && fSPDTrackleter) {
+      if (!RunSPDTrackleting(fesd)) {
+        if (fStopOnError) {CleanUp(); return kFALSE;}
       }
     }
 
     // Muon tracking
     if (!fRunTracking.IsNull()) {
       if (fRunMuonTracking) {
-       if (!RunMuonTracking(esd)) {
-         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
+       if (!RunMuonTracking(fesd)) {
+         if (fStopOnError) {CleanUp(); return kFALSE;}
        }
       }
     }
 
     // barrel tracking
     if (!fRunTracking.IsNull()) {
-      if (!ReadESD(esd, "tracking")) {
-       if (!RunTracking(esd)) {
-         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
-       }
-       if (fCheckPointLevel > 0) WriteESD(esd, "tracking");
+      if (!RunTracking(fesd,pid)) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
       }
     }
 
     // fill ESD
     if (!fFillESD.IsNull()) {
-      if (!FillESD(esd, fFillESD)) {
-       if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
+      TString detectors=fFillESD;
+      // run HLT first and on hltesd
+      // ;-( IsSelected changes the string
+      if (IsSelected("HLT", detectors) &&
+         !FillESD(fhltesd, "HLT")) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
+      }
+      detectors=fFillESD;
+      // Temporary fix to avoid problems with HLT that overwrites the offline ESDs
+      if (detectors.Contains("ALL")) {
+       detectors="";
+       for (Int_t idet=0; idet<kNDetectors; ++idet){
+         detectors += fgkDetectorName[idet];
+         detectors += " ";
+       }
+      }
+      detectors.ReplaceAll("HLT", "");
+      if (!FillESD(fesd, detectors)) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
       }
     }
-  
-    // fill Event header information from the RawEventHeader
-    if (fRawReader){FillRawEventHeaderESD(esd);}
+
+    // AdC+FN
+    GetReconstructor(3)->FillEventTimeWithTOF(fesd,&pid);
 
     // combined PID
-    AliESDpid::MakePID(esd);
-    if (fCheckPointLevel > 1) WriteESD(esd, "PID");
+    pid.MakePID(fesd);
 
     if (fFillTriggerESD) {
-      if (!ReadESD(esd, "trigger")) {
-       if (!FillTriggerESD(esd)) {
-         if (fStopOnError) {CleanUp(file, fileOld); return kFALSE;}
-       }
-       if (fCheckPointLevel > 1) WriteESD(esd, "trigger");
+      if (!FillTriggerESD(fesd)) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
       }
     }
+    // Always fill scalers
+    if (!FillTriggerScalers(fesd)) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
+    }
+    
+
+    ffile->cd();
+
+    //
+    // Propagate track to the beam pipe  (if not already done by ITS)
+    //
+    const Int_t ntracks = fesd->GetNumberOfTracks();
+    const Double_t kRadius  = 2.8; //something less than the beam pipe radius
+
+    TObjArray trkArray;
+    UShort_t *selectedIdx=new UShort_t[ntracks];
+
+    for (Int_t itrack=0; itrack<ntracks; itrack++){
+      const Double_t kMaxStep = 1;   //max step over the material
+      Bool_t ok;
+
+      AliESDtrack *track = fesd->GetTrack(itrack);
+      if (!track) continue;
+
+      AliExternalTrackParam *tpcTrack =
+           (AliExternalTrackParam *)track->GetTPCInnerParam();
+      ok = kFALSE;
+      if (tpcTrack)
+       ok = AliTracker::
+         PropagateTrackToBxByBz(tpcTrack,kRadius,track->GetMass(),kMaxStep,kFALSE);
+
+      if (ok) {
+       Int_t n=trkArray.GetEntriesFast();
+        selectedIdx[n]=track->GetID();
+        trkArray.AddLast(tpcTrack);
+      }
+
+      //Tracks refitted by ITS should already be at the SPD vertex
+      if (track->IsOn(AliESDtrack::kITSrefit)) continue;
 
-    file->cd();
+      AliTracker::
+         PropagateTrackToBxByBz(track,kRadius,track->GetMass(),kMaxStep,kFALSE);
+      Double_t x[3]; track->GetXYZ(x);
+      Double_t b[3]; AliTracker::GetBxByBz(x,b);
+      track->RelateToVertexBxByBz(fesd->GetPrimaryVertexSPD(), b, kVeryBig);
 
-    //Try to improve the reconstructed primary vertex position using the tracks
-    AliESDVertex *pvtx=0;
-    Bool_t dovertex=kTRUE;
-    TObject* obj = fOptions.FindObject("ITS");
-    if (obj) {
-      TString optITS = obj->GetTitle();
-      if (optITS.Contains("cosmics") || optITS.Contains("COSMICS")) 
-       dovertex=kFALSE;
     }
-    if(dovertex) pvtx=tVertexer.FindPrimaryVertex(esd);
-    if(fDiamondProfile) esd->SetDiamond(fDiamondProfile);
-    
-    if (pvtx)
-    if (pvtx->GetStatus()) {
-       // Store the improved primary vertex
-       esd->SetPrimaryVertex(pvtx);
-       // Propagate the tracks to the DCA to the improved primary vertex
-       Double_t somethingbig = 777.;
-       Double_t bz = esd->GetMagneticField();
-       Int_t nt=esd->GetNumberOfTracks();
-       while (nt--) {
-        AliESDtrack *t = esd->GetTrack(nt);
-         t->RelateToVertex(pvtx, bz, somethingbig);
-       } 
+
+    //
+    // Improve the reconstructed primary vertex position using the tracks
+    //
+    Bool_t runVertexFinderTracks = fRunVertexFinderTracks;
+    if(fesd->GetPrimaryVertexSPD()) {
+      TString vtitle = fesd->GetPrimaryVertexSPD()->GetTitle();
+      if(vtitle.Contains("cosmics")) {
+       runVertexFinderTracks=kFALSE;
+      }
+    }
+
+    if (runVertexFinderTracks) {
+       // TPC + ITS primary vertex
+       ftVertexer->SetITSMode();
+       ftVertexer->SetConstraintOff();
+       // get cuts for vertexer from AliGRPRecoParam
+       Bool_t constrSPD=kFALSE;
+       if (grpRecoParam) {
+        Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
+        Double_t *cutsVertexer = new Double_t[nCutsVertexer];
+        grpRecoParam->GetVertexerTracksCutsITS(cutsVertexer);
+        ftVertexer->SetCuts(cutsVertexer);
+        delete [] cutsVertexer; cutsVertexer = NULL; 
+        if(grpRecoParam->GetVertexerTracksConstraintITS()) { 
+          if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius){
+            ftVertexer->SetVtxStart(fDiamondProfile); // apply constraint only if sigmax is smaller than the beam pipe radius 
+          }else{
+            if(fDiamondProfileSPD && fDiamondProfileSPD->GetXRes()<kRadius){
+              ftVertexer->SetVtxStart(fDiamondProfileSPD);
+              constrSPD=kTRUE;
+            }
+          }
+        } 
+       }
+       AliESDVertex *pvtx=ftVertexer->FindPrimaryVertex(fesd);
+       if (pvtx) {
+        if(constrSPD){
+          TString title=pvtx->GetTitle();
+          title.Append("SPD");
+          pvtx->SetTitle(title);
+        }
+          if (pvtx->GetStatus()) {
+             fesd->SetPrimaryVertexTracks(pvtx);
+             for (Int_t i=0; i<ntracks; i++) {
+                AliESDtrack *t = fesd->GetTrack(i);
+                 Double_t x[3]; t->GetXYZ(x);
+                 Double_t b[3]; AliTracker::GetBxByBz(x,b);
+                 t->RelateToVertexBxByBz(pvtx, b, kVeryBig);
+             } 
+          }
+         delete pvtx; pvtx=NULL;
+       }
+
+       // TPC-only primary vertex
+       ftVertexer->SetTPCMode();
+       ftVertexer->SetConstraintOff();
+       // get cuts for vertexer from AliGRPRecoParam
+       if (grpRecoParam) {
+        Int_t nCutsVertexer = grpRecoParam->GetVertexerTracksNCuts();
+        Double_t *cutsVertexer = new Double_t[nCutsVertexer];
+        grpRecoParam->GetVertexerTracksCutsTPC(cutsVertexer);
+        ftVertexer->SetCuts(cutsVertexer);
+        delete [] cutsVertexer; cutsVertexer = NULL; 
+        if(fDiamondProfileTPC && grpRecoParam->GetVertexerTracksConstraintTPC()) { 
+          if(fDiamondProfileTPC->GetXRes()<kRadius) ftVertexer->SetVtxStart(fDiamondProfileTPC); // apply constraint only if sigmax is smaller than the beam pipe radius 
+        } 
+       }
+       pvtx=ftVertexer->FindPrimaryVertex(&trkArray,selectedIdx);
+       if (pvtx) {
+          if (pvtx->GetStatus()) {
+             fesd->SetPrimaryVertexTPC(pvtx);
+             for (Int_t i=0; i<ntracks; i++) {
+                AliESDtrack *t = fesd->GetTrack(i);
+                 Double_t x[3]; t->GetXYZ(x);
+                 Double_t b[3]; AliTracker::GetBxByBz(x,b);
+                 t->RelateToVertexTPCBxByBz(pvtx, b, kVeryBig);
+             } 
+          }
+         delete pvtx; pvtx=NULL;
+       }
+
     }
+    delete[] selectedIdx;
+
+    if(fDiamondProfile && fDiamondProfile->GetXRes()<kRadius) fesd->SetDiamond(fDiamondProfile);
+    else fesd->SetDiamond(fDiamondProfileSPD);
 
     if (fRunV0Finder) {
        // V0 finding
        AliV0vertexer vtxer;
-       vtxer.Tracks2V0vertices(esd);
+       vtxer.Tracks2V0vertices(fesd);
 
        if (fRunCascadeFinder) {
           // Cascade finding
           AliCascadeVertexer cvtxer;
-          cvtxer.V0sTracks2CascadeVertices(esd);
+          cvtxer.V0sTracks2CascadeVertices(fesd);
        }
     }
+
     // write ESD
-    if (fCleanESD) CleanESD(esd);
+    if (fCleanESD) CleanESD(fesd);
+    // 
+    // RS run updated trackleter: since we want to mark the clusters used by tracks and also mark the 
+    // tracks interpreted as primary, this step should be done in the very end, when full 
+    // ESD info is available (particulalry, V0s)
+    // vertex finder
+    if (fRunMultFinder) {
+      if (!RunMultFinder(fesd)) {
+       if (fStopOnError) {CleanUp(); return kFALSE;}
+      }
+    }
+
+  if (fRunQA && IsInTasks(AliQAv1::kESDS)) {
+    AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
+    AliQAManager::QAManager()->RunOneEvent(fesd, fhltesd) ; 
+  }
+  if (fRunGlobalQA) {
+    AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
+      qadm->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
+    if (qadm && IsInTasks(AliQAv1::kESDS))
+      qadm->Exec(AliQAv1::kESDS, fesd);
+  }
+
+  // copy HLT decision from HLTesd to esd
+  // the most relevant information is stored in a reduced container in the esd,
+  // while the full information can be found in the HLTesd
+  TObject* pHLTSrc=fhltesd->FindListObject(AliESDHLTDecision::Name());
+  TObject* pHLTTgt=fesd->FindListObject(AliESDHLTDecision::Name());
+  if (pHLTSrc && pHLTTgt) {
+    pHLTSrc->Copy(*pHLTTgt);
+  }
+
+    if (fWriteESDfriend) 
+      fesd->GetESDfriend(fesdf);
+
+    ftree->Fill();
     if (fWriteESDfriend) {
-      esdf->~AliESDfriend();
-      new (esdf) AliESDfriend(); // Reset...
-      esd->GetESDfriend(esdf);
+      WriteESDfriend();
+    }
+
+    // Auto-save the ESD tree in case of prompt reco @P2
+    if (fRawReader && fRawReader->UseAutoSaveESD()) {
+      ftree->AutoSave("SaveSelf");
+      if (fWriteESDfriend) ftreeF->AutoSave("SaveSelf");
+      TFile *friendfile = (TFile *)(gROOT->GetListOfFiles()->FindObject("AliESDfriends.root"));
+      if (friendfile) friendfile->Save();
     }
-    tree->Fill();
 
     // write HLT ESD
-    hlttree->Fill();
+    fhlttree->Fill();
 
-    if (fCheckPointLevel > 0)  WriteESD(esd, "final"); 
-    esd->Reset();
-    hltesd->Reset();
+    // call AliEVE
+    if (fRunAliEVE) RunAliEVE();
+
+    fesd->Reset();
+    fhltesd->Reset();
     if (fWriteESDfriend) {
-      esdf->~AliESDfriend();
-      new (esdf) AliESDfriend(); // Reset...
+      fesdf->~AliESDfriend();
+      new (fesdf) AliESDfriend(); // Reset...
     }
  
-    gSystem->GetProcInfo(&ProcInfo);
-    AliInfo(Form("Event %d -> Current memory usage %d %d",iEvent, ProcInfo.fMemResident, ProcInfo.fMemVirtual));
+    gSystem->GetProcInfo(&procInfo);
+    Long_t dMres=(procInfo.fMemResident-oldMres)/1024;
+    Long_t dMvir=(procInfo.fMemVirtual-oldMvir)/1024;
+    Float_t dCPU=procInfo.fCpuUser+procInfo.fCpuSys-oldCPU;
+    aveDMres+=(dMres-aveDMres)/(iEvent-fFirstEvent+1);
+    aveDMvir+=(dMvir-aveDMvir)/(iEvent-fFirstEvent+1);
+    aveDCPU+=(dCPU-aveDCPU)/(iEvent-fFirstEvent+1);
+    AliInfo(Form("======================= End Event %d: Res %ld(%3ld <%3ld>) Vir %ld(%3ld <%3ld>) CPU %5.2f <%5.2f> ===================",
+                iEvent, procInfo.fMemResident/1024, dMres, aveDMres, procInfo.fMemVirtual/1024, dMvir, aveDMvir, dCPU, aveDCPU));
+    oldMres=procInfo.fMemResident;
+    oldMvir=procInfo.fMemVirtual;
+    oldCPU=procInfo.fCpuUser+procInfo.fCpuSys;
   
+    fEventInfo.Reset();
+    for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+      if (fReconstructor[iDet]) {
+       fReconstructor[iDet]->SetRecoParam(NULL);
+       fReconstructor[iDet]->SetEventInfo(NULL);
+      }
+      if (fTracker[iDet]) fTracker[iDet]->SetEventInfo(NULL);
+    }
+       
+  if (fRunQA || fRunGlobalQA) 
+    AliQAManager::QAManager()->Increment() ; 
+  
+    return kTRUE;
+}
 
-  // End of cycle for the in-loop QA
-     if (fRunQA && fInLoopQA) {
-        RunQA(fFillESD.Data(), esd);
-        TString detStr(fFillESD); 
-        for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-          if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
-          AliQADataMakerRec * qadm = GetQADataMaker(iDet);
-          if (!qadm) continue;
-          qadm->EndOfCycle(AliQA::kRECPOINTS);
-          qadm->EndOfCycle(AliQA::kESDS);
-          qadm->Finish();
-        }
-        if (fRunGlobalQA) {
-           AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
-           if (qadm) {
-             qadm->EndOfCycle(AliQA::kRECPOINTS);
-             qadm->Finish();
-          }
-        }
-     }
-  } 
-  //******** End of the loop over events 
-
+//_____________________________________________________________________________
+void AliReconstruction::SlaveTerminate()
+{
+  // Finalize the run on the slave side
+  // Called after the exit
+  // from the event loop
+  AliCodeTimerAuto("",0);
 
+  if (fIsNewRunLoader) { // galice.root didn't exist
+    fRunLoader->WriteHeader("OVERWRITE");
+    fRunLoader->CdGAFile();
+    fRunLoader->Write(0, TObject::kOverwrite);
+  }
 
-  tree->GetUserInfo()->Add(esd);
-  hlttree->GetUserInfo()->Add(hltesd);
-  
   const TMap *cdbMap = AliCDBManager::Instance()->GetStorageMap();      
   const TList *cdbList = AliCDBManager::Instance()->GetRetrievedIds();  
                 
@@ -1021,125 +2171,97 @@ Bool_t AliReconstruction::Run(const char* input, Bool_t IsOnline)
         
    TIter iter2(cdbList);        
         
-   AliCDBId* id=0;      
-   while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){        
+       AliCDBId* id=0;
+       while((id = dynamic_cast<AliCDBId*> (iter2.Next()))){    
          cdbListCopy->Add(new TObjString(id->ToString().Data()));       
    }    
         
-   tree->GetUserInfo()->Add(cdbMapCopy);        
-   tree->GetUserInfo()->Add(cdbListCopy);
-
-
-  if(fESDPar.Contains("ESD.par")){
-    AliInfo("Attaching ESD.par to Tree");
-    TNamed *fn = CopyFileToTNamed(fESDPar.Data(),"ESD.par");
-    tree->GetUserInfo()->Add(fn);
-  }
+   ftree->GetUserInfo()->Add(cdbMapCopy);       
+   ftree->GetUserInfo()->Add(cdbListCopy);
 
 
-  file->cd();
+  ffile->cd();
 
-  if (fWriteESDfriend)
-    tree->SetBranchStatus("ESDfriend*",0);
   // we want to have only one tree version number
-  tree->Write(tree->GetName(),TObject::kOverwrite);
-  hlttree->Write();
+  ftree->Write(ftree->GetName(),TObject::kOverwrite);
+  fhlttree->Write(fhlttree->GetName(),TObject::kOverwrite);
 
-  if (fWriteAOD) {
-    TFile *aodFile = TFile::Open("AliAOD.root", "RECREATE");
-    ESDFile2AODFile(file, aodFile);
-    aodFile->Close();
+  if (fWriteESDfriend) {
+    ffileF->cd();
+    ftreeF->Write(ftreeF->GetName(),TObject::kOverwrite);
   }
 
-  gROOT->cd();
-  CleanUp(file, fileOld);
-    
-  // Create tags for the events in the ESD tree (the ESD tree is always present)
-  // In case of empty events the tags will contain dummy values
-  AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
-  esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPList);
-  if (fWriteAOD) {
-    AliAODTagCreator *aodtagCreator = new AliAODTagCreator();
-    aodtagCreator->CreateAODTags(fFirstEvent,fLastEvent,fGRPList);
-  }
-
-  //Finish QA and end of cycle for out-of-loop QA
-  if (fRunQA && !fInLoopQA) {
-     qas.Run(fRunLocalReconstruction.Data(), AliQA::kRECPOINTS);
-     //qas.Reset() ;
-     qas.Run(fRunTracking.Data(), AliQA::kESDS);
-
-     if (fRunGlobalQA) {
-        AliQADataMakerRec *qadm = GetQADataMaker(fgkNDetectors);
-        if (qadm) {
-          qadm->EndOfCycle(AliQA::kRECPOINTS);
-          qadm->Finish();
-       }
-     }
+// Finish with Plane Efficiency evaluation: before of CleanUp !!!
+  if (fRunPlaneEff && !FinishPlaneEff()) {
+   AliWarning("Finish PlaneEff evaluation failed");
   }
-  
-  // Cleanup of CDB manager: cache and active storages!
-  AliCDBManager::Instance()->ClearCache();
-  
-  
-  return kTRUE;
-}
-
 
-//_____________________________________________________________________________
-Bool_t AliReconstruction::RunLocalReconstruction(const TString& /*detectors*/)
-{
-// run the local reconstruction
-  static Int_t eventNr=0;
-  AliCodeTimerAuto("")
+  // End of cycle for the in-loop  
 
- //  AliCDBManager* man = AliCDBManager::Instance();
-//   Bool_t origCache = man->GetCacheFlag();
+  if (fRunQA || fRunGlobalQA) {
+    AliQAManager::QAManager()->EndOfCycle() ;
+    if (fInput &&
+       !fProofOutputLocation.IsNull() &&
+       fProofOutputArchive.IsNull() &&
+       !fProofOutputDataset) {
+      TString qaOutputFile(Form("%sMerged.%s.Data.root",
+                               fProofOutputLocation.Data(),
+                               AliQAv1::GetQADataFileName()));
+      TProofOutputFile *qaProofFile = new TProofOutputFile(Form("Merged.%s.Data.root",
+                                                               AliQAv1::GetQADataFileName()));
+      qaProofFile->SetOutputFileName(qaOutputFile.Data());
+      if (AliDebugLevel() > 0) qaProofFile->Dump();
+      fOutput->Add(qaProofFile);
+      MergeQA(qaProofFile->GetFileName());
+    }
+    else {
+      MergeQA();
+    }
+  }
 
-//   TString detStr = detectors;
-//   for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-//     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
-//     AliReconstructor* reconstructor = GetReconstructor(iDet);
-//     if (!reconstructor) continue;
-//     if (reconstructor->HasLocalReconstruction()) continue;
+  gROOT->cd();
+  CleanUp();
 
-//     AliCodeTimerStart(Form("running reconstruction for %s", fgkDetectorName[iDet]));
-//     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
+  if (fInput) {
+    if (!fProofOutputFileName.IsNull() &&
+       !fProofOutputLocation.IsNull() &&
+       fProofOutputDataset &&
+       !fProofOutputArchive.IsNull()) {
+      TProofOutputFile *zipProofFile = new TProofOutputFile(fProofOutputFileName.Data(),
+                                                           "DROV",
+                                                           fProofOutputLocation.Data());
+      if (AliDebugLevel() > 0) zipProofFile->Dump();
+      fOutput->Add(zipProofFile);
+      TString fileList(fProofOutputArchive.Data());
+      fileList.ReplaceAll(","," ");
+      TString command;
+#if ROOT_SVN_REVISION >= 30174
+      command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(kTRUE),zipProofFile->GetFileName(),fileList.Data());
+#else
+      command.Form("zip -n root %s/%s %s",zipProofFile->GetDir(),zipProofFile->GetFileName(),fileList.Data());
+#endif
+      AliInfo(Form("Executing: %s",command.Data()));
+      gSystem->Exec(command.Data());
+    }
+  }
+}
     
-//     AliCodeTimerStart(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));                          
-//     AliInfo(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
-
-//     man->SetCacheFlag(kTRUE);
-//     TString calibPath = Form("%s/Calib/*", fgkDetectorName[iDet]);
-//     man->GetAll(calibPath); // entries are cached!
-
-//     AliCodeTimerStop(Form("Loading calibration data from OCDB for %s", fgkDetectorName[iDet]));
-     
-//     if (fRawReader) {
-//       fRawReader->RewindEvents();
-//       reconstructor->Reconstruct(fRunLoader, fRawReader);
-//     } else {
-//       reconstructor->Reconstruct(fRunLoader);
-//     }
-     
-//      AliCodeTimerStop(Form("running reconstruction for %s", fgkDetectorName[iDet]));
-    // AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr));
-
-//     // unload calibration data
-//     man->UnloadFromCache(calibPath);
-//     //man->ClearCache();
-//   }
-
-//   man->SetCacheFlag(origCache);
+//_____________________________________________________________________________
+void AliReconstruction::Terminate()
+{
+  // Create tags for the events in the ESD tree (the ESD tree is always present)
+  // In case of empty events the tags will contain dummy values
+  AliCodeTimerAuto("",0);
 
-//   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
-//     AliError(Form("the following detectors were not found: %s",
-//                   detStr.Data()));
-//     if (fStopOnError) return kFALSE;
-//   }
+  // Do not call the ESD tag creator in case of PROOF-based reconstruction
+  if (!fInput) {
+    AliESDTagCreator *esdtagCreator = new AliESDTagCreator();
+    esdtagCreator->CreateESDTags(fFirstEvent,fLastEvent,fGRPData, AliQAv1::Instance()->GetQA(), AliQAv1::Instance()->GetEventSpecies(), AliQAv1::kNDET, AliRecoParam::kNSpecies);
+    delete esdtagCreator;
+  }
 
-         eventNr++;
-  return kTRUE;
+  // Cleanup of CDB manager: cache and active storages!
+  AliCDBManager::Instance()->ClearCache();
 }
 
 //_____________________________________________________________________________
@@ -1148,14 +2270,25 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
 // run the local reconstruction
 
   static Int_t eventNr=0;
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
 
   TString detStr = detectors;
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
     AliReconstructor* reconstructor = GetReconstructor(iDet);
     if (!reconstructor) continue;
     AliLoader* loader = fLoader[iDet];
+    // Matthias April 2008: temporary fix to run HLT reconstruction
+    // although the HLT loader is missing
+    if (strcmp(fgkDetectorName[iDet], "HLT")==0) {
+      if (fRawReader) {
+        reconstructor->Reconstruct(fRawReader, NULL);
+      } else {
+        TTree* dummy=NULL;
+        reconstructor->Reconstruct(dummy, NULL);
+      }
+      continue;
+    }
     if (!loader) {
       AliWarning(Form("No loader is defined for %s!",fgkDetectorName[iDet]));
       continue;
@@ -1164,8 +2297,8 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
     if (fRawReader && reconstructor->HasDigitConversion()) {
       AliInfo(Form("converting raw data digits into root objects for %s", 
                   fgkDetectorName[iDet]));
-      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
-                            fgkDetectorName[iDet]));
+//      AliCodeTimerAuto(Form("converting raw data digits into root objects for %s", 
+//                            fgkDetectorName[iDet]),0);
       loader->LoadDigits("update");
       loader->CleanDigits();
       loader->MakeDigitsContainer();
@@ -1176,7 +2309,7 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
     }
     // local reconstruction
     AliInfo(Form("running reconstruction for %s", fgkDetectorName[iDet]));
-    AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]));
+    //AliCodeTimerAuto(Form("running reconstruction for %s", fgkDetectorName[iDet]),0);
     loader->LoadRecPoints("update");
     loader->CleanRecPoints();
     loader->MakeRecPointsContainer();
@@ -1187,97 +2320,180 @@ Bool_t AliReconstruction::RunLocalEventReconstruction(const TString& detectors)
       loader->LoadDigits("read");
       TTree* digitsTree = loader->TreeD();
       if (!digitsTree) {
-       AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
-       if (fStopOnError) return kFALSE;
+        AliError(Form("Can't get the %s digits tree", fgkDetectorName[iDet]));
+        if (fStopOnError) 
+          return kFALSE;
       } else {
-       reconstructor->Reconstruct(digitsTree, clustersTree);
+        reconstructor->Reconstruct(digitsTree, clustersTree);
+        if (fRunQA && IsInTasks(AliQAv1::kDIGITSR)) {
+          AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
+          AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, digitsTree) ; 
+        }
       }
       loader->UnloadDigits();
     }
-
-    // In-loop QA for local reconstrucion 
-    if (fRunQA && fInLoopQA) {
-       AliQADataMakerRec * qadm = GetQADataMaker(iDet);
-       if (qadm) {
-         //AliCodeTimerStart
-         //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
-         //AliInfo
-          //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
-
-         qadm->Exec(AliQA::kRECPOINTS, clustersTree) ;
-         //AliCodeTimerStop
-          //(Form("Running QA data maker for %s", fgkDetectorName[iDet]));
-       }
+               if (fRunQA && IsInTasks(AliQAv1::kRECPOINTS)) {
+      AliQAManager::QAManager()->SetEventSpecie(fRecoParam.GetEventSpecie()) ;
+                       AliQAManager::QAManager()->RunOneEventInOneDetector(iDet, clustersTree) ; 
     }
-
     loader->WriteRecPoints("OVERWRITE");
     loader->UnloadRecPoints();
     AliSysInfo::AddStamp(Form("LRec%s_%d",fgkDetectorName[iDet],eventNr), iDet,1,eventNr);
   }
-
+  IsSelected("CTP", detStr);
   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
     AliError(Form("the following detectors were not found: %s",
                   detStr.Data()));
-    if (fStopOnError) return kFALSE;
+    if (fStopOnError) 
+      return kFALSE;
   }
   eventNr++;
   return kTRUE;
 }
-
 //_____________________________________________________________________________
-Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
+Bool_t AliReconstruction::RunSPDTrackleting(AliESDEvent*& esd)
 {
-// run the barrel tracking
+// run the SPD trackleting (for SPD efficiency purpouses)
 
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
 
-  AliESDVertex* vertex = NULL;
   Double_t vtxPos[3] = {0, 0, 0};
-  Double_t vtxErr[3] = {0.07, 0.07, 0.1};
-  TArrayF mcVertex(3); 
+  Double_t vtxErr[3] = {0.0, 0.0, 0.0};
+/*
+  TArrayF mcVertex(3);
+  // if(MC)
   if (fRunLoader->GetHeader() && fRunLoader->GetHeader()->GenEventHeader()) {
     fRunLoader->GetHeader()->GenEventHeader()->PrimaryVertex(mcVertex);
     for (Int_t i = 0; i < 3; i++) vtxPos[i] = mcVertex[i];
   }
+*/
+  const AliESDVertex *vertex = esd->GetVertex();
+  if(!vertex){
+    AliWarning("Vertex not found");
+    return kFALSE;
+  }
+  vertex->GetXYZ(vtxPos);
+  vertex->GetSigmaXYZ(vtxErr);
+  if (fSPDTrackleter) {
+    AliInfo("running the SPD Trackleter for Plane Efficiency Evaluation");
 
-  if (fVertexer) {
-    if(fDiamondProfile) fVertexer->SetVtxStart(fDiamondProfile);
-    AliInfo("running the ITS vertex finder");
-    if (fLoader[0]) fLoader[0]->LoadRecPoints();
-    vertex = fVertexer->FindVertexForCurrentEvent(fRunLoader->GetEventNumber());
-    if (fLoader[0]) fLoader[0]->UnloadRecPoints();
-    if(!vertex){
-      AliWarning("Vertex not found");
-      vertex = new AliESDVertex();
-      vertex->SetName("default");
+    // load clusters
+    fLoader[0]->LoadRecPoints("read");
+    TTree* tree = fLoader[0]->TreeR();
+    if (!tree) {
+      AliError("Can't get the ITS cluster tree");
+      return kFALSE;
     }
-    else {
-      vertex->SetName("reconstructed");
+    fSPDTrackleter->LoadClusters(tree);
+    fSPDTrackleter->SetVertex(vtxPos, vtxErr);
+    // run trackleting
+    if (fSPDTrackleter->Clusters2Tracks(esd) != 0) {
+      AliWarning("AliITSTrackleterSPDEff Clusters2Tracks failed");
+     // fLoader[0]->UnloadRecPoints();
+      return kFALSE;
     }
-
+//fSPDTrackleter->UnloadRecPoints();
   } else {
-    AliInfo("getting the primary vertex from MC");
-    vertex = new AliESDVertex(vtxPos, vtxErr);
+    AliWarning("SPDTrackleter not available");
+    return kFALSE;
   }
+  return kTRUE;
+}
 
-  if (vertex) {
-    vertex->GetXYZ(vtxPos);
-    vertex->GetSigmaXYZ(vtxErr);
-  } else {
-    AliWarning("no vertex reconstructed");
-    vertex = new AliESDVertex(vtxPos, vtxErr);
+//_____________________________________________________________________________
+Bool_t AliReconstruction::RunVertexFinder(AliESDEvent*& esd)
+{
+// run the barrel tracking
+
+  AliCodeTimerAuto("",0)
+
+  AliVertexer *vertexer = CreateVertexer();
+  if (!vertexer) return kFALSE;
+
+  AliInfo(Form("running the ITS vertex finder: %s",vertexer->ClassName()));
+  AliESDVertex* vertex = NULL;
+  if (fLoader[0]) {
+    fLoader[0]->LoadRecPoints();
+    TTree* cltree = fLoader[0]->TreeR();
+    if (cltree) {
+      if(fDiamondProfileSPD) vertexer->SetVtxStart(fDiamondProfileSPD);
+      vertex = vertexer->FindVertexForCurrentEvent(cltree);
+    }
+    else {
+      AliError("Can't get the ITS cluster tree");
+    }
+    fLoader[0]->UnloadRecPoints();
+  }
+  else {
+    AliError("Can't get the ITS loader");
+  }
+  if(!vertex){
+    AliWarning("Vertex not found");
+    vertex = new AliESDVertex();
+    vertex->SetName("default");
+  }
+  else {
+    vertex->SetName("reconstructed");
+  }
+
+  Double_t vtxPos[3];
+  Double_t vtxErr[3];
+  vertex->GetXYZ(vtxPos);
+  vertex->GetSigmaXYZ(vtxErr);
+
+  esd->SetPrimaryVertexSPD(vertex);
+  AliESDVertex *vpileup = NULL;
+  Int_t novertices = 0;
+  vpileup = vertexer->GetAllVertices(novertices);
+  if(novertices>1){
+    for (Int_t kk=1; kk<novertices; kk++)esd->AddPileupVertexSPD(&vpileup[kk]);
   }
-  esd->SetVertex(vertex);
+  /*
   // if SPD multiplicity has been determined, it is stored in the ESD
-  AliMultiplicity *mult = fVertexer->GetMultiplicity();
+  AliMultiplicity *mult = vertexer->GetMultiplicity();
   if(mult)esd->SetMultiplicity(mult);
-
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+  */
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     if (fTracker[iDet]) fTracker[iDet]->SetVertex(vtxPos, vtxErr);
   }  
   delete vertex;
 
+  delete vertexer;
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::RunMultFinder(AliESDEvent*& esd)
+{
+  // run the trackleter for multiplicity study
+
+  AliCodeTimerAuto("",0)
+
+  AliTrackleter *trackleter = CreateMultFinder();
+  if (!trackleter) return kFALSE;
+
+  AliInfo(Form("running the ITS multiplicity finder: %s",trackleter->ClassName()));
+
+  if (fLoader[0]) {
+    fLoader[0]->LoadRecPoints();
+    TTree* cltree = fLoader[0]->TreeR();
+    if (cltree) {
+      trackleter->Reconstruct(esd,cltree);
+      AliMultiplicity *mult = trackleter->GetMultiplicity();
+      if(mult) esd->SetMultiplicity(mult);
+    }
+    else {
+      AliError("Can't get the ITS cluster tree");
+    }
+    fLoader[0]->UnloadRecPoints();
+  }
+  else {
+    AliError("Can't get the ITS loader");
+  }
+
+  delete trackleter;
+
   return kTRUE;
 }
 
@@ -1286,7 +2502,7 @@ Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
 {
 // run the HLT barrel tracking
 
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
 
   if (!fRunLoader) {
     AliError("Missing runLoader!");
@@ -1296,7 +2512,7 @@ Bool_t AliReconstruction::RunHLTTracking(AliESDEvent*& esd)
   AliInfo("running HLT tracking");
 
   // Get a pointer to the HLT reconstructor
-  AliReconstructor *reconstructor = GetReconstructor(fgkNDetectors-1);
+  AliReconstructor *reconstructor = GetReconstructor(kNDetectors-1);
   if (!reconstructor) return kFALSE;
 
   // TPC + ITS
@@ -1342,7 +2558,7 @@ Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
 {
 // run the muon spectrometer tracking
 
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
 
   if (!fRunLoader) {
     AliError("Missing runLoader!");
@@ -1372,36 +2588,48 @@ Bool_t AliReconstruction::RunMuonTracking(AliESDEvent*& esd)
   
   Int_t rv = tracker->Clusters2Tracks(esd);
   
-  if ( rv )
-  {
-    AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
-    return kFALSE;
-  }
-  
   fLoader[iDet]->UnloadRecPoints();
 
   tracker->UnloadClusters();
   
   delete tracker;
   
+  if ( rv )
+  {
+    AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
+    return kFALSE;
+  }
+  
   return kTRUE;
 }
 
 
 //_____________________________________________________________________________
-Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
+Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd,AliESDpid &PID)
 {
 // run the barrel tracking
   static Int_t eventNr=0;
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
 
   AliInfo("running tracking");
 
+  // Set the event info which is used
+  // by the trackers in order to obtain
+  // information about read-out detectors,
+  // trigger etc.
+  AliDebug(1, "Setting event info");
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+    if (!fTracker[iDet]) continue;
+    fTracker[iDet]->SetEventInfo(&fEventInfo);
+  }
+
   //Fill the ESD with the T0 info (will be used by the TOF) 
   if (fReconstructor[11] && fLoader[11]) {
     fLoader[11]->LoadRecPoints("READ");
     TTree *treeR = fLoader[11]->TreeR();
-    GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
+    if (treeR) {
+      GetReconstructor(11)->FillESD((TTree *)NULL,treeR,esd);
+    }
   }
 
   // pass 1: TPC + ITS inwards
@@ -1424,22 +2652,17 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
       AliError(Form("%s Clusters2Tracks failed", fgkDetectorName[iDet]));
       return kFALSE;
     }
-    if (fCheckPointLevel > 1) {
-      WriteESD(esd, Form("%s.tracking", fgkDetectorName[iDet]));
-    }
     // preliminary PID in TPC needed by the ITS tracker
     if (iDet == 1) {
       GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
-      AliESDpid::MakePID(esd);
+      PID.MakePID(esd,kTRUE);
     } 
     AliSysInfo::AddStamp(Form("Tracking0%s_%d",fgkDetectorName[iDet],eventNr), iDet,3,eventNr);
   }
 
   // pass 2: ALL backwards
 
-  if (fRunQA && fRunGlobalQA) AliTracker::SetFillResiduals(kTRUE);     
-
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
     if (!fTracker[iDet]) continue;
     AliDebug(1, Form("%s back propagation", fgkDetectorName[iDet]));
 
@@ -1450,50 +2673,69 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
       AliSysInfo::AddStamp(Form("RLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,1, eventNr);
       tree = fLoader[iDet]->TreeR();
       if (!tree) {
-       AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
-       return kFALSE;
+        AliError(Form("Can't get the %s cluster tree", fgkDetectorName[iDet]));
+        return kFALSE;
       }
       fTracker[iDet]->LoadClusters(tree); 
       AliSysInfo::AddStamp(Form("TLoadCluster0%s_%d",fgkDetectorName[iDet],eventNr), iDet,2, eventNr);
     }
 
     // run tracking
+    if (iDet>1) // start filling residuals for the "outer" detectors
+      if (fRunGlobalQA) {
+        AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
+        TObjArray ** arr = AliTracker::GetResidualsArray() ; 
+       if (arr) {
+         AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
+         TObjArray * elem = arr[AliRecoParam::AConvert(es)];
+         if ( elem && (! elem->At(0)) ) {
+           AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
+           if (qadm) qadm->InitRecPointsForTracker() ; 
+         }
+       }
+      }
     if (fTracker[iDet]->PropagateBack(esd) != 0) {
       AliError(Form("%s backward propagation failed", fgkDetectorName[iDet]));
       //      return kFALSE;
     }
-    if (fCheckPointLevel > 1) {
-      WriteESD(esd, Form("%s.back", fgkDetectorName[iDet]));
-    }
 
     // unload clusters
-    if (iDet > 2) {     // all except ITS, TPC, TRD
+    if (iDet > 3) {     // all except ITS, TPC, TRD and TOF
       fTracker[iDet]->UnloadClusters();
       fLoader[iDet]->UnloadRecPoints();
     }
     // updated PID in TPC needed by the ITS tracker -MI
     if (iDet == 1) {
-      GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
-      AliESDpid::MakePID(esd);
+      //GetReconstructor(1)->FillESD((TTree*)NULL, (TTree*)NULL, esd);
+      //AliESDpid::MakePID(esd);
+      PID.MakePID(esd,kTRUE);
     }
     AliSysInfo::AddStamp(Form("Tracking1%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
   }
-
-  if (fRunQA && fRunGlobalQA) AliTracker::SetFillResiduals(kFALSE);     
-
-  // write space-points to the ESD in case alignment data output
-  // is switched on
-  if (fWriteAlignmentData)
-    WriteAlignmentData(esd);
+  //stop filling residuals for the "outer" detectors
+  if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
 
   // pass 3: TRD + TPC + ITS refit inwards
 
-
   for (Int_t iDet = 2; iDet >= 0; iDet--) {
     if (!fTracker[iDet]) continue;
     AliDebug(1, Form("%s inward refit", fgkDetectorName[iDet]));
 
     // run tracking
+    if (iDet<2) // start filling residuals for TPC and ITS
+      if (fRunGlobalQA) {
+        AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kTRUE);     
+        TObjArray ** arr = AliTracker::GetResidualsArray() ; 
+       if (arr) {
+         AliRecoParam::EventSpecie_t es=fRecoParam.GetEventSpecie();
+         TObjArray * elem = arr[AliRecoParam::AConvert(es)];
+         if ( elem && (! elem->At(0)) ) {
+           AliQADataMaker *qadm = AliQAManager::QAManager()->GetQADataMaker(AliQAv1::kGLOBAL);
+           if (qadm) qadm->InitRecPointsForTracker() ; 
+         }
+       }
+      }
+    
     if (fTracker[iDet]->RefitInward(esd) != 0) {
       AliError(Form("%s inward refit failed", fgkDetectorName[iDet]));
       //      return kFALSE;
@@ -1503,32 +2745,25 @@ Bool_t AliReconstruction::RunTracking(AliESDEvent*& esd)
       AliError(Form("%s postprocessing failed", fgkDetectorName[iDet]));
       //      return kFALSE;
     }
-    if (fCheckPointLevel > 1) {
-      WriteESD(esd, Form("%s.refit", fgkDetectorName[iDet]));
-    }
     AliSysInfo::AddStamp(Form("Tracking2%s_%d",fgkDetectorName[iDet],eventNr), iDet,3, eventNr);
+  }
+
+  // write space-points to the ESD in case alignment data output
+  // is switched on
+  if (fWriteAlignmentData)
+    WriteAlignmentData(esd);
+
+  for (Int_t iDet = 3; iDet >= 0; iDet--) {
+    if (!fTracker[iDet]) continue;
     // unload clusters
     fTracker[iDet]->UnloadClusters();
     AliSysInfo::AddStamp(Form("TUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,4, eventNr);
     fLoader[iDet]->UnloadRecPoints();
     AliSysInfo::AddStamp(Form("RUnloadCluster%s_%d",fgkDetectorName[iDet],eventNr), iDet,5, eventNr);
   }
+  // stop filling residuals for TPC and ITS
+  if (fRunGlobalQA) AliTracker::SetFillResiduals(fRecoParam.GetEventSpecie(), kFALSE);     
 
-  //
-  // Propagate track to the vertex - if not done by ITS
-  //
-  Int_t ntracks = esd->GetNumberOfTracks();
-  for (Int_t itrack=0; itrack<ntracks; itrack++){
-    const Double_t kRadius  = 3;   // beam pipe radius
-    const Double_t kMaxStep = 5;   // max step
-    const Double_t kMaxD    = 123456;  // max distance to prim vertex
-    Double_t       fieldZ   = AliTracker::GetBz();  //
-    AliESDtrack * track = esd->GetTrack(itrack);
-    if (!track) continue;
-    if (track->IsOn(AliESDtrack::kITSrefit)) continue;
-   AliTracker::PropagateTrackTo(track,kRadius,track->GetMass(),kMaxStep,kTRUE);
-    track->RelateToVertex(esd->GetVertex(),fieldZ, kMaxD);
-  }
   eventNr++;
   return kTRUE;
 }
@@ -1560,56 +2795,54 @@ Bool_t AliReconstruction::FillESD(AliESDEvent*& esd, const TString& detectors)
 {
 // fill the event summary data
 
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
     static Int_t eventNr=0; 
   TString detStr = detectors;
   
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+  AliSysInfo::AddStamp(Form("FillESDb%d",eventNr), -19,-19, eventNr);
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
     AliReconstructor* reconstructor = GetReconstructor(iDet);
     if (!reconstructor) continue;
-    if (!ReadESD(esd, fgkDetectorName[iDet])) {
-      AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
-      TTree* clustersTree = NULL;
+    AliDebug(1, Form("filling ESD for %s", fgkDetectorName[iDet]));
+    TTree* clustersTree = NULL;
+    if (fLoader[iDet]) {
+      fLoader[iDet]->LoadRecPoints("read");
+      clustersTree = fLoader[iDet]->TreeR();
+      if (!clustersTree) {
+       AliError(Form("Can't get the %s clusters tree", 
+                     fgkDetectorName[iDet]));
+       if (fStopOnError) return kFALSE;
+      }
+    }
+    if (fRawReader && !reconstructor->HasDigitConversion()) {
+      reconstructor->FillESD(fRawReader, clustersTree, esd);
+    } else {
+      TTree* digitsTree = NULL;
       if (fLoader[iDet]) {
-       fLoader[iDet]->LoadRecPoints("read");
-       clustersTree = fLoader[iDet]->TreeR();
-       if (!clustersTree) {
-         AliError(Form("Can't get the %s clusters tree", 
+       fLoader[iDet]->LoadDigits("read");
+       digitsTree = fLoader[iDet]->TreeD();
+       if (!digitsTree) {
+         AliError(Form("Can't get the %s digits tree", 
                        fgkDetectorName[iDet]));
          if (fStopOnError) return kFALSE;
        }
       }
-      if (fRawReader && !reconstructor->HasDigitConversion()) {
-        reconstructor->FillESD(fRawReader, clustersTree, esd);
-      } else {
-       TTree* digitsTree = NULL;
-       if (fLoader[iDet]) {
-         fLoader[iDet]->LoadDigits("read");
-         digitsTree = fLoader[iDet]->TreeD();
-         if (!digitsTree) {
-           AliError(Form("Can't get the %s digits tree", 
-                         fgkDetectorName[iDet]));
-           if (fStopOnError) return kFALSE;
-         }
-       }
-       reconstructor->FillESD(digitsTree, clustersTree, esd);
-       if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
-      }
-      if (fLoader[iDet]) {
-       fLoader[iDet]->UnloadRecPoints();
-      }
-
-      if (fCheckPointLevel > 2) WriteESD(esd, fgkDetectorName[iDet]);
+      reconstructor->FillESD(digitsTree, clustersTree, esd);
+      if (fLoader[iDet]) fLoader[iDet]->UnloadDigits();
+    }
+    if (fLoader[iDet]) {
+      fLoader[iDet]->UnloadRecPoints();
     }
   }
-
+  
+  IsSelected("CTP", detStr);
   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
     AliError(Form("the following detectors were not found: %s", 
                   detStr.Data()));
     if (fStopOnError) return kFALSE;
   }
-  AliSysInfo::AddStamp(Form("FillESD%d",eventNr), 0,1, eventNr);
+  AliSysInfo::AddStamp(Form("FillESDe%d",eventNr), -20,-20, eventNr);
   eventNr++;
   return kTRUE;
 }
@@ -1621,45 +2854,57 @@ Bool_t AliReconstruction::FillTriggerESD(AliESDEvent*& esd)
   // stored in Trigger.root file and fills
   // the corresponding esd entries
 
-  AliCodeTimerAuto("")
+  AliCodeTimerAuto("",0)
   
   AliInfo("Filling trigger information into the ESD");
-
-  if (fRawReader) {
-    AliCTPRawStream input(fRawReader);
-    if (!input.Next()) {
-      AliError("No valid CTP (trigger) DDL raw data is found ! The trigger information is not stored in the ESD !");
-      return kFALSE;
-    }
-    esd->SetTriggerMask(input.GetClassMask());
-    esd->SetTriggerCluster(input.GetClusterMask());
-  }
-  else {
-    AliRunLoader *runloader = AliRunLoader::GetRunLoader();
-    if (runloader) {
-      if (!runloader->LoadTrigger()) {
-       AliCentralTrigger *aCTP = runloader->GetTrigger();
-       esd->SetTriggerMask(aCTP->GetClassMask());
-       esd->SetTriggerCluster(aCTP->GetClusterMask());
-      }
-      else {
-       AliWarning("No trigger can be loaded! The trigger information is not stored in the ESD !");
-       return kFALSE;
-      }
+
+  if (fRawReader) {
+    AliCTPRawStream input(fRawReader);
+    if (!input.Next()) {
+      AliWarning("No valid CTP (trigger) DDL raw data is found ! The trigger info is taken from the event header!");
     }
     else {
-      AliError("No run loader is available! The trigger information is not stored in the ESD !");
-      return kFALSE;
+      if (esd->GetTriggerMask() != input.GetClassMask())
+       AliError(Form("Invalid trigger pattern found in CTP raw-data: %llx %llx",
+                     input.GetClassMask(),esd->GetTriggerMask()));
+      if (esd->GetOrbitNumber() != input.GetOrbitID())
+       AliError(Form("Invalid orbit id found in CTP raw-data: %x %x",
+                     input.GetOrbitID(),esd->GetOrbitNumber()));
+      if (esd->GetBunchCrossNumber() != input.GetBCID())
+       AliError(Form("Invalid bunch-crossing id found in CTP raw-data: %x %x",
+                     input.GetBCID(),esd->GetBunchCrossNumber()));
+      AliESDHeader* esdheader = esd->GetHeader();
+      esdheader->SetL0TriggerInputs(input.GetL0Inputs());
+      esdheader->SetL1TriggerInputs(input.GetL1Inputs());
+      esdheader->SetL2TriggerInputs(input.GetL2Inputs());
+      // IR
+      UInt_t orbit=input.GetOrbitID();
+       for(Int_t i=0 ; i<input.GetNIRs() ; i++ )
+          if(TMath::Abs(Int_t(orbit-(input.GetIR(i))->GetOrbit()))<=1){
+            esdheader->AddTriggerIR(input.GetIR(i));
+         }
     }
   }
-
   return kTRUE;
 }
-
-
-
-
-
+//_____________________________________________________________________________
+Bool_t AliReconstruction::FillTriggerScalers(AliESDEvent*& esd)
+{
+  //Scalers
+  //fRunScalers->Print();
+  if(fRunScalers && fRunScalers->CheckRunScalers()){
+     AliTimeStamp* timestamp = new AliTimeStamp(esd->GetOrbitNumber(), esd->GetPeriodNumber(), esd->GetBunchCrossNumber());
+     //AliTimeStamp* timestamp = new AliTimeStamp(10308000, 0, (ULong64_t)486238);
+     AliESDHeader* esdheader = fesd->GetHeader();
+     for(Int_t i=0;i<50;i++){
+          if((1ull<<i) & esd->GetTriggerMask()){
+          AliTriggerScalersESD* scalesd = fRunScalers->GetScalersForEventClass( timestamp, i+1);
+          if(scalesd)esdheader->SetTriggerScalersRecord(scalesd);
+        }
+     }
+  }
+  return kTRUE;
+}
 //_____________________________________________________________________________
 Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
 {
@@ -1667,23 +2912,16 @@ Bool_t AliReconstruction::FillRawEventHeaderESD(AliESDEvent*& esd)
   // Filling information from RawReader Header
   // 
 
+  if (!fRawReader) return kFALSE;
+
   AliInfo("Filling information from RawReader Header");
-  esd->SetBunchCrossNumber(0);
-  esd->SetOrbitNumber(0);
-  esd->SetPeriodNumber(0);
-  esd->SetTimeStamp(0);
-  esd->SetEventType(0);
-  const AliRawEventHeaderBase * eventHeader = fRawReader->GetEventHeader();
-  if (eventHeader){
 
-    const UInt_t *id = eventHeader->GetP("Id");
-    esd->SetBunchCrossNumber((id)[1]&0x00000fff);
-    esd->SetOrbitNumber((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff));
-    esd->SetPeriodNumber(((id)[0]>>4)&0x0fffffff);
+  esd->SetBunchCrossNumber(fRawReader->GetBCID());
+  esd->SetOrbitNumber(fRawReader->GetOrbitID());
+  esd->SetPeriodNumber(fRawReader->GetPeriod());
 
-    esd->SetTimeStamp((eventHeader->Get("Timestamp")));  
-    esd->SetEventType((eventHeader->Get("Type")));
-  }
+  esd->SetTimeStamp(fRawReader->GetTimestamp());  
+  esd->SetEventType(fRawReader->GetType());
 
   return kTRUE;
 }
@@ -1730,10 +2968,15 @@ Bool_t AliReconstruction::InitRunLoader()
   if (gAlice) delete gAlice;
   gAlice = NULL;
 
-  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
+  TFile *gafile = TFile::Open(fGAliceFileName.Data());
+  //  if (!gSystem->AccessPathName(fGAliceFileName.Data())) { // galice.root exists
+  if (gafile) { // galice.root exists
+    gafile->Close();
+    delete gafile;
+
     // load all base libraries to get the loader classes
     TString libs = gSystem->GetLibraries();
-    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+    for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
       TString detName = fgkDetectorName[iDet];
       if (detName == "HLT") continue;
       if (libs.Contains("lib" + detName + "base.so")) continue;
@@ -1745,19 +2988,9 @@ Bool_t AliReconstruction::InitRunLoader()
       CleanUp();
       return kFALSE;
     }
+
     fRunLoader->CdGAFile();
-    if (gFile->GetKey(AliRunLoader::GetGAliceName())) {
-      if (fRunLoader->LoadgAlice() == 0) {
-       gAlice = fRunLoader->GetAliRun();
-       AliTracker::SetFieldMap(gAlice->Field(),fUniformField);
-      }
-    }
-    if (!gAlice && !fRawReader) {
-      AliError(Form("no gAlice object found in file %s",
-                   fGAliceFileName.Data()));
-      CleanUp();
-      return kFALSE;
-    }
+    fRunLoader->LoadgAlice();
 
     //PH This is a temporary fix to give access to the kinematics
     //PH that is needed for the labels of ITS clusters
@@ -1767,8 +3000,6 @@ Bool_t AliReconstruction::InitRunLoader()
   } else {               // galice.root does not exist
     if (!fRawReader) {
       AliError(Form("the file %s does not exist", fGAliceFileName.Data()));
-      CleanUp();
-      return kFALSE;
     }
     fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),
                                    AliConfig::GetDefaultEventFolderName(),
@@ -1779,25 +3010,13 @@ Bool_t AliReconstruction::InitRunLoader()
       CleanUp();
       return kFALSE;
     }
+    fIsNewRunLoader = kTRUE;
     fRunLoader->MakeTree("E");
-    Int_t iEvent = 0;
-    while (fRawReader->NextEvent()) {
-      fRunLoader->SetEventNumber(iEvent);
-      fRunLoader->GetHeader()->Reset(fRawReader->GetRunNumber(), 
-                                    iEvent, iEvent);
-      fRunLoader->MakeTree("H");
-      fRunLoader->TreeE()->Fill();
-      iEvent++;
-    }
-    fRawReader->RewindEvents();
+
     if (fNumberOfEventsPerFile > 0)
       fRunLoader->SetNumberOfEventsPerFile(fNumberOfEventsPerFile);
     else
-      fRunLoader->SetNumberOfEventsPerFile(iEvent);
-    fRunLoader->WriteHeader("OVERWRITE");
-    fRunLoader->CdGAFile();
-    fRunLoader->Write(0, TObject::kOverwrite);
-//    AliTracker::SetFieldMap(???);
+      fRunLoader->SetNumberOfEventsPerFile((UInt_t)-1);
   }
 
   return kTRUE;
@@ -1808,13 +3027,21 @@ AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
 {
 // get the reconstructor object and the loader for a detector
 
-  if (fReconstructor[iDet]) return fReconstructor[iDet];
+  if (fReconstructor[iDet]) {
+    if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
+      const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
+      fReconstructor[iDet]->SetRecoParam(par);
+      fReconstructor[iDet]->SetRunInfo(fRunInfo);
+    }
+    return fReconstructor[iDet];
+  }
 
   // load the reconstructor object
   TPluginManager* pluginManager = gROOT->GetPluginManager();
   TString detName = fgkDetectorName[iDet];
   TString recName = "Ali" + detName + "Reconstructor";
-  if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) return NULL;
+
+  if (!fIsNewRunLoader && !fRunLoader->GetLoader(detName+"Loader") && (detName != "HLT")) return NULL;
 
   AliReconstructor* reconstructor = NULL;
   // first check if a plugin is defined for the reconstructor
@@ -1840,6 +3067,7 @@ AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
   if (reconstructor) {
     TObject* obj = fOptions.FindObject(detName.Data());
     if (obj) reconstructor->SetOption(obj->GetTitle());
+    reconstructor->SetRunInfo(fRunInfo);
     reconstructor->Init();
     fReconstructor[iDet] = reconstructor;
   }
@@ -1883,969 +3111,187 @@ AliReconstructor* AliReconstruction::GetReconstructor(Int_t iDet)
     }
   }
       
+  if (fRecoParam.GetDetRecoParamArray(iDet) && !AliReconstructor::GetRecoParam(iDet)) {
+    const AliDetectorRecoParam *par = fRecoParam.GetDetRecoParam(iDet);
+    reconstructor->SetRecoParam(par);
+    reconstructor->SetRunInfo(fRunInfo);
+  }
   return reconstructor;
 }
 
 //_____________________________________________________________________________
-Bool_t AliReconstruction::CreateVertexer()
+AliVertexer* AliReconstruction::CreateVertexer()
 {
 // create the vertexer
+// Please note that the caller is the owner of the
+// vertexer
 
-  fVertexer = NULL;
+  AliVertexer* vertexer = NULL;
   AliReconstructor* itsReconstructor = GetReconstructor(0);
-  if (itsReconstructor) {
-    fVertexer = itsReconstructor->CreateVertexer();
+  if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
+                          fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
+    vertexer = itsReconstructor->CreateVertexer();
   }
-  if (!fVertexer) {
+  if (!vertexer) {
     AliWarning("couldn't create a vertexer for ITS");
-    if (fStopOnError) return kFALSE;
-  }
-
-  return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
-{
-// create the trackers
-
-  TString detStr = detectors;
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
-    AliReconstructor* reconstructor = GetReconstructor(iDet);
-    if (!reconstructor) continue;
-    TString detName = fgkDetectorName[iDet];
-    if (detName == "HLT") {
-      fRunHLTTracking = kTRUE;
-      continue;
-    }
-    if (detName == "MUON") {
-      fRunMuonTracking = kTRUE;
-      continue;
-    }
-
-
-    fTracker[iDet] = reconstructor->CreateTracker();
-    if (!fTracker[iDet] && (iDet < 7)) {
-      AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
-      if (fStopOnError) return kFALSE;
-    }
-    AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
-  }
-
-  return kTRUE;
-}
-
-//_____________________________________________________________________________
-void AliReconstruction::CleanUp(TFile* file, TFile* fileOld)
-{
-// delete trackers and the run loader and close and delete the file
-
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-    delete fReconstructor[iDet];
-    fReconstructor[iDet] = NULL;
-    fLoader[iDet] = NULL;
-    delete fTracker[iDet];
-    fTracker[iDet] = NULL;
-//    delete fQADataMaker[iDet];
-//    fQADataMaker[iDet] = NULL;
-  }
-  delete fVertexer;
-  fVertexer = NULL;
-  
-  if(!(AliCDBManager::Instance()->GetCacheFlag())) {
-       delete fDiamondProfile;
-       fDiamondProfile = NULL;
-  }
-
-  delete fGRPList;
-  fGRPList = NULL;
-
-  delete fRunLoader;
-  fRunLoader = NULL;
-  delete fRawReader;
-  fRawReader = NULL;
-
-  if (file) {
-    file->Close();
-    delete file;
-  }
-
-  if (fileOld) {
-    fileOld->Close();
-    delete fileOld;
-    gSystem->Unlink("AliESDs.old.root");
-  }
-}
-
-//_____________________________________________________________________________
-
-Bool_t AliReconstruction::ReadESD(AliESDEvent*& 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->GetEventNumberInFile(), recStep);
-  if (gSystem->AccessPathName(fileName)) return kFALSE;
-
-  AliInfo(Form("reading ESD from file %s", fileName));
-  AliDebug(1, Form("reading ESD from file %s", fileName));
-  TFile* file = TFile::Open(fileName);
-  if (!file || !file->IsOpen()) {
-    AliError(Form("opening %s failed", fileName));
-    delete file;
-    return kFALSE;
   }
 
-  gROOT->cd();
-  delete esd;
-  esd = (AliESDEvent*) file->Get("ESD");
-  file->Close();
-  delete file;
-  return kTRUE;
-
-}
-
-
-
-//_____________________________________________________________________________
-void AliReconstruction::WriteESD(AliESDEvent* 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->GetEventNumberInFile(), recStep);
-
-  AliDebug(1, Form("writing ESD to file %s", fileName));
-  TFile* file = TFile::Open(fileName, "recreate");
-  if (!file || !file->IsOpen()) {
-    AliError(Form("opening %s failed", fileName));
-  } else {
-    esd->Write("ESD");
-    file->Close();
-  }
-  delete file;
+  return vertexer;
 }
 
-
-
-
-
 //_____________________________________________________________________________
-void AliReconstruction::ESDFile2AODFile(TFile* esdFile, TFile* aodFile)
+AliTrackleter* AliReconstruction::CreateMultFinder()
 {
-  // write all files from the given esd file to an aod file
-
-  // create an AliAOD object 
-  AliAODEvent *aod = new AliAODEvent();
-  aod->CreateStdContent();
-  
-  // go to the file
-  aodFile->cd();
-  
-  // create the tree
-  TTree *aodTree = new TTree("aodTree", "AliAOD tree");
-  aodTree->Branch(aod->GetList());
-
-  // connect to ESD
-  TTree *t = (TTree*) esdFile->Get("esdTree");
-  AliESDEvent *esd = new AliESDEvent();
-  esd->ReadFromTree(t);
-
-  Int_t nEvents = t->GetEntries();
-
-  // set arrays and pointers
-  Float_t posF[3];
-  Double_t pos[3];
-  Double_t p[3];
-  Double_t p_pos[3];
-  Double_t p_neg[3];
-  Double_t covVtx[6];
-  Double_t covTr[21];
-  Double_t pid[10];
-
-  // loop over events and fill them
-  for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
-    //cout << "event: " << iEvent << endl;
-    t->GetEntry(iEvent);
-
-    // Multiplicity information needed by the header (to be revised!)
-    Int_t nTracks   = esd->GetNumberOfTracks();
-    Int_t nPosTracks = 0;
-    for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) 
-      if (esd->GetTrack(iTrack)->Charge()> 0) nPosTracks++;
-
-    // Access the header
-    AliAODHeader *header = aod->GetHeader();
-
-    // fill the header
-    header->SetRunNumber       (esd->GetRunNumber()       );
-    header->SetBunchCrossNumber(esd->GetBunchCrossNumber());
-    header->SetOrbitNumber     (esd->GetOrbitNumber()     );
-    header->SetPeriodNumber    (esd->GetPeriodNumber()    );
-    header->SetTriggerMask     (esd->GetTriggerMask()     ); 
-    header->SetTriggerCluster  (esd->GetTriggerCluster()  );
-    header->SetEventType       (esd->GetEventType()       );
-    header->SetMagneticField   (esd->GetMagneticField()   );
-    header->SetZDCN1Energy     (esd->GetZDCN1Energy()     );
-    header->SetZDCP1Energy     (esd->GetZDCP1Energy()     );
-    header->SetZDCN2Energy     (esd->GetZDCN2Energy()     );
-    header->SetZDCP2Energy     (esd->GetZDCP2Energy()     );
-    header->SetZDCEMEnergy     (esd->GetZDCEMEnergy(0),esd->GetZDCEMEnergy(1));
-    header->SetRefMultiplicity   (nTracks);
-    header->SetRefMultiplicityPos(nPosTracks);
-    header->SetRefMultiplicityNeg(nTracks - nPosTracks);
-    header->SetMuonMagFieldScale(-999.); // FIXME
-    header->SetCentrality(-999.);        // FIXME
-
-    Int_t nV0s      = esd->GetNumberOfV0s();
-    Int_t nCascades = esd->GetNumberOfCascades();
-    Int_t nKinks    = esd->GetNumberOfKinks();
-       Int_t nVertices = nV0s + 2*nCascades /*could lead to two vertices, one V0 and the Xi */+ nKinks + 1 /* = prim. vtx*/;    
-       Int_t nJets     = 0;
-    Int_t nCaloClus = esd->GetNumberOfCaloClusters();
-    Int_t nFmdClus  = 0;
-    Int_t nPmdClus  = esd->GetNumberOfPmdTracks();
-   
-    aod->ResetStd(nTracks, nVertices, nV0s+nCascades, nJets, nCaloClus, nFmdClus, nPmdClus);
-    
-    // Array to take into account the tracks already added to the AOD
-    Bool_t * usedTrack = NULL;
-    if (nTracks>0) {
-      usedTrack = new Bool_t[nTracks];
-      for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
-    }
-    // Array to take into account the V0s already added to the AOD
-    Bool_t * usedV0 = NULL;
-    if (nV0s>0) {
-      usedV0 = new Bool_t[nV0s];
-      for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
-    }
-    // Array to take into account the kinks already added to the AOD
-    Bool_t * usedKink = NULL;
-    if (nKinks>0) {
-      usedKink = new Bool_t[nKinks];
-      for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
-    }
-    
-    // Access to the AOD container of vertices
-    TClonesArray &vertices = *(aod->GetVertices());
-    Int_t jVertices=0;
-
-    // Access to the AOD container of tracks
-    TClonesArray &tracks = *(aod->GetTracks());
-    Int_t jTracks=0; 
-   
-    // Access to the AOD container of V0s
-    TClonesArray &V0s = *(aod->GetV0s());
-    Int_t jV0s=0;
-    
-    // Add primary vertex. The primary tracks will be defined
-    // after the loops on the composite objects (V0, cascades, kinks)
-    const AliESDVertex *vtx = esd->GetPrimaryVertex();
-      
-    vtx->GetXYZ(pos); // position
-    vtx->GetCovMatrix(covVtx); //covariance matrix
-
-    AliAODVertex * primary = new(vertices[jVertices++])
-      AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, -1, AliAODVertex::kPrimary);
-         
-
-    AliAODTrack *aodTrack = 0x0;
-    
-    // Create vertices starting from the most complex objects
-
-    // Cascades
-    for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
-      AliESDcascade *cascade = esd->GetCascade(nCascade);
-      
-      cascade->GetXYZ(pos[0], pos[1], pos[2]);
-      cascade->GetPosCovXi(covVtx);
-     
-      // Add the cascade vertex
-      AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
-                                                                       covVtx,
-                                                                       cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
-                                                                       primary,
-                                                                       nCascade,
-                                                                       AliAODVertex::kCascade);
-
-      primary->AddDaughter(vcascade); // the cascade 'particle' (represented by a vertex) is added as a daughter to the primary vertex
-
-      // Add the V0 from the cascade. The ESD class have to be optimized...
-      // Now we have to search for the corresponding V0 in the list of V0s
-      // using the indeces of the positive and negative tracks
-
-      Int_t posFromV0 = cascade->GetPindex();
-      Int_t negFromV0 = cascade->GetNindex();
-
-
-      AliESDv0 * v0 = 0x0;
-      Int_t indV0 = -1;
-
-      for (Int_t iV0=0; iV0<nV0s; ++iV0) {
-
-       v0 = esd->GetV0(iV0);
-       Int_t posV0 = v0->GetPindex();
-       Int_t negV0 = v0->GetNindex();
-
-       if (posV0==posFromV0 && negV0==negFromV0) {
-         indV0 = iV0;
-         break;
-       }
-      }
-
-      AliAODVertex * vV0FromCascade = 0x0;
-
-      if (indV0>-1 && !usedV0[indV0]) {
-       
-       // the V0 exists in the array of V0s and is not used
-
-       usedV0[indV0] = kTRUE;
-       
-       v0->GetXYZ(pos[0], pos[1], pos[2]);
-       v0->GetPosCov(covVtx);
-       
-       vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
-                                                                covVtx,
-                                                                v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
-                                                                vcascade,
-                                                                indV0,
-                                                                AliAODVertex::kV0);
-      } else {
-
-       // the V0 doesn't exist in the array of V0s or was used
-       cerr << "Error: event " << iEvent << " cascade " << nCascade
-            << " The V0 " << indV0 
-            << " doesn't exist in the array of V0s or was used!" << endl;
-
-       cascade->GetXYZ(pos[0], pos[1], pos[2]);
-       cascade->GetPosCov(covVtx);
-      
-       vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
-                                                                covVtx,
-                                                                v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
-                                                                vcascade,
-                                                                indV0,
-                                                                AliAODVertex::kV0);
-       vcascade->AddDaughter(vV0FromCascade);
-
-      }
-
-      // Add the positive tracks from the V0
-
-      if (! usedTrack[posFromV0]) {
-
-       usedTrack[posFromV0] = kTRUE;
-
-       AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
-       esdTrack->GetPxPyPz(p_pos);
-       esdTrack->GetXYZ(pos);
-       esdTrack->GetCovarianceXYZPxPyPz(covTr);
-       esdTrack->GetESDpid(pid);
-       
-       vV0FromCascade->AddDaughter(aodTrack =
-                                   new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(), 
-                                          p_pos, 
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          vV0FromCascade,
-                                          kTRUE,  // check if this is right
-                                          kFALSE, // check if this is right
-                                          AliAODTrack::kSecondary)
-               );
-       aodTrack->ConvertAliPIDtoAODPID();
-      }
-      else {
-       cerr << "Error: event " << iEvent << " cascade " << nCascade
-            << " track " << posFromV0 << " has already been used!" << endl;
-      }
-
-      // Add the negative tracks from the V0
-
-      if (!usedTrack[negFromV0]) {
-       
-       usedTrack[negFromV0] = kTRUE;
-       
-       AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
-       esdTrack->GetPxPyPz(p_neg);
-       esdTrack->GetXYZ(pos);
-       esdTrack->GetCovarianceXYZPxPyPz(covTr);
-       esdTrack->GetESDpid(pid);
-       
-       vV0FromCascade->AddDaughter(aodTrack =
-                new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(),
-                                          p_neg,
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          vV0FromCascade,
-                                          kTRUE,  // check if this is right
-                                          kFALSE, // check if this is right
-                                          AliAODTrack::kSecondary)
-               );
-       aodTrack->ConvertAliPIDtoAODPID();
-      }
-      else {
-       cerr << "Error: event " << iEvent << " cascade " << nCascade
-            << " track " << negFromV0 << " has already been used!" << endl;
-      }
-
-      // add it to the V0 array as well
-      Double_t d0[2] = { -999., -99.};
-      // counting is probably wrong
-      new(V0s[jV0s++]) AliAODv0(vV0FromCascade, -999., -99., p_pos, p_neg, d0); // to be refined
-
-      // Add the bachelor track from the cascade
-
-      Int_t bachelor = cascade->GetBindex();
-      
-      if(!usedTrack[bachelor]) {
-      
-       usedTrack[bachelor] = kTRUE;
-       
-       AliESDtrack *esdTrack = esd->GetTrack(bachelor);
-       esdTrack->GetPxPyPz(p);
-       esdTrack->GetXYZ(pos);
-       esdTrack->GetCovarianceXYZPxPyPz(covTr);
-       esdTrack->GetESDpid(pid);
-
-       vcascade->AddDaughter(aodTrack =
-               new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(),
-                                          p,
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          vcascade,
-                                          kTRUE,  // check if this is right
-                                          kFALSE, // check if this is right
-                                          AliAODTrack::kSecondary)
-               );
-       aodTrack->ConvertAliPIDtoAODPID();
-     }
-      else {
-       cerr << "Error: event " << iEvent << " cascade " << nCascade
-            << " track " << bachelor << " has already been used!" << endl;
-      }
-      
-      // Add the primary track of the cascade (if any)
-      
-    } // end of the loop on cascades
-    // V0s
-        
-    for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
-
-      if (usedV0[nV0]) continue; // skip if aready added to the AOD
+// create the ITS trackleter for mult. estimation
+// Please note that the caller is the owner of the
+// trackleter
 
-      AliESDv0 *v0 = esd->GetV0(nV0); 
-     
-      v0->GetXYZ(pos[0], pos[1], pos[2]);
-      v0->GetPosCov(covVtx);
-
-      AliAODVertex * vV0 = 
-       new(vertices[jVertices++]) AliAODVertex(pos,
-                                               covVtx,
-                                               v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
-                                               primary,
-                                               nV0,
-                                               AliAODVertex::kV0);
-      primary->AddDaughter(vV0);
-
-      Int_t posFromV0 = v0->GetPindex();
-      Int_t negFromV0 = v0->GetNindex();
-      
-      // Add the positive tracks from the V0
-
-      if (!usedTrack[posFromV0]) {
-       
-       usedTrack[posFromV0] = kTRUE;
-
-       AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
-       esdTrack->GetPxPyPz(p_pos);
-       esdTrack->GetXYZ(pos);
-       esdTrack->GetCovarianceXYZPxPyPz(covTr);
-       esdTrack->GetESDpid(pid);
-       
-       vV0->AddDaughter(aodTrack =
-               new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(), 
-                                          p_pos, 
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          vV0,
-                                          kTRUE,  // check if this is right
-                                          kFALSE, // check if this is right
-                                          AliAODTrack::kSecondary)
-               );
-       aodTrack->ConvertAliPIDtoAODPID();
-      }
-      else {
-       cerr << "Error: event " << iEvent << " V0 " << nV0
-            << " track " << posFromV0 << " has already been used!" << endl;
-      }
-
-      // Add the negative tracks from the V0
-
-      if (!usedTrack[negFromV0]) {
-
-       usedTrack[negFromV0] = kTRUE;
-
-       AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
-       esdTrack->GetPxPyPz(p_neg);
-       esdTrack->GetXYZ(pos);
-       esdTrack->GetCovarianceXYZPxPyPz(covTr);
-       esdTrack->GetESDpid(pid);
-
-       vV0->AddDaughter(aodTrack =
-                new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(),
-                                          p_neg,
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          vV0,
-                                          kTRUE,  // check if this is right
-                                          kFALSE, // check if this is right
-                                          AliAODTrack::kSecondary)
-               );
-       aodTrack->ConvertAliPIDtoAODPID();
-      }
-      else {
-       cerr << "Error: event " << iEvent << " V0 " << nV0
-            << " track " << negFromV0 << " has already been used!" << endl;
-      }
-
-      // add it to the V0 array as well
-      Double_t d0[2] = { 999., 99.};
-      new(V0s[jV0s++]) AliAODv0(vV0, 999., 99., p_pos, p_neg, d0); // to be refined
-    }
-       V0s.Expand(jV0s);        
-    // end of the loop on V0s
-    
-    // Kinks: it is a big mess the access to the information in the kinks
-    // The loop is on the tracks in order to find the mother and daugther of each kink
-
-
-    for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
-
-      AliESDtrack * esdTrack = esd->GetTrack(iTrack);
-
-      Int_t ikink = esdTrack->GetKinkIndex(0);
-
-      if (ikink) {
-       // Negative kink index: mother, positive: daughter
-
-       // Search for the second track of the kink
-
-       for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
-
-         AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
-
-         Int_t jkink = esdTrack1->GetKinkIndex(0);
-
-         if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
-
-           // The two tracks are from the same kink
-         
-           if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
-
-           Int_t imother = -1;
-           Int_t idaughter = -1;
-
-           if (ikink<0 && jkink>0) {
-
-             imother = iTrack;
-             idaughter = jTrack;
-           }
-           else if (ikink>0 && jkink<0) {
-
-             imother = jTrack;
-             idaughter = iTrack;
-           }
-           else {
-             cerr << "Error: Wrong combination of kink indexes: "
-             << ikink << " " << jkink << endl;
-             continue;
-           }
-
-           // Add the mother track
-
-           AliAODTrack * mother = NULL;
-
-           if (!usedTrack[imother]) {
-       
-             usedTrack[imother] = kTRUE;
-       
-             AliESDtrack *esdTrack = esd->GetTrack(imother);
-             esdTrack->GetPxPyPz(p);
-             esdTrack->GetXYZ(pos);
-             esdTrack->GetCovarianceXYZPxPyPz(covTr);
-             esdTrack->GetESDpid(pid);
-
-             mother = 
-               new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(),
-                                          p,
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          primary,
-                                          kTRUE, // check if this is right
-                                          kTRUE, // check if this is right
-                                          AliAODTrack::kPrimary);
-             primary->AddDaughter(mother);
-             mother->ConvertAliPIDtoAODPID();
-           }
-           else {
-             cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
-             << " track " << imother << " has already been used!" << endl;
-           }
-
-           // Add the kink vertex
-           AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
-
-           AliAODVertex * vkink = 
-           new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
-                                                   NULL,
-                                                   0.,
-                                                   mother,
-                                                   esdTrack->GetID(), // This is the track ID of the mother's track!
-                                                   AliAODVertex::kKink);
-           // Add the daughter track
-
-           AliAODTrack * daughter = NULL;
-
-           if (!usedTrack[idaughter]) {
-       
-             usedTrack[idaughter] = kTRUE;
-       
-             AliESDtrack *esdTrack = esd->GetTrack(idaughter);
-             esdTrack->GetPxPyPz(p);
-             esdTrack->GetXYZ(pos);
-             esdTrack->GetCovarianceXYZPxPyPz(covTr);
-             esdTrack->GetESDpid(pid);
-
-             daughter = 
-               new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                          esdTrack->GetLabel(),
-                                          p,
-                                          kTRUE,
-                                          pos,
-                                          kFALSE,
-                                          covTr, 
-                                          (Short_t)esdTrack->Charge(),
-                                          esdTrack->GetITSClusterMap(), 
-                                          pid,
-                                          vkink,
-                                          kTRUE, // check if this is right
-                                          kTRUE, // check if this is right
-                                          AliAODTrack::kPrimary);
-             vkink->AddDaughter(daughter);
-             daughter->ConvertAliPIDtoAODPID();
-           }
-           else {
-             cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
-             << " track " << idaughter << " has already been used!" << endl;
-           }
-         }
-       }
-      }
-    }
-    vertices.Expand(jVertices);
-
-    // Tracks (primary and orphan)
-    for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
-
-      if (usedTrack[nTrack]) continue;
-
-      AliESDtrack *esdTrack = esd->GetTrack(nTrack);
-      esdTrack->GetPxPyPz(p);
-      esdTrack->GetXYZ(pos);
-      esdTrack->GetCovarianceXYZPxPyPz(covTr);
-      esdTrack->GetESDpid(pid);
-
-      Float_t impactXY, impactZ;
-
-      esdTrack->GetImpactParameters(impactXY,impactZ);
-
-      if (impactXY<3.) {
-       // track inside the beam pipe
-      
-       primary->AddDaughter(aodTrack =
-           new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
-                                        esdTrack->GetLabel(),
-                                        p,
-                                        kTRUE,
-                                        pos,
-                                        kFALSE,
-                                        covTr, 
-                                        (Short_t)esdTrack->Charge(),
-                                        esdTrack->GetITSClusterMap(), 
-                                        pid,
-                                        primary,
-                                        kTRUE, // check if this is right
-                                        kTRUE, // check if this is right
-                                        AliAODTrack::kPrimary)
-           );
-       aodTrack->ConvertAliPIDtoAODPID();
-      }
-      else {
-       // outside the beam pipe: orphan track
-       // Don't write them anymore!
-       continue;
-      }        
-    } // end of loop on tracks
-    
-    // muon tracks
-    Int_t nMuTracks = esd->GetNumberOfMuonTracks();
-    for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
-      
-      AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);     
-      p[0] = esdMuTrack->Px(); 
-      p[1] = esdMuTrack->Py(); 
-      p[2] = esdMuTrack->Pz();
-      pos[0] = primary->GetX(); 
-      pos[1] = primary->GetY(); 
-      pos[2] = primary->GetZ();
-      
-      // has to be changed once the muon pid is provided by the ESD
-      for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
-      
-      primary->AddDaughter(aodTrack =
-         new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
-                                            0, // no label provided
-                                            p,
-                                            kTRUE,
-                                            pos,
-                                            kFALSE,
-                                            NULL, // no covariance matrix provided
-                                            esdMuTrack->Charge(),
-                                            0, // ITSClusterMap is set below
-                                            pid,
-                                            primary,
-                                            kFALSE,  // muon tracks are not used to fit the primary vtx
-                                            kFALSE,  // not used for vertex fit
-                                            AliAODTrack::kPrimary)
-         );
-
-      aodTrack->SetHitsPatternInTrigCh(esdMuTrack->GetHitsPatternInTrigCh());
-      Int_t track2Trigger = esdMuTrack->GetMatchTrigger();
-      aodTrack->SetMatchTrigger(track2Trigger);
-      if (track2Trigger) 
-       aodTrack->SetChi2MatchTrigger(esdMuTrack->GetChi2MatchTrigger());
-      else 
-       aodTrack->SetChi2MatchTrigger(0.);
-    }
-    tracks.Expand(jTracks); // remove 'empty slots' due to unwritten tracks
-       
-    // Access to the AOD container of PMD clusters
-    TClonesArray &pmdClusters = *(aod->GetPmdClusters());
-    Int_t jPmdClusters=0;
-  
-    for (Int_t iPmd = 0; iPmd < nPmdClus; ++iPmd) {
-      // file pmd clusters, to be revised!
-      AliESDPmdTrack *pmdTrack = esd->GetPmdTrack(iPmd);
-      Int_t nLabel = 0;
-      Int_t *label = 0x0;
-      Double_t pos[3] = { pmdTrack->GetClusterX(), pmdTrack->GetClusterY(), pmdTrack->GetClusterZ() };
-      Double_t pid[9] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. }; // to be revised!
-      // type not set!
-      // assoc cluster not set
-      new(pmdClusters[jPmdClusters++]) AliAODPmdCluster(iPmd, nLabel, label, pmdTrack->GetClusterADC(), pos, pid);
-    }
-
-    // Access to the AOD container of clusters
-    TClonesArray &caloClusters = *(aod->GetCaloClusters());
-    Int_t jClusters=0;
-    for (Int_t iClust=0; iClust<nCaloClus; ++iClust) {
-
-      AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
-
-      Int_t id = cluster->GetID();
-      Int_t nLabel = 0;
-      Int_t *label = 0x0;
-      Float_t energy = cluster->E();
-      cluster->GetPosition(posF);
-      Char_t ttype=AliAODCluster::kUndef;
-
-      if (cluster->GetClusterType() == AliESDCaloCluster::kPHOSCluster) {
-       ttype=AliAODCluster::kPHOSNeutral;
-      } 
-      else if (cluster->GetClusterType() == AliESDCaloCluster::kEMCALClusterv1) {
-       ttype = AliAODCluster::kEMCALClusterv1;
-      }
+  AliTrackleter* trackleter = NULL;
+  AliReconstructor* itsReconstructor = GetReconstructor(0);
+  if (itsReconstructor && ((fRunLocalReconstruction.Contains("ITS")) || 
+                          fRunTracking.Contains("ITS") || fFillESD.Contains("ITS") )) {
+    trackleter = itsReconstructor->CreateMultFinder();
+  }
+  else {
+    AliWarning("ITS is not in reconstruction, switching off RunMultFinder");
+    fRunMultFinder = kFALSE;
+  }
 
-      
-      AliAODCaloCluster *caloCluster = new(caloClusters[jClusters++]) AliAODCaloCluster(id,
-                                                                                       nLabel,
-                                                                                       label,
-                                                                                       energy,
-                                                                                       pos,
-                                                                                       NULL,
-                                                                                       ttype);
-      
-      caloCluster->SetCaloCluster(); // to be refined!
+  return trackleter;
+}
 
-    } 
-    caloClusters.Expand(jClusters); // resize TObjArray to 'remove' slots for pseudo clusters   
-    // end of loop on calo clusters
+//_____________________________________________________________________________
+Bool_t AliReconstruction::CreateTrackers(const TString& detectors)
+{
+// create the trackers
+       AliInfo("Creating trackers");
 
-    // fill EMCAL cell info
-    if (esd->GetEMCALCells()) { // protection against missing ESD information
-      AliESDCaloCells &esdEMcells = *(esd->GetEMCALCells());
-      Int_t nEMcell = esdEMcells.GetNumberOfCells() ;
-      
-      AliAODCaloCells &aodEMcells = *(aod->GetEMCALCells());
-      aodEMcells.CreateContainer(nEMcell);
-      aodEMcells.SetType(AliAODCaloCells::kEMCAL);
-      for (Int_t iCell = 0; iCell < nEMcell; iCell++) {      
-       aodEMcells.SetCell(iCell,esdEMcells.GetCellNumber(iCell),esdEMcells.GetAmplitude(iCell));
-      }
-      aodEMcells.Sort();
+  TString detStr = detectors;
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+    AliReconstructor* reconstructor = GetReconstructor(iDet);
+    if (!reconstructor) continue;
+    TString detName = fgkDetectorName[iDet];
+    if (detName == "HLT") {
+      fRunHLTTracking = kTRUE;
+      continue;
+    }
+    if (detName == "MUON") {
+      fRunMuonTracking = kTRUE;
+      continue;
     }
 
-    // fill PHOS cell info
-    if (esd->GetPHOSCells()) { // protection against missing ESD information
-      AliESDCaloCells &esdPHcells = *(esd->GetPHOSCells());
-      Int_t nPHcell = esdPHcells.GetNumberOfCells() ;
-      
-      AliAODCaloCells &aodPHcells = *(aod->GetPHOSCells());
-      aodPHcells.CreateContainer(nPHcell);
-      aodPHcells.SetType(AliAODCaloCells::kPHOS);
-      for (Int_t iCell = 0; iCell < nPHcell; iCell++) {      
-       aodPHcells.SetCell(iCell,esdPHcells.GetCellNumber(iCell),esdPHcells.GetAmplitude(iCell));
-      }
-      aodPHcells.Sort();
+    fTracker[iDet] = reconstructor->CreateTracker();
+    if (!fTracker[iDet] && (iDet < 7)) {
+      AliWarning(Form("couldn't create a tracker for %s", detName.Data()));
+      if (fStopOnError) return kFALSE;
     }
+    AliSysInfo::AddStamp(Form("LTracker%s",fgkDetectorName[iDet]), iDet,0);
+  }
 
-    // tracklets    
-    AliAODTracklets &SPDTracklets = *(aod->GetTracklets());
-    const AliMultiplicity *mult = esd->GetMultiplicity();
-    if (mult) {
-      if (mult->GetNumberOfTracklets()>0) {
-       SPDTracklets.CreateContainer(mult->GetNumberOfTracklets());
+  return kTRUE;
+}
 
-       for (Int_t n=0; n<mult->GetNumberOfTracklets(); n++) {
-         SPDTracklets.SetTracklet(n, mult->GetTheta(n), mult->GetPhi(n), mult->GetDeltaPhi(n), mult->GetLabel(n));
-       }
-      }
-    } else {
-      Printf("ERROR: AliMultiplicity could not be retrieved from ESD");
-    }
+//_____________________________________________________________________________
+void AliReconstruction::CleanUp()
+{
+// delete trackers and the run loader and close and delete the file
 
-    delete [] usedTrack;
-    delete [] usedV0;
-    delete [] usedKink;
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+    delete fReconstructor[iDet];
+    fReconstructor[iDet] = NULL;
+    fLoader[iDet] = NULL;
+    delete fTracker[iDet];
+    fTracker[iDet] = NULL;
+  }
+  delete fRunInfo;
+  fRunInfo = NULL;
 
-    // fill the tree for this event
-    aodTree->Fill();
-  } // end of event loop
+  delete fSPDTrackleter;
+  fSPDTrackleter = NULL;
 
-  aodTree->GetUserInfo()->Add(aod);
+  delete ftVertexer;
+  ftVertexer = NULL;
+  
+  delete fRunLoader;
+  fRunLoader = NULL;
+  delete fRawReader;
+  fRawReader = NULL;
+  delete fParentRawReader;
+  fParentRawReader=NULL;
 
-  // write the tree to the specified file
-  aodFile = aodTree->GetCurrentFile();
-  aodFile->cd();
-  aodTree->Write();
+  if (ffile) {
+    ffile->Close();
+    delete ffile;
+    ffile = NULL;
+  }
 
-  return;
+  if (AliQAManager::QAManager())
+    AliQAManager::QAManager()->ShowQA() ; 
+  AliQAManager::Destroy() ; 
+  
 }
 
 void AliReconstruction::WriteAlignmentData(AliESDEvent* esd)
 {
   // Write space-points which are then used in the alignment procedures
-  // For the moment only ITS, TRD and TPC
+  // For the moment only ITS, TPC, TRD and TOF
 
-  // Load TOF clusters
-  if (fTracker[3]){
-    fLoader[3]->LoadRecPoints("read");
-    TTree* tree = fLoader[3]->TreeR();
-    if (!tree) {
-      AliError(Form("Can't get the %s cluster tree", fgkDetectorName[3]));
-      return;
-    }
-    fTracker[3]->LoadClusters(tree);
-  }
   Int_t ntracks = esd->GetNumberOfTracks();
   for (Int_t itrack = 0; itrack < ntracks; itrack++)
     {
       AliESDtrack *track = esd->GetTrack(itrack);
       Int_t nsp = 0;
       Int_t idx[200];
-      for (Int_t iDet = 3; iDet >= 0; iDet--)
-       nsp += track->GetNcls(iDet);
+      for (Int_t i=0; i<200; ++i) idx[i] = -1; //PH avoid uninitialized values
+      for (Int_t iDet = 5; iDet >= 0; iDet--) {// TOF, TRD, TPC, ITS clusters
+          nsp += (iDet==GetDetIndex("TRD")) ? track->GetTRDntracklets():track->GetNcls(iDet);
+
+          if (iDet==GetDetIndex("ITS")) { // ITS "extra" clusters
+             track->GetClusters(iDet,idx);
+             for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nsp++;
+          }  
+      }
+
       if (nsp) {
        AliTrackPointArray *sp = new AliTrackPointArray(nsp);
        track->SetTrackPointArray(sp);
        Int_t isptrack = 0;
-       for (Int_t iDet = 3; iDet >= 0; iDet--) {
+       for (Int_t iDet = 5; iDet >= 0; iDet--) {
          AliTracker *tracker = fTracker[iDet];
          if (!tracker) continue;
-         Int_t nspdet = track->GetNcls(iDet);
+         Int_t nspdet = (iDet==GetDetIndex("TRD")) ? track->GetTRDtracklets(idx):track->GetClusters(iDet,idx);
+
+         if (iDet==GetDetIndex("ITS")) // ITS "extra" clusters             
+             for (Int_t i=6; i<12; i++) if(idx[i] >= 0) nspdet++;
+
          if (nspdet <= 0) continue;
-         track->GetClusters(iDet,idx);
          AliTrackPoint p;
          Int_t isp = 0;
          Int_t isp2 = 0;
          while (isp2 < nspdet) {
-           Bool_t isvalid;
+           Bool_t isvalid=kTRUE;
+
+            Int_t index=idx[isp++];
+            if (index < 0) continue;
+
             TString dets = fgkDetectorName[iDet];
             if ((fUseTrackingErrorsForAlignment.CompareTo(dets) == 0) ||
             fUseTrackingErrorsForAlignment.BeginsWith(dets+" ") ||
             fUseTrackingErrorsForAlignment.EndsWith(" "+dets) ||
             fUseTrackingErrorsForAlignment.Contains(" "+dets+" ")) {
-              isvalid = tracker->GetTrackPointTrackingError(idx[isp2],p,track);
+              isvalid = tracker->GetTrackPointTrackingError(index,p,track);
            } else {
-             isvalid = tracker->GetTrackPoint(idx[isp2],p); 
+             isvalid = tracker->GetTrackPoint(index,p); 
            } 
            isp2++;
-           const Int_t kNTPCmax = 159;
-           if (iDet==1 && isp2>kNTPCmax) break;   // to be fixed
            if (!isvalid) continue;
-           sp->AddPoint(isptrack,&p); isptrack++; isp++;
+           if (iDet==GetDetIndex("ITS") && (isp-1)>=6) p.SetExtra();
+           sp->AddPoint(isptrack,&p); isptrack++;
          }
        }       
       }
     }
-  if (fTracker[3]){
-    fTracker[3]->UnloadClusters();
-    fLoader[3]->UnloadRecPoints();
-  }
 }
 
 //_____________________________________________________________________________
@@ -2870,177 +3316,687 @@ void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESDEvent* esd)
 
 }
 
-TNamed* AliReconstruction::CopyFileToTNamed(TString fPath,TString fName){
-  // Dump a file content into a char in TNamed
-  ifstream in;
-  in.open(fPath.Data(),ios::in | ios::binary|ios::ate);
-  Int_t kBytes = (Int_t)in.tellg();
-  printf("Size: %d \n",kBytes);
-  TNamed *fn = 0;
-  if(in.good()){
-    char* memblock = new char [kBytes];
-    in.seekg (0, ios::beg);
-    in.read (memblock, kBytes);
-    in.close();
-    TString fData(memblock,kBytes);
-    fn = new TNamed(fName,fData);
-    printf("fData Size: %d \n",fData.Sizeof());
-    printf("fName Size: %d \n",fName.Sizeof());
-    printf("fn    Size: %d \n",fn->Sizeof());
-    delete[] memblock;
-  }
-  else{
-    AliInfo(Form("Could not Open %s\n",fPath.Data()));
+//_____________________________________________________________________________
+// void AliReconstruction::CheckQA()
+// {
+// check the QA of SIM for this run and remove the detectors 
+// with status Fatal
+  
+//     TString newRunLocalReconstruction ; 
+//     TString newRunTracking ;
+//     TString newFillESD ;
+//      
+//     for (Int_t iDet = 0; iDet < AliQAv1::kNDET; iDet++) {
+//             TString detName(AliQAv1::GetDetName(iDet)) ;
+//             AliQAv1 * qa = AliQAv1::Instance(AliQAv1::DETECTORINDEX_t(iDet)) ;       
+//      if ( qa->IsSet(AliQAv1::DETECTORINDEX_t(iDet), AliQAv1::kSIM, specie, AliQAv1::kFATAL)) {
+//        AliInfo(Form("QA status for %s %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", 
+//                   detName.Data(), AliRecoParam::GetEventSpecieName(es))) ;
+//                     } else {
+//                     if ( fRunLocalReconstruction.Contains(AliQAv1::GetDetName(iDet)) || 
+//                                     fRunLocalReconstruction.Contains("ALL") )  {
+//                             newRunLocalReconstruction += detName ; 
+//                             newRunLocalReconstruction += " " ;                      
+//                     }
+//                     if ( fRunTracking.Contains(AliQAv1::GetDetName(iDet)) || 
+//                                     fRunTracking.Contains("ALL") )  {
+//                             newRunTracking += detName ; 
+//                             newRunTracking += " " ;                         
+//                     }
+//                     if ( fFillESD.Contains(AliQAv1::GetDetName(iDet)) || 
+//                                     fFillESD.Contains("ALL") )  {
+//                             newFillESD += detName ; 
+//                             newFillESD += " " ;                     
+//                     }
+//             }
+//     }
+//     fRunLocalReconstruction = newRunLocalReconstruction ; 
+//     fRunTracking            = newRunTracking ; 
+//     fFillESD                = newFillESD ; 
+// }
+
+//_____________________________________________________________________________
+Int_t AliReconstruction::GetDetIndex(const char* detector)
+{
+  // return the detector index corresponding to detector
+  Int_t index = -1 ; 
+  for (index = 0; index < kNDetectors ; index++) {
+    if ( strcmp(detector, fgkDetectorName[index]) == 0 )
+       break ; 
+  }    
+  return index ; 
+}
+//_____________________________________________________________________________
+Bool_t AliReconstruction::FinishPlaneEff() {
+ //
+ // Here execute all the necessary operationis, at the end of the tracking phase,
+ // in case that evaluation of PlaneEfficiencies was required for some detector.
+ // E.g., write into a DataBase file the PlaneEfficiency which have been evaluated.
+ //
+ // This Preliminary version works only FOR ITS !!!!!
+ // other detectors (TOF,TRD, etc. have to develop their specific codes)
+ //
+ //  Input: none
+ //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
+ //
+ Bool_t ret=kFALSE;
+ TString detStr = fLoadCDB;
+ //for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
+ for (Int_t iDet = 0; iDet < 1; iDet++) { // for the time being only ITS
+   if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+   if(fTracker[iDet] && fTracker[iDet]->GetPlaneEff()) {
+      AliPlaneEff *planeeff=fTracker[iDet]->GetPlaneEff();
+      TString name=planeeff->GetName();
+      name+=".root";
+      TFile* pefile = TFile::Open(name, "RECREATE");
+      ret=(Bool_t)planeeff->Write();
+      pefile->Close();
+      if(planeeff->GetCreateHistos()) {
+        TString hname=planeeff->GetName();
+        hname+="Histo.root";
+        ret*=planeeff->WriteHistosToFile(hname,"RECREATE");
+      }
+   }
+   if(fSPDTrackleter) {
+     AliPlaneEff *planeeff=fSPDTrackleter->GetPlaneEff();
+      TString name="AliITSPlaneEffSPDtracklet.root";
+      TFile* pefile = TFile::Open(name, "RECREATE");
+      ret=(Bool_t)planeeff->Write();
+      pefile->Close();
+      AliESDEvent *dummy=NULL;
+      ret=(Bool_t)fSPDTrackleter->PostProcess(dummy); // take care of writing other files
+   }
+ }
+ return ret;
+}
+//_____________________________________________________________________________
+Bool_t AliReconstruction::InitPlaneEff() {
+//
+ // Here execute all the necessary operations, before of the tracking phase,
+ // for the evaluation of PlaneEfficiencies, in case required for some detectors.
+ // E.g., read from a DataBase file a first evaluation of the PlaneEfficiency
+ // which should be updated/recalculated.
+ //
+ // This Preliminary version will work only FOR ITS !!!!!
+ // other detectors (TOF,TRD, etc. have to develop their specific codes)
+ //
+ //  Input: none
+ //  Return: kTRUE if all operations have been done properly, kFALSE otherwise
+ //
+
+  fSPDTrackleter = NULL;
+  TString detStr = fLoadCDB;
+  if (IsSelected(fgkDetectorName[0], detStr)) {
+    AliReconstructor* itsReconstructor = GetReconstructor(0);
+    if (itsReconstructor) {
+      fSPDTrackleter = itsReconstructor->CreateTrackleter(); // this is NULL unless required in RecoParam
+    }
+    if (fSPDTrackleter) {
+      AliInfo("Trackleter for SPD has been created");
+    }
   }
+ return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliReconstruction::InitAliEVE()
+{
+  // This method should be called only in case 
+  // AliReconstruction is run
+  // within the alieve environment.
+  // It will initialize AliEVE in a way
+  // so that it can visualize event processed
+  // by AliReconstruction.
+  // The return flag shows whenever the
+  // AliEVE initialization was successful or not.
+
+  TString macroPath;
+  macroPath.Form(".:%s:%s/EVE/macros/",
+                gROOT->GetMacroPath(),
+                gSystem->ExpandPathName("$ALICE_ROOT"));
+  gROOT->SetMacroPath(macroPath.Data());
+
+  TString macroStr("alieve_online.C");
+  AliInfo(Form("Loading AliEVE macro: %s (%s)",macroStr.Data(), 
+              gSystem->Which(gROOT->GetMacroPath(), macroStr.Data())));
+  if (gROOT->LoadMacro(macroStr.Data()) != 0) return kFALSE;
+
+  gROOT->ProcessLine("if (!AliEveEventManager::GetMaster()){new AliEveEventManager();AliEveEventManager::GetMaster()->AddNewEventCommand(\"alieve_online_on_new_event()\");gEve->AddEvent(AliEveEventManager::GetMaster());};");
+  gROOT->ProcessLine("alieve_online_init()");
 
-  return fn;
+  return kTRUE;
+}
+  
+//_____________________________________________________________________________
+void AliReconstruction::RunAliEVE()
+{
+  // Runs AliEVE visualisation of
+  // the current event.
+  // Should be executed only after
+  // successful initialization of AliEVE.
+
+  AliInfo("Running AliEVE...");
+  gROOT->ProcessLine(Form("AliEveEventManager::GetMaster()->SetEvent((AliRunLoader*)%p,(AliRawReader*)%p,(AliESDEvent*)%p,(AliESDfriend*)%p);",fRunLoader,fRawReader,fesd,fesdf));
+  gSystem->Run();
 }
 
-void AliReconstruction::TNamedToFile(TTree* fTree, TString fName){
-  // This is not really needed in AliReconstruction at the moment
-  // but can serve as a template
+//_____________________________________________________________________________
+Bool_t AliReconstruction::SetRunQA(TString detAndAction) 
+{
+       // Allows to run QA for a selected set of detectors
+       // and a selected set of tasks among RAWS, DIGITSR, RECPOINTS and ESDS
+       // all selected detectors run the same selected tasks
+       
+       if (!detAndAction.Contains(":")) {
+               AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
+               fRunQA = kFALSE ;
+               return kFALSE ;                 
+       }
+       Int_t colon = detAndAction.Index(":") ; 
+       fQADetectors = detAndAction(0, colon) ; 
+       fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
+       if (fQATasks.Contains("ALL") ) {
+               fQATasks = Form("%d %d %d %d", AliQAv1::kRAWS, AliQAv1::kDIGITSR, AliQAv1::kRECPOINTS, AliQAv1::kESDS) ; 
+       } else {
+               fQATasks.ToUpper() ; 
+               TString tempo("") ; 
+               if ( fQATasks.Contains("RAW") ) 
+                       tempo = Form("%d ", AliQAv1::kRAWS) ; 
+               if ( fQATasks.Contains("DIGIT") ) 
+                       tempo += Form("%d ", AliQAv1::kDIGITSR) ; 
+               if ( fQATasks.Contains("RECPOINT") ) 
+                       tempo += Form("%d ", AliQAv1::kRECPOINTS) ; 
+               if ( fQATasks.Contains("ESD") ) 
+                       tempo += Form("%d ", AliQAv1::kESDS) ; 
+               fQATasks = tempo ; 
+               if (fQATasks.IsNull()) {
+                       AliInfo("No QA requested\n")  ;
+                       fRunQA = kFALSE ;
+                       return kTRUE ; 
+               }
+       }       
+       TString tempo(fQATasks) ; 
+       tempo.ReplaceAll(Form("%d", AliQAv1::kRAWS), AliQAv1::GetTaskName(AliQAv1::kRAWS))      ;
+       tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITSR), AliQAv1::GetTaskName(AliQAv1::kDIGITSR)) ;      
+       tempo.ReplaceAll(Form("%d", AliQAv1::kRECPOINTS), AliQAv1::GetTaskName(AliQAv1::kRECPOINTS)) ;  
+       tempo.ReplaceAll(Form("%d", AliQAv1::kESDS), AliQAv1::GetTaskName(AliQAv1::kESDS)) ;    
+       AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
+       fRunQA = kTRUE ;
+       return kTRUE; 
+} 
 
-  TList *fList = fTree->GetUserInfo();
-  TNamed *fn = (TNamed*)fList->FindObject(fName.Data());
-  printf("fn Size: %d \n",fn->Sizeof());
+//_____________________________________________________________________________
+Bool_t AliReconstruction::InitRecoParams() 
+{
+  // The method accesses OCDB and retrieves all
+  // the available reco-param objects from there.
 
-  TString fTmp(fn->GetName()); // to be 100% sure in principle fName also works
-  const char* cdata = fn->GetTitle();
-  printf("fTmp Size %d\n",fTmp.Sizeof());
+  Bool_t isOK = kTRUE;
 
-  int size = fn->Sizeof()-fTmp.Sizeof()-sizeof(UChar_t)-sizeof(Int_t); // see dfinition of TString::SizeOf()...
-  printf("calculated size %d\n",size);
-  ofstream out(fName.Data(),ios::out | ios::binary);
-  out.write(cdata,size);
-  out.close();
+  if (fRecoParam.GetDetRecoParamArray(kNDetectors)) {
+    AliInfo("Using custom GRP reconstruction parameters");
+  }
+  else {
+    AliInfo("Loading GRP reconstruction parameter objects");
 
-}
+    AliCDBPath path("GRP","Calib","RecoParam");
+    AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
+    if(!entry){ 
+      AliWarning("Couldn't find GRP RecoParam entry in OCDB");
+      isOK = kFALSE;
+    }
+    else {
+      TObject *recoParamObj = entry->GetObject();
+      if (dynamic_cast<TObjArray*>(recoParamObj)) {
+       // GRP has a normal TobjArray of AliDetectorRecoParam objects
+       // Registering them in AliRecoParam
+       fRecoParam.AddDetRecoParamArray(kNDetectors,dynamic_cast<TObjArray*>(recoParamObj));
+      }
+      else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
+       // GRP has only onse set of reco parameters
+       // Registering it in AliRecoParam
+       AliInfo("Single set of GRP reconstruction parameters found");
+       dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
+       fRecoParam.AddDetRecoParam(kNDetectors,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
+      }
+      else {
+       AliError("No valid GRP RecoParam object found in the OCDB");
+       isOK = kFALSE;
+      }
+      entry->SetOwner(0);
+    }
+  }
+
+  TString detStr = fLoadCDB;
+  for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
+
+    if (!IsSelected(fgkDetectorName[iDet], detStr)) continue;
+
+    if (fRecoParam.GetDetRecoParamArray(iDet)) {
+      AliInfo(Form("Using custom reconstruction parameters for detector %s",fgkDetectorName[iDet]));
+      continue;
+    }
+
+    AliInfo(Form("Loading reconstruction parameter objects for detector %s",fgkDetectorName[iDet]));
   
+    AliCDBPath path(fgkDetectorName[iDet],"Calib","RecoParam");
+    AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
+    if(!entry){ 
+      AliWarning(Form("Couldn't find RecoParam entry in OCDB for detector %s",fgkDetectorName[iDet]));
+      isOK = kFALSE;
+    }
+    else {
+      TObject *recoParamObj = entry->GetObject();
+      if (dynamic_cast<TObjArray*>(recoParamObj)) {
+       // The detector has a normal TobjArray of AliDetectorRecoParam objects
+       // Registering them in AliRecoParam
+       fRecoParam.AddDetRecoParamArray(iDet,dynamic_cast<TObjArray*>(recoParamObj));
+      }
+      else if (dynamic_cast<AliDetectorRecoParam*>(recoParamObj)) {
+       // The detector has only onse set of reco parameters
+       // Registering it in AliRecoParam
+       AliInfo(Form("Single set of reconstruction parameters found for detector %s",fgkDetectorName[iDet]));
+       dynamic_cast<AliDetectorRecoParam*>(recoParamObj)->SetAsDefault();
+       fRecoParam.AddDetRecoParam(iDet,dynamic_cast<AliDetectorRecoParam*>(recoParamObj));
+      }
+      else {
+       AliError(Form("No valid RecoParam object found in the OCDB for detector %s",fgkDetectorName[iDet]));
+       isOK = kFALSE;
+      }
+      entry->SetOwner(0);
+      //      FIX ME: We have to disable the unloading of reco-param CDB
+      //      entries because QA framework is using them. Has to be fix in
+      //      a way that the QA takes the objects already constructed in
+      //      this method.
+      //      AliCDBManager::Instance()->UnloadFromCache(path.GetPath());
+    }
+  }
+
+  if (AliDebugLevel() > 0) fRecoParam.Print();
+
+  return isOK;
+}
+
 //_____________________________________________________________________________
-AliQADataMakerRec * AliReconstruction::GetQADataMaker(Int_t iDet)
+Bool_t AliReconstruction::GetEventInfo() 
 {
- // get the quality assurance data maker object and the loader for a detector
+  // Fill the event info object
+  // ...
+  AliCodeTimerAuto("",0)
 
-  if (fQADataMaker[iDet]) 
-    return fQADataMaker[iDet];
+  AliCentralTrigger *aCTP = NULL;
+  if (fRawReader) {
+    fEventInfo.SetEventType(fRawReader->GetType());
+
+    ULong64_t mask = fRawReader->GetClassMask();
+    fEventInfo.SetTriggerMask(mask);
+    UInt_t clmask = fRawReader->GetDetectorPattern()[0];
+    fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(clmask));
+
+    aCTP = new AliCentralTrigger();
+    TString configstr("");
+    if (!aCTP->LoadConfiguration(configstr)) { // Load CTP config from OCDB
+      AliError("No trigger configuration found in OCDB! The trigger configuration information will not be used!");
+      delete aCTP;
+      return kFALSE;
+    }
+    aCTP->SetClassMask(mask);
+    aCTP->SetClusterMask(clmask);
+  }
+  else {
+    fEventInfo.SetEventType(AliRawEventHeaderBase::kPhysicsEvent);
+
+    if (fRunLoader && (!fRunLoader->LoadTrigger())) {
+      aCTP = fRunLoader->GetTrigger();
+      fEventInfo.SetTriggerMask(aCTP->GetClassMask());
+      // get inputs from actp - just get
+      AliESDHeader* esdheader = fesd->GetHeader();
+      esdheader->SetL0TriggerInputs(aCTP->GetL0TriggerInputs());
+      esdheader->SetL1TriggerInputs(aCTP->GetL1TriggerInputs());
+      esdheader->SetL2TriggerInputs(aCTP->GetL2TriggerInputs());
+      fEventInfo.SetTriggerCluster(AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask()));
+    }
+    else {
+      AliWarning("No trigger can be loaded! The trigger information will not be used!");
+      return kFALSE;
+    }
+  }
 
-  AliQADataMakerRec * qadm = NULL;
-  if (iDet == fgkNDetectors) { //Global QA
-     qadm = new AliGlobalQADataMaker();
-     fQADataMaker[iDet] = qadm;
-     return qadm;
+  AliTriggerConfiguration *config = aCTP->GetConfiguration();
+  if (!config) {
+    AliError("No trigger configuration has been found! The trigger configuration information will not be used!");
+    if (fRawReader) delete aCTP;
+    return kFALSE;
   }
 
-  // load the QA data maker object
-  TPluginManager* pluginManager = gROOT->GetPluginManager();
-  TString detName = fgkDetectorName[iDet];
-  TString qadmName = "Ali" + detName + "QADataMakerRec";
-  if (gAlice && !gAlice->GetDetector(detName) && (detName != "HLT")) 
-    return NULL;
+  UChar_t clustmask = 0;
+  TString trclasses;
+  ULong64_t trmask = fEventInfo.GetTriggerMask();
+  const TObjArray& classesArray = config->GetClasses();
+  Int_t nclasses = classesArray.GetEntriesFast();
+  for( Int_t iclass=0; iclass < nclasses; iclass++ ) {
+    AliTriggerClass* trclass = (AliTriggerClass*)classesArray.At(iclass);
+    if (trclass && trclass->GetMask()>0) {
+      Int_t trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
+      fesd->SetTriggerClass(trclass->GetName(),trindex);
+      if (fRawReader) fRawReader->LoadTriggerClass(trclass->GetName(),trindex);
+      if (trmask & (1ull << trindex)) {
+       trclasses += " ";
+       trclasses += trclass->GetName();
+       trclasses += " ";
+       clustmask |= trclass->GetCluster()->GetClusterMask();
+      }
+    }
+  }
+  fEventInfo.SetTriggerClasses(trclasses);
 
-  // first check if a plugin is defined for the quality assurance data maker
-  TPluginHandler* pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
-  // if not, add a plugin for it
-  if (!pluginHandler) {
-    AliDebug(1, Form("defining plugin for %s", qadmName.Data()));
-    TString libs = gSystem->GetLibraries();
-    if (libs.Contains("lib" + detName + "base.so") ||
-       (gSystem->Load("lib" + detName + "base.so") >= 0)) {
-      pluginManager->AddHandler("AliQADataMakerRec", detName, 
-                               qadmName, detName + "qadm", qadmName + "()");
-    } else {
-      pluginManager->AddHandler("AliQADataMakerRec", detName, 
-                               qadmName, detName, qadmName + "()");
+  // Write names of active trigger inputs in ESD Header
+  const TObjArray& inputsArray = config->GetInputs(); 
+  Int_t ninputs = inputsArray.GetEntriesFast();
+  for( Int_t iinput=0; iinput < ninputs; iinput++ ) {
+    AliTriggerInput* trginput = (AliTriggerInput*)inputsArray.At(iinput);
+    if (trginput && trginput->GetMask()>0) {
+      Int_t inputIndex = (Int_t)TMath::Nint(TMath::Log2(trginput->GetMask()));
+      AliESDHeader* headeresd = fesd->GetHeader();
+      Int_t trglevel = (Int_t)trginput->GetLevel();
+      if (trglevel == 0) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex);
+      if (trglevel == 1) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+24);
+      if (trglevel == 2) headeresd->SetActiveTriggerInputs(trginput->GetInputName(), inputIndex+48);
     }
-    pluginHandler = pluginManager->FindHandler("AliQADataMakerRec", detName);
   }
-  if (pluginHandler && (pluginHandler->LoadPlugin() == 0)) {
-    qadm = (AliQADataMakerRec *) pluginHandler->ExecPlugin(0);
+
+  // Set the information in ESD
+  fesd->SetTriggerMask(trmask);
+  fesd->SetTriggerCluster(clustmask);
+
+  if (!aCTP->CheckTriggeredDetectors()) {
+    if (fRawReader) delete aCTP;
+    return kFALSE;
+  }    
+
+  if (fRawReader) delete aCTP;
+
+  // We have to fill also the HLT decision here!!
+  // ...
+
+  return kTRUE;
+}
+
+const char *AliReconstruction::MatchDetectorList(const char *detectorList, UInt_t detectorMask)
+{
+  // Match the detector list found in the rec.C or the default 'ALL'
+  // to the list found in the GRP (stored there by the shuttle PP which
+  // gets the information from ECS)
+  static TString resultList;
+  TString detList = detectorList;
+
+  resultList = "";
+
+  for(Int_t iDet = 0; iDet < (AliDAQ::kNDetectors-1); iDet++) {
+    if ((detectorMask >> iDet) & 0x1) {
+      TString det = AliDAQ::OfflineModuleName(iDet);
+      if ((detList.CompareTo("ALL") == 0) ||
+         ((detList.BeginsWith("ALL ") ||
+           detList.EndsWith(" ALL") ||
+           detList.Contains(" ALL ")) &&
+          !(detList.BeginsWith("-"+det+" ") ||
+            detList.EndsWith(" -"+det) ||
+            detList.Contains(" -"+det+" "))) ||
+         (detList.CompareTo(det) == 0) ||
+         detList.BeginsWith(det+" ") ||
+         detList.EndsWith(" "+det) ||
+         detList.Contains( " "+det+" " )) {
+       if (!resultList.EndsWith(det + " ")) {
+         resultList += det;
+         resultList += " ";
+       }
+      }               
+    }
+  }
+
+  // HLT
+  if ((detectorMask >> AliDAQ::kHLTId) & 0x1) {
+    TString hltDet = AliDAQ::OfflineModuleName(AliDAQ::kNDetectors-1);
+    if ((detList.CompareTo("ALL") == 0) ||
+       ((detList.BeginsWith("ALL ") ||
+         detList.EndsWith(" ALL") ||
+         detList.Contains(" ALL ")) &&
+        !(detList.BeginsWith("-"+hltDet+" ") ||
+          detList.EndsWith(" -"+hltDet) ||
+          detList.Contains(" -"+hltDet+" "))) ||
+       (detList.CompareTo(hltDet) == 0) ||
+       detList.BeginsWith(hltDet+" ") ||
+       detList.EndsWith(" "+hltDet) ||
+       detList.Contains( " "+hltDet+" " )) {
+      resultList += hltDet;
+    }
   }
 
-  fQADataMaker[iDet] = qadm;
+  return resultList.Data();
 
-  return qadm;
 }
 
-//_____________________________________________________________________________
-Bool_t AliReconstruction::RunQA(const char* detectors, AliESDEvent *& esd)
+//______________________________________________________________________________
+void AliReconstruction::Abort(const char *method, EAbort what)
 {
-  // run the Quality Assurance data producer
+  // Abort processing. If what = kAbortProcess, the Process() loop will be
+  // aborted. If what = kAbortFile, the current file in a chain will be
+  // aborted and the processing will continue with the next file, if there
+  // is no next file then Process() will be aborted. Abort() can also  be
+  // called from Begin(), SlaveBegin(), Init() and Notify(). After abort
+  // the SlaveTerminate() and Terminate() are always called. The abort flag
+  // can be checked in these methods using GetAbort().
+  //
+  // The method is overwritten in AliReconstruction for better handling of
+  // reco specific errors 
 
-  AliCodeTimerAuto("")
-  TString detStr = detectors;
-  for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) {
-   if (!IsSelected(fgkDetectorName[iDet], detStr)) 
-     continue;
-   AliQADataMakerRec * qadm = GetQADataMaker(iDet);
-   if (!qadm) 
-     continue;
-   AliCodeTimerStart(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
-   AliInfo(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
-    
-   qadm->Exec(AliQA::kESDS, esd) ; 
-   qadm->Increment() ; 
+  if (!fStopOnError) return;
 
-   AliCodeTimerStop(Form("running quality assurance data maker for %s", fgkDetectorName[iDet]));
- }
- if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
-   AliError(Form("the following detectors were not found: %s",
-                detStr.Data()));
-   if (fStopOnError) 
-     return kFALSE;
- }
- return kTRUE;
-  
+  CleanUp();
+
+  TString whyMess = method;
+  whyMess += " failed! Aborting...";
+
+  AliError(whyMess.Data());
+
+  fAbort = what;
+  TString mess = "Abort";
+  if (fAbort == kAbortProcess)
+    mess = "AbortProcess";
+  else if (fAbort == kAbortFile)
+    mess = "AbortFile";
+
+  Info(mess, whyMess.Data());
 }
 
-//_____________________________________________________________________________
-void AliReconstruction::CheckQA()
+//______________________________________________________________________________
+Bool_t AliReconstruction::ProcessEvent(void* event)
 {
-// check the QA of SIM for this run and remove the detectors 
-// with status Fatal
-  
-       TString newRunLocalReconstruction ; 
-       TString newRunTracking ;
-       TString newFillESD ;
-        
-       for (Int_t iDet = 0; iDet < AliQA::kNDET; iDet++) {
-               TString detName(AliQA::GetDetName(iDet)) ;
-               AliQA * qa = AliQA::Instance(AliQA::DETECTORINDEX(iDet)) ; 
-               if ( qa->IsSet(AliQA::DETECTORINDEX(iDet), AliQA::kSIM, AliQA::kFATAL)) {
-                               AliInfo(Form("QA status for %s in Hits and/or SDIGITS  and/or Digits was Fatal; No reconstruction performed", detName.Data())) ;
-               } else {
-                       if ( fRunLocalReconstruction.Contains(AliQA::GetDetName(iDet)) || 
-                                       fRunLocalReconstruction.Contains("ALL") )  {
-                               newRunLocalReconstruction += detName ; 
-                               newRunLocalReconstruction += " " ;                      
-                       }
-                       if ( fRunTracking.Contains(AliQA::GetDetName(iDet)) || 
-                                       fRunTracking.Contains("ALL") )  {
-                               newRunTracking += detName ; 
-                               newRunTracking += " " ;                         
-                       }
-                       if ( fFillESD.Contains(AliQA::GetDetName(iDet)) || 
-                                       fFillESD.Contains("ALL") )  {
-                               newFillESD += detName ; 
-                               newFillESD += " " ;                     
-                       }
-               }
-       }
-       fRunLocalReconstruction = newRunLocalReconstruction ; 
-       fRunTracking            = newRunTracking ; 
-       fFillESD                = newFillESD ; 
+  // Method that is used in case the event loop
+  // is steered from outside, for example by AMORE
+  // 'event' is a pointer to the DATE event in the memory
+
+  if (fRawReader) delete fRawReader;
+  fRawReader = new AliRawReaderDate(event);
+  fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());  
+  delete fRawReader;
+  fRawReader = NULL;
+
+  return fStatus;
 }
 
-//_____________________________________________________________________________
-Int_t AliReconstruction::GetDetIndex(const char* detector)
+//______________________________________________________________________________
+Bool_t AliReconstruction::ParseOutput()
 {
-  // return the detector index corresponding to detector
-  Int_t index = -1 ; 
-  for (index = 0; index < fgkNDetectors ; index++) {
-    if ( strcmp(detector, fgkDetectorName[index]) == 0 )
-       break ; 
-  }    
-  return index ; 
+  // The method parses the output file
+  // location string in order to steer
+  // properly the selector
+
+  TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
+  TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
+
+  if (re1.Match(fESDOutput) == 4) {
+    // root archive with output files stored and regustered
+    // in proof dataset
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
+    AliInfo(Form("%s files will be stored within %s in dataset %s",
+                re1[2].Data(),
+                re1[1].Data(),
+                re1[3].Data()));
+  }
+  else if (re2.Match(fESDOutput) == 3) {
+    // output file stored and registered
+    // in proof dataset
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
+    gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
+    AliInfo(Form("%s will be stored in dataset %s",
+                (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
+                re2[2].Data()));
+  }
+  else {
+    if (fESDOutput.IsNull()) {
+      // Output location not given.
+      // Assuming xrootd has been already started and
+      // the output file has to be sent back
+      // to the client machine
+      TString esdUrl(Form("root://%s/%s/",
+                         TUrl(gSystem->HostName()).GetHostFQDN(),
+                         gSystem->pwd()));
+      gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
+      gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
+      AliInfo(Form("AliESDs.root will be stored in %s",
+                  esdUrl.Data()));
+    }
+    else {
+      // User specified an output location.
+      // Ones has just to parse it here
+      TUrl outputUrl(fESDOutput.Data());
+      TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
+      gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
+      TString outputLocation(outputUrl.GetUrl());
+      outputLocation.ReplaceAll(outputFile.Data(),"");
+      gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
+      AliInfo(Form("%s will be stored in %s",
+                  outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
+                  outputLocation.Data()));
+    }
+  }
+
+  return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t AliReconstruction::IsHighPt() const {
+  // Selection of events containing "high" pT tracks
+  // If at least one track is found within 1.5 and 100 GeV (pT)
+  // that was reconstructed by both ITS and TPC, the event is accepted
+
+  // Track cuts
+
+  const Double_t pTmin = 1.5;
+  const Double_t pTmax = 100;
+  ULong_t mask = 0;
+  mask |= (AliESDtrack::kITSrefit);
+  mask |= (AliESDtrack::kTPCrefit);
+
+  Bool_t isOK = kFALSE;
+
+  if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
+    // Check if this ia a physics event (code 7)
+    Int_t ntrk = fesd->GetNumberOfTracks();
+    for (Int_t itrk=0; itrk<ntrk; ++itrk) {
+         
+      AliESDtrack * trk = fesd->GetTrack(itrk);
+      if (trk 
+         && trk->Pt() > pTmin 
+         && trk->Pt() < pTmax
+         && (trk->GetStatus() & mask) == mask ) {
+       
+       isOK = kTRUE;
+       break;
+      }
+    }
+  }
+  return isOK;
+}
+
+//______________________________________________________________________________
+Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
+  // Select cosmic or calibration events
+
+  Bool_t isOK = kFALSE;
+
+  if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
+      // Check if this ia a physics event (code 7)
+      
+      UInt_t specie = fesd->GetEventSpecie();
+      if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
+       isOK = kTRUE;
+      }
+  }
+  return isOK;
+}
+
+//______________________________________________________________________________
+void AliReconstruction::WriteESDfriend() {
+  // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
+  // in fFractionFriends. We select events where we store the ESD friends according
+  // to the following algorithm:
+  // 1. Store all Cosmic or Calibration events within the required fraction
+  // 2. Sample "high Pt" events within the remaining fraction after step 1.
+  // 3. Sample randomly events if we still have remaining slot
+
+  fNall++;
+
+  Bool_t isSelected = kFALSE;
+
+  if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
+    fNspecie++;
+    Double_t curentSpecieFraction = ((Double_t)(fNspecie+1))/((Double_t)(fNall+1)); 
+    // "Bayesian" estimate supposing that without events all the events are of the required type
+    
+    Double_t rnd = gRandom->Rndm()*curentSpecieFraction;
+    if (rnd<fFractionFriends) {
+      isSelected = kTRUE;
+      fSspecie++;
+    }
+  }
+  
+  Double_t remainingFraction = fFractionFriends;
+  remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
+  
+  if (IsHighPt())  { // Selection of "high Pt" events
+    fNhighPt++;
+    Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
+    // "Bayesian" estimate supposing that without events all the events are of the required type
+    
+    if (!isSelected) {
+      Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
+      if (rnd<remainingFraction) {
+       isSelected = kTRUE;
+       fShighPt++;
+      }
+    }
+  }
+  remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
+  
+  // Random selection to fill the remaining fraction (if any)
+  if (!isSelected) {
+    Double_t rnd = gRandom->Rndm();
+    if (rnd<remainingFraction) {       
+      isSelected = kTRUE;
+    }
+  }
+  
+  if (!isSelected) {
+    fesdf->~AliESDfriend();
+    new (fesdf) AliESDfriend(); // Reset...
+    fesdf->SetSkipBit(kTRUE);
+  }
+  
+  ftreeF->Fill();
 }