def nonlinear_fit_with_independent_as_t(): """Test of PHS3000 nonlinear fit using an independent variable that was not 'x'""" ### Get results ### import monashspa.PHS3000 as spa # load the data data = spa.tutorials.fitting.part_b_data # slice the data into columns t = data[:,0] A = data[:,1] u_A = data[:,2] model = spa.make_lmfit_model("A_0*exp(-l*t)", independent_vars=["t"]) params = model.make_params(A_0=30, l=.005) params.add('halflife', expr="log(2)/l") fit_results = spa.model_fit(model, params, x=t, y=A, u_y=u_A) results = spa.get_fit_parameters(fit_results) ### Expected results ### expected_results = { 'A_0': 20.573035990441486, 'u_A_0': 0.6181473325960677, 'l': 0.005004779941925933, 'u_l': 0.00015840653659960648, 'halflife': 138.49703455557113, 'u_halflife': 4.38357646646529, } precision = 2e-7 ### Check results match within precision ### success = compare_dictionary(results, expected_results, precision) return success
def nonlinear_fit_part_c2(): """Test of PHS3000 non-linear fit to multi-model nuclear decay data""" import monashspa.PHS3000 as spa # load the data data = spa.tutorials.fitting.part_c2_data # slice the data into columns t = data[:,0] A = data[:,1] u_A = data[:,2] ag110_model = spa.make_lmfit_model("A_0*exp(-l*x)", prefix="AG110_") ag108_model = spa.make_lmfit_model("A_0*exp(-l*x)", prefix="AG108_") offset = spa.make_lmfit_model("c+x*0", name="offset") model = ag110_model + ag108_model + offset params = model.make_params(AG110_A_0=A[0], AG110_l=np.log(2)/t[4], AG108_l=np.log(2)/t[9], c=0) params.add('c', min=0, value=0, max=0.1, vary=True) params.add('AG110_halflife', expr='log(2)/AG110_l') params.add('AG108_halflife', expr='log(2)/AG108_l') fit_results = spa.model_fit(model, params, x=t, y=A, u_y=u_A) results = spa.get_fit_parameters(fit_results) expected_results = { 'AG110_A_0': 106.62466958768731, 'u_AG110_A_0': 3.7021128718124436, 'AG110_l': 0.03272908958050027, 'u_AG110_l': 0.0019419683658320412, 'AG108_A_0': 24.504027101025645, 'u_AG108_A_0': 2.492813131791383, 'AG108_l': 0.005097263436001847, 'u_AG108_l': 0.000586527763335435, 'c': 6.436383415431291e-06, 'u_c': 1.1676201, 'AG110_halflife': 21.178321470112536, 'u_AG110_halflife': 1.2566078265666092, 'AG108_halflife': 135.98417842489044, 'u_AG108_halflife': 15.647316857620634 } precision = 5e-3 # split off the check for u_c as the precision (variation across platforms) is much worse than everything else. # This is to be expected with multi-model non-linear fits. u_c_precision = 3.0 u_c_result = {'u_c':results['u_c']} u_c_expected_result = {'u_c':expected_results['u_c']} del results['u_c'] del expected_results['u_c'] ### Check results match within precision ### success = compare_dictionary(results, expected_results, precision) and compare_dictionary(u_c_result, u_c_expected_result, u_c_precision) return success
def non_linear_fit_part_c(): """Test of PHS3000 non-linear fit to generic multi-model data""" ### Get results ### import monashspa.PHS3000 as spa # load the data data = spa.tutorials.fitting.part_c1_data # slice the data into columns x = data[:,0] y = data[:,1] # Define the models model1 = spa.make_lmfit_model("A1*exp(-(x-B1)**2/D1**2)", name="Gaussian1") model2 = spa.make_lmfit_model("A2*exp(-(x-B2)**2/D2**2)", name="Gaussian2") model3 = spa.make_lmfit_model("c+x*0", name="Offset") model = model1 + model2 + model3 params = model.make_params(A1=np.max(y), B1=100, D1=6, A2=np.max(y), B2=160, c=3) params.add('D2', expr='D1') params.add('FWHM', expr='2*sqrt(log(2)*D1)') fit_results = spa.model_fit(model, params, x=x, y=y) results = spa.get_fit_parameters(fit_results) ### Expected results ### expected_results = { 'A1': 16.58279101985785, 'u_A1': 0.351003396364092, 'B1': 95.82492417888295, 'u_B1': 0.12363799249150613, 'D1': 6.705149651134903, 'u_D1': 0.1412232821933916, 'A2': 13.690661831671, 'u_A2': 0.33945028545509237, 'B2': 164.19308257427863, 'u_B2': 0.1497567729486557, 'D2': 6.705149651134903, 'u_D2': 0.14122328218157232, 'c': 2.636117481366362, 'u_c': 0.06764023986252798, 'FWHM': 4.311684392863958, 'u_FWHM': 0.045406161696634036 } precision = 1e-5 ### Check results match within precision ### success = compare_dictionary(results, expected_results, precision) return success
def linear_fit_dual_custom_named_model(): """Test of PHS3000 linear fit using the sum of two custom models with prefixes""" ### Get results ### import monashspa.PHS3000 as spa # load the data data = spa.tutorials.fitting.part_b_data # slice the data into columns t = data[:,0] A = data[:,1] u_A = data[:,2] model1 = spa.make_lmfit_model("m*x", prefix="m1") model2 = spa.make_lmfit_model("c+x*0", prefix="m2") model = model1 + model2 params = model.make_params(m1m=0.04, m2c=5) params.add('halflife', expr="-log(2)/m1m") params.add('A_0', expr="exp(m2c)") fit_results = spa.model_fit(model, params, x=t, y=np.log(A), u_y=u_A/A) results = spa.get_fit_parameters(fit_results) ### Expected results ### expected_results = { 'm2c': 3.02843895796932, 'u_m2c': 0.030620495054301592, 'm1m': -0.004897938859868103, 'u_m1m': 0.0001633020007207088, 'halflife': 141.51813658584769, 'u_halflife': 4.718351025589936, 'A_0': 20.664948544330286, 'u_A_0': 0.6327709546990624, } precision = 1e-5 ### Check results match within precision ### success = compare_dictionary(results, expected_results, precision) return success