source: sasmodels/sasmodels/sesans.py @ 54f1d96

core_shell_microgelscostrafo411magnetic_modelticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since 54f1d96 was 54f1d96, checked in by jhbakker, 7 years ago

Manually added in all SESANS modifications from Jurtest branch because of
corrupted git history…

  • Property mode set to 100644
File size: 3.2 KB
Line 
1"""
2Conversion of scattering cross section from SANS (I(q), or rather, ds/dO) in absolute
3units (cm-1)into SESANS correlation function G using a Hankel transformation, then converting
4the SESANS correlation function into polarisation from the SESANS experiment
5
6Everything is in units of metres except specified otherwise (NOT TRUE!!!)
7Everything is in conventional units (nm for spin echo length)
8
9Wim Bouwman (w.g.bouwman@tudelft.nl), June 2013
10"""
11
12from __future__ import division
13
14import numpy as np  # type: ignore
15from numpy import pi, exp  # type: ignore
16from scipy.special import j0
17#from mpmath import j0 as j0
18       
19class SesansTransform(object):
20    #: Set of spin-echo lengths in the measured data
21    SE = None  # type: np.ndarray
22    #: Maximum acceptance of scattering vector in the spin echo encoding dimension (for ToF: Q of min(R) and max(lam))
23    zaccept = None # type: float
24    #: Maximum size sensitivity; larger radius requires more computation
25    Rmax = None  # type: float
26    #: q values to calculate when computing transform
27    q = None  # type: np.ndarray
28
29    # transform arrays
30    _H = None  # type: np.ndarray
31    _H0 = None # type: np.ndarray
32
33    def set_transform(self, SE, zaccept, Rmax):
34        if self.SE is None or len(SE) != len(self.SE) or np.any(SE != self.SE) or zaccept != self.zaccept or Rmax != self.Rmax:
35            self.SE, self.zaccept, self.Rmax = SE, zaccept, Rmax
36            self._set_q()
37            self._set_hankel()
38
39    def apply(self, Iq):
40        G0 = np.dot(self._H0, Iq)
41        G = np.dot(self._H.T, Iq)
42        P = G - G0
43        return P
44
45    def _set_q(self):
46        #q_min = dq = 0.1 * 2*pi / self.Rmax
47
48        q_max = 2*pi / (self.SE[1]-self.SE[0])
49        q_min = dq = 0.1 *2*pi / (np.size(self.SE) * self.SE[-1])
50
51        #q_min = dq = q_max / 100000
52        q=np.arange(q_min, q_max, q_min)
53        self.q = q
54        self.dq = dq
55
56    def _set_hankel(self):
57        #Rmax = #value in text box somewhere in FitPage?
58        q = self.q
59        dq = self.dq
60        SElength = self.SE
61
62        H0 = dq / (2 * pi) * q
63        q=np.array(q,dtype='float32')
64        SElength=np.array(SElength,dtype='float32')
65
66        # Using numpy tile, dtype is conserved
67        repq=np.tile(q,(SElength.size,1))
68        repSE=np.tile(SElength,(q.size,1))
69        H = dq / (2 * pi) * j0(repSE*repq.T)*repq.T
70
71        # Using numpy meshgrid - meshgrid produces float64 from float32 inputs! Problem for 32-bit OS: Memerrors!
72        #H0 = dq / (2 * pi) * q
73        #repSE, repq = np.meshgrid(SElength, q)
74        #repq=np.array(repq,dtype='float32')
75        #repSE=np.array(repSE,dtype='float32')
76        #H = dq / (2 * pi) * j0(repSE*repq)*repq
77
78        self._H, self._H0 = H, H0
79
80class SESANS1D(SesansTransform):
81    def __init__(self, data, _H0, _H, q_calc):
82        # x values of the data (Sasview requires these to be named "q")
83        self.q = data.x
84        self._H0 = _H0
85        self._H = _H
86        # Pysmear does some checks on the smearer object, these checks require the "data" object...
87        self.data=data
88        # q values of the SAS model
89        self.q_calc = q_calc # These are the MODEL's q values used by the smearer (in this case: the Hankel transform)
90    def apply(self, theory):
91        return SesansTransform.apply(self,theory)
Note: See TracBrowser for help on using the repository browser.