BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
TRunge.cxx
Go to the documentation of this file.
1//-----------------------------------------------------------------------------
2// $Id: TRunge.cxx,v 1.41 2022/01/28 22:04:42 maqm Exp $
3//-----------------------------------------------------------------------------
4// Filename : TRunge.cc
5// Section : Tracking
6// Owner : Kenji Inami
7// Email : inami@bmail.kek.jp
8//-----------------------------------------------------------------------------
9// Description : A class to represent a track using Runge Kutta method
10// See http://bsunsrv1.kek.jp/~yiwasaki/tracking/
11//-----------------------------------------------------------------------------
12
13#include "TrkReco/TRunge.h"
14#include "TrkReco/TMDCWire.h"
15#include "TrkReco/TRungeFitter.h"
16#include "TrkReco/TTrack.h"
17#include <float.h>
18#include <string.h>
19
20#include "CLHEP/Matrix/Matrix.h"
21#include "GaudiKernel/Bootstrap.h"
22#include "GaudiKernel/IDataProviderSvc.h"
23#include "GaudiKernel/IInterface.h"
24#include "GaudiKernel/IMessageSvc.h"
25#include "GaudiKernel/ISvcLocator.h"
26#include "GaudiKernel/Kernel.h"
27#include "GaudiKernel/MsgStream.h"
28#include "GaudiKernel/Service.h"
29#include "GaudiKernel/SmartDataPtr.h"
30#include "GaudiKernel/StatusCode.h"
31typedef HepGeom::Transform3D HepTransform3D;
32
33// const double alpha2 = 333.5640952; //(cm Tesla /(GeV/c))
34TRungeFitter TRunge::_fitter = TRungeFitter( "TRunge Default fitter" );
35
36// const double default_stepSize = 0;
37const double default_stepSize = 1.5; // cm
38const double default_stepSize0 = 1.5; // cm
39const double default_stepSizeMax = 5; // cm
40const double default_stepSizeMin = 0.001; // cm
41
42const double EPS = 1.0e-6;
43
44const double default_maxflightlength = 1000; // 10m
45
47 : TTrackBase()
48 , _pivot( ORIGIN )
49 , _a( Vector( 5, 0 ) )
50 , _Ea( SymMatrix( 5, 0 ) )
51 , _chi2( 0 )
52 , _ndf( 0 )
53 , _charge( 1 )
54 , _bfieldID( 21 )
55 , _Nstep( 0 )
56 , _stepSize( default_stepSize )
57 , _mass( 0.140 )
58 , _eps( EPS )
59 , _stepSizeMax( default_stepSizeMax )
60 , _stepSizeMin( default_stepSizeMin )
61 , _maxflightlength( default_maxflightlength )
62 , m_pmgnIMF( nullptr ) {
63
64 //...Set a default fitter...
65 fitter( &TRunge::_fitter );
66
67 _fitted = false;
68 _fittedWithCathode = false;
69
70 _bfield = Bfield::getBfield( _bfieldID );
71
72 _mass2 = _mass * _mass;
73
74 _yscal[0] = 0.1; // 1mm -> error = 1mm*EPS
75 _yscal[1] = 0.1; // 1mm
76 _yscal[2] = 0.1; // 1mm
77 _yscal[3] = 0.001; // 1MeV
78 _yscal[4] = 0.001; // 1MeV
79 _yscal[5] = 0.001; // 1MeV
80}
81
83 : TTrackBase()
84 , _pivot( a.getPivot() )
85 , _a( a.helix() )
86 , _Ea( a.err() )
87 , _chi2( a.chi2() )
88 , _ndf( a.ndof() )
89 , _bfieldID( 21 )
90 , _Nstep( 0 )
91 , _stepSize( default_stepSize )
92 , _mass( 0.140 )
93 , _eps( EPS )
94 , _stepSizeMax( default_stepSizeMax )
95 , _stepSizeMin( default_stepSizeMin )
96 , _maxflightlength( default_maxflightlength )
97 , m_pmgnIMF( nullptr ) {
98 // _a[2]=-_a[2];
99 //...Set a default fitter...
100 fitter( &TRunge::_fitter );
101
102 _fitted = false;
103 _fittedWithCathode = false;
104
105 if ( _a[2] < 0 ) _charge = -1;
106 else _charge = 1;
107
108 _bfield = Bfield::getBfield( _bfieldID );
109
110 _mass2 = _mass * _mass;
111
112 _yscal[0] = 0.1; // 1mm -> error = 1mm*EPS
113 _yscal[1] = 0.1; // 1mm
114 _yscal[2] = 0.1; // 1mm
115 _yscal[3] = 0.001; // 1MeV
116 _yscal[4] = 0.001; // 1MeV
117 _yscal[5] = 0.001; // 1MeV
118 // SetFlightLength();
119 // cout<<"TR:: _maxflightlength="<<_maxflightlength<<endl;
120}
121
123 : TTrackBase( a )
124 , _pivot( a.helix().pivot() )
125 , _a( a.helix().a() )
126 , _Ea( a.helix().Ea() )
127 , _chi2( 0 )
128 , _ndf( 0 )
129 , _bfieldID( 21 )
130 , _Nstep( 0 )
131 , _stepSize( default_stepSize )
132 , _mass( 0.140 )
133 , _eps( EPS )
134 , _stepSizeMax( default_stepSizeMax )
135 , _stepSizeMin( default_stepSizeMin )
136 , _maxflightlength( default_maxflightlength )
137 , m_pmgnIMF( nullptr ) {
138 // _a[2]=-_a[2];
139 //...Set a default fitter...
140 fitter( &TRunge::_fitter );
141
142 _fitted = false;
143 _fittedWithCathode = false;
144
145 if ( _a[2] < 0 ) _charge = -1;
146 else _charge = 1;
147
148 _bfield = Bfield::getBfield( _bfieldID );
149
150 _mass2 = _mass * _mass;
151
152 _yscal[0] = 0.1; // 1mm -> error = 1mm*EPS
153 _yscal[1] = 0.1; // 1mm
154 _yscal[2] = 0.1; // 1mm
155 _yscal[3] = 0.001; // 1MeV
156 _yscal[4] = 0.001; // 1MeV
157 _yscal[5] = 0.001; // 1MeV
158
159 // SetFlightLength();
160 // cout<<"TR:: _maxflightlength="<<_maxflightlength<<endl;
161}
162
164 : TTrackBase()
165 , _pivot( h.pivot() )
166 , _a( h.a() )
167 , _Ea( h.Ea() )
168 , _chi2( 0 )
169 , _ndf( 0 )
170 , _bfieldID( 21 )
171 , _Nstep( 0 )
172 , _stepSize( default_stepSize )
173 , _mass( 0.140 )
174 , _eps( EPS )
175 , _stepSizeMax( default_stepSizeMax )
176 , _stepSizeMin( default_stepSizeMin )
177 , _maxflightlength( default_maxflightlength )
178 , m_pmgnIMF( nullptr ) {
179
180 //...Set a default fitter...
181 fitter( &TRunge::_fitter );
182
183 _fitted = false;
184 _fittedWithCathode = false;
185
186 if ( _a[2] < 0 ) _charge = -1;
187 else _charge = 1;
188
189 _bfield = Bfield::getBfield( _bfieldID );
190
191 _mass2 = _mass * _mass;
192
193 _yscal[0] = 0.1; // 1mm -> error = 1mm*EPS
194 _yscal[1] = 0.1; // 1mm
195 _yscal[2] = 0.1; // 1mm
196 _yscal[3] = 0.001; // 1MeV
197 _yscal[4] = 0.001; // 1MeV
198 _yscal[5] = 0.001; // 1MeV
199}
200
202 : TTrackBase( (TTrackBase&)a )
203 , _pivot( a.pivot() )
204 , _a( a.a() )
205 , _Ea( a.Ea() )
206 , _chi2( a.chi2() )
207 , _ndf( a.ndf() )
208 , _bfieldID( a.BfieldID() )
209 , _Nstep( 0 )
210 , _stepSize( a.StepSize() )
211 , _mass( a.Mass() )
212 , _eps( a.Eps() )
213 , _stepSizeMax( a.StepSizeMax() )
214 , _stepSizeMin( a.StepSizeMin() )
215 , _maxflightlength( a.MaxFlightLength() )
216 , m_pmgnIMF( nullptr ) {
217
218 //...Set a default fitter...
219 fitter( &TRunge::_fitter );
220
221 _fitted = false;
222 _fittedWithCathode = false;
223
224 if ( _a[2] < 0 ) _charge = -1;
225 else _charge = 1;
226
227 _bfield = Bfield::getBfield( _bfieldID );
228
229 _mass2 = _mass * _mass;
230
231 for ( unsigned i = 0; i < 6; i++ ) _yscal[i] = a.Yscal()[i];
232}
233
234// destructor
236
237double TRunge::dr( void ) const { return ( _a[0] ); }
238
239double TRunge::phi0( void ) const { return ( _a[1] ); }
240
241double TRunge::kappa( void ) const { return ( _a[2] ); }
242
243double TRunge::dz( void ) const { return ( _a[3] ); }
244
245double TRunge::tanl( void ) const { return ( _a[4] ); }
246
247const HepPoint3D& TRunge::pivot( void ) const { return ( _pivot ); }
248
249const Vector& TRunge::a( void ) const { return ( _a ); }
250
251const SymMatrix& TRunge::Ea( void ) const { return ( _Ea ); }
252
253Helix TRunge::helix( void ) const { return ( Helix( _pivot, _a, _Ea ) ); }
254
255unsigned TRunge::ndf( void ) const { return _ndf; }
256
257double TRunge::chi2( void ) const { return _chi2; }
258
259double TRunge::reducedchi2( void ) const {
260 if ( _ndf == 0 )
261 {
262 std::cout << "error at TRunge::reducedchi2 ndf=0" << std::endl;
263 return 0;
264 }
265 return ( _chi2 / _ndf );
266}
267
268int TRunge::BfieldID( void ) const { return ( _bfieldID ); }
269
270double TRunge::StepSize( void ) const { return ( _stepSize ); }
271
272const double* TRunge::Yscal( void ) const { return ( _yscal ); }
273double TRunge::Eps( void ) const { return ( _eps ); }
274double TRunge::StepSizeMax( void ) const { return ( _stepSizeMax ); }
275double TRunge::StepSizeMin( void ) const { return ( _stepSizeMin ); }
276
277float TRunge::Mass( void ) const { return ( _mass ); }
278
279double TRunge::MaxFlightLength( void ) const { return ( _maxflightlength ); }
280
281const HepPoint3D& TRunge::pivot( const HepPoint3D& newpivot ) {
282 /// !!!!! under construction !!!!!
283 /// track parameter should be extracted after track propagation.
284 Helix tHelix( helix() );
285 tHelix.pivot( newpivot );
286 _pivot = newpivot;
287 _a = tHelix.a();
288 _Ea = tHelix.Ea();
289 _Nstep = 0;
290 return ( _pivot );
291}
292
293const Vector& TRunge::a( const Vector& ta ) {
294 _a = ta;
295 if ( _a[2] < 0 ) _charge = -1;
296 else _charge = 1;
297 _Nstep = 0;
298 return ( _a );
299}
300
301const SymMatrix& TRunge::Ea( const SymMatrix& tEa ) {
302 _Ea = tEa;
303 _Nstep = 0;
304 return ( _Ea );
305}
306
307int TRunge::BfieldID( int id ) {
308 _bfieldID = id;
309 _bfield = Bfield::getBfield( _bfieldID );
310 _Nstep = 0;
311 return ( _bfieldID );
312}
313
314double TRunge::StepSize( double step ) {
315 _stepSize = step;
316 _Nstep = 0;
317 return ( _stepSize );
318}
319
320const double* TRunge::Yscal( const double y[6] ) {
321 for ( unsigned i = 0; i < 6; i++ ) _yscal[i] = y[i];
322 _Nstep = 0;
323 return ( _yscal );
324}
325double TRunge::Eps( double eps ) {
326 _eps = eps;
327 _Nstep = 0;
328 return ( _eps );
329}
330double TRunge::StepSizeMax( double step ) {
331 _stepSizeMax = step;
332 _Nstep = 0;
333 return ( _stepSizeMax );
334}
335double TRunge::StepSizeMin( double step ) {
336 _stepSizeMin = step;
337 _Nstep = 0;
338 return ( _stepSizeMin );
339}
340
341float TRunge::Mass( float mass ) {
342 _mass = mass;
343 _mass2 = _mass * _mass;
344 return ( _mass );
345}
346
347double TRunge::MaxFlightLength( double length ) {
348 if ( length > 0 ) _maxflightlength = length;
349 else _maxflightlength = default_maxflightlength;
350 _Nstep = 0;
351 return ( _maxflightlength );
352}
353
354int TRunge::approach( TMLink& l, const RkFitMaterial material, bool doSagCorrection ) {
355 float tof;
356 HepVector3D p;
357 return ( approach( l, tof, p, material, doSagCorrection ) );
358}
359
360int TRunge::approach( TMLink& l, float& tof, HepVector3D& p, const RkFitMaterial material,
361 bool doSagCorrection ) {
362 HepPoint3D xw;
363 HepPoint3D wireBackwardPosition;
365 HepPoint3D onWire, onTrack;
366 double onWire_x, onWire_y, onWire_z, zwf, zwb;
367 const TMDCWire& w = *l.wire();
368 xw = w.xyPosition();
369 wireBackwardPosition = w.backwardPosition();
370 v = w.direction();
371
372 unsigned stepNum = 0;
373 if ( approach_line( l, wireBackwardPosition, v, onWire, onTrack, tof, p, material,
374 stepNum ) < 0 )
375 {
376 // cout<<"TR::error approach_line"<<endl;
377 return ( -1 );
378 }
379 zwf = w.forwardPosition().z();
380 zwb = w.backwardPosition().z();
381 // protection for strange wire hit info. (Only 'onWire' is corrected)
382 if ( onWire.z() > zwf ) w.wirePosition( zwf, onWire, wireBackwardPosition, (HepVector3D&)v );
383 else if ( onWire.z() < zwb )
384 w.wirePosition( zwb, onWire, wireBackwardPosition, (HepVector3D&)v );
385
386 // onWire,onTrack filled
387
388 if ( !doSagCorrection )
389 {
390 l.positionOnWire( onWire );
391 l.positionOnTrack( onTrack );
392 double phipoint = atan( ( onTrack.y() - _pivot.y() ) / onTrack.x() - _pivot.x() );
393 // cout<<"dphi track:"<<l.dPhi()<<endl;
394 // cout<<"dphi rk:"<<phipoint-_a[0]<<endl;
395 // l.dPhi(phipoint-_a[0]);
396 return ( 0 ); // no sag correction
397 }
398 // Sag correction
399 // loop for sag correction
400 onWire_y = onWire.y();
401 onWire_z = onWire.z();
402
403 unsigned nTrial = 1;
404 while ( nTrial < 100 )
405 {
406 // cout<<"TR: nTrial "<<nTrial<<endl;
407 w.wirePosition( onWire_z, xw, wireBackwardPosition, (HepVector3D&)v );
408 if ( approach_line( l, wireBackwardPosition, v, onWire, onTrack, tof, p, material,
409 stepNum ) < 0 )
410 return ( -1 );
411 if ( fabs( onWire_y - onWire.y() ) < 0.0001 ) break; // |dy|< 1 micron
412 onWire_y = onWire.y();
413 onWire_z += ( onWire.z() - onWire_z ) / 2;
414 // protection for strange wire hit info.
415 if ( onWire_z > zwf ) onWire_z = zwf;
416 else if ( onWire_z < zwb ) onWire_z = zwb;
417
418 nTrial++;
419 }
420 // cout<<"TR nTrial="<<nTrial<<endl;
421 l.positionOnWire( onWire );
422 l.positionOnTrack( onTrack );
423 return ( nTrial );
424}
425
427 HepPoint3D& onLine, HepPoint3D& onTrack,
428 const RkFitMaterial material ) {
429 float tof;
430 HepVector3D p;
431 return ( approach_line( l, w0, v, onLine, onTrack, tof, p, material ) );
432}
433
435 HepPoint3D& onLine, HepPoint3D& onTrack, float& tof, HepVector3D& p,
436 const RkFitMaterial material ) {
437 unsigned stepNum = 0;
438 return ( approach_line( l, w0, v, onLine, onTrack, tof, p, material, stepNum ) );
439}
440
442 HepPoint3D& onLine, HepPoint3D& onTrack, float& tof, HepVector3D& p,
443 const RkFitMaterial material, unsigned& stepNum ) {
444 // line = [w0] + t * [v] -> [onLine]
445 if ( _Nstep == 0 )
446 {
447 if ( _stepSize == 0 ) Fly_SC();
448 else Fly( material );
449 }
450 // cout<<"TR::approach_line stepNum="<<stepNum<<endl;
451
452 const double w0x = w0.x();
453 const double w0y = w0.y();
454 const double w0z = w0.z();
455 // cout<<"TR::line w0="<<w0x<<","<<w0y<<","<<w0z<<endl;
456 const double vx = v.x();
457 const double vy = v.y();
458 const double vz = v.z();
459 const double v_2 = vx * vx + vy * vy + vz * vz;
460
461 const float clight = 29.9792458; //[cm/ns]
462 // const float M2=_mass*_mass;
463 // const float& M2=_mass2;
464 const float p2 = _y[0][3] * _y[0][3] + _y[0][4] * _y[0][4] + _y[0][5] * _y[0][5];
465 const float tof_factor = 1. / clight * sqrt( 1 + _mass2 / p2 );
466
467 // search for the closest point in cache (point - line)
468 // unsigned stepNum;
469 double l2_old = DBL_MAX;
470 if ( stepNum > _Nstep ) stepNum = 0;
471 unsigned stepNumLo;
472 unsigned stepNumHi;
473 if ( stepNum == 0 && _stepSize != 0 )
474 { // skip
475 const double dx = _y[0][0] - w0x;
476 const double dy = _y[0][1] - w0y;
477 stepNum = (unsigned)( sqrt( ( dx * dx + dy * dy ) * ( 1 + _a[4] * _a[4] ) ) / _stepSize );
478 }
479 unsigned mergin;
480 if ( _stepSize == 0 )
481 {
482 mergin = 10; // 10 step back
483 }
484 else
485 {
486 mergin = (unsigned)( 1.0 / _stepSize ); // 1mm back
487 }
488 if ( stepNum > mergin ) stepNum -= mergin;
489 else stepNum = 0;
490 if ( stepNum >= _Nstep ) stepNum = _Nstep - 1;
491 // hunt
492 // unsigned inc=1;
493 unsigned inc = ( mergin >> 1 ) + 1;
494 stepNumLo = stepNum;
495 stepNumHi = stepNum;
496 for ( ;; )
497 {
498 const double dx = _y[stepNumHi][0] - w0x;
499 const double dy = _y[stepNumHi][1] - w0y;
500 const double dz = _y[stepNumHi][2] - w0z;
501 const double t = ( dx * vx + dy * vy + dz * vz ) / v_2;
502 // const double l2 = (dx*dx+dy*dy+dz*dz)-(t*t)/v_2;
503 HepVector3D zvec;
504 zvec.setX( 0 );
505 zvec.setY( 0 );
506 zvec.setZ( 1 );
507 HepVector3D hitv = t * v;
508 HepPoint3D pp, onw;
509 pp.setX( _y[stepNumHi][0] );
510 pp.setY( _y[stepNumHi][1] );
511 pp.setZ( _y[stepNumHi][2] );
512 double zwire = hitv.dot( zvec ) + w0z;
513 double dtl = DisToWire( l, zwire, pp, onw );
514 const double l2 = dtl * dtl;
515 if ( l2 > l2_old ) break;
516 l2_old = l2;
517 stepNumLo = stepNumHi;
518 // inc+=inc;
519 stepNumHi += inc;
520 if ( stepNumHi >= _Nstep )
521 {
522 stepNumHi = _Nstep;
523 break;
524 }
525 }
526 // locate (2-bun-hou, bisection method)
527 while ( stepNumHi - stepNumLo > 1 )
528 {
529 unsigned j = ( stepNumHi + stepNumLo ) >> 1;
530 const double dx = _y[j][0] - w0x;
531 const double dy = _y[j][1] - w0y;
532 const double dz = _y[j][2] - w0z;
533 const double t = ( dx * vx + dy * vy + dz * vz ) / v_2;
534 // const double l2 = (dx*dx+dy*dy+dz*dz)-(t*t)/v_2;
535 HepVector3D zv;
536 zv.setX( 0 );
537 zv.setY( 0 );
538 zv.setZ( 1 );
539 HepVector3D hitv = t * v;
540 HepPoint3D point, onwir;
541 point.setX( _y[j][0] );
542 point.setY( _y[j][1] );
543 point.setZ( _y[j][2] );
544 double zwir = hitv.dot( zv ) + w0z;
545 double dtll = DisToWire( l, zwir, point, onwir );
546 const double l2 = dtll * dtll;
547 if ( l2 > l2_old ) { stepNumHi = j; }
548 else
549 {
550 l2_old = l2;
551 stepNumLo = j;
552 }
553 }
554 // stepNum=stepNumHi;
555 stepNum = stepNumLo;
556 /*
557 for(;stepNum<_Nstep;stepNum++){
558 const double dx = _y[stepNum][0]-w0x;
559 const double dy = _y[stepNum][1]-w0y;
560 const double dz = _y[stepNum][2]-w0z;
561 const double t = (dx*vx+dy*vy+dz*vz)/v_2;
562 const double l2 = (dx*dx+dy*dy+dz*dz)-(t*t)/v_2;
563 if(l2 > l2_old) break;
564 l2_old=l2;
565 // const float p2 = _y[stepNum][3]*_y[stepNum][3]+
566 // _y[stepNum][4]*_y[stepNum][4]+
567 // _y[stepNum][5]*_y[stepNum][5];
568 // tof+=_stepSize/clight*sqrt(1+M2/p2);
569 }
570 */
571 // cout<<"TR stepNum="<<stepNum<<endl;
572 // if(stepNum>=_Nstep) return(-1); // not found
573 // stepNum--;
574 if ( _stepSize == 0 )
575 {
576 double dstep = 0;
577 for ( unsigned i = 0; i < stepNum; i++ ) dstep += _h[i];
578 tof = dstep * tof_factor;
579 }
580 else { tof = stepNum * _stepSize * tof_factor; }
581
582 // propagate the track and search for the closest point
583 // 2-bun-hou (bisection method)
584 /*
585 double y[6],y_old[6];
586 for(unsigned i=0;i<6;i++) y[i]=_y[stepNum][i];
587 double step=_stepSize;
588 double step2=0;
589 for(;;){
590 for(unsigned i=0;i<6;i++) y_old[i]=y[i];
591 Propagate(y,step);
592 const double dx = y[0]-w0x;
593 const double dy = y[1]-w0y;
594 const double dz = y[2]-w0z;
595 const double t = (dx*vx+dy*vy+dz*vz)/v_2;
596 const double l2 = (dx*dx+dy*dy+dz*dz)-(t*t)/v_2;
597 if(l2 > l2_old){ // back
598 for(unsigned i=0;i<6;i++) y[i]=y_old[i];
599 }else{ // propagate
600 l2_old=l2;
601 // const float p2=y[3]*y[3]+y[4]*y[4]+y[5]*y[5];
602 // tof+=step/clight*sqrt(1+M2/p2);
603 step2+=step;
604 }
605 step/=2;
606 if(step < 0.0001) break; // step < 1 [um]
607 }
608 */
609 // Hasamiuchi-Hou (false position method)
610 /*
611 double y[6],y1[6],y2[6];
612 for(unsigned i=0;i<6;i++) y1[i]=_y[stepNum][i];
613 for(unsigned i=0;i<6;i++) y2[i]=_y[stepNum+2][i];
614 double minStep=0;
615 double maxStep=_stepSize*2;
616 double step2=0;
617 const double A[3][3]={{1-vx*vx/v_2, -vx*vy/v_2, -vx*vz/v_2},
618 { -vy*vx/v_2,1-vy*vy/v_2, -vy*vz/v_2},
619 { -vz*vx/v_2, -vz*vy/v_2,1-vz*vz/v_2}};
620
621 double Y1=0;
622 {
623 const double dx = y1[0]-w0x;
624 const double dy = y1[1]-w0y;
625 const double dz = y1[2]-w0z;
626 const double t = (dx*vx+dy*vy+dz*vz)/v_2;
627 const double d[3]={dx-t*vx,dy-t*vy,dz-t*vz};
628 const double l = sqrt( (dx*dx+dy*dy+dz*dz)-(t*t)/v_2 );
629 const double pmag=sqrt(y1[3]*y1[3]+y1[4]*y1[4]+y1[5]*y1[5]);
630 for(int j=0;j<3;j++){
631 double g=0;
632 for(int k=0;k<3;k++) g+=A[j][k]*d[k];
633 Y1+=y1[j+3]*g;
634 }
635 Y1=Y1/pmag/l;
636 }
637 double Y2=0;
638 {
639 const double dx = y2[0]-w0x;
640 const double dy = y2[1]-w0y;
641 const double dz = y2[2]-w0z;
642 const double t = (dx*vx+dy*vy+dz*vz)/v_2;
643 const double d[3]={dx-t*vx,dy-t*vy,dz-t*vz};
644 const double l = sqrt( (dx*dx+dy*dy+dz*dz)-(t*t)/v_2 );
645 const double pmag=sqrt(y2[3]*y2[3]+y2[4]*y2[4]+y2[5]*y2[5]);
646 for(int j=0;j<3;j++){
647 double g=0;
648 for(int k=0;k<3;k++) g+=A[j][k]*d[k];
649 Y2+=y2[j+3]*g;
650 }
651 Y2=Y2/pmag/l;
652 }
653 if(Y1*Y2>=0) cout<<"TR fatal error!"<<endl;
654 double step_old= DBL_MAX;
655 for(;;){
656 const double step=(minStep*Y2-maxStep*Y1)/(Y2-Y1);
657 if(fabs(step-step_old)<0.0001) break;
658 step_old=step;
659 for(unsigned i=0;i<6;i++) y[i]=y1[i];
660 Propagate(y,step-minStep);
661 double Y=0;
662 {
663 const double dx = y[0]-w0x;
664 const double dy = y[1]-w0y;
665 const double dz = y[2]-w0z;
666 const double t = (dx*vx+dy*vy+dz*vz)/v_2;
667 const double d[3]={dx-t*vx,dy-t*vy,dz-t*vz};
668 const double l = sqrt( (dx*dx+dy*dy+dz*dz)-(t*t)/v_2 );
669 const double pmag=sqrt(y[3]*y[3]+y[4]*y[4]+y[5]*y[5]);
670 for(int j=0;j<3;j++){
671 double g=0;
672 for(int k=0;k<3;k++) g+=A[j][k]*d[k];
673 Y+=y[j+3]*g;
674 }
675 Y=Y/pmag/l;
676 }
677 if(Y1*Y<0){ //Y->Y2
678 Y2=Y;
679 for(unsigned i=0;i<6;i++) y2[i]=y[i];
680 maxStep=step;
681 }else{ //Y->Y1
682 Y1=Y;
683 for(unsigned i=0;i<6;i++) y1[i]=y[i];
684 minStep=step;
685 }
686 if(Y1==Y2) break;
687 }
688 step2=step_old;
689 */
690 // Newton method
691 double y[6];
692 for ( unsigned i = 0; i < 6; i++ ) y[i] = _y[stepNum][i];
693 // memcpy(y,_y[stepNum],sizeof(double)*6);
694 double step2 = 0;
695 const double A[3][3] = { { 1 - vx * vx / v_2, -vx * vy / v_2, -vx * vz / v_2 },
696 { -vy * vx / v_2, 1 - vy * vy / v_2, -vy * vz / v_2 },
697 { -vz * vx / v_2, -vz * vy / v_2, 1 - vz * vz / v_2 } };
698 double factor = 1;
699 double g[3];
700 double f[6];
701 double Af[3], Af2[3];
702 unsigned i, j, k;
703 HepPoint3D point, onwir;
704 for ( i = 0; i < 10; i++ )
705 {
706 // cout<<"TR::line "<<y[0]<<","<<y[1]<<","<<y[2]<<","<<y[3]<<","<<y[4]<<","<<y[5]<<endl;
707 const double dx = y[0] - w0x;
708 const double dy = y[1] - w0y;
709 const double dz = y[2] - w0z;
710 const double t = ( dx * vx + dy * vy + dz * vz ) / v_2;
711 const double d[3] = { dx - t * vx, dy - t * vy, dz - t * vz };
712 // const double l2 = (dx*dx+dy*dy+dz*dz)-(t*t)/v_2;
713 HepVector3D zv;
714 zv.setX( 0 );
715 zv.setY( 0 );
716 zv.setZ( 1 );
717 HepVector3D hitv = t * v;
718 point.setX( y[0] );
719 point.setY( y[1] );
720 point.setZ( y[2] );
721 double zwir = hitv.dot( zv ) + w0z;
722 double dtll = DisToWire( l, zwir, point, onwir );
723 const double l2 = dtll * dtll;
724 for ( j = 0; j < 3; j++ )
725 {
726 g[j] = 0;
727 for ( k = 0; k < 3; k++ ) g[j] += A[j][k] * d[k];
728 }
729 // cout<<"g="<<g[0]<<","<<g[1]<<","<<g[2]<<endl;
730 Function( y, f );
731 // cout<<"f="<<f[0]<<","<<f[1]<<","<<f[2]<<","<<f[3]<<","<<f[4]<<","<<f[5]<<endl;
732 // cout<<"A="<<A[0][0]<<","<<A[0][1]<<","<<A[0][2]<<endl;
733 // cout<<"A="<<A[1][0]<<","<<A[1][1]<<","<<A[1][2]<<endl;
734 // cout<<"A="<<A[2][0]<<","<<A[2][1]<<","<<A[2][2]<<endl;
735 double Y = 0;
736 for ( j = 0; j < 3; j++ ) Y += y[j + 3] * g[j];
737 double dYds = 0;
738 for ( j = 0; j < 3; j++ ) dYds += f[j + 3] * g[j];
739 // cout<<"dYds="<<dYds<<endl;
740 for ( j = 0; j < 3; j++ )
741 {
742 Af[j] = 0;
743 Af2[j] = 0;
744 }
745 for ( j = 0; j < 3; j++ )
746 {
747 // Af[j]=0;
748 // Af2[j]=0;
749 for ( k = 0; k < 3; k++ ) Af[j] += ( A[j][k] * f[k] );
750 for ( k = 0; k < 3; k++ ) Af2[j] += ( A[j][k] * Af[k] );
751 dYds += y[j + 3] * Af2[j];
752 // cout<<j<<" dYds="<<dYds<<endl;
753 }
754 // cout<<"dYds="<<dYds<<endl;
755 const double step = -Y / dYds * factor;
756 // cout<<"TR step="<<step<<" i="<<i<<endl;
757 if ( fabs( step ) < 0.00001 ) break; // step < 1 [um]
758 if ( l2 > l2_old ) factor /= 2;
759 l2_old = l2;
760 Propagate( y, step, material );
761 step2 += step;
762 }
763
764 tof += step2 * tof_factor;
765
766 onTrack.setX( y[0] );
767 onTrack.setY( y[1] );
768 onTrack.setZ( y[2] );
769 p.setX( y[3] );
770 p.setY( y[4] );
771 p.setZ( y[5] );
772
773 const double dx = y[0] - w0x;
774 const double dy = y[1] - w0y;
775 const double dz = y[2] - w0z;
776 const double s = ( dx * vx + dy * vy + dz * vz ) / v_2;
777 // onLine.setX(w0x+s*vx);
778 // onLine.setY(w0y+s*vy);
779 // onLine.setZ(w0z+s*vz);
780 onLine.setX( onwir.x() );
781 onLine.setY( onwir.y() );
782 onLine.setZ( onwir.z() );
783 return ( 0 );
784}
785
787 const RkFitMaterial material ) {
788 if ( _Nstep == 0 )
789 {
790 if ( _stepSize == 0 ) Fly_SC();
791 else Fly( material );
792 }
793
794 double x0 = p0.x();
795 double y0 = p0.y();
796 double z0 = p0.z();
797
798 // tof=0;
799 // const float clight=29.9792458; //[cm/ns]
800 // const float M2=_mass*_mass;
801
802 // search for the closest point in cache
803 unsigned stepNum;
804 double l2_old = DBL_MAX;
805 for ( stepNum = 0; stepNum < _Nstep; stepNum++ )
806 {
807 double l2 = ( _y[stepNum][0] - x0 ) * ( _y[stepNum][0] - x0 ) +
808 ( _y[stepNum][1] - y0 ) * ( _y[stepNum][1] - y0 ) +
809 ( _y[stepNum][2] - z0 ) * ( _y[stepNum][2] - z0 );
810 if ( l2 > l2_old ) break;
811 l2_old = l2;
812 // const double p2 = _y[stepNum][3]*_y[stepNum][3]+
813 // _y[stepNum][4]*_y[stepNum][4]+
814 // _y[stepNum][5]*_y[stepNum][5];
815 // tof+=_stepSize/clight*sqrt(1+M2/p2);
816 }
817 if ( stepNum >= _Nstep ) return ( -1 ); // not found
818 stepNum--;
819
820 // propagate the track and search for the closest point
821 double y[6], y_old[6];
822 for ( unsigned i = 0; i < 6; i++ ) y[i] = _y[stepNum][i];
823 double step = _stepSize;
824 for ( ;; )
825 {
826 for ( unsigned i = 0; i < 6; i++ ) y_old[i] = y[i];
827 Propagate( y, step, material );
828 double l2 = ( y[0] - x0 ) * ( y[0] - x0 ) + ( y[1] - y0 ) * ( y[1] - y0 ) +
829 ( y[2] - z0 ) * ( y[2] - z0 );
830 if ( l2 > l2_old )
831 { // back
832 for ( unsigned i = 0; i < 6; i++ ) y[i] = y_old[i];
833 }
834 else
835 { // propagate
836 l2_old = l2;
837 // const double p2=y[3]*y[3]+y[4]*y[4]+y[5]*y[5];
838 // tof+=step/clight*sqrt(1+M2/p2);
839 }
840 step /= 2;
841 if ( step < 0.0001 ) break; // step < 1 [um]
842 }
843
844 onTrack.setX( y[0] );
845 onTrack.setY( y[1] );
846 onTrack.setZ( y[2] );
847 // p.setX(y[3]);
848 // p.setY(y[4]);
849 // p.setZ(y[5]);
850 return ( 0 );
851}
852
853unsigned TRunge::Fly( const RkFitMaterial material ) {
854 double y[6];
855 unsigned Nstep;
856 double flightlength;
857
858 flightlength = 0;
859 SetFirst( y );
860 for ( Nstep = 0; Nstep < TRunge_MAXstep; Nstep++ )
861 {
862 for ( unsigned j = 0; j < 6; j++ ) _y[Nstep][j] = y[j];
863 // memcpy(_y[Nstep],y,sizeof(double)*6);
864
865 Propagate( y, _stepSize, material );
866
867 if ( y[2] > 160 || y[2] < -80 || ( y[0] * y[0] + y[1] * y[1] ) > 8100 ) break;
868 // if position is out side of MDC, stop to fly
869 // R>90cm, z<-80cm,160cm<z
870
871 flightlength += _stepSize;
872 if ( flightlength > _maxflightlength ) break;
873
874 _h[Nstep] = _stepSize;
875 }
876 _Nstep = Nstep + 1;
877 return ( _Nstep );
878}
879
880void TRunge::Propagate( double y[6], const double& step, const RkFitMaterial material ) {
881 // y[6] = (x,y,z,px,py,pz)
882 double f1[6], f2[6], f3[6], f4[6], yt[6];
883 double hh;
884 double h6;
885 unsigned i;
886 const double mpi = 0.13957;
887 double me = 0.000511;
888 // eloss(step,&material, me,y,0);
889 hh = step * 0.5;
890 // cout<<"TR:Pro hh="<<hh<<endl;
891 Function( y, f1 );
892 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * f1[i];
893 //{
894 // register double *a=y;
895 // register double *b=f1;
896 // register double *t=yt;
897 // register double *e=y+6;
898 // for(;a<e;a++,b++,t++) (*t)=(*a)+hh*(*b);
899 //}
900 Function( yt, f2 );
901 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * f2[i];
902 //{
903 // register double *a=y;
904 // register double *b=f2;
905 // register double *t=yt;
906 // register double *e=y+6;
907 // for(;a<e;a++,b++,t++) (*t)=(*a)+hh*(*b);
908 //}
909 Function( yt, f3 );
910 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + step * f3[i];
911 //{
912 // register double *a=y;
913 // register double *b=f3;
914 // register double *t=yt;
915 // register double *e=y+6;
916 // for(;a<e;a++,b++,t++) (*t)=(*a)+step*(*b);
917 //}
918 Function( yt, f4 );
919
920 h6 = step / 6;
921 for ( i = 0; i < 6; i++ ) y[i] += h6 * ( f1[i] + 2 * f2[i] + 2 * f3[i] + f4[i] );
922 //{
923 // register double *a=f1;
924 // register double *b=f2;
925 // register double *c=f3;
926 // register double *d=f4;
927 // register double *t=y;
928 // register double *e=y+6;
929 // for(;t<e;a++,b++,c++,d++,t++)
930 // (*t)+=h6*((*a)+2*(*b)+2*(*c)+(*d));
931 //}
932}
933
934void TRunge::Function( const double y[6], double f[6] ) {
935 // return the value of formula
936 // y[6] = (x,y,z,px,py,pz)
937 // f[6] = ( dx[3]/ds, dp[3]/ds )
938 // dx/ds = p/|p|
939 // dp/ds = e/|e| 1/alpha (p x B)/|p||B|
940 // alpha = 1/cB = 333.5640952/B[Tesla] [cm/(GeV/c)]
941 // const float Bx = _bfield->bx(y[0],y[1],y[2]);
942 // const float By = _bfield->by(y[0],y[1],y[2]);
943 // const float Bz = _bfield->bz(y[0],y[1],y[2]); //[kGauss]
944 double pmag;
945 double factor;
946 HepVector3D B;
947 HepPoint3D pos;
948 pos.setX( (float)y[0] );
949 pos.setY( (float)y[1] );
950 pos.setZ( (float)y[2] );
951 // cout<<"TR::pos="<<pos[0]<<","<<pos[1]<<","<<pos[2]<<endl;
952 // _bfield->fieldMap(pos,B);
953 // cout<<"TR::B="<<B[0]<<","<<B[1]<<","<<B[2]<<endl;
954 // const double Bmag = sqrt(Bx*Bx+By*By+Bz*Bz);
955 getPmgnIMF()->fieldVector( 10 * pos, B );
956 pmag = sqrt( y[3] * y[3] + y[4] * y[4] + y[5] * y[5] );
957 f[0] = y[3] / pmag; // p/|p|
958 f[1] = y[4] / pmag;
959 f[2] = y[5] / pmag;
960
961 // const factor = _charge/(alpha2/Bmag)/pmag/Bmag;
962 // factor = ((double)_charge)/alpha2/10.; //[(GeV/c)/(cm kG)]
963 // factor = ((double)_charge)/(333.564095/(-1000*(getPmgnIMF()->getReferField())))/10.;
964 // //[(GeV/c)/(cm kG)]
965 double Bmag = sqrt( B.x() * B.x() + B.y() * B.y() + B.z() * B.z() );
966 factor = ( (double)_charge ) / ( 0.333564095 );
967 // f[3] = factor*(f[1]*Bz-f[2]*By);
968 // f[4] = factor*(f[2]*Bx-f[0]*Bz);
969 // f[5] = factor*(f[0]*By-f[1]*Bx);
970 f[3] = factor * ( f[1] * B.z() - f[2] * B.y() );
971 f[4] = factor * ( f[2] * B.x() - f[0] * B.z() );
972 f[5] = factor * ( f[0] * B.y() - f[1] * B.x() );
973}
974
975void TRunge::SetFirst( double y[6] ) const {
976 // y[6] = (x,y,z,px,py,pz)
977 const double cosPhi0 = cos( _a[1] );
978 const double sinPhi0 = sin( _a[1] );
979 const double invKappa = 1 / abs( _a[2] );
980
981 y[0] = _pivot.x() + _a[0] * cosPhi0; // x
982 y[1] = _pivot.y() + _a[0] * sinPhi0; // y
983 y[2] = _pivot.z() + _a[3]; // z
984 y[3] = -sinPhi0 * invKappa; // px
985 y[4] = cosPhi0 * invKappa; // py
986 y[5] = _a[4] * invKappa; // pz
987}
988
989// const double alpha = alpha2/1.5; //[cm/(GeV/c)] #### 1.5T fix ####!!!!
990// The unit of kappa is defined by this constant. [about 1/(GeV/c)]
991
992unsigned TRunge::Nstep( void ) const { return ( _Nstep ); }
993
994int TRunge::GetXP( unsigned stepNum, double y[6] ) const {
995 if ( stepNum >= _Nstep || stepNum >= TRunge_MAXstep ) return ( -1 );
996
997 for ( unsigned i = 0; i < 6; i++ ) y[i] = _y[stepNum][i];
998 return ( 0 );
999}
1000int TRunge::GetStep( unsigned stepNum, double& step ) const {
1001 if ( stepNum >= _Nstep || stepNum >= TRunge_MAXstep ) return ( -1 );
1002 step = _h[stepNum];
1003 return ( 0 );
1004}
1005
1006void TRunge::Propagate1( const double y[6], const double dydx[6], const double& step,
1007 double yout[6] ) {
1008 // y[6] = (x,y,z,px,py,pz)
1009 double f2[6], f3[6], f4[6], yt[6];
1010 double hh;
1011 double h6;
1012 unsigned i;
1013
1014 hh = step * 0.5;
1015 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * dydx[i]; // 1st step
1016 //{
1017 // const register double *a=y;
1018 // const register double *b=dydx;
1019 // register double *t=yt;
1020 // const register double *e=y+6;
1021 // for(;a<e;a++,b++,t++) (*t)=(*a)+hh*(*b);
1022 //}
1023 Function( yt, f2 ); // 2nd step
1024 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + hh * f2[i];
1025 //{
1026 // const register double *a=y;
1027 // const register double *b=f2;
1028 // register double *t=yt;
1029 // const register double *e=y+6;
1030 // for(;a<e;a++,b++,t++) (*t)=(*a)+hh*(*b);
1031 //}
1032 Function( yt, f3 ); // 3rd step
1033 for ( i = 0; i < 6; i++ ) yt[i] = y[i] + step * f3[i];
1034 //{
1035 // const register double *a=y;
1036 // const register double *b=f3;
1037 // register double *t=yt;
1038 // const register double *e=y+6;
1039 // for(;a<e;a++,b++,t++) (*t)=(*a)+step*(*b);
1040 //}
1041 Function( yt, f4 ); // 4th step
1042
1043 h6 = step / 6;
1044 for ( i = 0; i < 6; i++ ) yout[i] = y[i] + h6 * ( dydx[i] + 2 * f2[i] + 2 * f3[i] + f4[i] );
1045 //{
1046 // const register double *a=dydx;
1047 // const register double *b=f2;
1048 // const register double *c=f3;
1049 // const register double *d=f4;
1050 // const register double *e=y;
1051 // register double *t=yout;
1052 // const register double *s=yout+6;
1053 // for(;t<s;a++,b++,c++,d++,e++,t++)
1054 // (*t)=(*e)+h6*((*a)+2*(*b)+2*(*c)+(*d));
1055 //}
1056}
1057
1058#define PGROW -0.20
1059#define PSHRNK -0.25
1060#define FCOR 0.06666666 // 1.0/15.0
1061#define SAFETY 0.9
1062#define ERRCON 6.0e-4 // (4/SAFETY)^(1/PGROW)
1063void TRunge::Propagate_QC( double y[6], double dydx[6], const double& steptry,
1064 const double& eps, const double yscal[6], double& stepdid,
1065 double& stepnext ) {
1066 // propagate with quality check, step will be scaled automatically
1067 double ysav[6], dysav[6], ytemp[6];
1068 double h, hh, errmax, temp;
1069 unsigned i;
1070
1071 for ( i = 0; i < 6; i++ ) ysav[i] = y[i];
1072 // memcpy(ysav,y,sizeof(double)*6);
1073 for ( i = 0; i < 6; i++ ) dysav[i] = dydx[i];
1074 // memcpy(dysav,dydx,sizeof(double)*6);
1075
1076 h = steptry;
1077 for ( ;; )
1078 {
1079 hh = h * 0.5; // 2 half step
1080 Propagate1( ysav, dysav, hh, ytemp );
1081 Function( ytemp, dydx );
1082 Propagate1( ytemp, dydx, hh, y );
1083 // if check step size
1084 Propagate1( ysav, dysav, h, ytemp ); // 1 full step
1085 // error calculation
1086 errmax = 0.0;
1087 for ( i = 0; i < 6; i++ )
1088 {
1089 ytemp[i] = y[i] - ytemp[i];
1090 temp = fabs( ytemp[i] / yscal[i] );
1091 if ( errmax < temp ) errmax = temp;
1092 }
1093 // cout<<"TR: errmax="<<errmax<<endl;
1094 errmax /= eps;
1095 if ( errmax <= 1.0 )
1096 { // step O.K. calc. for next step
1097 stepdid = h;
1098 stepnext = ( errmax > ERRCON ? SAFETY * h * exp( PGROW * log( errmax ) ) : 4.0 * h );
1099 break;
1100 }
1101 h = SAFETY * h * exp( PSHRNK * log( errmax ) );
1102 }
1103 for ( i = 0; i < 6; i++ ) y[i] += ytemp[i] * FCOR;
1104 //{
1105 // register double *a=ytemp;
1106 // register double *t=y;
1107 // register double *e=y+6;
1108 // for(;t<e;a++,t++) (*t)+=(*a)*FCOR;
1109 //}
1110}
1111
1112#define TINY 1.0e-30
1113// #define EPS 1.0e-6
1114unsigned TRunge::Fly_SC( void ) { // fly the particle track with stepsize control
1115 double y[6], dydx[6], yscal[6];
1116 unsigned Nstep;
1117 double step, stepdid, stepnext;
1118 unsigned i;
1119 double flightlength;
1120
1121 // yscal[0]=0.1; //1mm -> error = 1mm*EPS
1122 // yscal[1]=0.1; //1mm
1123 // yscal[2]=0.1; //1mm
1124 // yscal[3]=0.001; //1MeV
1125 // yscal[4]=0.001; //1MeV
1126 // yscal[5]=0.001; //1MeV
1127
1128 step = default_stepSize0;
1129 flightlength = 0;
1130 SetFirst( y );
1131 for ( Nstep = 0; Nstep < TRunge_MAXstep; Nstep++ )
1132 {
1133 for ( i = 0; i < 6; i++ ) _y[Nstep][i] = y[i]; // save each step
1134 // memcpy(_y[Nstep],y,sizeof(double)*6);
1135
1136 Function( y, dydx );
1137 // for(i=0;i<6;i++) yscal[i]=abs(y[i])+abs(dydx[i]*step)+TINY;
1138
1139 Propagate_QC( y, dydx, step, _eps, _yscal, stepdid, stepnext );
1140
1141 if ( y[2] > 160 || y[2] < -80 || ( y[0] * y[0] + y[1] * y[1] ) > 8100 ) break;
1142 // if position is out side of MDC, stop to fly
1143 // R>90cm, z<-80cm,160cm<z
1144
1145 flightlength += stepdid;
1146 if ( flightlength > _maxflightlength ) break;
1147
1148 _h[Nstep] = stepdid;
1149 // cout<<"TR:"<<Nstep<<":step="<<stepdid<<endl;
1150 if ( stepnext < _stepSizeMin ) step = _stepSizeMin;
1151 else if ( stepnext > _stepSizeMax ) step = _stepSizeMax;
1152 else step = stepnext;
1153 }
1154 _Nstep = Nstep + 1;
1155 // cout<<"TR: Nstep="<<_Nstep<<endl;
1156 return ( _Nstep );
1157}
1158
1160
1161 // get a list of links to a wire hit
1162 const AList<TMLink>& cores = this->cores();
1163 // cout<<"TR:: cores.length="<<cores.length()<<endl;
1164
1165 const Helix hel( this->helix() );
1166 double tanl = hel.tanl();
1167 // double curv=hel.curv();
1168 // double rho = Helix::ConstantAlpha / hel.kappa();
1169 // double rho = 333.564095 / hel.kappa();
1170 const double Bz = 1000 * getPmgnIMF()->getReferField();
1171 double rho = 333.564095 / ( hel.kappa() * Bz );
1172
1173 // search max phi
1174 double phi_max = -DBL_MAX;
1175 double phi_min = DBL_MAX;
1176 // loop over link
1177 for ( int j = 0; j < cores.length(); j++ )
1178 {
1179 TMLink& l = *cores[j];
1180 // fitting valid?
1181 const TMDCWire& wire = *l.wire();
1182 double Wz = 0;
1183 // double mindist;
1184 HepPoint3D onWire;
1185 HepPoint3D dummy_bP;
1186 HepVector3D dummy_dir;
1187 Helix th( hel );
1188 for ( int i = 0; i < 10; i++ )
1189 {
1190 wire.wirePosition( Wz, onWire, dummy_bP, dummy_dir );
1191 th.pivot( onWire );
1192 if ( abs( th.dz() ) < 0.1 )
1193 { //<1mm
1194 // mindist=abs(hel.dr());
1195 break;
1196 }
1197 Wz += th.dz();
1198 }
1199 // onWire is closest point , th.x() is closest point on trk
1200 // Wz is z position of closest point
1201 // Z->dphi
1202 /*
1203 // Calculate position (x,y,z) along helix.
1204 // x = x0 + dr * cos(phi0) + (alpha / kappa) * (cos(phi0) - cos(phi0+phi))
1205 // y = y0 + dr * sin(phi0) + (alpha / kappa) * (sin(phi0) - sin(phi0+phi))
1206 // z = z0 + dz - (alpha / kappa) * tan(lambda) * phi
1207 cout<<"TR:: Wz="<<Wz<<" tanl="<<tanl<<endl;
1208 double phi=( hel.pivot().z()+hel.dz()-Wz )/( curv*tanl );
1209 */
1210 //...Cal. dPhi to rotate...
1211 const HepPoint3D& xc = hel.center();
1212 const HepPoint3D& xt = hel.x();
1213 HepVector3D v0, v1;
1214 v0 = xt - xc;
1215 v1 = th.x() - xc;
1216 const double vCrs = v0.x() * v1.y() - v0.y() * v1.x();
1217 const double vDot = v0.x() * v1.x() + v0.y() * v1.y();
1218 double phi = atan2( vCrs, vDot );
1219
1220 double tz = hel.x( phi ).z();
1221 // cout<<"TR:: Wz="<<Wz<<" tz="<<tz<<endl;
1222
1223 if ( phi > phi_max ) phi_max = phi;
1224 if ( phi < phi_min ) phi_min = phi;
1225 // cout<<"TR:: phi="<<phi<<endl;
1226 }
1227 // cout<<"TR:: phi_max="<<phi_max<<" phi_min="<<phi_min
1228 // <<" rho="<<rho<<" tanl="<<tanl<<endl;
1229 // phi->length, set max filght length
1230 // tanl*=1.2; // for mergin
1231 _maxflightlength =
1232 abs( rho * ( phi_max - phi_min ) * sqrt( 1 + tanl * tanl ) ) * 1.2; // x1.1 mergin
1233
1234 return ( _maxflightlength );
1235}
1236double TRunge::DisToWire( TMLink& l, double z, HepPoint3D a,
1237 HepPoint3D& b ) { // by liucy 2011/7/28
1238 double zinter[400];
1239 double ddist = 999;
1240 double finalz = 0;
1241 const TMDCWire& w = *l.wire();
1242 HepPoint3D onwire;
1243 // for(int i=0;i<20;i++){
1244 // zinter[i]=z-0.0002*i+0.002;
1245 HepPoint3D point = w.xyPosition( z );
1246 // HepPoint3D point=w.xyPosition(zinter[i]);
1247 onwire.setX( point.x() );
1248 onwire.setY( point.y() );
1249 // onwire.setZ(zinter[i]);
1250 onwire.setZ( z );
1251 // double
1252 // dist=sqrt((point.x()-a.x())*(point.x()-a.x())+(point.y()-a.y())*(point.y()-a.y())+(zinter[i]-a.z())*(zinter[i]-a.z()));
1253 double dist =
1254 sqrt( ( point.x() - a.x() ) * ( point.x() - a.x() ) +
1255 ( point.y() - a.y() ) * ( point.y() - a.y() ) + ( z - a.z() ) * ( z - a.z() ) );
1256 if ( dist < ddist )
1257 {
1258 ddist = dist;
1259 // finalz=zinter[i];
1260 b = onwire;
1261 }
1262 // }
1263 return ddist;
1264}
1265double TRunge::dEpath( double mass, double path, double p ) const {
1266 double z = 4.72234;
1267 double a = 9.29212;
1268 double Density = 0.00085144;
1269 double coeff = Density * z / a;
1270 double i = 51.4709;
1271 double isq = i * i * 1e-18;
1272 // double sigma0_2 = 0.1569*coeff*path;
1273 //
1274 // if (sigma0_2<0) return 0;
1275 //
1276 // double psq = p * p;
1277 // double bsq = psq / (psq + mass * mass);
1278 //
1279 // // Correction for relativistic particles :
1280 // double sigma_2 = sigma0_2*(1-0.5*bsq)/(1-bsq);
1281 //
1282 // if (sigma_2<0) return 0;
1283 //
1284 // // Return sigma in GeV !!
1285 // return sqrt(sigma_2)*0.001;
1286 const double Me = 0.000510999;
1287 double psq = p * p;
1288 double bsq = psq / ( psq + mass * mass );
1289 double esq = psq / ( mass * mass );
1290
1291 double s = Me / mass;
1292 double w = ( 4 * Me * esq / ( 1 + 2 * s * sqrt( 1 + esq ) + s * s ) );
1293
1294 // Density correction :
1295 double cc, x0;
1296 cc = 1 + 2 * log( sqrt( isq ) / ( 28.8E-09 * sqrt( coeff ) ) );
1297 if ( cc < 5.215 ) x0 = 0.2;
1298 else x0 = 0.326 * cc - 1.5;
1299 double x1( 3 ), xa( cc / 4.606 ), aa;
1300 aa = 4.606 * ( xa - x0 ) / ( ( x1 - x0 ) * ( x1 - x0 ) * ( x1 - x0 ) );
1301 double delta( 0 );
1302 double x( log10( sqrt( esq ) ) );
1303 if ( x > x0 )
1304 {
1305 delta = 4.606 * x - cc;
1306 if ( x < x1 ) delta = delta + aa * ( x1 - x ) * ( x1 - x ) * ( x1 - x );
1307 }
1308
1309 // Shell correction :
1310 float f1, f2, f3, f4, f5, ce;
1311 f1 = 1 / esq;
1312 f2 = f1 * f1;
1313 f3 = f1 * f2;
1314 f4 = ( f1 * 0.42237 + f2 * 0.0304 - f3 * 0.00038 ) * 1E12;
1315 f5 = ( f1 * 3.858 - f2 * 0.1668 + f3 * 0.00158 ) * 1E18;
1316 ce = f4 * isq + f5 * isq * sqrt( isq );
1317
1318 return ( 0.0001535 * coeff / bsq *
1319 ( log( Me * esq * w / isq ) - 2 * bsq - delta - 2.0 * ce / z ) ) *
1320 path;
1321}
1322void TRunge::eloss( double path, const RkFitMaterial* materiral, double mass, double y[6],
1323 int index ) const {
1324 double psq = y[5] * y[5] + y[3] * y[3] + y[4] * y[4];
1325
1326 double p = sqrt( psq );
1327
1328 double dE = materiral->dE( mass, path, p );
1329 if ( index > 0 ) psq += dE * ( dE + 2 * sqrt( mass * mass + psq ) );
1330 else psq += dE * ( dE - 2 * sqrt( mass * mass + psq ) );
1331 double pnew = sqrt( psq );
1332 double coeff = pnew / p;
1333
1334 y[3] = y[3] * coeff;
1335 y[4] = y[4] * coeff;
1336 y[5] = y[5] * coeff;
1337}
1338double TRunge::intersect_cylinder( double r ) const {
1339 double m_rad = helix().radius();
1340 double l = helix().center().perp();
1341 double cosPhi = ( m_rad * m_rad + l * l - r * r ) / ( 2 * m_rad * l );
1342
1343 if ( cosPhi < -1 || cosPhi > 1 ) return 0.;
1344
1345 double dPhi = helix().center().phi() - acos( cosPhi ) - helix().phi0();
1346 if ( dPhi < -M_PI ) dPhi += 2 * M_PI;
1347
1348 return dPhi;
1349}
1350double TRunge::intersect_zx_plane( const HepTransform3D& plane, double y ) const {
1351 HepPoint3D xc = plane * helix().center();
1352 double r = helix().radius();
1353 double d = r * r - ( y - xc.y() ) * ( y - xc.y() );
1354 if ( d < 0 ) return 0;
1355
1356 double xx = xc.x();
1357 if ( xx > 0 ) xx -= sqrt( d );
1358 else xx += sqrt( d );
1359
1360 double l = ( plane.inverse() * HepPoint3D( xx, y, 0 ) ).perp();
1361
1362 return intersect_cylinder( l );
1363}
1364
1365double TRunge::intersect_yz_plane( const HepTransform3D& plane, double x ) const {
1366 HepPoint3D xc = plane * helix().center();
1367 double r = helix().radius();
1368 double d = r * r - ( x - xc.x() ) * ( x - xc.x() );
1369 if ( d < 0 ) return 0;
1370
1371 double yy = xc.y();
1372 if ( yy > 0 ) yy -= sqrt( d );
1373 else yy += sqrt( d );
1374
1375 double l = ( plane.inverse() * HepPoint3D( x, yy, 0 ) ).perp();
1376
1377 return intersect_cylinder( l );
1378}
1379
1380double TRunge::intersect_xy_plane( double z ) const {
1381 if ( helix().tanl() != 0 && helix().radius() != 0 )
1382 return ( helix().pivot().z() + helix().dz() - z ) / ( helix().radius() * helix().tanl() );
1383 else return 0;
1384}
1385
1386IBesMagFieldSvc* TRunge::getPmgnIMF() const {
1387 if ( nullptr == m_pmgnIMF )
1388 {
1389 StatusCode sc = Gaudi::svcLocator()->service( "MagneticFieldSvc", m_pmgnIMF );
1390 if ( sc.isFailure() )
1391 { std::cout << "Unable to open Magnetic field service" << std::endl; }
1392 }
1393 return m_pmgnIMF;
1394}
double p2[4]
double mass
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")
TFile * f1
Double_t x[10]
EvtComplex exp(const EvtComplex &c)
double mpi
double me
double w
EvtTensor3C eps(const EvtVector3R &v)
XmlRpcServer s
const HepPoint3D ORIGIN
Constants.
Definition TMDCUtil.cxx:47
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
Definition KarLud.h:35
HepGeom::Point3D< double > HepPoint3D
HepGeom::Vector3D< double > HepVector3D
#define M_PI
Definition TConstant.h:4
#define FCOR
Definition TRunge.cxx:1060
const double default_maxflightlength
Definition TRunge.cxx:44
const double default_stepSize0
Definition TRunge.cxx:38
const double default_stepSizeMin
Definition TRunge.cxx:40
const double default_stepSize
Definition TRunge.cxx:37
#define SAFETY
Definition TRunge.cxx:1061
const double default_stepSizeMax
Definition TRunge.cxx:39
#define ERRCON
Definition TRunge.cxx:1062
#define PSHRNK
Definition TRunge.cxx:1059
#define PGROW
Definition TRunge.cxx:1058
const double EPS
Definition TRunge.cxx:42
static Bfield * getBfield(int)
returns Bfield object.
const HepPoint3D & center(void) const
returns position of helix center(z = 0.);
const HepSymMatrix & Ea(void) const
returns error matrix.
HepPoint3D x(double dPhi=0.) const
returns position after rotating angle dPhi in phi direction.
double radius(void) const
returns radious of helix.
const HepVector & a(void) const
returns helix parameters.
const HepPoint3D & pivot(void) const
returns pivot position.
double dE(double mass, double path, double p) const
Calculate energy loss.
void wirePosition(float zPosition, HepPoint3D &xyPosition, HepPoint3D &backwardPosition, HepVector3D &direction) const
calculates position and direction vector with sag correction.
Definition TMDCWire.cxx:542
A class to fit a TTrackBase object to a 3D line.
double dr(void) const
Track parameters (at pivot).
Definition TRunge.cxx:237
int GetXP(unsigned stepNum, double y[6]) const
Definition TRunge.cxx:994
double kappa(void) const
Definition TRunge.cxx:241
double MaxFlightLength(void) const
return max flight length
Definition TRunge.cxx:279
Helix helix(void) const
returns helix class
Definition TRunge.cxx:253
void SetFirst(double y[6]) const
set first point (position, momentum) s=0, phi=0
Definition TRunge.cxx:975
unsigned Nstep(void) const
access to trajectory cache
Definition TRunge.cxx:992
double phi0(void) const
Definition TRunge.cxx:239
double intersect_yz_plane(const HepTransform3D &plane, double x) const
Definition TRunge.cxx:1365
const Vector & a(void) const
returns helix parameter
Definition TRunge.cxx:249
~TRunge()
Destructor.
Definition TRunge.cxx:235
void eloss(double path, const RkFitMaterial *material, double mass, double y[6], int index) const
Definition TRunge.cxx:1322
double intersect_xy_plane(double z) const
Definition TRunge.cxx:1380
double SetFlightLength(void)
set flight length using wire hits
Definition TRunge.cxx:1159
int approach_point(TMLink &, const HepPoint3D &, HepPoint3D &onTrack, const RkFitMaterial material)
caluculate closest point between a point and this track
Definition TRunge.cxx:786
double intersect_zx_plane(const HepTransform3D &plane, double y) const
Definition TRunge.cxx:1350
double DisToWire(TMLink &, double, HepPoint3D, HepPoint3D &)
Definition TRunge.cxx:1236
void Propagate_QC(double y[6], double dydx[6], const double &steptry, const double &eps, const double yscal[6], double &stepdid, double &stepnext)
Definition TRunge.cxx:1063
int approach(TMLink &, const RkFitMaterial, bool sagCorrection=true)
Definition TRunge.cxx:354
void Propagate1(const double y[6], const double dydx[6], const double &step, double yout[6])
Definition TRunge.cxx:1006
double StepSize(void) const
returns step size
Definition TRunge.cxx:270
const double * Yscal(void) const
return error parameters for fitting with step size control
Definition TRunge.cxx:272
double StepSizeMax(void) const
Definition TRunge.cxx:274
double dz(void) const
Definition TRunge.cxx:243
double Eps(void) const
Definition TRunge.cxx:273
int approach_line(TMLink &, const HepPoint3D &, const HepVector3D &, HepPoint3D &onLine, HepPoint3D &onTrack, const RkFitMaterial material)
caluculate closest points between a line and this track
Definition TRunge.cxx:426
const SymMatrix & Ea(void) const
returns error matrix
Definition TRunge.cxx:251
const HepPoint3D & pivot(void) const
pivot position
Definition TRunge.cxx:247
void Propagate(double y[6], const double &step, const RkFitMaterial material)
propagate the track using 4th-order Runge-Kutta method
Definition TRunge.cxx:880
double reducedchi2(void) const
returns reduced-chi2
Definition TRunge.cxx:259
float Mass(void) const
return mass
Definition TRunge.cxx:277
TRunge()
Constructors.
Definition TRunge.cxx:46
int BfieldID(void) const
returns B field ID
Definition TRunge.cxx:268
void Function(const double y[6], double f[6])
Definition TRunge.cxx:934
double StepSizeMin(void) const
Definition TRunge.cxx:275
int GetStep(unsigned stepNum, double &step) const
Definition TRunge.cxx:1000
double tanl(void) const
Definition TRunge.cxx:245
double dEpath(double, double, double) const
Definition TRunge.cxx:1265
unsigned Fly_SC(void)
Definition TRunge.cxx:1114
unsigned Fly(const RkFitMaterial material)
make the trajectory in cache, return the number of step
Definition TRunge.cxx:853
unsigned ndf(void) const
returns NDF
Definition TRunge.cxx:255
double chi2(void) const
returns chi2.
Definition TRunge.cxx:257
double intersect_cylinder(double r) const
Definition TRunge.cxx:1338
const TMFitter *const fitter(void) const
returns a pointer to a default fitter.
TTrackBase()
Constructor.
const AList< TMLink > & cores(unsigned mask=0) const
returns a list of masked TMLinks for fit. 'mask' will be applied if mask is not 0.
A class to represent a track in tracking.
int t()
Definition t.c:1