def _get_parameter(self, name, pars, schema=None): interpreted_pars = _interpret_parameters(pars) if name in pars.keys(): return pars[name] elif name in interpreted_pars.keys(): return interpreted_pars[name] elif hasattr(self, name): return getattr(self, name) try: return getattr(schema, name) except: raise MissingParameter(name)
def __init__(self, data, model, strategy, time, kwargs={}): self.data = data self.model = model self.strategy = strategy if hasattr(strategy, 'parallel') and hasattr(strategy.parallel, 'map'): self.strategy.parallel = 'external_pool' self.time = time self._kwargs_keys = [] self.add_attr(kwargs) needs_intervals = not isinstance(self, SamplingResult) if needs_intervals and not hasattr(self, 'intervals'): raise MissingParameter('intervals')
def _find_noise(self, pars, schema): """ finds appropriate noise_sd for residuals calculations Parameters ---------- pars: list values to create noise_sd. Order should match model._parameters """ optics_map = read_map(self._maps['optics'], pars) if 'noise_sd' in optics_map and optics_map['noise_sd'] is not None: val = optics_map['noise_sd'] elif hasattr(schema, 'noise_sd'): val = schema.noise_sd else: raise MissingParameter('noise_sd') if val is None: if np.all([isinstance(par, Uniform) for par in self._parameters]): val = 1 else: raise MissingParameter('noise_sd for non-uniform priors') return val
def calculate_scattered_field(self, scatterer, schema): """ Implemented in derived classes only. Parameters ---------- scatterer : :mod:`.scatterer` object (possibly composite) scatterer for which to compute scattering Returns ------- e_field : :mod:`.VectorGrid` scattered electric field """ if scatterer.center is None: raise MissingParameter("center") is_multicolor_hologram = len(ensure_array(schema.illum_wavelen)) > 1 field = (self._calculate_multiple_color_scattered_field( scatterer, schema) if is_multicolor_hologram else self._calculate_single_color_scattered_field( scatterer, schema)) return field
def fit(self, model, data): """ fit a model to some data Parameters ---------- model : :class:`~holopy.fitting.model.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 : xarray.DataArray The data to fit Returns ------- result : :class:`FitResult` Contains the best fit parameters and information about the fit """ # timing decorator... time_start = time.time() parameters = model._parameters if len(parameters) == 0: raise MissingParameter('at least one parameter to fit') if self.npixels is None: data = flat(data) else: data = make_subset_data(data, pixels=self.npixels) guess_lnprior = model.lnprior( {par.name:par.guess for par in parameters}) def residual(rescaled_values): unscaled_values = self.unscale_pars_from_minimizer( parameters, rescaled_values) noise = model._find_noise(unscaled_values, data) residuals = model._residuals(unscaled_values, data, noise) ln_prior = model.lnprior(unscaled_values) - guess_lnprior zscore_prior = np.sqrt(2 * -ln_prior) np.append(residuals, zscore_prior) return residuals # The only work here fitted_pars, minimizer_info = self.minimize(parameters, residual) if not minimizer_info.success: warnings.warn("Minimizer Convergence Failed, your results \ may not be correct.") unit_errors = self._calculate_unit_noise_errors_from_fit(minimizer_info) noise = model._find_noise(fitted_pars, data) errors_scaled = noise * unit_errors errors = self.unscale_pars_from_minimizer(parameters, errors_scaled) intervals = [ UncertainValue( fitted_pars[par.name], errors[par.name], name=par.name) for err, par in zip(errors, parameters)] # timing decorator... d_time = time.time() - time_start kwargs = {'intervals': intervals, 'minimizer_info': minimizer_info} return FitResult(data, model, self, d_time, kwargs)