Print

Print


Commit in hps-java/src/main/java/org/lcsim/hps/recon/tracking on MAIN
HPSNearestNeighborRMS.java+265added 1.1
Nearest Neighbor clustering algorithm for HPS tracker

hps-java/src/main/java/org/lcsim/hps/recon/tracking
HPSNearestNeighborRMS.java added at 1.1
diff -N HPSNearestNeighborRMS.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ HPSNearestNeighborRMS.java	22 Apr 2012 21:14:57 -0000	1.1
@@ -0,0 +1,265 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.hps.recon.tracking;
+
+import java.util.*;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.base.BaseTrackerHit;
+
+/**
+ *
+ * @author mgraham
+ */
+public class HPSNearestNeighborRMS implements HPSClusteringAlgorithm {
+  
+    private static String _NAME = "NearestNeighborRMS";
+    private double _seed_threshold;
+    private double _neighbor_threshold;
+    private double _cluster_threshold;    
+
+    /**
+     * Instantiate NearestNeighborRMS with specified thresholds.
+     * Seed threshold is the minimum charge to initiate a cluster.  Neighbor
+     * threshold is the minimum charge to add a neighboring cell to a cluster.
+     * Cluster threshold is minimum charge of the entire cluster.
+     * All thresholds are in units of RMS noise of the channel(s).
+     *
+     * @param seed_threshold seed threshhold
+     * @param neighbor_threshold neighbor threshold
+     * @param cluster_threshold cluster threshold
+     */
+    public HPSNearestNeighborRMS(double seed_threshold, double neighbor_threshold, double cluster_threshold) {
+        _seed_threshold = seed_threshold;
+        _neighbor_threshold = neighbor_threshold;
+        _cluster_threshold = cluster_threshold;       
+    }
+
+    /**
+     * Instantiate NearestNeighborRMS with default thresholds:
+     *
+     * seed_threshold = 4*RMS noise
+     * neighbor_threshold = 3*RMS noise
+     * cluster_threshold = 4*RMS noise
+     */
+    public HPSNearestNeighborRMS() {
+        this(4.0, 3.0, 4.0);
+    }
+
+    /**
+     * Set the seed threshold.  Units are RMS noise.
+     *
+     * @param seed_threshold seed threshold
+     */
+    public void setSeedThreshold(double seed_threshold) {
+        _seed_threshold = seed_threshold;
+    }
+
+    /**
+     * Set the neighbor threshold.  Units are RMS noise.
+     *
+     * @param neighbor_threshold neighbor threshold
+     */
+    public void setNeighborThreshold(double neighbor_threshold) {
+        _neighbor_threshold = neighbor_threshold;
+    }
+
+    /**
+     * Set the cluster threshold.  Units are RMS noise.
+     *
+     * @param cluster_threshold cluster threshold
+     */
+    public void setClusterThreshold(double cluster_threshold) {
+        _cluster_threshold = cluster_threshold;
+    }
+
+    /**
+     * Return the seed threshold.  Units are RMS noise.
+     *
+     * @return seed threshold
+     */
+    public double getSeedThreshold() {
+        return _seed_threshold;
+    }
+
+    /**
+     * Return the neighbor threshold.  Units are RMS noise.
+     *
+     * @return neighbor threshold
+     */
+    public double getNeighborThreshold() {
+        return _neighbor_threshold;
+    }
+
+    /**
+     * Return the cluster threshold.  Units are RMS noise.
+     *
+     * @return cluster threshold
+     */
+    public double getClusterThreshold() {
+        return _cluster_threshold;
+    }
+
+    /**
+     * Return the name of the clustering algorithm.
+     * 
+     * @return _name clusting algorithm name
+     */
+    public String getName() {
+        return _NAME;
+    }
+
+    /**
+     * Find clusters using the nearest neighbor algorithm.
+     *    
+     * @param base_hits List of RawTrackerHits to be clustered
+     * @return list of clusters, with a cluster being a list of RawTrackerHits
+     */
+    public List<List<BaseTrackerHit>> findClusters(List<BaseTrackerHit> base_hits) {
+
+        //  Check that the seed threshold is at least as large as  the neighbor threshold
+        if (_seed_threshold < _neighbor_threshold) {
+            throw new RuntimeException("Tracker hit clustering error: seed threshold below neighbor threshold");
+        }
+
+        //  Create maps that show the channel status and relate the channel number to the raw hit and vice versa
+        int mapsize = 2 * base_hits.size();
+        Map<Integer, Boolean> clusterable = new HashMap<Integer, Boolean>(mapsize);
+        Map<BaseTrackerHit, Integer> hit_to_channel = new HashMap<BaseTrackerHit, Integer>(mapsize);
+        Map<Integer, BaseTrackerHit> channel_to_hit = new HashMap<Integer, BaseTrackerHit>(mapsize);
+
+        //  Create list of channel numbers to be used as cluster seeds
+        List<Integer> cluster_seeds = new ArrayList<Integer>();
+
+        //  Loop over the raw hits and construct the maps used to relate cells and hits, initialize the
+        //  clustering status map, and create a list of possible cluster seeds
+        for (BaseTrackerHit base_hit : base_hits) {
+            RawTrackerHit raw_hit=(RawTrackerHit) base_hit.getRawHits().get(0);
+            
+            // get the channel number for this hit
+            SiTrackerIdentifierHelper sid_helper = (SiTrackerIdentifierHelper) raw_hit.getIdentifierHelper();
+            IIdentifier id = raw_hit.getIdentifier();
+            int channel_number = sid_helper.getElectrodeValue(id);
+
+            //  Check for duplicate RawTrackerHit
+            if (hit_to_channel.containsKey(raw_hit)) {
+                throw new RuntimeException("Duplicate hit: "+id.toString());
+            }
+
+            //  Check for duplicate RawTrackerHits or channel numbers
+            if (channel_to_hit.containsKey(channel_number)) {
+                throw new RuntimeException("Duplicate channel number: "+channel_number);
+            }
+
+            //  Add this hit to the maps that relate channels and hits
+            hit_to_channel.put(base_hit, channel_number);
+            channel_to_hit.put(channel_number, base_hit);
+
+            //  Get the signal from the readout chip
+            double signal = base_hit.getdEdx();
+            double noiseRMS = 666;   //need to get the noise from the calib. const. class
+
+            //  Mark this hit as available for clustering if it is above the neighbor threshold
+            clusterable.put(channel_number, signal/noiseRMS >= _neighbor_threshold);
+
+            //  Add this hit to the list of seeds if it is above the seed threshold
+            if (signal/noiseRMS >= _seed_threshold) {
+                cluster_seeds.add(channel_number);
+            }
+        }
+
+        //  Create a list of clusters
+        List<List<BaseTrackerHit>> cluster_list = new ArrayList<List<BaseTrackerHit>>();
+
+        //  Now loop over the cluster seeds to form clusters
+        for (int seed_channel : cluster_seeds) {
+
+            //  First check if this hit is still available for clustering
+            if (!clusterable.get(seed_channel)) continue;
+
+            //  Create a new cluster
+            List<BaseTrackerHit> cluster = new ArrayList<BaseTrackerHit>();
+            double cluster_signal = 0.;
+            double cluster_noise_squared = 0.;
+
+            //  Create a queue to hold channels whose neighbors need to be checked for inclusion
+            LinkedList<Integer> unchecked = new LinkedList<Integer>();
+
+            //  Add the seed channel to the unchecked list and mark it as unavailable for clustering
+            unchecked.addLast(seed_channel);
+            clusterable.put(seed_channel, false);
+
+            //  Check the neighbors of channels added to the cluster
+            while (unchecked.size() > 0) {
+
+                //  Pull the next channel off the queue and add it's hit to the cluster
+                int clustered_cell = unchecked.removeFirst();
+                cluster.add(channel_to_hit.get(clustered_cell));
+                cluster_signal += channel_to_hit.get(clustered_cell).getdEdx();
+//                cluster_noise_squared += Math.pow(readout_chip.getChannel(clustered_cell).computeNoise(electrodes.getCapacitance(clustered_cell)),2);
+                cluster_noise_squared +=0;  //need to get the noise from the calib. const. class
+                //  Get the neigbor channels
+//                Set<Integer> neighbor_channels = electrodes.getNearestNeighborCells(clustered_cell);
+                Set<Integer> neighbor_channels = getNearestNeighborCells(clustered_cell);
+
+                //   Now loop over the neighbors and see if we can add them to the cluster
+                for (int channel : neighbor_channels) {
+
+                    //  Get the status of this channel
+                    Boolean addhit = clusterable.get(channel);
+
+                    //  If the map entry is null, there is no raw hit for this channel
+                    if (addhit == null) continue;
+
+                    //  Check if this neighbor channel is still available for clustering
+                    if (!addhit) continue;
+
+                    //  Add channel to the list of unchecked clustered channels
+                    //  and mark it unavailable for clustering
+                    unchecked.addLast(channel);
+                    clusterable.put(channel, false);
+
+                }  // end of loop over neighbor cells
+            }  // end of loop over unchecked cells
+
+            //  Finished with this cluster, check cluster threshold and add it to the list of clusters
+            if (cluster.size() > 0 &&
+                cluster_signal/Math.sqrt(cluster_noise_squared) > _cluster_threshold)
+            {
+                cluster_list.add(cluster);
+            }
+
+        }  //  End of loop over seeds
+
+        //  Finished finding clusters
+        return cluster_list;
+    }  
+    
+    
+    public int getNeighborCell(int cell, int ncells_0, int ncells_1)
+    {
+        int neighbor_cell = cell + ncells_0;
+        if (isValidCell(neighbor_cell)) return neighbor_cell;
+        else return -1;
+    }
+    
+    public Set<Integer> getNearestNeighborCells(int cell)
+    {
+        Set<Integer> neighbors = new HashSet<Integer>();
+        for (int ineigh = -1 ; ineigh <= 1; ineigh=ineigh+2)
+        {
+            int neighbor_cell = getNeighborCell(cell,ineigh,0);
+            if (isValidCell(neighbor_cell)) neighbors.add(neighbor_cell);
+        }
+        return neighbors;
+    }
+    
+    
+    public boolean isValidCell(int cell)
+    {
+        return (cell >= 0 && cell < HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR);
+    }
+}
CVSspam 0.2.12


Use REPLY-ALL to reply to list

To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1