FairRoot/PandaRoot
KFParticleBaseSIMD.cxx
Go to the documentation of this file.
1 //---------------------------------------------------------------------------------
2 // Implementation of the KFParticleBaseSIMD class
3 // .
4 // @author S.Gorbunov, I.Kisel, I.Kulakov, M.Zyzak
5 // @version 1.0
6 // @since 13.05.07
7 //
8 // Class to reconstruct and store the decayed particle parameters.
9 // The method is described in CBM-SOFT note 2007-003,
10 // ``Reconstruction of decayed particles based on the Kalman filter'',
11 // http://www.gsi.de/documents/DOC-2007-May-14-1.pdf
12 //
13 // This class describes general mathematics which is used by KFParticle class
14 //
15 // -= Copyright &copy ALICE HLT and CBM L1 Groups =-
16 //_________________________________________________________________________________
17 
18 
19 #include "KFParticleBaseSIMD.h"
20 
21 #include <iostream>
22 
23 static const fvec Zero = 0;
24 static const fvec One = 1;
25 static const fvec small = 1.e-20;
26 
27 KFParticleBaseSIMD::KFParticleBaseSIMD() :fQ(0), fNDF(-3), fChi2(0), fSFromDecay(0), fAtProductionVertex(0), fIsLinearized(0), fConstructMethod(2), SumDaughterMass(0), fMassHypo(-1), fId(-1), fDaughterIds(), fPDG(0)
28 {
29  //* Constructor
30 
31  Initialize();
32 }
33 
34 void KFParticleBaseSIMD::Initialize( const fvec Param[], const fvec Cov[], fvec Charge, fvec Mass )
35 {
36  // Constructor from "cartesian" track, particle mass hypothesis should be provided
37  //
38  // Param[6] = { X, Y, Z, Px, Py, Pz } - position and momentum
39  // Cov [21] = lower-triangular part of the covariance matrix:
40  //
41  // ( 0 . . . . . )
42  // ( 1 2 . . . . )
43  // Cov. matrix = ( 3 4 5 . . . ) - numbering of covariance elements in Cov[]
44  // ( 6 7 8 9 . . )
45  // ( 10 11 12 13 14 . )
46  // ( 15 16 17 18 19 20 )
47 
48 
49  for( Int_t i=0; i<6 ; i++ ) fP[i] = Param[i];
50  for( Int_t i=0; i<21; i++ ) fC[i] = Cov[i];
51 
52  fvec energy = sqrt( Mass*Mass + fP[3]*fP[3] + fP[4]*fP[4] + fP[5]*fP[5]);
53  fP[6] = energy;
54  fP[7] = 0;
55  fQ = Charge;
56  fNDF = 0;
57  fChi2 = 0;
59  fIsLinearized = 0;
60  fSFromDecay = 0;
61 
62  fvec energyInv = 1./energy;
63  fvec
64  h0 = fP[3]*energyInv,
65  h1 = fP[4]*energyInv,
66  h2 = fP[5]*energyInv;
67 
68  fC[21] = h0*fC[ 6] + h1*fC[10] + h2*fC[15];
69  fC[22] = h0*fC[ 7] + h1*fC[11] + h2*fC[16];
70  fC[23] = h0*fC[ 8] + h1*fC[12] + h2*fC[17];
71  fC[24] = h0*fC[ 9] + h1*fC[13] + h2*fC[18];
72  fC[25] = h0*fC[13] + h1*fC[14] + h2*fC[19];
73  fC[26] = h0*fC[18] + h1*fC[19] + h2*fC[20];
74  fC[27] = ( h0*h0*fC[ 9] + h1*h1*fC[14] + h2*h2*fC[20]
75  + 2*(h0*h1*fC[13] + h0*h2*fC[18] + h1*h2*fC[19] ) );
76  for( Int_t i=28; i<36; i++ ) fC[i] = 0;
77  fC[35] = 1.;
78 
80  fMassHypo = Mass;
81 }
82 
84 {
85  //* Initialise covariance matrix and set current parameters to 0.0
86 
87  for( Int_t i=0; i<8; i++) fP[i] = 0;
88  for(Int_t i=0;i<36;++i) fC[i]=0.;
89  fC[0] = fC[2] = fC[5] = 100.;
90  fC[35] = 1.;
91  fNDF = -3;
92  fChi2 = 0.;
93  fQ = 0;
94  fSFromDecay = 0;
96  fVtxGuess[0]=fVtxGuess[1]=fVtxGuess[2]=0.;
98  fIsVtxGuess = 0;
99  fIsVtxGuess = 0;
100  fIsLinearized = 0;
101  SumDaughterMass = 0;
102  fMassHypo = -1;
103 }
104 
106 {
107  //* Set decay vertex parameters for linearisation
108 
109  fVtxGuess[0] = x;
110  fVtxGuess[1] = y;
111  fVtxGuess[2] = z;
112  fIsLinearized = 1;
113 }
114 
116 {
117  //* Set errors of the decay vertex parameters for linearisation
118 
119  fVtxErrGuess[0] = dx;
120  fVtxErrGuess[1] = dy;
121  fVtxErrGuess[2] = dz;
122  fIsVtxErrGuess = 1;
123 }
124 
126 {
127  //* Calculate particle momentum
128 
129  fvec ret = Zero;
130 
131  fvec x = fP[3];
132  fvec y = fP[4];
133  fvec z = fP[5];
134  fvec x2 = x*x;
135  fvec y2 = y*y;
136  fvec z2 = z*z;
137  fvec p2 = x2+y2+z2;
138  p = sqrt(p2);
139  error = (x2*fC[9]+y2*fC[14]+z2*fC[20] + 2*(x*y*fC[13]+x*z*fC[18]+y*z*fC[19]) );
140  const fvec LocalSmall = 1.e-4;
141  fvec mask = fvec( fvec(Zero < error) & fvec(LocalSmall < fabs(p)));
142  error = (mask & error);
143  error = sqrt(error);
144  ret = (!mask);
145  return ret;
146 }
147 
149 {
150  //* Calculate particle transverse momentum
151 
152  fvec ret = Zero;
153 
154  fvec px = fP[3];
155  fvec py = fP[4];
156  fvec px2 = px*px;
157  fvec py2 = py*py;
158  fvec pt2 = px2+py2;
159  pt = sqrt(pt2);
160  error = (px2*fC[9] + py2*fC[14] + 2*px*py*fC[13] );
161  const fvec LocalSmall = 1.e-4;
162  fvec mask = fvec( fvec(Zero < error) & fvec(LocalSmall < fabs(pt)));
163  error = (mask & error);
164  error = sqrt(error);
165  error += ((!mask) & fvec(1.e10));
166  ret = (!mask);
167  return ret;
168 }
169 
171 {
172  //* Calculate particle pseudorapidity
173 
174  fvec ret = Zero;
175 
176  const fvec BIG = 1.e10;
177  const fvec LocalSmall = 1.e-8;
178 
179  fvec px = fP[3];
180  fvec py = fP[4];
181  fvec pz = fP[5];
182  fvec pt2 = px*px + py*py;
183  fvec p2 = pt2 + pz*pz;
184  fvec p = sqrt(p2);
185  fvec a = p + pz;
186  fvec b = p - pz;
187  eta = BIG;
188  fvec c = Zero;
189  c = fvec(b > LocalSmall) & (a/b);
190  fvec logc = 0.5*log(c);
191  eta = if3(fvec(LocalSmall<fabs(c)), logc, eta);
192 
193  fvec h3 = -px*pz;
194  fvec h4 = -py*pz;
195  fvec pt4 = pt2*pt2;
196  fvec p2pt4 = p2*pt4;
197  error = (h3*h3*fC[9] + h4*h4*fC[14] + pt4*fC[20] + 2*( h3*(h4*fC[13] + fC[18]*pt2) + pt2*h4*fC[19] ) );
198 
199  fvec mask = fvec(fvec(LocalSmall < fabs(p2pt4)) & fvec(Zero < error));
200  error = if3( mask, (sqrt(error/p2pt4)), BIG);
201 
202  ret = (!mask);
203 
204  return ret;
205 }
206 
208 {
209  //* Calculate particle polar angle
210 
211  fvec ret = Zero;
212 
213  fvec px = fP[3];
214  fvec py = fP[4];
215  fvec px2 = px*px;
216  fvec py2 = py*py;
217  fvec pt2 = px2 + py2;
218  phi = atan2(py,px);
219  error = (py2*fC[9] + px2*fC[14] - fvec(2.f)*px*py*fC[13] );
220 
221  fvec mask = fvec(fvec(Zero < error) & fvec(fvec(1.e-4) < pt2));
222  error = if3( mask, sqrt(error)/pt2, fvec(1.e10));
223  ret = !mask;
224  return ret;
225 }
226 
228 {
229  //* Calculate distance to the origin
230 
231  fvec ret = Zero;
232 
233  fvec x = fP[0];
234  fvec y = fP[1];
235  fvec x2 = x*x;
236  fvec y2 = y*y;
237  r = sqrt(x2 + y2);
238  error = (x2*fC[0] + y2*fC[2] - fvec(2.f)*x*y*fC[1] );
239 
240  fvec mask = fvec(fvec(Zero < error) & fvec(fvec(1.e-4) < r));
241  error = if3( mask, sqrt(error)/r, fvec(1.e10));
242  ret = !mask;
243  return ret;
244 }
245 
247 {
248  //* Calculate particle mass
249 
250  // s = sigma^2 of m2/2
251 
252  const fvec BIG = 1.e20;
253  const fvec LocalSmall = 1.e-10;
254 
255  fvec ret = Zero;
256 
257  fvec s = ( fP[3]*fP[3]*fC[9] + fP[4]*fP[4]*fC[14] + fP[5]*fP[5]*fC[20]
258  + fP[6]*fP[6]*fC[27]
259  +fvec(2.f)*( + fP[3]*fP[4]*fC[13] + fP[5]*(fP[3]*fC[18] + fP[4]*fC[19])
260  - fP[6]*( fP[3]*fC[24] + fP[4]*fC[25] + fP[5]*fC[26] ) )
261  );
262 // fvec m2 = fabs(fP[6]*fP[6] - fP[3]*fP[3] - fP[4]*fP[4] - fP[5]*fP[5]);
263 // m = sqrt(m2);
264 // if( m>1.e-10 ){
265 // if( s>=0 ){
266 // error = sqrt(s)/m;
267 // return 0;
268 // }
269 // }
270 // error = 1.e20;
271  fvec m2 = (fP[6]*fP[6] - fP[3]*fP[3] - fP[4]*fP[4] - fP[5]*fP[5]);
272 
273  fvec mask = fvec(Zero <= m2);
274  m = if3(mask, sqrt(m2), -sqrt(-m2));
275 
276  mask = fvec(mask & fvec(fvec(Zero <= s) & (LocalSmall < m)));
277  error = if3(mask, sqrt(s)/m, BIG);
278 
279  ret = !mask;
280  return ret;
281 }
282 
283 
285 {
286  //* Calculate particle decay length [cm]
287 
288  fvec ret = Zero;
289  const fvec BIG = 1.e20;
290 
291  fvec x = fP[3];
292  fvec y = fP[4];
293  fvec z = fP[5];
294  fvec t = fP[7];
295  fvec x2 = x*x;
296  fvec y2 = y*y;
297  fvec z2 = z*z;
298  fvec p2 = x2+y2+z2;
299  l = t*sqrt(p2);
300 
301  error = p2*fC[35] + t*t/p2*(x2*fC[9]+y2*fC[14]+z2*fC[20]
302  + fvec(2.f)*(x*y*fC[13]+x*z*fC[18]+y*z*fC[19]) )
303  + fvec(2.f)*t*(x*fC[31]+y*fC[32]+z*fC[33]);
304 
305  fvec mask = fvec(fvec(1.e-4) < p2);
306  error = if3( mask, sqrt(fabs(error)), BIG);
307  ret = !mask;
308  return ret;
309 }
310 
312 {
313  //* Calculate particle decay length in XY projection [cm]
314 
315  const fvec BIG = 1.e20;
316  fvec ret = Zero;
317 
318  fvec x = fP[3];
319  fvec y = fP[4];
320  fvec t = fP[7];
321  fvec x2 = x*x;
322  fvec y2 = y*y;
323  fvec pt2 = x2+y2;
324  l = t*sqrt(pt2);
325 
326  error = pt2*fC[35] + t*t/pt2*(x2*fC[9]+y2*fC[14] + 2*x*y*fC[13] )
327  + fvec(2.f)*t*(x*fC[31]+y*fC[32]);
328  fvec mask = fvec(fvec(1.e-4) < pt2);
329  error = if3( mask, sqrt(fabs(error)), BIG);
330  ret = !mask;
331  return ret;
332 }
333 
334 
336 {
337  //* Calculate particle decay time [s]
338 
339  const fvec BIG = 1.e20;
340  fvec ret = Zero;
341 
342  fvec m, dm;
343  GetMass( m, dm );
344  fvec cTM = (-fP[3]*fC[31] - fP[4]*fC[32] - fP[5]*fC[33] + fP[6]*fC[34]);
345  tauC = fP[7]*m;
346  error = m*m*fC[35] + 2*fP[7]*cTM + fP[7]*fP[7]*dm*dm;
347  fvec mask = fvec(Zero < error);
348  error = if3( mask, sqrt(error), BIG);
349  ret = !mask;
350  return ret;
351 }
352 
353 
355 {
356  //* Add daughter via operator+=
357 
358  AddDaughter( Daughter );
359 }
360 
361 fvec KFParticleBaseSIMD::GetSCorrection( const fvec Part[], const fvec XYZ[] ) const
362 {
363  //* Get big enough correction for S error to let the particle Part be fitted to XYZ point
364 
365  fvec d[3] = { XYZ[0]-Part[0], XYZ[1]-Part[1], XYZ[2]-Part[2] };
366  fvec p2 = Part[3]*Part[3]+Part[4]*Part[4]+Part[5]*Part[5];
367 // fvec sigmaS = if3( fvec(fvec(1.e-4)<p2) , ( fvec(10.1)+fvec(3.)*sqrt( d[0]*d[0]+d[1]*d[1]+d[2]*d[2]) )/sqrt(p2) , One);
368 // fvec sigmaS = if3( fvec(fvec(1.e-4)<p2) , ( fvec(0.1)+fvec(10.)*sqrt( d[0]*d[0]+d[1]*d[1]+d[2]*d[2]) )/sqrt(p2) , One);
369 
370  fvec sigmaS = if3( fvec(fvec(1.e-4)<p2) , fvec(0.1)+fvec(10.)*sqrt( (d[0]*d[0]+d[1]*d[1]+d[2]*d[2])/p2 ) , One);
371 // fvec sigmaS = GetDStoPoint(XYZ)*0.08;
372 
373  return sigmaS;
374 }
375 
376 void KFParticleBaseSIMD::GetMeasurement( const fvec XYZ[], fvec m[], fvec V[], Bool_t isAtVtxGuess ) const
377 {
378  //* Get additional covariances V used during measurement
379 
380  fvec b[3];
381  GetFieldValue( XYZ, b );
382  const fvec kCLight = 0.000299792458;
383  b[0]*=kCLight*GetQ(); b[1]*=kCLight*GetQ(); b[2]*=kCLight*GetQ();
384 
385  if(!isAtVtxGuess)
386  Transport( GetDStoPoint(XYZ), m, V );
387  else
388  {
389  for(int iM=0; iM<8; iM++)
390  m[iM] = fP[iM];
391  for(int iV=0; iV<8; iV++)
392  V[iV] = fC[iV];
393  }
394 
395  fvec sigmaS = GetSCorrection( m, XYZ );
396 
397  fvec h[6];
398 
399  h[0] = m[3]*sigmaS;
400  h[1] = m[4]*sigmaS;
401  h[2] = m[5]*sigmaS;
402  h[3] = ( h[1]*b[2]-h[2]*b[1] );
403  h[4] = ( h[2]*b[0]-h[0]*b[2] );
404  h[5] = ( h[0]*b[1]-h[1]*b[0] );
405 
406  V[ 0]+= h[0]*h[0];
407  V[ 1]+= h[1]*h[0];
408  V[ 2]+= h[1]*h[1];
409  V[ 3]+= h[2]*h[0];
410  V[ 4]+= h[2]*h[1];
411  V[ 5]+= h[2]*h[2];
412 
413  V[ 6]+= h[3]*h[0];
414  V[ 7]+= h[3]*h[1];
415  V[ 8]+= h[3]*h[2];
416  V[ 9]+= h[3]*h[3];
417 
418  V[10]+= h[4]*h[0];
419  V[11]+= h[4]*h[1];
420  V[12]+= h[4]*h[2];
421  V[13]+= h[4]*h[3];
422  V[14]+= h[4]*h[4];
423 
424  V[15]+= h[5]*h[0];
425  V[16]+= h[5]*h[1];
426  V[17]+= h[5]*h[2];
427  V[18]+= h[5]*h[3];
428  V[19]+= h[5]*h[4];
429  V[20]+= h[5]*h[5];
430 
431 }
432 
433 void KFParticleBaseSIMD::AddDaughter( const KFParticleBaseSIMD &Daughter, Bool_t isAtVtxGuess )
434 {
435  AddDaughterId( Daughter.Id() );
436 
437  if( fNDF[0]<-1 ){ // first daughter -> just copy
438  fNDF = -1;
439  fQ = Daughter.GetQ();
440  if( Daughter.fC[35][0]>0 ){ //TODO Check this: only the first daughter is used here!
441  Daughter.GetMeasurement( fVtxGuess, fP, fC, isAtVtxGuess );
442  } else {
443  for( Int_t i=0; i<8; i++ ) fP[i] = Daughter.fP[i];
444  for( Int_t i=0; i<36; i++ ) fC[i] = Daughter.fC[i];
445  }
446  fSFromDecay = 0;
447  fMassHypo = Daughter.fMassHypo;
448  SumDaughterMass = Daughter.SumDaughterMass;
449  return;
450  }
451 
452  if(fConstructMethod == 0)
453  AddDaughterWithEnergyFit(Daughter,isAtVtxGuess);
454  else if(fConstructMethod == 1)
455  AddDaughterWithEnergyCalc(Daughter,isAtVtxGuess);
456  else if(fConstructMethod == 2)
457  AddDaughterWithEnergyFitMC(Daughter,isAtVtxGuess);
458 
459  SumDaughterMass += Daughter.SumDaughterMass;
460  fMassHypo = -1;
461 }
462 
464 {
465  //* Energy considered as an independent veriable, fitted independently from momentum, without any constraints on mass
466 
467  //* Add daughter
468 
469 // if(!isAtVtxGuess)
470 // TransportToDecayVertex();
471 
472  Int_t maxIter = 1;
473 
474  if( (!fIsLinearized) && (!isAtVtxGuess) ){
475  if( fNDF[0]==-1 ){
476  fvec ds, ds1;
477  GetDStoParticle(Daughter, ds, ds1);
478  TransportToDS( ds );
479  fvec m[8];
480  fvec mCd[36];
481  Daughter.Transport( ds1, m, mCd );
482  fVtxGuess[0] = .5*( fP[0] + m[0] );
483  fVtxGuess[1] = .5*( fP[1] + m[1] );
484  fVtxGuess[2] = .5*( fP[2] + m[2] );
485  } else {
486  fVtxGuess[0] = fP[0];
487  fVtxGuess[1] = fP[1];
488  fVtxGuess[2] = fP[2];
489  }
490  maxIter = 3;
491  }
492 
493  for( Int_t iter=0; iter<maxIter; iter++ ){
494 
495  fvec *ffP = fP, *ffC = fC;
496 
497  fvec m[8], mV[36];
498 
499  if( Daughter.fC[35][0]>0 ){ //TODO Check this: only the first daughter is used here!
500  Daughter.GetMeasurement( fVtxGuess, m, mV, isAtVtxGuess );
501  } else {
502  for( Int_t i=0; i<8; i++ ) m[i] = Daughter.fP[i];
503  for( Int_t i=0; i<36; i++ ) mV[i] = Daughter.fC[i];
504  }
505  //*
506 
507  fvec mS[6]= { ffC[0]+mV[0],
508  ffC[1]+mV[1], ffC[2]+mV[2],
509  ffC[3]+mV[3], ffC[4]+mV[4], ffC[5]+mV[5] };
510  InvertCholetsky3(mS);
511 
512  //* Residual (measured - estimated)
513 
514  fvec zeta[3] = { m[0]-ffP[0], m[1]-ffP[1], m[2]-ffP[2] };
515 
516 
517  //* CHt = CH' - D'
518 
519  fvec mCHt0[7], mCHt1[7], mCHt2[7];
520 
521  mCHt0[0]=ffC[ 0] ; mCHt1[0]=ffC[ 1] ; mCHt2[0]=ffC[ 3] ;
522  mCHt0[1]=ffC[ 1] ; mCHt1[1]=ffC[ 2] ; mCHt2[1]=ffC[ 4] ;
523  mCHt0[2]=ffC[ 3] ; mCHt1[2]=ffC[ 4] ; mCHt2[2]=ffC[ 5] ;
524  mCHt0[3]=ffC[ 6]-mV[ 6]; mCHt1[3]=ffC[ 7]-mV[ 7]; mCHt2[3]=ffC[ 8]-mV[ 8];
525  mCHt0[4]=ffC[10]-mV[10]; mCHt1[4]=ffC[11]-mV[11]; mCHt2[4]=ffC[12]-mV[12];
526  mCHt0[5]=ffC[15]-mV[15]; mCHt1[5]=ffC[16]-mV[16]; mCHt2[5]=ffC[17]-mV[17];
527  mCHt0[6]=ffC[21]-mV[21]; mCHt1[6]=ffC[22]-mV[22]; mCHt2[6]=ffC[23]-mV[23];
528 
529  //* Kalman gain K = mCH'*S
530 
531  fvec k0[7], k1[7], k2[7];
532 
533  for(Int_t i=0;i<7;++i){
534  k0[i] = mCHt0[i]*mS[0] + mCHt1[i]*mS[1] + mCHt2[i]*mS[3];
535  k1[i] = mCHt0[i]*mS[1] + mCHt1[i]*mS[2] + mCHt2[i]*mS[4];
536  k2[i] = mCHt0[i]*mS[3] + mCHt1[i]*mS[4] + mCHt2[i]*mS[5];
537  }
538 
539  //* New estimation of the vertex position
540 
541  if( iter<maxIter-1 ){
542  for(Int_t i=0; i<3; ++i)
543  fVtxGuess[i]= ffP[i] + k0[i]*zeta[0]+k1[i]*zeta[1]+k2[i]*zeta[2];
544  continue;
545  }
546 
547  // last itearation -> update the particle
548 
549  //* Add the daughter momentum to the particle momentum
550 
551  ffP[ 3] += m[ 3];
552  ffP[ 4] += m[ 4];
553  ffP[ 5] += m[ 5];
554  ffP[ 6] += m[ 6];
555 
556  ffC[ 9] += mV[ 9];
557  ffC[13] += mV[13];
558  ffC[14] += mV[14];
559  ffC[18] += mV[18];
560  ffC[19] += mV[19];
561  ffC[20] += mV[20];
562  ffC[24] += mV[24];
563  ffC[25] += mV[25];
564  ffC[26] += mV[26];
565  ffC[27] += mV[27];
566 
567 
568  //* New estimation of the vertex position r += K*zeta
569 
570  for(Int_t i=0;i<7;++i)
571  fP[i] = ffP[i] + (k0[i]*zeta[0] + k1[i]*zeta[1] + k2[i]*zeta[2]);
572 
573  //* New covariance matrix C -= K*(mCH')'
574 
575  for(Int_t i=0, k=0;i<7;++i){
576  for(Int_t j=0;j<=i;++j,++k){
577  fC[k] = ffC[k] - (k0[i]*mCHt0[j] + k1[i]*mCHt1[j] + k2[i]*mCHt2[j] );
578  }
579  }
580 
581  //* Calculate Chi^2
582  if( iter == (maxIter-1) ) {
583  fNDF += 2;
584  fQ += Daughter.GetQ();
585  fSFromDecay = 0;
586  fChi2 += (mS[0]*zeta[0] + mS[1]*zeta[1] + mS[3]*zeta[2])*zeta[0]
587  + (mS[1]*zeta[0] + mS[2]*zeta[1] + mS[4]*zeta[2])*zeta[1]
588  + (mS[3]*zeta[0] + mS[4]*zeta[1] + mS[5]*zeta[2])*zeta[2];
589  }
590 
591  }
592 }
593 
595 {
596  //* Energy considered as a dependent variable, calculated from the momentum and mass hypothesis
597 
598  //* Add daughter
599 
600 // if(!isAtVtxGuess)
601 // TransportToDecayVertex();
602 
603  Int_t maxIter = 1;
604 
605  if( (!fIsLinearized) && (!isAtVtxGuess) ){
606  if( fNDF[0]==-1 ){
607  fvec ds, ds1;
608  GetDStoParticle(Daughter, ds, ds1);
609  TransportToDS( ds );
610  fvec m[8];
611  fvec mCd[36];
612  Daughter.Transport( ds1, m, mCd );
613  fVtxGuess[0] = .5*( fP[0] + m[0] );
614  fVtxGuess[1] = .5*( fP[1] + m[1] );
615  fVtxGuess[2] = .5*( fP[2] + m[2] );
616  } else {
617  fVtxGuess[0] = fP[0];
618  fVtxGuess[1] = fP[1];
619  fVtxGuess[2] = fP[2];
620  }
621  maxIter = 3;
622  }
623 
624  for( Int_t iter=0; iter<maxIter; iter++ ){
625 
626  fvec *ffP = fP, *ffC = fC;
627 
628  fvec m[8], mV[36];
629 
630  if( Daughter.fC[35][0]>0 ){ //TODO Check this: only the first daughter is used here!
631  Daughter.GetMeasurement( fVtxGuess, m, mV, isAtVtxGuess );
632  } else {
633  for( Int_t i=0; i<8; i++ ) m[i] = Daughter.fP[i];
634  for( Int_t i=0; i<36; i++ ) mV[i] = Daughter.fC[i];
635  }
636 
637  fvec massMf2 = m[6]*m[6] - (m[3]*m[3] + m[4]*m[4] + m[5]*m[5]);
638  fvec massRf2 = fP[6]*fP[6] - (fP[3]*fP[3] + fP[4]*fP[4] + fP[5]*fP[5]);
639 
640  //*
641 
642  fvec mS[6]= { ffC[0]+mV[0],
643  ffC[1]+mV[1], ffC[2]+mV[2],
644  ffC[3]+mV[3], ffC[4]+mV[4], ffC[5]+mV[5] };
645  InvertCholetsky3(mS);
646 
647  //* Residual (measured - estimated)
648 
649  fvec zeta[3] = { m[0]-ffP[0], m[1]-ffP[1], m[2]-ffP[2] };
650 
651  //* CHt = CH' - D'
652 
653  fvec mCHt0[6], mCHt1[6], mCHt2[6];
654 
655  mCHt0[0]=ffC[ 0] ; mCHt1[0]=ffC[ 1] ; mCHt2[0]=ffC[ 3] ;
656  mCHt0[1]=ffC[ 1] ; mCHt1[1]=ffC[ 2] ; mCHt2[1]=ffC[ 4] ;
657  mCHt0[2]=ffC[ 3] ; mCHt1[2]=ffC[ 4] ; mCHt2[2]=ffC[ 5] ;
658  mCHt0[3]=ffC[ 6]-mV[ 6]; mCHt1[3]=ffC[ 7]-mV[ 7]; mCHt2[3]=ffC[ 8]-mV[ 8];
659  mCHt0[4]=ffC[10]-mV[10]; mCHt1[4]=ffC[11]-mV[11]; mCHt2[4]=ffC[12]-mV[12];
660  mCHt0[5]=ffC[15]-mV[15]; mCHt1[5]=ffC[16]-mV[16]; mCHt2[5]=ffC[17]-mV[17];
661 
662  //* Kalman gain K = mCH'*S
663 
664  fvec k0[6], k1[6], k2[6];
665 
666  for(Int_t i=0;i<6;++i){
667  k0[i] = mCHt0[i]*mS[0] + mCHt1[i]*mS[1] + mCHt2[i]*mS[3];
668  k1[i] = mCHt0[i]*mS[1] + mCHt1[i]*mS[2] + mCHt2[i]*mS[4];
669  k2[i] = mCHt0[i]*mS[3] + mCHt1[i]*mS[4] + mCHt2[i]*mS[5];
670  }
671 
672  //* New estimation of the vertex position
673 
674  if( iter<maxIter-1 ){
675  for(Int_t i=0; i<3; ++i)
676  fVtxGuess[i]= ffP[i] + k0[i]*zeta[0]+k1[i]*zeta[1]+k2[i]*zeta[2];
677  continue;
678  }
679 
680  //* find mf and mVf - optimum value of the measurement and its covariance matrix
681  //* mVHt = V*H'
682  fvec mVHt0[6], mVHt1[6], mVHt2[6];
683 
684  mVHt0[0]= mV[ 0] ; mVHt1[0]= mV[ 1] ; mVHt2[0]= mV[ 3] ;
685  mVHt0[1]= mV[ 1] ; mVHt1[1]= mV[ 2] ; mVHt2[1]= mV[ 4] ;
686  mVHt0[2]= mV[ 3] ; mVHt1[2]= mV[ 4] ; mVHt2[2]= mV[ 5] ;
687  mVHt0[3]= mV[ 6] ; mVHt1[3]= mV[ 7] ; mVHt2[3]= mV[ 8] ;
688  mVHt0[4]= mV[10] ; mVHt1[4]= mV[11] ; mVHt2[4]= mV[12] ;
689  mVHt0[5]= mV[15] ; mVHt1[5]= mV[16] ; mVHt2[5]= mV[17] ;
690 
691  //* Kalman gain Km = mCH'*S
692 
693  fvec km0[6], km1[6], km2[6];
694 
695  for(Int_t i=0;i<6;++i){
696  km0[i] = mVHt0[i]*mS[0] + mVHt1[i]*mS[1] + mVHt2[i]*mS[3];
697  km1[i] = mVHt0[i]*mS[1] + mVHt1[i]*mS[2] + mVHt2[i]*mS[4];
698  km2[i] = mVHt0[i]*mS[3] + mVHt1[i]*mS[4] + mVHt2[i]*mS[5];
699  }
700 
701  fvec mf[7] = { m[0], m[1], m[2], m[3], m[4], m[5], m[6] };
702 
703  for(Int_t i=0;i<6;++i)
704  mf[i] = mf[i] - km0[i]*zeta[0] - km1[i]*zeta[1] - km2[i]*zeta[2];
705 
706  fvec energyMf = sqrt( massMf2 + (mf[3]*mf[3] + mf[4]*mf[4] + mf[5]*mf[5]) );
707 
708  fvec mVf[28];
709  for(Int_t iC=0; iC<28; iC++)
710  mVf[iC] = mV[iC];
711 
712  //* hmf = d(energyMf)/d(mf)
713  fvec hmf[7];
714  hmf[3] = if3( fvec(fabs(energyMf) < small), Zero, hmf[3]/energyMf);
715  hmf[4] = if3( fvec(fabs(energyMf) < small), Zero, hmf[4]/energyMf);
716  hmf[5] = if3( fvec(fabs(energyMf) < small), Zero, hmf[5]/energyMf);
717  hmf[6] = 0;
718 
719  for(Int_t i=0, k=0;i<6;++i){
720  for(Int_t j=0;j<=i;++j,++k){
721  mVf[k] = mVf[k] - (km0[i]*mVHt0[j] + km1[i]*mVHt1[j] + km2[i]*mVHt2[j] );
722  }
723  }
724  fvec mVf24 = mVf[24], mVf25 = mVf[25], mVf26 = mVf[26];
725  mVf[21] = mVf[6 ]*hmf[3] + mVf[10]*hmf[4] + mVf[15]*hmf[5] + mVf[21]*hmf[6];
726  mVf[22] = mVf[7 ]*hmf[3] + mVf[11]*hmf[4] + mVf[16]*hmf[5] + mVf[22]*hmf[6];
727  mVf[23] = mVf[8 ]*hmf[3] + mVf[12]*hmf[4] + mVf[17]*hmf[5] + mVf[23]*hmf[6];
728  mVf[24] = mVf[9 ]*hmf[3] + mVf[13]*hmf[4] + mVf[18]*hmf[5] + mVf[24]*hmf[6];
729  mVf[25] = mVf[13]*hmf[3] + mVf[14]*hmf[4] + mVf[19]*hmf[5] + mVf[25]*hmf[6];
730  mVf[26] = mVf[18]*hmf[3] + mVf[19]*hmf[4] + mVf[20]*hmf[5] + mVf[26]*hmf[6];
731  mVf[27] = mVf[24]*hmf[3] + mVf[25]*hmf[4] + mVf[26]*hmf[5] + (mVf24*hmf[3] + mVf25*hmf[4] + mVf26*hmf[5] + mVf[27]*hmf[6])*hmf[6]; //here mVf[] are already modified
732 
733  mf[6] = energyMf;
734 
735  //* find rf and mCf - optimum value of the measurement and its covariance matrix
736 
737  //* mCCHt = C*H'
738  fvec mCCHt0[6], mCCHt1[6], mCCHt2[6];
739 
740  mCCHt0[0]=ffC[ 0]; mCCHt1[0]=ffC[ 1]; mCCHt2[0]=ffC[ 3];
741  mCCHt0[1]=ffC[ 1]; mCCHt1[1]=ffC[ 2]; mCCHt2[1]=ffC[ 4];
742  mCCHt0[2]=ffC[ 3]; mCCHt1[2]=ffC[ 4]; mCCHt2[2]=ffC[ 5];
743  mCCHt0[3]=ffC[ 6]; mCCHt1[3]=ffC[ 7]; mCCHt2[3]=ffC[ 8];
744  mCCHt0[4]=ffC[10]; mCCHt1[4]=ffC[11]; mCCHt2[4]=ffC[12];
745  mCCHt0[5]=ffC[15]; mCCHt1[5]=ffC[16]; mCCHt2[5]=ffC[17];
746 
747  //* Kalman gain Krf = mCH'*S
748 
749  fvec krf0[6], krf1[6], krf2[6];
750 
751  for(Int_t i=0;i<6;++i){
752  krf0[i] = mCCHt0[i]*mS[0] + mCCHt1[i]*mS[1] + mCCHt2[i]*mS[3];
753  krf1[i] = mCCHt0[i]*mS[1] + mCCHt1[i]*mS[2] + mCCHt2[i]*mS[4];
754  krf2[i] = mCCHt0[i]*mS[3] + mCCHt1[i]*mS[4] + mCCHt2[i]*mS[5];
755  }
756  fvec rf[7] = { ffP[0], ffP[1], ffP[2], ffP[3], ffP[4], ffP[5], ffP[6] };
757 
758  for(Int_t i=0;i<6;++i)
759  rf[i] = rf[i] + krf0[i]*zeta[0] + krf1[i]*zeta[1] + krf2[i]*zeta[2];
760 
761  fvec energyRf = sqrt( massRf2 + (rf[3]*rf[3] + rf[4]*rf[4] + rf[5]*rf[5]) );
762 
763  fvec mCf[28];
764  for(Int_t iC=0; iC<28; iC++)
765  mCf[iC] = ffC[iC];
766  //* hrf = d(Erf)/d(rf)
767  fvec hrf[7];
768  hrf[3] = if3( fvec(fabs(energyRf) < small), Zero, rf[3]/energyRf);
769  hrf[4] = if3( fvec(fabs(energyRf) < small), Zero, rf[4]/energyRf);
770  hrf[5] = if3( fvec(fabs(energyRf) < small), Zero, rf[5]/energyRf);
771 // hrf[6] = if3( fvec(fabs(E_rf) < small), Zero, rf[6]/E_rf);
772  hrf[6] = 0;
773 
774  for(Int_t i=0, k=0;i<6;++i){
775  for(Int_t j=0;j<=i;++j,++k){
776  mCf[k] = mCf[k] - (krf0[i]*mCCHt0[j] + krf1[i]*mCCHt1[j] + krf2[i]*mCCHt2[j] );
777  }
778  }
779  fvec mCf24 = mCf[24], mCf25 = mCf[25], mCf26 = mCf[26];
780  mCf[21] = mCf[6 ]*hrf[3] + mCf[10]*hrf[4] + mCf[15]*hrf[5] + mCf[21]*hrf[6];
781  mCf[22] = mCf[7 ]*hrf[3] + mCf[11]*hrf[4] + mCf[16]*hrf[5] + mCf[22]*hrf[6];
782  mCf[23] = mCf[8 ]*hrf[3] + mCf[12]*hrf[4] + mCf[17]*hrf[5] + mCf[23]*hrf[6];
783  mCf[24] = mCf[9 ]*hrf[3] + mCf[13]*hrf[4] + mCf[18]*hrf[5] + mCf[24]*hrf[6];
784  mCf[25] = mCf[13]*hrf[3] + mCf[14]*hrf[4] + mCf[19]*hrf[5] + mCf[25]*hrf[6];
785  mCf[26] = mCf[18]*hrf[3] + mCf[19]*hrf[4] + mCf[20]*hrf[5] + mCf[26]*hrf[6];
786  mCf[27] = mCf[24]*hrf[3] + mCf[25]*hrf[4] + mCf[26]*hrf[5] + (mCf24*hrf[3] + mCf25*hrf[4] + mCf26*hrf[5] + mCf[27]*hrf[6])*hrf[6]; //here mCf[] are already modified
787 
788  for(Int_t iC=21; iC<28; iC++)
789  {
790  ffC[iC] = mCf[iC];
791  mV[iC] = mVf[iC];
792  }
793 
794  fP[6] = energyRf + energyMf;
795  rf[6] = energyRf;
796 
797  //fvec Dvv[3][3]; do not need this
798  fvec mDvp[3][3];
799  fvec mDpv[3][3];
800  fvec mDpp[3][3];
801  fvec mDe[7];
802 
803  for(int i=0; i<3; i++)
804  {
805  for(int j=0; j<3; j++)
806  {
807  mDvp[i][j] = km0[i+3]*mCCHt0[j] + km1[i+3]*mCCHt1[j] + km2[i+3]*mCCHt2[j];
808  mDpv[i][j] = km0[i]*mCCHt0[j+3] + km1[i]*mCCHt1[j+3] + km2[i]*mCCHt2[j+3];
809  mDpp[i][j] = km0[i+3]*mCCHt0[j+3] + km1[i+3]*mCCHt1[j+3] + km2[i+3]*mCCHt2[j+3];
810  }
811  }
812 
813  mDe[0] = hmf[3]*mDvp[0][0] + hmf[4]*mDvp[1][0] + hmf[5]*mDvp[2][0];
814  mDe[1] = hmf[3]*mDvp[0][1] + hmf[4]*mDvp[1][1] + hmf[5]*mDvp[2][1];
815  mDe[2] = hmf[3]*mDvp[0][2] + hmf[4]*mDvp[1][2] + hmf[5]*mDvp[2][2];
816  mDe[3] = hmf[3]*mDpp[0][0] + hmf[4]*mDpp[1][0] + hmf[5]*mDpp[2][0];
817  mDe[4] = hmf[3]*mDpp[0][1] + hmf[4]*mDpp[1][1] + hmf[5]*mDpp[2][1];
818  mDe[5] = hmf[3]*mDpp[0][2] + hmf[4]*mDpp[1][2] + hmf[5]*mDpp[2][2];
819  mDe[6] = 2*(mDe[3]*hrf[3] + mDe[4]*hrf[4] + mDe[5]*hrf[5]);
820 
821  // last itearation -> update the particle
822 
823  //* Add the daughter momentum to the particle momentum
824 
825  ffP[ 3] += m[ 3];
826  ffP[ 4] += m[ 4];
827  ffP[ 5] += m[ 5];
828 
829  ffC[ 9] += mV[ 9];
830  ffC[13] += mV[13];
831  ffC[14] += mV[14];
832  ffC[18] += mV[18];
833  ffC[19] += mV[19];
834  ffC[20] += mV[20];
835  ffC[24] += mV[24];
836  ffC[25] += mV[25];
837  ffC[26] += mV[26];
838  ffC[27] += mV[27];
839 
840  ffC[21] += mDe[0];
841  ffC[22] += mDe[1];
842  ffC[23] += mDe[2];
843  ffC[24] += mDe[3];
844  ffC[25] += mDe[4];
845  ffC[26] += mDe[5];
846  ffC[27] += mDe[6];
847 
848  //* New estimation of the vertex position r += K*zeta
849 
850  for(Int_t i=0;i<6;++i)
851  fP[i] = ffP[i] + k0[i]*zeta[0] + k1[i]*zeta[1] + k2[i]*zeta[2];
852 
853  //* New covariance matrix C -= K*(mCH')'
854 
855  for(Int_t i=0, k=0;i<6;++i){
856  for(Int_t j=0;j<=i;++j,++k){
857  fC[k] = ffC[k] - (k0[i]*mCHt0[j] + k1[i]*mCHt1[j] + k2[i]*mCHt2[j] );
858  }
859  }
860 
861  for(int i=21; i<28; i++) fC[i] = ffC[i];
862 
863  //* Calculate Chi^2
864 
865  if( iter == (maxIter-1) ) {
866  fNDF += 2;
867  fQ += Daughter.GetQ();
868  fSFromDecay = 0;
869  fChi2 += (mS[0]*zeta[0] + mS[1]*zeta[1] + mS[3]*zeta[2])*zeta[0]
870  + (mS[1]*zeta[0] + mS[2]*zeta[1] + mS[4]*zeta[2])*zeta[1]
871  + (mS[3]*zeta[0] + mS[4]*zeta[1] + mS[5]*zeta[2])*zeta[2];
872  }
873  }
874 }
875 
877 {
878  //* Energy considered as an independent variable, fitted independently from momentum, without any constraints on mass
879 
880  //* Add daughter
881 
882 // if(!isAtVtxGuess)
883 // TransportToDecayVertex();
884 
885  Int_t maxIter = 1;
886 
887  if( (!fIsLinearized) && (!isAtVtxGuess) ){
888  if( fNDF[0]==-1 ){
889  fvec ds, ds1;
890  GetDStoParticle(Daughter, ds, ds1);
891  TransportToDS( ds );
892  fvec m[8];
893  fvec mCd[36];
894  Daughter.Transport( ds1, m, mCd );
895  fVtxGuess[0] = .5*( fP[0] + m[0] );
896  fVtxGuess[1] = .5*( fP[1] + m[1] );
897  fVtxGuess[2] = .5*( fP[2] + m[2] );
898  } else {
899  fVtxGuess[0] = fP[0];
900  fVtxGuess[1] = fP[1];
901  fVtxGuess[2] = fP[2];
902  }
903  maxIter = 3;
904  }
905 
906  for( Int_t iter=0; iter<maxIter; iter++ ){
907 
908  fvec *ffP = fP, *ffC = fC;
909  fvec m[8], mV[36];
910 
911  if( Daughter.fC[35][0]>0 ){ //TODO Check this: only the first daughter is used here!
912  Daughter.GetMeasurement( fVtxGuess, m, mV, isAtVtxGuess );
913  } else {
914  for( Int_t i=0; i<8; i++ ) m[i] = Daughter.fP[i];
915  for( Int_t i=0; i<36; i++ ) mV[i] = Daughter.fC[i];
916  }
917  //*
918 
919  fvec mS[6]= { ffC[0]+mV[0],
920  ffC[1]+mV[1], ffC[2]+mV[2],
921  ffC[3]+mV[3], ffC[4]+mV[4], ffC[5]+mV[5] };
922  InvertCholetsky3(mS);
923 
924  //* Residual (measured - estimated)
925 
926  fvec zeta[3] = { m[0]-ffP[0], m[1]-ffP[1], m[2]-ffP[2] };
927 
928 
929  //* CHt = CH'
930 
931  fvec mCHt0[7], mCHt1[7], mCHt2[7];
932 
933  mCHt0[0]=ffC[ 0] ; mCHt1[0]=ffC[ 1] ; mCHt2[0]=ffC[ 3] ;
934  mCHt0[1]=ffC[ 1] ; mCHt1[1]=ffC[ 2] ; mCHt2[1]=ffC[ 4] ;
935  mCHt0[2]=ffC[ 3] ; mCHt1[2]=ffC[ 4] ; mCHt2[2]=ffC[ 5] ;
936  mCHt0[3]=ffC[ 6] ; mCHt1[3]=ffC[ 7] ; mCHt2[3]=ffC[ 8] ;
937  mCHt0[4]=ffC[10] ; mCHt1[4]=ffC[11] ; mCHt2[4]=ffC[12] ;
938  mCHt0[5]=ffC[15] ; mCHt1[5]=ffC[16] ; mCHt2[5]=ffC[17] ;
939  mCHt0[6]=ffC[21] ; mCHt1[6]=ffC[22] ; mCHt2[6]=ffC[23] ;
940 
941  //* Kalman gain K = mCH'*S
942 
943  fvec k0[7], k1[7], k2[7];
944 
945  for(Int_t i=0;i<7;++i){
946  k0[i] = mCHt0[i]*mS[0] + mCHt1[i]*mS[1] + mCHt2[i]*mS[3];
947  k1[i] = mCHt0[i]*mS[1] + mCHt1[i]*mS[2] + mCHt2[i]*mS[4];
948  k2[i] = mCHt0[i]*mS[3] + mCHt1[i]*mS[4] + mCHt2[i]*mS[5];
949  }
950 
951  //* New estimation of the vertex position
952 
953  if( iter<maxIter-1 ){
954  for(Int_t i=0; i<3; ++i)
955  fVtxGuess[i]= ffP[i] + k0[i]*zeta[0]+k1[i]*zeta[1]+k2[i]*zeta[2];
956  continue;
957  }
958 
959  // last itearation -> update the particle
960 
961  //* VHt = VH'
962 
963  fvec mVHt0[7], mVHt1[7], mVHt2[7];
964 
965  mVHt0[0]=mV[ 0] ; mVHt1[0]=mV[ 1] ; mVHt2[0]=mV[ 3] ;
966  mVHt0[1]=mV[ 1] ; mVHt1[1]=mV[ 2] ; mVHt2[1]=mV[ 4] ;
967  mVHt0[2]=mV[ 3] ; mVHt1[2]=mV[ 4] ; mVHt2[2]=mV[ 5] ;
968  mVHt0[3]=mV[ 6] ; mVHt1[3]=mV[ 7] ; mVHt2[3]=mV[ 8] ;
969  mVHt0[4]=mV[10] ; mVHt1[4]=mV[11] ; mVHt2[4]=mV[12] ;
970  mVHt0[5]=mV[15] ; mVHt1[5]=mV[16] ; mVHt2[5]=mV[17] ;
971  mVHt0[6]=mV[21] ; mVHt1[6]=mV[22] ; mVHt2[6]=mV[23] ;
972 
973  //* Kalman gain Km = mCH'*S
974 
975  fvec km0[7], km1[7], km2[7];
976 
977  for(Int_t i=0;i<7;++i){
978  km0[i] = mVHt0[i]*mS[0] + mVHt1[i]*mS[1] + mVHt2[i]*mS[3];
979  km1[i] = mVHt0[i]*mS[1] + mVHt1[i]*mS[2] + mVHt2[i]*mS[4];
980  km2[i] = mVHt0[i]*mS[3] + mVHt1[i]*mS[4] + mVHt2[i]*mS[5];
981  }
982 
983  for(Int_t i=0;i<7;++i)
984  ffP[i] = ffP[i] + k0[i]*zeta[0] + k1[i]*zeta[1] + k2[i]*zeta[2];
985 
986  for(Int_t i=0;i<7;++i)
987  m[i] = m[i] - km0[i]*zeta[0] - km1[i]*zeta[1] - km2[i]*zeta[2];
988 
989  for(Int_t i=0, k=0;i<7;++i){
990  for(Int_t j=0;j<=i;++j,++k){
991  ffC[k] = ffC[k] - (k0[i]*mCHt0[j] + k1[i]*mCHt1[j] + k2[i]*mCHt2[j] );
992  }
993  }
994 
995  for(Int_t i=0, k=0;i<7;++i){
996  for(Int_t j=0;j<=i;++j,++k){
997  mV[k] = mV[k] - (km0[i]*mVHt0[j] + km1[i]*mVHt1[j] + km2[i]*mVHt2[j] );
998  }
999  }
1000 
1001  fvec mDf[7][7];
1002 
1003  for(Int_t i=0;i<7;++i){
1004  for(Int_t j=0;j<7;++j){
1005  mDf[i][j] = (km0[i]*mCHt0[j] + km1[i]*mCHt1[j] + km2[i]*mCHt2[j] );
1006  }
1007  }
1008 
1009  fvec mJ1[7][7], mJ2[7][7];
1010  for(Int_t iPar1=0; iPar1<7; iPar1++)
1011  {
1012  for(Int_t iPar2=0; iPar2<7; iPar2++)
1013  {
1014  mJ1[iPar1][iPar2] = 0;
1015  mJ2[iPar1][iPar2] = 0;
1016  }
1017  }
1018 
1019  fvec mMassParticle = ffP[6]*ffP[6] - (ffP[3]*ffP[3] + ffP[4]*ffP[4] + ffP[5]*ffP[5]);
1020  fvec mMassDaughter = m[6]*m[6] - (m[3]*m[3] + m[4]*m[4] + m[5]*m[5]);
1021  mMassParticle = if3( fvec( mMassParticle > Zero ), sqrt(mMassParticle) , Zero);
1022  mMassDaughter = if3( fvec( mMassDaughter > Zero ), sqrt(mMassDaughter) , Zero);
1023 
1024  fvec mask1 = fvec(fMassHypo > fvec(-0.5));
1025  fvec mask2 = fvec ( fvec(!mask1) & fvec( fvec(mMassParticle < SumDaughterMass) | fvec(ffP[6]<Zero)) );
1026  SetMassConstraint(ffP,ffC,mJ1,fMassHypo, mask1);
1027  SetMassConstraint(ffP,ffC,mJ1,SumDaughterMass, mask2);
1028 
1029  fvec mask3 = fvec(fvec(Daughter.fMassHypo) > fvec(-0.5));
1030  fvec mask4 = fvec( fvec(!mask3) & fvec( fvec(mMassDaughter<Daughter.SumDaughterMass) | fvec(m[6]<Zero)) );
1031  SetMassConstraint(m,mV,mJ2,Daughter.fMassHypo, mask3);
1032  SetMassConstraint(m,mV,mJ2,Daughter.SumDaughterMass, mask4);
1033 
1034  fvec mDJ[7][7];
1035 
1036  for(Int_t i=0; i<7; i++) {
1037  for(Int_t j=0; j<7; j++) {
1038  mDJ[i][j] = 0;
1039  for(Int_t k=0; k<7; k++) {
1040  mDJ[i][j] += mDf[i][k]*mJ1[j][k];
1041  }
1042  }
1043  }
1044 
1045  for(Int_t i=0; i<7; ++i){
1046  for(Int_t j=0; j<7; ++j){
1047  mDf[i][j]=0;
1048  for(Int_t l=0; l<7; l++){
1049  mDf[i][j] += mJ2[i][l]*mDJ[l][j];
1050  }
1051  }
1052  }
1053 
1054  //* Add the daughter momentum to the particle momentum
1055 
1056  ffP[ 3] += m[ 3];
1057  ffP[ 4] += m[ 4];
1058  ffP[ 5] += m[ 5];
1059  ffP[ 6] += m[ 6];
1060 
1061  ffC[ 9] += mV[ 9];
1062  ffC[13] += mV[13];
1063  ffC[14] += mV[14];
1064  ffC[18] += mV[18];
1065  ffC[19] += mV[19];
1066  ffC[20] += mV[20];
1067  ffC[24] += mV[24];
1068  ffC[25] += mV[25];
1069  ffC[26] += mV[26];
1070  ffC[27] += mV[27];
1071 
1072  ffC[6 ] += mDf[3][0]; ffC[7 ] += mDf[3][1]; ffC[8 ] += mDf[3][2];
1073  ffC[10] += mDf[4][0]; ffC[11] += mDf[4][1]; ffC[12] += mDf[4][2];
1074  ffC[15] += mDf[5][0]; ffC[16] += mDf[5][1]; ffC[17] += mDf[5][2];
1075  ffC[21] += mDf[6][0]; ffC[22] += mDf[6][1]; ffC[23] += mDf[6][2];
1076 
1077  ffC[9 ] += mDf[3][3] + mDf[3][3];
1078  ffC[13] += mDf[4][3] + mDf[3][4]; ffC[14] += mDf[4][4] + mDf[4][4];
1079  ffC[18] += mDf[5][3] + mDf[3][5]; ffC[19] += mDf[5][4] + mDf[4][5]; ffC[20] += mDf[5][5] + mDf[5][5];
1080  ffC[24] += mDf[6][3] + mDf[3][6]; ffC[25] += mDf[6][4] + mDf[4][6]; ffC[26] += mDf[6][5] + mDf[5][6]; ffC[27] += mDf[6][6] + mDf[6][6];
1081 
1082  //* New estimation of the vertex position r += K*zeta
1083 
1084  for(Int_t i=0;i<7;++i)
1085  fP[i] = ffP[i];
1086 
1087  //* New covariance matrix C -= K*(mCH')'
1088 
1089  for(Int_t i=0, k=0;i<7;++i){
1090  for(Int_t j=0;j<=i;++j,++k){
1091  fC[k] = ffC[k];
1092  }
1093  }
1094  //* Calculate Chi^2
1095 
1096  if( iter == (maxIter-1) ) {
1097  fNDF += 2;
1098  fQ += Daughter.GetQ();
1099  fSFromDecay = 0;
1100  fChi2 += (mS[0]*zeta[0] + mS[1]*zeta[1] + mS[3]*zeta[2])*zeta[0]
1101  + (mS[1]*zeta[0] + mS[2]*zeta[1] + mS[4]*zeta[2])*zeta[1]
1102  + (mS[3]*zeta[0] + mS[4]*zeta[1] + mS[5]*zeta[2])*zeta[2];
1103  }
1104  }
1105 }
1106 
1108 {
1109  //* Set production vertex for the particle, when the particle was not used in the vertex fit
1110 
1111  const fvec *m = Vtx.fP, *mV = Vtx.fC;
1112 
1113  Bool_t noS = ( fC[35][0]<=0 ); // no decay length allowed //TODO Check this: only the first daughter is used here!
1114 
1115  if( noS ){
1117  fP[7] = 0;
1118  fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = fC[35] = 0;
1119  } else {
1120  TransportToDS( GetDStoPoint( m ) );
1121  fP[7] = -fSFromDecay;
1122  fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = 0;
1123  fC[35] = 0.1;
1124 
1125  Convert(1);
1126  }
1127 
1128  fvec mAi[6] = {fC[0], fC[1], fC[2], fC[3], fC[4], fC[5]};
1129 
1130  InvertCholetsky3(mAi);
1131 // InvertSym3( fC, mAi );
1132 
1133  fvec mB[5][3];
1134 
1135  mB[0][0] = fC[ 6]*mAi[0] + fC[ 7]*mAi[1] + fC[ 8]*mAi[3];
1136  mB[0][1] = fC[ 6]*mAi[1] + fC[ 7]*mAi[2] + fC[ 8]*mAi[4];
1137  mB[0][2] = fC[ 6]*mAi[3] + fC[ 7]*mAi[4] + fC[ 8]*mAi[5];
1138 
1139  mB[1][0] = fC[10]*mAi[0] + fC[11]*mAi[1] + fC[12]*mAi[3];
1140  mB[1][1] = fC[10]*mAi[1] + fC[11]*mAi[2] + fC[12]*mAi[4];
1141  mB[1][2] = fC[10]*mAi[3] + fC[11]*mAi[4] + fC[12]*mAi[5];
1142 
1143  mB[2][0] = fC[15]*mAi[0] + fC[16]*mAi[1] + fC[17]*mAi[3];
1144  mB[2][1] = fC[15]*mAi[1] + fC[16]*mAi[2] + fC[17]*mAi[4];
1145  mB[2][2] = fC[15]*mAi[3] + fC[16]*mAi[4] + fC[17]*mAi[5];
1146 
1147  mB[3][0] = fC[21]*mAi[0] + fC[22]*mAi[1] + fC[23]*mAi[3];
1148  mB[3][1] = fC[21]*mAi[1] + fC[22]*mAi[2] + fC[23]*mAi[4];
1149  mB[3][2] = fC[21]*mAi[3] + fC[22]*mAi[4] + fC[23]*mAi[5];
1150 
1151  mB[4][0] = fC[28]*mAi[0] + fC[29]*mAi[1] + fC[30]*mAi[3];
1152  mB[4][1] = fC[28]*mAi[1] + fC[29]*mAi[2] + fC[30]*mAi[4];
1153  mB[4][2] = fC[28]*mAi[3] + fC[29]*mAi[4] + fC[30]*mAi[5];
1154 
1155  fvec z[3] = { m[0]-fP[0], m[1]-fP[1], m[2]-fP[2] };
1156 
1157  {
1158  fvec mAVi[6] = { fC[0]-mV[0], fC[1]-mV[1], fC[2]-mV[2],
1159  fC[3]-mV[3], fC[4]-mV[4], fC[5]-mV[5] };
1160 
1161 // fvec init = InvertSym3( mAVi, mAVi ) ;
1162  InvertCholetsky3(mAVi);
1163 
1164  fvec dChi2 = ( +(mAVi[0]*z[0] + mAVi[1]*z[1] + mAVi[3]*z[2])*z[0]
1165  +(mAVi[1]*z[0] + mAVi[2]*z[1] + mAVi[4]*z[2])*z[1]
1166  +(mAVi[3]*z[0] + mAVi[4]*z[1] + mAVi[5]*z[2])*z[2] );
1167 
1168  // Take Abs(dChi2) here. Negative value of 'det' or 'dChi2' shows that the particle
1169  // was not used in the production vertex fit
1170 
1171 // fChi2 += (!init) & fabs( dChi2 );
1172  fChi2 += fabs( dChi2 );
1173  fNDF += 2;
1174  }
1175 
1176  fP[0] = m[0];
1177  fP[1] = m[1];
1178  fP[2] = m[2];
1179  fP[3]+= mB[0][0]*z[0] + mB[0][1]*z[1] + mB[0][2]*z[2];
1180  fP[4]+= mB[1][0]*z[0] + mB[1][1]*z[1] + mB[1][2]*z[2];
1181  fP[5]+= mB[2][0]*z[0] + mB[2][1]*z[1] + mB[2][2]*z[2];
1182  fP[6]+= mB[3][0]*z[0] + mB[3][1]*z[1] + mB[3][2]*z[2];
1183  fP[7]+= mB[4][0]*z[0] + mB[4][1]*z[1] + mB[4][2]*z[2];
1184 
1185  fvec d0, d1, d2;
1186 
1187  fC[0] = mV[0];
1188  fC[1] = mV[1];
1189  fC[2] = mV[2];
1190  fC[3] = mV[3];
1191  fC[4] = mV[4];
1192  fC[5] = mV[5];
1193 
1194  d0= mB[0][0]*mV[0] + mB[0][1]*mV[1] + mB[0][2]*mV[3] - fC[ 6];
1195  d1= mB[0][0]*mV[1] + mB[0][1]*mV[2] + mB[0][2]*mV[4] - fC[ 7];
1196  d2= mB[0][0]*mV[3] + mB[0][1]*mV[4] + mB[0][2]*mV[5] - fC[ 8];
1197 
1198  fC[ 6]+= d0;
1199  fC[ 7]+= d1;
1200  fC[ 8]+= d2;
1201  fC[ 9]+= d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
1202 
1203  d0= mB[1][0]*mV[0] + mB[1][1]*mV[1] + mB[1][2]*mV[3] - fC[10];
1204  d1= mB[1][0]*mV[1] + mB[1][1]*mV[2] + mB[1][2]*mV[4] - fC[11];
1205  d2= mB[1][0]*mV[3] + mB[1][1]*mV[4] + mB[1][2]*mV[5] - fC[12];
1206 
1207  fC[10]+= d0;
1208  fC[11]+= d1;
1209  fC[12]+= d2;
1210  fC[13]+= d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
1211  fC[14]+= d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
1212 
1213  d0= mB[2][0]*mV[0] + mB[2][1]*mV[1] + mB[2][2]*mV[3] - fC[15];
1214  d1= mB[2][0]*mV[1] + mB[2][1]*mV[2] + mB[2][2]*mV[4] - fC[16];
1215  d2= mB[2][0]*mV[3] + mB[2][1]*mV[4] + mB[2][2]*mV[5] - fC[17];
1216 
1217  fC[15]+= d0;
1218  fC[16]+= d1;
1219  fC[17]+= d2;
1220  fC[18]+= d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
1221  fC[19]+= d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
1222  fC[20]+= d0*mB[2][0] + d1*mB[2][1] + d2*mB[2][2];
1223 
1224  d0= mB[3][0]*mV[0] + mB[3][1]*mV[1] + mB[3][2]*mV[3] - fC[21];
1225  d1= mB[3][0]*mV[1] + mB[3][1]*mV[2] + mB[3][2]*mV[4] - fC[22];
1226  d2= mB[3][0]*mV[3] + mB[3][1]*mV[4] + mB[3][2]*mV[5] - fC[23];
1227 
1228  fC[21]+= d0;
1229  fC[22]+= d1;
1230  fC[23]+= d2;
1231  fC[24]+= d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
1232  fC[25]+= d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
1233  fC[26]+= d0*mB[2][0] + d1*mB[2][1] + d2*mB[2][2];
1234  fC[27]+= d0*mB[3][0] + d1*mB[3][1] + d2*mB[3][2];
1235 
1236  d0= mB[4][0]*mV[0] + mB[4][1]*mV[1] + mB[4][2]*mV[3] - fC[28];
1237  d1= mB[4][0]*mV[1] + mB[4][1]*mV[2] + mB[4][2]*mV[4] - fC[29];
1238  d2= mB[4][0]*mV[3] + mB[4][1]*mV[4] + mB[4][2]*mV[5] - fC[30];
1239 
1240  fC[28]+= d0;
1241  fC[29]+= d1;
1242  fC[30]+= d2;
1243  fC[31]+= d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
1244  fC[32]+= d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
1245  fC[33]+= d0*mB[2][0] + d1*mB[2][1] + d2*mB[2][2];
1246  fC[34]+= d0*mB[3][0] + d1*mB[3][1] + d2*mB[3][2];
1247  fC[35]+= d0*mB[4][0] + d1*mB[4][1] + d2*mB[4][2];
1248 
1249  if( noS ){
1250  fP[7] = 0;
1251  fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = fC[35] = 0;
1252  } else {
1253  TransportToDS( fP[7] );
1254  Convert(0);
1255  }
1256 
1257  fSFromDecay = 0;
1258 }
1259 
1260 void KFParticleBaseSIMD::SetMassConstraint( fvec *mP, fvec *mC, fvec mJ[7][7], fvec mass, fvec mask )
1261 {
1262  //* Set nonlinear mass constraint (Mass) on the state vector mP with a covariance matrix mC.
1263 
1264  const fvec energy2 = mP[6]*mP[6], p2 = mP[3]*mP[3]+mP[4]*mP[4]+mP[5]*mP[5], mass2 = mass*mass;
1265 
1266  const fvec a = energy2 - p2 + 2.*mass2;
1267  const fvec b = -2.*(energy2 + p2);
1268  const fvec c = energy2 - p2 - mass2;
1269 
1270  fvec lambda = if3( fvec( fabs(b) > fvec(1.e-10) ), -c/b , Zero);
1271 
1272  fvec d = 4.*energy2*p2 - mass2*(energy2-p2-2.*mass2);
1273  fvec qMask = fvec( fvec(d >= Zero) & fvec(fabs(a) > fvec(1.e-10)) );
1274  lambda = if3( qMask, ((energy2 + p2 - sqrt(d))/a), lambda );
1275 
1276  lambda = if3( fvec(mP[6]<Zero), fvec(-1000000.f), lambda );
1277 
1278  Int_t iIter=0;
1279  for(iIter=0; iIter<100; iIter++)
1280  {
1281  fvec lambda2 = lambda*lambda;
1282  fvec lambda4 = lambda2*lambda2;
1283 
1284 // fvec lambda0 = lambda;
1285 
1286  fvec f = -mass2 * lambda4 + a*lambda2 + b*lambda + c;
1287  fvec df = -4.*mass2 * lambda2*lambda + 2.*a*lambda + b;
1288  lambda -= if3(fvec( fabs(df) > fvec(1.e-10) ) , f/df, Zero);
1289 // if(TMath::Abs(lambda0 - lambda) < 1.e-8) break;
1290  }
1291 
1292  const fvec lpi = 1./(1. + lambda);
1293  const fvec lmi = 1./(1. - lambda);
1294  const fvec lp2i = lpi*lpi;
1295  const fvec lm2i = lmi*lmi;
1296 
1297  fvec lambda2 = lambda*lambda;
1298 
1299  fvec dfl = -4.*mass2 * lambda2*lambda + 2.*a*lambda + b;
1300  fvec dfx[7] = {0};//,0,0,0};
1301  dfx[0] = -2.*(1. + lambda)*(1. + lambda)*mP[3];
1302  dfx[1] = -2.*(1. + lambda)*(1. + lambda)*mP[4];
1303  dfx[2] = -2.*(1. + lambda)*(1. + lambda)*mP[5];
1304  dfx[3] = 2.*(1. - lambda)*(1. - lambda)*mP[6];
1305  fvec dlx[4] = {1,1,1,1};
1306 
1307  for(int i=0; i<4; i++)
1308  dlx[i] = if3( fvec( fabs(dfl) > fvec(1.e-10) ), -dfx[i] / dfl, dlx[i] );
1309 
1310  fvec dxx[4] = {mP[3]*lm2i, mP[4]*lm2i, mP[5]*lm2i, -mP[6]*lp2i};
1311 
1312  for(Int_t i=0; i<7; i++)
1313  for(Int_t j=0; j<7; j++)
1314  mJ[i][j]=0;
1315  mJ[0][0] = 1.;
1316  mJ[1][1] = 1.;
1317  mJ[2][2] = 1.;
1318 
1319  for(Int_t i=3; i<7; i++)
1320  for(Int_t j=3; j<7; j++)
1321  mJ[i][j] = dlx[j-3]*dxx[i-3];
1322 
1323  for(Int_t i=3; i<6; i++)
1324  mJ[i][i] += lmi;
1325  mJ[6][6] += lpi;
1326 
1327  fvec mCJ[7][7];
1328 
1329  for(Int_t i=0; i<7; i++) {
1330  for(Int_t j=0; j<7; j++) {
1331  mCJ[i][j] = 0;
1332  for(Int_t k=0; k<7; k++) {
1333  mCJ[i][j] += mC[IJ(i,k)]*mJ[j][k];
1334  }
1335  }
1336  }
1337 
1338  for(Int_t i=0; i<7; ++i){
1339  for(Int_t j=0; j<=i; ++j){
1340  mC[IJ(i,j)] = if3(mask, Zero, mC[IJ(i,j)]);
1341  for(Int_t l=0; l<7; l++){
1342  mC[IJ(i,j)] += if3(mask, mJ[i][l]*mCJ[l][j], Zero);
1343  }
1344  }
1345  }
1346 
1347  mP[3] *= if3(mask, lmi, One);
1348  mP[4] *= if3(mask, lmi, One);
1349  mP[5] *= if3(mask, lmi, One);
1350  mP[6] *= if3(mask, lpi, One);
1351 }
1352 
1354 {
1355  //* Set nonlinear mass constraint (mass)
1356 
1357  fvec mJ[7][7];
1358  SetMassConstraint( fP, fC, mJ, mass, fvec( One > Zero) );
1359  fMassHypo = mass;
1360  SumDaughterMass = mass;
1361 }
1362 
1364 {
1365  //* Set hard( SigmaMass=0 ) or soft (SigmaMass>0) mass constraint
1366 
1367  fMassHypo = Mass;
1369 
1370  fvec m2 = Mass*Mass; // measurement, weighted by Mass
1371  fvec s2 = m2*SigmaMass*SigmaMass; // sigma^2
1372 
1373  fvec p2 = fP[3]*fP[3] + fP[4]*fP[4] + fP[5]*fP[5];
1374  fvec e0 = sqrt(m2+p2);
1375 
1376  fvec mH[8];
1377  mH[0] = mH[1] = mH[2] = 0.;
1378  mH[3] = -2*fP[3];
1379  mH[4] = -2*fP[4];
1380  mH[5] = -2*fP[5];
1381  mH[6] = 2*fP[6];//e0;
1382  mH[7] = 0;
1383 
1384  fvec zeta = e0*e0 - e0*fP[6];
1385  zeta = m2 - (fP[6]*fP[6]-p2);
1386 
1387  fvec mCHt[8], s2_est=0;
1388  for( Int_t i=0; i<8; ++i ){
1389  mCHt[i] = 0.0;
1390  for (Int_t j=0;j<8;++j) mCHt[i] += Cij(i,j)*mH[j];
1391  s2_est += mH[i]*mCHt[i];
1392  }
1393 
1394 //TODO Next line should be uncommented
1395 // if( s2_est<1.e-20 ) return; // calculated mass error is already 0,
1396  // the particle can not be constrained on mass
1397 
1398  fvec w2 = 1./( s2 + s2_est );
1399  fChi2 += zeta*zeta*w2;
1400  fNDF += 1;
1401  for( Int_t i=0, ii=0; i<8; ++i ){
1402  fvec ki = mCHt[i]*w2;
1403  fP[i]+= ki*zeta;
1404  for(Int_t j=0;j<=i;++j) fC[ii++] -= ki*mCHt[j];
1405  }
1406 }
1407 
1408 
1410 {
1411  //* Set no decay length for resonances
1412 
1414 
1415  fvec h[8];
1416  h[0] = h[1] = h[2] = h[3] = h[4] = h[5] = h[6] = 0;
1417  h[7] = 1;
1418 
1419  fvec zeta = 0 - fP[7];
1420  for(Int_t i=0;i<8;++i) zeta -= h[i]*(fP[i]-fP[i]);
1421 
1422  fvec s = fC[35];
1423 // if( s>1.e-20 ) //TODO Should be uncommented!
1424  {
1425  s = 1./s;
1426  fChi2 += zeta*zeta*s;
1427  fNDF += 1;
1428  for( Int_t i=0, ii=0; i<7; ++i ){
1429  fvec ki = fC[28+i]*s;
1430  fP[i]+= ki*zeta;
1431  for(Int_t j=0;j<=i;++j) fC[ii++] -= ki*fC[28+j];
1432  }
1433  }
1434  fP[7] = 0;
1435  fC[28] = fC[29] = fC[30] = fC[31] = fC[32] = fC[33] = fC[34] = fC[35] = 0;
1436 }
1437 
1438 void KFParticleBaseSIMD::Construct( const KFParticleBaseSIMD* vDaughters[], Int_t nDaughters,
1439  const KFParticleBaseSIMD *Parent, Float_t Mass, Bool_t IsConstrained ,
1440  Bool_t isAtVtxGuess )
1441 {
1442  //* Full reconstruction in one go
1443 
1444  Int_t maxIter = 1;
1445  bool wasLinearized = fIsLinearized;
1446  if( (!fIsLinearized || IsConstrained) && (!isAtVtxGuess) ){
1447  //fVtxGuess[0] = fVtxGuess[1] = fVtxGuess[2] = 0; //!!!!
1448  fvec ds=0., ds1=0.;
1449  fvec P[8], C[36];
1450  vDaughters[0]->GetDStoParticleLine(*vDaughters[1], ds, ds1);
1451  vDaughters[0]->TransportLine(ds,P,C);
1452  fVtxGuess[0] = P[0];
1453  fVtxGuess[1] = P[1];
1454  fVtxGuess[2] = P[2];
1455 /* fVtxGuess[0] = GetX();
1456  fVtxGuess[1] = GetY();
1457  fVtxGuess[2] = GetZ();*/
1458 
1459  if(!fIsVtxErrGuess)
1460  {
1461  fVtxErrGuess[0] = if3(fvec(C[0]>Zero), 10*sqrt(C[0]), One);
1462  fVtxErrGuess[1] = if3(fvec(C[2]>Zero), 10*sqrt(C[2]), One);
1463  fVtxErrGuess[2] = if3(fvec(C[5]>Zero), 10*sqrt(C[5]), One);
1464  }
1465 
1466  fIsLinearized = 1;
1467  maxIter = 3;
1468  }
1469  else {
1470  if(!fIsVtxErrGuess)
1471  {
1472  fVtxErrGuess[0] = 1;
1473  fVtxErrGuess[1] = 1;
1474  fVtxErrGuess[2] = 1;
1475  }
1476  }
1477 
1478  fvec constraintC[6];
1479 
1480  if( IsConstrained ){
1481  for(Int_t i=0;i<6;++i) constraintC[i]=fC[i];
1482  }
1483  else {
1484  for(Int_t i=0;i<6;++i) constraintC[i]=0.;
1485 // constraintC[0] = constraintC[2] = constraintC[5] = 100.;
1486 
1487  constraintC[0] = fVtxErrGuess[0]*fVtxErrGuess[0];
1488  constraintC[2] = fVtxErrGuess[1]*fVtxErrGuess[1];
1489  constraintC[5] = fVtxErrGuess[2]*fVtxErrGuess[2];
1490  }
1491 
1492 
1493  for( Int_t iter=0; iter<maxIter; iter++ ){
1494 
1495  CleanDaughtersId();
1496  SetNDaughters(nDaughters);
1497 
1498  fAtProductionVertex = 0;
1499  fSFromDecay = 0;
1500  fP[0] = fVtxGuess[0];
1501  fP[1] = fVtxGuess[1];
1502  fP[2] = fVtxGuess[2];
1503  fP[3] = 0;
1504  fP[4] = 0;
1505  fP[5] = 0;
1506  fP[6] = 0;
1507  fP[7] = 0;
1508  SumDaughterMass = 0;
1509 
1510  for(Int_t i=0;i<6; ++i) fC[i]=constraintC[i];
1511  for(Int_t i=6;i<36;++i) fC[i]=0.;
1512  fC[35] = 1.;
1513 
1514  fNDF = IsConstrained ?0 :-3;
1515  fChi2 = 0.;
1516  fQ = 0;
1517 
1518  for( Int_t itr =0; itr<nDaughters; itr++ ){
1519  AddDaughter( *vDaughters[itr], isAtVtxGuess );
1520  }
1521  if( iter<maxIter-1){
1522  for( Int_t i=0; i<3; i++ ) fVtxGuess[i] = fP[i];
1523  }
1524  }
1525  fIsLinearized = wasLinearized;
1526 
1527  if( Mass>=0 ) SetMassConstraint( Mass );
1528  if( Parent ) SetProductionVertex( *Parent );
1529 }
1530 
1531 void KFParticleBaseSIMD::Convert( bool ToProduction )
1532 {
1533  //* Tricky function - convert the particle error along its trajectory to
1534  //* the value which corresponds to its production/decay vertex
1535  //* It is done by combination of the error of decay length with the position errors
1536 
1537  fvec fld[3];
1538  {
1539  GetFieldValue( fP, fld );
1540  const fvec kCLight = fQ*0.000299792458;
1541  fld[0]*=kCLight; fld[1]*=kCLight; fld[2]*=kCLight;
1542  }
1543 
1544  fvec h[6];
1545 
1546  h[0] = fP[3];
1547  h[1] = fP[4];
1548  h[2] = fP[5];
1549  if( ToProduction ){ h[0]=-h[0]; h[1]=-h[1]; h[2]=-h[2]; }
1550  h[3] = h[1]*fld[2]-h[2]*fld[1];
1551  h[4] = h[2]*fld[0]-h[0]*fld[2];
1552  h[5] = h[0]*fld[1]-h[1]*fld[0];
1553 
1554  fvec c;
1555 
1556  c = fC[28]+h[0]*fC[35];
1557  fC[ 0]+= h[0]*(c+fC[28]);
1558  fC[28] = c;
1559 
1560  fC[ 1]+= h[1]*fC[28] + h[0]*fC[29];
1561  c = fC[29]+h[1]*fC[35];
1562  fC[ 2]+= h[1]*(c+fC[29]);
1563  fC[29] = c;
1564 
1565  fC[ 3]+= h[2]*fC[28] + h[0]*fC[30];
1566  fC[ 4]+= h[2]*fC[29] + h[1]*fC[30];
1567  c = fC[30]+h[2]*fC[35];
1568  fC[ 5]+= h[2]*(c+fC[30]);
1569  fC[30] = c;
1570 
1571  fC[ 6]+= h[3]*fC[28] + h[0]*fC[31];
1572  fC[ 7]+= h[3]*fC[29] + h[1]*fC[31];
1573  fC[ 8]+= h[3]*fC[30] + h[2]*fC[31];
1574  c = fC[31]+h[3]*fC[35];
1575  fC[ 9]+= h[3]*(c+fC[31]);
1576  fC[31] = c;
1577 
1578  fC[10]+= h[4]*fC[28] + h[0]*fC[32];
1579  fC[11]+= h[4]*fC[29] + h[1]*fC[32];
1580  fC[12]+= h[4]*fC[30] + h[2]*fC[32];
1581  fC[13]+= h[4]*fC[31] + h[3]*fC[32];
1582  c = fC[32]+h[4]*fC[35];
1583  fC[14]+= h[4]*(c+fC[32]);
1584  fC[32] = c;
1585 
1586  fC[15]+= h[5]*fC[28] + h[0]*fC[33];
1587  fC[16]+= h[5]*fC[29] + h[1]*fC[33];
1588  fC[17]+= h[5]*fC[30] + h[2]*fC[33];
1589  fC[18]+= h[5]*fC[31] + h[3]*fC[33];
1590  fC[19]+= h[5]*fC[32] + h[4]*fC[33];
1591  c = fC[33]+h[5]*fC[35];
1592  fC[20]+= h[5]*(c+fC[33]);
1593  fC[33] = c;
1594 
1595  fC[21]+= h[0]*fC[34];
1596  fC[22]+= h[1]*fC[34];
1597  fC[23]+= h[2]*fC[34];
1598  fC[24]+= h[3]*fC[34];
1599  fC[25]+= h[4]*fC[34];
1600  fC[26]+= h[5]*fC[34];
1601 }
1602 
1603 
1605 {
1606  //* Transport the particle to its decay vertex
1607 
1609  if( fAtProductionVertex ) Convert(0);
1610  fAtProductionVertex = 0;
1611 }
1612 
1614 {
1615  //* Transport the particle to its production vertex
1616 
1617  TransportToDS( -fSFromDecay-fP[7] );
1618  if( !fAtProductionVertex ) Convert( 1 );
1619  fAtProductionVertex = 1;
1620 }
1621 
1622 
1624 {
1625  //* Transport the particle on dS parameter (SignedPath/Momentum)
1626 
1627  Transport( dS, fP, fC );
1628  fSFromDecay+= dS;
1629 }
1630 
1631 
1632 void KFParticleBaseSIMD::GetDistanceToVertexLine( const KFParticleBaseSIMD &Vertex, fvec &l, fvec &dl, fvec *isParticleFromVertex ) const
1633 {
1634  //* Get dS to a certain space point without field
1635 
1636  fvec c[6] = {Vertex.fC[0]+fC[0], Vertex.fC[1]+fC[1], Vertex.fC[2]+fC[2],
1637  Vertex.fC[3]+fC[3], Vertex.fC[4]+fC[4], Vertex.fC[5]+fC[5]};
1638 
1639  fvec dx = (Vertex.fP[0]-fP[0]);
1640  fvec dy = (Vertex.fP[1]-fP[1]);
1641  fvec dz = (Vertex.fP[2]-fP[2]);
1642 
1643  l = sqrt( dx*dx + dy*dy + dz*dz );
1644  dl = c[0]*dx*dx + c[2]*dy*dy + c[5]*dz*dz + 2*(c[1]*dx*dy + c[3]*dx*dz + c[4]*dy*dz);
1645  fvec ok = fvec(fvec(0)<dl);
1646  dl = fvec(ok & (sqrt( dl )/l)) + fvec(!ok & fvec(1.e8));
1647 
1648  if(isParticleFromVertex)
1649  {
1650  *isParticleFromVertex = fvec(ok & fvec( l<fvec(3*dl) ));
1651  fvec cos = dx*fP[3] + dy*fP[4] + dz*fP[5];
1652 // fvec dCos = dy*dy*fC[14] + dz*dz*fC[20] + dx*dx*fC[9] + 2*dz*fC[15]*fP[3] + c[0]* fP[3]*fP[3] +
1653 // 2*dz*fC[16]* fP[4] + 2 *c[1] *fP[3] *fP[4] + c[2] *fP[4]*fP[4] + 2 *dz *fC[17]* fP[5] +
1654 // 2*c[3] *fP[3]* fP[5] + 2 *c[4] *fP[4] *fP[5] + c[5]*fP[5] *fP[5] +
1655 // 2*dy *(dz *fC[19] + fC[10] *fP[3] + fC[11]* fP[4] + fC[12]* fP[5]) +
1656 // 2*dx *(dy *fC[13] + dz *fC[18] + fC[6]* fP[3] + fC[7]* fP[4] + fC[8]* fP[5]);
1657 // ok = fvec(fvec(0)<dCos);
1658 // dCos = fvec(ok & ( dCos ));
1659 // dCos = sqrt(dCos);
1660  *isParticleFromVertex = fvec( (*isParticleFromVertex) | fvec(!(*isParticleFromVertex) & fvec(cos<Zero) ) );
1661  }
1662 }
1663 
1664 
1666  const
1667 {
1668 
1669  //* Get dS to a certain space point for Bz field
1670  const fvec kCLight = 0.000299792458;
1671  fvec bq = B*fQ*kCLight;
1672  fvec pt2 = fP[3]*fP[3] + fP[4]*fP[4];
1673 
1674  fvec dx = xyz[0] - fP[0];
1675  fvec dy = xyz[1] - fP[1];
1676  fvec a = dx*fP[3]+dy*fP[4];
1677  fvec dS = Zero;
1678 
1679  const fvec LocalSmall = 1.e-8;
1680  fvec mask = fvec( fabs(bq)<LocalSmall );
1681  dS = if3(mask, a/pt2, (atan2( bq*a, pt2 + bq*(dy*fP[3] -dx*fP[4]) )/bq));
1682 
1683  #if 0
1684  {
1685 
1686  fvec px = fP[3];
1687  fvec py = fP[4];
1688  fvec pz = fP[5];
1689  fvec ss[2], g[2][5];
1690 
1691  ss[0] = dS;
1692  ss[1] = -dS;
1693  for( Int_t i=0; i<2; i++){
1694  fvec bs = bq*ss[i];
1695  fvec c = TMath::Cos(bs), s = TMath::Sin(bs);
1696  fvec cB,sB;
1697  if( TMath::Abs(bq)>1.e-8){
1698  cB= (1-c)/bq;
1699  sB= s/bq;
1700  }else{
1701  const fvec kOvSqr6 = 1./TMath::Sqrt(6.);
1702  sB = (1.-bs*kOvSqr6)*(1.+bs*kOvSqr6)*ss[i];
1703  cB = .5*sB*bs;
1704  }
1705  g[i][0] = fP[0] + sB*px + cB*py;
1706  g[i][1] = fP[1] - cB*px + sB*py;
1707  g[i][2] = fP[2] + ss[i]*pz;
1708  g[i][3] = + c*px + s*py;
1709  g[i][4] = - s*px + c*py;
1710  }
1711 
1712  Int_t i=0;
1713 
1714  fvec dMin = 1.e10;
1715  for( Int_t j=0; j<2; j++){
1716  fvec xx = g[j][0]-xyz[0];
1717  fvec yy = g[j][1]-xyz[1];
1718  fvec zz = g[j][2]-xyz[2];
1719  fvec d = xx*xx + yy*yy + zz*zz;
1720  if( d<dMin ){
1721  dMin = d;
1722  i = j;
1723  }
1724  }
1725 
1726  dS = ss[i];
1727 
1728  fvec x= g[i][0], y= g[i][1], z= g[i][2], ppx= g[i][3], ppy= g[i][4];
1729  fvec ddx = x-xyz[0];
1730  fvec ddy = y-xyz[1];
1731  fvec ddz = z-xyz[2];
1732  fvec c = ddx*ppx + ddy*ppy + ddz*pz ;
1733  fvec pp2 = ppx*ppx + ppy*ppy + pz*pz;
1734  if( TMath::Abs(pp2)>1.e-8 ){
1735  dS+=c/pp2;
1736  }
1737  }
1738  #endif
1739  return dS;
1740 }
1741 
1743  const
1744 {
1745 
1746  //* Get dS to a certain space point for Bz field
1747 
1748  const fvec kCLight = 0.000299792458;
1749  fvec bq = B*fQ*kCLight;
1750  fvec pt2 = fP[3]*fP[3] + fP[5]*fP[5];
1751 
1752  fvec dx = xyz[0] - fP[0];
1753  fvec dy = -xyz[2] + fP[2];
1754  fvec a = dx*fP[3]-dy*fP[5];
1755  fvec dS = Zero;
1756 
1757  const fvec LocalSmall = 1.e-8;
1758  fvec mask = fvec( fabs(bq)<LocalSmall );
1759  dS = if3(mask, a/pt2, (atan2( bq*a, pt2 + bq*(dy*fP[3] +dx*fP[5]) )/bq));
1760  return dS;
1761 }
1762 
1764 {
1765  //* Get dS to another particle for Bz field
1766 
1767  fvec px = fP[3];
1768  fvec py = fP[4];
1769  fvec pz = fP[5];
1770 
1771  fvec px1 = p.fP[3];
1772  fvec py1 = p.fP[4];
1773  fvec pz1 = p.fP[5];
1774 
1775  const fvec kCLight = 0.000299792458;
1776 
1777  fvec bq = B*fQ*kCLight;
1778  fvec bq1 = B*p.fQ*kCLight;
1779  fvec s=Zero, ds=Zero, s1=Zero, ds1=Zero;
1780 
1781  const fvec LocalSmall = 1.e-8;
1782 
1783  fvec bq_big = fvec(LocalSmall < fabs(bq));
1784  fvec bq1_big = fvec(LocalSmall < fabs(bq1));
1785  {
1786  const fvec two = 2.;
1787  const fvec four = 2.;
1788  fvec dx = (p.fP[0] - fP[0]);
1789  fvec dy = (p.fP[1] - fP[1]);
1790  fvec d2 = (dx*dx+dy*dy);
1791 
1792  fvec p2 = (px *px + py *py);
1793  fvec p21 = (px1*px1 + py1*py1);
1794 
1795  fvec a = (px*py1 - py*px1);
1796  fvec b = (px*px1 + py*py1);
1797 
1798  fvec ldx = bq*bq1*dx - bq1*py + bq*py1 ;
1799  fvec ldy = bq*bq1*dy + bq1*px - bq*px1 ;
1800  fvec l2 = ldx*ldx + ldy*ldy;
1801 
1802  fvec cS = bq1*p2 + bq*bq1*(dy* px - dx* py) - bq*b;
1803  fvec cS1= bq*p21 - bq*bq1*(dy*px1 - dx*py1) - bq1*b;
1804 
1805  fvec ca = bq*bq*bq1*d2 + two*( cS + bq*bq*(py1*dx-px1*dy)) ;
1806  fvec ca1 = bq*bq1*bq1*d2 + two*( cS1 - bq1*bq1*(py*dx-px*dy)) ;
1807 
1808  fvec sa = 4*l2*p2 - ca*ca;
1809  fvec sa1 = 4*l2*p21 - ca1*ca1;
1810 
1811  const fvec saNeg = fvec(sa<Zero);
1812  sa = (!saNeg) & sa;
1813  const fvec sa1Neg = fvec(sa1<Zero);
1814  sa1= (!sa1Neg) & sa1;
1815 
1816 
1817  s = if3( bq_big, (atan2( bq*( bq1*(dx*px +dy*py) + a ) , cS )/bq), (( (dx*px + dy*py) + (py*px1-px*py1)/bq1)/p2) );
1818  ds = if3( bq_big, (atan2(sqrt(sa),ca)/bq) , (s*s - (d2-two*(px1*dy-py1*dx)/bq1)/p2) );
1819  fvec dsNeg = fvec(ds<Zero);
1820  ds = ( fvec((!dsNeg) & (!bq_big)) & sqrt(ds) ) + (bq_big & ds);
1821 
1822  s1 = if3( bq1_big, (atan2( -bq1*( bq*(dx*px1+dy*py1) + a), cS1 )/bq1), ((-(dx*px1 + dy*py1) + (py*px1-px*py1)/bq)/p21) );
1823  ds1 = if3( bq1_big, (atan2(sqrt(sa1),ca1)/bq1) , (s1*s1 - (d2+two*(px*dy-py*dx)/bq)/p21) );
1824  fvec ds1Neg = fvec(ds1<Zero);
1825  ds1 = ( fvec((!ds1Neg) & (!bq1_big)) & sqrt(ds1) ) + (bq1_big & ds1);
1826  }
1827 
1828  fvec ss[2], ss1[2], g[2][5],g1[2][5];
1829 
1830  ss[0] = s + ds;
1831  ss[1] = s - ds;
1832  ss1[0] = s1 + ds1;
1833  ss1[1] = s1 - ds1;
1834 // std::cout << " ss " << ss[0][0] << " " << ss[1][0] << " " << ss1[0][0] << " " << ss1[1][0] << std::endl;
1835  for( Int_t i=0; i<2; i++){
1836  fvec bs = bq*ss[i];
1837  fvec c = cos(bs), sss = sin(bs);
1838 
1839  fvec cB,sB;
1840  const fvec kOvSqr6 = 1./sqrt(6.);
1841  sB = if3( bq_big, (sss/bq), ((One-bs*kOvSqr6)*(One+bs*kOvSqr6)*ss[i]));
1842  cB = if3( bq_big, ((One-c)/bq), (.5*sB*bs));
1843 
1844  g[i][0] = fP[0] + sB*px + cB*py;
1845  g[i][1] = fP[1] - cB*px + sB*py;
1846  g[i][2] = fP[2] + ss[i]*pz;
1847  g[i][3] = + c*px + sss*py;
1848  g[i][4] = - sss*px + c*py;
1849 
1850  bs = bq1*ss1[i];
1851  c = cos(bs); sss = sin(bs);
1852 
1853  sB = if3( bq1_big, (sss/bq1), ((One-bs*kOvSqr6)*(One+bs*kOvSqr6)*ss1[i]));
1854  cB = if3( bq1_big, ((One-c)/bq1), (.5*sB*bs));
1855 
1856  g1[i][0] = p.fP[0] + sB*px1 + cB*py1;
1857  g1[i][1] = p.fP[1] - cB*px1 + sB*py1;
1858  g1[i][2] = p.fP[2] + ss[i]*pz1;
1859  g1[i][3] = + c*px1 + sss*py1;
1860  g1[i][4] = - sss*px1 + c*py1;
1861  }
1862 
1863  DS = ss[0];
1864  DS1 = ss1[0];
1865 
1866  fvec dMin = 1.e10;
1867  for( Int_t j=0; j<2; j++){
1868  for( Int_t j1=0; j1<2; j1++){
1869  fvec xx = g[j][0]-g1[j1][0];
1870  fvec yy = g[j][1]-g1[j1][1];
1871  fvec zz = g[j][2]-g1[j1][2];
1872  fvec d = xx*xx + yy*yy + zz*zz;
1873 
1874  fvec mask = fvec(d<dMin);
1875  DS = (mask & ss[j]) + ((!mask) & DS);
1876  DS1 = (mask & ss1[j]) + ((!mask) & DS1);
1877  dMin = (mask & d) + ((!mask) & dMin);
1878  }
1879  }
1880  #if 0
1881  {
1882  fvec x= g[i][0], y= g[i][1], z= g[i][2], ppx= g[i][3], ppy= g[i][4];
1883  fvec x1=g1[i1][0], y1= g1[i1][1], z1= g1[i1][2], ppx1= g1[i1][3], ppy1= g1[i1][4];
1884  fvec dx = x1-x;
1885  fvec dy = y1-y;
1886  fvec dz = z1-z;
1887  fvec a = ppx*ppx1 + ppy*ppy1 + pz*pz1;
1888  fvec b = dx*ppx1 + dy*ppy1 + dz*pz1;
1889  fvec c = dx*ppx + dy*ppy + dz*pz ;
1890  fvec pp2 = ppx*ppx + ppy*ppy + pz*pz;
1891  fvec pp21= ppx1*ppx1 + ppy1*ppy1 + pz1*pz1;
1892  fvec det = pp2*pp21 - a*a;
1893  if( fabs(det)>1.e-8 ){
1894  DS+=(a*b-pp21*c)/det;
1895  DS1+=(a*c-pp2*b)/det;
1896  }
1897  }
1898  #endif
1899 }
1900 
1902 {
1903  //* Get dS to another particle for Bz field
1904 
1905  fvec px = fP[3];
1906  fvec py = -fP[5];
1907  fvec pz = fP[4];
1908 
1909  fvec px1 = p.fP[3];
1910  fvec py1 = -p.fP[5];
1911  fvec pz1 = p.fP[4];
1912 
1913  const fvec kCLight = 0.000299792458;
1914 
1915  fvec bq = B*fQ*kCLight;
1916  fvec bq1 = B*p.fQ*kCLight;
1917  fvec s=Zero, ds=Zero, s1=Zero, ds1=Zero;
1918 
1919  const fvec LocalSmall = 1.e-8;
1920 
1921  fvec bq_big = fvec(LocalSmall < fabs(bq));
1922  fvec bq1_big = fvec(LocalSmall < fabs(bq1));
1923  {
1924  const fvec two = 2.;
1925  const fvec four = 2.;
1926  fvec dx = (p.fP[0] - fP[0]);
1927  fvec dy = (-p.fP[2] + fP[2]);
1928  fvec d2 = (dx*dx+dy*dy);
1929 
1930  fvec p2 = (px *px + py *py);
1931  fvec p21 = (px1*px1 + py1*py1);
1932 
1933  fvec a = (px*py1 - py*px1);
1934  fvec b = (px*px1 + py*py1);
1935 
1936  fvec ldx = bq*bq1*dx - bq1*py + bq*py1 ;
1937  fvec ldy = bq*bq1*dy + bq1*px - bq*px1 ;
1938  fvec l2 = ldx*ldx + ldy*ldy;
1939 
1940  fvec cS = bq1*p2 + bq*bq1*(dy* px - dx* py) - bq*b;
1941  fvec cS1= bq*p21 - bq*bq1*(dy*px1 - dx*py1) - bq1*b;
1942 
1943  fvec ca = bq*bq*bq1*d2 + two*( cS + bq*bq*(py1*dx-px1*dy)) ;
1944  fvec ca1 = bq*bq1*bq1*d2 + two*( cS1 - bq1*bq1*(py*dx-px*dy)) ;
1945 
1946  fvec sa = 4*l2*p2 - ca*ca;
1947  fvec sa1 = 4*l2*p21 - ca1*ca1;
1948 
1949  const fvec saNeg = fvec(sa<Zero);
1950  sa = (!saNeg) & sa;
1951  const fvec sa1Neg = fvec(sa1<Zero);
1952  sa1= (!sa1Neg) & sa1;
1953 
1954  s = if3( bq_big, (atan2( bq*( bq1*(dx*px +dy*py) + a ) , cS )/bq), (( (dx*px + dy*py) + (py*px1-px*py1)/bq1)/p2) );
1955  ds = if3( bq_big, (atan2(sqrt(sa),ca)/bq) , (s*s - (d2-two*(px1*dy-py1*dx)/bq1)/p2) );
1956  fvec dsNeg = fvec(ds<Zero);
1957  ds = ( fvec((!dsNeg) & (!bq_big)) & sqrt(ds) ) + (bq_big & ds);
1958 
1959  s1 = if3( bq1_big, (atan2( -bq1*( bq*(dx*px1+dy*py1) + a), cS1 )/bq1), ((-(dx*px1 + dy*py1) + (py*px1-px*py1)/bq)/p21) );
1960  ds1 = if3( bq1_big, (atan2(sqrt(sa1),ca1)/bq1) , (s1*s1 - (d2+two*(px*dy-py*dx)/bq)/p21) );
1961  fvec ds1Neg = fvec(ds1<Zero);
1962  ds1 = ( fvec((!ds1Neg) & (!bq1_big)) & sqrt(ds1) ) + (bq1_big & ds1);
1963  }
1964 
1965  fvec ss[2], ss1[2], g[2][5],g1[2][5];
1966 
1967  ss[0] = s + ds;
1968  ss[1] = s - ds;
1969  ss1[0] = s1 + ds1;
1970  ss1[1] = s1 - ds1;
1971 // std::cout << " ss " << ss[0][0] << " " << ss[1][0] << " " << ss1[0][0] << " " << ss1[1][0] << std::endl;
1972  for( Int_t i=0; i<2; i++){
1973  fvec bs = bq*ss[i];
1974  fvec c = cos(bs), sss = sin(bs);
1975 
1976  fvec cB,sB;
1977  const fvec kOvSqr6 = 1./sqrt(6.);
1978  sB = if3( bq_big, (sss/bq), ((One-bs*kOvSqr6)*(One+bs*kOvSqr6)*ss[i]));
1979  cB = if3( bq_big, ((One-c)/bq), (.5*sB*bs));
1980 
1981  g[i][0] = fP[0] + sB*px + cB*py;
1982  g[i][1] = -fP[2] - cB*px + sB*py;
1983  g[i][2] = fP[1] + ss[i]*pz;
1984  g[i][3] = + c*px + sss*py;
1985  g[i][4] = - sss*px + c*py;
1986 
1987  bs = bq1*ss1[i];
1988  c = cos(bs); sss = sin(bs);
1989 
1990  sB = if3( bq1_big, (sss/bq1), ((One-bs*kOvSqr6)*(One+bs*kOvSqr6)*ss1[i]));
1991  cB = if3( bq1_big, ((One-c)/bq1), (.5*sB*bs));
1992 
1993  g1[i][0] = p.fP[0] + sB*px1 + cB*py1;
1994  g1[i][1] = -p.fP[2] - cB*px1 + sB*py1;
1995  g1[i][2] = p.fP[1] + ss[i]*pz1;
1996  g1[i][3] = + c*px1 + sss*py1;
1997  g1[i][4] = - sss*px1 + c*py1;
1998  }
1999 
2000  DS = ss[0];
2001  DS1 = ss1[0];
2002 
2003  fvec dMin = 1.e10;
2004  for( Int_t j=0; j<2; j++){
2005  for( Int_t j1=0; j1<2; j1++){
2006  fvec xx = g[j][0]-g1[j1][0];
2007  fvec yy = g[j][1]-g1[j1][1];
2008  fvec zz = g[j][2]-g1[j1][2];
2009  fvec d = xx*xx + yy*yy + zz*zz;
2010 
2011  fvec mask = fvec(d<dMin);
2012  DS = (mask & ss[j]) + ((!mask) & DS);
2013  DS1 = (mask & ss1[j]) + ((!mask) & DS1);
2014  dMin = (mask & d) + ((!mask) & dMin);
2015  }
2016  }
2017 }
2018 
2020 {
2021  //* Transport the particle on dS, output to P[],C[], for CBM field
2022 
2023  const fvec *r = fP;
2024  fvec p2 = r[3]*r[3] + r[4]*r[4] + r[5]*r[5];
2025  fvec dS = if3(fabs(p2) > fvec(1.E-4), (( r[3]*(xyz[0]-r[0]) + r[4]*(xyz[1]-r[1]) + r[5]*(xyz[2]-r[2]) )/p2), Zero);
2026 
2027 // fvec dS = 0;
2028 //
2029 // if( fQ[0]==0 ){
2030 // dS = GetDStoPointLine( xyz );
2031 // return dS;
2032 // }
2033 //
2034 // fvec fld[3];
2035 // GetFieldValue( fP, fld );
2036 // dS = GetDStoPointBy( fld[1],xyz );
2037 
2038  dS = if3(fabs(dS)>1.E3, Zero, dS);
2039 
2040  return dS;
2041 }
2042 
2044 {
2045  fvec p12 = fP[3]*fP[3] + fP[4]*fP[4] + fP[5]*fP[5];
2046  fvec p22 = p.fP[3]*p.fP[3] + p.fP[4]*p.fP[4] + p.fP[5]*p.fP[5];
2047  fvec p1p2 = fP[3]*p.fP[3] + fP[4]*p.fP[4] + fP[5]*p.fP[5];
2048 
2049  fvec drp1 = fP[3]*(p.fP[0]-fP[0]) + fP[4]*(p.fP[1]-fP[1]) + fP[5]*(p.fP[2]-fP[2]);
2050  fvec drp2 = p.fP[3]*(p.fP[0]-fP[0]) + p.fP[4]*(p.fP[1]-fP[1]) + p.fP[5]*(p.fP[2]-fP[2]);
2051 
2052  fvec detp = p1p2*p1p2 - p12*p22;
2053 
2054  dS = (drp2*p1p2 - drp1*p22) /detp; //TODO put defence against detp = 0
2055  dS1 = (drp2*p12 - drp1*p1p2)/detp;
2056 }
2057 
2059 {
2060  //* Transport the particle on dS, output to P[],C[], for CBM field
2061 
2062  fvec mTy[2];
2063  fvec mY[2];
2064  fvec mZ[2];
2065 
2066  mY[0] = GetY();
2067  mZ[0] = GetZ();
2068  mTy[0] = if3( fabs(GetPz()) > small, GetPy()/GetPz(), 1.);
2069 
2070  mY[1] = p.GetY();
2071  mZ[1] = p.GetZ();
2072  mTy[1] = if3( fabs(p.GetPz()) > small, p.GetPy()/p.GetPz(), 1.);
2073 
2074  fvec r0[3];
2075  fvec dty = mTy[0]-mTy[1];
2076 
2077  r0[2] = if3( fabs(dty) > small, (mTy[0]*mZ[0]-mTy[1]*mZ[1] + mY[1] -mY[0])/dty, 0. );
2078  r0[1] = mY[0] + mTy[0]*(r0[2]-mZ[0]);
2079  r0[0] = GetX() + GetPx()/GetPz()*(r0[2]-mZ[0]);
2080 
2081  dS = GetDStoPointCBM(r0);
2082  dS1 = p.GetDStoPoint(r0);
2083 
2084 // if( fQ[0]==0 ){
2085 // GetDStoParticleLine( p, dS, dS1 );
2086 // return;
2087 // }
2088 //
2089 // fvec fld[3];
2090 // GetFieldValue( fP, fld );
2091 //
2092 // GetDStoParticleBy(fld[1],p,dS,dS1);
2093 }
2094 
2096  fvec P[], fvec C[] ) const
2097 {
2098  //* Transport the particle on dS, output to P[],C[], for CBM field
2099 
2100  if( fQ[0]==0 ){
2101  TransportLine( dS, P, C );
2102  return;
2103  }
2104 
2105  const fvec kCLight = 0.000299792458;
2106 
2107  fvec c = fQ*kCLight;
2108 
2109  // construct coefficients
2110 
2111  fvec
2112  px = fP[3],
2113  py = fP[4],
2114  pz = fP[5];
2115 
2116  fvec sx=0, sy=0, sz=0, syy=0, syz=0, syyy=0, ssx=0, ssy=0, ssz=0, ssyy=0, ssyz=0, ssyyy=0;
2117 
2118  { // get field integrals
2119 
2120  fvec fld[3][3];
2121  fvec p0[3], p1[3], p2[3];
2122 
2123  // line track approximation
2124 
2125  p0[0] = fP[0];
2126  p0[1] = fP[1];
2127  p0[2] = fP[2];
2128 
2129  p2[0] = fP[0] + px*dS;
2130  p2[1] = fP[1] + py*dS;
2131  p2[2] = fP[2] + pz*dS;
2132 
2133  p1[0] = 0.5*(p0[0]+p2[0]);
2134  p1[1] = 0.5*(p0[1]+p2[1]);
2135  p1[2] = 0.5*(p0[2]+p2[2]);
2136 
2137  // first order track approximation
2138  {
2139  GetFieldValue( p0, fld[0] );
2140  GetFieldValue( p1, fld[1] );
2141  GetFieldValue( p2, fld[2] );
2142 
2143  fvec ssy1 = ( 7*fld[0][1] + 6*fld[1][1]-fld[2][1] )*c*dS*dS/96.;
2144  fvec ssy2 = ( fld[0][1] + 2*fld[1][1] )*c*dS*dS/6.;
2145 
2146  p1[0] -= ssy1*pz;
2147  p1[2] += ssy1*px;
2148  p2[0] -= ssy2*pz;
2149  p2[2] += ssy2*px;
2150  }
2151 
2152  GetFieldValue( p0, fld[0] );
2153  GetFieldValue( p1, fld[1] );
2154  GetFieldValue( p2, fld[2] );
2155 
2156  for(int iF1=0; iF1<3; iF1++)
2157  for(int iF2=0; iF2<3; iF2++)
2158  fld[iF1][iF2] = if3( (fabs(fld[iF1][iF2]) > fvec(100.)), Zero, fld[iF1][iF2] );
2159 
2160  sx = c*( fld[0][0] + 4*fld[1][0] + fld[2][0] )*dS/6.;
2161  sy = c*( fld[0][1] + 4*fld[1][1] + fld[2][1] )*dS/6.;
2162  sz = c*( fld[0][2] + 4*fld[1][2] + fld[2][2] )*dS/6.;
2163 
2164  ssx = c*( fld[0][0] + 2*fld[1][0])*dS*dS/6.;
2165  ssy = c*( fld[0][1] + 2*fld[1][1])*dS*dS/6.;
2166  ssz = c*( fld[0][2] + 2*fld[1][2])*dS*dS/6.;
2167 
2168  fvec c2[3][3] = { { 5, -4, -1},{ 44, 80, -4},{ 11, 44, 5} }; // /=360.
2169  fvec cc2[3][3] = { { 38, 8, -4},{ 148, 208, -20},{ 3, 36, 3} }; // /=2520.
2170  for(Int_t n=0; n<3; n++)
2171  for(Int_t m=0; m<3; m++)
2172  {
2173  syz += c2[n][m]*fld[n][1]*fld[m][2];
2174  ssyz += cc2[n][m]*fld[n][1]*fld[m][2];
2175  }
2176 
2177  syz *= c*c*dS*dS/360.;
2178  ssyz *= c*c*dS*dS*dS/2520.;
2179 
2180  syy = c*( fld[0][1] + 4*fld[1][1] + fld[2][1] )*dS;
2181  syyy = syy*syy*syy / 1296;
2182  syy = syy*syy/72;
2183 
2184  ssyy = ( fld[0][1]*( 38*fld[0][1] + 156*fld[1][1] - fld[2][1] )+
2185  fld[1][1]*( 208*fld[1][1] +16*fld[2][1] )+
2186  fld[2][1]*( 3*fld[2][1] )
2187  )*dS*dS*dS*c*c/2520.;
2188  ssyyy =
2189  (
2190  fld[0][1]*( fld[0][1]*( 85*fld[0][1] + 526*fld[1][1] - 7*fld[2][1] )+
2191  fld[1][1]*( 1376*fld[1][1] +84*fld[2][1] )+
2192  fld[2][1]*( 19*fld[2][1] ) )+
2193  fld[1][1]*( fld[1][1]*( 1376*fld[1][1] +256*fld[2][1] )+
2194  fld[2][1]*( 62*fld[2][1] ) )+
2195  fld[2][1]*fld[2][1] *( 3*fld[2][1] )
2196  )*dS*dS*dS*dS*c*c*c/90720.;
2197 
2198  }
2199 
2200  fvec mJ[11];
2201 
2202  mJ[0]=dS-ssyy; mJ[1]=ssx; mJ[2]=ssyyy-ssy;
2203  mJ[3]=-ssz; mJ[4]=dS; mJ[5]=ssx+ssyz;
2204 
2205  mJ[6]=1-syy; mJ[7]=sx; mJ[8]=syyy-sy;
2206  mJ[9]=-sz; mJ[10]=sx+syz;
2207 
2208 
2209 
2210  P[0] = fP[0] + mJ[0]*px + mJ[1]*py + mJ[2]*pz;
2211  P[1] = fP[1] + mJ[3]*px + mJ[4]*py + mJ[5]*pz;
2212  P[2] = fP[2] - mJ[2]*px - mJ[1]*py + mJ[0]*pz;
2213  P[3] = mJ[6]*px + mJ[7]*py + mJ[8]*pz;
2214  P[4] = mJ[9]*px + py + mJ[10]*pz;
2215  P[5] = -mJ[8]*px - mJ[7]*py + mJ[6]*pz;
2216  P[6] = fP[6];
2217  P[7] = fP[7];
2218 
2219  if(C!=fC)
2220  {
2221  for(int iC=0; iC<36; iC++)
2222  C[iC] = fC[iC];
2223  }
2224 
2225  multQSQt1( mJ, C);
2226 
2227 // fvec mJ[8][8];
2228 // for( Int_t i=0; i<8; i++ ) for( Int_t j=0; j<8; j++) mJ[i][j]=0;
2229 //
2230 // mJ[0][0]=1; mJ[0][1]=0; mJ[0][2]=0; mJ[0][3]=dS-ssyy; mJ[0][4]=ssx; mJ[0][5]=ssyyy-ssy;
2231 // mJ[1][0]=0; mJ[1][1]=1; mJ[1][2]=0; mJ[1][3]=-ssz; mJ[1][4]=dS; mJ[1][5]=ssx+ssyz;
2232 // mJ[2][0]=0; mJ[2][1]=0; mJ[2][2]=1; mJ[2][3]=ssy-ssyyy; mJ[2][4]=-ssx; mJ[2][5]=dS-ssyy;
2233 //
2234 // mJ[3][0]=0; mJ[3][1]=0; mJ[3][2]=0; mJ[3][3]=1-syy; mJ[3][4]=sx; mJ[3][5]=syyy-sy;
2235 // mJ[4][0]=0; mJ[4][1]=0; mJ[4][2]=0; mJ[4][3]=-sz; mJ[4][4]=1; mJ[4][5]=sx+syz;
2236 // mJ[5][0]=0; mJ[5][1]=0; mJ[5][2]=0; mJ[5][3]=sy-syyy; mJ[5][4]=-sx; mJ[5][5]=1-syy;
2237 // mJ[6][6] = mJ[7][7] = 1;
2238 //
2239 // P[0] = fP[0] + mJ[0][3]*px + mJ[0][4]*py + mJ[0][5]*pz;
2240 // P[1] = fP[1] + mJ[1][3]*px + mJ[1][4]*py + mJ[1][5]*pz;
2241 // P[2] = fP[2] + mJ[2][3]*px + mJ[2][4]*py + mJ[2][5]*pz;
2242 // P[3] = mJ[3][3]*px + mJ[3][4]*py + mJ[3][5]*pz;
2243 // P[4] = mJ[4][3]*px + mJ[4][4]*py + mJ[4][5]*pz;
2244 // P[5] = mJ[5][3]*px + mJ[5][4]*py + mJ[5][5]*pz;
2245 // P[6] = fP[6];
2246 // P[7] = fP[7];
2247 
2248 // MultQSQt( mJ, fC, C);
2249 
2250 }
2251 
2252 void KFParticleBaseSIMD::multQSQt1( const fvec J[11], fvec S[] )
2253 {
2254  const fvec A00 = S[0 ]+S[6 ]*J[0]+S[10]*J[1]+S[15]*J[2];
2255  const fvec A10 = S[1 ]+S[7 ]*J[0]+S[11]*J[1]+S[16]*J[2];
2256  const fvec A20 = S[3 ]+S[8 ]*J[0]+S[12]*J[1]+S[17]*J[2];
2257  const fvec A30 = S[6 ]+S[9 ]*J[0]+S[13]*J[1]+S[18]*J[2];
2258  const fvec A40 = S[10]+S[13]*J[0]+S[14]*J[1]+S[19]*J[2];
2259  const fvec A50 = S[15]+S[18]*J[0]+S[19]*J[1]+S[20]*J[2];
2260  const fvec A60 = S[21]+S[24]*J[0]+S[25]*J[1]+S[26]*J[2];
2261  const fvec A70 = S[28]+S[31]*J[0]+S[32]*J[1]+S[33]*J[2];
2262 
2263  S[0 ] = A00+J[0]*A30+J[1]*A40+J[2]*A50;
2264  S[1 ] = A10+J[3]*A30+J[4]*A40+J[5]*A50;
2265  S[3 ] = A20-J[2]*A30-J[1]*A40+J[0]*A50;
2266  S[6 ] = J[6]*A30+J[7]*A40+J[8]*A50;
2267  S[10] = J[9]*A30+ A40+J[10]*A50;
2268  S[15] = -J[8]*A30-J[7]*A40+J[6]*A50;
2269  S[21] = A60;
2270  S[28] = A70;
2271 
2272 // const fvec A01 = S[1 ]+S[6 ]*J[3]+S[10]*J[4]+S[15]*J[5];
2273  const fvec A11 = S[2 ]+S[7 ]*J[3]+S[11]*J[4]+S[16]*J[5];
2274  const fvec A21 = S[4 ]+S[8 ]*J[3]+S[12]*J[4]+S[17]*J[5];
2275  const fvec A31 = S[7 ]+S[9 ]*J[3]+S[13]*J[4]+S[18]*J[5];
2276  const fvec A41 = S[11]+S[13]*J[3]+S[14]*J[4]+S[19]*J[5];
2277  const fvec A51 = S[16]+S[18]*J[3]+S[19]*J[4]+S[20]*J[5];
2278  const fvec A61 = S[22]+S[24]*J[3]+S[25]*J[4]+S[26]*J[5];
2279  const fvec A71 = S[29]+S[31]*J[3]+S[32]*J[4]+S[33]*J[5];
2280 
2281  S[2 ] = A11+J[3]*A31+J[4]*A41+J[5]*A51;
2282  S[4 ] = A21-J[2]*A31-J[1]*A41+J[0]*A51;
2283  S[7 ] = J[6]*A31+J[7]*A41+J[8]*A51;
2284  S[11] = J[9]*A31+ A41+J[10]*A51;
2285  S[16] = -J[8]*A31-J[7]*A41+J[6]*A51;
2286  S[22] = A61;
2287  S[29] = A71;
2288 
2289 // const fvec A02 = S[3 ]+S[6 ]*J[2][3]+S[10]*J[2][4]+S[15]*J[2][5];
2290 // const fvec A12 = S[4 ]+S[7 ]*J[2][3]+S[11]*J[2][4]+S[16]*J[2][5];
2291  const fvec A22 = S[5 ]-S[8 ]*J[2]-S[12]*J[1]+S[17]*J[0];
2292  const fvec A32 = S[8 ]-S[9 ]*J[2]-S[13]*J[1]+S[18]*J[0];
2293  const fvec A42 = S[12]-S[13]*J[2]-S[14]*J[1]+S[19]*J[0];
2294  const fvec A52 = S[17]-S[18]*J[2]-S[19]*J[1]+S[20]*J[0];
2295  const fvec A62 = S[23]-S[24]*J[2]-S[25]*J[1]+S[26]*J[0];
2296  const fvec A72 = S[30]-S[31]*J[2]-S[32]*J[1]+S[33]*J[0];
2297 
2298  S[5 ] = A22-J[2]*A32-J[1]*A42+J[0]*A52;
2299  S[8 ] = J[6]*A32+J[7]*A42+J[8]*A52;
2300  S[12] = J[9]*A32+ A42+J[10]*A52;
2301  S[17] = -J[8]*A32-J[7]*A42+J[6]*A52;
2302  S[23] = A62;
2303  S[30] = A72;
2304 
2305 // const fvec A03 = S[6] *J[6]+S[10]*J[7]+S[15]*J[8];
2306 // const fvec A13 = S[7] *J[6]+S[11]*J[7]+S[16]*J[8];
2307 // const fvec A23 = S[8] *J[6]+S[12]*J[7]+S[17]*J[8];
2308  const fvec A33 = S[9] *J[6]+S[13]*J[7]+S[18]*J[8];
2309  const fvec A43 = S[13]*J[6]+S[14]*J[7]+S[19]*J[8];
2310  const fvec A53 = S[18]*J[6]+S[19]*J[7]+S[20]*J[8];
2311  const fvec A63 = S[24]*J[6]+S[25]*J[7]+S[26]*J[8];
2312  const fvec A73 = S[31]*J[6]+S[32]*J[7]+S[33]*J[8];
2313 
2314 // const fvec A04 = S[6] *J[9]+S[10]*J[4][4]+S[15]*J[10];
2315 // const fvec A14 = S[7] *J[9]+S[11]*J[4][4]+S[16]*J[10];
2316 // const fvec A24 = S[8] *J[9]+S[12]*J[4][4]+S[17]*J[10];
2317  const fvec A34 = S[9] *J[9]+S[13]+S[18]*J[10];
2318  const fvec A44 = S[13]*J[9]+S[14]+S[19]*J[10];
2319  const fvec A54 = S[18]*J[9]+S[19]+S[20]*J[10];
2320  const fvec A64 = S[24]*J[9]+S[25]+S[26]*J[10];
2321  const fvec A74 = S[31]*J[9]+S[32]+S[33]*J[10];
2322 
2323 // const fvec A05 = S[6] *J[5][3]+S[10]*J[5][4]+S[15]*J[6];
2324 // const fvec A15 = S[7] *J[5][3]+S[11]*J[5][4]+S[16]*J[6];
2325 // const fvec A25 = S[8] *J[5][3]+S[12]*J[5][4]+S[17]*J[6];
2326  const fvec A35 = -S[9] *J[8]-S[13]*J[7]+S[18]*J[6];
2327  const fvec A45 = -S[13]*J[8]-S[14]*J[7]+S[19]*J[6];
2328  const fvec A55 = -S[18]*J[8]-S[19]*J[7]+S[20]*J[6];
2329  const fvec A65 = -S[24]*J[8]-S[25]*J[7]+S[26]*J[6];
2330  const fvec A75 = -S[31]*J[8]-S[32]*J[7]+S[33]*J[6];
2331 
2332 
2333  S[9 ] = J[6]*A33+J[7]*A43+J[8]*A53;
2334  S[13] = J[9]*A33+ A43+J[10]*A53;
2335  S[18] = -J[8]*A33-J[7]*A43+J[6]*A53;
2336  S[24] = A63;
2337  S[31] = A73;
2338 
2339  S[14] = J[9]*A34+ A44+J[10]*A54;
2340  S[19] = -J[8]*A34-J[7]*A44+J[6]*A54;
2341  S[25] = A64;
2342  S[32] = A74;
2343 
2344  S[20] = -J[8]*A35-J[7]*A45+J[6]*A55;
2345  S[26] = A65;
2346  S[33] = A75;
2347 
2348 //S[27] = S27;
2349 //S[34] = S34;
2350 //S[35] = S35;
2351 }
2352 
2354  fvec p[], fvec e[] ) const
2355 {
2356  //* Transport the particle on dS, output to P[],C[], for Bz field
2357 
2358  const fvec kCLight = 0.000299792458;
2359  b = b*fQ*kCLight;
2360  fvec bs= b*t;
2361  fvec s = sin(bs), c = cos(bs);
2362  fvec sB, cB;
2363 
2364  const fvec kOvSqr6 = 1./sqrt(6.);
2365  const fvec LocalSmall = 1.e-10;
2366 
2367  sB = if3( fvec(LocalSmall < fabs(bs)), (s/b), ((One-bs*kOvSqr6)*(One+bs*kOvSqr6)*t) );
2368  cB = if3( fvec(LocalSmall < fabs(bs)), ((One-c)/b), (.5*sB*bs) );
2369 
2370  fvec px = fP[3];
2371  fvec py = fP[4];
2372  fvec pz = fP[5];
2373 
2374  p[0] = fP[0] + sB*px + cB*py;
2375  p[1] = fP[1] - cB*px + sB*py;
2376  p[2] = fP[2] + t*pz;
2377  p[3] = c*px + s*py;
2378  p[4] = -s*px + c*py;
2379  p[5] = fP[5];
2380  p[6] = fP[6];
2381  p[7] = fP[7];
2382 
2383  /*
2384  fvec mJ[8][8] = { {1,0,0, sB, cB, 0, 0, 0 },
2385  {0,1,0, -cB, sB, 0, 0, 0 },
2386  {0,0,1, 0, 0, t, 0, 0 },
2387  {0,0,0, c, s, 0, 0, 0 },
2388  {0,0,0, -s, c, 0, 0, 0 },
2389  {0,0,0, 0, 0, 1, 0, 0 },
2390  {0,0,0, 0, 0, 0, 1, 0 },
2391  {0,0,0, 0, 0, 0, 0, 1 } };
2392  fvec mA[8][8];
2393  for( Int_t k=0,i=0; i<8; i++)
2394  for( Int_t j=0; j<=i; j++, k++ ) mA[i][j] = mA[j][i] = fC[k];
2395 
2396  fvec mJC[8][8];
2397  for( Int_t i=0; i<8; i++ )
2398  for( Int_t j=0; j<8; j++ ){
2399  mJC[i][j]=0;
2400  for( Int_t k=0; k<8; k++ ) mJC[i][j]+=mJ[i][k]*mA[k][j];
2401  }
2402 
2403  for( Int_t k=0,i=0; i<8; i++)
2404  for( Int_t j=0; j<=i; j++, k++ ){
2405  e[k] = 0;
2406  for( Int_t l=0; l<8; l++ ) e[k]+=mJC[i][l]*mJ[j][l];
2407  }
2408 
2409  return;
2410  */
2411 
2412  fvec
2413  c6=fC[6], c7=fC[7], c8=fC[8], c17=fC[17], c18=fC[18],
2414  c24 = fC[24], c31 = fC[31];
2415 
2416  fvec
2417  cBC13 = cB*fC[13],
2418  mJC13 = c7 - cB*fC[9] + sB*fC[13],
2419  mJC14 = fC[11] - cBC13 + sB*fC[14],
2420  mJC23 = c8 + t*c18,
2421  mJC24 = fC[12] + t*fC[19],
2422  mJC33 = c*fC[9] + s*fC[13],
2423  mJC34 = c*fC[13] + s*fC[14],
2424  mJC43 = -s*fC[9] + c*fC[13],
2425  mJC44 = -s*fC[13] + c*fC[14];
2426 
2427 
2428  e[0]= fC[0] + 2*(sB*c6 + cB*fC[10]) + (sB*fC[9] + 2*cBC13)*sB + cB*cB*fC[14];
2429  e[1]= fC[1] - cB*c6 + sB*fC[10] + mJC13*sB + mJC14*cB;
2430  e[2]= fC[2] - cB*c7 + sB*fC[11] - mJC13*cB + mJC14*sB;
2431  e[3]= fC[3] + t*fC[15] + mJC23*sB + mJC24*cB;
2432  e[4]= fC[4] + t*fC[16] - mJC23*cB + mJC24*sB;
2433 
2434  e[15]= fC[15] + c18*sB + fC[19]*cB;
2435  e[16]= fC[16] - c18*cB + fC[19]*sB;
2436  e[17]= c17 + fC[20]*t;
2437  e[18]= c18*c + fC[19]*s;
2438  e[19]= -c18*s + fC[19]*c;
2439 
2440  e[5]= fC[5] + (c17 + e[17] )*t;
2441 
2442  e[6]= c*c6 + s*fC[10] + mJC33*sB + mJC34*cB;
2443  e[7]= c*c7 + s*fC[11] - mJC33*cB + mJC34*sB;
2444  e[8]= c*c8 + s*fC[12] + e[18]*t;
2445  e[9]= mJC33*c + mJC34*s;
2446  e[10]= -s*c6 + c*fC[10] + mJC43*sB + mJC44*cB;
2447 
2448 
2449  e[11]= -s*c7 + c*fC[11] - mJC43*cB + mJC44*sB;
2450  e[12]= -s*c8 + c*fC[12] + e[19]*t;
2451  e[13]= mJC43*c + mJC44*s;
2452  e[14]= -mJC43*s + mJC44*c;
2453  e[20]= fC[20];
2454  e[21]= fC[21] + fC[25]*cB + c24*sB;
2455  e[22]= fC[22] - c24*cB + fC[25]*sB;
2456  e[23]= fC[23] + fC[26]*t;
2457  e[24]= c*c24 + s*fC[25];
2458  e[25]= c*fC[25] - c24*s;
2459  e[26]= fC[26];
2460  e[27]= fC[27];
2461  e[28]= fC[28] + fC[32]*cB + c31*sB;
2462  e[29]= fC[29] - c31*cB + fC[32]*sB;
2463  e[30]= fC[30] + fC[33]*t;
2464  e[31]= c*c31 + s*fC[32];
2465  e[32]= c*fC[32] - s*c31;
2466  e[33]= fC[33];
2467  e[34]= fC[34];
2468  e[35]= fC[35];
2469 }
2470 
2471 
2473 {
2474  //* Calculate distance from vertex [cm]
2475 
2476  return GetDistanceFromVertex( Vtx.fP );
2477 }
2478 
2480 {
2481  //* Calculate distance from vertex [cm]
2482 
2483  fvec mP[8], mC[36];
2484  Transport( GetDStoPoint(vtx), mP, mC );
2485  fvec d[3]={ vtx[0]-mP[0], vtx[1]-mP[1], vtx[2]-mP[2]};
2486  return sqrt( d[0]*d[0]+d[1]*d[1]+d[2]*d[2] );
2487 }
2488 
2490  const
2491 {
2492  //* Calculate distance to other particle [cm]
2493 
2494  fvec dS, dS1;
2495  GetDStoParticle( p, dS, dS1 );
2496  fvec mP[8], mC[36], mP1[8], mC1[36];
2497  Transport( dS, mP, mC );
2498  p.Transport( dS1, mP1, mC1 );
2499  fvec dx = mP[0]-mP1[0];
2500  fvec dy = mP[1]-mP1[1];
2501  fvec dz = mP[2]-mP1[2];
2502  return sqrt(dx*dx+dy*dy+dz*dz);
2503 }
2504 
2506 {
2507  //* Calculate sqrt(Chi2/ndf) deviation from vertex
2508 
2509  return GetDeviationFromVertex( Vtx.fP, Vtx.fC );
2510 }
2511 
2512 
2514 {
2515  //* Calculate sqrt(Chi2/ndf) deviation from vertex
2516  //* v = [xyz], Cv=[Cxx,Cxy,Cyy,Cxz,Cyz,Czz]-covariance matrix
2517 
2518  fvec mP[8];
2519  fvec mC[36];
2520 
2521 // Transport( GetDStoPoint(v), mP, mC );
2522 
2523 for(int i=0; i<8; i++)
2524 mP[i] = fP[i];
2525 
2526 for(int i=0; i<36; i++)
2527 mC[i] = fC[i];
2528 
2529  fvec d[3]={ v[0]-mP[0], v[1]-mP[1], v[2]-mP[2]};
2530 
2531  fvec sigmaS = .1+10.*sqrt( (d[0]*d[0]+d[1]*d[1]+d[2]*d[2])/
2532  (mP[3]*mP[3]+mP[4]*mP[4]+mP[5]*mP[5]) );
2533 
2534 
2535  fvec h[3] = { mP[3]*sigmaS*0, mP[4]*sigmaS*0, mP[5]*sigmaS*0 };
2536 
2537  fvec mSi[6] =
2538  { mC[0] +h[0]*h[0],
2539  mC[1] +h[1]*h[0], mC[2] +h[1]*h[1],
2540  mC[3] +h[2]*h[0], mC[4] +h[2]*h[1], mC[5] +h[2]*h[2] };
2541 
2542  if( Cv ){
2543  mSi[0]+=Cv[0];
2544  mSi[1]+=Cv[1];
2545  mSi[2]+=Cv[2];
2546  mSi[3]+=Cv[3];
2547  mSi[4]+=Cv[4];
2548  mSi[5]+=Cv[5];
2549  }
2550 
2551 // fvec mS[6];
2552 //
2553 // mS[0] = mSi[2]*mSi[5] - mSi[4]*mSi[4];
2554 // mS[1] = mSi[3]*mSi[4] - mSi[1]*mSi[5];
2555 // mS[2] = mSi[0]*mSi[5] - mSi[3]*mSi[3];
2556 // mS[3] = mSi[1]*mSi[4] - mSi[2]*mSi[3];
2557 // mS[4] = mSi[1]*mSi[3] - mSi[0]*mSi[4];
2558 // mS[5] = mSi[0]*mSi[2] - mSi[1]*mSi[1];
2559 //
2560 // fvec s = ( mSi[0]*mS[0] + mSi[1]*mS[1] + mSi[3]*mS[3] );
2561 // s = if3( fvec( fabs(s) > 1.E-8 ) , One/s , Zero);
2562 //
2563 // return sqrt( fabs(s*( ( mS[0]*d[0] + mS[1]*d[1] + mS[3]*d[2])*d[0]
2564 // +(mS[1]*d[0] + mS[2]*d[1] + mS[4]*d[2])*d[1]
2565 // +(mS[3]*d[0] + mS[4]*d[1] + mS[5]*d[2])*d[2] ))/2);
2566 
2567  InvertCholetsky3(mSi);
2568  return sqrt( ( ( mSi[0]*d[0] + mSi[1]*d[1] + mSi[3]*d[2])*d[0]
2569  +(mSi[1]*d[0] + mSi[2]*d[1] + mSi[4]*d[2])*d[1]
2570  +(mSi[3]*d[0] + mSi[4]*d[1] + mSi[5]*d[2])*d[2] ));
2571 }
2572 
2573 
2575  const
2576 {
2577  //* Calculate sqrt(Chi2/ndf) deviation from other particle
2578 
2579  fvec dS, dS1;
2580  GetDStoParticle( p, dS, dS1 );
2581  fvec mP1[8], mC1[36];
2582  p.Transport( dS1, mP1, mC1 );
2583 
2584  fvec d[3]={ fP[0]-mP1[0], fP[1]-mP1[1], fP[2]-mP1[2]};
2585 
2586  fvec sigmaS = .1+10.*sqrt( (d[0]*d[0]+d[1]*d[1]+d[2]*d[2])/
2587  (mP1[3]*mP1[3]+mP1[4]*mP1[4]+mP1[5]*mP1[5]) );
2588 
2589  fvec h[3] = { mP1[3]*sigmaS, mP1[4]*sigmaS, mP1[5]*sigmaS };
2590 
2591  mC1[0] +=h[0]*h[0];
2592  mC1[1] +=h[1]*h[0];
2593  mC1[2] +=h[1]*h[1];
2594  mC1[3] +=h[2]*h[0];
2595  mC1[4] +=h[2]*h[1];
2596  mC1[5] +=h[2]*h[2];
2597 
2598  return GetDeviationFromVertex( mP1, mC1 )*sqrt(2./1.);
2599 }
2600 
2601 
2602 
2604 {
2605  //* Subtract the particle from the vertex
2606 
2607  fvec m[8];
2608  fvec mCm[36];
2609 
2610  if( Vtx.fIsLinearized ){
2611  GetMeasurement( Vtx.fVtxGuess, m, mCm );
2612  } else {
2613  GetMeasurement( Vtx.fP, m, mCm );
2614  }
2615 
2616  fvec mV[6];
2617 
2618  mV[ 0] = mCm[ 0];
2619  mV[ 1] = mCm[ 1];
2620  mV[ 2] = mCm[ 2];
2621  mV[ 3] = mCm[ 3];
2622  mV[ 4] = mCm[ 4];
2623  mV[ 5] = mCm[ 5];
2624 
2625  //*
2626 
2627  fvec mS[6];
2628  {
2629  fvec mSi[6] = { mV[0]-Vtx.fC[0],
2630  mV[1]-Vtx.fC[1], mV[2]-Vtx.fC[2],
2631  mV[3]-Vtx.fC[3], mV[4]-Vtx.fC[4], mV[5]-Vtx.fC[5] };
2632 
2633  mS[0] = mSi[2]*mSi[5] - mSi[4]*mSi[4];
2634  mS[1] = mSi[3]*mSi[4] - mSi[1]*mSi[5];
2635  mS[2] = mSi[0]*mSi[5] - mSi[3]*mSi[3];
2636  mS[3] = mSi[1]*mSi[4] - mSi[2]*mSi[3];
2637  mS[4] = mSi[1]*mSi[3] - mSi[0]*mSi[4];
2638  mS[5] = mSi[0]*mSi[2] - mSi[1]*mSi[1];
2639 
2640  fvec s = ( mSi[0]*mS[0] + mSi[1]*mS[1] + mSi[3]*mS[3] );
2641  s = if3(fvec( fabs(s) > small ) , One/s, Zero);
2642  mS[0]*=s;
2643  mS[1]*=s;
2644  mS[2]*=s;
2645  mS[3]*=s;
2646  mS[4]*=s;
2647  mS[5]*=s;
2648  }
2649 
2650  //* Residual (measured - estimated)
2651 
2652  fvec zeta[3] = { m[0]-Vtx.fP[0], m[1]-Vtx.fP[1], m[2]-Vtx.fP[2] };
2653 
2654  //* mCHt = mCH' - D'
2655 
2656  fvec mCHt0[3], mCHt1[3], mCHt2[3];
2657 
2658  mCHt0[0]=Vtx.fC[ 0] ; mCHt1[0]=Vtx.fC[ 1] ; mCHt2[0]=Vtx.fC[ 3] ;
2659  mCHt0[1]=Vtx.fC[ 1] ; mCHt1[1]=Vtx.fC[ 2] ; mCHt2[1]=Vtx.fC[ 4] ;
2660  mCHt0[2]=Vtx.fC[ 3] ; mCHt1[2]=Vtx.fC[ 4] ; mCHt2[2]=Vtx.fC[ 5] ;
2661 
2662  //* Kalman gain K = mCH'*S
2663 
2664  fvec k0[3], k1[3], k2[3];
2665 
2666  for(Int_t i=0;i<3;++i){
2667  k0[i] = mCHt0[i]*mS[0] + mCHt1[i]*mS[1] + mCHt2[i]*mS[3];
2668  k1[i] = mCHt0[i]*mS[1] + mCHt1[i]*mS[2] + mCHt2[i]*mS[4];
2669  k2[i] = mCHt0[i]*mS[3] + mCHt1[i]*mS[4] + mCHt2[i]*mS[5];
2670  }
2671 
2672  //* New estimation of the vertex position r += K*zeta
2673 
2674  fvec dChi2 = -(mS[0]*zeta[0] + mS[1]*zeta[1] + mS[3]*zeta[2])*zeta[0]
2675  - (mS[1]*zeta[0] + mS[2]*zeta[1] + mS[4]*zeta[2])*zeta[1]
2676  - (mS[3]*zeta[0] + mS[4]*zeta[1] + mS[5]*zeta[2])*zeta[2];
2677 
2678 // fvec mask = fvec( (Vtx.fChi2 - dChi2) < Zero ); //TODO Check and correct!
2679  fvec mask = fvec(One>Zero); //TODO Check and correct!
2680 
2681  for(Int_t i=0;i<3;++i)
2682  Vtx.fP[i] -= (mask & (k0[i]*zeta[0] + k1[i]*zeta[1] + k2[i]*zeta[2]) );
2683  //* New covariance matrix C -= K*(mCH')'
2684 
2685  for(Int_t i=0, k=0;i<3;++i){
2686  for(Int_t j=0;j<=i;++j,++k)
2687  Vtx.fC[k] += (mask & (k0[i]*mCHt0[j] + k1[i]*mCHt1[j] + k2[i]*mCHt2[j]));
2688  }
2689 
2690  //* Calculate Chi^2
2691 
2692  Vtx.fNDF -= 2; //TODO Check and correct!
2693  Vtx.fChi2 += (mask & dChi2);
2694 }
2695 
2697 {
2698  //* Subtract the particle from the mother particle
2699 
2700  fvec m[8];
2701  fvec mV[36];
2702 
2703  if( Vtx.fIsLinearized ){
2704  GetMeasurement( Vtx.fVtxGuess, m, mV,0 );
2705  } else {
2706  GetMeasurement( Vtx.fP, m, mV );
2707  }
2708 
2709  fvec mS[6]= { mV[0] - Vtx.fC[0],
2710  mV[1] - Vtx.fC[1], mV[2] - Vtx.fC[2],
2711  mV[3] - Vtx.fC[3], mV[4] - Vtx.fC[4], mV[5] - Vtx.fC[5] };
2712  InvertCholetsky3(mS);
2713 
2714  //* Residual (measured - estimated)
2715 
2716  fvec zeta[3] = { m[0]-Vtx.fP[0], m[1]-Vtx.fP[1], m[2]-Vtx.fP[2] };
2717 
2718  //* CHt = CH' - D'
2719 
2720  fvec mCHt0[7], mCHt1[7], mCHt2[7];
2721 
2722  mCHt0[0]=mV[ 0] ; mCHt1[0]=mV[ 1] ; mCHt2[0]=mV[ 3] ;
2723  mCHt0[1]=mV[ 1] ; mCHt1[1]=mV[ 2] ; mCHt2[1]=mV[ 4] ;
2724  mCHt0[2]=mV[ 3] ; mCHt1[2]=mV[ 4] ; mCHt2[2]=mV[ 5] ;
2725  mCHt0[3]=Vtx.fC[ 6]-mV[ 6]; mCHt1[3]=Vtx.fC[ 7]-mV[ 7]; mCHt2[3]=Vtx.fC[ 8]-mV[ 8];
2726  mCHt0[4]=Vtx.fC[10]-mV[10]; mCHt1[4]=Vtx.fC[11]-mV[11]; mCHt2[4]=Vtx.fC[12]-mV[12];
2727  mCHt0[5]=Vtx.fC[15]-mV[15]; mCHt1[5]=Vtx.fC[16]-mV[16]; mCHt2[5]=Vtx.fC[17]-mV[17];
2728  mCHt0[6]=Vtx.fC[21]-mV[21]; mCHt1[6]=Vtx.fC[22]-mV[22]; mCHt2[6]=Vtx.fC[23]-mV[23];
2729 
2730  //* Kalman gain K = mCH'*S
2731 
2732  fvec k0[7], k1[7], k2[7];
2733 
2734  for(Int_t i=0;i<7;++i){
2735  k0[i] = mCHt0[i]*mS[0] + mCHt1[i]*mS[1] + mCHt2[i]*mS[3];
2736  k1[i] = mCHt0[i]*mS[1] + mCHt1[i]*mS[2] + mCHt2[i]*mS[4];
2737  k2[i] = mCHt0[i]*mS[3] + mCHt1[i]*mS[4] + mCHt2[i]*mS[5];
2738  }
2739 
2740  //* Add the daughter momentum to the particle momentum
2741 
2742  Vtx.fP[ 3] -= m[ 3];
2743  Vtx.fP[ 4] -= m[ 4];
2744  Vtx.fP[ 5] -= m[ 5];
2745  Vtx.fP[ 6] -= m[ 6];
2746 
2747  Vtx.fC[ 9] -= mV[ 9];
2748  Vtx.fC[13] -= mV[13];
2749  Vtx.fC[14] -= mV[14];
2750  Vtx.fC[18] -= mV[18];
2751  Vtx.fC[19] -= mV[19];
2752  Vtx.fC[20] -= mV[20];
2753  Vtx.fC[24] -= mV[24];
2754  Vtx.fC[25] -= mV[25];
2755  Vtx.fC[26] -= mV[26];
2756  Vtx.fC[27] -= mV[27];
2757 
2758  //* New estimation of the vertex position r += K*zeta
2759 
2760  for(Int_t i=0;i<3;++i)
2761  Vtx.fP[i] = m[i] - (k0[i]*zeta[0] + k1[i]*zeta[1] + k2[i]*zeta[2]);
2762  for(Int_t i=3;i<7;++i)
2763  Vtx.fP[i] = Vtx.fP[i] - (k0[i]*zeta[0] + k1[i]*zeta[1] + k2[i]*zeta[2]);
2764 
2765  //* New covariance matrix C -= K*(mCH')'
2766 
2767  fvec ffC[28] = { -mV[ 0],
2768  -mV[ 1], -mV[ 2],
2769  -mV[ 3], -mV[ 4], -mV[ 5],
2770  mV[ 6], mV[ 7], mV[ 8], Vtx.fC[ 9],
2771  mV[10], mV[11], mV[12], Vtx.fC[13], Vtx.fC[14],
2772  mV[15], mV[16], mV[17], Vtx.fC[18], Vtx.fC[19], Vtx.fC[20],
2773  mV[21], mV[22], mV[23], Vtx.fC[24], Vtx.fC[25], Vtx.fC[26], Vtx.fC[27] };
2774 
2775  for(Int_t i=0, k=0;i<7;++i){
2776  for(Int_t j=0;j<=i;++j,++k){
2777  Vtx.fC[k] = ffC[k] + (k0[i]*mCHt0[j] + k1[i]*mCHt1[j] + k2[i]*mCHt2[j] );
2778  }
2779  }
2780 
2781  //* Calculate Chi^2
2782  Vtx.fNDF -= 2;
2783  Vtx.fQ -= GetQ();
2784  Vtx.fSFromDecay = 0;
2785  Vtx.fChi2 -= ((mS[0]*zeta[0] + mS[1]*zeta[1] + mS[3]*zeta[2])*zeta[0]
2786  +(mS[1]*zeta[0] + mS[2]*zeta[1] + mS[4]*zeta[2])*zeta[1]
2787  +(mS[3]*zeta[0] + mS[4]*zeta[1] + mS[5]*zeta[2])*zeta[2]);
2788 }
2789 
2791  fvec P[], fvec C[] ) const
2792 {
2793  //* Transport the particle as a straight line
2794 
2795  P[0] = fP[0] + dS*fP[3];
2796  P[1] = fP[1] + dS*fP[4];
2797  P[2] = fP[2] + dS*fP[5];
2798  P[3] = fP[3];
2799  P[4] = fP[4];
2800  P[5] = fP[5];
2801  P[6] = fP[6];
2802  P[7] = fP[7];
2803 
2804  fvec c6 = fC[ 6] + dS*fC[ 9];
2805  fvec c11 = fC[11] + dS*fC[14];
2806  fvec c17 = fC[17] + dS*fC[20];
2807  fvec sc13 = dS*fC[13];
2808  fvec sc18 = dS*fC[18];
2809  fvec sc19 = dS*fC[19];
2810 
2811  C[ 0] = fC[ 0] + dS*( fC[ 6] + c6 );
2812  C[ 2] = fC[ 2] + dS*( fC[11] + c11 );
2813  C[ 5] = fC[ 5] + dS*( fC[17] + c17 );
2814 
2815  C[ 7] = fC[ 7] + sc13;
2816  C[ 8] = fC[ 8] + sc18;
2817  C[ 9] = fC[ 9];
2818 
2819  C[12] = fC[12] + sc19;
2820 
2821  C[ 1] = fC[ 1] + dS*( fC[10] + C[ 7] );
2822  C[ 3] = fC[ 3] + dS*( fC[15] + C[ 8] );
2823  C[ 4] = fC[ 4] + dS*( fC[16] + C[12] );
2824  C[ 6] = c6;
2825 
2826  C[10] = fC[10] + sc13;
2827  C[11] = c11;
2828 
2829  C[13] = fC[13];
2830  C[14] = fC[14];
2831  C[15] = fC[15] + sc18;
2832  C[16] = fC[16] + sc19;
2833  C[17] = c17;
2834 
2835  C[18] = fC[18];
2836  C[19] = fC[19];
2837  C[20] = fC[20];
2838  C[21] = fC[21] + dS*fC[24];
2839  C[22] = fC[22] + dS*fC[25];
2840  C[23] = fC[23] + dS*fC[26];
2841 
2842  C[24] = fC[24];
2843  C[25] = fC[25];
2844  C[26] = fC[26];
2845  C[27] = fC[27];
2846  C[28] = fC[28] + dS*fC[31];
2847  C[29] = fC[29] + dS*fC[32];
2848  C[30] = fC[30] + dS*fC[33];
2849 
2850  C[31] = fC[31];
2851  C[32] = fC[32];
2852  C[33] = fC[33];
2853  C[34] = fC[34];
2854  C[35] = fC[35];
2855 }
2856 
2858  const KFParticleBaseSIMD &daughter2, fvec Bz )
2859 {
2860  //* Create gamma
2861 
2862  const KFParticleBaseSIMD *daughters[2] = { &daughter1, &daughter2};
2863 
2864  fvec v0[3];
2865 
2866  if( !fIsLinearized ){
2867  fvec ds, ds1;
2868  fvec m[8];
2869  fvec mCd[36];
2870  daughter1.GetDStoParticle(daughter2, ds, ds1);
2871  daughter1.Transport( ds, m, mCd );
2872  fP[0] = m[0];
2873  fP[1] = m[1];
2874  fP[2] = m[2];
2875  daughter2.Transport( ds1, m, mCd );
2876  fP[0] = .5*( fP[0] + m[0] );
2877  fP[1] = .5*( fP[1] + m[1] );
2878  fP[2] = .5*( fP[2] + m[2] );
2879  } else {
2880  fP[0] = fVtxGuess[0];
2881  fP[1] = fVtxGuess[1];
2882  fP[2] = fVtxGuess[2];
2883  }
2884 
2885  fvec daughterP[2][8], daughterC[2][36];
2886  fvec vtxMom[2][3];
2887 
2888  int nIter = fIsLinearized ?1 :2;
2889 
2890  for( int iter=0; iter<nIter; iter++){
2891 
2892  v0[0] = fP[0];
2893  v0[1] = fP[1];
2894  v0[2] = fP[2];
2895 
2896  fAtProductionVertex = 0;
2897  fSFromDecay = 0;
2898  fP[0] = v0[0];
2899  fP[1] = v0[1];
2900  fP[2] = v0[2];
2901  fP[3] = 0;
2902  fP[4] = 0;
2903  fP[5] = 0;
2904  fP[6] = 0;
2905  fP[7] = 0;
2906 
2907 
2908  // fit daughters to the vertex guess
2909 
2910  {
2911  for( int id=0; id<2; id++ ){
2912 
2913  fvec *p = daughterP[id];
2914  fvec *mC = daughterC[id];
2915 
2916  daughters[id]->GetMeasurement( v0, p, mC );
2917 
2918  fvec mAi[6];
2919  InvertSym3(mC, mAi );
2920 
2921  fvec mB[3][3];
2922 
2923  mB[0][0] = mC[ 6]*mAi[0] + mC[ 7]*mAi[1] + mC[ 8]*mAi[3];
2924  mB[0][1] = mC[ 6]*mAi[1] + mC[ 7]*mAi[2] + mC[ 8]*mAi[4];
2925  mB[0][2] = mC[ 6]*mAi[3] + mC[ 7]*mAi[4] + mC[ 8]*mAi[5];
2926 
2927  mB[1][0] = mC[10]*mAi[0] + mC[11]*mAi[1] + mC[12]*mAi[3];
2928  mB[1][1] = mC[10]*mAi[1] + mC[11]*mAi[2] + mC[12]*mAi[4];
2929  mB[1][2] = mC[10]*mAi[3] + mC[11]*mAi[4] + mC[12]*mAi[5];
2930 
2931  mB[2][0] = mC[15]*mAi[0] + mC[16]*mAi[1] + mC[17]*mAi[3];
2932  mB[2][1] = mC[15]*mAi[1] + mC[16]*mAi[2] + mC[17]*mAi[4];
2933  mB[2][2] = mC[15]*mAi[3] + mC[16]*mAi[4] + mC[17]*mAi[5];
2934 
2935  fvec z[3] = { v0[0]-p[0], v0[1]-p[1], v0[2]-p[2] };
2936 
2937  vtxMom[id][0] = p[3] + mB[0][0]*z[0] + mB[0][1]*z[1] + mB[0][2]*z[2];
2938  vtxMom[id][1] = p[4] + mB[1][0]*z[0] + mB[1][1]*z[1] + mB[1][2]*z[2];
2939  vtxMom[id][2] = p[5] + mB[2][0]*z[0] + mB[2][1]*z[1] + mB[2][2]*z[2];
2940 
2941  daughters[id]->Transport( daughters[id]->GetDStoPoint(v0), p, mC );
2942 
2943  }
2944 
2945  } // fit daughters to guess
2946 
2947 
2948  // fit new vertex
2949  {
2950 
2951  fvec mpx0 = vtxMom[0][0]+vtxMom[1][0];
2952  fvec mpy0 = vtxMom[0][1]+vtxMom[1][1];
2953  fvec mpt0 = sqrt(mpx0*mpx0 + mpy0*mpy0);
2954  // fvec a0 = TMath::ATan2(mpy0,mpx0);
2955 
2956  fvec ca0 = mpx0/mpt0;
2957  fvec sa0 = mpy0/mpt0;
2958  fvec r[3] = { v0[0], v0[1], v0[2] };
2959  fvec mC[3][3] = {{1000., 0 , 0 },
2960  {0, 1000., 0 },
2961  {0, 0, 1000. } };
2962  fvec chi2=0;
2963 
2964  for( int id=0; id<2; id++ ){
2965  const fvec kCLight = 0.000299792458;
2966  fvec q = Bz*daughters[id]->GetQ()*kCLight;
2967  fvec px0 = vtxMom[id][0];
2968  fvec py0 = vtxMom[id][1];
2969  fvec pz0 = vtxMom[id][2];
2970  fvec pt0 = sqrt(px0*px0+py0*py0);
2971  fvec mG[3][6], mB[3], mH[3][3];
2972  // r = {vx,vy,vz};
2973  // m = {x,y,z,Px,Py,Pz};
2974  // V = daughter.C
2975  // G*m + B = H*r;
2976  // q*x + Py - q*vx - sin(a)*Pt = 0
2977  // q*y - Px - q*vy + cos(a)*Pt = 0
2978  // (Px*cos(a) + Py*sin(a) ) (vz -z) - Pz( cos(a)*(vx-x) + sin(a)*(vy-y)) = 0
2979 
2980  mG[0][0] = q;
2981  mG[0][1] = 0;
2982  mG[0][2] = 0;
2983  mG[0][3] = -sa0*px0/pt0;
2984  mG[0][4] = 1 -sa0*py0/pt0;
2985  mG[0][5] = 0;
2986  mH[0][0] = q;
2987  mH[0][1] = 0;
2988  mH[0][2] = 0;
2989  mB[0] = py0 - sa0*pt0 - mG[0][3]*px0 - mG[0][4]*py0 ;
2990 
2991  // q*y - Px - q*vy + cos(a)*Pt = 0
2992 
2993  mG[1][0] = 0;
2994  mG[1][1] = q;
2995  mG[1][2] = 0;
2996  mG[1][3] = -1 + ca0*px0/pt0;
2997  mG[1][4] = + ca0*py0/pt0;
2998  mG[1][5] = 0;
2999  mH[1][0] = 0;
3000  mH[1][1] = q;
3001  mH[1][2] = 0;
3002  mB[1] = -px0 + ca0*pt0 - mG[1][3]*px0 - mG[1][4]*py0 ;
3003 
3004  // (Px*cos(a) + Py*sin(a) ) (z -vz) - Pz( cos(a)*(x-vx) + sin(a)*(y-vy)) = 0
3005 
3006  mG[2][0] = -pz0*ca0;
3007  mG[2][1] = -pz0*sa0;
3008  mG[2][2] = px0*ca0 + py0*sa0;
3009  mG[2][3] = 0;
3010  mG[2][4] = 0;
3011  mG[2][5] = 0;
3012 
3013  mH[2][0] = mG[2][0];
3014  mH[2][1] = mG[2][1];
3015  mH[2][2] = mG[2][2];
3016 
3017  mB[2] = 0;
3018 
3019  // fit the vertex
3020 
3021  // V = GVGt
3022 
3023  fvec mGV[3][6];
3024  fvec mV[6];
3025  fvec m[3];
3026  for( int i=0; i<3; i++ ){
3027  m[i] = mB[i];
3028  for( int k=0; k<6; k++ ) m[i]+=mG[i][k]*daughterP[id][k];
3029  }
3030  for( int i=0; i<3; i++ ){
3031  for( int j=0; j<6; j++ ){
3032  mGV[i][j] = 0;
3033  for( int k=0; k<6; k++ ) mGV[i][j]+=mG[i][k]*daughterC[id][ IJ(k,j) ];
3034  }
3035  }
3036  for( int i=0, k=0; i<3; i++ ){
3037  for( int j=0; j<=i; j++,k++ ){
3038  mV[k] = 0;
3039  for( int l=0; l<6; l++ ) mV[k]+=mGV[i][l]*mG[j][l];
3040  }
3041  }
3042 
3043 
3044  //* CHt
3045 
3046  fvec mCHt[3][3];
3047  fvec mHCHt[6];
3048  fvec mHr[3];
3049  for( int i=0; i<3; i++ ){
3050  mHr[i] = 0;
3051  for( int k=0; k<3; k++ ) mHr[i]+= mH[i][k]*r[k];
3052  }
3053 
3054  for( int i=0; i<3; i++ ){
3055  for( int j=0; j<3; j++){
3056  mCHt[i][j] = 0;
3057  for( int k=0; k<3; k++ ) mCHt[i][j]+= mC[i][k]*mH[j][k];
3058  }
3059  }
3060 
3061  for( int i=0, k=0; i<3; i++ ){
3062  for( int j=0; j<=i; j++, k++ ){
3063  mHCHt[k] = 0;
3064  for( int l=0; l<3; l++ ) mHCHt[k]+= mH[i][l]*mCHt[l][j];
3065  }
3066  }
3067 
3068  fvec mS[6] = { mHCHt[0]+mV[0],
3069  mHCHt[1]+mV[1], mHCHt[2]+mV[2],
3070  mHCHt[3]+mV[3], mHCHt[4]+mV[4], mHCHt[5]+mV[5] };
3071 
3072 
3073  InvertSym3(mS,mS);
3074 
3075  //* Residual (measured - estimated)
3076 
3077  fvec zeta[3] = { m[0]-mHr[0], m[1]-mHr[1], m[2]-mHr[2] };
3078 
3079  //* Kalman gain K = mCH'*S
3080 
3081  fvec k[3][3];
3082 
3083  for(Int_t i=0;i<3;++i){
3084  k[i][0] = mCHt[i][0]*mS[0] + mCHt[i][1]*mS[1] + mCHt[i][2]*mS[3];
3085  k[i][1] = mCHt[i][0]*mS[1] + mCHt[i][1]*mS[2] + mCHt[i][2]*mS[4];
3086  k[i][2] = mCHt[i][0]*mS[3] + mCHt[i][1]*mS[4] + mCHt[i][2]*mS[5];
3087  }
3088 
3089  //* New estimation of the vertex position r += K*zeta
3090 
3091  for(Int_t i=0;i<3;++i)
3092  r[i] = r[i] + k[i][0]*zeta[0] + k[i][1]*zeta[1] + k[i][2]*zeta[2];
3093 
3094  //* New covariance matrix C -= K*(mCH')'
3095 
3096  for(Int_t i=0;i<3;++i){
3097  for(Int_t j=0;j<=i;++j){
3098  mC[i][j] = mC[i][j] - (k[i][0]*mCHt[j][0] + k[i][1]*mCHt[j][1] + k[i][2]*mCHt[j][2]);
3099  mC[j][i] = mC[i][j];
3100  }
3101  }
3102 
3103  //* Calculate Chi^2
3104 
3105  chi2 += ( ( mS[0]*zeta[0] + mS[1]*zeta[1] + mS[3]*zeta[2] )*zeta[0]
3106  +(mS[1]*zeta[0] + mS[2]*zeta[1] + mS[4]*zeta[2] )*zeta[1]
3107  +(mS[3]*zeta[0] + mS[4]*zeta[1] + mS[5]*zeta[2] )*zeta[2] );
3108  }
3109 
3110  // store vertex
3111 
3112  fNDF = 2;
3113  fChi2 = chi2;
3114  for( int i=0; i<3; i++ ) fP[i] = r[i];
3115  for( int i=0,k=0; i<3; i++ ){
3116  for( int j=0; j<=i; j++,k++ ){
3117  fC[k] = mC[i][j];
3118  }
3119  }
3120  }
3121 
3122  } // iterations
3123 
3124  // now fit daughters to the vertex
3125 
3126  fQ = 0;
3127  fSFromDecay = 0;
3128 
3129  for(Int_t i=3;i<8;++i) fP[i]=0.;
3130  for(Int_t i=6;i<35;++i) fC[i]=0.;
3131  fC[35] = 100.;
3132 
3133  for( int id=0; id<2; id++ ){
3134 
3135  fvec *p = daughterP[id];
3136  fvec *mC = daughterC[id];
3137  daughters[id]->GetMeasurement( v0, p, mC );
3138 
3139  const fvec *m = fP, *mV = fC;
3140 
3141  fvec mAi[6];
3142  InvertSym3(mC, mAi );
3143 
3144  fvec mB[4][3];
3145 
3146  mB[0][0] = mC[ 6]*mAi[0] + mC[ 7]*mAi[1] + mC[ 8]*mAi[3];
3147  mB[0][1] = mC[ 6]*mAi[1] + mC[ 7]*mAi[2] + mC[ 8]*mAi[4];
3148  mB[0][2] = mC[ 6]*mAi[3] + mC[ 7]*mAi[4] + mC[ 8]*mAi[5];
3149 
3150  mB[1][0] = mC[10]*mAi[0] + mC[11]*mAi[1] + mC[12]*mAi[3];
3151  mB[1][1] = mC[10]*mAi[1] + mC[11]*mAi[2] + mC[12]*mAi[4];
3152  mB[1][2] = mC[10]*mAi[3] + mC[11]*mAi[4] + mC[12]*mAi[5];
3153 
3154  mB[2][0] = mC[15]*mAi[0] + mC[16]*mAi[1] + mC[17]*mAi[3];
3155  mB[2][1] = mC[15]*mAi[1] + mC[16]*mAi[2] + mC[17]*mAi[4];
3156  mB[2][2] = mC[15]*mAi[3] + mC[16]*mAi[4] + mC[17]*mAi[5];
3157 
3158  mB[3][0] = mC[21]*mAi[0] + mC[22]*mAi[1] + mC[23]*mAi[3];
3159  mB[3][1] = mC[21]*mAi[1] + mC[22]*mAi[2] + mC[23]*mAi[4];
3160  mB[3][2] = mC[21]*mAi[3] + mC[22]*mAi[4] + mC[23]*mAi[5];
3161 
3162 
3163  fvec z[3] = { m[0]-p[0], m[1]-p[1], m[2]-p[2] };
3164 
3165 // {
3166 // fvec mAV[6] = { mC[0]-mV[0], mC[1]-mV[1], mC[2]-mV[2],
3167 // mC[3]-mV[3], mC[4]-mV[4], mC[5]-mV[5] };
3168 //
3169 // fvec mAVi[6];
3170 // if( !InvertSym3(mAV, mAVi) ){
3171 // fvec dChi2 = ( +(mAVi[0]*z[0] + mAVi[1]*z[1] + mAVi[3]*z[2])*z[0]
3172 // +(mAVi[1]*z[0] + mAVi[2]*z[1] + mAVi[4]*z[2])*z[1]
3173 // +(mAVi[3]*z[0] + mAVi[4]*z[1] + mAVi[5]*z[2])*z[2] );
3174 // fChi2+= TMath::Abs( dChi2 );
3175 // }
3176 // fNDF += 2;
3177 // }
3178 
3179  //* Add the daughter momentum to the particle momentum
3180 
3181  fP[3]+= p[3] + mB[0][0]*z[0] + mB[0][1]*z[1] + mB[0][2]*z[2];
3182  fP[4]+= p[4] + mB[1][0]*z[0] + mB[1][1]*z[1] + mB[1][2]*z[2];
3183  fP[5]+= p[5] + mB[2][0]*z[0] + mB[2][1]*z[1] + mB[2][2]*z[2];
3184  fP[6]+= p[6] + mB[3][0]*z[0] + mB[3][1]*z[1] + mB[3][2]*z[2];
3185 
3186  fvec d0, d1, d2;
3187 
3188  d0= mB[0][0]*mV[0] + mB[0][1]*mV[1] + mB[0][2]*mV[3] - mC[ 6];
3189  d1= mB[0][0]*mV[1] + mB[0][1]*mV[2] + mB[0][2]*mV[4] - mC[ 7];
3190  d2= mB[0][0]*mV[3] + mB[0][1]*mV[4] + mB[0][2]*mV[5] - mC[ 8];
3191 
3192  //fC[6]+= mC[ 6] + d0;
3193  //fC[7]+= mC[ 7] + d1;
3194  //fC[8]+= mC[ 8] + d2;
3195  fC[9]+= mC[ 9] + d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
3196 
3197  d0= mB[1][0]*mV[0] + mB[1][1]*mV[1] + mB[1][2]*mV[3] - mC[10];
3198  d1= mB[1][0]*mV[1] + mB[1][1]*mV[2] + mB[1][2]*mV[4] - mC[11];
3199  d2= mB[1][0]*mV[3] + mB[1][1]*mV[4] + mB[1][2]*mV[5] - mC[12];
3200 
3201  //fC[10]+= mC[10]+ d0;
3202  //fC[11]+= mC[11]+ d1;
3203  //fC[12]+= mC[12]+ d2;
3204  fC[13]+= mC[13]+ d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
3205  fC[14]+= mC[14]+ d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
3206 
3207  d0= mB[2][0]*mV[0] + mB[2][1]*mV[1] + mB[2][2]*mV[3] - mC[15];
3208  d1= mB[2][0]*mV[1] + mB[2][1]*mV[2] + mB[2][2]*mV[4] - mC[16];
3209  d2= mB[2][0]*mV[3] + mB[2][1]*mV[4] + mB[2][2]*mV[5] - mC[17];
3210 
3211  //fC[15]+= mC[15]+ d0;
3212  //fC[16]+= mC[16]+ d1;
3213  //fC[17]+= mC[17]+ d2;
3214  fC[18]+= mC[18]+ d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
3215  fC[19]+= mC[19]+ d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
3216  fC[20]+= mC[20]+ d0*mB[2][0] + d1*mB[2][1] + d2*mB[2][2];
3217 
3218  d0= mB[3][0]*mV[0] + mB[3][1]*mV[1] + mB[3][2]*mV[3] - mC[21];
3219  d1= mB[3][0]*mV[1] + mB[3][1]*mV[2] + mB[3][2]*mV[4] - mC[22];
3220  d2= mB[3][0]*mV[3] + mB[3][1]*mV[4] + mB[3][2]*mV[5] - mC[23];
3221 
3222  //fC[21]+= mC[21] + d0;
3223  //fC[22]+= mC[22] + d1;
3224  //fC[23]+= mC[23] + d2;
3225  fC[24]+= mC[24] + d0*mB[0][0] + d1*mB[0][1] + d2*mB[0][2];
3226  fC[25]+= mC[25] + d0*mB[1][0] + d1*mB[1][1] + d2*mB[1][2];
3227  fC[26]+= mC[26] + d0*mB[2][0] + d1*mB[2][1] + d2*mB[2][2];
3228  fC[27]+= mC[27] + d0*mB[3][0] + d1*mB[3][1] + d2*mB[3][2];
3229  }
3230 
3231 // SetMassConstraint(0,0);
3233 }
3234 
3236 {
3237 // example:
3238 // KFParticle PosParticle(...)
3239 // KFParticle NegParticle(...)
3240 // Gamma.ConstructGamma(PosParticle, NegParticle);
3241 // fvec VertexGamma[3] = {Gamma.GetX(), Gamma.GetY(), Gamma.GetZ()};
3242 // PosParticle.TransportToPoint(VertexGamma);
3243 // NegParticle.TransportToPoint(VertexGamma);
3244 // fvec armenterosQtAlfa[2] = {0.};
3245 // KFParticle::GetArmenterosPodolanski(PosParticle, NegParticle, armenterosQtAlfa );
3246 
3247  fvec alpha = 0., qt = 0.;
3248  fvec spx = positive.GetPx() + negative.GetPx();
3249  fvec spy = positive.GetPy() + negative.GetPy();
3250  fvec spz = positive.GetPz() + negative.GetPz();
3251  fvec sp = sqrt(spx*spx + spy*spy + spz*spz);
3252  fvec mask = fvec( fabs(sp) < fvec(1.E-10));
3253  fvec pn, pp, pln, plp;
3254 
3255  pn = sqrt(negative.GetPx()*negative.GetPx() + negative.GetPy()*negative.GetPy() + negative.GetPz()*negative.GetPz());
3256  pp = sqrt(positive.GetPx()*positive.GetPx() + positive.GetPy()*positive.GetPy() + positive.GetPz()*positive.GetPz());
3257  pln = (negative.GetPx()*spx+negative.GetPy()*spy+negative.GetPz()*spz)/sp;
3258  plp = (positive.GetPx()*spx+positive.GetPy()*spy+positive.GetPz()*spz)/sp;
3259 
3260  mask = fvec(mask & fvec( fabs(pn) < fvec(1.E-10)));
3261  fvec ptm = (1.-((pln/pn)*(pln/pn)));
3262  qt= if3( fvec(ptm >= Zero) , pn*sqrt(ptm) , Zero );
3263  alpha = (plp-pln)/(plp+pln);
3264 
3265  QtAlfa[0] = fvec(qt & mask);
3266  QtAlfa[1] = fvec(alpha & mask);
3267 }
3268 
3270 {
3271  // Rotates the KFParticle object around OZ axis, OZ axis is set by the vertex position
3272  // fvec angle - angle of rotation in XY plane in [rad]
3273  // fvec Vtx[3] - position of the vertex in [cm]
3274 
3275  // Before rotation the center of the coordinat system should be moved to the vertex position; move back after rotation
3276  X() = X() - Vtx[0];
3277  Y() = Y() - Vtx[1];
3278  Z() = Z() - Vtx[2];
3279 
3280  // Rotate the kf particle
3281  fvec c = cos(angle);
3282  fvec s = sin(angle);
3283 
3284  fvec mA[8][ 8];
3285  for( Int_t i=0; i<8; i++ ){
3286  for( Int_t j=0; j<8; j++){
3287  mA[i][j] = 0;
3288  }
3289  }
3290  for( int i=0; i<8; i++ ){
3291  mA[i][i] = 1;
3292  }
3293  mA[0][0] = c; mA[0][1] = s;
3294  mA[1][0] = -s; mA[1][1] = c;
3295  mA[3][3] = c; mA[3][4] = s;
3296  mA[4][3] = -s; mA[4][4] = c;
3297 
3298  fvec mAC[8][8];
3299  fvec mAp[8];
3300 
3301  for( Int_t i=0; i<8; i++ ){
3302  mAp[i] = 0;
3303  for( Int_t k=0; k<8; k++){
3304  mAp[i]+=mA[i][k] * fP[k];
3305  }
3306  }
3307 
3308  for( Int_t i=0; i<8; i++){
3309  fP[i] = mAp[i];
3310  }
3311 
3312  for( Int_t i=0; i<8; i++ ){
3313  for( Int_t j=0; j<8; j++ ){
3314  mAC[i][j] = 0;
3315  for( Int_t k=0; k<8; k++ ){
3316  mAC[i][j]+= mA[i][k] * GetCovariance(k,j);
3317  }
3318  }
3319  }
3320 
3321  for( Int_t i=0; i<8; i++ ){
3322  for( Int_t j=0; j<=i; j++ ){
3323  fvec xx = 0;
3324  for( Int_t k=0; k<8; k++){
3325  xx+= mAC[i][k]*mA[j][k];
3326  }
3327  Covariance(i,j) = xx;
3328  }
3329  }
3330 
3331  X() = GetX() + Vtx[0];
3332  Y() = GetY() + Vtx[1];
3333  Z() = GetZ() + Vtx[2];
3334 }
3335 
3337 {
3338  //* Invert symmetric matric stored in low-triagonal form
3339 
3340  fvec ret = 0;
3341  fvec a0 = A[0], a1 = A[1], a2 = A[2], a3 = A[3];
3342 
3343  Ai[0] = a2*A[5] - A[4]*A[4];
3344  Ai[1] = a3*A[4] - a1*A[5];
3345  Ai[3] = a1*A[4] - a2*a3;
3346  fvec det = (a0*Ai[0] + a1*Ai[1] + a3*Ai[3]);
3347 
3348  fvec idet = 1. / det;
3349  fvec init = fvec(small < fabs(det));
3350  det = init & idet;
3351  ret += (!init);
3352 
3353  Ai[0] *= det;
3354  Ai[1] *= det;
3355  Ai[3] *= det;
3356  Ai[2] = ( a0*A[5] - a3*a3 )*det;
3357  Ai[4] = ( a1*a3 - a0*A[4] )*det;
3358  Ai[5] = ( a0*a2 - a1*a1 )*det;
3359  return ret;
3360 }
3361 
3363 {
3364 //a[3] = a[3]/10;
3365 //a[4] = a[4]/10;
3366 //a[5] = a[5]/10;
3367 // fvec ai[6] = {a[0], a[1], a[2], a[3], a[4], a[5]};
3368 
3369  fvec d[3], uud, u[3][3];
3370  for(int i=0; i<3; i++)
3371  {
3372  d[i]=Zero;
3373  for(int j=0; j<3; j++)
3374  u[i][j]=Zero;
3375  }
3376 
3377  for(int i=0; i<3 ; i++)
3378  {
3379  uud=Zero;
3380  for(int j=0; j<i; j++)
3381  uud += u[j][i]*u[j][i]*d[j];
3382  uud = a[i*(i+3)/2] - uud;
3383 
3384  fvec smallval = 1.e-12f;
3385  fvec initialised = fvec( fabs(uud)<smallval );
3386  uud = ((!initialised) & uud) + (smallval & initialised);
3387 
3388  d[i] = uud/fabs(uud);
3389  u[i][i] = sqrt(fabs(uud));
3390 
3391  for(int j=i+1; j<3; j++)
3392  {
3393  uud = Zero;
3394  for(int k=0; k<i; k++)
3395  uud += u[k][i]*u[k][j]*d[k];
3396  uud = a[j*(j+1)/2+i] - uud;
3397  u[i][j] = d[i]/u[i][i]*uud;
3398  }
3399  }
3400 
3401  fvec u1[3];
3402 
3403  for(int i=0; i<3; i++)
3404  {
3405  u1[i] = u[i][i];
3406  u[i][i] = One/u[i][i];
3407  }
3408  for(int i=0; i<2; i++)
3409  {
3410  u[i][i+1] = - u[i][i+1]*u[i][i]*u[i+1][i+1];
3411  }
3412  for(int i=0; i<1; i++)
3413  {
3414  u[i][i+2] = u[i][i+1]*u1[i+1]*u[i+1][i+2]-u[i][i+2]*u[i][i]*u[i+2][i+2];
3415  }
3416 
3417  for(int i=0; i<3; i++)
3418  a[i+3] = u[i][2]*u[2][2]*d[2];
3419  for(int i=0; i<2; i++)
3420  a[i+1] = u[i][1]*u[1][1]*d[1] + u[i][2]*u[1][2]*d[2];
3421  a[0] = u[0][0]*u[0][0]*d[0] + u[0][1]*u[0][1]*d[1] + u[0][2]*u[0][2]*d[2];
3422 
3423 // fvec mI[9];
3424 // mI[0] = a[0]*ai[0] + a[1]*ai[1] + a[3]*ai[3];
3425 // mI[1] = a[0]*ai[1] + a[1]*ai[2] + a[3]*ai[4];
3426 // mI[2] = a[0]*ai[3] + a[1]*ai[4] + a[3]*ai[5];
3427 //
3428 // mI[3] = a[1]*ai[0] + a[2]*ai[1] + a[4]*ai[3];
3429 // mI[4] = a[1]*ai[1] + a[2]*ai[2] + a[4]*ai[4];
3430 // mI[5] = a[1]*ai[3] + a[2]*ai[4] + a[4]*ai[5];
3431 //
3432 // mI[6] = a[3]*ai[0] + a[4]*ai[1] + a[5]*ai[3];
3433 // mI[7] = a[3]*ai[1] + a[4]*ai[2] + a[5]*ai[4];
3434 // mI[8] = a[3]*ai[3] + a[4]*ai[4] + a[5]*ai[5];
3435 //
3436 //
3437 // std::cout << "In Matrix"<<std::endl;
3438 // std::cout << ai[0][0] << " " << ai[1][0] << " " << ai[3][0] << std::endl;
3439 // std::cout << ai[1][0] << " " << ai[2][0] << " " << ai[4][0] << std::endl;
3440 // std::cout << ai[3][0] << " " << ai[4][0] << " " << ai[5][0] << std::endl;
3441 // std::cout << "I"<<std::endl;
3442 // std::cout << mI[0][0] << " " << mI[1][0] << " " << mI[2][0] << std::endl;
3443 // std::cout << mI[3][0] << " " << mI[4][0] << " " << mI[5][0] << std::endl;
3444 // std::cout << mI[6][0] << " " << mI[7][0] << " " << mI[8][0] << std::endl;
3445 // std::cout << " " <<std::endl;
3446 // std::cout << (ai[0][0]/ai[1][0]) << " "<< (ai[1][0]/ai[2][0]) << " " << (ai[3][0]/ai[4][0]) <<std::endl;
3447 // std::cout << (ai[0][0]/ai[3][0]) << " "<< (ai[1][0]/ai[4][0]) << " " << (ai[3][0]/ai[5][0]) <<std::endl;
3448 //
3449 // int ui;
3450 // std::cin >>ui;
3451 
3452 }
3453 
3454 void KFParticleBaseSIMD::MultQSQt( const fvec Q[], const fvec S[], fvec SOut[] )
3455 {
3456  //* Matrix multiplication Q*S*Q^T, Q - square matrix, S - symmetric
3457 
3458  const Int_t kN= 8;
3459  fvec mA[kN*kN];
3460 
3461  for( Int_t i=0, ij=0; i<kN; i++ ){
3462  for( Int_t j=0; j<kN; j++, ++ij ){
3463  mA[ij] = 0 ;
3464  for( Int_t k=0; k<kN; ++k ) mA[ij]+= S[( k<=i ) ? i*(i+1)/2+k :k*(k+1)/2+i] * Q[ j*kN+k];
3465  }
3466  }
3467 
3468  for( Int_t i=0; i<kN; i++ ){
3469  for( Int_t j=0; j<=i; j++ ){
3470  Int_t ij = ( j<=i ) ? i*(i+1)/2+j :j*(j+1)/2+i;
3471  SOut[ij] = 0 ;
3472  for( Int_t k=0; k<kN; k++ ) SOut[ij] += Q[ i*kN+k ] * mA[ k*kN+j ];
3473  }
3474  }
3475 }
3476 
3477 
3478 // 72-charachters line to define the printer border
3479 //3456789012345678901234567890123456789012345678901234567890123456789012
3480 
void GetDStoParticleBy(fvec B, const KFParticleBaseSIMD &p, fvec &dS, fvec &dS1) const
void AddDaughterWithEnergyFit(const KFParticleBaseSIMD &Daughter, Bool_t isAtVtxGuess)
Double_t p
Definition: anasim.C:58
friend F32vec4 cos(const F32vec4 &a)
Definition: P4_F32vec4.h:112
double dy
fvec GetEta(fvec &Eta, fvec &SigmaEta) const
TCanvas * c11
double r
Definition: RiemannTest.C:14
TObjArray * d
fvec GetDStoPointCBM(const fvec xyz[]) const
double mP
fvec GetDeviationFromParticle(const KFParticleBaseSIMD &p) const
Int_t i
Definition: run_full.C:25
__m128 m
Definition: P4_F32vec4.h:28
TTree * b
fvec GetDecayLength(fvec &L, fvec &SigmaL) const
virtual void GetDStoParticle(const KFParticleBaseSIMD &p, fvec &DS, fvec &DSp) const =0
fvec GetMomentum(fvec &P, fvec &SigmaP) const
Double_t lambda(Double_t x, Double_t y, Double_t z)
Definition: drawdal.C:48
fvec GetDeviationFromVertex(const fvec v[], const fvec Cv[]=0) const
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
virtual void Transport(fvec dS, fvec P[], fvec C[]) const =0
static T Sqrt(const T &x)
Definition: PndCAMath.h:37
void SetVtxErrGuess(fvec &x, fvec &y, fvec &z)
TH1F * h4
friend F32vec4 sin(const F32vec4 &a)
Definition: P4_F32vec4.h:111
void GetDStoParticleLine(const KFParticleBaseSIMD &p, fvec &dS, fvec &dS1) const
TCanvas * c7
TLorentzVector s
Definition: Pnd2DStar.C:50
static T Sin(const T &x)
Definition: PndCAMath.h:42
int n
void GetDistanceToVertexLine(const KFParticleBaseSIMD &Vertex, fvec &l, fvec &dl, fvec *isParticleFromVertex=0) const
TFile * g
friend F32vec4 log(const F32vec4 &a)
Definition: P4_F32vec4.h:110
void ConstructGammaBz(const KFParticleBaseSIMD &daughter1, const KFParticleBaseSIMD &daughter2, fvec Bz)
const fvec & Y() const
c2
Definition: plot_dirc.C:39
void AddDaughterId(fvec id)
fvec GetLifeTime(fvec &T, fvec &SigmaT) const
void operator+=(const KFParticleBaseSIMD &Daughter)
void GetDStoParticleCBM(const KFParticleBaseSIMD &p, fvec &dS, fvec &dS1) const
void TransportLine(fvec S, fvec P[], fvec C[]) const
fvec GetR(fvec &R, fvec &SigmaR) const
fvec GetSCorrection(const fvec Part[], const fvec XYZ[]) const
void GetMeasurement(const fvec XYZ[], fvec m[], fvec V[], Bool_t isAtVtxGuess=0) const
static const fvec Zero
fvec & Cij(Int_t i, Int_t j)
virtual void GetFieldValue(const fvec xyz[], fvec B[]) const =0
static T Cos(const T &x)
Definition: PndCAMath.h:43
void RotateXY(fvec angle, fvec Vtx[3])
__m128 v
Definition: P4_F32vec4.h:4
static void error(int no)
Definition: ranlxd.cxx:419
TLorentzVector Vertex
Definition: Pnd2DStar.C:50
TF1 * g1
fvec GetCovariance(Int_t i) const
fvec GetDStoPointBy(fvec By, const fvec xyz[]) const
static int init
Definition: ranlxd.cxx:374
void AddDaughterWithEnergyCalc(const KFParticleBaseSIMD &Daughter, Bool_t isAtVtxGuess)
TString pt(TString pts, TString exts="px py pz")
Definition: invexp.C:133
Double_t d0
Definition: checkhelixhit.C:59
void TransportCBM(fvec dS, fvec P[], fvec C[]) const
int Pic_FED Eff_lEE C()
static T Abs(const T &x)
Definition: PndCAMath.h:39
void Convert(bool ToProduction)
TString m2(TString pts, TString exts="e px py pz")
Definition: invexp.C:117
fvec & Covariance(Int_t i)
const fvec & Z() const
Int_t a
Definition: anaLmdDigi.C:126
static const fvec small
static void multQSQt1(const fvec J[11], fvec S[])
static fvec InvertSym3(const fvec A[], fvec Ainv[])
static void MultQSQt(const fvec Q[], const fvec S[], fvec SOut[])
static void GetArmenterosPodolanski(KFParticleBaseSIMD &positive, KFParticleBaseSIMD &negative, fvec QtAlfa[2])
fvec GetDistanceFromParticle(const KFParticleBaseSIMD &p) const
void GetDStoParticleBz(fvec Bz, const KFParticleBaseSIMD &p, fvec &dS, fvec &dS1) const
float_m ok
const fvec & E() const
const fvec & X() const
TFile * f
Definition: bump_analys.C:12
F32vec4 fvec
Definition: P4_F32vec4.h:218
Double_t z
void AddDaughterWithEnergyFitMC(const KFParticleBaseSIMD &Daughter, Bool_t isAtVtxGuess)
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
fvec GetDistanceFromVertex(const fvec vtx[]) const
fvec GetPt(fvec &Pt, fvec &SigmaPt) const
TH1F * h3
static void InvertCholetsky3(fvec a[6])
TPad * p2
Definition: hist-t7.C:117
double dx
TParticlePDG * fPDG
Definition: poormantracks.C:18
friend F32vec4 atan2(const F32vec4 &y, const F32vec4 &x)
Definition: P4_F32vec4.h:117
void SubtractFromParticle(KFParticleBaseSIMD &Vtx) const
GeV c P
void AddDaughter(const KFParticleBaseSIMD &Daughter, Bool_t isAtVtxGuess=0)
fvec GetDStoPointBz(fvec Bz, const fvec xyz[]) const
Double_t x
virtual fvec GetDStoPoint(const fvec xyz[]) const =0
fvec GetMass(fvec &M, fvec &SigmaM) const
TPad * p1
Definition: hist-t7.C:116
fvec GetPhi(fvec &Phi, fvec &SigmaPhi) const
static Int_t IJ(Int_t i, Int_t j)
TTree * t
Definition: bump_analys.C:13
TParticlePDG * eta
Double_t y
double alpha
Definition: f_Init.h:9
Double_t angle
void SetProductionVertex(const KFParticleBaseSIMD &Vtx)
static const fvec One
void SetNonlinearMassConstraint(fvec Mass)
TCanvas * c8
void SetVtxGuess(fvec x, fvec y, fvec z)
void TransportBz(fvec Bz, fvec dS, fvec P[], fvec C[]) const
#define if3(a, b, c)
Definition: P4_F32vec4.h:91
void SubtractFromVertex(KFParticleBaseSIMD &Vtx) const
fvec GetDecayLengthXY(fvec &L, fvec &SigmaL) const
double pz[39]
Definition: pipisigmas.h:14
void SetMassConstraint(fvec Mass, fvec SigmaMass=0)
Double_t energy
Definition: plot_dirc.C:15
void Construct(const KFParticleBaseSIMD *vDaughters[], Int_t nDaughters, const KFParticleBaseSIMD *ProdVtx=0, Float_t Mass=-1, Bool_t IsConstrained=0, Bool_t isAtVtxGuess=0)