Author: [log in to unmask]
Date: Wed Mar 4 08:05:05 2015
New Revision: 2239
Log:
Updating EcalRawConverter(Driver) to use NSA/NSB instead of integralWindow in order to unify conversion of all FADC Modes. Updated a couple old steering files accordingly. TODO: Implmement mode-1->mode-7 conversion, implmement more correct pedestal correction for clipped pulses.
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
java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerMonitoring.lcsim
java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerWindowMonitoring.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/EcalRawConverter.java (original)
+++ java/trunk/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java Wed Mar 4 08:05:05 2015
@@ -20,10 +20,14 @@
* information. It has methods to convert pedestal subtracted ADC counts to
* energy.
*
+ * TODO: Switch all mode's HitDtoAs to use a clipped pedestal for clipped pulses.
+ * This requires another parameter, the window size.
+ *
* @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 {
@@ -33,15 +37,28 @@
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)
-
+ /*
+ * The time for one FADC sample (units = ns).
+ */
+ private static final int nsPerSample = 4;
+
+ /*
+ * The leading-edge threshold, relative to pedestal, for readout and pulse time
+ * determination. Units = ADC. This is used to convert mode-1 readout into
+ * mode-3/7 for clustering.
+ *
+ * The default value of 12 is what we used for most of the 2014 run.
+ */
+ private double leadingEdgeThreshold=12;
+
+ /*
+ * Integration range after (NSA) and before (NSB) threshold crossing. (units = ns)
+ * These must be multiples of 4 ns.
+ *
+ * The default values of 20/100 are what we had during the entire 2014 run.
+ */
+ private int NSB=20;
+ private int NSA=100;
private EcalConditions ecalConditions = null;
@@ -52,9 +69,15 @@
leadingEdgeThreshold=thresh;
}
public void setNSA(int nsa) {
+ if (NSA%nsPerSample !=0 || NSA<0) {
+ throw new RuntimeException("NSA must be multiples of 4ns and non-negative.");
+ }
NSA=nsa;
}
public void setNSB(int nsb) {
+ if (NSB%nsPerSample !=0 || NSB<0) {
+ throw new RuntimeException("NSB must be multiples of 4ns and non-negative.");
+ }
NSB=nsb;
}
@@ -89,7 +112,6 @@
event.get("EcalRunningPedestals");
EcalChannel chan = ecalConditions.getChannelCollection().
findGeometric(hit.getCellID());
- //System.err.println(" %%%%%%%%%%%%%%%%% "+chan.getChannelId()+" "+runningPedMap.get(chan));
if (!runningPedMap.containsKey(chan)){
System.err.println("************** Missing Pedestal");
} else {
@@ -105,6 +127,7 @@
}
return findChannel(hit.getCellID()).getCalibration().getPedestal();
}
+
public short sumADC(RawTrackerHit hit) {
EcalChannelConstants channelData = findChannel(hit.getCellID());
double pedestal = channelData.getCalibration().getPedestal();
@@ -116,6 +139,10 @@
return sum;
}
+ /*
+ * This should this be replaced by firmwareHitDtoA, as that has the
+ * same functionality if NSA+NSB > window size. Left for now.
+ */
public CalorimeterHit HitDtoA(RawTrackerHit hit) {
double time = hit.getTime();
long id = hit.getCellID();
@@ -125,42 +152,28 @@
/*
* NAB 2015/02/26
+ * This HitDtoA is for emulating the conversion of Mode-1 readout (RawTrackerHit)
+ * into what EcalRawConverter would have created from a Mode-3 readout.
*
- * 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();
-
+ double absoluteThreshold = pedestal+leadingEdgeThreshold;
+
// find threshold crossing:
int thresholdCrossing = -1;
- if (samples[0] > pedestal+leadingEdgeThreshold) {
+ if (samples[0] > absoluteThreshold) {
// 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)
+ if ( samples[ii] >absoluteThreshold &&
+ samples[ii-1]<=absoluteThreshold)
{
// found threshold crossing:
thresholdCrossing = ii;
@@ -171,41 +184,52 @@
}
if (thresholdCrossing < 0) return null;
- // pulse time:
- double time = thresholdCrossing*nsPerSample;
-
+ // choose integration range:
+ int firstSample,lastSample;
+ if ((NSA+NSB)/nsPerSample >= samples.length) {
+ // firmware treats this case specially:
+ firstSample = 0;
+ lastSample = samples.length-1;
+ } else {
+ firstSample = thresholdCrossing - NSB/nsPerSample;
+ lastSample = thresholdCrossing + NSA/nsPerSample - 1;
+ }
+
// pulse integral:
short sum = 0;
- for (int jj=thresholdCrossing-NSB/nsPerSample; jj<thresholdCrossing+NSA/nsPerSample; jj++) {
+ for (int jj=firstSample; jj<=lastSample; 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);
+ // pulse time:
+ double time = thresholdCrossing*nsPerSample;
+ if (useTimeWalkCorrection) {
+ time = EcalTimeWalk.correctTimeWalk(time,rawEnergy);
+ }
+
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).
- */
- public CalorimeterHit HitDtoA(RawCalorimeterHit hit, int window, double timeOffset) {
+ * This HitDtoA is for Mode-3 data.
+ * A time-walk correction can be applied.
+ */
+ public CalorimeterHit HitDtoA(RawCalorimeterHit hit, double timeOffset) {
if (hit.getTimeStamp() % 64 != 0) {
System.out.println("unexpected timestamp " + hit.getTimeStamp());
}
double time = hit.getTimeStamp() / 16.0;
long id = hit.getCellID();
EcalChannelConstants channelData = findChannel(id);
+ int window = (NSA+NSB)/nsPerSample;
double adcSum = hit.getAmplitude() - window * channelData.getCalibration().getPedestal();
double rawEnergy = adcToEnergy(adcSum, id);
if (useTimeWalkCorrection) {
@@ -220,20 +244,26 @@
* format of the input EVIO data. EventHeader is also passed in order to allow access
* to running pedestals, which is only applicable to Mode-7 data. (NAB, 2015/02/11)
*/
- public CalorimeterHit HitDtoA(EventHeader event,RawCalorimeterHit hit, GenericObject mode7Data, int window, double timeOffset) {
+ public CalorimeterHit HitDtoA(EventHeader event,RawCalorimeterHit hit, GenericObject mode7Data, double timeOffset) {
double time = hit.getTimeStamp() / 16.0; //timestamps use the full 62.5 ps resolution
long id = hit.getCellID();
+ int window = (NSA+NSB)/nsPerSample;
double adcSum = hit.getAmplitude() - window * getMode7Pedestal(event,hit);
double rawEnergy = adcToEnergy(adcSum, id);
return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id);
}
- public RawCalorimeterHit HitAtoD(CalorimeterHit hit, int window) {
+ /*
+ * This converts a corrected pulse integral (pedestal-subtracted and gain-scaled)
+ * back into raw pulse integral with units ADC.
+ */
+ public RawCalorimeterHit HitAtoD(CalorimeterHit hit) {
int time = (int) (Math.round(hit.getTime() / 4.0) * 64.0);
long id = hit.getCellID();
// Get the channel data.
EcalChannelConstants channelData = findChannel(id);
int amplitude;
+ int window = (NSA+NSB)/nsPerSample;
if (constantGain) {
amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + window * channelData.getCalibration().getPedestal());
} else {
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 Wed Mar 4 08:05:05 2015
@@ -21,10 +21,14 @@
* @version $Id: HPSEcalRawConverterDriver.java,v 1.2 2012/05/03 00:17:54
* phansson Exp $
*
- * baltzell Feb 26, 2015:
+ * 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.
+ * defaults to previous behavior. Removed integralWindow in favor of NSA and
+ * NSB in EcalRawConverter, so that all conversions can use the same window.
+ * March 3, 2015: Removed integralWindow in favor of NSA/NSB in order to treat
+ * all modes uniformly.
+ *
*/
public class EcalRawConverterDriver extends Driver {
@@ -39,7 +43,6 @@
private static final String extraDataRelationsName = "EcalReadoutExtraDataRelations";
// private static final String extraDataCollectionName = "EcalReadoutExtraData";
- private int integralWindow = 30; //A.C. on 12/14/2014 8:44 after discussion with Nathan.
private boolean debug = false;
private double threshold = Double.NEGATIVE_INFINITY;
private boolean applyBadCrystalMap = true;
@@ -92,10 +95,6 @@
public void setGain(double gain) {
converter.setGain(gain);
- }
-
- public void setIntegralWindow(int integralWindow) {
- this.integralWindow = integralWindow;
}
public void setEcalCollectionName(String ecalCollectionName) {
@@ -237,7 +236,7 @@
}
GenericObject extraData = (GenericObject) rel.getTo();
CalorimeterHit newHit;
- newHit = converter.HitDtoA(event,hit, extraData, integralWindow, timeOffset);
+ newHit = converter.HitDtoA(event,hit, extraData, timeOffset);
if (newHit.getRawEnergy() > threshold) {
if (applyBadCrystalMap && isBadCrystal(newHit)) {
continue;
@@ -259,7 +258,7 @@
System.out.format("old hit energy %d\n", hit.getAmplitude());
}
CalorimeterHit newHit;
- newHit = converter.HitDtoA(hit, integralWindow, timeOffset);
+ newHit = converter.HitDtoA(hit, timeOffset);
if (newHit.getRawEnergy() > threshold) {
if (applyBadCrystalMap && isBadCrystal(newHit)) {
continue;
@@ -285,7 +284,7 @@
if (debug) {
System.out.format("old hit energy %f\n", hit.getRawEnergy());
}
- RawCalorimeterHit newHit = converter.HitAtoD(hit, integralWindow);
+ RawCalorimeterHit newHit = converter.HitAtoD(hit);
if (newHit.getAmplitude() > 0) {
if (debug) {
System.out.format("new hit energy %d\n", newHit.getAmplitude());
Modified: java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerMonitoring.lcsim
=============================================================================
--- java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerMonitoring.lcsim (original)
+++ java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerMonitoring.lcsim Wed Mar 4 08:05:05 2015
@@ -23,7 +23,9 @@
<drivers>
<driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalReadoutToTriggerConverterDriver">
<rawCollectionName>EcalReadoutHits</rawCollectionName>
- <integralWindow>35</integralWindow>
+ <!--<integralWindow>35</integralWindow> Deprecated, now use the equivalent in NSA/NSB-->
+ <nsa>120</nsa>
+ <nsb>20</nsb>
<applyBadCrystalMap>false</applyBadCrystalMap>
<dropBadFADC>true</dropBadFADC>
<tp>14.0</tp>
Modified: java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerWindowMonitoring.lcsim
=============================================================================
--- java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerWindowMonitoring.lcsim (original)
+++ java/trunk/steering-files/src/main/resources/org/hps/steering/monitoring/ECalTriggerWindowMonitoring.lcsim Wed Mar 4 08:05:05 2015
@@ -26,7 +26,9 @@
</driver>
<driver name="EcalRawConverter" type="org.hps.recon.ecal.EcalRawConverterDriver">
<rawCollectionName>EcalIntegralHits</rawCollectionName>
- <integralWindow>35</integralWindow>
+ <!--<integralWindow>35</integralWindow> Deprecated, now use the equivalent in NSA/NSB-->
+ <nsa>120</nsa>
+ <nsb>20</nsb>
<gain>1.0</gain>
<use2014Gain>false</use2014Gain>
</driver>
|