]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCConfMapFit.cxx
- made package indepentend of src
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCConfMapFit.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliHLTTPCRootTypes.h"
7 #include "AliHLTTPCLogging.h"
8 #include "AliHLTTPCVertex.h"
9 #include "AliHLTTPCConfMapTrack.h"
10 #include "AliHLTTPCConfMapPoint.h"
11 #include "AliHLTTPCTransform.h"
12 #include "AliHLTTPCConfMapFit.h"
13
14 /** \class AliHLTTPCConfMapFit
15 <pre>
16 //_____________________________________________________________
17 // AliHLTTPCConfMapFit
18 //
19 // Fit class for conformal mapping tracking
20 </pre>
21 */
22
23 #if __GNUC__ >= 3
24 using namespace std;
25 #endif
26
27 ClassImp(AliHLTTPCConfMapFit)
28
29
30 AliHLTTPCConfMapFit::AliHLTTPCConfMapFit(AliHLTTPCConfMapTrack *track,AliHLTTPCVertex *vertex)
31 {
32   //constructor
33   fTrack = track;
34   fVertex = vertex;
35 }
36
37 Int_t AliHLTTPCConfMapFit::FitHelix()
38 {
39   //fit the helix
40   if(FitCircle())
41     {
42       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
43         "Problems during circle fit"<<ENDLOG;
44       return 1;
45     }
46   if(FitLine())
47     {
48       LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitHelix","TrackFit")<<AliHLTTPCLog::kDec<<
49         "Problems during line fit"<<ENDLOG;
50       return 1;
51     }
52   return 0;
53 }
54
55 Int_t AliHLTTPCConfMapFit::FitCircle()
56 {
57   //-----------------------------------------------------------------
58   //Fits circle parameters using algorithm
59   //described by ChErnov and Oskov in Computer Physics
60   //Communications.
61   // 
62   //Written in FORTRAN by Jawluen Tang, Physics department , UT-Austin 
63   //Moved to C by Pablo Yepes
64   //Moved to AliROOT by ASV.
65   //------------------------------------------------------------------
66   
67   Double_t wsum  = 0.0 ;
68   Double_t xav   = 0.0 ;
69   Double_t yav   = 0.0 ;
70   
71   Int_t num_of_hits = fTrack->GetNumberOfPoints();
72   //
73   //     Loop over hits calculating average
74   Int_t co=0;
75   
76   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
77     {
78       co++;
79       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
80       cHit->SetXYWeight( 1./ (Double_t)(cHit->GetXerr()*cHit->GetXerr() + cHit->GetYerr()*cHit->GetYerr()) );
81       wsum      += cHit->GetXYWeight() ;
82       xav       += cHit->GetXYWeight() * cHit->GetX() ;
83       yav       += cHit->GetXYWeight() * cHit->GetY() ;
84     }
85   if(co!=num_of_hits) 
86     LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
87       "Mismatch of hits. Counter: "<<co<<" nHits: "<<num_of_hits<<ENDLOG;
88   if (fTrack->ComesFromMainVertex() == true)
89     {    
90       wsum += fVertex->GetXYWeight() ;
91       xav  += fVertex->GetX() ;
92       yav  += fVertex->GetY() ;
93     }
94   
95   xav = xav / wsum ;
96   yav = yav / wsum ;
97 //
98 //  CALCULATE <X**2>, <XY>, AND <Y**2> WITH <X> = 0, & <Y> = 0
99 //
100   Double_t xxav  = 0.0 ;
101   Double_t xyav  = 0.0 ; 
102   Double_t yyav  = 0.0 ;
103   Double_t xi, yi ;
104
105   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())
106     { 
107       //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint *)hits->At(hit_counter);
108       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
109       xi        = cHit->GetX() - xav ;
110       yi        = cHit->GetY() - yav ;
111       xxav     += xi * xi * cHit->GetXYWeight() ;
112       xyav     += xi * yi * cHit->GetXYWeight() ;
113       yyav     += yi * yi * cHit->GetXYWeight() ;
114     }
115   
116   if (fTrack->ComesFromMainVertex() == true)
117     {
118       xi        = fVertex->GetX() - xav ;
119       yi        = fVertex->GetY() - yav ;
120       xxav     += xi * xi * fVertex->GetXYWeight() ;
121       xyav     += xi * yi * fVertex->GetXYWeight() ;
122       yyav     += yi * yi * fVertex->GetXYWeight() ; 
123     }
124   xxav = xxav / wsum ;
125   xyav = xyav / wsum ;
126   yyav = yyav / wsum ;
127 //
128 //-->  ROTATE COORDINATES SO THAT <XY> = 0
129 //
130 //-->  SIGN(C**2 - S**2) = SIGN(XXAV - YYAV) >
131 //-->  &                                     > ==> NEW : (XXAV-YYAV) > 0
132 //-->  SIGN(S) = SIGN(XYAV)                  >
133
134   Double_t a = fabs( xxav - yyav ) ;
135   Double_t b = 4.0 * xyav * xyav ;
136
137   Double_t asqpb  = a * a + b  ;
138   Double_t rasqpb = sqrt ( asqpb) ;
139
140   Double_t splus  = 1.0 + a / rasqpb ;
141   Double_t sminus = b / (asqpb * splus) ;
142
143   splus  = sqrt (0.5 * splus ) ;
144   sminus = sqrt (0.5 * sminus) ;
145 //
146 //->  FIRST REQUIRE : SIGN(C**2 - S**2) = SIGN(XXAV - YYAV)
147 //
148   Double_t sinrot, cosrot ;
149   if ( xxav <= yyav ) {
150          cosrot = sminus ;
151          sinrot = splus  ;
152   }
153   else {
154           cosrot = splus ;
155           sinrot = sminus ;
156   }
157 //
158 //->  REQUIRE : SIGN(S) = SIGN(XYAV) * SIGN(C) (ASSUMING SIGN(C) > 0)
159 //
160   if ( xyav < 0.0 ) sinrot = - sinrot ;
161 //
162 //-->  WE NOW HAVE THE SMALLEST ANGLE THAT GUARANTEES <X**2> > <Y**2>
163 //-->  TO GET THE SIGN OF THE CHARGE RIGHT, THE NEW X-AXIS MUST POINT
164 //-->  OUTWARD FROM THE ORGIN.  WE ARE FREE TO CHANGE SIGNS OF BOTH
165 //-->  COSROT AND SINROT SIMULTANEOUSLY TO ACCOMPLISH THIS.
166 //
167 //-->  CHOOSE SIGN OF C WISELY TO BE ABLE TO GET THE SIGN OF THE CHARGE
168 //
169   if ( cosrot*xav+sinrot*yav < 0.0 ) {
170           cosrot = -cosrot ;
171           sinrot = -sinrot ;
172   }
173 //
174 //->  NOW GET <R**2> AND RSCALE= SQRT(<R**2>)
175 //
176   Double_t rrav   = xxav + yyav ;
177   Double_t rscale = sqrt(rrav) ;
178
179   xxav   = 0.0 ;
180   yyav   = 0.0 ;
181   xyav   = 0.0 ;
182   Double_t xrrav = 0.0 ;
183   Double_t yrrav = 0.0 ;
184   Double_t rrrrav  = 0.0 ;
185
186   Double_t xixi, yiyi, riri, wiriri, xold, yold ;
187   
188   //for (hit_counter=0; hit_counter<num_of_hits; hit_counter++) 
189   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
190     { 
191       //AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);  
192       AliHLTTPCConfMapPoint* cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
193
194       xold = cHit->GetX() - xav ;
195       yold = cHit->GetY() - yav ;
196       //
197       //-->  ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
198       //
199       xi = (  cosrot * xold + sinrot * yold ) / rscale ;
200       yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
201       
202       xixi   = xi * xi ;
203       yiyi   = yi * yi ;
204       riri   = xixi + yiyi ;
205       wiriri = cHit->GetXYWeight() * riri ;
206       
207       xyav   += cHit->GetXYWeight() * xi * yi ;
208       xxav   += cHit->GetXYWeight() * xixi ;
209       yyav   += cHit->GetXYWeight() * yiyi ;
210       
211       xrrav  += wiriri * xi ;
212       yrrav  += wiriri * yi ;
213       rrrrav += wiriri * riri ;
214     }
215   //
216 //   Include vertex if required
217 //
218   if (fTrack->ComesFromMainVertex() == true)
219     {
220         xold = fVertex->GetX() - xav ;
221         yold = fVertex->GetY() - yav ;
222         //
223         //-->  ROTATE SO THAT <XY> = 0 & DIVIDE BY RSCALE SO THAT <R**2> = 1
224         //
225         xi = (  cosrot * xold + sinrot * yold ) / rscale ;
226         yi = ( -sinrot * xold + cosrot * yold ) / rscale ;
227         
228         xixi   = xi * xi ;
229         yiyi   = yi * yi ;
230         riri   = xixi + yiyi ;
231         wiriri = fVertex->GetXYWeight() * riri ;
232
233         xyav   += fVertex->GetXYWeight() * xi * yi ;
234         xxav   += fVertex->GetXYWeight() * xixi ;
235         yyav   += fVertex->GetXYWeight() * yiyi ;
236
237         xrrav  += wiriri * xi ;
238         yrrav  += wiriri * yi ;
239         rrrrav += wiriri * riri ;
240   }
241   //
242   //    
243   //
244   //-->  DIVIDE BY WSUM TO MAKE AVERAGES
245   //
246   xxav    = xxav   / wsum ;
247   yyav    = yyav   / wsum ;
248   xrrav   = xrrav  / wsum ;
249   yrrav   = yrrav  / wsum ;
250   rrrrav  = rrrrav / wsum ;
251   xyav    = xyav   / wsum ;
252
253   Int_t const ntry = 5 ;
254 //
255 //-->  USE THESE TO GET THE COEFFICIENTS OF THE 4-TH ORDER POLYNIMIAL
256 //-->  DON'T PANIC - THE THIRD ORDER TERM IS ZERO !
257 //
258   Double_t xrrxrr = xrrav * xrrav ;
259   Double_t yrryrr = yrrav * yrrav ;
260   Double_t rrrrm1 = rrrrav - 1.0  ;
261   Double_t xxyy   = xxav  * yyav  ;        
262
263   Double_t c0  =          rrrrm1*xxyy - xrrxrr*yyav - yrryrr*xxav ;
264   Double_t c1  =        - rrrrm1      + xrrxrr      + yrryrr   - 4.0*xxyy ;        
265   Double_t c2  =   4.0  + rrrrm1                               - 4.0*xxyy ;           
266   Double_t c4  = - 4.0  ;                
267 //
268 //-->  COEFFICIENTS OF THE DERIVATIVE - USED IN NEWTON-RAPHSON ITERATIONS
269 //
270   Double_t c2d =   2.0 * c2 ;
271   Double_t c4d =   4.0 * c4 ;
272 //
273 //-->  0'TH VALUE OF LAMDA - LINEAR INTERPOLATION BETWEEN P(0) & P(YYAV)
274 //
275 //   LAMDA = YYAV * C0 / (C0 + YRRSQ * (XXAV-YYAV))
276   Double_t lamda  = 0.0 ;
277   Double_t dlamda = 0.0 ;
278 //
279   Double_t chiscl = wsum * rscale * rscale ;
280   Double_t dlamax = 0.001 / chiscl ;   
281    
282   Double_t p, pd ;
283   for ( int itry = 1 ; itry <= ntry ; itry++ ) {
284      p      = c0 + lamda * (c1 + lamda * (c2 + lamda * lamda * c4 )) ;
285      pd     = (c1 + lamda * (c2d + lamda * lamda * c4d)) ;
286      dlamda = -p / pd ;
287      lamda  = lamda + dlamda ;
288      if (fabs(dlamda)<   dlamax) break ;
289   }
290
291   Double_t chi2 = (Double_t)(chiscl * lamda) ;
292  
293   fTrack->SetChiSq1(chi2);
294   // Double_t dchisq = chiscl * dlamda ;             
295 //
296 //-->  NOW CALCULATE THE MATRIX ELEMENTS FOR ALPHA, BETA & KAPPA
297 //
298   Double_t h11   = xxav  -     lamda ;
299   Double_t h14   = xrrav ;
300   Double_t h22   = yyav  -     lamda ; 
301   Double_t h24   = yrrav ;
302   Double_t h34   = 1.0   + 2.0*lamda ;
303   if ( h11 == 0.0 || h22 == 0.0 ){
304     LOG(AliHLTTPCLog::kError,"AliHLTTPCConfMapFit::FitCircle","TrackFit")<<AliHLTTPCLog::kDec<<
305       "Problems fitting circle"<<ENDLOG;
306     return 1 ;
307   }
308   Double_t rootsq = (h14*h14)/(h11*h11) + 4.0*h34 ;
309
310   Double_t ratio, kappa, beta ;
311   if ( fabs(h22) > fabs(h24) ) {
312      ratio  = h24 / h22 ;
313      rootsq = ratio * ratio + rootsq ;
314      kappa = 1.0 / sqrt(rootsq) ;
315      beta  = - ratio * kappa ;
316   }
317   else {
318      ratio  = h22 / h24 ;
319      rootsq = 1.0 + ratio * ratio * rootsq ;
320      beta  = 1.0 / sqrt(rootsq) ;
321      if ( h24 > 0 ) beta = - beta ;
322      kappa = -ratio * beta ;
323   }            
324   Double_t alpha = - (h14/h11) * kappa ;
325 //
326 //-->  transform these into the lab coordinate system
327 //-->  first get kappa and back to real dimensions
328 //
329   Double_t kappa1 = kappa / rscale ;
330   Double_t dbro   = 0.5   / kappa1 ;
331 //
332 //-->  next rotate alpha and beta and scale
333 //
334   Double_t alphar = (cosrot * alpha - sinrot * beta)* dbro ;
335   Double_t betar  = (sinrot * alpha + cosrot * beta)* dbro ;
336 //
337 //-->  then translate by (xav,yav)
338 //
339   Double_t acent  = (double)(xav - alphar) ;
340   Double_t bcent  = (double)(yav - betar ) ;
341   Double_t radius = (double)dbro ;
342 //
343 //   Get charge
344 //
345   Int_t q = ( ( yrrav < 0 ) ? 1 : -1 ) ;
346
347   fTrack->SetCharge(q);
348   
349   
350   //Set the first point on the track to the space point coordinates of the innermost track
351   //This will be updated to lie on the fit later on (AliHLTTPCTrack::UpdateToFirstPoint).
352   Double_t x0,y0,psi,pt ;
353   AliHLTTPCConfMapPoint *lHit = (AliHLTTPCConfMapPoint*)fTrack->GetLastHit();
354   x0 = lHit->GetX();
355   y0 = lHit->GetY();
356   fTrack->SetFirstPoint(x0,y0,0); //Z-value is set in FitLine
357
358   psi  = (Double_t)atan2(bcent-y0,acent-x0) ;
359   psi  = psi + q * AliHLTTPCTransform::PiHalf();
360   if ( psi < 0 ) psi = psi + AliHLTTPCTransform::TwoPi();
361   pt   = (Double_t)(AliHLTTPCTransform::GetBFieldValue() * radius ) ;
362   
363   //Update the track parameters with the parameters from this fit:
364   fTrack->SetPsi(psi);
365   fTrack->SetPt(pt);
366   fTrack->SetRadius(radius);
367   fTrack->SetCenterX(acent);
368   fTrack->SetCenterY(bcent);
369
370   //
371 //    Get errors from fast fit
372 //
373   //if ( getPara()->getErrors ) getErrorsCircleFit ( acent, bcent, radius ) ;
374 //
375   return 0 ;
376   
377 }
378
379 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
380 //    Fit Line in s-z plane
381 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
382 Int_t AliHLTTPCConfMapFit::FitLine ( )
383 {
384   //
385   //Initialization 
386   //
387   Double_t sum = 0.F ;
388   Double_t ss  = 0.F ;
389   Double_t sz  = 0.F ;
390   Double_t sss = 0.F ;
391   Double_t ssz = 0.F ;
392   //
393   //find sum , sums ,sumz, sumss 
394   // 
395   Double_t dx, dy ;
396   Double_t radius = (Double_t)(fTrack->GetPt() / AliHLTTPCTransform::GetBFieldValue() ) ;
397
398   //TObjArray *hits = fTrack->GetHits();
399   //Int_t num_of_hits = fTrack->GetNumberOfPoints();
400
401   if (0)// fTrack->ComesFromMainVertex() == true ) 
402     {
403       dx = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetX() - fVertex->GetX();
404       dy = ((AliHLTTPCConfMapPoint*)fTrack->GetFirstHit())->GetY() - fVertex->GetY() ;
405     }
406   else 
407     {
408       dx = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetX() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetX() ;
409       dy = ((AliHLTTPCConfMapPoint *)fTrack->GetFirstHit())->GetY() - ((AliHLTTPCConfMapPoint *)fTrack->GetLastHit())->GetY() ;
410       //dx = ((AliHLTTPCConfMapPoint *)hits->First())->GetX() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetX() ;
411       //dy = ((AliHLTTPCConfMapPoint *)hits->First())->GetY() - ((AliHLTTPCConfMapPoint *)hits->Last())->GetY() ;
412     }
413   
414   Double_t localPsi = 0.5F * sqrt ( dx*dx + dy*dy ) / radius ;
415   Double_t total_s ;
416   
417   if ( fabs(localPsi) < 1. ) 
418     {
419       total_s = 2.0 * radius * asin ( localPsi ) ;
420     } 
421   else 
422     { 
423       total_s = 2.0 * radius * AliHLTTPCTransform::Pi() ;
424     } 
425   
426   AliHLTTPCConfMapPoint *previousHit = NULL;
427
428   // FtfBaseHit *previousHit = 0  ;
429   
430   //for ( startLoop() ; done() ; nextHit() ) {
431   Double_t dpsi,s;
432
433   //  for(hit_counter=0; hit_counter<num_of_hits; hit_counter++)
434   for(fTrack->StartLoop(); fTrack->LoopDone(); fTrack->GetNextHit())  
435     {
436       // AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)hits->At(hit_counter);
437       AliHLTTPCConfMapPoint *cHit = (AliHLTTPCConfMapPoint*)fTrack->GetCurrentHit();
438       // if ( GetCurrentHit() != GetFirstHit() ) 
439       if(cHit != fTrack->GetFirstHit())//  hits->First())
440         {
441           dx   = cHit->GetX() - previousHit->GetX() ;
442           dy   = cHit->GetY() - previousHit->GetY() ;
443           dpsi = 0.5 * (Double_t)sqrt ( dx*dx + dy*dy ) / radius ;
444           fTrack->SetPsierr(dpsi);
445           s = previousHit->GetS() - 2.0 * radius * (Double_t)asin ( dpsi ) ;
446           cHit->SetS(s);
447         }
448       else
449         cHit->SetS(total_s);
450       //        cHit->s = total_s ;
451     
452       sum += cHit->GetZWeight() ;
453       ss  += cHit->GetZWeight() * cHit->GetS() ;
454       sz  += cHit->GetZWeight() * cHit->GetZ() ;
455       sss += cHit->GetZWeight() * cHit->GetS() * cHit->GetS() ;
456       ssz += cHit->GetZWeight() * cHit->GetS() * cHit->GetZ() ;
457       previousHit = cHit ;
458     }
459   
460   Double_t chi2,det = sum * sss - ss * ss;
461   if ( fabs(det) < 1e-20)
462     { 
463       chi2 = 99999.F ;
464       fTrack->SetChiSq2(chi2);
465       return 0 ;
466     }
467   
468   //Compute the best fitted parameters A,B
469   Double_t tanl,z0,dtanl,dz0;
470
471   tanl = (Double_t)((sum * ssz - ss * sz ) / det );
472   z0   = (Double_t)((sz * sss - ssz * ss ) / det );
473
474   fTrack->SetTgl(tanl);
475   fTrack->SetZ0(z0);
476   
477   //     calculate chi-square 
478   
479   chi2 = 0.;
480   Double_t r1 ;
481   
482   //for(hit_counter=0; hit_counter<num_of_hits; 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       r1   = cHit->GetZ() - tanl * cHit->GetS() - z0 ;
488       chi2 += (Double_t) ( (Double_t)cHit->GetZWeight() * (r1 * r1) );
489     }
490   fTrack->SetChiSq2(chi2);
491   //
492   //     calculate estimated variance
493   //      varsq=chi/(double(n)-2.) 
494   //     calculate covariance matrix 
495   //      siga=sqrt(varsq*sxx/det) 
496   //      sigb=sqrt(varsq*sum/det) 
497   //
498   dtanl = (Double_t) ( sum / det );
499   dz0   = (Double_t) ( sss / det );
500   
501   fTrack->SetTglerr(dtanl);
502   fTrack->SetZ0err(dz0);
503   
504   return 0 ;
505