Changeset 7c1cce3 in sasmodels for sasmodels/sesans.py


Ignore:
Timestamp:
Apr 10, 2017 7:39:56 AM (7 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
costrafo411
Children:
2cdc35b
Parents:
a86e249
Message:

oriented sesans: split transform into oriented and unoriented versions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/sesans.py

    ra86e249 r7c1cce3  
    2020    Spin-Echo SANS transform calculator.  Similar to a resolution function, 
    2121    the SesansTransform object takes I(q) for the set of *q_calc* values and 
    22     produces a transformed dataset 
     22    produces a transformed dataset. 
    2323 
    2424    *SElength* (A) is the set of spin-echo lengths in the measured data. 
     
    4545        #import logging; logging.info("creating SESANS transform") 
    4646        self.q = z 
    47         # isoriented flag determines whether data is from an oriented sample or not, should be a selection variable upon entering SESANS data. 
    48         if self.isoriented==False: 
    49             self._set_hankel(SElength, zaccept, Rmax) 
    50         if self.isoriented==True: 
    51             self._set_cosmat(SElength, zaccept, Rmax) 
     47        # isoriented flag determines whether data is from an oriented sample or 
     48        # not, should be a selection variable upon entering SESANS data. 
     49        self._set_hankel(SElength, zaccept, Rmax) 
    5250 
    5351    def apply(self, Iq): 
    54         try: 
    55             G0 = np.dot(self._H0, Iq) 
    56             G = np.dot(self._H.T, Iq) 
    57             P = G - G0 
    58         except: 
    59             try: 
    60                 dq = self.q_calc[0] 
    61                 G0 = sum(np.dot(self._cos0, Iq) * dq) 
    62                 G = sum(np.dot(self._cosmat.T, Iq) * dq) 
    63                 P = G - G0 
    64             except: 
    65                 raise ValueError('Sesanstransform.apply cannot generate either a Hankel transform or a cosine transform of you SESANS data') 
     52        G0 = np.dot(self._H0, Iq) 
     53        G = np.dot(self._H.T, Iq) 
     54        P = G - G0 
    6655        return P 
    6756 
     
    8675        self._H, self._H0 = H, H0 
    8776 
     77class OrientedSesansTransform(object): 
     78    """ 
     79    Oriented Spin-Echo SANS transform calculator.  Similar to a resolution 
     80    function, the OrientedSesansTransform object takes I(q) for the set 
     81    of *q_calc* values and produces a transformed dataset. 
     82 
     83    *SElength* (A) is the set of spin-echo lengths in the measured data. 
     84 
     85    *zaccept* (1/A) is the maximum acceptance of scattering vector in the spin 
     86    echo encoding dimension (for ToF: Q of min(R) and max(lam)). 
     87 
     88    *Rmax* (A) is the maximum size sensitivity; larger radius requires more 
     89    computation time. 
     90    """ 
     91    #: SElength from the data in the original data units; not used by transform 
     92    #: but the GUI uses it, so make sure that it is present. 
     93    q = None  # type: np.ndarray 
     94 
     95    #: q values to calculate when computing transform 
     96    q_calc = None  # type: np.ndarray 
     97 
     98    # transform arrays 
     99    _cosmat = None  # type: np.ndarray 
     100    _cos0 = None # type: np.ndarray 
     101    _Iq_shape = None # type: Tuple[int, int] 
     102 
     103    def __init__(self, z, SElength, zaccept, Rmax): 
     104        # type: (np.ndarray, float, float) -> None 
     105        #import logging; logging.info("creating SESANS transform") 
     106        self.q = z 
     107        # isoriented flag determines whether data is from an oriented sample or 
     108        # not, should be a selection variable upon entering SESANS data. 
     109        self._set_cosmat(SElength, zaccept, Rmax) 
     110 
     111    def apply(self, Iq): 
     112        dq = self.q_calc[0][0] 
     113        Iq = np.reshape(Iq, self._Iq_shape) 
     114        G0 = self._cos0 * np.sum(Iq) * dq 
     115        G = np.sum(np.dot(Iq, self._cosmat.T), axis=1) * dq 
     116        P = G - G0 
     117        return P 
     118 
    88119    def _set_cosmat(self, SElength, zaccept, Rmax): 
    89120        # type: (np.ndarray, float, float) -> None 
     
    99130 
    100131        cos0 = np.float32(dq / (2 * pi)) 
     132        cosmat = np.float32(dq / (2 * pi)) * np.cos(q[:, None] * SE[None, :]) 
    101133 
    102         repq = np.tile(q, (SElength.size, 1)).T 
    103         repSE = np.tile(SElength, (q.size, 1)) 
    104         cosmat = np.float32(dq / (2 * pi)) * np.cos(repSE * repq) 
    105  
    106         self.q_calc = q 
     134        qx, qy = np.meshgrid(q, q) 
     135        self._Iq_shape = qx.shape 
     136        self.q_calc = qx.flatten(), qy.flatten() 
    107137        self._cosmat, self._cos0 = cosmat, cos0 
Note: See TracChangeset for help on using the changeset viewer.