hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.7 -r1.8
--- Apv25Full.java 30 Aug 2012 03:31:59 -0000 1.7
+++ Apv25Full.java 15 Sep 2012 01:28:28 -0000 1.8
@@ -15,12 +15,14 @@
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: Apv25Full.java,v 1.7 2012/08/30 03:31:59 omoreno Exp $
+ * @version $Id: Apv25Full.java,v 1.8 2012/09/15 01:28:28 omoreno Exp $
*/
public class Apv25Full {
// APV25 trigger bit
public static boolean readoutBit = false;
+ protected int triggerLatency = 0; // Clock cycles
+ protected int triggerLatencyTime = 240; // ns
// APV25 Channels; An APV25 Readout Chip contains a total of 128 channels
private Apv25Channel[] channels = new Apv25Channel[CHANNELS];
@@ -34,6 +36,16 @@
for(int channelN = 0; channelN < CHANNELS; channelN++){
channels[channelN] = new Apv25Channel();
}
+ // Set the trigger latency
+ this.setLatency(triggerLatencyTime);
+ }
+
+ /**
+ *
+ */
+ public void setLatency(int triggerLatencyTime /*ns*/){
+ this.triggerLatency = (int) Math.floor(triggerLatencyTime/SAMPLING_INTERVAL);
+ for(int channelN = 0; channelN < CHANNELS; channelN++) channels[channelN].getPipeline().resetPointerPositions();
}
/**
@@ -179,8 +191,6 @@
// TODO: Possibly store the pipeline in the event
// Note: ptr gives the position of the trigger pointer
-
- private int triggerLatency = 0;
private int writerPointer = 0;
/**
@@ -191,20 +201,15 @@
// Initialize the pipeline to the APV25 pipeline length
super(ANALOG_PIPELINE_LENGTH);
- triggerLatency = (int) Math.floor(220 /* ns */ / SAMPLING_INTERVAL);
-
// Initialize the position of the trigger pointer to a random position
this.ptr = (int) (Math.random()*ANALOG_PIPELINE_LENGTH);
-
- // Set the position of the writer pointer
- writerPointer = (ptr + triggerLatency)%ANALOG_PIPELINE_LENGTH;
}
/**
*
*/
- public void setLatency(int triggerLatency /*ns*/){
- triggerLatency = (int) Math.floor(triggerLatency/SAMPLING_INTERVAL);
+ public void resetPointerPositions(){
+ writerPointer = (ptr + triggerLatency)%ANALOG_PIPELINE_LENGTH;
}
/**
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.5 -r1.6
--- SvtHalfModule.java 30 Aug 2012 03:31:59 -0000 1.5
+++ SvtHalfModule.java 15 Sep 2012 01:28:29 -0000 1.6
@@ -3,7 +3,6 @@
//--- constants ---//
import static org.lcsim.hps.recon.tracking.HPSSVTConstants.TOTAL_APV25_PER_HYBRID;
import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.CHANNELS;
-import static org.lcsim.hps.recon.tracking.HPSSVTConstants.RTM_GAIN;
//--- lcsim ---//
import org.lcsim.detector.tracker.silicon.SiSensor;
@@ -12,7 +11,7 @@
/**
*
* @author Omar Moreno
- * @version $Id: SvtHalfModule.java,v 1.5 2012/08/30 03:31:59 omoreno Exp $
+ * @version $Id: SvtHalfModule.java,v 1.6 2012/09/15 01:28:29 omoreno Exp $
*/
public class SvtHalfModule {
@@ -29,10 +28,12 @@
apv25[chip] = new Apv25Full();
for(int channel = 0; channel < CHANNELS; channel++){
int physicalChannel = 639 - (chip*128 + 127 - channel);
+
// Mark all bad channels which were found during QA
if(HPSSVTCalibrationConstants.isBadChannel(sensor, physicalChannel)){
apv25[chip].getChannel(channel).markAsBadChannel();
}
+
// Set the shaping time
double tp = HPSSVTCalibrationConstants.getTShaping(sensor, physicalChannel);
apv25[chip].getChannel(channel).setShapingTime(tp);
@@ -55,10 +56,4 @@
public Apv25Full[] getAllApv25s(){
return apv25;
}
-
- public void incrementPointerPositions(){
- for(int chip = 0; chip < TOTAL_APV25_PER_HYBRID; chip++){
- apv25[chip].incrementPointerPositions();
- }
- }
}
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.6 -r1.7
--- SvtReadout.java 6 Sep 2012 09:30:03 -0000 1.6
+++ SvtReadout.java 15 Sep 2012 01:28:29 -0000 1.7
@@ -13,7 +13,6 @@
//--- lcsim ---//
import org.lcsim.detector.tracker.silicon.ChargeCarrier;
import org.lcsim.detector.tracker.silicon.SiSensor;
-import org.lcsim.detector.tracker.silicon.SiSensorElectrodes;
import org.lcsim.event.EventHeader;
import org.lcsim.geometry.Detector;
import org.lcsim.recon.tracking.digitization.sisim.CDFSiSensorSim;
@@ -30,34 +29,43 @@
//--- Constants ---//
import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.SAMPLING_INTERVAL;
import static org.lcsim.hps.recon.tracking.HPSSVTConstants.TOTAL_APV25_CHANNELS;
-import static org.lcsim.hps.recon.tracking.HPSSVTConstants.TOTAL_APV25_PER_HYBRID;
import static org.lcsim.hps.recon.tracking.HPSSVTConstants.TOTAL_NUMBER_OF_SAMPLES;
import static org.lcsim.hps.recon.tracking.HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR;
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: SvtReadout.java,v 1.6 2012/09/06 09:30:03 omoreno Exp $
+ * @version $Id: SvtReadout.java,v 1.7 2012/09/15 01:28:29 omoreno Exp $
*/
public class SvtReadout extends Driver {
- Set<SvtHalfModule> halfModules = new HashSet<SvtHalfModule>();
+ private Set<SvtHalfModule> halfModules = new HashSet<SvtHalfModule>();
private SiSensorSim siSimulation = new CDFSiSensorSim();
- String apv25AnalogDataCollectioName = "APV25AnalogData";
- // FIFO queue to store "local" triggers by time
- private Queue<Double> triggerQueue = new LinkedList<Double>();
+ // FIFO queue used to store readout times
+ private Queue<Double> fifo = new LinkedList<Double>();
+
List<String> readouts = new ArrayList<String>();
Map<SiSensor, List<Integer>> sensorToChannel = new HashMap<SiSensor, List<Integer>>();
- double readoutDeadTime = 24; // ns
+ // Assuming at 41.6 MHz clock, minimum readout time per sample is 3.36 us
+ // For now, a dead time of 250 ns is fine
+ double readoutDeadTimePerSample = 250; // ns
double lastTriggerTime = 0;
+ static private int nTriggers = 0;
+ int nTriggersDropped = 0;
+ int triggerLatencyTime = 0; // ns
+ int eventNumber = 0;
+
boolean debug = false;
- boolean timingIn = false;
boolean pedestalRun = false;
- static private int nTriggers = 0;
+ // Collection Names
+ String apv25AnalogDataCollectioName = "APV25AnalogData";
+ /**
+ * Default Ctor
+ */
public SvtReadout(){
// Load the driver which transfers SimTrackerHits to their
// corresponding sensor readout
@@ -75,15 +83,15 @@
/**
*
*/
- public void setTimingIn(boolean timingIn){
- this.timingIn = timingIn;
+ public void setPedestalRun(boolean pedestalRun){
+ this.pedestalRun = pedestalRun;
}
/**
*
*/
- public void setPedestalRun(boolean pedestalRun){
- this.pedestalRun = pedestalRun;
+ public void setTriggerLatencyTime(int triggerLatencyTime /* ns */){
+ this.triggerLatencyTime = triggerLatencyTime;
}
/**
@@ -96,6 +104,13 @@
/**
*
*/
+ public void setReadoutDeadTime(int readoutDeadTimePerSample){
+ this.readoutDeadTimePerSample = readoutDeadTimePerSample;
+ }
+
+ /**
+ *
+ */
@Override
public void detectorChanged(Detector detector){
super.detectorChanged(detector);
@@ -103,7 +118,14 @@
// Instantiate all SVT Half modules
for(SiSensor sensor : SvtUtils.getInstance().getSensors()){
halfModules.add(new SvtHalfModule(sensor));
- }
+ }
+
+ // Set the trigger latency
+ for(SvtHalfModule halfModule : halfModules){
+ for(Apv25Full apv : halfModule.getAllApv25s()){
+ apv.setLatency(triggerLatencyTime);
+ }
+ }
}
/**
@@ -112,16 +134,15 @@
@Override
public void process(EventHeader event){
super.process(event);
-
+
+ eventNumber++;
+
// Increment all trigger pointer and writer positions when necessary
if((ClockSingleton.getTime() + ClockSingleton.getDt()) % SAMPLING_INTERVAL == 0){
- if(debug){
- System.out.println(this.getClass().getSimpleName() + ": Time: " + (ClockSingleton.getTime() + ClockSingleton.getDt()));
- System.out.println(this.getClass().getSimpleName() + ": Incrementing trigger positions");
- }
-
for(SvtHalfModule halfModule : halfModules){
- halfModule.incrementPointerPositions();
+ for(Apv25Full apv : halfModule.getAllApv25s()){
+ apv.incrementPointerPositions();
+ }
}
}
@@ -133,42 +154,41 @@
this.readoutSensor(halfModule);
}
- // If an Ecal trigger is received, generate six local triggers in order to read out six
- // samples
+ // If an Ecal trigger is received, readout six samples from each APV25
if(Apv25Full.readoutBit){
nTriggers++;
Apv25Full.readoutBit = false;
- if(debug) System.out.println(this.getClass().getSimpleName() + ": APVs have been triggered!");
-
// An APV25 cannot receive a trigger while it's still reading out samples;
// drop the trigger
- // TODO: Verify that the APV25 readout time is approx. 24 ns
- if(ClockSingleton.getTime() >= (lastTriggerTime + readoutDeadTime)){
+ if(ClockSingleton.getTime() >= (lastTriggerTime + readoutDeadTimePerSample*TOTAL_NUMBER_OF_SAMPLES)){
+ if(debug) System.out.println(this.getClass().getSimpleName() + ": APVs have been triggered on event " + eventNumber);
+
lastTriggerTime = ClockSingleton.getTime();
for(int sample = 0; sample < TOTAL_NUMBER_OF_SAMPLES; sample++){
// Add the time at which each of the six samples should be collected
// the trigger queue
- triggerQueue.offer(ClockSingleton.getTime() + sample*ClockSingleton.getDt()*2);
+ fifo.offer(ClockSingleton.getTime() + sample*24);
}
- } else if(debug) System.out.println(this.getClass().getSimpleName() + ": Trigger has been dropped!");
+ } else {
+ if(debug) System.out.println(this.getClass().getSimpleName() + ": Trigger has been dropped!");
+ nTriggersDropped++;
+ nTriggers--;
+ }
}
// Process any triggers in the queue
- if(triggerQueue.peek() != null){
+ if(fifo.peek() != null){
- if(triggerQueue.peek() == ClockSingleton.getTime()){
- if(debug){
- System.out.println(this.getClass().getSimpleName() + ": Reading out sample " + (TOTAL_NUMBER_OF_SAMPLES - triggerQueue.size()));
- System.out.println(this.getClass().getSimpleName() + ": " + triggerQueue.toString());
- }
+ if(fifo.peek() == ClockSingleton.getTime()){
+
// Clear the analog data and readout all APV25's
analogData.addAll(this.readoutAPV25s());
- triggerQueue.remove();
+ fifo.remove();
}
}
@@ -220,25 +240,15 @@
double charge = pedestalRun ? 0 : electrodeData.getCharge();
if(debug){
- if(charge > 0) System.out.println(this.getClass().getSimpleName() + ": Injecting charge " + charge + " into channel " + physicalChannel);
- }
-
- if(timingIn){
- if(charge > 0){
- if(!sensorToChannel.containsKey(halfModule.getSensor())){
- sensorToChannel.put(halfModule.getSensor(), new ArrayList<Integer>());
- }
- sensorToChannel.get(halfModule.getSensor()).add(physicalChannel);
+ if(charge > 0){
+ System.out.println(this.getClass().getSimpleName()
+ + ": Sensor: " + SvtUtils.getInstance().getDescription(halfModule.getSensor())
+ + ": Injecting charge " + charge + " into channel " + physicalChannel);
}
}
// Inject the charge into the APV25 amplifier chain
halfModule.getAPV25(physicalChannel).injectCharge(channel, charge);
-
- if(debug){
- System.out.println(this.getClass().getSimpleName() + ": Writer pointer value: " + halfModule.getAPV25(physicalChannel).getChannel(channel).getPipeline().getWriterPointerValue());
- System.out.println(this.getClass().getSimpleName() + ": Channel " + physicalChannel + " pipeline: " + halfModule.getAPV25(physicalChannel).getChannel(channel).getPipeline().toString() );
- }
}
}
}
@@ -260,17 +270,6 @@
// Get the sensor associated with this half-module
SiSensor sensor = halfModule.getSensor();
- if(timingIn && sensorToChannel.containsKey(sensor)){
- for(Integer physicalChannel = 0; physicalChannel < 640; physicalChannel++){
- if(sensorToChannel.get(sensor).contains(physicalChannel)){
- // find the APV channel number from the physical channel
- int channel = physicalChannel - TOTAL_STRIPS_PER_SENSOR
- + halfModule.getAPV25Number(physicalChannel)*TOTAL_APV25_CHANNELS + (TOTAL_APV25_CHANNELS - 1);
- System.out.println(this.getClass().getSimpleName() + ": Channel " + physicalChannel + " pipeline: " + halfModule.getAPV25(physicalChannel).getChannel(channel).getPipeline().toString() );
- }
- }
- }
-
// Get all of the APVs associated with the sensor
Apv25Full[] apv25 = halfModule.getAllApv25s();
@@ -281,8 +280,6 @@
analogDatum.setApv(apvN);
analogData.add(analogDatum);
}
- // Increment the pointer positions
- halfModule.incrementPointerPositions();
}
return analogData;