hps-java/src/main/java/org/lcsim/hps/recon/tracking
diff -u -r1.11 -r1.12
--- SimpleSvtReadout.java 20 Mar 2013 01:03:32 -0000 1.11
+++ SimpleSvtReadout.java 24 Apr 2013 19:07:33 -0000 1.12
@@ -5,12 +5,15 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Set;
//--- lcsim ---//
import org.lcsim.detector.tracker.silicon.ChargeCarrier;
import org.lcsim.detector.tracker.silicon.SiSensor;
import org.lcsim.event.EventHeader;
import org.lcsim.event.RawTrackerHit;
+import org.lcsim.event.SimTrackerHit;
import org.lcsim.event.base.BaseRawTrackerHit;
import org.lcsim.geometry.Detector;
import org.lcsim.hps.readout.ecal.TriggerableDriver;
@@ -26,18 +29,20 @@
import org.lcsim.util.lcio.LCIOConstants;
/**
- *
+ *
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: SimpleSvtReadout.java,v 1.11 2013/03/20 01:03:32 meeg Exp $
+ * @version $Id: SimpleSvtReadout.java,v 1.12 2013/04/24 19:07:33 meeg Exp $
*/
public class SimpleSvtReadout extends TriggerableDriver {
private SimTrackerHitReadoutDriver readoutDriver = new SimTrackerHitReadoutDriver();
private SiSensorSim siSimulation = new CDFSiSensorSim();
private String outputCollection = "SVTRawTrackerHits";
- private Map<SiSensor, APV25Pipeline[]> pipelineMap = new HashMap<SiSensor, APV25Pipeline[]>();
+ private Map<SiSensor, APV25Pipeline[]> pipelineMap = new HashMap<>();
+ private Map<SiSensor, PriorityQueue<StripHit>[]> hitMap = new HashMap<>();
//readout period time offset in ns
private double readoutOffset = 0.0;
+ private double readoutLatencyT = 240.0;
private int readoutLatency = 11;
private String readout = "TrackerHits";
private int readoutCycle = 0;
@@ -50,12 +55,17 @@
private double noiseThreshold = 2.0;
private boolean enablePileupCut = true;
private boolean dropBadChannels = true;
+ private boolean oldReadout = false;
public SimpleSvtReadout() {
add(readoutDriver);
triggerDelay = 100.0;
}
+ public void setOldReadout(boolean oldReadout) {
+ this.oldReadout = oldReadout;
+ }
+
public void setAddNoise(boolean addNoise) {
this.addNoise = addNoise;
}
@@ -85,7 +95,7 @@
}
/**
- *
+ *
*/
@Override
public void detectorChanged(Detector detector) {
@@ -100,6 +110,10 @@
for (SiSensor sensor : SvtUtils.getInstance().getSensors()) {
APV25Pipeline[] pipelines = new APV25Pipeline[HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR];
pipelineMap.put(sensor, pipelines);
+
+ PriorityQueue<StripHit>[] hitQueues = new PriorityQueue[HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR];
+ hitMap.put(sensor, hitQueues);
+
if (addNoise) {
for (int channel = 0; channel < HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR; channel++) {
pipelines[channel] = new APV25Pipeline(readoutLatency);
@@ -110,7 +124,7 @@
}
/**
- *
+ *
*/
@Override
public void process(EventHeader event) {
@@ -128,6 +142,16 @@
pipelines[i].step();
}
}
+
+ PriorityQueue<StripHit>[] hitQueues = hitMap.get(sensor);
+ for (int i = 0; i < hitQueues.length; i++) {
+ if (hitQueues[i] != null) {
+ while (!hitQueues[i].isEmpty() && hitQueues[i].peek().time < ClockSingleton.getTime() - 500.0) { //TODO: more intelligent time cut
+// System.out.format("Time %f: Dump stale hit with time %f\n",ClockSingleton.getTime(),hitQueues[i].peek().time);
+ hitQueues[i].poll();
+ }
+ }
+ }
}
readoutCycle++;
}
@@ -143,13 +167,19 @@
for (int i = 0; i < 20; i++) {
pipelines[channel].addToCell(i, amplitude * pulseAmplitude((i + 1) * Apv25Constants.SAMPLING_INTERVAL + readoutTime() - ClockSingleton.getTime(), HPSSVTCalibrationConstants.getTShaping(sensor, channel)));
}
+
+ PriorityQueue<StripHit>[] hitQueues = hitMap.get(sensor);
+ if (hitQueues[channel] == null) {
+ hitQueues[channel] = new PriorityQueue<>();
+ }
+ hitQueues[channel].add(stripHit);
}
// If an ECal trigger is received, make hits from pipelines
checkTrigger(event);
} else {
// Create a list to hold the analog data
- List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
+ List<RawTrackerHit> hits = new ArrayList<>();
for (StripHit stripHit : stripHits) {
SiSensor sensor = stripHit.sensor;
@@ -176,6 +206,7 @@
RawTrackerHit hit = new BaseRawTrackerHit(0, cell_id, samples, null, sensor);
// System.out.println("Making RTH");
if (readoutCuts(hit)) {
+ System.out.println("RTH passed cuts");
hits.add(hit);
}
}
@@ -187,7 +218,7 @@
}
private List<StripHit> doSiSimulation() {
- List<StripHit> stripHits = new ArrayList<StripHit>();
+ List<StripHit> stripHits = new ArrayList<>();
for (SiSensor sensor : SvtUtils.getInstance().getSensors()) {
// Set the sensor to be used in the charge deposition simulation
@@ -214,6 +245,17 @@
// Get the electrode data for this channel
SiElectrodeData electrodeData = electrodeDataCol.get(channel);
+ Set<SimTrackerHit> simHits = electrodeData.getSimulatedHits();
+
+ // compute hit time as the unweighted average of SimTrackerHit times; this is dumb but okay since there's generally only one SimTrackerHit
+ double time = 0.0;
+ if (!oldReadout) {
+ for (SimTrackerHit hit : simHits) {
+ time += hit.getTime();
+ }
+ time /= simHits.size();
+ time += ClockSingleton.getTime();
+ }
// Get the charge in units of electrons
double charge = electrodeData.getCharge();
@@ -222,7 +264,7 @@
double inputStageGain = 1.5;
double amplitude = (charge / Apv25Constants.MIP) * resistorValue * inputStageGain * Math.pow(2, 14) / 2000;
- stripHits.add(new StripHit(sensor, channel, amplitude));
+ stripHits.add(new StripHit(sensor, channel, amplitude, time, simHits));
}
}
}
@@ -241,14 +283,24 @@
return samples;
}
+ private void addNoise(SiSensor sensor, int channel, double[] signal) {
+ double noise = HPSSVTCalibrationConstants.getNoise(sensor, channel);
+ for (int i = 0; i < 6; i++) {
+ signal[i] += RandomGaussian.getGaussian(0, noise);
+ }
+ }
+
private boolean readoutCuts(RawTrackerHit hit) {
if (enableThresholdCut && !samplesAboveThreshold(hit)) {
+// System.out.println("Failed threshold cut");
return false;
}
if (enablePileupCut && !pileupCut(hit)) {
+// System.out.println("Failed pileup cut");
return false;
}
if (dropBadChannels && !badChannelCut(hit)) {
+// System.out.println("Failed bad channel cut");
return false;
}
return true;
@@ -288,27 +340,70 @@
// System.out.println("Got trigger");
// Create a list to hold the analog data
- List<RawTrackerHit> hits = new ArrayList<RawTrackerHit>();
+ List<RawTrackerHit> hits = new ArrayList<>();
+ // Calculate time of first sample
+ double firstSample = Math.floor((ClockSingleton.getTime() - readoutLatencyT - readoutOffset) / Apv25Constants.SAMPLING_INTERVAL) * Apv25Constants.SAMPLING_INTERVAL + readoutOffset;
for (SiSensor sensor : SvtUtils.getInstance().getSensors()) {
- APV25Pipeline[] pipelines = pipelineMap.get(sensor);
- for (int channel = 0; channel < pipelines.length; channel++) {
- if (pipelines[channel] != null) {
+ if (oldReadout) {
+ APV25Pipeline[] pipelines = pipelineMap.get(sensor);
+ for (int channel = 0; channel < pipelines.length; channel++) {
+ if (pipelines[channel] != null) {
+ short[] samples = new short[6];
+ if (addNoise) {
+ double[] noise = makeNoise(sensor, channel);
+ for (int i = 0; i < 6; i++) {
+ samples[i] = (short) Math.round(pipelines[channel].getValue(i) + HPSSVTCalibrationConstants.getPedestal(sensor, channel) + noise[i]);
+ }
+ } else {
+ for (int i = 0; i < 6; i++) {
+ samples[i] = (short) Math.round(pipelines[channel].getValue(i) + HPSSVTCalibrationConstants.getPedestal(sensor, channel));
+ }
+ }
+ long cell_id = SvtUtils.makeCellID(sensor, channel);
+
+ RawTrackerHit hit = new BaseRawTrackerHit(0, cell_id, samples, null, sensor);
+// System.out.println("Making RTH");
+ if (readoutCuts(hit)) {
+ hits.add(hit);
+ }
+ }
+ }
+ } else {
+ PriorityQueue<StripHit>[] hitQueues = hitMap.get(sensor);
+ for (int channel = 0; channel < hitQueues.length; channel++) {
+ if (!addNoise && (hitQueues[channel] == null || hitQueues[channel].isEmpty())) {
+ continue;
+ }
short[] samples = new short[6];
+ double[] signal = new double[6];
+ for (int i = 0; i < 6; i++) {
+ signal[i] = HPSSVTCalibrationConstants.getPedestal(sensor, channel);
+ }
if (addNoise) {
- double[] noise = makeNoise(sensor, channel);
- for (int i = 0; i < 6; i++) {
- samples[i] = (short) Math.round(pipelines[channel].getValue(i) + HPSSVTCalibrationConstants.getPedestal(sensor, channel) + noise[i]);
- }
- } else {
- for (int i = 0; i < 6; i++) {
- samples[i] = (short) Math.round(pipelines[channel].getValue(i) + HPSSVTCalibrationConstants.getPedestal(sensor, channel));
+ addNoise(sensor, channel, signal);
+ }
+
+ if (hitQueues[channel] != null) {
+ for (StripHit hit : hitQueues[channel]) {
+ for (int i = 0; i < 6; i++) {
+ double sampleTime = firstSample + i * Apv25Constants.SAMPLING_INTERVAL;
+ signal[i] += hit.amplitude * pulseAmplitude(sampleTime - hit.time, HPSSVTCalibrationConstants.getTShaping(sensor, channel));
+// System.out.format("new value of signal[%d] = %f\n", i, signal[i]);
+ }
}
}
- long cell_id = SvtUtils.makeCellID(sensor, channel);
+ for (int i = 0; i < 6; i++) {
+ samples[i] = (short) Math.round(signal[i]);
+ }
+// if (hitQueues[channel] != null && !hitQueues[channel].isEmpty()) {
+// for (int i = 0; i < 6; i++) {
+// System.out.format("samples[%d] = %d\n", i, samples[i]);
+// }
+// }
+ long cell_id = SvtUtils.makeCellID(sensor, channel);
RawTrackerHit hit = new BaseRawTrackerHit(0, cell_id, samples, null, sensor);
-// System.out.println("Making RTH");
if (readoutCuts(hit)) {
hits.add(hit);
}
@@ -341,7 +436,7 @@
/**
* Set the trigger latency
- *
+ *
* @param latency : trigger latency in [ns]
*/
public void setTriggerLatency(int latency) {
@@ -357,7 +452,7 @@
}
/**
- *
+ *
*/
@Override
public String toString() {
@@ -375,16 +470,32 @@
}
}
- private class StripHit {
+ private class StripHit implements Comparable {
SiSensor sensor;
int channel;
double amplitude;
+ double time;
+ Set<SimTrackerHit> simHits;
- public StripHit(SiSensor sensor, int channel, double amplitude) {
+ public StripHit(SiSensor sensor, int channel, double amplitude, double time, Set<SimTrackerHit> simHits) {
this.sensor = sensor;
this.channel = channel;
this.amplitude = amplitude;
+ this.time = time;
+ this.simHits = simHits;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ double deltaT = time - ((StripHit) o).time;
+ if (deltaT > 0) {
+ return 1;
+ } else if (deltaT < 0) {
+ return -1;
+ } else {
+ return 0;
+ }
}
}