AliRoot Core  v5-06-30 (35d6c57)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliMUONTrackReconstructor.cxx
Go to the documentation of this file.
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 //-----------------------------------------------------------------------------
27 //-----------------------------------------------------------------------------
28 
30 
31 #include "AliMUONConstants.h"
32 #include "AliMUONVCluster.h"
33 #include "AliMUONVClusterServer.h"
34 #include "AliMUONVClusterStore.h"
35 #include "AliMUONTrack.h"
36 #include "AliMUONTrackParam.h"
37 #include "AliMUONTrackExtrap.h"
38 #include "AliMUONRecoParam.h"
40 
41 #include "AliMpArea.h"
42 
43 #include "AliLog.h"
44 
45 #include <TMinuit.h>
46 #include <Riostream.h>
47 #include <TMath.h>
48 #include <TMatrixD.h>
49 #include <TClonesArray.h>
50 
51 // Functions to be minimized with Minuit
52 void TrackChi2(Int_t &nParam, Double_t *gradient, Double_t &chi2, Double_t *param, Int_t flag);
53 
54 using std::endl;
55 using std::cout;
57 ClassImp(AliMUONTrackReconstructor) // Class implementation in ROOT context
59 
60  //__________________________________________________________________________
62  const AliMUONGeometryTransformer* transformer)
63  : AliMUONVTrackReconstructor(recoParam, clusterServer, transformer)
64 {
66 }
67 
68  //__________________________________________________________________________
70 {
72 }
73 
74  //__________________________________________________________________________
76 {
81 
82  TClonesArray *segments;
84  Int_t iCandidate = 0;
85  Bool_t clusterFound;
86 
87  AliDebug(1,"Enter MakeTrackCandidates");
88 
89  // Unless we're doing combined tracking, we'll clusterize all stations at once
90  Int_t firstChamber(0);
91  Int_t lastChamber(9);
92 
93  if (GetRecoParam()->CombineClusterTrackReco()) {
94  // ... Here's the exception : ask the clustering to reconstruct
95  // clusters *only* in station 4 and 5 for combined tracking
96  firstChamber = 6;
97  }
98 
99  for (Int_t i = firstChamber; i <= lastChamber; ++i )
100  {
101  if (fClusterServer && GetRecoParam()->UseChamber(i)) fClusterServer->Clusterize(i, clusterStore, AliMpArea(), GetRecoParam());
102  }
103 
104  // Loop over stations(1..) 5 and 4 and make track candidates
105  for (Int_t istat=4; istat>=3; istat--) {
106 
107  // Make segments in the station
108  segments = MakeSegmentsBetweenChambers(clusterStore, 2*istat, 2*istat+1);
109 
110  // Loop over segments
111  for (Int_t iseg=0; iseg<segments->GetEntriesFast(); iseg++)
112  {
113  AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
114 
115  // Transform segments to tracks and put them at the end of fRecTracksPtr
116  track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack((AliMUONObjectPair*)((*segments)[iseg]),GetRecoParam()->GetBendingVertexDispersion());
117  fNRecTracks++;
118 
119  // Look for compatible cluster(s) in the other station
121  clusterFound = FollowLinearTrackInStation(*track, clusterStore, 7-istat);
122  else clusterFound = FollowTrackInStation(*track, clusterStore, 7-istat);
123 
124  // Remove track if no cluster found on a requested station
125  // or abort tracking if there are too many candidates
126  if (GetRecoParam()->RequestStation(7-istat)) {
127  if (!clusterFound) {
128  fRecTracksPtr->Remove(track);
129  fNRecTracks--;
130  } else if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
131  AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks));
132  return kFALSE;
133  }
134  } else {
135  if ((fNRecTracks + segments->GetEntriesFast() - iseg - 1) > GetRecoParam()->GetMaxTrackCandidates()) {
136  AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks + segments->GetEntriesFast() - iseg - 1));
137  return kFALSE;
138  }
139  }
140 
141  }
142 
143  }
144 
145  // Keep all different tracks or only the best ones as required
146  if (GetRecoParam()->TrackAllTracks()) RemoveIdenticalTracks();
147  else RemoveDoubleTracks();
148 
149  AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
150 
151  return kTRUE;
152 
153 }
154 
155  //__________________________________________________________________________
157 {
163 
164  TClonesArray *segments;
165  AliMUONObjectPair *segment;
167  Int_t iCandidate = 0, iCurrentTrack, nCurrentTracks;
168  Bool_t clusterFound;
169 
170  AliDebug(1,"Enter MakeMoreTrackCandidates");
171 
172  // Double loop over chambers in stations(1..) 4 and 5 to make track candidates
173  for (Int_t ich1 = 6; ich1 <= 7; ich1++) {
174  for (Int_t ich2 = 8; ich2 <= 9; ich2++) {
175 
176  // Make segments in the station
177  segments = MakeSegmentsBetweenChambers(clusterStore, ich1, ich2);
178 
180  RemoveUsedSegments(*segments);
181 
182  // Loop over segments
183  for (Int_t iSegment=0; iSegment<segments->GetEntriesFast(); iSegment++)
184  {
185  AliDebug(1,Form("Making primary candidate(1..) %d",++iCandidate));
186  segment = (AliMUONObjectPair*) segments->UncheckedAt(iSegment);
187 
188  // Transform segments to tracks and put them at the end of fRecTracksPtr
189  iCurrentTrack = fRecTracksPtr->GetLast()+1;
190  track = new ((*fRecTracksPtr)[iCurrentTrack]) AliMUONTrack(segment,GetRecoParam()->GetBendingVertexDispersion());
191  fNRecTracks++;
192 
193  // Look for compatible cluster(s) in the second chamber of station 5
194  clusterFound = FollowLinearTrackInChamber(*track, clusterStore, 17-ich2);
195 
196  // skip the original track in case it has been removed
197  if (GetRecoParam()->TrackAllTracks() && clusterFound) iCurrentTrack++;
198 
199  // loop over every new tracks
200  nCurrentTracks = fRecTracksPtr->GetLast()+1;
201  while (iCurrentTrack < nCurrentTracks) {
202  track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iCurrentTrack);
203 
204  // Look for compatible cluster(s) in the second chamber of station 4
205  FollowLinearTrackInChamber(*track, clusterStore, 13-ich1);
206 
207  iCurrentTrack++;
208  }
209 
210  // abort tracking if there are too many candidates
211  if ((fNRecTracks + segments->GetEntriesFast() - iSegment - 1) > GetRecoParam()->GetMaxTrackCandidates()) {
212  AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks + segments->GetEntriesFast() - iSegment - 1));
213  return kFALSE;
214  }
215 
216  }
217 
218  }
219  }
220 
221  // Keep only the best tracks if required
222  if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks();
223  else fRecTracksPtr->Compress();
224 
225  AliDebug(1,Form("Number of good candidates = %d",fNRecTracks));
226 
227  return kTRUE;
228 
229 }
230 
231  //__________________________________________________________________________
233 {
235  AliDebug(1,"Enter FollowTracks");
236 
237  AliMUONTrack *track, *nextTrack;
238  AliMUONTrackParam *trackParam, *nextTrackParam;
239  Int_t currentNRecTracks;
240 
241  Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForTracking() *
243 
244  for (Int_t station = 2; station >= 0; station--) {
245 
246  // Save the actual number of reconstructed track in case of
247  // tracks are added or suppressed during the tracking procedure
248  // !! Do not compress fRecTracksPtr until the end of the loop over tracks !!
249  currentNRecTracks = fNRecTracks;
250 
251  for (Int_t iRecTrack = 0; iRecTrack <currentNRecTracks; iRecTrack++) {
252  AliDebug(1,Form("FollowTracks: track candidate(1..) %d", iRecTrack+1));
253 
254  track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iRecTrack);
255 
256  // Fit the track:
257  // Do not take into account the multiple scattering to speed up the fit
258  // Calculate the track parameter covariance matrix
259  // If there is no cluster out of station 4 or 5 then use the vertex to better constrain the fit
260  if (((AliMUONTrackParam*) track->GetTrackParamAtCluster()->First())->GetClusterPtr()->GetChamberId() > 5)
261  Fit(*track, kFALSE, kTRUE, kTRUE);
262  else Fit(*track, kFALSE, kFALSE, kTRUE);
263 
264  // remove tracks out of limits
265  if (!IsAcceptable(*((AliMUONTrackParam*)track->GetTrackParamAtCluster()->First()))) {
266  fRecTracksPtr->Remove(track);
267  fNRecTracks--;
268  continue;
269  }
270 
271  // remove track if the normalized chi2 is too high
272  if (track->GetNormalizedChi2() > sigmaCut2) {
273  fRecTracksPtr->Remove(track);
274  fNRecTracks--;
275  continue;
276  }
277 
278  // save parameters from fit into smoothed parameters to complete track afterward
279  if (GetRecoParam()->ComplementTracks()) {
280 
281  if (station==2) { // save track parameters on stations 4 and 5
282 
283  // extrapolate track parameters and covariances at each cluster
284  // remove the track in case of failure
285  if (!track->UpdateCovTrackParamAtCluster()) {
286  fRecTracksPtr->Remove(track);
287  fNRecTracks--;
288  continue;
289  }
290 
291  // save them
292  trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
293  while (trackParam) {
294  trackParam->SetSmoothParameters(trackParam->GetParameters());
295  trackParam->SetSmoothCovariances(trackParam->GetCovariances());
296  trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
297  }
298 
299  } else { // or save track parameters on last station only
300 
301  trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
302  if (trackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) {
303 
304  // save parameters from fit
305  trackParam->SetSmoothParameters(trackParam->GetParameters());
306  trackParam->SetSmoothCovariances(trackParam->GetCovariances());
307 
308  // save parameters extrapolated to the second chamber of the same station if it has been hit
309  nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
310  if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2*(station+2)) {
311 
312  // reset parameters and covariances
313  nextTrackParam->SetParameters(trackParam->GetParameters());
314  nextTrackParam->SetZ(trackParam->GetZ());
315  nextTrackParam->SetCovariances(trackParam->GetCovariances());
316 
317  // extrapolate them to the z of the corresponding cluster
318  // remove the track in case of failure
319  if (!AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ())) {
320  fRecTracksPtr->Remove(track);
321  fNRecTracks--;
322  continue;
323  }
324 
325  // save them
326  nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
327  nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
328 
329  }
330 
331  }
332 
333  }
334 
335  }
336 
337  // Look for compatible cluster(s) in station(0..) "station"
338  if (!FollowTrackInStation(*track, clusterStore, station)) {
339 
340  // Try to recover track if required
341  if (GetRecoParam()->RecoverTracks()) {
342 
343  // work on a copy of the track if this station is not required
344  // to keep the case where no cluster is reconstructed as a possible candidate
345  if (!GetRecoParam()->RequestStation(station)) {
346  track = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(*track);
347  fNRecTracks++;
348  }
349 
350  // try to recover
351  if (!RecoverTrack(*track, clusterStore, station)) {
352  // remove track if no cluster found
353  fRecTracksPtr->Remove(track);
354  fNRecTracks--;
355  }
356 
357  } else if (GetRecoParam()->RequestStation(station)) {
358  // remove track if no cluster found
359  fRecTracksPtr->Remove(track);
360  fNRecTracks--;
361  }
362 
363  }
364 
365  // abort tracking if there are too many candidates
366  if (fNRecTracks > GetRecoParam()->GetMaxTrackCandidates()) {
367  AliError(Form("Too many track candidates (%d tracks). Stop tracking.", fNRecTracks));
368  return kFALSE;
369  }
370 
371  }
372 
373  // Compress fRecTracksPtr for the next step
374  fRecTracksPtr->Compress();
375 
376  // Keep only the best tracks if required
377  if (!GetRecoParam()->TrackAllTracks()) RemoveDoubleTracks();
378 
379  }
380 
381  // Last fit of track candidates with all stations
382  // Take into account the multiple scattering and remove bad tracks
383  Int_t trackIndex = -1;
384  track = (AliMUONTrack*) fRecTracksPtr->First();
385  while (track) {
386 
387  trackIndex++;
388  nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track); // prepare next track
389 
390  Fit(*track, kTRUE, kFALSE, kTRUE);
391 
392  // Printout for debuging
393  if (AliLog::GetGlobalDebugLevel() >= 3) {
394  cout << "FollowTracks: track candidate(0..) " << trackIndex << " after final fit" << endl;
395  track->RecursiveDump();
396  }
397 
398  // Remove the track if the normalized chi2 is too high
399  if (track->GetNormalizedChi2() > sigmaCut2) {
400  fRecTracksPtr->Remove(track);
401  fNRecTracks--;
402  track = nextTrack;
403  continue;
404  }
405 
406  // save parameters from fit into smoothed parameters to complete track afterward
407  if (GetRecoParam()->ComplementTracks()) {
408 
409  trackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->First();
410  if (trackParam->GetClusterPtr()->GetChamberId() < 2) {
411 
412  // save parameters from fit
413  trackParam->SetSmoothParameters(trackParam->GetParameters());
414  trackParam->SetSmoothCovariances(trackParam->GetCovariances());
415 
416  // save parameters extrapolated to the second chamber of the same station if it has been hit
417  nextTrackParam = (AliMUONTrackParam*) track->GetTrackParamAtCluster()->After(trackParam);
418  if (nextTrackParam->GetClusterPtr()->GetChamberId() < 2) {
419 
420  // reset parameters and covariances
421  nextTrackParam->SetParameters(trackParam->GetParameters());
422  nextTrackParam->SetZ(trackParam->GetZ());
423  nextTrackParam->SetCovariances(trackParam->GetCovariances());
424 
425  // extrapolate them to the z of the corresponding cluster
426  // remove the track in case of failure
427  if (!AliMUONTrackExtrap::ExtrapToZCov(nextTrackParam, nextTrackParam->GetClusterPtr()->GetZ())) {
428  fRecTracksPtr->Remove(track);
429  fNRecTracks--;
430  track = nextTrack;
431  continue;
432  }
433 
434  // save them
435  nextTrackParam->SetSmoothParameters(nextTrackParam->GetParameters());
436  nextTrackParam->SetSmoothCovariances(nextTrackParam->GetCovariances());
437 
438  }
439 
440  }
441 
442  }
443 
444  track = nextTrack;
445 
446  }
447 
448  fRecTracksPtr->Compress();
449 
450  return kTRUE;
451 
452 }
453 
454  //__________________________________________________________________________
455 Bool_t AliMUONTrackReconstructor::FollowTrackInChamber(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextChamber)
456 {
463  AliDebug(1,Form("Enter FollowTrackInChamber(1..) %d", nextChamber+1));
464 
465  Double_t chi2WithOneCluster = AliMUONTrack::MaxChi2();
466  Double_t maxChi2WithOneCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() *
467  GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
468  Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
469  Bool_t foundOneCluster = kFALSE;
470  AliMUONTrack *newTrack = 0x0;
471  AliMUONVCluster *cluster;
472  AliMUONTrackParam extrapTrackParam;
473  AliMUONTrackParam extrapTrackParamAtCh;
474  AliMUONTrackParam extrapTrackParamAtCluster;
475  AliMUONTrackParam bestTrackParamAtCluster;
476 
477  // Get track parameters according to the propagation direction
478  if (nextChamber > 7) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
479  else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
480 
481  // Printout for debuging
482  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
483  cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
484  extrapTrackParamAtCh.GetParameters().Print();
485  extrapTrackParamAtCh.GetCovariances().Print();
486  }
487 
488  // Add MCS effect
489  Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId();
490  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.);
491 
492  // Add MCS in the missing chamber(s) if any
493  while (currentChamber > nextChamber + 1) {
494  // extrapolation to the missing chamber
495  currentChamber--;
496  if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber))) return kFALSE;
497  // add MCS effect
498  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.);
499  }
500 
501  //Extrapolate trackCandidate to chamber
502  if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(nextChamber))) return kFALSE;
503 
504  // Printout for debuging
505  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
506  cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(nextChamber)<<":"<<endl;
507  extrapTrackParamAtCh.GetParameters().Print();
508  extrapTrackParamAtCh.GetCovariances().Print();
509  }
510 
511  // Printout for debuging
512  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
513  cout << "FollowTrackInStation: look for clusters in chamber(1..): " << nextChamber+1 << endl;
514  }
515 
516  // Ask the clustering to reconstruct new clusters around the track position in the current chamber
517  // except for station 4 and 5 that are already entirely clusterized
518  if (GetRecoParam()->CombineClusterTrackReco()) {
519  if (nextChamber < 6) AskForNewClustersInChamber(extrapTrackParamAtCh, clusterStore, nextChamber);
520  }
521 
522  // Create iterators to loop over clusters in both chambers
523  TIter next(clusterStore.CreateChamberIterator(nextChamber,nextChamber));
524 
525  // look for cluster in chamber
526  while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) ) {
527 
528  // try to add the current cluster fast
529  if (!TryOneClusterFast(extrapTrackParamAtCh, cluster)) continue;
530 
531  // try to add the current cluster accuratly
532  chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, cluster, extrapTrackParamAtCluster);
533 
534  // if good chi2 then consider to add cluster
535  if (chi2WithOneCluster < maxChi2WithOneCluster) {
536  foundOneCluster = kTRUE;
537 
538  // Printout for debuging
539  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
540  cout << "FollowTrackInStation: found one cluster in chamber(1..): " << nextChamber+1
541  << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
542  cluster->Print();
543  }
544 
545  if (GetRecoParam()->TrackAllTracks()) {
546  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
547  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
548  UpdateTrack(*newTrack,extrapTrackParamAtCluster);
549  fNRecTracks++;
550 
551  // Printout for debuging
552  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
553  cout << "FollowTrackInStation: added one cluster in chamber(1..): " << nextChamber+1 << endl;
554  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
555  }
556 
557  } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
558  // keep track of the best single cluster except if a couple of clusters has already been found
559  bestChi2WithOneCluster = chi2WithOneCluster;
560  bestTrackParamAtCluster = extrapTrackParamAtCluster;
561  }
562 
563  }
564 
565  }
566 
567  // fill out the best track if required else clean up the fRecTracksPtr array
568  if (!GetRecoParam()->TrackAllTracks()) {
569  if (foundOneCluster) {
570  UpdateTrack(trackCandidate,bestTrackParamAtCluster);
571 
572  // Printout for debuging
573  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
574  cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster.GetClusterPtr()->GetChamberId()+1 << endl;
575  if (AliLog::GetGlobalDebugLevel() >= 3) trackCandidate.RecursiveDump();
576  }
577 
578  } else return kFALSE;
579 
580  } else if (foundOneCluster) {
581 
582  // remove obsolete track
583  fRecTracksPtr->Remove(&trackCandidate);
584  fNRecTracks--;
585 
586  } else return kFALSE;
587 
588  return kTRUE;
589 
590 }
591 
592  //__________________________________________________________________________
593 Bool_t AliMUONTrackReconstructor::FollowTrackInStation(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextStation)
594 {
601  AliDebug(1,Form("Enter FollowTrackInStation(1..) %d", nextStation+1));
602 
603  // Order the chamber according to the propagation direction (tracking starts with chamber 2):
604  // - nextStation == station(1...) 5 => forward propagation
605  // - nextStation < station(1...) 5 => backward propagation
606  Int_t ch1, ch2;
607  if (nextStation==4) {
608  ch1 = 2*nextStation+1;
609  ch2 = 2*nextStation;
610  } else {
611  ch1 = 2*nextStation;
612  ch2 = 2*nextStation+1;
613  }
614 
615  Double_t chi2WithOneCluster = AliMUONTrack::MaxChi2();
616  Double_t chi2WithTwoClusters = AliMUONTrack::MaxChi2();
617  Double_t maxChi2WithOneCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() *
618  GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
619  Double_t maxChi2WithTwoClusters = 4. * GetRecoParam()->GetSigmaCutForTracking() *
620  GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2
621  Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
622  Double_t bestChi2WithTwoClusters = maxChi2WithTwoClusters;
623  Bool_t foundOneCluster = kFALSE;
624  Bool_t foundTwoClusters = kFALSE;
625  AliMUONTrack *newTrack = 0x0;
626  AliMUONVCluster *clusterCh1, *clusterCh2;
627  AliMUONTrackParam extrapTrackParam;
628  AliMUONTrackParam extrapTrackParamAtCh;
629  AliMUONTrackParam extrapTrackParamAtCluster1;
630  AliMUONTrackParam extrapTrackParamAtCluster2;
631  AliMUONTrackParam bestTrackParamAtCluster1;
632  AliMUONTrackParam bestTrackParamAtCluster2;
633 
634  // Get track parameters according to the propagation direction
635  if (nextStation==4) extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
636  else extrapTrackParamAtCh = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
637 
638  // Printout for debuging
639  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
640  cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
641  extrapTrackParamAtCh.GetParameters().Print();
642  extrapTrackParamAtCh.GetCovariances().Print();
643  }
644 
645  // Add MCS effect
646  Int_t currentChamber = extrapTrackParamAtCh.GetClusterPtr()->GetChamberId();
647  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.);
648 
649  // Add MCS in the missing chamber(s) if any
650  while (ch1 < ch2 && currentChamber > ch2 + 1) {
651  // extrapolation to the missing chamber
652  currentChamber--;
653  if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(currentChamber))) return kFALSE;
654  // add MCS effect
655  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCh,AliMUONConstants::ChamberThicknessInX0(currentChamber),-1.);
656  }
657 
658  //Extrapolate trackCandidate to chamber "ch2"
659  if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch2))) return kFALSE;
660 
661  // Printout for debuging
662  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
663  cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch2)<<":"<<endl;
664  extrapTrackParamAtCh.GetParameters().Print();
665  extrapTrackParamAtCh.GetCovariances().Print();
666  }
667 
668  // Printout for debuging
669  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
670  cout << "FollowTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl;
671  }
672 
673  // Ask the clustering to reconstruct new clusters around the track position in the current station
674  // except for station 4 and 5 that are already entirely clusterized
675  if (GetRecoParam()->CombineClusterTrackReco()) {
676  if (nextStation < 3) AskForNewClustersInStation(extrapTrackParamAtCh, clusterStore, nextStation);
677  }
678 
679  Int_t nClusters = clusterStore.GetSize();
680  Bool_t *clusterCh1Used = new Bool_t[nClusters];
681  for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE;
682  Int_t iCluster1;
683 
684  // Create iterators to loop over clusters in both chambers
685  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
686  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
687 
688  // look for candidates in chamber 2
689  while ( ( clusterCh2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
690 
691  // try to add the current cluster fast
692  if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh2)) continue;
693 
694  // try to add the current cluster accuratly
695  chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh2, extrapTrackParamAtCluster2);
696 
697  // if good chi2 then try to attach a cluster in the other chamber too
698  if (chi2WithOneCluster < maxChi2WithOneCluster) {
699  Bool_t foundSecondCluster = kFALSE;
700 
701  // Printout for debuging
702  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
703  cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch2+1
704  << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
705  clusterCh2->Print();
706  cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
707  }
708 
709  // add MCS effect for next step
710  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(ch2),-1.);
711 
712  // copy new track parameters for next step
713  extrapTrackParam = extrapTrackParamAtCluster2;
714 
715  //Extrapolate track parameters to chamber "ch1"
716  Bool_t normalExtrap = AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(ch1));
717 
718  // reset cluster iterator of chamber 1
719  nextInCh1.Reset();
720  iCluster1 = -1;
721 
722  // look for second candidates in chamber 1
723  if (normalExtrap) while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
724  iCluster1++;
725 
726  // try to add the current cluster fast
727  if (!TryOneClusterFast(extrapTrackParam, clusterCh1)) continue;
728 
729  // try to add the current cluster accurately
730  chi2WithTwoClusters = TryTwoClusters(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1);
731 
732  // if good chi2 then create a new track by adding the 2 clusters to the "trackCandidate"
733  if (chi2WithTwoClusters < maxChi2WithTwoClusters) {
734  foundSecondCluster = kTRUE;
735  foundTwoClusters = kTRUE;
736 
737  // Printout for debuging
738  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
739  cout << "FollowTrackInStation: found second cluster in chamber(1..): " << ch1+1
740  << " (Global Chi2 = " << chi2WithTwoClusters << ")" << endl;
741  clusterCh1->Print();
742  }
743 
744  if (GetRecoParam()->TrackAllTracks()) {
745  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
746  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
747  UpdateTrack(*newTrack,extrapTrackParamAtCluster1,extrapTrackParamAtCluster2);
748  fNRecTracks++;
749 
750  // Tag clusterCh1 as used
751  clusterCh1Used[iCluster1] = kTRUE;
752 
753  // Printout for debuging
754  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
755  cout << "FollowTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl;
756  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
757  }
758 
759  } else if (chi2WithTwoClusters < bestChi2WithTwoClusters) {
760  // keep track of the best couple of clusters
761  bestChi2WithTwoClusters = chi2WithTwoClusters;
762  bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
763  bestTrackParamAtCluster2 = extrapTrackParamAtCluster2;
764  }
765 
766  }
767 
768  }
769 
770  // if no clusterCh1 found then consider to add clusterCh2 only
771  if (!foundSecondCluster) {
772  foundOneCluster = kTRUE;
773 
774  if (GetRecoParam()->TrackAllTracks()) {
775  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
776  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
777  UpdateTrack(*newTrack,extrapTrackParamAtCluster2);
778  fNRecTracks++;
779 
780  // Printout for debuging
781  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
782  cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl;
783  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
784  }
785 
786  } else if (!foundTwoClusters && chi2WithOneCluster < bestChi2WithOneCluster) {
787  // keep track of the best single cluster except if a couple of clusters has already been found
788  bestChi2WithOneCluster = chi2WithOneCluster;
789  bestTrackParamAtCluster1 = extrapTrackParamAtCluster2;
790  }
791 
792  }
793 
794  }
795 
796  }
797 
798  // look for candidates in chamber 1 not already attached to a track
799  // if we want to keep all possible tracks or if no good couple of clusters has been found
800  if (GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
801 
802  // add MCS effect for next step
804 
805  //Extrapolate trackCandidate to chamber "ch1"
806  Bool_t normalExtrap = AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParamAtCh, AliMUONConstants::DefaultChamberZ(ch1));
807 
808  // Printout for debuging
809  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
810  cout<<endl<<"Track parameters and covariances at first cluster extrapolated to z = "<<AliMUONConstants::DefaultChamberZ(ch1)<<":"<<endl;
811  extrapTrackParamAtCh.GetParameters().Print();
812  extrapTrackParamAtCh.GetCovariances().Print();
813  }
814 
815  // Printout for debuging
816  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
817  cout << "FollowTrackInStation: look for single clusters in chamber(1..): " << ch1+1 << endl;
818  }
819 
820  // reset cluster iterator of chamber 1
821  nextInCh1.Reset();
822  iCluster1 = -1;
823 
824  // look for second candidates in chamber 1
825  if (normalExtrap) while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
826  iCluster1++;
827 
828  if (clusterCh1Used[iCluster1]) continue; // Skip cluster already used
829 
830  // try to add the current cluster fast
831  if (!TryOneClusterFast(extrapTrackParamAtCh, clusterCh1)) continue;
832 
833  // try to add the current cluster accuratly
834  chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCh, clusterCh1, extrapTrackParamAtCluster1);
835 
836  // if good chi2 then consider to add clusterCh1
837  // We do not try to attach a cluster in the other chamber too since it has already been done above
838  if (chi2WithOneCluster < maxChi2WithOneCluster) {
839  foundOneCluster = kTRUE;
840 
841  // Printout for debuging
842  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
843  cout << "FollowTrackInStation: found one cluster in chamber(1..): " << ch1+1
844  << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
845  clusterCh1->Print();
846  }
847 
848  if (GetRecoParam()->TrackAllTracks()) {
849  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
850  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
851  UpdateTrack(*newTrack,extrapTrackParamAtCluster1);
852  fNRecTracks++;
853 
854  // Printout for debuging
855  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
856  cout << "FollowTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl;
857  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
858  }
859 
860  } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
861  // keep track of the best single cluster except if a couple of clusters has already been found
862  bestChi2WithOneCluster = chi2WithOneCluster;
863  bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
864  }
865 
866  }
867 
868  }
869 
870  }
871 
872  // fill out the best track if required else clean up the fRecTracksPtr array
873  if (!GetRecoParam()->TrackAllTracks()) {
874  if (foundTwoClusters) {
875  UpdateTrack(trackCandidate,bestTrackParamAtCluster1,bestTrackParamAtCluster2);
876 
877  // Printout for debuging
878  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
879  cout << "FollowTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
880  if (AliLog::GetGlobalDebugLevel() >= 3) trackCandidate.RecursiveDump();
881  }
882 
883  } else if (foundOneCluster) {
884  UpdateTrack(trackCandidate,bestTrackParamAtCluster1);
885 
886  // Printout for debuging
887  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
888  cout << "FollowTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
889  if (AliLog::GetGlobalDebugLevel() >= 3) trackCandidate.RecursiveDump();
890  }
891 
892  } else {
893  delete [] clusterCh1Used;
894  return kFALSE;
895  }
896 
897  } else if (foundOneCluster || foundTwoClusters) {
898 
899  // remove obsolete track
900  fRecTracksPtr->Remove(&trackCandidate);
901  fNRecTracks--;
902 
903  } else {
904  delete [] clusterCh1Used;
905  return kFALSE;
906  }
907 
908  delete [] clusterCh1Used;
909  return kTRUE;
910 
911 }
912 
913  //__________________________________________________________________________
914 Double_t AliMUONTrackReconstructor::TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster* cluster2,
915  AliMUONTrackParam &trackParamAtCluster2)
916 {
920 
921  // extrapolate track parameters at the z position of the second cluster (no need to extrapolate the covariances)
922  // and set pointer to cluster into trackParamAtCluster
923  trackParamAtCluster2.SetParameters(trackParamAtCluster1.GetParameters());
924  trackParamAtCluster2.SetZ(trackParamAtCluster1.GetZ());
925  trackParamAtCluster2.SetClusterPtr(cluster2);
926  if (!AliMUONTrackExtrap::ExtrapToZ(&trackParamAtCluster2, cluster2->GetZ())) return 2.*AliMUONTrack::MaxChi2();
927 
928  // Set differences between track and the 2 clusters in the bending and non bending directions
929  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
930  TMatrixD dPos(4,1);
931  dPos(0,0) = cluster1->GetX() - trackParamAtCluster1.GetNonBendingCoor();
932  dPos(1,0) = cluster1->GetY() - trackParamAtCluster1.GetBendingCoor();
933  dPos(2,0) = cluster2->GetX() - trackParamAtCluster2.GetNonBendingCoor();
934  dPos(3,0) = cluster2->GetY() - trackParamAtCluster2.GetBendingCoor();
935 
936  // Calculate the error matrix from the track parameter covariances at first cluster
937  TMatrixD error(4,4);
938  error.Zero();
939  if (trackParamAtCluster1.CovariancesExist()) {
940  // Save track parameters at first cluster
941  TMatrixD paramAtCluster1Save(trackParamAtCluster1.GetParameters());
942 
943  // Save track coordinates at second cluster
944  Double_t nonBendingCoor2 = trackParamAtCluster2.GetNonBendingCoor();
945  Double_t bendingCoor2 = trackParamAtCluster2.GetBendingCoor();
946 
947  // copy track parameters at first cluster for jacobian calculation
948  AliMUONTrackParam trackParam(trackParamAtCluster1);
949 
950  // Get the pointer to the parameter covariance matrix at first cluster
951  const TMatrixD& kParamCov = trackParam.GetCovariances();
952 
953  // Calculate the jacobian related to the transformation between track parameters
954  // at first cluster and track coordinates at the 2 cluster z-positions
955  TMatrixD jacob(4,5);
956  jacob.Zero();
957  // first derivative at the first cluster:
958  jacob(0,0) = 1.; // dx1/dx
959  jacob(1,2) = 1.; // dy1/dy
960  // first derivative at the second cluster:
961  TMatrixD dParam(5,1);
962  Double_t direction[5] = {-1.,-1.,1.,1.,-1.};
963  for (Int_t i=0; i<5; i++) {
964  // Skip jacobian calculation for parameters with no associated error
965  if (kParamCov(i,i) == 0.) continue;
966  // Small variation of parameter i only
967  for (Int_t j=0; j<5; j++) {
968  if (j==i) {
969  dParam(j,0) = TMath::Sqrt(kParamCov(i,i));
970  dParam(j,0) *= TMath::Sign(1.,direction[j]*paramAtCluster1Save(j,0)); // variation always in the same direction
971  } else dParam(j,0) = 0.;
972  }
973 
974  // Set new track parameters at first cluster
975  trackParam.SetParameters(paramAtCluster1Save);
976  trackParam.AddParameters(dParam);
977  trackParam.SetZ(cluster1->GetZ());
978 
979  // Extrapolate new track parameters to the z position of the second cluster
980  if (!AliMUONTrackExtrap::ExtrapToZ(&trackParam,cluster2->GetZ())) return 2.*AliMUONTrack::MaxChi2();
981 
982  // Calculate the jacobian
983  jacob(2,i) = (trackParam.GetNonBendingCoor() - nonBendingCoor2) / dParam(i,0); // dx2/dParami
984  jacob(3,i) = (trackParam.GetBendingCoor() - bendingCoor2 ) / dParam(i,0); // dy2/dParami
985  }
986 
987  // Calculate the error matrix
988  TMatrixD tmp(jacob,TMatrixD::kMult,kParamCov);
989  error = TMatrixD(tmp,TMatrixD::kMultTranspose,jacob);
990  }
991 
992  // Add cluster resolution to the error matrix
993  error(0,0) += cluster1->GetErrX2();
994  error(1,1) += cluster1->GetErrY2();
995  error(2,2) += cluster2->GetErrX2();
996  error(3,3) += cluster2->GetErrY2();
997 
998  // invert the error matrix for Chi2 calculation
999  if (error.Determinant() != 0) {
1000  error.Invert();
1001  } else {
1002  AliWarning(" Determinant error=0");
1003  return 2.*AliMUONTrack::MaxChi2();
1004  }
1005 
1006  // Compute the Chi2 value
1007  TMatrixD tmp2(dPos,TMatrixD::kTransposeMult,error);
1008  TMatrixD result(tmp2,TMatrixD::kMult,dPos);
1009 
1010  return result(0,0);
1011 
1012 }
1013 
1014  //__________________________________________________________________________
1016 {
1019 
1020  // Compute local chi2
1021  AliMUONVCluster* cluster = trackParamAtCluster.GetClusterPtr();
1022  Double_t deltaX = trackParamAtCluster.GetNonBendingCoor() - cluster->GetX();
1023  Double_t deltaY = trackParamAtCluster.GetBendingCoor() - cluster->GetY();
1024  Double_t localChi2 = deltaX*deltaX / cluster->GetErrX2() +
1025  deltaY*deltaY / cluster->GetErrY2();
1026 
1027  // Flag cluster as being not removable
1028  if (GetRecoParam()->RequestStation(cluster->GetChamberId()/2))
1029  trackParamAtCluster.SetRemovable(kFALSE);
1030  else trackParamAtCluster.SetRemovable(kTRUE);
1031  trackParamAtCluster.SetLocalChi2(0.); // --> Local chi2 not used
1032 
1033  // Update the chi2 of the new track
1034  track.SetGlobalChi2(track.GetGlobalChi2() + localChi2);
1035 
1036  // Update TrackParamAtCluster
1037  track.AddTrackParamAtCluster(trackParamAtCluster,*cluster);
1038 
1039 }
1040 
1041  //__________________________________________________________________________
1043 {
1046 
1047  // Update local chi2 at first cluster
1048  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
1049  Double_t deltaX = trackParamAtCluster1.GetNonBendingCoor() - cluster1->GetX();
1050  Double_t deltaY = trackParamAtCluster1.GetBendingCoor() - cluster1->GetY();
1051  Double_t localChi2AtCluster1 = deltaX*deltaX / cluster1->GetErrX2() +
1052  deltaY*deltaY / cluster1->GetErrY2();
1053  trackParamAtCluster1.SetLocalChi2(localChi2AtCluster1);
1054 
1055  // Flag first cluster as being removable
1056  trackParamAtCluster1.SetRemovable(kTRUE);
1057 
1058  // Update local chi2 at second cluster
1059  AliMUONVCluster* cluster2 = trackParamAtCluster2.GetClusterPtr();
1060  deltaX = trackParamAtCluster2.GetNonBendingCoor() - cluster2->GetX();
1061  deltaY = trackParamAtCluster2.GetBendingCoor() - cluster2->GetY();
1062  Double_t localChi2AtCluster2 = deltaX*deltaX / cluster2->GetErrX2() +
1063  deltaY*deltaY / cluster2->GetErrY2();
1064  trackParamAtCluster2.SetLocalChi2(localChi2AtCluster2);
1065 
1066  // Flag first cluster as being removable
1067  trackParamAtCluster2.SetRemovable(kTRUE);
1068 
1069  // Update the chi2 of the new track
1070  track.SetGlobalChi2(track.GetGlobalChi2() + localChi2AtCluster1 + localChi2AtCluster2);
1071 
1072  // Update TrackParamAtCluster
1073  track.AddTrackParamAtCluster(trackParamAtCluster1,*cluster1);
1074  track.AddTrackParamAtCluster(trackParamAtCluster2,*cluster2);
1075 
1076 }
1077 
1078  //__________________________________________________________________________
1079 Bool_t AliMUONTrackReconstructor::RecoverTrack(AliMUONTrack &trackCandidate, AliMUONVClusterStore& clusterStore, Int_t nextStation)
1080 {
1084  AliDebug(1,"Enter RecoverTrack");
1085 
1086  // Do not try to recover track until we have attached cluster(s) on station(1..) 3
1087  if (nextStation > 1) return kFALSE;
1088 
1089  Int_t worstClusterNumber = -1;
1090  Double_t localChi2, worstLocalChi2 = -1.;
1091 
1092  // Look for the cluster to remove
1093  for (Int_t clusterNumber = 0; clusterNumber < 2; clusterNumber++) {
1094  AliMUONTrackParam *trackParamAtCluster = (AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(clusterNumber);
1095 
1096  // check if current cluster is in the previous station
1097  if (trackParamAtCluster->GetClusterPtr()->GetChamberId()/2 != nextStation+1) break;
1098 
1099  // check if current cluster is removable
1100  if (!trackParamAtCluster->IsRemovable()) return kFALSE;
1101 
1102  // reset the current cluster as beig not removable if it is on a required station
1103  if (GetRecoParam()->RequestStation(nextStation+1)) trackParamAtCluster->SetRemovable(kFALSE);
1104 
1105  // Pick up cluster with the worst chi2
1106  localChi2 = trackParamAtCluster->GetLocalChi2();
1107  if (localChi2 > worstLocalChi2) {
1108  worstLocalChi2 = localChi2;
1109  worstClusterNumber = clusterNumber;
1110  }
1111 
1112  }
1113 
1114  // check if worst cluster found
1115  if (worstClusterNumber < 0) return kFALSE;
1116 
1117  // Remove the worst cluster
1118  trackCandidate.RemoveTrackParamAtCluster((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->UncheckedAt(worstClusterNumber));
1119 
1120  // Re-fit the track:
1121  // Do not take into account the multiple scattering to speed up the fit
1122  // Calculate the track parameter covariance matrix
1123  Fit(trackCandidate, kFALSE, kFALSE, kTRUE);
1124 
1125  // skip track if the normalized chi2 is too high
1126  if (trackCandidate.GetNormalizedChi2() > GetRecoParam()->GetSigmaCutForTracking() * GetRecoParam()->GetSigmaCutForTracking()) return kFALSE;
1127 
1128  // skip track out of limits
1129  if (!IsAcceptable(*((AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First()))) return kFALSE;
1130 
1131  // Look for new cluster(s) in next station
1132  return FollowTrackInStation(trackCandidate,clusterStore,nextStation);
1133 
1134 }
1135 
1136  //__________________________________________________________________________
1138 {
1143  AliDebug(1,"Enter SetVertexForFit");
1144 
1145  Double_t nonBendingReso2 = GetRecoParam()->GetNonBendingVertexDispersion() *
1147  Double_t bendingReso2 = GetRecoParam()->GetBendingVertexDispersion() *
1149 
1150  // add multiple scattering effets
1151  AliMUONTrackParam paramAtVertex(*((AliMUONTrackParam*)(trackCandidate.GetTrackParamAtCluster()->First())));
1152  paramAtVertex.DeleteCovariances(); // to be sure to account only for multiple scattering
1154  nonBendingReso2 = 0.;
1155  bendingReso2 = 0.;
1156  } else {
1158  const TMatrixD& kParamCov = paramAtVertex.GetCovariances();
1159  nonBendingReso2 += kParamCov(0,0);
1160  bendingReso2 += kParamCov(2,2);
1161  }
1162 
1163  // Set the vertex resolution square
1164  trackCandidate.SetVertexErrXY2(nonBendingReso2,bendingReso2);
1165 }
1166 
1167  //__________________________________________________________________________
1168 void AliMUONTrackReconstructor::Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t fitWithVertex, Bool_t calcCov)
1169 {
1174  AliDebug(1,"Enter Fit");
1175 
1176  Double_t benC, errorParam, invBenP, nonBenC, x, y;
1177  AliMUONTrackParam *trackParam;
1178  Double_t arg[1], fedm, errdef, globalChi2;
1179  Int_t npari, nparx;
1180  Int_t status, covStatus;
1181 
1182  // Instantiate gMinuit if not already done
1183  if (!gMinuit) gMinuit = new TMinuit(6);
1184  // Clear MINUIT parameters
1185  gMinuit->mncler();
1186  // Give the fitted track to MINUIT
1187  gMinuit->SetObjectFit(&track);
1188  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
1189  // Define print level
1190  arg[0] = 1;
1191  gMinuit->mnexcm("SET PRI", arg, 1, status);
1192  // Print covariance matrix
1193  gMinuit->mnexcm("SHO COV", arg, 0, status);
1194  } else {
1195  arg[0] = -1;
1196  gMinuit->mnexcm("SET PRI", arg, 1, status);
1197  }
1198  // No warnings
1199  gMinuit->mnexcm("SET NOW", arg, 0, status);
1200  // Define strategy
1201  //arg[0] = 2;
1202  //gMinuit->mnexcm("SET STR", arg, 1, status);
1203 
1204  // set flag w/wo multiple scattering according to "includeMCS"
1205  track.FitWithMCS(includeMCS);
1206  if (includeMCS) {
1207  // compute cluster weights only once
1208  if (!track.UpdateTrackParamAtCluster() || !track.ComputeClusterWeights()) {
1209  AliWarning("cannot take into account the multiple scattering effects");
1210  track.FitWithMCS(kFALSE);
1211  }
1212  }
1213 
1214  track.FitWithVertex(fitWithVertex);
1215  if (fitWithVertex) SetVertexErrXY2ForFit(track);
1216 
1217  // Set fitting function
1218  gMinuit->SetFCN(TrackChi2);
1219 
1220  // Set fitted parameters (!! The order is very important for the covariance matrix !!)
1221  // Mandatory limits to avoid NaN values of parameters
1222  trackParam = (AliMUONTrackParam*) (track.GetTrackParamAtCluster()->First());
1223  Double_t maxIBM = 1. / GetRecoParam()->GetMinBendingMomentum();
1224  gMinuit->mnparm(0, "X", trackParam->GetNonBendingCoor(), 0.03, -500.0, 500.0, status);
1225  gMinuit->mnparm(1, "NonBenS", trackParam->GetNonBendingSlope(), 0.001, -1., 1., status);
1226  gMinuit->mnparm(2, "Y", trackParam->GetBendingCoor(), 0.10, -500.0, 500.0, status);
1227  gMinuit->mnparm(3, "BenS", trackParam->GetBendingSlope(), 0.001, -1.5, 1.5, status);
1228  gMinuit->mnparm(4, "InvBenP", trackParam->GetInverseBendingMomentum(), 0.003, -maxIBM, maxIBM, status);
1229 
1230  // minimization
1231  gMinuit->mnexcm("MIGRAD", arg, 0, status);
1232 
1233  // Calculate the covariance matrix more accurately if required
1234  if (calcCov) gMinuit->mnexcm("HESSE", arg, 0, status);
1235 
1236  // get results into "invBenP", "benC", "nonBenC" ("x", "y")
1237  gMinuit->GetParameter(0, x, errorParam);
1238  trackParam->SetNonBendingCoor(x);
1239  gMinuit->GetParameter(1, nonBenC, errorParam);
1240  trackParam->SetNonBendingSlope(nonBenC);
1241  gMinuit->GetParameter(2, y, errorParam);
1242  trackParam->SetBendingCoor(y);
1243  gMinuit->GetParameter(3, benC, errorParam);
1244  trackParam->SetBendingSlope(benC);
1245  gMinuit->GetParameter(4, invBenP, errorParam);
1246  trackParam->SetInverseBendingMomentum(invBenP);
1247 
1248  // global result of the fit
1249  gMinuit->mnstat(globalChi2, fedm, errdef, npari, nparx, covStatus);
1250  track.SetGlobalChi2(globalChi2);
1251 
1252  // Get the covariance matrix if required
1253  if (calcCov) {
1254  // Covariance matrix according to HESSE status
1255  // If problem then keep only the diagonal terms (variances)
1256  Double_t matrix[5][5];
1257  for (Int_t i=0; i<5; i++) for (Int_t j=0; j<5; j++) matrix[i][j] = 0.;
1258  gMinuit->mnemat(&matrix[0][0],5);
1259  if (covStatus == 3) trackParam->SetCovariances(matrix);
1260  else trackParam->SetVariances(matrix);
1261  } else trackParam->DeleteCovariances();
1262 
1263 }
1264 
1265  //__________________________________________________________________________
1266 void TrackChi2(Int_t & /*nParam*/, Double_t * /*gradient*/, Double_t &chi2, Double_t *param, Int_t /*flag*/)
1267 {
1273 
1274  AliMUONTrack *trackBeingFitted = (AliMUONTrack*) gMinuit->GetObjectFit();
1275  AliMUONTrackParam* trackParamAtCluster = (AliMUONTrackParam*) trackBeingFitted->GetTrackParamAtCluster()->First();
1276  Double_t dX, dY;
1277  chi2 = 0.; // initialize chi2
1278 
1279  // update track parameters
1280  trackParamAtCluster->SetNonBendingCoor(param[0]);
1281  trackParamAtCluster->SetNonBendingSlope(param[1]);
1282  trackParamAtCluster->SetBendingCoor(param[2]);
1283  trackParamAtCluster->SetBendingSlope(param[3]);
1284  trackParamAtCluster->SetInverseBendingMomentum(param[4]);
1285  if (!trackBeingFitted->UpdateTrackParamAtCluster()) {
1286  chi2 = 2.*AliMUONTrack::MaxChi2();
1287  return;
1288  }
1289 
1290  // Take the vertex into account in the fit if required
1291  if (trackBeingFitted->FitWithVertex()) {
1292  Double_t nonBendingReso2,bendingReso2;
1293  trackBeingFitted->GetVertexErrXY2(nonBendingReso2,bendingReso2);
1294  AliMUONTrackParam paramAtVertex(*trackParamAtCluster);
1295  if (nonBendingReso2 != 0. && bendingReso2 != 0. && AliMUONTrackExtrap::ExtrapToZ(&paramAtVertex, 0.)) { // vextex position = (0,0,0)
1296  dX = paramAtVertex.GetNonBendingCoor();
1297  dY = paramAtVertex.GetBendingCoor();
1298  chi2 += dX * dX / nonBendingReso2 + dY * dY / bendingReso2;
1299  } else {
1300  chi2 = 2.*AliMUONTrack::MaxChi2();
1301  return;
1302  }
1303  }
1304 
1305  // compute chi2 w/wo multiple scattering
1306  chi2 += trackBeingFitted->ComputeGlobalChi2(trackBeingFitted->FitWithMCS());
1307 
1308 }
1309 
1310  //__________________________________________________________________________
1312 {
1317  AliDebug(1,"Enter ComplementTracks");
1318 
1319  Int_t chamberId, detElemId;
1320  Double_t chi2OfCluster, bestChi2OfCluster;
1321  Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForTracking() *
1323  Bool_t foundOneCluster, trackModified, hasChanged = kFALSE;
1324  AliMUONVCluster* cluster;
1325  AliMUONTrackParam *trackParam, *nextTrackParam, copyOfTrackParam, trackParamAtCluster, bestTrackParamAtCluster;
1326 
1328  while (track) {
1329  trackModified = kFALSE;
1330 
1331  trackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->First();
1332  while (trackParam) {
1333  foundOneCluster = kFALSE;
1334  bestChi2OfCluster = 2. * sigmaCut2; // 2 because 2 quantities in chi2
1335  chamberId = trackParam->GetClusterPtr()->GetChamberId();
1336  detElemId = trackParam->GetClusterPtr()->GetDetElemId();
1337 
1338  // prepare nextTrackParam before adding new cluster because of the sorting
1339  nextTrackParam = (AliMUONTrackParam*)track->GetTrackParamAtCluster()->After(trackParam);
1340 
1341  // recover track parameters from local fit and put them into a copy of trackParam
1342  copyOfTrackParam.SetZ(trackParam->GetZ());
1343  copyOfTrackParam.SetParameters(trackParam->GetSmoothParameters());
1344  copyOfTrackParam.SetCovariances(trackParam->GetSmoothCovariances());
1345 
1346  // Create iterators to loop over clusters in current chamber
1347  TIter nextInCh(clusterStore.CreateChamberIterator(chamberId,chamberId));
1348 
1349  // look for one second candidate in the same chamber
1350  while ( ( cluster = static_cast<AliMUONVCluster*>(nextInCh()) ) ) {
1351 
1352  // look for a cluster in another detection element
1353  if (cluster->GetDetElemId() == detElemId) continue;
1354 
1355  // try to add the current cluster fast
1356  if (!TryOneClusterFast(copyOfTrackParam, cluster)) continue;
1357 
1358  // try to add the current cluster accurately
1359  chi2OfCluster = TryOneCluster(copyOfTrackParam, cluster, trackParamAtCluster);
1360 
1361  // if better chi2 then prepare to add this cluster to the track
1362  if (chi2OfCluster < bestChi2OfCluster) {
1363  bestChi2OfCluster = chi2OfCluster;
1364  bestTrackParamAtCluster = trackParamAtCluster;
1365  foundOneCluster = kTRUE;
1366  }
1367 
1368  }
1369 
1370  // add new cluster if any
1371  if (foundOneCluster) {
1372 
1373  // Printout for debuging
1374  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1375  cout << "ComplementTracks: found one cluster in chamber(1..): " << chamberId+1 << endl;
1376  bestTrackParamAtCluster.GetClusterPtr()->Print();
1377  cout<<endl<<"Track parameters and covariances at cluster:"<<endl;
1378  bestTrackParamAtCluster.GetParameters().Print();
1379  bestTrackParamAtCluster.GetCovariances().Print();
1380  }
1381 
1382  trackParam->SetRemovable(kTRUE);
1383  bestTrackParamAtCluster.SetRemovable(kTRUE);
1384  track->AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
1385  trackModified = kTRUE;
1386  hasChanged = kTRUE;
1387  }
1388 
1389  trackParam = nextTrackParam;
1390  }
1391 
1392  // re-fit track parameters if needed
1393  if (trackModified) Fit(*track, kTRUE, kFALSE, kTRUE);
1394 
1395  track = (AliMUONTrack*) fRecTracksPtr->After(track);
1396  }
1397 
1398  return hasChanged;
1399 
1400 }
1401 
1402  //__________________________________________________________________________
1404 {
1407  AliDebug(1,"Enter ImproveTrack");
1408 
1409  Double_t localChi2, worstLocalChi2;
1410  AliMUONTrackParam *trackParamAtCluster, *worstTrackParamAtCluster;
1411  Double_t sigmaCut2 = GetRecoParam()->GetSigmaCutForImprovement() *
1413 
1414  while (!track.IsImproved()) {
1415 
1416  // identify removable clusters
1417  track.TagRemovableClusters(GetRecoParam()->RequestedStationMask());
1418 
1419  // Update track parameters and covariances
1420  if (!track.UpdateCovTrackParamAtCluster()) {
1421  AliWarning("unable to update track parameters and covariances --> stop improvement");
1422  break;
1423  }
1424 
1425  // Compute local chi2 of each clusters
1426  track.ComputeLocalChi2(kTRUE);
1427 
1428  // Look for the cluster to remove
1429  worstTrackParamAtCluster = NULL;
1430  worstLocalChi2 = 0.;
1431  trackParamAtCluster = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First();
1432  while (trackParamAtCluster) {
1433 
1434  // Pick up cluster with the worst chi2
1435  localChi2 = trackParamAtCluster->GetLocalChi2();
1436  if (localChi2 > worstLocalChi2) {
1437  worstLocalChi2 = localChi2;
1438  worstTrackParamAtCluster = trackParamAtCluster;
1439  }
1440 
1441  trackParamAtCluster = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->After(trackParamAtCluster);
1442  }
1443 
1444  // Check if worst cluster found
1445  if (!worstTrackParamAtCluster) {
1446  AliWarning("Bad local chi2 values?");
1447  break;
1448  }
1449 
1450  // Check whether the worst chi2 is under requirement or not
1451  if (worstLocalChi2 < 2. * sigmaCut2) { // 2 because 2 quantities in chi2
1452  track.SetImproved(kTRUE);
1453  break;
1454  }
1455 
1456  // if the worst cluster is not removable then stop improvement
1457  if (!worstTrackParamAtCluster->IsRemovable()) break;
1458 
1459  // Remove the worst cluster
1460  track.RemoveTrackParamAtCluster(worstTrackParamAtCluster);
1461 
1462  // Re-fit the track:
1463  // Take into account the multiple scattering
1464  // Calculate the track parameter covariance matrix
1465  Fit(track, kTRUE, kFALSE, kTRUE);
1466 
1467  // Printout for debuging
1468  if ((AliLog::GetDebugLevel("MUON","AliMUONTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1469  cout << "ImproveTracks: track " << fRecTracksPtr->IndexOf(&track)+1 << " improved " << endl;
1470  }
1471 
1472  }
1473 
1474 }
1475 
1476  //__________________________________________________________________________
1478 {
1481  AliDebug(1,"Enter FinalizeTrack");
1482  if (!track.IsImproved() && !track.UpdateCovTrackParamAtCluster()) {
1483  AliWarning("finalization failed due to extrapolation problem");
1484  return kFALSE;
1485  }
1486  return kTRUE;
1487 }
1488 
1489  //__________________________________________________________________________
1491 {
1493 
1494  // check validity of the track
1495  if (track.GetNClusters() < 3) {
1496  AliWarning("the track does not contain enough clusters --> unable to refit");
1497  return kFALSE;
1498  }
1499 
1500  // reset the seed (i.e. parameters at first cluster) before fitting
1501  AliMUONTrackParam* firstTrackParam = (AliMUONTrackParam*) track.GetTrackParamAtCluster()->First();
1502  if (firstTrackParam->GetInverseBendingMomentum() == 0.) {
1503  AliWarning("track parameters at first chamber are not initialized --> unable to refit");
1504  return kFALSE;
1505  }
1506 
1507  // compute track parameters at each cluster from parameters at the first one
1508  // necessary to compute multiple scattering effect during refitting
1509  if (!track.UpdateTrackParamAtCluster()) {
1510  AliWarning("bad track refitting due to extrapolation failure");
1511  return kFALSE;
1512  }
1513 
1514  // Re-fit the track:
1515  // Take into account the multiple scattering
1516  // Calculate the track parameter covariance matrix
1517  Fit(track, kTRUE, kFALSE, kTRUE);
1518 
1519  // Improve the reconstructed tracks if required
1520  track.SetImproved(kFALSE);
1521  if (enableImprovement && GetRecoParam()->ImproveTracks()) ImproveTrack(track);
1522 
1523  // Fill AliMUONTrack data members
1524  if (track.GetGlobalChi2() < AliMUONTrack::MaxChi2()) return FinalizeTrack(track);
1525  else {
1526  AliWarning("track not finalized due to extrapolation failure");
1527  return kFALSE;
1528  }
1529 
1530 }
1531 
void AskForNewClustersInStation(const AliMUONTrackParam &trackParam, AliMUONVClusterStore &clusterStore, Int_t station)
static Double_t AbsZEnd()
Return z-position of absorber end.
Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore &clusterStore, Int_t nextStation)
void SetSmoothParameters(const TMatrixD &parameters)
Virtual class for the MUON track reconstruction.
void RemoveTrackParamAtCluster(AliMUONTrackParam *trackParam)
Int_t GetNClusters() const
return the number of clusters attached to the track
Definition: AliMUONTrack.h:46
virtual Int_t Clusterize(Int_t chamberId, AliMUONVClusterStore &clusterStore, const AliMpArea &area, const AliMUONRecoParam *recoParam=0x0)=0
Find and add clusters from a given region of a given chamber to the store.
Double_t GetLocalChi2() const
return the local chi2 of the associated cluster with respect to the track
virtual Bool_t FinalizeTrack(AliMUONTrack &track)
Finalize the given track.
Double_t GetSigmaCutForTracking() const
return the cut in sigma to apply on cluster (local chi2) and track (global chi2) during tracking ...
virtual Double_t GetZ() const =0
Return coordinate Z (cm)
Bool_t FollowTrackInStation(AliMUONTrack &trackCandidate, AliMUONVClusterStore &clusterStore, Int_t nextStation)
const TMatrixD & GetSmoothCovariances() const
void SetVertexErrXY2(Double_t nonBendingErr2, Double_t bendingErr2)
set the vertex resolution square used during the tracking procedure
Definition: AliMUONTrack.h:56
Double_t GetBendingCoor() const
return bending coordinate (cm)
Double_t TryOneCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster *cluster, AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator=kFALSE)
const TMatrixD & GetParameters() const
return track parameters
Top container class for geometry transformations.
void RemoveUsedSegments(TClonesArray &segments)
Interface of a cluster finder for combined tracking.
Bool_t CovariancesExist() const
return kTRUE if the covariance matrix exist, kFALSE if not
Bool_t FitWithVertex() const
return kTrue if the vertex must be used to constrain the fit, kFalse if not
Definition: AliMUONTrack.h:49
virtual Int_t GetSize() const =0
The number of objects stored.
Double_t GetZ() const
return Z coordinate (cm)
static void ExtrapToVertexUncorrected(AliMUONTrackParam *trackParam, Double_t zVtx)
A rectangle area positioned in plane..
Definition: AliMpArea.h:20
Track parameters in ALICE dimuon spectrometer.
virtual void ImproveTrack(AliMUONTrack &track)
Improve the given reconstructed track.
Double_t GetNormalizedChi2() const
Class with MUON reconstruction parameters.
Bool_t IsAcceptable(AliMUONTrackParam &trackParam)
virtual Double_t GetErrX2() const =0
Return resolution**2 (cm**2) on coordinate X.
AliTPCfastTrack * track
void SetNonBendingCoor(Double_t nonBendingCoor)
set non bending coordinate (cm)
static Bool_t ExtrapToZ(AliMUONTrackParam *trackParam, Double_t zEnd)
virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore &clusterStore)
Make track candidates from clusters in stations(1..) 4 and 5.
void SetLocalChi2(Double_t chi2)
set the local chi2 of the associated cluster with respect to the track
void AddParameters(const TMatrixD &parameters)
add track parameters
void Fit(AliMUONTrack &track, Bool_t includeMCS, Bool_t fitWithVertex, Bool_t calcCov)
Double_t TryTwoClusters(const AliMUONTrackParam &trackParamAtCluster, AliMUONVCluster *cluster2, AliMUONTrackParam &trackParamAtCluster2)
Bool_t TryOneClusterFast(const AliMUONTrackParam &trackParam, const AliMUONVCluster *cluster)
Bool_t ComputeLocalChi2(Bool_t accountForMCS)
void AskForNewClustersInChamber(const AliMUONTrackParam &trackParam, AliMUONVClusterStore &clusterStore, Int_t chamber)
Double_t GetInverseBendingMomentum() const
return inverse bending momentum (GeV/c ** -1) times the charge (assumed forward motion) ...
Double_t GetBendingVertexDispersion() const
return the vertex dispersion (cm) in bending plane
void SetVariances(const Double_t matrix[5][5])
ClassImp(TPCGenInfo)
Definition: AliTPCCmpNG.C:254
Bool_t UpdateCovTrackParamAtCluster()
void dY()
Definition: CalibAlign.C:547
const AliMUONRecoParam * GetRecoParam() const
Return reco parameters.
Int_t GetMaxTrackCandidates() const
Get the maximum number of track candidates above which the tracking abort.
virtual void Print(Option_t *option="") const
void UpdateTrack(AliMUONTrack &track, AliMUONTrackParam &trackParamAtCluster)
Double_t GetBendingSlope() const
return bending slope (cm ** -1)
Double_t ComputeGlobalChi2(Bool_t accountForMCS)
void SetSmoothCovariances(const TMatrixD &covariances)
void SetBendingSlope(Double_t bendingSlope)
set bending slope (cm ** -1)
Double_t chi2
Definition: AnalyzeLaser.C:7
abstract base class for clusters
static Bool_t ExtrapToZCov(AliMUONTrackParam *trackParam, Double_t zEnd, Bool_t updatePropagator=kFALSE)
AliMUONVClusterServer * fClusterServer
reference to our cluster server
void SetImproved(Bool_t improved)
set the flag telling whether the track has been improved or not
Definition: AliMUONTrack.h:76
Bool_t FitWithMCS() const
return kTrue if the multiple scattering must be accounted for in the fit, kFalse if not ...
Definition: AliMUONTrack.h:60
Double_t GetGlobalChi2() const
return the minimum value of the function minimized by the fit
Definition: AliMUONTrack.h:69
Bool_t RecoverTrack(AliMUONTrack &track, AliMUONVClusterStore &clusterStore, Int_t nextStation)
void SetClusterPtr(AliMUONVCluster *cluster, Bool_t owner=kFALSE)
Bool_t FollowTrackInChamber(AliMUONTrack &trackCandidate, AliMUONVClusterStore &clusterStore, Int_t nextChamber)
void TrackChi2(Int_t &nParam, Double_t *gradient, Double_t &chi2, Double_t *param, Int_t flag)
Bool_t FollowLinearTrackInChamber(AliMUONTrack &trackCandidate, const AliMUONVClusterStore &clusterStore, Int_t nextChamber)
Bool_t UpdateTrackParamAtCluster()
void AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy=kFALSE)
const TMatrixD & GetSmoothParameters() const
Bool_t IsRemovable() const
return kTRUE if the associated cluster can be removed from the track it belongs to ...
static void AddMCSEffect(AliMUONTrackParam *param, Double_t dZ, Double_t x0)
Double_t GetNonBendingVertexDispersion() const
return the vertex dispersion (cm) in non bending plane
TClonesArray * MakeSegmentsBetweenChambers(const AliMUONVClusterStore &clusterStore, Int_t ch1, Int_t ch2)
Interface of a cluster container.
virtual Bool_t FollowTracks(AliMUONVClusterStore &clusterStore)
Follow tracks in stations(1..) 3, 2 and 1.
virtual TIterator * CreateChamberIterator(Int_t firstChamberId, Int_t lastChamberId) const =0
Return an iterator to loop over the store in the given chamber range.
void SetNonBendingSlope(Double_t nonBendingSlope)
set non bending slope (cm ** -1)
void GetVertexErrXY2(Double_t &nonBendingErr2, Double_t &bendingErr2) const
return the vertex resolution square used during the tracking procedure
Definition: AliMUONTrack.h:53
virtual Double_t GetErrY2() const =0
Return resolution**2 (cm**2) on coordinate Y.
virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore &clusterStore)
Make extra track candidates from clusters in stations(1..) 4 and 5.
void SetVertexErrXY2ForFit(AliMUONTrack &trackCandidate)
void SetParameters(const TMatrixD &parameters)
set track parameters
static Int_t GetChamberId(UInt_t uniqueID)
Return chamber id (0..), part of the uniqueID.
void SetInverseBendingMomentum(Double_t inverseBendingMomentum)
set inverse bending momentum (GeV/c ** -1) times the charge (assumed forward motion) ...
virtual Double_t GetY() const =0
Return coordinate Y (cm)
void MakeTrackCandidatesFast(Bool_t flag)
switch on/off the fast building of track candidates (assuming linear propagation between stations 4 a...
virtual Bool_t RefitTrack(AliMUONTrack &track, Bool_t enableImprovement=kTRUE)
Re-fit the given track.
void SetBendingCoor(Double_t bendingCoor)
set bending coordinate (cm)
static Float_t * DefaultChamberZ()
Return pointer to array of positions.
void RequestStation(Int_t iSt, Bool_t flag)
request or not at least one cluster in the station to validate the track
Double_t GetNonBendingCoor() const
return non bending coordinate (cm)
void RecoverTracks(Bool_t flag)
switch on/off the recovering of tracks being lost during reconstruction
void SetRemovable(Bool_t removable)
set the flag telling whether the associated cluster can be removed from the track it belongs to or no...
AliMUONVCluster * GetClusterPtr() const
get pointeur to associated cluster
Int_t fNRecTracks
number of reconstructed tracks
static Double_t ChamberThicknessInX0(Int_t chId)
Return chamber thickness in X0.
static Int_t GetDetElemId(UInt_t uniqueID)
Return detection element id, part of the uniqueID.
Standard class for the MUON track reconstruction.
virtual Double_t GetX() const =0
Return coordinate X (cm)
virtual Bool_t ComplementTracks(const AliMUONVClusterStore &clusterStore)
Complement the reconstructed tracks.
void RecursiveDump(void) const
Reconstructed track in ALICE dimuon spectrometer.
Definition: AliMUONTrack.h:24
Bool_t IsImproved() const
return kTRUE if the track has been improved
Definition: AliMUONTrack.h:74
Double_t GetSigmaCutForImprovement() const
return the cut in sigma to apply on cluster (local chi2) during track improvement ...
void SetCovariances(const TMatrixD &covariances)
Double_t GetMinBendingMomentum() const
return the minimum value (GeV/c) of momentum in bending plane
void SetZ(Double_t z)
set Z coordinate (cm)
const TMatrixD & GetCovariances() const
TClonesArray * fRecTracksPtr
pointer to array of reconstructed tracks
The equivalent of a std::pair<TObject*,TObject*> ;-)
void TagRemovableClusters(UInt_t requestedStationMask)
static Double_t MaxChi2()
return the maximum chi2 above which the track can be considered as abnormal (due to extrapolation fai...
Definition: AliMUONTrack.h:144
TObjArray * GetTrackParamAtCluster() const
Bool_t ComputeClusterWeights(TMatrixD *mcsCovariances=0)
void SetGlobalChi2(Double_t chi2)
set the minimum value of the function minimized by the fit
Definition: AliMUONTrack.h:71
Double_t GetNonBendingSlope() const
return non bending slope (cm ** -1)