All:
authorlaphecet <laphecet@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 8 Apr 2009 10:35:16 +0000 (10:35 +0000)
committerlaphecet <laphecet@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 8 Apr 2009 10:35:16 +0000 (10:35 +0000)
- Speed up the computation/selection of primary track candidates (by up to a factor 100)
- Improve computation of initial covariance matrices for Kalman
- Use specific covariance matrices when there is no magnetic field
- fix potential bug by reordering cluster/track selection
- fix selection of track candidates when there is no magnetic field
- new protection against tracking divergences (see below)

AliMUONRecoParam:
- change Cosmic settings
- New parameter: maximum number of trigger tracks above which the tracking is cancelled
- New parameter: maximum number of track candidates above which the tracking abort

(Philippe Pillot)

15 files changed:
MUON/AliMUONRecoParam.cxx
MUON/AliMUONRecoParam.h
MUON/AliMUONTrack.cxx
MUON/AliMUONTrack.h
MUON/AliMUONTrackExtrap.cxx
MUON/AliMUONTrackReconstructor.cxx
MUON/AliMUONTrackReconstructor.h
MUON/AliMUONTrackReconstructorK.cxx
MUON/AliMUONTrackReconstructorK.h
MUON/AliMUONTracker.cxx
MUON/AliMUONVTrackReconstructor.cxx
MUON/AliMUONVTrackReconstructor.h
MUON/MUONefficiency.C
MUON/runDataReconstruction.C
OCDB/MUON/Calib/RecoParam/Run0_999999999_v0_s0.root

index 92455e5..5291eaf 100644 (file)
@@ -69,7 +69,9 @@ AliMUONRecoParam::AliMUONRecoParam()
   fBypassSt45(0),
   fPadGoodnessMask(0),
   fChargeSigmaCut(4.0),
-  fRemoveConnectedTracksInSt12(kFALSE)
+  fRemoveConnectedTracksInSt12(kFALSE),
+  fMaxTriggerTracks(0),
+  fMaxTrackCandidates(0)
 {
   /// Constructor
   
@@ -178,6 +180,8 @@ void AliMUONRecoParam::SetLowFluxParam()
   }
   for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
   fBypassSt45 = 0;
+  fMaxTriggerTracks = 100;
+  fMaxTrackCandidates = 10000;
   
 }
 
@@ -218,6 +222,8 @@ void AliMUONRecoParam::SetHighFluxParam()
   }
   for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
   fBypassSt45 = 0;
+  fMaxTriggerTracks = 100;
+  fMaxTrackCandidates = 10000;
   
 }
 
@@ -236,8 +242,8 @@ void AliMUONRecoParam::SetCosmicParam()
   fBendingVertexDispersion = 10.;
   fMaxNonBendingDistanceToTrack = 10.;
   fMaxBendingDistanceToTrack = 10.;
-  fSigmaCutForTracking = 20.;
-  fSigmaCutForImprovement = 20.;
+  fSigmaCutForTracking = 7.;
+  fSigmaCutForImprovement = 7.;
   fSigmaCutForTrigger = 8.;
   fStripCutForTrigger = 1.5;
   fMaxStripAreaForTrigger = 3.;
@@ -255,11 +261,14 @@ void AliMUONRecoParam::SetCosmicParam()
   fSaveFullClusterInESD = kTRUE;
   for (Int_t iCh = 0; iCh < 10; iCh++) {
     fUseChamber[iCh] = kTRUE;
-    fDefaultNonBendingReso[iCh] = 0.144;
-    fDefaultBendingReso[iCh] = 0.01;
+    fDefaultNonBendingReso[iCh] = 0.4;
+    fDefaultBendingReso[iCh] = 0.4;
   }
   for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
   fBypassSt45 = 0;
+  fPadGoodnessMask = 0x400BE80;
+  fMaxTriggerTracks = 100;
+  fMaxTrackCandidates = 10000;
   
 }
 
@@ -435,6 +444,8 @@ void AliMUONRecoParam::Print(Option_t *option) const
   cout << "chamber bending resolution = |";
   for (Int_t iCh = 0; iCh < 10; iCh++) cout << Form(" %6.3f |",fDefaultBendingReso[iCh]);
   cout << endl;
+  cout<<Form("maximum number of trigger tracks above which the tracking is cancelled = %d",fMaxTriggerTracks)<<endl;
+  cout<<Form("maximum number of track candidates above which the tracking abort = %d",fMaxTrackCandidates)<<endl;
   
   cout<<"\t-----------------------------------------------------"<<endl<<endl;
   
@@ -455,7 +466,7 @@ AliMUONRecoParam::SetDefaultLimits()
        fPedMeanLimits[0] = 50;
        fPedMeanLimits[1] = 1024;
        
-       fPedSigmaLimits[0] = 0.1;
+       fPedSigmaLimits[0] = 0.6;
        fPedSigmaLimits[1] = 100;
 
        fGainA1Limits[0] = 0.1;
index c1d928c..9fa4c20 100644 (file)
@@ -248,6 +248,16 @@ class AliMUONRecoParam : public AliDetectorRecoParam
   /// Get the default bending resolution of chamber iCh
   Double_t GetDefaultBendingReso(Int_t iCh) const {return (iCh >= 0 && iCh < 10) ? fDefaultBendingReso[iCh] : FLT_MAX;}
   
+  /// Set the maximum number of trigger tracks above which the tracking is cancelled
+  void SetMaxTriggerTracks(Int_t maxTriggerTracks) {fMaxTriggerTracks = maxTriggerTracks;}
+  /// Get the maximum number of trigger tracks above which the tracking is cancelled
+  Int_t GetMaxTriggerTracks() const {return fMaxTriggerTracks;}
+  
+  /// Set the maximum number of track candidates above which the tracking abort
+  void SetMaxTrackCandidates(Int_t maxTrackCandidates) {fMaxTrackCandidates = maxTrackCandidates;}
+  /// Get the maximum number of track candidates above which the tracking abort
+  Int_t GetMaxTrackCandidates() const {return fMaxTrackCandidates;}
+  
   virtual void Print(Option_t *option = "") const;
   
   
@@ -334,13 +344,16 @@ class AliMUONRecoParam : public AliDetectorRecoParam
   
   Bool_t     fRemoveConnectedTracksInSt12; ///< kTRUE to remove tracks sharing cluster in station 1 and 2
   
+  Int_t      fMaxTriggerTracks; ///< maximum number of trigger tracks above which the tracking is cancelled
+  Int_t      fMaxTrackCandidates; ///< maximum number of track candidates above which the tracking abort
+  
   // functions
   void SetLowFluxParam();
   void SetHighFluxParam();
   void SetCosmicParam();
   
   
-  ClassDef(AliMUONRecoParam,11) // MUON reco parameters
+  ClassDef(AliMUONRecoParam,12) // MUON reco parameters
 };
 
 #endif
index f311a65..06a49b5 100644 (file)
@@ -141,24 +141,31 @@ AliMUONTrack::AliMUONTrack(AliMUONObjectPair *segment, Double_t bendingVertexDis
   paramCov(3,2) = paramCov(2,3);
   paramCov(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ;
   // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
-  paramCov(4,4) = ( ( bendingVertexDispersion*bendingVertexDispersion +
-                   (z1 * z1 * lastCluster->GetErrY2() + z2 * z2 * firstCluster->GetErrY2()) / dZ / dZ) /
-                  bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum ;
-  paramCov(2,4) = - z2 * firstCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
-  paramCov(4,2) = paramCov(2,4);
-  paramCov(3,4) = - (z1 * lastCluster->GetErrY2() + z2 * firstCluster->GetErrY2()) * inverseBendingMomentum / bendingImpact / dZ / dZ;
-  paramCov(4,3) = paramCov(3,4);
-  
-  // Set covariances
+  if (AliMUONTrackExtrap::IsFieldON()) {
+    paramCov(4,4) = ( ( bendingVertexDispersion*bendingVertexDispersion +
+                      (z1 * z1 * lastCluster->GetErrY2() + z2 * z2 * firstCluster->GetErrY2()) / dZ / dZ) /
+                    bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum ;
+    paramCov(2,4) = - z2 * firstCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+    paramCov(4,2) = paramCov(2,4);
+    paramCov(3,4) = - (z1 * lastCluster->GetErrY2() + z2 * firstCluster->GetErrY2()) * inverseBendingMomentum / bendingImpact / dZ / dZ;
+    paramCov(4,3) = paramCov(3,4);
+  } else paramCov(4,4) = inverseBendingMomentum*inverseBendingMomentum;
   trackParamAtFirstCluster.SetCovariances(paramCov);
   
   // Compute and set track parameters covariances at last cluster
-  paramCov(1,0) = - paramCov(1,0);
-  paramCov(0,1) = - paramCov(0,1);
-  paramCov(3,2) = - paramCov(3,2);
-  paramCov(2,3) = - paramCov(2,3);
-  paramCov(2,4) = z1 * lastCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
-  paramCov(4,2) = paramCov(2,4);
+  // Non bending plane
+  paramCov(0,0) = lastCluster->GetErrX2();
+  paramCov(0,1) = - lastCluster->GetErrX2() / dZ;
+  paramCov(1,0) = paramCov(0,1);
+  // Bending plane
+  paramCov(2,2) = lastCluster->GetErrY2();
+  paramCov(2,3) = - lastCluster->GetErrY2() / dZ;
+  paramCov(3,2) = paramCov(2,3);
+  // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
+  if (AliMUONTrackExtrap::IsFieldON()) {
+    paramCov(2,4) = z1 * lastCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+    paramCov(4,2) = paramCov(2,4);
+  }
   trackParamAtLastCluster.SetCovariances(paramCov);
   
   // Add track parameters at clusters
@@ -971,33 +978,56 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const
 }
 
   //__________________________________________________________________________
-Int_t AliMUONTrack::ClustersInCommon(AliMUONTrack* track, Bool_t inSt345) const
+Int_t AliMUONTrack::ClustersInCommon(AliMUONTrack* track) const
 {
   /// Returns the number of clusters in common between the current track ("this")
   /// and the track pointed to by "track".
-  /// If inSt345=kTRUE only stations 3, 4 and 5 are considered.
   if (!fTrackParamAtCluster || !this->fTrackParamAtCluster) return 0;
+  Int_t nCluster1 = this->GetNClusters();
+  Int_t nCluster2 = track->GetNClusters();
   Int_t clustersInCommon = 0;
   AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2;
   // Loop over clusters of first track
-  trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->First();
-  while (trackParamAtCluster1) {
-    if ((!inSt345) || (trackParamAtCluster1->GetClusterPtr()->GetChamberId() > 3)) {
-      // Loop over clusters of second track
-      trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->First();
-      while (trackParamAtCluster2) {
-       if ((!inSt345) || (trackParamAtCluster2->GetClusterPtr()->GetChamberId() > 3)) {
-         // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
-         if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
-           clustersInCommon++;
-           break;
-         }
-       }
-       trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->After(trackParamAtCluster2);
-      } // trackParamAtCluster2
+  for(Int_t iCluster1 = 0; iCluster1 < nCluster1; iCluster1++) {
+    trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->UncheckedAt(iCluster1);
+    // Loop over clusters of second track
+    for(Int_t iCluster2 = 0; iCluster2 < nCluster2; iCluster2++) {
+      trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->UncheckedAt(iCluster2);
+      // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
+      if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
+       clustersInCommon++;
+       break;
+      }
     }
-    trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->After(trackParamAtCluster1);
-  } // trackParamAtCluster1
+  }
+  return clustersInCommon;
+}
+
+  //__________________________________________________________________________
+Int_t AliMUONTrack::ClustersInCommonInSt345(AliMUONTrack* track) const
+{
+  /// Returns the number of clusters in common on stations 3, 4 and 5
+  /// between the current track ("this") and the track pointed to by "track".
+  if (!fTrackParamAtCluster || !this->fTrackParamAtCluster) return 0;
+  Int_t nCluster1 = this->GetNClusters();
+  Int_t nCluster2 = track->GetNClusters();
+  Int_t clustersInCommon = 0;
+  AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2;
+  // Loop over clusters of first track
+  for(Int_t iCluster1 = 0; iCluster1 < nCluster1; iCluster1++) {
+    trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->UncheckedAt(iCluster1);
+    if (trackParamAtCluster1->GetClusterPtr()->GetChamberId() < 4) continue;
+    // Loop over clusters of second track
+    for(Int_t iCluster2 = 0; iCluster2 < nCluster2; iCluster2++) {
+      trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->UncheckedAt(iCluster2);
+      if (trackParamAtCluster2->GetClusterPtr()->GetChamberId() < 4) continue;
+      // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
+      if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
+       clustersInCommon++;
+       break;
+      }
+    }
+  }
   return clustersInCommon;
 }
 
index 6f7d85f..4e04b85 100644 (file)
@@ -88,7 +88,8 @@ class AliMUONTrack : public TObject
   /// set the chi2 of trigger/track matching 
   void     SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;}
 
-  Int_t ClustersInCommon(AliMUONTrack* track, Bool_t inSt345 = kFALSE) const;
+  Int_t ClustersInCommon(AliMUONTrack* track) const;
+  Int_t ClustersInCommonInSt345(AliMUONTrack* track) const;
 
   Int_t    GetNDF() const;
   Double_t GetNormalizedChi2() const;
index f63f50e..ba3fac9 100644 (file)
@@ -323,7 +323,7 @@ void AliMUONTrackExtrap::ExtrapToZCov(AliMUONTrackParam* trackParam, Double_t zE
     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.,-paramSave(4,0)); // variation always in the same direction
+       dParam(j,0) *= TMath::Sign(1.,paramSave(j,0)); // variation always in the same direction
       } else dParam(j,0) = 0.;
     }
     
index 1546223..3f0799c 100644 (file)
@@ -67,7 +67,7 @@ AliMUONTrackReconstructor::~AliMUONTrackReconstructor()
 } 
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructor::MakeTrackCandidates(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.
@@ -116,10 +116,15 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste
        clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
       else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
       
-      // Remove track if no cluster found
+      // Remove track if no cluster found on a requested station
+      // or abort tracking if there are too many candidates
       if (!clusterFound && GetRecoParam()->RequestStation(7-istat)) {
         fRecTracksPtr->Remove(track);
        fNRecTracks--;
+      }        else if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+       AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+       delete segments;
+       return kFALSE;
       }
       
     }
@@ -128,18 +133,18 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste
     delete segments;
   }
   
-  fRecTracksPtr->Compress(); // this is essential before checking tracks
-  
   // Keep all different tracks or only the best ones as required
   if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
   else RemoveDoubleTracks();
   
   AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
   
+  return kTRUE;
+  
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore)
 {
   /// To make extra track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
   /// clustering is supposed to be already done
@@ -148,6 +153,7 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
   
   TClonesArray *segments;
+  AliMUONObjectPair *segment;
   AliMUONTrack *track;
   Int_t iCandidate = 0, iCurrentTrack, nCurrentTracks;
   Bool_t clusterFound;
@@ -161,20 +167,22 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl
       // Make segments in the station
       segments = MakeSegmentsBetweenChambers(clusterStore, ich1, ich2);
       
+      /// Remove segments already attached to a track
+      RemoveUsedSegments(*segments);
+      
       // Loop over segments
-      for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) 
+      for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); iSegment++)
       {
        AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
+       segment = (AliMUONObjectPair*) segments->UncheckedAt(iSegment);
        
        // Transform segments to tracks and put them at the end of fRecTracksPtr
        iCurrentTrack = fRecTracksPtr->GetLast()+1;
-       track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]),GetRecoParam()->GetBendingVertexDispersion());
+       track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion());
        fNRecTracks++;
        
        // Look for compatible cluster(s) in the second chamber of station 5
-       if (GetRecoParam()->MakeTrackCandidatesFast())
-         clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
-       else clusterFound = FollowTrackInChamber(*track, clusterStore, 17-ich2);
+       clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
        
        // skip the original track in case it has been removed
        if (GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++;
@@ -185,13 +193,18 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl
          track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iCurrentTrack);
          
          // Look for compatible cluster(s) in the second chamber of station 4
-         if (GetRecoParam()->MakeTrackCandidatesFast())
-           FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
-         else FollowTrackInChamber(*track, clusterStore, 13-ich1);
+         FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
          
          iCurrentTrack++;
        }
        
+       // abort tracking if there are too many candidates
+       if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+         AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+         delete segments;
+         return kFALSE;
+       }
+       
       }
       
       // delete the array of segments
@@ -199,18 +212,18 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl
     }
   }
   
-  fRecTracksPtr->Compress(); // this is essential before checking tracks
-  
-  // Keep all different tracks or only the best ones as required
-  if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
-  else RemoveDoubleTracks();
+  // Keep only the best tracks if required
+  if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks();
+  else fRecTracksPtr->Compress();
   
   AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
   
+  return kTRUE;
+  
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore)
 {
   /// Follow tracks in stations(1..) 3, 2 and 1
   AliDebug(1,"Enter FollowTracks");
@@ -243,14 +256,21 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore)
       else Fit(*track, kFALSE, kFALSE, kTRUE);
       
       // remove track with absolute bending momentum out of limits
-      // or if the normalized chi2 is too high
-      Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
-      if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
-         bendingMomentum > GetRecoParam()->GetMaxBendingMomentum() ||
-         track->GetNormalizedChi2() > sigmaCut2) {
+      if (AliMUONTrackExtrap::IsFieldON()) {
+       Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+       if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+           bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) {
+         fRecTracksPtr->Remove(track);
+         fNRecTracks--;
+         continue;
+       }
+      }
+      
+      // remove track if the normalized chi2 is too high
+      if (track->GetNormalizedChi2() > sigmaCut2) {
        fRecTracksPtr->Remove(track);
-       fNRecTracks--;
-       continue;
+       fNRecTracks--;
+       continue;
       }
       
       // save parameters from fit into smoothed parameters to complete track afterward
@@ -330,6 +350,12 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore)
        
       }
       
+      // abort tracking if there are too many candidates
+      if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+       AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+       return kFALSE;
+      }
+      
     }
     
     // Compress fRecTracksPtr for the next step
@@ -403,6 +429,8 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore)
   
   fRecTracksPtr->Compress();
   
+  return kTRUE;
+  
 }
 
   //__________________________________________________________________________
@@ -1079,6 +1107,13 @@ Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, Ali
   // Calculate the track parameter covariance matrix
   Fit(trackCandidate, kFALSE, kFALSE, kTRUE);
   
+  // skip track with absolute bending momentum out of limits
+  if (AliMUONTrackExtrap::IsFieldON()) {
+    Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+    if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+       bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) return kFALSE;
+  }
+  
   // Look for new cluster(s) in next station
   return FollowTrackInStation(trackCandidate,clusterStore,nextStation);
   
@@ -1249,18 +1284,19 @@ void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Doub
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clusterStore)
+Bool_t 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)
-  /// Re-fit track parameters and covariances
+  /// two detection elements, the track may have two clusters in the same chamber).
+  /// Re-fit track parameters and covariances.
+  /// Return kTRUE if one or more tracks have been complemented.
   AliDebug(1,"Enter ComplementTracks");
   
   Int_t chamberId, detElemId;
   Double_t chi2OfCluster, bestChi2OfCluster;
   Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForTracking() *
                        GetRecoParam()->GetSigmaCutForTracking();
-  Bool_t foundOneCluster, trackModified;
+  Bool_t foundOneCluster, trackModified, hasChanged = kFALSE;
   AliMUONVCluster* cluster;
   AliMUONTrackParam *trackParam, *nextTrackParam, copyOfTrackParam, trackParamAtCluster, bestTrackParamAtCluster;
   
@@ -1323,6 +1359,7 @@ void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clu
        bestTrackParamAtCluster.SetRemovable(kTRUE);
        track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
        trackModified = kTRUE;
+       hasChanged = kTRUE;
       }
       
       trackParam = nextTrackParam;
@@ -1334,6 +1371,8 @@ void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clu
     track = (AliMUONTrack*) fRecTracksPtr->After(track);
   }
   
+  return hasChanged;
+  
 }
 
   //__________________________________________________________________________
index 5563fa5..0e0eefe 100644 (file)
@@ -30,10 +30,10 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor
  protected:
 
   // Functions
-  virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
-  virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
-  virtual void FollowTracks(AliMUONVClusterStore& clusterStore);
-  virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
+  virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
+  virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
+  virtual Bool_t FollowTracks(AliMUONVClusterStore& clusterStore);
+  virtual Bool_t ComplementTracks(const AliMUONVClusterStore& clusterStore);
   virtual void ImproveTrack(AliMUONTrack &track);
   virtual void FinalizeTrack(AliMUONTrack &track);
   
index 912cdf4..af722e5 100644 (file)
@@ -65,14 +65,15 @@ AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK()
 } 
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clusterStore)
 {
-  /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
+  /// To make track candidates (assuming linear propagation if AliMUONRecoParam::MakeTrackCandidatesFast() return 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 clusters if both station are requested (two otherwise).
-  /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
+  /// Good candidates are made of at least three clusters if both stations are requested (two otherwise).
+  /// Keep only best candidates or all of them according to the flag AliMUONRecoParam::TrackAllTracks().
   
   TClonesArray *segments;
+  AliMUONObjectPair *segment;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
   Bool_t clusterFound;
@@ -101,82 +102,82 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust
     segments = MakeSegmentsBetweenChambers(clusterStore, 2*istat, 2*istat+1);
     
     // Loop over segments
-    for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
+    for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); iSegment++) {
       AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
+      segment = (AliMUONObjectPair*) segments->UncheckedAt(iSegment);
       
       // Transform segments to tracks and put them at the end of fRecTracksPtr
-      track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]),GetRecoParam()->GetBendingVertexDispersion());
+      track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion());
       fNRecTracks++;
       
       // Look for compatible cluster(s) in the other station
-      if (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, kTRUE);
-       clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
-      }
+      if (GetRecoParam()->MakeTrackCandidatesFast()) clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
+      else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
       
       // Remove track if no cluster found on a requested station
-      if (!clusterFound) {
-       if (GetRecoParam()->RequestStation(7-istat)) {
-          fRecTracksPtr->Remove(track);
-         fNRecTracks--;
-       } else if (istat == 3 && !GetRecoParam()->MakeTrackCandidatesFast()) {
-         // update track parameters and covariances using Kalman filter
-         RetraceTrack(*track, kTRUE);
-       }
+      // or abort tracking if there are too many candidates
+      if (!clusterFound && GetRecoParam()->RequestStation(7-istat)) {
+       fRecTracksPtr->Remove(track);
+       fNRecTracks--;
+      } else if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+       AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+       delete segments;
+       return kFALSE;
       }
       
     }
+    
     // delete the array of segments
     delete segments;
   }
   
+  // Keep all different tracks if required
+  if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
   
-  // Retrace tracks using Kalman filter and remove bad ones
-  if (GetRecoParam()->MakeTrackCandidatesFast()) {
-    fRecTracksPtr->Compress(); // this is essential before checking tracks
+  // Retrace tracks using Kalman filter and select them if needed
+  Int_t nCurrentTracks = fRecTracksPtr->GetLast()+1;
+  for (Int_t iRecTrack = 0; iRecTrack < nCurrentTracks; iRecTrack++) {
+    track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
     
-    Int_t currentNRecTracks = fNRecTracks;
-    for (Int_t iRecTrack = 0; iRecTrack < currentNRecTracks; iRecTrack++) {
-      track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
-      
-      // Recompute track parameters and covariances using Kalman filter
-      RetraceTrack(*track,kTRUE);
-      
-      // Remove the track if the normalized chi2 is too high
-      if (track->GetNormalizedChi2() > GetRecoParam()->GetSigmaCutForTracking() *
-                                      GetRecoParam()->GetSigmaCutForTracking()) {
-        fRecTracksPtr->Remove(track);
-        fNRecTracks--;
+    // skip empty slots
+    if(!track) continue;
+    
+    // retrace tracks using Kalman filter
+    RetraceTrack(*track,kTRUE);
+    
+    // remove tracks with absolute bending momentum out of limits
+    if (GetRecoParam()->MakeTrackCandidatesFast() && AliMUONTrackExtrap::IsFieldON()) {
+      AliMUONTrackParam *trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
+      Double_t bendingMomentum = TMath::Abs(1. / trackParam->GetInverseBendingMomentum());
+      if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) {
+       fRecTracksPtr->Remove(track);
+       fNRecTracks--;
       }
-      
     }
     
   }
   
-  fRecTracksPtr->Compress(); // this is essential before checking tracks
-  
-  // Keep all different tracks or only the best ones as required
-  if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
-  else RemoveDoubleTracks();
+  // Keep only the best tracks if required
+  if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks();
+  else if (GetRecoParam()->MakeTrackCandidatesFast() && AliMUONTrackExtrap::IsFieldON()) fRecTracksPtr->Compress();
   
   AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
   
+  return kTRUE;
+  
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore)
 {
-  /// To make extra track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
+  /// To make extra track candidates assuming linear propagation:
   /// clustering is supposed to be already done
   /// Start with segments made of 1 cluster in each of the stations 4 and 5 then follow track in remaining chambers.
-  /// Good candidates are made of at least three clusters if both station are requested (two otherwise).
+  /// Good candidates are made of at least three clusters if both stations are requested (two otherwise).
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
   
   TClonesArray *segments;
+  AliMUONObjectPair *segment;
   AliMUONTrack *track;
   Int_t iCandidate = 0, iCurrentTrack, nCurrentTracks;
   Int_t initialNRecTracks = fNRecTracks;
@@ -191,19 +192,21 @@ void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& c
       // Make segments between ch1 and ch2
       segments = MakeSegmentsBetweenChambers(clusterStore, ich1, ich2);
       
+      /// Remove segments already attached to a track
+      RemoveUsedSegments(*segments);
+      
       // Loop over segments
-      for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
+      for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); iSegment++) {
        AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
+       segment = (AliMUONObjectPair*) segments->UncheckedAt(iSegment);
        
        // Transform segments to tracks and put them at the end of fRecTracksPtr
        iCurrentTrack = fRecTracksPtr->GetLast()+1;
-       track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]),GetRecoParam()->GetBendingVertexDispersion());
+       track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion());
        fNRecTracks++;
        
        // Look for compatible cluster(s) in the second chamber of station 5
-       if (GetRecoParam()->MakeTrackCandidatesFast())
-         clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
-       else clusterFound = FollowTrackInChamber(*track, clusterStore, 17-ich2);
+       clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
        
        // skip the original track in case it has been removed
        if (GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++;
@@ -214,13 +217,18 @@ void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& c
          track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iCurrentTrack);
          
          // Look for compatible cluster(s) in the second chamber of station 4
-         if (GetRecoParam()->MakeTrackCandidatesFast())
-           FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
-         else FollowTrackInChamber(*track, clusterStore, 13-ich1);
+         FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
          
          iCurrentTrack++;
        }
        
+       // abort tracking if there are too many candidates
+       if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+         AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+         delete segments;
+         return kFALSE;
+       }
+       
       }
       
       // delete the array of segments
@@ -228,35 +236,37 @@ void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& c
     }
   }
   
-  fRecTracksPtr->Compress(); // this is essential before checking tracks
-  
-  // Retrace tracks using Kalman filter
-  for (Int_t iRecTrack = initialNRecTracks; iRecTrack < fNRecTracks; iRecTrack++) {
+  // Retrace tracks using Kalman filter (also compute track chi2) and select them
+  nCurrentTracks = fRecTracksPtr->GetLast()+1;
+  for (Int_t iRecTrack = initialNRecTracks; iRecTrack < nCurrentTracks; iRecTrack++) {
     track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
     
-    // Recompute track parameters and covariances using Kalman filter
+    // skip empty slots
+    if(!track) continue;
+    
+    // retrace tracks using Kalman filter
     RetraceTrack(*track,kTRUE);
     
-    // Remove the track if the normalized chi2 is too high
-    // (only if the tracking has been done without magnetic field)
-    if (GetRecoParam()->MakeTrackCandidatesFast() &&
-       track->GetNormalizedChi2() > GetRecoParam()->GetSigmaCutForTracking() *
-                                    GetRecoParam()->GetSigmaCutForTracking()) {
-      fRecTracksPtr->Remove(track);
-      fNRecTracks--;
+    // remove tracks with absolute bending momentum out of limits
+    if (AliMUONTrackExtrap::IsFieldON()) {
+      AliMUONTrackParam *trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
+      Double_t bendingMomentum = TMath::Abs(1. / trackParam->GetInverseBendingMomentum());
+      if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) {
+       fRecTracksPtr->Remove(track);
+       fNRecTracks--;
+      }
     }
     
   }
   
-  // this is essential before checking tracks
-  if (GetRecoParam()->MakeTrackCandidatesFast()) fRecTracksPtr->Compress();
-  
-  // Keep all different tracks or only the best ones as required
-  if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
-  else RemoveDoubleTracks();
+  // Keep only the best tracks if required
+  if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks();
+  else fRecTracksPtr->Compress();
   
   AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
   
+  return kTRUE;
+  
 }
 
   //__________________________________________________________________________
@@ -304,15 +314,26 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool
     lastParamCov.Zero();
     // Non bending plane
     lastParamCov(0,0) = cluster2->GetErrX2();
-    lastParamCov(1,1) = 100. * ( cluster1->GetErrX2() + cluster2->GetErrX2() ) / dZ / dZ;
+    lastParamCov(0,1) = - cluster2->GetErrX2() / dZ;
+    lastParamCov(1,0) = lastParamCov(0,1);
+    lastParamCov(1,1) = ( 1000. * cluster1->GetErrX2() + cluster2->GetErrX2() ) / dZ / dZ;
     // Bending plane
     lastParamCov(2,2) = cluster2->GetErrY2();
-    lastParamCov(3,3) = 100. * ( cluster1->GetErrY2() + cluster2->GetErrY2() ) / dZ / dZ;
+    lastParamCov(2,3) = - cluster2->GetErrY2() / dZ;
+    lastParamCov(3,2) = lastParamCov(2,3);
+    lastParamCov(3,3) = ( 1000. * cluster1->GetErrY2() + cluster2->GetErrY2() ) / dZ / dZ;
     // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
-    lastParamCov(4,4) = ((GetRecoParam()->GetBendingVertexDispersion() *
-                         GetRecoParam()->GetBendingVertexDispersion() +
-                         (z1 * z1 * cluster2->GetErrY2() + z2 * z2 * cluster1->GetErrY2()) / dZ / dZ) /
-                        bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum;
+    if (AliMUONTrackExtrap::IsFieldON()) {
+      lastParamCov(4,4) = ((GetRecoParam()->GetBendingVertexDispersion() *
+                           GetRecoParam()->GetBendingVertexDispersion() +
+                           (z1 * z1 * cluster2->GetErrY2() + z2 * z2 * 1000. * cluster1->GetErrY2()) / dZ / dZ) /
+                          bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum;
+      lastParamCov(2,4) = z1 * cluster2->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+      lastParamCov(4,2) = lastParamCov(2,4);
+      lastParamCov(3,4) = - (z1 * cluster2->GetErrY2() + z2 * 1000. * cluster1->GetErrY2()) *
+      inverseBendingMomentum / bendingImpact / dZ / dZ;
+      lastParamCov(4,3) = lastParamCov(3,4);
+    } else lastParamCov(4,4) = inverseBendingMomentum*inverseBendingMomentum;
     lastTrackParam->SetCovariances(lastParamCov);
     
     // Reset the track chi2
@@ -401,7 +422,7 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore)
 {
   /// Follow tracks in stations(1..) 3, 2 and 1
   AliDebug(1,"Enter FollowTracks");
@@ -449,6 +470,12 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore
        
       }
       
+      // abort tracking if there are too many candidates
+      if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+       AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+       return kFALSE;
+      }
+      
     }
     
     fRecTracksPtr->Compress(); // this is essential before checking tracks
@@ -458,6 +485,8 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore
     
   }
   
+  return kTRUE;
+  
 }
 
   //__________________________________________________________________________
@@ -550,14 +579,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi
     
     // if good chi2 then consider to add cluster
     if (chi2OfCluster < maxChi2OfCluster) {
-      foundOneCluster = kTRUE;
-      
-      // Printout for debuging
-      if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
-       cout << "FollowTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1
-       << " (Chi2 = " << chi2OfCluster << ")" << endl;
-       cluster->Print();
-      }
       
       if (GetRecoParam()->UseSmoother()) {
        // save extrapolated parameters for smoother
@@ -571,9 +592,21 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi
       addChi2TrackAtCluster = RunKalmanFilter(extrapTrackParamAtCluster);
       
       // skip track with absolute bending momentum out of limits
-      bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster.GetInverseBendingMomentum());
-      if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
-         bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+      if (AliMUONTrackExtrap::IsFieldON()) {
+        bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster.GetInverseBendingMomentum());
+        if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+           bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+      }
+      
+      // remember a cluster was found
+      foundOneCluster = kTRUE;
+      
+      // Printout for debuging
+      if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+       cout << "FollowTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1
+       << " (Chi2 = " << chi2OfCluster << ")" << endl;
+       cluster->Print();
+      }
       
       if (GetRecoParam()->TrackAllTracks()) {
        // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
@@ -737,15 +770,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     
     // 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 cluster in chamber(1..): " << ch2+1
-            << " (Chi2 = " << chi2OfCluster << ")" << endl;
-       clusterCh2->Print();
-        cout << "                      look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
-      }
       
       if (GetRecoParam()->UseSmoother()) {
         // save extrapolated parameters for smoother
@@ -759,10 +783,20 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
       addChi2TrackAtCluster2 = RunKalmanFilter(extrapTrackParamAtCluster2);
       
       // skip track with absolute bending momentum out of limits
-      bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster2.GetInverseBendingMomentum());
-      if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
-         bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
-       
+      if (AliMUONTrackExtrap::IsFieldON()) {
+       bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster2.GetInverseBendingMomentum());
+       if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+           bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+      }
+      
+      // Printout for debuging
+      if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+        cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1
+       << " (Chi2 = " << chi2OfCluster << ")" << endl;
+       clusterCh2->Print();
+        cout << "                      look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
+      }
+      
       // copy new track parameters for next step
       extrapTrackParam = extrapTrackParamAtCluster2;
       
@@ -781,6 +815,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
       iCluster1 = -1;
       
       // look for second candidates in chamber 1
+      Bool_t foundSecondCluster = kFALSE;
       while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
        iCluster1++;
        
@@ -793,15 +828,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
        
        // 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 cluster in chamber(1..): " << ch1+1
-                << " (Chi2 = " << chi2OfCluster << ")" << endl;
-           clusterCh1->Print();
-         }
           
           if (GetRecoParam()->UseSmoother()) {
             // save extrapolated parameters for smoother
@@ -815,9 +841,22 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
           addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1);
           
          // skip track with absolute bending momentum out of limits
-         bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
-         if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
-             bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+         if (AliMUONTrackExtrap::IsFieldON()) {
+           bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
+           if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+               bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+         }
+         
+         // remember a second cluster was found
+         foundSecondCluster = kTRUE;
+         foundTwoClusters = kTRUE;
+          
+         // Printout for debuging
+         if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+           cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
+           << " (Chi2 = " << chi2OfCluster << ")" << endl;
+           clusterCh1->Print();
+         }
          
          if (GetRecoParam()->TrackAllTracks()) {
            // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
@@ -825,10 +864,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
            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 clusterCh1 as used
            clusterCh1Used[iCluster1] = kTRUE;
            
@@ -852,6 +887,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
       
       // if no clusterCh1 found then consider to add clusterCh2 only
       if (!foundSecondCluster) {
+       
+       // remember a cluster was found
        foundOneCluster = kTRUE;
         
        if (GetRecoParam()->TrackAllTracks()) {
@@ -860,10 +897,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          UpdateTrack(*newTrack,extrapTrackParamAtCluster2,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);
-         
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
            cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl;
@@ -925,14 +958,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
       // 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 cluster in chamber(1..): " << ch1+1
-              << " (Chi2 = " << chi2OfCluster << ")" << endl;
-         clusterCh1->Print();
-       }
         
        if (GetRecoParam()->UseSmoother()) {
           // save extrapolated parameters for smoother
@@ -946,9 +971,21 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
         addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1);
         
        // skip track with absolute bending momentum out of limits
-       bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
-       if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
-           bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+       if (AliMUONTrackExtrap::IsFieldON()) {
+         bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
+         if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+             bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue;
+       }
+       
+       // remember a cluster was found
+       foundOneCluster = kTRUE;
+       
+       // Printout for debuging
+       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+         cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
+         << " (Chi2 = " << chi2OfCluster << ")" << endl;
+         clusterCh1->Print();
+       }
        
        if (GetRecoParam()->TrackAllTracks()) {
          // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
@@ -956,10 +993,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          UpdateTrack(*newTrack,extrapTrackParamAtCluster1,addChi2TrackAtCluster1);
          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);
-         
          // Printout for debuging
          if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
            cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl;
@@ -983,10 +1016,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     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)
-      if (nextStation == 4) RetraceTrack(trackCandidate,kTRUE);
-      
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
         cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
@@ -996,10 +1025,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     } 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)
-      if (nextStation == 4) RetraceTrack(trackCandidate,kTRUE);
-      
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
         cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
@@ -1208,9 +1233,11 @@ Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Al
   RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1));
   
   // skip track with absolute bending momentum out of limits
-  Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
-  if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
-      bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) return kFALSE;
+  if (AliMUONTrackExtrap::IsFieldON()) {
+    Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+    if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+       bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) return kFALSE;
+  }
   
   // Look for new cluster(s) in next station
   return FollowTrackInStation(trackCandidate, clusterStore, nextStation);
@@ -1314,18 +1341,19 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track)
 }
 
   //__________________________________________________________________________
-void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& clusterStore)
+Bool_t 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)
-  /// Recompute track parameters and covariances at each clusters
+  /// two detection elements, the track may have two clusters in the same chamber).
+  /// Recompute track parameters and covariances at each clusters.
+  /// Return kTRUE if one or more tracks have been complemented.
   AliDebug(1,"Enter ComplementTracks");
   
   Int_t chamberId, detElemId;
   Double_t chi2OfCluster, addChi2TrackAtCluster, bestAddChi2TrackAtCluster;
   Double_t maxChi2OfCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() *
                                   GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
-  Bool_t foundOneCluster, trackModified;
+  Bool_t foundOneCluster, trackModified, hasChanged = kFALSE;
   AliMUONVCluster *cluster;
   AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam, trackParamAtCluster, bestTrackParamAtCluster;
   
@@ -1396,6 +1424,7 @@ void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& cl
        bestTrackParamAtCluster.SetRemovable(kTRUE);
        track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
        trackModified = kTRUE;
+       hasChanged = kTRUE;
       }
       
       previousTrackParam = trackParam;
@@ -1408,6 +1437,8 @@ void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& cl
     track = (AliMUONTrack*) fRecTracksPtr->After(track);
   }
   
+  return hasChanged;
+  
 }
 
 //__________________________________________________________________________
@@ -1538,6 +1569,7 @@ void AliMUONTrackReconstructorK::FinalizeTrack(AliMUONTrack &track)
 Bool_t AliMUONTrackReconstructorK::RefitTrack(AliMUONTrack &track, Bool_t enableImprovement)
 {
   /// re-fit the given track
+  AliDebug(1,"Enter RefitTrack");
   
   // check validity of the track
   if (track.GetNClusters() < 3) {
index 3891cb9..49bef9b 100644 (file)
@@ -29,10 +29,10 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor
  protected:
 
   // Functions
-  virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
-  virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
-  virtual void FollowTracks(AliMUONVClusterStore& clusterStore);
-  virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
+  virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
+  virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
+  virtual Bool_t FollowTracks(AliMUONVClusterStore& clusterStore);
+  virtual Bool_t ComplementTracks(const AliMUONVClusterStore& clusterStore);
   virtual void ImproveTrack(AliMUONTrack &track);
   virtual void FinalizeTrack(AliMUONTrack &track);
   
index 1acb43f..3043abc 100644 (file)
@@ -219,11 +219,9 @@ Int_t AliMUONTracker::Clusters2Tracks(AliESDEvent* esd)
     fTrackReco->EventReconstructTrigger(*fkTriggerCircuit,*fTriggerStore,*(TriggerTrackStore()));
   }
   
-  if ( ( GetRecoParam()->BypassSt4() || 
-                                GetRecoParam()->BypassSt5() ) && 
-                       TriggerTrackStore()->GetSize() > 5 ) 
+  if ( TriggerTrackStore()->GetSize() > GetRecoParam()->GetMaxTriggerTracks() ) 
   {
-    // Hard cut to reject shower events
+    // cut to reject shower events
     
     AliCodeTimerAuto("MUON Shower events");
 
index 902bb86..f80e016 100644 (file)
@@ -138,20 +138,24 @@ void AliMUONVTrackReconstructor::EventReconstruct(AliMUONVClusterStore& clusterS
   // Reset array of tracks
   ResetTracks();
   
-  // Look for candidates from clusters in stations(1..) 4 and 5
-  MakeTrackCandidates(clusterStore);
+  // Look for candidates from clusters in stations(1..) 4 and 5 (abort in case of failure)
+  if (!MakeTrackCandidates(clusterStore)) return;
   
-  // Look for extra candidates from clusters in stations(1..) 4 and 5
-  if (GetRecoParam()->MakeMoreTrackCandidates()) MakeMoreTrackCandidates(clusterStore);
+  // Look for extra candidates from clusters in stations(1..) 4 and 5 (abort in case of failure)
+  if (GetRecoParam()->MakeMoreTrackCandidates()) {
+    if (!MakeMoreTrackCandidates(clusterStore)) return;
+  }
   
   // Stop tracking if no candidate found
   if (fRecTracksPtr->GetEntriesFast() == 0) return;
   
-  // Follow tracks in stations(1..) 3, 2 and 1
-  FollowTracks(clusterStore);
+  // Follow tracks in stations(1..) 3, 2 and 1 (abort in case of failure)
+  if (!FollowTracks(clusterStore)) return;
   
   // Complement the reconstructed tracks
-  if (GetRecoParam()->ComplementTracks()) ComplementTracks(clusterStore);
+  if (GetRecoParam()->ComplementTracks()) {
+    if (ComplementTracks(clusterStore)) RemoveIdenticalTracks();
+  }
   
   // Improve the reconstructed tracks
   if (GetRecoParam()->ImproveTracks()) ImproveTracks();
@@ -252,22 +256,85 @@ TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsBetweenChambers(const AliM
 }
 
   //__________________________________________________________________________
+void AliMUONVTrackReconstructor::RemoveUsedSegments(TClonesArray& segments)
+{
+  /// To remove pairs of clusters already attached to a track
+  AliDebug(1,"Enter RemoveUsedSegments");
+  Int_t nSegments = segments.GetEntriesFast();
+  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
+  AliMUONObjectPair *segment;
+  AliMUONTrack *track;
+  AliMUONVCluster *cluster, *cluster1, *cluster2;
+  Bool_t foundCluster1, foundCluster2, removeSegment;
+  
+  // Loop over segments
+  for (Int_t iSegment=0; iSegment<nSegments; iSegment++) {
+    segment = (AliMUONObjectPair*) segments.UncheckedAt(iSegment);
+    
+    cluster1 = (AliMUONVCluster*) segment->First();
+    cluster2 = (AliMUONVCluster*) segment->Second();
+    removeSegment = kFALSE;
+    
+    // Loop over tracks
+    for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+      track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack);
+      
+      // skip empty slot
+      if (!track) continue;
+      
+      foundCluster1 = kFALSE;
+      foundCluster2 = kFALSE;
+      
+      // Loop over clusters
+      Int_t nClusters = track->GetNClusters();
+      for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+        cluster = ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
+       
+       // check if both clusters are in that track
+       if (cluster == cluster1) foundCluster1 = kTRUE;
+       else if (cluster == cluster2) foundCluster2 = kTRUE;
+       
+       if (foundCluster1 && foundCluster2) {
+         removeSegment = kTRUE;
+         break;
+       }
+       
+      }
+      
+      if (removeSegment) break;
+      
+    }
+    
+    if (removeSegment) segments.RemoveAt(iSegment);
+      
+  }
+  
+  segments.Compress();
+  
+  // Printout for debug
+  AliDebug(1,Form("NSegments =  %d ", segments.GetEntriesFast()));
+}
+
+  //__________________________________________________________________________
 void AliMUONVTrackReconstructor::RemoveIdenticalTracks()
 {
   /// To remove identical tracks:
   /// 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;
+  AliMUONTrack *track1, *track2;
+  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
   Int_t clustersInCommon, nClusters1, nClusters2;
-  Bool_t removedTrack1;
   // Loop over first track of the pair
-  track1 = (AliMUONTrack*) fRecTracksPtr->First();
-  while (track1) {
-    removedTrack1 = kFALSE;
+  for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
+    track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
+    // skip empty slot
+    if (!track1) continue;
     nClusters1 = track1->GetNClusters();
     // Loop over second track of the pair
-    track2 = (AliMUONTrack*) fRecTracksPtr->After(track1);
-    while (track2) {
+    for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
+      track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
+      // skip empty slot
+      if (!track2) continue;
       nClusters2 = track2->GetNClusters();
       // number of clusters in common between two tracks
       clustersInCommon = track1->ClustersInCommon(track2);
@@ -276,27 +343,18 @@ void AliMUONVTrackReconstructor::RemoveIdenticalTracks()
         // decide which track to remove
         if (nClusters2 > nClusters1) {
          // remove track1 and continue the first loop with the track next to track1
-         trackToRemove = track1;
-         track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
-          fRecTracksPtr->Remove(trackToRemove);
-         fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+          fRecTracksPtr->RemoveAt(iTrack1);
          fNRecTracks--;
-         removedTrack1 = kTRUE;
          break;
        } else {
          // remove track2 and continue the second loop with the track next to track2
-         trackToRemove = track2;
-         track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
-         fRecTracksPtr->Remove(trackToRemove);
-         fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+         fRecTracksPtr->RemoveAt(iTrack2);
          fNRecTracks--;
         }
-      } else track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
+      }
     } // track2
-    if (removedTrack1) continue;
-    track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
   } // track1
-  return;
+  fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
 }
 
   //__________________________________________________________________________
@@ -307,46 +365,40 @@ void AliMUONVTrackReconstructor::RemoveDoubleTracks()
   /// 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 clustersInCommon, nClusters1, nClusters2;
-  Bool_t removedTrack1;
+  AliMUONTrack *track1, *track2;
+  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
+  Int_t clustersInCommon2, nClusters1, nClusters2;
   // Loop over first track of the pair
-  track1 = (AliMUONTrack*) fRecTracksPtr->First();
-  while (track1) {
-    removedTrack1 = kFALSE;
+  for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
+    track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
+    // skip empty slot
+    if (!track1) continue;
     nClusters1 = track1->GetNClusters();
     // Loop over second track of the pair
-    track2 = (AliMUONTrack*) fRecTracksPtr->After(track1);
-    while (track2) {
+    for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
+      track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
+      // skip empty slot
+      if (!track2) continue;
       nClusters2 = track2->GetNClusters();
       // number of clusters in common between two tracks
-      clustersInCommon = track1->ClustersInCommon(track2);
+      clustersInCommon2 = 2 * track1->ClustersInCommon(track2);
       // check for identical tracks
-      if (((nClusters1 < nClusters2) && (2 * clustersInCommon > nClusters1)) || (2 * clustersInCommon > nClusters2)) {
+      if (clustersInCommon2 > nClusters1 || clustersInCommon2 > nClusters2) {
         // decide which track to remove
         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);
-         fRecTracksPtr->Remove(trackToRemove);
-         fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+         fRecTracksPtr->RemoveAt(iTrack2);
          fNRecTracks--;
         } else {
          // else remove track1 and continue the first loop with the track next to track1
-         trackToRemove = track1;
-         track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
-          fRecTracksPtr->Remove(trackToRemove);
-         fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+          fRecTracksPtr->RemoveAt(iTrack1);
          fNRecTracks--;
-         removedTrack1 = kTRUE;
          break;
         }
-      } else track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
+      }
     } // track2
-    if (removedTrack1) continue;
-    track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
   } // track1
-  return;
+  fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
 }
 
   //__________________________________________________________________________
@@ -370,7 +422,8 @@ void AliMUONVTrackReconstructor::RemoveConnectedTracks(Bool_t inSt345)
     while (track2) {
       nClusters2 = track2->GetNClusters();
       // number of clusters in common between two tracks
-      clustersInCommon = track1->ClustersInCommon(track2, inSt345);
+      if (inSt345) clustersInCommon = track1->ClustersInCommonInSt345(track2);
+      else clustersInCommon = track1->ClustersInCommon(track2);
       // check for identical tracks
       if (clustersInCommon > 0) {
         // decide which track to remove
@@ -618,6 +671,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInChamber(AliMUONTrack &trac
          extrapTrackParamAtCluster.SetRemovable(kFALSE);
        else extrapTrackParamAtCluster.SetRemovable(kTRUE);
        newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster,*cluster);
+       newTrack->SetGlobalChi2(trackCandidate.GetGlobalChi2()+chi2WithOneCluster);
        fNRecTracks++;
        
        // Printout for debuging
@@ -643,6 +697,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInChamber(AliMUONTrack &trac
        bestTrackParamAtCluster.SetRemovable(kFALSE);
       else bestTrackParamAtCluster.SetRemovable(kTRUE);
       trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
+      trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithOneCluster);
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
@@ -794,6 +849,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
            newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
            extrapTrackParamAtCluster2.SetRemovable(kTRUE);
            newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
+           newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithTwoClusters);
            fNRecTracks++;
            
            // Tag clusterCh1 as used
@@ -827,6 +883,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
            extrapTrackParamAtCluster2.SetRemovable(kFALSE);
          else extrapTrackParamAtCluster2.SetRemovable(kTRUE);
          newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
+         newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithOneCluster);
          fNRecTracks++;
          
          // Printout for debuging
@@ -899,6 +956,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
            extrapTrackParamAtCluster1.SetRemovable(kFALSE);
          else extrapTrackParamAtCluster1.SetRemovable(kTRUE);
          newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
+         newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithOneCluster);
          fNRecTracks++;
          
          // Printout for debuging
@@ -926,6 +984,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
       trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
       bestTrackParamAtCluster2.SetRemovable(kTRUE);
       trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster2,*(bestTrackParamAtCluster2.GetClusterPtr()));
+      trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithTwoClusters);
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
@@ -938,6 +997,7 @@ Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trac
        bestTrackParamAtCluster1.SetRemovable(kFALSE);
       else bestTrackParamAtCluster1.SetRemovable(kTRUE);
       trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
+      trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithOneCluster);
       
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
index 61fbcb2..84515d9 100644 (file)
@@ -69,13 +69,13 @@ class AliMUONVTrackReconstructor : public TObject {
   AliMUONVTrackReconstructor& operator=(const AliMUONVTrackReconstructor& rhs); ///< assignment operator
   
   /// Make track candidates from clusters in stations(1..) 4 and 5
-  virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
+  virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
   /// Make extra track candidates from clusters in stations(1..) 4 and 5
-  virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
+  virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
   /// Follow tracks in stations(1..) 3, 2 and 1
-  virtual void FollowTracks(AliMUONVClusterStore& clusterStore) = 0;
+  virtual Bool_t FollowTracks(AliMUONVClusterStore& clusterStore) = 0;
   /// Complement the reconstructed tracks
-  virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore) = 0;
+  virtual Bool_t ComplementTracks(const AliMUONVClusterStore& clusterStore) = 0;
   void ImproveTracks();
   /// Improve the given reconstructed track
   virtual void ImproveTrack(AliMUONTrack &track) = 0;
@@ -85,6 +85,7 @@ class AliMUONVTrackReconstructor : public TObject {
   
   TClonesArray* MakeSegmentsBetweenChambers(const AliMUONVClusterStore& clusterStore, Int_t ch1, Int_t ch2);
 
+  void RemoveUsedSegments(TClonesArray& segments);
   void RemoveIdenticalTracks();
   void RemoveDoubleTracks();
   void RemoveConnectedTracks(Bool_t inSt345 = kFALSE);
index 42838a8..7d17927 100644 (file)
@@ -351,8 +351,6 @@ Bool_t MUONefficiency( char* filename = "galice.root", char* geoFilename = "geom
       cout << " number of tracks: " << nTracks  <<endl;
     }
 
-    // set the magnetic field for track extrapolations
-    AliMUONTrackExtrap::SetField();
     // loop over all reconstructed tracks (also first track of combination)
     for (Int_t iTrack = 0; iTrack <  nTracks;  iTrack++) {
 
@@ -601,14 +599,15 @@ Bool_t MUONefficiency( char* filename = "galice.root", char* geoFilename = "geom
   cout << "PtCutMin for muon tracks = " << PtCutMin << endl;
   cout << "PtCutMax for muon tracks = " << PtCutMax << endl;
   
-  hInvMassAll->Fit("gaus","q0");
-                   
-  TF1* f1 = hInvMassAll->GetFunction("gaus");
+  cout << "Entries (unlike sign dimuons) : " << hInvMassAll->GetEntries();
   
-  cout << "Entries (unlike sign dimuons) : " << hInvMassAll->GetEntries() 
-    << Form(". Rough sigma = %7.2f MeV/c2",f1->GetParameter(2)*1000.0) << endl;
+  if (hInvMassAll->GetEntries() > 0) {
+    hInvMassAll->Fit("gaus","q0");
+    TF1* f1 = hInvMassAll->GetFunction("gaus");
+    cout << Form(". Rough sigma = %7.2f MeV/c2",f1->GetParameter(2)*1000.0);
+  }
   
-  cout << "Entries (unlike sign dimuons) in the mass range  ["<<invMassMinInPeak<<";"<<invMassMaxInPeak<<"] : " << EventInMass <<endl;
+  cout << endl << "Entries (unlike sign dimuons) in the mass range  ["<<invMassMinInPeak<<";"<<invMassMaxInPeak<<"] : " << EventInMass <<endl;
   
   if (ptTrig==0x800) cout << "Unlike Pair - All Pt" ;   
   if (ptTrig==0x400) cout << "Unlike Pair - High Pt" ;   
index 1d194d9..8720798 100644 (file)
@@ -77,22 +77,13 @@ void runDataReconstruction(const char* input = "/Users/laurent/Alice/Data/Raw/09
   AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetCosmicParam();
   
   // digit selection
-  muonRecoParam->SetPadGoodnessMask(0x400BE80);
   TString caliboption = caliboption1;
   if ( calib == 2 ) caliboption = caliboption2;
   muonRecoParam->SetCalibrationMode(caliboption.Data());
   
-  // chamber resolution (incuding misalignment)
-  for (Int_t iCh=0; iCh<10; iCh++) {
-    muonRecoParam->SetDefaultNonBendingReso(iCh,0.4);
-    muonRecoParam->SetDefaultBendingReso(iCh,0.4);
-  }
-  muonRecoParam->SetMaxNonBendingDistanceToTrack(10.);
-  muonRecoParam->SetMaxBendingDistanceToTrack(10.);
-  
   // cut on (non)bending slopes
-  //muonRecoParam->SetMaxNonBendingSlope(0.6);
-  //muonRecoParam->SetMaxBendingSlope(0.6);
+  muonRecoParam->SetMaxNonBendingSlope(0.6);
+  muonRecoParam->SetMaxBendingSlope(0.6);
   
   // tracking algorithm
   muonRecoParam->MakeMoreTrackCandidates(kTRUE);
@@ -100,8 +91,6 @@ void runDataReconstruction(const char* input = "/Users/laurent/Alice/Data/Raw/09
   muonRecoParam->RequestStation(2, kFALSE);
   muonRecoParam->RequestStation(3, kFALSE);
   muonRecoParam->RequestStation(4, kFALSE);
-  muonRecoParam->SetSigmaCutForTracking(7.);
-  muonRecoParam->ImproveTracks(kTRUE, 7.);
   
   muonRecoParam->Print("FULL");
   
index efbfc3b..e7ebd5c 100644 (file)
Binary files a/OCDB/MUON/Calib/RecoParam/Run0_999999999_v0_s0.root and b/OCDB/MUON/Calib/RecoParam/Run0_999999999_v0_s0.root differ