Changes in / [8803a38:899e050] in sasmodels
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
example/multiscatfit.py
r2c4a190 r49d1f8b8 15 15 16 16 # Show the model without fitting 17 PYTHONPATH=..:../ ../bumps:../../sasview/src python multiscatfit.py17 PYTHONPATH=..:../explore:../../bumps:../../sasview/src python multiscatfit.py 18 18 19 19 # Run the fit 20 PYTHONPATH=..:../ ../bumps:../../sasview/src ../../bumps/run.py \20 PYTHONPATH=..:../explore:../../bumps:../../sasview/src ../../bumps/run.py \ 21 21 multiscatfit.py --store=/tmp/t1 22 22 … … 55 55 ) 56 56 57 # Tie the model to the data58 M = Experiment(data=data, model=model)59 60 # Stack mulitple scattering on top of the existing resolution function.61 M.resolution = MultipleScattering(resolution=M.resolution, probability=0.)62 63 57 # SET THE FITTING PARAMETERS 64 58 model.radius_polar.range(15, 3000) … … 71 65 model.scale.range(0, 0.1) 72 66 73 # The multiple scattering probability parameter is in the resolution function 74 # instead of the scattering function, so access it through M.resolution 75 M.scattering_probability.range(0.0, 0.9) 67 # Mulitple scattering probability parameter 68 # HACK: the probability is stuffed in as an extra parameter to the experiment. 69 probability = Parameter(name="probability", value=0.0) 70 probability.range(0.0, 0.9) 76 71 77 # Let bumps know that we are fitting this experiment 72 M = Experiment(data=data, model=model, extra_pars={'probability': probability}) 73 74 # Stack mulitple scattering on top of the existing resolution function. 75 # Because resolution functions in sasview don't have fitting parameters, 76 # we instead allow the multiple scattering calculator to take a function 77 # instead of a probability. This function returns the current value of 78 # the parameter. ** THIS IS TEMPORARY ** when multiple scattering is 79 # properly integrated into sasmodels and sasview, its fittable parameter 80 # will be treated like the model parameters. 81 M.resolution = MultipleScattering(resolution=M.resolution, 82 probability=lambda: probability.value, 83 ) 84 M._kernel_inputs = M.resolution.q_calc 78 85 problem = FitProblem(M) 79 86 -
sasmodels/bumps_model.py
r2c4a190 r49d1f8b8 35 35 # when bumps is not on the path. 36 36 from bumps.names import Parameter # type: ignore 37 from bumps.parameter import Reference # type: ignore38 37 except ImportError: 39 38 pass … … 140 139 def __init__(self, data, model, cutoff=1e-5, name=None, extra_pars=None): 141 140 # type: (Data, Model, float) -> None 142 # Allow resolution function to define fittable parameters. We do this143 # by creating reference parameters within the resolution object rather144 # than modifying the object itself to use bumps parameters. We need145 # to reset the parameters each time the object has changed. These146 # additional parameters need to be returned from the fitting engine.147 # To make them available to the user, they are added as top-level148 # attributes to the experiment object. The only change to the149 # resolution function is that it needs an optional 'fittable' attribute150 # which maps the internal name to the user visible name for the151 # for the parameter.152 self._resolution = None153 self._resolution_pars = {}154 141 # remember inputs so we can inspect from outside 155 142 self.name = data.filename if name is None else name … … 158 145 self._interpret_data(data, model.sasmodel) 159 146 self._cache = {} 160 # CRUFT: no longer need extra parameters161 # Multiple scattering probability is now retrieved directly from the162 # multiple scattering resolution function.163 147 self.extra_pars = extra_pars 164 148 … … 178 162 return len(self.Iq) 179 163 180 @property181 def resolution(self):182 return self._resolution183 184 @resolution.setter185 def resolution(self, value):186 self._resolution = value187 188 # Remove old resolution fitting parameters from experiment189 for name in self._resolution_pars:190 delattr(self, name)191 192 # Create new resolution fitting parameters193 res_pars = getattr(self._resolution, 'fittable', {})194 self._resolution_pars = {195 name: Reference(self._resolution, refname, name=name)196 for refname, name in res_pars.items()197 }198 199 # Add new resolution fitting parameters as experiment attributes200 for name, ref in self._resolution_pars.items():201 setattr(self, name, ref)202 203 164 def parameters(self): 204 165 # type: () -> Dict[str, Parameter] … … 207 168 """ 208 169 pars = self.model.parameters() 209 if self.extra_pars is not None:170 if self.extra_pars: 210 171 pars.update(self.extra_pars) 211 pars.update(self._resolution_pars)212 172 return pars 213 173 -
sasmodels/direct_model.py
r2c4a190 r7b9e4dd 242 242 else: 243 243 Iq, dIq = None, None 244 #self._theory = np.zeros_like(q) 245 q_vectors = [res.q_calc] 244 246 elif self.data_type == 'Iqxy': 245 247 #if not model.info.parameters.has_2d: … … 258 260 res = resolution2d.Pinhole2D(data=data, index=index, 259 261 nsigma=3.0, accuracy=accuracy) 262 #self._theory = np.zeros_like(self.Iq) 263 q_vectors = res.q_calc 260 264 elif self.data_type == 'Iq': 261 265 index = (data.x >= data.qmin) & (data.x <= data.qmax) … … 282 286 else: 283 287 res = resolution.Perfect1D(data.x[index]) 288 289 #self._theory = np.zeros_like(self.Iq) 290 q_vectors = [res.q_calc] 284 291 elif self.data_type == 'Iq-oriented': 285 292 index = (data.x >= data.qmin) & (data.x <= data.qmax) … … 297 304 qx_width=data.dxw[index], 298 305 qy_width=data.dxl[index]) 306 q_vectors = res.q_calc 299 307 else: 300 308 raise ValueError("Unknown data type") # never gets here … … 302 310 # Remember function inputs so we can delay loading the function and 303 311 # so we can save/restore state 312 self._kernel_inputs = q_vectors 304 313 self._kernel = None 305 314 self.Iq, self.dIq, self.index = Iq, dIq, index … … 338 347 # type: (ParameterSet, float) -> np.ndarray 339 348 if self._kernel is None: 340 # TODO: change interfaces so that resolution returns kernel inputs 341 # Maybe have resolution always return a tuple, or maybe have 342 # make_kernel accept either an ndarray or a pair of ndarrays. 343 kernel_inputs = self.resolution.q_calc 344 if isinstance(kernel_inputs, np.ndarray): 345 kernel_inputs = (kernel_inputs,) 346 self._kernel = self._model.make_kernel(kernel_inputs) 349 self._kernel = self._model.make_kernel(self._kernel_inputs) 347 350 348 351 # Need to pull background out of resolution for multiple scattering -
sasmodels/multiscat.py
r2c4a190 rb3703f5 342 342 343 343 *probability* is related to the expected number of scattering 344 events in the sample $\lambda$ as $p = 1 - e^{-\lambda}$. 345 *coverage* determines how many scattering steps to consider. The 346 default is 0.99, which sets $n$ such that $1 \ldots n$ covers 99% 347 of the Poisson probability mass function. 344 events in the sample $\lambda$ as $p = 1 = e^{-\lambda}$. As a 345 hack to allow probability to be a fitted parameter, the "value" 346 can be a function that takes no parameters and returns the current 347 value of the probability. *coverage* determines how many scattering 348 steps to consider. The default is 0.99, which sets $n$ such that 349 $1 \ldots n$ covers 99% of the Poisson probability mass function. 348 350 349 351 *is2d* is True then 2D scattering is used, otherwise it accepts … … 397 399 self.qmin = qmin 398 400 self.nq = nq 399 self.probability = 0. if probability is None elseprobability401 self.probability = probability 400 402 self.coverage = coverage 401 403 self.is2d = is2d … … 454 456 self.Iqxy = None # type: np.ndarray 455 457 456 # Label probability as a fittable parameter, and give its external name457 # Note that the external name must be a valid python identifier, since458 # is will be set as an experiment attribute.459 self.fittable = {'probability': 'scattering_probability'}460 461 458 def apply(self, theory): 462 459 if self.is2d: … … 466 463 Iq_calc = Iq_calc.reshape(self.nq, self.nq) 467 464 468 # CRUFT: don't need probability as a function anymore469 465 probability = self.probability() if callable(self.probability) else self.probability 470 466 coverage = self.coverage
Note: See TracChangeset
for help on using the changeset viewer.