Changes in sasmodels/bumps_model.py [ea75043:04dc697] in sasmodels
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/bumps_model.py
rea75043 r04dc697 11 11 12 12 """ 13 14 import warnings 15 16 import numpy as np 13 from __future__ import print_function 14 15 __all__ = [ "Model", "Experiment" ] 16 17 import numpy as np # type: ignore 17 18 18 19 from .data import plot_theory 19 20 from .direct_model import DataMixin 20 21 21 __all__ = [ 22 "Model", "Experiment", 23 ] 24 25 # CRUFT: old style bumps wrapper which doesn't separate data and model 26 # pylint: disable=invalid-name 27 def BumpsModel(data, model, cutoff=1e-5, **kw): 28 r""" 29 Bind a model to data, along with a polydispersity cutoff. 30 31 *data* is a :class:`data.Data1D`, :class:`data.Data2D` or 32 :class:`data.Sesans` object. Use :func:`data.empty_data1D` or 33 :func:`data.empty_data2D` to define $q, \Delta q$ calculation 34 points for displaying the SANS curve when there is no measured data. 35 36 *model* is a runnable module as returned from :func:`core.load_model`. 37 38 *cutoff* is the polydispersity weight cutoff. 39 40 Any additional *key=value* pairs are model dependent parameters. 41 42 Returns an :class:`Experiment` object. 43 44 Note that the usual Bumps semantics is not fully supported, since 45 assigning *M.name = parameter* on the returned experiment object 46 does not set that parameter in the model. Range setting will still 47 work as expected though. 48 49 .. deprecated:: 0.1 50 Use :class:`Experiment` instead. 51 """ 52 warnings.warn("Use of BumpsModel is deprecated. Use bumps_model.Experiment instead.") 53 54 # Create the model and experiment 55 model = Model(model, **kw) 56 experiment = Experiment(data=data, model=model, cutoff=cutoff) 57 58 # Copy the model parameters up to the experiment object. 59 for k, v in model.parameters().items(): 60 setattr(experiment, k, v) 61 return experiment 22 try: 23 from typing import Dict, Union, Tuple, Any 24 from .data import Data1D, Data2D 25 from .kernel import KernelModel 26 from .modelinfo import ModelInfo 27 Data = Union[Data1D, Data2D] 28 except ImportError: 29 pass 30 31 try: 32 # Optional import. This allows the doc builder and nosetests to run even 33 # when bumps is not on the path. 34 from bumps.names import Parameter # type: ignore 35 except ImportError: 36 pass 62 37 63 38 64 39 def create_parameters(model_info, **kwargs): 40 # type: (ModelInfo, **Union[float, str, Parameter]) -> Tuple[Dict[str, Parameter], Dict[str, str]] 65 41 """ 66 42 Generate Bumps parameters from the model info. … … 71 47 Any additional *key=value* pairs are initial values for the parameters 72 48 to the models. Uninitialized parameters will use the model default 73 value. 49 value. The value can be a float, a bumps parameter, or in the case 50 of the distribution type parameter, a string. 74 51 75 52 Returns a dictionary of *{name: Parameter}* containing the bumps … … 77 54 *{name: str}* containing the polydispersity distribution types. 78 55 """ 79 # lazy import; this allows the doc builder and nosetests to run even 80 # when bumps is not on the path. 81 from bumps.names import Parameter 82 83 pars = {} 84 for p in model_info['parameters']: 56 pars = {} # type: Dict[str, Parameter] 57 pd_types = {} # type: Dict[str, str] 58 for p in model_info.parameters.call_parameters: 85 59 value = kwargs.pop(p.name, p.default) 86 60 pars[p.name] = Parameter.default(value, name=p.name, limits=p.limits) 87 for name in model_info['partype']['pd-2d']: 88 for xpart, xdefault, xlimits in [ 89 ('_pd', 0., pars[name].limits), 90 ('_pd_n', 35., (0, 1000)), 91 ('_pd_nsigma', 3., (0, 10)), 92 ]: 93 xname = name + xpart 94 xvalue = kwargs.pop(xname, xdefault) 95 pars[xname] = Parameter.default(xvalue, name=xname, limits=xlimits) 96 97 pd_types = {} 98 for name in model_info['partype']['pd-2d']: 99 xname = name + '_pd_type' 100 xvalue = kwargs.pop(xname, 'gaussian') 101 pd_types[xname] = xvalue 61 if p.polydisperse: 62 for part, default, limits in [ 63 ('_pd', 0., pars[p.name].limits), 64 ('_pd_n', 35., (0, 1000)), 65 ('_pd_nsigma', 3., (0, 10)), 66 ]: 67 name = p.name + part 68 value = kwargs.pop(name, default) 69 pars[name] = Parameter.default(value, name=name, limits=limits) 70 name = p.name + '_pd_type' 71 pd_types[name] = str(kwargs.pop(name, 'gaussian')) 102 72 103 73 if kwargs: # args not corresponding to parameters … … 118 88 """ 119 89 def __init__(self, model, **kwargs): 120 self._sasmodel = model 90 # type: (KernelModel, **Dict[str, Union[float, Parameter]]) -> None 91 self.sasmodel = model 121 92 pars, pd_types = create_parameters(model.info, **kwargs) 122 93 for k, v in pars.items(): … … 128 99 129 100 def parameters(self): 101 # type: () -> Dict[str, Parameter] 130 102 """ 131 103 Return a dictionary of parameters objects for the parameters, … … 135 107 136 108 def state(self): 109 # type: () -> Dict[str, Union[Parameter, str]] 137 110 """ 138 111 Return a dictionary of current values for all the parameters, … … 159 132 The resulting model can be used directly in a Bumps FitProblem call. 160 133 """ 134 _cache = None # type: Dict[str, np.ndarray] 161 135 def __init__(self, data, model, cutoff=1e-5): 162 136 # type: (Data, Model, float) -> None 163 137 # remember inputs so we can inspect from outside 164 138 self.model = model 165 139 self.cutoff = cutoff 166 self._interpret_data(data, model. _sasmodel)167 self. update()140 self._interpret_data(data, model.sasmodel) 141 self._cache = {} 168 142 169 143 def update(self): 144 # type: () -> None 170 145 """ 171 146 Call when model parameters have changed and theory needs to be 172 147 recalculated. 173 148 """ 174 self._cache = {}149 self._cache.clear() 175 150 176 151 def numpoints(self): 152 # type: () -> float 177 153 """ 178 154 Return the number of data points … … 181 157 182 158 def parameters(self): 159 # type: () -> Dict[str, Parameter] 183 160 """ 184 161 Return a dictionary of parameters … … 187 164 188 165 def theory(self): 166 # type: () -> np.ndarray 189 167 """ 190 168 Return the theory corresponding to the model parameters. … … 199 177 200 178 def residuals(self): 179 # type: () -> np.ndarray 201 180 """ 202 181 Return theory minus data normalized by uncertainty. … … 206 185 207 186 def nllf(self): 187 # type: () -> float 208 188 """ 209 189 Return the negative log likelihood of seeing data given the model … … 213 193 delta = self.residuals() 214 194 #if np.any(np.isnan(R)): print("NaN in residuals") 215 return 0.5 * np.sum(delta **2)195 return 0.5 * np.sum(delta**2) 216 196 217 197 #def __call__(self): … … 219 199 220 200 def plot(self, view='log'): 201 # type: (str) -> None 221 202 """ 222 203 Plot the data and residuals. … … 226 207 227 208 def simulate_data(self, noise=None): 209 # type: (float) -> None 228 210 """ 229 211 Generate simulated data. … … 233 215 234 216 def save(self, basename): 217 # type: (str) -> None 235 218 """ 236 219 Save the model parameters and data into a file. … … 243 226 244 227 def __getstate__(self): 228 # type: () -> Dict[str, Any] 245 229 # Can't pickle gpu functions, so instead make them lazy 246 230 state = self.__dict__.copy() … … 249 233 250 234 def __setstate__(self, state): 235 # type: (Dict[str, Any]) -> None 251 236 # pylint: disable=attribute-defined-outside-init 252 237 self.__dict__ = state 238
Note: See TracChangeset
for help on using the changeset viewer.