Main changes:
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 12 Nov 2007 14:33:09 +0000 (14:33 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 12 Nov 2007 14:33:09 +0000 (14:33 +0000)
- Removed class AliMUONHitForRec (use AliMUONVCluster instead)
- Changed some variable, data member and function names to be consistent
Also:
- Modified AliMUONRecoCheck to use AliMCEventHandler to handle
trackRef and Particles
- Corrected comments about AliMUONRecoParam

Philippe Pillot

34 files changed:
MUON/AliMUONAlignment.cxx
MUON/AliMUONAlignment.h
MUON/AliMUONCheck.cxx
MUON/AliMUONCheck.h
MUON/AliMUONClusterStoreV2.cxx
MUON/AliMUONRawCluster.h
MUON/AliMUONRawClusterV2.h
MUON/AliMUONRecoCheck.cxx
MUON/AliMUONRecoCheck.h
MUON/AliMUONRecoParam.cxx
MUON/AliMUONReconstructor.cxx
MUON/AliMUONTrack.cxx
MUON/AliMUONTrack.h
MUON/AliMUONTrackHitPattern.cxx
MUON/AliMUONTrackLight.cxx
MUON/AliMUONTrackParam.cxx
MUON/AliMUONTrackParam.h
MUON/AliMUONTrackReconstructor.cxx
MUON/AliMUONTrackReconstructor.h
MUON/AliMUONTrackReconstructorK.cxx
MUON/AliMUONTrackReconstructorK.h
MUON/AliMUONTracker.cxx
MUON/AliMUONTriggerChamberEff.cxx
MUON/AliMUONVCluster.h
MUON/AliMUONVTrackReconstructor.cxx
MUON/AliMUONVTrackReconstructor.h
MUON/MUONAlignment.C
MUON/MUONCheck.C
MUON/MUONCheckDI.C
MUON/MUONRecoCheck.C
MUON/MUONResoEffChamber.C
MUON/MUONrecLinkDef.h
MUON/libMUONrec.pkg
MUON/mapping/AliMpLocalBoard.h

index 0e12d05..93a1e64 100644 (file)
@@ -21,8 +21,8 @@
 ///
 /// MUON specific alignment class which interface to AliMillepede.   
 /// For each track ProcessTrack calculates the local and global derivatives
-/// at each hit and fill the corresponding local equations. Provide methods for
-/// fixing or constraining detection elements for best results. 
+/// at each cluster and fill the corresponding local equations. Provide methods
+/// for fixing or constraining detection elements for best results. 
 ///
 /// \author Bruce Becker, Javier Castillo
 //-----------------------------------------------------------------------------
@@ -30,7 +30,7 @@
 #include "AliMUONAlignment.h"
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
-#include "AliMUONHitForRec.h"
+#include "AliMUONVCluster.h"
 #include "AliMUONGeometryTransformer.h"
 #include "AliMUONGeometryModuleTransformer.h"
 #include "AliMUONGeometryDetElement.h"
@@ -64,10 +64,9 @@ AliMUONAlignment::AliMUONAlignment()
     fResCutInitial(100.), 
     fResCut(100.),
     fMillepede(0),
-    fTrackParamAtHit(0),
-    fHitForRecAtHit(0),
+    fTrackParamAtCluster(0),
     fTrack(0),
-    fRecHit(0),
+    fCluster(0),
     fTrackParam(0),
     fNGlobal(fgNDetElem*fgNParCh),
     fNLocal(4),
@@ -727,7 +726,7 @@ void AliMUONAlignment::SetNonLinear(Int_t iPar  /* set non linear flag */ ) {
 }
 
 void AliMUONAlignment::LocalEquationX() {
-  /// Define local equation for current track and hit in x coor. measurement
+  /// Define local equation for current track and cluster in x coor. measurement
   // set local derivatives
   SetLocalDerivative(0, fCosPhi);
   SetLocalDerivative(1, fCosPhi * (fTrackPos[2] - fTrackPos0[2]));
@@ -754,7 +753,7 @@ void AliMUONAlignment::LocalEquationX() {
 }
 
 void AliMUONAlignment::LocalEquationY() {
-  /// Define local equation for current track and hit in y coor. measurement
+  /// Define local equation for current track and cluster in y coor. measurement
   // set local derivatives
   SetLocalDerivative(0,-fSinPhi);
   SetLocalDerivative(1,-fSinPhi * (fTrackPos[2] - fTrackPos0[2]));
@@ -781,16 +780,16 @@ void AliMUONAlignment::LocalEquationY() {
 }
 
 void AliMUONAlignment::FillRecPointData() {
-  /// Get information of current hit
-  fClustPos[0] = fRecHit->GetNonBendingCoor();
-  fClustPos[1] = fRecHit->GetBendingCoor();
-  fClustPos[2] = fRecHit->GetZ();
+  /// Get information of current cluster
+  fClustPos[0] = fCluster->GetX();
+  fClustPos[1] = fCluster->GetY();
+  fClustPos[2] = fCluster->GetZ();
   fTransform->Global2Local(fDetElemId,fClustPos[0],fClustPos[1],fClustPos[2],
                            fClustPosLoc[0],fClustPosLoc[1],fClustPosLoc[2]);
 }
 
 void AliMUONAlignment::FillTrackParamData() {
-  /// Get information of current track at current hit
+  /// Get information of current track at current cluster
   fTrackPos[0] = fTrackParam->GetNonBendingCoor();
   fTrackPos[1] = fTrackParam->GetBendingCoor();
   fTrackPos[2] = fTrackParam->GetZ();
@@ -805,7 +804,7 @@ void AliMUONAlignment::FillDetElemData() {
   Double_t lDetElemLocX = 0.;
   Double_t lDetElemLocY = 0.;
   Double_t lDetElemLocZ = 0.;
-  fDetElemId = fRecHit->GetDetElemId();
+  fDetElemId = fCluster->GetDetElemId();
   fDetElemNumber = fDetElemId%100;
   for (int iCh=0; iCh<fDetElemId/100-1; iCh++){
     fDetElemNumber += fgNDetElemCh[iCh];
@@ -815,22 +814,19 @@ void AliMUONAlignment::FillDetElemData() {
 }
 
 void AliMUONAlignment::ProcessTrack(AliMUONTrack * track) {
-  /// Process track; Loop over hits and set local equations
+  /// Process track; Loop over clusters and set local equations
   fTrack = track;
   // get tclones arrays.
-  fTrackParamAtHit = fTrack->GetTrackParamAtHit();
-  fHitForRecAtHit = fTrack->GetHitForRecAtHit();
+  fTrackParamAtCluster = fTrack->GetTrackParamAtCluster();
   
   // get size of arrays
-  Int_t nTrackParam = fTrackParamAtHit->GetEntries();
-  Int_t nHitForRec = fHitForRecAtHit->GetEntries();
+  Int_t nTrackParam = fTrackParamAtCluster->GetEntries();
   AliDebug(1,Form("Number of track param entries : %i ", nTrackParam));
-  AliDebug(1,Form("Number of hit for rec entries : %i ", nHitForRec));
 
-  for(Int_t iHit=0; iHit<nHitForRec; iHit++) {
-    fRecHit = (AliMUONHitForRec *) fHitForRecAtHit->At(iHit);
-    fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtHit()->At(iHit);
-    if (!fRecHit || !fTrackParam) continue;
+  for(Int_t iCluster=0; iCluster<nTrackParam; iCluster++) {
+    fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtCluster()->At(iCluster);
+    fCluster = fTrackParam->GetClusterPtr();
+    if (!fCluster || !fTrackParam) continue;
     // fill local variables for this position --> one measurement
     FillDetElemData();
     FillRecPointData();
@@ -844,21 +840,21 @@ void AliMUONAlignment::ProcessTrack(AliMUONTrack * track) {
     break;
   }
 
-  for(Int_t iHit=0; iHit<nHitForRec; iHit++) {
+  for(Int_t iCluster=0; iCluster<nTrackParam; iCluster++) {
     // and get new pointers
-    fRecHit = (AliMUONHitForRec *) fHitForRecAtHit->At(iHit);
-    fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtHit()->At(iHit);
-    if (!fRecHit || !fTrackParam) continue;
+    fTrackParam = (AliMUONTrackParam *) fTrack->GetTrackParamAtCluster()->At(iCluster);
+    fCluster = fTrackParam->GetClusterPtr();
+    if (!fCluster || !fTrackParam) continue;
     // fill local variables for this position --> one measurement
     FillDetElemData();        
     FillRecPointData();
     FillTrackParamData();
 //     if (fDetElemId<500) continue;
-    AliDebug(1,Form("cluster: %i", iHit));
+    AliDebug(1,Form("cluster: %i", iCluster));
     AliDebug(1,Form("x: %f\t y: %f\t z: %f\t DetElemID: %i\t ", fClustPos[0], fClustPos[1], fClustPos[2], fDetElemId));
     AliDebug(1,Form("fDetElemPos[0]: %f\t fDetElemPos[1]: %f\t fDetElemPos[2]: %f\t DetElemID: %i\t ", fDetElemPos[0],fDetElemPos[1],fDetElemPos[2], fDetElemId));
 
-    AliDebug(1,Form("Track Parameter: %i", iHit));
+    AliDebug(1,Form("Track Parameter: %i", iCluster));
     AliDebug(1,Form("x: %f\t y: %f\t z: %f\t slopex: %f\t slopey: %f", fTrackPos[0], fTrackPos[1], fTrackPos[2], fTrackSlope[0], fTrackSlope[1]));
     AliDebug(1,Form("x0: %f\t y0: %f\t z0: %f\t slopex0: %f\t slopey0: %f", fTrackPos0[0], fTrackPos0[1], fTrackPos0[2], fTrackSlope0[0], fTrackSlope0[1]));
     
index f95e09c..e2b6074 100644 (file)
@@ -19,7 +19,7 @@ class AliMillepede;
 class AliMUONGeometryTransformer;
 class AliMUONTrack;
 class AliMUONTrackParam;
-class AliMUONHitForRec;
+class AliMUONVCluster;
 
 class AliMUONAlignment:public TObject
 {
@@ -97,11 +97,10 @@ public:
 
   AliMillepede *fMillepede; ///< Detector independent alignment class
   
-  TClonesArray *fTrackParamAtHit; ///< Array of track parameters 
-  TClonesArray *fHitForRecAtHit;  ///< Array of track hits 
-  AliMUONTrack *fTrack;           ///< AliMUONTrack 
-  AliMUONHitForRec *fRecHit;      ///< AliMUONHitForRec
-  AliMUONTrackParam *fTrackParam; ///< Track parameters 
+  TClonesArray *fTrackParamAtCluster; ///< Array of track parameters 
+  AliMUONTrack *fTrack;               ///< AliMUONTrack 
+  AliMUONVCluster *fCluster;          ///< AliMUONVCluster
+  AliMUONTrackParam *fTrackParam;     ///< Track parameters 
 
   Int_t fNGlobal;  ///< Number of global parameters
   Int_t fNLocal;   ///< Number of local parameters
index d83fbf9..f391f63 100644 (file)
@@ -32,9 +32,6 @@
 
 #include "AliMUONCheck.h"
 #include "AliMUONConstants.h"
-#include "AliMUONTrack.h"
-#include "AliMUONTrackParam.h"
-#include "AliMUONTrackExtrap.h"
 #include "AliMUONMCDataInterface.h"
 #include "AliMUONDataInterface.h"
 #include "AliMpCDB.h"
@@ -827,52 +824,6 @@ AliMUONCheck::CheckOccupancy(Bool_t perDetEle) const
 }
 
 //_____________________________________________________________________________
-void 
-AliMUONCheck::CheckRecTracks () const
-{
-  /// Reads and dumps rec tracks objects
-  
-  AliWarning("Reimplement me ? or use AliMUONDumper simply ?");
-  
-  //  // waiting for mag field in CDB 
-  //  AliInfoStream() << "Loading field map...\n";
-  //  if (!AliTracker::GetFieldMap()) {
-  //    AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 1, 1., 10., AliMagFMaps::k5kG);
-  //    AliTracker::SetFieldMap(field, kFALSE);
-  //  }
-  //  
-  //  // Loading data
-  //  fLoader->LoadTracks("READ");
-  //  
-  //  Int_t endOfLoop = fLastEvent+1;
-  //  if ( fLastEvent == -1 ) endOfLoop = fRunLoader->GetNumberOfEvents();
-  //
-  //  for (Int_t ievent=fFirstEvent; ievent<endOfLoop; ievent++) {
-  //    fRunLoader->GetEvent(ievent);
-  //    
-  //    fRecData->SetTreeAddress("RT");
-  //    fRecData->GetRecTracks();
-  //    TClonesArray* recTracks = fRecData->RecTracks();
-  //    
-  //    Int_t nrectracks = (Int_t) recTracks->GetEntriesFast(); //
-  //    printf(">>> Event %d, Number of Recconstructed tracks %d \n",ievent, nrectracks);
-  //
-  //    // Set the magnetic field for track extrapolations
-  //    AliMUONTrackExtrap::SetField(AliTracker::GetFieldMap());
-  //
-  //    // Loop over tracks
-  //    for (Int_t iRecTracks = 0; iRecTracks <  nrectracks;  iRecTracks++) {
-  //      AliMUONTrack* recTrack = (AliMUONTrack*) recTracks->At(iRecTracks);
-  //      AliMUONTrackParam* trackParam = (AliMUONTrackParam*) (recTrack->GetTrackParamAtHit())->First();
-  //      AliMUONTrackExtrap::ExtrapToZ(trackParam,0.);
-  //      recTrack->Print("full");
-  //    }
-  //    fRecData->ResetRecTracks();
-  //  }   
-  //  fLoader->UnloadTracks();
-}
-
-//_____________________________________________________________________________
 void AliMUONCheck::SetEventsToCheck(Int_t firstEvent, Int_t lastEvent)
 {
   /// Set first and last event number to check
index 00912ac..6457410 100644 (file)
@@ -36,7 +36,6 @@ public:
   void CheckKine();
   void CheckTrackRef();
   void CheckOccupancy(Bool_t perDetEle =kFALSE) const;  
-  void CheckRecTracks() const;
   
   void SetEventsToCheck(Int_t firstEvent, Int_t lastEvent);
 
index 39ac6b2..13e63ff 100644 (file)
@@ -135,6 +135,13 @@ Bool_t AliMUONClusterStoreV2::Add(const AliMUONVCluster& vCluster)
     return kFALSE;
   }
   
+  // check chamberId
+  Int_t chamberId = cluster->GetChamberId();
+  if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) {
+    AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers()));
+    return 0x0;
+  }
+  
   // check that there is no cluster with the same Id
   if (FindObject(cluster->GetUniqueID())) {
     AliError("cluster store already contains a cluster with the same ID --> add() aborted");
@@ -154,6 +161,12 @@ AliMUONVCluster* AliMUONClusterStoreV2::Add(Int_t chamberId, Int_t detElemId, In
 {
   /// Add an empty cluster with an unique ID to this store
   
+  // check chamberId
+  if (chamberId < 0 || chamberId >= AliMpConstants::NofTrackingChambers()) {
+    AliError(Form("ChamberId (%d) out of boundaries [0,%d[",chamberId,AliMpConstants::NofTrackingChambers()));
+    return 0x0;
+  }
+  
   // check that there is no cluster with the same Id
   AliMUONVCluster *c = FindObject(AliMUONVCluster::BuildUniqueID(chamberId, detElemId, clusterIndex));
   if (c) {
index b3670ee..4f385f2 100644 (file)
@@ -29,7 +29,10 @@ public:
            /// Clear method (used by TClonesArray)
    virtual void Clear(Option_t* = "") {}
    
-          /// Set coordinates (cm)
+           /// Create a copy of the current cluster
+   virtual AliMUONRawCluster* CreateCopy() const {return new AliMUONRawCluster(*this);}
+   
+           /// Set coordinates (cm)
   virtual void     SetXYZ(Double_t x, Double_t y, Double_t z) {fX[0] = x; fY[0] = y; fZ[0] = z;}
            /// Return coordinate X (cm)
   virtual Double_t GetX() const {return fX[0];}
index 04e99e8..b8e9ff6 100644 (file)
@@ -27,7 +27,10 @@ class AliMUONRawClusterV2 : public AliMUONVCluster {
   
   virtual void Clear(Option_t* = "");
   
-          /// Set coordinates (cm)
+          /// Create a copy of the current cluster
+  virtual AliMUONRawClusterV2* CreateCopy() const {return new AliMUONRawClusterV2(*this);}
+  
+           /// Set coordinates (cm)
   virtual void     SetXYZ(Double_t x, Double_t y, Double_t z) {fX = x; fY = y; fZ = z;}
           /// Return coordinate X (cm)
   virtual Double_t GetX() const {return fX;}
index 0d7d8ab..337f6ab 100644 (file)
 //-----------------------------------------------------------------------------
 
 #include "AliMUONRecoCheck.h"
-#include "AliMUONHitForRec.h"
+#include "AliMUONRawClusterV2.h"
 #include "AliMUONTrack.h"
 #include "AliMUONConstants.h"
-#include "AliMUONMCDataInterface.h"
 #include "AliMUONDataInterface.h"
+#include "AliMUONTrackStoreV1.h"
+
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
 #include "AliStack.h"
 #include "AliTrackReference.h"
 #include "AliLog.h" 
-#include "AliMUONTrackStoreV1.h"
-#include <Riostream.h>
+
 #include <TParticle.h>
 #include <TParticlePDG.h>
 
+#include <Riostream.h>
+
 /// \cond CLASSIMP
 ClassImp(AliMUONRecoCheck)
 /// \endcond
 
 //_____________________________________________________________________________
-AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader, Char_t *chLoaderSim)
+AliMUONRecoCheck::AliMUONRecoCheck(Char_t *chLoader, Char_t *pathSim)
 : TObject(),
-fMCDataInterface(new AliMUONMCDataInterface(chLoaderSim)),
-fDataInterface(new AliMUONDataInterface(chLoader))
+fMCEventHandler(new AliMCEventHandler()),
+fDataInterface(new AliMUONDataInterface(chLoader)),
+fCurrentEvent(0),
+fTrackRefStore(0x0),
+fRecoTrackRefStore(0x0),
+fRecoTrackStore(0x0)
 {
   /// Normal ctor
+  fMCEventHandler->SetInputPath(pathSim);
+  fMCEventHandler->InitIO("");
 }
 
 //_____________________________________________________________________________
 AliMUONRecoCheck::~AliMUONRecoCheck()
 {
   /// Destructor
-  delete fMCDataInterface;
+  delete fMCEventHandler;
   delete fDataInterface;
+  ResetStores();
+}
+
+//_____________________________________________________________________________
+void AliMUONRecoCheck::ResetStores()
+{
+  /// Deletes all the store objects that have been created and resets the pointers to 0x0
+  delete fTrackRefStore;      fTrackRefStore = 0x0;
+  delete fRecoTrackRefStore;  fRecoTrackRefStore = 0x0;
+  delete fRecoTrackStore;     fRecoTrackStore = 0x0;
+}
+
+//_____________________________________________________________________________
+Int_t AliMUONRecoCheck::NumberOfEvents() const
+{
+  /// Return the number of events
+  if (fDataInterface->IsValid()) return fDataInterface->NumberOfEvents();
+  return 0;
 }
 
 //_____________________________________________________________________________
-AliMUONVTrackStore* 
-AliMUONRecoCheck::ReconstructedTracks(Int_t event)
+AliMUONVTrackStore* AliMUONRecoCheck::ReconstructedTracks(Int_t event)
 {
   /// Return the reconstructed track store for a given event
-  return fDataInterface->TrackStore(event);
+  if (!fDataInterface->IsValid()) return new AliMUONTrackStoreV1();
+  
+  if (event != fCurrentEvent) {
+    ResetStores();
+    fCurrentEvent = event;
+  }
+  
+  if (fRecoTrackStore != 0x0) return fRecoTrackStore;
+  
+  fRecoTrackStore = new AliMUONTrackStoreV1();
+  
+  return fRecoTrackStore;
 }
 
 //_____________________________________________________________________________
-AliMUONVTrackStore* 
-AliMUONRecoCheck::TrackRefs(Int_t event)
+AliMUONVTrackStore* AliMUONRecoCheck::TrackRefs(Int_t event)
 {
   /// Return a track store containing the track references (converted into 
   /// MUONTrack objects) for a given event
-  return MakeTrackRefs(event);
+  if (event != fCurrentEvent) {
+    ResetStores();
+    fCurrentEvent = event;
+  }
+  
+  if (fTrackRefStore != 0x0) return fTrackRefStore;
+  else {
+    if (!fMCEventHandler->GetEvent(event)) return 0x0;
+    MakeTrackRefs();
+    return fTrackRefStore;
+  }
 }
 
 //_____________________________________________________________________________
-AliMUONVTrackStore* 
-AliMUONRecoCheck::ReconstructibleTracks(Int_t event)
+AliMUONVTrackStore* AliMUONRecoCheck::ReconstructibleTracks(Int_t event)
 {
   /// Return a track store containing the reconstructible tracks for a given event
-  AliMUONVTrackStore* tmp = MakeTrackRefs(event);
-  AliMUONVTrackStore* reconstructible = MakeReconstructibleTracks(*tmp);
-  delete tmp;
-  return reconstructible;
+  if (event != fCurrentEvent) {
+    ResetStores();
+    fCurrentEvent = event;
+  }
+  
+  if (fRecoTrackRefStore != 0x0) return fRecoTrackRefStore;
+  else {
+    if (TrackRefs(event) == 0x0) return 0x0;
+    MakeReconstructibleTracks();
+    return fRecoTrackRefStore;
+  }
 }
 
 //_____________________________________________________________________________
-AliMUONVTrackStore*
-AliMUONRecoCheck::MakeTrackRefs(Int_t event)
+void AliMUONRecoCheck::MakeTrackRefs()
 {
   /// Make reconstructible tracks
-    
-  AliMUONVTrackStore* trackRefStore = new AliMUONTrackStoreV1;
-  
-  Int_t nTrackRef = fMCDataInterface->NumberOfTrackRefs(event);
+  AliMUONVTrackStore *tmpTrackRefStore = new AliMUONTrackStoreV1();
   
-  Int_t trackSave(-999);
-  Int_t iHitMin(0);
+  Double_t x, y, z, pX, pY, pZ, bendingSlope, nonBendingSlope, inverseBendingMomentum;
+  TParticle* particle;
+  TClonesArray* trackRefs;
+  Int_t nTrackRef = fMCEventHandler->MCEvent()->GetNumberOfTracks();
   
-  Bool_t isNewTrack;
+  // loop over simulated tracks
+  for (Int_t iTrackRef  = 0; iTrackRef < nTrackRef; ++iTrackRef) {
+    Int_t nHits = fMCEventHandler->GetParticleAndTR(iTrackRef, particle, trackRefs);
     
-  AliStack* stack = fMCDataInterface->Stack(event);
-  Int_t max = stack->GetNtrack();
-  
-  for (Int_t iTrackRef  = 0; iTrackRef < nTrackRef; ++iTrackRef) 
-  {
-    TClonesArray* trackRefs = fMCDataInterface->TrackRefs(event,iTrackRef);
+    // skip empty trackRefs
+    if (nHits < 1) continue;
+    
+    // skip trackRefs not in MUON
+    AliTrackReference* trackReference0 = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(0));
+    if (trackReference0->DetectorId() != AliTrackReference::kMUON) continue;
+    
+    AliMUONTrack track;
     
-    iHitMin = 0;
-    isNewTrack = kTRUE;
+    // get track parameters at particle's vertex
+    x = particle->Vx();
+    y = particle->Vy();
+    z = particle->Vz();
+    pX = particle->Px();
+    pY = particle->Py();
+    pZ = particle->Pz();
     
-    if (!trackRefs->GetEntries()) continue; 
+    // compute rest of track parameters at particle's vertex
+    bendingSlope = 0;
+    nonBendingSlope = 0;
+    inverseBendingMomentum = 0;
+    if (TMath::Abs(pZ) > 0) {
+      bendingSlope = pY/pZ;
+      nonBendingSlope = pX/pZ;
+    }
+    Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
+    if (pYZ >0) inverseBendingMomentum = 1/pYZ;
+    TParticlePDG* ppdg = particle->GetPDG(1);
+    Int_t charge = (Int_t)(ppdg->Charge()/3.0);
+    inverseBendingMomentum *= charge;
+    
+    // set track parameters at particle's vertex
+    AliMUONTrackParam trackParamAtVertex;
+    trackParamAtVertex.SetNonBendingCoor(x);
+    trackParamAtVertex.SetBendingCoor(y);
+    trackParamAtVertex.SetZ(z);
+    trackParamAtVertex.SetBendingSlope(bendingSlope);
+    trackParamAtVertex.SetNonBendingSlope(nonBendingSlope);
+    trackParamAtVertex.SetInverseBendingMomentum(inverseBendingMomentum);
+        
+    // add track parameters at vertex
+    track.SetTrackParamAtVertex(&trackParamAtVertex);
     
-    while (isNewTrack) {
+    // loop over simulated track hits
+    for (Int_t iHit = 0; iHit < nHits; ++iHit) {        
+      AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->UncheckedAt(iHit));
       
-      AliMUONTrack muonTrack;
+      // Get track parameters of current hit
+      x = trackReference->X();
+      y = trackReference->Y();
+      z = trackReference->Z();
+      pX = trackReference->Px();
+      pY = trackReference->Py();
+      pZ = trackReference->Pz();
       
-      for (Int_t iHit = iHitMin; iHit < trackRefs->GetEntries(); ++iHit) 
-      {        
-        AliTrackReference* trackReference = static_cast<AliTrackReference*>(trackRefs->At(iHit));
-        
-        Float_t x = trackReference->X();
-        Float_t y = trackReference->Y();
-        Float_t z = trackReference->Z();
-        Float_t pX = trackReference->Px();
-        Float_t pY = trackReference->Py();
-        Float_t pZ = trackReference->Pz();
-        
-        Int_t track = trackReference->GetTrack();
-        
-        if ( track >= max )
-        {
-          AliWarningStream()
-          << "Track ID " << track 
-          << " larger than max number of particles " << max << endl;
-          isNewTrack = kFALSE;
-          break;
-        }
-        if (track != trackSave && iHit != 0) {
-          iHitMin = iHit;
-          trackSave = track;
-          break;
-        }
-        
-        Float_t bendingSlope = 0;
-        Float_t nonBendingSlope = 0;
-        Float_t inverseBendingMomentum = 0;
-        
-        AliMUONTrackParam trackParam;
-        
-        // track parameters at hit
-        trackParam.SetBendingCoor(y);
-        trackParam.SetNonBendingCoor(x);
-        trackParam.SetZ(z);
-        
-        if (TMath::Abs(pZ) > 0) 
-        {
-          bendingSlope = pY/pZ;
-          nonBendingSlope = pX/pZ;
-        }
-        Float_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
-        if (pYZ >0) inverseBendingMomentum = 1/pYZ; 
-        
-        trackParam.SetBendingSlope(bendingSlope);
-        trackParam.SetNonBendingSlope(nonBendingSlope);
-        trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
-        
-        AliMUONHitForRec hitForRec;
-        
-        hitForRec.SetBendingCoor(y);
-        hitForRec.SetNonBendingCoor(x);
-        hitForRec.SetZ(z);
-        hitForRec.SetBendingReso2(0.0); 
-        hitForRec.SetNonBendingReso2(0.0);
-        Int_t detElemId = hitForRec.GetDetElemId();
-        Int_t iChamber;
-        if (detElemId) 
-        {
-          iChamber = detElemId / 100 - 1; 
-        }
-        else 
-        {
-          iChamber = AliMUONConstants::ChamberNumber(z);
-        }
-        hitForRec.SetChamberNumber(iChamber);
-        
-        muonTrack.AddTrackParamAtHit(&trackParam,0);
-        muonTrack.AddHitForRecAtHit(&hitForRec);
-        muonTrack.SetTrackID(track);
-        
-        trackSave = track;
-        if (iHit == trackRefs->GetEntries()-1) isNewTrack = kFALSE;
-      }
+      // check chamberId of current trackReference
+      Int_t chamberId = AliMUONConstants::ChamberNumber(z);
+      if (chamberId < 0 || chamberId >= AliMUONConstants::NTrackingCh()) continue;
       
-      // track parameters at vertex 
-      TParticle* particle = stack->Particle(muonTrack.GetTrackID());
+      // set hit parameters
+      AliMUONRawClusterV2 hit(chamberId, 0, 0);
+      hit.SetXYZ(x,y,z);
+      hit.SetErrXY(0.,0.);
       
-      if (particle) 
-      {        
-        Float_t x = particle->Vx();
-        Float_t y = particle->Vy();
-        Float_t z = particle->Vz();
-        Float_t pX = particle->Px();
-        Float_t pY = particle->Py();
-        Float_t pZ = particle->Pz();
-        
-        AliMUONTrackParam trackParam;
-        
-        trackParam.SetBendingCoor(y);
-        trackParam.SetNonBendingCoor(x);
-        trackParam.SetZ(z);
-        
-        Float_t bendingSlope = 0;
-        Float_t nonBendingSlope = 0;
-        Float_t inverseBendingMomentum = 0;
-                
-        if (TMath::Abs(pZ) > 0) 
-        {
-          bendingSlope = pY/pZ;
-          nonBendingSlope = pX/pZ;
-        }
-        
-        Float_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
-        if (pYZ >0) inverseBendingMomentum = 1/pYZ;       
-        
-        TParticlePDG* ppdg = particle->GetPDG(1);
-        Int_t charge = (Int_t)(ppdg->Charge()/3.0);
-        inverseBendingMomentum *= charge;
-        
-        trackParam.SetBendingSlope(bendingSlope);
-        trackParam.SetNonBendingSlope(nonBendingSlope);
-        trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
-        
-        muonTrack.SetTrackParamAtVertex(&trackParam);
+      // compute track parameters at hit
+      Double_t bendingSlope = 0;
+      Double_t nonBendingSlope = 0;
+      Double_t inverseBendingMomentum = 0;
+      if (TMath::Abs(pZ) > 0) {
+       bendingSlope = pY/pZ;
+       nonBendingSlope = pX/pZ;
       }
-
-      trackRefStore->Add(muonTrack);
-    } // end while isNewTrack
+      Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
+      if (pYZ >0) inverseBendingMomentum = 1/pYZ; 
+      inverseBendingMomentum *= charge;
+      
+      // set track parameters at hit
+      AliMUONTrackParam trackParam;
+      trackParam.SetNonBendingCoor(x);
+      trackParam.SetBendingCoor(y);
+      trackParam.SetZ(z);
+      trackParam.SetBendingSlope(bendingSlope);
+      trackParam.SetNonBendingSlope(nonBendingSlope);
+      trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
+      
+      // add track parameters at current hit to the track
+      track.AddTrackParamAtCluster(trackParam,hit,kTRUE);
+    }
+    
+    track.GetTrackParamAtCluster()->Sort();
+    track.SetTrackID(iTrackRef);
+    tmpTrackRefStore->Add(track);
   }
   
-  AliMUONVTrackStore* rv = CleanMuonTrackRef(*trackRefStore);
+  CleanMuonTrackRef(tmpTrackRefStore);
   
-  delete trackRefStore;
-
-  return rv;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliMUONRecoCheck::NumberOfEvents() const
-{
-  /// Return the number of events
-  if ( fDataInterface ) 
-  {
-    return fDataInterface->NumberOfEvents();
-  }
-  return 0;
+  delete tmpTrackRefStore;
 }
 
 //_____________________________________________________________________________
-AliMUONVTrackStore*
-AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore& trackRefs)
+void AliMUONRecoCheck::CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore)
 {
   /// Re-calculate hits parameters because two AliTrackReferences are recorded for
   /// each chamber (one when particle is entering + one when particle is leaving 
   /// the sensitive volume) 
+  fTrackRefStore = new AliMUONTrackStoreV1();
   
-  Float_t maxGasGap = 1.; // cm 
-  AliMUONHitForRec *hitForRec, *hitForRec1, *hitForRec2;
-  AliMUONTrackParam *trackParam, *trackParam1, *trackParam2, *trackParamAtVertex;
-  TClonesArray *  hitForRecAtHit = 0;
-  TClonesArray *  trackParamAtHit = 0;
-  Float_t xRec,yRec,zRec;
-  Float_t xRec1,yRec1,zRec1;
-  Float_t xRec2,yRec2,zRec2;
-  Float_t bendingSlope,nonBendingSlope,bendingMomentum;
-  Float_t bendingSlope1,nonBendingSlope1,bendingMomentum1;
-  Float_t bendingSlope2,nonBendingSlope2,bendingMomentum2;
-  
-  AliMUONVTrackStore* newMuonTrackRef = static_cast<AliMUONVTrackStore*>(trackRefs.Create());
-  Int_t iHit1;
-  Int_t iChamber = 0, detElemId = 0;
-  Int_t nRec = 0;
-  Int_t nTrackHits = 0;
+  Double_t maxGasGap = 1.; // cm 
+  Double_t x, y, z, pX, pY, pZ, x1, y1, z1, pX1, pY1, pZ1, z2;
+  Double_t bendingSlope,nonBendingSlope,inverseBendingMomentum;
   
-  hitForRec = new AliMUONHitForRec();
-  trackParam = new AliMUONTrackParam();
+  // create iterator
+  TIter next(tmpTrackRefStore->CreateIterator());
   
-  TIter next(trackRefs.CreateIterator());
+  // loop over tmpTrackRef
   AliMUONTrack* track;
-  
-  while ( ( track = static_cast<AliMUONTrack*>(next())) ) 
-  {
-    hitForRecAtHit = track->GetHitForRecAtHit();
-    trackParamAtHit = track->GetTrackParamAtHit();
-    trackParamAtVertex = track->GetTrackParamAtVertex();
-    nTrackHits = hitForRecAtHit->GetEntriesFast();
-    AliMUONTrack trackNew;
-    iHit1 = 0;
-    while (iHit1 < nTrackHits) 
-    {
-      hitForRec1 = (AliMUONHitForRec*) hitForRecAtHit->At(iHit1); 
-      trackParam1 = (AliMUONTrackParam*) trackParamAtHit->At(iHit1); 
-      xRec1  = hitForRec1->GetNonBendingCoor();
-      yRec1  = hitForRec1->GetBendingCoor();
-      zRec1  = hitForRec1->GetZ();     
-      xRec   = xRec1;
-      yRec   = yRec1;
-      zRec   = zRec1;
-      bendingSlope1 = trackParam1->GetBendingSlope();
-      nonBendingSlope1 = trackParam1->GetNonBendingSlope();
-      bendingMomentum1 = 0;
-      if (TMath::Abs(trackParam1->GetInverseBendingMomentum()) > 0)
-        bendingMomentum1 = 1./trackParam1->GetInverseBendingMomentum();
-      bendingSlope = bendingSlope1;
-      nonBendingSlope = nonBendingSlope1;
-      bendingMomentum = bendingMomentum1;
-      nRec = 1;  
-      for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++)
-      {
-        hitForRec2 = (AliMUONHitForRec*) hitForRecAtHit->At(iHit2); 
-        trackParam2 = (AliMUONTrackParam*) trackParamAtHit->At(iHit2); 
-        xRec2  = hitForRec2->GetNonBendingCoor();
-        yRec2  = hitForRec2->GetBendingCoor();
-        zRec2  = hitForRec2->GetZ();     
-        bendingSlope2 = trackParam2->GetBendingSlope();
-        nonBendingSlope2 = trackParam2->GetNonBendingSlope();
-        bendingMomentum2 = 0;
-        if (TMath::Abs(trackParam2->GetInverseBendingMomentum()) > 0)
-          bendingMomentum2 = 1./trackParam2->GetInverseBendingMomentum();
+  while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
+    
+    AliMUONTrack newTrack;
+    
+    // loop over tmpTrackRef's hits
+    Int_t iHit1 = 0;
+    Int_t nTrackHits = track->GetNClusters();
+    while (iHit1 < nTrackHits) {
+      AliMUONTrackParam *trackParam1 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit1);
+      
+      // get track parameters at hit1
+      x1  = trackParam1->GetNonBendingCoor();
+      y1  = trackParam1->GetBendingCoor();
+      z1  = trackParam1->GetZ();
+      pX1 = trackParam1->Px();
+      pY1 = trackParam1->Py();
+      pZ1 = trackParam1->Pz();
+      
+      // prepare new track parameters
+      x  = x1;
+      y  = y1;
+      z  = z1;
+      pX = pX1;
+      pY = pY1;
+      pZ = pZ1;
+      
+      // loop over next tmpTrackRef's hits
+      Int_t nCombinedHits = 1;
+      for (Int_t iHit2 = iHit1+1; iHit2 < nTrackHits; iHit2++) {
+       AliMUONTrackParam *trackParam2 = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit2);
         
-        if ( TMath::Abs(zRec2-zRec1) < maxGasGap ) {
-          
-          nRec++;
-          xRec += xRec2;
-          yRec += yRec2;
-          zRec += zRec2;
-          bendingSlope += bendingSlope2;
-          nonBendingSlope += nonBendingSlope2;
-          bendingMomentum += bendingMomentum2;
+       // get z position of hit2
+       z2 = trackParam2->GetZ();
+       
+       // complete new track parameters if hit2 is on the same detection element
+        if ( TMath::Abs(z2-z1) < maxGasGap ) {
+         x  += trackParam2->GetNonBendingCoor();
+         y  += trackParam2->GetBendingCoor();
+         z  += z2;
+         pX += trackParam2->Px();
+         pY += trackParam2->Py();
+         pZ += trackParam2->Pz();
+         nCombinedHits++;
           iHit1 = iHit2;
         }
         
-      } // end iHit2
-      xRec /= (Float_t)nRec;
-      yRec /= (Float_t)nRec;
-      zRec /= (Float_t)nRec;
-      bendingSlope /= (Float_t)nRec;
-      nonBendingSlope /= (Float_t)nRec;
-      bendingMomentum /= (Float_t)nRec;
+      }
+      
+      // finalize new track parameters
+      x  /= (Double_t)nCombinedHits;
+      y  /= (Double_t)nCombinedHits;
+      z  /= (Double_t)nCombinedHits;
+      pX /= (Double_t)nCombinedHits;
+      pY /= (Double_t)nCombinedHits;
+      pZ /= (Double_t)nCombinedHits;
+      bendingSlope = 0;
+      nonBendingSlope = 0;
+      inverseBendingMomentum = 0;
+      if (TMath::Abs(pZ) > 0) {
+       bendingSlope = pY/pZ;
+       nonBendingSlope = pX/pZ;
+      }
+      Double_t pYZ = TMath::Sqrt(pY*pY+pZ*pZ);
+      if (pYZ >0) inverseBendingMomentum = 1/pYZ; 
+      inverseBendingMomentum *= trackParam1->GetCharge();
       
-      hitForRec->SetNonBendingCoor(xRec);
-      hitForRec->SetBendingCoor(yRec);
-      hitForRec->SetZ(zRec);
-      detElemId = hitForRec->GetDetElemId();
-      if (detElemId) iChamber = detElemId / 100 - 1;
-      else iChamber = AliMUONConstants::ChamberNumber(zRec);
-      hitForRec->SetChamberNumber(iChamber);
-      hitForRec->SetBendingReso2(0.0); 
-      hitForRec->SetNonBendingReso2(0.0); 
-      trackParam->SetNonBendingCoor(xRec);
-      trackParam->SetBendingCoor(yRec);
-      trackParam->SetZ(zRec);
-      trackParam->SetNonBendingSlope(nonBendingSlope);
-      trackParam->SetBendingSlope(bendingSlope);
-      if (TMath::Abs(bendingMomentum) > 0)
-        trackParam->SetInverseBendingMomentum(1./bendingMomentum);
+      // set hit parameters
+      AliMUONRawClusterV2 hit(trackParam1->GetClusterPtr()->GetChamberId(), 0, 0);
+      hit.SetXYZ(x,y,z);
+      hit.SetErrXY(0.,0.);
       
-      trackNew.AddHitForRecAtHit(hitForRec);
-      trackNew.AddTrackParamAtHit(trackParam,0);
+      // set new track parameters at new hit
+      AliMUONTrackParam trackParam;
+      trackParam.SetNonBendingCoor(x);
+      trackParam.SetBendingCoor(y);
+      trackParam.SetZ(z);
+      trackParam.SetBendingSlope(bendingSlope);
+      trackParam.SetNonBendingSlope(nonBendingSlope);
+      trackParam.SetInverseBendingMomentum(inverseBendingMomentum);
+      
+      // add track parameters at current hit to the track
+      newTrack.AddTrackParamAtCluster(trackParam,hit,kTRUE);
       
       iHit1++;
-    } // end iHit1
+    }
     
-    trackNew.SetTrackID(track->GetTrackID());
-    trackNew.SetTrackParamAtVertex(trackParamAtVertex);
-    newMuonTrackRef->Add(trackNew);
+    newTrack.GetTrackParamAtCluster()->Sort();
+    newTrack.SetTrackID(track->GetTrackID());
+    newTrack.SetTrackParamAtVertex(track->GetTrackParamAtVertex());
+    fTrackRefStore->Add(newTrack);
     
-  } // end trackRef
+  }
   
-  delete hitForRec;
-  delete trackParam;
-  return newMuonTrackRef;  
 }
 
 //_____________________________________________________________________________
-AliMUONVTrackStore*
-AliMUONRecoCheck::MakeReconstructibleTracks(const AliMUONVTrackStore& trackRefs)
+void AliMUONRecoCheck::MakeReconstructibleTracks()
 {
   /// Calculate the number of reconstructible tracks
+  fRecoTrackRefStore = new AliMUONTrackStoreV1();
   
-  AliMUONVTrackStore* reconstructibleStore = static_cast<AliMUONVTrackStore*>(trackRefs.Create());
+  // create iterator on trackRef
+  TIter next(fTrackRefStore->CreateIterator());
   
-  TClonesArray* hitForRecAtHit = NULL;
-  AliMUONHitForRec* hitForRec;
-  Float_t zRec;
-  Int_t nTrackHits;
-  Int_t isChamberInTrack[10];
-  Int_t iChamber = 0;
-  Bool_t isTrackOK = kTRUE;
-    
-  TIter next(trackRefs.CreateIterator());
+  // loop over trackRef
   AliMUONTrack* track;
-
-  while ( ( track = static_cast<AliMUONTrack*>(next()) ) )
-  {
-    hitForRecAtHit = track->GetHitForRecAtHit();
-    nTrackHits = hitForRecAtHit->GetEntriesFast();
-    for (Int_t ch = 0; ch < 10; ch++) isChamberInTrack[ch] = 0;
+  while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
+    
+    Bool_t* chamberInTrack = new Bool_t(AliMUONConstants::NTrackingCh());
+    for (Int_t iCh = 0; iCh < AliMUONConstants::NTrackingCh(); iCh++) chamberInTrack[iCh] = kFALSE;
     
-    for ( Int_t iHit = 0; iHit < nTrackHits; iHit++) {
-      hitForRec = (AliMUONHitForRec*) hitForRecAtHit->At(iHit); 
-      zRec  = hitForRec->GetZ();
-      iChamber = hitForRec->GetChamberNumber(); 
-      if (iChamber < 0 || iChamber > 10) continue;
-      isChamberInTrack[iChamber] = 1;
+    // loop over trackRef's hits to get hit chambers
+    Int_t nTrackHits = track->GetNClusters();
+    for (Int_t iHit = 0; iHit < nTrackHits; iHit++) {
+      AliMUONVCluster* hit = ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iHit))->GetClusterPtr(); 
+      chamberInTrack[hit->GetChamberId()] = kTRUE;
     } 
+    
     // track is reconstructible if the particle is depositing a hit
     // in the following chamber combinations:
+    Bool_t trackOK = kTRUE;
+    if (!chamberInTrack[0] && !chamberInTrack[1]) trackOK = kFALSE;
+    if (!chamberInTrack[2] && !chamberInTrack[3]) trackOK = kFALSE;
+    if (!chamberInTrack[4] && !chamberInTrack[5]) trackOK = kFALSE;
+    Int_t nHitsInLastStations = 0;
+    for (Int_t iCh = 6; iCh < AliMUONConstants::NTrackingCh(); iCh++)
+      if (chamberInTrack[iCh]) nHitsInLastStations++; 
+    if(nHitsInLastStations < 3) trackOK = kFALSE;
     
-    isTrackOK = kTRUE;
-    if (!isChamberInTrack[0] && !isChamberInTrack[1]) isTrackOK = kFALSE;
-    if (!isChamberInTrack[2] && !isChamberInTrack[3]) isTrackOK = kFALSE;
-    if (!isChamberInTrack[4] && !isChamberInTrack[5]) isTrackOK = kFALSE;
-    Int_t nHitsInLastStations=0;
-    for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++)
-      if (isChamberInTrack[ch]) nHitsInLastStations++; 
-    if(nHitsInLastStations < 3) isTrackOK = kFALSE;
+    // Add reconstructible tracks to fRecoTrackRefStore
+    if (trackOK) fRecoTrackRefStore->Add(*track);
     
-    if (isTrackOK) 
-    {
-      reconstructibleStore->Add(*track);
-    }
+    delete [] chamberInTrack;
   }
 
-  return reconstructibleStore;
 }
 
index 4529a96..cf6e255 100644 (file)
 /// \brief Utility class to check reconstruction
 
 #include <TObject.h>
-#include "AliMUONTrack.h"
 
 class TClonesArray;
-class AliMUONMCDataInterface;
+class AliMCEventHandler;
 class AliMUONDataInterface;
 class AliMUONVTrackStore;
 
 class AliMUONRecoCheck : public TObject 
 {
 public:
-  AliMUONRecoCheck(Char_t *chLoader, Char_t *chLoaderSim);
+  AliMUONRecoCheck(Char_t *chLoader, Char_t *pathSim = "./");
   virtual ~AliMUONRecoCheck();
 
-  /// Return number of reconstructed tracks
+  Int_t NumberOfEvents() const;
+  
   AliMUONVTrackStore* ReconstructedTracks(Int_t event);
   
-  /// Return reference muon tracks
   AliMUONVTrackStore* TrackRefs(Int_t event);
 
-  /// Return reconstructible ref tracks
   AliMUONVTrackStore* ReconstructibleTracks(Int_t event);
   
-  Int_t NumberOfEvents() const;
-  
 private:
   /// Not implemented
   AliMUONRecoCheck(const AliMUONRecoCheck& rhs);
   /// Not implemented
   AliMUONRecoCheck& operator = (const AliMUONRecoCheck& rhs);
 
-  AliMUONVTrackStore* MakeReconstructibleTracks(const AliMUONVTrackStore& refTracks);
-
-  AliMUONVTrackStore* MakeTrackRefs(Int_t event);
+  void ResetStores();
+  
+  void MakeTrackRefs();
   
-  AliMUONVTrackStore* CleanMuonTrackRef(const AliMUONVTrackStore& refTracks);
+  void CleanMuonTrackRef(const AliMUONVTrackStore *tmpTrackRefStore);
   
+  void MakeReconstructibleTracks();
+
 private:
-    
-  AliMUONMCDataInterface* fMCDataInterface; ///< to access MC information
+  AliMCEventHandler* fMCEventHandler; ///< to access MC truth information
   AliMUONDataInterface* fDataInterface; ///< to access MUON data
   
+  Int_t fCurrentEvent; ///< current event number
+  
+  AliMUONVTrackStore* fTrackRefStore;     ///< current simulated tracks (owner)
+  AliMUONVTrackStore* fRecoTrackRefStore; ///< current reconstructible tracks (owner)
+  AliMUONVTrackStore* fRecoTrackStore;    ///< current reconstructed tracks (owner)
+  
   ClassDef(AliMUONRecoCheck, 0)   //Utility class to check reconstruction
 };
 
 #endif
 
-
-
-
-
-
-
-
index f193eae..45cc7b6 100644 (file)
@@ -93,7 +93,7 @@ void AliMUONRecoParam::SetLowFluxParam()
 {
   /// Set reconstruction parameters for low flux environment
   
-  fMinBendingMomentum = 3.;
+  fMinBendingMomentum = 0.5;
   fMaxBendingMomentum = 3000.;
   fNonBendingVertexDispersion = 10.;
   fBendingVertexDispersion = 10.;
@@ -116,7 +116,7 @@ void AliMUONRecoParam::SetHighFluxParam()
 {
   /// Set reconstruction parameters for high flux environment
   
-  fMinBendingMomentum = 3.;
+  fMinBendingMomentum = 0.5;
   fMaxBendingMomentum = 3000.;
   fNonBendingVertexDispersion = 10.;
   fBendingVertexDispersion = 10.;
index 1b32c18..79debec 100644 (file)
 ///
 /// Implementation of AliReconstructor for MUON subsystem.
 ///
-/// The behavior of the MUON reconstruction can be changed, besides
-/// the usual methods found in AliReconstruction (e.g. to disable tracking)
-/// by using AliReconstruction::SetOption("MUON",options)
-/// where options should be a space separated string.
+/// The clustering mode and the associated parameters can be changed by using
+/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam();
+/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details
+/// AliMUONReconstructor::SetRecoParam(muonRecoParam);
 ///
-/// Valid options are :
-///
-/// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits
-///     that are used for the clustering
+/// Valid modes are :
 ///
 /// SIMPLEFIT : use the AliMUONClusterFinderSimpleFit clusterizer
 ///
-/// MLEM : another implementation of AZ, where preclustering is external (default)
-/// MLEMV3 : MLEM with preclustering=PRECLUSTERV2
+/// SIMPLEFITV3 : SIMPLEFIT with preclustering=PRECLUSTERV3
+///
+/// MLEM : use AliMUONClusterFinderMLEM and AliMUONPreClusterFinder for preclustering (default)
+/// MLEMV2 : MLEM with preclustering=PRECLUSTERV2
 /// MLEMV3 : MLEM with preclustering=PRECLUSTERV3
 ///
 /// PRECLUSTER : use only AliMUONPreClusterFinder. Only for debug as
 ///
 /// NOCLUSTERING : bypass completely the clustering stage
 ///
-/// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence
-/// "recover" old behavior)
+/// ------
 ///
-/// TRIGGERDISABLE : disable the treatment of MUON trigger
+/// The behavior of the MUON reconstruction can also be changed, besides
+/// the usual methods found in AliReconstruction (e.g. to disable tracking)
+/// by using AliReconstruction::SetOption("MUON",options)
+/// where options should be a space separated string.
+///
+/// Valid options are :
+///
+/// SAVEDIGITS : if you want to save in the TreeD the *calibrated* digits
+///     that are used for the clustering
 ///
 /// DIGITSTOREV1 : use the V1 implementation of the digitstore 
 /// DIGITSTOREV2R : use the V2R implementation of the digitstore 
 ///
+/// NOLOCALRECONSTRUCTION : for debug, to disable local reconstruction (and hence
+/// "recover" old behavior)
+///
+/// TRIGGERDISABLE : disable the treatment of MUON trigger
+///
 /// \author Laurent Aphecetche, Subatech
 //-----------------------------------------------------------------------------
 
@@ -418,7 +429,6 @@ AliMUONReconstructor::CreateCalibrator() const
   
   TString opt(GetOption());
   opt.ToUpper();
-  Bool_t statusMap(kTRUE);
   
   if ( strstr(opt,"NOSTATUSMAP") )
   {
index adfd54c..76eb487 100644 (file)
@@ -24,7 +24,7 @@
 #include "AliMUONTrack.h"
 
 #include "AliMUONTrackParam.h" 
-#include "AliMUONHitForRec.h" 
+#include "AliMUONVCluster.h" 
 #include "AliMUONObjectPair.h" 
 #include "AliMUONConstants.h"
 #include "AliMUONTrackExtrap.h" 
@@ -43,134 +43,131 @@ ClassImp(AliMUONTrack) // Class implementation in ROOT context
 //__________________________________________________________________________
 AliMUONTrack::AliMUONTrack()
   : TObject(),
-    fTrackParamAtVertex(),
-    fTrackParamAtHit(0x0),
-    fHitForRecAtHit(0x0),
-    fNTrackHits(0),
+    fTrackParamAtCluster(new TClonesArray("AliMUONTrackParam",10)),
     fFitWithVertex(kFALSE),
-    fVertex(0x0),
+    fVertexErrXY2(),
     fFitWithMCS(kFALSE),
-    fHitWeightsNonBending(0x0),
-    fHitWeightsBending(0x0),
+    fClusterWeightsNonBending(0x0),
+    fClusterWeightsBending(0x0),
     fGlobalChi2(-1.),
     fImproved(kFALSE),
     fMatchTrigger(-1),
     floTrgNum(-1),
     fChi2MatchTrigger(0.),
     fTrackID(0),
+    fTrackParamAtVertex(0x0),
     fHitsPatternInTrigCh(0),
     fLocalTrigger(0)
 {
   /// Default constructor
+  fTrackParamAtCluster->SetOwner(kTRUE);
+  fVertexErrXY2[0] = 0.;
+  fVertexErrXY2[1] = 0.;
 }
 
   //__________________________________________________________________________
 AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment)
   : TObject(),
-    fTrackParamAtVertex(),
-    fTrackParamAtHit(0x0),
-    fHitForRecAtHit(0x0),
-    fNTrackHits(0),
+    fTrackParamAtCluster(new TClonesArray("AliMUONTrackParam",10)),
     fFitWithVertex(kFALSE),
-    fVertex(0x0),
+    fVertexErrXY2(),
     fFitWithMCS(kFALSE),
-    fHitWeightsNonBending(0x0),
-    fHitWeightsBending(0x0),
+    fClusterWeightsNonBending(0x0),
+    fClusterWeightsBending(0x0),
     fGlobalChi2(0.),
     fImproved(kFALSE),
     fMatchTrigger(-1),
     floTrgNum(-1),    
     fChi2MatchTrigger(0.),
     fTrackID(0),
+    fTrackParamAtVertex(0x0),
     fHitsPatternInTrigCh(0),
     fLocalTrigger(0)
 {
-  /// Constructor from thw hitForRec's
-
-  fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10);
-  fTrackParamAtHit->SetOwner(kTRUE);
-  fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10);
-  fHitForRecAtHit->SetOwner(kTRUE);
+  /// Constructor from two clusters
+  fTrackParamAtCluster->SetOwner(kTRUE);
   
-  if (!segment) return; //AZ
+  fVertexErrXY2[0] = 0.;
+  fVertexErrXY2[1] = 0.;
   
-  // Pointers to hits from the segment
-  AliMUONHitForRec* hit1 = (AliMUONHitForRec*) segment->First();
-  AliMUONHitForRec* hit2 = (AliMUONHitForRec*) segment->Second();
+  // Pointers to clusters from the segment
+  AliMUONVCluster* cluster1 = (AliMUONVCluster*) segment->First();
+  AliMUONVCluster* cluster2 = (AliMUONVCluster*) segment->Second();
   
   // check sorting in -Z (spectro z<0)
-  if (hit1->GetZ() < hit2->GetZ()) {
-    hit1 = hit2;
-    hit2 = (AliMUONHitForRec*) segment->First();
+  if (cluster1->GetZ() < cluster2->GetZ()) {
+    cluster1 = cluster2;
+    cluster2 = (AliMUONVCluster*) segment->First();
   }
   
-  // order the hits into the track according to the station the segment belong to
-  //(the hit first attached is the one from which we will start the tracking procedure)
-  if (hit1->GetChamberNumber() == 8) {
-    AddTrackParamAtHit(0,hit1);
-    AddTrackParamAtHit(0,hit2);
+  // order the clusters into the track according to the station the segment belong to
+  //(the cluster first attached is the one from which we will start the tracking procedure)
+  AliMUONVCluster *firstCluster, *lastCluster;
+  if (cluster1->GetChamberId() == 8) {
+    firstCluster = cluster1;
+    lastCluster = cluster2;
   } else {
-    AddTrackParamAtHit(0,hit2);
-    AddTrackParamAtHit(0,hit1);
+    firstCluster = cluster2;
+    lastCluster = cluster1;
   }
   
-  AliMUONTrackParam* trackParamAtFirstHit = (AliMUONTrackParam*) fTrackParamAtHit->First();
-  AliMUONHitForRec* firstHit = trackParamAtFirstHit->GetHitForRecPtr();
-  AliMUONTrackParam* trackParamAtLastHit = (AliMUONTrackParam*) fTrackParamAtHit->Last();
-  AliMUONHitForRec* lastHit = trackParamAtLastHit->GetHitForRecPtr();
-  
-  
   // Compute track parameters
-  Double_t dZ = firstHit->GetZ() - lastHit->GetZ();
+  Double_t z1 = firstCluster->GetZ();
+  Double_t z2 = lastCluster->GetZ();
+  Double_t dZ = z1 - z2;
   // Non bending plane
-  Double_t nonBendingCoor1 = firstHit->GetNonBendingCoor();
-  Double_t nonBendingCoor2 = lastHit->GetNonBendingCoor();
+  Double_t nonBendingCoor1 = firstCluster->GetX();
+  Double_t nonBendingCoor2 = lastCluster->GetX();
   Double_t nonBendingSlope = (nonBendingCoor1 - nonBendingCoor2) / dZ;
   // Bending plane
-  Double_t bendingCoor1 = firstHit->GetBendingCoor();
-  Double_t bendingCoor2 = lastHit->GetBendingCoor();
+  Double_t bendingCoor1 = firstCluster->GetY();
+  Double_t bendingCoor2 = lastCluster->GetY();
   Double_t bendingSlope = (bendingCoor1 - bendingCoor2) / dZ;
   // Inverse bending momentum
-  Double_t bendingImpact = bendingCoor1 - firstHit->GetZ() * bendingSlope;
+  Double_t bendingImpact = bendingCoor1 - z1 * bendingSlope;
   Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact);
   
   
-  // Set track parameters at first hit
-  trackParamAtFirstHit->SetNonBendingCoor(nonBendingCoor1);
-  trackParamAtFirstHit->SetNonBendingSlope(nonBendingSlope);
-  trackParamAtFirstHit->SetBendingCoor(bendingCoor1);
-  trackParamAtFirstHit->SetBendingSlope(bendingSlope);
-  trackParamAtFirstHit->SetInverseBendingMomentum(inverseBendingMomentum);
+  // Set track parameters at first cluster
+  AliMUONTrackParam trackParamAtFirstCluster;
+  trackParamAtFirstCluster.SetZ(z1);
+  trackParamAtFirstCluster.SetNonBendingCoor(nonBendingCoor1);
+  trackParamAtFirstCluster.SetNonBendingSlope(nonBendingSlope);
+  trackParamAtFirstCluster.SetBendingCoor(bendingCoor1);
+  trackParamAtFirstCluster.SetBendingSlope(bendingSlope);
+  trackParamAtFirstCluster.SetInverseBendingMomentum(inverseBendingMomentum);
   
   
-  // Set track parameters at last hit
-  trackParamAtLastHit->SetNonBendingCoor(nonBendingCoor2);
-  trackParamAtLastHit->SetNonBendingSlope(nonBendingSlope);
-  trackParamAtLastHit->SetBendingCoor(bendingCoor2);
-  trackParamAtLastHit->SetBendingSlope(bendingSlope);
-  trackParamAtLastHit->SetInverseBendingMomentum(inverseBendingMomentum);
+  // Set track parameters at last cluster
+  AliMUONTrackParam trackParamAtLastCluster;
+  trackParamAtLastCluster.SetZ(z2);
+  trackParamAtLastCluster.SetNonBendingCoor(nonBendingCoor2);
+  trackParamAtLastCluster.SetNonBendingSlope(nonBendingSlope);
+  trackParamAtLastCluster.SetBendingCoor(bendingCoor2);
+  trackParamAtLastCluster.SetBendingSlope(bendingSlope);
+  trackParamAtLastCluster.SetInverseBendingMomentum(inverseBendingMomentum);
   
   
-  // Compute and set track parameters covariances at first hit
+  // Compute and set track parameters covariances at first cluster
   TMatrixD paramCov1(5,5);
   paramCov1.Zero();
   // Non bending plane
-  paramCov1(0,0) = firstHit->GetNonBendingReso2();
-  paramCov1(0,1) = firstHit->GetNonBendingReso2() / dZ;
+  paramCov1(0,0) = firstCluster->GetErrX2();
+  paramCov1(0,1) = firstCluster->GetErrX2() / dZ;
   paramCov1(1,0) = paramCov1(0,1);
-  paramCov1(1,1) = ( firstHit->GetNonBendingReso2() + lastHit->GetNonBendingReso2() ) / dZ / dZ;
+  paramCov1(1,1) = ( firstCluster->GetErrX2() + lastCluster->GetErrX2() ) / dZ / dZ;
   // Bending plane
-  paramCov1(2,2) = firstHit->GetBendingReso2();
-  paramCov1(2,3) = firstHit->GetBendingReso2() / dZ;
+  paramCov1(2,2) = firstCluster->GetErrY2();
+  paramCov1(2,3) = firstCluster->GetErrY2() / dZ;
   paramCov1(3,2) = paramCov1(2,3);
-  paramCov1(3,3) = ( firstHit->GetBendingReso2() + lastHit->GetBendingReso2() ) / dZ / dZ;
+  paramCov1(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ;
   // Inverse bending momentum (50% error)
   paramCov1(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum;
   // Set covariances
-  trackParamAtFirstHit->SetCovariances(paramCov1);
+  trackParamAtFirstCluster.SetCovariances(paramCov1);
   
   
-  // Compute and set track parameters covariances at last hit (as if the first hit did not exist)
+  // Compute and set track parameters covariances at last cluster (as if the first cluster did not exist)
   TMatrixD paramCov2(5,5);
   paramCov2.Zero();
   // Non bending plane
@@ -182,65 +179,56 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment)
   // Inverse bending momentum
   paramCov2(4,4) = paramCov1(4,4);
   // Set covariances
-  trackParamAtLastHit->SetCovariances(paramCov2);
+  trackParamAtLastCluster.SetCovariances(paramCov2);
   
+  // Flag clusters as being removable
+  trackParamAtFirstCluster.SetRemovable(kTRUE);
+  trackParamAtLastCluster.SetRemovable(kTRUE);
   
-  // Flag first hit as being removable
-  trackParamAtFirstHit->SetRemovable(kTRUE);
-  
-  // Flag last hit as being removable
-  trackParamAtLastHit->SetRemovable(kTRUE);
+  // Add track parameters at clusters
+  AddTrackParamAtCluster(trackParamAtFirstCluster,*firstCluster);
+  AddTrackParamAtCluster(trackParamAtLastCluster,*lastCluster);
   
 }
 
   //__________________________________________________________________________
-AliMUONTrack::AliMUONTrack (const AliMUONTrack& track)
+AliMUONTrack::AliMUONTrack(const AliMUONTrack& track)
   : TObject(track),
-    fTrackParamAtVertex(track.fTrackParamAtVertex),
-    fTrackParamAtHit(0x0),
-    fHitForRecAtHit(0x0),
-    fNTrackHits(track.fNTrackHits),
+    fTrackParamAtCluster(new TClonesArray("AliMUONTrackParam",10)),
     fFitWithVertex(track.fFitWithVertex),
-    fVertex(0x0),
+    fVertexErrXY2(),
     fFitWithMCS(track.fFitWithMCS),
-    fHitWeightsNonBending(0x0),
-    fHitWeightsBending(0x0),
+    fClusterWeightsNonBending(0x0),
+    fClusterWeightsBending(0x0),
     fGlobalChi2(track.fGlobalChi2),
     fImproved(track.fImproved),
     fMatchTrigger(track.fMatchTrigger),
     floTrgNum(track.floTrgNum),    
     fChi2MatchTrigger(track.fChi2MatchTrigger),
     fTrackID(track.fTrackID),
+    fTrackParamAtVertex(0x0),
     fHitsPatternInTrigCh(track.fHitsPatternInTrigCh),
     fLocalTrigger(track.fLocalTrigger)
 {
   ///copy constructor
-  Int_t maxIndex = 0;
   
   // necessary to make a copy of the objects and not only the pointers in TClonesArray.
-  if (track.fTrackParamAtHit) {
-    maxIndex = (track.fTrackParamAtHit)->GetEntriesFast();
-    fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",maxIndex);
-    for (Int_t index = 0; index < maxIndex; index++) {
-      new ((*fTrackParamAtHit)[index]) AliMUONTrackParam(*(AliMUONTrackParam*)track.fTrackParamAtHit->At(index));
-    }
+  AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->First();
+  while (trackParamAtCluster) {
+    new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(*trackParamAtCluster);
+    trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->After(trackParamAtCluster);
   }
   
-  // necessary to make a copy of the objects and not only the pointers in TClonesArray.
-  if (track.fHitForRecAtHit) {
-    maxIndex = (track.fHitForRecAtHit)->GetEntriesFast();
-    fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",maxIndex);
-    for (Int_t index = 0; index < maxIndex; index++) {
-      new ((*fHitForRecAtHit)[index]) AliMUONHitForRec(*(AliMUONHitForRec*)track.fHitForRecAtHit->At(index));
-    }
-  }
+  // copy vertex resolution square used during the tracking procedure
+  fVertexErrXY2[0] = track.fVertexErrXY2[0];
+  fVertexErrXY2[1] = track.fVertexErrXY2[1];
   
-  // copy vertex used during the tracking procedure if any
-  if (track.fVertex) fVertex = new AliMUONHitForRec(*(track.fVertex));
+  // copy cluster weights matrices if any
+  if (track.fClusterWeightsNonBending) fClusterWeightsNonBending = new TMatrixD(*(track.fClusterWeightsNonBending));
+  if (track.fClusterWeightsBending) fClusterWeightsBending = new TMatrixD(*(track.fClusterWeightsBending));
   
-  // copy hit weights matrices if any
-  if (track.fHitWeightsNonBending) fHitWeightsNonBending = new TMatrixD(*(track.fHitWeightsNonBending));
-  if (track.fHitWeightsBending) fHitWeightsBending = new TMatrixD(*(track.fHitWeightsBending));
+  // copy track parameters at vertex if any
+  if (track.fTrackParamAtVertex) fTrackParamAtVertex = new AliMUONTrackParam(*(track.fTrackParamAtVertex));
   
 }
 
@@ -255,71 +243,48 @@ AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& track)
   // base class assignement
   TObject::operator=(track);
 
-  fTrackParamAtVertex = track.fTrackParamAtVertex;
-
-  Int_t maxIndex = 0;
-  
   // necessary to make a copy of the objects and not only the pointers in TClonesArray.
-  if (track.fTrackParamAtHit) {
-    if (fTrackParamAtHit) fTrackParamAtHit->Clear();
-    else fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10);
-    maxIndex = (track.fTrackParamAtHit)->GetEntriesFast();
-    for (Int_t index = 0; index < maxIndex; index++) {
-      new ((*fTrackParamAtHit)[fTrackParamAtHit->GetEntriesFast()])
-       AliMUONTrackParam(*(AliMUONTrackParam*)(track.fTrackParamAtHit)->At(index));
-    }
-  } else if (fTrackParamAtHit) {
-    delete fTrackParamAtHit;
-    fTrackParamAtHit = 0x0;
-  }
-
-  // necessary to make a copy of the objects and not only the pointers in TClonesArray.
-  if (track.fHitForRecAtHit) {
-    if (fHitForRecAtHit) fHitForRecAtHit->Clear();
-    else fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10);
-    maxIndex = (track.fHitForRecAtHit)->GetEntriesFast();
-    for (Int_t index = 0; index < maxIndex; index++) {
-      new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()])
-       AliMUONHitForRec(*(AliMUONHitForRec*)(track.fHitForRecAtHit)->At(index));
-    }
-  } else if (fHitForRecAtHit) {
-    delete fHitForRecAtHit;
-    fHitForRecAtHit = 0x0;
+  fTrackParamAtCluster = new TClonesArray("AliMUONTrackParam",10);
+  AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->First();
+  while (trackParamAtCluster) {
+    new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(*trackParamAtCluster);
+    trackParamAtCluster = (AliMUONTrackParam*) track.fTrackParamAtCluster->After(trackParamAtCluster);
   }
   
-  // copy vertex used during the tracking procedure if any.
-  if (track.fVertex) {
-    if (fVertex) *fVertex = *(track.fVertex);
-    else fVertex = new AliMUONHitForRec(*(track.fVertex));
-  } else if (fVertex) {
-    delete fVertex;
-    fVertex = 0x0;
+  // copy cluster weights matrix if any
+  if (track.fClusterWeightsNonBending) {
+    if (fClusterWeightsNonBending) {
+      fClusterWeightsNonBending->ResizeTo(*(track.fClusterWeightsNonBending));
+      *fClusterWeightsNonBending = *(track.fClusterWeightsNonBending);
+    } else fClusterWeightsNonBending = new TMatrixD(*(track.fClusterWeightsNonBending));
+  } else if (fClusterWeightsNonBending) {
+    delete fClusterWeightsNonBending;
+    fClusterWeightsNonBending = 0x0;
   }
   
-  // copy hit weights matrix if any
-  if (track.fHitWeightsNonBending) {
-    if (fHitWeightsNonBending) {
-      fHitWeightsNonBending->ResizeTo(*(track.fHitWeightsNonBending));
-      *fHitWeightsNonBending = *(track.fHitWeightsNonBending);
-    } else fHitWeightsNonBending = new TMatrixD(*(track.fHitWeightsNonBending));
-  } else if (fHitWeightsNonBending) {
-    delete fHitWeightsNonBending;
-    fHitWeightsNonBending = 0x0;
+  // copy cluster weights matrix if any
+  if (track.fClusterWeightsBending) {
+    if (fClusterWeightsBending) {
+      fClusterWeightsBending->ResizeTo(*(track.fClusterWeightsBending));
+      *fClusterWeightsBending = *(track.fClusterWeightsBending);
+    } else fClusterWeightsBending = new TMatrixD(*(track.fClusterWeightsBending));
+  } else if (fClusterWeightsBending) {
+    delete fClusterWeightsBending;
+    fClusterWeightsBending = 0x0;
   }
   
-  // copy hit weights matrix if any
-  if (track.fHitWeightsBending) {
-    if (fHitWeightsBending) {
-      fHitWeightsBending->ResizeTo(*(track.fHitWeightsBending));
-      *fHitWeightsBending = *(track.fHitWeightsBending);
-    } else fHitWeightsBending = new TMatrixD(*(track.fHitWeightsBending));
-  } else if (fHitWeightsBending) {
-    delete fHitWeightsBending;
-    fHitWeightsBending = 0x0;
+  // copy track parameters at vertex if any
+  if (track.fTrackParamAtVertex) {
+    if (fTrackParamAtVertex) *fTrackParamAtVertex = *(track.fTrackParamAtVertex);
+    else fTrackParamAtVertex = new AliMUONTrackParam(*(track.fTrackParamAtVertex));
+  } else if (fTrackParamAtVertex) {
+    delete fTrackParamAtVertex;
+    fTrackParamAtVertex = 0x0;
   }
   
-  fNTrackHits         =  track.fNTrackHits;
   fFitWithVertex      =  track.fFitWithVertex;
+  fVertexErrXY2[0]    =  track.fVertexErrXY2[0];
+  fVertexErrXY2[1]    =  track.fVertexErrXY2[1];
   fFitWithMCS         =  track.fFitWithMCS;
   fGlobalChi2         =  track.fGlobalChi2;
   fImproved           =  track.fImproved;
@@ -337,178 +302,156 @@ AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& track)
 AliMUONTrack::~AliMUONTrack()
 {
   /// Destructor
-  delete fTrackParamAtHit;
-  delete fHitForRecAtHit;
-  delete fVertex;
-  delete fHitWeightsNonBending;
-  delete fHitWeightsBending;
+  delete fTrackParamAtCluster;
+  delete fClusterWeightsNonBending;
+  delete fClusterWeightsBending;
+  delete fTrackParamAtVertex;
 }
 
   //__________________________________________________________________________
 void AliMUONTrack::Clear(Option_t* opt)
 {
   /// Clear arrays
-  if ( fTrackParamAtHit ) fTrackParamAtHit->Clear(opt);
-  if ( fHitForRecAtHit ) fHitForRecAtHit->Clear(opt);
-  delete fVertex; fVertex = 0x0;
-  delete fHitWeightsNonBending; fHitWeightsNonBending = 0x0;
-  delete fHitWeightsBending; fHitWeightsBending = 0x0;
+  fTrackParamAtCluster->Clear(opt);
+  delete fClusterWeightsNonBending; fClusterWeightsNonBending = 0x0;
+  delete fClusterWeightsBending; fClusterWeightsBending = 0x0;
+  delete fTrackParamAtVertex; fTrackParamAtVertex = 0x0;
 }
 
   //__________________________________________________________________________
-void AliMUONTrack::AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec)
+void AliMUONTrack::AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy)
 {
-  /// Add TrackParamAtHit if "trackParam" != NULL
-  /// else create empty TrackParamAtHit and set the z position to the one of "hitForRec" if any
-  /// Update link to HitForRec if "hitForRec" != NULL
-  if (!fTrackParamAtHit) {
-    fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10);  
-    fNTrackHits = 0;
-  }
-  AliMUONTrackParam* trackParamAtHit;
-  if (trackParam) {
-    trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam(*trackParam);
-    if (hitForRec) {
-      if (hitForRec->GetZ() != trackParam->GetZ())
-        AliWarning("Added track parameters at a different z position than the one of the attached hit");
-    }
-  } else {
-    trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam();
-    if (hitForRec) trackParamAtHit->SetZ(hitForRec->GetZ());
-  }
-  if (hitForRec) trackParamAtHit->SetHitForRecPtr(hitForRec);
-  fNTrackHits++;
-}
-
-  //__________________________________________________________________________
-void AliMUONTrack::RemoveTrackParamAtHit(AliMUONTrackParam *trackParam)
-{
-  /// Remove trackParam from the array of TrackParamAtHit
-  if (!fTrackParamAtHit) {
-    AliWarning("array fTrackParamAtHit does not exist");
+  /// Copy given track parameters into a new TrackParamAtCluster
+  /// Link parameters with the associated cluster
+  /// If copy=kTRUE: the cluster is copied then passed the trackParam which become its owner 
+  ///     otherwise: make sure to do not delete the cluster until it is used by the track
+  
+  // check chamber ID of the associated cluster
+  if (cluster.GetChamberId() < 0 || cluster.GetChamberId() > AliMUONConstants::NTrackingCh()) {
+    AliError(Form("Chamber ID of the associated cluster is not valid (ChamberId=%d)",cluster.GetChamberId()));
     return;
   }
   
-  if (!fTrackParamAtHit->Remove(trackParam)) {
-    AliWarning("object to remove does not exist in array fTrackParamAtHit");
+  // check whether track parameters are given at the correct cluster z position
+  if (cluster.GetZ() != trackParam.GetZ()) {
+    AliError("track parameters are given at a different z position than the one of the associated cluster");
     return;
   }
   
-  fTrackParamAtHit->Compress();
-  fNTrackHits--;
+  // add parameters to the array of track parameters
+  AliMUONTrackParam* trackParamAtCluster = new ((*fTrackParamAtCluster)[GetNClusters()]) AliMUONTrackParam(trackParam);
+  
+  // link parameters with the associated cluster or its copy
+  if (copy) {
+    AliMUONVCluster *clusterCopy = cluster.CreateCopy();
+    trackParamAtCluster->SetClusterPtr(clusterCopy, kTRUE);
+  } else trackParamAtCluster->SetClusterPtr(&cluster);
 }
 
   //__________________________________________________________________________
-void AliMUONTrack::AddHitForRecAtHit(const AliMUONHitForRec *hitForRec) 
+void AliMUONTrack::RemoveTrackParamAtCluster(AliMUONTrackParam *trackParam)
 {
-  /// Add hitForRec to the array of hitForRec at hit
-  if (!fHitForRecAtHit)
-    fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); 
-  
-  if (!hitForRec)
-    AliFatal("AliMUONTrack::AddHitForRecAtHit: hitForRec == NULL");
+  /// Remove trackParam from the array of TrackParamAtCluster
+  if (!fTrackParamAtCluster->Remove(trackParam)) {
+    AliWarning("object to remove does not exist in array fTrackParamAtCluster");
+    return;
+  }
   
-  new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()]) AliMUONHitForRec(*hitForRec);
+  fTrackParamAtCluster->Compress();
 }
 
   //__________________________________________________________________________
-void AliMUONTrack::UpdateTrackParamAtHit()
+void AliMUONTrack::UpdateTrackParamAtCluster()
 {
-  /// Update track parameters at each attached hit
+  /// Update track parameters at each attached cluster
   
-  if (fNTrackHits == 0) {
-    AliWarning("no hit attached to the track");
+  if (GetNClusters() == 0) {
+    AliWarning("no cluster attached to the track");
     return;
   }
   
-  Double_t z;
-  AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtHit->First();
-  AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(startingTrackParam);
-  while (trackParamAtHit) {
-    
-    // save current z
-    z = trackParamAtHit->GetZ();
+  AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtCluster->First();
+  AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(startingTrackParam);
+  while (trackParamAtCluster) {
     
     // reset track parameters and their covariances
-    trackParamAtHit->SetParameters(startingTrackParam->GetParameters());
-    trackParamAtHit->SetZ(startingTrackParam->GetZ());
+    trackParamAtCluster->SetParameters(startingTrackParam->GetParameters());
+    trackParamAtCluster->SetZ(startingTrackParam->GetZ());
     
     // extrapolation to the given z
-    AliMUONTrackExtrap::ExtrapToZ(trackParamAtHit, z);
+    AliMUONTrackExtrap::ExtrapToZ(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ());
     
     // prepare next step
-    startingTrackParam = trackParamAtHit;
-    trackParamAtHit = (AliMUONTrackParam*) (fTrackParamAtHit->After(trackParamAtHit));
+    startingTrackParam = trackParamAtCluster;
+    trackParamAtCluster = (AliMUONTrackParam*) (fTrackParamAtCluster->After(trackParamAtCluster));
   }
 
 }
 
   //__________________________________________________________________________
-void AliMUONTrack::UpdateCovTrackParamAtHit()
+void AliMUONTrack::UpdateCovTrackParamAtCluster()
 {
-  /// Update track parameters and their covariances at each attached hit
+  /// Update track parameters and their covariances at each attached cluster
+  /// Include effects of multiple scattering in chambers
   
-  if (fNTrackHits == 0) {
-    AliWarning("no hit attached to the track");
+  if (GetNClusters() == 0) {
+    AliWarning("no cluster attached to the track");
     return;
   }
   
-  Double_t z;
-  AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtHit->First();
-  AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(startingTrackParam);
-  while (trackParamAtHit) {
-    
-    // save current z
-    z = trackParamAtHit->GetZ();
+  AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) fTrackParamAtCluster->First();
+  AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(startingTrackParam);
+  Int_t expectedChamber = startingTrackParam->GetClusterPtr()->GetChamberId() + 1;
+  Int_t currentChamber;
+  while (trackParamAtCluster) {
     
     // reset track parameters and their covariances
-    trackParamAtHit->SetParameters(startingTrackParam->GetParameters());
-    trackParamAtHit->SetZ(startingTrackParam->GetZ());
-    trackParamAtHit->SetCovariances(startingTrackParam->GetCovariances());
+    trackParamAtCluster->SetParameters(startingTrackParam->GetParameters());
+    trackParamAtCluster->SetZ(startingTrackParam->GetZ());
+    trackParamAtCluster->SetCovariances(startingTrackParam->GetCovariances());
     
-    // extrapolation to the given z
-    AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, z);
+    // add MCS effect
+    AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.);
+    
+    // add MCS in missing chambers if any
+    currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId();
+    while (currentChamber > expectedChamber) {
+      // extrapolation to the missing chamber
+      AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber));
+      // add MCS effect
+      AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.);
+      expectedChamber++;
+    }
+    
+    // extrapolation to the z of the current cluster
+    AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ());
     
     // prepare next step
-    startingTrackParam = trackParamAtHit;
-    trackParamAtHit = (AliMUONTrackParam*) (fTrackParamAtHit->After(trackParamAtHit));
+    expectedChamber = currentChamber + 1;
+    startingTrackParam = trackParamAtCluster;
+    trackParamAtCluster = (AliMUONTrackParam*) (fTrackParamAtCluster->After(trackParamAtCluster));
   }
-
-}
-
-  //__________________________________________________________________________
-void AliMUONTrack::SetVertex(const AliMUONHitForRec* vertex)
-{
-  /// Set the vertex used during the tracking procedure
-  if (!fVertex) fVertex = new AliMUONHitForRec(*vertex);
-  else *fVertex = *vertex;
+  
 }
 
-
   //__________________________________________________________________________
 Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
 {
-  /// Compute the removable hit contribution to the chi2 of the track
+  /// Compute each cluster contribution to the chi2 of the track
   /// accounting for multiple scattering or not according to the flag
-  /// - Also recompute the weight matrices of the attached hits if accountForMCS=kTRUE
-  /// - Assume that track parameters at each hit are corrects
+  /// - Also recompute the weight matrices of the attached clusters if accountForMCS=kTRUE
+  /// - Assume that track parameters at each cluster are corrects
   /// - Return kFALSE if computation failed
   
-  // Check hits (if the first one exist, assume that the other ones exit too!)
-  AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->First();
-  if (!trackParamAtHit->GetHitForRecPtr()) {
-    AliWarning("hit is missing");
-    return kFALSE;
-  }
-  
   if (accountForMCS) { // Compute local chi2 taking into account multiple scattering effects
       
     // Compute MCS covariance matrix only once
-    TMatrixD mcsCovariances(fNTrackHits,fNTrackHits);
+    Int_t nClusters = GetNClusters();
+    TMatrixD mcsCovariances(nClusters,nClusters);
     ComputeMCSCovariances(mcsCovariances);
     
-    // Make sure hit weights are consistent with following calculations
-    if (!ComputeHitWeights(&mcsCovariances)) {
+    // Make sure cluster weights are consistent with following calculations
+    if (!ComputeClusterWeights(&mcsCovariances)) {
       AliWarning("cannot take into account the multiple scattering effects");
       return ComputeLocalChi2(kFALSE);
     }
@@ -517,64 +460,67 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
     Double_t globalChi2 = ComputeGlobalChi2(kTRUE);
     if (globalChi2 < 0.) return kFALSE;
     
-    // Loop over removable hits and compute their local chi2
-    AliMUONTrackParam* trackParamAtHit1;
-    AliMUONHitForRec *hitForRec, *discardedHit;
-    Int_t hitNumber1, hitNumber2, currentHitNumber1, currentHitNumber2;
-    TMatrixD hitWeightsNB(fNTrackHits-1,fNTrackHits-1);
-    TMatrixD hitWeightsB(fNTrackHits-1,fNTrackHits-1);
-    Double_t *dX = new Double_t[fNTrackHits-1];
-    Double_t *dY = new Double_t[fNTrackHits-1];
+    // Loop over removable clusters and compute their local chi2
+    AliMUONTrackParam* trackParamAtCluster1;
+    AliMUONVCluster *cluster, *discardedCluster;
+    Int_t iCluster1, iCluster2, iCurrentCluster1, iCurrentCluster2;
+    TMatrixD ClusterWeightsNB(nClusters-1,nClusters-1);
+    TMatrixD ClusterWeightsB(nClusters-1,nClusters-1);
+    Double_t *dX = new Double_t[nClusters-1];
+    Double_t *dY = new Double_t[nClusters-1];
     Double_t globalChi2b;
-    while (trackParamAtHit) {
+    AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->First();
+    while (trackParamAtCluster) {
       
-      discardedHit = trackParamAtHit->GetHitForRecPtr();
+      discardedCluster = trackParamAtCluster->GetClusterPtr();
       
-      // Recompute hit weights without the current hit
-      if (!ComputeHitWeights(hitWeightsNB, hitWeightsB, &mcsCovariances, discardedHit)) {
+      // Recompute cluster weights without the current cluster
+      if (!ComputeClusterWeights(ClusterWeightsNB, ClusterWeightsB, &mcsCovariances, discardedCluster)) {
        AliWarning("cannot take into account the multiple scattering effects");
-       ComputeLocalChi2(kFALSE);
+       delete [] dX;
+       delete [] dY;
+       return ComputeLocalChi2(kFALSE);
       }
       
-      // Compute track chi2 without the current hit
+      // Compute track chi2 without the current cluster
       globalChi2b = 0.;
-      currentHitNumber1 = 0;
-      for (hitNumber1 = 0; hitNumber1 < fNTrackHits ; hitNumber1++) { 
-       trackParamAtHit1 = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1);
-       hitForRec = trackParamAtHit1->GetHitForRecPtr();
+      iCurrentCluster1 = 0;
+      for (iCluster1 = 0; iCluster1 < nClusters ; iCluster1++) { 
+       trackParamAtCluster1 = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster1);
+       cluster = trackParamAtCluster1->GetClusterPtr();
         
-        if (hitForRec == discardedHit) continue;
+        if (cluster == discardedCluster) continue;
         
         // Compute and save residuals
-       dX[currentHitNumber1] = hitForRec->GetNonBendingCoor() - trackParamAtHit1->GetNonBendingCoor();
-       dY[currentHitNumber1] = hitForRec->GetBendingCoor() - trackParamAtHit1->GetBendingCoor();
+       dX[iCurrentCluster1] = cluster->GetX() - trackParamAtCluster1->GetNonBendingCoor();
+       dY[iCurrentCluster1] = cluster->GetY() - trackParamAtCluster1->GetBendingCoor();
         
-        currentHitNumber2 = 0;
-       for (hitNumber2 = 0; hitNumber2 < hitNumber1; hitNumber2++) {
-         hitForRec = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber2))->GetHitForRecPtr();
+        iCurrentCluster2 = 0;
+       for (iCluster2 = 0; iCluster2 < iCluster1; iCluster2++) {
+         cluster = ((AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster2))->GetClusterPtr();
           
-          if (hitForRec == discardedHit) continue;
+          if (cluster == discardedCluster) continue;
           
           // Add contribution from covariances
-          globalChi2b += (hitWeightsNB(currentHitNumber1, currentHitNumber2) +
-                         hitWeightsNB(currentHitNumber2, currentHitNumber1)) * dX[currentHitNumber1] * dX[currentHitNumber2] +
-                        (hitWeightsB(currentHitNumber1, currentHitNumber2) +
-                         hitWeightsB(currentHitNumber2, currentHitNumber1)) * dY[currentHitNumber1] * dY[currentHitNumber2];
+          globalChi2b += (ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2) +
+                         ClusterWeightsNB(iCurrentCluster2, iCurrentCluster1)) * dX[iCurrentCluster1] * dX[iCurrentCluster2] +
+                        (ClusterWeightsB(iCurrentCluster1, iCurrentCluster2) +
+                         ClusterWeightsB(iCurrentCluster2, iCurrentCluster1)) * dY[iCurrentCluster1] * dY[iCurrentCluster2];
           
-          currentHitNumber2++;
+          iCurrentCluster2++;
        }
         
         // Add contribution from variances
-       globalChi2b += hitWeightsNB(currentHitNumber1, currentHitNumber1) * dX[currentHitNumber1] * dX[currentHitNumber1] +
-                      hitWeightsB(currentHitNumber1, currentHitNumber1) * dY[currentHitNumber1] * dY[currentHitNumber1];
+       globalChi2b += ClusterWeightsNB(iCurrentCluster1, iCurrentCluster1) * dX[iCurrentCluster1] * dX[iCurrentCluster1] +
+                      ClusterWeightsB(iCurrentCluster1, iCurrentCluster1) * dY[iCurrentCluster1] * dY[iCurrentCluster1];
        
-        currentHitNumber1++;
+        iCurrentCluster1++;
       }
 
       // Set local chi2
-      trackParamAtHit->SetLocalChi2(globalChi2 - globalChi2b);
+      trackParamAtCluster->SetLocalChi2(globalChi2 - globalChi2b);
       
-      trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit);
+      trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(trackParamAtCluster);
     }
     
     delete [] dX;
@@ -582,20 +528,21 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
     
   } else { // without multiple scattering effects
     
-    AliMUONHitForRec *discardedHit;
+    AliMUONVCluster *discardedCluster;
     Double_t dX, dY;
-    while (trackParamAtHit) {
+    AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->First();
+    while (trackParamAtCluster) {
       
-      discardedHit = trackParamAtHit->GetHitForRecPtr();
+      discardedCluster = trackParamAtCluster->GetClusterPtr();
       
       // Compute residuals
-      dX = discardedHit->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor();
-      dY = discardedHit->GetBendingCoor() - trackParamAtHit->GetBendingCoor();
+      dX = discardedCluster->GetX() - trackParamAtCluster->GetNonBendingCoor();
+      dY = discardedCluster->GetY() - trackParamAtCluster->GetBendingCoor();
       
       // Set local chi2
-      trackParamAtHit->SetLocalChi2(dX * dX / discardedHit->GetNonBendingReso2() + dY * dY / discardedHit->GetBendingReso2());
+      trackParamAtCluster->SetLocalChi2(dX * dX / discardedCluster->GetErrX2() + dY * dY / discardedCluster->GetErrY2());
     
-    trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit);
+      trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->After(trackParamAtCluster);
     }
   
   }
@@ -608,61 +555,57 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
 Double_t AliMUONTrack::ComputeGlobalChi2(Bool_t accountForMCS)
 {
   /// Compute the chi2 of the track accounting for multiple scattering or not according to the flag
-  /// - Assume that track parameters at each hit are corrects
-  /// - Assume the hits weights matrices are corrects
+  /// - Assume that track parameters at each cluster are corrects
+  /// - Assume the cluster weights matrices are corrects
   /// - Return negative value if chi2 computation failed
   
-  // Check hits (if the first one exist, assume that the other ones exit too!)
-  AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->First();
-  if (!trackParamAtHit->GetHitForRecPtr()) {
-    AliWarning("hit is missing");
-    return -1.;
-  }
-  
   Double_t chi2 = 0.;
   
   if (accountForMCS) {
     
     // Check the weight matrices. If weight matrices are not available compute chi2 without MCS
-    if (!fHitWeightsNonBending || !fHitWeightsBending) {
-      AliWarning("hit weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering");
+    if (!fClusterWeightsNonBending || !fClusterWeightsBending) {
+      AliWarning("cluster weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering");
       return ComputeGlobalChi2(kFALSE);
     }
-    if (fHitWeightsNonBending->GetNrows() != fNTrackHits || fHitWeightsBending->GetNcols() != fNTrackHits) {
-      AliWarning("hit weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering");
+    Int_t nClusters = GetNClusters();
+    if (fClusterWeightsNonBending->GetNrows() != nClusters || fClusterWeightsBending->GetNcols() != nClusters) {
+      AliWarning("cluster weights including multiple scattering effects are not available\n\t\t --> compute chi2 WITHOUT multiple scattering");
       return ComputeGlobalChi2(kFALSE);
     }
     
     // Compute chi2
-    AliMUONHitForRec *hitForRec;
-    Double_t *dX = new Double_t[fNTrackHits];
-    Double_t *dY = new Double_t[fNTrackHits];
-    Int_t hitNumber1, hitNumber2;
-    for (hitNumber1 = 0; hitNumber1 < fNTrackHits ; hitNumber1++) { 
-      trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1);
-      hitForRec = trackParamAtHit->GetHitForRecPtr();
-      dX[hitNumber1] = hitForRec->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor();
-      dY[hitNumber1] = hitForRec->GetBendingCoor() - trackParamAtHit->GetBendingCoor();
-      for (hitNumber2 = 0; hitNumber2 < hitNumber1; hitNumber2++) {
-        chi2 += ((*fHitWeightsNonBending)(hitNumber1, hitNumber2) + (*fHitWeightsNonBending)(hitNumber2, hitNumber1)) * dX[hitNumber1] * dX[hitNumber2] +
-               ((*fHitWeightsBending)(hitNumber1, hitNumber2) + (*fHitWeightsBending)(hitNumber2, hitNumber1)) * dY[hitNumber1] * dY[hitNumber2];
+    AliMUONVCluster *cluster;
+    Double_t *dX = new Double_t[nClusters];
+    Double_t *dY = new Double_t[nClusters];
+    AliMUONTrackParam* trackParamAtCluster;
+    for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { 
+      trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster1);
+      cluster = trackParamAtCluster->GetClusterPtr();
+      dX[iCluster1] = cluster->GetX() - trackParamAtCluster->GetNonBendingCoor();
+      dY[iCluster1] = cluster->GetY() - trackParamAtCluster->GetBendingCoor();
+      for (Int_t iCluster2 = 0; iCluster2 < iCluster1; iCluster2++) {
+        chi2 += ((*fClusterWeightsNonBending)(iCluster1, iCluster2) + (*fClusterWeightsNonBending)(iCluster2, iCluster1)) * dX[iCluster1] * dX[iCluster2] +
+               ((*fClusterWeightsBending)(iCluster1, iCluster2) + (*fClusterWeightsBending)(iCluster2, iCluster1)) * dY[iCluster1] * dY[iCluster2];
       }
-      chi2 += ((*fHitWeightsNonBending)(hitNumber1, hitNumber1) * dX[hitNumber1] * dX[hitNumber1]) +
-             ((*fHitWeightsBending)(hitNumber1, hitNumber1) * dY[hitNumber1] * dY[hitNumber1]);
+      chi2 += ((*fClusterWeightsNonBending)(iCluster1, iCluster1) * dX[iCluster1] * dX[iCluster1]) +
+             ((*fClusterWeightsBending)(iCluster1, iCluster1) * dY[iCluster1] * dY[iCluster1]);
     }
     delete [] dX;
     delete [] dY;
     
   } else {
     
-    AliMUONHitForRec *hitForRec;
+    AliMUONVCluster *cluster;
     Double_t dX, dY;
-    for (Int_t hitNumber = 0; hitNumber < fNTrackHits ; hitNumber++) { 
-      trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber);
-      hitForRec = trackParamAtHit->GetHitForRecPtr();
-      dX = hitForRec->GetNonBendingCoor() - trackParamAtHit->GetNonBendingCoor();
-      dY = hitForRec->GetBendingCoor() - trackParamAtHit->GetBendingCoor();
-      chi2 += dX * dX / hitForRec->GetNonBendingReso2() + dY * dY / hitForRec->GetBendingReso2();
+    AliMUONTrackParam* trackParamAtCluster;
+    Int_t nClusters = GetNClusters();
+    for (Int_t iCluster = 0; iCluster < nClusters ; iCluster++) { 
+      trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster);
+      cluster = trackParamAtCluster->GetClusterPtr();
+      dX = cluster->GetX() - trackParamAtCluster->GetNonBendingCoor();
+      dY = cluster->GetY() - trackParamAtCluster->GetBendingCoor();
+      chi2 += dX * dX / cluster->GetErrX2() + dY * dY / cluster->GetErrY2();
     }
     
   }
@@ -672,114 +615,109 @@ Double_t AliMUONTrack::ComputeGlobalChi2(Bool_t accountForMCS)
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD* mcsCovariances)
+Bool_t AliMUONTrack::ComputeClusterWeights(TMatrixD* mcsCovariances)
 {
-  /// Compute the weight matrices of the attached hits, in non bending and bending direction,
-  /// accounting for multiple scattering correlations and hits resolution
+  /// Compute the weight matrices of the attached clusters, in non bending and bending direction,
+  /// accounting for multiple scattering correlations and cluster resolution
   /// - Use the provided MCS covariance matrix if any (otherwise build it temporarily)
-  /// - Assume that track parameters at each hit are corrects
+  /// - Assume that track parameters at each cluster are corrects
   /// - Return kFALSE if computation failed
   
   // Alocate memory
-  if (!fHitWeightsNonBending) fHitWeightsNonBending = new TMatrixD(fNTrackHits,fNTrackHits);
-  if (!fHitWeightsBending) fHitWeightsBending = new TMatrixD(fNTrackHits,fNTrackHits);
-  
-  // Check hits (if the first one exist, assume that the other ones exit too!)
-  if (!((AliMUONTrackParam*) fTrackParamAtHit->First())->GetHitForRecPtr()) {
-    AliWarning("hit is missing");
-    fHitWeightsNonBending->ResizeTo(0,0);
-    fHitWeightsBending->ResizeTo(0,0);
-    return kFALSE;
-  }
+  Int_t nClusters = GetNClusters();
+  if (!fClusterWeightsNonBending) fClusterWeightsNonBending = new TMatrixD(nClusters,nClusters);
+  if (!fClusterWeightsBending) fClusterWeightsBending = new TMatrixD(nClusters,nClusters);
   
   // Compute weights matrices
-  if (!ComputeHitWeights(*fHitWeightsNonBending, *fHitWeightsBending, mcsCovariances)) return kFALSE;
+  if (!ComputeClusterWeights(*fClusterWeightsNonBending, *fClusterWeightsBending, mcsCovariances)) return kFALSE;
   
   return kTRUE;
   
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeightsB, TMatrixD* mcsCovariances, AliMUONHitForRec* discardedHit) const
+Bool_t AliMUONTrack::ComputeClusterWeights(TMatrixD& ClusterWeightsNB, TMatrixD& ClusterWeightsB,
+                                          TMatrixD* mcsCovariances, AliMUONVCluster* discardedCluster) const
 {
   /// Compute the weight matrices, in non bending and bending direction,
-  /// of the other attached hits assuming the discarded one does not exist
-  /// accounting for multiple scattering correlations and hits resolution
+  /// of the other attached clusters assuming the discarded one does not exist
+  /// accounting for multiple scattering correlations and cluster resolution
   /// - Use the provided MCS covariance matrix if any (otherwise build it temporarily)
   /// - Return kFALSE if computation failed
   
   // Check MCS covariance matrix and recompute it if need
+  Int_t nClusters = GetNClusters();
   Bool_t deleteMCSCov = kFALSE;
   if (!mcsCovariances) {
-    mcsCovariances = new TMatrixD(fNTrackHits,fNTrackHits);
+    mcsCovariances = new TMatrixD(nClusters,nClusters);
     deleteMCSCov = kTRUE;
     ComputeMCSCovariances(*mcsCovariances);
   }
   
   // Resize the weights matrices; alocate memory
-  if (discardedHit) {
-    hitWeightsNB.ResizeTo(fNTrackHits-1,fNTrackHits-1);
-    hitWeightsB.ResizeTo(fNTrackHits-1,fNTrackHits-1);
+  if (discardedCluster) {
+    ClusterWeightsNB.ResizeTo(nClusters-1,nClusters-1);
+    ClusterWeightsB.ResizeTo(nClusters-1,nClusters-1);
   } else {
-    hitWeightsNB.ResizeTo(fNTrackHits,fNTrackHits);
-    hitWeightsB.ResizeTo(fNTrackHits,fNTrackHits);
+    ClusterWeightsNB.ResizeTo(nClusters,nClusters);
+    ClusterWeightsB.ResizeTo(nClusters,nClusters);
   }
   
   // Define variables
-  AliMUONHitForRec *hitForRec1, *hitForRec2;
-  Int_t currentHitNumber1, currentHitNumber2;
+  AliMUONVCluster *cluster1, *cluster2;
+  Int_t iCurrentCluster1, iCurrentCluster2;
   
   // Compute the covariance matrices
-  currentHitNumber1 = 0;
-  for (Int_t hitNumber1 = 0; hitNumber1 < fNTrackHits; hitNumber1++) { 
-    hitForRec1 = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber1))->GetHitForRecPtr();
+  iCurrentCluster1 = 0;
+  for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { 
+    cluster1 = ((AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster1))->GetClusterPtr();
     
-    if (hitForRec1 == discardedHit) continue;
+    if (cluster1 == discardedCluster) continue;
     
-    // Loop over next hits
-    currentHitNumber2 = currentHitNumber1;
-    for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) {
-      hitForRec2 = ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber2))->GetHitForRecPtr();
+    // Loop over next clusters
+    iCurrentCluster2 = iCurrentCluster1;
+    for (Int_t iCluster2 = iCluster1; iCluster2 < nClusters; iCluster2++) {
+      cluster2 = ((AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster2))->GetClusterPtr();
       
-      if (hitForRec2 == discardedHit) continue;
+      if (cluster2 == discardedCluster) continue;
       
       // Fill with MCS covariances
-      hitWeightsNB(currentHitNumber1, currentHitNumber2) = (*mcsCovariances)(hitNumber1,hitNumber2);
+      ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2) = (*mcsCovariances)(iCluster1,iCluster2);
       
       // Equal contribution from multiple scattering in non bending and bending directions
-      hitWeightsB(currentHitNumber1, currentHitNumber2) = hitWeightsNB(currentHitNumber1, currentHitNumber2);
+      ClusterWeightsB(iCurrentCluster1, iCurrentCluster2) = ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2);
       
-      // Add contribution from hit resolution to diagonal element and symmetrize the matrix
-      if (currentHitNumber1 == currentHitNumber2) {
+      // Add contribution from cluster resolution to diagonal element and symmetrize the matrix
+      if (iCurrentCluster1 == iCurrentCluster2) {
        
        // In non bending plane
-        hitWeightsNB(currentHitNumber1, currentHitNumber1) += hitForRec1->GetNonBendingReso2();
+        ClusterWeightsNB(iCurrentCluster1, iCurrentCluster1) += cluster1->GetErrX2();
        // In bending plane
-       hitWeightsB(currentHitNumber1, currentHitNumber1) += hitForRec1->GetBendingReso2();
+       ClusterWeightsB(iCurrentCluster1, iCurrentCluster1) += cluster1->GetErrY2();
        
       } else {
        
        // In non bending plane
-       hitWeightsNB(currentHitNumber2, currentHitNumber1) = hitWeightsNB(currentHitNumber1, currentHitNumber2);
+       ClusterWeightsNB(iCurrentCluster2, iCurrentCluster1) = ClusterWeightsNB(iCurrentCluster1, iCurrentCluster2);
        // In bending plane
-       hitWeightsB(currentHitNumber2, currentHitNumber1) = hitWeightsB(currentHitNumber1, currentHitNumber2);
+       ClusterWeightsB(iCurrentCluster2, iCurrentCluster1) = ClusterWeightsB(iCurrentCluster1, iCurrentCluster2);
        
       }
       
-      currentHitNumber2++;
+      iCurrentCluster2++;
     }
     
-    currentHitNumber1++;
+    iCurrentCluster1++;
   }
     
   // Inversion of covariance matrices to get the weights
-  if (hitWeightsNB.Determinant() != 0 && hitWeightsB.Determinant() != 0) {
-    hitWeightsNB.Invert();
-    hitWeightsB.Invert();
+  if (ClusterWeightsNB.Determinant() != 0 && ClusterWeightsB.Determinant() != 0) {
+    ClusterWeightsNB.Invert();
+    ClusterWeightsB.Invert();
   } else {
     AliWarning(" Determinant = 0");
-    hitWeightsNB.ResizeTo(0,0);
-    hitWeightsB.ResizeTo(0,0);
+    ClusterWeightsNB.ResizeTo(0,0);
+    ClusterWeightsB.ResizeTo(0,0);
     if(deleteMCSCov) delete mcsCovariances;
     return kFALSE;
   }
@@ -794,40 +732,39 @@ Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeig
 void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const
 {
   /// Compute the multiple scattering covariance matrix
-  /// (assume that track parameters at each hit are corrects)
+  /// (assume that track parameters at each cluster are corrects)
   
   // Reset the size of the covariance matrix if needed
-  if (mcsCovariances.GetNrows() != fNTrackHits) mcsCovariances.ResizeTo(fNTrackHits,fNTrackHits);
+  Int_t nClusters = GetNClusters();
+  if (mcsCovariances.GetNrows() != nClusters) mcsCovariances.ResizeTo(nClusters,nClusters);
   
   // Define variables
   Int_t nChambers = AliMUONConstants::NTrackingCh();
-  AliMUONTrackParam* trackParamAtHit;
-  AliMUONHitForRec *hitForRec;
+  AliMUONTrackParam* trackParamAtCluster;
   AliMUONTrackParam extrapTrackParam;
   Int_t currentChamber = 0, expectedChamber = 0, size = 0;
   Double_t *mcsAngle2 = new Double_t[2*nChambers];
   Double_t *zMCS = new Double_t[2*nChambers];
-  Int_t *indices = new Int_t[2*fNTrackHits];
+  Int_t *indices = new Int_t[2*nClusters];
   
   // Compute multiple scattering dispersion angle at each chamber
   // and save the z position where it is calculated
-  for (Int_t hitNumber = 0; hitNumber < fNTrackHits; hitNumber++) {
-    trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber);
-    hitForRec = trackParamAtHit->GetHitForRecPtr();
+  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+    trackParamAtCluster = (AliMUONTrackParam*) fTrackParamAtCluster->UncheckedAt(iCluster);
     
     // look for missing chambers if any
-    currentChamber = hitForRec->GetChamberNumber();
+    currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId();
     while (currentChamber > expectedChamber) {
       
       // Save the z position where MCS dispersion is calculated
       zMCS[size] = AliMUONConstants::DefaultChamberZ(expectedChamber);
       
-      // Do not take into account MCS in chambers prior the first hit
-      if (hitNumber > 0) {
+      // Do not take into account MCS in chambers prior the first cluster
+      if (iCluster > 0) {
         
         // Get track parameters at missing chamber z
-        extrapTrackParam = *trackParamAtHit;
-        AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, zMCS[expectedChamber]);
+        extrapTrackParam = *trackParamAtCluster;
+        AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, zMCS[size]);
         
         // Save multiple scattering dispersion angle in missing chamber
         mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
@@ -839,36 +776,36 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const
     }
     
     // Save z position where MCS dispersion is calculated
-    zMCS[size] = trackParamAtHit->GetZ();
+    zMCS[size] = trackParamAtCluster->GetZ();
     
     // Save multiple scattering dispersion angle in current chamber
-    mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.);
+    mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.);
     
     // Save indice in zMCS array corresponding to the current cluster
-    indices[hitNumber] = size;
+    indices[iCluster] = size;
     
     expectedChamber = currentChamber + 1;
     size++;
   }
   
-  // complete array of z if last hit is on the last but one chamber
+  // complete array of z if last cluster is on the last but one chamber
   if (currentChamber != nChambers-1) zMCS[size++] = AliMUONConstants::DefaultChamberZ(nChambers-1);
   
   // Compute the covariance matrix
-  for (Int_t hitNumber1 = 0; hitNumber1 < fNTrackHits; hitNumber1++) { 
+  for (Int_t iCluster1 = 0; iCluster1 < nClusters; iCluster1++) { 
     
-    for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) {
+    for (Int_t iCluster2 = iCluster1; iCluster2 < nClusters; iCluster2++) {
       
       // Initialization to 0 (diagonal plus upper triangular part)
-      mcsCovariances(hitNumber1,hitNumber2) = 0.;
+      mcsCovariances(iCluster1,iCluster2) = 0.;
       
       // Compute contribution from multiple scattering in upstream chambers
-      for (Int_t k = 0; k < indices[hitNumber1]; k++) {        
-       mcsCovariances(hitNumber1,hitNumber2) += (zMCS[indices[hitNumber1]] - zMCS[k]) * (zMCS[indices[hitNumber2]] - zMCS[k]) * mcsAngle2[k];
+      for (Int_t k = 0; k < indices[iCluster1]; k++) {         
+       mcsCovariances(iCluster1,iCluster2) += (zMCS[indices[iCluster1]] - zMCS[k]) * (zMCS[indices[iCluster2]] - zMCS[k]) * mcsAngle2[k];
       }
       
       // Symetrize the matrix
-      mcsCovariances(hitNumber2,hitNumber1) = mcsCovariances(hitNumber1,hitNumber2);
+      mcsCovariances(iCluster2,iCluster1) = mcsCovariances(iCluster1,iCluster2);
     }
     
   }
@@ -880,28 +817,28 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const
 }
 
   //__________________________________________________________________________
-Int_t AliMUONTrack::HitsInCommon(AliMUONTrack* track) const
+Int_t AliMUONTrack::ClustersInCommon(AliMUONTrack* track) const
 {
-  /// Returns the number of hits in common between the current track ("this")
+  /// Returns the number of clusters in common between the current track ("this")
   /// and the track pointed to by "track".
-  Int_t hitsInCommon = 0;
-  AliMUONTrackParam *trackParamAtHit1, *trackParamAtHit2;
-  // Loop over hits of first track
-  trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->First();
-  while (trackParamAtHit1) {
-    // Loop over hits of second track
-    trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->First();
-    while (trackParamAtHit2) {
-      // Increment "hitsInCommon" if both TrackParamAtHits point to the same HitForRec
-      if ((trackParamAtHit1->GetHitForRecPtr()) == (trackParamAtHit2->GetHitForRecPtr())) {
-        hitsInCommon++;
+  Int_t clustersInCommon = 0;
+  AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2;
+  // Loop over clusters of first track
+  trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->First();
+  while (trackParamAtCluster1) {
+    // Loop over clusters of second track
+    trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->First();
+    while (trackParamAtCluster2) {
+      // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
+      if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
+        clustersInCommon++;
        break;
       }
-      trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->After(trackParamAtHit2);
-    } // trackParamAtHit2
-    trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->After(trackParamAtHit1);
-  } // trackParamAtHit1
-  return hitsInCommon;
+      trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->After(trackParamAtCluster2);
+    } // trackParamAtCluster2
+    trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->After(trackParamAtCluster1);
+  } // trackParamAtCluster1
+  return clustersInCommon;
 }
 
   //__________________________________________________________________________
@@ -909,68 +846,98 @@ Double_t AliMUONTrack::GetNormalizedChi2() const
 {
   /// return the chi2 value divided by the number of degrees of freedom (or 1.e10 if ndf < 0)
   
-  Double_t numberOfDegFree = (2. * fNTrackHits - 5.);
+  Double_t numberOfDegFree = (2. * GetNClusters() - 5.);
   if (numberOfDegFree > 0.) return fGlobalChi2 / numberOfDegFree;
   else return 1.e10;
 }
 
   //__________________________________________________________________________
-Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack * track, Double_t sigma2Cut) const
+Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack *track, Double_t sigma2Cut) const
 {
-  /// Return kTRUE/kFALSE for each chamber if hit is compatible or not 
-  TClonesArray *hitArray, *thisHitArray;
-  AliMUONHitForRec *hit, *thisHit;
-  Int_t chamberNumber;
-  Float_t deltaZ;
-  Float_t deltaZMax = 1.; // 1 cm
-  Float_t chi2 = 0;
-  Bool_t *nCompHit = new Bool_t[AliMUONConstants::NTrackingCh()]; 
-
-  for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) {
-    nCompHit[ch] = kFALSE;
-  }
+  /// for each chamber: return kTRUE (kFALSE) if clusters are compatible (not compatible)
+  AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2;
+  AliMUONVCluster *cluster1, *cluster2;
+  Double_t chi2, dX, dY, dZ;
+  Double_t chi2Max = sigma2Cut * sigma2Cut;
+  Double_t dZMax = 1.; // 1 cm
+  
+  Bool_t *compatibleCluster = new Bool_t[AliMUONConstants::NTrackingCh()]; 
+  for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) compatibleCluster[ch] = kFALSE;
 
-  thisHitArray = this->GetHitForRecAtHit();
-
-  hitArray =  track->GetHitForRecAtHit();
-
-  for (Int_t iHthis = 0; iHthis < thisHitArray->GetEntriesFast(); iHthis++) {
-    thisHit = (AliMUONHitForRec*) thisHitArray->At(iHthis);
-    chamberNumber = thisHit->GetChamberNumber();
-    if (chamberNumber < 0 || chamberNumber > AliMUONConstants::NTrackingCh()) continue; 
-    nCompHit[chamberNumber] = kFALSE;
-    for (Int_t iH = 0; iH < hitArray->GetEntriesFast(); iH++) {
-      hit = (AliMUONHitForRec*) hitArray->At(iH);
-      deltaZ = TMath::Abs(thisHit->GetZ() - hit->GetZ());
-      chi2 = thisHit->NormalizedChi2WithHitForRec(hit,sigma2Cut); // set cut to 4 sigmas
-      if (chi2 < 3. && deltaZ < deltaZMax) {
-       nCompHit[chamberNumber] = kTRUE;
-       break;
-      }
-    }  
+  // Loop over clusters of first track
+  trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->First();
+  while (trackParamAtCluster1) {
+    
+    cluster1 = trackParamAtCluster1->GetClusterPtr();
+    
+    // Loop over clusters of second track
+    trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->First();
+    while (trackParamAtCluster2) {
+      
+      cluster2 = trackParamAtCluster2->GetClusterPtr();
+      
+      //prepare next step
+      trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->After(trackParamAtCluster2);
+      
+      // z direction
+      dZ = cluster1->GetZ() - cluster2->GetZ();
+      if (dZ > dZMax) continue;
+      
+      // non bending direction
+      dX = cluster1->GetX() - cluster2->GetX();
+      chi2 = dX * dX / (cluster1->GetErrX2() + cluster2->GetErrX2());
+      if (chi2 > chi2Max) continue;
+      
+      // bending direction
+      dY = cluster1->GetY() - cluster2->GetY();
+      chi2 = dY * dY / (cluster1->GetErrY2() + cluster2->GetErrY2());
+      if (chi2 > chi2Max) continue;
+      
+      compatibleCluster[cluster1->GetChamberId()] = kTRUE;
+      break;
+    }
+    
+    trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->After(trackParamAtCluster1);
   }
   
-  return nCompHit;
+  return compatibleCluster;
 }
 
-  //__________________________________________________________________________
-void AliMUONTrack::RecursiveDump(void) const
+//__________________________________________________________________________
+AliMUONTrackParam* AliMUONTrack::GetTrackParamAtVertex()
+{
+  /// return reference to track parameters at vertex (create it before if needed)
+  if (!fTrackParamAtVertex) fTrackParamAtVertex = new AliMUONTrackParam();
+  return fTrackParamAtVertex;
+}
+
+//__________________________________________________________________________
+void AliMUONTrack::SetTrackParamAtVertex(const AliMUONTrackParam* trackParam)
+{
+  /// set track parameters at vertex
+  if (trackParam == 0x0) return;
+  if (fTrackParamAtVertex) *fTrackParamAtVertex = *trackParam;
+  else fTrackParamAtVertex = new AliMUONTrackParam(*trackParam);
+}
+
+//__________________________________________________________________________
+void AliMUONTrack::RecursiveDump() const
 {
-  /// Recursive dump of AliMUONTrack, i.e. with dump of TrackParamAtHit's and attached HitForRec's
-  AliMUONTrackParam *trackParamAtHit;
-  AliMUONHitForRec *hitForRec;
+  /// Recursive dump of AliMUONTrack, i.e. with dump of trackParamAtCluster and attached clusters
+  AliMUONTrackParam *trackParamAtCluster;
+  AliMUONVCluster *cluster;
   cout << "Recursive dump of Track: " << this << endl;
   // Track
   this->Dump();
-  for (Int_t trackHitIndex = 0; trackHitIndex < fNTrackHits; trackHitIndex++) {
-    trackParamAtHit = (AliMUONTrackParam*) ((*fTrackParamAtHit)[trackHitIndex]);
-    // TrackHit
-    cout << "TrackParamAtHit: " << trackParamAtHit << " (index: " << trackHitIndex << ")" << endl;
-    trackParamAtHit->Dump();
-    hitForRec = trackParamAtHit->GetHitForRecPtr();
-    // HitForRec
-    cout << "HitForRec: " << hitForRec << endl;
-    hitForRec->Dump();
+  for (Int_t iCluster = 0; iCluster < GetNClusters(); iCluster++) {
+    trackParamAtCluster = (AliMUONTrackParam*) ((*fTrackParamAtCluster)[iCluster]);
+    // trackParamAtCluster
+    cout << "trackParamAtCluster: " << trackParamAtCluster << " (index: " << iCluster << ")" << endl;
+    trackParamAtCluster->Dump();
+    cluster = trackParamAtCluster->GetClusterPtr();
+    // cluster
+    cout << "cluster: " << cluster << endl;
+    cluster->Print();
   }
   return;
 }
@@ -980,12 +947,12 @@ void AliMUONTrack::Print(Option_t*) const
 {
   /// Printing Track information 
 
-  cout << "<AliMUONTrack> No.Clusters=" << setw(2)   << GetNTrackHits() << 
+  cout << "<AliMUONTrack> No.Clusters=" << setw(2)   << GetNClusters() << 
       ", Match2Trig=" << setw(1) << GetMatchTrigger()  << 
       ", LoTrgNum=" << setw(3) << GetLoTrgNum()  << 
     ", Chi2-tracking-trigger=" << setw(8) << setprecision(5) <<  GetChi2MatchTrigger();
   cout << Form(" HitTriggerPattern %x",fHitsPatternInTrigCh) << endl;
-  GetTrackParamAtHit()->First()->Print("FULL");
+  fTrackParamAtCluster->First()->Print("FULL");
 }
 
 //__________________________________________________________________________
index c3eda41..b7b072c 100644 (file)
@@ -17,7 +17,7 @@
 #include "AliMUONTrackParam.h" // object belongs to the class
 #include <TClonesArray.h>
 
-class AliMUONHitForRec;
+class AliMUONVCluster;
 class AliMUONObjectPair;
 
 class AliMUONTrack : public TObject 
@@ -30,89 +30,80 @@ class AliMUONTrack : public TObject
   AliMUONTrack& operator=(const AliMUONTrack& track); // assignment operator
 
 
-       /// return pointeur to track parameters at vertex
-  AliMUONTrackParam*         GetTrackParamAtVertex() {return &fTrackParamAtVertex;}
-       /// set track parameters at vertex
-  void                       SetTrackParamAtVertex(const AliMUONTrackParam* trackParam) {fTrackParamAtVertex = *trackParam;}
-
-       /// return array of track parameters at hit
-  TClonesArray*              GetTrackParamAtHit() const {return fTrackParamAtHit;}
-       /// reset array of track parameters at hit
-  void                       ResetTrackParamAtHit() { fTrackParamAtHit->Delete(); }
-  void                       AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec); 
-  void                       RemoveTrackParamAtHit(AliMUONTrackParam *trackParam);
-  void                       UpdateTrackParamAtHit();
-  void                       UpdateCovTrackParamAtHit();
-  
-       /// return array of hitForRec at hit
-  TClonesArray*              GetHitForRecAtHit() const {return fHitForRecAtHit;}
-       /// reset array of hitForRec at hit
-  void                       ResetHitForRecAtHit() { fHitForRecAtHit->Delete(); }
-  void                       AddHitForRecAtHit(const AliMUONHitForRec *hitForRec); 
-
-       /// return the number of hits attached to the track
-  Int_t                      GetNTrackHits() const {return fNTrackHits;}
-       /// set the number of hits attached to the track
-  void                       SetNTrackHits(Int_t nTrackHits) {fNTrackHits = nTrackHits;}
-
-       /// return kTrue if the vertex must be used to constrain the fit, kFalse if not
-  Bool_t                     GetFitWithVertex() const {return fFitWithVertex;}
-       /// set the flag telling whether the vertex must be used to constrain the fit or not
-  void                       SetFitWithVertex(Bool_t fitWithVertex) { fFitWithVertex = fitWithVertex; }
-       /// return the vertex used during the tracking procedure
-  AliMUONHitForRec*          GetVertex() const {return fVertex;}
-  void                       SetVertex(const AliMUONHitForRec* vertex);
-
-       /// return kTrue if the multiple scattering must be accounted for in the fit, kFalse if not
-  Bool_t                     GetFitWithMCS() const {return fFitWithMCS;}
-       /// set the flag telling whether the multiple scattering must be accounted for in the fit or not
-  void                       SetFitWithMCS(Bool_t fitWithMCS) {fFitWithMCS = fitWithMCS;}
-  
-  Bool_t    ComputeHitWeights(TMatrixD* mcsCovariances = 0);
-  Bool_t    ComputeLocalChi2(Bool_t accountForMCS);
-  Double_t  ComputeGlobalChi2(Bool_t accountForMCS);
-
-       /// return the minimum value of the function minimized by the fit
-  Double_t                   GetFitFMin() const {return fGlobalChi2;}
-       /// set the minimum value of the function minimized by the fit
-  void                       SetFitFMin(Double_t chi2) { fGlobalChi2 = chi2;}
-  
-       /// return kTRUE if the track has been improved
-  Bool_t                     IsImproved() const {return fImproved;}
-       /// set the flag telling whether the track has been improved or not
-  void                       SetImproved(Bool_t improved) { fImproved = improved;}
-  
-        /// return 1,2,3 if track matches with trigger track, 0 if not
-  Int_t                      GetMatchTrigger(void) const {return fMatchTrigger;}
+  /// return array of track parameters at cluster
+  TClonesArray* GetTrackParamAtCluster() const {return fTrackParamAtCluster;}
+  void          AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy = kFALSE); 
+  void          RemoveTrackParamAtCluster(AliMUONTrackParam *trackParam);
+  void          UpdateTrackParamAtCluster();
+  void          UpdateCovTrackParamAtCluster();
+  
+  /// return the number of clusters attached to the track
+  Int_t GetNClusters() const {return fTrackParamAtCluster->GetEntriesFast();}
+
+  /// return kTrue if the vertex must be used to constrain the fit, kFalse if not
+  Bool_t FitWithVertex() const {return fFitWithVertex;}
+  /// set the flag telling whether the vertex must be used to constrain the fit or not
+  void   FitWithVertex(Bool_t fitWithVertex) { fFitWithVertex = fitWithVertex; }
+  /// return the vertex resolution square used during the tracking procedure
+  void   GetVertexErrXY2(Double_t &nonBendingErr2, Double_t &bendingErr2) const
+         { nonBendingErr2 = fVertexErrXY2[0]; bendingErr2 = fVertexErrXY2[1]; }
+  /// set the vertex resolution square used during the tracking procedure
+  void   SetVertexErrXY2(Double_t nonBendingErr2, Double_t bendingErr2)
+        { fVertexErrXY2[0] = nonBendingErr2; fVertexErrXY2[1] = bendingErr2; }
+
+  /// return kTrue if the multiple scattering must be accounted for in the fit, kFalse if not
+  Bool_t FitWithMCS() const {return fFitWithMCS;}
+  /// set the flag telling whether the multiple scattering must be accounted for in the fit or not
+  void   FitWithMCS(Bool_t fitWithMCS) {fFitWithMCS = fitWithMCS;}
+  
+  Bool_t   ComputeClusterWeights(TMatrixD* mcsCovariances = 0);
+  Bool_t   ComputeLocalChi2(Bool_t accountForMCS);
+  Double_t ComputeGlobalChi2(Bool_t accountForMCS);
+
+  /// return the minimum value of the function minimized by the fit
+  Double_t GetGlobalChi2() const {return fGlobalChi2;}
+  /// set the minimum value of the function minimized by the fit
+  void     SetGlobalChi2(Double_t chi2) { fGlobalChi2 = chi2;}
+  
+  /// return kTRUE if the track has been improved
+  Bool_t IsImproved() const {return fImproved;}
+  /// set the flag telling whether the track has been improved or not
+  void   SetImproved(Bool_t improved) { fImproved = improved;}
+  
+  /// return 1,2,3 if track matches with trigger track, 0 if not
+  Int_t    GetMatchTrigger(void) const {return fMatchTrigger;}
   /// returns the local trigger number corresponding to the trigger track 
-  Int_t                      GetLoTrgNum(void) const {return floTrgNum;}
-       /// set the flag telling whether track matches with trigger track or not
-   void                             SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;}
-   /// set the local trigger number corresponding to the trigger track
-   void                             SetLoTrgNum(Int_t loTrgNum) {floTrgNum = loTrgNum;}
-       /// return the chi2 of trigger/track matching 
-  Double_t                   GetChi2MatchTrigger(void) const {return fChi2MatchTrigger;}
-       /// set the chi2 of trigger/track matching 
-  void                       SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;}
+  Int_t    GetLoTrgNum(void) const {return floTrgNum;}
+  /// set the flag telling whether track matches with trigger track or not
+  void    SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;}
+  /// set the local trigger number corresponding to the trigger track
+  void    SetLoTrgNum(Int_t loTrgNum) {floTrgNum = loTrgNum;}
+  /// return the chi2 of trigger/track matching 
+  Double_t GetChi2MatchTrigger(void) const {return fChi2MatchTrigger;}
+  /// set the chi2 of trigger/track matching 
+  void     SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;}
 
-  Int_t                      HitsInCommon(AliMUONTrack* track) const;
+  Int_t ClustersInCommon(AliMUONTrack* track) const;
 
-  Double_t                   GetNormalizedChi2() const;
+  Double_t GetNormalizedChi2() const;
 
-  Bool_t*                    CompatibleTrack(AliMUONTrack* track, Double_t sigma2Cut) const; // return array of compatible chamber
+  Bool_t* CompatibleTrack(AliMUONTrack* track, Double_t sigma2Cut) const; // return array of compatible chamber
   
-       /// return track number in TrackRefs
-  Int_t                      GetTrackID() const {return fTrackID;}
-       /// set track number in TrackRefs
-  void                       SetTrackID(Int_t trackID) {fTrackID = trackID;}
+  /// return track number in TrackRefs
+  Int_t GetTrackID() const {return fTrackID;}
+  /// set track number in TrackRefs
+  void  SetTrackID(Int_t trackID) {fTrackID = trackID;}
 
-        /// set word telling which trigger chambers where hit by track
-  UShort_t                   GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;}
-        /// set word telling which trigger chambers where hit by track
-  void                       SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;}
+  AliMUONTrackParam* GetTrackParamAtVertex();
+  void               SetTrackParamAtVertex(const AliMUONTrackParam* trackParam);
+
+  /// set word telling which trigger chambers where hit by track
+  UShort_t GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;}
+  /// set word telling which trigger chambers where hit by track
+  void     SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;}
 
   /// set local trigger information for the matched trigger track
-  void SetLocalTrigger(Int_t loCirc, Int_t loStripX, Int_t loStripY, Int_t loDev, Int_t loLpt, Int_t loHpt);
+  void  SetLocalTrigger(Int_t loCirc, Int_t loStripX, Int_t loStripY, Int_t loDev, Int_t loLpt, Int_t loHpt);
   /// return local trigger information for the matched trigger track
   Int_t GetLocalTrigger(void) const { return fLocalTrigger;              }
   /// number of triggering circuit
@@ -128,29 +119,26 @@ class AliMUONTrack : public TObject
   /// high pt decision local trigger 
   Int_t LoHpt(void)    const  { return fLocalTrigger >> 24 & 0x03; }
 
-  void                       RecursiveDump(void) const; // Recursive dump (with track hits)
+  void RecursiveDump(void) const; // Recursive dump (with associated clusters)
 
-  virtual void               Print(Option_t* opt="") const;
+  virtual void Print(Option_t* opt="") const;
 
   virtual void Clear(Option_t* opt="");
 
 
  private:
  
-  AliMUONTrackParam fTrackParamAtVertex; //!< Track parameters at vertex
-  TClonesArray *fTrackParamAtHit; ///< Track parameters at hit
-  TClonesArray *fHitForRecAtHit; ///< Cluster parameters at hit
-  Int_t fNTrackHits; ///< Number of hits attached to the track
+  TClonesArray* fTrackParamAtCluster; ///< Track parameters at cluster
   
-  Bool_t fFitWithVertex; //!< kTRUE if using the vertex to constrain the fit, kFALSE if not
-  AliMUONHitForRec *fVertex; //!< Vertex used during the tracking procedure if required
+  Bool_t   fFitWithVertex;   //!< kTRUE if using the vertex to constrain the fit, kFALSE if not
+  Double_t fVertexErrXY2[2]; //!< Vertex resolution square used during the tracking procedure if required
   
   Bool_t fFitWithMCS; //!< kTRUE if accounting for multiple scattering in the fit, kFALSE if not
   
-  TMatrixD* fHitWeightsNonBending; //!< weights matrix, in non bending direction, of hits attached to the track
-                                  //!< (accounting for multiple scattering and hits resolution)
-  TMatrixD* fHitWeightsBending;    //!< weights matrix, in bending direction, of hits attached to the track
-                                  //!< (accounting for multiple scattering and hits resolution)
+  TMatrixD* fClusterWeightsNonBending; //!< weights matrix, in non bending direction, of clusters attached to the track
+                                      //!< (accounting for multiple scattering and cluster resolution)
+  TMatrixD* fClusterWeightsBending;    //!< weights matrix, in bending direction, of clusters attached to the track
+                                      //!< (accounting for multiple scattering and cluster resolution)
   
   Double_t fGlobalChi2; ///< Global chi2 of the track
   
@@ -164,17 +152,21 @@ class AliMUONTrack : public TObject
   Double_t fChi2MatchTrigger; ///< chi2 of trigger/track matching 
   
   Int_t fTrackID; ///< track ID = track number in TrackRefs
+  
+  AliMUONTrackParam* fTrackParamAtVertex; //!< Track parameters at vertex
+  
   UShort_t fHitsPatternInTrigCh; ///< Word containing info on the hits left in trigger chambers
 
   Int_t fLocalTrigger;    ///< packed local trigger information
   
   
   // methods
-  Bool_t ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeightsB, TMatrixD* mcsCovariances = 0, AliMUONHitForRec* discardedHit = 0) const;
+  Bool_t ComputeClusterWeights(TMatrixD& clusterWeightsNB, TMatrixD& clusterWeightsB,
+                              TMatrixD* mcsCovariances = 0, AliMUONVCluster* discardedCluster = 0) const;
   void   ComputeMCSCovariances(TMatrixD& mcsCovariances) const;
   
   
-  ClassDef(AliMUONTrack, 7) // Reconstructed track in ALICE dimuon spectrometer
+  ClassDef(AliMUONTrack, 8) // Reconstructed track in ALICE dimuon spectrometer
 };
        
 #endif
index b3f56c2..88977ce 100644 (file)
@@ -121,7 +121,7 @@ void AliMUONTrackHitPattern::GetHitPattern(AliMUONVTrackStore& trackStore,
     {
       pattern = 0;
       AliMUONTrackParam trackParam = (*(static_cast<AliMUONTrackParam*> 
-        (muonTrack->GetTrackParamAtHit()->Last())));
+        (muonTrack->GetTrackParamAtCluster()->Last())));
       
       for(Int_t ch=0; ch<4; ++ch)
       {
index fe79c5a..abe4d71 100644 (file)
@@ -133,7 +133,7 @@ AliMUONTrackLight::~AliMUONTrackLight()
 
 void AliMUONTrackLight::FillFromAliMUONTrack(AliMUONTrack *trackReco,Double_t zvert){
   /// this method sets the muon reconstructed momentum according to the value given by AliMUONTrack
-  AliMUONTrackParam trPar(*((AliMUONTrackParam*) (trackReco->GetTrackParamAtHit()->First())));
+  AliMUONTrackParam trPar(*((AliMUONTrackParam*) (trackReco->GetTrackParamAtCluster()->First())));
   //  AliMUONTrackParam *trPar  = trackReco->GetTrackParamAtVertex();
   AliMUONTrackExtrap::ExtrapToVertex(&trPar,0.,0.,0.);
   this->SetCharge(Int_t(TMath::Sign(1.,trPar.GetInverseBendingMomentum())));
index c67058f..694e408 100644 (file)
@@ -22,7 +22,7 @@
 //-----------------------------------------------------------------------------
 
 #include "AliMUONTrackParam.h"
-#include "AliMUONHitForRec.h"
+#include "AliMUONVCluster.h"
 
 #include "AliESDMuonTrack.h"
 #include "AliLog.h"
@@ -46,7 +46,8 @@ AliMUONTrackParam::AliMUONTrackParam()
     fExtrapCovariances(0x0),
     fSmoothParameters(0x0),
     fSmoothCovariances(0x0),
-    fHitForRecPtr(0x0),
+    fClusterPtr(0x0),
+    fOwnCluster(kFALSE),
     fRemovable(kFALSE),
     fAloneInChamber(kTRUE),
     fTrackChi2(0.),
@@ -66,7 +67,8 @@ AliMUONTrackParam::AliMUONTrackParam(const AliMUONTrackParam& theMUONTrackParam)
     fExtrapCovariances(0x0),
     fSmoothParameters(0x0),
     fSmoothCovariances(0x0),
-    fHitForRecPtr(theMUONTrackParam.fHitForRecPtr),
+    fClusterPtr(0x0),
+    fOwnCluster(theMUONTrackParam.fOwnCluster),
     fRemovable(theMUONTrackParam.fRemovable),
     fAloneInChamber(theMUONTrackParam.fAloneInChamber),
     fTrackChi2(theMUONTrackParam.fTrackChi2),
@@ -79,6 +81,9 @@ AliMUONTrackParam::AliMUONTrackParam(const AliMUONTrackParam& theMUONTrackParam)
   if (theMUONTrackParam.fExtrapCovariances) fExtrapCovariances = new TMatrixD(*(theMUONTrackParam.fExtrapCovariances));
   if (theMUONTrackParam.fSmoothParameters) fSmoothParameters = new TMatrixD(*(theMUONTrackParam.fSmoothParameters));
   if (theMUONTrackParam.fSmoothCovariances) fSmoothCovariances = new TMatrixD(*(theMUONTrackParam.fSmoothCovariances));
+  
+  if(fOwnCluster) fClusterPtr = theMUONTrackParam.fClusterPtr->CreateCopy();
+  else fClusterPtr = theMUONTrackParam.fClusterPtr;
 }
 
   //_________________________________________________________________________
@@ -143,7 +148,9 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
     fSmoothCovariances = 0x0;
   }
   
-  fHitForRecPtr = theMUONTrackParam.fHitForRecPtr;
+  fOwnCluster = theMUONTrackParam.fOwnCluster;
+  if(fOwnCluster) fClusterPtr = theMUONTrackParam.fClusterPtr->CreateCopy();
+  else fClusterPtr = theMUONTrackParam.fClusterPtr;
   
   fRemovable = theMUONTrackParam.fRemovable;
   
@@ -165,28 +172,23 @@ AliMUONTrackParam::~AliMUONTrackParam()
   delete fExtrapCovariances;
   delete fSmoothParameters;
   delete fSmoothCovariances;
+  if(fOwnCluster) delete fClusterPtr;
 }
 
   //__________________________________________________________________________
 void
 AliMUONTrackParam::Clear(Option_t* /*opt*/)
 {
-  /// Delete the covariance matrix
+  /// clear memory
   DeleteCovariances();
   delete fPropagator; fPropagator = 0x0;
   delete fExtrapParameters; fExtrapParameters = 0x0;
   delete fExtrapCovariances; fExtrapCovariances = 0x0;
   delete fSmoothParameters; fSmoothParameters = 0x0;
   delete fSmoothCovariances; fSmoothCovariances = 0x0;
-}
-
-  //__________________________________________________________________________
-AliMUONHitForRec* AliMUONTrackParam::GetHitForRecPtr(void) const
-{
-/// return pointer to HitForRec attached to the current TrackParam
-/// this method should not be called when fHitForRecPtr == NULL
-  if (!fHitForRecPtr) AliWarning("fHitForRecPtr == NULL");
-  return fHitForRecPtr;
+  if(fOwnCluster) {
+    delete fClusterPtr; fClusterPtr = 0x0;
+  }
 }
 
   //_________________________________________________________________________
@@ -402,7 +404,7 @@ const TMatrixD& AliMUONTrackParam::GetPropagator() const
     fPropagator->UnitMatrix();
   }
   return *fPropagator;
-  }
+}
 
   //__________________________________________________________________________
 void AliMUONTrackParam::ResetPropagator()
@@ -499,12 +501,8 @@ void AliMUONTrackParam::SetSmoothCovariances(const TMatrixD& smoothCovariances)
 Int_t AliMUONTrackParam::Compare(const TObject* trackParam) const
 {
   /// "Compare" function to sort with decreasing Z (spectro. muon Z <0).
-  /// Returns 1 (0, -1) if Z of current TrackHit
-  /// is smaller than (equal to, larger than) Z of TrackHit
-  if (fHitForRecPtr) {
-    if (fHitForRecPtr->GetZ() != fZ)
-      AliWarning("track parameters are given at a different z position than the one of the corresponding hit");
-  }
+  /// Returns 1 (0, -1) if the current Z
+  /// is smaller than (equal to, larger than) Z of trackParam
   if (fZ < ((AliMUONTrackParam*)trackParam)->GetZ()) return(1);
   else if (fZ == ((AliMUONTrackParam*)trackParam)->GetZ()) return(0);
   else return(-1);
index 9dd8a7f..4523bff 100644 (file)
@@ -17,7 +17,7 @@
 #include <TObject.h>
 #include <TMatrixD.h>
 
-class AliMUONHitForRec;
+class AliMUONVCluster;
 class AliESDMuonTrack;
 
 class AliMUONTrackParam : public TObject 
@@ -104,30 +104,31 @@ class AliMUONTrackParam : public TObject
   const TMatrixD& GetSmoothCovariances() const;
   void            SetSmoothCovariances(const TMatrixD& covariances);
   
-  AliMUONHitForRec* GetHitForRecPtr() const;
-       /// set pointeur to associated HitForRec
-  void              SetHitForRecPtr(AliMUONHitForRec* hitForRec) {fHitForRecPtr = hitForRec;}
+        /// get pointeur to associated cluster
+  AliMUONVCluster* GetClusterPtr() const {return fClusterPtr;}
+       /// set pointeur to associated cluster
+  void             SetClusterPtr(AliMUONVCluster* cluster, Bool_t owner = kFALSE) {fClusterPtr = cluster; fOwnCluster = owner;}
   
-       /// return kTRUE if the associated hit can be removed from the track it belongs to
+       /// return kTRUE if the associated cluster can be removed from the track it belongs to
   Bool_t IsRemovable() const {return fRemovable;}
-       /// set the flag telling whether the associated hit can be removed from the track it belongs to or not
+       /// set the flag telling whether the associated cluster can be removed from the track it belongs to or not
   void   SetRemovable(Bool_t removable) {fRemovable = removable;}
   
-       /// return kTRUE if the associated hit alone in its chamber
+       /// return kTRUE if the associated cluster alone in its chamber
   Bool_t IsAloneInChamber() const {return fAloneInChamber;}
        /// set the flag telling whether the associated hi alone in its chamber or not
   void   SetAloneInChamber(Bool_t aloneInChamber) {fAloneInChamber = aloneInChamber;}
   
-  /// return the chi2 of the track when the associated HitForRec was attached
+  /// return the chi2 of the track when the associated cluster was attached
   Double_t GetTrackChi2() const {return fTrackChi2;}
-       /// set the chi2 of the track when the associated HitForRec was attached
+       /// set the chi2 of the track when the associated cluster was attached
   void     SetTrackChi2(Double_t chi2) {fTrackChi2 = chi2;}
-       /// return the local chi2 of the associated HitForRec with respect to the track
+       /// return the local chi2 of the associated cluster with respect to the track
   Double_t GetLocalChi2() const {return fLocalChi2;}
-       /// set the local chi2 of the associated HitForRec with respect to the track
+       /// set the local chi2 of the associated cluster with respect to the track
   void     SetLocalChi2(Double_t chi2) {fLocalChi2 = chi2;}
   
-       /// necessary for sorting TClonesArray of TrackHit's
+       /// necessary for sorting TClonesArray of AliMUONTrackParam
   Bool_t IsSortable () const {return kTRUE;}
   Int_t Compare(const TObject* trackParam) const;
 
@@ -155,21 +156,22 @@ class AliMUONTrackParam : public TObject
   /// <X,InvP_yz> <SlopeX,InvP_yz> <Y,InvP_yz> <SlopeY,InvP_yz> <InvP_yz,InvP_yz>  </pre>
   mutable TMatrixD *fCovariances; ///< \brief Covariance matrix of track parameters 
   
-  mutable TMatrixD *fPropagator; //!< Jacobian used to extrapolate the track parameters and covariances to the actual z position
-  mutable TMatrixD *fExtrapParameters; //!< Track parameters extrapolated to the actual z position (not filtered by Kalman)
+  mutable TMatrixD *fPropagator;        //!< Jacobian used to extrapolate the track parameters and covariances to the actual z position
+  mutable TMatrixD *fExtrapParameters;  //!< Track parameters extrapolated to the actual z position (not filtered by Kalman)
   mutable TMatrixD *fExtrapCovariances; //!< Covariance matrix extrapolated to the actual z position (not filtered by Kalman)
   
-  mutable TMatrixD *fSmoothParameters; //!< Track parameters obtained using smoother
+  mutable TMatrixD *fSmoothParameters;  //!< Track parameters obtained using smoother
   mutable TMatrixD *fSmoothCovariances; //!< Covariance matrix obtained using smoother
   
-  AliMUONHitForRec *fHitForRecPtr; //!< Pointer to associated HitForRec if any
+  AliMUONVCluster *fClusterPtr; //!< Pointer to associated cluster if any
+  Bool_t           fOwnCluster; //!< Ownership of the associated cluster
   
-  Bool_t fRemovable; //!< kTRUE if the associated hit can be removed from the track it belongs to
+  Bool_t fRemovable; //!< kTRUE if the associated cluster can be removed from the track it belongs to
   
-  Bool_t fAloneInChamber; //!< kTRUE if the associated hit is alone in its chamber
+  Bool_t fAloneInChamber; //!< kTRUE if the associated cluster is alone in its chamber
 
-  Double_t fTrackChi2; //!< Chi2 of the track when the associated HitForRec was attached
-  Double_t fLocalChi2; //!< Local chi2 of the associated HitForRec with respect to the track
+  Double_t fTrackChi2; //!< Chi2 of the track when the associated cluster was attached
+  Double_t fLocalChi2; //!< Local chi2 of the associated cluster with respect to the track
   
   ClassDef(AliMUONTrackParam, 4) // Track parameters in ALICE dimuon spectrometer
 };
index 96aac39..2ce0754 100644 (file)
@@ -29,7 +29,8 @@
 #include "AliMUONTrackReconstructor.h"
 
 #include "AliMUONConstants.h"
-#include "AliMUONHitForRec.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterStore.h"
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
 #include "AliMUONTrackExtrap.h"
@@ -52,8 +53,7 @@ ClassImp(AliMUONTrackReconstructor) // Class implementation in ROOT context
 AliMUONTrackReconstructor::AliMUONTrackReconstructor()
   : AliMUONVTrackReconstructor()
 {
-  /// Constructor for class AliMUONTrackReconstructor
-  AliInfo("*** Original tracking ***");
+  /// Constructor
 }
 
   //__________________________________________________________________________
@@ -63,17 +63,17 @@ AliMUONTrackReconstructor::~AliMUONTrackReconstructor()
 } 
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::MakeTrackCandidates()
+void AliMUONTrackReconstructor::MakeTrackCandidates(const AliMUONVClusterStore& clusterStore)
 {
   /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
   /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4.
-  /// Good candidates are made of at least three hitForRec's.
+  /// Good candidates are made of at least three clusters.
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
   
   TClonesArray *segments;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
-  Bool_t hitFound;
+  Bool_t clusterFound;
 
   AliDebug(1,"Enter MakeTrackCandidates");
 
@@ -81,7 +81,7 @@ void AliMUONTrackReconstructor::MakeTrackCandidates()
   for (Int_t istat=4; istat>=3; istat--) {
     
     // Make segments in the station
-    segments = MakeSegmentsInStation(istat);
+    segments = MakeSegmentsInStation(clusterStore,istat);
     
     // Loop over segments
     for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) 
@@ -93,18 +93,18 @@ void AliMUONTrackReconstructor::MakeTrackCandidates()
       fNRecTracks++;
       
       // Printout for debuging
-      if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2))
-      {
-        cout<<endl<<"Track parameter covariances at first hit with multiple Coulomb scattering effects:"<<endl;
-        ((AliMUONTrackParam*) track->GetTrackParamAtHit()->First())->GetCovariances().Print();
+      if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
+        cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
+        ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First())->GetCovariances().Print();
       }
       
-      // Look for compatible hitForRec(s) in the other station
-      if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) hitFound = FollowLinearTrackInStation(*track,7-istat);
-      else hitFound = FollowTrackInStation(*track,7-istat);
+      // Look for compatible cluster(s) in the other station
+      if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
+       clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
+      else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
       
-      // Remove track if no hit found
-      if (!hitFound) {
+      // Remove track if no cluster found
+      if (!clusterFound) {
         fRecTracksPtr->Remove(track);
        fNRecTracks--;
       }
@@ -126,7 +126,7 @@ void AliMUONTrackReconstructor::MakeTrackCandidates()
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::FollowTracks()
+void AliMUONTrackReconstructor::FollowTracks(const AliMUONVClusterStore& clusterStore)
 {
   /// Follow tracks in stations(1..) 3, 2 and 1
   AliDebug(1,"Enter FollowTracks");
@@ -134,7 +134,7 @@ void AliMUONTrackReconstructor::FollowTracks()
   AliMUONTrack *track, *nextTrack;
   AliMUONTrackParam *trackParam, *nextTrackParam;
   Int_t currentNRecTracks;
-  Bool_t hitFound;
+  Bool_t clusterFound;
   
   Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
                        AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking();
@@ -155,11 +155,8 @@ void AliMUONTrackReconstructor::FollowTracks()
       // Do not take into account the multiple scattering to speed up the fit
       // Calculate the track parameter covariance matrix
       // If "station" is station(1..) 3 then use the vertex to better constrain the fit
-      if (station==2) {
-        SetVertexForFit(*track);
-        track->SetFitWithVertex(kTRUE);
-      } else track->SetFitWithVertex(kFALSE);
-      Fit(*track, kFALSE, kTRUE);
+      if (station==2) Fit(*track, kFALSE, kTRUE, kTRUE);
+      else Fit(*track, kFALSE, kFALSE, kTRUE);
       
       // Remove the track if the normalized chi2 is too high
       if (track->GetNormalizedChi2() > sigmaCut2) {
@@ -174,26 +171,26 @@ void AliMUONTrackReconstructor::FollowTracks()
        if (station==2) { // save track parameters on stations 4 and 5
          
          // extrapolate track parameters and covariances at each cluster
-         track->UpdateCovTrackParamAtHit();
+         track->UpdateCovTrackParamAtCluster();
          
          // save them
-         trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First();
+         trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
          while (trackParam) {
            trackParam->SetSmoothParameters(trackParam->GetParameters());
            trackParam->SetSmoothCovariances(trackParam->GetCovariances());
-           trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam);
+           trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
          }
          
        } else { // or save track parameters on last station only
          
          // save parameters from fit
-         trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First();
+         trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
          trackParam->SetSmoothParameters(trackParam->GetParameters());
          trackParam->SetSmoothCovariances(trackParam->GetCovariances());
          
          // save parameters extrapolated to the second chamber of the same station if it has been hit
-         nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam);
-         if (nextTrackParam->GetHitForRecPtr()->GetChamberNumber() < 2*(station+2)) {
+         nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
+         if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) {
            
            // reset parameters and covariances
            nextTrackParam->SetParameters(trackParam->GetParameters());
@@ -201,7 +198,7 @@ void AliMUONTrackReconstructor::FollowTracks()
            nextTrackParam->SetCovariances(trackParam->GetCovariances());
            
            // extrapolate them to the z of the corresponding cluster
-           AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetHitForRecPtr()->GetZ());
+           AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ());
            
            // save them
            nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
@@ -215,18 +212,19 @@ void AliMUONTrackReconstructor::FollowTracks()
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-        cout<<endl<<"Track parameter covariances at first hit with multiple Coulomb scattering effects:"<<endl;
-        ((AliMUONTrackParam*) track->GetTrackParamAtHit()->First())->GetCovariances().Print();
+        cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
+        ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First())->GetCovariances().Print();
       }
       
-      // Look for compatible hitForRec in station(0..) "station"
-      hitFound = FollowTrackInStation(*track,station);
+      // Look for compatible cluster(s) in station(0..) "station"
+      clusterFound = FollowTrackInStation(*track, clusterStore, station);
       
       // Try to recover track if required
-      if (!hitFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks()) hitFound = RecoverTrack(*track,station);
+      if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks())
+       clusterFound = RecoverTrack(*track, clusterStore, station);
       
-      // remove track if no hit found
-      if (!hitFound) {
+      // remove track if no cluster found
+      if (!clusterFound) {
        fRecTracksPtr->Remove(track);
        fNRecTracks--;
       }
@@ -241,7 +239,7 @@ void AliMUONTrackReconstructor::FollowTracks()
     
   }
   
-  // Last fit of track candidates with all station
+  // Last fit of track candidates with all stations
   // Take into account the multiple scattering and remove bad tracks
   Int_t trackIndex = -1;
   track = (AliMUONTrack*) fRecTracksPtr->First();
@@ -250,8 +248,7 @@ void AliMUONTrackReconstructor::FollowTracks()
     trackIndex++;
     nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track); // prepare next track
     
-    track->SetFitWithVertex(kFALSE); // just to be sure
-    Fit(*track, kTRUE, kTRUE);
+    Fit(*track, kTRUE, kFALSE, kTRUE);
     
     // Printout for debuging
     if (AliLog::GetGlobalDebugLevel() >= 3) {
@@ -269,13 +266,13 @@ void AliMUONTrackReconstructor::FollowTracks()
     if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) {
       
       // save parameters from fit
-      trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First();
+      trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
       trackParam->SetSmoothParameters(trackParam->GetParameters());
       trackParam->SetSmoothCovariances(trackParam->GetCovariances());
       
       // save parameters extrapolated to the second chamber of the same station if it has been hit
-      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam);
-      if (nextTrackParam->GetHitForRecPtr()->GetChamberNumber() < 2) {
+      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
+      if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2) {
        
        // reset parameters and covariances
        nextTrackParam->SetParameters(trackParam->GetParameters());
@@ -283,7 +280,7 @@ void AliMUONTrackReconstructor::FollowTracks()
        nextTrackParam->SetCovariances(trackParam->GetCovariances());
        
        // extrapolate them to the z of the corresponding cluster
-       AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetHitForRecPtr()->GetZ());
+       AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ());
        
        // save them
        nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
@@ -302,14 +299,14 @@ void AliMUONTrackReconstructor::FollowTracks()
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation)
+Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation)
 {
-  /// Follow trackCandidate in station(0..) nextStation and search for compatible HitForRec(s)
+  /// Follow trackCandidate in station(0..) nextStation and search for compatible cluster(s)
   /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
   /// kTRUE:  duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
   ///         fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
   ///         Remove the obsolete "trackCandidate" at the end.
-  /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority.
+  /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority.
   AliDebug(1,Form("Enter FollowTrackInStation(1..) %d", nextStation+1));
   
   // Order the chamber according to the propagation direction (tracking starts with chamber 2):
@@ -324,34 +321,37 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
     ch2 = 2*nextStation+1;
   }
   
-  Double_t chi2WithOneHitForRec = 1.e10;
-  Double_t chi2WithTwoHitForRec = 1.e10;
-  Double_t maxChi2WithOneHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
-                                          AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
-  Double_t maxChi2WithTwoHitForRec = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
-                                          AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2
-  Double_t bestChi2WithOneHitForRec = maxChi2WithOneHitForRec;
-  Double_t bestChi2WithTwoHitForRec = maxChi2WithTwoHitForRec;
-  Bool_t foundOneHit = kFALSE;
-  Bool_t foundTwoHits = kFALSE;
+  Double_t chi2WithOneCluster = 1.e10;
+  Double_t chi2WithTwoClusters = 1.e10;
+  Double_t maxChi2WithOneCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+                                       AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+  Double_t maxChi2WithTwoClusters = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+                                        AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2
+  Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
+  Double_t bestChi2WithTwoClusters = maxChi2WithTwoClusters;
+  Bool_t foundOneCluster = kFALSE;
+  Bool_t foundTwoClusters = kFALSE;
   AliMUONTrack *newTrack = 0x0;
-  AliMUONHitForRec *hitForRecCh1, *hitForRecCh2;
+  AliMUONVCluster *clusterCh1, *clusterCh2;
   AliMUONTrackParam extrapTrackParam;
-  AliMUONTrackParam extrapTrackParamAtHit1;
-  AliMUONTrackParam extrapTrackParamAtHit2;
-  AliMUONTrackParam bestTrackParamAtHit1;
-  AliMUONTrackParam bestTrackParamAtHit2;
-  Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]];
-  for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE;
+  AliMUONTrackParam extrapTrackParamAtCluster1;
+  AliMUONTrackParam extrapTrackParamAtCluster2;
+  AliMUONTrackParam bestTrackParamAtCluster1;
+  AliMUONTrackParam bestTrackParamAtCluster2;
+  
+  Int_t nClusters = clusterStore.GetSize();
+  Bool_t *clusterCh1Used = new Bool_t[nClusters];
+  for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE;
+  Int_t iCluster1;
   
   // Get track parameters
-  AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
+  AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First());
   
   // Add MCS effect
   AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
   
   // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria)
-  if (ch1 < ch2 && extrapTrackParamAtCh.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) {
+  if (ch1 < ch2 && extrapTrackParamAtCh.GetClusterPtr()->GetChamberId() > ch2 + 1) {
     // extrapolation to the missing chamber
     AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1));
     // add MCS effect
@@ -363,113 +363,119 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-    cout<<endl<<"Track parameter covariances at first hit extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+    cout<<endl<<"Track parameter covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
     extrapTrackParamAtCh.GetCovariances().Print();
   }
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-    cout << "FollowTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl;
+    cout << "FollowTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl;
   }
   
-  // look for candidates in chamber 2 
-  for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) {
-    
-    hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2);
+  // Create iterators to loop over clusters in both chambers
+  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
+  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
+  
+  // look for candidates in chamber 2
+  while ( ( clusterCh2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
     
-    // try to add the current hit fast
-    if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh2)) continue;
+    // try to add the current cluster fast
+    if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh2)) continue;
     
-    // try to add the current hit accuratly
-    chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh2, extrapTrackParamAtHit2);
+    // try to add the current cluster accuratly
+    chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh2, extrapTrackParamAtCluster2);
     
-    // if good chi2 then try to attach a hitForRec in the other chamber too
-    if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
-      Bool_t foundSecondHit = kFALSE;
+    // if good chi2 then try to attach a cluster in the other chamber too
+    if (chi2WithOneCluster < maxChi2WithOneCluster) {
+      Bool_t foundSecondCluster = kFALSE;
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch2+1
-            << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl;
-        cout << "                      look for second hits in chamber(1..): " << ch1+1 << " ..." << endl;
+        cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1
+            << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+        cout << "                      look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
       }
       
       // add MCS effect for next step
-      AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtHit2,AliMUONConstants::ChamberThicknessInX0(),1.);
+      AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(),1.);
       
       // copy new track parameters for next step
-      extrapTrackParam = extrapTrackParamAtHit2;
+      extrapTrackParam = extrapTrackParamAtCluster2;
       
       //Extrapolate track parameters to chamber "ch1"
       AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1));
       
-      for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
-        
-       hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+      // reset cluster iterator of chamber 1
+      nextInCh1.Reset();
+      iCluster1 = -1;
+      
+      // look for second candidates in chamber 1
+      while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+        iCluster1++;
        
-       // try to add the current hit fast
-       if (!TryOneHitForRecFast(extrapTrackParam, hitForRecCh1)) continue;
+       // try to add the current cluster fast
+       if (!TryOneClusterFast(extrapTrackParam, clusterCh1)) continue;
        
-       // try to add the current hit accuratly
-       chi2WithTwoHitForRec = TryTwoHitForRec(extrapTrackParamAtHit2, hitForRecCh1, extrapTrackParamAtHit1);
+       // try to add the current cluster accuratly
+       chi2WithTwoClusters = TryTwoClusters(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1);
         
-       // if good chi2 then create a new track by adding the 2 hitForRec to the "trackCandidate"
-       if (chi2WithTwoHitForRec < maxChi2WithTwoHitForRec) {
-         foundSecondHit = kTRUE;
-          foundTwoHits = kTRUE;
+       // if good chi2 then create a new track by adding the 2 clusters to the "trackCandidate"
+       if (chi2WithTwoClusters < maxChi2WithTwoClusters) {
+         foundSecondCluster = kTRUE;
+          foundTwoClusters = kTRUE;
           
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowTrackInStation: found second hit in chamber(1..): " << ch1+1
-                << " (Global Chi2 = " << chi2WithTwoHitForRec << ")" << endl;
+           cout << "FollowTrackInStation: found second cluster in chamber(1..): " << ch1+1
+                << " (Global Chi2 = " << chi2WithTwoClusters << ")" << endl;
          }
          
          if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
             newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-           UpdateTrack(*newTrack,extrapTrackParamAtHit1,extrapTrackParamAtHit2);
+           UpdateTrack(*newTrack,extrapTrackParamAtCluster1,extrapTrackParamAtCluster2);
            fNRecTracks++;
            
-           // Tag hitForRecCh1 as used
-           hitForRecCh1Used[hit1] = kTRUE;
+           // Tag clusterCh1 as used
+           clusterCh1Used[iCluster1] = kTRUE;
            
            // Printout for debuging
            if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-             cout << "FollowTrackInStation: added two hits in station(1..): " << nextStation+1 << endl;
+             cout << "FollowTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl;
              if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
            }
            
-          } else if (chi2WithTwoHitForRec < bestChi2WithTwoHitForRec) {
-           // keep track of the best couple of hits
-           bestChi2WithTwoHitForRec = chi2WithTwoHitForRec;
-           bestTrackParamAtHit1 = extrapTrackParamAtHit1;
-           bestTrackParamAtHit2 = extrapTrackParamAtHit2;
+          } else if (chi2WithTwoClusters < bestChi2WithTwoClusters) {
+           // keep track of the best couple of clusters
+           bestChi2WithTwoClusters = chi2WithTwoClusters;
+           bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
+           bestTrackParamAtCluster2 = extrapTrackParamAtCluster2;
           }
          
        }
        
       }
       
-      // if no hitForRecCh1 found then consider to add hitForRecCh2 only
-      if (!foundSecondHit) {
-        foundOneHit = kTRUE;
+      // if no clusterCh1 found then consider to add clusterCh2 only
+      if (!foundSecondCluster) {
+        foundOneCluster = kTRUE;
         
        if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
           newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-         UpdateTrack(*newTrack,extrapTrackParamAtHit2);
+         UpdateTrack(*newTrack,extrapTrackParamAtCluster2);
          fNRecTracks++;
          
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl;
+           cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl;
            if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
          }
          
-       } else if (!foundTwoHits && chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
-         // keep track of the best single hitForRec except if a couple of hits has already been found
-         bestChi2WithOneHitForRec = chi2WithOneHitForRec;
-         bestTrackParamAtHit1 = extrapTrackParamAtHit2;
+       } else if (!foundTwoClusters && chi2WithOneCluster < bestChi2WithOneCluster) {
+         // keep track of the best single cluster except if a couple of clusters has already been found
+         bestChi2WithOneCluster = chi2WithOneCluster;
+         bestTrackParamAtCluster1 = extrapTrackParamAtCluster2;
         }
        
       }
@@ -479,12 +485,12 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
   }
   
   // look for candidates in chamber 1 not already attached to a track
-  // if we want to keep all possible tracks or if no good couple of hitForRec has been found
-  if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoHits) {
+  // if we want to keep all possible tracks or if no good couple of clusters has been found
+  if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
     
     // Printout for debuging
     if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-      cout << "FollowTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl;
+      cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
     }
     
     // add MCS effect for next step
@@ -493,45 +499,49 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
     //Extrapolate trackCandidate to chamber "ch1"
     AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1));
     
-    for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
-      
-      hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+    // reset cluster iterator of chamber 1
+    nextInCh1.Reset();
+    iCluster1 = -1;
+    
+    // look for second candidates in chamber 1
+    while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+      iCluster1++;
       
-      if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used
+      if (clusterCh1Used[iCluster1]) continue; // Skip cluster already used
       
-      // try to add the current hit fast
-      if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh1)) continue;
+      // try to add the current cluster fast
+      if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh1)) continue;
       
-      // try to add the current hit accuratly
-      chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh1, extrapTrackParamAtHit1);
+      // try to add the current cluster accuratly
+      chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1);
     
-      // if good chi2 then consider to add hitForRecCh1
-      // We do not try to attach a hitForRec in the other chamber too since it has already been done above
-      if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
-        foundOneHit = kTRUE;
+      // if good chi2 then consider to add clusterCh1
+      // We do not try to attach a cluster in the other chamber too since it has already been done above
+      if (chi2WithOneCluster < maxChi2WithOneCluster) {
+        foundOneCluster = kTRUE;
          
        // Printout for debuging
        if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-         cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
-              << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl;
+         cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
+              << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
        }
        
        if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
          newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-         UpdateTrack(*newTrack,extrapTrackParamAtHit1);
+         UpdateTrack(*newTrack,extrapTrackParamAtCluster1);
          fNRecTracks++;
          
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl;
+           cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl;
            if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
          }
          
-       } else if (chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
-         // keep track of the best single hitForRec except if a couple of hits has already been found
-         bestChi2WithOneHitForRec = chi2WithOneHitForRec;
-         bestTrackParamAtHit1 = extrapTrackParamAtHit1;
+       } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
+         // keep track of the best single cluster except if a couple of clusters has already been found
+         bestChi2WithOneCluster = chi2WithOneCluster;
+         bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
        }
        
       }
@@ -542,96 +552,97 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
   
   // fill out the best track if required else clean up the fRecTracksPtr array
   if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-    if (foundTwoHits) {
-      UpdateTrack(trackCandidate,bestTrackParamAtHit1,bestTrackParamAtHit2);
+    if (foundTwoClusters) {
+      UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestTrackParamAtCluster2);
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl;
+        cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
         if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
       }
       
-    } else if (foundOneHit) {
-      UpdateTrack(trackCandidate,bestTrackParamAtHit1);
+    } else if (foundOneCluster) {
+      UpdateTrack(trackCandidate,bestTrackParamAtCluster1);
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl;
+        cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
         if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
       }
       
     } else {
-      delete [] hitForRecCh1Used;
+      delete [] clusterCh1Used;
       return kFALSE;
     }
     
-  } else if (foundOneHit || foundTwoHits) {
+  } else if (foundOneCluster || foundTwoClusters) {
     
     // remove obsolete track
     fRecTracksPtr->Remove(&trackCandidate);
     fNRecTracks--;
     
   } else {
-    delete [] hitForRecCh1Used;
+    delete [] clusterCh1Used;
     return kFALSE;
   }
   
-  delete [] hitForRecCh1Used;
+  delete [] clusterCh1Used;
   return kTRUE;
   
 }
 
   //__________________________________________________________________________
-Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2,
-                                                   AliMUONTrackParam &trackParamAtHit2)
+Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2,
+                                                  AliMUONTrackParam &trackParamAtCluster2)
 {
-/// Test the compatibility between the track and the 2 hitForRec together (using trackParam's covariance matrix):
-/// return the corresponding Chi2 accounting for covariances between the 2 hitForRec
-/// return trackParamAtHit1 & 2
+/// Test the compatibility between the track and the 2 clusters together (using trackParam's covariance matrix):
+/// return the corresponding Chi2 accounting for covariances between the 2 clusters
+/// return trackParamAtCluster1 & 2
   
-  // extrapolate track parameters at the z position of the second hit
-  trackParamAtHit2.SetParameters(trackParamAtHit1.GetParameters());
-  trackParamAtHit2.SetZ(trackParamAtHit1.GetZ());
-  AliMUONTrackExtrap::ExtrapToZ(&trackParamAtHit2, hitForRec2->GetZ());
+  // extrapolate track parameters at the z position of the second cluster (no need to extrapolate the covariances)
+  trackParamAtCluster2.SetParameters(trackParamAtCluster1.GetParameters());
+  trackParamAtCluster2.SetZ(trackParamAtCluster1.GetZ());
+  AliMUONTrackExtrap::ExtrapToZ(&trackParamAtCluster2, cluster2->GetZ());
   
-  // set pointer to hit2 into trackParamAtHit2
-  trackParamAtHit2.SetHitForRecPtr(hitForRec2);
+  // set pointer to cluster2 into trackParamAtCluster2
+  trackParamAtCluster2.SetClusterPtr(cluster2);
   
-  // Set differences between track and the 2 hitForRec in the bending and non bending directions
-  AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr();
+  // Set differences between track and the 2 clusters in the bending and non bending directions
+  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
   TMatrixD dPos(4,1);
-  dPos(0,0) = hitForRec1->GetNonBendingCoor() - trackParamAtHit1.GetNonBendingCoor();
-  dPos(1,0) = hitForRec1->GetBendingCoor() - trackParamAtHit1.GetBendingCoor();
-  dPos(2,0) = hitForRec2->GetNonBendingCoor() - trackParamAtHit2.GetNonBendingCoor();
-  dPos(3,0) = hitForRec2->GetBendingCoor() - trackParamAtHit2.GetBendingCoor();
+  dPos(0,0) = cluster1->GetX() - trackParamAtCluster1.GetNonBendingCoor();
+  dPos(1,0) = cluster1->GetY() - trackParamAtCluster1.GetBendingCoor();
+  dPos(2,0) = cluster2->GetX() - trackParamAtCluster2.GetNonBendingCoor();
+  dPos(3,0) = cluster2->GetY() - trackParamAtCluster2.GetBendingCoor();
   
-  // Calculate the error matrix from the track parameter covariances at first hitForRec
+  // Calculate the error matrix from the track parameter covariances at first cluster
   TMatrixD error(4,4);
   error.Zero();
-  if (trackParamAtHit1.CovariancesExist()) {
-    // Save track parameters at first hitForRec
-    AliMUONTrackParam trackParamAtHit1Save(trackParamAtHit1);
-    TMatrixD paramAtHit1Save(trackParamAtHit1Save.GetParameters());
-    Double_t z1 = trackParamAtHit1Save.GetZ();
+  if (trackParamAtCluster1.CovariancesExist()) {
+    // Save track parameters at first cluster
+    TMatrixD paramAtCluster1Save(trackParamAtCluster1.GetParameters());
+    
+    // Save track coordinates at second cluster
+    Double_t nonBendingCoor2 = trackParamAtCluster2.GetNonBendingCoor();
+    Double_t bendingCoor2    = trackParamAtCluster2.GetBendingCoor();
     
-    // Save track coordinates at second hitForRec
-    Double_t nonBendingCoor2        = trackParamAtHit2.GetNonBendingCoor();
-    Double_t bendingCoor2           = trackParamAtHit2.GetBendingCoor();
+    // copy track parameters at first cluster for jacobian calculation
+    AliMUONTrackParam trackParam(trackParamAtCluster1);
     
-    // add MCS effect at first hitForRec
-    AliMUONTrackExtrap::AddMCSEffect(&trackParamAtHit1Save,AliMUONConstants::ChamberThicknessInX0(),1.);
+    // add MCS effect to the covariance matrix at first cluster
+    AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
     
-    // Get the pointer to the parameter covariance matrix at first hitForRec
-    const TMatrixD& kParamCov = trackParamAtHit1Save.GetCovariances();
+    // Get the pointer to the parameter covariance matrix at first cluster
+    const TMatrixD& kParamCov = trackParam.GetCovariances();
     
     // Calculate the jacobian related to the transformation between track parameters
-    // at first hitForRec and track coordinates at the 2 hitForRec z-position
+    // at first cluster and track coordinates at the 2 cluster z-positions
     TMatrixD jacob(4,5);
     jacob.Zero();
-    // first derivative at the first hitForRec:
+    // first derivative at the first cluster:
     jacob(0,0) = 1.; // dx1/dx
     jacob(1,2) = 1.; // dy1/dy
-    // first derivative at the second hitForRec:
+    // first derivative at the second cluster:
     TMatrixD dParam(5,1);
     for (Int_t i=0; i<5; i++) {
       // Skip jacobian calculation for parameters with no associated error
@@ -640,21 +651,21 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra
       for (Int_t j=0; j<5; j++) {
         if (j==i) {
           dParam(j,0) = TMath::Sqrt(kParamCov(i,i));
-         if (j == 4) dParam(j,0) *= TMath::Sign(1.,-paramAtHit1Save(4,0)); // variation always in the same direction
+         if (j == 4) dParam(j,0) *= TMath::Sign(1.,-paramAtCluster1Save(4,0)); // variation always in the same direction
         } else dParam(j,0) = 0.;
       }
       
-      // Set new track parameters at first hitForRec
-      trackParamAtHit1Save.SetParameters(paramAtHit1Save);
-      trackParamAtHit1Save.AddParameters(dParam);
-      trackParamAtHit1Save.SetZ(z1);
+      // Set new track parameters at first cluster
+      trackParam.SetParameters(paramAtCluster1Save);
+      trackParam.AddParameters(dParam);
+      trackParam.SetZ(cluster1->GetZ());
       
-      // Extrapolate new track parameters to the z position of the second hitForRec
-      AliMUONTrackExtrap::ExtrapToZ(&trackParamAtHit1Save,hitForRec2->GetZ());
+      // Extrapolate new track parameters to the z position of the second cluster
+      AliMUONTrackExtrap::ExtrapToZ(&trackParam,cluster2->GetZ());
       
       // Calculate the jacobian
-      jacob(2,i) = (trackParamAtHit1Save.GetNonBendingCoor()  - nonBendingCoor2) / dParam(i,0); // dx2/dParami
-      jacob(3,i) = (trackParamAtHit1Save.GetBendingCoor()     - bendingCoor2   ) / dParam(i,0); // dy2/dParami
+      jacob(2,i) = (trackParam.GetNonBendingCoor() - nonBendingCoor2) / dParam(i,0); // dx2/dParami
+      jacob(3,i) = (trackParam.GetBendingCoor()    - bendingCoor2   ) / dParam(i,0); // dy2/dParami
     }
     
     // Calculate the error matrix
@@ -662,11 +673,11 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra
     error = TMatrixD(tmp,TMatrixD::kMultTranspose,jacob);
   }
   
-  // Add hitForRec resolution to the error matrix
-  error(0,0) += hitForRec1->GetNonBendingReso2();
-  error(1,1) += hitForRec1->GetBendingReso2();
-  error(2,2) += hitForRec2->GetNonBendingReso2();
-  error(3,3) += hitForRec2->GetBendingReso2();
+  // Add cluster resolution to the error matrix
+  error(0,0) += cluster1->GetErrX2();
+  error(1,1) += cluster1->GetErrY2();
+  error(2,2) += cluster2->GetErrX2();
+  error(3,3) += cluster2->GetErrY2();
   
   // invert the error matrix for Chi2 calculation
   if (error.Determinant() != 0) {
@@ -685,120 +696,118 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit)
+void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster)
 {
-  /// Add 1 hit to the track candidate
+  /// Add 1 cluster to the track candidate
   /// Update chi2 of the track 
   
   // Compute local chi2
-  AliMUONHitForRec* hit = trackParamAtHit.GetHitForRecPtr();
-  Double_t deltaX = trackParamAtHit.GetNonBendingCoor() - hit->GetNonBendingCoor();
-  Double_t deltaY = trackParamAtHit.GetBendingCoor() - hit->GetBendingCoor();
-  Double_t localChi2 = deltaX*deltaX / hit->GetNonBendingReso2() +
-                      deltaY*deltaY / hit->GetBendingReso2();
+  AliMUONVCluster* cluster = trackParamAtCluster.GetClusterPtr();
+  Double_t deltaX = trackParamAtCluster.GetNonBendingCoor() - cluster->GetX();
+  Double_t deltaY = trackParamAtCluster.GetBendingCoor() - cluster->GetY();
+  Double_t localChi2 = deltaX*deltaX / cluster->GetErrX2() +
+                      deltaY*deltaY / cluster->GetErrY2();
   
-  // Flag hit as being not removable
-  trackParamAtHit.SetRemovable(kFALSE);
-  trackParamAtHit.SetLocalChi2(0.); // --> Local chi2 not used
+  // Flag cluster as being not removable
+  trackParamAtCluster.SetRemovable(kFALSE);
+  trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used
   
   // Update the chi2 of the new track
-  track.SetFitFMin(track.GetFitFMin() + localChi2);
+  track.SetGlobalChi2(track.GetGlobalChi2() + localChi2);
   
-  // Update TrackParamAtHit
-  track.AddTrackParamAtHit(&trackParamAtHit,trackParamAtHit.GetHitForRecPtr());
-  track.GetTrackParamAtHit()->Sort();
+  // Update TrackParamAtCluster
+  track.AddTrackParamAtCluster(trackParamAtCluster,*cluster);
+  track.GetTrackParamAtCluster()->Sort();
   
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2)
+void AliMUONTrackReconstructor::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2)
 {
-  /// Add 2 hits to the track candidate
+  /// Add 2 clusters to the track candidate
   /// Update track and local chi2
   
-  // Update local chi2 at first hit
-  AliMUONHitForRec* hit1 = trackParamAtHit1.GetHitForRecPtr();
-  Double_t deltaX = trackParamAtHit1.GetNonBendingCoor() - hit1->GetNonBendingCoor();
-  Double_t deltaY = trackParamAtHit1.GetBendingCoor() - hit1->GetBendingCoor();
-  Double_t localChi2AtHit1 = deltaX*deltaX / hit1->GetNonBendingReso2() +
-                            deltaY*deltaY / hit1->GetBendingReso2();
-  trackParamAtHit1.SetLocalChi2(localChi2AtHit1);
+  // Update local chi2 at first cluster
+  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
+  Double_t deltaX = trackParamAtCluster1.GetNonBendingCoor() - cluster1->GetX();
+  Double_t deltaY = trackParamAtCluster1.GetBendingCoor() - cluster1->GetY();
+  Double_t localChi2AtCluster1 = deltaX*deltaX / cluster1->GetErrX2() +
+                                deltaY*deltaY / cluster1->GetErrY2();
+  trackParamAtCluster1.SetLocalChi2(localChi2AtCluster1);
   
-  // Flag first hit as being removable
-  trackParamAtHit1.SetRemovable(kTRUE);
+  // Flag first cluster as being removable
+  trackParamAtCluster1.SetRemovable(kTRUE);
   
-  // Update local chi2 at second hit
-  AliMUONHitForRec* hit2 = trackParamAtHit2.GetHitForRecPtr();
-  deltaX = trackParamAtHit2.GetNonBendingCoor() - hit2->GetNonBendingCoor();
-  deltaY = trackParamAtHit2.GetBendingCoor() - hit2->GetBendingCoor();
-  Double_t localChi2AtHit2 = deltaX*deltaX / hit2->GetNonBendingReso2() +
-                            deltaY*deltaY / hit2->GetBendingReso2();
-  trackParamAtHit2.SetLocalChi2(localChi2AtHit2);
+  // Update local chi2 at second cluster
+  AliMUONVCluster* cluster2 = trackParamAtCluster2.GetClusterPtr();
+  deltaX = trackParamAtCluster2.GetNonBendingCoor() - cluster2->GetX();
+  deltaY = trackParamAtCluster2.GetBendingCoor() - cluster2->GetY();
+  Double_t localChi2AtCluster2 = deltaX*deltaX / cluster2->GetErrX2() +
+                                deltaY*deltaY / cluster2->GetErrY2();
+  trackParamAtCluster2.SetLocalChi2(localChi2AtCluster2);
   
-  // Flag first hit as being removable
-  trackParamAtHit2.SetRemovable(kTRUE);
+  // Flag first cluster as being removable
+  trackParamAtCluster2.SetRemovable(kTRUE);
   
   // Update the chi2 of the new track
-  track.SetFitFMin(track.GetFitFMin() + localChi2AtHit1 + localChi2AtHit2);
+  track.SetGlobalChi2(track.GetGlobalChi2() + localChi2AtCluster1 + localChi2AtCluster2);
   
-  // Update TrackParamAtHit
-  track.AddTrackParamAtHit(&trackParamAtHit1,trackParamAtHit1.GetHitForRecPtr());
-  track.AddTrackParamAtHit(&trackParamAtHit2,trackParamAtHit2.GetHitForRecPtr());
-  track.GetTrackParamAtHit()->Sort();
+  // Update TrackParamAtCluster
+  track.AddTrackParamAtCluster(trackParamAtCluster1,*cluster1);
+  track.AddTrackParamAtCluster(trackParamAtCluster2,*cluster2);
+  track.GetTrackParamAtCluster()->Sort();
   
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, Int_t nextStation)
+Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation)
 {
   /// Try to recover the track candidate in the next station
-  /// by removing the worst of the two hits attached in the current station
+  /// by removing the worst of the two clusters attached in the current station
   /// Return kTRUE if recovering succeeds
   AliDebug(1,"Enter RecoverTrack");
   
-  // Do not try to recover track until we have attached hit(s) on station(1..) 3
+  // Do not try to recover track until we have attached cluster(s) on station(1..) 3
   if (nextStation > 1) return kFALSE;
   
-  Int_t worstHitNumber = -1;
+  Int_t worstClusterNumber = -1;
   Double_t localChi2, worstLocalChi2 = 0.;
   
-  // Look for the hit to remove
-  for (Int_t hitNumber = 0; hitNumber < 2; hitNumber++) {
-    AliMUONTrackParam *trackParamAtHit = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(hitNumber);
+  // Look for the cluster to remove
+  for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) {
+    AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber);
     
-    // check if current hit is removable
-    if (!trackParamAtHit->IsRemovable()) return kFALSE;
+    // check if current cluster is removable
+    if (!trackParamAtCluster->IsRemovable()) return kFALSE;
     
-    // Pick up hit with the worst chi2
-    localChi2 = trackParamAtHit->GetLocalChi2();
+    // Pick up cluster with the worst chi2
+    localChi2 = trackParamAtCluster->GetLocalChi2();
     if (localChi2 > worstLocalChi2) {
       worstLocalChi2 = localChi2;
-      worstHitNumber = hitNumber;
+      worstClusterNumber = clusterNumber;
     }
   }
   
-  // Reset best hit as being NOT removable
-  ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt((worstHitNumber+1)%2))->SetRemovable(kFALSE);
+  // Reset best cluster as being NOT removable
+  ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt((worstClusterNumber+1)%2))->SetRemovable(kFALSE);
   
-  // Remove the worst hit
-  trackCandidate.RemoveTrackParamAtHit((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(worstHitNumber));
+  // Remove the worst cluster
+  trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber));
   
   // Re-fit the track:
   // Do not take into account the multiple scattering to speed up the fit
   // Calculate the track parameter covariance matrix
-  trackCandidate.SetFitWithVertex(kFALSE); // To be sure
-  Fit(trackCandidate, kFALSE, kTRUE);
+  Fit(trackCandidate, kFALSE, kFALSE, kTRUE);
   
-  // Look for new hit(s) in next station
-  return FollowTrackInStation(trackCandidate,nextStation);
+  // Look for new cluster(s) in next station
+  return FollowTrackInStation(trackCandidate,clusterStore,nextStation);
   
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::SetVertexForFit(AliMUONTrack &trackCandidate)
+void AliMUONTrackReconstructor::SetVertexErrXY2ForFit(AliMUONTrack &trackCandidate)
 {
-  /// Add the vertex as a measured hit to constrain the fit of the "trackCandidate"
-  /// Compute the vertex resolution from natural vertex dispersion and
+  /// Compute the vertex resolution square from natural vertex dispersion and
   /// multiple scattering effets according to trackCandidate path in absorber
   /// It is necessary to account for multiple scattering effects here instead of during the fit of
   /// the "trackCandidate" to do not influence the result by changing track resolution at vertex
@@ -808,28 +817,30 @@ void AliMUONTrackReconstructor::SetVertexForFit(AliMUONTrack &trackCandidate)
                              AliMUONReconstructor::GetRecoParam()->GetNonBendingVertexDispersion();
   Double_t bendingReso2 = AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() *
                          AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion();
+  
   // add multiple scattering effets
-  AliMUONTrackParam paramAtVertex(*((AliMUONTrackParam*)(trackCandidate.GetTrackParamAtHit()->First())));
+  AliMUONTrackParam paramAtVertex(*((AliMUONTrackParam*)(trackCandidate.GetTrackParamAtCluster()->First())));
   paramAtVertex.DeleteCovariances(); // to be sure to account only for multiple scattering
   AliMUONTrackExtrap::ExtrapToVertexUncorrected(&paramAtVertex,0.);
   const TMatrixD& kParamCov = paramAtVertex.GetCovariances();
   nonBendingReso2 += kParamCov(0,0);
   bendingReso2 += kParamCov(2,2);
-  // Set the vertex
-  AliMUONHitForRec vertex; // Coordinates set to (0.,0.,0.) by default
-  vertex.SetNonBendingReso2(nonBendingReso2);
-  vertex.SetBendingReso2(bendingReso2);
-  trackCandidate.SetVertex(&vertex);
+  
+  // Set the vertex resolution square
+  trackCandidate.SetVertexErrXY2(nonBendingReso2,bendingReso2);
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t calcCov)
+void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t fitWithVertex, Bool_t calcCov)
 {
-  /// Fit the track "track" w/wo multiple Coulomb scattering according to "includeMCS".
+  /// Fit the track
+  /// w/wo multiple Coulomb scattering according to "includeMCS".
+  /// w/wo constraining the vertex according to "fitWithVertex".
+  /// calculating or not the covariance matrix according to "calcCov".
   
   Double_t benC, errorParam, invBenP, nonBenC, x, y;
   AliMUONTrackParam *trackParam;
-  Double_t arg[1], fedm, errdef, fitFMin;
+  Double_t arg[1], fedm, errdef, globalChi2;
   Int_t npari, nparx;
   Int_t status, covStatus;
   
@@ -856,20 +867,23 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool
   //gMinuit->mnexcm("SET STR", arg, 1, status);
   
   // set flag w/wo multiple scattering according to "includeMCS"
-  track.SetFitWithMCS(includeMCS);
+  track.FitWithMCS(includeMCS);
   if (includeMCS) {
-    // compute hit weights only once
-    if (!track.ComputeHitWeights()) {
+    // compute cluster weights only once
+    if (!track.ComputeClusterWeights()) {
       AliWarning("cannot take into account the multiple scattering effects");
-      track.SetFitWithMCS(kFALSE);
+      track.FitWithMCS(kFALSE);
     }
   }
   
+  track.FitWithVertex(fitWithVertex);
+  if (fitWithVertex) SetVertexErrXY2ForFit(track);
+  
   // Set fitting function
   gMinuit->SetFCN(TrackChi2);
   
   // Set fitted parameters (!! The order is very important for the covariance matrix !!)
-  trackParam = (AliMUONTrackParam*) (track.GetTrackParamAtHit()->First());
+  trackParam = (AliMUONTrackParam*) (track.GetTrackParamAtCluster()->First());
   // could be tried with no limits for the search (min=max=0) ????
   // mandatory limits in non Bending to avoid NaN values of parameters
   gMinuit->mnparm(0, "X", trackParam->GetNonBendingCoor(), 0.03, -500.0, 500.0, status);
@@ -898,8 +912,8 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool
   trackParam->SetInverseBendingMomentum(invBenP);
   
   // global result of the fit
-  gMinuit->mnstat(fitFMin, fedm, errdef, npari, nparx, covStatus);
-  track.SetFitFMin(fitFMin);
+  gMinuit->mnstat(globalChi2, fedm, errdef, npari, nparx, covStatus);
+  track.SetGlobalChi2(globalChi2);
   
   // Get the covariance matrix if required
   if (calcCov) {
@@ -917,45 +931,45 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool
 void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Double_t *param, Int_t /*flag*/)
 {
   /// Return the "Chi2" to be minimized with Minuit for track fitting.
-  /// Assumes that the track hits are sorted according to increasing Z.
-  /// Track parameters at each TrackHit are updated accordingly.
+  /// Assumes that the trackParamAtCluster are sorted according to increasing Z.
+  /// Track parameters at each cluster are updated accordingly.
   /// Vertex is used according to the flag "trackBeingFitted->GetFitWithVertex()".
   /// Multiple Coulomb scattering is taken into account according to the flag "trackBeingFitted->GetFitWithMCS()".
   
   AliMUONTrack *trackBeingFitted = (AliMUONTrack*) gMinuit->GetObjectFit();
-  AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) trackBeingFitted->GetTrackParamAtHit()->First();
+  AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) trackBeingFitted->GetTrackParamAtCluster()->First();
   Double_t dX, dY;
   chi2 = 0.; // initialize chi2
   
   // update track parameters
-  trackParamAtHit->SetNonBendingCoor(param[0]);
-  trackParamAtHit->SetNonBendingSlope(param[1]);
-  trackParamAtHit->SetBendingCoor(param[2]);
-  trackParamAtHit->SetBendingSlope(param[3]);
-  trackParamAtHit->SetInverseBendingMomentum(param[4]);
-  trackBeingFitted->UpdateTrackParamAtHit();
+  trackParamAtCluster->SetNonBendingCoor(param[0]);
+  trackParamAtCluster->SetNonBendingSlope(param[1]);
+  trackParamAtCluster->SetBendingCoor(param[2]);
+  trackParamAtCluster->SetBendingSlope(param[3]);
+  trackParamAtCluster->SetInverseBendingMomentum(param[4]);
+  trackBeingFitted->UpdateTrackParamAtCluster();
   
   // Take the vertex into account in the fit if required
-  if (trackBeingFitted->GetFitWithVertex()) {
-    AliMUONTrackParam paramAtVertex(*trackParamAtHit);
-    AliMUONTrackExtrap::ExtrapToZ(&paramAtVertex, 0.);
-    AliMUONHitForRec *vertex = trackBeingFitted->GetVertex();
-    if (!vertex) {
-      cout<<"Error in TrackChi2: Want to use the vertex in tracking but it has not been created!!"<<endl;
-      exit(-1);
+  if (trackBeingFitted->FitWithVertex()) {
+    Double_t nonBendingReso2,bendingReso2;
+    trackBeingFitted->GetVertexErrXY2(nonBendingReso2,bendingReso2);
+    if (nonBendingReso2 == 0. || bendingReso2 == 0.) chi2 += 1.e10;
+    else {
+      AliMUONTrackParam paramAtVertex(*trackParamAtCluster);
+      AliMUONTrackExtrap::ExtrapToZ(&paramAtVertex, 0.); // vextex position = (0,0,0)
+      dX = paramAtVertex.GetNonBendingCoor();
+      dY = paramAtVertex.GetBendingCoor();
+      chi2 += dX * dX / nonBendingReso2 + dY * dY / bendingReso2;
     }
-    dX = vertex->GetNonBendingCoor() - paramAtVertex.GetNonBendingCoor();
-    dY = vertex->GetBendingCoor() - paramAtVertex.GetBendingCoor();
-    chi2 += dX * dX / vertex->GetNonBendingReso2() + dY * dY / vertex->GetBendingReso2();
   }
   
   // compute chi2 w/wo multiple scattering
-  chi2 += trackBeingFitted->ComputeGlobalChi2(trackBeingFitted->GetFitWithMCS());
+  chi2 += trackBeingFitted->ComputeGlobalChi2(trackBeingFitted->FitWithMCS());
   
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::ComplementTracks()
+void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clusterStore)
 {
   /// Complete tracks by adding missing clusters (if there is an overlap between
   /// two detection elements, the track may have two clusters in the same chamber)
@@ -963,15 +977,12 @@ void AliMUONTrackReconstructor::ComplementTracks()
   AliDebug(1,"Enter ComplementTracks");
   
   Int_t chamberId, detElemId;
-  Double_t chi2OfHitForRec, bestChi2OfHitForRec;
-  Bool_t foundOneHit, trackModified;
-  AliMUONHitForRec* hitForRec;
-  AliMUONTrackParam* trackParam, *nextTrackParam;
-  AliMUONTrackParam copyOfTrackParam;
-  AliMUONTrackParam trackParamAtHit;
-  AliMUONTrackParam bestTrackParamAtHit;
+  Double_t chi2OfCluster, bestChi2OfCluster;
   Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
                        AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking();
+  Bool_t foundOneCluster, trackModified;
+  AliMUONVCluster* cluster;
+  AliMUONTrackParam *trackParam, *nextTrackParam, copyOfTrackParam, trackParamAtCluster, bestTrackParamAtCluster;
   
   // Remove double track to complete only "good" tracks
   RemoveDoubleTracks();
@@ -980,49 +991,49 @@ void AliMUONTrackReconstructor::ComplementTracks()
   while (track) {
     trackModified = kFALSE;
     
-    trackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First();
+    trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
     while (trackParam) {
-      foundOneHit = kFALSE;
-      bestChi2OfHitForRec = 2. * sigmaCut2; // 2 because 2 quantities in chi2
+      foundOneCluster = kFALSE;
+      bestChi2OfCluster = 2. * sigmaCut2; // 2 because 2 quantities in chi2
+      chamberId = trackParam->GetClusterPtr()->GetChamberId();
+      detElemId = trackParam->GetClusterPtr()->GetDetElemId();
       
       // prepare nextTrackParam before adding new cluster because of the sorting
-      nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParam);
-      
-      chamberId = trackParam->GetHitForRecPtr()->GetChamberNumber();
-      detElemId = trackParam->GetHitForRecPtr()->GetDetElemId();
+      nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParam);
       
       // recover track parameters from local fit and put them into a copy of trackParam
       copyOfTrackParam.SetZ(trackParam->GetZ());
       copyOfTrackParam.SetParameters(trackParam->GetSmoothParameters());
       copyOfTrackParam.SetCovariances(trackParam->GetSmoothCovariances());
       
+      // Create iterators to loop over clusters in current chamber
+      TIter nextInCh(clusterStore.CreateChamberIterator(chamberId,chamberId));
+      
       // look for one second candidate in the same chamber
-      for (Int_t hit = 0; hit < fNHitsForRecPerChamber[chamberId]; hit++) {
-       
-       hitForRec = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[chamberId]+hit);
+      while ( ( cluster = static_cast<AliMUONVCluster*>(nextInCh()) ) ) {
         
        // look for a cluster in another detection element
-       if (hitForRec->GetDetElemId() == detElemId) continue;
+       if (cluster->GetDetElemId() == detElemId) continue;
        
-       // try to add the current hit fast
-       if (!TryOneHitForRecFast(copyOfTrackParam, hitForRec)) continue;
+       // try to add the current cluster fast
+       if (!TryOneClusterFast(copyOfTrackParam, cluster)) continue;
        
-       // try to add the current hit accurately
-       chi2OfHitForRec = TryOneHitForRec(copyOfTrackParam, hitForRec, trackParamAtHit);
+       // try to add the current cluster accurately
+       chi2OfCluster = TryOneCluster(copyOfTrackParam, cluster, trackParamAtCluster);
        
        // if better chi2 then prepare to add this cluster to the track
-       if (chi2OfHitForRec < bestChi2OfHitForRec) {
-         bestChi2OfHitForRec = chi2OfHitForRec;
-         bestTrackParamAtHit = trackParamAtHit;
-         foundOneHit = kTRUE;
+       if (chi2OfCluster < bestChi2OfCluster) {
+         bestChi2OfCluster = chi2OfCluster;
+         bestTrackParamAtCluster = trackParamAtCluster;
+         foundOneCluster = kTRUE;
        }
        
       }
       
       // add new cluster if any
-      if (foundOneHit) {
-       UpdateTrack(*track,bestTrackParamAtHit);
-       bestTrackParamAtHit.SetAloneInChamber(kFALSE);
+      if (foundOneCluster) {
+       UpdateTrack(*track,bestTrackParamAtCluster);
+       bestTrackParamAtCluster.SetAloneInChamber(kFALSE);
        trackParam->SetAloneInChamber(kFALSE);
        trackModified = kTRUE;
       }
@@ -1031,7 +1042,7 @@ void AliMUONTrackReconstructor::ComplementTracks()
     }
     
     // re-fit track parameters if needed
-    if (trackModified) Fit(*track, kTRUE, kTRUE);
+    if (trackModified) Fit(*track, kTRUE, kFALSE, kTRUE);
     
     track = (AliMUONTrack*) fRecTracksPtr->After(track);
   }
@@ -1048,7 +1059,7 @@ void AliMUONTrackReconstructor::ImproveTracks()
   Double_t localChi2, worstLocalChi2;
   Int_t worstChamber, previousChamber;
   AliMUONTrack *track, *nextTrack;
-  AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit, *previousTrackParam, *nextTrackParam;
+  AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster, *previousTrackParam, *nextTrackParam;
   Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement() *
                       AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement();
   
@@ -1064,29 +1075,29 @@ void AliMUONTrackReconstructor::ImproveTracks()
     while (!track->IsImproved()) {
       
       // Update track parameters and covariances
-      track->UpdateCovTrackParamAtHit();
+      track->UpdateCovTrackParamAtCluster();
       
-      // Compute local chi2 of each hits
+      // Compute local chi2 of each clusters
       track->ComputeLocalChi2(kTRUE);
       
-      // Look for the hit to remove
-      worstTrackParamAtHit = NULL;
+      // Look for the cluster to remove
+      worstTrackParamAtCluster = NULL;
       worstLocalChi2 = 0.;
-      trackParamAtHit = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First();
-      while (trackParamAtHit) {
+      trackParamAtCluster = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
+      while (trackParamAtCluster) {
         
-        // Pick up hit with the worst chi2
-        localChi2 = trackParamAtHit->GetLocalChi2();
+        // Pick up cluster with the worst chi2
+        localChi2 = trackParamAtCluster->GetLocalChi2();
         if (localChi2 > worstLocalChi2) {
           worstLocalChi2 = localChi2;
-          worstTrackParamAtHit = trackParamAtHit;
+          worstTrackParamAtCluster = trackParamAtCluster;
         }
         
-      trackParamAtHit = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParamAtHit);
+      trackParamAtCluster = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParamAtCluster);
       }
       
-      // Check if bad hit found
-      if (!worstTrackParamAtHit) {
+      // Check if bad cluster found
+      if (!worstTrackParamAtCluster) {
         track->SetImproved(kTRUE);
         break;
       }
@@ -1097,62 +1108,62 @@ void AliMUONTrackReconstructor::ImproveTracks()
         break;
       }
       
-      // if the worst hit is not removable then remove the entire track
-      if (!worstTrackParamAtHit->IsRemovable() && worstTrackParamAtHit->IsAloneInChamber()) {
+      // if the worst cluster is not removable then remove the entire track
+      if (!worstTrackParamAtCluster->IsRemovable() && worstTrackParamAtCluster->IsAloneInChamber()) {
        fRecTracksPtr->Remove(track);
        fNRecTracks--;
         break;
       }
       
-      // Reset the second hit in the same station as being not removable
-      // or reset the second hit in the same chamber as being alone
-      worstChamber = worstTrackParamAtHit->GetHitForRecPtr()->GetChamberNumber();
-      previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(worstTrackParamAtHit);
-      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(worstTrackParamAtHit);
-      if (worstTrackParamAtHit->IsAloneInChamber()) { // Worst hit removable and alone in chamber
+      // Reset the second cluster in the same station as being not removable
+      // or reset the second cluster in the same chamber as being alone
+      worstChamber = worstTrackParamAtCluster->GetClusterPtr()->GetChamberId();
+      previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(worstTrackParamAtCluster);
+      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(worstTrackParamAtCluster);
+      if (worstTrackParamAtCluster->IsAloneInChamber()) { // Worst cluster removable and alone in chamber
        
        if (worstChamber%2 == 0) { // Modify flags in next chamber
          
          nextTrackParam->SetRemovable(kFALSE);
-         if (!nextTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore
-           ((AliMUONTrackParam*) track->GetTrackParamAtHit()->After(nextTrackParam))->SetRemovable(kFALSE);
+         if (!nextTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore
+           ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(nextTrackParam))->SetRemovable(kFALSE);
          
        } else { // Modify flags in previous chamber
          
          previousTrackParam->SetRemovable(kFALSE);
-         if (!previousTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore
-           ((AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(previousTrackParam))->SetRemovable(kFALSE);
+         if (!previousTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore
+           ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(previousTrackParam))->SetRemovable(kFALSE);
          
        }
        
-      } else { // Worst hit not alone in its chamber
+      } else { // Worst cluster not alone in its chamber
         
-       if (previousTrackParam) previousChamber = previousTrackParam->GetHitForRecPtr()->GetChamberNumber();
+       if (previousTrackParam) previousChamber = previousTrackParam->GetClusterPtr()->GetChamberId();
        else previousChamber = -1;
        
-       if (previousChamber == worstChamber) { // the second hit on the same chamber is the previous one
+       if (previousChamber == worstChamber) { // the second cluster on the same chamber is the previous one
          
          previousTrackParam->SetAloneInChamber(kTRUE);
-         // transfert the removability to the second hit
-         if (worstTrackParamAtHit->IsRemovable()) previousTrackParam->SetRemovable(kTRUE);
+         // transfert the removability to the second cluster
+         if (worstTrackParamAtCluster->IsRemovable()) previousTrackParam->SetRemovable(kTRUE);
          
-       } else { // the second hit on the same chamber is the next one
+       } else { // the second cluster on the same chamber is the next one
          
          nextTrackParam->SetAloneInChamber(kTRUE);
-         // transfert the removability to the second hit
-         if (worstTrackParamAtHit->IsRemovable()) nextTrackParam->SetRemovable(kTRUE);
+         // transfert the removability to the second cluster
+         if (worstTrackParamAtCluster->IsRemovable()) nextTrackParam->SetRemovable(kTRUE);
          
        }
        
       }
       
-      // Remove the worst hit
-      track->RemoveTrackParamAtHit(worstTrackParamAtHit);
+      // Remove the worst cluster
+      track->RemoveTrackParamAtCluster(worstTrackParamAtCluster);
       
       // Re-fit the track:
       // Take into account the multiple scattering
       // Calculate the track parameter covariance matrix
-      Fit(*track, kTRUE, kTRUE);
+      Fit(*track, kTRUE, kFALSE, kTRUE);
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
@@ -1172,31 +1183,19 @@ void AliMUONTrackReconstructor::ImproveTracks()
   //__________________________________________________________________________
 void AliMUONTrackReconstructor::Finalize()
 {
-  /// Fill AliMUONTrack's fHitForRecAtHit array
   /// Recompute track parameters and covariances at each attached cluster from those at the first one
   
   AliMUONTrack *track;
-  AliMUONTrackParam *trackParamAtHit;
   
   track = (AliMUONTrack*) fRecTracksPtr->First();
   while (track) {
     
     // update track parameters if not already done
-    if (!track->IsImproved()) track->UpdateCovTrackParamAtHit();
-    
-    trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->First());
-    while (trackParamAtHit) {
-      
-      // update array of track hit
-      track->AddHitForRecAtHit(trackParamAtHit->GetHitForRecPtr());
-      
-      trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->After(trackParamAtHit));
-    }
+    if (!track->IsImproved()) track->UpdateCovTrackParamAtCluster();
     
     track = (AliMUONTrack*) fRecTracksPtr->After(track);
     
   }
-    
+  
 }
 
-
index fb9f282..333211b 100644 (file)
@@ -11,7 +11,8 @@
 
 #include "AliMUONVTrackReconstructor.h"
 
-class AliMUONHitForRec;
+class AliMUONVCluster;
+class AliMUONVClusterStore;
 class AliMUONTrackParam;
 class AliMUONTrack;
 
@@ -27,9 +28,9 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor
  protected:
 
   // Functions
-  virtual void MakeTrackCandidates();
-  virtual void FollowTracks();
-  virtual void ComplementTracks();
+  virtual void MakeTrackCandidates(const AliMUONVClusterStore& clusterStore);
+  virtual void FollowTracks(const AliMUONVClusterStore& clusterStore);
+  virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
   virtual void ImproveTracks();
   virtual void Finalize();
   
@@ -41,18 +42,18 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor
   /// Not implemented copy assignment operator
   AliMUONTrackReconstructor& operator=(const AliMUONTrackReconstructor& rhs);
   
-  Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation);
+  Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation);
   
-  Double_t TryTwoHitForRec(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2, AliMUONTrackParam &trackParamAtHit2);
+  Double_t TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster, AliMUONVCluster* cluster2, AliMUONTrackParam &trackParamAtCluster2);
 
-  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit);
-  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2);
+  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster);
+  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2);
   
-  Bool_t RecoverTrack(AliMUONTrack &track, Int_t nextStation);
+  Bool_t RecoverTrack(AliMUONTrack &track, const AliMUONVClusterStore& clusterStore, Int_t nextStation);
   
-  void SetVertexForFit(AliMUONTrack &trackCandidate);
+  void SetVertexErrXY2ForFit(AliMUONTrack &trackCandidate);
   
-  void Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t calcCov);
+  void Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t fitWithVertex, Bool_t calcCov);
 
 
   ClassDef(AliMUONTrackReconstructor, 0) // MUON track reconstructor in ALICE
index 1320e84..cfed776 100644 (file)
 //-----------------------------------------------------------------------------
 
 #include "AliMUONTrackReconstructorK.h"
+
 #include "AliMUONConstants.h"
-#include "AliMUONHitForRec.h"
+#include "AliMUONVCluster.h"
+#include "AliMUONVClusterStore.h"
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
 #include "AliMUONTrackExtrap.h"
@@ -49,8 +51,7 @@ ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context
 AliMUONTrackReconstructorK::AliMUONTrackReconstructorK()
   : AliMUONVTrackReconstructor()
 {
-  /// Constructor for class AliMUONTrackReconstructorK
-  AliInfo("*** Tracking with Kalman Filter ***");
+  /// Constructor
 }
 
   //__________________________________________________________________________
@@ -60,17 +61,17 @@ AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK()
 } 
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::MakeTrackCandidates()
+void AliMUONTrackReconstructorK::MakeTrackCandidates(const AliMUONVClusterStore& clusterStore)
 {
   /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
   /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4.
-  /// Good candidates are made of at least three hitForRec's.
+  /// Good candidates are made of at least three clusters.
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
   
   TClonesArray *segments;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
-  Bool_t hitFound;
+  Bool_t clusterFound;
 
   AliDebug(1,"Enter MakeTrackCandidates");
 
@@ -78,7 +79,7 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
   for (Int_t istat=4; istat>=3; istat--) {
     
     // Make segments in the station
-    segments = MakeSegmentsInStation(istat);
+    segments = MakeSegmentsInStation(clusterStore, istat);
     
     // Loop over segments
     for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
@@ -90,21 +91,22 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-        cout<<endl<<"Track parameter covariances at first hit:"<<endl;
-        ((AliMUONTrackParam*) (track->GetTrackParamAtHit()->First()))->GetCovariances().Print();
+        cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
+        ((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->First()))->GetCovariances().Print();
       }
       
-      // Look for compatible hitForRec(s) in the other station
-      if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) hitFound = FollowLinearTrackInStation(*track,7-istat);
+      // Look for compatible cluster(s) in the other station
+      if (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast())
+       clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
       else {
         // First recompute track parameters and covariances on station(1..) 5 using Kalman filter
         // (to make sure all tracks are treated in the same way)
-        if (istat == 4) RetraceTrack(*track,kFALSE);
-       hitFound = FollowTrackInStation(*track,7-istat);
+        if (istat == 4) RetraceTrack(*track, kFALSE);
+       clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
       }
       
-      // Remove track if no hit found
-      if (!hitFound) {
+      // Remove track if no cluster found
+      if (!clusterFound) {
         fRecTracksPtr->Remove(track);
        fNRecTracks--;
       }
@@ -150,27 +152,27 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
   //__________________________________________________________________________
 void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed)
 {
-  /// Re-run the kalman filter from the most downstream hit to the most uptream one
+  /// Re-run the kalman filter from the most downstream cluster to the most uptream one
   AliDebug(1,"Enter RetraceTrack");
   
-  AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtHit()->Last();
+  AliMUONTrackParam* startingTrackParam = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtCluster()->Last();
   
-  // Reset the "seed" (= track parameters and their covariances at last hit) if required
+  // Reset the "seed" (= track parameters and their covariances at last cluster) if required
   if (resetSeed) {
-    // => Shift track parameters at the position of the last hit
-    AliMUONHitForRec* hitForRecAtHit = startingTrackParam->GetHitForRecPtr();
-    startingTrackParam->SetNonBendingCoor(hitForRecAtHit->GetNonBendingCoor());
-    startingTrackParam->SetBendingCoor(hitForRecAtHit->GetBendingCoor());
+    // => Shift track parameters at the position of the last cluster
+    AliMUONVCluster* cluster = startingTrackParam->GetClusterPtr();
+    startingTrackParam->SetNonBendingCoor(cluster->GetX());
+    startingTrackParam->SetBendingCoor(cluster->GetY());
     
-    // => Re-compute and reset track parameters covariances at last hit (as if the other hits did not exist)
+    // => Re-compute and reset track parameters covariances at last cluster (as if the other clusters did not exist)
     const TMatrixD& kParamCov = startingTrackParam->GetCovariances();
     TMatrixD newParamCov(5,5);
     newParamCov.Zero();
     // Non bending plane
-    newParamCov(0,0) = hitForRecAtHit->GetNonBendingReso2();
+    newParamCov(0,0) = cluster->GetErrX2();
     newParamCov(1,1) = 100.*kParamCov(1,1);
     // Bending plane
-    newParamCov(2,2) = hitForRecAtHit->GetBendingReso2();
+    newParamCov(2,2) = cluster->GetErrY2();
     newParamCov(3,3) = 100.*kParamCov(3,3);
     // Inverse bending momentum
     newParamCov(4,4) = 0.5*startingTrackParam->GetInverseBendingMomentum() * 0.5*startingTrackParam->GetInverseBendingMomentum();
@@ -189,87 +191,87 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool
   //__________________________________________________________________________
 void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam)
 {
-  /// Re-run the kalman filter from the hit attached to startingTrackParam to the most uptream hit
+  /// Re-run the kalman filter from the cluster attached to startingTrackParam to the most uptream cluster
   AliDebug(1,"Enter RetracePartialTrack");
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-    cout << "RetracePartialTrack: track chi2 before re-tracking: " << trackCandidate.GetFitFMin() << endl;
+    cout << "RetracePartialTrack: track chi2 before re-tracking: " << trackCandidate.GetGlobalChi2() << endl;
   }
   
   // Reset the track chi2
-  trackCandidate.SetFitFMin(startingTrackParam->GetTrackChi2());
+  trackCandidate.SetGlobalChi2(startingTrackParam->GetTrackChi2());
   
-  // loop over attached hits until the first one and recompute track parameters and covariances using kalman filter
-  Int_t expectedChamber = startingTrackParam->GetHitForRecPtr()->GetChamberNumber() - 1;
+  // loop over attached clusters until the first one and recompute track parameters and covariances using kalman filter
+  Int_t expectedChamber = startingTrackParam->GetClusterPtr()->GetChamberId() - 1;
   Int_t currentChamber;
-  Double_t addChi2TrackAtHit;
-  AliMUONTrackParam* trackParamAtHit = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtHit()->Before(startingTrackParam); 
-  while (trackParamAtHit) {
+  Double_t addChi2TrackAtCluster;
+  AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtCluster()->Before(startingTrackParam); 
+  while (trackParamAtCluster) {
     
     // reset track parameters and their covariances
-    trackParamAtHit->SetParameters(startingTrackParam->GetParameters());
-    trackParamAtHit->SetZ(startingTrackParam->GetZ());
-    trackParamAtHit->SetCovariances(startingTrackParam->GetCovariances());
+    trackParamAtCluster->SetParameters(startingTrackParam->GetParameters());
+    trackParamAtCluster->SetZ(startingTrackParam->GetZ());
+    trackParamAtCluster->SetCovariances(startingTrackParam->GetCovariances());
     
     // add MCS effect
-    AliMUONTrackExtrap::AddMCSEffect(trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.);
+    AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.);
     
     // reset propagator for smoother
-    if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) trackParamAtHit->ResetPropagator();
+    if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) trackParamAtCluster->ResetPropagator();
     
     // add MCS in missing chambers if any (at most 2 chambers can be missing according to tracking criteria)
-    currentChamber = trackParamAtHit->GetHitForRecPtr()->GetChamberNumber();
+    currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId();
     while (currentChamber < expectedChamber) {
       // extrapolation to the missing chamber (update the propagator)
-      AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, AliMUONConstants::DefaultChamberZ(expectedChamber),
+      AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber),
                                       AliMUONReconstructor::GetRecoParam()->UseSmoother());
       // add MCS effect
-      AliMUONTrackExtrap::AddMCSEffect(trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.);
+      AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.);
       expectedChamber--;
     }
     
-    // extrapolation to the plane of the hitForRec attached to the current trackParamAtHit (update the propagator)
-    AliMUONTrackExtrap::ExtrapToZCov(trackParamAtHit, trackParamAtHit->GetHitForRecPtr()->GetZ(),
+    // extrapolation to the plane of the cluster attached to the current trackParamAtCluster (update the propagator)
+    AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ(),
                                     AliMUONReconstructor::GetRecoParam()->UseSmoother());
     
     if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
       // save extrapolated parameters for smoother
-      trackParamAtHit->SetExtrapParameters(trackParamAtHit->GetParameters());
+      trackParamAtCluster->SetExtrapParameters(trackParamAtCluster->GetParameters());
       
       // save extrapolated covariance matrix for smoother
-      trackParamAtHit->SetExtrapCovariances(trackParamAtHit->GetCovariances());
+      trackParamAtCluster->SetExtrapCovariances(trackParamAtCluster->GetCovariances());
     }
     
-    // Compute new track parameters including "hitForRecCh2" using kalman filter
-    addChi2TrackAtHit = RunKalmanFilter(*trackParamAtHit);
+    // Compute new track parameters including "clusterCh2" using kalman filter
+    addChi2TrackAtCluster = RunKalmanFilter(*trackParamAtCluster);
     
     // Update the track chi2
-    trackCandidate.SetFitFMin(trackCandidate.GetFitFMin() + addChi2TrackAtHit);
-    trackParamAtHit->SetTrackChi2(trackCandidate.GetFitFMin());
+    trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2() + addChi2TrackAtCluster);
+    trackParamAtCluster->SetTrackChi2(trackCandidate.GetGlobalChi2());
     
-    // prepare next step, add MCS effects in parameter covariances
-    expectedChamber--;
-    startingTrackParam = trackParamAtHit;
-    trackParamAtHit = (AliMUONTrackParam*) (trackCandidate.GetTrackParamAtHit()->Before(startingTrackParam)); 
+    // prepare next step
+    expectedChamber = currentChamber - 1;
+    startingTrackParam = trackParamAtCluster;
+    trackParamAtCluster = (AliMUONTrackParam*) (trackCandidate.GetTrackParamAtCluster()->Before(startingTrackParam)); 
   }
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-    cout << "RetracePartialTrack: track chi2 after re-tracking: " << trackCandidate.GetFitFMin() << endl;
+    cout << "RetracePartialTrack: track chi2 after re-tracking: " << trackCandidate.GetGlobalChi2() << endl;
   }
   
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::FollowTracks()
+void AliMUONTrackReconstructorK::FollowTracks(const AliMUONVClusterStore& clusterStore)
 {
   /// Follow tracks in stations(1..) 3, 2 and 1
   AliDebug(1,"Enter FollowTracks");
   
   AliMUONTrack *track;
   Int_t currentNRecTracks;
-  Bool_t hitFound;
+  Bool_t clusterFound;
   
   for (Int_t station = 2; station >= 0; station--) {
     
@@ -285,18 +287,19 @@ void AliMUONTrackReconstructorK::FollowTracks()
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-        cout<<endl<<"Track parameter covariances at first hit:"<<endl;
-        ((AliMUONTrackParam*) (track->GetTrackParamAtHit()->First()))->GetCovariances().Print();
+        cout<<endl<<"Track parameter covariances at first cluster:"<<endl;
+        ((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->First()))->GetCovariances().Print();
       }
       
-      // Look for compatible hitForRec in station(0..) "station"
-      hitFound = FollowTrackInStation(*track,station);
+      // Look for compatible cluster(s) in station(0..) "station"
+      clusterFound = FollowTrackInStation(*track, clusterStore, station);
       
       // Try to recover track if required
-      if (!hitFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks()) hitFound = RecoverTrack(*track,station);
+      if (!clusterFound && AliMUONReconstructor::GetRecoParam()->RecoverTracks())
+       clusterFound = RecoverTrack(*track, clusterStore, station);
       
-      // remove track if no hit found
-      if (!hitFound) {
+      // remove track if no cluster found
+      if (!clusterFound) {
        fRecTracksPtr->Remove(track);
        fNRecTracks--;
       }
@@ -313,15 +316,15 @@ void AliMUONTrackReconstructorK::FollowTracks()
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation)
+Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation)
 {
-  /// Follow trackCandidate in station(0..) nextStation and search for compatible HitForRec(s)
+  /// Follow trackCandidate in station(0..) nextStation and search for compatible cluster(s)
   /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
   /// kTRUE:  duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
   ///         fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
   ///         Remove the obsolete "trackCandidate" at the end.
-  /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority.
-  /// return kTRUE if new hits have been found (otherwise return kFALSE)
+  /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority.
+  /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE)
   AliDebug(1,Form("Enter FollowTrackInStation(1..) %d", nextStation+1));
   
   // Order the chamber according to the propagation direction (tracking starts with chamber 2):
@@ -336,27 +339,30 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     ch2 = 2*nextStation+1;
   }
   
-  Double_t chi2OfHitForRec;
-  Double_t maxChi2OfHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
-                                    AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
-  Double_t addChi2TrackAtHit1;
-  Double_t addChi2TrackAtHit2;
-  Double_t bestAddChi2TrackAtHit1 = 1.e10;
-  Double_t bestAddChi2TrackAtHit2 = 1.e10;
-  Bool_t foundOneHit = kFALSE;
-  Bool_t foundTwoHits = kFALSE;
+  Double_t chi2OfCluster;
+  Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+                                  AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+  Double_t addChi2TrackAtCluster1;
+  Double_t addChi2TrackAtCluster2;
+  Double_t bestAddChi2TrackAtCluster1 = 1.e10;
+  Double_t bestAddChi2TrackAtCluster2 = 1.e10;
+  Bool_t foundOneCluster = kFALSE;
+  Bool_t foundTwoClusters = kFALSE;
   AliMUONTrack *newTrack = 0x0;
-  AliMUONHitForRec *hitForRecCh1, *hitForRecCh2;
+  AliMUONVCluster *clusterCh1, *clusterCh2;
   AliMUONTrackParam extrapTrackParam;
-  AliMUONTrackParam extrapTrackParamAtHit1;
-  AliMUONTrackParam extrapTrackParamAtHit2;
-  AliMUONTrackParam bestTrackParamAtHit1;
-  AliMUONTrackParam bestTrackParamAtHit2;
-  Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]];
-  for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE;
-
+  AliMUONTrackParam extrapTrackParamAtCluster1;
+  AliMUONTrackParam extrapTrackParamAtCluster2;
+  AliMUONTrackParam bestTrackParamAtCluster1;
+  AliMUONTrackParam bestTrackParamAtCluster2;
+  
+  Int_t nClusters = clusterStore.GetSize();
+  Bool_t *clusterCh1Used = new Bool_t[nClusters];
+  for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE;
+  Int_t iCluster1;
+  
   // Get track parameters
-  AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
+  AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First());
   
   // Add MCS effect
   AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
@@ -365,7 +371,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
   if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator();
   
   // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria)
-  if (ch1 < ch2 && extrapTrackParamAtCh.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) {
+  if (ch1 < ch2 && extrapTrackParamAtCh.GetClusterPtr()->GetChamberId() > ch2 + 1) {
     // extrapolation to the missing chamber
     AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1),
                                     AliMUONReconstructor::GetRecoParam()->UseSmoother());
@@ -379,51 +385,53 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-    cout<<endl<<"Track parameter covariances at first hit extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+    cout<<endl<<"Track parameter covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
     extrapTrackParamAtCh.GetCovariances().Print();
   }
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-    cout << "FollowTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl;
+    cout << "FollowTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl;
   }
   
-  // look for candidates in chamber 2 
-  for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) {
-    
-    hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2);
+  // Create iterators to loop over clusters in both chambers
+  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
+  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
+  
+  // look for candidates in chamber 2
+  while ( ( clusterCh2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
     
-    // try to add the current hit fast
-    if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh2)) continue;
+    // try to add the current cluster fast
+    if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh2)) continue;
     
-    // try to add the current hit accuratly
-    chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh2, extrapTrackParamAtHit2,
-                                     AliMUONReconstructor::GetRecoParam()->UseSmoother());
+    // try to add the current cluster accuratly
+    chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh2, extrapTrackParamAtCluster2,
+                                 AliMUONReconstructor::GetRecoParam()->UseSmoother());
     
-    // if good chi2 then try to attach a hitForRec in the other chamber too
-    if (chi2OfHitForRec < maxChi2OfHitForRec) {
-      Bool_t foundSecondHit = kFALSE;
+    // if good chi2 then try to attach a cluster in the other chamber too
+    if (chi2OfCluster < maxChi2OfCluster) {
+      Bool_t foundSecondCluster = kFALSE;
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch2+1
-            << " (Chi2 = " << chi2OfHitForRec << ")" << endl;
-        cout << "                      look for second hits in chamber(1..): " << ch1+1 << " ..." << endl;
+        cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1
+            << " (Chi2 = " << chi2OfCluster << ")" << endl;
+        cout << "                      look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
       }
       
       if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
         // save extrapolated parameters for smoother
-        extrapTrackParamAtHit2.SetExtrapParameters(extrapTrackParamAtHit2.GetParameters());
+        extrapTrackParamAtCluster2.SetExtrapParameters(extrapTrackParamAtCluster2.GetParameters());
         
         // save extrapolated covariance matrix for smoother
-        extrapTrackParamAtHit2.SetExtrapCovariances(extrapTrackParamAtHit2.GetCovariances());
+        extrapTrackParamAtCluster2.SetExtrapCovariances(extrapTrackParamAtCluster2.GetCovariances());
       }
       
-      // Compute new track parameters including "hitForRecCh2" using kalman filter
-      addChi2TrackAtHit2 = RunKalmanFilter(extrapTrackParamAtHit2);
+      // Compute new track parameters including "clusterCh2" using kalman filter
+      addChi2TrackAtCluster2 = RunKalmanFilter(extrapTrackParamAtCluster2);
       
       // copy new track parameters for next step
-      extrapTrackParam = extrapTrackParamAtHit2;
+      extrapTrackParam = extrapTrackParamAtCluster2;
       
       // add MCS effect
       AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
@@ -435,78 +443,82 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
       AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1),
                                       AliMUONReconstructor::GetRecoParam()->UseSmoother());
       
-      for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
-        
-       hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+      // reset cluster iterator of chamber 1
+      nextInCh1.Reset();
+      iCluster1 = -1;
+      
+      // look for second candidates in chamber 1
+      while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+       iCluster1++;
        
-       // try to add the current hit fast
-       if (!TryOneHitForRecFast(extrapTrackParam, hitForRecCh1)) continue;
+       // try to add the current cluster fast
+       if (!TryOneClusterFast(extrapTrackParam, clusterCh1)) continue;
        
-       // try to add the current hit accuratly
-       chi2OfHitForRec = TryOneHitForRec(extrapTrackParam, hitForRecCh1, extrapTrackParamAtHit1,
+       // try to add the current cluster accuratly
+       chi2OfCluster = TryOneCluster(extrapTrackParam, clusterCh1, extrapTrackParamAtCluster1,
                                          AliMUONReconstructor::GetRecoParam()->UseSmoother());
        
-       // if good chi2 then consider to add the 2 hitForRec to the "trackCandidate"
-       if (chi2OfHitForRec < maxChi2OfHitForRec) {
-         foundSecondHit = kTRUE;
-         foundTwoHits = kTRUE;
+       // if good chi2 then consider to add the 2 clusters to the "trackCandidate"
+       if (chi2OfCluster < maxChi2OfCluster) {
+         foundSecondCluster = kTRUE;
+         foundTwoClusters = kTRUE;
           
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
-                << " (Chi2 = " << chi2OfHitForRec << ")" << endl;
+           cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
+                << " (Chi2 = " << chi2OfCluster << ")" << endl;
          }
           
           if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
             // save extrapolated parameters for smoother
-            extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters());
+            extrapTrackParamAtCluster1.SetExtrapParameters(extrapTrackParamAtCluster1.GetParameters());
             
             // save extrapolated covariance matrix for smoother
-            extrapTrackParamAtHit1.SetExtrapCovariances(extrapTrackParamAtHit1.GetCovariances());
+            extrapTrackParamAtCluster1.SetExtrapCovariances(extrapTrackParamAtCluster1.GetCovariances());
           }
           
-          // Compute new track parameters including "hitForRecCh1" using kalman filter
-          addChi2TrackAtHit1 = RunKalmanFilter(extrapTrackParamAtHit1);
+          // Compute new track parameters including "clusterCh1" using kalman filter
+          addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1);
           
          if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
             newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-           UpdateTrack(*newTrack,extrapTrackParamAtHit1,extrapTrackParamAtHit2,addChi2TrackAtHit1,addChi2TrackAtHit2);
+           UpdateTrack(*newTrack,extrapTrackParamAtCluster1,extrapTrackParamAtCluster2,addChi2TrackAtCluster1,addChi2TrackAtCluster2);
            fNRecTracks++;
            
            // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
            // (going in the right direction)
            if (nextStation == 4) RetraceTrack(*newTrack,kTRUE);
            
-           // Tag hitForRecCh1 as used
-           hitForRecCh1Used[hit1] = kTRUE;
+           // Tag clusterCh1 as used
+           clusterCh1Used[iCluster1] = kTRUE;
            
            // Printout for debuging
            if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-             cout << "FollowTrackInStation: added two hits in station(1..): " << nextStation+1 << endl;
+             cout << "FollowTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl;
              if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
            }
            
-          } else if (addChi2TrackAtHit1+addChi2TrackAtHit2 < bestAddChi2TrackAtHit1+bestAddChi2TrackAtHit2) {
-           // keep track of the best couple of hits
-           bestAddChi2TrackAtHit1 = addChi2TrackAtHit1;
-           bestAddChi2TrackAtHit2 = addChi2TrackAtHit2;
-           bestTrackParamAtHit1 = extrapTrackParamAtHit1;
-           bestTrackParamAtHit2 = extrapTrackParamAtHit2;
+          } else if (addChi2TrackAtCluster1+addChi2TrackAtCluster2 < bestAddChi2TrackAtCluster1+bestAddChi2TrackAtCluster2) {
+           // keep track of the best couple of clusters
+           bestAddChi2TrackAtCluster1 = addChi2TrackAtCluster1;
+           bestAddChi2TrackAtCluster2 = addChi2TrackAtCluster2;
+           bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
+           bestTrackParamAtCluster2 = extrapTrackParamAtCluster2;
           }
          
        }
        
       }
       
-      // if no hitForRecCh1 found then consider to add hitForRecCh2 only
-      if (!foundSecondHit) {
-       foundOneHit = kTRUE;
+      // if no clusterCh1 found then consider to add clusterCh2 only
+      if (!foundSecondCluster) {
+       foundOneCluster = kTRUE;
         
        if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
           newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-         UpdateTrack(*newTrack,extrapTrackParamAtHit2,addChi2TrackAtHit2);
+         UpdateTrack(*newTrack,extrapTrackParamAtCluster2,addChi2TrackAtCluster2);
          fNRecTracks++;
          
          // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
@@ -515,14 +527,14 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl;
+           cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl;
            if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
          }
          
-       } else if (!foundTwoHits && addChi2TrackAtHit2 < bestAddChi2TrackAtHit1) {
-         // keep track of the best single hitForRec except if a couple of hits has already been found
-         bestAddChi2TrackAtHit1 = addChi2TrackAtHit2;
-         bestTrackParamAtHit1 = extrapTrackParamAtHit2;
+       } else if (!foundTwoClusters && addChi2TrackAtCluster2 < bestAddChi2TrackAtCluster1) {
+         // keep track of the best single cluster except if a couple of clusters has already been found
+         bestAddChi2TrackAtCluster1 = addChi2TrackAtCluster2;
+         bestTrackParamAtCluster1 = extrapTrackParamAtCluster2;
         }
        
       }
@@ -532,12 +544,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
   }
   
   // look for candidates in chamber 1 not already attached to a track
-  // if we want to keep all possible tracks or if no good couple of hitForRec has been found
-  if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoHits) {
+  // if we want to keep all possible tracks or if no good couple of clusters has been found
+  if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
     
     // Printout for debuging
     if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-      cout << "FollowTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl;
+      cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
     }
     
     // add MCS effect for next step
@@ -547,45 +559,49 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1),
                                     AliMUONReconstructor::GetRecoParam()->UseSmoother());
     
-    for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
-      
-      hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+    // reset cluster iterator of chamber 1
+    nextInCh1.Reset();
+    iCluster1 = -1;
+    
+    // look for second candidates in chamber 1
+    while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+      iCluster1++;
       
-      if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used
+      if (clusterCh1Used[iCluster1]) continue; // Skip clusters already used
       
-      // try to add the current hit fast
-      if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh1)) continue;
+      // try to add the current cluster fast
+      if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh1)) continue;
       
-      // try to add the current hit accuratly
-      chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh1, extrapTrackParamAtHit1,
-                                       AliMUONReconstructor::GetRecoParam()->UseSmoother());
+      // try to add the current cluster accuratly
+      chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1,
+                                   AliMUONReconstructor::GetRecoParam()->UseSmoother());
       
-      // if good chi2 then consider to add hitForRecCh1
-      // We do not try to attach a hitForRec in the other chamber too since it has already been done above
-      if (chi2OfHitForRec < maxChi2OfHitForRec) {
-       foundOneHit = kTRUE;
+      // if good chi2 then consider to add clusterCh1
+      // We do not try to attach a cluster in the other chamber too since it has already been done above
+      if (chi2OfCluster < maxChi2OfCluster) {
+       foundOneCluster = kTRUE;
        
        // Printout for debuging
        if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-         cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
-              << " (Chi2 = " << chi2OfHitForRec << ")" << endl;
+         cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
+              << " (Chi2 = " << chi2OfCluster << ")" << endl;
        }
         
        if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) {
           // save extrapolated parameters for smoother
-          extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters());
+          extrapTrackParamAtCluster1.SetExtrapParameters(extrapTrackParamAtCluster1.GetParameters());
           
           // save extrapolated covariance matrix for smoother
-          extrapTrackParamAtHit1.SetExtrapCovariances(extrapTrackParamAtHit1.GetCovariances());
+          extrapTrackParamAtCluster1.SetExtrapCovariances(extrapTrackParamAtCluster1.GetCovariances());
         }
         
-        // Compute new track parameters including "hitForRecCh1" using kalman filter
-        addChi2TrackAtHit1 = RunKalmanFilter(extrapTrackParamAtHit1);
+        // Compute new track parameters including "clusterCh1" using kalman filter
+        addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1);
         
        if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
          newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-         UpdateTrack(*newTrack,extrapTrackParamAtHit1,addChi2TrackAtHit1);
+         UpdateTrack(*newTrack,extrapTrackParamAtCluster1,addChi2TrackAtCluster1);
          fNRecTracks++;
          
          // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
@@ -594,14 +610,14 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl;
+           cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl;
            if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
          }
          
-       } else if (addChi2TrackAtHit1 < bestAddChi2TrackAtHit1) {
-         // keep track of the best single hitForRec except if a couple of hits has already been found
-         bestAddChi2TrackAtHit1 = addChi2TrackAtHit1;
-         bestTrackParamAtHit1 = extrapTrackParamAtHit1;
+       } else if (addChi2TrackAtCluster1 < bestAddChi2TrackAtCluster1) {
+         // keep track of the best single cluster except if a couple of clusters has already been found
+         bestAddChi2TrackAtCluster1 = addChi2TrackAtCluster1;
+         bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
        }
        
       }
@@ -612,8 +628,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
   
   // fill out the best track if required else clean up the fRecTracksPtr array
   if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-    if (foundTwoHits) {
-      UpdateTrack(trackCandidate,bestTrackParamAtHit1,bestTrackParamAtHit2,bestAddChi2TrackAtHit1,bestAddChi2TrackAtHit2);
+    if (foundTwoClusters) {
+      UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestTrackParamAtCluster2,bestAddChi2TrackAtCluster1,bestAddChi2TrackAtCluster2);
       
       // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
       // (going in the right direction)
@@ -621,12 +637,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
 
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl;
+        cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
         if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
       }
       
-    } else if (foundOneHit) {
-      UpdateTrack(trackCandidate,bestTrackParamAtHit1,bestAddChi2TrackAtHit1);
+    } else if (foundOneCluster) {
+      UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestAddChi2TrackAtCluster1);
       
       // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station
       // (going in the right direction)
@@ -634,48 +650,48 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
 
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl;
+        cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
         if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
       }
       
     } else {
-      delete [] hitForRecCh1Used;
+      delete [] clusterCh1Used;
       return kFALSE;
     }
-  } else if (foundOneHit || foundTwoHits) {
+  } else if (foundOneCluster || foundTwoClusters) {
     
     // remove obsolete track
     fRecTracksPtr->Remove(&trackCandidate);
     fNRecTracks--;
     
   } else {
-    delete [] hitForRecCh1Used;
+    delete [] clusterCh1Used;
     return kFALSE;
   }  
-  delete [] hitForRecCh1Used;
+  delete [] clusterCh1Used;
   return kTRUE;
   
 }
 
   //__________________________________________________________________________
-Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackParamAtHit)
+Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster)
 {
-  /// Compute new track parameters and their covariances including new hit using kalman filter
+  /// Compute new track parameters and their covariances including new cluster using kalman filter
   /// return the additional track chi2
   AliDebug(1,"Enter RunKalmanFilter");
   
   // Get actual track parameters (p)
-  TMatrixD param(trackParamAtHit.GetParameters());
+  TMatrixD param(trackParamAtCluster.GetParameters());
   
-  // Get new hit parameters (m)
-  AliMUONHitForRec *hitForRecAtHit = trackParamAtHit.GetHitForRecPtr();
-  TMatrixD hit(5,1);
-  hit.Zero();
-  hit(0,0) = hitForRecAtHit->GetNonBendingCoor();
-  hit(2,0) = hitForRecAtHit->GetBendingCoor();
+  // Get new cluster parameters (m)
+  AliMUONVCluster *cluster = trackParamAtCluster.GetClusterPtr();
+  TMatrixD clusterParam(5,1);
+  clusterParam.Zero();
+  clusterParam(0,0) = cluster->GetX();
+  clusterParam(2,0) = cluster->GetY();
   
   // Compute the actual parameter weight (W)
-  TMatrixD paramWeight(trackParamAtHit.GetCovariances());
+  TMatrixD paramWeight(trackParamAtCluster.GetCovariances());
   if (paramWeight.Determinant() != 0) {
     paramWeight.Invert();
   } else {
@@ -683,14 +699,14 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar
     return 1.e10;
   }
   
-  // Compute the new hit weight (U)
-  TMatrixD hitWeight(5,5);
-  hitWeight.Zero();
-  hitWeight(0,0) = 1. / hitForRecAtHit->GetNonBendingReso2();
-  hitWeight(2,2) = 1. / hitForRecAtHit->GetBendingReso2();
+  // Compute the new cluster weight (U)
+  TMatrixD clusterWeight(5,5);
+  clusterWeight.Zero();
+  clusterWeight(0,0) = 1. / cluster->GetErrX2();
+  clusterWeight(2,2) = 1. / cluster->GetErrY2();
 
   // Compute the new parameters covariance matrix ( (W+U)^-1 )
-  TMatrixD newParamCov(paramWeight,TMatrixD::kPlus,hitWeight);
+  TMatrixD newParamCov(paramWeight,TMatrixD::kPlus,clusterWeight);
   if (newParamCov.Determinant() != 0) {
     newParamCov.Invert();
   } else {
@@ -699,16 +715,16 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar
   }
   
   // Save the new parameters covariance matrix
-  trackParamAtHit.SetCovariances(newParamCov);
+  trackParamAtCluster.SetCovariances(newParamCov);
   
   // Compute the new parameters (p' = ((W+U)^-1)U(m-p) + p)
-  TMatrixD tmp(hit,TMatrixD::kMinus,param);
-  TMatrixD tmp2(hitWeight,TMatrixD::kMult,tmp); // U(m-p)
+  TMatrixD tmp(clusterParam,TMatrixD::kMinus,param);
+  TMatrixD tmp2(clusterWeight,TMatrixD::kMult,tmp); // U(m-p)
   TMatrixD newParam(newParamCov,TMatrixD::kMult,tmp2); // ((W+U)^-1)U(m-p)
   newParam += param; // ((W+U)^-1)U(m-p) + p
   
   // Save the new parameters
-  trackParamAtHit.SetParameters(newParam);
+  trackParamAtCluster.SetParameters(newParam);
   
   // Compute the additional chi2 (= ((p'-p)^-1)W(p'-p) + ((p'-m)^-1)U(p'-m))
   tmp = newParam; // p'
@@ -716,8 +732,8 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar
   TMatrixD tmp3(paramWeight,TMatrixD::kMult,tmp); // W(p'-p)
   TMatrixD addChi2Track(tmp,TMatrixD::kTransposeMult,tmp3); // ((p'-p)^-1)W(p'-p)
   tmp = newParam; // p'
-  tmp -= hit; // (p'-m)
-  TMatrixD tmp4(hitWeight,TMatrixD::kMult,tmp); // U(p'-m)
+  tmp -= clusterParam; // (p'-m)
+  TMatrixD tmp4(clusterWeight,TMatrixD::kMult,tmp); // U(p'-m)
   addChi2Track += TMatrixD(tmp,TMatrixD::kTransposeMult,tmp4); // ((p'-p)^-1)W(p'-p) + ((p'-m)^-1)U(p'-m)
   
   return addChi2Track(0,0);
@@ -725,114 +741,114 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit, Double_t addChi2)
+void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster, Double_t addChi2)
 {
-  /// Add 1 hit to the track candidate
+  /// Add 1 cluster to the track candidate
   /// Update chi2 of the track 
   
-  // Flag hit as being not removable
-  trackParamAtHit.SetRemovable(kFALSE);
-  trackParamAtHit.SetLocalChi2(0.); // --> Local chi2 not used
+  // Flag cluster as being not removable
+  trackParamAtCluster.SetRemovable(kFALSE);
+  trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used
   
-  // Update the track chi2 into TrackParamAtHit
-  trackParamAtHit.SetTrackChi2(track.GetFitFMin() + addChi2);
+  // Update the track chi2 into trackParamAtCluster
+  trackParamAtCluster.SetTrackChi2(track.GetGlobalChi2() + addChi2);
   
   // Update the chi2 of the new track
-  track.SetFitFMin(trackParamAtHit.GetTrackChi2());
+  track.SetGlobalChi2(trackParamAtCluster.GetTrackChi2());
   
-  // Update array of TrackParamAtHit
-  track.AddTrackParamAtHit(&trackParamAtHit,trackParamAtHit.GetHitForRecPtr());
-  track.GetTrackParamAtHit()->Sort();
+  // Update array of TrackParamAtCluster
+  track.AddTrackParamAtCluster(trackParamAtCluster,*(trackParamAtCluster.GetClusterPtr()));
+  track.GetTrackParamAtCluster()->Sort();
   
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2,
-                                            Double_t addChi2AtHit1, Double_t addChi2AtHit2)
+void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2,
+                                            Double_t addChi2AtCluster1, Double_t addChi2AtCluster2)
 {
-  /// Add 2 hits to the track candidate
+  /// Add 2 clusters to the track candidate (order is important)
   /// Update track and local chi2
   
-  // Update local chi2 at first hit
-  AliMUONHitForRec* hit1 = trackParamAtHit1.GetHitForRecPtr();
-  Double_t deltaX = trackParamAtHit1.GetNonBendingCoor() - hit1->GetNonBendingCoor();
-  Double_t deltaY = trackParamAtHit1.GetBendingCoor() - hit1->GetBendingCoor();
-  Double_t localChi2AtHit1 = deltaX*deltaX / hit1->GetNonBendingReso2() +
-                            deltaY*deltaY / hit1->GetBendingReso2();
-  trackParamAtHit1.SetLocalChi2(localChi2AtHit1);
+  // Update local chi2 at first cluster
+  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
+  Double_t deltaX = trackParamAtCluster1.GetNonBendingCoor() - cluster1->GetX();
+  Double_t deltaY = trackParamAtCluster1.GetBendingCoor() - cluster1->GetY();
+  Double_t localChi2AtCluster1 = deltaX*deltaX / cluster1->GetErrX2() +
+                                deltaY*deltaY / cluster1->GetErrY2();
+  trackParamAtCluster1.SetLocalChi2(localChi2AtCluster1);
   
-  // Flag first hit as being removable
-  trackParamAtHit1.SetRemovable(kTRUE);
+  // Flag first cluster as being removable
+  trackParamAtCluster1.SetRemovable(kTRUE);
   
-  // Update local chi2 at second hit
-  AliMUONHitForRec* hit2 = trackParamAtHit2.GetHitForRecPtr();
-  AliMUONTrackParam extrapTrackParamAtHit2(trackParamAtHit1);
-  AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParamAtHit2, trackParamAtHit2.GetZ());
-  deltaX = extrapTrackParamAtHit2.GetNonBendingCoor() - hit2->GetNonBendingCoor();
-  deltaY = extrapTrackParamAtHit2.GetBendingCoor() - hit2->GetBendingCoor();
-  Double_t localChi2AtHit2 = deltaX*deltaX / hit2->GetNonBendingReso2() +
-                            deltaY*deltaY / hit2->GetBendingReso2();
-  trackParamAtHit2.SetLocalChi2(localChi2AtHit2);
+  // Update local chi2 at second cluster
+  AliMUONVCluster* cluster2 = trackParamAtCluster2.GetClusterPtr();
+  AliMUONTrackParam extrapTrackParamAtCluster2(trackParamAtCluster1);
+  AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParamAtCluster2, trackParamAtCluster2.GetZ());
+  deltaX = extrapTrackParamAtCluster2.GetNonBendingCoor() - cluster2->GetX();
+  deltaY = extrapTrackParamAtCluster2.GetBendingCoor() - cluster2->GetY();
+  Double_t localChi2AtCluster2 = deltaX*deltaX / cluster2->GetErrX2() +
+                                deltaY*deltaY / cluster2->GetErrY2();
+  trackParamAtCluster2.SetLocalChi2(localChi2AtCluster2);
   
-  // Flag second hit as being removable
-  trackParamAtHit2.SetRemovable(kTRUE);
+  // Flag second cluster as being removable
+  trackParamAtCluster2.SetRemovable(kTRUE);
   
-  // Update the track chi2 into TrackParamAtHit1
-  trackParamAtHit1.SetTrackChi2(track.GetFitFMin() + addChi2AtHit1);
+  // Update the track chi2 into trackParamAtCluster2
+  trackParamAtCluster2.SetTrackChi2(track.GetGlobalChi2() + addChi2AtCluster2);
   
-  // Update the track chi2 into TrackParamAtHit2
-  trackParamAtHit2.SetTrackChi2(trackParamAtHit1.GetTrackChi2() + addChi2AtHit2);
+  // Update the track chi2 into trackParamAtCluster1
+  trackParamAtCluster1.SetTrackChi2(trackParamAtCluster2.GetTrackChi2() + addChi2AtCluster1);
   
   // Update the chi2 of the new track
-  track.SetFitFMin(trackParamAtHit2.GetTrackChi2());
+  track.SetGlobalChi2(trackParamAtCluster1.GetTrackChi2());
   
-  // Update array of TrackParamAtHit
-  track.AddTrackParamAtHit(&trackParamAtHit1,trackParamAtHit1.GetHitForRecPtr());
-  track.AddTrackParamAtHit(&trackParamAtHit2,trackParamAtHit2.GetHitForRecPtr());
-  track.GetTrackParamAtHit()->Sort();
+  // Update array of trackParamAtCluster
+  track.AddTrackParamAtCluster(trackParamAtCluster1,*cluster1);
+  track.AddTrackParamAtCluster(trackParamAtCluster2,*cluster2);
+  track.GetTrackParamAtCluster()->Sort();
   
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Int_t nextStation)
+Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation)
 {
   /// Try to recover the track candidate in the next station
-  /// by removing the worst of the two hits attached in the current station
+  /// by removing the worst of the two clusters attached in the current station
   /// Return kTRUE if recovering succeeds
   AliDebug(1,"Enter RecoverTrack");
   
-  // Do not try to recover track until we have attached hit(s) on station(1..) 3
+  // Do not try to recover track until we have attached cluster(s) on station(1..) 3
   if (nextStation > 1) return kFALSE;
   
-  Int_t worstHitNumber = -1;
-  Double_t localChi2, worstChi2 = 0.;
+  Int_t worstClusterNumber = -1;
+  Double_t localChi2, worstLocalChi2 = 0.;
   
-  // Look for the hit to remove
-  for (Int_t hitNumber = 0; hitNumber < 2; hitNumber++) {
-    AliMUONTrackParam *trackParamAtHit = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(hitNumber);
+  // Look for the cluster to remove
+  for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) {
+    AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber);
     
-    // check if current hit is removable
-    if (!trackParamAtHit->IsRemovable()) return kFALSE;
+    // check if current cluster is removable
+    if (!trackParamAtCluster->IsRemovable()) return kFALSE;
     
-    // Pick up hit with the worst chi2
-    localChi2 = trackParamAtHit->GetLocalChi2();
-    if (localChi2 > worstChi2) {
-      worstChi2 = localChi2;
-      worstHitNumber = hitNumber;
+    // Pick up cluster with the worst chi2
+    localChi2 = trackParamAtCluster->GetLocalChi2();
+    if (localChi2 > worstLocalChi2) {
+      worstLocalChi2 = localChi2;
+      worstClusterNumber = clusterNumber;
     }
   }
   
-  // Reset best hit as being NOT removable
-  ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt((worstHitNumber+1)%2))->SetRemovable(kFALSE);
+  // Reset best cluster as being NOT removable
+  ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt((worstClusterNumber+1)%2))->SetRemovable(kFALSE);
   
-  // Remove the worst hit
-  trackCandidate.RemoveTrackParamAtHit((AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(worstHitNumber));
+  // Remove the worst cluster
+  trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber));
   
-  // Re-calculate track parameters at the (new) first hit
-  RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->UncheckedAt(1));
+  // Re-calculate track parameters at the (new) first cluster
+  RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1));
   
-  // Look for new hit(s) in next station
-  return FollowTrackInStation(trackCandidate,nextStation);
+  // Look for new cluster(s) in next station
+  return FollowTrackInStation(trackCandidate, clusterStore, nextStation);
   
 }
 
@@ -842,22 +858,22 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track)
   /// Compute new track parameters and their covariances using smoother
   AliDebug(1,"Enter UseSmoother");
   
-  AliMUONTrackParam *previousTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtHit()->First();
+  AliMUONTrackParam *previousTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First();
   
-  // Smoothed parameters and covariances at first hit = filtered parameters and covariances
+  // Smoothed parameters and covariances at first cluster = filtered parameters and covariances
   previousTrackParam->SetSmoothParameters(previousTrackParam->GetParameters());
   previousTrackParam->SetSmoothCovariances(previousTrackParam->GetCovariances());
   
-  // Compute local chi2 at first hit
-  AliMUONHitForRec *hitForRecAtHit = previousTrackParam->GetHitForRecPtr();
-  Double_t dX = hitForRecAtHit->GetNonBendingCoor() - previousTrackParam->GetNonBendingCoor();
-  Double_t dY = hitForRecAtHit->GetBendingCoor() - previousTrackParam->GetBendingCoor();
-  Double_t localChi2 = dX * dX / hitForRecAtHit->GetNonBendingReso2() + dY * dY / hitForRecAtHit->GetBendingReso2();
+  // Compute local chi2 at first cluster
+  AliMUONVCluster *cluster = previousTrackParam->GetClusterPtr();
+  Double_t dX = cluster->GetX() - previousTrackParam->GetNonBendingCoor();
+  Double_t dY = cluster->GetY() - previousTrackParam->GetBendingCoor();
+  Double_t localChi2 = dX * dX / cluster->GetErrX2() + dY * dY / cluster->GetErrY2();
   
-  // Save local chi2 at first hit
+  // Save local chi2 at first cluster
   previousTrackParam->SetLocalChi2(localChi2);
   
-  AliMUONTrackParam *currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtHit()->After(previousTrackParam);
+  AliMUONTrackParam *currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(previousTrackParam);
   while (currentTrackParam) {
     
     // Get variables
@@ -897,19 +913,19 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track)
     // Save smoothed covariances
     currentTrackParam->SetSmoothCovariances(smoothCovariances);
     
-    // Compute smoothed residual: r(k n) = hit - X(k n)
-    hitForRecAtHit = currentTrackParam->GetHitForRecPtr();
+    // Compute smoothed residual: r(k n) = cluster - X(k n)
+    cluster = currentTrackParam->GetClusterPtr();
     TMatrixD smoothResidual(2,1);
     smoothResidual.Zero();
-    smoothResidual(0,0) = hitForRecAtHit->GetNonBendingCoor() - smoothParameters(0,0);
-    smoothResidual(1,0) = hitForRecAtHit->GetBendingCoor() - smoothParameters(2,0);
+    smoothResidual(0,0) = cluster->GetX() - smoothParameters(0,0);
+    smoothResidual(1,0) = cluster->GetY() - smoothParameters(2,0);
     
-    // Compute weight of smoothed residual: W(k n) = (hitCov - C(k n))^-1
+    // Compute weight of smoothed residual: W(k n) = (clusterCov - C(k n))^-1
     TMatrixD smoothResidualWeight(2,2);
-    smoothResidualWeight(0,0) = hitForRecAtHit->GetNonBendingReso2() - smoothCovariances(0,0);
+    smoothResidualWeight(0,0) = cluster->GetErrX2() - smoothCovariances(0,0);
     smoothResidualWeight(0,1) = - smoothCovariances(0,2);
     smoothResidualWeight(1,0) = - smoothCovariances(2,0);
-    smoothResidualWeight(1,1) = hitForRecAtHit->GetBendingReso2() - smoothCovariances(2,2);
+    smoothResidualWeight(1,1) = cluster->GetErrY2() - smoothCovariances(2,2);
     if (smoothResidualWeight.Determinant() != 0) {
       smoothResidualWeight.Invert();
     } else {
@@ -925,7 +941,7 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track)
     currentTrackParam->SetLocalChi2(localChi2(0,0));
     
     previousTrackParam = currentTrackParam;
-    currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtHit()->After(previousTrackParam);
+    currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(previousTrackParam);
   }
   
   return kTRUE;
@@ -933,7 +949,7 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track)
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::ComplementTracks()
+void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& clusterStore)
 {
   /// Complete tracks by adding missing clusters (if there is an overlap between
   /// two detection elements, the track may have two clusters in the same chamber)
@@ -941,14 +957,12 @@ void AliMUONTrackReconstructorK::ComplementTracks()
   AliDebug(1,"Enter ComplementTracks");
   
   Int_t chamberId, detElemId;
-  Double_t chi2OfHitForRec, addChi2TrackAtHit, bestAddChi2TrackAtHit;
-  Double_t maxChi2OfHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
-                                     AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
-  Bool_t foundOneHit, trackModified;
-  AliMUONHitForRec *hitForRec;
-  AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam;
-  AliMUONTrackParam trackParamAtHit;
-  AliMUONTrackParam bestTrackParamAtHit;
+  Double_t chi2OfCluster, addChi2TrackAtCluster, bestAddChi2TrackAtCluster;
+  Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+                                  AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+  Bool_t foundOneCluster, trackModified;
+  AliMUONVCluster *cluster;
+  AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam, trackParamAtCluster, bestTrackParamAtCluster;
   
   // Remove double track to complete only "good" tracks
   RemoveDoubleTracks();
@@ -957,45 +971,45 @@ void AliMUONTrackReconstructorK::ComplementTracks()
   while (track) {
     trackModified = kFALSE;
     
-    trackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First();
+    trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
     previousTrackParam = trackParam;
     while (trackParam) {
-      foundOneHit = kFALSE;
-      bestAddChi2TrackAtHit = 1.e10;
+      foundOneCluster = kFALSE;
+      bestAddChi2TrackAtCluster = 1.e10;
+      chamberId = trackParam->GetClusterPtr()->GetChamberId();
+      detElemId = trackParam->GetClusterPtr()->GetDetElemId();
       
       // prepare nextTrackParam before adding new cluster because of the sorting
-      nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParam);
+      nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParam);
       
-      chamberId = trackParam->GetHitForRecPtr()->GetChamberNumber();
-      detElemId = trackParam->GetHitForRecPtr()->GetDetElemId();
+      // Create iterators to loop over clusters in current chamber
+      TIter nextInCh(clusterStore.CreateChamberIterator(chamberId,chamberId));
       
       // look for one second candidate in the same chamber
-      for (Int_t hit = 0; hit < fNHitsForRecPerChamber[chamberId]; hit++) {
-       
-       hitForRec = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[chamberId]+hit);
+      while ( ( cluster = static_cast<AliMUONVCluster*>(nextInCh()) ) ) {
         
        // look for a cluster in another detection element
-       if (hitForRec->GetDetElemId() == detElemId) continue;
+       if (cluster->GetDetElemId() == detElemId) continue;
        
-       // try to add the current hit fast
-       if (!TryOneHitForRecFast(*trackParam, hitForRec)) continue;
+       // try to add the current cluster fast
+       if (!TryOneClusterFast(*trackParam, cluster)) continue;
        
-       // try to add the current hit accurately
+       // try to add the current cluster accurately
        // never use track parameters at last cluster because the covariance matrix is meaningless
-       if (nextTrackParam) chi2OfHitForRec = TryOneHitForRec(*trackParam, hitForRec, trackParamAtHit);
-       else chi2OfHitForRec = TryOneHitForRec(*previousTrackParam, hitForRec, trackParamAtHit);
+       if (nextTrackParam) chi2OfCluster = TryOneCluster(*trackParam, cluster, trackParamAtCluster);
+       else chi2OfCluster = TryOneCluster(*previousTrackParam, cluster, trackParamAtCluster);
        
        // if good chi2 then consider to add this cluster to the track
-       if (chi2OfHitForRec < maxChi2OfHitForRec) {
+       if (chi2OfCluster < maxChi2OfCluster) {
           
-         // Compute local track parameters including "hitForRec" using kalman filter
-          addChi2TrackAtHit = RunKalmanFilter(trackParamAtHit);
+         // Compute local track parameters including current cluster using kalman filter
+          addChi2TrackAtCluster = RunKalmanFilter(trackParamAtCluster);
           
          // keep track of the best cluster
-         if (addChi2TrackAtHit < bestAddChi2TrackAtHit) {
-           bestAddChi2TrackAtHit = addChi2TrackAtHit;
-           bestTrackParamAtHit = trackParamAtHit;
-           foundOneHit = kTRUE;
+         if (addChi2TrackAtCluster < bestAddChi2TrackAtCluster) {
+           bestAddChi2TrackAtCluster = addChi2TrackAtCluster;
+           bestTrackParamAtCluster = trackParamAtCluster;
+           foundOneCluster = kTRUE;
          }
          
        }
@@ -1003,9 +1017,9 @@ void AliMUONTrackReconstructorK::ComplementTracks()
       }
       
       // add new cluster if any
-      if (foundOneHit) {
-       UpdateTrack(*track,bestTrackParamAtHit,bestAddChi2TrackAtHit);
-       bestTrackParamAtHit.SetAloneInChamber(kFALSE);
+      if (foundOneCluster) {
+       UpdateTrack(*track,bestTrackParamAtCluster,bestAddChi2TrackAtCluster);
+       bestTrackParamAtCluster.SetAloneInChamber(kFALSE);
        trackParam->SetAloneInChamber(kFALSE);
        trackModified = kTRUE;
       }
@@ -1032,7 +1046,7 @@ void AliMUONTrackReconstructorK::ImproveTracks()
   Double_t localChi2, worstLocalChi2;
   Int_t worstChamber, previousChamber;
   AliMUONTrack *track, *nextTrack;
-  AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit, *previousTrackParam, *nextTrackParam;
+  AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster, *previousTrackParam, *nextTrackParam;
   Bool_t smoothed;
   Double_t sigmaCut2 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement() *
                        AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement();
@@ -1056,30 +1070,30 @@ void AliMUONTrackReconstructorK::ImproveTracks()
       if (!smoothed) {
         
         // Update track parameters and covariances
-        track->UpdateCovTrackParamAtHit();
+        track->UpdateCovTrackParamAtCluster();
         
-        // Compute local chi2 of each hits
+        // Compute local chi2 of each clusters
         track->ComputeLocalChi2(kTRUE);
       }
       
-      // Look for the hit to remove
-      worstTrackParamAtHit = NULL;
+      // Look for the cluster to remove
+      worstTrackParamAtCluster = NULL;
       worstLocalChi2 = 0.;
-      trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First();
-      while (trackParamAtHit) {
+      trackParamAtCluster = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
+      while (trackParamAtCluster) {
         
-        // Pick up hit with the worst chi2
-        localChi2 = trackParamAtHit->GetLocalChi2();
+        // Pick up cluster with the worst chi2
+        localChi2 = trackParamAtCluster->GetLocalChi2();
         if (localChi2 > worstLocalChi2) {
           worstLocalChi2 = localChi2;
-          worstTrackParamAtHit = trackParamAtHit;
+          worstTrackParamAtCluster = trackParamAtCluster;
         }
         
-       trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParamAtHit);
+       trackParamAtCluster = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParamAtCluster);
       }
       
-      // Check if bad removable hit found
-      if (!worstTrackParamAtHit) {
+      // Check if bad removable cluster found
+      if (!worstTrackParamAtCluster) {
         track->SetImproved(kTRUE);
         break;
       }
@@ -1090,62 +1104,62 @@ void AliMUONTrackReconstructorK::ImproveTracks()
         break;
       }
       
-      // if the worst hit is not removable then remove the entire track
-      if (!worstTrackParamAtHit->IsRemovable() && worstTrackParamAtHit->IsAloneInChamber()) {
+      // if the worst cluster is not removable then remove the entire track
+      if (!worstTrackParamAtCluster->IsRemovable() && worstTrackParamAtCluster->IsAloneInChamber()) {
        fRecTracksPtr->Remove(track);
        fNRecTracks--;
         break;
       }
       
-      // Reset the second hit in the same station as being not removable
-      // or reset the second hit in the same chamber as being alone
-      worstChamber = worstTrackParamAtHit->GetHitForRecPtr()->GetChamberNumber();
-      previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(worstTrackParamAtHit);
-      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(worstTrackParamAtHit);
-      if (worstTrackParamAtHit->IsAloneInChamber()) { // Worst hit removable and alone in chamber
+      // Reset the second cluster in the same station as being not removable
+      // or reset the second cluster in the same chamber as being alone
+      worstChamber = worstTrackParamAtCluster->GetClusterPtr()->GetChamberId();
+      previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(worstTrackParamAtCluster);
+      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(worstTrackParamAtCluster);
+      if (worstTrackParamAtCluster->IsAloneInChamber()) { // Worst cluster removable and alone in chamber
        
        if (worstChamber%2 == 0) { // Modify flags in next chamber
          
          nextTrackParam->SetRemovable(kFALSE);
-         if (!nextTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore
-           ((AliMUONTrackParam*) track->GetTrackParamAtHit()->After(nextTrackParam))->SetRemovable(kFALSE);
+         if (!nextTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore
+           ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(nextTrackParam))->SetRemovable(kFALSE);
          
        } else { // Modify flags in previous chamber
          
          previousTrackParam->SetRemovable(kFALSE);
-         if (!previousTrackParam->IsAloneInChamber()) // Make sure both hits in second chamber are not removable anymore
-           ((AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(previousTrackParam))->SetRemovable(kFALSE);
+         if (!previousTrackParam->IsAloneInChamber()) // Make sure both clusters in second chamber are not removable anymore
+           ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->Before(previousTrackParam))->SetRemovable(kFALSE);
          
        }
        
-      } else { // Worst hit not alone in its chamber
+      } else { // Worst cluster not alone in its chamber
         
-       if (previousTrackParam) previousChamber = previousTrackParam->GetHitForRecPtr()->GetChamberNumber();
+       if (previousTrackParam) previousChamber = previousTrackParam->GetClusterPtr()->GetChamberId();
        else previousChamber = -1;
        
-       if (previousChamber == worstChamber) { // the second hit on the same chamber is the previous one
+       if (previousChamber == worstChamber) { // the second cluster on the same chamber is the previous one
          
          previousTrackParam->SetAloneInChamber(kTRUE);
-         // transfert the removability to the second hit
-         if (worstTrackParamAtHit->IsRemovable()) previousTrackParam->SetRemovable(kTRUE);
+         // transfert the removability to the second cluster
+         if (worstTrackParamAtCluster->IsRemovable()) previousTrackParam->SetRemovable(kTRUE);
          
-       } else { // the second hit on the same chamber is the next one
+       } else { // the second cluster on the same chamber is the next one
          
          nextTrackParam->SetAloneInChamber(kTRUE);
-         // transfert the removability to the second hit
-         if (worstTrackParamAtHit->IsRemovable()) nextTrackParam->SetRemovable(kTRUE);
+         // transfert the removability to the second cluster
+         if (worstTrackParamAtCluster->IsRemovable()) nextTrackParam->SetRemovable(kTRUE);
          
        }
        
       }
       
-      // Remove the worst hit
-      track->RemoveTrackParamAtHit(worstTrackParamAtHit);
+      // Remove the worst cluster
+      track->RemoveTrackParamAtCluster(worstTrackParamAtCluster);
       
       // Re-calculate track parameters
-      // - from the hit immediately downstream the one suppressed
+      // - from the cluster immediately downstream the one suppressed
       // - or from the begining - if parameters have been re-computed using the standard method (kalman parameters have been lost)
-      //                       - or if the removed hit was the last one
+      //                       - or if the removed cluster was the last one
       if (smoothed && nextTrackParam) RetracePartialTrack(*track,nextTrackParam);
       else RetraceTrack(*track,kTRUE);
       
@@ -1167,10 +1181,10 @@ void AliMUONTrackReconstructorK::ImproveTracks()
   //__________________________________________________________________________
 void AliMUONTrackReconstructorK::Finalize()
 {
-  /// Fill AliMUONTrack's fHitForRecAtHit array
+  /// Update track parameters and covariances at each attached cluster
   
   AliMUONTrack *track;
-  AliMUONTrackParam *trackParamAtHit;
+  AliMUONTrackParam *trackParamAtCluster;
   Bool_t smoothed = kFALSE;
   
   track = (AliMUONTrack*) fRecTracksPtr->First();
@@ -1180,26 +1194,24 @@ void AliMUONTrackReconstructorK::Finalize()
     if (!track->IsImproved()) {
       smoothed = kFALSE;
       if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) smoothed = RunSmoother(*track);
-      if (!smoothed) track->UpdateCovTrackParamAtHit();
+      if (!smoothed) track->UpdateCovTrackParamAtCluster();
     }
     
-    trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->First());
-    while (trackParamAtHit) {
+    // copy smoothed parameters and covariances if any
+    if (smoothed) {
       
-      // copy smoothed parameters and covariances if any
-      if (smoothed) {
-        trackParamAtHit->SetParameters(trackParamAtHit->GetSmoothParameters());
-        trackParamAtHit->SetCovariances(trackParamAtHit->GetSmoothCovariances());
+      trackParamAtCluster = (AliMUONTrackParam*) (track->GetTrackParamAtCluster()->First());
+      while (trackParamAtCluster) {
+       
+       trackParamAtCluster->SetParameters(trackParamAtCluster->GetSmoothParameters());
+       trackParamAtCluster->SetCovariances(trackParamAtCluster->GetSmoothCovariances());
+       
+       trackParamAtCluster = (AliMUONTrackParam*) (track->GetTrackParamAtCluster()->After(trackParamAtCluster));
       }
       
-      // update array of track hits
-      track->AddHitForRecAtHit(trackParamAtHit->GetHitForRecPtr());
-      
-      trackParamAtHit = (AliMUONTrackParam*) (track->GetTrackParamAtHit()->After(trackParamAtHit));
     }
     
     track = (AliMUONTrack*) fRecTracksPtr->After(track);
-    
   }
     
 }
index bf1492f..cb507a2 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "AliMUONVTrackReconstructor.h"
 
+class AliMUONVClusterStore;
 class AliMUONTrack;
 class AliMUONTrackParam;
 
@@ -26,9 +27,9 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor
  protected:
 
   // Functions
-  virtual void MakeTrackCandidates();
-  virtual void FollowTracks();
-  virtual void ComplementTracks();
+  virtual void MakeTrackCandidates(const AliMUONVClusterStore& clusterStore);
+  virtual void FollowTracks(const AliMUONVClusterStore& clusterStore);
+  virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
   virtual void ImproveTracks();
   virtual void Finalize();
   
@@ -43,15 +44,15 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor
   void RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed);
   void RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam);
   
-  Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation);
+  Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore, Int_t nextStation);
   
-  Double_t RunKalmanFilter(AliMUONTrackParam &trackParamAtHit);
+  Double_t RunKalmanFilter(AliMUONTrackParam &trackParamAtCluster);
 
-  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit, Double_t addChi2);
-  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtHit1, AliMUONTrackParam &trackParamAtHit2,
-                  Double_t addChi2AtHit1, Double_t addChi2AtHit2);
+  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster, Double_t addChi2);
+  void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster1, AliMUONTrackParam &trackParamAtCluster2,
+                  Double_t addChi2AtCluster1, Double_t addChi2AtCluster2);
   
-  Bool_t RecoverTrack(AliMUONTrack &track, Int_t nextStation);
+  Bool_t RecoverTrack(AliMUONTrack &track, const AliMUONVClusterStore& clusterStore, Int_t nextStation);
   
   Bool_t RunSmoother(AliMUONTrack &track);
 
index d54051a..ffd551b 100644 (file)
 /// reconstruct tracks from recpoints
 ///
 /// Actual tracking is performed by some AliMUONVTrackReconstructor children
+/// Tracking modes (ORIGINAL, KALMAN) and associated options and parameters
+/// can be changed by using:
+/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam();
+/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details
+/// AliMUONReconstructor::SetRecoParam(muonRecoParam);
 ///
 /// \author Christian Finck and Laurent Aphecetche, SUBATECH Nantes
 //-----------------------------------------------------------------------------
@@ -34,7 +39,7 @@
 #include "AliMUONTrackExtrap.h"
 #include "AliMUONTrackHitPattern.h"
 #include "AliMUONTrackParam.h"
-#include "AliMUONHitForRec.h"
+#include "AliMUONVCluster.h"
 #include "AliMUONTrackReconstructor.h"
 #include "AliMUONTrackReconstructorK.h"
 #include "AliMUONTrackStoreV1.h"
@@ -200,7 +205,7 @@ void AliMUONTracker::FillESD(AliMUONVTrackStore& trackStore, AliESDEvent* esd) c
   
   while ( ( track = static_cast<AliMUONTrack*>(next()) ) )
   {
-    AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>((track->GetTrackParamAtHit())->First());
+    AliMUONTrackParam* trackParam = static_cast<AliMUONTrackParam*>((track->GetTrackParamAtCluster())->First());
     AliMUONTrackParam trackParamAtVtx(*trackParam);
     
     /// Extrapolate to vertex (which is set to (0,0,0) if not available, see above)
@@ -214,16 +219,15 @@ void AliMUONTracker::FillESD(AliMUONVTrackStore& trackStore, AliESDEvent* esd) c
     // at vertex
     trackParamAtVtx.SetParamFor(esdTrack);
     // global info
-    esdTrack.SetChi2(track->GetFitFMin());
-    esdTrack.SetNHit(track->GetNTrackHits());
+    esdTrack.SetChi2(track->GetGlobalChi2());
+    esdTrack.SetNHit(track->GetNClusters());
     esdTrack.SetLocalTrigger(track->GetLocalTrigger());
     esdTrack.SetChi2MatchTrigger(track->GetChi2MatchTrigger());
     esdTrack.SetHitsPatternInTrigCh(track->GetHitsPatternInTrigCh());
     // muon cluster map
-    AliMUONHitForRec* cluster = static_cast<AliMUONHitForRec*>((track->GetHitForRecAtHit())->First());
-    while (cluster) {
-      esdTrack.AddInMuonClusterMap(cluster->GetChamberNumber());
-      cluster = static_cast<AliMUONHitForRec*>((track->GetHitForRecAtHit())->After(cluster));
+    while (trackParam) {
+      esdTrack.AddInMuonClusterMap(trackParam->GetClusterPtr()->GetChamberId());
+      trackParam = static_cast<AliMUONTrackParam*>(track->GetTrackParamAtCluster()->After(trackParam));
     }
     
     // storing ESD MUON Track into ESD Event 
index 241f7c3..4088bfb 100644 (file)
@@ -899,7 +899,7 @@ Bool_t AliMUONTriggerChamberEff::IsCleanTrack(AliMUONTriggerTrack *triggerTrack,
     
     while ( ( track = static_cast<AliMUONTrack*>(next()) ) )
     {
-       trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last()));
+       trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last()));
        AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber
     
        xTrack = trackParam.GetNonBendingCoor();
index 464ec39..3d2b7a0 100644 (file)
@@ -23,6 +23,9 @@ class AliMUONVCluster : public TObject {
   
            /// Clear method (used by TClonesArray)
   virtual void Clear(Option_t*) = 0;
+
+           /// Create a copy of the current cluster
+  virtual AliMUONVCluster* CreateCopy() const = 0;
   
            /// Set coordinates (cm)
   virtual void     SetXYZ(Double_t x, Double_t y, Double_t z) = 0;
index 682733d..5adaaf7 100644 (file)
 /// \class AliMUONVTrackReconstructor
 /// Virtual MUON track reconstructor in ALICE (class renamed from AliMUONEventReconstructor)
 ///
-/// This class contains as data:
-/// * a pointer to the array of hits to be reconstructed (the event)
-/// * a pointer to the array of reconstructed tracks
+/// This class contains as data a pointer to the array of reconstructed tracks
 ///
 /// It contains as methods, among others:
 /// * EventReconstruct to build the muon tracks
 /// * EventReconstructTrigger to build the trigger tracks
+/// * ValidateTracksWithTrigger to match tracker/trigger tracks
 ///
-/// Several options and adjustable parameters are available for both Kalman and Original
-/// tracking algorithms (hard coded for the moment in AliMUONVTrackReconstructor.cxx):
+/// Several options and adjustable parameters are available for both KALMAN and ORIGINAL
+/// tracking algorithms. They can be changed by using:
+/// AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetLow(High)FluxParam();
+/// muonRecoParam->Set...(); // see methods in AliMUONRecoParam.h for details
+/// AliMUONReconstructor::SetRecoParam(muonRecoParam);
+///
+/// Main parameters and options are:
 /// - *fgkSigmaToCutForTracking* : quality cut used to select new clusters to be
 ///   attached to the track candidate and to select good tracks.
 /// - *fgkMakeTrackCandidatesFast* : if this flag is set to 'true', the track candidates
@@ -55,7 +59,6 @@
 #include "AliMUONVTrackReconstructor.h"
 
 #include "AliMUONConstants.h"
-#include "AliMUONHitForRec.h"
 #include "AliMUONObjectPair.h"
 #include "AliMUONTriggerTrack.h"
 #include "AliMUONTriggerCircuit.h"
@@ -89,23 +92,13 @@ ClassImp(AliMUONVTrackReconstructor) // Class implementation in ROOT context
   //__________________________________________________________________________
 AliMUONVTrackReconstructor::AliMUONVTrackReconstructor()
   : TObject(),
-    fHitsForRecPtr(0x0),
-    fNHitsForRec(0),
-    fNHitsForRecPerChamber(0x0),
-    fIndexOfFirstHitForRecPerChamber(0x0),
     fRecTracksPtr(0x0),
     fNRecTracks(0)
 {
   /// Constructor for class AliMUONVTrackReconstructor
-  fNHitsForRecPerChamber = new Int_t[AliMUONConstants::NTrackingCh()];
-  fIndexOfFirstHitForRecPerChamber = new Int_t[AliMUONConstants::NTrackingCh()];
-
-  // Memory allocation for the TClonesArray of hits for reconstruction
-  // Is 10000 the right size ????
-  fHitsForRecPtr = new TClonesArray("AliMUONHitForRec", 10000);
   
   // Memory allocation for the TClonesArray of reconstructed tracks
-  fRecTracksPtr = new TClonesArray("AliMUONTrack", 10);
+  fRecTracksPtr = new TClonesArray("AliMUONTrack", 100);
   
   // set the magnetic field for track extrapolations
   const AliMagF* kField = AliTracker::GetFieldMap();
@@ -117,26 +110,10 @@ AliMUONVTrackReconstructor::AliMUONVTrackReconstructor()
 AliMUONVTrackReconstructor::~AliMUONVTrackReconstructor()
 {
   /// Destructor for class AliMUONVTrackReconstructor
-  delete [] fNHitsForRecPerChamber;
-  delete [] fIndexOfFirstHitForRecPerChamber;
-  delete fHitsForRecPtr;
   delete fRecTracksPtr;
 }
 
   //__________________________________________________________________________
-void AliMUONVTrackReconstructor::ResetHitsForRec()
-{
-  /// To reset the TClonesArray of HitsForRec,
-  /// and the number of HitForRec and the index of the first HitForRec per chamber
-  if (fHitsForRecPtr) fHitsForRecPtr->Clear("C");
-  fNHitsForRec = 0;
-  for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) {
-    fNHitsForRecPerChamber[ch] = 0;
-    fIndexOfFirstHitForRecPerChamber[ch] = 0;
-  }
-}
-
-  //__________________________________________________________________________
 void AliMUONVTrackReconstructor::ResetTracks()
 {
   /// To reset the TClonesArray of reconstructed tracks
@@ -152,189 +129,104 @@ void AliMUONVTrackReconstructor::EventReconstruct(const AliMUONVClusterStore& cl
   AliDebug(1,"");
   AliCodeTimerAuto("");
   
+  // Reset array of tracks
   ResetTracks();
-  ResetHitsForRec();
-  AddHitsForRecFromRawClusters(clusterStore);
-  MakeTracks();
-
-  // Add tracks to MUON data container 
-  for (Int_t i=0; i<fNRecTracks; ++i) 
-  {
-    AliMUONTrack * track = (AliMUONTrack*) fRecTracksPtr->At(i);
-    trackStore.Add(*track);
-  }
-}
-
-  //__________________________________________________________________________
-void AliMUONVTrackReconstructor::AddHitsForRecFromRawClusters(const AliMUONVClusterStore& clusterStore)
-{
-  /// Build internal array of hit for rec from clusterStore
-  
-  AliMUONVCluster* clus(0x0);
-  Int_t iclus(0);
   
-  TIter next(clusterStore.CreateIterator());
-  
-  while ( ( clus = static_cast<AliMUONVCluster*>(next()) ) )
-  {
-    // new AliMUONHitForRec from raw cluster
-    // and increment number of AliMUONHitForRec's (total and in chamber)
-    AliMUONHitForRec* hitForRec = new ((*fHitsForRecPtr)[fNHitsForRec]) AliMUONHitForRec(clus);
-    fNHitsForRec++;
-    // more information into HitForRec
-    hitForRec->SetNonBendingReso2(clus->GetErrX2());
-    hitForRec->SetBendingReso2(clus->GetErrY2());
-    //  original raw cluster
-    Int_t ch = AliMpDEManager::GetChamberId(clus->GetDetElemId());
-    hitForRec->SetChamberNumber(ch);
-    hitForRec->SetHitNumber(iclus);
-    // Z coordinate of the raw cluster (cm)
-    hitForRec->SetZ(clus->GetZ());
-    if (AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 3) {
-      cout << "Chamber " << ch <<" raw cluster  " << iclus << " : " << endl;
-      clus->Print("full");
-      cout << "AliMUONHitForRec number (1...): " << fNHitsForRec << endl;
-      hitForRec->Print("full");
-    }
-    ++iclus;
-  } // end of chamber loop
-  
-  SortHitsForRecWithIncreasingChamber(); 
-  
-  AliDebug(1,"End of AddHitsForRecFromRawClusters");
-  
-  if (AliLog::GetGlobalDebugLevel() > 0) 
-  {
-    AliDebug(1, Form("NHitsForRec: %d",fNHitsForRec));
-    for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) 
-    {
-      AliDebug(1, Form("Chamber(0...): %d",ch));
-      AliDebug(1, Form("NHitsForRec: %d", fNHitsForRecPerChamber[ch]));
-      AliDebug(1, Form("Index(first HitForRec): %d", fIndexOfFirstHitForRecPerChamber[ch]));
-      for (Int_t hit = fIndexOfFirstHitForRecPerChamber[ch];
-           hit < fIndexOfFirstHitForRecPerChamber[ch] + fNHitsForRecPerChamber[ch];
-           hit++) {
-        AliDebug(1, Form("HitForRec index(0...): %d",hit));
-        ((*fHitsForRecPtr)[hit])->Dump();
-      }
-    }
-  }
-}
-
-  //__________________________________________________________________________
-void AliMUONVTrackReconstructor::SortHitsForRecWithIncreasingChamber()
-{
-  /// Sort HitsForRec's in increasing order with respect to chamber number.
-  /// Uses the function "Compare".
-  /// Update the information for HitsForRec per chamber too.
-  Int_t ch, nhits, prevch;
-  fHitsForRecPtr->Sort();
-  for (ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) {
-    fNHitsForRecPerChamber[ch] = 0;
-    fIndexOfFirstHitForRecPerChamber[ch] = 0;
-  }
-  prevch = 0; // previous chamber
-  nhits = 0; // number of hits in current chamber
-  // Loop over HitsForRec
-  for (Int_t hit = 0; hit < fNHitsForRec; hit++) {
-    // chamber number (0...)
-    ch = ((AliMUONHitForRec*)  ((*fHitsForRecPtr)[hit]))->GetChamberNumber();
-    // increment number of hits in current chamber
-    (fNHitsForRecPerChamber[ch])++;
-    // update index of first HitForRec in current chamber
-    // if chamber number different from previous one
-    if (ch != prevch) {
-      fIndexOfFirstHitForRecPerChamber[ch] = hit;
-      prevch = ch;
-    }
-  }
-  return;
-}
-
-  //__________________________________________________________________________
-void AliMUONVTrackReconstructor::MakeTracks()
-{
-  /// To make the tracks from the list of segments and points in all stations
-  AliDebug(1,"Enter MakeTracks");
   // Look for candidates from at least 3 aligned points in stations(1..) 4 and 5
-  MakeTrackCandidates();
+  MakeTrackCandidates(clusterStore);
+  
+  // Stop tracking if no candidate found
   if (fRecTracksPtr->GetEntriesFast() == 0) return;
+  
   // Follow tracks in stations(1..) 3, 2 and 1
-  FollowTracks();
+  FollowTracks(clusterStore);
+  
   // Complement the reconstructed tracks
-  if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) ComplementTracks();
+  if (AliMUONReconstructor::GetRecoParam()->ComplementTracks()) ComplementTracks(clusterStore);
+  
   // Improve the reconstructed tracks
   if (AliMUONReconstructor::GetRecoParam()->ImproveTracks()) ImproveTracks();
+  
   // Remove double tracks
   RemoveDoubleTracks();
+  
   // Fill AliMUONTrack data members
   Finalize();
+  
+  // Add tracks to MUON data container 
+  for (Int_t i=0; i<fNRecTracks; ++i) 
+  {
+    AliMUONTrack * track = (AliMUONTrack*) fRecTracksPtr->At(i);
+    trackStore.Add(*track);
+  }
 }
 
   //__________________________________________________________________________
-TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station)
+TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(const AliMUONVClusterStore& clusterStore, Int_t station)
 {
-  /// To make the list of segments in station(0..) "Station" from the list of hits to be reconstructed.
+  /// To make the list of segments in station(0..) "Station" from the list of clusters to be reconstructed.
   /// Return a new TClonesArray of segments.
   /// It is the responsibility of the user to delete it afterward.
-  AliDebug(1,Form("Enter MakeSegmentsPerStation (0...) %d",station));
+  AliDebug(1,Form("Enter MakeSegmentsPerStation (1..) %d",station+1));
   
-  AliMUONHitForRec *hit1Ptr, *hit2Ptr;
+  AliMUONVCluster *cluster1, *cluster2;
   AliMUONObjectPair *segment;
   Double_t bendingSlope = 0, impactParam = 0., bendingMomentum = 0.; // to avoid compilation warning
-                                                                     // first and second chambers (0...) in the station
   Int_t ch1 = 2 * station;
   Int_t ch2 = ch1 + 1;
   
+  // Create iterators to loop over clusters in both chambers
+  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
+  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
+  
   // list of segments
-  TClonesArray *segments = new TClonesArray("AliMUONObjectPair", fNHitsForRecPerChamber[ch2]);
+  TClonesArray *segments = new TClonesArray("AliMUONObjectPair", 100);
   segments->SetOwner(kTRUE);
   
-  // Loop over HitForRec's in the first chamber of the station
-  for (Int_t hit1 = fIndexOfFirstHitForRecPerChamber[ch1];
-       hit1 < fIndexOfFirstHitForRecPerChamber[ch1] + fNHitsForRecPerChamber[ch1];
-       hit1++) 
-  {
-    // pointer to the HitForRec
-    hit1Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit1]);
-    // Loop over HitsForRec's in the second chamber of the station
-    for (Int_t hit2 = fIndexOfFirstHitForRecPerChamber[ch2];
-         hit2 < fIndexOfFirstHitForRecPerChamber[ch2] + fNHitsForRecPerChamber[ch2];
-         hit2++) 
-    {
-      // pointer to the HitForRec
-      hit2Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit2]);
-      if ( hit1Ptr->GetZ() - hit2Ptr->GetZ() != 0. ) 
-      {
-        // bending slope
-        bendingSlope = (hit1Ptr->GetBendingCoor() - hit2Ptr->GetBendingCoor()) / (hit1Ptr->GetZ() - hit2Ptr->GetZ());
-        // impact parameter
-        impactParam = hit1Ptr->GetBendingCoor() - hit1Ptr->GetZ() * bendingSlope;
-        // absolute value of bending momentum
-        bendingMomentum = TMath::Abs(AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(impactParam));
-      } else 
-      {
-        AliWarning("hit1Ptr->GetZ() = hit2Ptr->GetZ(): no segment created");
-        continue;
-      }   
+  // Loop over clusters in the first chamber of the station
+  while ( ( cluster1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+    
+    // reset cluster iterator of chamber 2
+    nextInCh2.Reset();
+    
+    // Loop over clusters in the second chamber of the station
+    while ( ( cluster2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
+      
+      // bending slope
+      bendingSlope = (cluster1->GetY() - cluster2->GetY()) / (cluster1->GetZ() - cluster2->GetZ());
+      
+      // impact parameter
+      impactParam = cluster1->GetY() - cluster1->GetZ() * bendingSlope;
+     
+      // absolute value of bending momentum
+      bendingMomentum = TMath::Abs(AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(impactParam));
+      
       // check for bending momentum within tolerances
       if ((bendingMomentum < AliMUONReconstructor::GetRecoParam()->GetMaxBendingMomentum()) &&
-         (bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum())) 
-      {
-        // make new segment
-        segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(hit1Ptr, hit2Ptr, kFALSE, kFALSE);
-        if (AliLog::GetGlobalDebugLevel() > 1) {
+         (bendingMomentum > AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum())) {
+        
+       // make new segment
+        segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(cluster1, cluster2, kFALSE, kFALSE);
+        
+       // Printout for debug
+       if (AliLog::GetGlobalDebugLevel() > 1) {
           cout << "segmentIndex(0...): " << segments->GetLast() << endl;
           segment->Dump();
-          cout << "HitForRec in first chamber" << endl;
-          hit1Ptr->Dump();
-          cout << "HitForRec in second chamber" << endl;
-          hit2Ptr->Dump();
+          cout << "Cluster in first chamber" << endl;
+          cluster1->Print();
+          cout << "Cluster in second chamber" << endl;
+          cluster2->Print();
         }
+       
       }
-    } //for (Int_t hit2
-  } // for (Int_t hit1...
-  AliDebug(1,Form("Station: %d  NSegments:  %d ", station, segments->GetEntriesFast()));
+      
+    }
+    
+  }
+  
+  // Printout for debug
+  AliDebug(1,Form("Station: %d  NSegments:  %d ", station+1, segments->GetEntriesFast()));
+  
   return segments;
 }
 
@@ -342,26 +234,26 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsInStation(Int_t station)
 void AliMUONVTrackReconstructor::RemoveIdenticalTracks()
 {
   /// To remove identical tracks:
-  /// Tracks are considered identical if they have all their hits in common.
-  /// One keeps the track with the larger number of hits if need be
+  /// Tracks are considered identical if they have all their clusters in common.
+  /// One keeps the track with the larger number of clusters if need be
   AliMUONTrack *track1, *track2, *trackToRemove;
-  Int_t hitsInCommon, nHits1, nHits2;
+  Int_t clustersInCommon, nClusters1, nClusters2;
   Bool_t removedTrack1;
   // Loop over first track of the pair
   track1 = (AliMUONTrack*) fRecTracksPtr->First();
   while (track1) {
     removedTrack1 = kFALSE;
-    nHits1 = track1->GetNTrackHits();
+    nClusters1 = track1->GetNClusters();
     // Loop over second track of the pair
     track2 = (AliMUONTrack*) fRecTracksPtr->After(track1);
     while (track2) {
-      nHits2 = track2->GetNTrackHits();
-      // number of hits in common between two tracks
-      hitsInCommon = track1->HitsInCommon(track2);
+      nClusters2 = track2->GetNClusters();
+      // number of clusters in common between two tracks
+      clustersInCommon = track1->ClustersInCommon(track2);
       // check for identical tracks
-      if ((hitsInCommon == nHits1) || (hitsInCommon == nHits2)) {
+      if ((clustersInCommon == nClusters1) || (clustersInCommon == nClusters2)) {
         // decide which track to remove
-        if (nHits2 > nHits1) {
+        if (nClusters2 > nClusters1) {
          // remove track1 and continue the first loop with the track next to track1
          trackToRemove = track1;
          track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
@@ -390,28 +282,28 @@ void AliMUONVTrackReconstructor::RemoveIdenticalTracks()
 void AliMUONVTrackReconstructor::RemoveDoubleTracks()
 {
   /// To remove double tracks:
-  /// Tracks are considered identical if more than half of the hits of the track
-  /// which has the smaller number of hits are in common with the other track.
-  /// Among two identical tracks, one keeps the track with the larger number of hits
+  /// Tracks are considered identical if more than half of the clusters of the track
+  /// which has the smaller number of clusters are in common with the other track.
+  /// Among two identical tracks, one keeps the track with the larger number of clusters
   /// or, if these numbers are equal, the track with the minimum chi2.
   AliMUONTrack *track1, *track2, *trackToRemove;
-  Int_t hitsInCommon, nHits1, nHits2;
+  Int_t clustersInCommon, nClusters1, nClusters2;
   Bool_t removedTrack1;
   // Loop over first track of the pair
   track1 = (AliMUONTrack*) fRecTracksPtr->First();
   while (track1) {
     removedTrack1 = kFALSE;
-    nHits1 = track1->GetNTrackHits();
+    nClusters1 = track1->GetNClusters();
     // Loop over second track of the pair
     track2 = (AliMUONTrack*) fRecTracksPtr->After(track1);
     while (track2) {
-      nHits2 = track2->GetNTrackHits();
-      // number of hits in common between two tracks
-      hitsInCommon = track1->HitsInCommon(track2);
+      nClusters2 = track2->GetNClusters();
+      // number of clusters in common between two tracks
+      clustersInCommon = track1->ClustersInCommon(track2);
       // check for identical tracks
-      if (((nHits1 < nHits2) && (2 * hitsInCommon > nHits1)) || (2 * hitsInCommon > nHits2)) {
+      if (((nClusters1 < nClusters2) && (2 * clustersInCommon > nClusters1)) || (2 * clustersInCommon > nClusters2)) {
         // decide which track to remove
-        if ((nHits1 > nHits2) || ((nHits1 == nHits2) && (track1->GetFitFMin() <= track2->GetFitFMin()))) {
+        if ((nClusters1 > nClusters2) || ((nClusters1 == nClusters2) && (track1->GetGlobalChi2() <= track2->GetGlobalChi2()))) {
          // remove track2 and continue the second loop with the track next to track2
          trackToRemove = track2;
          track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
@@ -437,44 +329,44 @@ void AliMUONVTrackReconstructor::RemoveDoubleTracks()
 }
 
   //__________________________________________________________________________
-Double_t AliMUONVTrackReconstructor::TryOneHitForRec(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec,
-                                                    AliMUONTrackParam &trackParamAtHit, Bool_t updatePropagator)
+Double_t AliMUONVTrackReconstructor::TryOneCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster,
+                                                    AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator)
 {
-/// Test the compatibility between the track and the hitForRec (using trackParam's covariance matrix):
+/// Test the compatibility between the track and the cluster (using trackParam's covariance matrix):
 /// return the corresponding Chi2
-/// return trackParamAtHit
+/// return trackParamAtCluster
   
-  // extrapolate track parameters and covariances at the z position of the tested hit
-  trackParamAtHit = trackParam;
-  AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtHit, hitForRec->GetZ(), updatePropagator);
+  // extrapolate track parameters and covariances at the z position of the tested cluster
+  trackParamAtCluster = trackParam;
+  AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtCluster, cluster->GetZ(), updatePropagator);
   
-  // set pointer to hit into trackParamAtHit
-  trackParamAtHit.SetHitForRecPtr(hitForRec);
+  // set pointer to cluster into trackParamAtCluster
+  trackParamAtCluster.SetClusterPtr(cluster);
   
-  // Set differences between trackParam and hitForRec in the bending and non bending directions
-  Double_t dX = hitForRec->GetNonBendingCoor() - trackParamAtHit.GetNonBendingCoor();
-  Double_t dY = hitForRec->GetBendingCoor() - trackParamAtHit.GetBendingCoor();
+  // Set differences between trackParam and cluster in the bending and non bending directions
+  Double_t dX = cluster->GetX() - trackParamAtCluster.GetNonBendingCoor();
+  Double_t dY = cluster->GetY() - trackParamAtCluster.GetBendingCoor();
   
   // Calculate errors and covariances
-  const TMatrixD& kParamCov = trackParamAtHit.GetCovariances();
-  Double_t sigma2X = kParamCov(0,0) + hitForRec->GetNonBendingReso2();
-  Double_t sigma2Y = kParamCov(2,2) + hitForRec->GetBendingReso2();
+  const TMatrixD& kParamCov = trackParamAtCluster.GetCovariances();
+  Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2();
+  Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2();
   
   // Compute chi2
-  return dX * dX / sigma2X + dY * dY / sigma2Y;
+  return dX * dX / sigmaX2 + dY * dY / sigmaY2;
   
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONVTrackReconstructor::TryOneHitForRecFast(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec)
+Bool_t AliMUONVTrackReconstructor::TryOneClusterFast(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster)
 {
-/// Test the compatibility between the track and the hitForRec within a wide fix window
+/// Test the compatibility between the track and the cluster within a wide fix window
 /// assuming linear propagation of the track:
 /// return kTRUE if they are compatibles
   
-  Double_t dZ = hitForRec->GetZ() - trackParam.GetZ();
-  Double_t dX = hitForRec->GetNonBendingCoor() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ);
-  Double_t dY = hitForRec->GetBendingCoor() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ);
+  Double_t dZ = cluster->GetZ() - trackParam.GetZ();
+  Double_t dX = cluster->GetX() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ);
+  Double_t dY = cluster->GetY() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ);
   
   if (TMath::Abs(dX) > AliMUONReconstructor::GetRecoParam()->GetMaxNonBendingDistanceToTrack() ||
       TMath::Abs(dY) > AliMUONReconstructor::GetRecoParam()->GetMaxBendingDistanceToTrack()) return kFALSE;
@@ -484,37 +376,37 @@ Bool_t AliMUONVTrackReconstructor::TryOneHitForRecFast(const AliMUONTrackParam &
 }
 
   //__________________________________________________________________________
-Double_t AliMUONVTrackReconstructor::TryTwoHitForRecFast(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2,
-                                                        AliMUONTrackParam &trackParamAtHit2)
+Double_t AliMUONVTrackReconstructor::TryTwoClustersFast(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2,
+                                                       AliMUONTrackParam &trackParamAtCluster2)
 {
-/// Test the compatibility between the track and the 2 hitForRec together (using trackParam's covariance matrix)
-/// assuming linear propagation between the two hits:
-/// return the corresponding Chi2 accounting for covariances between the 2 hitForRec
-/// return trackParamAtHit1 & 2
+/// Test the compatibility between the track and the 2 clusters together (using trackParam's covariance matrix)
+/// assuming linear propagation between the two clusters:
+/// return the corresponding Chi2 accounting for covariances between the 2 clusters
+/// return trackParamAtCluster2
   
-  // extrapolate linearly track parameters at the z position of the second hit
-  trackParamAtHit2 = trackParamAtHit1;
-  AliMUONTrackExtrap::LinearExtrapToZ(&trackParamAtHit2, hitForRec2->GetZ());
+  // extrapolate linearly track parameters and covariances at the z position of the second cluster
+  trackParamAtCluster2 = trackParamAtCluster1;
+  AliMUONTrackExtrap::LinearExtrapToZ(&trackParamAtCluster2, cluster2->GetZ());
   
-  // set pointer to hit2 into trackParamAtHit2
-  trackParamAtHit2.SetHitForRecPtr(hitForRec2);
+  // set pointer to cluster2 into trackParamAtCluster2
+  trackParamAtCluster2.SetClusterPtr(cluster2);
   
-  // Set differences between track and hitForRec in the bending and non bending directions
-  AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr();
-  Double_t dX1 = hitForRec1->GetNonBendingCoor() - trackParamAtHit1.GetNonBendingCoor();
-  Double_t dX2 = hitForRec2->GetNonBendingCoor() - trackParamAtHit2.GetNonBendingCoor();
-  Double_t dY1 = hitForRec1->GetBendingCoor() - trackParamAtHit1.GetBendingCoor();
-  Double_t dY2 = hitForRec2->GetBendingCoor() - trackParamAtHit2.GetBendingCoor();
+  // Set differences between track and clusters in the bending and non bending directions
+  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
+  Double_t dX1 = cluster1->GetX() - trackParamAtCluster1.GetNonBendingCoor();
+  Double_t dX2 = cluster2->GetX() - trackParamAtCluster2.GetNonBendingCoor();
+  Double_t dY1 = cluster1->GetY() - trackParamAtCluster1.GetBendingCoor();
+  Double_t dY2 = cluster2->GetY() - trackParamAtCluster2.GetBendingCoor();
   
   // Calculate errors and covariances
-  const TMatrixD& kParamCov1 = trackParamAtHit1.GetCovariances();
-  const TMatrixD& kParamCov2 = trackParamAtHit2.GetCovariances();
-  Double_t dZ = trackParamAtHit2.GetZ() - trackParamAtHit1.GetZ();
-  Double_t sigma2X1 = kParamCov1(0,0) + hitForRec1->GetNonBendingReso2();
-  Double_t sigma2X2 = kParamCov2(0,0) + hitForRec2->GetNonBendingReso2();
+  const TMatrixD& kParamCov1 = trackParamAtCluster1.GetCovariances();
+  const TMatrixD& kParamCov2 = trackParamAtCluster2.GetCovariances();
+  Double_t dZ = trackParamAtCluster2.GetZ() - trackParamAtCluster1.GetZ();
+  Double_t sigma2X1 = kParamCov1(0,0) + cluster1->GetErrX2();
+  Double_t sigma2X2 = kParamCov2(0,0) + cluster2->GetErrX2();
   Double_t covX1X2  = kParamCov1(0,0) + dZ * kParamCov1(0,1);
-  Double_t sigma2Y1 = kParamCov1(2,2) + hitForRec1->GetBendingReso2();
-  Double_t sigma2Y2 = kParamCov2(2,2) + hitForRec2->GetBendingReso2();
+  Double_t sigma2Y1 = kParamCov1(2,2) + cluster1->GetErrY2();
+  Double_t sigma2Y2 = kParamCov2(2,2) + cluster2->GetErrY2();
   Double_t covY1Y2  = kParamCov1(2,2) + dZ * kParamCov1(2,3);
   
   // Compute chi2
@@ -527,15 +419,16 @@ Double_t AliMUONVTrackReconstructor::TryTwoHitForRecFast(const AliMUONTrackParam
 }
 
   //__________________________________________________________________________
-Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation)
+Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore,
+                                                             Int_t nextStation)
 {
-  /// Follow trackCandidate in station(0..) nextStation assuming linear propagation, and search for compatible HitForRec(s)
+  /// Follow trackCandidate in station(0..) nextStation assuming linear propagation, and search for compatible cluster(s)
   /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
   /// kTRUE:  duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
   ///         fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
   ///         Remove the obsolete "trackCandidate" at the end.
-  /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority.
-  /// return kTRUE if new hits have been found (otherwise return kFALSE)
+  /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority.
+  /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE)
   AliDebug(1,Form("Enter FollowLinearTrackInStation(1..) %d", nextStation+1));
   
   // Order the chamber according to the propagation direction (tracking starts with chamber 2):
@@ -550,136 +443,145 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
     ch2 = 2*nextStation+1;
   }
   
-  Double_t chi2WithOneHitForRec = 1.e10;
-  Double_t chi2WithTwoHitForRec = 1.e10;
-  Double_t maxChi2WithOneHitForRec = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
-                                          AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
-  Double_t maxChi2WithTwoHitForRec = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
-                                         AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2
-  Double_t bestChi2WithOneHitForRec = maxChi2WithOneHitForRec;
-  Double_t bestChi2WithTwoHitForRec = maxChi2WithTwoHitForRec;
-  Bool_t foundOneHit = kFALSE;
-  Bool_t foundTwoHits = kFALSE;
+  Double_t chi2WithOneCluster = 1.e10;
+  Double_t chi2WithTwoClusters = 1.e10;
+  Double_t maxChi2WithOneCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+                                       AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
+  Double_t maxChi2WithTwoClusters = 4. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() *
+                                        AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2
+  Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
+  Double_t bestChi2WithTwoClusters = maxChi2WithTwoClusters;
+  Bool_t foundOneCluster = kFALSE;
+  Bool_t foundTwoClusters = kFALSE;
   AliMUONTrack *newTrack = 0x0;
-  AliMUONHitForRec *hitForRecCh1, *hitForRecCh2;
-  AliMUONTrackParam extrapTrackParamAtHit1;
-  AliMUONTrackParam extrapTrackParamAtHit2;
-  AliMUONTrackParam bestTrackParamAtHit1;
-  AliMUONTrackParam bestTrackParamAtHit2;
-  Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]];
-  for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE;
+  AliMUONVCluster *clusterCh1, *clusterCh2;
+  AliMUONTrackParam extrapTrackParamAtCluster1;
+  AliMUONTrackParam extrapTrackParamAtCluster2;
+  AliMUONTrackParam bestTrackParamAtCluster1;
+  AliMUONTrackParam bestTrackParamAtCluster2;
+  
+  Int_t nClusters = clusterStore.GetSize();
+  Bool_t *clusterCh1Used = new Bool_t[nClusters];
+  for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE;
+  Int_t iCluster1;
   
   // Get track parameters
-  AliMUONTrackParam trackParam(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
+  AliMUONTrackParam trackParam(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First());
   
   // Add MCS effect
   AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-    cout << "FollowLinearTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl;
+    cout << "FollowLinearTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl;
   }
   
-  // look for candidates in chamber 2 
-  for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) {
-    
-    hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2);
+  // Create iterators to loop over clusters in both chambers
+  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
+  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
+  
+  // look for candidates in chamber 2
+  while ( ( clusterCh2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
     
-    // try to add the current hit fast
-    if (!TryOneHitForRecFast(trackParam, hitForRecCh2)) continue;
+    // try to add the current cluster fast
+    if (!TryOneClusterFast(trackParam, clusterCh2)) continue;
     
-    // try to add the current hit accuratly
-    extrapTrackParamAtHit2 = trackParam;
-    AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtHit2, hitForRecCh2->GetZ());
-    chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtHit2, hitForRecCh2, extrapTrackParamAtHit2);
+    // try to add the current cluster accuratly
+    extrapTrackParamAtCluster2 = trackParam;
+    AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtCluster2, clusterCh2->GetZ());
+    chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster2, clusterCh2, extrapTrackParamAtCluster2);
     
-    // if good chi2 then try to attach a hitForRec in the other chamber too
-    if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
-      Bool_t foundSecondHit = kFALSE;
+    // if good chi2 then try to attach a cluster in the other chamber too
+    if (chi2WithOneCluster < maxChi2WithOneCluster) {
+      Bool_t foundSecondCluster = kFALSE;
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch2+1
-            << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl;
-        cout << "                      look for second hits in chamber(1..): " << ch1+1 << " ..." << endl;
+        cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch2+1
+            << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
+        cout << "                      look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
       }
       
       // add MCS effect
-      AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtHit2,AliMUONConstants::ChamberThicknessInX0(),1.);
+      AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(),1.);
       
-      for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
-        
-       hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+      // reset cluster iterator of chamber 1
+      nextInCh1.Reset();
+      iCluster1 = -1;
+      
+      // look for second candidates in chamber 1
+      while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+        iCluster1++;
        
-        // try to add the current hit fast
-        if (!TryOneHitForRecFast(extrapTrackParamAtHit2, hitForRecCh1)) continue;
+        // try to add the current cluster fast
+        if (!TryOneClusterFast(extrapTrackParamAtCluster2, clusterCh1)) continue;
        
-       // try to add the current hit in addition to the one found on the previous chamber
-       chi2WithTwoHitForRec = TryTwoHitForRecFast(extrapTrackParamAtHit2, hitForRecCh1, extrapTrackParamAtHit1);
+       // try to add the current cluster in addition to the one found in the previous chamber
+       chi2WithTwoClusters = TryTwoClustersFast(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1);
         
-       // if good chi2 then consider to add the 2 hitForRec to the "trackCandidate"
-       if (chi2WithTwoHitForRec < maxChi2WithTwoHitForRec) {
-         foundSecondHit = kTRUE;
-         foundTwoHits = kTRUE;
+       // if good chi2 then consider to add the 2 clusters to the "trackCandidate"
+       if (chi2WithTwoClusters < maxChi2WithTwoClusters) {
+         foundSecondCluster = kTRUE;
+         foundTwoClusters = kTRUE;
           
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch1+1
-                << " (Chi2 = " << chi2WithTwoHitForRec << ")" << endl;
+           cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1
+                << " (Chi2 = " << chi2WithTwoClusters << ")" << endl;
          }
          
          if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
             newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-           extrapTrackParamAtHit1.SetRemovable(kTRUE);
-           newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit1,hitForRecCh1);
-           extrapTrackParamAtHit2.SetRemovable(kTRUE);
-           newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit2,hitForRecCh2);
-           newTrack->GetTrackParamAtHit()->Sort();
+           extrapTrackParamAtCluster1.SetRemovable(kTRUE);
+           newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
+           extrapTrackParamAtCluster2.SetRemovable(kTRUE);
+           newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
+           newTrack->GetTrackParamAtCluster()->Sort();
            fNRecTracks++;
            
-           // Tag hitForRecCh1 as used
-           hitForRecCh1Used[hit1] = kTRUE;
+           // Tag clusterCh1 as used
+           clusterCh1Used[iCluster1] = kTRUE;
            
            // Printout for debuging
            if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-             cout << "FollowLinearTrackInStation: added two hits in station(1..): " << nextStation+1 << endl;
+             cout << "FollowLinearTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl;
              if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
            }
            
-          } else if (chi2WithTwoHitForRec < bestChi2WithTwoHitForRec) {
-           // keep track of the best couple of hits
-           bestChi2WithTwoHitForRec = chi2WithTwoHitForRec;
-           bestTrackParamAtHit1 = extrapTrackParamAtHit1;
-           bestTrackParamAtHit2 = extrapTrackParamAtHit2;
+          } else if (chi2WithTwoClusters < bestChi2WithTwoClusters) {
+           // keep track of the best couple of clusters
+           bestChi2WithTwoClusters = chi2WithTwoClusters;
+           bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
+           bestTrackParamAtCluster2 = extrapTrackParamAtCluster2;
           }
          
        }
        
       }
       
-      // if no hitForRecCh1 found then consider to add hitForRecCh2 only
-      if (!foundSecondHit) {
-       foundOneHit = kTRUE;
+      // if no cluster found in chamber1 then consider to add clusterCh2 only
+      if (!foundSecondCluster) {
+       foundOneCluster = kTRUE;
         
        if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
           newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-         extrapTrackParamAtHit2.SetRemovable(kFALSE);
-         newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit2,hitForRecCh2);
-         newTrack->GetTrackParamAtHit()->Sort();
+         extrapTrackParamAtCluster2.SetRemovable(kFALSE);
+         newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
+         newTrack->GetTrackParamAtCluster()->Sort();
          fNRecTracks++;
          
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowLinearTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl;
+           cout << "FollowLinearTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl;
            if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
          }
          
-       } else if (!foundTwoHits && chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
-         // keep track of the best single hitForRec except if a couple of hits has already been found
-         bestChi2WithOneHitForRec = chi2WithOneHitForRec;
-         bestTrackParamAtHit1 = extrapTrackParamAtHit2;
+       } else if (!foundTwoClusters && chi2WithOneCluster < bestChi2WithOneCluster) {
+         // keep track of the best cluster except if a couple of clusters has already been found
+         bestChi2WithOneCluster = chi2WithOneCluster;
+         bestTrackParamAtCluster1 = extrapTrackParamAtCluster2;
         }
        
       }
@@ -689,12 +591,12 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
   }
   
   // look for candidates in chamber 1 not already attached to a track
-  // if we want to keep all possible tracks or if no good couple of hitForRec has been found
-  if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoHits) {
+  // if we want to keep all possible tracks or if no good couple of clusters has been found
+  if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
     
     // Printout for debuging
     if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-      cout << "FollowLinearTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl;
+      cout << "FollowLinearTrackInStation: look for single cluster in chamber(1..): " << ch1+1 << endl;
     }
     
     //Extrapolate trackCandidate to chamber "ch2"
@@ -703,49 +605,53 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
     // add MCS effect for next step
     AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
       
-    for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
-      
-      hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+    // reset cluster iterator of chamber 1
+    nextInCh1.Reset();
+    iCluster1 = -1;
+    
+    // look for second candidates in chamber 1
+    while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
+      iCluster1++;
       
-      if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used
+      if (clusterCh1Used[iCluster1]) continue; // Skip clusters already used
       
-      // try to add the current hit fast
-      if (!TryOneHitForRecFast(trackParam, hitForRecCh1)) continue;
+      // try to add the current cluster fast
+      if (!TryOneClusterFast(trackParam, clusterCh1)) continue;
        
-      // try to add the current hit accuratly
-      extrapTrackParamAtHit1 = trackParam;
-      AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtHit1, hitForRecCh1->GetZ());
-      chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtHit1, hitForRecCh1, extrapTrackParamAtHit1);
+      // try to add the current cluster accuratly
+      extrapTrackParamAtCluster1 = trackParam;
+      AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtCluster1, clusterCh1->GetZ());
+      chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster1, clusterCh1, extrapTrackParamAtCluster1);
     
-      // if good chi2 then consider to add hitForRecCh1
-      // We do not try to attach a hitForRec in the other chamber too since it has already been done above
-      if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
-       foundOneHit = kTRUE;
+      // if good chi2 then consider to add clusterCh1
+      // We do not try to attach a cluster in the other chamber too since it has already been done above
+      if (chi2WithOneCluster < maxChi2WithOneCluster) {
+       foundOneCluster = kTRUE;
        
        // Printout for debuging
        if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-         cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch1+1
-              << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl;
+         cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1
+              << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
        }
        
        if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
          newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
-         extrapTrackParamAtHit1.SetRemovable(kFALSE);
-         newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit1,hitForRecCh1);
-         newTrack->GetTrackParamAtHit()->Sort();
+         extrapTrackParamAtCluster1.SetRemovable(kFALSE);
+         newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
+         newTrack->GetTrackParamAtCluster()->Sort();
          fNRecTracks++;
          
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-           cout << "FollowLinearTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl;
+           cout << "FollowLinearTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl;
            if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
          }
          
-       } else if (chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
-         // keep track of the best single hitForRec except if a couple of hits has already been found
-         bestChi2WithOneHitForRec = chi2WithOneHitForRec;
-         bestTrackParamAtHit1 = extrapTrackParamAtHit1;
+       } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
+         // keep track of the best cluster except if a couple of clusters has already been found
+         bestChi2WithOneCluster = chi2WithOneCluster;
+         bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
        }
        
       }
@@ -756,47 +662,47 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
   
   // fill out the best track if required else clean up the fRecTracksPtr array
   if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) {
-    if (foundTwoHits) {
-      bestTrackParamAtHit1.SetRemovable(kTRUE);
-      trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit1,bestTrackParamAtHit1.GetHitForRecPtr());
-      bestTrackParamAtHit2.SetRemovable(kTRUE);
-      trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit2,bestTrackParamAtHit2.GetHitForRecPtr());
-      trackCandidate.GetTrackParamAtHit()->Sort();
+    if (foundTwoClusters) {
+      bestTrackParamAtCluster1.SetRemovable(kTRUE);
+      trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
+      bestTrackParamAtCluster2.SetRemovable(kTRUE);
+      trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster2,*(bestTrackParamAtCluster2.GetClusterPtr()));
+      trackCandidate.GetTrackParamAtCluster()->Sort();
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowLinearTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl;
+        cout << "FollowLinearTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
         if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
       }
       
-    } else if (foundOneHit) {
-      bestTrackParamAtHit1.SetRemovable(kFALSE);
-      trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit1,bestTrackParamAtHit1.GetHitForRecPtr());
-      trackCandidate.GetTrackParamAtHit()->Sort();
+    } else if (foundOneCluster) {
+      bestTrackParamAtCluster1.SetRemovable(kFALSE);
+      trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
+      trackCandidate.GetTrackParamAtCluster()->Sort();
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-        cout << "FollowLinearTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl;
+        cout << "FollowLinearTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
         if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
       }
       
     } else {
-      delete [] hitForRecCh1Used;
+      delete [] clusterCh1Used;
       return kFALSE;
     }
     
-  } else if (foundOneHit || foundTwoHits) {
+  } else if (foundOneCluster || foundTwoClusters) {
     
     // remove obsolete track
     fRecTracksPtr->Remove(&trackCandidate);
     fNRecTracks--;
     
   } else {
-    delete [] hitForRecCh1Used;  
+    delete [] clusterCh1Used;  
     return kFALSE;
   }
   
-  delete [] hitForRecCh1Used;
+  delete [] clusterCh1Used;
   return kTRUE;
   
 }
@@ -828,7 +734,7 @@ void AliMUONVTrackReconstructor::ValidateTracksWithTrigger(AliMUONVTrackStore& t
     Int_t doubleMatch=-1; // Check if track matches 2 trigger tracks
     Double_t doubleChi2 = -1.;
     
-    AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last())));
+    AliMUONTrackParam trackParam(*((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last())));
     AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber
     
     xTrack = trackParam.GetNonBendingCoor();
index a8d0366..9630de6 100644 (file)
@@ -18,7 +18,7 @@
 
 class AliMUONTrack;
 class AliMUONTrackParam;
-class AliMUONHitForRec;
+class AliMUONVCluster;
 class AliMUONTriggerTrack;
 class AliMUONTrackHitPattern;
 class AliMUONVClusterStore;
@@ -36,11 +36,6 @@ class AliMUONVTrackReconstructor : public TObject {
   AliMUONVTrackReconstructor(); // default Constructor
   virtual ~AliMUONVTrackReconstructor(); // Destructor
 
-  // Parameters for track reconstruction: public methods
-  // Get and Set, Set to defaults
-           /// Return minimum value (GeV/c) of momentum in bending plane
-  Double_t GetMinBendingMomentum() const {return AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum();}
-
   // Reconstructed tracks
            /// Return number of reconstructed tracks
   Int_t GetNRecTracks() const {return fNRecTracks;} // Number
@@ -65,12 +60,6 @@ class AliMUONVTrackReconstructor : public TObject {
   
  protected:
 
-  TClonesArray* fHitsForRecPtr; ///< pointer to the array of hits for reconstruction
-  Int_t fNHitsForRec; ///< number of hits for reconstruction
-  Int_t* fNHitsForRecPerChamber; ///< number of HitsForRec
-  Int_t* fIndexOfFirstHitForRecPerChamber; ///< index (0...) of first HitForRec
-
-  // Reconstructed tracks
   TClonesArray *fRecTracksPtr; ///< pointer to array of reconstructed tracks
   Int_t fNRecTracks; ///< number of reconstructed tracks
 
@@ -80,40 +69,35 @@ class AliMUONVTrackReconstructor : public TObject {
   AliMUONVTrackReconstructor& operator=(const AliMUONVTrackReconstructor& rhs); ///< assignment operator
   
   /// Make track candidats from clusters in stations(1..) 4 and 5
-  virtual void MakeTrackCandidates() = 0;
+  virtual void MakeTrackCandidates(const AliMUONVClusterStore& clusterStore) = 0;
   /// Follow tracks in stations(1..) 3, 2 and 1
-  virtual void FollowTracks() = 0;
+  virtual void FollowTracks(const AliMUONVClusterStore& clusterStore) = 0;
   /// Complement the reconstructed tracks
-  virtual void ComplementTracks() = 0;
+  virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore) = 0;
   /// Improve the reconstructed tracks
   virtual void ImproveTracks() = 0;
   /// Finalize the tracking results
   virtual void Finalize() = 0;
   
-  TClonesArray* MakeSegmentsInStation(Int_t station);
+  TClonesArray* MakeSegmentsInStation(const AliMUONVClusterStore& clusterStore, Int_t station);
 
   void RemoveIdenticalTracks();
   void RemoveDoubleTracks();
 
-  Double_t TryOneHitForRec(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec,
-                          AliMUONTrackParam &trackParamAtHit, Bool_t updatePropagator = kFALSE);
-  Bool_t   TryOneHitForRecFast(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec);
-  Double_t TryTwoHitForRecFast(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2,
-                              AliMUONTrackParam &trackParamAtHit2);
+  Double_t TryOneCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster,
+                        AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator = kFALSE);
+  Bool_t   TryOneClusterFast(const AliMUONTrackParam &trackParam, AliMUONVCluster* cluster);
+  Double_t TryTwoClustersFast(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2,
+                             AliMUONTrackParam &trackParamAtCluster2);
 
-  Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation);
+  Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore& clusterStore,
+                                   Int_t nextStation);
   
 
  private:
   
   // Functions
   void ResetTracks();
-  void ResetHitsForRec();
-  
-  void AddHitsForRecFromRawClusters(const AliMUONVClusterStore& clusterStore);
-  void SortHitsForRecWithIncreasingChamber();
-  
-  void MakeTracks();
   
   
   ClassDef(AliMUONVTrackReconstructor, 0) // MUON track reconstructor in ALICE
index 40af52d..3549070 100644 (file)
@@ -186,7 +186,7 @@ void MUONAlignment(Int_t nEvents = 100000, char* geoFilename = "geometry.root",
        cout << " there are " << ntracks << " tracks in event " << event << endl;
       TIter next(trackStore->CreateIterator());
       while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) {
-       AliMUONTrackParam trackParam(*((AliMUONTrackParam*)(track->GetTrackParamAtHit()->First())));
+       AliMUONTrackParam trackParam(*((AliMUONTrackParam*)(track->GetTrackParamAtCluster()->First())));
        AliMUONTrackExtrap::ExtrapToVertex(&trackParam,0.,0.,0.);
        Double_t invBenMom = trackParam.GetInverseBendingMomentum();
        fInvBenMom->Fill(invBenMom);
index baf35c6..0d8a75a 100644 (file)
@@ -43,7 +43,6 @@ void MUONCheck(Int_t firstEvent, Int_t lastEvent,
    check->CheckKine();
    check->CheckTrackRef();
    check->CheckOccupancy();
-   check->CheckRecTracks();
 
    // delete check;  
 }
index eef1a29..3026f70 100644 (file)
@@ -61,16 +61,16 @@ Int_t Compare(const TObject* a, const TObject* b)
        {
                const AliMUONTrack* ta = static_cast<const AliMUONTrack*>(a);
                const AliMUONTrack* tb = static_cast<const AliMUONTrack*>(b);
-               if (ta->GetNTrackHits() < tb->GetNTrackHits()) return -1;
-               if (ta->GetNTrackHits() > tb->GetNTrackHits()) return 1;
+               if (ta->GetNClusters() < tb->GetNClusters()) return -1;
+               if (ta->GetNClusters() > tb->GetNClusters()) return 1;
                if (ta->GetMatchTrigger() < tb->GetMatchTrigger()) return -1;
                if (ta->GetMatchTrigger() > tb->GetMatchTrigger()) return 1;
                if (ta->GetLoTrgNum() < tb->GetLoTrgNum()) return -1;
                if (ta->GetLoTrgNum() > tb->GetLoTrgNum()) return 1;
                if (ta->GetChi2MatchTrigger() < tb->GetChi2MatchTrigger()) return -1;
                if (ta->GetChi2MatchTrigger() > tb->GetChi2MatchTrigger()) return 1;
-               const AliMUONTrackParam* tpa = static_cast<const AliMUONTrackParam*>(ta->GetTrackParamAtHit()->First());
-               const AliMUONTrackParam* tpb = static_cast<const AliMUONTrackParam*>(tb->GetTrackParamAtHit()->First());
+               const AliMUONTrackParam* tpa = static_cast<const AliMUONTrackParam*>(ta->GetTrackParamAtCluster()->First());
+               const AliMUONTrackParam* tpb = static_cast<const AliMUONTrackParam*>(tb->GetTrackParamAtCluster()->First());
                if (tpa->GetNonBendingCoor() < tpb->GetNonBendingCoor()) return -1;
                if (tpa->GetNonBendingCoor() > tpb->GetNonBendingCoor()) return 1;
                if (tpa->GetNonBendingSlope() < tpb->GetNonBendingSlope()) return -1;
index 1a15a00..ee28248 100644 (file)
@@ -39,7 +39,7 @@
 Int_t TrackCheck( Bool_t *compTrack);
 
 void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root", 
-                    char * filenameSim="galice_sim.root", char * filename="galice.root"){
+                    char * pathSim="./generated/", char * filename="galice.root"){
   
   // Utility macro to check the muon reconstruction. Reconstructed tracks are compared
   // to reference tracks. The reference tracks are built from AliTrackReference for the
@@ -47,14 +47,13 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
   
   Bool_t *compTrack;
   Bool_t compTrackOK[10];
-  Int_t nHitOK = 0;
+  Int_t nClusterOk = 0;
   Int_t testTrack = 0; 
   Int_t iTrack = 0;
   AliMUONTrack* trackOK(0x0);
   Int_t trackID = 0;
   Double_t sigma2Cut = 16;  // 4 sigmas cut, sigma2Cut = 4*4
   AliMUONTrackParam *trackParam;
-  TClonesArray *trackParamAtHit;
   Double_t x1,y1,z1,pX1,pY1,pZ1,p1;
   Double_t x2,y2,z2,pX2,pY2,pZ2,p2;
   
@@ -63,12 +62,12 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
   
   TH1F *hReconstructible = new TH1F("hReconstructible"," Nb of reconstructible tracks ",15,-0.5,14.5);
   TH1F *hReco = new TH1F("hReco"," Nb of reconstructed tracks / evt",15,-0.5,14.5);
-  TH1F *hNHitComp = new TH1F("hNHitComp"," Nb of compatible hits / track ",15,-0.5,14.5);
+  TH1F *hNClusterComp = new TH1F("hNClusterComp"," Nb of compatible clusters / track ",15,-0.5,14.5);
   TH1F *hTestTrack = new TH1F("hTestTrack"," Reconstruction requirement / track",15,-0.5,14.5);
   TH1F *hTrackRefID = new TH1F("hTrackRefID"," track reference ID ",100,-0.5,99.5);
   
-  TH1F *hResMomVertex = new TH1F("hMomVertex"," delta P vertex (GeV/c)",100,-10.,10);
-  TH1F *hResMomFirstHit = new TH1F("hMomFirstHit"," delta P first hit (GeV/c)",100,-10.,10);
+  TH1F *hResMomVertex = new TH1F("hResMomVertex"," delta P vertex (GeV/c)",100,-10.,10);
+  TH1F *hResMomFirstCluster = new TH1F("hResMomFirstCluster"," delta P first cluster (GeV/c)",100,-10.,10);
   
   // Import TGeo geometry (needed by AliMUONTrackExtrap::ExtrapToVertex)
   if (!gGeoManager) {
@@ -87,7 +86,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
   // set the magnetic field for track extrapolations
   AliMUONTrackExtrap::SetField(AliTracker::GetFieldMap());
     
-  AliMUONRecoCheck rc(filename,filenameSim);
+  AliMUONRecoCheck rc(filename,pathSim);
   
   Int_t nevents = rc.NumberOfEvents();
   
@@ -135,10 +134,10 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         
         if (iTrack > testTrack) 
         {
-          nHitOK = 0;
+          nClusterOk = 0;
           for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) 
           {
-            if (compTrack[ch]) nHitOK++;
+            if (compTrack[ch]) nClusterOk++;
             compTrackOK[ch] = compTrack[ch];
           }
           testTrack = iTrack;
@@ -152,7 +151,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
       
       if (testTrack == 4) {     // tracking requirements verified, track is found
         nReconstructibleTracksCheck++;
-        hNHitComp->Fill(nHitOK);
+        hNClusterComp->Fill(nClusterOk);
         trackParam = trackRef->GetTrackParamAtVertex();
         x1 = trackParam->GetNonBendingCoor();
         y1 = trackParam->GetBendingCoor();
@@ -164,7 +163,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         
         //     printf(" Ref. track at vertex: x,y,z: %f %f %f px,py,pz,p: %f %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1,p1);
         trackReco = trackOK;
-        trackParam = new AliMUONTrackParam(*((AliMUONTrackParam*)(trackReco->GetTrackParamAtHit()->First())));
+        trackParam = new AliMUONTrackParam(*((AliMUONTrackParam*)(trackReco->GetTrackParamAtCluster()->First())));
         AliMUONTrackExtrap::ExtrapToVertex(trackParam,x1,y1,z1);
         x2 = trackParam->GetNonBendingCoor();
         y2 = trackParam->GetBendingCoor();
@@ -178,8 +177,7 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         
         hResMomVertex->Fill(p2-p1);
         
-        trackParamAtHit =  trackRef->GetTrackParamAtHit();
-        trackParam = (AliMUONTrackParam*) trackParamAtHit->First();
+        trackParam = (AliMUONTrackParam*) trackRef->GetTrackParamAtCluster()->First();
         x1 = trackParam->GetNonBendingCoor();
         y1 = trackParam->GetBendingCoor();
         z1 = trackParam->GetZ();
@@ -187,9 +185,8 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         pY1 = trackParam->Py();
         pZ1 = trackParam->Pz();
         p1  = trackParam->P();
-        //     printf(" Ref. track at 1st hit: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1);
-        trackParamAtHit =  trackOK->GetTrackParamAtHit();
-        trackParam = (AliMUONTrackParam*) trackParamAtHit->First();
+        //     printf(" Ref. track at 1st cluster: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x1,y1,z1,pX1,pY1,pZ1);
+        trackParam = (AliMUONTrackParam*) trackOK->GetTrackParamAtCluster()->First();
         x2 = trackParam->GetNonBendingCoor();
         y2 = trackParam->GetBendingCoor();
         z2 = trackParam->GetZ();
@@ -197,9 +194,9 @@ void MUONRecoCheck (Int_t nEvent = 1, char* geoFilename = "geometry.root",
         pY2 = trackParam->Py();
         pZ2 = trackParam->Pz();
         p2  = trackParam->P();
-        //     printf(" Reconst. track at 1st hit: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2);
+        //     printf(" Reconst. track at 1st cluster: x,y,z: %f %f %f px,py,pz: %f %f %f \n",x2,y2,z2,pX2,pY2,pZ2);
         
-        hResMomFirstHit->Fill(p2-p1);
+        hResMomFirstCluster->Fill(p2-p1);
               
       }
     } // end loop track ref.
@@ -223,24 +220,18 @@ Int_t TrackCheck( Bool_t *compTrack)
   // Return number of validated conditions 
   // If all the tests are verified then TrackCheck = 4 (good track)
   Int_t iTrack = 0;
-  Int_t hitsInLastStations = 0;
+  Int_t nCompClustersInLastStations = 0;
   
   // apply reconstruction requirements
-  if (compTrack[0] || compTrack[1]) iTrack++; // at least one hit in st. 0
-  if (compTrack[2] || compTrack[3]) iTrack++; // at least one hit in st. 1
-  if (compTrack[4] || compTrack[5]) iTrack++; // at least one hit in st. 2
+  if (compTrack[0] || compTrack[1]) iTrack++; // at least one compatible cluster in st. 0
+  if (compTrack[2] || compTrack[3]) iTrack++; // at least one compatible cluster in st. 1
+  if (compTrack[4] || compTrack[5]) iTrack++; // at least one compatible cluster in st. 2
   for (Int_t ch = 6; ch < AliMUONConstants::NTrackingCh(); ch++) {
-    if (compTrack[ch]) hitsInLastStations++; 
+    if (compTrack[ch]) nCompClustersInLastStations++; 
   }
-  if (hitsInLastStations > 2) iTrack++; // at least 3 hits in st. 3 & 4
+  if (nCompClustersInLastStations > 2) iTrack++; // at least 3 compatible clusters in st. 3 & 4
   
   return iTrack;
   
 }
 
-
-
-
-
-
-
index de23626..e578918 100644 (file)
@@ -277,7 +277,7 @@ void efficiencyThetaPhi( Int_t event2Check=0, char * filename="galice.root" )
       for ( iTrack = 0; iTrack < nTracks; ++iTrack )
       {
        track       = (AliMUONTrack*) tracks ->At(iTrack)          ;
-       trackParams =                 track  ->GetTrackParamAtHit();
+       trackParams =                 track  ->GetTrackParamAtCluster();
        hits        =                 track  ->GetHitForRecAtHit() ;
        chamber     = firstChamber-1;
        oldChamber  = -1;
@@ -542,7 +542,7 @@ void efficiencyThetaI( Int_t event2Check=0, char * filename="galice.root" )
       for ( iTrack = 0; iTrack < nTracks; ++iTrack )
       { 
        track       = (AliMUONTrack*) tracks ->At(iTrack)          ;
-       trackParams =                 track  ->GetTrackParamAtHit();
+       trackParams =                 track  ->GetTrackParamAtCluster();
        hits        =                 track  ->GetHitForRecAtHit() ;
        chamber     = firstChamber - 1;
        oldChamber  = -1;
@@ -765,7 +765,7 @@ void resolution( Int_t event2Check=0, char * filename="galice.root" )
       for ( iTrack = 0; iTrack < nTracks; ++iTrack )
       {
        track       = (AliMUONTrack*) tracks ->At(iTrack)          ;
-       trackParams =                 track  ->GetTrackParamAtHit();
+       trackParams =                 track  ->GetTrackParamAtCluster();
        hits        =                 track  ->GetHitForRecAtHit() ;
        
        //Loop on hits
@@ -921,7 +921,7 @@ void resolutionPhi( Int_t event2Check=0, char * filename="galice.root" )
       for ( iTrack = 0; iTrack < nTracks; ++iTrack )
       {
        track       = (AliMUONTrack*) tracks ->At(iTrack)          ;
-       trackParams =                 track  ->GetTrackParamAtHit();
+       trackParams =                 track  ->GetTrackParamAtCluster();
        hits        =                 track  ->GetHitForRecAtHit() ;
        
        //Loop on hits
@@ -1128,7 +1128,7 @@ void resolutionTheta( Int_t event2Check=0, char * filename="galice.root" )
       for ( iTrack = 0; iTrack < nTracks; ++iTrack )
       { 
        track       = (AliMUONTrack*) tracks ->At(iTrack)          ;
-       trackParams =                 track  ->GetTrackParamAtHit();
+       trackParams =                 track  ->GetTrackParamAtCluster();
        hits        =                 track  ->GetHitForRecAtHit() ;
        
        //Loop on hits
@@ -1339,7 +1339,7 @@ void resolutionThetaI( Int_t event2Check=0, char * filename="galice.root" )
       for ( iTrack = 0; iTrack < nTracks; ++iTrack )
       {
        track       = (AliMUONTrack*) tracks ->At(iTrack)          ;
-       trackParams =                 track  ->GetTrackParamAtHit();
+       trackParams =                 track  ->GetTrackParamAtCluster();
        hits        =                 track  ->GetHitForRecAtHit() ;
        
        //Loop on hits
index 9e550ae..7f30c14 100644 (file)
@@ -21,7 +21,6 @@
 #pragma link C++ class AliMUONTrackExtrap+; 
 #pragma link C++ class AliMUONTriggerTrack+; 
 #pragma link C++ class AliMUONRecoTrack+; 
-#pragma link C++ class AliMUONHitForRec+; 
 #pragma link C++ class AliMUONAlignment+;
 #pragma link C++ class AliMUONVClusterFinder+;
 #pragma link C++ class AliMUONPad+;
index b39a2f0..fe2a093 100644 (file)
@@ -14,7 +14,6 @@ SRCS:= AliMUONClusterReconstructor.cxx \
        AliMUONVTriggerTrackStore.cxx \
        AliMUONTriggerTrackStoreV1.cxx \
        AliMUONRecoTrack.cxx \
-       AliMUONHitForRec.cxx \
        AliMUONDigitCalibrator.cxx \
        AliMUONAlignment.cxx \
        AliMUONVClusterFinder.cxx \
index 0624ec7..241cfdf 100644 (file)
@@ -50,7 +50,9 @@ class AliMpLocalBoard : public TNamed
     Int_t  GetNofSwitches() const;
     Int_t  GetSwitch(Int_t index) const;
 
+            /// Set switch in a compact way
     void   SetSwitch(UInt_t swit) {fSwitch = swit;}
+            /// Get switch in a compact way
     UInt_t  GetSwitch() const {return fSwitch;}
 
     // switch enum for local board (see PRR, chpt: 2.4.4)