View Javadoc

1   package org.lcsim.recon.tracking.trfxyp;
2   // ThinXYPlaneMs
3   
4   import org.lcsim.recon.tracking.trfutil.Assert;
5   import org.lcsim.recon.tracking.trfutil.TRFMath;
6   
7   import org.lcsim.recon.tracking.trfbase.ETrack;
8   import org.lcsim.recon.tracking.trfbase.TrackError;
9   import org.lcsim.recon.tracking.trfbase.TrackVector;
10  import org.lcsim.recon.tracking.trfbase.Surface;
11  import org.lcsim.recon.tracking.trfbase.Interactor;
12  import org.lcsim.recon.tracking.trfbase.PropDir;
13  /**
14   *
15   * Class for modifying the covariance matrix of a track to account
16   * for multiple scattering at a thin XY-plane whose material is
17   *represented by the number of radiation lengths.
18   *
19   *@author Norman A. Graf
20   *@version 1.0
21   *
22   */
23  public class ThinXYPlaneMs extends Interactor
24  {
25      
26      // static methods
27      
28      /**
29       *Return a String representation of the class' type name.
30       *Included for completeness with the C++ version.
31       *
32       * @return   A String representation of the class' type name.
33       */
34      public static String typeName()
35      { return "ThinXYPlaneMs"; }
36      
37      /**
38       *Return a String representation of the class' type name.
39       *Included for completeness with the C++ version.
40       *
41       * @return   A String representation of the class' type name.
42       */
43      public static String staticType()
44      { return typeName(); }
45      
46      // static attributes
47      // Assign track parameter indices.
48      
49      private static final int IV = SurfXYPlane.IV;
50      private static final int IZ   = SurfXYPlane.IZ;
51      private static final int IDVDU = SurfXYPlane.IDVDU;
52      private static final int IDZDU = SurfXYPlane.IDZDU;
53      private static final int IQP  = SurfXYPlane.IQP;
54      
55      //attributes
56      private  double _radLength;
57      
58      //non-static methods
59      
60      // Constructor.  The Interactor is constructed with the
61      // appropriate number of radiation lengths.
62      
63      /**
64       * Construct an instance from the number of radiation
65       * lengths of the thin xy plane material.
66       * The Interactor is constructed with the
67       * appropriate number of radiation lengths.
68       *
69       * @param   radLength The thickness of the material in radiation lengths.
70       */
71      public ThinXYPlaneMs(double radLength)
72      {
73          _radLength = radLength;
74      }
75      
76      /**
77       *Interact the given track in this xy plane,
78       *using the thin material approximation for multiple scattering.
79       *Note that the track parameters are not modified. Only the
80       *covariance matrix is updated to reflect the uncertainty caused
81       *by traversing the thin xy plane of material.
82       *
83       * @param   tre The ETrack to scatter.
84       */
85      public void interact(ETrack tre)
86      {
87          
88          // This can only be used with XYplanes... check that we have one..
89          
90          SurfXYPlane XYpl = new SurfXYPlane( 10.0, 0.0 );
91          Surface srf = tre.surface();
92          Assert.assertTrue( srf.pureType().equals(XYpl.pureType()) );
93          
94          TrackError cleanError = tre.error();
95          TrackError newError = new TrackError(cleanError);
96          
97          // set the rms scattering appropriate to this momentum
98          
99          // Theta = (0.0136 GeV)*(z/p)*(sqrt(radLength))*(1+0.038*log(radLength))
100         
101         
102         
103         TrackVector theVec = tre.vector();
104         double trackMomentum = theVec.get(IQP);
105         
106         double f = theVec.get(IDVDU);
107         double g = theVec.get(IDZDU);
108         
109         double theta = Math.atan(Math.sqrt(f*f + g*g));
110         double phi = f!=0. ? Math.atan(Math.sqrt((g*g)/(f*f))) : TRFMath.PI2;
111         if ( f==0 && g<0 ) phi=3*TRFMath.PI2;
112         if((f<0)&&(g>0))
113             phi = Math.PI - phi;
114         if((f<0)&&(g<0))
115             phi = Math.PI + phi;
116         if((f>0)&&(g<0))
117             phi = 2*Math.PI - phi;
118         
119         double trueLength = _radLength/Math.cos(theta);
120         
121         double stdTheta = (0.0136)*trackMomentum*Math.sqrt(trueLength)*
122                 (1 + 0.038*Math.log(trueLength));
123         
124         double uhat = Math.sqrt(1-Math.sin(theta)*Math.sin(theta));
125         double vhat = Math.sin(theta)*Math.cos(phi);
126         double zhat = Math.sin(theta)*Math.sin(phi);
127         
128         double Qvu,Qzu,Qvz;
129         
130         // The MS covariance matrix can now be set.
131         
132         // **************** code for matrix ***********************//
133         
134         // Insert values for upper triangle... use symmetry to set lower.
135         
136         double norm = Math.sqrt(vhat*vhat + zhat*zhat);
137         
138         Qvu = (zhat/(norm*uhat))*(zhat/(norm*uhat));
139         Qvu += Math.pow((vhat/norm)*(1 + (norm*norm)/(uhat*uhat)),2.0);
140         Qvu *= stdTheta;
141         Qvu *= stdTheta;
142         
143         Qzu = (vhat/(norm*uhat))*(vhat/(norm*uhat));
144         Qzu += Math.pow((zhat/norm)*(1 + (norm*norm)/(uhat*uhat)),2.0);
145         Qzu *= stdTheta;
146         Qzu *= stdTheta;
147         
148         Qvz = - vhat*zhat/(uhat*uhat);
149         Qvz += vhat*zhat/(norm*norm)*Math.pow((1 + (norm*norm)/(uhat*uhat)),2.0);
150         Qvz *= stdTheta;
151         Qvz *= stdTheta;
152         
153         newError.set(IDVDU,IDVDU, newError.get(IDVDU,IDVDU) + Qvu);
154         newError.set(IDZDU,IDZDU, newError.get(IDZDU,IDZDU) + Qzu);
155         newError.set(IDVDU,IDZDU, newError.get(IDVDU,IDZDU) + Qvz);
156         
157         
158         tre.setError( newError );
159         
160     }
161     
162     // method for adding the interaction with direction
163     public void interact_dir(ETrack tre, PropDir dir)
164     {
165         interact(tre);
166     }
167     
168     /**
169      *Return the number of radiation lengths.
170      *
171      * @return The thickness of the scattering material in radiation lengths.
172      */
173     public double radLength()
174     {
175         return _radLength;
176     }
177     
178     /**
179      *Make a clone of this object.
180      *
181      * @return A Clone of this instance.
182      */
183     public Interactor newCopy()
184     {
185         return new ThinXYPlaneMs(_radLength);
186     }
187     
188     
189     /**
190      *Return a String representation of the class' type name.
191      *Included for completeness with the C++ version.
192      *
193      * @return   A String representation of the class' type name.
194      */
195     public String type()
196     { return staticType(); }
197     
198     /**
199      *output stream
200      *
201      * @return  A String representation of this instance.
202      */
203     public String toString()
204     {
205         return "ThinXYPlaneMs with "+_radLength+" radiation lengths";
206     }
207     
208     
209     
210     
211 }
212