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>