LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  September 2016

HPS-SVN September 2016

Subject:

r4501 - in /java/trunk/users/src/main/java/org/hps/users/kmccarty: ./ plots/ plots/formatter/

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Tue, 27 Sep 2016 15:50:16 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (6614 lines)

Author: [log in to unmask]
Date: Tue Sep 27 08:50:14 2016
New Revision: 4501

Log:
Adding working copy of a DAQConfigDriver that can read runtime settings from the database.

Added:
    java/trunk/users/src/main/java/org/hps/users/kmccarty/DatabaseDAQConfigDriver.java   (with props)
Modified:
    java/trunk/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java
    java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java

Added: java/trunk/users/src/main/java/org/hps/users/kmccarty/DatabaseDAQConfigDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/DatabaseDAQConfigDriver.java	(added)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/DatabaseDAQConfigDriver.java	Tue Sep 27 08:50:14 2016
@@ -0,0 +1,79 @@
+package org.hps.users.kmccarty;
+
+import org.hps.record.daqconfig.ConfigurationManager;
+import org.hps.record.daqconfig.DAQConfigDriver;
+import org.hps.record.daqconfig.EvioDAQParser;
+import org.hps.record.triggerbank.TriggerConfigData;
+import org.hps.record.triggerbank.TriggerConfigData.Crate;
+import org.hps.rundb.DaoProvider;
+import org.hps.rundb.RunManager;
+import org.lcsim.event.EventHeader;
+import org.lcsim.geometry.Detector;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+
+public class DatabaseDAQConfigDriver extends DAQConfigDriver {
+	// Define the crate enumerables by crate number. Crates are
+	// in the order 46, 37, 39.
+	private static final Crate[] CRATES = { Crate.CONFIG3, Crate.CONFIG1, Crate.CONFIG2 };
+	
+	@Override
+	public void detectorChanged(Detector detector) {
+		// Make sure that the run number is defined.
+		if(getRunNumber() == -1) { throw new IllegalArgumentException("Run number is undefined."); }
+		
+		// Get the trigger configuration data.
+		RunManager manager = new RunManager();
+		manager.setRun(getRunNumber());
+		DaoProvider factory = new DaoProvider(manager.getConnection());
+		TriggerConfigData triggerConfig = factory.getTriggerConfigDao().getTriggerConfig(RunManager.getRunManager().getRun());
+		
+		// Convert the trigger configuration text blocks into individual
+		// strings.
+		String[][] data = null;
+		try { data = getDataFileArrays(triggerConfig); }
+		catch(IOException e) {
+			throw new RuntimeException("An error occurred when processing the trigger data.");
+		}
+        
+        // Instantiate an EvIO DAQ parser and feed it the data.
+        EvioDAQParser daqConfig = new EvioDAQParser();
+        for(int i = 0; i < 3; i++) {
+            daqConfig.parse(CRATES[i].getCrateNumber(), getRunNumber(), data[i]);
+        }
+        
+        // Update the configuration manager.
+        ConfigurationManager.updateConfiguration(daqConfig);
+        
+        // Close the manager.
+        manager.closeConnection();
+	}
+	
+	@Override
+	public void process(EventHeader event) { }
+	
+	private static final String[][] getDataFileArrays(TriggerConfigData triggerConfig) throws IOException {
+        // Create file readers to process the data files.
+		StringReader[] fr = new StringReader[3];
+        BufferedReader[] reader = new BufferedReader[3];
+        for(int i = 0; i < 3; i++) {
+        	fr[i] = new StringReader(triggerConfig.getData().get(CRATES[i]));
+            reader[i] = new BufferedReader(fr[i]);
+        }
+		
+		// Convert the crate data into an array of strings. These must
+		// be in the order of 46, 37, 39.
+        String[][] data = getDataFileArrays(reader);
+		
+		// Close the readers.
+		for(int i = 0; i < 3; i++) {
+			reader[i].close();
+			fr[i].close();
+		}
+		
+		// Return the converted data.
+		return data;
+	}
+}

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/HPSEcalDataPlotsDriver.java	Tue Sep 27 08:50:14 2016
@@ -27,22 +27,23 @@
  * @author Kyle McCarty <[log in to unmask]>
  */
 public class HPSEcalDataPlotsDriver extends Driver {
-    private String plotsGroupName= "Data Plots";
-    private String bankCollectionName = "TriggerBank";
-    private String clusterCollectionName = "EcalClusters";
-    
-    private static final int PULSER   = 0;
-    private static final int SINGLES0 = 1;
-    private static final int SINGLES1 = 2;
-    private static final int PAIR0    = 3;
-    private static final int PAIR1    = 4;
-    
-    private static final int ALL       = 0;
-    private static final int EDGE      = 1;
-    private static final int FIDUCIAL = 2;
-    
-    private AIDA aida = AIDA.defaultInstance();
-    private IHistogram1D[][] clusterTotalEnergy = new IHistogram1D[5][3];
+	private boolean useGoodSVT = false;
+	private String plotsGroupName= "Data Plots";
+	private String bankCollectionName = "TriggerBank";
+	private String clusterCollectionName = "EcalClusters";
+	
+	private static final int PULSER   = 0;
+	private static final int SINGLES0 = 1;
+	private static final int SINGLES1 = 2;
+	private static final int PAIR0    = 3;
+	private static final int PAIR1    = 4;
+	
+	private static final int ALL       = 0;
+	private static final int EDGE      = 1;
+	private static final int FIDUCIAL  = 2;
+	
+	private AIDA aida = AIDA.defaultInstance();
+	private IHistogram1D[][] clusterTotalEnergy = new IHistogram1D[5][3];
     private IHistogram1D[][] clusterTime = new IHistogram1D[5][3];
     private IHistogram1D[][] clusterHitCount = new IHistogram1D[5][3];
     private IHistogram1D[][] clusterSeedEnergy = new IHistogram1D[5][3];
@@ -101,204 +102,228 @@
                 pairCoplanarityEnergySum[i][j] = aida.histogram2D(plotsGroupName + "/" + triggerNames[i] + "/"
                         + positionNames[j] + "/Pair Energy Sum vs. Coplanarity", 150, 0.000, 1.500, 180, 0, 180);
                 pairEnergySlope2D[i][j] = aida.histogram2D(plotsGroupName + "/" + triggerNames[i] + "/"
-                        + positionNames[j] + "/Pair Energy Slope 2D", 75, 0.000, 1.500, 100, 0.0, 400.0);
+                		+ positionNames[j] + "/Pair Energy Slope 2D", 75, 0.000, 1.500, 100, 0.0, 400.0);
+			}
+		}
+	}
+	
+	/**
+	 * Processes the event clusters and populates distribution charts
+	 * from them for each trigger. Also creates separate plots for the
+	 * edge and fiducial regions.
+	 * @param event - The event containing LCIO collections to be used
+	 * for plot population.
+	 */
+	@Override
+	public void process(EventHeader event) {
+		// Check whether the SVT was active in this event.
+		final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
+		boolean svtGood = true;
+        for(int i = 0; i < flagNames.length; i++) {
+            int[] flag = event.getIntegerParameters().get(flagNames[i]);
+            if(flag == null || flag[0] == 0) {
+                svtGood = false;
             }
         }
-    }
-    
-    /**
-     * Processes the event clusters and populates distribution charts
-     * from them for each trigger. Also creates separate plots for the
-     * edge and fiducial regions.
-     * @param event - The event containing LCIO collections to be used
-     * for plot population.
-     */
-    @Override
-    public void process(EventHeader event) {
-        // Get the TI and SSP banks.
-        TIData tiBank = null;
-        SSPData sspBank = null;
-        if(event.hasCollection(GenericObject.class, bankCollectionName)) {
-            // Get the bank list.
-            List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
-            
-            // Search through the banks and get the SSP and TI banks.
-            for(GenericObject obj : bankList) {
-                // If this is an SSP bank, parse it.
-                if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
-                    sspBank = new SSPData(obj);
-                }
-                
-                // Otherwise, if this is a TI bank, parse it.
-                else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
-                    tiBank = new TIData(obj);
-                }
-            }
-        }
+		
+        // If the SVT is not properly running, skip the event.
+        if(!svtGood && useGoodSVT) { return; }
         
-        // Get the list of clusters.
-        List<Cluster> clusters = null;
-        if(event.hasCollection(Cluster.class, clusterCollectionName)) {
-            clusters = event.get(Cluster.class, clusterCollectionName);
-        }
-        
-        // Require that all collections be initialized.
-        if(sspBank == null || tiBank == null || clusters == null) {
-            return;
-        }
-        
-        // Track which triggers are active.
-        boolean[] activeTrigger = new boolean[5];
-        activeTrigger[PULSER] = tiBank.isPulserTrigger();
-        activeTrigger[SINGLES0] = tiBank.isSingle0Trigger();
-        activeTrigger[SINGLES1] = tiBank.isSingle1Trigger();
-        activeTrigger[PAIR0] = tiBank.isPair0Trigger();
-        activeTrigger[PAIR1] = tiBank.isPair1Trigger();
-        
-        // Plot all cluster properties for each trigger.
-        for(Cluster cluster : clusters) {
-            // Check whether the cluster is a fiducial or edge cluster.
-            int positional = inFiducialRegion(cluster) ? FIDUCIAL : EDGE;
-            
-            // Fill the appropriate plots for each trigger with an
-            // active trigger bit for single clusters.
-            for(int i = 0; i < 5; i++) {
-                if(activeTrigger[i]) {
-                    // Populate the ALL plots.
-                    clusterSeedEnergy[i][ALL].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
-                    clusterTotalEnergy[i][ALL].fill(cluster.getEnergy());
-                    clusterHitCount[i][ALL].fill(TriggerModule.getClusterHitCount(cluster));
-                    clusterTime[i][ALL].fill(TriggerModule.getClusterTime(cluster));
-                    clusterSeedPosition[i][ALL].fill(TriggerModule.getClusterXIndex(cluster),
-                            TriggerModule.getClusterYIndex(cluster));
-                    
-                    // Populate the positional plots.
-                    clusterSeedEnergy[i][positional].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
-                    clusterTotalEnergy[i][positional].fill(cluster.getEnergy());
-                    clusterHitCount[i][positional].fill(TriggerModule.getClusterHitCount(cluster));
-                    clusterTime[i][positional].fill(TriggerModule.getClusterTime(cluster));
-                    clusterSeedPosition[i][positional].fill(TriggerModule.getClusterXIndex(cluster),
-                            TriggerModule.getClusterYIndex(cluster));
-                }
-            }
-        }
-        
-        // Plot all pair properties for each trigger.
-        List<Cluster[]> pairs = TriggerModule.getTopBottomPairs(clusters, Cluster.class);
-        for(Cluster[] pair : pairs) {
-            // Check whether the cluster is a fiducial or edge cluster.
-            boolean[] isFiducial = {
-                    inFiducialRegion(pair[0]),
-                    inFiducialRegion(pair[1])
-            };
-            int positional = (isFiducial[0] && isFiducial[1]) ? FIDUCIAL : EDGE;
-            
-            // Fill the appropriate plots for each trigger with an
-            // active trigger bit for single clusters.
-            for(int i = 0; i < 5; i++) {
-                if(activeTrigger[i]) {
-                    // Calculate the values.
-                    double energySum = TriggerModule.getValueEnergySum(pair);
-                    double energyDiff = TriggerModule.getValueEnergyDifference(pair);
-                    double energySlope = TriggerModule.getValueEnergySlope(pair, 0.00550);
-                    double coplanarity = TriggerModule.getValueCoplanarity(pair);
-                    double timeCoincidence = TriggerModule.getValueTimeCoincidence(pair);
-                    
-                    // Get the energy slope values.
-                    Cluster lowCluster = pair[0].getEnergy() < pair[1].getEnergy() ? pair[0] : pair[1];
-                    double clusterDistance = TriggerModule.getClusterDistance(lowCluster);
-                    
-                    // Populate the ALL plots.
-                    pairEnergySum[i][ALL].fill(energySum);
-                    pairEnergyDifference[i][ALL].fill(energyDiff);
-                    pairEnergySlope[i][ALL].fill(energySlope);
-                    pairCoplanarity[i][ALL].fill(coplanarity);
-                    pairTimeCoincidence[i][ALL].fill(timeCoincidence);
-                    pairEnergySum2D[i][ALL].fill(pair[0].getEnergy(), pair[1].getEnergy());
-                    pairCoplanarityEnergySum[i][ALL].fill(energySum, coplanarity);
-                    pairEnergySlope2D[i][ALL].fill(lowCluster.getEnergy(), clusterDistance);
-                    
-                    // Populate the positional plots.
-                    pairEnergySum[i][positional].fill(energySum);
-                    pairEnergyDifference[i][positional].fill(energyDiff);
-                    pairEnergySlope[i][positional].fill(energySlope);
-                    pairCoplanarity[i][positional].fill(coplanarity);
-                    pairTimeCoincidence[i][positional].fill(timeCoincidence);
-                    pairEnergySum2D[i][positional].fill(pair[0].getEnergy(), pair[1].getEnergy());
-                    pairCoplanarityEnergySum[i][positional].fill(energySum, coplanarity);
-                    pairEnergySlope2D[i][positional].fill(lowCluster.getEnergy(), clusterDistance);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Indicates whether the argument cluster is located in the fiducial
-     * region or not.
-     * @param cluster - The cluster to check.
-     * @return Returns <code>true</code> if the cluster is located in
-     * the fiducial region and <code>false</code> otherwise.
-     */
-    private static final boolean inFiducialRegion(Cluster cluster) {
-        // Get the x and y indices for the cluster.
-        int ix   = TriggerModule.getClusterXIndex(cluster);
-        int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
-        int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
-        
-        // Check if the cluster is on the top or the bottom of the
-        // calorimeter, as defined by |y| == 5. This is an edge cluster
-        // and is not in the fiducial region.
-        if(absy == 5) {
-            return false;
-        }
-        
-        // Check if the cluster is on the extreme left or right side
-        // of the calorimeter, as defined by |x| == 23. This is also
-        // and edge cluster is not in the fiducial region.
-        if(absx == 23) {
-            return false;
-        }
-        
-        // Check if the cluster is along the beam gap, as defined by
-        // |y| == 1. This is an internal edge cluster and is not in the
-        // fiducial region.
-        if(absy == 1) {
-            return false;
-        }
-        
-        // Lastly, check if the cluster falls along the beam hole, as
-        // defined by clusters with -11 <= x <= -1 and |y| == 2. This
-        // is not the fiducial region.
-        if(absy == 2 && ix <= -1 && ix >= -11) {
-            return false;
-        }
-        
-        // If all checks fail, the cluster is in the fiducial region.
-        return true;
-    }
-    
-    /**
-     * Sets the name of the LCIO collection containing the clusters
-     * that are to be plotted.
-     * @param collection - The LCIO collection name.
-     */
-    public void setClusterCollectionName(String collection) {
-        clusterCollectionName = collection;
-    }
-    
-    /**
-     * Defines the name of the LCIO collection containing the TI bank.
-     * @param collection - The LCIO collection name.
-     */
-    public void setBankCollectionName(String collection) {
-        bankCollectionName = collection;
-    }
-    
-    /**
-     * Sets the name of the super-group folder containing all plots.
-     * @param name - The name of the plots folder.
-     */
-    public void setPlotsGroupName(String name) {
-        plotsGroupName = name;
-    }
+		// Get the TI and SSP banks.
+		TIData tiBank = null;
+		SSPData sspBank = null;
+		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+			// Get the bank list.
+			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+			
+			// Search through the banks and get the SSP and TI banks.
+			for(GenericObject obj : bankList) {
+				// If this is an SSP bank, parse it.
+				if(AbstractIntData.getTag(obj) == SSPData.BANK_TAG) {
+					sspBank = new SSPData(obj);
+				}
+				
+				// Otherwise, if this is a TI bank, parse it.
+				else if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+					tiBank = new TIData(obj);
+				}
+			}
+		}
+		
+		// Get the list of clusters.
+		List<Cluster> clusters = null;
+		if(event.hasCollection(Cluster.class, clusterCollectionName)) {
+			clusters = event.get(Cluster.class, clusterCollectionName);
+		}
+		
+		// Require that all collections be initialized.
+		if(sspBank == null || tiBank == null || clusters == null) {
+			return;
+		}
+		
+		// Track which triggers are active.
+		boolean[] activeTrigger = new boolean[5];
+		activeTrigger[PULSER] = tiBank.isPulserTrigger();
+		activeTrigger[SINGLES0] = tiBank.isSingle0Trigger();
+		activeTrigger[SINGLES1] = tiBank.isSingle1Trigger();
+		activeTrigger[PAIR0] = tiBank.isPair0Trigger();
+		activeTrigger[PAIR1] = tiBank.isPair1Trigger();
+		
+		// Plot all cluster properties for each trigger.
+		for(Cluster cluster : clusters) {
+			// Check whether the cluster is a fiducial or edge cluster.
+			int positional = inFiducialRegion(cluster) ? FIDUCIAL : EDGE;
+			
+			// Fill the appropriate plots for each trigger with an
+			// active trigger bit for single clusters.
+			for(int i = 0; i < 5; i++) {
+				if(activeTrigger[i]) {
+					// Populate the ALL plots.
+					clusterSeedEnergy[i][ALL].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
+					clusterTotalEnergy[i][ALL].fill(cluster.getEnergy());
+					clusterHitCount[i][ALL].fill(TriggerModule.getClusterHitCount(cluster));
+					clusterTime[i][ALL].fill(TriggerModule.getClusterTime(cluster));
+					clusterSeedPosition[i][ALL].fill(TriggerModule.getClusterXIndex(cluster),
+							TriggerModule.getClusterYIndex(cluster));
+					
+					// Populate the positional plots.
+					clusterSeedEnergy[i][positional].fill(TriggerModule.getValueClusterSeedEnergy(cluster));
+					clusterTotalEnergy[i][positional].fill(cluster.getEnergy());
+					clusterHitCount[i][positional].fill(TriggerModule.getClusterHitCount(cluster));
+					clusterTime[i][positional].fill(TriggerModule.getClusterTime(cluster));
+					clusterSeedPosition[i][positional].fill(TriggerModule.getClusterXIndex(cluster),
+							TriggerModule.getClusterYIndex(cluster));
+				}
+			}
+		}
+		
+		// Plot all pair properties for each trigger.
+		List<Cluster[]> pairs = TriggerModule.getTopBottomPairs(clusters, Cluster.class);
+		for(Cluster[] pair : pairs) {
+			// Check whether the cluster is a fiducial or edge cluster.
+			boolean[] isFiducial = {
+					inFiducialRegion(pair[0]),
+					inFiducialRegion(pair[1])
+			};
+			int positional = (isFiducial[0] && isFiducial[1]) ? FIDUCIAL : EDGE;
+			
+			// Fill the appropriate plots for each trigger with an
+			// active trigger bit for single clusters.
+			for(int i = 0; i < 5; i++) {
+				if(activeTrigger[i]) {
+					// Calculate the values.
+					double energySum = TriggerModule.getValueEnergySum(pair);
+					double energyDiff = TriggerModule.getValueEnergyDifference(pair);
+					double energySlope = TriggerModule.getValueEnergySlope(pair, 0.00550);
+					double coplanarity = TriggerModule.getValueCoplanarity(pair);
+					double timeCoincidence = TriggerModule.getValueTimeCoincidence(pair);
+					
+					// Get the energy slope values.
+					Cluster lowCluster = pair[0].getEnergy() < pair[1].getEnergy() ? pair[0] : pair[1];
+					double clusterDistance = TriggerModule.getClusterDistance(lowCluster);
+					
+					// Populate the ALL plots.
+					pairEnergySum[i][ALL].fill(energySum);
+					pairEnergyDifference[i][ALL].fill(energyDiff);
+					pairEnergySlope[i][ALL].fill(energySlope);
+					pairCoplanarity[i][ALL].fill(coplanarity);
+					pairTimeCoincidence[i][ALL].fill(timeCoincidence);
+					pairEnergySum2D[i][ALL].fill(pair[0].getEnergy(), pair[1].getEnergy());
+					pairCoplanarityEnergySum[i][ALL].fill(energySum, coplanarity);
+					pairEnergySlope2D[i][ALL].fill(lowCluster.getEnergy(), clusterDistance);
+					
+					// Populate the positional plots.
+					pairEnergySum[i][positional].fill(energySum);
+					pairEnergyDifference[i][positional].fill(energyDiff);
+					pairEnergySlope[i][positional].fill(energySlope);
+					pairCoplanarity[i][positional].fill(coplanarity);
+					pairTimeCoincidence[i][positional].fill(timeCoincidence);
+					pairEnergySum2D[i][positional].fill(pair[0].getEnergy(), pair[1].getEnergy());
+					pairCoplanarityEnergySum[i][positional].fill(energySum, coplanarity);
+					pairEnergySlope2D[i][positional].fill(lowCluster.getEnergy(), clusterDistance);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Indicates whether the argument cluster is located in the fiducial
+	 * region or not.
+	 * @param cluster - The cluster to check.
+	 * @return Returns <code>true</code> if the cluster is located in
+	 * the fiducial region and <code>false</code> otherwise.
+	 */
+	private static final boolean inFiducialRegion(Cluster cluster) {
+		// Get the x and y indices for the cluster.
+		int ix   = TriggerModule.getClusterXIndex(cluster);
+		int absx = Math.abs(TriggerModule.getClusterXIndex(cluster));
+		int absy = Math.abs(TriggerModule.getClusterYIndex(cluster));
+		
+		// Check if the cluster is on the top or the bottom of the
+		// calorimeter, as defined by |y| == 5. This is an edge cluster
+		// and is not in the fiducial region.
+		if(absy == 5) {
+			return false;
+		}
+		
+		// Check if the cluster is on the extreme left or right side
+		// of the calorimeter, as defined by |x| == 23. This is also
+		// and edge cluster is not in the fiducial region.
+		if(absx == 23) {
+			return false;
+		}
+		
+		// Check if the cluster is along the beam gap, as defined by
+		// |y| == 1. This is an internal edge cluster and is not in the
+		// fiducial region.
+		if(absy == 1) {
+			return false;
+		}
+		
+		// Lastly, check if the cluster falls along the beam hole, as
+		// defined by clusters with -11 <= x <= -1 and |y| == 2. This
+		// is not the fiducial region.
+		if(absy == 2 && ix <= -1 && ix >= -11) {
+			return false;
+		}
+		
+		// If all checks fail, the cluster is in the fiducial region.
+		return true;
+	}
+	
+	/**
+	 * Sets the name of the LCIO collection containing the clusters
+	 * that are to be plotted.
+	 * @param collection - The LCIO collection name.
+	 */
+	public void setClusterCollectionName(String collection) {
+		clusterCollectionName = collection;
+	}
+	
+	/**
+	 * Defines the name of the LCIO collection containing the TI bank.
+	 * @param collection - The LCIO collection name.
+	 */
+	public void setBankCollectionName(String collection) {
+		bankCollectionName = collection;
+	}
+	
+	/**
+	 * Sets the name of the super-group folder containing all plots.
+	 * @param name - The name of the plots folder.
+	 */
+	public void setPlotsGroupName(String name) {
+		plotsGroupName = name;
+	}
+	
+	/**
+	 * Sets whether or not to skip events where the SVT was not in
+	 * position and active.
+	 * @param state - <code>true</code> indicates that only events
+	 * with an active, properly positioned SVT should be analyzed, and
+	 * <code>false</code> that all events will be included.
+	 */
+	public void setUseGoodSVT(boolean state) {
+		useGoodSVT = state;
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/TriggerProcessAnalysisDriver.java	Tue Sep 27 08:50:14 2016
@@ -9,11 +9,18 @@
 import java.util.List;
 import java.util.Set;
 
+import org.hps.analysis.trigger.SimTriggerData;
+import org.hps.analysis.trigger.data.TriggerDiagStats;
+import org.hps.analysis.trigger.util.OutputLogger;
 import org.hps.recon.tracking.TrackType;
 import org.hps.recon.tracking.TrackUtils;
+import org.hps.record.triggerbank.AbstractIntData;
+import org.hps.record.triggerbank.SSPData;
+import org.hps.record.triggerbank.TIData;
 import org.hps.record.triggerbank.TriggerModule;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
+import org.lcsim.event.GenericObject;
 import org.lcsim.event.ReconstructedParticle;
 import org.lcsim.event.RelationalTable;
 import org.lcsim.event.Track;
@@ -21,78 +28,245 @@
 import org.lcsim.util.aida.AIDA;
 
 public class TriggerProcessAnalysisDriver extends Driver {
-    private int eventsProcessed = 0;
-    private int mollersProcessed = 0; 
-    private boolean checkSVT = false;
-    private int tridentsProcessed = 0;
-    private int gblMollersProcessed = 0;
-    private int gblTridentsProcessed = 0;
-    private double timeCoincidence = 2.5;
-    private double elasticThreshold = 0.800;
-    private double mollerLowerRange = 0.900;
-    private double mollerUpperRange = 1.200;
-    private AIDA aida = AIDA.defaultInstance();
-    private boolean checkTriggerTimeWindow = false;
-    private String clusterCollectionName = "EcalClustersCorr";
-    private String particleCollectionName = "FinalStateParticles";
-    
-    // Define trident cluster-track matched condition plots.
-    private IHistogram1D trctmInvariantMass = aida.histogram1D("Tridents CTMatched/Invariant Mass", 140, 0.0, 0.070);
-    private IHistogram1D trctmInstancesInEvent = aida.histogram1D("Tridents CTMatched/Instances in Event", 9, 0.5, 9.5);
-    private IHistogram1D trctmEnergySum1D = aida.histogram1D("Tridents CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
-    private IHistogram1D trctmMomentumSum1D = aida.histogram1D("Tridents CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
-    private IHistogram1D trctmElectronEnergy = aida.histogram1D("Tridents CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
-    private IHistogram1D trctmElectronMomentum = aida.histogram1D("Tridents CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
-    private IHistogram1D trctmPositronEnergy = aida.histogram1D("Tridents CTMatched/Positron Cluster Energy", 150, 0.000, 1.500);
-    private IHistogram1D trctmPositronMomentum = aida.histogram1D("Tridents CTMatched/Positron Track Momentum", 150, 0.000, 1.500);
-    private IHistogram1D trctmTimeCoincidence = aida.histogram1D("Tridents CTMatched/Time Coincidence", 100, -4, 4);
-    private IHistogram2D trctmClusterPosition = aida.histogram2D("Tridents CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
-    private IHistogram2D trctmEnergySum2D = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-    private IHistogram2D trctmTrackPosition = aida.histogram2D("Tridents CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-    private IHistogram2D trctmMomentumSum2D = aida.histogram2D("Tridents CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-    private IHistogram2D trctmESumCoplanarity = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-    private IHistogram2D trctmPSumCoplanarity = aida.histogram2D("Tridents CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-    
-    // Define the Moller cluster-track matched condition plots.
-    private IHistogram1D moctmInvariantMass = aida.histogram1D("Moller CTMatched/Invariant Mass", 140, 0.0, 0.070);
-    private IHistogram1D moctmInstancesInEvent = aida.histogram1D("Moller CTMatched/Instances in Event", 9, 0.5, 9.5);
-    private IHistogram1D moctmEnergySum1D = aida.histogram1D("Moller CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
-    private IHistogram1D moctmMomentumSum1D = aida.histogram1D("Moller CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
-    private IHistogram1D moctmElectronEnergy = aida.histogram1D("Moller CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
-    private IHistogram1D moctmElectronMomentum = aida.histogram1D("Moller CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
-    private IHistogram1D moctmTimeCoincidence = aida.histogram1D("Moller CTMatched/Time Coincidence", 100, -4, 4);
-    private IHistogram2D moctmClusterPosition = aida.histogram2D("Moller CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
-    private IHistogram2D moctmEnergySum2D = aida.histogram2D("Moller CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-    private IHistogram2D moctmTrackPosition = aida.histogram2D("Moller CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-    private IHistogram2D moctmMomentumSum2D = aida.histogram2D("Moller CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-    private IHistogram2D moctmESumCoplanarity = aida.histogram2D("Moller CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-    private IHistogram2D moctmPSumCoplanarity = aida.histogram2D("Moller CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-    
-    // Define the Moller track-only condition plots.
-    private IHistogram1D mogblTimeCoincidence = aida.histogram1D("Moller Track-Only/Time Coincidence", 100, -4, 4);
-    private IHistogram1D mogblInvariantMass = aida.histogram1D("Moller Track-Only/Invariant Mass", 140, 0.0, 0.070);
-    private IHistogram1D mogblInstancesInEvent = aida.histogram1D("Moller Track-Only/Instances in Event", 9, 0.5, 9.5);
-    private IHistogram1D mogblMomentumSum1D = aida.histogram1D("Moller Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
-    private IHistogram1D mogblElectronMomentum = aida.histogram1D("Moller Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
-    private IHistogram2D mogblTrackPosition = aida.histogram2D("Moller Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-    private IHistogram2D mogblMomentumSum2D = aida.histogram2D("Moller Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-    private IHistogram2D mogblPSumCoplanarity = aida.histogram2D("Moller Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-    
-    // Define the GBL trident condition plots.
-    private IHistogram1D trgblInvariantMass = aida.histogram1D("Tridents Track-Only/Invariant Mass", 140, 0.0, 0.070);
-    private IHistogram1D trgblInstancesInEvent = aida.histogram1D("Tridents Track-Only/Instances in Event", 9, 0.5, 9.5);
-    private IHistogram1D trgblMomentumSum1D = aida.histogram1D("Tridents Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
-    private IHistogram1D trgblElectronMomentum = aida.histogram1D("Tridents Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
-    private IHistogram1D trgblPositronMomentum = aida.histogram1D("Tridents Track-Only/Positron Track Momentum", 150, 0.000, 1.500);
-    private IHistogram1D trgblTimeCoincidence = aida.histogram1D("Tridents Track-Only/Time Coincidence", 100, -4, 4);
-    private IHistogram2D trgblTrackPosition = aida.histogram2D("Tridents Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
-    private IHistogram2D trgblMomentumSum2D = aida.histogram2D("Tridents Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
-    private IHistogram2D trgblPSumCoplanarity = aida.histogram2D("Tridents Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
-    
-    @Override
-    public void endOfData() {
-        // Calculate the scaling factor for Hertz.
-        double scale = 19000.0 / eventsProcessed;
+	private int eventsProcessed = 0;
+	private int møllersProcessed = 0;
+	private boolean checkSVT = false;
+	private int tridentsProcessed = 0;
+	private int gblMøllersProcessed = 0;
+	private int gblTridentsProcessed = 0;
+	private int vertexedMøllersProcessed = 0;
+	private int vertexedTridentsProcessed = 0;
+	private double timeCoincidence = 2.5;
+	private double elasticThreshold = 0.900;
+	private double møllerLowerRange = 0.800;
+	private double møllerUpperRange = 1.300;
+	private AIDA aida = AIDA.defaultInstance();
+	private boolean checkTriggerTimeWindow = false;
+	private String bankCollectionName = "TriggerBank";
+	private String clusterCollectionName = "EcalClustersCorr";
+	private String particleCollectionName = "FinalStateParticles";
+	private String møllerCollectionName = "UnconstrainedMollerCandidates";
+	private String tridentCollectionName = "TargetConstrainedV0Candidates";
+	
+	// Track how many events pass each trigger configuration.
+	private int triggerActiveEvents = 0;
+	private int[][][][][] ctmTriggerMøllers = new int[2][2][2][2][2];
+	private int[][][][][] vtxTriggerMøllers = new int[2][2][2][2][2];
+	private int[][][][][] ctmTriggerTridents = new int[2][2][2][2][2];
+	private int[][][][][] vtxTriggerTridents = new int[2][2][2][2][2];
+	
+	// Define Møller cut constants.
+	/*
+	private static final int LOW = 0;
+	private static final int HIGH = 1;
+	private static final double[] MØLLER_ANGLE_THRESHOLD = {
+			(1 - 0.40) * 0.5109989 / (2 * 1056),
+			(1 + 0.40) * 0.5109989 / (2 * 1056)
+	};
+	private static final double[] MØLLER_ENERGY_THRESHOLD = {
+			(1 - 0.15) * 1.056,
+			(1 + 0.15) * 1.056
+	};
+	private static final double BEAM_ROTATION = -0.0305;
+	private static final double ELECTRON_MASS_2 = 0.0005109989 * 0.0005109989;
+	*/
+	
+	// Define trident cluster-track matched condition plots.
+	private IHistogram1D trctmInvariantMass = aida.histogram1D("Tridents CTMatched/Invariant Mass", 140, 0.0, 0.070);
+	private IHistogram1D trctmInstancesInEvent = aida.histogram1D("Tridents CTMatched/Instances in Event", 9, 0.5, 9.5);
+	private IHistogram1D trctmEnergySum1D = aida.histogram1D("Tridents CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
+	private IHistogram1D trctmMomentumSum1D = aida.histogram1D("Tridents CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
+	private IHistogram1D trctmElectronEnergy = aida.histogram1D("Tridents CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
+	private IHistogram1D trctmElectronMomentum = aida.histogram1D("Tridents CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D trctmPositronEnergy = aida.histogram1D("Tridents CTMatched/Positron Cluster Energy", 150, 0.000, 1.500);
+	private IHistogram1D trctmPositronMomentum = aida.histogram1D("Tridents CTMatched/Positron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D trctmTimeCoincidence = aida.histogram1D("Tridents CTMatched/Time Coincidence", 100, -4, 4);
+	private IHistogram2D trctmClusterPosition = aida.histogram2D("Tridents CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
+	private IHistogram2D trctmEnergySum2D = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D trctmTrackPosition = aida.histogram2D("Tridents CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+	private IHistogram2D trctmMomentumSum2D = aida.histogram2D("Tridents CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D trctmESumCoplanarity = aida.histogram2D("Tridents CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	private IHistogram2D trctmPSumCoplanarity = aida.histogram2D("Tridents CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	
+	// Define trident vertexed condition plots.
+	private IHistogram1D trvtxInvariantMass = aida.histogram1D("Tridents Vertexed/Invariant Mass", 140, 0.0, 0.070);
+	private IHistogram1D trvtxInstancesInEvent = aida.histogram1D("Tridents Vertexed/Instances in Event", 9, 0.5, 9.5);
+	private IHistogram1D trvtxEnergySum1D = aida.histogram1D("Tridents Vertexed/Cluster Energy Sum", 150, 0.000, 1.500);
+	private IHistogram1D trvtxMomentumSum1D = aida.histogram1D("Tridents Vertexed/Track Momentum Sum", 150, 0.000, 1.500);
+	private IHistogram1D trvtxElectronEnergy = aida.histogram1D("Tridents Vertexed/Electron Cluster Energy", 150, 0.000, 1.500);
+	private IHistogram1D trvtxElectronMomentum = aida.histogram1D("Tridents Vertexed/Electron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D trvtxPositronEnergy = aida.histogram1D("Tridents Vertexed/Positron Cluster Energy", 150, 0.000, 1.500);
+	private IHistogram1D trvtxPositronMomentum = aida.histogram1D("Tridents Vertexed/Positron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D trvtxTimeCoincidence = aida.histogram1D("Tridents Vertexed/Time Coincidence", 100, -4, 4);
+	private IHistogram2D trvtxClusterPosition = aida.histogram2D("Tridents Vertexed/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
+	private IHistogram2D trvtxEnergySum2D = aida.histogram2D("Tridents Vertexed/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D trvtxTrackPosition = aida.histogram2D("Tridents Vertexed/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+	private IHistogram2D trvtxMomentumSum2D = aida.histogram2D("Tridents Vertexed/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D trvtxESumCoplanarity = aida.histogram2D("Tridents Vertexed/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	private IHistogram2D trvtxPSumCoplanarity = aida.histogram2D("Tridents Vertexed/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	private IHistogram1D trvtxChiSquared = aida.histogram1D("Tridents Vertexed/Chi Squared", 1000, 0.0, 1000.0);
+	
+	// Define the Møller cluster-track matched condition plots.
+	private IHistogram1D møctmInvariantMass = aida.histogram1D("Møller CTMatched/Invariant Mass", 140, 0.0, 0.070);
+	private IHistogram1D møctmInstancesInEvent = aida.histogram1D("Møller CTMatched/Instances in Event", 9, 0.5, 9.5);
+	private IHistogram1D møctmEnergySum1D = aida.histogram1D("Møller CTMatched/Cluster Energy Sum", 150, 0.000, 1.500);
+	private IHistogram1D møctmMomentumSum1D = aida.histogram1D("Møller CTMatched/Track Momentum Sum", 150, 0.000, 1.500);
+	private IHistogram1D møctmElectronEnergy = aida.histogram1D("Møller CTMatched/Electron Cluster Energy", 150, 0.000, 1.500);
+	private IHistogram1D møctmElectronMomentum = aida.histogram1D("Møller CTMatched/Electron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D møctmTimeCoincidence = aida.histogram1D("Møller CTMatched/Time Coincidence", 100, -4, 4);
+	private IHistogram2D møctmClusterPosition = aida.histogram2D("Møller CTMatched/Cluster Seed Position", 46, -23, 23, 11, -5.5, 5.5);
+	private IHistogram2D møctmEnergySum2D = aida.histogram2D("Møller CTMatched/Cluster Energy Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D møctmTrackPosition = aida.histogram2D("Møller CTMatched/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+	private IHistogram2D møctmMomentumSum2D = aida.histogram2D("Møller CTMatched/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D møctmESumCoplanarity = aida.histogram2D("Møller CTMatched/Cluster Energy Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	private IHistogram2D møctmPSumCoplanarity = aida.histogram2D("Møller CTMatched/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	
+	// Define the Møller track-only condition plots.
+	private IHistogram1D møgblTimeCoincidence = aida.histogram1D("Møller Track-Only/Time Coincidence", 100, -4, 4);
+	private IHistogram1D møgblInvariantMass = aida.histogram1D("Møller Track-Only/Invariant Mass", 140, 0.0, 0.070);
+	private IHistogram1D møgblInstancesInEvent = aida.histogram1D("Møller Track-Only/Instances in Event", 9, 0.5, 9.5);
+	private IHistogram1D møgblMomentumSum1D = aida.histogram1D("Møller Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
+	private IHistogram1D møgblElectronMomentum = aida.histogram1D("Møller Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram2D møgblTrackPosition = aida.histogram2D("Møller Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+	private IHistogram2D møgblMomentumSum2D = aida.histogram2D("Møller Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D møgblPSumCoplanarity = aida.histogram2D("Møller Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	
+	// Define the Møller vertexed condition plots.
+	private IHistogram1D møvtxTimeCoincidence = aida.histogram1D("Møller Vertexed/Time Coincidence", 100, -4, 4);
+	private IHistogram1D møvtxInvariantMass = aida.histogram1D("Møller Vertexed/Invariant Mass", 140, 0.0, 0.070);
+	private IHistogram1D møvtxInstancesInEvent = aida.histogram1D("Møller Vertexed/Instances in Event", 9, 0.5, 9.5);
+	private IHistogram1D møvtxMomentumSum1D = aida.histogram1D("Møller Vertexed/Track Momentum Sum", 150, 0.000, 1.500);
+	private IHistogram1D møvtxElectronMomentum = aida.histogram1D("Møller Vertexed/Electron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram2D møvtxTrackPosition = aida.histogram2D("Møller Vertexed/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+	private IHistogram2D møvtxMomentumSum2D = aida.histogram2D("Møller Vertexed/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D møvtxPSumCoplanarity = aida.histogram2D("Møller Vertexed/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	
+	// Define the GBL trident condition plots.
+	private IHistogram1D trgblInvariantMass = aida.histogram1D("Tridents Track-Only/Invariant Mass", 140, 0.0, 0.070);
+	private IHistogram1D trgblInstancesInEvent = aida.histogram1D("Tridents Track-Only/Instances in Event", 9, 0.5, 9.5);
+	private IHistogram1D trgblMomentumSum1D = aida.histogram1D("Tridents Track-Only/Track Momentum Sum", 150, 0.000, 1.500);
+	private IHistogram1D trgblElectronMomentum = aida.histogram1D("Tridents Track-Only/Electron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D trgblPositronMomentum = aida.histogram1D("Tridents Track-Only/Positron Track Momentum", 150, 0.000, 1.500);
+	private IHistogram1D trgblTimeCoincidence = aida.histogram1D("Tridents Track-Only/Time Coincidence", 100, -4, 4);
+	private IHistogram2D trgblTrackPosition = aida.histogram2D("Tridents Track-Only/Extrapolated Track Position", 200, -400, 400, 55, -110, 110);
+	private IHistogram2D trgblMomentumSum2D = aida.histogram2D("Tridents Track-Only/Track Momentum Sum 2D", 300, 0.000, 1.500, 300, 0.000, 1.500);
+	private IHistogram2D trgblPSumCoplanarity = aida.histogram2D("Tridents Track-Only/Track Momentum Sum vs. Coplanarity", 300, 0.000, 1.500, 360, 0, 360);
+	
+	@Override
+	public void endOfData() {
+		// Calculate the scaling factor for Hertz.
+		double scale = 19000.0 / eventsProcessed;
+		
+		System.out.println("Processed " + eventsProcessed + " events.");
+		System.out.println("Processed " + møllersProcessed + " Møller events");
+		System.out.println("\tAcceptance :: " + (100.0 * møllersProcessed / eventsProcessed) + "%");
+		System.out.println("\tRate       :: " + (møllersProcessed * scale) + " Hz");
+		
+		System.out.println("Processed " + tridentsProcessed + " trident events");
+		System.out.println("\tAcceptance :: " + (100.0 * tridentsProcessed / eventsProcessed) + "%");
+		System.out.println("\tRate       :: " + (tridentsProcessed * scale) + " Hz");
+		
+		/*
+		System.out.println("Processed " + gblMøllersProcessed + " track-only Møller events");
+		System.out.println("\tAcceptance :: " + (100.0 * gblMøllersProcessed / eventsProcessed) + "%");
+		System.out.println("\tRate       :: " + (gblMøllersProcessed * scale) + " Hz");
+		
+		System.out.println("Processed " + gblTridentsProcessed + " track-only trident events");
+		System.out.println("\tAcceptance :: " + (100.0 * gblTridentsProcessed / eventsProcessed) + "%");
+		System.out.println("\tRate       :: " + (gblTridentsProcessed * scale) + " Hz");
+		*/
+		
+		System.out.println("Processed " + vertexedMøllersProcessed + " vertexed Møller events");
+		System.out.println("\tAcceptance :: " + (100.0 * vertexedMøllersProcessed / eventsProcessed) + "%");
+		System.out.println("\tRate       :: " + (vertexedMøllersProcessed * scale) + " Hz");
+		
+		System.out.println("Processed " + vertexedTridentsProcessed + " vertexed trident events");
+		System.out.println("\tAcceptance :: " + (100.0 * vertexedTridentsProcessed / eventsProcessed) + "%");
+		System.out.println("\tRate       :: " + (vertexedTridentsProcessed * scale) + " Hz");
+		
+		
+		System.out.println("CTM Møllers:");
+		for(int pulser = 0; pulser < 2; pulser++) {
+			for(int singles0 = 0; singles0 < 2; singles0++) {
+				for(int singles1 = 0; singles1 < 2; singles1++) {
+					for(int pair0 = 0; pair0 < 2; pair0++) {
+						for(int pair1 = 0; pair1 < 2; pair1++) {
+							System.out.printf("\t%5b  %5b  %5b  %5b  %5b  %d%n",
+									pulser == 1 ? true : false, singles0 == 1 ? true : false,
+									singles1 == 1 ? true : false, pair0 == 1 ? true : false,
+									pair1 == 1 ? true : false, ctmTriggerMøllers[pulser][singles0][singles1][pair0][pair1]);
+						}
+					}
+				}
+			}
+		}
+		
+		System.out.println("CTM Tridents:");
+		for(int pulser = 0; pulser < 2; pulser++) {
+			for(int singles0 = 0; singles0 < 2; singles0++) {
+				for(int singles1 = 0; singles1 < 2; singles1++) {
+					for(int pair0 = 0; pair0 < 2; pair0++) {
+						for(int pair1 = 0; pair1 < 2; pair1++) {
+							System.out.printf("\t%5b  %5b  %5b  %5b  %5b  %d%n",
+									pulser == 1 ? true : false, singles0 == 1 ? true : false,
+									singles1 == 1 ? true : false, pair0 == 1 ? true : false,
+									pair1 == 1 ? true : false, ctmTriggerTridents[pulser][singles0][singles1][pair0][pair1]);
+						}
+					}
+				}
+			}
+		}
+		
+		System.out.println("VTX Møllers:");
+		for(int pulser = 0; pulser < 2; pulser++) {
+			for(int singles0 = 0; singles0 < 2; singles0++) {
+				for(int singles1 = 0; singles1 < 2; singles1++) {
+					for(int pair0 = 0; pair0 < 2; pair0++) {
+						for(int pair1 = 0; pair1 < 2; pair1++) {
+							System.out.printf("\t%5b  %5b  %5b  %5b  %5b  %d%n",
+									pulser == 1 ? true : false, singles0 == 1 ? true : false,
+									singles1 == 1 ? true : false, pair0 == 1 ? true : false,
+									pair1 == 1 ? true : false, vtxTriggerMøllers[pulser][singles0][singles1][pair0][pair1]);
+						}
+					}
+				}
+			}
+		}
+		
+		System.out.println("VTX Tridents:");
+		for(int pulser = 0; pulser < 2; pulser++) {
+			for(int singles0 = 0; singles0 < 2; singles0++) {
+				for(int singles1 = 0; singles1 < 2; singles1++) {
+					for(int pair0 = 0; pair0 < 2; pair0++) {
+						for(int pair1 = 0; pair1 < 2; pair1++) {
+							System.out.printf("\t%5b  %5b  %5b  %5b  %5b  %d%n",
+									pulser == 1 ? true : false, singles0 == 1 ? true : false,
+									singles1 == 1 ? true : false, pair0 == 1 ? true : false,
+									pair1 == 1 ? true : false, vtxTriggerTridents[pulser][singles0][singles1][pair0][pair1]);
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	/**
+	@Override
+	public void process(EventHeader event) {
+		// Check whether the SVT was active in this event and, if so,
+		// skip it. This can be disabled through the steering file for
+		// Monte Carlo data, where the "SVT" is always active.
+		if(checkSVT) {
+			final String[] flagNames = { "svt_bias_good", "svt_burstmode_noise_good", "svt_position_good" };
+			boolean svtGood = true;
+	        for(int i = 0; i < flagNames.length; i++) {
+	            int[] flag = event.getIntegerParameters().get(flagNames[i]);
+	            if(flag == null || flag[0] == 0) {
+	                svtGood = false;
+	            }
+	        }
+	        if(!svtGood) { return; }
+		}
         
         System.out.println("Processed " + eventsProcessed + " events.");
         System.out.println("Processed " + mollersProcessed + " Moller events");
@@ -110,7 +284,7 @@
         System.out.println("Processed " + gblTridentsProcessed + " Rafo trident events");
         System.out.println("\tAcceptance :: " + (100.0 * gblTridentsProcessed / eventsProcessed) + "%");
         System.out.println("\tRate       :: " + (gblTridentsProcessed * scale) + " Hz");
-    }
+    }**/
     
 /*
     @Override
@@ -171,583 +345,870 @@
         
         // Check if the event has a collection of tracks. If it exists,
         // extract it. Otherwise, skip the event.
-        if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
-            return;
-        }
-        List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
-        
-        // Check if the event has a collection of clusters. If it
-        // exists, extract it. Otherwise, skip the event.
-        if(!event.hasCollection(Cluster.class, clusterCollectionName)) {
-            return;
-        }
-        List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
-        
-        // Get cluster-track matched top/bottom pairs.
-        List<ReconstructedParticle[]> gblMatchedPairs = getTopBottomTracksGBL(trackList);
-        List<ReconstructedParticle[]> ctMatchedPairs  = getTopBottomTracksCTMatched(trackList);
-        
-        System.out.println("CTM Pairs :: " + ctMatchedPairs.size());
-        System.out.println("GBL Pairs :: " + gblMatchedPairs.size());
-        
-        // Get the trident and Moller tracks for the matched track
-        // and cluster pair condition sets.
-        List<ReconstructedParticle[]> mollers     = getMollerTracksCTMatched(ctMatchedPairs);
-        List<ReconstructedParticle[]> mollersGBL  = getMollerTracksGBL(gblMatchedPairs, event);
-        List<ReconstructedParticle[]> tridents    = getTridentTracksCTMatched(ctMatchedPairs);
-        List<ReconstructedParticle[]> tridentsGBL = getTridentClustersGBL(gblMatchedPairs, TriggerModule.getTopBottomPairs(clusterList, Cluster.class), event);
-        
-        // Track how many events had tridents and Mollers.
-        if(!mollers.isEmpty()) { mollersProcessed++; }
-        if(!tridents.isEmpty()) { tridentsProcessed++; }
-        if(!mollersGBL.isEmpty()) { gblMollersProcessed++; }
-        if(!tridentsGBL.isEmpty()) { gblTridentsProcessed++; }
-        
-        // Produce Moller cluster-track matched plots.
-        moctmInstancesInEvent.fill(mollers.size());
-        for(ReconstructedParticle[] pair : mollers) {
-            // Get the track clusters.
-            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-            
-            // Populate the cluster plots.
-            moctmElectronEnergy.fill(trackClusters[0].getEnergy());
-            moctmElectronEnergy.fill(trackClusters[1].getEnergy());
-            moctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
-            moctmEnergySum2D.fill(trackClusters[0].getEnergy(), trackClusters[1].getEnergy());
-            moctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
-            moctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
-            moctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
-            moctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
-            
-            // Populate the momentum plots.
-            moctmInvariantMass.fill(getInvariantMass(pair));
-            moctmElectronMomentum.fill(pair[0].getMomentum().magnitude());
-            moctmElectronMomentum.fill(pair[1].getMomentum().magnitude());
-            moctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-            moctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-            moctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-            moctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-            moctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-        }
-        
-        // Produce trident cluster-track matched plots.
-        trctmInstancesInEvent.fill(tridents.size());
-        for(ReconstructedParticle[] pair : tridents) {
-            // Get the electron and positron tracks.
-            ReconstructedParticle electronTrack = pair[pair[0].getCharge() < 0 ? 0 : 1];
-            ReconstructedParticle positronTrack = pair[pair[0].getCharge() > 0 ? 0 : 1];
-            
-            // Get the track clusters.
-            Cluster electronCluster = electronTrack.getClusters().get(0);
-            Cluster positronCluster = positronTrack.getClusters().get(0);
-            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-            
-            // Populate the cluster plots.
-            trctmElectronEnergy.fill(electronCluster.getEnergy());
-            trctmPositronEnergy.fill(positronCluster.getEnergy());
-            trctmEnergySum2D.fill(pair[0].getEnergy(), pair[1].getEnergy());
-            trctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
-            trctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
-            trctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
-            trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
-            trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
-            
-            // Populate the momentum plots.
-            trctmInvariantMass.fill(getInvariantMass(pair));
-            trctmElectronMomentum.fill(electronTrack.getMomentum().magnitude());
-            trctmPositronMomentum.fill(positronTrack.getMomentum().magnitude());
-            trctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-            trctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-            trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-            trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-            trctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-        }
-        
-        // Produce the Moller track-only plots.
-        mogblInstancesInEvent.fill(mollersGBL.size());
-        RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
-        RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
-        for(ReconstructedParticle pair[] : mollersGBL) {
-            // Get the tracks and track times.
-            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-            double times[] = {
-                    TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
-                    TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)    
-            };
-            
-            // Fill the plots.
-            mogblTimeCoincidence.fill(times[0] - times[1]);
-            mogblInvariantMass.fill(getInvariantMass(pair));
-            mogblElectronMomentum.fill(pair[0].getMomentum().magnitude());
-            mogblElectronMomentum.fill(pair[1].getMomentum().magnitude());
-            mogblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-            mogblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-            mogblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-            mogblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-            mogblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-        }
-        
-        // Produce track-only trident plots.
-        trgblInstancesInEvent.fill(tridentsGBL.size());
-        for(ReconstructedParticle[] pair : tridentsGBL) {
-            // Get the tracks and track times.
-            Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
-            double times[] = {
-                    TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
-                    TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)    
-            };
-            
-            // Get the positron and the electron.
-            ReconstructedParticle positron = pair[0].getCharge() > 0 ? pair[0] : pair[1];
-            ReconstructedParticle electron = pair[0].getCharge() < 0 ? pair[0] : pair[1];
-            
-            // Fill the plots.
-            trgblTimeCoincidence.fill(times[0] - times[1]);
-            trgblInvariantMass.fill(getInvariantMass(pair));
-            trgblElectronMomentum.fill(electron.getMomentum().magnitude());
-            trgblPositronMomentum.fill(positron.getMomentum().magnitude());
-            trgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
-            trgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
-            trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
-            trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
-            trgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
-                    getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
-        }
-    }
-    
-    public void setCheckSVT(boolean state) {
-        checkSVT = state;
-    }
-    
-    public void setCheckTriggerTimeWindow(boolean state) {
-        checkTriggerTimeWindow = state;
-    }
-    
-    /**
-     * Gets a list of all possible GBL top/bottom track pairs. These
-     * tracks are not guaranteed to have a matched cluster.
-     * @param trackList - A list of all possible tracks.
-     * @return Returns a list of track pairs.
-     */
-    private static final List<ReconstructedParticle[]> getTopBottomTracksGBL(List<ReconstructedParticle> trackList) {
-        // Separate the tracks into top and bottom tracks based on
-        // the value of tan(Λ). Use only GBL tracks to avoid track
-        // duplication.
-        List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
-        List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
-        trackLoop:
-        for(ReconstructedParticle track : trackList) {
-            // Require that the ReconstructedParticle contain an actual
-            // Track object.
-            if(track.getTracks().isEmpty()) {
-                continue trackLoop;
-            }
-            
-            // Ignore tracks that are not GBL tracks.
-            if(!TrackType.isGBL(track.getType())) {
-                continue trackLoop;
-            }
-            
-            // If the above tests pass, the ReconstructedParticle has
-            // a track and is also a GBL track. Separate it into either
-            // a top or a bottom track based on its tan(Λ) value.
-            if(track.getTracks().get(0).getTrackStates().get(0).getTanLambda() > 0) {
-                topTracks.add(track);
-            } else {
-                botTracks.add(track);
-            }
-        }
-        
-        // Form all top/bottom pairs with the unique tracks.
-        List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
-        for(ReconstructedParticle topTrack : topTracks) {
-            for(ReconstructedParticle botTrack : botTracks) {
-                pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
-            }
-        }
-        
-        // Return the result.
-        return pairList;
-    }
-    
-    /**
-     * Produces pairs of tracks. The track pairs are required to be
-     * matched to a cluster and the associated clusters must form a
-     * top/bottom pair. If more than one track points to the same
-     * cluster, only the first track is retained.
-     * @param trackList - A list of all tracks.
-     * @return Returns a list of track pairs meeting the aforementioned
-     * conditions.
-     */
-    private static final List<ReconstructedParticle[]> getTopBottomTracksCTMatched(List<ReconstructedParticle> trackList) {
-        // Track clusters that have already been seen to prevent clusters
-        // that have duplicate tracks from reappearing.
-        Set<Cluster> clusterSet = new HashSet<Cluster>();
-        
-        // Separate the tracks into top and bottom tracks based on
-        // the track cluster. Filter out tracks with no clusters.
-        List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
-        List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
-        trackLoop:
-        for(ReconstructedParticle track : trackList) {
-            // Check if the track has a cluster. If not, skip it.
-            if(track.getClusters().isEmpty()) {
-                continue trackLoop;
-            }
-            
-            // If the track doesn't have actual tracks, skip it.
-            if(track.getTracks().isEmpty()) {
-                continue trackLoop;
-            }
-            
-            // Check if the track cluster has already seen.
-            Cluster trackCluster = track.getClusters().get(0);
-            if(clusterSet.contains(trackCluster)) {
-                continue trackLoop;
-            }
-            
-            // If the track has a unique cluster, add it to the proper
-            // list based on the cluster y-index.
-            clusterSet.add(trackCluster);
-            if(TriggerModule.getClusterYIndex(trackCluster) > 0) {
-                topTracks.add(track);
-            } else {
-                botTracks.add(track);
-            }
-        }
-        
-        // Form all top/bottom pairs with the unique tracks.
-        List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
-        for(ReconstructedParticle topTrack : topTracks) {
-            for(ReconstructedParticle botTrack : botTracks) {
-                pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
-            }
-        }
-        
-        // Return the result.
-        return pairList;
-    }
-    
-    private final List<ReconstructedParticle[]> getTridentClustersGBL(List<ReconstructedParticle[]> pairList, List<Cluster[]> clusterList, EventHeader event) {
-        // Store the set of track pairs that meet the trident condition.
-        List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
-        
-        // Extract track relational tables from the event object.
-        RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
-        RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
-        
-        // Tracks will not be considered for trident analysis unless there
-        // is at least one top/bottom cluster pair within the time window.
-        boolean passesClusterCondition = false;
-        tridentClusterLoop:
-        for(Cluster[] pair : clusterList) {
-            // Ignore clusters that are too far apart temporally.
-            if(TriggerModule.getValueTimeCoincidence(pair) > timeCoincidence) {
-                continue tridentClusterLoop;
-            }
-            
-            // Require that the cluster pair be top/bottom.
-            boolean hasTop = TriggerModule.getClusterYIndex(pair[0]) > 0 || TriggerModule.getClusterYIndex(pair[1]) > 0;
-            boolean hasBot = TriggerModule.getClusterYIndex(pair[0]) < 0 || TriggerModule.getClusterYIndex(pair[1]) < 0;
-            if(!hasTop || !hasBot) {
-                continue tridentClusterLoop;
-            }
-            
-            // If the cluster passes, mark that it has done so and skip
-            // the rest. Only one pair need pass.
-            passesClusterCondition = true;
-            break tridentClusterLoop;
-        }
-        
-        // If no cluster pair passed the cluster condition, no tracks
-        // are allowed to pass either.
-        if(!passesClusterCondition) {
-            return tridentTracks;
-        }
-        
-        // Next, check the track pair list. A track pair must have a
-        // positive and a negative track and must also be within the
-        // time coincidence window.
-        tridentTrackLoop:
-        for(ReconstructedParticle[] pair : pairList) {
-            // Check that there is at least one positive and one negative
-            // track in the pair.
-            boolean hasPositive = pair[0].getCharge() > 0 || pair[1].getCharge() > 0;
-            boolean hasNegative = pair[0].getCharge() < 0 || pair[1].getCharge() < 0;
-            if(!hasPositive || !hasNegative) {
-                break tridentTrackLoop;
-            }
-            
-            // Check that the track pair passes the time cut.
-            double times[] = {
-                TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
-                TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)    
-            };
-            
-            if(Math.abs(times[0] - times[1]) > timeCoincidence) {
-                continue tridentTrackLoop;
-            }
-            
-            // Require that the negative track have less than the
-            // elastic threshold momentum to exclude elastic electrons.
-            if(pair[0].getCharge() < 0 && pair[0].getMomentum().magnitude() > elasticThreshold
-                    || pair[1].getCharge() < 0 && pair[1].getMomentum().magnitude() > elasticThreshold) {
-                continue tridentTrackLoop;
-            }
-            
-            // If the track passes both, it is considered a trident pair.
-            tridentTracks.add(pair);
-        }
-        
-        // Return the resultant pairs.
-        return tridentTracks;
-    }
-    
-    /**
-     * Gets a list track pairs that meet the trident condition defined
-     * using tracks with matched calorimeter clusters. A pair meets the
-     * cluster/track matched trident condition is it meets the following:
-     * <ul><li>Both tracks have matched clusters.</li>
-     * <li>Has one positive track.</li>
-     * <li>Has one negative track.</li>
-     * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
-     * <li>The electron momentum is below 900 MeV.</li></ul>
-     * @param pairList - A <code>List</code> collection of parameterized
-     * type <code>ReconstructedParticle[]</code> containing all valid
-     * top/bottom pairs of tracks with matched clusters. These will be
-     * tested to see if they meet the process criteria.
-     * @return Returns a list containing pairs of tracks that meet the
-     * trident condition.
-     */
-    private final List<ReconstructedParticle[]> getTridentTracksCTMatched(List<ReconstructedParticle[]> pairList) {
-        // Store the set of track pairs that meet the trident condition.
-        List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
-        
-        // Loop over the filtered pair list and apply the trident
-        // condition test.
-        tridentLoop:
-        for(ReconstructedParticle[] pair : pairList) {
-            // There must be one positive and one negative track.
-            ReconstructedParticle electron = null;
-            ReconstructedParticle positron = null;
-            if(pair[0].getCharge() > 0) { positron = pair[0]; }
-            else if(pair[1].getCharge() > 0) { positron = pair[1]; }
-            if(pair[0].getCharge() < 0) { electron = pair[0]; }
-            else if(pair[1].getCharge() < 0) { electron = pair[1]; }
-            if(electron == null || positron == null) {
-                continue tridentLoop;
-            }
-            
-            // Make sure that the clusters are not the same. This should
-            // not actually ever be possible...
-            if(pair[0].getClusters().get(0) == pair[1].getClusters().get(0)) {
-                continue tridentLoop;
-            }
-            
-            // The clusters must within a limited time window.
-            /*
-            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-            if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
-                continue tridentLoop;
-            }
-            */
-            
-            // The clusters must be coincidental within an energy
-            // dependent coincidence window.
-            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-            if(!isCoincidental(trackClusters)) {
-                continue tridentLoop;
-            }
-            
-            // Require that the electron in the pair have an energy
-            // below the elastic threshold to exclude elastic electrons.
-            if(electron.getMomentum().magnitude() >= elasticThreshold) {
-                continue tridentLoop;
-            }
-            
-            // Require that all clusters occur within the trigger time
-            // window to exclude accidentals.
-            if(checkTriggerTimeWindow) {
-                if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
-                    continue tridentLoop;
-                }
-            }
-            
-            // If all the above conditions are met, the pair is to be
-            // considered a trident pair. Add it to the list.
-            tridentTracks.add(pair);
-        }
-        
-        // Return the list of pairs that passed the condition.
-        return tridentTracks;
-    }
-    
-    private final List<ReconstructedParticle[]> getMollerTracksGBL(List<ReconstructedParticle[]> pairList, EventHeader event) {
-        // Store the set of track pairs that meet the Moller condition.
-        List<ReconstructedParticle[]> mollerTracks = new ArrayList<ReconstructedParticle[]>();
-        
-        // Extract track relational tables from the event object.
-        RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
-        RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
-        
-        // Loop over the filtered pair list and apply the Moller
-        // condition test.
-        mollerLoop:
-        for(ReconstructedParticle[] pair : pairList) {
-            // Both tracks must be negatively charged.
-            if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
-                continue mollerLoop;
-            }
-            
-            // The clusters must within a limited time window.
-            double times[] = {
-                TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
-                TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)    
-            };
-            
-            if(Math.abs(times[0] - times[1]) > timeCoincidence) {
-                continue mollerLoop;
-            }
-            
-            // Require that the electrons in the pair have energies
-            // below the elastic threshold to exclude said electrons.
-            if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
-                continue mollerLoop;
-            }
-            
-            // Require that the energy of the pair be within a range
-            // that is sufficiently "Moller-like."
-            double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
-            if(momentumSum < mollerLowerRange || momentumSum > mollerUpperRange) {
-                continue mollerLoop;
-            }
-            
-            // If all the above conditions are met, the pair is to be
-            // considered a trident pair. Add it to the list.
-            mollerTracks.add(pair);
-        }
-        
-        // Return the list of pairs that passed the condition.
-        return mollerTracks;
-    }
-    
-    /**
-     * Gets a list track pairs that meet the Moller condition defined
-     * using tracks with matched calorimeter clusters. A pair meets the
-     * cluster/track matched Moller condition is it meets the following:
-     * <ul><li>Both tracks have matched clusters.</li>
-     * <li>Both tracks are negative.</li>
-     * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
-     * <li>The electron momenta are below 900 MeV.</li>
-     * <li>The momentum sum of the tracks is in the range <code>800 MeV
-     * ≤ p1 + p2 ≤ 1500 MeV</li></ul>
-     * @param pairList - A <code>List</code> collection of parameterized
-     * type <code>ReconstructedParticle[]</code> containing all valid
-     * top/bottom pairs of tracks with matched clusters. These will be
-     * tested to see if they meet the process criteria.
-     * @return Returns a list containing pairs of tracks that meet the
-     * Moller condition.
-     */
-    private final List<ReconstructedParticle[]> getMollerTracksCTMatched(List<ReconstructedParticle[]> pairList) {
-        // Store the set of track pairs that meet the Moller condition.
-        List<ReconstructedParticle[]> mollerTracks = new ArrayList<ReconstructedParticle[]>();
-        
-        // Loop over the filtered pair list and apply the Moller
-        // condition test.
-        mollerLoop:
-        for(ReconstructedParticle[] pair : pairList) {
-            // Both tracks must be negatively charged.
-            if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
-                continue mollerLoop;
-            }
-            
-            // The clusters must within a limited time window.
-            /*
-            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-            if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
-                continue mollerLoop;
-            }
-            */
-            
-            // The clusters must be coincidental within an energy
-            // dependent coincidence window.
-            Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
-            if(!isCoincidental(trackClusters)) {
-                continue mollerLoop;
-            }
-            
-            // Require that the electrons in the pair have energies
-            // below the elastic threshold to exclude said electrons.
-            if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
-                continue mollerLoop;
-            }
-            
-            // Require that the energy of the pair be within a range
-            // that is sufficiently "Moller-like."
-            double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
-            if(momentumSum < mollerLowerRange || momentumSum > mollerUpperRange) {
-                continue mollerLoop;
-            }
-            
-            // Require that all clusters occur within the trigger time
-            // window to exclude accidentals.
-            if(checkTriggerTimeWindow) {
-                if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
-                    continue mollerLoop;
-                }
-            }
-            
-            // If all the above conditions are met, the pair is to be
-            // considered a trident pair. Add it to the list.
-            mollerTracks.add(pair);
-        }
-        
-        // Return the list of pairs that passed the condition.
-        return mollerTracks;
-    }
-    
-    /**
-     * Calculates the approximate invariant mass for a pair of tracks
-     * from their momentum. This assumes that the particles are either
-     * electrons or positrons, and thusly have a sufficiently small
-     * mass term that it can be safely excluded.
-     * @param pair - The track pair for which to calculate the invariant
-     * mass.
-     * @return Returns the approximate invariant mass in units of GeV.
-     */
-    private static final double getInvariantMass(ReconstructedParticle[] pair) {
-        // Get the momentum squared.
-        double p2 = Math.pow(pair[0].getMomentum().magnitude() + pair[1].getMomentum().magnitude(), 2);
-        
-        // Get the remaining terms.
-        double xPro = pair[0].getMomentum().x() + pair[1].getMomentum().x();
-        double yPro = pair[0].getMomentum().y() + pair[1].getMomentum().y();
-        double zPro = pair[0].getMomentum().z() + pair[1].getMomentum().z();
-        
-        // Calculate the invariant mass.
-        return Math.sqrt(p2 - Math.pow(xPro, 2) - Math.pow(yPro, 2) - Math.pow(zPro, 2));
-    }
-    
-    /**
-     * Calculates the coplanarity angle between two points, specified
-     * by a double array. The array must be of the format (x, y, z).
-     * @param position - The first position array.
-     * @param otherPosition - The second position array.
-     * @return Returns the coplanarity angle between the points in units
-     * of degrees.
-     */
-    private static final double getCalculatedCoplanarity(double[] position, double[] otherPosition) {
-        // Define the x- and y-coordinates of the clusters as well as
-        // calorimeter center.
-        final double ORIGIN_X = 42.52;
-        double x[] = { position[0], otherPosition[0] };
-        double y[] = { position[1], otherPosition[1] };
-        
+		if(!event.hasCollection(ReconstructedParticle.class, particleCollectionName)) {
+			return;
+		}
+		List<ReconstructedParticle> trackList = event.get(ReconstructedParticle.class, particleCollectionName);
+		
+		// Check if the event has a collection of clusters. If it
+		// exists, extract it. Otherwise, skip the event.
+		if(!event.hasCollection(Cluster.class, clusterCollectionName)) {
+			return;
+		}
+		List<Cluster> clusterList = event.get(Cluster.class, clusterCollectionName);
+		
+		// Check if a trident candidate collection exists, and obtain
+		// it if so. Continue with the event if it does not.
+		List<ReconstructedParticle> tridentCandidates = null;
+		if(event.hasCollection(ReconstructedParticle.class, tridentCollectionName)) {
+			tridentCandidates = event.get(ReconstructedParticle.class, tridentCollectionName);
+		} else {
+			tridentCandidates = new ArrayList<ReconstructedParticle>(0);
+		}
+		
+		// Check if a Møller candidate collection exists, and obtain
+		// it if so. Continue with the event if it does not.
+		List<ReconstructedParticle> møllerCandidates = null;
+		if(event.hasCollection(ReconstructedParticle.class, møllerCollectionName)) {
+			møllerCandidates = event.get(ReconstructedParticle.class, møllerCollectionName);
+		} else {
+			møllerCandidates = new ArrayList<ReconstructedParticle>(0);
+		}
+		
+		// Get cluster-track matched top/bottom pairs.
+		List<ReconstructedParticle[]> gblMatchedPairs = getTopBottomTracksGBL(trackList);
+		List<ReconstructedParticle[]> ctMatchedPairs  = getTopBottomTracksCTMatched(trackList);
+		
+		// Get the trident and Møller tracks for the matched track
+		// and cluster pair condition sets.
+		List<ReconstructedParticle[]> møllers     = getMøllerTracksCTMatched(ctMatchedPairs);
+		List<ReconstructedParticle[]> møllersGBL  = getMøllerTracksGBL(gblMatchedPairs, event);
+		List<ReconstructedParticle[]> tridents    = getTridentTracksCTMatched(ctMatchedPairs);
+		List<ReconstructedParticle[]> tridentsVTX = getTridentTracksVertexed(tridentCandidates);
+		List<ReconstructedParticle[]> møllersVTX  = getMøllerTracksVertexed(møllerCandidates);
+		List<ReconstructedParticle[]> tridentsGBL = getTridentClustersGBL(gblMatchedPairs, TriggerModule.getTopBottomPairs(clusterList, Cluster.class), event);
+		
+		// Track how many events had tridents and Møllers.
+		if(!møllers.isEmpty()) { møllersProcessed++; }
+		if(!tridents.isEmpty()) { tridentsProcessed++; }
+		if(!møllersGBL.isEmpty()) { gblMøllersProcessed++; }
+		if(!tridentsGBL.isEmpty()) { gblTridentsProcessed++; }
+		if(!møllersVTX.isEmpty()) { vertexedMøllersProcessed++; }
+		if(!tridentsVTX.isEmpty()) { vertexedTridentsProcessed++; }
+		
+		// Get the SSP clusters.
+		if(event.hasCollection(GenericObject.class, bankCollectionName)) {
+			// Get the bank list.
+			List<GenericObject> bankList = event.get(GenericObject.class, bankCollectionName);
+			
+			// Check for simulated triggers. If they exist, populate the
+			// trigger tracking variables.
+			for(GenericObject obj : bankList) {
+				if(AbstractIntData.getTag(obj) == TIData.BANK_TAG) {
+					TIData tiBank = new TIData(obj);
+					
+					// Establish which triggers were active.
+					boolean isPulser   = tiBank.isPulserTrigger();
+					boolean isPair0    = tiBank.isPair0Trigger();
+					boolean isPair1    = tiBank.isPair1Trigger();
+					boolean isSingles0 = tiBank.isSingle0Trigger();
+					boolean isSingles1 = tiBank.isSingle1Trigger();
+					
+					// Populate the appropriate trigger tracking variables.
+					triggerActiveEvents++;
+					if(!møllers.isEmpty()) {
+						ctmTriggerMøllers[isPulser ? 1 : 0][isSingles0 ? 1 : 0][isSingles1 ? 1 : 0][isPair0 ? 1 : 0][isPair1 ? 1 : 0]++;
+					} if(!tridents.isEmpty()) {
+						ctmTriggerTridents[isPulser ? 1 : 0][isSingles0 ? 1 : 0][isSingles1 ? 1 : 0][isPair0 ? 1 : 0][isPair1 ? 1 : 0]++;
+					} if(!møllersVTX.isEmpty()) {
+						vtxTriggerMøllers[isPulser ? 1 : 0][isSingles0 ? 1 : 0][isSingles1 ? 1 : 0][isPair0 ? 1 : 0][isPair1 ? 1 : 0]++;
+					} if(!tridentsVTX.isEmpty()) {
+						vtxTriggerTridents[isPulser ? 1 : 0][isSingles0 ? 1 : 0][isSingles1 ? 1 : 0][isPair0 ? 1 : 0][isPair1 ? 1 : 0]++;
+					}
+				}
+			}
+		}
+		
+		// Produce Møller cluster-track matched plots.
+		møctmInstancesInEvent.fill(møllers.size());
+		for(ReconstructedParticle[] pair : møllers) {
+			// Get the track clusters.
+			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			
+			// Populate the cluster plots.
+			møctmElectronEnergy.fill(trackClusters[0].getEnergy());
+			møctmElectronEnergy.fill(trackClusters[1].getEnergy());
+			møctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
+			møctmEnergySum2D.fill(trackClusters[0].getEnergy(), trackClusters[1].getEnergy());
+			møctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
+			møctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
+			møctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
+			møctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
+			
+			// Populate the momentum plots.
+			møctmInvariantMass.fill(getInvariantMass(pair));
+			møctmElectronMomentum.fill(pair[0].getMomentum().magnitude());
+			møctmElectronMomentum.fill(pair[1].getMomentum().magnitude());
+			møctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+			møctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+			møctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+			møctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+			møctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+		}
+		
+		// Produce trident cluster-track matched plots.
+		trctmInstancesInEvent.fill(tridents.size());
+		for(ReconstructedParticle[] pair : tridents) {
+			// Get the electron and positron tracks.
+			ReconstructedParticle electronTrack = pair[pair[0].getCharge() < 0 ? 0 : 1];
+			ReconstructedParticle positronTrack = pair[pair[0].getCharge() > 0 ? 0 : 1];
+			
+			// Get the track clusters.
+			Cluster electronCluster = electronTrack.getClusters().get(0);
+			Cluster positronCluster = positronTrack.getClusters().get(0);
+			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			
+			// Populate the cluster plots.
+			trctmElectronEnergy.fill(electronCluster.getEnergy());
+			trctmPositronEnergy.fill(positronCluster.getEnergy());
+			trctmEnergySum2D.fill(pair[0].getEnergy(), pair[1].getEnergy());
+			trctmEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
+			trctmESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
+			trctmTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
+			trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
+			trctmClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
+			
+			// Populate the momentum plots.
+			trctmInvariantMass.fill(getInvariantMass(pair));
+			trctmElectronMomentum.fill(electronTrack.getMomentum().magnitude());
+			trctmPositronMomentum.fill(positronTrack.getMomentum().magnitude());
+			trctmMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+			trctmMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+			trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+			trctmTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+			trctmPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+		}
+		
+		// Produce trident vertexed plots.
+		trvtxInstancesInEvent.fill(tridentsVTX.size());
+		for(ReconstructedParticle[] pair : tridentsVTX) {
+			// Get the electron and positron tracks.
+			ReconstructedParticle electronTrack = pair[pair[0].getCharge() < 0 ? 0 : 1];
+			ReconstructedParticle positronTrack = pair[pair[0].getCharge() > 0 ? 0 : 1];
+			
+			// Get the track clusters.
+			Cluster electronCluster = electronTrack.getClusters().get(0);
+			Cluster positronCluster = positronTrack.getClusters().get(0);
+			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			
+			// Populate the cluster plots.
+			trvtxElectronEnergy.fill(electronCluster.getEnergy());
+			trvtxPositronEnergy.fill(positronCluster.getEnergy());
+			trvtxEnergySum2D.fill(pair[0].getEnergy(), pair[1].getEnergy());
+			trvtxEnergySum1D.fill(TriggerModule.getValueEnergySum(trackClusters));
+			trvtxESumCoplanarity.fill(TriggerModule.getValueEnergySum(trackClusters), getCalculatedCoplanarity(trackClusters));
+			trvtxTimeCoincidence.fill(TriggerModule.getClusterTime(trackClusters[0]) - TriggerModule.getClusterTime(trackClusters[1]));
+			trvtxClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[0]), TriggerModule.getClusterYIndex(trackClusters[0]));
+			trvtxClusterPosition.fill(TriggerModule.getClusterXIndex(trackClusters[1]), TriggerModule.getClusterYIndex(trackClusters[1]));
+			
+			// Populate the momentum plots.
+			trvtxInvariantMass.fill(getInvariantMass(pair));
+			trvtxElectronMomentum.fill(electronTrack.getMomentum().magnitude());
+			trvtxPositronMomentum.fill(positronTrack.getMomentum().magnitude());
+			trvtxMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+			trvtxMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+			trvtxTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+			trvtxTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+			trvtxPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+		}
+		
+		// Produce the Møller vertexed plots.
+		møvtxInstancesInEvent.fill(møllersVTX.size());
+		RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+		RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+		for(ReconstructedParticle pair[] : møllersVTX) {
+			// Get the tracks and track times.
+			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+			double times[] = {
+					TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
+					TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)	
+			};
+			
+			// Fill the plots.
+			møvtxTimeCoincidence.fill(times[0] - times[1]);
+			møvtxInvariantMass.fill(getInvariantMass(pair));
+			møvtxElectronMomentum.fill(pair[0].getMomentum().magnitude());
+			møvtxElectronMomentum.fill(pair[1].getMomentum().magnitude());
+			møvtxMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+			møvtxMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+			møvtxTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+			møvtxTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+			møvtxPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+		}
+		
+		// Produce the Møller track-only plots.
+		møgblInstancesInEvent.fill(møllersGBL.size());
+		for(ReconstructedParticle pair[] : møllersGBL) {
+			// Get the tracks and track times.
+			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+			double times[] = {
+					TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
+					TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)	
+			};
+			
+			// Fill the plots.
+			møgblTimeCoincidence.fill(times[0] - times[1]);
+			møgblInvariantMass.fill(getInvariantMass(pair));
+			møgblElectronMomentum.fill(pair[0].getMomentum().magnitude());
+			møgblElectronMomentum.fill(pair[1].getMomentum().magnitude());
+			møgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+			møgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+			møgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+			møgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+			møgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+		}
+		
+		// Produce track-only trident plots.
+		trgblInstancesInEvent.fill(tridentsGBL.size());
+		for(ReconstructedParticle[] pair : tridentsGBL) {
+			// Get the tracks and track times.
+			Track[] tracks = { pair[0].getTracks().get(0), pair[1].getTracks().get(0) };
+			double times[] = {
+					TrackUtils.getTrackTime(tracks[0], hitToStrips, hitToRotated),
+					TrackUtils.getTrackTime(tracks[1], hitToStrips, hitToRotated)	
+			};
+			
+			// Get the positron and the electron.
+			ReconstructedParticle positron = pair[0].getCharge() > 0 ? pair[0] : pair[1];
+			ReconstructedParticle electron = pair[0].getCharge() < 0 ? pair[0] : pair[1];
+			
+			// Fill the plots.
+			trgblTimeCoincidence.fill(times[0] - times[1]);
+			trgblInvariantMass.fill(getInvariantMass(pair));
+			trgblElectronMomentum.fill(electron.getMomentum().magnitude());
+			trgblPositronMomentum.fill(positron.getMomentum().magnitude());
+			trgblMomentumSum1D.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude());
+			trgblMomentumSum2D.fill(pair[0].getMomentum().magnitude(), pair[1].getMomentum().magnitude());
+			trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[0]).x(), TrackUtils.getTrackPositionAtEcal(tracks[0]).y());
+			trgblTrackPosition.fill(TrackUtils.getTrackPositionAtEcal(tracks[1]).x(), TrackUtils.getTrackPositionAtEcal(tracks[1]).y());
+			trgblPSumCoplanarity.fill(VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude(),
+					getCalculatedCoplanarity(new Track[] { pair[0].getTracks().get(0), pair[1].getTracks().get(0) }));
+		}
+	}
+	
+	public void setCheckSVT(boolean state) {
+		checkSVT = state;
+	}
+	
+	public void setCheckTriggerTimeWindow(boolean state) {
+		checkTriggerTimeWindow = state;
+	}
+	
+	/**
+	 * Gets a list of all possible GBL top/bottom track pairs. These
+	 * tracks are not guaranteed to have a matched cluster.
+	 * @param trackList - A list of all possible tracks.
+	 * @return Returns a list of track pairs.
+	 */
+	private static final List<ReconstructedParticle[]> getTopBottomTracksGBL(List<ReconstructedParticle> trackList) {
+		// Separate the tracks into top and bottom tracks based on
+		// the value of tan(Λ). Use only GBL tracks to avoid track
+		// duplication.
+		List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
+		List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
+		trackLoop:
+		for(ReconstructedParticle track : trackList) {
+			// Require that the ReconstructedParticle contain an actual
+			// Track object.
+			if(track.getTracks().isEmpty()) {
+				continue trackLoop;
+			}
+			
+			// Ignore tracks that are not GBL tracks.
+			if(!TrackType.isGBL(track.getType())) {
+				continue trackLoop;
+			}
+			
+			// If the above tests pass, the ReconstructedParticle has
+			// a track and is also a GBL track. Separate it into either
+			// a top or a bottom track based on its tan(Λ) value.
+			if(track.getTracks().get(0).getTrackStates().get(0).getTanLambda() > 0) {
+				topTracks.add(track);
+			} else {
+				botTracks.add(track);
+			}
+		}
+		
+		// Form all top/bottom pairs with the unique tracks.
+		List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
+		for(ReconstructedParticle topTrack : topTracks) {
+			for(ReconstructedParticle botTrack : botTracks) {
+				pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
+			}
+		}
+		
+		// Return the result.
+		return pairList;
+	}
+	
+	/**
+	 * Produces pairs of tracks. The track pairs are required to be
+	 * matched to a cluster and the associated clusters must form a
+	 * top/bottom pair. If more than one track points to the same
+	 * cluster, only the first track is retained.
+	 * @param trackList - A list of all tracks.
+	 * @return Returns a list of track pairs meeting the aforementioned
+	 * conditions.
+	 */
+	private static final List<ReconstructedParticle[]> getTopBottomTracksCTMatched(List<ReconstructedParticle> trackList) {
+		// Track clusters that have already been seen to prevent clusters
+		// that have duplicate tracks from reappearing.
+		Set<Cluster> clusterSet = new HashSet<Cluster>();
+		
+		// Separate the tracks into top and bottom tracks based on
+		// the track cluster. Filter out tracks with no clusters.
+		List<ReconstructedParticle> topTracks = new ArrayList<ReconstructedParticle>();
+		List<ReconstructedParticle> botTracks = new ArrayList<ReconstructedParticle>();
+		trackLoop:
+		for(ReconstructedParticle track : trackList) {
+			// Check if the track has a cluster. If not, skip it.
+			if(track.getClusters().isEmpty()) {
+				continue trackLoop;
+			}
+			
+			// If the track doesn't have actual tracks, skip it.
+			if(track.getTracks().isEmpty()) {
+				continue trackLoop;
+			}
+			
+			// Check if the track cluster has already seen.
+			Cluster trackCluster = track.getClusters().get(0);
+			if(clusterSet.contains(trackCluster)) {
+				continue trackLoop;
+			}
+			
+			// If the track has a unique cluster, add it to the proper
+			// list based on the cluster y-index.
+			clusterSet.add(trackCluster);
+			if(TriggerModule.getClusterYIndex(trackCluster) > 0) {
+				topTracks.add(track);
+			} else {
+				botTracks.add(track);
+			}
+		}
+		
+		// Form all top/bottom pairs with the unique tracks.
+		List<ReconstructedParticle[]> pairList = new ArrayList<ReconstructedParticle[]>();
+		for(ReconstructedParticle topTrack : topTracks) {
+			for(ReconstructedParticle botTrack : botTracks) {
+				pairList.add(new ReconstructedParticle[] { topTrack, botTrack });
+			}
+		}
+		
+		// Return the result.
+		return pairList;
+	}
+	
+	private final List<ReconstructedParticle[]> getTridentTracksVertexed(List<ReconstructedParticle> candidateList) {
+		// Store the set of track pairs that meet the trident condition.
+		List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
+		
+		// Loop over the filtered pair list and apply the trident
+		// condition test.
+		tridentLoop:
+		for(ReconstructedParticle candidate : candidateList) {
+			// Require that the vertex fit have a X^2 value of less
+			// than 25.
+			trvtxChiSquared.fill(candidate.getStartVertex().getChi2());
+			if(candidate.getStartVertex().getChi2() > 10) {
+				continue tridentLoop;
+			}
+			
+			// Make sure that each particle is track/cluster matched.
+			ReconstructedParticle[] pair = {
+					candidate.getParticles().get(0),
+					candidate.getParticles().get(1)
+			};
+			if(pair[0].getTracks().isEmpty() || pair[0].getClusters().isEmpty()) {
+				continue tridentLoop;
+			}
+			if(pair[1].getTracks().isEmpty() || pair[1].getClusters().isEmpty()) {
+				continue tridentLoop;
+			}
+			
+			// Make sure there is a top/bottom cluster pair.
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			boolean hasTop = TriggerModule.getClusterYIndex(trackClusters[0]) > 0 || TriggerModule.getClusterYIndex(trackClusters[1]) > 0;
+			boolean hasBot = TriggerModule.getClusterYIndex(trackClusters[0]) < 0 || TriggerModule.getClusterYIndex(trackClusters[1]) < 0;
+			if(!hasTop || !hasBot) {
+				continue tridentLoop;
+			}
+			
+			// There must be one positive and one negative track.
+			ReconstructedParticle electron = null;
+			ReconstructedParticle positron = null;
+			if(pair[0].getCharge() > 0) { positron = pair[0]; }
+			else if(pair[1].getCharge() > 0) { positron = pair[1]; }
+			if(pair[0].getCharge() < 0) { electron = pair[0]; }
+			else if(pair[1].getCharge() < 0) { electron = pair[1]; }
+			if(electron == null || positron == null) {
+				continue tridentLoop;
+			}
+			
+			// Make sure that the clusters are not the same. This should
+			// not actually ever be possible...
+			if(pair[0].getClusters().get(0) == pair[1].getClusters().get(0)) {
+				continue tridentLoop;
+			}
+			
+			// The clusters must within a limited time window.
+			if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
+				continue tridentLoop;
+			}
+			
+			// Require that the electron in the pair have an energy
+			// below the elastic threshold to exclude elastic electrons.
+			if(electron.getMomentum().magnitude() >= elasticThreshold) {
+				continue tridentLoop;
+			}
+			
+			// Require that all clusters occur within the trigger time
+			// window to exclude accidentals.
+			if(checkTriggerTimeWindow) {
+				if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
+					continue tridentLoop;
+				}
+			}
+			
+			// If all the above conditions are met, the pair is to be
+			// considered a trident pair. Add it to the list.
+			tridentTracks.add(pair);
+		}
+		
+		// Return the list of pairs that passed the condition.
+		return tridentTracks;
+	}
+	
+	private final List<ReconstructedParticle[]> getTridentClustersGBL(List<ReconstructedParticle[]> pairList, List<Cluster[]> clusterList, EventHeader event) {
+		// Store the set of track pairs that meet the trident condition.
+		List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
+		
+		// Extract track relational tables from the event object.
+		RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+		RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+		
+		// Tracks will not be considered for trident analysis unless there
+		// is at least one top/bottom cluster pair within the time window.
+		boolean passesClusterCondition = false;
+		tridentClusterLoop:
+		for(Cluster[] pair : clusterList) {
+			// Ignore clusters that are too far apart temporally.
+			if(TriggerModule.getValueTimeCoincidence(pair) > timeCoincidence) {
+				continue tridentClusterLoop;
+			}
+			
+			// Require that the cluster pair be top/bottom.
+			boolean hasTop = TriggerModule.getClusterYIndex(pair[0]) > 0 || TriggerModule.getClusterYIndex(pair[1]) > 0;
+			boolean hasBot = TriggerModule.getClusterYIndex(pair[0]) < 0 || TriggerModule.getClusterYIndex(pair[1]) < 0;
+			if(!hasTop || !hasBot) {
+				continue tridentClusterLoop;
+			}
+			
+			// If the cluster passes, mark that it has done so and skip
+			// the rest. Only one pair need pass.
+			passesClusterCondition = true;
+			break tridentClusterLoop;
+		}
+		
+		// If no cluster pair passed the cluster condition, no tracks
+		// are allowed to pass either.
+		if(!passesClusterCondition) {
+			return tridentTracks;
+		}
+		
+		// Next, check the track pair list. A track pair must have a
+		// positive and a negative track and must also be within the
+		// time coincidence window.
+		tridentTrackLoop:
+		for(ReconstructedParticle[] pair : pairList) {
+			// Check that there is at least one positive and one negative
+			// track in the pair.
+			boolean hasPositive = pair[0].getCharge() > 0 || pair[1].getCharge() > 0;
+			boolean hasNegative = pair[0].getCharge() < 0 || pair[1].getCharge() < 0;
+			if(!hasPositive || !hasNegative) {
+				break tridentTrackLoop;
+			}
+			
+			// Check that the track pair passes the time cut.
+			double times[] = {
+				TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
+				TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)	
+			};
+			
+			if(Math.abs(times[0] - times[1]) > timeCoincidence) {
+				continue tridentTrackLoop;
+			}
+			
+			// Require that the negative track have less than the
+			// elastic threshold momentum to exclude elastic electrons.
+			if(pair[0].getCharge() < 0 && pair[0].getMomentum().magnitude() > elasticThreshold
+					|| pair[1].getCharge() < 0 && pair[1].getMomentum().magnitude() > elasticThreshold) {
+				continue tridentTrackLoop;
+			}
+			
+			// If the track passes both, it is considered a trident pair.
+			tridentTracks.add(pair);
+		}
+		
+		// Return the resultant pairs.
+		return tridentTracks;
+	}
+	
+	/**
+	 * Gets a list track pairs that meet the trident condition defined
+	 * using tracks with matched calorimeter clusters. A pair meets the
+	 * cluster/track matched trident condition is it meets the following:
+	 * <ul><li>Both tracks have matched clusters.</li>
+	 * <li>Has one positive track.</li>
+	 * <li>Has one negative track.</li>
+	 * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
+	 * <li>The electron momentum is below 900 MeV.</li></ul>
+	 * @param pairList - A <code>List</code> collection of parameterized
+	 * type <code>ReconstructedParticle[]</code> containing all valid
+	 * top/bottom pairs of tracks with matched clusters. These will be
+	 * tested to see if they meet the process criteria.
+	 * @return Returns a list containing pairs of tracks that meet the
+	 * trident condition.
+	 */
+	private final List<ReconstructedParticle[]> getTridentTracksCTMatched(List<ReconstructedParticle[]> pairList) {
+		// Store the set of track pairs that meet the trident condition.
+		List<ReconstructedParticle[]> tridentTracks = new ArrayList<ReconstructedParticle[]>();
+		
+		// Loop over the filtered pair list and apply the trident
+		// condition test.
+		tridentLoop:
+		for(ReconstructedParticle[] pair : pairList) {
+			// There must be one positive and one negative track.
+			ReconstructedParticle electron = null;
+			ReconstructedParticle positron = null;
+			if(pair[0].getCharge() > 0) { positron = pair[0]; }
+			else if(pair[1].getCharge() > 0) { positron = pair[1]; }
+			if(pair[0].getCharge() < 0) { electron = pair[0]; }
+			else if(pair[1].getCharge() < 0) { electron = pair[1]; }
+			if(electron == null || positron == null) {
+				continue tridentLoop;
+			}
+			
+			// Make sure that the clusters are not the same. This should
+			// not actually ever be possible...
+			if(pair[0].getClusters().get(0) == pair[1].getClusters().get(0)) {
+				continue tridentLoop;
+			}
+			
+			// The clusters must within a limited time window.
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
+				continue tridentLoop;
+			}
+			
+			// Require that the electron in the pair have an energy
+			// below the elastic threshold to exclude elastic electrons.
+			if(electron.getMomentum().magnitude() >= elasticThreshold) {
+				continue tridentLoop;
+			}
+			
+			// Require that all clusters occur within the trigger time
+			// window to exclude accidentals.
+			if(checkTriggerTimeWindow) {
+				if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
+					continue tridentLoop;
+				}
+			}
+			
+			// If all the above conditions are met, the pair is to be
+			// considered a trident pair. Add it to the list.
+			tridentTracks.add(pair);
+		}
+		
+		// Return the list of pairs that passed the condition.
+		return tridentTracks;
+	}
+	
+	private final List<ReconstructedParticle[]> getMøllerTracksGBL(List<ReconstructedParticle[]> pairList, EventHeader event) {
+		// Store the set of track pairs that meet the Møller condition.
+		List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
+		
+		// Extract track relational tables from the event object.
+		RelationalTable<?, ?> hitToStrips = TrackUtils.getHitToStripsTable(event);
+		RelationalTable<?, ?> hitToRotated = TrackUtils.getHitToRotatedTable(event);
+		
+		// Loop over the filtered pair list and apply the Møller
+		// condition test.
+		møllerLoop:
+		for(ReconstructedParticle[] pair : pairList) {
+			// Both tracks must be negatively charged.
+			if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
+				continue møllerLoop;
+			}
+			
+			// The clusters must within a limited time window.
+			double times[] = {
+				TrackUtils.getTrackTime(pair[0].getTracks().get(0), hitToStrips, hitToRotated),
+				TrackUtils.getTrackTime(pair[1].getTracks().get(0), hitToStrips, hitToRotated)	
+			};
+			
+			if(Math.abs(times[0] - times[1]) > timeCoincidence) {
+				continue møllerLoop;
+			}
+			
+			// Require that the electrons in the pair have energies
+			// below the elastic threshold to exclude said electrons.
+			if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
+				continue møllerLoop;
+			}
+			
+			// Require that the energy of the pair be within a range
+			// that is sufficiently "Møller-like."
+			double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
+			if(momentumSum < møllerLowerRange || momentumSum > møllerUpperRange) {
+				continue møllerLoop;
+			}
+			
+			// If all the above conditions are met, the pair is to be
+			// considered a trident pair. Add it to the list.
+			møllerTracks.add(pair);
+		}
+		
+		// Return the list of pairs that passed the condition.
+		return møllerTracks;
+	}
+	
+	private final List<ReconstructedParticle[]> getMøllerTracksVertexed(List<ReconstructedParticle> candidateList) {
+		// Store the set of track pairs that meet the Møller condition.
+		List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
+		
+		// Loop over the candidate list and apply the Møller cuts.
+		møllerLoop:
+		for(ReconstructedParticle candidate : candidateList) {
+			// Require that the vertex fit have a X^2 value of less
+			// than 25.
+			if(candidate.getStartVertex().getChi2() > 10) {
+				continue møllerLoop;
+			}
+			
+			// Make sure that each particle is track/cluster matched.
+			ReconstructedParticle[] pair = {
+					candidate.getParticles().get(0),
+					candidate.getParticles().get(1)
+			};
+			if(pair[0].getTracks().isEmpty() || pair[0].getClusters().isEmpty()) {
+				continue møllerLoop;
+			}
+			if(pair[1].getTracks().isEmpty() || pair[1].getClusters().isEmpty()) {
+				continue møllerLoop;
+			}
+			
+			// Make sure there is a top/bottom cluster pair.
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			boolean hasTop = TriggerModule.getClusterYIndex(trackClusters[0]) > 0 || TriggerModule.getClusterYIndex(trackClusters[1]) > 0;
+			boolean hasBot = TriggerModule.getClusterYIndex(trackClusters[0]) < 0 || TriggerModule.getClusterYIndex(trackClusters[1]) < 0;
+			if(!hasTop || !hasBot) {
+				continue møllerLoop;
+			}
+			
+			// Require that the clusters be within the time coincidence.
+			if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
+				continue møllerLoop;
+			}
+			
+			// Require that both tracks have less than the elastic
+			// threshold in momentum.
+			if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
+				continue møllerLoop;
+			}
+			
+			
+			
+			
+			// Variable definitions
+			double[] mom1 = pair[0].getMomentum().v();
+			double px1 = mom1[0];
+			double py1 = mom1[1];
+			double pz1 = mom1[2];
+			
+			double unrot_px1 = px1*Math.cos(-0.0305) + pz1*Math.sin(-0.0305);
+			double unrot_pz1 = pz1*Math.cos(-0.0305) - px1*Math.sin(-0.0305);
+			
+			double unrot_theta1 = Math.atan2(Math.sqrt(unrot_px1*unrot_px1 + py1*py1),unrot_pz1);
+			double TrackE1 = Math.sqrt(Math.sqrt(px1*px1 + py1*py1 + pz1*pz1)*Math.sqrt(px1*px1 + py1*py1 + pz1*pz1) + 0.0005109989*0.0005109989);
+			
+			
+			double[] mom2 = pair[1].getMomentum().v();
+			double px2 = mom2[0];
+			double py2 = mom2[1];
+			double pz2 = mom2[2];
+			
+			double unrot_px2 = px2*Math.cos(-0.0305) + pz2*Math.sin(-0.0305);
+			double unrot_pz2 = pz2*Math.cos(-0.0305) - px2*Math.sin(-0.0305);
+			
+			double unrot_theta2 = Math.atan2(Math.sqrt(unrot_px2*unrot_px2 + py2*py2),unrot_pz2);
+			double TrackE2 = Math.sqrt(Math.sqrt(px2*px2 + py2*py2 + pz2*pz2)*Math.sqrt(px2*px2 + py2*py2 + pz2*pz2) + 0.0005109989*0.0005109989);
+			
+			
+			// Ultimate Moller Cut
+			if((Math.sin(unrot_theta1/2)*Math.sin(unrot_theta2/2)<=(1+0.20)*0.5109989/(2*1056) && Math.sin(unrot_theta1/2)*Math.sin(unrot_theta2/2)>=(1-0.20)*0.5109989/(2*1056)) ) {
+				if( (TrackE1+TrackE2<=(1+0.10)*1.056 && TrackE1+TrackE2>=(1-0.10)*1.056) ) {
+					
+					
+					
+					
+					møllerTracks.add(pair);
+				}
+			}
+			
+			
+			
+			
+			/*
+			double[] trackE = new double[2];
+			double[] unrotTheta = new double[2];
+			double[][] unrotP = new double[2][3];
+			for(int i = 0; i < pair.length; i++) {
+				unrotP[i][0] = pair[i].getMomentum().x() * Math.cos(BEAM_ROTATION) + pair[i].getMomentum().z() * Math.sin(BEAM_ROTATION);
+				unrotP[i][2] = pair[i].getMomentum().z() * Math.cos(BEAM_ROTATION) - pair[i].getMomentum().x() * Math.sin(BEAM_ROTATION);
+				unrotTheta[i] = Math.atan2(Math.sqrt(unrotP[i][0] * unrotP[i][0] + pair[0].getMomentum().y() * pair[i].getMomentum().y()), unrotP[0][2]);
+				trackE[i] = Math.sqrt(pair[i].getMomentum().magnitudeSquared() + ELECTRON_MASS_2);
+			}
+			
+			// Perform the track angle threshold cuts.
+			double unrotatedTheta = Math.sin(unrotTheta[0] / 2) * Math.sin(unrotTheta[1] / 2);
+			if((unrotatedTheta <= MØLLER_ANGLE_THRESHOLD[HIGH] && unrotatedTheta >= MØLLER_ANGLE_THRESHOLD[LOW])) {
+				// Perform the track energy sum threshold cuts.
+				double trackESum = trackE[0] + trackE[1];
+				if((trackESum <= MØLLER_ENERGY_THRESHOLD[HIGH] && trackESum >= MØLLER_ENERGY_THRESHOLD[LOW])) {
+					// If a pair passes all the Møller cuts, then it
+					// is a Møller pair.
+					møllerTracks.add(pair);
+				}
+			}
+			*/
+		}
+		
+		// Return the Møller list.
+		return møllerTracks;
+	}
+	
+	/**
+	 * Gets a list track pairs that meet the Møller condition defined
+	 * using tracks with matched calorimeter clusters. A pair meets the
+	 * cluster/track matched Møller condition is it meets the following:
+	 * <ul><li>Both tracks have matched clusters.</li>
+	 * <li>Both tracks are negative.</li>
+	 * <li>Clusters have a time coincidence of 2.5 ns or less.</li>
+	 * <li>The electron momenta are below 900 MeV.</li>
+	 * <li>The momentum sum of the tracks is in the range <code>800 MeV
+	 * ≤ p1 + p2 ≤ 1500 MeV</li></ul>
+	 * @param pairList - A <code>List</code> collection of parameterized
+	 * type <code>ReconstructedParticle[]</code> containing all valid
+	 * top/bottom pairs of tracks with matched clusters. These will be
+	 * tested to see if they meet the process criteria.
+	 * @return Returns a list containing pairs of tracks that meet the
+	 * Møller condition.
+	 */
+	private final List<ReconstructedParticle[]> getMøllerTracksCTMatched(List<ReconstructedParticle[]> pairList) {
+		// Store the set of track pairs that meet the Møller condition.
+		List<ReconstructedParticle[]> møllerTracks = new ArrayList<ReconstructedParticle[]>();
+		
+		// Loop over the filtered pair list and apply the Møller
+		// condition test.
+		møllerLoop:
+		for(ReconstructedParticle[] pair : pairList) {
+			// Both tracks must be negatively charged.
+			if(pair[0].getCharge() > 0 || pair[1].getCharge() > 0) {
+				continue møllerLoop;
+			}
+			
+			// The clusters must within a limited time window.
+			Cluster[] trackClusters = { pair[0].getClusters().get(0), pair[1].getClusters().get(0) };
+			if(TriggerModule.getValueTimeCoincidence(trackClusters) > timeCoincidence) {
+				continue møllerLoop;
+			}
+			
+			// Require that the electrons in the pair have energies
+			// below the elastic threshold to exclude said electrons.
+			if(pair[0].getMomentum().magnitude() > elasticThreshold || pair[1].getMomentum().magnitude() > elasticThreshold) {
+				continue møllerLoop;
+			}
+			
+			// Require that the energy of the pair be within a range
+			// that is sufficiently "Møller-like."
+			double momentumSum = VecOp.add(pair[0].getMomentum(), pair[1].getMomentum()).magnitude();
+			if(momentumSum < møllerLowerRange || momentumSum > møllerUpperRange) {
+				continue møllerLoop;
+			}
+			
+			// Require that all clusters occur within the trigger time
+			// window to exclude accidentals.
+			if(checkTriggerTimeWindow) {
+				if(!inTriggerWindow(trackClusters[0]) || !inTriggerWindow(trackClusters[1])) {
+					continue møllerLoop;
+				}
+			}
+			
+			// If all the above conditions are met, the pair is to be
+			// considered a trident pair. Add it to the list.
+			møllerTracks.add(pair);
+		}
+		
+		// Return the list of pairs that passed the condition.
+		return møllerTracks;
+	}
+	
+	/**
+	 * Calculates the approximate invariant mass for a pair of tracks
+	 * from their momentum. This assumes that the particles are either
+	 * electrons or positrons, and thusly have a sufficiently small
+	 * mass term that it can be safely excluded.
+	 * @param pair - The track pair for which to calculate the invariant
+	 * mass.
+	 * @return Returns the approximate invariant mass in units of GeV.
+	 */
+	private static final double getInvariantMass(ReconstructedParticle[] pair) {
+		// Get the momentum squared.
+		double p2 = Math.pow(pair[0].getMomentum().magnitude() + pair[1].getMomentum().magnitude(), 2);
+		
+		// Get the remaining terms.
+		double xPro = pair[0].getMomentum().x() + pair[1].getMomentum().x();
+		double yPro = pair[0].getMomentum().y() + pair[1].getMomentum().y();
+		double zPro = pair[0].getMomentum().z() + pair[1].getMomentum().z();
+		
+		// Calculate the invariant mass.
+		return Math.sqrt(p2 - Math.pow(xPro, 2) - Math.pow(yPro, 2) - Math.pow(zPro, 2));
+	}
+	
+	/**
+	 * Calculates the coplanarity angle between two points, specified
+	 * by a double array. The array must be of the format (x, y, z).
+	 * @param position - The first position array.
+	 * @param otherPosition - The second position array.
+	 * @return Returns the coplanarity angle between the points in units
+	 * of degrees.
+	 */
+	private static final double getCalculatedCoplanarity(double[] position, double[] otherPosition) {
+		// Define the x- and y-coordinates of the clusters as well as
+		// calorimeter center.
+		final double ORIGIN_X = 42.52;
+		double x[] = { position[0], otherPosition[0] };
+		double y[] = { position[1], otherPosition[1] };
+		
         // Get the cluster angles.
         double[] clusterAngle = new double[2];
         for(int i = 0; i < 2; i++) {

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot.java	Tue Sep 27 08:50:14 2016
@@ -1,25 +1,25 @@
 package org.hps.users.kmccarty.plots;
 
 public abstract class FormattedPlot {
-    private final String xAxis;
-    private final String yAxis;
-    private final String plotName;
-    
-    public FormattedPlot(String xAxis, String yAxis, String plotName) {
-        this.xAxis = xAxis;
-        this.yAxis = yAxis;
-        this.plotName = plotName;
-    }
-    
-    public String getPlotName() {
-        return plotName;
-    }
-    
-    public String getXAxisName() {
-        return xAxis;
-    }
-    
-    public String getYAxisName() {
-        return yAxis;
-    }
+	private final String xAxis;
+	private final String yAxis;
+	private final String plotName;
+	
+	public FormattedPlot(String xAxis, String yAxis, String plotName) {
+		this.xAxis = xAxis;
+		this.yAxis = yAxis;
+		this.plotName = plotName;
+	}
+	
+	public String getPlotName() {
+		return plotName;
+	}
+	
+	public String getXAxisName() {
+		return xAxis;
+	}
+	
+	public String getYAxisName() {
+		return yAxis;
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot1D.java	Tue Sep 27 08:50:14 2016
@@ -1,41 +1,136 @@
 package org.hps.users.kmccarty.plots;
 
+import java.util.HashSet;
+import java.util.Set;
+
 import org.hps.users.kmccarty.plots.PlotsFormatter.ColorStyle;
+import org.hps.users.kmccarty.plots.PlotsFormatter.DisplayStyle;
 
 import hep.aida.IHistogram1D;
 
 public class FormattedPlot1D extends FormattedPlot {
-    private final ColorStyle style;
-    private final IHistogram1D plot;
-    private final double axisRange;
-    
-    public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName) {
-        super(xAxis, yAxis, plotName);
-        this.plot = plot;
-        this.style = style;
-        this.axisRange = -1;
-    }
-    
-    public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName, double axisRange) {
-        super(xAxis, yAxis, plotName);
-        this.plot = plot;
-        this.style = style;
-        this.axisRange = axisRange;
-    }
-    
-    public IHistogram1D getPlot() {
-        return plot;
-    }
-    
-    public ColorStyle getColorStyle() {
-        return style;
-    }
-    
-    public boolean definesAxisRange() {
-        return axisRange != -1;
-    }
-    
-    public double getAxisRange() {
-        return axisRange;
-    }
+	private final double axisMin;
+	private final double axisMax;
+	private final ColorStyle[] styles;
+	private final IHistogram1D[] plots;
+	private final DisplayStyle dispStyle;
+	
+	public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName) {
+		this(new IHistogram1D[] { plot }, new ColorStyle[] { style }, new String[] { plotName }, xAxis, yAxis, DisplayStyle.BAR, plotName);
+	}
+	
+	public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, DisplayStyle dispStyle, String plotName) {
+		this(new IHistogram1D[] { plot }, new ColorStyle[] { style }, new String[] { plotName }, xAxis, yAxis, dispStyle, plotName);
+	}
+	
+	public FormattedPlot1D(IHistogram1D plots[], ColorStyle[] styles, String[] entryNames,
+			String xAxis, String yAxis, DisplayStyle dispStyle, String plotName) {
+		this(plots, styles, entryNames, xAxis, yAxis, dispStyle, plotName, -1, -1);
+	}
+	
+	public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis, String plotName, double axisMin, double axisMax) {
+		this(new IHistogram1D[] { plot }, new ColorStyle[] { style }, new String[] { plotName },
+				xAxis, yAxis, DisplayStyle.BAR, plotName, axisMin, axisMax);
+	}
+	
+	public FormattedPlot1D(IHistogram1D plot, ColorStyle style, String xAxis, String yAxis,
+			DisplayStyle dispStyle, String plotName, double axisMin, double axisMax) {
+		this(new IHistogram1D[] { plot }, new ColorStyle[] { style }, new String[] { plotName },
+				xAxis, yAxis, dispStyle, plotName, axisMin, axisMax);
+	}
+	
+	public FormattedPlot1D(IHistogram1D plots[], ColorStyle[] styles, String[] entryNames, String xAxis,
+			String yAxis, DisplayStyle dispStyle, String plotName, double axisMin, double axisMax) {
+		// Initialize the object.
+		super(xAxis, yAxis, plotName);
+		this.plots = plots;
+		this.styles = styles;
+		this.axisMin = axisMin;
+		this.axisMax = axisMax;
+		if(dispStyle == null) { this.dispStyle = DisplayStyle.BAR; }
+		else { this.dispStyle = dispStyle; }
+		
+		// Verify that the plot array is valid for a compound plot.
+		if(!verifyPlots(plots)) {
+			throw new IllegalArgumentException("Plots array invalid; plots must have the same bins!");
+		}
+		
+		// Verify that all color styles are defined and are equal in
+		// number to the plots.
+		if(styles == null || styles.length != plots.length) {
+			throw new IllegalArgumentException("Color style array invalid; a number of color styles equal to plots must be defined.");
+		}
+		for(int i = 0; i < styles.length; i++) {
+			if(styles[i] == null) {
+				throw new IllegalArgumentException("Color style array invalid; all color styles must be defined.");
+			}
+		}
+		
+		// Set the names of each individual entry plot.
+		if(entryNames == null || entryNames.length != plots.length) {
+			throw new IllegalArgumentException("When defining multiple plots, a unique entry name must be defined for each.");
+		}
+		Set<String> entryNameSet = new HashSet<String>(entryNames.length);
+		for(int i = 0; i < plots.length; i++) {
+			if(entryNames[i] == null || entryNameSet.contains(entryNames[i])) {
+				throw new IllegalArgumentException("When defining multiple plots, a unique entry name must be defined for each.");
+			}
+			entryNameSet.add(entryNames[i]);
+			plots[i].setTitle(entryNames[i]);
+		}
+	}
+	
+	public IHistogram1D[] getPlots() {
+		return plots;
+	}
+	
+	public ColorStyle[] getColorStyle() {
+		return styles;
+	}
+	
+	public boolean definesAxisRange() {
+		return axisMax != -1;
+	}
+	
+	public double getAxisMin() {
+		return axisMin;
+	}
+	
+	public double getAxisMax() {
+		return axisMax;
+	}
+	
+	public DisplayStyle getDisplayStyle() {
+		return dispStyle;
+	}
+	
+	private static final boolean verifyPlots(IHistogram1D[] plots) {
+		// The plot file must be defined.
+		if(plots == null) { return false; }
+		
+		// If there is only one plot, it passes automatically.
+		if(plots.length == 1) { return true; }
+		
+		// All plots must have the same dimensions and bin values.
+		int baseBins = plots[0].axis().bins();
+		for(IHistogram1D plot : plots) {
+			// Check that the plot has the same number of bins.
+			if(plot.axis().bins() != baseBins) { return false; }
+		}
+		
+		// Check that each bin in the plots has the same value.
+		for(int bin = 0; bin < baseBins; bin++) {
+			// Get the value of the first bin in the base plot.
+			double baseBinValue = plots[0].axis().binLowerEdge(0);
+			
+			// Check that all other plots are the same.
+			for(IHistogram1D plot : plots) {
+				// Check that the plot has the same number of bins.
+				if(plot.axis().binLowerEdge(0) != baseBinValue) { return false; }
+			}
+		}
+		
+		// Otherwise, the plots are the same.
+		return true;
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/FormattedPlot2D.java	Tue Sep 27 08:50:14 2016
@@ -3,48 +3,48 @@
 import hep.aida.IHistogram2D;
 
 public class FormattedPlot2D extends FormattedPlot {
-    private final IHistogram2D plot;
-    private final boolean logarithmic;
-    private final double xAxisRange;
-    private final double yAxisRange;
-    
-    public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName) {
-        super(xAxis, yAxis, plotName);
-        this.plot = plot;
-        this.xAxisRange = -1;
-        this.yAxisRange = -1;
-        this.logarithmic = logarithmic;
-    }
-    
-    public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName, double xAxisRange, double yAxisRange) {
-        super(xAxis, yAxis, plotName);
-        this.plot = plot;
-        this.xAxisRange = xAxisRange;
-        this.yAxisRange = yAxisRange;
-        this.logarithmic = logarithmic;
-    }
-    
-    public IHistogram2D getPlot() {
-        return plot;
-    }
-    
-    public boolean isLogarithmic() {
-        return logarithmic;
-    }
-    
-    public boolean definesXAxisRange() {
-        return xAxisRange != -1;
-    }
-    
-    public boolean definesYAxisRange() {
-        return yAxisRange != -1;
-    }
-    
-    public double getXAxisRange() {
-        return xAxisRange;
-    }
-    
-    public double getYAxisRange() {
-        return yAxisRange;
-    }
+	private final IHistogram2D plot;
+	private final boolean logarithmic;
+	private final double xAxisRange;
+	private final double yAxisRange;
+	
+	public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName) {
+		super(xAxis, yAxis, plotName);
+		this.plot = plot;
+		this.xAxisRange = -1;
+		this.yAxisRange = -1;
+		this.logarithmic = logarithmic;
+	}
+	
+	public FormattedPlot2D(IHistogram2D plot, boolean logarithmic, String xAxis, String yAxis, String plotName, double xAxisRange, double yAxisRange) {
+		super(xAxis, yAxis, plotName);
+		this.plot = plot;
+		this.xAxisRange = xAxisRange;
+		this.yAxisRange = yAxisRange;
+		this.logarithmic = logarithmic;
+	}
+	
+	public IHistogram2D getPlot() {
+		return plot;
+	}
+	
+	public boolean isLogarithmic() {
+		return logarithmic;
+	}
+	
+	public boolean definesXAxisRange() {
+		return xAxisRange != -1;
+	}
+	
+	public boolean definesYAxisRange() {
+		return yAxisRange != -1;
+	}
+	
+	public double getXAxisRange() {
+		return xAxisRange;
+	}
+	
+	public double getYAxisRange() {
+		return yAxisRange;
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotFormatModule.java	Tue Sep 27 08:50:14 2016
@@ -7,8 +7,6 @@
 import hep.aida.IPlotterFactory;
 import hep.aida.ref.plotter.PlotterRegion;
 
-import org.hps.users.kmccarty.plots.PlotsFormatter.ColorStyle;
-
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
@@ -17,189 +15,220 @@
 import java.util.List;
 
 public class PlotFormatModule {
-    private String width = "2000";
-    private String height = "1200";
-    private List<FormattedPlot1D> formattedPlots1D = new ArrayList<FormattedPlot1D>();
-    private List<FormattedPlot2D> formattedPlots2D = new ArrayList<FormattedPlot2D>();
-    
-    public void addPlot1D(FormattedPlot1D plot) {
-        formattedPlots1D.add(plot);
-    }
-    
-    public void addPlot2D(FormattedPlot2D plot) {
-        formattedPlots2D.add(plot);
-    }
-    
-    public void setDisplayHeight(int height) {
-        this.height = "" + height;
-    }
-    
-    public void setDisplayWidth(int width) {
-        this.width = "" + width;
-    }
-    
-    public void displayPlots() {
-        try { processPlots(null); }
-        catch (IOException e) { e.printStackTrace(); }
-    }
-    
-    public void savePlots(String filePath) throws IOException {
-        processPlots(filePath);
-    }
-    
-    private void processPlots(String filePath) throws IOException {
-        // Create a plotter factory.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        IPlotterFactory plotterFactory = af.createPlotterFactory();
-        
-        // Format and display the 1D plots.
-        for(FormattedPlot1D formattedPlot : formattedPlots1D) {
-            // Get the plot.
-            IHistogram1D plot = formattedPlot.getPlot();
-            
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(plot.title());
-            plotter.createRegions(1);
-            plotter.region(0).plot(plot);
-            
-            // Set the axis range.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            if(formattedPlot.definesAxisRange()) {
-                region.getPlot().getXAxis().setMax(formattedPlot.getAxisRange());
-            }
-            
-            // Format the axis labels.
-            region.getPlot().setTitle(formattedPlot.getPlotName());
-            region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
-            region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
-            
-            // Format the fonts and general plot presentation.
-            PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { formattedPlot.getColorStyle() });
-            
-            // Set the plotter dimensions.
-            plotter.setParameter("plotterWidth", width);
-            plotter.setParameter("plotterHeight", height);
-            
-            // If the file path is null, display the plots. Otherwise,
-            // save them to the destination folder.
-            if(filePath == null) { plotter.show(); }
-            else {
-                File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
-                if(plotFile.exists()) { plotFile.delete(); }
-                plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
-                System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
-            }
-        }
-        
-        // Format and display the 2D plots.
-        for(FormattedPlot2D formattedPlot : formattedPlots2D) {
-            // Get the plot.
-            IHistogram2D plot = formattedPlot.getPlot();
-            
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(formattedPlot.getPlotName());
-            plotter.createRegions(1);
-            plotter.region(0).plot(plot);
-            
-            // Set the axis range.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            if(formattedPlot.definesXAxisRange()) {
-                region.getPlot().getXAxis().setMax(formattedPlot.getXAxisRange());
-            } if(formattedPlot.definesYAxisRange()) {
-                region.getPlot().getYAxis().setMax(formattedPlot.getYAxisRange());
-            }
-            
-            // Format the axis labels.
-            region.getPlot().setTitle(formattedPlot.getPlotName());
-            region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
-            region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
-            
-            // Format the fonts and general plot presentation.
-            PlotsFormatter.setDefault2DStyle(region, formattedPlot.isLogarithmic());
-            
-            // Set the plotter dimensions.
-            plotter.setParameter("plotterWidth", width);
-            plotter.setParameter("plotterHeight", height);
-            
-            // If the file path is null, display the plots. Otherwise,
-            // save them to the destination folder.
-            if(filePath == null) { plotter.show(); }
-            else {
-                File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
-                if(plotFile.exists()) { plotFile.delete(); }
-                plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
-                System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
-            }
-        }
-    }
-    
-    public void exportPlots(String filePath) throws IOException {
-        // Export the 1D plots in a text format.
-        for(FormattedPlot1D plot : formattedPlots1D) {
-            exportPlot(filePath, plot);
-        }
-        
-        // Export the 2D plots in a text format.
-        for(FormattedPlot2D plot : formattedPlots2D) {
-            exportPlot(filePath, plot);
-        }
-    }
-    
-    private static final void exportPlot(String filePath, FormattedPlot plot) throws IOException {
-        // Check if this is a one or two dimensional plot.
-        boolean is1D = plot instanceof FormattedPlot1D;
-        
-        // Create a file object for the plot.
-        String plotPath = filePath + plot.getPlotName() + (is1D ? ".aida1D" : ".aida2D");
-        File datFile = new File(plotPath);
-        
-        // If the plot file already exists, delete it.
-        if(datFile.exists()) { datFile.delete(); }
-        
-        // Create a new file for the plot to occupy.
-        datFile.createNewFile();
-        
-        // Get the textual form of the plot.
-        String plotText = null;
-        if(is1D) { plotText = toTextFormat(((FormattedPlot1D) plot).getPlot()); }
-        else { plotText = toTextFormat(((FormattedPlot2D) plot).getPlot()); }
-        
-        // Write the plot text to the file.
-        BufferedWriter writer = new BufferedWriter(new FileWriter(datFile));
-        writer.write(plotText);
-        writer.close();
-        
-        // Note that the file was written.
-        System.out.printf("Plot \"%s\" was exported to path: %s%n", plot.getPlotName(), plotPath);
-    }
-    
-    private static final String toTextFormat(IHistogram1D plot) {
-        // Create a buffer to hold the converted plot.
-        StringBuffer buffer = new StringBuffer();
-        
-        // Iterate over the bins and output the plot in the format of
-        // "[BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
-        for(int bin = 0; bin < plot.axis().bins(); bin++) {
-            buffer.append(String.format("%f\t%f%n", plot.binMean(bin), plot.binHeight(bin)));
-        }
-        
-        // Return the converted file.
-        return buffer.toString();
-    }
-    
-    private static final String toTextFormat(IHistogram2D plot) {
-        // Create a buffer to hold the converted plot.
-        StringBuffer buffer = new StringBuffer();
-        
-        // Iterate over the bins and output the plot in the format of
-        // "[X_BIN_MEAN] [Y_BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
-        for(int xBin = 0; xBin < plot.xAxis().bins(); xBin++) {
-            for(int yBin = 0; yBin < plot.yAxis().bins(); yBin++) {
-                buffer.append(String.format("%f\t%f\t%f%n", plot.binMeanX(xBin, yBin), plot.binMeanY(xBin, yBin), plot.binHeight(xBin, yBin)));
-            }
-        }
-        
-        // Return the converted file.
-        return buffer.toString();
-    }
+	private String width = "2000";
+	private String height = "1200";
+	private List<FormattedPlot1D> formattedPlots1D = new ArrayList<FormattedPlot1D>();
+	private List<FormattedPlot2D> formattedPlots2D = new ArrayList<FormattedPlot2D>();
+	
+	public void addPlot1D(FormattedPlot1D plot) {
+		formattedPlots1D.add(plot);
+	}
+	
+	public void addPlot2D(FormattedPlot2D plot) {
+		formattedPlots2D.add(plot);
+	}
+	
+	public void setDisplayHeight(int height) {
+		this.height = "" + height;
+	}
+	
+	public void setDisplayWidth(int width) {
+		this.width = "" + width;
+	}
+	
+	public void displayPlots() {
+		try { processPlots(null); }
+		catch (IOException e) { e.printStackTrace(); }
+	}
+	
+	public void savePlots(String filePath) throws IOException {
+		processPlots(filePath);
+	}
+	
+	private void processPlots(String filePath) throws IOException {
+		// Create a plotter factory.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		IPlotterFactory plotterFactory = af.createPlotterFactory();
+		
+		// Format and display the 1D plots.
+		for(FormattedPlot1D formattedPlot : formattedPlots1D) {
+			// Get the plot(s).
+			IHistogram1D[] plots = formattedPlot.getPlots();
+			
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(formattedPlot.getPlotName());
+			plotter.createRegions(1);
+			for(IHistogram1D plot : plots) {
+				plotter.region(0).plot(plot);
+			}
+			
+			// Set the axis range.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			if(formattedPlot.definesAxisRange()) {
+				region.getPlot().getXAxis().setMin(formattedPlot.getAxisMin());
+				region.getPlot().getXAxis().setMax(formattedPlot.getAxisMax());
+			}
+			
+			// Format the axis labels.
+			region.getPlot().setTitle(formattedPlot.getPlotName());
+			region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
+			region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
+			
+			// Format the fonts and general plot presentation.
+			PlotsFormatter.setDefault1DStyle(region, formattedPlot.getColorStyle(), formattedPlot.getDisplayStyle());
+			
+			// Set the plotter dimensions.
+			plotter.setParameter("plotterWidth", width);
+			plotter.setParameter("plotterHeight", height);
+			
+			// If the file path is null, display the plots. Otherwise,
+			// save them to the destination folder.
+			if(filePath == null) { plotter.show(); }
+			else {
+				String name = sanitize(formattedPlot.getPlotName());
+				File plotFile = new File(filePath + name + ".png");
+				if(plotFile.exists()) { plotFile.delete(); }
+				plotter.writeToFile(filePath + name + ".png");
+				System.out.printf("Saved plot \"%s\" to path: %s%n", name, filePath + name + ".png");
+			}
+		}
+		
+		// Format and display the 2D plots.
+		for(FormattedPlot2D formattedPlot : formattedPlots2D) {
+			// Get the plot.
+			IHistogram2D plot = formattedPlot.getPlot();
+			
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(formattedPlot.getPlotName());
+			plotter.createRegions(1);
+			plotter.region(0).plot(plot);
+			
+			// Set the axis range.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			if(formattedPlot.definesXAxisRange()) {
+				region.getPlot().getXAxis().setMax(formattedPlot.getXAxisRange());
+			} if(formattedPlot.definesYAxisRange()) {
+				region.getPlot().getYAxis().setMax(formattedPlot.getYAxisRange());
+			}
+			
+			// Format the axis labels.
+			region.getPlot().setTitle(formattedPlot.getPlotName());
+			region.getPlot().getXAxis().setLabel(formattedPlot.getXAxisName());
+			region.getPlot().getYAxis().setLabel(formattedPlot.getYAxisName());
+			
+			// Format the fonts and general plot presentation.
+			PlotsFormatter.setDefault2DStyle(region, formattedPlot.isLogarithmic());
+			
+			// Set the plotter dimensions.
+			plotter.setParameter("plotterWidth", width);
+			plotter.setParameter("plotterHeight", height);
+			
+			// If the file path is null, display the plots. Otherwise,
+			// save them to the destination folder.
+			if(filePath == null) { plotter.show(); }
+			else {
+				File plotFile = new File(filePath + formattedPlot.getPlotName() + ".png");
+				if(plotFile.exists()) { plotFile.delete(); }
+				plotter.writeToFile(filePath + formattedPlot.getPlotName() + ".png");
+				System.out.printf("Saved plot \"%s\" to path: %s%n", formattedPlot.getPlotName(), filePath + formattedPlot.getPlotName() + ".png");
+			}
+		}
+	}
+	
+	public void exportPlots(String filePath) throws IOException {
+		// Export the 1D plots in a text format.
+		for(FormattedPlot1D plot : formattedPlots1D) {
+			exportPlot(filePath, plot);
+		}
+		
+		// Export the 2D plots in a text format.
+		for(FormattedPlot2D plot : formattedPlots2D) {
+			exportPlot(filePath, plot);
+		}
+	}
+	
+	private static final void exportPlot(String filePath, FormattedPlot plot) throws IOException {
+		// Check if this is a one or two dimensional plot.
+		boolean is1D = plot instanceof FormattedPlot1D;
+		
+		// Create a file object for the plot.
+		String plotPath = filePath + plot.getPlotName() + (is1D ? ".aida1D" : ".aida2D");
+		File datFile = new File(plotPath);
+		
+		// If the plot file already exists, delete it.
+		if(datFile.exists()) { datFile.delete(); }
+		
+		// Create a new file for the plot to occupy.
+		datFile.createNewFile();
+		
+		// Get the textual form of the plot.
+		String plotText = null;
+		if(is1D) { plotText = toTextFormat(((FormattedPlot1D) plot).getPlots()); }
+		else { plotText = toTextFormat(((FormattedPlot2D) plot).getPlot()); }
+		
+		// Write the plot text to the file.
+		BufferedWriter writer = new BufferedWriter(new FileWriter(datFile));
+		writer.write(plotText);
+		writer.close();
+		
+		// Note that the file was written.
+		System.out.printf("Plot \"%s\" was exported to path: %s%n", plot.getPlotName(), plotPath);
+	}
+	
+	private static final String toTextFormat(IHistogram1D[] plot) {
+		// Create a buffer to hold the converted plot.
+		StringBuffer buffer = new StringBuffer();
+		
+		// Iterate over the bins and output the plot in the format of
+		// "[BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
+		for(int bin = 0; bin < plot[0].axis().bins(); bin++) {
+			// Add the bin value to the file once.
+			buffer.append(String.format("%f", plot[0].binMean(bin)));
+			
+			// Add all the plots' bin heights to the line.)
+			for(int i = 0; i < plot.length; i++) {
+				buffer.append(String.format("\t%f", plot[i].binHeight(bin)));
+			}
+		}
+		
+		// Return the converted file.
+		return buffer.toString();
+	}
+	
+	private static final String toTextFormat(IHistogram2D plot) {
+		// Create a buffer to hold the converted plot.
+		StringBuffer buffer = new StringBuffer();
+		
+		// Iterate over the bins and output the plot in the format of
+		// "[X_BIN_MEAN] [Y_BIN_MEAN] [BIN_VALUE]" with a tab delimiter.
+		for(int xBin = 0; xBin < plot.xAxis().bins(); xBin++) {
+			for(int yBin = 0; yBin < plot.yAxis().bins(); yBin++) {
+				buffer.append(String.format("%f\t%f\t%f%n", plot.binMeanX(xBin, yBin), plot.binMeanY(xBin, yBin), plot.binHeight(xBin, yBin)));
+			}
+		}
+		
+		// Return the converted file.
+		return buffer.toString();
+	}
+	
+	/**
+	 * Sanitizes a filename for saving.
+	 * @param filename - The original filename.
+	 * @return Returns the filename, but with all characters except
+	 * those which are alphanumeric or a dash ('-') excluded.
+	 */
+	private static final String sanitize(String filename) {
+		// Store the sanitized filename.
+		StringBuffer cleanName = new StringBuffer();
+		
+		// Only allow alphanumeric characters.
+		for(char c : filename.toCharArray()) {
+			if(Character.isLetterOrDigit(c) || c == '-') {
+				cleanName.append(c);
+			}
+		}
+		
+		// Return the cleaned name.
+		return cleanName.toString();
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/PlotsFormatter.java	Tue Sep 27 08:50:14 2016
@@ -8,120 +8,146 @@
 import java.awt.Font;
 
 public class PlotsFormatter {
-    // Define plot fonts.
-    public static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 30);
-    public static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  35);
-    public static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  45);
-    
-    // Defines the color style options for plot data.
-    public static enum ColorStyle {
-         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-        
-        private final Color fillColor;
-        private final Color lineColor;
-        
-        private ColorStyle(Color fillColor, Color lineColor) {
-            this.fillColor = fillColor;
-            this.lineColor = lineColor;
-        }
-        
-        public Color getFillColor() { return fillColor; }
-        
-        public Color getLineColor() { return lineColor; }
-    };
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     * @param color - The data color settings to use.
-     */
-    public static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-        // Get the names of each plot on in the region.
-        String[] dataNames = region.getAllDataNames();
-        
-        // Check whether this is an overlay plot. Overlay plots contain
-        // more than one data name.
-        boolean overlay = (dataNames.length > 1 ? true : false);
-        
-        // Iterate over each plot in the region.
-        for(int i = 0; i < dataNames.length; i++) {
-            // Set the overlay style if needed.
-            if(overlay) {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with no fill. The color is set by the "color" argument.
-                fillStyle.setHistogramFill(false);
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-                
-                // Set the legend text style.
-                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-            }
-            
-            // Otherwise, set the fill style for a single plot.
-            else {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with a fill color. The colors are defined by the
-                // "color" argument.
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarColor(color[i].getFillColor());
-                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-            }
-            
-            // Set the statistics box style.
-            region.getPlot().getStats().setVisible(true);
-            region.getPlot().getStats().setFont(BASIC_FONT);
-            
-            // Set the title font.
-            region.getPlot().getTitleObject().setFont(TITLE_FONT);
-            
-            // Set the axis tick-mark fonts.
-            region.getPlot().getXAxis().setFont(BASIC_FONT);
-            region.getPlot().getYAxis().setFont(BASIC_FONT);
-            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-        }
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     */
-    public static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-        // Get the fill style object. 2D plots should never be overlay
-        // plots, so there should only ever be one data name.
-        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-        
-        // Set the fill style for a two-dimensional plot.
-        if(logarithmic) { fillStyle.setLogZ(true); }
-        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-        
-        // Make the statistics box invisible.
-        region.getPlot().getStats().setVisible(false);
-        
-        // Set the general plot font (which is also the z-axis font).
-        region.getPlot().setFont(BASIC_FONT);
-        
-        // Set the title font.
-        region.getPlot().getTitleObject().setFont(TITLE_FONT);
-        
-        // Set the axis tick-mark fonts.
-        region.getPlot().getXAxis().setFont(BASIC_FONT);
-        region.getPlot().getYAxis().setFont(BASIC_FONT);
-        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-    }
+	// Define plot fonts.
+	public static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 30);
+	public static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  35);
+	public static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  45);
+	
+	// Defines whether the histogram should be a line or bar histogram.
+	public enum DisplayStyle { BAR, LINE };
+	
+	// Defines the color style options for plot data.
+	public static enum ColorStyle {
+		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+		
+		private final Color fillColor;
+		private final Color lineColor;
+		
+		private ColorStyle(Color fillColor, Color lineColor) {
+			this.fillColor = fillColor;
+			this.lineColor = lineColor;
+		}
+		
+		public Color getFillColor() { return fillColor; }
+		
+		public Color getLineColor() { return lineColor; }
+	};
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 * @param color - The data color settings to use.
+	 */
+	public static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color, DisplayStyle style) {
+		// Get the names of each plot on in the region.
+		String[] dataNames = region.getAllDataNames();
+		
+		// Check whether this is an overlay plot. Overlay plots contain
+		// more than one data name.
+		boolean overlay = (dataNames.length > 1 ? true : false);
+		System.out.println("Is overlay: " + overlay);
+		
+		// Iterate over each plot in the region.
+		for(int i = 0; i < dataNames.length; i++) {
+			System.out.println("Processing data name [" + i + "]: " + dataNames[i]);
+			
+			// Set the overlay style if needed.
+			if(overlay) {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with no fill. The color is set by the "color" argument.
+				fillStyle.setHistogramFill(false);
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setShowErrorBars(false);
+				if(style == DisplayStyle.LINE) {
+					fillStyle.setLinesBetweenPointsWidth(3);
+					fillStyle.setShowHistogramBars(false);
+					fillStyle.setShowLinesBetweenPoints(true);
+					fillStyle.setLineColor(color[i].getFillColor());
+				} else {
+					fillStyle.setShowHistogramBars(true);
+					fillStyle.setShowLinesBetweenPoints(false);
+					fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+				}
+				
+				// Set the legend text style.
+				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+			}
+			
+			// Otherwise, set the fill style for a single plot.
+			else {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with a fill color. The colors are defined by the
+				// "color" argument.
+				fillStyle.setHistogramBarLineWidth(3);
+				if(style == DisplayStyle.LINE) {
+					fillStyle.setHistogramFill(false);
+					fillStyle.setLinesBetweenPointsWidth(3);
+					fillStyle.setShowHistogramBars(false);
+					fillStyle.setShowLinesBetweenPoints(true);
+					fillStyle.setLineColor(color[i].getFillColor());
+				} else {
+					fillStyle.setShowHistogramBars(true);
+					fillStyle.setShowLinesBetweenPoints(false);
+					fillStyle.setHistogramBarColor(color[i].getFillColor());
+					fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+				}
+			}
+			
+			// Set the statistics box style.
+			region.getPlot().getStats().setVisible(true);
+			region.getPlot().getStats().setFont(BASIC_FONT);
+			
+			// Set the title font.
+			region.getPlot().getTitleObject().setFont(TITLE_FONT);
+			
+			// Set the axis tick-mark fonts.
+			region.getPlot().getXAxis().setFont(BASIC_FONT);
+			region.getPlot().getYAxis().setFont(BASIC_FONT);
+			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+		}
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 */
+	public static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+		// Get the fill style object. 2D plots should never be overlay
+		// plots, so there should only ever be one data name.
+		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+		
+		// Set the fill style for a two-dimensional plot.
+		if(logarithmic) { fillStyle.setLogZ(true); }
+		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+		
+		// Make the statistics box invisible.
+		region.getPlot().getStats().setVisible(false);
+		
+		// Set the general plot font (which is also the z-axis font).
+		region.getPlot().setFont(BASIC_FONT);
+		
+		// Set the title font.
+		region.getPlot().getTitleObject().setFont(TITLE_FONT);
+		
+		// Set the axis tick-mark fonts.
+		region.getPlot().getXAxis().setFont(BASIC_FONT);
+		region.getPlot().getYAxis().setFont(BASIC_FONT);
+		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/InvariantMassPlotsFormatter.java	Tue Sep 27 08:50:14 2016
@@ -19,317 +19,317 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class InvariantMassPlotsFormatter {
-    // Define plot fonts.
-    private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
-    private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
-    private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
-    
-    // Defines the color style options for plot data.
-    private enum ColorStyle {
-         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-        
-        private final Color fillColor;
-        private final Color lineColor;
-        
-        private ColorStyle(Color fillColor, Color lineColor) {
-            this.fillColor = fillColor;
-            this.lineColor = lineColor;
-        }
-        
-        public Color getFillColor() { return fillColor; }
-        
-        public Color getLineColor() { return lineColor; }
-    };
-        
-    /**
-     * Loads all plots in a file and formats them according to the
-     * indicated style.
-     * @param args - Unused default executable parameter.
-     * @throws IOException Occurs if there is an issue opening the file.
-     */
-    public static void main(String[] args) throws IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String[] plotFile = {
-                rootDir + "temp.aida"
-        };
-        
-        // Define the run numbers for each file.
-        String[] runNumber = { "1 Hits", "2 Hits" };
-        
-        // Define the scaling factors for each plot.
-        double scaleFactor = 13.254;
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree[] tree = new ITree[plotFile.length];
-        for(int i = 0; i < plotFile.length; i++) {
-            tree[i] = af.createTreeFactory().create(plotFile[i]);
-            if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        }
-        
-        // Get the histograms.
-        IHistogram1D[] invariantMassPlots = new IHistogram1D[3];
-        invariantMassPlots[0] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (1 Hit)");
-        invariantMassPlots[1] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (2 Hit)");
-        IHistogram1D electronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Electron Energy");
-        IHistogram1D positronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Positron Energy");
-        IHistogram1D energySumPlot = (IHistogram1D) tree[0].find("Trident Analysis/Energy Sum Distribution");
-        IHistogram2D energySum2DPlot = (IHistogram2D) tree[0].find("Trident Analysis/2D Energy Distribution");
-        IHistogram1D tridentElectronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Electron Energy");
-        IHistogram1D tridentPositronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Positron Energy");
-        
-        // Define the plot titles and arrays.
-        IHistogram[] plots = { electronEnergyPlot, positronEnergyPlot, energySumPlot, tridentElectronEnergyPlot, tridentPositronEnergyPlot };
-        String[] titles = { "Electron Energy", "Positron Energy", "Energy Sum", "Trident Electron Energy", "Trident Positron Energy" };
-        String[] xTitles = { "Energy (GeV)", "Energy (GeV)", "Energy Sum (GeV)", "Energy (GeV)", "Energy (GeV)" };
-        
-        // Re-bin the histograms to have 5-times larger bins. First,
-        // get the bin count and upper and lower bounds of the plot.
-        int bins = invariantMassPlots[0].axis().bins();
-        double low = invariantMassPlots[0].axis().binLowerEdge(0);
-        double high = invariantMassPlots[0].axis().binUpperEdge(invariantMassPlots[0].axis().bins() - 1);
-        
-        // Create new plots with the larger bin sizes.
-        AIDA aida = AIDA.defaultInstance();
-        IHistogram1D[] newPlot = new IHistogram1D[2];
-        newPlot[0] = aida.histogram1D("Particle Invariant Mass (1 Hit)", bins / 5, low, high);
-        newPlot[1] = aida.histogram1D("Particle Invariant Mass (2 Hit)", bins / 5, low, high);
-        
-        // Populate the new plots with the data from the old ones.
-        for(int j = 0; j < 2; j++) {
-            for(int i = 0; i < bins; i++) {
-                int entries = invariantMassPlots[j].binEntries(i);
-                double center = invariantMassPlots[j].axis().binCenter(i);
-                for(int k = 0; k < entries; k++) {
-                    newPlot[j].fill(center);
-                }
-            }
-        }
-        
-        // Replace the old plots.
-        invariantMassPlots = newPlot;
-        
-        // Create a plotter factory.
-        IPlotterFactory plotterFactory = af.createPlotterFactory();
-        
-        // Format and display the basic histograms.
-        for(int i = 0; i < plots.length; i++) {
-            // Scale the histogram by the appropriate scaling factor.
-            plots[i].scale(1.0 / scaleFactor);
-            
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(titles[i]);
-            plotter.createRegions(1);
-            plotter.region(0).plot(plots[i]);
-            
-            // Format the axis labels.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            region.getPlot().setTitle(titles[i]);
-            region.getPlot().getXAxis().setLabel(xTitles[i]);
-            region.getPlot().getYAxis().setLabel("Rate (Hz)");
-            
-            // Format the fonts and general plot presentation.
-            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-            
-            // Show the plot.
-            plotter.setParameter("plotterWidth", "2000");
-            plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Format and display the 2D histogram.
-        energySum2DPlot.scale(1.0 / scaleFactor);
-        IPlotter plotter2D = plotterFactory.create("2D Energy Sum");
-        plotter2D.createRegions(1);
-        plotter2D.region(0).plot(energySum2DPlot);
-        
-        // Format the axis labels.
-        PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
-        region2D.getPlot().setTitle("2D Energy Sum");
-        region2D.getPlot().getXAxis().setLabel("Electron Energy (GeV)");
-        region2D.getPlot().getYAxis().setLabel("Positron Energy (GeV)");
-        
-        // Format the fonts and general plot presentation.
-        setDefault2DStyle(region2D, false);
-        
-        // Show the plot.
-        plotter2D.setParameter("plotterWidth", "2000");
-        plotter2D.setParameter("plotterHeight", "1200");
-        plotter2D.show();
-        
-        // Format and display the histograms.
-        for(int i = 0; i < 2; i++) {
-            // Scale the histogram by the appropriate scaling factor.
-            invariantMassPlots[i].scale(1.0 / scaleFactor);
-            
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create("Particle Invariant Mass (" + runNumber[i] + ")");
-            plotter.createRegions(1);
-            plotter.region(0).plot(invariantMassPlots[i]);
-            
-            // Format the axis labels.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            region.getPlot().setTitle("Particle Invariant Mass (" + runNumber[i] + ")");
-            region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
-            region.getPlot().getYAxis().setLabel("Rate (Hz)");
-            
-            // Format the fonts and general plot presentation.
-            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-            
-            // Show the plot.
-            plotter.setParameter("plotterWidth", "2000");
-            plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Note which plot is the numerator and which is the denominator.
-        int numerator   = 0;
-        int denominator = 1;
-        
-        // Create a new histogram to display the ratios of the rates.
-        IHistogram1D ratioPlot = AIDA.defaultInstance().histogram1D("Invariant Mass Ratio (" + runNumber[numerator] + " / "
-                + runNumber[denominator] + ")", invariantMassPlots[0].axis().bins(),
-                invariantMassPlots[0].axis().lowerEdge(), invariantMassPlots[0].axis().upperEdge());
-        
-        // Iterate over each bin.
-        for(int bin = 0; bin < invariantMassPlots[0].axis().bins(); bin++) {
-            // Calculate the ratio.
-            double ratio = invariantMassPlots[numerator].binHeight(bin) / invariantMassPlots[denominator].binHeight(bin);
-            
-            // If the ratio is either not a number of infinite, skip
-            // this bin.
-            if(Double.isNaN(ratio) || Double.isInfinite(ratio)) { continue; }
-            
-            // Populate the ratio plot bin.
-            ratioPlot.fill(invariantMassPlots[0].axis().binCenter(bin), ratio);
-        }
-        
-        // Create a plotter and plotting region for the plot.
-        IPlotter plotter = plotterFactory.create("Invariant Mass Ratio (5411 / 5554)");
-        plotter.createRegions(1);
-        plotter.region(0).plot(ratioPlot);
-        
-        // Format the axis labels.
-        PlotterRegion region = (PlotterRegion) plotter.region(0);
-        region.getPlot().setTitle("Invariant Mass Ratio (" + runNumber[numerator] + " / " + runNumber[denominator] + ")");
-        region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
-        region.getPlot().getXAxis().setMin(0.010);
-        region.getPlot().getXAxis().setMax(0.060);
-        region.getPlot().getYAxis().setLabel("Ratio");
-        
-        // Format the fonts and general plot presentation.
-        setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-        
-        // Disable the error bars.
-        JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-        fillStyle.setShowErrorBars(false);
-        
-        // Show the plot.
-        plotter.setParameter("plotterWidth", "2000");
-        plotter.setParameter("plotterHeight", "1200");
-        plotter.show();
-        
-        // Close the trees.
-        for(int i = 0; i < plotFile.length; i++) {
-            tree[i].close();
-        }
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     * @param color - The data color settings to use.
-     */
-    private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-        // Get the names of each plot on in the region.
-        String[] dataNames = region.getAllDataNames();
-        
-        // Check whether this is an overlay plot. Overlay plots contain
-        // more than one data name.
-        boolean overlay = (dataNames.length > 1 ? true : false);
-        
-        // Iterate over each plot in the region.
-        for(int i = 0; i < dataNames.length; i++) {
-            // Set the overlay style if needed.
-            if(overlay) {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with no fill. The color is set by the "color" argument.
-                fillStyle.setHistogramFill(false);
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-                
-                // Set the legend text style.
-                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-            }
-            
-            // Otherwise, set the fill style for a single plot.
-            else {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with a fill color. The colors are defined by the
-                // "color" argument.
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarColor(color[i].getFillColor());
-                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-            }
-            
-            // Set the statistics box style.
-            region.getPlot().getStats().setVisible(true);
-            region.getPlot().getStats().setFont(BASIC_FONT);
-            
-            // Set the title font.
-            region.getPlot().getTitleObject().setFont(TITLE_FONT);
-            
-            // Set the axis tick-mark fonts.
-            region.getPlot().getXAxis().setFont(BASIC_FONT);
-            region.getPlot().getYAxis().setFont(BASIC_FONT);
-            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-        }
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     */
-    private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-        // Get the fill style object. 2D plots should never be overlay
-        // plots, so there should only ever be one data name.
-        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-        
-        // Set the fill style for a two-dimensional plot.
-        if(logarithmic) { fillStyle.setLogZ(true); }
-        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-        
-        // Make the statistics box invisible.
-        region.getPlot().getStats().setVisible(false);
-        
-        // Set the general plot font (which is also the z-axis font).
-        region.getPlot().setFont(BASIC_FONT);
-        
-        // Set the title font.
-        region.getPlot().getTitleObject().setFont(TITLE_FONT);
-        
-        // Set the axis tick-mark fonts.
-        region.getPlot().getXAxis().setFont(BASIC_FONT);
-        region.getPlot().getYAxis().setFont(BASIC_FONT);
-        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-    }
+	// Define plot fonts.
+	private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
+	private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
+	private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
+	
+	// Defines the color style options for plot data.
+	private enum ColorStyle {
+		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+		
+		private final Color fillColor;
+		private final Color lineColor;
+		
+		private ColorStyle(Color fillColor, Color lineColor) {
+			this.fillColor = fillColor;
+			this.lineColor = lineColor;
+		}
+		
+		public Color getFillColor() { return fillColor; }
+		
+		public Color getLineColor() { return lineColor; }
+	};
+		
+	/**
+	 * Loads all plots in a file and formats them according to the
+	 * indicated style.
+	 * @param args - Unused default executable parameter.
+	 * @throws IOException Occurs if there is an issue opening the file.
+	 */
+	public static void main(String[] args) throws IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String[] plotFile = {
+				rootDir + "temp.aida"
+		};
+		
+		// Define the run numbers for each file.
+		String[] runNumber = { "1 Hits", "2 Hits" };
+		
+		// Define the scaling factors for each plot.
+		double scaleFactor = 13.254;
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree[] tree = new ITree[plotFile.length];
+		for(int i = 0; i < plotFile.length; i++) {
+			tree[i] = af.createTreeFactory().create(plotFile[i]);
+			if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		}
+		
+		// Get the histograms.
+		IHistogram1D[] invariantMassPlots = new IHistogram1D[3];
+		invariantMassPlots[0] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (1 Hit)");
+		invariantMassPlots[1] = (IHistogram1D) tree[0].find("Trident Analysis/Particle Invariant Mass (2 Hit)");
+		IHistogram1D electronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Electron Energy");
+		IHistogram1D positronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Positron Energy");
+		IHistogram1D energySumPlot = (IHistogram1D) tree[0].find("Trident Analysis/Energy Sum Distribution");
+		IHistogram2D energySum2DPlot = (IHistogram2D) tree[0].find("Trident Analysis/2D Energy Distribution");
+		IHistogram1D tridentElectronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Electron Energy");
+		IHistogram1D tridentPositronEnergyPlot = (IHistogram1D) tree[0].find("Trident Analysis/Trident Positron Energy");
+		
+		// Define the plot titles and arrays.
+		IHistogram[] plots = { electronEnergyPlot, positronEnergyPlot, energySumPlot, tridentElectronEnergyPlot, tridentPositronEnergyPlot };
+		String[] titles = { "Electron Energy", "Positron Energy", "Energy Sum", "Trident Electron Energy", "Trident Positron Energy" };
+		String[] xTitles = { "Energy (GeV)", "Energy (GeV)", "Energy Sum (GeV)", "Energy (GeV)", "Energy (GeV)" };
+		
+		// Re-bin the histograms to have 5-times larger bins. First,
+		// get the bin count and upper and lower bounds of the plot.
+		int bins = invariantMassPlots[0].axis().bins();
+		double low = invariantMassPlots[0].axis().binLowerEdge(0);
+		double high = invariantMassPlots[0].axis().binUpperEdge(invariantMassPlots[0].axis().bins() - 1);
+		
+		// Create new plots with the larger bin sizes.
+		AIDA aida = AIDA.defaultInstance();
+		IHistogram1D[] newPlot = new IHistogram1D[2];
+		newPlot[0] = aida.histogram1D("Particle Invariant Mass (1 Hit)", bins / 5, low, high);
+		newPlot[1] = aida.histogram1D("Particle Invariant Mass (2 Hit)", bins / 5, low, high);
+		
+		// Populate the new plots with the data from the old ones.
+		for(int j = 0; j < 2; j++) {
+			for(int i = 0; i < bins; i++) {
+				int entries = invariantMassPlots[j].binEntries(i);
+				double center = invariantMassPlots[j].axis().binCenter(i);
+				for(int k = 0; k < entries; k++) {
+					newPlot[j].fill(center);
+				}
+			}
+		}
+		
+		// Replace the old plots.
+		invariantMassPlots = newPlot;
+		
+		// Create a plotter factory.
+		IPlotterFactory plotterFactory = af.createPlotterFactory();
+		
+		// Format and display the basic histograms.
+		for(int i = 0; i < plots.length; i++) {
+			// Scale the histogram by the appropriate scaling factor.
+			plots[i].scale(1.0 / scaleFactor);
+			
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(titles[i]);
+			plotter.createRegions(1);
+			plotter.region(0).plot(plots[i]);
+			
+			// Format the axis labels.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			region.getPlot().setTitle(titles[i]);
+			region.getPlot().getXAxis().setLabel(xTitles[i]);
+			region.getPlot().getYAxis().setLabel("Rate (Hz)");
+			
+			// Format the fonts and general plot presentation.
+			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+			
+			// Show the plot.
+			plotter.setParameter("plotterWidth", "2000");
+			plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Format and display the 2D histogram.
+		energySum2DPlot.scale(1.0 / scaleFactor);
+		IPlotter plotter2D = plotterFactory.create("2D Energy Sum");
+		plotter2D.createRegions(1);
+		plotter2D.region(0).plot(energySum2DPlot);
+		
+		// Format the axis labels.
+		PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
+		region2D.getPlot().setTitle("2D Energy Sum");
+		region2D.getPlot().getXAxis().setLabel("Electron Energy (GeV)");
+		region2D.getPlot().getYAxis().setLabel("Positron Energy (GeV)");
+		
+		// Format the fonts and general plot presentation.
+		setDefault2DStyle(region2D, false);
+		
+		// Show the plot.
+		plotter2D.setParameter("plotterWidth", "2000");
+		plotter2D.setParameter("plotterHeight", "1200");
+		plotter2D.show();
+		
+		// Format and display the histograms.
+		for(int i = 0; i < 2; i++) {
+			// Scale the histogram by the appropriate scaling factor.
+			invariantMassPlots[i].scale(1.0 / scaleFactor);
+			
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create("Particle Invariant Mass (" + runNumber[i] + ")");
+			plotter.createRegions(1);
+			plotter.region(0).plot(invariantMassPlots[i]);
+			
+			// Format the axis labels.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			region.getPlot().setTitle("Particle Invariant Mass (" + runNumber[i] + ")");
+			region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
+			region.getPlot().getYAxis().setLabel("Rate (Hz)");
+			
+			// Format the fonts and general plot presentation.
+			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+			
+			// Show the plot.
+			plotter.setParameter("plotterWidth", "2000");
+			plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Note which plot is the numerator and which is the denominator.
+		int numerator   = 0;
+		int denominator = 1;
+		
+		// Create a new histogram to display the ratios of the rates.
+		IHistogram1D ratioPlot = AIDA.defaultInstance().histogram1D("Invariant Mass Ratio (" + runNumber[numerator] + " / "
+				+ runNumber[denominator] + ")", invariantMassPlots[0].axis().bins(),
+				invariantMassPlots[0].axis().lowerEdge(), invariantMassPlots[0].axis().upperEdge());
+		
+		// Iterate over each bin.
+		for(int bin = 0; bin < invariantMassPlots[0].axis().bins(); bin++) {
+			// Calculate the ratio.
+			double ratio = invariantMassPlots[numerator].binHeight(bin) / invariantMassPlots[denominator].binHeight(bin);
+			
+			// If the ratio is either not a number of infinite, skip
+			// this bin.
+			if(Double.isNaN(ratio) || Double.isInfinite(ratio)) { continue; }
+			
+			// Populate the ratio plot bin.
+			ratioPlot.fill(invariantMassPlots[0].axis().binCenter(bin), ratio);
+		}
+		
+		// Create a plotter and plotting region for the plot.
+		IPlotter plotter = plotterFactory.create("Invariant Mass Ratio (5411 / 5554)");
+		plotter.createRegions(1);
+		plotter.region(0).plot(ratioPlot);
+		
+		// Format the axis labels.
+		PlotterRegion region = (PlotterRegion) plotter.region(0);
+		region.getPlot().setTitle("Invariant Mass Ratio (" + runNumber[numerator] + " / " + runNumber[denominator] + ")");
+		region.getPlot().getXAxis().setLabel("Invariant Mass (GeV)");
+		region.getPlot().getXAxis().setMin(0.010);
+		region.getPlot().getXAxis().setMax(0.060);
+		region.getPlot().getYAxis().setLabel("Ratio");
+		
+		// Format the fonts and general plot presentation.
+		setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+		
+		// Disable the error bars.
+		JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+		fillStyle.setShowErrorBars(false);
+		
+		// Show the plot.
+		plotter.setParameter("plotterWidth", "2000");
+		plotter.setParameter("plotterHeight", "1200");
+		plotter.show();
+		
+		// Close the trees.
+		for(int i = 0; i < plotFile.length; i++) {
+			tree[i].close();
+		}
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 * @param color - The data color settings to use.
+	 */
+	private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+		// Get the names of each plot on in the region.
+		String[] dataNames = region.getAllDataNames();
+		
+		// Check whether this is an overlay plot. Overlay plots contain
+		// more than one data name.
+		boolean overlay = (dataNames.length > 1 ? true : false);
+		
+		// Iterate over each plot in the region.
+		for(int i = 0; i < dataNames.length; i++) {
+			// Set the overlay style if needed.
+			if(overlay) {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with no fill. The color is set by the "color" argument.
+				fillStyle.setHistogramFill(false);
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+				
+				// Set the legend text style.
+				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+			}
+			
+			// Otherwise, set the fill style for a single plot.
+			else {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with a fill color. The colors are defined by the
+				// "color" argument.
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setHistogramBarColor(color[i].getFillColor());
+				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+			}
+			
+			// Set the statistics box style.
+			region.getPlot().getStats().setVisible(true);
+			region.getPlot().getStats().setFont(BASIC_FONT);
+			
+			// Set the title font.
+			region.getPlot().getTitleObject().setFont(TITLE_FONT);
+			
+			// Set the axis tick-mark fonts.
+			region.getPlot().getXAxis().setFont(BASIC_FONT);
+			region.getPlot().getYAxis().setFont(BASIC_FONT);
+			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+		}
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 */
+	private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+		// Get the fill style object. 2D plots should never be overlay
+		// plots, so there should only ever be one data name.
+		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+		
+		// Set the fill style for a two-dimensional plot.
+		if(logarithmic) { fillStyle.setLogZ(true); }
+		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+		
+		// Make the statistics box invisible.
+		region.getPlot().getStats().setVisible(false);
+		
+		// Set the general plot font (which is also the z-axis font).
+		region.getPlot().setFont(BASIC_FONT);
+		
+		// Set the title font.
+		region.getPlot().getTitleObject().setFont(TITLE_FONT);
+		
+		// Set the axis tick-mark fonts.
+		region.getPlot().getXAxis().setFont(BASIC_FONT);
+		region.getPlot().getYAxis().setFont(BASIC_FONT);
+		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTEPlotFormatter.java	Tue Sep 27 08:50:14 2016
@@ -19,308 +19,308 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class MTEPlotFormatter {
-    // Define plot fonts.
-    private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
-    private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
-    private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
-    
-    // Defines the color style options for plot data.
-    private enum ColorStyle {
-         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-        
-        private final Color fillColor;
-        private final Color lineColor;
-        
-        private ColorStyle(Color fillColor, Color lineColor) {
-            this.fillColor = fillColor;
-            this.lineColor = lineColor;
-        }
-        
-        public Color getFillColor() { return fillColor; }
-        
-        public Color getLineColor() { return lineColor; }
-    };
-        
-    /**
-     * Loads all plots in a file and formats them according to the
-     * indicated style.
-     * @param args - Unused default executable parameter.
-     * @throws IOException Occurs if there is an issue opening the file.
-     */
-    public static void main(String[] args) throws IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String plotFile = rootDir + "temp.aida";
-        
-        // Define the scaling factors for each plot.
-        double scaleFactor = 1;
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree tree = af.createTreeFactory().create(plotFile);
-        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        
-        // Define index references for each event type.
-        int MOLLER  = 0;
-        int TRIDENT = 1;
-        int ELASTIC = 2;
-        
-        // Get the histograms.
-        IHistogram1D[] trackCountPlots = new IHistogram1D[3];
-        trackCountPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks");
-        trackCountPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks");
-        trackCountPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks");
-        
-        IHistogram1D[] energyPlots = new IHistogram1D[3];
-        energyPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution");
-        energyPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution");
-        energyPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution");
-        
-        IHistogram1D[] energySumPlots = new IHistogram1D[2];
-        energySumPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution");
-        energySumPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution");
-        
-        IHistogram2D[] energy2DPlots = new IHistogram2D[2];
-        energy2DPlots[MOLLER]  = (IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution");
-        energy2DPlots[TRIDENT] = (IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution");
-        
-        // Create a plotter factory.
-        IPlotterFactory plotterFactory = af.createPlotterFactory();
-        
-        // Format the track count plots.
-        for(IHistogram1D trackCountPlot : trackCountPlots) {
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(trackCountPlot.title());
-            plotter.createRegions(1);
-            plotter.region(0).plot(trackCountPlot);
-            
-            // Format the axis labels.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            region.getPlot().setTitle(trackCountPlot.title());
-            region.getPlot().getXAxis().setLabel("Number of Tracks");
-            region.getPlot().getYAxis().setLabel("Count");
-            
-            // Format the fonts and general plot presentation.
-            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-            
-            // Show the plot.
-            plotter.setParameter("plotterWidth", "2000");
-            plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Format the electron energy plots.
-        for(IHistogram1D energyPlot : energyPlots) {
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(energyPlot.title());
-            plotter.createRegions(1);
-            plotter.region(0).plot(energyPlot);
-            
-            // Format the axis labels.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            region.getPlot().setTitle(energyPlot.title());
-            region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
-            region.getPlot().getYAxis().setLabel("Count");
-            
-            // Format the fonts and general plot presentation.
-            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-            
-            // Show the plot.
-            plotter.setParameter("plotterWidth", "2000");
-            plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Format the energy sum plots.
-        for(IHistogram1D energySumPlot : energySumPlots) {
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(energySumPlot.title());
-            plotter.createRegions(1);
-            plotter.region(0).plot(energySumPlot);
-            
-            // Format the axis labels.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            region.getPlot().setTitle(energySumPlot.title());
-            region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
-            region.getPlot().getYAxis().setLabel("Count");
-            
-            // Format the fonts and general plot presentation.
-            setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-            
-            // Show the plot.
-            plotter.setParameter("plotterWidth", "2000");
-            plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Format the 2D energy sum plots.
-        for(IHistogram2D energy2DPlot : energy2DPlots) {
-            // Create a plotter and plotting region for the plot.
-            IPlotter plotter = plotterFactory.create(energy2DPlot.title());
-            plotter.createRegions(1);
-            plotter.region(0).plot(energy2DPlot);
-            
-            // Format the axis labels.
-            PlotterRegion region = (PlotterRegion) plotter.region(0);
-            region.getPlot().setTitle(energy2DPlot.title());
-            region.getPlot().getXAxis().setLabel("First Track Energy (GeV)");
-            region.getPlot().getYAxis().setLabel("Second Track Energy (GeV)");
-            
-            
-            // Format the fonts and general plot presentation.
-            setDefault2DStyle(region, false);
-            
-            // Show the plot.
-            plotter.setParameter("plotterWidth", "2000");
-            plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Disable the error bars.
-        //JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-        //fillStyle.setShowErrorBars(false);
-        
-        // Close the tree.
-        tree.close();
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     * @param color - The data color settings to use.
-     */
-    private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-        // Get the names of each plot on in the region.
-        String[] dataNames = region.getAllDataNames();
-        
-        // Check whether this is an overlay plot. Overlay plots contain
-        // more than one data name.
-        boolean overlay = (dataNames.length > 1 ? true : false);
-        
-        // Iterate over each plot in the region.
-        for(int i = 0; i < dataNames.length; i++) {
-            // Set the overlay style if needed.
-            if(overlay) {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with no fill. The color is set by the "color" argument.
-                fillStyle.setHistogramFill(false);
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-                
-                // Set the legend text style.
-                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-            }
-            
-            // Otherwise, set the fill style for a single plot.
-            else {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with a fill color. The colors are defined by the
-                // "color" argument.
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarColor(color[i].getFillColor());
-                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-            }
-            
-            // Set the statistics box style.
-            region.getPlot().getStats().setVisible(true);
-            region.getPlot().getStats().setFont(BASIC_FONT);
-            
-            // Set the title font.
-            region.getPlot().getTitleObject().setFont(TITLE_FONT);
-            
-            // Set the axis tick-mark fonts.
-            region.getPlot().getXAxis().setFont(BASIC_FONT);
-            region.getPlot().getYAxis().setFont(BASIC_FONT);
-            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-        }
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     */
-    private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
-        // Get the fill style object. 2D plots should never be overlay
-        // plots, so there should only ever be one data name.
-        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-        
-        // Set the fill style for a two-dimensional plot.
-        if(logarithmic) { fillStyle.setLogZ(true); }
-        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-        
-        // Make the statistics box invisible.
-        region.getPlot().getStats().setVisible(false);
-        
-        // Set the general plot font (which is also the z-axis font).
-        region.getPlot().setFont(BASIC_FONT);
-        
-        // Set the title font.
-        region.getPlot().getTitleObject().setFont(TITLE_FONT);
-        
-        // Set the axis tick-mark fonts.
-        region.getPlot().getXAxis().setFont(BASIC_FONT);
-        region.getPlot().getYAxis().setFont(BASIC_FONT);
-        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-    }
-    
-    /**
-     * Recursive method that gets all object names from a tree that
-     * are not directories. Method should not be called directly, but
-     * rather called only through the <code>getHistograms(ITree)</code>
-     * method.
-     * @param tree - The tree from which to obtain the object names.
-     * @param directory - The directory in which to search for objects.
-     * @param list - The list in which to place the objects.
-     * @return Returns the <code>List</code> collection that was given
-     * as an argument.
-     */
-    private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
-        // Get the list of objects in the directory.
-        String[] treeObjects = tree.listObjectNames(directory);
-        
-        // Print the objects.
-        for(String objectName : treeObjects) {
-            // Check if the object is a directory.
-            boolean isDirectory = isDirectory(objectName);
-            
-            // If the object is a directory, get the histograms from it.
-            if(isDirectory) {
-                getHistograms(tree, objectName, list);
-            }
-            
-            // If the object is a plot, add it to the list.
-            else { list.add(objectName); }
-        }
-        
-        // Return the list.
-        return list;
-    }
-    
-    /**
-     * Checks whether a tree object is a directory.
-     * @param object - The object to check.
-     * @return Returns <code>true</code> if the object is a directory
-     * and <code>false</code> otherwise.
-     */
-    private static final boolean isDirectory(String object) {
-        return (object.toCharArray()[object.length() - 1] == '/');
-    }
+	// Define plot fonts.
+	private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
+	private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
+	private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
+	
+	// Defines the color style options for plot data.
+	private enum ColorStyle {
+		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+		
+		private final Color fillColor;
+		private final Color lineColor;
+		
+		private ColorStyle(Color fillColor, Color lineColor) {
+			this.fillColor = fillColor;
+			this.lineColor = lineColor;
+		}
+		
+		public Color getFillColor() { return fillColor; }
+		
+		public Color getLineColor() { return lineColor; }
+	};
+		
+	/**
+	 * Loads all plots in a file and formats them according to the
+	 * indicated style.
+	 * @param args - Unused default executable parameter.
+	 * @throws IOException Occurs if there is an issue opening the file.
+	 */
+	public static void main(String[] args) throws IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String plotFile = rootDir + "temp.aida";
+		
+		// Define the scaling factors for each plot.
+		double scaleFactor = 1;
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree tree = af.createTreeFactory().create(plotFile);
+		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		
+		// Define index references for each event type.
+		int MOLLER  = 0;
+		int TRIDENT = 1;
+		int ELASTIC = 2;
+		
+		// Get the histograms.
+		IHistogram1D[] trackCountPlots = new IHistogram1D[3];
+		trackCountPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks");
+		trackCountPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks");
+		trackCountPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks");
+		
+		IHistogram1D[] energyPlots = new IHistogram1D[3];
+		energyPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution");
+		energyPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution");
+		energyPlots[ELASTIC] = (IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution");
+		
+		IHistogram1D[] energySumPlots = new IHistogram1D[2];
+		energySumPlots[MOLLER]  = (IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution");
+		energySumPlots[TRIDENT] = (IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution");
+		
+		IHistogram2D[] energy2DPlots = new IHistogram2D[2];
+		energy2DPlots[MOLLER]  = (IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution");
+		energy2DPlots[TRIDENT] = (IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution");
+		
+		// Create a plotter factory.
+		IPlotterFactory plotterFactory = af.createPlotterFactory();
+		
+		// Format the track count plots.
+		for(IHistogram1D trackCountPlot : trackCountPlots) {
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(trackCountPlot.title());
+			plotter.createRegions(1);
+			plotter.region(0).plot(trackCountPlot);
+			
+			// Format the axis labels.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			region.getPlot().setTitle(trackCountPlot.title());
+			region.getPlot().getXAxis().setLabel("Number of Tracks");
+			region.getPlot().getYAxis().setLabel("Count");
+			
+			// Format the fonts and general plot presentation.
+			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+			
+			// Show the plot.
+			plotter.setParameter("plotterWidth", "2000");
+			plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Format the electron energy plots.
+		for(IHistogram1D energyPlot : energyPlots) {
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(energyPlot.title());
+			plotter.createRegions(1);
+			plotter.region(0).plot(energyPlot);
+			
+			// Format the axis labels.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			region.getPlot().setTitle(energyPlot.title());
+			region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
+			region.getPlot().getYAxis().setLabel("Count");
+			
+			// Format the fonts and general plot presentation.
+			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+			
+			// Show the plot.
+			plotter.setParameter("plotterWidth", "2000");
+			plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Format the energy sum plots.
+		for(IHistogram1D energySumPlot : energySumPlots) {
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(energySumPlot.title());
+			plotter.createRegions(1);
+			plotter.region(0).plot(energySumPlot);
+			
+			// Format the axis labels.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			region.getPlot().setTitle(energySumPlot.title());
+			region.getPlot().getXAxis().setLabel("Track Energy (GeV)");
+			region.getPlot().getYAxis().setLabel("Count");
+			
+			// Format the fonts and general plot presentation.
+			setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
+			
+			// Show the plot.
+			plotter.setParameter("plotterWidth", "2000");
+			plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Format the 2D energy sum plots.
+		for(IHistogram2D energy2DPlot : energy2DPlots) {
+			// Create a plotter and plotting region for the plot.
+			IPlotter plotter = plotterFactory.create(energy2DPlot.title());
+			plotter.createRegions(1);
+			plotter.region(0).plot(energy2DPlot);
+			
+			// Format the axis labels.
+			PlotterRegion region = (PlotterRegion) plotter.region(0);
+			region.getPlot().setTitle(energy2DPlot.title());
+			region.getPlot().getXAxis().setLabel("First Track Energy (GeV)");
+			region.getPlot().getYAxis().setLabel("Second Track Energy (GeV)");
+			
+			
+			// Format the fonts and general plot presentation.
+			setDefault2DStyle(region, false);
+			
+			// Show the plot.
+			plotter.setParameter("plotterWidth", "2000");
+			plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Disable the error bars.
+		//JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+		//fillStyle.setShowErrorBars(false);
+		
+		// Close the tree.
+		tree.close();
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 * @param color - The data color settings to use.
+	 */
+	private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+		// Get the names of each plot on in the region.
+		String[] dataNames = region.getAllDataNames();
+		
+		// Check whether this is an overlay plot. Overlay plots contain
+		// more than one data name.
+		boolean overlay = (dataNames.length > 1 ? true : false);
+		
+		// Iterate over each plot in the region.
+		for(int i = 0; i < dataNames.length; i++) {
+			// Set the overlay style if needed.
+			if(overlay) {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with no fill. The color is set by the "color" argument.
+				fillStyle.setHistogramFill(false);
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+				
+				// Set the legend text style.
+				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+			}
+			
+			// Otherwise, set the fill style for a single plot.
+			else {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with a fill color. The colors are defined by the
+				// "color" argument.
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setHistogramBarColor(color[i].getFillColor());
+				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+			}
+			
+			// Set the statistics box style.
+			region.getPlot().getStats().setVisible(true);
+			region.getPlot().getStats().setFont(BASIC_FONT);
+			
+			// Set the title font.
+			region.getPlot().getTitleObject().setFont(TITLE_FONT);
+			
+			// Set the axis tick-mark fonts.
+			region.getPlot().getXAxis().setFont(BASIC_FONT);
+			region.getPlot().getYAxis().setFont(BASIC_FONT);
+			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+		}
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 */
+	private static final void setDefault2DStyle(PlotterRegion region, boolean logarithmic) {
+		// Get the fill style object. 2D plots should never be overlay
+		// plots, so there should only ever be one data name.
+		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+		
+		// Set the fill style for a two-dimensional plot.
+		if(logarithmic) { fillStyle.setLogZ(true); }
+		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+		
+		// Make the statistics box invisible.
+		region.getPlot().getStats().setVisible(false);
+		
+		// Set the general plot font (which is also the z-axis font).
+		region.getPlot().setFont(BASIC_FONT);
+		
+		// Set the title font.
+		region.getPlot().getTitleObject().setFont(TITLE_FONT);
+		
+		// Set the axis tick-mark fonts.
+		region.getPlot().getXAxis().setFont(BASIC_FONT);
+		region.getPlot().getYAxis().setFont(BASIC_FONT);
+		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+	}
+	
+	/**
+	 * Recursive method that gets all object names from a tree that
+	 * are not directories. Method should not be called directly, but
+	 * rather called only through the <code>getHistograms(ITree)</code>
+	 * method.
+	 * @param tree - The tree from which to obtain the object names.
+	 * @param directory - The directory in which to search for objects.
+	 * @param list - The list in which to place the objects.
+	 * @return Returns the <code>List</code> collection that was given
+	 * as an argument.
+	 */
+	private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
+		// Get the list of objects in the directory.
+		String[] treeObjects = tree.listObjectNames(directory);
+		
+		// Print the objects.
+		for(String objectName : treeObjects) {
+			// Check if the object is a directory.
+			boolean isDirectory = isDirectory(objectName);
+			
+			// If the object is a directory, get the histograms from it.
+			if(isDirectory) {
+				getHistograms(tree, objectName, list);
+			}
+			
+			// If the object is a plot, add it to the list.
+			else { list.add(objectName); }
+		}
+		
+		// Return the list.
+		return list;
+	}
+	
+	/**
+	 * Checks whether a tree object is a directory.
+	 * @param object - The object to check.
+	 * @return Returns <code>true</code> if the object is a directory
+	 * and <code>false</code> otherwise.
+	 */
+	private static final boolean isDirectory(String object) {
+		return (object.toCharArray()[object.length() - 1] == '/');
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/MTETriggerPlotsFormatter.java	Tue Sep 27 08:50:14 2016
@@ -15,164 +15,164 @@
 
 
 public class MTETriggerPlotsFormatter {
-    public static void main(String[] args) throws IllegalArgumentException, IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String plotFile = rootDir + "5772-ana.aida";
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree tree = af.createTreeFactory().create(plotFile);
-        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        
-        // Define the 1D trigger plot names for Møllers and tridents.
-        String[] plotNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
-                "Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
-        String[] displayNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
-                "Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
-        String[] xAxisNames1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)",
-                "Coplanarity (Degrees)", "Energy Difference (GeV)", "Energy Slope (GeV)", "Energy Sum (GeV)" };
-        String yAxisName1D = "Count";
-        
-        // Define the 2D trigger plot names for Møllers and tridents.
-        String[] plotNames2D = { "Cluster Seed", "Pair Energy Sum 2D" };
-        String[] displayNames2D = { "Cluster Seed Distribution", "2D Energy Sum" };
-        String[] xAxisNames2D = { "x-Index", "Second Cluster Energy (GeV)" };
-        String[] yAxisNames2D = { "y-Index", "First Cluster Energy (GeV)" };
-        
-        // Define the 1D trigger plot names for elastics.
-        String[] plotNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
-        String[] displayNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
-        String[] xAxisNamesElastic1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)" };
-        String yAxisNameElastic1D = "Count";
-        
-        // Define the 2D trigger plot names for elastics.
-        String[] plotNamesElastic2D = { "Cluster Seed" };
-        String[] displayNamesElastic2D = { "Cluster Seed Distribution" };
-        String[] xAxisNamesElastic2D = { "x-Index" };
-        String[] yAxisNamesElastic2D = { "y-Index" };
-        
-        // Define the Møller, trident, and elastic prefixes.
-        String allPrefix = "All Trigger Plots/Pair Plots/";
-        String møllerPrefix = "Møller Trigger Plots/Pair Plots/";
-        String tridentPrefix = "Trident Trigger Plots/Pair Plots/";
-        String elasticPrefix = "Elastic Trigger Plots/Singles Plots/";
-        String allSinglesPrefix = "All Trigger Plots/Singles Plots/";
-        
-        // Define the plot type prefix.
-        String allTypeName = "All Pairs - ";
-        String møllerTypeName = "Møller - ";
-        String tridentTypeName = "Trident - ";
-        String elasticTypeName = "Elastic - ";
-        String allSinglesTypeName = "All Singles - ";
-        
-        // Define the plot type colors.
-        ColorStyle allColor = PlotsFormatter.ColorStyle.GREY;
-        ColorStyle møllerColor = PlotsFormatter.ColorStyle.MS_BLUE;
-        ColorStyle tridentColor = PlotsFormatter.ColorStyle.MS_ORANGE;
-        ColorStyle elasticColor = PlotsFormatter.ColorStyle.MS_GREEN;
-        
-        // Create a plot formatting module.
-        PlotFormatModule module = new PlotFormatModule();
-        
-        // Get the histograms and add them to the module. Start with the
-        // trident and Møller plots.
-        for(int i = 0; i < plotNames1D.length; i++) {
-            // Get the Møller and trident plots.
-            IHistogram1D allPlot = (IHistogram1D) tree.find(allPrefix + plotNames1D[i]);
-            IHistogram1D møllerPlot = (IHistogram1D) tree.find(møllerPrefix + plotNames1D[i]);
-            IHistogram1D tridentPlot = (IHistogram1D) tree.find(tridentPrefix + plotNames1D[i]);
-            
-            // Make a formatted plot for each.
-            FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNames1D[i], yAxisName1D, allTypeName + displayNames1D[i]);
-            FormattedPlot1D møllerFormattedPlot = new FormattedPlot1D(møllerPlot, møllerColor, xAxisNames1D[i], yAxisName1D, møllerTypeName + displayNames1D[i]);
-            FormattedPlot1D tridentFormattedPlot = new FormattedPlot1D(tridentPlot, tridentColor, xAxisNames1D[i], yAxisName1D, tridentTypeName + displayNames1D[i]);
-            
-            // Add them to the module.
-            module.addPlot1D(allFormattedPlot);
-            module.addPlot1D(møllerFormattedPlot);
-            module.addPlot1D(tridentFormattedPlot);
-        }
-        for(int i = 0; i < plotNames2D.length; i++) {
-            // Get the Møller and trident plots.
-            IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNames2D[i]);
-            IHistogram2D møllerPlot = (IHistogram2D) tree.find(møllerPrefix + plotNames2D[i]);
-            IHistogram2D tridentPlot = (IHistogram2D) tree.find(tridentPrefix + plotNames2D[i]);
-            
-            // Make a formatted plot for each.
-            FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], allTypeName + displayNames2D[i]);
-            FormattedPlot2D møllerFormattedPlot = new FormattedPlot2D(møllerPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], møllerTypeName + displayNames2D[i]);
-            FormattedPlot2D tridentFormattedPlot = new FormattedPlot2D(tridentPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], tridentTypeName + displayNames2D[i]);
-            
-            // Add them to the module.
-            module.addPlot2D(allFormattedPlot);
-            module.addPlot2D(møllerFormattedPlot);
-            module.addPlot2D(tridentFormattedPlot);
-        }
-        
-        // Get the histograms for the elastic plots and add them to the module.
-        for(int i = 0; i < plotNamesElastic1D.length; i++) {
-            // Get the Møller and trident plots.
-            IHistogram1D allPlot = (IHistogram1D) tree.find(allSinglesPrefix + plotNames1D[i]);
-            IHistogram1D elasticPlot = (IHistogram1D) tree.find(elasticPrefix + plotNames1D[i]);
-            
-            // Make a formatted plot for each.
-            FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
-                    allSinglesTypeName + displayNamesElastic1D[i]);
-            FormattedPlot1D elasticFormattedPlot = new FormattedPlot1D(elasticPlot, elasticColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
-                    elasticTypeName + displayNamesElastic1D[i]);
-            
-            // Add them to the module.
-            module.addPlot1D(allFormattedPlot);
-            module.addPlot1D(elasticFormattedPlot);
-        }
-        for(int i = 0; i < plotNamesElastic2D.length; i++) {
-            // Get the Møller and trident plots.
-            IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNamesElastic2D[i]);
-            IHistogram2D elasticPlot = (IHistogram2D) tree.find(møllerPrefix + plotNamesElastic2D[i]);
-            
-            // Make a formatted plot for each.
-            FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
-                    allSinglesTypeName + plotNames2D[i]);
-            FormattedPlot2D elasticFormattedPlot = new FormattedPlot2D(elasticPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
-                    elasticTypeName + displayNamesElastic2D[i]);
-            
-            // Add them to the module.
-            module.addPlot2D(allFormattedPlot);
-            module.addPlot2D(elasticFormattedPlot);
-        }
-        
-        // Add the MTE plots to the module.
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution"), elasticColor,
-                "Momentum (GeV)", "Count", "Elastic - Momentum"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks"), elasticColor,
-                "Tracks", "Count", "Elastic - Tracks in Event"));
-        
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution"), møllerColor,
-                "Momentum Sum (GeV)", "Count", "Møller - Momentum Sum"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution"), møllerColor,
-                "Momentum (GeV)", "Count", "Møller - Momentum (Electron)"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)"), møllerColor,
-                "Time (ns)", "Count", "Møller - Time Coincidence"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks"), møllerColor,
-                "Tracks", "Count", "Møller - Tracks in Event"));
-        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution"), false,
-                "First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Møller - 2D Momentum Sum"));
-        
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution"), tridentColor,
-                "Momentum Sum (GeV)", "Count", "Trident - Momentum Sum"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution"), tridentColor,
-                "Momentum (GeV)", "Count", "Trident - Momentum (Electron)"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Positron Energy Distribution"), tridentColor,
-                "Momentum (GeV)", "Count", "Trident - Momentum (Positron)"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks"), tridentColor,
-                "Tracks", "Count", "Trident - Tracks in Event"));
-        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution"), false,
-                "First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Trident - 2D Momentum Sum"));
-        
-        // Display the plots.
-        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\TestPrint\\");
-    }
+	public static void main(String[] args) throws IllegalArgumentException, IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String plotFile = rootDir + "5772-ana.aida";
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree tree = af.createTreeFactory().create(plotFile);
+		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		
+		// Define the 1D trigger plot names for Møllers and tridents.
+		String[] plotNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
+				"Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
+		String[] displayNames1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy",
+				"Pair Coplanarity", "Pair Energy Difference", "Pair Energy Slope", "Pair Energy Sum" };
+		String[] xAxisNames1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)",
+				"Coplanarity (Degrees)", "Energy Difference (GeV)", "Energy Slope (GeV)", "Energy Sum (GeV)" };
+		String yAxisName1D = "Count";
+		
+		// Define the 2D trigger plot names for Møllers and tridents.
+		String[] plotNames2D = { "Cluster Seed", "Pair Energy Sum 2D" };
+		String[] displayNames2D = { "Cluster Seed Distribution", "2D Energy Sum" };
+		String[] xAxisNames2D = { "x-Index", "Second Cluster Energy (GeV)" };
+		String[] yAxisNames2D = { "y-Index", "First Cluster Energy (GeV)" };
+		
+		// Define the 1D trigger plot names for elastics.
+		String[] plotNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
+		String[] displayNamesElastic1D = { "Cluster Hit Count", "Cluster Seed Energy", "Cluster Total Energy" };
+		String[] xAxisNamesElastic1D = { "Hit Count", "Seed Energy (GeV)", "Total Energy (GeV)" };
+		String yAxisNameElastic1D = "Count";
+		
+		// Define the 2D trigger plot names for elastics.
+		String[] plotNamesElastic2D = { "Cluster Seed" };
+		String[] displayNamesElastic2D = { "Cluster Seed Distribution" };
+		String[] xAxisNamesElastic2D = { "x-Index" };
+		String[] yAxisNamesElastic2D = { "y-Index" };
+		
+		// Define the Møller, trident, and elastic prefixes.
+		String allPrefix = "All Trigger Plots/Pair Plots/";
+		String møllerPrefix = "Møller Trigger Plots/Pair Plots/";
+		String tridentPrefix = "Trident Trigger Plots/Pair Plots/";
+		String elasticPrefix = "Elastic Trigger Plots/Singles Plots/";
+		String allSinglesPrefix = "All Trigger Plots/Singles Plots/";
+		
+		// Define the plot type prefix.
+		String allTypeName = "All Pairs - ";
+		String møllerTypeName = "Møller - ";
+		String tridentTypeName = "Trident - ";
+		String elasticTypeName = "Elastic - ";
+		String allSinglesTypeName = "All Singles - ";
+		
+		// Define the plot type colors.
+		ColorStyle allColor = PlotsFormatter.ColorStyle.GREY;
+		ColorStyle møllerColor = PlotsFormatter.ColorStyle.MS_BLUE;
+		ColorStyle tridentColor = PlotsFormatter.ColorStyle.MS_ORANGE;
+		ColorStyle elasticColor = PlotsFormatter.ColorStyle.MS_GREEN;
+		
+		// Create a plot formatting module.
+		PlotFormatModule module = new PlotFormatModule();
+		
+		// Get the histograms and add them to the module. Start with the
+		// trident and Møller plots.
+		for(int i = 0; i < plotNames1D.length; i++) {
+			// Get the Møller and trident plots.
+			IHistogram1D allPlot = (IHistogram1D) tree.find(allPrefix + plotNames1D[i]);
+			IHistogram1D møllerPlot = (IHistogram1D) tree.find(møllerPrefix + plotNames1D[i]);
+			IHistogram1D tridentPlot = (IHistogram1D) tree.find(tridentPrefix + plotNames1D[i]);
+			
+			// Make a formatted plot for each.
+			FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNames1D[i], yAxisName1D, allTypeName + displayNames1D[i]);
+			FormattedPlot1D møllerFormattedPlot = new FormattedPlot1D(møllerPlot, møllerColor, xAxisNames1D[i], yAxisName1D, møllerTypeName + displayNames1D[i]);
+			FormattedPlot1D tridentFormattedPlot = new FormattedPlot1D(tridentPlot, tridentColor, xAxisNames1D[i], yAxisName1D, tridentTypeName + displayNames1D[i]);
+			
+			// Add them to the module.
+			module.addPlot1D(allFormattedPlot);
+			module.addPlot1D(møllerFormattedPlot);
+			module.addPlot1D(tridentFormattedPlot);
+		}
+		for(int i = 0; i < plotNames2D.length; i++) {
+			// Get the Møller and trident plots.
+			IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNames2D[i]);
+			IHistogram2D møllerPlot = (IHistogram2D) tree.find(møllerPrefix + plotNames2D[i]);
+			IHistogram2D tridentPlot = (IHistogram2D) tree.find(tridentPrefix + plotNames2D[i]);
+			
+			// Make a formatted plot for each.
+			FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], allTypeName + displayNames2D[i]);
+			FormattedPlot2D møllerFormattedPlot = new FormattedPlot2D(møllerPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], møllerTypeName + displayNames2D[i]);
+			FormattedPlot2D tridentFormattedPlot = new FormattedPlot2D(tridentPlot, i == 0 ? true : false, xAxisNames2D[i], yAxisNames2D[i], tridentTypeName + displayNames2D[i]);
+			
+			// Add them to the module.
+			module.addPlot2D(allFormattedPlot);
+			module.addPlot2D(møllerFormattedPlot);
+			module.addPlot2D(tridentFormattedPlot);
+		}
+		
+		// Get the histograms for the elastic plots and add them to the module.
+		for(int i = 0; i < plotNamesElastic1D.length; i++) {
+			// Get the Møller and trident plots.
+			IHistogram1D allPlot = (IHistogram1D) tree.find(allSinglesPrefix + plotNames1D[i]);
+			IHistogram1D elasticPlot = (IHistogram1D) tree.find(elasticPrefix + plotNames1D[i]);
+			
+			// Make a formatted plot for each.
+			FormattedPlot1D allFormattedPlot = new FormattedPlot1D(allPlot, allColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
+					allSinglesTypeName + displayNamesElastic1D[i]);
+			FormattedPlot1D elasticFormattedPlot = new FormattedPlot1D(elasticPlot, elasticColor, xAxisNamesElastic1D[i], yAxisNameElastic1D,
+					elasticTypeName + displayNamesElastic1D[i]);
+			
+			// Add them to the module.
+			module.addPlot1D(allFormattedPlot);
+			module.addPlot1D(elasticFormattedPlot);
+		}
+		for(int i = 0; i < plotNamesElastic2D.length; i++) {
+			// Get the Møller and trident plots.
+			IHistogram2D allPlot = (IHistogram2D) tree.find(allPrefix + plotNamesElastic2D[i]);
+			IHistogram2D elasticPlot = (IHistogram2D) tree.find(møllerPrefix + plotNamesElastic2D[i]);
+			
+			// Make a formatted plot for each.
+			FormattedPlot2D allFormattedPlot = new FormattedPlot2D(allPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
+					allSinglesTypeName + plotNames2D[i]);
+			FormattedPlot2D elasticFormattedPlot = new FormattedPlot2D(elasticPlot, i == 0 ? true : false, xAxisNamesElastic2D[i], yAxisNamesElastic2D[i],
+					elasticTypeName + displayNamesElastic2D[i]);
+			
+			// Add them to the module.
+			module.addPlot2D(allFormattedPlot);
+			module.addPlot2D(elasticFormattedPlot);
+		}
+		
+		// Add the MTE plots to the module.
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Energy Distribution"), elasticColor,
+				"Momentum (GeV)", "Count", "Elastic - Momentum"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Elastic Event Tracks"), elasticColor,
+				"Tracks", "Count", "Elastic - Tracks in Event"));
+		
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Energy Sum Distribution"), møllerColor,
+				"Momentum Sum (GeV)", "Count", "Møller - Momentum Sum"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Electron Energy Distribution"), møllerColor,
+				"Momentum (GeV)", "Count", "Møller - Momentum (Electron)"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Time Coincidence Distribution (All Møller Cuts)"), møllerColor,
+				"Time (ns)", "Count", "Møller - Time Coincidence"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Møller Event Tracks"), møllerColor,
+				"Tracks", "Count", "Møller - Tracks in Event"));
+		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Møller 2D Energy Distribution"), false,
+				"First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Møller - 2D Momentum Sum"));
+		
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Energy Sum Distribution"), tridentColor,
+				"Momentum Sum (GeV)", "Count", "Trident - Momentum Sum"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Electron Energy Distribution"), tridentColor,
+				"Momentum (GeV)", "Count", "Trident - Momentum (Electron)"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Positron Energy Distribution"), tridentColor,
+				"Momentum (GeV)", "Count", "Trident - Momentum (Positron)"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MTE Analysis/Trident Event Tracks"), tridentColor,
+				"Tracks", "Count", "Trident - Tracks in Event"));
+		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MTE Analysis/Trident 2D Energy Distribution"), false,
+				"First Track Momentum (GeV)", "Second Track Momentum (GeV)", "Trident - 2D Momentum Sum"));
+		
+		// Display the plots.
+		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\TestPrint\\");
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/ParticleMCAnalysisPlotsFormatter.java	Tue Sep 27 08:50:14 2016
@@ -13,43 +13,43 @@
 import org.hps.users.kmccarty.plots.PlotsFormatter.ColorStyle;
 
 public class ParticleMCAnalysisPlotsFormatter {
-    public static void main(String[] args) throws IllegalArgumentException, IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String plotFile = rootDir + "moller-mc-out_triggerPlots.aida";
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree tree = af.createTreeFactory().create(plotFile);
-        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        
-        // Create a plot formatting module.
-        PlotFormatModule module = new PlotFormatModule();
-        
-        // Define the plot color.
-        ColorStyle plotColor = ColorStyle.MS_BLUE;
-        
-        // Define the plots to be read.
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron Energy Distribution"),
-                plotColor, "Electron Energy (GeV)", "Count", "Electron Energy Distribution"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Momentum Sum Distribution"),
-                plotColor, "Momentum Sum (GeV)", "Count", "Momentum Sum Distribution"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Pair Angle Distribution"),
-                plotColor, "Momentum Sum (GeV)", "Count", "Pair Angle Distribution"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle x-Momentum Distribution"),
-                plotColor, "Momentum (GeV)", "Count", "Particle x-Momentum Distribution"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle y-Momentum Distribution"),
-                plotColor, "Momentum (GeV)", "Count", "Particle y-Momentum Distribution"));
-        module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle z-Momentum Distribution"),
-                plotColor, "Momentum (GeV)", "Count", "Particle z-Momentum Distribution"));
-        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Electron\\Electron 2D Momentum Distribution"),
-                true, "Particle 1 Momentum (GeV)", "Particle 2 Momentum (GeV)", "2D Momentum Sum Distribution"));
-        module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Particle Momentum Distribution"),
-                true, "px (GeV)", "py (GeV)", "Particle x/y Momentum Distribution"));
-        
-        // Display the plots.
-        module.displayPlots();
-    }
+	public static void main(String[] args) throws IllegalArgumentException, IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String plotFile = rootDir + "moller-mc-out_triggerPlots.aida";
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree tree = af.createTreeFactory().create(plotFile);
+		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		
+		// Create a plot formatting module.
+		PlotFormatModule module = new PlotFormatModule();
+		
+		// Define the plot color.
+		ColorStyle plotColor = ColorStyle.MS_BLUE;
+		
+		// Define the plots to be read.
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron Energy Distribution"),
+				plotColor, "Electron Energy (GeV)", "Count", "Electron Energy Distribution"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Momentum Sum Distribution"),
+				plotColor, "Momentum Sum (GeV)", "Count", "Momentum Sum Distribution"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Electron\\Electron Pair Angle Distribution"),
+				plotColor, "Momentum Sum (GeV)", "Count", "Pair Angle Distribution"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle x-Momentum Distribution"),
+				plotColor, "Momentum (GeV)", "Count", "Particle x-Momentum Distribution"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle y-Momentum Distribution"),
+				plotColor, "Momentum (GeV)", "Count", "Particle y-Momentum Distribution"));
+		module.addPlot1D(new FormattedPlot1D((IHistogram1D) tree.find("MC Analysis/Particle z-Momentum Distribution"),
+				plotColor, "Momentum (GeV)", "Count", "Particle z-Momentum Distribution"));
+		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Electron\\Electron 2D Momentum Distribution"),
+				true, "Particle 1 Momentum (GeV)", "Particle 2 Momentum (GeV)", "2D Momentum Sum Distribution"));
+		module.addPlot2D(new FormattedPlot2D((IHistogram2D) tree.find("MC Analysis/Particle Momentum Distribution"),
+				true, "px (GeV)", "py (GeV)", "Particle x/y Momentum Distribution"));
+		
+		// Display the plots.
+		module.displayPlots();
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/RafoTridentFormatter.java	Tue Sep 27 08:50:14 2016
@@ -13,101 +13,101 @@
 import hep.aida.ITree;
 
 public class RafoTridentFormatter {
-    /**
-     * Loads all plots in a file and formats them according to the
-     * indicated style.
-     * @param args - Unused default executable parameter.
-     * @throws IOException Occurs if there is an issue opening the file.
-     */
-    public static void main(String[] args) throws IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String plotFile = rootDir + "mte-out.aida";
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree tree = af.createTreeFactory().create(plotFile);
-        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        
-        // Declare the histogram names.
-        String energySumName = "Energy Sum";
-        String timeCoincidenceName = "Time Coincidence";
-        String timeEnergy2DName = "Cluster Time vs. Cluster Energy";
-        String hCoplanaritySum2DName = "Hardware Coplanarity vs. Energy Sum";
-        String coplanaritySum2DName = "Calculated Coplanarity vs. Energy Sum";
-        String energySum2DName = "Top Cluster Energy vs. Bottom Cluster Energy";
-        String fiducial = " (Fiducial Region)";
-        
-        // Get the histograms.
-        IHistogram1D[] energySum = {
-                (IHistogram1D) tree.find("Trident/" + energySumName),
-                (IHistogram1D) tree.find("Trident/" + energySumName + fiducial)
-        };
-        IHistogram1D[] timeCoincidence = {
-                (IHistogram1D) tree.find("Trident/" + timeCoincidenceName),
-                (IHistogram1D) tree.find("Trident/" + timeCoincidenceName + fiducial)
-        };
-        IHistogram2D[] coplanaritySum = {
-                (IHistogram2D) tree.find("Trident/" + coplanaritySum2DName),
-                (IHistogram2D) tree.find("Trident/" + coplanaritySum2DName + fiducial)
-        };
-        IHistogram2D[] hcoplanaritySum = {
-                (IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName),
-                (IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName + fiducial)
-        };
-        IHistogram2D[] energySum2D = {
-                (IHistogram2D) tree.find("Trident/" + energySum2DName),
-                (IHistogram2D) tree.find("Trident/" + energySum2DName + fiducial)
-        };
-        IHistogram2D[] timeEnergy = {
-                (IHistogram2D) tree.find("Trident/" + timeEnergy2DName),
-                (IHistogram2D) tree.find("Trident/" + timeEnergy2DName + fiducial)
-        };
-        
-        // Define the scaling factors for each plot.
-        double scaleFactor = 19000.0 / 9736969.0;
-        
-        // Define the plot titles and arrays for 1D plots.
-        IHistogram1D[][] plots = { energySum, timeCoincidence  };
-        String titles[] = { energySumName, timeCoincidenceName, coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
-        String[] xTitles = { "Energy (GeV)", "Time Difference (ns)" };
-        String yTitle = "Rate (Hz)";
-        
-        // Define the plot titles and arrays for 2D plots.
-        IHistogram2D[][] plots2D = { coplanaritySum, hcoplanaritySum, energySum2D, timeEnergy };
-        String[] titles2D = { coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
-        String[] xTitles2D = { "Coplanarity (Degrees)", "Coplanarity (Degrees)", "Top Cluster Energy (GeV)", "Time Coincidence (ns)" };
-        String[] yTitles2D = { "Energy Sum (GeV)", "Energy Sum (GeV)", "Bottom Cluster Energy (GeV)", "Energy Sum (GeV)" };
-        String zTitle2D = "Rate (Hz)";
-        
-        // Create a plot formatting module.
-        PlotFormatModule module = new PlotFormatModule();
-        
-        // Define the plot color.
-        ColorStyle plotColor = ColorStyle.MS_BLUE;
-        
-        // Define the plots to be read.
-        for(int i = 0; i < plots.length; i++) {
-            plots[i][0].scale(scaleFactor);
-            plots[i][1].scale(scaleFactor);
-            module.addPlot1D(new FormattedPlot1D(plots[i][0], plotColor, xTitles[i], yTitle, titles[i]));
-            module.addPlot1D(new FormattedPlot1D(plots[i][1], plotColor, xTitles[i],  yTitle, titles[i] + fiducial));
-        }
-        for(int i = 0; i < plots2D.length; i++) {
-            plots2D[i][0].scale(scaleFactor);
-            plots2D[i][1].scale(scaleFactor);
-            module.addPlot2D(new FormattedPlot2D(plots2D[i][0], false, xTitles2D[i], yTitles2D[i], titles2D[i]));
-            module.addPlot2D(new FormattedPlot2D(plots2D[i][1], false, xTitles2D[i], yTitles2D[i], titles2D[i] + fiducial));
-        }
-        
-        // Display the plots.
-        //module.displayPlots();
-        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
-        module.exportPlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
-        
-        // Close the tree.
-        tree.close();
-    }
+	/**
+	 * Loads all plots in a file and formats them according to the
+	 * indicated style.
+	 * @param args - Unused default executable parameter.
+	 * @throws IOException Occurs if there is an issue opening the file.
+	 */
+	public static void main(String[] args) throws IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String plotFile = rootDir + "mte-out.aida";
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree tree = af.createTreeFactory().create(plotFile);
+		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		
+		// Declare the histogram names.
+		String energySumName = "Energy Sum";
+		String timeCoincidenceName = "Time Coincidence";
+		String timeEnergy2DName = "Cluster Time vs. Cluster Energy";
+		String hCoplanaritySum2DName = "Hardware Coplanarity vs. Energy Sum";
+		String coplanaritySum2DName = "Calculated Coplanarity vs. Energy Sum";
+		String energySum2DName = "Top Cluster Energy vs. Bottom Cluster Energy";
+		String fiducial = " (Fiducial Region)";
+		
+		// Get the histograms.
+		IHistogram1D[] energySum = {
+				(IHistogram1D) tree.find("Trident/" + energySumName),
+				(IHistogram1D) tree.find("Trident/" + energySumName + fiducial)
+		};
+		IHistogram1D[] timeCoincidence = {
+				(IHistogram1D) tree.find("Trident/" + timeCoincidenceName),
+				(IHistogram1D) tree.find("Trident/" + timeCoincidenceName + fiducial)
+		};
+		IHistogram2D[] coplanaritySum = {
+				(IHistogram2D) tree.find("Trident/" + coplanaritySum2DName),
+				(IHistogram2D) tree.find("Trident/" + coplanaritySum2DName + fiducial)
+		};
+		IHistogram2D[] hcoplanaritySum = {
+				(IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName),
+				(IHistogram2D) tree.find("Trident/" + hCoplanaritySum2DName + fiducial)
+		};
+		IHistogram2D[] energySum2D = {
+				(IHistogram2D) tree.find("Trident/" + energySum2DName),
+				(IHistogram2D) tree.find("Trident/" + energySum2DName + fiducial)
+		};
+		IHistogram2D[] timeEnergy = {
+				(IHistogram2D) tree.find("Trident/" + timeEnergy2DName),
+				(IHistogram2D) tree.find("Trident/" + timeEnergy2DName + fiducial)
+		};
+		
+		// Define the scaling factors for each plot.
+		double scaleFactor = 19000.0 / 9736969.0;
+		
+		// Define the plot titles and arrays for 1D plots.
+		IHistogram1D[][] plots = { energySum, timeCoincidence  };
+		String titles[] = { energySumName, timeCoincidenceName, coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
+		String[] xTitles = { "Energy (GeV)", "Time Difference (ns)" };
+		String yTitle = "Rate (Hz)";
+		
+		// Define the plot titles and arrays for 2D plots.
+		IHistogram2D[][] plots2D = { coplanaritySum, hcoplanaritySum, energySum2D, timeEnergy };
+		String[] titles2D = { coplanaritySum2DName, hCoplanaritySum2DName, energySum2DName, timeEnergy2DName };
+		String[] xTitles2D = { "Coplanarity (Degrees)", "Coplanarity (Degrees)", "Top Cluster Energy (GeV)", "Time Coincidence (ns)" };
+		String[] yTitles2D = { "Energy Sum (GeV)", "Energy Sum (GeV)", "Bottom Cluster Energy (GeV)", "Energy Sum (GeV)" };
+		String zTitle2D = "Rate (Hz)";
+		
+		// Create a plot formatting module.
+		PlotFormatModule module = new PlotFormatModule();
+		
+		// Define the plot color.
+		ColorStyle plotColor = ColorStyle.MS_BLUE;
+		
+		// Define the plots to be read.
+		for(int i = 0; i < plots.length; i++) {
+			plots[i][0].scale(scaleFactor);
+			plots[i][1].scale(scaleFactor);
+			module.addPlot1D(new FormattedPlot1D(plots[i][0], plotColor, xTitles[i], yTitle, titles[i]));
+			module.addPlot1D(new FormattedPlot1D(plots[i][1], plotColor, xTitles[i],  yTitle, titles[i] + fiducial));
+		}
+		for(int i = 0; i < plots2D.length; i++) {
+			plots2D[i][0].scale(scaleFactor);
+			plots2D[i][1].scale(scaleFactor);
+			module.addPlot2D(new FormattedPlot2D(plots2D[i][0], false, xTitles2D[i], yTitles2D[i], titles2D[i]));
+			module.addPlot2D(new FormattedPlot2D(plots2D[i][1], false, xTitles2D[i], yTitles2D[i], titles2D[i] + fiducial));
+		}
+		
+		// Display the plots.
+		//module.displayPlots();
+		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
+		module.exportPlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\run-5772\\RafoPlots\\");
+		
+		// Close the tree.
+		tree.close();
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/SingleTriggerPlotsFormatter.java	Tue Sep 27 08:50:14 2016
@@ -13,151 +13,151 @@
 import hep.aida.ITree;
 
 public class SingleTriggerPlotsFormatter {
-    
-    public static void main(String[] args) throws IllegalArgumentException, IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String plotFile = rootDir + "trident-readout-full.aida";
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree tree = af.createTreeFactory().create(plotFile);
-        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        
-        // Define plots variables.
-        int UNCUT     = 0;
-        int TRIGGERED = 1;
-        String[] plotsDir = { "NoCuts/", "PassedAll/" };
-        int PLOT_HIT_COUNT      = 0;
-        int PLOT_SEED_ENERGY    = 1;
-        int PLOT_CLUSTER_ENERGY = 2;
-        int PLOT_COPLANARITY    = 3;
-        int PLOT_ENERGY_SUM     = 4;
-        int PLOT_ENERGY_DIFF    = 5;
-        int PLOT_ENERGY_SLOPE   = 6;
-        int PLOT_SEED_DIST      = 0;
-        int PLOT_ENERGY_SUM_2D  = 1;
-        
-        // Define the internal plot names.
-        String[] plotNameInternal1D = new String[7];
-        String[] plotNameInternal2D = new String[2];
-        plotNameInternal1D[PLOT_HIT_COUNT]      = "Cluster Hit Count";
-        plotNameInternal1D[PLOT_SEED_ENERGY]    = "Cluster Seed Energy";
-        plotNameInternal1D[PLOT_CLUSTER_ENERGY] = "Cluster Total Energy";
-        plotNameInternal1D[PLOT_COPLANARITY]    = "Pair Coplanarity";
-        plotNameInternal1D[PLOT_ENERGY_SUM]     = "Pair Energy Sum";
-        plotNameInternal1D[PLOT_ENERGY_DIFF]    = "Pair Energy Difference";
-        plotNameInternal1D[PLOT_ENERGY_SLOPE]   = "Pair Energy Slope";
-        plotNameInternal2D[PLOT_SEED_DIST]      = "Cluster Seed";
-        plotNameInternal2D[PLOT_ENERGY_SUM_2D]  = "Pair Energy Sum 2D";
-        
-        // Define the plot display names.
-        String[] plotName1D = new String[7];
-        String[] plotName2D = new String[2];
-        for(int j = 0; j < plotNameInternal1D.length; j++) {
-            plotName1D[j] = plotNameInternal1D[j];
-        }
-        for(int j = 0; j < plotNameInternal2D.length; j++) {
-            plotName2D[j] = plotNameInternal2D[j];
-        }
-        plotName1D[PLOT_ENERGY_SUM]    = "1D Pair Energy Sum";
-        plotName2D[PLOT_SEED_DIST]     = "Cluster Seed Distribution";
-        plotName2D[PLOT_ENERGY_SUM_2D] = "2D Pair Energy Sum";
-        
-        String[] xTitles1D = new String[plotName1D.length];
-        String[] xTitles2D = new String[plotName2D.length];
-        xTitles1D[PLOT_HIT_COUNT]      = "Hit Count";
-        xTitles1D[PLOT_SEED_ENERGY]    = "Seed Energy (GeV)";
-        xTitles1D[PLOT_CLUSTER_ENERGY] = "Cluster Energy (GeV)";
-        xTitles1D[PLOT_COPLANARITY]    = "Coplanarity Angle (Degrees)";
-        xTitles1D[PLOT_ENERGY_SUM]     = "Energy Sum (GeV)";
-        xTitles1D[PLOT_ENERGY_DIFF]    = "Energy Difference (GeV)";
-        xTitles1D[PLOT_ENERGY_SLOPE]   = "Energy Slope (GeV)";
-        xTitles2D[PLOT_SEED_DIST]      = "x-Index";
-        xTitles2D[PLOT_ENERGY_SUM_2D]  = "First Cluster Energy (GeV)";
-        String yTitle1D = "Count";
-        String[] yTitles2D = new String[plotName2D.length];
-        yTitles2D[PLOT_SEED_DIST]      = "y-Index";
-        yTitles2D[PLOT_ENERGY_SUM_2D]  = "Second Cluster Energy (GeV)";
-        
-        // Define axis ranges.
-        double[] axisRanges1D = new double[plotName1D.length];
-        axisRanges1D[PLOT_HIT_COUNT]      = -1;
-        axisRanges1D[PLOT_SEED_ENERGY]    = 1.1;
-        axisRanges1D[PLOT_CLUSTER_ENERGY] = 1.1;
-        axisRanges1D[PLOT_COPLANARITY]    = 180;
-        axisRanges1D[PLOT_ENERGY_SUM]     = 2.2;
-        axisRanges1D[PLOT_ENERGY_DIFF]    = 1.1;
-        axisRanges1D[PLOT_ENERGY_SLOPE]   = 2.4;
-        double[] xAxisRanges2D = new double[plotName2D.length];
-        double[] yAxisRanges2D = new double[plotName2D.length];
-        xAxisRanges2D[PLOT_SEED_DIST]      = -1;
-        xAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
-        yAxisRanges2D[PLOT_SEED_DIST]      = -1;
-        yAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
-        
-        // Define the plot names.
-        String[][] plotLocations1D = new String[plotsDir.length][plotNameInternal1D.length];
-        String[][] plotLocations2D = new String[plotsDir.length][plotNameInternal2D.length];
-        for(int i = 0; i < plotsDir.length; i++) {
-            for(int j = 0; j < plotNameInternal1D.length; j++) {
-                plotLocations1D[i][j] = plotsDir[i] + plotNameInternal1D[j];
-            }
-        }
-        for(int i = 0; i < plotsDir.length; i++) {
-            for(int j = 0; j < plotNameInternal2D.length; j++) {
-                plotLocations2D[i][j] = plotsDir[i] + plotNameInternal2D[j];
-            }
-        }
-        
-        // Create a plot formatting module.
-        PlotFormatModule module = new PlotFormatModule();
-        
-        // Load the plot objects.
-        for(int i = 0; i < plotName1D.length; i++) {
-            // Get the uncut and triggered plots.
-            IHistogram1D uncutPlot = (IHistogram1D) tree.find(plotLocations1D[UNCUT][i]);
-            IHistogram1D triggeredPlot = (IHistogram1D) tree.find(plotLocations1D[TRIGGERED][i] + " (Passed All Cuts)");
-            
-            // Make a formatted plot for each.
-            FormattedPlot1D uncutFormattedPlot;
-            FormattedPlot1D triggeredFormattedPlot;
-            if(axisRanges1D[i] != -1) {
-                uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)", axisRanges1D[i]);
-                triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)", axisRanges1D[i]);
-            } else {
-                uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)");
-                triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)");
-            }
-            
-            // Add the plots to the module.
-            module.addPlot1D(uncutFormattedPlot);
-            module.addPlot1D(triggeredFormattedPlot);
-        }
-        for(int i = 0; i < plotName2D.length; i++) {
-            // Get the uncut and triggered plots.
-            IHistogram2D uncutPlot = (IHistogram2D) tree.find(plotLocations2D[UNCUT][i]);
-            IHistogram2D triggeredPlot = (IHistogram2D) tree.find(plotLocations2D[TRIGGERED][i] + " (Passed All Cuts)");
-            
-            // Make a formatted plot for each.
-            FormattedPlot2D uncutFormattedPlot;
-            FormattedPlot2D triggeredFormattedPlot;
-            if(xAxisRanges2D[i] != -1) {
-                uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)", xAxisRanges2D[i], yAxisRanges2D[i]);
-                triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)", xAxisRanges2D[i], yAxisRanges2D[i]);
-            } else {
-                uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)");
-                triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)");
-            }
-            
-            // Add the plots to the module.
-            module.addPlot2D(uncutFormattedPlot);
-            module.addPlot2D(triggeredFormattedPlot);
-        }
-        
-        // Save the plots.
-        module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\MonteCarlo\\Trident\\Trigger\\");
-    }
+	
+	public static void main(String[] args) throws IllegalArgumentException, IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String plotFile = rootDir + "trident-readout-full.aida";
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree tree = af.createTreeFactory().create(plotFile);
+		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		
+		// Define plots variables.
+		int UNCUT     = 0;
+		int TRIGGERED = 1;
+		String[] plotsDir = { "NoCuts/", "PassedAll/" };
+		int PLOT_HIT_COUNT      = 0;
+		int PLOT_SEED_ENERGY    = 1;
+		int PLOT_CLUSTER_ENERGY = 2;
+		int PLOT_COPLANARITY    = 3;
+		int PLOT_ENERGY_SUM     = 4;
+		int PLOT_ENERGY_DIFF    = 5;
+		int PLOT_ENERGY_SLOPE   = 6;
+		int PLOT_SEED_DIST      = 0;
+		int PLOT_ENERGY_SUM_2D  = 1;
+		
+		// Define the internal plot names.
+		String[] plotNameInternal1D = new String[7];
+		String[] plotNameInternal2D = new String[2];
+		plotNameInternal1D[PLOT_HIT_COUNT]      = "Cluster Hit Count";
+		plotNameInternal1D[PLOT_SEED_ENERGY]    = "Cluster Seed Energy";
+		plotNameInternal1D[PLOT_CLUSTER_ENERGY] = "Cluster Total Energy";
+		plotNameInternal1D[PLOT_COPLANARITY]    = "Pair Coplanarity";
+		plotNameInternal1D[PLOT_ENERGY_SUM]     = "Pair Energy Sum";
+		plotNameInternal1D[PLOT_ENERGY_DIFF]    = "Pair Energy Difference";
+		plotNameInternal1D[PLOT_ENERGY_SLOPE]   = "Pair Energy Slope";
+		plotNameInternal2D[PLOT_SEED_DIST]      = "Cluster Seed";
+		plotNameInternal2D[PLOT_ENERGY_SUM_2D]  = "Pair Energy Sum 2D";
+		
+		// Define the plot display names.
+		String[] plotName1D = new String[7];
+		String[] plotName2D = new String[2];
+		for(int j = 0; j < plotNameInternal1D.length; j++) {
+			plotName1D[j] = plotNameInternal1D[j];
+		}
+		for(int j = 0; j < plotNameInternal2D.length; j++) {
+			plotName2D[j] = plotNameInternal2D[j];
+		}
+		plotName1D[PLOT_ENERGY_SUM]    = "1D Pair Energy Sum";
+		plotName2D[PLOT_SEED_DIST]     = "Cluster Seed Distribution";
+		plotName2D[PLOT_ENERGY_SUM_2D] = "2D Pair Energy Sum";
+		
+		String[] xTitles1D = new String[plotName1D.length];
+		String[] xTitles2D = new String[plotName2D.length];
+		xTitles1D[PLOT_HIT_COUNT]      = "Hit Count";
+		xTitles1D[PLOT_SEED_ENERGY]    = "Seed Energy (GeV)";
+		xTitles1D[PLOT_CLUSTER_ENERGY] = "Cluster Energy (GeV)";
+		xTitles1D[PLOT_COPLANARITY]    = "Coplanarity Angle (Degrees)";
+		xTitles1D[PLOT_ENERGY_SUM]     = "Energy Sum (GeV)";
+		xTitles1D[PLOT_ENERGY_DIFF]    = "Energy Difference (GeV)";
+		xTitles1D[PLOT_ENERGY_SLOPE]   = "Energy Slope (GeV)";
+		xTitles2D[PLOT_SEED_DIST]      = "x-Index";
+		xTitles2D[PLOT_ENERGY_SUM_2D]  = "First Cluster Energy (GeV)";
+		String yTitle1D = "Count";
+		String[] yTitles2D = new String[plotName2D.length];
+		yTitles2D[PLOT_SEED_DIST]      = "y-Index";
+		yTitles2D[PLOT_ENERGY_SUM_2D]  = "Second Cluster Energy (GeV)";
+		
+		// Define axis ranges.
+		double[] axisRanges1D = new double[plotName1D.length];
+		axisRanges1D[PLOT_HIT_COUNT]      = -1;
+		axisRanges1D[PLOT_SEED_ENERGY]    = 1.1;
+		axisRanges1D[PLOT_CLUSTER_ENERGY] = 1.1;
+		axisRanges1D[PLOT_COPLANARITY]    = 180;
+		axisRanges1D[PLOT_ENERGY_SUM]     = 2.2;
+		axisRanges1D[PLOT_ENERGY_DIFF]    = 1.1;
+		axisRanges1D[PLOT_ENERGY_SLOPE]   = 2.4;
+		double[] xAxisRanges2D = new double[plotName2D.length];
+		double[] yAxisRanges2D = new double[plotName2D.length];
+		xAxisRanges2D[PLOT_SEED_DIST]      = -1;
+		xAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
+		yAxisRanges2D[PLOT_SEED_DIST]      = -1;
+		yAxisRanges2D[PLOT_ENERGY_SUM_2D]  = 1.1;
+		
+		// Define the plot names.
+		String[][] plotLocations1D = new String[plotsDir.length][plotNameInternal1D.length];
+		String[][] plotLocations2D = new String[plotsDir.length][plotNameInternal2D.length];
+		for(int i = 0; i < plotsDir.length; i++) {
+			for(int j = 0; j < plotNameInternal1D.length; j++) {
+				plotLocations1D[i][j] = plotsDir[i] + plotNameInternal1D[j];
+			}
+		}
+		for(int i = 0; i < plotsDir.length; i++) {
+			for(int j = 0; j < plotNameInternal2D.length; j++) {
+				plotLocations2D[i][j] = plotsDir[i] + plotNameInternal2D[j];
+			}
+		}
+		
+		// Create a plot formatting module.
+		PlotFormatModule module = new PlotFormatModule();
+		
+		// Load the plot objects.
+		for(int i = 0; i < plotName1D.length; i++) {
+			// Get the uncut and triggered plots.
+			IHistogram1D uncutPlot = (IHistogram1D) tree.find(plotLocations1D[UNCUT][i]);
+			IHistogram1D triggeredPlot = (IHistogram1D) tree.find(plotLocations1D[TRIGGERED][i] + " (Passed All Cuts)");
+			
+			// Make a formatted plot for each.
+			FormattedPlot1D uncutFormattedPlot;
+			FormattedPlot1D triggeredFormattedPlot;
+			if(axisRanges1D[i] != -1) {
+				uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)", 0, axisRanges1D[i]);
+				triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)", 0, axisRanges1D[i]);
+			} else {
+				uncutFormattedPlot = new FormattedPlot1D(uncutPlot, PlotsFormatter.ColorStyle.GREY, xTitles1D[i], yTitle1D, plotName1D[i] + " (No Cuts)");
+				triggeredFormattedPlot = new FormattedPlot1D(triggeredPlot, PlotsFormatter.ColorStyle.MS_GREEN, xTitles1D[i], yTitle1D, plotName1D[i] + " (Triggered)");
+			}
+			
+			// Add the plots to the module.
+			module.addPlot1D(uncutFormattedPlot);
+			module.addPlot1D(triggeredFormattedPlot);
+		}
+		for(int i = 0; i < plotName2D.length; i++) {
+			// Get the uncut and triggered plots.
+			IHistogram2D uncutPlot = (IHistogram2D) tree.find(plotLocations2D[UNCUT][i]);
+			IHistogram2D triggeredPlot = (IHistogram2D) tree.find(plotLocations2D[TRIGGERED][i] + " (Passed All Cuts)");
+			
+			// Make a formatted plot for each.
+			FormattedPlot2D uncutFormattedPlot;
+			FormattedPlot2D triggeredFormattedPlot;
+			if(xAxisRanges2D[i] != -1) {
+				uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)", xAxisRanges2D[i], yAxisRanges2D[i]);
+				triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)", xAxisRanges2D[i], yAxisRanges2D[i]);
+			} else {
+				uncutFormattedPlot = new FormattedPlot2D(uncutPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (No Cuts)");
+				triggeredFormattedPlot = new FormattedPlot2D(triggeredPlot, true, xTitles2D[i], yTitles2D[i], plotName2D[i] + " (Triggered)");
+			}
+			
+			// Add the plots to the module.
+			module.addPlot2D(uncutFormattedPlot);
+			module.addPlot2D(triggeredFormattedPlot);
+		}
+		
+		// Save the plots.
+		module.savePlots("C:\\Users\\Kyle\\Desktop\\EnergyShift\\MonteCarlo\\Trident\\Trigger\\");
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TridentTrackFormatter.java	Tue Sep 27 08:50:14 2016
@@ -16,187 +16,187 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class TridentTrackFormatter {
-    /**
-     * Loads all plots in a file and formats them according to the
-     * indicated style.
-     * @param args - Unused default executable parameter.
-     * @throws IOException Occurs if there is an issue opening the file.
-     */
-    public static void main(String[] args) throws IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\tmp\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String plotFile = rootDir + "trident-out.aida";
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree tree = af.createTreeFactory().create(plotFile);
-        if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        
-        // Declare the histogram names.
-        String trackName = "Tracks in Event (All)";
-        String posTrackName = "Tracks in Event (Positive)";
-        String negTrackName = "Tracks in Event (Negative)";
-        String posMomentumName = "Momentum (Positive)";
-        String negMomentumName = "Momentum (Negative)";
-        String energySumName = "Energy Sum";
-        String momentumSumName = "Momentum Sum";
-        String energyMomentumDiffName = "Energy-Momentum Difference";
-        String invariantMassName = "Invariant Mass";
-        String energySum2DName = "2D Energy Sum";
-        String momentumSum2DName = "2D Momentum Sum";
-        String positionName = "Track Cluster Position";
-        
-        // Get the histograms.
-        IHistogram1D[] tracks = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + trackName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + trackName)
-        };
-        IHistogram1D[] posTracks = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + posTrackName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + posTrackName)
-        };
-        IHistogram1D[] negTracks = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + negTrackName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + negTrackName)
-        };
-        IHistogram1D[] posMomentum = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + posMomentumName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + posMomentumName)
-        };
-        IHistogram1D[] negMomentum = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + negMomentumName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + negMomentumName)
-        };
-        IHistogram1D[] energySum = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + energySumName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + energySumName)
-        };
-        IHistogram1D[] momentumSum = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + momentumSumName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + momentumSumName)
-        };
-        IHistogram1D[] energyMomentumDiff = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + energyMomentumDiffName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + energyMomentumDiffName)
-        };
-        IHistogram1D[] invariantMass = {
-                (IHistogram1D) tree.find("Trident Analysis/All/" + invariantMassName),
-                (IHistogram1D) tree.find("Trident Analysis/Cluster/" + invariantMassName)
-        };
-        IHistogram2D[] energySum2D = {
-                (IHistogram2D) tree.find("Trident Analysis/All/" + energySum2DName),
-                (IHistogram2D) tree.find("Trident Analysis/Cluster/" + energySum2DName)
-        };
-        IHistogram2D[] momentumSum2D = {
-                (IHistogram2D) tree.find("Trident Analysis/All/" + momentumSum2DName),
-                (IHistogram2D) tree.find("Trident Analysis/Cluster/" + momentumSum2DName)
-        };
-        IHistogram2D[] position = {
-                (IHistogram2D) tree.find("Trident Analysis/All/" + positionName),
-                (IHistogram2D) tree.find("Trident Analysis/Cluster/" + positionName)
-        };
-        
-        // Re-bin the histograms to have 5-times larger bins. First,
-        // get the bin count and upper and lower bounds of the plot.
-        int bins = invariantMass[0].axis().bins();
-        double low = invariantMass[0].axis().binLowerEdge(0);
-        double high = invariantMass[0].axis().binUpperEdge(invariantMass[0].axis().bins() - 1);
-        
-        // Create new plots with the larger bin sizes.
-        AIDA aida = AIDA.defaultInstance();
-        IHistogram1D[] newPlot = new IHistogram1D[2];
-        newPlot[0] = aida.histogram1D(invariantMassName, bins / 5, low, high);
-        newPlot[1] = aida.histogram1D("Cluster " + invariantMassName, bins / 5, low, high);
-        
-        // Populate the new plots with the data from the old ones.
-        for(int j = 0; j < 2; j++) {
-            for(int i = 0; i < bins; i++) {
-                int entries = invariantMass[j].binEntries(i);
-                double center = invariantMass[j].axis().binCenter(i);
-                for(int k = 0; k < entries; k++) {
-                    newPlot[j].fill(center);
-                }
-            }
-        }
-        
-        // Replace the old plots.
-        invariantMass = newPlot;
-        
-        // Define the scaling factors for each plot.
-        double scaleFactor = 1;
-        
-        // Define the plot titles and arrays for 1D plots.
-        IHistogram[][] plots = { tracks, posTracks, negTracks, posMomentum, negMomentum, energySum, momentumSum, energyMomentumDiff, invariantMass };
-        String[] titles = { trackName, posTrackName, negTrackName, posMomentumName, negMomentumName, energySumName, momentumSumName,
-                energyMomentumDiffName, invariantMassName };
-        String[] xTitles = { "Tracks", "Tracks", "Tracks", "Momentum (GeV)", "Momentum (GeV)", "Energy Sum (GeV)", "Momentum Sum (GeV)",
-                "|E_Cluster - P_Track| (GeV)", "Invariant Mass (GeV)" };
-        String yTitle = "Count";
-        
-        // Define the plot titles and arrays for 2D plots.
-        IHistogram2D[][] plots2D = { energySum2D, momentumSum2D, position };
-        String[] titles2D = { energySum2DName, momentumSum2DName, positionName };
-        String[] xTitles2D = { "Positive Cluster Energy", "Positive Track Momentum", "x-Index" };
-        String[] yTitles2D = { "Negative Cluster Energy", "Negative Track Momentum", "y-Index" };
-        String zTitle2D = "Count";
-        
-        // Create a plotter factory.
-        IPlotterFactory plotterFactory = af.createPlotterFactory();
-        
-        // Format and display the basic histograms.
-        for(int i = 0; i < plots.length; i++) {
-            for(int j = 0; j < 2; j++) {
-                // Scale the histogram by the appropriate scaling factor.
-                plots[i][j].scale(1.0 / scaleFactor);
-                
-                // Create a plotter and plotting region for the plot.
-                IPlotter plotter = plotterFactory.create((j == 1 ? "Cluster " : "") + titles[i]);
-                plotter.createRegions(1);
-                plotter.region(0).plot(plots[i][j]);
-                
-                // Format the axis labels.
-                PlotterRegion region = (PlotterRegion) plotter.region(0);
-                region.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles[i]);
-                region.getPlot().getXAxis().setLabel(xTitles[i]);
-                region.getPlot().getYAxis().setLabel(yTitle);
-                
-                // Format the fonts and general plot presentation.
-                PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY });
-                
-                // Show the plot.
-                plotter.setParameter("plotterWidth", "2000");
-                plotter.setParameter("plotterHeight", "1200");
-                plotter.show();
-            }
-        }
-        
-        // Format and display the 2D histogram.
-        for(int i = 0; i < plots2D.length; i++) {
-            for(int j = 0; j < 2; j++) {
-                plots2D[i][j].scale(1.0 / scaleFactor);
-                IPlotter plotter2D = plotterFactory.create((j == 1 ? "Cluster " : "") + titles2D[i]);
-                plotter2D.createRegions(1);
-                plotter2D.region(0).plot(plots2D[i][j]);
-                
-                // Format the axis labels.
-                PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
-                region2D.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles2D[i]);
-                region2D.getPlot().getXAxis().setLabel(xTitles2D[i]);
-                region2D.getPlot().getYAxis().setLabel(yTitles2D[i]);
-                
-                // Format the fonts and general plot presentation.
-                PlotsFormatter.setDefault2DStyle(region2D, true);
-                
-                // Show the plot.
-                plotter2D.setParameter("plotterWidth", "2000");
-                plotter2D.setParameter("plotterHeight", "1200");
-                plotter2D.show();
-            }
-        }
-        
-        // Close the tree.
-        tree.close();
-    }
+	/**
+	 * Loads all plots in a file and formats them according to the
+	 * indicated style.
+	 * @param args - Unused default executable parameter.
+	 * @throws IOException Occurs if there is an issue opening the file.
+	 */
+	public static void main(String[] args) throws IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\tmp\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String plotFile = rootDir + "trident-out.aida";
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree tree = af.createTreeFactory().create(plotFile);
+		if(tree == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		
+		// Declare the histogram names.
+		String trackName = "Tracks in Event (All)";
+		String posTrackName = "Tracks in Event (Positive)";
+		String negTrackName = "Tracks in Event (Negative)";
+		String posMomentumName = "Momentum (Positive)";
+		String negMomentumName = "Momentum (Negative)";
+		String energySumName = "Energy Sum";
+		String momentumSumName = "Momentum Sum";
+		String energyMomentumDiffName = "Energy-Momentum Difference";
+		String invariantMassName = "Invariant Mass";
+		String energySum2DName = "2D Energy Sum";
+		String momentumSum2DName = "2D Momentum Sum";
+		String positionName = "Track Cluster Position";
+		
+		// Get the histograms.
+		IHistogram1D[] tracks = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + trackName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + trackName)
+		};
+		IHistogram1D[] posTracks = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + posTrackName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + posTrackName)
+		};
+		IHistogram1D[] negTracks = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + negTrackName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + negTrackName)
+		};
+		IHistogram1D[] posMomentum = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + posMomentumName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + posMomentumName)
+		};
+		IHistogram1D[] negMomentum = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + negMomentumName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + negMomentumName)
+		};
+		IHistogram1D[] energySum = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + energySumName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + energySumName)
+		};
+		IHistogram1D[] momentumSum = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + momentumSumName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + momentumSumName)
+		};
+		IHistogram1D[] energyMomentumDiff = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + energyMomentumDiffName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + energyMomentumDiffName)
+		};
+		IHistogram1D[] invariantMass = {
+				(IHistogram1D) tree.find("Trident Analysis/All/" + invariantMassName),
+				(IHistogram1D) tree.find("Trident Analysis/Cluster/" + invariantMassName)
+		};
+		IHistogram2D[] energySum2D = {
+				(IHistogram2D) tree.find("Trident Analysis/All/" + energySum2DName),
+				(IHistogram2D) tree.find("Trident Analysis/Cluster/" + energySum2DName)
+		};
+		IHistogram2D[] momentumSum2D = {
+				(IHistogram2D) tree.find("Trident Analysis/All/" + momentumSum2DName),
+				(IHistogram2D) tree.find("Trident Analysis/Cluster/" + momentumSum2DName)
+		};
+		IHistogram2D[] position = {
+				(IHistogram2D) tree.find("Trident Analysis/All/" + positionName),
+				(IHistogram2D) tree.find("Trident Analysis/Cluster/" + positionName)
+		};
+		
+		// Re-bin the histograms to have 5-times larger bins. First,
+		// get the bin count and upper and lower bounds of the plot.
+		int bins = invariantMass[0].axis().bins();
+		double low = invariantMass[0].axis().binLowerEdge(0);
+		double high = invariantMass[0].axis().binUpperEdge(invariantMass[0].axis().bins() - 1);
+		
+		// Create new plots with the larger bin sizes.
+		AIDA aida = AIDA.defaultInstance();
+		IHistogram1D[] newPlot = new IHistogram1D[2];
+		newPlot[0] = aida.histogram1D(invariantMassName, bins / 5, low, high);
+		newPlot[1] = aida.histogram1D("Cluster " + invariantMassName, bins / 5, low, high);
+		
+		// Populate the new plots with the data from the old ones.
+		for(int j = 0; j < 2; j++) {
+			for(int i = 0; i < bins; i++) {
+				int entries = invariantMass[j].binEntries(i);
+				double center = invariantMass[j].axis().binCenter(i);
+				for(int k = 0; k < entries; k++) {
+					newPlot[j].fill(center);
+				}
+			}
+		}
+		
+		// Replace the old plots.
+		invariantMass = newPlot;
+		
+		// Define the scaling factors for each plot.
+		double scaleFactor = 1;
+		
+		// Define the plot titles and arrays for 1D plots.
+		IHistogram[][] plots = { tracks, posTracks, negTracks, posMomentum, negMomentum, energySum, momentumSum, energyMomentumDiff, invariantMass };
+		String[] titles = { trackName, posTrackName, negTrackName, posMomentumName, negMomentumName, energySumName, momentumSumName,
+				energyMomentumDiffName, invariantMassName };
+		String[] xTitles = { "Tracks", "Tracks", "Tracks", "Momentum (GeV)", "Momentum (GeV)", "Energy Sum (GeV)", "Momentum Sum (GeV)",
+				"|E_Cluster - P_Track| (GeV)", "Invariant Mass (GeV)" };
+		String yTitle = "Count";
+		
+		// Define the plot titles and arrays for 2D plots.
+		IHistogram2D[][] plots2D = { energySum2D, momentumSum2D, position };
+		String[] titles2D = { energySum2DName, momentumSum2DName, positionName };
+		String[] xTitles2D = { "Positive Cluster Energy", "Positive Track Momentum", "x-Index" };
+		String[] yTitles2D = { "Negative Cluster Energy", "Negative Track Momentum", "y-Index" };
+		String zTitle2D = "Count";
+		
+		// Create a plotter factory.
+		IPlotterFactory plotterFactory = af.createPlotterFactory();
+		
+		// Format and display the basic histograms.
+		for(int i = 0; i < plots.length; i++) {
+			for(int j = 0; j < 2; j++) {
+				// Scale the histogram by the appropriate scaling factor.
+				plots[i][j].scale(1.0 / scaleFactor);
+				
+				// Create a plotter and plotting region for the plot.
+				IPlotter plotter = plotterFactory.create((j == 1 ? "Cluster " : "") + titles[i]);
+				plotter.createRegions(1);
+				plotter.region(0).plot(plots[i][j]);
+				
+				// Format the axis labels.
+				PlotterRegion region = (PlotterRegion) plotter.region(0);
+				region.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles[i]);
+				region.getPlot().getXAxis().setLabel(xTitles[i]);
+				region.getPlot().getYAxis().setLabel(yTitle);
+				
+				// Format the fonts and general plot presentation.
+				PlotsFormatter.setDefault1DStyle(region, new ColorStyle[] { ColorStyle.GREY }, PlotsFormatter.DisplayStyle.BAR);
+				
+				// Show the plot.
+				plotter.setParameter("plotterWidth", "2000");
+				plotter.setParameter("plotterHeight", "1200");
+				plotter.show();
+			}
+		}
+		
+		// Format and display the 2D histogram.
+		for(int i = 0; i < plots2D.length; i++) {
+			for(int j = 0; j < 2; j++) {
+				plots2D[i][j].scale(1.0 / scaleFactor);
+				IPlotter plotter2D = plotterFactory.create((j == 1 ? "Cluster " : "") + titles2D[i]);
+				plotter2D.createRegions(1);
+				plotter2D.region(0).plot(plots2D[i][j]);
+				
+				// Format the axis labels.
+				PlotterRegion region2D = (PlotterRegion) plotter2D.region(0);
+				region2D.getPlot().setTitle((j == 1 ? "Cluster " : "") + titles2D[i]);
+				region2D.getPlot().getXAxis().setLabel(xTitles2D[i]);
+				region2D.getPlot().getYAxis().setLabel(yTitles2D[i]);
+				
+				// Format the fonts and general plot presentation.
+				PlotsFormatter.setDefault2DStyle(region2D, true);
+				
+				// Show the plot.
+				plotter2D.setParameter("plotterWidth", "2000");
+				plotter2D.setParameter("plotterHeight", "1200");
+				plotter2D.show();
+			}
+		}
+		
+		// Close the tree.
+		tree.close();
+	}
 }

Modified: java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java
 =============================================================================
--- java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java	(original)
+++ java/trunk/users/src/main/java/org/hps/users/kmccarty/plots/formatter/TriggerPlotsFormat.java	Tue Sep 27 08:50:14 2016
@@ -20,331 +20,331 @@
 import hep.aida.ref.plotter.PlotterRegion;
 
 public class TriggerPlotsFormat {
-    // Define plot fonts.
-    private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
-    private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
-    private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
-    
-    // Defines the color style options for plot data.
-    private enum ColorStyle {
-         MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
-          MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
-        MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
-            RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
-          FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
-            TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
-            BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
-          PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
-        
-        private final Color fillColor;
-        private final Color lineColor;
-        
-        private ColorStyle(Color fillColor, Color lineColor) {
-            this.fillColor = fillColor;
-            this.lineColor = lineColor;
-        }
-        
-        public Color getFillColor() { return fillColor; }
-        
-        public Color getLineColor() { return lineColor; }
-    };
-        
-    /**
-     * Loads all plots in a file and formats them according to the
-     * indicated style.
-     * @param args - Unused default executable parameter.
-     * @throws IOException Occurs if there is an issue opening the file.
-     */
-    public static void main(String[] args) throws IOException {
-        // Define the root directory for the plots.
-        String rootDir = "D:\\cygwin64\\home\\Kyle\\beam-plots\\base\\";
-        //String rootDir = "D:\\cygwin64\\home\\Kyle\\aprime-plots\\base\\readout-plots\\";
-        
-        // Define the new name of the file containing the trigger plots.
-        String[] plotFile = {
-                rootDir + "compiled-plots.aida"
-                //rootDir + "15-MeV\\compiled-plots.aida",
-                //rootDir + "20-MeV\\compiled-plots.aida",
-                //rootDir + "30-MeV\\compiled-plots.aida",
-                //rootDir + "40-MeV\\compiled-plots.aida",
-                //rootDir + "50-MeV\\compiled-plots.aida"
-        };
-        
-        // Define the names of each plot. This will be used for the
-        // legend in the case of multiple plots.
-        String[] treeName = {
-            "Background",
-            "15 MeV A'",
-            "20 MeV A'",
-            "30 MeV A'",
-            "40 MeV A'",
-            "50 MeV A'"
-        };
-        
-        // Define the color style for the plots.
-        ColorStyle[] dataColorStyle = {
-                ColorStyle.GREY,
-                ColorStyle.MS_GREEN,
-                ColorStyle.MS_BLUE,
-                ColorStyle.MS_ORANGE,
-                ColorStyle.MS_RED,
-                ColorStyle.TEAL,
-                ColorStyle.CRIMSON,
-                ColorStyle.FOREST
-        };
-        
-        // Get the plots file and open it.
-        IAnalysisFactory af = IAnalysisFactory.create();
-        ITree[] tree = new ITree[plotFile.length];
-        for(int i = 0; i < plotFile.length; i++) {
-            tree[i] = af.createTreeFactory().create(plotFile[i]);
-            if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
-        }
-        
-        // Get a list of all the histograms in the file.
-        List<List<String>> treeHistograms = new ArrayList<List<String>>(plotFile.length);
-        for(int i = 0; i < plotFile.length; i++) {
-            treeHistograms.add(getHistograms(tree[i], "/NoCuts/"));//, "/PassedAll/"));
-        }
-        
-        // Create a plotter factory.
-        IPlotterFactory plotterFactory = af.createPlotterFactory();
-        
-        // Plot each histogram and format it.
-        for(String histogram : treeHistograms.get(0)) {
-            // Get the plot from the tree and verify that it is a 1D
-            // or 2D histogram. Other types are not supported.
-            IManagedObject histObject = tree[0].find(histogram);
-            if(!(histObject instanceof IHistogram1D) && !(histObject instanceof IHistogram2D)) {
-                continue;
-            }
-            
-            // Obtain the histogram object.
-            IBaseHistogram hist;
-            if(histObject instanceof IHistogram1D) { hist = (IHistogram1D) histObject; }
-            else { hist = (IHistogram2D) histObject; }
-            
-            // Define whether this is an overlay plot and whether
-            // this is a one or two dimensional plot.
-            boolean overlay = plotFile.length > 1;
-            boolean twoDimensional = hist instanceof IHistogram2D;
-            
-            // Generate the plotter and set its title. The plotter will
-            // use the title of the first tree's plot.
-            String plotTitle = hist.title();
-            IPlotter plotter = plotterFactory.create(plotTitle);
-            
-            // For single plots and one-dimensional overlay plots,
-            // there should only be a single plotter region.
-            if(!twoDimensional || !overlay) { plotter.createRegions(1); }
-            
-            // For two-dimensional overlay plots, create a region for
-            // each plot individually.
-            else { plotter.createRegions(2, (int) Math.ceil(plotFile.length / 2.0)); }
-            
-            // Find the histogram in each of the trees and plot them
-            // all on the same region.
-            for(int i = 0; i < plotFile.length; i++) {
-                // Get the histogram from the tree.
-                IManagedObject treeObject = tree[i].find(histogram);
-                IBaseHistogram treeHist;
-                if(treeObject instanceof IHistogram1D) { treeHist = (IHistogram1D) treeObject; }
-                else { treeHist = (IHistogram2D) treeObject; }
-                
-                // Display the plot.
-                if(treeHist != null) {
-                    // Set the title of plot to the name associated with
-                    // its tree. This ensures that the correct name will
-                    // appear on the legend.
-                    if(plotFile.length > 1) {
-                        treeHist.setTitle(treeName[i]);
-                    }
-                    
-                    // Plot the tree's data in the plotter region.
-                    if(!twoDimensional || !overlay) { plotter.region(0).plot(treeHist); }
-                    else {
-                        plotter.region(i).plot(treeHist);
-                        setDefault2DStyle(((PlotterRegion) plotter.region(i)), dataColorStyle);
-                    }
-                }
-            }
-            
-            // Format the plot region.
-            if(!twoDimensional) { setDefault1DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
-            else { setDefault2DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
-            
-            // Show the plotter.
-            plotter.region(0).setTitle(plotTitle);
-            plotter.setParameter("plotterWidth", "750");
-            plotter.setParameter("plotterHeight", "600");
-            //plotter.setParameter("plotterWidth", "2000");
-            //plotter.setParameter("plotterHeight", "1200");
-            plotter.show();
-        }
-        
-        // Close the trees.
-        for(int i = 0; i < plotFile.length; i++) {
-            tree[i].close();
-        }
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     * @param color - The data color settings to use.
-     */
-    private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
-        // Get the names of each plot on in the region.
-        String[] dataNames = region.getAllDataNames();
-        
-        // Check whether this is an overlay plot. Overlay plots contain
-        // more than one data name.
-        boolean overlay = (dataNames.length > 1 ? true : false);
-        
-        // Iterate over each plot in the region.
-        for(int i = 0; i < dataNames.length; i++) {
-            // Set the overlay style if needed.
-            if(overlay) {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with no fill. The color is set by the "color" argument.
-                fillStyle.setHistogramFill(false);
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarLineColor(color[i].getFillColor());
-                
-                // Set the legend text style.
-                region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
-            }
-            
-            // Otherwise, set the fill style for a single plot.
-            else {
-                // Get the fill style for the current data type.
-                JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
-                
-                // Set the histogram style to display thick-lined bars
-                // with a fill color. The colors are defined by the
-                // "color" argument.
-                fillStyle.setHistogramBarLineWidth(3);
-                fillStyle.setHistogramBarColor(color[i].getFillColor());
-                fillStyle.setHistogramBarLineColor(color[i].getLineColor());
-            }
-            
-            // Set the statistics box style.
-            region.getPlot().getStats().setVisible(true);
-            region.getPlot().getStats().setFont(BASIC_FONT);
-            
-            // Set the title font.
-            region.getPlot().getTitleObject().setFont(TITLE_FONT);
-            
-            // Set generic axis titles.
-            region.getPlot().getXAxis().setLabel("Data Label (Unit)");
-            region.getPlot().getYAxis().setLabel("Count");
-            
-            // Set the axis tick-mark fonts.
-            region.getPlot().getXAxis().setFont(BASIC_FONT);
-            region.getPlot().getYAxis().setFont(BASIC_FONT);
-            region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-            region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-        }
-    }
-    
-    /**
-     * Sets the plot display formatting for 1D plots.
-     * @param region - The plotter region to format.
-     * @param color - The data color settings to use.
-     */
-    private static final void setDefault2DStyle(PlotterRegion region, ColorStyle[] color) {
-        // Get the fill style object. 2D plots should never be overlay
-        // plots, so there should only ever be one data name.
-        JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
-        
-        // Set the fill style for a two-dimensional plot.
-        fillStyle.setLogZ(true);
-        fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
-        fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
-        
-        // Make the statistics box invisible.
-        region.getPlot().getStats().setVisible(false);
-        
-        // Set the general plot font (which is also the z-axis font).
-        region.getPlot().setFont(BASIC_FONT);
-        
-        // Set the title font.
-        region.getPlot().getTitleObject().setFont(TITLE_FONT);
-        
-        // Set generic axis titles.
-        region.getPlot().getXAxis().setLabel("Data Label (Unit)");
-        region.getPlot().getYAxis().setLabel("Data Label (Unit)");
-        
-        // Set the axis tick-mark fonts.
-        region.getPlot().getXAxis().setFont(BASIC_FONT);
-        region.getPlot().getYAxis().setFont(BASIC_FONT);
-        region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
-        region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
-    }
-    
-    /**
-     * Gets a list of all objects that are not directories in a tree.
-     * @param tree - The tree from which to extract the object names.
-     * @return Returns the object names as <code>String</code> objects
-     * in a <code>List</code> collection.
-     */
-    private static final List<String> getHistograms(ITree tree) {
-        return getHistograms(tree, "/");
-    }
-    
-    /**
-     * Gets a list of all objects that are not directories in a tree.
-     * @param tree - The tree from which to extract the object names.
-     * @return Returns the object names as <code>String</code> objects
-     * in a <code>List</code> collection.
-     */
-    private static final List<String> getHistograms(ITree tree, String rootDir) {
-        return getHistograms(tree, rootDir, new ArrayList<String>());
-    }
-    
-    /**
-     * Recursive method that gets all object names from a tree that
-     * are not directories. Method should not be called directly, but
-     * rather called only through the <code>getHistograms(ITree)</code>
-     * method.
-     * @param tree - The tree from which to obtain the object names.
-     * @param directory - The directory in which to search for objects.
-     * @param list - The list in which to place the objects.
-     * @return Returns the <code>List</code> collection that was given
-     * as an argument.
-     */
-    private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
-        // Get the list of objects in the directory.
-        String[] treeObjects = tree.listObjectNames(directory);
-        
-        // Print the objects.
-        for(String objectName : treeObjects) {
-            // Check if the object is a directory.
-            boolean isDirectory = isDirectory(objectName);
-            
-            // If the object is a directory, get the histograms from it.
-            if(isDirectory) {
-                getHistograms(tree, objectName, list);
-            }
-            
-            // If the object is a plot, add it to the list.
-            else { list.add(objectName); }
-        }
-        
-        // Return the list.
-        return list;
-    }
-    
-    /**
-     * Checks whether a tree object is a directory.
-     * @param object - The object to check.
-     * @return Returns <code>true</code> if the object is a directory
-     * and <code>false</code> otherwise.
-     */
-    private static final boolean isDirectory(String object) {
-        return (object.toCharArray()[object.length() - 1] == '/');
-    }
+	// Define plot fonts.
+	private static final Font BASIC_FONT = new Font("Calibri", Font.PLAIN, 20);
+	private static final Font AXIS_FONT  = new Font("Calibri", Font.BOLD,  25);
+	private static final Font TITLE_FONT = new Font("Calibri", Font.BOLD,  35);
+	
+	// Defines the color style options for plot data.
+	private enum ColorStyle {
+		 MS_BLUE(new Color( 79, 129, 189), new Color( 36,  64,  97)), MS_ORANGE(new Color(247, 150,  70), new Color(152,  72,   6)),
+		  MS_RED(new Color(192,  80,  77), new Color( 99,  36,  35)),      GREY(new Color(166, 166, 166), new Color( 89,  89,  89)),
+		MS_GREEN(new Color(155, 187,  89), new Color( 79,  98,  40)),   CRIMSON(new Color(161,   0,   0), new Color(104,   0,   0)),
+		    RUST(new Color(161,  80,   0), new Color(105,  80,   0)),    YELLOW(new Color(161, 161,   0), new Color(122, 109,   8)),
+		  FOREST(new Color( 65, 102,   0), new Color( 37,  79,   0)),     GREEN(new Color(  7, 132,  70), new Color(  7,  82,  30)),
+		    TEAL(new Color(  0, 130, 130), new Color(  0,  90, 100)),  CERULEAN(new Color(  0,  86, 130), new Color(  0,  28,  83)),
+		    BLUE(new Color(  0,  33, 203), new Color(  0,   0, 137)),    INDIGO(new Color( 68,  10, 127), new Color(  0,   0,  61)),
+		  PURPLE(new Color(106,   0, 106), new Color( 63,   0,  56)),   FUSCHIA(new Color(119,   0,  60), new Color( 60,   0,  60));
+		
+		private final Color fillColor;
+		private final Color lineColor;
+		
+		private ColorStyle(Color fillColor, Color lineColor) {
+			this.fillColor = fillColor;
+			this.lineColor = lineColor;
+		}
+		
+		public Color getFillColor() { return fillColor; }
+		
+		public Color getLineColor() { return lineColor; }
+	};
+		
+	/**
+	 * Loads all plots in a file and formats them according to the
+	 * indicated style.
+	 * @param args - Unused default executable parameter.
+	 * @throws IOException Occurs if there is an issue opening the file.
+	 */
+	public static void main(String[] args) throws IOException {
+		// Define the root directory for the plots.
+		String rootDir = "D:\\cygwin64\\home\\Kyle\\beam-plots\\base\\";
+		//String rootDir = "D:\\cygwin64\\home\\Kyle\\aprime-plots\\base\\readout-plots\\";
+		
+		// Define the new name of the file containing the trigger plots.
+		String[] plotFile = {
+				rootDir + "compiled-plots.aida"
+				//rootDir + "15-MeV\\compiled-plots.aida",
+				//rootDir + "20-MeV\\compiled-plots.aida",
+				//rootDir + "30-MeV\\compiled-plots.aida",
+				//rootDir + "40-MeV\\compiled-plots.aida",
+				//rootDir + "50-MeV\\compiled-plots.aida"
+		};
+		
+		// Define the names of each plot. This will be used for the
+		// legend in the case of multiple plots.
+		String[] treeName = {
+			"Background",
+			"15 MeV A'",
+			"20 MeV A'",
+			"30 MeV A'",
+			"40 MeV A'",
+			"50 MeV A'"
+		};
+		
+		// Define the color style for the plots.
+		ColorStyle[] dataColorStyle = {
+				ColorStyle.GREY,
+				ColorStyle.MS_GREEN,
+				ColorStyle.MS_BLUE,
+				ColorStyle.MS_ORANGE,
+				ColorStyle.MS_RED,
+				ColorStyle.TEAL,
+				ColorStyle.CRIMSON,
+				ColorStyle.FOREST
+		};
+		
+		// Get the plots file and open it.
+		IAnalysisFactory af = IAnalysisFactory.create();
+		ITree[] tree = new ITree[plotFile.length];
+		for(int i = 0; i < plotFile.length; i++) {
+			tree[i] = af.createTreeFactory().create(plotFile[i]);
+			if(tree[i] == null) { throw new IllegalArgumentException("Unable to load plot file."); }
+		}
+		
+		// Get a list of all the histograms in the file.
+		List<List<String>> treeHistograms = new ArrayList<List<String>>(plotFile.length);
+		for(int i = 0; i < plotFile.length; i++) {
+			treeHistograms.add(getHistograms(tree[i], "/NoCuts/"));//, "/PassedAll/"));
+		}
+		
+		// Create a plotter factory.
+		IPlotterFactory plotterFactory = af.createPlotterFactory();
+		
+		// Plot each histogram and format it.
+		for(String histogram : treeHistograms.get(0)) {
+			// Get the plot from the tree and verify that it is a 1D
+			// or 2D histogram. Other types are not supported.
+			IManagedObject histObject = tree[0].find(histogram);
+			if(!(histObject instanceof IHistogram1D) && !(histObject instanceof IHistogram2D)) {
+				continue;
+			}
+			
+			// Obtain the histogram object.
+			IBaseHistogram hist;
+			if(histObject instanceof IHistogram1D) { hist = (IHistogram1D) histObject; }
+			else { hist = (IHistogram2D) histObject; }
+			
+			// Define whether this is an overlay plot and whether
+			// this is a one or two dimensional plot.
+			boolean overlay = plotFile.length > 1;
+			boolean twoDimensional = hist instanceof IHistogram2D;
+			
+			// Generate the plotter and set its title. The plotter will
+			// use the title of the first tree's plot.
+			String plotTitle = hist.title();
+			IPlotter plotter = plotterFactory.create(plotTitle);
+			
+			// For single plots and one-dimensional overlay plots,
+			// there should only be a single plotter region.
+			if(!twoDimensional || !overlay) { plotter.createRegions(1); }
+			
+			// For two-dimensional overlay plots, create a region for
+			// each plot individually.
+			else { plotter.createRegions(2, (int) Math.ceil(plotFile.length / 2.0)); }
+			
+			// Find the histogram in each of the trees and plot them
+			// all on the same region.
+			for(int i = 0; i < plotFile.length; i++) {
+				// Get the histogram from the tree.
+				IManagedObject treeObject = tree[i].find(histogram);
+				IBaseHistogram treeHist;
+				if(treeObject instanceof IHistogram1D) { treeHist = (IHistogram1D) treeObject; }
+				else { treeHist = (IHistogram2D) treeObject; }
+				
+				// Display the plot.
+				if(treeHist != null) {
+					// Set the title of plot to the name associated with
+					// its tree. This ensures that the correct name will
+					// appear on the legend.
+					if(plotFile.length > 1) {
+						treeHist.setTitle(treeName[i]);
+					}
+					
+					// Plot the tree's data in the plotter region.
+					if(!twoDimensional || !overlay) { plotter.region(0).plot(treeHist); }
+					else {
+						plotter.region(i).plot(treeHist);
+						setDefault2DStyle(((PlotterRegion) plotter.region(i)), dataColorStyle);
+					}
+				}
+			}
+			
+			// Format the plot region.
+			if(!twoDimensional) { setDefault1DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
+			else { setDefault2DStyle(((PlotterRegion) plotter.region(0)), dataColorStyle); }
+			
+			// Show the plotter.
+			plotter.region(0).setTitle(plotTitle);
+			plotter.setParameter("plotterWidth", "750");
+			plotter.setParameter("plotterHeight", "600");
+			//plotter.setParameter("plotterWidth", "2000");
+			//plotter.setParameter("plotterHeight", "1200");
+			plotter.show();
+		}
+		
+		// Close the trees.
+		for(int i = 0; i < plotFile.length; i++) {
+			tree[i].close();
+		}
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 * @param color - The data color settings to use.
+	 */
+	private static final void setDefault1DStyle(PlotterRegion region, ColorStyle[] color) {
+		// Get the names of each plot on in the region.
+		String[] dataNames = region.getAllDataNames();
+		
+		// Check whether this is an overlay plot. Overlay plots contain
+		// more than one data name.
+		boolean overlay = (dataNames.length > 1 ? true : false);
+		
+		// Iterate over each plot in the region.
+		for(int i = 0; i < dataNames.length; i++) {
+			// Set the overlay style if needed.
+			if(overlay) {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with no fill. The color is set by the "color" argument.
+				fillStyle.setHistogramFill(false);
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setHistogramBarLineColor(color[i].getFillColor());
+				
+				// Set the legend text style.
+				region.getPlot().getLegend().setFont(new Font("Calibri", Font.PLAIN, 20));
+			}
+			
+			// Otherwise, set the fill style for a single plot.
+			else {
+				// Get the fill style for the current data type.
+				JASHist1DHistogramStyle fillStyle = (JASHist1DHistogramStyle) region.getDataForName(dataNames[i]).getStyle();
+				
+				// Set the histogram style to display thick-lined bars
+				// with a fill color. The colors are defined by the
+				// "color" argument.
+				fillStyle.setHistogramBarLineWidth(3);
+				fillStyle.setHistogramBarColor(color[i].getFillColor());
+				fillStyle.setHistogramBarLineColor(color[i].getLineColor());
+			}
+			
+			// Set the statistics box style.
+			region.getPlot().getStats().setVisible(true);
+			region.getPlot().getStats().setFont(BASIC_FONT);
+			
+			// Set the title font.
+			region.getPlot().getTitleObject().setFont(TITLE_FONT);
+			
+			// Set generic axis titles.
+			region.getPlot().getXAxis().setLabel("Data Label (Unit)");
+			region.getPlot().getYAxis().setLabel("Count");
+			
+			// Set the axis tick-mark fonts.
+			region.getPlot().getXAxis().setFont(BASIC_FONT);
+			region.getPlot().getYAxis().setFont(BASIC_FONT);
+			region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+			region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+		}
+	}
+	
+	/**
+	 * Sets the plot display formatting for 1D plots.
+	 * @param region - The plotter region to format.
+	 * @param color - The data color settings to use.
+	 */
+	private static final void setDefault2DStyle(PlotterRegion region, ColorStyle[] color) {
+		// Get the fill style object. 2D plots should never be overlay
+		// plots, so there should only ever be one data name.
+		JASHist2DHistogramStyle fillStyle = (JASHist2DHistogramStyle) region.getDataForName(region.getAllDataNames()[0]).getStyle();
+		
+		// Set the fill style for a two-dimensional plot.
+		fillStyle.setLogZ(true);
+		fillStyle.setHistStyle(JASHist2DHistogramStyle.STYLE_COLORMAP);
+		fillStyle.setColorMapScheme(JASHist2DHistogramStyle.COLORMAP_RAINBOW);
+		
+		// Make the statistics box invisible.
+		region.getPlot().getStats().setVisible(false);
+		
+		// Set the general plot font (which is also the z-axis font).
+		region.getPlot().setFont(BASIC_FONT);
+		
+		// Set the title font.
+		region.getPlot().getTitleObject().setFont(TITLE_FONT);
+		
+		// Set generic axis titles.
+		region.getPlot().getXAxis().setLabel("Data Label (Unit)");
+		region.getPlot().getYAxis().setLabel("Data Label (Unit)");
+		
+		// Set the axis tick-mark fonts.
+		region.getPlot().getXAxis().setFont(BASIC_FONT);
+		region.getPlot().getYAxis().setFont(BASIC_FONT);
+		region.getPlot().getXAxis().getLabelObject().setFont(AXIS_FONT);
+		region.getPlot().getYAxis().getLabelObject().setFont(AXIS_FONT);
+	}
+	
+	/**
+	 * Gets a list of all objects that are not directories in a tree.
+	 * @param tree - The tree from which to extract the object names.
+	 * @return Returns the object names as <code>String</code> objects
+	 * in a <code>List</code> collection.
+	 */
+	private static final List<String> getHistograms(ITree tree) {
+		return getHistograms(tree, "/");
+	}
+	
+	/**
+	 * Gets a list of all objects that are not directories in a tree.
+	 * @param tree - The tree from which to extract the object names.
+	 * @return Returns the object names as <code>String</code> objects
+	 * in a <code>List</code> collection.
+	 */
+	private static final List<String> getHistograms(ITree tree, String rootDir) {
+		return getHistograms(tree, rootDir, new ArrayList<String>());
+	}
+	
+	/**
+	 * Recursive method that gets all object names from a tree that
+	 * are not directories. Method should not be called directly, but
+	 * rather called only through the <code>getHistograms(ITree)</code>
+	 * method.
+	 * @param tree - The tree from which to obtain the object names.
+	 * @param directory - The directory in which to search for objects.
+	 * @param list - The list in which to place the objects.
+	 * @return Returns the <code>List</code> collection that was given
+	 * as an argument.
+	 */
+	private static final List<String> getHistograms(ITree tree, String directory, List<String> list) {
+		// Get the list of objects in the directory.
+		String[] treeObjects = tree.listObjectNames(directory);
+		
+		// Print the objects.
+		for(String objectName : treeObjects) {
+			// Check if the object is a directory.
+			boolean isDirectory = isDirectory(objectName);
+			
+			// If the object is a directory, get the histograms from it.
+			if(isDirectory) {
+				getHistograms(tree, objectName, list);
+			}
+			
+			// If the object is a plot, add it to the list.
+			else { list.add(objectName); }
+		}
+		
+		// Return the list.
+		return list;
+	}
+	
+	/**
+	 * Checks whether a tree object is a directory.
+	 * @param object - The object to check.
+	 * @return Returns <code>true</code> if the object is a directory
+	 * and <code>false</code> otherwise.
+	 */
+	private static final boolean isDirectory(String object) {
+		return (object.toCharArray()[object.length() - 1] == '/');
+	}
 }

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use