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 ///////////////////////////////////////////////////////////////////////////////
19 // Class to make a internal alignemnt of TPC chambers //
21 // Different linear tranformation investigated
22 // 12 parameters - arbitrary transformation
23 // 9 parameters - scaling fixed to 1
26 //// Only the 12 parameter version works so far...
31 #include "TLinearFitter.h"
32 #include "AliTPCcalibAlign.h"
33 #include "AliExternalTrackParam.h"
38 ClassImp(AliTPCcalibAlign)
40 AliTPCcalibAlign::AliTPCcalibAlign()
41 :fFitterArray12(72*72),fFitterArray9(72*72),fFitterArray6(72*72)
46 for (Int_t i=0;i<72*72;++i) {
51 AliTPCcalibAlign::~AliTPCcalibAlign() {
57 void AliTPCcalibAlign::Process(const AliExternalTrackParam &tp1,
58 const AliExternalTrackParam &tp2,
61 // Process function to fill fitters
64 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
65 Double_t &x2=t2[0], &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
69 Double_t snp1=tp1.GetSnp();
70 dydx1=snp1/TMath::Sqrt(1.-snp1*snp1);
71 Double_t tgl1=tp1.GetTgl();
72 // dz/dx = 1/(cos(theta)*cos(phi))
73 dzdx1=1./TMath::Sqrt((1.+tgl1*tgl1)*(1.-snp1*snp1));
77 Double_t snp2=tp2.GetSnp();
78 dydx2=snp2/TMath::Sqrt(1.-snp2*snp2);
79 Double_t tgl2=tp2.GetTgl();
80 dzdx1=1./TMath::Sqrt((1.+tgl2*tgl2)*(1.-snp2*snp2));
82 Process12(t1,t2,GetOrMakeFitter12(s1,s2));
83 Process9(t1,t2,GetOrMakeFitter12(s1,s2));
84 Process6(t1,t2,GetOrMakeFitter12(s1,s2));
88 void AliTPCcalibAlign::Process12(Double_t *t1,
90 TLinearFitter *fitter) {
91 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
92 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
93 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
94 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
95 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
97 // a00 a01 a02 a03 p[0] p[1] p[2] p[9]
98 // a10 a11 a12 a13 ==> p[3] p[4] p[5] p[10]
99 // a20 a21 a22 a23 p[6] p[7] p[8] p[11]
100 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
101 Double_t &x2=t2[0], &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
112 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
113 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
114 // y2' = a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
115 for (Int_t i=0; i<12;i++) p[i]=0.;
120 p[0+1] = y1*dydx2; // a01
121 p[0+2] = z1*dydx2; // a02
122 p[9+0] = dydx2; // a03
124 fitter->AddPoint(p,value,sy);
126 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
127 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
128 // z2' = a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 + a03)*dzdx2;
129 for (Int_t i=0; i<12;i++) p[i]=0.;
134 p[0+1] = y1*dzdx2; // a01
135 p[0+2] = z1*dzdx2; // a02
136 p[9+0] = dzdx2; // a03
138 fitter->AddPoint(p,value,sz);
140 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
141 // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
142 for (Int_t i=0; i<12;i++) p[i]=0.;
144 p[3+1] = dydx1; // a11
145 p[3+2] = dzdx1; // a12
146 p[0+0] = -dydx2; // a00
147 p[0+1] = -dydx1*dydx2; // a01
148 p[0+2] = -dzdx1*dydx2; // a02
150 fitter->AddPoint(p,value,sdydx);
152 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
153 // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
154 for (Int_t i=0; i<12;i++) p[i]=0.;
156 p[6+1] = dydx1; // a21
157 p[6+2] = dzdx1; // a22
158 p[0+0] = -dzdx2; // a00
159 p[0+1] = -dydx1*dzdx2; // a01
160 p[0+2] = -dzdx1*dzdx2; // a02
162 fitter->AddPoint(p,value,sdzdx);
165 void AliTPCcalibAlign::Process9(Double_t *t1,
167 TLinearFitter *fitter) {
168 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
169 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
170 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
171 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
172 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
174 // a00 a01 a02 a03 p[0] p[1] p[2] p[9]
175 // a10 a11 a12 a13 ==> p[3] p[4] p[5] p[10]
176 // a20 a21 a22 a23 p[6] p[7] p[8] p[11]
177 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
178 Double_t &x2=t2[0], &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
189 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
190 // y2 = a10*x1 + a11*y1 + a12*z1 + a13
191 // y2' = a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a03)*dydx2
192 for (Int_t i=0; i<12;i++) p[i]=0.;
201 fitter->AddPoint(p,value,sy);
203 // x2 = a00*x1 + a01*y1 + a02*z1 + a03
204 // z2 = a20*x1 + a21*y1 + a22*z1 + a23
205 // z2' = a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a03)*dzdx2;
206 for (Int_t i=0; i<12;i++) p[i]=0.;
215 fitter->AddPoint(p,value,sz);
217 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
218 // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
219 for (Int_t i=0; i<12;i++) p[i]=0.;
224 p[0+1] = -dydx1*dydx2;
225 p[0+2] = -dzdx1*dydx2;
227 fitter->AddPoint(p,value,sdydx);
229 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
230 // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
231 for (Int_t i=0; i<12;i++) p[i]=0.;
236 p[0+1] = -dydx1*dzdx2;
237 p[0+2] = -dzdx1*dzdx2;
239 fitter->AddPoint(p,value,sdzdx);
242 void AliTPCcalibAlign::Process6(Double_t *t1,
244 TLinearFitter *fitter) {
245 // x2 = 1 *x1 +-a01*y1 + 0 +a03
246 // y2 = a01*x1 + 1 *y1 + 0 +a13
247 // z2 = a20*x1 + a21*y1 + 1 *z1 +a23
248 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
249 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/(a00 + a01*dydx1 + a02*dzdx1)
251 // 1 -a01 0 a03 x -p[0] x p[3]
252 // a10 1 0 a13 ==> p[0] x x p[4]
253 // a20 a21 1 a23 p[1] p[2] x p[5]
254 Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
255 Double_t &x2=t2[0], &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
266 // x2 = 1 *x1 +-a01*y1 + 0 +a03
267 // y2 = a01*x1 + 1 *y1 + 0 +a13
268 // y2' = a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
269 for (Int_t i=0; i<12;i++) p[i]=0.;
278 fitter->AddPoint(p,value,sy);
280 // x2 = 1 *x1 +-a01*y1 + 0 + a03
281 // z2 = a20*x1 + a21*y1 + 1 *z1 + a23
282 // z2' = a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 +a03)*dzdx2;
283 for (Int_t i=0; i<12;i++) p[i]=0.;
292 fitter->AddPoint(p,value,sz);
294 // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
295 // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
296 for (Int_t i=0; i<12;i++) p[i]=0.;
301 p[0+1] = -dydx1*dydx2;
302 p[0+2] = -dzdx1*dydx2;
304 fitter->AddPoint(p,value,sdydx);
306 // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
307 // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
308 for (Int_t i=0; i<12;i++) p[i]=0.;
313 p[0+1] = -dydx1*dzdx2;
314 p[0+2] = -dzdx1*dzdx2;
316 fitter->AddPoint(p,value,sdzdx);
319 void AliTPCcalibAlign::Eval() {
321 for (Int_t s1=0;s1<72;++s1)
322 for (Int_t s2=0;s2<72;++s2)
323 if ((f=GetFitter12(s1,s2))&&fPoints[72*s1+s2]>12) {
324 // cerr<<s1<<","<<s2<<": "<<fPoints[72*s1+s2]<<endl;
326 cerr<<"Evaluation failed for "<<s1<<","<<s2<<endl;
333 chi212 = align->GetChisquare()/(4.*entries);
337 align->GetParameters(par);
338 align->GetCovarianceMatrix(mat);
342 for (Int_t i=0; i<12;i++){
343 palign12(i)= par(i+1);
344 for (Int_t j=0; j<12;j++){
345 pcovar12(i,j) = mat(i+1,j+1);
346 pcovar12(i,j) *= chi212;
350 for (Int_t i=0; i<12;i++){
351 psigma12(i) = TMath::Sqrt(pcovar12(i,i));
352 palignR12(i) = palign12(i)/TMath::Sqrt(pcovar12(i,i));
353 for (Int_t j=0; j<12;j++){
354 pcovarN12(i,j) = pcovar12(i,j)/TMath::Sqrt(pcovar12(i,i)*pcovar12(j,j));
360 Bool_t AliTPCcalibAlign::GetTransformation12(Int_t s1,Int_t s2,TMatrixD &a) {
361 if (!GetFitter12(s1,s2))
366 GetFitter12(s1,s2)->GetParameters(p);
389 Bool_t AliTPCcalibAlign::GetTransformation9(Int_t s1,Int_t s2,TMatrixD &a) {
390 if (!GetFitter9(s1,s2))
394 GetFitter9(s1,s2)->GetParameters(p);
416 Bool_t AliTPCcalibAlign::GetTransformation6(Int_t s1,Int_t s2,TMatrixD &a) {
417 if (!GetFitter6(s1,s2))
422 GetFitter6(s1,s2)->GetParameters(p);