View Javadoc

1   package org.lcsim.recon.tracking.trfcylplane;
2   
3   
4   import org.lcsim.recon.tracking.trfbase.Propagator;
5   import org.lcsim.recon.tracking.trfbase.PropDirected;
6   import org.lcsim.recon.tracking.trfbase.PropDir;
7   import org.lcsim.recon.tracking.trfbase.TrackVector;
8   import org.lcsim.recon.tracking.trfbase.TrackDerivative;
9   import org.lcsim.recon.tracking.trfxyp.PropXYXY;
10  import org.lcsim.recon.tracking.trfbase.PropStat;
11  import org.lcsim.recon.tracking.trfutil.TRFMath;
12  import org.lcsim.recon.tracking.trfutil.Assert;
13  import org.lcsim.recon.tracking.trfxyp.SurfXYPlane;
14  import org.lcsim.recon.tracking.trfzp.SurfZPlane;
15  import org.lcsim.recon.tracking.trfbase.Surface;
16  import org.lcsim.recon.tracking.trfbase.VTrack;
17  import org.lcsim.recon.tracking.trfbase.ETrack;
18  
19  /**
20   * Propagates tracks from a ZPlane to an XYPlane in a constant magnetic field.
21   *<p>
22   * Propagation will fail if either the origin is not a ZPlane
23   * or destination is not a XYPlane.
24   * Propagator works incorrectly for tracks with very small curvatures
25   *<p>
26   *@author Norman A. Graf
27   *@version 1.0
28   *
29   */
30  
31  public class PropZXY extends PropDirected
32  {
33      
34      // Assign track parameter indices.
35      
36      private static final int IV = SurfXYPlane.IV;
37      private static final int   IZ   = SurfXYPlane.IZ;
38      private static final int   IDVDU = SurfXYPlane.IDVDU;
39      private static final int   IDZDU = SurfXYPlane.IDZDU;
40      private static final int   IQP_XY  = SurfXYPlane.IQP;
41      
42      private static final int   IX = SurfZPlane.IX;
43      private static final int   IY   = SurfZPlane.IY;
44      private static final int   IDXDZ = SurfZPlane.IDXDZ;
45      private static final int   IDYDZ = SurfZPlane.IDYDZ;
46      private static final int   IQP_Z  = SurfZPlane.IQP;
47      
48      
49      // attributes
50      
51      private double _bfac;
52      private PropXYXY _propxyxy;
53      
54      // static methods
55      
56      // Return the type name.
57      /**
58       *Return a String representation of the class' type name.
59       *Included for completeness with the C++ version.
60       *
61       * @return   A String representation of the class' type name.
62       */
63      public static String typeName()
64      { return "PropZXY";
65      }
66      
67      // Return the type.
68      /**
69       *Return a String representation of the class' type name.
70       *Included for completeness with the C++ version.
71       *
72       * @return   A String representation of the class' type name.
73       */
74      public static String staticType()
75      { return typeName();
76      }
77      
78      
79      
80      // constructor from magnetic field in Tesla.
81      /**
82       *Construct an instance from a constant solenoidal magnetic field in Tesla.
83       *
84       * @param   bfield The magnetic field strength in Tesla.
85       */
86      public PropZXY(double bfield)
87      {
88          _bfac = TRFMath.BFAC*bfield;
89          _propxyxy = new PropXYXY(bfield);
90      }
91      
92      
93      // Clone.
94      /**
95       *Clone an instance.
96       *
97       * @return A Clone of this instance.
98       */
99      public Propagator newPropagator( )
100     {
101         return new PropZXY(bField());
102         
103     }
104     
105     /**
106      *Propagate a track without error in the specified direction
107      *and return the derivative matrix in deriv.
108      *
109      * The track parameters for a cylinder are:
110      * phi z alpha tan(lambda) curvature
111      *
112      * @param   trv The VTrack to propagate.
113      * @param   srf The Surface to which to propagate.
114      * @param   dir The direction in which to propagate.
115      * @param   deriv The track derivatives to update at the surface srf.
116      * @return The propagation status.
117      */
118     public PropStat vecDirProp( VTrack trv, Surface srf,
119             PropDir dir, TrackDerivative deriv )
120     {
121         
122         PropStat pstat = new PropStat();
123         Propagator.reduceDirection(dir);
124         
125         // Check destination is a XYPlane.
126         Assert.assertTrue( srf.pureType().equals(SurfXYPlane.staticType()) );
127         if ( !srf.pureType( ).equals(SurfXYPlane.staticType()) )
128             return pstat;
129         SurfXYPlane sxyp2 = ( SurfXYPlane ) srf;
130         
131         // Fetch phi of the destination plane
132         
133         int iphi  = SurfXYPlane.NORMPHI;
134         double phi_n = sxyp2.parameter(iphi);
135         VTrack trv0 = trv; // we want to change this vector!
136         TrackDerivative deriv1 = new TrackDerivative();
137         TrackDerivative deriv2 = new TrackDerivative();
138         TrackDerivative lderiv = deriv;
139         if ( deriv != null ) pstat = vecTransformZXY( _bfac, trv0, phi_n, dir,deriv1 );
140         else pstat = vecTransformZXY( _bfac, trv0, phi_n, dir, lderiv );
141         if ( ! pstat.success() ) return pstat;
142         
143         if ( deriv != null ) pstat = _propxyxy.vecDirProp(trv0,srf,dir,deriv2);
144         else  pstat = _propxyxy.vecDirProp(trv0,srf,dir, lderiv);
145         if ( pstat.success() )
146         {
147             trv = trv0;
148             if ( deriv != null )  deriv.set(deriv2.times(deriv1));
149         }
150         return pstat;
151     }
152     
153     /**
154      *Propagate a track without error in the specified direction.
155      *
156      * The track parameters for a cylinder are:
157      * phi z alpha tan(lambda) curvature
158      *
159      * @param   trv The VTrack to propagate.
160      * @param   srf The Surface to which to propagate.
161      * @param   dir The direction in which to propagate.
162      * @return The propagation status.
163      */
164     public PropStat vecDirProp( VTrack trv, Surface srf,
165             PropDir dir)
166     {
167         TrackDerivative deriv = null;
168         return vecDirProp(trv, srf, dir, deriv);
169         
170     }
171     
172     /**
173      *Return the strength of the magnetic field in Tesla.
174      *
175      * @return The strength of the magnetic field in Tesla.
176      */
177     public double bField()
178     {
179         return _bfac/TRFMath.BFAC;
180     }
181     
182     // Return the type.
183     /**
184      *Return a String representation of the class' type name.
185      *Included for completeness with the C++ version.
186      *
187      * @return   A String representation of the class' type name.
188      */
189     public String type()
190     { return staticType();
191     }
192     
193     /**
194      *output stream
195      * @return  A String representation of this instance.
196      */
197     public String toString()
198     {
199         return "ZPlane-XYPlane propagation with constant "
200                 + bField() + " Tesla field";
201         
202     }
203     
204     //**********************************************************************
205     
206     // Private function to propagate a track without error
207     // The corresponding track parameters are:
208     // On ZPlane:
209     // z (cm) is fixed
210     // 0 - x (cm)
211     // 1 - y (cm)
212     // 2 - dx/dz
213     // 3 - dy/dz
214     // 4 - q/p   p is momentum of a track, q is its charge
215     // On XYPlane:
216     // u (cm) is fixed
217     // 0 - v (cm)
218     // 1 - z (cm)
219     // 2 - dv/du
220     // 3 - dz/du
221     // 4 - q/p   p is momentum of a track, q is its charge
222     // If pderiv is nonzero, return the derivative matrix there.
223     
224     private PropStat
225             vecTransformZXY( double B, VTrack trv, double phi_n,
226             PropDir dir,
227             TrackDerivative deriv )
228     {
229         
230         // construct return status
231         PropStat pstat = new PropStat();
232         
233         // fetch the originating surface and vector
234         Surface srf1 = trv.surface();
235         // TrackVector vec1 = trv.get_vector();
236         
237         // Check origin is a ZPlane.
238         Assert.assertTrue( srf1.pureType().equals(SurfZPlane.staticType()) );
239         if ( !srf1.pureType( ).equals(SurfZPlane.staticType()) )
240             return pstat;
241         SurfZPlane szp1 = ( SurfZPlane ) srf1;
242         
243         
244         // Fetch the zpos's of the planes and the starting track vector.
245         int izpos  = SurfZPlane.ZPOS;
246         
247         double zpos_0 = szp1.parameter(izpos);
248         
249         TrackVector vec = trv.vector();
250         double a1 = vec.get(IX);                  // x
251         double a2 = vec.get(IY);                  // y
252         double a3 = vec.get(IDXDZ);               // dx/dz
253         double a4 = vec.get(IDYDZ);               // dy/dz
254         double a5 = vec.get(IQP_Z);               // q/p
255         
256         int sign_dz = 0;
257         if(trv.isForward())  sign_dz =  1;
258         if(trv.isBackward()) sign_dz = -1;
259         if(sign_dz == 0)
260         {
261             System.out.println("PropZXY._vec_propagate: Unknown direction of a track ");
262             System.exit(1);
263         }
264         
265         double sinphi_n = Math.sin(phi_n);
266         double cosphi_n = Math.cos(phi_n);
267         
268         double  u =  a1*cosphi_n + a2*sinphi_n;
269         if( u < 0. )
270         {
271             u = - u;
272             sinphi_n = - sinphi_n;
273             cosphi_n = - cosphi_n;
274             phi_n = phi_n + Math.PI;
275             if( phi_n >= TRFMath.TWOPI) phi_n -= TRFMath.TWOPI;
276         }
277         // check if du == 0 ( that is track moves parallel to the destination plane )
278         double du_dz = a3*cosphi_n + a4*sinphi_n;
279         if(du_dz == 0.) return pstat;
280         
281         double a_hat_phin = 1./du_dz;
282         double a_hat_phin2 = a_hat_phin*a_hat_phin;
283         
284         // double  u =  a1*cosphi_n + a2*sinphi_n;
285         double b1 = -a1*sinphi_n + a2*cosphi_n;
286         double b2 = zpos_0;
287         double b3 = (a4*cosphi_n - a3*sinphi_n)*a_hat_phin;
288         double b4 = a_hat_phin;
289         double b5 = a5;
290         
291         int sign_du = 0;
292         if(b4*sign_dz > 0) sign_du =  1;
293         if(b4*sign_dz < 0) sign_du = -1;
294         
295         vec.set(IV     , b1);
296         vec.set(IZ     , b2);
297         vec.set(IDVDU  , b3);
298         vec.set(IDZDU  , b4);
299         vec.set(IQP_XY , b5);
300         
301         // Update trv
302         SurfXYPlane sxyp = new SurfXYPlane(u,phi_n);
303         trv.setSurface(sxyp.newPureSurface());
304         trv.setVector(vec);
305         
306         // set new direction of the track
307         if(sign_du ==  1) trv.setForward();
308         if(sign_du == -1) trv.setBackward();
309         
310         // Set the return status.
311         pstat.setSame();
312         
313         // exit now if user did not ask for error matrix.
314         if ( deriv == null ) return pstat;
315         
316         double b34_hat = Math.sqrt(1 + b3*b3 + b4*b4);
317         double rsinphi =  (b5*B)*sign_du*b34_hat;
318         
319         // du_da
320         
321         double du_da1 = cosphi_n;
322         double du_da2 = sinphi_n;
323         
324         // db1_da
325         
326         double db1_da1 = - sinphi_n;
327         double db1_da2 =   cosphi_n;
328         
329         // db3_da
330         
331         double db3_da3 = -a4*a_hat_phin2;
332         double db3_da4 =  a3*a_hat_phin2;
333         
334         // db4_da
335         
336         double db4_da3 = - cosphi_n*a_hat_phin2;
337         double db4_da4 = - sinphi_n*a_hat_phin2;
338         
339         
340         // db3_n_db
341         
342         double db3_n_du  = -(1. + b3*b3)*rsinphi;
343         
344         // db4_n_db
345         
346         double db4_n_du  = -b4*b3*rsinphi;
347         
348         // db5_n_db
349         
350         
351         // db1_n_da
352         
353         double db1_n_da1 = -b3 * du_da1 + db1_da1;
354         double db1_n_da2 = -b3 * du_da2 + db1_da2;
355         double db1_n_da3 = 0.;
356         double db1_n_da4 = 0.;
357         double db1_n_da5 = 0.;
358         
359         // db2_n_da
360         
361         double db2_n_da1 = -b4 * du_da1;
362         double db2_n_da2 = -b4 * du_da2;
363         double db2_n_da3 = 0.;
364         double db2_n_da4 = 0.;
365         double db2_n_da5 = 0.;
366         
367         // db3_n_da
368         
369         double db3_n_da1 = db3_n_du * du_da1;
370         double db3_n_da2 = db3_n_du * du_da2;
371         double db3_n_da3 = db3_da3;
372         double db3_n_da4 = db3_da4;
373         double db3_n_da5 = 0.;
374         
375         // db4_n_da
376         
377         double db4_n_da1 = db4_n_du * du_da1;
378         double db4_n_da2 = db4_n_du * du_da2;
379         double db4_n_da3 = db4_da3;
380         double db4_n_da4 = db4_da4;
381         double db4_n_da5 = 0.;
382         
383         // db5_n_da
384         
385         double db5_n_da1 = 0.;
386         double db5_n_da2 = 0.;
387         double db5_n_da3 = 0.;
388         double db5_n_da4 = 0.;
389         double db5_n_da5 = 1.;
390         
391         deriv.set(IV,IX        , db1_n_da1);
392         deriv.set(IV,IY        , db1_n_da2);
393         deriv.set(IV,IDXDZ     , db1_n_da3);
394         deriv.set(IV,IDYDZ     , db1_n_da4);
395         deriv.set(IV,IQP_Z     , db1_n_da5);
396         deriv.set(IZ,IX        , db2_n_da1);
397         deriv.set(IZ,IY        , db2_n_da2);
398         deriv.set(IZ,IDXDZ     , db2_n_da3);
399         deriv.set(IZ,IDYDZ     , db2_n_da4);
400         deriv.set(IZ,IQP_Z     , db2_n_da5);
401         deriv.set(IDVDU,IX     , db3_n_da1);
402         deriv.set(IDVDU,IY     , db3_n_da2);
403         deriv.set(IDVDU,IDXDZ  , db3_n_da3);
404         deriv.set(IDVDU,IDYDZ  , db3_n_da4);
405         deriv.set(IDVDU,IQP_Z  , db3_n_da5);
406         deriv.set(IDZDU,IX     , db4_n_da1);
407         deriv.set(IDZDU,IY     , db4_n_da2);
408         deriv.set(IDZDU,IDXDZ  , db4_n_da3);
409         deriv.set(IDZDU,IDYDZ  , db4_n_da4);
410         deriv.set(IDZDU,IQP_Z  , db4_n_da5);
411         deriv.set(IQP_XY,IX    , db5_n_da1);
412         deriv.set(IQP_XY,IY    , db5_n_da2);
413         deriv.set(IQP_XY,IDXDZ , db5_n_da3);
414         deriv.set(IQP_XY,IDYDZ , db5_n_da4);
415         deriv.set(IQP_XY,IQP_Z , db5_n_da5);
416         
417         return pstat;
418     }
419     
420     
421 }
422