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  August 2015

HPS-SVN August 2015

Subject:

r3348 - in /java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal: cluster/ daqconfig/ triggerbank/

From:

[log in to unmask]

Reply-To:

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

Date:

Fri, 7 Aug 2015 00:19:44 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (3394 lines)

Author: [log in to unmask]
Date: Thu Aug  6 17:19:42 2015
New Revision: 3348

Log:
Updated documentation for many ecal-recon drivers. Classes TDCData and HeadBankData require documentation still; I am not familiar enough with their function to provide it.

Modified:
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/ConfigurationManager.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/DAQConfigDriver.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/EvioDAQParser.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/AbstractIntData.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/SSPCluster.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TIData.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TriggerModule.java

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterDriver.java	Thu Aug  6 17:19:42 2015
@@ -1,24 +1,36 @@
 package org.hps.recon.ecal.cluster;
 
 /**
- * Class <code>GTPClusterDriver</code> instantiates an instance of
- * the clustering algorithm framework for the Monte Carlo version
- * of the GTP algorithm. This version assumes that events are equal
- * to 2 ns beam bunches. The class also allows the seed energy threshold
- * and cluster window to be set as well as whether or not the algorithm
- * should employ an asymmetric time window and write out verbose debug
- * text.
+ * Class <code>GTPClusterDriver</code> is an implementation of the
+ * <code>ClusterDriver</code> class that defines employs the readout
+ * variant of the GTP hardware clustering algorithm. Specifics on the
+ * behavior of this algorithm can be found in its documentation.<br/>
+ * <br/>
+ * <code>GTPClusterDriver</code> allows for all of the variable settings
+ * used by the GTP algorithm to be defined. It also can be set to
+ * "verbose" mode, where it will output detailed information on each
+ * event and the cluster forming process. This is disabled by default,
+ * but can be enabled for debugging purposes.<br/>
+ * <br/>
+ * <code>GTPClusterDriver</code> is designed to read from Monte Carlo
+ * data organized into 2-ns beam bunches. It can not be used for hardware
+ * readout data, or Monte Carlo formatted in this style. For this data,
+ * the <code>GTPOnlineClusterer</code> should be employed instead.
  * 
  * @author Kyle McCarty <[log in to unmask]>
  * @author Jeremy McCormick <[log in to unmask]>
  * @see GTPClusterer
  */
 public class GTPClusterDriver extends ClusterDriver {
-    // The GTP clustering algorithm.
+	/** An instance of the clustering algorithm object for producing
+	 * cluster objects. */
     private final GTPClusterer gtp;
     
     /**
-     * Instantiates a new <code>GTPClusterer</code>.
+     * Instantiates a new <code>GTPClusterer</code>, which will produce
+     * clusters using the GTP algorithm in the 2-ns beam bunch scheme.
+     * It will, by default, use a 50 MeV seed energy cut with +/- 2 a
+     * clock-cycle verification and inclusion window.
      */
     public GTPClusterDriver() {
         clusterer = ClustererFactory.create("GTPClusterer");
@@ -27,66 +39,77 @@
     }
     
     /**
-     * Sets whether hits should be added to a cluster from the entire
-     * cluster window or just the "future" hits, plus one clock-cycle
-     * of "past" hits as a safety buffer to account for time uncertainty.
-     * 
-     * @param limitClusterRange - <code>true</code> indicates that
-     * the asymmetric clustering window should be used and <code>
-     * false</code> that the symmetric window should be used.
+     * Sets whether the behavior of the hit inclusion window with respect
+     * to the hit verification window. If set to <code>false</code>,
+     * both windows will be identical in size. Otherwise, the inclusion
+     * window will be equal in size after the seed hit, but encompass
+     * only one clock-cycle before the seed hit. This should be replaced
+     * by the method <code>setAsymmetricWindow</code>.
+     * @param limitClusterRange - <code>true</code> indicates that the
+     * asymmetric window should be used and <code>false</code> that it
+     * should not.
      */
     @Deprecated
     public void setLimitClusterRange(boolean limitClusterRange) {
-        gtp.setLimitClusterRange(limitClusterRange);
+        gtp.setAsymmetricWindow(limitClusterRange);
     }
     
     /**
-     * Sets the number of clock-cycles (4 ns) before and after a hit
-     * in which the hit must be the maximum energy hit in its 3 x 3
-     * window in order to be considered a seed hit and form a cluster.
+     * Sets the size of the hit verification temporal window. Note
+     * that this defines the size of the window in one direction, so
+     * the full time window will be <code>(2 * clusterWindow) + 1</code>
+     * clock-cycles in length. (i.e., it will be a length of
+     * <code>clusterWindow</code> before the seed hit, a length of
+     * <code>clusterWindow</code> after the seed hit, plus the cycle
+     * that includes the seed hit.) Time length is in clock-cycles.
      * @param clusterWindow - The number of clock-cycles around the
-     * hit in one direction; i.e. a value of 1 indicates that the full
-     * window will include the current clock-cycle, plus one cycle both
-     * before and after the current cycle. This gives a total number
-     * of cycles equal to (2 * clusterWindow) + 1.
+     * hit in one direction.
      */
     public void setClusterWindow(int clusterWindow) {
         gtp.getCuts().setValue("clusterWindow", clusterWindow);
     }
     
     /**
-     * Sets the minimum energy needed for a seed hit to form a cluster.
-     * @param seedEnergyThreshold - The minimum seed energy in GeV.
+     * Sets the minimum seed energy needed for a hit to be considered
+     * for forming a cluster. This is the seed energy lower bound trigger
+     * cut and is in units of GeV.
+     * @param seedEnergyThreshold - The minimum cluster seed energy in
+     * GeV.
      */
     public void setSeedEnergyThreshold(double seedEnergyThreshold) {
         gtp.getCuts().setValue("seedEnergyThreshold", seedEnergyThreshold);
     }
     
     /**
-     * Sets whether the clustering algorithm should use an asymmetric
-     * clustering window. The asymmetric window will include hits in
-     * a cluster that are present within the full time window ahead of
-     * the seed hit, but only one clock-cycle behind it. This is to
-     * allow for variation in hit timing with respect to the seed due
-     * to jitter in the hardware.
+     * Sets whether the behavior of the hit inclusion window with respect
+     * to the hit verification window. If set to <code>false</code>,
+     * both windows will be identical in size. Otherwise, the inclusion
+     * window will be equal in size after the seed hit, but encompass
+     * only one clock-cycle before the seed hit.
      * @param asymmetricWindow - <code>true</code> indicates that the
      * asymmetric window should be used and <code>false</code> that it
      * should not.
      */
     public void setAsymmetricWindow(boolean asymmetricWindow) {
-        gtp.setLimitClusterRange(asymmetricWindow);
+        gtp.setAsymmetricWindow(asymmetricWindow);
     }
     
     /**
      * Sets whether the clustering algorithm should output diagnostic
      * text or not.
-     * @param verbose <code>true</code> indicates that the driver should
+     * @param verbose - <code>true</code> indicates that the driver should
      * output diagnostic text and <code>false</code> that it should not.
      */
     public void setVerbose(boolean verbose) {
         gtp.setVerbose(verbose);
     }
     
+    /**
+     * Defines whether the output of this clusterer should be persisted
+     * to LCIO or not. By default, this 
+     * @param state - <code>true</code> indicates that clusters will
+     * be persisted, and <code>false</code> that they will not.
+     */
     @Override
     public void setWriteClusterCollection(boolean state) {
     	// Set the flag as appropriate with the superclass.

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java	Thu Aug  6 17:19:42 2015
@@ -15,37 +15,70 @@
 import org.lcsim.event.base.BaseCluster;
 
 /**
- * Class <code>GTPCalorimeterClusterer</code> processes events and
- * converts hits into clusters, where appropriate. It uses the modified
- * 2014 clustering algorithm.<br/>
+ * Class <code>GTPClusterer</code> is an implementation of the abstract
+ * class <code>AbstractClusterer</code> that is responsible for producing
+ * clusters using the GTP algorithm employed by the hardware.<br/>
  * <br/>
- * For a hit to be a cluster center, it is required to have an energy
- * above some tunable minimum threshold. Additionally, the hit must be
- * a local maximum with respect to its neighbors and itself over a tunable
- * (default 2) clock cycles. Hits that pass these checks are then required
- * to additional have a total cluster energy that exceeds another tunable
- * minimum threshold.<br/>
+ * The GTP algorithm produces clusters by finding hits representing
+ * local spatiotemporal energy maxima and forming a cluster from the
+ * hits within the aforementioned spatiotemporal window. A given hit
+ * is first checked to see if it exceeds some minimum energy threshold
+ * (referred to as the "seed energy threshold"). If this is the case,
+ * the algorithm looks at all hits that occurred in the same crystal as
+ * the comparison hit, or any crystal directly adjacent to it, within
+ * a programmable time window. If the hit exceeds all hits meeting these
+ * criteria in energy, the hit is considered the “seed hit” of a cluster.
+ * Then, all hits within the 3x3 spatial window which occur in the time
+ * window are added to a <code>Cluster</code> object.<br/>
  * <br/>
- * A hit is added to a cluster as a component if it has a non-zero energy
- * and within the aforementioned tunable time buffer used for clustering
- * and is either at the same location as the seed hit or is a neighbor
- * to the seed hit.
- * @author Kyle McCarty
- * @author Sho Uemura
+ * Note that the algorithm employs two distinct temporal windows. The
+ * first is the “verification” window. This is used to check that the
+ * potential seed hit is a local maximum in energy, and is required to
+ * be symmetric (i.e. as long before the seed time as after it) to ensure
+ * consistency. The second temporal window is the “inclusion” window,
+ * which determines which hits are included in the cluster. The inclusion
+ * window can be asymmetric, but can not exceed the verification window
+ * in length. As an example, one could choose a 12 ns verification window,
+ * meaning that the algorithm would 12 ns before and after the seed hit
+ * to check that it has the highest energy, but use a 4 ns/12 ns inclusion
+ * window, meaning that the algorithm would only include hits in 3x3
+ * spatial window up to 4 ns before and up to 12 ns after the seed hit
+ * in the cluster. Due to the way the hardware processes hits, the higher
+ * energy parts of a cluster always occur first in time, so it is not
+ * necessarily desirable to include hits significantly before the seed.
+ * It is however, necessary to verify a hit’s status as a maximum across
+ * the full time window to ensure consistency in cluster formation.
+ * <code>GTPClusterer</code> automatically defines the inclusion window
+ * in terms of the verification window.<br/>
+ * <br/>
+ * <code>GTPClusterer</code> requires as input a collection of
+ * <code>CalorimeterHit</code> objects representing the event hits. It
+ * will then produce a collection of <code>Cluster</code> objects
+ * representing the GTP algorithm output. It is designed to be run on
+ * Monte Carlo events where each event represents a 2 ns beam bunch.
+ * If the input data is formatted in the style of hardware readout, the
+ * sister class <code>GTPOnlineClusterer</code> should be used instead.
+ * 
+ * @author Kyle McCarty <[log in to unmask]>
+ * @author Sho Uemura <[log in to unmask]>
+ * @see Cluster
+ * @see CalorimeterHit
+ * @see AbstractClusterer
+ * @see GTPOnlineClusterer
  */
 public class GTPClusterer extends AbstractClusterer {
-	
     /**
      * The minimum energy required for a hit to be considered as a
      * cluster center. Hits with energy less than this value will be
-     * ignored.
+     * ignored. This is the seed energy lower bound cut.
      */
     private double seedEnergyThreshold;
     
     /**
      * Indicates the number of FADC clock cycles (each cycle is 4 ns)
      * before and after a given cycle that should be considered when
-     * checking if a cluster is a local maximum in space-time.
+     * checking if a cluster is a local maximum in space-time. This
+     * is the hit verification temporal window.
      */
     private int clusterWindow;
     
@@ -58,7 +91,8 @@
     
     /**
      * Whether an asymmetric or symmetric window should be used for
-     * adding hits to a cluster.
+     * adding hits to a cluster. This defines the hit inclusion temporal
+     * window with respect to the verification window.
      */
     private boolean limitClusterRange = false;
     
@@ -75,213 +109,23 @@
     private boolean writeHitCollection = true;
     
     /**
-     * Instantiates the clusterer.
+     * Instantiates a new instance of a Monte Carlo GTP clustering
+     * algorithm. It will use the default seed energy threshold of
+     * 50 MeV and a default hit inclusion window of +/- 2 ns. By
+     * default the cluster inclusion and verification windows are
+     * identical.
      */
     GTPClusterer() {
-        super(new String[] { "seedEnergyThreshold", "clusterWindow" }, new double[] { 0.00, 2.});
-    }
-    
-    /**
-     * Sets the clustering algorithm parameters.
-     */
-    @Override
-    public void initialize() {
-        // Set cuts.
-        setSeedEnergyThreshold(getCuts().getValue("seedEnergyThreshold"));
-        setClusterWindow((int) getCuts().getValue("clusterWindow"));
-        
-        // Initiate the hit buffer.
-        hitBuffer = new LinkedList<Map<Long, CalorimeterHit>>();
-        
-        // Populate the event buffer with (2 * clusterWindow + 1)
-        // empty events. These empty events represent the fact that
-        // the first few events will not have any events in the past
-        // portion of the buffer.
-        int bufferSize = (2 * clusterWindow) + 1;
-        for (int i = 0; i < bufferSize; i++) {
-            hitBuffer.add(new HashMap<Long, CalorimeterHit>(0));
-        }
-    }
-        
-    /**
-     * Generates a list of clusters from the current hit buffer. The
-     * "present" event is taken to be the list of hits occurring at
-     * index <code>clusterWindow</code>, which is the middle of the
-     * buffer.
-     * @return Returns a <code>List</code> of <code>HPSEcalCluster
-     * </code> objects generated from the current event.
-     */
-    private List<Cluster> getClusters() {
-        // Generate a list for storing clusters.
-        List<Cluster> clusters = new ArrayList<Cluster>();
-        
-        // Get the list of hits at the current time in the event buffer.
-        Map<Long, CalorimeterHit> currentHits = hitBuffer.get(clusterWindow);
-        
-        // VERBOSE :: Print the cluster window.
-        if(verbose) {
-        	// Print the event header.
-	        System.out.printf("%n%nEvent:%n");
-	        
-	        // Calculate some constants.
-	        int window = (hitBuffer.size() - 1) / 2;
-	        int bufferNum = 0;
-	        
-	        // Print out all of the hits in the event buffer.
-	        for(Map<Long, CalorimeterHit> bufferMap : hitBuffer) {
-	            System.out.printf("Buffer %d:%n", hitBuffer.size() - bufferNum - window - 1);
-	            CalorimeterHit hit = null;
-	            
-	            for(Entry<Long, CalorimeterHit> entry : bufferMap.entrySet()) {
-	            	hit = entry.getValue();
-	            	System.out.printf("\t(%3d, %3d) --> %.4f (%.4f)%n", hit.getIdentifierFieldValue("ix"),
-	            			hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
-	            }
-	            
-	            bufferNum++;
-	        }
-	        
-	        // If there are not hits, indicate this.
-	        if(currentHits.isEmpty()) { System.out.println("\tNo hits this event!"); }
-        }
-        
-        // For a hit to be a cluster center, it must be a local maximum
-        // both with respect to its neighbors and itself both in the
-        // present time and at all times within the event buffer.
-        seedLoop:
-        for (Long currentID : currentHits.keySet()) {
-            // Get the actual hit object.
-            CalorimeterHit currentHit = currentHits.get(currentID);
-            
-            // VERBOSE :: Print the current cluster.
-            if(verbose) {
-	            System.out.printf("Cluster Check:%n");
-	        	System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
-	        			currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy());
-            }
-            
-            // Store the energy of the current hit.
-            double currentEnergy = currentHit.getCorrectedEnergy();
-            
-            // If the hit energy is lower than the minimum threshold,
-            // then we immediately reject this hit as a possible cluster.
-            if (currentEnergy < seedEnergyThreshold) {
-            	// VERBOSE :: Note the reason the potential seed was
-            	//            rejected.
-            	if(verbose) { System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", seedEnergyThreshold); }
-            	
-            	// Skip to the next potential seed.
-                continue seedLoop;
-            }
-            
-            // Store the crystals that are part of this potential cluster, 
-            // starting with the cluster seed candidate.
-            BaseCluster cluster = createBasicCluster();            
-            cluster.addHit(currentHit);
-            cluster.setPosition(currentHit.getDetectorElement().getGeometry().getPosition().v());
-            cluster.setNeedsPropertyCalculation(false);
-            
-            // Get the set of neighbors for this hit.
-            Set<Long> neighbors = neighborMap.get(currentHit.getCellID());
-            
-            // Sort through each event stored in the buffer.
-            int bufferIndex = 0;
-            for (Map<Long, CalorimeterHit> bufferHits : hitBuffer) {
-                // Get the hit energy at the current hit's position in
-                // the buffer, if it exists. Ignore the current seed candidate.
-                CalorimeterHit bufferHit = bufferHits.get(currentID);
-                if (bufferHit != null && bufferHit != currentHit) {
-                    double bufferHitEnergy = bufferHit.getRawEnergy();
-                    
-                    // Check to see if the hit at this point in the buffer
-                    // is larger than then original hit. If it is, we may
-                    // stop the comparison because this is not a cluster.
-                    if (bufferHitEnergy > currentEnergy) {
-                    	// VERBOSE :: Output the reason the potential
-                    	//            seed was rejected along with the
-                    	//            hit that caused it.
-                    	if(verbose) {
-	                    	System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.");
-	                    	System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", bufferHit.getIdentifierFieldValue("ix"),
-	                    			bufferHit.getIdentifierFieldValue("iy"), bufferHit.getCorrectedEnergy(), bufferHit.getRawEnergy());
-                    	}
-                    	
-                    	// Skip to the next potential seed.
-                        continue seedLoop;
-                    }
-                    
-                    // If the buffer hit is smaller, then add its energy
-                    // to the cluster total energy.
-                    else {
-                        if(limitClusterRange && bufferIndex <= clusterWindow + 1) { cluster.addHit(bufferHit); }
-                        else if(!limitClusterRange) { cluster.addHit(bufferHit); }
-                    }
-                }
-                
-                // We must also make sure that the original hit is
-                // larger than all of the neighboring hits at this
-                // point in the buffer as well.
-                for (Long neighborID : neighbors) {
-                    // Get the neighbor hit energy if it exists.
-                    CalorimeterHit neighborHit = bufferHits.get(neighborID);
-                    if (neighborHit != null) {
-                        double neighborHitEnergy = neighborHit.getRawEnergy();
-                        
-                        // Check to see if the neighbor hit at this point
-                        // in the buffer is larger than then original hit.
-                        // If it is, we may stop the comparison because this
-                        // is not a cluster.
-                        if (neighborHitEnergy > currentEnergy) {
-                        	// VERBOSE :: Output the reason the potential
-                        	//            seed was rejected along with the
-                        	//            hit that caused it.
-                        	if(verbose) {
-	                        	System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.%n");
-	                        	System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", neighborHit.getIdentifierFieldValue("ix"),
-	                        			neighborHit.getIdentifierFieldValue("iy"), neighborHit.getCorrectedEnergy(), neighborHit.getRawEnergy());
-                        	}
-                        	
-                        	// Skip to the next potential seed.
-                            continue seedLoop;
-                        }
-                        
-                        // If the buffer neighbor hit is smaller, then
-                        // add its energy to the cluster total energy.
-                        else {
-                            if(limitClusterRange && bufferIndex <= clusterWindow + 1) { cluster.addHit(neighborHit); }
-                            else if(!limitClusterRange) { cluster.addHit(neighborHit); }
-                        }
-                    }
-                }
-                
-                // Increment the buffer index.
-                bufferIndex++;
-            }
-            
-            // Add the cluster to the list of clusters.
-            clusters.add(cluster);
-            
-            // VERBOSE :: Output the clusters generated from this event.
-            if(verbose) {
-	            System.out.printf("Cluster added.%n");
-	            System.out.printf("\t(%3d, %3d) --> %.4f GeV --> %d hits%n", cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
-	            		cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"), cluster.getEnergy(), cluster.getCalorimeterHits().size());
-	            for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
-	            	System.out.printf("\t\tCLUSTER HIT :: (%3d, %3d) --> %.4f%n", hit.getIdentifierFieldValue("ix"),
-	            			hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
-	            }
-            }
-        }
-        
-        // Return the generated list of clusters.
-        return clusters;
-    }
-    
-    /**
-     * Places hits from the current event into the event hit buffer
-     * and processes the buffer to extract clusters. Clusters are then
-     * stored in the event object.
-     * @param event - The event to process.
+        super(new String[] { "seedEnergyThreshold", "clusterWindow" }, new double[] { 0.050, 2 });
+    }
+    
+    /**
+     * Processes the argument <code>CalorimeterHit</code> collection and
+     * forms a collection of <code>Cluster</code> objects according to
+     * the GTP clustering algorithm.
+     * @param event - The object containing event data.
+     * @param hitList - A list of <code>CalorimeterHit</code> objects
+     * from which clusters should be formed.
      */
     public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits) {
         // Store each hit in a set by its cell ID so that it may be
@@ -327,61 +171,93 @@
     }
     
     /**
+     * Indicates the type of cluster that is generated by this algorithm.
+     * @return Returns the type of cluster as a <code>ClusterType</code>
+     * object; specifically, returns <code>ClusterType.GTP</code>.
+     */
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.GTP;
+    }
+    
+    /**
+     * Sets the clustering algorithm parameters.
+     */
+    @Override
+    public void initialize() {
+        // Set cuts.
+        setSeedEnergyThreshold(getCuts().getValue("seedEnergyThreshold"));
+        setClusterWindow((int) getCuts().getValue("clusterWindow"));
+        
+        // Initiate the hit buffer.
+        hitBuffer = new LinkedList<Map<Long, CalorimeterHit>>();
+        
+        // Populate the event buffer with (2 * clusterWindow + 1)
+        // empty events. These empty events represent the fact that
+        // the first few events will not have any events in the past
+        // portion of the buffer.
+        int bufferSize = (2 * clusterWindow) + 1;
+        for (int i = 0; i < bufferSize; i++) {
+            hitBuffer.add(new HashMap<Long, CalorimeterHit>(0));
+        }
+    }
+    
+    /**
      * Sets the number of clock cycles before and after a given cycle
      * that will be used when checking whether a given hit is a local
      * maximum in both time and space. Note that a value of <code>N</code>
      * indicates that <code>N</code> clock cycles before and
      * <code>N</code> clock cycles after will be considered. Thusly, a
-     * total of <code>2N + 1</code> clock cycles will be used.
+     * total of <code>2N + 1</code> clock cycles will be used. This
+     * defines the size of the hit verification window. The inclusion
+     * window is defined as a function of this, as discussed in the
+     * method <code>setLimitClusterRange</code>.
      * @param clusterWindow - The number of additional clock cycles to
      * include in the clustering checks. A negative value will be treated
      * as zero.
      */
     void setClusterWindow(int clusterWindow) {
         // The cluster window of must always be at least zero.
-        if (clusterWindow < 0) {
-            this.clusterWindow = 0;
-        }
+        if (clusterWindow < 0) { this.clusterWindow = 0; }
         
         // If the cluster window is non-zero, then store it.
-        else {
-            this.clusterWindow = clusterWindow;
-        }
-    }
-    
-    /**
-     * Sets whether hits should be added to a cluster from the entire
-     * cluster window or just the "future" hits, plus one clock-cycle
-     * of "past" hits as a safety buffer to account for time uncertainty.
+        else { this.clusterWindow = clusterWindow; }
+    }
+    
+    /**
+     * Sets the behavior of the hit inclusion and verification temporal
+     * windows. If set to <code>true</code>, the hit inclusion window
+     * will be defined as one clock-cycle before the seed hit and the
+     * regular length of the verification window after the seed hit. If
+     * <code>false</code>, the inclusion window and the verification
+     * window are set to be identical.
      * @param limitClusterRange - <code>true</code> indicates that the
      * asymmetric clustering window should be used and <code>false</code>
      * that the symmetric window should be used.
      */
-    void setLimitClusterRange(boolean limitClusterRange) {
+    void setAsymmetricWindow(boolean limitClusterRange) {
         this.limitClusterRange = limitClusterRange;
     }
     
     /**
-     * Sets the minimum energy threshold below which hits will not be
-     * considered as cluster centers.
-     * @param seedEnergyThreshold - The minimum energy for a cluster center.
+     * Sets the minimum energy a hit must have before it will be
+     * considered for cluster formation.
+     * @param seedThreshold - The seed threshold in GeV.
      */
     void setSeedEnergyThreshold(double seedEnergyThreshold) {
         // A negative energy threshold is non-physical. All thresholds
         // be at least zero.
-        if (seedEnergyThreshold < 0.0) {
-            this.seedEnergyThreshold = 0.0;
-        } // If the energy threshold is valid, then use it.
-        else {
-            this.seedEnergyThreshold = seedEnergyThreshold;
-        }
-    }
-    
-    /**
-     * Sets whether diagnostic text should be written out or not.
-     * @param verbose - <code>true</code> indicates that diagnostic
-     * text will be written out and <code>false</code> that it will
-     * not.
+        if (seedEnergyThreshold < 0.0) { this.seedEnergyThreshold = 0.0; }
+        
+        // If the energy threshold is valid, then use it.
+        else { this.seedEnergyThreshold = seedEnergyThreshold; }
+    }
+    
+    /**
+     * Sets whether the clusterer should output diagnostic text or not.
+     * @param verbose - <code>true</code> indicates that the clusterer
+     * should output diagnostic text and <code>false</code> that it
+     * should not.
      */
     void setVerbose(boolean verbose) {
     	this.verbose = verbose;
@@ -398,13 +274,177 @@
     	writeHitCollection = state;
     }
     
-    /**
-     * Indicates the type of cluster that is generated by this algorithm.
-     * @return Returns the type of cluster as a <code>ClusterType</code>
-     * object, specifically, <code>ClusterType.GTP</code>.
-     */
-    @Override
-    public ClusterType getClusterType() {
-        return ClusterType.GTP;
-    }
+/**
+ * Generates a list of clusters from the current hit buffer. The
+ * "present" event is taken to be the list of hits occurring at
+ * index <code>clusterWindow</code>, which is the middle of the
+ * buffer.
+ * @return Returns a <code>List</code> of <code>HPSEcalCluster
+ * </code> objects generated from the current event.
+ */
+private List<Cluster> getClusters() {
+    // Generate a list for storing clusters.
+    List<Cluster> clusters = new ArrayList<Cluster>();
+    
+    // Get the list of hits at the current time in the event buffer.
+    Map<Long, CalorimeterHit> currentHits = hitBuffer.get(clusterWindow);
+    
+    // VERBOSE :: Print the cluster window.
+    if(verbose) {
+    	// Print the event header.
+        System.out.printf("%n%nEvent:%n");
+        
+        // Calculate some constants.
+        int window = (hitBuffer.size() - 1) / 2;
+        int bufferNum = 0;
+        
+        // Print out all of the hits in the event buffer.
+        for(Map<Long, CalorimeterHit> bufferMap : hitBuffer) {
+            System.out.printf("Buffer %d:%n", hitBuffer.size() - bufferNum - window - 1);
+            CalorimeterHit hit = null;
+            
+            for(Entry<Long, CalorimeterHit> entry : bufferMap.entrySet()) {
+            	hit = entry.getValue();
+            	System.out.printf("\t(%3d, %3d) --> %.4f (%.4f)%n", hit.getIdentifierFieldValue("ix"),
+            			hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+            }
+            
+            bufferNum++;
+        }
+        
+        // If there are not hits, indicate this.
+        if(currentHits.isEmpty()) { System.out.println("\tNo hits this event!"); }
+    }
+    
+    // For a hit to be a cluster center, it must be a local maximum
+    // both with respect to its neighbors and itself both in the
+    // present time and at all times within the event buffer.
+    seedLoop:
+    for (Long currentID : currentHits.keySet()) {
+        // Get the actual hit object.
+        CalorimeterHit currentHit = currentHits.get(currentID);
+        
+        // VERBOSE :: Print the current cluster.
+        if(verbose) {
+            System.out.printf("Cluster Check:%n");
+        	System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
+        			currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy());
+        }
+        
+        // Store the energy of the current hit.
+        double currentEnergy = currentHit.getCorrectedEnergy();
+        
+        // If the hit energy is lower than the minimum threshold,
+        // then we immediately reject this hit as a possible cluster.
+        if (currentEnergy < seedEnergyThreshold) {
+        	// VERBOSE :: Note the reason the potential seed was
+        	//            rejected.
+        	if(verbose) { System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", seedEnergyThreshold); }
+        	
+        	// Skip to the next potential seed.
+            continue seedLoop;
+        }
+        
+        // Store the crystals that are part of this potential cluster, 
+        // starting with the cluster seed candidate.
+        BaseCluster cluster = createBasicCluster();            
+        cluster.addHit(currentHit);
+        cluster.setPosition(currentHit.getDetectorElement().getGeometry().getPosition().v());
+        cluster.setNeedsPropertyCalculation(false);
+        
+        // Get the set of neighbors for this hit.
+        Set<Long> neighbors = neighborMap.get(currentHit.getCellID());
+        
+        // Sort through each event stored in the buffer.
+        int bufferIndex = 0;
+        for (Map<Long, CalorimeterHit> bufferHits : hitBuffer) {
+            // Get the hit energy at the current hit's position in
+            // the buffer, if it exists. Ignore the current seed candidate.
+            CalorimeterHit bufferHit = bufferHits.get(currentID);
+            if (bufferHit != null && bufferHit != currentHit) {
+                double bufferHitEnergy = bufferHit.getRawEnergy();
+                
+                // Check to see if the hit at this point in the buffer
+                // is larger than then original hit. If it is, we may
+                // stop the comparison because this is not a cluster.
+                if (bufferHitEnergy > currentEnergy) {
+                	// VERBOSE :: Output the reason the potential
+                	//            seed was rejected along with the
+                	//            hit that caused it.
+                	if(verbose) {
+                    	System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.");
+                    	System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", bufferHit.getIdentifierFieldValue("ix"),
+                    			bufferHit.getIdentifierFieldValue("iy"), bufferHit.getCorrectedEnergy(), bufferHit.getRawEnergy());
+                	}
+                	
+                	// Skip to the next potential seed.
+                    continue seedLoop;
+                }
+                
+                // If the buffer hit is smaller, then add its energy
+                // to the cluster total energy.
+                else {
+                    if(limitClusterRange && bufferIndex <= clusterWindow + 1) { cluster.addHit(bufferHit); }
+                    else if(!limitClusterRange) { cluster.addHit(bufferHit); }
+                }
+            }
+            
+            // We must also make sure that the original hit is
+            // larger than all of the neighboring hits at this
+            // point in the buffer as well.
+            for (Long neighborID : neighbors) {
+                // Get the neighbor hit energy if it exists.
+                CalorimeterHit neighborHit = bufferHits.get(neighborID);
+                if (neighborHit != null) {
+                    double neighborHitEnergy = neighborHit.getRawEnergy();
+                    
+                    // Check to see if the neighbor hit at this point
+                    // in the buffer is larger than then original hit.
+                    // If it is, we may stop the comparison because this
+                    // is not a cluster.
+                    if (neighborHitEnergy > currentEnergy) {
+                    	// VERBOSE :: Output the reason the potential
+                    	//            seed was rejected along with the
+                    	//            hit that caused it.
+                    	if(verbose) {
+                        	System.out.printf("\tREJECT :: Buffer hit surpasses hit energy.%n");
+                        	System.out.printf("\tBUFFER HIT :: (%3d, %3d) --> %.4f%n", neighborHit.getIdentifierFieldValue("ix"),
+                        			neighborHit.getIdentifierFieldValue("iy"), neighborHit.getCorrectedEnergy(), neighborHit.getRawEnergy());
+                    	}
+                    	
+                    	// Skip to the next potential seed.
+                        continue seedLoop;
+                    }
+                    
+                    // If the buffer neighbor hit is smaller, then
+                    // add its energy to the cluster total energy.
+                    else {
+                        if(limitClusterRange && bufferIndex <= clusterWindow + 1) { cluster.addHit(neighborHit); }
+                        else if(!limitClusterRange) { cluster.addHit(neighborHit); }
+                    }
+                }
+            }
+            
+            // Increment the buffer index.
+            bufferIndex++;
+        }
+        
+        // Add the cluster to the list of clusters.
+        clusters.add(cluster);
+        
+        // VERBOSE :: Output the clusters generated from this event.
+        if(verbose) {
+            System.out.printf("Cluster added.%n");
+            System.out.printf("\t(%3d, %3d) --> %.4f GeV --> %d hits%n", cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("ix"),
+            		cluster.getCalorimeterHits().get(0).getIdentifierFieldValue("iy"), cluster.getEnergy(), cluster.getCalorimeterHits().size());
+            for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
+            	System.out.printf("\t\tCLUSTER HIT :: (%3d, %3d) --> %.4f%n", hit.getIdentifierFieldValue("ix"),
+            			hit.getIdentifierFieldValue("iy"), hit.getCorrectedEnergy(), hit.getRawEnergy());
+            }
+        }
+    }
+    
+    // Return the generated list of clusters.
+    return clusters;
 }
+}

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterDriver.java	Thu Aug  6 17:19:42 2015
@@ -8,18 +8,49 @@
 import org.lcsim.event.EventHeader;
 
 /**
- * Class <code>GTPOnlineClusterDriver</code> allows parameters for the
- * readout variant of the GTP algorithm to be set.
+ * Class <code>GTPOnlineClusterDriver</code> is an implementation of
+ * the <code>ClusterDriver</code> class that defines employs the readout
+ * variant of the GTP hardware clustering algorithm. Specifics on the
+ * behavior of this algorithm can be found in its documentation.<br/>
+ * <br/>
+ * <code>GTPOnlineClusterDriver</code> allows for all of the variable
+ * settings used by the GTP algorithm to be defined. It also can be
+ * set to "verbose" mode, where it will output detailed information on
+ * each event and the cluster forming process. This is disabled by
+ * default, but can be enabled for debugging purposes.<br/>
+ * <br/>
+ * Lastly, <code>GTPOnlineClusterDriver</code> can be set to draw its
+ * settings from the <code>ConfigurationManager</code> static class,
+ * which reads and stores settings extracted directly from EvIO data.
+ * This option is disabled by default, and can be activated with the
+ * method <code>setUseDAQConfig</code>. When enabled, no clusters will
+ * be generated until <code>ConfigurationManager</code> reads a config
+ * event. This requires that the driver <code>DAQConfigDriver</code>
+ * be included in the driver chain.<br/>
+ * <br/>
+ * <code>GTPOnlineClusterDriver</code> is designed for use on hardware
+ * readout data or Monte Carlo formatted in this style. It can not be
+ * used for 2-ns beam bunch formatted data. <code>GTPClusterDriver</code>
+ * should be used for this data instead.
  * 
  * @author Kyle McCarty <[log in to unmask]>
+ * @see GTPOnlineClusterer
+ * @see ConfigurationManager
+ * @see org.hps.recon.ecal.daqconfig.DAQConfigDriver
  */
 public class GTPOnlineClusterDriver extends ClusterDriver {
+	/** An instance of the clustering algorithm object for producing
+	 * cluster objects. */
     private final GTPOnlineClusterer gtp;
+    /** Indicates whether the <code>ConfigurationManager</code> object
+     * should be used for clustering settings or not. */
     private boolean useDAQConfig = false;
     
     /**
-     * Instantiates a new clustering algorithm using the readout
-     * variant of the GTP clustering algorithm.
+     * Initializes a clustering driver. This implements the readout
+     * variant of the hardware GTP algorithm, as defined in the class
+     * <code>GTPClusterer</code>.
+     * @see GTPOnlineClusterer
      */
     public GTPOnlineClusterDriver() {
     	// Instantiate the clusterer.
@@ -48,6 +79,15 @@
         });
     }
     
+    /**
+     * Processes an an <code>EventHeader</code> object to generate
+     * clusters. Events will not be processed if <code>UseDAQConfig</code>
+     * is <code>true</code> unless the <code>ConfigurationManager</code>
+     * static class has received a DAQ configuration from the event
+     * stream and is initialized. Driver <code>DAQConfigDriver</code>
+     * must be in the driver chain for this to occur.
+     * @see org.hps.recon.ecal.daqconfig.DAQConfigDriver
+     */
     @Override
     public void process(EventHeader event) {
     	// Only process an event if either the DAQ configuration is not
@@ -58,7 +98,8 @@
     }
     
     /**
-     * Outputs the clusterer settings.
+     * Outputs the clusterer settings at driver initialization, assuming
+     * <code>setVerbose</code> is set to <code>true</code>.
      */
     @Override
     public void startOfData() {
@@ -68,7 +109,8 @@
     
     /**
      * Sets the minimum seed energy needed for a hit to be considered
-     * for forming a cluster.
+     * for forming a cluster. This is the seed energy lower bound trigger
+     * cut and is in units of GeV.
      * @param seedEnergyThreshold - The minimum cluster seed energy in
      * GeV.
      */
@@ -80,6 +122,9 @@
     /**
      * Sets the number of clock-cycles to include in the clustering
      * window before the seed hit. One clock-cycle is four nanoseconds.
+     * This defines the first half of the temporal hit inclusion window.
+     * The temporal hit verification window is defined as
+     * <code>max(windowAfter, windowBefore) * 2) + 1</code>.
      * @param cyclesBefore - The length of the clustering window before
      * the seed hit in clock cycles.
      */
@@ -90,8 +135,12 @@
     /**
      * Sets the number of clock-cycles to include in the clustering
      * window after the seed hit. One clock-cycle is four nanoseconds.
+     * This defines the latter half of the temporal hit inclusion window.
+     * The temporal hit verification window is defined as
+     * <code>max(windowAfter, windowBefore) * 2) + 1</code>.
      * @param cyclesAfter - The length of the clustering window after
      * the seed hit in clock cycles.
+     * @see GTPOnlineClusterer
      */
     public void setWindowAfter(int cyclesAfter) {
         gtp.setWindowAfter(cyclesAfter);
@@ -109,9 +158,14 @@
     
     /**
      * Sets whether GTP settings should be drawn from the EvIO data
-     * DAQ configuration or read from the steering file.
+     * DAQ configuration or read from the steering file. If this is
+     * set to <code>true</code>, no clusters will be generated until
+     * the static class <code>ConfigurationManager</code> has received
+     * a DAQ settings event and initialized. If this class is not part
+     * of the driver chain, then no clusters will ever be created.
      * @param state - <code>true</code> means that DAQ configuration
      * will be used and <code>false</code> that it will not.
+     * @see org.hps.recon.ecal.daqconfig.DAQConfigDriver
      */
     public void setUseDAQConfig(boolean state) {
     	useDAQConfig = state;

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPOnlineClusterer.java	Thu Aug  6 17:19:42 2015
@@ -16,74 +16,115 @@
 
 /**
  * Class <code>GTPOnlineClusterer</code> is an implementation of the
- * GTP clustering algorithm for EVIO readout data for use in either
- * online reconstruction/diagnostics or for general analysis of EVIO
- * readout data.<br/>
+ * abstract class <code>AbstractClusterer</code> that is responsible
+ * for producing clusters using the GTP algorithm employed by the
+ * hardware.<br/>
  * <br/>
- * The GTP algorithm searches the set of hits in a readout event and
- * compares them to select those that are a maximum in their 3x3 window
- * and across a period of time that can be set. Hits that are maxima
- * are declared "cluster seeds" and a cluster is created from them.
- * All hits within the clustering window of the seed time are then
- * added to the cluster and it is written to the event stream.<br/>
+ * The GTP algorithm produces clusters by finding hits representing
+ * local spatiotemporal energy maxima and forming a cluster from the
+ * hits within the aforementioned spatiotemporal window. A given hit
+ * is first checked to see if it exceeds some minimum energy threshold
+ * (referred to as the "seed energy threshold"). If this is the case,
+ * the algorithm looks at all hits that occurred in the same crystal as
+ * the comparison hit, or any crystal directly adjacent to it, within
+ * a programmable time window. If the hit exceeds all hits meeting these
+ * criteria in energy, the hit is considered the “seed hit” of a cluster.
+ * Then, all hits within the 3x3 spatial window which occur in the time
+ * window are added to a <code>Cluster</code> object.<br/>
  * <br/>
- * The GTP algorithm uses three time windows. THe verification window
- * is the time around the seed hit in which it is required to have more
- * energy than any other hits in the 3x3 spatial window surrounding it.
- * This is always symmetric. The other two windows combined define the
- * clustering window. The clustering window is composed of a window
- * before and a window after the seed time. These may be defined using
- * different values. The window after should be as long or longer than
- * the window before to make physical sense. The verification window is
- * then defined as the larger of the two constituents of the clustering
- * window. This is required for clustering to be consistent.
+ * Note that the algorithm employs two distinct temporal windows. The
+ * first is the “verification” window. This is used to check that the
+ * potential seed hit is a local maximum in energy, and is required to
+ * be symmetric (i.e. as long before the seed time as after it) to ensure
+ * consistency. The second temporal window is the “inclusion” window,
+ * which determines which hits are included in the cluster. The inclusion
+ * window can be asymmetric, but can not exceed the verification window
+ * in length. As an example, one could choose a 12 ns verification window,
+ * meaning that the algorithm would 12 ns before and after the seed hit
+ * to check that it has the highest energy, but use a 4 ns/12 ns inclusion
+ * window, meaning that the algorithm would only include hits in 3x3
+ * spatial window up to 4 ns before and up to 12 ns after the seed hit
+ * in the cluster. Due to the way the hardware processes hits, the higher
+ * energy parts of a cluster always occur first in time, so it is not
+ * necessarily desirable to include hits significantly before the seed.
+ * It is however, necessary to verify a hit’s status as a maximum across
+ * the full time window to ensure consistency in cluster formation.
+ * <code>GTPOnlineClusterer</code> automatically selects the larger of
+ * the two inclusion window parts as the verification window length.<br/>
+ * <br/>
+ * <code>GTPOnlineClusterer</code> requires as input a collection of
+ * <code>CalorimeterHit</code> objects representing the event hits. It
+ * will then produce a collection of <code>Cluster</code> objects
+ * representing the GTP algorithm output. It also produces a series of
+ * distribution plots under the “GTP(O) Cluster Plots” header. It is
+ * designed to be run on readout events, either from the hardware or
+ * Monte Carlo that has been processed through the readout simulation.
+ * If the input data is formatted into constant-time beam bunches, the
+ * sister class <code>GTPClusterer</code> should be used instead.
  * 
  * @author Kyle McCarty <[log in to unmask]>
+ * @see Cluster
+ * @see CalorimeterHit
+ * @see AbstractClusterer
+ * @see GTPClusterer
  */
 public class GTPOnlineClusterer extends AbstractClusterer {
-    
-    // The size of the temporal window in nanoseconds. By default,
-    // this is 1 clock-cycle before and 3 clock-cycles after.
+	/**
+	 * The length of the temporal window for inclusing clusters that
+	 * occur before the seed hit.
+	 */
     private double timeBefore = 4;
+    
+    /**
+     * The length of the temporal window for including clusters that
+     * occur after the seed hit.
+     */
     private double timeAfter = 12;
+    
+    /**
+     * The length of the temporal window for verifying that a hit is
+     * a local maximum in energy. This length represents both halves
+     * of the verification window, so the full length would be defined
+     * by <code>timeWindow * 2 + 4</code> ns.
+     */
     private double timeWindow = 12;
-
-    // Cluster formation energy thresholds. Currently, the hardware
-    // only supports a lower bound seed energy. Units are in GeV.
+    
+    /**
+     * The minimum energy a hit must have to be considered for cluster
+     * seed formation. Units are in GeV.
+     */
     private double seedThreshold = 0.050;
     
-    // Internal variables.
+    /**
+     * Controls whether or not verbose diagnostic information is output.
+     */
     private boolean verbose = false;
     
     // Diagnostic plots.
     private AIDA aida = AIDA.defaultInstance();
-    IHistogram1D hitEnergy = aida.histogram1D("GTP(O) Cluster Plots :: Hit Energy Distribution", 256, -1.0, 2.2);
-    IHistogram1D clusterSeedEnergy = aida.histogram1D("GTP(O) Cluster Plots :: Cluster Seed Energy Distribution", 176, 0.0, 2.2);
-    IHistogram1D clusterHitCount = aida.histogram1D("GTP(O) Cluster Plots :: Cluster Hit Count Distribution", 9, 1, 10);
-    IHistogram1D clusterTotalEnergy = aida.histogram1D("GTP(O) Cluster Plots :: Cluster Total Energy Distribution", 176, 0.0, 2.2);
-    IHistogram2D hitDistribution = aida.histogram2D("GTP(O) Cluster Plots :: Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
-    IHistogram2D clusterDistribution = aida.histogram2D("GTP(O) Cluster Plots :: Cluster Seed Distribution", 46, -23, 23, 11, -5.5, 5.5);
-    IHistogram1D energyDistribution = aida.histogram1D("GTP(O) Cluster Plots :: Percent Negative Energy Distribution", 100, 0.0, 1.0);
+    private IHistogram1D hitEnergy = aida.histogram1D("GTP(O) Cluster Plot/Hit Energy Distribution", 256, -1.0, 2.2);
+    private IHistogram1D clusterSeedEnergy = aida.histogram1D("GTP(O) Cluster Plots/Cluster Seed Energy Distribution", 176, 0.0, 2.2);
+    private IHistogram1D clusterHitCount = aida.histogram1D("GTP(O) Cluster Plots/Cluster Hit Count Distribution", 9, 1, 10);
+    private IHistogram1D clusterTotalEnergy = aida.histogram1D("GTP(O) Cluster Plots/Cluster Total Energy Distribution", 176, 0.0, 2.2);
+    private IHistogram2D hitDistribution = aida.histogram2D("GTP(O) Cluster Plots/Hit Distribution", 46, -23, 23, 11, -5.5, 5.5);
+    private IHistogram2D clusterDistribution = aida.histogram2D("GTP(O) Cluster Plots/Cluster Seed Distribution", 46, -23, 23, 11, -5.5, 5.5);
+    private IHistogram1D energyDistribution = aida.histogram1D("GTP(O) Cluster Plots/Percent Negative Energy Distribution", 100, 0.0, 1.0);
     
     /**
      * Instantiates a new instance of a readout GTP clustering algorithm.
+     * This will use the default seed energy threshold of 50 MeV.
      */
     GTPOnlineClusterer() {
         super(new String[] { "seedThreshold" }, new double[] { 0.050 });
     }
     
     /**
-     * Gets any relevant cuts from the superclass and sets the local
-     * clusterer variables accordingly. 
-     */
-    public void initialize() {
-        seedThreshold = getCuts().getValue("seedThreshold");
-    }
-    
-    /**
-     * Reads in hits and processes them into clusters as per the GTP
-     * clustering algorithm implemented in the hardware.
+     * Processes the argument <code>CalorimeterHit</code> collection and
+     * forms a collection of <code>Cluster</code> objects according to
+     * the GTP clustering algorithm.
      * @param event - The object containing event data.
+     * @param hitList - A list of <code>CalorimeterHit</code> objects
+     * from which clusters should be formed.
      */
     @Override
     public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hitList) {
@@ -95,6 +136,7 @@
     		System.out.println("=== GTP Readout Clusterer ============================================");
     		System.out.println("======================================================================");
     		
+    		// Sort the hits by x-index and then by y-index.
         	Collections.sort(hitList, new Comparator<CalorimeterHit>() {
 				@Override
 				public int compare(CalorimeterHit firstHit, CalorimeterHit secondHit) {
@@ -106,6 +148,8 @@
 					}
 				}
         	});
+        	
+        	// Print the hit collection.
         	System.out.println("Event Hit Collection:");
             for(CalorimeterHit hit : hitList) {
                 int ix = hit.getIdentifierFieldValue("ix");
@@ -155,7 +199,7 @@
                 protoCluster.setPosition(seed.getDetectorElement().getGeometry().getPosition().v());
                 protoCluster.setNeedsPropertyCalculation(false);
                 
-                // Iterate over the other hits and if the are within
+                // Iterate over the other hits and if they are within
                 // the clustering spatiotemporal window, compare their
                 // energies.
                 hitLoop:
@@ -217,16 +261,18 @@
         
         // VERBOSE :: Print out all the clusters in the event.
         if(verbose) {
+        	// Print the clusters.
         	System.out.println("Event Cluster Collection:");
             for(Cluster cluster : clusterList) {
+            	// Output basic cluster positional and energy data.
                 CalorimeterHit seedHit = cluster.getCalorimeterHits().get(0);
                 int ix = seedHit.getIdentifierFieldValue("ix");
                 int iy = seedHit.getIdentifierFieldValue("iy");
                 double energy = cluster.getEnergy();
                 double time = seedHit.getTime();
-                
                 System.out.printf("\tCluster --> %6.3f GeV at (%3d, %3d) and at t = %.2f%n", energy, ix, iy, time);
                 
+                // Output the cluster hit collection.
                 for(CalorimeterHit hit : cluster.getCalorimeterHits()) {
                     int hix = hit.getIdentifierFieldValue("ix");
                     int hiy = hit.getIdentifierFieldValue("iy");
@@ -241,16 +287,125 @@
         // VERBOSE :: Print a new line.
         if(verbose) { System.out.println(); }
         
+        // Return the list of clusters.
         return clusterList;
     }
     
     /**
-     * Checks whether the hit <code>hit</code> keeps the hit <code>seed
-     * </code> from meeting the criteria for being a seed hit. Note that
-     * this does not check to see if the two hits are within the valid
-     * spatiotemporal window of one another.
+     * Gets the type of cluster produced by this clusterer.
+     * @return Returns the cluster type as a <code>ClusterType</code>
+     * enumerable.
+     */
+    @Override
+    public ClusterType getClusterType() {
+        return ClusterType.GTP_ONLINE;
+    }
+    
+    /**
+     * Gets the seed energy lower bound threshold in units of GeV.
+     * @return Returns the threshold as a <code>double</code>.
+     */
+    public double getSeedLowThreshold() { return seedThreshold; }
+    
+    /**
+     * Gets the number of nanoseconds before the seed hit time that
+     * the clusterer will look to include hits when a cluster is formed.
+     * @return Returns the time window as a <code>double</code>.
+     */
+    public double getWindowBefore() { return timeBefore; }
+    
+    /**
+     * Gets the number of nanoseconds after the seed hit time that
+     * the clusterer will look to include hits when a cluster is formed.
+     * @return Returns the time window as a <code>double</code>.
+     */
+    public double getWindowAfter() { return timeAfter; }
+    
+    /**
+     * Sets up the clusterer parameters so that it is ready to be used.
+     * This should be run before the cluster formation.
+     */
+    @Override
+    public void initialize() {
+        seedThreshold = getCuts().getValue("seedThreshold");
+    }
+    
+    /**
+     * Returns whether the clusterer will output verbose diagnostic
+     * information.
+     * @return Returns <code>true</code> if the clusterer will output
+     * diagnostic information and <code>false</code> otherwise.
+     */
+    boolean isVerbose() { return verbose; }
+    
+    /**
+     * Sets the minimum energy a hit must have before it will be
+     * considered for cluster formation.
+     * @param seedThreshold - The seed threshold in GeV.
+     */
+    void setSeedLowThreshold(double seedThreshold) {
+        this.seedThreshold = seedThreshold;
+    }
+    
+    /**
+     * Sets whether the clusterer should output diagnostic text or not.
+     * @param verbose - <code>true</code> indicates that the clusterer
+     * should output diagnostic text and <code>false</code> that it
+     * should not.
+     */
+    void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+    
+    /**
+     * Sets the number of clock-cycles to include in the clustering
+     * window before the seed hit. One clock-cycle is four nanoseconds.
+     * Note that the larger of this time and the time defined in method
+     * <code>setWindowAfter</code> will be the verification window size.
+     * @param cyclesBefore - The length of the clustering window before
+     * the seed hit in clock cycles.
+     */
+    void setWindowBefore(int cyclesBefore) {
+    	// The cluster window can not be negative.
+    	if(cyclesBefore < 0) { cyclesBefore = 0; }
+    	
+    	// Convert the window to nanoseconds and set the two time
+    	// windows appropriately.
+        timeBefore = cyclesBefore * 4;
+        timeWindow = Math.max(timeBefore, timeAfter);
+    }
+    
+    /**
+     * Sets the number of clock-cycles to include in the clustering
+     * window after the seed hit. One clock-cycle is four nanoseconds.
+     * Note that the larger of this time and the time defined in method
+     * <code>setWindowBefore</code> will be the verification window size.
+     * @param cyclesAfter - The length of the clustering window after
+     * the seed hit in clock cycles.
+     */
+    void setWindowAfter(int cyclesAfter) {
+    	// The cluster window can not be negative.
+    	if(cyclesAfter < 0) { cyclesAfter = 0; }
+    	
+    	// Convert the window to nanoseconds and set the two time
+    	// windows appropriately.
+        timeAfter = cyclesAfter * 4;
+        timeWindow = Math.max(timeBefore, timeAfter);
+    }
+    
+    /**
+     * Compares the argument <code>CalorimeterHit</code> <code>hit</code>
+     * against the <code>CalorimeterHit</code> <code>seed</code> to see
+     * if <code>seed</code> meets the criteria for a seed hit given the
+     * presence of <code>hit</code>, which is assumed to be located in
+     * the appropriate spatiotemporal window.<br/>
+     * <br/>
+     * Note that it is the responsibility of the calling method to
+     * ascertain whether the two <code>CalorimeterHit</code> objects
+     * are actually within the proper spatial and temporal windows of
+     * one another.
      * @param seed - The potential seed hit.
-     * @param hit - The hit to compare with the seed.
+     * @param hit - The hit with which to compare the seed.
      * @return Returns <code>true</code> if either the two hits are the
      * same hit or if the hit does not invalidate the potential seed.
      * Returns <code>false</code> otherwise.
@@ -303,10 +458,12 @@
     }
     
     /**
-     * Checks whether the hit <code>hit</code> falls within the spatial
-     * window of the hit <code>Seed</code>. This is defined as within
-     * 1 index of the seed's x-index and similarly for the seed's
-     * y-index. 
+     * Checks whether the <code>CalorimeterHit</code> <code>hit</code>
+     * is within the 3x3 spatial window of <code>CalorimeterHit</code>
+     * <code>seed</code>. This is defined as <code>seed</code> having
+     * an x-index within +/-1 of the x-index of <code>hit</code> and
+     * similarly for the y-index. Allowance is made for the fact that
+     * the x-indices go from -1 to 1 and skip zero.
      * @param seed - The seed hit.
      * @param hit - The comparison hit.
      * @return Returns <code>true</code> if either both hits are the
@@ -353,9 +510,9 @@
     }
     
     /**
-     * Checks whether the hit <code>hit</code> is within the temporal
-     * window of the hit <code>seed</code> for the purpose of seed
-     * verification.
+     * Checks whether <code>CalorimeterHit</code> <code>hit</code> is
+     * within the verification temporal window for potential seed hit
+     * <code>seed</code>.
      * @param seed - The seed hit.
      * @param hit - The comparison hit.
      * @return Returns <code>true</code> if the comparison hit is within
@@ -373,9 +530,9 @@
     }
     
     /**
-     * Checks whether the hit <code>hit</code> is within the temporal
-     * window of the hit <code>seed</code> for the purpose of adding
-     * a hit to a cluster.
+     * Checks whether <code>CalorimeterHit</code> <code>hit</code> is
+     * within the inclusion temporal window for potential seed hit
+     * <code>seed</code>.
      * @param seed - The seed hit.
      * @param hit - The comparison hit.
      * @return Returns <code>true</code> if the comparison hit is within
@@ -397,87 +554,11 @@
             return (hitTime - seedTime) <= timeAfter;
         }
         
-        // If the times are the same, the are within the window.
+        // If the times are the same, they are within the window.
         if(hitTime == seedTime) { return true; }
         
         // Otherwise, one or both times is undefined and should not be
         // treated as within time.
         else { return false; }
     }
-    
-    /**
-     * Gets the seed energy lower bound threshold in units of GeV.
-     * @return Returns the seed energy lower bound threshold.
-     */
-    public double getSeedLowThreshold() { return seedThreshold; }
-    
-    /**
-     * Gets the number of nanoseconds before the seed hit time the
-     * clusterer will look to verify the seed hit.
-     * @return Returns the size of the time window before the seed
-     * hit time.
-     */
-    public double getWindowBefore() { return timeBefore; }
-    
-    /**
-     * Gets the number of nanoseconds after the seed hit time the
-     * clusterer will look to verify the seed hit.
-     * @return Returns the size of the time window after the seed
-     * hit time.
-     */
-    public double getWindowAfter() { return timeAfter; }
-    
-    /**
-     * Returns whether the clusterer will output verbose diagnostic
-     * information.
-     * @return Returns <code>true</code> if the clusterer will output
-     * diagnostic information and <code>false</code> otherwise.
-     */
-    public boolean isVerbose() { return verbose; }
-    
-    /**
-     * Sets the minimum energy a hit must have before it will be
-     * considered for cluster formation.
-     * @param seedThreshold - The seed threshold in GeV.
-     */
-    public void setSeedLowThreshold(double seedThreshold) {
-        this.seedThreshold = seedThreshold;
-    }
-    
-    /**
-     * Sets the number of clock-cycles to include in the clustering
-     * window before the seed hit. One clock-cycle is four nanoseconds.
-     * @param cyclesBefore - The length of the clustering window before
-     * the seed hit in clock cycles.
-     */
-    public void setWindowBefore(int cyclesBefore) {
-        timeBefore = cyclesBefore * 4;
-        timeWindow = Math.max(timeBefore, timeAfter);
-    }
-    
-    /**
-     * Sets the number of clock-cycles to include in the clustering
-     * window after the seed hit. One clock-cycle is four nanoseconds.
-     * @param cyclesAfter - The length of the clustering window after
-     * the seed hit in clock cycles.
-     */
-    public void setWindowAfter(int cyclesAfter) {
-        timeAfter = cyclesAfter * 4;
-        timeWindow = Math.max(timeBefore, timeAfter);
-    }
-    
-    /**
-     * Sets whether the clusterer should output diagnostic text or not.
-     * @param verbose - <code>true</code> indicates that the clusterer
-     * should output diagnostic text and <code>false</code> that it
-     * should not.
-     */
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-    
-    @Override
-    public ClusterType getClusterType() {
-        return ClusterType.GTP_ONLINE;
-    }
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/ConfigurationManager.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/ConfigurationManager.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/ConfigurationManager.java	Thu Aug  6 17:19:42 2015
@@ -10,7 +10,7 @@
  * the DAQ configuration that can be parsed from EVIO files. It works
  * in conjunction with the <code>DAQConfigDriver</code>, which obtains
  * the configuration parser object when available and passes it to this
- * manager, and <code>TriggerConfig</code>, which parses the EVIO data.
+ * manager, and <code>EvioDAQParser</code>, which parses the EVIO data.
  * 
  * @author Kyle McCarty <[log in to unmask]>
  * @see DAQConfigDriver

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/DAQConfigDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/DAQConfigDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/DAQConfigDriver.java	Thu Aug  6 17:19:42 2015
@@ -5,8 +5,25 @@
 import org.lcsim.event.EventHeader;
 import org.lcsim.util.Driver;
 
+/**
+ * Class <code>DAQConfigDriver</code> is responsible for checking events
+ * for DAQ configuration settings, and then passing them to the associated
+ * class <code>ConfigurationManager</code> so that they can be accessed
+ * by other classes.<br/>
+ * <br/>
+ * This driver must be included in the driver chain if any other drivers
+ * in the chain rely on <code>ConfigurationManager</code>, as it can
+ * not be initialized otherwise.
+ * 
+ * @author Kyle McCarty
+ * @see ConfigurationManager
+ */
 public class DAQConfigDriver extends Driver {
-    
+    /**
+     * Checks an event for the DAQ configuration banks and passes them
+     * to the <code>ConfigurationManager</code>.
+     * @param - The event to check.
+     */
     @Override
     public void process(EventHeader event) {
         // Check if a trigger configuration bank exists.
@@ -21,5 +38,4 @@
             ConfigurationManager.updateConfiguration(daqConfig);
         }
     }
-    
 }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/EvioDAQParser.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/EvioDAQParser.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/daqconfig/EvioDAQParser.java	Thu Aug  6 17:19:42 2015
@@ -12,6 +12,18 @@
 import org.hps.conditions.ecal.EcalChannel;
 import org.hps.conditions.ecal.EcalConditions;
 
+/**
+ * Class <code>EvioDAQParser</code> takes DAQ configuration banks from
+ * EvIO data and extracts the configuration parameters from them. These
+ * are then stored within package-accessible variables within the class.
+ * <br/><br/>
+ * Note that this class should not be used directly to acquire DAQ
+ * configuration data. It is intended to be used internally by the EvIO
+ * parser and the class <code>ConfigurationManager</code>. The latter
+ * should be used for accessing this information for any other classes.
+ * 
+ * @author Nathan Baltzell <[log in to unmask]>
+ */
 public class EvioDAQParser {
     /*
      * Read/Parse/Save the DAQ trigger configuration settings.
@@ -22,135 +34,271 @@
      * 
      * GTP settings and Prescale factors will need to be added to this class when added to EVIO.
      * 
-     * TODO: Error in EVIO format for Crate 39 for 2014 data requires another JEVIO workaround (realized Feb 16).
+     * TODO: Error in EVIO format for Crate 39 for 2014 data requires another JEVIO workaround (realized Feb. 16).
      *       ** This was fixed in EVIO for data after run 4044.
      * 
      * TODO: Manually put in GTP settings based on run number for 2014 data.
      * TODO: Manually deal with change in format of SSP_HPS_SINGLES_NMIN (at 3312(?)).
      * 
-     * TODO: Restructure, clean up..
-     *  
-     *  @author <[log in to unmask]>
-     */
-    public int nBanks = 0;
+     * TODO: Restructure, clean up...
+     */
+	/** The EvIO bank identification tag for DAQ configuration banks. */
     public static final int BANK_TAG = 0xE10E;
     
-    // need to know these in order to interpret DAQ strings:
+    // Stores the hardware codes for each trigger type.
     private static final int[] singlesIOsrc = { 20, 21 };
     private static final int[] pairsIOsrc = { 22, 23 };
     
     // Dump everything read from the DAQ Configuration Bank, minimal interpretation:
-    Map<String,List<String>> configMap = new HashMap<String,List<String>>();
-    
-    // link ECAL FADC channel settings to EcalChannels:
-    Map<EcalChannel,Float> GAIN = new HashMap<EcalChannel,Float>();
-    Map<EcalChannel,Float> PEDESTAL = new HashMap<EcalChannel,Float>();
-    Map<EcalChannel,Integer> THRESHOLD = new HashMap<EcalChannel,Integer>();
-    
-    // private boolean debug = true;
+    private Map<String, List<String>> configMap = new HashMap<String, List<String>>();
+    
+    // Class parameters.
+    private int nBanks = 0;
     private boolean debug = false;
     
     // FADC Config:
+    /** The length of time after a pulse-crossing event that the pulse
+     * should be integrated. Uses units of clock-cycles. */
     int fadcNSA    = 0;
+    /** The length of time before a pulse-crossing event that the pulse
+     * should be integrated. Uses units of clock-cycles. */
     int fadcNSB    = 0;
+    /** The maximum number of pulses that will be extracted from a single
+     * channel within  a readout window. */
     int fadcNPEAK  = 0;
+    /** The pulse-processing mode used by the FADC. This should be 1,
+     * 3, or 7. */
     int fadcMODE   = 0;
+    /** The size of readout window in nanoseconds. */
     int fadcWIDTH  = 0;
+    /** The time-offset of the readout window in ns. */
     int fadcOFFSET = 0;
+    /** Map of <code>EcalChannel</code> to the gain for that channel.
+     * Uses units of ADC / MeV for the mapped value. */
+    Map<EcalChannel, Float> GAIN = new HashMap<EcalChannel, Float>();
+    /** Map of <code>EcalChannel</code> to the pedestal for that channel.
+     * Uses units of ADC for the mapped value. */
+    Map<EcalChannel, Float> PEDESTAL = new HashMap<EcalChannel, Float>();
+    /** Map of <code>EcalChannel</code> to the threshold for that channel.
+     * Uses units of ADC for the mapped value. */
+    Map<EcalChannel, Integer> THRESHOLD = new HashMap<EcalChannel, Integer>();
     
     // GTP Clustering Cut Values:
+    /** The seed energy lower bound cut used by the clusterer. Value is
+     * in units of MeV. */
     int gtpMinSeedEnergy  = 0;
+    /** The length of the clustering verification/inclusion window before
+     * the seed hit. Uses units of clock-cycles. */
     int gtpWindowBefore = 0;
+    /** The length of the clustering verification/inclusion window after
+     * the seed hit. Uses units of clock-cycles. */
     int gtpWindowAfter = 0;
     
     // Triggers Enabled:
+    /** Indicates whether the singles triggers are enabled or not. Uses
+     * the format <code>{ Singles0_Enabled, Singles1_Enabled }</code>. */
     boolean[] singlesEn = { false, false };
+    /** Indicates whether the pair triggers are enabled or not. Uses
+     * the format <code>{ Pair0_Enabled, Pair1_Enabled }</code>. */
     boolean[] pairsEn   = { false, false };
     
     // Singles Cuts Enabled:
+    /** Indicates whether the singles trigger cluster hit count cuts
+     * are enabled or not. Uses the format
+     * <code>{ Singles0_Cut_Enabled, Singles1_Cut_Enabled }</code>. */
     boolean[] singlesNhitsEn     = { false, false };
+    /** Indicates whether the singles trigger cluster total energy lower
+     * bound cuts are enabled or not. Uses the format
+     * <code>{ Singles0_Cut_Enabled, Singles1_Cut_Enabled }</code>. */
     boolean[] singlesEnergyMinEn = { false, false };
+    /** Indicates whether the singles trigger cluster total energy upper
+     * bound cuts are enabled or not. Uses the format
+     * <code>{ Singles0_Cut_Enabled, Singles1_Cut_Enabled }</code>. */
     boolean[] singlesEnergyMaxEn = { false, false };
     
     // Pairs Cuts Enabled:
+    /** Indicates whether the pair trigger pair energy sum cuts are
+     * enabled or not. Uses the format
+     * <code>{ Pair0_Cut_Enabled, Pair1_Cut_Enabled }</code>. */
     boolean[] pairsEnergySumMaxMinEn = { false, false };
+    /** Indicates whether the pair trigger pair energy difference cuts
+     * are enabled or not. Uses the format
+     * <code>{ Pair0_Cut_Enabled, Pair1_Cut_Enabled }</code>. */
     boolean[] pairsEnergyDiffEn      = { false, false };
+    /** Indicates whether the pair trigger pair coplanarity cuts are
+     * enabled or not. Uses the format
+     * <code>{ Pair0_Cut_Enabled, Pair1_Cut_Enabled }</code>. */
     boolean[] pairsCoplanarityEn     = { false, false };
+    /** Indicates whether the pair trigger pair energy slope cuts are
+     * enabled or not. Uses the format
+     * <code>{ Pair0_Cut_Enabled, Pair1_Cut_Enabled }</code>. */
     boolean[] pairsEnergyDistEn      = { false, false };
     
     // Singles Cut Values:
+    /** Specifies the value of the singles trigger cluster hit count
+     * cuts. Use the format, in units of hits,
+     * <code>{ Singles0_Cut_Value, Singles1_Cut_Value }</code>. */
     int[] singlesNhits     = { 0, 0 };
+    /** Specifies the value of the singles trigger cluster total energy
+     * lower bound cuts. Use the format, in units of MeV,
+     * <code>{ Singles0_Cut_Value, Singles1_Cut_Value }</code>. */
     int[] singlesEnergyMin = { 0, 0 };
+    /** Specifies the value of the singles trigger cluster total energy
+     * upper bound cuts. Use the format, in units of MeV,
+     * <code>{ Singles0_Cut_Value, Singles1_Cut_Value }</code>. */
     int[] singlesEnergyMax = { 0, 0 };
     
     // Pairs Cut Values:
+    /** Specifies the value of the pair trigger cluster hit count cuts.
+     * Use the format, in units of hits,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsNhitsMin       = { 0, 0 };
+    /** Specifies the value of the pair trigger cluster total energy
+     * lower bound cuts. Use the format, in units of MeV,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsEnergyMin      = { 0, 0 };
+    /** Specifies the value of the pair trigger cluster total energy
+     * upper bound cuts. Use the format, in units of MeV,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsEnergyMax      = { 0, 0 };
+    /** Specifies the value of the pair trigger pair energy sum upper
+     * bound cuts. Use the format, in units of MeV,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsEnergySumMin   = { 0, 0 };
+    /** Specifies the value of the pair trigger pair energy sum lower
+     * bound cuts. Use the format, in units of MeV,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsEnergySumMax   = { 0, 0 };
+    /** Specifies the value of the pair trigger pair energy difference
+     * cuts. Use the format, in units of MeV,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsEnergyDiffMax  = { 0, 0 };
+    /** Specifies the value of the pair trigger pair coplanarity cuts.
+     * Use the format, in units of degrees,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsCoplanarityMax = { 0, 0 };
+    /** Specifies the value of the pair trigger pair time coincidence
+     * cuts. Use the format, in units of nanoseconds,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsTimeDiffMax    = { 0, 0 };
+    /** Specifies the value of the pair trigger pair energy slope cuts.
+     * Use the format, in units of MeV,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     int[] pairsEnergyDistMin  = { 0, 0 };
     
     // Pairs Cut Parameters:
+    /** Specifies the value of the pair trigger pair energy slope cuts'
+     * parameter F. Use the format, in units of MeV / mm,
+     * <code>{ Pair0_Cut_Value, Pair1_Cut_Value }</code>. */
     float[] pairsEnergyDistSlope = { 0, 0 };
     
-    // Have to remember the previous slot line in order to interpret the data:
+    // Tracks the last FADC slot seen. This is needed for parsing FADC
+    // threshold, pedestal, and gain information.
     private int thisFadcSlot = 0;
     
     // Cache local set of EcalChannels:
     private EcalConditions ecalConditions = null;
     private List<EcalChannel> channels = new ArrayList<EcalChannel>();
     
+    /**
+     * Instantiates the <code>EvioDAQParser</code>.
+     */
     public EvioDAQParser() {
+    	// Create a map to map crystals to their database channel object.
         ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions();
         for (int ii = 0; ii < 442; ii++) {
-            channels.add(findChannel(ii+1));
+            channels.add(findChannel(ii + 1));
         } 
     }
     
-    public void parse(int crate, int runNumber, String[] dump) {
+    /**
+     * Parses a set of configuration tables to obtain DAQ configuration
+     * parameters.
+     * @param crate - The crate associated with the configuration tables.
+     * @param runNumber - The run number for the current data set.
+     * @param configurationTables - Tables containing DAQ configuration
+     * parameters.
+     */
+    public void parse(int crate, int runNumber, String[] configurationTables) {
+    	// Track the number of banks that have been parsed. If the
+    	// parameter values have not been populated after a certain
+    	// number of banks, there is missing information.
         nBanks++;
-        loadConfigMap(crate,dump); 
-        if (debug) printMap();
+        
+        // Create a map that maps an identifier for each configuration
+        // parameter (its parameter key) to any values associated
+        // with it (its parameter values).
+        loadConfigMap(crate, configurationTables);
+        
+        // If debugging text is enabled, print the map to the terminal.
+        if(debug) { printMap(); }
+        
+        // If this run is known to be missing configuration values,
+        // handle the missing values.
         fixConfigMap2014Run(runNumber);
+        
+        // Parse the previously generated configuration map and extract
+        // the DAQ configuration from it.
         parseConfigMap();
         
+        // If the expected number of banks have been parsed and debugging
+        // text is enabled, print out all of the parsed variables.
         if(nBanks > 2 && debug) { printVars(); }
     }
     
-    /*
-     * The first parsing routine.  Just dumps the config strings
-     * into a map whose keys are the first column in the config file.
-     * Also treats some special cases.
-     */
-    private void loadConfigMap(int crate, String[] dump) {
-        for(String dump1 : dump) {
-            for(String line : dump1.trim().split("\n")) {
+    /**
+     * Converts the textual configuration information into a map, where
+     * the first column value becomes the map entry key and the remainder
+     * becomes the map entry value.
+     * @param crate - The calorimeter crate associated with the textual
+     * configuration data.
+     * @param configTables - An array of textual configuration tables that
+     * contain the DAQ configuration parameters.
+     */
+    private void loadConfigMap(int crate, String[] configTables) {
+    	// Iterate over each configuration table.
+        for(String configTable : configTables) {
+        	// Split each table into rows and iterate over the rows.
+        	rowLoop:
+            for(String line : configTable.trim().split("\n")) {
+                // Split the first column from the row.
+                String[] cols = line.trim().split(" +", 2);
                 
-                String[] cols = line.trim().split(" +", 2);
-                if(cols.length < 2) continue;
+                // If there are fewer than two segments after the split,
+                // then this is not a valid parameter entry.
+                if(cols.length < 2) continue rowLoop;
                 
+                // The row name is the value of the first column. The
+                // rest are typically values.
                 String key = cols[0];
-                List<String> vals = new ArrayList<String>
-                    (Arrays.asList(cols[1].trim().split(" +")));
+                List<String> vals = new ArrayList<String>(Arrays.asList(cols[1].trim().split(" +")));
                 
+                // If no values are present, this is not a valid entry.
                 if (vals.size() < 1) {
-                    continue;
+                    continue rowLoop;
                 }
-               
-                // SPECIAL CASE:
-                // parse the 16+1 column slot configurations. 
+                
+                // SPECIAL CASE:: Key "FADC250"
+                // This entry marks parameter values for FADC channels,
+                // such as pedestals, gains, and thresholds. These are
+                // stored in separate lists from the other parameters.
                 if (key.startsWith("FADC250")) {
                     parseFADC(crate, key.trim(), vals);
                 }
                 
-                // SPECIAL CASE:
-                // figure out which triggers are enabled:
+                // SPECIAL CASE: Key "SSP_HPS_SET_IO_SRC"
+                // This entry indicates which triggers are enabled and
+                // needs to be parsed differently than normal.
                 else if(key.startsWith("SSP_HPS_SET_IO_SRC")) {
+                	// The first "parameter value" is a hardware code
+                	// that identifies the trigger. Obtain it.
                     int trig = Integer.valueOf(vals.get(1));
+                    
+                    // There are two trigger of each type, singles and
+                    // pairs. Compare the hardware code to the codes
+                    // for each of these triggers to determine which
+                    // it this parameter entry represents and then set
+                    // its value appropriately.
                     for (int ii = 0; ii < pairsIOsrc.length; ii++) {
                         if(trig == singlesIOsrc[ii]) {
                             singlesEn[ii] = true;
@@ -160,50 +308,60 @@
                         }
                     }
                 }
-               
-                // GENERAL CASE:
-                // Append trigger# onto key:
+                
+                // GENERAL CASE: Basic Parameter
+                // This indicates a regular parameter that does not
+                // require any special parsing.
                 if(vals.size() > 1 && key.startsWith("SSP")) {
+                	// List the parameter by "[ROW NAME]_[KEY]" and
+                	// remove the key so that only the values remain.
                     key += "_" + vals.remove(0);
                 }
-                // dump it into the map:
+                
+                // Add the parameter key and its values to the map.
                 configMap.put(key, vals);
             }
         }
     }
     
-    /*
-     * This function parses the config map for the cases where the
-     * config string has a simple format:
-     * TAG VALUE
-     * TAG TRIGGER VALUES
+    /**
+     * Parses the configuration parameter map entries and extracts the
+     * parameter values for those parameters which have the standard
+     * format of <code>[PARAMETER KEY] --> { [PARAMETER VALUES] }</code>.
      */
     public void parseConfigMap() {
-        fadcNSA    = Integer.valueOf(getConfig("FADC250_NSA", 0));
-        fadcNSB    = Integer.valueOf(getConfig("FADC250_NSB", 0));
-        fadcNPEAK  = Integer.valueOf(getConfig("FADC250_NPEAK", 0));
-        fadcMODE   = Integer.valueOf(getConfig("FADC250_MODE", 0));
-        fadcWIDTH  = Integer.valueOf(getConfig("FADC250_W_WIDTH", 0));
-        fadcOFFSET = Integer.valueOf(getConfig("FADC250_W_OFFSET", 0));
-        
-        gtpMinSeedEnergy = Integer.valueOf(getConfig("GTP_CLUSTER_PULSE_THRESHOLD", 0));
-        gtpWindowBefore  = Integer.valueOf(getConfig("GTP_CLUSTER_PULSE_COIN", 0));
-        gtpWindowAfter   = Integer.valueOf(getConfig("GTP_CLUSTER_PULSE_COIN", 1));
-        
+    	// Parse simple FADC data.
+        fadcNSA    = Integer.valueOf(getConfigParameter("FADC250_NSA",      0));
+        fadcNSB    = Integer.valueOf(getConfigParameter("FADC250_NSB",      0));
+        fadcNPEAK  = Integer.valueOf(getConfigParameter("FADC250_NPEAK",    0));
+        fadcMODE   = Integer.valueOf(getConfigParameter("FADC250_MODE",     0));
+        fadcWIDTH  = Integer.valueOf(getConfigParameter("FADC250_W_WIDTH",  0));
+        fadcOFFSET = Integer.valueOf(getConfigParameter("FADC250_W_OFFSET", 0));
+        
+        // Parse GTP data.
+        gtpMinSeedEnergy = Integer.valueOf(getConfigParameter("GTP_CLUSTER_PULSE_THRESHOLD", 0));
+        gtpWindowBefore  = Integer.valueOf(getConfigParameter("GTP_CLUSTER_PULSE_COIN",      0));
+        gtpWindowAfter   = Integer.valueOf(getConfigParameter("GTP_CLUSTER_PULSE_COIN",      1));
+        
+        // Parse trigger data.
         for(int ii = 0; ii < 2; ii++) {
+        	// Check singles trigger cuts enabled status.
             singlesNhitsEn[ii]         = getBoolConfigSSP(ii,  "SINGLES_NMIN",          1);
             singlesEnergyMinEn[ii]     = getBoolConfigSSP(ii,  "SINGLES_EMIN",          1);
             singlesEnergyMaxEn[ii]     = getBoolConfigSSP(ii,  "SINGLES_EMAX",          1);
             
+        	// Check pair trigger cuts enabled status.
             pairsEnergySumMaxMinEn[ii] = getBoolConfigSSP(ii,  "PAIRS_SUMMAX_MIN",      2);
             pairsEnergyDiffEn[ii]      = getBoolConfigSSP(ii,  "PAIRS_DIFFMAX",         1);
             pairsCoplanarityEn[ii]     = getBoolConfigSSP(ii,  "PAIRS_COPLANARITY",     1);
             pairsEnergyDistEn[ii]      = getBoolConfigSSP(ii,  "PAIRS_ENERGYDIST",      2);
             
+            // Get the singles trigger cuts.
             singlesNhits[ii]           = getIntConfigSSP(ii,   "SINGLES_NMIN",          0);
             singlesEnergyMin[ii]       = getIntConfigSSP(ii,   "SINGLES_EMIN",          0);
             singlesEnergyMax[ii]       = getIntConfigSSP(ii,   "SINGLES_EMAX",          0);
             
+            // Get the pair trigger cuts.
             pairsNhitsMin[ii]          = getIntConfigSSP(ii,   "PAIRS_NMIN",            0);
             pairsEnergyMin[ii]         = getIntConfigSSP(ii,   "PAIRS_EMIN",            0);
             pairsEnergyMax[ii]         = getIntConfigSSP(ii,   "PAIRS_EMAX",            0);
@@ -217,20 +375,18 @@
         }
     }
     
-    
-    
-    /*
-     * UNFINISHED.
-     * This is a fixer-upper for before we had the full config in EVIO
-     * or when there was a bug in it.
+    /**
+     * Method corrects parameter data for runs that either did not
+     * correctly record the full configuration data or were bugged.
+     * It populates missing fields with a zero value entry.
+     * @param runNumber - The run number for the current run. This is
+     * used to determine if the run is a "bugged" run.
      */
     private void fixConfigMap2014Run(int runNumber) {
+    	// If this is a good run, noting should be done. Return.
         if(runNumber > 3470 || runNumber < 3100) { return; }
-        // TODO: port datacat/python/engrun/engrun_metadata.py
-        // 1. SET GTP SETTINGS MANUALLY BASED ON RUN NUMBER
-        // 2. FIX SINGLES_NMIN prior to 3312
-        for (String key : configMap.keySet()) {
-        }
+        
+        // Populate missing GTP entries.
         List<String> tmp = new ArrayList<String>();
         tmp.add("0");
         tmp.add("0");
@@ -238,41 +394,90 @@
         tmp.add("0");
         configMap.put("GTP_CLUSTER_THRESH" ,tmp);
         configMap.put("GTP_TIMEDIFF", tmp);
-    }
-    
-    /*
-     * These treat the FADC config lines with 16+1 columns.
-     * Must keep track of most recent FADC250_SLOT tag, since it's
-     * not on the line with the data. 
+        
+        // TODO: Port datacat/python/engrun/engrun_metadata.py
+        // 1. SET GTP SETTINGS MANUALLY BASED ON RUN NUMBER
+        // 2. FIX SINGLES_NMIN prior to 3312
+    }
+    
+    /**
+     * Parses FADC configuration parameter entries. These all have 17
+     * lines, the first of which is the parameter key and the subsequent
+     * being parameter values corresponding to the 16 FADC channels for
+     * the indicated FADC slot. These entries contain thresholds, gains,
+     * and pedestals.
+     * @param crate - The crate associated with this parameter entry.
+     * @param key - The parameter key.
+     * @param vals - A list of 16 values with indices corresponding to
+     * the FADC channel with which they are associated.
      */
     private void parseFADC(int crate, String key, List<String> vals) {
-    	// System.out.println(crate);
-        if (key.equals("FADC250_SLOT")) {
+    	// The FADC slot is not stored on the same line as the other
+    	// data and must be parsed and retained, as it is necessary
+    	// for handling the subsequent lines. If this line is the
+    	// FADC slot, store it.
+        if(key.equals("FADC250_SLOT")) {
             thisFadcSlot = Integer.valueOf(vals.get(0));
         }
-        else if (key.equals("FADC250_ALLCH_TET")) {
+        
+        // Parse the channel thresholds.
+        else if(key.equals("FADC250_ALLCH_TET")) {
             setChannelParsInt(crate, thisFadcSlot, THRESHOLD, vals);
         }
-        else if (key.equals("FADC250_ALLCH_PED")) {
+        
+        // Parse the channel pedestals.
+        else if(key.equals("FADC250_ALLCH_PED")) {
             setChannelParsFloat(crate, thisFadcSlot, PEDESTAL, vals);    
         }
-        else if (key.equals("FADC250_ALLCH_GAIN")) {
+        
+        // Parse the channel gains.
+        else if(key.equals("FADC250_ALLCH_GAIN")) {
             setChannelParsFloat(crate, thisFadcSlot, GAIN, vals);
         }
     }
     
-    private void setChannelParsFloat(int crate, int slot, Map<EcalChannel, Float>map, List<String> vals) {
-        for (int ii = 0; ii < 16; ii++) {
-            map.put(findChannel(crate, slot, ii),Float.valueOf(vals.get(ii)));
-        }
-    }
-    
-    private void setChannelParsInt(int crate, int slot, Map<EcalChannel, Integer>map, List<String> vals) {
-        for (int ii = 0; ii < 16; ii++) {
-            map.put(findChannel(crate, slot, ii),Integer.valueOf(vals.get(ii)));
-        }
-    }
-    
+    /**
+     * Takes a list of 16 values (in argument <code>vals</code>) and
+     * maps the appropriate database calorimeter channel to the list
+     * value. This assumes that the <code>String</code> values should
+     * be parsed to <code>Float</code> objects.
+     * @param crate - The calorimeter crate associated with the values.
+     * @param slot - The FADC slot associated with the values.
+     * @param map - The map in which to place the values.
+     * @param vals - A <code>List</code> of 16 <code>String</code>
+     * objects representing the channel values. This should correspond
+     * to FADC channels 0 - 15.
+     */
+    private void setChannelParsFloat(int crate, int slot, Map<EcalChannel, Float> map, List<String> vals) {
+    	// Iterate over each channel and map the database channel object
+    	// to the corresponding list value.
+        for(int ii = 0; ii < 16; ii++) {
+            map.put(findChannel(crate, slot, ii), Float.valueOf(vals.get(ii)));
+        }
+    }
+    
+    /**
+     * Takes a list of 16 values (in argument <code>vals</code>) and
+     * maps the appropriate database calorimeter channel to the list
+     * value. This assumes that the <code>String</code> values should
+     * be parsed to <code>Integer</code> objects.
+     * @param crate - The calorimeter crate associated with the values.
+     * @param slot - The FADC slot associated with the values.
+     * @param map - The map in which to place the values.
+     * @param vals - A <code>List</code> of 16 <code>String</code>
+     * objects representing the channel values.
+     */
+    private void setChannelParsInt(int crate, int slot, Map<EcalChannel, Integer> map, List<String> vals) {
+    	// Iterate over each channel and map the database channel object
+    	// to the corresponding list value.
+        for(int ii = 0; ii < 16; ii++) {
+            map.put(findChannel(crate, slot, ii), Integer.valueOf(vals.get(ii)));
+        }
+    }
+    
+    /**
+     * Prints the mapped parameter keys and values to the terminal.
+     */
     public void printMap() {
         System.out.print("\nTriggerConfigMap::::::::::::::::::::::::::::\n");
         for (String key : configMap.keySet()) {
@@ -285,8 +490,10 @@
         System.out.println("::::::::::::::::::::::::::::::::::::::::::::");
     }
     
-    public void printVars()
-    {
+    /**
+     * Prints the parsed parameter values to the terminal.
+     */
+    public void printVars() {
         System.out.println("\nTriggerConfigVars%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
         System.out.println();
         System.out.println(String.format("GTPMINSEED: %d",     gtpMinSeedEnergy));
@@ -300,7 +507,6 @@
         System.out.println(String.format("FADC250_WIDTH: %d",  fadcWIDTH));
         System.out.println(String.format("FADC250_OFFSET: %d", fadcOFFSET));
         for(EcalChannel cc : ecalConditions.getChannelCollection()) {
-            //System.out.print(String.format("SLOT%d CHAN%d --",cc.getSlot(),cc.getChannel()));
             if(!PEDESTAL.containsKey(cc)) {
                 System.out.println("\nP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
             }
@@ -310,8 +516,6 @@
             if(!GAIN.containsKey(cc)) {
                 System.out.println("\nG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
             }
-            //System.out.println(String.format(" %f %d %f",
-            //        PEDESTAL.get(cc),THRESHOLD.get(cc),GAIN.get(cc)));
         }
         
         System.out.println();
@@ -345,55 +549,138 @@
         System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
     }
     
-    /*
-     * Parsing wrappers to make rest of code easier.
+    /**
+     * Gets an SSP parameter value using a shortened version of the
+     * full parameter key and parses it as a <code>float</code>.
+     * @param itrig - The number of the trigger for which to obtain
+     * the parameter value.
+     * @param stub - The shortened version of the parameter key. This
+     * corresponds to "SSP_HPS_[STUB]_[TRIGGER NUMBER]".
+     * @param ival - The index of the value that is to be obtained.
+     * @return Returns the requested value if it exists. Otherwise, a
+     * value of <code>0</code> is returned and a message is logged.
      */
     public float getFloatConfigSSP(int itrig, String stub, int ival) {
         return Float.valueOf(getConfigSSP(itrig, stub, ival));
     }
     
+    /**
+     * Gets an SSP parameter value using a shortened version of the
+     * full parameter key and parses it as a <code>int</code>.
+     * @param itrig - The number of the trigger for which to obtain
+     * the parameter value.
+     * @param stub - The shortened version of the parameter key. This
+     * corresponds to "SSP_HPS_[STUB]_[TRIGGER NUMBER]".
+     * @param ival - The index of the value that is to be obtained.
+     * @return Returns the requested value if it exists. Otherwise, a
+     * value of <code>0</code> is returned and a message is logged.
+     */
     public int getIntConfigSSP(int itrig, String stub, int ival) {
         return Integer.valueOf(getConfigSSP(itrig, stub, ival));
     }
     
+    /**
+     * Gets an SSP parameter value using a shortened version of the
+     * full parameter key and parses it as a <code>boolean</code>.
+     * @param itrig - The number of the trigger for which to obtain
+     * the parameter value.
+     * @param stub - The shortened version of the parameter key. This
+     * corresponds to "SSP_HPS_[STUB]_[TRIGGER NUMBER]".
+     * @param ival - The index of the value that is to be obtained.
+     * @return Returns the requested value if it exists. Otherwise, a
+     * value of <code>false</code> is returned and a message is logged.
+     */
     public boolean getBoolConfigSSP(int itrig, String stub, int ival) {
         return "1".equals(getConfigSSP(itrig, stub, ival));
     }
     
+    /**
+     * Gets an SSP parameter value using a shortened version of the
+     * full parameter key.
+     * @param itrig - The number of the trigger for which to obtain
+     * the parameter value.
+     * @param stub - The shortened version of the parameter key. This
+     * corresponds to "SSP_HPS_[STUB]_[TRIGGER NUMBER]".
+     * @param ival - The index of the value that is to be obtained.
+     * @return Returns the requested value if it exists. Otherwise, a
+     * value of <code>"0"</code> is returned and a message is logged.
+     */
     public String getConfigSSP(int itrig, String stub, int ival) {
         String key = "SSP_HPS_" + stub + "_" + itrig;
-        return getConfig(key,ival);
-    }
-    
-    public String getConfig(String key, int ival) {
-        if (configMap.containsKey(key)) {
+        return getConfigParameter(key, ival);
+    }
+    
+    /**
+     * Gets a parameter value associated with a parameter key.
+     * @param key - The parameter key to which the value belongs.
+     * @param ival - The index of the desired parameter value.
+     * @return Returns the requested parameter value if it exists and
+     * returns <code>"0"</code> otherwise. In the event that a parameter
+     * can not be found, an error message is passed to the logger.
+     */
+    public String getConfigParameter(String key, int ival) {
+    	// Check the parameter map for the requested parameter key.
+        if(configMap.containsKey(key)) {
+        	// Get the list of values associated with this parameter key.
             List<String> vals = configMap.get(key);
-            if (ival < vals.size()) {
-                return configMap.get(key).get(ival);
-            } else {
-                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
-                        "ConfigMap TOO SHORT:   " + ival + " " + configMap.get(key));
+            
+            // Check that the list of values contains a parameter for
+            // the requested parameter index. If it does, return it.
+            if (ival < vals.size()) { return configMap.get(key).get(ival); }
+            
+            // Otherwise, an error has occurred. Log this and return the
+            // default value of zero.
+            else {
+                Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "ConfigMap TOO SHORT:   " + ival + " " + configMap.get(key));
                 return "0";
             }
-        } else {
-            // this is only necessarily an error if we've read 3 banks:
+        }
+        
+        // If the key is not present...
+        else {
+            // If more than 2 banks have been read, the absence of a
+        	// key represents an error. Log that this has occurred.
             if(nBanks > 2) {
                 Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "ConfigMap MISSING KEY:   " + key);
             }
+            
+            // Return a default value of zero.
             return "0";
         }
     }
     
+    /**
+     * Gets the database calorimeter channel for a channel defined by
+     * a crate number, FADC slot, and FADC channel.
+     * @param crate - The crate number.
+     * @param fadcSlot - The FADC slot.
+     * @param fadcChan - The FADC channel.
+     * @return Returns the database channel as a <code>EcalChannel</code>
+     * if it exists, and <code>null</code> if it does not.
+     */
     public EcalChannel findChannel(int crate, int fadcSlot, int fadcChan) {
+    	// Search through the database channels for a channel that
+    	// matches the the argument parameters.
         for (EcalChannel cc : channels) {
-            // EcalChannel follows different convention on crate numbering:
-            if ((cc.getCrate() - 1) * 2 == crate - 37 && cc.getSlot() == fadcSlot && cc.getChannel() == fadcChan) {
+        	// A channel matches the argument if the slot and channel
+        	// values are the same. Crate number must also match, but
+        	// note that EcalChannel follows a different convention
+        	// with respect to crate numbering.
+            if( ((cc.getCrate() - 1) * 2 == crate - 37) && (cc.getSlot() == fadcSlot) && (cc.getChannel() == fadcChan) ) {
                 return cc;
             }
         }
+        
+        // If no matching channel is found, return null.
         return null;
     }
     
+    /**
+     * Gets the database crystal channel object based on the crystal's
+     * numerical index.
+     * @param channel_id - The crystal index.
+     * @return Returns the channel as an <code>EcalChannel</code>.
+     */
     public EcalChannel findChannel(int channel_id) {
         return ecalConditions.getChannelCollection().findChannel(channel_id);
     }

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/AbstractIntData.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/AbstractIntData.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/AbstractIntData.java	Thu Aug  6 17:19:42 2015
@@ -4,57 +4,64 @@
 import org.lcsim.event.GenericObject;
 
 /**
- * GenericObject representation of an INT32/UINT32 bank read from EVIO. The bank
- * header tag identifies the type of data, and is stored as the first int in the
- * GenericObject. The contents of the bank are the remaining N-1 ints.
- * Constructors are provided from int[] (for reading from EVIO) and from
- * GenericObject (for reading from LCIO).
- *
+ * Class <code>GenericObject</code> representation of an INT32/UINT32
+ * bank read from EvIO. The bank header tag identifies the type of
+ * data, and is stored as the first int in the <code>GenericObject</code>.
+ * The contents of the bank are the remaining N-1 <code>int</code>
+ * primitives. Constructors are provided from <code>int[]</code> (for
+ * reading from EvIO) and from <code>GenericObject</code> (for reading
+ * from LCIO).<br/>
+ * <br/>
  * Subclasses must implement the two constructors and two abstract methods, plus
  * whatever methods are needed to access the parsed data.
  *
  * @author Sho Uemura <[log in to unmask]>
- * @version $Id: $
+ * @see GenericObject
  */
 public abstract class AbstractIntData implements GenericObject {
-
+	/** The data bank. */
     protected int[] bank;
-
+    
     /**
-     * Constructor from EVIO int bank. Bank tag must be checked by EVIO reader
-     * before the constructor is called.
-     *
-     * @param bank
+     * Constructs an <code>AbstractIntData</code> from a raw EvIO integer
+     * bank. It is expected that the EvIO reader will verify that the
+     * bank tag is the appropriate type before calling the constructor.
+     * @param bank - An EvIO bank of <code>int</code> data.
      */
     protected AbstractIntData(int[] bank) {
-        if (bank == null) {
-            this.bank = new int[0];
-        } else {
-            this.bank = Arrays.copyOf(bank, bank.length);
-        }
+        if(bank == null) { this.bank = new int[0]; }
+        else { this.bank = Arrays.copyOf(bank, bank.length); }
     }
-
+    
     /**
-     * Constructor from LCIO GenericObject. Checks the bank tag; subclass
-     * constructor must set the expected value of the tag.
-     *
-     * @param data
-     * @param expectedTag
+     * Create an <code>AbstractIntData</code> object from an LCIO
+     * <code>genericObject</code>. Constructor requires that the
+     * <code>GenericObject</code> tag match the expected EvIO header
+     * tag type as defined by the implementing class.
+     * @param data - The source data bank.
+     * @param expectedTag - The required EvIO bank header tag.
      */
     protected AbstractIntData(GenericObject data, int expectedTag) {
-        if (getTag(data) != expectedTag) {
+    	// If the EvIO bank header tag is not the required type,
+    	// produce an exception.
+        if(getTag(data) != expectedTag) {
             throw new RuntimeException("expected tag " + expectedTag + ", got " + getTag(data));
         }
+        
+        // Otherwise, store the bank.
         this.bank = getBank(data);
     }
-
+    
+    /**
+     * Gets the entire, unparsed integer data bank from the object.
+     * @return Returns the data as an <code>int[]</code> array.
+     */
     public int[] getBank() {
         return bank;
     }
-
+    
     /**
      * Return the int bank of an AbstractIntData read from LCIO.
-     *
      * @param object
      * @return
      */
@@ -66,55 +73,55 @@
         }
         return bank;
     }
-
+    
     /**
-     * Return a single value from the int bank of an AbstractIntData.
-     *
-     * @param object
-     * @param index
-     * @return
+     * Return a single value from the integer bank of an
+     * <code>AbstractIntData</code>.
+     * @param object - The bank from which to obtain the data.
+     * @param index - The index of the data in the bank.
+     * @return Returns the requested entry from the integer bank.
      */
     public static int getBankInt(GenericObject object, int index) {
         return object.getIntVal(index + 1);
     }
-
+    
     /**
-     * Returns the EVIO bank header tag expected for this data.
-     *
-     * @return
+     * Returns the EvIO bank header tag expected for this data.
+     * @return Returns the tag as an <code>int</code> primitive.
      */
     public abstract int getTag();
-
+    
     /**
      * Returns the EVIO bank tag for a data object.
-     *
-     * @param data
-     * @return
+     * @param data - A <code>GenericObject</code> representing an integer
+     * data bank.
+     * @return Returns the EvIO tag identifying the type of bank the object
+     * represents.
      */
     public static int getTag(GenericObject data) {
         return data.getIntVal(0);
     }
-
+    
     /**
      * Parses the bank so the object can be used in analysis.
      */
     protected abstract void decodeData();
-
+    
     @Override
     public int getNInt() {
         return bank.length + 1;
     }
-
+    
     @Override
     public int getNFloat() {
         return 0;
     }
-
+    
     @Override
     public int getNDouble() {
         return 0;
     }
-
+    
     @Override
     public int getIntVal(int index) {
         if (index == 0) {
@@ -122,19 +129,19 @@
         }
         return bank[index - 1];
     }
-
+    
     @Override
     public float getFloatVal(int index) {
         throw new UnsupportedOperationException("No float values in " + this.getClass().getSimpleName());
     }
-
+    
     @Override
     public double getDoubleVal(int index) {
         throw new UnsupportedOperationException("No double values in " + this.getClass().getSimpleName());
     }
-
+    
     @Override
     public boolean isFixedSize() {
         return true;
     }
-}
+}

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/SSPCluster.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/SSPCluster.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/SSPCluster.java	Thu Aug  6 17:19:42 2015
@@ -7,7 +7,14 @@
 
 /**
  * Class <code>SSPCluster</code> stores all of the information on 
- * clusters that is reported by the SSP.
+ * clusters that is reported by the SSP. SSP clusters store:
+ * <ul><li>Cluster center x-index</li>
+ * <li>Cluster center y-index</li>
+ * <li>Cluster total energy</li>
+ * <li>Cluster hit count</li>
+ * <li>Cluster time</li></ul>
+ * <code>SSPCluster</code> does not support the ability to track
+ * individual hits that are part of a cluster.
  * 
  * @author Kyle McCarty <[log in to unmask]>
  */

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TIData.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TIData.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TIData.java	Thu Aug  6 17:19:42 2015
@@ -2,17 +2,22 @@
 
 import org.lcsim.event.GenericObject;
 
-//import org.hps.record.evio.EvioEventConstants; // doesn't work
 /**
- * TI Trigger Data
+ * Class <code>TIData</code> is an implementation of abstract class
+ * <code>AbstractIntData</code> that represents a TI trigger bit bank.
+ * It contains both a time window length and a set of flags that track
+ * whether a trigger of a given type was registered with the event to
+ * which this bank is attached.
  *
  * @author Nathan Baltzell <[log in to unmask]>
  */
 public class TIData extends AbstractIntData {
-
+	/** The EvIO bank header tag for TI data banks. */
     public static final int BANK_TAG = 0xe10a; // EvioEventConstants.TI_TRIGGER_BANK_TAG;
+    /** The expected number of entries in the data bank. */
     public static final int BANK_SIZE = 4;
-
+    
+    // Store the parsed data bank parameters.
     private long time = 0;
     private boolean singles0 = false;
     private boolean singles1 = false;
@@ -20,69 +25,122 @@
     private boolean pairs1 = false;
     private boolean calib = false;
     private boolean pulser = false;
-
+    
+    /**
+     * Creates a <code>TIData</code> bank from a raw EvIO data bank.
+     * It is expected that the EvIO reader will verify that the bank
+     * tag is of the appropriate type.
+     * @param bank - The EvIO data bank.
+     */
     public TIData(int[] bank) {
         super(bank);
         decodeData();
     }
-
+    
+    /**
+     * Creates a <code>TIData</code> object from an existing LCIO
+     * <code>GenericObject</code>.
+     * @param tiData - The source data bank object.
+     */
     public TIData(GenericObject tiData) {
         super(tiData, BANK_TAG);
         decodeData();
     }
-
+    
     @Override
     protected final void decodeData() {
-        if (this.bank.length != BANK_SIZE) {
+    	// Check that the data bank is the expected size. If not, throw
+    	// and exception.
+        if(this.bank.length != BANK_SIZE) {
             throw new RuntimeException("Invalid Data Length:  " + bank.length);
         }
-
+        
+        // Check each trigger bit to see if it is active. A value of 
+        // 1 indicates a trigger of that type occurred, and 0 that it
+        // did not.
         singles0 = ((bank[0] >> 24) & 1) == 1;
         singles1 = ((bank[0] >> 25) & 1) == 1;
         pairs0 = ((bank[0] >> 26) & 1) == 1;
         pairs1 = ((bank[0] >> 27) & 1) == 1;
         calib = ((bank[0] >> 28) & 1) == 1;
         pulser = ((bank[0] >> 29) & 1) == 1;
-
+        
+        // Get the unprocessed start and end times for the bank.
         long w1 = bank[2] & 0xffffffffL;
         long w2 = bank[3] & 0xffffffffL;
-
+        
+        // Process the times into units of clock-cycles.
         final long timelo = w1;
         final long timehi = (w2 & 0xffff) << 32;
-
-        time = 4 * (timelo + timehi); // units ns
+        
+        // Store the time difference in nanoseconds.
+        time = 4 * (timelo + timehi);
     }
-
+    
     @Override
     public int getTag() {
         return BANK_TAG;
     }
-
+    
+    /**
+     * Gets the time window for the bank.
+     * @return Returns the time window length in nanoseconds.
+     */
     public long getTime() {
         return time;
     }
-
+    
+    /**
+     * Indicates whether a singles 0 trigger was registered.
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise.
+     */
     public boolean isSingle0Trigger() {
         return singles0;
     }
-
+    
+    /**
+     * Indicates whether a singles 1 trigger was registered.
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise.
+     */
     public boolean isSingle1Trigger() {
         return singles1;
     }
-
+    
+    /**
+     * Indicates whether a pair 0 trigger was registered.
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise.
+     */
     public boolean isPair0Trigger() {
         return pairs0;
     }
-
+    
+    /**
+     * Indicates whether a pair 1 trigger was registered.
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise.
+     */
     public boolean isPair1Trigger() {
         return pairs1;
     }
-
+    
+    /**
+     * Indicates whether a cosmic trigger was registered.
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise.
+     */
     public boolean isCalibTrigger() {
         return calib;
     }
-
+    
+    /**
+     * Indicates whether a random/pulser trigger was registered.
+     * @return Returns <code>true</code> if the trigger occurred, and
+     * <code>false</code> otherwise.
+     */
     public boolean isPulserTrigger() {
         return pulser;
     }
-}
+}

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TriggerModule.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TriggerModule.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/triggerbank/TriggerModule.java	Thu Aug  6 17:19:42 2015
@@ -20,62 +20,85 @@
  * called without initializing an instance of the module.<br/>
  * <br/>
  * Both <code>Cluster</code> objects and <code>SSPCluster</code> objects
- * are supported.
- * 
+ * are supported, except for the seed energy cut, as this value is not
+ * present in <code>SSPCluster</code> objects.<br/>
+ * <br/>
+ * This module supports the following cuts:
+ * <ul><li>Seed Energy Lower Bound</li>
+ * <li>Seed Energy Lower Bound</li>
+ * <li>Seed Energy Upper Bound</li>
+ * <li>Cluster Total Energy Upper Bound</li>
+ * <li>Cluster Total Energy Lower Bound</li>
+ * <li>Cluster Hit Count Lower Bound</li>
+ * <li>Pair Energy Sum Upper Bound</li>
+ * <li>Pair Energy Sum Lower Bound</li>
+ * <li>Pair Energy Difference Upper Bound</li>
+ * <li>Pair Energy Slope Lower Bound</li>
+ * <li>Pair Coplanarity Upper Bound</li>
+ * <li>Pair Time Coincidence Upper Bound</li></ul>
  * @author Kyle McCarty <[log in to unmask]>
  * @see Cluster
  * @see SSPCluster
  */
 public final class TriggerModule {
-	// The calorimeter mid-plane, defined by the photon beam position
-	// (30.52 mrad) at the calorimeter face (z = 1393 mm).
+	/** The calorimeter mid-plane, defined by the photon beam position
+	* (30.52 mrad) at the calorimeter face (z = 1393 mm). */
     private static final double ORIGIN_X = 1393.0 * Math.tan(0.03052);
     
-    // Trigger module property names.
     /** The value of the parameter "F" in the energy slope equation
-     * <code>E_low GeV + R_min mm * F GeV/mm</code>. */
+     * <code>E_low GeV + R_min mm * F GeV/mm</code>. Units are in GeV
+     * / mm. */
     public static final String PAIR_ENERGY_SLOPE_F = "pairEnergySlopeF";
     /** The lower bound for the pair energy sum cut. The sum of the
-     * energies of two clusters must exceed this value to pass the cut. */
+     * energies of two clusters must exceed this value to pass the cut.
+     * Units are in GeV. */
     public static final String PAIR_ENERGY_SUM_LOW = "pairEnergySumLow";
     /** The upper bound for the pair energy sum cut. The sum of the
-     * energies of two clusters must be below this value to pass the cut. */
+     * energies of two clusters must be below this value to pass the
+     * cut. Units are in GeV. */
     public static final String PAIR_ENERGY_SUM_HIGH = "pairEnergySumHigh";
     /** The threshold for the cluster hit count cut. Clusters must have
      * this many hits or more to pass the cut. */
     public static final String CLUSTER_HIT_COUNT_LOW = "clusterHitCountLow";
     /** The threshold for the energy slope cut. The value of the energy
-     * slope equation must exceed this value to pass the cut. */
+     * slope equation must exceed this value to pass the cut. Units are
+     * in GeV. */
     public static final String PAIR_ENERGY_SLOPE_LOW = "pairEnergySlopeLow";
     /** The bound for the coplanarity cut. The coplanarity angle for
-     * the cluster pair must be below this value to pass the cut. */
+     * the cluster pair must be below this value to pass the cut. Units
+     * are in degrees. */
     public static final String PAIR_COPLANARITY_HIGH = "pairCoplanarityHigh";
     /** The lower bound for the cluster seed energy cut. The seed energy
-     * of a cluster must exceed this value to pass the cut. */
+     * of a cluster must exceed this value to pass the cut. Units are in
+     * GeV. */
     public static final String CLUSTER_SEED_ENERGY_LOW = "clusterSeedEnergyLow";
     /** The upper bound for the cluster seed energy cut. The seed energy
-     * of a cluster must be below this value to pass the cut. */
+     * of a cluster must be below this value to pass the cut. Units are
+     * in GeV. */
     public static final String CLUSTER_SEED_ENERGY_HIGH = "clusterSeedEnergyHigh";
     /** The lower bound for the cluster total energy cut. The energy
      * of a cluster must exceed this value to pass the cut. */
     public static final String CLUSTER_TOTAL_ENERGY_LOW = "clusterTotalEnergyLow";
     /** The upper bound for the cluster total energy cut. The energy
-     * of a cluster must be below this value to pass the cut. */
+     * of a cluster must be below this value to pass the cut. Units are
+     * in GeV. */
     public static final String CLUSTER_TOTAL_ENERGY_HIGH = "clusterTotalEnergyHigh";
     /** The bound for the pair energy difference cut. The absolute value
      * of the difference between the energies of the cluster pair must
-     * be below this value to pass the cut. */
+     * be below this value to pass the cut. Units are in GeV. */
     public static final String PAIR_ENERGY_DIFFERENCE_HIGH = "pairEnergyDifferenceHigh";
     /** The maximum amount of time by which two clusters are allowed
-     * to be separated. */
+     * to be separated. Units are in ns. */
     public static final String PAIR_TIME_COINCIDENCE = "pairTimeCoincidence";
     
-    // Trigger cut settings map.
+    /** Stores each of the cut values used by the module. Map keys are
+     * defined as publicly-accessible static variables in the class. */
     private final Map<String, Double> cuts = new HashMap<String, Double>(11);
     
     /**
-     * Creates an <code>SSPTriggerModule</code> that accepts all single
-     * cluster and cluster pair events.
+     * Creates a default <code>TriggerModule</code>. The cuts are
+     * defined such that all physical clusters (i.e. with energy
+     * above zero) will be accepted.
      */
     public TriggerModule() {
     	// Set the cluster singles cuts to accept all values by default.
@@ -98,21 +121,21 @@
     }
     
     /**
-     * Creates an <code>SSPTriggerModule</code> that uses the default
-     * cut values specified by the argument array. The array should be
-     * of size 11. Values are applied in the order:
+     * Creates a <code>TriggerModule</code> with trigger cuts defined
+     * by the argument array. The order of the cut value arguments are
+     * as follows:
      * <ul>
-     * <li>Cluster Hit Count Lower Bound</li>
-     * <li>Cluster Seed Energy Lower Bound</li>
-     * <li>Cluster Seed Energy Upper Bound</li>
-     * <li>Cluster Seed Total Lower Bound</li>
-     * <li>Cluster Seed Total Upper Bound</li>
-     * <li>Pair Energy Sum Lower Bound</li>
-     * <li>Pair Energy Sum Upper Bound</li>
-     * <li>Pair Energy Difference Upper Bound</li>
-     * <li>Pair Energy Slope Lower Bound</li>
-     * <li>Pair Coplanarity Upper Bound</li>
-     * <li>Pair Energy Slope Parameter F</li>
+     * <li>Cluster Hit Count Lower Bound (Hits)</li>
+     * <li>Cluster Seed Energy Lower Bound (GeV)</li>
+     * <li>Cluster Seed Energy Upper Bound (GeV)</li>
+     * <li>Cluster Seed Total Lower Bound (GeV)</li>
+     * <li>Cluster Seed Total Upper Bound (GeV)</li>
+     * <li>Pair Energy Sum Lower Bound (GeV)</li>
+     * <li>Pair Energy Sum Upper Bound (GeV)</li>
+     * <li>Pair Energy Difference Upper Bound (GeV)</li>
+     * <li>Pair Energy Slope Lower Bound (GeV)</li>
+     * <li>Pair Coplanarity Upper Bound (Degrees)</li>
+     * <li>Pair Energy Slope Parameter F (GeV / mm)</li>
      * </ul>
      */
     public TriggerModule(double... cutValues) {
@@ -139,9 +162,11 @@
     
     /**
      * Gets the value of the requested cut, if it exists.
-     * @param cut - The identifier of the cut.
+     * @param cut - The identifier of the cut. This can be obtained
+     * through the publicly-accessible static identifiers in this class.
      * @return Returns the cut value as a <code>double</code>.
-     * @throws IllegalArgumentException Occurs if the cut does not exist.
+     * @throws IllegalArgumentException Occurs if the cut identifier
+     * specified in the argument is not valid.
      */
     public double getCutValue(String cut) throws IllegalArgumentException {
     	// Try to get the indicated cut.
@@ -156,8 +181,9 @@
     
     /**
      * Loads triggers settings from the DAQ configuration for a singles
-     * trigger. Pair trigger settings will be set to accept all possible
-     * values, while singles trigger settings will
+     * trigger. Singles trigger cuts will be set to match those defined
+     * in the configuration object, while pair trigger cuts will be set
+     * to accept all possible clusters.
      * @param config - The DAQ configuration settings.
      */
     public void loadDAQConfiguration(SinglesTriggerConfig config) {
@@ -205,11 +231,14 @@
     }
     
     /**
-     * Sets the value of the indicated cut to a new value.
+     * Sets the value of the cut specified by the identifier given in
+     * the argument to the specified value.
      * @param cut - The identifier of the cut to which the new value
-     * should be assigned.
+     * should be assigned. These can be obtained as publicly-accessible
+     * static variables from this class.
      * @param value - The new cut value.
-     * @throws IllegalArgumentException Occurs if the cut does not exist.
+     * @throws IllegalArgumentException Occurs if the argument cut
+     * identifier is not valid.
      */
     public void setCutValue(String cut, double value) throws IllegalArgumentException {
     	// Make sure that the cut exists. If it does, change it to the
@@ -230,6 +259,7 @@
 	 * @param cutValues - A string representing the cuts values. This
 	 * must be formatted in the style of "Emin Emax Nmin ...".
 	 */
+    // TODO: Specify in JavaDoc what the order of these arguments is.
 	public void setCutValues(boolean isSingles, String cutValues) {
 		// Make sure that the string is not null.
 		if(cutValues == null) {
@@ -283,8 +313,8 @@
 	}
     
     /**
-     * Checks whether the argument cluster possesses the minimum
-     * allowed hits.
+     * Checks whether a cluster passes the cluster hit count cut. This
+     * is defined as <code>N_hits >= CLUSTER_HIT_COUNT_LOW</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -294,8 +324,8 @@
     }
     
     /**
-     * Checks whether the argument cluster possesses the minimum
-     * allowed hits.
+     * Checks whether a cluster passes the cluster hit count cut. This
+     * is defined as <code>N_hits >= CLUSTER_HIT_COUNT_LOW</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -305,8 +335,9 @@
     }
     
     /**
-     * Checks whether the argument cluster seed hit falls within the
-     * allowed seed hit energy range.
+     * Checks whether a cluster passes the seed energy cut. This is
+     * defined as <code>CLUSTER_SEED_ENERGY_LOW <= E_seed <=
+     * CLUSTER_SEED_ENERGY_HIGH</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -316,8 +347,8 @@
     }
     
     /**
-     * Checks whether the argument cluster seed hit falls below the
-     * allowed seed hit energy upper bound.
+     * Checks whether a cluster passes the seed energy upper bound cut.
+     * This is defined as <code>E_seed <= CLUSTER_SEED_ENERGY_HIGH</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -327,8 +358,8 @@
     }
     
     /**
-     * Checks whether the argument cluster seed hit falls above the
-     * allowed seed hit energy lower bound.
+     * Checks whether a cluster passes the seed energy lower bound cut.
+     * This is defined as <code>CLUSTER_SEED_ENERGY_LOW <= E_seed</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -338,8 +369,9 @@
     }
     
     /**
-     * Checks whether the argument cluster falls within the allowed
-     * cluster total energy range.
+     * Checks whether a cluster passes the cluster total energy cut.
+     * This is defined as <code>CLUSTER_TOTAL_ENERGY_LOW <= E_cluster
+     * <= CLUSTER_TOTAL_ENERGY_HIGH</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -349,8 +381,9 @@
     }
     
     /**
-     * Checks whether the argument cluster falls below the allowed
-     * cluster total energy upper bound.
+     * Checks whether a cluster passes the cluster total energy upper
+     * bound cut. This is defined as <code>E_cluster <=
+     * CLUSTER_TOTAL_ENERGY_HIGH</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -360,8 +393,9 @@
     }
     
     /**
-     * Checks whether the argument cluster falls above the allowed
-     * cluster total energy lower bound.
+     * Checks whether a cluster passes the cluster total energy lower
+     * bound cut. This is defined as <code>CLUSTER_TOTAL_ENERGY_LOW <=
+     * E_cluster</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -371,8 +405,9 @@
     }
     
     /**
-     * Checks whether the argument cluster falls within the allowed
-     * cluster total energy range.
+     * Checks whether a cluster passes the cluster total energy cut.
+     * This is defined as <code>CLUSTER_TOTAL_ENERGY_LOW <= E_cluster
+     * <= CLUSTER_TOTAL_ENERGY_HIGH</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -382,8 +417,9 @@
     }
     
     /**
-     * Checks whether the argument cluster falls below the allowed
-     * cluster total energy upper bound.
+     * Checks whether a cluster passes the cluster total energy upper
+     * bound cut. This is defined as <code>E_cluster <=
+     * CLUSTER_TOTAL_ENERGY_HIGH</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -393,8 +429,9 @@
     }
     
     /**
-     * Checks whether the argument cluster falls above the allowed
-     * cluster total energy lower bound.
+     * Checks whether a cluster passes the cluster total energy lower
+     * bound cut. This is defined as <code>CLUSTER_TOTAL_ENERGY_LOW <=
+     * E_cluster</code>.
      * @param cluster - The cluster to check.
      * @return Returns <code>true</code> if the cluster passes the cut
      * and <code>false</code> if the cluster does not.
@@ -409,6 +446,7 @@
      * be calculated.
      * @return Returns displacement of the cluster.
      */
+    // TODO: What defines cluster distance?
     public static double getClusterDistance(Cluster cluster) {
     	// Get the variables from the cluster.
     	double x = getClusterX(cluster);
@@ -419,12 +457,23 @@
     }
     
     /**
-     * Gets the size of a cluster.
+     * Gets the number of hits in a cluster, as used in the cluster
+     * hit count cut.
      * @param cluster - The cluster for which to obtain the size.
      * @return Returns the size as an <code>int</code>.
      */
     public static final double getClusterHitCount(Cluster cluster) {
     	return cluster.getCalorimeterHits().size();
+    }
+    
+    /**
+     * Gets the number of hits in a cluster, as used in the cluster
+     * hit count cut.
+     * @param cluster - The cluster for which to obtain the size.
+     * @return Returns the size as an <code>int</code>.
+     */
+    public static final double getClusterHitCount(SSPCluster cluster) {
+    	return cluster.getHitCount();
     }
     
     /**
@@ -442,12 +491,23 @@
     }
     
     /**
-     * Gets the time-stamp of a cluster.
+     * Gets the time-stamp of a cluster, as used in the time-coincidence
+     * cut.
      * @param cluster - The cluster for which to obtain the time.
      * @return Returns the time as a <code>double</code>.
      */
     public static final double getClusterTime(Cluster cluster) {
     	return getClusterSeedHit(cluster).getTime();
+    }
+    
+    /**
+     * Gets the time-stamp of a cluster, as used in the time-coincidence
+     * cut.
+     * @param cluster - The cluster for which to obtain the time.
+     * @return Returns the time as a <code>double</code>.
+     */
+    public static final double getClusterTime(SSPCluster cluster) {
+    	return cluster.getTime();
     }
     
     /**
@@ -471,12 +531,21 @@
     }
     
     /**
-     * Gets the x-index of a cluster.
+     * Gets the x-index of a cluster's
      * @param cluster - The cluster for which to obtain the index.
      * @return Returns the index as an <code>int</code>.
      */
     public static final int getClusterXIndex(Cluster cluster) {
     	return getClusterSeedHit(cluster).getIdentifierFieldValue("ix");
+    }
+    
+    /**
+     * Gets the x-index of a cluster's
+     * @param cluster - The cluster for which to obtain the index.
+     * @return Returns the index as an <code>int</code>.
+     */
+    public static final int getClusterXIndex(SSPCluster cluster) {
+    	return cluster.getXIndex();
     }
     
     /**
@@ -509,6 +578,15 @@
     }
     
     /**
+     * Gets the y-index of a cluster.
+     * @param cluster - The cluster for which to obtain the index.
+     * @return Returns the index as an <code>int</code>.
+     */
+    public static final int getClusterYIndex(SSPCluster cluster) {
+    	return cluster.getYIndex();
+    }
+    
+    /**
      * Gets the z-position of a cluster in millimeters in the hardware
      * coordinate system.
      * @param cluster - The cluster of which to get the z-position.
@@ -529,27 +607,30 @@
     }
     
     /**
-     * Gets the value used for the cluster total energy cut.
+     * Gets the value used for the cluster total energy cut. This is
+     * the energy of the entire cluster.
      * @param cluster - The cluster from which the value should be
      * derived.
-     * @return Returns the energy of the entire cluster in GeV.
+     * @return Returns the cluster energy in GeV.
      */
     public static double getValueClusterTotalEnergy(Cluster cluster) {
         return cluster.getEnergy();
     }
     
     /**
-     * Gets the value used for the cluster total energy cut.
+     * Gets the value used for the cluster total energy cut. This is
+     * the energy of the entire cluster.
      * @param cluster - The cluster from which the value should be
      * derived.
-     * @return Returns the energy of the entire cluster in GeV.
+     * @return Returns the cluster energy in GeV.
      */
     public static double getValueClusterTotalEnergy(SSPCluster cluster) {
         return cluster.getEnergy();
     }
     
     /**
-     * Gets the value used for the cluster hit count cut.
+     * Gets the value used for the cluster hit count cut. This is the
+     * total number of hits included in the cluster.
      * @param cluster - The cluster from which the value should be
      * derived.
      * @return Returns the number of hits in the cluster.
@@ -559,7 +640,8 @@
     }
     
     /**
-     * Gets the value used for the cluster hit count cut.
+     * Gets the value used for the cluster hit count cut. This is the
+     * total number of hits included in the cluster.
      * @param cluster - The cluster from which the value should be
      * derived.
      * @return Returns the number of hits in the cluster.
@@ -587,14 +669,15 @@
     public static double getValueCoplanarity(Cluster[] clusterPair) {
     	// Get the variables used by the calculation.
     	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double z[] = { getClusterZ(clusterPair[0]), getClusterZ(clusterPair[1]) };
+    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
     	
     	// Return the calculated value.
-    	return getValueCoplanarity(x, z);
-    }
-    
-    /**
-     * Calculates the value used by the coplanarity cut.
+    	return getValueCoplanarity(x, y);
+    }
+    
+    /**
+     * Calculates the value used by the coplanarity cut. A value of zero
+     * represents clusters in the same plane.
      * @param clusterPair - The cluster pair from which the value should
      * be calculated.
      * @return Returns the cut value.
@@ -602,10 +685,10 @@
     public static double getValueCoplanarity(SSPCluster[] clusterPair) {
     	// Get the variables used by the calculation.
     	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double z[] = { getClusterZ(clusterPair[0]), getClusterZ(clusterPair[1]) };
+    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
     	
     	// Return the calculated value.
-    	return getValueCoplanarity(x, z);
+    	return getValueCoplanarity(x, y);
     }
     
     /**
@@ -667,10 +750,10 @@
     	// Get the variables used by the calculation.
     	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
     	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double z[] = { getClusterZ(clusterPair[0]), getClusterZ(clusterPair[1]) };
+    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
     	
     	// Perform the calculation.
-    	return getValueEnergySlope(energy, x, z, energySlopeParamF);
+    	return getValueEnergySlope(energy, x, y, energySlopeParamF);
     }
     
     /**
@@ -685,10 +768,10 @@
     	// Get the variables used by the calculation.
     	double[] energy = { clusterPair[0].getEnergy(), clusterPair[1].getEnergy() };
     	double x[] = { getClusterX(clusterPair[0]), getClusterX(clusterPair[1]) };
-    	double z[] = { getClusterZ(clusterPair[0]), getClusterZ(clusterPair[1]) };
+    	double y[] = { getClusterY(clusterPair[0]), getClusterY(clusterPair[1]) };
     	
     	// Perform the calculation.
-    	return getValueEnergySlope(energy, x, z, energySlopeParamF);
+    	return getValueEnergySlope(energy, x, y, energySlopeParamF);
     }
     
     /**
@@ -773,7 +856,7 @@
     
     /**
      * Checks if a cluster pair is coplanar to the beam within a given
-     * angle.
+     * angle. This is defined as <code>θ <= PAIR_COPLANARITY_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -784,7 +867,7 @@
     
     /**
      * Checks if a cluster pair is coplanar to the beam within a given
-     * angle.
+     * angle. This is defined as <code>θ <= PAIR_COPLANARITY_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -795,7 +878,8 @@
     
     /**
      * Checks if the energy difference between the clusters making up
-     * a cluster pair is below an energy difference threshold.
+     * a cluster pair is below an energy difference threshold. This is
+     * defined as <code>|E_1 - E_2| <= PAIR_ENERGY_DIFFERENCE_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -806,7 +890,8 @@
     
     /**
      * Checks if the energy difference between the clusters making up
-     * a cluster pair is below an energy difference threshold.
+     * a cluster pair is below an energy difference threshold. This is
+     * defined as <code>|E_1 - E_2| <= PAIR_ENERGY_DIFFERENCE_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -818,7 +903,7 @@
     /**
      * Requires that the distance from the beam of the lowest energy
      * cluster in a cluster pair satisfies the following:<br/>
-     * <code>E_low + R_min * F < [ Threshold ]</code>
+     * <code>E_low + R_min * F >= PAIR_ENERGY_SLOPE_LOW</code>
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -830,7 +915,7 @@
     /**
      * Requires that the distance from the beam of the lowest energy
      * cluster in a cluster pair satisfies the following:<br/>
-     * <code>E_low + R_min * F < [ Threshold ]</code>
+     * <code>E_low + R_min * F >= PAIR_ENERGY_SLOPE_LOW</code>
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -841,7 +926,9 @@
     
     /**
      * Checks if the sum of the energies of the clusters making up a
-     * cluster pair is within an energy sum threshold.
+     * cluster pair is within an energy sum threshold. This is defined
+     * as <code>PAIR_ENERGY_SUM_LOW <= E_1 + E_2 <=
+     * PAIR_ENERGY_SUM_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -853,6 +940,7 @@
     /**
      * Checks if the sum of the energies of the clusters making up a
      * cluster pair is below the energy sum upper bound threshold.
+     * This is defined as <code>E_1 + E_2 <= PAIR_ENERGY_SUM_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -864,6 +952,7 @@
     /**
      * Checks if the sum of the energies of the clusters making up a
      * cluster pair is above the energy sum lower bound threshold.
+     * This is defined as <code>PAIR_ENERGY_SUM_LOW <= E_1 + E_2</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -874,7 +963,9 @@
     
     /**
      * Checks if the sum of the energies of clusters making up a cluster
-     * pair is below an energy sum threshold.
+     * pair is below an energy sum threshold. This is defined
+     * as <code>PAIR_ENERGY_SUM_LOW <= E_1 + E_2 <=
+     * PAIR_ENERGY_SUM_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -886,6 +977,7 @@
     /**
      * Checks if the sum of the energies of the clusters making up a
      * cluster pair is below the energy sum upper bound threshold.
+     * This is defined as <code>E_1 + E_2 <= PAIR_ENERGY_SUM_HIGH</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -897,6 +989,7 @@
     /**
      * Checks if the sum of the energies of the clusters making up a
      * cluster pair is above the energy sum lower bound threshold.
+     * This is defined as <code>PAIR_ENERGY_SUM_LOW <= E_1 + E_2</code>.
      * @param clusterPair - The cluster pair to check.
      * @return Returns <code>true</code> if the cluster pair passes
      * the cut and <code>false</code> if it does not.
@@ -907,7 +1000,8 @@
     
     /**
      * Checks if the absolute difference between the times between
-     * two clusters is below the time coincidence cut.
+     * two clusters is below the time coincidence cut. This is defined
+     * as <code>|t_1 - t_2| <= PAIR_TIME_COINCIDENCE</code>.
      * @param clusterPair - The cluster pair to check.
      * @return <code>true</code> if the energy sum passes
      * the cut and <code>false</code> if it does not.
@@ -918,7 +1012,8 @@
     
     /**
      * Checks if the absolute difference between the times between
-     * two clusters is below the time coincidence cut.
+     * two clusters is below the time coincidence cut. This is defined
+     * as <code>|t_1 - t_2| <= PAIR_TIME_COINCIDENCE</code>.
      * @param clusterPair - The cluster pair to check.
      * @return <code>true</code> if the energy sum passes
      * the cut and <code>false</code> if it does not.
@@ -1018,9 +1113,8 @@
      * Gets the mapped position used by the SSP for a specific crystal.
      * @param ix - The crystal x-index.
      * @param iy - The crystal y-index.
-     * @return Returns the crystal position as a <double</code> array
-     * where the coordinates are ordered from the lowest to highest
-     * index as x, y, z.
+     * @return Returns the crystal position as a <code>double</code>
+     * array of form { x, y, z }.
      * @throws IndexOutOfBoundsException Occurs if in either of the
      * cases where <code>ix == 0</code> or <code>|ix| > 23</code> for
      * the x-index and either of the cases where <code>iy == 0</code>
@@ -1034,9 +1128,13 @@
 			throw new IndexOutOfBoundsException(String.format("Value \"%d\" is invalid for field y-index.", iy));
 		}
 		
-		// Return the mapped position.
-		if(ix < 1) { return position[5 - iy][22 - ix]; }
-		else { return position[5 - iy][23 - ix]; }
+		// Get the position map.
+		double posMap[];
+		if(ix < 1) { posMap = position[5 - iy][22 - ix]; }
+		else { posMap = position[5 - iy][23 - ix]; }
+		
+		// Return the corrected mapped position.
+		return new double[] { posMap[0], posMap[2], posMap[1] };
 	}
     
     /**
@@ -1047,11 +1145,11 @@
      * second clusters' y-positions.
      * @return Returns the cluster pair's coplanarity.
      */
-    private static double getValueCoplanarity(double[] x, double z[]) {
+    private static double getValueCoplanarity(double[] x, double y[]) {
         // Get the cluster angles.
         int[] clusterAngle = new int[2];
         for(int i = 0; i < 2; i++) {
-        	clusterAngle[i] = (int) Math.round(Math.atan(x[i] / z[i]) * 180.0 / Math.PI);
+        	clusterAngle[i] = (int) Math.round(Math.atan(x[i] / y[i]) * 180.0 / Math.PI);
         }
         
         // Calculate the coplanarity cut value.
@@ -1098,33 +1196,7 @@
      * energy slope equation E_low + R_min * F.
      * @return Returns the cut value.
      */
-    private static double getValueEnergySlope(double energy[], double x[], double z[], double energySlopeParamF) {
-    	// Determine which cluster is the lower-energy cluster.
-    	int lei = energy[0] < energy[1] ? 0 : 1;
-    	
-        // E + R*F
-        // Get the low energy cluster energy.
-        double slopeParamE = energy[lei];
-        
-        // Get the low energy cluster radial distance.
-        double slopeParamR = Math.sqrt((x[lei] * x[lei]) + (z[lei] * z[lei]));
-        
-        // Calculate the energy slope.
-        return slopeParamE + slopeParamR * energySlopeParamF;
-    }
-    
-    /**
-     * Calculates the value used by the energy slope cut. This version
-     * is superseded by the <code>getValueEnergySlope</code>, which
-     * more accurately mirrors the hardware behavior.
-     * @param clusterPair - The cluster pair from which the value should
-     * be calculated.
-     * @param energySlopeParamF - The value of the variable F in the
-     * energy slope equation E_low + R_min * F.
-     * @return Returns the cut value.
-     */
-    @Deprecated
-    private static double getValueEnergySlopeLegacy(double energy[], double x[], double y[], double energySlopeParamF) {
+    private static double getValueEnergySlope(double energy[], double x[], double y[], double energySlopeParamF) {
     	// Determine which cluster is the lower-energy cluster.
     	int lei = energy[0] < energy[1] ? 0 : 1;
     	
@@ -1140,6 +1212,32 @@
     }
     
     /**
+     * Calculates the value used by the energy slope cut. This version
+     * is superseded by the <code>getValueEnergySlope</code>, which
+     * more accurately mirrors the hardware behavior.
+     * @param clusterPair - The cluster pair from which the value should
+     * be calculated.
+     * @param energySlopeParamF - The value of the variable F in the
+     * energy slope equation E_low + R_min * F.
+     * @return Returns the cut value.
+     */
+    @Deprecated
+    private static double getValueEnergySlopeLegacy(double energy[], double x[], double y[], double energySlopeParamF) {
+    	// Determine which cluster is the lower-energy cluster.
+    	int lei = energy[0] < energy[1] ? 0 : 1;
+    	
+        // E + R*F
+        // Get the low energy cluster energy.
+        double slopeParamE = energy[lei];
+        
+        // Get the low energy cluster radial distance.
+        double slopeParamR = Math.sqrt((x[lei] * x[lei]) + (y[lei] * y[lei]));
+        
+        // Calculate the energy slope.
+        return slopeParamE + slopeParamR * energySlopeParamF;
+    }
+    
+    /**
      * Calculates the value used by the energy sum cut.
      * @param energy - A two-dimensional array consisting of the first
      * and second clusters' energies.
@@ -1242,7 +1340,10 @@
      * the hardware SSP position mappings for each crystal. Note that
      * ix in the array goes from -22 (representing ix = 23) up to 25
      * (representing ix = 23) and uses array index x = 0 as a valid
-     * parameter, while ix skips zero.
+     * parameter, while ix skips zero.<br/>
+     * <br/>
+     * Note that in this table, position[][] = { x, z, y } by in the
+     * coordinate system employed by the rest of the class.
      */
 	private static final double[][][] position = {
 		{	{ -340.003,   97.065,   87.845 }, { -324.283,   97.450,   87.875 }, { -308.648,   97.810,   87.900 },

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