Use the inteface from AliTPCcalibBase (Magnus)
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibAlign.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
17 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 //     Class to make a internal alignemnt of TPC chambers                    //
20 //
21 //     Different linear tranformation investigated
22 //     12 parameters - arbitrary transformation 
23 //      9 parameters - scaling fixed to 1
24 //      6 parameters - 
25 ////
26 //// Only the 12 parameter version works so far...
27 ////
28 ////
29 //// 
30
31 #include "TLinearFitter.h"
32 #include "AliTPCcalibAlign.h"
33 #include "AliExternalTrackParam.h"
34 #include "AliTPCTracklet.h"
35 #include "TH1D.h"
36
37 #include <iostream>
38 #include <sstream>
39 using namespace std;
40
41 ClassImp(AliTPCcalibAlign)
42
43 AliTPCcalibAlign::AliTPCcalibAlign()
44   :  fDphiHistArray(72*72),
45      fDthetaHistArray(72*72),
46      fDyHistArray(72*72),
47      fDzHistArray(72*72),
48      fFitterArray12(72*72),
49      fFitterArray9(72*72),
50      fFitterArray6(72*72)
51 {
52   //
53   // Constructor
54   //
55   for (Int_t i=0;i<72*72;++i) {
56     fPoints[i]=0;
57   }
58 }
59
60 AliTPCcalibAlign::~AliTPCcalibAlign() {
61   //
62   // destructor
63   //
64 }
65
66 void AliTPCcalibAlign::Process(AliTPCseed *seed) {
67   TObjArray tracklets=
68     AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kKalman,
69                                     kFALSE,20,2);
70   TObjArray trackletsL=
71     AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kLinear,
72                                     kFALSE,20,2);
73   TObjArray trackletsQ=
74     AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kQuadratic,
75                                     kFALSE,20,2);
76   TObjArray trackletsR=
77     AliTPCTracklet::CreateTracklets(seed,AliTPCTracklet::kRiemann,
78                                     kFALSE,20,2);
79   tracklets.SetOwner();
80   if (tracklets.GetEntries()==2) {
81     AliTPCTracklet *t1=static_cast<AliTPCTracklet*>(tracklets[0]);
82     AliTPCTracklet *t2=static_cast<AliTPCTracklet*>(tracklets[1]);
83     if (t1->GetSector()>t2->GetSector()) {
84       AliTPCTracklet* tmp=t1;
85       t1=t2;
86       t2=tmp;
87     }
88     AliExternalTrackParam *common1=0,*common2=0;
89     if (AliTPCTracklet::PropagateToMeanX(*t1,*t2,common1,common2))
90       ProcessTracklets(*common1,*common2,t1->GetSector(),t2->GetSector());
91     delete common1;
92     delete common2;
93   }
94
95 }
96
97 void AliTPCcalibAlign::ProcessTracklets(const AliExternalTrackParam &tp1,
98                                         const AliExternalTrackParam &tp2,
99                                         Int_t s1,Int_t s2) {
100
101   if (s2-s1==36) {//only inner-outer
102     if (!fDphiHistArray[s1*72+s2]) {
103       stringstream name;
104       stringstream title;
105       name<<"hist_phi_"<<s1<<"_"<<s2;
106       title<<"Phi Missalignment for sectors "<<s1<<" and "<<s2;
107       fDphiHistArray[s1*72+s2]=new TH1D(name.str().c_str(),title.str().c_str(),1024,-0.01,0.01); // +/- 10 mrad
108       ((TH1D*)fDphiHistArray[s1*72+s2])->SetDirectory(0);
109     }
110     if (!fDthetaHistArray[s1*72+s2]) {
111       stringstream name;
112       stringstream title;
113       name<<"hist_theta_"<<s1<<"_"<<s2;
114       title<<"Theta Missalignment for sectors "<<s1<<" and "<<s2;
115       fDthetaHistArray[s1*72+s2]=new TH1D(name.str().c_str(),title.str().c_str(),1024,-0.01,0.01); // +/- 10 mrad
116       ((TH1D*)fDthetaHistArray[s1*72+s2])->SetDirectory(0);
117     }
118     if (!fDyHistArray[s1*72+s2]) {
119       stringstream name;
120       stringstream title;
121       name<<"hist_y_"<<s1<<"_"<<s2;
122       title<<"Y Missalignment for sectors "<<s1<<" and "<<s2;
123       fDyHistArray[s1*72+s2]=new TH1D(name.str().c_str(),title.str().c_str(),1024,-0.3,0.3); // +/- 3 mm
124       ((TH1D*)fDyHistArray[s1*72+s2])->SetDirectory(0);
125     }
126     if (!fDzHistArray[s1*72+s2]) {
127       stringstream name;
128       stringstream title;
129       name<<"hist_z_"<<s1<<"_"<<s2;
130       title<<"Z Missalignment for sectors "<<s1<<" and "<<s2;
131       fDzHistArray[s1*72+s2]=new TH1D(name.str().c_str(),title.str().c_str(),1024,-0.3,0.3); // +/- 3 mm
132       ((TH1D*)fDzHistArray[s1*72+s2])->SetDirectory(0);
133     }
134     static_cast<TH1D*>(fDphiHistArray[s1*72+s2])
135       ->Fill(TMath::ASin(tp1.GetSnp())
136              -TMath::ASin(tp2.GetSnp()));
137     static_cast<TH1D*>(fDthetaHistArray[s1*72+s2])
138       ->Fill(TMath::ATan(tp1.GetTgl())
139              -TMath::ATan(tp2.GetTgl()));
140     static_cast<TH1D*>(fDyHistArray[s1*72+s2])
141       ->Fill(tp1.GetY()
142              -tp2.GetY());
143     static_cast<TH1D*>(fDzHistArray[s1*72+s2])
144       ->Fill(tp1.GetZ()
145              -tp2.GetZ());
146   }
147   return;
148
149
150
151   //
152   // Process function to fill fitters
153   //
154   Double_t t1[5],t2[5];
155   Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
156   Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3]/*, &dzdx2=t2[4]*/;
157   x1   =tp1.GetX();
158   y1   =tp1.GetY();
159   z1   =tp1.GetZ();
160   Double_t snp1=tp1.GetSnp();
161   dydx1=snp1/TMath::Sqrt(1.-snp1*snp1);
162   Double_t tgl1=tp1.GetTgl();
163   // dz/dx = 1/(cos(theta)*cos(phi))
164   dzdx1=1./TMath::Sqrt((1.+tgl1*tgl1)*(1.-snp1*snp1));
165   //  x2  =tp1->GetX();
166   y2   =tp2.GetY();
167   z2   =tp2.GetZ();
168   Double_t snp2=tp2.GetSnp();
169   dydx2=snp2/TMath::Sqrt(1.-snp2*snp2);
170   Double_t tgl2=tp2.GetTgl();
171   dzdx1=1./TMath::Sqrt((1.+tgl2*tgl2)*(1.-snp2*snp2));
172
173   Process12(t1,t2,GetOrMakeFitter12(s1,s2));
174   Process9(t1,t2,GetOrMakeFitter12(s1,s2));
175   Process6(t1,t2,GetOrMakeFitter12(s1,s2));
176   ++fPoints[72*s1+s2];
177 }
178
179 void AliTPCcalibAlign::Process12(Double_t *t1,
180                                  Double_t *t2,
181                                  TLinearFitter *fitter) {
182   // x2    =  a00*x1 + a01*y1 + a02*z1 + a03
183   // y2    =  a10*x1 + a11*y1 + a12*z1 + a13
184   // z2    =  a20*x1 + a21*y1 + a22*z1 + a23
185   // dydx2 = (a10    + a11*dydx1 + a12*dzdx1)/(a00    + a01*dydx1 + a02*dzdx1)
186   // dzdx2 = (a20    + a21*dydx1 + a22*dzdx1)/(a00    + a01*dydx1 + a02*dzdx1)
187   //
188   //       a00  a01 a02  a03     p[0]   p[1]  p[2]  p[9]
189   //       a10  a11 a12  a13 ==> p[3]   p[4]  p[5]  p[10]
190   //       a20  a21 a22  a23     p[6]   p[7]  p[8]  p[11] 
191   Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
192   Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
193
194   // TODO:
195   Double_t sy    = 1.;
196   Double_t sz    = 1.;
197   Double_t sdydx = 1.;
198   Double_t sdzdx = 1.;
199
200   Double_t p[12];
201   Double_t value;
202
203   // x2  =  a00*x1 + a01*y1 + a02*z1 + a03
204   // y2  =  a10*x1 + a11*y1 + a12*z1 + a13
205   // y2' =  a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
206   for (Int_t i=0; i<12;i++) p[i]=0.;
207   p[3+0] = x1;          // a10
208   p[3+1] = y1;          // a11
209   p[3+2] = z1;          // a12
210   p[9+1] = 1.;          // a13
211   p[0+1] = y1*dydx2;    // a01
212   p[0+2] = z1*dydx2;    // a02
213   p[9+0] = dydx2;       // a03
214   value  = y2;
215   fitter->AddPoint(p,value,sy);
216
217   // x2  =  a00*x1 + a01*y1 + a02*z1 + a03
218   // z2  =  a20*x1 + a21*y1 + a22*z1 + a23
219   // z2' =  a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 + a03)*dzdx2;
220   for (Int_t i=0; i<12;i++) p[i]=0.;
221   p[6+0] = x1;           // a20 
222   p[6+1] = y1;           // a21
223   p[6+2] = z1;           // a22
224   p[9+2] = 1.;           // a23
225   p[0+1] = y1*dzdx2;     // a01
226   p[0+2] = z1*dzdx2;     // a02
227   p[9+0] = dzdx2;        // a03
228   value  = z2;
229   fitter->AddPoint(p,value,sz);
230
231   // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
232   // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
233   for (Int_t i=0; i<12;i++) p[i]=0.;
234   p[3+0] = 1.;           // a10
235   p[3+1] = dydx1;        // a11
236   p[3+2] = dzdx1;        // a12
237   p[0+0] = -dydx2;       // a00
238   p[0+1] = -dydx1*dydx2; // a01
239   p[0+2] = -dzdx1*dydx2; // a02
240   value  = 0.;
241   fitter->AddPoint(p,value,sdydx);
242
243   // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
244   // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
245   for (Int_t i=0; i<12;i++) p[i]=0.;
246   p[6+0] = 1;            // a20
247   p[6+1] = dydx1;        // a21
248   p[6+2] = dzdx1;        // a22
249   p[0+0] = -dzdx2;       // a00
250   p[0+1] = -dydx1*dzdx2; // a01
251   p[0+2] = -dzdx1*dzdx2; // a02
252   value  = 0.;
253   fitter->AddPoint(p,value,sdzdx);
254 }
255
256 void AliTPCcalibAlign::Process9(Double_t *t1,
257                                 Double_t *t2,
258                                 TLinearFitter *fitter) {
259   // x2    =  a00*x1 + a01*y1 + a02*z1 + a03
260   // y2    =  a10*x1 + a11*y1 + a12*z1 + a13
261   // z2    =  a20*x1 + a21*y1 + a22*z1 + a23
262   // dydx2 = (a10    + a11*dydx1 + a12*dzdx1)/(a00    + a01*dydx1 + a02*dzdx1)
263   // dzdx2 = (a20    + a21*dydx1 + a22*dzdx1)/(a00    + a01*dydx1 + a02*dzdx1)
264   //
265   //       a00  a01 a02  a03     p[0]   p[1]  p[2]  p[9]
266   //       a10  a11 a12  a13 ==> p[3]   p[4]  p[5]  p[10]
267   //       a20  a21 a22  a23     p[6]   p[7]  p[8]  p[11] 
268   Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
269   Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
270
271   // TODO:
272   Double_t sy    = 1.;
273   Double_t sz    = 1.;
274   Double_t sdydx = 1.;
275   Double_t sdzdx = 1.;
276
277   Double_t p[12];
278   Double_t value;
279
280   // x2  =  a00*x1 + a01*y1 + a02*z1 + a03
281   // y2  =  a10*x1 + a11*y1 + a12*z1 + a13
282   // y2' =  a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a03)*dydx2
283   for (Int_t i=0; i<12;i++) p[i]=0.;
284   p[3+0] = x1;
285   p[3+1] = y1;
286   p[3+2] = z1;
287   p[9+1] = 1.;
288   p[0+1] = y1*dydx2;
289   p[0+2] = z1*dydx2;
290   p[9+0] = dydx2;
291   value  = y2;
292   fitter->AddPoint(p,value,sy);
293
294   // x2  =  a00*x1 + a01*y1 + a02*z1 + a03
295   // z2  =  a20*x1 + a21*y1 + a22*z1 + a23
296   // z2' =  a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a03)*dzdx2;
297   for (Int_t i=0; i<12;i++) p[i]=0.;
298   p[6+0] = x1;
299   p[6+1] = y1;
300   p[6+2] = z1;
301   p[9+2] = 1.;
302   p[0+1] = y1*dzdx2;
303   p[0+2] = z1*dzdx2;
304   p[9+0] = dzdx2;
305   value  = z2;
306   fitter->AddPoint(p,value,sz);
307
308   // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
309   // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
310   for (Int_t i=0; i<12;i++) p[i]=0.;
311   p[3+0] = 1.;
312   p[3+1] = dydx1;
313   p[3+2] = dzdx1;
314   p[0+0] = -dydx2;
315   p[0+1] = -dydx1*dydx2;
316   p[0+2] = -dzdx1*dydx2;
317   value  = 0.;
318   fitter->AddPoint(p,value,sdydx);
319
320   // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
321   // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
322   for (Int_t i=0; i<12;i++) p[i]=0.;
323   p[6+0] = 1;
324   p[6+1] = dydx1;
325   p[6+2] = dzdx1;
326   p[0+0] = -dzdx2;
327   p[0+1] = -dydx1*dzdx2;
328   p[0+2] = -dzdx1*dzdx2;
329   value  = 0.;
330   fitter->AddPoint(p,value,sdzdx);
331 }
332
333 void AliTPCcalibAlign::Process6(Double_t *t1,
334                                 Double_t *t2,
335                                 TLinearFitter *fitter) {
336   // x2    =  1  *x1 +-a01*y1 + 0      +a03
337   // y2    =  a01*x1 + 1  *y1 + 0      +a13
338   // z2    =  a20*x1 + a21*y1 + 1  *z1 +a23
339   // dydx2 = (a10    + a11*dydx1 + a12*dzdx1)/(a00    + a01*dydx1 + a02*dzdx1)
340   // dzdx2 = (a20    + a21*dydx1 + a22*dzdx1)/(a00    + a01*dydx1 + a02*dzdx1)
341   //
342   //       1   -a01 0    a03     x     -p[0]  x     p[3]
343   //       a10  1   0    a13 ==> p[0]   x     x     p[4]
344   //       a20  a21 1    a23     p[1]   p[2]  x     p[5] 
345   Double_t &x1=t1[0], &y1=t1[1], &z1=t1[2], &dydx1=t1[3], &dzdx1=t1[4];
346   Double_t /*&x2=t2[0],*/ &y2=t2[1], &z2=t2[2], &dydx2=t2[3], &dzdx2=t2[4];
347
348   // TODO:
349   Double_t sy    = 1.;
350   Double_t sz    = 1.;
351   Double_t sdydx = 1.;
352   Double_t sdzdx = 1.;
353
354   Double_t p[12];
355   Double_t value;
356
357   // x2  =  1  *x1 +-a01*y1 + 0      +a03
358   // y2  =  a01*x1 + 1  *y1 + 0      +a13
359   // y2' =  a10*x1 + a11*y1 + a12*z1 + a13 + (a01*y1 + a02*z1 + a03)*dydx2
360   for (Int_t i=0; i<12;i++) p[i]=0.;
361   p[3+0] = x1;
362   p[3+1] = y1;
363   p[3+2] = z1;
364   p[9+1] = 1.;
365   p[0+1] = y1*dydx2;
366   p[0+2] = z1*dydx2;
367   p[9+0] = dydx2;
368   value  = y2;
369   fitter->AddPoint(p,value,sy);
370
371   // x2  =  1  *x1 +-a01*y1 + 0      + a03
372   // z2  =  a20*x1 + a21*y1 + 1  *z1 + a23
373   // z2' =  a20*x1 + a21*y1 + a22*z1 + a23 + (a01*y1 + a02*z1 +a03)*dzdx2;
374   for (Int_t i=0; i<12;i++) p[i]=0.;
375   p[6+0] = x1;
376   p[6+1] = y1;
377   p[6+2] = z1;
378   p[9+2] = 1.;
379   p[0+1] = y1*dzdx2;
380   p[0+2] = z1*dzdx2;
381   p[9+0] = dzdx2;
382   value  = z2;
383   fitter->AddPoint(p,value,sz);
384
385   // dydx2 = (a10 + a11*dydx1 + a12*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
386   // (a10 + a11*dydx1 + a12*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dydx2 = 0
387   for (Int_t i=0; i<12;i++) p[i]=0.;
388   p[3+0] = 1.;
389   p[3+1] = dydx1;
390   p[3+2] = dzdx1;
391   p[0+0] = -dydx2;
392   p[0+1] = -dydx1*dydx2;
393   p[0+2] = -dzdx1*dydx2;
394   value  = 0.;
395   fitter->AddPoint(p,value,sdydx);
396
397   // dzdx2 = (a20 + a21*dydx1 + a22*dzdx1)/( a00 + a01*dydx1 + a02*dzdx1)
398   // (a20 + a21*dydx1 + a22*dzdx1) - (a00 + a01*dydx1 + a02*dzdx1)*dzdx2 = 0
399   for (Int_t i=0; i<12;i++) p[i]=0.;
400   p[6+0] = 1;
401   p[6+1] = dydx1;
402   p[6+2] = dzdx1;
403   p[0+0] = -dzdx2;
404   p[0+1] = -dydx1*dzdx2;
405   p[0+2] = -dzdx1*dzdx2;
406   value  = 0.;
407   fitter->AddPoint(p,value,sdzdx);
408 }
409
410 void AliTPCcalibAlign::Eval() {
411   TLinearFitter *f;
412   for (Int_t s1=0;s1<72;++s1)
413     for (Int_t s2=0;s2<72;++s2)
414       if ((f=GetFitter12(s1,s2))&&fPoints[72*s1+s2]>12) {
415         //      cerr<<s1<<","<<s2<<": "<<fPoints[72*s1+s2]<<endl;
416         if (!f->Eval()) {
417           cerr<<"Evaluation failed for "<<s1<<","<<s2<<endl;
418         }
419       }
420   /*
421                     
422   fitter->Eval();
423   fitter->Eval();
424   chi212 = align->GetChisquare()/(4.*entries);
425
426   TMatrixD mat(13,13);
427   TVectorD par(13);
428   align->GetParameters(par);
429   align->GetCovarianceMatrix(mat);
430
431   //
432   //
433   for (Int_t i=0; i<12;i++){
434     palign12(i)= par(i+1);
435     for (Int_t j=0; j<12;j++){
436       pcovar12(i,j)   = mat(i+1,j+1);
437       pcovar12(i,j) *= chi212;
438     }
439   }
440   //
441   for (Int_t i=0; i<12;i++){
442     psigma12(i)  = TMath::Sqrt(pcovar12(i,i));
443     palignR12(i) = palign12(i)/TMath::Sqrt(pcovar12(i,i));
444     for (Int_t j=0; j<12;j++){
445       pcovarN12(i,j) = pcovar12(i,j)/TMath::Sqrt(pcovar12(i,i)*pcovar12(j,j));
446     }
447   }
448   */
449 }
450
451 Bool_t AliTPCcalibAlign::GetTransformation12(Int_t s1,Int_t s2,TMatrixD &a) {
452   if (!GetFitter12(s1,s2))
453     return false;
454   else {
455     TVectorD p(12);
456     cerr<<"foo"<<endl;
457     GetFitter12(s1,s2)->GetParameters(p);
458     cerr<<"bar"<<endl;
459     a.ResizeTo(4,4);
460     a[0][0]=p[0];
461     a[0][1]=p[1];
462     a[0][2]=p[2];
463     a[0][3]=p[9];
464     a[1][0]=p[3];
465     a[1][1]=p[4];
466     a[1][2]=p[5];
467     a[1][3]=p[10];
468     a[2][0]=p[6];
469     a[2][1]=p[7];
470     a[2][2]=p[8];
471     a[2][3]=p[11];
472     a[3][0]=0.;
473     a[3][1]=0.;
474     a[3][2]=0.;
475     a[3][3]=1.;
476     return true;
477   } 
478 }
479
480 Bool_t AliTPCcalibAlign::GetTransformation9(Int_t s1,Int_t s2,TMatrixD &a) {
481   if (!GetFitter9(s1,s2))
482     return false;
483   else {
484     TVectorD p(9);
485     GetFitter9(s1,s2)->GetParameters(p);
486     a.ResizeTo(4,4);
487     a[0][0]=p[0];
488     a[0][1]=p[1];
489     a[0][2]=p[2];
490     a[0][3]=p[9];
491     a[1][0]=p[3];
492     a[1][1]=p[4];
493     a[1][2]=p[5];
494     a[1][3]=p[10];
495     a[2][0]=p[6];
496     a[2][1]=p[7];
497     a[2][2]=p[8];
498     a[2][3]=p[11];
499     a[3][0]=0.;
500     a[3][1]=0.;
501     a[3][2]=0.;
502     a[3][3]=1.;
503     return true;
504   } 
505 }
506
507 Bool_t AliTPCcalibAlign::GetTransformation6(Int_t s1,Int_t s2,TMatrixD &a) {
508   if (!GetFitter6(s1,s2))
509     return false;
510   else {
511     TVectorD p(6);
512     cerr<<"foo"<<endl;
513     GetFitter6(s1,s2)->GetParameters(p);
514     cerr<<"bar"<<endl;
515     a.ResizeTo(4,4);
516     a[0][0]=p[0];
517     a[0][1]=p[1];
518     a[0][2]=p[2];
519     a[0][3]=p[9];
520     a[1][0]=p[3];
521     a[1][1]=p[4];
522     a[1][2]=p[5];
523     a[1][3]=p[10];
524     a[2][0]=p[6];
525     a[2][1]=p[7];
526     a[2][2]=p[8];
527     a[2][3]=p[11];
528     a[3][0]=0.;
529     a[3][1]=0.;
530     a[3][2]=0.;
531     a[3][3]=1.;
532     return true;
533   } 
534 }