def call_ocl(self, x, dtype, platform='ocl'): """ Calculation using sasmodels ocl libraries. """ x = np.asarray(x, dtype) model = core.build_model(self.ocl_function, dtype=dtype) calculator = direct_model.DirectModel(data.empty_data1D(x), model) return calculator(background=0)
def make_figure(model_info, opts): # type: (ModelInfo, Dict[str, Any]) -> None """ Generate the figure file to include in the docs. """ import matplotlib.pyplot as plt model = core.build_model(model_info) fig_height = 3.0 # in fig_left = 0.6 # in fig_right = 0.5 # in fig_top = 0.6 * 0.25 # in fig_bottom = 0.6 * 0.75 if model_info.parameters.has_2d: plot_height = fig_height - (fig_top + fig_bottom) plot_width = plot_height fig_width = 2 * (plot_width + fig_left + fig_right) aspect = (fig_width, fig_height) ratio = aspect[0] / aspect[1] ax_left = fig_left / fig_width ax_bottom = fig_bottom / fig_height ax_height = plot_height / fig_height ax_width = ax_height / ratio # square axes fig = plt.figure(figsize=aspect) ax2d = fig.add_axes([0.5 + ax_left, ax_bottom, ax_width, ax_height]) plot_2d(model, opts, ax2d) ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height]) plot_1d(model, opts, ax1d) #ax.set_aspect('square') else: plot_height = fig_height - (fig_top + fig_bottom) plot_width = (1 + np.sqrt(5)) / 2 * fig_height fig_width = plot_width + fig_left + fig_right ax_left = fig_left / fig_width ax_bottom = fig_bottom / fig_height ax_width = plot_width / fig_width ax_height = plot_height / fig_height aspect = (fig_width, fig_height) fig = plt.figure(figsize=aspect) ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height]) plot_1d(model, opts, ax1d) if model_info.profile: plot_profile_inset(model_info, ax1d) # Save image in model/img makedirs(joinpath(TARGET_DIR, 'img'), exist_ok=True) path = joinpath(TARGET_DIR, 'img', figfile(model_info)) plt.savefig(path, bbox_inches='tight') plt.close(fig)
def _eval_demo_1d(resolution, title): import sys from sasmodels import core from sasmodels import direct_model name = sys.argv[1] if len(sys.argv) > 1 else 'cylinder' if name == 'cylinder': pars = {'length': 210, 'radius': 500, 'background': 0} elif name == 'teubner_strey': pars = {'a2': 0.003, 'c1': -1e4, 'c2': 1e10, 'background': 0.312643} elif name == 'sphere' or name == 'spherepy': pars = TEST_PARS_SLIT_SPHERE elif name == 'ellipsoid': pars = { 'scale': 0.05, 'background': 0, 'r_polar': 500, 'r_equatorial': 15000, 'sld': 6, 'sld_solvent': 1, } else: pars = {} model_info = core.load_model_info(name) model = core.build_model(model_info) kernel = model.make_kernel([resolution.q_calc]) theory = direct_model.call_kernel(kernel, pars) Iq = resolution.apply(theory) if isinstance(resolution, Slit1D): width, height = resolution.qx_width, resolution.qy_width Iq_romb = romberg_slit_1d(resolution.q, width, height, model, pars) else: dq = resolution.q_width Iq_romb = romberg_pinhole_1d(resolution.q, dq, model, pars) import matplotlib.pyplot as plt # type: ignore plt.loglog(resolution.q_calc, theory, label='unsmeared') plt.loglog(resolution.q, Iq, label='smeared', hold=True) plt.loglog(resolution.q, Iq_romb, label='romberg smeared', hold=True) plt.legend() plt.title(title) plt.xlabel("Q (1/Ang)") plt.ylabel("I(Q) (1/cm)")
def make_figure(model_info, opts): # type: (ModelInfo, Dict[str, Any]) -> None """ Generate the figure file to include in the docs. """ model = core.build_model(model_info) fig_height = 3.0 # in fig_left = 0.6 # in fig_right = 0.5 # in fig_top = 0.6*0.25 # in fig_bottom = 0.6*0.75 if model_info.parameters.has_2d: plot_height = fig_height - (fig_top+fig_bottom) plot_width = plot_height fig_width = 2*(plot_width + fig_left + fig_right) aspect = (fig_width, fig_height) ratio = aspect[0]/aspect[1] ax_left = fig_left/fig_width ax_bottom = fig_bottom/fig_height ax_height = plot_height/fig_height ax_width = ax_height/ratio # square axes fig = plt.figure(figsize=aspect) ax2d = fig.add_axes([0.5+ax_left, ax_bottom, ax_width, ax_height]) plot_2d(model, opts, ax2d) ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height]) plot_1d(model, opts, ax1d) #ax.set_aspect('square') else: plot_height = fig_height - (fig_top+fig_bottom) plot_width = (1+np.sqrt(5))/2*fig_height fig_width = plot_width + fig_left + fig_right ax_left = fig_left/fig_width ax_bottom = fig_bottom/fig_height ax_width = plot_width/fig_width ax_height = plot_height/fig_height aspect = (fig_width, fig_height) fig = plt.figure(figsize=aspect) ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height]) plot_1d(model, opts, ax1d) # Save image in model/img path = os.path.join('model', 'img', figfile(model_info)) plt.savefig(path, bbox_inches='tight')
def _eval_demo_1d(resolution, title): import sys from sasmodels import core name = sys.argv[1] if len(sys.argv) > 1 else 'cylinder' if name == 'cylinder': pars = {'length':210, 'radius':500, 'background': 0} elif name == 'teubner_strey': pars = {'a2':0.003, 'c1':-1e4, 'c2':1e10, 'background':0.312643} elif name == 'sphere' or name == 'spherepy': pars = TEST_PARS_SLIT_SPHERE elif name == 'ellipsoid': pars = { 'scale':0.05, 'background': 0, 'r_polar':500, 'r_equatorial':15000, 'sld':6, 'sld_solvent': 1, } else: pars = {} model_info = core.load_model_info(name) model = core.build_model(model_info) kernel = model.make_kernel([resolution.q_calc]) theory = core.call_kernel(kernel, pars) Iq = resolution.apply(theory) if isinstance(resolution, Slit1D): width, height = resolution.dqx, resolution.dqy Iq_romb = romberg_slit_1d(resolution.q, width, height, model, pars) else: dq = resolution.q_width Iq_romb = romberg_pinhole_1d(resolution.q, dq, model, pars) import matplotlib.pyplot as plt plt.loglog(resolution.q_calc, theory, label='unsmeared') plt.loglog(resolution.q, Iq, label='smeared', hold=True) plt.loglog(resolution.q, Iq_romb, label='romberg smeared', hold=True) plt.legend() plt.title(title) plt.xlabel("Q (1/Ang)") plt.ylabel("I(Q) (1/cm)")
def select_calculator(model_name, n=150, size=(10, 40, 100)): """ Create a model calculator for the given shape. *model_name* is one of sphere, cylinder, ellipsoid, triaxial_ellipsoid, parallelepiped or bcc_paracrystal. *n* is the number of points to use in the q range. *qmax* is chosen based on model parameters for the given model to show something intersting. Returns *calculator* and tuple *size* (a,b,c) giving minor and major equitorial axes and polar axis respectively. See :func:`build_model` for details on the returned calculator. """ a, b, c = size if model_name == 'sphere': calculator = build_model('sphere', n=n, radius=c) a = b = c elif model_name == 'bcc_paracrystal': calculator = build_model('bcc_paracrystal', n=n, dnn=c, d_factor=0.06, radius=40) a = b = c elif model_name == 'cylinder': calculator = build_model('cylinder', n=n, qmax=0.3, radius=b, length=c) a = b elif model_name == 'ellipsoid': calculator = build_model('ellipsoid', n=n, qmax=1.0, radius_polar=c, radius_equatorial=b) a = b elif model_name == 'triaxial_ellipsoid': calculator = build_model('triaxial_ellipsoid', n=n, qmax=0.5, radius_equat_minor=a, radius_equat_major=b, radius_polar=c) elif model_name == 'parallelepiped': calculator = build_model('parallelepiped', n=n, a=a, b=b, c=c) else: raise ValueError("unknown model %s" % model_name) return calculator, (a, b, c)
def build_model(model_name, n=150, qmax=0.5, **pars): """ Build a calculator for the given shape. *model_name* is any sasmodels model. *n* and *qmax* define an n x n mesh on which to evaluate the model. The remaining parameters are stored in the returned calculator as *calculator.pars*. They are used by :func:`draw_scattering` to set the non-orientation parameters in the calculation. Returns a *calculator* function which takes a dictionary or parameters and produces Iqxy. The Iqxy value needs to be reshaped to an n x n matrix for plotting. See the :class:`sasmodels.direct_model.DirectModel` class for details. """ from sasmodels.core import load_model_info, build_model from sasmodels.data import empty_data2D from sasmodels.direct_model import DirectModel model_info = load_model_info(model_name) model = build_model(model_info) #, dtype='double!') q = np.linspace(-qmax, qmax, n) data = empty_data2D(q, q) calculator = DirectModel(data, model) # stuff the values for non-orientation parameters into the calculator calculator.pars = pars.copy() calculator.pars.setdefault('backgound', 1e-3) # fix the data limits so that we can see if the pattern fades # under rotation or angular dispersion Iqxy = calculator(theta=0, phi=0, psi=0, **calculator.pars) Iqxy = np.log(Iqxy) vmin, vmax = clipped_range(Iqxy, 0.95, mode='top') calculator.limits = vmin, vmax + 1 return calculator
import sys, os, math, re import numpy as np import matplotlib.pyplot as plt import pylab sys.path.insert(0, os.path.abspath('..')) from sasmodels import generate, core from sasmodels.direct_model import DirectModel from sasmodels.data import empty_data1D, empty_data2D # Convert ../sasmodels/models/name.py to name model_name = os.path.basename(sys.argv[1])[:-3] model_info = core.load_model_info(model_name) model = core.build_model(model_info) # Load the doc string from the module definition file and store it in rst docstr = generate.make_doc(model_info) # Calculate 1D curve for default parameters pars = dict((p.name, p.default) for p in model_info['parameters']) # Plotting ranges and options opts = { 'xscale': 'log', 'yscale': 'log' if not model_info['structure_factor'] else 'linear', 'zscale': 'log' if not model_info['structure_factor'] else 'linear', 'q_min': 0.001, 'q_max': 1.0, 'nq': 1000, 'nq2d': 1000, 'vmin': 1e-3, # floor for the 2D data results 'qx_max': 0.5,