# Changeset 8803a38 in sasmodels

Ignore:
Timestamp:
Dec 13, 2018 11:08:39 AM (5 weeks ago)
Branches:
master
Children:
f9014c7
Parents:
2c4a190 (diff), 899e050 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of github.com:sasview/sasmodels

Files:
6 edited

Unmodified
Removed
• ## doc/guide/plugin.rst

 r57c609b structure factor to account for interactions between particles.  See Form_Factors_ for more details. **model_info = ...** lets you define a model directly, for example, by loading and modifying existing models.  This is done implicitly by :func:sasmodels.core.load_model_info, which can create a mixture model from a pair of existing models.  For example:: from sasmodels.core import load_model_info model_info = load_model_info('sphere+cylinder') See :class:sasmodels.modelinfo.ModelInfo for details about the model attributes that are defined. Model Parameters
• ## sasmodels/sasview_model.py

 rce1eed5 from . import core from . import custom from . import kernelcl from . import product from . import generate from . import modelinfo from .details import make_kernel_args, dispersion_mesh from .kernelcl import reset_environment # pylint: disable=unused-import #: has changed since we last reloaded. _CACHED_MODULE = {}  # type: Dict[str, "module"] def reset_environment(): # type: () -> None """ Clear the compute engine context so that the GUI can change devices. This removes all compiled kernels, even those that are active on fit pages, but they will be restored the next time they are needed. """ kernelcl.reset_environment() for model in MODELS.values(): model._model = None def find_model(modelname): def _calculate_Iq(self, qx, qy=None): if self._model is None: self._model = core.build_model(self._model_info) # Only need one copy of the compiled kernel regardless of how many # times it is used, so store it in the class.  Also, to reset the # compute engine, need to clear out all existing compiled kernels, # which is much easier to do if we store them in the class. self.__class__._model = core.build_model(self._model_info) if qy is not None: q_vectors = [np.asarray(qx), np.asarray(qy)]
• ## example/multiscatfit.py

 r49d1f8b8 # Show the model without fitting PYTHONPATH=..:../explore:../../bumps:../../sasview/src python multiscatfit.py PYTHONPATH=..:../../bumps:../../sasview/src python multiscatfit.py # Run the fit PYTHONPATH=..:../explore:../../bumps:../../sasview/src ../../bumps/run.py \ PYTHONPATH=..:../../bumps:../../sasview/src ../../bumps/run.py \ multiscatfit.py --store=/tmp/t1 ) # Tie the model to the data M = Experiment(data=data, model=model) # Stack mulitple scattering on top of the existing resolution function. M.resolution = MultipleScattering(resolution=M.resolution, probability=0.) # SET THE FITTING PARAMETERS model.radius_polar.range(15, 3000) model.scale.range(0, 0.1) # Mulitple scattering probability parameter # HACK: the probability is stuffed in as an extra parameter to the experiment. probability = Parameter(name="probability", value=0.0) probability.range(0.0, 0.9) # The multiple scattering probability parameter is in the resolution function # instead of the scattering function, so access it through M.resolution M.scattering_probability.range(0.0, 0.9) M = Experiment(data=data, model=model, extra_pars={'probability': probability}) # Stack mulitple scattering on top of the existing resolution function. # Because resolution functions in sasview don't have fitting parameters, # we instead allow the multiple scattering calculator to take a function # instead of a probability.  This function returns the current value of # the parameter. ** THIS IS TEMPORARY ** when multiple scattering is # properly integrated into sasmodels and sasview, its fittable parameter # will be treated like the model parameters. M.resolution = MultipleScattering(resolution=M.resolution, probability=lambda: probability.value, ) M._kernel_inputs = M.resolution.q_calc # Let bumps know that we are fitting this experiment problem = FitProblem(M)
• ## sasmodels/bumps_model.py

 r49d1f8b8 # when bumps is not on the path. from bumps.names import Parameter # type: ignore from bumps.parameter import Reference # type: ignore except ImportError: pass def __init__(self, data, model, cutoff=1e-5, name=None, extra_pars=None): # type: (Data, Model, float) -> None # Allow resolution function to define fittable parameters.  We do this # by creating reference parameters within the resolution object rather # than modifying the object itself to use bumps parameters.  We need # to reset the parameters each time the object has changed.  These # additional parameters need to be returned from the fitting engine. # To make them available to the user, they are added as top-level # attributes to the experiment object.  The only change to the # resolution function is that it needs an optional 'fittable' attribute # which maps the internal name to the user visible name for the # for the parameter. self._resolution = None self._resolution_pars = {} # remember inputs so we can inspect from outside self.name = data.filename if name is None else name self._interpret_data(data, model.sasmodel) self._cache = {} # CRUFT: no longer need extra parameters # Multiple scattering probability is now retrieved directly from the # multiple scattering resolution function. self.extra_pars = extra_pars return len(self.Iq) @property def resolution(self): return self._resolution @resolution.setter def resolution(self, value): self._resolution = value # Remove old resolution fitting parameters from experiment for name in self._resolution_pars: delattr(self, name) # Create new resolution fitting parameters res_pars = getattr(self._resolution, 'fittable', {}) self._resolution_pars = { name: Reference(self._resolution, refname, name=name) for refname, name in res_pars.items() } # Add new resolution fitting parameters as experiment attributes for name, ref in self._resolution_pars.items(): setattr(self, name, ref) def parameters(self): # type: () -> Dict[str, Parameter] """ pars = self.model.parameters() if self.extra_pars: if self.extra_pars is not None: pars.update(self.extra_pars) pars.update(self._resolution_pars) return pars
• ## sasmodels/direct_model.py

 r7b9e4dd else: Iq, dIq = None, None #self._theory = np.zeros_like(q) q_vectors = [res.q_calc] elif self.data_type == 'Iqxy': #if not model.info.parameters.has_2d: res = resolution2d.Pinhole2D(data=data, index=index, nsigma=3.0, accuracy=accuracy) #self._theory = np.zeros_like(self.Iq) q_vectors = res.q_calc elif self.data_type == 'Iq': index = (data.x >= data.qmin) & (data.x <= data.qmax) else: res = resolution.Perfect1D(data.x[index]) #self._theory = np.zeros_like(self.Iq) q_vectors = [res.q_calc] elif self.data_type == 'Iq-oriented': index = (data.x >= data.qmin) & (data.x <= data.qmax) qx_width=data.dxw[index], qy_width=data.dxl[index]) q_vectors = res.q_calc else: raise ValueError("Unknown data type") # never gets here # Remember function inputs so we can delay loading the function and # so we can save/restore state self._kernel_inputs = q_vectors self._kernel = None self.Iq, self.dIq, self.index = Iq, dIq, index # type: (ParameterSet, float) -> np.ndarray if self._kernel is None: self._kernel = self._model.make_kernel(self._kernel_inputs) # TODO: change interfaces so that resolution returns kernel inputs # Maybe have resolution always return a tuple, or maybe have # make_kernel accept either an ndarray or a pair of ndarrays. kernel_inputs = self.resolution.q_calc if isinstance(kernel_inputs, np.ndarray): kernel_inputs = (kernel_inputs,) self._kernel = self._model.make_kernel(kernel_inputs) # Need to pull background out of resolution for multiple scattering
• ## sasmodels/multiscat.py

 rb3703f5 *probability* is related to the expected number of scattering events in the sample $\lambda$ as $p = 1 = e^{-\lambda}$.  As a hack to allow probability to be a fitted parameter, the "value" can be a function that takes no parameters and returns the current value of the probability.  *coverage* determines how many scattering steps to consider.  The default is 0.99, which sets $n$ such that $1 \ldots n$ covers 99% of the Poisson probability mass function. events in the sample $\lambda$ as $p = 1 - e^{-\lambda}$. *coverage* determines how many scattering steps to consider.  The default is 0.99, which sets $n$ such that $1 \ldots n$ covers 99% of the Poisson probability mass function. *is2d* is True then 2D scattering is used, otherwise it accepts self.qmin = qmin self.nq = nq self.probability = probability self.probability = 0. if probability is None else probability self.coverage = coverage self.is2d = is2d self.Iqxy = None # type: np.ndarray # Label probability as a fittable parameter, and give its external name # Note that the external name must be a valid python identifier, since # is will be set as an experiment attribute. self.fittable = {'probability': 'scattering_probability'} def apply(self, theory): if self.is2d: Iq_calc = Iq_calc.reshape(self.nq, self.nq) # CRUFT: don't need probability as a function anymore probability = self.probability() if callable(self.probability) else self.probability coverage = self.coverage
Note: See TracChangeset for help on using the changeset viewer.