Print

Print


Author: [log in to unmask]
Date: Thu Feb 26 17:59:21 2015
New Revision: 2216

Log:
Updating EcalRawConverter(Driver) to emulate FADC firmware in converting Mode-1 readout (ECalRawTrackerHit) into Mode-3 readout (CalorimeterHit) for use by clustering algorithms.  This new behavior is disabled by default; enabled with flag in steering file.

Added:
    java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EngineeringRun2014ECalRecon_Pass1_FirmwareEmulator.lcsim
Modified:
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java
    java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java	Thu Feb 26 17:59:21 2015
@@ -23,6 +23,7 @@
  * @author Sho Uemura <[log in to unmask]>
  * @author Jeremy McCormick <[log in to unmask]>
  * @author Andrea Celentano <[log in to unmask]>
+ * @author <[log in to unmask]>
  */
 public class EcalRawConverter {
 
@@ -32,11 +33,31 @@
     private double gain;
     private boolean use2014Gain = true;
 
+    
+    // Parameters for replicating the conversion of FADC Mode-1 readout into what
+    // the firmware would have reported for Mode-3 pulse.  Using the same conventions
+    // for these parameters used by the firmware configuration files.  This means
+    // NSA and NSB are in units nanoseconds and must be multiples of 4 ns.
+    private double leadingEdgeThreshold=-1; // above pedestal (units=ADC)
+    private int NSA=-1; // integration range after threshold crossing (units=ns)
+    private int NSB=-1; // integration range before threshold crossing (units=ns)
+    
+    
     private EcalConditions ecalConditions = null;
 
     public EcalRawConverter() {
     }
 
+    public void setLeadingEdgeThreshold(double thresh) {
+        leadingEdgeThreshold=thresh;
+    }
+    public void setNSA(int nsa) {
+        NSA=nsa;
+    }
+    public void setNSB(int nsb) {
+        NSB=nsb;
+    }
+    
     public void setGain(double gain) {
         constantGain = true;
         this.gain = gain;
@@ -103,6 +124,78 @@
     }
 
     /*
+     * NAB 2015/02/26
+     * 
+     * This HitDtoA is for emulating the conversion of Mode-1 readout (RawTrackerHit)
+     * into a Mode-3 readout.  This currently only supports finding 1 pulse in the window.
+     * (NOTE: Looks like ADCs have already been converted to doubles.)
+     * 
+     * TODO: Special case when NSA+NSB is greater than the window size is not dealt
+     * with properly, yet.
+     */
+    public CalorimeterHit firmwareHitDtoA(RawTrackerHit hit) {
+     
+        final int nsPerSample=4; // TODO: Get this from somewhere else.
+        
+        if (NSA<0 || NSB<0 || leadingEdgeThreshold<0.0) {
+            throw new RuntimeException("You have to set NSA, NSB, and leadingEdgeThreshold to positive values if you want to emulate firmware.");
+        }
+        
+        // using convention for NSA and NSB in the DAQ config file:
+        if (NSA%nsPerSample !=0 || NSB%nsPerSample !=0) {
+            throw new RuntimeException("NSA/NSB must be multiples of 4ns.");
+        }
+        
+        long id = hit.getCellID();
+        short samples[] = hit.getADCValues();
+        if (samples.length==0) return null;
+        EcalChannelConstants channelData = findChannel(hit.getCellID());
+        double pedestal = channelData.getCalibration().getPedestal();
+
+        // find threshold crossing:
+        int thresholdCrossing = -1;
+        if (samples[0] > pedestal+leadingEdgeThreshold) {
+            // special case, first sample above threshold:
+            thresholdCrossing=0;
+        } else {
+            for (int ii = 1; ii < samples.length; ++ii) {
+                if ( samples[ii]   >pedestal+leadingEdgeThreshold &&
+                     samples[ii-1]<=pedestal+leadingEdgeThreshold)
+                {
+                    // found threshold crossing:
+                    thresholdCrossing = ii;
+                    // one pulse only:
+                    break;
+                }
+            }
+        }
+        if (thresholdCrossing < 0) return null;
+
+        // pulse time:
+        double time = thresholdCrossing*nsPerSample;
+       
+        // pulse integral:
+        short sum = 0;
+        for (int jj=thresholdCrossing-NSB/nsPerSample; jj<thresholdCrossing+NSA/nsPerSample; jj++) {
+            if (jj<0) continue;
+            if (jj>=samples.length) break;
+            sum += samples[jj];
+        }
+
+        //System.err.println("000000000000000000000000      "+thresholdCrossing+"   "+sum+"  "+pedestal+"  "+NSA+NSB);
+
+        // pedestal subtraction:
+        sum -= pedestal*(NSA+NSB)/nsPerSample;
+      
+        //System.err.println("1111111111111111111      "+thresholdCrossing+"   "+sum);
+        
+        // conversion of ADC to energy:
+        double rawEnergy = adcToEnergy(sum, id);
+        
+        return CalorimeterHitUtilities.create(rawEnergy, time, id);
+    }
+
+    /*
      * This HitDtoA is for Mode-3 data at least, but definitely not Mode-7.
      * A time-walk correction can be applied.  (NAB 2015/02/11).
      */

Modified: java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java
 =============================================================================
--- java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java	(original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java	Thu Feb 26 17:59:21 2015
@@ -20,6 +20,11 @@
  *
  * @version $Id: HPSEcalRawConverterDriver.java,v 1.2 2012/05/03 00:17:54
  * phansson Exp $
+ *
+ * baltzell Feb 26, 2015:
+ * added firmware emulation for converting from Mode-1 readout (RawTrackerHit)
+ * to Mode-3 pulse (CalorimeterHit).  Turn it on with "emulateFirmware", else
+ * defaults to previous behavior.
  */
 public class EcalRawConverterDriver extends Driver {
 
@@ -43,6 +48,8 @@
     private boolean useTimestamps = false;
     private boolean useTruthTime = false;
 
+    private boolean emulateFirmware = false;
+    
     public EcalRawConverterDriver() {
         converter = new EcalRawConverter();
     }
@@ -70,6 +77,19 @@
         this.threshold = threshold;
     }
 
+    public void setEmulateFirmware(boolean emulateFirmware) {
+        this.emulateFirmware = emulateFirmware;
+    }
+    public void setLeadingEdgeThreshold(double threshold) {
+        converter.setLeadingEdgeThreshold(threshold);
+    }
+    public void setNsa(int nsa) {
+        converter.setNSA(nsa);
+    }
+    public void setNsb(int nsb) {
+        converter.setNSB(nsb);
+    }
+    
     public void setGain(double gain) {
         converter.setGain(gain);
     }
@@ -182,7 +202,15 @@
                 List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName);
 
                 for (RawTrackerHit hit : hits) {
-                    CalorimeterHit newHit = converter.HitDtoA(hit);
+                    
+                    CalorimeterHit newHit = null;
+                    if (emulateFirmware) {
+                        newHit = converter.firmwareHitDtoA(hit);
+                        if (newHit==null) continue;
+                    } else {
+                        newHit = converter.HitDtoA(hit);
+                    }
+                
 
                     // Get the channel data.
                     EcalChannelConstants channelData = findChannel(newHit.getCellID());

Added: java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EngineeringRun2014ECalRecon_Pass1_FirmwareEmulator.lcsim
 =============================================================================
--- java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EngineeringRun2014ECalRecon_Pass1_FirmwareEmulator.lcsim	(added)
+++ java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EngineeringRun2014ECalRecon_Pass1_FirmwareEmulator.lcsim	Thu Feb 26 17:59:21 2015
@@ -0,0 +1,70 @@
+<!-- 
+    Offline reconstruction for 2014 engineering run (ECal only) data.
+
+    Changes made by JM:
+            
+    -Replaced clustering Drivers with new recon.ecal.cluster classes.    
+    -Commented out the legacy clusterer. 
+    -Configured ReconClusterDriver to not write the rejected hit collection.
+    -Changed output cluster collection names.
+     
+     NAB: (Feb 11, 2015) Added EcalRunningPedestalDriver
+     
+    @author Matt Graham <[log in to unmask]> 
+    @author Jeremy McCormick<[log in to unmask]>
+-->
+<lcsim xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+    xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/lcsim/1.0/lcsim.xsd">
+    <execute>
+        <!--<driver name="EventMarkerDriver" />-->
+        <driver name="EcalRunningPedestal"/>
+        <driver name="EcalRawConverter" />
+        <driver name="ReconClusterer" />
+        <driver name="GTPOnlineClusterer" />
+        <driver name="LCIOWriter" />
+        <driver name="CleanupDriver" />
+    </execute>
+    <drivers>
+        <driver name="EventMarkerDriver" type="org.lcsim.job.EventMarkerDriver">
+            <eventInterval>1</eventInterval>
+        </driver>
+        <driver name="EcalRunningPedestal" type="org.hps.recon.ecal.ECalRunningPedestalDriver">
+            <minLookbackEvents>10</minLookbackEvents>
+            <maxLookbackEvents>50</maxLookbackEvents>
+        </driver>
+        <driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">
+            <ecalCollectionName>EcalCalHits</ecalCollectionName>
+            <use2014Gain>false</use2014Gain>
+            <useTimestamps>false</useTimestamps>
+            <useTruthTime>false</useTruthTime>
+            <useRunningPedestal>true</useRunningPedestal>
+            <useTimeWalkCorrection>true</useTimeWalkCorrection>
+            <emulateFirmware>true</emulateFirmware>
+            <leadingEdgeThreshold>12</leadingEdgeThreshold>
+            <nsa>20</nsa>
+            <nsb>100</nsb>
+        </driver>       
+        <driver name="ReconClusterer" type="org.hps.recon.ecal.cluster.ReconClusterDriver">
+            <logLevel>WARNING</logLevel>
+            <outputClusterCollectionName>EcalClusters</outputClusterCollectionName>
+            <hitEnergyThreshold>0.01</hitEnergyThreshold>
+            <seedEnergyThreshold>0.100</seedEnergyThreshold> 
+            <clusterEnergyThreshold>0.200</clusterEnergyThreshold>
+            <minTime>0.0</minTime>
+            <timeWindow>25.0</timeWindow>
+            <useTimeCut>true</useTimeCut>
+            <writeRejectedHitCollection>false</writeRejectedHitCollection>
+        </driver>
+        <driver name="GTPOnlineClusterer" type="org.hps.recon.ecal.cluster.ClusterDriver">
+            <logLevel>WARNING</logLevel>
+            <clustererName>GTPOnlineClusterer</clustererName>
+            <outputClusterCollectionName>EcalClustersGTP</outputClusterCollectionName>
+            <!-- seedMinEnergy -->
+            <cuts>0.100</cuts>
+        </driver>        
+        <driver name="LCIOWriter" type="org.lcsim.util.loop.LCIODriver">
+            <outputFilePath>${outputFile}.slcio</outputFilePath>
+        </driver>
+        <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />
+    </drivers>
+</lcsim>