View Javadoc

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   * SIO implementation of {@link org.lcsim.event.MCParticle}.
22   * @author Tony Johnson
23   * @author Jeremy McCormick
24   * @version $Id: SIOMCParticle.java,v 1.13 2011/08/24 18:51:18 jeremy Exp $
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          // Spin and colorflow for versions 1.60 and greater.
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         // Spin.
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         // Color flow.
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         // define the bit positions for the simulation flag
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 }