5 modified files
lcsim/src/org/lcsim/contrib/RobKutschke/TKNHits
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
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
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
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
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