Commit in lcsim/src/org/lcsim/contrib/SiStripSim on MAIN
ClusterMaker.java+23added 1.1
StripClusterMaker.java+285added 1.1
+308
2 added files
Cluster maker interface and implementation to cluster RawTrackerHits into TrackerHits: needs testing!

lcsim/src/org/lcsim/contrib/SiStripSim
ClusterMaker.java added at 1.1
diff -N ClusterMaker.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ClusterMaker.java	6 Nov 2007 20:06:33 -0000	1.1
@@ -0,0 +1,23 @@
+/*
+ * ClusterMaker.java
+ *
+ * Created on September 26, 2007, 1:57 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.SiStripSim;
+
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.TrackerHit;
+import java.util.List;
+
+/**
+ *
+ * @author tknelson
+ */
+public interface ClusterMaker
+{
+    List<TrackerHit> makeClusters(List<RawTrackerHit> raw_hits);
+}

lcsim/src/org/lcsim/contrib/SiStripSim
StripClusterMaker.java added at 1.1
diff -N StripClusterMaker.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ StripClusterMaker.java	6 Nov 2007 20:06:33 -0000	1.1
@@ -0,0 +1,285 @@
+/*
+ * StripClusterMaker.java
+ *
+ * Created on September 26, 2007, 1:57 PM
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.SiStripSim;
+
+import hep.physics.matrix.Matrix;
+import hep.physics.matrix.SymmetricMatrix;
+import hep.physics.vec.BasicHep3Matrix;
+import hep.physics.vec.BasicHep3Vector;
+import hep.physics.vec.Hep3Vector;
+import hep.physics.vec.VecOp;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.TrackerHit;
+import org.lcsim.detector.identifier.IExpandedIdentifier;
+import org.lcsim.detector.identifier.ExpandedIdentifier;
+import org.lcsim.detector.identifier.IIdentifierDictionary.FieldNotFoundException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import org.lcsim.detector.tracker.silicon.ChargeCarrier;
+import org.lcsim.detector.tracker.silicon.DopedSilicon;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.event.base.BaseTrackerHitMC;
+
+/**
+ *
+ * @author tknelson
+ */
+public class StripClusterMaker implements ClusterMaker
+{
+    int _seed_threshold = 4;
+    int _neighbor_threshold = 2;
+    int _cluster_threshold = 3;
+    
+    // Temporary maps connecting electrodes to hit list, hits to strip number, electrode ID to electrodes
+    // (the last should be cached... not a model of efficiency at the moment)
+    Map<IExpandedIdentifier,List<RawTrackerHit>> _hit_map = new HashMap<IExpandedIdentifier,List<RawTrackerHit>>();
+    Map<RawTrackerHit,Integer> _strip_map = new HashMap<RawTrackerHit,Integer>();
+    Map<IExpandedIdentifier,SiSensorElectrodes> _electrode_map = new HashMap<IExpandedIdentifier,SiSensorElectrodes>();
+    
+    /** Creates a new instance of StripClusterMaker */
+    public StripClusterMaker()
+    {
+        
+    }
+    
+    public List<TrackerHit> makeClusters(List<RawTrackerHit> raw_hits)
+    {
+        
+        // clear the maps
+        _hit_map.clear();
+        _strip_map.clear();
+        _electrode_map.clear();
+        
+        List<TrackerHit> clusters = new ArrayList<TrackerHit>();
+        
+//        Map<IExpandedIdentifier,List<RawTrackerHit>> hit_map = new HashMap<IExpandedIdentifier,List<RawTrackerHit>>();
+//        Map<IExpandedIdentifier,SiSensorElectrodes> electrode_map = new HashMap<IExpandedIdentifier,SiSensorElectrodes>();
+//        Map<RawTrackerHit,Integer> strip_map = new HashMap<RawTrackerHit,Integer>();
+        
+        // Sort RawTrackerHits by electrodes
+        for (RawTrackerHit raw_hit : raw_hits)
+        {
+            int strip_field;
+            try
+            {
+                strip_field = raw_hit.getIdentifierHelper().getFieldIndex("strip");
+            }
+            catch (FieldNotFoundException exception)
+            {
+                throw new RuntimeException(exception);
+            }
+            int side_field;
+            try
+            {
+                side_field = raw_hit.getIdentifierHelper().getFieldIndex("side");
+            }
+            catch (FieldNotFoundException exception)
+            {
+                throw new RuntimeException(exception);
+            }
+            
+            // Get expanded ID
+            IExpandedIdentifier id = new ExpandedIdentifier(raw_hit.getExpandedIdentifier());
+            
+            // Get strip number
+            int strip_id = id.getValue(strip_field);
+            _strip_map.put(raw_hit,strip_id);
+            
+            // Get side of sensor
+            ChargeCarrier carrier;
+            if (id.getValue(side_field) == 1)
+            {
+                carrier = ChargeCarrier.HOLE;
+            }
+            else if (id.getValue(side_field) == -1)
+            {
+                carrier = ChargeCarrier.ELECTRON;
+            }
+            else
+            {
+                throw new RuntimeException("Invalid side field in RawTrackerHit.");
+            }
+            
+            // Zero strip number to refer only to electrode set
+            id.setValue(strip_field,0);
+            
+            // Fill maps needed for clustering
+            if (_electrode_map.get(id) == null)
+            {
+                _electrode_map.put(id,((SiSensor)raw_hit.getDetectorElement()).getReadoutElectrodes(carrier));
+                _hit_map.put(id,new ArrayList<RawTrackerHit>());
+            }
+            _hit_map.get(id).add(raw_hit);
+            
+        }
+        
+        // Do clustering for each set of electrodes
+        for (IExpandedIdentifier electrodes_id : _electrode_map.keySet())
+        {
+            
+            List<RawTrackerHit> hits = _hit_map.get(electrodes_id);
+            List<RawTrackerHit> unclustered_hits = new ArrayList<RawTrackerHit>(hits);
+            SiSensorElectrodes electrodes = _electrode_map.get(electrodes_id);
+            
+            for (RawTrackerHit hit : hits)
+            {
+                
+                Kpix.ControlRegisters control_registers = Kpix.ControlRegisters.decoded(hit.getADCValues()[0]);
+                Kpix.KpixChannel.ReadoutRegisters readout_registers = Kpix.KpixChannel.ReadoutRegisters.decoded(hit.getADCValues()[1]);
+                double noise = Kpix.KpixChannel.computeNoise(10.0);  // FIXME: should get this information from the electrodes.
+                double signal = Kpix.computeCharge(readout_registers, control_registers);
+                
+                if (signal/noise > _seed_threshold && unclustered_hits.contains(hit))
+                {
+                    List<RawTrackerHit> cluster = new ArrayList<RawTrackerHit>();
+                    List<RawTrackerHit> clustered_hits = new ArrayList<RawTrackerHit>();
+                    
+                    clustered_hits.add(hit);
+                    
+                    while (clustered_hits.size() != 0)
+                    {
+                        cluster.addAll(clustered_hits);
+                        unclustered_hits.removeAll(clustered_hits);
+                        clustered_hits = neighborHits(clustered_hits,unclustered_hits,electrodes);
+                    }
+                    
+                    // now make a cluster or trackerhit
+                    clusters.add(makeTrackerHit(cluster,electrodes));
+                    
+                }
+            }
+            
+            
+        }
+        
+        return clusters;
+        
+    }
+    
+    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)
+            {
+                
+                Kpix.ControlRegisters control_registers = Kpix.ControlRegisters.decoded(hit.getADCValues()[0]);
+                Kpix.KpixChannel.ReadoutRegisters readout_registers = Kpix.KpixChannel.ReadoutRegisters.decoded(hit.getADCValues()[1]);
+                double noise = Kpix.KpixChannel.computeNoise(10.0);  // FIXME: should get this information from the electrodes.
+                double signal = Kpix.computeCharge(readout_registers, control_registers);
+                
+                if (neighbor_cells.contains(_strip_map.get(hit)) && signal/noise > _neighbor_threshold)
+                {
+                    neighbor_hits.add(hit);
+                }
+            }
+        }
+        return neighbor_hits;
+    }
+    
+    private TrackerHit makeTrackerHit(List<RawTrackerHit> cluster, SiSensorElectrodes electrodes)
+    {
+        double[] position = getPosition(cluster,electrodes);
+        SymmetricMatrix covariance = getCovariance(cluster,electrodes);
+        double time = getTime(cluster);
+        double energy = getEnergy(cluster);
+        int type = 0;
+        
+        TrackerHit hit = new BaseTrackerHitMC(position, covariance.asPackedArray(true), time, energy, type, getSimulatedHits(cluster));
+        return hit;
+    }
+    
+    private List<SimTrackerHit> getSimulatedHits(List<RawTrackerHit> cluster)
+    {
+        Set<SimTrackerHit> simulated_hits = new HashSet<SimTrackerHit>();
+        for (RawTrackerHit hit : cluster)
+        {
+            simulated_hits.addAll(hit.getSimTrackerHit());
+        }
+        return new ArrayList<SimTrackerHit>(simulated_hits);
+    }
+    
+    private double[] getPosition(List<RawTrackerHit> cluster, SiSensorElectrodes electrodes)
+    {   
+        double total_charge = 0;
+        Hep3Vector position = new BasicHep3Vector(0,0,0);
+        
+        for (RawTrackerHit hit : cluster)
+        {
+            Kpix.ControlRegisters control_registers = Kpix.ControlRegisters.decoded(hit.getADCValues()[0]);
+            Kpix.KpixChannel.ReadoutRegisters readout_registers = Kpix.KpixChannel.ReadoutRegisters.decoded(hit.getADCValues()[1]);
+            double signal = Kpix.computeCharge(readout_registers, control_registers);
+
+            total_charge += signal;
+            position = VecOp.add(position,VecOp.mult(signal,electrodes.getCellPosition(_strip_map.get(hit))));
+        }
+        position = VecOp.mult(1/total_charge,position);
+        
+        return electrodes.getLocalToGlobal().transformed(position).v();        
+    }
+    
+    private double getTime(List<RawTrackerHit> cluster)
+    {
+        int time_sum = 0;
+        int signal_sum = 0;
+        
+        for (RawTrackerHit hit : cluster)
+        {
+            Kpix.ControlRegisters control_registers = Kpix.ControlRegisters.decoded(hit.getADCValues()[0]);
+            Kpix.KpixChannel.ReadoutRegisters readout_registers = Kpix.KpixChannel.ReadoutRegisters.decoded(hit.getADCValues()[1]);
+            double signal = Kpix.computeCharge(readout_registers, control_registers);
+            double time = readout_registers.getTime();
+
+            time_sum += time_sum * signal;
+            signal_sum += signal_sum;
+
+        }
+        return (double)time_sum/(double)signal_sum;
+    }
+    
+    private SymmetricMatrix getCovariance(List<RawTrackerHit> cluster, SiSensorElectrodes electrodes)
+    { 
+        // FIXME: very raw hack
+        
+        BasicHep3Matrix covariance = new BasicHep3Matrix();
+        covariance.setElement(0,0,Math.pow(0.007,2));
+        covariance.setElement(1,1,Math.pow(93.031/Math.sqrt(12),2));
+        covariance.setElement(2,2,0.0);
+        VecOp.mult(electrodes.getLocalToGlobal().getRotation().getRotationMatrix(),covariance);
+        return new SymmetricMatrix((Matrix)covariance);
+    }
+    
+    private double getEnergy(List<RawTrackerHit> cluster)
+    {
+        double total_charge = 0.0;
+        for (RawTrackerHit hit : cluster)
+        {
+            Kpix.ControlRegisters control_registers = Kpix.ControlRegisters.decoded(hit.getADCValues()[0]);
+            Kpix.KpixChannel.ReadoutRegisters readout_registers = Kpix.KpixChannel.ReadoutRegisters.decoded(hit.getADCValues()[1]);
+            double signal = Kpix.computeCharge(readout_registers, control_registers);
+            
+            total_charge += signal;
+        }
+        return total_charge * DopedSilicon.ENERGY_EHPAIR;
+    }
+
+    
+}
CVSspam 0.2.8