Author: [log in to unmask] Date: Fri Oct 21 12:23:19 2016 New Revision: 4523 Log: (empty) Modified: java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java (contents, props changed) java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java (contents, props changed) Modified: java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java ============================================================================= --- java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java (original) +++ java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverter.java Fri Oct 21 12:23:19 2016 @@ -22,162 +22,117 @@ import org.lcsim.geometry.Detector; /** - * This class is used to convert between {@link org.lcsim.event.RawCalorimeterHit} - * or {@link org.lcsim.event.RawTrackerHit}, objects with ADC/sample information, - * and {@link org.lcsim.event.CalorimeterHit}, an object with energy+time information. - * - * At minimum this involves pedestal subtraction/addition and gain scaling. - * - * Knows how to deal with Mode-1/3/7 FADC readout formats. - * Can perform Mode-3/7 firmware algorithms on Mode-1 data. - * Can alternatively call pulse-fitting on Mode-1 data. - * + * This class is used to convert between {@link org.lcsim.event.RawCalorimeterHit} or + * {@link org.lcsim.event.RawTrackerHit}, objects with ADC/sample information, and + * {@link org.lcsim.event.CalorimeterHit}, an object with energy+time information. At minimum this involves pedestal + * subtraction/addition and gain scaling. Knows how to deal with Mode-1/3/7 FADC readout formats. Can perform Mode-3/7 + * firmware algorithms on Mode-1 data. Can alternatively call pulse-fitting on Mode-1 data. All time walk/time offset + * corrections are performed to this collection after gains in EcalTimeCorrectionDriver * * @author Sho Uemura <[log in to unmask]> * @author Andrea Celentano <[log in to unmask]> * @author Nathan Baltzell <[log in to unmask]> * @author Holly Szumila <[log in to unmask]> - * */ public class EcalRawConverter { - /** - * If true, time walk correction is performed. - */ - private boolean useTimeWalkCorrection = true; + + /** + * If true, running pedestal is used. + */ + private boolean useRunningPedestal = true; + - /** - * If true, running pedestal is used. - */ - private boolean useRunningPedestal = true; - - /** - * If true, use a single gain factor for all channels. - * Else, use 442 gains from the conditions system. - */ - private boolean constantGain = false; - - /** - * A single gain factor for all channels (only used if constantGain=true) - */ - private double gain; - - /** - * If true, the relationship between ADC and GeV is a convention that - * includes readoutPeriod and a global scaling factor. - * - * If false, it is the currently used convention: E(GeV) = GAIN * ADC - */ - private boolean use2014Gain = false; - - /** - * If true, use the DAQ configuration from EVIO to set EcalRawConverter parameters. - * This should be removed to a standalone EcalRawConverter solely for trigger emulation. + + /** + * If true, use the DAQ configuration from EVIO to set EcalRawConverter parameters. This should be removed to a + * standalone EcalRawConverter solely for trigger emulation. */ private boolean useDAQConfig = false; - - /** - * The DAQ configuration from EVIO used to set EcalRawConverter parameters - * if useDAQConfig=true. This should be removed to a standalone EcalRawConverter - * solely for trigger emulation. + + /** + * The DAQ configuration from EVIO used to set EcalRawConverter parameters if useDAQConfig=true. This should be + * removed to a standalone EcalRawConverter solely for trigger emulation. */ private FADCConfig config = null; - - /** - * Whether to use pulse fitting (EcalPulseFitter) to extract pulse energy time. - * Only applicable to Mode-1 data. + + /** + * Whether to use pulse fitting (EcalPulseFitter) to extract pulse energy time. Only applicable to Mode-1 data. */ private boolean useFit = true; - + /** * The pulse fitter class. */ private EcalPulseFitter pulseFitter = new EcalPulseFitter(); - /** - * activates a display of all the fits in AIDA. - * @param display - */ - public void setDisplay(boolean display){ - pulseFitter.setDebug(display); - } - + /** * The time for one FADC sample (units = ns). */ private static final int nsPerSample = 4; - - /** - * 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. + + /** + * 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, - * 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. + + /** + * 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. + + /** + * 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. - * This is applicable only to Mode-1 data. + + /** + * The maximum number of peaks to be searched for. This is applicable only to Mode-1 data. */ private int nPeak = 3; - - /** - * Perform Mode-7 algorithm, else Mode-3. - * Only applicable to Mode-1 data. + + /** + * Perform Mode-7 algorithm, else Mode-3. Only applicable to Mode-1 data. */ private boolean mode7 = true; - private EcalConditions ecalConditions = null; /** - * Currently sets up a listener for DAQ configuration from EVIO. - * This should be removed to a standalone ECalRawConverter solely - * for trigger emulation. + * Currently sets up a listener for DAQ configuration from EVIO. This should be removed to a standalone + * ECalRawConverter solely for trigger emulation. */ public EcalRawConverter() { // Track changes in the DAQ configuration. ConfigurationManager.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { // If the DAQ configuration should be used, load the // relevant settings into the driver. - if(useDAQConfig) { + if (useDAQConfig) { // Get the FADC configuration. config = ConfigurationManager.getInstance().getFADCConfig(); - + // Load the settings. NSB = config.getNSB(); NSA = config.getNSA(); windowSamples = config.getWindowWidth() / 4; - + // Get the number of peaks. - if(config.getMode() == 1) { + if (config.getMode() == 1) { nPeak = Integer.MAX_VALUE; } else { nPeak = config.getMaxPulses(); } - + // Print the FADC configuration. System.out.println(); System.out.println(); @@ -193,185 +148,140 @@ } }); } - + + public void setUseFit(boolean useFit) { + this.useFit = useFit; + } + + public void setFixShapeParameter(boolean fix) { + pulseFitter.fixShapeParameter = fix; + } + + public void setGlobalFixedPulseWidth(double width) { + pulseFitter.globalThreePoleWidth = width; + pulseFitter.fixShapeParameter = true; + } + + /** + * Pulses with threshold crossing earlier than this will not be fit. + */ + public void setFitThresholdTimeLo(int sample) { + pulseFitter.threshRange[0] = sample; + } + + /** + * Pulses with threshold crossing time greater than this will not be fit. + */ + public void setFitThresholdTimeHi(int sample) { + pulseFitter.threshRange[1] = sample; + } + + /** + * Tell Minuit to limit pulse time parameter in fit to be greater than this. + */ + public void setFitLimitTimeLo(int sample) { + pulseFitter.t0limits[0] = sample; + } + + /** + * Tell Minuit to limit pulse time parameter in fit to be less than this. + */ + public void setFitLimitTimeHi(int sample) { + pulseFitter.t0limits[1] = sample; + } + + /** + * Set threshold for pulse finding. Units = ADC + */ + public void setLeadingEdgeThreshold(double thresh) { + leadingEdgeThreshold = thresh; + } + + /** + * Set number of samples after threshold crossing for pulse integration range. + */ + 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; + } + + /** + * Set number of samples before threshold crossing for pulse integration range. + */ + 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; + } + + /** + * Set number of samples in readout window. Used for pedestal subtraction for clipped pulses. This is ignored for + * Mode-1 raw data, since Mode-1 knows its number of samples. + */ + public void setWindowSamples(int windowSamples) { + this.windowSamples = windowSamples; + } + + /** + * Set maximum number of pulses to search for in Mode-1 data. + */ + public void setNPeak(int nPeak) { + if (nPeak < 1 || nPeak > 3) { + throw new RuntimeException("Npeak must be 1, 2, or 3."); + } + this.nPeak = nPeak; + } + + /** + * Set Mode-7 emulation on/off. If off, falls back to Mode-3. + */ + public void setMode7(boolean mode7) { + this.mode7 = mode7; + } + - public void setUseFit(boolean useFit) { this.useFit=useFit; } - public void setFixShapeParameter(boolean fix) { pulseFitter.fixShapeParameter=fix; } - public void setGlobalFixedPulseWidth(double width) { - pulseFitter.globalThreePoleWidth=width; - pulseFitter.fixShapeParameter=true; - } - - /** - * Pulses with threshold crossing earlier than this will not be fit. - */ - public void setFitThresholdTimeLo(int sample) { pulseFitter.threshRange[0]=sample; } - /** - * Pulses with threshold crossing time greater than this will not be fit. - */ - public void setFitThresholdTimeHi(int sample) { pulseFitter.threshRange[1]=sample; } - /** - * Tell Minuit to limit pulse time parameter in fit to be greater than this. - */ - public void setFitLimitTimeLo(int sample) { pulseFitter.t0limits[0]=sample; } - /** - * Tell Minuit to limit pulse time parameter in fit to be less than this. - */ - public void setFitLimitTimeHi(int sample) { pulseFitter.t0limits[1]=sample; } - - - - /** - * Set threshold for pulse finding. Units = ADC - */ - public void setLeadingEdgeThreshold(double thresh) { - leadingEdgeThreshold=thresh; - } - - /** - * Set number of samples after threshold crossing for pulse integration range. - */ - 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; - } - - /** - * Set number of samples before threshold crossing for pulse integration range. - */ - 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; - } + + /** + * Enables using running pedestals calculated on the fly from previous events. If false, uses 442 fixed pedestals + * from the conditions system. Only applies to FADC Mode-1/7 input data formats. + */ + public void setUseRunningPedestal(boolean useRunningPedestal) { + this.useRunningPedestal = useRunningPedestal; + } + - /** - * Set number of samples in readout window. - * - * Used for pedestal subtraction for clipped pulses. - * This is ignored for Mode-1 raw data, since Mode-1 knows its number of samples. - */ - public void setWindowSamples(int windowSamples) { - this.windowSamples=windowSamples; - } - - /** - * Set maximum number of pulses to search for in Mode-1 data. - */ - public void setNPeak(int nPeak) { - if (nPeak<1 || nPeak>3) { - throw new RuntimeException("Npeak must be 1, 2, or 3."); - } - this.nPeak=nPeak; - } - - /** - * Set Mode-7 emulation on/off. If off, falls back to Mode-3. - */ - public void setMode7(boolean mode7) - { - this.mode7=mode7; - } - - /** - * Set global gain value and turn on constant gain. - * The 442 gains from the conditions system will be ignored. - */ - public void setGain(double gain) { - constantGain = true; - this.gain = gain; - } - - /** - * Chooses which ADC --> Energy convention is used. - * - * If true, the relationship between ADC and GeV is a convention that - * includes readoutPeriod and a global scaling factor. - * - * If false, it is the currently used convention: E(GeV) = GAIN * ADC - */ - public void setUse2014Gain(boolean use2014Gain) { - this.use2014Gain = use2014Gain; - } - - /** - * Enables using running pedestals calculated on the fly from previous events. - * If false, uses 442 fixed pedestals from the conditions system. - * - * Only applies to FADC Mode-1/7 input data formats. - */ - public void setUseRunningPedestal(boolean useRunningPedestal) { - this.useRunningPedestal=useRunningPedestal; - } - - /** - * Set whether to use timewalk corrections. - */ - public void setUseTimeWalkCorrection(boolean useTimeWalkCorrection) { - this.useTimeWalkCorrection=useTimeWalkCorrection; - } - - /** - * Set whether to use DAQ configuration read from EVIO to set EcalRawConverter parameters. - * This should be removed to a standalone EcalRawCongverterDriver solely - * for trigger emulation. + + /** + * Set whether to use DAQ configuration read from EVIO to set EcalRawConverter parameters. This should be removed to + * a standalone EcalRawCongverterDriver solely for trigger emulation. */ public void setUseDAQConfig(boolean state) { useDAQConfig = state; } + + + - - /** - * Integrate the entire window. Return pedestal-subtracted integral. - */ - public int sumADC(RawTrackerHit hit) { - EcalChannelConstants channelData = findChannel(hit.getCellID()); - double pedestal; - if(useDAQConfig) { - //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID()); - pedestal = config.getPedestal(hit.getCellID()); - } else { - pedestal = channelData.getCalibration().getPedestal(); - } - - int 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(useDAQConfig) { - //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(cellID); + /** + * 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 (useDAQConfig) { + // EcalChannel channel = + // ecalConditions.getChannelCollection().findGeometric(cellID); return config.getPedestal(cellID); } - if (useRunningPedestal && event!=null) { + if (useRunningPedestal && event != null) { if (event.hasItem("EcalRunningPedestals")) { + @SuppressWarnings("unchecked") Map<EcalChannel, Double> runningPedMap = (Map<EcalChannel, Double>) event.get("EcalRunningPedestals"); EcalChannel chan = ecalConditions.getChannelCollection().findGeometric(cellID); - if (!runningPedMap.containsKey(chan)){ + if (!runningPedMap.containsKey(chan)) { System.err.println("************** Missing Pedestal"); } else { return runningPedMap.get(chan); @@ -388,314 +298,311 @@ } /** - * 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 ) { + * 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; + lastSample = windowSamples - 1; } else { - firstSample = thresholdCrossing - NSB/nsPerSample; - lastSample = thresholdCrossing + NSA/nsPerSample-1; + 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 in conversion of Mode-1 waveform to a Mode-3/7 pulse, - * given a time for threshold crossing. - */ - public double[] convertWaveformToPulse(RawTrackerHit hit,int thresholdCrossing,boolean mode7) { - + // 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 in conversion of Mode-1 waveform to a Mode-3/7 pulse, given a time for threshold + * crossing. + */ + public double[] convertWaveformToPulse(RawTrackerHit hit, int thresholdCrossing, boolean mode7) { + double fitQuality = -1; - + short samples[] = hit.getADCValues(); - //System.out.println("NewEvent"); + // System.out.println("NewEvent"); // choose integration range: - int firstSample,lastSample; - if ((NSA+NSB)/nsPerSample >= samples.length) { + int firstSample, lastSample; + if ((NSA + NSB) / nsPerSample >= samples.length) { // firmware treats this case specially: firstSample = 0; - lastSample = samples.length-1; + lastSample = samples.length - 1; } else { - firstSample = thresholdCrossing - NSB/nsPerSample; - lastSample = thresholdCrossing + NSA/nsPerSample - 1; - } - + firstSample = thresholdCrossing - NSB / nsPerSample; + lastSample = thresholdCrossing + NSA / nsPerSample - 1; + } + // mode-7's minimum/pedestal (average of first 4 samples): - double minADC=0; - for (int jj=0; jj<4; jj++) minADC += samples[jj]; - // does the firmware's conversion of min to int occur before or after time calculation? undocumented. - //minADC=(int)(minADC/4); - minADC = (minADC/4); - - //System.out.println("Avg pedestal:\t"+minADC); - + double minADC = 0; + for (int jj = 0; jj < 4; jj++) + minADC += samples[jj]; + // does the firmware's conversion of min to int occur before or after + // time calculation? undocumented. + // minADC=(int)(minADC/4); + minADC = (minADC / 4); + + // System.out.println("Avg pedestal:\t"+minADC); + // mode-7's max pulse height: - double maxADC=0; - //int sampleMaxADC=0; - + double maxADC = 0; + // int sampleMaxADC=0; + // mode-3/7's pulse integral: double sumADC = 0; - - for (int jj=firstSample; jj<=lastSample; jj++) { - - if (jj<0) continue; - if (jj>=samples.length) break; - + + for (int jj = firstSample; jj <= lastSample; jj++) { + + if (jj < 0) + continue; + if (jj >= samples.length) + break; + // integrate pulse: sumADC += samples[jj]; } // find pulse maximum: - //if (jj>firstSample && jj<samples.length-5) { // The "5" here is a firmware constant. - for (int jj=thresholdCrossing; jj<samples.length-5; jj++) { // The "5" here is a firmware constant. - if (samples[jj+1]<samples[jj]){ - //sampleMaxADC=jj; - maxADC=samples[jj]; - break; - } - } - + // if (jj>firstSample && jj<samples.length-5) { // The "5" here is a + // firmware constant. + for (int jj = thresholdCrossing; jj < samples.length - 5; jj++) { // The + // "5" + // here + // is + // a + // firmware + // constant. + if (samples[jj + 1] < samples[jj]) { + // sampleMaxADC=jj; + maxADC = samples[jj]; + break; + } + } // pulse time with 4ns resolution: - double pulseTime=thresholdCrossing*nsPerSample; + double pulseTime = thresholdCrossing * nsPerSample; // calculate Mode-7 high-resolution time: if (mode7) { if (thresholdCrossing < 4) { - // special case where firmware sets max to zero and time to 4ns time. - maxADC=0; - } - else if (maxADC>0) { + // special case where firmware sets max to zero and time to 4ns + // time. + maxADC = 0; + } else if (maxADC > 0) { // linear interpolation between threshold crossing and // pulse maximum to find time at pulse half-height: - final double halfMax = (maxADC+minADC)/2; + final double halfMax = (maxADC + minADC) / 2; int t0 = -1; - for (int ii=thresholdCrossing-1; ii<lastSample; ii++) - { - if (ii>=samples.length-1) break; - if (samples[ii]<=halfMax && samples[ii+1]>halfMax) - { + for (int ii = thresholdCrossing - 1; ii < lastSample; ii++) { + if (ii >= samples.length - 1) + break; + if (samples[ii] <= halfMax && samples[ii + 1] > halfMax) { t0 = ii; break; } } - if (t0 > 0) - { + if (t0 > 0) { final int t1 = t0 + 1; final int a0 = samples[t0]; final int a1 = samples[t1]; - //final double slope = (a1 - a0); // units = ADC/sample - //final double yint = a1 - slope * t1; // units = ADC - pulseTime = ((halfMax - a0)/(a1-a0) + t0)* nsPerSample; + // final double slope = (a1 - a0); // units = ADC/sample + // final double yint = a1 - slope * t1; // units = ADC + pulseTime = ((halfMax - a0) / (a1 - a0) + t0) * nsPerSample; } } } - - if (useFit) - { - IFitResult fitResult = pulseFitter.fitPulse(hit,thresholdCrossing,maxADC); - if (fitResult!=null) { - fitQuality = fitResult.quality(); - if (fitQuality > 0) { - pulseTime = fitResult.fittedParameter("time0")*nsPerSample; - sumADC = fitResult.fittedParameter("integral"); - minADC = fitResult.fittedParameter("pedestal"); - maxADC = ((Ecal3PoleFunction)fitResult.fittedFunction()).maximum(); - } - } - } - - return new double []{pulseTime,sumADC,minADC,maxADC,fitQuality}; - } - - - /** - * 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. - * - */ - public ArrayList <CalorimeterHit> HitDtoA(EventHeader event, RawTrackerHit hit) { + + if (useFit) { + IFitResult fitResult = pulseFitter.fitPulse(hit, thresholdCrossing, maxADC); + if (fitResult != null) { + fitQuality = fitResult.quality(); + if (fitQuality > 0) { + pulseTime = fitResult.fittedParameter("time0") * nsPerSample; + sumADC = fitResult.fittedParameter("integral"); + minADC = fitResult.fittedParameter("pedestal"); + maxADC = ((Ecal3PoleFunction) fitResult.fittedFunction()).maximum(); + } + } + } + + return new double[] {pulseTime, sumADC, minADC, maxADC, fitQuality}; + } + + /** + * 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. + */ + public ArrayList<CalorimeterHit> HitDtoA(EventHeader event, RawTrackerHit hit) { final long cellID = hit.getCellID(); final short samples[] = hit.getADCValues(); - if(samples.length == 0) return null; - + if (samples.length == 0) + return null; + // threshold is pedestal plus threshold configuration parameter: final int absoluteThreshold; - if(useDAQConfig) { - //EcalChannel channel = ecalConditions.getChannelCollection().findGeometric(hit.getCellID()); - //int leadingEdgeThreshold = ConfigurationManager.getInstance().getFADCConfig().getThreshold(channel.getChannelId()); + if (useDAQConfig) { + // EcalChannel channel = + // ecalConditions.getChannelCollection().findGeometric(hit.getCellID()); + // int leadingEdgeThreshold = + // ConfigurationManager.getInstance().getFADCConfig().getThreshold(channel.getChannelId()); int leadingEdgeThreshold = config.getThreshold(cellID); absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold); } else { absoluteThreshold = (int) (getSingleSamplePedestal(event, cellID) + leadingEdgeThreshold); } - - ArrayList <Integer> thresholdCrossings = new ArrayList<Integer>(); - + + ArrayList<Integer> thresholdCrossings = new ArrayList<Integer>(); + // special case, first sample is above threshold: if (samples[0] > absoluteThreshold) { thresholdCrossings.add(0); - } - + } + // search for threshold crossings: - for(int ii = 1; ii < samples.length; ++ii) { - if ( samples[ii] > absoluteThreshold && - samples[ii-1] <= absoluteThreshold) { - + for (int ii = 1; ii < samples.length; ++ii) { + if (samples[ii] > absoluteThreshold && samples[ii - 1] <= absoluteThreshold) { + // found one: thresholdCrossings.add(ii); - // search for next threshold crossing begins at end of this pulse: - if(useDAQConfig && ConfigurationManager.getInstance().getFADCConfig().getMode() == 1) { + // search for next threshold crossing begins at end of this + // pulse: + if (useDAQConfig && ConfigurationManager.getInstance().getFADCConfig().getMode() == 1) { // special case, emulating SSP: ii += 8; } else { // "normal" case, emulating FADC250: - ii += NSA/nsPerSample - 1; + ii += NSA / nsPerSample - 1; } // firmware limit on # of peaks: - if (thresholdCrossings.size() >= nPeak) break; - } - } - + if (thresholdCrossings.size() >= nPeak) + break; + } + } + // make hits - ArrayList <CalorimeterHit> newHits = new ArrayList<CalorimeterHit>(); - for(int thresholdCrossing : thresholdCrossings) { + 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 + // 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 final double fitQuality = data[4]; + + if (!useFit || fitQuality <= 0) { + // do pedestal subtraction: + sum -= getPulsePedestal(event, cellID, samples.length, thresholdCrossing); + } + + // do gain scaling using a dummy gain. - if (!useFit || fitQuality<=0) { - // 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); - } - - // do time-walk correction, pulse-fitting only: - if (useFit && fitQuality>0 && useTimeWalkCorrection && mode7) { - time = EcalTimeWalk.correctTimeWalkPulseFitting(time,energy); - - } - - time -= findChannel(cellID).getTimeShift().getTimeShift(); - - - newHits.add(CalorimeterHitUtilities.create(energy,time,cellID)); - } - + + newHits.add(CalorimeterHitUtilities.create(sum, 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) { + + + /** + * 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(); - double pedestal = getPulsePedestal(event,id,windowSamples,(int)time/nsPerSample); + 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); - } - time -= findChannel(hit.getCellID()).getTimeShift().getTimeShift(); - return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id); + //double rawEnergy = adcToEnergy(adcSum); + + return CalorimeterHitUtilities.create(adcSum, time + timeOffset, id); } /** * This HitDtoA is exclusively for Mode-7 data, hence the GenericObject parameter. */ - 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 + 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(); - double pedestal = getPulsePedestal(event,id,windowSamples,(int)time/nsPerSample); + double pedestal = getPulsePedestal(event, id, windowSamples, (int) time / nsPerSample); double adcSum = hit.getAmplitude() - pedestal; - double rawEnergy = adcToEnergy(adcSum, id); - time -= findChannel(hit.getCellID()).getTimeShift().getTimeShift(); - return CalorimeterHitUtilities.create(rawEnergy, time + timeOffset, id); - } - - /** - * This converts a corrected pulse integral (pedestal-subtracted and gain-scaled) - * back into raw pulse integral with units ADC. + //double rawEnergy = adcToEnergy(adcSum); + return CalorimeterHitUtilities.create(adcSum, time + timeOffset, id); + } + + /** + * 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); + //EcalChannelConstants channelData = findChannel(id); int amplitude; double pedestal = getPulsePedestal(null, id, windowSamples, (int) hit.getTime() / nsPerSample); - if (constantGain) { - amplitude = (int) Math.round((hit.getRawEnergy() / EcalUtils.MeV) / gain + pedestal); - } else { - amplitude = (int) Math.round((hit.getRawEnergy() / EcalUtils.MeV) / channelData.getGain().getGain() + pedestal); - } - time += findChannel(id).getTimeShift().getTimeShift(); + amplitude = (int) Math.round((hit.getRawEnergy() / EcalUtils.MeV) / (EcalUtils.gainFactor * EcalUtils.ecalReadoutPeriod) + pedestal); + + // time += findChannel(id).getTimeShift().getTimeShift(); RawCalorimeterHit h = new BaseRawCalorimeterHit(id, amplitude, time); return h; } /** - * return energy (units of GeV) corresponding to the ADC sum and crystal ID - */ - private double adcToEnergy(double adcSum, long cellID) { - - // Get the channel data. - EcalChannelConstants channelData = findChannel(cellID); - - if(useDAQConfig) { - //float gain = ConfigurationManager.getInstance().getFADCConfig().getGain(ecalConditions.getChannelCollection().findGeometric(cellID)); - return config.getGain(cellID) * adcSum * EcalUtils.MeV; - } else if(use2014Gain) { - if (constantGain) { - return adcSum * EcalUtils.gainFactor * EcalUtils.ecalReadoutPeriod; - } else { - return channelData.getGain().getGain() * adcSum * EcalUtils.gainFactor * EcalUtils.ecalReadoutPeriod; // should not be used for the moment (2014/02) - } + * 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 adcSum = sumADC(hit); + return CalorimeterHitUtilities.create(adcSum, time, id); + } + + /** + * Integrate the entire window. Return pedestal-subtracted integral. + */ + public int sumADC(RawTrackerHit hit) { + EcalChannelConstants channelData = findChannel(hit.getCellID()); + double pedestal; + if (useDAQConfig) { + // EcalChannel channel = + // ecalConditions.getChannelCollection().findGeometric(hit.getCellID()); + pedestal = config.getPedestal(hit.getCellID()); } else { - if(constantGain) { - return gain * adcSum * EcalUtils.MeV; - } else { - return channelData.getGain().getGain() * adcSum * EcalUtils.MeV; //gain is defined as MeV/integrated ADC - } - } + pedestal = channelData.getCalibration().getPedestal(); + } + + int sum = 0; + short samples[] = hit.getADCValues(); + for (int isample = 0; isample < samples.length; ++isample) { + sum += (samples[isample] - pedestal); + } + return sum; } /** @@ -718,10 +625,5 @@ public EcalChannelConstants findChannel(long cellID) { return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID)); } - - - public void setFixedWidth(boolean fixedWidth) { - this.pulseFitter.fixShapeParameter = fixedWidth; - } - + } Modified: java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java ============================================================================= --- java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java (original) +++ java/branches/converter-div/ecal-recon/src/main/java/org/hps/recon/ecal/EcalRawConverterDriver.java Fri Oct 21 12:23:19 2016 @@ -18,12 +18,13 @@ import org.lcsim.util.Driver; /** - * This <code>Driver</code> converts raw ECal data collections to {@link org.lcsim.event.CalorimeterHit} collections - * with energy and time information. The {@link EcalRawConverter} does most of the low-level work. + * This <code>Driver</code> converts raw ECal data collections to {@link org.lcsim.event.CalorimeterHit} collections + * with energy and time information. The {@link EcalRawConverter} does most of the low-level work. * <p> * The following input collections are used: * <ul> - * <li>EcalReadoutHits<li> + * <li>EcalReadoutHits + * <li> * <li>EcalReadoutExtraDataRelations</li> * <li>EcalRunningPedestals</li> * </ul> @@ -37,21 +38,20 @@ private EcalRawConverter converter = null; /** - * Input collection name (unless runBackwards=true, then it's output). - * Can be a {@link org.lcsim.event.RawTrackerHit} or {@link org.lcsim.event.RawCalorimeterHit} - * These have ADC and sample time information. + * Input collection name (unless runBackwards=true, then it's output). Can be a + * {@link org.lcsim.event.RawTrackerHit} or {@link org.lcsim.event.RawCalorimeterHit} These have ADC and sample time + * information. */ private String rawCollectionName = "EcalReadoutHits"; - - /** - * Output collection name (unless runBackwards=true, then it's input). - * Always a {@link org.lcsim.event.CalorimeterHit} - * This has energy (GeV) and ns time information. - */ - private String ecalCollectionName = "EcalCalHits"; - - /** - * ecalCollectionName "type" (must match detector-data) + + /** + * Output collection name (unless runBackwards=true, then it's input). Always a + * {@link org.lcsim.event.CalorimeterHit} This has energy (GeV) and ns time information. + */ + private String ecalCollectionName = "EcalUncalHits"; + + /** + * ecalCollectionName "type" (must match detector-data) */ private final String ecalReadoutName = "EcalHits"; @@ -61,58 +61,52 @@ private static final String extraDataRelationsName = "EcalReadoutExtraDataRelations"; private boolean debug = false; - - /** - * Hit threshold in GeV. Anything less will not be put into LCIO. + + /** + * Hit threshold in GeV. Anything less will not be put into LCIO. */ private double threshold = Double.NEGATIVE_INFINITY; - - /** - * Whether to reject bad crystals. + + /** + * Whether to reject bad crystals. */ private boolean applyBadCrystalMap = true; - + /** * Whether to reject bad FADC channels. */ private boolean dropBadFADC = false; - - /** - * If true, convert ecalCollectionName to rawCollectionName (GeV to ADC). - * Else, convert rawCollectionName to ecalCollectionName (ADC to GeV). + + /** + * If true, convert ecalCollectionName to rawCollectionName (GeV to ADC). Else, convert rawCollectionName to + * ecalCollectionName (ADC to GeV). */ private boolean runBackwards = false; - + /** * */ private boolean useTimestamps = false; - + /** * */ private boolean useTruthTime = false; - - /** - * Whether to use DAQ config read from EVIO for EcalRawConverter parameters. - * Should be completely removed to a standalone class soilely for trigger emulation. + + /** + * Whether to use DAQ config read from EVIO for EcalRawConverter parameters. Should be completely removed to a + * standalone class soilely for trigger emulation. */ private boolean useDAQConfig = false; /** - * Whether to perform "firmware algorithm" on Mode-1 data. - * - * If so, this includes finding a threshold crossing, extracting - * a pulse time, and integrating over some configurable sample - * range inside the window to extract pulse integral. - * - * If not, it simply integrates the entire window and makes - * no attempt at extracting pulse time. - * - * This is poorly named. + * Whether to perform "firmware algorithm" on Mode-1 data. If so, this includes finding a threshold crossing, + * extracting a pulse time, and integrating over some configurable sample range inside the window to extract pulse + * integral. If not, it simply integrates the entire window and makes no attempt at extracting pulse time. This is + * poorly named. */ private boolean emulateFirmware = true; - + public EcalRawConverterDriver() { converter = new EcalRawConverter(); } @@ -120,74 +114,61 @@ /** * Set to <code>true</code> to use pulse fitting instead of arithmetic integration:<br/> */ - public void setUseFit(boolean useFit) { converter.setUseFit(useFit); } - - /** - * Fix 3-pole function width to be the same for all 442 ECal channels. Units=samples. - */ - public void setGlobalFixedPulseWidth(double width) { converter.setGlobalFixedPulseWidth(width); } - + public void setUseFit(boolean useFit) { + converter.setUseFit(useFit); + } + + /** + * Fix 3-pole function width to be the same for all 442 ECal channels. Units=samples. + */ + public void setGlobalFixedPulseWidth(double width) { + converter.setGlobalFixedPulseWidth(width); + } + /** * Set to <code>true</code> to fix fitted pulse widths to their channel's mean value:<br/> */ - public void setFixShapeParameter(boolean fix) { converter.setFixShapeParameter(fix); } - - /** - * Limit threshold crossing range that is candidate for pulse-fitting. Units=samples. - */ - public void setFitThresholdTimeLo(int sample) { converter.setFitThresholdTimeLo(sample); } - public void setFitThresholdTimeHi(int sample) { converter.setFitThresholdTimeHi(sample); } - - /** - * Constrain pulse fit time0 parameter. Units=samples. - */ - public void setFitLimitTimeLo(int sample) { converter.setFitLimitTimeLo(sample); } - public void setFitLimitTimeHi(int sample) { converter.setFitLimitTimeHi(sample); } - - /** - * Set to <code>true</code> to use the "2014" gain formula:<br/> - * <pre>channelGain * adcSum * gainFactor * readoutPeriod</pre> - * <p> - * Set to <code>false</code> to use the gain formula for the Test Run: - * <pre>gain * adcSum * ECalUtils.MeV</pre> - * - * @param use2014Gain True to use 2014 gain formulation. - */ - public void setUse2014Gain(boolean use2014Gain) { - converter.setUse2014Gain(use2014Gain); - } - - /** - * Set to <code>true</code> to apply time walk correction from {@link EcalTimeWalk#correctTimeWalk(double, double)}. - * <p> - * This is only applicable to Mode-3 data. - * - * @param useTimeWalkCorrection True to apply time walk correction. - */ - public void setUseTimeWalkCorrection(boolean useTimeWalkCorrection) { - converter.setUseTimeWalkCorrection(useTimeWalkCorrection); - } - + public void setFixShapeParameter(boolean fix) { + converter.setFixShapeParameter(fix); + } + + /** + * Limit threshold crossing range that is candidate for pulse-fitting. Units=samples. + */ + public void setFitThresholdTimeLo(int sample) { + converter.setFitThresholdTimeLo(sample); + } + + public void setFitThresholdTimeHi(int sample) { + converter.setFitThresholdTimeHi(sample); + } + + /** + * Constrain pulse fit time0 parameter. Units=samples. + */ + public void setFitLimitTimeLo(int sample) { + converter.setFitLimitTimeLo(sample); + } + + public void setFitLimitTimeHi(int sample) { + converter.setFitLimitTimeHi(sample); + } + /** * Set to <code>true</code> to use a running pedestal calibration from mode 7 data. * <p> - * The running pedestal values are retrieved from the event collection "EcalRunningPedestals" - * which is a <code>Map</code> between {@link org.hps.conditions.ecal.EcalChannel} objects - * are their average pedestal. + * The running pedestal values are retrieved from the event collection "EcalRunningPedestals" which is a + * <code>Map</code> between {@link org.hps.conditions.ecal.EcalChannel} objects are their average pedestal. * * @param useRunningPedestal True to use a running pedestal value. */ public void setUseRunningPedestal(boolean useRunningPedestal) { converter.setUseRunningPedestal(useRunningPedestal); } - - public void setFixedWidth(boolean fixedWidth){ - this.converter.setFixedWidth(fixedWidth); - } - - /** - * Set to <code>true</code> to generate a {@link org.lcsim.event.CalorimeterHit} - * collection which is a conversion from energy to raw signals. + + /** + * Set to <code>true</code> to generate a {@link org.lcsim.event.CalorimeterHit} collection which is a conversion + * from energy to raw signals. * * @param runBackwards True to run the procedure backwards. */ @@ -196,8 +177,7 @@ } /** - * Set to <code>true</code> to drop hits that are mapped to a hard-coded - * bad FADC configuration from the Test Run. + * Set to <code>true</code> to drop hits that are mapped to a hard-coded bad FADC configuration from the Test Run. * * @param dropBadFADC True to drop hits mapped to a bad FADC. */ @@ -206,8 +186,9 @@ } /** - * Set a minimum energy threshold in GeV for created {@link org.lcsim.event.CalorimeterHit} - * objects to be written into the output collection. + * Set a minimum energy threshold in GeV for created {@link org.lcsim.event.CalorimeterHit} objects to be written + * into the output collection. + * * @param threshold The minimum energy threshold in GeV. */ public void setThreshold(double threshold) { @@ -215,15 +196,14 @@ } /** - * Set to <code>true</code> to use Mode-7 emulation in calculations. - * False is Mode-3. + * Set to <code>true</code> to use Mode-7 emulation in calculations. False is Mode-3. * * @param mode7 True to use Mode-7 emulation in calculations. */ public void setEmulateMode7(boolean mode7) { converter.setMode7(mode7); } - + /** * Set to <code>true</code> to emulate firmware conversion of Mode-1 to Mode-3/7 data. * @@ -232,10 +212,9 @@ public void setEmulateFirmware(boolean emulateFirmware) { this.emulateFirmware = emulateFirmware; } - - /** - * Set the leading-edge threshold in ADC counts, relative to pedestal, for pulse-finding - * and time determination. + + /** + * Set the leading-edge threshold in ADC counts, relative to pedestal, for pulse-finding and time determination. * <p> * Used to convert Mode-1 readout into Mode-3 or Mode-7 data that is usable by clustering. * @@ -244,24 +223,24 @@ public void setLeadingEdgeThreshold(double threshold) { converter.setLeadingEdgeThreshold(threshold); } - + /** * Set the number of samples in the FADC readout window. * <p> - * This is needed in order to properly pedestal-correct clipped pulses for mode-3 and mode-7. - * It is ignored for mode-1 input, since this data already includes the number of samples. - * <p> - * A non-positive number disables pulse-clipped pedestals and reverts to the old behavior which - * assumed that the integration range was constant. + * This is needed in order to properly pedestal-correct clipped pulses for mode-3 and mode-7. It is ignored for + * mode-1 input, since this data already includes the number of samples. + * <p> + * A non-positive number disables pulse-clipped pedestals and reverts to the old behavior which assumed that the + * integration range was constant. * * @param windowSamples The number of samples in the FADC readout window. */ public void setWindowSamples(int windowSamples) { converter.setWindowSamples(windowSamples); } - - /** - * Set the integration range in nanoseconds after the threshold crossing. + + /** + * Set the integration range in nanoseconds after the threshold crossing. * <p> * These numbers must be multiples of 4 nanoseconds. * <p> @@ -273,7 +252,7 @@ public void setNsa(int nsa) { converter.setNSA(nsa); } - + /** * Set the integration range in nanoseconds before the threshold crossing. * <p> @@ -287,28 +266,19 @@ public void setNsb(int nsb) { converter.setNSB(nsb); } - - /** - * Set the maximum number of peaks to search for in the signal, - * which must be between 1 and 3, inclusive. + + /** + * Set the maximum number of peaks to search for in the signal, which must be between 1 and 3, inclusive. + * * @param nPeak The maximum number of peaks to search for in the signal. */ public void setNPeak(int nPeak) { converter.setNPeak(nPeak); } - - /** - * Set a constant gain factor in the converter for all channels. - * @param gain The constant gain value. - */ - public void setGain(double gain) { - converter.setGain(gain); - } - - /** - * Set the {@link org.lcsim.event.CalorimeterHit} collection name, - * which is used as input in "normal" mode and output when running - * "backwards". + + /** + * Set the {@link org.lcsim.event.CalorimeterHit} collection name, which is used as input in "normal" mode and + * output when running "backwards". * * @param ecalCollectionName The <code>CalorimeterHit</code> collection name. * @see #runBackwards @@ -318,13 +288,10 @@ } /** - * Set the raw collection name which is used as output in "normal" mode - * and input when running "backwards". - * <p> - * Depending on the Driver configuration, this could be a collection - * of {@link org.lcsim.event.RawTrackerHit} objects for Mode-1 - * or {@link org.lcsim.event.RawCalorimeterHit} objects for Mode-3 - * or Mode-7. + * Set the raw collection name which is used as output in "normal" mode and input when running "backwards". + * <p> + * Depending on the Driver configuration, this could be a collection of {@link org.lcsim.event.RawTrackerHit} + * objects for Mode-1 or {@link org.lcsim.event.RawCalorimeterHit} objects for Mode-3 or Mode-7. * * @param rawCollectionName The raw collection name. */ @@ -333,8 +300,8 @@ } /** - * Set to <code>true</code> to ignore data from channels that - * are flagged as "bad" in the conditions system. + * Set to <code>true</code> to ignore data from channels that are flagged as "bad" in the conditions system. + * * @param apply True to ignore bad channels. */ public void setApplyBadCrystalMap(boolean apply) { @@ -343,52 +310,44 @@ /** * Set to <code>true</code> to turn on debug output. + * * @param debug True to turn on debug output. */ public void setDebug(boolean debug) { this.debug = debug; } - - public void setDisplay(boolean display){ - this.display = display; - converter.setDisplay(display); - } - private boolean display; - /** * Set to <code>true</code> to use timestamp information from the ECal or trigger. + * * @param useTimestamps True to use timestamp information. */ - // FIXME: What does this actually do? What calculations does it affect? + // FIXME: What does this actually do? What calculations does it affect? public void setUseTimestamps(boolean useTimestamps) { this.useTimestamps = useTimestamps; } /** * Set to <code>true</code> to use MC truth information. + * * @param useTruthTime True to use MC truth information. */ - // FIXME: What does this actually do? What calculations does it affect? + // FIXME: What does this actually do? What calculations does it affect? public void setUseTruthTime(boolean useTruthTime) { this.useTruthTime = useTruthTime; } - - /** - * Sets whether the driver should use the DAQ configuration from - * EvIO file for its parameters. If activated, the converter will - * obtain gains, thresholds, pedestals, the window size, and the - * pulse integration window from the EvIO file. This will replace - * and overwrite any manually defined settings.<br/> + + /** + * Sets whether the driver should use the DAQ configuration from EvIO file for its parameters. If activated, the + * converter will obtain gains, thresholds, pedestals, the window size, and the pulse integration window from the + * EvIO file. This will replace and overwrite any manually defined settings.<br/> * <br/> - * Note that if this setting is active, the driver will not output - * any data until a DAQ configuration has been read from the data - * stream. - * @param state - <code>true</code> indicates that the configuration - * should be read from the DAQ data in an EvIO file. Setting this - * to <code>false</code> will cause the driver to use its regular - * manually-defined settings and pull gains and pedestals from the - * conditions database. + * Note that if this setting is active, the driver will not output any data until a DAQ configuration has been read + * from the data stream. + * + * @param state - <code>true</code> indicates that the configuration should be read from the DAQ data in an EvIO + * file. Setting this to <code>false</code> will cause the driver to use its regular manually-defined + * settings and pull gains and pedestals from the conditions database. */ public void setUseDAQConfig(boolean state) { useDAQConfig = state; @@ -431,7 +390,8 @@ return (getCrate(hit.getCellID()) == 1 && getSlot(hit.getCellID()) == 3); } - private static double getTimestamp(int system, EventHeader event) { //FIXME: copied from org.hps.readout.ecal.ReadoutTimestamp + private static double getTimestamp(int system, EventHeader event) { // FIXME: copied from + // org.hps.readout.ecal.ReadoutTimestamp if (event.hasCollection(GenericObject.class, "ReadoutTimestamps")) { List<GenericObject> timestamps = event.get(GenericObject.class, "ReadoutTimestamps"); for (GenericObject timestamp : timestamps) { @@ -449,12 +409,14 @@ public void process(EventHeader event) { // Do not process the event if the DAQ configuration should be // used for value, but is not initialized. - if(useDAQConfig && !ConfigurationManager.isInitialized()) { + if (useDAQConfig && !ConfigurationManager.isInitialized()) { + System.out.println("useDaqConfig " + useDAQConfig); + System.out.println(ConfigurationManager.isInitialized()); return; } - + final int SYSTEM_TRIGGER = 0; -// final int SYSTEM_TRACKER = 1; + // final int SYSTEM_TRACKER = 1; final int SYSTEM_ECAL = 2; double timeOffset = 0.0; @@ -469,27 +431,28 @@ } int flags = 0; - flags += 1 << LCIOConstants.RCHBIT_TIME; //store hit time - flags += 1 << LCIOConstants.RCHBIT_LONG; //store hit position; this flag has no effect for RawCalorimeterHits - + flags += 1 << LCIOConstants.RCHBIT_TIME; // store hit time + flags += 1 << LCIOConstants.RCHBIT_LONG; // store hit position; this flag has no effect for RawCalorimeterHits + if (!runBackwards) { ArrayList<CalorimeterHit> newHits = new ArrayList<CalorimeterHit>(); /* - * This is for FADC Mode-1 data: + * This is for FADC Mode-1 data: */ if (event.hasCollection(RawTrackerHit.class, rawCollectionName)) { + if(debug) System.out.println("mode1"); List<RawTrackerHit> hits = event.get(RawTrackerHit.class, rawCollectionName); for (RawTrackerHit hit : hits) { - + ArrayList<CalorimeterHit> newHits2 = new ArrayList<CalorimeterHit>(); if (emulateFirmware) { - newHits2.addAll(converter.HitDtoA(event,hit)); + newHits2.addAll(converter.HitDtoA(event, hit)); } else { newHits2.add(converter.HitDtoA(hit)); } - + for (CalorimeterHit newHit : newHits2) { // Get the channel data. @@ -507,17 +470,20 @@ } } event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName); + event.getMetaData(newHits).setTransient(true); + } - + /* * This is for FADC pulse mode data (Mode-3 or Mode-7): */ - if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { - + else if (event.hasCollection(RawCalorimeterHit.class, rawCollectionName)) { + if(debug)System.out.println("mode3or7"); /* * This is for FADC Mode-7 data: */ - if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from mode 7 readout + if (event.hasCollection(LCRelation.class, extraDataRelationsName)) { // extra information available from + if(debug) System.out.println("mode7"); // mode 7 readout List<LCRelation> extraDataRelations = event.get(LCRelation.class, extraDataRelationsName); for (LCRelation rel : extraDataRelations) { RawCalorimeterHit hit = (RawCalorimeterHit) rel.getFrom(); @@ -526,7 +492,7 @@ } GenericObject extraData = (GenericObject) rel.getTo(); CalorimeterHit newHit; - newHit = converter.HitDtoA(event,hit, extraData, timeOffset); + newHit = converter.HitDtoA(event, hit, extraData, timeOffset); if (newHit.getRawEnergy() > threshold) { if (applyBadCrystalMap && isBadCrystal(newHit)) { continue; @@ -545,6 +511,7 @@ /* * This is for FADC Mode-3 data: */ + if(debug) System.out.println("mode3"); List<RawCalorimeterHit> hits = event.get(RawCalorimeterHit.class, rawCollectionName); for (RawCalorimeterHit hit : hits) { if (debug) { @@ -567,6 +534,12 @@ } } event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName); + event.getMetaData(newHits).setTransient(true); + } + else { + if(debug) System.out.println("no raw hit collection"); + event.put(ecalCollectionName, newHits, CalorimeterHit.class, flags, ecalReadoutName); + event.getMetaData(newHits).setTransient(true); } } else { ArrayList<RawCalorimeterHit> newHits = new ArrayList<RawCalorimeterHit>(); @@ -586,9 +559,11 @@ } } event.put(rawCollectionName, newHits, RawCalorimeterHit.class, flags, ecalReadoutName); + event.getMetaData(newHits).setTransient(true); } } + } /**