Author: [log in to unmask]
Date: Wed May 27 14:10:48 2015
New Revision: 3040
Log:
~final pulse fitting
Added:
java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EcalReconPulseFit.lcsim
Modified:
java/trunk/users/src/main/java/org/hps/users/baltzell/Ecal3PoleFunction.java
java/trunk/users/src/main/java/org/hps/users/baltzell/EcalPulseFitter.java
java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter.java
java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver.java
Added: java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EcalReconPulseFit.lcsim
=============================================================================
--- java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EcalReconPulseFit.lcsim (added)
+++ java/trunk/steering-files/src/main/resources/org/hps/steering/users/baltzell/EcalReconPulseFit.lcsim Wed May 27 14:10:48 2015
@@ -0,0 +1,52 @@
+<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="EcalRunningPedestal"/>
+ <driver name="EcalRawConverter" />
+ <driver name="ReconClusterer" />
+ <driver name="LCIOWriter" />
+ <!--<driver name="AidaSaveDriver" />-->
+ <driver name="CleanupDriver" />
+ </execute>
+ <drivers>
+ <driver name="EcalRunningPedestal" type="org.hps.recon.ecal.EcalRunningPedestalDriver">
+ <minLookbackEvents>10</minLookbackEvents>
+ <maxLookbackEvents>50</maxLookbackEvents>
+ </driver>
+ <driver name="EcalRawConverter" type="org.hps.users.baltzell.EcalRawConverterDriver">
+ <ecalCollectionName>EcalCalHits</ecalCollectionName>
+ <use2014Gain>false</use2014Gain>
+ <useTimestamps>false</useTimestamps>
+ <useTruthTime>false</useTruthTime>
+ <useRunningPedestal>true</useRunningPedestal>
+ <useTimeWalkCorrection>false</useTimeWalkCorrection>
+ <emulateFirmware>true</emulateFirmware>
+ <emulateMode7>true</emulateMode7>
+ <leadingEdgeThreshold>12</leadingEdgeThreshold>
+ <nsa>20</nsa>
+ <nsb>100</nsb>
+ <useFit>true</useFit>
+ <fixShapeParameter>true</fixShapeParameter>
+ <debug>0</debug>
+ <!--<fitFileName>ecalPulseFits.txt</fitFileName>-->
+ </driver>
+ <driver name="ReconClusterer" type="org.hps.recon.ecal.cluster.ReconClusterDriver">
+ <logLevel>WARNING</logLevel>
+ <outputClusterCollectionName>EcalClusters</outputClusterCollectionName>
+ <hitEnergyThreshold>0.01</hitEnergyThreshold>
+ <seedEnergyThreshold>0.050</seedEnergyThreshold>
+ <clusterEnergyThreshold>0.100</clusterEnergyThreshold>
+ <minTime>0.0</minTime>
+ <timeWindow>25.0</timeWindow>
+ <useTimeCut>true</useTimeCut>
+ <writeRejectedHitCollection>false</writeRejectedHitCollection>
+ </driver>
+ <driver name="LCIOWriter" type="org.lcsim.util.loop.LCIODriver">
+ <outputFilePath>${outputFile}.slcio</outputFilePath>
+ </driver>
+ <driver name="AidaSaveDriver" type="org.lcsim.job.AidaSaveDriver">
+ <outputFileName>ecalPulseFits.root</outputFileName>
+ </driver>
+ <driver name="CleanupDriver" type="org.lcsim.recon.tracking.digitization.sisim.config.ReadoutCleanupDriver" />
+ </drivers>
+</lcsim>
Modified: java/trunk/users/src/main/java/org/hps/users/baltzell/Ecal3PoleFunction.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/Ecal3PoleFunction.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/Ecal3PoleFunction.java Wed May 27 14:10:48 2015
@@ -2,9 +2,17 @@
import hep.aida.ref.function.AbstractIFunction;
+/*
+ *
+ * "3-Pole Function:" x**2 * exp(-x/tau)
+ *
+ * Here x is time, and we have pedestal and time offsets, and it's normalized:
+ * PEDESTAL + INTEGRAL / WIDTH^3 / 2 * (TIME-TIME0)**2 * exp(-(TIME-TIME0)/WIDTH)
+ *
+ */
public class Ecal3PoleFunction extends AbstractIFunction {
-
+
protected double pedestal=0;
protected double time0=0;
protected double integral=0;
@@ -21,8 +29,9 @@
init(title);
}
- void setDebug(boolean debug) { this.debug=debug; }
-
+ public void setDebug(boolean debug) { this.debug=debug; }
+ public double maximum() { return value(new double[]{time0+2*width}); }
+
@Override
public double value(double[] v) {
final double time = v[0];
@@ -36,20 +45,20 @@
@Override
public void setParameters(double[] pars) throws IllegalArgumentException {
super.setParameters(pars);
- pedestal=pars[0];
- time0=pars[1];
- integral=pars[2];
- width=pars[3];
+ pedestal = pars[0];
+ time0 = pars[1];
+ integral = pars[2];
+ width = pars[3];
if (debug) System.err.println(String.format("%8.2f %8.2f %8.2f %8.2f",pars[0],pars[1],pars[2],pars[3]));
}
@Override
public void setParameter(String key,double value) throws IllegalArgumentException{
super.setParameter(key,value);
- if (key.equals("pedestal")) pedestal=value;
- else if (key.equals("time0")) time0=value;
- else if (key.equals("integral")) integral=value;
- else if (key.equals("width")) width=value;
+ if (key.equals("pedestal")) pedestal = value;
+ else if (key.equals("time0")) time0 = value;
+ else if (key.equals("integral")) integral = value;
+ else if (key.equals("width")) width = value;
}
}
Modified: java/trunk/users/src/main/java/org/hps/users/baltzell/EcalPulseFitter.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/EcalPulseFitter.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/EcalPulseFitter.java Wed May 27 14:10:48 2015
@@ -13,34 +13,110 @@
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.hps.conditions.database.DatabaseConditionsManager;
+import org.hps.conditions.ecal.EcalChannelConstants;
+import org.hps.conditions.ecal.EcalConditions;
+import org.lcsim.event.RawTrackerHit;
+import org.lcsim.geometry.Detector;
import org.lcsim.util.aida.AIDA;
public class EcalPulseFitter {
+
+ public int debug = 0;
+ public String fitFileName = null;
+ public boolean fixShapeParameter = true;
+
+ private final static int nsPerSample=4;
+ private final boolean doTimeFit = false;
+ private FileWriter fitFileWriter = null;
+ private EcalConditions ecalConditions = null;
+
+ // don't bother fitting pulses with threshold crossing outside this sample range:
+ private final static int threshRange[]={7,18}; // (28 ns <--> 72 ns)
+
+ // fit sample range relative to threshold crossing:
+ private final static int fitRange[]={-10,15};
+
+ // sample range relative to threshold crossing used to initialize pedestal fit parameter:
+ private final static int pedRange[]={-10,-5};
+
+ private final static double threePoleWidths[]={
+ 2.44057,2.40057,2.53389,2.32095,2.44267,2.43631,2.40292,2.46911,2.36032,2.42132,2.41473,2.43864,2.37710,2.43278,2.49126,2.41739,2.40560,
+ 2.42042,2.51278,2.46731,2.42647,2.35636,2.55308,2.47517,2.38748,2.48324,2.53726,2.54780,2.50771,2.45188,2.35011,2.35110,2.37575,2.37649,
+ 2.41037,2.38817,2.52422,2.47389,2.40672,2.59415,2.35626,2.44359,2.54118,2.42893,2.43100,2.32748,2.34831,2.30641,2.40003,2.38997,2.41643,
+ 2.45717,2.44830,2.48149,2.44339,2.33572,2.42276,2.43731,2.44205,2.37290,2.54975,2.44517,2.39132,2.48821,2.45687,2.39768,2.61674,2.52142,
+ 2.46620,2.46802,2.54764,2.45238,2.48421,2.44521,2.47204,2.50415,2.47346,2.51053,2.44811,2.54895,2.44839,2.51419,2.45706,2.38596,2.46743,
+ 2.49971,2.37904,2.46478,2.43015,2.52088,2.55846,2.50522,2.30973,2.41450,2.40907,2.31343,2.48668,2.46800,2.43559,2.42113,2.47494,2.36971,
+ 2.44022,2.44193,2.42661,2.41918,2.41102,2.51565,2.34875,2.36750,2.37355,2.48763,2.36659,2.42424,2.44321,2.46651,2.52053,2.46172,2.41316,
+ 2.41670,2.41661,2.53472,2.49345,2.46496,2.40006,2.41084,2.44442,2.49113,2.42821,2.56839,2.45630,2.46344,2.42585,2.43730,2.44339,2.44315,
+ 2.48069,2.39892,2.36987,2.40482,2.40103,2.36307,2.46118,2.47136,2.39327,2.46267,2.30668,2.45917,2.46903,2.51727,2.27056,2.46365,2.35228,
+ 2.52188,2.44052,2.41457,2.25591,2.51210,2.43585,2.57410,2.46877,2.37902,2.46975,2.45628,2.44264,2.36588,2.48233,2.46351,2.37512,2.44228,
+ 2.52664,2.51927,2.37348,2.52284,2.52505,2.55755,2.51522,2.44848,2.51430,2.41387,2.42311,2.42880,2.46546,2.40000,2.45992,2.46841,2.43101,
+ 2.22369,2.43262,2.41324,2.45465,2.40752,2.50491,2.45191,2.40109,2.49099,2.37011,2.70111,2.46843,2.44336,2.44675,2.42308,2.51800,2.45660,
+ 2.43406,2.43297,2.37133,2.50718,2.43035,2.42818,2.47709,2.40578,2.39228,2.47350,2.51876,2.39584,2.44114,2.49120,2.48185,2.59246,2.41612,
+ 2.42914,2.51496,2.38785,2.53339,2.30056,2.25807,2.40500,2.53300,2.37439,2.48418,2.33764,2.47934,2.33080,2.48834,2.48318,2.42860,2.28253,
+ 2.44013,2.38272,2.23632,2.37630,2.34564,2.34538,2.44281,2.33952,2.33574,2.40939,2.44992,2.43986,2.45022,2.39336,2.43253,2.38136,2.41941,
+ 2.56685,2.54684,2.43060,2.33258,2.43024,2.48895,2.51698,2.38837,2.45276,2.38518,2.35826,2.38321,2.31616,2.46480,2.53753,2.28027,2.50727,
+ 2.35369,2.29179,2.06776,2.49429,2.35639,2.42628,2.55657,2.51859,2.49579,2.45617,2.41293,2.47083,2.51653,2.47478,2.46354,2.48828,2.34846,
+ 2.34419,2.43172,2.46589,2.45462,2.52146,2.35946,2.38810,2.46027,2.53848,2.48102,2.42701,2.51750,2.57911,2.45136,2.48329,2.39329,2.48209,
+ 2.35948,2.49431,2.36117,2.26121,2.40899,2.51383,2.41642,2.52102,2.39702,2.43949,2.40867,2.38560,2.46874,2.22937,2.40741,2.36007,2.38784,
+ 2.41052,2.42673,2.39476,2.40239,2.46902,2.55278,2.44661,2.54734,2.41863,2.42451,2.40056,2.44307,2.35066,2.46254,2.43270,2.50439,2.49733,
+ 2.55563,2.48589,2.45219,2.44774,2.41116,2.49081,2.43893,2.43731,2.55774,2.42404,2.37911,2.45140,2.47196,2.50533,2.38292,2.47868,2.48262,
+ 2.39845,2.42290,2.54415,2.43109,2.54306,2.49385,2.35113,2.43233,2.50552,2.49532,2.42667,2.53772,2.41398,2.41968,2.59536,2.52077,2.42026,
+ 2.51269,2.42584,2.54930,2.63547,2.42869,2.43348,2.42402,2.38768,2.41903,2.50153,2.45315,2.45472,2.41113,2.44795,2.50849,2.41817,2.44166,
+ 2.61143,2.38567,2.40737,2.39843,2.43711,2.35324,2.48315,2.38388,2.45665,2.30220,2.41293,2.36640,2.38185,2.40913,2.49233,2.46818,2.51527,
+ 2.54177,2.37051,2.37318,2.38405,2.53258,2.58176,2.53786,2.52385,2.40308,2.45279,2.39370,2.50056,2.41076,2.40789,2.47444,2.52857,2.40741,
+ 2.38524,2.39403,2.42442,2.56829,2.56063,2.58340,2.42897,2.58796,2.56262,2.53480,2.43707,2.38258,2.46584,2.40596,2.42590,2.48281,2.47800
+ };
AIDA aida = AIDA.defaultInstance();
IAnalysisFactory analysisFactory = aida.analysisFactory();
IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null);
IFitFactory fitFactory = analysisFactory.createFitFactory();
IFitter fitter=fitFactory.createFitter();
- IFunction fitFunction=new Ecal3PoleFunction();
+ IFunction fitFcn3Pole=new Ecal3PoleFunction();
+ IFunction fitFcnLinear=functionFactory.createFunctionFromScript("fitFcnLinear",1,"p0+x[0]*p1","p0,p1","",null);
IDataPointSet fitData=aida.analysisFactory().createDataPointSetFactory(null).create("ADC DataPointSet", 2);
- private final int nsPerSample=4;
- public int debug = 0;
- public String fitFileName = null;
- public FileWriter fitFileWriter = null;
- public boolean fixShapeParameter = false;
- final private double threePoleWidth=2.478;
-
-
- public IFitResult fitPulse(short samples[],int threshCross,double maxADC,double noise) {
+ public IFitResult fitLeadingEdge(RawTrackerHit hit,int threshCross) {
+
+ final short samples[] = hit.getADCValues();
+ final double noise = findChannel(hit.getCellID()).getCalibration().getNoise();
+
+ int imaxADC=0;
+ for (int ii=threshCross; ii<samples.length-1; ii++)
+ {
+ if (ii<0) continue;
+ if (ii>=samples.length) break;
+ if (samples[ii+1] < samples[ii]) {
+ imaxADC=ii;
+ break;
+ }
+ }
+ fitData.clear();
+ int nFitPoints=0;
+ for (int ii=threshCross-1; ii<imaxADC-1; ii++) {
+ fitData.addPoint();
+ fitData.point(nFitPoints).coordinate(0).setValue(ii);
+ fitData.point(nFitPoints).coordinate(1).setValue(samples[ii]);
+ fitData.point(nFitPoints).coordinate(1).setErrorMinus(noise);
+ fitData.point(nFitPoints).coordinate(1).setErrorPlus(noise);
+ nFitPoints++;
+ }
+
+ if (nFitPoints<2) return null;
+
+ return fitter.fit(fitData,fitFcnLinear);
+ }
+
+ public IFitResult[] fitPulse(RawTrackerHit hit,int threshCross,double maxADC) {
if (debug>0) System.err.println("FITTING.....................................................");
- final int threshRange[]={6,25};
- final int fitRange[]={-10,15};
- final int pedRange[]={-10,-5};
-
+ final short samples[] = hit.getADCValues();
+ final double noise = findChannel(hit.getCellID()).getCalibration().getNoise();
+ final int cid = ecalConditions.getChannelCollection().findGeometric(hit.getCellID()).getChannelId();
+
// don't bother with pulses far from trigger:
if (threshCross < threshRange[0] || threshCross > threshRange[1]) return null;
@@ -62,6 +138,7 @@
// choose points to fit and get starting value for pulse integral:
fitData.clear();
int nFitPoints=0;
+ int iPeakADC=-1;
int sumADC=0;
// int maxADC=0;
for (int ii=threshCross+fitRange[0]; ii<threshCross+fitRange[1]; ii++)
@@ -70,6 +147,9 @@
if (ii>=samples.length) break;
if (debug>0) System.err.print(ii+":"+samples[ii]+" ");
// if (samples[ii] > maxADC) maxADC=samples[ii];
+ if (iPeakADC<0 && ii<samples.length-1 && samples[ii+1] < samples[ii]) {
+ iPeakADC=ii;
+ }
sumADC += samples[ii];
fitData.addPoint();
fitData.point(nFitPoints).coordinate(0).setValue(ii);
@@ -89,28 +169,29 @@
final double pulseIntegral = sumADC-ped*nFitPoints;
// initialize parameters:
- fitFunction.setParameter("pedestal",ped);
- fitFunction.setParameter("time0",(double)threshCross-2);
- fitFunction.setParameter("integral",pulseIntegral>0 ? pulseIntegral : 2);
- fitFunction.setParameter("width",threePoleWidth);
+ fitFcn3Pole.setParameter("pedestal",ped);
+ fitFcn3Pole.setParameter("time0",(double)threshCross-2);
+ fitFcn3Pole.setParameter("integral",pulseIntegral>0 ? pulseIntegral : 2);
+ fitFcn3Pole.setParameter("width",threePoleWidths[cid-1]);
// constrain parameters:
fitter.fitParameterSettings("integral").setBounds(0,999999);
fitter.fitParameterSettings("time0").setBounds(1,30);
+// fitter.fitParameterSettings("time0").setBounds(threshRange[0]-5,threshRange[1]+20);
fitter.fitParameterSettings("width").setBounds(0.1,5);
if (fixShapeParameter) fitter.fitParameterSettings("width").setFixed(true);
- ((Ecal3PoleFunction)fitFunction).setDebug(debug>1);
+ ((Ecal3PoleFunction)fitFcn3Pole).setDebug(debug>1);
if (debug>0) {
- System.err.println(String.format("A= %8.2f",fitFunction.parameter("integral")));
- System.err.println(String.format("T= %8.2f",fitFunction.parameter("time0")*4));
- System.err.println(String.format("P= %8.2f",fitFunction.parameter("pedestal")));
- System.err.println(String.format("S= %8.2f",fitFunction.parameter("width")));
+ System.err.println(String.format("A= %8.2f",fitFcn3Pole.parameter("integral")));
+ System.err.println(String.format("T= %8.2f",fitFcn3Pole.parameter("time0")*4));
+ System.err.println(String.format("P= %8.2f",fitFcn3Pole.parameter("pedestal")));
+ System.err.println(String.format("S= %8.2f",fitFcn3Pole.parameter("width")));
} else Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
- IFitResult fitResult = fitter.fit(fitData,fitFunction);
- writeFit(samples,fitResult);
+ IFitResult fitResult = fitter.fit(fitData,fitFcn3Pole);
+ writeFit(samples,fitResult,cid);
if (debug>0) {
final double P = fitResult.fittedParameter("pedestal");
@@ -119,22 +200,31 @@
final double S = fitResult.fittedParameter("width");
final double Q = fitResult.quality();
final double E[] = fitResult.errors();
-
- if (debug>0) {
- System.err.println(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
- System.err.println(String.format("I = %8.2f %8.2f",I,sumADC-P*30));
- System.err.println(String.format("T = %8.2f %8.2f",T,threshCross));
- System.err.println(String.format("P = %8.2f %8.2f",P,ped));
- System.err.println(String.format("S = %8.2f %8.2f",S,threePoleWidth));
- System.err.println(String.format("M = %8.2f",maxADC-P));
+ System.err.println(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
+ System.err.println(String.format("I = %8.2f %8.2f",I,sumADC-P*30));
+ System.err.println(String.format("T = %8.2f %8.2f",T,threshCross));
+ System.err.println(String.format("P = %8.2f %8.2f",P,ped));
+ System.err.println(String.format("S = %8.2f %8.2f",S,threePoleWidths[cid-1]));
+ System.err.println(String.format("M = %8.2f",maxADC-P));
+ System.err.println(String.format("Q = %8.2f",Q));
+ }
+
+ // now fit just leading edge:
+ IFitResult timeResult = null;
+ if (doTimeFit) {
+ for (int ii=fitData.size()-1; ii>=0; ii--) {
+ if (fitData.point(ii).coordinate(0).value() > iPeakADC+1) fitData.removePoint(ii);
+ else break;
}
- }
-
- return fitResult;
- }
-
-
- public void writeFit(short samples[],IFitResult fit) {
+ fitter.fit(fitData,fitFcn3Pole);
+ }
+
+ IFitResult fitResults[] = {fitResult,timeResult};
+ return fitResults;
+ }
+
+
+ public void writeFit(short samples[],IFitResult fit,final int cid) {
if (fitFileName == null) return;
if (fitFileWriter == null) {
try { fitFileWriter=new FileWriter(fitFileName); }
@@ -147,10 +237,31 @@
fitFileWriter.write(String.format("%8.3f",fit.fittedParameter("pedestal")));
fitFileWriter.write(String.format("%8.3f",fit.fittedParameter("width")));
fitFileWriter.write(String.format("%8.3f",fit.quality()));
+ fitFileWriter.write(String.format("%4d",cid));
fitFileWriter.write("\n");
} catch (IOException ee) {
throw new RuntimeException("Error writing file "+fitFileName,ee);
}
}
-
-}
+
+ public double getSmartPedestal(short samples[]) {
+ double ped = 99999;
+ final int nSamples = 6;
+ for (int ii=0; ii<samples.length-nSamples; ii++) {
+ double aped = 0;
+ for (int jj=ii; jj<ii+nSamples; jj++) aped += samples[jj];
+ aped /= nSamples;
+ if (aped < ped) ped = aped;
+ }
+ return ped;
+ }
+ public void setDetector(Detector detector) {
+ // ECAL combined conditions object.
+ ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions();
+ }
+ public EcalChannelConstants findChannel(long cellID) {
+ return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
+ }
+
+
+}
Modified: java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverter.java Wed May 27 14:10:48 2015
@@ -1,20 +1,12 @@
package org.hps.users.baltzell;
-import org.hps.users.baltzell.Ecal3PoleFunction;
-
-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.IHistogram1D;
+//import hep.aida.IHistogram2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
@@ -49,7 +41,9 @@
* @author Nathan Baltzell <[log in to unmask]>
* @author Holly Szumila <[log in to unmask]>
*
- * baltzell: New in 2015: (default behavior is still unchanged)
+ * baltzell: New in May, 2015: Pulse Fitting.
+ *
+ * baltzell: New in Early-2015: (default behavior is still unchanged)
*
* Implemented conversion of Mode-1 to Mode-3.
*
@@ -67,18 +61,22 @@
*/
public class EcalRawConverter {
-
- // wtf.
+ EcalPulseFitter pulseFitter = new EcalPulseFitter();
+
+ /*
AIDA aida = AIDA.defaultInstance();
- IAnalysisFactory analysisFactory = aida.analysisFactory();
- IFunctionFactory functionFactory = analysisFactory.createFunctionFactory(null);
- IFitFactory fitFactory = analysisFactory.createFitFactory();
- IFitter fitter=fitFactory.createFitter();
- IFunction fitFunction=new Ecal3PoleFunction();
- IDataPointSet data=aida.analysisFactory().createDataPointSetFactory(null).create("ADC DataPointSet", 2);
-
- IHistogram1D hWidth = aida.histogram1D("hShape",500,0,5);
- IHistogram1D hQuality = aida.histogram1D("hChiSquare",500,0,5);
+ IHistogram1D hWidth = aida.histogram1D("hWidth",500,0,5);
+ IHistogram2D hWidthE = aida.histogram2D("hWidthE",500,0,5,100,0,5000.0);
+ IHistogram1D hChiSquare = aida.histogram1D("hChiSquare",500,0,5);
+ IHistogram2D hWidthChan = aida.histogram2D("hWidthChan",500,0,5,442,0.5,442.5);
+ IHistogram2D hSamplesChanW = aida.histogram2D("hSamplesChanW",442,0.5,442.5,50,-0.5,49.5);
+ IHistogram2D hSamplesChan = aida.histogram2D("hSamplesChan",442,0.5,442.5,50,-0.5,49.5);
+ IHistogram2D hSamplesChanLoW = aida.histogram2D("hSamplesChanLoW",442,0.5,442.5,50,-0.5,49.5);
+ IHistogram2D hSamplesChanLo = aida.histogram2D("hSamplesChanLo",442,0.5,442.5,50,-0.5,49.5);
+ IHistogram2D hSamplesChanHiW = aida.histogram2D("hSamplesChanHiW",442,0.5,442.5,50,-0.5,49.5);
+ IHistogram2D hSamplesChanHi = aida.histogram2D("hSamplesChanHi",442,0.5,442.5,50,-0.5,49.5);
+ IHistogram2D hWidthEnergy153 = aida.histogram2D("hWidthEnergy153",500,0,5,500,0,5000);
+ */
private boolean useTimeWalkCorrection = false;
private boolean useRunningPedestal = false;
@@ -93,6 +91,11 @@
public String fitFileName = null;
public FileWriter fitFileWriter = null;
public boolean fixShapeParameter = false;
+ //final private double threePoleWidth=2.478;
+
+ public void setUseFit(boolean useFit) { this.useFit=useFit; }
+ public void setFitFileName(String name) { pulseFitter.fitFileName=name; }
+ public void setFixShapeParameter(boolean fix) { pulseFitter.fixShapeParameter=fix; }
/*
* The time for one FADC sample (units = ns).
@@ -322,89 +325,6 @@
return (lastSample-firstSample+1)*getSingleSamplePedestal(event,cellID);
}
- public IFitResult fitPulse(short samples[],int thresholdCrossing,double maxADC,double noise) {
-
- if (thresholdCrossing < 9 || thresholdCrossing > 15) return null;
-
- if (debug>0) System.err.println("FITTING.....................................................");
-
- data.clear();
- int nped=0;
- double ped=0;
- for (int ii=thresholdCrossing-9; ii<thresholdCrossing-5; ii++) {
- if (ii<0 || ii>=samples.length) break;
- ped += samples[ii];
- nped++;
- }
- ped /= nped;
- if (nped==0) return null;
- int npts=0;
- int sumADC=0;
- for (int ii=thresholdCrossing-10; ii<thresholdCrossing+15; ii++) {
- if (ii<0) continue;
- if (ii>=samples.length) break;
- if (debug>0) System.err.print(ii+":"+samples[ii]+" ");
- data.addPoint();
- data.point(npts).coordinate(0).setValue(ii);
- data.point(npts).coordinate(1).setValue(samples[ii]);
- data.point(npts).coordinate(1).setErrorMinus(noise);
- data.point(npts).coordinate(1).setErrorPlus(noise);
- sumADC += samples[ii];
- npts++;
- }
- if (debug>0) System.err.print("\n");
- if (npts>=10) {
- if (debug>0) System.err.println("------- "+ped+" "+thresholdCrossing+" "+maxADC);
- if (maxADC-ped < 0) return null;
- final double pulseIntegral = sumADC-ped*npts;
- fitFunction.setParameter("pedestal",ped);
- fitFunction.setParameter("time0",(double)thresholdCrossing-2);
- fitFunction.setParameter("integral",pulseIntegral>0?pulseIntegral:10);
- fitFunction.setParameter("width",2.478);
- ((Ecal3PoleFunction)fitFunction).setDebug(debug>1);
-
- if (debug>0) {
- System.err.println(String.format("A= %8.2f",fitFunction.parameter("integral")));
- System.err.println(String.format("T= %8.2f",fitFunction.parameter("time0")*4));
- System.err.println(String.format("P= %8.2f",fitFunction.parameter("pedestal")));
- System.err.println(String.format("S= %8.2f",fitFunction.parameter("width")));
- }
-
- fitter.fitParameterSettings("integral").setBounds(0,999999);
- fitter.fitParameterSettings("time0").setBounds(5,40);
- fitter.fitParameterSettings("width").setBounds(0.1,5);
- if (fixShapeParameter) fitter.fitParameterSettings("width").setFixed(true);
-
- if (debug<1) Logger.getLogger("org.freehep.math.minuit").setLevel(Level.OFF);
- IFitResult fitResult = fitter.fit(data,fitFunction);
- writeFit(samples,fitResult);
- return fitResult;
- }
- return null;
- }
-
- public void writeFit(short samples[],IFitResult fit) {
- if (fitFileName == null) return;
- if (fitFileWriter == null) {
- try { fitFileWriter=new FileWriter(fitFileName); }
- catch (IOException ee) { throw new RuntimeException("Error opening file "+fitFileName,ee); }
- }
-
- try {
- for (final short ss : samples) fitFileWriter.write(String.format("%6d ",ss));
- fitFileWriter.write(String.format("%8.3f",fit.fittedParameter("integral")));
- fitFileWriter.write(String.format("%8.3f",fit.fittedParameter("time0")));
- fitFileWriter.write(String.format("%8.3f",fit.fittedParameter("pedestal")));
- fitFileWriter.write(String.format("%8.3f",fit.fittedParameter("width")));
- fitFileWriter.write(String.format("%8.3f",fit.quality()));
- fitFileWriter.write("\n");
- } catch (IOException ee) {
- throw new RuntimeException("Error writing file "+fitFileName,ee);
- }
- }
-
-
-
/*
* Emulate the FADC250 firmware in conversion of Mode-1 waveform to a Mode-3/7 pulse,
* given a time for threshold crossing.
@@ -490,9 +410,13 @@
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
+ final double yint = a1 - slope * t1; // units = ADC
+
+ // mode-7 time, time at half max:
pulseTime = ((halfMax - a0)/(a1-a0) + t0)* nsPerSample;
-
+
+ // mode-8 time, time at pedestal intersection:
+ //pulseTime = (minADC-yint)/slope * nsPerSample;
}
}
@@ -500,40 +424,50 @@
if (useFit)
{
- final double noise=findChannel(hit.getCellID()).getCalibration().getNoise();
- IFitResult fitResult=fitPulse(samples,thresholdCrossing,maxADC,noise);
-
- if (fitResult != null) {
-
- final double P=fitResult.fittedParameter("pedestal");
- final double A=fitResult.fittedParameter("integral");
- final double T=fitResult.fittedParameter("time0");
- final double S=fitResult.fittedParameter("width");
- final double Q=fitResult.quality();
-
- // finite integral from T to T+NSAMP:
- //final int NSAMP=30;
- //final double I = (A/2/S) * S*S*S* ( 2 - Math.exp(-NSAMP/S) * (Math.pow((S+NSAMP)/S,2) + 1));
-
- // infinite integral:
- //final double I = A*S*S;
+ IFitResult fitResults[] = pulseFitter.fitPulse(hit,thresholdCrossing,maxADC);
+ if (fitResults!=null && fitResults[0]!=null) {
- // after normalizing the function:
- final double I = A;
+ IFitResult fitResult=fitResults[0];
+ IFitResult timeResult=fitResults[1]==null?fitResults[0]:fitResults[1];
+
+ pulseTime = timeResult.fittedParameter("time0")*nsPerSample;
+ sumADC = fitResult.fittedParameter("integral");
+ minADC = fitResult.fittedParameter("pedestal");
+ maxADC = ((Ecal3PoleFunction)fitResult.fittedFunction()).maximum();
- if (debug>0) {
- System.err.println(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
- System.err.println(String.format("A= %8.2f %8.2f",I,sumADC-P*30));
- System.err.println(String.format("T= %8.2f %8.2f",T*4,pulseTime));
- System.err.println(String.format("P= %8.2f %8.2f",P,minADC));
- System.err.println(String.format("S= %8.2f",S));
- System.err.println(String.format("M= %8.2f %8.2f",A,(maxADC-P)));
- }
-
- hWidth.fill(S);
- hQuality.fill(Q);
- pulseTime = T*4;
- sumADC = I;
+ /*
+ final double width = fitResult.fittedParameter("width");
+ //final double E[] = fitResult.errors();
+ final int cid = getChannelId(hit.getCellID());
+ hWidth.fill(width);
+ hWidthE.fill(width,fitResult.fittedParameter("integral"));
+ if (cid==153) hWidthEnergy153.fill(width,fitResult.fittedParameter("integral"));
+ hChiSquare.fill(fitResult.quality());
+ hWidthChan.fill(width,cid);
+ for (int ii=0; ii<samples.length; ii++) {
+ hSamplesChan.fill(cid,ii);
+ hSamplesChanW.fill(cid,ii,samples[ii]);
+ if (fitResult.fittedParameter("integral") > 2000)
+ {
+ hSamplesChanHi.fill(cid,ii);
+ hSamplesChanHiW.fill(cid,ii,samples[ii]);
+ }
+ else if (fitResult.fittedParameter("integral") < 1000)
+ {
+ hSamplesChanLo.fill(cid,ii);
+ hSamplesChanLoW.fill(cid,ii,samples[ii]);
+ }
+ }
+ */
+
+ /*
+ timeResult = pulseFitter.fitLeadingEdge(hit,thresholdCrossing);
+ if (timeResult != null) {
+ final double p0 = timeResult.fittedParameter("p0");
+ final double p1 = timeResult.fittedParameter("p1");
+ pulseTime = (minADC-p0)/p1 * nsPerSample;
+ }
+ */
}
}
return new double []{pulseTime,sumADC,minADC,maxADC};
@@ -711,6 +645,8 @@
public void setDetector(Detector detector) {
// ECAL combined conditions object.
ecalConditions = DatabaseConditionsManager.getInstance().getEcalConditions();
+
+ pulseFitter.setDetector(detector);
}
/**
@@ -723,4 +659,8 @@
return ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
}
+ public int getChannelId(long cellID) {
+ return ecalConditions.getChannelCollection().findGeometric(cellID).getChannelId();
+ }
+
}
Modified: java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver.java
=============================================================================
--- java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver.java (original)
+++ java/trunk/users/src/main/java/org/hps/users/baltzell/EcalRawConverterDriver.java Wed May 27 14:10:48 2015
@@ -57,9 +57,9 @@
converter = new EcalRawConverter();
}
- public void setUseFit(boolean useFit) { converter.useFit=useFit; }
- public void setFitFileName(String name) { converter.fitFileName=name; }
- public void setFixShapeParameter(boolean fix) { converter.fixShapeParameter=fix; }
+ public void setUseFit(boolean useFit) { converter.setUseFit(useFit); }
+ public void setFitFileName(String name) { converter.setFitFileName(name); }
+ public void setFixShapeParameter(boolean fix) { converter.setFixShapeParameter(fix); }
/**
|