Commit in java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal on MAIN
GTPEcalClusterer.java+76-66840 -> 841
Added asymmetric cluster window to GTPEcalClusterer.

java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal
GTPEcalClusterer.java 840 -> 841
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/GTPEcalClusterer.java	2014-08-07 16:51:33 UTC (rev 840)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/GTPEcalClusterer.java	2014-08-07 17:01:37 UTC (rev 841)
@@ -16,25 +16,22 @@
 import org.lcsim.util.Driver;
 
 /**
- * Class
- * <code>GTPCalorimeterClusterer</code> processes events and converts hits into
- * clusters, where appropriate. It uses the modified 2014 clustering algorithm.
- *
+ * Class <code>GTPCalorimeterClusterer</code> processes events and converts hits
+ * into clusters, where appropriate. It uses the modified 2014 clustering algorithm.<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.
- *
+ * cluster energy that exceeds another tunable minimum threshold.<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
  */
 public class GTPEcalClusterer extends Driver {
-
     /**
      * <b>calorimeter</b><br/><br/>
      * <code>private HPSEcal3 <b>calorimeter</b></code><br/><br/>
@@ -48,14 +45,14 @@
      * <code>
      * Detector</code> object for this run.
      */
-    String ecalName;
+    private String ecalName;
     /**
      * <b>clusterCollectionName</b><br/><br/>
      * <code>private String <b>clusterCollectionName</b></code><br/><br/>
      * The name of the LCIO collection name in which the clusters will be
      * stored.
      */
-    String clusterCollectionName = "EcalClusters";
+    private String clusterCollectionName = "EcalClusters";
     /**
      * <b>clusterWindow</b><br/><br/>
      * <code>private int <b>clusterWindow</b></code><br/><br/>
@@ -63,7 +60,7 @@
      * after a given cycle that should be considered when checking if a cluster
      * is a local maximum in space-time.
      */
-    int clusterWindow = 2;
+    private int clusterWindow = 2;
     /**
      * <b>hitBuffer</b><br/><br/>
      * <code>private LinkedList<List<CalorimeterHit>> <b>hitBuffer</b></code><br/><br/>
@@ -77,7 +74,7 @@
      * The name of LCIO collection containing the calorimeter hits that are to
      * be used for clustering.
      */
-    String ecalCollectionName;
+    private String ecalCollectionName;
     /**
      * <b>neighborMap</b><br/><br/>
      * <code>private NeighborMap <b>neighborMap</b></code><br/><br/>
@@ -92,11 +89,16 @@
      * The minimum energy required for a hit to be considered as a cluster
      * center. Hits with energy less than this value will be ignored.
      */
-    double seedEnergyThreshold = 0.05;
-
+    private double seedEnergyThreshold = 0.05;
     /**
-     * <b>detectorChanged</b><br/><br/>
-     * <code>public void <b>detectorChanged</b>(Detector detector)</code><br/><br/>
+     * <b>limitClusterRange</b><br/><br/>
+     * <code>private boolean <b>limitClusterRange</b></code><br/><br/>
+     * Whether an asymmetric or symmetric window should be used for
+     * adding hits to a cluster.
+     */
+    private boolean limitClusterRange = false;
+    
+    /**
      * Initializes detector-dependent parameters for clustering. Method is
      * responsible for determining which crystals are valid cluster centers
      * (stored in
@@ -112,14 +114,12 @@
     public void detectorChanged(Detector detector) {
         // Get the calorimeter object.
         calorimeter = (HPSEcal3) detector.getSubdetector(ecalName);
-
+        
         // Get a map to associate crystals with their neighbors.
         neighborMap = calorimeter.getNeighborMap();
     }
-
+    
     /**
-     * <b>getClusters</b><br/><br/>
-     * <code>public List<HPSEcalCluster> <b>getClusters</b>()</code><br/><br/>
      * 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.
@@ -130,10 +130,10 @@
     public List<HPSEcalCluster> getClusters() {
         // Generate a list for storing clusters.
         List<HPSEcalCluster> clusters = new ArrayList<HPSEcalCluster>();
-
+        
         // Get the list of hits at the current time in the event buffer.
         Map<Long, CalorimeterHit> currentHits = hitBuffer.get(clusterWindow);
-
+        
         // 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.
@@ -141,45 +141,48 @@
         for (Long currentID : currentHits.keySet()) {
             // Get the actual hit object.
             CalorimeterHit currentHit = currentHits.get(currentID);
-
+            
             // Store the energy of the current hit.
             double currentEnergy = currentHit.getRawEnergy();
-
+            
             // If the hit energy is lower than the minimum threshold,
             // then we immediately reject this hit as a possible cluster.
             if (currentEnergy < seedEnergyThreshold) {
                 continue seedLoop;
             }
-
+            
             // Store the crystals that are part of this potential cluster, 
             // starting with the cluster seed candidate.
             HPSEcalCluster cluster = new HPSEcalCluster(currentHit);
             cluster.addHit(currentHit);
-
+            
             // Get the set of neighbors for this hit.
             Set<Long> neighbors = neighborMap.get(currentHit.getCellID());
-
+            
             // Sort through each event stored in the buffer.
-            addLoop:
+            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) {
                         continue seedLoop;
-                    } // If the buffer hit is smaller, then add its energy
+                    }
+                    
+                    // If the buffer hit is smaller, then add its energy
                     // to the cluster total energy.
                     else {
-                        cluster.addHit(bufferHit);
+                    	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.
@@ -188,33 +191,37 @@
                     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) {
                             continue seedLoop;
-                        } // If the buffer neighbor hit is smaller, then
+                        }
+                        
+                        // If the buffer neighbor hit is smaller, then
                         // add its energy to the cluster total energy.
                         else {
-                            cluster.addHit(neighborHit);
+                        	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);
         }
-
+        
         // Return the generated list of clusters.
         return clusters;
     }
-
+    
     /**
-     * <b>process</b><br/><br/>
-     * <code>public void <b>process</b>(EventHeader event)</code><br/><br/>
      * 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.
@@ -228,30 +235,28 @@
         if (event.hasCollection(CalorimeterHit.class, ecalCollectionName)) {
             // Get the list of calorimeter hits from the event.
             List<CalorimeterHit> hitList = event.get(CalorimeterHit.class, ecalCollectionName);
-
+            
             // Store each hit in a set by its cell ID so that it may be
             // easily acquired later.
             HashMap<Long, CalorimeterHit> hitMap = new HashMap<Long, CalorimeterHit>();
             for (CalorimeterHit hit : hitList) {
                 hitMap.put(hit.getCellID(), hit);
             }
-
+            
             // Remove the last event from the hit buffer and add the new one.
             hitBuffer.removeLast();
             hitBuffer.addFirst(hitMap);
-
+            
             // Run the clustering algorithm on the buffer.
             List<HPSEcalCluster> clusterList = getClusters();
-
+            
             // Store the cluster list in the LCIO collection.
             int flag = 1 << LCIOConstants.CLBIT_HITS;
             event.put(clusterCollectionName, clusterList, HPSEcalCluster.class, flag);
         }
     }
-
+    
     /**
-     * <b>setEcalCollectionName</b><br/><br/>
-     * <code>public void <b>setEcalCollectionName</b>(String ecalCollectionName)</code><br/><br/>
      * Sets the name of the LCIO collection containing the calorimeter hits
      * which should be used for clustering.
      *
@@ -260,10 +265,8 @@
     public void setEcalCollectionName(String ecalCollectionName) {
         this.ecalCollectionName = ecalCollectionName;
     }
-
+    
     /**
-     * <b>setClusterCollectionName</b><br/><br/>
-     * <code>public void <b>setClusterCollectionName</b>(String clusterCollectionName)</code><br/><br/>
      * Sets the name of the LCIO collection in which the clusters should be
      * stored.
      *
@@ -272,10 +275,8 @@
     public void setClusterCollectionName(String clusterCollectionName) {
         this.clusterCollectionName = clusterCollectionName;
     }
-
+    
     /**
-     * <b>setEcalName</b><br/><br/>
-     * <code>public void <b>setEcalName</b>(String ecalName)</code><br/><br/>
      * Sets the name of the calorimeter sub-detector stored in the
      * <code>Detector</code> object that is to be used for this run.
      *
@@ -284,10 +285,8 @@
     public void setEcalName(String ecalName) {
         this.ecalName = ecalName;
     }
-
+    
     /**
-     * <b>setClusterWindow</b><br/><br/>
-     * <code>public void <b>setClusterWindow</b>(int clusterWindow)</code><br/><br/>
      * 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
@@ -304,15 +303,28 @@
         // The cluster window of must always be at least zero.
         if (clusterWindow < 0) {
             this.clusterWindow = 0;
-        } // If the cluster window is non-zero, then store it.
+        }
+        
+        // If the cluster window is non-zero, then store it.
         else {
             this.clusterWindow = clusterWindow;
         }
     }
-
+    
     /**
-     * <b>setSeedEnergyThreshold</b><br/><br/>
-     * <code>public void <b>setSeedEnergyThreshold</b>(double seedEnergyThreshold)</code><br/><br/>
+     * 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.
+     */
+    public void setLimitClusterRange(boolean limitClusterRange) {
+    	this.limitClusterRange = limitClusterRange;
+    }
+    
+    /**
      * Sets the minimum energy threshold below which hits will not be considered
      * as cluster centers.
      *
@@ -328,10 +340,8 @@
             this.seedEnergyThreshold = seedEnergyThreshold;
         }
     }
-
+    
     /**
-     * <b>startOfData</b><br/><br/>
-     * <code>public void <b>startOfData</b>()</code><br/><br/>
      * Initializes the clusterer. This ensures that the collection name for the
      * calorimeter hits from which clusters are to be generated, along with the
      * calorimeter name, have been defined. Method also initializes the event
@@ -344,15 +354,15 @@
         if (ecalCollectionName == null) {
             throw new RuntimeException("The parameter ecalCollectionName was not set!");
         }
-
+        
         // Make sure that there is a calorimeter detector.
         if (ecalName == null) {
             throw new RuntimeException("The parameter ecalName was not set!");
         }
-
+        
         // 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
SVNspam 0.1