1 package org.lcsim.recon.tracking.trfbase; 2 3 import org.lcsim.recon.tracking.spacegeom.SpacePoint; 4 import org.lcsim.recon.tracking.spacegeom.SpacePointVector; 5 import org.lcsim.recon.tracking.spacegeom.SpacePath; 6 7 /** Base class to describe a surface. 8 *<p> 9 * There are two conceptual levels of concrete surfaces: 10 * 1. Pure surfaces are unbounded and are used to specify the set 11 * of track parameters used in VTrack. They derive directly 12 * from Surface. Typically these are named SurfXXX. 13 * 2. Bounded surfaces are derived from pure surfaces. 14 * Typically these are named BSurfXXX. 15 *<p> 16 * Typically the first two track parameters specify the position on the 17 * surface, the next two the direction of the track and the last is 18 * q/p where q is the charge (in natural units where the electron is -1) 19 * and p is the total momentum in GeV/c. Note that the radius of 20 * curvature (in cm) is then Rc = cos(tht) / [ 0.003 * (q/p) * B ] 21 * where B is the magnetic field in Tesla and tht is the angle between the 22 * field and the direction. Also 0.003 is actually 0.0029979.... 23 *<p> 24 * This is an abstract class. Classes VTrack and Hit maintain pointers 25 * of this type. 26 * 27 * 28 * <p> 29 * Add attributes Interactor and SimInteractor to Surface to allow tracks made up of Hits 30 * to be refit, allowing for multiple scattering and energy loss. Will not need 31 * Layer to do this for us. 32 *<p> 33 * add methods interact() and simInteract() to smear and simulate, respectively. 34 * 35 * @author Norman A. Graf 36 * @version 1.0 37 */ 38 39 public abstract class Surface 40 { 41 // attributes... 42 private Interactor _interactor; 43 private SimInteractor _siminteractor; 44 45 // Statics here... 46 47 /** 48 * The type name for the class 49 * 50 * @return String name 51 */ 52 public static String typeName() 53 { 54 return "Surface"; 55 } 56 57 /** 58 *The type name for the class 59 * 60 * @return String name 61 */ 62 public static String staticType() 63 { 64 return typeName(); 65 } 66 // Methods here... 67 // 68 69 /** 70 * default constructor 71 * 72 */ 73 public Surface() 74 { 75 } 76 77 78 79 /** 80 * Return the full type. 81 * This implementation returns the pure type ==> 82 * Pure surfaces need not override. 83 * Bound surfaces should override. 84 * 85 * @return String type name 86 */ 87 public String type() 88 { 89 return pureType(); 90 } 91 92 // 93 94 /** 95 * Return the generic type of this class. 96 * Subclasses must not override. 97 * 98 * @return String type name 99 */ 100 public String genericType() 101 { 102 return staticType(); 103 } 104 105 // 106 107 /** 108 * Return whether this surface is pure. 109 * 110 * @return true if Surface is pure 111 */ 112 public boolean isPure( ) 113 { 114 return type().equals(pureType()); 115 } 116 117 118 // 119 120 /** 121 * Return true if two surfaces are exactly the same 122 * including bounds. 123 * 124 * @param srf Surface to be compared to 125 * @return true if both surfaces are exactly the same, including bounds 126 */ 127 public boolean boundEqual(Surface srf) 128 { 129 if ( type().equals(srf.type()) ) return safeBoundEqual(srf); 130 return false; 131 } 132 133 // 134 135 /** Return true if two surfaces have the same pure surface. 136 * 137 * @return true if two surfaces have the same pure surface. 138 * @param srf Surface to compare 139 */ 140 public boolean pureEqual( Surface srf) 141 { 142 if( pureType().equals(srf.pureType()) ) return safePureEqual(srf); 143 return false; 144 } 145 146 // 147 148 /** 149 * Ordering operator. 150 * Returns true if this surface comes before the 151 * argument surface. Comparison is based on the pure parameters only. 152 * As usual exactly one of a<b, b<a and a==b is true and all comparisons 153 * are transitive. 154 * 155 * @param srf Surface to be compared to. 156 * @return true if this surface comes before srf. 157 */ 158 public boolean pureLessThan(Surface srf) 159 { 160 if( pureType().equals(srf.pureType()) ) return safePureLessThan(srf); 161 // not sure what to do here... return get_pure_type() < srf.get_pure_type(); 162 return false; 163 } 164 165 // 166 167 /** 168 * Return q/p in 1/GeV/c. This is proportional to curvature. 169 * Override for non-standard fifth track parameter. 170 * 171 * @param vec TrackVector 172 * @return Track parameter q/p. 173 */ 174 public double qOverP(TrackVector vec) 175 { 176 return vec.get(4); 177 } 178 179 // 180 // 181 // 182 183 184 /** 185 *Return the direction consistent with the specified track vector. 186 *Subclasses for which the track vector does specify the direction 187 * should override this method. 188 * If the vector is ambiguous, then VTrack carries an attribute 189 * which is used to specify the direction. 190 * @param vec TrackVector 191 * @return The default defined here returns TSD_UNDEFINED. 192 */ 193 public TrackSurfaceDirection direction(TrackVector vec) 194 { 195 return TrackSurfaceDirection.TSD_UNDEFINED; 196 } 197 198 //cng 199 200 // 201 202 /** 203 * Interact the track parameters. 204 * If Surface contains an Interactor, modify tre accordingly. 205 * 206 * @param tre ETrack 207 */ 208 public void interact(ETrack tre) 209 { 210 if(_interactor!=null) _interactor.interact(tre); 211 } 212 213 // 214 215 /** 216 *Set the Interactor. 217 * 218 * @param interactor TrackInteractor 219 */ 220 public void setInteractor(Interactor interactor) 221 { 222 _interactor = interactor.newCopy(); 223 } 224 225 // 226 227 /** 228 *Return the Interactor. 229 * 230 * @return the Interactor 231 */ 232 public Interactor getInteractor() 233 { 234 return _interactor.newCopy(); 235 } 236 237 // 238 239 /** 240 *smear the track parameters 241 *If the Surface contains a SimInteractor, smear the track accordingly. 242 * @param trv VTrack to be smeared 243 */ 244 public void simInteract(VTrack trv) 245 { 246 if(_siminteractor!=null) _siminteractor.interact(trv); 247 } 248 249 // 250 251 /** 252 *Set the SimInteractor. 253 * 254 * @param siminteractor Interactor to set for this surface 255 */ 256 public void setSimInteractor(SimInteractor siminteractor) 257 { 258 _siminteractor = siminteractor.newCopy(); 259 } 260 261 262 // 263 264 /** 265 *Return the SimInteractor. 266 * 267 * @return Interactor for this surface 268 */ 269 public SimInteractor simInteractor() 270 { 271 return _siminteractor.newCopy(); 272 } 273 //cng 274 275 /** 276 * String representation of the Surface. 277 * 278 * @return String representation of the Surface. 279 */ 280 public String toString() 281 { 282 String className = getClass().getName(); 283 int lastDot = className.lastIndexOf('.'); 284 if(lastDot!=-1)className = className.substring(lastDot+1); 285 286 return className; 287 } 288 289 // Methods to implement in all surfaces. ***************************** 290 291 292 293 // Return true if two surfaces have the same pure surface. 294 // Argument may be safely downcast. 295 protected abstract boolean safePureEqual(Surface srf); 296 297 // Return true if this surface and the argument are in order. 298 // See pure_less_than() for more information. 299 // Argument may be safely downcast. 300 protected abstract boolean safePureLessThan(Surface srf); 301 302 // Return the pure type. 303 304 /** 305 * pure type of object 306 * 307 * @return String representation of object's pure type 308 */ 309 public abstract String pureType(); 310 311 // 312 313 /** 314 *Return a new surface corresponding to the underlying pure surface. 315 * 316 * @return copy of pure surface 317 */ 318 public abstract Surface newPureSurface(); 319 320 // 321 322 /** 323 *Return the crossing status for a track without error. 324 * Subclasses should override the return type with their own 325 * crossing status. 326 * 327 * @param trv VTrack 328 * @return crossing status for trv. 329 */ 330 public abstract CrossStat pureStatus( VTrack trv); 331 332 // 333 334 335 /** 336 * Return the surface parameter with specified index (0, 1, 2, 3, 4). 337 * 338 * @param i index 339 * @return value of surface parameter i. 340 */ 341 public abstract double parameter(int i); 342 343 // 344 345 /** 346 *Return the difference between two vectors on the surface. 347 * 348 * @param vec1 TrackVector 349 * @param vec2 TrackVector 350 * @return new TrackVector representing difference of vec1 and vec2 351 */ 352 public abstract TrackVector vecDiff(TrackVector vec1, 353 TrackVector vec2); 354 // 355 356 /** 357 *Return the position of a track vector. 358 * 359 * @param vec TrackVector 360 * @return the SpacePoint position of the TrackVector on the Surface 361 */ 362 public abstract SpacePoint spacePoint(TrackVector vec); 363 364 // 365 366 367 /** 368 *Return the position and direction of a track vector. 369 * 370 * @param vec TrackVector 371 * @param dir TrackSurfaceDirection 372 * @return Spacepath position and direction of vec. 373 */ 374 public abstract SpacePath spacePath(TrackVector vec, 375 TrackSurfaceDirection dir); 376 377 // Methods to implement only in bounded surfaces. ******************* 378 379 // The default implementations for these methods are only appropriate 380 // for pure surfaces. Bounded surfaces must override. This is checked 381 // with an assertion. 382 // Return true if two surfaces are exactly the same 383 // including bounds. Argument may be safely downcast. 384 // This method should be implemented by all bounded surfaces. 385 protected boolean safeBoundEqual(Surface srf) 386 { 387 if(!isPure()) throw new IllegalArgumentException("Surface is not pure!"); 388 return safePureEqual(srf); 389 } 390 391 // 392 393 /** 394 *Return a new Surface of the full type (clone). 395 * The default implementation is appropriate only for a pure Surface. 396 * 397 * @return clone Surface 398 */ 399 public Surface newSurface() 400 { 401 if(!isPure()) throw new IllegalArgumentException("Surface is not pure!"); 402 return newPureSurface(); 403 } 404 405 // 406 407 408 /** 409 *Return the crossing status for a track without or with error. 410 * Without error should produce the same result as with error 411 * with zero errors. 412 * Default for status is pure status. 413 * 414 * @param trv VTrack 415 * @return CrossStat status for track without error. 416 */ 417 public CrossStat status(VTrack trv) 418 { 419 if(!isPure()) throw new IllegalArgumentException("Surface is not pure!"); 420 return pureStatus(trv); 421 } 422 423 424 /** 425 *Return the crossing status for a track with error. 426 * Without error should produce the same result as with error 427 * with zero errors. 428 * Default for status is pure status. 429 * 430 * @param tre ETrack 431 * @return CrossStat status for track with error. 432 */ 433 public CrossStat status(ETrack tre) 434 { 435 if(!isPure()) throw new IllegalArgumentException("Surface is not pure!"); 436 return pureStatus(tre); 437 } 438 439 // 440 /** 441 *Equality operator. 442 * This compares the full surface types. 443 * 444 * @param srf Surface to be compared to 445 * @return true if Surfaces are equal, including bounds. 446 */ 447 public boolean equals( Surface srf) 448 { 449 return boundEqual(srf); 450 } 451 452 }