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>
|