Print

Print


Commit in hps-java/src/main/java/org/lcsim/hps/users/meeg on MAIN
SimpleTrackerDigiDriver.java+317added 1.1
NoiselessReadoutChip.java+314added 1.1
+631
2 added files
lobotomized version of TrackerDigiDriver, for testing

hps-java/src/main/java/org/lcsim/hps/users/meeg
SimpleTrackerDigiDriver.java added at 1.1
diff -N SimpleTrackerDigiDriver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ SimpleTrackerDigiDriver.java	29 Aug 2012 21:01:36 -0000	1.1
@@ -0,0 +1,317 @@
+package org.lcsim.hps.users.meeg;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.lcsim.detector.IDetectorElement;
+import org.lcsim.detector.identifier.IIdentifier;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiTrackerIdentifierHelper;
+import org.lcsim.detector.tracker.silicon.SiTrackerModule;
+import org.lcsim.event.EventHeader;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.SimTrackerHit;
+import org.lcsim.geometry.Detector;
+import org.lcsim.hps.recon.tracking.SvtUtils;
+import org.lcsim.recon.tracking.digitization.sisim.CDFSiSensorSim;
+import org.lcsim.recon.tracking.digitization.sisim.NearestNeighborRMS;
+import org.lcsim.recon.tracking.digitization.sisim.RawTrackerHitMaker;
+import org.lcsim.recon.tracking.digitization.sisim.SiDigitizer;
+import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHit;
+import org.lcsim.recon.tracking.digitization.sisim.SiTrackerHitStrip1D;
+import org.lcsim.recon.tracking.digitization.sisim.StripHitMaker;
+import org.lcsim.recon.tracking.digitization.sisim.config.SimTrackerHitReadoutDriver;
+import org.lcsim.util.Driver;
+import org.lcsim.util.lcio.LCIOUtil;
+
+/**
+ * This Driver runs the tracker digitization to create raw hits and strip hits
+ * from simulated data. The output can be used by a track reconstruction
+ * algorithm like Seed Tracker.
+ * 
+ * @author jeremym
+ * @version $Id: SimpleTrackerDigiDriver.java,v 1.1 2012/08/29 21:01:36 meeg Exp $
+ */
+public class SimpleTrackerDigiDriver extends Driver {
+    // Debug switch for development.
+
+    private boolean debug = false;
+    // Collection name.
+    private String readoutCollectionName = "TrackerHits";
+    // Subdetector name.
+    private String subdetectorName = "Tracker";
+    // Name of RawTrackerHit output collection.
+    private String rawTrackerHitOutputCollectionName = "RawTrackerHitMaker_RawTrackerHits";
+    // Name of StripHit1D output collection.
+    private String stripHitOutputCollectionName = "StripClusterer_SiTrackerHitStrip1D";
+    // Readout parameters.
+    private boolean dropBadChannels = true;
+    private double readoutNoiseIntercept = 270.0;
+    private double readoutNoiseSlope = 36.0;
+    private int readoutNBits = 10;
+    private int readoutDynamicRange = 40;
+    // Clustering parameters.
+    private double clusterSeedThreshold = 4.0;
+    private double clusterNeighborThreshold = 3.0;
+    private double clusterThreshold = 4.0;
+    private int clusterMaxSize = 10;
+    private int clusterCentralStripAveragingThreshold = 4;
+    // Clustering errors by number of TrackerHits.
+    private static final double clusterErrorMultiplier = 1.0;
+    private double oneClusterErr = clusterErrorMultiplier / Math.sqrt(12.);
+    private double twoClusterErr = clusterErrorMultiplier / 5.0;
+    private double threeClusterErr = clusterErrorMultiplier / 3.0;
+    private double fourClusterErr = clusterErrorMultiplier / 2.0;
+    private double fiveClusterErr = clusterErrorMultiplier / 1.0;
+    // Various data lists required by digitization.
+    private List<String> readouts = new ArrayList<String>();
+    private List<String> processPaths = new ArrayList<String>();
+    private List<IDetectorElement> processDEs = new ArrayList<IDetectorElement>();
+    private Set<SiSensor> processSensors = new HashSet<SiSensor>();
+    private Set<SiTrackerModule> processModules = new HashSet<SiTrackerModule>();
+    // Digi class objects.
+    private SiDigitizer stripDigitizer;
+    private StripHitMaker stripClusterer;
+    int[][] counts = new int[2][10];
+
+    public void setDebug(boolean debug) {
+        this.debug = debug;
+    }
+
+    public void setReadoutCollectionName(String readoutCollectionName) {
+        this.readoutCollectionName = readoutCollectionName;
+    }
+
+    public void setSubdetectorName(String subdetectorName) {
+        this.subdetectorName = subdetectorName;
+    }
+
+    public void setRawTrackerHitOutputCollectionName(String rawTrackerHitOutputCollectionName) {
+        this.rawTrackerHitOutputCollectionName = rawTrackerHitOutputCollectionName;
+    }
+
+    public void setStripHitOutputCollectionName(String stripHitOutputCollectionName) {
+        this.stripHitOutputCollectionName = stripHitOutputCollectionName;
+    }
+
+    public void setDropBadChannels(boolean dropBadChannels) {
+        this.dropBadChannels = dropBadChannels;
+    }
+
+    public void setReadoutNoiseIntercept(double readoutNoiseIntercept) {
+        this.readoutNoiseIntercept = readoutNoiseIntercept;
+    }
+
+    public void setReadoutNoiseSlope(double readoutNoiseSlope) {
+        this.readoutNoiseSlope = readoutNoiseSlope;
+    }
+
+    public void setReadoutNBits(int readoutNBits) {
+        this.readoutNBits = readoutNBits;
+    }
+
+    public void setReadoutDynamicRange(int readoutDynamicRange) {
+        this.readoutDynamicRange = readoutDynamicRange;
+    }
+
+    public void setClusterSeedThreshold(double clusterSeedThreshold) {
+        this.clusterSeedThreshold = clusterSeedThreshold;
+    }
+
+    public void setClusterNeighborThreshold(double clusterNeighborThreshold) {
+        this.clusterNeighborThreshold = clusterNeighborThreshold;
+    }
+
+    public void setClusterThreshold(double clusterThreshold) {
+        this.clusterThreshold = clusterThreshold;
+    }
+
+    public void setClusterMaxSize(int clusterMaxSize) {
+        this.clusterMaxSize = clusterMaxSize;
+    }
+
+    public void setClusterCentralStripAveragingThreshold(int clusterCentralStripAveragingThreshold) {
+        this.clusterCentralStripAveragingThreshold = clusterCentralStripAveragingThreshold;
+    }
+
+    public void setOneClusterErr(double oneClusterErr) {
+        this.oneClusterErr = oneClusterErr;
+    }
+
+    public void setTwoClusterErr(double twoClusterErr) {
+        this.twoClusterErr = twoClusterErr;
+    }
+
+    public void setThreeClusterErr(double threeClusterErr) {
+        this.threeClusterErr = threeClusterErr;
+    }
+
+    public void setFourClusterErr(double fourClusterErr) {
+        this.fourClusterErr = fourClusterErr;
+    }
+
+    public void setFiveClusterErr(double fiveClusterErr) {
+        this.fiveClusterErr = fiveClusterErr;
+    }
+
+    /**
+     * Creates a new instance of TrackerHitDriver.
+     */
+    public SimpleTrackerDigiDriver() {
+    }
+
+    /**
+     * Initializes this Driver's objects with the job parameters.
+     */
+    private void initialize() {
+
+        // Create the sensor simulation.
+        CDFSiSensorSim stripSim = new CDFSiSensorSim();
+
+        // Create the readout chips and set the noise parameters.
+        NoiselessReadoutChip stripReadout = new NoiselessReadoutChip();
+        stripReadout.setDropBadChannels(dropBadChannels);
+        stripReadout.setNoiseIntercept(readoutNoiseIntercept);
+        stripReadout.setNoiseSlope(readoutNoiseSlope);
+        stripReadout.setNbits(readoutNBits);
+        stripReadout.setDynamicRange(readoutDynamicRange);
+
+        // Create the digitizer that produces the raw hits
+        stripDigitizer = new RawTrackerHitMaker(stripSim, stripReadout);
+
+        // Create Strip clustering algorithm.
+        NearestNeighborRMS stripClusteringAlgo = new NearestNeighborRMS();
+        stripClusteringAlgo.setSeedThreshold(clusterSeedThreshold);
+        stripClusteringAlgo.setNeighborThreshold(clusterNeighborThreshold);
+        stripClusteringAlgo.setClusterThreshold(clusterThreshold);
+
+        // Create the clusterers and set hit-making parameters.
+        stripClusterer = new StripHitMaker(stripSim, stripReadout, stripClusteringAlgo);
+        stripClusterer.setMaxClusterSize(clusterMaxSize);
+        stripClusterer.setCentralStripAveragingThreshold(clusterCentralStripAveragingThreshold);
+
+        // Set the cluster errors.
+        stripClusterer.SetOneClusterErr(oneClusterErr);
+        stripClusterer.SetTwoClusterErr(twoClusterErr);
+        stripClusterer.SetThreeClusterErr(threeClusterErr);
+        stripClusterer.SetFourClusterErr(fourClusterErr);
+        stripClusterer.SetFiveClusterErr(fiveClusterErr);
+
+        // Set the readout to process.
+        readouts.add(readoutCollectionName);
+
+        // Set the detector to process.
+        processPaths.add(subdetectorName);
+    }
+
+    /**
+     * This is executed before detectorChanged and initialization of
+     * digitization objects is done here.
+     */
+    @Override
+    public void startOfData() {
+
+        // At start of job, setup digitization objects needed by this Driver.
+        initialize();
+
+        // If readouts not already set, set them up.
+        if (!readouts.isEmpty()) {
+            System.out.println("Adding SimTrackerHitIdentifierReadoutDriver with readouts: " + readouts);
+            super.add(new SimTrackerHitReadoutDriver(readouts));
+        }
+        super.startOfData();
+        readouts.clear(); // FIXME Is this needed?
+    }
+
+    /**
+     * Do initialization once we get a Detector.
+     */
+    @Override
+    public void detectorChanged(Detector detector) {
+
+        // Call sub-Driver's detectorChanged methods.
+        super.detectorChanged(detector);
+
+        // Process detectors specified by path, otherwise process entire
+        // detector
+        IDetectorElement deDetector = detector.getDetectorElement();
+
+        for (String path : processPaths) {
+            processDEs.add(deDetector.findDetectorElement(path));
+        }
+
+        if (processDEs.isEmpty()) {
+            processDEs.add(deDetector);
+        }
+
+        for (IDetectorElement detectorElement : processDEs) {
+            processSensors.addAll(detectorElement.findDescendants(SiSensor.class));
+            //if (debug)
+            //    System.out.println("added " + processSensors.size() + " sensors");
+            processModules.addAll(detectorElement.findDescendants(SiTrackerModule.class));
+            //if (debug)
+            //    System.out.println("added " + processModules.size() + " modules");
+        }
+    }
+
+    /**
+     * Perform the digitization.
+     */
+    @Override
+    public void process(EventHeader event) {
+        // Call sub-Driver processing.
+        super.process(event);
+
+        // Make new lists for output.
+        List<RawTrackerHit> rawHits = new ArrayList<RawTrackerHit>();
+        List<SiTrackerHit> stripHits1D = new ArrayList<SiTrackerHit>();
+
+        if (event.hasCollection(SimTrackerHit.class, this.readoutCollectionName)) {
+            // Make raw hits.
+            for (SiSensor sensor : processSensors) {
+                rawHits.addAll(stripDigitizer.makeHits(sensor));
+            }
+
+            // Make strip hits.
+            for (SiSensor sensor : processSensors) {
+                stripHits1D.addAll(stripClusterer.makeHits(sensor));
+            }
+
+            // Debug prints.
+            if (debug) {
+                if (event.hasCollection(SimTrackerHit.class, this.readoutCollectionName)) {
+                    List<SimTrackerHit> simHits = event.get(SimTrackerHit.class, this.readoutCollectionName);
+                    System.out.println("SimTrackerHit collection " + this.readoutCollectionName + " has " + simHits.size() + " hits.");
+                    System.out.println("RawTrackerHit collection " + this.rawTrackerHitOutputCollectionName + " has " + rawHits.size() + " hits.");
+                    System.out.println("TrackerHit collection " + this.stripHitOutputCollectionName + " has " + stripHits1D.size() + " hits.");
+                } else {
+                    System.out.println("SimTrackerHit collection " + this.readoutCollectionName + " not found.");
+                }
+            }
+        }
+
+        if (debug) {
+            for (int mod = 0; mod < 2; mod++) {
+                for (int layer = 0; layer < 10; layer++) {
+                    counts[mod][layer] += SvtUtils.getInstance().getSensor(mod, layer).getReadout().getHits(RawTrackerHit.class).size();
+                }
+            }
+        }
+        // Put output hits into collection.
+        int flag = LCIOUtil.bitSet(0, 31, true); // Turn on 64-bit cell ID.
+        event.put(this.rawTrackerHitOutputCollectionName, rawHits, RawTrackerHit.class, flag, toString());
+        event.put(this.stripHitOutputCollectionName, stripHits1D, SiTrackerHitStrip1D.class, 0, toString());
+    }
+
+    public void endOfData() {
+        if (debug) {
+            for (int mod = 0; mod < 2; mod++) {
+                for (int layer = 0; layer < 10; layer++) {
+                    System.out.format("mod %d, layer %d, count %d, ID %d\n", mod, layer, counts[mod][layer], SvtUtils.getInstance().getSensor(mod, layer).getIdentifier().getValue());
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

hps-java/src/main/java/org/lcsim/hps/users/meeg
NoiselessReadoutChip.java added at 1.1
diff -N NoiselessReadoutChip.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ NoiselessReadoutChip.java	29 Aug 2012 21:01:36 -0000	1.1
@@ -0,0 +1,314 @@
+/*
+ * Class BasicReadoutChip
+ */
+package org.lcsim.hps.users.meeg;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import org.lcsim.detector.tracker.silicon.SiSensor;
+import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.hps.recon.tracking.HPSSVTCalibrationConstants;
+import org.lcsim.recon.tracking.digitization.sisim.ReadoutChip;
+import org.lcsim.recon.tracking.digitization.sisim.ReadoutChip.ReadoutChannel;
+import org.lcsim.recon.tracking.digitization.sisim.SiElectrodeData;
+import org.lcsim.recon.tracking.digitization.sisim.SiElectrodeDataCollection;
+
+/**
+ * Basic readout chip class.  This class supports the minimal functions expected of
+ * a readout chip.  The charge on a strip/pixel is digitized as an integer number
+ * with a simple ADC with programmable resolution and dynamic range.  A chip with
+ * 1-bit ADC resolution (binary readout) is treated as a special case.
+ * 
+ * Noise is added to strips with charge and random noise hits are generated as well.
+ * Methods are provided to decode the charge and time (although the current
+ * implementation always returns a time of 0).
+ *
+ * This implementation has thresholds that are settable in units of RMS noise of
+ * each channel to enable simluation of highly optimized readout chains.  If
+ * absolute thresholds are desired, GenericReadoutChip should be used instead.
+ *
+ * @author Tim Nelson
+ */
+public class NoiselessReadoutChip implements ReadoutChip {
+
+    private BasicChannel _channel = new BasicChannel();
+    private ADC _adc = new ADC();
+    private boolean dropBadChannels = false;
+
+    /** Creates a new instance of BasicReadoutChip */
+    public NoiselessReadoutChip() {
+    }
+
+    public void setDropBadChannels(boolean dropBadChannels) {
+        this.dropBadChannels = dropBadChannels;
+    }
+
+    /**
+     * Set the noise intercept (i.e., the noise for 0 strip/pixel capacitance).
+     * Units are electrons of noise.
+     *
+     * @param noise_intercept noise for 0 capacitance
+     */
+    public void setNoiseIntercept(double noise_intercept) {
+        _channel.setNoiseIntercept(noise_intercept);
+    }
+
+    /**
+     * Set the noise slope (i.e., the proportionality between noise and capacitance).
+     * Units are electrons of noise per fF of capacitance.
+     *
+     * @param noise_slope noise slope per unit capacitance
+     */
+    public void setNoiseSlope(double noise_slope) {
+        _channel.setNoiseSlope(noise_slope);
+    }
+
+    /**
+     * Set the number of bits of ADC resolution
+     *
+     * @param nbits
+     */
+    public void setNbits(int nbits) {
+        getADC().setNbits(nbits);
+    }
+
+    /**
+     * Set the dynamic range of the ADC
+     *
+     * @param dynamic_range in fC
+     */
+    public void setDynamicRange(double dynamic_range) {
+        getADC().setDynamicRange(dynamic_range);
+    }
+
+    /**
+     * Return the BasicChannel associated with a given channel number.
+     * For the basic readout, there is a single instance of BasicChannel
+     * and thus the channel number is ignored.
+     *
+     * @param channel_number channel number
+     * @return associated BasicReadoutChannel
+     */
+    public BasicChannel getChannel(int channel_number) {
+        return _channel;
+    }
+
+    private ADC getADC() {
+        return _adc;
+    }
+
+    /**
+     * Given a collection of electrode data (i.e., charge on strips/pixels),
+     * return a map associating the channel and it's list of raw data.
+     *
+     * @param data  electrode data from the charge distribution
+     * @param electrodes  strip or pixel electrodes
+     * @return  map containing the ADC counts for this sensor
+     */
+    public SortedMap<Integer, List<Integer>> readout(SiElectrodeDataCollection data, SiSensorElectrodes electrodes) {
+
+        //  If there is no electrode data for this readout chip,  create an empty
+        //  electrode data collection
+        if (data == null) {
+            data = new SiElectrodeDataCollection();
+        }
+
+        //  Add noise hits to the electrode data collection
+//        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
+        return digitize(data, electrodes);
+    }
+
+    /**
+     * Decode the hit charge stored in the RawTrackerHit
+     *
+     * @param hit raw hit
+     * @return hit charge in units of electrons
+     */
+    public double decodeCharge(RawTrackerHit hit) {
+        return getADC().decodeCharge(hit.getADCValues()[0]);
+    }
+
+    /**
+     * Decode the hit time.  Currently, the basic readout chip ignores the
+     * hit time and returns 0.
+     *
+     * @param hit raw hit data
+     * @return hit time
+     */
+    public int decodeTime(RawTrackerHit hit) {
+        return 0;
+    }
+
+    /**
+     * Digitizes the hit channels in a SiElectrodeDataCollection.
+     *
+     * The SiElectrodeDataCollection is a map that associates a given channel with
+     * it's SiElectrodeData.  The SiElectrodeData encapsulates the deposited charge
+     * on an strip/pixel and any associated SimTrackerHits.
+     *
+     * The output of this class is a map that associates a channel number with
+     * a list of raw data
+     *
+     * @param data electrode data collection
+     * @return map associating channels with a list of raw data
+     */
+    private SortedMap<Integer, List<Integer>> digitize(SiElectrodeDataCollection data,
+            SiSensorElectrodes electrodes) {
+        //  Create the map that associates a given sensor channel with it's list of raw data
+        SortedMap<Integer, List<Integer>> chip_data = new TreeMap<Integer, List<Integer>>();
+
+        //  Loop over the channels contained in the SiElectrodeDataCollection
+        for (Integer channel : data.keySet()) {
+            if (dropBadChannels && HPSSVTCalibrationConstants.isBadChannel((SiSensor) electrodes.getDetectorElement(), channel)) {
+//                System.out.format("%d bad\n", channel);
+                continue;
+            }
+//                System.out.format("%d OK\n", channel);
+            //  Fetch the electrode data for this channel
+            SiElectrodeData eldata = data.get(channel);
+
+            //  Get the charge in units of electrons
+            double charge = eldata.getCharge();
+
+            //  Calculate the ADC value for this channel and make sure it is positive
+            int adc = getADC().convert(charge);
+            if (adc <= 0) {
+                continue;
+            }
+
+            //  Create a list containing the adc value - for the basic readout
+            //  there is only 1 word of raw data
+            List<Integer> channel_data = new ArrayList<Integer>();
+            channel_data.add(adc);
+
+            //  Save the list of raw data in the chip_data map
+            chip_data.put(channel, channel_data);
+        }
+
+        return chip_data;
+    }
+
+    /**
+     * BasicChannel class representing a single channel's behavior
+     *
+     * Note that binary readout is a special case.  Anything positive value
+     * passed to a binary ADC for digitization is assumed to have crossed t
+     * hreshold and is assigned a value of 1.  Decoding binary readout results
+     * in either 0 or dynamic_range.
+     */
+    private class BasicChannel implements ReadoutChannel {
+
+        private double _noise_intercept = 0.;
+        private double _noise_slope = 0.;
+
+        /**
+         * Set the noise (in electrons) for 0 capacitance
+         *
+         * @param noise_intercept noise intercept
+         */
+        private void setNoiseIntercept(double noise_intercept) {
+            _noise_intercept = noise_intercept;
+        }
+
+        /**
+         * Set the capacitative noise slope (in electrons / pF)
+         *
+         * @param noise_slope noise slope
+         */
+        private void setNoiseSlope(double noise_slope) {
+            _noise_slope = noise_slope;
+        }
+
+        /**
+         * Return the noise in electrons for a given strip/pixel capacitance
+         *
+         * @param capacitance capacitance in pF
+         * @return noise in electrons
+         */
+        public double computeNoise(double capacitance) {
+            return _noise_intercept + _noise_slope * capacitance;
+        }
+    }
+
+    /**
+     * ADC class representing analog to digital converter.
+     */
+    private class ADC {
+
+        private int _nbits = 8;
+        private double _dynamic_range = 20.;
+
+        /**
+         * Set the ADC resolution in number of bits.
+         *
+         * @param nbits number of bits
+         */
+        private void setNbits(int nbits) {
+            _nbits = nbits;
+        }
+
+        /**
+         * Set the dynamic range in fC
+         *
+         * @param dynamic range
+         */
+        private void setDynamicRange(double dynamic_range) {
+            _dynamic_range = dynamic_range;
+        }
+
+        /**
+         * Compute the maximum ADC value
+         *
+         * @return largest possible ADC value according to # of bits
+         */
+        private int maxADCValue() {
+            return (int) Math.pow(2, _nbits) - 1;
+        }
+
+        /**
+         * Compute the conversion constant in ADC/fC
+         *
+         * @return conversion constant for ADC
+         */
+        private double conversionConstant() {
+            return maxADCValue() / _dynamic_range;
+        }
+
+        /**
+         * Perform analog to digital conversion
+         *
+         * @return digital ADC output between 0 and maxADCValue
+         */
+        public int convert(double charge) {
+            if (_nbits != 1) {
+                return Math.max(0, Math.min(maxADCValue(), (int) Math.floor(charge * 1.602e-4 * conversionConstant())));
+            } else {
+                if (charge <= 0.0) {
+                    return 0;
+                } else {
+                    return 1;
+                }
+            }
+        }
+
+        /**
+         * Decode charge from ADC value
+         *
+         * @return charge specified by a given ADC value
+         */
+        public double decodeCharge(int adc_value) {
+            if (_nbits != 1) {
+                return (adc_value + 0.5) / (1.602e-4 * conversionConstant());
+            } else {
+                return adc_value * _dynamic_range;
+            }
+
+        }
+    }
+}
CVSspam 0.2.12


Use REPLY-ALL to reply to list

To unsubscribe from the LCD-CVS list, click the following link:
https://listserv.slac.stanford.edu/cgi-bin/wa?SUBED1=LCD-CVS&A=1