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