def runMinuit(numParameters): minuit = TMinuit(numParameters) minuit.SetPrintLevel(0) minuit.SetFCN(fcn) arglist = np.zeros(numParameters) + 0.01 internalFlag, arglist[0] = Long(0), 0.5 minuit.mnexcm("SET ERR", arglist, 1, internalFlag) initialValues = np.zeros(numParameters) + 0.01 steps = np.zeros(numParameters) + 0.0001 for i in xrange(numParameters): name = "epsilon%s" % i minuit.mnparm(i, name, initialValues[i], steps[i], 0, 1, internalFlag) # arglist[0] = 2 # minuit.mnexcm("SET STR", arglist, 1, internalFlag) arglist[0], arglist[1] = 10000, 0.1 minuit.mnexcm("SIMPLEX", arglist, 1, internalFlag) minuit.mnexcm("MIGRAD", arglist, 1, internalFlag) print "FIT STATUS is " +str(minuit.GetStatus()) return ratesAndErrors(numParameters, minuit)
def _recreate_gMinuit(self): self.__gMinuit = TMinuit(self.num_pars) self.__gMinuit.SetPrintLevel(-1) self.__gMinuit.mncomd("SET STRATEGY {}".format(self._strategy), ctypes.c_int(0)) self.__gMinuit.SetFCN(self._minuit_fcn) self.__gMinuit.SetErrorDef(self._err_def) # set gMinuit parameters error_code = ctypes.c_int(0) for _pid, (_pn, _pv, _pe) in enumerate( zip(self._par_names, self._par_val, self._par_err)): self.__gMinuit.mnparm(_pid, _pn, _pv, 0.1 * _pe, 0, 0, error_code) err_code = ctypes.c_int(0) # set fixed parameters for _par_id, _pf in enumerate(self._par_fixed): if _pf: self.__gMinuit.mnfixp(_par_id, err_code) # set parameter limits for _par_id, _pb in enumerate(self._par_bounds): if _pb is not None: _lo_lim, _up_lim = _pb self.__gMinuit.mnexcm( "SET LIM", arr('d', [_par_id + 1, _lo_lim, _up_lim]), 3, error_code)
def test1MinuitFit(self): """Test minuit callback and fit""" # setup minuit and callback gMinuit = TMinuit(5) gMinuit.SetPrintLevel(-1) # quiet gMinuit.SetGraphicsMode(ROOT.kFALSE) gMinuit.SetFCN(fcn) arglist = array('d', 10 * [0.]) ierflg = Long() arglist[0] = 1 gMinuit.mnexcm("SET ERR", arglist, 1, ierflg) # set starting values and step sizes for parameters vstart = array('d', [3, 1, 0.1, 0.01]) step = array('d', [0.1, 0.1, 0.01, 0.001]) gMinuit.mnparm(0, "a1", vstart[0], step[0], 0, 0, ierflg) gMinuit.mnparm(1, "a2", vstart[1], step[1], 0, 0, ierflg) gMinuit.mnparm(2, "a3", vstart[2], step[2], 0, 0, ierflg) gMinuit.mnparm(3, "a4", vstart[3], step[3], 0, 0, ierflg) # now ready for minimization step arglist[0] = 500 arglist[1] = 1. gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) # verify results amin, edm, errdef = Double(), Double(), Double() nvpar, nparx, icstat = Long(), Long(), Long() gMinuit.mnstat(amin, edm, errdef, nvpar, nparx, icstat) # gMinuit.mnprin( 3, amin ) self.assertEqual(nvpar, 4) self.assertEqual(nparx, 4) # success means that full covariance matrix is available (icstat==3) self.assertEqual(icstat, 3) # check results (somewhat debatable ... ) par, err = Double(), Double() gMinuit.GetParameter(0, par, err) self.assertEqual(round(par - 2.15, 2), 0.) self.assertEqual(round(err - 0.10, 2), 0.) gMinuit.GetParameter(1, par, err) self.assertEqual(round(par - 0.81, 2), 0.) self.assertEqual(round(err - 0.25, 2), 0.) gMinuit.GetParameter(2, par, err) self.assertEqual(round(par - 0.17, 2), 0.) self.assertEqual(round(err - 0.40, 2), 0.) gMinuit.GetParameter(3, par, err) self.assertEqual(round(par - 0.10, 2), 0.) self.assertEqual(round(err - 0.16, 2), 0.)
def __init__( self, fcn, pars, parerrors, parnames, ndof, maxpars=50 ): if len( pars ) > maxpars: raise MinuitError( "More than 50 parameters, increase maxpars" ) self.__minuit= TMinuit( maxpars ) self.minuitCommand( "SET PRI -1" ) self.__minuit.SetFCN( fcn ) self.__pars= pars self.__parerrors= parerrors self.__parnames= parnames self.__setParameters() self.__ndof= ndof return
def __init__(self, myFCN, params, **kwargs): from ROOT import TMinuit, Long, Double self.limits = np.zeros((len(params), 2)) self.steps = .04 * np.ones( len(params)) # about 10 percent in log10 space self.tolerance = .001 self.maxcalls = 10000 self.printMode = 0 self.up = 0.5 self.param_names = ['p%i' % i for i in xrange(len(params))] self.erflag = Long() self.npars = len(params) self.args = () self.gradient = None self.force_gradient = 0 self.strategy = 1 self.fixed = np.zeros_like(params) self.__dict__.update(kwargs) self.params = np.asarray(params, dtype='float') self.fixed = np.asarray(self.fixed, dtype=bool) self.fcn = FCN(myFCN, self.params, args=self.args, gradient=self.gradient) self.fval = self.fcn.fval self.minuit = TMinuit(self.npars) self.minuit.SetPrintLevel(self.printMode) self.minuit.SetFCN(self.fcn) if self.gradient: self.minuit.mncomd('SET GRA %i' % (self.force_gradient), self.erflag) self.minuit.mncomd('SET STR %i' % self.strategy, Long()) for i in xrange(self.npars): if self.limits[i][0] is None: self.limits[i][0] = 0.0 if self.limits[i][1] is None: self.limits[i][1] = 0.0 self.minuit.DefineParameter(i, self.param_names[i], self.params[i], self.steps[i], self.limits[i][0], self.limits[i][1]) self.minuit.SetErrorDef(self.up) for index in np.where(self.fixed)[0]: self.minuit.FixParameter(int(index))
def __init__(self, fcn, pars, parerrors, parnames, ndof, maxpars=50): if len(pars) > maxpars: raise MinuitError("More than 50 parameters, increase maxpars") self.__minuit = TMinuit(maxpars) self.minuitCommand("SET PRI -1") # Hold on to fcn or python will kill it after passing to TMinuit self.__fcn = fcn self.__minuit.SetFCN(fcn) self.__pars = pars self.__parerrors = parerrors self.__parnames = parnames self.__setParameters() self.__ndof = ndof return
def Minuit(fun, x0, args=(), bounds=None, verbose=0, step_size=0.01, n_iterations=500, delta_one_sigma=0.5, **options): """ Interface to ROOT Minuit @param bounds list of tuple with limits for each variable @param verbose -1 (silent) 0 (normal) 1 (verbose) @param step_size float or Sequence @param n_iterations maximum number of iterations @param delta_one_sigma delta in loss function which corresponds to one sigma errors """ from ROOT import TMinuit, Double, Long n_parameters = len(x0) def to_minimize(npar, deriv, f, apar, iflag): f[0] = fun(np.array([apar[i] for i in range(n_parameters)]), *args) minuit = TMinuit(n_parameters) minuit.SetFCN(to_minimize) minuit.SetPrintLevel(verbose) ierflg = np.array(0, dtype=np.int32) minuit.mnexcm("SET ERR", np.array([delta_one_sigma]), 1, ierflg) if ierflg > 0: raise RuntimeError("Error during \"SET ERR\" call") for i in range(n_parameters): low, high = 0.0, 0.0 # Zero seems to mean no limit if bounds is not None: low, high = bounds[i] minuit.mnparm( i, 'Parameter_{}'.format(i), x0[i], step_size[i] if isinstance( step_size, collections.Sequence) else step_size, low, high, ierflg) if ierflg > 0: raise RuntimeError( "Error during \"nmparm\" call for parmameter {}".format(i)) minuit.mnexcm("MIGRAD", np.array([n_iterations, 0.01], dtype=np.float64), 2, ierflg) if ierflg > 0: raise RuntimeError("Error during \"MIGRAD\" call") xbest = np.zeros(n_parameters) xbest_error = np.zeros(n_parameters) p, pe = Double(0), Double(0) for i in range(n_parameters): minuit.GetParameter(i, p, pe) xbest[i] = p xbest_error[i] = pe buf = array.array('d', [0.] * (n_parameters**2)) minuit.mnemat(buf, n_parameters) # retrieve error matrix hessian = np.array(buf).reshape(n_parameters, n_parameters) amin = Double(0.) # value of fcn at minimum edm = Double(0.) # estimated distance to mimimum errdef = Double(0.) # delta_fcn used to define 1 sigma errors nvpar = np.array(0, dtype=np.int32) # number of variable parameters nparx = np.array(0, dtype=np.int32) # total number of parameters icstat = np.array( 0, dtype=np.int32 ) # status of error matrix: 3=accurate 2=forced pos. def 1= approximative 0=not calculated minuit.mnstat(amin, edm, errdef, nvpar, nparx, icstat) return scipy.optimize.OptimizeResult(x=xbest, fun=amin, hessian=hessian, success=(ierflg == 0), status=ierflg)
outTag =outTag_name+str(q) loaded_model = joblib.load(os.path.expanduser('~/HHbbgg_ETH_devel/bregression/output_files/regression_heppy_'+outTag+'.pkl')) X_pred_data = loaded_model.predict(X_test_features).astype(np.float64) X_predicted_all.append(X_pred_data) n_evt = len(X_predicted_all[0]) X_predictions_for_fit = np.column_stack([x for x in X_predicted_all]) mpvs=[] print 'here' fit_quantile=[] gMinuit = TMinuit(4) gMinuit.SetPrintLevel(-1) gMinuit.SetFCN( fcn ) arglist = np.array( 10*[0.] ) ierflg = 0 arglist[0] = 1 gMinuit.mnexcm( "SET ERR", arglist, 1, Long(ierflg) ) arglist[0] = 0 gMinuit.mnexcm("SET PRINT", arglist ,0,Long(ierflg)); vstart = np.array( [ -2 , 4,-1, 0.5] ) step = np.array( [ 0.001, 0.001, 0.01, 0.01 ] ) gMinuit.mnparm( 0, "a1", vstart[0], step[0], 0, 0, Long(ierflg) ) gMinuit.mnparm( 1, "a2", vstart[1], step[1], 0, 0, Long(ierflg) ) gMinuit.mnparm( 2, "a3", vstart[2], step[2], 0, 0, Long(ierflg) ) gMinuit.mnparm( 3, "a4", vstart[3], step[3], 0, 0, Long(ierflg) ) arglist[0] = 500
def fit(self): numberOfParameters = len(self.samples) gMinuit = TMinuit(numberOfParameters) if self.method == 'logLikelihood': # set function for minimisation gMinuit.SetFCN(self.logLikelihood) gMinuit.SetMaxIterations(1000000000000) # set Minuit print level # printlevel = -1 quiet (also suppress all warnings) # = 0 normal # = 1 verbose # = 2 additional output giving intermediate results. # = 3 maximum output, showing progress of minimizations. gMinuit.SetPrintLevel(-1) # Error definition: 1 for chi-squared, 0.5 for negative log likelihood # SETERRDEF<up>: Sets the value of UP (default value= 1.), defining parameter errors. # Minuit defines parameter errors as the change in parameter value required to change the function value by UP. # Normally, for chisquared fits UP=1, and for negative log likelihood, UP=0.5. gMinuit.SetErrorDef(0.5) # error flag for functions passed as reference.set to as 0 is no error errorFlag = Long(2) N_min = 0 N_max = self.fit_data_collection.max_n_data() * 2 param_index = 0 # MNPARM # Implements one parameter definition: # mnparm(k, cnamj, uk, wk, a, b, ierflg) # K (external) parameter number # CNAMK parameter name # UK starting value # WK starting step size or uncertainty # A, B lower and upper physical parameter limits # and sets up (updates) the parameter lists. # Output: IERFLG =0 if no problems # >0 if MNPARM unable to implement definition for sample in self.samples: # all samples but data if self.n_distributions > 1: gMinuit.mnparm( param_index, sample, self.normalisation[self.distributions[0]][sample], 10.0, N_min, N_max, errorFlag) else: gMinuit.mnparm(param_index, sample, self.normalisation[sample], 10.0, N_min, N_max, errorFlag) param_index += 1 arglist = array('d', 10 * [0.]) # minimisation strategy: 1 standard, 2 try to improve minimum (a bit slower) arglist[0] = 2 # minimisation itself # SET STRategy<level>: Sets the strategy to be used in calculating first and second derivatives and in certain minimization methods. # In general, low values of <level> mean fewer function calls and high values mean more reliable minimization. # Currently allowed values are 0, 1 (default), and 2. gMinuit.mnexcm("SET STR", arglist, 1, errorFlag) gMinuit.Migrad() gMinuit.mnscan( ) # class for minimization using a scan method to find the minimum; allows for user interaction: set/change parameters, do minimization, change parameters, re-do minimization etc. gMinuit.mnmatu(1) # prints correlation matrix (always needed) self.module = gMinuit self.performedFit = True if not self.module: raise Exception( 'No fit results available. Please run fit method first') results = {} param_index = 0 for sample in self.samples: temp_par = Double(0) temp_err = Double(0) self.module.GetParameter(param_index, temp_par, temp_err) if (math.isnan(temp_err)): self.logger.warning( 'Template fit error is NAN, setting to sqrt(N).') temp_err = math.sqrt(temp_par) # gMinuit.Command("SCAn %i %i %i %i" % ( param_index, 100, N_min, N_total ) ); # scan = gMinuit.GetPlot() # results[sample] = ( temp_par, temp_err, scan ) results[sample] = (temp_par, temp_err) param_index += 1 # # gMinuit.Command("CONtour 1 2 3 50") # gMinuit.SetErrorDef(1) # results['contour'] = [gMinuit.Contour(100, 0, 1)] # gMinuit.SetErrorDef(4) # results['contour'].append(gMinuit.Contour(100, 0, 1)) self.results = results
def run_mass_fit(self, peak_scale_initial, mass=0): self.gMinuit = TMinuit(30) self.gMinuit.SetPrintLevel(-1) self.gMinuit.SetFCN(self.Fitfcn_max_likelihood) arglist = array("d", [ 0, ] * 10) ierflg = ROOT.Long(0) arglist[0] = ROOT.Double(1) # peak_scale_initial = ROOT.Double(peak_scale_initial) tmp = array("d", [ 0, ]) self.gMinuit.mnexcm("SET NOWarnings", tmp, 0, ierflg) self.gMinuit.mnexcm("SET ERR", arglist, 1, ierflg) self.gMinuit.mnparm(0, "p1", 5e-6, 1e-7, 0, 0, ierflg) self.gMinuit.mnparm(1, "p2", 10, 10, 0, 0, ierflg) self.gMinuit.mnparm(2, "p3", -5.3, 1, 0, 0, ierflg) self.gMinuit.mnparm(3, "p4", -4e-2, 1e-2, 0, 0, ierflg) self.gMinuit.mnparm(4, "p5", peak_scale_initial, peak_scale_initial / 50, 0, 0, ierflg) self.background_fit_only = [ 0, ] * len(self.data) arglist[0] = ROOT.Double(0) arglist[1] = ROOT.Double(0) #self.exclude_regions = ((2.2, 3.3),) self.gMinuit.FixParameter(2) self.gMinuit.FixParameter(3) self.gMinuit.FixParameter(4) self.gMinuit.mnexcm("simplex", arglist, 2, ierflg) self.gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) self.gMinuit.Release(2) self.gMinuit.mnexcm("simplex", arglist, 2, ierflg) self.gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) self.gMinuit.Release(3) self.gMinuit.mnexcm("simplex", arglist, 2, ierflg) self.gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) # Find an actual best fit #self.exclude_regions = ((0, 2), (3.3, 100),) self.gMinuit.FixParameter(0) self.gMinuit.FixParameter(1) self.gMinuit.FixParameter(2) self.gMinuit.FixParameter(3) self.gMinuit.Release(4) self.gMinuit.mnexcm("simplex", arglist, 2, ierflg) self.gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) self.exclude_regions = () self.gMinuit.Release(0) self.gMinuit.Release(1) self.gMinuit.Release(2) self.gMinuit.Release(3) self.gMinuit.mnexcm("simplex", arglist, 2, ierflg) self.gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) best_fit_value = ROOT.Double(0) self.gMinuit.mnstat(best_fit_value, ROOT.Double(0), ROOT.Double(0), ROOT.Long(0), ROOT.Long(0), ROOT.Long(0)) #print("Best fit value", best_fit_value) # And prepare for iterating over fit values for N injected events self.gMinuit.Release(0) self.gMinuit.Release(1) self.gMinuit.Release(2) self.gMinuit.Release(3) self.exclude_regions = () #self.data_fits = no_peak_data_fits x_values = [] y_values = [] fitted_N = ROOT.Double(0) self.gMinuit.GetParameter(4, fitted_N, ROOT.Double(0)) best_fit_likelihood = self.calc_likelihood(fitted_N) step = 5 if int(mass) >= 4000: step = 1 if int(mass) >= 5000: step = 0.2 if int(mass) >= 6000: step = 0.1 if int(mass) >= 6500: step = 0.05 N = 0 while N < 5000: start_sum = sum([math.exp(-a) for a in y_values]) fit_likelihood = self.calc_likelihood(N) x_values.append(N) y_values.append(fit_likelihood - best_fit_likelihood) probabilities = [math.exp(-a) for a in y_values] end_sum = sum(probabilities) max_prob = max(probabilities) normalised_probabilities = [a / max_prob for a in probabilities] if N / step > 50 and all( [v > 0.99 for v in normalised_probabilities]): print( "Probability=1 everywhere, probably something wrong with fit" ) print(normalised_probabilities) return None, None # if new value changes total by less than 0.1%, end loop if N > 0 and (end_sum - start_sum) / start_sum < 0.0001: print("Iterated up to {0}".format(N)) break N += step self.iflag = int(ierflg) return x_values, y_values
def main(): #The first part of the script is to input the root files# canvas = TCanvas("Canvas_d", "Canvas_d", 533, 76, 1383, 852) input_datafile = TFile(args["input_data"]) EV_data = input_datafile.Get("EventCategorizer subtask 0 stats/ExpecValue") entries_data = EV_data.GetSize() print "# of Entries in Data file:", entries_data print "Experimental Data Inputed" data_arr = [] canvas = TCanvas("Canvas_mc", "Canvas_mc", 533, 76, 1383, 852) input_mcfile = TFile(args["input_mc"]) EV_mc = input_mcfile.Get( "EventCategorizer subtask 0 stats/ExpecValue_Smeared") entries_mc = EV_mc.GetSize() print "# of Entries in MC file:", entries_mc print "MC Data Inputed" mc_arr = [] bin_arr = [] for x in range(entries_data): Data_i = EV_data.GetBinContent(x) MC_i = EV_mc.GetBinContent(x) data_arr.append(Data_i) mc_arr.append(MC_i) Bin_i = EV_data.GetBinCenter(x) bin_arr.append(Bin_i) #print Data_i #print MC_i #print data_arr #print mc_arr #print bin_arr # --> Set parameters and function to f i t name = ["c", "d"] #variable names vstart = arr('d', (1.0, 1.0)) #the initial values step = arr('d', (0.001, 0.001)) #the initial step size npar = len(name) # --> Defining the Chi-Square function to be minimized# def Chi_Induced(Data, MC, BinCenter, C, D): chi = 0. for i in range(0, entries_data): #num1 = Data[i] #num2 = D*((1-(C*BinCenter[i]))*MC[i]) #num = (num1 - num2)**2 #num = 0. #den1 = ((Data[i])**(1/2))**2 #den2 = (D*((1-(C*BinCenter[i])))*((MC[i])**(1/2)))**2 num = 2 den = 2 #den = den1 + den2 chi = chi + num / den return chi # --> set up MINUIT myMinuit = TMinuit( npar) # initialize TMinuit with maximum of npar parameters myMinuit.SetFCN(Chi_Induced) # set function to minimize ierflg = Long(0) arglist = arr('d', 2 * [0.01]) # set error definition arglist[0] = 6000 # Number of calls for FCN before gving up arglist[1] = 0.3 # Toleranceierflg = Long(0) myMinuit.mnexcm("SET ERR", arglist, 1, ierflg) for i in range(0, npar): myMinuit.mnparm(i, name[i], vstart[i], step[i], 0, 0, ierflg) myMinuit.mnexcm("MIGRAD", arglist, 1, ierflg) # execute the minimisation # --> check TMinuit status amin, edm, errdef = Double(0.), Double(0.), Double(0.) nvpar, nparx, icstat = Long(0), Long(0), Long(0) myMinuit.mnstat(amin, edm, errdef, nvpar, nparx, icstat)
def signalfit(data_hist, signalfunction, signalname): binning = HistBinsToList(data_hist) data_x = HistToList(data_hist) data_error = HistErrorList(data_hist) parfunction = signalfunction.GetNumberFreeParameters() partot = signalfunction.GetNumberFreeParameters() print partot ### the fucntion used for TMinuit def fcn(npar, gin, f, par, ifag): L = 0 # calculate likelihood, input par[0] is the N_B, par[1] is N_C, par[2] is N_L for ibin in range(len(binning)): #if (data_x[ibin] ==0): # continue bincen = binning[ibin] mu_x = 0 data = data_x[ibin] if data_error[ibin] == 0: continue #if data<0.1: # continue if signalname == "CrystalBall": if par[3] < 0: mu_x = 0 else: t = (bincen - par[2]) / (par[3]) if (par[0] < 0): t = -t absAlpha = abs(par[0]) if (t >= -absAlpha): mu_x = par[4] * exp(-0.5 * t * t) else: nDivAlpha = par[1] / absAlpha AA = exp(-0.5 * absAlpha * absAlpha) B = nDivAlpha - absAlpha arg = nDivAlpha / (B - t) mu_x = par[4] * (arg**par[1]) if signalname == "CrystalBallGaus": if par[3] < 0: mu_x = 0 else: t = (bincen - par[2]) / (par[3]) if (par[0] < 0): t = -t absAlpha = abs(par[0]) if (t >= -absAlpha): mu_x = par[4] * exp(-0.5 * t * t + exp(-(bincen - par[5])**2 / (2 * par[6]**2))) else: nDivAlpha = par[1] / absAlpha AA = exp(-0.5 * absAlpha * absAlpha) B = nDivAlpha - absAlpha arg = nDivAlpha / (B - t) mu_x = par[4] * (arg**par[1] + exp(-(bincen - par[5])**2 / (2 * par[6]**2))) #print mu_x, data, data_error[ibin] #L = L + mu_x - data*log(mu_x) L = L + ((mu_x - data) / data_error[ibin])**2 f[0] = L # initialize the TMinuit object arglist_p = 10 * [0] arglist = array.array('d') arglist.fromlist(arglist_p) ierflag = Long(0) maxiter = 1000000000 arglist_p = [1] gMinuit = TMinuit(partot) gMinuit.mnexcm('SET PRIntout', arglist, 0, ierflag) gMinuit.SetPrintLevel(1) gMinuit.SetErrorDef(1.0) gMinuit.SetFCN(fcn) arglist_p = [2] arglist = array.array('d') arglist.fromlist(arglist_p) gMinuit.mnexcm('SET STRategy', arglist, 1, ierflag) arglist_p = [maxiter, 0.0000001] arglist = array.array('d') arglist.fromlist(arglist_p) gMinuit.mnexcm('MIGrad', arglist, 2, ierflag) gMinuit.SetMaxIterations(maxiter) # initialize fitting the variables vstart = [125.0] * partot step = [0.1] * partot upper = [1000000] * partot lower = [-100] * partot varname = [] lower[3] = 0 lower[4] = 0 lower[1] = 0 vstart[3] = data_hist.GetRMS() lower[3] = data_hist.GetRMS() / 3.0 upper[3] = data_hist.GetRMS() * 3.0 vstart[3] = 125 lower[3] = 5 upper[3] = 20 vstart[4] = data_hist.Integral() vstart[2] = data_hist.GetMean() lower[2] = data_hist.GetMean() - 10 upper[2] = data_hist.GetMean() + 10 vstart[2] = 125 lower[2] = 110 upper[2] = 130 if len(vstart) > 5: vstart[5] = data_hist.GetMean() lower[5] = data_hist.GetMean() - 10 upper[5] = data_hist.GetMean() + 10 vstart[5] = 125 lower[5] = 110 upper[5] = 150 #vstart[6] = data_hist.GetRMS() #lower[6] = data_hist.GetRMS()/3.0 #upper[6] = data_hist.GetRMS()*3.0 vstart[6] = 10 lower[6] = 5 upper[6] = 20 for i in range(parfunction): varname.append("p" + str(i)) for i in range(partot): gMinuit.mnparm(i, varname[i], vstart[i], step[i], lower[i], upper[i], ierflag) # fitting procedure migradstat = gMinuit.Command('MIGrad ' + str(maxiter) + ' ' + str(0.001)) #improvestat = gMinuit.Command('IMProve ' + str(maxiter) + ' ' + str(0.01)) for i in range(partot): arglist_p.append(i + 1) arglist = array.array('d') arglist.fromlist(arglist_p) gMinuit.mnmnos() # get fitting parameters fitval_p = [Double(0)] * partot fiterr_p = [Double(0)] * partot errup_p = [Double(0)] * partot errdown_p = [Double(0)] * partot eparab_p = [Double(0)] * partot gcc_p = [Double(0)] * partot fmin_p = [Double(0)] fedm_p = [Double(0)] errdef_p = [Double(0)] npari_p = Long(0) nparx_p = Long(0) istat_p = Long(0) fitval = array.array('d') fiterr = array.array('d') errup = array.array('d') errdown = array.array('d') eparab = array.array('d') gcc = array.array('d') for i in range(partot): gMinuit.GetParameter(i, fitval_p[i], fiterr_p[i]) fitval.append(fitval_p[i]) fiterr.append(fiterr_p[i]) errup.append(errup_p[i]) errdown.append(errdown_p[i]) eparab.append(eparab_p[i]) gcc.append(gcc_p[i]) gMinuit.mnstat(fmin_p[0], fedm_p[0], errdef_p[0], npari_p, nparx_p, istat_p) for p in range(signalfunction.GetNumberFreeParameters()): signalfunction.SetParameter(p, fitval[p]) print "fit uncert", fiterr_p[p] signalfunction.SetChisquare(fmin_p[0]) print fmin_p[0] return fitval[partot - 1], fitval[partot - 2]
def bkgfit(data_hist, bkgfunction, bkgname, doFloatZ=False, signal_hist=None, z_hist=None): isBkgPlusZFit = False isSpuriousFit = False binning = HistBinsToList(data_hist) data_x = HistToList(data_hist) data_error = HistErrorList(data_hist) z_x = [] signal_x = [] if z_hist != None: isBkgPlusZFit = True z_x = HistToList(z_hist) if signal_hist != None: isSpuriousFit = True signal_x = HistToList(signal_hist) parfunction = bkgfunction.GetNumberFreeParameters() partot = bkgfunction.GetNumberFreeParameters() + 2 ### the fucntion used for TMinuit def fcn(npar, gin, f, par, ifag): L = 0 # calculate likelihood, input par[0] is the N_B, par[1] is N_C, par[2] is N_L for ibin in range(len(binning)): if (data_x[ibin] < 0.5): continue bincen = binning[ibin] bkg = 0 data = data_x[ibin] if bkgname == "BernsteinO2": bkg = (par[0] * (1 - (bincen - fit_start) / fit_range)**2 + 2 * par[1] * (1 - (bincen - fit_start) / fit_range) * ((bincen - fit_start) / fit_range) + par[2] * ((bincen - fit_start) / fit_range)**2) if bkgname == "BernsteinO3": bkg = par[0] * (1 - ( (bincen - fit_start) / fit_range))**3 + par[1] * ( 3 * ((bincen - fit_start) / fit_range) * (1 - ((bincen - fit_start) / fit_range))**2) + par[2] * ( 3 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))) + par[3] * ( (bincen - fit_start) / fit_range)**3 if bkgname == "BernsteinO4": bkg = par[0] * (1 - ( (bincen - fit_start) / fit_range))**4 + par[1] * ( 4 * ((bincen - fit_start) / fit_range) * (1 - ((bincen - fit_start) / fit_range))**3) + par[2] * ( 6 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))**2 ) + par[3] * ( 4 * ((bincen - fit_start) / fit_range)**3 * (1 - ((bincen - fit_start) / fit_range))) + par[4] * ( (bincen - fit_start) / fit_range)**4 if bkgname == "BernsteinO5": bkg = par[0] * (1 - ( (bincen - fit_start) / fit_range))**5 + par[1] * (5 * ( (bincen - fit_start) / fit_range) * (1 - ( (bincen - fit_start) / fit_range))**4) + par[2] * ( 10 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))**3 ) + par[3] * (10 * ( (bincen - fit_start) / fit_range)**3 * (1 - ( (bincen - fit_start) / fit_range ))**2) + par[4] * (5 * ( (bincen - fit_start) / fit_range)**4 * (1 - ((bincen - fit_start) / fit_range))) + par[5] * ( (bincen - fit_start) / fit_range)**5 if bkgname == "BernsteinO6": bkg = (par[0] * (1 - ((bincen - fit_start) / fit_range))**6 + par[1] * (6 * ((bincen - fit_start) / fit_range)**1 * (1 - ((bincen - fit_start) / fit_range))**5) + par[2] * (15 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))**4) + par[3] * (20 * ((bincen - fit_start) / fit_range)**3 * (1 - ((bincen - fit_start) / fit_range))**3) + par[4] * (15 * ((bincen - fit_start) / fit_range)**4 * (1 - ((bincen - fit_start) / fit_range))**2) + par[5] * (6 * ((bincen - fit_start) / fit_range)**5 * (1 - ((bincen - fit_start) / fit_range))**1) + par[6] * ((bincen - fit_start) / fit_range)**6) if bkgname == "ExpoBernsteinO2": try: bkg = exp(par[0] * (bincen - fit_start) / fit_range) * ( par[1] * (1 - (bincen - fit_start) / fit_range)**2 + 2 * par[2] * (1 - (bincen - fit_start) / fit_range) * ((bincen - fit_start) / fit_range) + par[3] * ((bincen - fit_start) / fit_range)**2) except OverflowError: bkg = 0 if bkgname == "ExpoBernsteinO3": try: bkg = exp(par[0] * (bincen - fit_start) / fit_range) * ( par[1] * (1 - ((bincen - fit_start) / fit_range))**3 + par[2] * (3 * ((bincen - fit_start) / fit_range) * (1 - ((bincen - fit_start) / fit_range))**2) + par[3] * (3 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))) + par[4] * ((bincen - fit_start) / fit_range)**3) except OverflowError: bkg = 0 if bkgname == "ExpoBernsteinO4": try: bkg = exp(par[0] * (bincen - fit_start) / fit_range) * ( par[1] * (1 - ((bincen - fit_start) / fit_range))**4 + par[2] * (4 * ((bincen - fit_start) / fit_range) * (1 - ((bincen - fit_start) / fit_range))**3) + par[3] * (6 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))**2) + par[4] * (4 * ((bincen - fit_start) / fit_range)**3 * (1 - ((bincen - fit_start) / fit_range))) + par[5] * ((bincen - fit_start) / fit_range)**4) except OverflowError: bkg = 0 if bkgname == "ExpoBernsteinO5": try: bkg = exp(par[0] * (bincen - fit_start) / fit_range) * ( par[1] * (1 - ((bincen - fit_start) / fit_range))**5 + par[2] * (5 * ((bincen - fit_start) / fit_range) * (1 - ((bincen - fit_start) / fit_range))**4) + par[3] * (10 * ((bincen - fit_start) / fit_range)**2 * (1 - ((bincen - fit_start) / fit_range))**3) + par[4] * (10 * ((bincen - fit_start) / fit_range)**3 * (1 - ((bincen - fit_start) / fit_range))**2) + par[5] * (5 * ((bincen - fit_start) / fit_range)**4 * (1 - ((bincen - fit_start) / fit_range))) + par[6] * ((bincen - fit_start) / fit_range)**5) except OverflowError: bkg = 0 if bkgname == "ExpoPolO2": bkg = exp(-(par[0] + par[1] * ((bincen - fit_start) / fit_range) + par[2] * ((bincen - fit_start) / fit_range)**2)) if bkgname == "ExpoPolO3": bkg = exp(-(par[0] + par[1] * ((bincen - fit_start) / fit_range) + par[2] * ((bincen - fit_start) / fit_range)**2 + par[3] * ((bincen - fit_start) / fit_range)**3)) if bkgname == "ExpoPolO4": bkg = exp(-(par[0] + par[1] * ((bincen - fit_start) / fit_range) + par[2] * ((bincen - fit_start) / fit_range)**2 + par[3] * ((bincen - fit_start) / fit_range)**3 + par[4] * ((bincen - fit_start) / fit_range)**4)) mu_x = bkg #if isBkgPlusZFit: # mu_x = mu_x + (par[partot-1] *z_x[ibin]) if isSpuriousFit: mu_x = mu_x + par[partot - 2] * signal_x[ibin] #L = L + mu_x - data*log(mu_x) L = L + ((mu_x - data) / data_error[ibin])**2 f[0] = L # initialize the TMinuit object arglist_p = 10 * [0] arglist = array.array('d') arglist.fromlist(arglist_p) ierflag = Long(0) maxiter = 1000000000 arglist_p = [1] gMinuit = TMinuit(partot) gMinuit.mnexcm('SET PRIntout', arglist, 0, ierflag) gMinuit.SetPrintLevel(1) gMinuit.SetErrorDef(1.0) gMinuit.SetFCN(fcn) arglist_p = [2] arglist = array.array('d') arglist.fromlist(arglist_p) gMinuit.mnexcm('SET STRategy', arglist, 1, ierflag) arglist_p = [maxiter, 0.0000001] arglist = array.array('d') arglist.fromlist(arglist_p) gMinuit.mnexcm('MIGrad', arglist, 2, ierflag) gMinuit.SetMaxIterations(maxiter) # initialize fitting the variables vstart = [100.0] * partot # start alpha_z with 1 vstart[partot - 1] = 1.0 vstart[partot - 2] = 0 step = [0.1] * partot upper = [100000] * partot lower = [0.1] * partot varname = [] if "ExpoPol" in bkgname: upper = [1000] * partot lower = [-1000] * partot if "ExpoBernstein" in bkgname: vstart[0] = -1 upper[0] = 0 lower[0] = -10 for i in range(parfunction): varname.append("p" + str(i)) varname.append("alpha_sig") varname.append("alpha_z") if doFloatZ: vstart[partot - 1] = 1.0 upper[partot - 1] = 2 lower[partot - 1] = 0 step[partot - 1] = 0.01 if isSpuriousFit: upper[partot - 2] = 10.0 lower[partot - 2] = -10.0 step[partot - 2] = 0.1 vstart[partot - 2] = 1 for i in range(partot): gMinuit.mnparm(i, varname[i], vstart[i], step[i], lower[i], upper[i], ierflag) if not isSpuriousFit: vstart[partot - 2] = 0 gMinuit.FixParameter(partot - 2) if not doFloatZ: lower[partot - 1] = 1 upper[partot - 1] = 1 gMinuit.FixParameter(partot - 1) if not isBkgPlusZFit: vstart[partot - 1] = 0.0 gMinuit.FixParameter(partot - 1) # fitting procedure migradstat = gMinuit.Command('MIGrad ' + str(maxiter) + ' ' + str(0.001)) improvestat = gMinuit.Command('IMProve ' + str(maxiter) + ' ' + str(0.01)) for i in range(partot): arglist_p.append(i + 1) arglist = array.array('d') arglist.fromlist(arglist_p) #gMinuit.mnmnos() # get fitting parameters fitval_p = [Double(0)] * partot fiterr_p = [Double(0)] * partot errup_p = [Double(0)] * partot errdown_p = [Double(0)] * partot eparab_p = [Double(0)] * partot gcc_p = [Double(0)] * partot fmin_p = [Double(0)] fedm_p = [Double(0)] errdef_p = [Double(0)] npari_p = Long(0) nparx_p = Long(0) istat_p = Long(0) fitval = array.array('d') fiterr = array.array('d') errup = array.array('d') errdown = array.array('d') eparab = array.array('d') gcc = array.array('d') for i in range(partot): gMinuit.GetParameter(i, fitval_p[i], fiterr_p[i]) fitval.append(fitval_p[i]) fiterr.append(fiterr_p[i]) errup.append(errup_p[i]) errdown.append(errdown_p[i]) eparab.append(eparab_p[i]) gcc.append(gcc_p[i]) gMinuit.mnstat(fmin_p[0], fedm_p[0], errdef_p[0], npari_p, nparx_p, istat_p) for p in range(bkgfunction.GetNumberFreeParameters()): bkgfunction.SetParameter(p, fitval[p]) print "fit uncert", fiterr_p[p] bkgfunction.SetChisquare(fmin_p[0]) return fitval[partot - 1], fitval[partot - 2]
# --- fcn -- called by MINUIT repeatedly with varying parameters # NOTE: the function name is set via TMinuit.SetFCN def fcn(npar, deriv, f, apar, iflag): """ meaning of parameters: npar: # of parameters deriv: array of derivatives df/dp_i(x), optional f: value of function to be minimised (typically chi2 or negLogL) apar: the array of parameters iflag: internal flag: 1 at first call, 3 at the last, 4 during minimisation """ f[0] = calcChi2(npar, apar) # --> set up MINUIT myMinuit = TMinuit(npar) # initialize TMinuit with maximum of npar parameters myMinuit.setFCN(fcn) # set func to minimize arglist = arr('d', 2*[0.01])# set error definition ieflg = Long(0) arglist[0] = 1. # 1 sigma is Delta chi^2 = 1 myMinuit.mnexcm("SET ERR", arglist, 1, ierflg) #−−>Set starting values and step sizes for parameters for i in range(0, npar): #Define the parameters for the fit myMinuit.mnparm(i, name[i], vstart[i], step[i], 0, 0, ierflg) arglist[0] = 6000 # Number of calls to FCN before giving up. arglist[1] = 0.3 # Tolerance
def prepareAndRunOptimizer(self, xValues, yValues, erryValues, fixParams, optFunction, parValues, parNames, printOutLevel=0): self.xValues = xValues self.yValues = yValues self.erryValues = erryValues self.fixParams = fixParams initialError = 0.1 nBins = len(self.xValues) gMinuit = TMinuit(nBins) gMinuit.SetFCN(optFunction) arglist = array('d', nBins * [0]) ierflg = c_int(0) arglist[0] = 1 # 1 for chi2, 0.5 for likelihood gMinuit.mnexcm('SET ERR', arglist, 1, ierflg) # Set starting values and step sizes for parameters vStart = parValues vStep = [initialError for i in range(len(parValues))] for i, name in enumerate(parNames): gMinuit.mnparm(i, name, vStart[i], vStep[i], 0, 0, ierflg) # Fix parameters (counting from 1) for i, fix in enumerate(self.fixParams): arglist[i] = fix + 1 gMinuit.mnexcm('FIX', arglist, len(self.fixParams), ierflg) # Define printout level arglist[0] = printOutLevel # -1 = no output except from SHOW # 0 = minimum output (no starting values or intermediate results) default value, normal output # 1 = additional output giving intermediate results. # 2 = maximum output, showing progress of minimizations. gMinuit.mnexcm('SET PRI', arglist, 1, ierflg) # Now ready for minimization step arglist[0] = 5000 # Max calls arglist[1] = 0.1 # Tolerance gMinuit.mnexcm('MIGRAD', arglist, 2, ierflg) # Print results self.dof = self.nMeas - len(parValues) + len(self.fixParams) fmin, fedm, errdef = c_double(0.), c_double(0.), c_double(0.) npari, nparx, istat = c_int(0), c_int(0), c_int(0) gMinuit.mnstat(fmin, fedm, errdef, npari, nparx, istat) print('\nFMIN:', round(fmin.value, 2), '\tFEDM:', '{:.1e}'.format(fedm.value), '\tERRDEF:', errdef.value, '\tNPARI:', npari.value, '\tNPARX:', nparx.value, '\tISTAT:', istat.value) print('chi-2:', round(self.chi2, 2), '\td.o.f.:', self.dof, '\tchi-2/d.o.f.:', round(self.chi2 / self.dof, 2), '\n') return gMinuit, istat
def test1MinuitFit(self): """Test minuit callback and fit""" # setup minuit and callback gMinuit = TMinuit(5) gMinuit.SetPrintLevel(-1) # quiet gMinuit.SetGraphicsMode(ROOT.kFALSE) gMinuit.SetFCN(fcn) arglist = array('d', 10 * [0.]) if not exp_pyroot and sys.hexversion < 0x3000000: ierflg = ROOT.Long() else: ierflg = ctypes.c_int() arglist[0] = 1 gMinuit.mnexcm("SET ERR", arglist, 1, ierflg) # set starting values and step sizes for parameters vstart = array('d', [3, 1, 0.1, 0.01]) step = array('d', [0.1, 0.1, 0.01, 0.001]) gMinuit.mnparm(0, "a1", vstart[0], step[0], 0, 0, ierflg) gMinuit.mnparm(1, "a2", vstart[1], step[1], 0, 0, ierflg) gMinuit.mnparm(2, "a3", vstart[2], step[2], 0, 0, ierflg) gMinuit.mnparm(3, "a4", vstart[3], step[3], 0, 0, ierflg) # now ready for minimization step arglist[0] = 500 arglist[1] = 1. gMinuit.mnexcm("MIGRAD", arglist, 2, ierflg) # verify results if exp_pyroot: Double = ctypes.c_double else: Double = ROOT.Double amin, edm, errdef = Double(), Double(), Double() if not exp_pyroot and sys.hexversion < 0x3000000: Long = ROOT.Long nvpar, nparx, icstat = Long(), Long(), Long() else: nvpar, nparx, icstat = ctypes.c_int(), ctypes.c_int( ), ctypes.c_int() gMinuit.mnstat(amin, edm, errdef, nvpar, nparx, icstat) # gMinuit.mnprin( 3, amin ) if exp_pyroot or sys.hexversion >= 0x3000000: nvpar, nparx, icstat = map(lambda x: x.value, [nvpar, nparx, icstat]) self.assertEqual(nvpar, 4) self.assertEqual(nparx, 4) # success means that full covariance matrix is available (icstat==3) self.assertEqual(icstat, 3) # check results (somewhat debatable ... ) par, err = Double(), Double() if exp_pyroot: # ctypes.c_double requires the explicit retrieval of the inner value gMinuit.GetParameter(0, par, err) self.assertEqual(round(par.value - 2.15, 2), 0.) self.assertEqual(round(err.value - 0.10, 2), 0.) gMinuit.GetParameter(1, par, err) self.assertEqual(round(par.value - 0.81, 2), 0.) self.assertEqual(round(err.value - 0.25, 2), 0.) gMinuit.GetParameter(2, par, err) self.assertEqual(round(par.value - 0.17, 2), 0.) self.assertEqual(round(err.value - 0.40, 2), 0.) gMinuit.GetParameter(3, par, err) self.assertEqual(round(par.value - 0.10, 2), 0.) self.assertEqual(round(err.value - 0.16, 2), 0.) else: gMinuit.GetParameter(0, par, err) self.assertEqual(round(par - 2.15, 2), 0.) self.assertEqual(round(err - 0.10, 2), 0.) gMinuit.GetParameter(1, par, err) self.assertEqual(round(par - 0.81, 2), 0.) self.assertEqual(round(err - 0.25, 2), 0.) gMinuit.GetParameter(2, par, err) self.assertEqual(round(par - 0.17, 2), 0.) self.assertEqual(round(err - 0.40, 2), 0.) gMinuit.GetParameter(3, par, err) self.assertEqual(round(par - 0.10, 2), 0.) self.assertEqual(round(err - 0.16, 2), 0.)
def main(): global freqs_hz, pv, sigq, sigu parser = OptionParser(usage) parser.add_option("-r", "--rm", type="float", dest="rm", default=0., help="Estimate of the RM") parser.add_option("-n", "--norm", action="store_true", dest="norm", default=False, help="Verbose mode") parser.add_option("-b", "--baseline", action="store_true", dest="baseline", default=False, help="Fit for a baseline") parser.add_option("-f", "--nofit", action="store_true", dest="nofit", default=False, help="Don't fit for the RM with Minuit") parser.add_option("-c", "--clean", action="store_true", dest="clean", default=False, help="Clean the baseline") (opts, args) = parser.parse_args() #if opts.help: # print full_usage arch = psrchive.Archive_load(sys.argv[1]) arch.tscrunch() arch.bscrunch(2) #arch.fscrunch(2) arch.dedisperse() arch.remove_baseline() arch.convert_state('Stokes') arch.centre_max_bin() #arch.rotate(0.5) data = arch.get_data() MJD = arch.get_first_Integration().get_epoch().strtempo() w = arch.get_weights().sum(0) I = data[:,0,:,:].mean(0) Q = data[:,1,:,:].mean(0) U = data[:,2,:,:].mean(0) #V = data[:,3,:,:].mean(0) I = ma.masked_array(I) Q = ma.masked_array(Q) U = ma.masked_array(U) #V = ma.masked_array(V) I[w==0] = np.ma.masked Q[w==0] = np.ma.masked U[w==0] = np.ma.masked # Get Freqs nchan = arch.get_nchan() freqs = np.zeros(nchan) for i in range(nchan): freqs[i] = arch.get_Profile(0,0,i).get_centre_frequency() ## Determine phase range arch.fscrunch() arch.tscrunch() arch.pscrunch() prof = arch.get_Profile(0,0,0) #print prof.get_amps() lowbin, hibin = get_pulse_range(arch) #lowbin, hibin = 458,531 #lowbin, hibin = 20,120 if opts.clean: for n in range(nchan): if n%20: continue baseline_idx = np.append(np.arange(0, lowbin), np.arange(hibin, arch.get_nbin())) baseline_dat = I[n][baseline_idx] print n, baseline_idx, baseline_dat poly = np.polyfit(baseline_idx, baseline_dat, 1) p = np.poly1d(poly) pylab.plot(I[n]) I[n] = I[n] - p(np.arange(0, arch.get_nbin())) pylab.plot(I[n]) pylab.show() for ii, wx in enumerate(w): I[ii] *= wx/np.max(w) Q[ii] *= wx/np.max(w) U[ii] *= wx/np.max(w) #V[ii] *= wx if opts.norm: print "Will normalize by the rms of the noise" scale = np.std(I, axis=1) / np.max(np.std(I, axis=1)) for ii, s in enumerate(scale): I[ii,:] /= s Q[ii,:] /= s U[ii,:] /= s #Q = Q / scale #U = U / scale freq_lo = freqs[0] freq_hi = freqs[-1] lowphase = lowbin / float(arch.get_nbin()) hiphase = hibin / float(arch.get_nbin()) #lowphase= 0.48 #hiphase = 0.515 #lowphase = 0.515 #hiphase = 0.54 print "Pulse phase window: ", lowphase, hiphase #pylab.plot(np.sum(I), axis) #pylab.show() # 2D plot f = pylab.figure() pylab.subplot(321) #print np.sum(I,axis=0) #pylab.plot(np.sum(I, axis=0)) pylab.plot(prof.get_amps()) pylab.xlim([0, arch.get_nbin()]) f.text( .5, 0.95, r'%s'%os.path.split(sys.argv[1])[1], horizontalalignment='center') pylab.subplot(323) pylab.axis([0,1,freq_lo,freq_hi]) pylab.imshow(I,extent=(0,1,freq_lo,freq_hi), origin='lower', aspect='auto', vmax=I.max()/1.5, vmin=I.min()/1.5) pylab.xlabel('Pulse phase') pylab.ylabel('Frequency (MHz)') # Compute errors of Q and U sigq = np.std(Q[:,lowbin:hibin], axis=1) / np.sqrt(hibin-lowbin) sigu = np.std(U[:,lowbin:hibin], axis=1) / np.sqrt(hibin-lowbin) #sigq = np.std(Q[:,:], axis=1) #sigu = np.std(U[:,:], axis=1) pylab.plot([lowphase,lowphase], [freq_lo, freq_hi], 'r--') pylab.plot([hiphase,hiphase], [freq_lo, freq_hi], 'r--') freqs_hz = freqs * 1e6 # Select phase range lowbin = int(lowphase * arch.get_nbin()) hibin = int(hiphase * arch.get_nbin()) dat = Q + 1j * U pv = dat[:,lowbin:hibin].mean(1) # Select phase range and average #rhos = np.arange(-90000, 90000, 10) rhos = np.arange(-2000, 2000, 1) res = np.absolute(getL(rhos, pv)) # Plot I f(RM) pylab.subplot(324) pylab.plot(rhos, res, 'b-') pylab.xlabel('RM') pylab.ylabel('I') # Plot Q pylab.subplot(325) pylab.errorbar(freqs, np.real(pv), yerr=sigq, ls='None') pylab.plot(freqs, np.real(pv), 'bo') pylab.xlabel('Frequency (MHz)') pylab.ylabel('Q') # Plot U pylab.subplot(326) pylab.errorbar(freqs, np.imag(pv), yerr=sigu, ls='None') pylab.plot(freqs, np.imag(pv), 'bo') pylab.xlabel('Frequency (MHz)') pylab.ylabel('U') # Should get the initial RM if opts.rm: initial_RM = -opts.rm else: initial_RM = -rhos[np.argmax(res)] print "Will use initial RM", initial_RM initial_L = getL(np.array([initial_RM]), pv) / (hibin-lowbin) if not opts.nofit: # Minuit part gMinuit = TMinuit(5) #gMinuit.SetErrorDef(1) # 1-Sigma Error gMinuit.SetErrorDef(4) # 2-Sigma Error gMinuit.SetFCN(fcn) arglist = arr('d', 2*[0.01]) ierflg = Long(0) #arglist[0] = 1 #gMinuit.mnexcm("SET ERR", arglist ,1,ierflg) # Set initial parameter values for fit vstart = arr( 'd', (np.real(initial_L), np.imag(initial_L), initial_RM) ) #vstart = arr( 'd', (2*np.real(initial_L), 2*np.imag(initial_L), initial_RM) ) # Set step size for fit step = arr( 'd', (0.001, 0.001, 0.001) ) # Define the parameters for the fit gMinuit.mnparm(0, "Qf", vstart[0], step[0], 0,0,ierflg) gMinuit.mnparm(1, "Uf", vstart[1], step[1], 0,0,ierflg) gMinuit.mnparm(2, "RM", vstart[2], step[2], 0,0,ierflg) gMinuit.mnparm(3, "a", 0.0, step[2], 0,0,ierflg) gMinuit.mnparm(4, "b", 0.0, step[2], 0,0,ierflg) #gMinuit.FixParameter(2) if not opts.baseline: gMinuit.FixParameter(3) gMinuit.FixParameter(4) arglist[0] = 6000 # Number of calls to FCN before giving up. arglist[1] = 0.1 # Tolerance gMinuit.mnexcm("MIGRAD", arglist ,2,ierflg) amin, edm, errdef = Double(0.18), Double(0.19), Double(1.0) nvpar, nparx, icstat = Long(1), Long(2), Long(3) gMinuit.mnstat(amin,edm,errdef,nvpar,nparx,icstat); gMinuit.mnmnos(); gMinuit.mnprin(3,amin); finalQ, finalQ_err = Double(0), Double(0) finalU, finalU_err = Double(0), Double(0) finalRM, finalRM_err = Double(0), Double(0) A, A_err = Double(0), Double(0) B, B_err = Double(0), Double(0) print "\n\n" gMinuit.GetParameter(0, finalQ, finalQ_err) gMinuit.GetParameter(1, finalU, finalU_err) gMinuit.GetParameter(2, finalRM, finalRM_err) gMinuit.GetParameter(3, A, A_err) gMinuit.GetParameter(4, B, B_err) finalRM *= -1. print finalQ, finalU line1 = "Final RM: %.1f"%(finalRM) + "(+/-) %.1f "%(finalRM_err) + " (2-sig) " line2 = "Chi**2r = %.2f"%(get_chi2((finalQ,finalU,-finalRM,A,B)) / ( 2*pv.size - 3 - 1 -2)) print line1 print line2 f.text( .5, 0.92, line1 + line2, horizontalalignment='center') print MJD, np.mean(freqs), finalRM, finalRM_err, get_chi2((finalQ,finalU,finalRM,A,B)), 2*pv.count() # Plot best fit model finalRM *= -1. pylab.subplot(325) pylab.plot(freqs, np.real( -A+getPV(finalQ+1j*finalU, finalRM) )) pylab.subplot(326) pylab.plot(freqs, np.imag( -B+getPV(finalQ+1j*finalU, finalRM) )) pylab.show()
def fit( p , perr ): global val, err, nBins val = p err = perr nBins=len(val) #name=['q0','q1','q2','q3','q4'] #name=['q0','q1','q2','q3'] #name=['q0','q1','q2'] name = [ 'q0' , 'q1' ] npar=len(name) # the initial values vstart = arr( 'd' , npar*[0.1] ) # the initial step size step = arr( 'd' , npar*[0.000001] ) # --> set up MINUIT gMinuit = TMinuit ( npar ) # initialize TMinuit with maximum of npar parameters gMinuit.SetFCN( fcn ) # set function to minimize arglist = arr( 'd' , npar*[0.01] ) # set error definition ierflg = c_int(0) arglist[0] = 1. # 1 sigma is Delta chi2 = 1 gMinuit.mnexcm("SET ERR", arglist, 1, ierflg ) # --> set starting values and step size for parameters # Define the parameters for the fit for i in range(0,npar): gMinuit.mnparm( i, name[i] , vstart[i] , step[i] , 0, 0, ierflg ) # now ready for minimization step arglist [0] = 500 # Number of calls for FCN before giving up arglist [1] = 1. # Tolerance gMinuit.mnexcm("MIGRAD" , arglist , 2 , ierflg) # execute the minimisation # --> check TMinuit status amin , edm , errdef = c_double(0.) , c_double(0.) , c_double(0.) nvpar , nparx , icstat = c_int(0) , c_int(0) , c_int(0) gMinuit.mnstat (amin , edm , errdef , nvpar , nparx , icstat ) gMinuit.mnprin(3,amin) # print-out by Minuit # meaning of parameters: # amin: value of fcn distance at minimum (=chi^2) # edm: estimated distance to minimum # errdef: delta_fcn used to define 1 sigam errors # nvpar: total number of parameters # icstat: status of error matrix: # 3 = accurate # 2 = forced pos. def # 1 = approximative # 0 = not calculated # # --> get results from MINUIT finalPar = [] finalParErr = [] p, pe = c_double(0.) , c_double(0.) for i in range(0,npar): gMinuit.GetParameter(i, p, pe) # retrieve parameters and errors finalPar.append( float(p.value) ) finalParErr.append( float(pe.value) ) # get covariance matrix buf = arr('d' , npar*npar*[0.]) gMinuit.mnemat( buf , npar ) # retrieve error matrix emat = np.array( buf ).reshape( npar , npar ) # --> provide formatted output of results print "\n" print "*==* MINUIT fit completed:" print'fcn@minimum = %.3g'%( amin.value ) , " error code =" , ierflg.value , " status =" , icstat.value , " (if its 3, mean accurate)" print " Results: \t value error corr. mat." for i in range(0,npar): print'%s: \t%10.3e +/- %.1e'%( name[i] , finalPar[i] , finalParErr[i] ) , for j in range (0,i): print'%+.3g'%( emat[i][j]/np.sqrt(emat[i][i])/np.sqrt(emat[j][j]) ), print "\n" return [ [i,j] for i,j in zip(finalPar , finalParErr) ]
def fit_model(self, country, time_range): s_data = self.data_sir["susceptible"] i_data = self.data_sir["infected"] r_data = self.data_sir["recovered"] def fcn(nPar, gin, f, par, flag): tr = par[0] rec = par[1] chi2 = 0. n_bins = s_data.GetNbinsX() s_model, i_model, r_model = solve_SIR(tr, rec, time_range) for i in range(1, n_bins + 1): dif = (i_data.GetBinContent(i) - i_model.GetBinContent(i)) / i_data.GetBinError(i) chi2 += dif**2 dif = (r_data.GetBinContent(i) - r_model.GetBinContent(i)) / r_data.GetBinError(i) chi2 += dif**2 f[0] = chi2 return minuit = TMinuit(3) minuit.SetFCN(fcn) vstep = [1e-10, 1e-10] vinit = [1e-10, 1e-10] # vinit = [1e-3, 1e-3] vmin = [1e-15, 1e-15] vmax = [1e0, 1e0] from ctypes import c_int, c_double import array as c_arr arglist = c_arr.array('d', 10 * [0.]) ierflag = 0 arglist[0] = 1 minuit.mnexcm("SET ERR", arglist, 1, c_int(ierflag)) minuit.mnparm(0, "transition rate", vinit[0], vstep[0], vmin[0], vmax[0], c_int(ierflag)) minuit.mnparm(1, "recovery rate", vinit[1], vstep[1], vmin[1], vmax[1], c_int(ierflag)) # minuit.SetErrorDef(1.) # minuit.SetMaxIteration(500) # minuit.Migrad() arglist[0] = 500 arglist[1] = 1. # minuit.mnexcm( "MIGRAD", arglist, 2, c_int(ierflag) ) res_trans = c_double(0.) res_rec = c_double(0.) err_trans = c_double(0.) err_rec = c_double(0.) minuit.GetParameter(0, res_trans, err_trans) minuit.GetParameter(1, res_rec, err_rec) # return res_trans.value, res_rec.value hists = self.solve_SIR(res_trans.value, res_rec.value, time_range) self.hists = { "susceptible": hists[0], "infected": hists[1], "recovered": hists[2] } self.draw()
def __init__(self, number_of_parameters, function_to_minimize, parameter_names, start_parameters, parameter_errors, quiet=True, verbose=False): ''' Create a Minuit minimizer for a function `function_to_minimize`. Necessary arguments are the number of parameters and the function to be minimized `function_to_minimize`. The function `function_to_minimize`'s arguments must be numerical values. The same goes for its output. Another requirement is for every parameter of `function_to_minimize` to have a default value. These are then used to initialize Minuit. **number_of_parameters** : int The number of parameters of the function to minimize. **function_to_minimize** : function The function which `Minuit` should minimize. This must be a Python function with <``number_of_parameters``> arguments. **parameter_names** : tuple/list of strings The parameter names. These are used to keep track of the parameters in `Minuit`'s output. **start_parameters** : tuple/list of floats The start values of the parameters. It is important to have a good, if rough, estimate of the parameters at the minimum before starting the minimization. Wrong initial parameters can yield a local minimum instead of a global one. **parameter_errors** : tuple/list of floats An initial guess of the parameter errors. These errors are used to define the initial step size. *quiet* : boolean (optional, default: ``True``) If ``True``, suppresses all output from ``TMinuit``. *verbose* : boolean (optional, default: ``False``) If ``True``, sets ``TMinuit``'s print level to a high value, so that all output is logged. ''' #: the name of this minimizer type self.name = "ROOT::TMinuit" #: the actual `FCN` called in ``FCN_wrapper`` self.function_to_minimize = function_to_minimize #: number of parameters to minimize for self.number_of_parameters = number_of_parameters if not quiet: self.out_file = open(log_file("minuit.log"), 'a') else: self.out_file = null_file() # create a TMinuit instance for that number of parameters self.__gMinuit = TMinuit(self.number_of_parameters) # instruct Minuit to use this class's FCN_wrapper method as a FCN self.__gMinuit.SetFCN(self.FCN_wrapper) # set print level according to flag if quiet: self.set_print_level(-1000) # suppress output elif verbose: self.set_print_level(10) # detailed output else: self.set_print_level(0) # frugal output # initialize minimizer self.set_err() self.set_strategy() self.set_parameter_values(start_parameters) self.set_parameter_errors(parameter_errors) self.set_parameter_names(parameter_names) #: maximum number of iterations until ``TMinuit`` gives up self.max_iterations = M_MAX_ITERATIONS #: ``TMinuit`` tolerance self.tolerance = M_TOLERANCE