def test_scale_fluxes(): """Specify a source_flux, blend_flux and make sure it works""" # Original Flux values f_s = 1.0 f_b = 0.5 # Generate fake data from a fake model pspl, t, A = generate_model() f_mod = f_s * A + f_b data = generate_dataset(f_mod, t) fit = mm.FitData(dataset=data, model=pspl) fit.fit_fluxes() num = 100 # Test the same (new_flux, new_err) = fit.scale_fluxes(source_flux=f_s, blend_flux=f_b) almost(data.flux[num], new_flux[num]) # Test Different (f_s_new, f_b_new) = (0.1, 0.) exp_flux = (data.flux - f_b) * f_s_new / f_s + f_b_new exp_err = data.err_flux * f_s_new / f_s (new_flux, new_err) = fit.scale_fluxes(source_flux=f_s_new, blend_flux=f_b_new) assert np.abs(data.flux[num] - new_flux[num]) > 0.5 almost(exp_flux / new_flux, 1.) almost(exp_err / new_err, 1.)
def test_satellite_and_annual_parallax_calculation(): """ test that data magnifications are correctly retrieved for Spitzer data. """ # Create Model model_parameters = { 't_0': 2456836.22, 'u_0': 0.922, 't_E': 22.87, 'pi_E_N': -0.248, 'pi_E_E': 0.234, 't_0_par': 2456836.2 } coords = "17:47:12.25 -21:22:58.2" model_with_par = mm.Model(model_parameters, coords=coords) model_with_par.parallax(satellite=True, earth_orbital=True, topocentric=False) # Load Spitzer data and answers data_Spitzer = mm.MulensData(file_name=SAMPLE_FILE_03, ephemerides_file=SAMPLE_FILE_03_EPH) ref_Spitzer = np.loadtxt(SAMPLE_FILE_03_REF, unpack=True, usecols=[5]) # Test FitData.data_magnification() my_fit = mm.FitData(dataset=data_Spitzer, model=model_with_par) ratio = my_fit.get_data_magnification() / ref_Spitzer np.testing.assert_almost_equal(ratio, [1.] * len(ratio), decimal=4)
def test_default(): """ test for when blend flux and source flux are to be determined """ pspl, t, A = generate_model() # secrets f_s = 1.0 f_b = 0.5 # generate f_mod f_mod = f_s * A + f_b my_dataset = generate_dataset(f_mod, t) my_fit = mm.FitData(model=pspl, dataset=my_dataset, fix_blend_flux=False, fix_source_flux=False) my_fit.fit_fluxes() almost(my_fit.blend_flux, f_b) almost(my_fit.source_flux, f_s) # Test get_model_fluxes() for 1 source peak_index = 500 mod_fluxes = my_fit.get_model_fluxes() almost(mod_fluxes[peak_index], my_dataset.flux[peak_index])
def test_chi2_per_point(): """Test that the chi2 shape is correct for multiple sources, i.e. = number of epochs, rather than epochs * sources.""" test_object = BinarySourceTest() my_fit = mm.FitData(model=test_object.model, dataset=test_object.dataset) my_fit.update() assert (my_fit.chi2_per_point.shape == (test_object.dataset.n_epochs, ))
def fit_fluxes(self): """ Allow the two source fluxes to be freely fit for some reference dataset, but then constrain the fluxes for all other datasets in the same bandpass. """ self.fits = [] kmtc_fits = { 1: mm.FitData(model=self.model, dataset=self.datasets[1]), 4: mm.FitData(model=self.model, dataset=self.datasets[4]) } band = {'I': 1, 'V': 4} # This simplies the code below. for (i, dataset) in enumerate(self.datasets): if i in kmtc_fits: fit = kmtc_fits[i] else: q_flux = kmtc_fits[band[dataset.bandpass]].source_flux_ratio fit = mm.FitData(model=self.model, dataset=dataset, fix_source_flux_ratio=q_flux) self.fits.append(fit)
def execute_test_blend_fixed(f_b): # test for when source flux is to be determined, but blend flux is a # fixed value pspl, t, A = generate_model() # secret source flux f_s = 1.0 f_mod = f_s * A + f_b my_dataset = generate_dataset(f_mod, t) my_fit = mm.FitData(model=pspl, dataset=my_dataset, fix_blend_flux=f_b, fix_source_flux=False) my_fit.fit_fluxes() almost(my_fit.source_flux, f_s)
def test_fit_fluxes(): """ test that when the model is updated, and fit fluxes is re-run, the fluxes actually change. """ pspl, t, A = generate_model() # secret blend flux, set source flux f_s = 1.0 f_b = 0.5 f_mod = f_s * A + f_b my_dataset = generate_dataset(f_mod, t) my_fit = mm.FitData(model=pspl, dataset=my_dataset, fix_blend_flux=False, fix_source_flux=False) # Before update or fit_fluxes is run, chi2_per_point should be None assert (my_fit.chi2_per_point is None) my_fit.update() # After update is run, chi2_per_point should have some values assert (len(my_fit.chi2_per_point) == 1000) f_s_1 = my_fit.source_flux chi2_1 = my_fit.chi2 t_E_2 = pspl.parameters.t_E / (f_s + f_b) u_0_2 = pspl.parameters.u_0 / (f_s + f_b) new_model = mm.Model({ 't_0': pspl.parameters.t_0, 'u_0': u_0_2, 't_E': t_E_2 }) my_fit.model = new_model my_fit.fix_blend_flux = 0. my_fit.fit_fluxes() assert (f_s_1 != my_fit.source_flux) assert (chi2_1 == my_fit.chi2) my_fit.update() assert (chi2_1 != my_fit.chi2)
def test_both_fixed(): """ test for when both fluxes are fixed --> evaluate chi2 but not fluxes. """ pspl, t, A = generate_model() # secret blend flux, set source flux f_s = 1.0 f_b = 0.5 f_mod = f_s * A + f_b my_dataset = generate_dataset(f_mod, t) my_fit = mm.FitData(model=pspl, dataset=my_dataset, fix_blend_flux=f_b, fix_source_flux=f_s) my_fit.update() almost(my_fit.blend_flux, f_b) almost(my_fit.source_flux, f_s)
def run_test(self, fix_blend_flux=False, fix_source_flux=False, fix_q_flux=False): self.my_fit = mm.FitData(model=self.model, dataset=self.dataset, fix_blend_flux=fix_blend_flux, fix_source_flux=fix_source_flux, fix_source_flux_ratio=fix_q_flux) self.my_fit.fit_fluxes() almost(self.my_fit.blend_flux, self.f_b) almost(self.my_fit.source_fluxes[0], self.f_s_1) almost(self.my_fit.source_fluxes[1], self.f_s_2) # Test get_model_fluxes() for 2 sources peak_index = 500 mod_fluxes = self.my_fit.get_model_fluxes() almost(mod_fluxes[peak_index], self.dataset.flux[peak_index])
def test_source_fixed(): """ test for when blend flux is to be determined, but source flux is a fixed value """ pspl, t, A = generate_model() # secret blend flux, set source flux f_s = 1.0 f_b = 0.5 f_mod = f_s * A + f_b my_dataset = generate_dataset(f_mod, t) my_fit = mm.FitData(model=pspl, dataset=my_dataset, fix_blend_flux=False, fix_source_flux=f_s) my_fit.fit_fluxes() almost(my_fit.blend_flux, f_b)
# Save the best-fit parameters chi2 = chi2_fun(result.x, parameters_to_fit, event) # Output the fit parameters msg = 'Best Fit: t_0 = {0:12.5f}, u_0 = {1:6.4f}, t_E = {2:8.3f}' print(msg.format(fit_t_0, fit_u_0, fit_t_E)) print('Chi2 = {0:12.2f}'.format(chi2)) print('scipy.optimize.minimize result:') print(result) # Plot and compare the two models init_model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E}) final_model = mm.Model({'t_0': fit_t_0, 'u_0': fit_u_0, 't_E': fit_t_E}) init_fit = mm.FitData(dataset=data, model=init_model) init_fit.fit_fluxes() final_fit = mm.FitData(dataset=data, model=final_model) final_fit.fit_fluxes() plt.figure() init_model.plot_lc(source_flux=init_fit.source_flux, blend_flux=init_fit.blend_flux, label='Initial Trial') final_model.plot_lc(source_flux=final_fit.source_flux, blend_flux=final_fit.blend_flux, label='Final Model') plt.title('Difference b/w Input and Fitted Model') plt.legend(loc='best') # Plot the fitted model with the data
############# # Define a basic PSPL fit # Initial Model t_0 = 2455379.571 u_0 = 0.5 t_E = 17.94 pspl_model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E}) # Import data file_name = os.path.join(mm.DATA_PATH, 'photometry_files', 'OB08092', 'phot_ob08092_O4.dat') data = mm.MulensData(file_name=file_name) # Freely fit the fluxes free_fit = mm.FitData(model=pspl_model, dataset=data) free_fit.update() # Required to calculate chi2 (not just fluxes) # Access different properties of that fit print(free_fit.chi2_per_point) print(free_fit.source_fluxes, free_fit.blend_flux) print(free_fit.chi2) # Constrain various aspects of the fit fit_1 = mm.FitData(model=pspl_model, dataset=data, fix_source_flux=False, fix_blend_flux=0.) fit_1.fit_fluxes() print(fit_1.source_flux, fit_1.blend_flux, 0.)
def setUp(self): self.model = mm.Model({'t_0': 8000., 'u_0': 0.3, 't_E': 25.}) self.generate_fake_dataset() self.fit = mm.FitData(model=self.model, dataset=self.dataset) self.fit.fit_fluxes()
def test_bad_data(): """ test how chi2 and chi2_per_point are affected if some datapoints are set to bad. Effectively tests update() fit_fluxes() get_data_magnification() get_model_fluxes() chi2 chi2_per_point """ # test that chi2 changes when using all data points vs. eliminating the # planet. (t_planet_start, t_planet_stop) = (2460982., 2460985.) data = mm.MulensData(file_name=SAMPLE_FILE_04_WF) flag_planet = (data.time > t_planet_start) & ( data.time < t_planet_stop) | np.isnan(data.err_mag) data_bad = mm.MulensData(file_name=SAMPLE_FILE_04_WF, bad=flag_planet) (t_0, u_0, t_E) = (2460962.36458, 0.411823, 22.8092) point_lens_model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E}) fit_all = mm.FitData(dataset=data, model=point_lens_model) fit_bad = mm.FitData(dataset=data_bad, model=point_lens_model) assert (fit_all.chi2 is None) fit_all.update() fit_bad.update() chi2_all = fit_all.chi2 chi2_bad = fit_bad.chi2 assert (chi2_all > chi2_bad) # test whether chi2_per_point is calculated for bad points. # not calculated --> magnification = 0, model_flux --> f_blend, dchi2=large # update: bad not specified --> not calculated # Likewise, do these tests for get_model_magnitudes # points: # during anomaly 13055 # before anomaly, but excluded: 12915 # before anomaly, but included: 12900 good_pt = 12900 bad_pt = 12915 assert (fit_bad.chi2_per_point[bad_pt] / fit_bad.chi2_per_point[good_pt] > 100.) expected_mag = mm.Utils.get_mag_from_flux(fit_bad.blend_flux) almost(fit_bad.get_model_magnitudes()[bad_pt], expected_mag) # update: bad=True --> calculated fit_bad.update(bad=True) assert (fit_bad.chi2_per_point[bad_pt] / fit_bad.chi2_per_point[good_pt] < 10.) almost(fit_bad.get_model_magnitudes()[bad_pt], 19.27, decimal=1) # update: bad=False --> not calculated fit_bad.update(bad=False) assert (fit_bad.chi2_per_point[bad_pt] / fit_bad.chi2_per_point[good_pt] > 100.) almost(fit_bad.get_model_magnitudes()[bad_pt], expected_mag) # Test fitted fluxes are different with and without bad data points. assert (fit_all.source_flux > fit_bad.source_flux)