Changeset 49d1d42f in sasmodels


Ignore:
Timestamp:
Mar 11, 2015 8:58:05 PM (9 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
aa4946b
Parents:
63b32bb
Message:

working demo of 1D resolution calculator (still incomplete and incorrect)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/resolution.py

    r63b32bb r49d1d42f  
    44 
    55SLIT_SMEAR_POINTS = 500 
     6 
     7class MatrixResolution: 
     8    def apply(self, Iq): 
     9        return np.dot(Iq, self.resolution_matrix) 
     10 
     11class Pinhole1D(MatrixResolution): 
     12    def __init__(self, q, q_width): 
     13        self.q, self.q_width = q, q_width 
     14        self.q_calc = pinhole_extend_q(q,q_width) 
     15        self.resolution_matrix = \ 
     16            pinhole_resolution(self.q_calc, self.q, self.q_width) 
     17 
     18class Slit1D(MatrixResolution): 
     19    def __init__(self, q, qx_width, qy_width): 
     20        if np.isscalar(qx_width): 
     21            qx_width = qx_width*np.ones(len(q)) 
     22        if np.isscalar(qy_width): 
     23            qy_width = qy_width*np.ones(len(q)) 
     24        self.q, self.qx_width, self.qy_width = q, qx_width, qy_width 
     25        self.q_calc = slit_extend_q(q, qx_width, qy_width) 
     26        self.resolution_matrix = \ 
     27            slit_resolution(self.q_calc, self.q, self.qx_width, self.qy_width) 
    628 
    729def pinhole_resolution(q_calc, q, q_width): 
     
    1941    G = erf( (edges[:,None] - q[None,:]) / (sqrt(2.0)*q_width)[None,:] ) 
    2042    weights = G[1:] - G[:-1] 
    21     weights /= sum(weights, axis=1) 
     43    weights /= np.sum(weights, axis=1) 
    2244    return weights 
     45 
     46 
     47def pinhole_extend_q(q, q_width): 
     48    return q 
     49 
    2350 
    2451def slit_resolution(q_calc, q, qx_width, qy_width): 
     
    2754    qy_min, qy_max = 0.0, edges[-1] 
    2855 
     56    # Make q_calc into a row vector, and q, qx_width, qy_width into columns 
     57    # Make weights match [ q_calc X q ] 
    2958    weights = np.zeros((len(q),len(q_calc)),'d') 
     59    q_calc = q_calc[None,:] 
     60    q, qx_width, qy_width, edges = [ 
     61        v[:,None] for v in (q, qx_width, qy_width, edges)] 
     62 
    3063    # Loop for width (height is analytical). 
    3164    # Condition: height >>> width, otherwise, below is not accurate enough. 
     
    3770    # In general, this weight numerical iteration for width>0 might be a rough 
    3871    # approximation, but it must be good enough when height >>> width. 
    39     E_sq = edges**2[:,None] 
     72    E_sq = edges**2 
    4073    y_points = SLIT_SMEAR_POINTS if np.any(qy_width>0) else 1 
    4174    qy_step = 0 if y_points == 1 else qy_width/(y_points-1) 
     
    4477        qx_low = qy 
    4578        qx_high = sqrt(qx_low**2 + qx_width**2) 
    46         in_x = (q_calc[:,None]>=qx_low[None,:])*(q_calc[:,None]<=qx_high[None,:]) 
    47         qy_sq = qy**2[None,:] 
    48         weights += (sqrt(E_sq[1:]-qy_sq) - sqrt(E_sq[:-1]-qy_sq))*in_x 
    49     weights /= sum(weights, axis=1) 
     79        in_x = (q_calc>=qx_low)*(q_calc<=qx_high) 
     80        qy_sq = qy**2 
     81        weights += (sqrt(E_sq[1:]-qy_sq) - sqrt(qy_sq - E_sq[:-1]))*in_x 
     82    weights /= np.sum(weights, axis=1) 
    5083    return weights 
     84 
     85 
     86def slit_extend_q(q, qx_width, qy_width): 
     87    return q 
     88 
    5189 
    5290def bin_edges(x): 
     
    5997        ]) 
    6098    return edges 
     99 
     100 
     101############################################################################ 
     102# usage demo 
     103############################################################################ 
     104 
     105def _eval_demo_1d(resolution, title): 
     106    from sasmodels import core 
     107    from sasmodels.models import cylinder 
     108    ## or alternatively: 
     109    # cylinder = core.load_model_definition('cylinder') 
     110    model = core.load_model(cylinder) 
     111 
     112    kernel = core.make_kernel(model, [resolution.q_calc]) 
     113    Iq_calc = core.call_kernel(kernel, {'length':210, 'radius':500}) 
     114    Iq = resolution.apply(Iq_calc) 
     115 
     116    import matplotlib.pyplot as plt 
     117    plt.loglog(resolution.q_calc, Iq_calc, label='unsmeared') 
     118    plt.loglog(resolution.q, Iq, label='smeared', hold=True) 
     119    plt.legend() 
     120    plt.title(title) 
     121    plt.xlabel("Q (1/Ang)") 
     122    plt.ylabel("I(Q) (1/cm)") 
     123 
     124def demo_pinhole_1d(): 
     125    q = np.logspace(-3,-1,400) 
     126    dq = 0.1*q 
     127    resolution = Pinhole1D(q, dq) 
     128    _eval_demo_1d(resolution, title="10% dQ/Q Pinhole Resolution") 
     129 
     130def demo_slit_1d(): 
     131    q = np.logspace(-3,-1,400) 
     132    qx_width = 0.005 
     133    qy_width = 0.0 
     134    resolution = Slit1D(q, qx_width, qy_width) 
     135    _eval_demo_1d(resolution, title="0.005 Qx Slit Resolution") 
     136 
     137def demo(): 
     138    import matplotlib.pyplot as plt 
     139    plt.subplot(121) 
     140    demo_pinhole_1d() 
     141    plt.subplot(122) 
     142    demo_slit_1d() 
     143    plt.show() 
     144 
     145 
     146if __name__ == "__main__": 
     147    demo() 
     148 
     149 
Note: See TracChangeset for help on using the changeset viewer.