def test_fit_mie_single(): holo = normalize(get_example_data('image0001.yaml')) parameters = [ Parameter(name='x', guess=.567e-5, limit=[0.0, 1e-5]), Parameter(name='y', guess=.576e-5, limit=[0, 1e-5]), Parameter(name='z', guess=15e-6, limit=[1e-5, 2e-5]), Parameter(name='n', guess=1.59, limit=[1, 2]), Parameter(name='r', guess=8.5e-7, limit=[1e-8, 1e-5]) ] def make_scatterer(x, y, z, r, n): return Sphere(n=n + 1e-4j, r=r, center=(x, y, z)) thry = Mie(False) model = Model(Parametrization(make_scatterer, parameters), thry.calc_holo, alpha=Parameter(name='alpha', guess=.6, limit=[.1, 1])) assert_raises(InvalidMinimizer, fit, model, holo, minimizer=Sphere) result = 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_dda_fit(): s = Sphere(n=1.59, r=.2, center=(5, 5, 5)) o = Optics(wavelen=.66, index=1.33, pixel_scale=.1) schema = ImageSchema(optics=o, shape=100) h = Mie.calc_holo(s, schema) def make_scatterer(r, x, y, z): local_s = Sphere(r=r, center=(x, y, z)) return Scatterer(local_s.indicators, n=s.n) parameters = [ par(.18, [.1, .3], name='r', step=.1), par(5, [4, 6], 'x'), par(5, [4, 6], 'y'), par(5.2, [4, 6], 'z') ] p = Parametrization(make_scatterer, parameters) model = Model(p, DDA.calc_holo) res = fit(model, h) assert_parameters_allclose(res.parameters, dict([('r', 0.2003609439787491), ('x', 5.0128083665603995), ('y', 5.0125252883133617), ('z', 4.9775097284878775)]), rtol=1e-3)
def test_serialization(): par_s = Sphere(center=(par(.567e-5, [0, 1e-5]), par(.576e-6, [0, 1e-5]), par(15e-6, [1e-5, 2e-5])), r=par(8.5e-7, [1e-8, 1e-5]), n=par(1.59, [1, 2])) alpha = par(.6, [.1, 1], 'alpha') schema = ImageSchema(shape=100, spacing=.1151e-6, optics=Optics(.66e-6, 1.33)) model = Model(par_s, Mie.calc_holo, alpha=alpha) holo = Mie.calc_holo(model.scatterer.guess, schema, model.alpha.guess) result = fit(model, holo) temp = tempfile.NamedTemporaryFile() save(temp, result) temp.flush() temp.seek(0) loaded = load(temp) assert_obj_close(result, loaded, context='serialized_result')
def series_guess(model, data, data_optics=None, data_spacing=None, bg=None, df=None, preprocess_func=div_normalize, **kwargs): """See the guess that would be used in a series fit This function intentionally takes the same arguments as series_fit so that you can call series_guess and compare to data[0] before starting a fit Parameters ---------- model : :class:`.Model` object A model describing the scattering system which leads to your data and the parameters to vary to fit it to the data data : list(filenames) or list(:class:`.Image`) List of Image objects to fit, or full paths of images to load data_optics : :class:`.Optics` (optional) Optics information (only required if loading image files without optical information) data_spacing : float or np.array Pixel spacing for data. (Only required if loading image files without spacing information) bg : :class:`.Image` object or path Optional background image to be used for cleaning up the raw data images df : :class:`.Image` object or path Optional darkfield image to be used for cleaning up the raw data images preprocess_func : function Handles pre-processing images before fitting the model to them kwargs : varies additional arguments to pass to fit for each frame Returns ------- guess : marray (like data[0]) The initial guess that would be used for fitting data[0] in fit_series """ if isinstance(bg, basestring): bg = load(bg, spacing=data_spacing, optics=data_optics) if not isinstance(frame, Image): frame = load(frame, spacing=data_spacing, optics=data_optics) imagetofit = preprocess_func(frame, bg, df, model) result = fit(model, imagetofit, **kwargs) allresults.append(result) if outf != '': save(outf, result) model = update_func(model, result) return allresults
def test_layered(): s = Sphere(n = (1,2), r = (1, 2), center = (2, 2, 2)) sch = ImageSchema((10, 10), .2, Optics(.66, 1, (1, 0))) hs = Mie.calc_holo(s, sch) guess = hp.scattering.scatterer.sphere.LayeredSphere((1,2), (par(1.01), par(.99)), (2, 2, 2)) model = Model(guess, Mie.calc_holo) res = fit(model, hs) assert_allclose(res.scatterer.t, (1, 1), rtol = 1e-12)
def test_fit_multisphere_noisydimer_slow(): optics = Optics(wavelen=658e-9, polarization = [0., 1.0], divergence = 0., pixel_scale = [0.345e-6, 0.345e-6], index = 1.334) holo = normalize(get_example_data('image0002.yaml')) # Now construct the model, and fit parameters = [Parameter(name = 'x0', guess = 1.64155e-5, limit = [0, 1e-4]), Parameter(1.7247e-5, [0, 1e-4], 'y0'), Parameter(20.582e-6, [0, 1e-4], 'z0'), Parameter(.6856e-6, [1e-8, 1e-4], 'r0'), Parameter(1.6026, [1, 2], 'nr0'), Parameter(1.758e-5, [0, 1e-4], 'x1'), Parameter(1.753e-5, [0, 1e-4], 'y1'), Parameter(21.2698e-6, [1e-8, 1e-4], 'z1'), Parameter(.695e-6, [1e-8, 1e-4], 'r1'), Parameter(1.6026, [1, 2], 'nr1')] def make_scatterer(x0, x1, y0, y1, z0, z1, r0, r1, nr0, nr1): s = Spheres([ Sphere(center = (x0, y0, z0), r=r0, n = nr0+1e-5j), Sphere(center = (x1, y1, z1), r=r1, n = nr1+1e-5j)]) return s # initial guess #s1 = Sphere(n=1.6026+1e-5j, r = .6856e-6, # center=(1.64155e-05, 1.7247e-05, 20.582e-6)) #s2 = Sphere(n=1.6026+1e-5j, r = .695e-6, # center=(1.758e-05, 1.753e-05, 21.2698e-6)) #sc = Spheres([s1, s2]) #alpha = 0.99 #lb1 = Sphere(1+1e-5j, 1e-8, 0, 0, 0) #ub1 = Sphere(2+1e-5j, 1e-5, 1e-4, 1e-4, 1e-4) #step1 = Sphere(1e-4+1e-4j, 1e-8, 0, 0, 0) #lb = Spheres([lb1, lb1]), .1 #ub = Spheres([ub1, ub1]), 1 #step = Spheres([step1, step1]), 0 model = Model(parameters, Multisphere, make_scatterer=make_scatterer, alpha = Parameter(.99, [.1, 1.0], 'alpha')) result = fit(model, holo) print result.scatterer gold = np.array([1.642e-5, 1.725e-5, 2.058e-5, 1e-5, 1.603, 6.857e-7, 1.758e-5, 1.753e-5, 2.127e-5, 1e-5, 1.603, 6.964e-7]) gold_alpha = 1.0 assert_parameters_allclose(result.scatterer, gold, rtol=1e-2) # TODO: This test fails, alpha comes back as .9899..., where did # the gold come from? assert_approx_equal(result.alpha, gold_alpha, significant=2)
def test_fit_complex_parameter(): ''' Test that complex parameters are handled correctly when fit. ''' # use a Sphere with complex n # a fake scattering model def scat_func(sph, schema, scaling=None): # TODO: scaling kwarg required, seems like a silly kluge def silly_function(theta): return theta * sph.r + sph.n.real * theta**2 + 2. * sph.n.imag #import pdb #pdb.set_trace() return Marray( np.array([ silly_function(theta) for theta, phi in schema.positions_theta_phi() ]), **schema._dict) # generate data schema = Schema(positions=Angles(np.linspace(0., np.pi / 2., 6))) ref_sph = Sphere(r=1.5, n=0.4 + 0.8j) data = scat_func(ref_sph, schema) # varying both real and imaginary parts par_s = Sphere(r=par(1.49), n=ComplexParameter(real=par(0.405), imag=par(0.81))) model = Model(par_s, scat_func) result = fit(model, data) assert_allclose(result.scatterer.r, ref_sph.r) assert_allclose(result.scatterer.n.real, ref_sph.n.real) assert_allclose(result.scatterer.n.imag, ref_sph.n.imag) # varying just the real part par_s2 = Sphere(r=par(1.49), n=ComplexParameter(real=par(0.405), imag=0.8)) model2 = Model(par_s2, scat_func) result2 = fit(model2, data) assert_allclose(result2.scatterer.r, ref_sph.r) assert_allclose(result2.scatterer.n.real, ref_sph.n.real) assert_allclose(result2.scatterer.n.imag, ref_sph.n.imag)
def test_fit_superposition(): """ Fit Mie superposition to a calculated hologram from two spheres """ # Make a test hologram optics = Optics(wavelen=6.58e-07, index=1.33, polarization=[0.0, 1.0], divergence=0, spacing=None, train=None, mag=None, pixel_scale=[2 * 2.302e-07, 2 * 2.302e-07]) s1 = Sphere(n=1.5891 + 1e-4j, r=.65e-6, center=(1.56e-05, 1.44e-05, 15e-6)) s2 = Sphere(n=1.5891 + 1e-4j, r=.65e-6, center=(3.42e-05, 3.17e-05, 10e-6)) sc = Spheres([s1, s2]) alpha = .629 theory = Mie(optics, 100) holo = theory.calc_holo(sc, alpha) # Now construct the model, and fit parameters = [ Parameter(name='x0', guess=1.6e-5, limit=[0, 1e-4]), Parameter('y0', 1.4e-5, [0, 1e-4]), Parameter('z0', 15.5e-6, [0, 1e-4]), Parameter('r0', .65e-6, [0.6e-6, 0.7e-6]), Parameter('nr', 1.5891, [1, 2]), Parameter('x1', 3.5e-5, [0, 1e-4]), Parameter('y1', 3.2e-5, [0, 1e-4]), Parameter('z1', 10.5e-6, [0, 1e-4]), Parameter('r1', .65e-6, [0.6e-6, 0.7e-6]) ] def make_scatterer(x0, x1, y0, y1, z0, z1, r0, r1, nr): s = Spheres([ Sphere(center=(x0, y0, z0), r=r0, n=nr + 1e-4j), Sphere(center=(x1, y1, z1), r=r1, n=nr + 1e-4j) ]) return s model = Model(parameters, Mie, make_scatterer=make_scatterer, alpha=Parameter('alpha', .63, [.5, 0.8])) result = fit(model, holo) assert_obj_close(result.scatterer, sc) assert_approx_equal(result.alpha, alpha, significant=4) assert_equal(result.model, model) assert_read_matches_write(result)
def test_integer_correctness(): # we keep having bugs where the fitter doesn't schema = ImageSchema(shape = 100, spacing = .1, optics = Optics(wavelen = .660, index = 1.33, polarization = (1, 0))) s = Sphere(center = (10.2, 9.8, 10.3), r = .5, n = 1.58) holo = Mie.calc_holo(s, schema) par_s = Sphere(center = (par(guess = 10, limit = [5,15]), par(10, [5, 15]), par(10, [5, 15])), r = .5, n = 1.58) model = Model(par_s, Mie.calc_holo, alpha = par(.6, [.1, 1])) result = fit(model, holo) assert_allclose(result.scatterer.center, [10.2, 9.8, 10.3])
def test_fit_complex_parameter(): ''' Test that complex parameters are handled correctly when fit. ''' # use a Sphere with complex n # a fake scattering model def scat_func(sph, schema, scaling = None): # TODO: scaling kwarg required, seems like a silly kluge def silly_function(theta): return theta * sph.r + sph.n.real * theta **2 + 2. * sph.n.imag #import pdb #pdb.set_trace() return Marray(np.array([silly_function(theta) for theta, phi in schema.positions_theta_phi()]), **schema._dict) # generate data schema = Schema(positions = Angles(np.linspace(0., np.pi/2., 6))) ref_sph = Sphere(r = 1.5, n = 0.4 + 0.8j) data = scat_func(ref_sph, schema) # varying both real and imaginary parts par_s = Sphere(r = par(1.49), n = ComplexParameter(real = par(0.405), imag = par(0.81))) model = Model(par_s, scat_func) result = fit(model, data) assert_allclose(result.scatterer.r, ref_sph.r) assert_allclose(result.scatterer.n.real, ref_sph.n.real) assert_allclose(result.scatterer.n.imag, ref_sph.n.imag) # varying just the real part par_s2 = Sphere(r = par(1.49), n = ComplexParameter(real = par(0.405), imag = 0.8)) model2 = Model(par_s2, scat_func) result2 = fit(model2, data) assert_allclose(result2.scatterer.r, ref_sph.r) assert_allclose(result2.scatterer.n.real, ref_sph.n.real) assert_allclose(result2.scatterer.n.imag, ref_sph.n.imag)
def test_fit_single_openopt(): holo = normalize(get_example_data('image0001.yaml')) s = Sphere(center = (par(guess=.567e-5, limit=[.4e-5,.6e-5]), par(.567e-5, (.4e-5, .6e-5)), par(15e-6, (1.3e-5, 1.8e-5))), r = par(8.5e-7, (5e-7, 1e-6)), n = ComplexParameter(par(1.59, (1.5,1.8)), 1e-4j)) model = Model(s, Mie(False).calc_holo, alpha = par(.6, [.1,1])) try: minimizer = OpenOpt('scipy_slsqp') except ImportError: raise SkipTest result = fit(model, holo, minimizer = minimizer) 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)
def test_fit_mie_par_scatterer(): holo = normalize(get_example_data('image0001.yaml')) s = Sphere(center = (par(guess=.567e-5, limit=[0,1e-5]), par(.567e-5, (0, 1e-5)), par(15e-6, (1e-5, 2e-5))), r = par(8.5e-7, (1e-8, 1e-5)), n = ComplexParameter(par(1.59, (1,2)), 1e-4j)) thry = Mie(False) model = Model(s, thry.calc_holo, alpha = par(.6, [.1,1])) result = 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_superposition(): """ Fit Mie superposition to a calculated hologram from two spheres """ # Make a test hologram optics = Optics(wavelen=6.58e-07, index=1.33, polarization=[0.0, 1.0], divergence=0, spacing=None, train=None, mag=None, pixel_scale=[2*2.302e-07, 2*2.302e-07]) s1 = Sphere(n=1.5891+1e-4j, r = .65e-6, center=(1.56e-05, 1.44e-05, 15e-6)) s2 = Sphere(n=1.5891+1e-4j, r = .65e-6, center=(3.42e-05, 3.17e-05, 10e-6)) sc = Spheres([s1, s2]) alpha = .629 theory = Mie(optics, 100) holo = theory.calc_holo(sc, alpha) # Now construct the model, and fit parameters = [Parameter(name = 'x0', guess = 1.6e-5, limit = [0, 1e-4]), Parameter('y0', 1.4e-5, [0, 1e-4]), Parameter('z0', 15.5e-6, [0, 1e-4]), Parameter('r0', .65e-6, [0.6e-6, 0.7e-6]), Parameter('nr', 1.5891, [1, 2]), Parameter('x1', 3.5e-5, [0, 1e-4]), Parameter('y1', 3.2e-5, [0, 1e-4]), Parameter('z1', 10.5e-6, [0, 1e-4]), Parameter('r1', .65e-6, [0.6e-6, 0.7e-6])] def make_scatterer(x0, x1, y0, y1, z0, z1, r0, r1, nr): s = Spheres([ Sphere(center = (x0, y0, z0), r=r0, n = nr+1e-4j), Sphere(center = (x1, y1, z1), r=r1, n = nr+1e-4j)]) return s model = Model(parameters, Mie, make_scatterer=make_scatterer, alpha = Parameter('alpha', .63, [.5, 0.8])) result = fit(model, holo) assert_obj_close(result.scatterer, sc) assert_approx_equal(result.alpha, alpha, significant=4) assert_equal(result.model, model) assert_read_matches_write(result)
def test_fit_random_subset(): holo = normalize(get_example_data('image0001.yaml')) s = Sphere(center = (par(guess=.567e-5, limit=[0,1e-5]), par(.567e-5, (0, 1e-5)), par(15e-6, (1e-5, 2e-5))), r = par(8.5e-7, (1e-8, 1e-5)), n = ComplexParameter(par(1.59, (1,2)),1e-4)) model = Model(s, Mie(False).calc_holo, alpha = par(.6, [.1,1])) np.random.seed(40) result = fit(model, holo, random_subset=.1) # 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_random_subset(): holo = normalize(get_example_data('image0001.yaml')) s = Sphere(center = (par(guess=.567e-5, limit=[0,1e-5]), par(.567e-5, (0, 1e-5)), par(15e-6, (1e-5, 2e-5))), r = par(8.5e-7, (1e-8, 1e-5)), n = ComplexParameter(par(1.59, (1,2)),1e-4j)) model = Model(s, Mie.calc_holo, alpha = par(.6, [.1,1])) np.random.seed(40) result = fit(model, holo, random_subset=.1) # we have to use a relatively loose tolerance here because the random # selection occasionally causes the fit to be a bit worse assert_obj_close(result.scatterer, gold_sphere, rtol=1e-3) # 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_random_subset(): holo = normalize(get_example_data('image0001.yaml')) s = Sphere(center = (par(guess=.567e-5, limit=[0,1e-5]), par(.567e-5, (0, 1e-5)), par(15e-6, (1e-5, 2e-5))), r = par(8.5e-7, (1e-8, 1e-5)), n = ComplexParameter(par(1.59, (1,2)),1e-4j)) model = Model(s, Mie.calc_holo, alpha = par(.6, [.1,1])) np.random.seed(40) result = fit(model, holo, use_random_fraction=.1) # we have to use a relatively loose tolerance here because the random # selection occasionally causes the fit to be a bit worse 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=2) assert_equal(model, result.model) assert_read_matches_write(result)
def test_fit_random_subset(): holo = normalize(get_example_data('image0001.yaml')) s = Sphere(center=(par(guess=.567e-5, limit=[0, 1e-5]), par(.567e-5, (0, 1e-5)), par(15e-6, (1e-5, 2e-5))), r=par(8.5e-7, (1e-8, 1e-5)), n=ComplexParameter(par(1.59, (1, 2)), 1e-4)) model = Model(s, Mie(False).calc_holo, alpha=par(.6, [.1, 1])) np.random.seed(40) result = fit(model, holo, random_subset=.1) # 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.yaml')) parameters = [Parameter(name='x', guess=.567e-5, limit = [0.0, 1e-5]), Parameter(name='y', guess=.576e-5, limit = [0, 1e-5]), Parameter(name='z', guess=15e-6, limit = [1e-5, 2e-5]), Parameter(name='n', guess=1.59, limit = [1, 2]), Parameter(name='r', guess=8.5e-7, limit = [1e-8, 1e-5])] def make_scatterer(x, y, z, r, n): return Sphere(n=n+1e-4j, r = r, center = (x, y, z)) thry = Mie(False) model = Model(Parametrization(make_scatterer, parameters), thry.calc_holo, alpha=Parameter(name='alpha', guess=.6, limit = [.1, 1])) assert_raises(InvalidMinimizer, fit, model, holo, minimizer=Sphere) result = 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_dda_fit(): s = Sphere(n = 1.59, r = .2, center = (5, 5, 5)) o = Optics(wavelen = .66, index=1.33, pixel_scale=.1) schema = ImageSchema(optics = o, shape = 100) h = Mie.calc_holo(s, schema) def make_scatterer(r, x, y, z): local_s = Sphere(r = r, center = (x, y, z)) return Scatterer(local_s.indicators, n = s.n) parameters = [par(.18, [.1, .3], name='r', step=.1), par(5, [4, 6], 'x'), par(5, [4,6], 'y'), par(5.2, [4, 6], 'z')] p = Parametrization(make_scatterer, parameters) model = Model(p, DDA.calc_holo) res = fit(model, h) assert_parameters_allclose(res.parameters, OrderedDict([('r', 0.2003609439787491), ('x', 5.0128083665603995), ('y', 5.0125252883133617), ('z', 4.9775097284878775)]), rtol=1e-3)
def test_serialization(): par_s = Sphere(center = (par(.567e-5, [0, 1e-5]), par(.576e-6, [0, 1e-5]), par(15e-6, [1e-5, 2e-5])), r = par(8.5e-7, [1e-8, 1e-5]), n = par(1.59, [1,2])) alpha = par(.6, [.1, 1], 'alpha') schema = ImageSchema(shape = 100, spacing = .1151e-6, optics = Optics(.66e-6, 1.33)) model = Model(par_s, Mie.calc_holo, alpha=alpha) holo = Mie.calc_holo(model.scatterer.guess, schema, model.alpha.guess) result = fit(model, holo) temp = tempfile.NamedTemporaryFile() save(temp, result) temp.flush() temp.seek(0) loaded = load(temp) assert_obj_close(result, loaded, context = 'serialized_result')
def fit_series(model, data, data_optics=None, data_spacing=None, bg=None, df=None, outfilenames=None, preprocess_func=div_normalize, update_func=update_all, **kwargs): """ fit a model to each frame of data in a time series Parameters ---------- model : :class:`.Model` object A model describing the scattering system which leads to your data and the parameters to vary to fit it to the data data : list(filenames) or list(:class:`.Image`) List of Image objects to fit, or full paths of images to load data_optics : :class:`.Optics` (optional) Optics information (only required if loading image files without optical information) data_spacing : float or np.array Pixel spacing for data. (Only required if loading image files without spacing information) bg : :class:`.Image` object or path Optional background image to be used for cleaning up the raw data images df : :class:`.Image` object or path Optional darkfield image to be used for cleaning up the raw data images outfilenames : list Full paths to save output for each image, if not included, nothing saved preprocess_func : function Handles pre-processing images before fitting the model to them update_func : function Updates the model (typically just the paramter guess) for the next frame kwargs : varies additional arguments to pass to fit for each frame Returns ------- allresults : :list:` List of all the result objects (one per frame) """ allresults = [] if isinstance(bg, basestring): bg = load(bg, spacing=data_spacing, optics=data_optics) #to allow running without saving output if outfilenames is None: outfilenames = ['']*len(data) else: mkdir_p(os.path.split(outfilenames[0])[0]) for frame, outf in zip(data, outfilenames): if not isinstance(frame, Image): frame = load(frame, spacing=data_spacing, optics=data_optics) imagetofit = preprocess_func(frame, bg, df, model) result = fit(model, imagetofit, **kwargs) allresults.append(result) if outf != '': save(outf, result) model = update_func(model, result) return allresults
def fit_series(model, data, data_optics=None, data_spacing=None, bg=None, df=None, outfilenames=None, preprocess_func=div_normalize, update_func=update_all, restart=False, **kwargs): """ fit a model to each frame of data in a time series Parameters ---------- model : :class:`.Model` object A model describing the scattering system which leads to your data and the parameters to vary to fit it to the data data : list(filenames) or list(:class:`.Image`) List of Image objects to fit, or full paths of images to load data_optics : :class:`.Optics` (optional) Optics information (only required if loading image files without optical information) data_spacing : float or np.array Pixel spacing for data. (Only required if loading image files without spacing information) bg : :class:`.Image` object or path Optional background image to be used for cleaning up the raw data images df : :class:`.Image` object or path Optional darkfield image to be used for cleaning up the raw data images outfilenames : list Full paths to save output for each image, if not included, nothing saved preprocess_func : function Handles pre-processing images before fitting the model to them update_func : function Updates the model (typically just the paramter guess) for the next frame restart : Bool Pick up a series fit that was interrupted. For any frame, if outfilename already exists load it instead of doing a fit kwargs : varies additional arguments to pass to fit for each frame Returns ------- allresults : :list:` List of all the result objects (one per frame) """ allresults = [] if isinstance(bg, basestring): bg = load(bg, spacing=data_spacing, optics=data_optis) #to allow running without saving output if outfilenames is None: outfilenames = [''] * len(data) for frame, outf in zip(data, outfilenames): if restart and os.path.exists(outf): result = load(outf) else: if outf != '': mkdir_p(os.path.split(outf)[0]) if not isinstance(frame, Image): frame = load(frame, spacing=data_spacing, optics=data_optics) imagetofit = preprocess_func(frame, bg, df, model) result = fit(model, imagetofit, **kwargs) allresults.append(result) if outf != '': save(outf, result) model = update_func(model, result) return allresults