]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDseed.cxx
- revert to the old version of tracklet (no row pad cross)
[u/mrichter/AliRoot.git] / TRD / AliTRDseed.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  The seed of a local TRD track                                            //  
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include "TMath.h"
25 #include "TLinearFitter.h"
26
27 #include "AliMathBase.h"
28
29 #include "AliTRDseed.h"
30 #include "AliTRDcalibDB.h"
31 #include "AliTRDcluster.h"
32 #include "AliTRDtracker.h"
33 #include "AliTRDtrackerV1.h"
34
35 ClassImp(AliTRDseed)
36
37 //_____________________________________________________________________________
38 AliTRDseed::AliTRDseed() 
39   :TObject()
40   ,fTilt(0)
41   ,fPadLength(0)
42   ,fX0(0)
43   ,fSigmaY(0)
44   ,fSigmaY2(0)
45   ,fMeanz(0)
46   ,fZProb(0)
47   ,fN(0)
48   ,fN2(0)
49   ,fNUsed(0)
50   ,fFreq(0)
51   ,fNChange(0)
52   ,fMPads(0)
53   ,fC(0)
54   ,fCC(0)
55   ,fChi2(1.0e10)
56   ,fChi2Z(1.0e10)
57 {
58   //
59   // Default constructor  
60   //
61
62   for (Int_t i = 0; i < knTimebins; i++) {
63     fX[i]        = 0;   // x position
64     fY[i]        = 0;   // y position
65     fZ[i]        = 0;   // z position
66     fIndexes[i]  = 0;   // Indexes
67     fClusters[i] = 0x0; // Clusters
68     fUsable[i]   = 0;   // Indication  - usable cluster
69   }
70
71   for (Int_t i = 0; i < 2; i++) {
72     fYref[i]     = 0;   // Reference y
73     fZref[i]     = 0;   // Reference z
74     fYfit[i]     = 0;   // Y fit position +derivation
75     fYfitR[i]    = 0;   // Y fit position +derivation
76     fZfit[i]     = 0;   // Z fit position
77     fZfitR[i]    = 0;   // Z fit position
78     fLabels[i]   = 0;   // Labels
79   }
80
81 }
82
83 //_____________________________________________________________________________
84 AliTRDseed::AliTRDseed(const AliTRDseed &s)
85   :TObject(s)
86   ,fTilt(s.fTilt)
87   ,fPadLength(s.fPadLength)
88   ,fX0(s.fX0)
89   ,fSigmaY(s.fSigmaY)
90   ,fSigmaY2(s.fSigmaY2)
91   ,fMeanz(s.fMeanz)
92   ,fZProb(s.fZProb)
93   ,fN(s.fN)
94   ,fN2(s.fN2)
95   ,fNUsed(s.fNUsed)
96   ,fFreq(s.fFreq)
97   ,fNChange(s.fNChange)
98   ,fMPads(s.fMPads)
99   ,fC(s.fC)
100   ,fCC(s.fCC)
101   ,fChi2(s.fChi2)
102   ,fChi2Z(s.fChi2Z)
103 {
104   //
105   // Copy constructor  
106   //
107
108   for (Int_t i = 0; i < knTimebins; i++) {
109     fX[i]        = s.fX[i];        // x position
110     fY[i]        = s.fY[i];        // y position
111     fZ[i]        = s.fZ[i];        // z position
112     fIndexes[i]  = s.fIndexes[i];  // Indexes
113     fClusters[i] = s.fClusters[i]; // Clusters
114     fUsable[i]   = s.fUsable[i];   // Indication  - usable cluster
115   }
116
117   for (Int_t i = 0; i < 2; i++) {
118     fYref[i]     = s.fYref[i];     // Reference y
119     fZref[i]     = s.fZref[i];     // Reference z
120     fYfit[i]     = s.fYfit[i];     // Y fit position +derivation
121     fYfitR[i]    = s.fYfitR[i];    // Y fit position +derivation
122     fZfit[i]     = s.fZfit[i];     // Z fit position
123     fZfitR[i]    = s.fZfitR[i];    // Z fit position
124     fLabels[i]   = s.fLabels[i];   // Labels
125   }
126
127 }
128
129 //_____________________________________________________________________________
130 void AliTRDseed::Copy(TObject &o) const
131 {
132         //printf("AliTRDseed::Copy()\n");
133
134         AliTRDseed &seed = (AliTRDseed &)o;
135   
136         seed.fTilt = fTilt;
137   seed.fPadLength = fPadLength;
138   seed.fX0 = fX0;
139   seed.fSigmaY = fSigmaY;
140   seed.fSigmaY2 = fSigmaY2;
141   seed.fMeanz = fMeanz;
142   seed.fZProb = fZProb;
143   seed.fN = fN;
144   seed.fN2 = fN2;
145   seed.fNUsed = fNUsed;
146   seed.fFreq = fFreq;
147   seed.fNChange = fNChange;
148   seed.fMPads = fMPads;
149   seed.fC = fC;
150   seed.fCC = fCC;
151   seed.fChi2 = fChi2;
152   seed.fChi2Z = fChi2Z;
153         for (Int_t i = 0; i < knTimebins; i++) {
154     seed.fX[i]        = fX[i];
155     seed.fY[i]        = fY[i]; 
156     seed.fZ[i]        = fZ[i]; 
157     seed.fIndexes[i]  = fIndexes[i]; 
158     seed.fClusters[i] = fClusters[i]; 
159     seed.fUsable[i]   = fUsable[i]; 
160   }
161
162   for (Int_t i = 0; i < 2; i++) {
163     seed.fYref[i]     = fYref[i];
164     seed.fZref[i]     = fZref[i];
165     seed.fYfit[i]     = fYfit[i];
166     seed.fYfitR[i]    = fYfitR[i]; 
167     seed.fZfit[i]     = fZfit[i]; 
168     seed.fZfitR[i]    = fZfitR[i];  
169     seed.fLabels[i]   = fLabels[i]; 
170   }
171
172   TObject::Copy(seed);
173
174 }
175
176 //_____________________________________________________________________________
177 void AliTRDseed::Reset()
178 {
179   //
180   // Reset seed
181   //
182
183   for (Int_t i = 0; i < knTimebins; i++) {
184     fX[i]        = 0;  // X position
185     fY[i]        = 0;  // Y position
186     fZ[i]        = 0;  // Z position
187     fIndexes[i]  = 0;  // Indexes
188     fClusters[i] = 0x0;  // Clusters
189     fUsable[i]   = kFALSE;    
190   }
191
192   for (Int_t i = 0; i < 2; i++) {
193     fYref[i]     = 0;  // Reference y
194     fZref[i]     = 0;  // Reference z
195     fYfit[i]     = 0;  // Y fit position +derivation
196     fYfitR[i]    = 0;  // Y fit position +derivation
197     fZfit[i]     = 0;  // Z fit position
198     fZfitR[i]    = 0;  // Z fit position
199     fLabels[i]   = -1; // Labels
200   }
201   fSigmaY  = 0;        // "Robust" sigma in y
202   fSigmaY2 = 0;        // "Robust" sigma in y
203   fMeanz   = 0;        // Mean vaue of z
204   fZProb   = 0;        // Max probbable z
205   fMPads   = 0;
206   fN       = 0;        // Number of associated clusters
207   fN2      = 0;        // Number of not crossed
208   fNUsed   = 0;        // Number of used clusters
209   fNChange = 0;        // Change z counter
210
211 }
212
213 //_____________________________________________________________________________
214 void AliTRDseed::CookLabels()
215 {
216   //
217   // Cook 2 labels for seed
218   //
219
220   Int_t labels[200];
221   Int_t out[200];
222   Int_t nlab = 0;
223
224   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
225     if (!fClusters[i]) continue;
226     for (Int_t ilab = 0; ilab < 3; ilab++) {
227       if (fClusters[i]->GetLabel(ilab) >= 0) {
228         labels[nlab] = fClusters[i]->GetLabel(ilab);
229         nlab++;
230       }
231     }
232   }
233
234   Int_t nlab2 = AliTRDtracker::Freq(nlab,labels,out,kTRUE);
235   fLabels[0] = out[0];
236   if ((nlab2  > 1) && 
237       (out[3] > 1)) {
238     fLabels[1] = out[2];
239   }
240
241 }
242
243 //_____________________________________________________________________________
244 void AliTRDseed::UseClusters()
245 {
246   //
247   // Use clusters
248   //
249
250   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
251     if (!fClusters[i]) continue;
252     if (!(fClusters[i]->IsUsed())) fClusters[i]->Use();
253   }
254
255 }
256
257 //_____________________________________________________________________________
258 void AliTRDseed::Update()
259 {
260   //
261   // Update the seed.
262   //
263
264
265
266         // linear fit on the y direction with respect to the reference direction. 
267         // The residuals for each x (x = xc - x0) are deduced from:
268         // dy = y - yt             (1)
269         // the tilting correction is written :
270         // y = yc + h*(zc-zt)      (2)
271         // yt = y0+dy/dx*x         (3)
272         // zt = z0+dz/dx*x         (4)
273         // from (1),(2),(3) and (4)
274         // dy = yc - y0 - (dy/dx + h*dz/dx)*x + h*(zc-z0)
275         // the last term introduces the correction on y direction due to tilting pads. There are 2 ways to account for this:
276         // 1. use tilting correction for calculating the y
277         // 2. neglect tilting correction here and account for it in the error parametrization of the tracklet.
278
279   const Float_t kRatio  = 0.8;
280   const Int_t   kClmin  = 5;
281   const Float_t kmaxtan = 2;
282
283   if (TMath::Abs(fYref[1]) > kmaxtan){
284                 //printf("Exit: Abs(fYref[1]) = %3.3f, kmaxtan = %3.3f\n", TMath::Abs(fYref[1]), kmaxtan);
285                 return;              // Track inclined too much
286         }
287
288   Float_t  sigmaexp  = 0.05 + TMath::Abs(fYref[1] * 0.25); // Expected r.m.s in y direction
289   Float_t  ycrosscor = fPadLength * fTilt * 0.5;           // Y correction for crossing 
290   fNChange = 0;
291
292   Double_t sumw;
293   Double_t sumwx;
294   Double_t sumwx2;
295   Double_t sumwy;
296   Double_t sumwxy;
297   Double_t sumwz;
298   Double_t sumwxz;
299
300         // Buffering: Leave it constant fot Performance issues
301   Int_t    zints[knTimebins];            // Histograming of the z coordinate 
302                                          // Get 1 and second max probable coodinates in z
303   Int_t    zouts[2*knTimebins];       
304   Float_t  allowedz[knTimebins];         // Allowed z for given time bin
305   Float_t  yres[knTimebins];             // Residuals from reference
306   Float_t  anglecor = fTilt * fZref[1];  // Correction to the angle
307   
308   
309   fN  = 0; 
310   fN2 = 0;
311   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
312     yres[i] = 10000.0;
313     if (!fClusters[i]) continue;
314     if(!fClusters[i]->IsInChamber()) continue;
315     yres[i] = fY[i] - fYref[0] - (fYref[1] + anglecor) * fX[i] + fTilt*(fZ[i] - fZref[0]);   // Residual y
316     zints[fN] = Int_t(fZ[i]);
317     fN++;    
318   }
319
320   if (fN < kClmin){
321                 //printf("Exit fN < kClmin: fN = %d\n", fN);
322                 return; 
323         }
324   Int_t nz = AliTRDtracker::Freq(fN, zints, zouts, kFALSE);
325   fZProb   = zouts[0];
326   if (nz <= 1) zouts[3] = 0;
327   if (zouts[1] + zouts[3] < kClmin) {
328                 //printf("Exit zouts[1] = %d, zouts[3] = %d\n",zouts[1],zouts[3]);
329                 return;
330         }
331   
332   // Z distance bigger than pad - length
333   if (TMath::Abs(zouts[0]-zouts[2]) > 12.0) zouts[3] = 0;
334   
335   Int_t  breaktime = -1;
336   Bool_t mbefore   = kFALSE;
337   Int_t  cumul[knTimebins][2];
338   Int_t  counts[2] = { 0, 0 };
339   
340   if (zouts[3] >= 3) {
341
342     //
343     // Find the break time allowing one chage on pad-rows
344     // with maximal number of accepted clusters
345     //
346     fNChange = 1;
347     for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
348       cumul[i][0] = counts[0];
349       cumul[i][1] = counts[1];
350       if (TMath::Abs(fZ[i]-zouts[0]) < 2) counts[0]++;
351       if (TMath::Abs(fZ[i]-zouts[2]) < 2) counts[1]++;
352     }
353     Int_t  maxcount = 0;
354     for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
355       Int_t after  = cumul[AliTRDtrackerV1::GetNTimeBins()][0] - cumul[i][0];
356       Int_t before = cumul[i][1];
357       if (after + before > maxcount) { 
358         maxcount  = after + before; 
359         breaktime = i;
360         mbefore   = kFALSE;
361       }
362       after  = cumul[AliTRDtrackerV1::GetNTimeBins()-1][1] - cumul[i][1];
363       before = cumul[i][0];
364       if (after + before > maxcount) { 
365         maxcount  = after + before; 
366         breaktime = i;
367         mbefore   = kTRUE;
368       }
369     }
370
371     breaktime -= 1;
372
373   }
374
375   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
376     if (i >  breaktime) allowedz[i] =   mbefore  ? zouts[2] : zouts[0];
377     if (i <= breaktime) allowedz[i] = (!mbefore) ? zouts[2] : zouts[0];
378   }  
379
380   if (((allowedz[0] > allowedz[AliTRDtrackerV1::GetNTimeBins()]) && (fZref[1] < 0)) ||
381       ((allowedz[0] < allowedz[AliTRDtrackerV1::GetNTimeBins()]) && (fZref[1] > 0))) {
382     //
383     // Tracklet z-direction not in correspondance with track z direction 
384     //
385     fNChange = 0;
386     for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
387       allowedz[i] = zouts[0];  // Only longest taken
388     } 
389   }
390   
391   if (fNChange > 0) {
392     //
393     // Cross pad -row tracklet  - take the step change into account
394     //
395     for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
396       if (!fClusters[i]) continue; 
397       if(!fClusters[i]->IsInChamber()) continue;
398       if (TMath::Abs(fZ[i] - allowedz[i]) > 2) continue;
399       yres[i] = fY[i] - fYref[0] - (fYref[1] + anglecor) * fX[i] /*+ fTilt*(fZ[i] - fZref[0])*/;   // Residual y
400       if (TMath::Abs(fZ[i] - fZProb) > 2) {
401         if (fZ[i] > fZProb) yres[i] += fTilt * fPadLength;
402         if (fZ[i] < fZProb) yres[i] -= fTilt * fPadLength;
403       }
404     }
405   }
406   
407   Double_t yres2[knTimebins];
408   Double_t mean;
409   Double_t sigma;
410   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
411     if (!fClusters[i]) continue;
412     if(!fClusters[i]->IsInChamber()) continue;
413     if (TMath::Abs(fZ[i] - allowedz[i]) > 2) continue;
414     yres2[fN2] = yres[i];
415     fN2++;
416   }
417   if (fN2 < kClmin) {
418                 //printf("Exit fN2 < kClmin: fN2 = %d\n", fN2);
419     fN2 = 0;
420     return;
421   }
422   AliMathBase::EvaluateUni(fN2,yres2,mean,sigma, Int_t(fN2*kRatio-2.));
423   if (sigma < sigmaexp * 0.8) {
424     sigma = sigmaexp;
425   }
426   fSigmaY = sigma;
427
428   // Reset sums
429   sumw   = 0; 
430   sumwx  = 0; 
431   sumwx2 = 0;
432   sumwy  = 0; 
433   sumwxy = 0; 
434   sumwz  = 0;
435   sumwxz = 0;
436
437   fN2    = 0;
438   fMeanz = 0;
439   fMPads = 0;
440
441   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
442
443     fUsable[i] = kFALSE;
444     if (!fClusters[i]) continue;
445     if (!fClusters[i]->IsInChamber()) continue;
446     if (TMath::Abs(fZ[i] - allowedz[i]) > 2){fClusters[i] = 0x0; continue;}
447     if (TMath::Abs(yres[i] - mean) > 4.0 * sigma){fClusters[i] = 0x0;  continue;}
448     fUsable[i] = kTRUE;
449     fN2++;
450     fMPads += fClusters[i]->GetNPads();
451     Float_t weight = 1.0;
452     if (fClusters[i]->GetNPads() > 4) weight = 0.5;
453     if (fClusters[i]->GetNPads() > 5) weight = 0.2;
454    
455         
456     Double_t x = fX[i];
457     //printf("x = %7.3f dy = %7.3f fit %7.3f\n", x, yres[i], fY[i]-yres[i]);
458     
459     sumw   += weight; 
460     sumwx  += x * weight; 
461     sumwx2 += x*x * weight;
462     sumwy  += weight * yres[i];  
463     sumwxy += weight * (yres[i]) * x;
464     sumwz  += weight * fZ[i];    
465     sumwxz += weight * fZ[i] * x;
466
467   }
468
469   if (fN2 < kClmin){
470                 //printf("Exit fN2 < kClmin(2): fN2 = %d\n",fN2);
471     fN2 = 0;
472     return;
473   }
474   fMeanz = sumwz / sumw;
475   Float_t correction = 0;
476   if (fNChange > 0) {
477     // Tracklet on boundary
478     if (fMeanz < fZProb) correction =  ycrosscor;
479     if (fMeanz > fZProb) correction = -ycrosscor;
480   }
481
482   Double_t det = sumw * sumwx2 - sumwx * sumwx;
483   fYfitR[0]    = (sumwx2 * sumwy  - sumwx * sumwxy) / det;
484   fYfitR[1]    = (sumw   * sumwxy - sumwx * sumwy)  / det;
485   
486   fSigmaY2 = 0;
487   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
488     if (!fUsable[i]) continue;
489     Float_t delta = yres[i] - fYfitR[0] - fYfitR[1] * fX[i];
490     fSigmaY2 += delta*delta;
491   }
492   fSigmaY2 = TMath::Sqrt(fSigmaY2 / Float_t(fN2-2));
493         // TEMPORARY UNTIL covariance properly calculated
494         fSigmaY2 = TMath::Max(fSigmaY2, Float_t(.1));
495   
496   fZfitR[0]  = (sumwx2 * sumwz  - sumwx * sumwxz) / det;
497   fZfitR[1]  = (sumw   * sumwxz - sumwx * sumwz)  / det;
498   fZfit[0]   = (sumwx2 * sumwz  - sumwx * sumwxz) / det;
499   fZfit[1]   = (sumw   * sumwxz - sumwx * sumwz)  / det;
500   fYfitR[0] += fYref[0] + correction;
501   fYfitR[1] += fYref[1];
502   fYfit[0]   = fYfitR[0];
503   fYfit[1]   = fYfitR[1];
504
505         //printf("y0 = %7.3f tgy = %7.3f z0 = %7.3f tgz = %7.3f \n", fYfitR[0], fYfitR[1], fZfitR[0], fZfitR[1]);
506
507   UpdateUsed();
508
509 }
510
511 //_____________________________________________________________________________
512 void AliTRDseed::UpdateUsed()
513 {
514   //
515   // Update used seed
516   //
517
518   fNUsed = 0;
519   for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
520     if (!fClusters[i]) continue;
521                 if(!fUsable[i]) continue;   
522     if ((fClusters[i]->IsUsed())) fNUsed++;
523   }
524
525 }
526
527 //_____________________________________________________________________________
528 Float_t AliTRDseed::FitRiemanTilt(AliTRDseed * cseed, Bool_t terror)
529 {
530   //
531   // Fit the Rieman tilt
532   //
533
534   // Fitting with tilting pads - kz not fixed
535   TLinearFitter fitterT2(4,"hyp4");  
536   fitterT2.StoreData(kTRUE);
537         
538   Float_t xref2 = (cseed[2].fX0 + cseed[3].fX0) * 0.5; // Reference x0 for z
539   
540   Int_t npointsT = 0;
541   fitterT2.ClearPoints();
542
543   for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
544
545     if (!cseed[iLayer].IsOK()) continue;
546     Double_t tilt = cseed[iLayer].fTilt;
547
548     for (Int_t itime = 0; itime < AliTRDtrackerV1::GetNTimeBins()+1; itime++) {
549
550       if (!cseed[iLayer].fUsable[itime]) continue;
551       // x relative to the midle chamber
552       Double_t x = cseed[iLayer].fX[itime] + cseed[iLayer].fX0 - xref2;  
553       Double_t y = cseed[iLayer].fY[itime];
554       Double_t z = cseed[iLayer].fZ[itime];
555
556       //
557       // Tilted rieman
558       //
559       Double_t uvt[6];
560       Double_t x2 = cseed[iLayer].fX[itime] + cseed[iLayer].fX0;      // Global x
561       Double_t t  = 1.0 / (x2*x2 + y*y);
562       uvt[1]  = t;
563       uvt[0]  = 2.0 * x2   * uvt[1];
564       uvt[2]  = 2.0 * tilt * uvt[1];
565       uvt[3]  = 2.0 * tilt *uvt[1] * x;       
566       uvt[4]  = 2.0 * (y + tilt * z) * uvt[1];
567       
568       Double_t error = 2.0 * uvt[1];
569       if (terror) {
570         error *= cseed[iLayer].fSigmaY;
571       }
572       else {
573         error *= 0.2; //Default error
574       } 
575       fitterT2.AddPoint(uvt,uvt[4],error);
576       npointsT++;
577
578     }
579
580   }
581
582   fitterT2.Eval();
583   Double_t rpolz0 = fitterT2.GetParameter(3);
584   Double_t rpolz1 = fitterT2.GetParameter(4);       
585
586   //
587   // Linear fitter  - not possible to make boundaries
588   // non accept non possible z and dzdx combination
589   //        
590   Bool_t acceptablez = kTRUE;
591   for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
592     if (!cseed[iLayer].IsOK()) continue;
593     Double_t zT2 = rpolz0 + rpolz1 * (cseed[iLayer].fX0 - xref2);
594     if (TMath::Abs(cseed[iLayer].fZProb - zT2) > cseed[iLayer].fPadLength * 0.5 + 1.0) acceptablez = kFALSE;
595   }
596   if (!acceptablez) {
597     Double_t zmf  = cseed[2].fZref[0] + cseed[2].fZref[1] * (xref2 - cseed[2].fX0);
598     Double_t dzmf = (cseed[2].fZref[1] + cseed[3].fZref[1]) * 0.5;
599     fitterT2.FixParameter(3,zmf);
600     fitterT2.FixParameter(4,dzmf);
601     fitterT2.Eval();
602     fitterT2.ReleaseParameter(3);
603     fitterT2.ReleaseParameter(4);
604     rpolz0 = fitterT2.GetParameter(3);
605     rpolz1 = fitterT2.GetParameter(4);
606   }
607   
608   Double_t chi2TR = fitterT2.GetChisquare() / Float_t(npointsT);  
609   Double_t params[3];
610   params[0] =  fitterT2.GetParameter(0);
611   params[1] =  fitterT2.GetParameter(1);
612   params[2] =  fitterT2.GetParameter(2);            
613   Double_t curvature =  1.0 + params[1] * params[1] - params[2] * params[0];
614
615         
616   for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
617     Double_t  x  = cseed[iLayer].fX0;
618     Double_t  y  = 0;
619     Double_t  dy = 0;
620     Double_t  z  = 0;
621     Double_t  dz = 0;
622
623     // y
624     Double_t res2 = (x * params[0] + params[1]);
625     res2 *= res2;
626     res2  = 1.0 - params[2]*params[0] + params[1]*params[1] - res2;
627     if (res2 >= 0) {
628       res2 = TMath::Sqrt(res2);
629       y    = (1.0 - res2) / params[0];
630     }
631
632     //dy
633     Double_t x0 = -params[1] / params[0];
634     if (-params[2]*params[0] + params[1]*params[1] + 1 > 0) {
635       Double_t rm1 = params[0] / TMath::Sqrt(-params[2]*params[0] + params[1]*params[1] + 1); 
636       if (1.0/(rm1*rm1) - (x-x0) * (x-x0) > 0.0) {
637                                 Double_t res = (x - x0) / TMath::Sqrt(1.0 / (rm1*rm1) - (x-x0)*(x-x0));
638                                 if (params[0] < 0) res *= -1.0;
639                                 dy = res;
640       }
641     }
642     z  = rpolz0 + rpolz1 * (x - xref2);
643     dz = rpolz1;
644     cseed[iLayer].fYref[0] = y;
645     cseed[iLayer].fYref[1] = dy;
646     cseed[iLayer].fZref[0] = z;
647     cseed[iLayer].fZref[1] = dz;
648     cseed[iLayer].fC       = curvature;
649     
650   }
651
652   return chi2TR;
653
654 }