(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.)
}
} 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++;
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
Double_t simpleBValue = (Double_t) b[0];
return (-0.0003 * simpleBValue * simpleBLength * simpleBPosition / impactParam);
+}
+
+ //__________________________________________________________________________
+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);
+ }
+
}
//__________________________________________________________________________
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);
if (theMUONTrackParam.fCovariances) {
if (fCovariances) *fCovariances = *(theMUONTrackParam.fCovariances);
else fCovariances = new TMatrixD(*(theMUONTrackParam.fCovariances));
- } else if (fCovariances) {
+ } else {
delete fCovariances;
fCovariances = 0x0;
}
if (theMUONTrackParam.fPropagator) {
if (fPropagator) *fPropagator = *(theMUONTrackParam.fPropagator);
else fPropagator = new TMatrixD(*(theMUONTrackParam.fPropagator));
- } else if (fPropagator) {
+ } else {
delete fPropagator;
fPropagator = 0x0;
}
if (theMUONTrackParam.fExtrapParameters) {
if (fExtrapParameters) *fExtrapParameters = *(theMUONTrackParam.fExtrapParameters);
else fExtrapParameters = new TMatrixD(*(theMUONTrackParam.fExtrapParameters));
- } else if (fExtrapParameters) {
+ } else {
delete fExtrapParameters;
fExtrapParameters = 0x0;
}
if (theMUONTrackParam.fExtrapCovariances) {
if (fExtrapCovariances) *fExtrapCovariances = *(theMUONTrackParam.fExtrapCovariances);
else fExtrapCovariances = new TMatrixD(*(theMUONTrackParam.fExtrapCovariances));
- } else if (fExtrapCovariances) {
+ } else {
delete fExtrapCovariances;
fExtrapCovariances = 0x0;
}
if (theMUONTrackParam.fSmoothParameters) {
if (fSmoothParameters) *fSmoothParameters = *(theMUONTrackParam.fSmoothParameters);
else fSmoothParameters = new TMatrixD(*(theMUONTrackParam.fSmoothParameters));
- } else if (fSmoothParameters) {
+ } else {
delete fSmoothParameters;
fSmoothParameters = 0x0;
}
if (theMUONTrackParam.fSmoothCovariances) {
if (fSmoothCovariances) *fSmoothCovariances = *(theMUONTrackParam.fSmoothCovariances);
else fSmoothCovariances = new TMatrixD(*(theMUONTrackParam.fSmoothCovariances));
- } else if (fSmoothCovariances) {
+ } else {
delete fSmoothCovariances;
fSmoothCovariances = 0x0;
}
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);
}
/// Return the propagator (create it before if needed)
if (!fPropagator) {
fPropagator = new TMatrixD(5,5);
- fPropagator->Zero();
+ fPropagator->UnitMatrix();
}
return *fPropagator;
}
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);
}
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);
}
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);
}
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);
}
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);
}
const Double_t AliMUONTrackReconstructor::fgkNonBendingVertexDispersion = 10.;
-//__________________________________________________________________________
+ //__________________________________________________________________________
AliMUONTrackReconstructor::AliMUONTrackReconstructor()
: AliMUONVTrackReconstructor()
{
AliInfo("*** Original tracking ***");
}
-//__________________________________________________________________________
+ //__________________________________________________________________________
AliMUONTrackReconstructor::~AliMUONTrackReconstructor()
{
/// Destructor
//__________________________________________________________________________
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");
}
// 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--;
}
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
Bool_t foundTwoHits = kFALSE;
AliMUONTrack *newTrack = 0x0;
AliMUONHitForRec *hitForRecCh1, *hitForRecCh2;
+ AliMUONTrackParam extrapTrackParam;
AliMUONTrackParam extrapTrackParamAtHit1;
AliMUONTrackParam extrapTrackParamAtHit2;
AliMUONTrackParam bestTrackParamAtHit1;
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
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) {
// 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"
}
} 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;
}
}
// 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
}
} 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;
}
}
//__________________________________________________________________________
-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());
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();
const Bool_t AliMUONTrackReconstructorK::fgkRunSmoother = kTRUE;
-//__________________________________________________________________________
+ //__________________________________________________________________________
AliMUONTrackReconstructorK::AliMUONTrackReconstructorK()
: AliMUONVTrackReconstructor()
{
AliInfo("*** Tracking with Kalman Filter ***");
}
-//__________________________________________________________________________
+ //__________________________________________________________________________
AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK()
{
/// Destructor
//__________________________________________________________________________
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");
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;
}
// 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--;
}
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--;
+ }
+
}
}
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();
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;
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
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) {
// 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;
cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
<< " (Chi2 = " << chi2OfHitForRec << ")" << endl;
}
-
+
if (fgkRunSmoother) {
// save extrapolated parameters for smoother
extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters());
}
} 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;
}
}
// 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) {
cout << "FollowTrackInStation: found one hit in chamber(1..): " << ch1+1
<< " (Chi2 = " << chi2OfHitForRec << ")" << endl;
}
-
+
if (fgkRunSmoother) {
// save extrapolated parameters for smoother
extrapTrackParamAtHit1.SetExtrapParameters(extrapTrackParamAtHit1.GetParameters());
}
} 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;
}
///
/// 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:
/// 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;
//__________________________________________________________________________
/// 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;
}
#include <TObject.h>
class TClonesArray;
+class AliMUONTrack;
class AliMUONTrackParam;
class AliMUONHitForRec;
class AliMUONTriggerTrack;
// 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
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:
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.