1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 // Class for global helix fit of a track
19 // The method uses the following idea:
20 //------------------------------------------------------
23 // (x-x0)^2+(y-y0)^2-R^2=0 ===>
25 // (x^2+y^2 -2*x*x0 - 2*y*y0+ x0^2 -y0^2 -R^2 =0; ==>
27 // substitution t = 1/(x^2+y^2), u = 2*x*t, v = 2*y*t, D0 = R^2 - x0^2- y0^2
29 // 1 - u*x0 - v*y0 - t *D0 =0 ; - linear equation
31 // next substition a = 1/y0 b = -x0/y0 c = -D0/y0
33 // final linear equation : a + u*b +t*c - v =0;
37 // sum( (a + ui*b +ti*c - vi)^2)/(sigmai)^2 = min;
39 // where sigmai is the error of maesurement (a + ui*b +ti*c - vi)
41 // neglecting error of xi, and supposing xi>>yi sigmai ~ sigmaVi ~ 2*sigmay*t
44 #include "TMatrixDSym.h"
45 //#include "TDecompChol.h"
47 #include "AliRieman.h"
53 AliRieman::AliRieman(){
55 // default constructor
57 for (Int_t i=0;i<6;i++) fParams[i] = 0;
58 for (Int_t i=0;i<9;i++) fSumXY[i] = 0;
59 for (Int_t i=0;i<9;i++) fSumXZ[i] = 0;
76 AliRieman::AliRieman(Int_t capacity){
78 // default constructor
80 for (Int_t i=0;i<6;i++) fParams[i] = 0;
81 for (Int_t i=0;i<9;i++) fSumXY[i] = 0;
82 for (Int_t i=0;i<9;i++) fSumXZ[i] = 0;
86 fX = new Double_t[fCapacity];
87 fY = new Double_t[fCapacity];
88 fZ = new Double_t[fCapacity];
89 fSy = new Double_t[fCapacity];
90 fSz = new Double_t[fCapacity];
91 fCovar = new TMatrixDSym(6);
98 AliRieman::AliRieman(const AliRieman &rieman):TObject(rieman){
102 for (Int_t i=0;i<6;i++) fParams[i] = rieman.fParams[i];
103 for (Int_t i=0;i<9;i++) fSumXY[i] = rieman.fSumXY[i];
104 for (Int_t i=0;i<9;i++) fSumXZ[i] = rieman.fSumXZ[i];
105 fCapacity = rieman.fN;
107 fCovar = new TMatrixDSym(*(rieman.fCovar));
108 fConv = rieman.fConv;
109 fX = new Double_t[fN];
110 fY = new Double_t[fN];
111 fZ = new Double_t[fN];
112 fSy = new Double_t[fN];
113 fSz = new Double_t[fN];
114 for (Int_t i=0;i<rieman.fN;i++){
115 fX[i] = rieman.fX[i];
116 fY[i] = rieman.fY[i];
117 fZ[i] = rieman.fZ[i];
118 fSy[i] = rieman.fSy[i];
119 fSz[i] = rieman.fSz[i];
123 AliRieman::~AliRieman()
136 void AliRieman::Reset()
139 // Reset all the data members
142 for (Int_t i=0;i<6;i++) fParams[i] = 0;
143 for (Int_t i=0;i<9;i++) fSumXY[i] = 0;
144 for (Int_t i=0;i<9;i++) fSumXZ[i] = 0;
149 void AliRieman::AddPoint(Double_t x, Double_t y, Double_t z, Double_t sy, Double_t sz)
154 //------------------------------------------------------
157 // (x-x0)^2+(y-y0)^2-R^2=0 ===>
159 // (x^2+y^2 -2*x*x0 - 2*y*y0+ x0^2 -y0^2 -R^2 =0; ==>
161 // substitution t = 1/(x^2+y^2), u = 2*x*t, v = 2*y*t, D0 = R^2 - x0^2- y0^2
163 // 1 - u*x0 - v*y0 - t *D0 =0 ; - linear equation
165 // next substition a = 1/y0 b = -x0/y0 c = -D0/y0
167 // final linear equation : a + u*b +t*c - v =0;
171 // sum( (a + ui*b +ti*c - vi)^2)/(sigmai)^2 = min;
173 // where sigmai is the error of maesurement (a + ui*b +ti*c - vi)
175 // neglecting error of xi, and supposing xi>>yi sigmai ~ sigmaVi ~ 2*sigmay*t
177 if (fN==fCapacity-1) return; // out of capacity
178 fX[fN] = x; fY[fN]=y; fZ[fN]=z; fSy[fN]=sy; fSz[fN]=sz;
182 Double_t t = x*x+y*y;
187 Double_t error = 2.*sy*t;
189 Double_t weight = 1./error;
191 fSumXY[1] +=u*weight; fSumXY[2]+=v*weight; fSumXY[3]+=t*weight;
192 fSumXY[4] +=u*u*weight; fSumXY[5]+=t*t*weight;
193 fSumXY[6] +=u*v*weight; fSumXY[7]+=u*t*weight; fSumXY[8]+=v*t*weight;
199 fSumXZ[1] +=weight*x; fSumXZ[2] +=weight*x*x; fSumXZ[3] +=weight*x*x*x; fSumXZ[4] += weight*x*x*x*x;
200 fSumXZ[5] +=weight*z; fSumXZ[6] +=weight*x*z; fSumXZ[7] +=weight*x*x*z;
209 void AliRieman::UpdatePol(){
215 for (Int_t i=0;i<6;i++)fParams[i]=0;
220 TMatrixDSym smatrix(3);
223 // smatrix(0,0) = s0; smatrix(1,1)=su2; smatrix(2,2)=st2;
224 // smatrix(0,1) = su; smatrix(0,2)=st; smatrix(1,2)=sut;
225 // sums(0,0) = sv; sums(0,1)=suv; sums(0,2)=svt;
227 smatrix(0,0) = fSumXY[0]; smatrix(1,1)=fSumXY[4]; smatrix(2,2)=fSumXY[5];
228 smatrix(0,1) = fSumXY[1]; smatrix(0,2)=fSumXY[3]; smatrix(1,2)=fSumXY[7];
229 sums(0,0) = fSumXY[2]; sums(0,1) =fSumXY[6]; sums(0,2) =fSumXY[8];
231 if (smatrix.IsValid()){
232 for (Int_t i=0;i<3;i++)
233 for (Int_t j=0;j<=i;j++){
234 (*fCovar)(i,j)=smatrix(i,j);
236 TMatrixD res = sums*smatrix;
237 fParams[0] = res(0,0);
238 fParams[1] = res(0,1);
239 fParams[2] = res(0,2);
245 TMatrixDSym smatrixz(3);
246 smatrixz(0,0) = fSumXZ[0]; smatrixz(0,1) = fSumXZ[1]; smatrixz(0,2) = fSumXZ[2];
247 smatrixz(1,1) = fSumXZ[2]; smatrixz(1,2) = fSumXZ[3];
248 smatrixz(2,2) = fSumXZ[4];
250 if (smatrixz.IsValid()){
251 sums(0,0) = fSumXZ[5];
252 sums(0,1) = fSumXZ[6];
253 sums(0,2) = fSumXZ[7];
254 TMatrixD res = sums*smatrixz;
255 fParams[3] = res(0,0);
256 fParams[4] = res(0,1);
257 fParams[5] = res(0,2);
258 for (Int_t i=0;i<3;i++)
259 for (Int_t j=0;j<=i;j++){
260 (*fCovar)(i+2,j+2)=smatrixz(i,j);
265 // (x-x0)^2+(y-y0)^2-R^2=0 ===>
267 // (x^2+y^2 -2*x*x0 - 2*y*y0+ x0^2 -y0^2 -R^2 =0; ==>
268 // substitution t = 1/(x^2+y^2), u = 2*x*t, y = 2*y*t, D0 = R^2 - x0^2- y0^2
270 // 1 - u*x0 - v*y0 - t *D0 =0 ; - linear equation
272 // next substition a = 1/y0 b = -x0/y0 c = -D0/y0
273 // final linear equation : a + u*b +t*c - v =0;
276 // fParam[1] = -x0/y0
277 // fParam[2] = - (R^2 - x0^2 - y0^2)/y0
278 if (conv>1) fConv =kTRUE;
283 void AliRieman::Update(){
289 for (Int_t i=0;i<6;i++)fParams[i]=0;
294 TMatrixDSym smatrix(3);
297 // smatrix(0,0) = s0; smatrix(1,1)=su2; smatrix(2,2)=st2;
298 // smatrix(0,1) = su; smatrix(0,2)=st; smatrix(1,2)=sut;
299 // sums(0,0) = sv; sums(0,1)=suv; sums(0,2)=svt;
301 smatrix(0,0) = fSumXY[0]; smatrix(1,1)=fSumXY[4]; smatrix(2,2)=fSumXY[5];
302 smatrix(0,1) = fSumXY[1]; smatrix(0,2)=fSumXY[3]; smatrix(1,2)=fSumXY[7];
304 smatrix(1,0) = fSumXY[1];
305 smatrix(2,0) = fSumXY[3];
306 smatrix(2,1) = fSumXY[7];
308 sums(0,0) = fSumXY[2]; sums(0,1) =fSumXY[6]; sums(0,2) =fSumXY[8];
309 //TDecompChol decomp(smatrix);
310 //decomp.SetTol(1.0e-14);
314 if (smatrix.IsValid()){
315 for (Int_t i=0;i<3;i++)
316 for (Int_t j=0;j<3;j++){
317 (*fCovar)(i,j)=smatrix(i,j);
319 TMatrixD res = sums*smatrix;
320 fParams[0] = res(0,0);
321 fParams[1] = res(0,1);
322 fParams[2] = res(0,2);
326 fConv = kFALSE; //non converged
329 if (-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1.<0){
330 fConv = kFALSE; //non converged
336 Double_t x0 = -fParams[1]/fParams[0];
337 Double_t rm1 = fParams[0]/TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1.);
340 for (Int_t i=0;i<9;i++) sumXZ[i]=0;
341 for (Int_t i=0;i<fN;i++){
342 Double_t phi = TMath::ASin((fX[i]-x0)*rm1);
343 Double_t phi0 = TMath::ASin((0.-x0)*rm1);
344 Double_t weight = 1/fSz[i];
346 Double_t dphi = (phi-phi0)/rm1;
348 sumXZ[1] +=weight*dphi;
349 sumXZ[2] +=weight*dphi*dphi;
350 sumXZ[3] +=weight*fZ[i];
351 sumXZ[4] +=weight*dphi*fZ[i];
355 TMatrixDSym smatrixz(2);
357 smatrixz(0,0) = sumXZ[0]; smatrixz(0,1) = sumXZ[1]; smatrixz(1,1) = sumXZ[2];
358 smatrixz(1,0) = sumXZ[1];
360 if (smatrixz.IsValid()){
361 sumsz(0,0) = sumXZ[3];
362 sumsz(0,1) = sumXZ[4];
363 TMatrixD res = sumsz*smatrixz;
364 fParams[3] = res(0,0);
365 fParams[4] = res(0,1);
366 for (Int_t i=0;i<2;i++)
367 for (Int_t j=0;j<2;j++){
368 (*fCovar)(i+3,j+3)=smatrixz(i,j);
373 // (x-x0)^2+(y-y0)^2-R^2=0 ===>
375 // (x^2+y^2 -2*x*x0 - 2*y*y0+ x0^2 -y0^2 -R^2 =0; ==>
376 // substitution t = 1/(x^2+y^2), u = 2*x*t, v = 2*y*t, D0 = R^2 - x0^2- y0^2
378 // 1 - u*x0 - v*y0 - t *D0 =0 ; - linear equation
380 // next substition a = 1/y0 b = -x0/y0 c = -D0/y0
381 // final linear equation : a + u*b +t*c - v =0;
384 // fParam[1] = -x0/y0
385 // fParam[2] = - (R^2 - x0^2 - y0^2)/y0
386 if (conv>1) fConv =kTRUE;
389 fChi2Y = CalcChi2Y();
390 fChi2Z = CalcChi2Z();
391 fChi2 = fChi2Y +fChi2Z;
396 Double_t AliRieman::GetYat(Double_t x) const {
398 // get y at given x position
400 if (!fConv) return 0.;
401 Double_t res2 = (x*fParams[0]+fParams[1]);
403 res2 = 1.-fParams[2]*fParams[0]+fParams[1]*fParams[1]-res2;
404 if (res2<0) return 0;
405 res2 = TMath::Sqrt(res2);
406 res2 = (1-res2)/fParams[0];
410 Double_t AliRieman::GetDYat(Double_t x) const {
412 // get dy/dx at given x position
414 if (!fConv) return 0.;
415 Double_t x0 = -fParams[1]/fParams[0];
416 if (-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1<0) return 0;
417 Double_t rm1 = fParams[0]/TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1);
418 if ( 1./(rm1*rm1)-(x-x0)*(x-x0)<=0) return 0;
419 Double_t res = (x-x0)/TMath::Sqrt(1./(rm1*rm1)-(x-x0)*(x-x0));
420 if (fParams[0]<0) res*=-1.;
426 Double_t AliRieman::GetZat(Double_t x) const {
428 // get z at given x position
430 if (!fConv) return 0.;
431 Double_t x0 = -fParams[1]/fParams[0];
432 if (-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1<=0) return 0;
433 Double_t rm1 = fParams[0]/TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1);
434 Double_t phi = TMath::ASin((x-x0)*rm1);
435 Double_t phi0 = TMath::ASin((0.-x0)*rm1);
436 Double_t dphi = (phi-phi0);
437 Double_t res = fParams[3]+fParams[4]*dphi/rm1;
441 Double_t AliRieman::GetDZat(Double_t x) const {
443 // get dz/dx at given x postion
445 if (!fConv) return 0.;
446 Double_t x0 = -fParams[1]/fParams[0];
447 if (-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1<=0) return 0;
448 Double_t rm1 = fParams[0]/TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1);
449 Double_t res = fParams[4]/TMath::Cos(TMath::ASin((x-x0)*rm1));
454 Double_t AliRieman::GetC() const{
458 return fParams[0]/TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1);
461 Double_t AliRieman::CalcChi2Y() const{
463 // calculate chi2 for Y
465 Double_t sumchi2 = 0;
466 for (Int_t i=0;i<fN;i++){
467 Double_t chi2 = (fY[i] - GetYat(fX[i]))/fSy[i];
474 Double_t AliRieman::CalcChi2Z() const{
476 // calculate chi2 for Z
478 Double_t sumchi2 = 0;
479 for (Int_t i=0;i<fN;i++){
480 Double_t chi2 = (fZ[i] - GetZat(fX[i]))/fSy[i];
486 Double_t AliRieman::CalcChi2() const{
488 // sum chi2 in both coord - supposing Y and Z independent
490 return CalcChi2Y()+CalcChi2Z();
493 AliRieman * AliRieman::MakeResiduals() const{
495 // create residual structure - ONLY for debug purposes
497 AliRieman *rieman = new AliRieman(fN);
498 for (Int_t i=0;i<fN;i++){
499 rieman->AddPoint(fX[i],fY[i]-GetYat(fX[i]),fZ[i]-GetZat(fX[i]), fSy[i],fSz[i]);