Print

Print


Commit in lcsim on MAIN
src/org/lcsim/contrib/RobKutschke/TKNHits/TKNRawHitsDriverV1.java+8-131.1 -> 1.2
src/org/lcsim/contrib/SiStripSim/SiElectrodeData.java+7-51.3 -> 1.4
                                /ReadoutChip.java+2-11.3 -> 1.4
                                /Kpix.java+306-671.6 -> 1.7
test/org/lcsim/detector/driver/TrackerDigitizationDriverTest.java+21-101.2 -> 1.3
+344-96
5 modified files
Changes to support new KPiX chip class for decoding ADC information from RawHits needed to properly make TrackerHits.

lcsim/src/org/lcsim/contrib/RobKutschke/TKNHits
TKNRawHitsDriverV1.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- TKNRawHitsDriverV1.java	1 Nov 2007 22:54:24 -0000	1.1
+++ TKNRawHitsDriverV1.java	6 Nov 2007 19:58:03 -0000	1.2
@@ -2,7 +2,6 @@
 
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Map;
 import java.util.SortedMap;
 import java.util.Set;
 import java.util.HashSet;
@@ -14,7 +13,6 @@
 import org.lcsim.event.base.BaseRawTrackerHit;
 
 import org.lcsim.detector.IDetectorElement;
-import org.lcsim.detector.IReadout;
 
 import org.lcsim.detector.tracker.silicon.SiSensor;
 import org.lcsim.detector.tracker.silicon.ChargeCarrier;
@@ -23,9 +21,6 @@
 import org.lcsim.contrib.SiStripSim.CDFSiSensorSim;
 import org.lcsim.contrib.SiStripSim.ReadoutChip;
 import org.lcsim.contrib.SiStripSim.Kpix;
-import org.lcsim.contrib.SiStripSim.SiElectrodeDataCollection;
-
-import org.lcsim.detector.driver.SimTrackerHitIdentifierReadoutDriver;
 
 /**
  *
@@ -38,10 +33,10 @@
  *
  * The driver SimTrackerHitIdentifierReadoutDriver must be called before this code is run.
  *
- *@author $Author: kutschke $
- *@version $Id: TKNRawHitsDriverV1.java,v 1.1 2007/11/01 22:54:24 kutschke Exp $
+ *@author $Author: tknelson $
+ *@version $Id: TKNRawHitsDriverV1.java,v 1.2 2007/11/06 19:58:03 tknelson Exp $
  *
- * Date $Date: 2007/11/01 22:54:24 $
+ * Date $Date: 2007/11/06 19:58:03 $
  *
  */
 
@@ -109,8 +104,8 @@
 		    if (sensor.hasElectrodesOnSide(carrier)){
 			
 			// Create digitized hit strips/pixels.
-			SortedMap<Integer,Integer> digitized_hits = 
-			    kpix.readout(si_simulation.getReadoutData(carrier).getChargeMap(),sensor.getReadoutElectrodes(carrier));
+			SortedMap<Integer,List<Integer>> digitized_hits = 
+			    kpix.readout(si_simulation.getReadoutData(carrier),sensor.getReadoutElectrodes(carrier));
 			
 			// Create RawTrackerHits.
 			for (Integer readout_cell : digitized_hits.keySet()){
@@ -119,13 +114,13 @@
 			    int time = 0;
 
 			    long cell_id = sensor.makeStripId(readout_cell,carrier.charge()).getValue();			    
-			    short[] adc_values = { digitized_hits.get(readout_cell).shortValue() };
-			    List<SimTrackerHit> simulated_hits = 
+                            short[] adc_values = {digitized_hits.get(readout_cell).get(0).shortValue(),digitized_hits.get(readout_cell).get(1).shortValue()};
+			    Set<SimTrackerHit> simulated_hits = 
 				si_simulation.getReadoutData(carrier).get(readout_cell).getSimulatedHits();
 			    IDetectorElement detector_element = sensor;
 			    
 			    // Create the hit and add it to the output list.
-			    RawTrackerHit raw_hit = new BaseRawTrackerHit(time,cell_id,adc_values,simulated_hits,detector_element);
+			    RawTrackerHit raw_hit = new BaseRawTrackerHit(time,cell_id,adc_values,new ArrayList<SimTrackerHit>(simulated_hits),detector_element);
 			    raw_hits.add(raw_hit);
 
 			}                        

lcsim/src/org/lcsim/contrib/SiStripSim
SiElectrodeData.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- SiElectrodeData.java	10 Jul 2007 23:43:19 -0000	1.3
+++ SiElectrodeData.java	6 Nov 2007 19:58:03 -0000	1.4
@@ -9,10 +9,12 @@
 
 package org.lcsim.contrib.SiStripSim;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import org.lcsim.event.SimTrackerHit;
 
 import java.util.List;
-import java.util.ArrayList;
+import java.util.Set;
 
 /**
  *
@@ -21,7 +23,7 @@
 public class SiElectrodeData
 {
     int _charge = 0;
-    List<SimTrackerHit> _simulated_hits = new ArrayList<SimTrackerHit>();
+    Set<SimTrackerHit> _simulated_hits = new HashSet<SimTrackerHit>();
     
     /** Creates a new instance of SiElectrodeData */
     public SiElectrodeData()
@@ -34,7 +36,7 @@
         _simulated_hits.add(simulated_hit);
     }
     
-    public SiElectrodeData(int charge, List<SimTrackerHit> simulated_hits)
+    public SiElectrodeData(int charge, Set<SimTrackerHit> simulated_hits)
     {
         _charge = charge;
         _simulated_hits = simulated_hits;
@@ -55,7 +57,7 @@
         _charge = charge;
     }
     
-    public List<SimTrackerHit> getSimulatedHits()
+    public Set<SimTrackerHit> getSimulatedHits()
     {
         return _simulated_hits;
     }
@@ -66,7 +68,7 @@
         return this;
     }
     
-    public SiElectrodeData add(int charge, List<SimTrackerHit> simulated_hits)
+    public SiElectrodeData add(int charge, Set<SimTrackerHit> simulated_hits)
     {
         this.addCharge(charge);
         for (SimTrackerHit hit : simulated_hits)

lcsim/src/org/lcsim/contrib/SiStripSim
ReadoutChip.java 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- ReadoutChip.java	10 Jul 2007 23:43:19 -0000	1.3
+++ ReadoutChip.java	6 Nov 2007 19:58:03 -0000	1.4
@@ -9,6 +9,7 @@
 
 package org.lcsim.contrib.SiStripSim;
 
+import java.util.List;
 import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
 import java.util.SortedMap;
 
@@ -19,6 +20,6 @@
 public interface ReadoutChip
 {
     
-    public SortedMap<Integer,Integer> readout(SortedMap<Integer,Integer> raw_charge, SiSensorElectrodes electrodes);
+    public SortedMap<Integer,List<Integer>> readout(SiElectrodeDataCollection data, SiSensorElectrodes electrodes);
     
 }

lcsim/src/org/lcsim/contrib/SiStripSim
Kpix.java 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- Kpix.java	14 Oct 2007 06:14:59 -0000	1.6
+++ Kpix.java	6 Nov 2007 19:58:03 -0000	1.7
@@ -9,9 +9,12 @@
 
 package org.lcsim.contrib.SiStripSim;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.SortedMap;
 import java.util.TreeMap;
 import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.units.clhep.SystemOfUnits;
 
 /**
  *
@@ -19,95 +22,331 @@
  */
 public class Kpix implements ReadoutChip
 {
-    // Fields
-    double _high_gain;
-    double _low_gain;
-
-    // Static
-    static double ELECTRON_CHARGE = 1.60217646E-4; // fC
+    
+    static final int VERSION_NUMBER = 0; // version number
+    
+    // Static values and defaults: DO NOT CHANGE
+    //==========================================
+    
+    public static class ControlRegisters
+    {
+        
+        enum GainMode
+        {SINGLE, DOUBLE}
+        enum Polarity
+        {POSITIVE, NEGATIVE}
+        
+        private int _version_number = VERSION_NUMBER;
+        private GainMode _gain_mode = GainMode.DOUBLE;
+        private Polarity _polarity = Polarity.POSITIVE;
+        private double _gain_crossover = 1.0;           // V
+        
+        public ControlRegisters()
+        {
+        }
+        
+        // Setters-
+        // do not allow public setting of version number
+        // do not allow setting gain crossover for now (more info needed for this)
+        private void setVersionNumber(int version_number)
+        {
+            _version_number = version_number;
+        }
+        
+        public void setPolarity(Polarity polarity)
+        {
+            _polarity = polarity;
+        }
+        
+        public void setGainMode(GainMode gain_mode)
+        {
+            _gain_mode = gain_mode;
+        }
+        
+        // Getters
+        public int getVersionNumber()
+        {
+            return _version_number;
+        }
+        
+        public GainMode getGainMode()
+        {
+            return _gain_mode;
+        }
+        
+        public Polarity getPolarity()
+        {
+            return _polarity;
+        }
+        
+        public double getGainCrossover()
+        {
+            return _gain_crossover;
+        }
+        
+        // Encoding and decoding resgister information
+        public int encoded()
+        {
+            return ( getVersionNumber()<<1 & getGainMode().ordinal() )<<1 & getPolarity().ordinal();
+        }
+        
+        public static ControlRegisters decoded(int encoded_registers)
+        {
+            ControlRegisters registers = new ControlRegisters();
             
-    static double NOISE_INTERCEPT = 300.0; // electrons
-    static double NOISE_SLOPE = 30.0; // electrons
-
-    static double HIGH_GAIN_DEFAULT = 10.0; // counts/fC
-    static double LOW_GAIN_DEFAULT = 0.5; // counts/fC
-//    static double GAIN_SWITCHOVER = ??; // Need a guess for this default
-
-    static boolean DOUBLE_GAIN_MODE = true; // double gain mode
+            int version_number = encoded_registers & 0xFC;
+            int double_gain = encoded_registers & 0x1;
+            int polarity = encoded_registers &    0x2;
+            
+            registers.setVersionNumber(version_number);
+            registers.setGainMode(GainMode.values()[double_gain]);
+            registers.setPolarity(Polarity.values()[polarity]);
+            
+            return registers;
+        }
+        
+    }
     
-    // Variables    
+    // Fields
+    ControlRegisters _control_registers = new ControlRegisters();
+    KpixChannel _channel = new KpixChannel(_control_registers); // one per chip for now
     
     /** Creates a new instance of Kpix */
     public Kpix()
     {
-        _high_gain = HIGH_GAIN_DEFAULT * ELECTRON_CHARGE;
-        _low_gain = LOW_GAIN_DEFAULT * ELECTRON_CHARGE;
-        if (DOUBLE_GAIN_MODE)
-        {
-            _high_gain *= 2;
-            _low_gain *=2;
-        }
     }
-
-    public SortedMap<Integer,Integer> readout(SortedMap<Integer,Integer> raw_charge, SiSensorElectrodes electrodes)
+    
+    // Set and get register information
+    public ControlRegisters getControlRegisters()
     {
-        int nchannels = electrodes.getNCells();
-        
-        addNoise(raw_charge, nchannels);              
-        SortedMap<Integer,Integer> digitized_charge = digitize(raw_charge);
-        raw_charge.clear();
-        
-        return digitized_charge;
+        return _control_registers;
     }
     
+    public KpixChannel getKpixChannels()
+    {
+        return _channel;
+    }
+    
+    // Actions
+    public SortedMap<Integer,List<Integer>> readout(SiElectrodeDataCollection data, SiSensorElectrodes electrodes)
+    {
+        addNoise(data,electrodes);
+        return digitize(data,electrodes);
+    }
+    
+    private void addNoise(SiElectrodeDataCollection data, SiSensorElectrodes electrodes)
+    {
+        
+    }
     
-    private void addNoise(SortedMap<Integer,Integer> electrode_charge, int nchannels)
+    private SortedMap<Integer,List<Integer>> digitize(SiElectrodeDataCollection data, SiSensorElectrodes electrodes)
     {
-        for (Integer channel : electrode_charge.keySet())
+        SortedMap<Integer,List<Integer>> chip_data = new TreeMap<Integer,List<Integer>>();
+        for (Integer channel : data.keySet())
         {
-            
+            List<Integer> channel_data = new ArrayList<Integer>();
+            channel_data.add(getControlRegisters().encoded());
+            channel_data.add(getKpixChannels().digitize(data.get(channel)));
+            chip_data.put(channel,channel_data);
         }
-        return;
+        return chip_data;
     }
     
+    // Static calculations of important quantities
+    public static double computeCharge(KpixChannel.ReadoutRegisters readout_registers, ControlRegisters control_registers)
+    {
+        double gain = KpixChannel.computeGain(readout_registers, control_registers);
+        return gain*readout_registers.getAdcValue();
+    }
     
-//    private SiElectrodeDataCollection digitize(SiElectrodeDataCollection electrode_charge)
-//    {        
-//        
-//        SiElectrodeDataCollection digitized_charge = new SiElectrodeDataCollection();
-//                
-//        for (Integer channel : electrode_charge.keySet())
-//        {
-//
-//            SiElectrodeData analog = electrode_charge.get(channel);
-//
-//            double gain = _high_gain; 
-//            
-//            int digital = (int)Math.floor(analog.getCharge() * gain);
-//           
-//            if (digital != 0) digitized_charge.put(channel,new SiElectrodeData(digital);
-//        }
-//        return digitized_charge;
-//    }    
-    
-    private SortedMap<Integer,Integer> digitize(SortedMap<Integer,Integer> electrode_charge)
-    {        
+    //=========================================
+    // Class representing a single KPiX channel
+    //=========================================
+
+    public static class KpixChannel
+    {
+        static final double NORMAL_GAIN_CAP = 400E-15; // 400 fF
+        static final double DOUBLE_GAIN_CAP = 200E-15; // 200 fF
+        static final double LOW_GAIN_CAP = 10E-12; // 10pF
+        static final double ADC_GAIN = 2.5; // count/mV
+        static final double NOISE_INTERCEPT = 300; // electrons
+        static final double NOISE_SLOPE = 30; // electrons
         
-        SortedMap<Integer,Integer> digitized_charge = new TreeMap<Integer,Integer>();
+        public static class ReadoutRegisters
+        {
+            enum GainRange
+            {NORMAL, LOW}
+            
+            GainRange _gain_range = GainRange.NORMAL;
+            int _buffer_number = 0;
+            int _time = 0;
+            int _adc_value = 0;
+            
+            public ReadoutRegisters()
+            {
+            }
+            
+            public void setGainRange(GainRange gain_range)
+            {
+                _gain_range = gain_range;
+            }
+            
+            public void setBufferNumber(int buffer_number)
+            {
+                _buffer_number = buffer_number;
+            }
+            
+            public void setTime(int time)
+            {
+                _time = time;
+            }
+            
+            public void setAdcValue(int adc_value)
+            {
+                _adc_value = adc_value;
+            }
+            
+            public GainRange getGainRange()
+            {
+                return _gain_range;
+            }
+            
+            public int getBufferNumber()
+            {
+                return _buffer_number;
+            }
+            
+            public int getTime()
+            {
+                return _time;
+            }
+            
+            public int getAdcValue()
+            {
+                return _adc_value;
+            }
+            
+            public int encoded()
+            {
+                return ((((getGainRange().ordinal()<<12 & getBufferNumber())<<8) & getTime())<<8) & getAdcValue() ;
+            }
+            
+            public static ReadoutRegisters decoded(int readout)
+            {
+                ReadoutRegisters registers = new ReadoutRegisters();
+                int adc_value = readout &          0xFF;
+                int time = readout &             0xFF00;
+                int buffer_number = readout & 0xFFF0000;
+                int gain_range = readout &   0x10000000;
                 
-        for (Integer channel : electrode_charge.keySet())
+                registers.setAdcValue(adc_value);
+                registers.setTime(time);
+                registers.setBufferNumber(buffer_number);
+                registers.setGainRange(GainRange.values()[gain_range]);
+                
+                return registers;
+            }
+            
+        }
+        
+        ControlRegisters _control_registers;
+        
+        /** Creates a new instance of KpixChannel */
+        public KpixChannel(ControlRegisters control_registers)
         {
-
-            double analog = electrode_charge.get(channel);
-
-            double gain = _high_gain; 
+            _control_registers = control_registers;
+        }
+        
+        private int digitize(SiElectrodeData data)
+        {
+            return computeReadoutRegisters(data).encoded();
+        }
+        
+        private ReadoutRegisters computeReadoutRegisters(SiElectrodeData data)
+        {
+            ReadoutRegisters registers = new ReadoutRegisters();
+            registers.setTime(computeTime());
+            registers.setBufferNumber(computeBufferNumber());
+            registers.setGainRange(computeGainRange(data));
+            registers.setAdcValue(computeAdcValue(data,registers));
             
-            int digital = (int)Math.floor(analog * gain);
-           
-            if (digital != 0) digitized_charge.put(channel,digital);
+            return registers;
+        }
+        
+        private int computeTime()
+        {
+            return 0; // return all hits on bunch crossing 0 for now
+        }
+        
+        private int computeBufferNumber()
+        {
+            return 0; // return all hits in first buffer for now
         }
-        return digitized_charge;
+        
+        private ReadoutRegisters.GainRange computeGainRange(SiElectrodeData data)
+        {
+            if (data.getCharge()*computeNormalFEGain(_control_registers) < _control_registers.getGainCrossover() )
+            {
+                return ReadoutRegisters.GainRange.NORMAL;
+            }
+            else
+            {
+                return ReadoutRegisters.GainRange.LOW;
+            }
+        }
+        
+        private int computeAdcValue(SiElectrodeData data, ReadoutRegisters readout_registers)
+        {
+            double gain = computeGain(readout_registers, _control_registers);
+            return (int)Math.floor(data.getCharge() * gain);
+        }
+        
+        
+        public static double computeGain(ReadoutRegisters readout_registers, ControlRegisters control_registers)
+        {
+            if (readout_registers.getGainRange() == ReadoutRegisters.GainRange.NORMAL)
+            {
+                return (int)Math.floor(computeNormalFEGain(control_registers)*ADC_GAIN);
+            }
+            else
+            {
+                return (int)Math.floor(computeLowFEGain(control_registers)*ADC_GAIN);
+            }
+        }
+        
+        public static double computeNormalFEGain(ControlRegisters control_registers)
+        {
+            double feedback_cap;
+            if (control_registers.getGainMode() == ControlRegisters.GainMode.SINGLE)
+            {
+                feedback_cap = NORMAL_GAIN_CAP;
+            }
+            else
+            {
+                feedback_cap = DOUBLE_GAIN_CAP;
+            }
+            return SystemOfUnits.e_SI/feedback_cap;
+        }
+        
+        public static double computeLowFEGain(ControlRegisters control_registers)
+        {
+            double feedback_cap;
+            if (control_registers.getGainMode() == ControlRegisters.GainMode.SINGLE)
+            {
+                feedback_cap = LOW_GAIN_CAP + NORMAL_GAIN_CAP;
+            }
+            else
+            {
+                feedback_cap = LOW_GAIN_CAP + DOUBLE_GAIN_CAP;
+            }
+            return SystemOfUnits.e_SI/feedback_cap;
+        }
+        
+        public static double computeNoise(double capacitance)
+        {
+            return NOISE_INTERCEPT + capacitance*NOISE_SLOPE;
+        }
+        
     }
     
-    
 }

lcsim/test/org/lcsim/detector/driver
TrackerDigitizationDriverTest.java 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- TrackerDigitizationDriverTest.java	31 Oct 2007 23:24:46 -0000	1.2
+++ TrackerDigitizationDriverTest.java	6 Nov 2007 19:58:03 -0000	1.3
@@ -5,7 +5,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
-import java.util.HashSet;
 import java.util.SortedMap;
 
 import junit.framework.Test;
@@ -29,10 +28,9 @@
 import org.lcsim.contrib.SiStripSim.CDFSiSensorSim;
 import org.lcsim.contrib.SiStripSim.ReadoutChip;
 import org.lcsim.contrib.SiStripSim.Kpix;
-import org.lcsim.contrib.SiStripSim.SiElectrodeDataCollection;
 
 /**
- * Reads 2 muon event generated in sid01_polyhedra, which uses
+ * Reads single muon events generated in sid01_polyhedra, which uses
  * SiTrackerBarrel.  For DetectorElements where there is a
  * Readout containing one hit, check that the hit from the event
  * and the DE's have matching cell id.
@@ -96,6 +94,8 @@
                         if (!hits.isEmpty())
                         {
                             
+                            System.out.println("Simulating sensor: "+sensor.getName());
+                            
                             List<RawTrackerHit> raw_hits = new ArrayList<RawTrackerHit>();
                             si_simulation.simulate(sensor);
                             
@@ -104,20 +104,31 @@
                                 if (sensor.hasElectrodesOnSide(carrier))
                                 {
                                     
-                                    SortedMap<Integer,Integer> digitized_hits = kpix.readout(si_simulation.getReadoutData(carrier).getChargeMap(),sensor.getReadoutElectrodes(carrier));
+//                                    System.out.println("Readout data: "+si_simulation.getReadoutData(carrier).getChargeMap());
+                                    
+                                    SortedMap<Integer,List<Integer>> digitized_hits = kpix.readout(si_simulation.getReadoutData(carrier),sensor.getReadoutElectrodes(carrier));
                                     
                                     // Create RawTrackerHits
-				    for (Integer readout_cell : digitized_hits.keySet())
+                                    
+                                    for (Integer readout_cell : digitized_hits.keySet())
                                     {
                                         int time = 0;
                                         long cell_id = sensor.makeStripId(readout_cell,carrier.charge()).getValue();
-					short[] adc_values = { ((Integer)digitized_hits.get(readout_cell)).shortValue() };
-                                        List<SimTrackerHit> simulated_hits = si_simulation.getReadoutData(carrier).get(readout_cell).getSimulatedHits();
+                                        short[] adc_values = {digitized_hits.get(readout_cell).get(0).shortValue(),digitized_hits.get(readout_cell).get(1).shortValue()};
+                                        
+                                        Set<SimTrackerHit> simulated_hits = si_simulation.getReadoutData(carrier).get(readout_cell).getSimulatedHits();
                                         IDetectorElement detector_element = sensor;
                                         
-                                        RawTrackerHit raw_hit = new BaseRawTrackerHit(time,cell_id,adc_values,simulated_hits,detector_element);
+                                        RawTrackerHit raw_hit = new BaseRawTrackerHit(time,cell_id,adc_values,new ArrayList<SimTrackerHit>(simulated_hits),detector_element);
                                         raw_hits.add(raw_hit);
                                         found_hits = true;
+                                        
+//                                        Kpix.ControlRegisters control_registers = Kpix.ControlRegisters.decoded(raw_hit.getADCValues()[0]);
+//                                        Kpix.KpixChannel.ReadoutRegisters readout_registers = Kpix.KpixChannel.ReadoutRegisters.decoded(raw_hit.getADCValues()[1]);
+//                                        double signal = Kpix.computeCharge(readout_registers, control_registers);
+//                                        
+//                                        System.out.println("Readout data for cell "+readout_cell+": "+si_simulation.getReadoutData(carrier).getChargeMap());
+                                        
                                     }
                                     
                                 }
@@ -133,8 +144,8 @@
                 }
             }
             
-            assertTrue(found_hits);    
-       
+            assertTrue(found_hits);
+            
         }
         
         
CVSspam 0.2.8