Commit in hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25 on MAIN | |||
Apv25Full.java | +67 | -18 | 1.1 -> 1.2 |
Apv25AnalogData.java | +50 | -8 | 1.1 -> 1.2 |
Apv25Constants.java | +9 | -10 | 1.1 -> 1.2 |
Apv25DigitalData.java | +24 | -3 | 1.1 -> 1.2 |
SvtHalfModule.java | +27 | -4 | 1.1 -> 1.2 |
SvtReadout.java | +65 | -23 | 1.1 -> 1.2 |
+242 | -66 |
APV25 Sim now uses calibration constants; Updated readout; Other changes ...
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++){
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;
} }
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; -
}
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; + }
}
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(); + } + }
}
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;
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