Changes in / [4e96703:cf3d0ce] in sasmodels


Ignore:
Files:
5 deleted
4 edited

Legend:

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

    ra5cb9bc rd089a00  
    1111-------------------------------------------- 
    1212 
    13 For some models we can calculate the average intensity for a population of 
    14 particles that possess size and/or orientational (ie, angular) distributions. 
    15 In SasView we call the former *polydispersity* but use the parameter *PD* to 
    16 parameterise both. In other words, the meaning of *PD* in a model depends on 
     13For some models we can calculate the average intensity for a population of  
     14particles that possess size and/or orientational (ie, angular) distributions.  
     15In SasView we call the former *polydispersity* but use the parameter *PD* to  
     16parameterise both. In other words, the meaning of *PD* in a model depends on  
    1717the actual parameter it is being applied too. 
    1818 
    19 The resultant intensity is then normalized by the average particle volume such 
     19The resultant intensity is then normalized by the average particle volume such  
    2020that 
    2121 
     
    2424  P(q) = \text{scale} \langle F^* F \rangle / V + \text{background} 
    2525 
    26 where $F$ is the scattering amplitude and $\langle\cdot\rangle$ denotes an 
     26where $F$ is the scattering amplitude and $\langle\cdot\rangle$ denotes an  
    2727average over the distribution $f(x; \bar x, \sigma)$, giving 
    2828 
    2929.. math:: 
    3030 
    31   P(q) = \frac{\text{scale}}{V} \int_\mathbb{R} 
     31  P(q) = \frac{\text{scale}}{V} \int_\mathbb{R}  
    3232  f(x; \bar x, \sigma) F^2(q, x)\, dx + \text{background} 
    3333 
    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 the standard deviation, so read the description carefully), the number of 
    37 sigmas $N_\sigma$ to include from the tails of the distribution, and the 
    38 number of points used to compute the average. The center of the distribution 
    39 is set by the value of the model parameter. The meaning of a polydispersity 
    40 parameter *PD* (not to be confused with a molecular weight distributions 
    41 in polymer science) in a model depends on the type of parameter it is being 
    42 applied too. 
    43  
    44 The distribution width applied to *volume* (ie, shape-describing) parameters 
    45 is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$. 
    46 However, the distribution width applied to *orientation* (ie, angle-describing) 
    47 parameters is just $\sigma = \mathrm{PD}$. 
     36the standard deviation, so read the description of the distribution carefully),  
     37the number of sigmas $N_\sigma$ to include from the tails of the distribution,  
     38and the number of points used to compute the average. The center of the  
     39distribution is set by the value of the model parameter. 
     40 
     41The distribution width applied to *volume* (ie, shape-describing) parameters  
     42is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$.  
     43However, the distribution width applied to *orientation* parameters is just  
     44$\sigma = \mathrm{PD}$. 
    4845 
    4946$N_\sigma$ determines how far into the tails to evaluate the distribution, 
     
    5552 
    5653Users should note that the averaging computation is very intensive. Applying 
    57 polydispersion and/or orientational distributions to multiple parameters at 
    58 the same time, or increasing the number of points in the distribution, will 
    59 require patience! However, the calculations are generally more robust with 
     54polydispersion and/or orientational distributions to multiple parameters at  
     55the same time, or increasing the number of points in the distribution, will  
     56require patience! However, the calculations are generally more robust with  
    6057more data points or more angles. 
    6158 
     
    6966*  *Schulz Distribution* 
    7067*  *Array Distribution* 
    71 *  *User-defined Distributions* 
    7268 
    7369These are all implemented as *number-average* distributions. 
    7470 
     71Additional distributions are under consideration. 
    7572 
    7673**Beware: when the Polydispersity & Orientational Distribution panel in SasView is** 
     
    7875**This may not be suitable. See Suggested Applications below.** 
    7976 
    80 .. note:: In 2009 IUPAC decided to introduce the new term 'dispersity' to replace 
    81            the term 'polydispersity' (see `Pure Appl. Chem., (2009), 81(2), 
    82            351-353 <http://media.iupac.org/publications/pac/2009/pdf/8102x0351.pdf>`_ 
    83            in order to make the terminology describing distributions of chemical 
    84            properties unambiguous. However, these terms are unrelated to the 
    85            proportional size distributions and orientational distributions used in 
     77.. note:: In 2009 IUPAC decided to introduce the new term 'dispersity' to replace  
     78           the term 'polydispersity' (see `Pure Appl. Chem., (2009), 81(2),  
     79           351-353 <http://media.iupac.org/publications/pac/2009/pdf/8102x0351.pdf>`_  
     80           in order to make the terminology describing distributions of chemical  
     81           properties unambiguous. However, these terms are unrelated to the  
     82           proportional size distributions and orientational distributions used in  
    8683           SasView models. 
    8784 
     
    9592or angular orientations, consider using the Gaussian or Boltzmann distributions. 
    9693 
    97 If applying polydispersion to parameters describing angles, use the Uniform 
    98 distribution. Beware of using distributions that are always positive (eg, the 
     94If applying polydispersion to parameters describing angles, use the Uniform  
     95distribution. Beware of using distributions that are always positive (eg, the  
    9996Lognormal) because angles can be negative! 
    10097 
    101 The array distribution provides a very simple means of implementing a user- 
    102 defined distribution, but without any fittable parameters. Greater flexibility 
    103 is conferred by the user-defined distribution. 
     98The array distribution allows a user-defined distribution to be applied. 
    10499 
    105100.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    339334.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    340335 
    341 User-defined Distributions 
    342 ^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    343  
    344 You can also define your own distribution by creating a python file defining a 
    345 *Distribution* object with a *_weights* method.  The *_weights* method takes 
    346 *center*, *sigma*, *lb* and *ub* as arguments, and can access *self.npts* 
    347 and *self.nsigmas* from the distribution.  They are interpreted as follows: 
    348  
    349 * *center* the value of the shape parameter (for size dispersity) or zero 
    350   if it is an angular dispersity.  This parameter may be fitted. 
    351  
    352 * *sigma* the width of the distribution, which is the polydispersity parameter 
    353   times the center for size dispersity, or the polydispersity parameter alone 
    354   for angular dispersity.  This parameter may be fitted. 
    355  
    356 * *lb*, *ub* are the parameter limits (lower & upper bounds) given in the model 
    357   definition file.  For example, a radius parameter has *lb* equal to zero.  A 
    358   volume fraction parameter would have *lb* equal to zero and *ub* equal to one. 
    359  
    360 * *self.nsigmas* the distance to go into the tails when evaluating the 
    361   distribution.  For a two parameter distribution, this value could be 
    362   co-opted to use for the second parameter, though it will not be available 
    363   for fitting. 
    364  
    365 * *self.npts* the number of points to use when evaluating the distribution. 
    366   The user will adjust this to trade calculation time for accuracy, but the 
    367   distribution code is free to return more or fewer, or use it for the third 
    368   parameter in a three parameter distribution. 
    369  
    370 As an example, the code following wraps the Laplace distribution from scipy stats:: 
    371  
    372     import numpy as np 
    373     from scipy.stats import laplace 
    374  
    375     from sasmodels import weights 
    376  
    377     class Dispersion(weights.Dispersion): 
    378         r""" 
    379         Laplace distribution 
    380  
    381         .. math:: 
    382  
    383             w(x) = e^{-\sigma |x - \mu|} 
    384         """ 
    385         type = "laplace" 
    386         default = dict(npts=35, width=0, nsigmas=3)  # default values 
    387         def _weights(self, center, sigma, lb, ub): 
    388             x = self._linspace(center, sigma, lb, ub) 
    389             wx = laplace.pdf(x, center, sigma) 
    390             return x, wx 
    391  
    392 You can plot the weights for a given value and width using the following:: 
    393  
    394     from numpy import inf 
    395     from matplotlib import pyplot as plt 
    396     from sasmodels import weights 
    397  
    398     # reload the user-defined weights 
    399     weights.load_weights() 
    400     x, wx = weights.get_weights('laplace', n=35, width=0.1, nsigmas=3, value=50, 
    401                                 limits=[0, inf], relative=True) 
    402  
    403     # plot the weights 
    404     plt.interactive(True) 
    405     plt.plot(x, wx, 'x') 
    406  
    407 The *self.nsigmas* and *self.npts* parameters are normally used to control 
    408 the accuracy of the distribution integral. The *self._linspace* function 
    409 uses them to define the *x* values (along with the *center*, *sigma*, 
    410 *lb*, and *ub* which are passed as parameters).  If you repurpose npts or 
    411 nsigmas you will need to generate your own *x*.  Be sure to honour the 
    412 limits *lb* and *ub*, for example to disallow a negative radius or constrain 
    413 the volume fraction to lie between zero and one. 
    414  
    415 To activate a user-defined distribution, put it in a file such as *distname.py* 
    416 in the *SAS_WEIGHTS_PATH* folder.  This is defined with an environment 
    417 variable, defaulting to:: 
    418  
    419     SAS_WEIGHTS_PATH=~/.sasview/weights 
    420  
    421 The weights path is loaded on startup.  To update the distribution definition 
    422 in a running application you will need to enter the following python commands:: 
    423  
    424     import sasmodels.weights 
    425     sasmodels.weights.load_weights('path/to/distname.py') 
    426  
    427 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
    428  
    429336Note about DLS polydispersity 
    430337^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    431338 
    432 Several measures of polydispersity abound in Dynamic Light Scattering (DLS) and 
    433 it should not be assumed that any of the following can be simply equated with 
     339Several measures of polydispersity abound in Dynamic Light Scattering (DLS) and  
     340it should not be assumed that any of the following can be simply equated with  
    434341the polydispersity *PD* parameter used in SasView. 
    435342 
    436 The dimensionless **Polydispersity Index (PI)** is a measure of the width of the 
    437 distribution of autocorrelation function decay rates (*not* the distribution of 
    438 particle sizes itself, though the two are inversely related) and is defined by 
     343The dimensionless **Polydispersity Index (PI)** is a measure of the width of the  
     344distribution of autocorrelation function decay rates (*not* the distribution of  
     345particle sizes itself, though the two are inversely related) and is defined by  
    439346ISO 22412:2017 as 
    440347 
     
    443350    PI = \mu_{2} / \bar \Gamma^2 
    444351 
    445 where $\mu_\text{2}$ is the second cumulant, and $\bar \Gamma^2$ is the 
     352where $\mu_\text{2}$ is the second cumulant, and $\bar \Gamma^2$ is the  
    446353intensity-weighted average value, of the distribution of decay rates. 
    447354 
     
    452359    PI = \sigma^2 / 2\bar \Gamma^2 
    453360 
    454 where $\sigma$ is the standard deviation, allowing a **Relative Polydispersity (RP)** 
     361where $\sigma$ is the standard deviation, allowing a **Relative Polydispersity (RP)**  
    455362to be defined as 
    456363 
     
    459366    RP = \sigma / \bar \Gamma = \sqrt{2 \cdot PI} 
    460367 
    461 PI values smaller than 0.05 indicate a highly monodisperse system. Values 
     368PI values smaller than 0.05 indicate a highly monodisperse system. Values  
    462369greater than 0.7 indicate significant polydispersity. 
    463370 
    464 The **size polydispersity P-parameter** is defined as the relative standard 
    465 deviation coefficient of variation 
     371The **size polydispersity P-parameter** is defined as the relative standard  
     372deviation coefficient of variation   
    466373 
    467374.. math:: 
     
    470377 
    471378where $\nu$ is the variance of the distribution and $\bar R$ is the mean 
    472 value of $R$. Here, the product $P \bar R$ is *equal* to the standard 
     379value of $R$. Here, the product $P \bar R$ is *equal* to the standard  
    473380deviation of the Lognormal distribution. 
    474381 
  • sasmodels/compare.py

    r4de14584 r4de14584  
    3939 
    4040from . import core 
    41 from . import weights 
    4241from . import kerneldll 
    4342from . import kernelcl 
     
    4645from .direct_model import DirectModel, get_mesh 
    4746from .generate import FLOAT_RE, set_integration_size 
     47from .weights import plot_weights 
    4848 
    4949# pylint: disable=unused-import 
     
    115115 
    116116    === environment variables === 
    117     -DSAS_MODELPATH=~/.sasmodels/custom_models sets path to custom models 
    118     -DSAS_WEIGHTS_PATH=~/.sasview/weights sets path to custom distributions 
     117    -DSAS_MODELPATH=path sets directory containing custom models 
    119118    -DSAS_OPENCL=vendor:device|cuda:device|none sets the target GPU device 
    120119    -DXDG_CACHE_HOME=~/.cache sets the pyopencl cache root (linux only) 
    121120    -DSAS_COMPILER=tinycc|msvc|mingw|unix sets the DLL compiler 
    122     -DSAS_OPENMP=0 set to 1 to turn on OpenMP for the DLLs 
    123     -DSAS_DLL_PATH=~/.sasmodels/compiled_models sets the DLL cache 
     121    -DSAS_OPENMP=1 turns on OpenMP for the DLLs 
     122    -DSAS_DLL_PATH=path sets the path to the compiled modules 
    124123 
    125124The interpretation of quad precision depends on architecture, and may 
     
    726725        set_integration_size(model_info, ngauss) 
    727726 
    728     if (dtype != "default" and not dtype.endswith('!') 
     727    if (dtype != "default" and not dtype.endswith('!')  
    729728            and not (kernelcl.use_opencl() or kernelcuda.use_cuda())): 
    730729        raise RuntimeError("OpenCL not available " + kernelcl.OPENCL_ERROR) 
     
    785784            model_info = base._kernel.info 
    786785            dim = base._kernel.dim 
    787             weights.plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) 
     786            plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) 
    788787        if opts['show_profile']: 
    789788            import pylab 
     
    14421441    #import pprint; pprint.pprint(model_info) 
    14431442 
    1444     # Hack to load user-defined distributions; run through all parameters 
    1445     # and make sure any pd_type parameter is a defined distribution. 
    1446     if (any(p.endswith('pd_type') and v not in weights.MODELS 
    1447             for p, v in pars.items()) or 
    1448         any(p.endswith('pd_type') and v not in weights.MODELS 
    1449             for p, v in pars2.items())): 
    1450        weights.load_weights() 
    1451  
    14521443    if opts['show_pars']: 
    14531444        if model_info.name != model_info2.name or pars != pars2: 
  • sasmodels/sasview_model.py

    r5024a56 r5024a56  
    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") 
    36 weights.load_weights() 
    3732 
    3833# pylint: disable=unused-import 
  • sasmodels/weights.py

    rf41027b r3d58247  
    231231)) 
    232232 
    233 SAS_WEIGHTS_PATH = "~/.sasview/weights" 
    234 def 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)) 
    255233 
    256234def get_weights(disperser, n, width, nsigmas, value, limits, relative): 
Note: See TracChangeset for help on using the changeset viewer.