Adding setters and getters to retrieve Local Trigger number from AliMUONTrack (Thanks...
[u/mrichter/AliRoot.git] / MUON / AliMUONTrack.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////
19 //
20 // Reconstructed track
21 // in
22 // ALICE
23 // dimuon
24 // spectrometer
25 //
26 ///////////////////////////////////////////////////
27
28 #include <stdlib.h> // for exit()
29 #include <Riostream.h>
30 #include <TMatrixD.h>
31
32 #include "AliMUONTrack.h"
33
34 #include "AliMUONTrackParam.h" 
35 #include "AliMUONHitForRec.h" 
36 #include "AliMUONConstants.h"
37 #include "AliMUONTrackExtrap.h" 
38
39 #include "AliLog.h"
40
41 #include <TMath.h>
42
43 /// \cond CLASSIMP
44 ClassImp(AliMUONTrack) // Class implementation in ROOT context
45 /// \endcond
46
47 const Double_t AliMUONTrack::fgkMaxTrackingDistanceBending    = 2.;
48 const Double_t AliMUONTrack::fgkMaxTrackingDistanceNonBending = 2.;
49
50 //__________________________________________________________________________
51 AliMUONTrack::AliMUONTrack()
52   : TObject(),
53     fTrackParamAtVertex(),
54     fTrackParamAtHit(0x0),
55     fHitForRecAtHit(0x0),
56     fNTrackHits(0),
57     fExtrapTrackParam(),
58     fFitWithVertex(kFALSE),
59     fVertex(0x0),
60     fFitFMin(-1.),
61     fMatchTrigger(kFALSE),
62     floTrgNum(-1),
63     fChi2MatchTrigger(0.),
64     fTrackID(0)
65 {
66   /// Default constructor
67 }
68
69   //__________________________________________________________________________
70 AliMUONTrack::AliMUONTrack(AliMUONHitForRec* hitForRec1, AliMUONHitForRec* hitForRec2)
71   : TObject(),
72     fTrackParamAtVertex(),
73     fTrackParamAtHit(0x0),
74     fHitForRecAtHit(0x0),
75     fNTrackHits(0),
76     fExtrapTrackParam(),
77     fFitWithVertex(kFALSE),
78     fVertex(0x0),
79     fFitFMin(-1.),
80     fMatchTrigger(kFALSE),
81     floTrgNum(-1),    
82     fChi2MatchTrigger(0.),
83     fTrackID(0)
84 {
85   /// Constructor from thw hitForRec's
86
87   fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10);
88   fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10);
89   
90   if (!hitForRec1) return; //AZ
91   
92   // Add hits to the track
93   AddTrackParamAtHit(0,hitForRec1);
94   AddTrackParamAtHit(0,hitForRec2);
95   
96   // sort TrackParamAtHit according to increasing -Z
97   fTrackParamAtHit->Sort();
98   
99   // Set track parameters at first track hit
100   AliMUONTrackParam* trackParamAtFirstHit = (AliMUONTrackParam*) fTrackParamAtHit->First();
101   AliMUONHitForRec* firstHit = trackParamAtFirstHit->GetHitForRecPtr();
102   AliMUONHitForRec* lastHit = ((AliMUONTrackParam*) fTrackParamAtHit->Last())->GetHitForRecPtr();
103   Double_t dZ = firstHit->GetZ() - lastHit->GetZ();
104   // Non bending plane
105   Double_t nonBendingCoor = firstHit->GetNonBendingCoor();
106   trackParamAtFirstHit->SetNonBendingCoor(nonBendingCoor);
107   trackParamAtFirstHit->SetNonBendingSlope((nonBendingCoor - lastHit->GetNonBendingCoor()) / dZ);
108   // Bending plane
109   Double_t bendingCoor = firstHit->GetBendingCoor();
110   trackParamAtFirstHit->SetBendingCoor(bendingCoor);
111   Double_t bendingSlope = (bendingCoor - lastHit->GetBendingCoor()) / dZ;
112   trackParamAtFirstHit->SetBendingSlope(bendingSlope);
113   // Inverse bending momentum
114   Double_t bendingImpact = bendingCoor - firstHit->GetZ() * bendingSlope;
115   Double_t inverseBendingMomentum = 1. / AliMUONTrackExtrap::GetBendingMomentumFromImpactParam(bendingImpact);
116   trackParamAtFirstHit->SetInverseBendingMomentum(inverseBendingMomentum);
117   
118   // Evaluate covariances
119   TMatrixD *paramCov = trackParamAtFirstHit->GetCovariances();
120   (*paramCov) = 0;
121   // Non bending plane
122   (*paramCov)(0,0) = firstHit->GetNonBendingReso2();
123   (*paramCov)(0,1) = firstHit->GetNonBendingReso2() / dZ;
124   (*paramCov)(1,0) = (*paramCov)(0,1);
125   (*paramCov)(1,1) = ( firstHit->GetNonBendingReso2() + lastHit->GetNonBendingReso2() ) / dZ / dZ;
126   // Bending plane
127   (*paramCov)(2,2) = firstHit->GetBendingReso2();
128   (*paramCov)(2,3) = firstHit->GetBendingReso2() / dZ;
129   (*paramCov)(3,2) = (*paramCov)(2,3);
130   (*paramCov)(3,3) = ( firstHit->GetBendingReso2() + lastHit->GetBendingReso2() ) / dZ / dZ;
131   // Inverse bending momentum (50% error)
132   (*paramCov)(4,4) = 0.5*inverseBendingMomentum * 0.5*inverseBendingMomentum;
133   
134 }
135
136   //__________________________________________________________________________
137 AliMUONTrack::~AliMUONTrack()
138 {
139   /// Destructor
140   if (fTrackParamAtHit) {
141     // delete the TClonesArray of pointers to TrackParam
142     delete fTrackParamAtHit;
143     fTrackParamAtHit = 0x0;
144   }
145
146   if (fHitForRecAtHit) {
147     // delete the TClonesArray of pointers to HitForRec
148     delete fHitForRecAtHit;
149     fHitForRecAtHit = 0x0;
150   }
151   
152   if (fVertex) {
153     // delete the vertex used during the tracking procedure
154     delete fVertex;
155     fVertex = 0x0;
156   }
157 }
158
159   //__________________________________________________________________________
160 AliMUONTrack::AliMUONTrack (const AliMUONTrack& theMUONTrack)
161   : TObject(theMUONTrack),
162     fTrackParamAtVertex(theMUONTrack.fTrackParamAtVertex),
163     fTrackParamAtHit(0x0),
164     fHitForRecAtHit(0x0),
165     fNTrackHits(theMUONTrack.fNTrackHits),
166     fExtrapTrackParam(theMUONTrack.fExtrapTrackParam),
167     fFitWithVertex(theMUONTrack.fFitWithVertex),
168     fVertex(0x0),
169     fFitFMin(theMUONTrack.fFitFMin),
170     fMatchTrigger(theMUONTrack.fMatchTrigger),
171     floTrgNum(theMUONTrack.floTrgNum),    
172     fChi2MatchTrigger(theMUONTrack.fChi2MatchTrigger),
173     fTrackID(theMUONTrack.fTrackID)
174 {
175   ///copy constructor
176   Int_t maxIndex = 0;
177   
178   // necessary to make a copy of the objects and not only the pointers in TClonesArray.
179   if (theMUONTrack.fTrackParamAtHit) {
180     maxIndex = (theMUONTrack.fTrackParamAtHit)->GetEntriesFast();
181     fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",maxIndex);
182     for (Int_t index = 0; index < maxIndex; index++) {
183       new ((*fTrackParamAtHit)[index]) AliMUONTrackParam(*(AliMUONTrackParam*)theMUONTrack.fTrackParamAtHit->At(index));
184     }
185   }
186   
187   // necessary to make a copy of the objects and not only the pointers in TClonesArray.
188   if (theMUONTrack.fHitForRecAtHit) {
189     maxIndex = (theMUONTrack.fHitForRecAtHit)->GetEntriesFast();
190     fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",maxIndex);
191     for (Int_t index = 0; index < maxIndex; index++) {
192       new ((*fHitForRecAtHit)[index]) AliMUONHitForRec(*(AliMUONHitForRec*)theMUONTrack.fHitForRecAtHit->At(index));
193     }
194   }
195   
196   // copy vertex used during the tracking procedure if any
197   if (theMUONTrack.fVertex) fVertex = new AliMUONHitForRec(*(theMUONTrack.fVertex));
198   
199 }
200
201   //__________________________________________________________________________
202 AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& theMUONTrack)
203 {
204   /// Asignment operator
205   // check assignement to self
206   if (this == &theMUONTrack)
207     return *this;
208
209   // base class assignement
210   TObject::operator=(theMUONTrack);
211
212   fTrackParamAtVertex = theMUONTrack.fTrackParamAtVertex;
213
214   Int_t maxIndex = 0;
215   
216   // necessary to make a copy of the objects and not only the pointers in TClonesArray.
217   if (theMUONTrack.fTrackParamAtHit) {
218     if (fTrackParamAtHit) fTrackParamAtHit->Clear();
219     else fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10);
220     maxIndex = (theMUONTrack.fTrackParamAtHit)->GetEntriesFast();
221     for (Int_t index = 0; index < maxIndex; index++) {
222       new ((*fTrackParamAtHit)[fTrackParamAtHit->GetEntriesFast()])
223         AliMUONTrackParam(*(AliMUONTrackParam*)(theMUONTrack.fTrackParamAtHit)->At(index));
224     }
225   } else if (fTrackParamAtHit) {
226     delete fTrackParamAtHit;
227     fTrackParamAtHit = 0x0;
228   }
229
230   // necessary to make a copy of the objects and not only the pointers in TClonesArray.
231   if (theMUONTrack.fHitForRecAtHit) {
232     if (fHitForRecAtHit) fHitForRecAtHit->Clear();
233     else fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10);
234     maxIndex = (theMUONTrack.fHitForRecAtHit)->GetEntriesFast();
235     for (Int_t index = 0; index < maxIndex; index++) {
236       new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()])
237         AliMUONHitForRec(*(AliMUONHitForRec*)(theMUONTrack.fHitForRecAtHit)->At(index));
238     }
239   } else if (fHitForRecAtHit) {
240     delete fHitForRecAtHit;
241     fHitForRecAtHit = 0x0;
242   }
243   
244   // copy vertex used during the tracking procedure if any.
245   if (theMUONTrack.fVertex) {
246     if (fVertex) *fVertex = *(theMUONTrack.fVertex);
247     else fVertex = new AliMUONHitForRec(*(theMUONTrack.fVertex));
248   } else if (fVertex) {
249     delete fVertex;
250     fVertex = 0x0;
251   }
252   
253   fExtrapTrackParam = theMUONTrack.fExtrapTrackParam;
254   
255   fNTrackHits         =  theMUONTrack.fNTrackHits;
256   fFitWithVertex      =  theMUONTrack.fFitWithVertex;
257   fFitFMin            =  theMUONTrack.fFitFMin;
258   fMatchTrigger       =  theMUONTrack.fMatchTrigger;
259   floTrgNum           =  theMUONTrack.floTrgNum;
260   fChi2MatchTrigger   =  theMUONTrack.fChi2MatchTrigger;
261   fTrackID            =  theMUONTrack.fTrackID;
262
263   return *this;
264 }
265
266   //__________________________________________________________________________
267 void AliMUONTrack::AddTrackParamAtHit(AliMUONTrackParam *trackParam, AliMUONHitForRec *hitForRec) 
268 {
269   /// Add TrackParamAtHit if "trackParam" != NULL
270   /// else create empty TrackParamAtHit and set the z position to the one of "hitForRec" if any
271   /// Update link to HitForRec if "hitForRec" != NULL
272   if (!fTrackParamAtHit) {
273     fTrackParamAtHit = new TClonesArray("AliMUONTrackParam",10);  
274     fNTrackHits = 0;
275   }
276   AliMUONTrackParam* trackParamAtHit;
277   if (trackParam) {
278     trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam(*trackParam);
279     if (hitForRec) {
280       if (hitForRec->GetZ() != trackParam->GetZ())
281         AliWarning("Added track parameters at a different z position than the one of the attached hit");
282     }
283   } else {
284     trackParamAtHit = new ((*fTrackParamAtHit)[fNTrackHits]) AliMUONTrackParam();
285     if (hitForRec) ((AliMUONTrackParam*) fTrackParamAtHit->UncheckedAt(fNTrackHits))->SetZ(hitForRec->GetZ());
286   }
287   if (hitForRec) trackParamAtHit->SetHitForRecPtr(hitForRec);
288   fNTrackHits++;
289 }
290
291   //__________________________________________________________________________
292 void AliMUONTrack::AddHitForRecAtHit(const AliMUONHitForRec *hitForRec) 
293 {
294   /// Add hitForRec to the array of hitForRec at hit
295   if (!fHitForRecAtHit)
296     fHitForRecAtHit = new TClonesArray("AliMUONHitForRec",10); 
297   
298   if (!hitForRec)
299     AliFatal("AliMUONTrack::AddHitForRecAtHit: hitForRec == NULL");
300   
301   new ((*fHitForRecAtHit)[fHitForRecAtHit->GetEntriesFast()]) AliMUONHitForRec(*hitForRec);
302 }
303
304   //__________________________________________________________________________
305 void AliMUONTrack::SetVertex(AliMUONHitForRec* vertex)
306 {
307   /// Set the vertex used during the tracking procedure
308   if (!fVertex) fVertex = new AliMUONHitForRec(*vertex);
309   else *fVertex = *vertex;
310 }
311
312   //__________________________________________________________________________
313 Int_t AliMUONTrack::HitsInCommon(AliMUONTrack* track) const
314 {
315   /// Returns the number of hits in common between the current track ("this")
316   /// and the track pointed to by "track".
317   Int_t hitsInCommon = 0;
318   AliMUONTrackParam *trackParamAtHit1, *trackParamAtHit2;
319   // Loop over hits of first track
320   trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->First();
321   while (trackParamAtHit1) {
322     // Loop over hits of second track
323     trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->First();
324     while (trackParamAtHit2) {
325       // Increment "hitsInCommon" if both TrackParamAtHits point to the same HitForRec
326       if ((trackParamAtHit1->GetHitForRecPtr()) == (trackParamAtHit2->GetHitForRecPtr())) {
327         hitsInCommon++;
328         break;
329       }
330       trackParamAtHit2 = (AliMUONTrackParam*) track->fTrackParamAtHit->After(trackParamAtHit2);
331     } // trackParamAtHit2
332     trackParamAtHit1 = (AliMUONTrackParam*) this->fTrackParamAtHit->After(trackParamAtHit1);
333   } // trackParamAtHit1
334   return hitsInCommon;
335 }
336
337   //__________________________________________________________________________
338 Bool_t* AliMUONTrack::CompatibleTrack(AliMUONTrack * track, Double_t sigma2Cut) const
339 {
340   /// Return kTRUE/kFALSE for each chamber if hit is compatible or not 
341   TClonesArray *hitArray, *thisHitArray;
342   AliMUONHitForRec *hit, *thisHit;
343   Int_t chamberNumber;
344   Float_t deltaZ;
345   Float_t deltaZMax = 1.; // 1 cm
346   Float_t chi2 = 0;
347   Bool_t *nCompHit = new Bool_t[AliMUONConstants::NTrackingCh()]; 
348
349   for ( Int_t ch = 0; ch < AliMUONConstants::NTrackingCh(); ch++) {
350     nCompHit[ch] = kFALSE;
351   }
352
353   thisHitArray = this->GetHitForRecAtHit();
354
355   hitArray =  track->GetHitForRecAtHit();
356
357   for (Int_t iHthis = 0; iHthis < thisHitArray->GetEntriesFast(); iHthis++) {
358     thisHit = (AliMUONHitForRec*) thisHitArray->At(iHthis);
359     chamberNumber = thisHit->GetChamberNumber();
360     if (chamberNumber < 0 || chamberNumber > AliMUONConstants::NTrackingCh()) continue; 
361     nCompHit[chamberNumber] = kFALSE;
362     for (Int_t iH = 0; iH < hitArray->GetEntriesFast(); iH++) {
363       hit = (AliMUONHitForRec*) hitArray->At(iH);
364       deltaZ = TMath::Abs(thisHit->GetZ() - hit->GetZ());
365       chi2 = thisHit->NormalizedChi2WithHitForRec(hit,sigma2Cut); // set cut to 4 sigmas
366       if (chi2 < 3. && deltaZ < deltaZMax) {
367         nCompHit[chamberNumber] = kTRUE;
368         break;
369       }
370     }  
371   }
372   
373   return nCompHit;
374 }
375
376   //__________________________________________________________________________
377 Double_t AliMUONTrack::TryOneHitForRec(AliMUONHitForRec* hitForRec)
378 {
379 /// Test the compatibility between the track and the hitForRec:
380 /// return the corresponding Chi2
381   
382   // Get track parameters and their covariances at the z position of hitForRec
383   AliMUONTrackParam extrapTrackParam(fExtrapTrackParam);
384   AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam, hitForRec->GetZ());
385   
386   // Set differences between trackParam and hitForRec in the bending and non bending directions
387   TMatrixD dPos(2,1);
388   dPos(0,0) = hitForRec->GetNonBendingCoor() - extrapTrackParam.GetNonBendingCoor();
389   dPos(1,0) = hitForRec->GetBendingCoor() - extrapTrackParam.GetBendingCoor();
390   
391   // quick test of hitForRec compatibility within a wide road of x*y = 10*1 cm2 to save computing time
392   if (TMath::Abs(dPos(0,0)) > fgkMaxTrackingDistanceNonBending ||
393       TMath::Abs(dPos(1,0)) > fgkMaxTrackingDistanceBending) return 1.e10;
394   
395   // Set the error matrix from trackParam covariances and hitForRec resolution
396   TMatrixD* paramCov = extrapTrackParam.GetCovariances();
397   TMatrixD error(2,2);
398   error(0,0) = (*paramCov)(0,0) + hitForRec->GetNonBendingReso2();
399   error(0,1) = (*paramCov)(0,2);
400   error(1,0) = (*paramCov)(2,0);
401   error(1,1) = (*paramCov)(2,2) + hitForRec->GetBendingReso2();
402   
403   // Invert the error matrix for Chi2 calculation
404   if (error.Determinant() != 0) {
405     error.Invert();
406   } else {
407     AliWarning(" Determinant error=0");
408     return 1.e10;
409   }
410   
411   // Compute the Chi2 value
412   TMatrixD tmp(error,TMatrixD::kMult,dPos);
413   TMatrixD result(dPos,TMatrixD::kTransposeMult,tmp);
414   
415   return result(0,0);
416   
417 }
418
419   //__________________________________________________________________________
420 Double_t AliMUONTrack::TryTwoHitForRec(AliMUONHitForRec* hitForRec1, AliMUONHitForRec* hitForRec2)
421 {
422 /// Test the compatibility between the track and the 2 hitForRec together:
423 /// return the corresponding Chi2 accounting for covariances between the 2 hitForRec
424   
425   // Get track parameters and their covariances at the z position of the first hitForRec
426   AliMUONTrackParam extrapTrackParam1(fExtrapTrackParam);
427   AliMUONTrackExtrap::ExtrapToZCov(&extrapTrackParam1, hitForRec1->GetZ());
428   
429   // Get track parameters at second hitForRec
430   AliMUONTrackParam extrapTrackParam2(extrapTrackParam1);
431   AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam2, hitForRec2->GetZ());
432   
433   // Set differences between track and the 2 hitForRec in the bending and non bending directions
434   TMatrixD dPos(4,1);
435   dPos(0,0) = hitForRec1->GetNonBendingCoor() - extrapTrackParam1.GetNonBendingCoor();
436   dPos(1,0) = hitForRec1->GetBendingCoor() - extrapTrackParam1.GetBendingCoor();
437   dPos(2,0) = hitForRec2->GetNonBendingCoor() - extrapTrackParam2.GetNonBendingCoor();
438   dPos(3,0) = hitForRec2->GetBendingCoor() - extrapTrackParam2.GetBendingCoor();
439   
440   // quick tests of hitForRec compatibility within a wide road of x*y = 1*1 cm2 to save computing time
441   if (TMath::Abs(dPos(0,0)) > fgkMaxTrackingDistanceNonBending ||
442       TMath::Abs(dPos(1,0)) > fgkMaxTrackingDistanceBending    ||
443       TMath::Abs(dPos(2,0)) > fgkMaxTrackingDistanceNonBending ||
444       TMath::Abs(dPos(3,0)) > fgkMaxTrackingDistanceBending) return 1.e10;
445   
446   // Calculate the error matrix from the track parameter covariances at first hitForRec
447   TMatrixD error(4,4);
448   error = 0.;
449   if (extrapTrackParam1.CovariancesExist()) {
450     // Get the pointer to the parameter covariance matrix at first hitForRec
451     TMatrixD* paramCov = extrapTrackParam1.GetCovariances();
452     
453     // Save track parameters at first hitForRec
454     AliMUONTrackParam extrapTrackParam1Save(extrapTrackParam1);
455     Double_t nonBendingCoor1         = extrapTrackParam1Save.GetNonBendingCoor();
456     Double_t nonBendingSlope1        = extrapTrackParam1Save.GetNonBendingSlope();
457     Double_t bendingCoor1            = extrapTrackParam1Save.GetBendingCoor();
458     Double_t bendingSlope1           = extrapTrackParam1Save.GetBendingSlope();
459     Double_t inverseBendingMomentum1 = extrapTrackParam1Save.GetInverseBendingMomentum();
460     Double_t z1                      = extrapTrackParam1Save.GetZ();
461     
462     // Save track coordinates at second hitForRec
463     Double_t nonBendingCoor2         = extrapTrackParam2.GetNonBendingCoor();
464     Double_t bendingCoor2            = extrapTrackParam2.GetBendingCoor();
465     
466     // Calculate the jacobian related to the transformation between track parameters
467     // at first hitForRec and track coordinates at the 2 hitForRec z-position
468     TMatrixD jacob(4,5);
469     jacob = 0.;
470     // first derivative at the first hitForRec:
471     jacob(0,0) = 1.; // dx1/dx
472     jacob(1,2) = 1.; // dy1/dy
473     // first derivative at the second hitForRec:
474     Double_t dParam[5];
475     for (Int_t i=0; i<5; i++) {
476       // Skip jacobian calculation for parameters with no associated error
477       if ((*paramCov)(i,i) == 0.) continue;
478       // Small variation of parameter i only
479       for (Int_t j=0; j<5; j++) {
480         if (j==i) {
481           dParam[j] = TMath::Sqrt((*paramCov)(i,i));
482           if (j == 4) dParam[j] *= TMath::Sign(1.,-inverseBendingMomentum1); // variation always in the same direction
483         } else dParam[j] = 0.;
484       }
485       // Set new track parameters at first hitForRec
486       extrapTrackParam1Save.SetNonBendingCoor        (nonBendingCoor1         + dParam[0]);
487       extrapTrackParam1Save.SetNonBendingSlope       (nonBendingSlope1        + dParam[1]);
488       extrapTrackParam1Save.SetBendingCoor           (bendingCoor1            + dParam[2]);
489       extrapTrackParam1Save.SetBendingSlope          (bendingSlope1           + dParam[3]);
490       extrapTrackParam1Save.SetInverseBendingMomentum(inverseBendingMomentum1 + dParam[4]);
491       extrapTrackParam1Save.SetZ                     (z1);
492       // Extrapolate new track parameters to the z position of the second hitForRec
493       AliMUONTrackExtrap::ExtrapToZ(&extrapTrackParam1Save,hitForRec2->GetZ());
494       // Calculate the jacobian
495       jacob(2,i) = (extrapTrackParam1Save.GetNonBendingCoor()  - nonBendingCoor2) / dParam[i]; // dx2/dParami
496       jacob(3,i) = (extrapTrackParam1Save.GetBendingCoor()     - bendingCoor2   ) / dParam[i]; // dy2/dParami
497     }
498     
499     // Calculate the error matrix
500     TMatrixD tmp((*paramCov),TMatrixD::kMultTranspose,jacob);
501     error = TMatrixD(jacob,TMatrixD::kMult,tmp);
502   }
503   
504   // Add hitForRec resolution to the error matrix
505   error(0,0) += hitForRec1->GetNonBendingReso2();
506   error(1,1) += hitForRec1->GetBendingReso2();
507   error(2,2) += hitForRec2->GetNonBendingReso2();
508   error(3,3) += hitForRec2->GetBendingReso2();
509   
510   // invert the error matrix for Chi2 calculation
511   if (error.Determinant() != 0) {
512     error.Invert();
513   } else {
514     AliWarning(" Determinant error=0");
515     return 1.e10;
516   }
517   
518   // Compute the Chi2 value
519   TMatrixD tmp2(error,TMatrixD::kMult,dPos);
520   TMatrixD result(dPos,TMatrixD::kTransposeMult,tmp2);
521   
522   return result(0,0);
523   
524 }
525
526   //__________________________________________________________________________
527 void AliMUONTrack::RecursiveDump(void) const
528 {
529   /// Recursive dump of AliMUONTrack, i.e. with dump of TrackParamAtHit's and attached HitForRec's
530   AliMUONTrackParam *trackParamAtHit;
531   AliMUONHitForRec *hitForRec;
532   cout << "Recursive dump of Track: " << this << endl;
533   // Track
534   this->Dump();
535   for (Int_t trackHitIndex = 0; trackHitIndex < fNTrackHits; trackHitIndex++) {
536     trackParamAtHit = (AliMUONTrackParam*) ((*fTrackParamAtHit)[trackHitIndex]);
537     // TrackHit
538     cout << "TrackParamAtHit: " << trackParamAtHit << " (index: " << trackHitIndex << ")" << endl;
539     trackParamAtHit->Dump();
540     hitForRec = trackParamAtHit->GetHitForRecPtr();
541     // HitForRec
542     cout << "HitForRec: " << hitForRec << endl;
543     hitForRec->Dump();
544   }
545   return;
546 }
547   
548 //_____________________________________________-
549 void AliMUONTrack::Print(Option_t* opt) const
550 {
551   /// Printing Track information 
552   /// "full" option for printing all the information about the track
553   TString sopt(opt);
554   sopt.ToUpper();
555  
556   if ( sopt.Contains("FULL") ) { 
557     cout << "<AliMUONTrack> No.Clusters=" << setw(2)   << GetNTrackHits() << 
558       //      ", Bending P="<< setw(8) << setprecision(5)      << 1./GetInverseBendingMomentum() << 
559       //", NonBendSlope=" << setw(8) << setprecision(5)  << GetNonBendingSlope()*180./TMath::Pi() <<
560       //", BendSlope=" << setw(8) << setprecision(5)     << GetBendingSlope()*180./TMath::Pi() <<
561       ", Match2Trig=" << setw(1) << GetMatchTrigger()  << 
562       ", LoTrgNum=" << setw(3) << GetLoTrgNum()  << 
563       ", Chi2-tracking-trigger=" << setw(8) << setprecision(5) <<  GetChi2MatchTrigger() << endl ;
564     GetTrackParamAtHit()->First()->Print("full");
565   }
566   else {
567     cout << "<AliMUONTrack>";
568     GetTrackParamAtHit()->First()->Print("");
569
570   }
571     
572 }