Print

Print


Commit in hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25 on MAIN
Apv25Full.java+67-181.1 -> 1.2
Apv25AnalogData.java+50-81.1 -> 1.2
Apv25Constants.java+9-101.1 -> 1.2
Apv25DigitalData.java+24-31.1 -> 1.2
SvtHalfModule.java+27-41.1 -> 1.2
SvtReadout.java+65-231.1 -> 1.2
+242-66
6 modified files
APV25 Sim now uses calibration constants; Updated readout; Other changes ...

hps-java/src/main/java/org/lcsim/hps/recon/tracking/apv25
Apv25Full.java 1.1 -> 1.2
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
Apv25AnalogData.java 1.1 -> 1.2
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
Apv25Constants.java 1.1 -> 1.2
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
Apv25DigitalData.java 1.1 -> 1.2
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
SvtHalfModule.java 1.1 -> 1.2
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
SvtReadout.java 1.1 -> 1.2
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


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