+AliMUONTrack* AliMUONRefitter::RetrackFromDigits(const AliMUONTrack& track)
+{
+ /// refit the given track from the digits (i.e. re-clusterized the attached clusters):
+ /// several new clusters may be reconstructed per initial ESD cluster:
+ /// -> all the combinations of clusters are considered to build the new tracks
+ /// -> return the best track (largest number of clusters or best chi2 in case of equality)
+
+ // check if digits exist
+ UInt_t trackId = track.GetUniqueID();
+ if (fkESDInterface->GetNDigits(trackId) == 0) {
+ AliError(Form("no digit attached to track #%d",trackId));
+ return 0x0;
+ }
+
+ // prepare new track(s)
+ AliMUONVTrackStore* newTrackStore = AliMUONESDInterface::NewTrackStore();
+ if (!newTrackStore) return 0x0;
+ newTrackStore->Add(track)->Clear("C");
+
+ // prepare new cluster store
+ AliMUONVClusterStore* newClusterStore = AliMUONESDInterface::NewClusterStore();
+ if (!newClusterStore) {
+ delete newTrackStore;
+ return 0x0;
+ }
+
+ // loop over clusters, re-clusterize and build new tracks
+ AliMUONVCluster* cluster;
+ TIter nextCluster(fkESDInterface->CreateClusterIterator(trackId));
+ while ((cluster = static_cast<AliMUONVCluster*>(nextCluster()))) {
+
+ // reset the new cluster store
+ newClusterStore->Clear();
+
+ // re-clusterize current cluster
+ TIter nextDigit(fkESDInterface->CreateDigitIterator(trackId, cluster->GetUniqueID()));
+ fClusterServer->UseDigits(nextDigit,fkESDInterface->GetDigits());
+ Int_t nNewClusters = fClusterServer->Clusterize(cluster->GetChamberId(),*newClusterStore,AliMpArea(),fkRecoParam);
+
+ // check that re-clusterizing succeeded
+ if (nNewClusters == 0) {
+ AliWarning(Form("refit gave no cluster (chamber %d)",cluster->GetChamberId()));
+ AliInfo("initial ESD cluster:");
+ cluster->Print("FULL");
+ continue;
+ }
+
+ // add the new cluster(s) to the tracks
+ if (!AddClusterToTracks(*newClusterStore, *newTrackStore)) {
+ delete newClusterStore;
+ delete newTrackStore;
+ return 0x0;
+ }
+
+ }
+
+ if (newTrackStore->GetSize() > 1000) AliInfo(Form("%d tracks to refit... be patient!!",newTrackStore->GetSize()));
+
+ // refit the tracks and pick up the best one
+ AliMUONTrack *currentTrack, *bestTrack = 0x0;
+ Double_t currentChi2, bestChi2 = AliMUONTrack::MaxChi2();
+ Int_t currentNCluster, bestNClusters = 0;
+ TIter next(newTrackStore->CreateIterator());
+ while ((currentTrack = static_cast<AliMUONTrack*>(next()))) {
+
+ // set the track parameters at first cluster if any (used as seed in original tracking)
+ AliMUONTrackParam* param = (AliMUONTrackParam*) currentTrack->GetTrackParamAtCluster()->First();
+ if (param) *param = *((AliMUONTrackParam*) track.GetTrackParamAtCluster()->First());
+
+ // refit the track
+ if (!fTracker->RefitTrack(*currentTrack)) continue;
+
+ // find best track (the one with the higher number of cluster or the best chi2 in case of equality)
+ currentNCluster = currentTrack->GetNClusters();
+ currentChi2 = currentTrack->GetGlobalChi2();
+ if (currentNCluster > bestNClusters || (currentNCluster == bestNClusters && currentChi2 < bestChi2)) {
+ bestTrack = currentTrack;
+ bestNClusters = currentNCluster;
+ bestChi2 = currentChi2;
+ }
+
+ }
+
+ // copy best track and free memory
+ AliMUONTrack* newTrack = bestTrack ? new AliMUONTrack(*bestTrack) : 0x0;
+ delete newClusterStore;
+ delete newTrackStore;
+
+ return newTrack;
+}
+
+//_____________________________________________________________________________
+Bool_t AliMUONRefitter::AddClusterToTracks(const AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore)