X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONTrackReconstructorK.cxx;h=8c265ba3b3bd0b1905b98497cf0a369dd5924559;hb=d7f41d16b19bdfaf7b69832df771e8567d87c89e;hp=71a6b8860a8a1a22ac11fcd45f9b46ac142e4b72;hpb=0e894e58da0a093dd283c5311297442bb77163f9;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONTrackReconstructorK.cxx b/MUON/AliMUONTrackReconstructorK.cxx index 71a6b8860a8..8c265ba3b3b 100644 --- a/MUON/AliMUONTrackReconstructorK.cxx +++ b/MUON/AliMUONTrackReconstructorK.cxx @@ -37,6 +37,7 @@ #include "AliMUONTrack.h" #include "AliMUONTrackParam.h" #include "AliMUONTrackExtrap.h" +#include "AliMUONRecoParam.h" #include "AliMpArea.h" @@ -51,8 +52,8 @@ ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context /// \endcond //__________________________________________________________________________ -AliMUONTrackReconstructorK::AliMUONTrackReconstructorK(AliMUONVClusterServer& clusterServer) - : AliMUONVTrackReconstructor(clusterServer) +AliMUONTrackReconstructorK::AliMUONTrackReconstructorK(const AliMUONRecoParam* recoParam, AliMUONVClusterServer* clusterServer) + : AliMUONVTrackReconstructor(recoParam, clusterServer) { /// Constructor } @@ -64,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; @@ -82,7 +84,7 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust Int_t firstChamber(0); Int_t lastChamber(9); - if (AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco()) { + if (GetRecoParam()->CombineClusterTrackReco()) { // ... Here's the exception : ask the clustering to reconstruct // clusters *only* in station 4 and 5 for combined tracking firstChamber = 6; @@ -90,7 +92,7 @@ void AliMUONTrackReconstructorK::MakeTrackCandidates(AliMUONVClusterStore& clust for (Int_t i = firstChamber; i <= lastChamber; ++i ) { - if (AliMUONReconstructor::GetRecoParam()->UseChamber(i)) fClusterServer.Clusterize(i, clusterStore, AliMpArea()); + if (fClusterServer && GetRecoParam()->UseChamber(i)) fClusterServer->Clusterize(i, clusterStore, AliMpArea(), GetRecoParam()); } // Loop over stations(1..) 5 and 4 and make track candidates @@ -100,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])); + track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion()); fNRecTracks++; // Look for compatible cluster(s) in the other station - if (AliMUONReconstructor::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 (AliMUONReconstructor::GetRecoParam()->RequestStation(7-istat)) { - fRecTracksPtr->Remove(track); - fNRecTracks--; - } else if (istat == 3 && !AliMUONReconstructor::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 (AliMUONReconstructor::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() > AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::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 (AliMUONReconstructor::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; @@ -190,22 +193,24 @@ 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])); + track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion()); fNRecTracks++; // Look for compatible cluster(s) in the second chamber of station 5 - if (AliMUONReconstructor::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 (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++; + if (GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++; // loop over every new tracks nCurrentTracks = fRecTracksPtr->GetLast()+1; @@ -213,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 (AliMUONReconstructor::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 @@ -227,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 (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast() && - track->GetNormalizedChi2() > AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::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 (AliMUONReconstructor::GetRecoParam()->MakeTrackCandidatesFast()) fRecTracksPtr->Compress(); - - // Keep all different tracks or only the best ones as required - if (AliMUONReconstructor::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(); @@ -303,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) = ((AliMUONReconstructor::GetRecoParam()->GetBendingVertexDispersion() * - AliMUONReconstructor::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 @@ -320,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 @@ -339,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; @@ -351,27 +370,27 @@ void AliMUONTrackReconstructorK::RetracePartialTrack(AliMUONTrack &trackCandidat trackParamAtCluster->SetCovariances(startingTrackParam->GetCovariances()); // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(expectedChamber+1),-1.); // reset propagator for smoother - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) trackParamAtCluster->ResetPropagator(); + if (GetRecoParam()->UseSmoother()) trackParamAtCluster->ResetPropagator(); // add MCS in missing chambers if any currentChamber = trackParamAtCluster->GetClusterPtr()->GetChamberId(); while (currentChamber < expectedChamber) { // extrapolation to the missing chamber (update the propagator) - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber), - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, AliMUONConstants::DefaultChamberZ(expectedChamber), + GetRecoParam()->UseSmoother())) extrapStatus = kFALSE; // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(trackParamAtCluster,AliMUONConstants::ChamberThicknessInX0(expectedChamber),-1.); expectedChamber--; } // extrapolation to the plane of the cluster attached to the current trackParamAtCluster (update the propagator) - AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ(), - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(trackParamAtCluster, trackParamAtCluster->GetClusterPtr()->GetZ(), + GetRecoParam()->UseSmoother())) extrapStatus = kFALSE; - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { + if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother trackParamAtCluster->SetExtrapParameters(trackParamAtCluster->GetParameters()); @@ -397,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"); @@ -424,11 +447,11 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore if (!FollowTrackInStation(*track, clusterStore, station)) { // Try to recover track if required - if (AliMUONReconstructor::GetRecoParam()->RecoverTracks()) { + if (GetRecoParam()->RecoverTracks()) { // work on a copy of the track if this station is not required // to keep the case where no cluster is reconstructed as a possible candidate - if (!AliMUONReconstructor::GetRecoParam()->RequestStation(station)) { + if (!GetRecoParam()->RequestStation(station)) { track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(*track); fNRecTracks++; } @@ -440,7 +463,7 @@ void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore fNRecTracks--; } - } else if (AliMUONReconstructor::GetRecoParam()->RequestStation(station)) { + } else if (GetRecoParam()->RequestStation(station)) { // remove track if no cluster found fRecTracksPtr->Remove(track); fNRecTracks--; @@ -448,15 +471,30 @@ 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 // Keep only the best tracks if required - if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks(); + if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks(); } + return kTRUE; + } //__________________________________________________________________________ @@ -471,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. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + 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; @@ -496,25 +533,25 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi } // Add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId(); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.); // reset propagator for smoother - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator(); + if (GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator(); // Add MCS in the missing chamber(s) if any - Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId(); while (currentChamber > nextChamber + 1) { // extrapolation to the missing chamber currentChamber--; - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), + GetRecoParam()->UseSmoother())) return kFALSE; // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.); } //Extrapolate trackCandidate to chamber - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber), - AliMUONReconstructor::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)) { @@ -530,7 +567,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi // Ask the clustering to reconstruct new clusters around the track position in the current chamber // except for station 4 and 5 that are already entirely clusterized - if (AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco()) { + if (GetRecoParam()->CombineClusterTrackReco()) { if (nextChamber < 6) AskForNewClustersInChamber(extrapTrackParamAtCh, clusterStore, nextChamber); } @@ -545,20 +582,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi // try to add the current cluster accuratly chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, cluster, extrapTrackParamAtCluster, - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + GetRecoParam()->UseSmoother()); // 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 (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { + if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother extrapTrackParamAtCluster.SetExtrapParameters(extrapTrackParamAtCluster.GetParameters()); @@ -569,12 +598,20 @@ 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 < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > AliMUONReconstructor::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 (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { + if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); UpdateTrack(*newTrack,extrapTrackParamAtCluster,addChi2TrackAtCluster); @@ -597,7 +634,7 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInChamber(AliMUONTrack &trackCandi } // fill out the best track if required else clean up the fRecTracksPtr array - if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { + if (!GetRecoParam()->TrackAllTracks()) { if (foundOneCluster) { UpdateTrack(trackCandidate,bestTrackParamAtCluster,bestAddChi2TrackAtCluster); @@ -645,14 +682,13 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi ch2 = 2*nextStation+1; } - Double_t bendingMomentum; Double_t chi2OfCluster; - Double_t maxChi2OfCluster = 2. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + 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; @@ -664,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(); @@ -682,25 +712,25 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi } // Add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId(); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.); // reset propagator for smoother - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator(); + if (GetRecoParam()->UseSmoother()) extrapTrackParamAtCh.ResetPropagator(); // Add MCS in the missing chamber(s) if any - Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId(); while (ch1 < ch2 && currentChamber > ch2 + 1) { // extrapolation to the missing chamber currentChamber--; - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber), + GetRecoParam()->UseSmoother())) return kFALSE; // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.); } //Extrapolate trackCandidate to chamber "ch2" - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2), - AliMUONReconstructor::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)) { @@ -716,10 +746,15 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // Ask the clustering to reconstruct new clusters around the track position in the current station // except for station 4 and 5 that are already entirely clusterized - if (AliMUONReconstructor::GetRecoParam()->CombineClusterTrackReco()) { + if (GetRecoParam()->CombineClusterTrackReco()) { 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)); @@ -732,21 +767,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // try to add the current cluster accuratly chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh2, extrapTrackParamAtCluster2, - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + GetRecoParam()->UseSmoother()); // 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 (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { + if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother extrapTrackParamAtCluster2.SetExtrapParameters(extrapTrackParamAtCluster2.GetParameters()); @@ -757,30 +783,37 @@ 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 < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > AliMUONReconstructor::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; // add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParam,AliMUONConstants::ChamberThicknessInX0(ch2),-1.); // reset propagator for smoother - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) extrapTrackParam.ResetPropagator(); + if (GetRecoParam()->UseSmoother()) extrapTrackParam.ResetPropagator(); //Extrapolate track parameters to chamber "ch1" - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1), - AliMUONReconstructor::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 @@ -788,21 +821,12 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // try to add the current cluster accuratly chi2OfCluster = TryOneCluster(extrapTrackParam, clusterCh1, extrapTrackParamAtCluster1, - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + GetRecoParam()->UseSmoother()); // 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 (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { + if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother extrapTrackParamAtCluster1.SetExtrapParameters(extrapTrackParamAtCluster1.GetParameters()); @@ -813,21 +837,26 @@ 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 < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > AliMUONReconstructor::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 (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { + if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); 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; @@ -851,18 +880,16 @@ 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 (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { + if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); 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; @@ -883,14 +910,14 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // 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 clusters has been found - if (AliMUONReconstructor::GetRecoParam()->TrackAllTracks() || !foundTwoClusters) { + if (GetRecoParam()->TrackAllTracks() || !foundTwoClusters) { // add MCS effect for next step - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(ch2),-1.); //Extrapolate trackCandidate to chamber "ch1" - AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1), - AliMUONReconstructor::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)) { @@ -909,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 @@ -919,21 +946,13 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi // try to add the current cluster accuratly chi2OfCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1, - AliMUONReconstructor::GetRecoParam()->UseSmoother()); + GetRecoParam()->UseSmoother()); // 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 (AliMUONReconstructor::GetRecoParam()->UseSmoother()) { + if (GetRecoParam()->UseSmoother()) { // save extrapolated parameters for smoother extrapTrackParamAtCluster1.SetExtrapParameters(extrapTrackParamAtCluster1.GetParameters()); @@ -944,21 +963,25 @@ 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 < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > AliMUONReconstructor::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 (AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { + if (GetRecoParam()->TrackAllTracks()) { // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate); 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; @@ -978,14 +1001,10 @@ Bool_t AliMUONTrackReconstructorK::FollowTrackInStation(AliMUONTrack &trackCandi } // fill out the best track if required else clean up the fRecTracksPtr array - if (!AliMUONReconstructor::GetRecoParam()->TrackAllTracks()) { + if (!GetRecoParam()->TrackAllTracks()) { 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; @@ -995,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; @@ -1049,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) @@ -1064,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 @@ -1100,7 +1115,7 @@ void AliMUONTrackReconstructorK::UpdateTrack(AliMUONTrack &track, AliMUONTrackPa /// Update chi2 of the track // Flag cluster as being (not) removable - if (AliMUONReconstructor::GetRecoParam()->RequestStation(trackParamAtCluster.GetClusterPtr()->GetChamberId()/2)) + if (GetRecoParam()->RequestStation(trackParamAtCluster.GetClusterPtr()->GetChamberId()/2)) trackParamAtCluster.SetRemovable(kFALSE); else trackParamAtCluster.SetRemovable(kTRUE); trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used @@ -1187,7 +1202,7 @@ Bool_t AliMUONTrackReconstructorK::RecoverTrack(AliMUONTrack &trackCandidate, Al if (!trackParamAtCluster->IsRemovable()) return kFALSE; // reset the current cluster as being not removable if it is on a required station - if (AliMUONReconstructor::GetRecoParam()->RequestStation(nextStation+1)) trackParamAtCluster->SetRemovable(kFALSE); + if (GetRecoParam()->RequestStation(nextStation+1)) trackParamAtCluster->SetRemovable(kFALSE); // Pick up cluster with the worst chi2 localChi2 = trackParamAtCluster->GetLocalChi2(); @@ -1204,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 < AliMUONReconstructor::GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > AliMUONReconstructor::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); @@ -1227,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 localChi2 = 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(localChi2); + // 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 @@ -1249,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 @@ -1257,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) @@ -1278,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); @@ -1313,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. * AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 - Bool_t foundOneCluster, trackModified; + Double_t maxChi2OfCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() * + GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 + Bool_t foundOneCluster, trackModified, hasChanged = kFALSE; AliMUONVCluster *cluster; AliMUONTrackParam *trackParam, *previousTrackParam, *nextTrackParam, trackParamAtCluster, bestTrackParamAtCluster; + AliMUONTrack *nextTrack; AliMUONTrack *track = (AliMUONTrack*) fRecTracksPtr->First(); while (track) { @@ -1336,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(); @@ -1384,27 +1403,39 @@ void AliMUONTrackReconstructorK::ComplementTracks(const AliMUONVClusterStore& cl if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructorK") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) { cout << "ComplementTracks: found one cluster in chamber(1..): " << chamberId+1 << endl; bestTrackParamAtCluster.GetClusterPtr()->Print(); - cout<= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { + cout<SetRemovable(kTRUE); 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; + } //__________________________________________________________________________ @@ -1413,28 +1444,35 @@ 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 = AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement() * - AliMUONReconstructor::GetRecoParam()->GetSigmaCutForImprovement(); + Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForImprovement() * + GetRecoParam()->GetSigmaCutForImprovement(); while (!track.IsImproved()) { // identify removable clusters - track.TagRemovableClusters(); + track.TagRemovableClusters(GetRecoParam()->RequestedStationMask()); // Run smoother if required smoothed = kFALSE; - if (AliMUONReconstructor::GetRecoParam()->UseSmoother()) smoothed = RunSmoother(track); + if (GetRecoParam()->UseSmoother()) smoothed = RunSmoother(track); // Use standard procedure to compute local chi2 if smoother not required or not working 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); @@ -1442,12 +1480,12 @@ void AliMUONTrackReconstructorK::ImproveTrack(AliMUONTrack &track) // Look for the cluster to remove worstTrackParamAtCluster = 0x0; - worstLocalChi2 = 0.; + worstLocalChi2 = -1.; trackParamAtCluster = (AliMUONTrackParam*)track.GetTrackParamAtCluster()->First(); while (trackParamAtCluster) { // save parameters into smooth parameters in case of smoother did not work properly - if (AliMUONReconstructor::GetRecoParam()->UseSmoother() && !smoothed) { + if (GetRecoParam()->UseSmoother() && !smoothed) { trackParamAtCluster->SetSmoothParameters(trackParamAtCluster->GetParameters()); trackParamAtCluster->SetSmoothCovariances(trackParamAtCluster->GetCovariances()); } @@ -1462,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); @@ -1475,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); @@ -1486,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)) { @@ -1500,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 (AliMUONReconstructor::GetRecoParam()->UseSmoother()) smoothed = RunSmoother(track); - if (!smoothed) track.UpdateCovTrackParamAtCluster(); - } else smoothed = AliMUONReconstructor::GetRecoParam()->UseSmoother(); + if (track.IsImproved()) smoothed = GetRecoParam()->UseSmoother(); + else { + if (GetRecoParam()->UseSmoother()) smoothed = RunSmoother(track); + 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) { @@ -1529,29 +1592,38 @@ void AliMUONTrackReconstructorK::FinalizeTrack(AliMUONTrack &track) } + return kTRUE; + } //__________________________________________________________________________ -Bool_t AliMUONTrackReconstructorK::RefitTrack(AliMUONTrack &track) +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.IsValid()) { - 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 - if (AliMUONReconstructor::GetRecoParam()->ImproveTracks()) ImproveTrack(track); + 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; + } }