Print

Print


Author: [log in to unmask]
Date: Tue Jan  6 12:01:38 2015
New Revision: 1884

Log:
Energy sort cluster hit collections so seed hit always appears as first in list.

Modified:
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleReconClusterer.java
    java/trunk/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterUtilities.java	Tue Jan  6 12:01:38 2015
@@ -198,4 +198,86 @@
         }
         return rejectedHits;
     }   
+     
+    /**
+     * Sort in place the CalorimeterHit list of a set of clusters, 
+     * disambiguating when the energies are exactly the same.
+     * @param clusters The list of clusters with hits to sort.
+     */
+    public static void sortReconClusterHits(List<Cluster> clusters) {
+        Comparator<CalorimeterHit> comparator = Collections.reverseOrder(new UniqueEnergyComparator());
+        for (Cluster cluster : clusters) {
+            Collections.sort(cluster.getCalorimeterHits(), comparator);
+        }
+    }
+    
+    static class UniqueEnergyComparator implements Comparator<CalorimeterHit> {
+        /**
+         * Compares the first hit with respect to the second. This method will compare hits first by
+         * energy, and then spatially. In the case of equal energy hits, the hit closest to the beam
+         * gap and closest to the positron side of the detector will be selected. If all of these
+         * conditions are true, the hit with the positive y-index will be selected. Hits with all
+         * four conditions matching are the same hit.
+         * @param hit1 The hit to compare.
+         * @param hit2 The hit with respect to which the first should be compared.
+         */
+        public int compare(CalorimeterHit hit1, CalorimeterHit hit2) {
+            // Hits are sorted on a hierarchy by three conditions. First,
+            // the hits with the highest energy come first. Next, they
+            // are ranked by vertical proximity to the beam gap, and
+            // lastly, they are sorted by horizontal proximity to the
+            // positron side of the detector.
+
+            // Get the hit energies.
+            double[] e = { hit1.getCorrectedEnergy(), hit2.getCorrectedEnergy() };
+
+            // Perform the energy comparison. The higher energy hit
+            // will be ordered first.
+            if (e[0] < e[1]) {
+                return -1;
+            } else if (e[0] > e[1]) {
+                return 1;
+            }
+
+            // If the hits are the same energy, we must perform the
+            // spatial comparisons.
+            else {
+                // Get the position with respect to the beam gap.
+                int[] iy = { Math.abs(hit1.getIdentifierFieldValue("iy")), Math.abs(hit2.getIdentifierFieldValue("iy")) };
+
+                // The closest hit is first.
+                if (iy[0] > iy[1]) {
+                    return -1;
+                } else if (iy[0] < iy[1]) {
+                    return 1;
+                }
+
+                // Hits that are identical in vertical distance from
+                // beam gap and energy are differentiated with distance
+                // horizontally from the positron side of the detector.
+                else {
+                    // Get the position from the positron side.
+                    int[] ix = { hit1.getIdentifierFieldValue("ix"), hit2.getIdentifierFieldValue("ix") };
+
+                    // The closest hit is first.
+                    if (ix[0] > ix[1]) {
+                        return 1;
+                    } else if (ix[0] < ix[1]) {
+                        return -1;
+                    }
+
+                    // If all of these checks are the same, compare
+                    // the raw value for iy. If these are identical,
+                    // then the two hits are the same. Otherwise, sort
+                    // the numerical value of iy. (This removes the
+                    // issue where hits (x, y) and (x, -y) can have
+                    // the same energy and be otherwise seen as the
+                    // same hit from the above checks.
+                    else {
+                        return Integer.compare(hit1.getIdentifierFieldValue("iy"), hit2.getIdentifierFieldValue("iy"));
+                    }
+                }
+            }
+        }
+    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleReconClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleReconClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleReconClusterer.java	Tue Jan  6 12:01:38 2015
@@ -123,6 +123,8 @@
             cluster.addHit(hit);
         }
 
+        ClusterUtilities.sortReconClusterHits(clusters);
+        
         return clusters;
     }
 }

Modified: java/trunk/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java
 =============================================================================
--- java/trunk/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java	(original)
+++ java/trunk/ecal-recon/src/test/java/org/hps/recon/ecal/cluster/ClustererTest.java	Tue Jan  6 12:01:38 2015
@@ -34,7 +34,7 @@
     static final String fileLocation = "http://www.lcsim.org/test/hps-java/MockDataReconTest.slcio";
     File inputFile;
     File testOutputDir;
-    static int nEvents = 500; 
+    static int nEvents = -1; 
     
     public void setUp() {
         // Cache the input file.
@@ -55,7 +55,8 @@
     
     public void testReconClusterer() {
         //runClustererTest("ReconClusterer", new double[] { 0.0075, 0.1, 0.3, 0.0, 20.0, 0. }, true);
-        runClustererTest("ReconClusterer");
+        //runClustererTest("ReconClusterer");
+        runClustererTest("ReconClusterer", null, true, true);
     }
     
     public void testSimpleReconClusterer() {