1 package org.lcsim.recon.tracking.trfcyl; 2 import java.util.*; 3 4 import org.lcsim.recon.tracking.trfutil.Assert; 5 6 import org.lcsim.recon.tracking.trfbase.Surface; 7 import org.lcsim.recon.tracking.trfbase.ETrack; 8 import org.lcsim.recon.tracking.trfbase.Propagator; 9 import org.lcsim.recon.tracking.trfbase.Cluster; 10 import org.lcsim.recon.tracking.trfbase.Miss; 11 import org.lcsim.recon.tracking.trfbase.CrossStat; 12 import org.lcsim.recon.tracking.trfbase.PropDir; 13 import org.lcsim.recon.tracking.trfbase.PropStat; 14 15 import org.lcsim.recon.tracking.spacegeom.SpacePath; 16 17 import org.lcsim.recon.tracking.trflayer.Layer; 18 import org.lcsim.recon.tracking.trflayer.ClusterFindManager; 19 import org.lcsim.recon.tracking.trflayer.LTrack; 20 21 /** 22 * This is a simple layer consisting of one cylindrical surface. 23 * Propagation assumes tracks originate from inside the cylinder; 24 * i.e. forward for tracks inside and backward for tracks outside. 25 * Clusters may be associated with the layer via a cluster finder. 26 * 27 * 28 *@author Norman A. Graf 29 *@version 1.0 30 * 31 */ 32 33 public class LayerCylinder extends Layer 34 { 35 36 // static methods 37 38 // 39 40 /** 41 *Return a String representation of the class' type name. 42 *Included for completeness with the C++ version. 43 * 44 * @return A String representation of the class' type name. 45 */ 46 public static String typeName() 47 { return "LayerCylinder"; 48 } 49 50 // 51 52 /** 53 *Return a String representation of the class' type name. 54 *Included for completeness with the C++ version. 55 * 56 * @return A String representation of the class' type name. 57 */ 58 public static String staticType() 59 { return typeName(); 60 } 61 62 // attributes 63 64 // surface 65 private Surface _srf; 66 67 // cluster finder 68 private ClusterFindManager _find; 69 70 // Miss. 71 // If defined, a copy of this miss is added to the status after 72 // updating with track. 73 private Miss _miss; 74 75 // implement Layer methods 76 77 // propagate to this layer 78 protected List 79 _propagate(LTrack trl0, Propagator prop) 80 { 81 82 // Create the output track list. 83 // This is empty for early return. 84 List ltracks = new ArrayList(); 85 86 // The input state should be the default one. 87 if ( trl0.status().state() != 0 ) return ltracks; 88 89 // Copy the track. 90 LTrack trl = new LTrack(trl0); 91 92 // Access the kinematic track. 93 ETrack tre = trl.track(); 94 95 // Fetch the crossing status. 96 CrossStat xstat = _srf.status(tre); 97 98 // If track is not on surface, propagate it. 99 if ( ! xstat.at() ) 100 { 101 // Find the direction for propagation. 102 PropDir dir = PropDir.FORWARD; 103 SpacePath svec = tre.spacePath(); 104 if ( xstat.inside() ) 105 { 106 Assert.assertTrue( ! xstat.outside() ); 107 if ( svec.drxy() < 0.0 ) dir = PropDir.BACKWARD; 108 } 109 else 110 { 111 Assert.assertTrue( xstat.outside() ); 112 if ( svec.drxy() > 0.0 ) dir = PropDir.BACKWARD; 113 } 114 // Propagate. 115 // needs review here.. 116 // trl.get_prop_stat() = prop.err_dir_prop(tre,*_psrf,dir); 117 PropStat pstat = prop.errDirProp(tre,_srf,dir); 118 // If propagation fails, exit. 119 if ( ! trl.propStat().success() ) return ltracks; 120 } 121 else 122 { 123 trl.propStat().setPathDistance(0.0); 124 } 125 126 // Check the crossing status. 127 // We could but do not check bounds. 128 xstat = _srf.status(tre); 129 Assert.assertTrue( xstat.at() ); 130 131 // Modify the return status. 132 // Set the state to a non-default value and set at_exit. 133 trl.status().reset(); 134 trl.status().setState(1); 135 trl.status().setAtExit(); 136 if ( _find != null) 137 { 138 trl.status().setFinder(_find); 139 trl.setClusterStatus(); 140 } 141 if ( _miss != null ) 142 { 143 Miss miss = _miss.newCopy(); 144 miss.update(tre); 145 trl.status().setMiss(miss); 146 } 147 // Update the propagtor return status. 148 149 // Put the track on the list and return. 150 ltracks.add(trl); 151 152 return ltracks; 153 154 /* 155 //This needs to be replaced by above... 156 157 // Create the output track list. 158 // This is empty for early return. 159 List ltracks = new ArrayList(); 160 161 // Access the kinematic track. 162 ETrack tre = new ETrack(trl); 163 164 // Fetch the crossing status. 165 CrossStat xstat = _srf.status(tre); 166 167 // If track is not on surface, propagate it. 168 if ( ! xstat.at() ) 169 { 170 // Find the direction for propagation. 171 PropDir dir = PropDir.FORWARD; 172 SpacePath svec = tre.space_vector(); 173 if ( xstat.inside() ) 174 { 175 Assert.assertTrue( ! xstat.outside() ); 176 if ( svec.drxy() < 0.0 ) dir = PropDir.BACKWARD; 177 } 178 else 179 { 180 Assert.assertTrue( xstat.outside() ); 181 if ( svec.drxy() > 0.0 ) dir = PropDir.BACKWARD; 182 } 183 // Propagate. 184 // trl.get_prop_stat() = prop.err_dir_prop(tre,_srf,dir); 185 PropStat pstat = prop.err_dir_prop(tre,_srf,dir); 186 // If propagation fails, exit. 187 // if ( ! trl.get_prop_stat().success() ) return ltracks; 188 if(!pstat.success()) return ltracks; 189 } 190 else 191 { 192 // trl.get_prop_stat().set_path_distance(0.0); //needs work here 193 } 194 195 // Check the crossing status. 196 // We could but do not check bounds. 197 xstat = _srf.status(tre); 198 Assert.assertTrue( xstat.at() ); 199 */ /* 200 // Modify the return status. 201 // Set the state to a non-default value and set at_exit. 202 trl.get_status().reset(); 203 trl.get_status().set_state(1); 204 trl.get_status().set_at_exit(); 205 if ( _pfind ) { 206 trl.get_status().set_finder(*_pfind); 207 trl.set_cluster_status(); 208 } 209 if ( _pmiss ) { 210 Miss* pmiss = _pmiss->new_copy(); 211 pmiss->update(tre); 212 trl.get_status().set_miss(*pmiss); 213 delete pmiss; 214 } 215 // Update the propagtor return status. 216 217 // Put the track on the list and return. 218 */ 219 /* 220 ltracks.add(trl); 221 return ltracks; 222 */ 223 224 225 } 226 227 // 228 229 /** 230 *Construct an instance given the layer's radius and z extent. 231 * 232 * @param r The radius of the cylindrical layer (cm). 233 * @param zmin The minimum z extent of the cylindrical layer (cm). 234 * @param zmax The maximum z extent of the cylindrical layer (cm). 235 */ 236 public LayerCylinder(double r, double zmin, double zmax) 237 { 238 _srf = new BSurfCylinder(r,zmin,zmax); 239 } 240 241 242 /** 243 *Construct an instance given the layer's radius, z extent and a manager to 244 * find the clusters on this layer. 245 * 246 * @param r The radius of the cylindrical layer (cm). 247 * @param zmin The minimum z extent of the cylindrical layer (cm). 248 * @param zmax The maximum z extent of the cylindrical layer (cm). 249 * @param find The ClusterFindManager for this layer. Set find = null if no clusters are associated with layer. 250 */ 251 public LayerCylinder(double r, double zmin, double zmax, ClusterFindManager find) 252 { 253 _srf = new BSurfCylinder(r,zmin,zmax); 254 _find = find; 255 } 256 257 // 258 259 /** 260 *Construct an instance given the layer's radius, z extent, a manager to 261 * find the clusters on this layer and a Miss. 262 * 263 * @param r The radius of the cylindrical layer (cm). 264 * @param zmin The minimum z extent of the cylindrical layer (cm). 265 * @param zmax The maximum z extent of the cylindrical layer (cm). 266 * @param find The ClusterFindManager for this layer. Set find = null if no clusters are associated with layer. 267 * @param miss The Miss for this layer. 268 */ 269 public LayerCylinder(double r, double zmin, double zmax, 270 ClusterFindManager find, Miss miss ) 271 { 272 _srf = new BSurfCylinder(r,zmin,zmax); 273 _find = find; 274 _miss = miss; 275 } 276 277 // 278 279 /** 280 *Construct an instance given a bounded cylindrical surface, a manager to 281 * find the clusters on this layer and a Miss. 282 * 283 * @param srf The BSurfCylinder which represents this cylindrical layer. 284 * @param find The ClusterFindManager for this layer. Set find = null if no clusters are associated with layer. 285 * @param miss The Miss for this layer. 286 */ 287 public LayerCylinder( BSurfCylinder srf, 288 ClusterFindManager find, Miss miss ) 289 { 290 _srf = srf; 291 _find = find; 292 _miss = miss; 293 } 294 295 // 296 297 /** 298 *Construct an instance replicating the LayerCylinder ( copy constructor ). 299 * 300 * @param lc The LayerCylinder to replicate. 301 */ 302 public LayerCylinder( LayerCylinder lc) 303 { 304 _srf = lc._srf; 305 _find = lc._find; 306 _miss = lc._miss; 307 } 308 309 310 /** 311 *output stream 312 * 313 * @return A String representation of this instance. 314 */ 315 public String toString() 316 { 317 StringBuffer sb = new StringBuffer("Cylinder layer.\n Surface: " + _srf); 318 if ( _find!=null ) sb.append("\n Finder: " +_find); 319 else sb.append("No finder."); 320 if ( _miss!=null ) sb.append("\n Miss: " +_miss + "\n"); 321 else sb.append("\n No miss defined.\n"); 322 323 return sb.toString(); 324 } 325 326 // implement Layer methods 327 328 // 329 330 /** 331 *Return a String representation of the class' type name. 332 *Included for completeness with the C++ version. 333 * 334 * @return A String representation of the class' type name. 335 */ 336 public String type() 337 { 338 return staticType(); 339 } 340 341 // 342 343 /** 344 *Return the list of surfaces. 345 * 346 * @return The list of surfaces associated with this cylindrical layer. 347 */ 348 public List clusterSurfaces() 349 { 350 List tmp = new ArrayList(); 351 tmp.add(_srf); 352 return tmp; 353 } 354 355 // 356 357 /** 358 *Return the list of clusters. 359 * 360 * @return The list of clusters associated with this layer. 361 */ 362 public List clusters() 363 { 364 if ( _find != null ) return _find.clusters(); 365 else return new ArrayList(); 366 } 367 368 // 369 370 /** 371 *Return the clusters associated with a specified surface. 372 * 373 * @param srf The Surface within this layer for which to return clusters. 374 * @return A list of clusters for the surface srf. If the surface is not associated with this layer, return an empty list. 375 */ 376 public List clusters(Surface srf) 377 { 378 // If the surfaces is wrong, return an empty list. 379 if ( !srf.equals(_srf) ) 380 { 381 reportInvalidSurface(srf); 382 return new ArrayList(); 383 } 384 return clusters(); 385 386 } 387 388 // 389 390 /** 391 *Add a cluster to this layer. 392 * The cluster surface is required to match this cylinder. 393 * 394 * @param clu The Cluster to add. 395 * @return 0 if successful. 396 * 1 if the cluster's surface is not a cylinder. 397 * 2 if unsuccessful. 398 */ 399 public int addCluster(Cluster clu) 400 { 401 boolean ok = _srf.pureEqual( clu.surface() ); 402 Assert.assertTrue( ok ); 403 if ( ! ok ) return 1; 404 if ( _find!=null ) return _find.addCluster(clu); 405 else return 2; 406 } 407 408 // 409 410 /** 411 *Add a cluster associated with a specified surface. 412 * The cluster surface and surface are required to match 413 * this cylinder. 414 * 415 * @param clu The Cluster to add. 416 * @param srf The Surface to which to add the cluster. 417 * @return 0 if successful. 418 * 1 if the cluster's surface is not a cylinder. 419 * 2 if unsuccessful. 420 * 3 if surface is wrong. 421 */ 422 public int addCluster(Cluster clu, Surface srf) 423 { 424 // If the surface is wrong, return an error 425 if ( !srf.equals(_srf) ) 426 { 427 reportInvalidSurface(srf); 428 return 3; 429 } 430 return addCluster(clu); 431 } 432 433 // 434 435 /** 436 *Drop clusters from this layer. 437 * 438 */ 439 public void dropClusters() 440 { 441 if ( _find!=null ) _find.dropClusters(); 442 } 443 444 // methods specific to this subclass 445 446 // 447 448 /** 449 *Return the surface associated to this layer. 450 * 451 * @return The surface associated to this layer. 452 */ 453 public Surface surface() 454 { return _srf; 455 } 456 457 // 458 459 /** 460 *Return the Cluster finder. 461 * 462 * @return The ClusterFindManager associated to this layer. 463 */ 464 public ClusterFindManager finder() 465 { return _find; 466 } 467 468 } 469