View Javadoc

1   package  org.lcsim.recon.tracking.trfzp;
2   
3   import java.util.Map;
4   import java.util.HashMap;
5   import java.util.TreeMap;
6   import java.util.SortedMap;
7   
8   import java.util.List;
9   import java.util.LinkedList;
10  import java.util.ArrayList;
11  import java.util.Iterator;
12  import java.util.ListIterator;
13  
14  import org.lcsim.recon.tracking.trfutil.Assert;
15  import org.lcsim.recon.tracking.trfutil.TRFMath;
16  
17  import org.lcsim.recon.tracking.trfbase.Cluster;
18  import org.lcsim.recon.tracking.trfbase.Hit;
19  import org.lcsim.recon.tracking.trfbase.Surface;
20  import org.lcsim.recon.tracking.trfbase.ETrack;
21  
22  import org.lcsim.recon.tracking.trflayer.ClusterFindManager;
23  
24  /**
25   * Cluster finder for a z plane.  It maintains a map of
26   * clusters of type ZPlane1 indexed by position so
27   * the clusters near a track can be retrieved quickly.
28   *<p>
29   * A track is defined to be near a cluster if the chi-square difference
30   * between the corresponding hit measurement and prediction is less
31   * than _max_chsq_diff.
32   *
33   *@author Norman A. Graf
34   *@version 1.0
35   *
36   */
37  public class ClusFindZPlane1 extends ClusterFindManager
38  {
39      
40      // static methods
41      
42      //
43      
44      /**
45       *Return a String representation of the class' type name.
46       *Included for completeness with the C++ version.
47       *
48       * @return   A String representation of the class' type name.
49       */
50      public static String typeName()
51      { return "ClusFindZPlane1"; }
52      
53      //
54      
55      /**
56       *Return a String representation of the class' type name.
57       *Included for completeness with the C++ version.
58       *
59       * @return   A String representation of the class' type name.
60       */
61      public static String staticType()
62      { return typeName(); }
63      
64      
65      // attributes
66      
67      // surface
68      private SurfZPlane _szp;
69      
70      // stereo angle
71      private double _wx;
72      private double _wy;
73      
74      // maximum allowed chi-square difference
75      private double _max_chsq_diff;
76      
77      // clusters
78      private TreeMap _clusters;
79      
80      
81      // methods
82      
83      //
84      
85      /**
86       *Construct an instance from the z location of the plane, the stereo angles
87       * for the x-y measurement, and the maximum chi-square
88       *difference which defines the nearness of a hit to a track.
89       *
90       * @param   zpos The z position of the z plane.
91       * @param   wx   The stereo angle for the x measurement.
92       * @param   wy   The stereo angle for the y measurement.
93       * @param   max_chsq_diff The maximum chi-square for a track-hit association.
94       */
95      public ClusFindZPlane1(double zpos, double wx, double wy, double max_chsq_diff)
96      {
97          _clusters = new TreeMap(); //use a TreeMap to automatically sort
98          _szp = new SurfZPlane(zpos);
99          _wx = wx;
100         _wy = wy;
101         _max_chsq_diff = max_chsq_diff;
102     }
103     
104     //
105     
106     /**
107      *Add a cluster to this ClusterFindManager.
108      * The cluster must be of type ClusCylPhi or ClusCylPhiZ.
109      *
110      * @param   clus The Cluster to add.
111      * @return  0 if successful.
112      */
113     public int addCluster( Cluster clus)
114     {
115         // declare the key value
116         double keyval = 0.;
117         
118         // Extract the cluster position depending on type
119         if ( clus.type().equals(ClusZPlane1.staticType()) )
120         {
121             ClusZPlane1 clu = ( ClusZPlane1) clus;
122             Assert.assertTrue( clu.surface().equals(_szp) );
123             Assert.assertTrue( clu.wX() == _wx );
124             Assert.assertTrue( clu.wY() == _wy );
125             keyval = clu.aXY();
126         }
127         else
128         {
129             Assert.assertTrue(false);
130             System.exit(1);
131         }
132         
133         // Check there is no other cluster at this position.
134         Double key = new Double(keyval);
135         if ( _clusters.containsKey(key))
136         {
137             Assert.assertTrue(false);
138             System.exit(2);
139         }
140         // Store the cluster.
141         _clusters.put(key, clus);
142         return 0;
143         
144         
145         
146     }
147     
148     //
149     
150     /**
151      *Drop all clusters from this manager.
152      *
153      */
154     public void dropClusters()
155     {
156         _clusters.clear();
157     }
158     
159     //
160     
161    /**
162      *Return the surface.
163      *
164      * @return The Surface associated to this manager.
165      */
166     public Surface surface()
167     {
168         return _szp;
169     }
170     
171     //
172     
173      /**
174      *Return all the clusters.
175      *
176      * @return The list of clusters managed by this manager.
177      */
178     public List clusters()
179     {
180         // Create the list of clusters.
181         List clusters = new ArrayList();
182         
183         // Loop over clusters and add to output list.
184         
185         for ( Iterator iclu=_clusters.values().iterator();  iclu.hasNext(); )
186             clusters.add( iclu.next() );
187         
188         return clusters;
189         
190     }
191     
192     //
193     
194     
195 
196     /**
197      *Return all the clusters near a track at the surface. Nearness is delimited by the
198      *maximum chi-squared between the track prediction and the cluster measurement.
199      *
200      * Clusters have been ordered by axy.
201      * The nearby subset is returned in the same order.
202      *
203      * @param   tre The ETrack for which to return clusters.
204      * @return  A list of clusters near the track tre.
205      */
206     public List clusters( ETrack tre)
207     {
208         // Create the list of clusters.
209         List clusters = new ArrayList();
210         // Check the track surface.
211         if ( !tre.surface().equals(_szp) )
212         {
213             Assert.assertTrue(false);
214             return clusters;
215         }
216         
217         // If there are no clusters, return the empty list.
218         if ( _clusters.size() == 0 )
219         {
220             return clusters;
221         }
222         
223         // Fetch the predicted position.
224         double value = _wx*tre.vector(SurfZPlane.IX) +
225         _wy*tre.vector(SurfZPlane.IY);
226         
227         
228         //for time being loop over all the clusters.
229         // need to be smarter later
230         
231         for(Iterator it = _clusters.values().iterator(); it.hasNext(); )
232         {
233             //get the cluster
234             Cluster clu = (Cluster) it.next();
235             // is cluster within range?
236             if (chsq_diffzp1(clu,tre) < _max_chsq_diff )
237             {
238                 // if so add it to the list
239                 clusters.add( clu );
240             }
241         }
242         
243         
244         
245 /*
246   // Fetch first cluster after the prediction.
247  
248   ClusterMap::const_iterator iclu1 = _clusters.lower_bound(value);
249  
250   // Loop over clusters from this and above.
251   // If cluster is close, add it to the list; otherwise exit loop.
252  
253   ClusterMap::const_iterator iclu = iclu1;
254   for(iclu = iclu1 ; iclu != _clusters.end(); ++iclu ) {
255     ClusterPtr pclu = (*iclu).second;
256     if ( chsq_diffzp1(pclu,tre) > _max_chsq_diff ) break;
257     clusters.push_back( pclu );
258   }
259  
260   // We have checked all clusters in the range (iclu1, +).
261   // Next go backwards from iclu1.
262   iclu = iclu1;
263   if( iclu == _clusters.begin() ) return clusters;
264   iclu--;
265   while ( true ) {
266     ClusterPtr pclu = (*iclu).second;
267     if ( chsq_diffzp1(pclu,tre) > _max_chsq_diff ) break;
268     clusters.push_front( pclu );
269     // decrement iterator; check if the begining is reached
270     if ( iclu == _clusters.begin() ) break;
271     iclu--;
272   }
273  */
274         // Return the nearby clusters.
275         return clusters;
276     }
277     
278     
279     /**
280      * Return the maximum chi-square difference which defines a hit to be near a track.
281      *
282      * @return  The maximum chi-square for a track-hit association.
283      */
284     public double maxChsqDiff()
285     {
286         return _max_chsq_diff;
287     }
288     
289     //
290     
291     /**
292      *Return a String representation of the class' type name.
293      *Included for completeness with the C++ version.
294      *
295      * @return   A String representation of the class' type name.
296      */
297     public String type()
298     {
299         return staticType();
300     }
301     
302     //
303     
304     /**
305      *output stream
306      *
307      * @return  A String representation of this instance.
308      */
309     public String toString()
310     {
311         StringBuffer sb = new StringBuffer("1D Cluster finder for \n" + _szp +"\n");
312         sb.append("wx weight is " + _wx + ".\n" );
313         sb.append("wy weight is " + _wy + ".\n" );
314         sb.append("Maximum chi-square difference is "
315         + _max_chsq_diff + ".\n");
316         return sb.toString();
317     }
318     
319     //**********************************************************************
320     // Helper functions.
321     //**********************************************************************
322     
323     // Calculate the chi-square difference between a cluster and a track.
324     // It is assumed the cluster generates exactly one prediction and that
325     // this prediction has one dimension.
326     
327     private static double chsq_diffzp1( Cluster clu,  ETrack tre)
328     {
329         
330         // Fetch the hit predictions.
331         List hits = clu.predict(tre, clu);
332         
333         // Check there is one hit.
334         Assert.assertTrue( hits.size() == 1 );
335         
336         // Fetch the hit.
337         Hit hit = (Hit) hits.get(0);
338         
339         // Check the hit dimension.
340         Assert.assertTrue( hit.size() == 1 );
341         
342         // Fetch the difference between prediction and measurement.
343         double diff = hit.differenceVector().get(0);
344         
345         // Fetch the measurement error and the prediction error.
346         double emeas = hit.measuredError().get(0,0);
347         double epred = hit.predictedError().get(0,0);
348         
349         // Calculate and return chi-square difference.
350         return diff*diff/(emeas+epred);
351         
352     }
353     
354 }