source: sasmodels/doc/developer/overview.rst @ a5a12ca

core_shell_microgelsmagnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since a5a12ca was 870a2f4, checked in by Paul Kienzle <pkienzle@…>, 7 years ago

fix doc builds

  • Property mode set to 100644
File size: 10.6 KB
RevLine 
[2e66ef5]1.. py:currentmodule:: sasmodels
2
3***************************
4Code Overview
5***************************
6
7Computational kernels
8---------------------
9
[870a2f4]10* :mod:`core`
11* :mod:`modelinfo`
12* :mod:`kernel`
13* :mod:`product`
14* :mod:`mixture`
15
[2e66ef5]16At the heart of *sasmodels* are the individual computational kernels.  These
17functions take a particular $q$ value and a set of parameter values and
18return the expected scattering for that $q$. The instructions for writing
19a kernel are documented in :ref:`Writing_a_Plugin`.  The source code for
[870a2f4]20the kernels is stored in :mod:`models`.
[2e66ef5]21
[870a2f4]22The primary interface to the models is through :mod:`core`, which
[2e66ef5]23provides functions for listing available models, loading the model definition
[870a2f4]24and compiling the model.  Use :func:`core.load_model` to load in
25a model definition and compile it.  This makes use of
26:func:`core.load_model_info` to load the model definition and
27:func:`core.build_model` to turn it into a computational kernel model
28:class:`kernel.KernelModel`.
29
30The :class:`modelinfo.ModelInfo` class defines the properties
31of the model including the available model parameters
32:class:`modelinfo.ParameterTable` with individual parameter attributes
33such as units and hard limits defined in :class:`modelinfo.Parameter`.
34
35The :class:`product.ProductModel` and :class:`mixture.MixtureModel` classes
36are derived models, created automatically for models with names like
37"hardsphere*sphere" and "cylinder+sphere".
38
39Data loaders
40------------
41
42* :mod:`data`
43
44In order to test models a minimal set of data management routines is
45provided in :mod:`data`.  In particular, it provides mock :class:`data.Data1D`
46and :class:`data.Data2D` classes which mimic those classes in *SasView*.
47The functions :func:`data.empty_data1D` and :func:`data.empty_data2D`
48are handy for creating containers with a particular set of $q$, $\Delta q$
49points which can later be evaluated, and :func:`data.plot_theory` to show
50the result.  If *SasView* is available on the path then :func:`data.load_data`
51can be used to load any data type defined in *SasView*.  The function
52:func:`data.plot_data` can plot that data alone without the theory value.
53
54Kernel execution
55----------------
56
57* :mod:`resolution`
58* :mod:`resolution2d`
59* :mod:`sesans`
60* :mod:`weights`
61* :mod:`details`
62* :mod:`direct_model`
63* :mod:`bumps_model`
64* :mod:`sasview_model`
65
66To execute a computational kernel at a particular set of $q$ values, the
67use :meth:`kernel.KernelModel.make_kernel`, which returns a callable
68:class:`kernel.Kernel` for that $q$ vector (or a pair of $q_x$, $q_y$
69for 2-D datasets).
70
71The calculated $q$ values should include the measured
72data points as well as additional $q$ values required to properly compute the
73$q$ resolution function.  The *Resolution* subclasses in :mod:`resolution`
74define the *q_calc* attribute for this purpose.  These are
75:class:`resolution.Perfect1D` for perfect resolution,
76:class:`resolution.Pinhole1D` for the usual SANS pinhole aperture,
77:class:`resolution.Slit1D` for the usual USANS slit aperture and
78:class:`resolution2d.Pinhole2D` for 2-D pinhole data.
79In addition, :class:`resolution2d.Slit2D` defines 1-D slit smeared data
80for oriented samples, which require calculation at particular $q_x$ and
81$q_y$ values instead of $|q|$ as is the case for orientationally averaged
82USANS.  The :class:`sesans.SesansTransform` class acts like a 1-D resolution,
83having a *q_calc* attribute that defines the calculated $q$ values for
84the SANS models that get converted to spin-echo values by the
85:meth:`sesnas.SesansTransform.apply` method.
86
87Polydispersity is defined by :class:`weights.Dispersion` classes,
88:class:`weights.RectangleDispersion`, :class:`weights.ArrayDispersion`,
89:class:`weights.LogNormalDispersion`, :class:`weights.GaussianDispersion`,
90:class:`weights.SchulzDispersion`.  The :func:`weights.get_weights`
91function creates a dispersion object of the class matching
92:attr:`weights.Dispersion.type`, and calls it with the current value
93of the parameter.  This returns a vector of values and weights for a
94weighted average polydispersity.
95
96In order to call the :class:`kernel.Kernel`, the values and weights for
97all parameters must be composed into a :class:`details.CallDetails` object.
98This is a compact vector representation of the entire polydispersity
99loop that can be passed easily to the kernel.  Additionally, the magnetic
100parameters must be converted from polar to cartesian coordinates.  This
101work is done by the :func:`details.make_kernel_args` function, which returns
102values that can be sent directly to the kernel.  It uses
103:func:`details.make_details` to set the details object and
104:func:`details.convert_magnetism` for the coordinate transform.
105
106In the end, making a simple theory function evaluation requires a lot of
107setup. To make calling them a little easier, the *DirectModel* and
108*BumpsModel* interfaces are provided.  See :ref:`Scripting_Interface`
109for an example.
110
111The :class:`direct_model.DirectModel` interface accepts a data object
112and a kernel model.  Within the class,
113the :meth:`direct_model.DataMixin._interpret_data` method is called to
114query the data and set the resolution.
115The :meth:`direct_model.DataMixin._calc_theory` takes a set of parameter
116values, builds the kernel arguments, calls the kernel, and applies the
117resolution function, returning the predicted value for the data $q$ values.
118The :class:`bumps_model.Experiment` class is like the DirectModel class,
119but it defines a Fitness class that can be handed directly to the
120bumps optimization and uncertainty analysis program.
121
122The :class:`sasview_model.SasviewModel` class defines a SasView 4.x
123compatible interface to the sasmodels definitions, allowing sasmodels
124to be used directly from SasView.  Over time the SasView shim should
125disappear as SasView access the :class:`modelinfo.ModelInfo` and
126computational kernels directly.
127
128Kernel execution
129----------------
130
131* :mod:`kernelcl`
132* :mod:`kerneldll`
133* :mod:`kernelpy`
134* :mod:`generate`
[2e66ef5]135
136
137The kernel functions for the most part do not define polydispersity,
[870a2f4]138resolution or magnetism directly.  Instead sasmodels automatically
139applies these, calling the computation kernel as needed.
140
141The outermost loop is the resolution calculation.  For the 1-D case
142this computes a single vector of $I(q)$ values and applies the convolution
143to the resulting set.  Since the same $I(q)$ vector is used to compute the
144convolution at each point, it can be precomputed before the convolution,
145and so the convolution is reasonably efficient.  The 2-D case is not
146that efficient, and instead recomputes the entire shifted/scaled set
147of $q_x$, $q_y$ values many times, or very many times depending on the
148accuracy requested.
149
150Polydispersity is handled as a mesh over the polydisperse parameters.
151This is the next level of the loop.  For C kernels run in a DLL or
152using OpenCL, the polydisperisty loop is generated separately for each
153model as C code.  Inside the polydispersity loop there is a loop over
154the magnetic cross sections for magnetic models, updating the SLD
155parameters with the effective magnetic SLD for that particular $q$
156value. For OpenCL, each $q$ value loops over the
157polydispersity mesh on a separate processor. For DLL, the outer loop
158cycles through polydispersity, and the inner loop distributes q values
159amongst the processors.  Like the DLL, the Python kernel execution
160cycles over the polydisperse parameters and the magnetic cross sections,
161calling the computation kernel with a vector of $q$ values.  Assuming
162the kernel code accepts vectors, this can be fast enough (though it is
163painfully slow if not vectorized).
164
165Further details are provided in the next section,
166:ref:`Calculator_Interface`
167
168
169Testing
170-------
171
172* :mod:`model_test`
173* :mod:`compare`
174* :mod:`compare_many`
175* :mod:`rst2html`
176* :mod:`list_pars`
177
178Individual models should all have test values to make sure that the
179evaluation is correct.  This is particularly important in the context
180of OpenCL since sasmodels doesn't control the compiler or the hardware,
181and since GPUs are notorious for preferring speed over precision.  The
182tests can be run as a group using :mod:`model_test` as main::
183
184    $ python -m sasmodels.model_test all
185
186Individual models can be listed instead of *all*, which is convenient when
187adding new models.
188
189The :mod:`compare` module, usually invoked using *./sascomp* provides a
190rich interface for exploring model accuracy, execution speed and parameter
191ranges.  It also allows different models to be compared.
192The :mod:`compare_many` module does batch comparisons, keeping a list of
193the particular random seeds which lead to large differences in output
194between different computing platforms.
195
196The :mod:`rst2html` module provides tools for converting model docs to
197html and viewing the html.  This is used by :mod:`compare` to display
198the model description, such as::
199
200    $ ./sascomp -html sphere
201
202This makes debugging the latex much faster, though this may require
203Qt in order for mathjax to work correctly.
204
205When run as main, it can display arbitrary ReStructuredText files. E.g.,
206
207::
208
209    $ python -m sasmodels.rst2html doc/developer/overview.rst
210
211This is handy for sorting out rst and latex syntax.  With some work
212the results could be improved so that it recognizes sphinx roles
213such as *mod*, *class* and *func*, and so that it uses the style sheets
214from the sasmodels docs.
215
216The :mod:`list_pars` module lists all instances of parameters across
217all models.  This helps to make sure that similar parameters have
218similar names across the different models.  With the verbose flag,
219the particular models which use each named parameter are listed.
220
221
222Model conversion
223----------------
224
225* :mod:`convert`
226* :mod:`conversion_table`
227
228Model definitions are not static.  As needs change or problems are found,
229models may be updated with new model names or may be reparameterized
230with new parameter definitions.  For example, in translating the
231Teubner-Strey model from SasView 3.x to sasmodels, the definition
232in terms of *drho*, *k*, *c1*, *c2*, *a2* and prefactor was replaced
233by the defintion in terms of *volfraction_a*, *xi*, *d*, *sld_a* and
234*sld_b*.  Within :mod:`convert`, the *_hand_convert_3_1_2_to_4_1*
235function must be called when loading a 3.x model definition to update it to
2364.1, and then the model should be further updated to 4.2, 5.0, and so on.
237The :func:`convert.convert_model` function does this, using the conversion
238table in :mod:`conversion_table` (which handled the major renaming from
239SasView 3.x to sasmodels), and using the internal *_hand_convert* function
240for the more complicated cases.
241
242Other
243-----
244
245* :mod:`exception`
246* :mod:`alignment`
247
248The :func:`exception.annotate_exception` function annotates the current
249exception with a context string, such as "while opening myfile.dat" without
250adjusting the traceback.
251
252The :mod:`alignment` module is unused.
Note: See TracBrowser for help on using the repository browser.