Changeset c9d052d in sasmodels


Ignore:
Timestamp:
Jun 17, 2018 11:45:45 AM (6 years ago)
Author:
awashington
Branches:
master
Children:
298d2d4
Parents:
befe905 (diff), b032200 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'log_sesans' of github.com:rprospero/sasmodels into log_sesans

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • doc/guide/sesans/sans_to_sesans.rst

    rf0fc507 rd7af1c6  
    3131 
    3232in which :math:`t` is the thickness of the sample and :math:`\lambda` is the wavelength of the neutrons. 
     33 
     34Log Spaced SESANS 
     35----------------- 
     36 
     37For computational efficiency, the integral in the Hankel transform is 
     38converted into a Reimann sum 
     39 
     40 
     41.. math:: G(\delta) \approx 
     42          2 \pi 
     43          \sum_{Q=q_{min}}^{q_{max}} J_0(Q \delta) 
     44          \frac{d \Sigma}{d \Omega} (Q) 
     45          Q \Delta Q \! 
     46 
     47However, this model approximates more than is strictly necessary. 
     48Specifically, it is approximating the entire integral, when it is only 
     49the scattering function that cannot be handled analytically.  A better 
     50approximation might be 
     51 
     52.. math:: G(\delta) \approx 
     53          \sum_{n=0} 2 \pi \frac{d \Sigma}{d \Omega} (q_n) 
     54          \int_{q_{n-1}}^{q_n} J_0(Q \delta) Q dQ 
     55          = 
     56          \sum_{n=0} \frac{2 \pi}{\delta} \frac{d \Sigma}{d \Omega} (q_n) 
     57          (q_n J_1(q_n \delta) - q_{n-1}J_1(q_{n-1} \delta))\!, 
     58 
     59Assume that vectors :math:`q_n` and :math:`I_n` represent the q points 
     60and corresponding intensity data, respectively.  Further assume that 
     61:math:`\delta_m` and :math:`G_m` are the spin echo lengths and 
     62corresponding Hankel transform value. 
     63 
     64.. math:: G_m = H_{nm} I_n 
     65 
     66where 
     67 
     68.. math:: H_{nm} = \frac{2 \pi}{\delta_m} 
     69          (q_n J_1(q_n \delta_m) - q_{n-1} J_1(q_{n-1} \delta_m)) 
     70 
     71Also not that, for the limit as :math:`\delta_m` approaches zero, 
     72 
     73.. math:: G(0) 
     74          = 
     75          \sum_{n=0} \pi \frac{d \Sigma}{d \Omega} (q_n) (q_n^2 - q_{n-1}^2) 
  • sasmodels/sesans.py

    rfa79f5c rb032200  
    1414import numpy as np  # type: ignore 
    1515from numpy import pi  # type: ignore 
    16 from scipy.special import j0 
     16from scipy.special import j1 
     17 
    1718 
    1819class SesansTransform(object): 
     
    3839 
    3940    # transform arrays 
    40     _H = None  # type: np.ndarray 
    41     _H0 = None # type: np.ndarray 
     41    _H = None   # type: np.ndarray 
     42    _H0 = None  # type: np.ndarray 
    4243 
    4344    def __init__(self, z, SElength, lam, zaccept, Rmax): 
    4445        # type: (np.ndarray, float, float) -> None 
    45         #import logging; logging.info("creating SESANS transform") 
    4646        self.q = z 
    4747        self._set_hankel(SElength, lam, zaccept, Rmax) 
     
    5656    def _set_hankel(self, SElength, lam, zaccept, Rmax): 
    5757        # type: (np.ndarray, float, float) -> None 
    58         # Force float32 arrays, otherwise run into memory problems on some machines 
     58        # Force float32 arrays, otherwise run into memory problems on 
     59        # some machines 
    5960        SElength = np.asarray(SElength, dtype='float32') 
    6061 
    61         #Rmax = #value in text box somewhere in FitPage? 
     62        # Rmax = #value in text box somewhere in FitPage? 
    6263        q_max = 2*pi / (SElength[1] - SElength[0]) 
    6364        q_min = 0.1 * 2*pi / (np.size(SElength) * SElength[-1]) 
    64         q = np.arange(q_min, q_max, q_min, dtype='float32') 
    65         dq = q_min 
     65        # q = np.arange(q_min, q_max, q_min, dtype='float32') 
     66        # q = np.exp(np.arange(np.log(q_min), np.log(q_max), np.log(2), 
     67        #                      dtype=np.float32)) 
     68        q = np.exp(np.linspace(np.log(q_min), np.log(q_max), 10*SElength.size, 
     69                               dtype=np.float32)) 
     70        q = np.hstack([[0], q]) 
    6671 
    67         H0 = np.float32(dq/(2*pi)) * q 
     72        H0 = np.pi * (q[1:]**2 - q[:-1]**2) 
    6873 
    69         repq = np.tile(q, (SElength.size, 1)).T 
    70         repSE = np.tile(SElength, (q.size, 1)) 
    71         H = np.float32(dq/(2*pi)) * j0(repSE*repq) * repq 
     74        # repq = np.tile(q, (SElength.size, 1)).T 
     75        H = np.outer(q, SElength) 
     76        j1(H, out=H) 
     77        H *= q.reshape((-1, 1)) 
     78        H = H[1:] - H[:-1] 
     79        H *= 2 * np.pi / SElength 
    7280 
    73         replam = np.tile(lam, (q.size, 1)) 
    74         reptheta = np.arcsin(repq*replam/2*np.pi) 
     81        lam = np.asarray(lam, dtype=np.float32) 
     82        reptheta = np.outer(q[1:], lam) 
     83        reptheta /= np.float32(2*np.pi) 
     84        np.arcsin(reptheta, out=reptheta) 
     85        # reptheta = np.arcsin(repq*replam/2*np.pi) 
    7586        mask = reptheta > zaccept 
    76         H[mask] = 0 
     87        # H[mask] = 0 
    7788 
    78         self.q_calc = q 
     89        # H = np.zeros((q.size, SElength.size), dtype=np.float32) 
     90        # H0 = q * 0 
     91        assert(H.shape == (q.size-1, SElength.size)) 
     92 
     93        self.q_calc = q[1:] 
    7994        self._H, self._H0 = H, H0 
  • doc/guide/magnetism/magnetism.rst

    r4f5afc9 rbefe905  
    3939 
    4040.. math:: 
    41     -- &= ((1-u_i)(1-u_f))^{1/4} \\ 
    42     -+ &= ((1-u_i)(u_f))^{1/4} \\ 
    43     +- &= ((u_i)(1-u_f))^{1/4} \\ 
    44     ++ &= ((u_i)(u_f))^{1/4} 
     41    -- &= (1-u_i)(1-u_f) \\ 
     42    -+ &= (1-u_i)(u_f) \\ 
     43    +- &= (u_i)(1-u_f) \\ 
     44    ++ &= (u_i)(u_f) 
    4545 
    4646Ideally the experiment would measure the pure spin states independently and 
     
    104104| 2015-05-02 Steve King 
    105105| 2017-11-15 Paul Kienzle 
     106| 2018-06-02 Adam Washington 
  • sasmodels/kernel_iq.c

    rdc6f601 r7c35fda  
    8383  in_spin = clip(in_spin, 0.0, 1.0); 
    8484  out_spin = clip(out_spin, 0.0, 1.0); 
    85   // Note: sasview 3.1 scaled all slds by sqrt(weight) and assumed that 
     85  // Previous version of this function took the square root of the weights, 
     86  // under the assumption that  
     87  // 
    8688  //     w*I(q, rho1, rho2, ...) = I(q, sqrt(w)*rho1, sqrt(w)*rho2, ...) 
    87   // which is likely to be the case for simple models. 
    88   weight[0] = sqrt((1.0-in_spin) * (1.0-out_spin)); // dd 
    89   weight[1] = sqrt((1.0-in_spin) * out_spin);       // du.real 
    90   weight[2] = sqrt(in_spin * (1.0-out_spin));       // ud.real 
    91   weight[3] = sqrt(in_spin * out_spin);             // uu 
     89  // 
     90  // However, since the weights are applied to the final intensity and 
     91  // are not interned inside the I(q) function, we want the full 
     92  // weight and not the square root.  Any function using 
     93  // set_spin_weights as part of calculating an amplitude will need to 
     94  // manually take that square root, but there is currently no such 
     95  // function. 
     96  weight[0] = (1.0-in_spin) * (1.0-out_spin); // dd 
     97  weight[1] = (1.0-in_spin) * out_spin;       // du 
     98  weight[2] = in_spin * (1.0-out_spin);       // ud 
     99  weight[3] = in_spin * out_spin;             // uu 
    92100  weight[4] = weight[1]; // du.imag 
    93101  weight[5] = weight[2]; // ud.imag 
Note: See TracChangeset for help on using the changeset viewer.