- Timestamp:
- Mar 30, 2019 2:06:15 PM (6 years ago)
- 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. - Location:
- doc
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/guide/index.rst
rda5536f rbc69321 12 12 pd/polydispersity.rst 13 13 resolution.rst 14 plugin.rst 15 fitting_sq.rst 14 16 magnetism/magnetism.rst 15 17 orientation/orientation.rst 16 18 sesans/sans_to_sesans.rst 17 19 sesans/sesans_fitting.rst 18 plugin.rst19 20 scripting.rst 20 21 refs.rst -
doc/guide/plugin.rst
rc94ab04 re15a822 303 303 **Note: The order of the parameters in the definition will be the order of the 304 304 parameters in the user interface and the order of the parameters in Fq(), Iq(), 305 Iqac(), Iqabc(), form_volume() and shell_volume().305 Iqac(), Iqabc(), radius_effective(), form_volume() and shell_volume(). 306 306 And** *scale* **and** *background* **parameters are implicit to all models, 307 307 so they do not need to be included in the parameter table.** … … 387 387 can take arbitrary values, even for integer parameters, so your model should 388 388 round 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:: 389 you should round to the nearest integer. In C code, you can do this using: 390 391 .. code-block:: c 390 392 391 393 static double … … 454 456 ............. 455 457 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 456 464 For pure python models, define the *Iq* function:: 457 465 … … 499 507 Models should define *form_volume(par1, par2, ...)* where the parameter 500 508 list 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. 509 volume normalization so that scattering is on an absolute scale. For 510 solid shapes, the *I(q)* function should use *form_volume* squared 511 as its scale factor. If *form_volume* is not defined, then the default 512 *form_volume = 1.0* will be used. 504 513 505 514 Hollow shapes, where the volume fraction of particle corresponds to the 506 515 material in the shell rather than the volume enclosed by the shape, must 507 516 also 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).** 517 are 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 519 parameter corresponds to the volume fraction of material in the sample. 520 The structure factor calculation needs the volume fraction of the filled 521 shapes for its calculation, so the volume fraction parameter in the model 522 is automatically scaled by *form_volume/shell_volume* prior to calling the 523 structure factor. 517 524 518 525 Embedded C Models … … 525 532 """ 526 533 527 This expands into the equivalent C code:: 534 This expands into the equivalent C code: 535 536 .. code-block:: c 528 537 529 538 double Iq(double q, double par1, double par2, ...); … … 536 545 includes only the volume parameters. 537 546 538 * form_volume* defines the volume of the shell for hollow shapes. As in547 *shell_volume* defines the volume of the shell for hollow shapes. As in 539 548 python models, it includes only the volume parameters. 540 549 … … 568 577 Rather than returning NAN from Iq, you must define the *INVALID(v)*. The 569 578 *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 571 582 572 583 #define INVALID(v) (v.bell_radius < v.radius) … … 583 594 584 595 Instead of defining the *Iq* function, models can define *Fq* as 585 something like:: 596 something like: 597 598 .. code-block:: c 586 599 587 600 double Fq(double q, double *F1, double *F2, double par1, double par2, ...); … … 615 628 laboratory frame and beam travelling along $-z$. 616 629 617 The oriented C model (oriented pure Python models are not supported) 630 The oriented C model (oriented pure Python models are not supported) 618 631 is called using *Iqabc(qa, qb, qc, par1, par2, ...)* where 619 632 *par1*, etc. are the parameters to the model. If the shape is rotationally … … 644 657 645 658 Using the $z, w$ values for Gauss-Legendre integration in "lib/gauss76.c", the 646 numerical integration is then:: 659 numerical integration is then: 660 661 .. code-block:: c 647 662 648 663 double outer_sum = 0.0; … … 987 1002 memory, and wrong answers computed. The conclusion from a very long and 988 1003 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 990 1007 991 1008 double Iq(q, p1, p2, ...) … … 1019 1036 structure factor is the *hardsphere* interaction, which 1020 1037 uses 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.* 1038 factor model. The effective radius is the weighted average over all 1039 values of the shape in polydisperse systems. 1040 1041 There can be many notions of effective radius, depending on the shape. For 1042 a sphere it is clearly just the radius, but for an ellipsoid of revolution 1043 we provide average curvature, equivalent sphere radius, minimum radius and 1044 maximum radius. These options are listed as *radius_effective_modes* in 1045 the python model defintion, and must be computed by the *radius_effective* 1046 function which takes the *radius_effective_mode* parameter as an integer, 1047 along with the various model parameters. Unlike normal C/Python arrays, 1048 the first mode is 1, the second is 2, etc. Mode 0 indicates that the 1049 effective radius from the shape is to be ignored in favour of the the 1050 effective radius parameter in the structure factor model. 1051 1052 1053 Consider the core-shell sphere, which defines the following effective radius 1054 modes in the python model:: 1055 1056 radius_effective_modes = [ 1057 "outer radius", 1058 "core radius", 1059 ] 1060 1061 and 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 1081 Given polydispersity over *(r1, r2, ..., rm)* in radius and *(t1, t2, ..., tn)* 1082 in thickness, *radius_effective* is called over a mesh grid covering all 1083 possible combinations of radius and thickness, with a single *(ri, tj)* pair 1084 in each call. The weights each of these results according to the 1085 polydispersity distributions and calls the structure factor with the average 1086 effective radius. Similarly, for *form_volume*. 1087 1088 Hollow models have an additional volume ratio which is needed to scale the 1089 structure factor. The structure factor uses the volume fraction of the filled 1090 particles as part of its density estimate, but the scale factor for the 1091 scattering intensity (as non-solvent volume fraction / volume) is determined 1092 by the shell volume only. Therefore the *shell_volume* function is 1093 needed to compute the form:shell volume ratio, which then scales the 1094 *volfraction* parameter prior to calling the structure factor calculator. 1095 In 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 1107 If *shell_volume* is not present, then *form_volume* and *shell_volume* are 1108 assumed to be equal, and the shape is considered solid. 1058 1109 1059 1110 Unit Tests … … 1115 1166 ................... 1116 1167 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 1118 1169 SasView build environment available!** 1119 1170 … … 1253 1304 | 2016-10-25 Steve King 1254 1305 | 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 1 1 .. resolution.rst 2 2 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 4 4 .. text by S King, ISIS, during SasView CodeCamp-III in Feb 2015. 5 5 … … 17 17 resolution contribution into a model calculation/simulation (which by definition 18 18 will be exact) to make it more representative of what has been measured 19 experimentally - a process called *smearing*. The Sasmodels component of SasView 19 experimentally - a process called *smearing*. The Sasmodels component of SasView 20 20 does the latter. 21 21 … … 32 32 33 33 .. 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 42 42 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 46 46 the data from different detector distances simultaneously. 47 47 -
doc/conf.py
r30b60d2 rc1e44e5 36 36 #'only_directives', 37 37 #'matplotlib.sphinxext.mathmpl', 38 'matplotlib.sphinxext.only_directives',38 #'matplotlib.sphinxext.only_directives', 39 39 'matplotlib.sphinxext.plot_directive', 40 40 'dollarmath', -
doc/genmodel.py
rb866abf ra42b091 7 7 import matplotlib.pyplot as plt 8 8 sys.path.insert(0, os.path.abspath('..')) 9 import sasmodels 9 10 from sasmodels import generate, core 10 11 from sasmodels.direct_model import DirectModel, call_profile … … 127 128 #print("figure saved in",path) 128 129 130 def 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 141 def 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 129 187 def gen_docs(model_info): 130 188 # type: (ModelInfo) -> None … … 150 208 match = re.search(pattern, docstr.upper()) 151 209 210 sources = link_sources(model_info) 211 212 insertion = captionstr + sources 213 152 214 if match: 153 215 docstr1 = docstr[:match.start()] 154 216 docstr2 = docstr[match.start():] 155 docstr = docstr1 + captionstr+ docstr2217 docstr = docstr1 + insertion + docstr2 156 218 else: 157 219 print('------------------------------------------------------------------') 158 220 print('References NOT FOUND for model: ', model_info.id) 159 221 print('------------------------------------------------------------------') 160 docstr += captionstr222 docstr += insertion 161 223 162 224 open(sys.argv[2],'w').write(docstr)
Note: See TracChangeset
for help on using the changeset viewer.