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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
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.
28 // Internal usage of AliRieman class for minimization
30 //////////////////////////////////////////////////////////////////////////////
32 #include "TMatrixDSym.h"
35 #include "AliTrackFitterRieman.h"
37 #include "TTreeStream.h"
38 #include "AliRieman.h"
41 ClassImp(AliTrackFitterRieman)
44 AliTrackFitterRieman::AliTrackFitterRieman():
48 // default constructor
54 fDebugStream = new TTreeSRedirector("RiemanAlignDebug.root");
55 fRieman = new AliRieman(10000); // allocate rieman
59 AliTrackFitterRieman::AliTrackFitterRieman(AliTrackPointArray *array, Bool_t owner):
60 AliTrackFitter(array,owner)
69 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")) fDebugStream = new TTreeSRedirector("RiemanAlignDebug.root");
70 fRieman = new AliRieman(10000); //allocate rieman
73 AliTrackFitterRieman::AliTrackFitterRieman(const AliTrackFitterRieman &rieman):
74 AliTrackFitter(rieman)
79 fAlpha = rieman.fAlpha;
80 fNUsed = rieman.fNUsed;
82 fMaxDelta = rieman.fMaxDelta;
83 fRieman = new AliRieman(*(rieman.fRieman));
86 //_____________________________________________________________________________
87 AliTrackFitterRieman &AliTrackFitterRieman::operator =(const AliTrackFitterRieman& rieman)
90 // Assignment operator
92 if(this==&rieman) return *this;
93 ((AliTrackFitter *)this)->operator=(rieman);
95 fAlpha = rieman.fAlpha;
96 fNUsed = rieman.fNUsed;
98 fMaxDelta = rieman.fMaxDelta;
99 fRieman = new AliRieman(*(rieman.fRieman));
104 AliTrackFitterRieman::~AliTrackFitterRieman(){
112 void AliTrackFitterRieman::Reset()
114 // Reset the track parameters and
117 AliTrackFitter::Reset();
124 Bool_t AliTrackFitterRieman::Fit(const TArrayI *volIds,const TArrayI *volIdsFit,
125 AliAlignObj::ELayerID layerRangeMin,
126 AliAlignObj::ELayerID layerRangeMax)
128 // Fit the track points. The method takes as an input
129 // the set of id's (volids) of the volumes in which
130 // one wants to calculate the residuals.
131 // The following parameters are used to define the
132 // range of volumes to be used in the fitting
133 // As a result two AliTrackPointArray's obects are filled.
134 // The first one contains the space points with
135 // volume id's from volids list. The second array of points represents
136 // the track extrapolations corresponding to the space points
137 // in the first array. The two arrays can be used to find
138 // the residuals in the volids and consequently construct a
139 // chi2 function to be minimized during the alignment
140 // procedures. For the moment the track extrapolation is taken
141 // at the space-point reference plane. The reference plane is
142 // found using the covariance matrix of the point
143 // (assuming sigma(x)=0 at the reference coordinate system.
146 Int_t npoints = fPoints->GetNPoints();
147 if (fPoints && AliLog::GetDebugLevel("","AliTrackFitterRieman")>1){
148 Int_t nVol = volIds->GetSize();
149 Int_t nVolFit = volIdsFit->GetSize();
150 Int_t volId = volIds->At(0);
151 (*fDebugStream)<<"PInput"<<
152 "NPoints="<<npoints<< // number of points
153 "VolId="<<volId<< // first vol ID
154 "NVol="<<nVol<< // number of volumes
155 "NvolFit="<<nVolFit<< // number of volumes to fit
156 "fPoints.="<<fPoints<< // input points
159 if (npoints < 3) return kFALSE;
161 Bool_t isAlphaCalc = kFALSE;
162 AliTrackPoint p,plocal;
163 // fPoints->GetPoint(p,0);
164 // fAlpha = TMath::ATan2(p.GetY(),p.GetX());
168 Int_t *pindex = new Int_t[npoints];
169 for (Int_t ipoint = 0; ipoint < npoints; ipoint++)
171 fPoints->GetPoint(p,ipoint);
172 UShort_t iVolId = p.GetVolumeID();
173 if (FindVolId(volIds,iVolId)) {
174 pindex[npVolId] = ipoint;
177 if (volIdsFit != 0x0) {
178 if (!FindVolId(volIdsFit,iVolId)) continue;
181 if (iVolId < AliAlignObj::LayerToVolUID(layerRangeMin,0) ||
182 iVolId > AliAlignObj::LayerToVolUID(layerRangeMax,
183 AliAlignObj::LayerSize(layerRangeMax))) continue;
186 fAlpha = p.GetAngle();
189 plocal = p.Rotate(fAlpha);
190 if (TMath::Abs(plocal.GetX())>500 || TMath::Abs(plocal.GetX())<2 || plocal.GetCov()[3]<=0 ||plocal.GetCov()[5]<=0 ){
191 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</n");
194 printf("Problematic point\n");
195 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</n");
197 AddPoint(plocal.GetX(),plocal.GetY(),plocal.GetZ(),
198 TMath::Sqrt(plocal.GetCov()[3]),TMath::Sqrt(plocal.GetCov()[5]));
200 // fNUsed++; AddPoint should be responsible
203 if (npVolId == 0 || fNUsed < fMinNPoints) {
215 if ((fParams[0] == 0) ||
216 ((-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1) <= 0)) {
222 if (fNUsed < fMinNPoints) {
227 fPVolId = new AliTrackPointArray(npVolId);
228 fPTrack = new AliTrackPointArray(npVolId);
230 for (Int_t ipoint = 0; ipoint < npVolId; ipoint++)
232 Int_t index = pindex[ipoint];
233 fPoints->GetPoint(p,index);
234 if (GetPCA(p,p2) && (
235 TMath::Abs(p.GetX()-p2.GetX())<fMaxDelta &&
236 TMath::Abs(p.GetY()-p2.GetY())<fMaxDelta &&
237 TMath::Abs(p.GetZ()-p2.GetZ())<fMaxDelta
239 Float_t xyz[3],xyz2[3];
240 p.GetXYZ(xyz); p2.GetXYZ(xyz2);
241 // 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]);
242 fPVolId->AddPoint(ipoint,&p);
243 fPTrack->AddPoint(ipoint,&p2);
245 // what should be default bahavior -
255 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")>0){
259 AliTrackPointArray *lPVolId = new AliTrackPointArray(npVolId);
260 AliTrackPointArray *lPTrack = new AliTrackPointArray(npVolId);
261 AliRieman * residual = fRieman->MakeResiduals();
262 AliTrackPoint p2local;
263 for (Int_t ipoint = 0; ipoint < npVolId; ipoint++){
264 Int_t index = pindex[ipoint];
265 fPoints->GetPoint(p,index);
267 plocal = p.Rotate(fAlpha);
268 // plocal.Rotate(fAlpha);
269 Float_t xyz[3],xyz2[3];
273 xyz2[1] = GetYat(xyz[0]);
274 xyz2[2] = GetZat(xyz[0]);
275 p2local.SetXYZ(xyz2);
276 lPVolId->AddPoint(ipoint,&plocal);
277 lPTrack->AddPoint(ipoint,&p2local);
283 Int_t nVol = volIds->GetSize();
284 Int_t nVolFit = volIdsFit->GetSize();
285 Int_t volId = volIds->At(0);
287 Int_t layer = AliAlignObj::VolUIDToLayer(volId,modId);
289 (*fDebugStream)<<"Fit"<<
290 "VolId="<<volId<< // volume ID
291 "Layer="<<layer<< // layer ID
292 "Module="<<modId<< // module ID
293 "NVol="<<nVol<< // number of volumes
294 "NvolFit="<<nVolFit<< // number of volumes to fit
295 "Points0.="<<fPVolId<< // original points
296 "Points1.="<<fPTrack<< // fitted points
297 "LPoints0.="<<lPVolId<< // original points - local frame
298 "LPoints1.="<<lPTrack<< // fitted points - local frame
299 "Rieman.="<<this<< // original rieman fit
300 "Res.="<<residual<< // residuals of rieman fit
312 void AliTrackFitterRieman::AddPoint(Float_t x, Float_t y, Float_t z, Float_t sy, Float_t sz)
315 // add point to rieman fitter
317 fRieman->AddPoint(x,y,z,sy,sz);
318 fNUsed = fRieman->GetN();
323 void AliTrackFitterRieman::Update(){
329 if (fRieman->IsValid()){
330 for (Int_t ipar=0; ipar<6; ipar++){
331 fParams[ipar] = fRieman->GetParam()[ipar];
333 fChi2 = fRieman->GetChi2();
334 fNdf = fRieman->GetN()- 2;
335 fNUsed = fRieman->GetN();
340 //_____________________________________________________________________________
341 Bool_t AliTrackFitterRieman::GetPCA(const AliTrackPoint &p, AliTrackPoint &p2) const
344 // Get the closest to a given spacepoint track trajectory point
345 // Look for details in the description of the Fit() method
347 if (!fConv) return kFALSE;
349 // First X and Y coordinates
350 Double_t sin = TMath::Sin(fAlpha);
351 Double_t cos = TMath::Cos(fAlpha);
353 // fParam[1] = -x0/y0
354 // fParam[2] = - (R^2 - x0^2 - y0^2)/y0
355 if (fParams[0] == 0) return kFALSE;
356 // Track parameters in the global coordinate system
357 Double_t x0 = -fParams[1]/fParams[0]*cos - 1./fParams[0]*sin;
358 Double_t y0 = 1./fParams[0]*cos - fParams[1]/fParams[0]*sin;
359 if ((-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1) <= 0) return kFALSE;
360 Double_t r = TMath::Sqrt(-fParams[2]*fParams[0]+fParams[1]*fParams[1]+1)/
363 // Define space-point refence plane
364 Double_t alphap = p.GetAngle();
365 Double_t sinp = TMath::Sin(alphap);
366 Double_t cosp = TMath::Cos(alphap);
367 Double_t x = p.GetX()*cosp + p.GetY()*sinp;
368 Double_t y = p.GetY()*cosp - p.GetX()*sinp;
369 Double_t x0p= x0*cosp + y0*sinp;
370 Double_t y0p= y0*cosp - x0*sinp;
371 if ((r*r - (x-x0p)*(x-x0p))<0) {
372 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));
375 Double_t temp = TMath::Sqrt(r*r - (x-x0p)*(x-x0p));
376 Double_t y1 = y0p + temp;
377 Double_t y2 = y0p - temp;
378 Double_t yprime = y1;
379 if(TMath::Abs(y2-y) < TMath::Abs(y1-y)) yprime = y2;
381 // Back to the global coordinate system
382 Double_t xsecond = x*cosp - yprime*sinp;
383 Double_t ysecond = yprime*cosp + x*sinp;
385 // Now Z coordinate and track angles
386 Double_t x2 = xsecond*cos + ysecond*sin;
387 Double_t zsecond = GetZat(x2);
388 Double_t dydx = GetDYat(x2);
389 Double_t dzdx = GetDZat(x2);
391 // Fill the cov matrix of the track extrapolation point
392 Double_t cov[6] = {0,0,0,0,0,0};
393 Double_t sigmax = 100*100.;
394 cov[0] = sigmax; cov[1] = sigmax*dydx; cov[2] = sigmax*dzdx;
395 cov[3] = sigmax*dydx*dydx; cov[4] = sigmax*dydx*dzdx;
396 cov[5] = sigmax*dzdx*dzdx;
399 newcov[0] = cov[0]*cos*cos-
402 newcov[1] = cov[1]*(cos*cos-sin*sin)-
403 (cov[3]-cov[0])*sin*cos;
404 newcov[2] = cov[2]*cos-
406 newcov[3] = cov[0]*sin*sin+
409 newcov[4] = cov[4]*cos+
413 p2.SetXYZ(xsecond,ysecond,zsecond,newcov);
414 if (AliLog::GetDebugLevel("","AliTrackFitterRieman")>1){
415 AliTrackPoint lp0(p);
416 AliTrackPoint lp2(p2);
417 if (0)(*fDebugStream)<<"PCA"<<