X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=MUON%2FAliMUONTrackReconstructor.cxx;h=303af9148c0f32a2752958a21ab2fbbbc2fa0968;hb=cc2710b2840d45e8505d6289eefe9daa48bae4ca;hp=3e9ba9ba690e4a2fe30c5fbf251e825e89465247;hpb=a0dc65b45f53d95747053ece26219759360f5eb6;p=u%2Fmrichter%2FAliRoot.git diff --git a/MUON/AliMUONTrackReconstructor.cxx b/MUON/AliMUONTrackReconstructor.cxx index 3e9ba9ba690..303af9148c0 100644 --- a/MUON/AliMUONTrackReconstructor.cxx +++ b/MUON/AliMUONTrackReconstructor.cxx @@ -35,6 +35,7 @@ #include "AliMUONTrack.h" #include "AliMUONTrackParam.h" #include "AliMUONTrackExtrap.h" +#include "AliMUONRecoParam.h" #include "AliMpArea.h" @@ -66,7 +67,7 @@ AliMUONTrackReconstructor::~AliMUONTrackReconstructor() } //__________________________________________________________________________ -void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& clusterStore) { /// To make track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE): /// Start with segments station(1..) 4 or 5 then follow track in station 5 or 4. @@ -92,7 +93,7 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste for (Int_t i = firstChamber; i <= lastChamber; ++i ) { - if (fClusterServer && 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 @@ -115,10 +116,23 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat); else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat); - // Remove track if no cluster found - if (!clusterFound && GetRecoParam()->RequestStation(7-istat)) { - fRecTracksPtr->Remove(track); - fNRecTracks--; + // Remove track if no cluster found on a requested station + // 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() - iseg - 1) > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks + segments->GetEntriesFast() - iseg - 1)); + delete segments; + return kFALSE; + } } } @@ -127,18 +141,18 @@ void AliMUONTrackReconstructor::MakeTrackCandidates(AliMUONVClusterStore& cluste delete segments; } - 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(); AliDebug(1,Form("Number of good candidates = %d",fNRecTracks)); + return kTRUE; + } //__________________________________________________________________________ -void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) { /// To make extra track candidates (assuming linear propagation if the flag fgkMakeTrackCandidatesFast is set to kTRUE): /// clustering is supposed to be already done @@ -147,6 +161,7 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl /// 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; Bool_t clusterFound; @@ -160,20 +175,22 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl // Make segments in the station 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++; @@ -184,13 +201,18 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl 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 @@ -198,18 +220,18 @@ void AliMUONTrackReconstructor::MakeMoreTrackCandidates(AliMUONVClusterStore& cl } } - 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 AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) { /// Follow tracks in stations(1..) 3, 2 and 1 AliDebug(1,"Enter FollowTracks"); @@ -241,15 +263,18 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) Fit(*track, kFALSE, kTRUE, kTRUE); else Fit(*track, kFALSE, kFALSE, kTRUE); - // remove track with absolute bending momentum out of limits - // or if the normalized chi2 is too high - Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First())->GetInverseBendingMomentum()); - if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || - bendingMomentum > GetRecoParam()->GetMaxBendingMomentum() || - track->GetNormalizedChi2() > sigmaCut2) { + // remove tracks out of limits + if (!IsAcceptable(*((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First()))) { fRecTracksPtr->Remove(track); - fNRecTracks--; - continue; + fNRecTracks--; + continue; + } + + // remove track if the normalized chi2 is too high + if (track->GetNormalizedChi2() > sigmaCut2) { + fRecTracksPtr->Remove(track); + fNRecTracks--; + continue; } // save parameters from fit into smoothed parameters to complete track afterward @@ -258,7 +283,12 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) if (station==2) { // save track parameters on stations 4 and 5 // extrapolate track parameters and covariances at each cluster - track->UpdateCovTrackParamAtCluster(); + // remove the track in case of failure + if (!track->UpdateCovTrackParamAtCluster()) { + fRecTracksPtr->Remove(track); + fNRecTracks--; + continue; + } // save them trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First(); @@ -287,7 +317,12 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) nextTrackParam->SetCovariances(trackParam->GetCovariances()); // extrapolate them to the z of the corresponding cluster - AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ()); + // remove the track in case of failure + if (!AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ())) { + fRecTracksPtr->Remove(track); + fNRecTracks--; + continue; + } // save them nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters()); @@ -329,6 +364,12 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) } + // abort tracking if there are too many candidates + if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) { + AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks)); + return kFALSE; + } + } // Compress fRecTracksPtr for the next step @@ -384,7 +425,13 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) nextTrackParam->SetCovariances(trackParam->GetCovariances()); // extrapolate them to the z of the corresponding cluster - AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ()); + // remove the track in case of failure + if (!AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ())) { + fRecTracksPtr->Remove(track); + fNRecTracks--; + track = nextTrack; + continue; + } // save them nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters()); @@ -402,6 +449,8 @@ void AliMUONTrackReconstructor::FollowTracks(AliMUONVClusterStore& clusterStore) fRecTracksPtr->Compress(); + return kTRUE; + } //__________________________________________________________________________ @@ -415,7 +464,7 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInChamber(AliMUONTrack &trackCandid /// kFALSE: add only the best cluster(s) to the "trackCandidate". Try to add a couple of clusters in priority. AliDebug(1,Form("Enter FollowTrackInChamber(1..) %d", nextChamber+1)); - Double_t chi2WithOneCluster = 1.e10; + Double_t chi2WithOneCluster = AliMUONTrack::MaxChi2(); Double_t maxChi2WithOneCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 Double_t bestChi2WithOneCluster = maxChi2WithOneCluster; @@ -439,20 +488,20 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInChamber(AliMUONTrack &trackCandid } // Add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId(); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.); // 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)); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber))) 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)); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber))) return kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { @@ -565,8 +614,8 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid ch2 = 2*nextStation+1; } - Double_t chi2WithOneCluster = 1.e10; - Double_t chi2WithTwoClusters = 1.e10; + Double_t chi2WithOneCluster = AliMUONTrack::MaxChi2(); + Double_t chi2WithTwoClusters = AliMUONTrack::MaxChi2(); Double_t maxChi2WithOneCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2 Double_t maxChi2WithTwoClusters = 4. * GetRecoParam()->GetSigmaCutForTracking() * @@ -584,11 +633,6 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid 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(); @@ -601,20 +645,20 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid } // Add MCS effect - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(),1.); + Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId(); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.); // 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)); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber))) 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)); + if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2))) return kFALSE; // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { @@ -634,6 +678,11 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid 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)); @@ -660,26 +709,26 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid } // add MCS effect for next step - AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(),1.); + AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(ch2),-1.); // copy new track parameters for next step extrapTrackParam = extrapTrackParamAtCluster2; //Extrapolate track parameters to chamber "ch1" - AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1)); + Bool_t normalExtrap = AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1)); // reset cluster iterator of chamber 1 nextInCh1.Reset(); iCluster1 = -1; // look for second candidates in chamber 1 - while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { + if (normalExtrap) while ( ( clusterCh1 = static_cast(nextInCh1()) ) ) { iCluster1++; // try to add the current cluster fast if (!TryOneClusterFast(extrapTrackParam, clusterCh1)) continue; - // try to add the current cluster accuratly + // try to add the current cluster accurately chi2WithTwoClusters = TryTwoClusters(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1); // if good chi2 then create a new track by adding the 2 clusters to the "trackCandidate" @@ -753,10 +802,10 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid 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)); + Bool_t normalExtrap = AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1)); // Printout for debuging if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) { @@ -775,7 +824,7 @@ Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandid 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 cluster already used @@ -872,12 +921,11 @@ Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trac /// return trackParamAtCluster1 & 2 // extrapolate track parameters at the z position of the second cluster (no need to extrapolate the covariances) + // and set pointer to cluster into trackParamAtCluster trackParamAtCluster2.SetParameters(trackParamAtCluster1.GetParameters()); trackParamAtCluster2.SetZ(trackParamAtCluster1.GetZ()); - AliMUONTrackExtrap::ExtrapToZ(&trackParamAtCluster2, cluster2->GetZ()); - - // set pointer to cluster2 into trackParamAtCluster2 trackParamAtCluster2.SetClusterPtr(cluster2); + if (!AliMUONTrackExtrap::ExtrapToZ(&trackParamAtCluster2, cluster2->GetZ())) return 2.*AliMUONTrack::MaxChi2(); // Set differences between track and the 2 clusters in the bending and non bending directions AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr(); @@ -901,9 +949,6 @@ Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trac // copy track parameters at first cluster for jacobian calculation AliMUONTrackParam trackParam(trackParamAtCluster1); - // add MCS effect to the covariance matrix at first cluster - AliMUONTrackExtrap::AddMCSEffect(&trackParam,AliMUONConstants::ChamberThicknessInX0(),1.); - // Get the pointer to the parameter covariance matrix at first cluster const TMatrixD& kParamCov = trackParam.GetCovariances(); @@ -916,6 +961,7 @@ Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trac jacob(1,2) = 1.; // dy1/dy // first derivative at the second cluster: TMatrixD dParam(5,1); + Double_t direction[5] = {-1.,-1.,1.,1.,-1.}; for (Int_t i=0; i<5; i++) { // Skip jacobian calculation for parameters with no associated error if (kParamCov(i,i) == 0.) continue; @@ -923,7 +969,7 @@ Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trac for (Int_t j=0; j<5; j++) { if (j==i) { dParam(j,0) = TMath::Sqrt(kParamCov(i,i)); - if (j == 4) dParam(j,0) *= TMath::Sign(1.,-paramAtCluster1Save(4,0)); // variation always in the same direction + dParam(j,0) *= TMath::Sign(1.,direction[j]*paramAtCluster1Save(j,0)); // variation always in the same direction } else dParam(j,0) = 0.; } @@ -933,7 +979,7 @@ Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trac trackParam.SetZ(cluster1->GetZ()); // Extrapolate new track parameters to the z position of the second cluster - AliMUONTrackExtrap::ExtrapToZ(&trackParam,cluster2->GetZ()); + if (!AliMUONTrackExtrap::ExtrapToZ(&trackParam,cluster2->GetZ())) return 2.*AliMUONTrack::MaxChi2(); // Calculate the jacobian jacob(2,i) = (trackParam.GetNonBendingCoor() - nonBendingCoor2) / dParam(i,0); // dx2/dParami @@ -956,7 +1002,7 @@ Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trac error.Invert(); } else { AliWarning(" Determinant error=0"); - return 1.e10; + return 2.*AliMUONTrack::MaxChi2(); } // Compute the Chi2 value @@ -1078,6 +1124,12 @@ Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, Ali // Calculate the track parameter covariance matrix Fit(trackCandidate, kFALSE, kFALSE, kTRUE); + // skip track if the normalized chi2 is too high + if (trackCandidate.GetNormalizedChi2() > GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking()) 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); @@ -1100,10 +1152,15 @@ void AliMUONTrackReconstructor::SetVertexErrXY2ForFit(AliMUONTrack &trackCandida // add multiple scattering effets AliMUONTrackParam paramAtVertex(*((AliMUONTrackParam*)(trackCandidate.GetTrackParamAtCluster()->First()))); paramAtVertex.DeleteCovariances(); // to be sure to account only for multiple scattering - AliMUONTrackExtrap::ExtrapToVertexUncorrected(¶mAtVertex,0.); - const TMatrixD& kParamCov = paramAtVertex.GetCovariances(); - nonBendingReso2 += kParamCov(0,0); - bendingReso2 += kParamCov(2,2); + if (!AliMUONTrackExtrap::ExtrapToZ(¶mAtVertex,AliMUONConstants::AbsZEnd())) { + nonBendingReso2 = 0.; + bendingReso2 = 0.; + } else { + AliMUONTrackExtrap::ExtrapToVertexUncorrected(¶mAtVertex,0.); + const TMatrixD& kParamCov = paramAtVertex.GetCovariances(); + nonBendingReso2 += kParamCov(0,0); + bendingReso2 += kParamCov(2,2); + } // Set the vertex resolution square trackCandidate.SetVertexErrXY2(nonBendingReso2,bendingReso2); @@ -1150,7 +1207,7 @@ void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool track.FitWithMCS(includeMCS); if (includeMCS) { // compute cluster weights only once - if (!track.ComputeClusterWeights()) { + if (!track.UpdateTrackParamAtCluster() || !track.ComputeClusterWeights()) { AliWarning("cannot take into account the multiple scattering effects"); track.FitWithMCS(kFALSE); } @@ -1226,19 +1283,23 @@ void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Doub trackParamAtCluster->SetBendingCoor(param[2]); trackParamAtCluster->SetBendingSlope(param[3]); trackParamAtCluster->SetInverseBendingMomentum(param[4]); - trackBeingFitted->UpdateTrackParamAtCluster(); + if (!trackBeingFitted->UpdateTrackParamAtCluster()) { + chi2 = 2.*AliMUONTrack::MaxChi2(); + return; + } // Take the vertex into account in the fit if required if (trackBeingFitted->FitWithVertex()) { Double_t nonBendingReso2,bendingReso2; trackBeingFitted->GetVertexErrXY2(nonBendingReso2,bendingReso2); - if (nonBendingReso2 == 0. || bendingReso2 == 0.) chi2 += 1.e10; - else { - AliMUONTrackParam paramAtVertex(*trackParamAtCluster); - AliMUONTrackExtrap::ExtrapToZ(¶mAtVertex, 0.); // vextex position = (0,0,0) + AliMUONTrackParam paramAtVertex(*trackParamAtCluster); + if (nonBendingReso2 != 0. && bendingReso2 != 0. && AliMUONTrackExtrap::ExtrapToZ(¶mAtVertex, 0.)) { // vextex position = (0,0,0) dX = paramAtVertex.GetNonBendingCoor(); dY = paramAtVertex.GetBendingCoor(); chi2 += dX * dX / nonBendingReso2 + dY * dY / bendingReso2; + } else { + chi2 = 2.*AliMUONTrack::MaxChi2(); + return; } } @@ -1248,18 +1309,19 @@ void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Doub } //__________________________________________________________________________ -void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clusterStore) +Bool_t AliMUONTrackReconstructor::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) - /// Re-fit track parameters and covariances + /// two detection elements, the track may have two clusters in the same chamber). + /// Re-fit track parameters and covariances. + /// Return kTRUE if one or more tracks have been complemented. AliDebug(1,"Enter ComplementTracks"); Int_t chamberId, detElemId; Double_t chi2OfCluster, bestChi2OfCluster; Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking(); - Bool_t foundOneCluster, trackModified; + Bool_t foundOneCluster, trackModified, hasChanged = kFALSE; AliMUONVCluster* cluster; AliMUONTrackParam *trackParam, *nextTrackParam, copyOfTrackParam, trackParamAtCluster, bestTrackParamAtCluster; @@ -1322,6 +1384,7 @@ void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clu bestTrackParamAtCluster.SetRemovable(kTRUE); track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr())); trackModified = kTRUE; + hasChanged = kTRUE; } trackParam = nextTrackParam; @@ -1333,6 +1396,8 @@ void AliMUONTrackReconstructor::ComplementTracks(const AliMUONVClusterStore& clu track = (AliMUONTrack*) fRecTracksPtr->After(track); } + return hasChanged; + } //__________________________________________________________________________ @@ -1353,7 +1418,10 @@ void AliMUONTrackReconstructor::ImproveTrack(AliMUONTrack &track) track.TagRemovableClusters(GetRecoParam()->RequestedStationMask()); // Update track parameters and covariances - track.UpdateCovTrackParamAtCluster(); + if (!track.UpdateCovTrackParamAtCluster()) { + AliWarning("unable to update track parameters and covariances --> stop improvement"); + break; + } // Compute local chi2 of each clusters track.ComputeLocalChi2(kTRUE); @@ -1407,12 +1475,16 @@ void AliMUONTrackReconstructor::ImproveTrack(AliMUONTrack &track) } //__________________________________________________________________________ -void AliMUONTrackReconstructor::FinalizeTrack(AliMUONTrack &track) +Bool_t AliMUONTrackReconstructor::FinalizeTrack(AliMUONTrack &track) { /// Recompute track parameters and covariances at each attached cluster /// from those at the first one, if not already done AliDebug(1,"Enter FinalizeTrack"); - if (!track.IsImproved()) track.UpdateCovTrackParamAtCluster(); + if (!track.IsImproved() && !track.UpdateCovTrackParamAtCluster()) { + AliWarning("finalization failed due to extrapolation problem"); + return kFALSE; + } + return kTRUE; } //__________________________________________________________________________ @@ -1421,7 +1493,7 @@ Bool_t AliMUONTrackReconstructor::RefitTrack(AliMUONTrack &track, Bool_t enableI /// re-fit the given track // check validity of the track - if (!track.IsValid(GetRecoParam()->RequestedStationMask())) { + if (track.GetNClusters() < 3) { AliWarning("the track does not contain enough clusters --> unable to refit"); return kFALSE; } @@ -1435,7 +1507,10 @@ Bool_t AliMUONTrackReconstructor::RefitTrack(AliMUONTrack &track, Bool_t enableI // compute track parameters at each cluster from parameters at the first one // necessary to compute multiple scattering effect during refitting - track.UpdateTrackParamAtCluster(); + if (!track.UpdateTrackParamAtCluster()) { + AliWarning("bad track refitting due to extrapolation failure"); + return kFALSE; + } // Re-fit the track: // Take into account the multiple scattering @@ -1447,9 +1522,11 @@ Bool_t AliMUONTrackReconstructor::RefitTrack(AliMUONTrack &track, Bool_t enableI 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; + } }