1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 /// \class AliMUONTrackReconstructorK
19 /////////////////////////////////////
21 /// MUON track reconstructor using the kalman method
23 /// This class contains as data:
24 /// - the parameters for the track reconstruction
26 /// It contains as methods, among others:
27 /// - MakeTracks to build the tracks
29 ////////////////////////////////////
31 #include "AliMUONTrackReconstructorK.h"
32 #include "AliMUONConstants.h"
33 #include "AliMUONHitForRec.h"
34 #include "AliMUONObjectPair.h"
35 #include "AliMUONRawCluster.h"
36 #include "AliMUONTrackK.h"
40 #include <Riostream.h>
43 ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context
44 ClassImp(AliMUONConstants)
47 //__________________________________________________________________________
48 AliMUONTrackReconstructorK::AliMUONTrackReconstructorK(const Option_t* TrackMethod)
49 : AliMUONVTrackReconstructor(),
50 fTrackMethod(2) //tracking method (2-Kalman 3-Combination-Kalman/Clustering)
52 /// Constructor for class AliMUONTrackReconstructorK
54 if (strstr(TrackMethod,"Kalman")) {
55 AliInfo(" *** Tracking with the Kalman filter *** ");
57 } else if (strstr(TrackMethod,"Combi")) {
58 AliInfo(" *** Combined cluster / track finder ***");
60 } else AliFatal(Form("Tracking method %s not available",TrackMethod));
62 // Memory allocation for the TClonesArray of reconstructed tracks
63 fRecTracksPtr = new TClonesArray("AliMUONTrackK", 10);
66 //__________________________________________________________________________
67 AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK(void)
69 /// Destructor for class AliMUONTrackReconstructorK
73 //__________________________________________________________________________
74 void AliMUONTrackReconstructorK::MakeTracks(void)
76 /// To make the tracks from the list of segments and points in all stations
77 AliDebug(1,"Enter MakeTracks");
78 // The order may be important for the following Reset's
80 MakeTrackCandidates();
81 if (fRecTracksPtr->GetEntriesFast() == 0) return;
82 // Follow tracks in stations(1..) 3, 2 and 1
84 // Remove double tracks
86 // Print out some track info (if necessary)
88 // Fill AliMUONTrack data members
92 //__________________________________________________________________________
93 void AliMUONTrackReconstructorK::MakeTrackCandidates(void)
95 /// To make initial tracks for Kalman filter from segments in stations(1..) 4 and 5
97 TClonesArray *segments;
98 AliMUONObjectPair *segment;
99 AliMUONTrackK *trackK;
101 AliDebug(1,"Enter MakeTrackCandidatesK");
103 AliMUONTrackK a(this, fHitsForRecPtr);
104 // Loop over stations(1...) 5 and 4
105 for (istat=4; istat>=3; istat--)
107 // Make segments in the station
108 segments = MakeSegmentsInStation(istat);
109 // Loop over segments in the station
110 for (iseg=0; iseg<segments->GetEntriesFast(); iseg++)
112 // Transform segments to tracks
113 segment = (AliMUONObjectPair*) ((*segments)[iseg]);
114 trackK = new ((*fRecTracksPtr)[fNRecTracks++]) AliMUONTrackK(*segment);
115 } // for (iseg=0;...)
117 } // for (istat=4;...)
120 //__________________________________________________________________________
121 void AliMUONTrackReconstructorK::FollowTracks(void)
123 /// Follow tracks using Kalman filter
125 Int_t icand, ichamBeg = 0, ichamEnd, chamBits;
126 AliMUONTrackK *trackK;
127 AliMUONHitForRec *hit;
128 AliMUONRawCluster *clus;
129 TClonesArray *rawclusters;
130 clus = 0; rawclusters = 0;
132 Double_t simpleBPosition = 0.5 * (AliMUONConstants::CoilZ() + AliMUONConstants::YokeZ());
133 Double_t simpleBLength = 0.5 * (AliMUONConstants::CoilL() + AliMUONConstants::YokeL());
134 Double_t zDipole1 = simpleBPosition + 0.5 * simpleBLength;
135 Double_t zDipole2 = zDipole1 - simpleBLength;
138 trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[0]);
142 nSeeds = fNRecTracks; // starting number of seeds
143 // Loop over track candidates
144 while (icand < fNRecTracks-1) {
146 if (trackK->DebugLevel()>0) cout << " *** Kalman track candidate No. " << icand << endl;
147 trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[icand]);
148 if (trackK->GetRecover() < 0) continue; // failed track
150 // Discard candidate which will produce the double track
153 ok = CheckCandidate(icand,nSeeds);
155 trackK->SetRecover(-1); // mark candidate to be removed
162 if (trackK->GetRecover() == 0)
163 hit = (AliMUONHitForRec*) trackK->GetTrackHits()->Last(); // last hit
165 hit = trackK->GetHitLastOk(); // hit where track stopped
167 if (hit) ichamBeg = hit->GetChamberNumber();
168 if (ichamBeg == 8 && trackK->GetStation0() == 4) ichamBeg = 10;
171 // Check propagation direction
172 if (!hit) { ichamBeg = ichamEnd; AliFatal(" ??? "); }
173 else if (trackK->GetTrackDir() < 0) {
174 ichamEnd = 9; // forward propagation
175 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kFALSE,zDipole1,zDipole2);
177 ichamBeg = ichamEnd + 1;
178 ichamEnd = 6; // backward propagation
179 // Change weight matrix and zero fChi2 for backpropagation
181 trackK->SetTrackDir(1);
182 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kTRUE,zDipole1,zDipole2);
187 if (trackK->GetBPFlag()) {
189 if (ichamBeg == 10) ichamEnd = 8;
191 if (ichamBeg == 9) ichamBeg++;
193 // Change weight matrix and zero fChi2 for backpropagation
196 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kTRUE,zDipole1,zDipole2);
203 trackK->SetTrackDir(1);
204 trackK->SetBPFlag(kFALSE);
205 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kFALSE,zDipole1,zDipole2);
207 if (!ok) { trackK->SetRecover(-1); continue; } // mark candidate to be removed
210 if (trackK->GetRecover() >= 0) {
211 ok = trackK->Smooth();
212 if (!ok) trackK->SetRecover(-1); // mark candidate to be removed
215 // Majority 3 of 4 in first 2 stations
218 Double_t chi2max = 0;
219 for (Int_t i=0; i<trackK->GetNTrackHits(); i++) {
220 hit = (AliMUONHitForRec*) (*trackK->GetTrackHits())[i];
221 chamBits |= BIT(hit->GetChamberNumber());
222 if (trackK->GetChi2PerPoint(i) > chi2max) chi2max = trackK->GetChi2PerPoint(i);
224 if (!((chamBits&3)==3 || (chamBits>>2&3)==3) && chi2max > 25) {
226 trackK->SetRecover(-1); //mark candidate to be removed
229 if (ok) trackK->SetTrackQuality(0); // compute "track quality"
232 for (Int_t i=0; i<fNRecTracks; i++) {
233 trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[i]);
234 if (trackK->GetRecover() < 0) fRecTracksPtr->RemoveAt(i);
237 // Compress TClonesArray
238 fRecTracksPtr->Compress();
239 fNRecTracks = fRecTracksPtr->GetEntriesFast();
243 //__________________________________________________________________________
244 Bool_t AliMUONTrackReconstructorK::CheckCandidate(Int_t icand, Int_t nSeeds) const
246 /// Discards track candidate if it will produce the double track (having
247 /// the same seed segment hits as hits of a good track found before)
248 AliMUONTrackK *track1, *track2;
249 AliMUONHitForRec *hit1, *hit2, *hit;
250 AliMUONObjectPair *segment1, *segment2;
252 track1 = (AliMUONTrackK*) ((*fRecTracksPtr)[icand]);
253 hit1 = (AliMUONHitForRec*) (*track1->GetTrackHits())[0]; // 1'st hit
254 hit2 = (AliMUONHitForRec*) (*track1->GetTrackHits())[1]; // 2'nd hit
256 for (Int_t i=0; i<icand; i++) {
257 track2 = (AliMUONTrackK*) ((*fRecTracksPtr)[i]);
258 //if (track2->GetRecover() < 0) continue;
259 if (track2->GetRecover() < 0 && icand >= nSeeds) continue;
260 segment1 = track1->GetStartSegment();
261 segment2 = track2->GetStartSegment();
262 if (segment1->First() == segment2->First() &&
263 segment1->Second() == segment2->Second()) {
267 for (Int_t j=0; j<track2->GetNTrackHits(); j++) {
268 hit = (AliMUONHitForRec*) (*track2->GetTrackHits())[j];
269 if (hit == hit1 || hit == hit2) {
271 if (nSame == 2) return kFALSE;
279 //__________________________________________________________________________
280 void AliMUONTrackReconstructorK::RemoveDoubleTracks(void)
282 /// Removes double tracks (sharing more than half of their hits).
283 /// Keeps the track with higher quality
284 AliMUONTrackK *track1, *track2, *trackToKill;
286 // Sort tracks according to their quality
287 fRecTracksPtr->Sort();
289 // Loop over first track of the pair
290 track1 = (AliMUONTrackK*) fRecTracksPtr->First();
291 Int_t debug = track1->DebugLevel();
293 // Loop over second track of the pair
294 track2 = (AliMUONTrackK*) fRecTracksPtr->After(track1);
296 // Check whether or not to keep track2
297 if (!track2->KeepTrack(track1)) {
298 if (debug >= 0) cout << " Killed track: " << 1/(*track2->GetTrackParameters())(4,0) <<
299 " " << track2->GetTrackQuality() << endl;
300 trackToKill = track2;
301 track2 = (AliMUONTrackK*) fRecTracksPtr->After(track2);
303 fRecTracksPtr->Compress();
304 } else track2 = (AliMUONTrackK*) fRecTracksPtr->After(track2);
306 track1 = (AliMUONTrackK*) fRecTracksPtr->After(track1);
309 fNRecTracks = fRecTracksPtr->GetEntriesFast();
310 if (debug >= 0) cout << " Number of Kalman tracks: " << fNRecTracks << endl;
313 //__________________________________________________________________________
314 void AliMUONTrackReconstructorK::FillMUONTrack()
316 // Set track parameters at hits for Kalman track. Fill fTrackParamAtHit of AliMUONTrack's
317 AliMUONTrackK *track;
318 track = (AliMUONTrackK*) fRecTracksPtr->First();
320 track->FillMUONTrack();
321 track = (AliMUONTrackK*) fRecTracksPtr->After(track);
327 //__________________________________________________________________________
328 void AliMUONTrackReconstructorK::EventDump(void)
330 /// Dump reconstructed event (track parameters at vertex and at first hit),
331 /// and the particle parameters
332 AliDebug(1,"****** enter EventDump ******");
333 AliDebug(1, Form("Number of Reconstructed tracks : %d", fNRecTracks));
335 Int_t debug = ((AliMUONTrackK*) fRecTracksPtr->First())->DebugLevel();
336 if (debug < 0) return;
338 for (Int_t i = 0; i < fNRecTracks; ++i) {
339 AliMUONTrackK *track = (AliMUONTrackK*) fRecTracksPtr->UncheckedAt(i);