00001
00002
00003
00004 #include "GaudiKernel/IMagneticFieldSvc.h"
00005 #include "GaudiKernel/ToolFactory.h"
00006
00007
00008
00009
00010
00011
00012
00013 #include "Event/TrackParameters.h"
00014
00015
00016 #include "TrackHerabExtrapolator.h"
00017
00018
00019 static const ToolFactory<TrackHerabExtrapolator> s_factory;
00020 const IToolFactory& TrackHerabExtrapolatorFactory = s_factory;
00021
00034
00035 TrackHerabExtrapolator::TrackHerabExtrapolator(const std::string& type,
00036 const std::string& name,
00037 const IInterface* parent):
00038 TrackExtrapolator(type, name, parent)
00039 {
00040 declareInterface<ITrackExtrapolator>( this );
00041
00042 m_stepMin = 200.*mm;
00043 m_stepMinRK5 = 20. * mm;
00044 m_qpCurls = 0.02 ;
00045
00046 declareProperty( "extrapolatorID" , m_extrapolatorID = 5);
00047 declareProperty( "requiredPrecision" , m_error = 0.005*mm );
00048
00049 }
00050
00051 StatusCode TrackHerabExtrapolator::initialize() {
00052
00053 StatusCode sc = GaudiTool::initialize();
00054 if (sc.isFailure()){
00055 return Error("Failed to initialize", sc);
00056 }
00057
00058 m_pIMF = svc<IMagneticFieldSvc>( "MagneticFieldSvc",true);
00059
00060
00061
00062 debug() << "Load field map" << endreq;
00063 HepPoint3D P( 0., 0., 0. );
00064 m_pIMF->fieldVector( P, m_B );
00065
00066 return StatusCode::SUCCESS;
00067 }
00068
00069
00071 TrackHerabExtrapolator::~TrackHerabExtrapolator()
00072 {
00073 }
00074
00075 StatusCode TrackHerabExtrapolator::propagate( State& state,
00076 double zNew,
00077 ParticleID )
00078 {
00079
00080 size_t ndim = state.nParameters();
00081
00082
00083 m_F = HepMatrix(ndim, ndim, 1);
00084
00085
00086 double dz = fabs(zNew - state.z());
00087 if (dz < TrackParameters::hiTolerance) {
00088
00089 return StatusCode::SUCCESS;
00090 }
00091
00092
00093 HepVector& tX = state.state();
00094 double pIn[5];
00095 int i;
00096 for (i = 0; i < 5; ++i) {
00097 pIn[i] = tX[i];
00098 }
00099
00100
00101 double fQp[25];
00102
00103 for (i = 0; i < 25; ++i) {
00104 fQp[i] = 0.;
00105 }
00106 double pOut[5] ={0.,0.,0.,0.,0.};
00107 int istat = 0;
00108
00109 double zIn = state.z();
00110
00111
00112 this->extrapolate(zIn,pIn,zNew,pOut,fQp,istat);
00113
00114
00115 if (istat != 0){
00116 warning() <<"Runga kutta: transport impossible "<<endreq;
00117 if (istat == 1) warning() <<"curling track"<<endreq;
00118 return StatusCode::FAILURE;
00119 }
00120
00121
00122 for (i = 0; i < 5; ++i) {
00123 tX[i] = pOut[i];
00124 }
00125
00126 int j;
00127
00128 for (i = 0; i < 5; ++i) {
00129 for (j = 0; j < 5; ++j) {
00130 m_F[i][j] = fQp[(5*j)+i];
00131 }
00132 }
00133
00134
00135 HepSymMatrix& tC = state.covariance();
00136 tC = tC.similarity(m_F);
00137
00138
00139 state.setZ(zNew);
00140
00141 return StatusCode::SUCCESS;
00142 }
00143
00144 void TrackHerabExtrapolator::extrapolate(double& zIn,double pIn[5],
00145 double& zNew,
00146 double pOut[5], double fQp[25],
00147 int& istat) {
00148
00149
00150
00151 switch ( m_extrapolatorID ) {
00152
00153 case 1:
00154 rk4fast(zIn,pIn,zNew,pOut,fQp,istat);
00155 break;
00156
00157 case 2:
00158 rk4order(zIn,pIn,zNew,pOut,fQp,istat);
00159 break;
00160
00161 case 3:
00162 rk5fast(zIn,pIn,m_error,zNew,pOut,fQp,istat);
00163 break;
00164
00165 case 4:
00166 rk5order(zIn,pIn,m_error,zNew,pOut,fQp,istat);
00167 break;
00168
00169 case 5:
00170 rk5numde(zIn,pIn,m_error,zNew,pOut,fQp,istat);
00171 break;
00172
00173 default:
00174 warning() << "Incorrect Extrapolator name - taking rk5order !!!!"
00175 << endreq;
00176 rk5order(zIn,pIn,m_error,zNew,pOut,fQp,istat);
00177 break;
00178 }
00179
00180 }
00181
00182
00183
00184
00185
00186
00187 void TrackHerabExtrapolator::rk5order(
00188 double& z_in ,
00189 double* p_in,
00190 double& error,
00191 double& z_out,
00192 double* p_out,
00193 double* rkd,
00194 int& ierror)
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 {
00212 static double a[6] = {0.0, 0.2, 0.3, 0.6, 1.0, 7.0/8.0};
00213 static double c[6] = {37.0/378.0, 0.0, 250.0/621.0, 125.0/594.0, 0.,
00214 512.0/1771.0};
00215 static double c1[6] = {2825.0/27648.0, 0., 18575.0/48384.0, 13525.0/55296.0,
00216 277.0/14336.0,1.0/4.0};
00217 static double b[16] = {0.0, 1.0/5.0, 3.0/40.0, 9.0/40.0, 3.0/10.0,
00218 -9.0/10.0, 6.0/5.0,
00219 -11.0/54.0, 5.0/2.0, -70.0/27.0, 35.0f/27.0,
00220 1631.0/55296.0, 175.0/512.0, 575.0/13824.0,
00221 44275.0/110592.0, 253.0/4096.0};
00222
00223 double qp,hC,h;
00224 double k[24],x0[4],x[4],k1[24];
00225 double tx,ty,tx2,ty2,txty,tx2ty2,tx2ty2qp,tx2ty21,I_tx2ty2,I_tx2ty21;
00226 double Ax[6],Ay[6],Ax_tx[6],Ay_tx[6],Ax_ty[6],Ay_ty[6];
00227
00228 int step_j,step4;
00229 double p1_out[5],z2_out,p2_out[5],rkd1[25],rkd2[25];
00230
00231
00232
00233 if (msgLevel(MSG::DEBUG)){
00234 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
00235 z_in, z_out, p_in[0], p_in[1]) << endreq;
00236 }
00237
00238 qp = p_in[4];
00239 ierror = (fabs(qp) > m_qpCurls) ? 1 : 0;
00240 h = z_out - z_in;
00241 hC = h * c_light;
00242
00243 x0[0] = p_in[0];
00244 x0[1] = p_in[1];
00245 x0[2] = p_in[2];
00246 x0[3] = p_in[3];
00247
00248
00249
00250
00251
00252 int i, j, step;
00253
00254 for (step = 0; step < 6; ++step) {
00255 for(i=0; i < 4; ++i) {
00256 x[i] = x0[i]; step_j = ((step-1)*step)/2 + 1;
00257 for(j=0; j < step; ++j) {
00258 x[i] += b[step_j + j] * k[j*4+i];
00259 }
00260 }
00261
00262 m_point.setX( x[0] );
00263 m_point.setY( x[1] );
00264 m_point.setZ( z_in + a[step] * h );
00265 m_pIMF->fieldVector( m_point, m_B );
00266
00267 tx = x[2]; ty = x[3]; tx2 = tx * tx; ty2 = ty * ty; txty = tx * ty;
00268 tx2ty21= 1.0 + tx2 + ty2; I_tx2ty21 = 1.0 / tx2ty21 * qp;
00269 tx2ty2 = sqrt(tx2ty21 ) ; I_tx2ty2 = qp * hC / tx2ty2 ;
00270 tx2ty2 *= hC; tx2ty2qp = tx2ty2 * qp;
00271
00272 Ax[step] = ( txty*m_B.x() + ty*m_B.z() - ( 1.0 + tx2 )*m_B.y() ) * tx2ty2;
00273 Ay[step] = (-txty*m_B.y() - tx*m_B.z() + ( 1.0 + ty2 )*m_B.x() ) * tx2ty2;
00274
00275 Ax_tx[step] = Ax[step]*tx*I_tx2ty21 + (ty*m_B.x()-2.*tx*m_B.y())*tx2ty2qp;
00276 Ax_ty[step] = Ax[step]*ty*I_tx2ty21 + (tx*m_B.x()+m_B.z())*tx2ty2qp;
00277 Ay_tx[step] = Ay[step]*tx*I_tx2ty21 + (-ty*m_B.y()-m_B.z())*tx2ty2qp;
00278 Ay_ty[step] = Ay[step]*ty*I_tx2ty21 + (-tx*m_B.y()+2.*ty*m_B.x())*tx2ty2qp;
00279
00280 step4 = step * 4;
00281 k[step4 ] = tx * h;
00282 k[step4+1] = ty * h;
00283 k[step4+2] = Ax[step] * qp;
00284 k[step4+3] = Ay[step] * qp;
00285
00286 }
00287
00288 for(i=0; i < 4; ++i) {
00289 p_out[i]=x0[i]+c[0]*k[i]+c[2]*k[8+i]+c[3]*k[12+i]+c[5]*k[20+i];
00290 }
00291 p_out[4]=p_in[4];
00292
00293
00294
00295
00296
00297
00298
00299 for (i = 0; i < 2; ++i) {
00300 p1_out[i]=x0[i]+c1[0]*k[i]+c1[2]*k[8+i]+c1[3]*k[12+i]+c1[4]*k[16+i]
00301 +c1[5]*k[20+i];
00302 }
00303
00304
00305
00306
00307
00308 x0[0] = 0.; x0[1] = 0.; x0[2] = 0.; x0[3] = 0.;
00309
00310
00311
00312
00313 for (step = 0; step < 6; ++step) {
00314 for(i=0; i < 4; ++i) {
00315 x[i] = x0[i]; step_j = ((step-1)*step)/2 + 1;
00316 for(j=0; j < step; ++j) {
00317 x[i] += b[step_j + j] * k1[j*4+i];
00318 }
00319 }
00320 step4 = step * 4;
00321 k1[step4 ] = x[2] * h;
00322 k1[step4+1] = x[3] * h;
00323 k1[step4+2] = Ax[step] + Ax_tx[step] * x[2] + Ax_ty[step] * x[3];
00324 k1[step4+3] = Ay[step] + Ay_tx[step] * x[2] + Ay_ty[step] * x[3];
00325
00326 }
00327
00328 for (i = 0; i < 4; ++i ) {
00329 rkd[20+i]=x0[i]+c[0]*k1[i]+c[2]*k1[8+i]+c[3]*k1[12+i]+c[5]*k1[20+i];
00330 }
00331 rkd[24] = 1.;
00332
00333
00334
00335
00336
00337
00338 x0[0] = 0.0; x0[1] = 0.0; x0[2] = 1.0; x0[3] = 0.0;
00339
00340
00341
00342
00343
00344 for (step = 0; step < 6; ++step) {
00345 for(i=0; i < 4; ++i) {
00346 x[i] = x0[i]; step_j = ((step-1)*step)/2 + 1;
00347 for(j=0; j < step; ++j) {
00348 if(i != 2) {x[i] += b[step_j + j] * k1[j*4+i];}
00349 }
00350 }
00351 step4 = step * 4;
00352 k1[step4 ] = x[2] * h;
00353 k1[step4+1] = x[3] * h;
00354
00355 k1[step4+3] = Ay_tx[step] * x[2] + Ay_ty[step] * x[3];
00356
00357 }
00358
00359 for (i = 0; i < 4; ++i ) {
00360 if(i != 2) {
00361 rkd[10+i]=x0[i]+c[0]*k1[i]+c[2]*k1[8+i]+c[3]*k1[12+i]+c[5]*k1[20+i];
00362 }
00363 }
00364
00365 rkd[12] = 1.;
00366 rkd[14] = 0.;
00367
00368
00369
00370
00371 x0[0] = 0; x0[1] = 0.; x0[2] = 0.; x0[3] = 1.;
00372
00373
00374
00375
00376
00377 for (step = 0; step < 6; ++step) {
00378 for(i=0; i < 4; ++i) {
00379 x[i] = x0[i]; step_j = ((step-1)*step)/2 + 1;
00380 for(j=0; j < step; ++j) {
00381 if( i != 3){ x[i] += b[step_j + j] * k1[j*4+i];}
00382 }
00383 }
00384 step4 = step * 4;
00385 k1[step4 ] = x[2] * h;
00386 k1[step4+1] = x[3] * h;
00387 k1[step4+2] = Ax_tx[step] * x[2] + Ax_ty[step] * x[3];
00388
00389
00390 }
00391
00392 for (i = 0; i < 3; ++i ) {
00393 rkd[15+i]=x0[i]+c[0]*k1[i]+c[2]*k1[8+i]+c[3]*k1[12+i]+c[5]*k1[20+i];
00394 }
00395
00396 rkd[18] = 1.;
00397 rkd[19] = 0.;
00398
00399
00400
00401
00402 for(i = 0; i < 10; ++i){ rkd[i] = 0.;}
00403 rkd[0] = 1.; rkd[6] = 1.;
00404
00405
00406
00407
00408
00409 if( (fabs(p1_out[0]-p_out[0]) > error ) ||
00410 (fabs(p1_out[1]-p_out[1]) > error ) ) {
00411 if(fabs(h) > m_stepMinRK5 ) {
00412 z2_out = z_in + 0.5 * h;
00413 rk5order(z_in , p_in, error, z2_out, p2_out, rkd1, ierror);
00414 rk5order(z2_out, p2_out, error, z_out, p_out , rkd2, ierror);
00415
00416 rkd[0] = 1.; rkd[1] = 0.; rkd[2] = 0.; rkd[3] = 0.; rkd[4] = 0;
00417 rkd[5] = 0.; rkd[6] = 1.; rkd[7] = 0.; rkd[8] = 0.; rkd[4] = 0;
00418 rkd[10] = rkd1[10] + rkd2[10] + rkd2[15] * rkd1[13];
00419 rkd[11] = rkd1[11] + rkd2[11] + rkd2[16] * rkd1[13];
00420 rkd[12] = 1.;
00421 rkd[13] = rkd2[13] + rkd1[13];
00422 rkd[14] = 0.;
00423 rkd[15] = rkd1[15] + rkd2[10] * rkd1[17] + rkd2[15];
00424 rkd[16] = rkd1[16] + rkd2[11] * rkd1[17] + rkd2[16];
00425 rkd[17] = rkd1[17] + rkd2[17];
00426 rkd[18] = 1.;
00427 rkd[19] = 0.;
00428 rkd[20] = rkd1[20] + rkd2[10] * rkd1[22] + rkd2[15] * rkd1[23]
00429 +rkd2[20];
00430 rkd[21] = rkd1[21] + rkd2[11] * rkd1[22] + rkd2[16] * rkd1[23]
00431 +rkd2[21];
00432 rkd[22] = rkd1[22] + rkd2[17] * rkd1[23]
00433 +rkd2[22];
00434 rkd[23] = rkd2[13] * rkd1[22] + rkd1[23]
00435 +rkd2[23];
00436 rkd[24] = 1.;
00437
00438 }
00439
00440 }
00441
00442 }
00443
00444
00445
00446
00447
00448 void TrackHerabExtrapolator::rk5fast(
00449
00450 double& z_in ,
00451 double* p_in,
00452 double& error,
00453 double& z_out,
00454 double* p_out,
00455 double* rkd,
00456 int& ierror)
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 {
00474
00475 static double a[6] = {0.0, 0.2, 0.3, 0.6, 1.0, 7.0/8.0};
00476 static double c[6] = {37.0/378.0, 0.0, 250.0/621.0, 125.0/594.0, 0.0,
00477 512.0/1771.0};
00478 static double c1[6] = {2825.0/27648.0, 0.0, 18575.0/48384.0, 13525.0/55296.0,
00479 277.0/14336.,1.0/4.0};
00480 static double b[16] = {0.0, 1.0/5.0, 3.0/40.0, 9.0/40.0, 3.0/10.0, -9.0/10.0,
00481 6.0/5.0,
00482 -11.0/54.0, 5.0/2.0, -70.0/27.0, 35.0/27.0,
00483 1631.0/55296.0, 175.0/512.0, 575.0/13824.0,
00484 44275.0/110592.0, 253.0/4096.0};
00485
00486 int step_j,step4;
00487 double qp,hC,h;
00488 double k[24],x0[4],x[4],k1[24];
00489 double tx,ty,tx2,ty2,txty,tx2ty2;
00490 double Ax[6],Ay[6];
00491
00492 double p1_out[5],z2_out,p2_out[5];
00493
00494
00495 if (msgLevel(MSG::DEBUG)){
00496 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
00497 z_in, z_out, p_in[0], p_in[1]) << endreq;
00498 }
00499
00500 qp = p_in[4];
00501 ierror = (fabs(qp) > m_qpCurls) ? 1 : 0;
00502 h = z_out - z_in;
00503 hC = h * c_light;
00504
00505 x0[0] = p_in[0];
00506 x0[1] = p_in[1];
00507 x0[2] = p_in[2];
00508 x0[3] = p_in[3];
00509
00510
00511
00512
00513
00514 int i, j, step;
00515
00516 for (step = 0; step < 6; ++step){
00517 for(i=0; i < 4; ++i){
00518 x[i] = x0[i]; step_j = ((step-1)*step)/2 + 1;
00519 for(j=0; j < step; ++j){
00520 x[i] += b[step_j + j] * k[j*4+i];
00521 }
00522 }
00523
00524 m_point.setX( x[0] );
00525 m_point.setY( x[1] );
00526 m_point.setZ( z_in + a[step] * h );
00527 m_pIMF->fieldVector( m_point, m_B );
00528
00529 tx = x[2]; ty = x[3]; tx2 = tx * tx; ty2 = ty * ty; txty = tx * ty;
00530 tx2ty2 = sqrt( 1.0 + tx2 + ty2 ) * hC;
00531
00532 Ax[step] = ( txty*m_B.x() + ty*m_B.z() - ( 1.0 + tx2 )*m_B.y() ) * tx2ty2;
00533 Ay[step] = (-txty*m_B.y() - tx*m_B.z() + ( 1.0 + ty2 )*m_B.x() ) * tx2ty2;
00534
00535 step4 = step * 4;
00536 k[step4 ] = tx * h;
00537 k[step4+1] = ty * h;
00538 k[step4+2] = Ax[step] * qp;
00539 k[step4+3] = Ay[step] * qp;
00540
00541 }
00542
00543 for(i=0; i < 4; ++i){
00544 p_out[i]=x0[i]+c[0]*k[i]+c[2]*k[8+i]+c[3]*k[12+i]+c[5]*k[20+i];
00545 }
00546 p_out[4]=p_in[4];
00547
00548
00549
00550
00551 p1_out[0]=x0[0]+c1[0]*k[0]+c1[2]*k[8]+c1[3]*k[12]+c1[4]*k[16]+c1[5]*k[20];
00552
00553
00554
00555
00556
00557
00558 for (step = 0; step < 6; ++step) {
00559 x[0] = 0.0; step_j = ((step-1)*step)/2 + 1;
00560 for(j=0; j < step; ++j) {
00561 x[0] += b[step_j + j] * k1[j*4 ];
00562 }
00563 x[2] = 0.0; step_j = ((step-1)*step)/2 + 1;
00564 for(j=0; j < step; ++j) {
00565 x[2] += b[step_j + j] * k1[j*4+2];
00566 }
00567
00568 step4 = step * 4;
00569 k1[step4 ] = x[2] * h;
00570 k1[step4+2] = Ax[step];
00571
00572 }
00573
00574 rkd[20]=c[0]*k1[0]+c[2]*k1[8 ]+c[3]*k1[12]+c[5]*k1[20];
00575 rkd[21]=0.;
00576 rkd[22]=c[0]*k1[2]+c[2]*k1[10]+c[3]*k1[14]+c[5]*k1[22];
00577 rkd[23]=0.;
00578 rkd[24] = 1.;
00579
00580
00581
00582
00583
00584
00585 for(i = 0; i <= 19; ++i){
00586 rkd[i] = 0.;
00587 }
00588
00589 rkd[0] = 1.;
00590 rkd[6] = 1.;
00591 rkd[10] = h;
00592 rkd[12] = 1.;
00593 rkd[16] = h;
00594 rkd[18] = 1.;
00595
00596
00597
00598 if ( fabs(p1_out[0]-p_out[0]) > error ){
00599
00600 if(fabs(h) > m_stepMin *3.){
00601 z2_out = z_in + 0.5 * h;
00602 rk5fast(z_in , p_in, error, z2_out, p2_out);
00603 rk5fast(z2_out, p2_out, error, z_out, p_out );
00604 }
00605 else if(fabs(h) > m_stepMin){
00606 z2_out = z_in + 0.5 * h;
00607 rk4fast(z_in , p_in, z2_out, p2_out);
00608 rk4fast(z2_out, p2_out, z_out, p_out );
00609 }
00610 }
00611
00612 }
00613
00614
00615
00616
00617 void TrackHerabExtrapolator::rk5fast(
00618 double& z_in ,
00619 double* p_in,
00620 double& error,
00621 double& z_out,
00622 double* p_out )
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 {
00640
00641 static double a[6] = {0.0, 0.2, 0.3, 0.6, 1.0, 7.0/8.0};
00642 static double c[6] = {37.0/378.0, 0.0, 250.0/621.0, 125.0/594.0, 0.0,
00643 512.0/1771.0};
00644 static double c1[6] = {2825.0/27648.0, 0.0, 18575.0/48384.0, 13525.0/55296.0,
00645 277.0/14336.0,1.0/4.0};
00646 static double b[16] = {0.0, 1.0/5.0, 3.0/40.0, 9.0/40.0, 3.0/10.0, -9.0/10.0,
00647 6.0/5.0,
00648 -11.0/54.0, 5.0/2.0, -70.0/27.0, 35.0/27.0,
00649 1631.0/55296., 175.0/512.0, 575.0/13824.0,
00650 44275.0/110592.0, 253.0/4096.0};
00651
00652 int step_j,step4;
00653 double qp,hC,h;
00654 double k[24],x0[4],x[4];
00655 double tx,ty,tx2,ty2,txty,tx2ty2;
00656 double Ax[6],Ay[6];
00657
00658 double p1_out[5],z2_out,p2_out[5];
00659
00660
00661
00662 if (msgLevel(MSG::DEBUG)){
00663 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
00664 z_in, z_out, p_in[0], p_in[1]) << endreq;
00665 }
00666
00667 qp = p_in[4];
00668 h = z_out - z_in;
00669 hC = h * c_light;
00670
00671 x0[0] = p_in[0];
00672 x0[1] = p_in[1];
00673 x0[2] = p_in[2];
00674 x0[3] = p_in[3];
00675
00676
00677
00678
00679
00680 int i,j,step;
00681
00682 for (step = 0; step < 6; ++step){
00683 for(i=0; i < 4; ++i){
00684 x[i] = x0[i]; step_j = ((step-1)*step)/2 + 1;
00685 for(j=0; j < step; ++j){
00686 x[i] += b[step_j + j] * k[j*4+i];
00687 }
00688 }
00689
00690 m_point.setX( x[0] );
00691 m_point.setY( x[1] );
00692 m_point.setZ( z_in + a[step] * h );
00693 m_pIMF->fieldVector( m_point, m_B );
00694
00695 tx = x[2];
00696 ty = x[3];
00697 tx2 = tx * tx;
00698 ty2 = ty * ty;
00699 txty = tx * ty;
00700 tx2ty2 = sqrt( 1.0 + tx2 + ty2 ) * hC;
00701 Ax[step] = ( txty*m_B.x() + ty*m_B.z() - ( 1.0 + tx2 )*m_B.y() ) * tx2ty2;
00702 Ay[step] = (-txty*m_B.y() - tx*m_B.z() + ( 1.0 + ty2 )*m_B.x() ) * tx2ty2;
00703
00704 step4 = step * 4;
00705 k[step4 ] = tx * h;
00706 k[step4+1] = ty * h;
00707 k[step4+2] = Ax[step] * qp;
00708 k[step4+3] = Ay[step] * qp;
00709
00710 }
00711
00712 for(i=0; i < 4; ++i){
00713 p_out[i]=x0[i]+c[0]*k[i]+c[2]*k[8+i]+c[3]*k[12+i]+c[5]*k[20+i];
00714 }
00715
00716 p_out[4]=p_in[4];
00717
00718
00719
00720
00721 p1_out[0]=x0[0]+c1[0]*k[0]+c1[2]*k[8]+c1[3]*k[12]+c1[4]*k[16]+c1[5]*k[20];
00722
00723
00724
00725
00726 if ( fabs(p1_out[0]-p_out[0]) > error ){
00727
00728 if(fabs(h) > m_stepMin *3.) {
00729 z2_out = z_in + 0.5 * h;
00730 rk5fast(z_in , p_in, error, z2_out, p2_out);
00731 rk5fast(z2_out, p2_out, error, z_out, p_out );
00732 }
00733 else if(fabs(h) > m_stepMin ){
00734 z2_out = z_in + 0.5 * h;
00735 rk4fast(z_in , p_in, z2_out, p2_out);
00736 rk4fast(z2_out, p2_out, z_out, p_out );
00737 }
00738 }
00739
00740 }
00741
00742
00743
00744
00745
00746 void TrackHerabExtrapolator::rk5numde(
00747 double& z_in ,
00748 double* p_in,
00749 double& error,
00750 double& z_out,
00751 double* p_out,
00752 double* rkd,
00753 int& ierror)
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 {
00771 double qp;
00772 static double delta[5] = {2.5, 2.5, 0.01, 0.01, 0.05};
00773 double p1_out[5],p1_in[5],d_p[5];
00774
00775
00776 int i,j;
00777
00778 if (msgLevel(MSG::DEBUG)){
00779 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
00780 z_in, z_out, p_in[0], p_in[1]) << endreq;
00781 }
00782
00783 qp = p_in[4];
00784 ierror = (fabs(qp) > m_qpCurls) ? 1 : 0;
00785
00786 rk5fast(z_in , p_in, error, z_out, p_out);
00787
00788 for(i=0; i < 4; ++i){
00789 d_p[i] = delta[i];
00790 }
00791
00792 d_p[4] = qp * delta[4];
00793
00794 for(j=0; j < 5 ; ++j){
00795
00796 for( i=0; i < 5; ++i){
00797 p1_in[i] = p_in[i];
00798 }
00799
00800 p1_in[j] += d_p[j];
00801 rk5fast(z_in , p1_in, error, z_out, p1_out);
00802
00803 for( i=0; i < 5; ++i){
00804 rkd[5*j+i] = (p1_out[i]-p_out[i])/d_p[j];
00805 }
00806 }
00807
00808 }
00809
00810
00811
00812
00813
00814 void TrackHerabExtrapolator::rk4order(
00815 double& z_in ,
00816 double* p_in,
00817 double& z_out,
00818 double* p_out,
00819 double* rkd,
00820 int& ierror)
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 {
00838
00839 static double a[4] = {0.0, 0.5, 0.5, 1.0};
00840 static double c[4] = {1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0};
00841 static double b[4] = {0.0, 0.5, 0.5, 1.0};
00842
00843 int step4;
00844 double k[16],x0[4],x[4],k1[16];
00845 double Ax[4],Ay[4],Ax_tx[4],Ay_tx[4],Ax_ty[4],Ay_ty[4];
00846
00847
00848 if (msgLevel(MSG::DEBUG)){
00849 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
00850 z_in, z_out, p_in[0], p_in[1]) << endreq;
00851 }
00852
00853 double qp = p_in[4];
00854 ierror = (fabs(qp) > m_qpCurls) ? 1 : 0;
00855 double h = z_out - z_in;
00856 double hC = h * c_light;
00857 x0[0] = p_in[0]; x0[1] = p_in[1];
00858 x0[2] = p_in[2]; x0[3] = p_in[3];
00859
00860
00861
00862
00863 int step;
00864 int i;
00865
00866 for (step = 0; step < 4; ++step) {
00867 for(i=0; i < 4; ++i) {
00868 if(step == 0) {
00869 x[i] = x0[i];
00870 } else {
00871 x[i] = x0[i] + b[step] * k[step*4-4+i];
00872 }
00873 }
00874
00875 m_point.setX( x[0] );
00876 m_point.setY( x[1] );
00877 m_point.setZ( z_in + a[step] * h );
00878 m_pIMF->fieldVector( m_point, m_B );
00879
00880 double tx = x[2];
00881 double ty = x[3];
00882 double tx2 = tx * tx;
00883 double ty2 = ty * ty;
00884 double txty = tx * ty;
00885 double tx2ty21= 1.0 + tx2 + ty2;
00886 double I_tx2ty21 = 1.0 / tx2ty21 * qp;
00887 double tx2ty2 = sqrt(tx2ty21 ) ;
00888
00889 tx2ty2 *= hC;
00890 double tx2ty2qp = tx2ty2 * qp;
00891 Ax[step] = ( txty*m_B.x() + ty*m_B.z() - ( 1.0 + tx2 )*m_B.y() ) * tx2ty2;
00892 Ay[step] = (-txty*m_B.y() - tx*m_B.z() + ( 1.0 + ty2 )*m_B.x() ) * tx2ty2;
00893
00894 Ax_tx[step] = Ax[step]*tx*I_tx2ty21 + (ty*m_B.x()-2.0*tx*m_B.y())*tx2ty2qp;
00895 Ax_ty[step] = Ax[step]*ty*I_tx2ty21 + (tx*m_B.x()+m_B.z())*tx2ty2qp;
00896 Ay_tx[step] = Ay[step]*tx*I_tx2ty21 + (-ty*m_B.y()-m_B.z())*tx2ty2qp;
00897 Ay_ty[step] = Ay[step]*ty*I_tx2ty21 + (-tx*m_B.y()+2.0*ty*m_B.x())*tx2ty2qp;
00898
00899 step4 = step * 4;
00900 k[step4 ] = tx * h;
00901 k[step4+1] = ty * h;
00902 k[step4+2] = Ax[step] * qp;
00903 k[step4+3] = Ay[step] * qp;
00904
00905 }
00906
00907 for(i=0; i < 4; ++i) {
00908 p_out[i]=x0[i]+c[0]*k[i]+c[1]*k[4+i]+c[2]*k[8+i]+c[3]*k[12+i];
00909 }
00910 p_out[4]=p_in[4];
00911
00912
00913
00914
00915 x0[0] = 0.0; x0[1] = 0.0; x0[2] = 0.0; x0[3] = 0.0;
00916
00917
00918
00919
00920 for (step = 0; step < 4; ++step) {
00921 for(i=0; i < 4; ++i) {
00922 if(step == 0) {
00923 x[i] = x0[i];
00924 } else {
00925 x[i] = x0[i] + b[step] * k1[step*4-4+i];
00926 }
00927 }
00928 step4 = step * 4;
00929 k1[step4 ] = x[2] * h;
00930 k1[step4+1] = x[3] * h;
00931 k1[step4+2] = Ax[step] + Ax_tx[step] * x[2] + Ax_ty[step] * x[3];
00932 k1[step4+3] = Ay[step] + Ay_tx[step] * x[2] + Ay_ty[step] * x[3];
00933
00934 }
00935
00936 for (i = 0; i < 4; ++i ) {
00937 rkd[20+i]=x0[i]+c[0]*k1[i]+c[1]*k1[4+i]+c[2]*k1[8+i]+c[3]*k1[12+i];
00938 }
00939 rkd[24] = 1.;
00940
00941
00942
00943
00944
00945
00946
00947 x0[0] = 0.0; x0[1] = 0.0; x0[2] = 1.0; x0[3] = 0.0;
00948
00949
00950
00951
00952
00953 for (step = 0; step < 4; ++step) {
00954 for(i=0; i < 4; ++i) {
00955 if(step == 0) {
00956 x[i] = x0[i];
00957 } else if ( i!=2 ){
00958 x[i] = x0[i] + b[step] * k1[step*4-4+i];
00959 }
00960 }
00961 step4 = step * 4;
00962 k1[step4 ] = x[2] * h;
00963 k1[step4+1] = x[3] * h;
00964
00965 k1[step4+3] = Ay_tx[step] * x[2] + Ay_ty[step] * x[3];
00966
00967 }
00968
00969 for (i = 0; i < 4; ++i ) {
00970 if(i != 2) {
00971 rkd[10+i]=x0[i]+c[0]*k1[i]+c[1]*k1[4+i]+c[2]*k1[8+i]+c[3]*k1[12+i];
00972 }
00973 }
00974
00975 rkd[12] = 1.0;
00976 rkd[14] = 0.0;
00977
00978
00979
00980
00981 x0[0] = 0.0; x0[1] = 0.0; x0[2] = 0.0; x0[3] = 1.0;
00982
00983
00984
00985
00986
00987 for (step = 0; step < 4; ++step) {
00988 for(i=0; i < 4; ++i) {
00989 if(step == 0) {
00990 x[i] = x0[i];
00991 } else if(i!=3) {
00992 x[i] = x0[i] + b[step] * k1[step*4-4+i];
00993 }
00994
00995 }
00996 step4 = step * 4;
00997 k1[step4 ] = x[2] * h;
00998 k1[step4+1] = x[3] * h;
00999 k1[step4+2] = Ax_tx[step] * x[2] + Ax_ty[step] * x[3];
01000
01001
01002 }
01003
01004 for (i = 0; i < 3; ++i ) {
01005 rkd[15+i]=x0[i]+c[0]*k1[i]+c[1]*k1[4+i]+c[2]*k1[8+i]+c[3]*k1[12+i];
01006 }
01007
01008 rkd[18] = 1.;
01009 rkd[19] = 0.;
01010
01011
01012
01013
01014 for(i = 0; i < 10; ++i){ rkd[i] = 0.;}
01015 rkd[0] = 1.; rkd[6] = 1.;
01016
01017 }
01018
01019
01020
01021
01022
01023 void TrackHerabExtrapolator::rk4fast(
01024 double& z_in ,
01025 double* p_in,
01026 double& z_out,
01027 double* p_out,
01028 double* rkd,
01029 int& ierror)
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 {
01047 static double a[4] = {0.0, 0.5, 0.5, 1.0};
01048 static double c[4] = {1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0};
01049 static double b[4] = {0.0, 0.5, 0.5, 1.0};
01050 int step4;
01051 double qp,hC,h;
01052 double k[16],x0[4],x[4],k1[16];
01053 double tx,ty,tx2,ty2,txty,tx2ty2;
01054 double Ax[4],Ay[4];
01055
01056 if (msgLevel(MSG::DEBUG)){
01057 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
01058 z_in, z_out, p_in[0], p_in[1]) << endreq;
01059 }
01060
01061 qp = p_in[4];
01062 ierror = (fabs(qp) > m_qpCurls) ? 1 : 0;
01063 h = z_out - z_in;
01064 hC = h * c_light;
01065 x0[0] = p_in[0]; x0[1] = p_in[1];
01066 x0[2] = p_in[2]; x0[3] = p_in[3];
01067
01068
01069
01070
01071 int step, i;
01072
01073 for (step = 0; step < 4; ++step) {
01074 for(i=0; i < 4; ++i) {
01075 if(step == 0) {
01076 x[i] = x0[i];
01077 } else {
01078 x[i] = x0[i] + b[step] * k[step*4-4+i];
01079 }
01080 }
01081
01082 m_point.setX( x[0] );
01083 m_point.setY( x[1] );
01084 m_point.setZ( z_in + a[step] * h );
01085 m_pIMF->fieldVector( m_point, m_B );
01086
01087 tx = x[2]; ty = x[3]; tx2 = tx * tx; ty2 = ty * ty; txty = tx * ty;
01088 tx2ty2 = sqrt( 1.0 + tx2 + ty2 ) * hC;
01089 Ax[step] = ( txty*m_B.x() + ty*m_B.z() - ( 1.0 + tx2 )*m_B.y() ) * tx2ty2;
01090 Ay[step] = (-txty*m_B.y() - tx*m_B.z() + ( 1.0 + ty2 )*m_B.x() ) * tx2ty2;
01091
01092 step4 = step * 4;
01093 k[step4 ] = tx * h;
01094 k[step4+1] = ty * h;
01095 k[step4+2] = Ax[step] * qp;
01096 k[step4+3] = Ay[step] * qp;
01097
01098 }
01099
01100 for(i=0; i < 4; ++i) {
01101 p_out[i]=x0[i]+c[0]*k[i]+c[1]*k[4+i]+c[2]*k[8+i]+c[3]*k[12+i];
01102 }
01103 p_out[4]=p_in[4];
01104
01105
01106
01107
01108
01109
01110 for (step = 0; step < 4; ++step) {
01111 for(i=0; i < 4; ++i) {
01112 if(step == 0) {
01113 x[0] = 0.0; x[2] = 0.0;
01114 } else {
01115 x[0] = b[step] * k1[step*4-4];
01116 x[2] = b[step] * k1[step*4-2];
01117 }
01118 }
01119 step4 = step * 4;
01120 k1[step4 ] = x[2] * h;
01121 k1[step4+2] = Ax[step] ;
01122
01123 }
01124
01125 rkd[20] = c[0]*k1[0]+c[1]*k1[4]+c[2]*k1[8]+c[3]*k1[12];
01126 rkd[21] = 0.;
01127 rkd[22] = c[0]*k1[2]+c[1]*k1[6]+c[2]*k1[10]+c[3]*k1[14];
01128 rkd[23] = 0.;
01129 rkd[24] = 1.;
01130
01131
01132
01133
01134
01135 for(i = 0; i <= 19; ++i){ rkd[i] = 0.;}
01136 rkd[0] = 1.; rkd[6] = 1.; rkd[10] = h;
01137 rkd[12] = 1.; rkd[16] = h; rkd[18] = 1.;
01138
01139 }
01140
01141
01142
01143
01144
01145 void TrackHerabExtrapolator::rk4fast(
01146 double& z_in ,
01147 double* p_in,
01148 double& z_out,
01149 double* p_out)
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166 {
01167 static double a[4] = {0.0, 0.5, 0.5, 1.0};
01168 static double c[4] = {1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0};
01169 static double b[4] = {0.0, 0.5, 0.5, 1.};
01170 int step4;
01171 double qp,hC,h;
01172 double k[16],x0[4],x[4];
01173 double tx,ty,tx2,ty2,txty,tx2ty2;
01174 double Ax[4],Ay[4];
01175
01176
01177 if (msgLevel(MSG::DEBUG)){
01178 debug() << format( "rk5order zIn %8.1f zOut %8.1f X %7.1f y %7.1f ",
01179 z_in, z_out, p_in[0], p_in[1]) << endreq;
01180 }
01181
01182 qp = p_in[4];
01183 h = z_out - z_in;
01184 hC = h * c_light;
01185
01186 x0[0] = p_in[0]; x0[1] = p_in[1];
01187 x0[2] = p_in[2]; x0[3] = p_in[3];
01188
01189
01190
01191
01192 int i, step;
01193
01194 for (step = 0; step < 4; ++step) {
01195 for(i=0; i < 4; ++i) {
01196 if(step == 0) {
01197 x[i] = x0[i];
01198 } else {
01199 x[i] = x0[i] + b[step] * k[step*4-4+i];
01200 }
01201 }
01202
01203 m_point.setX( x[0] );
01204 m_point.setY( x[1] );
01205 m_point.setZ( z_in + a[step] * h );
01206 m_pIMF->fieldVector( m_point, m_B );
01207
01208 tx = x[2]; ty = x[3]; tx2 = tx * tx; ty2 = ty * ty; txty = tx * ty;
01209 tx2ty2 = sqrt( 1.0 + tx2 + ty2 ) * hC;
01210 Ax[step] = ( txty*m_B.x() + ty*m_B.z() - ( 1.0 + tx2 )*m_B.y() ) * tx2ty2;
01211 Ay[step] = (-txty*m_B.y() - tx*m_B.z() + ( 1.0 + ty2 )*m_B.x() ) * tx2ty2;
01212
01213 step4 = step * 4;
01214 k[step4 ] = tx * h;
01215 k[step4+1] = ty * h;
01216 k[step4+2] = Ax[step] * qp;
01217 k[step4+3] = Ay[step] * qp;
01218
01219 }
01220 for(i=0; i < 4; ++i) {
01221 p_out[i]=x0[i]+c[0]*k[i]+c[1]*k[4+i]+c[2]*k[8+i]+c[3]*k[12+i];
01222 }
01223 p_out[4]=p_in[4];
01224
01225 }