Print

Print


Author: [log in to unmask]
Date: Wed Jan 14 08:35:17 2015
New Revision: 1924

Log:
updated recon clusterer to use basecluster

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

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/cluster/ReconClusterer.java	Wed Jan 14 08:35:17 2015
@@ -1,8 +1,4 @@
 package org.hps.recon.ecal.cluster;
-
-import hep.physics.vec.BasicHep3Vector;
-import hep.physics.vec.Hep3Vector;
-import hep.physics.vec.VecOp;
 
 import java.awt.Point;
 import java.util.ArrayList;
@@ -13,12 +9,13 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.hps.recon.ecal.HPSEcalClusterIC;
-import org.lcsim.detector.IGeometryInfo;
-import org.lcsim.detector.solids.Trd;
+import org.hps.recon.ecal.cluster.AbstractClusterer;
+import org.hps.recon.ecal.cluster.ClusterType;
+import org.hps.recon.ecal.cluster.Clusterer;
 import org.lcsim.event.CalorimeterHit;
 import org.lcsim.event.Cluster;
 import org.lcsim.event.EventHeader;
+import org.lcsim.event.base.BaseCluster;
 
 /**
  * <p>
@@ -92,7 +89,7 @@
         }
         clusterEnergyThreshold = getCuts().getValue("clusterEnergyThreshold");
         minTime = getCuts().getValue("minTime");
-        timeWindow = getCuts().getValue("timeWindow");
+        timeWindow = getCuts().getValue("timeWindow");      
     }
     
     /**
@@ -102,16 +99,12 @@
     List<CalorimeterHit> getRejectedHitList() {
         return this.rejectedHitList;
     }
-
-    public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits) {
-
+    
+   
+    public List<Cluster> createClusters(EventHeader event, List<CalorimeterHit> hits) {	
         // Create a list to store the event hits in.
-        List<CalorimeterHit> hitList = new ArrayList<CalorimeterHit>();
-        List<CalorimeterHit> baseList = hits;
-        for (CalorimeterHit r : baseList) {
-            hitList.add(r);
-        }
-
+        List<CalorimeterHit> hitList = hits;
+        
         // Create a list to store the newly created clusters in.
         ArrayList<Cluster> clusterList = new ArrayList<Cluster>();
 
@@ -149,17 +142,21 @@
         for (CalorimeterHit hit : hitList) {
             hitMap.put(hit.getCellID(), hit);
         }
+        
+        // Create a map to connect a seed hit to its cluster.
+        Map<CalorimeterHit, BaseCluster> seedToCluster = new HashMap<CalorimeterHit,BaseCluster>();
 
         // Map a crystal to a list of all clusters in which it is a member.
         Map<CalorimeterHit, List<CalorimeterHit>> commonHits = new HashMap<CalorimeterHit, List<CalorimeterHit>>();
 
         // Map a crystal to the seed of the cluster of which it is a member.
-        HashMap<CalorimeterHit, CalorimeterHit> hitSeedMap = new HashMap<CalorimeterHit, CalorimeterHit>();
+        HashMap<CalorimeterHit, CalorimeterHit> hitToSeed = new HashMap<CalorimeterHit, CalorimeterHit>();
 
         // Loop through all calorimeter hits to locate seeds and perform
-        // first pass calculations for component and common hits.
+        // first pass calculations for component and common hits.        
         for (int ii = 0; ii <= hitList.size() - 1; ii++) {
             CalorimeterHit hit = hitList.get(ii);
+           
             // Get the set of all neighboring crystals to the current hit.
             Set<Long> neighbors = neighborMap.get(hit.getCellID());
 
@@ -174,7 +171,7 @@
                 CalorimeterHit neighborHit = hitMap.get(neighbor);
 
                 // If it exists, add it to the list.
-                if (neighborHit != null) {
+                if (neighborHit != null && hitList.contains(neighborHit)) {
                     neighborHits.add(neighborHit);
                 }
             }
@@ -191,31 +188,41 @@
                     break seedHitLoop;
                 }
             }
-            // If this hit is a seed hit, just map it to itself.
-            if (isSeed && hit.getCorrectedEnergy() >= seedEnergyThreshold) {
-                hitSeedMap.put(hit, hit);
-            }
-
-            // If this hit is a local maximum but does not pass seed threshold,
-            // remove from hit list and do not cluster.
-            else if (isSeed && hit.getCorrectedEnergy() < seedEnergyThreshold) {
-                hitList.remove(ii);
-                rejectedHitList.add(hit);
-                ii--;
-            }
+     
+            // Hit is a local maximum
+            if (isSeed){
+            	// Seed must pass minimum threshold
+            	if (hit.getCorrectedEnergy() >= seedEnergyThreshold)
+            	{
+            		// Create new cluster
+                    BaseCluster cluster = createBasicCluster();
+                    clusterList.add(cluster);
+                    seedToCluster.put(hit, cluster);
+                    hitToSeed.put(hit, hit);
+            		
+            	}
+            	// Seed does not pass minimum threshold
+            	else{
+                    rejectedHitList.add(hit);
+            		hitList.remove(ii);
+                    ii--;
+            	}            
+            }// end if isSeed
 
             // If this hit is not a seed hit, see if it should be
             // attached to any neighboring seed hits.
-            else {
+            else {     	
                 // Sort through the list of neighboring hits.
                 for (CalorimeterHit neighborHit : neighborHits) {
                     // Check whether the neighboring hit is a seed.
-                    if (hitSeedMap.get(neighborHit) == neighborHit) {
+                  //  if (seedToCluster.containsKey(neighborHit)) {
+                    if (hitToSeed.get(neighborHit) == neighborHit) {
+
                         // If the neighboring hit is a seed hit and the
                         // current hit has been associated with a cluster,
                         // then it is a common hit between its previous
                         // seed and the neighboring seed.
-                        if (hitSeedMap.containsKey(hit)) {
+                        if (hitToSeed.containsKey(hit)) {
                             // Check and see if a list of common seeds
                             // for this hit already exists or not.
                             List<CalorimeterHit> commonHitList = commonHits.get(hit);
@@ -228,7 +235,7 @@
                             // Add the neighbors to the seeds to set of
                             // common seeds.
                             commonHitList.add(neighborHit);
-                            commonHitList.add(hitSeedMap.get(hit));
+                            commonHitList.add(hitToSeed.get(hit));
 
                             // Put the common seed list back into the set.
                             commonHits.put(hit, commonHitList);
@@ -239,7 +246,7 @@
                         // associate it with the neighboring seed and note
                         // that it has been clustered.
                         else {
-                            hitSeedMap.put(hit, neighborHit);
+                            hitToSeed.put(hit, neighborHit);
                         }
                     }
                 }
@@ -249,7 +256,7 @@
         // Performs second pass calculations for component hits.
         secondaryHitsLoop: for (CalorimeterHit secondaryHit : hitList) {
             // Look for hits that already have an associated seed/clustering.
-            if (!hitSeedMap.containsKey(secondaryHit)) {
+            if (!hitToSeed.containsKey(secondaryHit)) {
                 continue secondaryHitsLoop;
             }
 
@@ -267,7 +274,7 @@
 
                 // If the neighboring crystal exists and is not already
                 // in a cluster, add it to the list of neighboring hits.
-                if (secondaryNeighborHit != null && !hitSeedMap.containsKey(secondaryNeighborHit)) {
+                if (secondaryNeighborHit != null && !hitToSeed.containsKey(secondaryNeighborHit)) {
                     secondaryNeighborHits.add(secondaryNeighborHit);
                 }
             }
@@ -278,20 +285,13 @@
                 // current secondary hit, then associate the neighboring
                 // hit with the current secondary hit's seed.
                 if (!equalEnergies(secondaryNeighborHit, secondaryHit)) {
-                    hitSeedMap.put(secondaryNeighborHit, hitSeedMap.get(secondaryHit));
-                } else {
-                    continue;
-                }
+                    hitToSeed.put(secondaryNeighborHit, hitToSeed.get(secondaryHit));
+                } else {continue;}
             }
         } // End component hits loop.
-
+        
         // Performs second pass calculations for common hits.
-        commonHitsLoop: for (CalorimeterHit clusteredHit : hitSeedMap.keySet()) {
-
-            // Seed hits are never common hits and can be skipped.
-            if (hitSeedMap.get(clusteredHit) == clusteredHit) {
-                continue commonHitsLoop;
-            }
+        commonHitsLoop: for (CalorimeterHit clusteredHit : hitToSeed.keySet()) {
 
             // Get the current clustered hit's neighboring crystals.
             Set<Long> clusteredNeighbors = neighborMap.get(clusteredHit.getCellID());
@@ -307,13 +307,13 @@
 
                 // If it exists, add it to the neighboring hit list.
 
-                if (clusteredNeighborHit != null && hitSeedMap.get(clusteredNeighborHit) != null) {
+                if (clusteredNeighborHit != null && hitToSeed.get(clusteredNeighborHit) != null) {
                     clusteredNeighborHits.add(clusteredNeighborHit);
                 }
             }
 
             // Get the seed hit associated with this clustered hit.
-            CalorimeterHit clusteredHitSeed = hitSeedMap.get(clusteredHit);
+            CalorimeterHit clusteredHitSeed = hitToSeed.get(clusteredHit);
 
             // Loop over the clustered neighbor hits.
             for (CalorimeterHit clusteredNeighborHit : clusteredNeighborHits) {
@@ -321,7 +321,7 @@
                 // is not already associated with the current clustered
                 // hit's seed.
 
-                if ((hitSeedMap.get(clusteredNeighborHit) != clusteredHitSeed)) {
+                if ((hitToSeed.get(clusteredNeighborHit) != clusteredHitSeed)) {
                     // Check for lowest energy hit and that comparison hit is not already common.
                     // If already common, this boundary is already accounted for.
                     if (!equalEnergies(clusteredHit, clusteredNeighborHit) && !commonHits.containsKey(clusteredNeighborHit)) {
@@ -338,7 +338,7 @@
                         // Add the neighbors to the seeds to set of
                         // common seeds.
                         commonHitList.add(clusteredHitSeed);
-                        commonHitList.add(hitSeedMap.get(clusteredNeighborHit));
+                        commonHitList.add(hitToSeed.get(clusteredNeighborHit));
 
                         // Put the common seed list back into the set.
                         commonHits.put(clusteredHit, commonHitList);
@@ -347,55 +347,69 @@
                 }
             }
         } // End common hits loop.
-
+        
         // Remove any common hits from the clustered hits collection.
         for (CalorimeterHit commonHit : commonHits.keySet()) {
-            hitSeedMap.remove(commonHit);
+            hitToSeed.remove(commonHit);
+            hitList.remove(commonHit);
         }
 
+        
+        /*
+         * All hits are sorted from above. The next part of the code is for 
+         * building the output cluster collections.
+         */
+        	// Add all hits except for common hits
+        	for (CalorimeterHit ihit : hitList)
+        	{
+        		CalorimeterHit iseed = hitToSeed.get(ihit);
+        		BaseCluster icluster = seedToCluster.get(iseed);
+        		icluster.addHit(ihit);
+        	}
+        
+        	// Add common hits
+        	for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> commHit : commonHits.entrySet())
+        	{
+        		CalorimeterHit seedA = commHit.getValue().get(0);
+        		CalorimeterHit seedB = commHit.getValue().get(1);
+        		double eclusterA = seedToCluster.get(seedA).getEnergy();
+        		double eclusterB = seedToCluster.get(seedB).getEnergy();       	
+        		double fractionA = eclusterA / (eclusterA + eclusterB);
+        		double fractionB = eclusterB / (eclusterA + eclusterB);        	
+        		double hitcontributionA = commHit.getKey().getCorrectedEnergy()*fractionA;
+        		double hitcontributionB = commHit.getKey().getCorrectedEnergy()*fractionB;
+        	
+        		BaseCluster clusterA = seedToCluster.get(seedA);
+        		BaseCluster clusterB = seedToCluster.get(seedB);
+
+        		clusterA.addHit(commHit.getKey(), hitcontributionA);
+        		clusterB.addHit(commHit.getKey(), hitcontributionB);
+        	}
+    
+        	// Remove clusters that do not pass cluster threshold and add to rejectedHitList.
+        	for (int j=0; j <= clusterList.size()-1; j++)
+        		{	
+        		Cluster checkcluster = clusterList.get(j);        	
+        		if (checkcluster.getEnergy() < clusterEnergyThreshold) {
+        			List<CalorimeterHit> clusterHits= checkcluster.getCalorimeterHits();
+        			for (CalorimeterHit nhit : clusterHits){
+        				rejectedHitList.add(nhit);
+        			}
+        			clusterList.remove(checkcluster);
+        			j--;
+        		} 
+        		else {       			
+        			continue;
+        		}
+        	}
+        return clusterList;
+    }
+        //TODO: Move this to a separate position/cluster calculator
         /*
          * All hits are sorted from above. The next part of the code is for calculating energies and
          * positions.
          */
-
-        // Create map to contain the total energy of each cluster
-        Map<CalorimeterHit, Double> seedEnergy = new HashMap<CalorimeterHit, Double>();
-
-        // Get energy of each cluster, excluding common hits
-        for (CalorimeterHit iSeed : hitList) {
-            if (hitSeedMap.get(iSeed) == iSeed) {
-                seedEnergy.put(iSeed, 0.0);
-            }
-        }
-
-        // Putting total cluster energies excluding common hit energies into map with seed keys
-        for (Map.Entry<CalorimeterHit, CalorimeterHit> entry : hitSeedMap.entrySet()) {
-            CalorimeterHit eSeed = entry.getValue();
-            double eEnergy = seedEnergy.get(eSeed);
-            eEnergy += entry.getKey().getCorrectedEnergy();
-            seedEnergy.put(eSeed, eEnergy);
-        }
-
-        // Create a map to contain final uncorrected cluster energies including common hit
-        // distributions.
-        Map<CalorimeterHit, Double> seedEnergyTot = seedEnergy;
-
-        // Distribute common hit energies with clusters
-        for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> entry1 : commonHits.entrySet()) {
-            CalorimeterHit commonCell = entry1.getKey();
-            CalorimeterHit seedA = entry1.getValue().get(0);
-            CalorimeterHit seedB = entry1.getValue().get(1);
-            double eFractionA = (seedEnergy.get(seedA)) / ((seedEnergy.get(seedA) + seedEnergy.get(seedB)));
-            double eFractionB = (seedEnergy.get(seedB)) / ((seedEnergy.get(seedA) + seedEnergy.get(seedB)));
-            double currEnergyA = seedEnergyTot.get(seedA);
-            double currEnergyB = seedEnergyTot.get(seedB);
-            currEnergyA += eFractionA * commonCell.getCorrectedEnergy();
-            currEnergyB += eFractionB * commonCell.getCorrectedEnergy();
-
-            seedEnergyTot.put(seedA, currEnergyA);
-            seedEnergyTot.put(seedB, currEnergyB);
-        }
-
+/*
         // Cluster Position as per HPS Note 2014-001
         // Create map with seed as key to position/centroid value
         Map<CalorimeterHit, double[]> rawSeedPosition = new HashMap<CalorimeterHit, double[]>();
@@ -465,66 +479,8 @@
             rawSeedPosition.put(seedP, rawPosition);
 
         }// end of cluster position calculation
-
-        /*
-         * Outputs results to cluster collection.
-         */
-        // Only write output if something actually exists.
-        if (hitMap.size() != 0) {
-            // Loop over seeds
-            for (Map.Entry<CalorimeterHit, CalorimeterHit> entry2 : hitSeedMap.entrySet()) {
-                if (entry2.getKey() == entry2.getValue()) {
-                    if (seedEnergyTot.get(entry2.getKey()) < clusterEnergyThreshold) {
-                        // Not clustered for not passing cuts
-                        rejectedHitList.add(entry2.getKey());
-                    }
-
-                    else {
-                        
-                        // FIXME: All of the following should be converted to use the BaseCluster API. --JM
-                        
-                        // New cluster
-                        HPSEcalClusterIC cluster = new HPSEcalClusterIC(entry2.getKey());
-                        cluster.setType(this.getClusterTypeEncoding());
-                        clusterList.add(cluster);
-                        // Loop over hits belonging to seeds
-                        for (Map.Entry<CalorimeterHit, CalorimeterHit> entry3 : hitSeedMap.entrySet()) {
-                            if (entry3.getValue() == entry2.getValue()) {
-                                if (rejectedHitList.contains(entry2.getValue())) {
-                                    rejectedHitList.add(entry3.getKey());
-                                } else {
-                                    // Add hit to cluster
-                                    cluster.addHit(entry3.getKey());
-                                }
-                            }
-                        }
-
-                        for (Map.Entry<CalorimeterHit, List<CalorimeterHit>> entry4 : commonHits.entrySet()) {
-                            if (entry4.getValue().contains(entry2.getKey())) {
-                                // Add shared hits for energy distribution between clusters
-                                cluster.addSharedHit(entry4.getKey());
-                                // fixes bug for SIO Writer?
-                                cluster.addHit(entry4.getKey());
-                            }
-                        }
-
-                        // Input uncorrected cluster energies
-                        if (seedEnergyTot.values().size() > 0) {
-                            cluster.setEnergy(seedEnergyTot.get(entry2.getKey()));
-                            cluster.setUncorrectedEnergy(seedEnergyTot.get(entry2.getKey()));
-                        }
-
-                        // Input uncorrected cluster positions.
-                        cluster.setRawPosition(rawSeedPosition.get(entry2.getKey()));
-
-                    }// End checking thresholds and write out.
-                }
-            } // End cluster loop
-            // System.out.println("Number of clusters: "+clusterList.size());
-        } // End event output loop.        
-        return clusterList;
-    }
-    
+*/
+
     private static class EnergyComparator implements Comparator<CalorimeterHit> {
         /**
          * Compares the first hit with respect to the second. This method will compare hits first by
@@ -548,10 +504,8 @@
             // Perform the energy comparison. The higher energy hit
             // will be ordered first.
             if (e[0] < e[1]) { 
-                // FIXME: This should return -1 instead.
                 return 1;
             } else if (e[0] > e[1]) {
-                // FIXME: This should return 1.
                 return -1;
             }