Print

Print


Author: [log in to unmask]
Date: Wed Jan 21 17:23:33 2015
New Revision: 1964

Log:
Uploaded correct version of the GTP clustering algorithm.

Modified:
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/GTPClusterer.java

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	Wed Jan 21 17:23:33 2015
@@ -14,60 +14,66 @@
 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>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.<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/>
  * <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.
+ * 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 GTPClusterer extends AbstractClusterer {
         
     /**
-     * <b>seedEnergyThreshold</b><br/><br/>
-     * <code>private double <b>seedEnergyThreshold</b></code><br/><br/>
-     * The minimum energy required for a hit to be considered as a cluster
-     * center. Hits with energy less than this value will be ignored.
+     * The minimum energy required for a hit to be considered as a
+     * cluster center. Hits with energy less than this value will be
+     * ignored.
      */
     private double seedEnergyThreshold;
     
     /**
-     * <b>clusterWindow</b><br/><br/>
-     * <code>private int <b>clusterWindow</b></code><br/><br/>
-     * 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.
+     * 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.
      */
     private int clusterWindow;
     
     /**
-     * <b>hitBuffer</b><br/><br/>
-     * <code>private LinkedList<List<CalorimeterHit>> <b>hitBuffer</b></code><br/><br/>
-     * Stores a set of all the hits occurring in each clock cycle for the number
-     * of clock cycles that should be considered for clustering.
+     * Stores a set of all the hits occurring in each clock cycle for
+     * the number of clock cycles that should be considered for
+     * clustering.
      */
     private LinkedList<Map<Long, CalorimeterHit>> hitBuffer;
 
     /**
-     * <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;
     
+    /**
+     * Sets whether debug text should be written.
+     */
+    private boolean verbose = false;
+    
     GTPClusterer() {
-        super(new String[] { "seedEnergyThreshold", "clusterWindow" }, new double[] { 0.05, 2.});
+        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"));
@@ -87,10 +93,10 @@
     }
         
     /**
-     * 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.
-     *
+     * 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.
      */
@@ -101,24 +107,32 @@
         // Get the list of hits at the current time in the event buffer.
         Map<Long, CalorimeterHit> currentHits = hitBuffer.get(clusterWindow);
         
-        // DEBUG :: Print the cluster window.
-        System.out.printf("%n%nEvent:%n");
-        int window = (hitBuffer.size() - 1) / 2;
-        int bufferNum = 0;
-        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(currentHits.isEmpty()) { System.out.println("\tNo hits this event!"); }
+        // 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
@@ -128,10 +142,12 @@
             // Get the actual hit object.
             CalorimeterHit currentHit = currentHits.get(currentID);
             
-            // DEBUG :: Print the current cluster.
-            System.out.printf("Cluster Check:%n");
-        	System.out.printf("\t(%3d, %3d) --> %.4f%n", currentHit.getIdentifierFieldValue("ix"),
-        			currentHit.getIdentifierFieldValue("iy"), currentHit.getCorrectedEnergy(), currentHit.getRawEnergy());
+            // 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(), currentHit.getRawEnergy());
+            }
             
             // Store the energy of the current hit.
             double currentEnergy = currentHit.getRawEnergy();
@@ -139,7 +155,13 @@
             // If the hit energy is lower than the minimum threshold,
             // then we immediately reject this hit as a possible cluster.
             if (currentEnergy < seedEnergyThreshold) {
-            	System.out.printf("\tREJECT :: Does not exceed seed threshold %.4f.%n", 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;
             }
             
@@ -147,6 +169,8 @@
             // 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());
@@ -164,9 +188,16 @@
                     // is larger than then original hit. If it is, we may
                     // stop the comparison because this is not a cluster.
                     if (bufferHitEnergy > currentEnergy) {
-                    	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());
+                    	// 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;
                     }
                     
@@ -192,9 +223,16 @@
                         // If it is, we may stop the comparison because this
                         // is not a cluster.
                         if (neighborHitEnergy > currentEnergy) {
-                        	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());
+                        	// 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;
                         }
                         
@@ -214,12 +252,15 @@
             // Add the cluster to the list of clusters.
             clusters.add(cluster);
             
-            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());
+            // 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());
+	            }
             }
         }
         
@@ -228,10 +269,9 @@
     }
     
     /**
-     * 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.
-     *
+     * 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.
      */
     public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits) {
@@ -253,17 +293,15 @@
     }
                
     /**
-     * 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.
-     *
-     * @param clusterWindow - The number of additional clock cycles to include
-     * in the clustering checks. A negative value will be treated as zero.
+     * 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.
+     * @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.
@@ -281,19 +319,17 @@
      * 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.
+     * @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) {
         this.limitClusterRange = limitClusterRange;
     }
     
     /**
-     * Sets the minimum energy threshold below which hits will not be considered
-     * as cluster centers.
-     *
+     * Sets the minimum energy threshold below which hits will not be
+     * considered as cluster centers.
      * @param seedEnergyThreshold - The minimum energy for a cluster center.
      */
     void setSeedEnergyThreshold(double seedEnergyThreshold) {
@@ -306,7 +342,12 @@
             this.seedEnergyThreshold = seedEnergyThreshold;
         }
     }
-
+    
+    /**
+     * 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;