Author: [log in to unmask]
Date: Sat Mar 7 10:02:10 2015
New Revision: 2337
Log:
Updating all FADC Modes to more properly pedestal subtract clipped pulses, mainly just to aid trigger studies although it will never 100% match SSP which is always unclipped. Updating Mode-1 to find multiple pulses in one channel. For Mode-1, switching to current status of SSP firmware emulation for threshold crossing (>=) instead of FADC firmware (>) to aid trigger studies. Apparently they are different, and firmware may be changed to make them equal. Implemented conversion from Mode-1 to Mode-7. Default behavior for Mode-3 and Mode-7 is unchanged.
Added:
java/trunk/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015ECalRecon.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 Sat Mar 7 10:02:10 2015
@@ -1,5 +1,7 @@
package org.hps.recon.ecal;
+import java.awt.List;
+import java.util.ArrayList;
import java.util.Map;
import org.hps.conditions.database.DatabaseConditionsManager;
@@ -16,18 +18,33 @@
/**
* This class is used to convert {@link org.lcsim.event.RawCalorimeterHit}
- * objects to {@link org.lcsim.event.CalorimeterHit} objects with energy
- * 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.
+ * and {@link org.lcsim.event.RawTrackerHit} to {@link org.lcsim.event.CalorimeterHit}
+ * objects with energy information.
*
* @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]>
+ * @author Nathan Baltzell <[log in to unmask]>
+ *
+ *
+ * baltzell: New in 2015: (default behavior is still unchanged)
+ *
+ * Implemented conversion of Mode-1 to Mode-3.
*
+ * Now using NSA/NSB for pedestal subtraction instead of integralWindow, to allow
+ * treating all FADC Modes uniformly. (New) NSA+NSB == (Old) integralWindow*4(ns)
+ *
+ * Pedestal subtracting clipped pulses more correctly for all Modes.
+ *
+ * Changed threshold cut for Mode-1 to >= instead of > to emulate SSP instead of
+ * FADC firmware for trigger diagnostics.
+ *
+ * Implemented finding multiple peaks for Mode-1.
+ *
+ * Implemented conversion of Mode-1 to Mode-7 with high-resolution timing.
+ * Only some of the special cases in the firmware for when this algorithm fails due
+ * to bad pulses (e.g. clipping) are already implemented. Not yet writing Mode-7's
+ * min/max to data stream.
*/
public class EcalRawConverter {
@@ -43,23 +60,46 @@
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 leading-edge threshold, relative to pedestal, for pulse-finding and
+ * time determination. Units = ADC. Used to convert mode-1 readout into
+ * mode-3/7 used by 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.
+ * Integration range after (NSA) and before (NSB) threshold crossing. Units=ns,
+ * same as the DAQ configuration files. These must be multiples of 4 ns. Used
+ * for pulse integration in Mode-1, and pedestal subtraction in all modes.
*
* The default values of 20/100 are what we had during the entire 2014 run.
*/
private int NSB=20;
private int NSA=100;
-
+
+ /*
+ * The number of samples in the FADC readout window. Needed in order to
+ * properly pedestal-correct clipped pulses for Mode-3/7. Ignored for
+ * mode-1 input, since it already knows its number of samples.
+ *
+ * A non-positive number disables pulse-clipped pedestals and reverts to
+ * the old behavior which assumed integration range was constant.
+ *
+ */
+ private int windowSamples=-1;
+
+ /*
+ * The maximum number of peaks to be searched for.
+ */
+ private int nPeak=3;
+
+ /*
+ * Convert Mode-1 into Mode-7, else Mode-3.
+ */
+ private boolean mode7=false;
+
+
private EcalConditions ecalConditions = null;
public EcalRawConverter() {
@@ -80,7 +120,20 @@
}
NSB=nsb;
}
-
+ public void setWindowSamples(int windowSamples) {
+ this.windowSamples=windowSamples;
+ }
+ public void setNPeak(int nPeak) {
+ if (nPeak<1 || nPeak>3) {
+ throw new RuntimeException("Npeak must be 1, 2, or 3.");
+ }
+ this.nPeak=nPeak;
+ }
+ public void setMode7(boolean mode7)
+ {
+ this.mode7=mode7;
+ }
+
public void setGain(double gain) {
constantGain = true;
this.gain = gain;
@@ -93,25 +146,48 @@
public void setUseRunningPedestal(boolean useRunningPedestal) {
this.useRunningPedestal=useRunningPedestal;
}
-
+
public void setUseTimeWalkCorrection(boolean useTimeWalkCorrection) {
this.useTimeWalkCorrection=useTimeWalkCorrection;
}
-
- /*
- * NAB 2015/02/11
- * Choose whether to use static pedestal from database or running pedestal.
- * This can only used for Mode-7 data.
- */
- public double getMode7Pedestal(EventHeader event,RawCalorimeterHit hit)
- {
- if (useRunningPedestal) {
+
+ /*
+ * This should probably be deprecated. It just integrates the entire window.
+ */
+ public short sumADC(RawTrackerHit hit) {
+ EcalChannelConstants channelData = findChannel(hit.getCellID());
+ double pedestal = channelData.getCalibration().getPedestal();
+ short sum = 0;
+ short samples[] = hit.getADCValues();
+ for (int isample = 0; isample < samples.length; ++isample) {
+ sum += (samples[isample] - pedestal);
+ }
+ return sum;
+ }
+
+ /*
+ * This should probably be deprecated. HitDtoA(EventHeader,RawTrackerHit)
+ * has the same functionality if NSA+NSB > windowSamples, with the exception
+ * that that one also finds pulse time instead of this one's always reporting zero.
+ */
+ public CalorimeterHit HitDtoA(RawTrackerHit hit) {
+ double time = hit.getTime();
+ long id = hit.getCellID();
+ double rawEnergy = adcToEnergy(sumADC(hit), id);
+ return CalorimeterHitUtilities.create(rawEnergy, time, id);
+ }
+
+ /*
+ * Get pedestal for a single ADC sample.
+ * Choose whether to use static pedestal from database or running pedestal from mode-7.
+ */
+ public double getSingleSamplePedestal(EventHeader event,long cellID) {
+ if (useRunningPedestal && event!=null) {
if (event.hasItem("EcalRunningPedestals")) {
Map<EcalChannel, Double> runningPedMap=
(Map<EcalChannel, Double>)
event.get("EcalRunningPedestals");
- EcalChannel chan = ecalConditions.getChannelCollection().
- findGeometric(hit.getCellID());
+ EcalChannel chan = ecalConditions.getChannelCollection().findGeometric(cellID);
if (!runningPedMap.containsKey(chan)){
System.err.println("************** Missing Pedestal");
} else {
@@ -125,65 +201,39 @@
useRunningPedestal = false;
}
}
- return findChannel(hit.getCellID()).getCalibration().getPedestal();
- }
-
- public short sumADC(RawTrackerHit hit) {
- EcalChannelConstants channelData = findChannel(hit.getCellID());
- double pedestal = channelData.getCalibration().getPedestal();
- short sum = 0;
+ return findChannel(cellID).getCalibration().getPedestal();
+ }
+
+ /*
+ * Get pedestal for entire pulse integral. Account for clipping if
+ * windowSamples is greater than zero.
+ */
+ public double getPulsePedestal(EventHeader event,long cellID,int windowSamples,int thresholdCrossing) {
+ int firstSample,lastSample;
+ if ( windowSamples>0 && (NSA+NSB)/nsPerSample >= windowSamples ) {
+ // special case where firmware always integrates entire window
+ firstSample = 0;
+ lastSample = windowSamples-1;
+ } else {
+ firstSample = thresholdCrossing - NSB/nsPerSample;
+ lastSample = thresholdCrossing + NSA/nsPerSample-1;
+ if (windowSamples > 0) {
+ // properly pedestal subtract pulses clipped by edge(s) of readout window:
+ if (firstSample < 0) firstSample=0;
+ if (lastSample >= windowSamples) lastSample=windowSamples-1;
+ }
+ }
+ return (lastSample-firstSample+1)*getSingleSamplePedestal(event,cellID);
+ }
+
+
+ /*
+ * Emulate the FADC250 firmware emulation Mode-1 waveform to a Mode-3/7 pulse,
+ * given a time for threshold crossing.
+ */
+ public double[] convertWaveformToPulse(RawTrackerHit hit,int thresholdCrossing,boolean mode7) {
short samples[] = hit.getADCValues();
- for (int isample = 0; isample < samples.length; ++isample) {
- sum += (samples[isample] - pedestal);
- }
- 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();
- double rawEnergy = adcToEnergy(sumADC(hit), id);
- return CalorimeterHitUtilities.create(rawEnergy, time, id);
- }
-
- /*
- * 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.
- *
- */
- public CalorimeterHit firmwareHitDtoA(RawTrackerHit hit) {
-
- 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] > absoluteThreshold) {
- // special case, first sample above threshold:
- thresholdCrossing=0;
- } else {
- for (int ii = 1; ii < samples.length; ++ii) {
- if ( samples[ii] >absoluteThreshold &&
- samples[ii-1]<=absoluteThreshold)
- {
- // found threshold crossing:
- thresholdCrossing = ii;
- // one pulse only:
- break;
- }
- }
- }
- if (thresholdCrossing < 0) return null;
-
+
// choose integration range:
int firstSample,lastSample;
if ((NSA+NSB)/nsPerSample >= samples.length) {
@@ -194,43 +244,154 @@
firstSample = thresholdCrossing - NSB/nsPerSample;
lastSample = thresholdCrossing + NSA/nsPerSample - 1;
}
-
+
+ // mode-7 min and max:
+ double minADC=0;
+ double maxADC=0;
+ int sampleMaxADC=0;
+
// pulse integral:
- short sum = 0;
+ short sumADC = 0;
+
for (int jj=firstSample; jj<=lastSample; jj++) {
+
if (jj<0) continue;
if (jj>=samples.length) break;
- sum += samples[jj];
- }
-
- // pedestal subtraction:
- sum -= pedestal*(NSA+NSB)/nsPerSample;
+
+ // integrate pulse:
+ sumADC += samples[jj];
+
+ // compute "minimum" at beginning of window:
+ if (jj<4) minADC+=samples[jj];
+
+ // find pulse maximum:
+ if (jj>firstSample && jj<samples.length-5) {
+ if (samples[jj+1]<samples[jj]) {
+ sampleMaxADC=jj;
+ maxADC=samples[jj];
+ }
+ }
+ }
+
+ // minADC is the average of first four samples:
+ minADC/=4;
- // 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.
- * A time-walk correction can be applied.
- */
- public CalorimeterHit HitDtoA(RawCalorimeterHit hit, double timeOffset) {
+ // pulse time with 4ns resolution:
+ double pulseTime=thresholdCrossing*nsPerSample;
+
+ // calculate Mode-7 high-resolution time:
+ if (mode7) {
+ if (thresholdCrossing < 4) {
+ maxADC=0;
+ }
+ else if (maxADC>0) {
+ // linear interpolation between threshold crossing and
+ // pulse maximum to find time at pulse half-height:
+ double t0 = thresholdCrossing*nsPerSample;
+ double a0 = samples[thresholdCrossing];
+ double t1 = sampleMaxADC*nsPerSample;
+ double a1 = maxADC;
+ double slope = (a1-a0)/(t1-t0);
+ double halfMax = (maxADC+minADC)/2;
+ double tmpTime = t1 - (a1 - halfMax) / slope;
+ if (slope>0 && tmpTime>0) {
+ pulseTime = tmpTime;
+ }
+ }
+ }
+
+ return new double []{pulseTime,sumADC,minADC,maxADC};
+ }
+
+
+ /*
+ * This HitDtoA is for emulating the conversion of Mode-1 readout (RawTrackerHit)
+ * into what EcalRawConverter would have created from a Mode-3 or Mode-7 readout.
+ * Clustering classes will read the resulting CalorimeterHits same as if they were
+ * directly readout from the FADCs in Mode-3/7.
+ *
+ * For Mode-3, hit time is just the time of threshold crossing, with an optional
+ * time-walk correction. For Mode-7, it is a "high-resolution" one calculated
+ * by linear interpolation between threshold crossing and pulse maximum.
+ *
+ * TODO: Generate GenericObject (and corresponding LCRelation) to store min and max
+ * to fully emulate mode-7. This is less important for now.
+ *
+ * NOTE: March 7, 2015. Threshold crossing requirement currently emulates the current
+ * SSP firmware (>=) instead of FADC firmware (>) to aid trigger studies. Firmware will
+ * be changed to make them identical. But for now this code prefers SSP over FADC.
+ */
+ public ArrayList <CalorimeterHit> HitDtoA(EventHeader event,RawTrackerHit hit) {
+
+ final long cellID = hit.getCellID();
+ final short samples[] = hit.getADCValues();
+ if (samples.length==0) return null;
+
+ // threshold is pedestal plus threshold configuration parameter:
+ final int absoluteThreshold = (int)(getSingleSamplePedestal(event,cellID)+leadingEdgeThreshold);
+
+ ArrayList <Integer> thresholdCrossings = new ArrayList<Integer>();
+
+ // special case, first sample is above threshold:
+ if (samples[0] >= absoluteThreshold) { // SSP/FADC firmware discrepancy.
+ thresholdCrossings.add(0);
+ }
+
+ // search for threshold crossings:
+ for (int ii = 1; ii < samples.length; ++ii) {
+ if ( samples[ii] >= absoluteThreshold &&
+ samples[ii-1] < absoluteThreshold) // SSP/FADC firmware discrepancy.
+ {
+ // found one:
+ thresholdCrossings.add(ii);
+
+ // search for next threshold crossing begins at end of this pulse:
+ ii += NSA/nsPerSample-1;
+
+ // firmware limit on # of peaks:
+ if (thresholdCrossings.size() >= nPeak) break;
+ }
+ }
+
+ // make hits
+ ArrayList <CalorimeterHit> newHits=new ArrayList<CalorimeterHit>();
+ for (int thresholdCrossing : thresholdCrossings) {
+
+ // do pulse integral:
+ final double[] data = convertWaveformToPulse(hit,thresholdCrossing,mode7);
+ double time = data[0];
+ double sum = data[1];
+ final double min = data[2]; // TODO: stick min and max in a GenericObject with an
+ final double max = data[3]; // LCRelation to finish mode-7 emulation
+
+ // do pedestal subtraction:
+ sum -= getPulsePedestal(event,cellID,samples.length,thresholdCrossing);
+
+ // do gain scaling:
+ double energy = adcToEnergy(sum, cellID);
+
+ // do time-walk correction, mode-3 only:
+ if (!mode7 && useTimeWalkCorrection) {
+ time = EcalTimeWalk.correctTimeWalk(time,energy);
+ }
+
+ newHits.add(CalorimeterHitUtilities.create(energy,time,cellID));
+ }
+
+ return newHits;
+ }
+
+ /*
+ * This HitDtoA is for Mode-3 data. A time-walk correction can be applied.
+ */
+ public CalorimeterHit HitDtoA(EventHeader event,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 pedestal = getPulsePedestal(event,id,windowSamples,(int)time/nsPerSample);
+ double adcSum = hit.getAmplitude() - pedestal;
double rawEnergy = adcToEnergy(adcSum, id);
if (useTimeWalkCorrection) {
time = EcalTimeWalk.correctTimeWalk(time,rawEnergy);
@@ -240,15 +401,12 @@
/*
* This HitDtoA is exclusively for Mode-7 data, hence the GenericObject parameter.
- * The decision to call this method is made in EcalRawConverterDriver based on the
- * 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, 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 pedestal = getPulsePedestal(event,id,windowSamples,(int)time/nsPerSample);
+ double adcSum = hit.getAmplitude() - pedestal;
double rawEnergy = adcToEnergy(adcSum, id);
return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id);
}
@@ -263,11 +421,11 @@
// Get the channel data.
EcalChannelConstants channelData = findChannel(id);
int amplitude;
- int window = (NSA+NSB)/nsPerSample;
+ double pedestal = getPulsePedestal(null,id,windowSamples,(int)hit.getTime()/nsPerSample);
if (constantGain) {
- amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + window * channelData.getCalibration().getPedestal());
+ amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / gain + pedestal);
} else {
- amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / channelData.getGain().getGain() + window * channelData.getCalibration().getPedestal());
+ amplitude = (int) Math.round((hit.getRawEnergy() / ECalUtils.MeV) / channelData.getGain().getGain() + pedestal);
}
RawCalorimeterHit h = new BaseRawCalorimeterHit(id, amplitude, time);
return h;
@@ -314,5 +472,6 @@
*/
public EcalChannelConstants findChannel(long cellID) {
return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
- }
+ }
+
}
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 Sat Mar 7 10:02:10 2015
@@ -20,15 +20,18 @@
*
* @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)
+ * baltzell
+ *
+ *
+ * baltzell New in 2015: (default behavior is unchanged)
+ * 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. 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.
+ * defaults to previous behavior.
+ *
+ * Removed integralWindow in favor of NSA/NSB to allow treating all Modes uniformly.
+ * (New) NSA+NSB == (Old) integralWindow*4(ns)
*
+ * Implemented finding multiple peaks for Mode-1.
*/
public class EcalRawConverterDriver extends Driver {
@@ -41,7 +44,6 @@
private String ecalCollectionName = "EcalCalHits";
private static final String extraDataRelationsName = "EcalReadoutExtraDataRelations";
-// private static final String extraDataCollectionName = "EcalReadoutExtraData";
private boolean debug = false;
private double threshold = Double.NEGATIVE_INFINITY;
@@ -80,17 +82,26 @@
this.threshold = threshold;
}
+ public void setEmulateMode7(boolean mode7) {
+ converter.setMode7(mode7);
+ }
public void setEmulateFirmware(boolean emulateFirmware) {
this.emulateFirmware = emulateFirmware;
}
public void setLeadingEdgeThreshold(double threshold) {
converter.setLeadingEdgeThreshold(threshold);
}
+ public void setWindowSamples(int windowSamples) {
+ converter.setWindowSamples(windowSamples);
+ }
public void setNsa(int nsa) {
converter.setNSA(nsa);
}
public void setNsb(int nsb) {
converter.setNSB(nsb);
+ }
+ public void setNPeak(int nPeak) {
+ converter.setNPeak(nPeak);
}
public void setGain(double gain) {
@@ -196,37 +207,48 @@
if (!runBackwards) {
ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>();
- // Get the list of ECal hits.
+ /*
+ * This is for FADC Mode-1 data:
+ */
if (event.hasCollection(RawTrackerHit.class, rawCollectionName)) {
List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName);
for (RawTrackerHit hit : hits) {
-
- CalorimeterHit newHit = null;
+
+ ArrayList<CalorimeterHit> newHits2 = new ArrayList<CalorimeterHit>();
if (emulateFirmware) {
- newHit = converter.firmwareHitDtoA(hit);
- if (newHit==null) continue;
+ newHits2.addAll(converter.HitDtoA(event,hit));
} else {
- newHit = converter.HitDtoA(hit);
- }
-
-
- // Get the channel data.
- EcalChannelConstants channelData = findChannel(newHit.getCellID());
-
- if (applyBadCrystalMap && channelData.isBadChannel()) {
- continue;
- }
- if (dropBadFADC && isBadFADC(newHit)) {
- continue;
- }
- if (newHit.getRawEnergy() > threshold) {
- newHits.add(newHit);
+ newHits2.add(converter.HitDtoA(hit));
+ }
+
+ for (CalorimeterHit newHit : newHits2) {
+
+ // Get the channel data.
+ EcalChannelConstants channelData = findChannel(newHit.getCellID());
+
+ if (applyBadCrystalMap && channelData.isBadChannel()) {
+ continue;
+ }
+ if (dropBadFADC && isBadFADC(newHit)) {
+ continue;
+ }
+ if (newHit.getRawEnergy() > threshold) {
+ newHits.add(newHit);
+ }
}
}
event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName);
}
+
+ /*
+ * This is for FADC pulse mode data (Mode-3 or Mode-7):
+ */
if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { //A.C. this is the case of the RAW pulse hits
+
+ /*
+ * This is for FADC Mode-7 data:
+ */
if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from mode 7 readout
List<LCRelation> extraDataRelations = event.get(LCRelation.class, extraDataRelationsName);
for (LCRelation rel : extraDataRelations) {
@@ -252,13 +274,16 @@
}
} else {
+ /*
+ * This is for FADC Mode-3 data:
+ */
List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, rawCollectionName);
for (RawCalorimeterHit hit : hits) {
if (debug) {
System.out.format("old hit energy %d\n", hit.getAmplitude());
}
CalorimeterHit newHit;
- newHit = converter.HitDtoA(hit, timeOffset);
+ newHit = converter.HitDtoA(event, hit, timeOffset);
if (newHit.getRawEnergy() > threshold) {
if (applyBadCrystalMap && isBadCrystal(newHit)) {
continue;
@@ -295,6 +320,7 @@
event.put(rawCollectionName, newHits, RawCalorimeterHit.class, flags, ecalReadoutName);
}
}
+
}
/**
Added: java/trunk/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015ECalRecon.lcsim
=============================================================================
--- java/trunk/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015ECalRecon.lcsim (added)
+++ java/trunk/steering-files/src/main/resources/org/hps/steering/recon/EngineeringRun2015ECalRecon.lcsim Sat Mar 7 10:02:10 2015
@@ -0,0 +1,74 @@
+<!--
+ 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">
+ <logLevel>CONFIG</logLevel>
+ <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>
+ <emulateMode7>false</emulateMode7>
+ <leadingEdgeThreshold>12</leadingEdgeThreshold>
+ <nsa>100</nsa>
+ <nsb>20</nsb>
+ <windowSamples>50</windowSamples>
+ <nPeak>3</nPeak>
+ </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>
|