- Speed up the computation/selection of primary track candidates (by up to a factor 100)
- Improve computation of initial covariance matrices for Kalman
- Use specific covariance matrices when there is no magnetic field
- fix potential bug by reordering cluster/track selection
- fix selection of track candidates when there is no magnetic field
- new protection against tracking divergences (see below)
AliMUONRecoParam:
- change Cosmic settings
- New parameter: maximum number of trigger tracks above which the tracking is cancelled
- New parameter: maximum number of track candidates above which the tracking abort
(Philippe Pillot)
fBypassSt45(0),
fPadGoodnessMask(0),
fChargeSigmaCut(4.0),
- fRemoveConnectedTracksInSt12(kFALSE)
+ fRemoveConnectedTracksInSt12(kFALSE),
+ fMaxTriggerTracks(0),
+ fMaxTrackCandidates(0)
{
/// Constructor
}
for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
fBypassSt45 = 0;
+ fMaxTriggerTracks = 100;
+ fMaxTrackCandidates = 10000;
}
}
for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
fBypassSt45 = 0;
+ fMaxTriggerTracks = 100;
+ fMaxTrackCandidates = 10000;
}
fBendingVertexDispersion = 10.;
fMaxNonBendingDistanceToTrack = 10.;
fMaxBendingDistanceToTrack = 10.;
- fSigmaCutForTracking = 20.;
- fSigmaCutForImprovement = 20.;
+ fSigmaCutForTracking = 7.;
+ fSigmaCutForImprovement = 7.;
fSigmaCutForTrigger = 8.;
fStripCutForTrigger = 1.5;
fMaxStripAreaForTrigger = 3.;
fSaveFullClusterInESD = kTRUE;
for (Int_t iCh = 0; iCh < 10; iCh++) {
fUseChamber[iCh] = kTRUE;
- fDefaultNonBendingReso[iCh] = 0.144;
- fDefaultBendingReso[iCh] = 0.01;
+ fDefaultNonBendingReso[iCh] = 0.4;
+ fDefaultBendingReso[iCh] = 0.4;
}
for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
fBypassSt45 = 0;
+ fPadGoodnessMask = 0x400BE80;
+ fMaxTriggerTracks = 100;
+ fMaxTrackCandidates = 10000;
}
cout << "chamber bending resolution = |";
for (Int_t iCh = 0; iCh < 10; iCh++) cout << Form(" %6.3f |",fDefaultBendingReso[iCh]);
cout << endl;
+ cout<<Form("maximum number of trigger tracks above which the tracking is cancelled = %d",fMaxTriggerTracks)<<endl;
+ cout<<Form("maximum number of track candidates above which the tracking abort = %d",fMaxTrackCandidates)<<endl;
cout<<"\t-----------------------------------------------------"<<endl<<endl;
fPedMeanLimits[0] = 50;
fPedMeanLimits[1] = 1024;
- fPedSigmaLimits[0] = 0.1;
+ fPedSigmaLimits[0] = 0.6;
fPedSigmaLimits[1] = 100;
fGainA1Limits[0] = 0.1;
/// Get the default bending resolution of chamber iCh
Double_t GetDefaultBendingReso(Int_t iCh) const {return (iCh >= 0 && iCh < 10) ? fDefaultBendingReso[iCh] : FLT_MAX;}
+ /// Set the maximum number of trigger tracks above which the tracking is cancelled
+ void SetMaxTriggerTracks(Int_t maxTriggerTracks) {fMaxTriggerTracks = maxTriggerTracks;}
+ /// Get the maximum number of trigger tracks above which the tracking is cancelled
+ Int_t GetMaxTriggerTracks() const {return fMaxTriggerTracks;}
+
+ /// Set the maximum number of track candidates above which the tracking abort
+ void SetMaxTrackCandidates(Int_t maxTrackCandidates) {fMaxTrackCandidates = maxTrackCandidates;}
+ /// Get the maximum number of track candidates above which the tracking abort
+ Int_t GetMaxTrackCandidates() const {return fMaxTrackCandidates;}
+
virtual void Print(Option_t *option = "") const;
Bool_t fRemoveConnectedTracksInSt12; ///< kTRUE to remove tracks sharing cluster in station 1 and 2
+ Int_t fMaxTriggerTracks; ///< maximum number of trigger tracks above which the tracking is cancelled
+ Int_t fMaxTrackCandidates; ///< maximum number of track candidates above which the tracking abort
+
// functions
void SetLowFluxParam();
void SetHighFluxParam();
void SetCosmicParam();
- ClassDef(AliMUONRecoParam,11) // MUON reco parameters
+ ClassDef(AliMUONRecoParam,12) // MUON reco parameters
};
#endif
paramCov(3,2) = paramCov(2,3);
paramCov(3,3) = ( firstCluster->GetErrY2() + lastCluster->GetErrY2() ) / dZ / dZ;
// Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
- paramCov(4,4) = ( ( bendingVertexDispersion*bendingVertexDispersion +
- (z1 * z1 * lastCluster->GetErrY2() + z2 * z2 * firstCluster->GetErrY2()) / dZ / dZ) /
- bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum ;
- paramCov(2,4) = - z2 * firstCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
- paramCov(4,2) = paramCov(2,4);
- paramCov(3,4) = - (z1 * lastCluster->GetErrY2() + z2 * firstCluster->GetErrY2()) * inverseBendingMomentum / bendingImpact / dZ / dZ;
- paramCov(4,3) = paramCov(3,4);
-
- // Set covariances
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ paramCov(4,4) = ( ( bendingVertexDispersion*bendingVertexDispersion +
+ (z1 * z1 * lastCluster->GetErrY2() + z2 * z2 * firstCluster->GetErrY2()) / dZ / dZ) /
+ bendingImpact / bendingImpact + 0.1 * 0.1) * inverseBendingMomentum * inverseBendingMomentum ;
+ paramCov(2,4) = - z2 * firstCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+ paramCov(4,2) = paramCov(2,4);
+ paramCov(3,4) = - (z1 * lastCluster->GetErrY2() + z2 * firstCluster->GetErrY2()) * inverseBendingMomentum / bendingImpact / dZ / dZ;
+ paramCov(4,3) = paramCov(3,4);
+ } else paramCov(4,4) = inverseBendingMomentum*inverseBendingMomentum;
trackParamAtFirstCluster.SetCovariances(paramCov);
// Compute and set track parameters covariances at last cluster
- paramCov(1,0) = - paramCov(1,0);
- paramCov(0,1) = - paramCov(0,1);
- paramCov(3,2) = - paramCov(3,2);
- paramCov(2,3) = - paramCov(2,3);
- paramCov(2,4) = z1 * lastCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
- paramCov(4,2) = paramCov(2,4);
+ // Non bending plane
+ paramCov(0,0) = lastCluster->GetErrX2();
+ paramCov(0,1) = - lastCluster->GetErrX2() / dZ;
+ paramCov(1,0) = paramCov(0,1);
+ // Bending plane
+ paramCov(2,2) = lastCluster->GetErrY2();
+ paramCov(2,3) = - lastCluster->GetErrY2() / dZ;
+ paramCov(3,2) = paramCov(2,3);
+ // Inverse bending momentum (vertex resolution + bending slope resolution + 10% error on dipole parameters+field)
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ paramCov(2,4) = z1 * lastCluster->GetErrY2() * inverseBendingMomentum / bendingImpact / dZ;
+ paramCov(4,2) = paramCov(2,4);
+ }
trackParamAtLastCluster.SetCovariances(paramCov);
// Add track parameters at clusters
}
//__________________________________________________________________________
-Int_t AliMUONTrack::ClustersInCommon(AliMUONTrack* track, Bool_t inSt345) const
+Int_t AliMUONTrack::ClustersInCommon(AliMUONTrack* track) const
{
/// Returns the number of clusters in common between the current track ("this")
/// and the track pointed to by "track".
- /// If inSt345=kTRUE only stations 3, 4 and 5 are considered.
if (!fTrackParamAtCluster || !this->fTrackParamAtCluster) return 0;
+ Int_t nCluster1 = this->GetNClusters();
+ Int_t nCluster2 = track->GetNClusters();
Int_t clustersInCommon = 0;
AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2;
// Loop over clusters of first track
- trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->First();
- while (trackParamAtCluster1) {
- if ((!inSt345) || (trackParamAtCluster1->GetClusterPtr()->GetChamberId() > 3)) {
- // Loop over clusters of second track
- trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->First();
- while (trackParamAtCluster2) {
- if ((!inSt345) || (trackParamAtCluster2->GetClusterPtr()->GetChamberId() > 3)) {
- // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
- if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
- clustersInCommon++;
- break;
- }
- }
- trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->After(trackParamAtCluster2);
- } // trackParamAtCluster2
+ for(Int_t iCluster1 = 0; iCluster1 < nCluster1; iCluster1++) {
+ trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->UncheckedAt(iCluster1);
+ // Loop over clusters of second track
+ for(Int_t iCluster2 = 0; iCluster2 < nCluster2; iCluster2++) {
+ trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->UncheckedAt(iCluster2);
+ // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
+ if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
+ clustersInCommon++;
+ break;
+ }
}
- trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->After(trackParamAtCluster1);
- } // trackParamAtCluster1
+ }
+ return clustersInCommon;
+}
+
+ //__________________________________________________________________________
+Int_t AliMUONTrack::ClustersInCommonInSt345(AliMUONTrack* track) const
+{
+ /// Returns the number of clusters in common on stations 3, 4 and 5
+ /// between the current track ("this") and the track pointed to by "track".
+ if (!fTrackParamAtCluster || !this->fTrackParamAtCluster) return 0;
+ Int_t nCluster1 = this->GetNClusters();
+ Int_t nCluster2 = track->GetNClusters();
+ Int_t clustersInCommon = 0;
+ AliMUONTrackParam *trackParamAtCluster1, *trackParamAtCluster2;
+ // Loop over clusters of first track
+ for(Int_t iCluster1 = 0; iCluster1 < nCluster1; iCluster1++) {
+ trackParamAtCluster1 = (AliMUONTrackParam*) this->fTrackParamAtCluster->UncheckedAt(iCluster1);
+ if (trackParamAtCluster1->GetClusterPtr()->GetChamberId() < 4) continue;
+ // Loop over clusters of second track
+ for(Int_t iCluster2 = 0; iCluster2 < nCluster2; iCluster2++) {
+ trackParamAtCluster2 = (AliMUONTrackParam*) track->fTrackParamAtCluster->UncheckedAt(iCluster2);
+ if (trackParamAtCluster2->GetClusterPtr()->GetChamberId() < 4) continue;
+ // Increment "clustersInCommon" if both trackParamAtCluster1 & 2 point to the same cluster
+ if ((trackParamAtCluster1->GetClusterPtr()) == (trackParamAtCluster2->GetClusterPtr())) {
+ clustersInCommon++;
+ break;
+ }
+ }
+ }
return clustersInCommon;
}
/// set the chi2 of trigger/track matching
void SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;}
- Int_t ClustersInCommon(AliMUONTrack* track, Bool_t inSt345 = kFALSE) const;
+ Int_t ClustersInCommon(AliMUONTrack* track) const;
+ Int_t ClustersInCommonInSt345(AliMUONTrack* track) const;
Int_t GetNDF() const;
Double_t GetNormalizedChi2() const;
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.,-paramSave(4,0)); // variation always in the same direction
+ dParam(j,0) *= TMath::Sign(1.,paramSave(j,0)); // variation always in the same direction
} else dParam(j,0) = 0.;
}
}
//__________________________________________________________________________
-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.
clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
- // Remove track if no cluster found
+ // Remove track if no cluster found on a requested station
+ // or abort tracking if there are too many candidates
if (!clusterFound && GetRecoParam()->RequestStation(7-istat)) {
fRecTracksPtr->Remove(track);
fNRecTracks--;
+ } else if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+ delete segments;
+ return kFALSE;
}
}
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
/// 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;
// 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; iseg<segments->GetEntriesFast(); iseg++)
+ for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); 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++;
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 > GetRecoParam()->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+ delete segments;
+ return kFALSE;
+ }
+
}
// delete the array of 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();
+ // 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");
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) {
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) {
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ continue;
+ }
+ }
+
+ // remove track if the normalized chi2 is too high
+ if (track->GetNormalizedChi2() > sigmaCut2) {
fRecTracksPtr->Remove(track);
- fNRecTracks--;
- continue;
+ fNRecTracks--;
+ continue;
}
// save parameters from fit into smoothed parameters to complete track afterward
}
+ // abort tracking if there are too many candidates
+ if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+ return kFALSE;
+ }
+
}
// Compress fRecTracksPtr for the next step
fRecTracksPtr->Compress();
+ return kTRUE;
+
}
//__________________________________________________________________________
// Calculate the track parameter covariance matrix
Fit(trackCandidate, kFALSE, kFALSE, kTRUE);
+ // skip track with absolute bending momentum out of limits
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) return kFALSE;
+ }
+
// Look for new cluster(s) in next station
return FollowTrackInStation(trackCandidate,clusterStore,nextStation);
}
//__________________________________________________________________________
-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;
bestTrackParamAtCluster.SetRemovable(kTRUE);
track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
trackModified = kTRUE;
+ hasChanged = kTRUE;
}
trackParam = nextTrackParam;
track = (AliMUONTrack*) fRecTracksPtr->After(track);
}
+ return hasChanged;
+
}
//__________________________________________________________________________
protected:
// Functions
- virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
- virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
- virtual void FollowTracks(AliMUONVClusterStore& clusterStore);
- virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
+ virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
+ virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
+ virtual Bool_t FollowTracks(AliMUONVClusterStore& clusterStore);
+ virtual Bool_t ComplementTracks(const AliMUONVClusterStore& clusterStore);
virtual void ImproveTrack(AliMUONTrack &track);
virtual void FinalizeTrack(AliMUONTrack &track);
}
//__________________________________________________________________________
-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;
segments = MakeSegmentsBetweenChambers(clusterStore, 2*istat, 2*istat+1);
// Loop over segments
- for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
+ for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); 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 (!clusterFound && GetRecoParam()->RequestStation(7-istat)) {
+ fRecTracksPtr->Remove(track);
+ fNRecTracks--;
+ } else if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+ 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
+ RetraceTrack(*track,kTRUE);
+
+ // remove tracks with absolute bending momentum out of limits
+ if (GetRecoParam()->MakeTrackCandidatesFast() && AliMUONTrackExtrap::IsFieldON()) {
+ AliMUONTrackParam *trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
+ Double_t bendingMomentum = TMath::Abs(1. / trackParam->GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) {
+ 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 if (GetRecoParam()->MakeTrackCandidatesFast() && AliMUONTrackExtrap::IsFieldON()) 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;
// 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; iseg<segments->GetEntriesFast(); iseg++) {
+ for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); 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++;
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 > GetRecoParam()->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+ delete segments;
+ return kFALSE;
+ }
+
}
// delete the array of segments
}
}
- 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
+ // skip empty slots
+ if(!track) continue;
+
+ // retrace tracks using Kalman filter
RetraceTrack(*track,kTRUE);
- // 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()) {
- fRecTracksPtr->Remove(track);
- fNRecTracks--;
+ // remove tracks with absolute bending momentum out of limits
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ AliMUONTrackParam *trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
+ Double_t bendingMomentum = TMath::Abs(1. / trackParam->GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() || bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) {
+ 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;
+
}
//__________________________________________________________________________
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
}
//__________________________________________________________________________
-void AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore)
+Bool_t AliMUONTrackReconstructorK::FollowTracks(AliMUONVClusterStore& clusterStore)
{
/// Follow tracks in stations(1..) 3, 2 and 1
AliDebug(1,"Enter FollowTracks");
}
+ // abort tracking if there are too many candidates
+ if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
+ AliError(Form("Too many track candidates (%d tracks). Abort tracking.", fNRecTracks));
+ return kFALSE;
+ }
+
}
fRecTracksPtr->Compress(); // this is essential before checking tracks
}
+ return kTRUE;
+
}
//__________________________________________________________________________
// 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
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;
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster.GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) 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
// 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
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;
-
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster2.GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) 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;
iCluster1 = -1;
// look for second candidates in chamber 1
+ Bool_t foundSecondCluster = kFALSE;
while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
iCluster1++;
// 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
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;
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) 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
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;
// if no clusterCh1 found then consider to add clusterCh2 only
if (!foundSecondCluster) {
+
+ // remember a cluster was found
foundOneCluster = kTRUE;
if (GetRecoParam()->TrackAllTracks()) {
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;
// 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
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;
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ bendingMomentum = TMath::Abs(1. / extrapTrackParamAtCluster1.GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) 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
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;
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;
} 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;
RetracePartialTrack(trackCandidate,(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(1));
// 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;
+ if (AliMUONTrackExtrap::IsFieldON()) {
+ Double_t bendingMomentum = TMath::Abs(1. / ((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First())->GetInverseBendingMomentum());
+ if (bendingMomentum < GetRecoParam()->GetMinBendingMomentum() ||
+ bendingMomentum > GetRecoParam()->GetMaxBendingMomentum()) return kFALSE;
+ }
// Look for new cluster(s) in next station
return FollowTrackInStation(trackCandidate, clusterStore, nextStation);
}
//__________________________________________________________________________
-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.
+ /// Return kTRUE if one or more tracks have been complemented.
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;
bestTrackParamAtCluster.SetRemovable(kTRUE);
track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
trackModified = kTRUE;
+ hasChanged = kTRUE;
}
previousTrackParam = trackParam;
track = (AliMUONTrack*) fRecTracksPtr->After(track);
}
+ return hasChanged;
+
}
//__________________________________________________________________________
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) {
protected:
// Functions
- virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
- virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
- virtual void FollowTracks(AliMUONVClusterStore& clusterStore);
- virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore);
+ virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore& clusterStore);
+ virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore);
+ virtual Bool_t FollowTracks(AliMUONVClusterStore& clusterStore);
+ virtual Bool_t ComplementTracks(const AliMUONVClusterStore& clusterStore);
virtual void ImproveTrack(AliMUONTrack &track);
virtual void FinalizeTrack(AliMUONTrack &track);
fTrackReco->EventReconstructTrigger(*fkTriggerCircuit,*fTriggerStore,*(TriggerTrackStore()));
}
- if ( ( GetRecoParam()->BypassSt4() ||
- GetRecoParam()->BypassSt5() ) &&
- TriggerTrackStore()->GetSize() > 5 )
+ if ( TriggerTrackStore()->GetSize() > GetRecoParam()->GetMaxTriggerTracks() )
{
- // Hard cut to reject shower events
+ // cut to reject shower events
AliCodeTimerAuto("MUON Shower events");
// Reset array of tracks
ResetTracks();
- // Look for candidates from clusters in stations(1..) 4 and 5
- MakeTrackCandidates(clusterStore);
+ // Look for candidates from clusters in stations(1..) 4 and 5 (abort in case of failure)
+ if (!MakeTrackCandidates(clusterStore)) return;
- // Look for extra candidates from clusters in stations(1..) 4 and 5
- if (GetRecoParam()->MakeMoreTrackCandidates()) MakeMoreTrackCandidates(clusterStore);
+ // Look for extra candidates from clusters in stations(1..) 4 and 5 (abort in case of failure)
+ if (GetRecoParam()->MakeMoreTrackCandidates()) {
+ if (!MakeMoreTrackCandidates(clusterStore)) return;
+ }
// Stop tracking if no candidate found
if (fRecTracksPtr->GetEntriesFast() == 0) return;
- // Follow tracks in stations(1..) 3, 2 and 1
- FollowTracks(clusterStore);
+ // Follow tracks in stations(1..) 3, 2 and 1 (abort in case of failure)
+ if (!FollowTracks(clusterStore)) return;
// Complement the reconstructed tracks
- if (GetRecoParam()->ComplementTracks()) ComplementTracks(clusterStore);
+ if (GetRecoParam()->ComplementTracks()) {
+ if (ComplementTracks(clusterStore)) RemoveIdenticalTracks();
+ }
// Improve the reconstructed tracks
if (GetRecoParam()->ImproveTracks()) ImproveTracks();
return segments;
}
+ //__________________________________________________________________________
+void AliMUONVTrackReconstructor::RemoveUsedSegments(TClonesArray& segments)
+{
+ /// To remove pairs of clusters already attached to a track
+ AliDebug(1,"Enter RemoveUsedSegments");
+ Int_t nSegments = segments.GetEntriesFast();
+ Int_t nTracks = fRecTracksPtr->GetEntriesFast();
+ AliMUONObjectPair *segment;
+ AliMUONTrack *track;
+ AliMUONVCluster *cluster, *cluster1, *cluster2;
+ Bool_t foundCluster1, foundCluster2, removeSegment;
+
+ // Loop over segments
+ for (Int_t iSegment=0; iSegment<nSegments; iSegment++) {
+ segment = (AliMUONObjectPair*) segments.UncheckedAt(iSegment);
+
+ cluster1 = (AliMUONVCluster*) segment->First();
+ cluster2 = (AliMUONVCluster*) segment->Second();
+ removeSegment = kFALSE;
+
+ // Loop over tracks
+ for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+ track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack);
+
+ // skip empty slot
+ if (!track) continue;
+
+ foundCluster1 = kFALSE;
+ foundCluster2 = kFALSE;
+
+ // Loop over clusters
+ Int_t nClusters = track->GetNClusters();
+ for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
+ cluster = ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
+
+ // check if both clusters are in that track
+ if (cluster == cluster1) foundCluster1 = kTRUE;
+ else if (cluster == cluster2) foundCluster2 = kTRUE;
+
+ if (foundCluster1 && foundCluster2) {
+ removeSegment = kTRUE;
+ break;
+ }
+
+ }
+
+ if (removeSegment) break;
+
+ }
+
+ if (removeSegment) segments.RemoveAt(iSegment);
+
+ }
+
+ segments.Compress();
+
+ // Printout for debug
+ AliDebug(1,Form("NSegments = %d ", segments.GetEntriesFast()));
+}
+
//__________________________________________________________________________
void AliMUONVTrackReconstructor::RemoveIdenticalTracks()
{
/// To remove identical tracks:
/// Tracks are considered identical if they have all their clusters in common.
/// One keeps the track with the larger number of clusters if need be
- AliMUONTrack *track1, *track2, *trackToRemove;
+ AliMUONTrack *track1, *track2;
+ Int_t nTracks = fRecTracksPtr->GetEntriesFast();
Int_t clustersInCommon, nClusters1, nClusters2;
- Bool_t removedTrack1;
// Loop over first track of the pair
- track1 = (AliMUONTrack*) fRecTracksPtr->First();
- while (track1) {
- removedTrack1 = kFALSE;
+ for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
+ track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
+ // skip empty slot
+ if (!track1) continue;
nClusters1 = track1->GetNClusters();
// Loop over second track of the pair
- track2 = (AliMUONTrack*) fRecTracksPtr->After(track1);
- while (track2) {
+ for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
+ track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
+ // skip empty slot
+ if (!track2) continue;
nClusters2 = track2->GetNClusters();
// number of clusters in common between two tracks
clustersInCommon = track1->ClustersInCommon(track2);
// decide which track to remove
if (nClusters2 > nClusters1) {
// remove track1 and continue the first loop with the track next to track1
- trackToRemove = track1;
- track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
- fRecTracksPtr->Remove(trackToRemove);
- fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+ fRecTracksPtr->RemoveAt(iTrack1);
fNRecTracks--;
- removedTrack1 = kTRUE;
break;
} else {
// remove track2 and continue the second loop with the track next to track2
- trackToRemove = track2;
- track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
- fRecTracksPtr->Remove(trackToRemove);
- fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+ fRecTracksPtr->RemoveAt(iTrack2);
fNRecTracks--;
}
- } else track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
+ }
} // track2
- if (removedTrack1) continue;
- track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
} // track1
- return;
+ fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
}
//__________________________________________________________________________
/// which has the smaller number of clusters are in common with the other track.
/// Among two identical tracks, one keeps the track with the larger number of clusters
/// or, if these numbers are equal, the track with the minimum chi2.
- AliMUONTrack *track1, *track2, *trackToRemove;
- Int_t clustersInCommon, nClusters1, nClusters2;
- Bool_t removedTrack1;
+ AliMUONTrack *track1, *track2;
+ Int_t nTracks = fRecTracksPtr->GetEntriesFast();
+ Int_t clustersInCommon2, nClusters1, nClusters2;
// Loop over first track of the pair
- track1 = (AliMUONTrack*) fRecTracksPtr->First();
- while (track1) {
- removedTrack1 = kFALSE;
+ for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
+ track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
+ // skip empty slot
+ if (!track1) continue;
nClusters1 = track1->GetNClusters();
// Loop over second track of the pair
- track2 = (AliMUONTrack*) fRecTracksPtr->After(track1);
- while (track2) {
+ for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
+ track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
+ // skip empty slot
+ if (!track2) continue;
nClusters2 = track2->GetNClusters();
// number of clusters in common between two tracks
- clustersInCommon = track1->ClustersInCommon(track2);
+ clustersInCommon2 = 2 * track1->ClustersInCommon(track2);
// check for identical tracks
- if (((nClusters1 < nClusters2) && (2 * clustersInCommon > nClusters1)) || (2 * clustersInCommon > nClusters2)) {
+ if (clustersInCommon2 > nClusters1 || clustersInCommon2 > nClusters2) {
// decide which track to remove
if ((nClusters1 > nClusters2) || ((nClusters1 == nClusters2) && (track1->GetGlobalChi2() <= track2->GetGlobalChi2()))) {
// remove track2 and continue the second loop with the track next to track2
- trackToRemove = track2;
- track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
- fRecTracksPtr->Remove(trackToRemove);
- fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+ fRecTracksPtr->RemoveAt(iTrack2);
fNRecTracks--;
} else {
// else remove track1 and continue the first loop with the track next to track1
- trackToRemove = track1;
- track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
- fRecTracksPtr->Remove(trackToRemove);
- fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
+ fRecTracksPtr->RemoveAt(iTrack1);
fNRecTracks--;
- removedTrack1 = kTRUE;
break;
}
- } else track2 = (AliMUONTrack*) fRecTracksPtr->After(track2);
+ }
} // track2
- if (removedTrack1) continue;
- track1 = (AliMUONTrack*) fRecTracksPtr->After(track1);
} // track1
- return;
+ fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
}
//__________________________________________________________________________
while (track2) {
nClusters2 = track2->GetNClusters();
// number of clusters in common between two tracks
- clustersInCommon = track1->ClustersInCommon(track2, inSt345);
+ if (inSt345) clustersInCommon = track1->ClustersInCommonInSt345(track2);
+ else clustersInCommon = track1->ClustersInCommon(track2);
// check for identical tracks
if (clustersInCommon > 0) {
// decide which track to remove
extrapTrackParamAtCluster.SetRemovable(kFALSE);
else extrapTrackParamAtCluster.SetRemovable(kTRUE);
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster,*cluster);
+ newTrack->SetGlobalChi2(trackCandidate.GetGlobalChi2()+chi2WithOneCluster);
fNRecTracks++;
// Printout for debuging
bestTrackParamAtCluster.SetRemovable(kFALSE);
else bestTrackParamAtCluster.SetRemovable(kTRUE);
trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
+ trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithOneCluster);
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
extrapTrackParamAtCluster2.SetRemovable(kTRUE);
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
+ newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithTwoClusters);
fNRecTracks++;
// Tag clusterCh1 as used
extrapTrackParamAtCluster2.SetRemovable(kFALSE);
else extrapTrackParamAtCluster2.SetRemovable(kTRUE);
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
+ newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithOneCluster);
fNRecTracks++;
// Printout for debuging
extrapTrackParamAtCluster1.SetRemovable(kFALSE);
else extrapTrackParamAtCluster1.SetRemovable(kTRUE);
newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
+ newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithOneCluster);
fNRecTracks++;
// Printout for debuging
trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
bestTrackParamAtCluster2.SetRemovable(kTRUE);
trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster2,*(bestTrackParamAtCluster2.GetClusterPtr()));
+ trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithTwoClusters);
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
bestTrackParamAtCluster1.SetRemovable(kFALSE);
else bestTrackParamAtCluster1.SetRemovable(kTRUE);
trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
+ trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithOneCluster);
// Printout for debuging
if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
AliMUONVTrackReconstructor& operator=(const AliMUONVTrackReconstructor& rhs); ///< assignment operator
/// Make track candidates from clusters in stations(1..) 4 and 5
- virtual void MakeTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
+ virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
/// Make extra track candidates from clusters in stations(1..) 4 and 5
- virtual void MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
+ virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore& clusterStore) = 0;
/// Follow tracks in stations(1..) 3, 2 and 1
- virtual void FollowTracks(AliMUONVClusterStore& clusterStore) = 0;
+ virtual Bool_t FollowTracks(AliMUONVClusterStore& clusterStore) = 0;
/// Complement the reconstructed tracks
- virtual void ComplementTracks(const AliMUONVClusterStore& clusterStore) = 0;
+ virtual Bool_t ComplementTracks(const AliMUONVClusterStore& clusterStore) = 0;
void ImproveTracks();
/// Improve the given reconstructed track
virtual void ImproveTrack(AliMUONTrack &track) = 0;
TClonesArray* MakeSegmentsBetweenChambers(const AliMUONVClusterStore& clusterStore, Int_t ch1, Int_t ch2);
+ void RemoveUsedSegments(TClonesArray& segments);
void RemoveIdenticalTracks();
void RemoveDoubleTracks();
void RemoveConnectedTracks(Bool_t inSt345 = kFALSE);
cout << " number of tracks: " << nTracks <<endl;
}
- // set the magnetic field for track extrapolations
- AliMUONTrackExtrap::SetField();
// loop over all reconstructed tracks (also first track of combination)
for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
cout << "PtCutMin for muon tracks = " << PtCutMin << endl;
cout << "PtCutMax for muon tracks = " << PtCutMax << endl;
- hInvMassAll->Fit("gaus","q0");
-
- TF1* f1 = hInvMassAll->GetFunction("gaus");
+ cout << "Entries (unlike sign dimuons) : " << hInvMassAll->GetEntries();
- cout << "Entries (unlike sign dimuons) : " << hInvMassAll->GetEntries()
- << Form(". Rough sigma = %7.2f MeV/c2",f1->GetParameter(2)*1000.0) << endl;
+ if (hInvMassAll->GetEntries() > 0) {
+ hInvMassAll->Fit("gaus","q0");
+ TF1* f1 = hInvMassAll->GetFunction("gaus");
+ cout << Form(". Rough sigma = %7.2f MeV/c2",f1->GetParameter(2)*1000.0);
+ }
- cout << "Entries (unlike sign dimuons) in the mass range ["<<invMassMinInPeak<<";"<<invMassMaxInPeak<<"] : " << EventInMass <<endl;
+ cout << endl << "Entries (unlike sign dimuons) in the mass range ["<<invMassMinInPeak<<";"<<invMassMaxInPeak<<"] : " << EventInMass <<endl;
if (ptTrig==0x800) cout << "Unlike Pair - All Pt" ;
if (ptTrig==0x400) cout << "Unlike Pair - High Pt" ;
AliMUONRecoParam *muonRecoParam = AliMUONRecoParam::GetCosmicParam();
// digit selection
- muonRecoParam->SetPadGoodnessMask(0x400BE80);
TString caliboption = caliboption1;
if ( calib == 2 ) caliboption = caliboption2;
muonRecoParam->SetCalibrationMode(caliboption.Data());
- // chamber resolution (incuding misalignment)
- for (Int_t iCh=0; iCh<10; iCh++) {
- muonRecoParam->SetDefaultNonBendingReso(iCh,0.4);
- muonRecoParam->SetDefaultBendingReso(iCh,0.4);
- }
- muonRecoParam->SetMaxNonBendingDistanceToTrack(10.);
- muonRecoParam->SetMaxBendingDistanceToTrack(10.);
-
// cut on (non)bending slopes
- //muonRecoParam->SetMaxNonBendingSlope(0.6);
- //muonRecoParam->SetMaxBendingSlope(0.6);
+ muonRecoParam->SetMaxNonBendingSlope(0.6);
+ muonRecoParam->SetMaxBendingSlope(0.6);
// tracking algorithm
muonRecoParam->MakeMoreTrackCandidates(kTRUE);
muonRecoParam->RequestStation(2, kFALSE);
muonRecoParam->RequestStation(3, kFALSE);
muonRecoParam->RequestStation(4, kFALSE);
- muonRecoParam->SetSigmaCutForTracking(7.);
- muonRecoParam->ImproveTracks(kTRUE, 7.);
muonRecoParam->Print("FULL");