View Javadoc

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