Changeset 4d76711 in sasmodels
- Timestamp:
- Apr 5, 2016 10:33:44 AM (9 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:
- 3a45c2c, c4e7a5f
- Parents:
- cd0a808
- Location:
- sasmodels
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/core.py
rb7172bb r4d76711 7 7 ] 8 8 9 10 9 from os.path import basename, dirname, join as joinpath, splitext 11 10 from glob import glob 12 import imp13 11 14 12 import numpy as np … … 40 38 return [np.asarray(v) for v in args] 41 39 40 # TODO: refactor composite model support 41 # The current load_model_info/build_model does not reuse existing model 42 # definitions when loading a composite model, instead reloading and 43 # rebuilding the kernel for each component model in the expression. This 44 # is fine in a scripting environment where the model is built when the script 45 # starts and is thrown away when the script ends, but may not be the best 46 # solution in a long-lived application. This affects the following functions: 47 # 48 # load_model 49 # load_model_info 50 # build_model 42 51 43 52 def list_models(): … … 64 73 return build_model(load_model_info(model_name), **kw) 65 74 66 def load_model_info_from_path(path):67 # Pull off the last .ext if it exists; there may be others68 name = basename(splitext(path)[0])69 70 # Not cleaning name since don't need to be able to reload this71 # model later72 # Should probably turf the model from sys.modules after we are done...73 74 # Placing the model in the 'sasmodels.custom' name space, even75 # though it doesn't actually exist. imp.load_source doesn't seem76 # to care.77 kernel_module = imp.load_source('sasmodels.custom.'+name, path)78 79 # Now that we have the module, we can load it as usual80 model_info = generate.make_model_info(kernel_module)81 return model_info82 75 83 76 def load_model_info(model_name): … … 102 95 return product.make_product_info(P_info, Q_info) 103 96 104 #import sys; print "\n".join(sys.path) 105 __import__('sasmodels.models.'+model_name) 106 kernel_module = getattr(models, model_name, None) 97 kernel_module = generate.load_kernel_module(model_name) 107 98 return generate.make_model_info(kernel_module) 108 99 … … 179 170 180 171 181 def make_kernel(model, q_vectors):182 """183 Return a computation kernel from the model definition and the q input.184 """185 return model(q_vectors)186 187 172 def get_weights(model_info, pars, name): 188 173 """ … … 220 205 def call_kernel(kernel, pars, cutoff=0, mono=False): 221 206 """ 222 Call *kernel* returned from :func:`make_kernel`with parameters *pars*.207 Call *kernel* returned from *model.make_kernel* with parameters *pars*. 223 208 224 209 *cutoff* is the limiting value for the product of dispersion weights used … … 228 213 with an error of about 1%, which is usually less than the measurement 229 214 uncertainty. 215 216 *mono* is True if polydispersity should be set to none on all parameters. 230 217 """ 231 218 fixed_pars = [pars.get(name, kernel.info['defaults'][name]) … … 259 246 260 247 261 def call_ER( info, pars):262 """ 263 Call the model ER function using * pars*.264 * info* is either *model.info* if you have a loaded model, or *kernel.info*265 if youhave a model kernel prepared for evaluation.266 """ 267 ER = info.get('ER', None)248 def call_ER(model_info, values): 249 """ 250 Call the model ER function using *values*. *model_info* is either 251 *model.info* if you have a loaded model, or *kernel.info* if you 252 have a model kernel prepared for evaluation. 253 """ 254 ER = model_info.get('ER', None) 268 255 if ER is None: 269 256 return 1.0 270 257 else: 271 vol_pars = [get_weights( info, pars, name)272 for name in info['partype']['volume']]258 vol_pars = [get_weights(model_info, values, name) 259 for name in model_info['partype']['volume']] 273 260 value, weight = dispersion_mesh(vol_pars) 274 261 individual_radii = ER(*value) … … 276 263 return np.sum(weight*individual_radii) / np.sum(weight) 277 264 278 def call_VR( info, pars):265 def call_VR(model_info, values): 279 266 """ 280 267 Call the model VR function using *pars*. … … 282 269 if you have a model kernel prepared for evaluation. 283 270 """ 284 VR = info.get('VR', None)271 VR = model_info.get('VR', None) 285 272 if VR is None: 286 273 return 1.0 287 274 else: 288 vol_pars = [get_weights( info, pars, name)289 for name in info['partype']['volume']]275 vol_pars = [get_weights(model_info, values, name) 276 for name in model_info['partype']['volume']] 290 277 value, weight = dispersion_mesh(vol_pars) 291 278 whole, part = VR(*value) -
sasmodels/direct_model.py
rea75043 r4d76711 25 25 import numpy as np 26 26 27 from .core import make_kernel28 27 from .core import call_kernel, call_ER_VR 29 28 from . import sesans … … 173 172 def _calc_theory(self, pars, cutoff=0.0): 174 173 if self._kernel is None: 175 self._kernel = make_kernel(self._model,self._kernel_inputs) # pylint: disable=attribute-dedata_type176 self._kernel_mono = ( make_kernel(self._model,self._kernel_mono_inputs)174 self._kernel = self._model.make_kernel(self._kernel_inputs) # pylint: disable=attribute-dedata_type 175 self._kernel_mono = (self._model.make_kernel(self._kernel_mono_inputs) 177 176 if self._kernel_mono_inputs else None) 178 177 -
sasmodels/exception.py
r823e620 r4d76711 2 2 Utility to add annotations to python exceptions. 3 3 """ 4 import sys 4 5 5 6 # Platform cruft: WindowsError is only defined on Windows. … … 13 14 pass 14 15 15 def annotate_exception( exc, msg):16 def annotate_exception(msg, exc=None): 16 17 """ 17 18 Add an annotation to the current exception, which can then be forwarded 18 to the caller using a bare "raise" statement to reraise the annotated 19 exception. 19 to the caller using a bare "raise" statement to raise the annotated 20 exception. If the exception *exc* is provided, then that exception is the 21 one that is annotated, otherwise *sys.exc_info* is used. 20 22 21 23 Example:: … … 24 26 >>> try: 25 27 ... print(D['hello']) 26 ... except Exception as exc:27 ... annotate_exception( exc,"while accessing 'D'")28 ... except: 29 ... annotate_exception("while accessing 'D'") 28 30 ... raise 29 31 Traceback (most recent call last): … … 31 33 KeyError: "hello while accessing 'D'" 32 34 """ 35 if not exc: 36 exc = sys.exc_info()[1] 37 33 38 # Can't extend WindowsError exceptions; instead raise a new exception. 34 39 # TODO: try to incorporate current stack trace in the raised exception -
sasmodels/generate.py
rf247314 r4d76711 204 204 from __future__ import print_function 205 205 206 # TODO: identify model files which have changed since loading and reload them. 206 #TODO: identify model files which have changed since loading and reload them. 207 #TODO: determine which functions are useful outside of generate 208 #__all__ = ["model_info", "make_doc", "make_source", "convert_type"] 207 209 208 210 import sys … … 216 218 import numpy as np 217 219 220 from .custom import load_custom_kernel_module 221 218 222 PARAMETER_FIELDS = ['name', 'units', 'default', 'limits', 'type', 'description'] 219 223 Parameter = namedtuple('Parameter', PARAMETER_FIELDS) 220 221 #TODO: determine which functions are useful outside of generate222 #__all__ = ["model_info", "make_doc", "make_source", "convert_type"]223 224 224 225 C_KERNEL_TEMPLATE_PATH = joinpath(dirname(__file__), 'kernel_template.c') … … 644 645 model_info['demo'] = model_info['defaults'] 645 646 model_info['has_2d'] = partype['orientation'] or partype['magnetic'] 647 648 649 def load_kernel_module(model_name): 650 if model_name.endswith('.py'): 651 kernel_module = load_custom_kernel_module(model_name) 652 else: 653 from sasmodels import models 654 __import__('sasmodels.models.'+model_name) 655 kernel_module = getattr(models, model_name, None) 656 return kernel_module 657 646 658 647 659 def make_model_info(kernel_module): … … 769 781 770 782 771 772 783 def demo_time(): 773 784 """ … … 789 800 else: 790 801 name = sys.argv[1] 791 import sasmodels.models 792 __import__('sasmodels.models.' + name) 793 model = getattr(sasmodels.models, name) 794 model_info = make_model_info(model) 802 kernel_module = load_kernel_module(name) 803 model_info = make_model_info(kernel_module) 795 804 source = make_source(model_info) 796 805 print(source) -
sasmodels/kernelcl.py
r8e0d974 r4d76711 314 314 self.program = None 315 315 316 def __call__(self, q_vectors):316 def make_kernel(self, q_vectors): 317 317 if self.program is None: 318 318 compiler = environment().compile_program -
sasmodels/kerneldll.py
r6ad0e87 r4d76711 205 205 try: 206 206 self.dll = ct.CDLL(self.dllpath) 207 except Exception as exc:208 annotate_exception( exc,"while loading "+self.dllpath)207 except: 208 annotate_exception("while loading "+self.dllpath) 209 209 raise 210 210 … … 229 229 self.dll = None 230 230 231 def __call__(self, q_vectors):231 def make_kernel(self, q_vectors): 232 232 q_input = PyInput(q_vectors, self.dtype) 233 233 if self.dll is None: self._load_dll() 234 234 kernel = self.Iqxy if q_input.is_2d else self.Iq 235 235 return DllKernel(kernel, self.info, q_input) 236 236 237 237 def release(self): 238 238 """ -
sasmodels/kernelpy.py
ra84a0ca r4d76711 19 19 self.info = model_info 20 20 21 def __call__(self, q_vectors):21 def make_kernel(self, q_vectors): 22 22 q_input = PyInput(q_vectors, dtype=F64) 23 23 kernel = self.info['Iqxy'] if q_input.is_2d else self.info['Iq'] -
sasmodels/model_test.py
ra84a0ca r4d76711 51 51 52 52 from .core import list_models, load_model_info, build_model, HAVE_OPENCL 53 from .core import make_kernel,call_kernel, call_ER, call_VR53 from .core import call_kernel, call_ER, call_VR 54 54 from .exception import annotate_exception 55 55 … … 166 166 pass 167 167 168 except Exception as exc:169 annotate_exception( exc,self.test_name)168 except: 169 annotate_exception(self.test_name) 170 170 raise 171 171 … … 187 187 Qx, Qy = zip(*x) 188 188 q_vectors = [np.array(Qx), np.array(Qy)] 189 kernel = m ake_kernel(model,q_vectors)189 kernel = model.make_kernel(q_vectors) 190 190 actual = call_kernel(kernel, pars) 191 191 else: 192 192 q_vectors = [np.array(x)] 193 kernel = m ake_kernel(model,q_vectors)193 kernel = model.make_kernel(q_vectors) 194 194 actual = call_kernel(kernel, pars) 195 195 -
sasmodels/resolution.py
r486fcf6 r4d76711 477 477 """ 478 478 from sasmodels import core 479 kernel = core.make_kernel(form,[q])479 kernel = form.make_kernel([q]) 480 480 theory = core.call_kernel(kernel, pars) 481 481 kernel.release() … … 693 693 def _eval_sphere(self, pars, resolution): 694 694 from sasmodels import core 695 kernel = core.make_kernel(self.model,[resolution.q_calc])695 kernel = self.model.make_kernel([resolution.q_calc]) 696 696 theory = core.call_kernel(kernel, pars) 697 697 result = resolution.apply(theory) … … 1062 1062 model = core.build_model(model_info) 1063 1063 1064 kernel = core.make_kernel(model,[resolution.q_calc])1064 kernel = model.make_kernel([resolution.q_calc]) 1065 1065 theory = core.call_kernel(kernel, pars) 1066 1066 Iq = resolution.apply(theory) -
sasmodels/sasview_model.py
rf247314 r4d76711 13 13 using :func:`sasmodels.convert.convert`. 14 14 """ 15 from __future__ import print_function 15 16 16 17 import math 17 18 from copy import deepcopy 18 19 import collections 20 import traceback 21 import logging 19 22 20 23 import numpy as np 21 24 22 25 from . import core 26 from . import custom 23 27 from . import generate 24 28 25 def standard_models(): 26 return [make_class(model_name) for model_name in core.list_models()] 27 28 # TODO: rename to make_class_from_name and update sasview 29 def make_class(model_name): 30 """ 31 Load the sasview model defined in *kernel_module*. 32 33 Returns a class that can be used directly as a sasview model.t 34 """ 35 model_info = core.load_model_info(model_name) 36 return make_class_from_info(model_info) 37 38 def make_class_from_file(path): 39 model_info = core.load_model_info_from_path(path) 40 return make_class_from_info(model_info) 41 42 def make_class_from_info(model_info): 29 def load_standard_models(): 30 """ 31 Load and return the list of predefined models. 32 33 If there is an error loading a model, then a traceback is logged and the 34 model is not returned. 35 """ 36 models = [] 37 for name in core.list_models(): 38 try: 39 models.append(_make_standard_model(name)) 40 except: 41 logging.error(traceback.format_exc()) 42 return models 43 44 45 def load_custom_model(path): 46 """ 47 Load a custom model given the model path. 48 """ 49 kernel_module = custom.load_custom_kernel_module(path) 50 model_info = generate.make_model_info(kernel_module) 51 return _make_model_from_info(model_info) 52 53 54 def _make_standard_model(name): 55 """ 56 Load the sasview model defined by *name*. 57 58 *name* can be a standard model name or a path to a custom model. 59 60 Returns a class that can be used directly as a sasview model. 61 """ 62 kernel_module = generate.load_kernel_module(name) 63 model_info = generate.make_model_info(kernel_module) 64 return _make_model_from_info(model_info) 65 66 67 def _make_model_from_info(model_info): 68 """ 69 Convert *model_info* into a SasView model wrapper. 70 """ 43 71 def __init__(self, multfactor=1): 44 72 SasviewModel.__init__(self) … … 47 75 return ConstructedModel 48 76 77 49 78 class SasviewModel(object): 50 79 """ 51 80 Sasview wrapper for opencl/ctypes model. 52 81 """ 82 _model_info = {} 53 83 def __init__(self): 54 self._ kernel = None84 self._model = None 55 85 model_info = self._model_info 56 86 … … 104 134 def __get_state__(self): 105 135 state = self.__dict__.copy() 106 model_id = self._model_info['id'] 107 state.pop('_kernel') 136 state.pop('_model') 108 137 # May need to reload model info on set state since it has pointers 109 138 # to python implementations of Iq, etc. … … 113 142 def __set_state__(self, state): 114 143 self.__dict__ = state 115 self._ kernel = None144 self._model = None 116 145 117 146 def __str__(self): … … 202 231 def getDispParamList(self): 203 232 """ 204 Return a list of all availableparameters for the model233 Return a list of polydispersity parameters for the model 205 234 """ 206 235 # TODO: fix test so that parameter order doesn't matter … … 303 332 to the card for each evaluation. 304 333 """ 305 if self._ kernel is None:306 self._ kernel = core.build_model(self._model_info)334 if self._model is None: 335 self._model = core.build_model(self._model_info) 307 336 q_vectors = [np.asarray(q) for q in args] 308 fn = self._ kernel(q_vectors)337 fn = self._model.make_kernel(q_vectors) 309 338 pars = [self.params[v] for v in fn.fixed_pars] 310 339 pd_pars = [self._get_weights(p) for p in fn.pd_pars] … … 384 413 def _get_weights(self, par): 385 414 """ 386 Return dispersion weights 387 :param par parameter name 415 Return dispersion weights for parameter 388 416 """ 389 417 from . import weights 390 391 418 relative = self._model_info['partype']['pd-rel'] 392 419 limits = self._model_info['limits'] … … 397 424 return value, weight / np.sum(weight) 398 425 426 427 def test_model(): 428 """ 429 Test that a sasview model (cylinder) can be run. 430 """ 431 Cylinder = _make_standard_model('cylinder') 432 cylinder = Cylinder() 433 return cylinder.evalDistribution([0.1,0.1]) 434 435 436 def test_model_list(): 437 """ 438 Make sure that all models build as sasview models. 439 """ 440 from .exception import annotate_exception 441 for name in core.list_models(): 442 try: 443 _make_standard_model(name) 444 except: 445 annotate_exception("when loading "+name) 446 raise 447 448 if __name__ == "__main__": 449 print("cylinder(0.1,0.1)=%g"%test_model())
Note: See TracChangeset
for help on using the changeset viewer.