HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hrungekutta.cc
Go to the documentation of this file.
1 //*-- Author : A.Ivashkin <ivashkin@inr.ru>
2 //*-- Modified: A.Sadovsky <sadovski@fz-rossendorf.de> (04.11.2004 Hydra implementation)
3 //*-- Last modified : 14/08/2005 by Ilse Koenig
4 
5 using namespace std;
6 #include <iostream>
7 #include <fstream>
8 #include "hrungekutta.h"
9 #include "hmdcsizescells.h"
10 #include <math.h>
11 #include "TMatrixD.h"
12 #include "TDecompLU.h"
14 
16 
17  // constructor
18  clear();
19 
20  // Eventually these parameters should be stored in a parameter container!
21  initialStepSize=50.;
22  stepSizeDec=0.75;
23  stepSizeInc=1.25;
24  maxStepSize=200.;
25  minStepSize=10.;
26  minPrecision=2.e-04;
27  maxPrecision=2.e-05;
28  maxNumSteps=1000;
29  maxDist=2.5;
30  dpar[0]=0.01; dpar[1]=0.001; dpar[2]=0.001; dpar[3]=0.01; dpar[4]=0.01;
31  resolution[0]=0.140*2.00; resolution[1]=0.140*1.00; // MDC1 intrinsic resolution
32  resolution[2]=0.140*2.00; resolution[3]=0.140*1.00; // MDC2
33  resolution[4]=0.140*2.00; resolution[5]=0.140*1.00; // MDC3
34  resolution[6]=0.140*2.00; resolution[7]=0.140*1.00; // MDC4
35  for(Int_t i=0;i<8;i++) {sig[i]=resolution[i];}
36  mTol=DBL_EPSILON;
37 }
38 
39 
41  // clears magnetic field definition and vertex position and direction
42  fieldMap=0;
43  fieldScalFact=0.;
44  for(Int_t m=0; m<4; m++) {
45  for(Int_t s=0; s<6; s++) {
46  mdcInstalled[m][s]=kFALSE;
47  mdcPos[m][s][0]=0.;
48  mdcPos[m][s][1]=0.;
49  mdcPos[m][s][2]=0.;
50  normVecMdc[m][s][0]=0.;
51  normVecMdc[m][s][1]=0.;
52  normVecMdc[m][s][2]=0.;
53  }
54  }
55 }
56 
57 
58 void HRungeKutta::setField(HMdcTrackGField* pField, Float_t fpol) {
59  // sets the field map and the scaling factor
60  fieldMap=pField;
61  fieldScalFact=fpol;
62 }
63 
64 
65 void HRungeKutta::setMdcPosition(Int_t s, Int_t m, HGeomTransform& gtrMod2Sec) {
66  // sets the MDC module position in the sector coordinate system
67  // calculates the normal vector on the planes
68  mdcInstalled[m][s]=kTRUE;
69  HGeomVector aTransl=gtrMod2Sec.getTransVector();
70  mdcPos[m][s][0] = aTransl.getX();
71  mdcPos[m][s][1] = aTransl.getY();
72  mdcPos[m][s][2] = aTransl.getZ();
73  HGeomVector r0_mod(0.0, 0.0, 0.0);
74  HGeomVector rz_mod(0.0, 0.0, 1.0);
75  HGeomVector norm= gtrMod2Sec.transFrom(rz_mod) - gtrMod2Sec.transFrom(r0_mod);
76  norm/=norm.length(); // to be shure it is normalized after transformation
77  normVecMdc[m][s][0]=norm.getX();
78  normVecMdc[m][s][1]=norm.getY();
79  normVecMdc[m][s][2]=norm.getZ();
80  if (m==0 || m==1) {
81  dzfacMdc[m][s]=tan(acos(norm.getZ()));
82  HGeomVector v(0.0, 0.0, -500.0);
83  if (m==1 && mdcInstalled[0][s]==kFALSE) v.setZ(-650.);
84  HGeomVector vs=gtrMod2Sec.transFrom(v);
85  pointForVertexRec[s][0]=vs.getX();
86  pointForVertexRec[s][1]=vs.getY();
87  pointForVertexRec[s][2]=vs.getZ();
88  }
89 }
90 
91 
92 Bool_t HRungeKutta::fit4Hits(Double_t* u1pos, Double_t* u1dir,
93  Double_t* u2pos, Double_t* u2dir,
94  Float_t* sigMult, Int_t sec, Double_t pGuess) {
95  // Input: position and direction of the two segments u1 and u2,
96  // array with multiplication factors for errors
97  // sector number, initial guess for momentum
98  // From the segments the hit positions are calculated.
99  // Calls fitMdc for Runge-Kutta track propagation and fitting
100  nMaxMod=4;
101  ndf = 3; //{x,y}*4mdc=8 - {p,x,y,dx,dy}=5 == 3
102  sector=sec;
103  p0Guess = pGuess;
104  findMdcIntersectionPoint(u1pos,u1dir,0,&hit[0][0]); // hit = hit position in modules
105  findMdcIntersectionPoint(u1pos,u1dir,1,&hit[1][0]);
106  findMdcIntersectionPoint(u2pos,u2dir,2,&hit[2][0]);
107  findMdcIntersectionPoint(u2pos,u2dir,3,&hit[3][0]);
108  for(Int_t i=0;i<4;i++) {
109  mdcModules[i]=i;
110  mdcLookup[i]=i;
111  sig[2*i]=sigMult[2*i]*resolution[2*i];
112  sig[2*i+1]=sigMult[2*i+1]*resolution[2*i+1];
113  }
114  return fitMdc();
115 }
116 
117 
118 Bool_t HRungeKutta::fit3Hits(Double_t* u1pos, Double_t* u1dir,
119  Double_t* u2pos, Double_t* u2dir,
120  Float_t* sigMult, Int_t sec, Double_t pGuess) {
121  // Input: position and direction of the two segments u1 and u2
122  // array with multiplication factors for errors
123  // sector number, initial guess for momentum
124  // From the segments the hit positions are calculated.
125  // If the multiplication factors for errors of a hit -1, the hit is discarded.
126  // Calls fitMdc for Runge-Kutta track propagation and fitting
127  nMaxMod=3;
128  ndf = 1; //{x,y}*3mdc=6 - {p,x,y,dx,dy}=5 == 1
129  sector=sec;
130  p0Guess = pGuess;
131  Int_t m=0;
132  // hit = hit position in modules
133  for (Int_t i=0;i<2;i++) {
134  if (sigMult[2*i]>0) {
135  findMdcIntersectionPoint(u1pos,u1dir,i,&hit[m][0]);
136  mdcModules[m]=i;
137  mdcLookup[i]=m;
138  sig[2*m]=sigMult[2*i]*resolution[2*i];
139  sig[2*m+1]=sigMult[2*i+1]*resolution[2*i+1];
140  m++;
141  } else mdcLookup[i]=-1;
142  }
143  for (Int_t i=2;i<4;i++) {
144  if (sigMult[2*i]>0) {
145  findMdcIntersectionPoint(u2pos,u2dir,i,&hit[m][0]);
146  mdcModules[m]=i;
147  mdcLookup[i]=m;
148  sig[2*m]=sigMult[2*i]*resolution[2*i];
149  sig[2*m+1]=sigMult[2*i+1]*resolution[2*i+1];
150  m++;
151  } else mdcLookup[i]=-1;
152  }
153  mdcModules[3]=-1;
154  return fitMdc();
155 }
156 
157 
159  initMom(); // sets pfit
160  if (fabs(pfit)<10.) return kFALSE;
161 
162  Bool_t rc=kTRUE;
163  Float_t chi2old=0.F;
164  for(Int_t i=0;i<3;i++) fit[0][i]=hit[0][i]; // fit = fitted position in first module
165  Float_t dist=distance(&hit[0][0],&hit[1][0]);
166  if (dist==0.) { return kFALSE; }
167  Float_t uh=(hit[1][0]-hit[0][0])/dist; // cos(phi)
168  Float_t uv=(hit[1][1]-hit[0][1])/dist; // cos(theta)
169  for(Int_t iter=0;iter<11;iter++) {
170  polbending=fieldScalFact*pfit;
171  chi2=0.;
172  parSetNew0(uh,uv,iter);
173  if (jstep>=maxNumSteps) { return kFALSE; }
174  for(Int_t m=0;m<nMaxMod;m++) {
175  for(Int_t i=0;i<2;i++) {
176  Float_t chi=(hit[m][i]-fit[m][i])/sig[(m*2)+i];
177  chi2+=chi*chi;
178  }
179  }
180  if (finite(pfit)==0||finite(chi2)==0) {
181  Warning("HRungeKuttta::fitMdc()","NaN or Inf value received for pFit or chi2...skipped!");
182  return kFALSE;
183  }
184  if (chi2==0.) chi2=0.001;
185  if ((TMath::Abs(chi2-chi2old)/chi2)<0.005||iter==10||(iter>5&&chi2old>1.e+06&&chi2>chi2old)) break;
186 
187  chi2old=chi2;
188  parSetNewVar(uh,uv);
189  if (jstep>=maxNumSteps) { return kFALSE; }
190 
191  derive(&fitdp[0][0],0);
192  derive(&fitdh[0][0],1);
193  derive(&fitdv[0][0],2);
194  derive(&fit1h[0][0],3);
195  derive(&fit1v[0][0],4);
196 
197  for(Int_t i=0;i<nMaxMod;i++) {
198  for(Int_t k=0;k<2;k++) {
199  ydata[i*2+k]=fit[i][k]-hit[i][k];
200  }
201  }
202 
203  if (!(rc=linSys())) break;
204  Double_t dpp=fitpar[0]/pfit;
205  if ( dpp>=0) {
206  pfit+=fitpar[0]*(1+dpp);
207  } else {
208  pfit+=fitpar[0]/(1-dpp);
209  }
210  uh+=fitpar[1];
211  uv+=fitpar[2];
212  fit[0][0]+=fitpar[3];
213  fit[0][1]+=fitpar[4];
214  fit[0][2]-=fitpar[4]*dzfacMdc[(mdcModules[0])][sector];
215  if (pfit==0.) pfit=10.;
216  }
217  return rc;
218 }
219 
220 
221 void HRungeKutta::findMdcIntersectionPoint(Double_t* upos,Double_t* udir,Int_t mdcN,Double_t* xyz) {
222  // calculates the hit points in the MDC module (index mdcN 0..3)
223  // input: posline == pos from track piece
224  // input: dirline == pos from segment
225  // mdcN == module number 0..3
226  // output: xyz == hit position in module
227  Double_t* normplane=&normVecMdc[mdcN][sector][0];
228  Double_t* pplane=&mdcPos[mdcN][sector][0];
229  findIntersectionPoint(upos,udir,pplane,normplane,xyz);
230 }
231 
232 
234  // Here we set initial approximation momentum value
235  if (p0Guess!=999999999.) {
236  // User supplied momentum guess, so we use it as 0-approximation
237  pfit=p0Guess;
238  } else {
239  // User did not supply a momentum guess. We start from simple-minded kickplane,
240  // which needs the tracklet directions on input.
241  Double_t dir1[3],dir2[3];
242  for(Int_t i=0;i<3;i++) {
243  dir1[i]=hit[1][i]-hit[0][i];
244  dir2[i]=hit[3][i]-hit[2][i];
245  }
246  Float_t temp=sqrt((dir1[1]*dir1[1]+dir1[2]*dir1[2])*(dir2[1]*dir2[1]+dir2[2]*dir2[2]));
247  if (temp==0.) temp=1.;
248  Float_t cosxi=(dir1[1]*dir2[1]+dir1[2]*dir2[2])/temp;
249  if (cosxi> 1.0) cosxi=1;
250  if (cosxi<-1.0) cosxi=-1;
251  Float_t xi=acos(cosxi);
252  Float_t vprod=(dir1[1]*dir2[2]-dir1[2]*dir2[1]);
253  temp=sin(xi/2.);
254  if (temp==0.) temp=0.001;
255  Float_t temp1=TMath::Abs(vprod);
256  if (temp1==0.) temp1=0.001;
257  pfit=75./(2*temp)*vprod/temp1;
258  }
259 }
260 
261 
262 Float_t HRungeKutta::distance(Double_t* p1,Double_t* p2) {
263  // calculates the distance between two points
264  Float_t dist=sqrt((p1[0]-p2[0])*(p1[0]-p2[0])+
265  (p1[1]-p2[1])*(p1[1]-p2[1])+
266  (p1[2]-p2[2])*(p1[2]-p2[2]));
267  return dist;
268 }
269 
270 
271 void HRungeKutta::parSetNew0(Float_t uh,Float_t uv,Int_t iter) {
272  // RK propagation with initial or last fit parameters
273  // uv - vertical direction in MDC1
274  // uh - horizontal direction
275  Double_t upos[3], udir[3];
276  for(Int_t i=0;i<3;i++) {
277  upos[i]=fit[0][i]; // position of track on MDC1
278  }
279  cosines(uh,uv,udir);
280  if (iter>0) {
281  // start with point on plane
282  findMdcIntersectionPoint(upos,udir,mdcModules[0],&fit[0][0]);
283  for(Int_t i=0;i<3;i++) { upos[i]=fit[0][i]; }
284  }
285  for(Int_t i=0;i<3;i++) {
286  dirAtFirstMDC[i]=udir[i]; // direction of track on first MDC
287  }
288  trackLength=0.;
289  gentrkNew(pfit,&upos[0],&udir[0],&fit[0][0],1);
290 }
291 
292 
293 void HRungeKutta::parSetNewVar(Float_t uh,Float_t uv) {
294  // calculates the derivatives (RK propagation with parameter variations)
295  // uv - vertical direction
296  // uh - horizontal direction in MDC1
297  Double_t upos[3], udir[3];
298  upos[0]=fit[0][0];
299  upos[1]=fit[0][1];
300  upos[2]=fit[0][2];
301  cosines(uh,uv,udir);
302  gentrkNew(pfit+dpar[0],&upos[0],&udir[0],&fitdp[0][0],2); // momentum additive
303 
304  upos[0]=fit[0][0];
305  upos[1]=fit[0][1];
306  upos[2]=fit[0][2];
307  cosines(uh+dpar[1],uv,udir); // x direction additive
308  gentrkNew(pfit,&upos[0],&udir[0],&fitdh[0][0],3);
309 
310  upos[0]=fit[0][0];
311  upos[1]=fit[0][1];
312  upos[2]=fit[0][2];
313  cosines(uh,uv+dpar[2],udir); // y direction additive
314  gentrkNew(pfit,&upos[0],&udir[0],&fitdv[0][0],4);
315 
316  upos[0]=fit[0][0]+dpar[3]; // x position additive
317  upos[1]=fit[0][1];
318  upos[2]=fit[0][2];
319  cosines(uh,uv,udir);
320  gentrkNew(pfit,&upos[0],&udir[0],&fit1h[0][0],5);
321 
322  upos[0]=fit[0][0];
323  upos[1]=fit[0][1]+dpar[4]; // y position additive
324  upos[2]=fit[0][2]-dpar[4]*dzfacMdc[(mdcModules[0])][sector]; // change in the first MDC plane
325  cosines(uh,uv,udir);
326  gentrkNew(pfit,&upos[0],&udir[0],&fit1v[0][0],6);
327 }
328 
329 
330 void HRungeKutta::cosines(Float_t uh, Float_t uv, Double_t* dir) {
331  // calculates the direction
332  Float_t prod=sqrt(uh*uh+uv*uv);
333  if (prod==0.) prod=0.0001;
334  if (prod<1.) {
335  dir[0]=uh;
336  dir[1]=uv;
337  dir[2]=sqrt(1.-prod*prod);
338  } else {
339  dir[0]=uh/prod;
340  dir[1]=uv/prod;
341  dir[2]=0.;
342  }
343 }
344 
345 
346 void HRungeKutta::derive(Double_t* hitpar, Int_t kind) {
347  // calculates the derivative (hit-fit)/variation
348  Double_t dp=dpar[kind];
349  for(Int_t i=0;i<nMaxMod;i++) {
350  Double_t* h=&hitpar[i*3];
351  for(Int_t k=0;k<2;k++) {
352  dydpar[kind][i*2+k]=(h[k]-fit[i][k])/dp;
353  }
354  }
355 }
356 
357 
359  // solves the system of linear equations and sets the new fitting parameters
360  Double_t data[5][5], elements[5];
361  Int_t kMax=nMaxMod*2;
362  for(Int_t i=0;i<5;i++) {
363  for(Int_t j=0;j<5;j++) {
364  data[j][i]=0.;
365  for(Int_t k=0;k<kMax;k++) {
366  data[j][i]+=dydpar[j][k]*dydpar[i][k]/(sig[k]*sig[k]);
367  }
368  }
369  }
370  for(Int_t i=0;i<5;i++) {
371  elements[i]=0.;
372  for(Int_t k=0;k<kMax;k++) {
373  elements[i]-= ydata[k]*dydpar[i][k]/(sig[k]*sig[k]);
374  }
375  }
376 
377 
378  //-------------------------------------------
379  // test if matrix is singular
380  TMatrixD test(5,5,(Double_t*)data,NULL);
381  Double_t sign;
382  Int_t nrZeros;
383  if(!decompose(test,sign,mTol,nrZeros)||nrZeros>0){return kFALSE;}
384  //-------------------------------------------
385 
386  TMatrixD m(5,5,(Double_t*)data,NULL);
387 
388  TMatrixD b(5,1,(Double_t*)elements,NULL);
389  TMatrixD m1(5,1);
390  m.Invert(0);
391  m1.Mult(m,b);
392 
393  for(Int_t i=0;i<5;i++) {
394  fitpar[i]=m1(i,0);
395  }
396 
397  return kTRUE;
398 }
399 
400 
401 void HRungeKutta::gentrkNew(Float_t p, Double_t* upos, Double_t* udir, Double_t* hitxyz, Int_t kind ) {
402  // propages the track through the MDC system
403  // p == momentum
404  // upos == initial position
405  // udir == initial direction
406  // hitxyz == hits in chambers
407  // kind == type of variation
408  Double_t* pHit=&hitxyz[0];
409  for(Int_t i=0;i<3;i++) pHit[i]=upos[i];
410  jstep=0;
411  Double_t d=0.;
412  Float_t step=initialStepSize;
413  Float_t nextStep=step;
414  Float_t stepFac=1.;
415  for(Int_t nMod=1;nMod<nMaxMod;nMod++) {
416  pHit=&hitxyz[nMod*3];
417  do {
418  stepFac=rkgtrk(step,p,upos,udir,kind);
419  findMdcIntersectionPoint(upos,udir,mdcModules[nMod],pHit);
420  d=distance(upos,pHit);
421  if (step<nextStep) { // last step was rest step to chamber
422  if (stepFac<1.) nextStep=step*stepFac;
423  } else nextStep*=stepFac;
424  if (d>nextStep||d<maxDist) step=nextStep;
425  else step=d;
426  } while (d>=maxDist&&((polbending>=0&&upos[2]<pHit[2])||(polbending<0&&upos[1]<pHit[1]))&&jstep<maxNumSteps);
427  }
428  if (kind==1) {
429  // we store the track position after the last RK step for subsequent propagation
430  // to Meta (this step ends near the chamber, while the position on the chamber is
431  // stored in fit[3])
432  for(Int_t i=0;i<3;i++) {
433  posNearLastMDC[i] = upos[i];
434  dirAtLastMDC[i] = udir[i]; // track direction
435  }
436  stepSizeAtLastMDC=nextStep;
437  }
438 }
439 
440 
441 Float_t HRungeKutta::rkgtrk(Float_t totStep, Float_t p, Double_t* upos, Double_t* udir, Int_t kind) {
442  // one step of track tracing from the position upos in the direction of udir
443  Float_t k1[3],k2[3],k3[3],k4[3],hstep,qstep;
444  Double_t u1pos[3], u1dir[3], u2pos[3], u2dir[3], ucm[3], b[3];
445  Double_t est=0.;
446  Float_t step=totStep;
447  Float_t stepFac=1.;
448  for(Int_t i=0;i<3;i++) ucm[i]=upos[i]/10.;
449  fieldMap->calcField(ucm,b,fieldScalFact);
450  rkeqfw(b,p,udir,k1);
451 
452  do {
453  jstep++;
454  hstep=step*0.5;
455  qstep=step*step*0.125;
456 
457  for(Int_t i=0;i<3;i++) {
458  u1pos[i]=upos[i]+hstep*udir[i]+qstep*k1[i];
459  u1dir[i]=udir[i]+hstep*k1[i];
460  }
461  for(Int_t i=0;i<3;i++) ucm[i]=u1pos[i]/10.;
462  fieldMap->calcField(ucm,b,fieldScalFact);
463  rkeqfw(b,p,u1dir,k2);
464 
465  for(Int_t i=0;i<3;i++) {
466  u1dir[i] = udir[i] + hstep*k2[i];
467  }
468  rkeqfw(b,p,u1dir,k3);
469 
470  for(Int_t i=0;i<3;i++) {
471  u2pos[i]=upos[i]+step*udir[i]+2.*hstep*hstep*k3[i];
472  u2dir[i]=udir[i]+step*k3[i];
473  }
474  for(Int_t i=0;i<3;i++) ucm[i]=u2pos[i]/10.;
475  fieldMap->calcField(ucm,b,fieldScalFact);
476  rkeqfw(b,p,u2dir,k4);
477 
478  est=0.;
479  for(Int_t i=0;i<3;i++) {
480  est+=fabs(k1[i]+k4[i]-k2[i]-k3[i])*hstep;
481  }
482  if (est<minPrecision||step<=minStepSize) {
483  break;
484  } else {
485  stepFac*=stepSizeDec;
486  step*=stepSizeDec;
487  }
488  } while (jstep<maxNumSteps);
489  for(Int_t i=0;i<3;i++) {
490  upos[i]=upos[i]+step*udir[i]+step*step*(k1[i]+k2[i]+k3[i])/6.;
491  udir[i]=udir[i]+step*(k1[i]+2.*k2[i]+2.*k3[i]+k4[i])/6.;
492  }
493  if (kind==1) {
494  trackLength+=step; // calculate track length
495  }
496  if (est<maxPrecision&&step<maxStepSize) {
497  stepFac*=stepSizeInc;
498  }
499  return stepFac;
500 }
501 
502 
503 void HRungeKutta::rkeqfw(Double_t b[3], Float_t p, Double_t* udir, Float_t* duds) {
504  // calculates 2nd derivative
505  Double_t con=0.2997925;
506  duds[0]=con*(udir[1]*b[2]-udir[2]*b[1])/p;
507  duds[1]=con*(udir[2]*b[0]-udir[0]*b[2])/p;
508  duds[2]=con*(udir[0]*b[1]-udir[1]*b[0])/p;
509 }
510 
511 
513  // propogates the track backwards from first MDC till Z=zVertex plane
514  // should be called only after RK-minimisation is done
515  Float_t step=initialStepSize;
516  Float_t stepFac=1.;
517  jstep=0;
518  Double_t dist=0.;
519  Double_t* normplane=&normVecMdc[(mdcModules[0])][sector][0];
520  Double_t* pplane=&pointForVertexRec[sector][0];
521  Double_t upos[3], udir[3], xyz[3];
522  for(Int_t i=0;i<3;i++) {
523  upos[i]=fit[0][i]; // track position at first MDC
524  udir[i]=-dirAtFirstMDC[i]; // direction (reversed to go back from first MDC to target)
525  }
526  do {
527  findIntersectionPoint(upos,udir,pplane,normplane,&xyz[0]);
528  dist=distance(upos,xyz);
529  if (dist<maxDist||upos[2]<=xyz[2]) {
530  break;
531  }
532  if (dist<step) { step=dist; }
533  stepFac=rkgtrk(step,-pfit,upos,udir,1); // with reversed momentum for correct track curvature
534  step*=stepFac;
535  } while (jstep<maxNumSteps);
536  HMdcSizesCells::calcMdcSeg(upos[0],upos[1],upos[2],
537  upos[0]-udir[0],upos[1]-udir[1],upos[2]-udir[2],
538  zSeg1,rSeg1,thetaSeg1,phiSeg1);
539  HMdcSizesCellsSec& fSCSec=(*pMSizesCells)[sector];
540  const HGeomVector& target=fSCSec.getTargetMiddlePoint();
541  xyz[0]=target.getX();
542  xyz[1]=target.getY();
543  xyz[2]=target.getZ();
544  dist=distance(xyz,upos);
545  trackLength+=dist;
546  trackLengthAtLastMDC=trackLength;
547 }
548 
549 
551  HGeomVector* pathCorrPos,HGeomVector* pathCorrNorm) {
552  // propagates the track from the last fitted MDC position till track intersection
553  // with META plane (is defined by META-hit and normal vector to rod's plane
554  // should be called only after RK-minimisation is done
555  trackLength=trackLengthAtLastMDC;
556  Double_t pointOnMETA[3], normVectorOfMETA[3];
557  pointOnMETA[0]=metaHit.getX();
558  pointOnMETA[1]=metaHit.getY();
559  pointOnMETA[2]=metaHit.getZ();
560  normVectorOfMETA[0] = metaNormVec.getX();
561  normVectorOfMETA[1] = metaNormVec.getY();
562  normVectorOfMETA[2] = metaNormVec.getZ();
563 
564  Float_t step = stepSizeAtLastMDC;
565  Float_t stepFac=1.;
566  jstep = 0;
567  Double_t upos[3], udir[3];
568  for(Int_t i=0;i<3;i++) {
569  upos[i]=posNearLastMDC[i]; // tracking position near last MDC
570  udir[i]=dirAtLastMDC[i]; // and direction
571  }
572  Double_t dist=0.;
573  Bool_t rc=kTRUE;
574  do {
575  rc=findIntersectionPoint(upos,udir,pointOnMETA,normVectorOfMETA,&trackPosOnMETA[0]);
576  if (!rc) break;
577  dist=distance(upos,trackPosOnMETA);
578  if ((polbending>=0&&upos[2]>trackPosOnMETA[2])||(polbending<0&&upos[1]>trackPosOnMETA[1])) {
579  trackLength-=dist;
580  break;
581  } else if (dist<maxDist) {
582  trackLength+=dist;
583  break;
584  } else if (upos[1]>=2475.||upos[1]<=0.) {
585  trackLength=0.;
586  break;
587  }
588  if (dist<step) { step=dist; }
589  stepFac=rkgtrk(step,pfit,upos,udir,1); // we use pfit as value for momentum to propagate
590  step*=stepFac;
591  } while (jstep<maxNumSteps);
592  if (!rc&&jstep>=maxNumSteps) {
593  trackLength=0.;
594  }
595  HMdcSizesCells::calcMdcSeg(upos[0],upos[1],upos[2],
596  upos[0]+udir[0],upos[1]+udir[1],upos[2]+udir[2],
597  zSeg2,rSeg2,thetaSeg2,phiSeg2);
598  if (pathCorrPos!=0&&pathCorrNorm!=0&&trackLength>0.) {
599  Double_t p1[3], pn[3], p2[3];
600  p1[0]=pathCorrPos->getX();
601  p1[1]=pathCorrPos->getY();
602  p1[2]=pathCorrPos->getZ();
603  pn[0]=pathCorrNorm->getX();
604  pn[1]=pathCorrNorm->getY();
605  pn[2]=pathCorrNorm->getZ();
606  findIntersectionPoint(trackPosOnMETA,udir,p1,pn,&p2[0]);
607  trackLength-=distance(trackPosOnMETA,p2);
608  }
609 }
610 
611 
612 Bool_t HRungeKutta::findIntersectionPoint(Double_t* upos, Double_t* udir,
613  Double_t* planeR0, Double_t* planeNorm,
614  Double_t* pointIntersect) {
615  // upos, udir - "moving point" current position and movement direction vector
616  // planeR0[3] some point on the plane to which intersection is supposed to happen
617  // planeNorm[3] perpendicular vector to the plane
618  // pointIntersect[3] - output - the intersection point of "moving point" with plane
619  Double_t denom = (planeNorm[0]*udir[0] + planeNorm[1]*udir[1] + planeNorm[2]*udir[2]);
620  if (denom!=0.0) {
621  Double_t t = ((planeR0[0]-upos[0])*planeNorm[0] +
622  (planeR0[1]-upos[1])*planeNorm[1] +
623  (planeR0[2]-upos[2])*planeNorm[2]) / denom;
624  for(Int_t i=0;i<3;i++) pointIntersect[i] = upos[i] + udir[i]*t;
625  return kTRUE;
626  } else {
627  Warning("findIntersectionPoint","No intersection point found : (plane || track)");
628  return kFALSE;
629  }
630 }
631 
632 
633 Bool_t HRungeKutta::decompose(TMatrixD &lu,Double_t &sign,Double_t tol,Int_t &nrZeros)
634 {
635  // THis part is copid from ROOT TDecompLU::Decompose() to get
636  // rid of error message!
637  // Crout/Doolittle algorithm of LU decomposing a square matrix, with implicit partial
638  // pivoting. The decomposition is stored in fLU: U is explicit in the upper triag
639  // and L is in multiplier form in the subdiagionals .
640  // Row permutations are mapped out in fIndex. fSign, used for calculating the
641  // determinant, is +/- 1 for even/odd row permutations. .
642 
643  // copied part from TDecompLU constructor-------
644 
645  Int_t fNIndex = lu.GetNcols();
646  Int_t* index = new Int_t[fNIndex];
647  memset(index,0,fNIndex*sizeof(Int_t));
648 
649  const Int_t kWorkMax = 100; // size of work array's in several routines
650  //-----------------------------------------------
651 
652  const Int_t n = lu.GetNcols();
653  Double_t *pLU = lu.GetMatrixArray();
654 
655  Double_t work[kWorkMax];
656  Bool_t isAllocated = kFALSE;
657  Double_t *scale = work;
658  if (n > kWorkMax) {
659  isAllocated = kTRUE;
660  scale = new Double_t[n];
661  }
662 
663  sign = 1.0;
664  nrZeros = 0;
665  // Find implicit scaling factors for each row
666  for (Int_t i = 0; i < n ; i++) {
667  const Int_t off_i = i*n;
668  Double_t max = 0.0;
669  for (Int_t j = 0; j < n; j++) {
670  const Double_t tmp = TMath::Abs(pLU[off_i+j]);
671  if (tmp > max)
672  max = tmp;
673  }
674  scale[i] = (max == 0.0 ? 0.0 : 1.0/max);
675  }
676 
677  for (Int_t j = 0; j < n; j++) {
678  const Int_t off_j = j*n;
679  Int_t i;
680  // Run down jth column from top to diag, to form the elements of U.
681  for (i = 0; i < j; i++) {
682  const Int_t off_i = i*n;
683  Double_t r = pLU[off_i+j];
684  for (Int_t k = 0; k < i; k++) {
685  const Int_t off_k = k*n;
686  r -= pLU[off_i+k]*pLU[off_k+j];
687  }
688  pLU[off_i+j] = r;
689  }
690 
691  // Run down jth subdiag to form the residuals after the elimination of
692  // the first j-1 subdiags. These residuals divided by the appropriate
693  // diagonal term will become the multipliers in the elimination of the jth.
694  // subdiag. Find fIndex of largest scaled term in imax.
695 
696  Double_t max = 0.0;
697  Int_t imax = 0;
698  for (i = j; i < n; i++) {
699  const Int_t off_i = i*n;
700  Double_t r = pLU[off_i+j];
701  for (Int_t k = 0; k < j; k++) {
702  const Int_t off_k = k*n;
703  r -= pLU[off_i+k]*pLU[off_k+j];
704  }
705  pLU[off_i+j] = r;
706  const Double_t tmp = scale[i]*TMath::Abs(r);
707  if (tmp >= max) {
708  max = tmp;
709  imax = i;
710  }
711  }
712 
713  // Permute current row with imax
714  if (j != imax) {
715  const Int_t off_imax = imax*n;
716  for (Int_t k = 0; k < n; k++ ) {
717  const Double_t tmp = pLU[off_imax+k];
718  pLU[off_imax+k] = pLU[off_j+k];
719  pLU[off_j+k] = tmp;
720  }
721  sign = -sign;
722  scale[imax] = scale[j];
723  }
724  index[j] = imax;
725 
726  // If diag term is not zero divide subdiag to form multipliers.
727  if (pLU[off_j+j] != 0.0) {
728  if (TMath::Abs(pLU[off_j+j]) < tol)
729  nrZeros++;
730  if (j != n-1) {
731  const Double_t tmp = 1.0/pLU[off_j+j];
732  for (Int_t i = j+1; i < n; i++) {
733  const Int_t off_i = i*n;
734  pLU[off_i+j] *= tmp;
735  }
736  }
737  } else {
738  if (isAllocated) delete [] scale;
739  delete [] index;
740  return kFALSE;
741  }
742  }
743 
744  if (isAllocated)
745  delete [] scale;
746 
747  delete [] index;
748  return kTRUE;
749 }
750 
void setField(HMdcTrackGField *, Float_t)
Definition: hrungekutta.cc:58
void initMom()
Definition: hrungekutta.cc:233
ClassImp(HRungeKutta) HRungeKutta
Definition: hrungekutta.cc:13
Bool_t fit3Hits(Double_t *, Double_t *, Double_t *, Double_t *, Float_t *, Int_t, Double_t pGuess=999999999.)
Definition: hrungekutta.cc:118
Double_t getZ() const
Definition: hgeomvector.h:24
Bool_t fit4Hits(Double_t *, Double_t *, Double_t *, Double_t *, Float_t *, Int_t, Double_t pGuess=999999999.)
Definition: hrungekutta.cc:92
Float_t dp
Definition: drawAccCuts.C:15
void traceToMETA(HGeomVector &, HGeomVector &, HGeomVector *point=NULL, HGeomVector *norm=NULL)
Definition: hrungekutta.cc:550
TGraph p2(xdim, pgrid, respme)
void setZ(const Double_t a)
Definition: hgeomvector.h:30
Int_t n
Int_t m1
Definition: drawAccCuts.C:11
Float_t rkgtrk(Float_t, Float_t, Double_t *, Double_t *, Int_t kind=0)
Definition: hrungekutta.cc:441
void findMdcIntersectionPoint(Double_t *, Double_t *, Int_t, Double_t *)
Definition: hrungekutta.cc:221
Float_t distance(Double_t *, Double_t *)
Definition: hrungekutta.cc:262
static void calcMdcSeg(Double_t x1, Double_t y1, Double_t z1, Double_t x2, Double_t y2, Double_t z2, Double_t &zm, Double_t &r0, Double_t &theta, Double_t &phi)
void parSetNewVar(Float_t, Float_t)
Definition: hrungekutta.cc:293
Bool_t linSys()
Definition: hrungekutta.cc:358
const HGeomVector & getTransVector() const
void rkeqfw(Double_t *, Float_t, Double_t *, Float_t *)
Definition: hrungekutta.cc:503
Bool_t fitMdc()
Definition: hrungekutta.cc:158
Double_t length() const
Definition: hgeomvector.h:53
void gentrkNew(Float_t, Double_t *, Double_t *, Double_t *, Int_t)
Definition: hrungekutta.cc:401
Bool_t decompose(TMatrixD &lu, Double_t &sign, Double_t tol, Int_t &nrZeros)
Definition: hrungekutta.cc:633
HGeomVector transFrom(const HGeomVector &p) const
Bool_t rc
TGraph p1(xdim, pgrid, resplo)
void traceToVertex(HMdcSizesCells *)
Definition: hrungekutta.cc:512
void derive(Double_t *, Int_t)
Definition: hrungekutta.cc:346
void setMdcPosition(Int_t, Int_t, HGeomTransform &)
Definition: hrungekutta.cc:65
void clear()
Definition: hrungekutta.cc:40
const HGeomVector & getTargetMiddlePoint(void) const
void cosines(Float_t, Float_t, Double_t *)
Definition: hrungekutta.cc:330
Double_t getX() const
Definition: hgeomvector.h:22
void parSetNew0(Float_t, Float_t, Int_t)
Definition: hrungekutta.cc:271
Double_t getY() const
Definition: hgeomvector.h:23
Bool_t findIntersectionPoint(Double_t *, Double_t *, Double_t *, Double_t *, Double_t *)
Definition: hrungekutta.cc:612