1 package org.lcsim.recon.tracking.trfdca;
2
3
4 import org.lcsim.recon.tracking.trfutil.Assert;
5 import org.lcsim.recon.tracking.trfutil.TRFMath;
6 import org.lcsim.recon.tracking.trfbase.PropDirected;
7 import org.lcsim.recon.tracking.trfbase.PropStat;
8 import org.lcsim.recon.tracking.trfbase.Surface;
9 import org.lcsim.recon.tracking.trfbase.VTrack;
10 import org.lcsim.recon.tracking.trfbase.TrackDerivative;
11 import org.lcsim.recon.tracking.trfbase.TrackVector;
12
13 import org.lcsim.recon.tracking.trfcyl.SurfCylinder;
14
15 import org.lcsim.recon.tracking.trfbase.Propagator;
16 import org.lcsim.recon.tracking.trfbase.PropDirected;
17 import org.lcsim.recon.tracking.trfbase.PropDir;
18
19
20
21
22
23
24
25
26
27
28
29
30 public class PropCylDCA extends PropDirected
31 {
32
33
34
35
36
37
38 private static final int IPHI = SurfCylinder.IPHI;
39 private static final int IZ_CYL = SurfCylinder.IZ;
40 private static final int IALF = SurfCylinder.IALF;
41 private static final int ITLM_CYL = SurfCylinder.ITLM;
42 private static final int IQPT_CYL = SurfCylinder.IQPT;
43
44 private static final int IRSIGNED = SurfDCA.IRSIGNED;
45 private static final int IZ_DCA = SurfDCA.IZ;
46 private static final int IPHID = SurfDCA.IPHID;
47 private static final int ITLM_DCA = SurfDCA.ITLM;
48 private static final int IQPT_DCA = SurfDCA.IQPT;
49
50
51
52
53
54
55
56
57 private double _bfac;
58
59
60
61
62
63
64
65
66
67
68
69
70 public static String typeName()
71 { return "PropCylDCA";
72 }
73
74
75
76
77
78
79
80 public String staticType()
81 { return typeName();
82 }
83
84
85
86
87
88
89 public PropCylDCA(double bfield)
90 {
91 _bfac = bfield * TRFMath.BFAC;
92 }
93
94
95
96
97
98
99 public Propagator newPropagator()
100 {
101 return new PropCylDCA( bField() );
102 }
103
104
105
106
107
108
109
110 public String type()
111 { return staticType();
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public PropStat vecDirProp( VTrack trv, Surface srf,
127 PropDir dir)
128 {
129 TrackDerivative deriv = null;
130 return cylDcaPropagate( _bfac, trv, srf, dir, deriv );
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 public PropStat vecDirProp( VTrack trv, Surface srf,
148 PropDir dir, TrackDerivative deriv)
149 {
150 return cylDcaPropagate( _bfac, trv, srf, dir, deriv );
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 public PropStat cylDcaPropagate( double _bfac,
169 VTrack trv,
170 Surface srf,
171 PropDir dir,
172 TrackDerivative deriv )
173 {
174
175
176 PropStat pstat = new PropStat();
177
178
179 Surface srf_scy = trv.surface();
180 Assert.assertTrue( srf_scy.pureType().equals(SurfCylinder.staticType()) );
181 if ( !srf_scy.pureType( ).equals(SurfCylinder.staticType()) )
182 return pstat;
183
184
185 Assert.assertTrue( srf.pureType().equals(SurfDCA.staticType()) );
186 if ( !srf.pureType( ).equals(SurfDCA.staticType()) )
187 return pstat;
188 SurfDCA srf_dca = ( SurfDCA ) srf;
189
190
191
192 boolean tilted = srf_dca.dXdZ() != 0 || srf_dca.dYdZ() != 0;
193 Assert.assertTrue(!tilted);
194 if(tilted) return pstat;
195
196
197
198
199
200
201 double r1p = srf_scy.parameter(SurfCylinder.RADIUS);
202 double xv = srf_dca.x();
203 double yv = srf_dca.y();
204
205
206 TrackVector vec_scy = trv.vector();
207 double phi1p = vec_scy.get(SurfCylinder.IPHI);
208 double z1 = vec_scy.get(SurfCylinder.IZ);
209 double alf1p = vec_scy.get(SurfCylinder.IALF);
210 double tlam1 = vec_scy.get(SurfCylinder.ITLM);
211 double qpt1 = vec_scy.get(SurfCylinder.IQPT);
212
213 double cosphi1p=Math.cos(phi1p);
214 double sinphi1p=Math.sin(phi1p);
215
216 double x1=r1p*cosphi1p-xv;
217 double y1=r1p*sinphi1p-yv;
218
219 double phi1 = Math.atan2(y1,x1);
220 double r1 = Math.sqrt(x1*x1+y1*y1);
221 double alf1 = alf1p + phi1p - phi1;
222
223
224
225 double salf1 = Math.sin( alf1 );
226 double calf1 = Math.cos( alf1 );
227 double crv1 = _bfac * qpt1;
228
229
230
231 double r2;
232 final double sign_alf1 = alf1 > 0.0 ? 1.0 : -1.0;
233 double sign_alf2 = 1.0;
234
235 double del = (r1*crv1 - 2.0*salf1);
236 double rcdel = r1*crv1*del;
237 double sroot = Math.sqrt(1.0 + rcdel);
238 double sroot_minus_one = sroot - 1.0;
239 if ( rcdel < 1.e-6 )
240 sroot_minus_one = 0.5*rcdel - 0.125*rcdel*rcdel + 0.0625*rcdel*rcdel*rcdel;
241
242 if ( Math.abs(del)<1e-14 )
243 {
244 sign_alf2 = sign_alf1;
245 r2 = 0.0;
246 }
247 else if ( TRFMath.isZero(crv1) )
248 {
249 sign_alf2 = sign_alf1;
250 r2 = r1 * Math.abs(salf1);
251 }
252 else
253 {
254 sign_alf2 = crv1*r1 > 2.0*salf1 ? -1.0 : 1.0;
255 r2 = -sign_alf2*sroot_minus_one/crv1;
256 Assert.assertTrue( r2 > 0.0 );
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 double alf2 = sign_alf2 * TRFMath.PI2;
278
279
280 double sign_crv = 1.;
281
282
283 double tlam2 = tlam1;
284 double qpt2 = qpt1;
285 double crv2 = crv1;
286
287
288 double salf2 = sign_alf2 > 0 ? 1.: (sign_alf2 < 0 ? -1.: 0. );
289
290 double cnst = salf2-r2*crv2 > 0. ? TRFMath.PI2: (sign_alf2 == 0. ? 0. : -TRFMath.PI2);
291 double phi2 = phi1p + Math.atan2( salf1-r1p*crv1, calf1 )
292 - cnst;
293 if(crv1 == 0. ) phi2= phi1p + alf1 - cnst;
294
295 double phid2 = phi2 + sign_alf2 * TRFMath.PI2;
296 phid2 = TRFMath.fmod2( phid2, TRFMath.TWOPI );
297
298
299 ST_CylDCA sto = new ST_CylDCA(r1,phi1,alf1,crv1,r2,phi2,alf2);
300
301 double st = sto.st();
302 double s = st*Math.sqrt(1+tlam1*tlam1);
303
304
305 double z2 = z1 + st * tlam1;
306
307
308 TrackVector vec_dca = new TrackVector();
309 vec_dca.set(IRSIGNED , sign_alf2 * r2);
310 vec_dca.set(IZ_DCA , z2);
311
312
313
314
315
316
317
318 vec_dca.set(IPHID , phid2);
319 vec_dca.set(ITLM_DCA , tlam2);
320 vec_dca.set(IQPT_DCA , qpt2);
321
322
323
324
325
326
327
328
329
330
331
332 trv.setSurface( srf_dca.newPureSurface() );
333
334
335 trv.setVector(vec_dca);
336
337
338 trv.setForward();
339
340
341 pstat.setPathDistance(s);
342
343
344 if ( deriv == null ) return pstat;
345
346
347
348
349 double dr2_dalf1_or = calf1/(sign_alf2-crv1*r2);
350 double dr2_dalf1 = r1*dr2_dalf1_or;
351 double dr2_dcrv1 = (r2*r2-r1*r1)/(2.0*(sign_alf2-crv1*r2));
352 double dr2_dr1 = -sign_alf2/sroot*(r1*crv1 - salf1);
353
354 double dphi2_dalf1 = sign_crv*(1.0-r1*crv1*salf1)/(sroot*sroot);
355 double dphi2_dalf1_m1_or = sign_crv*(-crv1*salf1-crv1*del)/(sroot*sroot);
356 double dphi2_dcrv1 = -sign_crv*(r1*calf1)/(sroot*sroot);
357 double dphi2_dr1 = -crv1*calf1/(1.+r1*crv1*r1*crv1-2.*salf1*r1*crv1);
358
359
360 double dst_dalf1 = sto.d_st_dalf1(dr2_dalf1, dphi2_dalf1);
361 double dst_dalf1_or = sto.d_st_dalf1_or(r1,dr2_dalf1_or, dphi2_dalf1_m1_or);
362 double dst_dcrv1 = sto.d_st_dcrv1(dr2_dcrv1, dphi2_dcrv1);
363 double dst_dr1 = sto.d_st_dr1();
364
365
366
367 double dphi1_dphi1p_tr = r1p*Math.cos(phi1p-phi1);
368 double dalf1_dphi1p_tr = r1 - dphi1_dphi1p_tr;
369 double dalf1_dalf1p = 1.;
370 double dr1_dphi1p = r1p*Math.sin(phi1-phi1p);
371
372
373
374
375 double dr2_dphi1p = dr2_dalf1_or*dalf1_dphi1p_tr + dr2_dr1*dr1_dphi1p;
376 double dr2_dalf1p = dr2_dalf1 * dalf1_dalf1p;
377
378 double dst_dphi1p = dst_dalf1_or*dalf1_dphi1p_tr + dst_dr1*dr1_dphi1p;
379 double dst_dalf1p = dst_dalf1*dalf1_dalf1p;
380
381 double dphi2_dphi1p = -dphi1_dphi1p_tr*dphi2_dalf1_m1_or + dphi2_dr1*dr1_dphi1p + dphi2_dalf1;
382 double dphi2_dalf1p = dphi2_dalf1*dalf1_dalf1p;
383
384
385
386
387
388
389
390 deriv.set(IRSIGNED, IPHI , sign_alf2 * dr2_dphi1p);
391 deriv.set(IRSIGNED, IZ_CYL , 0.0);
392 deriv.set(IRSIGNED, IALF , sign_alf2 * dr2_dalf1p);
393 deriv.set(IRSIGNED, ITLM_CYL , 0.0);
394 deriv.set(IRSIGNED, IQPT_CYL , sign_alf2 * _bfac * dr2_dcrv1);
395
396 deriv.set(IZ_DCA, IPHI , tlam1 * dst_dphi1p);
397 deriv.set(IZ_DCA, IZ_CYL , 1.0);
398 deriv.set(IZ_DCA, IALF , tlam1 * dst_dalf1p);
399 deriv.set(IZ_DCA, ITLM_CYL , st);
400 deriv.set(IZ_DCA, IQPT_CYL , tlam1 * _bfac * dst_dcrv1);
401
402 deriv.set(IPHID, IPHI , dphi2_dphi1p);
403 deriv.set(IPHID, IZ_CYL , 0.0);
404 deriv.set(IPHID, IALF , dphi2_dalf1p);
405 deriv.set(IPHID, ITLM_CYL , 0.0);
406 deriv.set(IPHID, IQPT_CYL , _bfac * dphi2_dcrv1);
407
408 deriv.set(ITLM_DCA, IPHI , 0.0);
409 deriv.set(ITLM_DCA, IZ_CYL , 0.0);
410 deriv.set(ITLM_DCA, IALF , 0.0);
411 deriv.set(ITLM_DCA, ITLM_CYL , 1.0);
412 deriv.set(ITLM_DCA, IQPT_CYL , 0.0);
413
414 deriv.set(IQPT_DCA, IPHI , 0.0);
415 deriv.set(IQPT_DCA, IZ_CYL , 0.0);
416 deriv.set(IQPT_DCA, IALF , 0.0);
417 deriv.set(IQPT_DCA, ITLM_CYL , 0.0);
418 deriv.set(IQPT_DCA, IQPT_CYL , 1.0);
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 return pstat;
437
438 }
439
440
441
442
443
444
445
446 public double bField()
447 {
448 return _bfac/TRFMath.BFAC;
449 }
450
451
452
453
454
455
456 public String toString()
457 {
458 return "Propagation from Cylinder to DCA with constant "
459 + bField() + " Tesla field";
460
461 }
462
463
464 /
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619