X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONTrackReconstructorK.cxx;h=7f18155a90b5ac687f878fb8d6a9c2eb584fd434;hb=b85ea106fc895e812397f1f3bab3ce9d20798225;hp=912cdf49d4cf4cbb5a9819947fd1ad2629f8fe6a;hpb=5a240757bd78901da589c49d12109dbdd63cfe46;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONTrackReconstructorK.cxx b/MUON/AliMUONTrackReconstructorK.cxx index 912cdf49d4c..7f18155a90b 100644 --- a/MUON/AliMUONTrackReconstructorK.cxx +++ b/MUON/AliMUONTrackReconstructorK.cxx @@ -65,14 +65,15 @@ AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK() } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clusterStore) { - /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE): + /// To make track candidates (assuming linear propagation if AliMUONRecoParam::MakeTrackCandidatesFast() return kTRUE): /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4. - /// Good candidates are made of at least three clusters if both station are requested (two otherwise). - /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks. + /// Good candidates are made of at least three clusters if both stations are requested (two otherwise). + /// Keep only best candidates or all of them according to the flag AliMUONRecoParam::TrackAllTracks(). TClonesArray *segments; + AliMUONObjectPair *segment; AliMUONTrack *track; Int_t iCandidate = 0; Bool_t clusterFound; @@ -101,82 +102,83 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust segments = MakeSegmentsBetweenChambers(clusterStore, 2*istat, 2*istat+1); // Loop over segments - for (Int_t iseg=0; isegGetEntriesFast(); iseg++) { + for (Int_t iSegment=0; iSegmentGetEntriesFast(); iSegment++) { AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate)); + segment = (AliMUONObjectPair*) segments->UncheckedAt(iSegment); // Transform segments to tracks and put them at the end of fRecTracksPtr - track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]),GetRecoParam()->GetBendingVertexDispersion()); + track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion()); fNRecTracks++; // Look for compatible cluster(s) in the other station - if (GetRecoParam()->MakeTrackCandidatesFast()) - clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat); - else { - // First recompute track parameters and covariances on station(1..) 5 using Kalman filter - // (to make sure all tracks are treated in the same way) - if (istat == 4) RetraceTrack(*track, kTRUE); - clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat); - } + if (GetRecoParam()->MakeTrackCandidatesFast()) clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat); + else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat); // Remove track if no cluster found on a requested station - if (!clusterFound) { - if (GetRecoParam()->RequestStation(7-istat)) { - fRecTracksPtr->Remove(track); - fNRecTracks--; - } else if (istat == 3 && !GetRecoParam()->MakeTrackCandidatesFast()) { - // update track parameters and covariances using Kalman filter - RetraceTrack(*track, kTRUE); + // or abort tracking if there are too many candidates + if (GetRecoParam()->RequestStation(7-istat)) { + if (!clusterFound) { + fRecTracksPtr->Remove(track); + fNRecTracks--; + } else if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks)); + delete segments; + return kFALSE; + } + } else { + if ((fNRecTracks + segments->GetEntriesFast() - iSegment - 1) > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks + segments->GetEntriesFast() - iSegment - 1)); + delete segments; + return kFALSE; } } } + // delete the array of segments delete segments; } + // Keep all different tracks if required + if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks(); - // Retrace tracks using Kalman filter and remove bad ones - if (GetRecoParam()->MakeTrackCandidatesFast()) { - fRecTracksPtr->Compress(); // this is essential before checking tracks + // Retrace tracks using Kalman filter and select them if needed + Int_t nCurrentTracks = fRecTracksPtr->GetLast()+1; + for (Int_t iRecTrack = 0; iRecTrack < nCurrentTracks; iRecTrack++) { + track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack); - Int_t currentNRecTracks = fNRecTracks; - for (Int_t iRecTrack = 0; iRecTrack < currentNRecTracks; iRecTrack++) { - track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack); - - // Recompute track parameters and covariances using Kalman filter - RetraceTrack(*track,kTRUE); - - // Remove the track if the normalized chi2 is too high - if (track->GetNormalizedChi2() > GetRecoParam()->GetSigmaCutForTracking() * - GetRecoParam()->GetSigmaCutForTracking()) { - fRecTracksPtr->Remove(track); - fNRecTracks--; - } - + // skip empty slots + if(!track) continue; + + // retrace tracks using Kalman filter and remove the ones for which extrap failed or that are out of limits + if (!RetraceTrack(*track,kTRUE) || !IsAcceptable(*((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First()))) { + fRecTracksPtr->Remove(track); + fNRecTracks--; } } - fRecTracksPtr->Compress(); // this is essential before checking tracks - - // Keep all different tracks or only the best ones as required - if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks(); - else RemoveDoubleTracks(); + // Keep only the best tracks if required + if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks(); + else fRecTracksPtr->Compress(); AliDebug(1,Form("Number of good candidates = %d",fNRecTracks)); + return kTRUE; + } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) { - /// To make extra track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE): + /// To make extra track candidates assuming linear propagation: /// clustering is supposed to be already done /// Start with segments made of 1 cluster in each of the stations 4 and 5 then follow track in remaining chambers. - /// Good candidates are made of at least three clusters if both station are requested (two otherwise). + /// Good candidates are made of at least three clusters if both stations are requested (two otherwise). /// Keep only best candidates or all of them according to the flag fgkTrackAllTracks. TClonesArray *segments; + AliMUONObjectPair *segment; AliMUONTrack *track; Int_t iCandidate = 0, iCurrentTrack, nCurrentTracks; Int_t initialNRecTracks = fNRecTracks; @@ -191,19 +193,21 @@ void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& c // Make segments between ch1 and ch2 segments = MakeSegmentsBetweenChambers(clusterStore, ich1, ich2); + /// Remove segments already attached to a track + RemoveUsedSegments(*segments); + // Loop over segments - for (Int_t iseg=0; isegGetEntriesFast(); iseg++) { + for (Int_t iSegment=0; iSegmentGetEntriesFast(); iSegment++) { AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate)); + segment = (AliMUONObjectPair*) segments->UncheckedAt(iSegment); // Transform segments to tracks and put them at the end of fRecTracksPtr iCurrentTrack = fRecTracksPtr->GetLast()+1; - track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]),GetRecoParam()->GetBendingVertexDispersion()); + track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion()); fNRecTracks++; // Look for compatible cluster(s) in the second chamber of station 5 - if (GetRecoParam()->MakeTrackCandidatesFast()) - clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2); - else clusterFound = FollowTrackInChamber(*track, clusterStore, 17-ich2); + clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2); // skip the original track in case it has been removed if (GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++; @@ -214,13 +218,18 @@ void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& c track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iCurrentTrack); // Look for compatible cluster(s) in the second chamber of station 4 - if (GetRecoParam()->MakeTrackCandidatesFast()) - FollowLinearTrackInChamber(*track, clusterStore, 13-ich1); - else FollowTrackInChamber(*track, clusterStore, 13-ich1); + FollowLinearTrackInChamber(*track, clusterStore, 13-ich1); iCurrentTrack++; } + // abort tracking if there are too many candidates + if ((fNRecTracks + segments->GetEntriesFast() - iSegment - 1) > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks + segments->GetEntriesFast() - iSegment - 1)); + delete segments; + return kFALSE; + } + } // delete the array of segments @@ -228,41 +237,37 @@ void AliMUONTrackReconstructorK::MakeMoreTrackCandidates(AliMUONVClusterStore& c } } - fRecTracksPtr->Compress(); // this is essential before checking tracks - - // Retrace tracks using Kalman filter - for (Int_t iRecTrack = initialNRecTracks; iRecTrack < fNRecTracks; iRecTrack++) { + // Retrace tracks using Kalman filter (also compute track chi2) and select them + nCurrentTracks = fRecTracksPtr->GetLast()+1; + for (Int_t iRecTrack = initialNRecTracks; iRecTrack < nCurrentTracks; iRecTrack++) { track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack); - // Recompute track parameters and covariances using Kalman filter - RetraceTrack(*track,kTRUE); + // skip empty slots + if(!track) continue; - // Remove the track if the normalized chi2 is too high - // (only if the tracking has been done without magnetic field) - if (GetRecoParam()->MakeTrackCandidatesFast() && - track->GetNormalizedChi2() > GetRecoParam()->GetSigmaCutForTracking() * - GetRecoParam()->GetSigmaCutForTracking()) { + // retrace tracks using Kalman filter and remove the ones for which extrap failed or that are out of limits + if (!RetraceTrack(*track,kTRUE) || !IsAcceptable(*((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First()))) { fRecTracksPtr->Remove(track); fNRecTracks--; } } - // this is essential before checking tracks - if (GetRecoParam()->MakeTrackCandidatesFast()) fRecTracksPtr->Compress(); - - // Keep all different tracks or only the best ones as required - if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks(); - else RemoveDoubleTracks(); + // Keep only the best tracks if required + if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks(); + else fRecTracksPtr->Compress(); AliDebug(1,Form("Number of good candidates = %d",fNRecTracks)); + return kTRUE; + } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed) +Bool_t AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool_t resetSeed) { /// Re-run the kalman filter from the most downstream cluster to the most uptream one + /// Return kFALSE in case of failure (i.e. extrapolation problem) AliDebug(1,"Enter RetraceTrack"); AliMUONTrackParam* lastTrackParam = (AliMUONTrackParam*) trackCandidate.GetTrackParamAtCluster()->Last(); @@ -304,15 +309,26 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool lastParamCov.Zero(); // Non bending plane lastParamCov(0,0) = cluster2->GetErrX2(); - lastParamCov(1,1) = 100. * ( cluster1->GetErrX2() + cluster2->GetErrX2() ) / dZ / dZ; + lastParamCov(0,1) = - cluster2->GetErrX2() / dZ; + lastParamCov(1,0) = lastParamCov(0,1); + lastParamCov(1,1) = ( 1000. * cluster1->GetErrX2() + cluster2->GetErrX2() ) / dZ / dZ; // Bending plane lastParamCov(2,2) = cluster2->GetErrY2(); - lastParamCov(3,3) = 100. * ( cluster1->GetErrY2() + cluster2->GetErrY2() ) / dZ / dZ; + lastParamCov(2,3) = - cluster2->GetErrY2() / dZ; + lastParamCov(3,2) = lastParamCov(2,3); + lastParamCov(3,3) = ( 1000. * cluster1->GetErrY2() + cluster2->GetErrY2() ) / dZ / dZ; // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field) - lastParamCov(4,4) = ((GetRecoParam()->GetBendingVertexDispersion() * - GetRecoParam()->GetBendingVertexDispersion() + - (z1 * z1 * cluster2->GetErrY2() + z2 * z2 * cluster1->GetErrY2()) / dZ / dZ) / - bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum; + if (AliMUONTrackExtrap::IsFieldON()) { + lastParamCov(4,4) = ((GetRecoParam()->GetBendingVertexDispersion() * + GetRecoParam()->GetBendingVertexDispersion() + + (z1 * z1 * cluster2->GetErrY2() + z2 * z2 * 1000. * cluster1->GetErrY2()) / dZ / dZ) / + bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum; + lastParamCov(2,4) = z1 * cluster2->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ; + lastParamCov(4,2) = lastParamCov(2,4); + lastParamCov(3,4) = - (z1 * cluster2->GetErrY2() + z2 * 1000. * cluster1->GetErrY2()) * + inverseBendingMomentum / bendingImpact / dZ / dZ; + lastParamCov(4,3) = lastParamCov(3,4); + } else lastParamCov(4,4) = inverseBendingMomentum*inverseBendingMomentum; lastTrackParam->SetCovariances(lastParamCov); // Reset the track chi2 @@ -321,14 +337,15 @@ void AliMUONTrackReconstructorK::RetraceTrack(AliMUONTrack &trackCandidate, Bool } // Redo the tracking - RetracePartialTrack(trackCandidate, lastTrackParam); + return RetracePartialTrack(trackCandidate, lastTrackParam); } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam) +Bool_t AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidate, const AliMUONTrackParam* startingTrackParam) { /// Re-run the kalman filter from the cluster attached to startingTrackParam to the most uptream cluster + /// Return kFALSE in case of failure (i.e. extrapolation problem) AliDebug(1,"Enter RetracePartialTrack"); // Printout for debuging @@ -340,6 +357,7 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat trackCandidate.SetGlobalChi2(startingTrackParam->GetTrackChi2()); // loop over attached clusters until the first one and recompute track parameters and covariances using kalman filter + Bool_t extrapStatus = kTRUE; Int_t expectedChamber = startingTrackParam->GetClusterPtr()->GetChamberId() - 1; Int_t currentChamber; Double_t addChi2TrackAtCluster; @@ -361,16 +379,16 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId(); while (currentChamber < expectedChamber) { // extrapolation to the missing chamber (update the propagator) - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber), - GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber), + GetRecoParam()->UseSmoother())) extrapStatus = kFALSE; // add MCS effect AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); expectedChamber--; } // extrapolation to the plane of the cluster attached to the current trackParamAtCluster (update the propagator) - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ(), - GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ(), + GetRecoParam()->UseSmoother())) extrapStatus = kFALSE; if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother @@ -398,10 +416,14 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat cout << "RetracePartialTrack: track chi2 after re-tracking: " << trackCandidate.GetGlobalChi2() << endl; } + // set global chi2 to max value in case of problem during track extrapolation + if (!extrapStatus) trackCandidate.SetGlobalChi2(2.*AliMUONTrack::MaxChi2()); + return extrapStatus; + } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore) { /// Follow tracks in stations(1..) 3, 2 and 1 AliDebug(1,"Enter FollowTracks"); @@ -449,6 +471,19 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore } + // abort tracking if there are too many candidates + if (GetRecoParam()->RequestStation(station)) { + if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks)); + return kFALSE; + } + } else { + if ((fNRecTracks + currentNRecTracks - iRecTrack - 1) > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks + currentNRecTracks - iRecTrack - 1)); + return kFALSE; + } + } + } fRecTracksPtr->Compress(); // this is essential before checking tracks @@ -458,6 +493,8 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore } + return kTRUE; + } //__________________________________________________________________________ @@ -472,12 +509,11 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi /// return kTRUE if new cluster(s) have been found (otherwise return kFALSE) AliDebug(1,Form("Enter FollowTrackInChamber(1..) %d", nextChamber+1)); - Double_t bendingMomentum; Double_t chi2OfCluster; Double_t maxChi2OfCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 Double_t addChi2TrackAtCluster; - Double_t bestAddChi2TrackAtCluster = 1.e10; + Double_t bestAddChi2TrackAtCluster = AliMUONTrack::MaxChi2(); Bool_t foundOneCluster = kFALSE; AliMUONTrack *newTrack = 0x0; AliMUONVCluster *cluster; @@ -507,15 +543,15 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi while (currentChamber > nextChamber + 1) { // extrapolation to the missing chamber currentChamber--; - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), - GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), + GetRecoParam()->UseSmoother())) return kFALSE; // add MCS effect AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); } //Extrapolate trackCandidate to chamber - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber), - GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber), + GetRecoParam()->UseSmoother())) return kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { @@ -550,14 +586,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi // if good chi2 then consider to add cluster if (chi2OfCluster < maxChi2OfCluster) { - foundOneCluster = kTRUE; - - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1 - << " (Chi2 = " << chi2OfCluster << ")" << endl; - cluster->Print(); - } if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother @@ -570,10 +598,18 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi // Compute new track parameters including new cluster using kalman filter addChi2TrackAtCluster = RunKalmanFilter(extrapTrackParamAtCluster); - // skip track with absolute bending momentum out of limits - bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster.GetInverseBendingMomentum()); - if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue; + // skip track out of limits + if (!IsAcceptable(extrapTrackParamAtCluster)) continue; + + // remember a cluster was found + foundOneCluster = kTRUE; + + // Printout for debuging + if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { + cout << "FollowTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; + cluster->Print(); + } if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster @@ -646,14 +682,13 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi ch2 = 2*nextStation+1; } - Double_t bendingMomentum; Double_t chi2OfCluster; Double_t maxChi2OfCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 Double_t addChi2TrackAtCluster1; Double_t addChi2TrackAtCluster2; - Double_t bestAddChi2TrackAtCluster1 = 1.e10; - Double_t bestAddChi2TrackAtCluster2 = 1.e10; + Double_t bestAddChi2TrackAtCluster1 = AliMUONTrack::MaxChi2(); + Double_t bestAddChi2TrackAtCluster2 = AliMUONTrack::MaxChi2(); Bool_t foundOneCluster = kFALSE; Bool_t foundTwoClusters = kFALSE; AliMUONTrack *newTrack = 0x0; @@ -665,13 +700,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi AliMUONTrackParam bestTrackParamAtCluster1; AliMUONTrackParam bestTrackParamAtCluster2; - Int_t nClusters = clusterStore.GetSize(); - Bool_t *clusterCh1Used = new Bool_t[nClusters]; - for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE; - Int_t iCluster1; - // Get track parameters according to the propagation direction - if (nextStation==4) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last(); else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First(); @@ -693,15 +722,15 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi while (ch1 < ch2 && currentChamber > ch2 + 1) { // extrapolation to the missing chamber currentChamber--; - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), - GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), + GetRecoParam()->UseSmoother())) return kFALSE; // add MCS effect AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); } //Extrapolate trackCandidate to chamber "ch2" - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2), - GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2), + GetRecoParam()->UseSmoother())) return kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { @@ -721,6 +750,11 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi if (nextStation < 3) AskForNewClustersInStation(extrapTrackParamAtCh, clusterStore, nextStation); } + Int_t nClusters = clusterStore.GetSize(); + Bool_t *clusterCh1Used = new Bool_t[nClusters]; + for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE; + Int_t iCluster1; + // Create iterators to loop over clusters in both chambers TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1)); TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2)); @@ -737,15 +771,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // if good chi2 then try to attach a cluster in the other chamber too if (chi2OfCluster < maxChi2OfCluster) { - Bool_t foundSecondCluster = kFALSE; - - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1 - << " (Chi2 = " << chi2OfCluster << ")" << endl; - clusterCh2->Print(); - cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl; - } if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother @@ -758,11 +783,17 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Compute new track parameters including "clusterCh2" using kalman filter addChi2TrackAtCluster2 = RunKalmanFilter(extrapTrackParamAtCluster2); - // skip track with absolute bending momentum out of limits - bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster2.GetInverseBendingMomentum()); - if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue; - + // skip track out of limits + if (!IsAcceptable(extrapTrackParamAtCluster2)) continue; + + // Printout for debuging + if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; + clusterCh2->Print(); + cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl; + } + // copy new track parameters for next step extrapTrackParam = extrapTrackParamAtCluster2; @@ -773,15 +804,16 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi if (GetRecoParam()->UseSmoother()) extrapTrackParam.ResetPropagator(); //Extrapolate track parameters to chamber "ch1" - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1), - GetRecoParam()->UseSmoother()); + Bool_t normalExtrap = AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1), + GetRecoParam()->UseSmoother()); // reset cluster iterator of chamber 1 nextInCh1.Reset(); iCluster1 = -1; // look for second candidates in chamber 1 - while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + Bool_t foundSecondCluster = kFALSE; + if (normalExtrap) while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { iCluster1++; // try to add the current cluster fast @@ -793,15 +825,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // if good chi2 then consider to add the 2 clusters to the "trackCandidate" if (chi2OfCluster < maxChi2OfCluster) { - foundSecondCluster = kTRUE; - foundTwoClusters = kTRUE; - - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2OfCluster << ")" << endl; - clusterCh1->Print(); - } if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother @@ -814,10 +837,19 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Compute new track parameters including "clusterCh1" using kalman filter addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1); - // skip track with absolute bending momentum out of limits - bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum()); - if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue; + // skip track out of limits + if (!IsAcceptable(extrapTrackParamAtCluster1)) continue; + + // remember a second cluster was found + foundSecondCluster = kTRUE; + foundTwoClusters = kTRUE; + + // Printout for debuging + if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; + clusterCh1->Print(); + } if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters @@ -825,10 +857,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi UpdateTrack(*newTrack,extrapTrackParamAtCluster1,extrapTrackParamAtCluster2,addChi2TrackAtCluster1,addChi2TrackAtCluster2); fNRecTracks++; - // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station - // (going in the right direction) - if (nextStation == 4) RetraceTrack(*newTrack,kTRUE); - // Tag clusterCh1 as used clusterCh1Used[iCluster1] = kTRUE; @@ -852,6 +880,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // if no clusterCh1 found then consider to add clusterCh2 only if (!foundSecondCluster) { + + // remember a cluster was found foundOneCluster = kTRUE; if (GetRecoParam()->TrackAllTracks()) { @@ -860,10 +890,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi UpdateTrack(*newTrack,extrapTrackParamAtCluster2,addChi2TrackAtCluster2); fNRecTracks++; - // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station - // (going in the right direction) - if (nextStation == 4) RetraceTrack(*newTrack,kTRUE); - // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl; @@ -890,8 +916,8 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); //Extrapolate trackCandidate to chamber "ch1" - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1), - GetRecoParam()->UseSmoother()); + Bool_t normalExtrap = AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1), + GetRecoParam()->UseSmoother()); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { @@ -910,7 +936,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi iCluster1 = -1; // look for second candidates in chamber 1 - while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + if (normalExtrap) while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { iCluster1++; if (clusterCh1Used[iCluster1]) continue; // Skip clusters already used @@ -925,14 +951,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // if good chi2 then consider to add clusterCh1 // We do not try to attach a cluster in the other chamber too since it has already been done above if (chi2OfCluster < maxChi2OfCluster) { - foundOneCluster = kTRUE; - - // Printout for debuging - if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { - cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 - << " (Chi2 = " << chi2OfCluster << ")" << endl; - clusterCh1->Print(); - } if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother @@ -945,10 +963,18 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Compute new track parameters including "clusterCh1" using kalman filter addChi2TrackAtCluster1 = RunKalmanFilter(extrapTrackParamAtCluster1); - // skip track with absolute bending momentum out of limits - bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum()); - if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) continue; + // skip track out of limits + if (!IsAcceptable(extrapTrackParamAtCluster1)) continue; + + // remember a cluster was found + foundOneCluster = kTRUE; + + // Printout for debuging + if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { + cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1 + << " (Chi2 = " << chi2OfCluster << ")" << endl; + clusterCh1->Print(); + } if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster @@ -956,10 +982,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi UpdateTrack(*newTrack,extrapTrackParamAtCluster1,addChi2TrackAtCluster1); fNRecTracks++; - // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station - // (going in the right direction) - if (nextStation == 4) RetraceTrack(*newTrack,kTRUE); - // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl; @@ -983,10 +1005,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi if (foundTwoClusters) { UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestTrackParamAtCluster2,bestAddChi2TrackAtCluster1,bestAddChi2TrackAtCluster2); - // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station - // (going in the right direction) - if (nextStation == 4) RetraceTrack(trackCandidate,kTRUE); - // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl; @@ -996,10 +1014,6 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi } else if (foundOneCluster) { UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestAddChi2TrackAtCluster1); - // if we are arrived on station(1..) 5, recompute track parameters and covariances starting from this station - // (going in the right direction) - if (nextStation == 4) RetraceTrack(trackCandidate,kTRUE); - // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl; @@ -1050,7 +1064,7 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar paramWeight.Invert(); } else { AliWarning(" Determinant = 0"); - return 1.e10; + return 2.*AliMUONTrack::MaxChi2(); } // Compute the new cluster weight (U) @@ -1065,7 +1079,7 @@ Double_t AliMUONTrackReconstructorK::RunKalmanFilter(AliMUONTrackParam &trackPar newParamCov.Invert(); } else { AliWarning(" Determinant = 0"); - return 1.e10; + return 2.*AliMUONTrack::MaxChi2(); } // Save the new parameters covariance matrix @@ -1205,12 +1219,10 @@ Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Al trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber)); // Re-calculate track parameters at the (new) first cluster - RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1)); + if (!RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1))) return kFALSE; - // skip track with absolute bending momentum out of limits - Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum()); - if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) return kFALSE; + // skip track out of limits + if (!IsAcceptable(*((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First()))) return kFALSE; // Look for new cluster(s) in next station return FollowTrackInStation(trackCandidate, clusterStore, nextStation); @@ -1228,17 +1240,20 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) // Smoothed parameters and covariances at first cluster = filtered parameters and covariances previousTrackParam->SetSmoothParameters(previousTrackParam->GetParameters()); previousTrackParam->SetSmoothCovariances(previousTrackParam->GetCovariances()); + + AliMUONTrackParam *currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(previousTrackParam); - // Compute local chi2 at first cluster - AliMUONVCluster *cluster = previousTrackParam->GetClusterPtr(); - Double_t dX = cluster->GetX() - previousTrackParam->GetNonBendingCoor(); - Double_t dY = cluster->GetY() - previousTrackParam->GetBendingCoor(); - Double_t chi2 = dX * dX / cluster->GetErrX2() + dY * dY / cluster->GetErrY2(); + // Save local chi2 at first cluster = last additional chi2 provided by Kalman + previousTrackParam->SetLocalChi2(previousTrackParam->GetTrackChi2() - currentTrackParam->GetTrackChi2()); - // Save local chi2 at first cluster - previousTrackParam->SetLocalChi2(chi2); + // if the track contains only 2 clusters simply copy the filtered parameters + if (track.GetNClusters() == 2) { + currentTrackParam->SetSmoothParameters(currentTrackParam->GetParameters()); + currentTrackParam->SetSmoothCovariances(currentTrackParam->GetCovariances()); + currentTrackParam->SetLocalChi2(currentTrackParam->GetTrackChi2()); + return kTRUE; + } - AliMUONTrackParam *currentTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(previousTrackParam); while (currentTrackParam) { // Get variables @@ -1250,7 +1265,7 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) const TMatrixD &filteredCovariances = currentTrackParam->GetCovariances(); // C(k k) const TMatrixD &previousSmoothCovariances = previousTrackParam->GetSmoothCovariances(); // C(k+1 n) - // Compute smoother gain: A(k) = C(kk) * F(f)^t * (C(k+1 k))^-1 + // Compute smoother gain: A(k) = C(kk) * F(k)^t * (C(k+1 k))^-1 TMatrixD extrapWeight(extrapCovariances); if (extrapWeight.Determinant() != 0) { extrapWeight.Invert(); // (C(k+1 k))^-1 @@ -1258,8 +1273,8 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) AliWarning(" Determinant = 0"); return kFALSE; } - TMatrixD smootherGain(filteredCovariances,TMatrixD::kMultTranspose,propagator); // C(kk) * F(f)^t - smootherGain *= extrapWeight; // C(kk) * F(f)^t * (C(k+1 k))^-1 + TMatrixD smootherGain(filteredCovariances,TMatrixD::kMultTranspose,propagator); // C(kk) * F(k)^t + smootherGain *= extrapWeight; // C(kk) * F(k)^t * (C(k+1 k))^-1 // Compute smoothed parameters: X(k n) = X(k k) + A(k) * (X(k+1 n) - X(k+1 k)) TMatrixD tmpParam(previousSmoothParameters,TMatrixD::kMinus,extrapParameters); // X(k+1 n) - X(k+1 k) @@ -1279,7 +1294,7 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) currentTrackParam->SetSmoothCovariances(smoothCovariances); // Compute smoothed residual: r(k n) = cluster - X(k n) - cluster = currentTrackParam->GetClusterPtr(); + AliMUONVCluster* cluster = currentTrackParam->GetClusterPtr(); TMatrixD smoothResidual(2,1); smoothResidual.Zero(); smoothResidual(0,0) = cluster->GetX() - smoothParameters(0,0); @@ -1314,20 +1329,23 @@ Bool_t AliMUONTrackReconstructorK::RunSmoother(AliMUONTrack &track) } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& clusterStore) { /// Complete tracks by adding missing clusters (if there is an overlap between - /// two detection elements, the track may have two clusters in the same chamber) - /// Recompute track parameters and covariances at each clusters + /// two detection elements, the track may have two clusters in the same chamber). + /// Recompute track parameters and covariances at each clusters. + /// Remove tracks getting abnormal (i.e. extrapolation failed...) after being complemented. + /// Return kTRUE if one or more tracks have been complemented or removed. AliDebug(1,"Enter ComplementTracks"); Int_t chamberId, detElemId; Double_t chi2OfCluster, addChi2TrackAtCluster, bestAddChi2TrackAtCluster; Double_t maxChi2OfCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 - Bool_t foundOneCluster, trackModified; + Bool_t foundOneCluster, trackModified, hasChanged = kFALSE; AliMUONVCluster *cluster; AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam, trackParamAtCluster, bestTrackParamAtCluster; + AliMUONTrack *nextTrack; AliMUONTrack *track = (AliMUONTrack*) fRecTracksPtr->First(); while (track) { @@ -1337,7 +1355,7 @@ void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& cl previousTrackParam = trackParam; while (trackParam) { foundOneCluster = kFALSE; - bestAddChi2TrackAtCluster = 1.e10; + bestAddChi2TrackAtCluster = AliMUONTrack::MaxChi2(); chamberId = trackParam->GetClusterPtr()->GetChamberId(); detElemId = trackParam->GetClusterPtr()->GetDetElemId(); @@ -1396,18 +1414,28 @@ void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& cl bestTrackParamAtCluster.SetRemovable(kTRUE); track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr())); trackModified = kTRUE; + hasChanged = kTRUE; } previousTrackParam = trackParam; trackParam = nextTrackParam; } + // prepare next track + nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track); + // re-compute track parameters using kalman filter if needed - if (trackModified) RetraceTrack(*track,kTRUE); + if (trackModified && !RetraceTrack(*track,kTRUE)) { + AliWarning("track modified but problem occur during refitting --> remove track"); + fRecTracksPtr->Remove(track); + fNRecTracks--; + } - track = (AliMUONTrack*) fRecTracksPtr->After(track); + track = nextTrack; } + return hasChanged; + } //__________________________________________________________________________ @@ -1416,10 +1444,12 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) /// Improve the given track by removing removable clusters with local chi2 highter than the defined cut /// Removable clusters are identified by the method AliMUONTrack::TagRemovableClusters() /// Recompute track parameters and covariances at the remaining clusters + /// and if something goes wrong (i.e. extrapolation failed...) set track chi2 to max value AliDebug(1,"Enter ImproveTrack"); Double_t localChi2, worstLocalChi2; - AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster, *nextTrackParam; + AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster, *nextTrackParam, *next2nextTrackParam; + Int_t nextChamber, next2nextChamber; Bool_t smoothed; Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForImprovement() * GetRecoParam()->GetSigmaCutForImprovement(); @@ -1437,7 +1467,12 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) if (!smoothed) { // Update track parameters and covariances - track.UpdateCovTrackParamAtCluster(); + if (!track.UpdateCovTrackParamAtCluster()) { + AliWarning("unable to update track parameters and covariances --> stop improvement"); + // restore the kalman parameters + RetraceTrack(track,kTRUE); + break; + } // Compute local chi2 of each clusters track.ComputeLocalChi2(kTRUE); @@ -1445,7 +1480,7 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) // Look for the cluster to remove worstTrackParamAtCluster = 0x0; - worstLocalChi2 = 0.; + worstLocalChi2 = -1.; trackParamAtCluster = (AliMUONTrackParam*)track.GetTrackParamAtCluster()->First(); while (trackParamAtCluster) { @@ -1465,12 +1500,6 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) trackParamAtCluster = (AliMUONTrackParam*)track.GetTrackParamAtCluster()->After(trackParamAtCluster); } - // Check if worst cluster found - if (!worstTrackParamAtCluster) { - AliWarning("Bad local chi2 values?"); - break; - } - // Check whether the worst chi2 is under requirement or not if (worstLocalChi2 < 2. * sigmaCut2) { // 2 because 2 quantities in chi2 track.SetImproved(kTRUE); @@ -1478,7 +1507,11 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) } // if the worst cluster is not removable then stop improvement - if (!worstTrackParamAtCluster->IsRemovable()) break; + if (!worstTrackParamAtCluster->IsRemovable()) { + // restore the kalman parameters in case they have been lost + if (!smoothed) RetraceTrack(track,kTRUE); + break; + } // get track parameters at cluster next to the one to be removed nextTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(worstTrackParamAtCluster); @@ -1489,9 +1522,29 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) // Re-calculate track parameters // - from the cluster 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 cluster was the last one - if (smoothed && nextTrackParam) RetracePartialTrack(track,nextTrackParam); - else RetraceTrack(track,kTRUE); + // - or if the removed cluster was used to compute the tracking seed + Bool_t normalExtrap; + if (smoothed && nextTrackParam) { + + nextChamber = nextTrackParam->GetClusterPtr()->GetChamberId(); + next2nextTrackParam = nextTrackParam; + do { + + next2nextChamber = next2nextTrackParam->GetClusterPtr()->GetChamberId(); + next2nextTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(next2nextTrackParam); + + } while (next2nextTrackParam && (next2nextChamber == nextChamber)); + + if (next2nextChamber == nextChamber) normalExtrap = RetraceTrack(track,kTRUE); + else normalExtrap = RetracePartialTrack(track,nextTrackParam); + + } else normalExtrap = RetraceTrack(track,kTRUE); + + // stop in case of extrapolation problem + if (!normalExtrap) { + AliWarning("track partially improved but problem occur during refitting --> stop improvement"); + break; + } // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { @@ -1503,20 +1556,27 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) } //__________________________________________________________________________ -void AliMUONTrackReconstructorK::FinalizeTrack(AliMUONTrack &track) +Bool_t AliMUONTrackReconstructorK::FinalizeTrack(AliMUONTrack &track) { /// Update track parameters and covariances at each attached cluster /// using smoother if required, if not already done + /// return kFALSE if the track cannot be extrapolated uo to the last chamber AliMUONTrackParam *trackParamAtCluster; Bool_t smoothed = kFALSE; // update track parameters (using smoother if required) if not already done - if (!track.IsImproved()) { - smoothed = kFALSE; + if (track.IsImproved()) smoothed = GetRecoParam()->UseSmoother(); + else { if (GetRecoParam()->UseSmoother()) smoothed = RunSmoother(track); - if (!smoothed) track.UpdateCovTrackParamAtCluster(); - } else smoothed = GetRecoParam()->UseSmoother(); + if (!smoothed) { + if (track.UpdateCovTrackParamAtCluster()) track.ComputeLocalChi2(kTRUE); + else { + AliWarning("finalization failed due to extrapolation problem"); + return kFALSE; + } + } + } // copy smoothed parameters and covariances if any if (smoothed) { @@ -1532,30 +1592,38 @@ void AliMUONTrackReconstructorK::FinalizeTrack(AliMUONTrack &track) } + return kTRUE; + } //__________________________________________________________________________ Bool_t AliMUONTrackReconstructorK::RefitTrack(AliMUONTrack &track, Bool_t enableImprovement) { /// re-fit the given track + AliDebug(1,"Enter RefitTrack"); - // check validity of the track - if (track.GetNClusters() < 3) { - AliWarning("the track does not contain enough clusters --> unable to refit"); + // check validity of the track (i.e. at least 2 chambers hit on stations 4 and 5) + if (!track.IsValid(0)) { + AliWarning("the track is not valid --> unable to refit"); return kFALSE; } // re-compute track parameters and covariances using Kalman filter - RetraceTrack(track,kTRUE); + if (!RetraceTrack(track,kTRUE)) { + AliWarning("bad track refitting due to extrapolation failure"); + return kFALSE; + } // Improve the reconstructed tracks if required track.SetImproved(kFALSE); if (enableImprovement && GetRecoParam()->ImproveTracks()) ImproveTrack(track); // Fill AliMUONTrack data members - FinalizeTrack(track); - - return kTRUE; + if (track.GetGlobalChi2() < AliMUONTrack::MaxChi2()) return FinalizeTrack(track); + else { + AliWarning("track not finalized due to extrapolation failure"); + return kFALSE; + } }