1 package org.lcsim.mc.fast.tracking;
2
3 import Jama.util.Maths;
4 import hep.physics.matrix.SymmetricMatrix;
5 import Jama.Matrix;
6 import hep.physics.particle.Particle;
7
8 import hep.physics.vec.BasicHep3Vector;
9 import hep.physics.vec.Hep3Vector;
10 import hep.physics.vec.VecOp;
11 import org.lcsim.constants.Constants;
12 import org.lcsim.event.MCParticle;
13
14
15
16
17
18
19
20 public class DocaTrackParameters implements TrackParameters {
21 private Hep3Vector m_pdoca_ref = null;
22 private Hep3Vector m_xdoca_ref = null;
23 private Hep3Vector m_xref = null;
24 private SymmetricMatrix m_err = new SymmetricMatrix(5);
25 private double[] m_parm = new double[5];
26 private double m_Bz = 0.;
27 private double m_chi2 = -1.;
28 private double m_l0 = 0.;
29 private double m_l_ref = 0.;
30 private int m_ndf = 5;
31
32
33
34
35
36
37 public DocaTrackParameters(double bField) {
38 reset();
39 m_Bz = bField;
40 }
41
42 public DocaTrackParameters(MCParticle p, double bField) {
43 this(bField, p.getMomentum(), p.getOrigin(), p.getCharge());
44 }
45
46 public DocaTrackParameters(double bField, Particle p) {
47 this(bField, p.getMomentum(), p.getOrigin(), p.getType().getCharge());
48 }
49
50 public DocaTrackParameters(double bField, Hep3Vector momentum, Hep3Vector x, double q) {
51 reset();
52 m_Bz = bField;
53 calculateDoca(momentum, x, q);
54 }
55
56 public DocaTrackParameters(double bField, double[] momentum, double[] x, double q) {
57 reset();
58 m_Bz = bField;
59 calculateDoca(momentum, x, q);
60 }
61
62 public DocaTrackParameters(double bField, double[] momentum, double[] x, double q, SymmetricMatrix errorMatrix) {
63 this(bField, momentum, x, q);
64 this.m_err = errorMatrix;
65 }
66
67 public DocaTrackParameters(double bField, double[] parameters) {
68 m_Bz = bField;
69 m_parm = parameters;
70 }
71
72 public DocaTrackParameters(double bField, double[] parameters, SymmetricMatrix errorMatrix) {
73 this(bField, parameters);
74 this.m_err = errorMatrix;
75 }
76
77 public DocaTrackParameters(double bField, double[] parameters, SymmetricMatrix errorMatrix, double chi2) {
78 this(bField, parameters);
79 this.m_err = errorMatrix;
80 setChi2(chi2);
81 }
82
83 public DocaTrackParameters(double bField, double[] parameters, SymmetricMatrix errorMatrix, double chi2, int ndf) {
84 this(bField, parameters);
85 this.m_err = errorMatrix;
86 setChi2(chi2);
87 setNDF(ndf);
88 }
89
90 public double getD0() {
91 return m_parm[0];
92 }
93
94
95
96
97
98 public SymmetricMatrix getErrorMatrix() {
99 return m_err;
100 }
101
102
103
104
105 public double[] getMomentum() {
106 return new double[] { getPX(), getPY(), getPZ() };
107 }
108
109 public double getOmega() {
110 return m_parm[2];
111 }
112
113 public double getPX() {
114 return getPt() * Math.cos(m_parm[1]);
115 }
116
117 public double getPY() {
118 return getPt() * Math.sin(m_parm[1]);
119 }
120
121 public double getPZ() {
122 return getPt() * m_parm[4];
123 }
124
125 public double getPhi0() {
126 return m_parm[1];
127 }
128
129
130
131
132 public double getPtot() {
133 return Math.sqrt((getPX() * getPX()) + (getPY() * getPY()) + (getPZ() * getPZ()));
134 }
135
136 public double getTanL() {
137 return m_parm[4];
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177 public double getTrackParameter(int i) {
178 return m_parm[i];
179 }
180
181
182
183
184
185 public double[] getTrackParameters() {
186 return m_parm;
187 }
188
189
190
191
192 public int getUnitCharge() {
193 if (m_Bz != 0) {
194 return (int) Math.signum(m_parm[2]);
195 } else {
196 return 0;
197 }
198 }
199
200 public double getZ0() {
201 return m_parm[3];
202 }
203
204
205
206
207
208
209
210 public double magnitude() {
211 return Math.sqrt(VecOp.dot(getDocaVec(), getDocaVec()));
212 }
213
214 public double magnitudeSquared() {
215 return VecOp.dot(getDocaVec(), getDocaVec());
216 }
217
218 public double[] v() {
219 return getDoca();
220 }
221
222
223 public double x() {
224 return getDocaX();
225 }
226
227 public double y() {
228 return getDocaY();
229 }
230
231 public double z() {
232 return getDocaZ();
233 }
234
235
236
237
238 void setChi2(double chi2) {
239 m_chi2 = chi2;
240 }
241
242
243
244
245
246
247 double getChi2() {
248 return m_chi2;
249 }
250
251
252
253
254 double getCosTheta() {
255 return getPZ() / getPtot();
256 }
257
258
259
260
261 double[] getDoca() {
262 return new double[] { getDocaX(), getDocaY(), getDocaZ() };
263 }
264
265 double[] getDocaMomentum(double[] refPoint) {
266 return getDocaMomentumVec(refPoint).v();
267 }
268
269
270
271
272 Hep3Vector getDocaMomentumVec(Hep3Vector refPoint) {
273 if ((refPoint.x() != 0.) || (refPoint.y() != 0.)) {
274 checkCalcDoca(refPoint);
275
276 return m_pdoca_ref;
277 } else {
278 return getMomentumVec();
279 }
280 }
281
282 Hep3Vector getDocaMomentumVec(double[] refPoint) {
283 return getDocaMomentumVec(new BasicHep3Vector(refPoint[0], refPoint[1], refPoint[2]));
284 }
285
286 double[] getDocaPosition(double[] refPoint) {
287 return getDocaPositionVec(refPoint).v();
288 }
289
290
291
292
293
294
295
296
297
298
299 Hep3Vector getDocaPositionVec(Hep3Vector refPoint) {
300 if ((refPoint.x() != 0.) || (refPoint.y() != 0.)) {
301 checkCalcDoca(refPoint);
302
303 return m_xdoca_ref;
304 } else {
305 return getDocaVec();
306 }
307 }
308
309 Hep3Vector getDocaPositionVec(double[] refPoint) {
310 return getDocaPositionVec(new BasicHep3Vector(refPoint[0], refPoint[1], refPoint[2]));
311 }
312
313
314
315
316
317 double getDocaTransversePathLength(Hep3Vector refPoint) {
318 if ((refPoint.x() != 0.) || (refPoint.y() != 0)) {
319 checkCalcDoca(refPoint);
320
321 return m_l_ref;
322 } else {
323 return 0.;
324 }
325 }
326
327 double getDocaTransversePathLength(double[] refPoint) {
328 return getDocaTransversePathLength(new BasicHep3Vector(refPoint[0], refPoint[1], refPoint[2]));
329 }
330
331
332
333
334 Hep3Vector getDocaVec() {
335 return new BasicHep3Vector(getDocaX(), getDocaY(), getDocaZ());
336 }
337
338 double getDocaX() {
339 return (-m_parm[0] * Math.sin(m_parm[1]));
340 }
341
342 double getDocaY() {
343 return (m_parm[0] * Math.cos(m_parm[1]));
344 }
345
346 double getDocaZ() {
347 return (m_parm[3]);
348 }
349
350
351
352
353 void setL0(double l0) {
354 m_l0 = l0;
355 }
356
357
358
359
360 double getL0() {
361 return m_l0;
362 }
363
364 double[] getMomentum(double l) {
365 return getMomentumVec(l).v();
366 }
367
368
369
370
371 Hep3Vector getMomentumVec(double l) {
372 double phi0 = m_parm[1];
373 double omega = m_parm[2];
374 double tanl = m_parm[4];
375
376 int iq = getUnitCharge();
377
378 double phi = phi0 + (omega * l);
379 double pt = Constants.fieldConversion * iq * m_Bz / omega;
380
381 double px = pt * Math.cos(phi);
382 double py = pt * Math.sin(phi);
383 double pz = pt * tanl;
384
385
386 return new BasicHep3Vector(px, py, pz);
387 }
388
389 Hep3Vector getMomentumVec() {
390 return new BasicHep3Vector(getPX(), getPY(), getPZ());
391 }
392
393
394
395
396 void setNDF(int ndf) {
397 m_ndf = ndf;
398 }
399
400
401
402
403
404
405 int getNDF() {
406 return m_ndf;
407 }
408
409 double[] getPosition(double l) {
410 return getPositionVec(l).v();
411 }
412
413
414
415
416 Hep3Vector getPositionVec(double l) {
417 double d0 = m_parm[0];
418 double phi0 = m_parm[1];
419 double omega = m_parm[2];
420 double z0 = m_parm[3];
421 double tanl = m_parm[4];
422
423 double phi = phi0 + l * omega;
424 double rho = 1 / omega;
425
426 double x = (rho * Math.sin(phi)) - ((rho + d0) * Math.sin(phi0));
427 double y = (-rho * Math.cos(phi)) + ((rho + d0) * Math.cos(phi0));
428 double z = z0 + (l * tanl);
429
430 return new BasicHep3Vector(x, y, z);
431 }
432
433
434
435
436 double getPt() {
437 if (m_parm[2] != 0.) {
438 return Math.abs(Constants.fieldConversion * m_Bz / m_parm[2]);
439 } else {
440 return 0.;
441 }
442 }
443
444
445
446
447 double getTheta() {
448 return Math.atan2(getPt(), getPZ());
449 }
450
451
452
453
454 SymmetricMatrix calcMomentumErrorMatrix(double l) {
455 double rho = 1. / getOmega();
456 double phi = getPhi0() + (getOmega() * l);
457 double tanl = getTanL();
458 double c = Constants.fieldConversion * Math.abs(m_Bz);
459 double sphi = Math.sin(phi);
460 double cphi = Math.cos(phi);
461
462 Matrix tMatrix = new Matrix(5, 3, 0.);
463 tMatrix.set(1, 0, -c * rho * sphi);
464 tMatrix.set(1, 1, c * rho * cphi);
465 tMatrix.set(2, 0, (-c * rho * rho * cphi) - (c * rho * l * sphi));
466 tMatrix.set(2, 1, (-c * rho * rho * sphi) + (c * rho * l * cphi));
467 tMatrix.set(2, 2, -c * rho * rho * tanl);
468 tMatrix.set(4, 2, c * rho);
469
470 Matrix errorMatrix = Maths.toJamaMatrix(getErrorMatrix());
471 Matrix pErrorMatrix = tMatrix.transpose().times(errorMatrix.times(tMatrix));
472
473 return new SymmetricMatrix(Maths.fromJamaMatrix(pErrorMatrix));
474 }
475
476
477
478
479 double[][] calcPositionErrorMatrix(double l) {
480 double d0 = getD0();
481 double rho = 1. / getOmega();
482 double phi = getPhi0() + (getOmega() * l);
483 double sphi0 = Math.sin(getPhi0());
484 double cphi0 = Math.cos(getPhi0());
485 double sphi = Math.sin(phi);
486 double cphi = Math.cos(phi);
487
488 Matrix tMatrix = new Matrix(5, 3, 0.);
489 tMatrix.set(0, 0, -sphi0);
490 tMatrix.set(0, 1, cphi0);
491 tMatrix.set(1, 0, (rho * cphi) - ((rho + d0) * cphi0));
492 tMatrix.set(1, 1, (rho * sphi) - ((rho + d0) * sphi0));
493 tMatrix.set(2, 0, (rho * l * cphi) - (rho * rho * (sphi - sphi0)));
494 tMatrix.set(2, 1, (rho * l * sphi) + (rho * rho * (cphi - cphi0)));
495 tMatrix.set(3, 2, 1.);
496 tMatrix.set(4, 2, l);
497
498 Matrix errorMatrix = Maths.toJamaMatrix(getErrorMatrix());
499
500
501
502
503 Matrix xErrorMatrix = tMatrix.transpose().times(errorMatrix.times(tMatrix));
504
505 return xErrorMatrix.getArrayCopy();
506 }
507
508
509
510
511
512
513
514
515
516
517 private void calculateDoca(double[] momentum, double[] trackPoint, double q) {
518 Hep3Vector p = new BasicHep3Vector(momentum[0], momentum[1], momentum[2]);
519 Hep3Vector x = new BasicHep3Vector(trackPoint[0], trackPoint[1], trackPoint[2]);
520 calculateDoca(p, x, q);
521 }
522
523
524
525
526 private void calculateDoca(Hep3Vector momentum, Hep3Vector trackPoint, double charge) {
527 reset();
528
529 Hep3Vector xOrigin = new BasicHep3Vector(0., 0., 0.);
530
531 Hep3Vector[] result = calculateDoca(momentum, trackPoint, charge, xOrigin);
532 Hep3Vector xdoca = result[0];
533 Hep3Vector pdoca = result[1];
534 Hep3Vector dphdl = result[2];
535
536 int iq = (int) (charge / Math.abs(charge));
537 double pt = Math.sqrt((pdoca.x() * pdoca.x()) + (pdoca.y() * pdoca.y()));
538
539
540 double d0 = Math.sqrt((xdoca.x() * xdoca.x()) + (xdoca.y() * xdoca.y()));
541 if (VecOp.cross(xdoca, pdoca).z() > 0) {
542 d0 = -d0;
543 }
544
545 double phi0 = Math.atan2(pdoca.y(), pdoca.x());
546 if (phi0 > Math.PI) {
547 phi0 -= (2 * Math.PI);
548 }
549 if (phi0 < -Math.PI) {
550 phi0 += (2 * Math.PI);
551 }
552
553 double omega = Constants.fieldConversion * iq * m_Bz / pt;
554 double tanl = pdoca.z() / pt;
555 double z0 = xdoca.z();
556
557
558 m_parm[0] = d0;
559 m_parm[1] = phi0;
560 m_parm[2] = omega;
561 m_parm[3] = z0;
562 m_parm[4] = tanl;
563
564
565 m_l0 = -dphdl.y();
566
567
568
569
570
571
572
573
574
575 }
576
577
578
579
580 private Hep3Vector[] calculateDoca(Hep3Vector momentum, Hep3Vector trackPoint, double charge, Hep3Vector refPoint) {
581
582 Hep3Vector xp = VecOp.sub(trackPoint, refPoint);
583
584 int iq = (int) (charge / Math.abs(charge));
585 double pt = Math.sqrt((momentum.x() * momentum.x()) + (momentum.y() * momentum.y()));
586 double tanl = momentum.z() / pt;
587 double rho = pt / (m_Bz * Constants.fieldConversion);
588
589 BasicHep3Vector xdoca;
590 Hep3Vector pdoca;
591 Hep3Vector dphdl;
592
593
594 if (xp.magnitude() > 0.)
595 {
596
597 Hep3Vector nzv = new BasicHep3Vector(0., 0., iq);
598 Hep3Vector xxc = new BasicHep3Vector(VecOp.cross(momentum, nzv).x(), VecOp.cross(momentum, nzv).y(), 0.);
599 Hep3Vector nxxc = VecOp.unit(xxc);
600 BasicHep3Vector xc = (BasicHep3Vector) VecOp.add(xp, VecOp.mult(rho, nxxc));
601 xc.setV(xc.x(), xc.y(), 0.);
602
603 Hep3Vector nxc = VecOp.unit(xc);
604
605 BasicHep3Vector catMC = (BasicHep3Vector) VecOp.cross(nzv, nxc);
606 catMC.setV(catMC.x(), catMC.y(), 0.);
607
608 Hep3Vector ncatMC = VecOp.unit(catMC);
609
610 pdoca = new BasicHep3Vector(pt * ncatMC.x(), pt * ncatMC.y(), momentum.z());
611
612 double dphi = Math.asin(VecOp.cross(nxxc, nxc).z());
613 double dl = -dphi * rho * iq;
614
615 xdoca = (BasicHep3Vector) VecOp.add(xc, VecOp.mult(-rho, nxc));
616 xdoca.setV(xdoca.x(), xdoca.y(), xp.z() + (dl * tanl));
617
618
619 dphdl = new BasicHep3Vector(dphi, dl, 0.);
620 } else {
621 xdoca = (BasicHep3Vector) xp;
622 pdoca = momentum;
623 dphdl = new BasicHep3Vector();
624 }
625
626
627 xdoca = (BasicHep3Vector) VecOp.add(xdoca, refPoint);
628
629 return new Hep3Vector[] { xdoca, pdoca, dphdl };
630 }
631
632
633
634
635 private void checkCalcDoca(Hep3Vector refPoint) {
636
637 if ((m_xref == null) || (refPoint.x() != m_xref.x()) || (refPoint.y() != m_xref.y()) || (refPoint.z() != m_xref.z())) {
638 m_xref = refPoint;
639
640
641 Hep3Vector xdoca = getDocaVec();
642 Hep3Vector pdoca = getMomentumVec();
643 int iq = getUnitCharge();
644
645
646 Hep3Vector[] result = calculateDoca(pdoca, xdoca, (double) iq, refPoint);
647 m_xdoca_ref = result[0];
648 m_pdoca_ref = result[1];
649
650
651 m_l_ref = result[2].y();
652 }
653 }
654
655 private void reset() {
656 for (int i = 0; i < 5; i++) {
657 m_parm[i] = 0;
658 for (int j = 0; j <= i; j++) {
659 m_err.setElement(i, j, 0);
660 }
661 }
662 m_l0 = 0.;
663 }
664
665 void setErrorMatrix(SymmetricMatrix error) {
666 m_err = error;
667 }
668 }