diff --git a/bin/environ.sh b/bin/environ.sh index 2c72d98f..0ad4b06b 100644 --- a/bin/environ.sh +++ b/bin/environ.sh @@ -42,8 +42,12 @@ timeline_groovy_opts=( -Djava.awt.headless=true ) +# run java with more resources, to mitigate large memory residence for long run periods +timeline_java_opts_highmem=$(echo ${timeline_java_opts[*]} | sed 's;Xmx.*m;Xmx2048m;') + # exports export CLASSPATH="$(echo "${java_classpath[*]}" | sed 's; ;:;g')${CLASSPATH:+:${CLASSPATH}}" export JYPATH="$(echo "${groovy_classpath[*]}" | sed 's; ;:;g')${JYPATH:+:${JYPATH}}" export TIMELINE_JAVA_OPTS="${timeline_java_opts[*]}" export TIMELINE_GROOVY_OPTS="${timeline_groovy_opts[*]}" +export TIMELINE_JAVA_OPTS_HIGHMEM=$timeline_java_opts_highmem diff --git a/detectors/src/main/java/org/jlab/clas/timeline/fitter/FTOFFitter.groovy b/detectors/src/main/java/org/jlab/clas/timeline/fitter/FTOFFitter.groovy index e7326b6f..d4138b98 100644 --- a/detectors/src/main/java/org/jlab/clas/timeline/fitter/FTOFFitter.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/fitter/FTOFFitter.groovy @@ -31,33 +31,33 @@ class FTOFFitter { return f1 } - static F1D timefit_p2(H1F h1) { - def f1 = new F1D("fit:"+h1.getName(), "[amp]*gaus(x,[mean],[sigma])", -0.5, 0.5); - double hAmp = h1.getBinContent(h1.getMaximumBin()); - double hMean = h1.getAxis().getBinCenter(h1.getMaximumBin()); - double hRMS = 0.3;//h1.getRMS(); //ns - double rangeMin = (hMean - 2.5*hRMS); - double rangeMax = (hMean + 2.5*hRMS); - f1.setRange(rangeMin, rangeMax); - f1.setParameter(0, hAmp); - f1.setParameter(1, hMean); - f1.setParameter(2, hRMS); - - def makefit = {func-> - hMean = func.getParameter(1) - hRMS = func.getParameter(2).abs() - func.setRange(hMean-1.5*hRMS,hMean+1.5*hRMS) - MoreFitter.fit(func,h1,"Q") - return [func.getChiSquare(), (0.. + hMean = func.getParameter(1) + hRMS = func.getParameter(2).abs() + func.setRange(hMean-1.5*hRMS,hMean+1.5*hRMS) + MoreFitter.fit(func,h1,"Q") + return [func.getChiSquare(), (0.. hMean = func.getParameter(1) hRMS = func.getParameter(2).abs() @@ -88,6 +87,7 @@ class FTOFFitter { return f1 } + static F1D tdcadcdifffit_p1b(H1F h1) { def f1 = new F1D("fit:"+h1.getName(), "[amp]*gaus(x,[mean],[sigma])", -1.0, 1.0); double hAmp = h1.getBinContent(h1.getMaximumBin()); @@ -120,19 +120,18 @@ class FTOFFitter { def f1 = new F1D("fit:"+h1.getName(), "[amp]*gaus(x,[mean],[sigma])", -1.0, 1.0); double hAmp = h1.getBinContent(h1.getMaximumBin()); double hMean = h1.getAxis().getBinCenter(h1.getMaximumBin()); - double hRMS = h1.getRMS(); //ns - double rangeMin = (hMean - 2.5*hRMS); - double rangeMax = (hMean + hRMS); + double hRMS = 1.9//h1.getRMS(); //ns + double rangeMin = (hMean - 1.5*hRMS); + double rangeMax = (hMean + 1.5*hRMS); f1.setRange(rangeMin, rangeMax); f1.setParameter(0, hAmp); f1.setParameter(1, hMean); f1.setParameter(2, hRMS); - def makefit = {func-> hMean = func.getParameter(1) hRMS = func.getParameter(2).abs() - func.setRange(hMean - 1.5*hRMS, hMean + 1.5*hRMS) + func.setRange(hMean-1.5*hRMS,hMean+1.5*hRMS) MoreFitter.fit(func,h1,"Q") return [func.getChiSquare(), (0.. - f1.setParameters(amp,mu,sig) - def rng = [mu-2.5*sig, mu+2.5*sig] - f1.setRange(*rng) - DataFitter.fit(f1,h1,"Q") - (amp,mu,sig) = (0..x2 || sig>(x2-x1)) return null - return [f1.getChiSquare(), [amp,mu,sig], rng] - } - - def fits = [norms,mus,sigs].combinations().findResults{makefit(it)} - fits += fits.findResults{makefit(it[1])} - - def best = fits.min{it[0]} ?: [0, [0,x1,x2-x1], [x1,x2]] - f1.setParameters(*best[1]) - f1.setRange(*best[2]) - return f1 - } - static F1D fitgaus(H1F h1) { def f1 = new F1D('fit:'+h1.getName(), '[amp]*gaus(x,[mean],[sigma])', 0,1) f1.setRange(h1.getDataX(0), h1.getDataX(h1.getDataSize(0)-1)) diff --git a/detectors/src/main/java/org/jlab/clas/timeline/run.groovy b/detectors/src/main/java/org/jlab/clas/timeline/run.groovy index 12daeb91..ec22078b 100644 --- a/detectors/src/main/java/org/jlab/clas/timeline/run.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/run.groovy @@ -100,9 +100,6 @@ def engines = [ new ftof.ftof_tdcadc_p1a(), new ftof.ftof_tdcadc_p1b(), new ftof.ftof_tdcadc_p2(), - // new ftof.ftof_tdcadc_p1a_zoomed(), - // new ftof.ftof_tdcadc_p1b_zoomed(), - // new ftof.ftof_tdcadc_p2_zoomed(), new ftof.ftof_ctof_vtdiff(), new dc.dc_residuals_sec(), new dc.dc_residuals_sec_sl(), diff --git a/detectors/src/main/java/org/jlab/clas/timeline/run_rgb.groovy b/detectors/src/main/java/org/jlab/clas/timeline/run_rgb.groovy index 16dfac0d..0c989730 100644 --- a/detectors/src/main/java/org/jlab/clas/timeline/run_rgb.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/run_rgb.groovy @@ -103,9 +103,6 @@ def engines = [ new ftof.ftof_tdcadc_p1a(), new ftof.ftof_tdcadc_p1b(), new ftof.ftof_tdcadc_p2(), - // new ftof.ftof_tdcadc_p1a_zoomed(), - // new ftof.ftof_tdcadc_p1b_zoomed(), - // new ftof.ftof_tdcadc_p2_zoomed(), new ftof.ftof_ctof_vtdiff(), new dc.dc_residuals_sec(), new dc.dc_residuals_sec_sl(), diff --git a/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/MYQuery.groovy b/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/MYQuery.groovy index 8fdae044..bbca9a93 100755 --- a/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/MYQuery.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/MYQuery.groovy @@ -14,6 +14,7 @@ class MYQuery { 'd': 'on', // data update events only 'p': 'on', // include prior point 'm': 'history', // MYA deployment + 'l': '', // limit by binning (downsample) ] // timestamps diff --git a/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/epics_xy.groovy b/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/epics_xy.groovy index b65bacf7..875c6d16 100755 --- a/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/epics_xy.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/timeline/epics/epics_xy.groovy @@ -3,6 +3,7 @@ package org.jlab.clas.timeline.timeline.epics import java.text.SimpleDateFormat import org.jlab.groot.data.TDirectory import org.jlab.groot.data.H1F +import org.jlab.groot.math.F1D import org.jlab.groot.data.GraphErrors import org.jlab.clas.timeline.fitter.MoreFitter @@ -14,9 +15,49 @@ class epics_xy { runlist.push(run) } + static F1D gausFit(H1F h1) { // FIXME: not stable... + + def f1 = new F1D("fit:"+h1.getName(), "[amp]*gaus(x,[mean],[sigma])", -10, 10); + double hAmp = h1.getBinContent(h1.getMaximumBin()); + double hMean = h1.getAxis().getBinCenter(h1.getMaximumBin()); + double hRMS = Math.min(h1.getRMS(),1.0); + f1.setRange(hMean-2.0*hRMS, hMean+2.0*hRMS); + f1.setParameter(0, hAmp); + f1.setParameter(1, hMean); + f1.setParameter(2, hRMS); + + def makefit = {func-> + hMean = func.getParameter(1) + hRMS = func.getParameter(2).abs() + func.setRange(hMean-2.0*hRMS,hMean+2.0*hRMS) + MoreFitter.fit(func,h1,"Q") + return [func.getChiSquare(), (0..minH && peak - TDirectory out = new TDirectory() - out.mkdir('/timelines') - (0..<6).each{ sec-> - def grtl = new GraphErrors('sec'+(sec+1)) - grtl.setTitle("p1a t_tdc-t_fadc (" + name +")") - grtl.setTitleY("p1a t_tdc-t_fadc (" + name +") (ns)") - grtl.setTitleX("run number") - - data.sort{it.key}.each{run,it-> - if (sec==0){ - out.mkdir('/'+it.run) - } - out.cd('/'+it.run) - out.addDataSet(it.hlist[sec]) - out.addDataSet(it.flist[sec]) - grtl.addPoint(it.run, it[name][sec], 0, 0) - } - out.cd('/timelines') - out.addDataSet(grtl) - } - - out.writeFile('ftof_tdcadc_time_p1a_zoomed_' + name + '.hipo') - } -} -} diff --git a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b.groovy b/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b.groovy index 007ec9d1..7df8f3c3 100644 --- a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b.groovy @@ -3,6 +3,7 @@ import java.util.concurrent.ConcurrentHashMap import org.jlab.groot.data.TDirectory import org.jlab.groot.data.GraphErrors import org.jlab.clas.timeline.fitter.FTOFFitter +import org.jlab.clas.timeline.util.HistoUtil class ftof_tdcadc_p1b { @@ -14,7 +15,7 @@ def processDirectory(dir, run) { def sigmalist = [] def chi2list = [] def histlist = (0..<6).collect{ - def h1 = dir.getObject('/tof/p1b_tdcadc_dt_S'+(it+1)) + def h1 = HistoUtil.zoomHisto(dir.getObject('/tof/p1b_tdcadc_dt_S'+(it+1))) def f1 = FTOFFitter.tdcadcdifffit_p1b(h1) funclist.add(f1) diff --git a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b_zoomed.groovy b/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b_zoomed.groovy deleted file mode 100644 index c57d2fcf..00000000 --- a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p1b_zoomed.groovy +++ /dev/null @@ -1,80 +0,0 @@ -package org.jlab.clas.timeline.timeline.ftof -import java.util.concurrent.ConcurrentHashMap -import org.jlab.groot.data.TDirectory -import org.jlab.groot.data.GraphErrors -import org.jlab.clas.timeline.fitter.FTOFFitter -import org.jlab.groot.data.H1F - -class ftof_tdcadc_p1b_zoomed { - -def data = new ConcurrentHashMap() - -def processDirectory(dir, run) { - def funclist = [] - def meanlist = [] - def sigmalist = [] - def chi2list = [] - def histlist = (0..<6).collect{ - def h1 = dir.getObject('/tof/p1b_tdcadc_dt_S'+(it+1)) - def f1 = FTOFFitter.tdcadcdifffit_p1b(h1) - def peak = f1.getParameter(1) - def sigma = f1.getParameter(2).abs() - def minH = h1.getAxis().min() - def maxH = h1.getAxis().max() - if (peak>minH && peak - TDirectory out = new TDirectory() - out.mkdir('/timelines') - (0..<6).each{ sec-> - def grtl = new GraphErrors('sec'+(sec+1)) - grtl.setTitle("p1b t_tdc-t_fadc (" + name +")") - grtl.setTitleY("p1b t_tdc-t_fadc (" + name +") (ns)") - grtl.setTitleX("run number") - - data.sort{it.key}.each{run,it-> - if (sec==0){ - out.mkdir('/'+it.run) - } - out.cd('/'+it.run) - out.addDataSet(it.hlist[sec]) - out.addDataSet(it.flist[sec]) - grtl.addPoint(it.run, it[name][sec], 0, 0) - } - out.cd('/timelines') - out.addDataSet(grtl) - } - - out.writeFile('ftof_tdcadc_time_p1b_zoomed_' + name + '.hipo') - } -} -} diff --git a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2.groovy b/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2.groovy index 8ad98aa0..0d52cae1 100644 --- a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2.groovy +++ b/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2.groovy @@ -3,6 +3,7 @@ import java.util.concurrent.ConcurrentHashMap import org.jlab.groot.data.TDirectory import org.jlab.groot.data.GraphErrors import org.jlab.clas.timeline.fitter.FTOFFitter +import org.jlab.clas.timeline.util.HistoUtil class ftof_tdcadc_p2 { @@ -14,7 +15,7 @@ def processDirectory(dir, run) { def sigmalist = [] def chi2list = [] def histlist = (0..<6).collect{ - def h1 = dir.getObject('/tof/p2_tdcadc_dt_S'+(it+1)) + def h1 = HistoUtil.zoomHisto(dir.getObject('/tof/p2_tdcadc_dt_S'+(it+1))) def f1 = FTOFFitter.tdcadcdifffit_p2(h1) funclist.add(f1) diff --git a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2_zoomed.groovy b/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2_zoomed.groovy deleted file mode 100644 index 3b90d321..00000000 --- a/detectors/src/main/java/org/jlab/clas/timeline/timeline/ftof/ftof_tdcadc_p2_zoomed.groovy +++ /dev/null @@ -1,84 +0,0 @@ -package org.jlab.clas.timeline.timeline.ftof -import java.util.concurrent.ConcurrentHashMap -import org.jlab.groot.data.TDirectory -import org.jlab.groot.data.GraphErrors -import org.jlab.clas.timeline.fitter.FTOFFitter -import org.jlab.groot.data.H1F - -class ftof_tdcadc_p2_zoomed { - -def data = new ConcurrentHashMap() - -def processDirectory(dir, run) { - def funclist = [] - def meanlist = [] - def sigmalist = [] - def chi2list = [] - def histlist = (0..<6).collect{ - def h1 = dir.getObject('/tof/p2_tdcadc_dt_S'+(it+1)) - def f1 = FTOFFitter.tdcadcdifffit_p2(h1) - def peak = f1.getParameter(1) - def sigma = f1.getParameter(2).abs() - def minX = h1.getAxis().min() - def maxX = h1.getAxis().max() - if (peak>minX && peakmaxX || maxH - TDirectory out = new TDirectory() - out.mkdir('/timelines') - (0..<6).each{ sec-> - def grtl = new GraphErrors('sec'+(sec+1)) - grtl.setTitle("p2 t_tdc-t_fadc (" + name +")") - grtl.setTitleY("p2 t_tdc-t_fadc (" + name +") (ns)") - grtl.setTitleX("run number") - - data.sort{it.key}.each{run,it-> - if (sec==0){ - out.mkdir('/'+it.run) - } - out.cd('/'+it.run) - out.addDataSet(it.hlist[sec]) - out.addDataSet(it.flist[sec]) - grtl.addPoint(it.run, it[name][sec], 0, 0) - } - out.cd('/timelines') - out.addDataSet(grtl) - } - - out.writeFile('ftof_tdcadc_time_p2_zoomed_' + name + '.hipo') - } -} -} diff --git a/detectors/src/main/java/org/jlab/clas/timeline/util/HistoUtil.groovy b/detectors/src/main/java/org/jlab/clas/timeline/util/HistoUtil.groovy new file mode 100644 index 00000000..bf77c728 --- /dev/null +++ b/detectors/src/main/java/org/jlab/clas/timeline/util/HistoUtil.groovy @@ -0,0 +1,60 @@ +package org.jlab.clas.timeline.util +import org.jlab.groot.data.H1F + +class HistoUtil { + + /// zoom on the range of filled bins of a histogram + /// @param histIn the input histogram + /// @param threshold the fraction of the max bin to assume valid data (useful for ignoring long tails) + /// @param nBufferBins how many extra bins on each side of the zoomed range + static def zoomHisto(H1F histIn, double threshold=0.0, int nBufferBins=3) { + + // read input histogram + def nBinsIn = histIn.getXaxis().getNBins() + def xData = (0..1 || nBufferBins<0) { + throw new Exception("bad arguments for zoomHisto") + } + + // find the data range + def minVal = xData.max() * threshold + def dataBinRange = [ + [ xData.findIndexOf{ it > minVal } - nBufferBins, 0 ].max(), + [ nBinsIn - xData.reverse().findIndexOf{ it > minVal } + nBufferBins, nBinsIn-1].min() + ] + def rangeOut = dataBinRange.collect{ histIn.getXaxis().getBinCenter(it) } + rangeOut[0] -= widthIn / 2 + rangeOut[1] += widthIn / 2 + def nBinsOut = dataBinRange[1] - dataBinRange[0] + 1 + def widthOut = (rangeOut[1]-rangeOut[0]) / nBinsOut + + // print some information, for debugging + def printDebug = { + System.err.println """ + histoZoom of histogram '${histIn.getName()}': + nBins: ${nBinsIn} -> ${nBinsOut} + xMin: ${rangeIn[0]} -> ${rangeOut[0]} + xMax: ${rangeIn[1]} -> ${rangeOut[1]} + binWidth: ${widthIn} -> ${widthOut} + """ + } + // printDebug() + + // check that the bin width is correct + if((widthIn-widthOut).abs()>0.0001) { + printDebug() + throw new Exception("bin widths don't match") + } + + // define and fill the output, zoomed histogram + def histOut = new H1F(histIn.getName(), histIn.getTitle(), nBinsOut, rangeOut[0], rangeOut[1]) + histOut.setTitleX(histIn.getTitleX()) + histOut.setTitleY(histIn.getTitleY()) + nBinsIn.times{ histOut.fill(histIn.getXaxis().getBinCenter(it), histIn.getBinContent(it)) } + return histOut + } +}