Changes in / [38d2c97:cb97bff] in sasmodels
- Files:
-
- 37 added
- 27 deleted
- 44 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/genmodel.py
rd138d43 r91c5fdc 1 import sys 2 sys.path.insert(0,'..') 1 import sys, os 2 sys.path.insert(0, os.path.abspath('..')) 3 from sasmodels import generate, core 3 4 4 # Convert ../sasmodels/models/name.py to sasmodels.models.name 5 module_name = sys.argv[1][3:-3].replace('/','.').replace('\\','.') 6 #print module_name 7 module = __import__(module_name) 8 for part in module_name.split('.')[1:]: 9 module = getattr(module, part) 10 #print module 5 # Convert ../sasmodels/models/name.py to name 6 model_name = os.path.basename(sys.argv[1])[:-3] 11 7 12 8 # Load the doc string from the module definition file and store it in rst 13 from sasmodels import generate 14 docstr = generate.doc(module) 9 docstr = generate.make_doc(core.load_model_info(model_name)) 15 10 open(sys.argv[2],'w').write(docstr) -
doc/gentoc.py
r9404dd3 r5041682 7 7 from os import mkdir 8 8 from os.path import basename, exists, join as joinpath 9 from sasmodels.core import load_model_ definition9 from sasmodels.core import load_model_info 10 10 11 11 … … 55 55 model_name = basename(item)[:-3] 56 56 if model_name.startswith('_'): continue 57 model_ definition = load_model_definition(model_name)58 if not hasattr(model_definition, 'category'):57 model_info = load_model_info(model_name) 58 if model_info['category'] is None: 59 59 print("Missing category for", item, file=sys.stderr) 60 60 else: 61 category.setdefault(model_ definition.category,[]).append(model_name)61 category.setdefault(model_info['category'],[]).append(model_name) 62 62 63 63 # Check category names -
example/sesansfit.py
r346bc88 ra98958b 1 #TODO: Convert units properly (nm -> A) 2 #TODO: Implement constraints 3 1 4 from bumps.names import * 2 3 5 from sasmodels import core, bumps_model 4 6 5 if True: # fix when data loader exists 6 # from sas.dataloader.readers\ 7 from sas.dataloader.loader import Loader 8 loader = Loader() 9 filename = 'testsasview1.ses' 10 data = loader.load(filename) 11 if data is None: raise IOError("Could not load file %r"%(filename,)) 12 data.x /= 10 13 # print data 14 # data = load_sesans('mydatfile.pz') 15 # sans_data = load_sans('mysansfile.xml') 7 HAS_CONVERTER = True 8 try: 9 from sas.sascalc.data_util.nxsunit import Converter 10 except ImportError: 11 HAS_CONVERTER = False 16 12 17 else: 18 SElength = np.linspace(0, 2400, 61) # [A] 19 data = np.ones_like(SElength) 20 err_data = np.ones_like(SElength)*0.03 13 def sesans_fit(file, model_name, initial_vals={}, custom_params={}, param_range=[]): 14 """ 21 15 22 class Sample: 23 zacceptance = 0.1 # [A^-1] 24 thickness = 0.2 # [cm] 25 26 class SESANSData1D: 27 #q_zmax = 0.23 # [A^-1] 28 lam = 0.2 # [nm] 29 x = SElength 30 y = data 31 dy = err_data 32 sample = Sample() 33 data = SESANSData1D() 16 @param file: SESANS file location 17 @param model_name: model name string - can be model, model_1 * model_2, and/or model_1 + model_2 18 @param initial_vals: dictionary of {param_name : initial_value} 19 @param custom_params: dictionary of {custom_parameter_name : Parameter() object} 20 @param param_range: dictionary of {parameter_name : [minimum, maximum]} 21 @return: FitProblem for Bumps usage 22 """ 23 try: 24 from sas.sascalc.dataloader.loader import Loader 25 loader = Loader() 26 data = loader.load(file) 27 if data is None: raise IOError("Could not load file %r"%(file)) 28 if HAS_CONVERTER == True: 29 default_unit = "A" 30 data_conv_q = Converter(data._xunit) 31 data.x = data_conv_q(data.x, units=default_unit) 32 data._xunit = default_unit 34 33 35 radius = 1000 36 data.Rmax = 3*radius # [A] 34 except: 35 # If no loadable data file, generate random data 36 SElength = np.linspace(0, 2400, 61) # [A] 37 data = np.ones_like(SElength) 38 err_data = np.ones_like(SElength)*0.03 37 39 38 ## Sphere parameters 40 class Sample: 41 zacceptance = 0.1 # [A^-1] 42 thickness = 0.2 # [cm] 39 43 40 kernel = core.load_model("sphere", dtype='single') 41 phi = Parameter(0.1, name="phi") 42 model = bumps_model.Model(kernel, 43 scale=phi*(1-phi), sld=7.0, solvent_sld=1.0, radius=radius, 44 ) 45 phi.range(0.001,0.5) 46 #model.radius.pmp(40) 47 model.radius.range(1,10000) 48 #model.sld.pm(5) 49 #model.background 50 #model.radius_pd=0 51 #model.radius_pd_n=0 44 class SESANSData1D: 45 #q_zmax = 0.23 # [A^-1] 46 lam = 0.2 # [nm] 47 x = SElength 48 y = data 49 dy = err_data 50 sample = Sample() 51 data = SESANSData1D() 52 52 53 ### Tri-Axial Ellipsoid 54 # 55 #kernel = core.load_model("triaxial_ellipsoid", dtype='single') 56 #phi = Parameter(0.1, name='phi') 57 #model = bumps_model.Model(kernel, 58 # scale=phi*(1-phi), sld=7.0, solvent_sld=1.0, radius=radius, 59 # ) 60 #phi.range(0.001,0.90) 61 ##model.radius.pmp(40) 62 #model.radius.range(100,10000) 63 ##model.sld.pmp(5) 64 ##model.background 65 ##model.radius_pd = 0 66 ##model.radius_pd_n = 0 53 radius = 1000 54 data.Rmax = 3*radius # [A] 67 55 68 if False: # have sans data 69 M_sesans = bumps_model.Experiment(data=data, model=model) 70 M_sans = bumps_model.Experiment(data=sans_data, model=model) 71 problem = FitProblem([M_sesans, M_sans]) 72 else: 73 M_sesans = bumps_model.Experiment(data=data, model=model) 74 problem = FitProblem(M_sesans) 56 kernel = core.load_model(model_name) 57 model = bumps_model.Model(kernel) 75 58 59 # Load custom parameters, initial values and parameter constraints 60 for k, v in custom_params.items(): 61 setattr(model, k, v) 62 model._parameter_names.append(k) 63 for k, v in initial_vals.items(): 64 param = model.parameters().get(k) 65 setattr(param, "value", v) 66 for k, v in param_range.items(): 67 param = model.parameters().get(k) 68 if param is not None: 69 setattr(param.bounds, "limits", v) 70 71 if False: # have sans data 72 M_sesans = bumps_model.Experiment(data=data, model=model) 73 M_sans = bumps_model.Experiment(data=sans_data, model=model) 74 problem = FitProblem([M_sesans, M_sans]) 75 else: 76 M_sesans = bumps_model.Experiment(data=data, model=model) 77 problem = FitProblem(M_sesans) 78 return problem -
sasmodels/compare.py
r6869ceb r91c5fdc 38 38 from . import core 39 39 from . import kerneldll 40 from . import generate40 from . import product 41 41 from .data import plot_theory, empty_data1D, empty_data2D 42 42 from .direct_model import DirectModel 43 from .convert import revert_ model, constrain_new_to_old43 from .convert import revert_pars, constrain_new_to_old 44 44 45 45 USAGE = """ … … 264 264 return pars 265 265 266 def constrain_pars(model_ definition, pars):266 def constrain_pars(model_info, pars): 267 267 """ 268 268 Restrict parameters to valid values. … … 272 272 cylinder radius in this case). 273 273 """ 274 name = model_definition.name 274 name = model_info['id'] 275 # if it is a product model, then just look at the form factor since 276 # none of the structure factors need any constraints. 277 if '*' in name: 278 name = name.split('*')[0] 279 275 280 if name == 'capped_cylinder' and pars['cap_radius'] < pars['radius']: 276 281 pars['radius'], pars['cap_radius'] = pars['cap_radius'], pars['radius'] … … 340 345 return pars 341 346 342 def eval_sasview(model_ definition, data):347 def eval_sasview(model_info, data): 343 348 """ 344 349 Return a model calculator using the SasView fitting engine. … … 349 354 from sas.models.qsmearing import smear_selection 350 355 351 # convert model parameters from sasmodel form to sasview form 352 #print("old",sorted(pars.items())) 353 modelname, _ = revert_model(model_definition, {}) 354 #print("new",sorted(_pars.items())) 355 sas = __import__('sas.models.'+modelname) 356 ModelClass = getattr(getattr(sas.models, modelname, None), modelname, None) 357 if ModelClass is None: 358 raise ValueError("could not find model %r in sas.models"%modelname) 359 model = ModelClass() 356 def get_model(name): 357 #print("new",sorted(_pars.items())) 358 sas = __import__('sas.models.' + name) 359 ModelClass = getattr(getattr(sas.models, name, None), name, None) 360 if ModelClass is None: 361 raise ValueError("could not find model %r in sas.models"%name) 362 return ModelClass() 363 364 # grab the sasview model, or create it if it is a product model 365 if model_info['composition']: 366 composition_type, parts = model_info['composition'] 367 if composition_type == 'product': 368 from sas.models.MultiplicationModel import MultiplicationModel 369 P, S = [get_model(p) for p in model_info['oldname']] 370 model = MultiplicationModel(P, S) 371 else: 372 raise ValueError("mixture models not handled yet") 373 else: 374 model = get_model(model_info['oldname']) 375 376 # build a smearer with which to call the model, if necessary 360 377 smearer = smear_selection(data, model=model) 361 362 378 if hasattr(data, 'qx_data'): 363 379 q = np.sqrt(data.qx_data**2 + data.qy_data**2) … … 382 398 """ 383 399 # paying for parameter conversion each time to keep life simple, if not fast 384 _, pars = revert_model(model_definition, pars)400 pars = revert_pars(model_info, pars) 385 401 for k, v in pars.items(): 386 402 parts = k.split('.') # polydispersity components … … 405 421 'longdouble': '128', 406 422 } 407 def eval_opencl(model_ definition, data, dtype='single', cutoff=0.):423 def eval_opencl(model_info, data, dtype='single', cutoff=0.): 408 424 """ 409 425 Return a model calculator using the OpenCL calculation engine. 410 426 """ 411 try: 412 model = core.load_model(model_definition, dtype=dtype, platform="ocl") 413 except Exception as exc: 414 print(exc) 415 print("... trying again with single precision") 416 dtype = 'single' 417 model = core.load_model(model_definition, dtype=dtype, platform="ocl") 427 def builder(model_info): 428 try: 429 return core.build_model(model_info, dtype=dtype, platform="ocl") 430 except Exception as exc: 431 print(exc) 432 print("... trying again with single precision") 433 return core.build_model(model_info, dtype='single', platform="ocl") 434 if model_info['composition']: 435 composition_type, parts = model_info['composition'] 436 if composition_type == 'product': 437 P, S = [builder(p) for p in parts] 438 model = product.ProductModel(P, S) 439 else: 440 raise ValueError("mixture models not handled yet") 441 else: 442 model = builder(model_info) 418 443 calculator = DirectModel(data, model, cutoff=cutoff) 419 444 calculator.engine = "OCL%s"%DTYPE_MAP[dtype] 420 445 return calculator 421 446 422 def eval_ctypes(model_ definition, data, dtype='double', cutoff=0.):447 def eval_ctypes(model_info, data, dtype='double', cutoff=0.): 423 448 """ 424 449 Return a model calculator using the DLL calculation engine. … … 426 451 if dtype == 'quad': 427 452 dtype = 'longdouble' 428 model = core.load_model(model_definition, dtype=dtype, platform="dll") 453 def builder(model_info): 454 return core.build_model(model_info, dtype=dtype, platform="dll") 455 456 if model_info['composition']: 457 composition_type, parts = model_info['composition'] 458 if composition_type == 'product': 459 P, S = [builder(p) for p in parts] 460 model = product.ProductModel(P, S) 461 else: 462 raise ValueError("mixture models not handled yet") 463 else: 464 model = builder(model_info) 429 465 calculator = DirectModel(data, model, cutoff=cutoff) 430 466 calculator.engine = "OMP%s"%DTYPE_MAP[dtype] … … 470 506 return data, index 471 507 472 def make_engine(model_ definition, data, dtype, cutoff):508 def make_engine(model_info, data, dtype, cutoff): 473 509 """ 474 510 Generate the appropriate calculation engine for the given datatype. … … 478 514 """ 479 515 if dtype == 'sasview': 480 return eval_sasview(model_ definition, data)516 return eval_sasview(model_info, data) 481 517 elif dtype.endswith('!'): 482 return eval_ctypes(model_definition, data, dtype=dtype[:-1], 483 cutoff=cutoff) 484 else: 485 return eval_opencl(model_definition, data, dtype=dtype, 486 cutoff=cutoff) 518 return eval_ctypes(model_info, data, dtype=dtype[:-1], cutoff=cutoff) 519 else: 520 return eval_opencl(model_info, data, dtype=dtype, cutoff=cutoff) 487 521 488 522 def compare(opts, limits=None): … … 642 676 643 677 644 def get_demo_pars(model_ definition):678 def get_demo_pars(model_info): 645 679 """ 646 680 Extract demo parameters from the model definition. 647 681 """ 648 info = generate.make_info(model_definition)649 682 # Get the default values for the parameters 650 pars = dict((p[0], p[2]) for p in info['parameters'])683 pars = dict((p[0], p[2]) for p in model_info['parameters']) 651 684 652 685 # Fill in default values for the polydispersity parameters 653 for p in info['parameters']:686 for p in model_info['parameters']: 654 687 if p[4] in ('volume', 'orientation'): 655 688 pars[p[0]+'_pd'] = 0.0 … … 659 692 660 693 # Plug in values given in demo 661 pars.update( info['demo'])694 pars.update(model_info['demo']) 662 695 return pars 696 663 697 664 698 def parse_opts(): … … 679 713 print(columnize(MODELS, indent=" ")) 680 714 sys.exit(1) 681 682 name = args[0]683 try:684 model_definition = core.load_model_definition(name)685 except ImportError, exc:686 print(str(exc))687 print("Use one of:\n " + models)688 sys.exit(1)689 715 if len(args) > 3: 690 716 print("expected parameters: model N1 N2") 717 718 def _get_info(name): 719 try: 720 model_info = core.load_model_info(name) 721 except ImportError, exc: 722 print(str(exc)) 723 print("Use one of:\n " + models) 724 sys.exit(1) 725 return model_info 726 727 name = args[0] 728 if '*' in name: 729 parts = [_get_info(k) for k in name.split('*')] 730 model_info = product.make_product_info(*parts) 731 else: 732 model_info = _get_info(name) 691 733 692 734 invalid = [o[1:] for o in flags … … 770 812 # Get demo parameters from model definition, or use default parameters 771 813 # if model does not define demo parameters 772 pars = get_demo_pars(model_ definition)814 pars = get_demo_pars(model_info) 773 815 774 816 # Fill in parameters given on the command line … … 791 833 pars = suppress_pd(pars) 792 834 pars.update(presets) # set value after random to control value 793 constrain_pars(model_ definition, pars)794 constrain_new_to_old(model_ definition, pars)835 constrain_pars(model_info, pars) 836 constrain_new_to_old(model_info, pars) 795 837 if opts['show_pars']: 796 838 print(str(parlist(pars))) … … 799 841 data, _ = make_data(opts) 800 842 if n1: 801 base = make_engine(model_ definition, data, engines[0], opts['cutoff'])843 base = make_engine(model_info, data, engines[0], opts['cutoff']) 802 844 else: 803 845 base = None 804 846 if n2: 805 comp = make_engine(model_ definition, data, engines[1], opts['cutoff'])847 comp = make_engine(model_info, data, engines[1], opts['cutoff']) 806 848 else: 807 849 comp = None … … 811 853 opts.update({ 812 854 'name' : name, 813 'def' : model_ definition,855 'def' : model_info, 814 856 'n1' : n1, 815 857 'n2' : n2, … … 854 896 config_matplotlib() 855 897 self.opts = opts 856 info = generate.make_info(opts['def'])857 pars, pd_types = bumps_model.create_parameters( info, **opts['pars'])898 model_info = opts['def'] 899 pars, pd_types = bumps_model.create_parameters(model_info, **opts['pars']) 858 900 if not opts['is2d']: 859 901 active = [base + ext 860 for base in info['partype']['pd-1d']902 for base in model_info['partype']['pd-1d'] 861 903 for ext in ['', '_pd', '_pd_n', '_pd_nsigma']] 862 active.extend( info['partype']['fixed-1d'])904 active.extend(model_info['partype']['fixed-1d']) 863 905 for k in active: 864 906 v = pars[k] -
sasmodels/compare_many.py
r4f2478e rb8e5e21 101 101 102 102 is_2d = hasattr(data, 'qx_data') 103 model_ definition = core.load_model_definition(name)104 pars = get_demo_pars(model_ definition)103 model_info = core.load_model_info(name) 104 pars = get_demo_pars(model_info) 105 105 header = ('\n"Model","%s","Count","%d","Dimension","%s"' 106 106 % (name, N, "2D" if is_2d else "1D")) … … 109 109 110 110 if is_2d: 111 info = generate.make_info(model_definition) 112 partype = info['partype'] 113 if not partype['orientation'] and not partype['magnetic']: 111 if not model_info['has_2d']: 114 112 print(',"1-D only"') 115 113 return … … 150 148 151 149 152 calc_base = make_engine(model_ definition, data, base, cutoff)153 calc_comp = make_engine(model_ definition, data, comp, cutoff)150 calc_base = make_engine(model_info, data, base, cutoff) 151 calc_comp = make_engine(model_info, data, comp, cutoff) 154 152 expected = max(PRECISION[base], PRECISION[comp]) 155 153 … … 161 159 seed = np.random.randint(1e6) 162 160 pars_i = randomize_pars(pars, seed) 163 constrain_pars(model_ definition, pars_i)164 constrain_new_to_old(model_ definition, pars_i)161 constrain_pars(model_info['id'], pars_i) 162 constrain_new_to_old(model_info['id'], pars_i) 165 163 if mono: 166 164 pars_i = suppress_pd(pars_i) -
sasmodels/convert.py
r0d0aee1 r667a6f2 4 4 import warnings 5 5 6 STRUCTURE_FACTORS = [ 7 'hardsphere', 8 'stickyhardsphere', 9 'squarewell', 10 'HayterMSAsq' 11 ] 6 12 # List of models which SasView versions don't contain the explicit 'scale' argument. 7 13 # When converting such a model, please update this list. 8 MODELS_WITHOUT_SCALE = [14 MODELS_WITHOUT_SCALE = STRUCTURE_FACTORS + [ 9 15 'teubner_strey', 10 16 'broad_peak', … … 15 21 'be_polyelectrolyte', 16 22 'correlation_length', 23 'fractal_core_shell' 17 24 'binary_hard_sphere', 18 'fractal_core_shell'19 25 ] 20 26 21 27 # List of models which SasView versions don't contain the explicit 'background' argument. 22 28 # When converting such a model, please update this list. 23 MODELS_WITHOUT_BACKGROUND = [29 MODELS_WITHOUT_BACKGROUND = STRUCTURE_FACTORS + [ 24 30 'guinier', 25 31 ] … … 52 58 new model definition end with sld. 53 59 """ 54 return dict((p, (v*1e6 if p.endswith('sld') else v*1e-15 if 'ndensity' in p else v)) 60 return dict((p, (v*1e6 if p.endswith('sld') 61 else v*1e-15 if 'ndensity' in p 62 else v)) 55 63 for p, v in pars.items()) 56 64 … … 70 78 new model definition end with sld. 71 79 """ 72 return dict((p, (v*1e-6 if p.endswith('sld') else v*1e15 if 'ndensity' in p else v)) 80 return dict((p, (v*1e-6 if p.endswith('sld') 81 else v*1e15 if 'ndensity' in p 82 else v)) 73 83 for p, v in pars.items()) 74 84 … … 109 119 return newpars 110 120 111 def revert_ model(model_definition, pars):121 def revert_pars(model_info, pars): 112 122 """ 113 123 Convert model from new style parameter names to old style. 114 124 """ 115 mapping = model_definition.oldpars 116 oldname = model_definition.oldname 125 mapping = model_info['oldpars'] 117 126 oldpars = _revert_pars(_unscale_sld(pars), mapping) 118 127 119 128 # Note: update compare.constrain_pars to match 120 name = model_ definition.name129 name = model_info['id'] 121 130 if name in MODELS_WITHOUT_SCALE: 122 131 if oldpars.pop('scale', 1.0) != 1.0: 123 132 warnings.warn("parameter scale not used in sasview %s"%name) 124 elif name in MODELS_WITHOUT_BACKGROUND:133 if name in MODELS_WITHOUT_BACKGROUND: 125 134 if oldpars.pop('background', 0.0) != 0.0: 126 135 warnings.warn("parameter background not used in sasview %s"%name) 127 elif getattr(model_definition, 'category', None) == 'structure-factor':128 if oldpars.pop('scale', 1.0) != 1.0:129 warnings.warn("parameter scale not used in sasview %s"%name)130 if oldpars.pop('background', 0.0) != 0.0:131 warnings.warn("parameter background not used in sasview %s"%name)132 elif name == 'pearl_necklace':133 _remove_pd(oldpars, 'num_pearls', name)134 _remove_pd(oldpars, 'thick_string', name)135 elif name == 'core_shell_parallelepiped':136 _remove_pd(oldpars, 'rimA', name)137 _remove_pd(oldpars, 'rimB', name)138 _remove_pd(oldpars, 'rimC', name)139 elif name == 'rpa':140 # convert scattering lengths from femtometers to centimeters141 for p in "La", "Lb", "Lc", "Ld":142 if p in oldpars: oldpars[p] *= 1e-13143 136 144 return oldname, oldpars 137 # If it is a product model P*S, then check the individual forms for special 138 # cases. Note: despite the structure factor alone not having scale or 139 # background, the product model does, so this is below the test for 140 # models without scale or background. 141 namelist = name.split('*') if '*' in name else [name] 142 for name in namelist: 143 if name == 'pearl_necklace': 144 _remove_pd(oldpars, 'num_pearls', name) 145 _remove_pd(oldpars, 'thick_string', name) 146 elif name == 'core_shell_parallelepiped': 147 _remove_pd(oldpars, 'rimA', name) 148 _remove_pd(oldpars, 'rimB', name) 149 _remove_pd(oldpars, 'rimC', name) 150 elif name == 'rpa': 151 # convert scattering lengths from femtometers to centimeters 152 for p in "La", "Lb", "Lc", "Ld": 153 if p in oldpars: oldpars[p] *= 1e-13 145 154 146 def constrain_new_to_old(model_definition, pars): 155 return oldpars 156 157 def constrain_new_to_old(model_info, pars): 147 158 """ 148 159 Restrict parameter values to those that will match sasview. 149 160 """ 161 name = model_info['id'] 150 162 # Note: update convert.revert_model to match 151 name = model_definition.name152 163 if name in MODELS_WITHOUT_SCALE: 153 164 pars['scale'] = 1 154 elif name in MODELS_WITHOUT_BACKGROUND:165 if name in MODELS_WITHOUT_BACKGROUND: 155 166 pars['background'] = 0 156 elif name == 'pearl_necklace': 157 pars['string_thickness_pd_n'] = 0 158 pars['number_of_pearls_pd_n'] = 0 159 elif name == 'line': 160 pars['scale'] = 1 167 # sasview multiplies background by structure factor 168 if '*' in name: 161 169 pars['background'] = 0 162 elif name == 'rpa':163 pars['case_num'] = int(pars['case_num'])164 elif getattr(model_definition, 'category', None) == 'structure-factor':165 pars['scale'], pars['background'] = 1, 0166 170 171 # If it is a product model P*S, then check the individual forms for special 172 # cases. Note: despite the structure factor alone not having scale or 173 # background, the product model does, so this is below the test for 174 # models without scale or background. 175 namelist = name.split('*') if '*' in name else [name] 176 for name in namelist: 177 if name == 'pearl_necklace': 178 pars['string_thickness_pd_n'] = 0 179 pars['number_of_pearls_pd_n'] = 0 180 elif name == 'line': 181 pars['scale'] = 1 182 pars['background'] = 0 183 elif name == 'rpa': 184 pars['case_num'] = int(pars['case_num']) -
sasmodels/core.py
rd18582e r7b3e62c 21 21 22 22 __all__ = [ 23 "list_models", "load_model_ definition", "precompile_dll",24 " load_model", "make_kernel", "call_kernel", "call_ER", "call_VR",23 "list_models", "load_model_info", "precompile_dll", 24 "build_model", "make_kernel", "call_kernel", "call_ER_VR", 25 25 ] 26 26 … … 34 34 return available_models 35 35 36 37 def load_model_definition(model_name):38 """39 Load a model definition given the model name.40 41 This returns a handle to the module defining the model. This can be42 used with functions in generate to build the docs or extract model info.43 """44 __import__('sasmodels.models.'+model_name)45 model_definition = getattr(models, model_name, None)46 return model_definition47 48 49 def precompile_dll(model_name, dtype="double"):50 """51 Precompile the dll for a model.52 53 Returns the path to the compiled model.54 55 This can be used when build the windows distribution of sasmodels56 (which may be missing the OpenCL driver and the dll compiler), or57 otherwise sharing models with windows users who do not have a compiler.58 59 See :func:`sasmodels.kerneldll.make_dll` for details on controlling the60 dll path and the allowed floating point precision.61 """62 model_definition = load_model_definition(model_name)63 source, info = generate.make(model_definition)64 return kerneldll.make_dll(source, info, dtype=dtype)65 66 67 36 def isstr(s): 68 37 """ … … 73 42 return True 74 43 75 def load_model(model_definition, dtype=None, platform="ocl"): 44 def load_model(model_name, **kw): 45 """ 46 Load model info and build model. 47 """ 48 parts = model_name.split('+') 49 if len(parts) > 1: 50 from .mixture import MixtureModel 51 models = [load_model(p, **kw) for p in parts] 52 return MixtureModel(models) 53 54 parts = model_name.split('*') 55 if len(parts) > 1: 56 # Note: currently have circular reference 57 from .product import ProductModel 58 if len(parts) > 2: 59 raise ValueError("use P*S to apply structure factor S to model P") 60 P, Q = [load_model(p, **kw) for p in parts] 61 return ProductModel(P, Q) 62 63 return build_model(load_model_info(model_name), **kw) 64 65 def load_model_info(model_name): 66 """ 67 Load a model definition given the model name. 68 69 This returns a handle to the module defining the model. This can be 70 used with functions in generate to build the docs or extract model info. 71 """ 72 #import sys; print "\n".join(sys.path) 73 __import__('sasmodels.models.'+model_name) 74 kernel_module = getattr(models, model_name, None) 75 return generate.make_model_info(kernel_module) 76 77 78 def build_model(model_info, dtype=None, platform="ocl"): 76 79 """ 77 80 Prepare the model for the default execution platform. … … 80 83 on the model and the computing platform. 81 84 82 *model_definition* is the python module which defines the model. If the 83 model name is given instead, then :func:`load_model_definition` will be 84 called with the model name. 85 *model_info* is the model definition structure returned from 86 :func:`load_model_info`. 85 87 86 88 *dtype* indicates whether the model should use single or double precision … … 93 95 otherwise it uses the default "ocl". 94 96 """ 95 if isstr(model_definition): 96 model_definition = load_model_definition(model_definition) 97 source = generate.make_source(model_info) 97 98 if dtype is None: 98 dtype = 'single' if getattr(model_definition, 'single', True) else 'double' 99 source, info = generate.make(model_definition) 100 if callable(info.get('Iq', None)): 101 return kernelpy.PyModel(info) 99 dtype = 'single' if model_info['single'] else 'double' 100 if callable(model_info.get('Iq', None)): 101 return kernelpy.PyModel(model_info) 102 102 103 103 ## for debugging: … … 107 107 ## 4. rerun "python -m sasmodels.direct_model $MODELNAME" 108 108 ## 5. uncomment open().read() so that source will be regenerated from model 109 # open( info['name']+'.c','w').write(source)110 # source = open( info['name']+'.cl','r').read()109 # open(model_info['name']+'.c','w').write(source) 110 # source = open(model_info['name']+'.cl','r').read() 111 111 112 112 if (platform == "dll" 113 113 or not HAVE_OPENCL 114 114 or not kernelcl.environment().has_type(dtype)): 115 return kerneldll.load_dll(source, info, dtype)115 return kerneldll.load_dll(source, model_info, dtype) 116 116 else: 117 return kernelcl.GpuModel(source, info, dtype) 117 return kernelcl.GpuModel(source, model_info, dtype) 118 119 def precompile_dll(model_name, dtype="double"): 120 """ 121 Precompile the dll for a model. 122 123 Returns the path to the compiled model, or None if the model is a pure 124 python model. 125 126 This can be used when build the windows distribution of sasmodels 127 (which may be missing the OpenCL driver and the dll compiler), or 128 otherwise sharing models with windows users who do not have a compiler. 129 130 See :func:`sasmodels.kerneldll.make_dll` for details on controlling the 131 dll path and the allowed floating point precision. 132 """ 133 model_info = load_model_info(model_name) 134 source = generate.make_source(model_info) 135 return kerneldll.make_dll(source, model_info, dtype=dtype) if source else None 136 118 137 119 138 def make_kernel(model, q_vectors): … … 123 142 return model(q_vectors) 124 143 125 def get_weights( info, pars, name):144 def get_weights(model_info, pars, name): 126 145 """ 127 146 Generate the distribution for parameter *name* given the parameter values … … 131 150 from the *pars* dictionary for parameter value and parameter dispersion. 132 151 """ 133 relative = name in info['partype']['pd-rel']134 limits = info['limits'][name]152 relative = name in model_info['partype']['pd-rel'] 153 limits = model_info['limits'][name] 135 154 disperser = pars.get(name+'_pd_type', 'gaussian') 136 value = pars.get(name, info['defaults'][name])155 value = pars.get(name, model_info['defaults'][name]) 137 156 npts = pars.get(name+'_pd_n', 0) 138 157 width = pars.get(name+'_pd', 0.0) … … 173 192 return kernel(fixed_pars, pd_pars, cutoff=cutoff) 174 193 194 def call_ER_VR(model_info, vol_pars): 195 """ 196 Return effect radius and volume ratio for the model. 197 198 *info* is either *kernel.info* for *kernel=make_kernel(model,q)* 199 or *model.info*. 200 201 *pars* are the parameters as expected by :func:`call_kernel`. 202 """ 203 ER = model_info.get('ER', None) 204 VR = model_info.get('VR', None) 205 value, weight = dispersion_mesh(vol_pars) 206 207 individual_radii = ER(*value) if ER else 1.0 208 whole, part = VR(*value) if VR else (1.0, 1.0) 209 210 effect_radius = np.sum(weight*individual_radii) / np.sum(weight) 211 volume_ratio = np.sum(weight*part)/np.sum(weight*whole) 212 return effect_radius, volume_ratio 213 214 175 215 def call_ER(info, pars): 176 216 """ 177 217 Call the model ER function using *pars*. 178 179 218 *info* is either *model.info* if you have a loaded model, or *kernel.info* 180 219 if you have a model kernel prepared for evaluation. … … 194 233 """ 195 234 Call the model VR function using *pars*. 196 197 235 *info* is either *model.info* if you have a loaded model, or *kernel.info* 198 236 if you have a model kernel prepared for evaluation. … … 208 246 return np.sum(weight*part)/np.sum(weight*whole) 209 247 248 # TODO: remove call_ER, call_VR 249 -
sasmodels/direct_model.py
rd18582e r17bbadd 25 25 import numpy as np 26 26 27 from .core import load_model_definition, load_model,make_kernel28 from .core import call_kernel, call_ER , call_VR27 from .core import make_kernel 28 from .core import call_kernel, call_ER_VR 29 29 from . import sesans 30 30 from . import resolution … … 180 180 return self._calc_theory(pars, cutoff=self.cutoff) 181 181 182 def ER(self, **pars): 183 """ 184 Compute the equivalent radius for the model. 185 186 Return 0. if not defined. 187 """ 188 return call_ER(self.model.info, pars) 189 190 def VR(self, **pars): 191 """ 192 Compute the equivalent volume for the model, including polydispersity 193 effects. 194 195 Return 1. if not defined. 196 """ 197 return call_VR(self.model.info, pars) 182 def ER_VR(self, **pars): 183 """ 184 Compute the equivalent radius and volume ratio for the model. 185 """ 186 return call_ER_VR(self.model.info, pars) 198 187 199 188 def simulate_data(self, noise=None, **pars): … … 210 199 import sys 211 200 from .data import empty_data1D, empty_data2D 201 from .core import load_model_info, build_model 212 202 213 203 if len(sys.argv) < 3: … … 216 206 model_name = sys.argv[1] 217 207 call = sys.argv[2].upper() 218 if call not in ("ER", "VR"):208 if call != "ER_VR": 219 209 try: 220 210 values = [float(v) for v in call.split(',')] … … 233 223 data = empty_data1D([0.001]) # Data not used in ER/VR 234 224 235 model_ definition = load_model_definition(model_name)236 model = load_model(model_definition)225 model_info = load_model_info(model_name) 226 model = build_model(model_info) 237 227 calculator = DirectModel(data, model) 238 228 pars = dict((k, float(v)) 239 229 for pair in sys.argv[3:] 240 230 for k, v in [pair.split('=')]) 241 if call == "ER": 242 print(calculator.ER(**pars)) 243 elif call == "VR": 244 print(calculator.VR(**pars)) 231 if call == "ER_VR": 232 print(calculator.ER_VR(**pars)) 245 233 else: 246 234 Iq = calculator(**pars) -
sasmodels/generate.py
r4a4ae41 r2f0c07d 117 117 are added to the beginning of the parameter list. They will show up 118 118 in the documentation as model parameters, but they are never sent to 119 the kernel functions. 120 121 *category* is the default category for the model. Models in the 122 *structure-factor* category do not have *scale* and *background* 123 added. 119 the kernel functions. Note that *effect_radius* and *volfraction* 120 must occur first in structure factor calculations. 121 122 *category* is the default category for the model. The category is 123 two level structure, with the form "group:section", indicating where 124 in the manual the model will be located. Models are alphabetical 125 within their section. 124 126 125 127 *source* is the list of C-99 source files that must be joined to … … 157 159 158 160 159 An * info* dictionary is constructed from the kernel meta data and161 An *model_info* dictionary is constructed from the kernel meta data and 160 162 returned to the caller. 161 163 … … 190 192 191 193 The function :func:`make` loads the metadata from the module and returns 192 the kernel source. The function :func:` doc` extracts the doc string194 the kernel source. The function :func:`make_doc` extracts the doc string 193 195 and adds the parameter table to the top. The function :func:`model_sources` 194 196 returns a list of files required by the model. … … 217 219 import numpy as np 218 220 219 #__all__ = ["make", "doc", "model_sources", "convert_type"] 221 #TODO: determine which functions are useful outside of generate 222 #__all__ = ["model_info", "make_doc", "make_source", "convert_type"] 220 223 221 224 C_KERNEL_TEMPLATE_PATH = joinpath(dirname(__file__), 'kernel_template.c') … … 232 235 COMMON_PARAMETERS = [ 233 236 ["scale", "", 1, [0, np.inf], "", "Source intensity"], 234 ["background", "1/cm", 0, [0, np.inf], "", "Source background"],237 ["background", "1/cm", 1e-3, [0, np.inf], "", "Source background"], 235 238 ] 236 239 … … 327 330 raise ValueError("%r not found in %s" % (filename, search_path)) 328 331 329 def model_sources( info):332 def model_sources(model_info): 330 333 """ 331 334 Return a list of the sources file paths for the module. 332 335 """ 333 search_path = [dirname( info['filename']),336 search_path = [dirname(model_info['filename']), 334 337 abspath(joinpath(dirname(__file__), 'models'))] 335 return [_search(search_path, f) for f in info['source']]338 return [_search(search_path, f) for f in model_info['source']] 336 339 337 340 # Pragmas for enable OpenCL features. Be sure to protect them so that they … … 391 394 392 395 393 def kernel_name( info, is_2d):396 def kernel_name(model_info, is_2d): 394 397 """ 395 398 Name of the exported kernel symbol. 396 399 """ 397 return info['name'] + "_" + ("Iqxy" if is_2d else "Iq") 398 400 return model_info['name'] + "_" + ("Iqxy" if is_2d else "Iq") 401 402 403 def indent(s, depth): 404 """ 405 Indent a string of text with *depth* additional spaces on each line. 406 """ 407 spaces = " "*depth 408 sep = "\n" + spaces 409 return spaces + sep.join(s.split("\n")) 410 411 412 LOOP_OPEN = """\ 413 for (int %(name)s_i=0; %(name)s_i < N%(name)s; %(name)s_i++) { 414 const double %(name)s = loops[2*(%(name)s_i%(offset)s)]; 415 const double %(name)s_w = loops[2*(%(name)s_i%(offset)s)+1];\ 416 """ 417 def build_polydispersity_loops(pd_pars): 418 """ 419 Build polydispersity loops 420 421 Returns loop opening and loop closing 422 """ 423 depth = 4 424 offset = "" 425 loop_head = [] 426 loop_end = [] 427 for name in pd_pars: 428 subst = {'name': name, 'offset': offset} 429 loop_head.append(indent(LOOP_OPEN % subst, depth)) 430 loop_end.insert(0, (" "*depth) + "}") 431 offset += '+N' + name 432 depth += 2 433 return "\n".join(loop_head), "\n".join(loop_end) 434 435 C_KERNEL_TEMPLATE = None 436 def make_source(model_info): 437 """ 438 Generate the OpenCL/ctypes kernel from the module info. 439 440 Uses source files found in the given search path. 441 """ 442 if callable(model_info['Iq']): 443 return None 444 445 # TODO: need something other than volume to indicate dispersion parameters 446 # No volume normalization despite having a volume parameter. 447 # Thickness is labelled a volume in order to trigger polydispersity. 448 # May want a separate dispersion flag, or perhaps a separate category for 449 # disperse, but not volume. Volume parameters also use relative values 450 # for the distribution rather than the absolute values used by angular 451 # dispersion. Need to be careful that necessary parameters are available 452 # for computing volume even if we allow non-disperse volume parameters. 453 454 # Load template 455 global C_KERNEL_TEMPLATE 456 if C_KERNEL_TEMPLATE is None: 457 with open(C_KERNEL_TEMPLATE_PATH) as fid: 458 C_KERNEL_TEMPLATE = fid.read() 459 460 # Load additional sources 461 source = [open(f).read() for f in model_sources(model_info)] 462 463 # Prepare defines 464 defines = [] 465 partype = model_info['partype'] 466 pd_1d = partype['pd-1d'] 467 pd_2d = partype['pd-2d'] 468 fixed_1d = partype['fixed-1d'] 469 fixed_2d = partype['fixed-1d'] 470 471 iq_parameters = [p[0] 472 for p in model_info['parameters'][2:] # skip scale, background 473 if p[0] in set(fixed_1d + pd_1d)] 474 iqxy_parameters = [p[0] 475 for p in model_info['parameters'][2:] # skip scale, background 476 if p[0] in set(fixed_2d + pd_2d)] 477 volume_parameters = [p[0] 478 for p in model_info['parameters'] 479 if p[4] == 'volume'] 480 481 # Fill in defintions for volume parameters 482 if volume_parameters: 483 defines.append(('VOLUME_PARAMETERS', 484 ','.join(volume_parameters))) 485 defines.append(('VOLUME_WEIGHT_PRODUCT', 486 '*'.join(p + '_w' for p in volume_parameters))) 487 488 # Generate form_volume function from body only 489 if model_info['form_volume'] is not None: 490 if volume_parameters: 491 vol_par_decl = ', '.join('double ' + p for p in volume_parameters) 492 else: 493 vol_par_decl = 'void' 494 defines.append(('VOLUME_PARAMETER_DECLARATIONS', 495 vol_par_decl)) 496 fn = """\ 497 double form_volume(VOLUME_PARAMETER_DECLARATIONS); 498 double form_volume(VOLUME_PARAMETER_DECLARATIONS) { 499 %(body)s 500 } 501 """ % {'body':model_info['form_volume']} 502 source.append(fn) 503 504 # Fill in definitions for Iq parameters 505 defines.append(('IQ_KERNEL_NAME', model_info['name'] + '_Iq')) 506 defines.append(('IQ_PARAMETERS', ', '.join(iq_parameters))) 507 if fixed_1d: 508 defines.append(('IQ_FIXED_PARAMETER_DECLARATIONS', 509 ', \\\n '.join('const double %s' % p for p in fixed_1d))) 510 if pd_1d: 511 defines.append(('IQ_WEIGHT_PRODUCT', 512 '*'.join(p + '_w' for p in pd_1d))) 513 defines.append(('IQ_DISPERSION_LENGTH_DECLARATIONS', 514 ', \\\n '.join('const int N%s' % p for p in pd_1d))) 515 defines.append(('IQ_DISPERSION_LENGTH_SUM', 516 '+'.join('N' + p for p in pd_1d))) 517 open_loops, close_loops = build_polydispersity_loops(pd_1d) 518 defines.append(('IQ_OPEN_LOOPS', 519 open_loops.replace('\n', ' \\\n'))) 520 defines.append(('IQ_CLOSE_LOOPS', 521 close_loops.replace('\n', ' \\\n'))) 522 if model_info['Iq'] is not None: 523 defines.append(('IQ_PARAMETER_DECLARATIONS', 524 ', '.join('double ' + p for p in iq_parameters))) 525 fn = """\ 526 double Iq(double q, IQ_PARAMETER_DECLARATIONS); 527 double Iq(double q, IQ_PARAMETER_DECLARATIONS) { 528 %(body)s 529 } 530 """ % {'body':model_info['Iq']} 531 source.append(fn) 532 533 # Fill in definitions for Iqxy parameters 534 defines.append(('IQXY_KERNEL_NAME', model_info['name'] + '_Iqxy')) 535 defines.append(('IQXY_PARAMETERS', ', '.join(iqxy_parameters))) 536 if fixed_2d: 537 defines.append(('IQXY_FIXED_PARAMETER_DECLARATIONS', 538 ', \\\n '.join('const double %s' % p for p in fixed_2d))) 539 if pd_2d: 540 defines.append(('IQXY_WEIGHT_PRODUCT', 541 '*'.join(p + '_w' for p in pd_2d))) 542 defines.append(('IQXY_DISPERSION_LENGTH_DECLARATIONS', 543 ', \\\n '.join('const int N%s' % p for p in pd_2d))) 544 defines.append(('IQXY_DISPERSION_LENGTH_SUM', 545 '+'.join('N' + p for p in pd_2d))) 546 open_loops, close_loops = build_polydispersity_loops(pd_2d) 547 defines.append(('IQXY_OPEN_LOOPS', 548 open_loops.replace('\n', ' \\\n'))) 549 defines.append(('IQXY_CLOSE_LOOPS', 550 close_loops.replace('\n', ' \\\n'))) 551 if model_info['Iqxy'] is not None: 552 defines.append(('IQXY_PARAMETER_DECLARATIONS', 553 ', '.join('double ' + p for p in iqxy_parameters))) 554 fn = """\ 555 double Iqxy(double qx, double qy, IQXY_PARAMETER_DECLARATIONS); 556 double Iqxy(double qx, double qy, IQXY_PARAMETER_DECLARATIONS) { 557 %(body)s 558 } 559 """ % {'body':model_info['Iqxy']} 560 source.append(fn) 561 562 # Need to know if we have a theta parameter for Iqxy; it is not there 563 # for the magnetic sphere model, for example, which has a magnetic 564 # orientation but no shape orientation. 565 if 'theta' in pd_2d: 566 defines.append(('IQXY_HAS_THETA', '1')) 567 568 #for d in defines: print(d) 569 defines = '\n'.join('#define %s %s' % (k, v) for k, v in defines) 570 sources = '\n\n'.join(source) 571 return C_KERNEL_TEMPLATE % { 572 'DEFINES': defines, 573 'SOURCES': sources, 574 } 399 575 400 576 def categorize_parameters(pars): … … 403 579 404 580 Returns a dictionary of categories. 581 582 Note: these categories are subject to change, depending on the needs of 583 the UI and the needs of the kernel calling function. 584 585 The categories are as follows: 586 587 * *volume* list of volume parameter names 588 * *orientation* list of orientation parameters 589 * *magnetic* list of magnetic parameters 590 * *<empty string>* list of parameters that have no type info 591 592 Each parameter is in one and only one category. 593 594 The following derived categories are created: 595 596 * *fixed-1d* list of non-polydisperse parameters for 1D models 597 * *pd-1d* list of polydisperse parameters for 1D models 598 * *fixed-2d* list of non-polydisperse parameters for 2D models 599 * *pd-d2* list of polydisperse parameters for 2D models 405 600 """ 406 601 partype = { … … 429 624 return partype 430 625 431 def indent(s, depth): 432 """ 433 Indent a string of text with *depth* additional spaces on each line. 434 """ 435 spaces = " "*depth 436 sep = "\n" + spaces 437 return spaces + sep.join(s.split("\n")) 438 439 440 LOOP_OPEN = """\ 441 for (int %(name)s_i=0; %(name)s_i < N%(name)s; %(name)s_i++) { 442 const double %(name)s = loops[2*(%(name)s_i%(offset)s)]; 443 const double %(name)s_w = loops[2*(%(name)s_i%(offset)s)+1];\ 444 """ 445 def build_polydispersity_loops(pd_pars): 446 """ 447 Build polydispersity loops 448 449 Returns loop opening and loop closing 450 """ 451 depth = 4 452 offset = "" 453 loop_head = [] 454 loop_end = [] 455 for name in pd_pars: 456 subst = {'name': name, 'offset': offset} 457 loop_head.append(indent(LOOP_OPEN % subst, depth)) 458 loop_end.insert(0, (" "*depth) + "}") 459 offset += '+N' + name 460 depth += 2 461 return "\n".join(loop_head), "\n".join(loop_end) 462 463 C_KERNEL_TEMPLATE = None 464 def make_model(info): 465 """ 466 Generate the code for the kernel defined by info, using source files 467 found in the given search path. 468 """ 469 # TODO: need something other than volume to indicate dispersion parameters 470 # No volume normalization despite having a volume parameter. 471 # Thickness is labelled a volume in order to trigger polydispersity. 472 # May want a separate dispersion flag, or perhaps a separate category for 473 # disperse, but not volume. Volume parameters also use relative values 474 # for the distribution rather than the absolute values used by angular 475 # dispersion. Need to be careful that necessary parameters are available 476 # for computing volume even if we allow non-disperse volume parameters. 477 478 # Load template 479 global C_KERNEL_TEMPLATE 480 if C_KERNEL_TEMPLATE is None: 481 with open(C_KERNEL_TEMPLATE_PATH) as fid: 482 C_KERNEL_TEMPLATE = fid.read() 483 484 # Load additional sources 485 source = [open(f).read() for f in model_sources(info)] 486 487 # Prepare defines 488 defines = [] 489 partype = info['partype'] 490 pd_1d = partype['pd-1d'] 491 pd_2d = partype['pd-2d'] 492 fixed_1d = partype['fixed-1d'] 493 fixed_2d = partype['fixed-1d'] 494 495 iq_parameters = [p[0] 496 for p in info['parameters'][2:] # skip scale, background 497 if p[0] in set(fixed_1d + pd_1d)] 498 iqxy_parameters = [p[0] 499 for p in info['parameters'][2:] # skip scale, background 500 if p[0] in set(fixed_2d + pd_2d)] 501 volume_parameters = [p[0] 502 for p in info['parameters'] 503 if p[4] == 'volume'] 504 505 # Fill in defintions for volume parameters 506 if volume_parameters: 507 defines.append(('VOLUME_PARAMETERS', 508 ','.join(volume_parameters))) 509 defines.append(('VOLUME_WEIGHT_PRODUCT', 510 '*'.join(p + '_w' for p in volume_parameters))) 511 512 # Generate form_volume function from body only 513 if info['form_volume'] is not None: 514 if volume_parameters: 515 vol_par_decl = ', '.join('double ' + p for p in volume_parameters) 516 else: 517 vol_par_decl = 'void' 518 defines.append(('VOLUME_PARAMETER_DECLARATIONS', 519 vol_par_decl)) 520 fn = """\ 521 double form_volume(VOLUME_PARAMETER_DECLARATIONS); 522 double form_volume(VOLUME_PARAMETER_DECLARATIONS) { 523 %(body)s 524 } 525 """ % {'body':info['form_volume']} 526 source.append(fn) 527 528 # Fill in definitions for Iq parameters 529 defines.append(('IQ_KERNEL_NAME', info['name'] + '_Iq')) 530 defines.append(('IQ_PARAMETERS', ', '.join(iq_parameters))) 531 if fixed_1d: 532 defines.append(('IQ_FIXED_PARAMETER_DECLARATIONS', 533 ', \\\n '.join('const double %s' % p for p in fixed_1d))) 534 if pd_1d: 535 defines.append(('IQ_WEIGHT_PRODUCT', 536 '*'.join(p + '_w' for p in pd_1d))) 537 defines.append(('IQ_DISPERSION_LENGTH_DECLARATIONS', 538 ', \\\n '.join('const int N%s' % p for p in pd_1d))) 539 defines.append(('IQ_DISPERSION_LENGTH_SUM', 540 '+'.join('N' + p for p in pd_1d))) 541 open_loops, close_loops = build_polydispersity_loops(pd_1d) 542 defines.append(('IQ_OPEN_LOOPS', 543 open_loops.replace('\n', ' \\\n'))) 544 defines.append(('IQ_CLOSE_LOOPS', 545 close_loops.replace('\n', ' \\\n'))) 546 if info['Iq'] is not None: 547 defines.append(('IQ_PARAMETER_DECLARATIONS', 548 ', '.join('double ' + p for p in iq_parameters))) 549 fn = """\ 550 double Iq(double q, IQ_PARAMETER_DECLARATIONS); 551 double Iq(double q, IQ_PARAMETER_DECLARATIONS) { 552 %(body)s 553 } 554 """ % {'body':info['Iq']} 555 source.append(fn) 556 557 # Fill in definitions for Iqxy parameters 558 defines.append(('IQXY_KERNEL_NAME', info['name'] + '_Iqxy')) 559 defines.append(('IQXY_PARAMETERS', ', '.join(iqxy_parameters))) 560 if fixed_2d: 561 defines.append(('IQXY_FIXED_PARAMETER_DECLARATIONS', 562 ', \\\n '.join('const double %s' % p for p in fixed_2d))) 563 if pd_2d: 564 defines.append(('IQXY_WEIGHT_PRODUCT', 565 '*'.join(p + '_w' for p in pd_2d))) 566 defines.append(('IQXY_DISPERSION_LENGTH_DECLARATIONS', 567 ', \\\n '.join('const int N%s' % p for p in pd_2d))) 568 defines.append(('IQXY_DISPERSION_LENGTH_SUM', 569 '+'.join('N' + p for p in pd_2d))) 570 open_loops, close_loops = build_polydispersity_loops(pd_2d) 571 defines.append(('IQXY_OPEN_LOOPS', 572 open_loops.replace('\n', ' \\\n'))) 573 defines.append(('IQXY_CLOSE_LOOPS', 574 close_loops.replace('\n', ' \\\n'))) 575 if info['Iqxy'] is not None: 576 defines.append(('IQXY_PARAMETER_DECLARATIONS', 577 ', '.join('double ' + p for p in iqxy_parameters))) 578 fn = """\ 579 double Iqxy(double qx, double qy, IQXY_PARAMETER_DECLARATIONS); 580 double Iqxy(double qx, double qy, IQXY_PARAMETER_DECLARATIONS) { 581 %(body)s 582 } 583 """ % {'body':info['Iqxy']} 584 source.append(fn) 585 586 # Need to know if we have a theta parameter for Iqxy; it is not there 587 # for the magnetic sphere model, for example, which has a magnetic 588 # orientation but no shape orientation. 589 if 'theta' in pd_2d: 590 defines.append(('IQXY_HAS_THETA', '1')) 591 592 #for d in defines: print(d) 593 defines = '\n'.join('#define %s %s' % (k, v) for k, v in defines) 594 sources = '\n\n'.join(source) 595 return C_KERNEL_TEMPLATE % { 596 'DEFINES': defines, 597 'SOURCES': sources, 598 } 599 600 def make_info(kernel_module): 626 def process_parameters(model_info): 627 """ 628 Process parameter block, precalculating parameter details. 629 """ 630 # Fill in the derived attributes 631 partype = categorize_parameters(model_info['parameters']) 632 model_info['limits'] = dict((p[0], p[3]) for p in model_info['parameters']) 633 model_info['partype'] = partype 634 model_info['defaults'] = dict((p[0], p[2]) for p in model_info['parameters']) 635 if model_info.get('demo', None) is None: 636 model_info['demo'] = model_info['defaults'] 637 model_info['has_2d'] = partype['orientation'] or partype['magnetic'] 638 639 def make_model_info(kernel_module): 601 640 """ 602 641 Interpret the model definition file, categorizing the parameters. 603 """ 604 #print(kernelfile) 605 category = getattr(kernel_module, 'category', None) 642 643 The module can be loaded with a normal python import statement if you 644 know which module you need, or with __import__('sasmodels.model.'+name) 645 if the name is in a string. 646 647 The *model_info* structure contains the following fields: 648 649 * *id* is the id of the kernel 650 * *name* is the display name of the kernel 651 * *title* is a short description of the kernel 652 * *description* is a long description of the kernel (this doesn't seem 653 very useful since the Help button on the model page brings you directly 654 to the documentation page) 655 * *docs* is the docstring from the module. Use :func:`make_doc` to 656 * *category* specifies the model location in the docs 657 * *parameters* is the model parameter table 658 * *single* is True if the model allows single precision 659 * *structure_factor* is True if the model is useable in a product 660 * *variant_info* contains the information required to select between 661 model variants (e.g., the list of cases) or is None if there are no 662 model variants 663 * *defaults* is the *{parameter: value}* table built from the parameter 664 description table. 665 * *limits* is the *{parameter: [min, max]}* table built from the 666 parameter description table. 667 * *partypes* categorizes the model parameters. See 668 :func:`categorize_parameters` for details. 669 * *demo* contains the *{parameter: value}* map used in compare (and maybe 670 for the demo plot, if plots aren't set up to use the default values). 671 If *demo* is not given in the file, then the default values will be used. 672 * *tests* is a set of tests that must pass 673 * *source* is the list of library files to include in the C model build 674 * *Iq*, *Iqxy*, *form_volume*, *ER*, *VR* and *sesans* are python functions 675 implementing the kernel for the module, or None if they are not 676 defined in python 677 * *oldname* is the model name in pre-4.0 Sasview 678 * *oldpars* is the *{new: old}* parameter translation table 679 from pre-4.0 Sasview 680 * *composition* is None if the model is independent, otherwise it is a 681 tuple with composition type ('product' or 'mixture') and a list of 682 *model_info* blocks for the composition objects. This allows us to 683 build complete product and mixture models from just the info. 684 685 """ 686 # TODO: maybe turn model_info into a class ModelDefinition 606 687 parameters = COMMON_PARAMETERS + kernel_module.parameters 607 # Default the demo parameters to the starting values for the individual608 # parameters if an explicit demo parameter set has not been specified.609 demo_parameters = getattr(kernel_module, 'demo', None)610 if demo_parameters is None:611 demo_parameters = dict((p[0], p[2]) for p in parameters)612 688 filename = abspath(kernel_module.__file__) 613 689 kernel_id = splitext(basename(filename))[0] … … 615 691 if name is None: 616 692 name = " ".join(w.capitalize() for w in kernel_id.split('_')) 617 info = dict(693 model_info = dict( 618 694 id=kernel_id, # string used to load the kernel 619 695 filename=abspath(kernel_module.__file__), … … 621 697 title=kernel_module.title, 622 698 description=kernel_module.description, 623 category=category,624 699 parameters=parameters, 625 demo=demo_parameters, 700 composition=None, 701 docs=kernel_module.__doc__, 702 category=getattr(kernel_module, 'category', None), 703 single=getattr(kernel_module, 'single', True), 704 structure_factor=getattr(kernel_module, 'structure_factor', False), 705 variant_info=getattr(kernel_module, 'invariant_info', None), 706 demo=getattr(kernel_module, 'demo', None), 626 707 source=getattr(kernel_module, 'source', []), 627 oldname=kernel_module.oldname, 628 oldpars=kernel_module.oldpars, 708 oldname=getattr(kernel_module, 'oldname', None), 709 oldpars=getattr(kernel_module, 'oldpars', {}), 710 tests=getattr(kernel_module, 'tests', []), 629 711 ) 630 # Fill in attributes which default to None 631 info.update((k, getattr(kernel_module, k, None)) 632 for k in ('ER', 'VR', 'form_volume', 'Iq', 'Iqxy')) 633 # Fill in the derived attributes 634 info['limits'] = dict((p[0], p[3]) for p in info['parameters']) 635 info['partype'] = categorize_parameters(info['parameters']) 636 info['defaults'] = dict((p[0], p[2]) for p in info['parameters']) 637 return info 638 639 def make(kernel_module): 640 """ 641 Build an OpenCL/ctypes function from the definition in *kernel_module*. 642 643 The module can be loaded with a normal python import statement if you 644 know which module you need, or with __import__('sasmodels.model.'+name) 645 if the name is in a string. 646 """ 647 info = make_info(kernel_module) 648 # Assume if one part of the kernel is python then all parts are. 649 source = make_model(info) if not callable(info['Iq']) else None 650 return source, info 712 process_parameters(model_info) 713 # Check for optional functions 714 functions = "ER VR form_volume Iq Iqxy shape sesans".split() 715 model_info.update((k, getattr(kernel_module, k, None)) for k in functions) 716 return model_info 651 717 652 718 section_marker = re.compile(r'\A(?P<first>[%s])(?P=first)*\Z' … … 683 749 return "\n".join(_convert_section_titles_to_boldface(s.split('\n'))) 684 750 685 def doc(kernel_module):751 def make_doc(model_info): 686 752 """ 687 753 Return the documentation for the model. … … 689 755 Iq_units = "The returned value is scaled to units of |cm^-1| |sr^-1|, absolute scale." 690 756 Sq_units = "The returned value is a dimensionless structure factor, $S(q)$." 691 info = make_info(kernel_module) 692 is_Sq = ("structure-factor" in info['category']) 693 #docs = kernel_module.__doc__ 694 docs = convert_section_titles_to_boldface(kernel_module.__doc__) 695 subst = dict(id=info['id'].replace('_', '-'), 696 name=info['name'], 697 title=info['title'], 698 parameters=make_partable(info['parameters']), 699 returns=Sq_units if is_Sq else Iq_units, 757 docs = convert_section_titles_to_boldface(model_info['docs']) 758 subst = dict(id=model_info['id'].replace('_', '-'), 759 name=model_info['name'], 760 title=model_info['title'], 761 parameters=make_partable(model_info['parameters']), 762 returns=Sq_units if model_info['structure_factor'] else Iq_units, 700 763 docs=docs) 701 764 return DOC_HEADER % subst … … 710 773 import datetime 711 774 tic = datetime.datetime.now() 712 make (cylinder)775 make_source(make_model_info(cylinder)) 713 776 toc = (datetime.datetime.now() - tic).total_seconds() 714 777 print("time: %g"%toc) … … 725 788 __import__('sasmodels.models.' + name) 726 789 model = getattr(sasmodels.models, name) 727 source, _ = make(model) 790 model_info = make_model_info(model) 791 source = make_source(model_info) 728 792 print(source) 729 793 -
sasmodels/kernelcl.py
re6a5556 r17bbadd 289 289 GPU wrapper for a single model. 290 290 291 *source* and * info* are the model source and interface as returned292 from :func:`gen .make`.291 *source* and *model_info* are the model source and interface as returned 292 from :func:`generate.make_source` and :func:`generate.make_model_info`. 293 293 294 294 *dtype* is the desired model precision. Any numpy dtype for single … … 300 300 that the compiler is allowed to take shortcuts. 301 301 """ 302 def __init__(self, source, info, dtype=generate.F32):303 self.info = info302 def __init__(self, source, model_info, dtype=generate.F32): 303 self.info = model_info 304 304 self.source = source 305 305 self.dtype = generate.F32 if dtype == 'fast' else np.dtype(dtype) … … 356 356 """ 357 357 def __init__(self, q_vectors, dtype=generate.F32): 358 # TODO: do we ever need double precision q? 358 359 env = environment() 359 360 self.nq = q_vectors[0].size … … 389 390 *kernel* is the GpuKernel object to call 390 391 391 * info* is the module information392 *model_info* is the module information 392 393 393 394 *q_vectors* is the q vectors at which the kernel should be evaluated … … 403 404 Call :meth:`release` when done with the kernel instance. 404 405 """ 405 def __init__(self, kernel, info, q_vectors, dtype):406 def __init__(self, kernel, model_info, q_vectors, dtype): 406 407 q_input = GpuInput(q_vectors, dtype) 407 408 self.kernel = kernel 408 self.info = info409 self.info = model_info 409 410 self.res = np.empty(q_input.nq, q_input.dtype) 410 411 dim = '2d' if q_input.is_2d else '1d' 411 self.fixed_pars = info['partype']['fixed-' + dim]412 self.pd_pars = info['partype']['pd-' + dim]412 self.fixed_pars = model_info['partype']['fixed-' + dim] 413 self.pd_pars = model_info['partype']['pd-' + dim] 413 414 414 415 # Inputs and outputs for each kernel call … … 430 431 else np.float32) # will never get here, so use np.float32 431 432 433 #print "pars", fixed_pars, pd_pars 432 434 res_bi = self.res_b 433 435 nq = np.uint32(self.q_input.nq) -
sasmodels/kerneldll.py
reafc9fa r17bbadd 89 89 90 90 91 def dll_path( info, dtype="double"):92 """ 93 Path to the compiled model defined by * info*.91 def dll_path(model_info, dtype="double"): 92 """ 93 Path to the compiled model defined by *model_info*. 94 94 """ 95 95 from os.path import join as joinpath, split as splitpath, splitext 96 basename = splitext(splitpath( info['filename'])[1])[0]96 basename = splitext(splitpath(model_info['filename'])[1])[0] 97 97 if np.dtype(dtype) == generate.F32: 98 98 basename += "32" … … 104 104 105 105 106 def make_dll(source, info, dtype="double"):106 def make_dll(source, model_info, dtype="double"): 107 107 """ 108 108 Load the compiled model defined by *kernel_module*. … … 123 123 models are allowed as DLLs. 124 124 """ 125 if callable( info.get('Iq', None)):126 return PyModel( info)125 if callable(model_info.get('Iq', None)): 126 return PyModel(model_info) 127 127 128 128 dtype = np.dtype(dtype) … … 133 133 134 134 if dtype == generate.F32: # 32-bit dll 135 tempfile_prefix = 'sas_' +info['name']+'32_'135 tempfile_prefix = 'sas_' + model_info['name'] + '32_' 136 136 elif dtype == generate.F64: 137 tempfile_prefix = 'sas_' +info['name']+'64_'137 tempfile_prefix = 'sas_' + model_info['name'] + '64_' 138 138 else: 139 tempfile_prefix = 'sas_' +info['name']+'128_'139 tempfile_prefix = 'sas_' + model_info['name'] + '128_' 140 140 141 141 source = generate.convert_type(source, dtype) 142 source_files = generate.model_sources( info) + [info['filename']]143 dll = dll_path( info, dtype)142 source_files = generate.model_sources(model_info) + [model_info['filename']] 143 dll = dll_path(model_info, dtype) 144 144 newest = max(os.path.getmtime(f) for f in source_files) 145 145 if not os.path.exists(dll) or os.path.getmtime(dll) < newest: … … 159 159 160 160 161 def load_dll(source, info, dtype="double"):161 def load_dll(source, model_info, dtype="double"): 162 162 """ 163 163 Create and load a dll corresponding to the source, info pair returned … … 167 167 allowed floating point precision. 168 168 """ 169 filename = make_dll(source, info, dtype=dtype)170 return DllModel(filename, info, dtype=dtype)169 filename = make_dll(source, model_info, dtype=dtype) 170 return DllModel(filename, model_info, dtype=dtype) 171 171 172 172 … … 178 178 ctypes wrapper for a single model. 179 179 180 *source* and * info* are the model source and interface as returned180 *source* and *model_info* are the model source and interface as returned 181 181 from :func:`gen.make`. 182 182 … … 188 188 Call :meth:`release` when done with the kernel. 189 189 """ 190 def __init__(self, dllpath, info, dtype=generate.F32):191 self.info = info190 def __init__(self, dllpath, model_info, dtype=generate.F32): 191 self.info = model_info 192 192 self.dllpath = dllpath 193 193 self.dll = None … … 244 244 *kernel* is the c function to call. 245 245 246 * info* is the module information246 *model_info* is the module information 247 247 248 248 *q_input* is the DllInput q vectors at which the kernel should be … … 257 257 Call :meth:`release` when done with the kernel instance. 258 258 """ 259 def __init__(self, kernel, info, q_input):260 self.info = info259 def __init__(self, kernel, model_info, q_input): 260 self.info = model_info 261 261 self.q_input = q_input 262 262 self.kernel = kernel 263 263 self.res = np.empty(q_input.nq, q_input.dtype) 264 264 dim = '2d' if q_input.is_2d else '1d' 265 self.fixed_pars = info['partype']['fixed-'+dim]266 self.pd_pars = info['partype']['pd-'+dim]265 self.fixed_pars = model_info['partype']['fixed-' + dim] 266 self.pd_pars = model_info['partype']['pd-' + dim] 267 267 268 268 # In dll kernel, but not in opencl kernel -
sasmodels/kernelpy.py
reafc9fa r17bbadd 16 16 Wrapper for pure python models. 17 17 """ 18 def __init__(self, info):19 self.info = info18 def __init__(self, model_info): 19 self.info = model_info 20 20 21 21 def __call__(self, q_vectors): … … 68 68 *kernel* is the DllKernel object to call. 69 69 70 * info* is the module information70 *model_info* is the module information 71 71 72 72 *q_input* is the DllInput q vectors at which the kernel should be … … 81 81 Call :meth:`release` when done with the kernel instance. 82 82 """ 83 def __init__(self, kernel, info, q_input):84 self.info = info83 def __init__(self, kernel, model_info, q_input): 84 self.info = model_info 85 85 self.q_input = q_input 86 86 self.res = np.empty(q_input.nq, q_input.dtype) … … 106 106 else: 107 107 self.kernel = kernel 108 fixed_pars = info['partype']['fixed-' + dim]109 pd_pars = info['partype']['pd-' + dim]110 vol_pars = info['partype']['volume']108 fixed_pars = model_info['partype']['fixed-' + dim] 109 pd_pars = model_info['partype']['pd-' + dim] 110 vol_pars = model_info['partype']['volume'] 111 111 112 112 # First two fixed pars are scale and background 113 pars = [p[0] for p in info['parameters'][2:]]113 pars = [p[0] for p in model_info['parameters'][2:]] 114 114 offset = len(self.q_input.q_vectors) 115 115 self.args = self.q_input.q_vectors + [None] * len(pars) -
sasmodels/list_pars.py
r5c962df r17bbadd 13 13 import sys 14 14 15 from .core import load_model_definition 16 from .generate import make_info 15 from .core import load_model_info 17 16 from .compare import MODELS, columnize 18 17 … … 25 24 partable = {} 26 25 for name in sorted(MODELS): 27 definition = load_model_definition(name) 28 info = make_info(definition) 29 for p in info['parameters']: 26 model_info = load_model_info(name) 27 for p in model_info['parameters']: 30 28 pname = p[0] 31 29 partable.setdefault(pname, []) -
sasmodels/model_test.py
r13ed84c r17bbadd 50 50 import numpy as np 51 51 52 from .core import list_models, load_model_ definition, load_model, HAVE_OPENCL52 from .core import list_models, load_model_info, build_model, HAVE_OPENCL 53 53 from .core import make_kernel, call_kernel, call_ER, call_VR 54 54 from .exception import annotate_exception 55 55 56 #TODO: rename to tests so that tab completion works better for models directory 56 57 57 58 def make_suite(loaders, models): … … 76 77 for model_name in models: 77 78 if model_name in skip: continue 78 model_ definition = load_model_definition(model_name)79 model_info = load_model_info(model_name) 79 80 80 81 #print('------') … … 85 86 # don't try to call cl kernel since it will not be 86 87 # available in some environmentes. 87 is_py = callable( getattr(model_definition, 'Iq', None))88 is_py = callable(model_info['Iq']) 88 89 89 90 if is_py: # kernel implemented in python 90 91 test_name = "Model: %s, Kernel: python"%model_name 91 92 test_method_name = "test_%s_python" % model_name 92 test = ModelTestCase(test_name, model_ definition,93 test = ModelTestCase(test_name, model_info, 93 94 test_method_name, 94 95 platform="dll", # so that … … 104 105 # single precision. The choice is determined by the 105 106 # presence of *single=False* in the model file. 106 test = ModelTestCase(test_name, model_ definition,107 test = ModelTestCase(test_name, model_info, 107 108 test_method_name, 108 109 platform="ocl", dtype=None) … … 114 115 test_name = "Model: %s, Kernel: dll"%model_name 115 116 test_method_name = "test_%s_dll" % model_name 116 test = ModelTestCase(test_name, model_ definition,117 test = ModelTestCase(test_name, model_info, 117 118 test_method_name, 118 119 platform="dll", … … 132 133 description file. 133 134 """ 134 def __init__(self, test_name, definition, test_method_name,135 def __init__(self, test_name, model_info, test_method_name, 135 136 platform, dtype): 136 137 self.test_name = test_name 137 self. definition = definition138 self.info = model_info 138 139 self.platform = platform 139 140 self.dtype = dtype … … 150 151 ] 151 152 152 tests = getattr(self.definition, 'tests', [])153 tests = self.info['tests'] 153 154 try: 154 model = load_model(self.definition, dtype=self.dtype,155 platform=self.platform)155 model = build_model(self.info, dtype=self.dtype, 156 platform=self.platform) 156 157 for test in smoke_tests + tests: 157 158 self._run_one_test(model, test) -
sasmodels/models/_onion.py
rfdb1487 r2f0c07d 146 146 \frac{j_1(qr_\text{in})}{qr_\text{in}} 147 147 148 .. figure:: img/onion_ annotated_profile.gif148 .. figure:: img/onion_geometry.gif 149 149 150 150 Example of an onion model profile. … … 159 159 NB: The outer most radius is used as the effective radius for $S(q)$ 160 160 when $P(q) S(q)$ is applied. 161 162 .. figure:: img/onion_1d.jpg163 164 1D plot using the default values (w/400 point)165 166 .. figure:: img/onion_profile.jpg167 168 SLD profile from the default values.169 161 170 162 References … … 321 313 322 314 323 def profile(core_sld, core_radius, solvent_sld, n, in_sld, out_sld, thickness, A):315 def shape(core_sld, core_radius, solvent_sld, n, in_sld, out_sld, thickness, A): 324 316 """ 325 Get SLD profile 326 327 Returns *(r, rho(r))* where *r* is the radius (Ang) and *rho(r)* is the 328 SLD (1/Ang^2). 317 SLD profile 329 318 """ 330 319 -
sasmodels/models/adsorbed_layer.py
r5b2930f r2f0c07d 20 20 21 21 Note that all parameters except the |sigma| are correlated so fitting more than one of these parameters will generally fail. Also note that unlike other shape models, no volume normalization is applied to this model (the calculation is exact). 22 23 .. figure:: img/adsorbed_layer_1d.jpg24 25 1D plot using the default values.26 27 The 2D scattering intensity is calculated in the same way as the 1D, but where the *q* vector is redefined as28 29 .. image:: img/2d_q_vector.gif30 22 31 23 References -
sasmodels/models/barbell.py
r50e1e40 r2f0c07d 68 68 up to you to restrict this during analysis. 69 69 70 .. figure:: img/barbell_1d.jpg 70 The 2D scattering intensity is calculated similar to the 2D cylinder model. 71 71 72 1D plot using the default values (w/256 data point). 73 74 For 2D data, the scattering intensity is calculated similar to the 2D 75 cylinder model. 76 77 .. figure:: img/barbell_2d.jpg 78 79 2D plot (w/(256X265) data points) for $\theta = 45^\circ$ and 80 $\phi = 0^\circ$ with default values for the remaining parameters. 81 82 .. figure:: img/orientation.jpg 72 .. figure:: img/cylinder_angle_definition.jpg 83 73 84 74 Definition of the angles for oriented 2D barbells. 85 75 86 .. figure:: img/ orientation2.jpg76 .. figure:: img/cylinder_angle_projection.jpg 87 77 88 78 Examples of the angles for oriented pp against the detector plane. -
sasmodels/models/bcc.py
rad90df9 r2f0c07d 45 45 46 46 47 .. figure:: img/bcc_ lattice.jpg47 .. figure:: img/bcc_geometry.jpg 48 48 49 49 Body-centered cubic lattice. … … 77 77 *qmin* = 0.001 |Ang^-1|, *qmax* = 0.1 |Ang^-1| and the above default values. 78 78 79 .. figure:: img/bcc_1d.jpg80 81 1D plot in the linear scale using the default values (w/200 data point).82 83 79 The 2D (Anisotropic model) is based on the reference below where $I(q)$ is 84 80 approximated for 1d scattering. Thus the scattering pattern for 2D may not … … 86 82 model computation. 87 83 88 .. figure:: img/ crystal_orientation.png84 .. figure:: img/bcc_angle_definition.png 89 85 90 86 Orientation of the crystal with respect to the scattering plane. 91 92 .. figure:: img/bcc_2d.jpg93 94 2D plot using the default values (w/200X200 pixels).*95 87 96 88 References -
sasmodels/models/be_polyelectrolyte.py
r0e86967 r2f0c07d 30 30 q = \sqrt{q_x^2 + q_y^2} 31 31 32 33 .. figure:: img/be_polyelectrolyte_1d.jpg34 35 1D plot using the default values (w/500 data point).36 32 37 33 NB: $1 barn = 10^{-24} cm^2$ -
sasmodels/models/broad_peak.py
rdcdf29d r2f0c07d 28 28 q = \sqrt{q_x^2 + q_y^2} 29 29 30 31 .. figure:: img/broad_peak_1d.jpg32 33 1D plot using the default values (w/200 data point).34 30 35 31 References -
sasmodels/models/capped_cylinder.py
r50e1e40 r2f0c07d 69 69 It is up to you to restrict this during analysis. 70 70 71 :num:`Figure #capped-cylinder-1d` shows the output produced by 72 a running the 1D capped cylinder model, using *qmin* = 0.001 |Ang^-1|, 73 *qmax* = 0.7 |Ang^-1| and the default values of the parameters. 71 The 2D scattering intensity is calculated similar to the 2D cylinder model. 74 72 75 .. _capped-cylinder-1d: 76 77 .. figure:: img/capped_cylinder_1d.jpg 78 79 1D plot using the default values (w/256 data point). 80 81 The 2D scattering intensity is calculated similar to the 2D cylinder model. 82 :num:`Figure #capped-cylinder-2d` shows the output for $\theta=45^\circ$ 83 and $\phi=0^\circ$ with default values for the other parameters. 84 85 .. _capped-cylinder-2d: 86 87 .. figure:: img/capped_cylinder_2d.jpg 88 89 2D plot (w/(256X265) data points). 90 91 .. figure:: img/orientation.jpg 73 .. figure:: img/cylinder_angle_definition.jpg 92 74 93 75 Definition of the angles for oriented 2D cylinders. 94 76 95 .. figure:: img/ orientation2.jpg77 .. figure:: img/cylinder_angle_projection.jpg 96 78 97 Examples of the angles for oriented ppagainst the detector plane.79 Examples of the angles for oriented 2D cylinders against the detector plane. 98 80 99 81 References -
sasmodels/models/core_shell_bicelle.py
re7678b2 r2f0c07d 4 4 ---------- 5 5 This model provides the form factor for a circular cylinder with a core-shell 6 scattering length density profile. 7 The form factor is normalized by theparticle volume.6 scattering length density profile. The form factor is normalized by the 7 particle volume. 8 8 9 9 .. _core-shell-bicelle-geometry: … … 21 21 use the c-library from NIST. 22 22 23 .. figure:: img/c ore_shell_bicelle_1d.jpg23 .. figure:: img/cylinder_angle_definition.jpg 24 24 25 1D plot using the default values (w/200 data point).25 Definition of the angles for the oriented core shell bicelle tmodel. 26 26 27 .. figure:: img/core_shell_bicelle_fig1.jpg 28 29 Definition of the angles for the oriented CoreShellBicelleModel. 30 31 .. figure:: img/core_shell_bicelle_fig2.jpg 27 .. figure:: img/cylinder_angle_projection.jpg 32 28 33 29 Examples of the angles for oriented pp against the detector plane. -
sasmodels/models/core_shell_cylinder.py
rf0aa7f8 r2f0c07d 67 67 Validation of our code was done by comparing the output of the 1D model to 68 68 the output of the software provided by the NIST (Kline, 2006). 69 :num:`Figure #core-shell-cylinder-1d` shows a comparison70 of the 1D output of our model and the output of the NIST software.71 72 .. _core-shell-cylinder-1d:73 74 .. figure:: img/core_shell_cylinder_1d.jpg75 76 Comparison of the SasView scattering intensity for a core-shell cylinder77 with the output of the NIST SANS analysis software. The parameters were78 set to: *scale* = 1.0 |Ang|, *radius* = 20 |Ang|, *thickness* = 10 |Ang|,79 *length* =400 |Ang|, *core_sld* =1e-6 |Ang^-2|, *shell_sld* = 4e-6 |Ang^-2|,80 *solvent_sld* = 1e-6 |Ang^-2|, and *background* = 0.01 |cm^-1|.81 69 82 70 Averaging over a distribution of orientation is done by evaluating the 83 71 equation above. Since we have no other software to compare the 84 implementation of the intensity for fully oriented cylinders, we can85 compare the result of averaging our 2D output using a uniform72 implementation of the intensity for fully oriented cylinders, we 73 compared the result of averaging our 2D output using a uniform 86 74 distribution $p(\theta,\phi) = 1.0$. 87 :num:`Figure #core-shell-cylinder-2d` shows the result88 of such a cross-check.89 90 .. _core-shell-cylinder-2d:91 92 .. figure:: img/core_shell_cylinder_2d.jpg93 94 Comparison of the intensity for uniformly distributed core-shell95 cylinders calculated from our 2D model and the intensity from the96 NIST SANS analysis software. The parameters used were: *scale* = 1.0,97 *radius* = 20 |Ang|, *thickness* = 10 |Ang|, *length* = 400 |Ang|,98 *core_sld* = 1e-6 |Ang^-2|, *shell_sld* = 4e-6 |Ang^-2|,99 *solvent_sld* = 1e-6 |Ang^-2|, and *background* = 0.0 |cm^-1|.100 75 101 76 2013/11/26 - Description reviewed by Heenan, R. -
sasmodels/models/core_shell_ellipsoid.py
r177c1a1 r2f0c07d 10 10 applied over all orientations for 1D. 11 11 12 .. figure:: img/core_shell_ellipsoid_ fig1.gif12 .. figure:: img/core_shell_ellipsoid_geometry.gif 13 13 14 14 The returned value is in units of $cm^{-1}$, on absolute scale. … … 36 36 To provide easy access to the orientation of the core-shell ellipsoid, 37 37 we define the axis of the solid ellipsoid using two angles $\theta$ and $\phi$. 38 These angles are defined on Figure 2 of the CylinderModel. 38 These angles are defined as for 39 :ref:`cylinder orientation <cylinder-angle-definition>`. 39 40 The contrast is defined as SLD(core) - SLD(shell) and SLD(shell) - SLD(solvent). 40 41 … … 48 49 and used as the effective radius for *S(Q)* when $P(Q) * S(Q)$ is applied. 49 50 50 .. figure:: img/core_shell_ellipsoid_1d.jpg 51 52 1D plot using the default values (w/200 data point). 53 54 .. figure:: img/core_shell_ellipsoid_fig2.jpg 51 .. figure:: img/core_shell_ellipsoid_angle_projection.jpg 55 52 56 53 The angles for oriented core_shell_ellipsoid. -
sasmodels/models/core_shell_ellipsoid_xt.py
r3882eeb r2f0c07d 10 10 ---------- 11 11 12 .. figure:: img/core_shell_ellipsoid_fig1.gif 13 12 .. figure:: img/core_shell_ellipsoid_geometry.gif 14 13 15 14 The geometric parameters of this model are -
sasmodels/models/core_shell_parallelepiped.py
r44bd2be r2f0c07d 22 22 *A* < *B* < *C*. 23 23 24 .. image:: img/core_shell_parallelepiped .jpg24 .. image:: img/core_shell_parallelepiped_geometry.jpg 25 25 26 26 There are rectangular "slabs" of thickness $t_A$ that add to the *A* dimension … … 72 72 To provide easy access to the orientation of the parallelepiped, we define the 73 73 axis of the cylinder using three angles |theta|, |phi| and |bigpsi|. 74 These angles are defined on Figure 2 of the :ref:`cylinder` model.74 (see :ref:`cylinder orientation <cylinder-angle-definition>`). 75 75 The angle |bigpsi| is the rotational angle around the *long_c* axis against the 76 76 *q* plane. For example, |bigpsi| = 0 when the *short_b* axis is parallel to the 77 77 *x*-axis of the detector. 78 78 79 .. figure:: img/parallelepiped_angle s_definition.jpg79 .. figure:: img/parallelepiped_angle_definition.jpg 80 80 81 81 Definition of the angles for oriented core-shell parallelepipeds. 82 82 83 .. figure:: img/parallelepiped_angle s_examples.jpg83 .. figure:: img/parallelepiped_angle_projection.jpg 84 84 85 85 Examples of the angles for oriented core-shell parallelepipeds against the -
sasmodels/models/cylinder.py
r50e1e40 r2f0c07d 31 31 To provide easy access to the orientation of the cylinder, we define the 32 32 axis of the cylinder using two angles $\theta$ and $\phi$. Those angles 33 are defined in :num:`figure #cylinder- orientation`.33 are defined in :num:`figure #cylinder-angle-definition`. 34 34 35 .. _cylinder- orientation:35 .. _cylinder-angle-definition: 36 36 37 .. figure:: img/ orientation.jpg37 .. figure:: img/cylinder_angle_definition.jpg 38 38 39 39 Definition of the angles for oriented cylinders. 40 40 41 .. figure:: img/ orientation2.jpg41 .. figure:: img/cylinder_angle_projection.jpg 42 42 43 43 Examples of the angles for oriented cylinders against the detector plane. -
sasmodels/models/ellipsoid.py
r431caae r2f0c07d 47 47 $S(q)$ when $P(q) \cdot S(q)$ is applied. 48 48 49 .. _ellipsoid-1d:50 51 .. figure:: img/ellipsoid_1d.jpg52 53 The output of the 1D scattering intensity function for randomly oriented54 ellipsoids given by the equation above.55 56 49 57 50 The $\theta$ and $\phi$ parameters are not used for the 1D output. … … 59 52 .. _ellipsoid-geometry: 60 53 61 .. figure:: img/ellipsoid_ geometry.jpg54 .. figure:: img/ellipsoid_angle_projection.jpg 62 55 63 56 The angles for oriented ellipsoid. -
sasmodels/models/elliptical_cylinder.py
rfa8011eb r2f0c07d 43 43 44 44 To provide easy access to the orientation of the elliptical cylinder, we define the axis of the cylinder using two 45 angles |theta|, |phi| and |bigpsi| . As for the case of the cylinder, the angles |theta| and |phi| are defined on46 Figure 2 of CylinderModel.The angle |bigpsi| is the rotational angle around its own long_c axis against the *q* plane.45 angles |theta|, |phi| and |bigpsi| (see :ref:`cylinder orientation <cylinder-angle-definition>`). 46 The angle |bigpsi| is the rotational angle around its own long_c axis against the *q* plane. 47 47 For example, |bigpsi| = 0 when the *r_minor* axis is parallel to the *x*\ -axis of the detector. 48 48 49 49 All angle parameters are valid and given only for 2D calculation; ie, an oriented system. 50 50 51 .. figure:: img/elliptical_cylinder_ geometry_2d.jpg51 .. figure:: img/elliptical_cylinder_angle_definition.jpg 52 52 53 53 Definition of angles for 2D 54 54 55 .. figure:: img/c ore_shell_bicelle_fig2.jpg55 .. figure:: img/cylinder_angle_projection.jpg 56 56 57 57 Examples of the angles for oriented elliptical cylinders against the detector plane. … … 60 60 and length values, and used as the effective radius for *S(Q)* when *P(Q)* \* *S(Q)* is applied. 61 61 62 63 .. figure:: img/elliptical_cylinder_comparison_1d.jpg64 65 1D plot using the default values (w/1000 data point).66 62 67 63 Validation -
sasmodels/models/fcc.py
rad90df9 r2f0c07d 43 43 where $g$ is a fractional distortion based on the nearest neighbor distance. 44 44 45 .. figure:: img/fcc_ lattice.jpg45 .. figure:: img/fcc_geometry.jpg 46 46 47 47 Face-centered cubic lattice. … … 71 71 integral. Very, very slow. Go get lunch! 72 72 73 This example dataset is produced using 200 data points, *qmin* = 0.01 |Ang^-1|,74 *qmax* = 0.1 |Ang^-1| and the above default values.75 76 .. figure:: img/fcc_1d.jpg77 78 1D plot in the linear scale using the default values (w/200 data point).79 80 73 The 2D (Anisotropic model) is based on the reference below where $I(q)$ is 81 74 approximated for 1d scattering. Thus the scattering pattern for 2D may not … … 83 76 2D model computation. 84 77 85 .. figure:: img/ crystal_orientation.png78 .. figure:: img/bcc_angle_definition.png 86 79 87 80 Orientation of the crystal with respect to the scattering plane. 88 89 .. figure:: img/fcc_2d.jpg90 91 2D plot using the default values (w/200X200 pixels).92 81 93 82 References -
sasmodels/models/hardsphere.py
r97e6d3c r8e45182 35 35 from numpy import inf 36 36 37 name = "hardsphere _fish"38 title = "Hard sphere structure factor from FISH, with Percus-Yevick closure"37 name = "hardsphere" 38 title = "Hard sphere structure factor, with Percus-Yevick closure" 39 39 description = """\ 40 40 [Hard sphere structure factor, with Percus-Yevick closure] … … 48 48 """ 49 49 category = "structure-factor" 50 structure_factor = True 50 51 51 52 # ["name", "units", default, [lower, upper], "type","description"], -
sasmodels/models/hollow_cylinder.py
re0fd913 r2f0c07d 34 34 Bessel function. 35 35 36 To provide easy access to the orientation of the core-shell cylinder, we define37 the axis of the cylinder using two angles $\theta$ and $\phi$. As for the case38 of the cylinder, those angles are defined in Figure 2 of the CylinderModel.39 40 36 **NB**: The 2nd virial coefficient of the cylinder is calculated 41 37 based on the radius and 2 length values, and used as the effective radius … … 45 41 and the *radius* is $R_\text{shell}$ while *core_radius* is $R_\text{core}$. 46 42 47 .. figure:: img/hollow_cylinder_1d.jpg 48 49 1D plot using the default values (w/1000 data point). 50 51 .. figure:: img/orientation.jpg 52 53 Definition of the angles for the oriented hollow_cylinder model. 54 55 .. figure:: img/orientation2.jpg 56 57 Examples of the angles for oriented pp against the detector plane. 43 To provide easy access to the orientation of the core-shell cylinder, we define 44 the axis of the cylinder using two angles $\theta$ and $\phi$ 45 (see :ref:`cylinder model <cylinder-angle-definition>`). 58 46 59 47 References -
sasmodels/models/lamellar.py
reb69cce r348557a 99 99 oldname = 'LamellarModel' 100 100 oldpars = dict(sld='sld_bi', solvent_sld='sld_sol', thickness='bi_thick') 101 101 tests = [ 102 [ {'scale': 1.0, 'background' : 0.0, 'thickness' : 50.0, 'sld' : 1.0,'solvent_sld' : 6.3, 'thickness_pd' : 0.0, 103 }, [0.001], [882289.54309]] 104 ] 105 # ADDED by: converted by PAK? (or RKH?) ON: 16Mar2016 - RKH adding unit tests from sasview to early 2015 conversion 106 # [(qx1, qy1), (qx2, qy2), ...], [I(qx1,qy1), I(qx2,qy2), ...]], -
sasmodels/models/linear_pearls.py
r32c743d r2f0c07d 5 5 The thickness of each string is assumed to be negligible. 6 6 7 .. figure:: img/linear_pearls_ fig1.jpg7 .. figure:: img/linear_pearls_geometry.jpg 8 8 9 9 … … 25 25 The 2D scattering intensity is the same as P(q) above, 26 26 regardless of the orientation of the q vector. 27 28 .. figure:: img/linear_pearls_1d.jpg29 30 1D plot using the default values (w/500 data point).31 27 32 28 References -
sasmodels/models/mono_gauss_coil.py
r38d2c97 r38d2c97 6 6 7 7 r""" 8 This model strictly describes the scattering from *monodisperse* polymer chains in theta solvents or polymer melts, conditions under which the distances between segments follow a Gaussian distribution. Provided the number of segments is large (ie, high molecular weight polymers) the single-chain Form Factor P(Q) is that described by Debye (1947).8 This model strictly describes the scattering from *monodisperse* polymer chains in theta solvents or polymer melts, conditions under which the distances between segments follow a Gaussian distribution. Provided the number of segments is large (ie, high molecular weight polymers) the single-chain form factor P(Q) is that described by Debye (1947). 9 9 10 10 To describe the scattering from *polydisperse* polymer chains, see the poly_gauss_coil model. … … 13 13 ---------- 14 14 15 *I(q)* = *scale* x*P(q)* + *background*15 *I(q)* = *scale* |cdot| *P(q)* + *background* 16 16 17 17 where 18 18 19 *scale* = |phi|\ :sub:`poly` x *V* x (|rho|\ :sub:`poly` - |rho|\ :sub:`solv`)\ :sup:'2'19 *scale* = |phi|\ :sub:`poly` |cdot| *V* |cdot| (|rho|\ :sub:`poly` - |rho|\ :sub:`solv`)\ :sup:`2` 20 20 21 *P(q)* = 2 [exp(-Z) + Z - 1] / Z \ :sup:'2'21 *P(q)* = 2 [exp(-Z) + Z - 1] / Z \ :sup:`2` 22 22 23 *Z* = (*q R* \ :sub:'g')\ :sup:'2'23 *Z* = (*q R* \ :sub:`g`)\ :sup:`2` 24 24 25 25 and 26 26 27 *V* = *M* / (*N*\ :sub: 'A'|delta|)27 *V* = *M* / (*N*\ :sub:`A` |delta|) 28 28 29 Here, |phi|\ :sub:`poly` , is the volume fraction of polymer, *V* is the volume of a polymer coil, *M* is the molecular weight of the polymer, *N*\ :sub:'A' is Avogadro's Number, |delta| is the bulk density of the polymer, |rho|\ :sub:`poly` is the sld of the polymer, |rho|\ :sub:`solv` is the sld of the solvent, and *R*\ :sub:'g'is the radius of gyration of the polymer coil.29 Here, |phi|\ :sub:`poly` is the volume fraction of polymer, *V* is the volume of a polymer coil, *M* is the molecular weight of the polymer, *N*\ :sub:`A` is Avogadro's Number, |delta| is the bulk density of the polymer, |rho|\ :sub:`poly` is the sld of the polymer, |rho|\ :sub:`solv` is the sld of the solvent, and *R*\ :sub:`g` is the radius of gyration of the polymer coil. 30 30 31 31 .. figure:: img/mono_gauss_coil_1d.jpg -
sasmodels/models/multi_shell.py
rd51ea74 r2f0c07d 19 19 parameters fixed as possible. 20 20 21 .. figure:: img/multi_shell_ fig1.jpg21 .. figure:: img/multi_shell_geometry.jpg 22 22 23 23 The 2D scattering intensity is the same as 1D, regardless of the orientation … … 33 33 is used as the effective radius for *S(Q)* when $P(Q) * S(Q)$ is applied. 34 34 35 36 .. figure:: img/multi_shell_1d.jpg37 38 1D plot using the default values (with 200 data point).39 35 40 36 Our model uses the form factor calculations implemented in a c-library provided -
sasmodels/models/parallelepiped.py
rdeb7ee0 r2f0c07d 99 99 .. _parallelepiped-orientation: 100 100 101 .. figure:: img/parallelepiped_angle s_definition.jpg101 .. figure:: img/parallelepiped_angle_definition.jpg 102 102 103 103 Definition of the angles for oriented parallelepipeds. 104 104 105 .. figure:: img/parallelepiped_angle s_examples.jpg105 .. figure:: img/parallelepiped_angle_projection.jpg 106 106 107 107 Examples of the angles for oriented parallelepipeds against the detector plane. … … 156 156 This model is based on form factor calculations implemented in a c-library 157 157 provided by the NIST Center for Neutron Research (Kline, 2006). 158 159 158 """ 160 159 -
sasmodels/models/pearl_necklace.py
rd18582e r2f0c07d 6 6 (= *A* - 2\ *R*)). *A* is the center-to-center pearl separation distance. 7 7 8 .. figure:: img/pearl_ fig.jpg8 .. figure:: img/pearl_necklace_geometry.jpg 9 9 10 10 Pearl Necklace schematic … … 48 48 NB: *number_of_pearls* must be an integer. 49 49 50 .. figure:: img/pearl_plot.jpg 51 52 1D plot using the default values (w/1000 data point). 53 54 REFERENCE 50 References 51 ---------- 55 52 56 53 R Schweins and K Huber, *Particle Scattering Factor of Pearl Necklace Chains*, -
sasmodels/models/sc_crystal.py
rad90df9 r2f0c07d 41 41 The simple cubic lattice is 42 42 43 .. figure:: img/sc_crystal_ fig1.jpg43 .. figure:: img/sc_crystal_geometry.jpg 44 44 45 45 For a crystal, diffraction peaks appear at reduced q-values given by … … 77 77 Go get lunch! 78 78 79 This example dataset is produced using 200 data points,80 $q_{min} = 0.01A^{-1}, q_{max} = 0.1A^{-1}$ and the above default values.81 82 .. figure:: img/sc_crystal_1d.jpg83 84 1D plot in the linear scale using the default values (w/200 data point).85 86 79 The 2D (Anisotropic model) is based on the reference below where *I(q)* is 87 80 approximated for 1d scattering. Thus the scattering pattern for 2D may not … … 89 82 model computation. 90 83 91 .. figure:: img/sc_crystal_fig2.jpg 92 .. figure:: img/sc_crystal_fig3.jpg 93 94 2D plot using the default values (w/200X200 pixels). 84 .. figure:: img/sc_crystal_angle_definition.jpg 95 85 96 86 Reference -
sasmodels/models/stacked_disks.py
rd507c3a r2f0c07d 21 21 ---------- 22 22 23 .. figure:: img/stacked_disks_ fig1.gif23 .. figure:: img/stacked_disks_geometry.gif 24 24 25 25 The scattered intensity $I(q)$ is calculated as … … 68 68 and $\sigma_D$ = the Gaussian standard deviation of the d-spacing (sigma_d). 69 69 70 To provide easy access to the orientation of the stacked disks, we define71 the axis of the cylinder using two angles $\theta$ and $\varphi$.72 These angles are defined on Figure 2 of cylinder_model.73 74 70 .. note:: 75 71 The 2nd virial coefficient of the cylinder is calculated based on the … … 78 74 is applied. 79 75 80 .. figure:: img/stacked_disks_1d.jpg 81 82 1D plot using the default values (w/1000 data point). 83 84 .. figure:: img/stacked_disks_fig2.jpg 76 To provide easy access to the orientation of the stacked disks, we define 77 the axis of the cylinder using two angles $\theta$ and $\varphi$. 78 79 .. figure:: img/stacked_disks_angle_definition.jpg 85 80 86 81 Examples of the angles for oriented stacked disks against 87 82 the detector plane. 88 83 89 .. figure:: img/stacked_disks_ fig3.jpg84 .. figure:: img/stacked_disks_angle_projection.jpg 90 85 91 86 Examples of the angles for oriented pp against the detector plane. -
sasmodels/models/stickyhardsphere.py
r13ed84c r8e45182 84 84 """ 85 85 category = "structure-factor" 86 structure_factor = True 86 87 87 88 single = False … … 122 123 //C SOLVE QUADRATIC FOR LAMBDA 123 124 //C 124 qa = eta/ 12.0;125 qb = -1.0*(stickiness + eta/etam1);125 qa = eta/6.0; 126 qb = stickiness + eta/etam1; 126 127 qc = (1.0 + eta/2.0)/etam1sq; 127 radic = qb*qb - 4.0*qa*qc;128 radic = qb*qb - 2.0*qa*qc; 128 129 if(radic<0) { 129 130 //if(x>0.01 && x<0.015) … … 133 134 } 134 135 //C KEEP THE SMALLER ROOT, THE LARGER ONE IS UNPHYSICAL 135 lam = (-1.0*qb-sqrt(radic))/(2.0*qa); 136 lam2 = (-1.0*qb+sqrt(radic))/(2.0*qa); 136 radic = sqrt(radic); 137 lam = (qb-radic)/qa; 138 lam2 = (qb+radic)/qa; 137 139 if(lam2<lam) { 138 140 lam = lam2; … … 186 188 tests = [ 187 189 [ {'scale': 1.0, 'background' : 0.0, 'effect_radius' : 50.0, 'perturb' : 0.05, 'stickiness' : 0.2, 'volfraction' : 0.1, 188 'effect_radius_pd' : 0}, [0.001 ], [1.09718]]190 'effect_radius_pd' : 0}, [0.001, 0.003], [1.09718, 1.087830]] 189 191 ] 190 192 -
sasmodels/models/triaxial_ellipsoid.py
r469e763 r2f0c07d 43 43 .. _triaxial-ellipsoid-angles: 44 44 45 .. figure:: img/triaxial_ellipsoid_angle s.jpg45 .. figure:: img/triaxial_ellipsoid_angle_projection.jpg 46 46 47 47 The angles for oriented ellipsoid. … … 57 57 radius $R_e = \sqrt{R_a R_b}$, and used as the effective radius for 58 58 $S(q)$ when $P(q) \cdot S(q)$ is applied. 59 60 .. figure:: img/triaxial_ellipsoid_1d.jpg61 62 1D plot using the default values (w/1000 data point).63 59 64 60 Validation -
sasmodels/resolution.py
r5925e90 r17bbadd 1061 1061 else: 1062 1062 pars = {} 1063 defn = core.load_model_definition(name)1064 model = core. load_model(defn)1063 model_info = core.load_model_info(name) 1064 model = core.build_model(model_info) 1065 1065 1066 1066 kernel = core.make_kernel(model, [resolution.q_calc]) -
sasmodels/sasview_model.py
reafc9fa r28da77d 22 22 from . import core 23 23 24 def make_class(model_ definition, dtype='single', namestyle='name'):24 def make_class(model_info, dtype='single', namestyle='name'): 25 25 """ 26 26 Load the sasview model defined in *kernel_module*. … … 32 32 compatible with SasView. 33 33 """ 34 model = core. load_model(model_definition, dtype=dtype)34 model = core.build_model(model_info, dtype=dtype) 35 35 def __init__(self, multfactor=1): 36 36 SasviewModel.__init__(self, model) … … 287 287 pd_pars = [self._get_weights(p) for p in fn.pd_pars] 288 288 result = fn(pars, pd_pars, self.cutoff) 289 fn. input.release()289 fn.q_input.release() 290 290 fn.release() 291 291 return result … … 373 373 self.params[par], limits[par], par in relative) 374 374 return value, weight / np.sum(weight) 375
Note: See TracChangeset
for help on using the changeset viewer.