# Changeset 315ac3a in sasmodels

Ignore:
Timestamp:
Sep 25, 2018 9:52:23 AM (4 weeks ago)
Branches:
ticket-1102-pinhole
Parents:
184f205 (diff), 2015f02 (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.
Message:

Merge branch 'master' into ticket-1102-pinhole

Files:
1 deleted
36 edited

Unmodified
Removed
• ## .travis.yml

 r335271e env: - PY=2.7 - DEPLOY=True #- DEPLOY=True - os: linux env:
• ## doc/guide/gpu_setup.rst

 r59485a4 the compiler. On Windows, set *SASCOMPILER=tinycc* for the tinycc compiler, *SASCOMPILER=msvc* for the Microsoft Visual C compiler, or *SASCOMPILER=mingw* for the MinGW compiler. If TinyCC is available On Windows, set *SAS_COMPILER=tinycc* for the tinycc compiler, *SAS_COMPILER=msvc* for the Microsoft Visual C compiler, or *SAS_COMPILER=mingw* for the MinGW compiler. If TinyCC is available on the python path (it is provided with SasView), that will be the default. If you want one of the other compilers, be sure to have it
• ## doc/guide/magnetism/magnetism.rst

 r4f5afc9 .. math:: -- &= ((1-u_i)(1-u_f))^{1/4} \\ -+ &= ((1-u_i)(u_f))^{1/4} \\ +- &= ((u_i)(1-u_f))^{1/4} \\ ++ &= ((u_i)(u_f))^{1/4} -- &= (1-u_i)(1-u_f) \\ -+ &= (1-u_i)(u_f) \\ +- &= (u_i)(1-u_f) \\ ++ &= (u_i)(u_f) Ideally the experiment would measure the pure spin states independently and | 2015-05-02 Steve King | 2017-11-15 Paul Kienzle | 2018-06-02 Adam Washington
• ## doc/guide/pd/polydispersity.rst

 r29afc50 .. _polydispersityhelp: Polydispersity Distributions ---------------------------- With some models in sasmodels we can calculate the average intensity for a population of particles that exhibit size and/or orientational polydispersity. The resultant intensity is normalized by the average particle volume such that Polydispersity & Orientational Distributions -------------------------------------------- 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 that .. math:: P(q) = \text{scale} \langle F^* F \rangle / V + \text{background} where $F$ is the scattering amplitude and $\langle\cdot\rangle$ denotes an average over the size distribution. 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} 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 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 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* (ie, angle-describing) parameters is just $\sigma = \mathrm{PD}$. However, the distribution width applied to *orientation* parameters is just $\sigma = \mathrm{PD}$. $N_\sigma$ determines how far into the tails to evaluate the distribution, with larger values of $N_\sigma$ required for heavier tailed distributions. The scattering in general falls rapidly with $qr$ so the usual assumption that $G(r - 3\sigma_r)$ is tiny and therefore $f(r - 3\sigma_r)G(r - 3\sigma_r)$ that $f(r - 3\sigma_r)$ is tiny and therefore $f(r - 3\sigma_r)f(r - 3\sigma_r)$ will not contribute much to the average may not hold when particles are large. This, too, will require increasing $N_\sigma$. Users should note that the averaging computation is very intensive. Applying polydispersion 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. 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. The following distribution functions are provided: Additional distributions are under consideration. **Beware: when the Polydispersity & Orientational Distribution panel in SasView is** **first opened, the default distribution for all parameters is the Gaussian Distribution.** **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 SasView models. Suggested Applications ^^^^^^^^^^^^^^^^^^^^^^ If applying polydispersion to parameters describing particle sizes, use If applying polydispersion to parameters describing particle sizes, consider using the Lognormal or Schulz distributions. If applying polydispersion to parameters describing interfacial thicknesses or angular orientations, use the Gaussian or Boltzmann distributions. or angular orientations, consider using the Gaussian or Boltzmann distributions. If applying polydispersion to parameters describing angles, use the Uniform ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Many commercial Dynamic Light Scattering (DLS) instruments produce a size polydispersity parameter, sometimes even given the symbol $p$\ ! This parameter is defined as the relative standard deviation coefficient of variation of the size distribution and is NOT the same as the polydispersity parameters in the Lognormal and Schulz distributions above (though they all related) except when the DLS polydispersity parameter is <0.13. .. math:: p_{DLS} = \sqrt(\nu / \bar x^2) where $\nu$ is the variance of the distribution and $\bar x$ is the mean value of $x$. 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 ISO 22412:2017 as .. math:: PI = \mu_{2} / \bar \Gamma^2 where $\mu_\text{2}$ is the second cumulant, and $\bar \Gamma^2$ is the intensity-weighted average value, of the distribution of decay rates. *If the distribution of decay rates is Gaussian* then .. math:: PI = \sigma^2 / 2\bar \Gamma^2 where $\sigma$ is the standard deviation, allowing a **Relative Polydispersity (RP)** to be defined as .. math:: RP = \sigma / \bar \Gamma = \sqrt{2 \cdot PI} 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 .. math:: P = \sqrt\nu / \bar R 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 deviation of the Lognormal distribution. P values smaller than 0.13 indicate a monodisperse system. For more information see: S King, C Washington & R Heenan, *Phys Chem Chem Phys*, (2005), 7, 143 ISO 22412:2017, International Standards Organisation (2017) _. Polydispersity: What does it mean for DLS and Chromatography _. Dynamic Light Scattering: Common Terms Defined, Whitepaper WP111214. Malvern Instruments (2011) _. S King, C Washington & R Heenan, *Phys Chem Chem Phys*, (2005), 7, 143. T Allen, in *Particle Size Measurement*, 4th Edition, Chapman & Hall, London (1990). .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ | 2018-03-20 Steve King | 2018-04-04 Steve King | 2018-08-09 Steve King
• ## doc/guide/plugin.rst

 r7e6bc45e calculations, but instead rely on numerical integration to compute the appropriately smeared pattern. Each .py file also contains a function:: def random(): ... This function provides a model-specific random parameter set which shows model features in the USANS to SANS range.  For example, core-shell sphere sets the outer radius of the sphere logarithmically in [20, 20,000], which sets the Q value for the transition from flat to falling.  It then uses a beta distribution to set the percentage of the shape which is shell, giving a preference for very thin or very thick shells (but never 0% or 100%).  Using -sets=10 in sascomp should show a reasonable variety of curves over the default sascomp q range. The parameter set is returned as a dictionary of {parameter: value, ...}. Any model parameters not included in the dictionary will default according to the code in the _randomize_one() function from sasmodels/compare.py. Python Models :code:source = ["lib/Si.c", ...] (Si.c _) (Si.c _) sas_3j1x_x(x):
• ## doc/guide/scripting.rst

 r4aa5dce The key functions are :func:sasmodels.core.load_model for loading the model definition and compiling the kernel and :func:sasmodels.data.load_data for calling sasview to load the data. Need the data because that defines the resolution function and the q values to evaluate. If there is no data, then use :func:sasmodels.data.empty_data1D or :func:sasmodels.data.empty_data2D to create some data with a given $q$. Using sasmodels through bumps ============================= With the data and the model, you can wrap it in a *bumps* model with :func:sasmodels.data.load_data for calling sasview to load the data. Preparing data ============== Usually you will load data via the sasview loader, with the :func:sasmodels.data.load_data function.  For example:: from sasmodels.data import load_data data = load_data("sasmodels/example/093191_201.dat") You may want to apply a data mask, such a beam stop, and trim high $q$:: from sasmodels.data import set_beam_stop set_beam_stop(data, qmin, qmax) The :func:sasmodels.data.set_beam_stop method simply sets the *mask* attribute for the data. The data defines the resolution function and the q values to evaluate, so even if you simulating experiments prior to making measurements, you still need a data object for reference. Use :func:sasmodels.data.empty_data1D or :func:sasmodels.data.empty_data2D to create a container with a given $q$ and $\Delta q/q$.  For example:: import numpy as np from sasmodels.data import empty_data1D # 120 points logarithmically spaced from 0.005 to 0.2, with dq/q = 5% q = np.logspace(np.log10(5e-3), np.log10(2e-1), 120) data = empty_data1D(q, resolution=0.05) To use a more realistic model of resolution, or to load data from a file format not understood by SasView, you can use :class:sasmodels.data.Data1D or :class:sasmodels.data.Data2D directly.  The 1D data uses *x*, *y*, *dx* and *dy* for $x = q$ and $y = I(q)$, and 2D data uses *x*, *y*, *z*, *dx*, *dy*, *dz* for $x, y = qx, qy$ and $z = I(qx, qy)$. [Note: internally, the Data2D object uses SasView conventions, *qx_data*, *qy_data*, *data*, *dqx_data*, *dqy_data*, and *err_data*.] For USANS data, use 1D data, but set *dxl* and *dxw* attributes to indicate slit resolution:: data.dxl = 0.117 See :func:sasmodels.resolution.slit_resolution for details. SESANS data is more complicated; if your SESANS format is not supported by SasView you need to define a number of attributes beyond *x*, *y*.  For example:: SElength = np.linspace(0, 2400, 61) # [A] data = np.ones_like(SElength) err_data = np.ones_like(SElength)*0.03 class Source: wavelength = 6 # [A] wavelength_unit = "A" class Sample: zacceptance = 0.1 # [A^-1] thickness = 0.2 # [cm] class SESANSData1D: #q_zmax = 0.23 # [A^-1] lam = 0.2 # [nm] x = SElength y = data dy = err_data sample = Sample() data = SESANSData1D() x, y = ... # create or load sesans data = smd.Data The *data* module defines various data plotters as well. Using sasmodels directly ======================== Once you have a computational kernel and a data object, you can evaluate the model for various parameters using :class:sasmodels.direct_model.DirectModel.  The resulting object *f* will be callable as *f(par=value, ...)*, returning the $I(q)$ for the $q$ values in the data.  For example:: import numpy as np from sasmodels.data import empty_data1D from sasmodels.core import load_model from sasmodels.direct_model import DirectModel # 120 points logarithmically spaced from 0.005 to 0.2, with dq/q = 5% q = np.logspace(np.log10(5e-3), np.log10(2e-1), 120) data = empty_data1D(q, resolution=0.05) kernel = load_model("ellipsoid) f = DirectModel(data, kernel) Iq = f(radius_polar=100) Polydispersity information is set with special parameter names: * *par_pd* for polydispersity width, $\Delta p/p$, * *par_pd_n* for the number of points in the distribution, * *par_pd_type* for the distribution type (as a string), and * *par_pd_nsigmas* for the limits of the distribution. Using sasmodels through the bumps optimizer =========================================== Like DirectModel, you can wrap data and a kernel in a *bumps* model with class:sasmodels.bumps_model.Model and create an class:sasmodels.bump_model.Experiment that you can fit with the *bumps* class:sasmodels.bumps_model.Experiment that you can fit with the *bumps* interface. Here is an example from the *example* directory such as *example/model.py*:: SasViewCom bumps.cli example/model.py --preview Using sasmodels directly ======================== Bumps has a notion of parameter boxes in which you can set and retrieve values.  Instead of using bumps, you can create a directly callable function with :class:sasmodels.direct_model.DirectModel.  The resulting object *f* will be callable as *f(par=value, ...)*, returning the $I(q)$ for the $q$ values in the data.  Polydisperse parameters use the same naming conventions as in the bumps model, with e.g., radius_pd being the polydispersity associated with radius. Calling the computation kernel ============================== Getting a simple function that you can call on a set of q values and return
• ## doc/rst_prolog

 r30b60d2 .. |Ang^-3| replace:: |Ang|\ :sup:-3 .. |Ang^-4| replace:: |Ang|\ :sup:-4 .. |nm^-1| replace:: nm\ :sup:-1 .. |cm^-1| replace:: cm\ :sup:-1 .. |cm^2| replace:: cm\ :sup:2
• ## example/model_ellipsoid_hayter_msa.py

 r8a5f021 # DEFINE THE MODEL kernel = load_model('ellipsoid*hayter_msa') kernel = load_model('ellipsoid@hayter_msa') pars = dict(scale=6.4, background=0.06, sld=0.33, sld_solvent=2.15, radius_polar=14.0,
• ## sasmodels/compare.py

 r65fbf7c -title="note" adds note to the plot title, after the model name -weights shows weights plots for the polydisperse parameters -profile shows the sld profile if the model has a plottable sld profile === output options === -edit starts the parameter explorer -help/-html shows the model docs instead of running the model === environment variables === -DSAS_MODELPATH=path sets directory containing custom models -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 The interpretation of quad precision depends on architecture, and may dim = base._kernel.dim plot_weights(model_info, get_mesh(model_info, base_pars, dim=dim)) if opts['show_profile']: import pylab base, comp = opts['engines'] base_pars, comp_pars = opts['pars'] have_base = base._kernel.info.profile is not None have_comp = ( comp is not None and comp._kernel.info.profile is not None and base_pars != comp_pars ) if have_base or have_comp: pylab.figure() if have_base: plot_profile(base._kernel.info, **base_pars) if have_comp: plot_profile(comp._kernel.info, label='comp', **comp_pars) pylab.legend() if opts['plot']: import matplotlib.pyplot as plt plt.show() return limits def plot_profile(model_info, label='base', **args): # type: (ModelInfo, List[Tuple[float, np.ndarray, np.ndarray]]) -> None """ Plot the profile returned by the model profile method. *model_info* defines model parameters, etc. *mesh* is a list of tuples containing (*value*, *dispersity*, *weights*) for each parameter, where (*dispersity*, *weights*) pairs are the distributions to be plotted. """ import pylab args = dict((k, v) for k, v in args.items() if "_pd" not in k and ":" not in k and k not in ("background", "scale", "theta", "phi", "psi")) args = args.copy() args.pop('scale', 1.) args.pop('background', 0.) z, rho = model_info.profile(**args) #pylab.interactive(True) pylab.plot(z, rho, '-', label=label) pylab.grid(True) #pylab.show() def run_models(opts, verbose=False): OPTIONS = [ # Plotting 'plot', 'noplot', 'weights', 'plot', 'noplot', 'weights', 'profile', 'linear', 'log', 'q4', 'rel', 'abs', invalid = [o[1:] for o in flags if o[1:] not in NAME_OPTIONS and not any(o.startswith('-%s='%t) for t in VALUE_OPTIONS)] if not (o[1:] in NAME_OPTIONS or any(o.startswith('-%s='%t) for t in VALUE_OPTIONS) or o.startswith('-D'))] if invalid: print("Invalid options: %s"%(", ".join(invalid))) 'count'     : '1', 'show_weights' : False, 'show_profile' : False, 'sphere'    : 0, 'ngauss'    : '0', elif arg == '-default': opts['use_demo'] = False elif arg == '-weights': opts['show_weights'] = True elif arg == '-profile': opts['show_profile'] = True elif arg == '-html':    opts['html'] = True elif arg == '-help':    opts['html'] = True elif arg.startswith('-D'): var, val = arg[2:].split('=') os.environ[var] = val # pylint: enable=bad-whitespace,C0321 if opts['datafile'] is not None: data = load_data(os.path.expanduser(opts['datafile'])) data0 = load_data(os.path.expanduser(opts['datafile'])) data = data0, data0 else: # Hack around the fact that make_data doesn't take a pair of resolutions
• ## sasmodels/core.py

 r3221de0 if CUSTOM_MODEL_PATH == "": CUSTOM_MODEL_PATH = joinpath(os.path.expanduser("~"), ".sasmodels", "custom_models") if not os.path.isdir(CUSTOM_MODEL_PATH): os.makedirs(CUSTOM_MODEL_PATH) #if not os.path.isdir(CUSTOM_MODEL_PATH): #    os.makedirs(CUSTOM_MODEL_PATH) # TODO: refactor composite model support if not callable(model_info.Iq): source = generate.make_source(model_info)['dll'] old_path = kerneldll.DLL_PATH old_path = kerneldll.SAS_DLL_PATH try: kerneldll.DLL_PATH = path kerneldll.SAS_DLL_PATH = path dll = kerneldll.make_dll(source, model_info, dtype=numpy_dtype) finally: kerneldll.DLL_PATH = old_path kerneldll.SAS_DLL_PATH = old_path compiled_dlls.append(dll) return compiled_dlls
• ## sasmodels/data.py

 r65fbf7c *x* is spin echo length and *y* is polarization (P/P0). """ isSesans = True def __init__(self, **kw): Data1D.__init__(self, **kw) self.wavelength_unit = "A" class Sample(object): """ Sample attributes. """ def __init__(self): # type: () -> None pass def empty_data1D(q, resolution=0.0, L=0., dL=0.): # Note: masks merge, so any masked theory points will stay masked, # and the data mask will be added to it. mtheory = masked_array(theory, data.mask.copy()) #mtheory = masked_array(theory, data.mask.copy()) theory_x = data.x[data.mask == 0] mtheory = masked_array(theory) mtheory[~np.isfinite(mtheory)] = masked if view is 'log': mtheory[mtheory <= 0] = masked plt.plot(data.x, scale*mtheory, '-') plt.plot(theory_x, scale*mtheory, '-') all_positive = all_positive and (mtheory > 0).all() some_present = some_present or (mtheory.count() > 0) if use_resid: mresid = masked_array(resid, data.mask.copy()) theory_x = data.x[data.mask == 0] mresid = masked_array(resid) mresid[~np.isfinite(mresid)] = masked some_present = (mresid.count() > 0) if num_plots > 1: plt.subplot(1, num_plots, use_calc + 2) plt.plot(data.x, mresid, '.') plt.plot(theory_x, mresid, '.') plt.xlabel("$q$/A$^{-1}$") plt.ylabel('residuals')
• ## sasmodels/direct_model.py

 rd18d6dd from . import resolution2d from .details import make_kernel_args, dispersion_mesh from .modelinfo import DEFAULT_BACKGROUND # pylint: disable=unused-import qmax = getattr(data, 'qmax', np.inf) accuracy = getattr(data, 'accuracy', 'Low') index = ~data.mask & (q >= qmin) & (q <= qmax) index = (data.mask == 0) & (q >= qmin) & (q <= qmax) if data.data is not None: index &= ~np.isnan(data.data) elif self.data_type == 'Iq': index = (data.x >= data.qmin) & (data.x <= data.qmax) mask = getattr(data, 'mask', None) if mask is not None: index &= (mask == 0) if data.y is not None: index &= ~np.isnan(data.y) # Need to pull background out of resolution for multiple scattering background = pars.get('background', 0.) background = pars.get('background', DEFAULT_BACKGROUND) pars = pars.copy() pars['background'] = 0.
• ## sasmodels/generate.py

 rd86f0fc docs = model_info.docs if model_info.docs is not None else "" docs = convert_section_titles_to_boldface(docs) pars = make_partable(model_info.parameters.COMMON + model_info.parameters.kernel_parameters) if model_info.structure_factor: pars = model_info.parameters.kernel_parameters else: pars = model_info.parameters.COMMON + model_info.parameters.kernel_parameters partable = make_partable(pars) subst = dict(id=model_info.id.replace('_', '-'), name=model_info.name, title=model_info.title, parameters=pars, parameters=partable, returns=Sq_units if model_info.structure_factor else Iq_units, docs=docs)
• ## sasmodels/kernel_iq.c

 rdc6f601 in_spin = clip(in_spin, 0.0, 1.0); out_spin = clip(out_spin, 0.0, 1.0); // Note: sasview 3.1 scaled all slds by sqrt(weight) and assumed that // Previous version of this function took the square root of the weights, // under the assumption that // //     w*I(q, rho1, rho2, ...) = I(q, sqrt(w)*rho1, sqrt(w)*rho2, ...) // which is likely to be the case for simple models. weight[0] = sqrt((1.0-in_spin) * (1.0-out_spin)); // dd weight[1] = sqrt((1.0-in_spin) * out_spin);       // du.real weight[2] = sqrt(in_spin * (1.0-out_spin));       // ud.real weight[3] = sqrt(in_spin * out_spin);             // uu // // However, since the weights are applied to the final intensity and // are not interned inside the I(q) function, we want the full // weight and not the square root.  Any function using // set_spin_weights as part of calculating an amplitude will need to // manually take that square root, but there is currently no such // function. weight[0] = (1.0-in_spin) * (1.0-out_spin); // dd weight[1] = (1.0-in_spin) * out_spin;       // du weight[2] = in_spin * (1.0-out_spin);       // ud weight[3] = in_spin * out_spin;             // uu weight[4] = weight[1]; // du.imag weight[5] = weight[2]; // ud.imag QACRotation *rotation, double qx, double qy, double *qa_out, double *qc_out) double *qab_out, double *qc_out) { // Indirect calculation of qab, from qab^2 = |q|^2 - qc^2 const double dqc = rotation->R31*qx + rotation->R32*qy; // Indirect calculation of qab, from qab^2 = |q|^2 - qc^2 const double dqa = sqrt(-dqc*dqc + qx*qx + qy*qy); *qa_out = dqa; const double dqab_sq = -dqc*dqc + qx*qx + qy*qy; //*qab_out = sqrt(fabs(dqab_sq)); *qab_out = dqab_sq > 0.0 ? sqrt(dqab_sq) : 0.0; *qc_out = dqc; }
• ## sasmodels/kerneldll.py

 r33969b6 pass # pylint: enable=unused-import if "SAS_DLL_PATH" in os.environ: SAS_DLL_PATH = os.environ["SAS_DLL_PATH"] else: # Assume the default location of module DLLs is in .sasmodels/compiled_models. SAS_DLL_PATH = os.path.join(os.path.expanduser("~"), ".sasmodels", "compiled_models") if "SAS_COMPILER" in os.environ: return CC + [source, "-o", output, "-lm"] # Assume the default location of module DLLs is in .sasmodels/compiled_models. DLL_PATH = os.path.join(os.path.expanduser("~"), ".sasmodels", "compiled_models") ALLOW_SINGLE_PRECISION_DLLS = True return path return joinpath(DLL_PATH, basename) return joinpath(SAS_DLL_PATH, basename) exist yet if it hasn't been compiled. """ return os.path.join(DLL_PATH, dll_name(model_info, dtype)) return os.path.join(SAS_DLL_PATH, dll_name(model_info, dtype)) models are not allowed as DLLs. Set *sasmodels.kerneldll.DLL_PATH* to the compiled dll output path. Set *sasmodels.kerneldll.SAS_DLL_PATH* to the compiled dll output path. Alternatively, set the environment variable *SAS_DLL_PATH*. The default is in ~/.sasmodels/compiled_models. """ if need_recompile: # Make sure the DLL path exists if not os.path.exists(DLL_PATH): os.makedirs(DLL_PATH) if not os.path.exists(SAS_DLL_PATH): os.makedirs(SAS_DLL_PATH) basename = splitext(os.path.basename(dll))[0] + "_" system_fd, filename = tempfile.mkstemp(suffix=".c", prefix=basename)
• ## sasmodels/model_test.py

• Property mode changed from 100644 to 100755
 r3221de0 stream.writeln(traceback.format_exc()) return # Run the test suite suite.run(result) # Print the failures and errors for _, tb in result.errors: stream.writeln(tb) for _, tb in result.failures: stream.writeln(tb) # Warn if there are no user defined tests. # iterator since we don't have direct access to the list of tests in the # test suite. # In Qt5 suite.run() will clear all tests in the suite after running # with no way of retaining them for the test below, so let's check # for user tests before running the suite. for test in suite: if not test.info.tests: else: stream.writeln("Note: no test suite created --- this should never happen") # Run the test suite suite.run(result) # Print the failures and errors for _, tb in result.errors: stream.writeln(tb) for _, tb in result.failures: stream.writeln(tb) output = stream.getvalue()
• ## sasmodels/modelinfo.py

 r95498a3 # Note that scale and background cannot be coordinated parameters whose value # depends on the some polydisperse parameter with the current implementation DEFAULT_BACKGROUND = 1e-3 COMMON_PARAMETERS = [ ("scale", "", 1, (0.0, np.inf), "", "Source intensity"), ("background", "1/cm", 1e-3, (-np.inf, np.inf), "", "Source background"), ("background", "1/cm", DEFAULT_BACKGROUND, (-np.inf, np.inf), "", "Source background"), ] assert (len(COMMON_PARAMETERS) == 2 Parameter('up:frac_f', '', 0., [0., 1.], 'magnetic', 'fraction of spin up final'), Parameter('up:angle', 'degress', 0., [0., 360.], Parameter('up:angle', 'degrees', 0., [0., 360.], 'magnetic', 'spin up angle'), ])
• ## sasmodels/models/_spherepy.py

 r108e70e r""" For information about polarised and magnetic scattering, see the :doc:magnetic help <../sasgui/perspectives/fitting/mag_help> documentation. the :ref:magnetism documentation. Definition
• ## sasmodels/models/core_shell_cylinder.py

 r2d81cfe The output of the 2D scattering intensity function for oriented core-shell cylinders is given by (Kline, 2006 [#kline]_). The form factor is normalized by the particle volume. by the particle volume. Note that in this model the shell envelops the entire core so that besides a "sleeve" around the core, the shell also provides two flat end caps of thickness = shell thickness. In other words the length of the total cyclinder is the length of the core cylinder plus twice the thickness of the shell. If no end caps are desired one should use the :ref:core-shell-bicelle and set the thickness of the end caps (in this case the "thick_face") to zero. .. math:: and $\alpha$ is the angle between the axis of the cylinder and $\vec q$, $V_s$ is the volume of the outer shell (i.e. the total volume, including the shell), $V_c$ is the volume of the core, $L$ is the length of the core, $V_s$ is the total volume (i.e. including both the core and the outer shell), $V_c$ is the volume of the core, $L$ is the length of the core, $R$ is the radius of the core, $T$ is the thickness of the shell, $\rho_c$ is the scattering length density of the core, $\rho_s$ is the scattering return 0.5 * (ddd) ** (1. / 3.) def VR(radius, thickness, length): """ Returns volume ratio """ whole = pi * (radius + thickness) ** 2 * (length + 2 * thickness) core = pi * radius ** 2 * length return whole, whole - core def random(): outer_radius = 10**np.random.uniform(1, 4.7)
• ## sasmodels/models/core_shell_parallelepiped.c

 re077231 // outer integral (with gauss points), integration limits = 0, 1 // substitute d_cos_alpha for sin_alpha d_alpha double outer_sum = 0; //initialize integral for( int i=0; i
• ## sasmodels/models/core_shell_parallelepiped.py

 r97be877 Calculates the form factor for a rectangular solid with a core-shell structure. The thickness and the scattering length density of the shell or "rim" can be different on each (pair) of faces. The thickness and the scattering length density of the shell or "rim" can be different on each (pair) of faces. The three dimensions of the core of the parallelepiped (strictly here a cuboid) may be given in *any* size order as long as the particles are randomly oriented (i.e. take on all possible orientations see notes on 2D below). To avoid multiple fit solutions, especially with Monte-Carlo fit methods, it may be advisable to restrict their ranges. There may be a number of closely similar "best fits", so some trial and error, or fixing of some dimensions at expected values, may help. The form factor is normalized by the particle volume $V$ such that .. math:: I(q) = \text{scale}\frac{\langle f^2 \rangle}{V} + \text{background} I(q) = \frac{\text{scale}}{V} \langle P(q,\alpha,\beta) \rangle + \text{background} where $\langle \ldots \rangle$ is an average over all possible orientations of the rectangular solid. The function calculated is the form factor of the rectangular solid below. The core of the solid is defined by the dimensions $A$, $B$, $C$ such that $A < B < C$. .. image:: img/core_shell_parallelepiped_geometry.jpg of the rectangular solid, and the usual $\Delta \rho^2 \ V^2$ term cannot be pulled out of the form factor term due to the multiple slds in the model. The core of the solid is defined by the dimensions $A$, $B$, $C$ here shown such that $A < B < C$. .. figure:: img/parallelepiped_geometry.jpg Core of the core shell parallelepiped with the corresponding definition of sides. There are rectangular "slabs" of thickness $t_A$ that add to the $A$ dimension (on the $BC$ faces). There are similar slabs on the $AC$ $(=t_B)$ and $AB$ $(=t_C)$ faces. The projection in the $AB$ plane is then .. image:: img/core_shell_parallelepiped_projection.jpg The volume of the solid is $(=t_C)$ faces. The projection in the $AB$ plane is .. figure:: img/core_shell_parallelepiped_projection.jpg AB cut through the core-shell parallelipiped showing the cross secion of four of the six shell slabs. As can be seen, this model leaves **"gaps"** at the corners of the solid. The total volume of the solid is thus given as .. math:: V = ABC + 2t_ABC + 2t_BAC + 2t_CAB **meaning that there are "gaps" at the corners of the solid.** The intensity calculated follows the :ref:parallelepiped model, with the core-shell intensity being calculated as the square of the sum of the amplitudes of the core and the slabs on the edges. the scattering amplitude is computed for a particular orientation of the core-shell parallelepiped with respect to the scattering vector and then averaged over all possible orientations, where $\alpha$ is the angle between the $z$ axis and the $C$ axis of the parallelepiped, $\beta$ is the angle between projection of the particle in the $xy$ detector plane and the $y$ axis. .. math:: F(Q) amplitudes of the core and the slabs on the edges. The scattering amplitude is computed for a particular orientation of the core-shell parallelepiped with respect to the scattering vector and then averaged over all possible orientations, where $\alpha$ is the angle between the $z$ axis and the $C$ axis of the parallelepiped, and $\beta$ is the angle between the projection of the particle in the $xy$ detector plane and the $y$ axis. .. math:: P(q)=\frac {\int_{0}^{\pi/2}\int_{0}^{\pi/2}F^2(q,\alpha,\beta) \ sin\alpha \ d\alpha \ d\beta} {\int_{0}^{\pi/2} \ sin\alpha \ d\alpha \ d\beta} and .. math:: F(q,\alpha,\beta) &= (\rho_\text{core}-\rho_\text{solvent}) S(Q_A, A) S(Q_B, B) S(Q_C, C) \\ &+ (\rho_\text{A}-\rho_\text{solvent}) \left[S(Q_A, A+2t_A) - S(Q_A, Q)\right] S(Q_B, B) S(Q_C, C) \\ \left[S(Q_A, A+2t_A) - S(Q_A, A)\right] S(Q_B, B) S(Q_C, C) \\ &+ (\rho_\text{B}-\rho_\text{solvent}) S(Q_A, A) \left[S(Q_B, B+2t_B) - S(Q_B, B)\right] S(Q_C, C) \\ .. math:: S(Q, L) = L \frac{\sin \tfrac{1}{2} Q L}{\tfrac{1}{2} Q L} S(Q_X, L) = L \frac{\sin (\tfrac{1}{2} Q_X L)}{\tfrac{1}{2} Q_X L} and .. math:: Q_A &= \sin\alpha \sin\beta \\ Q_B &= \sin\alpha \cos\beta \\ Q_C &= \cos\alpha Q_A &= q \sin\alpha \sin\beta \\ Q_B &= q \sin\alpha \cos\beta \\ Q_C &= q \cos\alpha where $\rho_\text{core}$, $\rho_\text{A}$, $\rho_\text{B}$ and $\rho_\text{C}$ are the scattering length of the parallelepiped core, and the rectangular are the scattering lengths of the parallelepiped core, and the rectangular slabs of thickness $t_A$, $t_B$ and $t_C$, respectively. $\rho_\text{solvent}$ is the scattering length of the solvent. .. note:: the code actually implements two substitutions: $d(cos\alpha)$ is substituted for -$sin\alpha \ d\alpha$ (note that in the :ref:parallelepiped code this is explicitly implemented with $\sigma = cos\alpha$), and $\beta$ is set to $\beta = u \pi/2$ so that $du = \pi/2 \ d\beta$.  Thus both integrals go from 0 to 1 rather than 0 to $\pi/2$. FITTING NOTES ~~~~~~~~~~~~~ If the scale is set equal to the particle volume fraction, $\phi$, the returned value is the scattered intensity per unit volume, $I(q) = \phi P(q)$. However, **no interparticle interference effects are included in this calculation.** There are many parameters in this model. Hold as many fixed as possible with known values, or you will certainly end up at a solution that is unphysical. The returned value is in units of |cm^-1|, on absolute scale. NB: The 2nd virial coefficient of the core_shell_parallelepiped is calculated based on the the averaged effective radius $(=\sqrt{(A+2t_A)(B+2t_B)/\pi})$ and length $(C+2t_C)$ values, after appropriately sorting the three dimensions to give an oblate or prolate particle, to give an effective radius, for $S(Q)$ when $P(Q) * S(Q)$ is applied. For 2d data the orientation of the particle is required, described using angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, for further details of the calculation and angular dispersions see :ref:orientation. The angle $\Psi$ is the rotational angle around the *long_c* axis. For example, $\Psi = 0$ when the *short_b* axis is parallel to the *x*-axis of the detector. For 2d, constraints must be applied during fitting to ensure that the inequality $A < B < C$ is not violated, and hence the correct definition of angles is preserved. The calculation will not report an error, but the results may be not correct. #. There are many parameters in this model. Hold as many fixed as possible with known values, or you will certainly end up at a solution that is unphysical. #. The 2nd virial coefficient of the core_shell_parallelepiped is calculated based on the the averaged effective radius $(=\sqrt{(A+2t_A)(B+2t_B)/\pi})$ and length $(C+2t_C)$ values, after appropriately sorting the three dimensions to give an oblate or prolate particle, to give an effective radius for $S(q)$ when $P(q) * S(q)$ is applied. #. For 2d data the orientation of the particle is required, described using angles $\theta$, $\phi$ and $\Psi$ as in the diagrams below, where $\theta$ and $\phi$ define the orientation of the director in the laboratry reference frame of the beam direction ($z$) and detector plane ($x-y$ plane), while the angle $\Psi$ is effectively the rotational angle around the particle $C$ axis. For $\theta = 0$ and $\phi = 0$, $\Psi = 0$ corresponds to the $B$ axis oriented parallel to the y-axis of the detector with $A$ along the x-axis. For other $\theta$, $\phi$ values, the order of rotations matters. In particular, the parallelepiped must first be rotated $\theta$ degrees in the $x-z$ plane before rotating $\phi$ degrees around the $z$ axis (in the $x-y$ plane). Applying orientational distribution to the particle orientation (i.e  jitter to one or more of these angles) can get more confusing as jitter is defined **NOT** with respect to the laboratory frame but the particle reference frame. It is thus highly recmmended to read :ref:orientation for further details of the calculation and angular dispersions. .. note:: For 2d, constraints must be applied during fitting to ensure that the order of sides chosen is not altered, and hence that the correct definition of angles is preserved. For the default choice shown here, that means ensuring that the inequality $A < B < C$ is not violated,  The calculation will not report an error, but the results may be not correct. .. figure:: img/parallelepiped_angle_definition.png Definition of the angles for oriented core-shell parallelepipeds. Note that rotation $\theta$, initially in the $xz$ plane, is carried Note that rotation $\theta$, initially in the $x-z$ plane, is carried out first, then rotation $\phi$ about the $z$ axis, finally rotation $\Psi$ is now around the axis of the cylinder. The neutron or X-ray beam is along the $z$ axis. $\Psi$ is now around the $C$ axis of the particle. The neutron or X-ray beam is along the $z$ axis and the detecotr defines the $x-y$ plane. .. figure:: img/parallelepiped_angle_projection.png Examples of the angles for oriented core-shell parallelepipeds against the detector plane. Validation ---------- Cross-checked against hollow rectangular prism and rectangular prism for equal thickness overlapping sides, and by Monte Carlo sampling of points within the shape for non-uniform, non-overlapping sides. References * **Author:** NIST IGOR/DANSE **Date:** pre 2010 * **Converted to sasmodels by:** Miguel Gonzales **Date:** February 26, 2016 * **Converted to sasmodels by:** Miguel Gonzalez **Date:** February 26, 2016 * **Last Modified by:** Paul Kienzle **Date:** October 17, 2017 * Cross-checked against hollow rectangular prism and rectangular prism for equal thickness overlapping sides, and by Monte Carlo sampling of points within the shape for non-uniform, non-overlapping sides. * **Last Reviewed by:** Paul Butler **Date:** May 24, 2018 - documentation updated """
• ## sasmodels/models/core_shell_sphere.py

 r2d81cfe .. math:: F^2(q) = \frac{3}{V_s}\left[ F(q) = \frac{3}{V_s}\left[ V_c(\rho_c-\rho_s)\frac{\sin(qr_c)-qr_c\cos(qr_c)}{(qr_c)^3} + V_s(\rho_s-\rho_\text{solv})\frac{\sin(qr_s)-qr_s\cos(qr_s)}{(qr_s)^3} return radius + thickness def VR(radius, thickness): """ Volume ratio @param radius: core radius @param thickness: shell thickness """ return (1, 1) whole = 4.0/3.0 * pi * (radius + thickness)**3 core = 4.0/3.0 * pi * radius**3 return whole, whole - core def random(): outer_radius = 10**np.random.uniform(1.3, 4.3) tests = [ [{'radius': 20.0, 'thickness': 10.0}, 'ER', 30.0], # TODO: VR test suppressed until we sort out new product model # and determine what to do with volume ratio. #[{'radius': 20.0, 'thickness': 10.0}, 'VR', 0.703703704], # The SasView test result was 0.00169, with a background of 0.001

• ## sasmodels/models/guinier.py

 r2d81cfe .. math:: I(q) = \text{scale} \cdot \exp{\left[ \frac{-Q^2R_g^2}{3} \right]} I(q) = \text{scale} \cdot \exp{\left[ \frac{-Q^2 R_g^2 }{3} \right]} + \text{background} .. math:: q = \sqrt{q_x^2 + q_y^2} In scattering, the radius of gyration $R_g$ quantifies the objects's distribution of SLD (not mass density, as in mechanics) from the objects's SLD centre of mass. It is defined by .. math:: R_g^2 = \frac{\sum_i\rho_i\left(r_i-r_0\right)^2}{\sum_i\rho_i} where $r_0$ denotes the object's SLD centre of mass and $\rho_i$ is the SLD at a point $i$. Notice that $R_g^2$ may be negative (since SLD can be negative), which happens when a form factor $P(Q)$ is increasing with $Q$ rather than decreasing. This can occur for core/shell particles, hollow particles, or for composite particles with domains of different SLDs in a solvent with an SLD close to the average match point. (Alternatively, this might be regarded as there being an internal inter-domain "structure factor" within a single particle which gives rise to a peak in the scattering). To specify a negative value of $R_g^2$ in SasView, simply give $R_g$ a negative value ($R_g^2$ will be evaluated as $R_g |R_g|$). Note that the physical radius of gyration, of the exterior of the particle, will still be large and positive. It is only the apparent size from the small $Q$ data that will give a small or negative value of $R_g^2$. References #             ["name", "units", default, [lower, upper], "type","description"], parameters = [["rg", "Ang", 60.0, [0, inf], "", "Radius of Gyration"]] parameters = [["rg", "Ang", 60.0, [-inf, inf], "", "Radius of Gyration"]] Iq = """ double exponent = rg*rg*q*q/3.0; double exponent = fabs(rg)*rg*q*q/3.0; double value = exp(-exponent); return value; # parameters for demo demo = dict(scale=1.0, rg=60.0) demo = dict(scale=1.0,  background=0.001, rg=60.0 ) # parameters for unit tests
• ## sasmodels/models/hollow_cylinder.py

 r2d81cfe r""" Definition ---------- This model provides the form factor, $P(q)$, for a monodisperse hollow right angle circular cylinder (rigid tube) where the form factor is normalized by the volume of the tube (i.e. not by the external volume). angle circular cylinder (rigid tube) where the The inside and outside of the hollow cylinder are assumed to have the same SLD and the form factor is thus normalized by the volume of the tube (i.e. not by the total cylinder volume). .. math:: P(q) = \text{scale} \left/V_\text{shell} + \text{background} where the averaging $\left<\ldots\right>$ is applied only for the 1D calculation. where the averaging $\left<\ldots\right>$ is applied only for the 1D calculation. If Intensity is given on an absolute scale, the scale factor here is the volume fraction of the shell.  This differs from the :ref:core-shell-cylinder in that, in that case, scale is the volume fraction of the entire cylinder (core+shell). The application might be for a bilayer which wraps into a hollow tube and the volume fraction of material is all in the shell, whereas the :ref:core-shell-cylinder model might be used for a cylindrical micelle where the tails in the core have a different SLD than the headgroups (in the shell) and the volume fraction of material comes fromm the whole cyclinder.  NOTE: the hollow_cylinder represents a tube whereas the core_shell_cylinder includes a shell layer covering the ends (end caps) as well. The inside and outside of the hollow cylinder are assumed have the same SLD. Definition ---------- The 1D scattering intensity is calculated in the following way (Guinier, 1955) ---------- L A Feigin and D I Svergun, *Structure Analysis by Small-Angle X-Ray and Neutron Scattering*, Plenum Press, New York, (1987) .. [#] L A Feigin and D I Svergun, *Structure Analysis by Small-Angle X-Ray and Neutron Scattering*, Plenum Press, New York, (1987) Authorship and Verification * **Author:** NIST IGOR/DANSE **Date:** pre 2010 * **Last Modified by:** Richard Heenan **Date:** October 06, 2016 (reparametrised to use thickness, not outer radius) * **Last Reviewed by:** Richard Heenan **Date:** October 06, 2016 * **Last Modified by:** Paul Butler **Date:** September 06, 2018 (corrected VR calculation) * **Last Reviewed by:** Paul Butler **Date:** September 06, 2018 """ vol_total = pi*router*router*length vol_shell = vol_total - vol_core return vol_shell, vol_total return vol_total, vol_shell def random(): tests = [ [{}, 0.00005, 1764.926], [{}, 'VR', 1.8], [{}, 'VR', 0.55555556], [{}, 0.001, 1756.76], [{}, (qx, qy), 2.36885476192],
• ## sasmodels/models/hollow_rectangular_prism.py

 r0e55afe # Note: model title and parameter table are inserted automatically r""" This model provides the form factor, $P(q)$, for a hollow rectangular parallelepiped with a wall of thickness $\Delta$. Definition ---------- The 1D scattering intensity for this model is calculated by forming the difference of the amplitudes of two massive parallelepipeds differing in their outermost dimensions in each direction by the same length increment $2\Delta$ (Nayuk, 2012). This model provides the form factor, $P(q)$, for a hollow rectangular parallelepiped with a wall of thickness $\Delta$. The 1D scattering intensity for this model is calculated by forming the difference of the amplitudes of two massive parallelepipeds differing in their outermost dimensions in each direction by the same length increment $2\Delta$ (\ [#Nayuk2012]_ Nayuk, 2012). As in the case of the massive parallelepiped model (:ref:rectangular-prism), \rho_\text{solvent})^2 \times P(q) + \text{background} where $\rho_\text{p}$ is the scattering length of the parallelepiped, $\rho_\text{solvent}$ is the scattering length of the solvent, where $\rho_\text{p}$ is the scattering length density of the parallelepiped, $\rho_\text{solvent}$ is the scattering length density of the solvent, and (if the data are in absolute units) *scale* represents the volume fraction (which is unitless). (which is unitless) of the rectangular shell of material (i.e. not including the volume of the solvent filled core). For 2d data the orientation of the particle is required, described using For 2d, constraints must be applied during fitting to ensure that the inequality $A < B < C$ is not violated, and hence the correct definition of angles is preserved. The calculation will not report an error, but the results may be not correct. $A < B < C$ is not violated, and hence the correct definition of angles is preserved. The calculation will not report an error if the inequality is *not* preserved, but the results may be not correct. .. figure:: img/parallelepiped_angle_definition.png ---------- R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 .. [#Nayuk2012] R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 Authorship and Verification ---------------------------- * **Author:** Miguel Gonzales **Date:** February 26, 2016 * **Last Modified by:** Paul Kienzle **Date:** December 14, 2017 * **Last Reviewed by:** Paul Butler **Date:** September 06, 2018 """
• ## sasmodels/models/hollow_rectangular_prism_thin_walls.py

 r2d81cfe # Note: model title and parameter table are inserted automatically r""" Definition ---------- This model provides the form factor, $P(q)$, for a hollow rectangular prism with infinitely thin walls. It computes only the 1D scattering, not the 2D. Definition ---------- The 1D scattering intensity for this model is calculated according to the equations given by Nayuk and Huber (Nayuk, 2012). equations given by Nayuk and Huber\ [#Nayuk2012]_. Assuming a hollow parallelepiped with infinitely thin walls, edge lengths I(q) = \text{scale} \times V \times (\rho_\text{p} - \rho_\text{solvent})^2 \times P(q) where $V$ is the volume of the rectangular prism, $\rho_\text{p}$ is the scattering length of the parallelepiped, $\rho_\text{solvent}$ is the scattering length of the solvent, and (if the data are in absolute units) *scale* represents the volume fraction (which is unitless). where $V$ is the surface area of the rectangular prism, $\rho_\text{p}$ is the scattering length density of the parallelepiped, $\rho_\text{solvent}$ is the scattering length density of the solvent, and (if the data are in absolute units) *scale* is related to the total surface area. **The 2D scattering intensity is not computed by this model.** Validation of the code was conducted  by qualitatively comparing the output of the 1D model to the curves shown in (Nayuk, 2012). of the 1D model to the curves shown in (Nayuk, 2012\ [#Nayuk2012]_). ---------- R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 .. [#Nayuk2012] R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 Authorship and Verification ---------------------------- * **Author:** Miguel Gonzales **Date:** February 26, 2016 * **Last Modified by:** Paul Kienzle **Date:** October 15, 2016 * **Last Reviewed by:** Paul Butler **Date:** September 07, 2018 """
• ## sasmodels/models/mass_surface_fractal.py

 r2d81cfe The surface ( $D_s$ ) and mass ( $D_m$ ) fractal dimensions are only valid if $0 < surface\_dim < 6$ , $0 < mass\_dim < 6$ , and $(surface\_dim + mass\_dim ) < 6$ . $(surface\_dim + mass\_dim ) < 6$ . Older versions of sasview may have the default primary particle radius larger than the cluster radius, this was an error, also present in the Schmidt review paper below. The primary particle should be the smaller as described in the original Hurd et.al. who also point out that polydispersity in the primary particle sizes may affect their apparent surface fractal dimension. References ---------- P Schmidt, *J Appl. Cryst.*, 24 (1991) 414-435 Equation(19) .. [#] P Schmidt, *J Appl. Cryst.*, 24 (1991) 414-435 Equation(19) .. [#] A J Hurd, D W Schaefer, J E Martin, *Phys. Rev. A*, 35 (1987) 2361-2364 Equation(2) A J Hurd, D W Schaefer, J E Martin, *Phys. Rev. A*, 35 (1987) 2361-2364 Equation(2) Authorship and Verification ---------------------------- * **Converted to sasmodels by:** Piotr Rozyczko **Date:** Jan 20, 2016 * **Last Reviewed by:** Richard Heenan **Date:** May 30, 2018 """ rg_primary    =  rg background   =  background Ref: Schmidt, J Appl Cryst, eq(19), (1991), 24, 414-435 Hurd, Schaefer, Martin, Phys Rev A, eq(2),(1987),35, 2361-2364 Note that 0 < Ds< 6 and 0 < Dm < 6. ["fractal_dim_mass", "",      1.8, [0.0, 6.0], "", "Mass fractal dimension"], ["fractal_dim_surf", "",      2.3, [0.0, 6.0], "", "Surface fractal dimension"], ["rg_cluster",       "Ang",  86.7, [0.0, inf], "", "Cluster radius of gyration"], ["rg_primary",       "Ang", 4000., [0.0, inf], "", "Primary particle radius of gyration"], ["rg_cluster",       "Ang", 4000., [0.0, inf], "", "Cluster radius of gyration"], ["rg_primary",       "Ang",  86.7, [0.0, inf], "", "Primary particle radius of gyration"], ] # pylint: enable=bad-whitespace, line-too-long fractal_dim_mass=1.8, fractal_dim_surf=2.3, rg_cluster=86.7, rg_primary=4000.0) rg_cluster=4000.0, rg_primary=86.7) tests = [ # Accuracy tests based on content in test/utest_other_models.py [{'fractal_dim_mass':      1.8, # Accuracy tests based on content in test/utest_other_models.py  All except first, changed so rg_cluster is the larger, RKH 30 May 2018 [{'fractal_dim_mass':   1.8, 'fractal_dim_surf':   2.3, 'rg_cluster':   86.7, [{'fractal_dim_mass':      3.3, 'fractal_dim_surf':   1.0, 'rg_cluster':   90.0, 'rg_primary': 4000.0, }, 0.001, 0.18562699016], 'rg_cluster': 4000.0, 'rg_primary':   90.0, }, 0.001, 0.0932516614456], [{'fractal_dim_mass':      1.3, 'fractal_dim_surf':   1.0, 'rg_cluster':   90.0, 'rg_primary': 2000.0, 'fractal_dim_surf':   2.0, 'rg_cluster': 2000.0, 'rg_primary':   90.0, 'background':    0.8, }, 0.001, 1.16539753641], }, 0.001, 1.28296431786], [{'fractal_dim_mass':      2.3, 'fractal_dim_surf':   1.0, 'rg_cluster':   90.0, 'rg_primary': 1000.0, 'fractal_dim_surf':   3.1, 'rg_cluster':  1000.0, 'rg_primary':  30.0, 'scale':        10.0, 'background':    0.0, }, 0.051, 0.000169548800377], }, 0.051, 0.00333804044899], ]
• ## sasmodels/models/parallelepiped.c

 r108e70e inner_total += GAUSS_W[j] * square(si1 * si2); } // now complete change of inner integration variable (1-0)/(1-(-1))= 0.5 inner_total *= 0.5; outer_total += GAUSS_W[i] * inner_total * si * si; } // now complete change of outer integration variable (1-0)/(1-(-1))= 0.5 outer_total *= 0.5;

• ## sasmodels/models/vesicle.py

 ref07e95 ---------- The 1D scattering intensity is calculated in the following way (Guinier, 1955) This model provides the form factor, *P(q)*, for an unilamellar vesicle and is effectively identical to the hollow sphere reparameterized to be more intuitive for a vesicle and normalizing the form factor by the volume of the shell. The 1D scattering intensity is calculated in the following way (Guinier,1955\ [#Guinier1955]_) .. math:: ---------- A Guinier and G. Fournet, *Small-Angle Scattering of X-Rays*, John Wiley and Sons, New York, (1955) .. [#Guinier1955] A Guinier and G. Fournet, *Small-Angle Scattering of X-Rays*, John Wiley and Sons, New York, (1955) Authorship and Verification ---------------------------- * **Author:** NIST IGOR/DANSE **Date:** pre 2010 * **Last Modified by:** Paul Butler **Date:** March 20, 2016 * **Last Reviewed by:** Paul Butler **Date:** March 20, 2016 * **Last Reviewed by:** Paul Butler **Date:** September 7, 2018 """ name = "vesicle" title = "This model provides the form factor, *P(q)*, for an unilamellar \ vesicle. This is model is effectively identical to the hollow sphere \ reparameterized to be more intuitive for a vesicle and normalizing the \ form factor by the volume of the shell." title = "Vesicle model representing a hollow sphere" description = """ Model parameters:
• ## sasmodels/resolution.py

 rbbb887d MINIMUM_RESOLUTION = 1e-8 MINIMUM_ABSOLUTE_Q = 0.02  # relative to the minimum q in the data PINHOLE_N_SIGMA = 2.5 # From: Barker & Pedersen 1995 JAC # According to (Barker & Pedersen 1995 JAC), 2.5 sigma is a good limit. # According to simulations with github.com:scattering/sansresolution.git # it is better to use asymmetric bounds (2.5, 3.0) PINHOLE_N_SIGMA = (2.5, 3.0) class Resolution(object): # from the geometry, they may appear since we are using a truncated # gaussian to represent resolution rather than a skew distribution. cutoff = MINIMUM_ABSOLUTE_Q*np.min(self.q) self.q_calc = self.q_calc[self.q_calc >= cutoff] #cutoff = MINIMUM_ABSOLUTE_Q*np.min(self.q) #self.q_calc = self.q_calc[self.q_calc >= cutoff] # Build weight matrix from calculated q values cdf = erf((edges[:, None] - q[None, :]) / (sqrt(2.0)*q_width)[None, :]) weights = cdf[1:] - cdf[:-1] # Limit q range to +/- 2.5 sigma qhigh = q + nsigma*q_width #qlow = q - nsigma*q_width  # linear limits qlow = q*q/qhigh  # log limits # Limit q range to (-2.5,+3) sigma try: nsigma_low, nsigma_high = nsigma except TypeError: nsigma_low = nsigma_high = nsigma qhigh = q + nsigma_high*q_width qlow = q - nsigma_low*q_width  # linear limits ##qlow = q*q/qhigh  # log limits weights[q_calc[:, None] < qlow[None, :]] = 0. weights[q_calc[:, None] > qhigh[None, :]] = 0. def pinhole_extend_q(q, q_width, nsigma=3): def pinhole_extend_q(q, q_width, nsigma=PINHOLE_N_SIGMA): """ Given *q* and *q_width*, find a set of sampling points *q_calc* so function. """ q_min, q_max = np.min(q - nsigma*q_width), np.max(q + nsigma*q_width) try: nsigma_low, nsigma_high = nsigma except TypeError: nsigma_low = nsigma_high = nsigma q_min, q_max = np.min(q - nsigma_low*q_width), np.max(q + nsigma_high*q_width) return linear_extrapolation(q, q_min, q_max) # TODO: turn pinhole/slit demos into tests @unittest.skip("suppress comparison with old version; pinhole calc changed") def test_pinhole(self): """
• ## setup.py

 r1f991d6 }, install_requires=[ 'numpy', 'scipy', ], extras_require={
Note: See TracChangeset for help on using the changeset viewer.