Changeset aa25fc7 in sasmodels

May 23, 2018 5:55:27 PM (3 months ago)
Paul Kienzle <pkienzle@…>

load user-defined weight functions from ~/.sasview/weights/*.py

4 edited


  • doc/guide/pd/polydispersity.rst

    r29afc50 raa25fc7  
    2828sigmas $N_\sigma$ to include from the tails of the distribution, and the 
    2929number of points used to compute the average. The center of the distribution 
    30 is set by the value of the model parameter. The meaning of a polydispersity  
    31 parameter *PD* (not to be confused with a molecular weight distributions  
    32 in polymer science) in a model depends on the type of parameter it is being  
     30is set by the value of the model parameter. The meaning of a polydispersity 
     31parameter *PD* (not to be confused with a molecular weight distributions 
     32in polymer science) in a model depends on the type of parameter it is being 
    3333applied too. 
    35 The distribution width applied to *volume* (ie, shape-describing) parameters  
    36 is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$.  
    37 However, the distribution width applied to *orientation* (ie, angle-describing)  
     35The distribution width applied to *volume* (ie, shape-describing) parameters 
     36is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$. 
     37However, the distribution width applied to *orientation* (ie, angle-describing) 
    3838parameters is just $\sigma = \mathrm{PD}$. 
    7373or angular orientations, use the Gaussian or Boltzmann distributions. 
    75 If applying polydispersion to parameters describing angles, use the Uniform  
    76 distribution. Beware of using distributions that are always positive (eg, the  
     75If applying polydispersion to parameters describing angles, use the Uniform 
     76distribution. Beware of using distributions that are always positive (eg, the 
    7777Lognormal) because angles can be negative! 
     317User-defined Distributions 
     320You can define your own distribution by creating a python file defining a 
     321*Distribution* object.  The distribution is parameterized by *center* 
     322(which is always zero for orientation dispersity, or parameter value for 
     323size dispersity), *sigma* (which is the distribution width in degrees for 
     324orientation parameters, or center times width for size dispersity), and 
     325bounds *lb* and *ub* (which are the bounds on the possible values of the 
     326parameter given in the model definition). 
     328For example, the following wraps the Laplace distribution from scipy stats:: 
     330    import numpy as np 
     331    from scipy.stats import laplace 
     333    from sasmodels import weights 
     335    class Dispersion(weights.Dispersion): 
     336        r""" 
     337        Laplace distribution 
     339        .. math:: 
     341            w(x) = e^{-\sigma |x - \mu|} 
     342        """ 
     343        type = "laplace" 
     344        default = dict(npts=35, width=0, nsigmas=3)  # default values 
     345        def _weights(self, center, sigma, lb, ub): 
     346            x = self._linspace(center, sigma, lb, ub) 
     347            wx = laplace.pdf(x, center, sigma) 
     348            return x, wx 
     350To see that the distribution is correct use the following:: 
     352    from numpy import inf 
     353    from matplotlib import pyplot as plt 
     354    from sasmodels import weights 
     356    # reload the user-defined weights 
     357    weights.load_weights() 
     358    x, wx = weights.get_weights('laplace', n=35, width=0.1, nsigmas=3, value=50, 
     359                                limits=[0, inf], relative=True) 
     361    # plot the weights 
     362    plt.interactive(True) 
     363    plt.plot(x, wx, 'x') 
     365Any python code can be used to define the distribution.  The distribution 
     366parameters are available as *self.npts*, *self.width* and *self.nsigmas*. 
     367Try to follow the convention of gaussian width, npts and number of sigmas 
     368in the tail, but if your distribution requires more parameters you are free 
     369to interpret them as something else.  In particular, npts allows you to 
     370trade accuracy against running time when evaluating your models.  The 
     371*self._linspace* function uses *self.npts* and *self.nsigmas* to define 
     372the set of *x* values to use for the distribution (along with the *center*, 
     373*sigma*, *lb*, and *ub* passed as parameters).  You can use an arbitrary 
     374set of *x* points. 
    317378Note about DLS polydispersity 
  • sasmodels/

    r1fbadb2 raa25fc7  
    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 
    4848# pylint: disable=unused-import 
    771771            model_info = 
    772772            dim = base._kernel.dim 
    773             plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) 
     773            weights.plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) 
    774774    if opts['plot']: 
    775775        import matplotlib.pyplot as plt 
    13531353    #import pprint; pprint.pprint(model_info) 
     1355    # Hack to load user-defined distributions; run through all parameters 
     1356    # and make sure any pd_type parameter is a defined distribution. 
     1357    if (any(p.endswith('pd_type') and v not in weights.MODELS 
     1358            for p, v in pars.items()) or 
     1359        any(p.endswith('pd_type') and v not in weights.MODELS 
     1360            for p, v in pars2.items())): 
     1361       weights.load_weights() 
    13551363    if opts['show_pars']: 
    13561364        if != or pars != pars2: 
  • sasmodels/

    rd533590 raa25fc7  
    3030from . import modelinfo 
    3131from .details import make_kernel_args, dispersion_mesh 
     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") 
    3338# pylint: disable=unused-import 
  • sasmodels/

    r3d58247 raa25fc7  
     233SASMODELS_WEIGHTS = "~/.sasview/weights/*.py" 
     234def load_weights(pattern=None): 
     235    # type: (str) -> None 
     236    """ 
     237    Load dispersion distributions matching the given 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        pattern = os.environ.get("SASMODELS_WEIGHTS", SASMODELS_WEIGHTS) 
     247    for filename in sorted(glob.glob(os.path.expanduser(pattern))): 
     248        try: 
     249            print("loading weights from", filename) 
     250            module = load_custom_kernel_module(filename) 
     251            MODELS[module.Dispersion.type] = module.Dispersion 
     252        except Exception as exc: 
     253            logging.error(traceback.format_exc(exc)) 
    234255def get_weights(disperser, n, width, nsigmas, value, limits, relative): 
Note: See TracChangeset for help on using the changeset viewer.