1 package org.lcsim.recon.tracking.trfzp;
2
3 import org.lcsim.recon.tracking.trfutil.Assert;
4 import org.lcsim.recon.tracking.trfutil.TRFMath;
5
6 import org.lcsim.recon.tracking.trfbase.ETrack;
7 import org.lcsim.recon.tracking.trfbase.TrackError;
8 import org.lcsim.recon.tracking.trfbase.TrackVector;
9 import org.lcsim.recon.tracking.trfbase.Surface;
10 import org.lcsim.recon.tracking.trfbase.VTrack;
11 import org.lcsim.recon.tracking.trfbase.Interactor;
12
13
14
15
16
17
18
19
20
21
22
23
24 public class ThinZPlaneMs extends Interactor
25 {
26
27
28
29
30
31
32
33
34
35
36
37 public static String typeName()
38 { return "ThinZPlaneMs"; }
39
40
41
42
43
44
45
46
47
48 public static String staticType()
49 { return typeName(); }
50
51
52
53
54 private static final int IX = SurfZPlane.IX;
55 private static final int IY = SurfZPlane.IY;
56 private static final int IDXDZ = SurfZPlane.IDXDZ;
57 private static final int IDYDZ = SurfZPlane.IDYDZ;
58 private static final int IQP = SurfZPlane.IQP;
59
60
61
62 private double _radLength;
63
64
65
66
67
68
69
70
71
72
73
74 public ThinZPlaneMs( double radLength )
75 {
76 _radLength = radLength;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90 public void interact(ETrack tre)
91 {
92
93 SurfZPlane szp = new SurfZPlane(1.0);
94 Surface srf = tre.surface();
95 Assert.assertTrue( srf.pureType().equals(szp.pureType()) );
96
97 TrackError cleanError = tre.error();
98 TrackError newError = new TrackError(cleanError);
99
100
101
102
103
104
105
106 TrackVector theVec = tre.vector();
107 double trackMomentum = theVec.get(IQP);
108
109 double f = theVec.get(IDXDZ);
110 double g = theVec.get(IDYDZ);
111
112 double theta = Math.atan(Math.sqrt(f*f + g*g));
113 double phi = f!=0 ? Math.atan(Math.sqrt((g*g)/(f*f))) : TRFMath.PI2;
114 if ( f==0 && g<0 ) phi=3*TRFMath.PI2;
115 if((f<0)&&(g>0))
116 phi = Math.PI - phi;
117 if((f<0)&&(g<0))
118 phi = Math.PI + phi;
119 if((f>0)&&(g<0))
120 phi = 2*Math.PI - phi;
121
122 double trueLength = _radLength/Math.cos(theta);
123
124 double stdTheta = (0.0136)*trackMomentum*Math.sqrt(trueLength)*
125 (1 + 0.038*Math.log(trueLength));
126
127 double zhat = Math.sqrt(1-Math.sin(theta)*Math.sin(theta));
128 double xhat = Math.sin(theta)*Math.cos(phi);
129 double yhat = Math.sin(theta)*Math.sin(phi);
130
131 double Qxz,Qyz,Qxy;
132
133
134
135
136
137
138
139
140 double norm = Math.sqrt(xhat*xhat + yhat*yhat);
141
142 Qxz = (yhat/(norm*zhat))*(yhat/(norm*zhat));
143 Qxz += Math.pow((xhat/norm)*(1 + (norm*norm)/(zhat*zhat)),2.0);
144 Qxz *= stdTheta;
145 Qxz *= stdTheta;
146
147 Qyz = (xhat/(norm*zhat))*(xhat/(norm*zhat));
148 Qyz += Math.pow((xhat/norm)*(1 + (norm*norm)/(zhat*zhat)),2.0);
149 Qyz *= stdTheta;
150 Qyz *= stdTheta;
151
152 Qxy = -xhat*yhat/(zhat*zhat);
153 Qxy += xhat*yhat/(norm*norm)*Math.pow((1 + (norm*norm)/(zhat*zhat)),2.0);
154 Qxy *= stdTheta;
155 Qxy *= stdTheta;
156
157 newError.set(IDXDZ,IDXDZ, newError.get(IDXDZ,IDXDZ) + Qxz);
158 newError.set(IDYDZ,IDYDZ, newError.get(IDYDZ,IDYDZ) + Qyz);
159 newError.set(IDXDZ,IDYDZ, newError.get(IDXDZ,IDYDZ) + Qxy);
160
161 /
162
163
164
165
166
167
168
169
170
171
172
173
174 public double radLength()
175 {
176 return _radLength;
177 }
178
179
180
181
182
183
184
185
186
187 public Interactor newCopy()
188 {
189 return new ThinZPlaneMs(_radLength);
190 }
191
192
193
194
195
196
197
198
199
200
201 public String type()
202 {
203 return staticType();
204 }
205
206
207
208
209
210
211
212
213 public String toString()
214 {
215 return "ThinZPlaneMs with "+_radLength+" radiation lengths";
216 }
217
218 }