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
12
13
14
15
16
17
18 public class ThinZPlaneMsSim extends SimInteractor
19 {
20
21
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
31
32
33 private Random _r;
34
35
36 private double _radLength;
37
38
39
40
41
42
43
44
45
46
47
48 public ThinZPlaneMsSim( double radLengths )
49 {
50 _radLength = radLengths;
51 _r = new Random();
52 }
53
54
55
56
57
58
59
60
61
62
63
64
65 public void interact( VTrack vtrk )
66 {
67 TrackVector trv = new TrackVector( vtrk.vector() );
68
69
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.;
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
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
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
131
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
155
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
167
168 vtrk.setVectorAndKeepDirection( trv );
169
170 }
171
172
173
174
175
176
177
178 public double radLength()
179 {
180 return _radLength;
181 }
182
183
184
185
186
187
188
189
190
191 public SimInteractor newCopy()
192 {
193 return new ThinZPlaneMsSim(_radLength);
194 }
195
196
197
198
199
200
201
202
203 public String toString()
204 {
205 return "ThinZPlaneMsSim with "+_radLength+" radiation lengths";
206 }
207
208 }