View Javadoc

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