from iminuit import Minuit def cost(x, y, z): return (x - 1) ** 2 + (y - x) ** 2 + (z - 2) ** 2 cost.errordef = Minuit.LEAST_SQUARES m = Minuit(cost, x=0, y=0, z=0) m.migrad() m.draw_mnprofile("y")
def test_typo(): with pytest.raises(RuntimeError): Minuit(func4, printlevel=0)
def test_minos_single_nonsense_variable(): m = Minuit(func3, pedantic=False, print_level=0) m.migrad() with pytest.raises(RuntimeError): m.minos('nonsense')
def fit_ringdown(int_index): #print fterm_prior, fterm_prior_width t_mean = np.mean(all_time[int_index]) t_last = np.max(all_time[int_index]) + 0.25 # bu.progress_bar(i, last_ind+1) fit_inds = all_time_flat < t_last derp_inds = all_time_flat < fit_end_time npts = np.sum(fit_inds) xdat = all_time_flat[fit_inds] ydat = all_freq_flat[fit_inds] yerr = all_freq_err_flat[fit_inds] #yerr = np.sqrt(ydat) #yerr = np.random.randn(npts) * np.std(yerr) + np.mean(yerr) if priors: fterm_init = prior_data[0] def chisquare_1d(tau, fterm): resid = ydat - fit_fun(xdat, t0_line, tau, fterm) prior = (fterm - prior_data[0])**2 / prior_data[1]**2 chisq = (1.0 / (npts - 1.0)) * np.sum(resid**2 / yerr**2) return chisq + prior elif manual_priors: fterm_init = fterm_prior def chisquare_1d(tau, fterm): resid = ydat - fit_fun(xdat, t0_line, tau, fterm) prior = (fterm - fterm_prior)**2 / fterm_prior_width**2 chisq = (1.0 / (npts - 1.0)) * np.sum(resid**2 / yerr**2) return chisq + prior else: fterm_init = 0.0 def chisquare_1d(tau, fterm): resid = ydat - fit_fun(xdat, t0_line, tau, fterm) chisq = (1.0 / (npts - 1.0)) * np.sum(resid**2 / yerr**2) return chisq # m=Minuit(chisquare_1d, # f0=50000.0, # tau = 1500.0, # set start parameter # limit_tau = (500.0, 4000.0), # if you want to limit things # #fix_a = "True", # you can also fix it # fopt = 1000.0, # limit_fopt = (0.0, 10000.0), # errordef = 1, # print_level = 0, # pedantic=False) # m.migrad(ncall=500000) m2 = Minuit( chisquare_1d, #t0 = 0.0, #fix_t0 = t0_line, #limit_t0 = (-5, 5), tau=two_point_tau, # set start parameter #fix_tau = True, #limit_tau = (500.0, 4000.0), # if you want to limit things fterm=fterm_init, # set start parameter fix_fterm=fix_fterm, # limit_tau = (500.0, 4000.0), # if you want to limit things #fix_a = "True", # you can also fix it # limit_fopt = (0.0, 10000.0), errordef=1, print_level=0, pedantic=False) m2.migrad(ncall=500000) # plt.figure() # m.draw_mnprofile('tau', bound = 3, bins = 50) # plt.figure() # m2.draw_mnprofile('tau', bound = 3, bins = 50) # plt.show() # p0 = [f0, 1500.0, 1000.0] # popt = [m2.values['t0'], m2.values['tau'], m2.values['fterm']] # # print tau_many # # print tau_many_2 # if m.values['tau'] < 1200: # plt.figure() # plt.plot(all_time_flat[derp_inds], all_freq_flat[derp_inds]) # plt.plot(all_time_flat[fit_inds], all_freq_flat[fit_inds]) # plt.plot(all_time_flat[derp_inds], exp_decay(all_time_flat[derp_inds], *p0), '--', \ # color='k', lw=4, alpha=0.5) # plt.plot(all_time_flat[derp_inds], exp_decay(all_time_flat[derp_inds], *popt), '--', \ # color='r', lw=4, alpha=0.5) # plt.figure() # plt.plot(yerr) # plt.show() try: minos = m2.minos() return [t_mean, minos['tau']['min'], minos['tau']['upper'], \ minos['tau']['lower'], minos['fterm']['min']] except: return [t_mean, m2.values['tau'], m2.errors['tau'], \ m2.errors['tau'], m2.values['fterm']]
m = Minuit( least_squares, CONC=params["CONC"]["value"], SPIN=params["SPIN"]["value"], B=params["B"]["value"], DIF=params["DIF"]["value"], TAUS0=params["TAUS0"]["value"], TAUV=params["TAUV"]["value"], PROPT=params["PROPT"]["value"], gl=params["gl"]["value"], limit_CONC=(float(params["CONC"]["minM"]), float(params["CONC"]["maxM"])), limit_SPIN=(float(params["SPIN"]["minM"]), float(params["SPIN"]["maxM"])), limit_B=(float(params["B"]["minM"]), float(params["B"]["maxM"])), limit_DIF=(float(params["DIF"]["minM"]), float(params["DIF"]["maxM"])), limit_TAUS0=(float(params["TAUS0"]["minM"]), float(params["TAUS0"]["maxM"])), limit_TAUV=(float(params["TAUV"]["minM"]), float(params["TAUV"]["maxM"])), limit_PROPT=(float(params["PROPT"]["minM"]), float(params["PROPT"]["maxM"])), limit_gl=(float(params["gl"]["minM"]), float(params["gl"]["maxM"])), fix_CONC=params["CONC"]["fixed"], fix_SPIN=params["SPIN"]["fixed"], fix_B=params["B"]["fixed"], fix_DIF=params["DIF"]["fixed"], fix_TAUS0=params["TAUS0"]["fixed"], fix_TAUV=params["TAUV"]["fixed"], fix_PROPT=params["PROPT"]["fixed"], fix_gl=params["gl"]["fixed"], )
def minimise(self, params, step, limits, minimiser_name="minuit"): """ Parameters ---------- params step limits minimiser_name Returns ------- """ if minimiser_name == "minuit": min = Minuit(self.get_likelihood, print_level=1, source_x=params[0], error_source_x=step[0], limit_source_x=limits[0], source_y=params[1], error_source_y=step[1], limit_source_y=limits[1], core_x=params[2], error_core_x=step[2], limit_core_x=limits[2], core_y=params[3], error_core_y=step[3], limit_core_y=limits[3], energy=params[4], error_energy=step[4], limit_energy=limits[4], x_max_scale=params[5], error_x_max_scale=step[5], limit_x_max_scale=limits[5], fix_x_max_scale=False, errordef=1) min.migrad() min.tol *= 1000 min.set_strategy(0) # Perform minimisation fit_params = min.values errors = min.errors return (fit_params["source_x"], fit_params["source_y"], fit_params["core_x"], fit_params["core_y"], fit_params["energy"], fit_params[ "x_max_scale"]),\ (errors["source_x"], errors["source_y"], errors["core_x"], errors["core_x"], errors["energy"], errors["x_max_scale"]) elif minimiser_name in ("lm", "trf", "dogleg"): self.array_return = True min = least_squares(self.get_likelihood_min, params, method=minimiser_name, x_scale=step, xtol=1e-10, ftol=1e-10 ) return min.x, (0, 0, 0, 0, 0, 0) else: min = minimize(self.get_likelihood_min, params, method=minimiser_name, bounds=limits ) return min.x, (0, 0, 0, 0, 0, 0)
prob = np.loadtxt(f'{photon_base_path}/prob{i:03.0f}.dat') for j in range(nsim): loglikes[j, 0] = - gta.like() p = prob[j] def cost_func_alps(norm, alpha, beta): dnde = p * norm * 1.0e-11 * np.power((x / Eb) , -(alpha + beta * 1.0e-1 * np.log((x / Eb)))) gta.set_source_dnde(source, dnde) return gta.like() def cost_func(norm, alpha, beta): dnde = norm * 1.0e-11 * np.power((x / Eb) , -(alpha + beta * 1.0e-1 * np.log((x / Eb)))) gta.set_source_dnde(source, dnde) return gta.like() m = Minuit(cost_func_alps, errordef=0.5, norm=norm, alpha=alpha, beta=beta,\ error_norm=norm_err, error_alpha=alpha_err, error_beta=beta_err,\ limit_norm=(0, 100), limit_alpha=(-5, 5), limit_beta=(-5, 10), print_level=1) r = m.migrad() loglikes[j, 1] = -gta.like() gta.fit(opimizer='NEWMINUIT', reoptimize=True) loglikes[j, 2] = -gta.like() m = Minuit(cost_func_alps, errordef=0.5, norm=norm, alpha=alpha, beta=beta,\ error_norm=norm_err, error_alpha=alpha_err, error_beta=beta_err,\ limit_norm=(0, 100), limit_alpha=(-5, 5), limit_beta=(-5, 10), print_level=1) r = m.migrad() loglikes[j, 3] = -gta.like() gta.fit(opimizer='NEWMINUIT', reoptimize=True) loglikes[j, 4] = -gta.like() try: gta.load_roi(roi_file) except:
def chi2_fit(func, x, y, yerr, get_values=False, pedantic=False, print_level=0, latex_format=False, **kwdarg): ''' ChiSquare fit of a given function to a given data set. Returns the fitted parameters for further plotting. **kwdarg allows the user to specify initial parameter values and fix values using the syntax from Minuit ''' chi2obj = Chi2Regression(func, x, y, yerr) minuit_obj = Minuit(chi2obj, pedantic=pedantic, print_level=print_level, **kwdarg) minuit_obj.migrad() if (not minuit_obj.get_fmin().is_valid): # Check if the fit converged print(" WARNING: The ChiSquare fit DID NOT converge!!!") Chi2_value = minuit_obj.fval # The Chi2 value NvarModel = len(minuit_obj.args) Ndof = len(x) - NvarModel ProbChi2 = stats.chi2.sf(Chi2_value, Ndof) if latex_format: print( r'''---------------------------------------------------------------------------------- NB! Units, caption, label and sometimes parameter names must be changed in LaTex. ---------------------------------------------------------------------------------- \begin{table}[b] \centering \begin{tabular}{lrr} \hline \hline Parameter & Value (Unit) & Unc. (Unit) \\ \hline''') for name in minuit_obj.parameters: print( f' ${name}$ & ${minuit_obj.values[name]:.5f}$ & ${minuit_obj.errors[name]:.5f}$ \\\ ' ) print(r''' \hline \hline''') print( r' $\chi^2$-value = {0:.3f} & Ndof = {1} & $\chi^2$-prob = {2:.3f} \\' .format(Chi2_value, Ndof, ProbChi2)) print(r''' \hline \hline \end{tabular} \caption{Results of $\chi^2$-fit.} \label{tab:chi2_fit} \end{table}''') else: print(f''' _____________________________________________________ ----------------------------------------------------- ChiSquare Fit Results ----------------------------------------------------- Chi2-value = {Chi2_value:.3f} Ndof = {Ndof} Chi2-prob = {ProbChi2:.2%} -----------------------------------------------------''') for name in minuit_obj.parameters: print( f'\n Chi2 Fit result: {name} = {minuit_obj.values[name]:.5f} +/- {minuit_obj.errors[name]:.5f}' ) print(' _____________________________________________________') if get_values: return minuit_obj.args, Chi2_value, Ndof, ProbChi2 else: return minuit_obj.args
def minuit(): m = Minuit(lambda x: x**2, pedantic=False) m.migrad() return m
def fit_muon(self, centre_x, centre_y, radius, pixel_x, pixel_y, image): """ Parameters ---------- centre_x: float Centre of muon ring in the field of view from circle fitting centre_y: float Centre of muon ring in the field of view from circle fitting radius: float Radius of muon ring from circle fitting pixel_x: ndarray X position of pixels in image from circle fitting pixel_y: ndarray Y position of pixel in image from circle fitting image: ndarray Amplitude of image pixels Returns ------- MuonIntensityParameters """ # First store these parameters in the class so we can use them in minimisation self.image = image self.pixel_x = pixel_x.to(u.deg) self.pixel_y = pixel_y.to(u.deg) self.unit = pixel_x.unit radius.to(u.deg) centre_x.to(u.deg) centre_y.to(u.deg) # Return interesting stuff fitoutput = MuonIntensityParameter() init_params = {} init_errs = {} init_constrain = {} init_params['impact_parameter'] = 4. init_params['phi'] = 0. init_params['radius'] = radius.value init_params['centre_x'] = centre_x.value init_params['centre_y'] = centre_y.value init_params['ring_width'] = 0.1 init_params['optical_efficiency_muon'] = 0.1 init_errs['error_impact_parameter'] = 2. init_constrain['limit_impact_parameter'] = (0., 25.) init_errs['error_phi'] = 0.1 init_errs['error_ring_width'] = 0.001 * radius.value init_errs['error_optical_efficiency_muon'] = 0.05 init_constrain['limit_phi'] = (-np.pi, np.pi) init_constrain['fix_radius'] = True init_constrain['fix_centre_x'] = True init_constrain['fix_centre_y'] = True init_constrain['limit_ring_width'] = (0., 1.) #init_constrain['limit_optical_efficiency_muon'] = (0., 1.) # Unneeded constraint - and misleading in case of changes leading to >1 values! logger.debug("radius = %3.3f pre migrad", radius) # Create Minuit object with first guesses at parameters # strip away the units as Minuit doesnt like them minuit = Minuit( self.likelihood, # forced_parameters=parameter_names, **init_params, **init_errs, **init_constrain, errordef=0.1, print_level=0, pedantic=False ) # Perform minimisation minuit.migrad() # Get fitted values fit_params = minuit.values fitoutput.impact_parameter = fit_params['impact_parameter'] * u.m # fitoutput.phi = fit_params['phi']*u.rad fitoutput.impact_parameter_pos_x = fit_params['impact_parameter'] * np.cos( fit_params['phi'] * u.rad) * u.m fitoutput.impact_parameter_pos_y = fit_params['impact_parameter'] * np.sin( fit_params['phi'] * u.rad) * u.m fitoutput.ring_width = fit_params['ring_width'] * self.unit fitoutput.optical_efficiency_muon = fit_params['optical_efficiency_muon'] fitoutput.prediction = self.prediction return fitoutput
def gauss_pdf(x, mu, sigma): """Normalized Gaussian""" return 1 / np.sqrt(2 * np.pi) / sigma * np.exp( -(x - mu)**2 / 2. / sigma**2) def gauss_extended(x, N, mu, sigma): """Non-normalized Gaussian""" return N * gauss_pdf(x, mu, sigma) chi_A_ill = Chi2Regression(gauss_extended, x, y, sy) minuit_ill = Minuit(chi_A_ill, pedantic=False, N=len(A_ill), mu=A_ill_mean, sigma=A_ill_sigma) minuit_ill.migrad() print(minuit_ill.fval) #Ndof = 120-*minuit_ill.args prob = stats.chi2.sf(minuit_ill.fval, (65 - len(minuit_ill.args))) print(prob) xaxis = np.linspace(0.0, 30, 1000) yaxis = gauss_extended(xaxis, *minuit_ill.args) names = [ 'Distribution of A ill:', 'Entries', 'Mean', 'RMS', "Chi2/Ndof", "Prob" ] values = [ "", "{:d}".format(len(A_ill)), "{:.3f}".format(x.mean()),
chisq = 0 for t in range(24, len(epos), 1): model_PWN = eta * funcinterpolate(epos[t], gamma) model_DM = np.power(epos[t],3.)*sigma_v_normalization*DM.DM_spectrum(epos[t], DM_mass, channel)[0]/np.power(10.,-26) model_sec = PWN.flux_secondary(epos[t], normalization_sec) model_tot = model_PWN + model_sec + model_DM chisq = chisq + np.power((model_tot - pos[t]) / errortot_pos[t], 2.) return chisq # Define an empty array of chisquare values from the the cross section array chisquare_arr = np.zeros((len(channel_arr), len(sigma_exp_arr))) upperlim_arr = np.zeros((len(channel_arr))) for i, DMchannel in enumerate(channel_arr): for j, sigma_exp in enumerate(sigma_exp_arr): m = Minuit(f_BPL_DM, par0=0.06, par1=1.44, par2=1.26, par3=sigma_exp) m.errors['par0'] = 0.06 m.errors['par1'] = 0.03 m.errors['par2'] = 0.02 m.errors['par3'] = 1e-4 m.limits['par0'] = (-10.0, 10.) m.limits['par1'] = (0., 5.) m.limits['par2'] = (0.1, 10.) m.limits['par3'] = (-29, 20) m.fixed['par3'] = True m.errordef = 1 m.migrad() print('value', m.values) print('error', m.errors) print('fval', m.fval) chisquare_arr[i, j] = m.fval
def main(): global Count x0 = np.array([ 0.301670059774, 0.994252132593, 0.00230538402151, 0.00590002382274, 0.8945971901, 0.464840905602, 8.25381559741, 3.94217843788, NearMean[0], NearMean[1], NearMean[2], FarMean[0], FarMean[1], FarMean[2], OldFarMean[0], OldFarMean[1], OldFarMean[2], 0.00453978243062, 0.10091505595897542, 0.0024079639515751355 ]) print "Make sure you have the proton normalization for the fiducial cut and the spill in/spill out normalization correctly." print "Minimizing" #res = minimize(SimplexFunc, x0, method='Powell', options={'xtol': 1e-8, 'disp': True}) Count = 0 #LOOK AT NEAR CUT print "MAKE SURE NEARDET IS SET TO TRUE IF NEAR DETECTOR ANALYSIS and UNCOMMENT OUT LIKELIHOODS" m = Minuit( LogLikelihood, SSTT13=0.12054415908568761, M13=0.0025043194579322248, Li9Rate=1.1244941107796325, FNSMRate=0.43741890871782574, NearLi9Rate=7.901068678691314, NearFNSMRate=3.7788535947724244, error_SSTT13=5., limit_SSTT13=(0., 1.), limit_M13=(0., 1.), limit_Li9Rate=(0., 10.), limit_FNSMRate=(0., 1.), limit_NearLi9Rate=(0., 10.), limit_NearFNSMRate=(0., 10.), error_Li9Rate=4., error_FNSMRate=4., error_M13=2.e-2, error_NearLi9Rate=4., error_NearFNSMRate=4., errordef=1., #fix_NearLi9Rate=True, fix_NearFNSMRate = True, BumpNorm=0.011238038728963017, error_BumpNorm=1., fix_BumpNorm=True, NearNorm_A=3.969585771201878e-11, NearNorm_B=0.0, NearNorm_C=0.0, limit_NearNorm_A=(0., 1.), limit_NearNorm_B=(0., 1.), #limit_NearNorm_A=(0., 10.), limit_NearNorm_B=(0., 10.), limit_NearNorm_C=(0., 10.), NearAcc=0.575028741826883, error_NearAcc=1.5, #fix_NearAcc=True, error_NearNorm_A=4., error_NearNorm_B=4., error_NearNorm_C=5., #fix_NearNorm_A=True, fix_NearNorm_B=True, fix_NearNorm_C=True, #fix_NearLi9Rate=True, fix_NearFNSMRate=True, Near_A=-0.004116474803739965, Near_B=1.0018032274975033, Near_C=-1.7993784835962714e-07, error_Near_A=3., error_Near_B=.1, error_Near_C=1.e-5, Far_A=-0.012606607718833054, Far_B=1.0056769330102382, Far_C=-3.662679490821011e-08, error_Far_A=1., error_Far_B=.1, error_Far_C=1.e-5, Old_Far_A=-0.012601515890730806, Old_Far_B=1.0056896190670936, Old_Far_C=-1.0659506576591107e-07, error_Old_Far_A=1., error_Old_Far_B=.1, #Near_A = NearMean[0], Near_B = NearMean[1], Near_C = NearMean[2], error_Near_A = 3., error_Near_B=.1, error_Near_C=1.e-5, #Far_A = FarMean[0], Far_B = FarMean[1], Far_C = FarMean[2], error_Far_A = 1., error_Far_B=.1, error_Far_C=1.e-5, #Old_Far_A = OldFarMean[0], Old_Far_B = OldFarMean[1], Old_Far_C = OldFarMean[2], error_Old_Far_A = 1., error_Old_Far_B=.1, error_Old_Far_C=1.e-5, #fix_Near_A=True, fix_Near_B=True, fix_Near_C=True, #fix_Far_A=True, fix_Far_B=True, fix_Far_C=True, fix_Old_Far_A=True, fix_Old_Far_B=True, fix_Old_Far_C=True #fix_SSTT13=True, fix_M13=True, fix_Li9Rate=True, fix_FNSMRate=True, fix_NearLi9Rate=True, #fix_Near_A=True, fix_Near_B=True, fix_Near_C=True, #fix_Far_A=True, fix_Far_B=True, fix_Far_C=True, fix_Old_Far_A=True, #fix_Old_Far_B=True, fix_Old_Far_C=True, limit_Near_A=(NearMean[0] - 5. * np.sqrt(NearCov[0][0]), NearMean[0] + 5. * np.sqrt(NearCov[0][0])), limit_Near_B=(NearMean[1] - 5. * np.sqrt(NearCov[1][1]), NearMean[1] + 5. * np.sqrt(NearCov[1][1])), limit_Near_C=(NearMean[2] - 5. * np.sqrt(NearCov[2][2]), NearMean[2] + 5. * np.sqrt(NearCov[2][2])), limit_Far_A=(FarMean[0] - 5. * np.sqrt(FarCov[0][0]), FarMean[0] + 5. * np.sqrt(FarCov[0][0])), limit_Far_B=(FarMean[1] - 5. * np.sqrt(FarCov[1][1]), FarMean[1] + 5. * np.sqrt(FarCov[1][1])), limit_Far_C=(FarMean[2] - 5. * np.sqrt(FarCov[2][2]), FarMean[2] + 5. * np.sqrt(FarCov[2][2])), limit_Old_Far_A=(OldFarMean[0] - 5. * np.sqrt(OldFarCov[0][0]), OldFarMean[0] + 5. * np.sqrt(OldFarCov[0][0])), limit_Old_Far_B=(OldFarMean[1] - 5. * np.sqrt(OldFarCov[1][1]), OldFarMean[1] + 5. * np.sqrt(OldFarCov[1][1])), limit_Old_Far_C=(OldFarMean[2] - 5. * np.sqrt(OldFarCov[2][2]), OldFarMean[2] + 5. * np.sqrt(OldFarCov[2][2]))) m.migrad() m.print_param() print('value', m.values) print('covariance', m.covariance) #m.profile('SSTT13') mi = .07 ma = .14 d = .001 N = int((ma - mi) / d) '''
a0=-3000, error_a0=100, alphas=1.18400000e-01, fix_alphas=True, invalpha=1.27944000e+02, fix_invalpha=True, m0=400, error_m0=100, m12=900, error_m12=100, mb=4.18000000e+00, fix_mb=True, mt=1.74500000e+02, fix_mt=True, signmu=1, fix_signmu=True, tanb=11, error_tanb=3, lambda=0.1, error_lambda=0.1, errordef=1, ) # Set Minuit likelihood function. m = Minuit(chisquared, **kwdarg) # Run migrad. m.migrad() print m.values print m.errors
def get_corrfunc(x, x_err=None, n_frac=2, viz=True, model=False, est=False): """ Auto correlation of a signal and mean estimation Parameters x : samples of the first variable x_err : error vector for the first variable n_frac : number of pixels over which to estiamte correlation wrt the size of the samples viz : plot the correlation function model : model the correlation function est : Get estimates on the best-fit values using the covariance matrices estmated Returns: loc, sig : the mean and uncertainty on the location parameter """ npp = len(x) coef = [ np.corrcoef(x[:npp - j], x[j:])[0, 1] for j in range(npp // n_frac) ] if viz: fig, ax = plt.subplots(1) ax.plot(coef, '-k') if model: def model_func(x, cl): # A simple exponential model return np.exp(-x / cl) popt, __ = curve_fit(model_func, np.arange(npp // n_frac)[:20], coef[:20]) if viz: x_plot = np.linspace(0, 50, 50) ax.plot(x_plot, model_func(x_plot, *popt), '-r') ax.text(10, 0.8, "$r_{x_0}=%.1f$" % popt[0]) ax.set_xlim(0, 50) if est: if x_err is None: raise TypeError("Requires errorbars on the samples") # Obtain band-diagonal correlation matrix from scipy.linalg import toeplitz Xi = toeplitz(model_func(np.arange(npp), *popt)) # Covariance matrix from errorbars and correlation matrix # C = D * Xi * D.T cov = np.diag(x_err).dot(Xi.dot(np.diag(x_err))) # Minimization using iminuit from iminuit import Minuit ico = np.linalg.inv(cov) def chi2(mu): dyi = x - mu return dyi.T.dot(ico.dot(dyi)) mm = Minuit(chi2, mu=x.mean(), error_mu=x.std(), fix_mu=False, errordef=1., print_level=-1) mm.migrad() loc, sig = mm.values["mu"], mm.errors["mu"] if viz: fig, ax = plt.subplots(figsize=(9, 3)) ax.plot(x) ax.fill_between(np.arange(npp), loc + sig, loc - sig, color='r', alpha=0.2) return loc, sig
def test_default_errordef(): with pytest.warns(DeprecationWarning): Minuit(Fcn(), pedantic=False)
def fit_model(charges, model, startparams=None, \ rej_outliers=False, nbins=200, \ silent=False,\ parameter_text=((r"$\mu_{{SPE}}$& {:4.2e}\\", 5),), use_minuit=False,\ normalize=True,\ **kwargs): """ Standardazied fitting routine Args: charges (np.ndarray): Charges obtained in a measurement (no histogram) model (pyevsel.fitting.Model): A model to fit to the data startparams (tuple): initial parameters to model, or None for first guess Keyword Args: rej_outliers (bool): Remove extreme outliers from data nbins (int): Number of bins parameter_text (tuple): will be passed to model.plot_result use_miniuit (bool): use minuit to minimize startparams for best chi2 normalize (bool): normalize data before fitting silent (bool): silence output Returns: tuple """ if rej_outliers: charges = reject_outliers(charges) if use_minuit: from iminuit import Minuit # FIXME!! This is too ugly. Minuit wants named parameters ... >.< assert len(startparams) < 10; "Currently more than 10 paramters are not supported for minuit fitting!" assert model.all_coupled, "Minuit fitting can only be done for models with all parmaters coupled!" names = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"] funcstring = "def do_min(" for i,__ in enumerate(startparams): funcstring += names[i] + "," funcstring = funcstring[:-1] + "):\n" funcstring += "\tmodel.startparams = (" for i,__ in enumerate(startparams): funcstring += names[i] + "," funcstring = funcstring[:-1] + ")\n" funcstring += "\tmodel.fit_to_data(charges, nbins, silent=True, **kwargs)" funcstring += "\treturn model.chi2_ndf" #def do_min(a, b, c, d, e, f, g, h, i, j, k): #FIXME!!! # model.startparams = (a, b, c, d, e, f, g, h, i, j, k) # model.fit_to_data(charges, nbins, silent=True, **kwargs) # return model.chi2_ndf exec(funcstring) bnd = kwargs["bounds"] if "bounds" in kwargs: min_kwargs = dict() for i,__ in enumerate(startparams): min_kwargs["limit_" + names[i]] =(bnd[0][i],bnd[1][i]) m = Minuit(do_min, **min_kwargs) #m = Minuit(do_min, limit_a=(bnd[0][0],bnd[1][0]), # limit_b=(bnd[0][1],bnd[1][1]), # limit_c=(bnd[0][2],bnd[1][2]), # limit_d=(bnd[0][3],bnd[1][3]), # limit_e=(bnd[0][4],bnd[1][4]), # limit_f=(bnd[0][5],bnd[1][5]), # limit_g=(bnd[0][6],bnd[1][6]), # limit_h=(bnd[0][7],bnd[1][7]), # limit_i=(bnd[0][8],bnd[1][8]), # limit_j=(bnd[0][9],bnd[1][9]), # limit_k=(bnd[0][10],bnd[1][10])) else: m = Minuit(do_min) # hand over the startparams for key, value in zip(["a","b","c","d","e","f","g","h","i","j"], startparams): m.values[key] = value m.migrad() else: model.startparams = startparams model.fit_to_data(charges, nbins,normalize=normalize, silent=silent, **kwargs) # check for named tuple if hasattr(startparams, "_make"): # duck typing best_fit_params = startparams._make(model.best_fit_params) else: best_fit_params = model.best_fit_params print("Best fit parameters {}".format(best_fit_params)) return model
"""Use iminuit to find the minimum of a 3D scalar field""" from vedo import show, Point, Line, printc from iminuit import Minuit # pip install iminuit # https://github.com/scikit-hep/iminuit import numpy as np def fcn(x, y, z): f = (x - 4)**4 + (y - 3)**4 + (z - 2)**2 if not vals or f < vals[-1]: path.append([x, y, z]) vals.append(f) return f paths = [] for x, y, z in np.random.rand(200, 3) * 3: path, vals = [], [] m = Minuit(fcn, x=x, y=y, z=z) m.errordef = m.LEAST_SQUARES # m.simplex() # run simplex optimiser m.migrad() # run migrad optimiser line = Line(path).cmap('jet_r', vals).lw(2).alpha(0.25) paths.append(line) printc('Last optimization output:', c='green7', invert=1) printc(m, c='green7', italic=1) show(paths, Point([4, 3, 2]), __doc__, axes=1).close()
def __call__(self, tel_id, center_x, center_y, radius, image, pedestal, mask=None): """ Parameters ---------- center_x: Angle quantity Initial guess for muon ring center in telescope frame center_y: Angle quantity Initial guess for muon ring center in telescope frame radius: Angle quantity Radius of muon ring from circle fitting pixel_x: ndarray X position of pixels in image from circle fitting pixel_y: ndarray Y position of pixel in image from circle fitting image: ndarray Amplitude of image pixels mask: ndarray mask marking the pixels to be used in the likelihood fit Returns ------- MuonEfficiencyContainer """ telescope = self.subarray.tel[tel_id] if telescope.optics.num_mirrors != 1: raise NotImplementedError( "Currently only single mirror telescopes" f" are supported in {self.__class__.__name__}") negative_log_likelihood = build_negative_log_likelihood( image, telescope, mask, oversampling=self.oversampling.tel[tel_id], min_lambda=self.min_lambda_m.tel[tel_id] * u.m, max_lambda=self.max_lambda_m.tel[tel_id] * u.m, spe_width=self.spe_width.tel[tel_id], pedestal=pedestal, hole_radius=self.hole_radius_m.tel[tel_id] * u.m, ) initial_guess = create_initial_guess(center_x, center_y, radius, telescope) step_sizes = {} step_sizes["error_impact_parameter"] = 0.5 step_sizes["error_phi"] = np.deg2rad(0.5) step_sizes["error_ring_width"] = 0.001 * radius.to_value(u.rad) step_sizes["error_optical_efficiency_muon"] = 0.05 constraints = {} constraints["limit_impact_parameter"] = (0, None) constraints["limit_phi"] = (-np.pi, np.pi) constraints["fix_radius"] = True constraints["fix_center_x"] = True constraints["fix_center_y"] = True constraints["limit_ring_width"] = (0.0, None) constraints["limit_optical_efficiency_muon"] = (0.0, None) # Create Minuit object with first guesses at parameters # strip away the units as Minuit doesnt like them minuit = Minuit( negative_log_likelihood, # forced_parameters=parameter_names, **initial_guess, **step_sizes, **constraints, errordef=0.5, print_level=0, pedantic=True, ) # Perform minimisation minuit.migrad() # Get fitted values result = minuit.values return MuonEfficiencyContainer( impact=result["impact_parameter"] * u.m, impact_x=result["impact_parameter"] * np.cos(result["phi"]) * u.m, impact_y=result["impact_parameter"] * np.sin(result["phi"]) * u.m, width=u.Quantity(np.rad2deg(result["ring_width"]), u.deg), optical_efficiency=result["optical_efficiency_muon"], )
def fit_sample(df_mbinfos, j): df_results = pd.DataFrame(columns=\ ['accountid','principal','oriinuldegdel','term','month0','month1', 'rate_mean','rate_error','month0_mean','month1_mean','fval','payment_pred', 'grace4','month3','month4','fval3','fval4', 'payment_prin_mean3']) i = 0 accountid, principal, term, months, oriinuldegdel = create_prod_df( df_mbinfos, j) print(accountid, principal, term, months, oriinuldegdel) global term_corr term_corr = term global principal_corr principal_corr = principal months_corr = [month + 0 for month in months] months_corr = months_corr[-1:] print(months_corr, principal_corr) global oriinuldegdel_corr oriinuldegdel_corr = oriinuldegdel[-1:] months_min = months[0] - 1 months_max = months[0] + 1 if months_min < 0: months_min = 0 start = time.time() m1 = Minuit( func_total_LL_two, rate=18.0, error_rate=0.1, limit_rate=(12, 25), month0=months[0], error_month0=0.1, limit_month0=(months_min, months_max), #month1=months[0], error_month1=1.0, limit_month1=(months[1]-1, months[1]+1), #term=term, error_term=1.0, limit_term=(term-2,term+2), errordef=1) m1.migrad() end = time.time() print("m1 {} {}".format(j, end - start)) start = time.time() m2 = Minuit( func_total_LL_two, rate=8.0, error_rate=0.1, limit_rate=(3, 10), month0=months[0], error_month0=1.0, limit_month0=(months_min, months_max), #month1=months[0], error_month1=1.0, limit_month1=(months[1]-1, months[1]+1), #term=term, error_term=1.0, limit_term=(term-2, term+2), errordef=1) m2.migrad() end = time.time() print("m2 {} {}".format(j, end - start)) start = time.time() m3 = Minuit( func_principal_LL_one, #grace=0.0, error_grace=0.1, limit_grace=(0.0, 12.0), month0=months[0], error_month0=0.1, limit_month0=(months_min, months_max), #month1=months[0], error_month1=1.0, limit_month1=(months[1]-1, months[1]+1), #term=term, error_term=1.0, limit_term=(term-2, term+2), errordef=1) m3.migrad() end = time.time() print("m3 {} {}".format(j, end - start)) fval1 = float(m1.get_fmin()['fval']) fval2 = float(m2.get_fmin()['fval']) log_fval1 = np.log(fval1 + 1) log_fval2 = np.log(fval2 + 1) log_fval_ratio = log_fval1 / log_fval2 month0_mean = months[0] month1_mean = 0 #months[1] fval3 = float(m3.get_fmin()['fval']) month3 = round(float(m3.fitarg['month0'])) payment_prin_mean3 = float(principal) * 0.20 / 12.0 + float( principal) / term_corr payment_prin_max3 = float(principal) * 0.25 / 12.0 + float( principal) / term_corr if log_fval_ratio > 50.0: error_rate = float(m2.fitarg['error_rate']) rate_mean = float(m2.fitarg['rate']) month0_mean = round(float(m2.fitarg['month0'])) #month1_mean = round(float(m2.fitarg['month0'])+months[1]-months[0]) fval = float(m2.get_fmin()['fval']) else: error_rate = float(m1.fitarg['error_rate']) rate_mean = float(m1.fitarg['rate']) month0_mean = round(float(m1.fitarg['month0'])) #month1_mean = round(float(m1.fitarg['month0'])+months[1]-months[0]) fval = float(m1.get_fmin()['fval']) df_results.loc[i, 'accountid'] = accountid df_results.loc[i, 'principal'] = float(principal) df_results.loc[i, 'oriinuldegdel'] = oriinuldegdel_corr df_results.loc[i, 'term'] = float(term_corr) df_results.loc[i, 'month0'] = months[0] df_results.loc[i, 'month1'] = 0 #months[1] df_results.loc[i, 'rate_error'] = error_rate df_results.loc[i, 'rate_mean'] = rate_mean df_results.loc[i, 'month0_mean'] = month0_mean df_results.loc[i, 'month1_mean'] = month1_mean df_results.loc[i, 'fval'] = fval payment_pred=df_results.loc[i:i].apply\ (lambda row: utils.pmt(row['principal'],row['term'],row['rate_mean']),\ axis=1).tolist()[0] df_results.loc[i:i, 'payment_pred'] = payment_pred df_results.loc[i, 'month3'] = round(float(m3.fitarg['month0'])) df_results.loc[i, 'fval3'] = fval3 df_results.loc[i, 'payment_prin_mean3'] = payment_prin_mean3 df_results.loc[i, 'payment_prin_max3'] = payment_prin_max3 i = i + 1 columns_float = [ 'principal', 'term', 'rate_mean', 'rate_error', 'fval', 'fval3', 'payment_pred' ] df_results[columns_float] = df_results[columns_float].astype(float) return df_results
# m.migrad(ncall=500000) # plt.figure() # m.draw_mnprofile('tau', bound = 50, bins = 50) two_point_tau = np.mean(two_point_estimates[-1]) two_point_tau_err = np.std(two_point_estimates[-1]) print(two_point_tau) m = Minuit( chisquare_1d_2, #t0 = 0, #fix_t0 = t0_line, #limit_t0 = (-5, 5), #tau = 2000.0, # set start parameter tau=two_point_tau, #limit_tau = (500.0, 4000.0), # if you want to limit things #fix_tau = True, #fix_a = "True", # you can also fix it fterm=fterm_prior, #limit_fopt = (0.0, 10000.0), errordef=1, print_level=0, pedantic=False) m.migrad(ncall=500000) minos = m.minos() # plt.figure() # m.draw_mnprofile('tau', bound = 5, bins = 50) # plt.show() print() print(file)
#signature dynamically self.func_code = make_func_code(f_sig[1:])#docking off independent variable self.func_defaults = None #this keeps np.vectorize happy def __call__(self,*arg): #notice that it accept variable length #positional arguments chi2 = sum((y-self.f(x,*arg))**2 for x,y in zip(self.x,self.y)) return chi2 def gaussian3(x,p1,p2,p3): g=(p1*exp(-(x-440)**2)+p2*exp(-(x-530)**2)+p3*exp(-(x-620)**2)) return g/sqrt(pi) comp3=Chi2Functor(gaussian3,x,y) describe(comp3) m=Minuit(comp3,p1=1,p2=1,p3=1) m.migrad(); print(m.values) sample_spd_fit = {i:gaussian3(i,m.values['p1'],m.values['p2'],m.values['p3']) for i in x } spd_fit = colour.SpectralPowerDistribution(sample_spd_fit) XYZf = colour.spectral_to_XYZ(spd_fit, cmfs) xy = colour.XYZ_to_xy(XYZ) # Conversion to correlated colour temperature in K. xyf = colour.XYZ_to_xy(XYZf) print("XYZ: ",XYZ) print(xy) print("XYZf: ",XYZf) print(xyf) #print(colour.delta_E(XYZ,XYZf)) # Plotting the *CIE 1931 Chromaticity Diagram*.
Hist_HitMiss_error = np.sqrt(Hist_HitMiss) Hist_HitMiss_indexes = Hist_HitMiss > 0 # Produce a new histogram, using only bins with non-zero entries #---------------------------------------------------------------------------------- # Plot histograms on screen: #---------------------------------------------------------------------------------- fig, ax = plt.subplots(figsize=(10, 5)) ax.set_xlabel("Random number") ax.set_ylabel("Frequency") chi2_object_hitmiss = Chi2Regression( fit_function, Hist_HitMiss_centers[Hist_HitMiss_indexes], Hist_HitMiss[Hist_HitMiss_indexes], Hist_HitMiss_error[Hist_HitMiss_indexes]) minuit_hitmiss = Minuit(chi2_object_hitmiss, p0=20.0, pedantic=False) minuit_hitmiss.migrad() chi2_hitmiss = minuit_hitmiss.fval ndof_hitmiss = chi2_object_hitmiss.ndof prob_hitmiss = stats.chi2.sf(chi2_hitmiss, ndof_hitmiss) p0 = minuit_hitmiss.args x_fit = np.linspace(xmin, xmax, 1000) y_fit_simple = fit_function(x_fit, p0) #ax.plot(x_fit, y_fit_simple, 'b-') names = ['Hit & Miss:', 'Entries', 'Mean', 'RMS'] values = [ "",
def minimise(self, params, step, limits, minimiser_name="minuit", max_calls=0): """ Parameters ---------- params: ndarray Seed parameters for fit step: ndarray Initial step size in the fit limits: ndarray Fit bounds minimiser_name: str Name of minimisation method max_calls: int Maximum number of calls to minimiser Returns ------- tuple: best fit parameters and errors """ limits = np.asarray(limits) if minimiser_name == "minuit": self.min = Minuit( self.get_likelihood, print_level=1, source_x=params[0], error_source_x=step[0], limit_source_x=limits[0], fix_source_x=False, source_y=params[1], error_source_y=step[1], limit_source_y=limits[1], fix_source_y=False, core_x=params[2], error_core_x=step[2], limit_core_x=limits[2], fix_core_x=False, core_y=params[3], error_core_y=step[3], limit_core_y=limits[3], fix_core_y=False, energy=params[4], error_energy=step[4], limit_energy=limits[4], fix_energy=False, x_max_scale=params[5], error_x_max_scale=step[5], limit_x_max_scale=limits[5], fix_x_max_scale=False, goodness_of_fit=False, fix_goodness_of_fit=True, errordef=1, ) self.min.tol *= 1000 self.min.set_strategy(1) migrad = self.min.migrad() fit_params = self.min.values errors = self.min.errors return ( ( fit_params["source_x"], fit_params["source_y"], fit_params["core_x"], fit_params["core_y"], fit_params["energy"], fit_params["x_max_scale"], ), ( errors["source_x"], errors["source_y"], errors["core_x"], errors["core_x"], errors["energy"], errors["x_max_scale"], ), self.min.fval, ) elif "nlopt" in minimiser_name: import nlopt opt = nlopt.opt(nlopt.LN_BOBYQA, 6) opt.set_min_objective(self.get_likelihood_nlopt) opt.set_initial_step(step) opt.set_lower_bounds(np.asarray(limits).T[0]) opt.set_upper_bounds(np.asarray(limits).T[1]) opt.set_xtol_rel(1e-3) if max_calls: opt.set_maxeval(max_calls) x = opt.optimize(np.asarray(params)) return x, (0, 0, 0, 0, 0, 0), self.get_likelihood_min(x) elif minimiser_name in ("lm", "trf", "dogleg"): self.array_return = True min = least_squares( self.get_likelihood_min, params, method=minimiser_name, x_scale=step, xtol=1e-10, ftol=1e-10, ) return min.x, (0, 0, 0, 0, 0, 0), self.get_likelihood_min(min.x) else: min = minimize( self.get_likelihood_min, np.array(params), method=minimiser_name, bounds=limits, options={"disp": False}, tol=1e-5, ) return np.array(min.x), (0, 0, 0, 0, 0, 0), self.get_likelihood_min(min.x)
capthick=1) ax1.set_title('Assignemnt 5.2 - Histogram of residuals with a Gaussian fit') ax1.set_xlabel('Residual') ax1.set_ylabel('Frequency / binwidth = 0.01') # Draw Gaussian: # ------------- def func_Gaussian(x, N, mu, sigma): return N * stats.norm.pdf(x, mu, sigma) Chi2_Gaussian = Chi2Regression(func_Gaussian, x, y, sy) minuit_Gaussian = Minuit(Chi2_Gaussian, pedantic=False, N=len(y), mu=mu, sigma=std) minuit_Gaussian.migrad() # perform the actual fit chi2_gaussian = minuit_Gaussian.fval ndof_gaussian = len(x) - len(minuit_Gaussian.args) prob_gaussian = stats.chi2.sf(chi2_gaussian, ndof_gaussian) xaxis = np.linspace(xmin, xmax, 1000) yaxis = func_Gaussian(xaxis, *minuit_Gaussian.args) ax1.plot(xaxis, yaxis, '-', label='Gaussian distribution fit') names = [ 'Entries', 'Mean', 'Std Dev', 'Chi2/ndf', 'Prob', 'N fit', 'mu fit', 'sigma fit'
def run_actual_fit(t, y, sy, cfg, dt, ts): debug = False # debug = True # np.random.seed(cfg.ID) np.random.seed(42) if debug: reload(SIR) print("delete this") # reload(SIR) normal_priors = dict( # multiplier=0, # lambda_E={'mean': cfg.lambda_E, 'std': cfg.lambda_E/10}, # lambda_I={'mean': cfg.lambda_I, 'std': cfg.lambda_I/10}, # beta= {'mean': 0.01, 'std': 0.05}, ) p0 = dict( lambda_E=cfg.lambda_E, lambda_I=cfg.lambda_I, beta=cfg.beta, tau=0, ) bounds = dict( limit_lambda_E=(1e-6, None), limit_lambda_I=(1e-6, None), limit_beta=(1e-6, None), ) fix = dict( fix_lambda_E=True, fix_lambda_I=True, ) fit_object = SIR.FitSIR(t, y, sy, normal_priors, cfg, dt=dt, ts=ts) minuit = Minuit( fit_object, pedantic=False, print_level=0, **p0, **bounds, **fix, errordef=Minuit.LEAST_SQUARES, ) minuit.migrad() fit_object.set_minuit(minuit) fit_object, fit_failed = refit_if_needed(fit_object, cfg, bounds, fix, minuit, debug=debug) return fit_object, fit_failed
def test_minos_single_no_migrad(): m = Minuit(func3, pedantic=False, print_level=0) with pytest.raises(RuntimeError): m.minos('x')
-0.190318, 3.5303, 0.504813) initialErrors = (0.1, 10., 10., 0.1, 0.1, 0.3, 0.5, 1., 1., 1., 1., 1., 1., 0.1) # searchLimits=((0.0001,2.),(0.01,80), (0.0,400), None,None, # (-2.,2.),(-0.99,2.5), (-10.,10.), # (-20.,20.),(-0.99,6.), (-15.,15.), # (-5.,5.),(-0.99,8), None) searchLimits = ((0, None), (0, None), (0, None), None, None, (-5., 5.), (-0.99, 30), (-30., 30.), (-5., 5.), (-0.99, 60.), (-30., 30.), (-5., 15.), (-0.99, 30.), (-5, 5)) parametersToMinimize = (False, False, False, True, True, False, False, False, False, False, False, False, False, False) m = Minuit(chi_2, initialValues) m.errors = initialErrors m.limits = searchLimits m.fixed = parametersToMinimize m.errordef = 1 print(m.params) m.tol = 0.0001 * totalN * 10000 ### the last 0.0001 is to compensate MINUIT def m.strategy = 1 #%% # m.tol=0.0001*totalN*10000 ### the last 0.0001 is to compensate MINUIT def # m.strategy=1
def setup(self): self.m = Minuit(func3, print_level=0, pedantic=False) self.m.migrad() self.m.hesse() self.m.minos()
def predict(self, shower_seed, energy_seed): """ Parameters ---------- source_x: float Initial guess of source position in the nominal frame source_y: float Initial guess of source position in the nominal frame core_x: float Initial guess of the core position in the tilted system core_y: float Initial guess of the core position in the tilted system energy: float Initial guess of energy Returns ------- Shower object with fit results """ horizon_seed = HorizonFrame(az=shower_seed.az, alt=shower_seed.alt) nominal_seed = horizon_seed.transform_to( NominalFrame(array_direction=self.array_direction)) source_x = nominal_seed.x.to(u.rad).value source_y = nominal_seed.y.to(u.rad).value ground = GroundFrame(x=shower_seed.core_x, y=shower_seed.core_y, z=0 * u.m) tilted = ground.transform_to( TiltedGroundFrame(pointing_direction=self.array_direction)) tilt_x = tilted.x.to(u.m).value tilt_y = tilted.y.to(u.m).value lower_en_limit = energy_seed.energy * 0.1 if lower_en_limit < 0.04 * u.TeV: lower_en_limit = 0.04 * u.TeV # Create Minuit object with first guesses at parameters, strip away the # units as Minuit doesnt like them min = Minuit(self.get_likelihood, print_level=1, source_x=source_x, error_source_x=0.01 / 57.3, fix_source_x=False, limit_source_x=(source_x - 0.5 / 57.3, source_x + 0.5 / 57.3), source_y=source_y, error_source_y=0.01 / 57.3, fix_source_y=False, limit_source_y=(source_y - 0.5 / 57.3, source_y + 0.5 / 57.3), core_x=tilt_x, error_core_x=10, limit_core_x=(tilt_x - 200, tilt_x + 200), core_y=tilt_y, error_core_y=10, limit_core_y=(tilt_y - 200, tilt_y + 200), energy=energy_seed.energy.value, error_energy=energy_seed.energy.value * 0.05, limit_energy=(lower_en_limit.value, energy_seed.energy.value * 10.), x_max_scale=1, error_x_max_scale=0.1, limit_x_max_scale=(0.5, 2), fix_x_max_scale=False, errordef=1) min.tol *= 1000 min.strategy = 0 # Perform minimisation migrad = min.migrad() fit_params = min.values errors = min.errors # print(migrad) # print(min.minos()) # container class for reconstructed showers ''' shower_result = ReconstructedShowerContainer() nominal = NominalFrame(x=fit_params["source_x"] * u.rad, y=fit_params["source_y"] * u.rad, array_direction=self.array_direction) horizon = nominal.transform_to(HorizonFrame()) shower_result.alt, shower_result.az = horizon.alt, horizon.az tilted = TiltedGroundFrame(x=fit_params["core_x"] * u.m, y=fit_params["core_y"] * u.m, pointing_direction=self.array_direction) ground = project_to_ground(tilted) shower_result.core_x = ground.x shower_result.core_y = ground.y shower_result.is_valid = True shower_result.alt_uncert = np.nan shower_result.az_uncert = np.nan shower_result.core_uncert = np.nan zenith = 90 * u.deg - self.array_direction[0] shower_result.h_max = fit_params["x_max_scale"] * \ self.get_shower_max(fit_params["source_x"], fit_params["source_y"], fit_params["core_x"], fit_params["core_y"], zenith.to(u.rad).value) shower_result.h_max_uncert = errors["x_max_scale"] * shower_result.h_max shower_result.goodness_of_fit = np.nan shower_result.tel_ids = list(self.image.keys()) energy_result = ReconstructedEnergyContainer() energy_result.energy = fit_params["energy"] * u.TeV energy_result.energy_uncert = errors["energy"] * u.TeV energy_result.is_valid = True energy_result.tel_ids = list(self.image.keys()) # Return interesting stuff return shower_result, energy_result