Print

Print


Author: [log in to unmask]
Date: Fri Jan  9 18:01:48 2015
New Revision: 1914

Log:
Add type encoding for different types of clusters.

Added:
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterType.java
Modified:
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CTPClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java
    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/Clusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/DualThresholdCosmicClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/NearestNeighborClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterDriver.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.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/AbstractClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/AbstractClusterer.java	Fri Jan  9 18:01:48 2015
@@ -8,6 +8,7 @@
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
+import org.lcsim.event.base.BaseCluster;
 import org.lcsim.geometry.subdetector.HPSEcal3;
 import org.lcsim.geometry.subdetector.HPSEcal3.NeighborMap;
 
@@ -71,6 +72,20 @@
     public abstract List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits);
     
     /**
+     * Get the type code for the clusters produced by this algorithm.
+     * @return The type code of the cluster.
+     */
+    public abstract ClusterType getClusterType();
+    
+    /**
+     * Get the integer encoding of the <code>Cluster</code> type.
+     * @return The integer encoding of the Cluster type.
+     */
+    public final int getClusterTypeEncoding() {
+        return getClusterType().getType();
+    }
+    
+    /**
      * Detector setup performed here to get reference to ECAL subdetector and neighbor mapping.
      */
     @Override
@@ -92,7 +107,7 @@
      * Get the numerical cut settings.
      * @return The numerical cuts.
      */
-    public NumericalCuts getCuts() {
+    public final NumericalCuts getCuts() {
         return this.cuts;
     }
     
@@ -100,7 +115,16 @@
      * Convenience method to get the identifier helper from the ECAL subdetector.
      * @return The identifier helper.
      */
-    protected IIdentifierHelper getIdentifierHelper() {
+    protected final IIdentifierHelper getIdentifierHelper() {
         return ecal.getDetectorElement().getIdentifierHelper();
     }
+    
+    /**
+     * Create a basic <code>Cluster</code> with the correct type.
+     */
+    public BaseCluster createBasicCluster() {
+        BaseCluster cluster = new BaseCluster();
+        cluster.setType(getClusterType().getType());
+        return cluster;
+    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CTPClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CTPClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/CTPClusterer.java	Fri Jan  9 18:01:48 2015
@@ -304,7 +304,7 @@
                 CalorimeterHit seedHit = (BaseCalorimeterHit)CalorimeterHitUtilities.create(0.0, clusterTime, possibleCluster, hits.get(0).getMetaData());
 
                 // Generate a new cluster from the seed hit.
-                BaseCluster cluster = new BaseCluster();
+                BaseCluster cluster = createBasicCluster();
                 cluster.addHit(seedHit);
                 // Populate the cluster with each of the chosen neighbors.
                 for (CalorimeterHit clusterHit : hits) {
@@ -329,4 +329,9 @@
             }
         }
     }
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.CTP;
+    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterDriver.java	Fri Jan  9 18:01:48 2015
@@ -44,9 +44,9 @@
     protected boolean writeClusterCollection = true;
     protected boolean storeHits = true;
     protected double[] cuts;
-    protected boolean sortHits = true;
-    protected boolean calculateProperties = true;
-    protected boolean applyCorrections = false;
+    protected boolean sortHits;
+    protected boolean calculateProperties;
+    protected boolean applyCorrections;
     
     /**
      * No argument constructor.

Added: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterType.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterType.java	(added)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ClusterType.java	Fri Jan  9 18:01:48 2015
@@ -0,0 +1,58 @@
+package org.hps.recon.ecal.cluster;
+
+/**
+ * Type codes for different kinds of ECAL clusters.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public enum ClusterType {
+    
+    // Do not change the value assignments!
+    RECON(1000),
+    SIMPLE_RECON(1001),
+    LEGACY(1002),
+    GTP(1003),
+    GTP_ONLINE(1004),
+    CTP(1005),
+    NN(1006),
+    SIMPLE_COSMIC(1007),
+    DUAL_THRESHOLD_COSMIC(1008);   
+    // Any additional types should be added at end of the list.
+                
+    private int type;
+    
+    ClusterType(int type) {
+        this.type = type;
+    }
+        
+    public int getType() {
+        return type;
+    }
+    
+    public static ClusterType getClusterType(int type) {                
+        if (type == RECON.getType()) {
+            return RECON;
+        } else if (type == SIMPLE_RECON.getType()) {
+            return SIMPLE_RECON;
+        } else if (type == LEGACY.getType()) {
+            return LEGACY;
+        } else if (type == GTP.getType()) {
+            return GTP;
+        } else if (type == GTP_ONLINE.getType()) {
+            return GTP_ONLINE;
+        } else if (type == CTP.getType()) {
+            return CTP;
+        } else if (type == NN.getType()) {
+            return NN;
+        } else if (type == SIMPLE_COSMIC.getType()) {
+            return SIMPLE_COSMIC;
+        } else if (type == DUAL_THRESHOLD_COSMIC.getType()) {
+            return DUAL_THRESHOLD_COSMIC;
+        } else {
+            return null;
+        }
+    }
+    
+    public boolean equals(ClusterType clusterType) {
+        return clusterType.getType() == getType();
+    }
+}

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	Fri Jan  9 18:01:48 2015
@@ -23,6 +23,9 @@
  * @see org.lcsim.event.base.BaseCluster
  */
 public final class ClusterUtilities {
+    
+    // Use the HPS specific property calculator.
+    private static final ReconClusterPropertyCalculator propertyCalculator = new ReconClusterPropertyCalculator();
     
     private ClusterUtilities() {        
     }
@@ -326,10 +329,7 @@
      * @see ReconClusterEnergyCorrection
      */
     public static void applyCorrections(List<Cluster> clusters) {
-        
-        // Use the HPS specific property calculator.
-        ReconClusterPropertyCalculator calc = new ReconClusterPropertyCalculator();
-        
+                
         // Loop over the clusters.
         for (Cluster cluster : clusters) {
             
@@ -340,7 +340,7 @@
                 // First calculate the cluster properties, if needed.
                 if (baseCluster.needsPropertyCalculation()) {                
                     // Calculate the properties of the cluster.
-                    baseCluster.setPropertyCalculator(calc);
+                    baseCluster.setPropertyCalculator(propertyCalculator);
                     baseCluster.calculateProperties();
                 }
             
@@ -351,6 +351,31 @@
                 ReconClusterEnergyCorrection.setCorrectedEnergy(baseCluster);
             }
         }
+    }
+    
+    /**
+     * Apply HPS-specific energy and position corrections to a single Cluster.
+     * 
+     * @see ReconClusterPropertyCalculator
+     * @see ReconClusterPositionCorrection
+     * @see ReconClusterEnergyCorrection
+     */
+    public static void applyCorrections(Cluster cluster) {
+
+        BaseCluster baseCluster = (BaseCluster)cluster;            
+
+        // First calculate the cluster properties, if needed.
+        if (baseCluster.needsPropertyCalculation()) {                
+            // Calculate the properties of the cluster.
+            baseCluster.setPropertyCalculator(propertyCalculator);
+            baseCluster.calculateProperties();
+        }
+
+        // Apply position correction, which should happen before final energy correction.
+        ReconClusterPositionCorrection.setCorrectedPosition(baseCluster);
+
+        // Apply energy correction.
+        ReconClusterEnergyCorrection.setCorrectedEnergy(baseCluster);              
     }
     
     /**

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/Clusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/Clusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/Clusterer.java	Fri Jan  9 18:01:48 2015
@@ -6,6 +6,7 @@
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
+import org.lcsim.event.base.BaseCluster;
 
 /**
  * This is an interface for creating clusters and providing cut values
@@ -51,4 +52,23 @@
      * @return The numerical cut settings.
      */
     NumericalCuts getCuts();
+    
+    /**
+     * Get the type of <code>Cluster</code> created by this algorithm.
+     * @return The type of the Cluster.
+     */
+    ClusterType getClusterType();
+    
+    /**
+     * Get the integer encoding of the <code>Cluster</code> type.
+     * This is a convenience method, and it is declared as final in the abstract implementation.
+     * @return The integer encoding of the Cluster type.
+     */
+    int getClusterTypeEncoding();
+    
+    /**
+     * Create a basic <code>Cluster</code> with the correct type for this algorithm. 
+     * @return The basic Cluster.
+     */
+    BaseCluster createBasicCluster();
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/DualThresholdCosmicClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/DualThresholdCosmicClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/DualThresholdCosmicClusterer.java	Fri Jan  9 18:01:48 2015
@@ -113,5 +113,9 @@
         }        
         return set;
     }
-    
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.DUAL_THRESHOLD_COSMIC;
+    }    
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java	Fri Jan  9 18:01:48 2015
@@ -120,7 +120,7 @@
             
             // Store the crystals that are part of this potential cluster, 
             // starting with the cluster seed candidate.
-            BaseCluster cluster = new BaseCluster();            
+            BaseCluster cluster = createBasicCluster();            
             cluster.addHit(currentHit);
             
             // Get the set of neighbors for this hit.
@@ -267,5 +267,10 @@
         else {
             this.seedEnergyThreshold = seedEnergyThreshold;
         }
+    }
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.GTP;
     }     
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java	Fri Jan  9 18:01:48 2015
@@ -112,7 +112,7 @@
                 }
 
                 // Create a cluster for the potential seed.
-                BaseCluster protoCluster = new BaseCluster();
+                BaseCluster protoCluster = createBasicCluster();
                 protoCluster.addHit(seed);
 
                 // Iterate over the other hits and if the are within
@@ -353,4 +353,9 @@
         timeAfter = cyclesAfter * 4;
         timeWindow = Math.max(timeBefore, timeAfter);
     }
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.GTP_ONLINE;
+    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/LegacyClusterer.java	Fri Jan  9 18:01:48 2015
@@ -80,7 +80,7 @@
             // Did we find a seed?
             if (isSeed) {
                 // Make a cluster from the hit list.
-                BaseCluster cluster = new BaseCluster();
+                BaseCluster cluster = createBasicCluster();
                 cluster.addHit(hit);
                 for (CalorimeterHit clusHit : neighborHits) {
                     cluster.addHit(clusHit);
@@ -90,4 +90,9 @@
         }
         return clusters;
     }
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.LEGACY;
+    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/NearestNeighborClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/NearestNeighborClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/NearestNeighborClusterer.java	Fri Jan  9 18:01:48 2015
@@ -59,7 +59,7 @@
      * @param neighborMap The map of HPS crystal neighbors.
      */    
     BaseCluster createCluster(Map<Long, CalorimeterHit> map, CalorimeterHit hit) {
-        BaseCluster cluster = new BaseCluster();
+        BaseCluster cluster = createBasicCluster();
         // start by adding this hit to the cluster
         cluster.addHit(hit);
         // remove this hit from the map so it can't be used again
@@ -88,4 +88,8 @@
         }
         return cluster;
     }
+    
+    public ClusterType getClusterType() {
+        return ClusterType.NN;
+    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterDriver.java	Fri Jan  9 18:01:48 2015
@@ -24,8 +24,13 @@
     boolean writeRejectedHitCollection = false;
             
     public ReconClusterDriver() {
+        // Setup the Clusterer with the correct type.
         clusterer = ClustererFactory.create("ReconClusterer");
-        this.applyCorrections = true;
+        
+        // Apply default Driver settings for the ReconClusterer algorithm.
+        //this.applyCorrections = true;
+        this.calculateProperties = false; // Not needed if corrections will be applied.
+        this.sortHits = true; // Need this for correct seed hit position in list.
     }
     
     public void setClusterer(Clusterer clusterer) {

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java	Fri Jan  9 18:01:48 2015
@@ -480,8 +480,12 @@
                     }
 
                     else {
+                        
+                        // FIXME: All of the following should be converted to use the BaseCluster API. --JM
+                        
                         // New cluster
                         HPSEcalClusterIC cluster = new HPSEcalClusterIC(entry2.getKey());
+                        cluster.setType(this.getClusterTypeEncoding());
                         clusterList.add(cluster);
                         // Loop over hits belonging to seeds
                         for (Map.Entry<CalorimeterHit, CalorimeterHit> entry3 : hitSeedMap.entrySet()) {
@@ -618,4 +622,8 @@
         return isSeed;
     }
     
+    public ClusterType getClusterType() {
+        return ClusterType.RECON;
+    }
+    
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/SimpleCosmicClusterer.java	Fri Jan  9 18:01:48 2015
@@ -155,5 +155,10 @@
             }
         }
         return selectedClusters;
+    }
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.SIMPLE_COSMIC;
     }    
 }

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	Fri Jan  9 18:01:48 2015
@@ -107,7 +107,7 @@
             }
             if (biggestSeed == null) { // if no neighbors had more energy than this hit, this hit is a seed
                 hitToSeed.put(hit, hit);
-                BaseCluster cluster = new BaseCluster();
+                BaseCluster cluster = createBasicCluster();
                 clusters.add(cluster);
                 seedToCluster.put(hit, cluster);
             } else {
@@ -124,4 +124,9 @@
         
         return clusters;
     }
+
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.SIMPLE_RECON;
+    }
 }

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	Fri Jan  9 18:01:48 2015
@@ -39,6 +39,42 @@
     static final String fileLocation = "http://www.lcsim.org/test/hps-java/MockDataReconTest.slcio";
     File inputFile;
     File testOutputDir;
+    
+    static class ClustererTestSetup {
+        
+        boolean writeLcioFile = false;
+        boolean checkSeedHit = false;
+        boolean applyCorrections = false;        
+        double[] cuts = null;
+        ClusterType clusterType; 
+        
+        ClustererTestSetup(double[] cuts) {
+            this.cuts = cuts;            
+        }
+        
+        ClustererTestSetup() {            
+        }
+        
+        ClustererTestSetup writeLcioFile() {
+            writeLcioFile = true;
+            return this;
+        }
+        
+        ClustererTestSetup checkSeedHit() {
+            checkSeedHit = true;
+            return this;
+        }
+        
+        ClustererTestSetup applyCorrections() {
+            applyCorrections = true;
+            return this;
+        }        
+        
+        ClustererTestSetup checkClusterType(ClusterType clusterType) {
+            this.clusterType = clusterType;
+            return this;
+        }
+    }
          
     public void setUp() {
         // Cache the input file.
@@ -57,36 +93,60 @@
         DatabaseConditionsManager.getInstance().setLogLevel(Level.WARNING);
     }
     
-    public void testReconClusterer() {
-        //runClustererTest("ReconClusterer", new double[] { 0.0075, 0.1, 0.3, 0.0, 20.0 }, true);
-        runClustererTest("ReconClusterer", null, true, true);
-    }
-    
+    /**
+     * Test the recon clustering algorithm, formerly called the IC clusterer.
+     */
+    public void testReconClusterer() {        
+        runClustererTest("ReconClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkSeedHit().applyCorrections().checkClusterType(ClusterType.RECON));
+    }
+    
+    /**
+     * Test a simple version of the recon clustering.
+     */
     public void testSimpleReconClusterer() {
-        //runClustererTest("SimpleReconClusterer", new double[] { 0.0, 0.0, 9999.0, 0. }, true);
-        runClustererTest("SimpleReconClusterer", null, true, true);
-    }
-    
+        runClustererTest("SimpleReconClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkSeedHit().checkClusterType(ClusterType.SIMPLE_RECON));
+    }
+    
+    /**
+     * Test a simplistic NN clustering algorithm.
+     */
     public void testNearestNeighborClusterer() {    
-        //runClustererTest("NearestNeighborClusterer", new double[] { 0.0, 2.0 }, true);
-        runClustererTest("NearestNeighborClusterer", null, true, false);
-    }
-    
+        runClustererTest("NearestNeighborClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkClusterType(ClusterType.NN));
+    }
+    
+    /**
+     * Test the clustering algorithm from the Test Run proposal document.
+     */
     public void testLegacyClusterer() {
-        //runClustererTest("LegacyClusterer", new double[] { 0.0, 0.0 }, true);
-        runClustererTest("LegacyClusterer", null, true, false);
-    }
-    
+        runClustererTest("LegacyClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkClusterType(ClusterType.LEGACY));
+    }
+    
+    /**
+     * Test the online version of the GTP algorithm.
+     */
     public void testGTPOnlineClusterer() {
-        runClustererTest("GTPOnlineClusterer", null, true, true);
-    }
-    
+        runClustererTest("GTPOnlineClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkSeedHit().checkClusterType(ClusterType.GTP_ONLINE));
+    }
+    
+    /**
+     * Test the CTP clustering algorithm.
+     */
     public void testCTPClusterer() {
-        runClustererTest("CTPClusterer", null, true, false);
-    }
-    
+        runClustererTest("CTPClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkClusterType(ClusterType.CTP));
+    }
+    
+    /**
+     * Test the GTP clustering algorithm.
+     */
     public void testGTPClusterer() {
-        runClustererTest("GTPClusterer", null, true, false);
+        runClustererTest("GTPClusterer", 
+                new ClustererTestSetup().writeLcioFile().checkSeedHit().checkClusterType(ClusterType.GTP));
     }
     
     /**
@@ -95,7 +155,7 @@
      * @param cuts The cut values.
      * @param writeLcioFile Whether or not to write an LCIO output file.
      */
-    private void runClustererTest(String clustererName, double[] cuts, boolean writeLcioFile, boolean checkSeedHit) {
+    private void runClustererTest(String clustererName, ClustererTestSetup setup) {
         
         System.out.println("testing Clusterer " + clustererName + " ...");
                 
@@ -117,8 +177,8 @@
         String clusterCollectionName = clustererName + "Clusters";
         ClusterDriver clusterDriver = new ClusterDriver();
         clusterDriver.setClustererName(clustererName);
-        if (cuts != null) {
-            clusterDriver.setCuts(cuts);
+        if (setup.cuts != null) {
+            clusterDriver.setCuts(setup.cuts);
         }
         clusterDriver.getLogger().setLevel(Level.ALL);
         clusterDriver.setInputHitCollectionName("EcalHits");       
@@ -126,13 +186,14 @@
         clusterDriver.setRaiseErrorNoHitCollection(true);
         clusterDriver.setCalculateProperties(true);
         clusterDriver.setSortHits(true);
+        clusterDriver.setApplyCorrections(setup.applyCorrections);
         clusterDriver.getLogger().setLevel(Level.CONFIG);
         loop.add(clusterDriver);                         
         
         // This Driver generates plots and the output LCIO file.
-        loop.add(new ClusterCheckDriver(clusterCollectionName, checkSeedHit));
-        
-        if (writeLcioFile) {
+        loop.add(new ClusterCheckDriver(clusterCollectionName, setup.checkSeedHit, setup.clusterType));
+        
+        if (setup.writeLcioFile) {
             loop.add(new LCIODriver(testOutputDir.getPath() + File.separator + clustererName + ".slcio"));
         }
         
@@ -177,10 +238,12 @@
         String clusterCollectionName;
         String clustererName;        
         boolean checkSeedHit = true;
-        
-        ClusterCheckDriver(String clusterCollectionName, boolean checkSeedHit) {
+        ClusterType clusterType;
+        
+        ClusterCheckDriver(String clusterCollectionName, boolean checkSeedHit, ClusterType clusterType) {
             this.clusterCollectionName = clusterCollectionName;
             this.checkSeedHit = checkSeedHit;
+            this.clusterType = clusterType;
         }        
         
         public void startOfData() {
@@ -212,6 +275,9 @@
                     assertEquals("First hit is not seed.", cluster.getCalorimeterHits().get(0), ClusterUtilities.findHighestEnergyHit(cluster));
                 }
                 assertTrue("Cluster properties not calculated.", !((BaseCluster)cluster).needsPropertyCalculation());
+                if (clusterType != null) {
+                    assertEquals("Cluster type is not correct.", clusterType, ClusterType.getClusterType(cluster.getType()));
+                }
                 energyH1D.fill(cluster.getEnergy());
                 double rawEnergy = ClusterUtilities.computeRawEnergy(cluster);
                 uncorrectedEnergyH1D.fill(rawEnergy);