Commit in java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal on MAIN
FADCPrimaryTriggerDriver.java+388-3781147 -> 1148
MollerTrigger.java+437added 1148
NeutralPionTriggerDriver.java+1027-10271147 -> 1148
+1852-1405
1 added + 2 modified, total 3 files
Added trigger plots to primary trigger; created Moller trigger driver; replaced tabs with spaces for primary trigger, moller trigger, and pion trigger.

java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal
FADCPrimaryTriggerDriver.java 1147 -> 1148
--- java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java	2014-10-07 08:18:48 UTC (rev 1147)
+++ java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/FADCPrimaryTriggerDriver.java	2014-10-07 20:04:37 UTC (rev 1148)
@@ -28,45 +28,45 @@
     // ==================================================================
     // ==== Trigger Cut Default Parameters ==============================
     // ==================================================================
-    private int minHitCount = 1;								// Minimum required cluster hit count threshold. (Hits)			
-    private double seedEnergyHigh = Double.MAX_VALUE;			// Maximum allowed cluster seed energy. (GeV)
-    private double seedEnergyLow = Double.MIN_VALUE;			// Minimum required cluster seed energy. (GeV)
-    private double clusterEnergyHigh = 1.5 * ECalUtils.GeV;		// Maximum allowed cluster total energy. (GeV)
-    private double clusterEnergyLow = .1 * ECalUtils.GeV;		// Minimum required cluster total energy. (GeV)
-    private double energySumHigh = 1.9 * ECalUtils.GeV;			// Maximum allowed pair energy sum. (GeV)
-    private double energySumLow = 0.0 * ECalUtils.GeV;			// Minimum required pair energy sum. (GeV)
-    private double energyDifferenceHigh = 2.2 * ECalUtils.GeV;	// Maximum allowed pair energy difference. (GeV)
-    private double energySlopeLow = 1.1;						// Minimum required pair energy slope value.
-    private double coplanarityHigh = 35;						// Maximum allowed pair coplanarity deviation. (Degrees)
+    private int minHitCount = 1;                                   // Minimum required cluster hit count threshold. (Hits)            
+    private double seedEnergyHigh = Double.MAX_VALUE;              // Maximum allowed cluster seed energy. (GeV)
+    private double seedEnergyLow = Double.MIN_VALUE;               // Minimum required cluster seed energy. (GeV)
+    private double clusterEnergyHigh = 1.5 * ECalUtils.GeV;        // Maximum allowed cluster total energy. (GeV)
+    private double clusterEnergyLow = .1 * ECalUtils.GeV;          // Minimum required cluster total energy. (GeV)
+    private double energySumHigh = 1.9 * ECalUtils.GeV;            // Maximum allowed pair energy sum. (GeV)
+    private double energySumLow = 0.0 * ECalUtils.GeV;             // Minimum required pair energy sum. (GeV)
+    private double energyDifferenceHigh = 2.2 * ECalUtils.GeV;     // Maximum allowed pair energy difference. (GeV)
+    private double energySlopeLow = 1.1;                           // Minimum required pair energy slope value.
+    private double coplanarityHigh = 35;                           // Maximum allowed pair coplanarity deviation. (Degrees)
     
     // ==================================================================
     // ==== Trigger General Default Parameters ==========================
     // ==================================================================
-    private String clusterCollectionName = "EcalClusters";		// Name for the LCIO cluster collection.
-    private int pairCoincidence = 2;							// Maximum allowed time difference between clusters. (4 ns clock-cycles)
-    private double energySlopeParamF = 0.005500;				// A parameter value used for the energy slope calculation.
-    private double originX = 1393.0 * Math.tan(0.03052);		// ECal mid-plane, defined by photon beam position (30.52 mrad) at ECal face (z=1393 mm)
-    private int backgroundLevel = -1;							// Automatically sets the cuts to achieve a predetermined background rate.
+    private String clusterCollectionName = "EcalClusters";        // Name for the LCIO cluster collection.
+    private int pairCoincidence = 2;                              // Maximum allowed time difference between clusters. (4 ns clock-cycles)
+    private double energySlopeParamF = 0.005500;                  // A parameter value used for the energy slope calculation.
+    private double originX = 1393.0 * Math.tan(0.03052);          // ECal mid-plane, defined by photon beam position (30.52 mrad) at ECal face (z=1393 mm)
+    private int backgroundLevel = -1;                            // Automatically sets the cuts to achieve a predetermined background rate.
     
     // ==================================================================
     // ==== Driver Internal Variables ===================================
     // ==================================================================
-    private Queue<List<HPSEcalCluster>> topClusterQueue = null;	// Store clusters on the top half of the calorimeter.
-    private Queue<List<HPSEcalCluster>> botClusterQueue = null;	// Store clusters on the bottom half of the calorimeter.
-    private int allClusters = 0;								// Track the number of clusters processed.
-    private int allPairs = 0;									// Track the number of cluster pairs processed.
-    private int clusterTotalEnergyCount = 0;					// Track the clusters which pass the total energy cut.
-    private int clusterSeedEnergyCount = 0;						// Track the clusters which pass the seed energy cut.
-    private int clusterHitCountCount = 0;						// Track the clusters which pass the hit count cut.
-    private int pairEnergySumCount = 0;							// Track the pairs which pass the energy sum cut.
-    private int pairEnergyDifferenceCount = 0;					// Track the pairs which pass the energy difference cut.
-    private int pairEnergySlopeCount = 0;						// Track the pairs which pass the energy slope cut.
-    private int pairCoplanarityCount = 0;						// Track the pairs which pass the coplanarity cut.
+    private Queue<List<HPSEcalCluster>> topClusterQueue = null;    // Store clusters on the top half of the calorimeter.
+    private Queue<List<HPSEcalCluster>> botClusterQueue = null;    // Store clusters on the bottom half of the calorimeter.
+    private int allClusters = 0;                                   // Track the number of clusters processed.
+    private int allPairs = 0;                                      // Track the number of cluster pairs processed.
+    private int clusterTotalEnergyCount = 0;                       // Track the clusters which pass the total energy cut.
+    private int clusterSeedEnergyCount = 0;                        // Track the clusters which pass the seed energy cut.
+    private int clusterHitCountCount = 0;                          // Track the clusters which pass the hit count cut.
+    private int pairEnergySumCount = 0;                            // Track the pairs which pass the energy sum cut.
+    private int pairEnergyDifferenceCount = 0;                     // Track the pairs which pass the energy difference cut.
+    private int pairEnergySlopeCount = 0;                          // Track the pairs which pass the energy slope cut.
+    private int pairCoplanarityCount = 0;                          // Track the pairs which pass the coplanarity cut.
     
     // ==================================================================
     // ==== Trigger Distribution Plots ==================================
     // ==================================================================
-	private AIDA aida = AIDA.defaultInstance();
+    private AIDA aida = AIDA.defaultInstance();
     IHistogram1D clusterSeedEnergy = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution", 176, 0.0, 2.2);
     IHistogram1D clusterSeedEnergy100 = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution (Over 100 MeV)", 176, 0.0, 2.2);
     IHistogram1D clusterSeedEnergySingle = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution (Passed Single Cuts)", 176, 0.0, 2.2);
@@ -89,34 +89,36 @@
     IHistogram1D pairEnergySlope = aida.histogram1D("Trigger Plots :: Pair Energy Slope Distribution", 400, 0.0, 4.0);
     IHistogram1D pairEnergySlopeAll = aida.histogram1D("Trigger Plots :: Pair Energy Slope Distribution (Passed All Cuts)", 400, 0.0, 4.0);
     
-	IHistogram2D clusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution", 44, -22.0, 22.0, 10, -5, 5);
-	IHistogram2D clusterDistribution100 = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Over 100 MeV)", 44, -23, 23, 11, -5.5, 5.5);
-	IHistogram2D clusterDistributionSingle = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed Single Cuts)", 44, -23, 23, 11, -5.5, 5.5);
-	IHistogram2D clusterDistributionAll = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed All Cuts)", 44, -23, 23, 11, -5.5, 5.5);
+    IHistogram2D clusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution", 46, -23, 23, 11, -5.5, 5.5);
+    IHistogram2D clusterDistribution100 = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Over 100 MeV)", 46, -23, 23, 11, -5.5, 5.5);
+    IHistogram2D clusterDistributionSingle = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed Single Cuts)", 46, -23, 23, 11, -5.5, 5.5);
+    IHistogram2D clusterDistributionAll = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed All Cuts)", 46, -23, 23, 11, -5.5, 5.5);
     
+    IHistogram1D hotCrystalEnergy = aida.histogram1D("Trigger Plots :: Hot Crystal Energy Distribution", 176, 0.0, 2.2);
+    
     /**
      * Prints out the results of the trigger at the end of the run.
      */
     @Override
     public void endOfData() {
-    	// Print out the results of the trigger cuts.
-    	System.out.printf("Trigger Processing Results%n");
-    	System.out.printf("\tSingle-Cluster Cuts%n");
-    	System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
-    	System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
-    	System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
-    	System.out.printf("\t\tPassed Total Energy Cut      :: %d%n", clusterTotalEnergyCount);
-    	System.out.printf("%n");
-    	System.out.printf("\tCluster Pair Cuts%n");
-    	System.out.printf("\t\tTotal Pairs Processed        :: %d%n", allPairs);
-    	System.out.printf("\t\tPassed Energy Sum Cut        :: %d%n", pairEnergySumCount);
-    	System.out.printf("\t\tPassed Energy Difference Cut :: %d%n", pairEnergyDifferenceCount);
-    	System.out.printf("\t\tPassed Energy Slope Cut      :: %d%n", pairEnergySlopeCount);
-    	System.out.printf("\t\tPassed Coplanarity Cut       :: %d%n", pairCoplanarityCount);
-    	System.out.printf("%n");
-    	System.out.printf("\tTrigger Count :: %d%n", numTriggers);
-    	
-    	// Run the superclass method.
+        // Print out the results of the trigger cuts.
+        System.out.printf("Trigger Processing Results%n");
+        System.out.printf("\tSingle-Cluster Cuts%n");
+        System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
+        System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
+        System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
+        System.out.printf("\t\tPassed Total Energy Cut      :: %d%n", clusterTotalEnergyCount);
+        System.out.printf("%n");
+        System.out.printf("\tCluster Pair Cuts%n");
+        System.out.printf("\t\tTotal Pairs Processed        :: %d%n", allPairs);
+        System.out.printf("\t\tPassed Energy Sum Cut        :: %d%n", pairEnergySumCount);
+        System.out.printf("\t\tPassed Energy Difference Cut :: %d%n", pairEnergyDifferenceCount);
+        System.out.printf("\t\tPassed Energy Slope Cut      :: %d%n", pairEnergySlopeCount);
+        System.out.printf("\t\tPassed Coplanarity Cut       :: %d%n", pairCoplanarityCount);
+        System.out.printf("%n");
+        System.out.printf("\tTrigger Count :: %d%n", numTriggers);
+        
+        // Run the superclass method.
         super.endOfData();
     }
     
@@ -126,81 +128,89 @@
      */
     @Override
     public void process(EventHeader event) {
-    	// Process the list of clusters for the event, if it exists.
+        // Process the list of clusters for the event, if it exists.
         if (event.hasCollection(HPSEcalCluster.class, clusterCollectionName)) {
-        	// Get the collection of clusters.
-        	List<HPSEcalCluster> clusterList = event.get(HPSEcalCluster.class, clusterCollectionName);
-        	
-        	// Create a list to hold clusters which pass the single
-        	// cluster cuts.
-        	List<HPSEcalCluster> goodClusterList = new ArrayList<HPSEcalCluster>(clusterList.size());
-        	
-        	// Sort through the cluster list and add clusters that pass
-        	// the single cluster cuts to the good list.
-        	clusterLoop:
-        	for(HPSEcalCluster cluster : clusterList) {
-        		// Increment the number of processed clusters.
-        		allClusters++;
-        		
-        		// Get the cluster plot values.
-        		int hitCount = cluster.getCalorimeterHits().size();
-        		double seedEnergy = cluster.getSeedHit().getCorrectedEnergy();
-        		double clusterEnergy = cluster.getEnergy();
-        		int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
-        		int iy = cluster.getSeedHit().getIdentifierFieldValue("iy");
-        		if(ix > 0) { ix = ix - 1; }
-        		
-        		// Fill the general plots.
-        		clusterSeedEnergy.fill(seedEnergy, 1);
-        		clusterTotalEnergy.fill(clusterEnergy, 1);
-        		clusterHitCount.fill(hitCount, 1);
-        		clusterDistribution.fill(ix, iy, 1);
-        		
-        		// Fill the "over 100 MeV" plots if applicable.
-        		if(seedEnergy >= 0.100) {
-            		clusterSeedEnergy100.fill(seedEnergy, 1);
-            		clusterTotalEnergy100.fill(clusterEnergy, 1);
-            		clusterHitCount100.fill(hitCount, 1);
-            		clusterDistribution100.fill(ix, iy, 1);
-        		}
-        		
-        		// ==== Seed Hit Energy Cut ====================================
-        		// =============================================================
-        		// If the cluster fails the cut, skip to the next cluster.
-        		if(!clusterSeedEnergyCut(cluster)) { continue clusterLoop; }
-        		
-        		// Otherwise, note that it passed the cut.
-        		clusterSeedEnergyCount++;
-        		
-        		// ==== Cluster Hit Count Cut ==================================
-        		// =============================================================
-        		// If the cluster fails the cut, skip to the next cluster.
-        		if(!clusterHitCountCut(cluster)) { continue clusterLoop; }
-        		
-        		// Otherwise, note that it passed the cut.
-        		clusterHitCountCount++;
-        		
-        		// ==== Cluster Total Energy Cut ===============================
-        		// =============================================================
-        		// If the cluster fails the cut, skip to the next cluster.
-        		if(!clusterTotalEnergyCut(cluster)) { continue clusterLoop; }
-        		
-        		// Otherwise, note that it passed the cut.
-        		clusterTotalEnergyCount++;
-        		
-        		// Fill the "passed single cuts" plots.
-        		clusterSeedEnergySingle.fill(seedEnergy, 1);
-        		clusterTotalEnergySingle.fill(clusterEnergy, 1);
-        		clusterHitCountSingle.fill(hitCount, 1);
-        		clusterDistributionSingle.fill(ix, iy, 1);
-        		
-        		// A cluster that passes all of the single-cluster cuts
-        		// can be used in cluster pairs.
-        		goodClusterList.add(cluster);
-        	}
-        	
-        	// Put the good clusters into the cluster queue.
-        	updateClusterQueues(goodClusterList);
+            // Get the collection of clusters.
+            List<HPSEcalCluster> clusterList = event.get(HPSEcalCluster.class, clusterCollectionName);
+            
+            // Create a list to hold clusters which pass the single
+            // cluster cuts.
+            List<HPSEcalCluster> goodClusterList = new ArrayList<HPSEcalCluster>(clusterList.size());
+            
+            // Sort through the cluster list and add clusters that pass
+            // the single cluster cuts to the good list.
+            clusterLoop:
+            for(HPSEcalCluster cluster : clusterList) {
+                // Increment the number of processed clusters.
+                allClusters++;
+                
+                // Get the cluster plot values.
+                int hitCount = cluster.getCalorimeterHits().size();
+                double seedEnergy = cluster.getSeedHit().getCorrectedEnergy();
+                double clusterEnergy = cluster.getEnergy();
+                int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
+                int iy = cluster.getSeedHit().getIdentifierFieldValue("iy");
+                
+                // If the cluster is in the "hot" region, write out its
+                // energy to a special plot.
+                if((iy == 1 || iy == -1) && (ix == -1 || ix == 1 || ix == 2)) {
+                    hotCrystalEnergy.fill(clusterEnergy, 1);
+                }
+                
+                // Correct for "hole" on the x-axis for plotting.
+                if(ix > 0) { ix = ix - 1; }
+                
+                // Fill the general plots.
+                clusterSeedEnergy.fill(seedEnergy, 1);
+                clusterTotalEnergy.fill(clusterEnergy, 1);
+                clusterHitCount.fill(hitCount, 1);
+                clusterDistribution.fill(ix, iy, 1);
+                
+                // Fill the "over 100 MeV" plots if applicable.
+                if(seedEnergy >= 0.100) {
+                    clusterSeedEnergy100.fill(seedEnergy, 1);
+                    clusterTotalEnergy100.fill(clusterEnergy, 1);
+                    clusterHitCount100.fill(hitCount, 1);
+                    clusterDistribution100.fill(ix, iy, 1);
+                }
+                
+                // ==== Seed Hit Energy Cut ====================================
+                // =============================================================
+                // If the cluster fails the cut, skip to the next cluster.
+                if(!clusterSeedEnergyCut(cluster)) { continue clusterLoop; }
+                
+                // Otherwise, note that it passed the cut.
+                clusterSeedEnergyCount++;
+                
+                // ==== Cluster Hit Count Cut ==================================
+                // =============================================================
+                // If the cluster fails the cut, skip to the next cluster.
+                if(!clusterHitCountCut(cluster)) { continue clusterLoop; }
+                
+                // Otherwise, note that it passed the cut.
+                clusterHitCountCount++;
+                
+                // ==== Cluster Total Energy Cut ===============================
+                // =============================================================
+                // If the cluster fails the cut, skip to the next cluster.
+                if(!clusterTotalEnergyCut(cluster)) { continue clusterLoop; }
+                
+                // Otherwise, note that it passed the cut.
+                clusterTotalEnergyCount++;
+                
+                // Fill the "passed single cuts" plots.
+                clusterSeedEnergySingle.fill(seedEnergy, 1);
+                clusterTotalEnergySingle.fill(clusterEnergy, 1);
+                clusterHitCountSingle.fill(hitCount, 1);
+                clusterDistributionSingle.fill(ix, iy, 1);
+                
+                // A cluster that passes all of the single-cluster cuts
+                // can be used in cluster pairs.
+                goodClusterList.add(cluster);
+            }
+            
+            // Put the good clusters into the cluster queue.
+            updateClusterQueues(goodClusterList);
         }
         
         // Perform the superclass event processing.
@@ -214,7 +224,7 @@
      * be set. Actual background rates equal about (5 * backgroundLevel) kHz.
      */
     public void setBackgroundLevel(int backgroundLevel) {
-    	this.backgroundLevel = backgroundLevel;
+        this.backgroundLevel = backgroundLevel;
     }
     
     /**
@@ -277,7 +287,7 @@
      * @param energySlopeLow - The parameter value.
      */
     public void setEnergySlopeLow(double energySlopeLow) {
-    	this.energySlopeLow = energySlopeLow;
+        this.energySlopeLow = energySlopeLow;
     }
     
     /**
@@ -361,12 +371,12 @@
      */
     @Override
     public void startOfData() {
-    	// Make sure that a valid cluster collection name has been
-    	// defined. If it has not, throw an exception.
+        // Make sure that a valid cluster collection name has been
+        // defined. If it has not, throw an exception.
         if (clusterCollectionName == null) {
             throw new RuntimeException("The parameter clusterCollectionName was not set!");
         }
-    	
+        
         // Initialize the top and bottom cluster queues.
         topClusterQueue = new LinkedList<List<HPSEcalCluster>>();
         botClusterQueue = new LinkedList<List<HPSEcalCluster>>();
@@ -407,9 +417,9 @@
         for (HPSEcalCluster botCluster : botClusterQueue.element()) {
             for (List<HPSEcalCluster> topClusters : topClusterQueue) {
                 for (HPSEcalCluster topCluster : topClusters) {
-                	// The first cluster in a pair should always be
-                	// the higher energy cluster. If the top cluster
-                	// is higher energy, it goes first.
+                    // The first cluster in a pair should always be
+                    // the higher energy cluster. If the top cluster
+                    // is higher energy, it goes first.
                     if (topCluster.getEnergy() > botCluster.getEnergy()) {
                         HPSEcalCluster[] clusterPair = {topCluster, botCluster};
                         clusterPairs.add(clusterPair);
@@ -428,24 +438,24 @@
         return clusterPairs;
     }
     
-	/**
-	 * Determines if the event produces a trigger.
-	 * 
-	 * @return Returns <code>true</code> if the event produces a trigger
-	 * and <code>false</code> if it does not.
-	 */
-	@Override
-	protected boolean triggerDecision(EventHeader event) {
-    	// If there is a list of clusters present for this event,
-    	// check whether it passes the trigger conditions.
-    	if (event.hasCollection(HPSEcalCluster.class, clusterCollectionName)) {
-        	return testTrigger();
+    /**
+     * Determines if the event produces a trigger.
+     * 
+     * @return Returns <code>true</code> if the event produces a trigger
+     * and <code>false</code> if it does not.
+     */
+    @Override
+    protected boolean triggerDecision(EventHeader event) {
+        // If there is a list of clusters present for this event,
+        // check whether it passes the trigger conditions.
+        if (event.hasCollection(HPSEcalCluster.class, clusterCollectionName)) {
+            return testTrigger();
         }
         
         // Otherwise, this event can not produce a trigger and should
         // return false automatically.
         else { return false; }
-	}
+    }
     
     /**
      * Checks whether the argument cluster possesses the minimum
@@ -456,7 +466,7 @@
      * and <code>false</code> if the cluster does not.
      */
     private boolean clusterHitCountCut(HPSEcalCluster cluster) {
-    	return (getValueClusterHitCount(cluster) >= minHitCount);
+        return (getValueClusterHitCount(cluster) >= minHitCount);
     }
     
     /**
@@ -468,12 +478,12 @@
      * and <code>false</code> if the cluster does not.
      */
     private boolean clusterSeedEnergyCut(HPSEcalCluster cluster) {
-    	// Get the cluster seed energy.
-    	double energy = getValueClusterSeedEnergy(cluster);
-    	
-    	// Check that it is above the minimum threshold and below the
-    	// maximum threshold.
-    	return (energy < seedEnergyHigh) && (energy > seedEnergyLow);
+        // Get the cluster seed energy.
+        double energy = getValueClusterSeedEnergy(cluster);
+        
+        // Check that it is above the minimum threshold and below the
+        // maximum threshold.
+        return (energy < seedEnergyHigh) && (energy > seedEnergyLow);
     }
     
     /**
@@ -485,12 +495,12 @@
      * and <code>false</code> if the cluster does not.
      */
     private boolean clusterTotalEnergyCut(HPSEcalCluster cluster) {
-    	// Get the total cluster energy.
-    	double energy = getValueClusterTotalEnergy(cluster);
-    	
-    	// Check that it is above the minimum threshold and below the
-    	// maximum threshold.
-    	return (energy < clusterEnergyHigh) && (energy > clusterEnergyLow);
+        // Get the total cluster energy.
+        double energy = getValueClusterTotalEnergy(cluster);
+        
+        // Check that it is above the minimum threshold and below the
+        // maximum threshold.
+        return (energy < clusterEnergyHigh) && (energy > clusterEnergyLow);
     }
     
     /**
@@ -512,7 +522,7 @@
      * @return Returns the cut value.
      */
     private double getValueClusterTotalEnergy(HPSEcalCluster cluster) {
-    	return cluster.getEnergy();
+        return cluster.getEnergy();
     }
     
     /**
@@ -523,7 +533,7 @@
      * @return Returns the cut value.
      */
     private int getValueClusterHitCount(HPSEcalCluster cluster) {
-    	return cluster.getCalorimeterHits().size();
+        return cluster.getCalorimeterHits().size();
     }
     
     /**
@@ -534,7 +544,7 @@
      * @return Returns the cut value.
      */
     private double getValueClusterSeedEnergy(HPSEcalCluster cluster) {
-    	return cluster.getSeedHit().getCorrectedEnergy();
+        return cluster.getSeedHit().getCorrectedEnergy();
     }
     
     /**
@@ -545,14 +555,14 @@
      * @return Returns the cut value.
      */
     private double getValueCoplanarity(HPSEcalCluster[] clusterPair) {
-    	// Get the cluster angles.
-    	double[] clusterAngle = new double[2];
-    	for(int i = 0; i < 2; i++) {
+        // Get the cluster angles.
+        double[] clusterAngle = new double[2];
+        for(int i = 0; i < 2; i++) {
             double position[] = clusterPair[i].getSeedHit().getPosition();
             clusterAngle[i] = (Math.toDegrees(Math.atan2(position[1], position[0] - originX)) + 180.0) % 180.0;
-    	}
-    	
-    	// Calculate the coplanarity cut value.
+        }
+        
+        // Calculate the coplanarity cut value.
         return Math.abs(clusterAngle[1] - clusterAngle[0]);
     }
     
@@ -564,7 +574,7 @@
      * @return Returns the cut value.
      */
     private double getValueEnergyDifference(HPSEcalCluster[] clusterPair) {
-    	return clusterPair[0].getEnergy() - clusterPair[1].getEnergy();
+        return clusterPair[0].getEnergy() - clusterPair[1].getEnergy();
     }
     
     /**
@@ -575,15 +585,15 @@
      * @return Returns the cut value.
      */
     private double getValueEnergySlope(HPSEcalCluster[] clusterPair) {
-    	// E + R*F
-    	// Get the low energy cluster energy.
-    	double slopeParamE = clusterPair[1].getEnergy();
-    	
-    	// Get the low energy cluster radial distance.
-    	double slopeParamR = getClusterDistance(clusterPair[1]);
-    	
-    	// Calculate the energy slope.
-    	return slopeParamE + slopeParamR * energySlopeParamF;
+        // E + R*F
+        // Get the low energy cluster energy.
+        double slopeParamE = clusterPair[1].getEnergy();
+        
+        // Get the low energy cluster radial distance.
+        double slopeParamR = getClusterDistance(clusterPair[1]);
+        
+        // Calculate the energy slope.
+        return slopeParamE + slopeParamR * energySlopeParamF;
     }
     
     /**
@@ -594,7 +604,7 @@
      * @return Returns the cut value.
      */
     private double getValueEnergySum(HPSEcalCluster[] clusterPair) {
-    	return clusterPair[0].getEnergy() + clusterPair[1].getEnergy();
+        return clusterPair[0].getEnergy() + clusterPair[1].getEnergy();
     }
     
     /**
@@ -630,7 +640,7 @@
      * @return true if pair is found, false otherwise
      */
     private boolean pairEnergySlopeCut(HPSEcalCluster[] clusterPair) {
-    	return (getValueEnergySlope(clusterPair) > energySlopeLow);
+        return (getValueEnergySlope(clusterPair) > energySlopeLow);
     }
     
     /**
@@ -642,216 +652,216 @@
      * the cut and <code>false</code> if it does not.
      */
     private boolean pairEnergySumCut(HPSEcalCluster[] clusterPair) {
-    	// Get the energy sum value.
-    	double energySum = getValueEnergySum(clusterPair);
-    	
-    	// Check that it is within the allowed range.
+        // Get the energy sum value.
+        double energySum = getValueEnergySum(clusterPair);
+        
+        // Check that it is within the allowed range.
         return (energySum < energySumHigh) && (energySum > energySumLow);
     }
-	
+    
     private void setBackgroundCuts(int backgroundLevel) {
-    	// Make sure that the background level is valid.
-    	if(backgroundLevel < 1 || backgroundLevel > 10) {
-    		throw new RuntimeException(String.format("Trigger cuts are undefined for background level %d.", backgroundLevel));
-    	}
-    	
-    	// Otherwise, set the trigger cuts. Certain cuts are constant
-    	// across all background levels.
-    	clusterEnergyLow = 0.000;
-    	seedEnergyLow = 0.100;
-    	
-    	// Set the variable values.
-    	if(backgroundLevel == 1) {
-    		clusterEnergyHigh = 1.700;
-    		seedEnergyHigh = 1.300;
-    		energySumLow = 0.400;
-    		energySumHigh = 2.00;
-    		energyDifferenceHigh = 1.500;
-    		energySlopeLow = 1.0;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 2) {
-    		clusterEnergyHigh = 1.600;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.300;
-    		energySumHigh = 2.00;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.8;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 3) {
-    		clusterEnergyHigh = 1.600;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.200;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.7;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 4) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.500;
-    		energySumHigh = 1.950;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 40;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 5) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.400;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 45;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 6) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.200;
-    		energySumHigh = 1.950;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 55;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 7) {
-    		clusterEnergyHigh = 1.700;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.200;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.500;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 60;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 8) {
-    		clusterEnergyHigh = 1.700;
-    		seedEnergyHigh = 1.300;
-    		energySumLow = 0.200;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.500;
-    		energySlopeLow = 0.6;
-    		coplanarityHigh = 65;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 9) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.400;
-    		energySumHigh = 1.950;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.5;
-    		coplanarityHigh = 60;
-    		minHitCount = 2;
-    	} else if(backgroundLevel == 10) {
-    		clusterEnergyHigh = 1.500;
-    		seedEnergyHigh = 1.200;
-    		energySumLow = 0.400;
-    		energySumHigh = 2.000;
-    		energyDifferenceHigh = 1.400;
-    		energySlopeLow = 0.5;
-    		coplanarityHigh = 65;
-    		minHitCount = 2;
-    	}
+        // Make sure that the background level is valid.
+        if(backgroundLevel < 1 || backgroundLevel > 10) {
+            throw new RuntimeException(String.format("Trigger cuts are undefined for background level %d.", backgroundLevel));
+        }
+        
+        // Otherwise, set the trigger cuts. Certain cuts are constant
+        // across all background levels.
+        clusterEnergyLow = 0.000;
+        seedEnergyLow = 0.100;
+        
+        // Set the variable values.
+        if(backgroundLevel == 1) {
+            clusterEnergyHigh = 1.700;
+            seedEnergyHigh = 1.300;
+            energySumLow = 0.400;
+            energySumHigh = 2.00;
+            energyDifferenceHigh = 1.500;
+            energySlopeLow = 1.0;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 2) {
+            clusterEnergyHigh = 1.600;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.300;
+            energySumHigh = 2.00;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.8;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 3) {
+            clusterEnergyHigh = 1.600;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.200;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.7;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 4) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.500;
+            energySumHigh = 1.950;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 40;
+            minHitCount = 2;
+        } else if(backgroundLevel == 5) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.400;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 45;
+            minHitCount = 2;
+        } else if(backgroundLevel == 6) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.200;
+            energySumHigh = 1.950;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 55;
+            minHitCount = 2;
+        } else if(backgroundLevel == 7) {
+            clusterEnergyHigh = 1.700;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.200;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.500;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 60;
+            minHitCount = 2;
+        } else if(backgroundLevel == 8) {
+            clusterEnergyHigh = 1.700;
+            seedEnergyHigh = 1.300;
+            energySumLow = 0.200;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.500;
+            energySlopeLow = 0.6;
+            coplanarityHigh = 65;
+            minHitCount = 2;
+        } else if(backgroundLevel == 9) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.400;
+            energySumHigh = 1.950;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.5;
+            coplanarityHigh = 60;
+            minHitCount = 2;
+        } else if(backgroundLevel == 10) {
+            clusterEnergyHigh = 1.500;
+            seedEnergyHigh = 1.200;
+            energySumLow = 0.400;
+            energySumHigh = 2.000;
+            energyDifferenceHigh = 1.400;
+            energySlopeLow = 0.5;
+            coplanarityHigh = 65;
+            minHitCount = 2;
+        }
     }
     
-	/**
-	 * Tests all of the current cluster pairs for triggers.
-	 * 
-	 * @return Returns <code>true</code> if one of the cluster pairs
-	 * passes all of the cluster cuts and <code>false</code> otherwise.
-	 */
+    /**
+     * Tests all of the current cluster pairs for triggers.
+     * 
+     * @return Returns <code>true</code> if one of the cluster pairs
+     * passes all of the cluster cuts and <code>false</code> otherwise.
+     */
     private boolean testTrigger() {
-    	// Get the list of cluster pairs.
-    	List<HPSEcalCluster[]> clusterPairs = getClusterPairsTopBot();
+        // Get the list of cluster pairs.
+        List<HPSEcalCluster[]> clusterPairs = getClusterPairsTopBot();
         
         // Iterate over the cluster pairs and perform each of the cluster
         // pair cuts on them. A cluster pair that passes all of the
         // cuts registers as a trigger.
-    	pairLoop:
+        pairLoop:
         for (HPSEcalCluster[] clusterPair : clusterPairs) {
-    		// Increment the number of processed cluster pairs.
-    		allPairs++;
-    		
-    		// Get the plot values for the pair cuts.
-    		double energySum = getValueEnergySum(clusterPair);
-    		double energyDifference = getValueEnergyDifference(clusterPair);
-    		double energySlope = getValueEnergySlope(clusterPair);
-    		double coplanarity = getValueCoplanarity(clusterPair);
-    		
-    		// Fill the general plots.
-    		pairEnergySum.fill(energySum, 1);
-    		pairEnergyDifference.fill(energyDifference, 1);
-    		pairEnergySlope.fill(energySlope, 1);
-    		pairCoplanarity.fill(coplanarity, 1);
-    		
-    		// ==== Pair Energy Sum Cut ====================================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		if(!pairEnergySumCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairEnergySumCount++;
-        	
-    		// ==== Pair Energy Difference Cut =============================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		if(!pairEnergyDifferenceCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairEnergyDifferenceCount++;
-    		
-    		// ==== Pair Energy Slope Cut ==================================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		//if(!energyDistanceCut(clusterPair)) { continue pairLoop; }
-    		if(!pairEnergySlopeCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairEnergySlopeCount++;
-    		
-    		// ==== Pair Coplanarity Cut ===================================
-    		// =============================================================
-    		// If the cluster fails the cut, skip to the next pair.
-    		if(!pairCoplanarityCut(clusterPair)) { continue pairLoop; }
-    		
-    		// Otherwise, note that it passed the cut.
-    		pairCoplanarityCount++;
-    		
-    		// Get the cluster plot values.
-    		int[] hitCount = new int[2];
-    		double[] seedEnergy = new double[2];
-    		double[] clusterEnergy = new double[2];
-    		int[] ix = new int[2];
-    		int[] iy = new int[2];
-    		for(int i = 0; i < 2; i++) {
-    			hitCount[i] = clusterPair[i].getCalorimeterHits().size();
-    			seedEnergy[i] = clusterPair[i].getSeedHit().getCorrectedEnergy();
-    			clusterEnergy[i] = clusterPair[i].getEnergy();
-    			ix[i] = clusterPair[i].getSeedHit().getIdentifierFieldValue("ix");
-    			iy[i] = clusterPair[i].getSeedHit().getIdentifierFieldValue("iy");
-    			if(ix[i] > 0) { ix[i] = ix[i] - 1; }
-    		}
-    		
-    		// Fill the general plots.
-    		for(int i = 0; i < 2; i++) {
-	    		clusterSeedEnergyAll.fill(seedEnergy[i], 1);
-	    		clusterTotalEnergyAll.fill(clusterEnergy[i], 1);
-	    		clusterHitCountAll.fill(hitCount[i], 1);
-	    		clusterDistributionAll.fill(ix[i], iy[i], 1);
-    		}
-    		
-    		// Fill the "passed all cuts" plots.
-    		pairEnergySumAll.fill(energySum, 1);
-    		pairEnergyDifferenceAll.fill(energyDifference, 1);
-    		pairEnergySlopeAll.fill(energySlope, 1);
-    		pairCoplanarityAll.fill(coplanarity, 1);
-    		
-    		// Clusters that pass all of the pair cuts produce a trigger.
-    		return true;
+            // Increment the number of processed cluster pairs.
+            allPairs++;
+            
+            // Get the plot values for the pair cuts.
+            double energySum = getValueEnergySum(clusterPair);
+            double energyDifference = getValueEnergyDifference(clusterPair);
+            double energySlope = getValueEnergySlope(clusterPair);
+            double coplanarity = getValueCoplanarity(clusterPair);
+            
+            // Fill the general plots.
+            pairEnergySum.fill(energySum, 1);
+            pairEnergyDifference.fill(energyDifference, 1);
+            pairEnergySlope.fill(energySlope, 1);
+            pairCoplanarity.fill(coplanarity, 1);
+            
+            // ==== Pair Energy Sum Cut ====================================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            if(!pairEnergySumCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairEnergySumCount++;
+            
+            // ==== Pair Energy Difference Cut =============================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            if(!pairEnergyDifferenceCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairEnergyDifferenceCount++;
+            
+            // ==== Pair Energy Slope Cut ==================================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            //if(!energyDistanceCut(clusterPair)) { continue pairLoop; }
+            if(!pairEnergySlopeCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairEnergySlopeCount++;
+            
+            // ==== Pair Coplanarity Cut ===================================
+            // =============================================================
+            // If the cluster fails the cut, skip to the next pair.
+            if(!pairCoplanarityCut(clusterPair)) { continue pairLoop; }
+            
+            // Otherwise, note that it passed the cut.
+            pairCoplanarityCount++;
+            
+            // Get the cluster plot values.
+            int[] hitCount = new int[2];
+            double[] seedEnergy = new double[2];
+            double[] clusterEnergy = new double[2];
+            int[] ix = new int[2];
+            int[] iy = new int[2];
+            for(int i = 0; i < 2; i++) {
+                hitCount[i] = clusterPair[i].getCalorimeterHits().size();
+                seedEnergy[i] = clusterPair[i].getSeedHit().getCorrectedEnergy();
+                clusterEnergy[i] = clusterPair[i].getEnergy();
+                ix[i] = clusterPair[i].getSeedHit().getIdentifierFieldValue("ix");
+                iy[i] = clusterPair[i].getSeedHit().getIdentifierFieldValue("iy");
+                if(ix[i] > 0) { ix[i] = ix[i] - 1; }
+            }
+            
+            // Fill the general plots.
+            for(int i = 0; i < 2; i++) {
+                clusterSeedEnergyAll.fill(seedEnergy[i], 1);
+                clusterTotalEnergyAll.fill(clusterEnergy[i], 1);
+                clusterHitCountAll.fill(hitCount[i], 1);
+                clusterDistributionAll.fill(ix[i], iy[i], 1);
+            }
+            
+            // Fill the "passed all cuts" plots.
+            pairEnergySumAll.fill(energySum, 1);
+            pairEnergyDifferenceAll.fill(energyDifference, 1);
+            pairEnergySlopeAll.fill(energySlope, 1);
+            pairCoplanarityAll.fill(coplanarity, 1);
+            
+            // Clusters that pass all of the pair cuts produce a trigger.
+            return true;
         }
         
         // If the loop terminates without producing a trigger, there
-    	// are no cluster pairs which meet the trigger conditions.
+        // are no cluster pairs which meet the trigger conditions.
         return false;
     }
     
@@ -862,14 +872,14 @@
      * @param clusterList - The clusters to add to the queues.
      */
     private void updateClusterQueues(List<HPSEcalCluster> clusterList) {
-    	// Create lists to store the top and bottom clusters.
+        // Create lists to store the top and bottom clusters.
         ArrayList<HPSEcalCluster> topClusterList = new ArrayList<HPSEcalCluster>();
         ArrayList<HPSEcalCluster> botClusterList = new ArrayList<HPSEcalCluster>();
         
         // Loop over the clusters in the cluster list.
         for (HPSEcalCluster cluster : clusterList) {
-        	// If the cluster is on the top of the calorimeter, it
-        	// goes into the top cluster list.
+            // If the cluster is on the top of the calorimeter, it
+            // goes into the top cluster list.
             if (cluster.getSeedHit().getIdentifierFieldValue("iy") > 0) {
                 topClusterList.add(cluster);
             }
@@ -886,4 +896,4 @@
         topClusterQueue.remove();
         botClusterQueue.remove();
     }
-}^M
+}
\ No newline at end of file

java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal
MollerTrigger.java added at 1148
--- java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTrigger.java	                        (rev 0)
+++ java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/MollerTrigger.java	2014-10-07 20:04:37 UTC (rev 1148)
@@ -0,0 +1,437 @@
+package org.hps.readout.ecal;
+
+import hep.aida.IHistogram1D;
+import hep.aida.IHistogram2D;
+
+import java.awt.Point;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hps.recon.ecal.HPSEcalCluster;
+import org.lcsim.event.EventHeader;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ * Class <code>MollerTrigger</code> simulates a Møller trigger. It
+ * executes four cuts, three of which are single cluster cuts and the
+ * last of which is a positional cut. The single cluster cuts are on
+ * the seed and total energies of the cluster and the energy of the seed
+ * hit of the cluster. The positional cut ignores clusters that occur
+ * outside of a high-activity region for Møller events and excludes the
+ * primary background high-activity region.
+ * <br/><br/>
+ * At each event, any extant clusters are examined one at a time. If
+ * a cluster passes all four of the cuts, a trigger is produced and
+ * the remaining clusters are ignored. If either no clusters are present
+ * or no clusters pass the trigger cuts, no trigger is produced.
+ * <br/><br/>
+ * All thresholds can be set through a steering file. The driver also
+ * supports a verbose mode where it will output more details with every
+ * event to help with diagnostics.
+ * 
+ * @author Kyle McCarty
+ */
+public class MollerTrigger extends TriggerDriver {
+    
+    // ==================================================================
+    // ==== Trigger Algorithms ==========================================
+    // ==================================================================    
+    
+    @Override
+    public void endOfData() {
+        // Print out the results of the trigger cuts.
+        System.out.printf("Trigger Processing Results%n");
+        System.out.printf("\tSingle-Cluster Cuts%n");
+        System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
+        System.out.printf("\t\tPassed Positional Cut        :: %d%n", clusterPositionCount);
+        System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
+        System.out.printf("\t\tPassed Total Energy Cut      :: %d%n", clusterTotalEnergyCount);
+        System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
+        System.out.printf("%n");
+        System.out.printf("\tTrigger Count :: %d%n", triggers);
+        
+        // Run the superclass method.
+        super.endOfData();
+    }
+    
+    @Override
+    public void process(EventHeader event) { super.process(event); }
+    
+    @Override
+    public void startOfData() {
+        // Initialize the cluster hit count diagnostic plots.
+        clusterHitCount = aida.histogram1D("Trigger Plots :: Cluster Hit Count Distribution", 9, 1, 10);
+        aClusterHitCount = aida.histogram1D("Trigger Plots :: Cluster Hit Count Distribution (Passed All Cuts)", 9, 1, 10);
+        
+        // Initialize the cluster total energy diagnostic plots.
+        clusterTotalEnergy = aida.histogram1D("Trigger Plots :: Cluster Total Energy Distribution", 176, 0.0, 2.2);
+        aClusterTotalEnergy = aida.histogram1D("Trigger Plots :: Cluster Total Energy Distribution (Passed All Cuts)", 176, 0.0, 2.2);
+        
+        // Initialize the cluster seed energy diagnostic plots.
+        clusterSeedEnergy = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution", 176, 0.0, 2.2);
+        aClusterSeedEnergy = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution (Passed All Cuts)", 176, 0.0, 2.2);
+        
+        // Initialize the seed distribution diagnostic plots.
+        clusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution", 46, -23, 23, 11, -5.5, 5.5);
+        aClusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed All Cuts)", 46, -23, 23, 11, -5.5, 5.5);
+        
+        // Initialize the seed percentage of cluster energy.
+        seedPercent = aida.histogram1D("Analysis Plots :: Seed Percentage of Total Energy", 400, 0.0, 1.0);
+        
+        // Add the allowed seed crystal positions to the seed set.
+        // y = +/- 1, x = -11 -> -15
+        for(int ix = -15; ix <= -11; ix++) {
+            allowedSeedSet.add(new Point(ix, -1));
+        } // y = +/- 2, x = -9 -> -15
+        for(int ix = -15; ix <= -9; ix++) {
+            allowedSeedSet.add(new Point(ix, -2));
+        }
+    }
+    
+    @Override
+    protected boolean triggerDecision(EventHeader event) {
+        // Check if there is a cluster collection. If not, there is no
+        // reason to continue; a trigger can not be produced if there
+        // are no clusters.
+        if(event.hasCollection(HPSEcalCluster.class, clusterCollectionName)) {
+            // VERBOSE :: Note that no cluster collection exists for
+            //            this event.
+            if(verbose) { System.out.println("No cluster collection is present for event."); }
+            
+            // Indicate that there is no trigger.
+            return false;
+        }
+        
+        // VERBOSE :: Note that a cluster collection exists for
+        //            this event.
+        if(verbose) { System.out.println("Cluster collection is present for event."); }
+        
+        // Get the cluster list from the event.
+        List<HPSEcalCluster> eventList = event.get(HPSEcalCluster.class, clusterCollectionName);
+        
+        // VERBOSE :: Output the number of extant clusters.
+        if(verbose) { System.out.printf("%d clusters in event.%n", eventList.size()); }
+        
+        // Add the clusters from the event into the cluster list
+        // if they pass the minimum total cluster energy and seed
+        // energy thresholds.
+        for(HPSEcalCluster cluster : eventList) {
+            // Increment the clusters processed count.
+            allClusters++;
+            
+            // Plot the seed energy / cluster energy histogram.
+            seedPercent.fill(cluster.getSeedHit().getCorrectedEnergy() / cluster.getEnergy(), 1);
+            
+            // Get the cluster position indices.
+            int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
+            int iy = cluster.getSeedHit().getIdentifierFieldValue("iy");
+            
+            // VERBOSE :: Output the current cluster's properties.
+            if(verbose) {
+                System.out.printf("\tTesting cluster at (%d, %d) with total energy %f and seed energy %f.%n",
+                        ix, iy, cluster.getSeedHit().getCorrectedEnergy(), cluster.getEnergy());
+            }
+            
+            // Add the clusters to the uncut histograms.
+            clusterHitCount.fill(cluster.getCalorimeterHits().size());
+            clusterTotalEnergy.fill(cluster.getEnergy());
+            clusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
+            clusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
+            
+            // VERBOSE :: Output the single cluster trigger thresholds.
+            if(verbose) {
+                System.out.printf("\tCluster seed energy threshold  :: [%f, %f]%n", clusterSeedEnergyThresholdLow, clusterSeedEnergyThresholdHigh);
+                System.out.printf("\tCluster total energy threshold :: %f%n%n", clusterTotalEnergyThresholdLow);
+            }
+            
+            // Perform the single cluster cuts.
+            boolean totalEnergyCut = clusterTotalEnergyCut(cluster);
+            boolean seedEnergyCut = clusterSeedEnergyCut(cluster);
+            boolean hitCountCut = clusterHitCountCut(cluster);
+            boolean positionCut = clusterPositionCut(cluster);
+            
+            // Increment the single cut counts.
+            if(positionCut) {
+                clusterPositionCount++;
+                if(seedEnergyCut) {
+                    clusterSeedEnergyCount++;
+                    if(totalEnergyCut) {
+                        clusterTotalEnergyCount++;
+                        if(hitCountCut) {
+                            clusterHitCountCount++;
+                        }
+                    }
+                }
+            }
+            
+            // VERBOSE :: Note whether the cluster passed the single
+            //            cluster cuts.
+            if(verbose) {
+                System.out.printf("\tPassed seed energy cut    :: %b%n", seedEnergyCut);
+                System.out.printf("\tPassed cluster energy cut :: %b%n", totalEnergyCut);
+                System.out.printf("\tPassed hit count cut      :: %b%n", hitCountCut);
+                System.out.printf("\tWithin allowed region     :: %b%n%n", positionCut);
+            }
+            
+            // Require that the cluster pass each of the cuts in
+            // order to qualify for a trigger.
+            if(totalEnergyCut && seedEnergyCut && hitCountCut && positionCut) {
+                // Add the clusters to the cut histograms.
+                aClusterHitCount.fill(cluster.getCalorimeterHits().size());
+                aClusterTotalEnergy.fill(cluster.getEnergy());
+                aClusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
+                aClusterDistribution.fill(ix > 0 ? ix - 1 : ix, iy, 1);
+                
+                // VERBOSE :: Indicate that a trigger occurred.
+                if(verbose) { System.out.printf("\tTriggered!%n%n"); }
+                
+                // Return a trigger.
+                return true;
+            }
+        }
+        
+        // VERBOSE :: Note that the event has failed to trigger.
+        if(verbose) { System.out.println("No trigger.\n\n"); }
+        
+        // If one or more of the pair cuts failed, the we do not trigger.
+        return false;
+    }
+    
+    // ==================================================================
+    // ==== Trigger Cut Methods =========================================
+    // ==================================================================
+    
+    /**
+     * Checks whether the cluster passes the threshold for minimum
+     * number of component hits.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster passes and <code>
+     * false</code> if it does not.
+     */
+    private boolean clusterHitCountCut(HPSEcalCluster cluster) {
+        return cluster.getCalorimeterHits().size() >= clusterHitCountThreshold;
+    }
+    
+    /**
+     * Checks whether the cluster falls within the allowed range for
+     * the seed hit energy cut.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster passes and <code>
+     * false</code> if it does not.
+     */
+    private boolean clusterSeedEnergyCut(HPSEcalCluster cluster) {
+        // Get the seed energy value.
+        double seedEnergy = cluster.getSeedHit().getCorrectedEnergy();
+        
+        // Perform the seed energy cut.
+        return seedEnergy >= clusterSeedEnergyThresholdLow && seedEnergy <= clusterSeedEnergyThresholdHigh;
+    }
+    
+    /**
+     * Checks whether the cluster passes the threshold for minimum
+     * total cluster energy.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster passes and <code>
+     * false</code> if it does not.
+     */
+    private boolean clusterTotalEnergyCut(HPSEcalCluster cluster) {
+        // Get the cluster energy.
+        double clusterEnergy = cluster.getEnergy();
+        
+        // Perform the cut.
+        return clusterEnergy >= clusterTotalEnergyThresholdLow && clusterEnergy <= clusterTotalEnergyThresholdHigh;
+    }
+    
+    /**
+     * Checks whether the cluster falls into the accepted region on
+     * the calorimeter face.
+     * @param cluster - The cluster to check.
+     * @return Returns <code>true</code> if the cluster passes and <code>
+     * false</code> if it does not.
+     */
+    private boolean clusterPositionCut(HPSEcalCluster cluster) {
+        // Get the cluster position.
+        Point seedLoc =  new Point(cluster.getSeedHit().getIdentifierFieldValue("ix"),
+                cluster.getSeedHit().getIdentifierFieldValue("iy"));
+        
+        // Check if it is one of the allowed seed crystals.
+        return allowedSeedSet.contains(seedLoc);
+    }
+    
+    // ==================================================================
+    // ==== Variables Mutator Methods ===================================
+    // ==================================================================
+    
+    /**
+     * Sets the LCIO collection name where <code>HPSEcalCluster</code>
+     * objects are stored for use in the trigger.
+     * @param clusterCollectionName - The name of the LCIO collection.
+     */
+    public void setClusterCollectionName(String clusterCollectionName) {
+        this.clusterCollectionName = clusterCollectionName;
+    }
+    
+    /**
+     * Sets the minimum number of hits required for a cluster to be
+     * used in triggering.
+     * @param clusterHitCountThreshold - The smallest number of hits
+     * in a cluster.
+     */
+    public void setClusterHitCountThreshold(int clusterHitCountThreshold) {
+        this.clusterHitCountThreshold = clusterHitCountThreshold;
+    }
+    
+    /**
+     * Sets the threshold for the cluster seed energy of individual
+     * clusters above which the cluster will be rejected and not used
+     * for triggering.
+     * @param clusterSeedEnergyThresholdHigh - The cluster seed energy
+     * lower bound.
+     */
+    public void setClusterSeedEnergyThresholdHigh(double clusterSeedEnergyThresholdHigh) {
+        this.clusterSeedEnergyThresholdHigh = clusterSeedEnergyThresholdHigh;
+    }
+    
+    /**
+     * Sets the threshold for the cluster seed energy of individual
+     * clusters under which the cluster will be rejected and not used
+     * for triggering.
+     * @param clusterSeedEnergyThresholdLow - The cluster seed energy
+     * lower bound.
+     */
+    public void setClusterSeedEnergyThresholdLow(double clusterSeedEnergyThresholdLow) {
+        this.clusterSeedEnergyThresholdLow = clusterSeedEnergyThresholdLow;
+    }
+    
+    /**
+     * Sets the threshold for the total cluster energy of individual
+     * clusters under which the cluster will be rejected and not used
+     * for triggering.
+     * @param clusterTotalEnergyThresholdLow - The cluster total energy
+     * lower bound.
+     */
+    public void setClusterTotalEnergyThresholdLow(double clusterTotalEnergyThresholdLow) {
+        this.clusterTotalEnergyThresholdLow = clusterTotalEnergyThresholdLow;
+    }
+    
+    /**
+     * Sets the threshold for the total cluster energy of individual
+     * clusters above which the cluster will be rejected and not used
+     * for triggering.
+     * @param clusterTotalEnergyThresholdHigh - The cluster total energy
+     * upper bound.
+     */
+    public void setClusterTotalEnergyThresholdHigh(double clusterTotalEnergyThresholdHigh) {
+        this.clusterTotalEnergyThresholdHigh = clusterTotalEnergyThresholdHigh;
+    }
+    
+    /**
+     * Toggles whether the driver will output its actions to the console
+     * during run time or not.
+     * @param verbose - <code>true</code> indicates that the console
+     * will write its actions and <code>false</code> that it will not.
+     */
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+    
+    // ==================================================================
+    // ==== AIDA Plots ==================================================
+    // ==================================================================
+    IHistogram2D aClusterDistribution;
+    IHistogram1D aClusterHitCount;
+    IHistogram1D aClusterSeedEnergy;
+    IHistogram1D aClusterTotalEnergy;
+    IHistogram2D clusterDistribution;
+    IHistogram1D clusterHitCount;
+    IHistogram1D clusterSeedEnergy;
+    IHistogram1D clusterTotalEnergy;
+    IHistogram1D pClusterHitCount;
+    IHistogram2D pClusterDistribution;
+    IHistogram1D pClusterSeedEnergy;
+    IHistogram1D pClusterTotalEnergy;
+    IHistogram1D seedPercent;
+    
+    // ==================================================================
+    // ==== Variables ===================================================
+    // ==================================================================
+    
+    /**
+     * <b>aida</b><br/><br/>
+     * <code>private AIDA <b>aida</b></code><br/><br/>
+     * Factory for generating histograms.
+     */
+    private AIDA aida = AIDA.defaultInstance();
+    
+    /**
+     * <b>allowedSeedSet</b><br/><br/>
+     * <code>private Set<Point> <b>allowedSeedSet</b></code><br/><br/>
+     * Contains all allowed seed crystal indices. Seeds outside of this
+     * set will be rejected and not produce a trigger.
+     */
+    private Set<Point> allowedSeedSet = new HashSet<Point>();
+    
+    /**
+     * <b>clusterCollectionName</b><br/><br/>
+     * <code>private String <b>clusterCollectionName</b></code><br/><br/>
+     * The name of the LCIO collection containing <code>HPSEcalCluster
+     * </code> objects.
+     */
+    private String clusterCollectionName = "EcalClusters";
+    
+    /**
+     * <b>clusterHitCountThreshold</b><br/><br/>
+     * <code>private int <b>clusterHitCountThreshold</b></code><br/><br/>
+     * Defines the minimum number of hits required for a cluster to
+     * be used in triggering.
+     */
+    private int clusterHitCountThreshold = 0;
+    
+    /**
+     * <b>clusterSeedEnergyThresholdLow</b><br/><br/>
+     * <code>private double <b>clusterSeedEnergyThresholdLow</b></code><br/><br/>
+     * Defines the threshold for the cluster seed energy under which
+     * a cluster will be rejected.
+     */
+    private double clusterSeedEnergyThresholdLow = 0.00;
+    
+    /**
+     * <b>clusterSeedEnergyThresholdHigh</b><br/><br/>
+     * <code>private double <b>clusterSeedEnergyThresholdHigh</b></code><br/><br/>
+     * Defines the threshold for the cluster seed energy above which
+     * a cluster will be rejected.
+     */
+    private double clusterSeedEnergyThresholdHigh = Double.MAX_VALUE;
+    
+    /**
+     * <b>clusterTotalEnergyThresholdLow</b><br/><br/>
+     * <code>private double <b>clusterTotalEnergyThreshold</b></code><br/><br/>
+     * Defines the threshold for the total cluster energy under which
+     * a cluster will be rejected.
+     */
+    private double clusterTotalEnergyThresholdLow = 0.0;
+    
+    /**
+     * <b>clusterTotalEnergyThresholdHigh</b><br/><br/>
+     * <code>private double <b>clusterTotalEnergyThresholdHigh</b></code><br/><br/>
+     * Defines the threshold for the total cluster energy above which
+     * a cluster will be rejected.
+     */
+    private double clusterTotalEnergyThresholdHigh = Double.MAX_VALUE;
+    
+    /**
+     * <b>verbose</b><br/><br/>
+     * <code>private boolean <b>verbose</b></code><br/><br/>
+     * Sets whether the driver outputs its clustering decisions to the
+     * console or not.
+     */
+    private boolean verbose = false;
+    
+    private int triggers = 0;                                      // Track the number of triggers.
+    private int allClusters = 0;                                   // Track the number of clusters processed.
+    private int clusterSeedEnergyCount = 0;                        // Track the clusters which pass the seed energy cut.
+    private int clusterHitCountCount = 0;                          // Track the clusters which pass the hit count cut.
+    private int clusterTotalEnergyCount = 0;                       // Track the clusters which pass the total energy cut.
+    private int clusterPositionCount = 0;                          // Track the clusters which pass the positional cut.
+}
\ No newline at end of file

java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal
NeutralPionTriggerDriver.java 1147 -> 1148
--- java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/NeutralPionTriggerDriver.java	2014-10-07 08:18:48 UTC (rev 1147)
+++ java/trunk/ecal-readout-sim/src/main/java/org/hps/readout/ecal/NeutralPionTriggerDriver.java	2014-10-07 20:04:37 UTC (rev 1148)
@@ -48,1034 +48,1034 @@
  * @author Michel Garçon
  */
 public class NeutralPionTriggerDriver extends TriggerDriver {
-	
-	// ==================================================================
-	// ==== Trigger Algorithms ==========================================
-	// ==================================================================	
-	
+    
+    // ==================================================================
+    // ==== Trigger Algorithms ==========================================
+    // ==================================================================    
+    
     @Override
     public void endOfData() {
-    	// Print out the results of the trigger cuts.
-    	System.out.printf("Trigger Processing Results%n");
-    	System.out.printf("\tSingle-Cluster Cuts%n");
-    	System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
-    	System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
-    	System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
-    	if(rejectEdgeCrystals) {
-    		System.out.printf("\t\tPassed Edge Crystal Cut      :: %d%n", clusterEdgeCount);
-    	}
-    	System.out.printf("%n");
-    	System.out.printf("\tCluster Pair Cuts%n");
-    	System.out.printf("\t\tTotal Pairs Processed        :: %d%n", allPairs);
-    	System.out.printf("\t\tPassed Energy Sum Cut        :: %d%n", pairEnergySumCount);
-    	System.out.printf("\t\tPassed Energy Invariant Mass :: %d%n", pairInvariantMassCount);
-    	System.out.printf("%n");
-    	System.out.printf("\tTrigger Count :: %d%n", triggers);
-    	
-    	// Run the superclass method.
+        // Print out the results of the trigger cuts.
+        System.out.printf("Trigger Processing Results%n");
+        System.out.printf("\tSingle-Cluster Cuts%n");
+        System.out.printf("\t\tTotal Clusters Processed     :: %d%n", allClusters);
+        System.out.printf("\t\tPassed Seed Energy Cut       :: %d%n", clusterSeedEnergyCount);
+        System.out.printf("\t\tPassed Hit Count Cut         :: %d%n", clusterHitCountCount);
+        if(rejectEdgeCrystals) {
+            System.out.printf("\t\tPassed Edge Crystal Cut      :: %d%n", clusterEdgeCount);
+        }
+        System.out.printf("%n");
+        System.out.printf("\tCluster Pair Cuts%n");
+        System.out.printf("\t\tTotal Pairs Processed        :: %d%n", allPairs);
+        System.out.printf("\t\tPassed Energy Sum Cut        :: %d%n", pairEnergySumCount);
+        System.out.printf("\t\tPassed Energy Invariant Mass :: %d%n", pairInvariantMassCount);
+        System.out.printf("%n");
+        System.out.printf("\tTrigger Count :: %d%n", triggers);
+        
+        // Run the superclass method.
         super.endOfData();
     }
-	
-	public void process(EventHeader event) {
-		// Generate a temporary list to store the good clusters
-		// in before they are added to the buffer.
-		List<HPSEcalCluster> tempList = new ArrayList<HPSEcalCluster>();
-		
-		// If the current event has a cluster collection, get it.
-		if(event.hasCollection(HPSEcalCluster.class, clusterCollectionName)) {
-			// VERBOSE :: Note that a cluster collection exists for
-			//            this event.
-			if(verbose) { System.out.println("Cluster collection is present for event."); }
-			
-			// Get the cluster list from the event.
-			List<HPSEcalCluster> eventList = event.get(HPSEcalCluster.class, clusterCollectionName);
-			
-			// VERBOSE :: Output the number of extant clusters.
-			if(verbose) { System.out.printf("%d clusters in event.%n", eventList.size()); }
-			
-			// Add the clusters from the event into the cluster list
-			// if they pass the minimum total cluster energy and seed
-			// energy thresholds.
-			for(HPSEcalCluster cluster : eventList) {
-				// Increment the clusters processed count.
-				allClusters++;
-				
-				// Plot the seed energy / cluster energy histogram.
-				seedPercent.fill(cluster.getSeedHit().getCorrectedEnergy() / cluster.getEnergy(), 1);
-				
-				// Get the cluster position indices.
-				int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
-				int iy = cluster.getSeedHit().getIdentifierFieldValue("iy");
-				
-				// VERBOSE :: Output the current cluster's properties.
-				if(verbose) {
-					System.out.printf("\tTesting cluster at (%d, %d) with total energy %f and seed energy %f.%n",
-							ix, iy, cluster.getSeedHit().getCorrectedEnergy(), cluster.getEnergy());
-				}
-				
-				// Add the clusters to the uncut histograms.
-				clusterHitCount.fill(cluster.getCalorimeterHits().size());
-				clusterTotalEnergy.fill(cluster.getEnergy());
-				clusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
-				clusterDistribution.fill(ix, iy, 1);
-				
-				// VERBOSE :: Output the single cluster trigger thresholds.
-				if(verbose) {
-					System.out.printf("\tCluster seed energy threshold  :: [%f, %f]%n", clusterSeedEnergyThresholdLow, clusterSeedEnergyThresholdHigh);
-					System.out.printf("\tCluster total energy threshold :: %f%n%n", clusterTotalEnergyThresholdLow);
-				}
-				
-				// Perform the single cluster cuts.
-				boolean totalEnergyCut = clusterTotalEnergyCut(cluster);
-				boolean seedEnergyCut = clusterSeedEnergyCut(cluster);
-				boolean hitCountCut = clusterHitCountCut(cluster);
-				boolean edgeCrystalCut = isEdgeCluster(cluster);
-				
-				// Increment the single cut counts.
-				if(seedEnergyCut) {
-					clusterSeedEnergyCount++;
-					if(hitCountCut) {
-						clusterHitCountCount++;
-						if(rejectEdgeCrystals && edgeCrystalCut) {
-							clusterEdgeCount++;
-						}
-					}
-				}
-				
-				// VERBOSE :: Note whether the cluster passed the single
-				//            cluster cuts.
-				if(verbose) {
-					System.out.printf("\tPassed seed energy cut    :: %b%n", seedEnergyCut);
-					System.out.printf("\tPassed cluster energy cut :: %b%n%n", totalEnergyCut);
-					System.out.printf("\tPassed hit count cut :: %b%n%n", hitCountCut);
-					System.out.printf("\tIs an edge cluster :: %b%n%n", edgeCrystalCut);
-				}
-				
-				// Determine whether the cluster passes all the single
-				// cluster cuts.
-				boolean passedCuts = false;
-				
-				// If edge crystals should be not be used for triggering,
-				// require that the cluster not be centered in an edge
-				// crystal.
-				if(rejectEdgeCrystals) {
-					if(totalEnergyCut && seedEnergyCut && hitCountCut && !edgeCrystalCut) {
-						passedCuts = true;
-					}
-				}
-				
-				// Otherwise, it just needs to pass the standard trigger
-				// cuts regardless of where it is located.
-				else {
-					if(totalEnergyCut && seedEnergyCut && hitCountCut) {
-						passedCuts = true;
-					}
-				}
-				
-				// If both pass, add the cluster to the list.
-				if(passedCuts) {
-					// Add the cluster to the cluster list.
-					tempList.add(cluster);
-					
-					// Add the cluster information to the single cut histograms.
-					pClusterHitCount.fill(cluster.getCalorimeterHits().size());
-					pClusterTotalEnergy.fill(cluster.getEnergy());
-					pClusterSeedEnergy.fill(cluster.getSeedHit().getCorrectedEnergy());
-					pClusterDistribution.fill(ix, iy, 1);
-				}
-			}
-			
-			// Remove the oldest cluster buffer element and add the new
-			// cluster list to the buffer.
-			clusterBuffer.removeFirst();
-			clusterBuffer.addLast(tempList);
-		}
-		
-		// Otherwise, clear the cluster list.
-		else {
-			// VERBOSE :: Note that the event has no clusters.
-			if(verbose) { System.out.println("No cluster collection is present for event.\n"); }
-		}
-		
-		// Reset the highest energy pair to null.
-		clusterTriplet[0] = null;
-		clusterTriplet[1] = null;
-		clusterTriplet[2] = null;
-		
-		// Loop over all of the cluster lists in the cluster buffer.
-		double[] energy = { 0.0, 0.0, 0.0 };
-		for(List<HPSEcalCluster> bufferList : clusterBuffer) {
-			// Loop over all of the clusters in each buffer list.
-			for(HPSEcalCluster cluster : bufferList) {
-				// If the new cluster is higher energy than the first
-				// slot cluster, move the subsequent clusters down and
-				// insert the new one.
-				if(cluster.getEnergy() > energy[0]) {
-					clusterTriplet[2] = clusterTriplet[1];
-					clusterTriplet[1] = clusterTriplet[0];
-					clusterTriplet[0] = cluster;
-					energy[2] = energy[1];
-					energy[1] = energy[0];
-					energy[0] = cluster.getEnergy();
-				}
-				
-				// Otherwise, if the new cluster has more energy than
-				// the second slot, it goes there and the second does
-				// to the third.
-				else if(cluster.getEnergy() > energy[1]) {
-					clusterTriplet[2] = clusterTriplet[1];
-					clusterTriplet[1] = cluster;
-					energy[2] = energy[1];
-					energy[1] = cluster.getEnergy();
-				}
-				
-				// If the new cluster has more energy than the third
-				// cluster, it just replaces it.
-				else if(cluster.getEnergy() > energy[2]) {
-					clusterTriplet[2] = cluster;
-					energy[2] = cluster.getEnergy();
-				}
-			}
-		}
-		
-		// The highest energy pair is the same as the first two slots
-		// of the highest energy triplet.
-		clusterPair[0] = clusterTriplet[0];
-		clusterPair[1] = clusterTriplet[1];
-		
-		// Run the superclass event process.
-		super.process(event);
-	}
-	
-	public void startOfData() {
-		// Initialize the cluster buffer to the size of the coincidence window.
-		clusterBuffer = new LinkedList<List<HPSEcalCluster>>();
-		
-		// Populate the buffer with empty lists.
-		for(int i = 0; i < coincidenceWindow; i++) {
-			clusterBuffer.add(new ArrayList<HPSEcalCluster>(0));
-		}
-		
-		// Initialize the cluster hit count diagnostic plots.
-		clusterHitCount = aida.histogram1D("Trigger Plots :: Cluster Hit Count Distribution", 9, 1, 10);
-		pClusterHitCount = aida.histogram1D("Trigger Plots :: Cluster Hit Count Distribution (Passed Single Cuts)", 9, 1, 10);
-		aClusterHitCount = aida.histogram1D("Trigger Plots :: Cluster Hit Count Distribution (Passed All Cuts)", 9, 1, 10);
-		
-		// Initialize the cluster total energy diagnostic plots.
-		clusterTotalEnergy = aida.histogram1D("Trigger Plots :: Cluster Total Energy Distribution", 176, 0.0, 2.2);
-		pClusterTotalEnergy = aida.histogram1D("Trigger Plots :: Cluster Total Energy Distribution (Passed Single Cuts)", 176, 0.0, 2.2);
-		aClusterTotalEnergy = aida.histogram1D("Trigger Plots :: Cluster Total Energy Distribution (Passed All Cuts)", 176, 0.0, 2.2);
-		
-		// Initialize the cluster seed energy diagnostic plots.
-		clusterSeedEnergy = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution", 176, 0.0, 2.2);
-		pClusterSeedEnergy = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution (Passed Single Cuts)", 176, 0.0, 2.2);
-		aClusterSeedEnergy = aida.histogram1D("Trigger Plots :: Cluster Seed Energy Distribution (Passed All Cuts)", 176, 0.0, 2.2);
-		
-		// Initialize the seed distribution diagnostic plots.
-		clusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution", 44, -22.0, 22.0, 10, -5, 5);
-		pClusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed Single Cuts)", 44, -23, 23, 11, -5.5, 5.5);
-		aClusterDistribution = aida.histogram2D("Trigger Plots :: Cluster Seed Distribution (Passed All Cuts)", 44, -23, 23, 11, -5.5, 5.5);
-		
-		// Initialize the cluster pair energy sum diagnostic plots.
-		pairEnergySum = aida.histogram1D("Trigger Plots :: Pair Energy Sum Distribution", 176, 0.0, 2.2);
-		pPairEnergySum = aida.histogram1D("Trigger Plots :: Pair Energy Sum Distribution (Passed Pair Cuts)", 176, 0.0, 2.2);
-		
-		// Initialize the cluster pair hypothetical invariant mass diagnostic plots.
-		invariantMass = aida.histogram1D("Trigger Plots :: Invariant Mass Distribution", 1500, 0.0, 0.03);
-		pInvariantMass = aida.histogram1D("Trigger Plots :: Invariant Mass Distribution (Passed Pair Cuts)", 1500, 0.0, 0.03);
-		
-		// Initialize the seed percentage of cluster energy.
-		seedPercent = aida.histogram1D("Analysis Plots :: Seed Percentage of Total Energy", 400, 0.0, 1.0);
-	}
-	
-	protected boolean triggerDecision(EventHeader event) {
-		// If the active cluster pair has a null value, then there were
-		// fewer than two clusters in the buffer and we can not trigger.
-		if(!useClusterTriplet && (clusterPair[0] == null || clusterPair[1] == null)) {
-			// VERBOSE :: Note that triggering failed due to insufficient
-			// clusters. in the cluster buffer.
-			if(verbose) { System.out.println("Inufficient clusters in buffer -- no trigger."); }
-			
-			// Return false; we can not trigger without two clusters.
-			return false;
-		}
-		
-		// If the active cluster triplet has a null value, then there
-		// were fewer than three clusters in the buffer and we can not
-		// trigger.
-		if(useClusterTriplet && (clusterTriplet[0] == null || clusterTriplet[1] == null || clusterTriplet[2] == null)) {
-			// VERBOSE :: Note that triggering failed due to insufficient
-			// clusters. in the cluster buffer.
-			if(verbose) { System.out.println("Inufficient clusters in buffer -- no trigger."); }
-			
-			// Return false; we can not trigger without three clusters.
-			return false;
-		}
-		
-		// Increment the number of pairs considered.
-		allPairs++;
-		
-		// Get the cluster position indices.
-		int[] ix = { clusterPair[0].getSeedHit().getIdentifierFieldValue("ix"), clusterPair[1].getSeedHit().getIdentifierFieldValue("ix") };
-		int[] iy = { clusterPair[0].getSeedHit().getIdentifierFieldValue("iy"), clusterPair[1].getSeedHit().getIdentifierFieldValue("iy") };
-		
-		// VERBOSE :: Output the clusters selected for triggering.
-		if(verbose) {
-			System.out.printf("\tTesting first cluster at (%d, %d) with total energy %f and seed energy %f.%n",
-					ix[0], iy[0], clusterPair[0].getSeedHit().getCorrectedEnergy(), clusterPair[0].getEnergy());
-			System.out.printf("\tTesting second cluster at (%d, %d) with total energy %f and seed energy %f.%n",
-					ix[1], iy[1], clusterPair[1].getSeedHit().getCorrectedEnergy(), clusterPair[1].getEnergy());
-			if(useClusterTriplet) {
-				System.out.printf("\tTesting third cluster at (%d, %d) with total energy %f and seed energy %f.%n",
-						ix[1], iy[1], clusterTriplet[2].getSeedHit().getCorrectedEnergy(), clusterTriplet[2].getEnergy());
-			}
-		}
-		
-		if(!useClusterTriplet) {
-			// Fill the uncut histograms.
-			pairEnergySum.fill(getEnergySumValue(clusterPair));
-			invariantMass.fill(getInvariantMassValue(clusterPair));
-			
-			// VERBOSE :: Output the cluster pair trigger thresholds.
-			if(verbose) {
-				System.out.printf("\tCluster pair energy sum threshold     :: %f%n", pairEnergySumThresholdLow);
-				System.out.printf("\tHypothetical invariant mass threshold :: [%f, %f]%n%n", invariantMassThresholdLow, invariantMassThresholdHigh);
-			}
-			
-			// Perform the cluster pair checks.
-			boolean energySumCut = pairEnergySumCut(clusterPair);
-			boolean invariantMassCut = pairInvariantMassCut(clusterPair);
-			
-			// Increment the pair cut counts.
-			if(energySumCut) {
-				pairEnergySumCount++;
-				if(invariantMassCut) {
-					pairInvariantMassCount++;
-				}
-			}
-			
-			// VERBOSE :: Note the outcome of the trigger cuts.
-			if(verbose) {
-				System.out.printf("\tPassed energy sum cut     :: %b%n", energySumCut);
-				System.out.printf("\tPassed invariant mass cut :: %b%n%n", invariantMassCut);
-			}
-			
-			// If the pair passes both cuts, we have a trigger.
-			if(energySumCut && invariantMassCut) {
-				// Fill the cut histograms.
-				pPairEnergySum.fill(getEnergySumValue(clusterPair));
-				pInvariantMass.fill(getInvariantMassValue(clusterPair));
-				
-				// Fill the all cuts histograms.
-				aClusterHitCount.fill(clusterPair[0].getCalorimeterHits().size());
-				aClusterHitCount.fill(clusterPair[1].getCalorimeterHits().size());
-				aClusterTotalEnergy.fill(clusterPair[0].getEnergy());
-				aClusterTotalEnergy.fill(clusterPair[1].getEnergy());
-				aClusterSeedEnergy.fill(clusterPair[0].getSeedHit().getCorrectedEnergy());
-				aClusterSeedEnergy.fill(clusterPair[1].getSeedHit().getCorrectedEnergy());
-				aClusterDistribution.fill(ix[0], iy[0], 1);
-				aClusterDistribution.fill(ix[1], iy[1], 1);
-				
-				// VERBOSE :: Note that the event has triggered.
-				if(verbose) { System.out.println("Event triggers!\n\n"); }
-				
-				// Increment the number of triggers.
-				triggers++;
-				
-				// Return the trigger.
-				return true;
-			}
-		}
-		
-		// If we are using a cluster triplet, apply the cluster triplet
-		// cuts.
-		else {
-			// Perform the cluster triplet checks.
-			boolean energySumCut = tripletEnergySumCut(clusterTriplet);
-			boolean horizontalCut = tripletHorizontalCut(clusterTriplet);
-			boolean energySpatialCut = tripletTotalEnergyCut(clusterTriplet);
-			
-			// Fill the all cuts histograms.
-			aClusterHitCount.fill(clusterPair[0].getCalorimeterHits().size());
-			aClusterHitCount.fill(clusterPair[1].getCalorimeterHits().size());
-			aClusterTotalEnergy.fill(clusterPair[0].getEnergy());
-			aClusterTotalEnergy.fill(clusterPair[1].getEnergy());
-			aClusterSeedEnergy.fill(clusterPair[0].getSeedHit().getCorrectedEnergy());
-			aClusterSeedEnergy.fill(clusterPair[1].getSeedHit().getCorrectedEnergy());
-			aClusterDistribution.fill(ix[0], iy[0], 1);
-			aClusterDistribution.fill(ix[1], iy[1], 1);
-			
-			if(energySumCut && horizontalCut && energySpatialCut) {
-				return true;
-			}
-		}
-		
-		// VERBOSE :: Note that the event has failed to trigger.
-		if(verbose) { System.out.println("No trigger.\n\n"); }
-		
-		// If one or more of the pair cuts failed, the we do not trigger.
-		return false;
-	}
-	
-	// ==================================================================
-	// ==== Trigger Cut Methods =========================================
-	// ==================================================================
-	
-	/**
-	 * Checks whether the cluster passes the threshold for minimum
-	 * number of component hits.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster passes and <code>
-	 * false</code> if it does not.
-	 */
-	private boolean clusterHitCountCut(HPSEcalCluster cluster) {
-		return cluster.getCalorimeterHits().size() >= clusterHitCountThreshold;
-	}
-	
-	/**
-	 * Checks whether the cluster falls within the allowed range for
-	 * the seed hit energy cut.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster passes and <code>
-	 * false</code> if it does not.
-	 */
-	private boolean clusterSeedEnergyCut(HPSEcalCluster cluster) {
-		// Get the seed energy value.
-		double seedEnergy = cluster.getSeedHit().getCorrectedEnergy();
-		
-		// Perform the seed energy cut.
-		return seedEnergy >= clusterSeedEnergyThresholdLow && seedEnergy <= clusterSeedEnergyThresholdHigh;
-	}
-	
-	/**
-	 * Checks whether the cluster passes the threshold for minimum
-	 * total cluster energy.
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster passes and <code>
-	 * false</code> if it does not.
-	 */
-	private boolean clusterTotalEnergyCut(HPSEcalCluster cluster) {
-		// Get the cluster energy.
-		double clusterEnergy = cluster.getEnergy();
-		
-		// Perform the cut.
-		return clusterEnergy >= clusterTotalEnergyThresholdLow && clusterEnergy <= clusterTotalEnergyThresholdHigh;
-	}
-	
-	/**
-	 * Calculates the value used in the pair energy sum cut from a pair
-	 * of two clusters.
-	 * @param clusterPair - The cluster pair from which to derive the
-	 * cut value.
-	 * @return Returns the cut value as a <code>double</code>.
-	 */
-	private static double getEnergySumValue(HPSEcalCluster[] clusterGroup) {
-		// Track the sum.
-		double energySum = 0.0;
-		
-		// Add the energies of all clusters in the array.
-		for(HPSEcalCluster cluster : clusterGroup) { energySum += cluster.getEnergy(); }
-		
-		// Return the sum.
-		return energySum;
-	}
-	
-	/**
-	 * Calculates the value used in the invariant mass cut from a pair
-	 * of two clusters.
-	 * @param clusterPair - The cluster pair from which to derive the
-	 * cut value.
-	 * @return Returns the cut value as a <code>double</code>.
-	 */
-	private double getInvariantMassValue(HPSEcalCluster[] clusterPair) {
-		// Store the x/y positions for the seeds.
-		double x[] = new double[2];
-		double y[] = new double[2];
-		
-		// Get the seed hits.
-		CalorimeterHit[] seed = { clusterPair[0].getSeedHit(), clusterPair[1].getSeedHit() };
-		
-		// Set the positions for each seed.
-		for(int index = 0; index < seed.length; index++) {
-			// Get the seed position array stored in the position map.
-			Double[] seedPos = seedPosMap.get(clusterPair[index].getSeedHit());
-			
-			// If there is a position array for the seed, use it.
-			if(seedPos != null) {
-				x[index] = seedPos[0];
-				y[index] = seedPos[1];
-			}
-			
-			// Otherwise, calculate the position at the crystal face.
-			else {
-				// Get the position and store it in a double array.
-				IGeometryInfo geom = clusterPair[index].getSeedHit().getDetectorElement().getGeometry();
-				double[] pos = geom.transformLocalToGlobal(VecOp.add(geom.transformGlobalToLocal(geom.getPosition()),
-						(Hep3Vector) new BasicHep3Vector(0, 0, -1 * ((Trd) geom.getLogicalVolume().getSolid()).getZHalfLength()))).v();
-				
-				// Set the seed location.
-				x[index] = pos[0];
-				y[index] = pos[1];
-				
-				// Store the seed location for future use.
-				Double[] positionVec = { pos[0], pos[1], pos[2] };
-				seedPosMap.put(clusterPair[index].getSeedHit(), positionVec);
-			}
-		}
-		
-		// Get the cluster energy for each seed.
-		double[] e = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
-		
-		//Return the invariant mass.
-		return (e[0] * e[1] * (Math.pow(x[0] - x[1], 2) + Math.pow(y[0] - y[1], 2)) / D2);
-	}
-	
-	/**
-	 * Indicates whether a cluster has a seed hit located on the edge
-	 * of the calorimeter or not.
-	 * 
-	 * @param cluster - The cluster to check.
-	 * @return Returns <code>true</code> if the cluster seed is on the
-	 * edge of the calorimeter and <code>false</code> otherwise.
-	 */
-	private static boolean isEdgeCluster(HPSEcalCluster cluster) {
-		// Get the x- and y-indices of the cluster seed hit.
-		int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
-		int iy = cluster.getSeedHit().getIdentifierFieldValue("iy");
-		
-		// Track whether the cluster is an edge cluster or not.
-    	boolean edge = false;
-    	
-    	// Get the absolute values of the coordinates.
-    	int aix = Math.abs(ix);
-    	int aiy = Math.abs(iy);
-    	
-    	// Check if this an outer edge crystal.
-    	if(aix == 23 || aiy == 5) { edge = true; }
-    	
-    	// Check if this along the central beam gap.
-    	if(aiy == 1) { edge = true; }
-    	
-    	// Check if this is around the beam gap.
-    	if(aiy == 2 && (ix >= -11 && ix <= -1)) { edge = true; }
-    	
-    	// Otherwise, this is not an edge crystal.
-    	return edge;
-	}
-	
-	/**
-	 * Checks whether the cluster pair passes the falls within the
-	 * allowed range for the piar energy sum cut.
-	 * @param clusterPair - An array of size two containing the cluster
-	 * pair to check.
-	 * @return Returns <code>true</code> if the clusters pass and <code>
-	 * false</code> if they does not.
-	 */
-	private boolean pairEnergySumCut(HPSEcalCluster[] clusterPair) {
-		// Get the energy sum value.
-		double energySum = getEnergySumValue(clusterPair);
-		
-		// Otherwise, get the energy sum and compare it to the threshold.
-		return energySum >= pairEnergySumThresholdLow && energySum <= pairEnergySumThresholdHigh;
-	}
-	
-	/**
-	 * Checks whether the cluster pair passes the threshold for the
-	 * invariant mass check.
-	 * @param clusterPair - An array of size two containing the cluster
-	 * pair to check.
-	 * @return Returns <code>true</code> if the clusters pass and <code>
-	 * false</code> if they does not.
-	 */
-	private boolean pairInvariantMassCut(HPSEcalCluster[] clusterPair) {
-		// Calculate the invariant mass.
-		double myy2 = getInvariantMassValue(clusterPair);
-		
-		// Perform the cut.
-		return ( (myy2 >= invariantMassThresholdLow) && (myy2 <= invariantMassThresholdHigh));
-	}
-	
-	/**
-	 * Checks whether the cluster pair passes the threshold for the
-	 * minimum pair energy sum check.
-	 * @param clusterTriplet - An array of size three containing the
-	 * cluster triplet to check.
-	 * @return Returns <code>true</code> if the clusters pass and <code>
-	 * false</code> if they does not.
-	 */
-	private boolean tripletEnergySumCut(HPSEcalCluster[] clusterTriplet) {
-		return (getEnergySumValue(clusterTriplet) >= tripletEnergySumThreshold);
-	}
-	
-	/**
-	 * Checks that there is at least one cluster is located on the right
-	 * side and at least one cluster on the left side of the calorimeter.
-	 * @param clusterTriplet - An array of size three containing the
-	 * cluster triplet to check.
-	 * @return Returns <code>true</code> if the clusters pass and <code>
-	 * false</code> if they does not.
-	 */
-	private static boolean tripletHorizontalCut(HPSEcalCluster[] clusterTriplet) {
-		// Track whether a cluster has occurred on each horizontal side
-		// of the calorimeter.
-		boolean leftCluster = false;
-		boolean rightCluster = false;
-		
-		// Sort through the cluster triplet and check where they occur.
-		for(HPSEcalCluster cluster : clusterTriplet) {
-			int ix = cluster.getSeedHit().getIdentifierFieldValue("ix");
-			if(ix < 0) { leftCluster = true; }
-			if(ix > 0) { rightCluster = true; }
-		}
-		
-		// If a cluster fell on both sides, it passes.
-		if(leftCluster && rightCluster) { return true; }
-		else { return false; }
-	}
-	
-	private boolean tripletTotalEnergyCut(HPSEcalCluster[] clusterTriplet) {
-		// Check to see if each cluster passes the check.
-		for(HPSEcalCluster cluster1 : clusterTriplet) {
-			for(HPSEcalCluster cluster2 : clusterTriplet) {
-				// The cluster pair must be two different clusters.
-				if(cluster1 == cluster2) { continue; }
-				
-				// Check to see if the clusters are over threshold.
-				boolean over1 = cluster1.getEnergy() >= tripletTotalEnergyThreshold;
-				boolean over2 = cluster1.getEnergy() >= tripletTotalEnergyThreshold;
-				
-				// If both the clusters are over threshold, check that
-				// they are sufficiently far apart.
-				if(over1 && over2) {
-					// Get the x and y coordinates of the clusters.
-					double x[] = { cluster1.getPosition()[0], cluster2.getPosition()[0] };
-					double y[] = { cluster1.getPosition()[1], cluster2.getPosition()[1] };
-					
-					// Calculate the distance between the clusters.
-					double dr = Math.sqrt(x[0] * x[0] + y[0] * y[0]);
-					
-					// Run the check.
-					if(dr >= tripletPairSeparationThreshold) { return true; }
-				}
-			}
-		}
-		
-		// If none of the cluster pairs pass all the checks, the
-		// triplet fails.
-		return false;
-	}
-	
-	// ==================================================================
-	// ==== Variables Mutator Methods ===================================
-	// ==================================================================
-	
-	/**
-	 * Sets the LCIO collection name where <code>HPSEcalCluster</code>
-	 * objects are stored for use in the trigger.
-	 * @param clusterCollectionName - The name of the LCIO collection.
-	 */
-	public void setClusterCollectionName(String clusterCollectionName) {
-		this.clusterCollectionName = clusterCollectionName;
-	}
-	
-	/**
-	 * Sets the minimum number of hits required for a cluster to be
-	 * used in triggering.
-	 * @param clusterHitCountThreshold - The smallest number of hits
-	 * in a cluster.
-	 */
-	public void setClusterHitCountThreshold(int clusterHitCountThreshold) {
-		this.clusterHitCountThreshold = clusterHitCountThreshold;
-	}
-	
-	/**
-	 * Sets the threshold for the cluster seed energy of individual
-	 * clusters above which the cluster will be rejected and not used
-	 * for triggering.
-	 * @param clusterSeedEnergyThresholdHigh - The cluster seed energy
-	 * lower bound.
-	 */
-	public void setClusterSeedEnergyThresholdHigh(double clusterSeedEnergyThresholdHigh) {
-		this.clusterSeedEnergyThresholdHigh = clusterSeedEnergyThresholdHigh;
-	}
-	
-	/**
-	 * Sets the threshold for the cluster seed energy of individual
-	 * clusters under which the cluster will be rejected and not used
-	 * for triggering.
-	 * @param clusterSeedEnergyThresholdLow - The cluster seed energy
-	 * lower bound.
-	 */
-	public void setClusterSeedEnergyThresholdLow(double clusterSeedEnergyThresholdLow) {
-		this.clusterSeedEnergyThresholdLow = clusterSeedEnergyThresholdLow;
-	}
-	
-	/**
-	 * Sets the threshold for the total cluster energy of individual
-	 * clusters under which the cluster will be rejected and not used
-	 * for triggering.
-	 * @param clusterTotalEnergyThresholdLow - The cluster total energy
-	 * lower bound.
-	 */
-	public void setClusterTotalEnergyThresholdLow(double clusterTotalEnergyThresholdLow) {
-		this.clusterTotalEnergyThresholdLow = clusterTotalEnergyThresholdLow;
-	}
-	
-	/**
-	 * Sets the threshold for the total cluster energy of individual
-	 * clusters above which the cluster will be rejected and not used
-	 * for triggering.
-	 * @param clusterTotalEnergyThresholdHigh - The cluster total energy
-	 * upper bound.
-	 */
-	public void setClusterTotalEnergyThresholdHigh(double clusterTotalEnergyThresholdHigh) {
-		this.clusterTotalEnergyThresholdHigh = clusterTotalEnergyThresholdHigh;
-	}
-	
-	/**
-	 * Sets the number of events that clusters will be retained and
-	 * employed for triggering before they are cleared.
-	 * @param coincidenceWindow - The number of events that clusters
-	 * should be retained.
-	 */
-	public void setCoincidenceWindow(int coincidenceWindow) {
-		this.coincidenceWindow = coincidenceWindow;
-	}
-	
-	/**
-	 * Sets the invariant mass threshold to accept only cluster pairs
-	 * with a reconstructed invariant mass within a certain number of
-	 * standard deviations of the mean (corrected for sampling fraction).
-	 * @param invariantMassSigma - The number of standard deviations
-	 * within which a cluster pair invariant mass is accepted.
-	 */
-	public void setInvariantMassSigma(int invariantMassSigma) {
-		this.invariantMassThresholdLow = 0.012499 - (invariantMassSigma * 0.0011095);
-		this.invariantMassThresholdHigh = 0.012499 + (invariantMassSigma * 0.0011095);
-	}
-	
-	/**
-	 * Sets the threshold for the calculated invariant mass of the
-	 * generating particle (assuming that the clusters are produced
-	 * by a positron/electron pair) above which the cluster pair will
-	 * be rejected and not produce a trigger.
-	 * @param invariantMassThresholdHigh - The invariant mass upper
-	 * bound.
-	 */
-	public void setInvariantMassThresholdHigh(double invariantMassThresholdHigh) {
-		this.invariantMassThresholdHigh = invariantMassThresholdHigh;
-	}
-	
-	/**
-	 * Sets the threshold for the calculated invariant mass of the
-	 * generating particle (assuming that the clusters are produced
-	 * by a positron/electron pair) under which the cluster pair will
-	 * be rejected and not produce a trigger.
-	 * @param invariantMassThresholdLow - The invariant mass lower
-	 * bound.
-	 */
-	public void setInvariantMassThresholdLow(double invariantMassThresholdLow) {
-		this.invariantMassThresholdLow = invariantMassThresholdLow;
-	}
-	
-	/**
-	 * Sets the threshold for the sum of the energies of a cluster pair
-	 * above which the pair will be rejected and not produce a trigger.
-	 * @param pairEnergySumThresholdHigh - The cluster pair energy sum
-	 * upper bound.
-	 */
-	public void setPairEnergySumThresholdHigh(double pairEnergySumThresholdHigh) {
-		this.pairEnergySumThresholdHigh = pairEnergySumThresholdHigh;
-	}
-	
-	/**
-	 * Sets the threshold for the sum of the energies of a cluster pair
-	 * under which the pair will be rejected and not produce a trigger.
-	 * @param pairEnergySumThresholdLow - The cluster pair energy sum
-	 * lower bound.
-	 */
-	public void setPairEnergySumThresholdLow(double pairEnergySumThresholdLow) {
-		this.pairEnergySumThresholdLow = pairEnergySumThresholdLow;
-	}
-	
-	/**
-	 * Sets whether clusters centered on an edge crystal should be
-	 * used for triggering or not.
-	 * 
-	 * @param rejectEdgeCrystals - <code>true</code> means that edge
-	 * clusters will not be used and <code>false</code> means that they
-	 * will be used.
-	 */
-	public void setRejectEdgeCrystals(boolean rejectEdgeCrystals) {
-		this.rejectEdgeCrystals = rejectEdgeCrystals;
-	}
-	
-	/**
-	 * Sets the threshold for the sum of the energies of a cluster triplet
-	 * under which the triplet will be rejected and not produce a trigger.
-	 * @param tripletEnergySumThreshold - The cluster triplet energy sum
-	 * lower bound.
-	 */
-	public void setTripletEnergySumThreshold(double tripletEnergySumThreshold) {
-		this.tripletEnergySumThreshold = tripletEnergySumThreshold;
-	}
-	
-	/**
-	 * Sets the minimum distance apart for a cluster pair within a
-	 * cluster triplet. Clusters that are not sufficiently far apart
-	 * are rejected and do not trigger. 
-	 * @param tripletPairSeparationThreshold - The minimum distance in
-	 * millimeters.
-	 */
-	public void setTripletPairSeparationThreshold(double tripletPairSeparationThreshold) {
-		this.tripletPairSeparationThreshold = tripletPairSeparationThreshold;
-	}
-	
-	/**
-	 * Sets the threshold for which at least two clusters in a cluster
-	 * triplet will be required to surpass. Cluster triplets with one
-	 * or fewer clusters above the threshold will be rejected.
-	 * @param tripletTotalEnergyThreshold - The cluster total energy
-	 * that two clusters must pass.
-	 */
-	public void setTripletTotalEnergyThreshold(double tripletTotalEnergyThreshold) {
-		this.tripletTotalEnergyThreshold = tripletTotalEnergyThreshold;
-	}
-	
-	/**
-	 * Toggles whether the driver will output its actions to the console
-	 * during run time or not.
-	 * @param verbose - <code>true</code> indicates that the console
-	 * will write its actions and <code>false</code> that it will not.
-	 */
-	public void setVerbose(boolean verbose) {
-		this.verbose = verbose;
-	}
-	
-	/**
-	 * Toggles whether the driver triggers off of a pair of clusters
-	 * or a triplet of clusters.
-	 * @param useClusterTriplet - <code>true</code> indicates that a
-	 * triplet should be used and <code>false</code> that a pair should
-	 * be used.
-	 */
-	public void setUseClusterTriplet(boolean useClusterTriplet) {
-		this.useClusterTriplet = useClusterTriplet;
-	}
-	
-	// ==================================================================
-	// ==== AIDA Plots ==================================================
-	// ==================================================================
-	IHistogram2D aClusterDistribution;
-	IHistogram1D aClusterHitCount;
-	IHistogram1D aClusterSeedEnergy;
-	IHistogram1D aClusterTotalEnergy;
-	IHistogram2D clusterDistribution;
-	IHistogram1D clusterHitCount;
-	IHistogram1D clusterSeedEnergy;
-	IHistogram1D clusterTotalEnergy;
-	IHistogram1D invariantMass;
-	IHistogram1D pairEnergySum;
-	IHistogram1D pClusterHitCount;
-	IHistogram2D pClusterDistribution;
-	IHistogram1D pClusterSeedEnergy;
-	IHistogram1D pClusterTotalEnergy;
-	IHistogram1D pPairEnergySum;
-	IHistogram1D pInvariantMass;
-	IHistogram1D seedPercent;
-	
-	// ==================================================================
-	// ==== Variables ===================================================
-	// ==================================================================
-	
-	/**
-	 * <b>aida</b><br/><br/>
-	 * <code>private AIDA <b>aida</b></code><br/><br/>
-	 * Factory for generating histograms.
-	 */
-	private AIDA aida = AIDA.defaultInstance();
-	
-	/**
-	 * <b>clusterBuffer</b><br/><br/>
-	 * <code>private LinkedList<List<HPSEcalCluster>> <b>clusterBuffer</b></code><br/><br/>
-	 * Stores the list of clusters from each event for a finite-sized
-	 * buffer. The size of the buffer is determined by the coincidence
-	 * window.
-	 */
-	private LinkedList<List<HPSEcalCluster>> clusterBuffer;
-	
-	/**
-	 * <b>clusterCollectionName</b><br/><br/>
-	 * <code>private String <b>clusterCollectionName</b></code><br/><br/>
-	 * The name of the LCIO collection containing <code>HPSEcalCluster
-	 * </code> objects.
-	 */
-	private String clusterCollectionName = "EcalClusters";
-	
-	/**
-	 * <b>clusterPair</b><br/><br/>
-	 * <code>private HPSEcalCluster[] <b>clusterPair</b></code><br/><br/>
-	 * Stores the two highest energy clusters located in the cluster
-	 * buffer. These are sorted by energy, with the highest energy
-	 * cluster first in the array.
-	 */
-	private HPSEcalCluster[] clusterPair = new HPSEcalCluster[2];
-	
-	/**
-	 * <b>clusterHitCountThreshold</b><br/><br/>
-	 * <code>private int <b>clusterHitCountThreshold</b></code><br/><br/>
-	 * Defines the minimum number of hits required for a cluster to
-	 * be used in triggering.
-	 */
-	private int clusterHitCountThreshold = 5;
-	
-	/**
-	 * <b>clusterSeedEnergyThresholdLow</b><br/><br/>
-	 * <code>private double <b>clusterSeedEnergyThresholdLow</b></code><br/><br/>
-	 * Defines the threshold for the cluster seed energy under which
-	 * a cluster will be rejected.
-	 */
-	private double clusterSeedEnergyThresholdLow = 0.15;
-	
-	/**
-	 * <b>clusterSeedEnergyThresholdHigh</b><br/><br/>
-	 * <code>private double <b>clusterSeedEnergyThresholdHigh</b></code><br/><br/>
-	 * Defines the threshold for the cluster seed energy above which
-	 * a cluster will be rejected.
-	 */
-	private double clusterSeedEnergyThresholdHigh = 1.00;
-	
-	/**
-	 * <b>clusterTotalEnergyThresholdLow</b><br/><br/>
-	 * <code>private double <b>clusterTotalEnergyThreshold</b></code><br/><br/>
-	 * Defines the threshold for the total cluster energy under which
-	 * a cluster will be rejected.
-	 */
-	private double clusterTotalEnergyThresholdLow = 0.0;
-	
-	/**
-	 * <b>clusterTotalEnergyThresholdHigh</b><br/><br/>
-	 * <code>private double <b>clusterTotalEnergyThresholdHigh</b></code><br/><br/>
-	 * Defines the threshold for the total cluster energy above which
-	 * a cluster will be rejected.
-	 */
-	private double clusterTotalEnergyThresholdHigh = Double.MAX_VALUE;
-	
-	/**
-	 * <b>clusterTriplet</b><br/><br/>
-	 * <code>private HPSEcalCluster[] <b>clusterTriplet</b></code><br/><br/>
-	 * Stores the three highest energy clusters located in the cluster
-	 * buffer. These are sorted by energy, with the highest energy
-	 * cluster first in the array.
-	 */
-	private HPSEcalCluster[] clusterTriplet = new HPSEcalCluster[3]; 
-	
-	/**
-	 * <b>coincidenceWindow</b><br/><br/>
-	 * <code>private int <b>coincidenceWindow</b></code><br/><br/>
-	 * The number of events for which clusters will be retained and
-	 * used in the trigger before they are removed.
-	 */
-	private int coincidenceWindow = 3;
-	
-	/**
-	 * <b>D2</b><br/><br/>
-	 * <code>private static final double <b>D2</b></code><br/><br/>
-	 * The squared distance of the calorimeter from the target.
-	 */
-	private static final double D2 = 1414 * 1414; // (1414^2 mm^2)
-	
-	/**
-	 * <b>invariantMassThresholdHigh</b><br/><br/>
-	 * <code>private double <b>invariantMassThresholdHigh</b></code><br/><br/>
-	 * Defines the threshold for the invariant mass of the generating
-	 * particle above which the cluster pair will be rejected.
-	 */
-	private double invariantMassThresholdHigh = 0.01472;
-	
-	/**
-	 * <b>invariantMassThresholdLow</b><br/><br/>
-	 * <code>private double <b>invariantMassThresholdLow</b></code><br/><br/>
-	 * Defines the threshold for the invariant mass of the generating
-	 * particle below which the cluster pair will be rejected.
-	 */
-	private double invariantMassThresholdLow = 0.01028;
-	
-	/**
-	 * <b>pairEnergySumThresholdLow</b><br/><br/>
-	 * <code>private double <b>pairEnergySumThresholdLow</b></code><br/><br/>
-	 * Defines the threshold for the sum of the energies of a cluster
-	 * pair below which the pair will be rejected.
-	 */
-	private double pairEnergySumThresholdLow = 1.5;
-	
-	/**
-	 * <b>pairEnergySumThresholdHigh</b><br/><br/>
-	 * <code>private double <b>pairEnergySumThresholdHigh</b></code><br/><br/>
-	 * Defines the threshold for the sum of the energies of a cluster
-	 * pair above which the pair will be rejected.
-	 */
-	private double pairEnergySumThresholdHigh = 1.8;
-	
-	/**
-	 * <b>rejectEdgeCrystals</b><br/><br/>
[truncated at 1000 lines; 1065 more skipped]
SVNspam 0.1