]>
Commit | Line | Data |
---|---|---|
8cc77df0 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
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 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
06ca6d7b | 18 | /// \class AliMUONTrackReconstructorK |
19 | ///////////////////////////////////// | |
20 | /// | |
21 | /// MUON track reconstructor using the kalman method | |
22 | /// | |
23 | /// This class contains as data: | |
24 | /// - the parameters for the track reconstruction | |
25 | /// | |
26 | /// It contains as methods, among others: | |
27 | /// - MakeTracks to build the tracks | |
28 | /// | |
8cc77df0 | 29 | //////////////////////////////////// |
30 | ||
8cc77df0 | 31 | #include "AliMUONTrackReconstructorK.h" |
8cc77df0 | 32 | #include "AliMUONConstants.h" |
33 | #include "AliMUONHitForRec.h" | |
208f139e | 34 | #include "AliMUONObjectPair.h" |
8cc77df0 | 35 | #include "AliMUONRawCluster.h" |
8cc77df0 | 36 | #include "AliMUONTrackK.h" |
8cde4af5 | 37 | |
8cc77df0 | 38 | #include "AliLog.h" |
39 | ||
8cde4af5 | 40 | #include <Riostream.h> |
41 | ||
42 | /// \cond CLASSIMP | |
8cc77df0 | 43 | ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context |
8cde4af5 | 44 | ClassImp(AliMUONConstants) |
45 | /// \endcond | |
8cc77df0 | 46 | |
47 | //__________________________________________________________________________ | |
7ec3b9cf | 48 | AliMUONTrackReconstructorK::AliMUONTrackReconstructorK(const Option_t* TrackMethod) |
49 | : AliMUONVTrackReconstructor(), | |
8cc77df0 | 50 | fTrackMethod(2), //tracking method (2-Kalman 3-Combination-Kalman/Clustering) |
51 | fMuons(0) | |
52 | { | |
53 | /// Constructor for class AliMUONTrackReconstructorK | |
54 | ||
55 | if (strstr(TrackMethod,"Kalman")) { | |
6abf71cd | 56 | AliInfo(" *** Tracking with the Kalman filter *** "); |
8cc77df0 | 57 | fTrackMethod = 2; |
58 | } else if (strstr(TrackMethod,"Combi")) { | |
6abf71cd | 59 | AliInfo(" *** Combined cluster / track finder ***"); |
8cc77df0 | 60 | fTrackMethod = 3; |
61 | } else AliFatal(Form("Tracking method %s not available",TrackMethod)); | |
62 | ||
63 | // Memory allocation for the TClonesArray of reconstructed tracks | |
64 | fRecTracksPtr = new TClonesArray("AliMUONTrackK", 10); | |
65 | } | |
66 | ||
7ec3b9cf | 67 | //__________________________________________________________________________ |
8cc77df0 | 68 | AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK(void) |
69 | { | |
70 | /// Destructor for class AliMUONTrackReconstructorK | |
71 | delete fRecTracksPtr; | |
72 | } | |
73 | ||
7ec3b9cf | 74 | //__________________________________________________________________________ |
8cc77df0 | 75 | void AliMUONTrackReconstructorK::MakeTracks(void) |
76 | { | |
77 | /// To make the tracks from the list of segments and points in all stations | |
78 | AliDebug(1,"Enter MakeTracks"); | |
79 | // The order may be important for the following Reset's | |
80 | //AZ ResetTracks(); | |
81 | MakeTrackCandidates(); | |
82 | if (fRecTracksPtr->GetEntriesFast() == 0) return; | |
83 | // Follow tracks in stations(1..) 3, 2 and 1 | |
84 | FollowTracks(); | |
85 | // Remove double tracks | |
86 | RemoveDoubleTracks(); | |
8cc77df0 | 87 | // Fill AliMUONTrack data members |
88 | FillMUONTrack(); | |
89 | } | |
90 | ||
91 | //__________________________________________________________________________ | |
92 | void AliMUONTrackReconstructorK::MakeTrackCandidates(void) | |
93 | { | |
208f139e | 94 | /// To make initial tracks for Kalman filter from segments in stations(1..) 4 and 5 |
8cc77df0 | 95 | Int_t istat, iseg; |
208f139e | 96 | TClonesArray *segments; |
97 | AliMUONObjectPair *segment; | |
8cc77df0 | 98 | AliMUONTrackK *trackK; |
99 | ||
100 | AliDebug(1,"Enter MakeTrackCandidatesK"); | |
101 | ||
102 | AliMUONTrackK a(this, fHitsForRecPtr); | |
103 | // Loop over stations(1...) 5 and 4 | |
7ec3b9cf | 104 | for (istat=4; istat>=3; istat--) |
105 | { | |
208f139e | 106 | // Make segments in the station |
107 | segments = MakeSegmentsInStation(istat); | |
8cc77df0 | 108 | // Loop over segments in the station |
7ec3b9cf | 109 | for (iseg=0; iseg<segments->GetEntriesFast(); iseg++) |
110 | { | |
208f139e | 111 | // Transform segments to tracks |
112 | segment = (AliMUONObjectPair*) ((*segments)[iseg]); | |
7ec3b9cf | 113 | trackK = new ((*fRecTracksPtr)[fNRecTracks++]) AliMUONTrackK(*segment); |
8cc77df0 | 114 | } // for (iseg=0;...) |
7ec3b9cf | 115 | delete segments; |
8cc77df0 | 116 | } // for (istat=4;...) |
8cc77df0 | 117 | } |
118 | ||
119 | //__________________________________________________________________________ | |
120 | void AliMUONTrackReconstructorK::FollowTracks(void) | |
121 | { | |
122 | /// Follow tracks using Kalman filter | |
123 | Bool_t ok; | |
124 | Int_t icand, ichamBeg = 0, ichamEnd, chamBits; | |
8cc77df0 | 125 | AliMUONTrackK *trackK; |
126 | AliMUONHitForRec *hit; | |
127 | AliMUONRawCluster *clus; | |
128 | TClonesArray *rawclusters; | |
129 | clus = 0; rawclusters = 0; | |
130 | ||
208f139e | 131 | Double_t simpleBPosition = 0.5 * (AliMUONConstants::CoilZ() + AliMUONConstants::YokeZ()); |
132 | Double_t simpleBLength = 0.5 * (AliMUONConstants::CoilL() + AliMUONConstants::YokeL()); | |
133 | Double_t zDipole1 = simpleBPosition + 0.5 * simpleBLength; | |
134 | Double_t zDipole2 = zDipole1 - simpleBLength; | |
8cc77df0 | 135 | |
136 | // Print hits | |
137 | trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[0]); | |
138 | ||
8cc77df0 | 139 | icand = -1; |
140 | Int_t nSeeds; | |
141 | nSeeds = fNRecTracks; // starting number of seeds | |
142 | // Loop over track candidates | |
143 | while (icand < fNRecTracks-1) { | |
144 | icand ++; | |
145 | if (trackK->DebugLevel()>0) cout << " *** Kalman track candidate No. " << icand << endl; | |
146 | trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[icand]); | |
147 | if (trackK->GetRecover() < 0) continue; // failed track | |
148 | ||
149 | // Discard candidate which will produce the double track | |
150 | /* | |
151 | if (icand > 0) { | |
152 | ok = CheckCandidate(icand,nSeeds); | |
153 | if (!ok) { | |
154 | trackK->SetRecover(-1); // mark candidate to be removed | |
155 | continue; | |
156 | } | |
157 | } | |
158 | */ | |
159 | ||
160 | ok = kTRUE; | |
161 | if (trackK->GetRecover() == 0) | |
162 | hit = (AliMUONHitForRec*) trackK->GetTrackHits()->Last(); // last hit | |
163 | else | |
164 | hit = trackK->GetHitLastOk(); // hit where track stopped | |
165 | ||
166 | if (hit) ichamBeg = hit->GetChamberNumber(); | |
167 | ichamEnd = 0; | |
168 | // Check propagation direction | |
169 | if (!hit) { ichamBeg = ichamEnd; AliFatal(" ??? "); } | |
170 | else if (trackK->GetTrackDir() < 0) { | |
171 | ichamEnd = 9; // forward propagation | |
172 | ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kFALSE,zDipole1,zDipole2); | |
173 | if (ok) { | |
174 | ichamBeg = ichamEnd; | |
175 | ichamEnd = 6; // backward propagation | |
176 | // Change weight matrix and zero fChi2 for backpropagation | |
177 | trackK->StartBack(); | |
178 | trackK->SetTrackDir(1); | |
179 | ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kTRUE,zDipole1,zDipole2); | |
180 | ichamBeg = ichamEnd; | |
181 | ichamEnd = 0; | |
182 | } | |
183 | } else { | |
184 | if (trackK->GetBPFlag()) { | |
185 | // backpropagation | |
186 | ichamEnd = 6; // backward propagation | |
187 | // Change weight matrix and zero fChi2 for backpropagation | |
188 | trackK->StartBack(); | |
189 | ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kTRUE,zDipole1,zDipole2); | |
190 | ichamBeg = ichamEnd; | |
191 | ichamEnd = 0; | |
192 | } | |
193 | } | |
194 | ||
195 | if (ok) { | |
196 | trackK->SetTrackDir(1); | |
197 | trackK->SetBPFlag(kFALSE); | |
198 | ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kFALSE,zDipole1,zDipole2); | |
199 | } | |
200 | if (!ok) { trackK->SetRecover(-1); continue; } // mark candidate to be removed | |
201 | ||
202 | // Apply smoother | |
203 | if (trackK->GetRecover() >= 0) { | |
204 | ok = trackK->Smooth(); | |
205 | if (!ok) trackK->SetRecover(-1); // mark candidate to be removed | |
206 | } | |
207 | ||
208 | // Majority 3 of 4 in first 2 stations | |
209 | if (!ok) continue; | |
210 | chamBits = 0; | |
211 | Double_t chi2max = 0; | |
212 | for (Int_t i=0; i<trackK->GetNTrackHits(); i++) { | |
213 | hit = (AliMUONHitForRec*) (*trackK->GetTrackHits())[i]; | |
214 | chamBits |= BIT(hit->GetChamberNumber()); | |
215 | if (trackK->GetChi2PerPoint(i) > chi2max) chi2max = trackK->GetChi2PerPoint(i); | |
216 | } | |
217 | if (!((chamBits&3)==3 || (chamBits>>2&3)==3) && chi2max > 25) { | |
218 | //trackK->Recover(); | |
219 | trackK->SetRecover(-1); //mark candidate to be removed | |
220 | continue; | |
221 | } | |
222 | if (ok) trackK->SetTrackQuality(0); // compute "track quality" | |
223 | } // while | |
224 | ||
225 | for (Int_t i=0; i<fNRecTracks; i++) { | |
226 | trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[i]); | |
227 | if (trackK->GetRecover() < 0) fRecTracksPtr->RemoveAt(i); | |
228 | } | |
229 | ||
230 | // Compress TClonesArray | |
231 | fRecTracksPtr->Compress(); | |
232 | fNRecTracks = fRecTracksPtr->GetEntriesFast(); | |
233 | return; | |
234 | } | |
235 | ||
236 | //__________________________________________________________________________ | |
237 | Bool_t AliMUONTrackReconstructorK::CheckCandidate(Int_t icand, Int_t nSeeds) const | |
238 | { | |
239 | /// Discards track candidate if it will produce the double track (having | |
240 | /// the same seed segment hits as hits of a good track found before) | |
241 | AliMUONTrackK *track1, *track2; | |
242 | AliMUONHitForRec *hit1, *hit2, *hit; | |
208f139e | 243 | AliMUONObjectPair *segment1, *segment2; |
8cc77df0 | 244 | |
245 | track1 = (AliMUONTrackK*) ((*fRecTracksPtr)[icand]); | |
246 | hit1 = (AliMUONHitForRec*) (*track1->GetTrackHits())[0]; // 1'st hit | |
247 | hit2 = (AliMUONHitForRec*) (*track1->GetTrackHits())[1]; // 2'nd hit | |
248 | ||
249 | for (Int_t i=0; i<icand; i++) { | |
250 | track2 = (AliMUONTrackK*) ((*fRecTracksPtr)[i]); | |
251 | //if (track2->GetRecover() < 0) continue; | |
252 | if (track2->GetRecover() < 0 && icand >= nSeeds) continue; | |
208f139e | 253 | segment1 = track1->GetStartSegment(); |
254 | segment2 = track2->GetStartSegment(); | |
255 | if (segment1->First() == segment2->First() && | |
256 | segment1->Second() == segment2->Second()) { | |
8cc77df0 | 257 | return kFALSE; |
258 | } else { | |
259 | Int_t nSame = 0; | |
260 | for (Int_t j=0; j<track2->GetNTrackHits(); j++) { | |
261 | hit = (AliMUONHitForRec*) (*track2->GetTrackHits())[j]; | |
262 | if (hit == hit1 || hit == hit2) { | |
263 | nSame++; | |
264 | if (nSame == 2) return kFALSE; | |
265 | } | |
266 | } // for (Int_t j=0; | |
267 | } | |
268 | } // for (Int_t i=0; | |
269 | return kTRUE; | |
270 | } | |
271 | ||
272 | //__________________________________________________________________________ | |
273 | void AliMUONTrackReconstructorK::RemoveDoubleTracks(void) | |
274 | { | |
275 | /// Removes double tracks (sharing more than half of their hits). | |
276 | /// Keeps the track with higher quality | |
277 | AliMUONTrackK *track1, *track2, *trackToKill; | |
278 | ||
279 | // Sort tracks according to their quality | |
280 | fRecTracksPtr->Sort(); | |
281 | ||
282 | // Loop over first track of the pair | |
283 | track1 = (AliMUONTrackK*) fRecTracksPtr->First(); | |
284 | Int_t debug = track1->DebugLevel(); | |
285 | while (track1) { | |
286 | // Loop over second track of the pair | |
287 | track2 = (AliMUONTrackK*) fRecTracksPtr->After(track1); | |
288 | while (track2) { | |
289 | // Check whether or not to keep track2 | |
290 | if (!track2->KeepTrack(track1)) { | |
291 | if (debug >= 0) cout << " Killed track: " << 1/(*track2->GetTrackParameters())(4,0) << | |
292 | " " << track2->GetTrackQuality() << endl; | |
293 | trackToKill = track2; | |
294 | track2 = (AliMUONTrackK*) fRecTracksPtr->After(track2); | |
295 | trackToKill->Kill(); | |
296 | fRecTracksPtr->Compress(); | |
297 | } else track2 = (AliMUONTrackK*) fRecTracksPtr->After(track2); | |
298 | } // track2 | |
299 | track1 = (AliMUONTrackK*) fRecTracksPtr->After(track1); | |
300 | } // track1 | |
301 | ||
302 | fNRecTracks = fRecTracksPtr->GetEntriesFast(); | |
303 | if (debug >= 0) cout << " Number of Kalman tracks: " << fNRecTracks << endl; | |
304 | } | |
305 | ||
8cc77df0 | 306 | //__________________________________________________________________________ |
307 | void AliMUONTrackReconstructorK::FillMUONTrack() | |
308 | { | |
309 | // Set track parameters at hits for Kalman track. Fill fTrackParamAtHit of AliMUONTrack's | |
310 | AliMUONTrackK *track; | |
311 | track = (AliMUONTrackK*) fRecTracksPtr->First(); | |
312 | while (track) { | |
313 | track->FillMUONTrack(); | |
314 | track = (AliMUONTrackK*) fRecTracksPtr->After(track); | |
315 | } | |
316 | return; | |
317 | } | |
318 | ||
8cc77df0 | 319 |