1 package org.lcsim.recon.tracking.trfcyl;
2
3 import org.lcsim.recon.tracking.trfutil.Assert;
4
5 import org.lcsim.recon.tracking.trfbase.Interactor;
6 import org.lcsim.recon.tracking.trfbase.ETrack;
7 import org.lcsim.recon.tracking.trfbase.PropDir;
8 import org.lcsim.recon.tracking.trfbase.Propagator;
9 import org.lcsim.recon.tracking.trfbase.Surface;
10 import org.lcsim.recon.tracking.trfbase.TrackError;
11 import org.lcsim.recon.tracking.trfbase.TrackVector;
12
13 import org.lcsim.recon.tracking.trfeloss.DeDx;
14
15 import static org.lcsim.recon.tracking.trfcyl.SurfCylinder.IALF;
16 import static org.lcsim.recon.tracking.trfcyl.SurfCylinder.IPHI;
17 import static org.lcsim.recon.tracking.trfcyl.SurfCylinder.IQPT;
18 import static org.lcsim.recon.tracking.trfcyl.SurfCylinder.ITLM;
19 import static org.lcsim.recon.tracking.trfcyl.SurfCylinder.IZ;
20
21 import static java.lang.Math.abs;
22 import static java.lang.Math.sqrt;
23 import static java.lang.Math.cos;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class CylEloss extends Interactor
38 {
39
40
41
42 private double _thickness;
43 private DeDx _dedx;
44
45
46
47
48
49
50
51
52
53
54
55 public CylEloss(double thickness, DeDx dedx)
56 {
57 _thickness = thickness;
58 _dedx = dedx;
59 }
60
61
62
63
64
65
66
67
68
69
70
71
72 public void interact(ETrack tre)
73 {
74
75
76 SurfCylinder cyl = new SurfCylinder(10.0);
77 Surface srf = tre.surface();
78 Assert.assertTrue( srf.pureType().equals(cyl.pureType()) );
79
80 TrackError cleanError = tre.error();
81 TrackError newError = new TrackError(cleanError);
82
83 TrackVector theVec = tre.vector();
84 TrackVector newVector = new TrackVector(theVec);
85
86 double pionMass = 0.13957;
87 double ptmax = 10000.;
88
89 double pinv = Math.abs(theVec.get(SurfCylinder.IQPT)*Math.cos(Math.atan(theVec.get(SurfCylinder.ITLM))));
90
91
92
93
94 double sign = 1;
95 if(pinv < 1./ptmax)
96 pinv = 1./ptmax;
97 else
98 sign = theVec.get(SurfCylinder.IQPT)/Math.abs(theVec.get(SurfCylinder.IQPT));
99
100
101
102 double trackEnergy = Math.sqrt(1./pinv/pinv+pionMass*pionMass);
103
104 double trueLength = _thickness/Math.abs(Math.cos(theVec.get(SurfCylinder.IALF)))/
105 Math.cos(Math.atan(theVec.get(SurfCylinder.ITLM)));
106
107 double stdEnergy = _dedx.sigmaEnergy(trackEnergy, trueLength);
108
109 double stdMomentum = stdEnergy;
110
111
112
113 if(tre.isTrackBackward()) trueLength = -trueLength;
114 trackEnergy = _dedx.loseEnergy(trackEnergy, trueLength);
115
116 double newMomentum = trackEnergy>pionMass ?
117 Math.sqrt(trackEnergy*trackEnergy-
118 pionMass*pionMass): 1./pinv;
119
120
121 newVector.set(SurfCylinder.IQPT, 1./newMomentum/Math.cos(Math.atan(theVec.get(SurfCylinder.ITLM)))*sign);
122
123
124 double stdVec = theVec.get(SurfCylinder.IQPT)*theVec.get(SurfCylinder.IQPT)*stdMomentum*Math.cos(Math.atan(
125 theVec.get(SurfCylinder.ITLM)));
126 stdVec *= stdVec;
127 newError.set(SurfCylinder.IQPT, SurfCylinder.IQPT, newError.get(SurfCylinder.IQPT, SurfCylinder.IQPT) + stdVec);
128
129 tre.setVectorAndKeepDirection(newVector);
130 tre.setError( newError );
131
132 }
133
134 public void interact_dir(ETrack theTrack, PropDir direction )
135 {
136
137
138 Surface srf = theTrack.surface();
139 Assert.assertTrue( srf instanceof SurfCylinder );
140
141
142
143 Propagator.reduceDirection(direction);
144 Assert.assertTrue(direction == PropDir.FORWARD || direction == PropDir.BACKWARD);
145
146 TrackError cleanError = theTrack.error();
147 TrackError newError = new TrackError(cleanError);
148
149 TrackVector theVec = theTrack.vector();
150 TrackVector newVector = new TrackVector(theVec);
151
152 double pionMass = 0.13957;
153 double ptmax = 10000.;
154
155 double tanlm = theVec.get(ITLM);
156 double coslm = 1. / sqrt(1. + tanlm*tanlm);
157 double pinv = abs(theVec.get(IQPT)*coslm);
158
159
160
161
162 int sign = 1;
163 if ( pinv < 1./ptmax )
164 pinv = 1./ptmax;
165 else
166 sign = (int) (theVec.get(IQPT)/abs(theVec.get(IQPT)));
167
168
169
170 double trackEnergy = sqrt(1./pinv/pinv+pionMass*pionMass);
171
172 double trueLength = _thickness/abs(cos(theVec.get(IALF)))/coslm;
173
174
175 double stdEnergy = _dedx.sigmaEnergy(trackEnergy, trueLength);
176
177 double stdMomentum = stdEnergy;
178 if(direction == PropDir.BACKWARD)
179 trueLength = -trueLength;
180 _dedx.loseEnergy(trackEnergy, trueLength);
181
182 double newMomentum = trackEnergy>pionMass ?
183 sqrt(trackEnergy*trackEnergy-
184 pionMass*pionMass): 1./pinv;
185
186
187 newVector.set(IQPT, 1./newMomentum/coslm*sign);
188
189
190 double stdVec = theVec.get(IQPT)*theVec.get(IQPT)*stdMomentum*coslm;
191 stdVec *= stdVec;
192 newError.set(IQPT, IQPT, newError.get(IQPT, IQPT) + stdVec);
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 theTrack.setVector(newVector);
209 theTrack.setError( newError );
210
211 }
212
213
214
215
216
217
218
219
220 public double thickness()
221 {
222 return _thickness;
223 }
224
225
226
227
228
229
230
231
232 public DeDx dEdX()
233 {
234 return _dedx;
235 }
236
237
238
239
240
241
242
243
244 public Interactor newCopy()
245 {
246 return new CylEloss(_thickness, _dedx);
247 }
248
249
250
251
252
253
254
255 public String toString()
256 {
257 return "CylEloss with thickness "+_thickness+" and energy loss "+_dedx;
258 }
259 }