hps-java/src/main/java/org/lcsim/hps/recon/ecal
diff -N HPSEcal3Clusterer.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ HPSEcal3Clusterer.java 3 Sep 2011 00:32:53 -0000 1.3
@@ -0,0 +1,216 @@
+package org.lcsim.hps.recon.ecal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.lcsim.event.CalorimeterHit;
+import org.lcsim.event.Cluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.geometry.Detector;
+import org.lcsim.geometry.IDDecoder;
+import org.lcsim.geometry.subdetector.HPSEcal3.NeighborMap;
+import org.lcsim.geometry.subdetector.HPSEcal3;
+import org.lcsim.recon.cluster.util.BasicCluster;
+import org.lcsim.util.Driver;
+import org.lcsim.util.lcio.LCIOConstants;
+
+/**
+ * This Driver creates clusters from the CalorimeterHits of an
+ * {@link org.lcsim.geometry.subdetectur.HPSEcal3} detector.
+ *
+ * This is based on {@link HPSEcalClusterer}. It removes the concept
+ * of side and uses signed Y indices.
+ *
+ * The clustering algorithm is from pages 83 and 84 of the HPS Proposal.
+ *
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @author Tim Nelson <[log in to unmask]>
+ *
+ * @version $Id: HPSEcal3Clusterer.java,v 1.3 2011/09/03 00:32:53 jeremy Exp $
+ */
+public class HPSEcal3Clusterer extends Driver
+{
+ // Reference to the HPSEcal3 subdetector.
+ HPSEcal3 ecal;
+
+ // Name of collection containing Ecal hits.
+ String ecalCollectionName;
+
+ // Name of Ecal detector.
+ String ecalName;
+
+ // Name of Ecal cluster output collection.
+ String clusterCollectionName = "EcalClusters";
+
+ // Execute debug code?
+ boolean debug = false;
+
+ // Minimum energy [GeV] for cluster seed.
+ double seedEMin = .05;
+
+ // Minimum energy [GeV] to add hit to cluster.
+ double addEMin = .03;
+
+ // Map of crystals to their neighbors.
+ NeighborMap neighborMap = null;
+
+ public HPSEcal3Clusterer()
+ {}
+
+ public void setDebug(boolean debug)
+ {
+ this.debug = debug;
+ }
+
+ public void setClusterCollectionName(String clusterCollectionName)
+ {
+ this.clusterCollectionName = clusterCollectionName;
+ }
+
+ public void setSeedEMin(double seedEMin)
+ {
+ this.seedEMin = seedEMin;
+ }
+
+ public void setAddEMin(double addEMin)
+ {
+ this.addEMin = addEMin;
+ }
+
+ public void setEcalCollectionName(String ecalCollectionName)
+ {
+ this.ecalCollectionName = ecalCollectionName;
+ }
+
+ public void setEcalName(String ecalName)
+ {
+ this.ecalName = ecalName;
+ }
+
+ public void startOfData()
+ {
+ if (ecalCollectionName == null)
+ throw new RuntimeException("The parameter ecalCollectionName was not set!");
+
+ if (ecalName == null)
+ throw new RuntimeException("The parameter ecalName was not set!");
+ }
+
+ public void detectorChanged(Detector detector)
+ {
+ // Get the Subdetector.
+ ecal = (HPSEcal3)detector.getSubdetector(ecalName);
+
+ // Cache the ref to neighbor map.
+ neighborMap = ecal.getNeighborMap();
+
+ // Print out subdet params and neighbor map.
+ if (debug)
+ {
+ System.out.println(ecal.getName());
+ System.out.println(" nx="+ecal.nx());
+ System.out.println(" ny="+ecal.ny());
+ System.out.println(" beamgap="+ecal.beamGap());
+ System.out.println(" dface="+ecal.distanceToFace());
+
+ System.out.println(neighborMap.toString());
+ }
+ }
+
+ public void process(EventHeader event)
+ {
+ //System.out.println(this.getClass().getCanonicalName() + " - process");
+
+ // Get the list of ECal hits.
+ List<CalorimeterHit> hits = event.get(CalorimeterHit.class, ecalCollectionName);
+ if (hits == null)
+ throw new RuntimeException("Event is missing ECal raw hits collection!");
+
+ // Get the decoder for the ECal IDs.
+ IDDecoder dec = ecal.getIDDecoder();
+
+ // Hit map.
+ Map<Long,CalorimeterHit> hitMap = new HashMap<Long,CalorimeterHit>();
+
+ // Make a hit map for quick lookup by ID.
+ for (CalorimeterHit hit : hits)
+ {
+ hitMap.put(hit.getCellID(), hit);
+ }
+
+ // New Cluster list to be added to event.
+ List<Cluster> clusters = new ArrayList<Cluster>();
+
+ // Loop over ECal hits to find cluster seeds.
+ for (CalorimeterHit hit : hits)
+ {
+ // Cut on min seed E.
+ if (hit.getRawEnergy() < seedEMin)
+ continue;
+
+ // Get neighbor crystal IDs.
+ Set<Long> neighbors = neighborMap.get(hit.getCellID());
+
+ /*
+ if (debug)
+ {
+ dec.setID(hit.getCellID());
+ System.out.println(dec.getValue("system") + ", " + dec.getValue("ix") + ", " + dec.getValue("iy"));
+ if (neighbors == null)
+ {
+ throw new RuntimeException("Oops! Set of neighbors is null!");
+ }
+ }
+ */
+
+ // New list for neighboring hits.
+ List<CalorimeterHit> neighborHits = new ArrayList<CalorimeterHit>();
+
+ // Loop over this hit's neighbors to make a hit list for the cluster.
+ boolean isSeed = true;
+ for (Long neighborId : neighbors)
+ {
+ // Look for the neighbor hit.
+ CalorimeterHit neighborHit = hitMap.get(neighborId);
+
+ // Does this neighboring crystal have a hit in the event?
+ if (neighborHit != null)
+ {
+ // Check if the neighbor cell has more energy.
+ if (neighborHit.getRawEnergy() > hit.getRawEnergy())
+ {
+ // Neighbor has more energy, so this cell cannot be a seed.
+ isSeed = false;
+ break;
+ }
+
+ // Add to the cluster if hit is above the minimum energy.
+ if (neighborHit.getRawEnergy() >= addEMin)
+ {
+ neighborHits.add(neighborHit);
+ }
+ }
+ }
+
+ // Did we find a seed?
+ if (isSeed)
+ {
+ // Make a new cluster from the hit list.
+ BasicCluster cluster = new BasicCluster();
+ cluster.addHit(hit);
+ for (CalorimeterHit clusHit : neighborHits)
+ {
+ cluster.addHit(clusHit);
+ }
+ clusters.add(cluster);
+ }
+ }
+
+ // Put Cluster collection into event.
+ int flag = 1 << LCIOConstants.CLBIT_HITS;
+ event.put(clusterCollectionName, clusters, Cluster.class, flag);
+ }
+}
\ No newline at end of file