Exemplo n.º 1
0
 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)
Exemplo n.º 2
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)
Exemplo n.º 3
0
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)")
Exemplo n.º 4
0
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')
Exemplo n.º 5
0
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)")
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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,