View Javadoc

1   package org.lcsim.recon.tracking.trfdca;
2   
3   
4   import org.lcsim.recon.tracking.trfutil.Assert;
5   import org.lcsim.recon.tracking.trfutil.TRFMath;
6   
7   import org.lcsim.recon.tracking.spacegeom.CylindricalPointVector;
8   import org.lcsim.recon.tracking.spacegeom.SpacePoint;
9   import org.lcsim.recon.tracking.spacegeom.SpacePath;
10  import org.lcsim.recon.tracking.spacegeom.CartesianPoint;
11  import org.lcsim.recon.tracking.spacegeom.CartesianPath;
12  import org.lcsim.recon.tracking.spacegeom.CylindricalPath;
13  import org.lcsim.recon.tracking.spacegeom.SpacePointVector;
14  
15  import org.lcsim.recon.tracking.trfbase.Surface;
16  import org.lcsim.recon.tracking.trfbase.PureStat;
17  import org.lcsim.recon.tracking.trfbase.CrossStat;
18  import org.lcsim.recon.tracking.trfbase.TrackVector;
19  import org.lcsim.recon.tracking.trfbase.TrackError;
20  import org.lcsim.recon.tracking.trfbase.TrackSurfaceDirection;
21  import org.lcsim.recon.tracking.trfbase.VTrack;
22  
23  /**
24   * Defines the pure surface corresponding to the point (Distance)
25   * of Closest Approach (DCA) of a track from a given origin.
26   *<p>
27   * The surface parameter is the angle alpha from the radial direction
28   * to the direction of the track:
29   * <li>  alpha = phi_direction-phi_position .
30   * By definition, alpha = +/- pi/2 for the DCA surface.
31   * <p>
32   * A track on a DCA surface would normally be parametrized by:
33   * (r, phi_position, z, tan(lamda), q/pT).
34   * In order to make the parameters continous when a track crosses
35   * the origin, however, a modified set of parameters has been chosen:
36   *<p>
37   * <li>alpha_positive = abs(alpha) = pi/2        for the DCA surface,
38   * <li> r
39   * <li>z
40   * <li>phi_direction
41   * <li>tan(lamda)
42   * <li>q/pT)
43   *<p>
44   * where:
45   * <li>  r_signed = sign(alpha) * r
46   * <li>  phi_direction = alpha + phi_position
47   *<p>
48   * The method get_parameter is designed to always return +pi/2
49   * and the method safe_pure_equal is designed to always return true.
50   *
51   * The crossing status of a track and the DCA surface is defined
52   * as following:
53   *<pre>
54   *  at      - the pure surface of the track is the DCA surface
55   *  on      - the track vector is on the DCA surface,
56   *            i.e. the angle from the radial direction to
57   *            the direction of the track is equal to pi/2
58   *            (in absolute value)
59   *  inside  - the track vector points towards the origin,
60   *            i.e. the angle from the radial direction to
61   *            the direction of the track is greater than pi/2
62   *            (in absolute value)
63   *  outside - the track vector points away from the origin,
64   *            i.e. the angle from the radial direction to
65   *            the direction of the track is less than pi/2
66   *            (in absolute value)
67   *</pre>
68   * Note that all angles are defined from -pi to pi.
69   *
70   *
71   *@author Norman A. Graf
72   *@version 1.0
73   *
74   */
75  public class SurfDCA extends Surface
76  {
77      
78      
79      // Parameters   ******************************************
80      
81      // Track parameters.
82      public static final int IRSIGNED=0;
83      public static final int IZ = 1;
84      public static final int IPHID=2;
85      public static final int ITLM=3;
86      public static final int IQPT=4;
87      
88      // Surface Parameters
89      public static final int IX =0;
90      public static final int IY=1;
91      public static final int IDXDZ=2;
92      public static final int IDYDZ=3;
93      
94      private double _x;
95      private double _y;
96      private double _dxdz;
97      private double _dydz;
98      
99      
100     // static methods
101     
102     //
103     
104     /**
105      *Return a String representation of the class'  type name.
106      *Included for completeness with the C++ version.
107      *
108      * @return   A String representation of the class' the type name.
109      */
110     public static String typeName()
111     { return "SurfDCA";
112     }
113     
114     //
115     
116     /**
117      *Return a String representation of the class' type name.
118      *Included for completeness with the C++ version.
119      *
120      * @return   A String representation of the class' type name.
121      */
122     public static String staticType()
123     { return typeName();
124     }
125     
126     // Methods   *********************************************
127     
128     
129     
130     //
131     
132     /**
133      *Construct a default instance .
134      *
135      */
136     
137     public SurfDCA()
138     {
139         this(0., 0., 0., 0.);
140     }
141     
142     /**
143      *Construct a default instance .
144      *
145      */
146     
147     public SurfDCA(double x, double y)
148     {
149         this(x, y, 0., 0.);
150     }
151     
152     
153     /**
154      *Construct a fully qualified instance .
155      *
156      */
157     
158     public SurfDCA(double x, double y, double dxdz, double dydz)
159     {
160         _x = x;
161         _y = y;
162         _dxdz = dxdz;
163         _dydz = dydz;
164     }
165     
166     
167     /**
168      * Return a copy of the underlying pure Surface.
169      *
170      * @return The underlying SurfCylinder.
171      */
172     public Surface newPureSurface()
173     {
174         return new SurfDCA();
175         
176     }
177     
178     //
179     
180     /**
181      *Return a String representation of the class'  type name.
182      *Included for completeness with the C++ version.
183      *
184      * @return   A String representation of the class' the type name.
185      */
186     public String pureType()
187     { return staticType();
188     }
189     
190     //
191     
192     /**
193      *Return the surface parameter.
194      *
195      * @param   ipar The surface parameter index. There is none for a DCA.
196      * @return 0.
197      */
198     public double parameter(int ipar)
199     {
200         Assert.assertTrue( ipar == IX || ipar == IY || ipar == IDXDZ || ipar == IDYDZ );
201         if( ipar == IX ) return _x;
202         else if ( ipar == IY ) return _y;
203         else if ( ipar == IDXDZ ) return _dxdz;
204         else return _dydz;
205     }
206     
207     
208     /**
209      *output stream
210      *
211      * @return The String representation of this instance.
212      */
213     public String toString()
214     {
215         return "DCA Surface to ("+_x+","+_y+") with slope ("+_dxdz+","+_dydz+")";
216     }
217     
218     //
219     
220     /**
221      *Find the crossing status for a track vector without error.
222      *
223      * @param   trv The VTrack to test.
224      * @return The crossing status.
225      */
226     public CrossStat pureStatus(VTrack trv )
227     {
228         // If the track surface is the same as this, return at.
229         Surface srf = trv.surface();
230         if ( equals(srf)  || pureEqual(srf) ) return new CrossStat(PureStat.AT);
231         // Otherwise extract the space vector and set flags using alpha.
232         double   vrtrk = trv.spacePath().v_rxy();
233         double vphitrk = trv.spacePath().v_phi();
234         double tan_a = vphitrk/vrtrk;
235         double atrk = Math.atan(vphitrk/vrtrk);
236         if ( (tan_a > 0.0) && (vrtrk < 0.0) )
237         {
238             atrk = Math.atan(vphitrk/vrtrk) - Math.PI;
239         }
240         if ( (tan_a < 0.0) && (vrtrk < 0.0) )
241         {
242             atrk = Math.atan(vphitrk/vrtrk) + Math.PI;
243         }
244         double asrf = TRFMath.PI2;
245         double prec = CrossStat.staticPrecision();
246         if ( Math.abs(atrk-asrf) < prec ) return new CrossStat(PureStat.ON);
247         if ( Math.abs(atrk) < asrf ) return new CrossStat(PureStat.OUTSIDE);
248         return new CrossStat(PureStat.INSIDE);
249     }
250     
251     //
252     
253     /**
254      * Return the vector difference of two tracks on this surface.
255      *
256      * @param   vec1 The first TrackVector.
257      * @param   vec2 The second TrackVector.
258      * @return The difference TrackVector.
259      */
260     public TrackVector vecDiff(TrackVector vec1,TrackVector vec2 )
261     {
262         TrackVector diff = new TrackVector(vec1);
263         diff = diff.minus(vec2);
264         diff.set(IPHID, TRFMath.fmod2( diff.get(IPHID), TRFMath.TWOPI ));
265         return diff;
266         
267     }
268     
269     //
270     
271     /**
272      *Return the space point for a track vector.
273      *
274      * @param   vec The TrackVector at this Surface.
275      * @return The SpacePoint for the track vec on this Surface.
276      */
277     public SpacePoint spacePoint(TrackVector vec )
278     {
279         double r    = Math.abs(vec.get(0));
280         double z    = vec.get(1);
281         double sign = 0.0;
282         double phi  = 0.0;
283         if ( vec.get(0) != 0.0 )
284         {
285             sign = vec.get(0)/Math.abs(vec.get(0));
286             phi  = vec.get(2)-(sign*TRFMath.PI2);
287             phi  = TRFMath.fmod2( phi, TRFMath.TWOPI );
288         }
289         double x = r*Math.cos(phi) + _x + _dxdz*z;
290         double y = r*Math.sin(phi) + _y + _dydz*z;
291         return new CartesianPoint( x, y, z );
292     }
293     
294     //
295     
296     
297     /**
298      *Return the space vector for a track vector.
299      *     dr/ds = cos(lambda)*cos(alpha)
300      * r*dphi/ds = cos(lambda)*sin(alpha)
301      *     dz/ds = sin(lambda)
302      *
303      * @param   vec The TrackVector at this Surface.
304      * @param   dir The direction for this track on this surface.
305      * @return The SpacePath for this track on this surface.
306      */
307     public SpacePath spacePath(TrackVector vec,
308             TrackSurfaceDirection dir )
309     {
310         /*
311         double r    = Math.abs(vec.get(0));
312         double z    = vec.get(1);
313         double sign = 0.0;
314         double phi  = 0.0;
315         if ( vec.get(0) != 0.0 )
316         {
317             sign = vec.get(0)/Math.abs(vec.get(0));
318             phi  = vec.get(2)-(sign*TRFMath.PI2);
319             phi  = TRFMath.fmod2( phi, TRFMath.TWOPI );
320         }
321         double tlam = vec.get(3);
322         double salf = sign;
323         double calf = 0.0;
324         double slam = tlam/Math.sqrt(1.0+tlam*tlam);
325         double clam = 1.0/Math.sqrt(1.0+tlam*tlam);
326         double dr_ds     = clam*calf;
327         double r_dphi_ds = clam*salf;
328         double dz_ds     = slam;
329         return new CylindricalPath(r, phi, z, dr_ds, r_dphi_ds, dz_ds);
330          */
331         double r    = Math.abs(vec.get(0));
332         double z    = vec.get(1);
333         double sign = 1.0;
334         if(vec.get(0) < 0.0) sign = -1.;
335         double phi  =  vec.get(2)-(sign*TRFMath.PI2);
336         phi  = TRFMath.fmod2( phi, TRFMath.TWOPI );
337         
338         double tlam = vec.get(3);
339         double salf = sign;
340         double calf = 0.0;
341         double slam = tlam/Math.sqrt(1.0+tlam*tlam);
342         double clam = 1.0/Math.sqrt(1.0+tlam*tlam);
343         double dr_ds     = clam*calf;
344         double r_dphi_ds = clam*salf;
345         double dz_ds     = slam;
346         SpacePointVector sp = new CylindricalPointVector(r, phi, z, dr_ds, r_dphi_ds, dz_ds);
347         double x = sp.x() + _x + _dxdz*z;
348         double y = sp.y() + _y + _dydz*z;
349         return new CartesianPath(x, y, sp.z(), sp.x(), sp.y(), sp.z());
350         
351     }
352     
353     //
354     
355     /**
356      *Return the signed inverse momentum, q/p.
357      *
358      * @param   vec The TrackVector on this Surface.
359      * @return The signed inverse momentum for track vec.
360      */
361     public double qOverP( TrackVector vec)
362     {
363         double tlam = vec.get(ITLM);
364         double clam = 1.0/Math.sqrt(1.0+tlam*tlam);
365         Assert.assertTrue( clam != 0.0 );
366         return vec.get(IQPT)*clam;
367         
368     }
369     
370     
371     
372     // Return true if two surfaces have the same pure surface.
373     // Argument may be safely downcast.
374     protected boolean safePureEqual( Surface srf)
375     {
376         return true;
377     }
378     
379     // Return true if two surfaces are ordered.
380     // Argument may be safely downcast.
381     protected boolean safePureLessThan( Surface srf)
382     {
383         return false;
384     }
385     
386     //
387     
388     /**
389      *Return the direction.
390      * Forward is radially outward.
391      *
392      * @param   vec The TrackVector on this Surface.
393      * @return The direction of trackvec on this surface.
394      */
395     public  TrackSurfaceDirection direction( TrackVector vec)
396     {
397         return TrackSurfaceDirection.TSD_FORWARD;
398     }
399     
400     
401     // Accessors.
402     public double x()
403     {
404         return x(0.);
405     }
406     public double y()
407     {
408         return y(0.);
409     }
410     public double x(double z)
411     {
412         return _x + _dxdz*z;
413     }
414     public double y(double z)
415     {
416         return _y + _dydz*z;
417     }
418     public double dXdZ()
419     {
420         return _dxdz;
421     }
422     public double dYdZ()
423     {
424         return _dydz;
425     }
426     
427     
428 }