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