]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCConfMapFit.cxx
first steps to set the covariance matrix from the errors calculated in conformal...
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCConfMapFit.cxx
1 // @(#) $Id$
2 // Original: AliHLTConfMapFit.cxx,v 1.14 2005/06/14 10:55:21 cvetan 
3
4 /**************************************************************************
5  * This file is property of and copyright by the ALICE HLT Project        * 
6  * ALICE Experiment at CERN, All rights reserved.                         *
7  *                                                                        *
8  * Primary Authors: Anders Vestbo, maintained by                          *
9  *                  Matthias Richter <Matthias.Richter@ift.uib.no>        *
10  *                  for The ALICE HLT Project.                            *
11  *                                                                        *
12  * Permission to use, copy, modify and distribute this software and its   *
13  * documentation strictly for non-commercial purposes is hereby granted   *
14  * without fee, provided that the above copyright notice appears in all   *
15  * copies and that both the copyright notice and this permission notice   *
16  * appear in the supporting documentation. The authors make no claims     *
17  * about the suitability of this software for any purpose. It is          *
18  * provided "as is" without express or implied warranty.                  *
19  **************************************************************************/
20
21 /** @file   AliHLTTPCConfMapFit.cxx
22     @author Anders Vestbo, maintained by Matthias Richter
23     @date   
24     @brief  Fit class for conformal mapping tracking.
25 */
26
27 // see header file for class documentation                                   //
28 // or                                                                        //
29 // refer to README to build package                                          //
30 // or                                                                        //
31 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt                          //
32
33 #include "AliHLTTPCRootTypes.h"
34 #include "AliHLTTPCLogging.h"
35 #include "AliHLTTPCVertex.h"
36 #include "AliHLTTPCConfMapTrack.h"
37 #include "AliHLTTPCConfMapPoint.h"
38 #include "AliHLTTPCTransform.h"
39 #include "AliHLTTPCConfMapFit.h"
40
41 #if __GNUC__ >= 3
42 using namespace std;
43 #endif
44
45 ClassImp(AliHLTTPCConfMapFit);
46
47 AliHLTTPCConfMapFit::AliHLTTPCConfMapFit()
48   :
49   fTrack(NULL),
50   fVertex(NULL)
51 {
52   //constructor
53 }
54
55 AliHLTTPCConfMapFit::AliHLTTPCConfMapFit(AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex)
56   :
57   fTrack(track),
58   fVertex(vertex)
59
60 {
61   //constructor
62 }
63
64 AliHLTTPCConfMapFit::~AliHLTTPCConfMapFit()
65 {
66   // destructor
67 }
68
69 Int_t AliHLTTPCConfMapFit::FitHelix()
70 {
71   //fit the helix
72   if(FitCircle())
73     {
74       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
75         "Problems during circle fit"<<ENDLOG;
76       return 1;
77     }
78   if(FitLine())
79     {
80       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
81         "Problems during line fit"<<ENDLOG;
82       return 1;
83     }
84   return 0;
85 }
86
87 Int_t AliHLTTPCConfMapFit::FitStraightLine() {
88     //fit the straight line 
89     if(FitLineXY()) {
90         LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitStraightLine","TrackFit")<<AliHLTTPCLog::kDec<<
91             "Problems during stright line fit in XY plane"<<ENDLOG;
92         return 1;
93     }
94     if(FitLineSZ()){
95         LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitStraightLine","TrackFit")<<AliHLTTPCLog::kDec<<
96             "Problems during stright line fit in SZ plane"<<ENDLOG;
97         return 1;
98     }
99     return 0;
100 }
101
102 Int_t AliHLTTPCConfMapFit::FitCircle()
103 {
104   //-----------------------------------------------------------------
105   //Fits circle parameters using algorithm
106   //described by ChErnov and Oskov in Computer Physics
107   //Communications.
108   // 
109   //Written in FORTRAN by Jawluen Tang, Physics department , UT-Austin 
110   //Moved to C by Pablo Yepes
111   //Moved to AliROOT by ASV.
112   //------------------------------------------------------------------
113   
114   Double_t wsum  = 0.0 ;
115   Double_t xav   = 0.0 ;
116   Double_t yav   = 0.0 ;
117   
118   Int_t numOfHits = fTrack->GetNumberOfPoints();
119   //
120   //     Loop over hits calculating average
121   Int_t co=0;
122   
123   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
124     {
125       co++;
126       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
127       cHit->SetXYWeight( 1./ (Double_t)(cHit->GetXerr()*cHit->GetXerr() + cHit->GetYerr()*cHit->GetYerr()) );
128       wsum      += cHit->GetXYWeight() ;
129       xav       += cHit->GetXYWeight() * cHit->GetX() ;
130       yav       += cHit->GetXYWeight() * cHit->GetY() ;
131     }
132   if(co!=numOfHits) 
133     LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
134       "Mismatch of hits. Counter: "<<co<<" nHits: "<<numOfHits<<ENDLOG;
135   if (fTrack->ComesFromMainVertex() == true)
136     {    
137       wsum += fVertex->GetXYWeight() ;
138       xav  += fVertex->GetX() ;
139       yav  += fVertex->GetY() ;
140     }
141   
142   xav = xav / wsum ;
143   yav = yav / wsum ;
144 //
145 //  CALCULATE <X**2>, <XY>, AND <Y**2> WITH <X> = 0, & <Y> = 0
146 //
147   Double_t xxav  = 0.0 ;
148   Double_t xyav  = 0.0 ; 
149   Double_t yyav  = 0.0 ;
150   Double_t xi, yi ;
151
152   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
153     { 
154       //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint *)hits->At(hit_counter);
155       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
156       xi        = cHit->GetX() - xav ;
157       yi        = cHit->GetY() - yav ;
158       xxav     += xi * xi * cHit->GetXYWeight() ;
159       xyav     += xi * yi * cHit->GetXYWeight() ;
160       yyav     += yi * yi * cHit->GetXYWeight() ;
161     }
162   
163   if (fTrack->ComesFromMainVertex() == true)
164     {
165       xi        = fVertex->GetX() - xav ;
166       yi        = fVertex->GetY() - yav ;
167       xxav     += xi * xi * fVertex->GetXYWeight() ;
168       xyav     += xi * yi * fVertex->GetXYWeight() ;
169       yyav     += yi * yi * fVertex->GetXYWeight() ; 
170     }
171   xxav = xxav / wsum ;
172   xyav = xyav / wsum ;
173   yyav = yyav / wsum ;
174 //
175 //-->  ROTATE COORDINATES SO THAT <XY> = 0
176 //
177 //-->  SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
178 //-->  &                                     > ==> NEW : (XXAV-YYAV) > 0
179 //-->  SIGN(S) = SIGN(XYAV)                  >
180
181   Double_t a = fabs( xxav - yyav ) ;
182   Double_t b = 4.0 * xyav * xyav ;
183
184   Double_t asqpb  = a * a + b  ;
185   Double_t rasqpb = sqrt ( asqpb) ;
186
187   Double_t splus  = 1.0 + a / rasqpb ;
188   Double_t sminus = b / (asqpb * splus) ;
189
190   splus  = sqrt (0.5 * splus ) ;
191   sminus = sqrt (0.5 * sminus) ;
192 //
193 //->  FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
194 //
195   Double_t sinrot, cosrot ;
196   if ( xxav <= yyav ) {
197          cosrot = sminus ;
198          sinrot = splus  ;
199   }
200   else {
201           cosrot = splus ;
202           sinrot = sminus ;
203   }
204 //
205 //->  REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
206 //
207   if ( xyav < 0.0 ) sinrot = - sinrot ;
208 //
209 //-->  WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
210 //-->  TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
211 //-->  OUTWARD FROM THE ORGIN.  WE ARE FREE TO CHANGE SIGNS OF BOTH
212 //-->  COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
213 //
214 //-->  CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
215 //
216   if ( cosrot*xav+sinrot*yav < 0.0 ) {
217           cosrot = -cosrot ;
218           sinrot = -sinrot ;
219   }
220 //
221 //->  NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
222 //
223   Double_t rrav   = xxav + yyav ;
224   Double_t rscale = sqrt(rrav) ;
225
226   xxav   = 0.0 ;
227   yyav   = 0.0 ;
228   xyav   = 0.0 ;
229   Double_t xrrav = 0.0 ;
230   Double_t yrrav = 0.0 ;
231   Double_t rrrrav  = 0.0 ;
232
233   Double_t xixi, yiyi, riri, wiriri, xold, yold ;
234   
235   //for (hit_counter=0; hit_counter<numOfHits; hit_counter++) 
236   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
237     { 
238       //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);  
239       AliHLTTPCConfMapPoint* cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
240
241       xold = cHit->GetX() - xav ;
242       yold = cHit->GetY() - yav ;
243       //
244       //-->  ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
245       //
246       xi = (  cosrot * xold + sinrot * yold ) / rscale ;
247       yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
248       
249       xixi   = xi * xi ;
250       yiyi   = yi * yi ;
251       riri   = xixi + yiyi ;
252       wiriri = cHit->GetXYWeight() * riri ;
253       
254       xyav   += cHit->GetXYWeight() * xi * yi ;
255       xxav   += cHit->GetXYWeight() * xixi ;
256       yyav   += cHit->GetXYWeight() * yiyi ;
257       
258       xrrav  += wiriri * xi ;
259       yrrav  += wiriri * yi ;
260       rrrrav += wiriri * riri ;
261     }
262   //
263 //   Include vertex if required
264 //
265   if (fTrack->ComesFromMainVertex() == true)
266     {
267         xold = fVertex->GetX() - xav ;
268         yold = fVertex->GetY() - yav ;
269         //
270         //-->  ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
271         //
272         xi = (  cosrot * xold + sinrot * yold ) / rscale ;
273         yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
274         
275         xixi   = xi * xi ;
276         yiyi   = yi * yi ;
277         riri   = xixi + yiyi ;
278         wiriri = fVertex->GetXYWeight() * riri ;
279
280         xyav   += fVertex->GetXYWeight() * xi * yi ;
281         xxav   += fVertex->GetXYWeight() * xixi ;
282         yyav   += fVertex->GetXYWeight() * yiyi ;
283
284         xrrav  += wiriri * xi ;
285         yrrav  += wiriri * yi ;
286         rrrrav += wiriri * riri ;
287   }
288   //
289   //    
290   //
291   //-->  DIVIDE BY WSUM TO MAKE AVERAGES
292   //
293   xxav    = xxav   / wsum ;
294   yyav    = yyav   / wsum ;
295   xrrav   = xrrav  / wsum ;
296   yrrav   = yrrav  / wsum ;
297   rrrrav  = rrrrav / wsum ;
298   xyav    = xyav   / wsum ;
299
300   const Int_t ntry = 5 ;
301 //
302 //-->  USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
303 //-->  DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
304 //
305   Double_t xrrxrr = xrrav * xrrav ;
306   Double_t yrryrr = yrrav * yrrav ;
307   Double_t rrrrm1 = rrrrav - 1.0  ;
308   Double_t xxyy   = xxav  * yyav  ;        
309
310   Double_t c0  =          rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
311   Double_t c1  =        - rrrrm1      + xrrxrr      + yrryrr   - 4.0*xxyy ;        
312   Double_t c2  =   4.0  + rrrrm1                               - 4.0*xxyy ;           
313   Double_t c4  = - 4.0  ;                
314 //
315 //-->  COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
316 //
317   Double_t c2d =   2.0 * c2 ;
318   Double_t c4d =   4.0 * c4 ;
319 //
320 //-->  0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
321 //
322 //   LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
323   Double_t lamda  = 0.0 ;
324   Double_t dlamda = 0.0 ;
325 //
326   Double_t chiscl = wsum * rscale * rscale ;
327   Double_t dlamax = 0.001 / chiscl ;   
328    
329   Double_t p, pd ;
330   for ( int itry = 1 ; itry <= ntry ; itry++ ) {
331      p      = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
332      pd     = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
333      dlamda = -p / pd ;
334      lamda  = lamda + dlamda ;
335      if (fabs(dlamda)<   dlamax) break ;
336   }
337
338   Double_t chi2 = (Double_t)(chiscl * lamda) ;
339  
340   fTrack->SetChiSq1(chi2);
341   // Double_t dchisq = chiscl * dlamda ;             
342 //
343 //-->  NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
344 //
345   Double_t h11   = xxav  -     lamda ;
346   Double_t h14   = xrrav ;
347   Double_t h22   = yyav  -     lamda ; 
348   Double_t h24   = yrrav ;
349   Double_t h34   = 1.0   + 2.0*lamda ;
350   if ( h11 == 0.0 || h22 == 0.0 ){
351     LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
352       "Problems fitting circle"<<ENDLOG;
353     return 1 ;
354   }
355   Double_t rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
356
357   Double_t ratio, kappa, beta ;
358   if ( fabs(h22) > fabs(h24) ) {
359      ratio  = h24 / h22 ;
360      rootsq = ratio * ratio + rootsq ;
361      kappa = 1.0 / sqrt(rootsq) ;
362      beta  = - ratio * kappa ;
363   }
364   else {
365      ratio  = h22 / h24 ;
366      rootsq = 1.0 + ratio * ratio * rootsq ;
367      beta  = 1.0 / sqrt(rootsq) ;
368      if ( h24 > 0 ) beta = - beta ;
369      kappa = -ratio * beta ;
370   }            
371   Double_t alpha = - (h14/h11) * kappa ;
372 //
373 //-->  transform these into the lab coordinate system
374 //-->  first get kappa and back to real dimensions
375 //
376   Double_t kappa1 = kappa / rscale ;
377   Double_t dbro   = 0.5   / kappa1 ;
378 //
379 //-->  next rotate alpha and beta and scale
380 //
381   Double_t alphar = (cosrot * alpha - sinrot * beta)* dbro ;
382   Double_t betar  = (sinrot * alpha + cosrot * beta)* dbro ;
383 //
384 //-->  then translate by (xav,yav)
385 //
386   Double_t acent  = (double)(xav - alphar) ;
387   Double_t bcent  = (double)(yav - betar ) ;
388   Double_t radius = (double)dbro ;
389 //
390 //   Get charge
391 //
392   Int_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
393
394   fTrack->SetCharge(q);
395   
396   
397   //Set the first point on the track to the space point coordinates of the innermost track
398   //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
399   Double_t x0,y0,psi,pt ;
400   AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fTrack->GetLastHit();
401   x0 = lHit->GetX();
402   y0 = lHit->GetY();
403   fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLine
404
405   psi  = (Double_t)atan2(bcent-y0,acent-x0) ;
406   psi  = psi + q * AliHLTTPCTransform::PiHalf();
407   if ( psi < 0 ) psi = psi + AliHLTTPCTransform::TwoPi();
408   pt   = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * radius ) ;
409   
410   //Update the track parameters with the parameters from this fit:
411   fTrack->SetPsi(psi);
412   fTrack->SetPt(pt);
413   fTrack->SetRadius(radius);
414   fTrack->SetCenterX(acent);
415   fTrack->SetCenterY(bcent);
416
417   //set error for pT and Y. psi, Z and Tgl are set.
418
419   //
420 //    Get errors from fast fit
421 //
422   //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
423 //
424   return 0 ;
425   
426 }
427
428 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
429 //    Fit Line in s-z plane
430 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
431 Int_t AliHLTTPCConfMapFit::FitLine ( )
432 {
433   //
434   //Initialization 
435   //
436   Double_t sum = 0.F ;
437   Double_t ss  = 0.F ;
438   Double_t sz  = 0.F ;
439   Double_t sss = 0.F ;
440   Double_t ssz = 0.F ;
441   //
442   //find sum , sums ,sumz, sumss 
443   // 
444   Double_t dx, dy ;
445   Double_t radius = (Double_t)(fTrack->GetPt() / AliHLTTPCTransform::GetBFieldValue() ) ;
446
447   //TObjArray *hits = fTrack->GetHits();
448   //Int_t numOfHits = fTrack->GetNumberOfPoints();
449
450   if (0)// fTrack->ComesFromMainVertex() == true ) 
451     {
452       dx = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetX() - fVertex->GetX();
453       dy = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetY() - fVertex->GetY() ;
454     }
455   else 
456     {
457       dx = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetX() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetX() ;
458       dy = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetY() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetY() ;
459       //dx = ((AliHLTTPCConfMapPoint *)hits->First())->GetX() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetX() ;
460       //dy = ((AliHLTTPCConfMapPoint *)hits->First())->GetY() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetY() ;
461     }
462   
463   Double_t localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
464   Double_t totalS ;
465   
466   if ( fabs(localPsi) < 1. ) 
467     {
468       totalS = 2.0 * radius * asin ( localPsi ) ;
469     } 
470   else 
471     { 
472       totalS = 2.0 * radius * AliHLTTPCTransform::Pi() ;
473     } 
474   
475   AliHLTTPCConfMapPoint *previousHit = NULL;
476
477   // FtfBaseHit *previousHit = 0  ;
478   
479   //for ( startLoop() ; done() ; nextHit() ) {
480   Double_t dpsi,s;
481
482   //  for(hit_counter=0; hit_counter<numOfHits; hit_counter++)
483   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
484     {
485       // AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
486       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
487       // if ( GetCurrentHit() != GetFirstHit() ) 
488       if(cHit != fTrack->GetFirstHit())//  hits->First())
489         {
490           dx   = cHit->GetX() - previousHit->GetX() ;
491           dy   = cHit->GetY() - previousHit->GetY() ;
492           dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
493           fTrack->SetPsierr(dpsi);
494           s = previousHit->GetS() - 2.0 * radius * (Double_t)asin ( dpsi ) ;
495           cHit->SetS(s);
496         }
497       else
498         cHit->SetS(totalS);
499       //        cHit->s = totalS ;
500     
501       sum += cHit->GetZWeight() ;
502       ss  += cHit->GetZWeight() * cHit->GetS() ;
503       sz  += cHit->GetZWeight() * cHit->GetZ() ;
504       sss += cHit->GetZWeight() * cHit->GetS() * cHit->GetS() ;
505       ssz += cHit->GetZWeight() * cHit->GetS() * cHit->GetZ() ;
506       previousHit = cHit ;
507     }
508   
509   Double_t chi2,det = sum * sss - ss * ss;
510   if ( fabs(det) < 1e-20)
511     { 
512       chi2 = 99999.F ;
513       fTrack->SetChiSq2(chi2);
514       return 0 ;
515     }
516   
517   //Compute the best fitted parameters A,B
518   Double_t tanl,z0,dtanl,dz0;
519
520   tanl = (Double_t)((sum * ssz - ss * sz ) / det );
521   z0   = (Double_t)((sz * sss - ssz * ss ) / det );
522
523   fTrack->SetTgl(tanl);
524   fTrack->SetZ0(z0);
525   
526   //     calculate chi-square 
527   
528   chi2 = 0.;
529   Double_t r1 ;
530   
531   //for(hit_counter=0; hit_counter<numOfHits; hit_counter++)
532   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
533     {
534       //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
535       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
536       r1   = cHit->GetZ() - tanl * cHit->GetS() - z0 ;
537       chi2 += (Double_t) ( (Double_t)cHit->GetZWeight() * (r1 * r1) );
538     }
539   fTrack->SetChiSq2(chi2);
540   //
541   //     calculate estimated variance
542   //      varsq=chi/(double(n)-2.) 
543   //     calculate covariance matrix 
544   //      siga=sqrt(varsq*sxx/det) 
545   //      sigb=sqrt(varsq*sum/det) 
546   //
547   dtanl = (Double_t) ( sum / det );
548   dz0   = (Double_t) ( sss / det );
549   
550   fTrack->SetTglerr(dtanl);
551   fTrack->SetZ0err(dz0);
552   
553   return 0 ;
554
555
556
557 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
558 //    Straight Line Fit  in x-y plane
559 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
560 Int_t AliHLTTPCConfMapFit::FitLineXY ( ){
561     // -----------------------------------------------------------------------------
562     // Implementation after Numerical Recipes in C, 2nd Edtion, chapter 15.2, p. 661
563     // with y = b*x + a
564     // and Data Analysis for Physical Science Students, Luis Lyons, chapter 2.4 p.51 
565     // with y = a' + bx' , x' = x - <x>
566     // -----------------------------------------------------------------------------
567
568     Double_t s = 0.;
569     Double_t sx = 0.;
570
571     Double_t sPrime = 0.;
572     Double_t sxPrime = 0.;
573     Double_t sxxPrime = 0.;
574     Double_t syPrime = 0.;
575     Double_t sxyPrime = 0.;
576
577     Double_t chi2 = 0.;
578
579     Int_t numOfHits = fTrack->GetNumberOfPoints();
580
581     Int_t co=0;
582     
583     // - Loop over hits calculating average : xav
584     for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit()) {
585         co++;
586         AliHLTTPCConfMapPoint *currentHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
587         // ** maybe not necessary, already done in ConfMapPoint
588         currentHit->SetXYWeight( 1./ (Double_t)(currentHit->GetXerr()*currentHit->GetXerr() + currentHit->GetYerr()*currentHit->GetYerr()) );
589         // **
590         s   += currentHit->GetXYWeight();
591         sx  += currentHit->GetXYWeight() * currentHit->GetX();
592     }   
593     
594     if(co!=numOfHits) 
595         LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitLineXY","TrackFit") << "Mismatch of hits. Counter: "<<co<<" nHits: "<<numOfHits<<ENDLOG;
596
597     Double_t xav = (Double_t)sx / s;
598     
599     // Calculate weighted means
600     for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit()) {
601         AliHLTTPCConfMapPoint *currentHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
602
603         Double_t xPrime =  currentHit->GetX() - xav;
604         sPrime   += currentHit->GetXYWeight();
605         sxPrime  += currentHit->GetXYWeight() * xPrime;
606         sxxPrime += currentHit->GetXYWeight() * xPrime * xPrime;
607         syPrime  += currentHit->GetXYWeight() * currentHit->GetY();
608         sxyPrime += currentHit->GetXYWeight() * xPrime * currentHit->GetY();
609     }
610
611     Double_t det = sPrime*sxxPrime + sxPrime*sxPrime;
612
613     if (fabs(det) < 1e-20) { 
614         LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapFit::FitLineXY","TrackFit") << "Determinant == 0" << ENDLOG;  
615         chi2 = 99999.F ;
616         fTrack->SetChiSq1(chi2);
617         return -1 ;
618     }
619
620     Double_t b   = (Double_t)(sPrime*sxyPrime - sxPrime*syPrime) / det;        // line parameter b
621     Double_t aPrime   = (Double_t)(sxxPrime*syPrime - sxPrime*sxyPrime) / det; // line parameter a
622
623     Double_t sigma2b = (Double_t)1. / sxxPrime;
624     //-- Double_t sigma2aprime = (Double_t)1. /sPrime;
625
626     // Get gradient angle psi of line in xy plane
627     Double_t psi  = (Double_t) atan(b) ; 
628
629     // Calculate chi2
630     for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit()) {
631         AliHLTTPCConfMapPoint *currentHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
632         Double_t tempchi = currentHit->GetY() - aPrime - b*(currentHit->GetX() - xav);
633         chi2 += tempchi*tempchi*currentHit->GetXYWeight() ;
634     }
635
636     Double_t a = aPrime - b*xav;
637
638
639     // Set TrackParameter
640     fTrack->SetChiSq1(chi2);
641     fTrack->SetPsi(psi);
642     fTrack->SetPsierr(sigma2b);   
643     fTrack->SetCenterX(0.);    // Set to point on the track (for UpdateToFirstPoint)
644     fTrack->SetCenterY(a);     // Set to point on the track (for UpdateToFirstPoint)
645
646     //Set the first point on the track to the space point coordinates of the innermost track
647     //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
648     AliHLTTPCConfMapPoint *lastHit = (AliHLTTPCConfMapPoint*)fTrack->GetLastHit();
649     Double_t x0 = lastHit->GetX();
650     Double_t y0 = lastHit->GetY();
651     fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLineSZ
652     
653
654     //Set Defaults
655     fTrack->SetRadius(-1.);
656     fTrack->SetCharge(1);
657     fTrack->SetPt(-1.);
658   
659
660     return 0;
661 }
662
663
664 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
665 //    Straight Line Fit  in s-z plane
666 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
667 Int_t AliHLTTPCConfMapFit::FitLineSZ ( ){
668     // -----------------------------------------------------------------------------
669     // Implementation after Numerical Recipes in C, 2nd Edtion, chapter 15.2, p. 661
670     // with z = b*s + a
671     // and Data Analysis for Physical Science Students, Luis Lyons, chapter 2.4 p.51 
672     // with z = a' + bs' , s' = s - <s>
673     // -----------------------------------------------------------------------------
674
675     Double_t S = 0.;
676     Double_t Ss = 0.;
677
678     Double_t sPrime = 0.;
679     Double_t ssPrime = 0.;
680     Double_t sssPrime = 0.;
681     Double_t szPrime = 0.;
682     Double_t sszPrime = 0.;
683
684     Double_t chi2 = 0.;
685
686     // Matthias 16.10.2007
687     // what's that!!! local variables 's' and 'S'
688     // change Double_t s = 0.; -> slength
689     Double_t slength = 0.;
690
691     AliHLTTPCConfMapPoint *previousHit = NULL;
692   
693     // - Loop over hits calculating length in xy-plane: s
694     // - Loop over hits calculating average : sav
695     for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit()) {
696         AliHLTTPCConfMapPoint *currentHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
697         if(currentHit != fTrack->GetFirstHit()) {
698             Double_t dx = currentHit->GetX() - previousHit->GetX() ;
699             Double_t dy = currentHit->GetY() - previousHit->GetY() ;
700             slength = previousHit->GetS() - (Double_t)sqrt ( dx*dx + dy*dy );
701         }
702         else{
703             Double_t dx = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetX() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetX(); 
704             Double_t dy = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetY() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetY();
705             slength = (Double_t)sqrt ( dx*dx + dy*dy );
706         }
707
708         currentHit->SetS(slength);
709
710         S   += currentHit->GetZWeight();
711         Ss  += currentHit->GetZWeight() * currentHit->GetS();
712     }
713
714     Double_t sav = (Double_t)Ss / S;
715
716     // Calculate weighted means
717     for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit()) {
718         AliHLTTPCConfMapPoint *currentHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
719
720         // Matthias 20.05.2008
721         // here was a shadowed variable, sPrime is formerly defined
722         // renamed it to lsPrime ('local')
723         Double_t lsPrime =  currentHit->GetS() - sav;
724         lsPrime   += currentHit->GetZWeight();
725         ssPrime  += currentHit->GetZWeight() * lsPrime;
726         sssPrime += currentHit->GetZWeight() * lsPrime * lsPrime;
727         szPrime  += currentHit->GetZWeight() * currentHit->GetZ();
728         sszPrime += currentHit->GetZWeight() * lsPrime * currentHit->GetZ();
729     }
730
731     Double_t det = sPrime*sssPrime + ssPrime*ssPrime;
732
733     if (fabs(det) < 1e-20) { 
734         LOG(AliHLTTPCLog::kDebug,"AliHLTTPCConfMapFit::FitLineSZ","TrackFit") << "Determinant == 0" << ENDLOG;  
735         chi2 = 99999.F ;
736         fTrack->SetChiSq2(chi2);
737         return -1 ;
738     }
739
740     Double_t b   = (Double_t)(sPrime*sszPrime - ssPrime*szPrime) / det;        // line parameter b
741     Double_t aPrime   = (Double_t)(sssPrime*szPrime - ssPrime*sszPrime) / det; // line parameter a
742
743     Double_t a = aPrime - b*sav;
744
745     Double_t sigma2b = (Double_t) 1. / sssPrime;
746     Double_t sigma2aprime = (Double_t) 1. /sPrime;
747
748     Double_t sigma2a = sigma2aprime + sav*sav * sigma2b*sigma2b;
749
750     // Calculate chi2
751     for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit()) {
752         AliHLTTPCConfMapPoint *currentHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
753         Double_t tempchi = currentHit->GetZ() - aPrime - b*(currentHit->GetS() - sav);
754         chi2 += tempchi*tempchi*currentHit->GetZWeight() ;
755     }
756
757     // Set TrackParameter
758     fTrack->SetChiSq2(chi2);
759     fTrack->SetTgl(b);
760     fTrack->SetZ0(a);
761     fTrack->SetTglerr(sigma2b);
762 //  fTrack->SetZ0err(sigma2aprime);   // maybe subject to check
763     fTrack->SetZ0err(sigma2a);        // maybe subject to check
764     return 0;
765 }
766