View Javadoc

1   package  org.lcsim.recon.tracking.trfzp;
2   
3   
4   import java.util.Random;
5   
6   import org.lcsim.recon.tracking.trfbase.SimInteractor;
7   import org.lcsim.recon.tracking.trfbase.VTrack;
8   import org.lcsim.recon.tracking.trfbase.TrackVector;
9   
10  /**
11   * Class for adding Multiple Scattering to track vectors defined at
12   * ZPlanes.  Single point interaction is assumed.
13   *
14   *@author Norman A. Graf
15   *@version 1.0
16   *
17   */
18  public class ThinZPlaneMsSim extends SimInteractor
19  {
20      // static attributes
21      // Assign track parameter indices.
22      
23      private static final int IX = SurfZPlane.IX;
24      private static final int IY   = SurfZPlane.IY;
25      private static final int IDXDZ = SurfZPlane.IDXDZ;
26      private static final int IDYDZ = SurfZPlane.IDYDZ;
27      private static final int IQP  = SurfZPlane.IQP;
28      
29      
30      // attributes
31      
32      // random number generator
33      private Random _r;
34      
35      // radiation lengths in material
36      private double _radLength;
37      
38      //
39      
40      /**
41       * Construct an instance from the number of radiation
42       * lengths of the thin z plane material.
43       * The Interactor is constructed with the
44       * appropriate number of radiation lengths.
45       *
46       * @param   radLengths The thickness of the material in radiation lengths.
47       */
48      public ThinZPlaneMsSim( double radLengths )
49      {
50          _radLength = radLengths;
51          _r = new Random();
52      }
53      
54      //
55      
56      /**
57       *Interact the given track in this thin z plane,
58       *using the thin material approximation for multiple scattering.
59       *Note that the track parameters are modified to simulate
60       *the effects of multiple scattering in traversing the thin z
61       *plane of material.
62       *
63       * @param   vtrk  The Vrack to scatter.
64       */
65      public void interact( VTrack vtrk )
66      {
67          TrackVector trv = new TrackVector( vtrk.vector() );
68          // first, how much should the track be scattered:
69          // uses radlength from material and angle track - plane (leyer)
70          double  trackMomentum = trv.get(IQP);
71          
72          double f = trv.get(IDXDZ);
73          double g = trv.get(IDYDZ);
74          
75          double theta = Math.atan(Math.sqrt(f*f + g*g));
76          double phi = 0.;
77          if (f != 0.) phi = Math.atan(Math.sqrt((g*g)/(f*f)));
78          if (f == 0.0 && g < 0.0) phi = 3.*Math.PI/2.;
79          if (f == 0.0 && g > 0.0) phi = Math.PI/2.;
80          if (f == 0.0 && g == 0.0)
81          {
82              phi = 99.;// that we can go on further.....
83              System.out.println(" DXDY and DXDZ both 0");
84          }
85          if((f<0)&&(g>0))
86              phi = Math.PI - phi;
87          if((f<0)&&(g<0))
88              phi = Math.PI + phi;
89          if((f>0)&&(g<0))
90              phi = 2*Math.PI - phi;
91          
92          double trueLength = _radLength/Math.cos(theta);
93          
94          double scatRMS = (0.0136)*trackMomentum*Math.sqrt(trueLength)*
95                  (1 + 0.038*Math.log(trueLength));
96          
97          double zhat = Math.sqrt(1-Math.sin(theta)*Math.sin(theta));
98          double xhat = Math.sin(theta)*Math.cos(phi);
99          double yhat = Math.sin(theta)*Math.sin(phi);
100         
101         double[] scatterVec = new double[3];
102         double[] finalVec = new double[3];
103         double[][] Rotation = new double[3][3];
104         
105         //set Rotation matrix as given in D0note ????
106         Rotation[0][0] = -yhat;
107         Rotation[0][1] = -zhat*xhat;
108         Rotation[0][2] = xhat;
109         Rotation[1][0] = xhat;
110         Rotation[1][1] = -zhat*yhat;
111         Rotation[1][2] = yhat;
112         Rotation[2][0] = 0;
113         Rotation[2][1] = xhat*xhat+yhat*yhat;
114         Rotation[2][2] = zhat;
115         
116         //now set the Vector after scattering ( (0,0,1) ->( theta1, theta2, 1)*norm)
117         scatterVec[0] = scatRMS*_r.nextGaussian();
118         scatterVec[1] = scatRMS*_r.nextGaussian();
119         scatterVec[2] = 1.0;
120         double norm = Math.sqrt(scatterVec[0]*scatterVec[0] + scatterVec[1]*scatterVec[1]
121                 + scatterVec[2]*scatterVec[2]);
122         
123         if (norm!=0)
124         {
125             scatterVec[0] /= norm;
126             scatterVec[1] /= norm;
127             scatterVec[2] /= norm;
128         };
129         
130         //now go back to the global coordinate system
131         //leave that step out if track coodsys = global coordsys
132         double finalxz;
133         double finalyz;
134         if (phi != 99.)
135         {
136             for (int k = 0; k<3; k++)
137             {
138                 finalVec[k] = 0.;
139                 for (int l = 0; l<3 ; l++)
140                 {
141                     finalVec[k] += Rotation[k][l]*scatterVec[l];
142                 }
143             }
144             finalxz = finalVec[0]/finalVec[2];
145             finalyz = finalVec[1]/finalVec[2];
146         }
147         else
148         {
149             finalxz = scatterVec[0];
150             finalyz = scatterVec[1];
151         };
152         
153         
154         // calculate new qpt
155         //qpt' = qpt * Math.sin theta' / Math.sin theta
156         double fprime = finalxz;
157         double gprime = finalyz;
158         double thetaprime = Math.atan(Math.sqrt(fprime*fprime + gprime*gprime));
159         
160         double zqprime = trackMomentum*Math.sin(thetaprime)/(Math.sqrt(1-zhat*zhat));
161         
162         trv.set(IDXDZ, finalxz);
163         trv.set(IDYDZ, finalyz);
164         trv.set(IQP, zqprime);
165         
166         // assume that we don't encounter back-scattering... which is
167         // assumed above anyway.
168         vtrk.setVectorAndKeepDirection( trv );
169         
170     }
171     
172     
173     /**
174      *Return the number of radiation lengths of material in this thin z plane.
175      *
176      * @return The number of radiation lengths.
177      */
178     public double radLength()
179     {
180         return _radLength;
181     }
182     
183     //
184     
185     /**
186      * Make a clone of this object.
187      * Note that new copy will have a different random number generator.
188      *
189      * @return A Clone of this instance.
190      */
191     public SimInteractor newCopy()
192     {
193         return new ThinZPlaneMsSim(_radLength);
194     }
195     
196     
197     
198     /**
199      *output stream
200      *
201      * @return A String representation of this instance.
202      */
203     public String toString()
204     {
205         return "ThinZPlaneMsSim with "+_radLength+" radiation lengths";
206     }
207     
208 }