1 package org.lcsim.lcio;
2
3 import hep.io.sio.SIOInputStream;
4 import hep.io.sio.SIOOutputStream;
5 import hep.io.sio.SIORef;
6 import hep.physics.particle.properties.ParticlePropertyManager;
7 import hep.physics.particle.properties.ParticleType;
8 import hep.physics.particle.properties.UnknownParticleIDException;
9 import hep.physics.vec.BasicHep3Vector;
10 import hep.physics.vec.BasicHepLorentzVector;
11 import hep.physics.vec.Hep3Vector;
12 import hep.physics.vec.HepLorentzVector;
13
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
18 import org.lcsim.event.MCParticle;
19
20
21
22
23
24
25
26 public class SIOMCParticle implements MCParticle
27 {
28 private int pdg;
29 private int generatorStatus;
30 private int simulatorStatus;
31 private Hep3Vector vertex;
32 private Hep3Vector endPoint;
33 private HepLorentzVector p;
34 private float mass;
35 private float charge;
36 private float time;
37 private List<MCParticle> daughters;
38 private List<MCParticle> parents;
39 private SimulatorStatus simStatus = new Status();
40 protected float[] spin = new float[3];
41 protected int[] colorFlow = new int[2];
42
43 private List temp = new ArrayList();
44
45 SIOMCParticle(SIOInputStream in, int flags, int version) throws IOException
46 {
47 boolean hasEndPoint = false;
48 in.readPTag(this);
49
50 if (version == 8)
51 {
52 in.readPntr();
53 in.readPntr();
54
55 int nDaughters = in.readInt();
56 for (int i = 0; i < nDaughters; i++)
57 temp.add(in.readPntr());
58
59 hasEndPoint = (nDaughters == 0);
60 }
61 else
62 {
63 int nParents = in.readInt();
64 for (int i = 0; i < nParents; i++)
65 {
66 temp.add(in.readPntr());
67 }
68 }
69 pdg = in.readInt();
70 generatorStatus = in.readInt();
71 if (version != 8)
72 {
73 simulatorStatus = in.readInt();
74 hasEndPoint = LCIOUtil.bitTest(simulatorStatus, Status.BITEndpoint);
75 simulatorStatus = LCIOUtil.bitSet(simulatorStatus, Status.BITEndpoint, false);
76 }
77 vertex = new BasicHep3Vector(in.readDouble(), in.readDouble(), in.readDouble());
78
79 if (version > 1002)
80 time = in.readFloat();
81
82 Hep3Vector momentum = new BasicHep3Vector(in.readFloat(), in.readFloat(), in.readFloat());
83 mass = in.readFloat();
84 double e = Math.sqrt(mass * mass + momentum.magnitudeSquared());
85 p = new BasicHepLorentzVector(e, momentum);
86 charge = in.readFloat();
87 if (hasEndPoint)
88 {
89 endPoint = new BasicHep3Vector(in.readDouble(), in.readDouble(), in.readDouble());
90 }
91
92
93 if (version >= 1060)
94 {
95 spin[0] = in.readFloat();
96 spin[1] = in.readFloat();
97 spin[2] = in.readFloat();
98
99 colorFlow[0] = in.readInt();
100 colorFlow[1] = in.readInt();
101 }
102 }
103
104 void resolve(int version)
105 {
106 if (version == 8)
107 {
108 for (int i = 0; i < temp.size(); i++)
109 {
110 SIOMCParticle daughter = (SIOMCParticle) ((SIORef) temp.get(i)).getObject();
111 this.addDaughter(daughter);
112 }
113 }
114 else
115 {
116 for (int i = 0; i < temp.size(); i++)
117 {
118 SIOMCParticle parent = (SIOMCParticle) ((SIORef) temp.get(i)).getObject();
119 parent.addDaughter(this);
120 }
121 }
122 temp = null;
123 }
124
125 private void addDaughter(SIOMCParticle child)
126 {
127 if (daughters == null)
128 daughters = new ArrayList<MCParticle>();
129 daughters.add(child);
130 child.addParent(this);
131 }
132
133 private void addParent(SIOMCParticle parent)
134 {
135 if (parents == null)
136 parents = new ArrayList<MCParticle>();
137 parents.add(parent);
138 }
139
140 public void setTime(double newTime)
141 {
142 time = (float) newTime;
143 }
144
145 public ParticleType getType()
146 {
147 return ParticlePropertyManager.getParticlePropertyProvider().get(pdg);
148 }
149
150 public double getProductionTime()
151 {
152 return time;
153 }
154
155 public List<MCParticle> getParents()
156 {
157 return parents == null ? Collections.EMPTY_LIST : parents;
158 }
159
160 public double getCharge()
161 {
162 return charge;
163 }
164
165 public List<MCParticle> getDaughters()
166 {
167 return daughters == null ? Collections.EMPTY_LIST : daughters;
168 }
169
170 public double getEnergy()
171 {
172 return p.t();
173 }
174
175 public int getGeneratorStatus()
176 {
177 return generatorStatus;
178 }
179
180 public double getMass()
181 {
182 return mass;
183 }
184
185 public Hep3Vector getMomentum()
186 {
187 return p.v3();
188 }
189
190 public Hep3Vector getOrigin()
191 {
192 return vertex;
193 }
194
195 public double getOriginX()
196 {
197 return vertex.x();
198 }
199
200 public double getOriginY()
201 {
202 return vertex.y();
203 }
204
205 public double getOriginZ()
206 {
207 return vertex.z();
208 }
209
210 public double getPX()
211 {
212 return p.v3().x();
213 }
214
215 public double getPY()
216 {
217 return p.v3().y();
218 }
219
220 public double getPZ()
221 {
222 return p.v3().z();
223 }
224
225 public Hep3Vector getEndPoint()
226 {
227 if (endPoint == null)
228 {
229 for (MCParticle daughter : getDaughters())
230 {
231 if (!daughter.getSimulatorStatus().vertexIsNotEndpointOfParent())
232 {
233 return daughter.getOrigin();
234 }
235 }
236 throw new RuntimeException("MCParticle end point not available");
237 }
238 else
239 return endPoint;
240 }
241
242 public SimulatorStatus getSimulatorStatus()
243 {
244 return simStatus;
245 }
246
247 static void write(MCParticle particle, SIOOutputStream out, int flags) throws IOException
248 {
249 out.writePTag(particle);
250 List<MCParticle> parents = particle.getParents();
251 out.writeInt(parents.size());
252
253 for (MCParticle parent : parents)
254 {
255 out.writePntr(parent);
256 }
257
258 out.writeInt(particle.getType().getPDGID());
259 out.writeInt(particle.getGeneratorStatus());
260 boolean shouldExplicityWriteOutEndPoint = true;
261 for (MCParticle daughter : particle.getDaughters())
262 {
263 if (!daughter.getSimulatorStatus().vertexIsNotEndpointOfParent())
264 {
265 shouldExplicityWriteOutEndPoint = false;
266 }
267 }
268 Hep3Vector endPoint = null;
269 if (shouldExplicityWriteOutEndPoint)
270 {
271 try
272 {
273 endPoint = particle.getEndPoint();
274 }
275 catch (Exception x)
276 {
277 shouldExplicityWriteOutEndPoint = false;
278 }
279 }
280 int simStatus = particle.getSimulatorStatus().getValue();
281 simStatus = LCIOUtil.bitSet(simStatus, Status.BITEndpoint, shouldExplicityWriteOutEndPoint);
282 out.writeInt(simStatus);
283
284 out.writeDouble(particle.getOriginX());
285 out.writeDouble(particle.getOriginY());
286 out.writeDouble(particle.getOriginZ());
287
288 out.writeFloat((float) particle.getProductionTime());
289
290 out.writeFloat((float) particle.getPX());
291 out.writeFloat((float) particle.getPY());
292 out.writeFloat((float) particle.getPZ());
293 out.writeFloat((float) particle.getMass());
294 try
295 {
296 out.writeFloat((float) particle.getCharge());
297 }
298 catch (UnknownParticleIDException x)
299 {
300 out.writeFloat(0);
301 }
302 if (shouldExplicityWriteOutEndPoint)
303 {
304 out.writeDouble(endPoint.x());
305 out.writeDouble(endPoint.y());
306 out.writeDouble(endPoint.z());
307 }
308
309
310 float[] spin = particle.getSpin();
311 out.writeFloat((float) spin[0]);
312 out.writeFloat((float) spin[1]);
313 out.writeFloat((float) spin[2]);
314
315
316 int[] colorFlow = particle.getColorFlow();
317 out.writeInt(colorFlow[0]);
318 out.writeInt(colorFlow[1]);
319 }
320
321 public int getPDGID()
322 {
323 return pdg;
324 }
325
326 public HepLorentzVector asFourVector()
327 {
328 return p;
329 }
330
331 public float[] getSpin()
332 {
333 return spin;
334 }
335
336 public int[] getColorFlow()
337 {
338 return colorFlow;
339 }
340
341 private class Status implements SimulatorStatus
342 {
343 public boolean vertexIsNotEndpointOfParent()
344 {
345 return (simulatorStatus & (1 << BITVertexIsNotEndpointOfParent)) != 0;
346 }
347
348 public boolean isStopped()
349 {
350 return (simulatorStatus & (1 << BITStopped)) != 0;
351 }
352
353 public boolean isDecayedInTracker()
354 {
355 return (simulatorStatus & (1 << BITDecayedInTracker)) != 0;
356 }
357
358 public boolean isDecayedInCalorimeter()
359 {
360 return (simulatorStatus & (1 << BITDecayedInCalorimeter)) != 0;
361 }
362
363 public boolean isCreatedInSimulation()
364 {
365 return (simulatorStatus & (1 << BITCreatedInSimulation)) != 0;
366 }
367
368 public boolean isBackscatter()
369 {
370 return (simulatorStatus & (1 << BITBackscatter)) != 0;
371 }
372
373 public boolean hasLeftDetector()
374 {
375 return (simulatorStatus & (1 << BITLeftDetector)) != 0;
376 }
377
378 public int getValue()
379 {
380 return simulatorStatus;
381 }
382
383
384 private final static int BITEndpoint = 31;
385 private final static int BITCreatedInSimulation = 30;
386 private final static int BITBackscatter = 29;
387 private final static int BITVertexIsNotEndpointOfParent = 28;
388 private final static int BITDecayedInTracker = 27;
389 private final static int BITDecayedInCalorimeter = 26;
390 private final static int BITLeftDetector = 25;
391 private final static int BITStopped = 24;
392 }
393 }