1
2
3
4 package org.lcsim.mc.fast.tracking.fix;
5
6 import static java.lang.Math.PI;
7 import static java.lang.Math.abs;
8 import static java.lang.Math.sqrt;
9 import static org.lcsim.event.LCIOParameters.ParameterName.omega;
10 import static org.lcsim.event.LCIOParameters.ParameterName.phi0;
11 import hep.physics.matrix.SymmetricMatrix;
12 import hep.physics.vec.Hep3Vector;
13
14 import java.io.IOException;
15 import java.util.Random;
16
17 import org.lcsim.conditions.ConditionsManager;
18 import org.lcsim.conditions.ConditionsSet;
19 import org.lcsim.event.EventHeader;
20 import org.lcsim.event.LCIOParameters;
21 import org.lcsim.event.MCParticle;
22 import org.lcsim.event.Track;
23 import org.lcsim.mc.fast.tracking.ResolutionTable;
24 import org.lcsim.mc.fast.tracking.SimpleTables;
25 import org.lcsim.mc.fast.tracking.TrackResolutionTables;
26 import org.lcsim.spacegeom.SpacePoint;
27 import org.lcsim.spacegeom.SpaceVector;
28 import org.lcsim.util.swim.HelixSwimmer;
29
30 import Jama.EigenvalueDecomposition;
31 import Jama.Matrix;
32 import Jama.util.Maths;
33
34
35
36
37
38
39 public class FastMCTrackFactory {
40 private TrackResolutionTables _tables;
41 private SimpleTables _simpleTables;
42 private ConditionsManager _manager;
43 private double _Bz;
44 private HelixSwimmer _swimmer;
45 private static Random rDummy = new Random();
46 private static SpacePoint pDummy = new SpacePoint();
47
48
49
50
51
52
53
54 public FastMCTrackFactory(EventHeader event, boolean beamConstraint) {
55 this(event.getDetectorName(), event.getDetector().getFieldMap().getField(new double[3])[2], beamConstraint);
56 }
57
58
59
60
61
62 public FastMCTrackFactory(String detectorName, double field, boolean beamConstraint) {
63 _Bz = field;
64 _manager = ConditionsManager.defaultInstance();
65 try {
66
67 _manager.setDetector(detectorName, 0);
68 } catch (ConditionsManager.ConditionsNotFoundException e) {
69 System.err.print("Conditions for detector " + detectorName + " not found!");
70 }
71 ConditionsSet trackParameters = _manager.getConditions("TrackParameters");
72 ConditionsSet simpleTrack = _manager.getConditions("SimpleTrack");
73 try {
74 _tables = new TrackResolutionTables(trackParameters, beamConstraint);
75 _simpleTables = new SimpleTables(simpleTrack);
76 } catch (IOException e) {
77 }
78 _swimmer = new HelixSwimmer(field);
79 }
80
81
82
83
84
85
86 public Track getTrack(MCParticle part) {
87 FastMCTrack t = (FastMCTrack) getTrack(part.getMomentum(), part.getOrigin(), (int) part.getCharge());
88 t._particle = part;
89 return t;
90 }
91
92
93
94
95
96
97 public Track getUnsmearedTrack(MCParticle part) {
98 FastMCTrack t = (FastMCTrack) getTrack(new SpaceVector(part.getMomentum()), new SpacePoint(part.getOrigin()), pDummy, (int) part.getCharge(), rDummy, false);
99 t._particle = part;
100 return t;
101 }
102
103
104
105
106
107
108
109
110
111 public Track getTrack(SpaceVector momentum, SpacePoint location, int charge) {
112 return getTrack(momentum, location, pDummy, charge, rDummy);
113 }
114
115
116
117
118
119
120
121
122
123
124 public Track getTrack(SpaceVector momentum, SpacePoint location, int charge, Random random) {
125 return getTrack(momentum, location, pDummy, charge, random);
126 }
127
128
129
130
131
132
133
134
135
136
137 public Track getTrack(SpaceVector momentum, SpacePoint location, SpacePoint referencePoint, int charge) {
138 return getTrack(momentum, location, referencePoint, charge, rDummy);
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152 public Track getTrack(SpaceVector momentum, SpacePoint location, SpacePoint referencePoint, int charge, Random random, boolean shouldISmear) {
153 _swimmer.setTrack(momentum, location, charge);
154 double alpha = _swimmer.getTrackLengthToPoint(referencePoint);
155 SpacePoint poca = _swimmer.getPointAtLength(alpha);
156 SpaceVector momentumAtPoca = _swimmer.getMomentumAtLength(alpha);
157 LCIOParameters parameters = LCIOParameters.SpaceMomentum2Parameters(poca, momentumAtPoca, referencePoint, charge, _Bz);
158 SymmetricMatrix errorMatrix = new SymmetricMatrix(5);
159
160 double cosTheta = abs(momentumAtPoca.cosTheta());
161 double p_mag = momentumAtPoca.magnitude();
162 ResolutionTable table = cosTheta < _tables.getPolarInner() ? _tables.getBarrelTable() : _tables.getEndcapTable();
163 for (int i = 0; i < 5; i++) {
164 for (int j = 0; j <= i; j++) {
165 double iVal = table.findTable(i, j).interpolateVal(cosTheta, p_mag);
166 errorMatrix.setElement(i, j, iVal);
167 }
168 }
169
170 LCIOParameters smearParams = shouldISmear ? smearParameters(parameters, errorMatrix, random) : parameters;
171
172
173
174
175
176
177
178 return new FastMCTrack(referencePoint, smearParams, errorMatrix, charge);
179 }
180
181
182
183
184
185
186
187
188
189
190
191 public Track getTrack(SpaceVector momentum, SpacePoint location, SpacePoint referencePoint, int charge, Random random) {
192 return getTrack(momentum, location, referencePoint, charge, random, true);
193 }
194
195 public Track getTrack(Hep3Vector momentum, Hep3Vector location, int charge) {
196 return getTrack(new SpaceVector(momentum), new SpacePoint(location), pDummy, charge, rDummy);
197 }
198
199
200
201
202
203
204 public void setNewReferencePoint(Track track, SpacePoint referencePoint) {
205 _swimmer.setTrack(track);
206 double alpha = _swimmer.getTrackLengthToPoint(referencePoint);
207
208
209
210 throw new RuntimeException("not yet implemented !");
211 }
212
213
214
215
216
217
218
219
220 private static LCIOParameters smearParameters(LCIOParameters oldParams, SymmetricMatrix sm, Random random) {
221 Matrix errorMatrix = Maths.toJamaMatrix(sm);
222 EigenvalueDecomposition eigen = errorMatrix.eig();
223 double[] realEigen = eigen.getRealEigenvalues();
224 double[] imaginaryEigen = eigen.getImagEigenvalues();
225 Matrix eigenValues = eigen.getV();
226 if (eigenValues.det() == 0) {
227 throw new RuntimeException("ErrorMatrix does not have orthogonal basis");
228 }
229 for (int i = 0; i < imaginaryEigen.length; i++) {
230 if (imaginaryEigen[i] != 0)
231 throw new RuntimeException("ErrorMatrix has imaginary eigenvalues");
232 }
233 Matrix x = new Matrix(5, 1);
234 for (int i = 0; i < 5; i++) {
235 if (realEigen[i] <= 0)
236 throw new RuntimeException("non-positive eigenvalue encountered");
237 x.set(i, 0, sqrt(realEigen[i]) * random.nextGaussian());
238 }
239 Matrix shift = eigenValues.times(x);
240 Matrix params = new Matrix(oldParams.getValues(), 5);
241
242 double[] parameters = params.plus(shift).getColumnPackedCopy();
243 double pt = oldParams.getPt() * oldParams.get(omega) / parameters[omega.ordinal()];
244
245 if (parameters[phi0.ordinal()] > PI) {
246 parameters[phi0.ordinal()] -= 2 * PI;
247 } else if (parameters[phi0.ordinal()] < -PI) {
248 parameters[phi0.ordinal()] += 2 * PI;
249 }
250 return new LCIOParameters(parameters, pt);
251 }
252 }