Changeset d57b06c in sasmodels for doc


Ignore:
Timestamp:
Mar 30, 2019 2:06:15 PM (6 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master
Children:
be0942c
Parents:
a42b091 (diff), e15a822 (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 remote-tracking branch 'origin/master' into ticket-1263-source-link

Location:
doc
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • doc/guide/index.rst

    rda5536f rbc69321  
    1212   pd/polydispersity.rst 
    1313   resolution.rst 
     14   plugin.rst 
     15   fitting_sq.rst 
    1416   magnetism/magnetism.rst 
    1517   orientation/orientation.rst 
    1618   sesans/sans_to_sesans.rst 
    1719   sesans/sesans_fitting.rst 
    18    plugin.rst 
    1920   scripting.rst 
    2021   refs.rst 
  • doc/guide/plugin.rst

    rc94ab04 re15a822  
    303303**Note: The order of the parameters in the definition will be the order of the 
    304304parameters in the user interface and the order of the parameters in Fq(), Iq(), 
    305 Iqac(), Iqabc(), form_volume() and shell_volume(). 
     305Iqac(), Iqabc(), radius_effective(), form_volume() and shell_volume(). 
    306306And** *scale* **and** *background* **parameters are implicit to all models, 
    307307so they do not need to be included in the parameter table.** 
     
    387387can take arbitrary values, even for integer parameters, so your model should 
    388388round the incoming parameter value to the nearest integer inside your model 
    389 you should round to the nearest integer.  In C code, you can do this using:: 
     389you should round to the nearest integer.  In C code, you can do this using: 
     390 
     391.. code-block:: c 
    390392 
    391393    static double 
     
    454456............. 
    455457 
     458.. note:: 
     459 
     460   Pure python models do not yet support direct computation of $<F(Q)^2>$ or 
     461   $<F(Q)>^2$. Neither do they support orientational distributions or magnetism 
     462   (use C models if these are required). 
     463 
    456464For pure python models, define the *Iq* function:: 
    457465 
     
    499507Models should define *form_volume(par1, par2, ...)* where the parameter 
    500508list includes the *volume* parameters in order.  This is used for a weighted 
    501 volume normalization so that scattering is on an absolute scale.  If 
    502 *form_volume* is not defined, then the default *form_volume = 1.0* will be 
    503 used. 
     509volume normalization so that scattering is on an absolute scale.  For 
     510solid shapes, the *I(q)* function should use *form_volume* squared 
     511as its scale factor.  If *form_volume* is not defined, then the default 
     512*form_volume = 1.0* will be used. 
    504513 
    505514Hollow shapes, where the volume fraction of particle corresponds to the 
    506515material in the shell rather than the volume enclosed by the shape, must 
    507516also define a *shell_volume(par1, par2, ...)* function.  The parameters 
    508 are the same as for *form_volume*.  The *I(q)* calculation should use 
    509 *shell_volume* squared as its scale factor for the volume normalization. 
    510 The structure factor calculation needs *form_volume* in order to properly 
    511 scale the volume fraction parameter, so both functions are required for 
    512 hollow shapes. 
    513  
    514 **Note: Pure python models do not yet support direct computation of the** 
    515 **average of $F(q)$ and $F^2(q)$. Neither do they support orientational** 
    516 **distributions or magnetism (use C models if these are required).** 
     517are the same as for *form_volume*.  Here the *I(q)* function should use 
     518*shell_volume* squared instead of *form_volume* squared so that the scale 
     519parameter corresponds to the volume fraction of material in the sample. 
     520The structure factor calculation needs the volume fraction of the filled 
     521shapes for its calculation, so the volume fraction parameter in the model 
     522is automatically scaled by *form_volume/shell_volume* prior to calling the 
     523structure factor. 
    517524 
    518525Embedded C Models 
     
    525532    """ 
    526533 
    527 This expands into the equivalent C code:: 
     534This expands into the equivalent C code: 
     535 
     536.. code-block:: c 
    528537 
    529538    double Iq(double q, double par1, double par2, ...); 
     
    536545includes only the volume parameters. 
    537546 
    538 *form_volume* defines the volume of the shell for hollow shapes. As in 
     547*shell_volume* defines the volume of the shell for hollow shapes. As in 
    539548python models, it includes only the volume parameters. 
    540549 
     
    568577Rather than returning NAN from Iq, you must define the *INVALID(v)*.  The 
    569578*v* parameter lets you access all the parameters in the model using 
    570 *v.par1*, *v.par2*, etc. For example:: 
     579*v.par1*, *v.par2*, etc. For example: 
     580 
     581.. code-block:: c 
    571582 
    572583    #define INVALID(v) (v.bell_radius < v.radius) 
     
    583594 
    584595Instead of defining the *Iq* function, models can define *Fq* as 
    585 something like:: 
     596something like: 
     597 
     598.. code-block:: c 
    586599 
    587600    double Fq(double q, double *F1, double *F2, double par1, double par2, ...); 
     
    615628laboratory frame and beam travelling along $-z$. 
    616629 
    617 The oriented C model (oriented pure Python models are not supported)  
     630The oriented C model (oriented pure Python models are not supported) 
    618631is called using *Iqabc(qa, qb, qc, par1, par2, ...)* where 
    619632*par1*, etc. are the parameters to the model.  If the shape is rotationally 
     
    644657 
    645658Using the $z, w$ values for Gauss-Legendre integration in "lib/gauss76.c", the 
    646 numerical integration is then:: 
     659numerical integration is then: 
     660 
     661.. code-block:: c 
    647662 
    648663    double outer_sum = 0.0; 
     
    9871002  memory, and wrong answers computed. The conclusion from a very long and 
    9881003  strange debugging session was that any arrays that you declare in your 
    989   model should be a multiple of four. For example:: 
     1004  model should be a multiple of four. For example: 
     1005 
     1006  .. code-block:: c 
    9901007 
    9911008      double Iq(q, p1, p2, ...) 
     
    10191036structure factor is the *hardsphere* interaction, which 
    10201037uses the effective radius of the form factor as an input to the structure 
    1021 factor model.  The effective radius is the average radius of the 
    1022 form averaged over all the polydispersity values. 
    1023  
    1024 :: 
    1025  
    1026     def ER(radius, thickness): 
    1027         """Effective radius of a core-shell sphere.""" 
    1028         return radius + thickness 
    1029  
    1030 Now consider the *core_shell_sphere*, which has a simple effective radius 
    1031 equal to the radius of the core plus the thickness of the shell, as 
    1032 shown above. Given polydispersity over *(r1, r2, ..., rm)* in radius and 
    1033 *(t1, t2, ..., tn)* in thickness, *ER* is called with a mesh 
    1034 grid covering all possible combinations of radius and thickness. 
    1035 That is, *radius* is *(r1, r2, ..., rm, r1, r2, ..., rm, ...)* 
    1036 and *thickness* is *(t1, t1, ... t1, t2, t2, ..., t2, ...)*. 
    1037 The *ER* function returns one effective radius for each combination. 
    1038 The effective radius calculator weights each of these according to 
    1039 the polydispersity distributions and calls the structure factor 
    1040 with the average *ER*. 
    1041  
    1042 :: 
    1043  
    1044     def VR(radius, thickness): 
    1045         """Sphere and shell volumes for a core-shell sphere.""" 
    1046         whole = 4.0/3.0 * pi * (radius + thickness)**3 
    1047         core = 4.0/3.0 * pi * radius**3 
    1048         return whole, whole - core 
    1049  
    1050 Core-shell type models have an additional volume ratio which scales 
    1051 the structure factor.  The *VR* function returns the volume of 
    1052 the whole sphere and the volume of the shell. Like *ER*, there is 
    1053 one return value for each point in the mesh grid. 
    1054  
    1055 *NOTE: we may be removing or modifying this feature soon. As of the 
    1056 time of writing, core-shell sphere returns (1., 1.) for VR, giving a volume 
    1057 ratio of 1.0.* 
     1038factor model.  The effective radius is the weighted average over all 
     1039values of the shape in polydisperse systems. 
     1040 
     1041There can be many notions of effective radius, depending on the shape.  For 
     1042a sphere it is clearly just the radius, but for an ellipsoid of revolution 
     1043we provide average curvature, equivalent sphere radius, minimum radius and 
     1044maximum radius.  These options are listed as *radius_effective_modes* in 
     1045the python model defintion, and must be computed by the *radius_effective* 
     1046function which takes the *radius_effective_mode* parameter as an integer, 
     1047along with the various model parameters.  Unlike normal C/Python arrays, 
     1048the first mode is 1, the second is 2, etc.  Mode 0 indicates that the 
     1049effective radius from the shape is to be ignored in favour of the the 
     1050effective radius parameter in the structure factor model. 
     1051 
     1052 
     1053Consider the core-shell sphere, which defines the following effective radius 
     1054modes in the python model:: 
     1055 
     1056    radius_effective_modes = [ 
     1057        "outer radius", 
     1058        "core radius", 
     1059    ] 
     1060 
     1061and the following function in the C-file for the model: 
     1062 
     1063.. code-block:: c 
     1064 
     1065    static double 
     1066    radius_effective(int mode, double radius, double thickness) 
     1067    { 
     1068        switch (mode) { 
     1069            case 0: return radius + thickness; 
     1070            case 1: return radius; 
     1071            default: return 0.; 
     1072        } 
     1073    } 
     1074 
     1075    static double 
     1076    form_volume(double radius, double thickness) 
     1077    { 
     1078        return M_4PI_3 * cube(radius + thickness); 
     1079    } 
     1080 
     1081Given polydispersity over *(r1, r2, ..., rm)* in radius and *(t1, t2, ..., tn)* 
     1082in thickness, *radius_effective* is called over a mesh grid covering all 
     1083possible combinations of radius and thickness, with a single *(ri, tj)* pair 
     1084in each call. The weights each of these results according to the 
     1085polydispersity distributions and calls the structure factor with the average 
     1086effective radius.  Similarly, for *form_volume*. 
     1087 
     1088Hollow models have an additional volume ratio which is needed to scale the 
     1089structure factor.  The structure factor uses the volume fraction of the filled 
     1090particles as part of its density estimate, but the scale factor for the 
     1091scattering intensity (as non-solvent volume fraction / volume) is determined 
     1092by the shell volume only.  Therefore the *shell_volume* function is 
     1093needed to compute the form:shell volume ratio, which then scales the 
     1094*volfraction* parameter prior to calling the structure factor calculator. 
     1095In the case of a hollow sphere, this would be: 
     1096 
     1097.. code-block:: c 
     1098 
     1099    static double 
     1100    shell_volume(double radius, double thickness) 
     1101    { 
     1102        double whole = M_4PI_3 * cube(radius + thickness); 
     1103        double core = M_4PI_3 * cube(radius); 
     1104        return whole - core; 
     1105    } 
     1106 
     1107If *shell_volume* is not present, then *form_volume* and *shell_volume* are 
     1108assumed to be equal, and the shape is considered solid. 
    10581109 
    10591110Unit Tests 
     
    11151166................... 
    11161167 
    1117 **NB: For now, this more detailed testing is only possible if you have a  
     1168**NB: For now, this more detailed testing is only possible if you have a 
    11181169SasView build environment available!** 
    11191170 
     
    12531304| 2016-10-25 Steve King 
    12541305| 2017-05-07 Paul Kienzle - Moved from sasview to sasmodels docs 
     1306| 2019-03-28 Paul Kienzle - Update docs for radius_effective and shell_volume 
  • doc/guide/resolution.rst

    r8d2df05 rdb1d9d5  
    11.. resolution.rst 
    22 
    3 .. This is a port of the original SasView html help file sm_help to ReSTructured  
     3.. This is a port of the original SasView html help file sm_help to ReSTructured 
    44.. text by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 
    55 
     
    1717resolution contribution into a model calculation/simulation (which by definition 
    1818will be exact) to make it more representative of what has been measured 
    19 experimentally - a process called *smearing*. The Sasmodels component of SasView  
     19experimentally - a process called *smearing*. The Sasmodels component of SasView 
    2020does the latter. 
    2121 
     
    3232 
    3333.. note:: 
    34     Problems may be encountered if the data set loaded by SasView is a  
    35     concatenation of SANS data from several detector distances where, of  
    36     course, the worst Q resolution is next to the beam stop at each detector  
    37     distance. (This will also be noticeable in the residuals plot where  
    38     there will be poor overlap). SasView sensibly orders all the input  
    39     data points by increasing Q for nicer-looking plots, however, the dQ  
    40     data can then vary considerably from point to point. If 'Use dQ data'  
    41     smearing is selected then spikes may appear in the model fits, whereas  
     34    Problems may be encountered if the data set loaded by SasView is a 
     35    concatenation of SANS data from several detector distances where, of 
     36    course, the worst Q resolution is next to the beam stop at each detector 
     37    distance. (This will also be noticeable in the residuals plot where 
     38    there will be poor overlap). SasView sensibly orders all the input 
     39    data points by increasing Q for nicer-looking plots, however, the dQ 
     40    data can then vary considerably from point to point. If 'Use dQ data' 
     41    smearing is selected then spikes may appear in the model fits, whereas 
    4242    if 'None' or 'Custom Pinhole Smear' are selected the fits look normal. 
    43      
    44     In such instances, possible solutions are to simply remove the data  
    45     with poor Q resolution from the shorter detector distances, or to fit  
     43 
     44    In such instances, possible solutions are to simply remove the data 
     45    with poor Q resolution from the shorter detector distances, or to fit 
    4646    the data from different detector distances simultaneously. 
    4747 
  • doc/conf.py

    r30b60d2 rc1e44e5  
    3636              #'only_directives', 
    3737              #'matplotlib.sphinxext.mathmpl', 
    38               'matplotlib.sphinxext.only_directives', 
     38              #'matplotlib.sphinxext.only_directives', 
    3939              'matplotlib.sphinxext.plot_directive', 
    4040              'dollarmath', 
  • doc/genmodel.py

    rb866abf ra42b091  
    77import matplotlib.pyplot as plt 
    88sys.path.insert(0, os.path.abspath('..')) 
     9import sasmodels 
    910from sasmodels import generate, core 
    1011from sasmodels.direct_model import DirectModel, call_profile 
     
    127128    #print("figure saved in",path) 
    128129 
     130def copy_if_newer(src, dst): 
     131    from os.path import dirname, exists, getmtime 
     132    import shutil 
     133    if not exists(dst): 
     134        path = dirname(dst) 
     135        if not exists(path): 
     136            os.makedirs(path) 
     137        shutil.copy2(src, dst) 
     138    elif getmtime(src) > getmtime(dst): 
     139        shutil.copy2(src, dst) 
     140 
     141def link_sources(model_info): 
     142    from os.path import basename, dirname, realpath, join as joinpath 
     143 
     144    # List source files in reverse order of dependency. 
     145    model_file = basename(model_info.filename) 
     146    sources = list(reversed(model_info.source + [model_file])) 
     147 
     148    # Copy files to src dir under models directory.  Need to do this 
     149    # because sphinx can't link to an absolute path. 
     150    root = dirname(dirname(realpath(__file__))) 
     151    src = joinpath(root, "sasmodels", "models") 
     152    dst = joinpath(root, "doc", "model", "src") 
     153    for path in sources: 
     154        copy_if_newer(joinpath(src, path), joinpath(dst, path)) 
     155 
     156    # Link to local copy of the files 
     157    downloads = [":download:`%s <src/%s>`"%(path, path) for path in sources] 
     158 
     159    # Could do syntax highlighting on the model files by creating a rst file 
     160    # beside each source file named containing source file with 
     161    # 
     162    #    src/path.rst: 
     163    # 
     164    #    .. {{ path.replace('/','_') }}: 
     165    # 
     166    #    .. literalinclude:: {{ src/path }} 
     167    #        :language: {{ "python" if path.endswith('.py') else "c" }} 
     168    #        :linenos: 
     169    # 
     170    # and link to it using 
     171    # 
     172    #     colors = [":ref:`%s`"%(path.replace('/','_')) for path in sources] 
     173    # 
     174    # Probably need to dump all the rst files into an index.rst to build them. 
     175 
     176    # Link to github repo (either the tagged sasmodels version or master) 
     177    url = "https://github.com/SasView/sasmodels/blob/v%s"%sasmodels.__version__ 
     178    #url = "https://github.com/SasView/sasmodels/blob/master"%sasmodels.__version__ 
     179    links = ["`%s <%s/sasmodels/models/%s>`_"%(path, url, path) for path in sources] 
     180 
     181    sep = u"\n\\ \u25E6 \\ "  # bullet 
     182    body = "\n**Source**\n" 
     183    #body += "\n\\ " + sep.join(links) + "\n\n" 
     184    body += "\n\\ " + sep.join(downloads) + "\n\n" 
     185    return body 
     186 
    129187def gen_docs(model_info): 
    130188    # type: (ModelInfo) -> None 
     
    150208    match = re.search(pattern, docstr.upper()) 
    151209 
     210    sources = link_sources(model_info) 
     211 
     212    insertion = captionstr + sources 
     213 
    152214    if match: 
    153215        docstr1 = docstr[:match.start()] 
    154216        docstr2 = docstr[match.start():] 
    155         docstr = docstr1 + captionstr + docstr2 
     217        docstr = docstr1 + insertion + docstr2 
    156218    else: 
    157219        print('------------------------------------------------------------------') 
    158220        print('References NOT FOUND for model: ', model_info.id) 
    159221        print('------------------------------------------------------------------') 
    160         docstr += captionstr 
     222        docstr += insertion 
    161223 
    162224    open(sys.argv[2],'w').write(docstr) 
Note: See TracChangeset for help on using the changeset viewer.