lcsim/src/org/lcsim/recon/cluster/cheat
diff -N PerfectClusterer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ PerfectClusterer.java 22 Jun 2006 01:18:55 -0000 1.1
@@ -0,0 +1,162 @@
+package org.lcsim.recon.cluster.cheat;
+
+import java.util.*;
+
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.Driver;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.SimCalorimeterHit;
+import org.lcsim.recon.cluster.util.BasicCluster;
+
+/**
+ * A clusterer with perfect pattern recognition
+ *
+ * @version $Id: PerfectClusterer.java,v 1.1 2006/06/22 01:18:55 mcharles Exp $
+ */
+
+public class PerfectClusterer extends Driver
+{
+ /**
+ * Trivial constructor
+ */
+ public PerfectClusterer() {
+ }
+
+ /**
+ * Process one event, separating the input hits into
+ * clusters as perfectly as possible based on the
+ * MC truth list.
+ */
+ public void process(EventHeader event)
+ {
+ List<MCParticle> mcList = event.get(MCParticle.class, m_mcName);
+ Map<Long, CalorimeterHit> inputHitMap = (Map<Long, CalorimeterHit>) (event.get(m_inputHitMapName));
+
+ Map<Long, CalorimeterHit> outputHitMap = new HashMap<Long, CalorimeterHit>(inputHitMap); // initially cloned
+ Collection<CalorimeterHit> hits = inputHitMap.values(); // initially full
+ Map<MCParticle, BasicCluster> particleToClusterMap = new HashMap<MCParticle, BasicCluster>(); // initially empty
+
+ for (CalorimeterHit hit : hits) {
+ // Find the particles that contributed to the hit.
+ // There can be more than one if:
+ // (1) More than one particle deposits energy in the cell
+ // (2) The list of MC particles is ambiguous
+ Set<MCParticle> truthParticles = findMCParticles(hit, mcList);
+ for (MCParticle part : truthParticles) {
+ BasicCluster clus = particleToClusterMap.get(part);
+ if (clus == null) {
+ // Haven't yet made a cluster for this particle -- make one now
+ clus = new BasicCluster();
+ particleToClusterMap.put(part, clus);
+ }
+ clus.addHit(hit);
+ }
+ }
+
+ // Finished assembling the clusters. Do book-keeping:
+ // (1) Build the output list of clusters
+ // (2) Build the output hitmap
+ Collection<BasicCluster> clusters = particleToClusterMap.values();
+ List<Cluster> outputClusterList = new Vector<Cluster>();
+ for (BasicCluster clus : clusters) {
+ outputClusterList.add(clus);
+ for (CalorimeterHit hit : clus.getCalorimeterHits()) {
+ outputHitMap.remove(hit.getCellID());
+ }
+ }
+
+ // Write out:
+ event.put(m_outputClusterListName, outputClusterList);
+ event.put(m_outputHitMapName, outputHitMap);
+ }
+
+ /**
+ * Internal utility routine
+ */
+ protected double findContributionByMCParticle(CalorimeterHit hit, List<MCParticle> mcList, MCParticle part)
+ {
+ if ( ! (hit instanceof SimCalorimeterHit) ) {
+ throw new AssertionError("Non-simulated hit!");
+ } else {
+ SimCalorimeterHit simHit = (SimCalorimeterHit) (hit);
+ int nContributingParticles = simHit.getMCParticleCount();
+ double energy = 0.0;
+ for (int i=0; i<nContributingParticles; i++) {
+ MCParticle contributingPart = simHit.getMCParticle(i);
+ List<MCParticle> parentsInList = findParentsInList(contributingPart, mcList);
+ if (parentsInList.contains(part)) {
+ energy += simHit.getContributedEnergy(i);
+ }
+ }
+ return energy;
+ }
+ }
+
+ /**
+ * Internal utility routine
+ */
+ protected Set<MCParticle> findMCParticles(CalorimeterHit hit, List<MCParticle> mcList)
+ {
+ if ( ! (hit instanceof SimCalorimeterHit) ) {
+ throw new AssertionError("Non-simulated hit!");
+ } else {
+ SimCalorimeterHit simHit = (SimCalorimeterHit) (hit);
+ Set<MCParticle> contributingParticlesFromList = new HashSet<MCParticle>();
+ int nContributingParticles = simHit.getMCParticleCount();
+ for (int i=0; i<nContributingParticles; i++) {
+ MCParticle part = simHit.getMCParticle(i);
+ List<MCParticle> parentsInList = findParentsInList(part, mcList);
+ contributingParticlesFromList.addAll(parentsInList);
+ }
+ return contributingParticlesFromList;
+ }
+ }
+
+ /**
+ * Internal utility routine
+ */
+ protected List<MCParticle> findParentsInList(MCParticle part, List<MCParticle> mcList)
+ {
+ List<MCParticle> outputList = new Vector<MCParticle>();
+ if (mcList.contains(part)) {
+ // Already in there
+ outputList.add(part);
+ } else {
+ // Not in there -- recurse up through parents
+ List<MCParticle> parents = part.getParents();
+ if (parents.size()==0) {
+ // Ran out of options -- add nothing and return below
+ } else {
+ for (MCParticle parent : parents) {
+ List<MCParticle> ancestorsInList = findParentsInList(parent, mcList);
+ outputList.addAll(ancestorsInList);
+ }
+ }
+ }
+ return outputList;
+ }
+
+ /** Specify the hits to cluster. */
+ public void setInputHitMap(String name) {
+ m_inputHitMapName = name;
+ }
+ /** Any unused hits will be written out to a HitMap under this name. */
+ public void setOutputHitMap(String name) {
+ m_outputHitMapName = name;
+ }
+ /** Clustered hits will be written to a list under this name. */
+ public void setOutputClusterList(String name) {
+ m_outputClusterListName = name;
+ }
+ /** Specify the MC truth list to use */
+ public void setMCParticleList(String name) {
+ m_mcName = name;
+ }
+
+ String m_inputHitMapName;
+ String m_outputHitMapName;
+ String m_outputClusterListName;
+ String m_mcName;
+}