]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliTrackFitterRieman.cxx
track matching macros from Alberto
[u/mrichter/AliRoot.git] / STEER / AliTrackFitterRieman.cxx
CommitLineData
6b6cba33 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// Class to the track points on the Riemann sphere. Inputs are
21// the set of id's (volids) of the volumes in which residuals are
22// calculated to construct a chi2 function to be minimized during
23// the alignment procedures. For the moment the track extrapolation is
24// taken at the space-point reference plane. The reference plane is
25// found using the covariance matrix of the point
26// (assuming sigma(x)=0 at the reference coordinate system.
27//
8849da04 28// Internal usage of AliRieman class for minimization
29//
6b6cba33 30//////////////////////////////////////////////////////////////////////////////
31
98937d93 32#include "TMatrixDSym.h"
33#include "TMatrixD.h"
8849da04 34#include "TArrayI.h"
dfce6628 35#include "TLinearFitter.h"
98937d93 36#include "AliTrackFitterRieman.h"
24d4520d 37#include "AliLog.h"
8849da04 38#include "TTreeStream.h"
39#include "AliRieman.h"
40#include "AliLog.h"
dfce6628 41#include "TRandom.h"
98937d93 42
43ClassImp(AliTrackFitterRieman)
44
8849da04 45
98937d93 46AliTrackFitterRieman::AliTrackFitterRieman():
75e3794b 47 AliTrackFitter(),
dfce6628 48 fBCorrection(kFALSE),
75e3794b 49 fAlpha(0.),
50 fNUsed(0),
51 fConv(kFALSE),
52 fMaxDelta(3),
53 fRieman(new AliRieman(10000)), // allocate rieman
54 fDebugStream(new TTreeSRedirector("RiemanAlignDebug.root"))
98937d93 55{
56 //
57 // default constructor
58 //
98937d93 59}
60
61
62AliTrackFitterRieman::AliTrackFitterRieman(AliTrackPointArray *array, Bool_t owner):
75e3794b 63 AliTrackFitter(array,owner),
dfce6628 64 fBCorrection(kFALSE),
75e3794b 65 fAlpha(0.),
66 fNUsed(0),
67 fConv(kFALSE),
68 fMaxDelta(3),
69 fRieman(new AliRieman(10000)), //allocate rieman
70 fDebugStream(0)
98937d93 71{
72 //
73 // Constructor
74 //
8849da04 75 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")) fDebugStream = new TTreeSRedirector("RiemanAlignDebug.root");
98937d93 76}
77
78AliTrackFitterRieman::AliTrackFitterRieman(const AliTrackFitterRieman &rieman):
75e3794b 79 AliTrackFitter(rieman),
dfce6628 80 fBCorrection(rieman.fBCorrection),
75e3794b 81 fAlpha(rieman.fAlpha),
82 fNUsed(rieman.fNUsed),
83 fConv(rieman.fConv),
84 fMaxDelta(rieman.fMaxDelta),
85 fRieman(new AliRieman(*(rieman.fRieman))),
86 fDebugStream(0)
98937d93 87{
88 //
89 // copy constructor
90 //
75e3794b 91 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")) fDebugStream = new TTreeSRedirector("RiemanAlignDebug.root");
98937d93 92}
93
94//_____________________________________________________________________________
95AliTrackFitterRieman &AliTrackFitterRieman::operator =(const AliTrackFitterRieman& rieman)
96{
6b6cba33 97 //
98 // Assignment operator
98937d93 99 //
100 if(this==&rieman) return *this;
101 ((AliTrackFitter *)this)->operator=(rieman);
102
dfce6628 103 fBCorrection = rieman.fBCorrection;
8849da04 104 fAlpha = rieman.fAlpha;
105 fNUsed = rieman.fNUsed;
106 fConv = rieman.fConv;
186e6ced 107 fMaxDelta = rieman.fMaxDelta;
8849da04 108 fRieman = new AliRieman(*(rieman.fRieman));
75e3794b 109 fDebugStream = 0;
110 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")) fDebugStream = new TTreeSRedirector("RiemanAlignDebug.root");
98937d93 111 return *this;
112}
113
8849da04 114
115AliTrackFitterRieman::~AliTrackFitterRieman(){
116 //
117 //
118 //
119 delete fRieman;
120 delete fDebugStream;
121}
122
98937d93 123void AliTrackFitterRieman::Reset()
124{
125 // Reset the track parameters and
126 // rieman sums
6b6cba33 127 //
98937d93 128 AliTrackFitter::Reset();
8849da04 129 fRieman->Reset();
98937d93 130 fAlpha = 0.;
46ae650f 131 fNUsed = 0;
98937d93 132 fConv =kFALSE;
133}
134
cc345ce3 135Bool_t AliTrackFitterRieman::Fit(const TArrayI *volIds,const TArrayI *volIdsFit,
98937d93 136 AliAlignObj::ELayerID layerRangeMin,
8849da04 137 AliAlignObj::ELayerID layerRangeMax)
98937d93 138{
139 // Fit the track points. The method takes as an input
cc345ce3 140 // the set of id's (volids) of the volumes in which
141 // one wants to calculate the residuals.
142 // The following parameters are used to define the
98937d93 143 // range of volumes to be used in the fitting
144 // As a result two AliTrackPointArray's obects are filled.
145 // The first one contains the space points with
cc345ce3 146 // volume id's from volids list. The second array of points represents
147 // the track extrapolations corresponding to the space points
98937d93 148 // in the first array. The two arrays can be used to find
cc345ce3 149 // the residuals in the volids and consequently construct a
98937d93 150 // chi2 function to be minimized during the alignment
151 // procedures. For the moment the track extrapolation is taken
cc345ce3 152 // at the space-point reference plane. The reference plane is
153 // found using the covariance matrix of the point
154 // (assuming sigma(x)=0 at the reference coordinate system.
dfce6628 155 Int_t debugLevel = AliLog::GetDebugLevel("","AliTrackFitterRieman");
156 Float_t debugRatio = 1./(1.+debugLevel);
98937d93 157
dfce6628 158 const Int_t kMinPoints =1;
98937d93 159 Int_t npoints = fPoints->GetNPoints();
dfce6628 160 if ( npoints<fMinNPoints) return kFALSE;
161 //
162 // fast count points
163 Int_t countFit = 0;
164 for (Int_t ifit=0; ifit<volIdsFit->GetSize(); ifit++){
165 Int_t volIdFit = volIdsFit->At(ifit);
166 for (Int_t ipoint = 0; ipoint < npoints; ipoint++)
167 if (volIdFit==fPoints->GetVolumeID()[ipoint]) countFit++;
168 }
169 if (countFit<fMinNPoints) return kFALSE;
170 //
171 Int_t countPoint = 0;
172 for (Int_t jpoint=0; jpoint<volIds->GetSize(); jpoint++){
173 Int_t volIdPoint = volIds->At(jpoint);
174 for (Int_t ipoint = 0; ipoint < npoints; ipoint++)
175 if (volIdPoint==fPoints->GetVolumeID()[ipoint]) countPoint++;
176 }
177 if (countPoint<kMinPoints) return kFALSE;
178 //
179 //
180
181 Reset();
182
183 if (fPoints && AliLog::GetDebugLevel("","AliTrackFitterRieman")>1&& gRandom->Rndm()<debugRatio){
8849da04 184 Int_t nVol = volIds->GetSize();
185 Int_t nVolFit = volIdsFit->GetSize();
186 Int_t volId = volIds->At(0);
187 (*fDebugStream)<<"PInput"<<
188 "NPoints="<<npoints<< // number of points
189 "VolId="<<volId<< // first vol ID
190 "NVol="<<nVol<< // number of volumes
191 "NvolFit="<<nVolFit<< // number of volumes to fit
192 "fPoints.="<<fPoints<< // input points
193 "\n";
194 }
98937d93 195
cc345ce3 196 Bool_t isAlphaCalc = kFALSE;
46ae650f 197 AliTrackPoint p,plocal;
cc345ce3 198// fPoints->GetPoint(p,0);
199// fAlpha = TMath::ATan2(p.GetY(),p.GetX());
98937d93 200
201 Int_t npVolId = 0;
46ae650f 202 fNUsed = 0;
98937d93 203 Int_t *pindex = new Int_t[npoints];
204 for (Int_t ipoint = 0; ipoint < npoints; ipoint++)
205 {
206 fPoints->GetPoint(p,ipoint);
207 UShort_t iVolId = p.GetVolumeID();
cc345ce3 208 if (FindVolId(volIds,iVolId)) {
98937d93 209 pindex[npVolId] = ipoint;
210 npVolId++;
211 }
cc345ce3 212 if (volIdsFit != 0x0) {
213 if (!FindVolId(volIdsFit,iVolId)) continue;
46ae650f 214 }
215 else {
216 if (iVolId < AliAlignObj::LayerToVolUID(layerRangeMin,0) ||
217 iVolId > AliAlignObj::LayerToVolUID(layerRangeMax,
c041444f 218 AliAlignObj::LayerSize(layerRangeMax))) continue;
46ae650f 219 }
cc345ce3 220 if (!isAlphaCalc) {
221 fAlpha = p.GetAngle();
222 isAlphaCalc = kTRUE;
223 }
46ae650f 224 plocal = p.Rotate(fAlpha);
186e6ced 225 if (TMath::Abs(plocal.GetX())>500 || TMath::Abs(plocal.GetX())<2 || plocal.GetCov()[3]<=0 ||plocal.GetCov()[5]<=0 ){
8849da04 226 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</n");
227 p.Dump();
228 plocal.Dump();
229 printf("Problematic point\n");
230 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</n");
186e6ced 231 }else{
232 AddPoint(plocal.GetX(),plocal.GetY(),plocal.GetZ(),
233 TMath::Sqrt(plocal.GetCov()[3]),TMath::Sqrt(plocal.GetCov()[5]));
8849da04 234 }
8849da04 235 // fNUsed++; AddPoint should be responsible
98937d93 236 }
237
8849da04 238 if (npVolId == 0 || fNUsed < fMinNPoints) {
98937d93 239 delete [] pindex;
240 return kFALSE;
241 }
242
243 Update();
cc345ce3 244
98937d93 245 if (!fConv) {
246 delete [] pindex;
247 return kFALSE;
248 }
249
250 if ((fParams[0] == 0) ||
251 ((-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1) <= 0)) {
252 delete [] pindex;
253 return kFALSE;
254 }
255
cc345ce3 256
257 if (fNUsed < fMinNPoints) {
258 delete [] pindex;
259 return kFALSE;
260 }
261
46ae650f 262 fPVolId = new AliTrackPointArray(npVolId);
263 fPTrack = new AliTrackPointArray(npVolId);
98937d93 264 AliTrackPoint p2;
265 for (Int_t ipoint = 0; ipoint < npVolId; ipoint++)
266 {
267 Int_t index = pindex[ipoint];
268 fPoints->GetPoint(p,index);
186e6ced 269 if (GetPCA(p,p2) && (
270 TMath::Abs(p.GetX()-p2.GetX())<fMaxDelta &&
271 TMath::Abs(p.GetY()-p2.GetY())<fMaxDelta &&
272 TMath::Abs(p.GetZ()-p2.GetZ())<fMaxDelta
273 )) {
cc345ce3 274 Float_t xyz[3],xyz2[3];
275 p.GetXYZ(xyz); p2.GetXYZ(xyz2);
186e6ced 276 // printf("residuals %f %d %d %f %f %f %f %f %f\n",fChi2,fNUsed,fConv,xyz[0],xyz[1],xyz[2],xyz2[0]-xyz[0],xyz2[1]-xyz[1],xyz2[2]-xyz[2]);
46ae650f 277 fPVolId->AddPoint(ipoint,&p);
278 fPTrack->AddPoint(ipoint,&p2);
8849da04 279 }else{
280 // what should be default bahavior -
281 delete [] pindex;
282 delete fPVolId;
283 delete fPTrack;
284 fPVolId =0;
285 fPTrack =0;
286 return kFALSE;
98937d93 287 }
288 }
8849da04 289
dfce6628 290 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")>0 && gRandom->Rndm()<debugRatio){
8849da04 291 //
292 // Debug Info
293 //
294 AliTrackPointArray *lPVolId = new AliTrackPointArray(npVolId);
295 AliTrackPointArray *lPTrack = new AliTrackPointArray(npVolId);
dfce6628 296 AliTrackPointArray *lPTrackE = new AliTrackPointArray(npVolId);
8849da04 297 AliRieman * residual = fRieman->MakeResiduals();
8849da04 298 for (Int_t ipoint = 0; ipoint < npVolId; ipoint++){
dfce6628 299 AliTrackPoint p0, p0local;
300 AliTrackPoint pFit, pFitlocal, pFitLocalE;
301 fPVolId->GetPoint(p0,ipoint);
302 Float_t lAngle = p0.GetAngle();
303 p0local= p0.MasterToLocal();
304 fPTrack->GetPoint(pFit,ipoint);
305 pFitlocal= pFit.Rotate(lAngle);
306 //
307 Float_t xyz[3], cov[3];
308 xyz[0] = pFitlocal.GetX();
309 xyz[1] = pFitlocal.GetY();
310 xyz[2] = pFitlocal.GetZ();
311 for (Int_t icov=0; icov<6; icov++) cov[icov]=0;
312 cov[3] = GetErrY2at(xyz[0]);
313 cov[5] = GetErrZ2at(xyz[0]);
314 pFitLocalE.SetXYZ(xyz,cov);
315 //
316 lPVolId->AddPoint(ipoint,&p0local);
317 lPTrack->AddPoint(ipoint,&pFitlocal);
318 lPTrackE->AddPoint(ipoint,&pFitLocalE);
8849da04 319 }
320 //
321 // debug info
322 //
323 Int_t nVol = volIds->GetSize();
324 Int_t nVolFit = volIdsFit->GetSize();
325 Int_t volId = volIds->At(0);
326 Int_t modId =0;
327 Int_t layer = AliAlignObj::VolUIDToLayer(volId,modId);
dfce6628 328 Int_t volIdFit = volIdsFit->At(0);
329 Int_t modIdFit =0;
330 Int_t layerFit = AliAlignObj::VolUIDToLayer(volIdFit,modIdFit);
8849da04 331
332 (*fDebugStream)<<"Fit"<<
333 "VolId="<<volId<< // volume ID
334 "Layer="<<layer<< // layer ID
335 "Module="<<modId<< // module ID
dfce6628 336 "LayerFit="<<layerFit<< // layer ID fit
337 "ModuleFit="<<modIdFit<< // module ID fit
8849da04 338 "NVol="<<nVol<< // number of volumes
339 "NvolFit="<<nVolFit<< // number of volumes to fit
340 "Points0.="<<fPVolId<< // original points
341 "Points1.="<<fPTrack<< // fitted points
342 "LPoints0.="<<lPVolId<< // original points - local frame
343 "LPoints1.="<<lPTrack<< // fitted points - local frame
dfce6628 344 "LPointsE.="<<lPTrackE<< // fitted points with ext error - local frame
8849da04 345 "Rieman.="<<this<< // original rieman fit
346 "Res.="<<residual<< // residuals of rieman fit
347 "\n";
348 delete lPVolId;
349 delete lPTrack;
350 delete residual;
351 }
98937d93 352
353 delete [] pindex;
98937d93 354 return kTRUE;
355}
356
8849da04 357
98937d93 358void AliTrackFitterRieman::AddPoint(Float_t x, Float_t y, Float_t z, Float_t sy, Float_t sz)
359{
360 //
8849da04 361 // add point to rieman fitter
98937d93 362 //
8849da04 363 fRieman->AddPoint(x,y,z,sy,sz);
364 fNUsed = fRieman->GetN();
98937d93 365}
366
8849da04 367
368
98937d93 369void AliTrackFitterRieman::Update(){
370 //
8849da04 371 //
98937d93 372 //
8849da04 373 fRieman->Update();
374 fConv = kFALSE;
375 if (fRieman->IsValid()){
376 for (Int_t ipar=0; ipar<6; ipar++){
377 fParams[ipar] = fRieman->GetParam()[ipar];
98937d93 378 }
8849da04 379 fChi2 = fRieman->GetChi2();
380 fNdf = fRieman->GetN()- 2;
381 fNUsed = fRieman->GetN();
382 fConv = kTRUE;
98937d93 383 }
dfce6628 384 //
385 //
386 //
387 TLinearFitter fitY(3,"pol2");
388 TLinearFitter fitZ(3,"pol2");
389 for (Int_t ip=0; ip<fRieman->GetN();ip++){
390 Double_t x = fRieman->GetX()[ip];
391 fitY.AddPoint(&x,fRieman->GetY()[ip]-fRieman->GetYat(x),1);
392 fitZ.AddPoint(&x,fRieman->GetZ()[ip]-fRieman->GetZat(x),1);
393 }
394 fitY.Eval();
395 fitZ.Eval();
396 for (Int_t iparam=0; iparam<3; iparam++){
397 fCorrY[iparam]=fitY.GetParameter(iparam);
398 fCorrZ[iparam]=fitZ.GetParameter(iparam);
399 }
400 fCorrY[3]=fitY.GetChisquare()/Float_t(fRieman->GetN()-3);
401 fCorrZ[3]=fitZ.GetChisquare()/Float_t(fRieman->GetN()-3);
98937d93 402}
403
dfce6628 404
405
6b6cba33 406//_____________________________________________________________________________
98937d93 407Bool_t AliTrackFitterRieman::GetPCA(const AliTrackPoint &p, AliTrackPoint &p2) const
408{
6b6cba33 409 //
98937d93 410 // Get the closest to a given spacepoint track trajectory point
411 // Look for details in the description of the Fit() method
6b6cba33 412 //
98937d93 413 if (!fConv) return kFALSE;
414
415 // First X and Y coordinates
416 Double_t sin = TMath::Sin(fAlpha);
417 Double_t cos = TMath::Cos(fAlpha);
418 // fParam[0] = 1/y0
419 // fParam[1] = -x0/y0
420 // fParam[2] = - (R^2 - x0^2 - y0^2)/y0
421 if (fParams[0] == 0) return kFALSE;
cc345ce3 422 // Track parameters in the global coordinate system
98937d93 423 Double_t x0 = -fParams[1]/fParams[0]*cos - 1./fParams[0]*sin;
424 Double_t y0 = 1./fParams[0]*cos - fParams[1]/fParams[0]*sin;
425 if ((-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1) <= 0) return kFALSE;
6b6cba33 426 Double_t r = TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1)/
98937d93 427 fParams[0];
428
cc345ce3 429 // Define space-point refence plane
430 Double_t alphap = p.GetAngle();
431 Double_t sinp = TMath::Sin(alphap);
432 Double_t cosp = TMath::Cos(alphap);
433 Double_t x = p.GetX()*cosp + p.GetY()*sinp;
434 Double_t y = p.GetY()*cosp - p.GetX()*sinp;
435 Double_t x0p= x0*cosp + y0*sinp;
436 Double_t y0p= y0*cosp - x0*sinp;
6b6cba33 437 if ((r*r - (x-x0p)*(x-x0p))<0) {
438 AliWarning(Form("Track extrapolation failed ! (Track radius = %f, track circle x = %f, space-point x = %f, reference plane angle = %f\n",r,x0p,x,alphap));
24d4520d 439 return kFALSE;
440 }
6b6cba33 441 Double_t temp = TMath::Sqrt(r*r - (x-x0p)*(x-x0p));
cc345ce3 442 Double_t y1 = y0p + temp;
443 Double_t y2 = y0p - temp;
444 Double_t yprime = y1;
445 if(TMath::Abs(y2-y) < TMath::Abs(y1-y)) yprime = y2;
446
447 // Back to the global coordinate system
448 Double_t xsecond = x*cosp - yprime*sinp;
449 Double_t ysecond = yprime*cosp + x*sinp;
450
451 // Now Z coordinate and track angles
452 Double_t x2 = xsecond*cos + ysecond*sin;
453 Double_t zsecond = GetZat(x2);
454 Double_t dydx = GetDYat(x2);
455 Double_t dzdx = GetDZat(x2);
456
457 // Fill the cov matrix of the track extrapolation point
458 Double_t cov[6] = {0,0,0,0,0,0};
459 Double_t sigmax = 100*100.;
460 cov[0] = sigmax; cov[1] = sigmax*dydx; cov[2] = sigmax*dzdx;
461 cov[3] = sigmax*dydx*dydx; cov[4] = sigmax*dydx*dzdx;
462 cov[5] = sigmax*dzdx*dzdx;
463
dfce6628 464 Double_t sigmay2 = GetErrY2at(x2);
465 Double_t sigmaz2 = GetErrZ2at(x2);
466 cov[3] += sigmay2;
467 cov[5] += sigmaz2;
468
469
cc345ce3 470 Float_t newcov[6];
471 newcov[0] = cov[0]*cos*cos-
472 2*cov[1]*sin*cos+
473 cov[3]*sin*sin;
474 newcov[1] = cov[1]*(cos*cos-sin*sin)-
475 (cov[3]-cov[0])*sin*cos;
476 newcov[2] = cov[2]*cos-
477 cov[4]*sin;
478 newcov[3] = cov[0]*sin*sin+
479 2*cov[1]*sin*cos+
480 cov[3]*cos*cos;
481 newcov[4] = cov[4]*cos+
482 cov[2]*sin;
483 newcov[5] = cov[5];
484
485 p2.SetXYZ(xsecond,ysecond,zsecond,newcov);
dfce6628 486 Int_t debugLevel = AliLog::GetDebugLevel("","AliTrackFitterRieman");
487 Float_t debugRatio = 1./(1.+debugLevel);
488 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")>0 && gRandom->Rndm()<debugRatio){
8849da04 489 AliTrackPoint lp0(p);
490 AliTrackPoint lp2(p2);
dfce6628 491 (*fDebugStream)<<"PCA"<<
8849da04 492 "P0.="<<&lp0<<
493 "P2.="<<&lp2<<
494 "\n";
495 }
98937d93 496 return kTRUE;
497}
dfce6628 498
499Double_t AliTrackFitterRieman::GetYat(Double_t x) const {
500 //
501 // get y position at given point
502 //
503 Double_t correction=0;
504 if (fBCorrection){ // systematic effect correction
505 correction = fCorrY[0]+fCorrY[1]*x +fCorrY[2]*x*x;
506 }
507 return fRieman->GetYat(x)+correction;
508}
509
510Double_t AliTrackFitterRieman::GetZat(Double_t x) const {
511 //
512 // get z position at given point
513 //
514 Double_t correction=0;
515 if (fBCorrection){ // systematic effect correction
516 correction = fCorrZ[0]+fCorrZ[1]*x +fCorrZ[2]*x*x;
517 }
518 return fRieman->GetZat(x)+correction;
519}
520
521Double_t AliTrackFitterRieman::GetErrY2at(Double_t x) const {
522 //
523 // get estimate of extrapolation error
524 //
525 Double_t error = fRieman->GetErrY(x);
526 Double_t correction=0;
527 if (fBCorrection){ // everestimate error due systematic effect
528 error *=fCorrY[3];
529 correction = fCorrY[0]+fCorrY[1]*x +fCorrY[2]*x*x;
530 correction *=correction;
531 }
532 return TMath::Sqrt(error+correction);
533}
534
535Double_t AliTrackFitterRieman::GetErrZ2at(Double_t x) const {
536 //
537 // get estimate of extrapolation error
538 //
539 Double_t error = fRieman->GetErrZ(x)*fCorrZ[3];
540 Double_t correction=0;
541 if (fBCorrection){
542 error *= fCorrZ[3];
543 correction = fCorrZ[0]+fCorrZ[1]*x +fCorrZ[2]*x*x;
544 correction*= correction;
545 }
546 return TMath::Sqrt(error+correction);
547}
548