Commit in hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25 on MAIN | |||
APV25Constants.java | +25 | added 1.1 | |
APV25Full.java | +231 | added 1.1 | |
+256 |
Initial commit of APV25 simulation rewrite; work in progress ...
diff -N APV25Constants.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ APV25Constants.java 3 Jul 2012 00:34:12 -0000 1.1 @@ -0,0 +1,25 @@
+package org.lcsim.hps.recon.tracking.apv25; + +/** + * + * @author Omar Moreno <[log in to unmask]> + * @version $Id: APV25Constants.java,v 1.1 2012/07/03 00:34:12 omoreno Exp $ + */ +public class APV25Constants { + + // 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 SAMPLING_TIME = 24; // [ns] + + // + public static final double FRONT_END_GAIN = 100.0; + public static final int ANALOG_PIPELINE_LENGTH = 192; + + +}
diff -N APV25Full.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ APV25Full.java 3 Jul 2012 00:34:12 -0000 1.1 @@ -0,0 +1,231 @@
+package org.lcsim.hps.recon.tracking.apv25; + +//--- Constants ---// +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; + +//--- hps-java ---// +import org.lcsim.hps.util.ClockSingleton; +import org.lcsim.hps.util.RingBuffer; + +/** + * + * @author Omar Moreno <[log in to unmask]> + * @version $Id: APV25Full.java,v 1.1 2012/07/03 00:34:12 omoreno Exp $ + */ +public class APV25Full { + + // 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(); + } + + /** + * Set the operating mode of the APV25 to either "peak", + * "deconvolution", or "multi-peak". + * + * @param mode : APV25 operating mode + */ + public void setAPV25Mode(String mode) { + apv25Mode = mode; + } + + /** + * Return an instance of an APV25 channel + * + * @return an instance of APV25Channel + */ + public APV25Channel getChannel(int channel){ + return channels[channel]; + } + + /** + * Inject charge into a channel and shape the signal. The resulting + * shaper signal is then sampled into the analog pipeline + * + * @param charge : Total charge being injected + * @param pipeline : Analog pipeline associated with a channel + */ + public void injectCharge(int channel, double charge) { + + // Shape the injected charge + this.getChannel(channel).shapeSignal(charge); + + // Sample the resulting shaper signal + this.getChannel(channel).sampleShaperSignal(); + } + + /** + * + */ + public void loadChannelConstants(){ + } + + //------------------------------------------// + // APV25 Channel // + //------------------------------------------// + public class APV25Channel { + + private APV25ShaperSignal shaperSignal; + private APV25Pipeline pipeline; + + private double shapingTime = 50; // [ns] + + /** + * Default Constructor + */ + public APV25Channel(){ + } + + /** + * Set the shaping time + * + * @param shapingTime : APV25 shaping time. The default Tp is set to 50 ns. + */ + public void setShapingTime(int shapingTime) { + this.shapingTime = shapingTime; + } + + /** + * Shape the injected charge + * + * @param charge + */ + public void shapeSignal(double charge){ + shaperSignal = new APV25ShaperSignal(charge); + } + + public void sampleShaperSignal(){ + + // Obtain the beam time + double beamTime = ClockSingleton.getTime(); + + // Fill the analog pipeline starting with the cell to which the writer pointer is pointing + // to. Signals arriving within the same bucket of length <samplingTime> will be shifted in + // time depending on when they arrive. + 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; + + // Sample the shaper signal + double sample = shaperSignal.getAmplitudeAtTime(sampleTime, shapingTime); + + // Add the value to the pipeline + pipeline.addToCell(cell, sample); + } + } + } + + //-------------------------------------// + // APV25 Analog Pipeline // + //-------------------------------------// + public class APV25Pipeline extends RingBuffer { + + // TODO: Possibly store the pipeline in the event + + // Note: ptr gives the position of the trigger pointer + + private int triggerLatency = (int) Math.floor(200 /* ns */ / SAMPLING_TIME); + private int writerPointer = 0; + + /** + * Constructor + */ + public APV25Pipeline(){ + + // Initialize the pipeline to the APV25 pipeline length + super(ANALOG_PIPELINE_LENGTH); + + // Initialize the position of the trigger pointer to a random position + this.ptr = (int) (Math.random()*(ANALOG_PIPELINE_LENGTH + 1)); + + // 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_TIME); + } + + /** + * + */ + @Override + public void addToCell(int position, double element){ + if((writerPointer + position)%ANALOG_PIPELINE_LENGTH == this.ptr) return; + super.addToCell(position, element); + } + + /** + * + */ + public double readout(){ + double triggerPointerValue = this.currentValue(); + array[ptr] = 0; + return triggerPointerValue; + } + + /** + * + */ + @Override + public String toString(){ + String analogPipeline = "[ "; + for(int element = 0; element < ANALOG_PIPELINE_LENGTH; element++){ + if(element == ptr) analogPipeline += " TP ===>"; + else if(element == writerPointer) analogPipeline += " WP ===>"; + analogPipeline += (array[element] + ", "); + } + analogPipeline += "] "; + return analogPipeline; + } + } + + //-----------------------------------// + // APV25 Shaper Signal // + //-----------------------------------// + public class APV25ShaperSignal { + + // Shaper signal maximum amplitude + private double maxAmp = 0; + + /** + * Constructor + * + * @param charge: Charge injected into a channel + */ + APV25ShaperSignal(double charge) { + // Find the maximum amplitude of the shaper signal + maxAmp = (charge/MIP)*FRONT_END_GAIN; // mV + } + + /** + * Get the amplitude at a time t + * + * @param time: time at which the shaper signal is to be sampled + */ + public double getAmplitudeAtTime(double time, double shapingTime) { + return maxAmp * (Math.max(0, time) / shapingTime) * Math.exp(1 - (time / shapingTime)); + } + + } + + +}
\ No newline at end of file
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