Changeset 04dc697 in sasmodels for sasmodels/bumps_model.py
- Timestamp:
- Apr 13, 2016 9:39:09 AM (8 years ago)
- Branches:
- master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 60f03de
- Parents:
- a18c5b3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/bumps_model.py
r7ae2b7f r04dc697 11 11 12 12 """ 13 14 import warnings 13 from __future__ import print_function 14 15 __all__ = [ "Model", "Experiment" ] 15 16 16 17 import numpy as np # type: ignore … … 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 # type: ignore 82 83 pars = {} # floating point parameters 84 pd_types = {} # distribution names 56 pars = {} # type: Dict[str, Parameter] 57 pd_types = {} # type: Dict[str, str] 85 58 for p in model_info.parameters.call_parameters: 86 59 value = kwargs.pop(p.name, p.default) … … 96 69 pars[name] = Parameter.default(value, name=name, limits=limits) 97 70 name = p.name + '_pd_type' 98 pd_types[name] = kwargs.pop(name, 'gaussian')71 pd_types[name] = str(kwargs.pop(name, 'gaussian')) 99 72 100 73 if kwargs: # args not corresponding to parameters … … 115 88 """ 116 89 def __init__(self, model, **kwargs): 117 self._sasmodel = model 90 # type: (KernelModel, **Dict[str, Union[float, Parameter]]) -> None 91 self.sasmodel = model 118 92 pars, pd_types = create_parameters(model.info, **kwargs) 119 93 for k, v in pars.items(): … … 125 99 126 100 def parameters(self): 101 # type: () -> Dict[str, Parameter] 127 102 """ 128 103 Return a dictionary of parameters objects for the parameters, … … 132 107 133 108 def state(self): 109 # type: () -> Dict[str, Union[Parameter, str]] 134 110 """ 135 111 Return a dictionary of current values for all the parameters, … … 156 132 The resulting model can be used directly in a Bumps FitProblem call. 157 133 """ 134 _cache = None # type: Dict[str, np.ndarray] 158 135 def __init__(self, data, model, cutoff=1e-5): 159 136 # type: (Data, Model, float) -> None 160 137 # remember inputs so we can inspect from outside 161 138 self.model = model 162 139 self.cutoff = cutoff 163 self._interpret_data(data, model. _sasmodel)164 self. update()140 self._interpret_data(data, model.sasmodel) 141 self._cache = {} 165 142 166 143 def update(self): 144 # type: () -> None 167 145 """ 168 146 Call when model parameters have changed and theory needs to be 169 147 recalculated. 170 148 """ 171 self._cache = {}149 self._cache.clear() 172 150 173 151 def numpoints(self): 152 # type: () -> float 174 153 """ 175 154 Return the number of data points … … 178 157 179 158 def parameters(self): 159 # type: () -> Dict[str, Parameter] 180 160 """ 181 161 Return a dictionary of parameters … … 184 164 185 165 def theory(self): 166 # type: () -> np.ndarray 186 167 """ 187 168 Return the theory corresponding to the model parameters. … … 196 177 197 178 def residuals(self): 179 # type: () -> np.ndarray 198 180 """ 199 181 Return theory minus data normalized by uncertainty. … … 203 185 204 186 def nllf(self): 187 # type: () -> float 205 188 """ 206 189 Return the negative log likelihood of seeing data given the model … … 210 193 delta = self.residuals() 211 194 #if np.any(np.isnan(R)): print("NaN in residuals") 212 return 0.5 * np.sum(delta **2)195 return 0.5 * np.sum(delta**2) 213 196 214 197 #def __call__(self): … … 216 199 217 200 def plot(self, view='log'): 201 # type: (str) -> None 218 202 """ 219 203 Plot the data and residuals. … … 223 207 224 208 def simulate_data(self, noise=None): 209 # type: (float) -> None 225 210 """ 226 211 Generate simulated data. … … 230 215 231 216 def save(self, basename): 217 # type: (str) -> None 232 218 """ 233 219 Save the model parameters and data into a file. … … 240 226 241 227 def __getstate__(self): 228 # type: () -> Dict[str, Any] 242 229 # Can't pickle gpu functions, so instead make them lazy 243 230 state = self.__dict__.copy() … … 246 233 247 234 def __setstate__(self, state): 235 # type: (Dict[str, Any]) -> None 248 236 # pylint: disable=attribute-defined-outside-init 249 237 self.__dict__ = state 238
Note: See TracChangeset
for help on using the changeset viewer.