Print

Print


Author: [log in to unmask]
Date: Thu Feb 19 17:54:39 2015
New Revision: 2172

Log:
Improvements to ClustererTest including reading back and checking the validity of the output LCIO file.

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

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	Thu Feb 19 17:54:39 2015
@@ -33,81 +33,93 @@
 import org.lcsim.util.test.TestUtil.TestOutputFile;
 
 /**
- * This test does basic sanity checks on the output from the {@link Clusterer} algorithms,
- * and it creates an AIDA file with some useful plots, as well as optionally writes
- * an LCIO file with the event data plus the clusters.
+ * This test performs basic sanity checks on the output from the various clustering algorithms, 
+ * and it creates an AIDA file with some useful plots, as well as optionally writes an LCIO 
+ * file with the event data plus the clusters.
  * 
  * @author Jeremy McCormick <[log in to unmask]>
+ * 
+ * @see Clusterer
+ * @see org.lcsim.event.Cluster
+ * @see org.lcsim.event.CalorimeterHit
  */
 public class ClustererTest extends TestCase {
-    
+
     static int nEvents = 100;
     static final String fileLocation = "http://www.lcsim.org/test/hps-java/MockDataReconTest.slcio";
     File inputFile;
     File testOutputDir;
-    
-    static class ClustererTestSetup {
-        
+
+    static class ClustererTestConfig {
+
         boolean writeLcioFile;
         boolean checkSeedHit;
-        boolean applyCorrections;        
         boolean checkHitEnergy;
         boolean checkPropCalc;
         boolean checkClusterPosition;
-        boolean checkHitPositions;
-        boolean calculateProperties;
-        boolean sortHits;
+        boolean checkNullHits;
+        boolean checkHitPositions;        
         double[] cuts = null;
-        ClusterType clusterType; 
+        ClusterType clusterType;
+        String clustererName;
+
+        ClustererTestConfig(String clustererName, double[] cuts) {
+            this.clustererName = clustererName;
+            this.cuts = cuts;
+        }
+
+        ClustererTestConfig(String clustererName) {
+            this.clustererName = clustererName;
+        }
+
+        ClustererTestConfig() {
+        }
+
+        ClustererTestConfig writeLcioFile() {
+            writeLcioFile = true;
+            return this;
+        }
+
+        ClustererTestConfig checkSeedHit() {
+            checkSeedHit = true;
+            return this;
+        }
+
+        ClustererTestConfig checkHitEnergy() {
+            checkHitEnergy = true;
+            return this;
+        }
+
+        ClustererTestConfig checkPropCalc() {
+            checkPropCalc = true;
+            return this;
+        }
+
+        ClustererTestConfig checkClusterType(ClusterType clusterType) {
+            this.clusterType = clusterType;
+            return this;
+        }
+
+        ClustererTestConfig checkClusterPosition() {
+            this.checkClusterPosition = true;
+            return this;
+        }
+
+        ClustererTestConfig checkHitPositions() {
+            this.checkHitPositions = true;
+            return this;
+        }
         
-        ClustererTestSetup(double[] cuts) {
-            this.cuts = cuts;            
-        }
-        
-        ClustererTestSetup() {            
-        }
-        
-        ClustererTestSetup writeLcioFile() {
-            writeLcioFile = true;
-            return this;
-        }
-        
-        ClustererTestSetup checkSeedHit() {
-            checkSeedHit = true;
-            return this;
-        }
-                
-        ClustererTestSetup sortHits() {
-            sortHits = true;
-            return this;
-        }
-        
-        ClustererTestSetup checkHitEnergy() {
-            checkHitEnergy = true;
-            return this;
-        }
-        
-        ClustererTestSetup checkPropCalc() {
-            checkPropCalc = true;
-            return this;
-        }
-        
-        ClustererTestSetup checkClusterType(ClusterType clusterType) {
-            this.clusterType = clusterType;
-            return this;
-        }
-        
-        ClustererTestSetup checkPosition() {
-            this.checkClusterPosition = true;
-            return this;
-        }
-        
-        ClustererTestSetup checkHitPositions() {
-            this.checkHitPositions = true;
-            return this;
-        }
-    }
-         
+        ClustererTestConfig checkNullHits() {
+            this.checkNullHits = true;
+            return this;
+        }
+
+        String getClusterCollectionName() {
+            return clustererName + "Clusters";
+        }
+    }
+
     public void setUp() {
         // Cache the input file.
         try {
@@ -115,172 +127,249 @@
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
-        
+
         // Create test output directory.
         testOutputDir = new TestOutputFile(getClass().getSimpleName());
-        testOutputDir.mkdir();        
-        
+        testOutputDir.mkdir();
+
         // Initialize the conditions system.
         new DatabaseConditionsManager();
         DatabaseConditionsManager.getInstance().setLogLevel(Level.WARNING);
     }
-    
+
     /**
      * Test the recon clustering algorithm, formerly called the IC clusterer.
      */
-    public void testReconClusterer() {        
-        runClustererTest("ReconClusterer", 
-                new ClustererTestSetup()
-                    .writeLcioFile()
-                    .checkSeedHit()
-                    .checkClusterType(ClusterType.RECON)
-                    .checkHitEnergy()
-                    .checkPosition()
-                    .checkHitPositions());
-    }
-    
+    public void testReconClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("ReconClusterer")
+            .writeLcioFile()
+            .checkSeedHit()
+            .checkClusterType(ClusterType.RECON)
+            .checkHitEnergy()
+            .checkClusterPosition()
+            .checkNullHits()
+            .checkHitPositions());
+    }
+
     /**
      * Test a simple version of the recon clustering.
      */
-    public void testSimpleReconClusterer() {
-        runClustererTest("SimpleReconClusterer", 
-                new ClustererTestSetup()
-                    .writeLcioFile()
-                    .checkSeedHit()
-                    .checkClusterType(ClusterType.SIMPLE_RECON)
-                    .checkHitEnergy()
-                    .checkPosition());
-    }
-    
+    public void testSimpleReconClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("SimpleReconClusterer")
+            .writeLcioFile()
+            .checkSeedHit()
+            .checkClusterType(ClusterType.SIMPLE_RECON)
+            .checkHitEnergy()
+            .checkClusterPosition()
+            .checkNullHits()
+            .checkHitPositions());
+    }
+
     /**
      * Test a simplistic NN clustering algorithm.
      */
-    public void testNearestNeighborClusterer() {    
-        runClustererTest("NearestNeighborClusterer", 
-                new ClustererTestSetup(new double[] { 0.0075, 3 })
-                    .writeLcioFile()
-                    .checkClusterType(ClusterType.NN)
-                    .checkHitEnergy()
-                    .checkPosition());
-    }
-    
+    public void testNearestNeighborClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("NearestNeighborClusterer", new double[] { 0.0075, 3 })
+            .writeLcioFile()
+            .checkClusterType(ClusterType.NN)
+            .checkHitEnergy()
+            .checkClusterPosition()
+            .checkHitPositions()
+            .checkNullHits());
+    }
+
     /**
      * Test the clustering algorithm from the Test Run proposal document.
      */
-    public void testLegacyClusterer() {
-        runClustererTest("LegacyClusterer", 
-                new ClustererTestSetup()
-                    .writeLcioFile()
-                    .checkClusterType(ClusterType.LEGACY)
-                    .checkHitEnergy()
-                    .checkPosition());
-    }
-    
+    public void testLegacyClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("LegacyClusterer")
+            .writeLcioFile()
+            .checkClusterType(ClusterType.LEGACY)
+            .checkHitEnergy()
+            .checkClusterPosition()
+            .checkHitPositions()
+            .checkNullHits());
+    }
+
     /**
      * Test the online version of the GTP algorithm.
      */
-    public void testGTPOnlineClusterer() {
-        runClustererTest("GTPOnlineClusterer", 
-                new ClustererTestSetup()
-                    .writeLcioFile().checkSeedHit()
-                    .checkClusterType(ClusterType.GTP_ONLINE)
-                    .checkHitEnergy()
-                    .checkPosition());
-    }
-    
+    public void testGTPOnlineClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("GTPOnlineClusterer")
+            .writeLcioFile()
+            .checkSeedHit()
+            .checkClusterType(ClusterType.GTP_ONLINE)
+            .checkHitEnergy()
+            .checkClusterPosition()
+            .checkHitPositions()
+            .checkNullHits());
+    }
+
     /**
      * Test the CTP clustering algorithm.
-     */
-    public void testCTPClusterer() {
-        runClustererTest("CTPClusterer", 
-                new ClustererTestSetup()
-                    .writeLcioFile()
-                    .checkClusterType(ClusterType.CTP)
-                    .checkPosition());
-    }
-    
+     */    
+    public void testCTPClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("CTPClusterer")
+            .writeLcioFile()
+            .checkClusterType(ClusterType.CTP)
+            .checkClusterPosition());
+    }
+
     /**
      * Test the GTP clustering algorithm.
      */
-    public void testGTPClusterer() {
-        runClustererTest("GTPClusterer", 
-                new ClustererTestSetup()
-                    .writeLcioFile()
-                    .checkClusterType(ClusterType.GTP)
-                    .checkHitEnergy()
-                    .checkPosition());
-    }
-    
+    public void testGTPClusterer() throws Exception {
+        runClustererTest(new ClustererTestConfig("GTPClusterer")
+            .writeLcioFile()
+            .checkClusterType(ClusterType.GTP)
+            .checkClusterPosition());
+    }
+
     /**
      * Run the standard test for a Clusterer.
      * @param clustererName The name of the Clusterer.
      * @param cuts The cut values.
      * @param writeLcioFile Whether or not to write an LCIO output file.
      */
-    private void runClustererTest(String clustererName, ClustererTestSetup setup) {
-        
-        System.out.println("testing Clusterer " + clustererName + " ...");
-                
+    private void runClustererTest(ClustererTestConfig config) throws Exception {
+
+        /**********************************************************
+         * Run the job to create clusters and write to LCIO file. *
+         **********************************************************/               
+        System.out.println("testing Clusterer " + config.clustererName + " ...");
         // Configure the loop.
-        LCSimLoop loop = new LCSimLoop();       
+        LCSimLoop loop = new LCSimLoop();
         try {
             // Set the input LCIO file.
             loop.setLCIORecordSource(inputFile);
         } catch (IOException e) {
             throw new RuntimeException(e);
-        }        
-        
+        }
+
         // Setup event number print outs.
         EventMarkerDriver eventMarkerDriver = new EventMarkerDriver();
         eventMarkerDriver.setEventInterval(1);
         loop.add(eventMarkerDriver);
+
+        // Configure the ClusterDriver and add it to the loop.
+        ClusterDriver clusterDriver = new ClusterDriver();
+        clusterDriver.setClustererName(config.clustererName);
+        if (config.cuts != null) {
+            clusterDriver.setCuts(config.cuts);
+        }
+        clusterDriver.getLogger().setLevel(Level.ALL);
+        clusterDriver.setInputHitCollectionName("EcalHits");
+        clusterDriver.setOutputClusterCollectionName(config.getClusterCollectionName());
+        clusterDriver.setRaiseErrorNoHitCollection(true);
+        loop.add(clusterDriver);
+
+        // This Driver checks the Clusters for validity.
+        loop.add(new ClusterCheckDriver(config));
         
-        // Configure the ClusterDriver and add it to the loop.
-        String clusterCollectionName = clustererName + "Clusters";
-        ClusterDriver clusterDriver = new ClusterDriver();
-        clusterDriver.setClustererName(clustererName);
-        if (setup.cuts != null) {
-            clusterDriver.setCuts(setup.cuts);
-        }
-        clusterDriver.getLogger().setLevel(Level.ALL);
-        clusterDriver.setInputHitCollectionName("EcalHits");       
-        clusterDriver.setOutputClusterCollectionName(clusterCollectionName);
-        clusterDriver.setRaiseErrorNoHitCollection(true);
-        clusterDriver.setSortHits(setup.sortHits);              
-        loop.add(clusterDriver);                         
+        // This Driver makes plots from the Cluster data.
+        loop.add(new ClusterPlotsDriver(config));
+       
+        // Setup writing of LCIO file with the output Clusters from this clustering algorithm.
+        String outputFilePath = testOutputDir.getPath() + File.separator + config.clustererName + ".slcio";
+        if (config.writeLcioFile) {
+            loop.add(new LCIODriver(outputFilePath));
+        }
         
-        // This Driver generates plots and the output LCIO file.
-        loop.add(new ClusterCheckDriver(clusterCollectionName, setup));
-        
-        if (setup.writeLcioFile) {
-            loop.add(new LCIODriver(testOutputDir.getPath() + File.separator + clustererName + ".slcio"));
-        }
-        
-        // Run the job.
-        long startMillis = System.currentTimeMillis();
-        try {
-            loop.loop(nEvents);
-            long elapsedSeconds = (System.currentTimeMillis() - startMillis) / 1000;
-            System.out.println(clustererName + " took " + elapsedSeconds + "s for " + 
-                    loop.getTotalSupplied() + " events which is " + (double)loop.getTotalSupplied()/(double)elapsedSeconds +
-                    " events/s");
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+        // Run job over the input events to generate clusters, check their validity, and fill plots.
+        long startNanos = System.nanoTime();
+        loop.loop(nEvents);
+        long elapsedMillis = (System.nanoTime() - startNanos) / 1000000;
+        System.out.println(config.clustererName + " took " + elapsedMillis + "ms for " + loop.getTotalSupplied() 
+                + " events which is " + (double) loop.getTotalSupplied() / (((double) elapsedMillis) / 1000.) + " events/s");
         loop.dispose();
-    }
-           
-    /**
-     * This Driver will check some of the basic Cluster values (currently just size and energy).
-     * It also produces some QA plots for each Clusterer in its own output AIDA dir within the plot tree.
-     */
-    static class ClusterCheckDriver extends Driver {                
-        
+
+        /***************************************************
+         * Reread the file and run the check Driver again. *
+         ***************************************************/         
+        File clusterFile = new File(testOutputDir.getPath() + File.separator + config.clustererName + ".slcio");
+        System.out.println("rereading " + clusterFile.getPath() + "...");
+        loop = new LCSimLoop();
+        loop.setLCIORecordSource(clusterFile);
+        loop.add(new ClusterCheckDriver(config));
+        loop.loop(nEvents);
+        loop.dispose();
+
+    }
+
+    /**
+     * Driver that performs test assertions on Cluster collections.
+     */
+    static class ClusterCheckDriver extends Driver {
+
+        ClustererTestConfig config;
+
+        ClusterCheckDriver(ClustererTestConfig config) {
+            this.config = config;
+        }
+
+        public void process(EventHeader event) {
+            List<Cluster> clusters = event.get(Cluster.class, config.getClusterCollectionName());
+            for (Cluster cluster : clusters) {
+                // Test assertions.
+                checkCluster(cluster);
+            }
+        }
+
+        /**
+         * @param cluster
+         */
+        private void checkCluster(Cluster cluster) {
+            assertTrue("The cluster energy is invalid.", cluster.getEnergy() > 0.);
+            assertTrue("The cluster has no hits.", !cluster.getCalorimeterHits().isEmpty());
+            if (config.checkSeedHit) {
+                assertEquals("First hit is not seed.", cluster.getCalorimeterHits().get(0), ClusterUtilities.findHighestEnergyHit(cluster));
+            }
+            if (config.checkPropCalc) {
+                assertTrue("Cluster properties not calculated.", !((BaseCluster) cluster).needsPropertyCalculation());
+            }
+            if (config.clusterType != null) {
+                assertEquals("Cluster type is not correct.", config.clusterType, ClusterType.getClusterType(cluster.getType()));
+            }            
+            if (config.checkClusterPosition) {
+                double[] position = cluster.getPosition();
+                assertTrue("Position X is invalid.", Math.abs(position[0]) < 400. && position[0] != 0.);
+                assertTrue("Position Y is invalid.", Math.abs(position[1]) > 25. && Math.abs(position[1]) < 90.);
+                assertTrue("Position Z is invalid.", position[2] > 1385. && position[2] < 1480.);
+            }
+            for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
+                if (config.checkNullHits) {
+                    TestCase.assertNotNull("A hit from the cluster points to null.", hit);
+                }                
+                if (hit != null) {
+                    if (config.checkHitPositions) {
+                        double[] hitPosition = hit.getPosition();
+                        assertTrue("Hit Position X is invalid.", hitPosition[0] != 0.);
+                        assertTrue("Hit Position Y is invalid.", hitPosition[1] != 0.);
+                        assertTrue("Hit Position Z is invalid.", hitPosition[2] != 0.);
+                        EcalCrystal crystal = CalorimeterHitUtilities.findCrystal(hit);
+                        assertTrue("Hit does not link correctly to geometry.", crystal != null);
+                    }
+                    if (config.checkHitEnergy) {    
+                        assertTrue("Hit energy " + hit.getCorrectedEnergy() + " is <= 0.", hit.getCorrectedEnergy() > 0.);
+                    }
+                    double time = hit.getTime();
+                    assertTrue("Hit time is invalid.", time != 0.);
+                }
+            }
+        }
+    }
+
+    /**
+     * This Driver produces some QA plots for each Clusterer in its own output AIDA dir within the plot tree.
+     * All the plots are written to a single file at the end of the job.
+     */
+    static class ClusterPlotsDriver extends Driver {
+
         AIDA aida = AIDA.defaultInstance();
         IHistogram1D energyH1D;
         IHistogram1D uncorrectedEnergyH1D;
         IHistogram1D countH1D;
-        IHistogram1D sizeH1D;    
+        IHistogram1D sizeH1D;
         IHistogram1D highestHitEnergyH1D;
         IHistogram1D hitEnergyH1D;
         IHistogram2D rawVsCorrectedH2D;
@@ -303,14 +392,14 @@
         IHistogram1D latestHitTimeH1D;
         String clusterCollectionName;
         String clustererName;
-        
-        ClustererTestSetup setup;
-        
-        ClusterCheckDriver(String clusterCollectionName, ClustererTestSetup setup) {
-            this.clusterCollectionName = clusterCollectionName;
-            this.setup = setup;
-        }        
-        
+
+        ClustererTestConfig config;
+
+        ClusterPlotsDriver(ClustererTestConfig config) {
+            this.config = config;
+            this.clusterCollectionName = config.getClusterCollectionName();
+        }
+
         public void startOfData() {
             energyH1D = aida.histogram1D(clusterCollectionName + "/Cluster Energy", 300, 0.0, 3.0);
             uncorrectedEnergyH1D = aida.histogram1D(clusterCollectionName + "/Uncorrected Cluster Energy", 200, 0.0, 2.0);
@@ -337,17 +426,14 @@
             latestHitTimeH1D = aida.histogram1D(clusterCollectionName + "/Latest Hit Time", 500, 0., 500.);
             clusterVsHitCountC2d = aida.cloud2D(clusterCollectionName + "/Cluster Vs Hit Count");
         }
-        
+
         public void process(EventHeader event) {
             List<Cluster> clusters = event.get(Cluster.class, this.clusterCollectionName);
             for (Cluster cluster : clusters) {
-                
-                // Test assertions.
-                checkCluster(cluster);                
-                
+
                 // Fill plots.
                 fillClusterPlots(cluster);
-            }            
+            }
             countH1D.fill(clusters.size());
             clusterVsHitCountC2d.fill(clusters.size(), ClusterUtilities.getHits(clusters).size());
         }
@@ -363,7 +449,7 @@
             rawVsCorrectedH2D.fill(rawEnergy, cluster.getEnergy());
             for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
                 hitEnergyH1D.fill(hit.getCorrectedEnergy());
-            }                
+            }
             highestHitEnergyH1D.fill(ClusterUtilities.findHighestEnergyHit(cluster).getCorrectedEnergy());
             positionXH1D.fill(Math.abs(cluster.getPosition()[0]));
             positionYH1D.fill(Math.abs(cluster.getPosition()[1]));
@@ -374,11 +460,11 @@
                 shapeParam3H1D.fill(cluster.getShape()[2]);
             }
             iphiC1D.fill(Math.toDegrees(cluster.getIPhi()));
-            ithetaC1D.fill(Math.toDegrees(cluster.getITheta()));                                
+            ithetaC1D.fill(Math.toDegrees(cluster.getITheta()));
             clusterPositionC2D.fill(cluster.getPosition()[0], cluster.getPosition()[1]);
-            
-            //Map<MCParticle, List<SimCalorimeterHit>> particleHitMap = ClusterUtilities.createParticleHitMap(cluster);
-            
+
+            // Map<MCParticle, List<SimCalorimeterHit>> particleHitMap = ClusterUtilities.createParticleHitMap(cluster);
+
             Set<MCParticle> particles = ClusterUtilities.findMCParticles(cluster);
             double particleEnergy = 0;
             double highestParticleEnergy = Double.MIN_VALUE;
@@ -400,46 +486,8 @@
             earliestHitTimeH1D.fill(hitsForTime.get(0).getTime());
             latestHitTimeH1D.fill(hitsForTime.get(hitsForTime.size() - 1).getTime());
         }
-
-        /**
-         * @param cluster
-         */
-        private void checkCluster(Cluster cluster) {
-            assertTrue("The cluster energy is invalid.", cluster.getEnergy() > 0.);
-            assertTrue("The cluster has no hits.", !cluster.getCalorimeterHits().isEmpty());
-            if (setup.checkSeedHit) {
-                assertEquals("First hit is not seed.", cluster.getCalorimeterHits().get(0), ClusterUtilities.findHighestEnergyHit(cluster));
-            }
-            if (setup.checkPropCalc) {
-                assertTrue("Cluster properties not calculated.", !((BaseCluster)cluster).needsPropertyCalculation());
-            }
-            if (setup.clusterType != null) {
-                assertEquals("Cluster type is not correct.", setup.clusterType, ClusterType.getClusterType(cluster.getType()));
-            }
-            if (setup.checkHitEnergy) {
-                for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
-                    assertTrue("Hit energy " + hit.getCorrectedEnergy() + " is <= 0.", hit.getCorrectedEnergy() > 0.);
-                }
-            }
-            if (setup.checkClusterPosition) {
-                double[] position = cluster.getPosition();
-                assertTrue("Position X is invalid.", Math.abs(position[0]) < 400. && position[0] != 0.);
-                assertTrue("Position Y is invalid.", Math.abs(position[1]) > 25. && Math.abs(position[1]) < 90.);
-                assertTrue("Position Z is invalid.", position[2] > 1385. && position[2] < 1480.);
-            }
-            if (setup.checkHitPositions) {
-                for (CalorimeterHit hit : cluster.getCalorimeterHits()) {
-                    double[] hitPosition = hit.getPosition();
-                    assertTrue("Hit Position X is invalid.", hitPosition[0] != 0.);
-                    assertTrue("Hit Position Y is invalid.", hitPosition[1] != 0.);
-                    assertTrue("Hit Position Z is invalid.", hitPosition[2] != 0.);
-                    EcalCrystal crystal = CalorimeterHitUtilities.findCrystal(hit);
-                    assertTrue("Hit does not link correctly to geometry.", crystal != null);
-                }
-            }
-        }              
-    }
-    
+    }
+
     /**
      * This method writes the AIDA file to disk from all the tests.
      */
@@ -449,5 +497,5 @@
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
-    }  
+    }
 }