1 package org.lcsim.recon.tracking.trfbase;
2 /**This class provides the interface for propagating a track to
3 * a surface. In general, there may be any number of points
4 * (0, 1, 2, 3, ...) where the track intersects the surface.
5 * This interface is intended to propagate to either the nearest
6 * point in forward direction or the nearest point in the backward
7 * direction. There are three options: the track may be propagated
8 * only in the forward direction, only the backward direction or
9 * to the nearest of the two crossings.
10 *<p>
11 * For each of the options there are two possibilities when the
12 * destination surface is the same as the original surface. The
13 * original specification was to stay at the same position. Now
14 * there are options (XXX_MOVE) to move to the next crossing.
15 *<p>
16 * Two methods of propagation are provided. One specifies this option.
17 * The other does not and it is the reponsibility of the subclass to
18 * make a clear and unambiguous choice.
19 *<p>
20 * There are also separate propagation methods for tracks with and
21 * without error matrices. These should behave in exactly the same
22 * manner except for changes to the error matrix. The new vector
23 * may not depend on the error matrix.
24 *<p>
25 * The methods to propagate a track with error are implemented here
26 * using the methods without error. Typically there should be no
27 * need for subclasses to override the former.
28 *<p>
29 * The original track is overwritten with the new track parameters
30 * if and only if the propagation is successful. A propagation
31 * status is returned to indicate whether the propagation was
32 * was successful and, if so, the direction of propagation relative
33 * to the track's direction.
34 *<p>
35 * The propagation may be called repeatedly to iterate over all the
36 * crossings in either the forward or backward direction. In order
37 * to maintain this capability, a track that is already at the
38 * surface (i.e. has the same pure surface as the destination) must
39 * be propagated to a new point or the propagation is not successful.
40 * However, if the point is on but not at the surface (i.e. it is on
41 * a different type of pure surface but has coordinates lying on the
42 * destination surface, then the transformed track should be returned
43 * as a successful propagation in the requested direction.
44 *<p>
45 * When labeling or choosing the direction of propagation, forward
46 * should be chosen if there is an ambiguity.
47 *<p>
48 * This clase is abstract: derived classes provide the algorithms
49 * for propagation.
50 *<p>
51 * A higher level class might make use of this interface to provide
52 * an iterator over crossings. It could carry out the propagation
53 * as needed and cache the results.
54 *<p>
55 * The propagate methods all include an optional argument which is a
56 * pointer to a track derivative. If this pointer is not null, then
57 * its location should be filled with the derivative of the new track
58 * w.r.t. the original.
59 *
60 * @author Norman A. Graf
61 * @version 1.0
62 */
63
64 public abstract class Propagator
65 {
66
67 // static methods
68
69 //
70
71 /**
72 *Return the type name.
73 *
74 * @return String representation of class type
75 *Included for completeness with C++ version
76 */
77 public static String typeName()
78 { return "Propagator";
79 }
80
81 //
82
83 /**
84 * return a reduced PropDir
85 *
86 * @param dir direction in which to propagate
87 * @return new propagation direction
88 */
89 public static PropDir reduce(PropDir dir)
90 {
91 if (dir.equals(PropDir.NEAREST_MOVE)) return PropDir.NEAREST;
92 if (dir.equals(PropDir.FORWARD_MOVE)) return PropDir.FORWARD;
93 if (dir.equals(PropDir.BACKWARD_MOVE)) return PropDir.BACKWARD;
94 return dir;
95 }
96
97 /**
98 * Reduce a propagation direction.
99 * This drops the _MOVE from a direction and returns true
100 * if the suffix was present.
101 * It is used in subclasses to separate the true direction from
102 * the move status in a direction.
103 * @param dir propagation direction
104 * @return true if dir was a _MOVE propagation direction
105 */
106 public static boolean reduceDirection(PropDir dir)
107 {
108 if(dir.equals(PropDir.NEAREST))
109 return false;
110 if(dir.equals(PropDir.FORWARD))
111 return false;
112 if(dir.equals(PropDir.BACKWARD))
113 return false;
114 if (dir.equals(PropDir.NEAREST_MOVE))
115 {
116 dir = PropDir.NEAREST;
117 return true;
118 }
119 if (dir.equals(PropDir.FORWARD_MOVE))
120 {
121 dir = PropDir.FORWARD;
122 return true;
123 }
124 if (dir.equals(PropDir.BACKWARD_MOVE))
125 {
126 dir = PropDir.BACKWARD;
127 return true;
128 }
129
130 return false;
131 }
132
133
134 //
135
136 /**
137 *constructor
138 *
139 */
140 public Propagator()
141 {
142 }
143
144 //
145
146 /**
147 *Clone, i.e. create a copy.
148 * Must be overriden in subclasses.
149 *
150 * @return new copy of this Propagator
151 */
152 public abstract Propagator newPropagator();
153
154 /**
155 *Propagate a track without error.
156 * Must be overriden in subclasses.
157 * This is implemented in PropDirected--typically subclasses
158 * will inherit from that and then not override this method.
159 *
160 * @param trv VTrack to propagate
161 * @param srf Surface to which to propagate
162 * @return propagation status
163 */
164 public PropStat vecProp(VTrack trv, Surface srf)
165 {
166 TrackDerivative tder = null;
167 return vecProp(trv, srf, tder);
168 }
169
170
171 /**
172 *propagate a track without error
173 *
174 * @param trv VTrack to propagate
175 * @param srf Surface to which to propagate
176 * @param tder TrackDerivative to update at srf
177 * @return propagation status
178 */
179 public abstract PropStat vecProp(VTrack trv, Surface srf,
180 TrackDerivative tder);
181
182 // Propagate a track without error in the specified direction.
183 // Must be overriden in subclasses.
184 /**
185 *propagate a track without error in the specified direction
186 *Must be overriden in subclasses.
187 *
188 * @param trv VTrack to propagate
189 * @param srf Surface to which to propagate
190 * @param dir direction in which to propagate
191 * @return propagation status
192 */
193 public PropStat vecDirProp(VTrack trv, Surface srf, PropDir dir)
194 {
195 TrackDerivative tder = null;
196 return vecDirProp(trv, srf, dir, tder);
197 }
198
199 /**
200 *propagate a track without error in the specified direction
201 *
202 * @param trv VTrack to propagate
203 * @param srf Surface to which to propagate
204 * @param dir direction in which to propagate
205 * @param tder TrackDerivative to update at srf
206 * @return propagation status
207 */
208 public abstract PropStat vecDirProp(VTrack trv, Surface srf, PropDir dir,
209 TrackDerivative tder);
210
211 // Propagate a track with error.
212 // Typically does not need to be overridden in subclasses.
213 /**
214 *propagate a track with error
215 *
216 * @param tre0 ETrack to propagate
217 * @param srf Surface to which to propagate
218 * @param tder TrackDerivative to update at srf
219 * @return propagation status
220 */
221 public PropStat errProp(ETrack tre0, Surface srf,
222 TrackDerivative tder)
223 {
224 // Default implementation of propagation with error. We ask
225 // for the derivative matrix and use it to update the error
226 // matrix.
227 ETrack tre = tre0;
228 PropStat pstat = vecProp(tre,srf,tder);
229 if ( ! pstat.success() ) return pstat;
230 TrackError err = tre.error();
231 tre.setError( err.Xform(tder) );
232 if ( tre.checkError() != 0 )
233 {
234 return new PropStat();
235 }
236 //cng tre0 = tre;
237 tre0 = new ETrack(tre);
238 return pstat;
239 }
240
241
242 // Propagate a track with error.
243 // Typically does not need to be overridden in subclasses.
244 /**
245 *propagate a track with error
246 *Typically does not need to be overridden in subclasses.
247 *
248 * @param tre0 ETrack to propagate
249 * @param srf Surface to which to propagate
250 * @return propagation status
251 */
252 public PropStat errProp(ETrack tre0, Surface srf)
253 {
254 TrackDerivative tder = null;
255 return errProp(tre0, srf, tder);
256 }
257
258 // Same as above with direction specified.
259
260 // Propagate a track with error in the specified direction.
261 // Typically does not need to be overridden in subclasses.
262 /**
263 *propagate a track with error in the specified direction
264 *Typically does not need to be overridden in subclasses.
265 *
266 * @param tre0 ETrack to propagate
267 * @param srf Surface to which to propagate
268 * @param dir direction in which to propagate
269 * @return propagation status
270 */
271 public PropStat errDirProp(ETrack tre0, Surface srf, PropDir dir)
272 {
273 TrackDerivative tder = null;
274 return errDirProp( tre0, srf, dir, tder);
275 }
276
277 /**
278 *propagate a track with error in the specified direction
279 *
280 * @param tre0 ETrack to propagate
281 * @param srf Surface to which to propagate
282 * @param dir direction in which to propagate
283 * @param tder TrackDerivative to update at srf
284 * @return propagation status
285 */
286 public PropStat errDirProp(ETrack tre0, Surface srf, PropDir dir,
287 TrackDerivative tder)
288 {
289 // want to change incoming ETrack!
290 ETrack tre = tre0;
291 TrackDerivative deriv;
292 if (tder != null)
293 {
294 deriv = tder;
295 }
296 else
297 {
298 deriv = new TrackDerivative();
299 }
300 //System.out.println("\n deriv= "+deriv);
301 //System.out.println("\n srf= "+srf);
302 PropStat pstat = vecDirProp(tre,srf,dir,deriv);
303 if ( ! pstat.success() ) return pstat;
304 //System.out.println("\n pstat= "+pstat+"\n tre= "+tre);
305 TrackError err = tre.error();
306 TrackError tmp = err.Xform(deriv);
307 //tre.set_error( err.Xform(deriv) );
308 tre.setError( tmp );
309 if ( tre.checkError() != 0 )
310 {
311 return new PropStat();
312 }
313 tre0 = new ETrack(tre);
314 return pstat;
315 }
316 }