Print

Print


Commit in java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal on MAIN
FADCEcalReadoutDriver.java+34-41218 -> 219
clean up test run code for consistency with new stuff

java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal
FADCEcalReadoutDriver.java 218 -> 219
--- java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal/FADCEcalReadoutDriver.java	2014-02-13 00:42:57 UTC (rev 218)
+++ java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal/FADCEcalReadoutDriver.java	2014-02-13 01:23:37 UTC (rev 219)
@@ -35,9 +35,9 @@
 
     String ecalName = "Ecal";
     Subdetector ecal;
-    //buffer for deposited energy
-    private Map<Long, RingBuffer> eDepMap = null;
-    //ADC pipeline for readout
+    //buffer for preamp signals (units of volts, no pedestal)
+    private Map<Long, RingBuffer> signalMap = null;
+    //ADC pipeline for readout (units of ADC counts)
     private Map<Long, FADCPipeline> pipelineMap = null;
     //buffer for window sums
     private Map<Long, Double> sumMap = null;
@@ -53,13 +53,10 @@
     private boolean useCRRCShape = false;
     //shaper time constant in ns; negative values generate square pulses of the given width (for test run sim)
     private double tp = 14.0;
-    //TODO: set riseTime, fallTime, pulseDelay
     //pulse rise time in ns
     private double riseTime = 10.0;
     //pulse fall time in ns
     private double fallTime = 17.0;
-    //pulse delay time in ns
-    private double pulseDelay = 3 * riseTime;
     //delay (number of readout periods) between start of summing window and output of hit to clusterer
     private int delay0 = 32;
     //start of readout window relative to trigger time (in readout cycles)
@@ -90,14 +87,14 @@
     private double fixedGain = -1;
     private boolean constantTriggerWindow = false;
     private boolean addNoise = false;
-    //TODO: change to 2014 value
+    private double pePerMeV = 2.0; //photoelectrons per MeV, used to calculate noise
+    //parameters for 2014 APDs and preamp
     private double lightYield = 120. / ECalUtils.MeV; // number of photons per MeV
     private double quantumEff = 0.7;  // quantum efficiency of the APD
     private double surfRatio = (10. * 10.) / (16 * 16); // surface ratio between APD and crystals
     private double gainAPD = 150.; // Gain of the APD
     private double elemCharge = 1.60217657e-19;
     private double gainPreAmpl = 0.550e12; // Gain of the preamplifier in V/C, true value is higher but does not take into account losses
-    private double pePerMeV = 2.0; //photoelectrons per MeV, used to calculate noise
 
     public FADCEcalReadoutDriver() {
         flags = 0;
@@ -175,10 +172,6 @@
         this.pePerMeV = pePerMeV;
     }
 
-    public void setPulseDelay(double pulseDelay) {
-        this.pulseDelay = pulseDelay;
-    }
-
     public void setRiseTime(double riseTime) {
         this.riseTime = riseTime;
     }
@@ -207,32 +200,16 @@
     @Override
     protected void readHits(List<RawCalorimeterHit> hits) {
 
-        for (Long cellID : eDepMap.keySet()) {
-            RingBuffer eDepBuffer = eDepMap.get(cellID);
-// TODO : gain is not necessary anymore for 2014 run, as I have introduced all the variables in the same function
-// If a variable gain should be introduced from a database, it should be done in pulseAmplitude in order to have all the information at the same place
-// Pedestal should stay here
+        for (Long cellID : signalMap.keySet()) {
+            RingBuffer signalBuffer = signalMap.get(cellID);
 
             FADCPipeline pipeline = pipelineMap.get(cellID);
             pipeline.step();
+
+            double currentValue = signalBuffer.currentValue() * 4095.0 / 2.0; //12-bit ADC with 2 V range
             double pedestal = EcalConditions.physicalToPedestal(cellID);
+            pipeline.writeValue(Math.min((int) Math.round(pedestal + currentValue), 4096)); //ADC can't return a value larger than 4095; 4096 (overflow) is returned for any input >2V
 
-            double currentValue;
-            if (useCRRCShape) {
-                //normalization constant from cal gain (MeV/integral bit) to amplitude gain (amplitude bit/GeV)
-                double gain;
-                if (fixedGain > 0) {
-                    gain = readoutPeriod / (fixedGain * ECalUtils.MeV);
-                } else {
-                    gain = readoutPeriod / (EcalConditions.physicalToGain(cellID) * ECalUtils.MeV);
-                }
-                currentValue = gain * eDepBuffer.currentValue();
-            } else {
-                currentValue = eDepBuffer.currentValue() * 4095.0 / 2.0; //12-bit ADC with 2 V range
-            }
-
-            pipeline.writeValue(Math.min((int) Math.round(pedestal + currentValue), 4095)); //ADC can't return a value larger than 4095
-
             Double sum = sumMap.get(cellID);
             if (sum == null && currentValue > triggerThreshold) {
                 timeMap.put(cellID, readoutCounter);
@@ -277,7 +254,7 @@
                     }
                 }
             }
-            eDepBuffer.step();
+            signalBuffer.step();
         }
         while (outputQueue.peek() != null && outputQueue.peek().getTimeStamp() / 64 <= readoutCounter - delay0) {
             if (outputQueue.peek().getTimeStamp() / 64 < readoutCounter - delay0) {
@@ -424,7 +401,7 @@
     protected void putHits(List<CalorimeterHit> hits) {
         //fill the readout buffers
         for (CalorimeterHit hit : hits) {
-            RingBuffer eDepBuffer = eDepMap.get(hit.getCellID());
+            RingBuffer eDepBuffer = signalMap.get(hit.getCellID());
             double energyAmplitude = hit.getRawEnergy();
             if (addNoise) {
                 //add preamp noise and photoelectron Poisson noise in quadrature
@@ -457,11 +434,11 @@
         if (ecal == null) {
             return false;
         }
-        eDepMap = new HashMap<Long, RingBuffer>();
+        signalMap = new HashMap<Long, RingBuffer>();
         pipelineMap = new HashMap<Long, FADCPipeline>();
         Set<Long> cells = ((HPSEcal3) ecal).getNeighborMap().keySet();
         for (Long cellID : cells) {
-            eDepMap.put(cellID, new RingBuffer(bufferLength));
+            signalMap.put(cellID, new RingBuffer(bufferLength));
             pipelineMap.put(cellID, new FADCPipeline(pipelineLength, (int) Math.round(EcalConditions.physicalToPedestal(cellID))));
         }
         return true;
@@ -472,8 +449,17 @@
             if (time <= 0.0) {
                 return 0.0;
             }
+
+            //normalization constant from cal gain (MeV/integral bit) to amplitude gain (amplitude bit/GeV)
+            double gain;
+            if (fixedGain > 0) {
+                gain = readoutPeriod / (fixedGain * ECalUtils.MeV * (4095.0 / 2.0));
+            } else {
+                gain = readoutPeriod / (EcalConditions.physicalToGain(cellID) * ECalUtils.MeV * (4095.0 / 2.0));
+            }
+
             if (tp > 0.0) {
-                return ((time / tp) * Math.exp(1.0 - time / tp)) / (tp * Math.E);
+                return gain * ((time / tp) * Math.exp(1.0 - time / tp)) / (tp * Math.E);
             } else {
                 if (time < -tp) {
                     return 1.0;
@@ -487,12 +473,19 @@
             if (time <= 0.0) {
                 return 0.0;
             }
+
+            //if fixedGain is set, multiply the default gain by this factor
+            double gain = 1.0;
+            if (fixedGain > 0) {
+                gain = fixedGain;
+            }
+
             double norm = ((riseTime + fallTime) / 2) * 1e-9 * Math.sqrt(2 * Math.PI); //to ensure the total integral is equal to 1; gives 3.3839e-8 for default rise and fall times
 
-            if (time < pulseDelay) {
-                return lightYield * quantumEff * surfRatio * gainAPD * gainPreAmpl * elemCharge * funcGaus(time - pulseDelay, riseTime) / norm;
+            if (time < 3 * riseTime) {
+                return gain * lightYield * quantumEff * surfRatio * gainAPD * gainPreAmpl * elemCharge * funcGaus(time - 3 * riseTime, riseTime) / norm;
             } else {
-                return lightYield * quantumEff * surfRatio * gainAPD * gainPreAmpl * elemCharge * funcGaus(time - pulseDelay, fallTime) / norm;
+                return gain * lightYield * quantumEff * surfRatio * gainAPD * gainPreAmpl * elemCharge * funcGaus(time - 3 * riseTime, fallTime) / norm;
             }
         }
     }
SVNspam 0.1