]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
- Added new option (AliMUONVTrackReconstructor::fgkComplementTracks) to add
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 27 Sep 2007 16:03:30 +0000 (16:03 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 27 Sep 2007 16:03:30 +0000 (16:03 +0000)
  potentially missing clusters to the reconstructed tracks.
  (This can happen when muons hit 2 detection elements within the same chamber,
  because they overlap).
- Modified the option ImproveTracks() to remove bad tracks.
- Added timer info to monitor the tracking algorithm.
(Philippe P.)

MUON/AliMUONTrack.cxx
MUON/AliMUONTrackParam.cxx
MUON/AliMUONTrackParam.h
MUON/AliMUONTrackReconstructor.cxx
MUON/AliMUONTrackReconstructor.h
MUON/AliMUONTrackReconstructorK.cxx
MUON/AliMUONTrackReconstructorK.h
MUON/AliMUONVTrackReconstructor.cxx
MUON/AliMUONVTrackReconstructor.h

index 79ad92d675c0e315394d659a7ee503ab7ada8f85..066967b5c8163fe97faf7c0da0b32712d27775eb 100644 (file)
@@ -504,7 +504,7 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
   if (accountForMCS) { // Compute local chi2 taking into account multiple scattering effects
       
     // Compute MCS covariance matrix only once
-    TMatrixD mcsCovariances(AliMUONConstants::NTrackingCh(),AliMUONConstants::NTrackingCh());
+    TMatrixD mcsCovariances(fNTrackHits,fNTrackHits);
     ComputeMCSCovariances(mcsCovariances);
     
     // Make sure hit weights are consistent with following calculations
@@ -600,7 +600,6 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
   
   }
   
-  
   return kTRUE;
   
 }
@@ -624,14 +623,12 @@ Double_t AliMUONTrack::ComputeGlobalChi2(Bool_t accountForMCS)
   
   if (accountForMCS) {
     
-    // Check the weight matrices
-    Bool_t weightsAvailable = kTRUE;
-    if (!fHitWeightsNonBending || !fHitWeightsBending) weightsAvailable = kFALSE;
-    else if (fHitWeightsNonBending->GetNrows() != fNTrackHits || fHitWeightsNonBending->GetNcols() != fNTrackHits ||
-            fHitWeightsBending->GetNrows()    != fNTrackHits || fHitWeightsBending->GetNcols()    != fNTrackHits) weightsAvailable = kFALSE;
-    
-    // if weight matrices are not available compute chi2 without MCS
-    if (!weightsAvailable) {
+    // 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");
+      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");
       return ComputeGlobalChi2(kFALSE);
     }
@@ -714,19 +711,9 @@ Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeig
   // Check MCS covariance matrix and recompute it if need
   Bool_t deleteMCSCov = kFALSE;
   if (!mcsCovariances) {
-    
-    // build MCS covariance matrix
-    mcsCovariances = new TMatrixD(AliMUONConstants::NTrackingCh(),AliMUONConstants::NTrackingCh());
+    mcsCovariances = new TMatrixD(fNTrackHits,fNTrackHits);
     deleteMCSCov = kTRUE;
     ComputeMCSCovariances(*mcsCovariances);
-    
-  } else {
-    
-    // check MCS covariance matrix size
-    if (mcsCovariances->GetNrows() != AliMUONConstants::NTrackingCh() || mcsCovariances->GetNcols() != AliMUONConstants::NTrackingCh()) {
-      ComputeMCSCovariances(*mcsCovariances);
-    }
-    
   }
   
   // Resize the weights matrices; alocate memory
@@ -740,7 +727,7 @@ Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeig
   
   // Define variables
   AliMUONHitForRec *hitForRec1, *hitForRec2;
-  Int_t chamber1, chamber2, currentHitNumber1, currentHitNumber2;
+  Int_t currentHitNumber1, currentHitNumber2;
   
   // Compute the covariance matrices
   currentHitNumber1 = 0;
@@ -749,8 +736,6 @@ Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeig
     
     if (hitForRec1 == discardedHit) continue;
     
-    chamber1 = hitForRec1->GetChamberNumber();
-    
     // Loop over next hits
     currentHitNumber2 = currentHitNumber1;
     for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) {
@@ -758,10 +743,8 @@ Bool_t AliMUONTrack::ComputeHitWeights(TMatrixD& hitWeightsNB, TMatrixD& hitWeig
       
       if (hitForRec2 == discardedHit) continue;
       
-      chamber2 = hitForRec2->GetChamberNumber();
-    
       // Fill with MCS covariances
-      hitWeightsNB(currentHitNumber1, currentHitNumber2) = (*mcsCovariances)(chamber1,chamber2);
+      hitWeightsNB(currentHitNumber1, currentHitNumber2) = (*mcsCovariances)(hitNumber1,hitNumber2);
       
       // Equal contribution from multiple scattering in non bending and bending directions
       hitWeightsB(currentHitNumber1, currentHitNumber2) = hitWeightsNB(currentHitNumber1, currentHitNumber2);
@@ -811,32 +794,23 @@ 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
-  /// - Return kFALSE if computation failed
+  /// (assume that track parameters at each hit are corrects)
   
-  // Make sure the size of the covariance matrix is correct
-  Int_t nChambers = AliMUONConstants::NTrackingCh();
-  mcsCovariances.ResizeTo(nChambers,nChambers);
-  
-  // check for too many track hits
-  if (fNTrackHits > nChambers) {
-    AliWarning("more than 1 hit per chamber!!");
-    mcsCovariances.Zero();
-    return;
-  }
+  // Reset the size of the covariance matrix if needed
+  if (mcsCovariances.GetNrows() != fNTrackHits) mcsCovariances.ResizeTo(fNTrackHits,fNTrackHits);
   
   // Define variables
+  Int_t nChambers = AliMUONConstants::NTrackingCh();
   AliMUONTrackParam* trackParamAtHit;
   AliMUONHitForRec *hitForRec;
   AliMUONTrackParam extrapTrackParam;
-  Int_t currentChamber, expectedChamber;
-  Double_t *mcsAngle2 = new Double_t[nChambers];
-  Double_t *zMCS = new Double_t[nChambers];
+  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];
   
   // Compute multiple scattering dispersion angle at each chamber
   // and save the z position where it is calculated
-  currentChamber = 0;
-  expectedChamber = 0;
   for (Int_t hitNumber = 0; hitNumber < fNTrackHits; hitNumber++) {
     trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(hitNumber);
     hitForRec = trackParamAtHit->GetHitForRecPtr();
@@ -846,7 +820,7 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const
     while (currentChamber > expectedChamber) {
       
       // Save the z position where MCS dispersion is calculated
-      zMCS[expectedChamber] = AliMUONConstants::DefaultChamberZ(expectedChamber);
+      zMCS[size] = AliMUONConstants::DefaultChamberZ(expectedChamber);
       
       // Do not take into account MCS in chambers prior the first hit
       if (hitNumber > 0) {
@@ -856,47 +830,52 @@ void AliMUONTrack::ComputeMCSCovariances(TMatrixD& mcsCovariances) const
         AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, zMCS[expectedChamber]);
         
         // Save multiple scattering dispersion angle in missing chamber
-        mcsAngle2[expectedChamber] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
+        mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
         
-      } else mcsAngle2[expectedChamber] = 0.;
+      } else mcsAngle2[size] = 0.;
       
       expectedChamber++;
+      size++;
     }
     
     // Save z position where MCS dispersion is calculated
-    zMCS[currentChamber] = trackParamAtHit->GetZ();
+    zMCS[size] = trackParamAtHit->GetZ();
     
     // Save multiple scattering dispersion angle in current chamber
-    mcsAngle2[currentChamber] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.);
+    mcsAngle2[size] = AliMUONTrackExtrap::GetMCSAngle2(*trackParamAtHit,AliMUONConstants::ChamberThicknessInX0(),1.);
+    
+    // Save indice in zMCS array corresponding to the current cluster
+    indices[hitNumber] = size;
     
-    expectedChamber++;
+    expectedChamber = currentChamber + 1;
+    size++;
   }
   
   // complete array of z if last hit is on the last but one chamber
-  if (currentChamber != nChambers-1) zMCS[nChambers-1] = AliMUONConstants::DefaultChamberZ(nChambers-1);
-  
+  if (currentChamber != nChambers-1) zMCS[size++] = AliMUONConstants::DefaultChamberZ(nChambers-1);
   
   // Compute the covariance matrix
-  for (Int_t chamber1 = 0; chamber1 < nChambers; chamber1++) { 
+  for (Int_t hitNumber1 = 0; hitNumber1 < fNTrackHits; hitNumber1++) { 
     
-    for (Int_t chamber2 = chamber1; chamber2 < nChambers; chamber2++) {
+    for (Int_t hitNumber2 = hitNumber1; hitNumber2 < fNTrackHits; hitNumber2++) {
       
       // Initialization to 0 (diagonal plus upper triangular part)
-      mcsCovariances(chamber1, chamber2) = 0.;
+      mcsCovariances(hitNumber1,hitNumber2) = 0.;
       
       // Compute contribution from multiple scattering in upstream chambers
-      for (currentChamber = 0; currentChamber < chamber1; currentChamber++) {  
-       mcsCovariances(chamber1, chamber2) += (zMCS[chamber1] - zMCS[currentChamber]) * (zMCS[chamber2] - zMCS[currentChamber]) * mcsAngle2[currentChamber];
+      for (Int_t k = 0; k < indices[hitNumber1]; k++) {        
+       mcsCovariances(hitNumber1,hitNumber2) += (zMCS[indices[hitNumber1]] - zMCS[k]) * (zMCS[indices[hitNumber2]] - zMCS[k]) * mcsAngle2[k];
       }
       
       // Symetrize the matrix
-      mcsCovariances(chamber2, chamber1) = mcsCovariances(chamber1, chamber2);
+      mcsCovariances(hitNumber2,hitNumber1) = mcsCovariances(hitNumber1,hitNumber2);
     }
     
   }
     
   delete [] mcsAngle2;
   delete [] zMCS;
+  delete [] indices;
   
 }
 
index 9506d704d9b4319caa21883fc97a5217242ba311..c67058fe58042104ebb9d4ef44e98992da15796e 100644 (file)
@@ -48,6 +48,7 @@ AliMUONTrackParam::AliMUONTrackParam()
     fSmoothCovariances(0x0),
     fHitForRecPtr(0x0),
     fRemovable(kFALSE),
+    fAloneInChamber(kTRUE),
     fTrackChi2(0.),
     fLocalChi2(0.)
 {
@@ -67,6 +68,7 @@ AliMUONTrackParam::AliMUONTrackParam(const AliMUONTrackParam& theMUONTrackParam)
     fSmoothCovariances(0x0),
     fHitForRecPtr(theMUONTrackParam.fHitForRecPtr),
     fRemovable(theMUONTrackParam.fRemovable),
+    fAloneInChamber(theMUONTrackParam.fAloneInChamber),
     fTrackChi2(theMUONTrackParam.fTrackChi2),
     fLocalChi2(theMUONTrackParam.fLocalChi2)
 {
@@ -145,6 +147,8 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   
   fRemovable = theMUONTrackParam.fRemovable;
   
+  fAloneInChamber = theMUONTrackParam.fAloneInChamber;
+  
   fTrackChi2 = theMUONTrackParam.fTrackChi2;
   fLocalChi2 = theMUONTrackParam.fLocalChi2;
   
index 5e811e8cf9f1ee4b329f6427d47f9cfdf664ba61..9dd8a7f0440014026b266e3c2f145d2dc50aa6ee 100644 (file)
@@ -113,7 +113,12 @@ class AliMUONTrackParam : public TObject
        /// set the flag telling whether the associated hit can be removed from the track it belongs to or not
   void   SetRemovable(Bool_t removable) {fRemovable = removable;}
   
-       /// return the chi2 of the track when the associated HitForRec was attached
+       /// return kTRUE if the associated hit 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
   Double_t GetTrackChi2() const {return fTrackChi2;}
        /// set the chi2 of the track when the associated HitForRec was attached
   void     SetTrackChi2(Double_t chi2) {fTrackChi2 = chi2;}
@@ -161,6 +166,8 @@ class AliMUONTrackParam : public TObject
   
   Bool_t fRemovable; //!< kTRUE if the associated hit can be removed from the track it belongs to
   
+  Bool_t fAloneInChamber; //!< kTRUE if the associated hit 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
   
index 17f826e6e7eb11db90e3c6be83b004081098d0ec..74a9f20081280b7aa344881f7e951089d2873f6a 100644 (file)
@@ -33,6 +33,7 @@
 #include "AliMUONTrack.h"
 #include "AliMUONTrackParam.h"
 #include "AliMUONTrackExtrap.h"
+
 #include "AliLog.h"
 
 #include <TMinuit.h>
@@ -73,6 +74,7 @@ void AliMUONTrackReconstructor::MakeTrackCandidates()
   /// 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.
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
+  
   TClonesArray *segments;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
@@ -135,6 +137,7 @@ void AliMUONTrackReconstructor::FollowTracks()
   AliDebug(1,"Enter FollowTracks");
   
   AliMUONTrack *track, *nextTrack;
+  AliMUONTrackParam *trackParam, *nextTrackParam;
   Int_t currentNRecTracks;
   Bool_t hitFound;
   
@@ -167,6 +170,51 @@ void AliMUONTrackReconstructor::FollowTracks()
        continue;
       }
       
+      // save parameters from fit into smoothed parameters to complete track afterward
+      if (fgkComplementTracks) {
+       
+       if (station==2) { // save track parameters on stations 4 and 5
+         
+         // extrapolate track parameters and covariances at each cluster
+         track->UpdateCovTrackParamAtHit();
+         
+         // save them
+         trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First();
+         while (trackParam) {
+           trackParam->SetSmoothParameters(trackParam->GetParameters());
+           trackParam->SetSmoothCovariances(trackParam->GetCovariances());
+           trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(trackParam);
+         }
+         
+       } else { // or save track parameters on last station only
+         
+         // save parameters from fit
+         trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->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)) {
+           
+           // reset parameters and covariances
+           nextTrackParam->SetParameters(trackParam->GetParameters());
+           nextTrackParam->SetZ(trackParam->GetZ());
+           nextTrackParam->SetCovariances(trackParam->GetCovariances());
+           
+           // extrapolate them to the z of the corresponding cluster
+           AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetHitForRecPtr()->GetZ());
+           
+           // save them
+           nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
+           nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
+           
+         }
+         
+       }
+       
+      }
+      
       // 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;
@@ -219,6 +267,34 @@ void AliMUONTrackReconstructor::FollowTracks()
       fNRecTracks--;
     }
     
+    // save parameters from fit into smoothed parameters to complete track afterward
+    if (fgkComplementTracks) {
+      
+      // save parameters from fit
+      trackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->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) {
+       
+       // reset parameters and covariances
+       nextTrackParam->SetParameters(trackParam->GetParameters());
+       nextTrackParam->SetZ(trackParam->GetZ());
+       nextTrackParam->SetCovariances(trackParam->GetCovariances());
+       
+       // extrapolate them to the z of the corresponding cluster
+       AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetHitForRecPtr()->GetZ());
+       
+       // save them
+       nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
+       nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
+       
+      }
+      
+    }
+    
     track = nextTrack;
     
   }
@@ -872,8 +948,89 @@ void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Doub
   }
   
   // compute chi2 w/wo multiple scattering
-  if (trackBeingFitted->GetFitWithMCS()) chi2 += trackBeingFitted->ComputeGlobalChi2(kTRUE);
-  else chi2 += trackBeingFitted->ComputeGlobalChi2(kFALSE);
+  chi2 += trackBeingFitted->ComputeGlobalChi2(trackBeingFitted->GetFitWithMCS());
+  
+}
+
+  //__________________________________________________________________________
+void AliMUONTrackReconstructor::ComplementTracks()
+{
+  /// 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
+  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;
+  
+  // Remove double track to complete only "good" tracks
+  RemoveDoubleTracks();
+  
+  AliMUONTrack *track = (AliMUONTrack*) fRecTracksPtr->First();
+  while (track) {
+    trackModified = kFALSE;
+    
+    trackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First();
+    while (trackParam) {
+      foundOneHit = kFALSE;
+      bestChi2OfHitForRec = 2. * fgkSigmaToCutForTracking * fgkSigmaToCutForTracking; // 2 because 2 quantities in chi2
+      
+      // prepare nextTrackParam before adding new cluster because of the sorting
+      nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParam);
+      
+      chamberId = trackParam->GetHitForRecPtr()->GetChamberNumber();
+      detElemId = trackParam->GetHitForRecPtr()->GetDetElemId();
+      
+      // 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());
+      
+      // 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);
+        
+       // look for a cluster in another detection element
+       if (hitForRec->GetDetElemId() == detElemId) continue;
+       
+       // try to add the current hit fast
+       if (!TryOneHitForRecFast(copyOfTrackParam, hitForRec)) continue;
+       
+       // try to add the current hit accurately
+       chi2OfHitForRec = TryOneHitForRec(copyOfTrackParam, hitForRec, trackParamAtHit);
+       
+       // if better chi2 then prepare to add this cluster to the track
+       if (chi2OfHitForRec < bestChi2OfHitForRec) {
+         bestChi2OfHitForRec = chi2OfHitForRec;
+         bestTrackParamAtHit = trackParamAtHit;
+         foundOneHit = kTRUE;
+       }
+       
+      }
+      
+      // add new cluster if any
+      if (foundOneHit) {
+       UpdateTrack(*track,bestTrackParamAtHit);
+       bestTrackParamAtHit.SetAloneInChamber(kFALSE);
+       trackParam->SetAloneInChamber(kFALSE);
+       trackModified = kTRUE;
+      }
+      
+      trackParam = nextTrackParam;
+    }
+    
+    // re-fit track parameters if needed
+    if (trackModified) Fit(*track, kTRUE, kTRUE);
+    
+    track = (AliMUONTrack*) fRecTracksPtr->After(track);
+  }
   
 }
 
@@ -885,15 +1042,19 @@ void AliMUONTrackReconstructor::ImproveTracks()
   AliDebug(1,"Enter ImproveTracks");
   
   Double_t localChi2, worstLocalChi2;
-  Int_t worstChamber;
-  AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit;
+  Int_t worstChamber, previousChamber;
+  AliMUONTrack *track, *nextTrack;
+  AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit, *previousTrackParam, *nextTrackParam;
   
   // Remove double track to improve only "good" tracks
   RemoveDoubleTracks();
   
-  AliMUONTrack *track = (AliMUONTrack*) fRecTracksPtr->First();
+  track = (AliMUONTrack*) fRecTracksPtr->First();
   while (track) {
     
+    // prepare next track in case the actual track is suppressed
+    nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track);
+    
     while (!track->IsImproved()) {
       
       // Update track parameters and covariances
@@ -903,7 +1064,7 @@ void AliMUONTrackReconstructor::ImproveTracks()
       track->ComputeLocalChi2(kTRUE);
       
       // Look for the hit to remove
-      worstTrackParamAtHit = 0;
+      worstTrackParamAtHit = NULL;
       worstLocalChi2 = 0.;
       trackParamAtHit = (AliMUONTrackParam*) track->GetTrackParamAtHit()->First();
       while (trackParamAtHit) {
@@ -924,22 +1085,60 @@ void AliMUONTrackReconstructor::ImproveTracks()
         break;
       }
       
-      // check whether the worst hit is removable or not
-      if (!worstTrackParamAtHit->IsRemovable()) {
+      // Check whether the worst chi2 is under requirement or not
+      if (worstLocalChi2 < 2. * fgkSigmaToCutForImprovement * fgkSigmaToCutForImprovement) { // 2 because 2 quantities in chi2
         track->SetImproved(kTRUE);
         break;
       }
       
-      // Check whether the worst chi2 is under requirement or not
-      if (worstLocalChi2 < 2. * fgkSigmaToCutForImprovement * fgkSigmaToCutForImprovement) { // 2 because 2 quantities in chi2
-        track->SetImproved(kTRUE);
+      // if the worst hit is not removable then remove the entire track
+      if (!worstTrackParamAtHit->IsRemovable() && worstTrackParamAtHit->IsAloneInChamber()) {
+       fRecTracksPtr->Remove(track);
+       fNRecTracks--;
         break;
       }
       
-      // Reset the second hit in the same station as the bad one as being NOT removable
+      // 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();
-      if (worstChamber%2 == 0) ((AliMUONTrackParam*)track->GetTrackParamAtHit()->After(worstTrackParamAtHit))->SetRemovable(kFALSE);
-      else ((AliMUONTrackParam*)track->GetTrackParamAtHit()->Before(worstTrackParamAtHit))->SetRemovable(kFALSE);
+      previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(worstTrackParamAtHit);
+      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(worstTrackParamAtHit);
+      if (worstTrackParamAtHit->IsAloneInChamber()) { // Worst hit 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);
+         
+       } 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);
+         
+       }
+       
+      } else { // Worst hit not alone in its chamber
+        
+       if (previousTrackParam) previousChamber = previousTrackParam->GetHitForRecPtr()->GetChamberNumber();
+       else previousChamber = -1;
+       
+       if (previousChamber == worstChamber) { // the second hit on the same chamber is the previous one
+         
+         previousTrackParam->SetAloneInChamber(kTRUE);
+         // transfert the removability to the second hit
+         if (worstTrackParamAtHit->IsRemovable()) previousTrackParam->SetRemovable(kTRUE);
+         
+       } else { // the second hit on the same chamber is the next one
+         
+         nextTrackParam->SetAloneInChamber(kTRUE);
+         // transfert the removability to the second hit
+         if (worstTrackParamAtHit->IsRemovable()) nextTrackParam->SetRemovable(kTRUE);
+         
+       }
+       
+      }
       
       // Remove the worst hit
       track->RemoveTrackParamAtHit(worstTrackParamAtHit);
@@ -947,7 +1146,6 @@ void AliMUONTrackReconstructor::ImproveTracks()
       // Re-fit the track:
       // Take into account the multiple scattering
       // Calculate the track parameter covariance matrix
-      track->SetFitWithVertex(kFALSE); // To be sure
       Fit(*track, kTRUE, kTRUE);
       
       // Printout for debuging
@@ -957,9 +1155,12 @@ void AliMUONTrackReconstructor::ImproveTracks()
       
     }
     
-    track = (AliMUONTrack*) fRecTracksPtr->After(track);
+    track = nextTrack;
   }
   
+  // compress the array in case of some tracks have been removed
+  fRecTracksPtr->Compress();
+  
 }
 
   //__________________________________________________________________________
@@ -967,6 +1168,7 @@ 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;
   
index e6331748bc19b41bfa3a4ce3b89cc0ceb1e74245..c7e782ac9158746bca6ddebd83f9138addbaccf2 100644 (file)
@@ -29,6 +29,7 @@ class AliMUONTrackReconstructor : public AliMUONVTrackReconstructor
   // Functions
   virtual void MakeTrackCandidates();
   virtual void FollowTracks();
+  virtual void ComplementTracks();
   virtual void ImproveTracks();
   virtual void Finalize();
   
index 7eefa406c8c5f2daa76ee6b83e90da6eca986999..09ae2269ab3ccbc170bd386d221aae586dd5ab99 100644 (file)
@@ -70,6 +70,7 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
   /// 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.
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
+  
   TClonesArray *segments;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
@@ -925,6 +926,95 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track)
 }
 
   //__________________________________________________________________________
+void AliMUONTrackReconstructorK::ComplementTracks()
+{
+  /// 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
+  AliDebug(1,"Enter ComplementTracks");
+  
+  Int_t chamberId, detElemId;
+  Double_t chi2OfHitForRec, addChi2TrackAtHit, bestAddChi2TrackAtHit;
+  Double_t maxChi2OfHitForRec = 2. * fgkSigmaToCutForTracking * fgkSigmaToCutForTracking; // 2 because 2 quantities in chi2
+  Bool_t foundOneHit, trackModified;
+  AliMUONHitForRec *hitForRec;
+  AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam;
+  AliMUONTrackParam trackParamAtHit;
+  AliMUONTrackParam bestTrackParamAtHit;
+  
+  // Remove double track to complete only "good" tracks
+  RemoveDoubleTracks();
+  
+  AliMUONTrack *track = (AliMUONTrack*) fRecTracksPtr->First();
+  while (track) {
+    trackModified = kFALSE;
+    
+    trackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->First();
+    previousTrackParam = trackParam;
+    while (trackParam) {
+      foundOneHit = kFALSE;
+      bestAddChi2TrackAtHit = 1.e10;
+      
+      // prepare nextTrackParam before adding new cluster because of the sorting
+      nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParam);
+      
+      chamberId = trackParam->GetHitForRecPtr()->GetChamberNumber();
+      detElemId = trackParam->GetHitForRecPtr()->GetDetElemId();
+      
+      // 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);
+        
+       // look for a cluster in another detection element
+       if (hitForRec->GetDetElemId() == detElemId) continue;
+       
+       // try to add the current hit fast
+       if (!TryOneHitForRecFast(*trackParam, hitForRec)) continue;
+       
+       // try to add the current hit 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 good chi2 then consider to add this cluster to the track
+       if (chi2OfHitForRec < maxChi2OfHitForRec) {
+          
+         // Compute local track parameters including "hitForRec" using kalman filter
+          addChi2TrackAtHit = RunKalmanFilter(trackParamAtHit);
+          
+         // keep track of the best cluster
+         if (addChi2TrackAtHit < bestAddChi2TrackAtHit) {
+           bestAddChi2TrackAtHit = addChi2TrackAtHit;
+           bestTrackParamAtHit = trackParamAtHit;
+           foundOneHit = kTRUE;
+         }
+         
+       }
+       
+      }
+      
+      // add new cluster if any
+      if (foundOneHit) {
+       UpdateTrack(*track,bestTrackParamAtHit,bestAddChi2TrackAtHit);
+       bestTrackParamAtHit.SetAloneInChamber(kFALSE);
+       trackParam->SetAloneInChamber(kFALSE);
+       trackModified = kTRUE;
+      }
+      
+      previousTrackParam = trackParam;
+      trackParam = nextTrackParam;
+    }
+    
+    // re-compute track parameters using kalman filter if needed
+    if (trackModified) RetraceTrack(*track,kTRUE);
+    
+    track = (AliMUONTrack*) fRecTracksPtr->After(track);
+  }
+  
+}
+
+//__________________________________________________________________________
 void AliMUONTrackReconstructorK::ImproveTracks()
 {
   /// Improve tracks by removing clusters with local chi2 highter than the defined cut
@@ -932,16 +1022,20 @@ void AliMUONTrackReconstructorK::ImproveTracks()
   AliDebug(1,"Enter ImproveTracks");
   
   Double_t localChi2, worstLocalChi2;
-  Int_t worstChamber;
-  AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit;
+  Int_t worstChamber, previousChamber;
+  AliMUONTrack *track, *nextTrack;
+  AliMUONTrackParam *trackParamAtHit, *worstTrackParamAtHit, *previousTrackParam, *nextTrackParam;
   Bool_t smoothed;
   
   // Remove double track to improve only "good" tracks
   RemoveDoubleTracks();
   
-  AliMUONTrack *track = (AliMUONTrack*) fRecTracksPtr->First();
+  track = (AliMUONTrack*) fRecTracksPtr->First();
   while (track) {
     
+    // prepare next track in case the actual track is suppressed
+    nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track);
+    
     while (!track->IsImproved()) {
       
       // Run smoother if required
@@ -971,7 +1065,7 @@ void AliMUONTrackReconstructorK::ImproveTracks()
           worstTrackParamAtHit = trackParamAtHit;
         }
         
-      trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParamAtHit);
+       trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(trackParamAtHit);
       }
       
       // Check if bad removable hit found
@@ -980,25 +1074,60 @@ void AliMUONTrackReconstructorK::ImproveTracks()
         break;
       }
       
-      // check whether the worst hit is removable or not
-      if (!worstTrackParamAtHit->IsRemovable()) {
+      // Check whether the worst chi2 is under requirement or not
+      if (worstLocalChi2 < 2. * fgkSigmaToCutForImprovement * fgkSigmaToCutForImprovement) { // 2 because 2 quantities in chi2
         track->SetImproved(kTRUE);
         break;
       }
       
-      // Check whether the worst chi2 is under requirement or not
-      if (worstLocalChi2 < 2. * fgkSigmaToCutForImprovement * fgkSigmaToCutForImprovement) { // 2 because 2 quantities in chi2
-        track->SetImproved(kTRUE);
+      // if the worst hit is not removable then remove the entire track
+      if (!worstTrackParamAtHit->IsRemovable() && worstTrackParamAtHit->IsAloneInChamber()) {
+       fRecTracksPtr->Remove(track);
+       fNRecTracks--;
         break;
       }
       
-      // Reset the second hit in the same station as the bad one as being NOT removable
+      // 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();
-      if (worstChamber%2 == 0) ((AliMUONTrackParam*)track->GetTrackParamAtHit()->After(worstTrackParamAtHit))->SetRemovable(kFALSE);
-      else ((AliMUONTrackParam*)track->GetTrackParamAtHit()->Before(worstTrackParamAtHit))->SetRemovable(kFALSE);
-      
-      // Save pointer to the trackParamAtHit next to the one to be removed
-      trackParamAtHit = (AliMUONTrackParam*)track->GetTrackParamAtHit()->After(worstTrackParamAtHit);
+      previousTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->Before(worstTrackParamAtHit);
+      nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtHit()->After(worstTrackParamAtHit);
+      if (worstTrackParamAtHit->IsAloneInChamber()) { // Worst hit 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);
+         
+       } 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);
+         
+       }
+       
+      } else { // Worst hit not alone in its chamber
+        
+       if (previousTrackParam) previousChamber = previousTrackParam->GetHitForRecPtr()->GetChamberNumber();
+       else previousChamber = -1;
+       
+       if (previousChamber == worstChamber) { // the second hit on the same chamber is the previous one
+         
+         previousTrackParam->SetAloneInChamber(kTRUE);
+         // transfert the removability to the second hit
+         if (worstTrackParamAtHit->IsRemovable()) previousTrackParam->SetRemovable(kTRUE);
+         
+       } else { // the second hit on the same chamber is the next one
+         
+         nextTrackParam->SetAloneInChamber(kTRUE);
+         // transfert the removability to the second hit
+         if (worstTrackParamAtHit->IsRemovable()) nextTrackParam->SetRemovable(kTRUE);
+         
+       }
+       
+      }
       
       // Remove the worst hit
       track->RemoveTrackParamAtHit(worstTrackParamAtHit);
@@ -1007,7 +1136,7 @@ void AliMUONTrackReconstructorK::ImproveTracks()
       // - from the hit 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
-      if (smoothed && trackParamAtHit) RetracePartialTrack(*track,trackParamAtHit);
+      if (smoothed && nextTrackParam) RetracePartialTrack(*track,nextTrackParam);
       else RetraceTrack(*track,kTRUE);
       
       // Printout for debuging
@@ -1017,15 +1146,19 @@ void AliMUONTrackReconstructorK::ImproveTracks()
       
     }
     
-    track = (AliMUONTrack*) fRecTracksPtr->After(track);
+    track = nextTrack;
   }
   
+  // compress the array in case of some tracks have been removed
+  fRecTracksPtr->Compress();
+  
 }
 
   //__________________________________________________________________________
 void AliMUONTrackReconstructorK::Finalize()
 {
   /// Fill AliMUONTrack's fHitForRecAtHit array
+  
   AliMUONTrack *track;
   AliMUONTrackParam *trackParamAtHit;
   Bool_t smoothed = kFALSE;
index bdd023286f46f09e2c0e199727ffb78cfebc09e7..75c5ffcaf732a8ca221c8aa20366cb73fe8a020a 100644 (file)
@@ -28,6 +28,7 @@ class AliMUONTrackReconstructorK : public AliMUONVTrackReconstructor
   // Functions
   virtual void MakeTrackCandidates();
   virtual void FollowTracks();
+  virtual void ComplementTracks();
   virtual void ImproveTracks();
   virtual void Finalize();
   
index 067b75922ca2e9759d3d8379612d836f567e340f..1d46d30b1f51b6086ccca0be81398c6ce89e343b 100644 (file)
@@ -71,6 +71,7 @@
 #include "AliMpDEManager.h"
 
 #include "AliLog.h"
+#include "AliCodeTimer.h"
 #include "AliTracker.h"
 
 #include <TClonesArray.h>
@@ -95,8 +96,9 @@ const Double_t AliMUONVTrackReconstructor::fgkSigmaToCutForTracking = 6.0;
 const Bool_t   AliMUONVTrackReconstructor::fgkMakeTrackCandidatesFast = kFALSE;
 const Bool_t   AliMUONVTrackReconstructor::fgkTrackAllTracks = kTRUE;
 const Bool_t   AliMUONVTrackReconstructor::fgkRecoverTracks = kTRUE;
+const Bool_t   AliMUONVTrackReconstructor::fgkComplementTracks = kTRUE;
 const Bool_t   AliMUONVTrackReconstructor::fgkImproveTracks = kTRUE;
-const Double_t AliMUONVTrackReconstructor::fgkSigmaToCutForImprovement = 4.0;
+const Double_t AliMUONVTrackReconstructor::fgkSigmaToCutForImprovement = 5.0;
 
 
   //__________________________________________________________________________
@@ -166,6 +168,7 @@ void AliMUONVTrackReconstructor::EventReconstruct(const AliMUONVClusterStore& cl
 {
   /// To reconstruct one event
   AliDebug(1,"");
+  AliCodeTimerAuto("");
   
   ResetTracks();
   ResetHitsForRec();
@@ -203,7 +206,7 @@ void AliMUONVTrackReconstructor::AddHitsForRecFromRawClusters(const AliMUONVClus
     hitForRec->SetChamberNumber(ch);
     hitForRec->SetHitNumber(iclus);
     // Z coordinate of the raw cluster (cm)
-    hitForRec->SetZ(clus->GetZ(0));
+    hitForRec->SetZ(clus->GetZ());
     if (AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 3) {
       cout << "Chamber " << ch <<" raw cluster  " << iclus << " : " << endl;
       clus->Print("full");
@@ -275,6 +278,8 @@ void AliMUONVTrackReconstructor::MakeTracks()
   if (fRecTracksPtr->GetEntriesFast() == 0) return;
   // Follow tracks in stations(1..) 3, 2 and 1
   FollowTracks();
+  // Complement the reconstructed tracks
+  if (fgkComplementTracks) ComplementTracks();
   // Improve the reconstructed tracks
   if (fgkImproveTracks) ImproveTracks();
   // Remove double tracks
@@ -816,6 +821,8 @@ void AliMUONVTrackReconstructor::ValidateTracksWithTrigger(AliMUONVTrackStore& t
                                                            const AliMUONTrackHitPattern& trackHitPattern)
 {
   /// Try to match track from tracking system with trigger track
+  AliCodeTimerAuto("");
+  
   static const Double_t kDistSigma[3]={1,1,0.02}; // sigma of distributions (trigger-track) X,Y,slopeY
   
   Int_t matchTrigger;
@@ -917,6 +924,7 @@ void AliMUONVTrackReconstructor::EventReconstructTrigger(const AliMUONTriggerCir
 {
   /// To make the trigger tracks from Local Trigger
   AliDebug(1, "");
+  AliCodeTimerAuto("");
   
   AliMUONGlobalTrigger* globalTrigger = triggerStore.Global();
   
index 5994a1d6ebc832d4f98dfc993d085845da6d814c..4e65100081e6735273be208ff5eed2e065c5cc6e 100644 (file)
@@ -75,7 +75,8 @@ class AliMUONVTrackReconstructor : public TObject {
   static const Double_t fgkMaxTrackingDistanceBending;    ///< Maximum distance to the track to search for compatible hitForRec(s) in bending direction
   static const Double_t fgkMaxTrackingDistanceNonBending; ///< Maximum distance to the track to search for compatible hitForRec(s) in non bending direction
   static const Bool_t   fgkRecoverTracks; ///< kTRUE to try to recover the tracks being lost during reconstruction
-  static const Bool_t   fgkImproveTracks; ///< kTRUE to try to improve the reconstructed tracks
+  static const Bool_t   fgkComplementTracks; ///< kTRUE to try to complete the reconstructed tracks by adding missing clusters
+  static const Bool_t   fgkImproveTracks; ///< kTRUE to try to improve the reconstructed tracks by removing bad clusters
   
   // Parameters for track reconstruction
   Double_t fMinBendingMomentum; ///< minimum value (GeV/c) of momentum in bending plane
@@ -100,6 +101,8 @@ class AliMUONVTrackReconstructor : public TObject {
   virtual void MakeTrackCandidates() = 0;
   /// Follow tracks in stations(1..) 3, 2 and 1
   virtual void FollowTracks() = 0;
+  /// Complement the reconstructed tracks
+  virtual void ComplementTracks() = 0;
   /// Improve the reconstructed tracks
   virtual void ImproveTracks() = 0;
   /// Finalize the tracking results