Print

Print


Commit in java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal on MAIN
FADCEcalReadoutDriver.java+46-15215 -> 216
new pulse shape function by Gabriel Charles

java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal
FADCEcalReadoutDriver.java 215 -> 216
--- java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal/FADCEcalReadoutDriver.java	2014-02-11 21:24:17 UTC (rev 215)
+++ java/trunk/hps-java/src/main/java/org/lcsim/hps/readout/ecal/FADCEcalReadoutDriver.java	2014-02-12 23:40:01 UTC (rev 216)
@@ -55,11 +55,11 @@
     private double tp = 14.0;
     //TODO: set riseTime, fallTime, pulseDelay
     //pulse rise time in ns
-    private double riseTime = 14.0;
+    private double riseTime = 10.0;
     //pulse fall time in ns
-    private double fallTime = 14.0;
+    private double fallTime = 17.0;
     //pulse delay time in ns
-    private double pulseDelay = 14.0;
+    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)
@@ -91,6 +91,12 @@
     private boolean constantTriggerWindow = false;
     private boolean addNoise = false;
     //TODO: change to 2014 value
+    private double lightYield = 120.; // 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() {
@@ -203,20 +209,29 @@
 
         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
 
             FADCPipeline pipeline = pipelineMap.get(cellID);
             pipeline.step();
             double pedestal = EcalConditions.physicalToPedestal(cellID);
-            //normalization constant from cal gain (MeV/integral bit) to amplitude gain (amplitude bit/GeV)
-            double gain;
-            if (fixedGain > 0) {
-                gain = readoutPeriod / (fixedGain * ECalUtils.MeV);
+
+            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 {
-                gain = readoutPeriod / (EcalConditions.physicalToGain(cellID) * ECalUtils.MeV);
+                currentValue = eDepBuffer.currentValue() * 4095.0 / 2.0; //12-bit ADC with 2 V range
             }
 
-            double currentValue = gain * eDepBuffer.currentValue();
-            pipeline.writeValue((int) Math.round(pedestal + currentValue));
+            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) {
@@ -417,7 +432,7 @@
                 energyAmplitude += RandomGaussian.getGaussian(0, noise);
             }
             for (int i = 0; i < bufferLength; i++) {
-                eDepBuffer.addToCell(i, energyAmplitude * pulseAmplitude((i + 1) * readoutPeriod + readoutTime() - (ClockSingleton.getTime() + hit.getTime())));
+                eDepBuffer.addToCell(i, energyAmplitude * pulseAmplitude((i + 1) * readoutPeriod + readoutTime() - (ClockSingleton.getTime() + hit.getTime()), hit.getCellID()));
             }
         }
     }
@@ -452,7 +467,7 @@
         return true;
     }
 
-    private double pulseAmplitude(double time) {
+    private double pulseAmplitude(double time, long cellID) {
         if (useCRRCShape) {
             if (time <= 0.0) {
                 return 0.0;
@@ -466,11 +481,27 @@
                     return 0.0;
                 }
             }
-        } else {
-            return 0.0; //TODO: new pulse shape definition for 2014
+        } else {   // According to measurements the output signal can be fitted by two gaussians, one for the rise of the signal, one for the fall
+            // Time corresponds to t-(t_eve+pulseDelay) such that the maximum of the amplitude is reached pulseDelay ns after the event t_eve
+            // Without the coefficient, the integral is equal to 1 - 1 per 1000
+            if (time <= 0.0) {
+                return 0.0;
+            }
+            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;
+            } else {
+                return lightYield * quantumEff * surfRatio * gainAPD * gainPreAmpl * elemCharge * funcGaus(time - pulseDelay, fallTime) / norm;
+            }
         }
     }
 
+    // Gaussian function needed for the calculation of the pulse shape amplitude  
+    public static double funcGaus(double t, double sig) {
+        return Math.exp(-t * t / (2 * sig * sig));
+    }
+
     private class FADCPipeline {
 
         private int[] array;
@@ -518,4 +549,4 @@
             return array[((ptr - pos) % size + size) % size];
         }
     }
-}
\ No newline at end of file
+}
SVNspam 0.1