Skip to content

Commit

Permalink
fix: rich_dt_m sigma bounds and timeout bad fits (#247)
Browse files Browse the repository at this point in the history
  • Loading branch information
c-dilks authored Oct 21, 2024
1 parent 2b92834 commit 4065b10
Showing 1 changed file with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package org.jlab.clas.timeline.fitter
import org.jlab.groot.fitter.DataFitter
import org.jlab.groot.data.H1F
import org.jlab.groot.math.F1D
import java.util.concurrent.TimeUnit
import java.util.concurrent.CompletableFuture


class RICHFitter {
Expand All @@ -10,21 +12,46 @@ class RICHFitter {
def hAmp = h1.getBinContent(h1.getMaximumBin());
def hMean = h1.getAxis().getBinCenter(h1.getMaximumBin())
def hRMS = Math.min(h1.getRMS(),0.44)
def h1range = h1.getDataX(h1.getDataSize(0)-1) - h1.getDataX(0)

f1.setParameter(0, hAmp)
f1.setParameter(1, hMean)
f1.setParameter(2, hRMS)
f1.setParLimits(2, 0, h1range) // don't let sigma be < 0
f1.setParameter(3, 0)

def fitTimedOut = false

def makefits = {func->
hRMS = func.getParameter(2).abs()
func.setRange(hMean-3.0*hRMS, hMean+3.0*hRMS)
DataFitter.fit(func,h1,"Q")

// try the fit, but don't try for too long...
if(!fitTimedOut) {
def out = System.out
def err = System.err
def fut = CompletableFuture.runAsync{DataFitter.fit(func,h1,"Q")}
try {
fut.get(10, TimeUnit.SECONDS) // 10 second timeout
} catch(def ex) {
System.setOut(out)
System.setErr(err)
err.println("FIT timeout")
fitTimedOut = true
}
}

// give up, if timed out
if(fitTimedOut) {
func.getNPars().times{func.setParameter(it, 0.0)}
}

return [func.getChiSquare(), (0..<func.getNPars()).collect{func.getParameter(it)}]
}
def fits1 = (0..10).collect{makefits(f1)}

def f2 = new F1D("fit:"+h1.getName(), "[amp]*gaus(x,[mean],[sigma])+[p0]+[p1]*x+[p2]*x*x",-0.2,0.2);
f2.setParLimits(2, 0, h1range) // don't let sigma be < 0

fits1.sort()[0][1].eachWithIndex{par,ipar->
f2.setParameter(ipar, par)
Expand All @@ -35,6 +62,12 @@ class RICHFitter {
def bestfit = fits2.sort()[0]
f2.setParameters(*bestfit[1])

// if the fit timed out, set the mean and sigma to an obviously bad value
if(fitTimedOut) {
f2.setParameter(1, 10 * h1range)
f2.setParameter(2, 10 * h1range)
}

return f2
}
}

0 comments on commit 4065b10

Please sign in to comment.