1 /* 2 * PropCylXY_Test.java 3 * 4 * Created on July 24, 2007, 10:53 PM 5 * 6 * $Id: PropCylXY_Test.java,v 1.1.1.1 2010/04/08 20:38:00 jeremy Exp $ 7 */ 8 9 package org.lcsim.recon.tracking.trfcylplane; 10 11 import junit.framework.TestCase; 12 import org.lcsim.recon.tracking.spacegeom.SpacePath; 13 import org.lcsim.recon.tracking.spacegeom.SpacePoint; 14 import org.lcsim.recon.tracking.trfbase.ETrack; 15 import org.lcsim.recon.tracking.trfbase.PropDir; 16 import org.lcsim.recon.tracking.trfbase.PropStat; 17 import org.lcsim.recon.tracking.trfbase.Propagator; 18 import org.lcsim.recon.tracking.trfbase.Surface; 19 import org.lcsim.recon.tracking.trfbase.TrackDerivative; 20 import org.lcsim.recon.tracking.trfbase.TrackError; 21 import org.lcsim.recon.tracking.trfbase.TrackVector; 22 import org.lcsim.recon.tracking.trfbase.VTrack; 23 import org.lcsim.recon.tracking.trfcyl.SurfCylinder; 24 import org.lcsim.recon.tracking.trfutil.Assert; 25 import org.lcsim.recon.tracking.trfutil.TRFMath; 26 import org.lcsim.recon.tracking.trfxyp.SurfXYPlane; 27 28 /** 29 * 30 * @author Norman Graf 31 */ 32 public class PropCylXY_Test extends TestCase 33 { 34 private boolean debug; 35 36 // Assign track parameter indices. 37 38 private static final int IV = SurfXYPlane.IV; 39 private static final int IZ = SurfXYPlane.IZ; 40 private static final int IDVDU = SurfXYPlane.IDVDU; 41 private static final int IDZDU = SurfXYPlane.IDZDU; 42 private static final int IQP_XY = SurfXYPlane.IQP; 43 44 private static final int IPHI = SurfCylinder.IPHI; 45 private static final int IZ_CYL = SurfCylinder.IZ; 46 private static final int IALF = SurfCylinder.IALF; 47 private static final int ITLM = SurfCylinder.ITLM; 48 private static final int IQPT = SurfCylinder.IQPT; 49 50 51 //************************************************************************ 52 53 // compare two tracks without errors 54 55 private double compare(VTrack trv1,VTrack trv2) 56 { 57 Surface srf = trv2.surface(); 58 59 Assert.assertTrue(trv1.surface().equals(srf)); 60 61 double diff = srf.vecDiff(trv2.vector(),trv1.vector()).amax(); 62 63 return diff; 64 } 65 66 //********************************************************************** 67 // compare two tracks with errors 68 69 private double[] compare(ETrack trv1,ETrack trv2 ) 70 { 71 double[] tmp = new double[2]; 72 Surface srf = trv2.surface(); 73 74 Assert.assertTrue(trv1.surface().equals(srf)); 75 76 tmp[0] = srf.vecDiff(trv2.vector(),trv1.vector()).amax(); 77 78 TrackError dfc = trv2.error().minus(trv1.error()); 79 tmp[1] = dfc.amax(); 80 81 82 return tmp; 83 } 84 /** Creates a new instance of PropCylXY_Test */ 85 public void testPropCylXY() 86 { 87 String ok_prefix = "PropCylXY (I): "; 88 String error_prefix = "PropCylXY test (E): "; 89 90 if(debug) System.out.println( ok_prefix 91 + "-------- Testing component PropCylXY. --------" ); 92 93 94 if(debug) System.out.println( ok_prefix + "Test constructor." ); 95 double BFIELD = 2.0; 96 PropCylXY prop = new PropCylXY(BFIELD); 97 if(debug) System.out.println( prop ); 98 99 PropCylXY_Test tst = new PropCylXY_Test(); 100 101 //******************************************************************** 102 103 // Here we propagate some tracks both forward and backward and then 104 // the same track forward and backward but using method 105 // that we checked very thoroughly before. 106 107 if(debug) System.out.println( ok_prefix + "Check against correct propagation." ); 108 109 PropCylXY propcylxy = new PropCylXY(BFIELD/TRFMath.BFAC); 110 111 double phi[] ={ Math.PI/5, Math.PI/6, Math.PI/6, 4/3*Math.PI, 5/3*Math.PI, 5/3*Math.PI }; 112 double z[] ={ 1.5, -2.3, 0., 1.5, -1.5, 1.5 }; 113 double alpha[] ={ 0.1, -0.1, 0., 0.2, -0.2, 0. }; 114 double tlm[] ={ 2.3, -1.5, -2.3, 2.3, -2.3, 0. }; 115 double qpt[] ={ 0.01, -0.01, 0.01, -0.01, -0.01, 0.01 }; 116 117 double u2b[] ={ 6., 6., 6., 6., 6., 6. }; 118 double phic2b[] ={ Math.PI/6., Math.PI/5., Math.PI/7., 5/3*Math.PI, 4/3*Math.PI, 7/4*Math.PI }; 119 double u2[] ={ 15., 15., 15., 15., 15., 15. }; 120 double phic2[] ={ Math.PI/6., Math.PI/5., Math.PI/7., 5/3*Math.PI, 4/3*Math.PI, 7/4*Math.PI }; 121 122 double maxdiff = 1.e-10; 123 double diff; 124 int ntrk = 6; 125 int i; 126 127 for ( i=0; i<ntrk; ++i ) 128 { 129 if(debug) System.out.println( "********** Propagate track " + i + ". **********" ); 130 PropStat pstat = new PropStat(); 131 SurfCylinder scy1 = new SurfCylinder(10.); 132 SurfXYPlane sxyp2 = new SurfXYPlane(u2[i],phic2[i]); 133 SurfXYPlane sxyp2b= new SurfXYPlane(u2b[i],phic2b[i]); 134 135 TrackVector vec1 = new TrackVector(); 136 137 vec1.set(IPHI , phi[i]); // phi 138 vec1.set(IZ_CYL , z[i]); // z 139 vec1.set(IALF , alpha[i]); // alpha 140 vec1.set(ITLM , tlm[i]); // tan(lambda) 141 vec1.set(IQPT , qpt[i]); // q/pt 142 143 VTrack trv1 = new VTrack(scy1.newPureSurface(),vec1); 144 145 if(debug) System.out.println( "\n starting: " + trv1 ); 146 147 148 VTrack trv2f = new VTrack(trv1); 149 pstat = propcylxy.vecDirProp(trv2f,sxyp2,PropDir.FORWARD); 150 Assert.assertTrue( pstat.forward() ); 151 if(debug) System.out.println( "\n forward: " + trv2f ); 152 153 VTrack trv2f_my = new VTrack(trv1); 154 pstat = tst.vec_propcylxy(BFIELD,trv2f_my,sxyp2,PropDir.FORWARD); 155 Assert.assertTrue( pstat.forward() ); 156 if(debug) System.out.println( "\n forward my: " + trv2f_my ); 157 diff = tst.compare(trv2f_my,trv2f); 158 159 if(debug) System.out.println( "\n diff: " + diff ); 160 Assert.assertTrue( diff < maxdiff ); 161 162 163 VTrack trv2b = new VTrack(trv1); 164 pstat = propcylxy.vecDirProp(trv2b,sxyp2b,PropDir.BACKWARD_MOVE); 165 Assert.assertTrue( pstat.backward() ); 166 if(debug) System.out.println( "\n backward: " + trv2b ); 167 168 VTrack trv2b_my = new VTrack(trv1); 169 pstat = tst.vec_propcylxy(BFIELD,trv2b_my,sxyp2b,PropDir.BACKWARD); 170 Assert.assertTrue( pstat.backward() ); 171 if(debug) System.out.println( "\n backward my: " + trv2b_my ); 172 diff = tst.compare(trv2b_my,trv2b); 173 174 if(debug) System.out.println( "\n diff: " + diff ); 175 Assert.assertTrue( diff < maxdiff ); 176 177 178 } 179 //******************************************************************** 180 181 // Repeat the above with errors. 182 if(debug) System.out.println( ok_prefix + "Check against correct propagation with errors." ); 183 184 double epp[] = { 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 }; 185 double epz[] = { 0.01, -0.01, 0.01, -0.01, 0.01, -0.01, 0.01 }; 186 double ezz[] = { 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25 }; 187 double epa[] = { 0.003, -0.003, 0.003, -0.003, 0.003, -0.003, 0.003 }; 188 double eza[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 189 double eaa[] = { 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 }; 190 double epl[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 191 double eal[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 192 double ezl[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 193 double ell[] = { 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02 }; 194 double epc[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 195 double ezc[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 196 double eac[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 197 double elc[] = { 0.004, -0.004, 0.004, -0.004, 0.004, -0.004, 0.004 }; 198 double ecc[] = { 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 }; 199 200 maxdiff = 1.e-8; 201 double ediff; 202 ntrk = 6; 203 204 for ( i=0; i<ntrk; ++i ) 205 { 206 if(debug) System.out.println( "********** Propagate track " + i + ". **********" ); 207 PropStat pstat = new PropStat(); 208 SurfCylinder scy1 = new SurfCylinder(10.); 209 SurfXYPlane sxyp2 = new SurfXYPlane(u2[i],phic2[i]); 210 SurfXYPlane sxyp2b = new SurfXYPlane(u2b[i],phic2b[i]); 211 212 TrackVector vec1 = new TrackVector(); 213 214 vec1.set(IPHI , phi[i]); // phi 215 vec1.set(IZ_CYL , z[i]); // z 216 vec1.set(IALF , alpha[i]); // alpha 217 vec1.set(ITLM , tlm[i]); // tan(lambda) 218 vec1.set(IQPT , qpt[i]); // q/pt 219 220 TrackError err1 = new TrackError(); 221 222 err1.set(IPHI,IPHI , epp[i]); 223 err1.set(IPHI,IZ_CYL , epz[i]); 224 err1.set(IZ_CYL,IZ_CYL , ezz[i]); 225 err1.set(IPHI,IALF , epa[i]); 226 err1.set(IZ_CYL,IALF , eza[i]); 227 err1.set(IALF,IALF , eaa[i]); 228 err1.set(IPHI,ITLM , epl[i]); 229 err1.set(IZ_CYL,ITLM , ezl[i]); 230 err1.set(IALF,ITLM , eal[i]); 231 err1.set(ITLM,ITLM , ell[i]); 232 err1.set(IPHI,IQPT , epc[i]); 233 err1.set(IZ_CYL,IQPT , ezc[i]); 234 err1.set(IALF,IQPT , eac[i]); 235 err1.set(ITLM,IQPT , elc[i]); 236 err1.set(IQPT,IQPT , ecc[i]); 237 238 ETrack trv1 = new ETrack(scy1.newPureSurface(),vec1,err1); 239 240 if(debug) System.out.println( "\n starting: " + trv1 ); 241 242 ETrack trv2f = new ETrack(trv1); 243 pstat = propcylxy.errDirProp(trv2f,sxyp2,PropDir.FORWARD); 244 Assert.assertTrue( pstat.forward() ); 245 if(debug) System.out.println( "\n forward: " + trv2f ); 246 247 ETrack trv2f_my = new ETrack(trv1); 248 TrackDerivative deriv = new TrackDerivative(); 249 pstat = tst.vec_propcylxy(BFIELD,trv2f_my,sxyp2,PropDir.FORWARD,deriv); 250 Assert.assertTrue( pstat.forward() ); 251 TrackError err = trv2f_my.error(); 252 trv2f_my.setError( err.Xform(deriv) ); 253 if(debug) System.out.println( "\n forward my: " + trv2f_my ); 254 double[] diffs = tst.compare(trv2f_my,trv2f); 255 256 if(debug) System.out.println( "\n diff: " + diffs[0] + ' ' + "ediff: "+ diffs[1] ); 257 Assert.assertTrue( diffs[0] < maxdiff ); 258 Assert.assertTrue( diffs[1] < maxdiff ); 259 260 261 ETrack trv2b = new ETrack(trv1); 262 pstat = propcylxy.errDirProp(trv2b,sxyp2b,PropDir.BACKWARD); 263 Assert.assertTrue( pstat.backward() ); 264 if(debug) System.out.println( "\n backward: " + trv2b ); 265 266 ETrack trv2b_my = new ETrack(trv1); 267 pstat = tst.vec_propcylxy(BFIELD,trv2b_my,sxyp2b,PropDir.BACKWARD,deriv); 268 Assert.assertTrue( pstat.backward() ); 269 err = trv2b_my.error(); 270 trv2b_my.setError( err.Xform(deriv) ); 271 if(debug) System.out.println( "\n backward my: " + trv2b_my ); 272 diffs = tst.compare(trv2b_my,trv2b); 273 274 if(debug) System.out.println( "\n diff: " + diffs[0] + ' ' + "ediff: "+ diffs[1] ); 275 Assert.assertTrue( diffs[0] < maxdiff ); 276 Assert.assertTrue( diffs[1] < maxdiff ); 277 278 279 } 280 //******************************************************************** 281 282 if(debug) System.out.println( ok_prefix + "Test cloning." ); 283 Assert.assertTrue( prop.newPropagator() != null ); 284 285 //******************************************************************** 286 287 if(debug) System.out.println( ok_prefix + "Test the field." ); 288 Assert.assertTrue( prop.bField() == 2.0 ); 289 290 //******************************************************************** 291 292 if(debug) System.out.println( ok_prefix + "Test Zero Field Propagation." ); 293 { 294 PropCylXY prop0 = new PropCylXY(0.0); 295 if(debug) System.out.println( prop0 ); 296 Assert.assertTrue( prop0.bField() == 0. ); 297 298 double u = 10.; 299 double phi2 = 0.1; 300 Surface srf = new SurfCylinder(13.0); 301 VTrack trv0 = new VTrack(srf); 302 TrackVector vec = new TrackVector(); 303 vec.set(SurfCylinder.IPHI, phi2+0.1); 304 vec.set(SurfCylinder.IZ, 10.); 305 vec.set(SurfCylinder.IALF, 0.1); 306 vec.set(SurfCylinder.ITLM, 2.); 307 vec.set(SurfCylinder.IQPT, 0.); 308 trv0.setVector(vec); 309 trv0.setForward(); 310 Surface srf_to = new SurfXYPlane(u,phi2); 311 312 VTrack trv = new VTrack(trv0); 313 VTrack trv_der = new VTrack(trv); 314 PropStat pstat = prop0.vecDirProp(trv,srf_to,PropDir.NEAREST); 315 if(debug) System.out.println("trv= \n"+trv+'\n'); 316 Assert.assertTrue( pstat.success() ); 317 318 Assert.assertTrue( pstat.backward() ); 319 Assert.assertTrue(trv.surface().pureEqual(srf_to)); 320 321 check_zero_propagation(trv0,trv,pstat); 322 check_derivatives(prop0,trv_der,srf_to); 323 } 324 325 //******************************************************************** 326 327 if(debug) System.out.println( ok_prefix 328 + "------------- All tests passed. -------------" ); 329 330 //******************************************************************** 331 } 332 333 // Very well tested Cyl-XY propagator. Each new one can be tested against it 334 PropStat 335 vec_propcylxy( double B, VTrack trv, Surface srf, 336 PropDir dir 337 ) 338 { 339 TrackDerivative deriv = null; 340 return vec_propcylxy(B, trv, srf, dir, deriv); 341 } 342 343 344 PropStat 345 vec_propcylxy( double B, VTrack trv, Surface srf, 346 PropDir dir, 347 TrackDerivative deriv ) 348 { 349 350 351 // construct return status 352 PropStat pstat = new PropStat(); 353 354 // fetch the originating surface and vector 355 Surface srf1 = trv.surface(); 356 // TrackVector vec1 = trv.vector(); 357 358 // Check origin is a Cylinder. 359 Assert.assertTrue( srf1.pureType().equals(SurfCylinder.staticType()) ); 360 if (! srf1.pureType( ).equals(SurfCylinder.staticType()) ) 361 return pstat; 362 SurfCylinder scy1 = ( SurfCylinder ) srf1; 363 364 // Fetch the R of the cylinder and the starting track vector. 365 int ir = SurfCylinder.RADIUS; 366 double Rcyl = scy1.parameter(ir); 367 368 TrackVector vec = trv.vector(); 369 double c1 = vec.get(IPHI); // phi 370 double c2 = vec.get(IZ); // z 371 double c3 = vec.get(IALF); // alpha 372 double c4 = vec.get(ITLM); // tan(lambda) 373 double c5 = vec.get(IQPT); // q/pt 374 375 376 // Check destination is a XYPlane. 377 Assert.assertTrue( srf.pureType().equals(SurfXYPlane.staticType()) ); 378 if ( !srf.pureType( ).equals(SurfXYPlane.staticType()) ) 379 return pstat; 380 SurfXYPlane sxyp2 = ( SurfXYPlane ) srf; 381 382 // Fetch the u and phi of the plane. 383 int iphi = SurfXYPlane.NORMPHI; 384 int idist = SurfXYPlane.DISTNORM; 385 386 double phi_n = sxyp2.parameter(iphi); 387 double u_n = sxyp2.parameter(idist); 388 389 // rotate coordinate system on phi_n 390 391 c1 -= phi_n; 392 if(c1 < 0.) c1 += TRFMath.TWOPI; 393 394 double cos_c1 = Math.cos(c1); 395 396 double u = Rcyl*cos_c1; 397 398 double sin_c1 = Math.sin(c1); 399 double cos_dir = Math.cos(c1+c3); 400 double sin_dir = Math.sin(c1+c3); 401 double c4_hat2 = 1+c4*c4; 402 double c4_hat = Math.sqrt(c4_hat2); 403 404 // check if du == 0 ( that is track moves parallel to the destination plane ) 405 // du = pt*cos_dir 406 if(cos_dir/c5 == 0.) return pstat; 407 408 double tan_dir = sin_dir/cos_dir; 409 410 double b1 = Rcyl*sin_c1; 411 double b2 = c2; 412 double b3 = tan_dir; 413 double b4 = c4/cos_dir; 414 double b5 = c5/c4_hat; 415 416 int sign_du = 0; 417 if(cos_dir > 0) sign_du = 1; 418 if(cos_dir < 0) sign_du = -1; 419 420 double b3_hat = Math.sqrt(1 + b3*b3); 421 double b34_hat = Math.sqrt(1 + b3*b3 + b4*b4); 422 double b3_hat2 = b3_hat*b3_hat; 423 double b34_hat2 = b34_hat*b34_hat; 424 double r = 1/(b5*B)*b3_hat/b34_hat; 425 double cosphi = -b3*sign_du/b3_hat; 426 double sinphi = sign_du/b3_hat; 427 double rsinphi = 1./(b5*B)*sign_du/b34_hat; 428 double rcosphi = -b3/(b5*B)*sign_du/b34_hat; 429 430 double du = u_n - u; 431 double norm = du/r - cosphi; 432 433 // cyl-xy propagation failed : noway to the new plane 434 if(Math.abs(norm)>1.) return pstat; 435 436 double cat = Math.sqrt(1.-norm*norm); 437 int sign_dphi = 0; 438 439 if (dir.equals(PropDir.NEAREST)) 440 { 441 if(debug) System.out.println("PropCylXY._vec_prop: Propagation in NEAREST direction is undefined"); 442 System.exit(1); 443 } 444 else if (dir.equals(PropDir.FORWARD)) 445 { 446 if(b5>0.) sign_dphi = 1; 447 if(b5<0.) sign_dphi = -1; 448 } 449 else if (dir.equals(PropDir.BACKWARD)) 450 { 451 if(b5>0.) sign_dphi = -1; 452 if(b5<0.) sign_dphi = 1; 453 } 454 else 455 { 456 if(debug) System.out.println("PropCylXY._vec_prop: Unknown direction." ); 457 System.exit(1); 458 } 459 460 int sign_cat = 0; 461 if(du*sign_dphi*b5>0.) sign_cat = 1; 462 if(du*sign_dphi*b5<0.) sign_cat = -1; 463 if(du == 0.) 464 { 465 if(sinphi >=0. ) sign_cat = 1; 466 if(sinphi < 0. ) sign_cat = -1; 467 } 468 469 double sin_dphi = norm*sinphi + cat*cosphi*sign_cat; 470 double cos_dphi = -norm*cosphi + cat*sinphi*sign_cat; 471 472 int sign_sindphi = 0; 473 if(sin_dphi> 0.) sign_sindphi = 1; 474 if(sin_dphi< 0.) sign_sindphi = -1; 475 if(sin_dphi == 0.) sign_sindphi = sign_dphi; 476 477 double dphi = Math.PI*(sign_dphi - sign_sindphi) + sign_sindphi*Math.acos(cos_dphi); 478 479 // check if dun == 0 ( that is track moves parallel to the destination plane) 480 double du_n_du = cos_dphi - b3*sin_dphi; 481 if(du_n_du==0.) return pstat; 482 483 double a_hat_dphi = 1./du_n_du; 484 double a_hat_dphi2 = a_hat_dphi*a_hat_dphi; 485 double c_hat_dphi = sin_dphi + b3*cos_dphi ; 486 487 double b1_n = b1 + rsinphi*(1-cos_dphi) - rcosphi*sin_dphi; 488 double b2_n = b2 + b4/(b5*B)*sign_du/b34_hat*dphi; 489 double b3_n = c_hat_dphi*a_hat_dphi; 490 double b4_n = b4*a_hat_dphi; 491 double b5_n = b5; 492 493 int sign_dun = 0; 494 if(du_n_du*sign_du > 0) sign_dun = 1; 495 if(du_n_du*sign_du < 0) sign_dun = -1; 496 497 vec.set(IV , b1_n); 498 vec.set(IZ , b2_n); 499 vec.set(IDVDU , b3_n); 500 vec.set(IDZDU , b4_n); 501 vec.set(IQP_XY , b5_n); 502 503 // Set the return status. 504 505 if (dir.equals(PropDir.FORWARD)) 506 { 507 pstat.setForward(); 508 } 509 else if (dir.equals(PropDir.BACKWARD)) 510 { 511 pstat.setBackward(); 512 } 513 514 // Update trv 515 trv.setSurface(srf.newPureSurface()); 516 trv.setVector(vec); 517 // set new direction of the track 518 if(sign_dun == 1) trv.setForward(); 519 if(sign_dun == -1) trv.setBackward(); 520 521 // exit now if user did not ask for error matrix. 522 if (deriv == null ) return pstat; 523 524 // du_dc 525 526 double du_dc1 = -Rcyl*sin_c1; 527 528 // db1_dc 529 530 double db1_dc1 = Rcyl*cos_c1; 531 532 // db2_dc 533 534 double db2_dc2 = 1.; 535 536 // db3_dc 537 538 double db3_dc1 = 1./(cos_dir*cos_dir); 539 double db3_dc3 = 1./(cos_dir*cos_dir); 540 541 // db4_dc 542 543 double db4_dc1 = b4*tan_dir; 544 double db4_dc3 = b4*tan_dir; 545 double db4_dc4 = 1/cos_dir; 546 547 // db5_dc 548 549 double db5_dc4 = -c4*c5/(c4_hat*c4_hat2); 550 double db5_dc5 = 1./c4_hat; 551 552 553 // dr_db 554 555 double dr_db3 = r*b3*b4*b4/(b3_hat2*b34_hat2); 556 double dr_db4 = -r*b4/b34_hat2; 557 double dr_db5 = -r/b5; 558 559 // dcosphi_db 560 561 double dcosphi_db3 = - sign_du/b3_hat - cosphi*b3/b3_hat2; 562 563 // dsinphi_db 564 565 double dsinphi_db3 = - sinphi*b3/b3_hat2; 566 567 // dcat_db 568 569 double dcat_db3 = norm/cat*(du/(r*r)*dr_db3 + dcosphi_db3 ); 570 double dcat_db4 = norm/cat* du/(r*r)*dr_db4; 571 double dcat_db5 = norm/cat* du/(r*r)*dr_db5; 572 double dcat_du = norm/(cat*r); 573 574 // dnorm_db 575 576 double dnorm_db3 = - du/(r*r)*dr_db3 - dcosphi_db3; 577 double dnorm_db4 = - du/(r*r)*dr_db4; 578 double dnorm_db5 = - du/(r*r)*dr_db5; 579 double dnorm_du = - 1./r; 580 581 // dcos_dphi_db 582 583 double dcos_dphi_db3 = - cosphi*dnorm_db3 - norm*dcosphi_db3 + 584 sign_cat*(sinphi*dcat_db3 + cat*dsinphi_db3); 585 double dcos_dphi_db4 = - cosphi*dnorm_db4 + sign_cat*sinphi*dcat_db4; 586 double dcos_dphi_db5 = - cosphi*dnorm_db5 + sign_cat*sinphi*dcat_db5; 587 double dcos_dphi_du = - cosphi*dnorm_du + sign_cat*sinphi*dcat_du; 588 589 // dsin_dphi_db 590 591 double dsin_dphi_db3 = sinphi*dnorm_db3 + norm*dsinphi_db3 + 592 sign_cat*(cosphi*dcat_db3 + cat*dcosphi_db3); 593 double dsin_dphi_db4 = sinphi*dnorm_db4 + sign_cat*cosphi*dcat_db4; 594 double dsin_dphi_db5 = sinphi*dnorm_db5 + sign_cat*cosphi*dcat_db5; 595 double dsin_dphi_du = sinphi*dnorm_du + sign_cat*cosphi*dcat_du; 596 597 // ddphi_db 598 599 double ddphi_db3; 600 double ddphi_db4; 601 double ddphi_db5; 602 double ddphi_du; 603 if(Math.abs(sin_dphi)>0.5) 604 { 605 ddphi_db3 = - dcos_dphi_db3/sin_dphi; 606 ddphi_db4 = - dcos_dphi_db4/sin_dphi; 607 ddphi_db5 = - dcos_dphi_db5/sin_dphi; 608 ddphi_du = - dcos_dphi_du /sin_dphi; 609 } 610 else 611 { 612 ddphi_db3 = dsin_dphi_db3/cos_dphi; 613 ddphi_db4 = dsin_dphi_db4/cos_dphi; 614 ddphi_db5 = dsin_dphi_db5/cos_dphi; 615 ddphi_du = dsin_dphi_du /cos_dphi; 616 } 617 618 // da_hat_dphi_db 619 620 double da_hat_dphi_db3 = - a_hat_dphi2* 621 (dcos_dphi_db3 - sin_dphi - b3*dsin_dphi_db3); 622 double da_hat_dphi_db4 = - a_hat_dphi2*(dcos_dphi_db4 - b3*dsin_dphi_db4); 623 double da_hat_dphi_db5 = - a_hat_dphi2*(dcos_dphi_db5 - b3*dsin_dphi_db5); 624 double da_hat_dphi_du = - a_hat_dphi2*(dcos_dphi_du - b3*dsin_dphi_du ); 625 626 // dc_hat_dphi_db 627 628 double dc_hat_dphi_db3 = b3*dcos_dphi_db3 + dsin_dphi_db3 + cos_dphi; 629 double dc_hat_dphi_db4 = b3*dcos_dphi_db4 + dsin_dphi_db4; 630 double dc_hat_dphi_db5 = b3*dcos_dphi_db5 + dsin_dphi_db5; 631 double dc_hat_dphi_du = b3*dcos_dphi_du + dsin_dphi_du ; 632 633 // db1_n_db 634 635 double db1_n_db1 = 1; 636 double db1_n_db3 = (dr_db3*sinphi+r*dsinphi_db3)*(1-cos_dphi) 637 - rsinphi*dcos_dphi_db3 638 - dr_db3*cosphi*sin_dphi - r*dcosphi_db3*sin_dphi 639 - rcosphi*dsin_dphi_db3; 640 double db1_n_db4 = dr_db4*sinphi*(1-cos_dphi) - rsinphi*dcos_dphi_db4 641 - dr_db4*cosphi*sin_dphi - rcosphi*dsin_dphi_db4; 642 double db1_n_db5 = dr_db5*sinphi*(1-cos_dphi) - rsinphi*dcos_dphi_db5 643 - dr_db5*cosphi*sin_dphi - rcosphi*dsin_dphi_db5; 644 double db1_n_du = - rsinphi*dcos_dphi_du - rcosphi*dsin_dphi_du; 645 646 // db2_n_db 647 648 double db2_n_db2 = 1.; 649 double db2_n_db3 = 1./(b5*B)*b4*sign_du/b34_hat* 650 ( - dphi*b3/b34_hat2 + ddphi_db3); 651 double db2_n_db4 = 1./(b5*B)*sign_du/b34_hat* 652 ( - dphi*b4*b4/b34_hat2 + b4*ddphi_db4 + dphi ); 653 double db2_n_db5 = 1./(b5*B)*b4*sign_du/b34_hat*( ddphi_db5 - dphi/b5); 654 double db2_n_du = 1./(b5*B)*b4*sign_du/b34_hat*ddphi_du; 655 656 // db3_n_db 657 658 double db3_n_db3 = a_hat_dphi*dc_hat_dphi_db3 + da_hat_dphi_db3*c_hat_dphi; 659 double db3_n_db4 = a_hat_dphi*dc_hat_dphi_db4 + da_hat_dphi_db4*c_hat_dphi; 660 double db3_n_db5 = a_hat_dphi*dc_hat_dphi_db5 + da_hat_dphi_db5*c_hat_dphi; 661 double db3_n_du = a_hat_dphi*dc_hat_dphi_du + da_hat_dphi_du *c_hat_dphi; 662 663 // db4_n_db 664 665 double db4_n_db3 = b4*da_hat_dphi_db3; 666 double db4_n_db4 = b4*da_hat_dphi_db4 + a_hat_dphi; 667 double db4_n_db5 = b4*da_hat_dphi_db5; 668 double db4_n_du = b4*da_hat_dphi_du; 669 670 // db5_n_db 671 672 // double db5_n_db5 = 1.; 673 674 // db1_n_dc 675 676 double db1_n_dc1 = db1_n_du * du_dc1 + db1_n_db1*db1_dc1 + 677 db1_n_db3*db3_dc1 + db1_n_db4*db4_dc1; 678 double db1_n_dc2 = 0.; 679 double db1_n_dc3 = db1_n_db3*db3_dc3 + db1_n_db4*db4_dc3; 680 double db1_n_dc4 = db1_n_db4*db4_dc4 + db1_n_db5*db5_dc4; 681 double db1_n_dc5 = db1_n_db5*db5_dc5; 682 683 684 // db2_n_dc 685 686 double db2_n_dc1 = db2_n_du * du_dc1 + db2_n_db3*db3_dc1 + db2_n_db4*db4_dc1; 687 double db2_n_dc2 = db2_n_db2 * db2_dc2; 688 double db2_n_dc3 = db2_n_db3*db3_dc3 + db2_n_db4*db4_dc3; 689 double db2_n_dc4 = db2_n_db4*db4_dc4 + db2_n_db5*db5_dc4; 690 double db2_n_dc5 = db2_n_db5*db5_dc5; 691 692 // db3_n_dc 693 694 double db3_n_dc1 = db3_n_du * du_dc1 + db3_n_db3*db3_dc1 + db3_n_db4*db4_dc1; 695 double db3_n_dc2 = 0.; 696 double db3_n_dc3 = db3_n_db3*db3_dc3 + db3_n_db4*db4_dc3; 697 double db3_n_dc4 = db3_n_db4*db4_dc4 + db3_n_db5*db5_dc4; 698 double db3_n_dc5 = db3_n_db5*db5_dc5; 699 700 // db4_n_dc 701 702 double db4_n_dc1 = db4_n_du * du_dc1 + db4_n_db3*db3_dc1 + db4_n_db4*db4_dc1; 703 double db4_n_dc2 = 0.; 704 double db4_n_dc3 = db4_n_db3*db3_dc3 + db4_n_db4*db4_dc3; 705 double db4_n_dc4 = db4_n_db4*db4_dc4 + db4_n_db5*db5_dc4; 706 double db4_n_dc5 = db4_n_db5*db5_dc5; 707 708 // db5_n_dc 709 710 double db5_n_dc1 = 0.; 711 double db5_n_dc2 = 0.; 712 double db5_n_dc3 = 0.; 713 double db5_n_dc4 = db5_dc4; 714 double db5_n_dc5 = db5_dc5; 715 716 deriv.set(IV,IPHI , db1_n_dc1); 717 deriv.set(IV,IZ_CYL , db1_n_dc2); 718 deriv.set(IV,IALF , db1_n_dc3); 719 deriv.set(IV,ITLM , db1_n_dc4); 720 deriv.set(IV,IQPT , db1_n_dc5); 721 deriv.set(IZ,IPHI , db2_n_dc1); 722 deriv.set(IZ,IZ_CYL , db2_n_dc2); 723 deriv.set(IZ,IALF , db2_n_dc3); 724 deriv.set(IZ,ITLM , db2_n_dc4); 725 deriv.set(IZ,IQPT , db2_n_dc5); 726 deriv.set(IDVDU,IPHI , db3_n_dc1); 727 deriv.set(IDVDU,IZ_CYL , db3_n_dc2); 728 deriv.set(IDVDU,IALF , db3_n_dc3); 729 deriv.set(IDVDU,ITLM , db3_n_dc4); 730 deriv.set(IDVDU,IQPT , db3_n_dc5); 731 deriv.set(IDZDU,IPHI , db4_n_dc1); 732 deriv.set(IDZDU,IZ_CYL , db4_n_dc2); 733 deriv.set(IDZDU,IALF , db4_n_dc3); 734 deriv.set(IDZDU,ITLM , db4_n_dc4); 735 deriv.set(IDZDU,IQPT , db4_n_dc5); 736 deriv.set(IQP_XY,IPHI , db5_n_dc1); 737 deriv.set(IQP_XY,IZ_CYL , db5_n_dc2); 738 deriv.set(IQP_XY,IALF , db5_n_dc3); 739 deriv.set(IQP_XY,ITLM , db5_n_dc4); 740 deriv.set(IQP_XY,IQPT , db5_n_dc5); 741 742 return pstat; 743 } 744 745 static void check_zero_propagation( VTrack trv0, VTrack trv, PropStat pstat) 746 { 747 748 SpacePoint sp = trv.spacePoint(); 749 SpacePoint sp0 = trv0.spacePoint(); 750 751 SpacePath sv = trv.spacePath(); 752 SpacePath sv0 = trv0.spacePath(); 753 754 Assert.assertTrue( Math.abs(sv0.dx() - sv.dx())<1e-7 ); 755 Assert.assertTrue( Math.abs(sv0.dy() - sv.dy())<1e-7 ); 756 Assert.assertTrue( Math.abs(sv0.dz() - sv.dz())<1e-7 ); 757 758 double x0 = sp0.x(); 759 double y0 = sp0.y(); 760 double z0 = sp0.z(); 761 double x1 = sp.x(); 762 double y1 = sp.y(); 763 double z1 = sp.z(); 764 765 double dx = sv.dx(); 766 double dy = sv.dy(); 767 double dz = sv.dz(); 768 769 double prod = dx*(x1-x0)+dy*(y1-y0)+dz*(z1-z0); 770 double moda = Math.sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0) + (z1-z0)*(z1-z0)); 771 double modb = Math.sqrt(dx*dx+dy*dy+dz*dz); 772 double st = pstat.pathDistance(); 773 // Assert.assertTrue( Math.abs(prod-st) < 1.e-7 ); 774 // Assert.assertTrue( Math.abs(Math.abs(prod) - moda*modb) < 1.e-7 ); 775 } 776 777 static void check_derivatives( Propagator prop, VTrack trv0, Surface srf) 778 { 779 for(int i=0;i<4;++i) 780 for(int j=0;j<4;++j) 781 check_derivative(prop,trv0,srf,i,j); 782 } 783 784 static void check_derivative( Propagator prop, VTrack trv0, Surface srf,int i,int j) 785 { 786 787 double dx = 1.e-3; 788 VTrack trv = new VTrack(trv0); 789 TrackVector vec = trv.vector(); 790 boolean forward = trv0.isForward(); 791 792 VTrack trv_0 = new VTrack(trv0); 793 TrackDerivative der = new TrackDerivative(); 794 PropStat pstat = prop.vecProp(trv_0,srf,der); 795 Assert.assertTrue(pstat.success()); 796 797 TrackVector tmp = new TrackVector(vec); 798 tmp.set(j, tmp.get(j)+dx); 799 trv.setVector(tmp); 800 if(forward) trv.setForward(); 801 else trv.setBackward(); 802 803 VTrack trv_pl = new VTrack(trv); 804 pstat = prop.vecProp(trv_pl,srf); 805 Assert.assertTrue(pstat.success()); 806 807 TrackVector vecpl = trv_pl.vector(); 808 809 tmp = new TrackVector(vec); 810 tmp.set(j,tmp.get(j)-dx); 811 trv.setVector(tmp); 812 if(forward) trv.setForward(); 813 else trv.setBackward(); 814 815 VTrack trv_mn = new VTrack(trv); 816 pstat = prop.vecProp(trv_mn,srf); 817 Assert.assertTrue(pstat.success()); 818 819 TrackVector vecmn = trv_mn.vector(); 820 821 double dy = (vecpl.get(i)-vecmn.get(i))/2.; 822 823 double dydx = dy/dx; 824 825 double didj = der.get(i,j); 826 827 if( Math.abs(didj) > 1e-10 ) 828 Assert.assertTrue( Math.abs((dydx - didj)/didj) < 1e-4 ); 829 else 830 Assert.assertTrue( Math.abs(dydx) < 1e-4 ); 831 } 832 }