- Changed the algorithm to improve the quick test of clusters
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 6 Jul 2007 15:36:10 +0000 (15:36 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 6 Jul 2007 15:36:10 +0000 (15:36 +0000)
  (within a wide fixe window) prior to really trying to attach them.
- Added an option (fgkMakeTrackCandidatesFast) to make track candidates
  assuming linear propagation between stations 4 and 5.
(Philippe P.)

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

index b181bab..118c973 100644 (file)
@@ -378,7 +378,7 @@ void AliMUONTrack::AddTrackParamAtHit(const AliMUONTrackParam *trackParam, AliMU
     }
   } else {
     trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam();
-    if (hitForRec) ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(fNTrackHits))->SetZ(hitForRec->GetZ());
+    if (hitForRec) trackParamAtHit->SetZ(hitForRec->GetZ());
   }
   if (hitForRec) trackParamAtHit->SetHitForRecPtr(hitForRec);
   fNTrackHits++;
@@ -590,12 +590,6 @@ Bool_t AliMUONTrack::ComputeLocalChi2(Bool_t accountForMCS)
     Double_t dX, dY;
     while (trackParamAtHit) {
       
-      // compute chi2 of removable hits only
-      if (!trackParamAtHit->IsRemovable()) {
-        trackParamAtHit = (AliMUONTrackParam*) fTrackParamAtHit->After(trackParamAtHit);
-        continue;
-      }
-      
       discardedHit = trackParamAtHit->GetHitForRecPtr();
       
       // Compute residuals
index c0aae90..15bce78 100644 (file)
@@ -97,6 +97,34 @@ Double_t AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(Double_t impactPa
 }
 
   //__________________________________________________________________________
+void AliMUONTrackExtrap::LinearExtrapToZ(AliMUONTrackParam* trackParam, Double_t zEnd)
+{
+  /// Track parameters (and their covariances if any) linearly extrapolated to the plane at "zEnd".
+  /// On return, results from the extrapolation are updated in trackParam.
+  
+  if (trackParam->GetZ() == zEnd) return; // nothing to be done if same z
+  
+  // Compute track parameters
+  Double_t dZ = zEnd - trackParam->GetZ();
+  trackParam->SetNonBendingCoor(trackParam->GetNonBendingCoor() + trackParam->GetNonBendingSlope() * dZ);
+  trackParam->SetBendingCoor(trackParam->GetBendingCoor() + trackParam->GetBendingSlope() * dZ);
+  trackParam->SetZ(zEnd);
+  
+  // Update track parameters covariances if any
+  if (trackParam->CovariancesExist()) {
+    TMatrixD paramCov(trackParam->GetCovariances());
+    paramCov(0,0) += dZ * dZ * paramCov(1,1) + 2. * dZ * paramCov(0,1);
+    paramCov(0,1) += dZ * paramCov(1,1);
+    paramCov(1,0) = paramCov(0,1);
+    paramCov(2,2) += dZ * dZ * paramCov(3,3) + 2. * dZ * paramCov(2,3);
+    paramCov(2,3) += dZ * paramCov(3,3);
+    paramCov(3,2) = paramCov(2,3);
+    trackParam->SetCovariances(paramCov);
+  }
+  
+}
+
+  //__________________________________________________________________________
 void AliMUONTrackExtrap::ExtrapToZ(AliMUONTrackParam* trackParam, Double_t zEnd)
 {
   /// Interface to track parameter extrapolation to the plane at "Z" using Helix or Rungekutta algorithm.
index e3312f6..d57ea45 100644 (file)
@@ -33,7 +33,8 @@ class AliMUONTrackExtrap : public TObject
   static Double_t GetImpactParamFromBendingMomentum(Double_t bendingMomentum);
   static Double_t GetBendingMomentumFromImpactParam(Double_t impactParam);
   
-  static void ExtrapToZ(AliMUONTrackParam *trackParam, Double_t Z);
+  static void LinearExtrapToZ(AliMUONTrackParam* trackParam, Double_t zEnd);
+  static void ExtrapToZ(AliMUONTrackParam *trackParam, Double_t zEnd);
   static void ExtrapToZCov(AliMUONTrackParam* trackParam, Double_t zEnd, Bool_t updatePropagator = kFALSE);
   static void ExtrapToStation(AliMUONTrackParam *trackParamIn, Int_t station, AliMUONTrackParam *trackParamOut);
   static void ExtrapToVertexUncorrected(AliMUONTrackParam* trackParam, Double_t zVtx);
index 7cea71b..f876a2b 100644 (file)
@@ -100,7 +100,7 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   if (theMUONTrackParam.fCovariances) {
     if (fCovariances) *fCovariances = *(theMUONTrackParam.fCovariances);
     else fCovariances = new TMatrixD(*(theMUONTrackParam.fCovariances));
-  } else if (fCovariances) {
+  } else {
     delete fCovariances;
     fCovariances = 0x0;
   }
@@ -108,7 +108,7 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   if (theMUONTrackParam.fPropagator) {
     if (fPropagator) *fPropagator = *(theMUONTrackParam.fPropagator);
     else fPropagator = new TMatrixD(*(theMUONTrackParam.fPropagator));
-  } else if (fPropagator) {
+  } else {
     delete fPropagator;
     fPropagator = 0x0;
   }
@@ -116,7 +116,7 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   if (theMUONTrackParam.fExtrapParameters) {
     if (fExtrapParameters) *fExtrapParameters = *(theMUONTrackParam.fExtrapParameters);
     else fExtrapParameters = new TMatrixD(*(theMUONTrackParam.fExtrapParameters));
-  } else if (fExtrapParameters) {
+  } else {
     delete fExtrapParameters;
     fExtrapParameters = 0x0;
   }
@@ -124,7 +124,7 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   if (theMUONTrackParam.fExtrapCovariances) {
     if (fExtrapCovariances) *fExtrapCovariances = *(theMUONTrackParam.fExtrapCovariances);
     else fExtrapCovariances = new TMatrixD(*(theMUONTrackParam.fExtrapCovariances));
-  } else if (fExtrapCovariances) {
+  } else {
     delete fExtrapCovariances;
     fExtrapCovariances = 0x0;
   }
@@ -132,7 +132,7 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   if (theMUONTrackParam.fSmoothParameters) {
     if (fSmoothParameters) *fSmoothParameters = *(theMUONTrackParam.fSmoothParameters);
     else fSmoothParameters = new TMatrixD(*(theMUONTrackParam.fSmoothParameters));
-  } else if (fSmoothParameters) {
+  } else {
     delete fSmoothParameters;
     fSmoothParameters = 0x0;
   }
@@ -140,7 +140,7 @@ AliMUONTrackParam& AliMUONTrackParam::operator=(const AliMUONTrackParam& theMUON
   if (theMUONTrackParam.fSmoothCovariances) {
     if (fSmoothCovariances) *fSmoothCovariances = *(theMUONTrackParam.fSmoothCovariances);
     else fSmoothCovariances = new TMatrixD(*(theMUONTrackParam.fSmoothCovariances));
-  } else if (fSmoothCovariances) {
+  } else {
     delete fSmoothCovariances;
     fSmoothCovariances = 0x0;
   }
@@ -305,7 +305,6 @@ const TMatrixD& AliMUONTrackParam::GetCovariances() const
 void AliMUONTrackParam::SetCovariances(const TMatrixD& covariances)
 {
   /// Set the covariance matrix
-  if (&covariances == fCovariances) return; // nothing to be done
   if (fCovariances) *fCovariances = covariances;
   else fCovariances = new TMatrixD(covariances);
 }
@@ -341,7 +340,7 @@ const TMatrixD& AliMUONTrackParam::GetPropagator() const
   /// Return the propagator (create it before if needed)
   if (!fPropagator) {
     fPropagator = new TMatrixD(5,5);
-    fPropagator->Zero();
+    fPropagator->UnitMatrix();
   }
   return *fPropagator;
   }
@@ -350,15 +349,13 @@ const TMatrixD& AliMUONTrackParam::GetPropagator() const
 void AliMUONTrackParam::ResetPropagator()
 {
   /// Reset the propagator
-  if (!fPropagator) fPropagator = new TMatrixD(5,5);
-  fPropagator->UnitMatrix();
+  if (fPropagator) fPropagator->UnitMatrix();
 }
 
   //__________________________________________________________________________
 void AliMUONTrackParam::UpdatePropagator(const TMatrixD& propagator)
 {
   /// Update the propagator
-  if (&propagator == fPropagator) return; // nothing to be done
   if (fPropagator) *fPropagator = TMatrixD(propagator,TMatrixD::kMult,*fPropagator);
   else fPropagator = new TMatrixD(propagator);
 }
@@ -378,7 +375,6 @@ const TMatrixD& AliMUONTrackParam::GetExtrapParameters() const
 void AliMUONTrackParam::SetExtrapParameters(const TMatrixD& extrapParameters)
 {
   /// Set extrapolated parameters
-  if (&extrapParameters == fExtrapParameters) return; // nothing to be done
   if (fExtrapParameters) *fExtrapParameters = extrapParameters;
   else fExtrapParameters = new TMatrixD(extrapParameters);
 }
@@ -398,7 +394,6 @@ const TMatrixD& AliMUONTrackParam::GetExtrapCovariances() const
 void AliMUONTrackParam::SetExtrapCovariances(const TMatrixD& extrapCovariances)
 {
   /// Set the extrapolated covariance matrix
-  if (&extrapCovariances == fExtrapCovariances) return; // nothing to be done
   if (fExtrapCovariances) *fExtrapCovariances = extrapCovariances;
   else fExtrapCovariances = new TMatrixD(extrapCovariances);
 }
@@ -418,7 +413,6 @@ const TMatrixD& AliMUONTrackParam::GetSmoothParameters() const
 void AliMUONTrackParam::SetSmoothParameters(const TMatrixD& smoothParameters)
 {
   /// Set the smoothed parameters
-  if (&smoothParameters == fSmoothParameters) return; // nothing to be done
   if (fSmoothParameters) *fSmoothParameters = smoothParameters;
   else fSmoothParameters = new TMatrixD(smoothParameters);
 }
@@ -438,7 +432,6 @@ const TMatrixD& AliMUONTrackParam::GetSmoothCovariances() const
 void AliMUONTrackParam::SetSmoothCovariances(const TMatrixD& smoothCovariances)
 {
   /// Set the smoothed covariance matrix
-  if (&smoothCovariances == fSmoothCovariances) return; // nothing to be done
   if (fSmoothCovariances) *fSmoothCovariances = smoothCovariances;
   else fSmoothCovariances = new TMatrixD(smoothCovariances);
 }
index e7198f0..d888016 100644 (file)
@@ -51,7 +51,7 @@ const Double_t AliMUONTrackReconstructor::fgkBendingVertexDispersion = 10.;
 const Double_t AliMUONTrackReconstructor::fgkNonBendingVertexDispersion = 10.;
 
 
-//__________________________________________________________________________
+  //__________________________________________________________________________
 AliMUONTrackReconstructor::AliMUONTrackReconstructor()
   : AliMUONVTrackReconstructor()
 {
@@ -59,7 +59,7 @@ AliMUONTrackReconstructor::AliMUONTrackReconstructor()
   AliInfo("*** Original tracking ***");
 }
 
-//__________________________________________________________________________
+  //__________________________________________________________________________
 AliMUONTrackReconstructor::~AliMUONTrackReconstructor()
 {
 /// Destructor
@@ -68,13 +68,14 @@ AliMUONTrackReconstructor::~AliMUONTrackReconstructor()
   //__________________________________________________________________________
 void AliMUONTrackReconstructor::MakeTrackCandidates()
 {
-  /// To make track candidates:
+  /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
   /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4.
   /// Good candidates are made of at least three hitForRec's.
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
   TClonesArray *segments;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
+  Bool_t hitFound;
 
   AliDebug(1,"Enter MakeTrackCandidates");
 
@@ -101,7 +102,11 @@ void AliMUONTrackReconstructor::MakeTrackCandidates()
       }
       
       // Look for compatible hitForRec(s) in the other station
-      if (!FollowTrackInStation(*track,7-istat)) {
+      if (fgkMakeTrackCandidatesFast) hitFound = FollowLinearTrackInStation(*track,7-istat);
+      else hitFound = FollowTrackInStation(*track,7-istat);
+      
+      // Remove track if no hit found
+      if (!hitFound) {
         fRecTracksPtr->Remove(track);
        fNRecTracks--;
       }
@@ -244,7 +249,6 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
     ch2 = 2*nextStation+1;
   }
   
-  Double_t zCh2 = AliMUONConstants::DefaultChamberZ(ch2);
   Double_t chi2WithOneHitForRec = 1.e10;
   Double_t chi2WithTwoHitForRec = 1.e10;
   Double_t maxChi2WithOneHitForRec = 2. * fgkSigmaToCutForTracking * fgkSigmaToCutForTracking; // 2 because 2 quantities in chi2
@@ -255,6 +259,7 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
   Bool_t foundTwoHits = kFALSE;
   AliMUONTrack *newTrack = 0x0;
   AliMUONHitForRec *hitForRecCh1, *hitForRecCh2;
+  AliMUONTrackParam extrapTrackParam;
   AliMUONTrackParam extrapTrackParamAtHit1;
   AliMUONTrackParam extrapTrackParamAtHit2;
   AliMUONTrackParam bestTrackParamAtHit1;
@@ -262,27 +267,27 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
   Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]];
   for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE;
   
-  // Get track parameters and extrapolate them to chamber "ch2" to save computing time in the next steps
-  AliMUONTrackParam extrapTrackParamAtCh2(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
+  // Get track parameters
+  AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
   
   // Add MCS effect
-  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh2,AliMUONConstants::ChamberThicknessInX0(),1.);
+  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
   
   // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria)
-  if (ch1 < ch2 && extrapTrackParamAtCh2.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) {
+  if (ch1 < ch2 && extrapTrackParamAtCh.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) {
     // extrapolation to the missing chamber
-    AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh2, AliMUONConstants::DefaultChamberZ(ch2 + 1));
+    AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1));
     // add MCS effect
-    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh2,AliMUONConstants::ChamberThicknessInX0(),1.);
+    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
   }
   
   //Extrapolate trackCandidate to chamber "ch2"
-  AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh2, zCh2);
+  AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2));
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-    cout<<endl<<"Track parameter covariances at first hit extrapolated to z = "<<zCh2<<":"<<endl;
-    extrapTrackParamAtCh2.GetCovariances().Print();
+    cout<<endl<<"Track parameter covariances at first hit extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+    extrapTrackParamAtCh.GetCovariances().Print();
   }
   
   // Printout for debuging
@@ -295,8 +300,11 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
     
     hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2);
     
-    // try to add the current hit
-    chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh2, hitForRecCh2, extrapTrackParamAtHit2);
+    // try to add the current hit fast
+    if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh2)) continue;
+    
+    // try to add the current hit accuratly
+    chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh2, extrapTrackParamAtHit2);
     
     // if good chi2 then try to attach a hitForRec in the other chamber too
     if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
@@ -312,11 +320,20 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
       // add MCS effect for next step
       AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtHit2,AliMUONConstants::ChamberThicknessInX0(),1.);
       
+      // copy new track parameters for next step
+      extrapTrackParam = extrapTrackParamAtHit2;
+      
+      //Extrapolate track parameters to chamber "ch1"
+      AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1));
+      
       for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
         
        hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
        
-       // try to add the current hit in addition to the one found on the previous chamber
+       // try to add the current hit fast
+       if (!TryOneHitForRecFast(extrapTrackParam, hitForRecCh1)) continue;
+       
+       // try to add the current hit accuratly
        chi2WithTwoHitForRec = TryTwoHitForRec(extrapTrackParamAtHit2, hitForRecCh1, extrapTrackParamAtHit1);
         
        // if good chi2 then create a new track by adding the 2 hitForRec to the "trackCandidate"
@@ -373,8 +390,7 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
          }
          
        } else if (!foundTwoHits && chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
-         // keep track of the best single hitForRec except if a couple
-          // of hits has already been found (i.e. bestHitForRec2!=0x0)
+         // keep track of the best single hitForRec except if a couple of hits has already been found
          bestChi2WithOneHitForRec = chi2WithOneHitForRec;
          bestTrackParamAtHit1 = extrapTrackParamAtHit2;
         }
@@ -395,16 +411,22 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
     }
     
     // add MCS effect for next step
-    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh2,AliMUONConstants::ChamberThicknessInX0(),1.);
-      
+    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
+    
+    //Extrapolate trackCandidate to chamber "ch1"
+    AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1));
+    
     for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
       
       hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
       
       if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used
       
-      // try to add the current hit
-      chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh2, hitForRecCh1, extrapTrackParamAtHit1);
+      // try to add the current hit fast
+      if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh1)) continue;
+      
+      // try to add the current hit accuratly
+      chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh1, extrapTrackParamAtHit1);
     
       // if good chi2 then consider to add hitForRecCh1
       // We do not try to attach a hitForRec in the other chamber too since it has already been done above
@@ -430,8 +452,7 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
          }
          
        } else if (chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
-         // keep track of the best single hitForRec except if a couple
-         // of hits has already been found (i.e. bestHitForRec1!=0x0)
+         // keep track of the best single hitForRec except if a couple of hits has already been found
          bestChi2WithOneHitForRec = chi2WithOneHitForRec;
          bestTrackParamAtHit1 = extrapTrackParamAtHit1;
        }
@@ -477,16 +498,13 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid
 }
 
   //__________________________________________________________________________
-Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2, AliMUONTrackParam &trackParamAtHit2)
+Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2,
+                                                   AliMUONTrackParam &trackParamAtHit2)
 {
 /// Test the compatibility between the track and the 2 hitForRec together (using trackParam's covariance matrix):
 /// return the corresponding Chi2 accounting for covariances between the 2 hitForRec
 /// return trackParamAtHit1 & 2
   
-  if (!trackParamAtHit1.CovariancesExist()) AliWarning(" track parameter covariance matrix does not exist");
-  AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr();
-  if (!hitForRec1) AliFatal(" no hitForRec attached to trackParamAtHit1");
-  
   // extrapolate track parameters at the z position of the second hit
   trackParamAtHit2.SetParameters(trackParamAtHit1.GetParameters());
   trackParamAtHit2.SetZ(trackParamAtHit1.GetZ());
@@ -496,18 +514,13 @@ Double_t AliMUONTrackReconstructor::TryTwoHitForRec(const AliMUONTrackParam &tra
   trackParamAtHit2.SetHitForRecPtr(hitForRec2);
   
   // Set differences between track and the 2 hitForRec in the bending and non bending directions
+  AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr();
   TMatrixD dPos(4,1);
   dPos(0,0) = hitForRec1->GetNonBendingCoor() - trackParamAtHit1.GetNonBendingCoor();
   dPos(1,0) = hitForRec1->GetBendingCoor() - trackParamAtHit1.GetBendingCoor();
   dPos(2,0) = hitForRec2->GetNonBendingCoor() - trackParamAtHit2.GetNonBendingCoor();
   dPos(3,0) = hitForRec2->GetBendingCoor() - trackParamAtHit2.GetBendingCoor();
   
-  // quick tests of hitForRec compatibility within a wide road of x*y = 1*1 cm2 to save computing time
-  if (TMath::Abs(dPos(0,0)) > fgkMaxTrackingDistanceNonBending ||
-      TMath::Abs(dPos(1,0)) > fgkMaxTrackingDistanceBending    ||
-      TMath::Abs(dPos(2,0)) > fgkMaxTrackingDistanceNonBending ||
-      TMath::Abs(dPos(3,0)) > fgkMaxTrackingDistanceBending) return 1.e10;
-  
   // Calculate the error matrix from the track parameter covariances at first hitForRec
   TMatrixD error(4,4);
   error.Zero();
index 7bde1b5..8e0dccb 100644 (file)
@@ -49,7 +49,7 @@ ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context
 const Bool_t AliMUONTrackReconstructorK::fgkRunSmoother = kTRUE;
 
 
-//__________________________________________________________________________
+  //__________________________________________________________________________
 AliMUONTrackReconstructorK::AliMUONTrackReconstructorK()
   : AliMUONVTrackReconstructor()
 {
@@ -57,7 +57,7 @@ AliMUONTrackReconstructorK::AliMUONTrackReconstructorK()
   AliInfo("*** Tracking with Kalman Filter ***");
 }
 
-//__________________________________________________________________________
+  //__________________________________________________________________________
 AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK()
 {
 /// Destructor
@@ -66,13 +66,14 @@ AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK()
   //__________________________________________________________________________
 void AliMUONTrackReconstructorK::MakeTrackCandidates()
 {
-  /// To make track candidates:
+  /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE):
   /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4.
   /// Good candidates are made of at least three hitForRec's.
   /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks.
   TClonesArray *segments;
   AliMUONTrack *track;
   Int_t iCandidate = 0;
+  Bool_t hitFound;
 
   AliDebug(1,"Enter MakeTrackCandidates");
 
@@ -90,10 +91,6 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
       track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]));
       fNRecTracks++;
       
-      // Recompute track parameters and covariances on station(1..) 5 using Kalman filter
-      // (to make sure all tracks are treated in the same way)
-      if (istat == 4) RetraceTrack(*track,kFALSE);
-      
       // Printout for debuging
       if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
         cout<<endl<<"Track parameter covariances at first hit:"<<endl;
@@ -101,8 +98,16 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
       }
       
       // Look for compatible hitForRec(s) in the other station
+      if (fgkMakeTrackCandidatesFast) hitFound = FollowLinearTrackInStation(*track,7-istat);
+      else {
+        // First recompute track parameters and covariances on station(1..) 5 using Kalman filter
+        // (to make sure all tracks are treated in the same way)
+        if (istat == 4) RetraceTrack(*track,kFALSE);
+       hitFound = FollowTrackInStation(*track,7-istat);
+      }
+      
       // Remove track if no hit found
-      if (!FollowTrackInStation(*track,7-istat)) {
+      if (!hitFound) {
         fRecTracksPtr->Remove(track);
        fNRecTracks--;
       }
@@ -112,18 +117,24 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates()
     delete segments;
   }
   
-  fRecTracksPtr->Compress(); // this is essential before checking tracks
   
-  // Remove bad tracks
-  Int_t currentNRecTracks = fNRecTracks;
-  for (Int_t iRecTrack = 0; iRecTrack < currentNRecTracks; iRecTrack++) {
-    
-    track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
+  // Retrace tracks using Kalman filter and remove bad ones
+  if (fgkMakeTrackCandidatesFast) {
+    fRecTracksPtr->Compress(); // this is essential before checking tracks
     
-    // Remove the track if the normalized chi2 is too high
-    if (track->GetNormalizedChi2() > fgkSigmaToCutForTracking * fgkSigmaToCutForTracking) {
-      fRecTracksPtr->Remove(track);
-      fNRecTracks--;
+    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() > fgkSigmaToCutForTracking * fgkSigmaToCutForTracking) {
+        fRecTracksPtr->Remove(track);
+        fNRecTracks--;
+      }
+      
     }
     
   }
@@ -294,21 +305,6 @@ void AliMUONTrackReconstructorK::FollowTracks()
     
     fRecTracksPtr->Compress(); // this is essential before checking tracks
     
-    // Remove bad tracks
-    Int_t currentNRecTracks = fNRecTracks;
-    for (Int_t iRecTrack = 0; iRecTrack < currentNRecTracks; iRecTrack++) {
-      track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
-      
-      // Remove the track if the normalized chi2 is too high
-      if (track->GetNormalizedChi2() > fgkSigmaToCutForTracking * fgkSigmaToCutForTracking) {
-       fRecTracksPtr->Remove(track);
-       fNRecTracks--;
-      }
-      
-    }
-    
-    fRecTracksPtr->Compress(); // this is essential before checking tracks
-    
     // Keep only the best tracks if required
     if (!fgkTrackAllTracks) RemoveDoubleTracks();
     
@@ -340,7 +336,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     ch2 = 2*nextStation+1;
   }
   
-  Double_t zCh2 = AliMUONConstants::DefaultChamberZ(ch2);
   Double_t chi2OfHitForRec;
   Double_t maxChi2OfHitForRec = 2. * fgkSigmaToCutForTracking * fgkSigmaToCutForTracking; // 2 because 2 quantities in chi2
   Double_t addChi2TrackAtHit1;
@@ -359,30 +354,30 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
   Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]];
   for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE;
   
-  // Get track parameters and extrapolate them to chamber "ch2" to save computing time in the next steps
-  AliMUONTrackParam extrapTrackParamAtCh2(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
+  // Get track parameters
+  AliMUONTrackParam extrapTrackParamAtCh(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
   
   // Add MCS effect
-  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh2,AliMUONConstants::ChamberThicknessInX0(),1.);
+  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
   
   // reset propagator for smoother
-  if (fgkRunSmoother) extrapTrackParamAtCh2.ResetPropagator();
+  if (fgkRunSmoother) extrapTrackParamAtCh.ResetPropagator();
   
   // Add MCS in the missing chamber if any (only 1 chamber can be missing according to tracking criteria)
-  if (ch1 < ch2 && extrapTrackParamAtCh2.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) {
+  if (ch1 < ch2 && extrapTrackParamAtCh.GetHitForRecPtr()->GetChamberNumber() > ch2 + 1) {
     // extrapolation to the missing chamber
-    AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh2, AliMUONConstants::DefaultChamberZ(ch2 + 1), fgkRunSmoother);
+    AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2 + 1), fgkRunSmoother);
     // add MCS effect
-    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh2,AliMUONConstants::ChamberThicknessInX0(),1.);
+    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
   }
   
   //Extrapolate trackCandidate to chamber "ch2"
-  AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh2, zCh2, fgkRunSmoother);
+  AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2), fgkRunSmoother);
   
   // Printout for debuging
   if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
-    cout<<endl<<"Track parameter covariances at first hit extrapolated to z = "<<zCh2<<":"<<endl;
-    extrapTrackParamAtCh2.GetCovariances().Print();
+    cout<<endl<<"Track parameter covariances at first hit extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
+    extrapTrackParamAtCh.GetCovariances().Print();
   }
   
   // Printout for debuging
@@ -395,8 +390,11 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     
     hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2);
     
-    // try to add the current hit
-    chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh2, hitForRecCh2, extrapTrackParamAtHit2, fgkRunSmoother);
+    // try to add the current hit fast
+    if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh2)) continue;
+    
+    // try to add the current hit accuratly
+    chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh2, extrapTrackParamAtHit2, fgkRunSmoother);
     
     // if good chi2 then try to attach a hitForRec in the other chamber too
     if (chi2OfHitForRec < maxChi2OfHitForRec) {
@@ -429,13 +427,19 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
       // reset propagator for smoother
       if (fgkRunSmoother) extrapTrackParam.ResetPropagator();
       
+      //Extrapolate track parameters to chamber "ch1"
+      AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1), fgkRunSmoother);
+      
       for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
         
        hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
        
-        // try to add the current hit
-       chi2OfHitForRec = TryOneHitForRec(extrapTrackParam, hitForRecCh1, extrapTrackParamAtHit1, fgkRunSmoother);
-        
+       // try to add the current hit fast
+       if (!TryOneHitForRecFast(extrapTrackParam, hitForRecCh1)) continue;
+       
+       // try to add the current hit accuratly
+       chi2OfHitForRec = TryOneHitForRec(extrapTrackParam, hitForRecCh1, extrapTrackParamAtHit1, fgkRunSmoother);
+       
        // if good chi2 then consider to add the 2 hitForRec to the "trackCandidate"
        if (chi2OfHitForRec < maxChi2OfHitForRec) {
          foundSecondHit = kTRUE;
@@ -446,7 +450,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
            cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
                 << " (Chi2 = " << chi2OfHitForRec << ")" << endl;
          }
-         
+          
           if (fgkRunSmoother) {
             // save extrapolated parameters for smoother
             extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters());
@@ -510,8 +514,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          }
          
        } else if (!foundTwoHits && addChi2TrackAtHit2 < bestAddChi2TrackAtHit1) {
-         // keep track of the best single hitForRec except if a couple
-          // of hits has already been found (i.e. bestHitForRec2!=0x0)
+         // keep track of the best single hitForRec except if a couple of hits has already been found
          bestAddChi2TrackAtHit1 = addChi2TrackAtHit2;
          bestTrackParamAtHit1 = extrapTrackParamAtHit2;
         }
@@ -532,17 +535,23 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
     }
     
     // add MCS effect for next step
-    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh2,AliMUONConstants::ChamberThicknessInX0(),1.);
-      
+    AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.);
+    
+    //Extrapolate trackCandidate to chamber "ch1"
+    AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1), fgkRunSmoother);
+    
     for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
       
       hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
       
       if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used
       
-      // try to add the current hit
-      chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh2, hitForRecCh1, extrapTrackParamAtHit1, fgkRunSmoother);
-    
+      // try to add the current hit fast
+      if (!TryOneHitForRecFast(extrapTrackParamAtCh, hitForRecCh1)) continue;
+      
+      // try to add the current hit accuratly
+      chi2OfHitForRec = TryOneHitForRec(extrapTrackParamAtCh, hitForRecCh1, extrapTrackParamAtHit1, fgkRunSmoother);
+      
       // if good chi2 then consider to add hitForRecCh1
       // We do not try to attach a hitForRec in the other chamber too since it has already been done above
       if (chi2OfHitForRec < maxChi2OfHitForRec) {
@@ -553,7 +562,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
               << " (Chi2 = " << chi2OfHitForRec << ")" << endl;
        }
-       
+        
        if (fgkRunSmoother) {
           // save extrapolated parameters for smoother
           extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters());
@@ -582,8 +591,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi
          }
          
        } else if (addChi2TrackAtHit1 < bestAddChi2TrackAtHit1) {
-         // keep track of the best single hitForRec except if a couple
-         // of hits has already been found (i.e. bestHitForRec1!=0x0)
+         // keep track of the best single hitForRec except if a couple of hits has already been found
          bestAddChi2TrackAtHit1 = addChi2TrackAtHit1;
          bestTrackParamAtHit1 = extrapTrackParamAtHit1;
        }
index 2632d6d..e30a560 100644 (file)
@@ -22,7 +22,6 @@
 ///
 /// This class contains as data:
 /// * a pointer to the array of hits to be reconstructed (the event)
-/// * a pointer to the array of segments made with these hits inside each station
 /// * a pointer to the array of reconstructed tracks
 ///
 /// It contains as methods, among others:
@@ -33,6 +32,8 @@
 /// tracking algorithms (hard coded for the moment in AliMUONVTrackReconstructor.cxx):
 /// - *fgkSigmaToCutForTracking* : quality cut used to select new clusters to be
 ///   attached to the track candidate and to select good tracks.
+/// - *fgkMakeTrackCandidatesFast* : if this flag is set to 'true', the track candidates
+///   are made assuming linear propagation between stations 4 and 5.
 /// - *fgkTrackAllTracks* : according to the value of this flag, in case that several
 ///   new clusters pass the quality cut, either we consider all the possibilities
 ///   (duplicating tracks) or we attach only the best cluster.
 ClassImp(AliMUONVTrackReconstructor) // Class implementation in ROOT context
 /// \endcond
 
+
 //************* Defaults parameters for reconstruction
 const Double_t AliMUONVTrackReconstructor::fgkDefaultMinBendingMomentum = 3.0;
 const Double_t AliMUONVTrackReconstructor::fgkDefaultMaxBendingMomentum = 3000.0;
 const Double_t AliMUONVTrackReconstructor::fgkDefaultMaxNormChi2MatchTrigger = 16.0;
+const Double_t AliMUONVTrackReconstructor::fgkMaxTrackingDistanceBending    = 2.;
+const Double_t AliMUONVTrackReconstructor::fgkMaxTrackingDistanceNonBending = 2.;
 
 const Double_t AliMUONVTrackReconstructor::fgkSigmaToCutForTracking = 6.0;
-const Double_t AliMUONVTrackReconstructor::fgkSigmaToCutForImprovement = 4.0;
+const Bool_t   AliMUONVTrackReconstructor::fgkMakeTrackCandidatesFast = kFALSE;
 const Bool_t   AliMUONVTrackReconstructor::fgkTrackAllTracks = kTRUE;
-const Double_t AliMUONVTrackReconstructor::fgkMaxTrackingDistanceBending    = 2.;
-const Double_t AliMUONVTrackReconstructor::fgkMaxTrackingDistanceNonBending = 2.;
 const Bool_t   AliMUONVTrackReconstructor::fgkRecoverTracks = kTRUE;
 const Bool_t   AliMUONVTrackReconstructor::fgkImproveTracks = kTRUE;
+const Double_t AliMUONVTrackReconstructor::fgkSigmaToCutForImprovement = 4.0;
 
 
   //__________________________________________________________________________
@@ -454,47 +457,350 @@ Double_t AliMUONVTrackReconstructor::TryOneHitForRec(const AliMUONTrackParam &tr
 /// return the corresponding Chi2
 /// return trackParamAtHit
   
-  if (!trackParam.CovariancesExist()) AliWarning(" track parameter covariance matrix does not exist");
-  
   // extrapolate track parameters and covariances at the z position of the tested hit
-  if (&trackParam != &trackParamAtHit) {
-    trackParamAtHit = trackParam;
-    AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtHit, hitForRec->GetZ(), updatePropagator);
-  }
+  trackParamAtHit = trackParam;
+  AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtHit, hitForRec->GetZ(), updatePropagator);
   
   // set pointer to hit into trackParamAtHit
   trackParamAtHit.SetHitForRecPtr(hitForRec);
   
   // Set differences between trackParam and hitForRec in the bending and non bending directions
-  TMatrixD dPos(2,1);
-  dPos(0,0) = hitForRec->GetNonBendingCoor() - trackParamAtHit.GetNonBendingCoor();
-  dPos(1,0) = hitForRec->GetBendingCoor() - trackParamAtHit.GetBendingCoor();
+  Double_t dX = hitForRec->GetNonBendingCoor() - trackParamAtHit.GetNonBendingCoor();
+  Double_t dY = hitForRec->GetBendingCoor() - trackParamAtHit.GetBendingCoor();
   
-  // quick test of hitForRec compatibility within a wide road of x*y = 10*1 cm2 to save computing time
-  if (TMath::Abs(dPos(0,0)) > fgkMaxTrackingDistanceNonBending ||
-      TMath::Abs(dPos(1,0)) > fgkMaxTrackingDistanceBending) return 1.e10;
-  
-  // Set the error matrix from trackParam covariances and hitForRec resolution
+  // Calculate errors and covariances
   const TMatrixD& kParamCov = trackParamAtHit.GetCovariances();
-  TMatrixD error(2,2);
-  error(0,0) = kParamCov(0,0) + hitForRec->GetNonBendingReso2();
-  error(0,1) = kParamCov(0,2);
-  error(1,0) = kParamCov(2,0);
-  error(1,1) = kParamCov(2,2) + hitForRec->GetBendingReso2();
-  
-  // Invert the error matrix for Chi2 calculation
-  if (error.Determinant() != 0) {
-    error.Invert();
+  Double_t sigma2X = kParamCov(0,0) + hitForRec->GetNonBendingReso2();
+  Double_t sigma2Y = kParamCov(2,2) + hitForRec->GetBendingReso2();
+  
+  // Compute chi2
+  return dX * dX / sigma2X + dY * dY / sigma2Y;
+  
+}
+
+  //__________________________________________________________________________
+Bool_t AliMUONVTrackReconstructor::TryOneHitForRecFast(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec)
+{
+/// Test the compatibility between the track and the hitForRec within a wide fix window
+/// assuming linear propagation of the track:
+/// return kTRUE if they are compatibles
+  
+  Double_t dZ = hitForRec->GetZ() - trackParam.GetZ();
+  Double_t dX = hitForRec->GetNonBendingCoor() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ);
+  Double_t dY = hitForRec->GetBendingCoor() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ);
+  
+  if (TMath::Abs(dX) > fgkMaxTrackingDistanceNonBending || TMath::Abs(dY) > fgkMaxTrackingDistanceBending) return kFALSE;
+  
+  return kTRUE;
+  
+}
+
+  //__________________________________________________________________________
+Double_t AliMUONVTrackReconstructor::TryTwoHitForRecFast(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2,
+                                                        AliMUONTrackParam &trackParamAtHit2)
+{
+/// Test the compatibility between the track and the 2 hitForRec together (using trackParam's covariance matrix)
+/// assuming linear propagation between the two hits:
+/// return the corresponding Chi2 accounting for covariances between the 2 hitForRec
+/// return trackParamAtHit1 & 2
+  
+  // extrapolate linearly track parameters at the z position of the second hit
+  trackParamAtHit2 = trackParamAtHit1;
+  AliMUONTrackExtrap::LinearExtrapToZ(&trackParamAtHit2, hitForRec2->GetZ());
+  
+  // set pointer to hit2 into trackParamAtHit2
+  trackParamAtHit2.SetHitForRecPtr(hitForRec2);
+  
+  // Set differences between track and hitForRec in the bending and non bending directions
+  AliMUONHitForRec* hitForRec1 = trackParamAtHit1.GetHitForRecPtr();
+  Double_t dX1 = hitForRec1->GetNonBendingCoor() - trackParamAtHit1.GetNonBendingCoor();
+  Double_t dX2 = hitForRec2->GetNonBendingCoor() - trackParamAtHit2.GetNonBendingCoor();
+  Double_t dY1 = hitForRec1->GetBendingCoor() - trackParamAtHit1.GetBendingCoor();
+  Double_t dY2 = hitForRec2->GetBendingCoor() - trackParamAtHit2.GetBendingCoor();
+  
+  // Calculate errors and covariances
+  const TMatrixD& kParamCov1 = trackParamAtHit1.GetCovariances();
+  const TMatrixD& kParamCov2 = trackParamAtHit2.GetCovariances();
+  Double_t dZ = trackParamAtHit2.GetZ() - trackParamAtHit1.GetZ();
+  Double_t sigma2X1 = kParamCov1(0,0) + hitForRec1->GetNonBendingReso2();
+  Double_t sigma2X2 = kParamCov2(0,0) + hitForRec2->GetNonBendingReso2();
+  Double_t covX1X2  = kParamCov1(0,0) + dZ * kParamCov1(0,1);
+  Double_t sigma2Y1 = kParamCov1(2,2) + hitForRec1->GetBendingReso2();
+  Double_t sigma2Y2 = kParamCov2(2,2) + hitForRec2->GetBendingReso2();
+  Double_t covY1Y2  = kParamCov1(2,2) + dZ * kParamCov1(2,3);
+  
+  // Compute chi2
+  Double_t detX = sigma2X1 * sigma2X2 - covX1X2 * covX1X2;
+  Double_t detY = sigma2Y1 * sigma2Y2 - covY1Y2 * covY1Y2;
+  if (detX == 0. || detY == 0.) return 1.e10;
+  return   (dX1 * dX1 * sigma2X2 + dX2 * dX2 * sigma2X1 - 2. * dX1 * dX2 * covX1X2) / detX
+        + (dY1 * dY1 * sigma2Y2 + dY2 * dY2 * sigma2Y1 - 2. * dY1 * dY2 * covY1Y2) / detY;
+  
+}
+
+  //__________________________________________________________________________
+Bool_t AliMUONVTrackReconstructor::FollowLinearTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation)
+{
+  /// Follow trackCandidate in station(0..) nextStation assuming linear propagation, and search for compatible HitForRec(s)
+  /// Keep all possibilities or only the best one(s) according to the flag fgkTrackAllTracks:
+  /// kTRUE:  duplicate "trackCandidate" if there are several possibilities and add the new tracks at the end of
+  ///         fRecTracksPtr to avoid conficts with other track candidates at this current stage of the tracking procedure.
+  ///         Remove the obsolete "trackCandidate" at the end.
+  /// kFALSE: add only the best hit(s) to the "trackCandidate". Try to add a couple of hits in priority.
+  /// return kTRUE if new hits have been found (otherwise return kFALSE)
+  AliDebug(1,Form("Enter FollowLinearTrackInStation(1..) %d", nextStation+1));
+  
+  // Order the chamber according to the propagation direction (tracking starts with chamber 2):
+  // - nextStation == station(1...) 5 => forward propagation
+  // - nextStation < station(1...) 5 => backward propagation
+  Int_t ch1, ch2;
+  if (nextStation==4) {
+    ch1 = 2*nextStation+1;
+    ch2 = 2*nextStation;
   } else {
-    AliWarning(" Determinant error=0");
-    return 1.e10;
+    ch1 = 2*nextStation;
+    ch2 = 2*nextStation+1;
+  }
+  
+  Double_t chi2WithOneHitForRec = 1.e10;
+  Double_t chi2WithTwoHitForRec = 1.e10;
+  Double_t maxChi2WithOneHitForRec = 2. * fgkSigmaToCutForTracking * fgkSigmaToCutForTracking; // 2 because 2 quantities in chi2
+  Double_t maxChi2WithTwoHitForRec = 4. * fgkSigmaToCutForTracking * fgkSigmaToCutForTracking; // 4 because 4 quantities in chi2
+  Double_t bestChi2WithOneHitForRec = maxChi2WithOneHitForRec;
+  Double_t bestChi2WithTwoHitForRec = maxChi2WithTwoHitForRec;
+  Bool_t foundOneHit = kFALSE;
+  Bool_t foundTwoHits = kFALSE;
+  AliMUONTrack *newTrack = 0x0;
+  AliMUONHitForRec *hitForRecCh1, *hitForRecCh2;
+  AliMUONTrackParam extrapTrackParamAtHit1;
+  AliMUONTrackParam extrapTrackParamAtHit2;
+  AliMUONTrackParam bestTrackParamAtHit1;
+  AliMUONTrackParam bestTrackParamAtHit2;
+  Bool_t *hitForRecCh1Used = new Bool_t[fNHitsForRecPerChamber[ch1]];
+  for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) hitForRecCh1Used[hit1] = kFALSE;
+  
+  // Get track parameters
+  AliMUONTrackParam trackParam(*(AliMUONTrackParam*)trackCandidate.GetTrackParamAtHit()->First());
+  
+  // Add MCS effect
+  AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
+  
+  // Printout for debuging
+  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+    cout << "FollowLinearTrackInStation: look for hits in chamber(1..): " << ch2+1 << endl;
+  }
+  
+  // look for candidates in chamber 2 
+  for (Int_t hit2 = 0; hit2 < fNHitsForRecPerChamber[ch2]; hit2++) {
+    
+    hitForRecCh2 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch2]+hit2);
+    
+    // try to add the current hit fast
+    if (!TryOneHitForRecFast(trackParam, hitForRecCh2)) continue;
+    
+    // try to add the current hit accuratly
+    extrapTrackParamAtHit2 = trackParam;
+    AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtHit2, hitForRecCh2->GetZ());
+    chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtHit2, hitForRecCh2, extrapTrackParamAtHit2);
+    
+    // if good chi2 then try to attach a hitForRec in the other chamber too
+    if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
+      Bool_t foundSecondHit = kFALSE;
+      
+      // Printout for debuging
+      if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+        cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch2+1
+            << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl;
+        cout << "                      look for second hits in chamber(1..): " << ch1+1 << " ..." << endl;
+      }
+      
+      // add MCS effect
+      AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtHit2,AliMUONConstants::ChamberThicknessInX0(),1.);
+      
+      for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
+        
+       hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+       
+        // try to add the current hit fast
+        if (!TryOneHitForRecFast(extrapTrackParamAtHit2, hitForRecCh1)) continue;
+       
+       // try to add the current hit in addition to the one found on the previous chamber
+       chi2WithTwoHitForRec = TryTwoHitForRecFast(extrapTrackParamAtHit2, hitForRecCh1, extrapTrackParamAtHit1);
+        
+       // if good chi2 then consider to add the 2 hitForRec to the "trackCandidate"
+       if (chi2WithTwoHitForRec < maxChi2WithTwoHitForRec) {
+         foundSecondHit = kTRUE;
+         foundTwoHits = kTRUE;
+          
+         // Printout for debuging
+         if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+           cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch1+1
+                << " (Chi2 = " << chi2WithTwoHitForRec << ")" << endl;
+         }
+         
+         if (fgkTrackAllTracks) {
+           // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+            newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
+           extrapTrackParamAtHit1.SetRemovable(kTRUE);
+           newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit1,hitForRecCh1);
+           extrapTrackParamAtHit2.SetRemovable(kTRUE);
+           newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit2,hitForRecCh2);
+           newTrack->GetTrackParamAtHit()->Sort();
+           fNRecTracks++;
+           
+           // Tag hitForRecCh1 as used
+           hitForRecCh1Used[hit1] = kTRUE;
+           
+           // Printout for debuging
+           if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+             cout << "FollowLinearTrackInStation: added two hits in station(1..): " << nextStation+1 << endl;
+             if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+           }
+           
+          } else if (chi2WithTwoHitForRec < bestChi2WithTwoHitForRec) {
+           // keep track of the best couple of hits
+           bestChi2WithTwoHitForRec = chi2WithTwoHitForRec;
+           bestTrackParamAtHit1 = extrapTrackParamAtHit1;
+           bestTrackParamAtHit2 = extrapTrackParamAtHit2;
+          }
+         
+       }
+       
+      }
+      
+      // if no hitForRecCh1 found then consider to add hitForRecCh2 only
+      if (!foundSecondHit) {
+       foundOneHit = kTRUE;
+        
+       if (fgkTrackAllTracks) {
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+          newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
+         extrapTrackParamAtHit2.SetRemovable(kFALSE);
+         newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit2,hitForRecCh2);
+         newTrack->GetTrackParamAtHit()->Sort();
+         fNRecTracks++;
+         
+         // Printout for debuging
+         if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+           cout << "FollowLinearTrackInStation: added one hit in chamber(1..): " << ch2+1 << endl;
+           if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+         }
+         
+       } else if (!foundTwoHits && chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
+         // keep track of the best single hitForRec except if a couple of hits has already been found
+         bestChi2WithOneHitForRec = chi2WithOneHitForRec;
+         bestTrackParamAtHit1 = extrapTrackParamAtHit2;
+        }
+       
+      }
+      
+    }
+    
   }
   
-  // Compute the Chi2 value
-  TMatrixD tmp(dPos,TMatrixD::kTransposeMult,error);
-  TMatrixD result(tmp,TMatrixD::kMult,dPos);
+  // look for candidates in chamber 1 not already attached to a track
+  // if we want to keep all possible tracks or if no good couple of hitForRec has been found
+  if (fgkTrackAllTracks || !foundTwoHits) {
+    
+    // Printout for debuging
+    if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+      cout << "FollowLinearTrackInStation: look for single hits in chamber(1..): " << ch1+1 << endl;
+    }
+    
+    //Extrapolate trackCandidate to chamber "ch2"
+    AliMUONTrackExtrap::LinearExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(ch2));
+    
+    // add MCS effect for next step
+    AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.);
+      
+    for (Int_t hit1 = 0; hit1 < fNHitsForRecPerChamber[ch1]; hit1++) {
+      
+      hitForRecCh1 = (AliMUONHitForRec*) fHitsForRecPtr->UncheckedAt(fIndexOfFirstHitForRecPerChamber[ch1]+hit1);
+      
+      if (hitForRecCh1Used[hit1]) continue; // Skip hitForRec already used
+      
+      // try to add the current hit fast
+      if (!TryOneHitForRecFast(trackParam, hitForRecCh1)) continue;
+       
+      // try to add the current hit accuratly
+      extrapTrackParamAtHit1 = trackParam;
+      AliMUONTrackExtrap::LinearExtrapToZ(&extrapTrackParamAtHit1, hitForRecCh1->GetZ());
+      chi2WithOneHitForRec = TryOneHitForRec(extrapTrackParamAtHit1, hitForRecCh1, extrapTrackParamAtHit1);
+    
+      // if good chi2 then consider to add hitForRecCh1
+      // We do not try to attach a hitForRec in the other chamber too since it has already been done above
+      if (chi2WithOneHitForRec < maxChi2WithOneHitForRec) {
+       foundOneHit = kTRUE;
+       
+       // Printout for debuging
+       if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+         cout << "FollowLinearTrackInStation: found one hit in chamber(1..): " << ch1+1
+              << " (Chi2 = " << chi2WithOneHitForRec << ")" << endl;
+       }
+       
+       if (fgkTrackAllTracks) {
+         // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new hitForRec's
+         newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
+         extrapTrackParamAtHit1.SetRemovable(kFALSE);
+         newTrack->AddTrackParamAtHit(&extrapTrackParamAtHit1,hitForRecCh1);
+         newTrack->GetTrackParamAtHit()->Sort();
+         fNRecTracks++;
+         
+         // Printout for debuging
+         if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+           cout << "FollowLinearTrackInStation: added one hit in chamber(1..): " << ch1+1 << endl;
+           if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+         }
+         
+       } else if (chi2WithOneHitForRec < bestChi2WithOneHitForRec) {
+         // keep track of the best single hitForRec except if a couple of hits has already been found
+         bestChi2WithOneHitForRec = chi2WithOneHitForRec;
+         bestTrackParamAtHit1 = extrapTrackParamAtHit1;
+       }
+       
+      }
+      
+    }
+    
+  }
+  
+  // fill out the best track if required else clean up the fRecTracksPtr array
+  if (!fgkTrackAllTracks) {
+    if (foundTwoHits) {
+      bestTrackParamAtHit1.SetRemovable(kTRUE);
+      trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit1,bestTrackParamAtHit1.GetHitForRecPtr());
+      bestTrackParamAtHit2.SetRemovable(kTRUE);
+      trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit2,bestTrackParamAtHit2.GetHitForRecPtr());
+      trackCandidate.GetTrackParamAtHit()->Sort();
+      
+      // Printout for debuging
+      if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+        cout << "FollowLinearTrackInStation: added the two best hits in station(1..): " << nextStation+1 << endl;
+        if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+      }
+      
+    } else if (foundOneHit) {
+      bestTrackParamAtHit1.SetRemovable(kFALSE);
+      trackCandidate.AddTrackParamAtHit(&bestTrackParamAtHit1,bestTrackParamAtHit1.GetHitForRecPtr());
+      trackCandidate.GetTrackParamAtHit()->Sort();
+      
+      // Printout for debuging
+      if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
+        cout << "FollowLinearTrackInStation: added the best hit in chamber(1..): " << bestTrackParamAtHit1.GetHitForRecPtr()->GetChamberNumber()+1 << endl;
+        if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
+      }
+      
+    } else return kFALSE;
+    
+  } else if (foundOneHit || foundTwoHits) {
+    
+    // remove obsolete track
+    fRecTracksPtr->Remove(&trackCandidate);
+    fNRecTracks--;
+    
+  } else return kFALSE;
   
-  return result(0,0);
+  return kTRUE;
   
 }
 
index 6be1720..5994a1d 100644 (file)
@@ -14,6 +14,7 @@
 #include <TObject.h>
 
 class TClonesArray;
+class AliMUONTrack;
 class AliMUONTrackParam;
 class AliMUONHitForRec;
 class AliMUONTriggerTrack;
@@ -69,6 +70,7 @@ class AliMUONVTrackReconstructor : public TObject {
   // Parameters for track reconstruction
   static const Double_t fgkSigmaToCutForTracking; ///< cut in sigma to apply on cluster local chi2 and track global chi2 during tracking
   static const Double_t fgkSigmaToCutForImprovement; ///< cut in sigma to apply on cluster local chi2 during track improvement
+  static const Bool_t   fgkMakeTrackCandidatesFast; ///< kTRUE to make track candidates assuming linear propagation between stations 4 and 5
   static const Bool_t   fgkTrackAllTracks; ///< kTRUE to track all the possible candidates; kFALSE to track only the best ones
   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
@@ -110,6 +112,11 @@ class AliMUONVTrackReconstructor : public TObject {
 
   Double_t TryOneHitForRec(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec,
                           AliMUONTrackParam &trackParamAtHit, Bool_t updatePropagator = kFALSE);
+  Bool_t   TryOneHitForRecFast(const AliMUONTrackParam &trackParam, AliMUONHitForRec* hitForRec);
+  Double_t TryTwoHitForRecFast(const AliMUONTrackParam &trackParamAtHit1, AliMUONHitForRec* hitForRec2,
+                              AliMUONTrackParam &trackParamAtHit2);
+
+  Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, Int_t nextStation);
   
 
  private:
index 753a847..c1489f4 100644 (file)
@@ -142,6 +142,8 @@ several options and adjustable parameters are available for both Kalman and Orig
 tracking algorithms (hard coded for the moment in AliMUONVTrackReconstructor.cxx):
 - *fgkSigmaToCutForTracking* : quality cut used to select new clusters to be
   attached to the track candidate and to select good tracks.
+- *fgkMakeTrackCandidatesFast* : if this flag is set to 'true', the track candidates
+  are made assuming linear propagation between stations 4 and 5.
 - *fgkTrackAllTracks* : according to the value of this flag, in case that several
   new clusters pass the quality cut, either we consider all the possibilities
   (duplicating tracks) or we attach only the best cluster.