Changeset afe206d in sasmodels


Ignore:
Timestamp:
Sep 25, 2018 7:41:04 AM (6 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
ce1eed5
Parents:
12eec1e (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-1142-plugin-reload

Files:
26 edited

Legend:

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

    rd712a0f rd089a00  
    88.. _polydispersityhelp: 
    99 
    10 Polydispersity Distributions 
    11 ---------------------------- 
    12  
    13 With some models in sasmodels we can calculate the average intensity for a 
    14 population of particles that exhibit size and/or orientational 
    15 polydispersity. The resultant intensity is normalized by the average 
    16 particle volume such that 
     10Polydispersity & Orientational Distributions 
     11-------------------------------------------- 
     12 
     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  
     17the actual parameter it is being applied too. 
     18 
     19The resultant intensity is then normalized by the average particle volume such  
     20that 
    1721 
    1822.. math:: 
     
    2125 
    2226where $F$ is the scattering amplitude and $\langle\cdot\rangle$ denotes an  
    23 average over the size distribution $f(x; \bar x, \sigma)$, giving 
     27average over the distribution $f(x; \bar x, \sigma)$, giving 
    2428 
    2529.. math:: 
     
    3034Each distribution is characterized by a center value $\bar x$ or 
    3135$x_\text{med}$, a width parameter $\sigma$ (note this is *not necessarily* 
    32 the standard deviation, so read the description carefully), the number of 
    33 sigmas $N_\sigma$ to include from the tails of the distribution, and the 
    34 number of points used to compute the average. The center of the distribution 
    35 is set by the value of the model parameter. The meaning of a polydispersity  
    36 parameter *PD* (not to be confused with a molecular weight distributions  
    37 in polymer science) in a model depends on the type of parameter it is being  
    38 applied too. 
     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. 
    3940 
    4041The distribution width applied to *volume* (ie, shape-describing) parameters  
    4142is relative to the center value such that $\sigma = \mathrm{PD} \cdot \bar x$.  
    42 However, the distribution width applied to *orientation* (ie, angle-describing)  
    43 parameters is just $\sigma = \mathrm{PD}$. 
     43However, the distribution width applied to *orientation* parameters is just  
     44$\sigma = \mathrm{PD}$. 
    4445 
    4546$N_\sigma$ determines how far into the tails to evaluate the distribution, 
     
    5152 
    5253Users should note that the averaging computation is very intensive. Applying 
    53 polydispersion to multiple parameters at the same time or increasing the 
    54 number of points in the distribution will require patience! However, the 
    55 calculations are generally more robust with more data points or more angles. 
     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  
     57more data points or more angles. 
    5658 
    5759The following distribution functions are provided: 
     
    6971Additional distributions are under consideration. 
    7072 
     73**Beware: when the Polydispersity & Orientational Distribution panel in SasView is** 
     74**first opened, the default distribution for all parameters is the Gaussian Distribution.** 
     75**This may not be suitable. See Suggested Applications below.** 
     76 
    7177.. note:: In 2009 IUPAC decided to introduce the new term 'dispersity' to replace  
    7278           the term 'polydispersity' (see `Pure Appl. Chem., (2009), 81(2),  
    7379           351-353 <http://media.iupac.org/publications/pac/2009/pdf/8102x0351.pdf>`_  
    74            in order to make the terminology describing distributions of properties  
    75            unambiguous. Throughout the SasView documentation we continue to use the  
    76            term polydispersity because one of the consequences of the IUPAC change is  
    77            that orientational polydispersity would not meet their new criteria (which  
    78            requires dispersity to be dimensionless). 
     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  
     83           SasView models. 
    7984 
    8085Suggested Applications 
    8186^^^^^^^^^^^^^^^^^^^^^^ 
    8287 
    83 If applying polydispersion to parameters describing particle sizes, use 
     88If applying polydispersion to parameters describing particle sizes, consider using 
    8489the Lognormal or Schulz distributions. 
    8590 
    8691If applying polydispersion to parameters describing interfacial thicknesses 
    87 or angular orientations, use the Gaussian or Boltzmann distributions. 
     92or angular orientations, consider using the Gaussian or Boltzmann distributions. 
    8893 
    8994If applying polydispersion to parameters describing angles, use the Uniform  
     
    332337^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    333338 
    334 Many commercial Dynamic Light Scattering (DLS) instruments produce a size 
    335 polydispersity parameter, sometimes even given the symbol $p$\ ! This 
    336 parameter is defined as the relative standard deviation coefficient of 
    337 variation of the size distribution and is NOT the same as the polydispersity 
    338 parameters in the Lognormal and Schulz distributions above (though they all 
    339 related) except when the DLS polydispersity parameter is <0.13. 
    340  
    341 .. math:: 
    342  
    343     p_{DLS} = \sqrt(\nu / \bar x^2) 
    344  
    345 where $\nu$ is the variance of the distribution and $\bar x$ is the mean 
    346 value of $x$. 
     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  
     341the polydispersity *PD* parameter used in SasView. 
     342 
     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  
     346ISO 22412:2017 as 
     347 
     348.. math:: 
     349 
     350    PI = \mu_{2} / \bar \Gamma^2 
     351 
     352where $\mu_\text{2}$ is the second cumulant, and $\bar \Gamma^2$ is the  
     353intensity-weighted average value, of the distribution of decay rates. 
     354 
     355*If the distribution of decay rates is Gaussian* then 
     356 
     357.. math:: 
     358 
     359    PI = \sigma^2 / 2\bar \Gamma^2 
     360 
     361where $\sigma$ is the standard deviation, allowing a **Relative Polydispersity (RP)**  
     362to be defined as 
     363 
     364.. math:: 
     365 
     366    RP = \sigma / \bar \Gamma = \sqrt{2 \cdot PI} 
     367 
     368PI values smaller than 0.05 indicate a highly monodisperse system. Values  
     369greater than 0.7 indicate significant polydispersity. 
     370 
     371The **size polydispersity P-parameter** is defined as the relative standard  
     372deviation coefficient of variation   
     373 
     374.. math:: 
     375 
     376    P = \sqrt\nu / \bar R 
     377 
     378where $\nu$ is the variance of the distribution and $\bar R$ is the mean 
     379value of $R$. Here, the product $P \bar R$ is *equal* to the standard  
     380deviation of the Lognormal distribution. 
     381 
     382P values smaller than 0.13 indicate a monodisperse system. 
    347383 
    348384For more information see: 
    349 S King, C Washington & R Heenan, *Phys Chem Chem Phys*, (2005), 7, 143 
     385 
     386`ISO 22412:2017, International Standards Organisation (2017) <https://www.iso.org/standard/65410.html>`_. 
     387 
     388`Polydispersity: What does it mean for DLS and Chromatography <http://www.materials-talks.com/blog/2014/10/23/polydispersity-what-does-it-mean-for-dls-and-chromatography/>`_. 
     389 
     390`Dynamic Light Scattering: Common Terms Defined, Whitepaper WP111214. Malvern Instruments (2011) <http://www.biophysics.bioc.cam.ac.uk/wp-content/uploads/2011/02/DLS_Terms_defined_Malvern.pdf>`_. 
     391 
     392S King, C Washington & R Heenan, *Phys Chem Chem Phys*, (2005), 7, 143. 
     393 
     394T Allen, in *Particle Size Measurement*, 4th Edition, Chapman & Hall, London (1990). 
    350395 
    351396.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 
     
    357402| 2018-03-20 Steve King 
    358403| 2018-04-04 Steve King 
     404| 2018-08-09 Steve King 
  • doc/guide/plugin.rst

    rf796469 r2015f02  
    423423calculations, but instead rely on numerical integration to compute the 
    424424appropriately smeared pattern. 
     425 
     426Each .py file also contains a function:: 
     427 
     428        def random(): 
     429        ... 
     430         
     431This function provides a model-specific random parameter set which shows model  
     432features in the USANS to SANS range.  For example, core-shell sphere sets the  
     433outer radius of the sphere logarithmically in `[20, 20,000]`, which sets the Q  
     434value for the transition from flat to falling.  It then uses a beta distribution  
     435to set the percentage of the shape which is shell, giving a preference for very  
     436thin or very thick shells (but never 0% or 100%).  Using `-sets=10` in sascomp  
     437should show a reasonable variety of curves over the default sascomp q range.   
     438The parameter set is returned as a dictionary of `{parameter: value, ...}`.   
     439Any model parameters not included in the dictionary will default according to  
     440the code in the `_randomize_one()` function from sasmodels/compare.py. 
    425441 
    426442Python Models 
  • doc/guide/scripting.rst

    r4aa5dce rbd7630d  
    1010The key functions are :func:`sasmodels.core.load_model` for loading the 
    1111model definition and compiling the kernel and 
    12 :func:`sasmodels.data.load_data` for calling sasview to load the data. Need 
    13 the data because that defines the resolution function and the q values to 
    14 evaluate. If there is no data, then use :func:`sasmodels.data.empty_data1D` 
    15 or :func:`sasmodels.data.empty_data2D` to create some data with a given $q$. 
    16  
    17 Using sasmodels through bumps 
    18 ============================= 
    19  
    20 With the data and the model, you can wrap it in a *bumps* model with 
     12:func:`sasmodels.data.load_data` for calling sasview to load the data. 
     13 
     14Preparing data 
     15============== 
     16 
     17Usually you will load data via the sasview loader, with the 
     18:func:`sasmodels.data.load_data` function.  For example:: 
     19 
     20    from sasmodels.data import load_data 
     21    data = load_data("sasmodels/example/093191_201.dat") 
     22 
     23You may want to apply a data mask, such a beam stop, and trim high $q$:: 
     24 
     25    from sasmodels.data import set_beam_stop 
     26    set_beam_stop(data, qmin, qmax) 
     27 
     28The :func:`sasmodels.data.set_beam_stop` method simply sets the *mask* 
     29attribute for the data. 
     30 
     31The data defines the resolution function and the q values to evaluate, so 
     32even if you simulating experiments prior to making measurements, you still 
     33need a data object for reference. Use :func:`sasmodels.data.empty_data1D` 
     34or :func:`sasmodels.data.empty_data2D` to create a container with a 
     35given $q$ and $\Delta q/q$.  For example:: 
     36 
     37    import numpy as np 
     38    from sasmodels.data import empty_data1D 
     39 
     40    # 120 points logarithmically spaced from 0.005 to 0.2, with dq/q = 5% 
     41    q = np.logspace(np.log10(5e-3), np.log10(2e-1), 120) 
     42    data = empty_data1D(q, resolution=0.05) 
     43 
     44To use a more realistic model of resolution, or to load data from a file 
     45format not understood by SasView, you can use :class:`sasmodels.data.Data1D` 
     46or :class:`sasmodels.data.Data2D` directly.  The 1D data uses 
     47*x*, *y*, *dx* and *dy* for $x = q$ and $y = I(q)$, and 2D data uses 
     48*x*, *y*, *z*, *dx*, *dy*, *dz* for $x, y = qx, qy$ and $z = I(qx, qy)$. 
     49[Note: internally, the Data2D object uses SasView conventions, 
     50*qx_data*, *qy_data*, *data*, *dqx_data*, *dqy_data*, and *err_data*.] 
     51 
     52For USANS data, use 1D data, but set *dxl* and *dxw* attributes to 
     53indicate slit resolution:: 
     54 
     55    data.dxl = 0.117 
     56 
     57See :func:`sasmodels.resolution.slit_resolution` for details. 
     58 
     59SESANS data is more complicated; if your SESANS format is not supported by 
     60SasView you need to define a number of attributes beyond *x*, *y*.  For 
     61example:: 
     62 
     63    SElength = np.linspace(0, 2400, 61) # [A] 
     64    data = np.ones_like(SElength) 
     65    err_data = np.ones_like(SElength)*0.03 
     66 
     67    class Source: 
     68        wavelength = 6 # [A] 
     69        wavelength_unit = "A" 
     70    class Sample: 
     71        zacceptance = 0.1 # [A^-1] 
     72        thickness = 0.2 # [cm] 
     73 
     74    class SESANSData1D: 
     75        #q_zmax = 0.23 # [A^-1] 
     76        lam = 0.2 # [nm] 
     77        x = SElength 
     78        y = data 
     79        dy = err_data 
     80        sample = Sample() 
     81    data = SESANSData1D() 
     82 
     83    x, y = ... # create or load sesans 
     84    data = smd.Data 
     85 
     86The *data* module defines various data plotters as well. 
     87 
     88Using sasmodels directly 
     89======================== 
     90 
     91Once you have a computational kernel and a data object, you can evaluate 
     92the model for various parameters using 
     93:class:`sasmodels.direct_model.DirectModel`.  The resulting object *f* 
     94will be callable as *f(par=value, ...)*, returning the $I(q)$ for the $q$ 
     95values in the data.  For example:: 
     96 
     97    import numpy as np 
     98    from sasmodels.data import empty_data1D 
     99    from sasmodels.core import load_model 
     100    from sasmodels.direct_model import DirectModel 
     101 
     102    # 120 points logarithmically spaced from 0.005 to 0.2, with dq/q = 5% 
     103    q = np.logspace(np.log10(5e-3), np.log10(2e-1), 120) 
     104    data = empty_data1D(q, resolution=0.05) 
     105    kernel = load_model("ellipsoid) 
     106    f = DirectModel(data, kernel) 
     107    Iq = f(radius_polar=100) 
     108 
     109Polydispersity information is set with special parameter names: 
     110 
     111    * *par_pd* for polydispersity width, $\Delta p/p$, 
     112    * *par_pd_n* for the number of points in the distribution, 
     113    * *par_pd_type* for the distribution type (as a string), and 
     114    * *par_pd_nsigmas* for the limits of the distribution. 
     115 
     116Using sasmodels through the bumps optimizer 
     117=========================================== 
     118 
     119Like DirectModel, you can wrap data and a kernel in a *bumps* model with 
    21120class:`sasmodels.bumps_model.Model` and create an 
    22 class:`sasmodels.bump_model.Experiment` that you can fit with the *bumps* 
     121class:`sasmodels.bumps_model.Experiment` that you can fit with the *bumps* 
    23122interface. Here is an example from the *example* directory such as 
    24123*example/model.py*:: 
     
    75174    SasViewCom bumps.cli example/model.py --preview 
    76175 
    77 Using sasmodels directly 
    78 ======================== 
    79  
    80 Bumps has a notion of parameter boxes in which you can set and retrieve 
    81 values.  Instead of using bumps, you can create a directly callable function 
    82 with :class:`sasmodels.direct_model.DirectModel`.  The resulting object *f* 
    83 will be callable as *f(par=value, ...)*, returning the $I(q)$ for the $q$ 
    84 values in the data.  Polydisperse parameters use the same naming conventions 
    85 as in the bumps model, with e.g., radius_pd being the polydispersity associated 
    86 with radius. 
     176Calling the computation kernel 
     177============================== 
    87178 
    88179Getting a simple function that you can call on a set of q values and return 
  • doc/rst_prolog

    r30b60d2 r2c12061  
    99.. |Ang^-3| replace:: |Ang|\ :sup:`-3` 
    1010.. |Ang^-4| replace:: |Ang|\ :sup:`-4` 
     11.. |nm^-1| replace:: nm\ :sup:`-1` 
    1112.. |cm^-1| replace:: cm\ :sup:`-1` 
    1213.. |cm^2| replace:: cm\ :sup:`2` 
  • sasmodels/compare.py

    raf7a97c rbd7630d  
    12881288 
    12891289    if opts['datafile'] is not None: 
    1290         data = load_data(os.path.expanduser(opts['datafile'])) 
     1290        data0 = load_data(os.path.expanduser(opts['datafile'])) 
     1291        data = data0, data0 
    12911292    else: 
    12921293        # Hack around the fact that make_data doesn't take a pair of resolutions 
  • sasmodels/core.py

    r4341dd4 r2dcd6e7  
    233233        if not callable(model_info.Iq): 
    234234            source = generate.make_source(model_info)['dll'] 
    235             old_path = kerneldll.DLL_PATH 
     235            old_path = kerneldll.SAS_DLL_PATH 
    236236            try: 
    237                 kerneldll.DLL_PATH = path 
     237                kerneldll.SAS_DLL_PATH = path 
    238238                dll = kerneldll.make_dll(source, model_info, dtype=numpy_dtype) 
    239239            finally: 
    240                 kerneldll.DLL_PATH = old_path 
     240                kerneldll.SAS_DLL_PATH = old_path 
    241241            compiled_dlls.append(dll) 
    242242    return compiled_dlls 
  • sasmodels/data.py

    r581661f rbd7630d  
    183183    *x* is spin echo length and *y* is polarization (P/P0). 
    184184    """ 
     185    isSesans = True 
    185186    def __init__(self, **kw): 
    186187        Data1D.__init__(self, **kw) 
     
    301302        self.wavelength_unit = "A" 
    302303 
     304class Sample(object): 
     305    """ 
     306    Sample attributes. 
     307    """ 
     308    def __init__(self): 
     309        # type: () -> None 
     310        pass 
    303311 
    304312def empty_data1D(q, resolution=0.0, L=0., dL=0.): 
  • sasmodels/direct_model.py

    r1a8c11c r7b9e4dd  
    3131from . import resolution2d 
    3232from .details import make_kernel_args, dispersion_mesh 
     33from .modelinfo import DEFAULT_BACKGROUND 
    3334 
    3435# pylint: disable=unused-import 
     
    349350 
    350351        # Need to pull background out of resolution for multiple scattering 
    351         background = pars.get('background', 0.) 
     352        background = pars.get('background', DEFAULT_BACKGROUND) 
    352353        pars = pars.copy() 
    353354        pars['background'] = 0. 
  • sasmodels/generate.py

    rd86f0fc r6e45516  
    965965    docs = model_info.docs if model_info.docs is not None else "" 
    966966    docs = convert_section_titles_to_boldface(docs) 
    967     pars = make_partable(model_info.parameters.COMMON 
    968                          + model_info.parameters.kernel_parameters) 
     967    if model_info.structure_factor: 
     968        pars = model_info.parameters.kernel_parameters 
     969    else: 
     970        pars = model_info.parameters.COMMON + model_info.parameters.kernel_parameters 
     971    partable = make_partable(pars) 
    969972    subst = dict(id=model_info.id.replace('_', '-'), 
    970973                 name=model_info.name, 
    971974                 title=model_info.title, 
    972                  parameters=pars, 
     975                 parameters=partable, 
    973976                 returns=Sq_units if model_info.structure_factor else Iq_units, 
    974977                 docs=docs) 
  • sasmodels/kernel_iq.c

    r7c35fda r70530778  
    8484  out_spin = clip(out_spin, 0.0, 1.0); 
    8585  // Previous version of this function took the square root of the weights, 
    86   // under the assumption that  
     86  // under the assumption that 
    8787  // 
    8888  //     w*I(q, rho1, rho2, ...) = I(q, sqrt(w)*rho1, sqrt(w)*rho2, ...) 
     
    188188    QACRotation *rotation, 
    189189    double qx, double qy, 
    190     double *qa_out, double *qc_out) 
     190    double *qab_out, double *qc_out) 
    191191{ 
     192    // Indirect calculation of qab, from qab^2 = |q|^2 - qc^2 
    192193    const double dqc = rotation->R31*qx + rotation->R32*qy; 
    193     // Indirect calculation of qab, from qab^2 = |q|^2 - qc^2 
    194     const double dqa = sqrt(-dqc*dqc + qx*qx + qy*qy); 
    195  
    196     *qa_out = dqa; 
     194    const double dqab_sq = -dqc*dqc + qx*qx + qy*qy; 
     195    //*qab_out = sqrt(fabs(dqab_sq)); 
     196    *qab_out = dqab_sq > 0.0 ? sqrt(dqab_sq) : 0.0; 
    197197    *qc_out = dqc; 
    198198} 
  • sasmodels/modelinfo.py

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

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

    r2d81cfe re31b19a  
    55The output of the 2D scattering intensity function for oriented core-shell 
    66cylinders is given by (Kline, 2006 [#kline]_). The form factor is normalized 
    7 by the particle volume. 
     7by the particle volume. Note that in this model the shell envelops the entire 
     8core so that besides a "sleeve" around the core, the shell also provides two 
     9flat end caps of thickness = shell thickness. In other words the length of the 
     10total cyclinder is the length of the core cylinder plus twice the thickness of 
     11the shell. If no end caps are desired one should use the 
     12:ref:`core-shell-bicelle` and set the thickness of the end caps (in this case 
     13the "thick_face") to zero. 
    814 
    915.. math:: 
     
    3339 
    3440and $\alpha$ is the angle between the axis of the cylinder and $\vec q$, 
    35 $V_s$ is the volume of the outer shell (i.e. the total volume, including 
    36 the shell), $V_c$ is the volume of the core, $L$ is the length of the core, 
     41$V_s$ is the total volume (i.e. including both the core and the outer shell), 
     42$V_c$ is the volume of the core, $L$ is the length of the core, 
    3743$R$ is the radius of the core, $T$ is the thickness of the shell, $\rho_c$ 
    3844is the scattering length density of the core, $\rho_s$ is the scattering 
     
    135141    return 0.5 * (ddd) ** (1. / 3.) 
    136142 
    137 def VR(radius, thickness, length): 
    138     """ 
    139     Returns volume ratio 
    140     """ 
    141     whole = pi * (radius + thickness) ** 2 * (length + 2 * thickness) 
    142     core = pi * radius ** 2 * length 
    143     return whole, whole - core 
    144  
    145143def random(): 
    146144    outer_radius = 10**np.random.uniform(1, 4.7) 
  • sasmodels/models/core_shell_sphere.py

    rdc76240 rda1c8d1  
    8989    return radius + thickness 
    9090 
    91 def VR(radius, thickness): 
    92     """ 
    93         Volume ratio 
    94         @param radius: core radius 
    95         @param thickness: shell thickness 
    96     """ 
    97     return (1, 1) 
    98     whole = 4.0/3.0 * pi * (radius + thickness)**3 
    99     core = 4.0/3.0 * pi * radius**3 
    100     return whole, whole - core 
    101  
    10291def random(): 
    10392    outer_radius = 10**np.random.uniform(1.3, 4.3) 
     
    114103tests = [ 
    115104    [{'radius': 20.0, 'thickness': 10.0}, 'ER', 30.0], 
    116     # TODO: VR test suppressed until we sort out new product model 
    117     # and determine what to do with volume ratio. 
    118     #[{'radius': 20.0, 'thickness': 10.0}, 'VR', 0.703703704], 
    119105 
    120106    # The SasView test result was 0.00169, with a background of 0.001 
  • sasmodels/models/ellipsoid.py

    r2d81cfe r0168844  
    125125import numpy as np 
    126126from numpy import inf, sin, cos, pi 
     127 
     128try: 
     129    from numpy import cbrt 
     130except ImportError: 
     131    def cbrt(x): return x ** (1.0/3.0) 
    127132 
    128133name = "ellipsoid" 
     
    170175    idx = radius_polar < radius_equatorial 
    171176    ee[idx] = (radius_equatorial[idx] ** 2 - radius_polar[idx] ** 2) / radius_equatorial[idx] ** 2 
    172     idx = radius_polar == radius_equatorial 
    173     ee[idx] = 2 * radius_polar[idx] 
    174     valid = (radius_polar * radius_equatorial != 0) 
     177    valid = (radius_polar * radius_equatorial != 0) & (radius_polar != radius_equatorial) 
    175178    bd = 1.0 - ee[valid] 
    176179    e1 = np.sqrt(ee[valid]) 
     
    179182    b2 = 1.0 + bd / 2 / e1 * np.log(bL) 
    180183    delta = 0.75 * b1 * b2 
    181  
    182     ddd = np.zeros_like(radius_polar) 
    183     ddd[valid] = 2.0 * (delta + 1.0) * radius_polar * radius_equatorial ** 2 
    184     return 0.5 * ddd ** (1.0 / 3.0) 
     184    ddd = 2.0 * (delta + 1.0) * (radius_polar * radius_equatorial**2)[valid] 
     185 
     186    r = np.zeros_like(radius_polar) 
     187    r[valid] = 0.5 * cbrt(ddd) 
     188    idx = radius_polar == radius_equatorial 
     189    r[idx] = radius_polar[idx] 
     190    return r 
    185191 
    186192def random(): 
  • sasmodels/models/fractal_core_shell.py

    ref07e95 reb3eb38  
    8888    ["sld_shell",   "1e-6/Ang^2", 2.0,  [-inf, inf], "sld",    "Sphere shell scattering length density"], 
    8989    ["sld_solvent", "1e-6/Ang^2", 3.0,  [-inf, inf], "sld",    "Solvent scattering length density"], 
    90     ["volfraction", "",           1.0,  [0.0, inf],  "",       "Volume fraction of building block spheres"], 
     90    ["volfraction", "",           0.05,  [0.0, inf],  "",       "Volume fraction of building block spheres"], 
    9191    ["fractal_dim",    "",        2.0,  [0.0, 6.0],  "",       "Fractal dimension"], 
    9292    ["cor_length",  "Ang",      100.0,  [0.0, inf],  "",       "Correlation length of fractal-like aggregates"], 
     
    134134    return radius + thickness 
    135135 
    136 def VR(radius, thickness): 
    137     """ 
    138         Volume ratio 
    139         @param radius: core radius 
    140         @param thickness: shell thickness 
    141     """ 
    142     whole = 4.0/3.0 * pi * (radius + thickness)**3 
    143     core = 4.0/3.0 * pi * radius**3 
    144     return whole, whole-core 
     136tests = [[{'radius': 20.0, 'thickness': 10.0}, 'ER', 30.0], 
    145137 
    146 tests = [[{'radius': 20.0, 'thickness': 10.0}, 'ER', 30.0], 
    147          [{'radius': 20.0, 'thickness': 10.0}, 'VR', 0.703703704]] 
    148  
    149 #         # The SasView test result was 0.00169, with a background of 0.001 
    150 #         # They are however wrong as we now know.  IGOR might be a more 
    151 #         # appropriate source. Otherwise will just have to assume this is now 
    152 #         # correct and self generate a correct answer for the future. Until we 
    153 #         # figure it out leave the tests commented out 
    154 #         [{'radius': 60.0, 
    155 #           'thickness': 10.0, 
    156 #           'sld_core': 1.0, 
    157 #           'sld_shell': 2.0, 
    158 #           'sld_solvent': 3.0, 
    159 #           'background': 0.0 
    160 #          }, 0.015211, 692.84]] 
     138#         # At some point the SasView 3.x test result was deemed incorrect. The 
     139          #following tests were verified against NIST IGOR macros ver 7.850. 
     140          #NOTE: NIST macros do only provide for a polydispers core (no option 
     141          #for a poly shell or for a monodisperse core.  The results seemed 
     142          #extremely sensitive to the core PD, varying non monotonically all 
     143          #the way to a PD of 1e-6. From 1e-6 to 1e-9 no changes in the 
     144          #results were observed and the values below were taken using PD=1e-9. 
     145          #Non-monotonically = I(0.001)=188 to 140 to 177 back to 160 etc. 
     146         [{'radius': 20.0, 
     147           'thickness': 5.0, 
     148           'sld_core': 3.5, 
     149           'sld_shell': 1.0, 
     150           'sld_solvent': 6.35, 
     151           'volfraction': 0.05, 
     152           'background': 0.0}, 
     153           [0.001,0.00291,0.0107944,0.029923,0.100726,0.476304], 
     154           [177.146,165.151,84.1596,20.1466,1.40906,0.00622666]]] 
  • sasmodels/models/hollow_cylinder.py

    r2d81cfe r455aaa1  
    11r""" 
     2Definition 
     3---------- 
     4 
    25This model provides the form factor, $P(q)$, for a monodisperse hollow right 
    3 angle circular cylinder (rigid tube) where the form factor is normalized by the 
    4 volume of the tube (i.e. not by the external volume). 
     6angle circular cylinder (rigid tube) where the The inside and outside of the 
     7hollow cylinder are assumed to have the same SLD and the form factor is thus 
     8normalized by the volume of the tube (i.e. not by the total cylinder volume). 
    59 
    610.. math:: 
     
    812    P(q) = \text{scale} \left<F^2\right>/V_\text{shell} + \text{background} 
    913 
    10 where the averaging $\left<\ldots\right>$ is applied only for the 1D calculation. 
     14where the averaging $\left<\ldots\right>$ is applied only for the 1D 
     15calculation. If Intensity is given on an absolute scale, the scale factor here 
     16is the volume fraction of the shell.  This differs from 
     17the :ref:`core-shell-cylinder` in that, in that case, scale is the volume 
     18fraction of the entire cylinder (core+shell). The application might be for a 
     19bilayer which wraps into a hollow tube and the volume fraction of material is 
     20all in the shell, whereas the :ref:`core-shell-cylinder` model might be used for 
     21a cylindrical micelle where the tails in the core have a different SLD than the 
     22headgroups (in the shell) and the volume fraction of material comes fromm the 
     23whole cyclinder.  NOTE: the hollow_cylinder represents a tube whereas the 
     24core_shell_cylinder includes a shell layer covering the ends (end caps) as well. 
    1125 
    12 The inside and outside of the hollow cylinder are assumed have the same SLD. 
    13  
    14 Definition 
    15 ---------- 
    1626 
    1727The 1D scattering intensity is calculated in the following way (Guinier, 1955) 
     
    4858---------- 
    4959 
    50 L A Feigin and D I Svergun, *Structure Analysis by Small-Angle X-Ray and 
    51 Neutron Scattering*, Plenum Press, New York, (1987) 
     60.. [#] L A Feigin and D I Svergun, *Structure Analysis by Small-Angle X-Ray and 
     61   Neutron Scattering*, Plenum Press, New York, (1987) 
    5262 
    5363Authorship and Verification 
     
    5565 
    5666* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    57 * **Last Modified by:** Richard Heenan **Date:** October 06, 2016 
    58    (reparametrised to use thickness, not outer radius) 
    59 * **Last Reviewed by:** Richard Heenan **Date:** October 06, 2016 
     67* **Last Modified by:** Paul Butler **Date:** September 06, 2018 
     68   (corrected VR calculation) 
     69* **Last Reviewed by:** Paul Butler **Date:** September 06, 2018 
    6070""" 
    6171 
     
    120130    vol_total = pi*router*router*length 
    121131    vol_shell = vol_total - vol_core 
    122     return vol_shell, vol_total 
     132    return vol_total, vol_shell 
    123133 
    124134def random(): 
     
    151161tests = [ 
    152162    [{}, 0.00005, 1764.926], 
    153     [{}, 'VR', 1.8], 
     163    [{}, 'VR', 0.55555556], 
    154164    [{}, 0.001, 1756.76], 
    155165    [{}, (qx, qy), 2.36885476192], 
  • sasmodels/models/hollow_rectangular_prism.py

    r0e55afe r455aaa1  
    22# Note: model title and parameter table are inserted automatically 
    33r""" 
    4  
    5 This model provides the form factor, $P(q)$, for a hollow rectangular 
    6 parallelepiped with a wall of thickness $\Delta$. 
    7  
    8  
    94Definition 
    105---------- 
    116 
    12 The 1D scattering intensity for this model is calculated by forming 
    13 the difference of the amplitudes of two massive parallelepipeds 
    14 differing in their outermost dimensions in each direction by the 
    15 same length increment $2\Delta$ (Nayuk, 2012). 
     7This model provides the form factor, $P(q)$, for a hollow rectangular 
     8parallelepiped with a wall of thickness $\Delta$. The 1D scattering intensity 
     9for this model is calculated by forming the difference of the amplitudes of two 
     10massive parallelepipeds differing in their outermost dimensions in each 
     11direction by the same length increment $2\Delta$ (\ [#Nayuk2012]_ Nayuk, 2012). 
    1612 
    1713As in the case of the massive parallelepiped model (:ref:`rectangular-prism`), 
     
    6157  \rho_\text{solvent})^2 \times P(q) + \text{background} 
    6258 
    63 where $\rho_\text{p}$ is the scattering length of the parallelepiped, 
    64 $\rho_\text{solvent}$ is the scattering length of the solvent, 
     59where $\rho_\text{p}$ is the scattering length density of the parallelepiped, 
     60$\rho_\text{solvent}$ is the scattering length density of the solvent, 
    6561and (if the data are in absolute units) *scale* represents the volume fraction 
    66 (which is unitless). 
     62(which is unitless) of the rectangular shell of material (i.e. not including 
     63the volume of the solvent filled core). 
    6764 
    6865For 2d data the orientation of the particle is required, described using 
     
    7370 
    7471For 2d, constraints must be applied during fitting to ensure that the inequality 
    75 $A < B < C$ is not violated, and hence the correct definition of angles is preserved. The calculation will not report an error, 
    76 but the results may be not correct. 
     72$A < B < C$ is not violated, and hence the correct definition of angles is 
     73preserved. The calculation will not report an error if the inequality is *not* 
     74preserved, but the results may be not correct. 
    7775 
    7876.. figure:: img/parallelepiped_angle_definition.png 
     
    9997---------- 
    10098 
    101 R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 
     99.. [#Nayuk2012] R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 
     100 
     101 
     102Authorship and Verification 
     103---------------------------- 
     104 
     105* **Author:** Miguel Gonzales **Date:** February 26, 2016 
     106* **Last Modified by:** Paul Kienzle **Date:** December 14, 2017 
     107* **Last Reviewed by:** Paul Butler **Date:** September 06, 2018 
    102108""" 
    103109 
  • sasmodels/models/hollow_rectangular_prism_thin_walls.py

    r2d81cfe r6e7d7b6  
    22# Note: model title and parameter table are inserted automatically 
    33r""" 
     4Definition 
     5---------- 
     6 
    47 
    58This model provides the form factor, $P(q)$, for a hollow rectangular 
    69prism with infinitely thin walls. It computes only the 1D scattering, not the 2D. 
    7  
    8  
    9 Definition 
    10 ---------- 
    11  
    1210The 1D scattering intensity for this model is calculated according to the 
    13 equations given by Nayuk and Huber (Nayuk, 2012). 
     11equations given by Nayuk and Huber\ [#Nayuk2012]_. 
    1412 
    1513Assuming a hollow parallelepiped with infinitely thin walls, edge lengths 
     
    5553  I(q) = \text{scale} \times V \times (\rho_\text{p} - \rho_\text{solvent})^2 \times P(q) 
    5654 
    57 where $V$ is the volume of the rectangular prism, $\rho_\text{p}$ 
    58 is the scattering length of the parallelepiped, $\rho_\text{solvent}$ 
    59 is the scattering length of the solvent, and (if the data are in absolute 
    60 units) *scale* represents the volume fraction (which is unitless). 
     55where $V$ is the surface area of the rectangular prism, $\rho_\text{p}$ 
     56is the scattering length density of the parallelepiped, $\rho_\text{solvent}$ 
     57is the scattering length density of the solvent, and (if the data are in 
     58absolute units) *scale* is related to the total surface area. 
    6159 
    6260**The 2D scattering intensity is not computed by this model.** 
     
    6765 
    6866Validation of the code was conducted  by qualitatively comparing the output 
    69 of the 1D model to the curves shown in (Nayuk, 2012). 
     67of the 1D model to the curves shown in (Nayuk, 2012\ [#Nayuk2012]_). 
    7068 
    7169 
     
    7371---------- 
    7472 
    75 R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 
     73.. [#Nayuk2012] R Nayuk and K Huber, *Z. Phys. Chem.*, 226 (2012) 837-854 
     74 
     75 
     76Authorship and Verification 
     77---------------------------- 
     78 
     79* **Author:** Miguel Gonzales **Date:** February 26, 2016 
     80* **Last Modified by:** Paul Kienzle **Date:** October 15, 2016 
     81* **Last Reviewed by:** Paul Butler **Date:** September 07, 2018 
    7682""" 
    7783 
  • sasmodels/models/spherical_sld.py

    r2d81cfe r5601947  
    11r""" 
     2Definition 
     3---------- 
     4 
    25Similarly to the onion, this model provides the form factor, $P(q)$, for 
    36a multi-shell sphere, where the interface between the each neighboring 
     
    1619interface. The form factor is normalized by the total volume of the sphere. 
    1720 
    18 Interface shapes are as follows:: 
     21Interface shapes are as follows: 
    1922 
    2023    0: erf($\nu z$) 
     24     
    2125    1: Rpow($z^\nu$) 
     26     
    2227    2: Lpow($z^\nu$) 
     28     
    2329    3: Rexp($-\nu z$) 
     30     
    2431    4: Lexp($-\nu z$) 
    25  
    26 Definition 
    27 ---------- 
    2832 
    2933The form factor $P(q)$ in 1D is calculated by: 
     
    174178    when $P(Q) * S(Q)$ is applied. 
    175179 
     180 
    176181References 
    177182---------- 
    178 L A Feigin and D I Svergun, Structure Analysis by Small-Angle X-Ray 
    179 and Neutron Scattering, Plenum Press, New York, (1987) 
     183 
     184.. [#] L A Feigin and D I Svergun, Structure Analysis by Small-Angle X-Ray 
     185   and Neutron Scattering, Plenum Press, New York, (1987) 
     186 
     187 
     188Authorship and Verification 
     189---------------------------- 
     190 
     191* **Author:** Jae-Hie Cho **Date:** Nov 1, 2010 
     192* **Last Modified by:** Paul Kienzle **Date:** Dec 20, 2016 
     193* **Last Reviewed by:** Paul Butler **Date:** September 8, 2018 
    180194""" 
    181195 
  • sasmodels/models/spinodal.py

    ref07e95 r475ff58  
    33---------- 
    44 
    5 This model calculates the SAS signal of a phase separating solution 
    6 under spinodal decomposition. The scattering intensity $I(q)$ is calculated as 
     5This model calculates the SAS signal of a phase separating system  
     6undergoing spinodal decomposition. The scattering intensity $I(q)$ is calculated  
     7as  
    78 
    89.. math:: 
    910    I(q) = I_{max}\frac{(1+\gamma/2)x^2}{\gamma/2+x^{2+\gamma}}+B 
    1011 
    11 where $x=q/q_0$ and $B$ is a flat background. The characteristic structure 
    12 length scales with the correlation peak at $q_0$. The exponent $\gamma$ is 
    13 equal to $d+1$ with d the dimensionality of the off-critical concentration 
    14 mixtures. A transition to $\gamma=2d$ is seen near the percolation threshold 
    15 into the critical concentration regime. 
     12where $x=q/q_0$, $q_0$ is the peak position, $I_{max}$ is the intensity  
     13at $q_0$ (parameterised as the $scale$ parameter), and $B$ is a flat  
     14background. The spinodal wavelength is given by $2\pi/q_0$.  
     15 
     16The exponent $\gamma$ is equal to $d+1$ for off-critical concentration  
     17mixtures (smooth interfaces) and $2d$ for critical concentration mixtures  
     18(entangled interfaces), where $d$ is the dimensionality (ie, 1, 2, 3) of the  
     19system. Thus 2 <= $\gamma$ <= 6. A transition from $\gamma=d+1$ to $\gamma=2d$  
     20is expected near the percolation threshold.  
     21 
     22As this function tends to zero as $q$ tends to zero, in practice it may be  
     23necessary to combine it with another function describing the low-angle  
     24scattering, or to simply omit the low-angle scattering from the fit. 
    1625 
    1726References 
     
    2231Physica A 123,497 (1984). 
    2332 
    24 Authorship and Verification 
    25 ---------------------------- 
     33Revision History 
     34---------------- 
    2635 
    27 * **Author:** Dirk Honecker **Date:** Oct 7, 2016 
     36* **Author:**  Dirk Honecker **Date:** Oct 7, 2016 
     37* **Revised:** Steve King    **Date:** Sep 7, 2018 
    2838""" 
    2939 
     
    3444title = "Spinodal decomposition model" 
    3545description = """\ 
    36       I(q) = scale ((1+gamma/2)x^2)/(gamma/2+x^(2+gamma))+background 
     46      I(q) = Imax ((1+gamma/2)x^2)/(gamma/2+x^(2+gamma)) + background 
    3747 
    3848      List of default parameters: 
    39       scale = scaling 
    40       gamma = exponent 
    41       x = q/q_0 
     49       
     50      Imax = correlation peak intensity at q_0 
     51      background = incoherent background 
     52      gamma = exponent (see model documentation) 
    4253      q_0 = correlation peak position [1/A] 
    43       background = Incoherent background""" 
     54      x = q/q_0""" 
     55       
    4456category = "shape-independent" 
    4557 
  • sasmodels/models/vesicle.py

    ref07e95 rb477605  
    33---------- 
    44 
    5 The 1D scattering intensity is calculated in the following way (Guinier, 1955) 
     5This model provides the form factor, *P(q)*, for an unilamellar vesicle and is 
     6effectively identical to the hollow sphere reparameterized to be 
     7more intuitive for a vesicle and normalizing the form factor by the volume of 
     8the shell. The 1D scattering intensity is calculated in the following way 
     9(Guinier,1955\ [#Guinier1955]_) 
    610 
    711.. math:: 
     
    5357---------- 
    5458 
    55 A Guinier and G. Fournet, *Small-Angle Scattering of X-Rays*, John Wiley and 
    56 Sons, New York, (1955) 
     59.. [#Guinier1955] A Guinier and G. Fournet, *Small-Angle Scattering of X-Rays*, John Wiley and 
     60   Sons, New York, (1955) 
     61 
     62 
     63Authorship and Verification 
     64---------------------------- 
    5765 
    5866* **Author:** NIST IGOR/DANSE **Date:** pre 2010 
    5967* **Last Modified by:** Paul Butler **Date:** March 20, 2016 
    60 * **Last Reviewed by:** Paul Butler **Date:** March 20, 2016 
     68* **Last Reviewed by:** Paul Butler **Date:** September 7, 2018 
    6169""" 
    6270 
     
    6573 
    6674name = "vesicle" 
    67 title = "This model provides the form factor, *P(q)*, for an unilamellar \ 
    68     vesicle. This is model is effectively identical to the hollow sphere \ 
    69     reparameterized to be more intuitive for a vesicle and normalizing the \ 
    70     form factor by the volume of the shell." 
     75title = "Vesicle model representing a hollow sphere" 
    7176description = """ 
    7277    Model parameters: 
  • sasmodels/resolution.py

    r0b9c6df r9e7837a  
    2020MINIMUM_RESOLUTION = 1e-8 
    2121MINIMUM_ABSOLUTE_Q = 0.02  # relative to the minimum q in the data 
    22 PINHOLE_N_SIGMA = 2.5 # From: Barker & Pedersen 1995 JAC 
     22# According to (Barker & Pedersen 1995 JAC), 2.5 sigma is a good limit. 
     23# According to simulations with github.com:scattering/sansresolution.git 
     24# it is better to use asymmetric bounds (2.5, 3.0) 
     25PINHOLE_N_SIGMA = (2.5, 3.0) 
    2326 
    2427class Resolution(object): 
     
    9093        # from the geometry, they may appear since we are using a truncated 
    9194        # gaussian to represent resolution rather than a skew distribution. 
    92         cutoff = MINIMUM_ABSOLUTE_Q*np.min(self.q) 
    93         self.q_calc = self.q_calc[self.q_calc >= cutoff] 
     95        #cutoff = MINIMUM_ABSOLUTE_Q*np.min(self.q) 
     96        #self.q_calc = self.q_calc[self.q_calc >= cutoff] 
    9497 
    9598        # Build weight matrix from calculated q values 
     
    188191    cdf = erf((edges[:, None] - q[None, :]) / (sqrt(2.0)*q_width)[None, :]) 
    189192    weights = cdf[1:] - cdf[:-1] 
    190     # Limit q range to +/- 2.5 sigma 
    191     qhigh = q + nsigma*q_width 
    192     #qlow = q - nsigma*q_width  # linear limits 
    193     qlow = q*q/qhigh  # log limits 
     193    # Limit q range to (-2.5,+3) sigma 
     194    try: 
     195        nsigma_low, nsigma_high = nsigma 
     196    except TypeError: 
     197        nsigma_low = nsigma_high = nsigma 
     198    qhigh = q + nsigma_high*q_width 
     199    qlow = q - nsigma_low*q_width  # linear limits 
     200    ##qlow = q*q/qhigh  # log limits 
    194201    weights[q_calc[:, None] < qlow[None, :]] = 0. 
    195202    weights[q_calc[:, None] > qhigh[None, :]] = 0. 
     
    365372 
    366373 
    367 def pinhole_extend_q(q, q_width, nsigma=3): 
     374def pinhole_extend_q(q, q_width, nsigma=PINHOLE_N_SIGMA): 
    368375    """ 
    369376    Given *q* and *q_width*, find a set of sampling points *q_calc* so 
     
    371378    function. 
    372379    """ 
    373     q_min, q_max = np.min(q - nsigma*q_width), np.max(q + nsigma*q_width) 
     380    try: 
     381        nsigma_low, nsigma_high = nsigma 
     382    except TypeError: 
     383        nsigma_low = nsigma_high = nsigma 
     384    q_min, q_max = np.min(q - nsigma_low*q_width), np.max(q + nsigma_high*q_width) 
    374385    return linear_extrapolation(q, q_min, q_max) 
    375386 
  • sasmodels/kernelpy.py

    r108e70e r12eec1e  
    3737        self.info = model_info 
    3838        self.dtype = np.dtype('d') 
    39         logger.info("load python model " + self.info.name) 
     39        logger.info("make python model " + self.info.name) 
    4040 
    4141    def make_kernel(self, q_vectors): 
  • sasmodels/model_test.py

    r012cd34 r12eec1e  
    4747import sys 
    4848import unittest 
     49import traceback 
    4950 
    5051try: 
     
    7475# pylint: enable=unused-import 
    7576 
    76  
    7777def make_suite(loaders, models): 
    7878    # type: (List[str], List[str]) -> unittest.TestSuite 
     
    8686    *models* is the list of models to test, or *["all"]* to test all models. 
    8787    """ 
    88     ModelTestCase = _hide_model_case_from_nose() 
    8988    suite = unittest.TestSuite() 
    9089 
     
    9594        skip = [] 
    9695    for model_name in models: 
    97         if model_name in skip: 
    98             continue 
    99         model_info = load_model_info(model_name) 
    100  
    101         #print('------') 
    102         #print('found tests in', model_name) 
    103         #print('------') 
    104  
    105         # if ispy then use the dll loader to call pykernel 
    106         # don't try to call cl kernel since it will not be 
    107         # available in some environmentes. 
    108         is_py = callable(model_info.Iq) 
    109  
    110         # Some OpenCL drivers seem to be flaky, and are not producing the 
    111         # expected result.  Since we don't have known test values yet for 
    112         # all of our models, we are instead going to compare the results 
    113         # for the 'smoke test' (that is, evaluation at q=0.1 for the default 
    114         # parameters just to see that the model runs to completion) between 
    115         # the OpenCL and the DLL.  To do this, we define a 'stash' which is 
    116         # shared between OpenCL and DLL tests.  This is just a list.  If the 
    117         # list is empty (which it will be when DLL runs, if the DLL runs 
    118         # first), then the results are appended to the list.  If the list 
    119         # is not empty (which it will be when OpenCL runs second), the results 
    120         # are compared to the results stored in the first element of the list. 
    121         # This is a horrible stateful hack which only makes sense because the 
    122         # test suite is thrown away after being run once. 
    123         stash = [] 
    124  
    125         if is_py:  # kernel implemented in python 
    126             test_name = "%s-python"%model_name 
    127             test_method_name = "test_%s_python" % model_info.id 
     96        if model_name not in skip: 
     97            model_info = load_model_info(model_name) 
     98            _add_model_to_suite(loaders, suite, model_info) 
     99 
     100    return suite 
     101 
     102def _add_model_to_suite(loaders, suite, model_info): 
     103    ModelTestCase = _hide_model_case_from_nose() 
     104 
     105    #print('------') 
     106    #print('found tests in', model_name) 
     107    #print('------') 
     108 
     109    # if ispy then use the dll loader to call pykernel 
     110    # don't try to call cl kernel since it will not be 
     111    # available in some environmentes. 
     112    is_py = callable(model_info.Iq) 
     113 
     114    # Some OpenCL drivers seem to be flaky, and are not producing the 
     115    # expected result.  Since we don't have known test values yet for 
     116    # all of our models, we are instead going to compare the results 
     117    # for the 'smoke test' (that is, evaluation at q=0.1 for the default 
     118    # parameters just to see that the model runs to completion) between 
     119    # the OpenCL and the DLL.  To do this, we define a 'stash' which is 
     120    # shared between OpenCL and DLL tests.  This is just a list.  If the 
     121    # list is empty (which it will be when DLL runs, if the DLL runs 
     122    # first), then the results are appended to the list.  If the list 
     123    # is not empty (which it will be when OpenCL runs second), the results 
     124    # are compared to the results stored in the first element of the list. 
     125    # This is a horrible stateful hack which only makes sense because the 
     126    # test suite is thrown away after being run once. 
     127    stash = [] 
     128 
     129    if is_py:  # kernel implemented in python 
     130        test_name = "%s-python"%model_info.name 
     131        test_method_name = "test_%s_python" % model_info.id 
     132        test = ModelTestCase(test_name, model_info, 
     133                                test_method_name, 
     134                                platform="dll",  # so that 
     135                                dtype="double", 
     136                                stash=stash) 
     137        suite.addTest(test) 
     138    else:   # kernel implemented in C 
     139 
     140        # test using dll if desired 
     141        if 'dll' in loaders or not use_opencl(): 
     142            test_name = "%s-dll"%model_info.name 
     143            test_method_name = "test_%s_dll" % model_info.id 
    128144            test = ModelTestCase(test_name, model_info, 
    129                                  test_method_name, 
    130                                  platform="dll",  # so that 
    131                                  dtype="double", 
    132                                  stash=stash) 
     145                                    test_method_name, 
     146                                    platform="dll", 
     147                                    dtype="double", 
     148                                    stash=stash) 
    133149            suite.addTest(test) 
    134         else:   # kernel implemented in C 
    135  
    136             # test using dll if desired 
    137             if 'dll' in loaders or not use_opencl(): 
    138                 test_name = "%s-dll"%model_name 
    139                 test_method_name = "test_%s_dll" % model_info.id 
    140                 test = ModelTestCase(test_name, model_info, 
    141                                      test_method_name, 
    142                                      platform="dll", 
    143                                      dtype="double", 
    144                                      stash=stash) 
    145                 suite.addTest(test) 
    146  
    147             # test using opencl if desired and available 
    148             if 'opencl' in loaders and use_opencl(): 
    149                 test_name = "%s-opencl"%model_name 
    150                 test_method_name = "test_%s_opencl" % model_info.id 
    151                 # Using dtype=None so that the models that are only 
    152                 # correct for double precision are not tested using 
    153                 # single precision.  The choice is determined by the 
    154                 # presence of *single=False* in the model file. 
    155                 test = ModelTestCase(test_name, model_info, 
    156                                      test_method_name, 
    157                                      platform="ocl", dtype=None, 
    158                                      stash=stash) 
    159                 #print("defining", test_name) 
    160                 suite.addTest(test) 
    161  
    162     return suite 
     150 
     151        # test using opencl if desired and available 
     152        if 'opencl' in loaders and use_opencl(): 
     153            test_name = "%s-opencl"%model_info.name 
     154            test_method_name = "test_%s_opencl" % model_info.id 
     155            # Using dtype=None so that the models that are only 
     156            # correct for double precision are not tested using 
     157            # single precision.  The choice is determined by the 
     158            # presence of *single=False* in the model file. 
     159            test = ModelTestCase(test_name, model_info, 
     160                                    test_method_name, 
     161                                    platform="ocl", dtype=None, 
     162                                    stash=stash) 
     163            #print("defining", test_name) 
     164            suite.addTest(test) 
     165 
    163166 
    164167def _hide_model_case_from_nose(): 
     
    348351    return abs(target-actual)/shift < 1.5*10**-digits 
    349352 
    350 def run_one(model): 
    351     # type: (str) -> str 
    352     """ 
    353     Run the tests for a single model, printing the results to stdout. 
    354  
    355     *model* can by a python file, which is handy for checking user defined 
    356     plugin models. 
     353# CRUFT: old interface; should be deprecated and removed 
     354def run_one(model_name): 
     355    # msg = "use check_model(model_info) rather than run_one(model_name)" 
     356    # warnings.warn(msg, category=DeprecationWarning, stacklevel=2) 
     357    try: 
     358        model_info = load_model_info(model_name) 
     359    except Exception: 
     360        output = traceback.format_exc() 
     361        return output 
     362 
     363    success, output = check_model(model_info) 
     364    return output 
     365 
     366def check_model(model_info): 
     367    # type: (ModelInfo) -> str 
     368    """ 
     369    Run the tests for a single model, capturing the output. 
     370 
     371    Returns success status and the output string. 
    357372    """ 
    358373    # Note that running main() directly did not work from within the 
     
    369384    # Build a test suite containing just the model 
    370385    loaders = ['opencl'] if use_opencl() else ['dll'] 
    371     models = [model] 
    372     try: 
    373         suite = make_suite(loaders, models) 
    374     except Exception: 
    375         import traceback 
    376         stream.writeln(traceback.format_exc()) 
    377         return 
     386    suite = unittest.TestSuite() 
     387    _add_model_to_suite(loaders, suite, model_info) 
    378388 
    379389    # Warn if there are no user defined tests. 
     
    390400    for test in suite: 
    391401        if not test.info.tests: 
    392             stream.writeln("Note: %s has no user defined tests."%model) 
     402            stream.writeln("Note: %s has no user defined tests."%model_info.name) 
    393403        break 
    394404    else: 
     
    406416    output = stream.getvalue() 
    407417    stream.close() 
    408     return output 
     418    return result.wasSuccessful(), output 
    409419 
    410420 
  • sasmodels/sasview_model.py

    rd533590 r12eec1e  
    786786            return value, [value], [1.0] 
    787787 
     788    @classmethod 
     789    def runTests(cls): 
     790        """ 
     791        Run any tests built into the model and captures the test output. 
     792 
     793        Returns success flag and output 
     794        """ 
     795        from .model_test import check_model 
     796        return check_model(cls._model_info) 
     797 
    788798def test_cylinder(): 
    789799    # type: () -> float 
Note: See TracChangeset for help on using the changeset viewer.