View Javadoc

1   package org.lcsim.recon.tracking.trffit;
2   import org.lcsim.recon.tracking.trfbase.ETrack;
3   import org.lcsim.recon.tracking.trfbase.Hit;
4   import org.lcsim.recon.tracking.trfbase.Propagator;
5   
6   import org.lcsim.recon.tracking.trfbase.Surface;
7   import org.lcsim.recon.tracking.trfbase.PropStat;
8   import org.lcsim.recon.tracking.trfbase.PropDir;
9   
10  import java.util.*;
11  /**
12   * This class describes a track as an ordered list of hits plus
13   * an ETrack (fitted vector and error matrix at a surface) and
14   * the fit chi-square.
15   *<p>
16   * Hits are ordered as they were fit.
17   *<p>
18   * The access to the list of hits is minimal.  Users are expected to
19   * construct a new object to do more than update the fit or add a
20   * hit to the end of the list.
21   *<p>
22   * The method is_fit returns true if the track has been fit with all its hits.
23   * This state is set by calling set_fit and is unset when hits are added.
24   * No hits are required to be on the track (so one can store a fit without
25   * any hits).
26   *
27   *@author Norman A. Graf
28   *@version 1.0
29   *
30   */
31  public class HTrack
32  {
33      // Number of hits used in the current fit.
34      // -1 for a track which has never been fit
35      private int _nfit;
36      
37      
38      // list of hits
39      protected List _hits;
40      
41      // fitted track (or starting track)
42      protected ETrack _tre;
43      
44      // fit chi-square
45      protected double _chisq;
46      
47      
48      //
49      
50      /**
51       * Construct an instance that contains no hits and whose fit is invalid.
52       *
53       */
54      public HTrack()
55      {
56          _tre = new ETrack();
57          _chisq = 0.0;
58          _nfit = -1;
59          _hits = new ArrayList();
60      }
61      
62      //
63      
64      /**
65       *Construct and instance from a track and its error.
66       * There are no hits on the track.
67       *
68       * @param   tre  The ETrack from which to construct this instance.
69       */
70      public HTrack( ETrack tre)
71      {
72          _tre = new ETrack(tre);
73          _chisq = 0.0;
74          _nfit = 0;
75          _hits = new ArrayList();
76      }
77      
78      //
79      
80      /**
81       *Construct an instance which replicates its argument (Copy Constructor).
82       *
83       * @param   ht  The HTrack to replicate.
84       */
85      public HTrack( HTrack ht)
86      {
87          _tre = new ETrack(ht._tre);
88          _chisq = ht._chisq;
89          _nfit = ht._nfit;
90          _hits = new ArrayList(ht._hits);
91      }
92      
93      
94      //
95      
96      /**
97       *Add a hit to the back of the list.
98       *
99       * @param   hit The Hit to add to this track.
100      */
101     public void addHit( Hit hit)
102     {_hits.add(hit);
103     }
104     
105     //
106     
107     /**
108      *Drop the last hit on the list. This does not affect the fit status.
109      *
110      */
111     public  void dropHit()
112     {
113         _hits.remove(_hits.size()-1); // is there no lastElement in List?
114     }
115     
116     //
117     
118     /**
119      *Drop all hits. This does not affect the fit status.
120      *
121      */
122     public  void dropHits()
123     {
124         _hits.clear();
125     }
126     
127     //
128     
129     
130     /**
131      *Set the fit parameters for the current list of hits.
132      *Be sure to add all relevant hits before invocation.
133      * It is assumed the track has been fit with all of its hits.
134      * The track and chi-square are assigned the specified value and
135      * the number of fitted hits is set to the current number of hits.
136      *
137      * @param   tre The ETrack which represents the fit parameters and errors.
138      * @param   chisq The chi-square of the fit.
139      */
140     public void setFit( ETrack tre, double chisq)
141     {
142         _tre = new ETrack(tre);
143         _chisq = chisq;
144         _nfit = _hits.size();
145     }
146     
147     //
148     
149     
150     /**
151      * Unset the fit.
152      * The number of hits is set to 0 and the chi-square is set to zero.
153      * The track is not modified (the last fit becomes the starting track).
154      *
155      */
156     public void unsetFit()
157     {
158         _nfit = -1;
159         _chisq = 0.0;
160     }
161     
162     //
163     
164     /**
165      *Unset the fit and reset the starting track.
166      * The fit is unset and the track is set to the specified value.
167      *
168      * @param   tre The ETrack which represents the track parameters and errors.
169      */
170     public void unsetFit( ETrack tre)
171     {
172         unsetFit();
173         _tre = new ETrack(tre);
174     }
175     
176     //
177     
178     /**
179      *Return the list of hits.
180      *
181      * @return The list of hits on this track.
182      */
183     public List hits()
184     {
185         return new ArrayList(_hits);
186     }
187     
188     //
189     
190     /**
191      *Return a copy of the fit track parameters and errors.
192      *
193      * @return The ETrack which represents the track parameters and errors.
194      */
195     public ETrack newTrack()
196     {
197         return new ETrack(_tre);
198     }
199     
200     //
201     
202     /**
203      * Fetch a handle to the fit track parameters and errors.
204      * @return The ETrack which represents the track parameters and errors.
205      */
206     public ETrack track()
207     {
208         return _tre;
209     }
210     
211     //
212     
213     /**
214      *Return the chi-square of the track fit.
215      *
216      * @return The chi-square of the track fit.
217      */
218     public double chisquared()
219     { return _chisq;
220     }
221     
222     //
223     
224     /**
225      *Return the number of measurements on this track.
226      *This is the number of hits times the dimension of the hit measurement.
227      *
228      * @return The number of measurements on this track.
229      */
230     public int numberOfMeasurements()
231     {
232         int nmeas = 0;
233         for (Iterator it = _hits.iterator(); it.hasNext(); )
234         {
235             nmeas+= ((Hit)it.next()).size();
236         }
237         return nmeas;
238     }
239     
240     //
241     
242     /**
243      *Return the MC track information for hits on this track.
244      *
245      * @return The TrackMcHitInfo object encapsulating the MC track information for hits on this track.
246      */
247     public TrackMcHitInfo mcInfo()
248     {
249         List idlist = new ArrayList();
250         Map idmap = new HashMap();
251         int nhits = _hits.size();
252         //Loop over the hits and fill the mcids list with all the McIds
253         List mcids = new ArrayList();
254 //        for (Iterator it = _hits.iterator(); it.hasNext(); )
255 //        {
256 //            System.out.println( ((Hit) it.next()).mcIds().size() );
257 //            //	 	mcids.addAll( ((Hit) it.next()).get_mc_ids() );
258 //        }
259         //Iterate over the list and fill the frequency map idmap
260         for (Iterator it = mcids.iterator(); it.hasNext(); )
261         {
262             Integer freq = (Integer) it.next();
263             idmap.put( freq, (freq==null ? new Integer(1) : new Integer(freq.intValue()+1)) );
264         }
265         // Return a TrackMcHitInfo object
266         return new TrackMcHitInfo(nhits, idmap);
267     }
268     
269     //
270     
271     /**
272      *Return the fit status: true if track has one or more hits
273      * and has been fit with all of its hits.
274      *
275      * @return true if the track contains a valid fit.
276      */
277     public boolean isFit()
278     {
279         return _tre.isValid() && ( _nfit == _hits.size() );
280     }
281     
282     //
283     
284     
285     /**
286      *Propagate the fit track.
287      * Note that this does not change the fit status because the propagation
288      * should be reversible.
289      *
290      * @param   prop The Propagator to use for propagation.
291      * @param   srf The Surface to propagate to.
292      * @return The propagation status.
293      */
294     public PropStat propagate( Propagator prop,  Surface srf)
295     {
296         return prop.errProp(_tre, srf);
297     }
298     
299     //
300     
301     
302     /**
303      *Propagate the fit track in a specified direction.
304      * Note that this does not change the fit status because the propagation
305      * should be reversible.
306      *
307      * @param   prop The Propagator to use for propagation.
308      * @param   srf The Surface to propagate to.
309      * @param   dir The direction in which to propagate.
310      * @return The propagation status.
311      */
312     public PropStat propagate( Propagator prop,  Surface srf, PropDir dir)
313     {
314         return prop.errDirProp(_tre,srf,dir);
315     }
316     
317     
318     /**
319      *output stream
320      *
321      * @return The String representation of this class.
322      */
323     public String toString()
324     {
325         StringBuffer sb =  new StringBuffer(getClass().getName()+" is ");
326         if( ! isFit()) sb.append("not ");
327         sb.append("fit: \n" + _tre +"\n");
328         sb.append("Chi-square: "+_chisq+"\n");
329         sb.append("Track has "+_hits.size()+" hit");
330         if(_hits.size() != 1) sb.append("s");
331         if (_hits.size() > 0 )
332         {
333             sb.append(":\n");
334             for (Iterator it = _hits.iterator(); it.hasNext(); )
335             {
336                 sb.append( ((Hit) it.next()+"\n") );
337             }
338         }
339         return sb.toString();
340     }
341     
342     
343     /**
344      *Test equality of this object against another HTrack.
345      *
346      * @param   ht The HTrack against which to compare.
347      * @return true if the two tracks are equal.
348      */
349     public boolean equals( HTrack ht)
350     {
351         if( ! hits().equals(ht.hits()) ) return false;
352         if( ! newTrack().equals(ht.newTrack()) ) return false;
353         if(   chisquared() != ht.chisquared() ) return false;
354         if(   isFit()     != ht.isFit() ) return false;
355         return true;
356     }
357     
358     
359     /**
360      * Test inequality of this object against another HTrack.
361      *
362      * @param   ht The HTrack against which to compare.
363      * @return true if the two tracks are equal.
364      */
365     public boolean notEquals( HTrack ht)
366     {
367         return ! equals(ht);
368     }
369 }
370 
371