6 modified files
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.1 -r1.2
--- Apv25Full.java 7 Jul 2012 00:32:05 -0000 1.1
+++ Apv25Full.java 13 Aug 2012 23:09:42 -0000 1.2
@@ -4,7 +4,7 @@
import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.ANALOG_PIPELINE_LENGTH;
import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.FRONT_END_GAIN;
import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.MIP;
-import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.SAMPLING_TIME;
+import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.SAMPLING_INTERVAL;
//--- hps-java ---//
import org.lcsim.hps.util.ClockSingleton;
@@ -13,27 +13,24 @@
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: Apv25Full.java,v 1.1 2012/07/07 00:32:05 omoreno Exp $
+ * @version $Id: Apv25Full.java,v 1.2 2012/08/13 23:09:42 omoreno Exp $
*/
public class Apv25Full {
// APV25 trigger bit
public static boolean triggerBit = false;
+ // APV25 clock cycle
+ public static int apv25ClockCycle = 0;
// APV25 Channels; An APV25 Readout Chip contains a total of 128 channels
private APV25Channel[] channels = new APV25Channel[128];
- private String apv25Mode = "multi-peak";
-
+
public Apv25Full(){
// Instantiate all APV25 channels
for(int channel = 0; channel < channels.length; channel++){
channels[channel] = new APV25Channel();
}
-
- // TODO: Load channel constants from the conditions database. Channel
- // constants need to be loaded on a run by run basis
- this.loadChannelConstants();
}
/**
@@ -54,17 +51,24 @@
*/
public void injectCharge(int channel, double charge) {
- // Shape the injected charge
- this.getChannel(channel).shapeSignal(charge);
+ // Only inject charge if the channel isn't bad
+ if(!this.getChannel(channel).isBadChannel()){
+
+ // Shape the injected charge
+ this.getChannel(channel).shapeSignal(charge);
- // Sample the resulting shaper signal
- this.getChannel(channel).sampleShaperSignal();
+ // Sample the resulting shaper signal
+ this.getChannel(channel).sampleShaperSignal();
+ }
}
/**
*
*/
- public void loadChannelConstants(){
+ public void incrementPointerPositions(){
+ for(int channel = 0; channel < channels.length; channel++){
+ channels[channel].pipeline.step();
+ }
}
/**
@@ -72,11 +76,16 @@
*/
public Apv25AnalogData readOut(){
+ // TODO: Add pedestal and noise to the samples when read out
+
Apv25AnalogData data = new Apv25AnalogData();
for(int channel = 0; channel < channels.length; channel++){
- data.setChannelData(channel, channels[channel].pipeline.readout());
+
+ // Only readout the channel if the channel isn't bad
+ if(!this.getChannel(channel).isBadChannel()){
+ data.setChannelData(channel, channels[channel].pipeline.readout());
+ }
}
-
return data;
}
@@ -89,6 +98,9 @@
private APV25Pipeline pipeline;
private double shapingTime = 50; // [ns]
+ private double baseline = 0;
+ private double noise = 0;
+ boolean badChannel = false;
/**
* Default Constructor
@@ -104,6 +116,34 @@
public void setShapingTime(int shapingTime) {
this.shapingTime = shapingTime;
}
+
+ /**
+ *
+ */
+ public void setBaseline(double baseline){
+ this.baseline = baseline;
+ }
+
+ /**
+ *
+ */
+ public void setNoise(double noise){
+ this.noise = noise;
+ }
+
+ /**
+ *
+ */
+ public void markAsBadChannel(){
+ badChannel = true;
+ }
+
+ /**
+ *
+ */
+ public boolean isBadChannel(){
+ return badChannel;
+ }
/**
* Shape the injected charge
@@ -125,7 +165,7 @@
for(int cell = 0; cell < ANALOG_PIPELINE_LENGTH; cell++){
// Time at which the shaper signal will be sampled
- int sampleTime = cell*SAMPLING_TIME - ((int) beamTime)%SAMPLING_TIME;
+ int sampleTime = cell*((int) SAMPLING_INTERVAL) - (int) (beamTime%SAMPLING_INTERVAL);
// Sample the shaper signal
double sample = shaperSignal.getAmplitudeAtTime(sampleTime, shapingTime);
@@ -145,7 +185,7 @@
// Note: ptr gives the position of the trigger pointer
- private int triggerLatency = (int) Math.floor(200 /* ns */ / SAMPLING_TIME);
+ private int triggerLatency = (int) Math.floor(200 /* ns */ / SAMPLING_INTERVAL);
private int writerPointer = 0;
/**
@@ -167,7 +207,7 @@
*
*/
public void setLatency(int triggerLatency /*ns*/){
- triggerLatency = (int) Math.floor(triggerLatency/SAMPLING_TIME);
+ triggerLatency = (int) Math.floor(triggerLatency/SAMPLING_INTERVAL);
}
/**
@@ -192,6 +232,15 @@
*
*/
@Override
+ public void step(){
+ super.step();
+ writerPointer = (ptr + triggerLatency)%ANALOG_PIPELINE_LENGTH;
+ }
+
+ /**
+ *
+ */
+ @Override
public String toString(){
String analogPipeline = "[ ";
for(int element = 0; element < ANALOG_PIPELINE_LENGTH; element++){
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.1 -r1.2
--- Apv25AnalogData.java 7 Jul 2012 00:32:05 -0000 1.1
+++ Apv25AnalogData.java 13 Aug 2012 23:09:42 -0000 1.2
@@ -1,14 +1,17 @@
package org.lcsim.hps.recon.tracking.apv25;
+//--- org.lcsim ---//
+import org.lcsim.detector.tracker.silicon.SiSensor;
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: Apv25AnalogData.java,v 1.1 2012/07/07 00:32:05 omoreno Exp $
+ * @version $Id: Apv25AnalogData.java,v 1.2 2012/08/13 23:09:42 omoreno Exp $
*/
public class Apv25AnalogData {
- // TODO: Add ability to associate the analog data to a SiSensor and APV25
+ private SiSensor sensor = null;
+ private int apv25;
// APV25 output stream
private double[] apv25AnalogOutput = new double[140];
@@ -17,7 +20,7 @@
private double error = 4.0;
private double[] samples = new double[128];
-
+
/**
* Default Ctor
*/
@@ -39,6 +42,39 @@
/**
*
*/
+ public Apv25AnalogData(SiSensor sensor, int apv25){
+ this();
+
+ // Set the sensor and APV number associated with this data
+ this.sensor = sensor;
+ this.apv25 = apv25;
+ }
+
+ /**
+ *
+ */
+ public void setChannelData(int channel, double data){
+ samples[channel] = data;
+ apv25AnalogOutput[12 + channel] = data;
+ }
+
+ /**
+ *
+ */
+ public void setSensor(SiSensor sensor){
+ this.sensor = sensor;
+ }
+
+ /**
+ *
+ */
+ public void setApv(int apv25){
+ this.apv25 = apv25;
+ }
+
+ /**
+ *
+ */
public double[] getHeader(){
return header;
}
@@ -68,14 +104,20 @@
*
*/
public double[] getApv25AnalogOutput(){
- return apv25AnalogOutput;
+ return this.apv25AnalogOutput;
}
-
+
/**
*
*/
- public void setChannelData(int channel, double data){
- samples[channel] = data;
- apv25AnalogOutput[12 + channel] = data;
+ public SiSensor getSensor(){
+ return this.sensor;
+ }
+
+ /**
+ *
+ */
+ public int getApv(){
+ return this.apv25;
}
}
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.1 -r1.2
--- Apv25Constants.java 7 Jul 2012 00:32:05 -0000 1.1
+++ Apv25Constants.java 13 Aug 2012 23:09:42 -0000 1.2
@@ -3,25 +3,24 @@
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: Apv25Constants.java,v 1.1 2012/07/07 00:32:05 omoreno Exp $
+ * @version $Id: Apv25Constants.java,v 1.2 2012/08/13 23:09:42 omoreno Exp $
*/
public class Apv25Constants {
- // Total number of channels an APV25 asic contains
+ // Total number of channels an APV25 ASIC contains
public static final int CHANNELS = 128;
// Number of electron-hole pairs created by a min. ionizing particle
// in 300 micrometers of Si
- public static final int MIP = 25000;
+ public static final int MIP = 25000; // electrons
- //
- public static final int SAMPLING_TIME = 24; // [ns]
+ // Time intervals at which an APV25 shaper signal is sampled at
+ public static final double SAMPLING_INTERVAL = 25.0; // [ns]
- //
- public static final double FRONT_END_GAIN = 100.0;
+ // The APV25 front end gain
+ public static final double FRONT_END_GAIN = 100.0; //
+
+ // Length of the APV25 analog pipeline
public static final int ANALOG_PIPELINE_LENGTH = 192;
- //
- public static final int APV25S_PER_HALF_MODULE = 5;
-
}
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.1 -r1.2
--- Apv25DigitalData.java 7 Jul 2012 00:32:05 -0000 1.1
+++ Apv25DigitalData.java 13 Aug 2012 23:09:42 -0000 1.2
@@ -1,15 +1,18 @@
package org.lcsim.hps.recon.tracking.apv25;
-import java.util.Arrays;
+//--- org.lcsim ---//
+import org.lcsim.detector.tracker.silicon.SiSensor;
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: Apv25DigitalData.java,v 1.1 2012/07/07 00:32:05 omoreno Exp $
+ * @version $Id: Apv25DigitalData.java,v 1.2 2012/08/13 23:09:42 omoreno Exp $
*/
public class Apv25DigitalData {
// TODO: Add ability to associate the analog data to a SiSensor and APV25
+ private SiSensor sensor = null;
+ private int apv25;
// APV25 output stream
private double[] apv25DigitalOutput = new double[140];
@@ -21,7 +24,7 @@
/**
* Default Ctor
*/
- public Apv25DigitalData(double[] apv25DigitalOutput){
+ public Apv25DigitalData(SiSensor sensor, int apv25, double[] apv25DigitalOutput){
// Check if the output format is valid
if(apv25DigitalOutput.length != this.apv25DigitalOutput.length)
@@ -31,6 +34,10 @@
System.arraycopy(apv25DigitalOutput, 3, address, 0, address.length);
error = apv25DigitalOutput[11];
System.arraycopy(apv25DigitalOutput, 12, samples, 0, samples.length);
+
+ // Set the sensor and APV number associated with this data
+ this.sensor = sensor;
+ this.apv25 = apv25;
}
/**
@@ -67,4 +74,18 @@
public double[] getApv25DigitalOutput(){
return apv25DigitalOutput;
}
+
+ /**
+ *
+ */
+ public SiSensor getSensor(){
+ return this.sensor;
+ }
+
+ /**
+ *
+ */
+ public int getApv(){
+ return this.apv25;
+ }
}
hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
diff -u -r1.1 -r1.2
--- SvtHalfModule.java 7 Jul 2012 00:32:05 -0000 1.1
+++ SvtHalfModule.java 13 Aug 2012 23:09:42 -0000 1.2
@@ -1,16 +1,18 @@
package org.lcsim.hps.recon.tracking.apv25;
//--- constants ---//
-import static org.lcsim.hps.recon.tracking.apv25.Apv25Constants.APV25S_PER_HALF_MODULE;
+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;
+import org.lcsim.hps.recon.tracking.HPSSVTCalibrationConstants;
/**
*
* @author Omar Moreno
- * @version $Id: SvtHalfModule.java,v 1.1 2012/07/07 00:32:05 omoreno Exp $
+ * @version $Id: SvtHalfModule.java,v 1.2 2012/08/13 23:09:42 omoreno Exp $
*/
public class SvtHalfModule {
@@ -23,8 +25,23 @@
this.sensor = sensor;
// Instantiate the APV25's
- for(int chip = 0; chip < APV25S_PER_HALF_MODULE; chip++){
+ for(int chip = 0; chip < TOTAL_APV25_PER_HYBRID; chip++){
apv25[chip] = new Apv25Full();
+ for(int channel = 0; channel < CHANNELS; channel++){
+ int physicalChannel = 639 - (chip*128 + 127 - channel);
+ // Set the pedestal and noise found for this channel during QA
+ // Note: The pedestals and noise as measured during QA include an RTM amplification of
+ // approximately 1.5 (Actual channel values will be extracted using gain measurements
+ // at a later time). The simulation amplifies the signal by the same amount so
+ // it is necessary to divide the pedestal and noise by the RTM gain in order to get
+ // accurate results.
+ apv25[chip].getChannel(channel).setBaseline(HPSSVTCalibrationConstants.getPedestal(sensor, physicalChannel)/RTM_GAIN);
+ apv25[chip].getChannel(channel).setNoise(HPSSVTCalibrationConstants.getNoise(sensor, physicalChannel)/RTM_GAIN);
+ // Mark all bad channels which were found during QA
+ if(HPSSVTCalibrationConstants.isBadChannel(sensor, physicalChannel)){
+ apv25[chip].getChannel(channel).markAsBadChannel();
+ }
+ }
}
}
@@ -33,11 +50,17 @@
}
public Apv25Full getAPV25(int physicalChannel){
- int apv = (int) ((APV25S_PER_HALF_MODULE - 1) - Math.floor(physicalChannel/CHANNELS));
+ int apv = (int) ((TOTAL_APV25_PER_HYBRID - 1) - Math.floor(physicalChannel/CHANNELS));
return apv25[apv];
}
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.1 -r1.2
--- SvtReadout.java 7 Jul 2012 00:32:05 -0000 1.1
+++ SvtReadout.java 13 Aug 2012 23:09:42 -0000 1.2
@@ -16,6 +16,7 @@
import org.lcsim.event.EventHeader;
import org.lcsim.geometry.Detector;
import org.lcsim.hps.recon.tracking.SvtUtils;
+import org.lcsim.hps.util.ClockSingleton;
import org.lcsim.recon.tracking.digitization.sisim.CDFSiSensorSim;
import org.lcsim.recon.tracking.digitization.sisim.SiElectrodeData;
import org.lcsim.recon.tracking.digitization.sisim.SiElectrodeDataCollection;
@@ -26,16 +27,21 @@
/**
*
* @author Omar Moreno <[log in to unmask]>
- * @version $Id: SvtReadout.java,v 1.1 2012/07/07 00:32:05 omoreno Exp $
+ * @version $Id: SvtReadout.java,v 1.2 2012/08/13 23:09:42 omoreno Exp $
*/
public class SvtReadout extends Driver {
Set<SvtHalfModule> halfModules = new HashSet<SvtHalfModule>();
private SiSensorSim siSimulation = new CDFSiSensorSim();
String apv25AnalogDataCollectioName = "APV25AnalogData";
-
// FIFO queue to store "local" triggers by time
- private Queue<Integer> triggerQueue = new LinkedList<Integer>();
+ private Queue<Double> triggerQueue = new LinkedList<Double>();
+
+
+ double readoutDeadTime = 24; // ns
+ double lastTriggerTime = 0;
+
+ boolean readingOut = false;
public SvtReadout(){
}
@@ -60,28 +66,57 @@
public void process(EventHeader event){
super.process(event);
+ // Increment all trigger pointer and writer positions when necessary
+ if((ClockSingleton.getTime() + ClockSingleton.getDt()) % 25 == 0){
+ for(SvtHalfModule halfModule : halfModules){
+ halfModule.incrementPointerPositions();
+ }
+ Apv25Full.apv25ClockCycle++;
+ }
+
// Create a list to hold the analog data
List<Apv25AnalogData> analogData = new ArrayList<Apv25AnalogData>();
// Loop over all half-modules, perform charge deposition simulation and read them out
for(SvtHalfModule halfModule : halfModules){
this.readoutSensor(halfModule);
+ }
+
+ // If an Ecal trigger is received, generate six local triggers in order to read out six
+ // samples
+ if(Apv25Full.triggerBit){
+
+ Apv25Full.triggerBit = false;
+
+ // 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 an Ecal trigger is received, generate six local triggers in order to read out six
- // samples
- if(Apv25Full.triggerBit){
+ lastTriggerTime = ClockSingleton.getTime();
+
+ for(int sample = 0; sample < 6; sample++){
- // Only generate a set of triggers if there isn't another trigger being processed
- // TODO: Verify that this is how the APV25 is actually read out
- // TODO: Where should pending triggers be stored?
+ // Add the time at which each of the six samples should be collected
+ // the trigger queue
+ triggerQueue.offer(ClockSingleton.getTime() + sample*ClockSingleton.getDt()*2);
+ }
+
+ readingOut = true;
}
+ }
+
+ // Process any triggers in the queue
+ if(triggerQueue.peek() != null){
- // Clear the analog data and readout all APV25's
- analogData.addAll(this.readoutAPV25s(halfModule));
+ if(triggerQueue.peek() == ClockSingleton.getTime()){
+ // Clear the analog data and readout all APV25's
+ analogData.addAll(this.readoutAPV25s());
+ triggerQueue.remove();
+ }
}
-
- event.put(apv25AnalogDataCollectioName, analogData, Apv25AnalogData.class, 0);
+ event.put(apv25AnalogDataCollectioName, analogData, Apv25AnalogData.class, 0);
}
/**
@@ -111,12 +146,6 @@
electrodeDataCol = new SiElectrodeDataCollection();
}
- // Get the readout electrodes
-// SiSensorElectrodes readoutElectrodes = halfModule.getSensor().getReadoutElectrodes(carrier);
-
- // Add noise to the electodes
- // TODO: Noise simulation needs to be improved to be more realistic
-
// Loop over all sensor channels
for(Integer channel : electrodeDataCol.keySet()){
@@ -139,14 +168,27 @@
/**
*
*/
- public List<Apv25AnalogData> readoutAPV25s(SvtHalfModule halfModule){
+ public List<Apv25AnalogData> readoutAPV25s(){
// Create a list to hold the analog data
List<Apv25AnalogData> analogData = new ArrayList<Apv25AnalogData>();
+
+ for(SvtHalfModule halfModule : halfModules){
+
+ // Get the sensor associated with this half-module
+ SiSensor sensor = halfModule.getSensor();
+
+ // Get all of the APVs associated with the sensor
+ Apv25Full[] apv25 = halfModule.getAllApv25s();
- // Readout all APV25's
- for(Apv25Full apv25 : halfModule.getAllApv25s()){
- analogData.add(apv25.readOut());
+ // Readout all APV25's
+ for(int apvN = 0; apvN < apv25.length; apvN++){
+
+ Apv25AnalogData analogDatum = apv25[apvN].readOut();
+ analogDatum.setSensor(sensor);
+ analogDatum.setApv(apvN);
+ analogData.add(analogDatum);
+ }
}
return analogData;
CVSspam 0.2.12