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() {