[2e66ef5] | 1 | .. _Scripting_Interface: |
---|
| 2 | |
---|
| 3 | ******************* |
---|
| 4 | Scripting Interface |
---|
| 5 | ******************* |
---|
| 6 | |
---|
| 7 | Need some basic details here of how to load models and data via script, evaluate |
---|
| 8 | them at given parameter values and run bumps fits. |
---|
| 9 | |
---|
| 10 | The key functions are :func:`sasmodels.core.load_model` for loading the |
---|
| 11 | model 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 |
---|
| 21 | class:`sasmodels.bumps_model.Model` and create an |
---|
| 22 | class:`sasmodels.bump_model.Experiment` that you can fit with the *bumps* |
---|
| 23 | interface. Here is an example from the *example* directory such as |
---|
| 24 | *example/model.py*:: |
---|
| 25 | |
---|
| 26 | import sys |
---|
| 27 | from bumps.names import * |
---|
| 28 | from sasmodels.core import load_model |
---|
| 29 | from sasmodels.bumps_model import Model, Experiment |
---|
| 30 | from sasmodels.data import load_data, set_beam_stop, set_top |
---|
| 31 | |
---|
| 32 | """ IMPORT THE DATA USED """ |
---|
| 33 | radial_data = load_data('DEC07267.DAT') |
---|
| 34 | set_beam_stop(radial_data, 0.00669, outer=0.025) |
---|
| 35 | set_top(radial_data, -.0185) |
---|
| 36 | |
---|
| 37 | kernel = load_model("ellipsoid") |
---|
| 38 | |
---|
| 39 | model = Model(kernel, |
---|
| 40 | scale=0.08, |
---|
| 41 | radius_polar=15, radius_equatorial=800, |
---|
| 42 | sld=.291, sld_solvent=7.105, |
---|
| 43 | background=0, |
---|
| 44 | theta=90, phi=0, |
---|
| 45 | theta_pd=15, theta_pd_n=40, theta_pd_nsigma=3, |
---|
| 46 | radius_polar_pd=0.222296, radius_polar_pd_n=1, radius_polar_pd_nsigma=0, |
---|
| 47 | radius_equatorial_pd=.000128, radius_equatorial_pd_n=1, radius_equatorial_pd_nsigma=0, |
---|
| 48 | phi_pd=0, phi_pd_n=20, phi_pd_nsigma=3, |
---|
| 49 | ) |
---|
| 50 | |
---|
| 51 | # SET THE FITTING PARAMETERS |
---|
| 52 | model.radius_polar.range(15, 1000) |
---|
| 53 | model.radius_equatorial.range(15, 1000) |
---|
| 54 | model.theta_pd.range(0, 360) |
---|
| 55 | model.background.range(0,1000) |
---|
| 56 | model.scale.range(0, 10) |
---|
| 57 | |
---|
| 58 | #cutoff = 0 # no cutoff on polydisperisity loops |
---|
| 59 | #cutoff = 1e-5 # default cutoff |
---|
| 60 | cutoff = 1e-3 # low precision cutoff |
---|
| 61 | M = Experiment(data=radial_data, model=model, cutoff=cutoff) |
---|
| 62 | problem = FitProblem(M) |
---|
| 63 | |
---|
| 64 | Assume that bumps has been installed and the bumps command is available. |
---|
| 65 | Maybe need to set the path to sasmodels/sasview |
---|
| 66 | using *PYTHONPATH=path/to/sasmodels:path/to/sasview/src*. |
---|
| 67 | To run the model use the *bumps* program:: |
---|
| 68 | |
---|
| 69 | $ bumps example/model.py --preview |
---|
| 70 | |
---|
| 71 | Using sasmodels directly |
---|
| 72 | ======================== |
---|
| 73 | |
---|
| 74 | Bumps has a notion of parameter boxes in which you can set and retrieve |
---|
| 75 | values. Instead of using bumps, you can create a directly callable function |
---|
| 76 | with :class:`sasmodels.direct_model.DirectModel`. The resulting object *f* |
---|
| 77 | will be callable as *f(par=value, ...)*, returning the $I(q)$ for the $q$ |
---|
| 78 | values in the data. Polydisperse parameters use the same naming conventions |
---|
| 79 | as in the bumps model, with e.g., radius_pd being the polydispersity associated |
---|
| 80 | with radius. |
---|
| 81 | |
---|
| 82 | Getting a simple function that you can call on a set of q values and return |
---|
| 83 | a result is not so simple. Since the time critical use case (fitting) involves |
---|
| 84 | calling the function over and over with identical $q$ values, we chose to |
---|
| 85 | optimize the call by only transfering the $q$ values to the GPU once at the |
---|
| 86 | start of the fit. We do this by creating a :class:`sasmodels.kernel.Kernel` |
---|
| 87 | object from the :class:`sasmodels.kernel.KernelModel` returned from |
---|
| 88 | :func:`sasmodels.core.load_model` using the |
---|
| 89 | :meth:`sasmodels.kernel.KernelModel.make_kernel` method. What it actual |
---|
| 90 | does depends on whether it is running as a DLL, as OpenCL or as a pure |
---|
| 91 | python kernel. Once the kernel is in hand, we can then marshal a set of |
---|
| 92 | parameters into a :class:`sasmodels.details.CallDetails` object and ship it to |
---|
| 93 | the kernel using the :func:`sansmodels.direct_model.call_kernel` function. An |
---|
| 94 | example should help, *example/cylinder_eval.py*:: |
---|
| 95 | |
---|
| 96 | from numpy import logspace |
---|
| 97 | from matplotlib import pyplot as plt |
---|
| 98 | from sasmodels.core import load_model |
---|
| 99 | from sasmodels.direct_model import call_kernel |
---|
| 100 | |
---|
| 101 | model = load_model('cylinder') |
---|
| 102 | q = logspace(-3, -1, 200) |
---|
| 103 | kernel = model.make_kernel([q]) |
---|
| 104 | Iq = call_kernel(kernel, dict(radius=200.)) |
---|
| 105 | plt.loglog(q, Iq) |
---|
| 106 | plt.show() |
---|