Commit in lcsim/src/org/lcsim/recon/cluster/cheat on MAIN
PerfectClusterer.java+162added 1.1
Another cheating clusterer, this time taking a specific input list

lcsim/src/org/lcsim/recon/cluster/cheat
PerfectClusterer.java added at 1.1
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;
+}
CVSspam 0.2.8