def test_magnifications_for_orbital_motion(): """ make sure that orbital motion parameters are properly passed to magnification methods calculations """ dict_static = { 't_0': 100., 'u_0': 0.1, 't_E': 100., 'q': 0.99, 's': 1.1, 'alpha': 10. } dict_motion = dict_static.copy() dict_motion.update({'ds_dt': -2, 'dalpha_dt': -300.}) static = mm.Model(dict_static) motion = mm.Model(dict_motion) t_1 = 100. almost(static.magnification(t_1), motion.magnification(t_1)) t_2 = 130. static.parameters.s = 0.93572895 static.parameters.alpha = 345.359342916 almost(static.magnification(t_2), motion.magnification(t_2))
def test_binary_source_and_fluxes_for_bands(): """ Test if setting different flux ratios for different bands in binary source models works properly. The argument flux_ratio_constraint is set as string. """ model = mm.Model({ 't_0_1': 5000., 'u_0_1': 0.05, 't_0_2': 5100., 'u_0_2': 0.003, 't_E': 30. }) times_I = np.linspace(4900., 5200., 3000) times_V = np.linspace(4800., 5300., 250) (f_s_1_I, f_s_2_I, f_b_I) = (10., 20., 3.) (f_s_1_V, f_s_2_V, f_b_V) = (15., 5., 30.) q_f_I = f_s_2_I / f_s_1_I q_f_V = f_s_2_V / f_s_1_V (mag_1_I, mag_2_I) = model.get_magnification(times_I, separate=True) (mag_1_V, mag_2_V) = model.get_magnification(times_V, separate=True) effective_mag_I = (mag_1_I + mag_2_I * q_f_I) / (1. + q_f_I) effective_mag_V = (mag_1_V + mag_2_V * q_f_V) / (1. + q_f_V) flux_I = mag_1_I * f_s_1_I + mag_2_I * f_s_2_I + f_b_I flux_V = mag_1_V * f_s_1_V + mag_2_V * f_s_2_V + f_b_V # model.set_source_flux_ratio_for_band('I', q_f_I) # model.set_source_flux_ratio_for_band('V', q_f_V) # Test Model.get_magnification() result_I = model.get_magnification(times_I, source_flux_ratio=q_f_I) result_V = model.get_magnification(times_V, source_flux_ratio=q_f_V) almost(result_I, effective_mag_I) almost(result_V, effective_mag_V)
def test_separate_method_for_each_source(): """ Checks if setting separate magnification method for each source in binary source models works properly. """ model = mm.Model({ 't_0_1': 5000., 'u_0_1': 0.01, 'rho_1': 0.005, 't_0_2': 5100., 'u_0_2': 0.001, 'rho_2': 0.005, 't_E': 1000. }) model.set_magnification_methods( [4999., 'finite_source_uniform_Gould94', 5101.], source=1) # In order not to get "no FS method" warning: model.set_magnification_methods([0., 'finite_source_uniform_Gould94', 1.], source=2) out = model.magnification(5000., separate=True) almost([out[0][0], out[1][0]], [103.46704167, 10.03696291]) model.set_magnification_methods( [4999., 'finite_source_uniform_Gould94', 5001.], source=1) model.set_magnification_methods( [5099., 'finite_source_uniform_Gould94', 5101.], source=2) out = model.magnification(5100., separate=True) almost([out[0][0], out[1][0]], [9.98801936, 395.96963727])
def test_caustic_for_orbital_motion(): """ check if caustics calculated for different epochs in orbital motion model are as expected """ q = 0.1 s = 1.3 params = { 't_0': 100., 'u_0': 0.1, 't_E': 10., 'q': q, 's': s, 'ds_dt': 0.5, 'alpha': 0., 'dalpha_dt': 0. } model = mm.Model(parameters=params) model.update_caustics() almost(model.caustics.get_caustics(), mm.Caustics(q=q, s=s).get_caustics()) model.update_caustics(100. + 365.25 / 2) almost(model.caustics.get_caustics(), mm.Caustics(q=q, s=1.55).get_caustics())
def test_limb_darkening(): """check if limb_darkening coeffs are properly passed and converted""" gamma = 0.4555 u = 3. * gamma / (2. + gamma) model = mm.Model({'t_0': 2450000., 'u_0': 0.1, 't_E': 100., 'rho': 0.001}) model.set_limb_coeff_gamma('I', gamma) almost(model.get_limb_coeff_gamma('I'), gamma) almost(model.get_limb_coeff_u('I'), u)
def test_model_PSPL_1(): """tests basic evaluation of Paczynski model""" t_0 = 5379.57091 u_0 = 0.52298 t_E = 17.94002 times = np.array([t_0 - 2.5 * t_E, t_0, t_0 + t_E]) model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E}) almost(model.get_magnification(times), np.array([1.028720763, 2.10290259, 1.26317278]), err_msg="PSPL model returns wrong values")
def test_t_E(): """make sure t_E can be accessed properly""" t_0 = 2460000. u_0 = 0.1 t_E = 12.3456 t_star = 0.01234 params = dict(t_0=t_0, u_0=u_0, t_E=t_E) model_1 = mm.Model(params) params['t_star'] = t_star model_2 = mm.Model(params) almost(model_1.parameters.t_E, t_E) almost(model_2.parameters.t_E, t_E)
def test_photfmt_scaled_2(self): """ check phot_fmt='scaled'; true values of f_source, f_blend should yield errorbars identical to the true values.""" f_source_0 = self.dataset_properties['f_source'] f_blend_0 = self.dataset_properties['f_blend'] # Bad = True (residuals, res_errors) = self.fit.get_residuals(phot_fmt='scaled', source_flux=f_source_0, blend_flux=f_blend_0, bad=True) almost(res_errors, self.dataset.err_mag)
def test_model_PSPL_1(): """tests basic evaluation of Paczynski model""" t_0 = 5379.57091 u_0 = 0.52298 t_E = 17.94002 times = np.array([t_0 - 2.5 * t_E, t_0, t_0 + t_E]) data = mm.MulensData(data_list=[times, times * 0., times * 0.]) model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E}) model.parameters.u_0 = u_0 model.parameters.t_E = t_E model.set_datasets([data]) almost(model.data_magnification, [np.array([1.028720763, 2.10290259, 1.26317278])], err_msg="PSPL model returns wrong values")
def test_bad_keyword(self): """ If bad = False, the magnification should be zero. Therefore, the flux calculated for the bad data points should be f_blend. If bad=True, the values should be the true values of the residuals. """ # Bad = False (residuals, res_errors) = self.fit.get_residuals(phot_fmt='flux', bad=False) for index in self.outliers['index']: exp_residual = (self.dataset.flux[index] - self.dataset_properties['f_blend']) almost(residuals[index], exp_residual) # Check errorbars almost(res_errors, self.dataset.err_flux) # Bad = True (residuals, res_errors) = self.fit.get_residuals(phot_fmt='flux', bad=True) for i, index in enumerate(self.outliers['index']): exp_residual = self.outliers['values'][i] almost(residuals[index], exp_residual) # Check errorbars almost(res_errors, self.dataset.err_flux)
def test_get_lc(): """ Test if Model.get_lc() works properly; we test on binary source model without finite source effect. """ model = mm.Model({ 't_0_1': 5000., 'u_0_1': 1., 't_0_2': 5100., 'u_0_2': 0.1, 't_E': 100. }) out = model.get_lc(5050., source_flux=[1., 2.], blend_flux=3.) almost(out, 19.668370500043526)
def test_BLPS_01(): """simple binary lens with point source""" params = mm.ModelParameters({ 't_0': t_0, 'u_0': u_0, 't_E': t_E, 'alpha': alpha, 's': s, 'q': q }) model = mm.Model(parameters=params) t = np.array([2456112.5]) data = mm.MulensData(data_list=[t, t * 0. + 16., t * 0. + 0.01]) magnification = model.get_magnification(data.time[0]) almost(magnification, 4.691830781584699)
def test_BLPS_02_AC(): """ simple binary lens with extended source and different methods to evaluate magnification - version with adaptivecontouring """ params = mm.ModelParameters({ 't_0': t_0, 'u_0': u_0, 't_E': t_E, 'alpha': alpha, 's': s, 'q': q, 'rho': rho }) model = mm.Model(parameters=params) t = np.array([6112.5, 6113., 6114., 6115., 6116., 6117., 6118., 6119]) t += 2450000. ac_name = 'Adaptive_Contouring' methods = [ 2456113.5, 'Quadrupole', 2456114.5, 'Hexadecapole', 2456116.5, ac_name, 2456117.5 ] accuracy_1 = {'accuracy': 0.04} accuracy_2 = {'accuracy': 0.01, 'ld_accuracy': 0.00001} model.set_magnification_methods(methods) model.set_magnification_methods_parameters({ac_name: accuracy_1}) data = mm.MulensData(data_list=[t, t * 0. + 16., t * 0. + 0.01]) result = model.get_magnification(data.time) expected = np.array([ 4.69183078, 2.87659723, 1.83733975, 1.63865704, 1.61038135, 1.63603122, 1.69045492, 1.77012807 ]) almost(result, expected, decimal=3) # Below we test passing the limb coeff to VBBL function. # data.bandpass = '******' model.set_limb_coeff_u('I', 10.) # This is an absurd value but I needed something quick. model.set_magnification_methods_parameters({ac_name: accuracy_2}) # result = model.data_magnification[0] result = model.get_magnification(data.time, gamma=model.get_limb_coeff_gamma('I')) almost(result[5], 1.6366862, decimal=3)
def test_intp_of_linear_arr(): h_in, w_in, d_in = 10, 20, 5 h_out, w_out, d_out = 5., 25., 5. x_in, y_in, z_in = np.mgrid[:h_in, :w_in, :d_in] x_out, y_out, z_out = np.mgrid[:h_out, :w_out, :d_out] x_out = 1. * x_out / x_out.max() * (h_in - 1.) y_out = 1. * y_out / y_out.max() * (w_in - 1.) z_out = 1. * z_out / z_out.max() * (d_in - 1.) # -- arbitray linear function def f1(x, y): a = 1.234 b = 0.987 return a * x + b * y ref_out = f1(x_out, y_out) out1 = resample(f1(x_in, y_in), (h_out, w_out, d_out), order=1) almost(ref_out, out1)
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_model_init_1(): """tests if basic parameters of Model.__init__() are properly passed""" t_0 = 5432.10987 u_0 = 0.001 t_E = 123.456 rho = 0.0123 my_model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E, 'rho': rho}) almost(my_model.parameters.t_0, t_0, err_msg='t_0 not set properly') almost(my_model.parameters.u_0, u_0, err_msg='u_0 not set properly') almost(my_model.parameters.t_E, t_E, err_msg='t_E not set properly') almost(my_model.parameters.rho, rho, err_msg='rho not set properly')
def test_coords_transformation(): """ this was tested using http://ned.ipac.caltech.edu/forms/calculator.html """ coords = "17:54:32.1 -30:12:34.0" model = mm.Model({'t_0': 2450000., 'u_0': 0.1, 't_E': 100.}, coords=coords) almost(model.coords.galactic_l.value, 359.90100049 - 360., decimal=4) almost(model.coords.galactic_b.value, -2.31694073, decimal=3) almost(model.coords.ecliptic_lon.value, 268.81102051, decimal=1) almost(model.coords.ecliptic_lat.value, -6.77579203, decimal=2)
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 test_BLPS_shear(): """ simple binary lens with point source and external convergence and shear """ params = mm.ModelParameters({ 't_0': t_0, 'u_0': u_0, 't_E': t_E, 'alpha': alpha, 's': s, 'q': q, 'convergence_K': 0.0, 'shear_G': complex(0, 0) }) model = mm.Model(parameters=params) t = np.array([2456112.5]) data = mm.MulensData(data_list=[t, t * 0. + 16., t * 0. + 0.01]) magnification = model.get_magnification(data.time[0]) almost(magnification, 4.691830781584699)
def test_BLPS_02(): """ simple binary lens with extended source and different methods to evaluate magnification """ params = mm.ModelParameters({ 't_0': t_0, 'u_0': u_0, 't_E': t_E, 'alpha': alpha, 's': s, 'q': q, 'rho': rho }) model = mm.Model(parameters=params) t = np.array([6112.5, 6113., 6114., 6115., 6116., 6117., 6118., 6119]) t += 2450000. methods = [ 2456113.5, 'Quadrupole', 2456114.5, 'Hexadecapole', 2456116.5, 'VBBL', 2456117.5 ] model.set_magnification_methods(methods) data = mm.MulensData(data_list=[t, t * 0. + 16., t * 0. + 0.01]) model.set_datasets([data]) result = model.data_magnification[0] expected = np.array([ 4.69183078, 2.87659723, 1.83733975, 1.63865704, 1.61038135, 1.63603122, 1.69045492, 1.77012807 ]) almost(result, expected) # Below we test passing the limb coeff to VBBL function. data.bandpass = '******' model.set_limb_coeff_u('I', 10.) # This is an absurd value but I needed something quick. result = model.data_magnification[0] almost(result[5], 1.6366862)
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)
def test_photfmt_scaled_1(self): """ check phot_fmt='scaled' """ f_source_0 = 1.0 f_blend_0 = 0.1 # Bad = True (residuals, res_errors) = self.fit.get_residuals(phot_fmt='scaled', source_flux=f_source_0, blend_flux=f_blend_0, bad=True) model_flux = ( f_source_0 * self.model.get_magnification(self.dataset.time) + f_blend_0) model_mag = mm.Utils.get_mag_from_flux(model_flux) for i in np.arange(len(self.dataset.time)): exp_flux = ( f_source_0 * (self.dataset.flux[i] - self.dataset_properties['f_blend']) / self.dataset_properties['f_source'] + f_blend_0) if i in self.outliers['index']: exp_mag = mm.Utils.get_mag_from_flux(exp_flux) exp_delta_mag = exp_mag - model_mag[i] almost(exp_delta_mag, residuals[i]) else: # Non-outliers should have zero residual almost(residuals[i], 0) # Check errorbars exp_err_flux = (f_source_0 * self.dataset.err_flux[i] / self.dataset_properties['f_source']) exp_err_mag = 2.5 * exp_err_flux / exp_flux / np.log(10.) almost(exp_err_mag, res_errors[i]) assert self.dataset.err_mag[i] != res_errors[i]
def test_photfmt_mag(self): """ check phot_fmt = 'mag' .""" # Bad = True (residuals, res_errors) = self.fit.get_residuals(phot_fmt='mag', bad=True) # Simple sign check for i, index in enumerate(self.outliers['index']): if self.outliers['values'][i] > 0: assert residuals[index] < 0 else: assert residuals[index] > 0 # Value check for i in np.arange(len(self.dataset.time)): if i in self.outliers['index']: index = np.where(self.outliers['index'] == i) f_0 = self.dataset.flux[i] - self.outliers['values'][index] f_obs = self.dataset.flux[i] delta_mag = -2.5 * np.log10(f_obs / f_0) almost(delta_mag, residuals[i]) else: # Non-outliers should have zero residual almost(residuals[i], 0) # Check errorbars almost(res_errors, self.dataset.err_mag)
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_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_init_parameters(): """are parameters properly passed between Model and ModelParameters?""" t_0 = 6141.593 u_0 = 0.5425 t_E = 62.63 * u.day params = mm.ModelParameters({'t_0': t_0, 'u_0': u_0, 't_E': t_E}) model = mm.Model(parameters=params) almost(model.parameters.t_0, t_0) almost(model.parameters.u_0, u_0) almost(model.parameters.t_E, t_E.value)
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_model_binary_and_finite_sources(): """ test if model magnification calculation for binary source works with finite sources (both rho and t_star given) """ model = mm.Model({ 't_0_1': 5000., 'u_0_1': 0.005, 'rho_1': 0.001, 't_0_2': 5100., 'u_0_2': 0.0003, 't_star_2': 0.03, 't_E': 25. }) model_1 = mm.Model(model.parameters.source_1_parameters) model_2 = mm.Model(model.parameters.source_2_parameters) (t1, t2) = (4999.95, 5000.05) (t3, t4) = (5099.95, 5100.05) finite = 'finite_source_uniform_Gould94' model.set_magnification_methods( [t1, finite, t2, 'point_source', t3, finite, t4]) model_1.set_magnification_methods([t1, finite, t2]) model_2.set_magnification_methods([t3, finite, t4]) # prepare fake data: (f_s_1, f_s_2, f_b) = (100., 300., 50.) time = np.linspace(4900., 5200., 4200) mag_1 = model_1.magnification(time) mag_2 = model_2.magnification(time) flux = f_s_1 * mag_1 + f_s_2 * mag_2 + f_b data = mm.MulensData(data_list=[time, flux, 1. + 0. * time], phot_fmt='flux') model.set_datasets([data]) model_1.set_datasets([data]) model_2.set_datasets([data]) # test: fitted = model.get_data_magnification(data) expected = (mag_1 * f_s_1 + mag_2 * f_s_2) / (f_s_1 + f_s_2) almost(fitted, expected) # test separate=True option: (mag_1_, mag_2_) = model.magnification(time, separate=True) almost(mag_1, mag_1_) almost(mag_2, mag_2_)
def test_model_binary_and_finite_sources(): """ test if model magnification calculation for binary source works with finite sources (both rho and t_star given) """ model = mm.Model({ 't_0_1': 5000., 'u_0_1': 0.005, 'rho_1': 0.001, 't_0_2': 5100., 'u_0_2': 0.0003, 't_star_2': 0.03, 't_E': 25. }) model_1 = mm.Model(model.parameters.source_1_parameters) model_2 = mm.Model(model.parameters.source_2_parameters) (t1, t2) = (4999.95, 5000.05) (t3, t4) = (5099.95, 5100.05) finite = 'finite_source_uniform_Gould94' model.set_magnification_methods( [t1, finite, t2, 'point_source', t3, finite, t4]) model_1.set_magnification_methods([t1, finite, t2]) model_2.set_magnification_methods([t3, finite, t4]) (f_s_1, f_s_2, f_b) = (100., 300., 50.) time = np.linspace(4900., 5200., 4200) mag_1 = model_1.get_magnification(time) mag_2 = model_2.get_magnification(time) # test: model.set_source_flux_ratio(f_s_2/f_s_1) fitted = model.get_magnification(time, source_flux_ratio=f_s_2 / f_s_1) expected = (mag_1 * f_s_1 + mag_2 * f_s_2) / (f_s_1 + f_s_2) almost(fitted, expected) # test separate=True option: (mag_1_, mag_2_) = model.get_magnification(time, separate=True) almost(mag_1, mag_1_) almost(mag_2, mag_2_)
def test_intp_of_constant_arr(): h_in, w_in, d_in = 10, 20, 5 h_out, w_out, d_out = 5., 25., 5. x_in, y_in, z_in = np.mgrid[:h_in, :w_in, :d_in] x_out, y_out, z_out = np.mgrid[:h_out, :w_out, :d_out] x_out = 1. * x_out / x_out.max() * (h_in - 1.) y_out = 1. * y_out / y_out.max() * (w_in - 1.) z_out = 1. * z_out / z_out.max() * (d_in - 1.) # -- arbitrary constant function def f0(x, y): a = 1.234 return a * np.ones(x.shape) ref_out = f0(x_out, y_out) out0 = resample(f0(x_in, y_in), (h_out, w_out, d_out), order=0) almost(ref_out, out0) out1 = resample(f0(x_in, y_in), (h_out, w_out, d_out), order=1) almost(ref_out, out1) out2 = resample(f0(x_in, y_in), (h_out, w_out, d_out), order=2) almost(ref_out, out2) out3 = resample(f0(x_in, y_in), (h_out, w_out, d_out), order=3) almost(ref_out, out3) out4 = resample(f0(x_in, y_in), (h_out, w_out, d_out), order=4) almost(ref_out, out4) out5 = resample(f0(x_in, y_in), (h_out, w_out, d_out), order=5) almost(ref_out, out5)