Changes in / [4e96703:e2da671] in sasmodels
- Files:
-
- 6 added
- 6 deleted
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
README.rst
re30d645 r2a64722 10 10 is available. 11 11 12 Example 12 Install 13 13 ------- 14 15 The easiest way to use sasmodels is from `SasView <http://www.sasview.org/>`_. 16 17 You can also install sasmodels as a standalone package in python. Use 18 `miniconda <https://docs.conda.io/en/latest/miniconda.html>`_ 19 or `anaconda <https://www.anaconda.com/>`_ 20 to create a python environment with the sasmodels dependencies:: 21 22 $ conda create -n sasmodels -c conda-forge numpy scipy matplotlib pyopencl 23 24 The option ``-n sasmodels`` names the environment sasmodels, and the option 25 ``-c conda-forge`` selects the conda-forge package channel because pyopencl 26 is not part of the base anaconda distribution. 27 28 Activate the environment and install sasmodels:: 29 30 $ conda activate sasmodels 31 (sasmodels) $ pip install sasmodels 32 33 Install `bumps <https://github.com/bumps/bumps>`_ if you want to use it to fit 34 your data:: 35 36 (sasmodels) $ pip install bumps 37 38 Usage 39 ----- 40 41 Check that the works:: 42 43 (sasmodels) $ python -m sasmodels.compare cylinder 44 45 To show the orientation explorer:: 46 47 (sasmodels) $ python -m sasmodels.jitter 48 49 Documentation is available online as part of the SasView 50 `fitting perspective <http://www.sasview.org/docs/index.html>`_ 51 as well as separate pages for 52 `individual models <http://www.sasview.org/docs/user/sasgui/perspectives/fitting/models/index.html>`_. 53 Programming details for sasmodels are available in the 54 `developer documentation <http://www.sasview.org/docs/dev/dev.html>`_. 55 56 57 Fitting Example 58 --------------- 14 59 15 60 The example directory contains a radial+tangential data set for an oriented 16 61 rod-like shape. 17 62 18 The data is loaded by sas.dataloader from the sasview package, so sasview 19 is needed to run the example. 63 To load the example data, you will need the SAS data loader from the sasview 64 package. This is not yet available on PyPI, so you will need a copy of the 65 SasView source code to run it. Create a directory somewhere to hold the 66 sasview and sasmodels source code, which we will refer to as $SOURCE. 20 67 21 To run the example, you need sasview, sasmodels and bumps. Assuming these 22 repositories are installed side by side, change to the sasmodels/example 23 directory and enter:: 68 Use the following to install sasview, and the sasmodels examples:: 24 69 25 PYTHONPATH=..:../../sasview/src ../../bumps/run.py fit.py \ 26 cylinder --preview 70 (sasmodels) $ cd $SOURCE 71 (sasmodels) $ conda install git 72 (sasmodels) $ git clone https://github.com/sasview/sasview.git 73 (sasmodels) $ git clone https://github.com/sasview/sasmodels.git 27 74 28 See bumps documentation for instructions on running the fit. With the 29 python packages installed, e.g., into a virtual environment, then the 30 python path need not be set, and the command would be:: 75 Set the path to the sasview source on your python path within the sasmodels 76 environment. On Windows, this will be:: 31 77 32 bumps fit.py cylinder --preview 78 (sasmodels)> set PYTHONPATH="$SOURCE\sasview\src" 79 (sasmodels)> cd $SOURCE/sasmodels/example 80 (sasmodels)> python -m bumps.cli fit.py cylinder --preview 81 82 On Mac/Linux with the standard shell this will be:: 83 84 (sasmodels) $ export PYTHONPATH="$SOURCE/sasview/src" 85 (sasmodels) $ cd $SOURCE/sasmodels/example 86 (sasmodels) $ bumps fit.py cylinder --preview 33 87 34 88 The fit.py model accepts up to two arguments. The first argument is the … … 38 92 both radial and tangential simultaneously, use the word "both". 39 93 40 Notes 41 ----- 42 43 cylinder.c + cylinder.py is the cylinder model with renamed variables and 44 sld scaled by 1e6 so the numbers are nicer. The model name is "cylinder" 45 46 lamellar.py is an example of a single file model with embedded C code. 94 See `bumps documentation <https://bumps.readthedocs.io/>`_ for detailed 95 instructions on running the fit. 47 96 48 97 |TravisStatus|_ -
doc/guide/plugin.rst
r81751c2 r94bfa42 272 272 structure factor to account for interactions between particles. See 273 273 `Form_Factors`_ for more details. 274 275 **model_info = ...** lets you define a model directly, for example, by 276 loading and modifying existing models. This is done implicitly by 277 :func:`sasmodels.core.load_model_info`, which can create a mixture model 278 from a pair of existing models. For example:: 279 280 from sasmodels.core import load_model_info 281 model_info = load_model_info('sphere+cylinder') 282 283 See :class:`sasmodels.modelinfo.ModelInfo` for details about the model 284 attributes that are defined. 274 285 275 286 Model Parameters … … 894 905 - \frac{\sin(x)}{x}\left(\frac{1}{x} - \frac{3!}{x^3} + \frac{5!}{x^5} - \frac{7!}{x^7}\right) 895 906 896 For small arguments 907 For small arguments, 897 908 898 909 .. math:: -
example/multiscatfit.py
r49d1f8b8 r2c4a190 15 15 16 16 # Show the model without fitting 17 PYTHONPATH=..:../ explore:../../bumps:../../sasview/src python multiscatfit.py17 PYTHONPATH=..:../../bumps:../../sasview/src python multiscatfit.py 18 18 19 19 # Run the fit 20 PYTHONPATH=..:../ explore:../../bumps:../../sasview/src ../../bumps/run.py \20 PYTHONPATH=..:../../bumps:../../sasview/src ../../bumps/run.py \ 21 21 multiscatfit.py --store=/tmp/t1 22 22 … … 55 55 ) 56 56 57 # Tie the model to the data 58 M = Experiment(data=data, model=model) 59 60 # Stack mulitple scattering on top of the existing resolution function. 61 M.resolution = MultipleScattering(resolution=M.resolution, probability=0.) 62 57 63 # SET THE FITTING PARAMETERS 58 64 model.radius_polar.range(15, 3000) … … 65 71 model.scale.range(0, 0.1) 66 72 67 # Mulitple scattering probability parameter 68 # HACK: the probability is stuffed in as an extra parameter to the experiment. 69 probability = Parameter(name="probability", value=0.0) 70 probability.range(0.0, 0.9) 73 # The multiple scattering probability parameter is in the resolution function 74 # instead of the scattering function, so access it through M.resolution 75 M.scattering_probability.range(0.0, 0.9) 71 76 72 M = Experiment(data=data, model=model, extra_pars={'probability': probability}) 73 74 # Stack mulitple scattering on top of the existing resolution function. 75 # Because resolution functions in sasview don't have fitting parameters, 76 # we instead allow the multiple scattering calculator to take a function 77 # instead of a probability. This function returns the current value of 78 # the parameter. ** THIS IS TEMPORARY ** when multiple scattering is 79 # properly integrated into sasmodels and sasview, its fittable parameter 80 # will be treated like the model parameters. 81 M.resolution = MultipleScattering(resolution=M.resolution, 82 probability=lambda: probability.value, 83 ) 84 M._kernel_inputs = M.resolution.q_calc 77 # Let bumps know that we are fitting this experiment 85 78 problem = FitProblem(M) 86 79 -
explore/beta/sasfit_compare.py
r2a12351b r119073a 505 505 } 506 506 507 Q, IQ = load_sasfit(data_file(' richard_test.txt'))508 Q, IQSD = load_sasfit(data_file(' richard_test2.txt'))509 Q, IQBD = load_sasfit(data_file(' richard_test3.txt'))507 Q, IQ = load_sasfit(data_file('sasfit_sphere_schulz_IQD.txt')) 508 Q, IQSD = load_sasfit(data_file('sasfit_sphere_schulz_IQSD.txt')) 509 Q, IQBD = load_sasfit(data_file('sasfit_sphere_schulz_IQBD.txt')) 510 510 target = Theory(Q=Q, F1=None, F2=None, P=IQ, S=None, I=IQSD, Seff=None, Ibeta=IQBD) 511 511 actual = sphere_r(Q, norm="sasfit", **pars) … … 526 526 } 527 527 528 Q, IQ = load_sasfit(data_file(' richard_test4.txt'))529 Q, IQSD = load_sasfit(data_file(' richard_test5.txt'))530 Q, IQBD = load_sasfit(data_file(' richard_test6.txt'))528 Q, IQ = load_sasfit(data_file('sasfit_ellipsoid_shulz_IQD.txt')) 529 Q, IQSD = load_sasfit(data_file('sasfit_ellipsoid_shulz_IQSD.txt')) 530 Q, IQBD = load_sasfit(data_file('sasfit_ellipsoid_shulz_IQBD.txt')) 531 531 target = Theory(Q=Q, F1=None, F2=None, P=IQ, S=None, I=IQSD, Seff=None, Ibeta=IQBD) 532 532 actual = ellipsoid_pe(Q, norm="sasfit", **pars) -
explore/precision.py
rfba9ca0 rcd28947 207 207 return model_info 208 208 209 # Hack to allow second parameter A in two parameter functions 209 # Hack to allow second parameter A in the gammainc and gammaincc functions. 210 # Create a 2-D variant of the precision test if we need to handle other two 211 # parameter functions. 210 212 A = 1 211 213 def parse_extra_pars(): 214 """ 215 Parse the command line looking for the second parameter "A=..." for the 216 gammainc/gammaincc functions. 217 """ 212 218 global A 213 219 … … 333 339 ) 334 340 add_function( 341 # Note: "a" is given as A=... on the command line via parse_extra_pars 335 342 name="gammainc(x)", 336 343 mp_function=lambda x, a=A: mp.gammainc(a, a=0, b=x)/mp.gamma(a), … … 339 346 ) 340 347 add_function( 348 # Note: "a" is given as A=... on the command line via parse_extra_pars 341 349 name="gammaincc(x)", 342 350 mp_function=lambda x, a=A: mp.gammainc(a, a=x, b=mp.inf)/mp.gamma(a), -
sasmodels/__init__.py
ra1ec908 r37f38ff 14 14 defining new models. 15 15 """ 16 __version__ = "0.9 8"16 __version__ = "0.99" 17 17 18 18 def data_files(): -
sasmodels/bumps_model.py
r49d1f8b8 r2c4a190 35 35 # when bumps is not on the path. 36 36 from bumps.names import Parameter # type: ignore 37 from bumps.parameter import Reference # type: ignore 37 38 except ImportError: 38 39 pass … … 139 140 def __init__(self, data, model, cutoff=1e-5, name=None, extra_pars=None): 140 141 # type: (Data, Model, float) -> None 142 # Allow resolution function to define fittable parameters. We do this 143 # by creating reference parameters within the resolution object rather 144 # than modifying the object itself to use bumps parameters. We need 145 # to reset the parameters each time the object has changed. These 146 # additional parameters need to be returned from the fitting engine. 147 # To make them available to the user, they are added as top-level 148 # attributes to the experiment object. The only change to the 149 # resolution function is that it needs an optional 'fittable' attribute 150 # which maps the internal name to the user visible name for the 151 # for the parameter. 152 self._resolution = None 153 self._resolution_pars = {} 141 154 # remember inputs so we can inspect from outside 142 155 self.name = data.filename if name is None else name … … 145 158 self._interpret_data(data, model.sasmodel) 146 159 self._cache = {} 160 # CRUFT: no longer need extra parameters 161 # Multiple scattering probability is now retrieved directly from the 162 # multiple scattering resolution function. 147 163 self.extra_pars = extra_pars 148 164 … … 162 178 return len(self.Iq) 163 179 180 @property 181 def resolution(self): 182 return self._resolution 183 184 @resolution.setter 185 def resolution(self, value): 186 self._resolution = value 187 188 # Remove old resolution fitting parameters from experiment 189 for name in self._resolution_pars: 190 delattr(self, name) 191 192 # Create new resolution fitting parameters 193 res_pars = getattr(self._resolution, 'fittable', {}) 194 self._resolution_pars = { 195 name: Reference(self._resolution, refname, name=name) 196 for refname, name in res_pars.items() 197 } 198 199 # Add new resolution fitting parameters as experiment attributes 200 for name, ref in self._resolution_pars.items(): 201 setattr(self, name, ref) 202 164 203 def parameters(self): 165 204 # type: () -> Dict[str, Parameter] … … 168 207 """ 169 208 pars = self.model.parameters() 170 if self.extra_pars :209 if self.extra_pars is not None: 171 210 pars.update(self.extra_pars) 211 pars.update(self._resolution_pars) 172 212 return pars 173 213 -
sasmodels/compare.py
r4de14584 r4de14584 1153 1153 'rel_err' : True, 1154 1154 'explore' : False, 1155 'use_demo' : True,1155 'use_demo' : False, 1156 1156 'zero' : False, 1157 1157 'html' : False, -
sasmodels/direct_model.py
r5024a56 r2c4a190 224 224 else: 225 225 Iq, dIq = None, None 226 #self._theory = np.zeros_like(q)227 q_vectors = [res.q_calc]228 226 elif self.data_type == 'Iqxy': 229 227 #if not model.info.parameters.has_2d: … … 242 240 res = resolution2d.Pinhole2D(data=data, index=index, 243 241 nsigma=3.0, accuracy=accuracy) 244 #self._theory = np.zeros_like(self.Iq)245 q_vectors = res.q_calc246 242 elif self.data_type == 'Iq': 247 243 index = (data.x >= data.qmin) & (data.x <= data.qmax) … … 268 264 else: 269 265 res = resolution.Perfect1D(data.x[index]) 270 271 #self._theory = np.zeros_like(self.Iq)272 q_vectors = [res.q_calc]273 266 elif self.data_type == 'Iq-oriented': 274 267 index = (data.x >= data.qmin) & (data.x <= data.qmax) … … 286 279 qx_width=data.dxw[index], 287 280 qy_width=data.dxl[index]) 288 q_vectors = res.q_calc289 281 else: 290 282 raise ValueError("Unknown data type") # never gets here … … 292 284 # Remember function inputs so we can delay loading the function and 293 285 # so we can save/restore state 294 self._kernel_inputs = q_vectors295 286 self._kernel = None 296 287 self.Iq, self.dIq, self.index = Iq, dIq, index … … 329 320 # type: (ParameterSet, float) -> np.ndarray 330 321 if self._kernel is None: 331 self._kernel = self._model.make_kernel(self._kernel_inputs) 322 # TODO: change interfaces so that resolution returns kernel inputs 323 # Maybe have resolution always return a tuple, or maybe have 324 # make_kernel accept either an ndarray or a pair of ndarrays. 325 kernel_inputs = self.resolution.q_calc 326 if isinstance(kernel_inputs, np.ndarray): 327 kernel_inputs = (kernel_inputs,) 328 self._kernel = self._model.make_kernel(kernel_inputs) 332 329 333 330 # Need to pull background out of resolution for multiple scattering 334 background = pars.get('background', DEFAULT_BACKGROUND) 331 default_background = self._model.info.parameters.common_parameters[1].default 332 background = pars.get('background', default_background) 335 333 pars = pars.copy() 336 334 pars['background'] = 0. -
sasmodels/generate.py
r39a06c9 rcd28947 703 703 """ 704 704 for code in source: 705 m = _FQ_PATTERN.search(code) 706 if m is not None: 705 if _FQ_PATTERN.search(code) is not None: 707 706 return True 708 707 return False … … 712 711 # type: (List[str]) -> bool 713 712 """ 714 Return True if C source defines " void Fq(".713 Return True if C source defines "double shell_volume(". 715 714 """ 716 715 for code in source: 717 m = _SHELL_VOLUME_PATTERN.search(code) 718 if m is not None: 716 if _SHELL_VOLUME_PATTERN.search(code) is not None: 719 717 return True 720 718 return False … … 1008 1006 pars = model_info.parameters.kernel_parameters 1009 1007 else: 1010 pars = model_info.parameters.COMMON + model_info.parameters.kernel_parameters 1008 pars = (model_info.parameters.common_parameters 1009 + model_info.parameters.kernel_parameters) 1011 1010 partable = make_partable(pars) 1012 1011 subst = dict(id=model_info.id.replace('_', '-'), -
sasmodels/jitter.py
r1198f90 r7d97437 15 15 pass 16 16 17 import matplotlib as mpl 17 18 import matplotlib.pyplot as plt 18 19 from matplotlib.widgets import Slider … … 746 747 pass 747 748 748 axcolor = 'lightgoldenrodyellow' 749 # CRUFT: use axisbg instead of facecolor for matplotlib<2 750 facecolor_prop = 'facecolor' if mpl.__version__ > '2' else 'axisbg' 751 props = {facecolor_prop: 'lightgoldenrodyellow'} 749 752 750 753 ## add control widgets to plot 751 axes_theta = plt.axes([0.1, 0.15, 0.45, 0.04], axisbg=axcolor)752 axes_phi = plt.axes([0.1, 0.1, 0.45, 0.04], axisbg=axcolor)753 axes_psi = plt.axes([0.1, 0.05, 0.45, 0.04], axisbg=axcolor)754 axes_theta = plt.axes([0.1, 0.15, 0.45, 0.04], **props) 755 axes_phi = plt.axes([0.1, 0.1, 0.45, 0.04], **props) 756 axes_psi = plt.axes([0.1, 0.05, 0.45, 0.04], **props) 754 757 stheta = Slider(axes_theta, 'Theta', -90, 90, valinit=theta) 755 758 sphi = Slider(axes_phi, 'Phi', -180, 180, valinit=phi) 756 759 spsi = Slider(axes_psi, 'Psi', -180, 180, valinit=psi) 757 760 758 axes_dtheta = plt.axes([0.75, 0.15, 0.15, 0.04], axisbg=axcolor)759 axes_dphi = plt.axes([0.75, 0.1, 0.15, 0.04], axisbg=axcolor)760 axes_dpsi = plt.axes([0.75, 0.05, 0.15, 0.04], axisbg=axcolor)761 axes_dtheta = plt.axes([0.75, 0.15, 0.15, 0.04], **props) 762 axes_dphi = plt.axes([0.75, 0.1, 0.15, 0.04], **props) 763 axes_dpsi = plt.axes([0.75, 0.05, 0.15, 0.04], **props) 761 764 # Note: using ridiculous definition of rectangle distribution, whose width 762 765 # in sasmodels is sqrt(3) times the given width. Divide by sqrt(3) to keep -
sasmodels/kernel.py
re44432d rcd28947 133 133 nout = 2 if self.info.have_Fq and self.dim == '1d' else 1 134 134 total_weight = self.result[nout*self.q_input.nq + 0] 135 # Note: total_weight = sum(weight > cutoff), with cutoff >= 0, so it 136 # is okay to test directly against zero. If weight is zero then I(q), 137 # etc. must also be zero. 135 138 if total_weight == 0.: 136 139 total_weight = 1. -
sasmodels/kernelcl.py
rf872fd1 rf872fd1 58 58 import time 59 59 60 try: 61 from time import perf_counter as clock 62 except ImportError: # CRUFT: python < 3.3 63 import sys 64 if sys.platform.count("darwin") > 0: 65 from time import time as clock 66 else: 67 from time import clock 68 60 69 import numpy as np # type: ignore 61 62 70 63 71 # Attempt to setup opencl. This may fail if the pyopencl package is not … … 611 619 #Call kernel and retrieve results 612 620 wait_for = None 613 last_nap = time.clock()621 last_nap = clock() 614 622 step = 1000000//self.q_input.nq + 1 615 623 for start in range(0, call_details.num_eval, step): … … 622 630 # Allow other processes to run 623 631 wait_for[0].wait() 624 current_time = time.clock()632 current_time = clock() 625 633 if current_time - last_nap > 0.5: 626 634 time.sleep(0.001) -
sasmodels/modelinfo.py
r39a06c9 r39a06c9 404 404 parameters counted as n individual parameters p1, p2, ... 405 405 406 * *common_parameters* is the list of common parameters, with a unique 407 copy for each model so that structure factors can have a default 408 background of 0.0. 409 406 410 * *call_parameters* is the complete list of parameters to the kernel, 407 411 including scale and background, with vector parameters recorded as … … 416 420 parameters don't use vector notation, and instead use p1, p2, ... 417 421 """ 418 # scale and background are implicit parameters419 COMMON = [Parameter(*p) for p in COMMON_PARAMETERS]420 421 422 def __init__(self, parameters): 422 423 # type: (List[Parameter]) -> None 424 425 # scale and background are implicit parameters 426 # Need them to be unique to each model in case they have different 427 # properties, such as default=0.0 for structure factor backgrounds. 428 self.common_parameters = [Parameter(*p) for p in COMMON_PARAMETERS] 429 423 430 self.kernel_parameters = parameters 424 431 self._set_vector_lengths() … … 468 475 if p.polydisperse and p.type not in ('orientation', 'magnetic')) 469 476 self.pd_2d = set(p.name for p in self.call_parameters if p.polydisperse) 477 478 def set_zero_background(self): 479 """ 480 Set the default background to zero for this model. This is done for 481 structure factor models. 482 """ 483 # type: () -> None 484 # Make sure background is the second common parameter. 485 assert self.common_parameters[1].id == "background" 486 self.common_parameters[1].default = 0.0 487 self.defaults = self._get_defaults() 470 488 471 489 def check_angles(self): … … 567 585 def _get_call_parameters(self): 568 586 # type: () -> List[Parameter] 569 full_list = self. COMMON[:]587 full_list = self.common_parameters[:] 570 588 for p in self.kernel_parameters: 571 589 if p.length == 1: … … 670 688 671 689 # Gather the user parameters in order 672 result = control + self. COMMON690 result = control + self.common_parameters 673 691 for p in self.kernel_parameters: 674 692 if not is2d and p.type in ('orientation', 'magnetic'): … … 770 788 771 789 info = ModelInfo() 790 791 # Build the parameter table 772 792 #print("make parameter table", kernel_module.parameters) 773 793 parameters = make_parameter_table(getattr(kernel_module, 'parameters', [])) 794 795 # background defaults to zero for structure factor models 796 structure_factor = getattr(kernel_module, 'structure_factor', False) 797 if structure_factor: 798 parameters.set_zero_background() 799 800 # TODO: remove demo parameters 801 # The plots in the docs are generated from the model default values. 802 # Sascomp set parameters from the command line, and so doesn't need 803 # demo values for testing. 774 804 demo = expand_pars(parameters, getattr(kernel_module, 'demo', None)) 805 775 806 filename = abspath(kernel_module.__file__).replace('.pyc', '.py') 776 807 kernel_id = splitext(basename(filename))[0] -
sasmodels/models/hardsphere.py
r304c775 r304c775 162 162 return pars 163 163 164 demo = dict(radius_effective=200, volfraction=0.2,165 radius_effective_pd=0.1, radius_effective_pd_n=40)166 164 # Q=0.001 is in the Taylor series, low Q part, so add Q=0.1, 167 165 # assuming double precision sasview is correct -
sasmodels/models/pearl_necklace.c
r99658f6 r9b5fd42 40 40 const double si = sas_sinx_x(q*A_s); 41 41 const double omsi = 1.0 - si; 42 const double pow_si = pow (si, num_pearls);42 const double pow_si = pown(si, num_pearls); 43 43 44 44 // form factor for num_pearls … … 81 81 radius_from_volume(double radius, double edge_sep, double thick_string, double fp_num_pearls) 82 82 { 83 const int num_pearls = (int) fp_num_pearls +0.5;84 83 const double vol_tot = form_volume(radius, edge_sep, thick_string, fp_num_pearls); 85 84 return cbrt(vol_tot/M_4PI_3); -
sasmodels/multiscat.py
rb3703f5 r2c4a190 342 342 343 343 *probability* is related to the expected number of scattering 344 events in the sample $\lambda$ as $p = 1 = e^{-\lambda}$. As a 345 hack to allow probability to be a fitted parameter, the "value" 346 can be a function that takes no parameters and returns the current 347 value of the probability. *coverage* determines how many scattering 348 steps to consider. The default is 0.99, which sets $n$ such that 349 $1 \ldots n$ covers 99% of the Poisson probability mass function. 344 events in the sample $\lambda$ as $p = 1 - e^{-\lambda}$. 345 *coverage* determines how many scattering steps to consider. The 346 default is 0.99, which sets $n$ such that $1 \ldots n$ covers 99% 347 of the Poisson probability mass function. 350 348 351 349 *is2d* is True then 2D scattering is used, otherwise it accepts … … 399 397 self.qmin = qmin 400 398 self.nq = nq 401 self.probability = probability399 self.probability = 0. if probability is None else probability 402 400 self.coverage = coverage 403 401 self.is2d = is2d … … 456 454 self.Iqxy = None # type: np.ndarray 457 455 456 # Label probability as a fittable parameter, and give its external name 457 # Note that the external name must be a valid python identifier, since 458 # is will be set as an experiment attribute. 459 self.fittable = {'probability': 'scattering_probability'} 460 458 461 def apply(self, theory): 459 462 if self.is2d: … … 463 466 Iq_calc = Iq_calc.reshape(self.nq, self.nq) 464 467 468 # CRUFT: don't need probability as a function anymore 465 469 probability = self.probability() if callable(self.probability) else self.probability 466 470 coverage = self.coverage -
sasmodels/resolution.py
r9e7837a re2592f0 445 445 q = np.sort(q) 446 446 if q_min + 2*MINIMUM_RESOLUTION < q[0]: 447 n_low = np.ceil((q[0]-q_min) / (q[1]-q[0])) if q[1] > q[0] else 15447 n_low = int(np.ceil((q[0]-q_min) / (q[1]-q[0]))) if q[1] > q[0] else 15 448 448 q_low = np.linspace(q_min, q[0], n_low+1)[:-1] 449 449 else: 450 450 q_low = [] 451 451 if q_max - 2*MINIMUM_RESOLUTION > q[-1]: 452 n_high = np.ceil((q_max-q[-1]) / (q[-1]-q[-2])) if q[-1] > q[-2] else 15452 n_high = int(np.ceil((q_max-q[-1]) / (q[-1]-q[-2]))) if q[-1] > q[-2] else 15 453 453 q_high = np.linspace(q[-1], q_max, n_high+1)[1:] 454 454 else: … … 499 499 q_min = q[0]*MINIMUM_ABSOLUTE_Q 500 500 n_low = log_delta_q * (log(q[0])-log(q_min)) 501 q_low = np.logspace(log10(q_min), log10(q[0]), np.ceil(n_low)+1)[:-1]501 q_low = np.logspace(log10(q_min), log10(q[0]), int(np.ceil(n_low))+1)[:-1] 502 502 else: 503 503 q_low = [] 504 504 if q_max > q[-1]: 505 505 n_high = log_delta_q * (log(q_max)-log(q[-1])) 506 q_high = np.logspace(log10(q[-1]), log10(q_max), np.ceil(n_high)+1)[1:]506 q_high = np.logspace(log10(q[-1]), log10(q_max), int(np.ceil(n_high))+1)[1:] 507 507 else: 508 508 q_high = [] -
sasmodels/sasview_model.py
r5024a56 r3a1afed 25 25 from . import core 26 26 from . import custom 27 from . import kernelcl 27 28 from . import product 28 29 from . import generate … … 30 31 from . import modelinfo 31 32 from .details import make_kernel_args, dispersion_mesh 33 from .kernelcl import reset_environment 32 34 33 35 # Hack: load in any custom distributions … … 73 75 #: has changed since we last reloaded. 74 76 _CACHED_MODULE = {} # type: Dict[str, "module"] 77 78 def reset_environment(): 79 # type: () -> None 80 """ 81 Clear the compute engine context so that the GUI can change devices. 82 83 This removes all compiled kernels, even those that are active on fit 84 pages, but they will be restored the next time they are needed. 85 """ 86 kernelcl.reset_environment() 87 for model in MODELS.values(): 88 model._model = None 75 89 76 90 def find_model(modelname): … … 387 401 hidden.add('scale') 388 402 hidden.add('background') 389 self._model_info.parameters.defaults['background'] = 0.390 403 391 404 # Update the parameter lists to exclude any hidden parameters … … 700 713 return self._calculate_Iq(qx, qy) 701 714 702 def _calculate_Iq(self, qx, qy=None , Fq=False, effective_radius_type=1):715 def _calculate_Iq(self, qx, qy=None): 703 716 if self._model is None: 704 self._model = core.build_model(self._model_info) 717 # Only need one copy of the compiled kernel regardless of how many 718 # times it is used, so store it in the class. Also, to reset the 719 # compute engine, need to clear out all existing compiled kernels, 720 # which is much easier to do if we store them in the class. 721 self.__class__._model = core.build_model(self._model_info) 705 722 if qy is not None: 706 723 q_vectors = [np.asarray(qx), np.asarray(qy)] … … 720 737 #print("values", values) 721 738 #print("is_mag", is_magnetic) 722 if Fq:723 result = calculator.Fq(call_details, values, cutoff=self.cutoff,724 magnetic=is_magnetic,725 effective_radius_type=effective_radius_type)726 739 result = calculator(call_details, values, cutoff=self.cutoff, 727 740 magnetic=is_magnetic) … … 741 754 Calculate the effective radius for P(q)*S(q) 742 755 756 *mode* is the R_eff type, which defaults to 1 to match the ER 757 calculation for sasview models from version 3.x. 758 743 759 :return: the value of the effective radius 744 760 """ 745 Fq = self._calculate_Iq([0.1], True, mode) 746 return Fq[2] 761 # ER and VR are only needed for old multiplication models, based on 762 # sas.sascalc.fit.MultiplicationModel. Fail for now. If we want to 763 # continue supporting them then add some test cases so that the code 764 # is exercised. We can access ER/VR using the kernel Fq function by 765 # extending _calculate_Iq so that it calls: 766 # if er_mode > 0: 767 # res = calculator.Fq(call_details, values, cutoff=self.cutoff, 768 # magnetic=False, effective_radius_type=mode) 769 # R_eff, form_shell_ratio = res[2], res[4] 770 # return R_eff, form_shell_ratio 771 # Then use the following in calculate_ER: 772 # ER, VR = self._calculate_Iq(q=[0.1], er_mode=mode) 773 # return ER 774 # Similarly, for calculate_VR: 775 # ER, VR = self._calculate_Iq(q=[0.1], er_mode=1) 776 # return VR 777 # Obviously a combined calculate_ER_VR method would be better, but 778 # we only need them to support very old models, so ignore the 2x 779 # performance hit. 780 raise NotImplementedError("ER function is no longer available.") 747 781 748 782 def calculate_VR(self): … … 753 787 :return: the value of the form:shell volume ratio 754 788 """ 755 Fq = self._calculate_Iq([0.1], True, mode)756 r eturn Fq[4]789 # See comments in calculate_ER. 790 raise NotImplementedError("VR function is no longer available.") 757 791 758 792 def set_dispersion(self, parameter, dispersion): … … 919 953 CylinderModel().evalDistribution([0.1, 0.1]) 920 954 955 def test_structure_factor_background(): 956 # type: () -> None 957 """ 958 Check that sasview model and direct model match, with background=0. 959 """ 960 from .data import empty_data1D 961 from .core import load_model_info, build_model 962 from .direct_model import DirectModel 963 964 model_name = "hardsphere" 965 q = [0.0] 966 967 sasview_model = _make_standard_model(model_name)() 968 sasview_value = sasview_model.evalDistribution(np.array(q))[0] 969 970 data = empty_data1D(q) 971 model_info = load_model_info(model_name) 972 model = build_model(model_info) 973 direct_model = DirectModel(data, model) 974 direct_value_zero_background = direct_model(background=0.0) 975 976 assert sasview_value == direct_value_zero_background 977 978 # Additionally check that direct value background defaults to zero 979 direct_value_default = direct_model() 980 assert sasview_value == direct_value_default 981 982 921 983 def magnetic_demo(): 922 984 Model = _make_standard_model('sphere') … … 939 1001 #print("rpa:", test_rpa()) 940 1002 #test_empty_distribution() 1003 #test_structure_factor_background() -
sasmodels/weights.py
rf41027b re2592f0 23 23 default = dict(npts=35, width=0, nsigmas=3) 24 24 def __init__(self, npts=None, width=None, nsigmas=None): 25 self.npts = self.default['npts'] if npts is None else npts25 self.npts = self.default['npts'] if npts is None else int(npts) 26 26 self.width = self.default['width'] if width is None else width 27 27 self.nsigmas = self.default['nsigmas'] if nsigmas is None else nsigmas
Note: See TracChangeset
for help on using the changeset viewer.