lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.1 -r1.2
--- PixelHitMaker.java 24 Apr 2009 01:22:58 -0000 1.1
+++ PixelHitMaker.java 30 Apr 2009 22:13:13 -0000 1.2
@@ -17,6 +17,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -61,8 +62,9 @@
// Identifier helper (reset once per sensor)
SiTrackerIdentifierHelper _sid_helper;
- // Temporary map connecting hits to pixel numbers for sake of speed (reset once per sensor)
+ // Temporary maps connecting hits to pixel numbers for sake of speed (reset once per sensor)
Map<RawTrackerHit,Integer> _pixel_map = new HashMap<RawTrackerHit,Integer>();
+ Map<Integer,RawTrackerHit> _pixel_map_inv = new HashMap<Integer,RawTrackerHit>();
/** Creates a new instance of Tracker1DHitMaker */
public PixelHitMaker(SiSensorSim simulation, ReadoutChip readout_chip)
@@ -146,6 +148,7 @@
// Get SiTrackerIdentifierHelper for this sensor and refresh the pixel map used to increase speed
_sid_helper = (SiTrackerIdentifierHelper)sensor.getIdentifierHelper();
_pixel_map.clear();
+ _pixel_map_inv.clear();
// Get hits for this sensor
IReadout ro = sensor.getReadout();
@@ -158,7 +161,15 @@
// get id and create pixel map, get electrodes.
IIdentifier id = raw_hit.getIdentifier();
- _pixel_map.put(raw_hit,_sid_helper.getElectrodeValue(id));
+ int pixel_number = _sid_helper.getElectrodeValue(id);
+
+ // Check for duplicates
+ if (_pixel_map.containsKey(raw_hit) || _pixel_map_inv.containsKey(pixel_number))
+ throw new RuntimeException("Duplicate hit or cell number");
+
+ // Add this hit to the pixel maps
+ _pixel_map.put(raw_hit, pixel_number);
+ _pixel_map_inv.put(pixel_number, raw_hit);
// Get electrodes and check that they are pixels
//System.out.println("proc raw hit from: " + DetectorElementStore.getInstance().find(raw_hit.getIdentifier()).get(0).getName());
@@ -189,46 +200,77 @@
// Make hits for an electrode
public List<SiTrackerHit> makeHits(SiSensorElectrodes electrodes, List<RawTrackerHit> raw_hits)
{
-
-// System.out.println("Clustering electrodes: "+electrodes_id);
-
+ // 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 a list for the clustered hits
List<SiTrackerHit> hits = new ArrayList<SiTrackerHit>();
+
+ // Create list of seed candidates and map showing hit status (true = available for clustering)
+ List<RawTrackerHit> cluster_seeds = new ArrayList<RawTrackerHit>();
+ Map<Integer, Boolean> clusterable = new HashMap<Integer, Boolean>();
- List<RawTrackerHit> unclustered_rawhits = new ArrayList<RawTrackerHit>(raw_hits);
-
- for (RawTrackerHit raw_hit : raw_hits)
- {
-
+ // Loop over the raw hits and check if they should be added to the unclustered and/or seed lists
+ for (RawTrackerHit raw_hit : raw_hits) {
+
+ // Get the signal/noise for this hit
int pixel_number = _pixel_map.get(raw_hit);
double signal = _readout_chip.decodeCharge(raw_hit);
double noise = _readout_chip.getChannel(pixel_number).computeNoise(electrodes.getCapacitance(pixel_number));
-
- if (signal/noise > _seed_threshold && unclustered_rawhits.contains(raw_hit))
- {
-
-// System.out.println("Creating new cluster, # Raw hits on electrodes is: "+hits.size());
-
+ double SNR = signal / noise;
+
+ // Mark this hit as available for clustering if it is above the neighbor threshold
+ clusterable.put(pixel_number, SNR > _neighbor_threshold);
+
+ // Add this hit to the list of seeds if appropriate
+ if (SNR > _seed_threshold) cluster_seeds.add(raw_hit);
+ }
+
+ // Now loop over the cluster seeds to form clusters
+ for (RawTrackerHit raw_hit : cluster_seeds) {
+
+ // First check if this hit is still available for clustering
+ int raw_pixel_number = _pixel_map.get(raw_hit);
+ if (clusterable.get(raw_pixel_number)) {
+
+ // Create a new cluster and add the hit to it
List<RawTrackerHit> cluster = new ArrayList<RawTrackerHit>();
- List<RawTrackerHit> clustered_hits = new ArrayList<RawTrackerHit>();
-
- clustered_hits.add(raw_hit);
-
- while (clustered_hits.size() != 0)
- {
- cluster.addAll(clustered_hits);
- unclustered_rawhits.removeAll(clustered_hits);
- clustered_hits = neighborHits(clustered_hits,unclustered_rawhits,electrodes);
-
-// System.out.println(" Cluster size: "+cluster.size());
-// System.out.println(" # Unclustered hits: "+unclustered_hits.size());
-// System.out.println(" # neighbors found: "+clustered_hits.size());
+
+ // Create a queue to hold hits whose neighbors need to be checked for inclusion
+ LinkedList<RawTrackerHit> unchecked = new LinkedList<RawTrackerHit>();
+
+ // Add the seed hit and mark it as unavailable for clustering
+ unchecked.addLast(raw_hit);
+ clusterable.put(raw_pixel_number, false);
+
+ // Check the neighbors of hits added to the cluster
+ while (unchecked.size() > 0) {
+
+ // Pull the next hit off the queue and add it to the cluster
+ RawTrackerHit clusteredhit = unchecked.removeFirst();
+ cluster.add(clusteredhit);
+
+ // Get the neigbor cells
+ Set<Integer> neighbor_cells = electrodes.getNearestNeighborCells(_pixel_map.get(clusteredhit));
+
+ // Now loop over the neighbors and see if we can add them to the cluster
+ for (int cell : neighbor_cells) {
+
+ // First see if this neighbor cell is in our clusterable hit map
+ if (clusterable.containsKey(cell)) {
+
+ // Now check if this neighbor cell is still available for clustering
+ if (clusterable.get(cell)) {
+
+ // Add hit to the list of unchecked cluster hits and mark it unavailable for clustering
+ unchecked.addLast(_pixel_map_inv.get(cell));
+ clusterable.put(cell, false);
+ }
+ }
+ }
}
-
-// if (cluster.size() > 10)
-// {
-// System.out.println("Cluster size: "+cluster.size());
-// }
-
+
// Make a TrackerHit from the cluster if it meets max cluster size requirement
if (cluster.size() <= _max_cluster_npixels)
{
@@ -244,33 +286,7 @@
}
return hits;
- }
-
-
- // Find the hits neigboring a cluster
- private List<RawTrackerHit> neighborHits(List<RawTrackerHit> clustered_hits, List<RawTrackerHit> unclustered_hits,
- SiSensorElectrodes electrodes)
- {
- List<RawTrackerHit> neighbor_hits = new ArrayList<RawTrackerHit>();
-
- for (RawTrackerHit seed_hit : clustered_hits)
- {
- Set<Integer> neighbor_cells = electrodes.getNearestNeighborCells(_pixel_map.get(seed_hit));
- for (RawTrackerHit hit : unclustered_hits)
- {
- int pixel_number = _pixel_map.get(hit);
- double signal = _readout_chip.decodeCharge(hit);
- double noise = _readout_chip.getChannel(pixel_number).computeNoise(electrodes.getCapacitance(pixel_number));
-
- if (neighbor_cells.contains(_pixel_map.get(hit)) && signal/noise > _neighbor_threshold)
- {
- neighbor_hits.add(hit);
- }
- }
- }
- return neighbor_hits;
- }
-
+ }
//Make the hit
private SiTrackerHitPixel makeTrackerHit(List<RawTrackerHit> cluster, SiSensorElectrodes electrodes)