1 package org.lcsim.recon.tracking.gtrbase;
2
3
4 import java.util.Set;
5 import java.util.TreeSet;
6 import java.util.SortedSet;
7 import java.util.Iterator;
8
9 import org.lcsim.recon.tracking.trfutil.Assert;
10
11 import org.lcsim.recon.tracking.trfbase.Propagator;
12 import org.lcsim.recon.tracking.trfbase.Surface;
13 /**
14 * This class describes a global track consisting of a list of states
15 * which specify the fit and hit or miss at different points along
16 * the track trajectory. See GTrackState for a more complete
17 * description of the states.
18 *
19 *@author Norman A. Graf
20 *@version 1.0
21 *
22 */
23 public class GTrack
24 {
25
26 // static attributes
27
28 // Minimum and maximum values for s.
29 // All states should have values in the range SMIN <= s <= SMAX.
30 static final double SMIN = -1.e30;;
31 static final double SMAX = 1.e30;;
32
33 static final GTrackState BAD_STATE = new GTrackState();
34 // propagator
35 private static Propagator _prop;
36
37 // attributes
38
39 // Flag indicating the track is valid.
40 // This is set false for the default constructor.
41 private boolean _valid;
42
43 // List of states.
44 private TreeSet _states;
45
46 // methods
47
48
49 /**
50 * Construct a default instance.
51 * Leaves object in an invalid state.
52 *
53 */
54 public GTrack()
55 {
56 _valid = false;
57 }
58
59 /**
60 *Construct an instance from a list of states.
61 * Track is set valid if all states meet the following:
62 * 1. have SMIN <= s <= SMAX
63 * 2. are valid
64 * 3. have valid fits (not INVALID)
65 *
66 * @param states The list of track states.
67 */
68 public GTrack( TreeSet states)
69 {
70 _valid = true;
71 _states = new TreeSet();
72 _states.addAll(states);
73
74
75 // Check below assumes list has at least one entry.
76 Assert.assertTrue( states().size()>0 );
77 if ( states().size()==0 ) _valid = false;
78
79 // Check that the s-values are in range.
80 Assert.assertTrue( ((GTrackState) states().first()).s() >= SMIN );
81 Assert.assertTrue( ((GTrackState) states().last()).s() <= SMAX );
82
83 // Check that all states are valid and have valid fits.
84 for ( Iterator ista=states().iterator(); ista.hasNext(); )
85 {
86 FitStatus fstat = ((GTrackState) ista.next()).fitStatus();
87 Assert.assertTrue( fstat != FitStatus.BADSTATE );
88 if ( fstat == FitStatus.BADSTATE ) _valid = false;
89 }
90 }
91
92 /**
93 * Construct a replica of the GTrack (copy constructor).
94 *
95 * @param gtr The GTrack to replicate.
96 */
97 public GTrack( GTrack gtr)
98 {
99 _valid = gtr._valid;
100 _states = new TreeSet();
101 if( _valid) _states.addAll(gtr._states);
102 }
103
104 /**
105 *Rebuild the existing track from new set of GTrackStates (needed for Java's inability
106 * to modify local handles)
107 *
108 * @param states The list of GTrackStates.
109 */
110 public void update( TreeSet states )
111 {
112 _valid = true;
113 _states = new TreeSet();
114 _states.addAll(states);
115
116
117 // Check below assumes list has at least one entry.
118 Assert.assertTrue( states().size()>0 );
119 if ( states().size()==0 ) _valid = false;
120
121 // Check that the s-values are in range.
122 Assert.assertTrue( ((GTrackState) states().first()).s() >= SMIN );
123 Assert.assertTrue( ((GTrackState) states().last()).s() <= SMAX );
124
125 // Check that all states are valid and have valid fits.
126 for ( Iterator ista=states().iterator(); ista.hasNext(); )
127 {
128 FitStatus fstat = ((GTrackState) ista.next()).fitStatus();
129 Assert.assertTrue( fstat != FitStatus.BADSTATE );
130 if ( fstat == FitStatus.BADSTATE ) _valid = false;
131 }
132 }
133
134 /**
135 * Drop the fit for the state at the specified path distance s.
136 *
137 * @param s The path distance at which to drop a fit.
138 * @return 0 for success.
139 */
140 public int dropFit(double s)
141 {
142 GTrackState gts = new GTrackState(s);
143 if( _states.contains(gts) )
144 {
145 ((GTrackState) _states.tailSet(gts).iterator().next()).dropFit();
146 return 0;
147 }
148 else
149 {
150 return 1;
151 }
152 }
153
154 /**
155 * Check the tracks validity.
156 *
157 * @return true if the GTrack is valid.
158 */
159 public boolean isValid()
160 {
161 return _valid;
162 }
163
164 /**
165 *Return the list of states.
166 *
167 * @return The list of states.
168 */
169 public TreeSet states()
170 {
171 return _states;
172 }
173
174 /**
175 *Return a state at a path distance s.
176 *
177 * @param s The path distance for which to return a state.
178 * @return an invalid state if there is no state at that s.
179 */
180 public GTrackState state(double s)
181 {
182 GTrackState gts = new GTrackState(s);
183 if( _states.contains(gts) )
184 {
185 return new GTrackState( (GTrackState) _states.tailSet(gts).iterator().next() );
186 }
187 else
188 {
189 return BAD_STATE;
190 }
191 }
192
193 /**
194 *Return the existing state at a particular surface.
195 * The first match with SMIN <= s < SMAX is returned.
196 * A reference to an invalid state is returned if the surface
197 * cannot be matched.
198 * Surface bounds are not required to match.
199 *
200 * @param srf The surface for which to return a state.
201 * @return an invalid state if there is no state at that s.
202 */
203 public GTrackState state( Surface srf)
204 {
205 return state(srf, SMIN, SMAX);
206 }
207
208 /**
209 *Return the existing state at a particular surface.
210 * The first match with s1 <= s < s2 is returned.
211 * A reference to an invalid state is returned if the surface
212 * cannot be matched.
213 * Surface bounds are not required to match. *
214 * @param srf The surface for which to return a state.
215 * @param s1 The lower bound on the path distance.
216 * @param s2 The upper bound on the path distance.
217 * @return an invalid state if there is no state betwee s1 and s2.
218 */
219 public GTrackState state( Surface srf,
220 double s1, double s2)
221 {
222 // Fetch the states between s1 and s2
223 SortedSet sset = _states.subSet(new GTrackState(s1), new GTrackState(s2) );
224 // If no states in this interval return
225 if( sset.size() == 0 ) return BAD_STATE;
226 // Else loop over the states and check the surface
227 for( Iterator it = sset.iterator(); it.hasNext(); )
228 {
229 GTrackState state = (GTrackState) it.next();
230 if ( state.track().surface().pureEqual(srf) ) return state;
231 }
232 return BAD_STATE;
233 }
234
235 // Return the number of measurements in the fit for this track
236 int numberOfMeasurements()
237 {
238 // Need to fix this to reflect measurements, not states
239 // Need Clusters in GTrackState
240 return _states.size();
241 }
242
243
244 /**
245 *output stream
246 *
247 * @return A String representation of this instance.
248 */
249 public String toString()
250 {
251 StringBuffer sb = new StringBuffer( "GTrack: \n" );
252 for (Iterator it = _states.iterator(); it.hasNext(); )
253 {
254 sb.append( (GTrackState) it.next() );
255 }
256 return sb.toString();
257 }
258
259 /**
260 *Test equality.
261 *
262 * @param gtr The GTrack to test.
263 * @return true if the tracks are equal.
264 */
265 public boolean equals( GTrack gtr)
266 {
267 if(_valid != gtr._valid) return false;
268 if(_states.size() != gtr._states.size() ) return false;
269 Iterator it0 = _states.iterator();
270 for ( Iterator it1 = gtr._states.iterator(); it1.hasNext(); )
271 {
272 if ( !( (GTrackState) it1.next()).equals( (GTrackState) it0.next() ) ) return false;
273 }
274 return true;
275 }
276
277 /**
278 *Test equality.
279 *
280 * @param gtr The GTrack to test.
281 * @return true if the tracks are not equal.
282 */
283 public boolean notEquals( GTrack gtr)
284 {
285 return !equals(gtr);
286 }
287
288 }
289
290