# Changeset c8c70d0 in sasmodels

Ignore:
Timestamp:
Sep 14, 2018 11:16:24 AM (8 days ago)
Parents:
2c12061 (diff), a5516b1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Paul Kienzle <pkienzle@…> (09/14/18 11:16:24)
git-committer:
Message:
Files:
4 edited

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

 rd089a00 -------------------------------------------- For some models we can calculate the average intensity for a population of particles that possess size and/or orientational (ie, angular) distributions. In SasView we call the former *polydispersity* but use the parameter *PD* to parameterise both. In other words, the meaning of *PD* in a model depends on For some models we can calculate the average intensity for a population of particles that possess size and/or orientational (ie, angular) distributions. In SasView we call the former *polydispersity* but use the parameter *PD* to parameterise both. In other words, the meaning of *PD* in a model depends on the actual parameter it is being applied too. The resultant intensity is then normalized by the average particle volume such The resultant intensity is then normalized by the average particle volume such that P(q) = \text{scale} \langle F^* F \rangle / V + \text{background} where $F$ is the scattering amplitude and $\langle\cdot\rangle$ denotes an where $F$ is the scattering amplitude and $\langle\cdot\rangle$ denotes an average over the distribution $f(x; \bar x, \sigma)$, giving .. math:: P(q) = \frac{\text{scale}}{V} \int_\mathbb{R} P(q) = \frac{\text{scale}}{V} \int_\mathbb{R} f(x; \bar x, \sigma) F^2(q, x)\, dx + \text{background} Each distribution is characterized by a center value $\bar x$ or $x_\text{med}$, a width parameter $\sigma$ (note this is *not necessarily* the standard deviation, so read the description of the distribution carefully), the number of sigmas $N_\sigma$ to include from the tails of the distribution, and the number of points used to compute the average. The center of the distribution is set by the value of the model parameter. The distribution width applied to *volume* (ie, shape-describing) parameters is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$. However, the distribution width applied to *orientation* parameters is just $\sigma = \mathrm{PD}$. the standard deviation, so read the description carefully), the number of sigmas $N_\sigma$ to include from the tails of the distribution, and the number of points used to compute the average. The center of the distribution is set by the value of the model parameter. The meaning of a polydispersity parameter *PD* (not to be confused with a molecular weight distributions in polymer science) in a model depends on the type of parameter it is being applied too. The distribution width applied to *volume* (ie, shape-describing) parameters is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$. However, the distribution width applied to *orientation* (ie, angle-describing) parameters is just $\sigma = \mathrm{PD}$. $N_\sigma$ determines how far into the tails to evaluate the distribution, Users should note that the averaging computation is very intensive. Applying polydispersion and/or orientational distributions to multiple parameters at the same time, or increasing the number of points in the distribution, will require patience! However, the calculations are generally more robust with polydispersion and/or orientational distributions to multiple parameters at the same time, or increasing the number of points in the distribution, will require patience! However, the calculations are generally more robust with more data points or more angles. *  *Schulz Distribution* *  *Array Distribution* *  *User-defined Distributions* These are all implemented as *number-average* distributions. Additional distributions are under consideration. **Beware: when the Polydispersity & Orientational Distribution panel in SasView is** **This may not be suitable. See Suggested Applications below.** .. note:: In 2009 IUPAC decided to introduce the new term 'dispersity' to replace the term 'polydispersity' (see Pure Appl. Chem., (2009), 81(2), 351-353 _ in order to make the terminology describing distributions of chemical properties unambiguous. However, these terms are unrelated to the proportional size distributions and orientational distributions used in .. note:: In 2009 IUPAC decided to introduce the new term 'dispersity' to replace the term 'polydispersity' (see Pure Appl. Chem., (2009), 81(2), 351-353 _ in order to make the terminology describing distributions of chemical properties unambiguous. However, these terms are unrelated to the proportional size distributions and orientational distributions used in SasView models. or angular orientations, consider using the Gaussian or Boltzmann distributions. If applying polydispersion to parameters describing angles, use the Uniform distribution. Beware of using distributions that are always positive (eg, the If applying polydispersion to parameters describing angles, use the Uniform distribution. Beware of using distributions that are always positive (eg, the Lognormal) because angles can be negative! The array distribution allows a user-defined distribution to be applied. The array distribution provides a very simple means of implementing a user- defined distribution, but without any fittable parameters. Greater flexibility is conferred by the user-defined distribution. .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ User-defined Distributions ^^^^^^^^^^^^^^^^^^^^^^^^^^ You can also define your own distribution by creating a python file defining a *Distribution* object with a *_weights* method.  The *_weights* method takes *center*, *sigma*, *lb* and *ub* as arguments, and can access *self.npts* and *self.nsigmas* from the distribution.  They are interpreted as follows: * *center* the value of the shape parameter (for size dispersity) or zero if it is an angular dispersity.  This parameter may be fitted. * *sigma* the width of the distribution, which is the polydispersity parameter times the center for size dispersity, or the polydispersity parameter alone for angular dispersity.  This parameter may be fitted. * *lb*, *ub* are the parameter limits (lower & upper bounds) given in the model definition file.  For example, a radius parameter has *lb* equal to zero.  A volume fraction parameter would have *lb* equal to zero and *ub* equal to one. * *self.nsigmas* the distance to go into the tails when evaluating the distribution.  For a two parameter distribution, this value could be co-opted to use for the second parameter, though it will not be available for fitting. * *self.npts* the number of points to use when evaluating the distribution. The user will adjust this to trade calculation time for accuracy, but the distribution code is free to return more or fewer, or use it for the third parameter in a three parameter distribution. As an example, the code following wraps the Laplace distribution from scipy stats:: import numpy as np from scipy.stats import laplace from sasmodels import weights class Dispersion(weights.Dispersion): r""" Laplace distribution .. math:: w(x) = e^{-\sigma |x - \mu|} """ type = "laplace" default = dict(npts=35, width=0, nsigmas=3)  # default values def _weights(self, center, sigma, lb, ub): x = self._linspace(center, sigma, lb, ub) wx = laplace.pdf(x, center, sigma) return x, wx You can plot the weights for a given value and width using the following:: from numpy import inf from matplotlib import pyplot as plt from sasmodels import weights # reload the user-defined weights weights.load_weights() x, wx = weights.get_weights('laplace', n=35, width=0.1, nsigmas=3, value=50, limits=[0, inf], relative=True) # plot the weights plt.interactive(True) plt.plot(x, wx, 'x') The *self.nsigmas* and *self.npts* parameters are normally used to control the accuracy of the distribution integral. The *self._linspace* function uses them to define the *x* values (along with the *center*, *sigma*, *lb*, and *ub* which are passed as parameters).  If you repurpose npts or nsigmas you will need to generate your own *x*.  Be sure to honour the limits *lb* and *ub*, for example to disallow a negative radius or constrain the volume fraction to lie between zero and one. To activate a user-defined distribution, put it in a file such as *distname.py* in the *SAS_WEIGHTS_PATH* folder.  This is defined with an environment variable, defaulting to:: SAS_WEIGHTS_PATH=~/.sasview/weights The weights path is loaded on startup.  To update the distribution definition in a running application you will need to enter the following python commands:: import sasmodels.weights sasmodels.weights.load_weights('path/to/distname.py') .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ Note about DLS polydispersity ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Several measures of polydispersity abound in Dynamic Light Scattering (DLS) and it should not be assumed that any of the following can be simply equated with Several measures of polydispersity abound in Dynamic Light Scattering (DLS) and it should not be assumed that any of the following can be simply equated with the polydispersity *PD* parameter used in SasView. The dimensionless **Polydispersity Index (PI)** is a measure of the width of the distribution of autocorrelation function decay rates (*not* the distribution of particle sizes itself, though the two are inversely related) and is defined by The dimensionless **Polydispersity Index (PI)** is a measure of the width of the distribution of autocorrelation function decay rates (*not* the distribution of particle sizes itself, though the two are inversely related) and is defined by ISO 22412:2017 as PI = \mu_{2} / \bar \Gamma^2 where $\mu_\text{2}$ is the second cumulant, and $\bar \Gamma^2$ is the where $\mu_\text{2}$ is the second cumulant, and $\bar \Gamma^2$ is the intensity-weighted average value, of the distribution of decay rates. PI = \sigma^2 / 2\bar \Gamma^2 where $\sigma$ is the standard deviation, allowing a **Relative Polydispersity (RP)** where $\sigma$ is the standard deviation, allowing a **Relative Polydispersity (RP)** to be defined as RP = \sigma / \bar \Gamma = \sqrt{2 \cdot PI} PI values smaller than 0.05 indicate a highly monodisperse system. Values PI values smaller than 0.05 indicate a highly monodisperse system. Values greater than 0.7 indicate significant polydispersity. The **size polydispersity P-parameter** is defined as the relative standard deviation coefficient of variation The **size polydispersity P-parameter** is defined as the relative standard deviation coefficient of variation .. math:: where $\nu$ is the variance of the distribution and $\bar R$ is the mean value of $R$. Here, the product $P \bar R$ is *equal* to the standard value of $R$. Here, the product $P \bar R$ is *equal* to the standard deviation of the Lognormal distribution.
• ## sasmodels/compare.py

 rbd7630d from . import kerneldll from . import kernelcl from . import weights from .data import plot_theory, empty_data1D, empty_data2D, load_data from .direct_model import DirectModel, get_mesh from .generate import FLOAT_RE, set_integration_size from .weights import plot_weights # pylint: disable=unused-import === environment variables === -DSAS_MODELPATH=path sets directory containing custom models -DSAS_MODELPATH=~/.sasmodels/custom_models sets path to custom models -DSAS_WEIGHTS_PATH=~/.sasview/weights sets path to custom distributions -DSAS_OPENCL=vendor:device|none sets the target OpenCL device -DXDG_CACHE_HOME=~/.cache sets the pyopencl cache root (linux only) -DSAS_COMPILER=tinycc|msvc|mingw|unix sets the DLL compiler -DSAS_OPENMP=1 turns on OpenMP for the DLLs -DSAS_DLL_PATH=path sets the path to the compiled modules -DSAS_OPENMP=0 set to 1 to turn on OpenMP for the DLLs -DSAS_DLL_PATH=~/.sasmodels/compiled_models sets the DLL cache The interpretation of quad precision depends on architecture, and may model_info = base._kernel.info dim = base._kernel.dim plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) weights.plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) if opts['show_profile']: import pylab #import pprint; pprint.pprint(model_info) # Hack to load user-defined distributions; run through all parameters # and make sure any pd_type parameter is a defined distribution. if (any(p.endswith('pd_type') and v not in weights.MODELS for p, v in pars.items()) or any(p.endswith('pd_type') and v not in weights.MODELS for p, v in pars2.items())): weights.load_weights() if opts['show_pars']: if model_info.name != model_info2.name or pars != pars2:
• ## sasmodels/sasview_model.py

 rd533590 from . import modelinfo from .details import make_kernel_args, dispersion_mesh # Hack: load in any custom distributions # Uses ~/.sasview/weights/*.py unless SASMODELS_WEIGHTS is set in the environ. # Override with weights.load_weights(pattern="/*.py") weights.load_weights() # pylint: disable=unused-import
• ## sasmodels/weights.py

 r3d58247 )) SAS_WEIGHTS_PATH = "~/.sasview/weights" def load_weights(pattern=None): # type: (str) -> None """ Load dispersion distributions matching the given glob pattern """ import logging import os import os.path import glob import traceback from .custom import load_custom_kernel_module if pattern is None: path = os.environ.get("SAS_WEIGHTS_PATH", SAS_WEIGHTS_PATH) pattern = os.path.join(path, "*.py") for filename in sorted(glob.glob(os.path.expanduser(pattern))): try: #print("loading weights from", filename) module = load_custom_kernel_module(filename) MODELS[module.Dispersion.type] = module.Dispersion except Exception as exc: logging.error(traceback.format_exc(exc)) def get_weights(disperser, n, width, nsigmas, value, limits, relative):
Note: See TracChangeset for help on using the changeset viewer.