Changes in / [2c12061:01dba26] in sasmodels


Ignore:
Files:
5 added
4 edited

Legend:

Unmodified
Added
Removed
  • doc/guide/pd/polydispersity.rst

    rd089a00 rd089a00  
    3434Each distribution is characterized by a center value $\bar x$ or 
    3535$x_\text{med}$, a width parameter $\sigma$ (note this is *not necessarily* 
     36<<<<<<< HEAD 
     37the standard deviation, so read the description carefully), the number of 
     38sigmas $N_\sigma$ to include from the tails of the distribution, and the 
     39number of points used to compute the average. The center of the distribution 
     40is set by the value of the model parameter. The meaning of a polydispersity 
     41parameter *PD* (not to be confused with a molecular weight distributions 
     42in polymer science) in a model depends on the type of parameter it is being 
     43applied too. 
     44 
     45The distribution width applied to *volume* (ie, shape-describing) parameters 
     46is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$. 
     47However, the distribution width applied to *orientation* (ie, angle-describing) 
     48parameters is just $\sigma = \mathrm{PD}$. 
     49======= 
    3650the standard deviation, so read the description of the distribution carefully),  
    3751the number of sigmas $N_\sigma$ to include from the tails of the distribution,  
     
    4357However, the distribution width applied to *orientation* parameters is just  
    4458$\sigma = \mathrm{PD}$. 
     59>>>>>>> master 
    4560 
    4661$N_\sigma$ determines how far into the tails to evaluate the distribution, 
     
    6681*  *Schulz Distribution* 
    6782*  *Array Distribution* 
     83*  *User-defined Distributions* 
    6884 
    6985These are all implemented as *number-average* distributions. 
    7086 
    71 Additional distributions are under consideration. 
    7287 
    7388**Beware: when the Polydispersity & Orientational Distribution panel in SasView is** 
     
    92107or angular orientations, consider using the Gaussian or Boltzmann distributions. 
    93108 
    94 If applying polydispersion to parameters describing angles, use the Uniform  
    95 distribution. Beware of using distributions that are always positive (eg, the  
     109If applying polydispersion to parameters describing angles, use the Uniform 
     110distribution. Beware of using distributions that are always positive (eg, the 
    96111Lognormal) because angles can be negative! 
    97112 
    98 The array distribution allows a user-defined distribution to be applied. 
     113The array distribution provides a very simple means of implementing a user- 
     114defined distribution, but without any fittable parameters. Greater flexibility 
     115is conferred by the user-defined distribution.  
    99116 
    100117.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    334351.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    335352 
     353User-defined Distributions 
     354^^^^^^^^^^^^^^^^^^^^^^^^^^ 
     355 
     356You can also define your own distribution by creating a python file defining a 
     357*Distribution* object with a *_weights* method.  The *_weights* method takes 
     358*center*, *sigma*, *lb* and *ub* as arguments, and can access *self.npts* 
     359and *self.nsigmas* from the distribution.  They are interpreted as follows: 
     360 
     361* *center* the value of the shape parameter (for size dispersity) or zero 
     362  if it is an angular dispersity.  This parameter may be fitted. 
     363 
     364* *sigma* the width of the distribution, which is the polydispersity parameter 
     365  times the center for size dispersity, or the polydispersity parameter alone 
     366  for angular dispersity.  This parameter may be fitted. 
     367 
     368* *lb*, *ub* are the parameter limits (lower & upper bounds) given in the model 
     369  definition file.  For example, a radius parameter has *lb* equal to zero.  A 
     370  volume fraction parameter would have *lb* equal to zero and *ub* equal to one. 
     371 
     372* *self.nsigmas* the distance to go into the tails when evaluating the 
     373  distribution.  For a two parameter distribution, this value could be 
     374  co-opted to use for the second parameter, though it will not be available 
     375  for fitting. 
     376 
     377* *self.npts* the number of points to use when evaluating the distribution. 
     378  The user will adjust this to trade calculation time for accuracy, but the 
     379  distribution code is free to return more or fewer, or use it for the third 
     380  parameter in a three parameter distribution. 
     381 
     382As an example, the code following wraps the Laplace distribution from scipy stats:: 
     383 
     384    import numpy as np 
     385    from scipy.stats import laplace 
     386 
     387    from sasmodels import weights 
     388 
     389    class Dispersion(weights.Dispersion): 
     390        r""" 
     391        Laplace distribution 
     392 
     393        .. math:: 
     394 
     395            w(x) = e^{-\sigma |x - \mu|} 
     396        """ 
     397        type = "laplace" 
     398        default = dict(npts=35, width=0, nsigmas=3)  # default values 
     399        def _weights(self, center, sigma, lb, ub): 
     400            x = self._linspace(center, sigma, lb, ub) 
     401            wx = laplace.pdf(x, center, sigma) 
     402            return x, wx 
     403 
     404You can plot the weights for a given value and width using the following:: 
     405 
     406    from numpy import inf 
     407    from matplotlib import pyplot as plt 
     408    from sasmodels import weights 
     409 
     410    # reload the user-defined weights 
     411    weights.load_weights() 
     412    x, wx = weights.get_weights('laplace', n=35, width=0.1, nsigmas=3, value=50, 
     413                                limits=[0, inf], relative=True) 
     414 
     415    # plot the weights 
     416    plt.interactive(True) 
     417    plt.plot(x, wx, 'x') 
     418 
     419The *self.nsigmas* and *self.npts* parameters are normally used to control 
     420the accuracy of the distribution integral. The *self._linspace* function 
     421uses them to define the *x* values (along with the *center*, *sigma*, 
     422*lb*, and *ub* which are passed as parameters).  If you repurpose npts or 
     423nsigmas you will need to generate your own *x*.  Be sure to honour the 
     424limits *lb* and *ub*, for example to disallow a negative radius or constrain 
     425the volume fraction to lie between zero and one. 
     426 
     427To activate a user-defined distribution, put it in a file such as *distname.py* 
     428in the *SAS_WEIGHTS_PATH* folder.  This is defined with an environment 
     429variable, defaulting to:: 
     430 
     431    SAS_WEIGHTS_PATH=~/.sasview/weights 
     432 
     433The weights path is loaded on startup.  To update the distribution definition 
     434in a running application you will need to enter the following python commands:: 
     435 
     436    import sasmodels.weights 
     437    sasmodels.weights.load_weights('path/to/distname.py') 
     438 
     439.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     440 
    336441Note about DLS polydispersity 
    337442^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
  • sasmodels/compare.py

    rbd7630d rbd7630d  
    4141from . import kerneldll 
    4242from . import kernelcl 
     43from . import weights 
    4344from .data import plot_theory, empty_data1D, empty_data2D, load_data 
    4445from .direct_model import DirectModel, get_mesh 
    4546from .generate import FLOAT_RE, set_integration_size 
    46 from .weights import plot_weights 
    4747 
    4848# pylint: disable=unused-import 
     
    114114 
    115115    === environment variables === 
    116     -DSAS_MODELPATH=path sets directory containing custom models 
     116    -DSAS_MODELPATH=~/.sasmodels/custom_models sets path to custom models 
     117    -DSAS_WEIGHTS_PATH=~/.sasview/weights sets path to custom distributions 
    117118    -DSAS_OPENCL=vendor:device|none sets the target OpenCL device 
    118119    -DXDG_CACHE_HOME=~/.cache sets the pyopencl cache root (linux only) 
    119120    -DSAS_COMPILER=tinycc|msvc|mingw|unix sets the DLL compiler 
    120     -DSAS_OPENMP=1 turns on OpenMP for the DLLs 
    121     -DSAS_DLL_PATH=path sets the path to the compiled modules 
     121    -DSAS_OPENMP=0 set to 1 to turn on OpenMP for the DLLs 
     122    -DSAS_DLL_PATH=~/.sasmodels/compiled_models sets the DLL cache 
    122123 
    123124The interpretation of quad precision depends on architecture, and may 
     
    783784            model_info = base._kernel.info 
    784785            dim = base._kernel.dim 
    785             plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) 
     786            weights.plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) 
    786787        if opts['show_profile']: 
    787788            import pylab 
     
    14401441    #import pprint; pprint.pprint(model_info) 
    14411442 
     1443    # Hack to load user-defined distributions; run through all parameters 
     1444    # and make sure any pd_type parameter is a defined distribution. 
     1445    if (any(p.endswith('pd_type') and v not in weights.MODELS 
     1446            for p, v in pars.items()) or 
     1447        any(p.endswith('pd_type') and v not in weights.MODELS 
     1448            for p, v in pars2.items())): 
     1449       weights.load_weights() 
     1450 
    14421451    if opts['show_pars']: 
    14431452        if model_info.name != model_info2.name or pars != pars2: 
  • sasmodels/sasview_model.py

    rd533590 raa25fc7  
    3030from . import modelinfo 
    3131from .details import make_kernel_args, dispersion_mesh 
     32 
     33# Hack: load in any custom distributions 
     34# Uses ~/.sasview/weights/*.py unless SASMODELS_WEIGHTS is set in the environ. 
     35# Override with weights.load_weights(pattern="<weights_path>/*.py") 
     36weights.load_weights() 
    3237 
    3338# pylint: disable=unused-import 
  • sasmodels/weights.py

    r3d58247 rf41027b  
    231231)) 
    232232 
     233SAS_WEIGHTS_PATH = "~/.sasview/weights" 
     234def load_weights(pattern=None): 
     235    # type: (str) -> None 
     236    """ 
     237    Load dispersion distributions matching the given glob pattern 
     238    """ 
     239    import logging 
     240    import os 
     241    import os.path 
     242    import glob 
     243    import traceback 
     244    from .custom import load_custom_kernel_module 
     245    if pattern is None: 
     246        path = os.environ.get("SAS_WEIGHTS_PATH", SAS_WEIGHTS_PATH) 
     247        pattern = os.path.join(path, "*.py") 
     248    for filename in sorted(glob.glob(os.path.expanduser(pattern))): 
     249        try: 
     250            #print("loading weights from", filename) 
     251            module = load_custom_kernel_module(filename) 
     252            MODELS[module.Dispersion.type] = module.Dispersion 
     253        except Exception as exc: 
     254            logging.error(traceback.format_exc(exc)) 
    233255 
    234256def get_weights(disperser, n, width, nsigmas, value, limits, relative): 
Note: See TracChangeset for help on using the changeset viewer.