1 package org.lcsim.recon.tracking.trfxyp; 2 3 import org.lcsim.recon.tracking.trfutil.TRFMath; 4 import org.lcsim.recon.tracking.trfutil.Assert; 5 6 import org.lcsim.recon.tracking.trfbase.Propagator; 7 import org.lcsim.recon.tracking.trfbase.PropDirected; 8 import org.lcsim.recon.tracking.trfbase.PropDir; 9 import org.lcsim.recon.tracking.trfbase.PropStat; 10 import org.lcsim.recon.tracking.trfbase.VTrack; 11 import org.lcsim.recon.tracking.trfbase.Surface; 12 import org.lcsim.recon.tracking.trfbase.TrackVector; 13 import org.lcsim.recon.tracking.trfbase.TrackDerivative; 14 15 /** 16 * Propagates tracks from one XYPlane to another in a constant field. 17 *<p> 18 * Propagation will fail if either the origin or destination is 19 * not a XYPlane. 20 * Propagator works incorrectly for tracks with very small curvatures 21 * 22 * 23 *@author Norman A. Graf 24 *@version 1.0 25 * 26 */ 27 public class PropXYXY extends PropDirected 28 { 29 30 // attributes 31 32 private double _bfac; 33 34 private static final int IV = SurfXYPlane.IV; 35 private static final int IZ = SurfXYPlane.IZ; 36 private static final int IDVDU = SurfXYPlane.IDVDU; 37 private static final int IDZDU = SurfXYPlane.IDZDU; 38 private static final int IQP = SurfXYPlane.IQP; 39 40 // static methods 41 42 /** 43 *Return a String representation of the class' type name. 44 *Included for completeness with the C++ version. 45 * 46 * @return A String representation of the class' type name. 47 */ 48 public static String typeName() 49 { return "PropXYXY"; } 50 51 /** 52 *Return a String representation of the class' type name. 53 *Included for completeness with the C++ version. 54 * 55 * @return A String representation of the class' type name. 56 */ 57 public static String staticType() 58 { return typeName(); } 59 60 61 /** 62 *Construct an instance from a constant solenoidal magnetic field in Tesla. 63 * 64 * @param bfield The magnetic field strength in Tesla. 65 */ 66 public PropXYXY(double bfield) 67 { 68 _bfac = TRFMath.BFAC*bfield; 69 } 70 71 /** 72 *Clone an instance. 73 * 74 * @return A Clone of this instance. 75 */ 76 public Propagator newPropagator( ) 77 { 78 return new PropXYXY( bField() ); 79 } 80 81 /** 82 *Propagate a track without error in the specified direction 83 *and return the derivative matrix in deriv. 84 * 85 * @param trv The VTrack to propagate. 86 * @param srf The Surface to which to propagate. 87 * @param dir The direction in which to propagate. 88 * @param deriv The track derivatives to update at the surface srf. 89 * @return The propagation status. 90 **/ 91 public PropStat vecDirProp( VTrack trv, Surface srf, 92 PropDir dir,TrackDerivative deriv ) 93 { 94 PropStat pstat = vec_propagatexyxy_( _bfac, trv, srf, dir, deriv ); 95 return pstat; 96 } 97 98 /** 99 *Propagate a track without error in the specified direction. 100 * 101 * @param trv The VTrack to propagate. 102 * @param srf The Surface to which to propagate. 103 * @param dir The direction in which to propagate. 104 * @return The propagation status. 105 */ 106 public PropStat vecDirProp( VTrack trv, Surface srf, 107 PropDir dir) 108 { 109 TrackDerivative deriv = null; 110 return vecDirProp(trv, srf, dir, deriv); 111 } 112 113 /** 114 *Return the strength of the magnetic field in Tesla. 115 * 116 * @return The strength of the magnetic field in Tesla. 117 */ 118 public double bField() 119 { 120 return _bfac/TRFMath.BFAC; 121 } 122 123 124 /** 125 *Return a String representation of the class' type name. 126 *Included for completeness with the C++ version. 127 * 128 * @return A String representation of the class' type name. 129 */ 130 public String type() 131 { return staticType(); } 132 133 134 /** 135 *output stream 136 * 137 * @return A String representation of this instance. 138 */ 139 public String toString() 140 { 141 return "XYPlane-XYPlane propagation with constant " 142 + bField() + " Tesla field"; 143 } 144 145 146 // Private function to determine dphi of the propagation 147 double direction(int flag_forward, int sign_dphi, 148 double du, 149 double norm, double cat, 150 double sinphi, double cosphi) 151 { 152 153 int sign_cat = 0; 154 if(du*flag_forward>0.) sign_cat = 1; 155 if(du*flag_forward<0.) sign_cat = -1; 156 if(du == 0.) 157 { 158 if(sinphi >=0. ) sign_cat = 1; 159 if(sinphi < 0. ) sign_cat = -1; 160 } 161 162 double sin_dphi = norm*sinphi + cat*cosphi*sign_cat; 163 double cos_dphi = -norm*cosphi + cat*sinphi*sign_cat; 164 165 int sign_sindphi = 0; 166 if(sin_dphi> 0.) sign_sindphi = 1; 167 if(sin_dphi< 0.) sign_sindphi = -1; 168 if(sin_dphi == 0.) sign_sindphi = sign_dphi; 169 170 if( Math.abs(cos_dphi)>1. ) 171 { 172 double sn= -1.; 173 if ( cos_dphi > 0 ) sn=1.; 174 cos_dphi= sn*Math.sqrt(1.-sin_dphi*sin_dphi); 175 } 176 if( Math.abs(sin_dphi)>1. ) 177 { 178 double sn= -1.; 179 if ( sin_dphi > 0 ) sn=1.; 180 sin_dphi= sn*Math.sqrt(1.-cos_dphi*cos_dphi); 181 } 182 183 double dphi = Math.PI*(sign_dphi - sign_sindphi) + sign_sindphi*Math.acos(cos_dphi); 184 return dphi; 185 186 } 187 //********************************************************************** 188 189 // Private function to propagate a track without error 190 // The corresponding track parameters are: 191 // u (cm) is fixed 192 // 0 - v (cm) 193 // 1 - z (cm) 194 // 2 - dv/du 195 // 3 - dz/du 196 // 4 - q/p p is momentum of a track, q is its charge 197 // If deriv is nonzero, return the derivative matrix there. 198 199 PropStat 200 vec_propagatexyxy_( double B, VTrack trv, Surface srf, 201 PropDir dir1, 202 TrackDerivative deriv ) 203 { 204 205 // construct return status 206 PropStat pstat = new PropStat(); 207 208 PropDir dir = dir1; //need to check constness of this 209 boolean move = Propagator.reduceDirection(dir); 210 if(move) dir = reduce(dir); 211 // fetch the originating surface and vector 212 Surface srf1 = trv.surface(); 213 // TrackVector vec1 = trv.get_vector(); 214 215 // Check origin is a XYPlane. 216 Assert.assertTrue( srf1.pureType().equals(SurfXYPlane.staticType()) ); 217 if ( !srf1.pureType( ).equals(SurfXYPlane.staticType()) ) 218 return pstat; 219 SurfXYPlane sxyp1 = (SurfXYPlane) srf1; 220 221 // Check destination is an XYPlane. 222 Assert.assertTrue( srf.pureType().equals(SurfXYPlane.staticType()) ); 223 if ( !srf.pureType( ).equals(SurfXYPlane.staticType()) ) 224 return pstat; 225 SurfXYPlane sxyp2 = (SurfXYPlane) srf; 226 227 // If surfaces are the same and no XXX_MOVE is requested we can return now. 228 boolean same = srf.pureEqual(srf1); 229 if ( same && ! move ) 230 { 231 if(deriv!=null) 232 { 233 deriv.setIdentity(); 234 } 235 pstat.setSame(); 236 return pstat; 237 } 238 239 240 if ( same && dir1.equals(PropDir.NEAREST_MOVE) ) dir = PropDir.FORWARD; 241 242 //v00.63.04 cng 01/12/01 243 if( Math.abs(B) < 1e-7 ) return zeroBField(trv,sxyp1,sxyp2,dir1,deriv); 244 245 // Fetch the u's and phi's of the planes and the starting track vector. 246 TrackVector vec = trv.vector(); 247 int iphi = SurfXYPlane.NORMPHI; 248 int idist = SurfXYPlane.DISTNORM; 249 double phi_0 = sxyp1.parameter(iphi); 250 double u_0 = sxyp1.parameter(idist); 251 double phi_n = sxyp2.parameter(iphi); 252 double u_n = sxyp2.parameter(idist); 253 if ( same && move ) 254 { 255 int forw= trv.isForward()? 1 : -1 ; 256 int forw_dir = (dir == PropDir.FORWARD) ? 1 : -1 ; 257 int sn = vec.get(IDVDU) > 0. ? 1 : -1 ; 258 u_0 += 1.e-7 * (double)(forw*forw_dir*sn); 259 } 260 261 double b1_0 = vec.get(IV); // v 262 double b2_0 = vec.get(IZ); // z 263 double b3_0 = vec.get(IDVDU); // dv/du 264 double b4_0 = vec.get(IDZDU); // dz/du 265 double b5_0 = vec.get(IQP); // q/p 266 267 double phi_u = phi_0 - phi_n; 268 269 double cosphi_u = Math.cos(phi_u); 270 double sinphi_u = Math.sin(phi_u); 271 272 // check if du == 0 ( that is track moves parallel to the destination plane ) 273 double du_du_0 = cosphi_u - b3_0*sinphi_u; 274 if(du_du_0==0.) return pstat; 275 276 double a_hat_u = 1./du_du_0; 277 double a_hat_u2 = a_hat_u*a_hat_u; 278 279 double u = u_0*cosphi_u - b1_0*sinphi_u; 280 double b1 = b1_0*cosphi_u + u_0*sinphi_u; 281 double b2 = b2_0; 282 double b3 = (b3_0*cosphi_u + sinphi_u)*a_hat_u; 283 double b4 = b4_0*a_hat_u; 284 double b5 = b5_0; 285 286 int sign_du0 = 0; 287 if(trv.isForward()) sign_du0 = 1; 288 if(trv.isBackward()) sign_du0 = -1; 289 if(sign_du0 == 0) 290 { 291 System.out.println( "PropXYXY._vec_propagate: Unknown direction of a track "); 292 System.exit(1); 293 } 294 int sign_du = 0; 295 if(du_du_0*sign_du0 > 0) sign_du = 1; 296 if(du_du_0*sign_du0 < 0) sign_du = -1; 297 298 // check that q/p != 0 299 Assert.assertTrue(b5 !=0. ); 300 301 // 1/curv of the track is r 302 double r = 1/(b5*B)*Math.sqrt(1 + b3_0*b3_0)/Math.sqrt(1 + b3_0*b3_0 + b4_0*b4_0); 303 double b3_hat = Math.sqrt(1 + b3*b3); 304 double b34_hat = Math.sqrt(1 + b3*b3 + b4*b4); 305 double b3_hat2 = b3_hat*b3_hat; 306 double b34_hat2 = b34_hat*b34_hat; 307 double cosphi = -b3*sign_du/b3_hat; 308 double sinphi = sign_du/b3_hat; 309 double rsinphi = 1./(b5*B)*sign_du/b34_hat; 310 double rcosphi = -b3/(b5*B)*sign_du/b34_hat; 311 312 double du = u_n - u; 313 double norm = du/r - cosphi; 314 315 // xy-xy propagation failed : noway to the new plane 316 if(Math.abs(norm)>1.) return pstat; 317 318 double cat = Math.sqrt(1.-norm*norm); 319 int flag_forward = 0; 320 int sign_dphi = 0; 321 322 if( dir.equals(PropDir.NEAREST)) 323 { 324 // try forward propagation 325 flag_forward = 1; 326 if(b5*B>0.) sign_dphi = 1; 327 if(b5*B<0.) sign_dphi = -1; 328 double dphi1= 329 direction(flag_forward,sign_dphi,du,norm, cat, sinphi, cosphi); 330 // try backward propagation 331 flag_forward = -1; 332 if(b5*B>0.) sign_dphi = -1; 333 if(b5*B<0.) sign_dphi = 1; 334 double dphi2= 335 direction(flag_forward,sign_dphi,du,norm, cat, sinphi, cosphi); 336 if( Math.abs(dphi2)>Math.abs(dphi1) ) 337 { 338 flag_forward = -flag_forward; 339 sign_dphi = - sign_dphi; 340 } 341 } 342 343 else if( dir.equals(PropDir.FORWARD)) 344 { 345 flag_forward = 1; 346 if(b5*B>0.) sign_dphi = 1; 347 if(b5*B<0.) sign_dphi = -1; 348 } 349 else if( dir.equals(PropDir.BACKWARD)) 350 { 351 flag_forward = -1; 352 if(b5*B>0.) sign_dphi = -1; 353 if(b5*B<0.) sign_dphi = 1; 354 } 355 else 356 { 357 System.out.println("PropXYXY._vec_propagate: Unknown direction."); 358 System.exit(1); 359 } 360 361 int sign_cat = 0; 362 if(du*sign_dphi*b5*B>0.) sign_cat = 1; 363 if(du*sign_dphi*b5*B<0.) sign_cat = -1; 364 if(du == 0.) 365 { 366 if(sinphi >=0. ) sign_cat = 1; 367 if(sinphi < 0. ) sign_cat = -1; 368 } 369 370 double sin_dphi = norm*sinphi + cat*cosphi*sign_cat; 371 double cos_dphi = -norm*cosphi + cat*sinphi*sign_cat; 372 if(cos_dphi>1.) cos_dphi=1.; 373 if(cos_dphi<-1.) cos_dphi= -1.; 374 375 int sign_sindphi = 0; 376 if(sin_dphi> 0.) sign_sindphi = 1; 377 if(sin_dphi< 0.) sign_sindphi = -1; 378 if(sin_dphi == 0.) sign_sindphi = sign_dphi; 379 380 double dphi = Math.PI*(sign_dphi - sign_sindphi) + sign_sindphi*Math.acos(cos_dphi); 381 382 // check that I didn't make any mistakes 383 384 Assert.assertTrue(Math.abs(Math.sin(dphi) - sin_dphi)<1.e-5); 385 386 // check if dun == 0 ( that is track moves parallel to the destination plane) 387 double du_n_du = cos_dphi - b3*sin_dphi; 388 if(du_n_du==0.) return pstat; 389 390 double a_hat_dphi = 1./du_n_du; 391 double a_hat_dphi2 = a_hat_dphi*a_hat_dphi; 392 double c_hat_dphi = sin_dphi + b3*cos_dphi ; 393 394 double b1_n = b1 + rsinphi*(1-cos_dphi) - rcosphi*sin_dphi; 395 double b2_n = b2 + b4/(b5*B)*sign_du/b34_hat*dphi; 396 double b3_n = c_hat_dphi*a_hat_dphi; 397 double b4_n = b4*a_hat_dphi; 398 double b5_n = b5; 399 400 // double u_n_0 = u_n*cosphi_u + b1_n*sinphi_u; 401 402 // check if track crossed original plane during the propagation 403 // switch (dir) { 404 // if( dir.equals(PropDir.FORWARD: 405 // if((u_n_0 - u_0)*sign_du0<0) return pstat; 406 // break; 407 // if( dir.equals(PropDir.BACKWARD: 408 // if((u_n_0 - u_0)*sign_du0>0) return pstat; 409 // break; 410 // } 411 412 int sign_dun = 0; 413 if(du_n_du*sign_du > 0) sign_dun = 1; 414 if(du_n_du*sign_du < 0) sign_dun = -1; 415 416 vec.set(IV ,b1_n); 417 vec.set(IZ ,b2_n); 418 vec.set(IDVDU ,b3_n); 419 vec.set(IDZDU ,b4_n); 420 vec.set(IQP ,b5_n); 421 422 // Update trv 423 trv.setSurface(srf.newPureSurface()); 424 trv.setVector(vec); 425 426 // set new direction of the track 427 if(sign_dun == 1) trv.setForward(); 428 if(sign_dun == -1) trv.setBackward(); 429 430 // Calculate sT. 431 double crv = B*b5; 432 double dv = b1_n - b1; 433 double dxy = Math.sqrt( du*du + dv*dv ); 434 double arg = 0.5*crv*dxy; 435 double dst = dxy*TRFMath.asinrat(arg); 436 437 // Calculate s. 438 double dz = b2_n - b2; 439 Assert.assertTrue( flag_forward==1 || flag_forward==-1 ); 440 double ds = ((double)(flag_forward))*Math.sqrt(dst*dst+dz*dz); 441 442 // Set the return status. 443 pstat.setPathDistance(ds); 444 //(flag_forward==1)?pstat.set_forward():pstat.set_backward(); 445 446 // exit now if user did not ask for error matrix. 447 if ( deriv == null ) return pstat; 448 449 // du_d0 450 451 double du_db1_0 = - sinphi_u; 452 453 // db1_d0 454 455 double db1_db1_0 = cosphi_u; 456 457 // db3_d0 458 459 double db3_db3_0 = a_hat_u2; 460 461 // db4_d0 462 463 double db4_db3_0 = b4_0*sinphi_u*a_hat_u2; 464 double db4_db4_0 = a_hat_u; 465 466 // dr_d 467 468 double dr_db3 = r*b3*b4*b4/(b3_hat2*b34_hat2); 469 double dr_db4 = -r*b4/b34_hat2; 470 double dr_db5 = -r/b5; 471 472 // dcosphi_d 473 474 double dcosphi_db3 = - sign_du/b3_hat - cosphi*b3/b3_hat2; 475 476 // dsinphi_d 477 478 double dsinphi_db3 = - sinphi*b3/b3_hat2; 479 480 // dcat_d 481 482 double dcat_db3 = norm/cat*(du/(r*r)*dr_db3 + dcosphi_db3 ); 483 double dcat_db4 = norm/cat* du/(r*r)*dr_db4; 484 double dcat_db5 = norm/cat* du/(r*r)*dr_db5; 485 double dcat_du = norm/(cat*r); 486 487 // dnorm_d 488 489 double dnorm_db3 = - du/(r*r)*dr_db3 - dcosphi_db3; 490 double dnorm_db4 = - du/(r*r)*dr_db4; 491 double dnorm_db5 = - du/(r*r)*dr_db5; 492 double dnorm_du = - 1./r; 493 494 // dcos_dphi_d 495 496 double dcos_dphi_db3 = - cosphi*dnorm_db3 - norm*dcosphi_db3 + 497 sign_cat*(sinphi*dcat_db3 + cat*dsinphi_db3); 498 double dcos_dphi_db4 = - cosphi*dnorm_db4 + sign_cat*sinphi*dcat_db4; 499 double dcos_dphi_db5 = - cosphi*dnorm_db5 + sign_cat*sinphi*dcat_db5; 500 double dcos_dphi_du = - cosphi*dnorm_du + sign_cat*sinphi*dcat_du; 501 502 // dsin_dphi_d 503 504 double dsin_dphi_db3 = sinphi*dnorm_db3 + norm*dsinphi_db3 + 505 sign_cat*(cosphi*dcat_db3 + cat*dcosphi_db3); 506 double dsin_dphi_db4 = sinphi*dnorm_db4 + sign_cat*cosphi*dcat_db4; 507 double dsin_dphi_db5 = sinphi*dnorm_db5 + sign_cat*cosphi*dcat_db5; 508 double dsin_dphi_du = sinphi*dnorm_du + sign_cat*cosphi*dcat_du; 509 510 // ddphi_d 511 512 double ddphi_db3; 513 double ddphi_db4; 514 double ddphi_db5; 515 double ddphi_du; 516 if(Math.abs(sin_dphi)>0.5) 517 { 518 ddphi_db3 = - dcos_dphi_db3/sin_dphi; 519 ddphi_db4 = - dcos_dphi_db4/sin_dphi; 520 ddphi_db5 = - dcos_dphi_db5/sin_dphi; 521 ddphi_du = - dcos_dphi_du /sin_dphi; 522 } 523 else 524 { 525 ddphi_db3 = dsin_dphi_db3/cos_dphi; 526 ddphi_db4 = dsin_dphi_db4/cos_dphi; 527 ddphi_db5 = dsin_dphi_db5/cos_dphi; 528 ddphi_du = dsin_dphi_du /cos_dphi; 529 } 530 531 // da_hat_dphi_d 532 533 double da_hat_dphi_db3 = - a_hat_dphi2* 534 (dcos_dphi_db3 - sin_dphi - b3*dsin_dphi_db3); 535 double da_hat_dphi_db4 = - a_hat_dphi2*(dcos_dphi_db4 - b3*dsin_dphi_db4); 536 double da_hat_dphi_db5 = - a_hat_dphi2*(dcos_dphi_db5 - b3*dsin_dphi_db5); 537 double da_hat_dphi_du = - a_hat_dphi2*(dcos_dphi_du - b3*dsin_dphi_du ); 538 539 // dc_hat_dphi_d 540 541 double dc_hat_dphi_db3 = b3*dcos_dphi_db3 + dsin_dphi_db3 + cos_dphi; 542 double dc_hat_dphi_db4 = b3*dcos_dphi_db4 + dsin_dphi_db4; 543 double dc_hat_dphi_db5 = b3*dcos_dphi_db5 + dsin_dphi_db5; 544 double dc_hat_dphi_du = b3*dcos_dphi_du + dsin_dphi_du ; 545 546 // db1_n_d 547 548 double db1_n_db1 = 1; 549 double db1_n_db3 = (dr_db3*sinphi+r*dsinphi_db3)*(1-cos_dphi) 550 - rsinphi*dcos_dphi_db3 551 - dr_db3*cosphi*sin_dphi - r*dcosphi_db3*sin_dphi 552 - rcosphi*dsin_dphi_db3; 553 double db1_n_db4 = dr_db4*sinphi*(1-cos_dphi) - rsinphi*dcos_dphi_db4 554 - dr_db4*cosphi*sin_dphi - rcosphi*dsin_dphi_db4; 555 double db1_n_db5 = dr_db5*sinphi*(1-cos_dphi) - rsinphi*dcos_dphi_db5 556 - dr_db5*cosphi*sin_dphi - rcosphi*dsin_dphi_db5; 557 double db1_n_du = - rsinphi*dcos_dphi_du - rcosphi*dsin_dphi_du; 558 559 // db2_n_d 560 561 double db2_n_db2 = 1.; 562 double db2_n_db3 = 1./(b5*B)*b4*sign_du/b34_hat* 563 ( - dphi*b3/b34_hat2 + ddphi_db3); 564 double db2_n_db4 = 1./(b5*B)*sign_du/b34_hat* 565 ( - dphi*b4*b4/b34_hat2 + b4*ddphi_db4 + dphi ); 566 double db2_n_db5 = 1./(b5*B)*b4*sign_du/b34_hat*( ddphi_db5 - dphi/b5); 567 double db2_n_du = 1./(b5*B)*b4*sign_du/b34_hat*ddphi_du; 568 569 // db3_n_d 570 571 double db3_n_db3 = a_hat_dphi*dc_hat_dphi_db3 + da_hat_dphi_db3*c_hat_dphi; 572 double db3_n_db4 = a_hat_dphi*dc_hat_dphi_db4 + da_hat_dphi_db4*c_hat_dphi; 573 double db3_n_db5 = a_hat_dphi*dc_hat_dphi_db5 + da_hat_dphi_db5*c_hat_dphi; 574 double db3_n_du = a_hat_dphi*dc_hat_dphi_du + da_hat_dphi_du *c_hat_dphi; 575 576 // db4_n_d 577 578 double db4_n_db3 = b4*da_hat_dphi_db3; 579 double db4_n_db4 = b4*da_hat_dphi_db4 + a_hat_dphi; 580 double db4_n_db5 = b4*da_hat_dphi_db5; 581 double db4_n_du = b4*da_hat_dphi_du; 582 583 // db5_n_d 584 585 // db1_n_d0 586 587 double db1_n_db1_0 = db1_n_du * du_db1_0 + db1_n_db1*db1_db1_0; 588 double db1_n_db2_0 = 0.; 589 double db1_n_db3_0 = db1_n_db3*db3_db3_0 + db1_n_db4*db4_db3_0; 590 double db1_n_db4_0 = db1_n_db4*db4_db4_0; 591 double db1_n_db5_0 = db1_n_db5; 592 593 // db2_n_d0 594 595 double db2_n_db1_0 = db2_n_du *du_db1_0; 596 double db2_n_db2_0 = db2_n_db2; 597 double db2_n_db3_0 = db2_n_db3*db3_db3_0 + db2_n_db4*db4_db3_0; 598 double db2_n_db4_0 = db2_n_db4*db4_db4_0; 599 double db2_n_db5_0 = db2_n_db5; 600 601 // db3_n_d0 602 603 double db3_n_db1_0 = db3_n_du*du_db1_0; 604 double db3_n_db2_0 = 0.; 605 double db3_n_db3_0 = db3_n_db3*db3_db3_0 + db3_n_db4*db4_db3_0; 606 double db3_n_db4_0 = db3_n_db4*db4_db4_0; 607 double db3_n_db5_0 = db3_n_db5; 608 609 // db4_n_d0 610 611 double db4_n_db1_0 = db4_n_du*du_db1_0; 612 double db4_n_db2_0 = 0.; 613 double db4_n_db3_0 = db4_n_db3*db3_db3_0 + db4_n_db4*db4_db3_0; 614 double db4_n_db4_0 = db4_n_db4*db4_db4_0; 615 double db4_n_db5_0 = db4_n_db5; 616 617 // db5_n_d0 618 619 double db5_n_db1_0 = 0.; 620 double db5_n_db2_0 = 0.; 621 double db5_n_db3_0 = 0.; 622 double db5_n_db4_0 = 0.; 623 double db5_n_db5_0 = 1.; 624 625 626 deriv.set(IV,IV ,db1_n_db1_0); 627 deriv.set(IV,IZ ,db1_n_db2_0); 628 deriv.set(IV,IDVDU ,db1_n_db3_0); 629 deriv.set(IV,IDZDU ,db1_n_db4_0); 630 deriv.set(IV,IQP ,db1_n_db5_0); 631 deriv.set(IZ,IV ,db2_n_db1_0); 632 deriv.set(IZ,IZ ,db2_n_db2_0); 633 deriv.set(IZ,IDVDU ,db2_n_db3_0); 634 deriv.set(IZ,IDZDU ,db2_n_db4_0); 635 deriv.set(IZ,IQP ,db2_n_db5_0); 636 deriv.set(IDVDU,IV ,db3_n_db1_0); 637 deriv.set(IDVDU,IZ ,db3_n_db2_0); 638 deriv.set(IDVDU,IDVDU ,db3_n_db3_0); 639 deriv.set(IDVDU,IDZDU ,db3_n_db4_0); 640 deriv.set(IDVDU,IQP ,db3_n_db5_0); 641 deriv.set(IDZDU,IV ,db4_n_db1_0); 642 deriv.set(IDZDU,IZ ,db4_n_db2_0); 643 deriv.set(IDZDU,IDVDU ,db4_n_db3_0); 644 deriv.set(IDZDU,IDZDU ,db4_n_db4_0); 645 deriv.set(IDZDU,IQP ,db4_n_db5_0); 646 deriv.set(IQP,IV ,db5_n_db1_0); 647 deriv.set(IQP,IZ ,db5_n_db2_0); 648 deriv.set(IQP,IDVDU ,db5_n_db3_0); 649 deriv.set(IQP,IDZDU ,db5_n_db4_0); 650 deriv.set(IQP,IQP ,db5_n_db5_0); 651 652 return pstat; 653 654 } 655 656 //cng 657 PropStat zeroBField( VTrack trv, SurfXYPlane sxyp1, 658 SurfXYPlane sxyp2, PropDir dir1, 659 TrackDerivative deriv) 660 { 661 // construct return status 662 PropStat pstat = new PropStat(); 663 664 PropDir dir = dir1; //need to check constness of this 665 boolean move = Propagator.reduceDirection(dir); 666 boolean same = sxyp2.pureEqual(sxyp1); 667 668 // There is only one solution. Can't XXX_MOVE 669 if ( same && move ) return pstat; 670 671 if ( same ) 672 { 673 if(deriv!=null) 674 { 675 deriv.setIdentity(); 676 } 677 pstat.setSame(); 678 return pstat; 679 } 680 681 TrackVector vec = trv.vector(); 682 double v0 = vec.get(IV); 683 double z0 = vec.get(IZ); 684 double dvdu0 = vec.get(IDVDU); 685 double dzdu0 = vec.get(IDZDU); 686 687 double du0 =1.; 688 if( trv.isBackward() ) du0 = -1.; 689 690 double phi0 = sxyp1.parameter(SurfXYPlane.NORMPHI); 691 double cphi0 = Math.cos(phi0); 692 double sphi0 = Math.sin(phi0); 693 double u0 = sxyp1.parameter(SurfXYPlane.DISTNORM); 694 695 double phi1 = sxyp2.parameter(SurfXYPlane.NORMPHI); 696 double cphi1 = Math.cos(phi1); 697 double sphi1 = Math.sin(phi1); 698 double u1 = sxyp2.parameter(SurfXYPlane.DISTNORM); 699 700 double a = (cphi0 - dvdu0*sphi0)*du0; 701 double b = (sphi0 + dvdu0*cphi0)*du0; 702 double c = dzdu0*du0; 703 704 double x0 = u0*cphi0 - v0*sphi0; 705 double y0 = u0*sphi0 + v0*cphi0; 706 707 double ap = u1*cphi1; 708 double bp = u1*sphi1; 709 double cp = 0; 710 711 double xp = ap; 712 double yp = bp; 713 double zp = 0.0; 714 715 double denom = a*ap + b*bp + c*cp; 716 717 if( denom == 0. ) return pstat; 718 719 double S = ( (xp-x0)*ap + (yp-y0)*bp + (zp-z0)*cp )/denom; 720 721 double x1 = x0 + S*a; 722 double y1 = y0 + S*b; 723 double z1 = z0 + S*c; 724 725 boolean forward = S > 0. ? true : false; 726 727 if( dir == PropDir.FORWARD && !forward ) return pstat; 728 if( dir == PropDir.BACKWARD && forward ) return pstat; 729 730 double v1 = y1*cphi1 - x1*sphi1; 731 732 double v01 = y0*cphi1 - x0*sphi1; 733 double u01 = y0*sphi1 + x0*cphi1; 734 double z01 = z0; 735 736 if( u01 == u1 ) return pstat; 737 738 double dvdu1 = (v1-v01)/(u1-u01); 739 double dzdu1 = (z1-z01)/(u1-u01); 740 741 vec.set(IV, v1); 742 vec.set(IZ, z1); 743 vec.set(IDVDU, dvdu1); 744 vec.set(IDZDU, dzdu1); 745 746 // Update trv 747 trv.setSurface(sxyp2.newPureSurface()); 748 trv.setVector(vec); 749 // set new direction of the track 750 if( b*sphi1 + a*cphi1 >0 ) trv.setForward(); 751 else trv.setBackward(); 752 753 // Calculate s. 754 double ds = S*Math.sqrt(a*a+b*b+c*c); 755 756 // Set the return status. 757 pstat.setPathDistance(ds); 758 759 if( deriv == null ) return pstat; 760 761 double dx0dv0 = -sphi0; 762 double dy0dv0 = cphi0; 763 764 double dadv_du = -sphi0*du0; 765 double dbdv_du = cphi0*du0; 766 double dcdz_du = du0; 767 768 double ddenomdv_du = dadv_du*ap + dbdv_du*bp; 769 double ddenomdz_du = dcdz_du*cp; 770 771 772 double dSdv0 = -(dx0dv0*ap + dy0dv0*bp)/denom; 773 double dSdz0 = -cp/denom; 774 double dSdv_du = -S/denom*ddenomdv_du; 775 double dSdz_du = -S/denom*ddenomdz_du; 776 777 double dy1dv0 = dy0dv0 + dSdv0*b; 778 double dx1dv0 = dx0dv0 + dSdv0*a; 779 double dx1dv_du = dSdv_du*a + S*dadv_du; 780 double dy1dv_du = dSdv_du*b + S*dbdv_du; 781 782 double du01dv0 = dy0dv0*sphi1 + dx0dv0*cphi1; 783 double dv01dv0 = dy0dv0*cphi1 - dx0dv0*sphi1; 784 785 double dv1dv0 = dy1dv0*cphi1 - dx1dv0*sphi1; 786 double dv1dv_du = dy1dv_du*cphi1 - dx1dv_du*sphi1; 787 788 double dz1dz0 = 1 + dSdz0*c; 789 double dz1dv0 = dSdv0*c; 790 double dz1dv_du = dSdv_du*c; 791 double dz1dz_du = dSdz_du*c + S*dcdz_du; 792 793 double dv_du1dv0 = ((dv1dv0-dv01dv0)*(u1-u01) + du01dv0*(v1-v01))/(u1-u01)/(u1-u01); 794 double dv_du1dv_du = dv1dv_du/(u1-u01); 795 796 double dz_du1dv0 = (dz1dv0*(u1-u01) + du01dv0*(z1-z01))/(u1-u01)/(u1-u01); 797 double dz_du1dz0 = (dz1dz0 - 1.)/(u1-u01); 798 double dz_du1dv_du = dz1dv_du/(u1-u01); 799 double dz_du1dz_du = dz1dz_du/(u1-u01); 800 801 //Set the track derivatives... 802 deriv.setIdentity(); 803 804 deriv.set(IV,IV, dv1dv0); 805 deriv.set(IV,IDVDU, dv1dv_du); 806 807 deriv.set(IZ,IV, dz1dv0); 808 deriv.set(IZ,IZ, dz1dz0); 809 deriv.set(IZ,IDVDU, dz1dv_du); 810 deriv.set(IZ,IDZDU, dz1dz_du); 811 812 deriv.set(IDVDU,IV, dv_du1dv0); 813 deriv.set(IDVDU,IDVDU, dv_du1dv_du); 814 815 deriv.set(IDZDU,IV, dz_du1dv0); 816 deriv.set(IDZDU,IZ, dz_du1dz0); 817 deriv.set(IDZDU,IDVDU, dz_du1dv_du); 818 deriv.set(IDZDU,IDZDU, dz_du1dz_du); 819 820 deriv.set(IQP,IQP, 1.0); 821 822 return pstat; 823 824 } 825 //cng 826 827 828 829 830 }