Author: [log in to unmask] Date: Wed Dec 10 12:02:20 2014 New Revision: 1668 Log: Checking in current snapshot of ECAL cosmic analysis code. This will all be subsequently moved from my user area. Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitFitDriver.java java/trunk/users/src/main/java/org/hps/users/jeremym/EcalWindowModeFitFunction.java Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCProfilePlotsDriver.java java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterDriver.java java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterPlotsDriver.java java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitSelectionDriver.java java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCProfilePlotsDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCProfilePlotsDriver.java (original) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalADCProfilePlotsDriver.java Wed Dec 10 12:02:20 2014 @@ -1,11 +1,18 @@ package org.hps.users.jeremym; import hep.aida.IAnalysisFactory; +import hep.aida.IFitFactory; +import hep.aida.IFitResult; +import hep.aida.IFitter; +import hep.aida.IFunction; +import hep.aida.IFunctionFactory; import hep.aida.IProfile1D; +import hep.aida.ref.fitter.FitResult; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.hps.conditions.database.TableConstants; import org.hps.conditions.ecal.EcalChannel; @@ -27,13 +34,13 @@ EcalChannelCollection channels = null; Map<EcalChannel, IProfile1D> adcProfiles = new HashMap<EcalChannel, IProfile1D>(); AIDA aida = AIDA.defaultInstance(); - IAnalysisFactory analysisFactory = aida.analysisFactory(); + IAnalysisFactory analysisFactory = aida.analysisFactory(); String inputHitsCollectionName = "EcalReadoutHits"; - + public void setInputHitsCollectionName(String inputHitsCollectionName) { this.inputHitsCollectionName = inputHitsCollectionName; } - + public void detectorChanged(Detector detector) { conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData(); channels = conditions.getChannelCollection(); @@ -58,5 +65,5 @@ } } } - } + } } Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterDriver.java (original) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterDriver.java Wed Dec 10 12:02:20 2014 @@ -89,13 +89,13 @@ calCluster.setEnergy(totalEnergy); clusterCollection.add(calCluster); } - if (clusterCollection.size() > 0) { - int flags = 1 << LCIOConstants.CLBIT_HITS; - event.put(outputClusterCollectionName, clusterCollection, Cluster.class, flags); - //System.out.println("added " + clusterCollection.size() + " clusters to " + outputClusterCollectionName); - } else { - throw new NextEventException(); - } + //if (clusterCollection.size() > 0) { + int flags = 1 << LCIOConstants.CLBIT_HITS; + event.put(outputClusterCollectionName, clusterCollection, Cluster.class, flags); + //System.out.println("added " + clusterCollection.size() + " clusters to " + outputClusterCollectionName); + //} else { + // throw new NextEventException(); + //} } } Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterPlotsDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterPlotsDriver.java (original) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicClusterPlotsDriver.java Wed Dec 10 12:02:20 2014 @@ -1,11 +1,26 @@ package org.hps.users.jeremym; import hep.aida.IAnalysisFactory; +import hep.aida.IFitFactory; +import hep.aida.IFitResult; +import hep.aida.IFitter; +import hep.aida.IFunction; +import hep.aida.IFunctionFactory; +import hep.aida.IPlotter; +import hep.aida.IPlotterFactory; +import hep.aida.IPlotterStyle; import hep.aida.IProfile1D; - +import hep.aida.ref.fitter.FitResult; +import hep.aida.ref.function.AbstractIFunction; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.PrintWriter; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.hps.conditions.database.TableConstants; import org.hps.conditions.ecal.EcalChannel; @@ -28,25 +43,57 @@ EcalConditions conditions = null; EcalChannelCollection channels = null; + IProfile1D combinedSignalProfile; Map<EcalChannel, IProfile1D> adcProfiles = new HashMap<EcalChannel, IProfile1D>(); AIDA aida = AIDA.defaultInstance(); IAnalysisFactory analysisFactory = aida.analysisFactory(); + IFunctionFactory functionFactory = aida.analysisFactory().createFunctionFactory(null); + IFitFactory fitFactory = aida.analysisFactory().createFitFactory(); + IPlotterFactory plotterFactory = aida.analysisFactory().createPlotterFactory(); String inputClusterCollectionName = "EcalCosmicClusters"; String rawHitsCollectionName = "EcalCosmicReadoutHits"; - + boolean doFits = true; + boolean writePulseShapeParameters = true; + boolean printFitResults = false; + String pulseShapeFileName = "ecal_pulse_shape_parameters.txt"; + StringBuffer buffer; + + public void setDoFits(boolean doFits) { + this.doFits = doFits; + } + + public void setWritePulseShapeParameters(boolean writePulseShapeParameters) { + this.writePulseShapeParameters = writePulseShapeParameters; + } + + public void setPulseShapeFileName(String calibrationsOutputFileName) { + this.pulseShapeFileName = calibrationsOutputFileName; + } + public void setInputHitsCollectionName(String inputClusterCollectionName) { this.inputClusterCollectionName = inputClusterCollectionName; } public void setRawHitsCollectionName(String rawHitsCollectionName) { this.rawHitsCollectionName = rawHitsCollectionName; + } + + public void setPrintFitResults(boolean printFitResults) { + this.printFitResults = printFitResults; + } + + public void startOfData() { + combinedSignalProfile = aida.profile1D(inputClusterCollectionName + "/Combined Signal Profile", 100, 0., 100.); } public void detectorChanged(Detector detector) { conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData(); channels = conditions.getChannelCollection(); for (EcalChannel channel : conditions.getChannelCollection()) { - adcProfiles.put(channel, aida.profile1D(inputClusterCollectionName + "/ADC Values : " + String.format("%03d", channel.getChannelId()), 100, 0, 100)); + IProfile1D profile = aida.profile1D(inputClusterCollectionName + "/ADC Values : Channel " + String.format("%03d", channel.getChannelId()), 100, 0, 100); + profile.annotation().addItem("xAxisLabel", "ADC Sample"); + profile.annotation().addItem("yAxisLabel", "Counts"); + adcProfiles.put(channel, profile); } } @@ -64,6 +111,9 @@ for (int adcIndex = 0; adcIndex < rawHit.getADCValues().length; adcIndex++) { // Fill the Profile1D with ADC value. profile.fill(adcIndex, rawHit.getADCValues()[adcIndex]); + + // Fill combined Profile histogram. + combinedSignalProfile.fill(adcIndex, rawHit.getADCValues()[adcIndex]); } } else { throw new RuntimeException("EcalChannel not found for cell ID 0x" + String.format("%08d", Long.toHexString(rawHit.getCellID()))); @@ -83,5 +133,127 @@ } return rawHitMap; } - -} + + public void endOfData() { + if (doFits) { + doFits(); + } + + if (this.writePulseShapeParameters) { + PrintWriter out = null; + try { + out = new PrintWriter(this.pulseShapeFileName); + out.print(buffer.toString()); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } finally { + if (out != null) { + out.close(); + } + } + } else { + System.out.println(); + System.out.println("Printing pulse shape parameters ..."); + System.out.println(buffer.toString()); + System.out.println(); + } + } + + private void doFits() { + File plotDir = new File("fits"); + plotDir.mkdir(); + + buffer = new StringBuffer(); + buffer.append("ecal_channel_id t0 pulse_width"); + buffer.append('\n'); + + AbstractIFunction fitFunction = new EcalWindowModeFitFunction(); + functionFactory.catalog().add("ecal_fit_function", fitFunction); + for (Entry<EcalChannel, IProfile1D> entry : this.adcProfiles.entrySet()) { + doFit(entry.getKey(), entry.getValue()); + } + + fitCombinedSignalProfile(this.combinedSignalProfile); + } + + public void fitCombinedSignalProfile(IProfile1D combinedSignalProfile) { + IFunction function = functionFactory.createFunctionByName("ecal_fit_function", "ecal_fit_function"); + function.setParameter("mean", 46); + function.setParameter("sigma", 2); + function.setParameter("pedestal", 100); + function.setParameter("norm", 60.0); + + IFitter fitter = fitFactory.createFitter(); + IFitResult fitResult = fitter.fit(combinedSignalProfile, function); + + if (printFitResults) { + System.out.println(); + System.out.println("Printing fit result for channel Combined Signal Profile"); + ((FitResult)fitResult).printResult(); + System.out.println(); + } + + IPlotter plotter = plotterFactory.create(); + IPlotterStyle functionStyle = plotterFactory.createPlotterStyle(); + functionStyle.dataStyle().outlineStyle().setColor("red"); + functionStyle.legendBoxStyle().setVisible(true); + functionStyle.statisticsBoxStyle().setVisible(true); + IPlotterStyle plotStyle = plotterFactory.createPlotterStyle(); + plotStyle.dataStyle().fillStyle().setColor("blue"); + plotStyle.legendBoxStyle().setVisible(true); + plotStyle.statisticsBoxStyle().setVisible(true); + + plotter.createRegion(); + plotter.region(0).plot(combinedSignalProfile, plotStyle); + plotter.region(0).plot(fitResult.fittedFunction(), functionStyle); + try { + plotter.writeToFile("fits" + File.separator + "CombinedSignalProfileFit.png"); + } catch (IOException e) { + throw new RuntimeException(e); + } + + buffer.append("Combined Signal Profile " + fitResult.fittedFunction().parameter("mean") + " " + fitResult.fittedFunction().parameter("sigma")); + buffer.append('\n'); + } + + public void doFit(EcalChannel channel, IProfile1D profile) { + + IFunction function = functionFactory.createFunctionByName("ecal_fit_function", "ecal_fit_function"); + function.setParameter("mean", 48); + function.setParameter("sigma", 2); + function.setParameter("pedestal", conditions.getChannelConstants(channel).getCalibration().getPedestal()); + function.setParameter("norm", 60.0); + + IFitter fitter = fitFactory.createFitter(); + IFitResult fitResult = fitter.fit(profile, function); + + if (printFitResults) { + System.out.println(); + System.out.println("Printing fit result for channel " + channel.getChannelId()); + ((FitResult)fitResult).printResult(); + System.out.println(); + } + + IPlotter plotter = plotterFactory.create(); + IPlotterStyle functionStyle = plotterFactory.createPlotterStyle(); + functionStyle.dataStyle().outlineStyle().setColor("red"); + functionStyle.legendBoxStyle().setVisible(true); + functionStyle.statisticsBoxStyle().setVisible(true); + IPlotterStyle plotStyle = plotterFactory.createPlotterStyle(); + plotStyle.dataStyle().fillStyle().setColor("blue"); + plotStyle.legendBoxStyle().setVisible(true); + plotStyle.statisticsBoxStyle().setVisible(true); + + plotter.createRegion(); + plotter.region(0).plot(profile, plotStyle); + plotter.region(0).plot(fitResult.fittedFunction(), functionStyle); + try { + plotter.writeToFile("fits" + File.separator + "EcalChannel" + String.format("%03d", channel.getChannelId()) + "Fit.png"); + } catch (IOException e) { + throw new RuntimeException(e); + } + + buffer.append(channel.getChannelId() + " " + fitResult.fittedFunction().parameter("mean") + " " + fitResult.fittedFunction().parameter("sigma")); + buffer.append('\n'); + } +} Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitFitDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitFitDriver.java (added) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitFitDriver.java Wed Dec 10 12:02:20 2014 @@ -0,0 +1,238 @@ +package org.hps.users.jeremym; + +import hep.aida.IAnalysisFactory; +import hep.aida.IDataPointSet; +import hep.aida.IFitFactory; +import hep.aida.IFitResult; +import hep.aida.IFitter; +import hep.aida.IFunction; +import hep.aida.IFunctionFactory; +import hep.aida.IHistogram1D; +import hep.aida.ref.fitter.FitResult; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hps.conditions.database.TableConstants; +import org.hps.conditions.ecal.EcalChannel; +import org.hps.conditions.ecal.EcalChannel.EcalChannelCollection; +import org.hps.conditions.ecal.EcalChannelConstants; +import org.hps.conditions.ecal.EcalConditions; +import org.lcsim.conditions.ConditionsManager; +import org.lcsim.event.EventHeader; +import org.lcsim.event.RawTrackerHit; +import org.lcsim.geometry.Detector; +import org.lcsim.geometry.subdetector.HPSEcal3; +import org.lcsim.util.Driver; +import org.lcsim.util.aida.AIDA; + +/** + * This Driver will perform a functional fit on ECAL window mode data + * to determine the likelihood of a signal being present, e.g. from a cosmic + * ray MIP signal. Those hits with a signal significance greater than a settable + * threshold (by default 4 sigma) will be written into an output collection + * of selected hits that can be used by other Drivers. + * + * @author Jeremy McCormick <[log in to unmask]> + * @author Tim Nelson <[log in to unmask]> + */ +public class EcalCosmicHitFitDriver extends Driver { + + // ECAL conditions data. + EcalConditions conditions = null; + EcalChannelCollection channels = null; + + // AIDA setup. + AIDA aida = AIDA.defaultInstance(); + IAnalysisFactory analysisFactory = aida.analysisFactory(); + IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null); + IFitFactory fitFactory = analysisFactory.createFitFactory(); + IFitter fitter = fitFactory.createFitter(); + + // DPS used to fit a hit's ADC samples. + IDataPointSet adcDataPointSet; + + // Per channel histograms filled when doing the fit. + Map<EcalChannel, IHistogram1D> signalNormHistograms = new HashMap<EcalChannel, IHistogram1D>(); + Map<EcalChannel, IHistogram1D> pedestalNormHistograms = new HashMap<EcalChannel, IHistogram1D>(); + Map<EcalChannel, IHistogram1D> signalSignificanceHistograms = new HashMap<EcalChannel, IHistogram1D>(); + + // The function that will be used for the signal fit. + IFunction fitFunction; + + // The output hits collection with the selected hits. + String outputHitsCollectionName = "EcalCosmicReadoutHits"; + + // The input hits collection with all the raw data hits. + String inputHitsCollectionName = "EcalReadoutHits"; + + HPSEcal3 ecal = null; + static String ecalName = "Ecal"; + + // The minimum number of required hits for event processing to continue. + int minimumHits = 3; + + // This determines whether the pedestal is fixed in the fit parameters. + boolean fixPedestal = false; + + // This is the required significance for signal hits (4 sigma default). + static double signalSignificanceThreshold = 4.0; + + // Global fit parameters. + static double signalMean = 45.857 - 0.5; // Subtracted because of binning effect in profile histogram. Fix this! + static double signalSigma = 1.9256; + + // The initial value of the function normalization, which is not fixed in the fit. + static double norm = 60.0; + + /** + * Set the output hits collection name for the selected hits. + * @param outputHitsCollectionName The output hits collection name. + */ + public void setOutputHitsCollectionName(String outputHitsCollectionName) { + this.outputHitsCollectionName = outputHitsCollectionName; + } + + /** + * Set the input RawTrackerHit collection name used for the hit selection. + * @param inputHitsCollectionName The input hits collection name. + */ + public void setInputHitsCollectionName(String inputHitsCollectionName) { + this.inputHitsCollectionName = inputHitsCollectionName; + } + + /** + * Set the minimum number of required hits to continue processing this event. + * By default this is 3 hits. + * @param minimumHits The minimum number of hits. + */ + public void setMinimumHits(int minimumHits) { + this.minimumHits = minimumHits; + } + + /** + * Set whether the pedestal is fixed in the signal fit. By default this is false. + * @param fixPedestal True to fix the pedestal in the signal fit. + */ + public void setFixPedestal(boolean fixPedestal) { + this.fixPedestal = fixPedestal; + } + + /** + * Perform start of job setup using the detector and conditions information. + */ + public void detectorChanged(Detector detector) { + ecal = (HPSEcal3)detector.getSubdetector(ecalName); + conditions = ConditionsManager.defaultInstance().getCachedConditions(EcalConditions.class, TableConstants.ECAL_CONDITIONS).getCachedData(); + channels = conditions.getChannelCollection(); + for (EcalChannel channel : conditions.getChannelCollection()) { + signalNormHistograms.put(channel, aida.histogram1D(inputHitsCollectionName + "/Signal Norm : Channel " + String.format("%03d", channel.getChannelId()), 500, 0, 500.)); + pedestalNormHistograms.put(channel, aida.histogram1D(inputHitsCollectionName + "/Pedestal Norm : Channel " + String.format("%03d", channel.getChannelId()), 500, 0, 500.)); + signalSignificanceHistograms.put(channel, aida.histogram1D(inputHitsCollectionName + "/Signal Significance : Channel " + String.format("%03d", channel.getChannelId()), 200, -5., 35.)); + } + } + + /** + * Perform initialization to create the DPS for the ADC values and configure the global fit parameters. + */ + public void startOfData() { + adcDataPointSet = aida.analysisFactory().createDataPointSetFactory(null).create("ADC DataPointSet", 2); + + fitFunction = new EcalWindowModeFitFunction(); + fitFunction.setParameter("mean", signalMean); + fitFunction.setParameter("sigma", signalSigma); + fitFunction.setParameter("norm", norm); + + fitter.fitParameterSettings("mean").setFixed(true); + fitter.fitParameterSettings("sigma").setFixed(true); + if (fixPedestal) { + fitter.fitParameterSettings("pedestal").setFixed(true); + } + } + + /** + * Process the event, performing a signal fit for every raw data hit in the input collection. + * Those hits that pass the selection cut are added to a new hits collection that can be converted + * to a CalorimeterHit collection and clustered. + * @throw NextEventException if there are not enough hits that pass the selection cut. + */ + public void process(EventHeader event) { + if (event.hasCollection(RawTrackerHit.class, inputHitsCollectionName)) { + List<RawTrackerHit> hits = event.get(RawTrackerHit.class, inputHitsCollectionName); + List<RawTrackerHit> selectedHitsList = new ArrayList<RawTrackerHit>(); + for (RawTrackerHit hit : hits) { + EcalChannel channel = channels.findGeometric(hit.getCellID()); + if (channel != null) { + + EcalChannelConstants channelConstants = conditions.getChannelConstants(channel); + double noise = channelConstants.getCalibration().getNoise(); + + // Clear the DPS from previous fit. + adcDataPointSet.clear(); + + // Loop over all ADC values of the hit. + for (int adcSample = 0; adcSample < hit.getADCValues().length; adcSample++) { + // Insert a DP into the DPS for each sample. + adcDataPointSet.addPoint(); + + // Coordinate 1 is the ADC sample number. + adcDataPointSet.point(adcSample).coordinate(0).setValue(adcSample); + + // Coordinate 2 is the ADC sample value and its errors, which is set to the + // noise from the EcalCalibration condition object for plus and minus. + adcDataPointSet.point(adcSample).coordinate(1).setValue(hit.getADCValues()[adcSample]); + adcDataPointSet.point(adcSample).coordinate(1).setErrorMinus(noise); + adcDataPointSet.point(adcSample).coordinate(1).setErrorPlus(noise); + } + + // Fit the ADC signal. + IFitResult fitResult = fitAdcSamples(channel, adcDataPointSet); + + // Calculate the signal significance which is norm over error. + double signalSignificance = fitResult.fittedParameter("norm") / fitResult.errors()[2]; + + // Fill signal significance histogram. + this.signalSignificanceHistograms.get(channel).fill(signalSignificance); + + // Is the significance over the threshold? + if (signalSignificance >= signalSignificanceThreshold) { + System.out.println(fitResult.fittedParameter("norm") + " " + fitResult.errors()[2] + " " + signalSignificance); + // Add the hit to the output list. + selectedHitsList.add(hit); + } + } else { + throw new RuntimeException("EcalChannel not found for cell ID 0x" + String.format("%08d", Long.toHexString(hit.getCellID()))); + } + } + + // Is the hit list greater than the minimum hits? + if (selectedHitsList.size() >= minimumHits) { + // Write the hits to a new collection of selected hits. + event.put(outputHitsCollectionName, selectedHitsList, RawTrackerHit.class, event.getMetaData(hits).getFlags(), ecal.getReadout().getName()); + } else { + // Discontinue processing this event because there aren't enough hits for clustering. + throw new NextEventException(); + } + } + } + + /** + * Fit the ADC samples of a hit, returning the signal significance. + * @param channel The ECAL channel information. + * @param adcDataPointSet The DPS to use for the fit containing all 100 ADC samples. + * @return The significance which is the normalization divided by its error. + */ + IFitResult fitAdcSamples(EcalChannel channel, IDataPointSet adcDataPointSet) { + EcalChannelConstants channelConstants = conditions.getChannelConstants(channel); + fitFunction.setParameter("pedestal", channelConstants.getCalibration().getPedestal()); + IFitResult fitResult = fitter.fit(adcDataPointSet, fitFunction); + this.signalNormHistograms.get(channel).fill(fitResult.fittedParameter("norm")); + this.pedestalNormHistograms.get(channel).fill(fitResult.fittedParameter("pedestal")); + //double signalSignificance = fitResult.fittedParameter("norm") / fitResult.errors()[2]; + //this.signalSignificanceHistograms.get(channel).fill(signalSignificance); + //return signalSignificance; + return fitResult; + } +} Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitSelectionDriver.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitSelectionDriver.java (original) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalCosmicHitSelectionDriver.java Wed Dec 10 12:02:20 2014 @@ -42,7 +42,7 @@ String outputHitsCollectionName = "EcalCosmicReadoutHits"; String inputHitsCollectionName = "EcalReadoutHits"; HPSEcal3 ecal = null; - static String ecalName = "Ecal"; + static String ecalName = "Ecal"; /** * Set the sigma threshold for an ADC value. Added: java/trunk/users/src/main/java/org/hps/users/jeremym/EcalWindowModeFitFunction.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/EcalWindowModeFitFunction.java (added) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/EcalWindowModeFitFunction.java Wed Dec 10 12:02:20 2014 @@ -0,0 +1,41 @@ +package org.hps.users.jeremym; + +import hep.aida.ref.function.AbstractIFunction; + +public class EcalWindowModeFitFunction extends AbstractIFunction { + + LandauPdf landauPdf = new LandauPdf(); + + public EcalWindowModeFitFunction() { + this(""); + } + + public EcalWindowModeFitFunction(String title) { + super(); + this.variableNames = new String[] { "x0" }; + this.parameterNames = new String[] { "mean", "sigma", "norm", "pedestal" }; + init(title); + } + + @Override + public double value(double[] v) { + return this.parameter("pedestal") + this.parameter("norm") * landauPdf.getValue(v[0]); + } + + @Override + public void setParameter(String key, double value) throws IllegalArgumentException { + super.setParameter(key, value); + if (key.equals("mean")) { + landauPdf.setMean(value); + } else if (key.equals("sigma")) { + landauPdf.setSigma(value); + } + } + + @Override + public void setParameters(double[] parameters) throws IllegalArgumentException { + super.setParameters(parameters); + landauPdf.setMean(parameters[0]); + landauPdf.setSigma(parameters[1]); + } +} Modified: java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java ============================================================================= --- java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java (original) +++ java/trunk/users/src/main/java/org/hps/users/jeremym/LandauFunction.java Wed Dec 10 12:02:20 2014 @@ -4,26 +4,19 @@ public class LandauFunction extends AbstractIFunction { - LandauPdf landauPdf = new LandauPdf(); - + LandauPdf landauPdf = new LandauPdf(); + public LandauFunction() { this(""); } public LandauFunction(String title) { - - super(); - - variableNames = new String[1]; - variableNames[0] = "x0"; - - parameterNames = new String[2]; - parameterNames[0] = "mean"; - parameterNames[1] = "sigma"; - + super(); + this.variableNames = new String[] { "x0" }; + this.parameterNames = new String[] { "mean", "sigma" }; init(title); } - + @Override public double value(double[] v) { return landauPdf.getValue(v[0]); @@ -33,10 +26,8 @@ public void setParameter(String key, double value) throws IllegalArgumentException { super.setParameter(key, value); if (key.equals("mean")) { - System.out.println("set mean = " + value); landauPdf.setMean(value); } else if (key.equals("sigma")) { - System.out.println("set sigma = " + value); landauPdf.setSigma(value); } }