java/trunk/users/src/main/java/org/lcsim/hps/users/ngraf
--- java/trunk/users/src/main/java/org/lcsim/hps/users/ngraf/NearestNeighborCluster.java (rev 0)
+++ java/trunk/users/src/main/java/org/lcsim/hps/users/ngraf/NearestNeighborCluster.java 2014-01-29 23:52:37 UTC (rev 136)
@@ -0,0 +1,58 @@
+package org.lcsim.hps.users.ngraf;
+
+import java.util.Map;
+import java.util.Set;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.base.BaseCluster;
+import org.lcsim.geometry.subdetector.HPSEcal3;
+
+/**
+ * This is a cluster created using a nearest-neighbor clustering algorithm. It
+ * currently extends BaseCluster but should extend a base HPS Cluster at some
+ * time
+ *
+ * @author Norman A Graf
+ *
+ * @version $Id:
+ */
+public class NearestNeighborCluster extends BaseCluster
+{
+
+ /**
+ *
+ * @param map A Map of CalorimeterHit keyed on CellID, Hits added to this
+ * cluster are removed from the map
+ * @param hit A CalorimeterHit representing a hit crystal
+ * @param threshold The energy threshold below which a hit crystal should
+ * NOT be added to the cluster
+ * @param neighborMap The map of HPS crystal neighbors.
+ */
+ public NearestNeighborCluster(Map<Long, CalorimeterHit> map, CalorimeterHit hit, double threshold, HPSEcal3.NeighborMap neighborMap)
+ {
+ // start by adding this hit to the cluster
+ addHit(hit);
+ // remove this hit from the map so it can't be used again
+ map.remove(hit.getCellID());
+ // loop over the hits in the cluster and add all its neighbors
+ // note that hits.size() grows as we add cells, so we recursively find neighbors of neighbors
+ for (int i = 0; i < hits.size(); ++i) {
+ CalorimeterHit c = hits.get(i);
+ // Get neighbor crystal IDs.
+ Set<Long> neighbors = neighborMap.get(c.getCellID());
+ // loop over all neighboring cell Ids
+ for (Long neighborId : neighbors) {
+ // Find the neighbor hit in the event if it exists.
+ CalorimeterHit neighborHit = map.get(neighborId);
+ // Was this neighbor cell hit?
+ if (neighborHit != null) {
+ // if so, does it meet or exceed threshold?
+ if (neighborHit.getRawEnergy() >= threshold) {
+ addHit(neighborHit);
+ }
+ //remove this hit from the map so it can't be used again
+ map.remove(neighborHit.getCellID());
+ }
+ }
+ }
+ }
+}
java/trunk/users/src/main/java/org/lcsim/hps/users/ngraf
--- java/trunk/users/src/main/java/org/lcsim/hps/users/ngraf/NearestNeighborClusterDriver.java (rev 0)
+++ java/trunk/users/src/main/java/org/lcsim/hps/users/ngraf/NearestNeighborClusterDriver.java 2014-01-29 23:52:37 UTC (rev 136)
@@ -0,0 +1,116 @@
+package org.lcsim.hps.users.ngraf;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.MCParticle;
+import org.lcsim.event.SimCalorimeterHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.subdetector.HPSEcal3;
+import org.lcsim.hps.recon.ecal.ECalUtils;
+import org.lcsim.lcio.LCIOConstants;
+import org.lcsim.util.Driver;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * This is a test
+ * @author Norman A Graf
+ *
+ * @version $Id:
+ */
+public class NearestNeighborClusterDriver extends Driver
+{
+ // Histogram manager
+ private AIDA aida;
+ // Minimum E for cluster seed.
+ double seedEMin = .00 * ECalUtils.GeV;
+ // Minimum E to add hit to cluster.
+ double addEMin = .00 * ECalUtils.GeV;
+ // Map of crystals to their neighbors.
+ HPSEcal3.NeighborMap _neighborMap = null;
+
+ @Override
+ public void processChildren(EventHeader event)
+ {
+ boolean debug = true;
+ // This is example code to run over a simple lcio file output from slic
+ // on which no calorimeter digitzation has been done.
+ // Therefore need to convert from SimCalorimeterHit to CalorimeterHit
+ // This would normally be done as a part of the reconstruction
+ if (event.hasCollection(SimCalorimeterHit.class, "EcalHits")) {
+ // Get the list of sim ECal hits.
+ List<SimCalorimeterHit> hits = event.get(SimCalorimeterHit.class, "EcalHits");
+
+ // create a list of CalorimeterHits
+ // Make a hit map for quick lookup by ID.
+ Map<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
+ for (SimCalorimeterHit hit : hits) {
+ hitMap.put(hit.getCellID(), hit);
+ }
+
+ // Cluster the hits using a nearest neighbor algorithm
+ int flag = 1 << LCIOConstants.CLBIT_HITS;
+ List<NearestNeighborCluster> clusters = createNearestNeighborClusters(hitMap);
+ // quick analysis example
+ if(debug) System.out.println("found " + clusters.size() + " clusters");
+ double eTop = 0.;
+ double eBottom = 0.;
+ for (Cluster clus : clusters) {
+ if(debug)System.out.println("x: " + clus.getPosition()[0] + " y: " + clus.getPosition()[1] + " iPhi: " + clus.getIPhi() + " iTheta " + clus.getITheta());
+ if(clus.getPosition()[1]>0)
+ {
+ eTop+=clus.getEnergy();
+ }
+ else
+ {
+ eBottom += clus.getEnergy();
+ }
+ }
+ //fill the histograms
+ aida.cloud1D("Top energy sum").fill(eTop);
+ aida.cloud1D("Bottom energy sum").fill(eBottom);
+ aida.cloud1D("energy diff").fill(eTop-eBottom);
+ //add the list of clusters to the event
+ event.put("NearestNeighborClusters", clusters, NearestNeighborCluster.class, flag);
+ }
+ }
+
+ @Override
+ protected void detectorChanged(Detector detector)
+ {
+ // Get the Subdetector.
+ HPSEcal3 ecal = (HPSEcal3) detector.getSubdetector("Ecal");
+ // Cache the neighbor map for use by the nearest neighbor clustering algorithm
+ _neighborMap = ecal.getNeighborMap();
+ // set up some plotting infrastructure
+ aida = AIDA.defaultInstance();
+ aida.tree().cd("/");
+ }
+
+ /**
+ * Run the clustering algorithm over the list of hit crystals
+ * @param map Map of CalorimeterHit keyed on CellID. Note that this map is modified
+ * @return The list of found clusters
+ */
+ public List<NearestNeighborCluster> createNearestNeighborClusters(Map<Long, CalorimeterHit> map)
+ {
+ // New Cluster list to be added to event.
+ List<NearestNeighborCluster> clusters = new ArrayList<NearestNeighborCluster>();
+
+ while (!map.isEmpty()) {
+ Long k = map.keySet().iterator().next();
+ CalorimeterHit hit = map.get(k);
+ NearestNeighborCluster nnclus = new NearestNeighborCluster(map, hit, addEMin, _neighborMap);
+ //done with this cluster, let's compute some shape properties
+ if (nnclus.getSize() > 1) {
+ nnclus.calculateProperties();
+ clusters.add(nnclus);
+ }
+ }
+ return clusters;
+ }
+}
\ No newline at end of file
java/trunk/users/src/test/java/org/lcsim/hps/users/ngraf
--- java/trunk/users/src/test/java/org/lcsim/hps/users/ngraf/NearestNeighborClusterDriverTest.java (rev 0)
+++ java/trunk/users/src/test/java/org/lcsim/hps/users/ngraf/NearestNeighborClusterDriverTest.java 2014-01-29 23:52:37 UTC (rev 136)
@@ -0,0 +1,35 @@
+package org.lcsim.hps.users.ngraf;
+
+import java.io.File;
+import java.net.URL;
+import junit.framework.TestCase;
+import org.lcsim.util.cache.FileCache;
+import org.lcsim.util.loop.LCSimLoop;
+
+/**
+ *
+ * @author ngraf
+ */
+public class NearestNeighborClusterDriverTest extends TestCase
+{
+ static final String testURLBase = "http://www.slac.stanford.edu/~ngraf/hps_data/";
+ static final String testFileName = "outfile3.slcio";
+ private final int nEvents = 500;
+
+ public void testClustering() throws Exception {
+
+ File lcioInputFile = null;
+
+ URL testURL = new URL(testURLBase + "/" + testFileName);
+ FileCache cache = new FileCache();
+ lcioInputFile = cache.getCachedFile(testURL);
+
+ //Process and write out the file
+ LCSimLoop loop = new LCSimLoop();
+ loop.setLCIORecordSource(lcioInputFile);
+ loop.add(new NearestNeighborClusterDriver());
+ loop.loop(nEvents, null);
+ loop.dispose();
+
+ }
+}