AliRoot Core  a565103 (a565103)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliMUONVTrackReconstructor.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 //-----------------------------------------------------------------------------
56 //-----------------------------------------------------------------------------
57 
59 
60 #include "AliMUONConstants.h"
61 #include "AliMUONObjectPair.h"
62 #include "AliMUONTriggerTrack.h"
63 #include "AliMUONTriggerCircuit.h"
64 #include "AliMUONLocalTrigger.h"
65 #include "AliMUONGlobalTrigger.h"
66 #include "AliMUONTrack.h"
67 #include "AliMUONTrackParam.h"
68 #include "AliMUONTrackExtrap.h"
69 #include "AliMUONTrackHitPattern.h"
70 #include "AliMUONVTrackStore.h"
71 #include "AliMUONVClusterStore.h"
72 #include "AliMUONVCluster.h"
73 #include "AliMUONVClusterServer.h"
74 #include "AliMUONVTriggerStore.h"
76 #include "AliMUONRecoParam.h"
78 #include "AliMUONVDigit.h"
79 
80 #include "AliMpDEManager.h"
81 #include "AliMpArea.h"
82 
83 #include "AliMpDDLStore.h"
84 #include "AliMpVSegmentation.h"
85 #include "AliMpSegmentation.h"
86 #include "AliMpPad.h"
87 #include "AliMpDetElement.h"
88 #include "AliMpCathodType.h"
89 
90 #include "AliLog.h"
91 #include "AliCodeTimer.h"
92 #include "AliTracker.h"
93 
94 #include <TClonesArray.h>
95 #include <TMath.h>
96 #include <TMatrixD.h>
97 #include <TVector2.h>
98 
99 #include <Riostream.h>
100 
101 using std::cout;
102 using std::endl;
104 ClassImp(AliMUONVTrackReconstructor) // Class implementation in ROOT context
106 
107  //__________________________________________________________________________
109  AliMUONVClusterServer* clusterServer,
110  const AliMUONGeometryTransformer* transformer)
111 : TObject(),
112 fRecTracksPtr(0x0),
113 fNRecTracks(0),
114 fClusterServer(clusterServer),
115 fkRecoParam(recoParam),
116 fkTransformer(transformer),
117 fMaxMCSAngle2(0x0)
118 {
121 
122  // Memory allocation for the TClonesArray of reconstructed tracks
123  fRecTracksPtr = new TClonesArray("AliMUONTrack", 100);
124 
125  // set the magnetic field for track extrapolations
127 
128  // set the maximum MCS angle in chamber from the minimum acceptable momentum
129  AliMUONTrackParam param;
130  Double_t inverseBendingP = (GetRecoParam()->GetMinBendingMomentum() > 0.) ? 1./GetRecoParam()->GetMinBendingMomentum() : 1.;
131  param.SetInverseBendingMomentum(inverseBendingP);
132  fMaxMCSAngle2 = new Double_t [AliMUONConstants::NTrackingCh()];
133  for (Int_t iCh=0; iCh<AliMUONConstants::NTrackingCh(); iCh++)
134  fMaxMCSAngle2[iCh] = AliMUONTrackExtrap::GetMCSAngle2(param, AliMUONConstants::ChamberThicknessInX0(iCh), 1.);
135 
136 }
137 
138  //__________________________________________________________________________
140 {
142  delete fRecTracksPtr;
143  delete[] fMaxMCSAngle2;
144 }
145 
146  //__________________________________________________________________________
148 {
150  if (fRecTracksPtr) fRecTracksPtr->Clear("C");
151  fNRecTracks = 0;
152  return;
153 }
154 
155  //__________________________________________________________________________
157 {
159  AliDebug(1,"");
160  AliCodeTimerAuto("",0);
161 
162  // Reset array of tracks
163  ResetTracks();
164 
165  // Look for candidates from clusters in stations(1..) 4 and 5 (abort in case of failure)
166  if (!MakeTrackCandidates(clusterStore)) return;
167 
168  // Look for extra candidates from clusters in stations(1..) 4 and 5 (abort in case of failure)
170  if (!MakeMoreTrackCandidates(clusterStore)) return;
171  }
172 
173  // Stop tracking if no candidate found
174  if (fRecTracksPtr->GetEntriesFast() == 0) return;
175 
176  // Follow tracks in stations(1..) 3, 2 and 1 (abort in case of failure)
177  if (!FollowTracks(clusterStore)) return;
178 
179  // Complement the reconstructed tracks
180  if (GetRecoParam()->ComplementTracks()) {
181  if (ComplementTracks(clusterStore)) RemoveIdenticalTracks();
182  }
183 
184  // Improve the reconstructed tracks
186 
187  // Remove connected tracks
188  RemoveConnectedTracks(3, 4, kFALSE);
189  RemoveConnectedTracks(2, 2, kFALSE);
190  if (GetRecoParam()->RemoveConnectedTracksInSt12()) RemoveConnectedTracks(0, 1, kFALSE);
191 
192  // Fill AliMUONTrack data members
193  Finalize();
194  if (!GetRecoParam()->RemoveConnectedTracksInSt12()) TagConnectedTracks(0, 1, kTRUE);
195 
196  // Make sure there is no bad track left
197  RemoveBadTracks();
198 
199  // Refit the reconstructed tracks with a different resolution for mono-cathod clusters
201 
202  // Add tracks to MUON data container
203  for (Int_t i=0; i<fNRecTracks; ++i)
204  {
206  track->SetUniqueID(i+1);
207  trackStore.Add(*track);
208  }
209 
210 }
211 
212 //__________________________________________________________________________
214 {
216 
217  const TMatrixD& kParamCov = trackParam.GetCovariances();
218  Int_t chamber = trackParam.GetClusterPtr()->GetChamberId();
219  Double_t z = trackParam.GetZ();
221 
222  // MCS dipersion
223  Double_t angleMCS2 = 0.;
224  Double_t impactMCS2 = 0.;
225  if (AliMUONTrackExtrap::IsFieldON() && chamber < 6) {
226 
227  // track momentum is known
228  for (Int_t iCh=0; iCh<=chamber; iCh++) {
229  Double_t localMCS2 = AliMUONTrackExtrap::GetMCSAngle2(trackParam, AliMUONConstants::ChamberThicknessInX0(iCh), 1.);
230  angleMCS2 += localMCS2;
231  impactMCS2 += AliMUONConstants::DefaultChamberZ(chamber) * AliMUONConstants::DefaultChamberZ(chamber) * localMCS2;
232  }
233 
234  } else {
235 
236  // track momentum is unknown
237  for (Int_t iCh=0; iCh<=chamber; iCh++) {
238  angleMCS2 += fMaxMCSAngle2[iCh];
240  }
241 
242  }
243 
244  // ------ track selection in non bending direction ------
245  if (GetRecoParam()->SelectOnTrackSlope()) {
246 
247  // check if non bending slope is within tolerances
248  Double_t nonBendingSlopeErr = TMath::Sqrt(kParamCov(1,1) + angleMCS2);
249  if ((TMath::Abs(trackParam.GetNonBendingSlope()) - sigmaCut * nonBendingSlopeErr) > GetRecoParam()->GetMaxNonBendingSlope()) return kFALSE;
250 
251  } else {
252 
253  // or check if non bending impact parameter is within tolerances
254  Double_t nonBendingImpactParam = TMath::Abs(trackParam.GetNonBendingCoor() - z * trackParam.GetNonBendingSlope());
255  Double_t nonBendingImpactParamErr = TMath::Sqrt(kParamCov(0,0) + z * z * kParamCov(1,1) - 2. * z * kParamCov(0,1) + impactMCS2);
256  if ((nonBendingImpactParam - sigmaCut * nonBendingImpactParamErr) > (3. * GetRecoParam()->GetNonBendingVertexDispersion())) return kFALSE;
257 
258  }
259 
260  // ------ track selection in bending direction ------
261  if (AliMUONTrackExtrap::IsFieldON()) { // depending whether the field is ON or OFF
262 
263  // check if bending momentum is within tolerances
264  Double_t bendingMomentum = TMath::Abs(1. / trackParam.GetInverseBendingMomentum());
265  Double_t bendingMomentumErr = TMath::Sqrt(kParamCov(4,4)) * bendingMomentum * bendingMomentum;
266  if (chamber < 6 && (bendingMomentum + sigmaCut * bendingMomentumErr) < GetRecoParam()->GetMinBendingMomentum()) return kFALSE;
267  else if ((bendingMomentum + 3. * bendingMomentumErr) < GetRecoParam()->GetMinBendingMomentum()) return kFALSE;
268 
269  } else {
270 
271  if (GetRecoParam()->SelectOnTrackSlope()) {
272 
273  // check if bending slope is within tolerances
274  Double_t bendingSlopeErr = TMath::Sqrt(kParamCov(3,3) + angleMCS2);
275  if ((TMath::Abs(trackParam.GetBendingSlope()) - sigmaCut * bendingSlopeErr) > GetRecoParam()->GetMaxBendingSlope()) return kFALSE;
276 
277  } else {
278 
279  // or check if bending impact parameter is within tolerances
280  Double_t bendingImpactParam = TMath::Abs(trackParam.GetBendingCoor() - z * trackParam.GetBendingSlope());
281  Double_t bendingImpactParamErr = TMath::Sqrt(kParamCov(2,2) + z * z * kParamCov(3,3) - 2. * z * kParamCov(2,3) + impactMCS2);
282  if ((bendingImpactParam - sigmaCut * bendingImpactParamErr) > (3. * GetRecoParam()->GetBendingVertexDispersion())) return kFALSE;
283 
284  }
285 
286  }
287 
288  return kTRUE;
289 
290 }
291 
292 //__________________________________________________________________________
293 TClonesArray* AliMUONVTrackReconstructor::MakeSegmentsBetweenChambers(const AliMUONVClusterStore& clusterStore, Int_t ch1, Int_t ch2)
294 {
297  AliDebug(1,Form("Enter MakeSegmentsBetweenChambers (1..) %d-%d", ch1+1, ch2+1));
298  AliCodeTimerAuto("",0);
299 
300  AliMUONVCluster *cluster1, *cluster2;
301  AliMUONObjectPair *segment;
302  Double_t z1 = 0., z2 = 0., dZ = 0.;
303  Double_t nonBendingSlope = 0., nonBendingSlopeErr = 0., nonBendingImpactParam = 0., nonBendingImpactParamErr = 0.;
304  Double_t bendingSlope = 0., bendingSlopeErr = 0., bendingImpactParam = 0., bendingImpactParamErr = 0., bendingImpactParamErr2 = 0.;
305  Double_t bendingMomentum = 0., bendingMomentumErr = 0.;
306  Double_t bendingVertexDispersion2 = GetRecoParam()->GetBendingVertexDispersion() * GetRecoParam()->GetBendingVertexDispersion();
307  Double_t angleMCS2 = 0.; // maximum angular dispersion**2 due to MCS in chamber
308  Double_t impactMCS2 = 0.; // maximum impact parameter dispersion**2 due to MCS in chamber
309  for (Int_t iCh=0; iCh<=ch1; iCh++) {
310  angleMCS2 += fMaxMCSAngle2[iCh];
312  }
314 
315  // Create iterators to loop over clusters in both chambers
316  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
317  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
318 
319  // list of segments
320  static TClonesArray *segments = new TClonesArray("AliMUONObjectPair", 100);
321  segments->Clear("C");
322 
323  // Loop over clusters in the first chamber of the station
324  while ( ( cluster1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
325  z1 = cluster1->GetZ();
326 
327  // reset cluster iterator of chamber 2
328  nextInCh2.Reset();
329 
330  // Loop over clusters in the second chamber of the station
331  while ( ( cluster2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
332  z2 = cluster2->GetZ();
333  dZ = z1 - z2;
334 
335  // ------ track selection in non bending direction ------
336  nonBendingSlope = (cluster1->GetX() - cluster2->GetX()) / dZ;
337  if (GetRecoParam()->SelectOnTrackSlope()) {
338 
339  // check if non bending slope is within tolerances
340  nonBendingSlopeErr = TMath::Sqrt((cluster1->GetErrX2() + cluster2->GetErrX2()) / dZ / dZ + angleMCS2);
341  if ((TMath::Abs(nonBendingSlope) - sigmaCut * nonBendingSlopeErr) > GetRecoParam()->GetMaxNonBendingSlope()) continue;
342 
343  } else {
344 
345  // or check if non bending impact parameter is within tolerances
346  nonBendingImpactParam = TMath::Abs(cluster1->GetX() - cluster1->GetZ() * nonBendingSlope);
347  nonBendingImpactParamErr = TMath::Sqrt((z1 * z1 * cluster2->GetErrX2() + z2 * z2 * cluster1->GetErrX2()) / dZ / dZ + impactMCS2);
348  if ((nonBendingImpactParam - sigmaCut * nonBendingImpactParamErr) > (3. * GetRecoParam()->GetNonBendingVertexDispersion())) continue;
349 
350  }
351 
352  // ------ track selection in bending direction ------
353  bendingSlope = (cluster1->GetY() - cluster2->GetY()) / dZ;
354  if (AliMUONTrackExtrap::IsFieldON()) { // depending whether the field is ON or OFF
355 
356  // check if bending momentum is within tolerances
357  bendingImpactParam = cluster1->GetY() - cluster1->GetZ() * bendingSlope;
358  bendingImpactParamErr2 = (z1 * z1 * cluster2->GetErrY2() + z2 * z2 * cluster1->GetErrY2()) / dZ / dZ + impactMCS2;
359  bendingMomentum = TMath::Abs(AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpactParam));
360  bendingMomentumErr = TMath::Sqrt((bendingVertexDispersion2 + bendingImpactParamErr2) /
361  bendingImpactParam / bendingImpactParam + 0.01) * bendingMomentum;
362  if ((bendingMomentum + 3. * bendingMomentumErr) < GetRecoParam()->GetMinBendingMomentum()) continue;
363 
364  } else {
365 
366  if (GetRecoParam()->SelectOnTrackSlope()) {
367 
368  // check if bending slope is within tolerances
369  bendingSlopeErr = TMath::Sqrt((cluster1->GetErrY2() + cluster2->GetErrY2()) / dZ / dZ + angleMCS2);
370  if ((TMath::Abs(bendingSlope) - sigmaCut * bendingSlopeErr) > GetRecoParam()->GetMaxBendingSlope()) continue;
371 
372  } else {
373 
374  // or check if bending impact parameter is within tolerances
375  bendingImpactParam = TMath::Abs(cluster1->GetY() - cluster1->GetZ() * bendingSlope);
376  bendingImpactParamErr = TMath::Sqrt((z1 * z1 * cluster2->GetErrY2() + z2 * z2 * cluster1->GetErrY2()) / dZ / dZ + impactMCS2);
377  if ((bendingImpactParam - sigmaCut * bendingImpactParamErr) > (3. * GetRecoParam()->GetBendingVertexDispersion())) continue;
378 
379  }
380 
381  }
382 
383  // make new segment
384  segment = new ((*segments)[segments->GetLast()+1]) AliMUONObjectPair(cluster1, cluster2, kFALSE, kFALSE);
385 
386  // Printout for debug
387  if (AliLog::GetGlobalDebugLevel() > 1) {
388  cout << "segmentIndex(0...): " << segments->GetLast() << endl;
389  segment->Dump();
390  cout << "Cluster in first chamber" << endl;
391  cluster1->Print();
392  cout << "Cluster in second chamber" << endl;
393  cluster2->Print();
394  }
395 
396  }
397 
398  }
399 
400  // Printout for debug
401  AliDebug(1,Form("chambers%d-%d: NSegments = %d ", ch1+1, ch2+1, segments->GetEntriesFast()));
402 
403  return segments;
404 }
405 
406  //__________________________________________________________________________
408 {
410  AliDebug(1,"Enter RemoveUsedSegments");
411  Int_t nSegments = segments.GetEntriesFast();
412  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
413  AliMUONObjectPair *segment;
415  AliMUONVCluster *cluster, *cluster1, *cluster2;
416  Bool_t foundCluster1, foundCluster2, removeSegment;
417 
418  // Loop over segments
419  for (Int_t iSegment=0; iSegment<nSegments; iSegment++) {
420  segment = (AliMUONObjectPair*) segments.UncheckedAt(iSegment);
421 
422  cluster1 = (AliMUONVCluster*) segment->First();
423  cluster2 = (AliMUONVCluster*) segment->Second();
424  removeSegment = kFALSE;
425 
426  // Loop over tracks
427  for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
428  track = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack);
429 
430  // skip empty slot
431  if (!track) continue;
432 
433  foundCluster1 = kFALSE;
434  foundCluster2 = kFALSE;
435 
436  // Loop over clusters
437  Int_t nClusters = track->GetNClusters();
438  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
439  cluster = ((AliMUONTrackParam*) track->GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
440 
441  // check if both clusters are in that track
442  if (cluster == cluster1) foundCluster1 = kTRUE;
443  else if (cluster == cluster2) foundCluster2 = kTRUE;
444 
445  if (foundCluster1 && foundCluster2) {
446  removeSegment = kTRUE;
447  break;
448  }
449 
450  }
451 
452  if (removeSegment) break;
453 
454  }
455 
456  if (removeSegment) segments.RemoveAt(iSegment);
457 
458  }
459 
460  segments.Compress();
461 
462  // Printout for debug
463  AliDebug(1,Form("NSegments = %d ", segments.GetEntriesFast()));
464 }
465 
466  //__________________________________________________________________________
468 {
472  AliMUONTrack *track1, *track2;
473  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
474  Int_t clustersInCommon, nClusters1, nClusters2;
475  // Loop over first track of the pair
476  for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
477  track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
478  // skip empty slot
479  if (!track1) continue;
480  nClusters1 = track1->GetNClusters();
481  // Loop over second track of the pair
482  for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
483  track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
484  // skip empty slot
485  if (!track2) continue;
486  nClusters2 = track2->GetNClusters();
487  // number of clusters in common between two tracks
488  clustersInCommon = track1->ClustersInCommon(track2);
489  // check for identical tracks
490  if ((clustersInCommon == nClusters1) || (clustersInCommon == nClusters2)) {
491  // decide which track to remove
492  if (nClusters2 > nClusters1) {
493  // remove track1 and continue the first loop with the track next to track1
494  fRecTracksPtr->RemoveAt(iTrack1);
495  fNRecTracks--;
496  break;
497  } else {
498  // remove track2 and continue the second loop with the track next to track2
499  fRecTracksPtr->RemoveAt(iTrack2);
500  fNRecTracks--;
501  }
502  }
503  } // track2
504  } // track1
505  fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
506 }
507 
508  //__________________________________________________________________________
510 {
516  AliMUONTrack *track1, *track2;
517  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
518  Int_t clustersInCommon2, nClusters1, nClusters2;
519  // Loop over first track of the pair
520  for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
521  track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
522  // skip empty slot
523  if (!track1) continue;
524  nClusters1 = track1->GetNClusters();
525  // Loop over second track of the pair
526  for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
527  track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
528  // skip empty slot
529  if (!track2) continue;
530  nClusters2 = track2->GetNClusters();
531  // number of clusters in common between two tracks
532  clustersInCommon2 = 2 * track1->ClustersInCommon(track2);
533  // check for identical tracks
534  if (clustersInCommon2 > nClusters1 || clustersInCommon2 > nClusters2) {
535  // decide which track to remove
536  if ((nClusters1 > nClusters2) || ((nClusters1 == nClusters2) && (track1->GetGlobalChi2() <= track2->GetGlobalChi2()))) {
537  // remove track2 and continue the second loop with the track next to track2
538  fRecTracksPtr->RemoveAt(iTrack2);
539  fNRecTracks--;
540  } else {
541  // else remove track1 and continue the first loop with the track next to track1
542  fRecTracksPtr->RemoveAt(iTrack1);
543  fNRecTracks--;
544  break;
545  }
546  }
547  } // track2
548  } // track1
549  fRecTracksPtr->Compress(); // this is essential to retrieve the TClonesArray afterwards
550 }
551 
552  //__________________________________________________________________________
554 {
556 
557  AliMUONTrack *track, *nextTrack;
558  Bool_t trackRemoved = kFALSE;
559 
560  track = (AliMUONTrack*) fRecTracksPtr->First();
561  while (track) {
562 
563  nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track);
564 
565  if (track->GetGlobalChi2() >= AliMUONTrack::MaxChi2()) {
566  AliWarning("problem occured somewhere during the tracking --> discard track");
567  fRecTracksPtr->Remove(track);
568  fNRecTracks--;
569  trackRemoved = kTRUE;
570  }
571 
572  track = nextTrack;
573 
574  }
575 
576  // compress array of tracks if needed
577  if (trackRemoved) fRecTracksPtr->Compress();
578 
579 }
580 
581  //__________________________________________________________________________
582 void AliMUONVTrackReconstructor::RemoveConnectedTracks(Int_t stMin, Int_t stMax, Bool_t all)
583 {
588 
589  // tag the tracks to be removed
590  TagConnectedTracks(stMin, stMax, all);
591 
592  // remove them
593  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
594  for (Int_t i = 0; i < nTracks; i++) {
595  if (((AliMUONTrack*) fRecTracksPtr->UncheckedAt(i))->IsConnected()) {
596  fRecTracksPtr->RemoveAt(i);
597  fNRecTracks--;
598  }
599  }
600 
601  // remove holes in the array if any
602  fRecTracksPtr->Compress();
603 }
604 
605  //__________________________________________________________________________
606 void AliMUONVTrackReconstructor::TagConnectedTracks(Int_t stMin, Int_t stMax, Bool_t all)
607 {
612 
613  AliMUONTrack *track1, *track2;
614  Int_t nClusters1, nClusters2;
615  Int_t nTracks = fRecTracksPtr->GetEntriesFast();
616 
617  // reset the tags
618  for (Int_t i = 0; i < nTracks; i++) ((AliMUONTrack*) fRecTracksPtr->UncheckedAt(i))->Connected(kFALSE);
619 
620  // Loop over first track of the pair
621  for (Int_t iTrack1 = 0; iTrack1 < nTracks; iTrack1++) {
622  track1 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack1);
623 
624  // Loop over second track of the pair
625  for (Int_t iTrack2 = iTrack1+1; iTrack2 < nTracks; iTrack2++) {
626  track2 = (AliMUONTrack*) fRecTracksPtr->UncheckedAt(iTrack2);
627 
628  // check for connected tracks and tag them
629  if (track1->ClustersInCommon(track2, stMin, stMax) > 0) {
630 
631  if (all) {
632 
633  // tag both tracks
634  track1->Connected();
635  track2->Connected();
636 
637  } else {
638 
639  // tag only the worst track
640  nClusters1 = track1->GetNClusters();
641  nClusters2 = track2->GetNClusters();
642  if ((nClusters1 > nClusters2) || ((nClusters1 == nClusters2) && (track1->GetGlobalChi2() <= track2->GetGlobalChi2()))) {
643  track2->Connected();
644  } else {
645  track1->Connected();
646  }
647 
648  }
649 
650  }
651 
652  }
653 
654  }
655 
656 }
657 
658  //__________________________________________________________________________
660  AliMUONVClusterStore& clusterStore, Int_t chamber)
661 {
663 
664  // check if the current chamber is useable
665  if (!fClusterServer || !GetRecoParam()->UseChamber(chamber)) return;
666 
667  // maximum distance between the center of the chamber and a detection element
668  // (accounting for the inclination of the chamber)
669  static const Double_t kMaxDZ = 15.; // 15 cm
670 
671  // extrapolate track parameters to the chamber
672  AliMUONTrackParam extrapTrackParam(trackParam);
673  if (!AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, AliMUONConstants::DefaultChamberZ(chamber))) return;
674 
675  // build the searching area using the track and chamber resolutions and the maximum-distance-to-track value
676  const TMatrixD& kParamCov = extrapTrackParam.GetCovariances();
677  Double_t errX2 = kParamCov(0,0) + kMaxDZ * kMaxDZ * kParamCov(1,1) + 2. * kMaxDZ * TMath::Abs(kParamCov(0,1)) +
679  Double_t errY2 = kParamCov(2,2) + kMaxDZ * kMaxDZ * kParamCov(3,3) + 2. * kMaxDZ * TMath::Abs(kParamCov(2,3)) +
681  Double_t dX = TMath::Abs(trackParam.GetNonBendingSlope()) * kMaxDZ +
683  GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(2. * errX2);
684  Double_t dY = TMath::Abs(trackParam.GetBendingSlope()) * kMaxDZ +
686  GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(2. * errY2);
687  AliMpArea area(extrapTrackParam.GetNonBendingCoor(),
688  extrapTrackParam.GetBendingCoor(),
689  dX, dY);
690 
691  // ask to cluterize in the given area of the given chamber
692  fClusterServer->Clusterize(chamber, clusterStore, area, GetRecoParam());
693 
694 }
695 
696  //__________________________________________________________________________
698  AliMUONVClusterStore& clusterStore, Int_t station)
699 {
702  AskForNewClustersInChamber(trackParam, clusterStore, 2*station+1);
703  AskForNewClustersInChamber(trackParam, clusterStore, 2*station);
704 }
705 
706  //__________________________________________________________________________
708  AliMUONTrackParam &trackParamAtCluster, Bool_t updatePropagator)
709 {
713 
714  // extrapolate track parameters and covariances at the z position of the tested cluster
715  // and set pointer to cluster into trackParamAtCluster
716  trackParamAtCluster = trackParam;
717  trackParamAtCluster.SetClusterPtr(cluster);
718  if (!AliMUONTrackExtrap::ExtrapToZCov(&trackParamAtCluster, cluster->GetZ(), updatePropagator))
719  return 2.*AliMUONTrack::MaxChi2();
720 
721  // Set differences between trackParam and cluster in the bending and non bending directions
722  Double_t dX = cluster->GetX() - trackParamAtCluster.GetNonBendingCoor();
723  Double_t dY = cluster->GetY() - trackParamAtCluster.GetBendingCoor();
724 
725  // Calculate errors and covariances
726  const TMatrixD& kParamCov = trackParamAtCluster.GetCovariances();
727  Double_t sigmaX2 = kParamCov(0,0) + cluster->GetErrX2();
728  Double_t sigmaY2 = kParamCov(2,2) + cluster->GetErrY2();
729  Double_t covXY = kParamCov(0,2);
730  Double_t det = sigmaX2 * sigmaY2 - covXY * covXY;
731 
732  // Compute chi2
733  if (det == 0.) return 2.*AliMUONTrack::MaxChi2();
734  return (dX * dX * sigmaY2 + dY * dY * sigmaX2 - 2. * dX * dY * covXY) / det;
735 
736 }
737 
738  //__________________________________________________________________________
740 {
745 
746  Double_t dZ = cluster->GetZ() - trackParam.GetZ();
747  Double_t dX = cluster->GetX() - (trackParam.GetNonBendingCoor() + trackParam.GetNonBendingSlope() * dZ);
748  Double_t dY = cluster->GetY() - (trackParam.GetBendingCoor() + trackParam.GetBendingSlope() * dZ);
749  const TMatrixD& kParamCov = trackParam.GetCovariances();
750  Double_t errX2 = kParamCov(0,0) + dZ * dZ * kParamCov(1,1) + 2. * dZ * kParamCov(0,1) + cluster->GetErrX2();
751  Double_t errY2 = kParamCov(2,2) + dZ * dZ * kParamCov(3,3) + 2. * dZ * kParamCov(2,3) + cluster->GetErrY2();
752 
753  Double_t dXmax = GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(2. * errX2) +
755  Double_t dYmax = GetRecoParam()->GetSigmaCutForTracking() * TMath::Sqrt(2. * errY2) +
757 
758  if (TMath::Abs(dX) > dXmax || TMath::Abs(dY) > dYmax) return kFALSE;
759 
760  return kTRUE;
761 
762 }
763 
764  //__________________________________________________________________________
766  AliMUONTrackParam &trackParamAtCluster2)
767 {
772 
773  // extrapolate linearly track parameters and covariances at the z position of the second cluster
774  trackParamAtCluster2 = trackParamAtCluster1;
775  AliMUONTrackExtrap::LinearExtrapToZCov(&trackParamAtCluster2, cluster2->GetZ());
776 
777  // set pointer to cluster2 into trackParamAtCluster2
778  trackParamAtCluster2.SetClusterPtr(cluster2);
779 
780  // Set differences between track and clusters in the bending and non bending directions
781  AliMUONVCluster* cluster1 = trackParamAtCluster1.GetClusterPtr();
782  Double_t dX1 = cluster1->GetX() - trackParamAtCluster1.GetNonBendingCoor();
783  Double_t dX2 = cluster2->GetX() - trackParamAtCluster2.GetNonBendingCoor();
784  Double_t dY1 = cluster1->GetY() - trackParamAtCluster1.GetBendingCoor();
785  Double_t dY2 = cluster2->GetY() - trackParamAtCluster2.GetBendingCoor();
786 
787  // Calculate errors and covariances
788  const TMatrixD& kParamCov1 = trackParamAtCluster1.GetCovariances();
789  const TMatrixD& kParamCov2 = trackParamAtCluster2.GetCovariances();
790  Double_t dZ = trackParamAtCluster2.GetZ() - trackParamAtCluster1.GetZ();
791  Double_t sigma2X1 = kParamCov1(0,0) + cluster1->GetErrX2();
792  Double_t sigma2X2 = kParamCov2(0,0) + cluster2->GetErrX2();
793  Double_t covX1X2 = kParamCov1(0,0) + dZ * kParamCov1(0,1);
794  Double_t sigma2Y1 = kParamCov1(2,2) + cluster1->GetErrY2();
795  Double_t sigma2Y2 = kParamCov2(2,2) + cluster2->GetErrY2();
796  Double_t covY1Y2 = kParamCov1(2,2) + dZ * kParamCov1(2,3);
797 
798  // Compute chi2
799  Double_t detX = sigma2X1 * sigma2X2 - covX1X2 * covX1X2;
800  Double_t detY = sigma2Y1 * sigma2Y2 - covY1Y2 * covY1Y2;
801  if (detX == 0. || detY == 0.) return 2.*AliMUONTrack::MaxChi2();
802  return (dX1 * dX1 * sigma2X2 + dX2 * dX2 * sigma2X1 - 2. * dX1 * dX2 * covX1X2) / detX
803  + (dY1 * dY1 * sigma2Y2 + dY2 * dY2 * sigma2Y1 - 2. * dY1 * dY2 * covY1Y2) / detY;
804 
805 }
806 
807  //__________________________________________________________________________
809  Int_t nextChamber)
810 {
818  AliDebug(1,Form("Enter FollowLinearTrackInChamber(1..) %d", nextChamber+1));
819 
820  Double_t chi2WithOneCluster = AliMUONTrack::MaxChi2();
821  Double_t maxChi2WithOneCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() *
822  GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
823  Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
824  Bool_t foundOneCluster = kFALSE;
825  AliMUONTrack *newTrack = 0x0;
826  AliMUONVCluster *cluster;
827  AliMUONTrackParam trackParam;
828  AliMUONTrackParam extrapTrackParamAtCluster;
829  AliMUONTrackParam bestTrackParamAtCluster;
830 
831  // Get track parameters according to the propagation direction
832  if (nextChamber > 7) trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
833  else trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
834 
835  // Printout for debuging
836  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
837  cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
838  trackParam.GetParameters().Print();
839  trackParam.GetCovariances().Print();
840  }
841 
842  // Add MCS effect
844 
845  // Printout for debuging
846  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
847  cout << "FollowLinearTrackInChamber: look for cluster in chamber(1..): " << nextChamber+1 << endl;
848  }
849 
850  // Create iterators to loop over clusters in chamber
851  TIter next(clusterStore.CreateChamberIterator(nextChamber,nextChamber));
852 
853  // look for candidates in chamber
854  while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) ) {
855 
856  // try to add the current cluster fast
857  if (!TryOneClusterFast(trackParam, cluster)) continue;
858 
859  // try to add the current cluster accuratly
860  extrapTrackParamAtCluster = trackParam;
861  AliMUONTrackExtrap::LinearExtrapToZCov(&extrapTrackParamAtCluster, cluster->GetZ());
862  chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster, cluster, extrapTrackParamAtCluster);
863 
864  // if good chi2 then consider to add cluster
865  if (chi2WithOneCluster < maxChi2WithOneCluster) {
866  foundOneCluster = kTRUE;
867 
868  // Printout for debuging
869  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
870  cout << "FollowLinearTrackInChamber: found one cluster in chamber(1..): " << nextChamber+1
871  << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
872  cluster->Print();
873  }
874 
875  if (GetRecoParam()->TrackAllTracks()) {
876  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
877  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
878  if (GetRecoParam()->RequestStation(nextChamber/2))
879  extrapTrackParamAtCluster.SetRemovable(kFALSE);
880  else extrapTrackParamAtCluster.SetRemovable(kTRUE);
881  newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster,*cluster);
882  newTrack->SetGlobalChi2(trackCandidate.GetGlobalChi2()+chi2WithOneCluster);
883  fNRecTracks++;
884 
885  // Printout for debuging
886  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
887  cout << "FollowLinearTrackInChamber: added one cluster in chamber(1..): " << nextChamber+1 << endl;
888  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
889  }
890 
891  } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
892  // keep track of the best cluster
893  bestChi2WithOneCluster = chi2WithOneCluster;
894  bestTrackParamAtCluster = extrapTrackParamAtCluster;
895  }
896 
897  }
898 
899  }
900 
901  // fill out the best track if required else clean up the fRecTracksPtr array
902  if (!GetRecoParam()->TrackAllTracks()) {
903  if (foundOneCluster) {
904  if (GetRecoParam()->RequestStation(nextChamber/2))
905  bestTrackParamAtCluster.SetRemovable(kFALSE);
906  else bestTrackParamAtCluster.SetRemovable(kTRUE);
907  trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster,*(bestTrackParamAtCluster.GetClusterPtr()));
908  trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithOneCluster);
909 
910  // Printout for debuging
911  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
912  cout << "FollowLinearTrackInChamber: added the best cluster in chamber(1..): " << bestTrackParamAtCluster.GetClusterPtr()->GetChamberId()+1 << endl;
913  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
914  }
915 
916  } else return kFALSE;
917 
918  } else if (foundOneCluster) {
919 
920  // remove obsolete track
921  fRecTracksPtr->Remove(&trackCandidate);
922  fNRecTracks--;
923 
924  } else return kFALSE;
925 
926  return kTRUE;
927 
928 }
929 
930 //__________________________________________________________________________
932  Int_t nextStation)
933 {
941  AliDebug(1,Form("Enter FollowLinearTrackInStation(1..) %d", nextStation+1));
942 
943  // Order the chamber according to the propagation direction (tracking starts with chamber 2):
944  // - nextStation == station(1...) 5 => forward propagation
945  // - nextStation < station(1...) 5 => backward propagation
946  Int_t ch1, ch2;
947  if (nextStation==4) {
948  ch1 = 2*nextStation+1;
949  ch2 = 2*nextStation;
950  } else {
951  ch1 = 2*nextStation;
952  ch2 = 2*nextStation+1;
953  }
954 
955  Double_t chi2WithOneCluster = AliMUONTrack::MaxChi2();
956  Double_t chi2WithTwoClusters = AliMUONTrack::MaxChi2();
957  Double_t maxChi2WithOneCluster = 2. * GetRecoParam()->GetSigmaCutForTracking() *
958  GetRecoParam()->GetSigmaCutForTracking(); // 2 because 2 quantities in chi2
959  Double_t maxChi2WithTwoClusters = 4. * GetRecoParam()->GetSigmaCutForTracking() *
960  GetRecoParam()->GetSigmaCutForTracking(); // 4 because 4 quantities in chi2
961  Double_t bestChi2WithOneCluster = maxChi2WithOneCluster;
962  Double_t bestChi2WithTwoClusters = maxChi2WithTwoClusters;
963  Bool_t foundOneCluster = kFALSE;
964  Bool_t foundTwoClusters = kFALSE;
965  AliMUONTrack *newTrack = 0x0;
966  AliMUONVCluster *clusterCh1, *clusterCh2;
967  AliMUONTrackParam trackParam;
968  AliMUONTrackParam extrapTrackParamAtCluster1;
969  AliMUONTrackParam extrapTrackParamAtCluster2;
970  AliMUONTrackParam bestTrackParamAtCluster1;
971  AliMUONTrackParam bestTrackParamAtCluster2;
972 
973  Int_t nClusters = clusterStore.GetSize();
974  Bool_t *clusterCh1Used = new Bool_t[nClusters];
975  for (Int_t i = 0; i < nClusters; i++) clusterCh1Used[i] = kFALSE;
976  Int_t iCluster1;
977 
978  // Get track parameters according to the propagation direction
979  if (nextStation==4) trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->Last();
980  else trackParam = *(AliMUONTrackParam*)trackCandidate.GetTrackParamAtCluster()->First();
981 
982  // Printout for debuging
983  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 2) || (AliLog::GetGlobalDebugLevel() >= 2)) {
984  cout<<endl<<"Track parameters and covariances at first cluster:"<<endl;
985  trackParam.GetParameters().Print();
986  trackParam.GetCovariances().Print();
987  }
988 
989  // Add MCS effect
991 
992  // Printout for debuging
993  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
994  cout << "FollowLinearTrackInStation: look for clusters in chamber(1..): " << ch2+1 << endl;
995  }
996 
997  // Create iterators to loop over clusters in both chambers
998  TIter nextInCh1(clusterStore.CreateChamberIterator(ch1,ch1));
999  TIter nextInCh2(clusterStore.CreateChamberIterator(ch2,ch2));
1000 
1001  // look for candidates in chamber 2
1002  while ( ( clusterCh2 = static_cast<AliMUONVCluster*>(nextInCh2()) ) ) {
1003 
1004  // try to add the current cluster fast
1005  if (!TryOneClusterFast(trackParam, clusterCh2)) continue;
1006 
1007  // try to add the current cluster accuratly
1008  extrapTrackParamAtCluster2 = trackParam;
1009  AliMUONTrackExtrap::LinearExtrapToZCov(&extrapTrackParamAtCluster2, clusterCh2->GetZ());
1010  chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster2, clusterCh2, extrapTrackParamAtCluster2);
1011 
1012  // if good chi2 then try to attach a cluster in the other chamber too
1013  if (chi2WithOneCluster < maxChi2WithOneCluster) {
1014  Bool_t foundSecondCluster = kFALSE;
1015 
1016  // Printout for debuging
1017  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1018  cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch2+1
1019  << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
1020  clusterCh2->Print();
1021  cout << " look for second clusters in chamber(1..): " << ch1+1 << " ..." << endl;
1022  }
1023 
1024  // add MCS effect
1025  AliMUONTrackExtrap::AddMCSEffect(&extrapTrackParamAtCluster2,AliMUONConstants::ChamberThicknessInX0(ch2),-1.);
1026 
1027  // reset cluster iterator of chamber 1
1028  nextInCh1.Reset();
1029  iCluster1 = -1;
1030 
1031  // look for second candidates in chamber 1
1032  while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
1033  iCluster1++;
1034 
1035  // try to add the current cluster fast
1036  if (!TryOneClusterFast(extrapTrackParamAtCluster2, clusterCh1)) continue;
1037 
1038  // try to add the current cluster in addition to the one found in the previous chamber
1039  chi2WithTwoClusters = TryTwoClustersFast(extrapTrackParamAtCluster2, clusterCh1, extrapTrackParamAtCluster1);
1040 
1041  // if good chi2 then consider to add the 2 clusters to the "trackCandidate"
1042  if (chi2WithTwoClusters < maxChi2WithTwoClusters) {
1043  foundSecondCluster = kTRUE;
1044  foundTwoClusters = kTRUE;
1045 
1046  // Printout for debuging
1047  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1048  cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1
1049  << " (Chi2 = " << chi2WithTwoClusters << ")" << endl;
1050  clusterCh1->Print();
1051  }
1052 
1053  if (GetRecoParam()->TrackAllTracks()) {
1054  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new clusters
1055  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
1056  extrapTrackParamAtCluster1.SetRemovable(kTRUE);
1057  newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
1058  extrapTrackParamAtCluster2.SetRemovable(kTRUE);
1059  newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
1060  newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithTwoClusters);
1061  fNRecTracks++;
1062 
1063  // Tag clusterCh1 as used
1064  clusterCh1Used[iCluster1] = kTRUE;
1065 
1066  // Printout for debuging
1067  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1068  cout << "FollowLinearTrackInStation: added two clusters in station(1..): " << nextStation+1 << endl;
1069  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
1070  }
1071 
1072  } else if (chi2WithTwoClusters < bestChi2WithTwoClusters) {
1073  // keep track of the best couple of clusters
1074  bestChi2WithTwoClusters = chi2WithTwoClusters;
1075  bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
1076  bestTrackParamAtCluster2 = extrapTrackParamAtCluster2;
1077  }
1078 
1079  }
1080 
1081  }
1082 
1083  // if no cluster found in chamber1 then consider to add clusterCh2 only
1084  if (!foundSecondCluster) {
1085  foundOneCluster = kTRUE;
1086 
1087  if (GetRecoParam()->TrackAllTracks()) {
1088  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
1089  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
1090  if (GetRecoParam()->RequestStation(nextStation))
1091  extrapTrackParamAtCluster2.SetRemovable(kFALSE);
1092  else extrapTrackParamAtCluster2.SetRemovable(kTRUE);
1093  newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster2,*clusterCh2);
1094  newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithOneCluster);
1095  fNRecTracks++;
1096 
1097  // Printout for debuging
1098  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1099  cout << "FollowLinearTrackInStation: added one cluster in chamber(1..): " << ch2+1 << endl;
1100  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
1101  }
1102 
1103  } else if (!foundTwoClusters && chi2WithOneCluster < bestChi2WithOneCluster) {
1104  // keep track of the best cluster except if a couple of clusters has already been found
1105  bestChi2WithOneCluster = chi2WithOneCluster;
1106  bestTrackParamAtCluster1 = extrapTrackParamAtCluster2;
1107  }
1108 
1109  }
1110 
1111  }
1112 
1113  }
1114 
1115  // look for candidates in chamber 1 not already attached to a track
1116  // if we want to keep all possible tracks or if no good couple of clusters has been found
1117  if (GetRecoParam()->TrackAllTracks() || !foundTwoClusters) {
1118 
1119  // Printout for debuging
1120  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1121  cout << "FollowLinearTrackInStation: look for single cluster in chamber(1..): " << ch1+1 << endl;
1122  }
1123 
1124  //Extrapolate trackCandidate to chamber "ch2"
1126 
1127  // add MCS effect for next step
1129 
1130  // reset cluster iterator of chamber 1
1131  nextInCh1.Reset();
1132  iCluster1 = -1;
1133 
1134  // look for second candidates in chamber 1
1135  while ( ( clusterCh1 = static_cast<AliMUONVCluster*>(nextInCh1()) ) ) {
1136  iCluster1++;
1137 
1138  if (clusterCh1Used[iCluster1]) continue; // Skip clusters already used
1139 
1140  // try to add the current cluster fast
1141  if (!TryOneClusterFast(trackParam, clusterCh1)) continue;
1142 
1143  // try to add the current cluster accuratly
1144  extrapTrackParamAtCluster1 = trackParam;
1145  AliMUONTrackExtrap::LinearExtrapToZCov(&extrapTrackParamAtCluster1, clusterCh1->GetZ());
1146  chi2WithOneCluster = TryOneCluster(extrapTrackParamAtCluster1, clusterCh1, extrapTrackParamAtCluster1);
1147 
1148  // if good chi2 then consider to add clusterCh1
1149  // We do not try to attach a cluster in the other chamber too since it has already been done above
1150  if (chi2WithOneCluster < maxChi2WithOneCluster) {
1151  foundOneCluster = kTRUE;
1152 
1153  // Printout for debuging
1154  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1155  cout << "FollowLinearTrackInStation: found one cluster in chamber(1..): " << ch1+1
1156  << " (Chi2 = " << chi2WithOneCluster << ")" << endl;
1157  clusterCh1->Print();
1158  }
1159 
1160  if (GetRecoParam()->TrackAllTracks()) {
1161  // copy trackCandidate into a new track put at the end of fRecTracksPtr and add the new cluster
1162  newTrack = new ((*fRecTracksPtr)[fRecTracksPtr->GetLast()+1]) AliMUONTrack(trackCandidate);
1163  if (GetRecoParam()->RequestStation(nextStation))
1164  extrapTrackParamAtCluster1.SetRemovable(kFALSE);
1165  else extrapTrackParamAtCluster1.SetRemovable(kTRUE);
1166  newTrack->AddTrackParamAtCluster(extrapTrackParamAtCluster1,*clusterCh1);
1167  newTrack->SetGlobalChi2(newTrack->GetGlobalChi2()+chi2WithOneCluster);
1168  fNRecTracks++;
1169 
1170  // Printout for debuging
1171  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1172  cout << "FollowLinearTrackInStation: added one cluster in chamber(1..): " << ch1+1 << endl;
1173  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
1174  }
1175 
1176  } else if (chi2WithOneCluster < bestChi2WithOneCluster) {
1177  // keep track of the best cluster except if a couple of clusters has already been found
1178  bestChi2WithOneCluster = chi2WithOneCluster;
1179  bestTrackParamAtCluster1 = extrapTrackParamAtCluster1;
1180  }
1181 
1182  }
1183 
1184  }
1185 
1186  }
1187 
1188  // fill out the best track if required else clean up the fRecTracksPtr array
1189  if (!GetRecoParam()->TrackAllTracks()) {
1190  if (foundTwoClusters) {
1191  bestTrackParamAtCluster1.SetRemovable(kTRUE);
1192  trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
1193  bestTrackParamAtCluster2.SetRemovable(kTRUE);
1194  trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster2,*(bestTrackParamAtCluster2.GetClusterPtr()));
1195  trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithTwoClusters);
1196 
1197  // Printout for debuging
1198  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1199  cout << "FollowLinearTrackInStation: added the two best clusters in station(1..): " << nextStation+1 << endl;
1200  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
1201  }
1202 
1203  } else if (foundOneCluster) {
1204  if (GetRecoParam()->RequestStation(nextStation))
1205  bestTrackParamAtCluster1.SetRemovable(kFALSE);
1206  else bestTrackParamAtCluster1.SetRemovable(kTRUE);
1207  trackCandidate.AddTrackParamAtCluster(bestTrackParamAtCluster1,*(bestTrackParamAtCluster1.GetClusterPtr()));
1208  trackCandidate.SetGlobalChi2(trackCandidate.GetGlobalChi2()+bestChi2WithOneCluster);
1209 
1210  // Printout for debuging
1211  if ((AliLog::GetDebugLevel("MUON","AliMUONVTrackReconstructor") >= 1) || (AliLog::GetGlobalDebugLevel() >= 1)) {
1212  cout << "FollowLinearTrackInStation: added the best cluster in chamber(1..): " << bestTrackParamAtCluster1.GetClusterPtr()->GetChamberId()+1 << endl;
1213  if (AliLog::GetGlobalDebugLevel() >= 3) newTrack->RecursiveDump();
1214  }
1215 
1216  } else {
1217  delete [] clusterCh1Used;
1218  return kFALSE;
1219  }
1220 
1221  } else if (foundOneCluster || foundTwoClusters) {
1222 
1223  // remove obsolete track
1224  fRecTracksPtr->Remove(&trackCandidate);
1225  fNRecTracks--;
1226 
1227  } else {
1228  delete [] clusterCh1Used;
1229  return kFALSE;
1230  }
1231 
1232  delete [] clusterCh1Used;
1233  return kTRUE;
1234 
1235 }
1236 
1237 //__________________________________________________________________________
1239 {
1242  AliDebug(1,"Enter ImproveTracks");
1243 
1244  AliMUONTrack *track, *nextTrack;
1245 
1246  track = (AliMUONTrack*) fRecTracksPtr->First();
1247  while (track) {
1248 
1249  // prepare next track in case the actual track is suppressed
1250  nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track);
1251 
1252  ImproveTrack(*track);
1253 
1254  // remove track if improvement failed
1255  if (!track->IsImproved()) {
1256  fRecTracksPtr->Remove(track);
1257  fNRecTracks--;
1258  }
1259 
1260  track = nextTrack;
1261  }
1262 
1263  // compress the array in case of some tracks have been removed
1264  fRecTracksPtr->Compress();
1265 
1266 }
1267 
1268 //__________________________________________________________________________
1270 {
1274 
1275  AliMUONTrack *track, *nextTrack;
1276  Bool_t trackRemoved = kFALSE;
1277 
1278  track = (AliMUONTrack*) fRecTracksPtr->First();
1279  while (track) {
1280 
1281  nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track);
1282 
1283  if (FinalizeTrack(*track)) track->FindMCLabel();
1284  else {
1285  fRecTracksPtr->Remove(track);
1286  fNRecTracks--;
1287  trackRemoved = kTRUE;
1288  }
1289 
1290  track = nextTrack;
1291 
1292  }
1293 
1294  // compress array of tracks if needed
1295  if (trackRemoved) fRecTracksPtr->Compress();
1296 
1297 }
1298 
1299 //__________________________________________________________________________
1301 {
1305 
1306  if (!fkTransformer) AliFatal("missing geometry transformer");
1307 
1308  AliMUONTrack *track, *nextTrack;
1309  Bool_t trackRemoved = kFALSE;
1310 
1311  track = (AliMUONTrack*) fRecTracksPtr->First();
1312  while (track) {
1313 
1314  nextTrack = (AliMUONTrack*) fRecTracksPtr->After(track);
1315 
1317 
1318  if (!RefitTrack(*track) || (GetRecoParam()->ImproveTracks() && !track->IsImproved())) {
1319  fRecTracksPtr->Remove(track);
1320  fNRecTracks--;
1321  trackRemoved = kTRUE;
1322  }
1323 
1324  track = nextTrack;
1325 
1326  }
1327 
1328  // compress array of tracks if needed
1329  if (trackRemoved) fRecTracksPtr->Compress();
1330 
1331 }
1332 
1333 //__________________________________________________________________________
1335 {
1338 
1339  // Loop over clusters
1340  AliMUONVCluster *cluster;
1341  Int_t nClusters = track.GetNClusters();
1342  for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
1343  cluster = ((AliMUONTrackParam*) track.GetTrackParamAtCluster()->UncheckedAt(iCluster))->GetClusterPtr();
1344 
1345  // do it only for stations 3, 4 & 5
1346  if (cluster->GetChamberId() < 4) continue;
1347 
1348  // get the cathod corresponding to the bending/non-bending plane
1349  Int_t deId = cluster->GetDetElemId();
1350  AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(deId, kFALSE);
1351  if (!de) continue;
1354 
1355  // get the corresponding segmentation
1358  if (!seg1 || !seg2) continue;
1359 
1360  // get local coordinate of the cluster
1361  Double_t lX,lY,lZ;
1362  Double_t gX = cluster->GetX();
1363  Double_t gY = cluster->GetY();
1364  Double_t gZ = cluster->GetZ();
1365  fkTransformer->Global2Local(deId,gX,gY,gZ,lX,lY,lZ);
1366 
1367  // find pads below the cluster
1368  AliMpPad pad1 = seg1->PadByPosition(lX, lY, kFALSE);
1369  AliMpPad pad2 = seg2->PadByPosition(lX, lY, kFALSE);
1370 
1371  // build their ID if pads are valid
1372  UInt_t padId1 = (pad1.IsValid()) ? AliMUONVDigit::BuildUniqueID(deId, pad1.GetManuId(), pad1.GetManuChannel(), cath1) : 0;
1373  UInt_t padId2 = (pad2.IsValid()) ? AliMUONVDigit::BuildUniqueID(deId, pad2.GetManuId(), pad2.GetManuChannel(), cath2) : 0;
1374 
1375  // check if the cluster contains these pads
1376  Bool_t hasNonBending = kFALSE;
1377  Bool_t hasBending = kFALSE;
1378  for (Int_t iDigit = 0; iDigit < cluster->GetNDigits(); iDigit++) {
1379 
1380  UInt_t digitId = cluster->GetDigitId(iDigit);
1381 
1382  if (digitId == padId1) {
1383 
1384  hasBending = kTRUE;
1385  if (hasNonBending) break;
1386 
1387  } else if (digitId == padId2) {
1388 
1389  hasNonBending = kTRUE;
1390  if (hasBending) break;
1391 
1392  }
1393 
1394  }
1395 
1396  // modify the cluster resolution if needed
1397  if (!hasNonBending) cluster->SetErrXY(GetRecoParam()->GetMonoCathodClNonBendingRes(), cluster->GetErrY());
1398  if (!hasBending) cluster->SetErrXY(cluster->GetErrX(), GetRecoParam()->GetMonoCathodClBendingRes());
1399 
1400  }
1401 
1402 }
1403 
1404 //__________________________________________________________________________
1406  const AliMUONVTriggerTrackStore& triggerTrackStore,
1407  const AliMUONVTriggerStore& triggerStore,
1408  const AliMUONTrackHitPattern& trackHitPattern)
1409 {
1411  AliCodeTimerAuto("",0);
1412 
1413  trackHitPattern.ExecuteValidation(trackStore, triggerTrackStore, triggerStore);
1414 }
1415 
1416 
1417 //__________________________________________________________________________
1419  const AliMUONVTriggerStore& triggerStore,
1420  AliMUONVTriggerTrackStore& triggerTrackStore)
1421 {
1423  AliDebug(1, "");
1424  AliCodeTimerAuto("",0);
1425 
1426  AliMUONGlobalTrigger* globalTrigger = triggerStore.Global();
1427 
1428  UChar_t gloTrigPat = 0;
1429 
1430  if (globalTrigger)
1431  {
1432  gloTrigPat = globalTrigger->GetGlobalResponse();
1433  }
1434 
1435  AliMUONTriggerTrack triggerTrack;
1436 
1437  TIter next(triggerStore.CreateIterator());
1438  AliMUONLocalTrigger* locTrg(0x0);
1439 
1440  while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
1441  {
1442  if ( locTrg->IsTrigX() && locTrg->IsTrigY() )
1443  { // make Trigger Track if trigger in X and Y
1444 
1445  if (TriggerToTrack(circuit, *locTrg, triggerTrack, gloTrigPat))
1446  triggerTrackStore.Add(triggerTrack);
1447 
1448  } // board is fired
1449  } // end of loop on Local Trigger
1450 }
1451 
1452 //__________________________________________________________________________
1454  const AliMUONLocalTrigger& locTrg,
1455  AliMUONTriggerTrack& triggerTrack,
1456  UChar_t globalTriggerPattern)
1457 {
1459  const Double_t kTrigNonBendReso = AliMUONConstants::TriggerNonBendingReso();
1460  const Double_t kTrigBendReso = AliMUONConstants::TriggerBendingReso();
1461  const Double_t kSqrt12 = TMath::Sqrt(12.);
1462 
1463  TMatrixD trigCov(3,3);
1464 
1465  Int_t localBoardId = locTrg.LoCircuit();
1466 
1467  Float_t y11 = circuit.GetY11Pos(localBoardId, locTrg.LoStripX());
1468  Float_t z11 = circuit.GetZ11Pos(localBoardId, locTrg.LoStripX());
1469  // need first to convert deviation to [0-30]
1470  // (see AliMUONLocalTriggerBoard::LocalTrigger)
1471  Int_t deviation = locTrg.GetDeviation();
1472  Int_t stripX21 = locTrg.LoStripX()+deviation+1;
1473  Float_t y21 = circuit.GetY21Pos(localBoardId, stripX21);
1474  Float_t z21 = circuit.GetZ21Pos(localBoardId, stripX21);
1475  Float_t x11 = circuit.GetX11Pos(localBoardId, locTrg.LoStripY());
1476 
1477  AliDebug(1, Form(" MakeTriggerTrack %3d %2d %2d %2d (%f %f %f) (%f %f)\n",locTrg.LoCircuit(),
1478  locTrg.LoStripX(),locTrg.LoStripX()+deviation+1,locTrg.LoStripY(),x11, y11, z11, y21, z21));
1479 
1480  if (TMath::Abs(z11) < 0.00001) return kFALSE;
1481 
1482  Double_t deltaZ = z11 - z21;
1483 
1484  Float_t slopeX = x11/z11;
1485  Float_t slopeY = (y11-y21) / deltaZ;
1486 
1487  Float_t sigmaX = circuit.GetX11Width(localBoardId, locTrg.LoStripY()) / kSqrt12;
1488  Float_t sigmaY = circuit.GetY11Width(localBoardId, locTrg.LoStripX()) / kSqrt12;
1489  Float_t sigmaY21 = circuit.GetY21Width(localBoardId, locTrg.LoStripX()) / kSqrt12;
1490 
1491  trigCov.Zero();
1492  trigCov(0,0) = kTrigNonBendReso * kTrigNonBendReso + sigmaX * sigmaX;
1493  trigCov(1,1) = kTrigBendReso * kTrigBendReso + sigmaY * sigmaY;
1494  trigCov(2,2) =
1495  (2. * kTrigBendReso * kTrigBendReso + sigmaY * sigmaY + sigmaY21 * sigmaY21 ) / deltaZ / deltaZ;
1496  trigCov(1,2) = trigCov(2,1) = trigCov(1,1) / deltaZ;
1497 
1498  triggerTrack.SetX11(x11);
1499  triggerTrack.SetY11(y11);
1500  triggerTrack.SetZ11(z11);
1501  triggerTrack.SetZ21(z21);
1502  triggerTrack.SetSlopeX(slopeX);
1503  triggerTrack.SetSlopeY(slopeY);
1504  triggerTrack.SetGTPattern(globalTriggerPattern);
1505  triggerTrack.SetLoTrgNum(localBoardId);
1506  triggerTrack.SetCovariances(trigCov);
1507  triggerTrack.SetUniqueID(locTrg.GetUniqueID());
1508 
1509  return kTRUE;
1510 
1511 }
void AskForNewClustersInStation(const AliMUONTrackParam &trackParam, AliMUONVClusterStore &clusterStore, Int_t station)
Bool_t FollowLinearTrackInStation(AliMUONTrack &trackCandidate, const AliMUONVClusterStore &clusterStore, Int_t nextStation)
Base class of a track container.
Virtual class for the MUON track reconstruction.
Int_t GetNClusters() const
return the number of clusters attached to the track
Definition: AliMUONTrack.h:46
Double_t GetMaxBendingSlope() const
return the maximum value of the bending slope
const AliMpVSegmentation * GetMpSegmentation(Int_t detElemId, AliMp::CathodType cath, Bool_t warn=true) const
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.
Float_t GetY21Pos(Int_t localBoardId, Int_t istrip) const
void ImproveTracks(Bool_t flag)
switch on/off the track improvement and keep the default cut in sigma to apply on cluster (local chi2...
virtual void ImproveTrack(AliMUONTrack &track)=0
Improve the given reconstructed track.
virtual Bool_t MakeMoreTrackCandidates(AliMUONVClusterStore &clusterStore)=0
Make extra track candidates from clusters in stations(1..) 4 and 5.
Double_t GetSigmaCutForTracking() const
return the cut in sigma to apply on cluster (local chi2) and track (global chi2) during tracking ...
static AliMpSegmentation * Instance(Bool_t warn=true)
virtual Double_t GetZ() const =0
Return coordinate Z (cm)
virtual Bool_t RefitTrack(AliMUONTrack &track, Bool_t enableImprovement=kTRUE)=0
Re-fit the given track.
static Int_t NTrackingCh()
Return number of tracking chambers.
virtual Bool_t FinalizeTrack(AliMUONTrack &track)=0
Finalize the given track.
Double_t GetBendingCoor() const
return bending coordinate (cm)
Int_t ClustersInCommon(AliMUONTrack *track, Int_t stMin=0, Int_t stMax=4) const
void ValidateTracksWithTrigger(AliMUONVTrackStore &trackStore, const AliMUONVTriggerTrackStore &triggerTrackStore, const AliMUONVTriggerStore &triggerStore, const AliMUONTrackHitPattern &trackHitPattern)
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 dZ()
Definition: CalibAlign.C:517
void RemoveUsedSegments(TClonesArray &segments)
Int_t GetManuId() const
Definition: AliMpPad.cxx:256
Double_t GetMaxNonBendingDistanceToTrack() const
return the maximum distance to the track to search for compatible cluster(s) in non bending direction...
Double_t GetDefaultNonBendingReso(Int_t iCh) const
Get the default non bending resolution of chamber iCh.
void SetSlopeY(Float_t slopeY)
Set track slope in Y.
void SelectOnTrackSlope(Bool_t flag)
switch on/off the track selection according to their slope (instead of their impact parameter) ...
Interface of a cluster finder for combined tracking.
virtual Bool_t ComplementTracks(const AliMUONVClusterStore &clusterStore)=0
Complement the reconstructed tracks.
virtual Int_t GetSize() const =0
The number of objects stored.
virtual Bool_t Add(TObject *object)
Add.
virtual Double_t GetErrX() const =0
Return resolution (cm) on coordinate X.
Double_t GetZ() const
return Z coordinate (cm)
A rectangle area positioned in plane..
Definition: AliMpArea.h:20
Float_t GetZ11Pos(Int_t localBoardId, Int_t istrip) const
Track parameters in ALICE dimuon spectrometer.
static Double_t TriggerBendingReso()
Return default trigger chamber resolution DUE TO ALIGNMENT ONLY in bending direction.
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
AliMpDetElement * GetDetElement(Int_t detElemId, Bool_t warn=true) const
TObject * First() const
Return the first element of the pair.
Reconstructed trigger track in ALICE dimuon spectrometer.
The class defines the electronics properties of detection element.
Bool_t TryOneClusterFast(const AliMUONTrackParam &trackParam, const AliMUONVCluster *cluster)
virtual void SetErrXY(Double_t errX, Double_t errY)=0
Set resolution (cm) on coordinates (X,Y)
Int_t LoStripY() const
Return Y strip in MT11.
Double_t GetMaxBendingDistanceToTrack() const
return the maximum distance to the track to search for compatible cluster(s) in bending direction ...
void AskForNewClustersInChamber(const AliMUONTrackParam &trackParam, AliMUONVClusterStore &clusterStore, Int_t chamber)
Bool_t TriggerToTrack(const AliMUONTriggerCircuit &circuit, const AliMUONLocalTrigger &locTrg, AliMUONTriggerTrack &triggerTrack, UChar_t globalTriggerPattern=0)
Base class of a trigger information store.
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
Float_t GetZ21Pos(Int_t localBoardId, Int_t istrip) const
Double_t TryTwoClustersFast(const AliMUONTrackParam &trackParamAtCluster1, AliMUONVCluster *cluster2, AliMUONTrackParam &trackParamAtCluster2)
virtual TIterator * CreateIterator() const
Create iterator (on local card)
Double_t GetMonoCathodClBendingRes() const
Get the bending resolution of mono-cathod clusters when the bending plane is missing.
ClassImp(TPCGenInfo)
Definition: AliTPCCmpNG.C:254
Int_t GetManuChannel() const
Definition: AliMpPad.cxx:264
void dY()
Definition: CalibAlign.C:547
virtual UInt_t GetDigitId(Int_t i) const =0
Return Id of digits i.
void SetLoTrgNum(Int_t loTrgNum)
Set local trigger number.
const AliMUONRecoParam * GetRecoParam() const
Return reco parameters.
virtual void Print(Option_t *option="") const
static AliMpDDLStore * Instance(Bool_t warn=true)
Double_t GetBendingSlope() const
return bending slope (cm ** -1)
Int_t LoStripX() const
Return X strip in MT11.
Double_t sigmaCut
Definition: DIMUONFakes.C:36
abstract base class for clusters
static Bool_t ExtrapToZCov(AliMUONTrackParam *trackParam, Double_t zEnd, Bool_t updatePropagator=kFALSE)
void SetSlopeX(Float_t slopeX)
Set track slope in X.
Reconstructed Local Trigger object.
MUON Trigger circuit.
static void LinearExtrapToZCov(AliMUONTrackParam *trackParam, Double_t zEnd, Bool_t updatePropagator=kFALSE)
AliMUONVClusterServer * fClusterServer
reference to our cluster server
virtual Bool_t MakeTrackCandidates(AliMUONVClusterStore &clusterStore)=0
Make track candidates from clusters in stations(1..) 4 and 5.
Double_t GetGlobalChi2() const
return the minimum value of the function minimized by the fit
Definition: AliMUONTrack.h:69
Float_t GetY11Pos(Int_t localBoardId, Int_t istrip) const
Class for the MUON track hit pattern.
void SetClusterPtr(AliMUONVCluster *cluster, Bool_t owner=kFALSE)
void SetZ21(Float_t z)
Set z position of fired X strip in MC21.
TObject * Second() const
Return the second element of the pair.
Bool_t FollowLinearTrackInChamber(AliMUONTrack &trackCandidate, const AliMUONVClusterStore &clusterStore, Int_t nextChamber)
void AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy=kFALSE)
void ComplementTracks(Bool_t flag)
switch on/off the completion of reconstructed track
virtual Double_t GetErrY() const =0
Return resolution (cm) on coordinate Y.
non-bending plane
Double_t * fMaxMCSAngle2
maximum angle dispersion due to MCS
static void AddMCSEffect(AliMUONTrackParam *param, Double_t dZ, Double_t x0)
TClonesArray * MakeSegmentsBetweenChambers(const AliMUONVClusterStore &clusterStore, Int_t ch1, Int_t ch2)
virtual Int_t GetNDigits() const =0
Return number of associated digits.
Interface of a cluster container.
virtual Bool_t FollowTracks(AliMUONVClusterStore &clusterStore)=0
Follow tracks in stations(1..) 3, 2 and 1.
Double_t GetMaxNonBendingSlope() const
return the maximum value of the non bending slope
Double_t GetDefaultBendingReso(Int_t iCh) const
Get the default bending resolution of chamber iCh.
virtual AliMUONGlobalTrigger * Global() const =0
Return global trigger.
void ChangeMonoCathodClusterRes(AliMUONTrack &track)
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 TagConnectedTracks(Int_t stMin, Int_t stMax, Bool_t all)
Base class of a trigger track store.
virtual Double_t GetErrY2() const =0
Return resolution**2 (cm**2) on coordinate Y.
void RemoveConnectedTracks(Int_t stMin, Int_t stMax, Bool_t all)
static Double_t GetMCSAngle2(const AliMUONTrackParam &param, Double_t dZ, Double_t x0)
void ExecuteValidation(const AliMUONVTrackStore &trackStore, const AliMUONVTriggerTrackStore &triggerTrackStore, const AliMUONVTriggerStore &triggerStore) const
void SetX11(Float_t x)
Set x position of fired Y strip in MC11.
static UInt_t BuildUniqueID(Int_t detElemId, Int_t manuId, Int_t manuChannel, Int_t cathode)
Bool_t IsValid() const
Return validity.
Definition: AliMpPad.h:89
static Int_t GetChamberId(UInt_t uniqueID)
Return chamber id (0..), part of the uniqueID.
void Connected(Bool_t flag=kTRUE)
set the flag which is kTRUE if that track shares cluster(s) with another
Definition: AliMUONTrack.h:147
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)
bending plane
virtual AliMpPad PadByPosition(Double_t x, Double_t y, Bool_t warning=true) const =0
Find pad by position.
void Global2Local(Int_t detElemId, Float_t xg, Float_t yg, Float_t zg, Float_t &xl, Float_t &yl, Float_t &zl) const
AliMp::CathodType GetCathodType(AliMp::PlaneType planeType) const
The abstract base class for the segmentation.
UChar_t GetGlobalResponse() const
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 SetRemovable(Bool_t removable)
set the flag telling whether the associated cluster can be removed from the track it belongs to or no...
Global trigger object.
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.
void SetY11(Float_t y)
Set y position of fired X strip in MC11.
Class which encapsuate all information about a pad.
Definition: AliMpPad.h:22
Float_t GetY11Width(Int_t localBoardId, Int_t istrip) const
static Int_t GetDetElemId(UInt_t uniqueID)
Return detection element id, part of the uniqueID.
virtual Double_t GetX() const =0
Return coordinate X (cm)
void SetZ11(Float_t z)
Set z position of fired X strip in MC11.
void RecursiveDump(void) const
void EventReconstructTrigger(const AliMUONTriggerCircuit &triggerCircuit, const AliMUONVTriggerStore &triggerStore, AliMUONVTriggerTrackStore &triggerTrackStore)
static Double_t TriggerNonBendingReso()
Return default trigger chamber resolution DUE TO ALIGNMENT ONLY in non bending direction.
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
static Bool_t IsFieldON()
return kTRUE if the field is switched ON
void SetCovariances(const TMatrixD &covariances)
virtual Bool_t Add(TObject *object)
Add an object, if of the right type.
Float_t GetY21Width(Int_t localBoardId, Int_t istrip) const
void SetGTPattern(UChar_t pat)
Set Global trigger pattern (do not work with static statement)
const AliMUONGeometryTransformer * fkTransformer
! geometry transformer (not owner)
const TMatrixD & GetCovariances() const
void EventReconstruct(AliMUONVClusterStore &clusterStore, AliMUONVTrackStore &trackStore)
static Double_t GetBendingMomentumFromImpactParam(Double_t impactParam)
Int_t LoCircuit() const
Return Circuit number.
TClonesArray * fRecTracksPtr
pointer to array of reconstructed tracks
The equivalent of a std::pair<TObject*,TObject*> ;-)
Float_t GetX11Pos(Int_t localBoardId, Int_t istrip) const
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
Float_t GetX11Width(Int_t localBoardId, Int_t istrip) const
TObjArray * GetTrackParamAtCluster() const
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)