2 added + 6 modified, total 8 files
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -N ClusteringAlgorithm.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ClusteringAlgorithm.java 7 May 2009 22:36:21 -0000 1.1
@@ -0,0 +1,35 @@
+/*
+ * ClusteringAlgorithm.java
+ *
+ */
+
+package org.lcsim.recon.tracking.digitization.sisim;
+
+import java.util.List;
+
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.event.RawTrackerHit;
+
+/**
+ * Interface for a clustering algorithm that clusters hits on an electrodes.
+ *
+ * @author Richard Partridge
+ */
+public interface ClusteringAlgorithm {
+
+ /**
+ * Finds the clusters given a list of RawTrackerHits on a particular
+ * silicon sensor with electrodes given by SiSensorElectrodes. A list
+ * of clusters is returned, with each cluster being a list of RawTrackerHits
+ * the form the cluster.
+ *
+ * @param sensor sensor to cluster
+ * @param electodes electrodes on this sensor to cluster
+ * @param readout readout chip for these electrodes
+ * @param hits raw hits
+ * @return list of clusters, with each cluster being a list of RawTrackerHits
+ */
+ public List<List<RawTrackerHit>> findClusters(SiSensorElectrodes electrodes,
+ ReadoutChip readout, List<RawTrackerHit> hits);
+
+}
\ No newline at end of file
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -N NearestNeighbor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ NearestNeighbor.java 7 May 2009 22:36:21 -0000 1.1
@@ -0,0 +1,219 @@
+/*
+ * NearestNeighborClusteringAlgorithm.java
+ */
+package org.lcsim.recon.tracking.digitization.sisim;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.event.RawTrackerHit;
+
+/**
+ * This class uses a nearest neighbor algorithm to find clusters of hits on a
+ * set of silicon sensor electrodes (i.e., an instance of SiStrips or SiPixels).
+ *
+ * The algorithm first finds possible cluster seeds that are above the seed
+ * threshold. Starting from a seed, the neighbor strips/pixels are searched
+ * to see if we have hits above the neighbor threshold. Neighbor channels
+ * are added until we have a cluster where every neighboring channel for the
+ * cluster has charge lying below the neighbor threshold.
+ *
+ * Thresholds are specified in units of electrons.
+ *
+ * HashMaps are used to speed up the algorithm when there are large numbers
+ * of hits, and the algorithm is expected to scale linearly with the number
+ * of RawTrackerHits on the electrodes.
+ *
+ * @author Richard Partridge
+ */
+public class NearestNeighbor implements ClusteringAlgorithm {
+
+ private static String _NAME = "NearestNeighbor";
+ private double _seed_threshold;
+ private double _neighbor_threshold;
+
+ /**
+ * Instantiate NearestNeighborClusteringAlgorithm 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.
+ * All thresholds are in units of electrons.
+ *
+ * @param seed_threshold seed threhold
+ * @param neighbor_threshold neighbor threshold
+ */
+ public NearestNeighbor(double seed_threshold, double neighbor_threshold) {
+
+ _seed_threshold = seed_threshold;
+ _neighbor_threshold = neighbor_threshold;
+ }
+
+ /**
+ * Instantiate NearestNeighborClusteringAlgorithm with default thresholds:
+ *
+ * seed_threshold = 4000 electrons
+ * neighbor_threhold = 2000 electrons
+ */
+ public NearestNeighbor() {
+ this(4000., 2000.);
+ }
+
+ /**
+ * Set the seed threshold. Units are electrons.
+ *
+ * @param seed_threshold seed threshold
+ */
+ public void setSeedThreshold(double seed_threshold) {
+ _seed_threshold = seed_threshold;
+ }
+
+ /**
+ * Set the neighbor threshold. Units are electrons.
+ *
+ * @param neighbor_threshold neighbor threshold
+ */
+ public void setNeighborThreshold(double neighbor_threshold) {
+ _neighbor_threshold = neighbor_threshold;
+ }
+
+ /**
+ * Return the seed threshold. Units are electrons.
+ *
+ * @return seed threshold
+ */
+ public double getSeedThreshold() {
+ return _seed_threshold;
+ }
+
+ /**
+ * Return the neighbor threshold. Units are electrons.
+ *
+ * @return neighbor threshold
+ */
+ public double getNeighborThreshold() {
+ return _neighbor_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 sensor sensor containing the electrodes
+ * @param electrodes electrodes we are clustering
+ * @param readout_chip readout chip for these electrodes
+ * @param raw_hits List of RawTrackerHits to be clustered
+ * @return list of clusters, with a cluster being a list of RawTrackerHits
+ */
+ public List<List<RawTrackerHit>> findClusters(SiSensorElectrodes electrodes,
+ ReadoutChip readout_chip, List<RawTrackerHit> raw_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
+ Map<Integer, Boolean> clusterable = new HashMap<Integer, Boolean>();
+ Map<RawTrackerHit, Integer> hit_to_channel = new HashMap<RawTrackerHit, Integer>();
+ Map<Integer, RawTrackerHit> channel_to_hit = new HashMap<Integer, RawTrackerHit>();
+
+ // 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 (RawTrackerHit raw_hit : raw_hits) {
+
+ // get the channel number for this hit
+ IIdentifier id = raw_hit.getIdentifier();
+ SiTrackerIdentifierHelper _sid_helper = (SiTrackerIdentifierHelper) raw_hit.getIdentifierHelper();
+ int channel_number = _sid_helper.getElectrodeValue(id);
+
+ // Check for duplicate RawTrackerHits or channel numberss
+ if (hit_to_channel.containsKey(raw_hit) || channel_to_hit.containsKey(channel_number)) {
+ throw new RuntimeException("Duplicate hit or channel number");
+ }
+
+ // Add this hit to the maps that relate channels and hits
+ hit_to_channel.put(raw_hit, channel_number);
+ channel_to_hit.put(channel_number, raw_hit);
+
+ // Get the signal from the readout chip (units are electrons)
+ double signal = readout_chip.decodeCharge(raw_hit);
+
+ // Mark this hit as available for clustering if it is above the neighbor threshold
+ clusterable.put(channel_number, signal >= _neighbor_threshold);
+
+ // Add this hit to the list of seeds if it is above the seed threshold
+ if (signal >= _seed_threshold) cluster_seeds.add(channel_number);
+ }
+
+ // Create a list of clusters
+ List<List<RawTrackerHit>> cluster_list = new ArrayList<List<RawTrackerHit>>();
+
+ // 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<RawTrackerHit> cluster = new ArrayList<RawTrackerHit>();
+
+ // 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));
+
+ // Get the neigbor channels
+ Set<Integer> neighbor_channels = electrodes.getNearestNeighborCells(clustered_cell);
+
+ // Now loop over the neighbors and see if we can add them to the cluster
+ for (int channel : neighbor_channels) {
+
+ // First see if this neighbor channel is in our clusterable hit map
+ if (clusterable.containsKey(channel)) {
+
+ // Now check if this neighbor channel is still available for clustering
+ if (clusterable.get(channel)) {
+
+ // 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 - add it to the list of clusters
+ if (cluster.size() > 0) cluster_list.add(cluster);
+
+ } // End of loop over seeds
+
+ // Finished finding clusters
+ return cluster_list;
+ }
+}
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.1 -r1.2
--- Clusterer.java 24 Apr 2009 01:22:58 -0000 1.1
+++ Clusterer.java 7 May 2009 22:36:21 -0000 1.2
@@ -23,12 +23,6 @@
{
public String getName();
- public double getSeedThreshold();
-
- public double getNeighborThreshold();
-
- public double getClusterThreshold();
-
public List<SiTrackerHit> makeHits(IDetectorElement detector);
public List<SiTrackerHit> makeHits(SiSensor sensor);
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.2 -r1.3
--- GenericReadoutChip.java 29 Apr 2009 21:37:11 -0000 1.2
+++ GenericReadoutChip.java 7 May 2009 22:36:21 -0000 1.3
@@ -36,9 +36,9 @@
private static Random _random = new Random();
private static NormalDistribution _gaussian = new NormalDistributionImpl(0.0, 1.0);
private static BinomialDistribution _binomial = new BinomialDistributionImpl(1, 1);
- private Clusterer _clusterer;
+ private double _noise_threshold;
+ private double _neighbor_threshold;
private GenericChannel _channel = new GenericChannel();
- private double _capacitance;
/** Creates a new instance of GenericReadoutChip */
public GenericReadoutChip() {
@@ -65,31 +65,32 @@
}
/**
- * Set the capacitance of the strip/pixels. Units are fF.
+ * Set the threshold for reading out a channel. Units are electrons.
*
- * @param capacitance
+ * @param noise_threshold
*/
- public void setCapacitance(double capacitance) {
- _capacitance = capacitance;
+ public void setNoiseThreshold(double noise_threshold) {
+ _noise_threshold = noise_threshold;
}
/**
- * Set the conversion between charge and ADC counts. Units are ADC counts
- * per fC of charge.
+ * Set the threshold for reading a channel if it's neighbor is
+ * above the noise threshold. Units are electrons.
*
- * @param adc_per_fC
+ * @param neighbor_threshold
*/
- public void setConversionConstant(double adc_per_fC) {
- _channel.setConversionConstant(adc_per_fC);
+ public void setNeighborThreshold(double neighbor_threshold) {
+ _neighbor_threshold = neighbor_threshold;
}
/**
- * Set the clusterer to be used for this readout chip.
+ * Set the conversion between charge and ADC counts. Units are ADC counts
+ * per fC of charge.
*
- * @param _clusterer
+ * @param adc_per_fC
*/
- public void setClusterer(Clusterer clusterer) {
- _clusterer = clusterer;
+ public void setConversionConstant(double adc_per_fC) {
+ _channel.setConversionConstant(adc_per_fC);
}
/**
@@ -121,9 +122,7 @@
}
// Add noise hits to the electrode data collection
-// if (_strip_clusterer != null) {
-// addNoise(data, electrodes);
-// }
+ addNoise(data, electrodes);
// return the digitized charge data as a map that associates a hit
// channel with a list of raw data for the channel
@@ -222,14 +221,15 @@
eldata.addCharge(noise_charge);
}
- // Add random noise hits where the noise charge exceeds the cluster seed threshold
+ // Add random noise hits where the noise charge exceeds the noise threshold
// Find the number of pixels/strips that are not currently hit
int nelectrodes = electrodes.getNCells();
int nelectrodes_empty = nelectrodes - data.size();
- // Get the seed threshold from the clusterer
- double normalized_integration_limit = _clusterer.getSeedThreshold();
+ // Get the noise threshold in units of the noise charge
+ double noiseRMS = _channel.computeNoise(electrodes.getCapacitance());
+ double normalized_integration_limit = _noise_threshold / noiseRMS;
// Calculate how many channels should get noise hits
double integral = Erf.phic(normalized_integration_limit);
@@ -265,7 +265,9 @@
neighbors.removeAll(data.keySet());
nelectrodes_empty = neighbors.size();
- normalized_integration_limit = _clusterer.getNeighborThreshold(); // We should get this from same place as clustering code
+
+ // Get the noise threshold in units of the noise charge
+ normalized_integration_limit = _neighbor_threshold / noiseRMS;
integral = Erf.phic(normalized_integration_limit);
nchannels_throw = drawBinomial(nelectrodes_empty, integral);
@@ -336,6 +338,8 @@
private double _noise_intercept = 0.;
private double _noise_slope = 0.;
+ private double _noise_threshold = 1.;
+ private double _neighbor_threshold = 1.;
private double _adc_per_fC = 100.;
/**
@@ -366,7 +370,7 @@
}
/**
- * Set the capacitative noise slope (in electrons / fF)
+ * Set the capacitative noise slope (in electrons / pF)
*
* @param noise_slope noise slope
*/
@@ -377,7 +381,7 @@
/**
* Return the noise in electrons for a given strip/pixel capacitance
*
- * @param capacitance capacitance in fF
+ * @param capacitance capacitance in pF
* @return noise in electrons
*/
public double computeNoise(double capacitance) {
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.1 -r1.2
--- Kpix.java 24 Apr 2009 01:22:58 -0000 1.1
+++ Kpix.java 7 May 2009 22:36:21 -0000 1.2
@@ -36,7 +36,8 @@
private static Random _random = new Random();
private static NormalDistribution _gaussian = new NormalDistributionImpl(0.0,1.0);
private static BinomialDistribution _binomial = new BinomialDistributionImpl(1,1);
- private Clusterer _clusterer;
+ private double _noise_threshold = 4;
+ private double _neighbor_threshold = 2;
// Static values and defaults: DO NOT CHANGE
//==========================================
@@ -118,20 +119,36 @@
public Kpix() {
}
- public void setClusterer(Clusterer clusterer)
- {
- _clusterer = clusterer;
- }
-
// ReadoutChip Interface
public KpixChannel getChannel(int channel_number) {
return _channel;
}
-
+
+ /**
+ * Set noise threshold for creating noise hits. Units are number of sigma
+ * above the RMS noise.
+ *
+ * @param noise_threshold
+ */
+ public void setNoiseThreshold(double noise_threshold) {
+ _noise_threshold = noise_threshold;
+ }
+
+ /**
+ * Set the threshold for reading a channel if it's neighbor is
+ * above the noise threshold. Units are number of sigma above
+ * the RMS noise.
+ *
+ * @param neighbor_threshold
+ */
+ public void setNeighborThreshold(double neighbor_threshold) {
+ _neighbor_threshold = neighbor_threshold;
+ }
+
public SortedMap<Integer,List<Integer>> readout(SiElectrodeDataCollection data, SiSensorElectrodes electrodes)
{
if (data == null) data = new SiElectrodeDataCollection();
- if (_clusterer != null) addNoise(data,electrodes);
+ addNoise(data,electrodes);
return digitize(data,electrodes);
}
@@ -188,7 +205,7 @@
int nelectrodes = electrodes.getNCells();
int nelectrodes_empty = nelectrodes - data.size();
- double normalized_integration_limit = _clusterer.getSeedThreshold(); // We should get this from same place as clustering code
+ double normalized_integration_limit = _noise_threshold;
double integral = normalCDF(normalized_integration_limit);
int nchannels_throw = drawBinomial(nelectrodes_empty, integral);
@@ -230,7 +247,7 @@
neighbors.removeAll(data.keySet());
nelectrodes_empty = neighbors.size();
- normalized_integration_limit = _clusterer.getNeighborThreshold(); // We should get this from same place as clustering code
+ normalized_integration_limit = _neighbor_threshold;
integral = normalCDF(normalized_integration_limit);
nchannels_throw = drawBinomial(nelectrodes_empty, integral);
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.2 -r1.3
--- PixelHitMaker.java 30 Apr 2009 22:13:13 -0000 1.2
+++ PixelHitMaker.java 7 May 2009 22:36:21 -0000 1.3
@@ -17,7 +17,6 @@
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;
@@ -31,7 +30,6 @@
import org.lcsim.detector.tracker.silicon.SiPixels;
import org.lcsim.detector.tracker.silicon.SiSensor;
import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
-import org.lcsim.detector.tracker.silicon.SiStrips;
import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
import org.lcsim.event.RawTrackerHit;
import org.lcsim.event.SimTrackerHit;
@@ -45,11 +43,9 @@
private static String _NAME = "PixelClusterer";
- // Thresholds
- double _seed_threshold = 4; // to seed a cluster
- double _neighbor_threshold = 2; // to add to a cluster
- double _cluster_threshold = 3; // to make a cluster (noise of channels is summed)
-
+ // Clustering algorithm
+ ClusteringAlgorithm _clustering;
+
// Absolute maximum cluster size
int _max_cluster_npixels = 10;
@@ -62,33 +58,35 @@
// Identifier helper (reset once per sensor)
SiTrackerIdentifierHelper _sid_helper;
- // Temporary maps connecting hits to pixel numbers for sake of speed (reset once per sensor)
+ // Temporary map 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 */
+ /**
+ * Create a new instance of PixelHitMaker that uses the default clustering algorithm
+ *
+ * @param simulation charge collection simulation
+ * @param readout_chip readout chip
+ */
public PixelHitMaker(SiSensorSim simulation, ReadoutChip readout_chip)
{
- _simulation = simulation;
- _readout_chip = readout_chip;
-
- _readout_chip.setClusterer(this);
- }
-
- // Settings for Tracker1DHitMaker
- public void setSeedThreshold(double nsigma)
- {
- _seed_threshold = nsigma;
+ this(simulation, readout_chip, new NearestNeighbor());
}
- public void setNeigborThreshold(double nsigma)
- {
- _neighbor_threshold = nsigma;
+ /**
+ * Fully qualified constructor for PixelHitMaker
+ *
+ * @param simulation charge collection simulation
+ * @param readout_chip readout chip
+ * @param clustering clustering algorithm
+ */
+ public PixelHitMaker(SiSensorSim simulation, ReadoutChip readout_chip, ClusteringAlgorithm clustering) {
+ _simulation = simulation;
+ _readout_chip = readout_chip;
+ _clustering = clustering;
}
-
- public void setClusterThreshold(double nsigma)
- {
- _cluster_threshold = nsigma;
+
+ public void setClusteringAlgorithm(ClusteringAlgorithm clustering_algorithm) {
+ _clustering = clustering_algorithm;
}
public void setMaxClusterSize(int max_cluster_npixels)
@@ -100,22 +98,7 @@
{
return _NAME;
}
-
- public double getSeedThreshold()
- {
- return _seed_threshold;
- }
-
- public double getNeighborThreshold()
- {
- return _neighbor_threshold;
- }
-
- public double getClusterThreshold()
- {
- return _cluster_threshold;
- }
-
+
// Make hits for all sensors within a DetectorElement
public List<SiTrackerHit> makeHits(IDetectorElement detector)
{
@@ -148,7 +131,6 @@
// 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();
@@ -163,14 +145,9 @@
IIdentifier id = raw_hit.getIdentifier();
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());
ChargeCarrier carrier = ChargeCarrier.getCarrier(_sid_helper.getSideValue(id));
@@ -200,88 +177,24 @@
// Make hits for an electrode
public List<SiTrackerHit> makeHits(SiSensorElectrodes electrodes, List<RawTrackerHit> raw_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 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>();
-
- // 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));
- 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>();
-
- // 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);
+ // Call the clustering algorithm to make clusters
+ List<List<RawTrackerHit>> cluster_list = _clustering.findClusters(electrodes, _readout_chip, raw_hits);
- // 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)) {
+ // Create an empty list for the pixel hits to be formed from clusters
+ List<SiTrackerHit> hits = new ArrayList<SiTrackerHit>();
- // 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);
- }
- }
- }
- }
+ // Make a pixel hit from this cluster
+ for (List<RawTrackerHit> cluster : cluster_list) {
- // Make a TrackerHit from the cluster if it meets max cluster size requirement
- if (cluster.size() <= _max_cluster_npixels)
- {
- SiTrackerHitPixel hit = makeTrackerHit(cluster,electrodes);
+ // Make a TrackerHit from the cluster if it meets max cluster size requirement
+ if (cluster.size() <= _max_cluster_npixels)
+ {
+ SiTrackerHitPixel hit = makeTrackerHit(cluster,electrodes);
- // Add to readout and to list of hits
- ((SiSensor)electrodes.getDetectorElement()).getReadout().addHit(hit);
- hits.add(hit);
- }
-
-
+ // Add to readout and to list of hits
+ ((SiSensor)electrodes.getDetectorElement()).getReadout().addHit(hit);
+ hits.add(hit);
}
}
@@ -335,20 +248,7 @@
position = VecOp.add(position,VecOp.mult(signal,positions.get(ipixel)));
}
position = VecOp.mult(1/total_charge,position);
-
-// double total_charge = 0;
-// Hep3Vector position = new BasicHep3Vector(0,0,0);
-//
-// for (RawTrackerHit hit : cluster)
-// {
-// int strip_number = _strip_map.get(hit);
-// double signal = _readout_chip.decodeCharge(hit);
-//
-// total_charge += signal;
-// position = VecOp.add(position,VecOp.mult(signal,((SiStrips)electrodes).getStripCenter(strip_number)));
-// }
-// position = VecOp.mult(1/total_charge,position);
-
+
// Put position in sensor coordinates
electrodes.getParentToLocal().inverse().transform(position);
@@ -400,19 +300,6 @@
return covariance_global;
-// BasicHep3Matrix rotation_matrix = (BasicHep3Matrix)electrodes.getLocalToGlobal().getRotation().getRotationMatrix();
-// BasicHep3Matrix rotation_matrix_transposed = new BasicHep3Matrix(rotation_matrix);
-// rotation_matrix_transposed.transpose();
-//
-//// System.out.println("Rotation matrix: \n"+rotation_matrix);
-//// System.out.println("Rotation matrix transposed: \n"+rotation_matrix_transposed);
-//// System.out.println("Local covariance matrix: \n"+covariance);
-//
-// BasicHep3Matrix covariance_global = (BasicHep3Matrix)VecOp.mult(rotation_matrix,VecOp.mult(covariance,rotation_matrix_transposed));
-//
-//// System.out.println("Global covariance matrix: \n"+covariance_global);
-//
-// return new SymmetricMatrix((Matrix)covariance_global);
}
private double getXResolution(List<RawTrackerHit> cluster, SiSensorElectrodes electrodes)
@@ -488,8 +375,6 @@
return measured_resolution;
}
-
-
private double getEnergy(List<RawTrackerHit> cluster)
{
@@ -505,5 +390,4 @@
return total_charge * DopedSilicon.ENERGY_EHPAIR;
}
-
}
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.1 -r1.2
--- ReadoutChip.java 24 Apr 2009 01:22:58 -0000 1.1
+++ ReadoutChip.java 7 May 2009 22:36:21 -0000 1.2
@@ -20,13 +20,12 @@
*/
public interface ReadoutChip
{
- public void setClusterer(Clusterer clusterer);
-
public SortedMap<Integer,List<Integer>> readout(SiElectrodeDataCollection data, SiSensorElectrodes electrodes);
public ReadoutChannel getChannel(int channel_number);
public double decodeCharge(RawTrackerHit hit);
+
public int decodeTime(RawTrackerHit hit);
public interface ReadoutChannel
lcsim/src/org/lcsim/recon/tracking/digitization/sisim
diff -u -r1.1 -r1.2
--- StripHitMaker.java 24 Apr 2009 01:22:58 -0000 1.1
+++ StripHitMaker.java 7 May 2009 22:36:21 -0000 1.2
@@ -42,11 +42,9 @@
{
private static String _NAME = "StripClusterer";
-
- // Thresholds
- double _seed_threshold = 4; // to seed a cluster
- double _neighbor_threshold = 2; // to add to a cluster
- double _cluster_threshold = 3; // to make a cluster (noise of channels is summed)
+
+ // Clustering algorithm
+ ClusteringAlgorithm _clustering;
// Number of strips beyond which charge is averaged on center strips
int _max_noaverage_nstrips = 4;
@@ -66,31 +64,13 @@
// Temporary map connecting hits to strip numbers for sake of speed (reset once per sensor)
Map<RawTrackerHit,Integer> _strip_map = new HashMap<RawTrackerHit,Integer>();
- /** Creates a new instance of Tracker1DHitMaker */
+ /** Creates a new instance of StripHitMaker */
public StripHitMaker(SiSensorSim simulation, ReadoutChip readout_chip)
{
_simulation = simulation;
_readout_chip = readout_chip;
-
- _readout_chip.setClusterer(this);
- }
-
- // Settings for Tracker1DHitMaker
- public void setSeedThreshold(double nsigma)
- {
- _seed_threshold = nsigma;
- }
-
- public void setNeigborThreshold(double nsigma)
- {
- _neighbor_threshold = nsigma;
- }
-
- public void setClusterThreshold(double nsigma)
- {
- _cluster_threshold = nsigma;
}
-
+
public void setCentralStripAveragingThreshold(int max_noaverage_nstrips)
{
_max_noaverage_nstrips = max_noaverage_nstrips;
@@ -106,21 +86,6 @@
return _NAME;
}
- public double getSeedThreshold()
- {
- return _seed_threshold;
- }
-
- public double getNeighborThreshold()
- {
- return _neighbor_threshold;
- }
-
- public double getClusterThreshold()
- {
- return _cluster_threshold;
- }
-
// Make hits for all sensors within a DetectorElement
public List<SiTrackerHit> makeHits(IDetectorElement detector)
{
@@ -196,89 +161,30 @@
// Make hits for an electrode
public List<SiTrackerHit> makeHits(SiSensorElectrodes electrodes, List<RawTrackerHit> raw_hits)
{
-
-// System.out.println("Clustering electrodes: "+electrodes_id);
-
+
+ // Call the clustering algorithm to make clusters
+ List<List<RawTrackerHit>> cluster_list = _clustering.findClusters(electrodes, _readout_chip, raw_hits);
+
+ // Create an empty list for the pixel hits to be formed from clusters
List<SiTrackerHit> hits = new ArrayList<SiTrackerHit>();
-
- List<RawTrackerHit> unclustered_rawhits = new ArrayList<RawTrackerHit>(raw_hits);
-
- for (RawTrackerHit raw_hit : raw_hits)
- {
-
- int strip_number = _strip_map.get(raw_hit);
- double signal = _readout_chip.decodeCharge(raw_hit);
- double noise = _readout_chip.getChannel(strip_number).computeNoise(electrodes.getCapacitance(strip_number));
-
- if (signal/noise > _seed_threshold && unclustered_rawhits.contains(raw_hit))
+
+ // Make a pixel hit from this cluster
+ for (List<RawTrackerHit> cluster : cluster_list) {
+
+ // Make a TrackerHit from the cluster if it meets max cluster size requirement
+ if (cluster.size() <= _max_cluster_nstrips)
{
-
-// System.out.println("Creating new cluster, # Raw hits on electrodes is: "+hits.size());
-
- 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());
- }
-
-// 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_nstrips)
- {
- SiTrackerHitStrip1D hit = makeTrackerHit(cluster,electrodes);
-
- // Add to readout and to list of hits
- ((SiSensor)electrodes.getDetectorElement()).getReadout().addHit(hit);
- hits.add(hit);
- }
-
-
+ SiTrackerHitStrip1D hit = makeTrackerHit(cluster,electrodes);
+
+ // Add to readout and to list of hits
+ ((SiSensor)electrodes.getDetectorElement()).getReadout().addHit(hit);
+ hits.add(hit);
}
}
-
+
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(_strip_map.get(seed_hit));
- for (RawTrackerHit hit : unclustered_hits)
- {
- int strip_number = _strip_map.get(hit);
- double signal = _readout_chip.decodeCharge(hit);
- double noise = _readout_chip.getChannel(strip_number).computeNoise(electrodes.getCapacitance(strip_number));
-
- if (neighbor_cells.contains(_strip_map.get(hit)) && signal/noise > _neighbor_threshold)
- {
- neighbor_hits.add(hit);
- }
- }
- }
- return neighbor_hits;
- }
-
-
+
//Make the hit
private SiTrackerHitStrip1D makeTrackerHit(List<RawTrackerHit> cluster, SiSensorElectrodes electrodes)
{
CVSspam 0.2.8