SlicDiagnostics/src/org/lcsim/slic/diagnostics
diff -u -r1.22 -r1.23
--- MCParticlePlots.java 21 Feb 2006 23:19:33 -0000 1.22
+++ MCParticlePlots.java 16 Mar 2006 02:35:22 -0000 1.23
@@ -2,35 +2,36 @@
import static java.lang.Math.log10;
import static java.lang.Math.sqrt;
-import hep.aida.ICloud1D;
-import hep.aida.ICloud2D;
-import hep.physics.vec.Hep3Vector;
-
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import hep.aida.ICloud1D;
+import hep.aida.ICloud2D;
+import hep.physics.vec.Hep3Vector;
+
import org.lcsim.event.Cluster;
import org.lcsim.event.EventHeader;
+import org.lcsim.event.EventHeader.LCMetaData;
import org.lcsim.event.MCParticle;
import org.lcsim.recon.cluster.cheat.CheatCluster;
/**
- * A set of MCParticle plots, including plots of each individual particle type.
+ * A set of MCParticle plots, including plots for each particle type by PDGID.
*
* @author jeremym
- * @version $Id: MCParticlePlots.java,v 1.22 2006/02/21 23:19:33 jeremy Exp $
+ * @version $Id: MCParticlePlots.java,v 1.23 2006/03/16 02:35:22 jeremy Exp $
*/
class MCParticlePlots extends AbstractPlots
{
// Plots
ICloud1D _count;
- ICloud1D _genFSE;
- ICloud1D _simFSE;
+ ICloud1D _totE;
+ ICloud1D _E;
ICloud1D _mcpVtxToEPDist;
ICloud1D _mcpVtxToEPDistLTMeV;
ICloud1D _mcpVtxToEPDistGTMeV;
- ICloud1D _mcpEnergyFinalState;
+ ICloud1D _mcpEnergy;
ICloud1D _mcpNeutralCount;
ICloud1D _mcpPositiveCount;
ICloud1D _mcpNegativeCount;
@@ -41,9 +42,9 @@
// Map of ParticleTypeInfo
private Map<Integer, MCParticleTypeInfo> _mcpMap = new HashMap<Integer, MCParticleTypeInfo>();
- public MCParticlePlots()
+ public MCParticlePlots(LCMetaData meta)
{
- super("MCParticles", null);
+ super("MCParticles", meta);
definePlots();
}
@@ -52,13 +53,13 @@
{
cd();
- _genFSE = aida().cloud1D("Event: Energy in Generator FS Particles");
- _genFSE.annotation().addItem("xAxisLabel", "Total Energy in Generator FS Particles (GeV)");
- _genFSE.annotation().addItem("yAxisLabel", "Number of Events");
-
- _simFSE = aida().cloud1D("Event: Energy in Simulator FS Particles");
- _simFSE.annotation().addItem("xAxisLabel", "Total Energy in Sim FS Particles (GeV)");
- _simFSE.annotation().addItem("yAxisLabel", "Number of Events");
+ _totE = aida().cloud1D("Event: Total Energy in All Particles");
+ _totE.annotation().addItem("xAxisLabel", "Energy (GeV)");
+ _totE.annotation().addItem("yAxisLabel", "Number of Events");
+
+ _E = aida().cloud1D("MCParticle Energy");
+ _E.annotation().addItem("xAxisLabel", "Energy (GeV)");
+ _E.annotation().addItem("yAxisLabel", "Number of Particles");
_endpointDau = aida().cloud1D("Number of Endpoint Daughters");
_endpointDau.annotation().addItem("xAxisLabel", "Number of End Point Daughters");
@@ -68,20 +69,20 @@
_count.annotation().addItem("xAxisLabel", "Number of Particles Per Event");
_count.annotation().addItem("yAxisLabel", "Number of Events");
- _mcpEnergyFinalState = aida().cloud1D("Event: Generator Final State Energies");
- _mcpEnergyFinalState.annotation().addItem("xAxisLabel", "Generator Final State Energy (GeV)");
- _mcpEnergyFinalState.annotation().addItem("yAxisLabel", "Number of Particles");
+ _mcpEnergy = aida().cloud1D("Event: Generator Final State Energies");
+ _mcpEnergy.annotation().addItem("xAxisLabel", "Generator Final State Energy (GeV)");
+ _mcpEnergy.annotation().addItem("yAxisLabel", "Number of Particles");
_mcpVtxToEPDist = aida().cloud1D("Vertex to Endpoint Distance");
- _mcpVtxToEPDist.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (log10(mm))");
+ _mcpVtxToEPDist.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (mm)");
_mcpVtxToEPDist.annotation().addItem("yAxisLabel", "Number of Particles");
_mcpVtxToEPDistLTMeV = aida().cloud1D("Vtx to EP Distance for kE < 1 MeV");
- _mcpVtxToEPDistLTMeV.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (log10(mm))");
+ _mcpVtxToEPDistLTMeV.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (mm)");
_mcpVtxToEPDistLTMeV.annotation().addItem("yAxisLabel", "Number of Particles");
_mcpVtxToEPDistGTMeV = aida().cloud1D("Vtx to EP Distance for kE > 1 MeV");
- _mcpVtxToEPDistGTMeV.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (log10(mm))");
+ _mcpVtxToEPDistGTMeV.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (mm)");
_mcpVtxToEPDistGTMeV.annotation().addItem("yAxisLabel", "Number of Particles");
_mcpNeutralCount = aida().cloud1D("Event: Neutral Charge Count");
@@ -140,15 +141,6 @@
cd();
- // Sim FS E
- double simFSE = 0;
-
- // Gen FS E
- double genFSE = 0;
-
- // Gen FS count
- int genFSCount = 0;
-
// Charge counts
int nPositive, nNeutral, nNegative;
nPositive = nNeutral = nNegative = 0;
@@ -162,12 +154,20 @@
// Make a new set of flag stats
MCParticleFlagStats flagStats = new MCParticleFlagStats();
+ double totEventE = 0;
+
// Main particle loop
for (MCParticle particle : particles)
{
// Energy
double energy = particle.getEnergy();
+ // Fill Energy
+ _E.fill(energy);
+
+ // Add to total event energy
+ totEventE += energy;
+
// Momentum
Hep3Vector p = particle.getMomentum();
double PX = p.x();
@@ -209,6 +209,9 @@
// Time
double time = particle.getProductionTime();
+ // Fill production time
+ _prodTime.fill(time);
+
// End Point
boolean hasEndpoint = true;
Hep3Vector endpoint = null;
@@ -223,7 +226,8 @@
eZ = endpoint.z();
// Plot vtx to EP distance if there is an End Point
- vtxEPdist = log10(MCParticleUtil.vertexToEndpointDistance(particle.getOrigin(), endpoint));
+ //vtxEPdist = log10(MCParticleUtil.vertexToEndpointDistance(particle.getOrigin(), endpoint));
+ vtxEPdist = MCParticleUtil.vertexToEndpointDistance(particle.getOrigin(), endpoint);
}
// No End Point
catch (RuntimeException rte)
@@ -231,18 +235,9 @@
hasEndpoint = false;
}
- // Plot production time
- if (time != 0)
- {
- _prodTime.fill(log10(time));
- }
- else {
- _prodTime.fill(0);
- }
-
// Create flags for this particle
MCParticleFlags flags = new MCParticleFlags(particle);
-
+
// Increment event flag stats
flagStats.incrFlagCounts(flags);
@@ -259,194 +254,177 @@
}
}
- // Particles without endpoint daughters are sim FS
- if (nendd == 0)
- {
- simFSE += energy;
- }
-
// Plot number of endpoint daughters
_endpointDau.fill(nendd);
}
- // Do plots for Gen FS particles
- if (particle.getGeneratorStatus() == MCParticle.FINAL_STATE)
- {
- // Increment gen FS count
- genFSCount += 1;
-
- // Increment gen FS E
- genFSE += energy;
-
- // Get info about this particle type
- MCParticleTypeInfo info = getMCParticleInfo(particle.getPDGID());
+ // Get info about this particle type
+ MCParticleTypeInfo info = getMCParticleInfo(particle.getPDGID());
- // Get particle name
- String particleName = info.getName();
-
- // Status flag counts
- info.incrFlagStats(particle);
+ // Get particle name
+ String particleName = info.getName();
- // Increment event energy
- info.addEventEnergy(particle.getEnergy());
+ // Status flag counts
+ info.incrFlagStats(particle);
- // Increment # of hits
- info.incrNumHits();
+ // Increment event energy
+ info.addEventEnergy(particle.getEnergy());
- // Plot Final State Energy
- _mcpEnergyFinalState.fill(particle.getEnergy());
+ // Increment # of hits
+ info.incrNumHits();
- // vtx to EP distance for gen FS particles
- if (hasEndpoint && vtxEPdist > 0)
- {
- // Plot vtx to EP distance
- _mcpVtxToEPDist.fill(vtxEPdist);
+ // Fill Energy
+ _mcpEnergy.fill(particle.getEnergy());
- // Plot vtx to EP distance for kE < 1 MeV
- if (kE < 0.001)
- {
- _mcpVtxToEPDistLTMeV.fill(vtxEPdist);
- }
- // Plot vtx to EP distance for kE > 1 MeV
- else
- {
- _mcpVtxToEPDistGTMeV.fill(vtxEPdist);
- }
- }
+ // vtx to EP distance for gen FS particles
+ if (hasEndpoint && vtxEPdist > 0)
+ {
+ // Fill vtx to EP distance
+ _mcpVtxToEPDist.fill(vtxEPdist);
- // Setup a particle directory if not already
- try
+ // Fill vtx to EP distance for kE < 1 MeV
+ if (kE < 0.001)
{
- tree().mkdir(particleName);
+ _mcpVtxToEPDistLTMeV.fill(vtxEPdist);
}
- catch (Exception e)
+ // Fill vtx to EP distance for kE > 1 MeV
+ else
{
+ _mcpVtxToEPDistGTMeV.fill(vtxEPdist);
}
- tree().cd(particleName);
+ }
- // Check that the particle information is valid before
- // proceeding with plots.
- if (particleName != null && !particleName.equals(""))
+ // Setup a particle directory
+ try
+ {
+ tree().mkdir(particleName);
+ }
+ catch (Exception e)
+ {
+ // There is already a directory for this particle.
+ }
+ tree().cd(particleName);
+
+ // Get the RefinedCheatClusters from the recon cheater
+ try
+ {
+ List<Cluster> clusters = getEventHeader().get(Cluster.class, "RefinedCheatClusters");
+
+ // Loop over the clusters
+ for (Cluster cluster : clusters)
{
- // Get the RefinedCheatClusters from the recon cheater
- List<Cluster> clusters = getEventHeader().get(Cluster.class, "RefinedCheatClusters");
+ CheatCluster cheat = (CheatCluster) cluster;
- // Loop over the clusters
- for (Cluster cluster : clusters)
+ if (cheat.getMCParticle() == particle)
{
- CheatCluster cheat = (CheatCluster) cluster;
+ // CheatCluster energy
+ double clusterE = cheat.getEnergy();
- if (cheat.getMCParticle() == particle)
- {
- // CheatCluster energy
- double clusterE = cheat.getEnergy();
+ // Add to measured energy of this particle type
+ info.addEventMeasuredEnergy(clusterE);
- // Add to measured energy of this particle type
- info.addEventMeasuredEnergy(clusterE);
+ // CheatCluster energy minus MCParticle Energy
+ double deltaE = clusterE - energy;
- // CheatCluster energy minus MCParticle Energy
- double deltaE = clusterE - energy;
+ // Delta over sqrt(E)
+ double delta1 = deltaE / (sqrt(energy));
- // Delta over sqrt(E)
- double delta1 = deltaE / (sqrt(energy));
+ // Delta over E
+ double delta2 = deltaE / energy;
- // Delta over E
- double delta2 = deltaE / energy;
+ // Plot dE / sqrt(E_generated)
+ aida().cloud1D(particleName + ": dE over sqrt(E_generated) for each particle").fill(delta1);
- // Plot dE / sqrt(E_generated)
- aida().cloud1D(particleName + ": dE over sqrt(E_generated) for each particle").fill(delta1);
+ // Plot dE / E_generated
+ aida().cloud1D(particleName + ": dE over E_generated for each particle").fill(delta2);
- // Plot dE / E_generated
- aida().cloud1D(particleName + ": dE over E_generated for each particle").fill(delta2);
+ // Plot particle KE vs CheatCluster E
+ aida().cloud2D(particleName + ": Particle Kinetic Energy vs CheatCluster Energy").fill(kE,
+ clusterE);
- // Plot particle KE vs CheatCluster E
- aida().cloud2D(particleName + ": Particle Kinetic Energy vs CheatCluster Energy").fill(kE,
- clusterE);
-
- // Break, because only a single CheatCluster should
- // exist for each MCParticle.
- break;
- }
+ // Break, because only a single CheatCluster should
+ // exist for each MCParticle.
+ break;
}
+ }
+ }
+ catch (Exception e)
+ {}
+
+ // Plot particle energy
+ aida().cloud1D(particleName + ": Energy").fill(particle.getEnergy());
+
+ // Plot particle time
+ aida().cloud1D(particleName + ": Production Time").fill(time);
+
+ // Plot momentum -> x2 + y2 + z2
+ aida().cloud1D(particleName + ": Momentum").fill(MCParticleUtil.PMagnitude(particle));
- // Plot particle energy
- aida().cloud1D(particleName + ": Energy").fill(particle.getEnergy());
+ // Plot transverse momentum -> x2 + y2
+ aida().cloud1D(particleName + ": Transverse Momentum").fill(log10(MCParticleUtil.PTransverse(particle)));
- // Plot particle time
- aida().cloud1D(particleName + ": Production Time").fill(time);
+ // Plot P cos theta
+ aida().cloud1D(particleName + ": Momentum cos(Theta)").fill(cosTheta);
- // Plot momentum -> x2 + y2 + z2
- aida().cloud1D(particleName + ": Momentum").fill(MCParticleUtil.PMagnitude(particle));
+ // Plot P phi
+ aida().cloud1D(particleName + ": Momentum phi").fill(phi);
- // Plot transverse momentum -> x2 + y2
- aida().cloud1D(particleName + ": Transverse Momentum").fill(
- log10(MCParticleUtil.PTransverse(particle)));
-
- // Plot P cos theta
- aida().cloud1D(particleName + ": Momentum cos(Theta)").fill(cosTheta);
-
- // Plot P phi
- aida().cloud1D(particleName + ": Momentum phi").fill(phi);
-
- // Plot particle momentum -> theta, phi
- aida().cloud2D(particleName + ": Momentum Theta vs. Phi").fill(
- VecUtil.getTheta(particle.getMomentum().v()), VecUtil.getPhi(particle.getMomentum().v()));
-
- // Plot PX, PY, PZ
- aida().cloud1D(particleName + ": PX").fill(PX);
- aida().cloud1D(particleName + ": PY").fill(PY);
- aida().cloud1D(particleName + ": PZ").fill(PZ);
-
- // Plot origin X, Y, Z
- aida().cloud1D(particleName + ": Origin X").fill(oX);
- aida().cloud1D(particleName + ": Origin Y").fill(oY);
- aida().cloud1D(particleName + ": Origin Z").fill(oZ);
- aida().cloud2D(particleName + ": Origin XY").fill(oX, oY);
- aida().cloud2D(particleName + ": Origin XZ").fill(oX, oZ);
+ // Plot particle momentum -> theta, phi
+ aida().cloud2D(particleName + ": Momentum Theta vs. Phi").fill(
+ VecUtil.getTheta(particle.getMomentum().v()), VecUtil.getPhi(particle.getMomentum().v()));
- // Plot kE
- aida().cloud1D(particleName + ": kE").fill(kE);
+ // Plot PX, PY, PZ
+ aida().cloud1D(particleName + ": PX").fill(PX);
+ aida().cloud1D(particleName + ": PY").fill(PY);
+ aida().cloud1D(particleName + ": PZ").fill(PZ);
- // FS end point
- if (hasEndpoint)
+ // Plot origin X, Y, Z
+ aida().cloud1D(particleName + ": Origin X").fill(oX);
+ aida().cloud1D(particleName + ": Origin Y").fill(oY);
+ aida().cloud1D(particleName + ": Origin Z").fill(oZ);
+ aida().cloud2D(particleName + ": Origin XY").fill(oX, oY);
+ aida().cloud2D(particleName + ": Origin XZ").fill(oX, oZ);
+
+ // Plot kE
+ aida().cloud1D(particleName + ": kE").fill(kE);
+
+ // FS end point
+ if (hasEndpoint)
+ {
+ // Plot End Point
+ aida().cloud1D(particleName + ": End Point X").fill(eX);
+ aida().cloud1D(particleName + ": End Point Y").fill(eY);
+ aida().cloud1D(particleName + ": End Point Z").fill(eZ);
+ aida().cloud2D(particleName + ": End Point XY").fill(eX, eY);
+ aida().cloud2D(particleName + ": End Point XZ").fill(eX, eZ);
+
+ // Plot vtx to endpoint distance
+ aida().cloud1D(particleName + ": Vertex to Endpoint Distance").fill(vtxEPdist);
+
+ // Plot endpoint RZ
+ aida().cloud2D(particleName + ": Endpoint R vs Z").fill(
+ VecUtil.getCylindricalRadius(particle.getEndPoint().v()), particle.getEndPoint().z());
+
+ // Plot E vs E in EP daughters
+ double dauE = 0.;
+ for (MCParticle dau : particle.getDaughters())
+ {
+ if (!dau.getSimulatorStatus().vertexIsNotEndpointOfParent()
+ && !dau.getSimulatorStatus().isBackscatter())
{
- // Plot End Point
- aida().cloud1D(particleName + ": End Point X").fill(eX);
- aida().cloud1D(particleName + ": End Point Y").fill(eY);
- aida().cloud1D(particleName + ": End Point Z").fill(eZ);
- aida().cloud2D(particleName + ": End Point XY").fill(eX, eY);
- aida().cloud2D(particleName + ": End Point XZ").fill(eX, eZ);
-
- // Plot vtx to endpoint distance
- aida().cloud1D(particleName + ": Vertex to Endpoint Distance").fill(vtxEPdist);
-
- // Plot endpoint RZ
- aida().cloud2D(particleName + ": Endpoint R vs Z").fill(
- VecUtil.getCylindricalRadius(particle.getEndPoint().v()), particle.getEndPoint().z());
-
- // Plot E vs E in EP daughters
- double dauE = 0.;
- for (MCParticle dau : particle.getDaughters())
- {
- if (!dau.getSimulatorStatus().vertexIsNotEndpointOfParent()
- && !dau.getSimulatorStatus().isBackscatter())
- {
- dauE += dau.getEnergy();
- }
- }
- if (dauE > 0)
- {
- //System.out.println(energy + " " + dauE);
- // Plot FS E vs EP Dau E
- aida().cloud2D(particleName + ": Final State Energy vs Total Energy of Endpoint Daughters").fill(
- energy, dauE);
- }
+ dauE += dau.getEnergy();
}
}
-
- // Go back to main dir
- tree().cd("..");
+ if (dauE > 0)
+ {
+ // Fill FS E vs EP Dau E
+ aida().cloud2D(particleName + ": Particle Energy vs Energy of Endpoint Daughters").fill(energy,
+ dauE);
+ }
}
+
+ // Go back to main dir
+ tree().cd("..");
}
// Do event summary plots of the particle types
@@ -468,18 +446,18 @@
double partTotE = info.getEventEnergy();
aida().cloud1D(k + ": Energy by Event").fill(partTotE);
- // Plot fraction of tot gen Final State Energy
- double percFSE = partTotE / genFSE;
- if (percFSE != 0)
+ // Plot fraction of Energy
+ double percE = partTotE / totEventE;
+ if (percE != 0)
{
- aida().cloud1D(k + ": Fraction of Total Final State Energy in Event").fill(percFSE);
+ aida().cloud1D(k + ": Fraction of Total Energy in Event").fill(percE);
}
// Plot fraction of FS particles
- double percFSParticles = ((double) nhits) / ((double) genFSCount);
- if (percFSParticles != 0)
+ double percParticles = ((double) nhits) / ((double) nparticles);
+ if (percParticles != 0)
{
- aida().cloud1D(k + ": Fraction of Final State Particle Count in Event").fill(percFSParticles);
+ aida().cloud1D(k + ": Fraction of Particle Count in Event").fill(percParticles);
}
// Plot status codes
@@ -489,7 +467,7 @@
}
// Plot E(measured) vs. E(genenerated)
- double deltaE = info.getEventEnergy() - info.getEventMeasuredEnergy();
+ double deltaE = info.getEventMeasuredEnergy() - info.getEventEnergy();
double delta1 = deltaE / sqrt(info.getEventEnergy());
double delta2 = deltaE / info.getEventEnergy();
@@ -505,23 +483,20 @@
// Go back to main dir
tree().cd("..");
}
+
+ // Fill total E
+ _totE.fill(totEventE);
- // Plot sim FS E
- _simFSE.fill(simFSE);
-
- // Plot gen FS E
- _genFSE.fill(genFSE);
-
- // Plot count per event of all MCPs
+ // Fill count
_count.fill(nparticles);
- // Plot charge counts
+ // Fill charge counts
_mcpNeutralCount.fill(nNeutral);
_mcpPositiveCount.fill(nPositive);
_mcpNegativeCount.fill(nNegative);
_mcpChargedCount.fill(nPositive + nNegative);
- // Plot event-level flag stats
+ // Fill event-level flag stats
for (MCParticleFlag flag : flagStats.flags())
{
aida().cloud1D("Status: " + flag.toString()).fill(flagStats.getFlagCount(flag));
@@ -551,7 +526,7 @@
p1 = aida().cloud1D(particleName + ": Production Time");
p1.annotation().addItem("xAxisLabel", "Time (seconds)");
p1.annotation().addItem("yAxisLabel", "Number of Particles");
-
+
p1 = aida().cloud1D(particleName + ": dE over sqrt(E_generated) for each particle");
p1.annotation().addItem("xAxisLabel", "dE / sqrt(E_gen) (GeV)");
p1.annotation().addItem("yAxisLabel", "Number of Particles");
@@ -617,7 +592,7 @@
p1.annotation().addItem("yAxisLabel", "Number of Particles");
p1 = aida().cloud1D(particleName + ": Vertex to Endpoint Distance");
- p1.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (log10(mm))");
+ p1.annotation().addItem("xAxisLabel", "Vertex to End Point Distance (mm)");
p1.annotation().addItem("yAxisLabel", "Number of Particles");
p1 = aida().cloud1D(particleName + ": Particle Count by Event");
@@ -628,13 +603,12 @@
p1.annotation().addItem("xAxisLabel", "Energy (GeV)");
p1.annotation().addItem("yAxisLabel", "Number of Events");
- p1 = aida().cloud1D(particleName + ": Fraction of Total Final State Energy in Event");
- p1.annotation().addItem("xAxisLabel", "Energy over Total Final State Energy (GeV)");
+ p1 = aida().cloud1D(particleName + ": Fraction of Total Energy in Event");
+ p1.annotation().addItem("xAxisLabel", "Energy over Total Energy (GeV)");
p1.annotation().addItem("yAxisLabel", "Number of Events");
- p1 = aida().cloud1D(particleName + ": Fraction of Final State Particle Count in Event");
- p1.annotation().addItem("xAxisLabel",
- "Number of this Particle Type Over Total Number of Final State Particles");
+ p1 = aida().cloud1D(particleName + ": Fraction of Particle Count in Event");
+ p1.annotation().addItem("xAxisLabel", "Number of this Particle Type Over Total Number of Particles");
p1.annotation().addItem("yAxisLabel", "Number of Events");
p1 = aida().cloud1D(particleName + ": dE over sqrt(E_generated) for Event");
@@ -673,8 +647,8 @@
p2.annotation().addItem("xAxisLabel", "End Point R (mm)");
p2.annotation().addItem("yAxisLabel", "End Point Z (mm)");
- p2 = aida().cloud2D(particleName + ": Final State Energy vs Total Energy of Endpoint Daughters");
- p2.annotation().addItem("xAxisLabel", "Final State Energy Total (GeV)");
+ p2 = aida().cloud2D(particleName + ": : Particle Energy vs Energy of Endpoint Daughters");
+ p2.annotation().addItem("xAxisLabel", "Particle Energy (GeV)");
p2.annotation().addItem("yAxisLabel", "Total Energy of End Point Daughters (GeV)");
for (MCParticleFlag flag : flagStats.flags())