def test_minimizer(): x = np.arange(-10, 10, .1) a = 5.3 b = -1.8 c = 3.4 gold_list = [a, b, c] y = a * x**2 + b * x + c # This test does NOT handle scaling correctly -- we would need a Model # which knows the parameters to properly handle the scaling/unscaling def cost_func(pars): a, b, c = pars return a * x**2 + b * x + c - y # test basic usage parameters = [ prior.Uniform(-np.inf, np.inf, name='a', guess=5), prior.Uniform(-np.inf, np.inf, name='b', guess=-2), prior.Uniform(-np.inf, np.inf, name='c', guess=3) ] minimizer = Nmpfit() result, minimization_details = minimizer.minimize(parameters, cost_func) assert_obj_close(result, gold_list, context='basic_minimized_parameters') # now test limiting minimizer iterations minimizer = Nmpfit(maxiter=1) try: result, minimization_details = minimizer.minimize( parameters, cost_func) except MinimizerConvergenceFailed as cf: # the fit shouldn't converge result, minimization_details = cf.result, cf.details assert_equal(minimization_details.niter, 2) # there's always an offset of 1
def test_fit_function_identical_to_strategy_method(self): model = SimpleModel() strategy = NmpfitStrategy(seed=123) strategy_result = strategy.fit(model, DATA) strategy_result.time = None model_result = fit(DATA, model, strategy=strategy) model_result.time = None self.assertEqual(strategy_result, model_result)
def test_model_fit_method_identical_to_strategy_method(self): model = SimpleModel() strategy = NmpfitStrategy(seed=123) data = np.array(.5) strategy_result = strategy.fit(model, data) strategy_result.time = None model_result = model.fit(data, strategy) model_result.time = None self.assertEqual(strategy_result, model_result)
def test_subset_data_fit_result_stores_model(self): model = self._make_model() holo = get_example_data('image0001') np.random.seed(40) fitter = NmpfitStrategy(npixels=100, maxiter=1) with warnings.catch_warnings(): warnings.simplefilter('ignore', UserWarning) # ignore not-converged warnings since we only do 2 iterations fitted = fitter.fit(model, holo) self.assertEqual(model, fitted.model)
def test_subset_data_fit_result_is_saveable(self): model = self._make_model() holo = get_example_data('image0001') np.random.seed(40) fitter = NmpfitStrategy(npixels=100, maxiter=1) with warnings.catch_warnings(): warnings.simplefilter('ignore', UserWarning) # ignore not-converged warnings since we only do 2 iterations fitted = fitter.fit(model, holo) result = fitted # was fix_flat(fitted) assert_read_matches_write(result)
def test_serialization(): par_s = Sphere(center=(Uniform(0, 1e-5, guess=.567e-5), Uniform(0, 1e-5, .567e-5), Uniform(1e-5, 2e-5)), r=Uniform(1e-8, 1e-5, 8.5e-7), n=Uniform(1, 2, 1.59)) alpha = Uniform(.1, 1, .6, 'alpha') schema = update_metadata(detector_grid(shape=100, spacing=.1151e-6), illum_wavelen=.66e-6, medium_index=1.33, illum_polarization=(1, 0)) model = AlphaModel(par_s, medium_index=schema.medium_index, illum_wavelen=schema.illum_wavelen, alpha=alpha) holo = calc_holo(schema, model.scatterer.guess, scaling=model.alpha.guess) result = fix_flat(NmpfitStrategy().fit(model, holo)) temp = tempfile.NamedTemporaryFile(suffix='.h5', delete=False) with warnings.catch_warnings(): warnings.simplefilter('ignore') save(temp.name, result) loaded = load(temp.name) assert_obj_close(result, loaded, context='serialized_result')
def fit(self): sphere_priors = self.make_guessed_scatterer() if self.theory == 'mielens': lens_prior = self.guess_lens_angle() model = PerfectLensModel( sphere_priors, noise_sd=self.data.noise_sd, lens_angle=lens_prior) elif self.theory == 'mieonly': alpha_prior = self.guess_alpha() model = AlphaModel( sphere_priors, noise_sd=self.data.noise_sd, alpha=alpha_prior) optimizer = NmpfitStrategy() result = optimizer.optimize(model, self.data) # FIXME this result sometimes leaves the allowed ranges. To get # result = hp.fitting.fit(model, self.data, minimizer=optimizer) return result
def test_fitted_uncertainties_similar_to_nmpfit(self): data = make_fake_data() model = make_model() fitter_scipy = LeastSquaresScipyStrategy(npixels=300) result_scipy = fitter_scipy.fit(model, data) uncertainties_scipy = pack_uncertainties_into_dict(result_scipy) fitter_nmp = NmpfitStrategy(npixels=300) result_nmp = fitter_nmp.fit(model, data) uncertainties_nmp = pack_uncertainties_into_dict(result_nmp) for key in uncertainties_scipy.keys(): self.assertTrue( np.isclose( uncertainties_scipy[key], uncertainties_nmp[key], rtol=0.1, atol=0))
def test_fitted_parameters_similar_to_nmpfit(self): data = make_fake_data() model = make_model() np.random.seed(40) fitter_scipy = LeastSquaresScipyStrategy(npixels=300, ftol=1e-6) result_scipy = fitter_scipy.fit(model, data) params_scipy = result_scipy.parameters np.random.seed(40) fitter_nmp = NmpfitStrategy(npixels=300, ftol=1e-6) result_nmp = fitter_nmp.fit(model, data) params_nmp = result_nmp.parameters for key in params_scipy.keys(): self.assertAlmostEqual(params_scipy[key], params_nmp[key], places=4)
def test_optimization_with_maxiter_of_2(): gold_fit_dict = { '0:r': 0.52480509800531849, '1:center.1': 14.003687569304704, 'alpha': 0.93045027963762217, '0:center.2': 19.93177549652841, '1:r': 0.56292664494653732, '0:center.1': 15.000340621607815, '1:center.0': 14.020984607646726, '0:center.0': 15.000222185576494, '1:center.2': 20.115613202192328 } #calculate a hologram with known particle positions to do a fit against schema = detector_grid(shape=100, spacing=.1) s1 = Sphere(center=(15, 15, 20), n=1.59, r=0.5) s2 = Sphere(center=(14, 14, 20), n=1.59, r=0.5) cluster = Spheres([s1, s2]) holo = calc_holo(schema, cluster, 1.33, .66, illum_polarization=(1, 0)) #trying to do a fast fit: guess1 = Sphere(center=(prior.Uniform(5, 25, guess=15), prior.Uniform(5, 25, 15), prior.Uniform(5, 25, 20)), r=(prior.Uniform(.4, .6, guess=.45)), n=1.59) guess2 = Sphere(center=(prior.Uniform(5, 25, guess=14), prior.Uniform(5, 25, 14), prior.Uniform(5, 25, 20)), r=(prior.Uniform(.4, .6, guess=.45)), n=1.59) par_s = Spheres([guess1, guess2]) model = AlphaModel(par_s, medium_index=1.33, illum_wavelen=.66, illum_polarization=(1, 0), alpha=prior.Uniform(.1, 1, .6)) optimizer = Nmpfit(maxiter=2) with warnings.catch_warnings(): warnings.simplefilter('ignore') result = optimizer.fit(model, holo) assert_obj_close(gold_fit_dict, result.parameters, rtol=1e-5)
def test_layered(): s = Sphere(n=(1, 2), r=(1, 2), center=(2, 2, 2)) sch = detector_grid((10, 10), .2) hs = calc_holo(sch, s, 1, .66, (1, 0)) guess = LayeredSphere((1, 2), (Uniform(1, 1.01), Uniform(.99, 1)), (2, 2, 2)) model = ExactModel(guess, calc_holo) res = NmpfitStrategy().fit(model, hs) assert_allclose(res.scatterer.t, (1, 1), rtol=1e-12)
def test_returns_close_values(self): model = self._make_model() holo = normalize(get_example_data('image0001')) np.random.seed(40) result = NmpfitStrategy(npixels=1000).fit(model, holo) # TODO: figure out if it is a problem that alpha is frequently # coming out wrong in the 3rd decimal place. self.assertAlmostEqual(result.parameters['alpha'], gold_alpha, places=3) # TODO: this tolerance has to be rather large to pass, we should # probably track down if this is a sign of a problem assert_obj_close(result.scatterer, gold_sphere, rtol=1e-2)
def test_integer_correctness(): # we keep having bugs where the fitter doesn't schema = detector_grid(shape=10, spacing=1) s = Sphere(center=(10.2, 9.8, 10.3), r=.5, n=1.58) holo = calc_holo(schema, s, illum_wavelen=.660, medium_index=1.33, illum_polarization=(1, 0)) par_s = Sphere(r=.5, n=1.58, center=(Uniform(5, 15), Uniform(5, 15), Uniform(5, 15))) model = AlphaModel(par_s, alpha=Uniform(.1, 1, .6)) result = NmpfitStrategy().fit(model, holo) assert_allclose(result.scatterer.center, [10.2, 9.8, 10.3])
def test_fit_mie_par_scatterer(): holo = normalize(get_example_data('image0001')) s = Sphere(center=(Uniform(0, 1e-5, guess=.567e-5), Uniform(0, 1e-5, .567e-5), Uniform(1e-5, 2e-5)), r=Uniform(1e-8, 1e-5, 8.5e-7), n=ComplexPrior(Uniform(1, 2, 1.59), 1e-4)) thry = Mie(False) model = AlphaModel(s, theory=thry, alpha=Uniform(.1, 1, .6)) result = fix_flat(NmpfitStrategy().fit(model, holo)) assert_obj_close(result.scatterer, gold_sphere, rtol=1e-3) # TODO: see if we can get this back to 3 sig figs correct alpha assert_approx_equal(result.parameters['alpha'], gold_alpha, significant=3) assert_equal(model, result.model) assert_read_matches_write(result)
def test_fit_random_subset(): holo = normalize(get_example_data('image0001')) s = Sphere(center=(Uniform(0, 1e-5, guess=.567e-5), Uniform(0, 1e-5, .567e-5), Uniform(1e-5, 2e-5)), r=Uniform(1e-8, 1e-5, 8.5e-7), n=ComplexPrior(Uniform(1, 2, 1.59), 1e-4)) model = AlphaModel(s, theory=Mie(False), alpha=Uniform(.1, 1, .6)) np.random.seed(40) result = fix_flat(NmpfitStrategy(npixels=1000).fit(model, holo)) # TODO: this tolerance has to be rather large to pass, we should # probably track down if this is a sign of a problem assert_obj_close(result.scatterer, gold_sphere, rtol=1e-2) # TODO: figure out if it is a problem that alpha is frequently coming out # wrong in the 3rd decimal place. assert_approx_equal(result.parameters['alpha'], gold_alpha, significant=3) assert_equal(model, result.model) assert_read_matches_write(result)
def test_fit_mie_single(): holo = normalize(get_example_data('image0001')) parameters = [ Uniform(0, 1e-5, name='x', guess=.567e-5), Uniform(0, 1e-5, name='y', guess=.576e-5), Uniform(1e-5, 2e-5, name='z', guess=15e-6), Uniform(1, 2, name='n', guess=1.59), Uniform(1e-8, 1e-5, name='r', guess=8.5e-7) ] def make_scatterer(parlist): return Sphere(n=parlist[3], r=parlist[4], center=parlist[0:3]) thry = Mie(False) model = AlphaModel(make_scatterer(parameters), theory=thry, alpha=Uniform(.1, 1, name='alpha', guess=.6)) result = NmpfitStrategy().fit(model, holo) assert_obj_close(result.scatterer, gold_sphere, rtol=1e-3) assert_approx_equal(result.parameters['alpha'], gold_alpha, significant=3) assert_equal(model, result.model)
def test_default_fit_strategy_is_nmpfit(self): model = Model(Sphere()) default_strategy = model.validate_strategy(None, 'fit') self.assertEqual(NmpfitStrategy(), default_strategy)
def test_default_fit_strategy_is_Nmpfit(self): result = fit(DATA, SimpleModel()) self.assertEqual(result.strategy, NmpfitStrategy())
def test_fit_takes_strategy_object(self): strategy = NmpfitStrategy(npixels=2, maxiter=2) result = fit(DATA, SimpleModel(), strategy=strategy) self.assertEqual(result.strategy, strategy)