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
8
9
10
11
12
13
14 public class ThinXYPlaneMsSim extends SimInteractor
15 {
16
17
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
25
26 private double _radLength;
27
28
29 private Random _r;
30
31
32
33
34
35
36
37
38
39 public ThinXYPlaneMsSim( double radLength )
40 {
41 _radLength = radLength;
42 _r = new Random();
43 }
44
45
46
47
48
49
50
51
52
53
54 public void interact( VTrack vtrk)
55 {
56
57 TrackVector trv = new TrackVector( vtrk.vector() );
58
59
60 double trackMomentum = trv.get(IQP);
61
62 double f = trv.get(IDVDU);
63 double g = trv.get(IDZDU);
64
65
66
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.;
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
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
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
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
148
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
164
165 vtrk.setVectorAndKeepDirection( trv );
166 }
167
168
169
170
171
172
173
174 public SimInteractor newCopy()
175 {
176 return new ThinXYPlaneMsSim(_radLength);
177 }
178
179
180
181
182
183
184 public double radLength()
185 {
186 return _radLength;
187 }
188
189 }
190
191