Commit in hps-java/src/main/java/org/lcsim/hps/recon/ecal on MAIN
HPSEcal1BitClusterer.java+302added 1.1
Added 1-bit clusterer

hps-java/src/main/java/org/lcsim/hps/recon/ecal
HPSEcal1BitClusterer.java added at 1.1
diff -N HPSEcal1BitClusterer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSEcal1BitClusterer.java	18 Aug 2011 22:20:24 -0000	1.1
@@ -0,0 +1,302 @@
+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 java.util.Iterator;
+
+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.HPSEcal;
+import org.lcsim.geometry.subdetector.HPSEcal.NeighborMap;
+import org.lcsim.geometry.subdetector.HPSEcal2;
+import org.lcsim.recon.cluster.util.BasicCluster;
+import org.lcsim.util.Driver;
+import org.lcsim.util.lcio.LCIOConstants;
+
+/**
+ * Creates clusters from CalorimeterHits in the HPSEcal detector.
+ * 
+ * The clustering algorithm is from JLab Hall B 6 GeV DVCS Trigger Design doc.
+ * 
+ * @author Jeremy McCormick <[log in to unmask]>
+ * @author Tim Nelson <[log in to unmask]>
+ * @author Sho Uemura <[log in to unmask]>
+ */
+public class HPSEcal1BitClusterer extends Driver {
+
+    HPSEcal ecal;
+    String ecalCollectionName;
+    String ecalName;
+    String clusterCollectionName = "EcalClusters";
+    // Threshold E for discriminator.
+    double hitEMin = .05;
+    // Threshold hit count for cluster. Cluster must have more than this many hits.
+    int clusterThreshold = 5;
+    // Odd or even number of crystals in X.
+    boolean oddX;
+    // Map of crystals to their neighbors.
+    NeighborMap neighborMap = null;
+
+    public HPSEcal1BitClusterer() {
+    }
+
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+
+    public void setHitEMin(double hitEMin) {
+        this.hitEMin = hitEMin;
+    }
+
+    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 = (HPSEcal2) detector.getSubdetector(ecalName);
+
+        // Cache ref to neighbor map.
+        neighborMap = ecal.getNeighborMap();
+
+        //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 hits collection!");
+        }
+
+        // Get the decoder for the ECal IDs.
+        IDDecoder dec = ecal.getIDDecoder();
+
+        // Hit map.
+        Map<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
+
+        Map<Long, Integer> hitCounts = new HashMap<Long, Integer>();
+
+        // 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 count hit towers
+        for (CalorimeterHit hit : hits) {
+            // Cut on min seed E.
+            if (hit.getRawEnergy() < hitEMin) {
+                continue;
+            }
+
+            // Get neighbor crystal IDs.
+            Set<Long> neighbors = neighborMap.get(hit.getCellID());
+
+            if (neighbors == null) {
+                throw new RuntimeException("Oops!  Set of neighbors is null!");
+            }
+
+            Integer hitCount = hitCounts.get(hit.getCellID());
+            if (hitCount == null)
+                hitCounts.put(hit.getCellID(), 1);
+            else
+                hitCount++;
+
+            // Loop over neighbors to make hit list for cluster.
+            for (Long neighborId : neighbors) {
+                hitCount = hitCounts.get(neighborId);
+                if (hitCount == null)
+                    hitCounts.put(hit.getCellID(), 1);
+                else
+                    hitCount++;
+            }
+        }
+
+        //for each crystal with a nonzero hit count, test for cluster
+        Iterator<Long> possibleClusters = hitCounts.keySet().iterator();
+        while (possibleClusters.hasNext()) {
+            Long possibleCluster = possibleClusters.next();
+            if (hitCounts.get(possibleCluster) <= clusterThreshold) {
+                continue;
+            }
+
+            // Get neighbor crystal IDs.
+            Set<Long> neighbors = neighborMap.get(possibleCluster);
+
+            if (neighbors == null) {
+                throw new RuntimeException("Oops!  Set of neighbors is null!");
+            }
+
+            //Apply peak detector scheme.
+            // Set the ID.
+            dec.setID(possibleCluster);
+            // Get ID field values.
+            int x1 = dec.getValue("ix");
+            int y1 = dec.getValue("iy");
+            int side1 = dec.getValue("side");
+            Integer hitCount = hitCounts.get(possibleCluster);
+
+            for (Long neighborId : neighbors) {
+                // Set the ID.
+                dec.setID(neighborId);
+                // Get ID field values.
+                int x2 = dec.getValue("ix");
+                int y2 = dec.getValue("iy");
+                if (side1 == 1) {
+                    if (x1 > 0) {
+                        //quadrant 1
+                        if (x1 == 1) {
+                            //special case: left edge of quadrant
+                            if (x1 > x2 && y1 < y2) {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            } else if (x1 > x2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else if (x1 < x2) {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            } else if (y1 < y2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            }
+                        } else {
+                            if (x1 > x2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else if (x1 < x2) {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            } else if (y1 < y2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            }
+                        }
+                    } else {
+                        //quadrant 2
+                        if (y1 > y2) {
+                            if (hitCounts.get(neighborId) > hitCount)
+                                continue;
+                        } else if (y1 < y2) {
+                            if (hitCounts.get(neighborId) >= hitCount)
+                                continue;
+                        } else if (x1 > x2) {
+                            if (hitCounts.get(neighborId) > hitCount)
+                                continue;
+                        } else {
+                            if (hitCounts.get(neighborId) >= hitCount)
+                                continue;
+                        }
+                    }
+                } else {
+                    if (x1 < 0) {
+                        //quadrant 3
+                        if (x1 == 1) {
+                            //special case: left edge of quadrant
+                            if (x1 < x2 && y1 > y2) {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            } else if (x1 < x2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else if (x1 > x2) {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            } else if (y1 > y2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            }
+                        } else {
+                            if (x1 < x2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else if (x1 > x2) {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            } else if (y1 > y2) {
+                                if (hitCounts.get(neighborId) > hitCount)
+                                    continue;
+                            } else {
+                                if (hitCounts.get(neighborId) >= hitCount)
+                                    continue;
+                            }
+                        }
+                    } else {
+                        //quadrant 4
+                        if (y1 < y2) {
+                            if (hitCounts.get(neighborId) > hitCount)
+                                continue;
+                        } else if (y1 > y2) {
+                            if (hitCounts.get(neighborId) >= hitCount)
+                                continue;
+                        } else if (x1 < x2) {
+                            if (hitCounts.get(neighborId) > hitCount)
+                                continue;
+                        } else {
+                            if (hitCounts.get(neighborId) >= hitCount)
+                                continue;
+                        }
+                    }
+                }
+            }
+
+            BasicCluster cluster = new BasicCluster();
+            cluster.addHit(hitMap.get(possibleCluster));
+            for (Long neighborId : neighbors) {
+                // Find the neighbor hit in the event if it exists.
+                CalorimeterHit neighborHit = hitMap.get(neighborId);
+
+                // Was this neighbor cell hit?
+                if (neighborHit != null) {
+                    cluster.addHit(neighborHit);
+                }
+            }
+            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
CVSspam 0.2.8