]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONTrackReconstructorK.cxx
Optional geometry without CPV
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackReconstructorK.cxx
CommitLineData
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
18////////////////////////////////////
19//
20// MUON track reconstructor using the kalman method
21//
22// This class contains as data:
23// * the parameters for the track reconstruction
24//
25// It contains as methods, among others:
26// * MakeTracks to build the tracks
27//
28////////////////////////////////////
29
30#include <stdlib.h>
31#include <Riostream.h>
32#include <TDirectory.h>
33#include <TFile.h>
34#include <TMatrixD.h>
35
36#include "AliMUONVTrackReconstructor.h"
37#include "AliMUONTrackReconstructorK.h"
38#include "AliMUONData.h"
39#include "AliMUONConstants.h"
40#include "AliMUONHitForRec.h"
208f139e 41#include "AliMUONObjectPair.h"
8cc77df0 42#include "AliMUONRawCluster.h"
8cc77df0 43#include "AliMUONTrackK.h"
44#include "AliLog.h"
45
46ClassImp(AliMUONTrackReconstructorK) // Class implementation in ROOT context
47
48//__________________________________________________________________________
49AliMUONTrackReconstructorK::AliMUONTrackReconstructorK(AliMUONData* data, const Option_t* TrackMethod)
50 : AliMUONVTrackReconstructor(data),
51 fTrackMethod(2), //tracking method (2-Kalman 3-Combination-Kalman/Clustering)
52 fMuons(0)
53{
54 /// Constructor for class AliMUONTrackReconstructorK
55
56 if (strstr(TrackMethod,"Kalman")) {
57 cout << " *** Tracking with the Kalman filter *** " << endl;
58 fTrackMethod = 2;
59 } else if (strstr(TrackMethod,"Combi")) {
60 cout << " *** Combined cluster / track finder ***" << endl;
61 fTrackMethod = 3;
62 } else AliFatal(Form("Tracking method %s not available",TrackMethod));
63
64 // Memory allocation for the TClonesArray of reconstructed tracks
65 fRecTracksPtr = new TClonesArray("AliMUONTrackK", 10);
66}
67
68 //__________________________________________________________________________
69AliMUONTrackReconstructorK::~AliMUONTrackReconstructorK(void)
70{
71 /// Destructor for class AliMUONTrackReconstructorK
72 delete fRecTracksPtr;
73}
74
75 //__________________________________________________________________________
76void AliMUONTrackReconstructorK::AddHitsForRecFromRawClusters()
77{
78 /// To add to the list of hits for reconstruction all the raw clusters
e6b25a6e 79 TTree *treeR;
8cc77df0 80 AliMUONHitForRec *hitForRec;
81 AliMUONRawCluster *clus;
208f139e 82 Int_t iclus, nclus;
8cc77df0 83 TClonesArray *rawclusters;
84 AliDebug(1,"Enter AddHitsForRecFromRawClusters");
85
e6b25a6e 86 treeR = fMUONData->TreeR();
87 if (!treeR) {
88 AliError("TreeR must be loaded");
89 exit(0);
90 }
91
8cc77df0 92 if (fTrackMethod != 3) { //AZ
e6b25a6e 93 fMUONData->SetTreeAddress("RC"); //AZ
8cc77df0 94 fMUONData->GetRawClusters(); // only one entry
95 }
96
97 // Loop over tracking chambers
98 for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) {
8cc77df0 99 rawclusters =fMUONData->RawClusters(ch);
100 nclus = (Int_t) (rawclusters->GetEntries());
101 // Loop over (cathode correlated) raw clusters
102 for (iclus = 0; iclus < nclus; iclus++) {
103 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(iclus);
104 // new AliMUONHitForRec from raw cluster
105 // and increment number of AliMUONHitForRec's (total and in chamber)
106 hitForRec = new ((*fHitsForRecPtr)[fNHitsForRec]) AliMUONHitForRec(clus);
107 fNHitsForRec++;
8cc77df0 108 // more information into HitForRec
109 hitForRec->SetBendingReso2(clus->GetErrY() * clus->GetErrY());
110 hitForRec->SetNonBendingReso2(clus->GetErrX() * clus->GetErrX());
111 // original raw cluster
112 hitForRec->SetChamberNumber(ch);
113 hitForRec->SetHitNumber(iclus);
114 // Z coordinate of the raw cluster (cm)
115 hitForRec->SetZ(clus->GetZ(0));
8cc77df0 116 StdoutToAliDebug(3,
117 cout << "Chamber " << ch <<
118 " raw cluster " << iclus << " : " << endl;
119 clus->Print("full");
120 cout << "AliMUONHitForRec number (1...): " << fNHitsForRec << endl;
121 hitForRec->Print("full");
122 );
123 } // end of cluster loop
124 } // end of chamber loop
125 SortHitsForRecWithIncreasingChamber();
126
127 AliDebug(1,"End of AddHitsForRecFromRawClusters");
128 if (AliLog::GetGlobalDebugLevel() > 0) {
129 AliDebug(1, Form("NHitsForRec: %d",fNHitsForRec));
130 for (Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) {
131 AliDebug(1, Form("Chamber(0...): %d",ch));
132 AliDebug(1, Form("NHitsForRec: %d", fNHitsForRecPerChamber[ch]));
133 AliDebug(1, Form("Index(first HitForRec): %d", fIndexOfFirstHitForRecPerChamber[ch]));
134 for (Int_t hit = fIndexOfFirstHitForRecPerChamber[ch];
135 hit < fIndexOfFirstHitForRecPerChamber[ch] + fNHitsForRecPerChamber[ch];
136 hit++) {
137 AliDebug(1, Form("HitForRec index(0...): %d",hit));
138 ((*fHitsForRecPtr)[hit])->Dump();
139 }
140 }
141 }
142
143 return;
144}
145
8cc77df0 146 //__________________________________________________________________________
147void AliMUONTrackReconstructorK::MakeTracks(void)
148{
149 /// To make the tracks from the list of segments and points in all stations
150 AliDebug(1,"Enter MakeTracks");
151 // The order may be important for the following Reset's
152 //AZ ResetTracks();
153 MakeTrackCandidates();
154 if (fRecTracksPtr->GetEntriesFast() == 0) return;
155 // Follow tracks in stations(1..) 3, 2 and 1
156 FollowTracks();
157 // Remove double tracks
158 RemoveDoubleTracks();
208f139e 159 // Propagate tracks to the vertex through absorber
160 ExtrapTracksToVertex();
8cc77df0 161 // Fill AliMUONTrack data members
162 FillMUONTrack();
163}
164
165 //__________________________________________________________________________
166void AliMUONTrackReconstructorK::MakeTrackCandidates(void)
167{
208f139e 168 /// To make initial tracks for Kalman filter from segments in stations(1..) 4 and 5
8cc77df0 169 Int_t istat, iseg;
208f139e 170 TClonesArray *segments;
171 AliMUONObjectPair *segment;
8cc77df0 172 AliMUONTrackK *trackK;
173
174 AliDebug(1,"Enter MakeTrackCandidatesK");
175
176 AliMUONTrackK a(this, fHitsForRecPtr);
177 // Loop over stations(1...) 5 and 4
178 for (istat=4; istat>=3; istat--) {
208f139e 179 // Make segments in the station
180 segments = MakeSegmentsInStation(istat);
8cc77df0 181 // Loop over segments in the station
208f139e 182 for (iseg=0; iseg<segments->GetEntriesFast(); iseg++) {
183 // Transform segments to tracks
184 segment = (AliMUONObjectPair*) ((*segments)[iseg]);
8cc77df0 185 trackK = new ((*fRecTracksPtr)[fNRecTracks++]) AliMUONTrackK(segment);
186 } // for (iseg=0;...)
187 } // for (istat=4;...)
188 return;
189}
190
191//__________________________________________________________________________
192void AliMUONTrackReconstructorK::FollowTracks(void)
193{
194 /// Follow tracks using Kalman filter
195 Bool_t ok;
196 Int_t icand, ichamBeg = 0, ichamEnd, chamBits;
8cc77df0 197 AliMUONTrackK *trackK;
198 AliMUONHitForRec *hit;
199 AliMUONRawCluster *clus;
200 TClonesArray *rawclusters;
201 clus = 0; rawclusters = 0;
202
208f139e 203 Double_t simpleBPosition = 0.5 * (AliMUONConstants::CoilZ() + AliMUONConstants::YokeZ());
204 Double_t simpleBLength = 0.5 * (AliMUONConstants::CoilL() + AliMUONConstants::YokeL());
205 Double_t zDipole1 = simpleBPosition + 0.5 * simpleBLength;
206 Double_t zDipole2 = zDipole1 - simpleBLength;
8cc77df0 207
208 // Print hits
209 trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[0]);
210
211 if (trackK->DebugLevel() > 0) {
212 for (Int_t i1=0; i1<fNHitsForRec; i1++) {
213 hit = (AliMUONHitForRec*) ((*fHitsForRecPtr)[i1]);
214 printf(" Hit # %d %10.4f %10.4f %10.4f",
215 hit->GetChamberNumber(), hit->GetBendingCoor(),
216 hit->GetNonBendingCoor(), hit->GetZ());
217
218 // from raw clusters
219 rawclusters = fMUONData->RawClusters(hit->GetChamberNumber());
220 clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(hit->
221 GetHitNumber());
222 printf(" %d", clus->GetTrack(1));
223 if (clus->GetTrack(2) != -1) printf(" %d \n", clus->GetTrack(2));
224 else printf("\n");
225
226 }
227 } // if (trackK->DebugLevel() > 0)
228
229 icand = -1;
230 Int_t nSeeds;
231 nSeeds = fNRecTracks; // starting number of seeds
232 // Loop over track candidates
233 while (icand < fNRecTracks-1) {
234 icand ++;
235 if (trackK->DebugLevel()>0) cout << " *** Kalman track candidate No. " << icand << endl;
236 trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[icand]);
237 if (trackK->GetRecover() < 0) continue; // failed track
238
239 // Discard candidate which will produce the double track
240 /*
241 if (icand > 0) {
242 ok = CheckCandidate(icand,nSeeds);
243 if (!ok) {
244 trackK->SetRecover(-1); // mark candidate to be removed
245 continue;
246 }
247 }
248 */
249
250 ok = kTRUE;
251 if (trackK->GetRecover() == 0)
252 hit = (AliMUONHitForRec*) trackK->GetTrackHits()->Last(); // last hit
253 else
254 hit = trackK->GetHitLastOk(); // hit where track stopped
255
256 if (hit) ichamBeg = hit->GetChamberNumber();
257 ichamEnd = 0;
258 // Check propagation direction
259 if (!hit) { ichamBeg = ichamEnd; AliFatal(" ??? "); }
260 else if (trackK->GetTrackDir() < 0) {
261 ichamEnd = 9; // forward propagation
262 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kFALSE,zDipole1,zDipole2);
263 if (ok) {
264 ichamBeg = ichamEnd;
265 ichamEnd = 6; // backward propagation
266 // Change weight matrix and zero fChi2 for backpropagation
267 trackK->StartBack();
268 trackK->SetTrackDir(1);
269 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kTRUE,zDipole1,zDipole2);
270 ichamBeg = ichamEnd;
271 ichamEnd = 0;
272 }
273 } else {
274 if (trackK->GetBPFlag()) {
275 // backpropagation
276 ichamEnd = 6; // backward propagation
277 // Change weight matrix and zero fChi2 for backpropagation
278 trackK->StartBack();
279 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kTRUE,zDipole1,zDipole2);
280 ichamBeg = ichamEnd;
281 ichamEnd = 0;
282 }
283 }
284
285 if (ok) {
286 trackK->SetTrackDir(1);
287 trackK->SetBPFlag(kFALSE);
288 ok = trackK->KalmanFilter(ichamBeg,ichamEnd,kFALSE,zDipole1,zDipole2);
289 }
290 if (!ok) { trackK->SetRecover(-1); continue; } // mark candidate to be removed
291
292 // Apply smoother
293 if (trackK->GetRecover() >= 0) {
294 ok = trackK->Smooth();
295 if (!ok) trackK->SetRecover(-1); // mark candidate to be removed
296 }
297
298 // Majority 3 of 4 in first 2 stations
299 if (!ok) continue;
300 chamBits = 0;
301 Double_t chi2max = 0;
302 for (Int_t i=0; i<trackK->GetNTrackHits(); i++) {
303 hit = (AliMUONHitForRec*) (*trackK->GetTrackHits())[i];
304 chamBits |= BIT(hit->GetChamberNumber());
305 if (trackK->GetChi2PerPoint(i) > chi2max) chi2max = trackK->GetChi2PerPoint(i);
306 }
307 if (!((chamBits&3)==3 || (chamBits>>2&3)==3) && chi2max > 25) {
308 //trackK->Recover();
309 trackK->SetRecover(-1); //mark candidate to be removed
310 continue;
311 }
312 if (ok) trackK->SetTrackQuality(0); // compute "track quality"
313 } // while
314
315 for (Int_t i=0; i<fNRecTracks; i++) {
316 trackK = (AliMUONTrackK*) ((*fRecTracksPtr)[i]);
317 if (trackK->GetRecover() < 0) fRecTracksPtr->RemoveAt(i);
318 }
319
320 // Compress TClonesArray
321 fRecTracksPtr->Compress();
322 fNRecTracks = fRecTracksPtr->GetEntriesFast();
323 return;
324}
325
326//__________________________________________________________________________
327Bool_t AliMUONTrackReconstructorK::CheckCandidate(Int_t icand, Int_t nSeeds) const
328{
329 /// Discards track candidate if it will produce the double track (having
330 /// the same seed segment hits as hits of a good track found before)
331 AliMUONTrackK *track1, *track2;
332 AliMUONHitForRec *hit1, *hit2, *hit;
208f139e 333 AliMUONObjectPair *segment1, *segment2;
8cc77df0 334
335 track1 = (AliMUONTrackK*) ((*fRecTracksPtr)[icand]);
336 hit1 = (AliMUONHitForRec*) (*track1->GetTrackHits())[0]; // 1'st hit
337 hit2 = (AliMUONHitForRec*) (*track1->GetTrackHits())[1]; // 2'nd hit
338
339 for (Int_t i=0; i<icand; i++) {
340 track2 = (AliMUONTrackK*) ((*fRecTracksPtr)[i]);
341 //if (track2->GetRecover() < 0) continue;
342 if (track2->GetRecover() < 0 && icand >= nSeeds) continue;
208f139e 343 segment1 = track1->GetStartSegment();
344 segment2 = track2->GetStartSegment();
345 if (segment1->First() == segment2->First() &&
346 segment1->Second() == segment2->Second()) {
8cc77df0 347 return kFALSE;
348 } else {
349 Int_t nSame = 0;
350 for (Int_t j=0; j<track2->GetNTrackHits(); j++) {
351 hit = (AliMUONHitForRec*) (*track2->GetTrackHits())[j];
352 if (hit == hit1 || hit == hit2) {
353 nSame++;
354 if (nSame == 2) return kFALSE;
355 }
356 } // for (Int_t j=0;
357 }
358 } // for (Int_t i=0;
359 return kTRUE;
360}
361
362 //__________________________________________________________________________
363void AliMUONTrackReconstructorK::RemoveDoubleTracks(void)
364{
365 /// Removes double tracks (sharing more than half of their hits).
366 /// Keeps the track with higher quality
367 AliMUONTrackK *track1, *track2, *trackToKill;
368
369 // Sort tracks according to their quality
370 fRecTracksPtr->Sort();
371
372 // Loop over first track of the pair
373 track1 = (AliMUONTrackK*) fRecTracksPtr->First();
374 Int_t debug = track1->DebugLevel();
375 while (track1) {
376 // Loop over second track of the pair
377 track2 = (AliMUONTrackK*) fRecTracksPtr->After(track1);
378 while (track2) {
379 // Check whether or not to keep track2
380 if (!track2->KeepTrack(track1)) {
381 if (debug >= 0) cout << " Killed track: " << 1/(*track2->GetTrackParameters())(4,0) <<
382 " " << track2->GetTrackQuality() << endl;
383 trackToKill = track2;
384 track2 = (AliMUONTrackK*) fRecTracksPtr->After(track2);
385 trackToKill->Kill();
386 fRecTracksPtr->Compress();
387 } else track2 = (AliMUONTrackK*) fRecTracksPtr->After(track2);
388 } // track2
389 track1 = (AliMUONTrackK*) fRecTracksPtr->After(track1);
390 } // track1
391
392 fNRecTracks = fRecTracksPtr->GetEntriesFast();
393 if (debug >= 0) cout << " Number of Kalman tracks: " << fNRecTracks << endl;
394}
395
396 //__________________________________________________________________________
208f139e 397void AliMUONTrackReconstructorK::ExtrapTracksToVertex(void)
8cc77df0 398{
399 /// Propagates track to the vertex thru absorber
400 /// (using Branson correction for now)
401 Double_t zVertex;
402 zVertex = 0;
403 for (Int_t i=0; i<fNRecTracks; i++) {
404 //((AliMUONTrackK*)(*fRecTracksPtr)[i])->Branson();
405 ((AliMUONTrackK*)(*fRecTracksPtr)[i])->SetTrackQuality(1); // compute Chi2
406 //((AliMUONTrackK*)(*fRecTracksPtr)[i])->GoToZ(zVertex); // w/out absorber
407 ((AliMUONTrackK*)(*fRecTracksPtr)[i])->GoToVertex(1); // with absorber
408 }
409}
410
411 //__________________________________________________________________________
412void AliMUONTrackReconstructorK::FillMUONTrack()
413{
414 // Set track parameters at hits for Kalman track. Fill fTrackParamAtHit of AliMUONTrack's
415 AliMUONTrackK *track;
416 track = (AliMUONTrackK*) fRecTracksPtr->First();
417 while (track) {
418 track->FillMUONTrack();
419 track = (AliMUONTrackK*) fRecTracksPtr->After(track);
420 }
421 return;
422}
423
424 //__________________________________________________________________________
425void AliMUONTrackReconstructorK::EventDump(void)
426{
427 /// Dump reconstructed event (track parameters at vertex and at first hit),
428 /// and the particle parameters
429 AliDebug(1,"****** enter EventDump ******");
430 AliDebug(1, Form("Number of Reconstructed tracks : %d", fNRecTracks));
431
432 AliWarning("AliMUONTrackReconstructorK::EventDump: not implemented");
433
434 // informations about generated particles NO !!!!!!!!
435
436// for (Int_t iPart = 0; iPart < np; iPart++) {
437// p = gAlice->Particle(iPart);
438// printf(" particle %d: type= %d px= %f py= %f pz= %f pdg= %d\n",
439// iPart, p->GetPdgCode(), p->Px(), p->Py(), p->Pz(), p->GetPdgCode());
440// }
441 return;
442}
443
444