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);
}
- }
+ }
}
|